From b65d4dd8f1ceb435371632afdf9de45aeb9d516c Mon Sep 17 00:00:00 2001 From: Joseph Rahmeh Date: Wed, 19 Feb 2020 18:25:04 -0800 Subject: [PATCH] Version 1.5 --- LICENSE | 206 +---- README.md | 203 +++-- configs/README.md | 6 +- configs/swerv.config | 795 ++++++++++------- design/dbg/dbg.sv | 317 +++---- design/dec/cdecode | 128 +-- design/dec/csrdecode | 62 +- design/dec/dec.sv | 233 ++--- design/dec/dec_decode_ctl.sv | 1276 ++++++++++++++-------------- design/dec/dec_gpr_ctl.sv | 46 +- design/dec/dec_ib_ctl.sv | 196 ++--- design/dec/dec_tlu_ctl.sv | 735 ++++++++-------- design/dec/dec_trigger.sv | 24 +- design/dec/decode | 108 +-- design/dma_ctrl.sv | 144 ++-- design/dmi/dmi_jtag_to_core_sync.v | 4 +- design/dmi/rvjtag_tap.sv | 28 +- design/exu/exu.sv | 12 +- design/exu/exu_alu_ctl.sv | 6 +- design/exu/exu_mul_ctl.sv | 2 +- design/ifu/ifu.sv | 134 +-- design/ifu/ifu_aln_ctl.sv | 528 ++++++------ design/ifu/ifu_bp_ctl.sv | 554 ++++++------ design/ifu/ifu_compress_ctl.sv | 86 +- design/ifu/ifu_ic_mem.sv | 262 +++--- design/ifu/ifu_iccm_mem.sv | 48 +- design/ifu/ifu_ifc_ctl.sv | 94 +- design/ifu/ifu_mem_ctl.sv | 647 +++++++------- design/include/build.h | 6 +- design/include/global.h | 12 +- design/include/swerv_types.sv | 68 +- design/lib/ahb_to_axi4.sv | 108 +-- design/lib/axi4_to_ahb.sv | 156 ++-- design/lib/beh_lib.sv | 165 ++-- design/lib/mem_lib.sv | 276 +++--- design/lsu/lsu.sv | 126 +-- design/lsu/lsu_addrcheck.sv | 69 +- design/lsu/lsu_bus_buffer.sv | 172 ++-- design/lsu/lsu_bus_intf.sv | 90 +- design/lsu/lsu_clkdomain.sv | 94 +- design/lsu/lsu_dccm_ctl.sv | 72 +- design/lsu/lsu_dccm_mem.sv | 58 +- design/lsu/lsu_ecc.sv | 76 +- design/lsu/lsu_lsc_ctl.sv | 141 +-- design/lsu/lsu_stbuf.sv | 106 +-- design/lsu/lsu_trigger.sv | 24 +- design/mem.sv | 42 +- design/pic_ctrl.sv | 304 ++++--- design/swerv.sv | 433 +++++----- design/swerv_wrapper.sv | 115 +-- testbench/ahb_sif.sv | 287 ++++--- testbench/asm/hello_world.s | 121 +-- testbench/link.ld | 8 +- testbench/tb_top.sv | 1211 ++++++++++++++++++-------- testbench/test_tb_top.cpp | 64 +- tools/JSON.pm | 90 +- tools/Makefile | 184 ++-- tools/addassign | 26 +- tools/coredecode | 146 ++-- tools/picmap | 10 +- tools/smalldiv | 38 +- 61 files changed, 6242 insertions(+), 5540 deletions(-) diff --git a/LICENSE b/LICENSE index 261eeb9..4b24f09 100644 --- a/LICENSE +++ b/LICENSE @@ -1,201 +1,69 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ +Apache License +Version 2.0, January 2004 +http://www.apache.org/licenses/ - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - 1. Definitions. +1. Definitions. - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. +"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. +"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. +"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. +"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. +"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. +"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). +"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. +"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." +"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. +"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. +2. Grant of Copyright License. - 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. +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. - 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: +3. Grant of Patent License. - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and +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. - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and +4. Redistribution. - (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 +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: - (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 must give any other recipients of the Work or Derivative Works a copy of this License; and - 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. +You must cause any modified files to carry prominent notices stating that You changed the files; and - 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. +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 - 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. +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. - 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. +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. - 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. +5. Submission of Contributions. - 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. +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. - END OF TERMS AND CONDITIONS +6. Trademarks. - APPENDIX: How to apply the Apache License to your work. +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. - 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. +7. Disclaimer of Warranty. - Copyright [yyyy] [name of copyright owner] +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. - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at +8. Limitation of Liability. - http://www.apache.org/licenses/LICENSE-2.0 +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. - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. +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. diff --git a/README.md b/README.md index 9671a03..d4c83d2 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,6 @@ -# SweRV RISC-V CoreTM 1.5 from Western Digital +# EH1 SweRV RISC-V CoreTM 1.5 from Western Digital -This repository contains the SweRV CoreTM 1.5 design RTL. The previous version can be found in [branch 1.4.](https://github.com/chipsalliance/Cores-SweRV/tree/branch1.4) -The SweRV 1 series provides a 32-bit, machine-mode only, implementation of the RISC-V ISA including options I (base integer), M (multiply/divide) and C (compressed instructions from I and M). +This repository contains the SweRV EH1.5 CoreTM design RTL ## License @@ -13,24 +12,26 @@ Files under the [tools](tools/) directory may be available under a different lic ├── configs # Configurations Dir │   └── snapshots # Where generated configuration files are created ├── design # Design root dir - │   ├── dbg # Debugger - │   ├── dec # Decode, Registers and Exceptions - │   ├── dmi # DMI block - │   ├── exu # EXU (ALU/MUL/DIV) - │   ├── ifu # Fetch & Branch Prediction + │   ├── dbg # Debugger + │   ├── dec # Decode, Registers and Exceptions + │   ├── dmi # DMI block + │   ├── exu # EXU (ALU/MUL/DIV) + │   ├── ifu # Fetch & Branch Prediction │   ├── include │   ├── lib - │   └── lsu # Load/Store + │   └── lsu # Load/Store ├── docs ├── tools # Scripts/Makefiles └── testbench # (Very) simple testbench -    ├── asm # Example assembly files -    └── hex # Canned demo hex files +    ├── asm # Example test files +    └── hex # Canned demo hex files ## Dependencies -- Verilator **(3.926 or later)** must be installed on the system -- If adding/removing instructions, espresso must be installed. Espresso is a logic minimization tool used in *tools/coredecode*. +- Verilator **(4.020 or later)** must be installed on the system if running with verilator +- If adding/removing instructions, espresso must be installed (used by *tools/coredecode*) +- RISCV tool chain (based on gcc version 7.3 or higher) must be +installed so that it can be used to prepare RISCV binaries to run. ## Quickstart guide 1. Clone the repository @@ -47,14 +48,17 @@ SweRV can be configured by running the `$RV_ROOT/configs/swerv.config` script: `% $RV_ROOT/configs/swerv.config -h` for detailed help options -For example to build with a DCCM of size 64 : +For example to build with a DCCM of size 64 Kb: `% $RV_ROOT/configs/swerv.config -dccm_size=64` -This will update the **default** snapshot in $RV_ROOT/configs/snapshots/default/ with parameters for a 64K DCCM. +This will update the **default** snapshot in $PWD/snapshots/default/ with parameters for a 64K DCCM. To **unset** a parameter, use `-unset=PARAM` option to swerv.config. Add `-snapshot=dccm64`, for example, if you wish to name your build snapshot *dccm64* and refer to it during the build. +There are four predefined target configurations: `default`, `default_ahb`, `default_pd`, `high_perf` that can be selected via +the `-target=name` option to swerv.config. + This script derives the following consistent set of include files : $RV_ROOT/configs/snapshots/default @@ -62,75 +66,134 @@ This script derives the following consistent set of include files : ├── defines.h # #defines for C/assembly headers ├── pd_defines.vh # `defines for physical design ├── perl_configs.pl # Perl %configs hash for scripting - ├── pic_ctrl_verilator_unroll.sv # Unrolled verilog based on PIC size ├── pic_map_auto.h # PIC memory map based on configure size └── whisper.json # JSON file for swerv-iss ### Building a model -1. Set the RV_ROOT environment variable to the root of the SweRV directory structure - `RV_ROOT = /path/to/swerv` - `export RV_ROOT` +while in a work directory: -1. Create your configuration +1. Set the RV_ROOT environment variable to the root of the SweRV directory structure. +Example for bash shell: + `export RV_ROOT=/path/to/swerv` +Example for csh or its derivatives: + `setenv RV_ROOT /path/to/swerv` + +1. Create your specific configuration *(Skip if default is sufficient)* - *(Name your snapshot to distinguish it from the default. Without an explicit name, it will update/override the **default** snapshot)* - `$RV_ROOT/configs/swerv.config [configuration options..] -snapshot=mybuild` + *(Name your snapshot to distinguish it from the default. Without an explicit name, it will update/override the __default__ snapshot)* + For example if `mybuild` is the name for the snapshot: - Snapshots are placed in `$RV_ROOT/configs/snapshots//` directory - -1. Build with **verilator**: - - `make -f $RV_ROOT/tools/Makefile verilator [snapshot=name]` - -This will create and populate the verilator *obj_dir/* in the current work dir. - -**Other targets supported**: - - vcs (Synopsys) - irun (Cadence) - -### Running a simple Hello World program (verilator) - - RV_ROOT = /path/to/swerv - export RV_ROOT - - make -f $RV_ROOT/tools/Makefile verilator-run - -This will build a verilator model of SweRV with AHB-lite bus, and execute a short sequence of instructions that writes out "HELLO -WORLD" to the bus. - -You can re-execute using - - ./obj_dir/Vtb_top - - Start of sim - - ------------------------------ - Hello World from SweRV @WDC !! - ------------------------------ - - Finished : minstret = 389, mcycle = 1658 - - End of sim - -A vcd file `sim.vcd` is created which can be browsed by gtkwave or similar waveform viewers. `trace_port.csv` contains a log of -the trace port. `exec.log` contains a basic execution trace showing PC, opcode and GPR writes. - -The Makefile allows you to specify different assembly files from command line + set BUILD_PATH environment variable: + + `setenv BUILD_PATH snapshots/mybuild` - make -f $RV_ROOT/tools/Makefile verilator-run ASM_TEST=my_hellow_world.s ASM_TEST_DIR=/path/to/dir + `$RV_ROOT/configs/swerv.config [configuration options..] -snapshot=mybuild` + + Snapshots are placed in `$BUILD_PATH` directory + + +1. Running a simple Hello World program (verilator) + + `make -f $RV_ROOT/tools/Makefile` + +This command will build a verilator model of SweRV EH1 with AXI bus, and +execute a short sequence of instructions that writes out "HELLO WORLD" +to the bus. + + +The simulation produces output on the screen like: + +```` +VerilatorTB: Start of sim + +---------------------------------- +Hello World from SweRV EH1 @WDC !! +---------------------------------- + +Finished : minstret = 443, mcycle = 1372 +See "exec.log" for execution trace with register updates.. + +TEST_PASSED +```` + +The simulation generates following files: + + `console.log` contains what the cpu writes to the console address of 0xd0580000. + `exec.log` shows instruction trace with GPR updates. + `trace_port.csv` contains a log of the trace port. + When `debug=1` is provided, a vcd file `sim.vcd` is created and can be browsed by + gtkwave or similar waveform viewers. + +You can re-execute simulation using: + ` ./obj_dir/Vtb_top ` +or + `make -f $RV_ROOT/tools/Makefile verilator` + + + +The simulation run/build command has following generic form: + +``` +make -f $RV_ROOT/tools/Makefile [] [debug=1] [snapshot=] [target=] [TEST=] [TEST_DIR=] [CONF_PARAMS=] + +where: + + - can be 'verilator' (by default) 'irun' - Cadence xrun, 'vcs' - Synopsys VCS, 'vlog' Mentor Questa + if not provided, 'make' cleans work directory, builds verilator executable and runs a test. +debug=1 - allows VCD generation for verilator and VCS and SHM waves for irun option. + - predefined CPU configurations 'default' ( by default), 'default_ahb', 'default_pd', 'high_perf' +TEST - allows to run a C (.c) or assembly (.s) test, hello_world is run by default +TEST_DIR - alternative to test source directory testbench/asm + - run and build executable model of custom CPU configuration, remember to provide 'snapshot' argument + for runs on custom configurations. +CONF_PARAMS - configuration parameter for swerv.config : ex: 'CONF_PARAMS=-unset=dccm_enable' to build with no DCCM +``` + +Example: + + make -f $RV_ROOT/tools/Makefile verilator TEST=cmark + +will simulate testbench/asm/cmark.c program with verilator on default target + + +If you want to compile a test only, you can run: + + make -f $RV_ROOT/tools/Makefile program.hex TEST= [TEST_DIR=/path/to/dir] + + +The Makefile uses `$RV_ROOT/testbench/link.ld` file by default to build test executable. +User can provide test specific linker file in form `.ld` to build the test executable, + in the same directory with the test source. + +User also can create a test specific makefile in form `.makefile`, contaning building instructions +how to create `program.hex`, `data.hex` files used by simulation. The private makefile should be in the same directory +as the test source. +*(`program.hex` file is loaded to instruction bus memory slave and `data.hex` file is loaded to LSU bus memory slave and +optionally to DCCM at the beginning of simulation)*. + +Note: You may need to delete `program.hex` file from work directory, when run a new test. + +The `$RV_ROOT/testbench/asm` directory contains following tests ready to simulate: + +``` +hello_world - default test to run, prints Hello World message to screen and console.log +hello_world_dccm - the same as above, but takes the string from preloaded DCCM. +cmark - coremark benchmark running with code and data in external memories +cmark_dccm - the same as above, running data and stack from DCCM (faster) +cmark_iccm - the same as above, but with code preloaded to iccm - runs only on CPU with ICCM + use CONF_PARAMS=-set=iccm_enable argument to `make` to build CPU with ICCM +``` + +The `$RV_ROOT/testbench/hex` directory contains precompiled hex files of the tests, ready for simulation in case RISCV SW tools are not installed. -If you change only the assembly files, you do not need to rebuild verilator, just specify the target as `program.hex` : - make -f $RV_ROOT/tools/Makefile program.hex ASM_TEST=my_hello_world.s ASM_TEST_DIR=/path/to/dir - ./obj_dir/Vtb_top -### SweRV CoreMark Benchmarking -We ran [CoreMark](https://www.eembc.org/coremark/) benchmark on Nexys4 board and achieved CoreMark score of **4.94**. Please see the [document](https://github.com/chipsalliance/Cores-SweRV/blob/master/docs/SweRV_CoreMark_Benchmarking.pdf) for details. ---- -Western Digital, the Western Digital logo, G-Technology, SanDisk, Tegile, Upthere, WD, SweRV Core, SweRV ISS, and OmniXtend are registered trademarks or trademarks of Western Digital Corporation or its affiliates in the US and/or other countries. All other marks are the property of their respective owners. +Western Digital, the Western Digital logo, G-Technology, SanDisk, Tegile, Upthere, WD, SweRV Core, SweRV ISS, +and OmniXtend are registered trademarks or trademarks of Western Digital Corporation or its affiliates in the US +and/or other countries. All other marks are the property of their respective owners. diff --git a/configs/README.md b/configs/README.md index 7496944..e5d2a58 100644 --- a/configs/README.md +++ b/configs/README.md @@ -8,7 +8,9 @@ Name | Description swerv.config | Configuration script for SweRV -This script will generate a consistent st of `defines/#defines needed for the design and testbench. +This script will generate a consistent set of `defines/#defines needed for the design and testbench. A perl hash (*perl_configs.pl*) and a JSON format for SweRV-iss are also generated. -While the defines fines may be modified by hand, it is recommended that this script be used to generate a consistent set. +`$RV_ROOT/configs/swerv.config -h` will provide options for the script. + +While the defines files may be modified by hand, it is recommended that this script be used to generate a consistent set. diff --git a/configs/swerv.config b/configs/swerv.config index 16cfb6e..20c409d 100755 --- a/configs/swerv.config +++ b/configs/swerv.config @@ -2,13 +2,13 @@ # # 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. @@ -36,7 +36,7 @@ my @argv_orig = @ARGV; # Default values and valid ranges should be specified # Can be overridden via the cmd line (-set=name=value-string) # -# Format of the hash is +# Format of the hash is # name => VALUE | LIST | HASH # # Special name "inside" followed by list .. values must be one of provided list @@ -82,7 +82,7 @@ my @unsets = (); # : multiple -set/-unset options accepted\n\n"; # -$helpusage = " +my $helpusage = " Main configuration database for SWERV @@ -91,7 +91,7 @@ This script documents, and generates the {`#} define/include files for verilog/a User options: - -target = { default, generic } + -target = { default, default_ahb, default_pd, high_perf} use default settings for one of the targets -set=var=value @@ -145,7 +145,7 @@ Direct options for the following parameters exist: size of PIC -pic_total_int = { 1, 2, 3, ..., 255 } number of interrupt sources in PIC - -ahb_lite + -ahb_lite build with AHB-lite bus interface default is AXI4 -fpga_optimize = { 0, 1 } @@ -179,7 +179,7 @@ my $top_align_iccm = 0; my $target = "default"; my $snapshot ; my $build_path ; - + GetOptions( "help" => \$help, "target=s" => \$target, @@ -188,21 +188,21 @@ GetOptions( "ret_stack_size=s" => \$ret_stack_size, "btb_size=s" => \$btb_size, "bht_size=s" => \$bht_size, - "dccm_enable=s" => \$dccm_enable, - "dccm_region=s" => \$dccm_region, - "dccm_offset=s" => \$dccm_offset, - "dccm_size=s" => \$dccm_size, - "iccm_enable=s" => \$iccm_enable, - "icache_enable=s" => \$icache_enable, - "icache_ecc=s" => \$icache_ecc, - "iccm_region=s" => \$iccm_region, - "iccm_offset=s" => \$iccm_offset, - "iccm_size=s" => \$iccm_size, - "pic_2cycle=s" => \$pic_2cycle, - "pic_region=s" => \$pic_region, - "pic_offset=s" => \$pic_offset, - "pic_size=s" => \$pic_size, - "pic_total_int=s" => \$pic_total_int, + "dccm_enable=s" => \$dccm_enable, + "dccm_region=s" => \$dccm_region, + "dccm_offset=s" => \$dccm_offset, + "dccm_size=s" => \$dccm_size, + "iccm_enable=s" => \$iccm_enable, + "icache_enable=s" => \$icache_enable, + "icache_ecc=s" => \$icache_ecc, + "iccm_region=s" => \$iccm_region, + "iccm_offset=s" => \$iccm_offset, + "iccm_size=s" => \$iccm_size, + "pic_2cycle=s" => \$pic_2cycle, + "pic_region=s" => \$pic_region, + "pic_offset=s" => \$pic_offset, + "pic_size=s" => \$pic_size, + "pic_total_int=s" => \$pic_total_int, "icache_size=s" => \$icache_size, "ahb_lite" => \$ahb_lite, "fpga_optimize" => \$fpga_optimize, @@ -246,90 +246,135 @@ my $perlfile = "$build_path/perl_configs.pl"; my $no_secondary_alu=0; -if ($target eq "generic") { - print "$self: Using target \"generic\"\n"; - if (!defined($ret_stack_size)) { $ret_stack_size=4; } - if (!defined($btb_size)) { $btb_size=32; } - if (!defined($bht_size)) { $bht_size=128; } - if (!defined($dccm_enable)) { $dccm_enable=1; } - if (!defined($dccm_region)) { $dccm_region="0xf"; } - if (!defined($dccm_offset)) { $dccm_offset="0x80000"; } #1*256*1024 - if (!defined($dccm_size)) { $dccm_size=512; } - if (!defined($dccm_num_banks)) { $dccm_num_banks=8; } - if (!defined($iccm_enable)) { $iccm_enable=1; } - if (!defined($iccm_region)) { $iccm_region="0xe"; } - if (!defined($iccm_offset)) { $iccm_offset="0xe000000"; } #0x380*256*1024 - if (!defined($iccm_size)) { $iccm_size=512; } - if (!defined($iccm_num_banks)) { $iccm_num_banks=8; } - if (!defined($icache_enable)) { $icache_enable=0; } - if (!defined($icache_ecc)) { $icache_ecc=0; } - if (!defined($icache_size)) { $icache_size=16; } - if (!defined($pic_2cycle)) { $pic_2cycle=0; } - if (!defined($pic_region)) { $pic_region="0xf"; } - if (!defined($pic_offset)) { $pic_offset="0x100000"; } # 3*256*1024 - if (!defined($pic_size)) { $pic_size=32; } - if (!defined($pic_total_int)) { $pic_total_int=8; } - if (!defined($dec_instbuf_depth)) { $dec_instbuf_depth=2; } -} -elsif ($target eq "default") { - if (!defined($ret_stack_size)) { $ret_stack_size=4; } - if (!defined($btb_size)) { $btb_size=32; } - if (!defined($bht_size)) { $bht_size=128; } - if (!defined($dccm_enable)) { $dccm_enable=1; } - if (!defined($dccm_region)) { $dccm_region="0xf"; } +if ($target eq "default") { + if (!defined($ret_stack_size)) { $ret_stack_size=4; } + if (!defined($btb_size)) { $btb_size=32; } + if (!defined($bht_size)) { $bht_size=128; } + if (!defined($dccm_enable)) { $dccm_enable=1; } + if (!defined($dccm_region)) { $dccm_region="0xf"; } if (!defined($dccm_offset)) { $dccm_offset="0x40000"; } #1*256*1024 - if (!defined($dccm_size)) { $dccm_size=64; } - if (!defined($dccm_num_banks)) { $dccm_num_banks=8; } - if (!defined($iccm_enable)) { $iccm_enable=0; } - if (!defined($iccm_region)) { $iccm_region="0xe"; } + if (!defined($dccm_size)) { $dccm_size=64; } + if (!defined($dccm_num_banks)) { $dccm_num_banks=8; } + if (!defined($iccm_enable)) { $iccm_enable=0; } + if (!defined($iccm_region)) { $iccm_region="0xe"; } if (!defined($iccm_offset)) { $iccm_offset="0xe000000"; } #0x380*256*1024 - if (!defined($iccm_size)) { $iccm_size=512; } - if (!defined($iccm_num_banks)) { $iccm_num_banks=8; } - if (!defined($icache_enable)) { $icache_enable=1; } - if (!defined($icache_ecc)) { $icache_ecc=0; } - if (!defined($icache_size)) { $icache_size=16; } - if (!defined($pic_2cycle)) { $pic_2cycle=0; } - if (!defined($pic_region)) { $pic_region="0xf"; } + if (!defined($iccm_size)) { $iccm_size=512; } + if (!defined($iccm_num_banks)) { $iccm_num_banks=8; } + if (!defined($icache_enable)) { $icache_enable=1; } + if (!defined($icache_ecc)) { $icache_ecc=0; } + if (!defined($icache_size)) { $icache_size=16; } + if (!defined($pic_2cycle)) { $pic_2cycle=0; } + if (!defined($pic_region)) { $pic_region="0xf"; } if (!defined($pic_offset)) { $pic_offset="0xc0000"; } # 3*256*1024 - if (!defined($pic_size)) { $pic_size=32; } - if (!defined($pic_total_int)) { $pic_total_int=8; } + if (!defined($pic_size)) { $pic_size=32; } + if (!defined($pic_total_int)) { $pic_total_int=8; } # default is AXI bus } -else { - die "$self: ERROR! Unsupported target \"$target\". Supported targets are: \"default,generic\"!\n"; +elsif ($target eq "default_ahb") { + if (!defined($ret_stack_size)) { $ret_stack_size=4; } + if (!defined($btb_size)) { $btb_size=32; } + if (!defined($bht_size)) { $bht_size=128; } + if (!defined($dccm_enable)) { $dccm_enable=1; } + if (!defined($dccm_region)) { $dccm_region="0xf"; } + if (!defined($dccm_offset)) { $dccm_offset="0x40000"; } #1*256*1024 + if (!defined($dccm_size)) { $dccm_size=64; } + if (!defined($dccm_num_banks)) { $dccm_num_banks=8; } + if (!defined($iccm_enable)) { $iccm_enable=0; } + if (!defined($iccm_region)) { $iccm_region="0xe"; } + if (!defined($iccm_offset)) { $iccm_offset="0xe000000"; } #0x380*256*1024 + if (!defined($iccm_size)) { $iccm_size=512; } + if (!defined($iccm_num_banks)) { $iccm_num_banks=8; } + if (!defined($icache_enable)) { $icache_enable=1; } + if (!defined($icache_ecc)) { $icache_ecc=0; } + if (!defined($icache_size)) { $icache_size=16; } + if (!defined($pic_2cycle)) { $pic_2cycle=0; } + if (!defined($pic_region)) { $pic_region="0xf"; } + if (!defined($pic_offset)) { $pic_offset="0xc0000"; } # 3*256*1024 + if (!defined($pic_size)) { $pic_size=32; } + if (!defined($pic_total_int)) { $pic_total_int=8; } + $ahb_lite = 1; + +} elsif ($target eq "default_pd") { + if (!defined($ret_stack_size)) { $ret_stack_size=4; } + if (!defined($btb_size)) { $btb_size=32; } + if (!defined($bht_size)) { $bht_size=128; } + if (!defined($dccm_enable)) { $dccm_enable=1; } + if (!defined($dccm_region)) { $dccm_region="0xf"; } + if (!defined($dccm_offset)) { $dccm_offset="0x40000"; } #1*256*1024 + if (!defined($dccm_size)) { $dccm_size=32; } + if (!defined($dccm_num_banks)) { $dccm_num_banks=8; } + if (!defined($iccm_enable)) { $iccm_enable=0; } + if (!defined($iccm_region)) { $iccm_region="0xe"; } + if (!defined($iccm_offset)) { $iccm_offset="0xe000000"; } #0x380*256*1024 + if (!defined($iccm_size)) { $iccm_size=512; } + if (!defined($iccm_num_banks)) { $iccm_num_banks=8; } + if (!defined($icache_enable)) { $icache_enable=1; } + if (!defined($icache_ecc)) { $icache_ecc=0; } + if (!defined($icache_size)) { $icache_size=16; } + if (!defined($pic_2cycle)) { $pic_2cycle=0; } + if (!defined($pic_region)) { $pic_region="0xf"; } + if (!defined($pic_offset)) { $pic_offset="0xc0000"; } # 3*256*1024 + if (!defined($pic_size)) { $pic_size=32; } + if (!defined($pic_total_int)) { $pic_total_int=8; } + +} elsif ($target eq "high_perf") { + if (!defined($ret_stack_size)) { $ret_stack_size=4; } + if (!defined($btb_size)) { $btb_size=512; } + if (!defined($bht_size)) { $bht_size=2048; } + if (!defined($dccm_enable)) { $dccm_enable=1; } + if (!defined($dccm_region)) { $dccm_region="0xf"; } + if (!defined($dccm_offset)) { $dccm_offset="0x40000"; } #1*256*1024 + if (!defined($dccm_size)) { $dccm_size=64; } + if (!defined($dccm_num_banks)) { $dccm_num_banks=8; } + if (!defined($iccm_enable)) { $iccm_enable=0; } + if (!defined($iccm_region)) { $iccm_region="0xe"; } + if (!defined($iccm_offset)) { $iccm_offset="0xe000000"; } #0x380*256*1024 + if (!defined($iccm_size)) { $iccm_size=512; } + if (!defined($iccm_num_banks)) { $iccm_num_banks=8; } + if (!defined($icache_enable)) { $icache_enable=1; } + if (!defined($icache_ecc)) { $icache_ecc=0; } + if (!defined($icache_size)) { $icache_size=32; } + if (!defined($pic_2cycle)) { $pic_2cycle=0; } + if (!defined($pic_region)) { $pic_region="0xf"; } + if (!defined($pic_offset)) { $pic_offset="0xc0000"; } # 3*256*1024 + if (!defined($pic_size)) { $pic_size=32; } + if (!defined($pic_total_int)) { $pic_total_int=8; } + +} else { + die "$self: ERROR! Unsupported target \"$target\". Supported targets are: \"default, default_ahb, default_pd, high_perf\"!\n"; } # general stuff - can't set from command line other than -set -if (!defined($lsu_stbuf_depth)) { $lsu_stbuf_depth=8; } -if (!defined($dma_buf_depth)) { $dma_buf_depth=4; } -if (!defined($lsu_num_nbload)) { $lsu_num_nbload=8; } -if (!defined($dec_instbuf_depth)) { $dec_instbuf_depth=4; } +if (!defined($lsu_stbuf_depth)) { $lsu_stbuf_depth=8; } +if (!defined($dma_buf_depth)) { $dma_buf_depth=4; } +if (!defined($lsu_num_nbload)) { $lsu_num_nbload=8; } +if (!defined($dec_instbuf_depth)) { $dec_instbuf_depth=4; } # Configure triggers our @triggers = (#{{{ { - "reset" => ["0x23e00000", "0x00000000", "0x00000000"], - "mask" => ["0x081818c7", "0xffffffff", "0x00000000"], - "poke_mask" => ["0x081818c7", "0xffffffff", "0x00000000"] - }, - { - "reset" => ["0x23e00000", "0x00000000", "0x00000000"], + "reset" => ["0x23e00000", "0x00000000", "0x00000000"], "mask" => ["0x081818c7", "0xffffffff", "0x00000000"], "poke_mask" => ["0x081818c7", "0xffffffff", "0x00000000"] - }, + }, { - "reset" => ["0x23e00000", "0x00000000", "0x00000000"], + "reset" => ["0x23e00000", "0x00000000", "0x00000000"], "mask" => ["0x081818c7", "0xffffffff", "0x00000000"], - "poke_mask" => ["0x081818c7", "0xffffffff", "0x00000000"] - }, + "poke_mask" => ["0x081818c7", "0xffffffff", "0x00000000"] + }, { - "reset" => ["0x23e00000", "0x00000000", "0x00000000"], + "reset" => ["0x23e00000", "0x00000000", "0x00000000"], "mask" => ["0x081818c7", "0xffffffff", "0x00000000"], - "poke_mask" => ["0x081818c7", "0xffffffff", "0x00000000"] - }, + "poke_mask" => ["0x081818c7", "0xffffffff", "0x00000000"] + }, + { + "reset" => ["0x23e00000", "0x00000000", "0x00000000"], + "mask" => ["0x081818c7", "0xffffffff", "0x00000000"], + "poke_mask" => ["0x081818c7", "0xffffffff", "0x00000000"] + }, );#}}} @@ -342,18 +387,18 @@ our %csr = (#{{{ }, "mie" => { "reset" => "0x0", - # Only external, timer, local, and software writeable - "mask" => "0x40000888", - "exists" => "true", + # Only external, timer, local, and software writeable + "mask" => "0x40000888", + "exists" => "true", }, "mip" => { - "reset" => "0x0", - # None of the bits are writeable using CSR instructions + "reset" => "0x0", + # None of the bits are writeable using CSR instructions "mask" => "0x0", - # Bits corresponding to error overflow, external, timer and stoftware - # interrupts are modifiable - "poke_mask" => "0x40000888", - "exists" => "true", + # Bits corresponding to error overflow, external, timer and stoftware + # interrupts are modifiable + "poke_mask" => "0x40000888", + "exists" => "true", }, "mvendorid" => { "reset" => "0x45", @@ -366,7 +411,7 @@ our %csr = (#{{{ "exists" => "true", }, "mimpid" => { - "reset" => "0x1", + "reset" => "0x2", "mask" => "0x0", "exists" => "true", }, @@ -387,13 +432,13 @@ our %csr = (#{{{ "exists" => "true", }, "cycle" => { - "exists" => "false", + "exists" => "false", }, "time" => { - "exists" => "false", + "exists" => "false", }, "instret" => { - "exists" => "false", + "exists" => "false", }, "mhpmcounter3" => { "reset" => "0x0", @@ -625,10 +670,10 @@ our %config = (#{{{ "max_mmode_perf_event" => "50", # Whisper only: performance counters event ids will be clamped to this "target" => $target, "tec_rv_icg" => "clockhdr", - "verilator" => "$verilator", + "verilator" => "$verilator", "retstack" => { - "ret_stack_size" => "$ret_stack_size", + "ret_stack_size" => "$ret_stack_size", }, "btb" => { @@ -653,18 +698,18 @@ our %config = (#{{{ "bht_ghr_range" => "derived", "bht_ghr_pad" => "derived", "bht_ghr_pad2" => "derived", - "bht_hash_string" => "derived", + "bht_hash_string" => "derived", }, "core" => { - "dec_instbuf_depth" => "$dec_instbuf_depth", - "lsu_stbuf_depth" => "$lsu_stbuf_depth", - "dma_buf_depth" => "$dma_buf_depth", - "lsu_num_nbload" => "$lsu_num_nbload", - "no_secondary_alu" => "$no_secondary_alu", - "fpga_optimize" => "$fpga_optimize" - }, + "dec_instbuf_depth" => "$dec_instbuf_depth", + "lsu_stbuf_depth" => "$lsu_stbuf_depth", + "dma_buf_depth" => "$dma_buf_depth", + "lsu_num_nbload" => "$lsu_num_nbload", + "no_secondary_alu" => "$no_secondary_alu", + "fpga_optimize" => "$fpga_optimize" + }, "dccm" => { "dccm_enable" => "$dccm_enable", # Comment this out if no DCCM @@ -686,7 +731,7 @@ our %config = (#{{{ "dccm_data_cell" => 'derived', "dccm_rows" => 'derived', "dccm_reserved" => 'derived', # reserve dccm space for SW/stack - no random r/w - }, + }, "iccm" => { @@ -694,28 +739,28 @@ our %config = (#{{{ "iccm_region" => "$iccm_region", # 256M region number "iccm_offset" => "$iccm_offset", # 256K offset number "iccm_size" => "$iccm_size", # Size in Kbytes - "iccm_num_banks" => "$iccm_num_banks", - "iccm_bank_bits" => 'derived', + "iccm_num_banks" => "$iccm_num_banks", + "iccm_bank_bits" => 'derived', "iccm_index_bits" => 'derived', - "iccm_rows" => 'derived', + "iccm_rows" => 'derived', "iccm_data_cell" => 'derived', "iccm_sadr" => 'derived', "iccm_eadr" => 'derived', "iccm_reserved" => 'derived', # reserve iccm space for SW/handlers - no random r/w }, "icache" => { - "icache_enable" => "$icache_enable", + "icache_enable" => "$icache_enable", "icache_size" => "$icache_size", - "icache_data_cell" => 'derived', - "icache_tag_cell" => 'derived', - "icache_taddr_high" => 'derived', - "icache_tag_high" => 'derived', - "icache_tag_depth" => 'derived', - "icache_ic_depth" => 'derived', - "icache_ic_rows" => 'derived', + "icache_data_cell" => 'derived', + "icache_tag_cell" => 'derived', + "icache_taddr_high" => 'derived', + "icache_tag_high" => 'derived', + "icache_tag_depth" => 'derived', + "icache_ic_depth" => 'derived', + "icache_ic_rows" => 'derived', "icache_ic_index" => 'derived', - "icache_tag_low" => '6', - "icache_ecc" => "$icache_ecc", + "icache_tag_low" => '6', + "icache_ecc" => "$icache_ecc", }, "pic" => { "pic_2cycle" => "$pic_2cycle", # two cycle PIC for timing reasons @@ -728,21 +773,21 @@ our %config = (#{{{ "pic_int_words" => 'derived', # number of 32 bit words for packed registers (Xmax) "pic_bits" => 'derived', # of bits needs to address the PICM "pic_meipl_offset" => '0x0000', # Offset of meipl relative to pic_base_addr - "pic_meip_offset" => '0x1000', # Offset of meip relative to pic_base_addr - "pic_meie_offset" => '0x2000', # Offset of meie relative to pic_base_addr - "pic_mpiccfg_offset" => '0x3000', # Offset of mpiccfg relative to pic_base_addr + "pic_meip_offset" => '0x1000', # Offset of meip relative to pic_base_addr + "pic_meie_offset" => '0x2000', # Offset of meie relative to pic_base_addr + "pic_mpiccfg_offset" => '0x3000', # Offset of mpiccfg relative to pic_base_addr "pic_meipt_offset" => '0x3004', # Offset of meipt relative to pic_base_addr -- deprecated - "pic_meigwctrl_offset" => '0x4000', # gateway control regs relative to pic_base_addr - "pic_meigwclr_offset" => '0x5000' # gateway clear regs relative to pic_base_addr + "pic_meigwctrl_offset" => '0x4000', # gateway control regs relative to pic_base_addr + "pic_meigwclr_offset" => '0x5000' # gateway clear regs relative to pic_base_addr - }, + }, "testbench" => { "TOP" => "tb_top", "RV_TOP" => "`TOP.rvtop", "CPU_TOP" => "`RV_TOP.swerv", "clock_period" => "100", "build_ahb_lite" => "$ahb_lite", # one and only one bus build arg will ever be defined - "build_axi4" => "", + "build_axi4" => "1", "assert_on" => "", "datawidth" => "64", # deprecate this !! FIXME "ext_datawidth" => "64", @@ -752,54 +797,54 @@ our %config = (#{{{ "SDVT_AHB" => "1", }, "protection" => { - "inst_access_enable0" => "0x0", - "inst_access_addr0" => "0x00000000", - "inst_access_mask0" => "0xffffffff", - "inst_access_enable1" => "0x0", - "inst_access_addr1" => "0x00000000", - "inst_access_mask1" => "0xffffffff", - "inst_access_enable2" => "0x0", - "inst_access_addr2" => "0x00000000", - "inst_access_mask2" => "0xffffffff", - "inst_access_enable3" => "0x0", - "inst_access_addr3" => "0x00000000", - "inst_access_mask3" => "0xffffffff", - "inst_access_enable4" => "0x0", - "inst_access_addr4" => "0x00000000", - "inst_access_mask4" => "0xffffffff", - "inst_access_enable5" => "0x0", - "inst_access_addr5" => "0x00000000", - "inst_access_mask5" => "0xffffffff", - "inst_access_enable6" => "0x0", - "inst_access_addr6" => "0x00000000", - "inst_access_mask6" => "0xffffffff", - "inst_access_enable7" => "0x0", - "inst_access_addr7" => "0x00000000", - "inst_access_mask7" => "0xffffffff", - "data_access_enable0" => "0x0", - "data_access_addr0" => "0x00000000", - "data_access_mask0" => "0xffffffff", - "data_access_enable1" => "0x0", - "data_access_addr1" => "0x00000000", - "data_access_mask1" => "0xffffffff", - "data_access_enable2" => "0x0", - "data_access_addr2" => "0x00000000", - "data_access_mask2" => "0xffffffff", - "data_access_enable3" => "0x0", - "data_access_addr3" => "0x00000000", - "data_access_mask3" => "0xffffffff", - "data_access_enable4" => "0x0", - "data_access_addr4" => "0x00000000", - "data_access_mask4" => "0xffffffff", - "data_access_enable5" => "0x0", - "data_access_addr5" => "0x00000000", - "data_access_mask5" => "0xffffffff", - "data_access_enable6" => "0x0", - "data_access_addr6" => "0x00000000", - "data_access_mask6" => "0xffffffff", - "data_access_enable7" => "0x0", - "data_access_addr7" => "0x00000000", - "data_access_mask7" => "0xffffffff", + "inst_access_enable0" => "0x0", + "inst_access_addr0" => "0x00000000", + "inst_access_mask0" => "0xffffffff", + "inst_access_enable1" => "0x0", + "inst_access_addr1" => "0x00000000", + "inst_access_mask1" => "0xffffffff", + "inst_access_enable2" => "0x0", + "inst_access_addr2" => "0x00000000", + "inst_access_mask2" => "0xffffffff", + "inst_access_enable3" => "0x0", + "inst_access_addr3" => "0x00000000", + "inst_access_mask3" => "0xffffffff", + "inst_access_enable4" => "0x0", + "inst_access_addr4" => "0x00000000", + "inst_access_mask4" => "0xffffffff", + "inst_access_enable5" => "0x0", + "inst_access_addr5" => "0x00000000", + "inst_access_mask5" => "0xffffffff", + "inst_access_enable6" => "0x0", + "inst_access_addr6" => "0x00000000", + "inst_access_mask6" => "0xffffffff", + "inst_access_enable7" => "0x0", + "inst_access_addr7" => "0x00000000", + "inst_access_mask7" => "0xffffffff", + "data_access_enable0" => "0x0", + "data_access_addr0" => "0x00000000", + "data_access_mask0" => "0xffffffff", + "data_access_enable1" => "0x0", + "data_access_addr1" => "0x00000000", + "data_access_mask1" => "0xffffffff", + "data_access_enable2" => "0x0", + "data_access_addr2" => "0x00000000", + "data_access_mask2" => "0xffffffff", + "data_access_enable3" => "0x0", + "data_access_addr3" => "0x00000000", + "data_access_mask3" => "0xffffffff", + "data_access_enable4" => "0x0", + "data_access_addr4" => "0x00000000", + "data_access_mask4" => "0xffffffff", + "data_access_enable5" => "0x0", + "data_access_addr5" => "0x00000000", + "data_access_mask5" => "0xffffffff", + "data_access_enable6" => "0x0", + "data_access_addr6" => "0x00000000", + "data_access_mask6" => "0xffffffff", + "data_access_enable7" => "0x0", + "data_access_addr7" => "0x00000000", + "data_access_mask7" => "0xffffffff", }, "memmap" => { "serialio" => 'derived, overridable', @@ -807,7 +852,7 @@ our %config = (#{{{ "external_prog" => 'derived, overridable', "debug_sb_mem" => 'derived, overridable', "external_data_1" => 'derived, overridable', -# "consoleio" => 'derived', # Part of serial io. +# "consoleio" => 'derived', # Part of serial io. }, "bus" => { "lsu_bus_tag" => 'derived', @@ -817,7 +862,7 @@ our %config = (#{{{ }, "triggers" => \@triggers, "csr" => \%csr, - "even_odd_trigger_chains" => "true", + "even_odd_trigger_chains" => "true", ); if (($fpga_optimize==0) && !grep(/fpga_optimize/, @sets)) { delete $config{"core"}{"fpga_optimize"}; } @@ -862,42 +907,42 @@ $c=$config{core}{lsu_stbuf_depth}; if (!($c==2 || $c==4 || $c==8)) $c=$config{core}{dma_buf_depth}; if (!($c==2 || $c==4)) { die("$helpusage\n\nFAIL: dma_buf_depth == $c ILLEGAL !!!\n\n"); } $c=$config{core}{lsu_num_nbload}; if (!($c==2 || $c==4 || $c==8)) { die("$helpusage\n\nFAIL: lsu_num_nbload == $c ILLEGAL !!!\n\n"); } -$c=$config{protection}{inst_access_addr0}; if ((hex($c)&0x3f) != 0) { die("$helpusage\n\nFAIL: inst_access_addr0 lower 6b must be 0s $c !!!\n\n"); } -$c=$config{protection}{inst_access_addr1}; if ((hex($c)&0x3f) != 0) { die("$helpusage\n\nFAIL: inst_access_addr1 lower 6b must be 0s !!!\n\n"); } -$c=$config{protection}{inst_access_addr2}; if ((hex($c)&0x3f) != 0) { die("$helpusage\n\nFAIL: inst_access_addr2 lower 6b must be 0s !!!\n\n"); } -$c=$config{protection}{inst_access_addr3}; if ((hex($c)&0x3f) != 0) { die("$helpusage\n\nFAIL: inst_access_addr3 lower 6b must be 0s !!!\n\n"); } -$c=$config{protection}{inst_access_addr4}; if ((hex($c)&0x3f) != 0) { die("$helpusage\n\nFAIL: inst_access_addr4 lower 6b must be 0s !!!\n\n"); } -$c=$config{protection}{inst_access_addr5}; if ((hex($c)&0x3f) != 0) { die("$helpusage\n\nFAIL: inst_access_addr5 lower 6b must be 0s !!!\n\n"); } -$c=$config{protection}{inst_access_addr6}; if ((hex($c)&0x3f) != 0) { die("$helpusage\n\nFAIL: inst_access_addr6 lower 6b must be 0s !!!\n\n"); } -$c=$config{protection}{inst_access_addr7}; if ((hex($c)&0x3f) != 0) { die("$helpusage\n\nFAIL: inst_access_addr7 lower 6b must be 0s !!!\n\n"); } -$c=$config{protection}{inst_access_mask0}; if ((hex($c)&0x3f) != 63) { die("$helpusage\n\nFAIL: inst_access_mask0 lower 6b must be 1s !!!\n\n"); } -$c=$config{protection}{inst_access_mask1}; if ((hex($c)&0x3f) != 63) { die("$helpusage\n\nFAIL: inst_access_mask1 lower 6b must be 1s !!!\n\n"); } -$c=$config{protection}{inst_access_mask2}; if ((hex($c)&0x3f) != 63) { die("$helpusage\n\nFAIL: inst_access_mask2 lower 6b must be 1s !!!\n\n"); } -$c=$config{protection}{inst_access_mask3}; if ((hex($c)&0x3f) != 63) { die("$helpusage\n\nFAIL: inst_access_mask3 lower 6b must be 1s !!!\n\n"); } -$c=$config{protection}{inst_access_mask4}; if ((hex($c)&0x3f) != 63) { die("$helpusage\n\nFAIL: inst_access_mask4 lower 6b must be 1s !!!\n\n"); } -$c=$config{protection}{inst_access_mask5}; if ((hex($c)&0x3f) != 63) { die("$helpusage\n\nFAIL: inst_access_mask5 lower 6b must be 1s !!!\n\n"); } -$c=$config{protection}{inst_access_mask6}; if ((hex($c)&0x3f) != 63) { die("$helpusage\n\nFAIL: inst_access_mask6 lower 6b must be 1s !!!\n\n"); } -$c=$config{protection}{inst_access_mask7}; if ((hex($c)&0x3f) != 63) { die("$helpusage\n\nFAIL: inst_access_mask7 lower 6b must be 1s !!!\n\n"); } -$c=$config{protection}{data_access_addr0}; if ((hex($c)&0x3f) != 0) { die("$helpusage\n\nFAIL: data_access_addr0 lower 6b must be 0s !!!\n\n"); } -$c=$config{protection}{data_access_addr1}; if ((hex($c)&0x3f) != 0) { die("$helpusage\n\nFAIL: data_access_addr1 lower 6b must be 0s !!!\n\n"); } -$c=$config{protection}{data_access_addr2}; if ((hex($c)&0x3f) != 0) { die("$helpusage\n\nFAIL: data_access_addr2 lower 6b must be 0s !!!\n\n"); } -$c=$config{protection}{data_access_addr3}; if ((hex($c)&0x3f) != 0) { die("$helpusage\n\nFAIL: data_access_addr3 lower 6b must be 0s !!!\n\n"); } -$c=$config{protection}{data_access_addr4}; if ((hex($c)&0x3f) != 0) { die("$helpusage\n\nFAIL: data_access_addr4 lower 6b must be 0s !!!\n\n"); } -$c=$config{protection}{data_access_addr5}; if ((hex($c)&0x3f) != 0) { die("$helpusage\n\nFAIL: data_access_addr5 lower 6b must be 0s !!!\n\n"); } -$c=$config{protection}{data_access_addr6}; if ((hex($c)&0x3f) != 0) { die("$helpusage\n\nFAIL: data_access_addr6 lower 6b must be 0s !!!\n\n"); } -$c=$config{protection}{data_access_addr7}; if ((hex($c)&0x3f) != 0) { die("$helpusage\n\nFAIL: data_access_addr7 lower 6b must be 0s !!!\n\n"); } -$c=$config{protection}{data_access_mask0}; if ((hex($c)&0x3f) != 63) { die("$helpusage\n\nFAIL: data_access_mask0 lower 6b must be 1s !!!\n\n"); } -$c=$config{protection}{data_access_mask1}; if ((hex($c)&0x3f) != 63) { die("$helpusage\n\nFAIL: data_access_mask1 lower 6b must be 1s !!!\n\n"); } -$c=$config{protection}{data_access_mask2}; if ((hex($c)&0x3f) != 63) { die("$helpusage\n\nFAIL: data_access_mask2 lower 6b must be 1s !!!\n\n"); } -$c=$config{protection}{data_access_mask3}; if ((hex($c)&0x3f) != 63) { die("$helpusage\n\nFAIL: data_access_mask3 lower 6b must be 1s !!!\n\n"); } -$c=$config{protection}{data_access_mask4}; if ((hex($c)&0x3f) != 63) { die("$helpusage\n\nFAIL: data_access_mask4 lower 6b must be 1s !!!\n\n"); } -$c=$config{protection}{data_access_mask5}; if ((hex($c)&0x3f) != 63) { die("$helpusage\n\nFAIL: data_access_mask5 lower 6b must be 1s !!!\n\n"); } -$c=$config{protection}{data_access_mask6}; if ((hex($c)&0x3f) != 63) { die("$helpusage\n\nFAIL: data_access_mask6 lower 6b must be 1s !!!\n\n"); } -$c=$config{protection}{data_access_mask7}; if ((hex($c)&0x3f) != 63) { die("$helpusage\n\nFAIL: data_access_mask7 lower 6b must be 1s !!!\n\n"); } +$c=$config{protection}{inst_access_addr0}; if ((hex($c)&0x3f) != 0) { die("$helpusage\n\nFAIL: inst_access_addr0 lower 6b must be 0s $c !!!\n\n"); } +$c=$config{protection}{inst_access_addr1}; if ((hex($c)&0x3f) != 0) { die("$helpusage\n\nFAIL: inst_access_addr1 lower 6b must be 0s !!!\n\n"); } +$c=$config{protection}{inst_access_addr2}; if ((hex($c)&0x3f) != 0) { die("$helpusage\n\nFAIL: inst_access_addr2 lower 6b must be 0s !!!\n\n"); } +$c=$config{protection}{inst_access_addr3}; if ((hex($c)&0x3f) != 0) { die("$helpusage\n\nFAIL: inst_access_addr3 lower 6b must be 0s !!!\n\n"); } +$c=$config{protection}{inst_access_addr4}; if ((hex($c)&0x3f) != 0) { die("$helpusage\n\nFAIL: inst_access_addr4 lower 6b must be 0s !!!\n\n"); } +$c=$config{protection}{inst_access_addr5}; if ((hex($c)&0x3f) != 0) { die("$helpusage\n\nFAIL: inst_access_addr5 lower 6b must be 0s !!!\n\n"); } +$c=$config{protection}{inst_access_addr6}; if ((hex($c)&0x3f) != 0) { die("$helpusage\n\nFAIL: inst_access_addr6 lower 6b must be 0s !!!\n\n"); } +$c=$config{protection}{inst_access_addr7}; if ((hex($c)&0x3f) != 0) { die("$helpusage\n\nFAIL: inst_access_addr7 lower 6b must be 0s !!!\n\n"); } +$c=$config{protection}{inst_access_mask0}; if ((hex($c)&0x3f) != 63) { die("$helpusage\n\nFAIL: inst_access_mask0 lower 6b must be 1s !!!\n\n"); } +$c=$config{protection}{inst_access_mask1}; if ((hex($c)&0x3f) != 63) { die("$helpusage\n\nFAIL: inst_access_mask1 lower 6b must be 1s !!!\n\n"); } +$c=$config{protection}{inst_access_mask2}; if ((hex($c)&0x3f) != 63) { die("$helpusage\n\nFAIL: inst_access_mask2 lower 6b must be 1s !!!\n\n"); } +$c=$config{protection}{inst_access_mask3}; if ((hex($c)&0x3f) != 63) { die("$helpusage\n\nFAIL: inst_access_mask3 lower 6b must be 1s !!!\n\n"); } +$c=$config{protection}{inst_access_mask4}; if ((hex($c)&0x3f) != 63) { die("$helpusage\n\nFAIL: inst_access_mask4 lower 6b must be 1s !!!\n\n"); } +$c=$config{protection}{inst_access_mask5}; if ((hex($c)&0x3f) != 63) { die("$helpusage\n\nFAIL: inst_access_mask5 lower 6b must be 1s !!!\n\n"); } +$c=$config{protection}{inst_access_mask6}; if ((hex($c)&0x3f) != 63) { die("$helpusage\n\nFAIL: inst_access_mask6 lower 6b must be 1s !!!\n\n"); } +$c=$config{protection}{inst_access_mask7}; if ((hex($c)&0x3f) != 63) { die("$helpusage\n\nFAIL: inst_access_mask7 lower 6b must be 1s !!!\n\n"); } +$c=$config{protection}{data_access_addr0}; if ((hex($c)&0x3f) != 0) { die("$helpusage\n\nFAIL: data_access_addr0 lower 6b must be 0s !!!\n\n"); } +$c=$config{protection}{data_access_addr1}; if ((hex($c)&0x3f) != 0) { die("$helpusage\n\nFAIL: data_access_addr1 lower 6b must be 0s !!!\n\n"); } +$c=$config{protection}{data_access_addr2}; if ((hex($c)&0x3f) != 0) { die("$helpusage\n\nFAIL: data_access_addr2 lower 6b must be 0s !!!\n\n"); } +$c=$config{protection}{data_access_addr3}; if ((hex($c)&0x3f) != 0) { die("$helpusage\n\nFAIL: data_access_addr3 lower 6b must be 0s !!!\n\n"); } +$c=$config{protection}{data_access_addr4}; if ((hex($c)&0x3f) != 0) { die("$helpusage\n\nFAIL: data_access_addr4 lower 6b must be 0s !!!\n\n"); } +$c=$config{protection}{data_access_addr5}; if ((hex($c)&0x3f) != 0) { die("$helpusage\n\nFAIL: data_access_addr5 lower 6b must be 0s !!!\n\n"); } +$c=$config{protection}{data_access_addr6}; if ((hex($c)&0x3f) != 0) { die("$helpusage\n\nFAIL: data_access_addr6 lower 6b must be 0s !!!\n\n"); } +$c=$config{protection}{data_access_addr7}; if ((hex($c)&0x3f) != 0) { die("$helpusage\n\nFAIL: data_access_addr7 lower 6b must be 0s !!!\n\n"); } +$c=$config{protection}{data_access_mask0}; if ((hex($c)&0x3f) != 63) { die("$helpusage\n\nFAIL: data_access_mask0 lower 6b must be 1s !!!\n\n"); } +$c=$config{protection}{data_access_mask1}; if ((hex($c)&0x3f) != 63) { die("$helpusage\n\nFAIL: data_access_mask1 lower 6b must be 1s !!!\n\n"); } +$c=$config{protection}{data_access_mask2}; if ((hex($c)&0x3f) != 63) { die("$helpusage\n\nFAIL: data_access_mask2 lower 6b must be 1s !!!\n\n"); } +$c=$config{protection}{data_access_mask3}; if ((hex($c)&0x3f) != 63) { die("$helpusage\n\nFAIL: data_access_mask3 lower 6b must be 1s !!!\n\n"); } +$c=$config{protection}{data_access_mask4}; if ((hex($c)&0x3f) != 63) { die("$helpusage\n\nFAIL: data_access_mask4 lower 6b must be 1s !!!\n\n"); } +$c=$config{protection}{data_access_mask5}; if ((hex($c)&0x3f) != 63) { die("$helpusage\n\nFAIL: data_access_mask5 lower 6b must be 1s !!!\n\n"); } +$c=$config{protection}{data_access_mask6}; if ((hex($c)&0x3f) != 63) { die("$helpusage\n\nFAIL: data_access_mask6 lower 6b must be 1s !!!\n\n"); } +$c=$config{protection}{data_access_mask7}; if ((hex($c)&0x3f) != 63) { die("$helpusage\n\nFAIL: data_access_mask7 lower 6b must be 1s !!!\n\n"); } -if (($config{"testbench"}{"build_ahb_lite"} ne "")) { +if (($config{"testbench"}{"build_ahb_lite"} ne "")) { delete $config{"testbench"}{"build_axi4"}; } else { # default is AXI bus @@ -909,7 +954,13 @@ else { # default is AXI bus if (exists($config{"testbench"}{"build_axi_native"}) and $config{"testbench"}{"build_axi_native"} ne "") { $config{csr}{mfdc}{reset} = "0x00070040" if exists $config{csr}{mfdc}; -} +} + +# Over-ride MFDC reset value for AXI. +if (exists($config{"testbench"}{"build_axi_native"}) and + $config{"testbench"}{"build_axi_native"} ne "") { + $config{csr}{mfdc}{reset} = "0x00070040" if exists $config{csr}{mfdc}; +} # Fill in derived configuration entries. @@ -971,19 +1022,19 @@ sub ghrhash{ $ghr_start = "{"; if($ghr_size > $btb_addr_width){ - if($ghr_size-1 == $btb_addr_width){ - $string= "{ghr[$ghr_hi:$ghr_lo] ^ ghr[$ghr_hi+1],hashin[$config{btb}{btb_index1_hi}:4]^ghr[$ghr_lo-1:0]}"; - } - else{ - $string = "{ghr[$ghr_hi:$ghr_lo] ^ {ghr[$ghr_hi+1], {$ghr_size-1-$btb_addr_width\{1'b0} } },hashin[$config{btb}{btb_index1_hi}:4]^ghr[$ghr_lo-1:0]}"; - } + if($ghr_size-1 == $btb_addr_width){ + $string= "{ghr[$ghr_hi:$ghr_lo] ^ ghr[$ghr_hi+1],hashin[$config{btb}{btb_index1_hi}:4]^ghr[$ghr_lo-1:0]}"; + } + else{ + $string = "{ghr[$ghr_hi:$ghr_lo] ^ {ghr[$ghr_hi+1], {$ghr_size-1-$btb_addr_width\{1'b0} } },hashin[$config{btb}{btb_index1_hi}:4]^ghr[$ghr_lo-1:0]}"; + } } elsif($ghr_size < $btb_addr_width){ - $string = "{hashin[$ghr_size+3:4]^ghr[$ghr_size-1:0]^{ghr[$ghr_hi+1], {$ghr_hi\{1'b0} } }}"; + $string = "{hashin[$ghr_size+3:4]^ghr[$ghr_size-1:0]^{ghr[$ghr_hi+1], {$ghr_hi\{1'b0} } }}"; } else{ $string = "{hashin[$config{btb}{btb_index1_hi}:4]^ghr[$ghr_lo-1:0]^{ghr[$ghr_hi+1], {$btb_addr_width-1\{1'b0} } } }"} return $string; - + } @@ -1091,7 +1142,7 @@ if($config{bht}{bht_size}==2048){ $config{bht}{bht_hash_string} = &ghrhash($config{btb}{btb_index1_hi}, $config{bht}{bht_ghr_size}-1); -$config{pic}{pic_base_addr} = (hex($config{pic}{pic_region})<<28) + +$config{pic}{pic_base_addr} = (hex($config{pic}{pic_region})<<28) + (hex($config{pic}{pic_offset})); $config{pic}{pic_base_addr} = sprintf("0x%x", $config{pic}{pic_base_addr}); @@ -1102,11 +1153,11 @@ $config{core}{lsu_num_nbload_width} = log2($config{core}{lsu_num_nbload}); $config{bus}{lsu_bus_tag} = log2($config{core}{lsu_num_nbload}) + 1; -$config{dccm}{dccm_sadr} = (hex($config{dccm}{dccm_region})<<28) + +$config{dccm}{dccm_sadr} = (hex($config{dccm}{dccm_region})<<28) + (hex($config{dccm}{dccm_offset})); $config{dccm}{dccm_sadr} = sprintf("0x%x", $config{dccm}{dccm_sadr}); -$config{dccm}{dccm_eadr} = (hex($config{dccm}{dccm_region})<<28) + +$config{dccm}{dccm_eadr} = (hex($config{dccm}{dccm_region})<<28) + (hex($config{dccm}{dccm_offset})) + size($config{dccm}{dccm_size})-1; $config{dccm}{dccm_eadr} = sprintf("0x%x", $config{dccm}{dccm_eadr}); @@ -1124,19 +1175,19 @@ $config{dccm}{dccm_index_bits} = $config{dccm}{dccm_bits} - $config{dccm}{dccm_b $config{dccm}{dccm_ecc_width} = log2($config{dccm}{dccm_data_width}) + 2; $config{dccm}{lsu_sb_bits} = (($config{dccm}{dccm_bits}) > ($config{pic}{pic_bits})) ? ($config{dccm}{dccm_bits}) : ($config{pic}{pic_bits}); -$config{dccm}{dccm_rows} = ($config{dccm}{dccm_size}==48 ) ? (2**($config{dccm}{dccm_index_bits}-1) + 2**$config{dccm}{dccm_index_bits})/2 : 2**$config{dccm}{dccm_index_bits}; +$config{dccm}{dccm_rows} = ($config{dccm}{dccm_size}==48 ) ? (2**($config{dccm}{dccm_index_bits}-1) + 2**$config{dccm}{dccm_index_bits})/2 : 2**$config{dccm}{dccm_index_bits}; $config{dccm}{dccm_data_cell} = "ram_$config{dccm}{dccm_rows}x39"; $config{icache}{icache_tag_high} = (($config{icache}{icache_size}==256) ? 16 : - ($config{icache}{icache_size}==128) ? 15 : - ($config{icache}{icache_size}==64) ? 14 : - ($config{icache}{icache_size}==32) ? 13 : 12); + ($config{icache}{icache_size}==128) ? 15 : + ($config{icache}{icache_size}==64) ? 14 : + ($config{icache}{icache_size}==32) ? 13 : 12); $config{icache}{icache_tag_depth} = (($config{icache}{icache_size}==256) ? 1024 : - ($config{icache}{icache_size}==128) ? 512 : - ($config{icache}{icache_size}==64) ? 256 : - ($config{icache}{icache_size}==32) ? 128 : 64); + ($config{icache}{icache_size}==128) ? 512 : + ($config{icache}{icache_size}==64) ? 256 : + ($config{icache}{icache_size}==32) ? 128 : 64); $config{icache}{icache_ic_depth} = log2($config{icache}{icache_size}) + 4; @@ -1167,7 +1218,7 @@ if ($top_align_iccm && ($config{iccm}{iccm_offset} eq $iccm_offset) && ($config{ $config{iccm}{iccm_offset} = sprintf("0x%08x",256*1024*1024-size($config{iccm}{iccm_size})); print "$self: Aligning default iccm offset to top of region @ $config{iccm}{iccm_offset}\n"; } -$config{iccm}{iccm_sadr} = (hex($config{iccm}{iccm_region})<<28) + +$config{iccm}{iccm_sadr} = (hex($config{iccm}{iccm_region})<<28) + (hex($config{iccm}{iccm_offset})); $config{iccm}{iccm_sadr} = sprintf("0x%08x", $config{iccm}{iccm_sadr}); @@ -1180,7 +1231,7 @@ $config{iccm}{iccm_reserved} = sprintf("0x%x", ($config{iccm}{iccm_size}>30)? 40 $config{iccm}{iccm_bits} = 10 + log2($config{iccm}{iccm_size}); $config{iccm}{iccm_bank_bits} = log2($config{iccm}{iccm_num_banks}); //-1; $config{iccm}{iccm_index_bits} = $config{iccm}{iccm_bits} - $config{iccm}{iccm_bank_bits} - 2; # always 4 bytes -$config{iccm}{iccm_rows} = 2**$config{iccm}{iccm_index_bits}; +$config{iccm}{iccm_rows} = 2**$config{iccm}{iccm_index_bits}; $config{iccm}{iccm_data_cell} = "ram_$config{iccm}{iccm_rows}x39"; # Defines with explicit values in the macro name $config{iccm}{"iccm_num_banks_$config{iccm}{iccm_num_banks}"} = ""; @@ -1188,8 +1239,8 @@ $config{iccm}{"iccm_size_$config{iccm}{iccm_size}"} = ""; # Find an unused region for serial IO for ($rgn = 15;$rgn >= 0; $rgn--) { - if (($rgn != hex($config{iccm}{iccm_region})) && - ($rgn != hex($config{dccm}{dccm_region})) && + if (($rgn != hex($config{iccm}{iccm_region})) && + ($rgn != hex($config{dccm}{dccm_region})) && ($rgn != (hex($config{pic}{pic_region})))) { $config{memmap}{serialio} = ($rgn << 28) + (22<<18); last; @@ -1199,9 +1250,9 @@ $config{memmap}{serialio} = sprintf("0x%08x", $config{memmap}{serialio}); # Find an unused region for external data for ($rgn = 15;$rgn >= 0; $rgn--) { - if (($rgn != hex($config{iccm}{iccm_region})) && - ($rgn != hex($config{dccm}{dccm_region})) && - ($rgn != (hex($config{memmap}{serialio})>>28)) && + if (($rgn != hex($config{iccm}{iccm_region})) && + ($rgn != hex($config{dccm}{dccm_region})) && + ($rgn != (hex($config{memmap}{serialio})>>28)) && ($rgn != (hex($config{pic}{pic_region})))) { $config{memmap}{external_data} = ($rgn << 28) + (22<<18); last; @@ -1211,10 +1262,10 @@ $config{memmap}{external_data} = sprintf("0x%08x", $config{memmap}{external_data # # Find an unused region for external prog for ($rgn = 15;$rgn >= 0; $rgn--) { - if (($rgn != hex($config{iccm}{iccm_region})) && - ($rgn != hex($config{dccm}{dccm_region})) && - ($rgn != (hex($config{memmap}{serialio})>>28)) && - ($rgn != (hex($config{memmap}{external_data})>>28)) && + if (($rgn != hex($config{iccm}{iccm_region})) && + ($rgn != hex($config{dccm}{dccm_region})) && + ($rgn != (hex($config{memmap}{serialio})>>28)) && + ($rgn != (hex($config{memmap}{external_data})>>28)) && ($rgn != (hex($config{pic}{pic_region})))) { $config{memmap}{external_prog} = ($rgn << 28); last; @@ -1222,11 +1273,11 @@ for ($rgn = 15;$rgn >= 0; $rgn--) { } $config{memmap}{external_prog} = sprintf("0x%08x", $config{memmap}{external_prog}); -# Unused region for second data +# Unused region for second data for ($rgn = 15;$rgn >= 0; $rgn--) { - if (($rgn != hex($config{iccm}{iccm_region})) && - ($rgn != hex($config{dccm}{dccm_region})) && - ($rgn != (hex($config{memmap}{serialio})>>28)) && + if (($rgn != hex($config{iccm}{iccm_region})) && + ($rgn != hex($config{dccm}{dccm_region})) && + ($rgn != (hex($config{memmap}{serialio})>>28)) && ($rgn != (hex($config{memmap}{external_data})>>28)) && ($rgn != (hex($config{memmap}{external_prog})>>28) && ($rgn != (hex($config{pic}{pic_region}))) @@ -1243,9 +1294,9 @@ $config{memmap}{external_data_1} = sprintf("0x%08x", $config{memmap}{data_1}); # Find an unused region for debug_sb_memory data for ($rgn = 15;$rgn >= 0; $rgn--) { - if (($rgn != hex($config{iccm}{iccm_region})) && - ($rgn != hex($config{dccm}{dccm_region})) && - ($rgn != (hex($config{memmap}{serialio})>>28)) && + if (($rgn != hex($config{iccm}{iccm_region})) && + ($rgn != hex($config{dccm}{dccm_region})) && + ($rgn != (hex($config{memmap}{serialio})>>28)) && ($rgn != (hex($config{memmap}{external_data})>>28)) && ($rgn != (hex($config{pic}{pic_region})))) { $config{memmap}{debug_sb_mem} = ($rgn << 28) + (22<<18); @@ -1254,14 +1305,6 @@ for ($rgn = 15;$rgn >= 0; $rgn--) { } $config{memmap}{debug_sb_mem} = sprintf("0x%08x", $config{memmap}{debug_sb_mem}); -# Boot generic from ICCM -if ($target eq "generic") { - $config{reset_vec} = $config{iccm}{iccm_sadr}; - $config{testbench}{generic} = 1; - print "$self: Setting reset_vec = ICCM start address for Generic\n"; -} - - # Output bit-width specifiers for these variables our %widths = ( @@ -1296,6 +1339,31 @@ our %widths = ( ); #}}} + +#-----------------------Reset Vector MPU check-----------------------# +$flag_pass=0; +if(!(hex($config{reset_vec}) >= ((hex($config{iccm}{iccm_region})<<28) + (hex($config{iccm}{iccm_offset}))) && (hex($config{reset_vec}) < ((hex($config{iccm}{iccm_region})<<28) + (hex($config{iccm}{iccm_offset})) + size($config{iccm}{iccm_size})-1)))) +{ + for(my $i=0; $i<8; $i++) + { + $inst_access_enable = "inst_access_enable$i"; + $inst_access_addr = "inst_access_addr$i"; + $inst_access_mask = "inst_access_mask$i"; + if(hex($config{protection}{$inst_access_enable})) + { + if((hex($config{reset_vec})>= hex($config{protection}{$inst_access_addr})) && (hex($config{reset_vec})< (hex($config{protection}{$inst_access_addr}) | hex($config{protection}{$inst_access_mask})))) + { + $flag_pass++; + last; + } + } + else {$enable_check++;} + } + +if($flag_pass == 0 & $enable_check < 8) { die("$helpusage\n\nFAIL: RESET_VECTOR not in any of MPU enabled instruction access windows or ICCM !!!\n\n");} +} +#-----------------------Reset Vector MPU check-----------------------# + #print Dumper(\%config); #print Dumper(\%width); @@ -1408,7 +1476,7 @@ sub print_define {#{{{ } }#}}} -# print header +# print header sub print_header {#{{{ my $cs = shift; print FILE "$cs NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE\n"; @@ -1434,7 +1502,7 @@ sub gen_define {#{{{ $re = qr/($re)/; #print Dumper($hash); foreach my $key (keys %$hash) { - next if $key eq "csr"; + next if $key eq "csr"; #print "looking at $key:$matched ($re)\n"; if (defined($unsets{$key})) { print "$self:unsetting $key\n"; @@ -1456,10 +1524,10 @@ sub gen_define {#{{{ } gen_define($matched,$prefix, $value, \@printvars, \@overridable); $matched = 0; - } elsif (ref($value) eq "ARRAY") { + } elsif (ref($value) eq "ARRAY") { # print "$key : @{$value}\n"; $matched = 0; - } else { + } else { if ($matched eq "1" || $key =~ /$re/) { if($value =~ /derive\(.*\)/o) { $value = eval($value); @@ -1504,10 +1572,10 @@ sub dump_define {#{{{ } dump_define($matched,$prefix, $value, \@printvars, \@overridable); $matched = 0; - } elsif (ref($value) eq "ARRAY") { + } elsif (ref($value) eq "ARRAY") { # print "$key : @{$value}\n"; $matched = 0; - } else { + } else { if ($matched eq "1" || $key =~ /$re/) { if($value =~ /derive\(.*\)/o) { $value = eval($value); @@ -1559,59 +1627,126 @@ sub collect_mem_protection { my $mask_tag = $tag . "_access_mask"; foreach my $key (keys %{$prot}) { - next unless $key =~ /^$enable_tag(\d+)$/; - my $ix = $1; + next unless $key =~ /^$enable_tag(\d+)$/; + my $ix = $1; - my $enable = $prot->{$key}; - if ($enable !~ /[01]$/) { - warn("Invalid value for protection entry $key: $enable\n"); - next; - } + my $enable = $prot->{$key}; + if ($enable !~ /[01]$/) { + warn("Invalid value for protection entry $key: $enable\n"); + next; + } - next unless ($enable eq "1" or $enable eq "1'b1"); + next unless ($enable eq "1" or $enable eq "1'b1"); - if (! exists $prot->{"$addr_tag$ix"}) { - warn("Missing $addr_tag$ix\n"); - next; - } + if (! exists $prot->{"$addr_tag$ix"}) { + warn("Missing $addr_tag$ix\n"); + next; + } - if (! exists $prot->{"$mask_tag$ix"}) { - warn("Missing $mask_tag$ix\n"); - next; - } + if (! exists $prot->{"$mask_tag$ix"}) { + warn("Missing $mask_tag$ix\n"); + next; + } - my $addr = $prot->{"$addr_tag$ix"}; - my $mask = $prot->{"$mask_tag$ix"}; + my $addr = $prot->{"$addr_tag$ix"}; + my $mask = $prot->{"$mask_tag$ix"}; - if ($addr !~ /^0x[0-9a-fA-F]+$/) { - warn("Invalid $addr_tag$ix: $addr\n"); - next; - } + if ($addr !~ /^0x[0-9a-fA-F]+$/) { + warn("Invalid $addr_tag$ix: $addr\n"); + next; + } - if ($mask !~ /^0x[0-9a-fA-F]+$/) { - warn("Invalid $mask_tag$ix: $mask\n"); - next; - } + if ($mask !~ /^0x[0-9a-fA-F]+$/) { + warn("Invalid $mask_tag$ix: $mask\n"); + next; + } - if ((hex($addr) & hex($mask)) != 0) { - warn("Protection mask bits overlap address bits in mask $mask and addr $addr\n"); - } + if ((hex($addr) & hex($mask)) != 0) { + warn("Protection mask bits overlap address bits in mask $mask and addr $addr\n"); + } - if ($mask !~ /^0x0*[137]?f*$/) { - warn("Protection mask ($mask) must have all its one bits to the right of its zero bits\n"); - next; - } + if ($mask !~ /^0x0*[137]?f*$/) { + warn("Protection mask ($mask) must have all its one bits to the right of its zero bits\n"); + next; + } - my $start = hex($addr) & ~hex($mask) & 0xffffffff; - my $end = (hex($addr) | hex($mask)) & 0xffffffff; + my $start = hex($addr) & ~hex($mask) & 0xffffffff; + my $end = (hex($addr) | hex($mask)) & 0xffffffff; - $start = sprintf("0x%08x", $start); - $end = sprintf("0x%08x", $end); + $start = sprintf("0x%08x", $start); + $end = sprintf("0x%08x", $end); - push(@{$results}, [ $start, $end ]); + push(@{$results}, [ $start, $end ]); } } +# Collect memory protection specs (array of address pairs) in the given +# resutls array. Tag is either "data" or "inst". +sub collect_mem_protection { + my ($tag, $config, $results) = @_; + return unless exists $config{protection}; + + my $prot = $config{protection}; + + my $enable_tag = $tag . "_access_enable"; + my $addr_tag = $tag . "_access_addr"; + my $mask_tag = $tag . "_access_mask"; + + foreach my $key (keys %{$prot}) { + next unless $key =~ /^$enable_tag(\d+)$/; + my $ix = $1; + + my $enable = $prot->{$key}; + if ($enable !~ /[01]$/) { + warn("Invalid value for protection entry $key: $enable\n"); + next; + } + + next unless ($enable eq "1" or $enable eq "1'b1"); + + if (! exists $prot->{"$addr_tag$ix"}) { + warn("Missing $addr_tag$ix\n"); + next; + } + + if (! exists $prot->{"$mask_tag$ix"}) { + warn("Missing $mask_tag$ix\n"); + next; + } + + my $addr = $prot->{"$addr_tag$ix"}; + my $mask = $prot->{"$mask_tag$ix"}; + + if ($addr !~ /^0x[0-9a-fA-F]+$/) { + warn("Invalid $addr_tag$ix: $addr\n"); + next; + } + + if ($mask !~ /^0x[0-9a-fA-F]+$/) { + warn("Invalid $mask_tag$ix: $mask\n"); + next; + } + + if ((hex($addr) & hex($mask)) != 0) { + warn("Protection mask bits overlap address bits in mask $mask and addr $addr\n"); + } + + if ($mask !~ /^0x0*[137]?f*$/) { + warn("Protection mask ($mask) must have all its one bits to the right of its zero bits\n"); + next; + } + + my $start = hex($addr) & ~hex($mask) & 0xffffffff; + my $end = (hex($addr) | hex($mask)) & 0xffffffff; + + $start = sprintf("0x%08x", $start); + $end = sprintf("0x%08x", $end); + + push(@{$results}, [ $start, $end ]); + } +} + + sub dump_whisper_config{#{{{ my ($config, $path) = @_; @@ -1623,13 +1758,13 @@ sub dump_whisper_config{#{{{ # Collect top-level integer entries. foreach my $tag (qw( harts xlen )) { - $jh{$tag} = $config{$tag} + 0 if exists $config{$tag}; + $jh{$tag} = $config{$tag} + 0 if exists $config{$tag}; } # Collect top-level string/hex entries. foreach my $tag (qw ( reset_vec nmi_vec num_mmode_perf_regs max_mmode_perf_event - even_odd_trigger_chains)) { - $jh{$tag} = $config{$tag} if exists $config{$tag}; + even_odd_trigger_chains)) { + $jh{$tag} = $config{$tag} if exists $config{$tag}; } # Collect memory map configs. @@ -1639,31 +1774,31 @@ sub dump_whisper_config{#{{{ $jh{memmap}{inst} = [@inst_mem_prot] if @inst_mem_prot; $jh{memmap}{data} = [@data_mem_prot] if @data_mem_prot; $jh{memmap}{cosnoleio} = $config{memmap}{serialio} if exists $config{memmap}{serialio}; - + # Collect load/store-error rollback parameter. if (exists $config{testbench} and exists $config{testbench}{sterr_rollback}) { - $jh{store_error_rollback} = $config{testbench}{sterr_rollback}; + $jh{store_error_rollback} = $config{testbench}{sterr_rollback}; } if (exists $config{testbench} and exists $config{testbench}{lderr_rollback}) { - $jh{load_error_rollback} = $config{testbench}{lderr_rollback}; + $jh{load_error_rollback} = $config{testbench}{lderr_rollback}; } # Collect dccm configs if (exists $config{dccm} and exists $config{dccm}{dccm_enable}) { - $jh{dccm}{region} = $config{dccm}{dccm_region}; - $jh{dccm}{size} = 1024*decimal($config{dccm}{dccm_size}); # From 1k to bytes - $jh{dccm}{offset} = $config{dccm}{dccm_offset}; + $jh{dccm}{region} = $config{dccm}{dccm_region}; + $jh{dccm}{size} = 1024*decimal($config{dccm}{dccm_size}); # From 1k to bytes + $jh{dccm}{offset} = $config{dccm}{dccm_offset}; - $jh{dccm}{size} = sprintf("0x%x", $jh{dccm}{size}); + $jh{dccm}{size} = sprintf("0x%x", $jh{dccm}{size}); } # Collect icccm configs. if (exists $config{iccm} and exists $config{iccm}{iccm_enable}) { - $jh{iccm}{region} = $config{iccm}{iccm_region}; - $jh{iccm}{size} = 1024*decimal($config{iccm}{iccm_size}); # From 1k to bytes - $jh{iccm}{offset} = $config{iccm}{iccm_offset}; + $jh{iccm}{region} = $config{iccm}{iccm_region}; + $jh{iccm}{size} = 1024*decimal($config{iccm}{iccm_size}); # From 1k to bytes + $jh{iccm}{offset} = $config{iccm}{iccm_offset}; - $jh{iccm}{size} = sprintf("0x%x", $jh{iccm}{size}); + $jh{iccm}{size} = sprintf("0x%x", $jh{iccm}{size}); } # Collect CSRs @@ -1672,16 +1807,16 @@ sub dump_whisper_config{#{{{ # Collect pic configs. if (exists $config{pic}) { - while (my ($k, $v) = each %{$config{pic}}) { - next if $k eq 'pic_base_addr'; # derived from region and offset - if ($k eq 'pic_size') { - $v *= 1024; # from kbytes to bytes - $v = sprintf("0x%x", $v); - } - $k =~ s/^pic_//o; - $v += 0 if $v =~ /^\d+$/o; - $jh{pic}{$k} = $v; - } + while (my ($k, $v) = each %{$config{pic}}) { + next if $k eq 'pic_base_addr'; # derived from region and offset + if ($k eq 'pic_size') { + $v *= 1024; # from kbytes to bytes + $v = sprintf("0x%x", $v); + } + $k =~ s/^pic_//o; + $v += 0 if $v =~ /^\d+$/o; + $jh{pic}{$k} = $v; + } } # Collect triggers. @@ -1708,12 +1843,12 @@ sub check_addr_align { $size = 2*$p2 if $size != $p2; if (($addr % $size) != 0) { - printf("Address of $section area(0x%x) is not a multiple of its size (0x%x)\n", - $addr, $size); - exit(1); + printf("Address of $section area(0x%x) is not a multiple of its size (0x%x)\n", + $addr, $size); + exit(1); } } - + sub log2 { my ($n) = @_; diff --git a/design/dbg/dbg.sv b/design/dbg/dbg.sv index c6cdbd2..681459c 100644 --- a/design/dbg/dbg.sv +++ b/design/dbg/dbg.sv @@ -1,12 +1,12 @@ // 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. @@ -16,10 +16,10 @@ // $Id$ // // Function: Top level SWERV core file to control the debug mode -// Comments: Responsible to put the rest of the core in quiesce 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 : +// And then Resume the core to do the normal mode +// Author : //******************************************************************************** module dbg ( // outputs to the core for command and data interface @@ -27,10 +27,10 @@ module dbg ( 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_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 @@ -39,25 +39,25 @@ module dbg ( // 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_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 output logic [31:0] dmi_reg_rdata, // read data -// output logic dmi_reg_ack, +// output logic dmi_reg_ack, - // AXI signals + // AXI signals // AXI Write Channels output logic sb_axi_awvalid, input logic sb_axi_awready, @@ -71,19 +71,19 @@ module dbg ( output logic [3:0] sb_axi_awcache, output logic [2:0] sb_axi_awprot, output logic [3:0] sb_axi_awqos, - - output logic sb_axi_wvalid, + + 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 [`RV_SB_BUS_TAG-1:0] sb_axi_bid, - - // AXI Read Channels + + // AXI Read Channels output logic sb_axi_arvalid, input logic sb_axi_arready, output logic [`RV_SB_BUS_TAG-1:0] sb_axi_arid, @@ -96,45 +96,46 @@ module dbg ( output logic [3:0] sb_axi_arcache, output logic [2:0] sb_axi_arprot, output logic [3:0] sb_axi_arqos, - + input logic sb_axi_rvalid, output logic sb_axi_rready, input logic [`RV_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, - + input logic dbg_bus_clk_en, - - // general inputs + + // general inputs input logic clk, input logic free_clk, input logic rst_l, + input logic dbg_rst_l, input logic clk_override, input logic scan_mode ); `include "global.h" - + typedef enum logic [2:0] {IDLE=3'b000, HALTING=3'b001, HALTED=3'b010, CMD_START=3'b011, CMD_WAIT=3'b100, CMD_DONE=3'b101, RESUMING=3'b110} 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_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] 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 + // data 0 logic [31:0] data0_din; - logic data0_reg_wren, data0_reg_wren0, data0_reg_wren1; - // data 1 + logic data0_reg_wren, data0_reg_wren0, data0_reg_wren1; + // data 1 logic [31:0] data1_din; logic data1_reg_wren, data1_reg_wren0, data1_reg_wren1; // abstractcs @@ -151,6 +152,8 @@ module dbg ( logic dmstatus_havereset_wren; logic dmstatus_havereset_rst; logic dmstatus_resumeack; + logic dmstatus_unavail; + logic dmstatus_running; logic dmstatus_halted; logic dmstatus_havereset; @@ -160,34 +163,34 @@ module dbg ( logic command_wren; // 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_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; - + // data logic sbdata0_reg_wren0; - logic sbdata0_reg_wren1; + logic sbdata0_reg_wren1; logic sbdata0_reg_wren; logic [31:0] sbdata0_din; - + logic sbdata1_reg_wren0; - logic sbdata1_reg_wren1; + 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; @@ -196,7 +199,7 @@ module dbg ( logic sbreadonaddr_access; logic sbreadondata_access; logic sbdata0wr_access; - + logic sb_axi_awvalid_q, sb_axi_awready_q; logic sb_axi_wvalid_q, sb_axi_wready_q; logic sb_axi_arvalid_q, sb_axi_arready_q; @@ -204,7 +207,7 @@ module dbg ( logic sb_axi_rvalid_q, sb_axi_rready_q; logic [1:0] sb_axi_bresp_q, sb_axi_rresp_q; logic [63:0] sb_axi_rdata_q; - + logic [63:0] sb_bus_rdata; //registers @@ -212,23 +215,23 @@ module dbg ( logic [31:0] sbaddress0_reg; logic [31:0] sbdata0_reg; logic [31:0] sbdata1_reg; - + logic dbg_dm_rst_l; //clken logic dbg_free_clken; logic dbg_free_clk; - + logic sb_free_clken; logic sb_free_clk; - + logic bus_clken; logic bus_clk; - + // clocking - // used for the abstract commands. + // used for the abstract commands. assign dbg_free_clken = dmi_reg_en | (dbg_state != IDLE) | dbg_state_en | dec_tlu_dbg_halted | clk_override; - + // used for the system bus assign sb_free_clken = dmi_reg_en | sb_state_en | (sb_state != SBIDLE) | clk_override; assign bus_clken = (sb_axi_awvalid | sb_axi_wvalid | sb_axi_arvalid | sb_axi_bvalid | sb_axi_rvalid | clk_override) & dbg_bus_clk_en; @@ -236,90 +239,93 @@ module dbg ( rvoclkhdr dbg_free_cgc (.en(dbg_free_clken), .l1clk(dbg_free_clk), .*); rvoclkhdr sb_free_cgc (.en(sb_free_clken), .l1clk(sb_free_clk), .*); rvclkhdr bus_cgc (.en(bus_clken), .l1clk(bus_clk), .*); - - // end clocking section - + + // end clocking section + // Reset logic - assign dbg_dm_rst_l = rst_l & (dmcontrol_reg[0] | scan_mode); - assign dbg_core_rst_l = ~dmcontrol_reg[1]; - + assign dbg_dm_rst_l = dbg_rst_l & (dmcontrol_reg[0] | scan_mode); + assign dbg_core_rst_l = ~dmcontrol_reg[1]; + // 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[11:5] = 7'h20; - assign sbcs_reg[4:0] = 5'b01111; + 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); // & (sbcs_reg[14:12] == 3'b000); assign sbcs_sbbusyerror_wren = (sbcs_wren & dmi_reg_wdata[22]) | ((sb_state != SBIDLE) & dmi_reg_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:15]), .dout(sbcs_reg[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])) | + + 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'b000)}} & 4'b0001) | - ({4{(sbcs_reg[19:17] == 3'b001)}} & 4'b0010) | - ({4{(sbcs_reg[19:17] == 3'b010)}} & 4'b0100) | - ({4{(sbcs_reg[19:17] == 3'b100)}} & 4'b1000); - - // sbdata + 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 == 32'h3c); 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_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_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}} & (sbaddress0_reg[31:0] + {28'b0,sbaddress0_incr[3:0]})); + ({32{sbaddress0_reg_wren1}} & (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 + 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 6 bits implemented. 31: haltreq, 30: resumereq, 29: haltreset, 28: ackhavereset, 1: ndmreset, 0: dmactive. + // dmcontrol register has only 6 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; - rvdffs #(5) dmcontrolff (.din({dmi_reg_wdata[31:28],dmi_reg_wdata[1]}), .dout({dmcontrol_reg[31: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(rst_l), .clk(dbg_free_clk)); + 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 == 32'h11) & dmi_reg_en; assign dmstatus_reg[31:20] = '0; assign dmstatus_reg[19:18] = {2{dmstatus_havereset}}; - assign dmstatus_reg[15:10] = '0; + 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; @@ -328,11 +334,14 @@ module dbg ( assign dmstatus_havereset_wren = (dmi_reg_addr == 7'h10) & dmi_reg_wdata[1] & dmi_reg_en & dmi_reg_wr_en; assign dmstatus_havereset_rst = (dmi_reg_addr == 7'h10) & dmi_reg_wdata[28] & dmi_reg_en & dmi_reg_wr_en; - + + assign dmstatus_unavail = dmcontrol_reg[1] | ~rst_l; + 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)); rvdffsc #(1) dmstatus_havereset_reg (.din(1'b1), .dout(dmstatus_havereset), .en(dmstatus_havereset_wren), .clear(dmstatus_havereset_rst), .rst_l(dbg_dm_rst_l), .clk(dbg_free_clk)); - + // haltsum0 register assign haltsum0_reg[31:1] = '0; assign haltsum0_reg[0] = dmstatus_halted; @@ -343,37 +352,37 @@ module dbg ( 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] & dmi_reg_en & ((dmi_reg_wr_en & ( (dmi_reg_addr == 7'h16) | (dmi_reg_addr == 7'h17))) | (dmi_reg_addr == 7'h4)); + assign abstractcs_error_sel0 = abstractcs_reg[12] & dmi_reg_en & ((dmi_reg_wr_en & ( (dmi_reg_addr == 7'h16) | (dmi_reg_addr == 7'h17))) | (dmi_reg_addr == 7'h4)); assign abstractcs_error_sel1 = dmi_reg_en & dmi_reg_wr_en & (dmi_reg_addr == 7'h17) & ~((dmi_reg_wdata[31:24] == 8'b0) | (dmi_reg_wdata[31:24] == 8'h2)); assign abstractcs_error_sel2 = core_dbg_cmd_done & core_dbg_cmd_fail; assign abstractcs_error_sel3 = dmi_reg_en & dmi_reg_wr_en & (dmi_reg_addr == 7'h17) & (dbg_state != HALTED); - assign abstractcs_error_sel4 = (dmi_reg_addr == 7'h17) & dmi_reg_en & dmi_reg_wr_en & - ( ((dmi_reg_wdata[22:20] == 3'b001) & data1_reg[0]) | - ((dmi_reg_wdata[22:20] == 3'b010) & (|data1_reg[1:0])) | + assign abstractcs_error_sel4 = (dmi_reg_addr == 7'h17) & dmi_reg_en & dmi_reg_wr_en & + ( ((dmi_reg_wdata[22:20] == 3'b001) & data1_reg[0]) | + ((dmi_reg_wdata[22:20] == 3'b010) & (|data1_reg[1:0])) | dmi_reg_wdata[22] | (dmi_reg_wdata[22:20] == 3'b011) ); - + assign abstractcs_error_sel5 = (dmi_reg_addr == 7'h16) & dmi_reg_en & dmi_reg_wr_en; - + assign abstractcs_error_selor = abstractcs_error_sel0 | abstractcs_error_sel1 | abstractcs_error_sel2 | abstractcs_error_sel3 | abstractcs_error_sel4 | abstractcs_error_sel5; - - assign abstractcs_error_din[2:0] = ({3{abstractcs_error_sel0}} & 3'b001) | // writing command or abstractcs while a command was executing. Or accessing data0 + + assign abstractcs_error_din[2:0] = ({3{abstractcs_error_sel0}} & 3'b001) | // writing command or abstractcs while a command was executing. Or accessing data0 ({3{abstractcs_error_sel1}} & 3'b010) | // writing a non-zero command to cmd field of command ({3{abstractcs_error_sel2}} & 3'b011) | // exception while running command ({3{abstractcs_error_sel3}} & 3'b100) | // writing a comnand when not in the halted state ({3{abstractcs_error_sel4}} & 3'b111) | // unaligned abstract memory command ({3{abstractcs_error_sel5}} & ~dmi_reg_wdata[10:8] & abstractcs_reg[10:8]) | // W1C ({3{~abstractcs_error_selor}} & 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)); - - + + // command register - implemented all the bits in this register // command[16] = 1: write, 0: read assign command_wren = (dmi_reg_addr == 7'h17) & dmi_reg_en & dmi_reg_wr_en & (dbg_state == HALTED); rvdffe #(32) dmcommand_reg (.*, .din(dmi_reg_wdata[31:0]), .dout(command_reg[31:0]), .en(command_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)); assign data0_reg_wren1 = core_dbg_cmd_done & (dbg_state == CMD_WAIT) & ~command_reg[16]; @@ -381,17 +390,17 @@ module dbg ( assign data0_din[31:0] = ({32{data0_reg_wren0}} & dmi_reg_wdata[31:0]) | ({32{data0_reg_wren1}} & core_dbg_rddata[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 + // data 1 assign data1_reg_wren0 = (dmi_reg_en & dmi_reg_wr_en & (dmi_reg_addr == 7'h5) & (dbg_state == HALTED)); assign data1_reg_wren1 = 1'b0; // core_dbg_cmd_done & (dbg_state == CMD_WAIT) & ~command_reg[16]; 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{data0_reg_wren1}} & core_dbg_rddata[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)); @@ -401,47 +410,47 @@ module dbg ( 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 + dbg_halt_req = dmcontrol_wren_Q & dmcontrol_reg[31] & ~dmcontrol_reg[1]; // 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 - + 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] & ~dec_tlu_debug_mode) | dmstatus_reg[9] | dec_tlu_mpc_halted_only) & ~dmcontrol_reg[1]; // when the jtag writes the halt bit in the DM register, OR when the status indicates Halted - dbg_halt_req = dmcontrol_reg[31]; // Removed debug mode qualification during MPC changes - //dbg_halt_req = dmcontrol_reg[31] & ~dec_tlu_debug_mode; // only when jtag has written the halt_req bit in the control + dbg_state_en = ((dmcontrol_reg[31] & ~dec_tlu_debug_mode) | dmstatus_reg[9] | dec_tlu_mpc_halted_only) & ~dmcontrol_reg[1]; // when the jtag writes the halt bit in the DM register, OR when the status indicates Halted + dbg_halt_req = dmcontrol_reg[31] & ~dmcontrol_reg[1]; // Removed debug mode qualification during MPC changes + //dbg_halt_req = dmcontrol_reg[31] & ~dec_tlu_debug_mode; // only when jtag has written the halt_req bit in the control end HALTING : begin - dbg_nxtstate = HALTED; // Goto HALTED once the core sends an ACK - dbg_state_en = dmstatus_reg[9]; // core indicates halted + dbg_nxtstate = dmcontrol_reg[1] ? IDLE : HALTED; // Goto HALTED once the core sends an ACK + dbg_state_en = dmstatus_reg[9] | dmcontrol_reg[1]; // 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] & ~dmcontrol_reg[1]) ? ((dmcontrol_reg[30] & ~dmcontrol_reg[31]) ? RESUMING : CMD_START) : + dbg_nxtstate = (dmstatus_reg[9] & ~dmcontrol_reg[1]) ? ((dmcontrol_reg[30] & ~dmcontrol_reg[31]) ? RESUMING : CMD_START) : (dmcontrol_reg[31] ? HALTING : IDLE); // This is MPC halted case //dbg_nxtstate = dmcontrol_reg[1] ? IDLE : (dmcontrol_reg[30] & ~dmcontrol_reg[31]) ? RESUMING : CMD_START; // wait for halted to go away before send to resume. Else start of new command dbg_state_en = (dmstatus_reg[9] & dmcontrol_reg[30] & ~dmcontrol_reg[31] & dmcontrol_wren_Q) | command_wren | dmcontrol_reg[1] | ~(dmstatus_reg[9] | dec_tlu_mpc_halted_only); abstractcs_busy_wren = dbg_state_en & (dbg_nxtstate == 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 + abstractcs_busy_din = 1'b1; + dbg_resume_req = dbg_state_en & (dbg_nxtstate == RESUMING); // single cycle pulse to core if resuming end CMD_START: begin - dbg_nxtstate = (|abstractcs_reg[10:8]) ? CMD_DONE : CMD_WAIT; // new command sent to the core - dbg_state_en = dbg_cmd_valid | (|abstractcs_reg[10:8]); - end + dbg_nxtstate = dmcontrol_reg[1] ? IDLE : (|abstractcs_reg[10:8]) ? CMD_DONE : CMD_WAIT; // new command sent to the core + dbg_state_en = dbg_cmd_valid | (|abstractcs_reg[10:8]) | dmcontrol_reg[1]; + end 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 + dbg_nxtstate = dmcontrol_reg[1] ? IDLE : CMD_DONE; + dbg_state_en = core_dbg_cmd_done | dmcontrol_reg[1]; // go to done state for one cycle after completing current command end CMD_DONE: begin - dbg_nxtstate = HALTED; + dbg_nxtstate = dmcontrol_reg[1] ? IDLE : 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; end RESUMING : begin - dbg_nxtstate = IDLE; - dbg_state_en = dmstatus_reg[17]; // resume ack has been updated in the dmstatus register + dbg_nxtstate = IDLE; + dbg_state_en = dmstatus_reg[17] | dmcontrol_reg[1]; // resume ack has been updated in the dmstatus register end default : begin dbg_nxtstate = IDLE; @@ -456,33 +465,33 @@ module dbg ( 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}} & dmcontrol_reg[31:0]) | + ({32{dmi_reg_addr == 7'h10}} & dmcontrol_reg[31:0]) | ({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'h16}} & abstractcs_reg[31:0]) | ({32{dmi_reg_addr == 7'h17}} & command_reg[31: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'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), .clk(dbg_free_clk)); + + + 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)); // Reset for both core/dbg reset // Ack will use the power on reset only otherwise there won't be any ack until dmactive is 1 // rvdff #(1) dmi_ack_reg (.din(dmi_reg_en), .dout(dmi_reg_ack), .rst_l(rst_l), .clk(free_clk)); rvdffs #(32) dmi_rddata_reg(.din(dmi_reg_rdata_din), .dout(dmi_reg_rdata), .en(dmi_reg_en), .rst_l(dbg_dm_rst_l), .clk(dbg_free_clk)); - + // interface for the core assign dbg_cmd_addr[31:0] = (command_reg[31:24] == 8'h2) ? {data1_reg[31:2],2'b0} : {20'b0, command_reg[11:0]}; // Only word addresses for abstract memory assign dbg_cmd_wrdata[31:0] = data0_reg[31:0]; - assign dbg_cmd_valid = (dbg_state == CMD_START) & ~(|abstractcs_reg[10:8]) & dma_dbg_ready; + assign dbg_cmd_valid = (dbg_state == CMD_START) & ~(|abstractcs_reg[10:8]) & 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]; // Ask DMA to stop taking bus trxns since debug request is done assign dbg_dma_bubble = ((dbg_state == CMD_START) & ~(|abstractcs_reg[10:8])) | (dbg_state == CMD_WAIT); - + // system bus FSM always_comb begin sb_nxtstate = SBIDLE; @@ -491,7 +500,7 @@ module dbg ( sbcs_sbbusy_din = 1'b0; sbcs_sberror_wren = 1'b0; sbcs_sberror_din[2:0] = 3'b0; - sbaddress0_reg_wren1 = 1'b0; + sbaddress0_reg_wren1 = 1'b0; case (sb_state) SBIDLE: begin sb_nxtstate = sbdata0wr_access ? WAIT_WR : WAIT_RD; @@ -500,7 +509,7 @@ module dbg ( 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 + end WAIT_RD: begin sb_nxtstate = (sbcs_unaligned | sbcs_illegal_size) ? DONE : CMD_RD; sb_state_en = dbg_bus_clk_en | sbcs_unaligned | sbcs_illegal_size; @@ -513,55 +522,55 @@ module dbg ( 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; + CMD_RD : begin + sb_nxtstate = RSP_RD; sb_state_en = sb_axi_arvalid_q & sb_axi_arready_q & dbg_bus_clk_en; - end - CMD_WR : begin - sb_nxtstate = (sb_axi_awready_q & sb_axi_wready_q) ? RSP_WR : (sb_axi_awready_q ? CMD_WR_DATA : CMD_WR_ADDR); + end + CMD_WR : begin + sb_nxtstate = (sb_axi_awready_q & sb_axi_wready_q) ? RSP_WR : (sb_axi_awready_q ? CMD_WR_DATA : CMD_WR_ADDR); sb_state_en = ((sb_axi_awvalid_q & sb_axi_awready_q) | (sb_axi_wvalid_q & sb_axi_wready_q)) & dbg_bus_clk_en; - end - CMD_WR_ADDR : begin - sb_nxtstate = RSP_WR; + end + CMD_WR_ADDR : begin + sb_nxtstate = RSP_WR; sb_state_en = sb_axi_awvalid_q & sb_axi_awready_q & dbg_bus_clk_en; - end - CMD_WR_DATA : begin - sb_nxtstate = RSP_WR; + end + CMD_WR_DATA : begin + sb_nxtstate = RSP_WR; sb_state_en = sb_axi_wvalid_q & sb_axi_wready_q & dbg_bus_clk_en; - end - RSP_RD: begin + end + RSP_RD: begin sb_nxtstate = DONE; sb_state_en = sb_axi_rvalid_q & sb_axi_rready_q & dbg_bus_clk_en; sbcs_sberror_wren = sb_state_en & sb_axi_rresp_q[1]; sbcs_sberror_din[2:0] = 3'b010; - end - RSP_WR: begin + end + RSP_WR: begin sb_nxtstate = DONE; sb_state_en = sb_axi_bvalid_q & sb_axi_bready_q & dbg_bus_clk_en; sbcs_sberror_wren = sb_state_en & sb_axi_bresp_q[1]; sbcs_sberror_din[2:0] = 3'b010; - end - DONE: begin + 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]; // auto increment was set. Update to new address after completing the current command + sbaddress0_reg_wren1 = sbcs_reg[16]; // auto increment was set. Update to new address after completing the current command end - default : begin + 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 + sbaddress0_reg_wren1 = 1'b0; + end 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)); - + //rvdff #(.WIDTH(1)) bus_clken_ff (.din(dbg_bus_clk_en), .dout(dbg_bus_clk_en_q), .rst_l(dbg_dm_rst_l), .clk(dbg_sb_c2_free_clk), .*); rvdffs #(.WIDTH(1)) axi_awvalid_ff (.din(sb_axi_awvalid), .dout(sb_axi_awvalid_q), .en(dbg_bus_clk_en), .rst_l(dbg_dm_rst_l), .clk(sb_free_clk), .*); @@ -591,7 +600,7 @@ module dbg ( 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_state == CMD_WR) | (sb_state == CMD_WR_DATA)) & ~(sb_axi_wvalid_q & sb_axi_wready_q); assign sb_axi_wdata[63:0] = ({64{(sbcs_reg[19:17] == 3'h0)}} & {8{sbdata0_reg[7:0]}}) | ({64{(sbcs_reg[19:17] == 3'h1)}} & {4{sbdata0_reg[15:0]}}) | @@ -604,9 +613,9 @@ module dbg ( assign sb_axi_wlast = '1; assign sb_axi_arvalid = (sb_state == CMD_RD) & ~(sb_axi_arvalid_q & sb_axi_arready_q); - assign sb_axi_araddr[31:0] = {sbaddress0_reg[31:3],3'b0}; + assign sb_axi_araddr[31:0] = sbaddress0_reg[31:0]; assign sb_axi_arid[SB_BUS_TAG-1:0] = '0; - assign sb_axi_arsize[2:0] = 3'b011; + assign sb_axi_arsize[2:0] = sbcs_reg[19:17]; assign sb_axi_arprot[2:0] = '0; assign sb_axi_arcache[3:0] = 4'b0; assign sb_axi_arregion[3:0] = sbaddress0_reg[31:28]; @@ -623,10 +632,10 @@ module dbg ( ({64{sbcs_reg[19:17] == 3'h1}} & ((sb_axi_rdata_q[63:0] >> 16*sbaddress0_reg[2:1]) & 64'hffff)) | ({64{sbcs_reg[19:17] == 3'h2}} & ((sb_axi_rdata_q[63:0] >> 32*sbaddress0_reg[2]) & 64'hffff_ffff)) | ({64{sbcs_reg[19:17] == 3'h3}} & sb_axi_rdata_q[63:0]); - + `ifdef ASSERT_ON -// assertion. -// when the resume_ack is asserted then the dec_tlu_dbg_halted should be 0 +// 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)); `endif endmodule diff --git a/design/dec/cdecode b/design/dec/cdecode index 52b3dd3..d98b523 100644 --- a/design/dec/cdecode +++ b/design/dec/cdecode @@ -116,24 +116,24 @@ c.swsp = [110...........10] c.xor = [100011...01...01] -.input +.input rv32c = { - i[15] - i[14] - i[13] - i[12] - 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[15] + i[14] + i[13] + i[12] + i[11] + i[10] + i[9] + i[8] + i[7] + i[6] + i[5] + i[4] + i[3] + i[2] + i[1] + i[0] } .output @@ -145,52 +145,52 @@ rv32c = { rdprs1 rs2prs2 rs2prd - uimm9_2 - ulwimm6_2 - ulwspimm7_2 - rdeq2 - rdeq1 - rs1eq2 - sbroffset8_1 - simm9_4 - simm5_0 - sjaloffset11_1 - sluimm17_12 - uimm5_0 - uswimm6_2 - uswspimm7_2 - o[31] - o[30] - o[29] - o[28] - o[27] - o[26] - o[25] - o[24] - o[23] - o[22] - o[21] - o[20] - o[19] - o[18] - o[17] - o[16] - o[15] - o[14] - o[13] - o[12] - o[11] - o[10] - o[9] - o[8] - o[7] - o[6] - o[5] - o[4] - o[3] - o[2] - o[1] - o[0] + uimm9_2 + ulwimm6_2 + ulwspimm7_2 + rdeq2 + rdeq1 + rs1eq2 + sbroffset8_1 + simm9_4 + simm5_0 + sjaloffset11_1 + sluimm17_12 + uimm5_0 + uswimm6_2 + uswspimm7_2 + o[31] + o[30] + o[29] + o[28] + o[27] + o[26] + o[25] + o[24] + o[23] + o[22] + o[21] + o[20] + o[19] + o[18] + o[17] + o[16] + o[15] + o[14] + o[13] + o[12] + o[11] + o[10] + o[9] + o[8] + o[7] + o[6] + o[5] + o[4] + o[3] + o[2] + o[1] + o[0] } # assign rs2d[4:0] = i[6:2]; @@ -199,7 +199,7 @@ rv32c = { # # assign rdpd[4:0] = {2'b01, i[9:7]}; # -# assign rs2pd[4:0] = {2'b01, i[4:2]}; +# assign rs2pd[4:0] = {2'b01, i[4:2]}; .decode diff --git a/design/dec/csrdecode b/design/dec/csrdecode index 4544cdd..aad4c86 100644 --- a/design/dec/csrdecode +++ b/design/dec/csrdecode @@ -67,7 +67,7 @@ csr_perfvg = [001100100111] csr_perfvh = [001100101...] csr_perfvi = [00110011....] -.input +.input csr = { dec_csr_rdaddr_d[11] @@ -87,23 +87,23 @@ csr = { .output csr = { - csr_misa - csr_mvendorid - csr_marchid - csr_mimpid - csr_mhartid - csr_mstatus - csr_mtvec - csr_mip - csr_mie - csr_mcyclel - csr_mcycleh - csr_minstretl - csr_minstreth - csr_mscratch - csr_mepc - csr_mcause - csr_mtval + csr_misa + csr_mvendorid + csr_marchid + csr_mimpid + csr_mhartid + csr_mstatus + csr_mtvec + csr_mip + csr_mie + csr_mcyclel + csr_mcycleh + csr_minstretl + csr_minstreth + csr_mscratch + csr_mepc + csr_mcause + csr_mtval csr_mrac csr_dmst csr_mdeau @@ -120,8 +120,8 @@ csr = { csr_mcpc csr_mfdc csr_dpc - csr_mtsel - csr_mtdata1 + csr_mtsel + csr_mtdata1 csr_mtdata2 csr_mhpmc3 csr_mhpmc4 @@ -211,19 +211,19 @@ csr[ csr_mhpme6 ] = { csr_mhpme6 } csr[ csr_micect ] = { csr_micect } csr[ csr_miccmect ] = { csr_miccmect } csr[ csr_mdccmect ] = { csr_mdccmect } -csr[ csr_dicawics ] = { csr_dicawics } -csr[ csr_dicad0 ] = { csr_dicad0 } -csr[ csr_dicad1 ] = { csr_dicad1 } -csr[ csr_dicago ] = { csr_dicago } +csr[ csr_dicawics ] = { csr_dicawics } +csr[ csr_dicad0 ] = { csr_dicad0 } +csr[ csr_dicad1 ] = { csr_dicad1 } +csr[ csr_dicago ] = { csr_dicago } csr[ csr_perfva ] = { valid_only } -csr[ csr_perfvb ] = { valid_only } -csr[ csr_perfvc ] = { valid_only } -csr[ csr_perfvd ] = { valid_only } -csr[ csr_perfve ] = { valid_only } -csr[ csr_perfvf ] = { valid_only } -csr[ csr_perfvg ] = { valid_only } -csr[ csr_perfvh ] = { valid_only } +csr[ csr_perfvb ] = { valid_only } +csr[ csr_perfvc ] = { valid_only } +csr[ csr_perfvd ] = { valid_only } +csr[ csr_perfve ] = { valid_only } +csr[ csr_perfvf ] = { valid_only } +csr[ csr_perfvg ] = { valid_only } +csr[ csr_perfvh ] = { valid_only } csr[ csr_perfvi ] = { valid_only } .end diff --git a/design/dec/dec.sv b/design/dec/dec.sv index e4c1de1..a14dee4 100644 --- a/design/dec/dec.sv +++ b/design/dec/dec.sv @@ -1,12 +1,12 @@ // 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. @@ -14,19 +14,19 @@ // limitations under the License. // dec: decode unit - decode, bypassing, ARF, interrupts -// +// //******************************************************************************** // $Id$ // -// -// Function: Decode +// +// Function: Decode // Comments: Decode, dependency scoreboard, ARF // -// +// // A -> D -> EX1 ... WB -// +// //******************************************************************************** - + module dec import swerv_types::*; ( @@ -36,12 +36,12 @@ module dec output logic dec_pause_state_cg, // pause state for clock-gating - + input logic rst_l, // reset, active low input logic [31:1] rst_vec, // reset vector, from core pins input logic nmi_int, // NMI pin - input logic [31:1] nmi_vec, // NMI vector, from pins + input logic [31:1] nmi_vec, // NMI vector, from pins input logic i_cpu_halt_req, // Asynchronous Halt request to CPU input logic i_cpu_run_req, // Asynchronous Restart request to CPU @@ -58,41 +58,41 @@ module dec 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_ib0_valid_eff_d, // effective valid taking decode into account + + + output logic dec_ib0_valid_eff_d, // effective valid taking decode into account output logic dec_ib1_valid_eff_d, 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 exu_pmu_i1_br_misp, // slot 1 branch misp + input logic exu_pmu_i0_pc4, // slot 0 4 byte branch + input logic exu_pmu_i1_br_misp, // slot 1 branch misp input logic exu_pmu_i1_br_ataken, // slot 1 branch actual taken - input logic exu_pmu_i1_pc4, // slot 1 4 byte branch + input logic exu_pmu_i1_pc4, // slot 1 4 byte branch - input logic lsu_nonblock_load_valid_dc3, // valid nonblock load at dc3 - input logic [`RV_LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_tag_dc3, // -> corresponding tag - input logic lsu_nonblock_load_inv_dc5, // invalidate request for nonblock load dc5 - input logic [`RV_LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_inv_tag_dc5, // -> 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 [`RV_LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_data_tag, // -> corresponding tag + input logic lsu_nonblock_load_valid_dc3, // valid nonblock load at dc3 + input logic [`RV_LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_tag_dc3, // -> corresponding tag + input logic lsu_nonblock_load_inv_dc5, // invalidate request for nonblock load dc5 + input logic [`RV_LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_inv_tag_dc5, // -> 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 [`RV_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_dc3, // D side load or store misaligned - + input logic [1:0] ifu_pmu_instr_aligned, // aligned instructions input logic ifu_pmu_align_stall, // aligner stalled 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_busy, // Instruction side bus busy input logic ifu_pmu_bus_trxn, // Instruction side bus transaction input logic [3:0] lsu_trigger_match_dc3, @@ -102,28 +102,31 @@ module dec 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 ifu_i1_icaf, + + input logic ifu_i0_icaf, // icache access fault + input logic ifu_i1_icaf, input logic ifu_i0_icaf_f1, // i0 has access fault on second fetch group - input logic ifu_i1_icaf_f1, - input logic ifu_i0_perr, // icache parity error - input logic ifu_i1_perr, + input logic ifu_i1_icaf_f1, + input logic ifu_i0_perr, // icache parity error + input logic ifu_i1_perr, input logic ifu_i0_sbecc, // icache/iccm single-bit error - input logic ifu_i1_sbecc, + input logic ifu_i1_sbecc, input logic ifu_i0_dbecc, // icache/iccm double-bit error input logic ifu_i1_dbecc, input logic lsu_freeze_dc3, // freeze pipe: decode -> dc3 input logic lsu_idle_any, // lsu idle for fence instructions input logic lsu_halt_idle_any, // lsu idle for halting - + input br_pkt_t i0_brp, // branch packet input br_pkt_t i1_brp, input lsu_error_pkt_t lsu_error_pkt_dc3, // LSU exception/error packet - + input logic lsu_single_ecc_error_incr, // Increment the counter for Single ECC error + + input logic lsu_load_ecc_stbuf_full_dc3, // STBUF full, ecc errors should be rfpc'd + 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 @@ -135,7 +138,7 @@ module dec input logic [31:1] exu_i1_flush_path_e4, // slot 1 flush target for mp input logic [15:0] ifu_illegal_inst, // 16b opcode for illegal inst - + input logic exu_div_stall, // stall decode for div executing input logic [31:0] exu_div_result, // final div result input logic exu_div_finish, // cycle div finishes @@ -146,14 +149,14 @@ module dec input logic [31:0] lsu_result_dc3, // load result input logic [31:0] lsu_result_corr_dc4, // corrected load result - + 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_i0_flush_final, // slot0 flush input logic exu_i1_flush_final, // slot1 flush @@ -162,10 +165,10 @@ module dec input logic exu_flush_final, // final flush input logic [31:0] exu_i0_result_e1, // alu result e1 - input logic [31:0] exu_i1_result_e1, + input logic [31:0] exu_i1_result_e1, input logic [31:0] exu_i0_result_e4, // alu result e4 - input logic [31:0] exu_i1_result_e4, + input logic [31:0] exu_i1_result_e4, input logic ifu_i0_valid, ifu_i1_valid, // fetch valids to instruction buffer @@ -173,14 +176,14 @@ module dec input logic [31:1] ifu_i0_pc, ifu_i1_pc, // pc's for instruction buffer input logic ifu_i0_pc4, ifu_i1_pc4, // indication of 4B or 2B for corresponding inst input logic [31:1] exu_i0_pc_e1, // pc's for e1 from the alu's - input logic [31:1] exu_i1_pc_e1, + input logic [31:1] exu_i1_pc_e1, input logic mexintpend, // External interrupt pending input logic timer_int, // Timer 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 + 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 @@ -192,13 +195,13 @@ module dec `endif input logic ifu_ic_debug_rd_data_valid, // diagnostic icache read data valid output 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_flush_noredir_wb , // 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_dbg_halted, // Core is halted and ready for debug command @@ -208,7 +211,7 @@ module dec output logic dec_tlu_flush_leak_one_wb, // single step output logic dec_tlu_flush_err_wb, // iside perr/ecc rfpc output logic dec_tlu_stall_dma, // stall dma access when there's a halt request - + 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 @@ -228,8 +231,8 @@ module dec input logic exu_i0_br_valid_e4, // valid input logic exu_i0_br_mp_e4, // mispredict input logic exu_i0_br_middle_e4, // middle of bank - input logic [`RV_BHT_GHR_RANGE] exu_i0_br_fghr_e4, // FGHR when predicted - + input logic [`RV_BHT_GHR_RANGE] exu_i0_br_fghr_e4, // FGHR when predicted + // branch info from pipe1 for errors or counter updates input logic [`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO] exu_i1_br_index_e4, // index input logic [1:0] exu_i1_br_hist_e4, // history @@ -245,22 +248,22 @@ module dec `ifdef RV_BTB_48 input logic [1:0] exu_i1_br_way_e4, // way hit or repl input logic [1:0] exu_i0_br_way_e4, // way hit or repl -`else +`else input logic exu_i1_br_way_e4, // way hit or repl input logic exu_i0_br_way_e4, // way hit or repl -`endif - +`endif + 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] gpr_i1_rs1_d, - output logic [31:0] gpr_i1_rs2_d, - + output logic [31:0] gpr_i1_rs1_d, + output logic [31:0] gpr_i1_rs2_d, + output logic [31:0] dec_i0_immed_d, // immediate data - output logic [31:0] dec_i1_immed_d, - + output logic [31:0] dec_i1_immed_d, + output logic [12:1] dec_i0_br_immed_d, // br immediate data - output logic [12:1] dec_i1_br_immed_d, - + output logic [12:1] dec_i1_br_immed_d, + output alu_pkt_t i0_ap, // alu packet output alu_pkt_t i1_ap, @@ -268,14 +271,14 @@ module dec output logic dec_i1_alu_decode_d, output logic dec_i0_select_pc_d, // select pc onto rs1 for jal's - output logic dec_i1_select_pc_d, + output logic dec_i1_select_pc_d, output logic [31:1] dec_i0_pc_d, dec_i1_pc_d, // pc's at decode output logic dec_i0_rs1_bypass_en_d, // rs1 bypass enable output logic dec_i0_rs2_bypass_en_d, // rs2 bypass enable output logic dec_i1_rs1_bypass_en_d, output logic dec_i1_rs2_bypass_en_d, - + output logic [31:0] i0_rs1_bypass_data_d, // rs1 bypass data output logic [31:0] i0_rs2_bypass_data_d, // rs2 bypass data output logic [31:0] i1_rs1_bypass_data_d, @@ -286,22 +289,22 @@ module dec output lsu_pkt_t lsu_p, // lsu packet output mul_pkt_t mul_p, // mul packet output div_pkt_t div_p, // div packet - + output logic [11:0] dec_lsu_offset_d, // 12b offset for load/store addresses output logic dec_i0_lsu_d, // is load/store output logic dec_i1_lsu_d, - + output logic flush_final_e3, // final flush output logic i0_flush_final_e3, // final flush from i0 - output logic dec_csr_ren_d, // csr read enable + output logic dec_csr_ren_d, // csr read enable output logic dec_tlu_cancel_e4, // Cancel lsu op at DC4 due to future trigger hit output logic dec_tlu_flush_lower_wb, // tlu flush due to late mp, exception, rfpc, or int output logic [31:1] dec_tlu_flush_path_wb, // tlu flush target - output logic dec_tlu_i0_kill_writeb_wb, // I0 is flushed, don't writeback any results to arch state - output logic dec_tlu_i1_kill_writeb_wb, // I1 is flushed, don't writeback any results to arch state + output logic dec_tlu_i0_kill_writeb_wb, // I0 is flushed, don't writeback any results to arch state + output logic dec_tlu_i1_kill_writeb_wb, // I1 is flushed, don't writeback any results to arch state output logic dec_tlu_fence_i_wb, // flush is a fence_i rfnpc, flush icache output logic dec_i0_mul_d, // chose which gpr value to use @@ -311,14 +314,14 @@ module dec output logic dec_i1_valid_e1, // i1 valid at e1 stage output logic dec_div_decode_e4, // div at e4 stage output logic [31:1] pred_correct_npc_e2, // npc if prediction is correct at e2 stage - + output logic dec_i0_rs1_bypass_en_e3, // rs1 bypass enable e3 output logic dec_i0_rs2_bypass_en_e3, // rs2 bypass enable e3 - output logic dec_i1_rs1_bypass_en_e3, - output logic dec_i1_rs2_bypass_en_e3, - output logic [31:0] i0_rs1_bypass_data_e3, // rs1 bypass data e3 + output logic dec_i1_rs1_bypass_en_e3, + output logic dec_i1_rs2_bypass_en_e3, + output logic [31:0] i0_rs1_bypass_data_e3, // rs1 bypass data e3 output logic [31:0] i0_rs2_bypass_data_e3, // rs2 bypass data e3 - output logic [31:0] i1_rs1_bypass_data_e3, + output logic [31:0] i1_rs1_bypass_data_e3, output logic [31:0] i1_rs2_bypass_data_e3, output logic dec_i0_sec_decode_e3, // secondary decode e3 output logic dec_i1_sec_decode_e3, @@ -343,11 +346,11 @@ module dec output logic [1:0] dec_tlu_perfcnt3, // toggles when perf counter 3 has an event inc output predict_pkt_t i0_predict_p_d, // prediction packet to alus - output predict_pkt_t i1_predict_p_d, + output predict_pkt_t i1_predict_p_d, - output logic dec_i0_lsu_decode_d, // load/store decode - - output logic [31:0] i0_result_e4_eff, // alu result e4 + output logic dec_i0_lsu_decode_d, // load/store decode + + output logic [31:0] i0_result_e4_eff, // alu result e4 output logic [31:0] i1_result_e4_eff, output logic dec_tlu_i0_valid_e4, // slot 0 instruction is valid at e4 @@ -357,12 +360,12 @@ module dec output logic [31:0] dec_tlu_mrac_ff, // CSR for memory region control output logic [31:1] dec_tlu_i0_pc_e4, // pc e4 - output logic [31:1] dec_tlu_i1_pc_e4, + output logic [31:1] dec_tlu_i1_pc_e4, output logic [4:2] dec_i0_data_en, // clock-gate control logic - output logic [4:1] dec_i0_ctl_en, + output logic [4:1] dec_i0_ctl_en, output logic [4:2] dec_i1_data_en, - output logic [4:1] dec_i1_ctl_en, + output logic [4:1] dec_i1_ctl_en, output logic dec_nonblock_load_freeze_dc2, // lsu must freeze nonblock load due to younger dependency in pipe @@ -370,7 +373,7 @@ module dec input logic [15:0] ifu_i1_cinst, output trace_pkt_t trace_rv_trace_pkt, // trace packet - + // feature disable from mfdc output logic dec_tlu_sideeffect_posted_disable, // disable posted writes to side-effect address output logic dec_tlu_core_ecc_disable, // disable core ECC @@ -392,8 +395,8 @@ module dec output logic dec_tlu_dccm_clk_override, // override DCCM clock domain gating output logic dec_tlu_icm_clk_override, // override ICCM clock domain gating - input logic scan_mode - + input logic scan_mode + ); localparam GPR_BANKS = 1; @@ -401,7 +404,7 @@ module dec logic dec_tlu_dec_clk_override; // to and from dec blocks logic clk_override; - + logic dec_ib1_valid_d; logic dec_ib0_valid_d; @@ -409,55 +412,55 @@ module dec logic dec_pmu_decode_stall; logic dec_pmu_presync_stall; logic dec_pmu_postsync_stall; - + logic dec_tlu_wr_pause_wb; // CSR write to pause reg is at WB. - + logic dec_i0_rs1_en_d; logic dec_i0_rs2_en_d; logic dec_fence_pending; // tell TLU to stall DMA logic [4:0] dec_i0_rs1_d; logic [4:0] dec_i0_rs2_d; - + logic dec_i1_rs1_en_d; logic dec_i1_rs2_en_d; logic [4:0] dec_i1_rs1_d; logic [4:0] dec_i1_rs2_d; - + logic [31:0] dec_i0_instr_d, dec_i1_instr_d; logic dec_tlu_pipelining_disable; logic dec_tlu_dual_issue_disable; - - + + logic [4:0] dec_i0_waddr_wb; logic dec_i0_wen_wb; logic [31:0] dec_i0_wdata_wb; - + logic [4:0] dec_i1_waddr_wb; logic dec_i1_wen_wb; logic [31:0] dec_i1_wdata_wb; - - logic dec_csr_wen_wb; // csr write enable at wb - logic [11:0] dec_csr_rdaddr_d; // read address for csr + + logic dec_csr_wen_wb; // csr write enable at wb + logic [11:0] dec_csr_rdaddr_d; // read address for csr logic [11:0] dec_csr_wraddr_wb; // write address for csryes - + logic [31:0] dec_csr_wrdata_wb; // csr write data at wb logic [31:0] dec_csr_rddata_d; // csr read data at wb - logic dec_csr_legal_d; // csr indicates legal operation + 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_any_unq_d; // valid csr - for csr legal logic dec_csr_stall_int_ff; // csr is mie/mstatus - + trap_pkt_t dec_tlu_packet_e4; - + logic dec_i0_pc4_d, dec_i1_pc4_d; logic dec_tlu_presync_d; logic dec_tlu_postsync_d; @@ -465,7 +468,7 @@ module dec logic [31:0] dec_illegal_inst; - + // GPR Bank ID write signals logic wen_bank_id; logic [GPR_BANKS_LOG2-1:0] wr_bank_id; @@ -483,11 +486,11 @@ module dec logic dec_i0_decode_d; logic dec_i1_decode_d; - + logic [3:0] dec_i0_trigger_match_d; logic [3:0] dec_i1_trigger_match_d; - + logic dec_debug_fence_d; logic dec_nonblock_load_wen; @@ -497,15 +500,15 @@ module dec logic dec_i0_load_e4; logic dec_pause_state; - + br_pkt_t dec_i0_brp; br_pkt_t dec_i1_brp; - + assign clk_override = dec_tlu_dec_clk_override; assign dec_dbg_rddata[31:0] = dec_i0_wdata_wb[31:0]; - + dec_ib_ctl instbuff (.* ); @@ -518,7 +521,7 @@ module dec assign wr_bank_id = '0; - + dec_gpr_ctl #(.GPR_BANKS(GPR_BANKS), .GPR_BANKS_LOG2(GPR_BANKS_LOG2)) arf (.*, // inputs @@ -526,24 +529,24 @@ module dec .raddr1(dec_i0_rs2_d[4:0]), .rden1(dec_i0_rs2_en_d), .raddr2(dec_i1_rs1_d[4:0]), .rden2(dec_i1_rs1_en_d), .raddr3(dec_i1_rs2_d[4:0]), .rden3(dec_i1_rs2_en_d), - + .waddr0(dec_i0_waddr_wb[4:0]), .wen0(dec_i0_wen_wb), .wd0(dec_i0_wdata_wb[31:0]), - .waddr1(dec_i1_waddr_wb[4:0]), .wen1(dec_i1_wen_wb), .wd1(dec_i1_wdata_wb[31:0]), - .waddr2(dec_nonblock_load_waddr[4:0]), .wen2(dec_nonblock_load_wen), .wd2(lsu_nonblock_load_data[31:0]), - + .waddr1(dec_i1_waddr_wb[4:0]), .wen1(dec_i1_wen_wb), .wd1(dec_i1_wdata_wb[31:0]), + .waddr2(dec_nonblock_load_waddr[4:0]), .wen2(dec_nonblock_load_wen), .wd2(lsu_nonblock_load_data[31:0]), + // outputs .rd0(gpr_i0_rs1_d[31:0]), .rd1(gpr_i0_rs2_d[31:0]), - .rd2(gpr_i1_rs1_d[31:0]), .rd3(gpr_i1_rs2_d[31:0]) + .rd2(gpr_i1_rs1_d[31:0]), .rd3(gpr_i1_rs2_d[31:0]) ); - + // Trigger - + dec_trigger dec_trigger (.*); - + // trace logic [15:0] dec_i0_cinst_d; logic [15:0] dec_i1_cinst_d; @@ -558,7 +561,7 @@ module dec logic dec_tlu_i0_exc_valid_wb1, dec_tlu_i1_exc_valid_wb1; // also need retires_p==3 - + assign trace_rv_trace_pkt.trace_rv_i_insn_ip = { 32'b0, dec_i1_inst_wb1[31:0], dec_i0_inst_wb1[31:0] }; assign trace_rv_trace_pkt.trace_rv_i_address_ip = { 32'b0, dec_i1_pc_wb1[31:1], 1'b0, dec_i0_pc_wb1[31:1], 1'b0 }; @@ -571,9 +574,9 @@ module dec assign trace_rv_trace_pkt.trace_rv_i_interrupt_ip = {dec_tlu_int_valid_wb1,2'b0}; assign trace_rv_trace_pkt.trace_rv_i_tval_ip = dec_tlu_mtval_wb1[31:0]; // replicate across ports - - + + // end trace - + endmodule // dec diff --git a/design/dec/dec_decode_ctl.sv b/design/dec/dec_decode_ctl.sv index 883922c..ee7c33d 100644 --- a/design/dec/dec_decode_ctl.sv +++ b/design/dec/dec_decode_ctl.sv @@ -1,12 +1,12 @@ // 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. @@ -21,19 +21,19 @@ module dec_decode_ctl input logic [15:0] dec_i1_cinst_d, output logic [31:0] dec_i0_inst_wb1, // 32b instruction at wb+1 for trace encoder - output logic [31:0] dec_i1_inst_wb1, + output logic [31:0] dec_i1_inst_wb1, output logic [31:1] dec_i0_pc_wb1, // 31b pc at wb+1 for trace encoder - output logic [31:1] dec_i1_pc_wb1, + output logic [31:1] dec_i1_pc_wb1, - - input logic lsu_nonblock_load_valid_dc3, // valid nonblock load at dc3 - input logic [`RV_LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_tag_dc3, // -> corresponding tag - input logic lsu_nonblock_load_inv_dc5, // invalidate request for nonblock load dc5 - input logic [`RV_LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_inv_tag_dc5, // -> 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 [`RV_LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_data_tag, // -> corresponding tag + + input logic lsu_nonblock_load_valid_dc3, // valid nonblock load at dc3 + input logic [`RV_LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_tag_dc3, // -> corresponding tag + input logic lsu_nonblock_load_inv_dc5, // invalidate request for nonblock load dc5 + input logic [`RV_LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_inv_tag_dc5, // -> 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 [`RV_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 [3:0] dec_i1_trigger_match_d, // i1 decode trigger matches @@ -41,26 +41,26 @@ module dec_decode_ctl input logic dec_tlu_wr_pause_wb, // pause instruction at wb input logic dec_tlu_pipelining_disable, // pipeline disable - presync, i0 decode only input logic dec_tlu_dual_issue_disable, // i0 decode only - + input logic dec_tlu_sec_alu_disable, // no alu ops sent to secondary alus - + input logic [3:0] lsu_trigger_match_dc3, // lsu trigger matches input logic lsu_pmu_misaligned_dc3, // perf mon: load/store misalign input logic dec_tlu_debug_stall, // debug stall decode input logic dec_tlu_flush_leak_one_wb, // 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_i1_icaf_d, + input logic dec_i0_icaf_d, // icache access fault + input logic dec_i1_icaf_d, input logic dec_i0_icaf_f1_d, // i0 instruction access fault at decode for f1 fetch group - input logic dec_i0_perr_d, // icache parity error - input logic dec_i1_perr_d, + input logic dec_i0_perr_d, // icache parity error + input logic dec_i1_perr_d, input logic dec_i0_sbecc_d, // icache/iccm single-bit error - input logic dec_i1_sbecc_d, + input logic dec_i1_sbecc_d, input logic dec_i0_dbecc_d, // icache/iccm double-bit error input logic dec_i1_dbecc_d, @@ -70,10 +70,10 @@ module dec_decode_ctl input logic [15:0] ifu_illegal_inst, // 16b illegal inst from aligner input logic [31:1] dec_i0_pc_d, // pc - + input logic lsu_freeze_dc3, // freeze pipe: decode -> dc3 input logic lsu_halt_idle_any, // lsu idle: if fence instr & ~lsu_halt_idle_any then stall decode - + input logic lsu_load_stall_any, // stall any store at load input logic lsu_store_stall_any, // stall any store at decode input logic dma_dccm_stall_any, // stall any load/store at decode @@ -82,106 +82,106 @@ module dec_decode_ctl input logic exu_div_stall, // div executing: stall decode input logic [31:0] exu_div_result, // div result - input logic dec_tlu_i0_kill_writeb_wb, // I0 is flushed, don't writeback any results to arch state - input logic dec_tlu_i1_kill_writeb_wb, // I1 is flushed, don't writeback any results to arch state + input logic dec_tlu_i0_kill_writeb_wb, // I0 is flushed, don't writeback any results to arch state + input logic dec_tlu_i1_kill_writeb_wb, // I1 is flushed, don't writeback any results to arch state input logic dec_tlu_flush_lower_wb, // trap lower flush input logic dec_tlu_flush_pause_wb, // 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_tlu_postsync_d, // CSR ops that need to be postsync'd + input logic [31:0] exu_mul_result_e3, // multiply result input logic dec_i0_pc4_d, // inst is 4B inst else 2B input logic dec_i1_pc4_d, - + 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_e1, // rs1 for csr instr - + input logic [31:0] lsu_result_dc3, // load result input logic [31:0] lsu_result_corr_dc4, // corrected load result - + input logic exu_i0_flush_final, // lower flush or i0 flush at e2 input logic exu_i1_flush_final, // lower flush or i1 flush at e2 - input logic [31:1] exu_i0_pc_e1, // pcs at e1 - input logic [31:1] exu_i1_pc_e1, - + input logic [31:1] exu_i0_pc_e1, // pcs at e1 + input logic [31:1] exu_i1_pc_e1, + input logic [31:0] dec_i0_instr_d, // inst at decode input logic [31:0] dec_i1_instr_d, input logic dec_ib0_valid_d, // inst valid at decode input logic dec_ib1_valid_d, - + input logic [31:0] exu_i0_result_e1, // from primary alu's - input logic [31:0] exu_i1_result_e1, - + input logic [31:0] exu_i1_result_e1, + input logic [31:0] exu_i0_result_e4, // from secondary alu's - input logic [31:0] exu_i1_result_e4, - + input logic [31:0] exu_i1_result_e4, + input logic clk, // for rvdffe's input logic active_clk, // clk except for halt / pause input logic free_clk, // free running clock - + input logic clk_override, // test stuff input logic rst_l, output logic dec_i0_rs1_en_d, // rs1 enable at decode - output logic dec_i0_rs2_en_d, + output logic dec_i0_rs2_en_d, output logic [4:0] dec_i0_rs1_d, // rs1 logical source output logic [4:0] dec_i0_rs2_d, - - + + output logic [31:0] dec_i0_immed_d, // 32b immediate data decode - + output logic dec_i1_rs1_en_d, output logic dec_i1_rs2_en_d, output logic [4:0] dec_i1_rs1_d, output logic [4:0] dec_i1_rs2_d, - - + + output logic [31:0] dec_i1_immed_d, output logic [12:1] dec_i0_br_immed_d, // 12b branch immediate - output logic [12:1] dec_i1_br_immed_d, - + output logic [12:1] dec_i1_br_immed_d, + output alu_pkt_t i0_ap, // alu packets output alu_pkt_t i1_ap, output logic dec_i0_decode_d, // i0 decode output logic dec_i1_decode_d, - output logic dec_ib0_valid_eff_d, // effective valid taking decode into account + output logic dec_ib0_valid_eff_d, // effective valid taking decode into account output logic dec_ib1_valid_eff_d, - + output logic dec_i0_alu_decode_d, // decode to primary alu's output logic dec_i1_alu_decode_d, - + output logic [31:0] i0_rs1_bypass_data_d, // i0 rs1 bypass data output logic [31:0] i0_rs2_bypass_data_d, // i0 rs2 bypass data output logic [31:0] i1_rs1_bypass_data_d, output logic [31:0] i1_rs2_bypass_data_d, - - + + output logic [4:0] dec_i0_waddr_wb, // i0 logical source to write to gpr's output logic dec_i0_wen_wb, // i0 write enable output logic [31:0] dec_i0_wdata_wb, // i0 write data - + output logic [4:0] dec_i1_waddr_wb, output logic dec_i1_wen_wb, output logic [31:0] dec_i1_wdata_wb, - + output logic dec_i0_select_pc_d, // i0 select pc for rs1 - branches - output logic dec_i1_select_pc_d, - + output logic dec_i1_select_pc_d, + output logic dec_i0_rs1_bypass_en_d, // i0 rs1 bypass enable output logic dec_i0_rs2_bypass_en_d, // i0 rs2 bypass enable output logic dec_i1_rs1_bypass_en_d, @@ -192,7 +192,7 @@ module dec_decode_ctl output mul_pkt_t mul_p, // multiply packet output div_pkt_t div_p, // divide packet - + output logic [11:0] dec_lsu_offset_d, output logic dec_i0_lsu_d, // chose which gpr value to use output logic dec_i1_lsu_d, @@ -204,21 +204,21 @@ module dec_decode_ctl // review output logic flush_final_e3, // flush final at e3: i0 or i1 output logic i0_flush_final_e3, // i0 flush final at e3 - + 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 dec_csr_wen_wb, // csr write enable at wb + output logic dec_csr_any_unq_d, // valid csr - for csr legal + output logic dec_csr_wen_wb, // csr write enable at wb output logic [11:0] dec_csr_rdaddr_d, // read address for csr output logic [11:0] dec_csr_wraddr_wb, // write address for csr - output logic [31:0] dec_csr_wrdata_wb, // csr write data at wb + output logic [31:0] dec_csr_wrdata_wb, // csr write data at wb output logic dec_csr_stall_int_ff, // csr is mie/mstatus - + output dec_tlu_i0_valid_e4, // i0 valid inst at e4 output dec_tlu_i1_valid_e4, - + output trap_pkt_t dec_tlu_packet_e4, // trap packet - + output logic dec_fence_pending, // tell TLU to stall DMA output logic [31:1] dec_tlu_i0_pc_e4, // i0 trap pc output logic [31:1] dec_tlu_i1_pc_e4, @@ -226,11 +226,11 @@ module dec_decode_ctl output logic [31:0] dec_illegal_inst, // illegal inst output logic dec_i1_valid_e1, // i1 valid e1 output logic dec_div_decode_e4, // i0 div e4 - output logic [31:1] pred_correct_npc_e2, // npc e2 if the prediction is correct + output logic [31:1] pred_correct_npc_e2, // npc e2 if the prediction is correct output logic dec_i0_rs1_bypass_en_e3, // i0 rs1 bypass enables e3 output logic dec_i0_rs2_bypass_en_e3, // i1 rs1 bypass enables e3 output logic dec_i1_rs1_bypass_en_e3, - output logic dec_i1_rs2_bypass_en_e3, + output logic dec_i1_rs2_bypass_en_e3, output logic [31:0] i0_rs1_bypass_data_e3, // i0 rs1 bypass data e3 output logic [31:0] i0_rs2_bypass_data_e3, // i1 rs1 bypass data e3 output logic [31:0] i1_rs1_bypass_data_e3, @@ -251,17 +251,17 @@ module dec_decode_ctl output predict_pkt_t i0_predict_p_d, // i0 predict packet decode output predict_pkt_t i1_predict_p_d, - + output logic dec_i0_lsu_decode_d, // i0 lsu decode - + output logic [31:0] i0_result_e4_eff, // i0 e4 result taking freeze into account output logic [31:0] i1_result_e4_eff, output logic [31:0] i0_result_e2, // i0 result e2 output logic [4:2] dec_i0_data_en, // clock-gating logic - output logic [4:1] dec_i0_ctl_en, + output logic [4:1] dec_i0_ctl_en, output logic [4:2] dec_i1_data_en, - output logic [4:1] dec_i1_ctl_en, + output logic [4:1] dec_i1_ctl_en, output logic [1:0] dec_pmu_instr_decoded, // number of instructions decode this cycle encoded output logic dec_pmu_decode_stall, // decode is stalled @@ -275,16 +275,16 @@ module dec_decode_ctl output logic dec_pause_state_cg, // pause state for clock-gating output logic dec_i0_load_e4, // pipe down if load is i0 or not in case of lsu_freeze - + input logic scan_mode ); - + dec_pkt_t i0_dp_raw, i0_dp; dec_pkt_t i1_dp_raw, i1_dp; - + logic [31:0] i0, i1; @@ -294,7 +294,7 @@ module dec_decode_ctl logic [31:0] i1_result_e2; logic [31:0] i0_result_e3, i1_result_e3; logic [31:0] i0_result_e4, i1_result_e4; - logic [31:0] i0_result_wb, i1_result_wb; + logic [31:0] i0_result_wb, i1_result_wb; logic [31:1] i0_pc_e1, i1_pc_e1; logic [31:1] i0_pc_e2, i1_pc_e2; @@ -302,7 +302,7 @@ module dec_decode_ctl logic [31:1] i0_pc_e4, i1_pc_e4; logic [9:0] i0_rs1bypass, i0_rs2bypass; - logic [9:0] i1_rs1bypass, i1_rs2bypass; + logic [9:0] i1_rs1bypass, i1_rs2bypass; logic i0_jalimm20, i1_jalimm20; logic i0_uiimm20, i1_uiimm20; @@ -311,16 +311,16 @@ module dec_decode_ctl logic lsu_decode_d; logic [31:0] i0_immed_d; - logic i0_presync; - logic i0_postsync; + logic i0_presync; + logic i0_postsync; logic postsync_stall; logic ps_stall; - + logic prior_inflight, prior_inflight_e1e4, prior_inflight_wb; - + logic csr_clr_d, csr_set_d, csr_write_d; - + logic csr_clr_e1,csr_set_e1,csr_write_e1,csr_imm_e1; logic [31:0] csr_mask_e1; @@ -340,11 +340,11 @@ module dec_decode_ctl logic i1_load2_block_d; logic i1_mul2_block_d; logic mul_decode_d; - logic div_decode_d; + logic div_decode_d; logic [31:1] div_pc; logic div_stall, div_stall_ff; logic [3:0] div_trigger; - + logic i0_legal; logic shift_illegal; logic illegal_inst_en; @@ -359,13 +359,13 @@ module dec_decode_ctl logic [12:1] last_br_immed_d; logic i1_depend_i0_d; logic i0_rs1_depend_i0_e1, i0_rs1_depend_i0_e2, i0_rs1_depend_i0_e3, i0_rs1_depend_i0_e4, i0_rs1_depend_i0_wb; - logic i0_rs1_depend_i1_e1, i0_rs1_depend_i1_e2, i0_rs1_depend_i1_e3, i0_rs1_depend_i1_e4, i0_rs1_depend_i1_wb; + logic i0_rs1_depend_i1_e1, i0_rs1_depend_i1_e2, i0_rs1_depend_i1_e3, i0_rs1_depend_i1_e4, i0_rs1_depend_i1_wb; logic i0_rs2_depend_i0_e1, i0_rs2_depend_i0_e2, i0_rs2_depend_i0_e3, i0_rs2_depend_i0_e4, i0_rs2_depend_i0_wb; - logic i0_rs2_depend_i1_e1, i0_rs2_depend_i1_e2, i0_rs2_depend_i1_e3, i0_rs2_depend_i1_e4, i0_rs2_depend_i1_wb; + logic i0_rs2_depend_i1_e1, i0_rs2_depend_i1_e2, i0_rs2_depend_i1_e3, i0_rs2_depend_i1_e4, i0_rs2_depend_i1_wb; logic i1_rs1_depend_i0_e1, i1_rs1_depend_i0_e2, i1_rs1_depend_i0_e3, i1_rs1_depend_i0_e4, i1_rs1_depend_i0_wb; - logic i1_rs1_depend_i1_e1, i1_rs1_depend_i1_e2, i1_rs1_depend_i1_e3, i1_rs1_depend_i1_e4, i1_rs1_depend_i1_wb; + logic i1_rs1_depend_i1_e1, i1_rs1_depend_i1_e2, i1_rs1_depend_i1_e3, i1_rs1_depend_i1_e4, i1_rs1_depend_i1_wb; logic i1_rs2_depend_i0_e1, i1_rs2_depend_i0_e2, i1_rs2_depend_i0_e3, i1_rs2_depend_i0_e4, i1_rs2_depend_i0_wb; - logic i1_rs2_depend_i1_e1, i1_rs2_depend_i1_e2, i1_rs2_depend_i1_e3, i1_rs2_depend_i1_e4, i1_rs2_depend_i1_wb; + logic i1_rs2_depend_i1_e1, i1_rs2_depend_i1_e2, i1_rs2_depend_i1_e3, i1_rs2_depend_i1_e4, i1_rs2_depend_i1_wb; logic i1_rs1_depend_i0_d, i1_rs2_depend_i0_d; logic i0_secondary_d, i1_secondary_d; @@ -376,24 +376,24 @@ module dec_decode_ctl logic i0_load_block_d; logic i0_mul_block_d; logic [3:0] i0_rs1_depth_d, i0_rs2_depth_d; - logic [3:0] i1_rs1_depth_d, i1_rs2_depth_d; + logic [3:0] i1_rs1_depth_d, i1_rs2_depth_d; logic i0_rs1_match_e1_e2, i0_rs1_match_e1_e3; - logic i0_rs2_match_e1_e2, i0_rs2_match_e1_e3; + logic i0_rs2_match_e1_e2, i0_rs2_match_e1_e3; logic i1_rs1_match_e1_e2, i1_rs1_match_e1_e3; - logic i1_rs2_match_e1_e2, i1_rs2_match_e1_e3; + logic i1_rs2_match_e1_e2, i1_rs2_match_e1_e3; logic i0_load_stall_d, i1_load_stall_d; - logic i0_store_stall_d, i1_store_stall_d; + logic i0_store_stall_d, i1_store_stall_d; logic i0_predict_nt, i0_predict_t; - logic i1_predict_nt, i1_predict_t; - + logic i1_predict_nt, i1_predict_t; + logic i0_notbr_error, i0_br_toffset_error; logic i1_notbr_error, i1_br_toffset_error; logic i0_ret_error, i1_ret_error; - logic i0_br_error, i1_br_error; - logic i0_br_error_all, i1_br_error_all; + logic i0_br_error, i1_br_error; + logic i0_br_error_all, i1_br_error_all; logic [11:0] i0_br_offset, i1_br_offset; logic freeze; @@ -401,49 +401,49 @@ module dec_decode_ctl logic [20:1] i0_pcall_imm, i1_pcall_imm; // predicted jal's logic i0_pcall_12b_offset, i1_pcall_12b_offset; logic i0_pcall_raw, i1_pcall_raw; - logic i0_pcall_case, i1_pcall_case; + logic i0_pcall_case, i1_pcall_case; logic i0_pcall, i1_pcall; logic i0_pja_raw, i1_pja_raw; - logic i0_pja_case, i1_pja_case; + logic i0_pja_case, i1_pja_case; logic i0_pja, i1_pja; logic i0_pret_case, i1_pret_case; logic i0_pret_raw, i0_pret; - logic i1_pret_raw, i1_pret; - - logic i0_jal, i1_jal; // jal's that are not predicted - + logic i1_pret_raw, i1_pret; + + logic i0_jal, i1_jal; // jal's that are not predicted + logic i0_predict_br, i1_predict_br; logic freeze_prior1, freeze_prior2; logic [31:0] i0_result_e4_freeze, i1_result_e4_freeze; - logic [31:0] i0_result_wb_freeze, i1_result_wb_freeze; + logic [31:0] i0_result_wb_freeze, i1_result_wb_freeze; logic [31:0] i1_result_wb_eff, i0_result_wb_eff; logic [2:0] i1rs1_intra, i1rs2_intra; logic i1_rs1_intra_bypass, i1_rs2_intra_bypass; logic store_data_bypass_c1, store_data_bypass_c2; logic [1:0] store_data_bypass_e4_c1, store_data_bypass_e4_c2, store_data_bypass_e4_c3; logic store_data_bypass_i0_e2_c2; - + class_pkt_t i0_rs1_class_d, i0_rs2_class_d; - class_pkt_t i1_rs1_class_d, i1_rs2_class_d; + class_pkt_t i1_rs1_class_d, i1_rs2_class_d; class_pkt_t i0_dc, i0_e1c, i0_e2c, i0_e3c, i0_e4c, i0_wbc; class_pkt_t i1_dc, i1_e1c, i1_e2c, i1_e3c, i1_e4c, i1_wbc; logic i0_rs1_match_e1, i0_rs1_match_e2, i0_rs1_match_e3; - logic i1_rs1_match_e1, i1_rs1_match_e2, i1_rs1_match_e3; + logic i1_rs1_match_e1, i1_rs1_match_e2, i1_rs1_match_e3; logic i0_rs2_match_e1, i0_rs2_match_e2, i0_rs2_match_e3; - logic i1_rs2_match_e1, i1_rs2_match_e2, i1_rs2_match_e3; - + logic i1_rs2_match_e1, i1_rs2_match_e2, i1_rs2_match_e3; + logic i0_secondary_stall_d; logic i0_ap_pc2, i0_ap_pc4; - logic i1_ap_pc2, i1_ap_pc4; + logic i1_ap_pc2, i1_ap_pc4; logic div_wen_wb; logic i0_rd_en_d; @@ -453,10 +453,10 @@ module dec_decode_ctl logic load_ldst_bypass_c1; logic load_mul_rs1_bypass_e1; - logic load_mul_rs2_bypass_e1; - + logic load_mul_rs2_bypass_e1; + logic leak1_i0_stall_in, leak1_i0_stall; - logic leak1_i1_stall_in, leak1_i1_stall; + logic leak1_i1_stall_in, leak1_i1_stall; logic leak1_mode; logic i0_csr_write_only_d; @@ -468,11 +468,11 @@ module dec_decode_ctl logic [5:0] i0_pipe_en; logic i0_e1_ctl_en, i0_e2_ctl_en, i0_e3_ctl_en, i0_e4_ctl_en, i0_wb_ctl_en; - logic i0_e1_data_en, i0_e2_data_en, i0_e3_data_en, i0_e4_data_en, i0_wb_data_en, i0_wb1_data_en; - + logic i0_e1_data_en, i0_e2_data_en, i0_e3_data_en, i0_e4_data_en, i0_wb_data_en, i0_wb1_data_en; + logic [5:0] i1_pipe_en; logic i1_e1_ctl_en, i1_e2_ctl_en, i1_e3_ctl_en, i1_e4_ctl_en, i1_wb_ctl_en; - logic i1_e1_data_en, i1_e2_data_en, i1_e3_data_en, i1_e4_data_en, i1_wb_data_en, i1_wb1_data_en; + logic i1_e1_data_en, i1_e2_data_en, i1_e3_data_en, i1_e4_data_en, i1_wb_data_en, i1_wb1_data_en; logic debug_fence_i; logic debug_fence; @@ -485,13 +485,13 @@ module dec_decode_ctl logic i1_icaf_d; logic i0_not_alu_eff, i1_not_alu_eff; - + logic disable_secondary; logic clear_pause; logic pause_state_in, pause_state; logic pause_stall; - + logic [31:1] i1_pc_wb; logic i0_brp_valid; @@ -501,29 +501,29 @@ module dec_decode_ctl logic i0_block_d; logic i1_block_d; logic ps_stall_in; - + logic freeze_after_unfreeze1; logic freeze_after_unfreeze2; logic unfreeze_cycle1; logic unfreeze_cycle2; - + logic tlu_wr_pause_wb1, tlu_wr_pause_wb2; localparam NBLOAD_SIZE = `RV_LSU_NUM_NBLOAD; localparam NBLOAD_SIZE_MSB = `RV_LSU_NUM_NBLOAD-1; - localparam NBLOAD_TAG_MSB = `RV_LSU_NUM_NBLOAD_WIDTH-1; + localparam NBLOAD_TAG_MSB = `RV_LSU_NUM_NBLOAD_WIDTH-1; // non block load cam logic - - logic cam_write, cam_inv_reset, cam_data_reset; + + 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_SIZE_MSB:0] cam_wen; logic [NBLOAD_TAG_MSB:0] load_data_tag; logic [NBLOAD_SIZE_MSB:0] nonblock_load_write; - + load_cam_pkt_t [NBLOAD_SIZE_MSB:0] cam; - load_cam_pkt_t [NBLOAD_SIZE_MSB:0] cam_in; + load_cam_pkt_t [NBLOAD_SIZE_MSB:0] cam_in; logic [4:0] nonblock_load_rd; logic i1_nonblock_load_stall, i0_nonblock_load_stall; @@ -559,16 +559,16 @@ module dec_decode_ctl logic [4:0] div_waddr_wb; logic [12:1] last_br_immed_e1, last_br_immed_e2; logic [31:0] i0_inst_d, i1_inst_d; - logic [31:0] i0_inst_e1, i1_inst_e1; + logic [31:0] i0_inst_e1, i1_inst_e1; logic [31:0] i0_inst_e2, i1_inst_e2; logic [31:0] i0_inst_e3, i1_inst_e3; logic [31:0] i0_inst_e4, i1_inst_e4; logic [31:0] i0_inst_wb, i1_inst_wb; - logic [31:0] i0_inst_wb1,i1_inst_wb1; + logic [31:0] i0_inst_wb1,i1_inst_wb1; logic [31:0] div_inst; logic [31:1] i0_pc_wb, i0_pc_wb1; - logic [31:1] i1_pc_wb1; + logic [31:1] i1_pc_wb1; logic [31:1] last_pc_e2; reg_pkt_t i0r, i1r; @@ -580,30 +580,30 @@ module dec_decode_ctl dest_pkt_t dd, e1d, e2d, e3d, e4d, wbd; dest_pkt_t e1d_in, e2d_in, e3d_in, e4d_in; - + assign freeze = lsu_freeze_dc3; `ifdef RV_NO_SECONDARY_ALU assign disable_secondary = 1; -`else +`else assign disable_secondary = dec_tlu_sec_alu_disable; `endif - - + + // 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; - + assign i0_predict_p_d.misp = '0; assign i0_predict_p_d.ataken = '0; assign i0_predict_p_d.boffset = '0; assign i0_predict_p_d.pcall = i0_pcall; // dont mark as pcall if branch error - assign i0_predict_p_d.pja = i0_pja; - assign i0_predict_p_d.pret = i0_pret; + assign i0_predict_p_d.pja = i0_pja; + assign i0_predict_p_d.pret = i0_pret; assign i0_predict_p_d.prett[31:1] = dec_i0_brp.prett[31:1]; assign i0_predict_p_d.pc4 = dec_i0_pc4_d; assign i0_predict_p_d.hist[1:0] = dec_i0_brp.hist[1:0]; @@ -623,22 +623,22 @@ module dec_decode_ctl assign i0_predict_p_d.toffset[11:0] = i0_br_offset[11:0]; assign i0_predict_p_d.fghr[`RV_BHT_GHR_RANGE] = dec_i0_brp.fghr[`RV_BHT_GHR_RANGE]; assign i0_predict_p_d.way = dec_i0_brp.way; - + assign i1_predict_p_d.misp = '0; assign i1_predict_p_d.ataken = '0; assign i1_predict_p_d.boffset = '0; assign i1_predict_p_d.pcall = i1_pcall; - assign i1_predict_p_d.pja = i1_pja; - assign i1_predict_p_d.pret = i1_pret; + assign i1_predict_p_d.pja = i1_pja; + assign i1_predict_p_d.pret = i1_pret; assign i1_predict_p_d.prett[31:1] = dec_i1_brp.prett[31:1]; assign i1_predict_p_d.pc4 = dec_i1_pc4_d; assign i1_predict_p_d.hist[1:0] = dec_i1_brp.hist[1:0]; assign i1_predict_p_d.valid = dec_i1_brp.valid & dec_i1_decode_d; assign i1_notbr_error = dec_i1_brp.valid & ~(i1_dp_raw.condbr | i1_pcall_raw | i1_pja_raw | i1_pret_raw); - + assign i1_br_toffset_error = dec_i1_brp.valid & dec_i1_brp.hist[1] & (dec_i1_brp.toffset[11:0] != i1_br_offset[11:0]) & !i1_pret_raw; assign i1_ret_error = dec_i1_brp.valid & dec_i1_brp.ret & ~i1_pret_raw; assign i1_br_error = dec_i1_brp.br_error | i1_notbr_error | i1_br_toffset_error | i1_ret_error; @@ -648,7 +648,7 @@ module dec_decode_ctl assign i1_predict_p_d.bank[1:0] = dec_i1_brp.bank[1:0]; assign i1_predict_p_d.btag[`RV_BTB_BTAG_SIZE-1:0] = dec_i1_brp.btag[`RV_BTB_BTAG_SIZE-1:0]; assign i1_br_error_all = (i1_br_error | dec_i1_brp.br_start_error); - assign i1_predict_p_d.toffset[11:0] = i1_br_offset[11:0]; + assign i1_predict_p_d.toffset[11:0] = i1_br_offset[11:0]; assign i1_predict_p_d.fghr[`RV_BHT_GHR_RANGE] = dec_i1_brp.fghr[`RV_BHT_GHR_RANGE]; assign i1_predict_p_d.way = dec_i1_brp.way; @@ -660,7 +660,7 @@ module dec_decode_ctl assign i0_icaf_d = dec_i0_icaf_d | dec_i0_dbecc_d; assign i1_icaf_d = dec_i1_icaf_d | dec_i1_dbecc_d; - + assign i0_instr_error = i0_icaf_d | dec_i0_perr_d | dec_i0_sbecc_d; always_comb begin @@ -685,25 +685,25 @@ module dec_decode_ctl i1_dp.legal = 1'b1; i1_dp.postsync = 1'b1; end - + end - + assign flush_lower_wb = dec_tlu_flush_lower_wb; - + assign i0[31:0] = dec_i0_instr_d[31:0]; - assign i1[31:0] = dec_i1_instr_d[31:0]; - + assign i1[31:0] = dec_i1_instr_d[31:0]; + assign dec_i0_select_pc_d = i0_dp.pc; - assign dec_i1_select_pc_d = i1_dp.pc; + assign dec_i1_select_pc_d = i1_dp.pc; // branches that can be predicted assign i0_predict_br = i0_dp.condbr | i0_pcall | i0_pja | i0_pret; - assign i1_predict_br = i1_dp.condbr | i1_pcall | i1_pja | i1_pret; - + assign i1_predict_br = i1_dp.condbr | i1_pcall | i1_pja | i1_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_predict_t = (dec_i0_brp.hist[1] & i0_brp_valid) & i0_predict_br; assign i0_ap.valid = (i0_dc.sec | i0_dc.alu | i0_dp.alu ); assign i0_ap.add = i0_dp.add; @@ -722,23 +722,23 @@ module dec_decode_ctl assign i0_ap.bge = i0_dp.bge; - + 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; - + assign i1_predict_nt = ~(dec_i1_brp.hist[1] & dec_i1_brp.valid) & i1_predict_br; - assign i1_predict_t = (dec_i1_brp.hist[1] & dec_i1_brp.valid) & i1_predict_br; - + assign i1_predict_t = (dec_i1_brp.hist[1] & dec_i1_brp.valid) & i1_predict_br; + assign i1_ap.valid = (i1_dc.sec | i1_dc.alu | i1_dp.alu); assign i1_ap.add = i1_dp.add; assign i1_ap.sub = i1_dp.sub; @@ -757,12 +757,12 @@ module dec_decode_ctl assign i1_ap.csr_write = 1'b0; assign i1_ap.csr_imm = 1'b0; - + assign i1_ap.jal = i1_jal; - + assign i1_ap_pc2 = ~dec_i1_pc4_d; assign i1_ap_pc4 = dec_i1_pc4_d; - + assign i1_ap.predict_nt = i1_predict_nt; assign i1_ap.predict_t = i1_predict_t; @@ -778,11 +778,12 @@ module dec_decode_ctl end end end - - assign cam_reset_same_dest_wb = wbd.i0v & wbd.i1v & (wbd.i0rd[4:0] == wbd.i1rd[4:0]) & + + + assign cam_reset_same_dest_wb = wbd.i0v & wbd.i1v & (wbd.i0rd[4:0] == wbd.i1rd[4:0]) & wbd.i0load & nonblock_load_valid_wb & ~dec_tlu_i0_kill_writeb_wb & ~dec_tlu_i1_kill_writeb_wb; - - + + assign cam_write = lsu_nonblock_load_valid_dc3; assign cam_write_tag[NBLOAD_TAG_MSB:0] = lsu_nonblock_load_tag_dc3[NBLOAD_TAG_MSB:0]; @@ -794,27 +795,28 @@ module dec_decode_ctl assign nonblock_load_rd[4:0] = (e3d.i0load) ? e3d.i0rd[4:0] : e3d.i1rd[4:0]; // rd data + // checks -`ifdef ASSERT_ON +`ifdef ASSERT_ON assert_dec_data_valid_data_error_onehot: assert #0 ($onehot0({lsu_nonblock_load_data_valid,lsu_nonblock_load_data_error})); - + assert_dec_cam_inv_reset_onehot: assert #0 ($onehot0(cam_inv_reset_val[NBLOAD_SIZE_MSB:0])); assert_dec_cam_data_reset_onehot: assert #0 ($onehot0(cam_data_reset_val[NBLOAD_SIZE_MSB:0])); -`endif - - // case of multiple loads to same dest ie. x1 ... you have to invalidate the older one +`endif + + // case of multiple loads to same dest ie. x1 ... you have to invalidate the older one for (genvar i=0; i used for clockgating for wb stage ctl logic rvdff #(1) divwbff (.*, .clk(active_clk), .din(exu_div_finish), .dout(div_wen_wb)); - + assign i0_result_e1[31:0] = exu_i0_result_e1[31:0]; - assign i1_result_e1[31:0] = exu_i1_result_e1[31:0]; + assign i1_result_e1[31:0] = exu_i1_result_e1[31:0]; // pipe the results down the pipe rvdffe #(32) i0e2resultff (.*, .en(i0_e2_data_en), .din(i0_result_e1[31:0]), .dout(i0_result_e2[31:0])); - rvdffe #(32) i1e2resultff (.*, .en(i1_e2_data_en), .din(i1_result_e1[31:0]), .dout(i1_result_e2[31:0])); + rvdffe #(32) i1e2resultff (.*, .en(i1_e2_data_en), .din(i1_result_e1[31:0]), .dout(i1_result_e2[31:0])); rvdffe #(32) i0e3resultff (.*, .en(i0_e3_data_en), .din(i0_result_e2[31:0]), .dout(i0_result_e3[31:0])); - rvdffe #(32) i1e3resultff (.*, .en(i1_e3_data_en), .din(i1_result_e2[31:0]), .dout(i1_result_e3[31:0])); + rvdffe #(32) i1e3resultff (.*, .en(i1_e3_data_en), .din(i1_result_e2[31:0]), .dout(i1_result_e3[31:0])); assign i0_result_e3_final[31:0] = (e3d.i0v & e3d.i0load) ? lsu_result_dc3[31:0] : (e3d.i0v & e3d.i0mul) ? exu_mul_result_e3[31:0] : i0_result_e3[31:0]; - assign i1_result_e3_final[31:0] = (e3d.i1v & e3d.i1load) ? lsu_result_dc3[31:0] : (e3d.i1v & e3d.i1mul) ? exu_mul_result_e3[31:0] : i1_result_e3[31:0]; + assign i1_result_e3_final[31:0] = (e3d.i1v & e3d.i1load) ? lsu_result_dc3[31:0] : (e3d.i1v & e3d.i1mul) ? exu_mul_result_e3[31:0] : i1_result_e3[31:0]; rvdffe #(32) i0e4resultff (.*, .en(i0_e4_data_en), .din(i0_result_e3_final[31:0]), .dout(i0_result_e4[31:0])); - rvdffe #(32) i1e4resultff (.*, .en(i1_e4_data_en), .din(i1_result_e3_final[31:0]), .dout(i1_result_e4[31:0])); - + rvdffe #(32) i1e4resultff (.*, .en(i1_e4_data_en), .din(i1_result_e3_final[31:0]), .dout(i1_result_e4[31:0])); + assign i0_result_e4_final[31:0] = - ( e4d.i0secondary) ? exu_i0_result_e4[31:0] : (e4d.i0v & e4d.i0load) ? lsu_result_corr_dc4[31:0] : i0_result_e4[31:0]; - - assign i1_result_e4_final[31:0] = + ( e4d.i0secondary) ? exu_i0_result_e4[31:0] : (e4d.i0v & e4d.i0load) ? lsu_result_corr_dc4[31:0] : i0_result_e4[31:0]; + + assign i1_result_e4_final[31:0] = (e4d.i1v & e4d.i1secondary) ? exu_i1_result_e4[31:0] : (e4d.i1v & e4d.i1load) ? lsu_result_corr_dc4[31:0] :i1_result_e4[31:0]; rvdffe #(32) i0wbresultff (.*, .en(i0_wb_data_en), .din(i0_result_e4_final[31:0]), .dout(i0_result_wb_raw[31:0])); - rvdffe #(32) i1wbresultff (.*, .en(i1_wb_data_en), .din(i1_result_e4_final[31:0]), .dout(i1_result_wb_raw[31:0])); + rvdffe #(32) i1wbresultff (.*, .en(i1_wb_data_en), .din(i1_result_e4_final[31:0]), .dout(i1_result_wb_raw[31:0])); assign i0_result_wb[31:0] = (div_wen_wb) ? exu_div_result[31:0] : i0_result_wb_raw[31:0]; assign i1_result_wb[31:0] = i1_result_wb_raw[31:0]; - + rvdffe #(12) e1brpcff (.*, .en(i0_e1_data_en), .din(last_br_immed_d[12:1] ), .dout(last_br_immed_e1[12:1])); rvdffe #(12) e2brpcff (.*, .en(i0_e2_data_en), .din(last_br_immed_e1[12:1]), .dout(last_br_immed_e2[12:1])); + // trace stuff rvdffe #(32) divinstff (.*, .en(i0_div_decode_d), .din(i0_inst_d[31:0]), .dout(div_inst[31:0])); - + assign i0_inst_d[31:0] = (dec_i0_pc4_d) ? i0[31:0] : {16'b0, dec_i0_cinst_d[15:0] }; - + rvdffe #(32) i0e1instff (.*, .en(i0_e1_data_en), .din(i0_inst_d[31:0]), .dout(i0_inst_e1[31:0])); - rvdffe #(32) i0e2instff (.*, .en(i0_e2_data_en), .din(i0_inst_e1[31:0]), .dout(i0_inst_e2[31:0])); + rvdffe #(32) i0e2instff (.*, .en(i0_e2_data_en), .din(i0_inst_e1[31:0]), .dout(i0_inst_e2[31:0])); rvdffe #(32) i0e3instff (.*, .en(i0_e3_data_en), .din(i0_inst_e2[31:0]), .dout(i0_inst_e3[31:0])); rvdffe #(32) i0e4instff (.*, .en(i0_e4_data_en), .din(i0_inst_e3[31:0]), .dout(i0_inst_e4[31:0])); rvdffe #(32) i0wbinstff (.*, .en(i0_wb_data_en | exu_div_finish), .din( (exu_div_finish) ? div_inst[31:0] : i0_inst_e4[31:0]), .dout(i0_inst_wb[31:0])); - rvdffe #(32) i0wb1instff (.*, .en(i0_wb1_data_en | div_wen_wb), .din(i0_inst_wb[31:0]), .dout(i0_inst_wb1[31:0])); + rvdffe #(32) i0wb1instff (.*, .en(i0_wb1_data_en | div_wen_wb), .din(i0_inst_wb[31:0]), .dout(i0_inst_wb1[31:0])); assign i1_inst_d[31:0] = (dec_i1_pc4_d) ? i1[31:0] : {16'b0, dec_i1_cinst_d[15:0] }; - + rvdffe #(32) i1e1instff (.*, .en(i1_e1_data_en), .din(i1_inst_d[31:0]), .dout(i1_inst_e1[31:0])); - rvdffe #(32) i1e2instff (.*, .en(i1_e2_data_en), .din(i1_inst_e1[31:0]), .dout(i1_inst_e2[31:0])); + rvdffe #(32) i1e2instff (.*, .en(i1_e2_data_en), .din(i1_inst_e1[31:0]), .dout(i1_inst_e2[31:0])); rvdffe #(32) i1e3instff (.*, .en(i1_e3_data_en), .din(i1_inst_e2[31:0]), .dout(i1_inst_e3[31:0])); rvdffe #(32) i1e4instff (.*, .en(i1_e4_data_en), .din(i1_inst_e3[31:0]), .dout(i1_inst_e4[31:0])); rvdffe #(32) i1wbinstff (.*, .en(i1_wb_data_en), .din(i1_inst_e4[31:0]), .dout(i1_inst_wb[31:0])); - rvdffe #(32) i1wb1instff (.*, .en(i1_wb1_data_en),.din(i1_inst_wb[31:0]), .dout(i1_inst_wb1[31:0])); + rvdffe #(32) i1wb1instff (.*, .en(i1_wb1_data_en),.din(i1_inst_wb[31:0]), .dout(i1_inst_wb1[31:0])); assign dec_i0_inst_wb1[31:0] = i0_inst_wb1[31:0]; - assign dec_i1_inst_wb1[31:0] = i1_inst_wb1[31:0]; + assign dec_i1_inst_wb1[31:0] = i1_inst_wb1[31:0]; rvdffe #(31) i0wbpcff (.*, .en(i0_wb_data_en | exu_div_finish), .din(dec_tlu_i0_pc_e4[31:1]), .dout(i0_pc_wb[31:1])); - rvdffe #(31) i0wb1pcff (.*, .en(i0_wb1_data_en | div_wen_wb), .din(i0_pc_wb[31:1]), .dout(i0_pc_wb1[31:1])); + rvdffe #(31) i0wb1pcff (.*, .en(i0_wb1_data_en | div_wen_wb), .din(i0_pc_wb[31:1]), .dout(i0_pc_wb1[31:1])); - rvdffe #(31) i1wb1pcff (.*, .en(i1_wb1_data_en),.din(i1_pc_wb[31:1]), .dout(i1_pc_wb1[31:1])); + rvdffe #(31) i1wb1pcff (.*, .en(i1_wb1_data_en),.din(i1_pc_wb[31:1]), .dout(i1_pc_wb1[31:1])); assign dec_i0_pc_wb1[31:1] = i0_pc_wb1[31:1]; - assign dec_i1_pc_wb1[31:1] = i1_pc_wb1[31:1]; - - + assign dec_i1_pc_wb1[31:1] = i1_pc_wb1[31:1]; + + // pipe the pc's down the pipe assign i0_pc_e1[31:1] = exu_i0_pc_e1[31:1]; - assign i1_pc_e1[31:1] = exu_i1_pc_e1[31:1]; - + assign i1_pc_e1[31:1] = exu_i1_pc_e1[31:1]; + rvdffe #(31) i0e2pcff (.*, .en(i0_e2_data_en), .din(i0_pc_e1[31:1]), .dout(i0_pc_e2[31:1])); rvdffe #(31) i0e3pcff (.*, .en(i0_e3_data_en), .din(i0_pc_e2[31:1]), .dout(i0_pc_e3[31:1])); rvdffe #(31) i0e4pcff (.*, .en(i0_e4_data_en), .din(i0_pc_e3[31:1]), .dout(i0_pc_e4[31:1])); @@ -2328,15 +2336,15 @@ end : cam_array rvdffe #(31) i1e4pcff (.*, .en(i1_e4_data_en), .din(i1_pc_e3[31:1]), .dout(i1_pc_e4[31:1])); assign dec_i0_pc_e3[31:1] = i0_pc_e3[31:1]; - assign dec_i1_pc_e3[31:1] = i1_pc_e3[31:1]; - - + assign dec_i1_pc_e3[31:1] = i1_pc_e3[31:1]; + + assign dec_tlu_i0_pc_e4[31:1] = (exu_div_finish) ? div_pc[31:1] : i0_pc_e4[31:1]; - assign dec_tlu_i1_pc_e4[31:1] = i1_pc_e4[31:1]; - + assign dec_tlu_i1_pc_e4[31:1] = i1_pc_e4[31:1]; + // generate the correct npc for correct br predictions assign last_pc_e2[31:1] = (e2d.i1valid) ? i1_pc_e2[31:1] : i0_pc_e2[31:1]; - + rvbradder ibradder_correct ( .pc(last_pc_e2[31:1]), .offset(last_br_immed_e2[12:1]), @@ -2345,18 +2353,18 @@ end : cam_array - // needed for debug triggers - rvdffe #(31) i1wbpcff (.*, .en(i1_wb_data_en), .din(dec_tlu_i1_pc_e4[31:1]), .dout(i1_pc_wb[31:1])); + // needed for debug triggers + rvdffe #(31) i1wbpcff (.*, .en(i1_wb_data_en), .din(dec_tlu_i1_pc_e4[31:1]), .dout(i1_pc_wb[31:1])); + + + - - - // bit 9 is priority match, bit 0 lowest priority, i1_e1, i0_e1, i1_e2, ... i1_wb, i0_wb - + assign i0_rs1bypass[9:0] = { i0_rs1_depth_d[3:0] == 4'd1 & i0_rs1_class_d.alu, i0_rs1_depth_d[3:0] == 4'd2 & i0_rs1_class_d.alu, i0_rs1_depth_d[3:0] == 4'd3 & i0_rs1_class_d.alu, @@ -2367,7 +2375,7 @@ end : cam_array i0_rs1_depth_d[3:0] == 4'd8 & (i0_rs1_class_d.alu | i0_rs1_class_d.load | i0_rs1_class_d.mul | i0_rs1_class_d.sec), i0_rs1_depth_d[3:0] == 4'd9 & (i0_rs1_class_d.alu | i0_rs1_class_d.load | i0_rs1_class_d.mul | i0_rs1_class_d.sec), i0_rs1_depth_d[3:0] == 4'd10 & (i0_rs1_class_d.alu | i0_rs1_class_d.load | i0_rs1_class_d.mul | i0_rs1_class_d.sec) }; - + assign i0_rs2bypass[9:0] = { i0_rs2_depth_d[3:0] == 4'd1 & i0_rs2_class_d.alu, i0_rs2_depth_d[3:0] == 4'd2 & i0_rs2_class_d.alu, @@ -2379,7 +2387,7 @@ end : cam_array i0_rs2_depth_d[3:0] == 4'd8 & (i0_rs2_class_d.alu | i0_rs2_class_d.load | i0_rs2_class_d.mul | i0_rs2_class_d.sec), i0_rs2_depth_d[3:0] == 4'd9 & (i0_rs2_class_d.alu | i0_rs2_class_d.load | i0_rs2_class_d.mul | i0_rs2_class_d.sec), i0_rs2_depth_d[3:0] == 4'd10 & (i0_rs2_class_d.alu | i0_rs2_class_d.load | i0_rs2_class_d.mul | i0_rs2_class_d.sec) }; - + assign i1_rs1bypass[9:0] = { i1_rs1_depth_d[3:0] == 4'd1 & i1_rs1_class_d.alu, i1_rs1_depth_d[3:0] == 4'd2 & i1_rs1_class_d.alu, @@ -2391,7 +2399,7 @@ end : cam_array i1_rs1_depth_d[3:0] == 4'd8 & (i1_rs1_class_d.alu | i1_rs1_class_d.load | i1_rs1_class_d.mul | i1_rs1_class_d.sec), i1_rs1_depth_d[3:0] == 4'd9 & (i1_rs1_class_d.alu | i1_rs1_class_d.load | i1_rs1_class_d.mul | i1_rs1_class_d.sec), i1_rs1_depth_d[3:0] == 4'd10 & (i1_rs1_class_d.alu | i1_rs1_class_d.load | i1_rs1_class_d.mul | i1_rs1_class_d.sec) }; - + assign i1_rs2bypass[9:0] = { i1_rs2_depth_d[3:0] == 4'd1 & i1_rs2_class_d.alu, i1_rs2_depth_d[3:0] == 4'd2 & i1_rs2_class_d.alu, @@ -2403,16 +2411,16 @@ end : cam_array i1_rs2_depth_d[3:0] == 4'd8 & (i1_rs2_class_d.alu | i1_rs2_class_d.load | i1_rs2_class_d.mul | i1_rs2_class_d.sec), i1_rs2_depth_d[3:0] == 4'd9 & (i1_rs2_class_d.alu | i1_rs2_class_d.load | i1_rs2_class_d.mul | i1_rs2_class_d.sec), i1_rs2_depth_d[3:0] == 4'd10 & (i1_rs2_class_d.alu | i1_rs2_class_d.load | i1_rs2_class_d.mul | i1_rs2_class_d.sec) }; - + assign dec_i0_rs1_bypass_en_d = |i0_rs1bypass[9:0]; assign dec_i0_rs2_bypass_en_d = |i0_rs2bypass[9:0]; assign dec_i1_rs1_bypass_en_d = |i1_rs1bypass[9:0]; - assign dec_i1_rs2_bypass_en_d = |i1_rs2bypass[9:0]; + assign dec_i1_rs2_bypass_en_d = |i1_rs2bypass[9:0]; + - assign i0_rs1_bypass_data_d[31:0] = ({32{i0_rs1bypass[9]}} & i1_result_e1[31:0]) | ({32{i0_rs1bypass[8]}} & i0_result_e1[31:0]) | @@ -2424,7 +2432,7 @@ end : cam_array ({32{i0_rs1bypass[2]}} & i0_result_e4_final[31:0]) | ({32{i0_rs1bypass[1]}} & i1_result_wb[31:0]) | ({32{i0_rs1bypass[0]}} & i0_result_wb[31:0]); - + assign i0_rs2_bypass_data_d[31:0] = ({32{i0_rs2bypass[9]}} & i1_result_e1[31:0]) | ({32{i0_rs2bypass[8]}} & i0_result_e1[31:0]) | @@ -2436,7 +2444,7 @@ end : cam_array ({32{i0_rs2bypass[2]}} & i0_result_e4_final[31:0]) | ({32{i0_rs2bypass[1]}} & i1_result_wb[31:0]) | ({32{i0_rs2bypass[0]}} & i0_result_wb[31:0]); - + assign i1_rs1_bypass_data_d[31:0] = ({32{i1_rs1bypass[9]}} & i1_result_e1[31:0]) | ({32{i1_rs1bypass[8]}} & i0_result_e1[31:0]) | ({32{i1_rs1bypass[7]}} & i1_result_e2[31:0]) | @@ -2447,7 +2455,7 @@ end : cam_array ({32{i1_rs1bypass[2]}} & i0_result_e4_final[31:0]) | ({32{i1_rs1bypass[1]}} & i1_result_wb[31:0]) | ({32{i1_rs1bypass[0]}} & i0_result_wb[31:0]); - + assign i1_rs2_bypass_data_d[31:0] = ({32{i1_rs2bypass[9]}} & i1_result_e1[31:0]) | ({32{i1_rs2bypass[8]}} & i0_result_e1[31:0]) | @@ -2459,12 +2467,12 @@ end : cam_array ({32{i1_rs2bypass[2]}} & i0_result_e4_final[31:0]) | ({32{i1_rs2bypass[1]}} & i1_result_wb[31:0]) | ({32{i1_rs2bypass[0]}} & i0_result_wb[31:0]); - - - - - - + + + + + + endmodule // file "decode" is human readable file that has all of the instruction decodes defined and is part of git repo @@ -2491,8 +2499,8 @@ module dec_dec_ctl ); logic [31:0] i; - - + + assign i[31:0] = inst[31:0]; @@ -2656,5 +2664,5 @@ assign out.legal = (!i[31]&!i[30]&i[29]&i[28]&!i[27]&!i[26]&!i[25]&!i[24]&!i[23] i[13]&!i[6]&!i[5]&i[4]&!i[3]&i[1]&i[0]) | (!i[14]&!i[12]&!i[6]&!i[4] &!i[3]&!i[2]&i[1]&i[0]) | (!i[6]&i[4]&!i[3]&i[2]&i[1]&i[0]); - + endmodule diff --git a/design/dec/dec_gpr_ctl.sv b/design/dec/dec_gpr_ctl.sv index e1822cd..5110c1b 100644 --- a/design/dec/dec_gpr_ctl.sv +++ b/design/dec/dec_gpr_ctl.sv @@ -1,12 +1,12 @@ // 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. @@ -29,22 +29,22 @@ module dec_gpr_ctl #(parameter GPR_BANKS = 1, input logic [4:0] waddr0, // logical write addresses input logic [4:0] waddr1, - input logic [4:0] waddr2, + input logic [4:0] waddr2, input logic wen0, // write enables - input logic wen1, + input logic wen1, input logic wen2, input logic [31:0] wd0, // write data input logic [31:0] wd1, input logic [31:0] wd2, - + input logic wen_bank_id, // write enable for banks input logic [GPR_BANKS_LOG2-1:0] wr_bank_id, // read enable for banks input logic clk, input logic rst_l, - + output logic [31:0] rd0, // read data output logic [31:0] rd1, output logic [31:0] rd2, @@ -59,55 +59,55 @@ module dec_gpr_ctl #(parameter GPR_BANKS = 1, logic [31:1] gpr_wr_en; logic [GPR_BANKS-1:0][31:1] gpr_bank_wr_en; logic [GPR_BANKS_LOG2-1:0] gpr_bank_id; - + //assign gpr_bank_id[GPR_BANKS_LOG2-1:0] = '0; - rvdffs #(GPR_BANKS_LOG2) bankid_ff (.*, .clk(active_clk), .en(wen_bank_id), .din(wr_bank_id[GPR_BANKS_LOG2-1:0]), .dout(gpr_bank_id[GPR_BANKS_LOG2-1:0])); - - // GPR Write Enables for power savings + rvdffs #(GPR_BANKS_LOG2) bankid_ff (.*, .clk(active_clk), .en(wen_bank_id), .din(wr_bank_id[GPR_BANKS_LOG2-1:0]), .dout(gpr_bank_id[GPR_BANKS_LOG2-1:0])); + + // GPR Write Enables for power savings assign gpr_wr_en[31:1] = (w0v[31:1] | w1v[31:1] | w2v[31:1]); for (genvar i=0; i 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); - +// 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_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_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 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}) | @@ -404,38 +404,38 @@ module dec_ib_ctl // special fence csr for use only in debug mode logic debug_fence_in; - + assign debug_fence_in = debug_write_csr & (dcsr[11:0] == 12'h7c4); - - rvdff #(1) debug_fence_ff (.*, .clk(free_clk), .din(debug_fence_in), .dout(dec_debug_fence_d)); - - + + rvdff #(1) debug_fence_ff (.*, .clk(free_clk), .din(debug_fence_in), .dout(dec_debug_fence_d)); + + assign ib0_in[31:0] = ({32{write_i0_ib0}} & ((debug_valid) ? ib0_debug_in[31:0] : ifu_i0_instr[31:0])) | ({32{shift_ib1_ib0}} & ib1[31:0]) | ({32{shift_ib2_ib0}} & ib2[31:0]); - + rvdffe #(32) ib0ff (.*, .en(ibwrite[0]), .din(ib0_in[31:0]), .dout(ib0[31:0])); assign dec_ib3_valid_d = ibval[3]; assign dec_ib2_valid_d = ibval[2]; assign dec_ib1_valid_d = ibval[1]; - assign dec_ib0_valid_d = ibval[0]; - + assign dec_ib0_valid_d = ibval[0]; + assign dec_i0_instr_d[31:0] = ib0[31:0]; - assign dec_i1_instr_d[31:0] = ib1[31:0]; + assign dec_i1_instr_d[31:0] = ib1[31:0]; assign dec_i0_brp = bp0; - assign dec_i1_brp = bp1; - - + assign dec_i1_brp = bp1; + + assign shift1 = dec_i0_decode_d & ~dec_i1_decode_d; assign shift2 = dec_i0_decode_d & dec_i1_decode_d; assign shift0 = ~dec_i0_decode_d; - - + + // compute shifted ib valids to determine where to write assign shift_ibval[3:0] = ({4{shift1}} & {1'b0, ibval[3:1] }) | ({4{shift2}} & {2'b0, ibval[3:2]}) | @@ -445,7 +445,7 @@ module dec_ib_ctl assign write_i0_ib1 = shift_ibval[0] & ~shift_ibval[1] & ifu_i0_val; assign write_i0_ib2 = shift_ibval[1] & ~shift_ibval[2] & ifu_i0_val; assign write_i0_ib3 = shift_ibval[2] & ~shift_ibval[3] & ifu_i0_val; - + assign write_i1_ib1 = ~shift_ibval[0] & ifu_i1_val; assign write_i1_ib2 = shift_ibval[0] & ~shift_ibval[1] & ifu_i1_val; assign write_i1_ib3 = shift_ibval[1] & ~shift_ibval[2] & ifu_i1_val; @@ -453,11 +453,11 @@ module dec_ib_ctl assign shift_ib1_ib0 = shift1 & ibval[1]; assign shift_ib2_ib1 = shift1 & ibval[2]; - assign shift_ib3_ib2 = shift1 & ibval[3]; - + assign shift_ib3_ib2 = shift1 & ibval[3]; + assign shift_ib2_ib0 = shift2 & ibval[2]; assign shift_ib3_ib1 = shift2 & ibval[3]; - - + + endmodule diff --git a/design/dec/dec_tlu_ctl.sv b/design/dec/dec_tlu_ctl.sv index 4464bec..c2ab8dc 100644 --- a/design/dec/dec_tlu_ctl.sv +++ b/design/dec/dec_tlu_ctl.sv @@ -1,12 +1,12 @@ // 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. @@ -17,9 +17,9 @@ //******************************************************************************** // dec_tlu_ctl.sv // -// +// // Function: CSRs, Commit/WB, flushing, exceptions, interrupts -// Comments: +// Comments: // //******************************************************************************** @@ -31,17 +31,17 @@ module dec_tlu_ctl input logic free_clk, input logic rst_l, input logic scan_mode, - + input logic [31:1] rst_vec, // reset vector, from core pins input logic nmi_int, // nmi pin - input logic [31:1] nmi_vec, // nmi vector + input logic [31:1] nmi_vec, // nmi vector input logic i_cpu_halt_req, // Asynchronous Halt request to CPU input logic i_cpu_run_req, // Asynchronous Restart request to CPU 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 - + // perf counter inputs input logic [1:0] ifu_pmu_instr_aligned, // aligned instructions input logic ifu_pmu_align_stall, // aligner stalled @@ -49,7 +49,7 @@ module dec_tlu_ctl 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_busy, // Instruction side bus busy input logic ifu_pmu_bus_trxn, // Instruction side bus transaction input logic [1:0] dec_pmu_instr_decoded, // decoded instructions input logic dec_pmu_decode_stall, // decode stall @@ -58,13 +58,13 @@ module dec_tlu_ctl input logic lsu_freeze_dc3, // lsu freeze stall 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 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 exu_pmu_i1_br_misp, // pipe 1 branch misp + input logic exu_pmu_i0_pc4, // pipe 0 4 byte branch + input logic exu_pmu_i1_br_misp, // pipe 1 branch misp input logic exu_pmu_i1_br_ataken, // pipe 1 branch actual taken - input logic exu_pmu_i1_pc4, // pipe 1 4 byte branch + input logic exu_pmu_i1_pc4, // pipe 1 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 @@ -72,8 +72,11 @@ module dec_tlu_ctl input logic iccm_dma_sb_error, // I side dma single bit error - + input lsu_error_pkt_t lsu_error_pkt_dc3, // lsu precise exception/error packet + input logic lsu_single_ecc_error_incr, // Increment the counter for Single ECC error + + input logic lsu_load_ecc_stbuf_full_dc3, // STBUF full, ecc errors should be rfpc'd input logic dec_pause_state, // Pause counter not zero input logic lsu_imprecise_error_store_any, // store bus error @@ -82,11 +85,11 @@ module dec_tlu_ctl input logic lsu_freeze_external_ints_dc3, // load to side effect region 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 dec_csr_wen_wb, // csr write enable at wb - input logic [11:0] dec_csr_rdaddr_d, // read address for csr + input logic dec_csr_any_unq_d, // valid csr - for csr legal + input logic dec_csr_wen_wb, // csr write enable at wb + input logic [11:0] dec_csr_rdaddr_d, // read address for csr input logic [11:0] dec_csr_wraddr_wb, // write address for csr - input logic [31:0] dec_csr_wrdata_wb, // csr write data at wb + input logic [31:0] dec_csr_wrdata_wb, // csr write data at wb input logic dec_csr_stall_int_ff, // csr is mie/mstatus input logic dec_tlu_i0_valid_e4, // pipe 0 op at e4 is valid @@ -119,8 +122,8 @@ module dec_tlu_ctl input logic exu_i0_br_valid_e4, // valid input logic exu_i0_br_mp_e4, // mispredict input logic exu_i0_br_middle_e4, // middle of bank - input logic [`RV_BHT_GHR_RANGE] exu_i0_br_fghr_e4, // FGHR when predicted - + input logic [`RV_BHT_GHR_RANGE] exu_i0_br_fghr_e4, // FGHR when predicted + // branch info from pipe1 for errors or counter updates input logic [`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO] exu_i1_br_index_e4, // index input logic [1:0] exu_i1_br_hist_e4, // history @@ -186,27 +189,27 @@ module dec_tlu_ctl output logic [3:0] dec_tlu_meicurpl, // to PIC output logic [3:0] dec_tlu_meipt, // to PIC - + output br_tlu_pkt_t dec_tlu_br0_wb_pkt, // branch pkt to bp output br_tlu_pkt_t dec_tlu_br1_wb_pkt, // branch pkt to bp output logic [31:0] dec_csr_rddata_d, // csr read data at wb output logic dec_csr_legal_d, // csr indicates legal operation - output logic dec_tlu_i0_kill_writeb_wb, // I0 is flushed, don't writeback any results to arch state - output logic dec_tlu_i1_kill_writeb_wb, // I1 is flushed, don't writeback any results to arch state + output logic dec_tlu_i0_kill_writeb_wb, // I0 is flushed, don't writeback any results to arch state + output logic dec_tlu_i1_kill_writeb_wb, // I1 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 [31:1] dec_tlu_flush_path_wb, // flush pc output logic dec_tlu_fence_i_wb, // flush is a fence_i rfnpc, flush icache - + 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_cancel_e4, // Cancel lsu op at DC4 due to future trigger hit - + output logic dec_tlu_wr_pause_wb, // CSR write to pause reg is at WB. output logic dec_tlu_flush_pause_wb, // Flush is due to pause @@ -223,7 +226,7 @@ module dec_tlu_ctl 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_sideeffect_posted_disable, // disable posted writes to side-effect address output logic dec_tlu_dual_issue_disable, // disable dual issue @@ -236,7 +239,7 @@ module dec_tlu_ctl output logic dec_tlu_ld_miss_byp_wb_disable, // disable loads miss bypass write buffer output logic dec_tlu_pipelining_disable, // disable pipelining 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 @@ -250,14 +253,14 @@ module dec_tlu_ctl ); - logic dec_csr_wen_wb_mod, clk_override, e4e5_int_clk, 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_wb, - i0_mp_e4, i1_mp_e4, sel_npc_e4, sel_npc_wb, ce_int, mtval_capture_lsu_wb, wr_mdeau_wb, micect_cout_nc, miccmect_cout_nc, + logic dec_csr_wen_wb_mod, clk_override, e4e5_int_clk, 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_wb, + i0_mp_e4, i1_mp_e4, sel_npc_e4, sel_npc_wb, ce_int, mtval_capture_lsu_wb, wr_mdeau_wb, micect_cout_nc, miccmect_cout_nc, mdccmect_cout_nc, nmi_in_debug_mode, dpc_capture_npc, dpc_capture_pc, tdata_load, tdata_opcode, tdata_action, perfcnt_halted; - + logic reset_delayed, reset_detect, reset_detected; - logic wr_mstatus_wb, wr_mtvec_wb, wr_mie_wb, wr_mcyclel_wb, wr_mcycleh_wb, + logic wr_mstatus_wb, wr_mtvec_wb, wr_mie_wb, wr_mcyclel_wb, wr_mcycleh_wb, wr_minstretl_wb, wr_minstreth_wb, wr_mscratch_wb, wr_mepc_wb, wr_mcause_wb, wr_mtval_wb, wr_mrac_wb, wr_meihap_wb, wr_meicurpl_wb, wr_meipt_wb, wr_dcsr_wb, wr_dpc_wb, wr_meicidpl_wb, wr_meivt_wb, wr_meicpct_wb, wr_micect_wb, wr_miccmect_wb, @@ -272,14 +275,14 @@ module dec_tlu_ctl logic [1:0] mstatus_ns, mstatus; logic mstatus_mie_ns; logic [30:0] mtvec_ns, mtvec; - logic [15:2] dcsr_ns, dcsr; + logic [15:2] dcsr_ns, dcsr; logic [3:0] mip_ns, mip; logic [3: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 [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; @@ -311,12 +314,12 @@ module dec_tlu_ctl `ifdef RV_ICACHE_ECC logic [9:0] dicad1_ns, dicad1; `else - logic [1:0] dicad1_ns, dicad1; + logic [1:0] dicad1_ns, dicad1; `endif logic ebreak_e4, ebreak_to_debug_mode_e4, ecall_e4, illegal_e4, illegal_e4_qual, mret_e4, inst_acc_e4, fence_i_e4, ic_perr_e4, iccm_sbecc_e4, ebreak_to_debug_mode_wb, kill_ebreak_count_wb, inst_acc_second_e4; logic ebreak_wb, ecall_wb, illegal_wb, illegal_raw_wb, inst_acc_wb, inst_acc_second_wb, fence_i_wb, ic_perr_wb, iccm_sbecc_wb; - logic ce_int_ready, ext_int_ready, timer_int_ready, mhwakeup_ready, + logic ce_int_ready, ext_int_ready, timer_int_ready, mhwakeup_ready, take_ext_int, take_ce_int, take_timer_int, take_nmi, take_nmi_wb; logic i0_exception_valid_e4, interrupt_valid, i0_exception_valid_wb, interrupt_valid_wb, exc_or_int_valid, exc_or_int_valid_wb, mdccme_ce_req, miccme_ce_req, mice_ce_req; logic synchronous_flush_e4; @@ -336,11 +339,12 @@ module dec_tlu_ctl logic [1:0] dec_tlu_br0_bank_e4, dec_tlu_br1_bank_e4; logic rfpc_i0_e4, rfpc_i1_e4; logic lsu_i0_rfnpc_dc4, lsu_i1_rfnpc_dc4; + logic lsu_i0_rfpc_dc4, lsu_i1_rfpc_dc4; logic dec_tlu_br0_error_e4, dec_tlu_br0_start_error_e4, dec_tlu_br0_v_e4; logic dec_tlu_br1_error_e4, dec_tlu_br1_start_error_e4, dec_tlu_br1_v_e4; - logic lsu_i0_exc_dc4, lsu_i1_exc_dc4, lsu_i0_exc_dc4_raw, lsu_i1_exc_dc4_raw, lsu_exc_ma_dc4, lsu_exc_acc_dc4, lsu_exc_st_dc4, - lsu_exc_valid_e4, lsu_exc_valid_e4_raw, lsu_exc_valid_wb, lsu_i0_exc_wb, - block_interrupts, lsu_block_interrupts_dc3, lsu_block_interrupts_e4; + logic lsu_i0_exc_dc4, lsu_i1_exc_dc4, lsu_i0_exc_dc4_raw, lsu_i1_exc_dc4_raw, lsu_exc_ma_dc4, lsu_exc_acc_dc4, lsu_exc_st_dc4, + lsu_exc_valid_e4, lsu_exc_valid_e4_raw, lsu_exc_valid_wb, lsu_i0_exc_wb, + block_interrupts, lsu_block_interrupts_dc3, lsu_block_interrupts_e4, lsu_load_ecc_stbuf_full_dc4; logic tlu_i0_commit_cmt, tlu_i1_commit_cmt; logic i0_trigger_eval_e4, i1_trigger_eval_e4, lsu_freeze_e4, lsu_freeze_pulse_e3, lsu_freeze_pulse_e4; @@ -349,8 +353,8 @@ module dec_tlu_ctl dbg_tlu_halted, core_empty, lsu_halt_idle_any_f, ifu_miss_state_idle_f, resume_ack_ns, debug_halt_req_f, 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_e4, i1_trigger_e4, trigger_action, trigger_enabled, + + logic [3:0] i0_trigger_e4, i1_trigger_e4, trigger_action, trigger_enabled, i0_trigger_chain_masked_e4, i1_trigger_chain_masked_e4; logic [2:0] trigger_chain; logic i0_trigger_hit_e4, i0_trigger_hit_raw_e4, i0_trigger_action_e4, @@ -358,34 +362,34 @@ module dec_tlu_ctl mepc_trigger_hit_sel_pc_e4, mepc_trigger_hit_sel_pc_wb; logic i1_trigger_hit_e4, i1_trigger_hit_raw_e4, i1_trigger_action_e4; - logic [3:0] update_hit_bit_e4, update_hit_bit_wb, i0_iside_trigger_has_pri_e4, i1_iside_trigger_has_pri_e4, + logic [3:0] update_hit_bit_e4, update_hit_bit_wb, i0_iside_trigger_has_pri_e4, i1_iside_trigger_has_pri_e4, i0_lsu_trigger_has_pri_e4, i1_lsu_trigger_has_pri_e4; 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_e4_raw, trigger_hit_dmode_e4, trigger_hit_dmode_wb, trigger_hit_for_dscr_cause_wb; logic wr_mcgc_wb, wr_mfdc_wb; logic [8:0] mcgc; - logic [18:0] mfdc; + logic [18:0] mfdc; logic [13:0] mfdc_int, mfdc_ns; logic i_cpu_halt_req_sync_qual, i_cpu_run_req_sync_qual, pmu_fw_halt_req_ns, pmu_fw_halt_req_f, - fw_halt_req, enter_pmu_fw_halt_req, pmu_fw_tlu_halted, pmu_fw_tlu_halted_f, internal_pmu_fw_halt_mode, + 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; logic dcsr_single_step_running_ff; logic nmi_int_delayed, nmi_int_detected; logic [3:0] trigger_execute, trigger_data, trigger_store; - 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, dbg_halt_state_ff, mpc_debug_halt_req_sync_pulse, + 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, dbg_halt_state_ff, 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; - + assign clk_override = dec_tlu_dec_clk_override; - + // Async inputs to the core have to be sync'd to the core clock. logic nmi_int_sync, timer_int_sync, i_cpu_halt_req_sync, i_cpu_run_req_sync, mpc_debug_halt_req_sync, mpc_debug_run_req_sync; - rvsyncss #(6) syncro_ff(.*, - .clk(free_clk), - .din ({nmi_int, timer_int, i_cpu_halt_req, i_cpu_run_req, mpc_debug_halt_req, mpc_debug_run_req}), + rvsyncss #(6) syncro_ff(.*, + .clk(free_clk), + .din ({nmi_int, timer_int, i_cpu_halt_req, i_cpu_run_req, mpc_debug_halt_req, mpc_debug_run_req}), .dout({nmi_int_sync, timer_int_sync, i_cpu_halt_req_sync, i_cpu_run_req_sync, mpc_debug_halt_req_sync, mpc_debug_run_req_sync})); // for CSRs that have inpipe writes only @@ -404,7 +408,7 @@ module dec_tlu_ctl assign lsu_freeze_pulse_e3 = lsu_freeze_dc3 & ~lsu_freeze_e4; - rvdff #(8) freeff (.*, .clk(free_clk), .din({lsu_freeze_dc3, lsu_freeze_pulse_e3, e4_valid, lsu_block_interrupts_dc3, internal_dbg_halt_mode, tlu_flush_lower_e4, tlu_i0_kill_writeb_e4, tlu_i1_kill_writeb_e4 }), + rvdff #(8) freeff (.*, .clk(free_clk), .din({lsu_freeze_dc3, lsu_freeze_pulse_e3, e4_valid, lsu_block_interrupts_dc3, internal_dbg_halt_mode, tlu_flush_lower_e4, tlu_i0_kill_writeb_e4, tlu_i1_kill_writeb_e4 }), .dout({lsu_freeze_e4, lsu_freeze_pulse_e4, e5_valid, lsu_block_interrupts_e4, internal_dbg_halt_mode_f, tlu_flush_lower_wb, dec_tlu_i0_kill_writeb_wb, dec_tlu_i1_kill_writeb_wb})); @@ -415,7 +419,7 @@ module dec_tlu_ctl // 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); - + assign nmi_int_detected = (nmi_int_sync & ~nmi_int_delayed) | nmi_lsu_detected | (nmi_int_detected_f & ~take_nmi_wb); // if the first nmi is a lsu type, note it. If there's already an nmi pending, ignore assign nmi_lsu_load_type = (nmi_lsu_detected & lsu_imprecise_error_load_any & ~(nmi_int_detected_f & ~take_nmi_wb)) | (nmi_lsu_load_type_f & ~take_nmi_wb); @@ -432,24 +436,24 @@ module dec_tlu_ctl `define MIE_MTIE 1 `define MIE_MSIE 0 -`define DCSR_EBREAKM 15 -`define DCSR_STEPIE 11 -`define DCSR_STOPC 10 -//`define DCSR_STOPT 9 -`define DCSR_STEP 2 +`define DCSR_EBREAKM 15 +`define DCSR_STEPIE 11 +`define DCSR_STOPC 10 +//`define DCSR_STOPT 9 +`define DCSR_STEP 2 // ---------------------------------------------------------------------- // MPC halt // - can interact with debugger halt and v-v - rvdff #(11) mpvhalt_ff (.*, .clk(free_clk), + rvdff #(11) mpvhalt_ff (.*, .clk(free_clk), .din({mpc_debug_halt_req_sync, mpc_debug_run_req_sync, - mpc_halt_state_ns, mpc_run_state_ns, debug_brkpt_status_ns, + 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, dbg_halt_state_f, - dec_tlu_mpc_halted_only_ns}), + dec_tlu_mpc_halted_only_ns}), .dout({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_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, dbg_halt_state_ff, dec_tlu_mpc_halted_only})); @@ -459,7 +463,7 @@ module dec_tlu_ctl 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) & ~mpc_debug_run_req_sync; + 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 @@ -467,9 +471,9 @@ module dec_tlu_ctl assign dbg_halt_state_ns = (dbg_halt_state_f | (dbg_halt_req | dcsr_single_step_done_f | trigger_hit_dmode_wb | ebreak_to_debug_mode_wb)) & ~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 + // 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_wb | trigger_hit_dmode_wb; assign debug_brkpt_status_ns = (debug_brkpt_valid | debug_brkpt_status_f) & (internal_dbg_halt_mode & ~dcsr_single_step_running_f); @@ -484,18 +488,18 @@ module dec_tlu_ctl assign debug_brkpt_status = debug_brkpt_status_f; - // combine MPC and DBG halt requests + // combine MPC and DBG halt requests assign debug_halt_req = (dbg_halt_req | mpc_debug_halt_req_sync | (reset_delayed & ~mpc_reset_run_req)) & ~internal_dbg_halt_mode_f; - + 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 - + + // 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) & ~lsu_block_interrupts_e4 & ~synchronous_flush_e4 & ~mret_e4 & ~halt_taken_f & ~dec_tlu_flush_noredir_wb & ~take_reset; - + // hold after we take a halt, so we don't keep taking halts assign halt_taken = (dec_tlu_flush_noredir_wb & ~dec_tlu_flush_pause_wb) | (halt_taken_f & ~dbg_tlu_halted_f & ~pmu_fw_tlu_halted_f & ~interrupt_valid_wb); @@ -508,16 +512,16 @@ module dec_tlu_ctl // assign enter_debug_halt_req = (~internal_dbg_halt_mode_f & debug_halt_req) | dcsr_single_step_done_f | trigger_hit_dmode_wb | ebreak_to_debug_mode_wb; - + // 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); @@ -527,17 +531,17 @@ module dec_tlu_ctl 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_e4 & dec_tlu_dbg_halted; - + // used to hold off commits after an in-pipe debug mode request (triggers, DCSR) assign request_debug_mode_e4 = (trigger_hit_dmode_e4 | ebreak_to_debug_mode_e4) | (request_debug_mode_wb & ~dec_tlu_flush_lower_wb); assign request_debug_mode_done = (request_debug_mode_wb | request_debug_mode_done_f) & ~dbg_tlu_halted_f; - rvdff #(22) halt_ff (.*, .clk(free_clk), .din({halt_taken, take_halt, lsu_halt_idle_any, ifu_miss_state_idle, dbg_tlu_halted, - resume_ack_ns, dbg_cmd_done_ns, debug_halt_req_ns, debug_resume_req, trigger_hit_dmode_e4, + rvdff #(22) halt_ff (.*, .clk(free_clk), .din({halt_taken, take_halt, lsu_halt_idle_any, ifu_miss_state_idle, dbg_tlu_halted, + resume_ack_ns, dbg_cmd_done_ns, debug_halt_req_ns, debug_resume_req, trigger_hit_dmode_e4, dcsr_single_step_done, debug_halt_req, update_hit_bit_e4[3:0], dec_tlu_wr_pause_wb, dec_pause_state, - request_debug_mode_e4, request_debug_mode_done, dcsr_single_step_running, dcsr_single_step_running_f}), - .dout({halt_taken_f, take_halt_f, lsu_halt_idle_any_f, ifu_miss_state_idle_f, dbg_tlu_halted_f, + request_debug_mode_e4, request_debug_mode_done, dcsr_single_step_running, dcsr_single_step_running_f}), + .dout({halt_taken_f, take_halt_f, lsu_halt_idle_any_f, ifu_miss_state_idle_f, dbg_tlu_halted_f, dec_tlu_resume_ack, dec_dbg_cmd_done, debug_halt_req_f, debug_resume_req_f, trigger_hit_dmode_wb, dcsr_single_step_done_f, debug_halt_req_d1, update_hit_bit_wb[3:0], dec_tlu_wr_pause_wb_f, dec_pause_state_f, request_debug_mode_wb, request_debug_mode_done_f, dcsr_single_step_running_f, dcsr_single_step_running_ff})); @@ -555,7 +559,7 @@ module dec_tlu_ctl // detect end of pause counter and rfpc assign pause_expired_e4 = ~dec_pause_state & dec_pause_state_f & ~(ext_int_ready | ce_int_ready | timer_int_ready | nmi_int_detected) & ~interrupt_valid_wb & ~debug_halt_req_f & ~pmu_fw_halt_req_f & ~halt_taken_f; - + // stall dma fifo if a fence is pending, decode is waiting for lsu to idle before decoding the fence inst. assign dec_tlu_stall_dma = dec_fence_pending; assign dec_tlu_flush_leak_one_wb = dec_tlu_flush_lower_wb & dcsr[`DCSR_STEP] & (dec_tlu_resume_ack | dcsr_single_step_running); @@ -564,7 +568,7 @@ module dec_tlu_ctl // If DM attempts to access an illegal CSR, send cmd_fail back assign dec_dbg_cmd_fail = illegal_raw_wb & dec_dbg_cmd_done; - + //-------------------------------------------------------------------------------- //-------------------------------------------------------------------------------- // Triggers @@ -590,9 +594,9 @@ module dec_tlu_ctl // 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], + 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 @@ -618,12 +622,12 @@ module dec_tlu_ctl assign i0_trigger_chain_masked_e4[3:0] = {i0_trigger_e4[3] & (~trigger_chain[2] | i0_trigger_e4[2]), i0_trigger_e4[2] & (~trigger_chain[2] | i0_trigger_e4[3]), i0_trigger_e4[1] & (~trigger_chain[0] | i0_trigger_e4[0]), - i0_trigger_e4[0] & (~trigger_chain[0] | i0_trigger_e4[1])}; + i0_trigger_e4[0] & (~trigger_chain[0] | i0_trigger_e4[1])}; assign i1_trigger_chain_masked_e4[3:0] = {i1_trigger_e4[3] & (~trigger_chain[2] | i1_trigger_e4[2]), i1_trigger_e4[2] & (~trigger_chain[2] | i1_trigger_e4[3]), i1_trigger_e4[1] & (~trigger_chain[0] | i1_trigger_e4[0]), - i1_trigger_e4[0] & (~trigger_chain[0] | i1_trigger_e4[1])}; + i1_trigger_e4[0] & (~trigger_chain[0] | i1_trigger_e4[1])}; // This is the highest priority by this point. assign i0_trigger_hit_raw_e4 = |i0_trigger_chain_masked_e4[3:0]; @@ -634,16 +638,16 @@ module dec_tlu_ctl assign i1_trigger_hit_e4 = ~(dec_tlu_flush_lower_wb | ~tlu_i0_commit_cmt | exu_i0_br_mp_e4 | dec_tlu_dbg_halted | lsu_freeze_pulse_e4 | lsu_i0_rfnpc_dc4) & i1_trigger_hit_raw_e4; assign dec_tlu_cancel_e4 = (i0_trigger_hit_raw_e4 | i1_trigger_hit_raw_e4) & lsu_freeze_pulse_e4; - + // 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_t1[`MTDATA1_ACTION] & mtdata1_t1[`MTDATA1_DMODE], + assign trigger_action[3:0] = {mtdata1_t3[`MTDATA1_ACTION] & mtdata1_t3[`MTDATA1_DMODE], + mtdata1_t2[`MTDATA1_ACTION] & mtdata1_t2[`MTDATA1_DMODE], + mtdata1_t1[`MTDATA1_ACTION] & mtdata1_t1[`MTDATA1_DMODE], mtdata1_t0[`MTDATA1_ACTION] & mtdata1_t0[`MTDATA1_DMODE]}; // this is needed to set the HIT bit in the triggers - assign update_hit_bit_e4[3:0] = ({4{i0_trigger_hit_e4 }} & i0_trigger_chain_masked_e4[3:0]) | + assign update_hit_bit_e4[3:0] = ({4{i0_trigger_hit_e4 }} & i0_trigger_chain_masked_e4[3:0]) | ({4{i1_trigger_hit_e4 & ~i0_trigger_hit_e4}} & i1_trigger_chain_masked_e4[3:0]); // action, 1 means dmode. Simultaneous triggers with at least 1 set for dmode force entire action to dmode. @@ -652,14 +656,14 @@ module dec_tlu_ctl assign trigger_hit_e4 = i0_trigger_hit_e4 | i1_trigger_hit_e4; assign trigger_hit_dmode_e4 = (i0_trigger_hit_e4 & i0_trigger_action_e4) | (i1_trigger_hit_e4 & ~i0_trigger_hit_e4 & i1_trigger_action_e4); - + assign mepc_trigger_hit_sel_pc_e4 = trigger_hit_e4 & ~trigger_hit_dmode_e4; - - -// + + +// // Debug end //-------------------------------------------------------------------------------- - + //---------------------------------------------------------------------- // // Commit @@ -669,7 +673,7 @@ module dec_tlu_ctl //-------------------------------------------------------------------------------- - // External halt (not debug halt) + // External halt (not debug halt) // - Fully interlocked handshake // i_cpu_halt_req ____|--------------|_______________ // core_empty ---------------|___________ @@ -683,17 +687,17 @@ module dec_tlu_ctl // 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; assign i_cpu_run_req_sync_qual = i_cpu_run_req_sync & ~dec_tlu_debug_mode & pmu_fw_tlu_halted_f; - - rvdff #(8) exthaltff (.*, .clk(free_clk), .din({i_cpu_halt_req_sync_qual, i_cpu_run_req_sync_qual, cpu_halt_status, + + rvdff #(8) exthaltff (.*, .clk(free_clk), .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}), - .dout({i_cpu_halt_req_d1, i_cpu_run_req_d1_raw, o_cpu_halt_status, + pmu_fw_halt_req_ns, pmu_fw_tlu_halted}), + .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})); // 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; @@ -709,25 +713,25 @@ module dec_tlu_ctl assign debug_mode_status = internal_dbg_halt_mode_f; assign o_debug_mode_status = debug_mode_status;// & ~mpc_debug_run_ack_f; -`ifdef ASSERT_ON +`ifdef ASSERT_ON assert_commit_while_halted: assert #0 (~((tlu_i0_commit_cmt | tlu_i1_commit_cmt) & o_cpu_halt_status)) else $display("ERROR: Commiting while cpu_halt_status asserted!"); `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 | (mhwakeup & mhwakeup_ready)) & o_cpu_halt_status); //-------------------------------------------------------------------------------- //-------------------------------------------------------------------------------- - + // LSU exceptions (LSU responsible for prioritizing simultaneous cases) lsu_error_pkt_t lsu_error_pkt_dc4; - rvdff #( $bits(lsu_error_pkt_t) ) lsu_error_dc4ff (.*, .clk(lsu_e3_e4_clk), .din(lsu_error_pkt_dc3), .dout(lsu_error_pkt_dc4)); + rvdff #( $bits(lsu_error_pkt_t)+1 ) lsu_error_dc4ff (.*, .clk(lsu_e3_e4_clk), .din({lsu_error_pkt_dc3, lsu_load_ecc_stbuf_full_dc3}), .dout({lsu_error_pkt_dc4, lsu_load_ecc_stbuf_full_dc4})); logic lsu_single_ecc_error_wb_ns; - assign lsu_single_ecc_error_wb_ns = lsu_error_pkt_dc4.single_ecc_error;// & ((~lsu_error_pkt_dc4.inst_pipe & tlu_i0_commit_cmt) | (lsu_error_pkt_dc4.inst_pipe & tlu_i1_commit_cmt)); + assign lsu_single_ecc_error_wb_ns = lsu_single_ecc_error_incr; rvdff #(2) lsu_dccm_errorff (.*, .clk(free_clk), .din({mdseac_locked_ns, lsu_single_ecc_error_wb_ns}), .dout({mdseac_locked_f, lsu_single_ecc_error_wb})); - + logic [31:0] lsu_error_pkt_addr_dc4, lsu_error_pkt_addr_wb; assign lsu_error_pkt_addr_dc4[31:0] = lsu_error_pkt_dc4.addr[31:0]; rvdff #(34) lsu_error_wbff (.*, .clk(lsu_e4_e5_clk), .din({lsu_error_pkt_addr_dc4[31:0], lsu_exc_valid_e4, lsu_i0_exc_dc4}), .dout({lsu_error_pkt_addr_wb[31:0], lsu_exc_valid_wb, lsu_i0_exc_wb})); @@ -735,23 +739,29 @@ module dec_tlu_ctl // lsu exception is valid unless it's in pipe1 and there was a rfpc_i0_e4, brmp, or an iside exception in pipe0. assign lsu_exc_valid_e4_raw = lsu_error_pkt_dc4.exc_valid & ~(lsu_error_pkt_dc4.inst_pipe & (rfpc_i0_e4 | i0_exception_valid_e4 | exu_i0_br_mp_e4)) & ~dec_tlu_flush_lower_wb; - + assign lsu_i0_exc_dc4_raw = lsu_error_pkt_dc4.exc_valid & ~lsu_error_pkt_dc4.inst_pipe; assign lsu_i1_exc_dc4_raw = lsu_error_pkt_dc4.exc_valid & lsu_error_pkt_dc4.inst_pipe; assign lsu_i0_exc_dc4 = lsu_i0_exc_dc4_raw & lsu_exc_valid_e4_raw & ~i0_trigger_hit_e4; assign lsu_i1_exc_dc4 = lsu_i1_exc_dc4_raw & lsu_exc_valid_e4_raw & ~trigger_hit_e4; assign lsu_exc_valid_e4 = lsu_i0_exc_dc4 | lsu_i1_exc_dc4; - + assign lsu_exc_ma_dc4 = (lsu_i0_exc_dc4 | lsu_i1_exc_dc4) & ~lsu_error_pkt_dc4.exc_type; assign lsu_exc_acc_dc4 = (lsu_i0_exc_dc4 | lsu_i1_exc_dc4) & lsu_error_pkt_dc4.exc_type; assign lsu_exc_st_dc4 = (lsu_i0_exc_dc4 | lsu_i1_exc_dc4) & lsu_error_pkt_dc4.inst_type; - // Single bit ECC errors on loads are RFNPC corrected, with the corrected data written to the GPR. + // If the stbuf is not full, then + // 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_dc4 = dec_tlu_i0_valid_e4 & ~lsu_error_pkt_dc4.inst_pipe & ~lsu_error_pkt_dc4.inst_type & - lsu_error_pkt_dc4.single_ecc_error & ~lsu_error_pkt_dc4.dma_valid & ~i0_trigger_hit_e4; - assign lsu_i1_rfnpc_dc4 = dec_tlu_i1_valid_e4 & lsu_error_pkt_dc4.inst_pipe & ~lsu_error_pkt_dc4.inst_type & - lsu_error_pkt_dc4.single_ecc_error & ~lsu_error_pkt_dc4.dma_valid & ~i0_trigger_hit_e4 & ~i1_trigger_hit_e4; + assign lsu_i0_rfnpc_dc4 = dec_tlu_i0_valid_e4 & ~lsu_error_pkt_dc4.inst_pipe & ~lsu_error_pkt_dc4.inst_type & + lsu_error_pkt_dc4.single_ecc_error & ~lsu_error_pkt_dc4.dma_valid & ~i0_trigger_hit_e4 & ~lsu_load_ecc_stbuf_full_dc4; + assign lsu_i1_rfnpc_dc4 = dec_tlu_i1_valid_e4 & lsu_error_pkt_dc4.inst_pipe & ~lsu_error_pkt_dc4.inst_type & + lsu_error_pkt_dc4.single_ecc_error & ~lsu_error_pkt_dc4.dma_valid & ~i0_trigger_hit_e4 & ~i1_trigger_hit_e4 & ~lsu_load_ecc_stbuf_full_dc4; + // otherwise, they are rfpcs + assign lsu_i0_rfpc_dc4 = dec_tlu_i0_valid_e4 & ~lsu_error_pkt_dc4.inst_pipe & ~lsu_error_pkt_dc4.inst_type & + lsu_error_pkt_dc4.single_ecc_error & ~lsu_error_pkt_dc4.dma_valid & lsu_load_ecc_stbuf_full_dc4; + assign lsu_i1_rfpc_dc4 = dec_tlu_i1_valid_e4 & lsu_error_pkt_dc4.inst_pipe & ~lsu_error_pkt_dc4.inst_type & + lsu_error_pkt_dc4.single_ecc_error & ~lsu_error_pkt_dc4.dma_valid & lsu_load_ecc_stbuf_full_dc4; // Branch prediction updating assign dec_tlu_br0_addr_e4[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO] = exu_i0_br_index_e4[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO]; @@ -762,32 +772,32 @@ module dec_tlu_ctl // Final commit valids assign tlu_i0_commit_cmt = dec_tlu_i0_valid_e4 & - ~rfpc_i0_e4 & - ~lsu_i0_exc_dc4 & - ~inst_acc_e4 & - ~dec_tlu_dbg_halted & + ~rfpc_i0_e4 & + ~lsu_i0_exc_dc4 & + ~inst_acc_e4 & + ~dec_tlu_dbg_halted & ~request_debug_mode_wb & ~i0_trigger_hit_e4; - - assign tlu_i1_commit_cmt = dec_tlu_i1_valid_e4 & - ~rfpc_i0_e4 & ~rfpc_i1_e4 & - ~exu_i0_br_mp_e4 & + + assign tlu_i1_commit_cmt = dec_tlu_i1_valid_e4 & + ~rfpc_i0_e4 & ~rfpc_i1_e4 & + ~exu_i0_br_mp_e4 & ~lsu_i0_exc_dc4 & ~lsu_i1_exc_dc4 & - ~lsu_i0_rfnpc_dc4 & + ~lsu_i0_rfnpc_dc4 & ~inst_acc_e4 & ~request_debug_mode_wb & ~trigger_hit_e4; - + // unified place to manage the killing of arch state writebacks assign tlu_i0_kill_writeb_e4 = rfpc_i0_e4 | lsu_i0_exc_dc4 | inst_acc_e4 | (illegal_e4 & dec_tlu_dbg_halted) | i0_trigger_hit_e4 ; assign tlu_i1_kill_writeb_e4 = rfpc_i0_e4 | rfpc_i1_e4 | lsu_exc_valid_e4 | exu_i0_br_mp_e4 | inst_acc_e4 | (illegal_e4 & dec_tlu_dbg_halted) | trigger_hit_e4 | lsu_i0_rfnpc_dc4; // refetch PC, microarch flush // ic errors only in pipe0 - assign rfpc_i0_e4 = dec_tlu_i0_valid_e4 & ~tlu_flush_lower_wb & (exu_i0_br_error_e4 | exu_i0_br_start_error_e4 | ic_perr_e4 | iccm_sbecc_e4) & ~i0_trigger_hit_e4; - assign rfpc_i1_e4 = dec_tlu_i1_valid_e4 & ~tlu_flush_lower_wb & ~i0_exception_valid_e4 & ~exu_i0_br_mp_e4 & ~lsu_i0_exc_dc4 & ~lsu_i0_rfnpc_dc4 & - ~(exu_i0_br_error_e4 | exu_i0_br_start_error_e4 | ic_perr_e4 | iccm_sbecc_e4) & - (exu_i1_br_error_e4 | exu_i1_br_start_error_e4) & + assign rfpc_i0_e4 = dec_tlu_i0_valid_e4 & ~tlu_flush_lower_wb & (exu_i0_br_error_e4 | exu_i0_br_start_error_e4 | ic_perr_e4 | iccm_sbecc_e4 | lsu_i0_rfpc_dc4) & ~i0_trigger_hit_e4; + assign rfpc_i1_e4 = dec_tlu_i1_valid_e4 & ~tlu_flush_lower_wb & ~i0_exception_valid_e4 & ~exu_i0_br_mp_e4 & ~lsu_i0_exc_dc4 & ~lsu_i0_rfnpc_dc4 & + ~(exu_i0_br_error_e4 | exu_i0_br_start_error_e4 | ic_perr_e4 | iccm_sbecc_e4 | lsu_i0_rfpc_dc4) & + (exu_i1_br_error_e4 | exu_i1_br_start_error_e4 | lsu_i1_rfpc_dc4) & ~trigger_hit_e4; // go ahead and repair the branch error on other flushes, doesn't have to be the rfpc flush @@ -798,18 +808,18 @@ module dec_tlu_ctl assign dec_tlu_br1_error_e4 = exu_i1_br_error_e4 & dec_tlu_i1_valid_e4 & ~tlu_flush_lower_wb & ~exu_i0_br_mp_e4; assign dec_tlu_br1_start_error_e4 = exu_i1_br_start_error_e4 & dec_tlu_i1_valid_e4 & ~tlu_flush_lower_wb & ~exu_i0_br_mp_e4; assign dec_tlu_br1_v_e4 = exu_i1_br_valid_e4 & ~tlu_flush_lower_wb & dec_tlu_i1_valid_e4 & ~exu_i0_br_mp_e4 & ~exu_i1_br_mp_e4; - + `ifdef RV_BTB_48 - rvdff #(20) + rvdff #(20) `else - rvdff #(18) + rvdff #(18) `endif bp_wb_ff (.*, .clk(e4e5_clk), - .din({exu_i0_br_hist_e4[1:0], + .din({exu_i0_br_hist_e4[1:0], dec_tlu_br0_error_e4, dec_tlu_br0_start_error_e4, dec_tlu_br0_v_e4, - exu_i1_br_hist_e4[1:0], + exu_i1_br_hist_e4[1:0], dec_tlu_br1_error_e4, dec_tlu_br1_start_error_e4, dec_tlu_br1_v_e4, @@ -819,14 +829,14 @@ module dec_tlu_ctl exu_i1_br_way_e4, exu_i0_br_middle_e4, exu_i1_br_middle_e4 - }), - .dout({dec_tlu_br0_wb_pkt.hist[1:0], - dec_tlu_br0_wb_pkt.br_error, - dec_tlu_br0_wb_pkt.br_start_error, + }), + .dout({dec_tlu_br0_wb_pkt.hist[1:0], + dec_tlu_br0_wb_pkt.br_error, + dec_tlu_br0_wb_pkt.br_start_error, dec_tlu_br0_wb_pkt.valid, - dec_tlu_br1_wb_pkt.hist[1:0], - dec_tlu_br1_wb_pkt.br_error, - dec_tlu_br1_wb_pkt.br_start_error, + dec_tlu_br1_wb_pkt.hist[1:0], + dec_tlu_br1_wb_pkt.br_error, + dec_tlu_br1_wb_pkt.br_start_error, dec_tlu_br1_wb_pkt.valid, dec_tlu_br0_wb_pkt.bank[1:0], dec_tlu_br1_wb_pkt.bank[1:0], @@ -836,18 +846,18 @@ module dec_tlu_ctl dec_tlu_br1_wb_pkt.middle })); - rvdff #(`RV_BHT_GHR_SIZE*2) bp_wb_ghrff (.*, .clk(e4e5_clk), + rvdff #(`RV_BHT_GHR_SIZE*2) bp_wb_ghrff (.*, .clk(e4e5_clk), .din({exu_i0_br_fghr_e4[`RV_BHT_GHR_RANGE], exu_i1_br_fghr_e4[`RV_BHT_GHR_RANGE] - }), + }), .dout({dec_tlu_br0_wb_pkt.fghr[`RV_BHT_GHR_RANGE], dec_tlu_br1_wb_pkt.fghr[`RV_BHT_GHR_RANGE] })); - rvdff #(2*$bits(dec_tlu_br0_addr_e4[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO])) + rvdff #(2*$bits(dec_tlu_br0_addr_e4[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO])) bp_wb_index_ff (.*, .clk(e4e5_clk), .din({dec_tlu_br0_addr_e4[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO], - dec_tlu_br1_addr_e4[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO]}), + dec_tlu_br1_addr_e4[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO]}), .dout({dec_tlu_br0_wb_pkt.index[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO], dec_tlu_br1_wb_pkt.index[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO]})); @@ -863,15 +873,15 @@ module dec_tlu_ctl assign inst_acc_e4_raw = dec_tlu_packet_e4.icaf & dec_tlu_i0_valid_e4; assign inst_acc_e4 = inst_acc_e4_raw & ~rfpc_i0_e4 & ~i0_trigger_hit_e4; assign inst_acc_second_e4 = dec_tlu_packet_e4.icaf_f1; - + assign ebreak_to_debug_mode_e4 = (dec_tlu_packet_e4.pmu_i0_itype == EBREAK) & dec_tlu_i0_valid_e4 & ~i0_trigger_hit_e4 & dcsr[`DCSR_EBREAKM]; assign illegal_e4_qual = illegal_e4 & ~dec_tlu_dbg_halted; - rvdff #(11) exctype_wb_ff (.*, .clk(e4e5_clk), - .din({ic_perr_e4, iccm_sbecc_e4, ebreak_e4, ebreak_to_debug_mode_e4, ecall_e4, illegal_e4, - illegal_e4_qual, inst_acc_e4, inst_acc_second_e4, fence_i_e4, mret_e4}), - .dout({ic_perr_wb, iccm_sbecc_wb, ebreak_wb, ebreak_to_debug_mode_wb, ecall_wb, illegal_raw_wb, + rvdff #(11) exctype_wb_ff (.*, .clk(e4e5_clk), + .din({ic_perr_e4, iccm_sbecc_e4, ebreak_e4, ebreak_to_debug_mode_e4, ecall_e4, illegal_e4, + illegal_e4_qual, inst_acc_e4, inst_acc_second_e4, fence_i_e4, mret_e4}), + .dout({ic_perr_wb, iccm_sbecc_wb, ebreak_wb, ebreak_to_debug_mode_wb, ecall_wb, illegal_raw_wb, illegal_wb, inst_acc_wb, inst_acc_second_wb, fence_i_wb, mret_wb})); assign dec_tlu_fence_i_wb = fence_i_wb; @@ -888,12 +898,12 @@ module dec_tlu_ctl assign i0_exception_valid_e4 = (ebreak_e4 | ecall_e4 | illegal_e4 | inst_acc_e4) & ~rfpc_i0_e4 & ~dec_tlu_dbg_halted; // Cause: - // + // // 0x2 : illegal // 0x3 : breakpoint // 0xb : Environment call M-mode - + assign exc_cause_e4[4:0] = ( ({5{take_ext_int}} & 5'h0b) | ({5{take_timer_int}} & 5'h07) | ({5{take_ce_int}} & 5'h1e) | @@ -910,14 +920,14 @@ module dec_tlu_ctl // // Interrupts // - // Priv spec 1.10, 3.1.14 + // Priv spec 1.10, 3.1.14 // "Multiple simultaneous interrupts and traps at the same privilege level are handled in the following // decreasing priority order: external interrupts, software interrupts, timer interrupts, then finally any // synchronous traps." // - // For above purposes, exceptions that are committed have already happened and will cause an int at E4 to wait a cycle + // For above purposes, 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 @@ -929,7 +939,7 @@ module dec_tlu_ctl // mispredicts assign i0_mp_e4 = exu_i0_flush_lower_e4 & ~i0_trigger_hit_e4; assign i1_mp_e4 = exu_i1_flush_lower_e4 & ~trigger_hit_e4 & ~lsu_i0_rfnpc_dc4; - + assign internal_dbg_halt_timers = internal_dbg_halt_mode_f & ~dcsr_single_step_running; // Prioritize externals @@ -943,16 +953,16 @@ module dec_tlu_ctl mret_wb | // mret (need time for MIE to update) mret_e4 // mret in progress, for cases were ISR enables ints before mret ); - + assign take_ext_int = ext_int_ready & ~block_interrupts; assign take_ce_int = ce_int_ready & ~ext_int_ready & ~block_interrupts; assign take_timer_int = timer_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_e4 & ~dcsr_single_step_done_f)) & ~synchronous_flush_e4 & ~mret_e4 & ~take_reset & ~ebreak_to_debug_mode_e4; assign interrupt_valid = take_ext_int | take_timer_int | take_nmi | take_ce_int; - + // Compute interrupt path: // If vectored async is set in mtvec, flush path for interrupts is MTVEC + (4 * CAUSE); @@ -963,7 +973,7 @@ module dec_tlu_ctl assign sel_npc_e4 = lsu_i0_rfnpc_dc4 | (lsu_i1_rfnpc_dc4 & tlu_i1_commit_cmt) | fence_i_e4 | (i_cpu_run_req_d1 & ~interrupt_valid); assign sel_npc_wb = (i_cpu_run_req_d1 & pmu_fw_tlu_halted_f) | pause_expired_e4; - + assign synchronous_flush_e4 = i0_exception_valid_e4 | // exception i0_mp_e4 | i1_mp_e4 | // mispredict rfpc_i0_e4 | rfpc_i1_e4 | // rfpc @@ -978,39 +988,39 @@ module dec_tlu_ctl assign tlu_flush_lower_e4 = interrupt_valid | mret_e4 | synchronous_flush_e4 | take_halt | take_reset; assign tlu_flush_path_e4[31:1] = take_reset ? rst_vec[31:1] : - - ( ({31{~take_nmi & i0_mp_e4}} & exu_i0_flush_path_e4[31:1]) | + + ( ({31{~take_nmi & i0_mp_e4}} & exu_i0_flush_path_e4[31:1]) | ({31{~take_nmi & ~i0_mp_e4 & i1_mp_e4 & ~rfpc_i0_e4 & ~lsu_i0_exc_dc4}} & exu_i1_flush_path_e4[31:1]) | - ({31{~take_nmi & sel_npc_e4}} & npc_e4[31:1]) | - ({31{~take_nmi & rfpc_i0_e4}} & dec_tlu_i0_pc_e4[31:1]) | - ({31{~take_nmi & rfpc_i1_e4}} & dec_tlu_i1_pc_e4[31:1]) | - ({31{interrupt_valid}} & interrupt_path[31:1]) | + ({31{~take_nmi & sel_npc_e4}} & npc_e4[31:1]) | + ({31{~take_nmi & rfpc_i0_e4}} & dec_tlu_i0_pc_e4[31:1]) | + ({31{~take_nmi & rfpc_i1_e4}} & dec_tlu_i1_pc_e4[31:1]) | + ({31{interrupt_valid}} & interrupt_path[31:1]) | ({31{(i0_exception_valid_e4 | lsu_exc_valid_e4 | (trigger_hit_e4 & ~trigger_hit_dmode_e4)) & ~interrupt_valid}} & {mtvec[30:1],1'b0}) | ({31{~take_nmi & mret_e4 & ~wr_mepc_wb}} & mepc[31:1]) | ({31{~take_nmi & debug_resume_req_f}} & dpc[31:1]) | ({31{~take_nmi & sel_npc_wb}} & npc_wb[31:1]) | ({31{~take_nmi & mret_e4 & wr_mepc_wb}} & dec_csr_wrdata_wb[31:1]) ); - rvdff #(31) flush_lower_ff (.*, .clk(e4e5_int_clk), - .din({tlu_flush_path_e4[31:1]}), + rvdff #(31) flush_lower_ff (.*, .clk(e4e5_int_clk), + .din({tlu_flush_path_e4[31:1]}), .dout({tlu_flush_path_wb[31:1]})); assign dec_tlu_flush_lower_wb = tlu_flush_lower_wb; assign dec_tlu_flush_path_wb[31:1] = tlu_flush_path_wb[31:1]; - + // this is used to capture mepc, etc. assign exc_or_int_valid = lsu_exc_valid_e4 | i0_exception_valid_e4 | interrupt_valid | (trigger_hit_e4 & ~trigger_hit_dmode_e4); assign lsu_block_interrupts_dc3 = lsu_freeze_external_ints_dc3 & ~dec_tlu_flush_lower_wb; - - rvdff #(15) excinfo_wb_ff (.*, .clk(e4e5_int_clk), - .din({interrupt_valid, i0_exception_valid_e4, exc_or_int_valid, - exc_cause_e4[4:0], tlu_i0_commit_cmt & ~illegal_e4, tlu_i1_commit_cmt, + + rvdff #(15) excinfo_wb_ff (.*, .clk(e4e5_int_clk), + .din({interrupt_valid, i0_exception_valid_e4, exc_or_int_valid, + exc_cause_e4[4:0], tlu_i0_commit_cmt & ~illegal_e4, tlu_i1_commit_cmt, mepc_trigger_hit_sel_pc_e4, trigger_hit_e4, i0_trigger_hit_e4, - take_nmi, pause_expired_e4 }), - .dout({interrupt_valid_wb, i0_exception_valid_wb, exc_or_int_valid_wb, - exc_cause_wb[4:0], i0_valid_wb, i1_valid_wb, + take_nmi, pause_expired_e4 }), + .dout({interrupt_valid_wb, i0_exception_valid_wb, exc_or_int_valid_wb, + exc_cause_wb[4:0], i0_valid_wb, i1_valid_wb, mepc_trigger_hit_sel_pc_wb, trigger_hit_wb, i0_trigger_hit_wb, take_nmi_wb, pause_expired_wb})); @@ -1035,7 +1045,7 @@ module dec_tlu_ctl `define MIMPID 12'hf13 `define MHARTID 12'hf14 - + // ---------------------------------------------------------------------- // MSTATUS (RW) // [12:11] MPP : Prior priv level, always 2'b11, not flopped @@ -1050,7 +1060,8 @@ module dec_tlu_ctl assign dec_csr_wen_wb_mod = dec_csr_wen_wb & ~trigger_hit_wb; assign wr_mstatus_wb = dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[11:0] == `MSTATUS); - assign mstatus_ns[1:0] = ( ({2{exc_or_int_valid_wb}} & {mstatus[`MSTATUS_MIE], 1'b0}) | + assign mstatus_ns[1:0] = ( ({2{~wr_mstatus_wb & exc_or_int_valid_wb}} & {mstatus[`MSTATUS_MIE], 1'b0}) | + ({2{ wr_mstatus_wb & exc_or_int_valid_wb}} & {dec_csr_wrdata_wb[3], 1'b0}) | ({2{mret_wb & ~exc_or_int_valid_wb}} & {1'b1, mstatus[1]}) | ({2{wr_mstatus_wb & ~exc_or_int_valid_wb}} & {dec_csr_wrdata_wb[7], dec_csr_wrdata_wb[3]}) | ({2{~wr_mstatus_wb & ~exc_or_int_valid_wb & ~mret_wb}} & mstatus[1:0]) ); @@ -1065,14 +1076,14 @@ module dec_tlu_ctl // [1] - Reserved, not implemented, reads zero // [0] MODE : 0 = Direct, 1 = Asyncs are vectored to BASE + (4 * CAUSE) `define MTVEC 12'h305 - + assign wr_mtvec_wb = dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[11:0] == `MTVEC); - assign mtvec_ns[30:0] = {dec_csr_wrdata_wb[31:2], dec_csr_wrdata_wb[0]} ; + assign mtvec_ns[30:0] = {dec_csr_wrdata_wb[31:2], dec_csr_wrdata_wb[0]} ; rvdffe #(31) mtvec_ff (.*, .en(wr_mtvec_wb), .din(mtvec_ns[30:0]), .dout(mtvec[30:0])); // ---------------------------------------------------------------------- // MIP (RW) - // + // // [30] MCEIP : (RO) M-Mode Correctable Error interrupt pending // [11] MEIP : (RO) M-Mode external interrupt pending // [7] MTIP : (RO) M-Mode timer interrupt pending @@ -1081,7 +1092,7 @@ module dec_tlu_ctl assign ce_int = (mdccme_ce_req | miccme_ce_req | mice_ce_req); - assign mip_ns[3:0] = {ce_int, mexintpend, timer_int_sync, mip[0]}; + assign mip_ns[3:0] = {ce_int, mexintpend, timer_int_sync, mip[0]}; rvdff #(4) mip_ff (.*, .clk(free_clk), .din(mip_ns[3:0]), .dout(mip[3:0])); // ---------------------------------------------------------------------- @@ -1091,16 +1102,16 @@ module dec_tlu_ctl // [7] MTIE : (RW) M-Mode timer interrupt enable // [3] MSIE : (RW) M-Mode software interrupt enable `define MIE 12'h304 - + assign wr_mie_wb = dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[11:0] == `MIE); - assign mie_ns[3:0] = wr_mie_wb ? {dec_csr_wrdata_wb[30], dec_csr_wrdata_wb[11], dec_csr_wrdata_wb[7], dec_csr_wrdata_wb[3]} : mie[3:0]; + assign mie_ns[3:0] = wr_mie_wb ? {dec_csr_wrdata_wb[30], dec_csr_wrdata_wb[11], dec_csr_wrdata_wb[7], dec_csr_wrdata_wb[3]} : mie[3:0]; rvdff #(4) mie_ff (.*, .clk(csr_wr_clk), .din(mie_ns[3:0]), .dout(mie[3:0])); // ---------------------------------------------------------------------- // MCYCLEL (RW) // [31:0] : Lower Cycle count - + `define MCYCLEL 12'hb00 @@ -1111,9 +1122,9 @@ module dec_tlu_ctl assign kill_ebreak_count_wb = ebreak_to_debug_mode_wb & dcsr[`DCSR_STOPC]; assign mcyclel_cout_in = ~(kill_ebreak_count_wb | (dec_tlu_dbg_halted & dcsr[`DCSR_STOPC]) | dec_tlu_pmu_fw_halted); - - assign {mcyclel_cout, mcyclel_inc[31:0]} = mcyclel[31:0] + {31'b0, mcyclel_cout_in}; - assign mcyclel_ns[31:0] = wr_mcyclel_wb ? dec_csr_wrdata_wb[31:0] : mcyclel_inc[31:0]; + + assign {mcyclel_cout, mcyclel_inc[31:0]} = mcyclel[31:0] + {31'b0, mcyclel_cout_in}; + assign mcyclel_ns[31:0] = wr_mcyclel_wb ? dec_csr_wrdata_wb[31:0] : mcyclel_inc[31:0]; rvdffe #(32) mcyclel_ff (.*, .en(wr_mcyclel_wb | mcyclel_cout_in), .din(mcyclel_ns[31:0]), .dout(mcyclel[31:0])); rvdff #(1) mcyclef_cout_ff (.*, .clk(free_clk), .din(mcyclel_cout & ~wr_mcycleh_wb), .dout(mcyclel_cout_f)); @@ -1123,14 +1134,14 @@ module dec_tlu_ctl // Chained with mcyclel. Note: mcyclel overflow due to a mcycleh write gets ignored. `define MCYCLEH 12'hb80 - + assign wr_mcycleh_wb = dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[11:0] == `MCYCLEH); - assign {mcycleh_cout_nc, mcycleh_inc[31:0]} = mcycleh[31:0] + {31'b0, mcyclel_cout_f}; - assign mcycleh_ns[31:0] = wr_mcycleh_wb ? dec_csr_wrdata_wb[31:0] : mcycleh_inc[31:0]; + assign {mcycleh_cout_nc, mcycleh_inc[31:0]} = mcycleh[31:0] + {31'b0, mcyclel_cout_f}; + assign mcycleh_ns[31:0] = wr_mcycleh_wb ? dec_csr_wrdata_wb[31:0] : mcycleh_inc[31:0]; rvdffe #(32) mcycleh_ff (.*, .en(wr_mcycleh_wb | mcyclel_cout_f), .din(mcycleh_ns[31:0]), .dout(mcycleh[31:0])); - + // ---------------------------------------------------------------------- // MINSTRETL (RW) // [31:0] : Lower Instruction retired count @@ -1146,12 +1157,12 @@ module dec_tlu_ctl assign wr_minstretl_wb = dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[11:0] == `MINSTRETL); - assign {minstretl_cout, minstretl_inc[31:0]} = minstretl[31:0] + {31'b0,i0_valid_no_ebreak_ecall_wb} + {31'b0,i1_valid_wb}; + assign {minstretl_cout, minstretl_inc[31:0]} = minstretl[31:0] + {31'b0,i0_valid_no_ebreak_ecall_wb} + {31'b0,i1_valid_wb}; - assign minstret_enable = i0_valid_no_ebreak_ecall_wb | i1_valid_wb | wr_minstretl_wb; - - assign minstretl_ns[31:0] = wr_minstretl_wb ? dec_csr_wrdata_wb[31:0] : minstretl_inc[31:0]; - rvdffe #(32) minstretl_ff (.*, .en(minstret_enable), .din(minstretl_ns[31:0]), .dout(minstretl[31:0])); + assign minstret_enable = i0_valid_no_ebreak_ecall_wb | i1_valid_wb; + + assign minstretl_ns[31:0] = wr_minstretl_wb ? dec_csr_wrdata_wb[31:0] : minstretl_inc[31:0]; + rvdffe #(32) minstretl_ff (.*, .en(minstret_enable | wr_minstretl_wb), .din(minstretl_ns[31:0]), .dout(minstretl[31:0])); logic minstret_enable_f; rvdff #(2) minstretf_cout_ff (.*, .clk(free_clk), .din({minstret_enable, minstretl_cout & ~wr_minstreth_wb}), .dout({minstret_enable_f, minstretl_cout_f})); @@ -1162,20 +1173,20 @@ module dec_tlu_ctl // Chained with minstretl. Note: minstretl overflow due to a minstreth write gets ignored. `define MINSTRETH 12'hb82 - + assign wr_minstreth_wb = dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[11:0] == `MINSTRETH); - assign {minstreth_cout_nc, minstreth_inc[31:0]} = minstreth[31:0] + {31'b0, minstretl_cout_f}; - assign minstreth_ns[31:0] = wr_minstreth_wb ? dec_csr_wrdata_wb[31:0] : minstreth_inc[31:0]; + assign {minstreth_cout_nc, minstreth_inc[31:0]} = minstreth[31:0] + {31'b0, minstretl_cout_f}; + assign minstreth_ns[31:0] = wr_minstreth_wb ? dec_csr_wrdata_wb[31:0] : minstreth_inc[31:0]; rvdffe #(32) minstreth_ff (.*, .en(minstret_enable_f | wr_minstreth_wb), .din(minstreth_ns[31:0]), .dout(minstreth[31:0])); - + assign minstreth_read[31:0] = minstreth_inc[31:0]; // ---------------------------------------------------------------------- // MSCRATCH (RW) // [31:0] : Scratch register `define MSCRATCH 12'h340 - + assign wr_mscratch_wb = dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[11:0] == `MSCRATCH); rvdffe #(32) mscratch_ff (.*, .en(wr_mscratch_wb), .din(dec_csr_wrdata_wb[31:0]), .dout(mscratch[31:0])); @@ -1204,42 +1215,42 @@ module dec_tlu_ctl ({31{(sel_hold_npc_e4)}} & npc_wb[31:1]) ); rvdffe #(31) npwbc_ff (.*, .en(sel_i0_npc_e4 | sel_exu_npc_e4 | sel_flush_npc_e4 | reset_delayed), .din(npc_e4[31:1]), .dout(npc_wb[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. logic pc0_valid_e4, pc1_valid_e4; assign pc0_valid_e4 = ~dec_tlu_dbg_halted & dec_tlu_i0_valid_e4; assign pc1_valid_e4 = ~dec_tlu_dbg_halted & dec_tlu_i0_valid_e4 & dec_tlu_i1_valid_e4 & ~lsu_i0_exc_dc4 & ~rfpc_i0_e4 & ~inst_acc_e4 & ~i0_trigger_hit_e4; - + assign pc_e4[31:1] = ( ({31{ pc0_valid_e4 & ~pc1_valid_e4}} & dec_tlu_i0_pc_e4[31:1]) | ({31{ pc1_valid_e4}} & dec_tlu_i1_pc_e4[31:1]) | ({31{~pc0_valid_e4 & ~pc1_valid_e4}} & pc_wb[31:1]) ); rvdffe #(31) pwbc_ff (.*, .en(pc0_valid_e4 | pc1_valid_e4), .din(pc_e4[31:1]), .dout(pc_wb[31:1])); - + assign wr_mepc_wb = dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[11:0] == `MEPC); assign mepc_ns[31:1] = ( ({31{i0_exception_valid_wb | lsu_exc_valid_wb | mepc_trigger_hit_sel_pc_wb}} & pc_wb[31:1]) | ({31{interrupt_valid_wb}} & npc_wb[31:1]) | ({31{wr_mepc_wb & ~exc_or_int_valid_wb}} & dec_csr_wrdata_wb[31:1]) | - ({31{~wr_mepc_wb & ~exc_or_int_valid_wb}} & mepc[31:1]) ); + ({31{~wr_mepc_wb & ~exc_or_int_valid_wb}} & mepc[31:1]) ); rvdff #(31) mepc_ff (.*, .clk(e4e5_int_clk), .din(mepc_ns[31:1]), .dout(mepc[31:1])); // ---------------------------------------------------------------------- // MCAUSE (RW) - // [31:0] : Exception Cause + // [31:0] : Exception Cause `define MCAUSE 12'h342 - + assign wr_mcause_wb = dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[11:0] == `MCAUSE); assign mcause_ns[31:0] = ( ({32{exc_or_int_valid_wb & take_nmi_wb & nmi_lsu_store_type_f}} & {32'hf000_0000}) | ({32{exc_or_int_valid_wb & take_nmi_wb & nmi_lsu_load_type_f}} & {32'hf000_0001}) | ({32{exc_or_int_valid_wb & ~take_nmi_wb}} & {interrupt_valid_wb, 26'b0, exc_cause_wb[4:0]}) | ({32{wr_mcause_wb & ~exc_or_int_valid_wb}} & dec_csr_wrdata_wb[31:0]) | - ({32{~wr_mcause_wb & ~exc_or_int_valid_wb}} & mcause[31:0]) ); + ({32{~wr_mcause_wb & ~exc_or_int_valid_wb}} & mcause[31:0]) ); rvdff #(32) mcause_ff (.*, .clk(e4e5_int_clk), .din(mcause_ns[31:0]), .dout(mcause[31:0])); @@ -1247,27 +1258,27 @@ module dec_tlu_ctl // MTVAL (RW) // [31:0] : Exception address if relevant `define MTVAL 12'h343 - + assign wr_mtval_wb = dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[11:0] == `MTVAL); assign mtval_capture_pc_wb = exc_or_int_valid_wb & (ebreak_wb | (inst_acc_wb & ~inst_acc_second_wb) | mepc_trigger_hit_sel_pc_wb) & ~take_nmi_wb; assign mtval_capture_pc_plus2_wb = exc_or_int_valid_wb & (inst_acc_wb & inst_acc_second_wb) & ~take_nmi_wb; assign mtval_capture_inst_wb = exc_or_int_valid_wb & illegal_wb & ~take_nmi_wb; assign mtval_capture_lsu_wb = exc_or_int_valid_wb & lsu_exc_valid_wb & ~take_nmi_wb; assign mtval_clear_wb = exc_or_int_valid_wb & ~mtval_capture_pc_wb & ~mtval_capture_inst_wb & ~mtval_capture_lsu_wb & ~mepc_trigger_hit_sel_pc_wb; - - + + assign mtval_ns[31:0] = (({32{mtval_capture_pc_wb}} & {pc_wb[31:1], 1'b0}) | ({32{mtval_capture_pc_plus2_wb}} & {pc_wb[31:1] + 31'b1, 1'b0}) | ({32{mtval_capture_inst_wb}} & dec_illegal_inst[31:0]) | - ({32{mtval_capture_lsu_wb}} & lsu_error_pkt_addr_wb[31:0]) | + ({32{mtval_capture_lsu_wb}} & lsu_error_pkt_addr_wb[31:0]) | ({32{wr_mtval_wb & ~interrupt_valid_wb}} & dec_csr_wrdata_wb[31:0]) | - ({32{~take_nmi_wb & ~wr_mtval_wb & ~mtval_capture_pc_wb & ~mtval_capture_inst_wb & ~mtval_clear_wb & ~mtval_capture_lsu_wb}} & mtval[31:0]) ); + ({32{~take_nmi_wb & ~wr_mtval_wb & ~mtval_capture_pc_wb & ~mtval_capture_inst_wb & ~mtval_clear_wb & ~mtval_capture_lsu_wb}} & mtval[31:0]) ); rvdff #(32) mtval_ff (.*, .clk(e4e5_int_clk), .din(mtval_ns[31:0]), .dout(mtval[31:0])); // ---------------------------------------------------------------------- - // MCGC (RW) Clock gating control + // MCGC (RW) Clock gating control // [31:9] : Reserved, reads 0x0 // [8] : misc_clk_override // [7] : dec_clk_override @@ -1278,7 +1289,7 @@ module dec_tlu_ctl // [2] : pic_clk_override // [1] : dccm_clk_override // [0] : icm_clk_override - // + // `define MCGC 12'h7f8 assign wr_mcgc_wb = dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[11:0] == `MCGC); @@ -1302,17 +1313,17 @@ module dec_tlu_ctl // [10] : Disable dual issue // [9] : Disable pic multiple ints // [8] : Disable core ecc - // [7] : Disable secondary alu?s + // [7] : Disable secondary alu?s // [6] : Disable multiple outstanding sideeffect accesses to bus - // [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 - // + // [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 + // `define MFDC 12'h7f9 - + assign wr_mfdc_wb = dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[11:0] == `MFDC); rvdffe #(14) mfdc_ff (.*, .en(wr_mfdc_wb), .din(mfdc_ns[13:0]), .dout(mfdc_int[13:0])); @@ -1337,7 +1348,7 @@ module dec_tlu_ctl assign dec_tlu_wb_coalescing_disable = mfdc[2]; assign dec_tlu_ld_miss_byp_wb_disable = mfdc[1]; assign dec_tlu_pipelining_disable = mfdc[0]; - + // ---------------------------------------------------------------------- // MCPC (RW) Pause counter // [31:0] : Reads 0x0, decs in the wb register in decode_ctl @@ -1349,7 +1360,7 @@ module dec_tlu_ctl // MRAC (RW) // [31:0] : Region Access Control Register, 16 regions, {side_effect, cachable} pairs `define MRAC 12'h7c0 - + assign wr_mrac_wb = dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[11:0] == `MRAC); // prevent pairs of 0x11, side_effect and cacheable @@ -1370,43 +1381,43 @@ module dec_tlu_ctl dec_csr_wrdata_wb[5], dec_csr_wrdata_wb[4] & ~dec_csr_wrdata_wb[5], dec_csr_wrdata_wb[3], dec_csr_wrdata_wb[2] & ~dec_csr_wrdata_wb[3], dec_csr_wrdata_wb[1], dec_csr_wrdata_wb[0] & ~dec_csr_wrdata_wb[1]}; - + rvdffe #(32) mrac_ff (.*, .en(wr_mrac_wb), .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 - // + // `define MDEAU 12'hbc0 - + assign wr_mdeau_wb = dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[11:0] == `MDEAU); - + // ---------------------------------------------------------------------- // MDSEAC (R) // [31:0] : Dbus Store Error Address Capture register - // + // `define MDSEAC 12'hfc0 - + // only capture error bus if the MDSEAC reg is not locked assign mdseac_locked_ns = mdseac_en | (mdseac_locked_f & ~wr_mdeau_wb); - + assign mdseac_en = (lsu_imprecise_error_store_any | lsu_imprecise_error_load_any) & ~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:0] : FW halt - // + // `define MPMC 12'h7c6 logic wr_mpmc_wb; assign wr_mpmc_wb = dec_csr_wrdata_wb[0] & dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[11:0] == `MPMC); - assign fw_halt_req = wr_mpmc_wb & ~internal_dbg_halt_mode_f; - + assign fw_halt_req = wr_mpmc_wb & ~internal_dbg_halt_mode_f & ~interrupt_valid_wb; + // ---------------------------------------------------------------------- // MICECT (I-Cache error counter/threshold) // [31:27] : Icache parity error threshold @@ -1415,7 +1426,7 @@ module dec_tlu_ctl logic [31:27] csr_sat; assign csr_sat[31:27] = (dec_csr_wrdata_wb[31:27] > 5'd26) ? 5'd26 : dec_csr_wrdata_wb[31:27]; - + assign wr_micect_wb = dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[11:0] == `MICECT); assign {micect_cout_nc, micect_inc[26:0]} = micect[26:0] + {26'b0, ic_perr_wb}; assign micect_ns = wr_micect_wb ? {csr_sat[31:27], dec_csr_wrdata_wb[26:0]} : {micect[31:27], micect_inc[26:0]}; @@ -1423,13 +1434,13 @@ module dec_tlu_ctl rvdffe #(32) micect_ff (.*, .en(wr_micect_wb | ic_perr_wb), .din(micect_ns[31:0]), .dout(micect[31:0])); assign mice_ce_req = |({32'b1 << 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 `define MICCMECT 12'h7f1 - + assign wr_miccmect_wb = dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[11:0] == `MICCMECT); assign {miccmect_cout_nc, miccmect_inc[26:0]} = miccmect[26:0] + {26'b0, iccm_sbecc_wb | iccm_dma_sb_error}; assign miccmect_ns = wr_miccmect_wb ? {csr_sat[31:27], dec_csr_wrdata_wb[26:0]} : {miccmect[31:27], miccmect_inc[26:0]}; @@ -1437,13 +1448,13 @@ module dec_tlu_ctl rvdffe #(32) miccmect_ff (.*, .en(wr_miccmect_wb | iccm_sbecc_wb | iccm_dma_sb_error), .din(miccmect_ns[31:0]), .dout(miccmect[31:0])); assign miccme_ce_req = |({32'b1 << miccmect[31:27]} & {5'b0, miccmect[26:0]}); - + // ---------------------------------------------------------------------- - // MDCCMECT (DCCM error counter/threshold) + // MDCCMECT (DCCM error counter/threshold) // [31:27] : DCCM parity error threshold // [26:0] : DCCM parity error count `define MDCCMECT 12'h7f2 - + assign wr_mdccmect_wb = dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[11:0] == `MDCCMECT); assign {mdccmect_cout_nc, mdccmect_inc[26:0]} = mdccmect[26:0] + {26'b0, lsu_single_ecc_error_wb}; assign mdccmect_ns = wr_mdccmect_wb ? {csr_sat[31:27], dec_csr_wrdata_wb[26:0]} : {mdccmect[31:27], mdccmect_inc[26:0]}; @@ -1451,13 +1462,13 @@ module dec_tlu_ctl rvdffe #(32) mdccmect_ff (.*, .en(wr_mdccmect_wb | lsu_single_ecc_error_wb), .din(mdccmect_ns[31:0]), .dout(mdccmect[31:0])); assign mdccme_ce_req = |({32'b1 << mdccmect[31:27]} & {5'b0, mdccmect[26:0]}); - + // ---------------------------------------------------------------------- // MEIVT (External Interrupt Vector Table (R/W)) // [31:10]: Base address (R/W) // [9:0] : Reserved, reads 0x0 `define MEIVT 12'hbc8 - + assign wr_meivt_wb = dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[11:0] == `MEIVT); rvdffe #(22) meivt_ff (.*, .en(wr_meivt_wb), .din(dec_csr_wrdata_wb[31:10]), .dout(meivt[31:10])); @@ -1468,38 +1479,38 @@ module dec_tlu_ctl // [9:2] : ClaimID (R) // [1:0] : Reserved, 0x0 `define MEIHAP 12'hfc8 - + assign wr_meihap_wb = wr_meicpct_wb; rvdffe #(8) meihap_ff (.*, .en(wr_meihap_wb), .din(pic_claimid[7:0]), .dout(meihap[9:2])); - + // ---------------------------------------------------------------------- // MEICURPL (R/W) // [31:4] : Reserved (read 0x0) // [3:0] : CURRPRI - Priority level of current interrupt service routine (R/W) `define MEICURPL 12'hbcc - + assign wr_meicurpl_wb = dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[11:0] == `MEICURPL); - assign meicurpl_ns[3:0] = wr_meicurpl_wb ? dec_csr_wrdata_wb[3:0] : meicurpl[3:0]; - + assign meicurpl_ns[3:0] = wr_meicurpl_wb ? dec_csr_wrdata_wb[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 `define MEICIDPL 12'hbcb - + assign wr_meicidpl_wb = (dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[11:0] == `MEICIDPL)); - - assign meicidpl_ns[3:0] = wr_meicpct_wb ? pic_pl[3:0] : (wr_meicidpl_wb ? dec_csr_wrdata_wb[3:0] : meicidpl[3:0]); - + + assign meicidpl_ns[3:0] = wr_meicpct_wb ? pic_pl[3:0] : (wr_meicidpl_wb ? dec_csr_wrdata_wb[3:0] : meicidpl[3:0]); + rvdff #(4) meicidpl_ff (.*, .clk(csr_wr_clk), .din(meicidpl_ns[3:0]), .dout(meicidpl[3:0])); - + // ---------------------------------------------------------------------- // MEICPCT (Capture CLAIMID in MEIHAP and PL in MEICIDPL // [31:1] : Reserved (read 0x0) @@ -1511,12 +1522,12 @@ module dec_tlu_ctl // ---------------------------------------------------------------------- // MEIPT (External Interrupt Priority Threshold) // [31:4] : Reserved (read 0x0) - // [3:0] : PRITHRESH + // [3:0] : PRITHRESH `define MEIPT 12'hbc9 - + assign wr_meipt_wb = dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[11:0] == `MEIPT); - assign meipt_ns[3:0] = wr_meipt_wb ? dec_csr_wrdata_wb[3:0] : meipt[3:0]; - + assign meipt_ns[3:0] = wr_meipt_wb ? dec_csr_wrdata_wb[3:0] : meipt[3:0]; + rvdff #(4) meipt_ff (.*, .clk(active_clk), .din(meipt_ns[3:0]), .dout(meipt[3:0])); // to PIC @@ -1541,7 +1552,7 @@ module dec_tlu_ctl `define DCSR 12'h7b0 logic [8:6] dcsr_cause; - // RV has clarified that 'priority 4' in the spec means top priority. + // 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. @@ -1549,31 +1560,31 @@ module dec_tlu_ctl assign dcsr_cause[8:6] = ( ({3{dcsr_single_step_done_f & ~ebreak_to_debug_mode_wb & ~trigger_hit_for_dscr_cause_wb & ~debug_halt_req}} & 3'b100) | ({3{debug_halt_req & ~ebreak_to_debug_mode_wb & ~trigger_hit_for_dscr_cause_wb}} & 3'b011) | - ({3{ebreak_to_debug_mode_wb & ~trigger_hit_for_dscr_cause_wb}} & 3'b001) | + ({3{ebreak_to_debug_mode_wb & ~trigger_hit_for_dscr_cause_wb}} & 3'b001) | ({3{trigger_hit_for_dscr_cause_wb}} & 3'b010)); assign wr_dcsr_wb = allow_dbg_halt_csr_write & dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[11:0] == `DCSR); - - // Multiple halt enter requests can happen before we are halted. + + // 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. logic enter_debug_halt_req_le, dcsr_cause_upgradeable; 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]} : + assign dcsr_ns[15:2] = enter_debug_halt_req_le ? {dcsr[15:9], dcsr_cause[8:6], dcsr[5:2]} : (wr_dcsr_wb ? {dec_csr_wrdata_wb[15], 3'b0, dec_csr_wrdata_wb[11:10], 1'b0, dcsr[8:6], 2'b00, nmi_in_debug_mode | dcsr[3], dec_csr_wrdata_wb[2]} : {dcsr[15:4], nmi_in_debug_mode, dcsr[2]}); - + rvdffe #(14) dcsr_ff (.*, .en(enter_debug_halt_req_le | wr_dcsr_wb | internal_dbg_halt_mode | take_nmi_wb), .din(dcsr_ns[15:2]), .dout(dcsr[15:2])); // ---------------------------------------------------------------------- // DPC (R/W) (Only accessible in debug mode) // [31:0] : Debug PC `define DPC 12'h7b1 - + assign wr_dpc_wb = allow_dbg_halt_csr_write & dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[11:0] == `DPC); assign dpc_capture_npc = dbg_tlu_halted & ~dbg_tlu_halted_f & ~request_debug_mode_done_f; assign dpc_capture_pc = request_debug_mode_wb; @@ -1581,7 +1592,7 @@ module dec_tlu_ctl assign dpc_ns[31:1] = ( ({31{~dpc_capture_pc & ~dpc_capture_npc & wr_dpc_wb}} & dec_csr_wrdata_wb[31:1]) | ({31{dpc_capture_pc}} & pc_wb[31:1]) | ({31{~dpc_capture_pc & dpc_capture_npc}} & npc_wb[31:1]) ); - + rvdffe #(31) dpc_ff (.*, .en(wr_dpc_wb | dpc_capture_pc | dpc_capture_npc), .din(dpc_ns[31:1]), .dout(dpc[31:1])); // ---------------------------------------------------------------------- @@ -1597,7 +1608,7 @@ module dec_tlu_ctl assign dicawics_ns[18:2] = {dec_csr_wrdata_wb[24], dec_csr_wrdata_wb[21:20], dec_csr_wrdata_wb[15:2]}; assign wr_dicawics_wb = allow_dbg_halt_csr_write & dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[11:0] == `DICAWICS); - + rvdffe #(17) dicawics_ff (.*, .en(wr_dicawics_wb), .din(dicawics_ns[18:2]), .dout(dicawics[18:2])); // ---------------------------------------------------------------------- @@ -1617,7 +1628,7 @@ module dec_tlu_ctl assign dicad0_ns[31:0] = wr_dicad0_wb ? dec_csr_wrdata_wb[31:0] : ifu_ic_debug_rd_data[31:0]; assign wr_dicad0_wb = allow_dbg_halt_csr_write & dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[11:0] == `DICAD0); - + rvdffe #(32) dicad0_ff (.*, .en(wr_dicad0_wb | ifu_ic_debug_rd_data_valid), .din(dicad0_ns[31:0]), .dout(dicad0[31:0])); @@ -1630,7 +1641,7 @@ module dec_tlu_ctl assign dicad1_ns[9:0] = wr_dicad1_wb ? dec_csr_wrdata_wb[9:0] : ifu_ic_debug_rd_data[41:32]; assign wr_dicad1_wb = allow_dbg_halt_csr_write & dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[11:0] == `DICAD1); - + rvdffs #(10) dicad1_ff (.*, .clk(active_clk), .en(wr_dicad1_wb | ifu_ic_debug_rd_data_valid), .din(dicad1_ns[9:0]), .dout(dicad1[9:0])); `else @@ -1642,16 +1653,16 @@ module dec_tlu_ctl assign dicad1_ns[1:0] = wr_dicad1_wb ? dec_csr_wrdata_wb[1:0] : ifu_ic_debug_rd_data[33:32]; assign wr_dicad1_wb = allow_dbg_halt_csr_write & dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[11:0] == `DICAD1); - + rvdffs #(2) dicad1_ff (.*, .clk(active_clk), .en(wr_dicad1_wb | ifu_ic_debug_rd_data_valid), .din(dicad1_ns[1:0]), .dout(dicad1[1:0])); `endif // ---------------------------------------------------------------------- // DICAGO (R/W) (Only accessible in debug mode) // [0] : Go `define DICAGO 12'h7cb - + `ifdef RV_ICACHE_ECC - assign dec_tlu_ic_diag_pkt.icache_wrdata[41:0] = {dicad1[9:0], dicad0[31:0]}; + assign dec_tlu_ic_diag_pkt.icache_wrdata[41:0] = {dicad1[9:0], dicad0[31:0]}; `else assign dec_tlu_ic_diag_pkt.icache_wrdata[33:0] = {dicad1[1:0], dicad0[31:0]}; `endif @@ -1670,12 +1681,12 @@ module dec_tlu_ctl // MTSEL (R/W) // [1:0] : Trigger select : 00, 01, 10 are data/address triggers. 11 is inst count `define MTSEL 12'h7a0 - + assign wr_mtsel_wb = dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[11:0] == `MTSEL); - assign mtsel_ns[1:0] = wr_mtsel_wb ? {dec_csr_wrdata_wb[1:0]} : mtsel[1:0]; + assign mtsel_ns[1:0] = wr_mtsel_wb ? {dec_csr_wrdata_wb[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 @@ -1716,76 +1727,76 @@ module dec_tlu_ctl assign tdata_opcode = dec_csr_wrdata_wb[2] & ~dec_csr_wrdata_wb[19]; // don't allow clearing DMODE and action=1 assign tdata_action = (dec_csr_wrdata_wb[27] & dbg_tlu_halted_f) & dec_csr_wrdata_wb[12]; - - assign tdata_wrdata_wb[9:0] = {dec_csr_wrdata_wb[27] & dbg_tlu_halted_f, + + assign tdata_wrdata_wb[9:0] = {dec_csr_wrdata_wb[27] & dbg_tlu_halted_f, dec_csr_wrdata_wb[20:19], - tdata_action, - dec_csr_wrdata_wb[11], - dec_csr_wrdata_wb[7:6], - tdata_opcode, - dec_csr_wrdata_wb[1], + tdata_action, + dec_csr_wrdata_wb[11], + dec_csr_wrdata_wb[7:6], + tdata_opcode, + dec_csr_wrdata_wb[1], tdata_load}; // If the DMODE bit is set, tdata1 can only be updated in debug_mode assign wr_mtdata1_t0_wb = dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[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_wb ? tdata_wrdata_wb[9:0] : - {mtdata1_t0[9], update_hit_bit_wb[0] | mtdata1_t0[8], mtdata1_t0[7:0]}; + assign mtdata1_t0_ns[9:0] = wr_mtdata1_t0_wb ? tdata_wrdata_wb[9:0] : + {mtdata1_t0[9], update_hit_bit_wb[0] | mtdata1_t0[8], mtdata1_t0[7:0]}; assign wr_mtdata1_t1_wb = dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[11:0] == `MTDATA1) & (mtsel[1:0] == 2'b01) & (~mtdata1_t1[`MTDATA1_DMODE] | dbg_tlu_halted_f); - assign mtdata1_t1_ns[9:0] = wr_mtdata1_t1_wb ? tdata_wrdata_wb[9:0] : - {mtdata1_t1[9], update_hit_bit_wb[1] | mtdata1_t1[8], mtdata1_t1[7:0]}; + assign mtdata1_t1_ns[9:0] = wr_mtdata1_t1_wb ? tdata_wrdata_wb[9:0] : + {mtdata1_t1[9], update_hit_bit_wb[1] | mtdata1_t1[8], mtdata1_t1[7:0]}; assign wr_mtdata1_t2_wb = dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[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_wb ? tdata_wrdata_wb[9:0] : - {mtdata1_t2[9], update_hit_bit_wb[2] | mtdata1_t2[8], mtdata1_t2[7:0]}; + assign mtdata1_t2_ns[9:0] = wr_mtdata1_t2_wb ? tdata_wrdata_wb[9:0] : + {mtdata1_t2[9], update_hit_bit_wb[2] | mtdata1_t2[8], mtdata1_t2[7:0]}; assign wr_mtdata1_t3_wb = dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[11:0] == `MTDATA1) & (mtsel[1:0] == 2'b11) & (~mtdata1_t3[`MTDATA1_DMODE] | dbg_tlu_halted_f); - assign mtdata1_t3_ns[9:0] = wr_mtdata1_t3_wb ? tdata_wrdata_wb[9:0] : - {mtdata1_t3[9], update_hit_bit_wb[3] | mtdata1_t3[8], mtdata1_t3[7:0]}; + assign mtdata1_t3_ns[9:0] = wr_mtdata1_t3_wb ? tdata_wrdata_wb[9:0] : + {mtdata1_t3[9], update_hit_bit_wb[3] | mtdata1_t3[8], mtdata1_t3[7:0]}; + - rvdff #(10) mtdata1_t0_ff (.*, .clk(active_clk), .din(mtdata1_t0_ns[9:0]), .dout(mtdata1_t0[9:0])); rvdff #(10) mtdata1_t1_ff (.*, .clk(active_clk), .din(mtdata1_t1_ns[9:0]), .dout(mtdata1_t1[9:0])); rvdff #(10) mtdata1_t2_ff (.*, .clk(active_clk), .din(mtdata1_t2_ns[9:0]), .dout(mtdata1_t2[9:0])); rvdff #(10) mtdata1_t3_ff (.*, .clk(active_clk), .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].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 @@ -1801,12 +1812,12 @@ module dec_tlu_ctl rvdffe #(32) mtdata2_t1_ff (.*, .en(wr_mtdata2_t1_wb), .din(dec_csr_wrdata_wb[31:0]), .dout(mtdata2_t1[31:0])); rvdffe #(32) mtdata2_t2_ff (.*, .en(wr_mtdata2_t2_wb), .din(dec_csr_wrdata_wb[31:0]), .dout(mtdata2_t2[31:0])); rvdffe #(32) mtdata2_t3_ff (.*, .en(wr_mtdata2_t3_wb), .din(dec_csr_wrdata_wb[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]; @@ -1825,21 +1836,21 @@ module dec_tlu_ctl `define MHPME_INST_COMMIT_32B 6'd6 `define MHPME_INST_ALIGNED 6'd7 // OOP `define MHPME_INST_DECODED 6'd8 // OOP - `define MHPME_INST_MUL 6'd9 + `define MHPME_INST_MUL 6'd9 `define MHPME_INST_DIV 6'd10 - `define MHPME_INST_LOAD 6'd11 - `define MHPME_INST_STORE 6'd12 - `define MHPME_INST_MALOAD 6'd13 - `define MHPME_INST_MASTORE 6'd14 - `define MHPME_INST_ALU 6'd15 - `define MHPME_INST_CSRREAD 6'd16 - `define MHPME_INST_CSRRW 6'd17 - `define MHPME_INST_CSRWRITE 6'd18 - `define MHPME_INST_EBREAK 6'd19 - `define MHPME_INST_ECALL 6'd20 - `define MHPME_INST_FENCE 6'd21 - `define MHPME_INST_FENCEI 6'd22 - `define MHPME_INST_MRET 6'd23 + `define MHPME_INST_LOAD 6'd11 + `define MHPME_INST_STORE 6'd12 + `define MHPME_INST_MALOAD 6'd13 + `define MHPME_INST_MASTORE 6'd14 + `define MHPME_INST_ALU 6'd15 + `define MHPME_INST_CSRREAD 6'd16 + `define MHPME_INST_CSRRW 6'd17 + `define MHPME_INST_CSRWRITE 6'd18 + `define MHPME_INST_EBREAK 6'd19 + `define MHPME_INST_ECALL 6'd20 + `define MHPME_INST_FENCE 6'd21 + `define MHPME_INST_FENCEI 6'd22 + `define MHPME_INST_MRET 6'd23 `define MHPME_INST_BRANCH 6'd24 `define MHPME_BRANCH_MP 6'd25 `define MHPME_BRANCH_TAKEN 6'd26 @@ -1867,9 +1878,9 @@ module dec_tlu_ctl `define MHPME_DBUS_STALL 6'd48 // OOP `define MHPME_INT_DISABLED 6'd49 // OOP `define MHPME_INT_STALLED 6'd50 // OOP - - - logic [3:0][1:0] mhpmc_inc_e4, mhpmc_inc_wb; + + + logic [3:0][1:0] mhpmc_inc_e4, mhpmc_inc_wb; logic [3:0][5:0] mhpme_vec; logic mhpmc3_wr_en0, mhpmc3_wr_en1, mhpmc3_wr_en; logic mhpmc4_wr_en0, mhpmc4_wr_en1, mhpmc4_wr_en; @@ -1880,7 +1891,7 @@ module dec_tlu_ctl 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; - + // Pack the event selects into a vector for genvar assign mhpme_vec[0][5:0] = mhpme3[5:0]; assign mhpme_vec[1][5:0] = mhpme4[5:0]; @@ -1891,11 +1902,11 @@ module dec_tlu_ctl logic [3:0] pmu_i0_itype_qual, pmu_i1_itype_qual; assign pmu_i0_itype_qual[3:0] = dec_tlu_packet_e4.pmu_i0_itype[3:0] & {4{tlu_i0_commit_cmt}}; assign pmu_i1_itype_qual[3:0] = dec_tlu_packet_e4.pmu_i1_itype[3:0] & {4{tlu_i1_commit_cmt}}; - + // Generate the muxed incs for all counters based on event type for (genvar i=0 ; i < 4; i++) begin - assign mhpmc_inc_e4[i][1:0] = {2{mgpmc}} & - ( + assign mhpmc_inc_e4[i][1:0] = {2{mgpmc}} & + ( ({2{(mhpme_vec[i][5:0] == `MHPME_CLK_ACTIVE )}} & 2'b01) | ({2{(mhpme_vec[i][5:0] == `MHPME_ICACHE_HIT )}} & {1'b0, ifu_pmu_ic_hit}) | ({2{(mhpme_vec[i][5:0] == `MHPME_ICACHE_MISS )}} & {1'b0, ifu_pmu_ic_miss}) | @@ -1910,9 +1921,9 @@ module dec_tlu_ctl ({2{(mhpme_vec[i][5:0] == `MHPME_INST_DIV )}} & {1'b0, dec_tlu_packet_e4.pmu_divide & tlu_i0_commit_cmt}) | ({2{(mhpme_vec[i][5:0] == `MHPME_INST_LOAD )}} & {(pmu_i1_itype_qual[3:0] == LOAD), (pmu_i0_itype_qual[3:0] == LOAD)}) | ({2{(mhpme_vec[i][5:0] == `MHPME_INST_STORE )}} & {(pmu_i1_itype_qual[3:0] == STORE), (pmu_i0_itype_qual[3:0] == STORE)}) | - ({2{(mhpme_vec[i][5:0] == `MHPME_INST_MALOAD )}} & {(pmu_i1_itype_qual[3:0] == LOAD), (pmu_i0_itype_qual[3:0] == LOAD)} & + ({2{(mhpme_vec[i][5:0] == `MHPME_INST_MALOAD )}} & {(pmu_i1_itype_qual[3:0] == LOAD), (pmu_i0_itype_qual[3:0] == LOAD)} & {2{dec_tlu_packet_e4.pmu_lsu_misaligned}}) | - ({2{(mhpme_vec[i][5:0] == `MHPME_INST_MASTORE )}} & {(pmu_i1_itype_qual[3:0] == STORE), (pmu_i0_itype_qual[3:0] == STORE)} & + ({2{(mhpme_vec[i][5:0] == `MHPME_INST_MASTORE )}} & {(pmu_i1_itype_qual[3:0] == STORE), (pmu_i0_itype_qual[3:0] == STORE)} & {2{dec_tlu_packet_e4.pmu_lsu_misaligned}}) | ({2{(mhpme_vec[i][5:0] == `MHPME_INST_ALU )}} & {(pmu_i1_itype_qual[3:0] == ALU), (pmu_i0_itype_qual[3:0] == ALU)}) | ({2{(mhpme_vec[i][5:0] == `MHPME_INST_CSRREAD )}} & {1'b0, (pmu_i0_itype_qual[3:0] == CSRREAD)}) | @@ -1950,7 +1961,7 @@ module dec_tlu_ctl ({2{(mhpme_vec[i][5:0] == `MHPME_IBUS_STALL )}} & {1'b0, ifu_pmu_bus_busy}) | ({2{(mhpme_vec[i][5:0] == `MHPME_DBUS_STALL )}} & {1'b0, lsu_pmu_bus_busy}) | ({2{(mhpme_vec[i][5:0] == `MHPME_INT_DISABLED )}} & {1'b0, ~mstatus[`MSTATUS_MIE]}) | - ({2{(mhpme_vec[i][5:0] == `MHPME_INT_STALLED )}} & {1'b0, ~mstatus[`MSTATUS_MIE] & |(mip[3:0] & mie[3:0])}) + ({2{(mhpme_vec[i][5:0] == `MHPME_INT_STALLED )}} & {1'b0, ~mstatus[`MSTATUS_MIE] & |(mip[3:0] & mie[3:0])}) ); end @@ -1960,7 +1971,7 @@ module dec_tlu_ctl rvdff #(2) pmu3inc_ff (.*, .clk(free_clk), .din(mhpmc_inc_e4[3][1:0]), .dout(mhpmc_inc_wb[3][1:0])); assign perfcnt_halted = ((dec_tlu_dbg_halted & dcsr[`DCSR_STOPC]) | dec_tlu_pmu_fw_halted); - + assign dec_tlu_perfcnt0[1:0] = mhpmc_inc_wb[0][1:0] & ~{2{perfcnt_halted}}; assign dec_tlu_perfcnt1[1:0] = mhpmc_inc_wb[1][1:0] & ~{2{perfcnt_halted}}; assign dec_tlu_perfcnt2[1:0] = mhpmc_inc_wb[2][1:0] & ~{2{perfcnt_halted}}; @@ -1971,11 +1982,11 @@ module dec_tlu_ctl // [63:32][31:0] : Hardware Performance Monitor Counter 3 `define MHPMC3 12'hB03 `define MHPMC3H 12'hB83 - + assign mhpmc3_wr_en0 = dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[11:0] == `MHPMC3); assign mhpmc3_wr_en1 = ~perfcnt_halted & (|(mhpmc_inc_wb[0][1:0])); assign mhpmc3_wr_en = mhpmc3_wr_en0 | mhpmc3_wr_en1; - assign mhpmc3_incr[63:0] = {mhpmc3h[31:0],mhpmc3[31:0]} + {63'b0,mhpmc_inc_wb[0][1]} + {63'b0,mhpmc_inc_wb[0][0]}; + assign mhpmc3_incr[63:0] = {mhpmc3h[31:0],mhpmc3[31:0]} + {63'b0,mhpmc_inc_wb[0][1]} + {63'b0,mhpmc_inc_wb[0][0]}; assign mhpmc3_ns[31:0] = mhpmc3_wr_en0 ? dec_csr_wrdata_wb[31:0] : mhpmc3_incr[31:0]; rvdffe #(32) mhpmc3_ff (.*, .en(mhpmc3_wr_en), .din(mhpmc3_ns[31:0]), .dout(mhpmc3[31:0])); @@ -1989,11 +2000,11 @@ module dec_tlu_ctl // [63:32][31:0] : Hardware Performance Monitor Counter 4 `define MHPMC4 12'hB04 `define MHPMC4H 12'hB84 - + assign mhpmc4_wr_en0 = dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[11:0] == `MHPMC4); assign mhpmc4_wr_en1 = ~perfcnt_halted & (|(mhpmc_inc_wb[1][1:0])); assign mhpmc4_wr_en = mhpmc4_wr_en0 | mhpmc4_wr_en1; - assign mhpmc4_incr[63:0] = {mhpmc4h[31:0],mhpmc4[31:0]} + {63'b0,mhpmc_inc_wb[1][1]} + {63'b0,mhpmc_inc_wb[1][0]}; + assign mhpmc4_incr[63:0] = {mhpmc4h[31:0],mhpmc4[31:0]} + {63'b0,mhpmc_inc_wb[1][1]} + {63'b0,mhpmc_inc_wb[1][0]}; assign mhpmc4_ns[31:0] = mhpmc4_wr_en0 ? dec_csr_wrdata_wb[31:0] : mhpmc4_incr[31:0]; rvdffe #(32) mhpmc4_ff (.*, .en(mhpmc4_wr_en), .din(mhpmc4_ns[31:0]), .dout(mhpmc4[31:0])); @@ -2007,11 +2018,11 @@ module dec_tlu_ctl // [63:32][31:0] : Hardware Performance Monitor Counter 5 `define MHPMC5 12'hB05 `define MHPMC5H 12'hB85 - + assign mhpmc5_wr_en0 = dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[11:0] == `MHPMC5); assign mhpmc5_wr_en1 = ~perfcnt_halted & (|(mhpmc_inc_wb[2][1:0])); assign mhpmc5_wr_en = mhpmc5_wr_en0 | mhpmc5_wr_en1; - assign mhpmc5_incr[63:0] = {mhpmc5h[31:0],mhpmc5[31:0]} + {63'b0,mhpmc_inc_wb[2][1]} + {63'b0,mhpmc_inc_wb[2][0]}; + assign mhpmc5_incr[63:0] = {mhpmc5h[31:0],mhpmc5[31:0]} + {63'b0,mhpmc_inc_wb[2][1]} + {63'b0,mhpmc_inc_wb[2][0]}; assign mhpmc5_ns[31:0] = mhpmc5_wr_en0 ? dec_csr_wrdata_wb[31:0] : mhpmc5_incr[31:0]; rvdffe #(32) mhpmc5_ff (.*, .en(mhpmc5_wr_en), .din(mhpmc5_ns[31:0]), .dout(mhpmc5[31:0])); @@ -2025,11 +2036,11 @@ module dec_tlu_ctl // [63:32][31:0] : Hardware Performance Monitor Counter 6 `define MHPMC6 12'hB06 `define MHPMC6H 12'hB86 - + assign mhpmc6_wr_en0 = dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[11:0] == `MHPMC6); assign mhpmc6_wr_en1 = ~perfcnt_halted & (|(mhpmc_inc_wb[3][1:0])); assign mhpmc6_wr_en = mhpmc6_wr_en0 | mhpmc6_wr_en1; - assign mhpmc6_incr[63:0] = {mhpmc6h[31:0],mhpmc6[31:0]} + {63'b0,mhpmc_inc_wb[3][1]} + {63'b0,mhpmc_inc_wb[3][0]}; + assign mhpmc6_incr[63:0] = {mhpmc6h[31:0],mhpmc6[31:0]} + {63'b0,mhpmc_inc_wb[3][1]} + {63'b0,mhpmc_inc_wb[3][0]}; assign mhpmc6_ns[31:0] = mhpmc6_wr_en0 ? dec_csr_wrdata_wb[31:0] : mhpmc6_incr[31:0]; rvdffe #(32) mhpmc6_ff (.*, .en(mhpmc6_wr_en), .din(mhpmc6_ns[31:0]), .dout(mhpmc6[31:0])); @@ -2046,28 +2057,28 @@ module dec_tlu_ctl // we only have 50 events, HPME* are WARL so saturate at 50 logic [5:0] event_saturate_wb; assign event_saturate_wb[5:0] = ((dec_csr_wrdata_wb[5:0] > 6'd50) | (|dec_csr_wrdata_wb[31:6])) ? 6'd50 : dec_csr_wrdata_wb[5:0]; - + assign wr_mhpme3_wb = dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[11:0] == `MHPME3); rvdffs #(6) mhpme3_ff (.*, .clk(active_clk), .en(wr_mhpme3_wb), .din(event_saturate_wb[5:0]), .dout(mhpme3[5:0])); // ---------------------------------------------------------------------- // MHPME4(RW) // [5:0] : Hardware Performance Monitor Event 4 `define MHPME4 12'h324 - + assign wr_mhpme4_wb = dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[11:0] == `MHPME4); rvdffs #(6) mhpme4_ff (.*, .clk(active_clk), .en(wr_mhpme4_wb), .din(event_saturate_wb[5:0]), .dout(mhpme4[5:0])); // ---------------------------------------------------------------------- // MHPME5(RW) // [5:0] : Hardware Performance Monitor Event 5 `define MHPME5 12'h325 - + assign wr_mhpme5_wb = dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[11:0] == `MHPME5); rvdffs #(6) mhpme5_ff (.*, .clk(active_clk), .en(wr_mhpme5_wb), .din(event_saturate_wb[5:0]), .dout(mhpme5[5:0])); // ---------------------------------------------------------------------- // MHPME6(RW) // [5:0] : Hardware Performance Monitor Event 6 `define MHPME6 12'h326 - + assign wr_mhpme6_wb = dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[11:0] == `MHPME6); rvdffs #(6) mhpme6_ff (.*, .clk(active_clk), .en(wr_mhpme6_wb), .din(event_saturate_wb[5:0]), .dout(mhpme6[5:0])); @@ -2086,21 +2097,21 @@ module dec_tlu_ctl assign wr_mgpmc_wb = dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[11:0] == `MGPMC); rvdffs #(1) mgpmc_ff (.*, .clk(active_clk), .en(wr_mgpmc_wb), .din(~dec_csr_wrdata_wb[0]), .dout(mgpmc_b)); assign mgpmc = ~mgpmc_b; - + //-------------------------------------------------------------------------------- // trace //-------------------------------------------------------------------------------- logic usoc_tclk; - - rvoclkhdr usoctrace_cgc ( .en(i0_valid_wb | exc_or_int_valid_wb | interrupt_valid_wb | dec_tlu_i0_valid_wb1 | + + rvoclkhdr usoctrace_cgc ( .en(i0_valid_wb | exc_or_int_valid_wb | interrupt_valid_wb | dec_tlu_i0_valid_wb1 | dec_tlu_i0_exc_valid_wb1 | dec_tlu_i1_exc_valid_wb1 | dec_tlu_int_valid_wb1 | clk_override), .l1clk(usoc_tclk), .* ); - rvdff #(10) traceff (.*, .clk(usoc_tclk), - .din ({i0_valid_wb, i1_valid_wb, - i0_exception_valid_wb | lsu_i0_exc_wb | (i0_trigger_hit_wb & ~trigger_hit_dmode_wb), + rvdff #(10) traceff (.*, .clk(usoc_tclk), + .din ({i0_valid_wb, i1_valid_wb, + i0_exception_valid_wb | lsu_i0_exc_wb | (i0_trigger_hit_wb & ~trigger_hit_dmode_wb), ~(i0_exception_valid_wb | lsu_i0_exc_wb | i0_trigger_hit_wb) & exc_or_int_valid_wb & ~interrupt_valid_wb, exc_cause_wb[4:0], - interrupt_valid_wb}), + interrupt_valid_wb}), .dout({dec_tlu_i0_valid_wb1, dec_tlu_i1_valid_wb1, dec_tlu_i0_exc_valid_wb1, dec_tlu_i1_exc_valid_wb1, dec_tlu_exc_cause_wb1[4:0], @@ -2111,7 +2122,7 @@ module dec_tlu_ctl // end trace //-------------------------------------------------------------------------------- - + // ---------------------------------------------------------------------- // CSR read mux // ---------------------------------------------------------------------- @@ -2471,20 +2482,20 @@ assign legal_csr = (!dec_csr_rdaddr_d[11]&dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[ - + 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; assign valid_csr = ( legal_csr & (~(csr_dcsr | csr_dpc | csr_dmst | csr_dicawics | csr_dicad0 | csr_dicad1 | csr_dicago) | dbg_tlu_halted_f)); - -assign dec_csr_legal_d = ( dec_csr_any_unq_d & + +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] = ( ({32{csr_misa}} & 32'h40001104) | ({32{csr_mvendorid}} & 32'h00000045) | ({32{csr_marchid}} & 32'h0000000b) | - ({32{csr_mimpid}} & 32'h1) | + ({32{csr_mimpid}} & 32'h2) | ({32{csr_mstatus}} & {19'b0, 2'b11, 3'b0, mstatus[1], 3'b0, mstatus[0], 3'b0}) | ({32{csr_mtvec}} & {mtvec[30:1], 1'b0, mtvec[0]}) | ({32{csr_mip}} & {1'b0, mip[3], 18'b0, mip[2], 3'b0, mip[1], 3'b0, mip[0], 3'b0}) | @@ -2536,8 +2547,8 @@ assign dec_csr_rddata_d[31:0] = ( ({32{csr_misa}} & 32'h40001104) | ({32{csr_mgpmc}} & {31'b0, mgpmc}) ); - - + + `undef MSTATUS_MIE `undef MISA `undef MVENDORID @@ -2567,6 +2578,6 @@ assign dec_csr_rddata_d[31:0] = ( ({32{csr_misa}} & 32'h40001104) | `undef MEIPT `undef MEICURPL - + endmodule // dec_tlu_ctl diff --git a/design/dec/dec_trigger.sv b/design/dec/dec_trigger.sv index f95d69f..7ecb7d3 100644 --- a/design/dec/dec_trigger.sv +++ b/design/dec/dec_trigger.sv @@ -1,12 +1,12 @@ // 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. @@ -16,13 +16,13 @@ //******************************************************************************** // $Id$ // -// -// Owner: +// +// Owner: // Function: DEC Trigger Logic // Comments: // //******************************************************************************** -module dec_trigger +module dec_trigger import swerv_types::*; ( input logic clk, @@ -30,23 +30,23 @@ module dec_trigger input 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 - input logic [31:1] dec_i1_pc_d, // i1 pc - + input logic [31:1] dec_i1_pc_d, // i1 pc + output logic [3:0] dec_i0_trigger_match_d, - output logic [3:0] dec_i1_trigger_match_d + output logic [3:0] dec_i1_trigger_match_d ); logic [3:0][31:0] dec_i0_match_data; logic [3:0] dec_i0_trigger_data_match; logic [3:0][31:0] dec_i1_match_data; logic [3:0] dec_i1_trigger_data_match; - + for (genvar i=0; i<4; i++) begin 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 assign dec_i1_match_data[i][31:0] = ({32{~trigger_pkt_any[i].select & trigger_pkt_any[i].execute}} & {dec_i1_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])); + + 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])); rvmaskandmatch trigger_i1_match (.mask(trigger_pkt_any[i].tdata2[31:0]), .data(dec_i1_match_data[i][31:0]), .masken(trigger_pkt_any[i].match), .match(dec_i1_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]; diff --git a/design/dec/decode b/design/dec/decode index e4e85dd..efce112 100644 --- a/design/dec/decode +++ b/design/dec/decode @@ -3,21 +3,21 @@ add = [0000000..........000.....0110011] addi = [.................000.....0010011] - + sub = [0100000..........000.....0110011] - + and = [0000000..........111.....0110011] andi = [.................111.....0010011] - + or = [0000000..........110.....0110011] ori = [.................110.....0010011] - + xor = [0000000..........100.....0110011] xori = [.................100.....0010011] - + sll = [0000000..........001.....0110011] slli = [0000000..........001.....0010011] - + sra = [0100000..........101.....0110011] srai = [0100000..........101.....0010011] @@ -26,30 +26,30 @@ srli = [0000000..........101.....0010011] lui = [.........................0110111] auipc= [.........................0010111] - + slt = [0000000..........010.....0110011] sltu = [0000000..........011.....0110011] slti = [.................010.....0010011] sltiu= [.................011.....0010011] - + beq = [.................000.....1100011] bne = [.................001.....1100011] bge = [.................101.....1100011] blt = [.................100.....1100011] bgeu = [.................111.....1100011] bltu = [.................110.....1100011] - + jal = [.........................1101111] jalr = [.................000.....1100111] - + lb = [.................000.....0000011] lh = [.................001.....0000011] lw = [.................010.....0000011] - + sb = [.................000.....0100011] sh = [.................001.....0100011] sw = [.................010.....0100011] - + lbu = [.................100.....0000011] lhu = [.................101.....0000011] @@ -117,41 +117,41 @@ rem = [0000001..........110.....0110011] remu = [0000001..........111.....0110011] -.input +.input rv32i = { - 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[13] - i[12] - 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[13] + i[12] + i[11] + i[10] + i[9] + i[8] + i[7] + i[6] + i[5] + i[4] + i[3] + i[2] + i[1] + i[0] } @@ -188,7 +188,7 @@ rv32i = { by half word - csr_read + csr_read csr_clr csr_set csr_write @@ -294,22 +294,22 @@ rv32i[csrrc_ro] = { alu rd csr_read lor } # put csr on rs2 and make rs1 0's into alu. Save rs1 for csr_clr later rv32i[csrrc_rw{0-4}] = { alu rd csr_read rs1 csr_clr lor presync postsync } - + rv32i[csrrci_ro] = { alu rd csr_read lor } - + rv32i[csrrci_rw{0-4}] = { alu rd csr_read rs1 csr_clr csr_imm lor presync postsync } - + rv32i[csrrs_ro] = { alu rd csr_read lor } - + rv32i[csrrs_rw{0-4}] = { alu rd csr_read rs1 csr_set lor presync postsync } - + rv32i[csrrsi_ro] = { alu rd csr_read lor } - + rv32i[csrrsi_rw{0-4}] = { alu rd csr_read rs1 csr_set csr_imm lor presync postsync } - + rv32i[csrrw{0-4}] = { alu rd csr_read rs1 csr_write lor presync postsync } - + rv32i[csrrwi{0-4}] = { alu rd csr_read rs1 csr_write csr_imm lor presync postsync } # optimize csr write only - pipelined diff --git a/design/dma_ctrl.sv b/design/dma_ctrl.sv index cc97042..4238b28 100644 --- a/design/dma_ctrl.sv +++ b/design/dma_ctrl.sv @@ -1,12 +1,12 @@ // 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. @@ -17,7 +17,7 @@ // $Id$ // // Function: Top level SWERV core file -// Comments: +// Comments: // //******************************************************************************** @@ -28,7 +28,7 @@ module dma_ctrl ( input logic dma_bus_clk_en, // slave bus clock enable input logic clk_override, - // AXI signals + // AXI signals // AXI Write Channels input logic dma_axi_awvalid, output logic dma_axi_awready, @@ -39,12 +39,12 @@ module dma_ctrl ( input logic [7:0] dma_axi_awlen, input logic [1:0] dma_axi_awburst, - input logic dma_axi_wvalid, + 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, @@ -54,7 +54,7 @@ module dma_ctrl ( input logic dma_axi_arvalid, output logic dma_axi_arready, input logic [`RV_DMA_BUS_TAG-1:0] dma_axi_arid, - input logic [31:0] dma_axi_araddr, + 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, @@ -67,13 +67,13 @@ module dma_ctrl ( output logic [1:0] dma_axi_rresp, output logic dma_axi_rlast, - output logic dma_slv_algn_err, + output logic dma_slv_algn_err, // 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_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_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 @@ -82,7 +82,7 @@ module dma_ctrl ( 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 @@ -104,16 +104,16 @@ module dma_ctrl ( input logic iccm_ready, // iccm ready to accept DMA request input logic dec_tlu_stall_dma, // stall dma accesses, tlu is attempting to enter halt/debug mode input logic [2:0] dec_tlu_dma_qos_prty, // DMA QoS priority coming from MFDC [18:15] - - input logic scan_mode + + input logic scan_mode ); `include "global.h" - + localparam DEPTH = 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_dccm_valid; @@ -132,7 +132,7 @@ module dma_ctrl ( logic [DEPTH-1:0] fifo_dbg; logic [DEPTH-1:0][63:0] fifo_data; logic [DEPTH-1:0][DMA_BUS_TAG-1:0] fifo_tag; - + logic [DEPTH-1:0] fifo_cmd_en; logic [DEPTH-1:0] fifo_valid_en; logic [DEPTH-1:0] fifo_data_en; @@ -152,7 +152,7 @@ module dma_ctrl ( logic fifo_dbg_in; logic [31:0] fifo_addr_in; logic [2:0] fifo_sz_in; - + logic [DEPTH_PTR-1:0] RspPtr, PrevRspPtr, NxtRspPtr; logic [DEPTH_PTR-1:0] WrPtr, NxtWrPtr; logic [DEPTH_PTR-1:0] RdPtr, NxtRdPtr; @@ -164,7 +164,7 @@ module dma_ctrl ( logic fifo_full, fifo_full_spec, fifo_empty; logic dma_address_error, dma_alignment_error; - logic [3:0] num_fifo_vld; + logic [3:0] num_fifo_vld; logic dma_mem_req; logic dma_addr_in_dccm; logic dma_addr_in_iccm; @@ -172,7 +172,7 @@ module dma_ctrl ( logic dma_addr_in_pic_region_nc; logic dma_addr_in_dccm_region_nc; logic dma_addr_in_iccm_region_nc; - + logic [2:0] dma_nack_count_csr; logic [2:0] dma_nack_count, dma_nack_count_d; @@ -181,7 +181,7 @@ module dma_ctrl ( logic dma_buffer_c1_clk; logic dma_free_clk; logic dma_bus_clk; - + logic wrbuf_en, wrbuf_data_en; logic wrbuf_cmd_sent, wrbuf_rst, wrbuf_data_rst; @@ -193,7 +193,7 @@ module dma_ctrl ( 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; @@ -210,7 +210,7 @@ module dma_ctrl ( logic [2:0] axi_mstr_size; logic [63:0] axi_mstr_wdata; logic [7:0] axi_mstr_wstrb; - + logic axi_mstr_prty_in, axi_mstr_prty_en; logic axi_mstr_priority; logic axi_mstr_sel; @@ -222,7 +222,7 @@ module dma_ctrl ( logic [DMA_BUS_TAG-1:0] axi_slv_tag; logic [1:0] axi_slv_error; logic [63:0] axi_slv_rdata; - + logic dma_bus_clk_en_q; logic fifo_full_spec_bus; logic dbg_dma_bubble_bus; @@ -238,14 +238,14 @@ module dma_ctrl ( assign fifo_posted_write_in = axi_mstr_valid & axi_mstr_posted_write; assign fifo_dbg_in = dbg_cmd_valid; //assign fifo_error_in[1:0] = dccm_dma_rvalid ? {1'b0,dccm_dma_ecc_error} : iccm_dma_rvalid ? {1'b0,iccm_dma_ecc_error} : {(dma_address_error | dma_alignment_error | dma_dbg_cmd_error_in), dma_alignment_error}; - //assign fifo_data_in[63:0] = dccm_dma_rvalid ? dccm_dma_rdata[63:0] : (iccm_dma_rvalid ? iccm_dma_rdata[63:0] : + //assign fifo_data_in[63:0] = dccm_dma_rvalid ? dccm_dma_rdata[63:0] : (iccm_dma_rvalid ? iccm_dma_rdata[63:0] : // (dbg_cmd_valid ? {2{dbg_cmd_wrdata[31:0]}} : axi_mstr_wdata[63:0])); for (genvar i=0 ;i= dma_nack_count_csr); assign dma_iccm_stall_any = dma_mem_req & fifo_iccm_valid[RdPtr] & (dma_nack_count >= dma_nack_count_csr); // Used to indicate ready to debug assign fifo_empty = ~(|(fifo_valid_en[DEPTH-1:0] | fifo_valid[DEPTH-1:0]) | axi_mstr_valid | axi_slv_sent_q); // We want RspPtr to settle before accepting debug command - + // 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]) : + 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 @@ -372,7 +372,7 @@ module dma_ctrl ( .in_range(dma_addr_in_dccm), .in_region(dma_addr_in_dccm_region_nc) ); - + // Address check iccm `ifdef RV_ICCM_ENABLE rvrangecheck #(.CCM_SADR(`RV_ICCM_SADR), @@ -385,7 +385,7 @@ module dma_ctrl ( assign dma_addr_in_iccm = '0; assign dma_addr_in_iccm_region_nc = '0; `endif - + // PIC memory address check rvrangecheck #(.CCM_SADR(`RV_PIC_BASE_ADDR), .CCM_SIZE(`RV_PIC_SIZE)) addr_pic_rangecheck ( @@ -408,14 +408,14 @@ module dma_ctrl ( 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), .*); rvclkhdr dma_bus_cgc (.en(dma_bus_clk_en), .l1clk(dma_bus_clk), .*); - + // 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 = axi_mstr_valid & axi_mstr_write; assign wrbuf_rst = wrbuf_cmd_sent & ~wrbuf_en; assign wrbuf_data_rst = wrbuf_cmd_sent & ~wrbuf_data_en; - + rvdffsc #(.WIDTH(1)) wrbuf_vldff(.din(1'b1), .dout(wrbuf_vld), .en(wrbuf_en), .clear(wrbuf_rst), .clk(dma_bus_clk), .*); rvdffsc #(.WIDTH(1)) wrbuf_data_vldff(.din(1'b1), .dout(wrbuf_data_vld), .en(wrbuf_data_en), .clear(wrbuf_data_rst), .clk(dma_bus_clk), .*); rvdffs #(.WIDTH(1)) wrbuf_postedff(.din(1'b0), .dout(wrbuf_posted), .en(wrbuf_en), .clk(dma_bus_clk), .*); @@ -428,16 +428,16 @@ module dma_ctrl ( assign rdbuf_en = dma_axi_arvalid & dma_axi_arready; assign rdbuf_cmd_sent = axi_mstr_valid & ~axi_mstr_write & dma_fifo_ready; assign rdbuf_rst = rdbuf_cmd_sent & ~rdbuf_en; - + rvdffsc #(.WIDTH(1)) rdbuf_vldff(.din(1'b1), .dout(rdbuf_vld), .en(rdbuf_en), .clear(rdbuf_rst), .clk(dma_bus_clk), .*); rvdffs #(.WIDTH(DMA_BUS_TAG)) rdbuf_tagff(.din(dma_axi_arid[DMA_BUS_TAG-1:0]), .dout(rdbuf_tag[DMA_BUS_TAG-1:0]), .en(rdbuf_en), .clk(dma_bus_clk), .*); rvdffs #(.WIDTH(3)) rdbuf_sizeff(.din(dma_axi_arsize[2:0]), .dout(rdbuf_size[2:0]), .en(rdbuf_en), .clk(dma_bus_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); - + assign dma_axi_arready = ~(rdbuf_vld & ~rdbuf_cmd_sent); + //Generate a single request from read/write channel assign axi_mstr_valid = ((wrbuf_vld & wrbuf_data_vld) | rdbuf_vld) & dma_fifo_ready; assign axi_mstr_tag[DMA_BUS_TAG-1:0] = axi_mstr_sel ? wrbuf_tag[DMA_BUS_TAG-1:0] : rdbuf_tag[DMA_BUS_TAG-1:0]; @@ -446,7 +446,7 @@ module dma_ctrl ( assign axi_mstr_addr[31:0] = axi_mstr_sel ? wrbuf_addr[31:0] : rdbuf_addr[31:0]; assign axi_mstr_size[2:0] = axi_mstr_sel ? wrbuf_size[2:0] : rdbuf_size[2:0]; assign axi_mstr_wdata[63:0] = wrbuf_data[63:0]; - assign axi_mstr_wstrb[7:0] = wrbuf_byteen[7:0]; + assign axi_mstr_wstrb[7:0] = wrbuf_byteen[7: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); @@ -457,33 +457,33 @@ module dma_ctrl ( rvdff #(.WIDTH(1)) axi_mstr_validff (.din(axi_mstr_valid), .dout(axi_mstr_valid_q), .clk(dma_bus_clk), .*); rvdff #(.WIDTH(1)) axi_slv_sentff (.din(axi_slv_sent), .dout(axi_slv_sent_q), .clk(dma_bus_clk), .*); - //assign axi_slv_valid = fifo_valid[RspPtr] & ~fifo_rsp_done[RspPtr] & ~fifo_dbg[RspPtr] & + //assign axi_slv_valid = fifo_valid[RspPtr] & ~fifo_rsp_done[RspPtr] & ~fifo_dbg[RspPtr] & // ((fifo_write[RspPtr] & fifo_done_bus[RspPtr]) | (~fifo_write[RspPtr] & fifo_data_bus_valid[RspPtr]) | fifo_error_bus[RspPtr]); assign axi_slv_valid = fifo_valid[RspPtr] & ~fifo_dbg[RspPtr] & fifo_done_bus[RspPtr]; - assign axi_slv_tag[DMA_BUS_TAG-1:0] = fifo_tag[RspPtr]; + assign axi_slv_tag[DMA_BUS_TAG-1:0] = fifo_tag[RspPtr]; //assign axi_slv_rdata[63:0] = (|fifo_error[RspPtr]) ? {32'b0,fifo_addr[RspPtr]} : fifo_data[RspPtr]; assign axi_slv_rdata[63:0] = fifo_data[RspPtr]; assign axi_slv_write = fifo_write[RspPtr]; assign axi_slv_posted_write = axi_slv_write & fifo_posted_write[RspPtr]; assign axi_slv_error[1:0] = fifo_error[RspPtr][0] ? 2'b10 : (fifo_error[RspPtr][1] ? 2'b11 : 2'b0); - - + + // AXI response channel signals assign dma_axi_bvalid = axi_slv_valid & axi_slv_write; assign dma_axi_bresp[1:0] = axi_slv_error[1:0]; assign dma_axi_bid[DMA_BUS_TAG-1:0] = axi_slv_tag[DMA_BUS_TAG-1:0]; - + assign dma_axi_rvalid = axi_slv_valid & ~axi_slv_write; - assign dma_axi_rresp[1:0] = axi_slv_error; + assign dma_axi_rresp[1:0] = axi_slv_error; assign dma_axi_rid[DMA_BUS_TAG-1:0] = axi_slv_tag[DMA_BUS_TAG-1:0]; assign dma_axi_rdata[63:0] = axi_slv_rdata[63:0]; assign dma_axi_rlast = 1'b1; - + assign axi_slv_sent = (dma_axi_bvalid & dma_axi_bready) | (dma_axi_rvalid & dma_axi_rready); assign dma_slv_algn_err = fifo_error[RspPtr][1]; `ifdef ASSERT_ON - //assert_nack_count: assert #0 (dma_nack_count[2:0] < 3'h4); + //assert_nack_count: assert #0 (dma_nack_count[2:0] < 3'h4); for (genvar i=0; i ((dma_axi_arsize[2:0] == 3'h0) | @@ -507,37 +507,37 @@ module dma_ctrl ( ((dma_axi_arsize[2:0] == 3'h2) & (dma_axi_araddr[1:0] == 2'b0)) | ((dma_axi_arsize[2:0] == 3'h3) & (dma_axi_araddr[2:0] == 3'b0))); endproperty - // assert_dma_read_trxn_aligned: assert property (dma_axi_read_trxn_aligned) else + // assert_dma_read_trxn_aligned: assert property (dma_axi_read_trxn_aligned) else // $display("Assertion dma_axi_read_trxn_aligned failed: dma_axi_arvalid=1'b%b, dma_axi_arsize=3'h%h, dma_axi_araddr=32'h%h",dma_axi_arvalid, dma_axi_arsize[2:0], dma_axi_araddr[31:0]); - + // Assertion to check write size is 8 byte or less property dma_axi_awsize_check; @(posedge dma_bus_clk) disable iff(~rst_l) (dma_axi_awvalid & dma_axi_awready) |-> (dma_axi_awsize[2] == 1'b0); endproperty assert_dma_axi_awsize_check: assert property (dma_axi_awsize_check) else $display("DMA AXI awsize is illegal. Size greater than 8B not supported"); - + // Assertion to check there are no burst commands property dma_axi_awlen_check; @(posedge dma_bus_clk) disable iff(~rst_l) (dma_axi_awvalid & dma_axi_awready) |-> (dma_axi_awlen[7:0] == 8'b0); endproperty assert_dma_axi_awlen_check: assert property (dma_axi_awlen_check) else $display("DMA AXI awlen is illegal. Length greater than 0 not supported"); - + // Assertion to check write size is 8 byte or less property dma_axi_arsize_check; @(posedge dma_bus_clk) disable iff(~rst_l) (dma_axi_arvalid & dma_axi_arready) |-> (dma_axi_arsize[2] == 1'b0); endproperty assert_dma_axi_arsize_check: assert property (dma_axi_arsize_check) else $display("DMA AXI arsize is illegal, Size bigger than 8B not supported"); - + // Assertion to check there are no burst commands property dma_axi_arlen_check; @(posedge dma_bus_clk) disable iff(~rst_l) (dma_axi_arvalid & dma_axi_arready) |-> (dma_axi_arlen[7:0] == 8'b0); endproperty assert_dma_axi_arlen_check: assert property (dma_axi_arlen_check) else $display("DMA AXI arlen greater than 0 not supported."); - + // Assertion to check cmd valid stays stable during entire bus clock property dma_axi_awvalid_stable; @(posedge clk) disable iff(~rst_l) (dma_axi_awvalid != $past(dma_axi_awvalid)) |-> $past(dma_bus_clk_en); @@ -692,6 +692,6 @@ module dma_ctrl ( assert_dma_axi_rid_stable: assert property (dma_axi_rid_stable) else $display("DMA AXI bid changed in middle of bus clock"); -`endif - +`endif + endmodule // dma_ctrl diff --git a/design/dmi/dmi_jtag_to_core_sync.v b/design/dmi/dmi_jtag_to_core_sync.v index c382cd6..aa4c19f 100644 --- a/design/dmi/dmi_jtag_to_core_sync.v +++ b/design/dmi/dmi_jtag_to_core_sync.v @@ -48,8 +48,8 @@ module dmi_jtag_to_core_sync ( // synchronizers always @ ( posedge clk or negedge rst_n) begin if(!rst_n) begin - rden <= 3'b0; - wren <= 3'b0; + rden <= '0; + wren <= '0; end else begin rden <= {rden[1:0], rd_en}; diff --git a/design/dmi/rvjtag_tap.sv b/design/dmi/rvjtag_tap.sv index 43c6e02..fce8f31 100644 --- a/design/dmi/rvjtag_tap.sv +++ b/design/dmi/rvjtag_tap.sv @@ -1,12 +1,12 @@ // 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. @@ -46,7 +46,7 @@ input [1:0] dmi_stat, input [31:1] jtag_id, input [3:0] version ); - + localparam USER_DR_LENGTH = AWIDTH + 34; @@ -57,13 +57,13 @@ reg [USER_DR_LENGTH-1:0] sr, nsr, dr; /////////////////////////////////////////////////////// logic[3:0] state, nstate; logic [4:0] ir; -wire jtag_reset; -wire shift_dr; -wire pause_dr; -wire update_dr; +wire jtag_reset; +wire shift_dr; +wire pause_dr; +wire update_dr; wire capture_dr; -wire shift_ir; -wire pause_ir ; +wire shift_ir; +wire pause_ir ; wire update_ir ; wire capture_ir; wire[1:0] dr_en; @@ -94,7 +94,7 @@ 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; + 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; @@ -146,7 +146,7 @@ end assign devid_sel = ir == 5'b00001; assign dr_en[0] = ir == 5'b10000; assign dr_en[1] = ir == 5'b10001; - + /////////////////////////////////////////////////////// // Shift register /////////////////////////////////////////////////////// @@ -192,11 +192,11 @@ always @ (posedge tck or negedge trst) begin if(!trst) begin dmi_hard_reset <= 1'b0; dmi_reset <= 1'b0; - end + end else if (update_dr & dr_en[0]) begin dmi_hard_reset <= sr[17]; dmi_reset <= sr[16]; - end + end else begin dmi_hard_reset <= 1'b0; dmi_reset <= 1'b0; diff --git a/design/exu/exu.sv b/design/exu/exu.sv index 20dfd2f..08b5dc3 100644 --- a/design/exu/exu.sv +++ b/design/exu/exu.sv @@ -176,7 +176,7 @@ module exu output logic [`RV_BHT_GHR_RANGE] exu_i0_br_fghr_e4, // to DEC I0 branch fghr output logic exu_i0_br_ret_e4, // to DEC I0 branch return output logic exu_i0_br_call_e4, // to DEC I0 branch call - + output logic [1:0] exu_i1_br_hist_e4, // to DEC I1 branch history output logic [1:0] exu_i1_br_bank_e4, // to DEC I1 branch bank output logic exu_i1_br_error_e4, // to DEC I1 branch error @@ -292,7 +292,7 @@ module exu ({32{ dec_i1_rs1_bypass_en_d}} & i1_rs1_bypass_data_d[31:0]); assign i1_rs2_d[31:0] = ({32{~dec_i1_rs2_bypass_en_d}} & gpr_i1_rs2_d[31:0]) | - ({32{~dec_i1_rs2_bypass_en_d}} & dec_i1_immed_d[31:0]) | + ({32{~dec_i1_rs2_bypass_en_d}} & dec_i1_immed_d[31:0]) | ({32{ dec_i1_rs2_bypass_en_d}} & i1_rs2_bypass_data_d[31:0]); assign exu_lsu_rs1_d[31:0] = ({32{ ~dec_i0_rs1_bypass_en_d & dec_i0_lsu_d }} & gpr_i0_rs1_d[31:0] ) | @@ -477,7 +477,7 @@ module exu .dout({i0_rs1_e1[31:0], i0_rs2_e1[31:0], i0_br_immed_e1[12:1]}) ); - rvdffe #(76) i0_src_e2_ff (.*, + rvdffe #(76) i0_src_e2_ff (.*, .en(i0_e2_data_en), .din( {i0_rs1_e1[31:0], i0_rs2_e1[31:0], i0_br_immed_e1[12:1]}), .dout({i0_rs1_e2[31:0], i0_rs2_e2[31:0], i0_br_immed_e2[12:1]}) @@ -538,7 +538,7 @@ module exu assign i1_taken_e1= (i1_ataken_e1 & dec_i1_alu_decode_e1) | (i1_predict_p_e1.hist[1] & ~dec_i1_alu_decode_e1); assign ghr_e1_ns[`RV_BHT_GHR_RANGE] = ( ({`RV_BHT_GHR_SIZE{~dec_tlu_flush_lower_wb & i0_valid_e1 & (i0_predict_p_e1.misp | ~i1_valid_e1)}} & {ghr_e1[`RV_BHT_GHR_SIZE-2:0], i0_taken_e1}) | -`ifdef RV_BHT_GHR_SIZE_2 +`ifdef RV_BHT_GHR_SIZE_2 ({`RV_BHT_GHR_SIZE{~dec_tlu_flush_lower_wb & i0_valid_e1 & ~i0_predict_p_e1.misp & i1_valid_e1}} & { i0_taken_e1, i1_taken_e1}) | `else ({`RV_BHT_GHR_SIZE{~dec_tlu_flush_lower_wb & i0_valid_e1 & ~i0_predict_p_e1.misp & i1_valid_e1}} & {ghr_e1[`RV_BHT_GHR_SIZE-3:0], i0_taken_e1, i1_taken_e1}) | @@ -556,7 +556,7 @@ module exu assign i0_valid_e4 = dec_tlu_i0_valid_e4 & ((i0_predict_p_e4.valid) | i0_predict_p_e4.misp); assign i1_pred_valid_e4 = dec_tlu_i1_valid_e4 & ((i1_predict_p_e4.valid) | i1_predict_p_e4.misp) & ~exu_i0_flush_upper_e4; assign ghr_e4_ns[`RV_BHT_GHR_RANGE] = ( ({`RV_BHT_GHR_SIZE{i0_valid_e4 & (i0_predict_p_e4.misp | ~i1_pred_valid_e4)}} & {ghr_e4[`RV_BHT_GHR_SIZE-2:0], i0_predict_p_e4.ataken}) | -`ifdef RV_BHT_GHR_SIZE_2 +`ifdef RV_BHT_GHR_SIZE_2 ({`RV_BHT_GHR_SIZE{i0_valid_e4 & ~i0_predict_p_e4.misp & i1_pred_valid_e4}} & { i0_predict_p_e4.ataken, i1_predict_p_e4.ataken}) | `else ({`RV_BHT_GHR_SIZE{i0_valid_e4 & ~i0_predict_p_e4.misp & i1_pred_valid_e4}} & {ghr_e4[`RV_BHT_GHR_SIZE-3:0], i0_predict_p_e4.ataken, i1_predict_p_e4.ataken}) | @@ -715,7 +715,7 @@ module exu .din({ exu_i0_flush_path_e1[31:1], exu_i0_flush_upper_e1}), - + .dout({ i0_flush_path_upper_e2[31:1], exu_i0_flush_upper_e2}) diff --git a/design/exu/exu_alu_ctl.sv b/design/exu/exu_alu_ctl.sv index 3ca0d70..ee3ba4e 100644 --- a/design/exu/exu_alu_ctl.sv +++ b/design/exu/exu_alu_ctl.sv @@ -192,7 +192,7 @@ module exu_alu_ctl // branch handling logic any_jal; - + assign any_jal = ap.jal | pp_ff.pcall | pp_ff.pja | @@ -217,7 +217,7 @@ module exu_alu_ctl // 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 = ((ap.predict_nt & ~actual_taken) | (ap.predict_t & actual_taken)) & ~any_jal; @@ -242,7 +242,7 @@ module exu_alu_ctl // .ilb hist[1] hist[0] taken // .ob newhist[1] newhist[0] // .type fd - // + // // 00 0 01 // 01 0 01 // 10 0 00 diff --git a/design/exu/exu_mul_ctl.sv b/design/exu/exu_mul_ctl.sv index a5e0bb1..d6e74a1 100644 --- a/design/exu/exu_mul_ctl.sv +++ b/design/exu/exu_mul_ctl.sv @@ -59,7 +59,7 @@ module exu_mul_ctl assign mul_c1_e2_clken = (valid_e1 | clk_override) & ~freeze; assign mul_c1_e3_clken = (valid_e2 | clk_override) & ~freeze; - // C1 - 1 clock pulse for data + // C1 - 1 clock pulse for data rvclkhdr exu_mul_c1e1_cgc (.*, .en(mul_c1_e1_clken), .l1clk(exu_mul_c1_e1_clk)); rvclkhdr exu_mul_c1e2_cgc (.*, .en(mul_c1_e2_clken), .l1clk(exu_mul_c1_e2_clk)); rvclkhdr exu_mul_c1e3_cgc (.*, .en(mul_c1_e3_clken), .l1clk(exu_mul_c1_e3_clk)); diff --git a/design/ifu/ifu.sv b/design/ifu/ifu.sv index 14c5faa..d978439 100644 --- a/design/ifu/ifu.sv +++ b/design/ifu/ifu.sv @@ -30,9 +30,9 @@ module ifu input logic dec_ib3_valid_d, dec_ib2_valid_d, // mass balance for decode buffer - input logic dec_ib0_valid_eff_d, // effective valid taking decode into account - input logic dec_ib1_valid_eff_d, // effective valid taking decode into account - + input logic dec_ib0_valid_eff_d, // effective valid taking decode into account + input logic dec_ib1_valid_eff_d, // effective valid taking decode into account + input logic exu_i0_br_ret_e4, // i0 branch commit is a ret input logic exu_i1_br_ret_e4, // i1 branch commit is a ret input logic exu_i0_br_call_e4, // i0 branch commit is a call @@ -49,8 +49,8 @@ module ifu 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_bpred_disable, // disable all branch prediction input logic dec_tlu_core_ecc_disable, // disable ecc checking and flagging // AXI Write Channels - IFU never writes. So, 0 out mostly @@ -66,19 +66,19 @@ module ifu 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 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 [`RV_IFU_BUS_TAG-1:0] ifu_axi_bid, - - // AXI Read Channels + + // AXI Read Channels output logic ifu_axi_arvalid, input logic ifu_axi_arready, output logic [`RV_IFU_BUS_TAG-1:0] ifu_axi_arid, @@ -91,7 +91,7 @@ module ifu output logic [3:0] ifu_axi_arcache, output logic [2:0] ifu_axi_arprot, output logic [3:0] ifu_axi_arqos, - + input logic ifu_axi_rvalid, output logic ifu_axi_rready, input logic [`RV_IFU_BUS_TAG-1:0] ifu_axi_rid, @@ -100,101 +100,101 @@ module ifu input logic ifu_axi_rlast, //// AHB LITE BUS -//`ifdef RV_BUILD_AHB_LITE +//`ifdef RV_BUILD_AHB_LITE input logic ifu_bus_clk_en, - input logic dma_iccm_req, - input logic dma_iccm_stall_any, + input logic dma_iccm_req, + input logic dma_iccm_stall_any, 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, - - output logic iccm_dma_ecc_error, - output logic iccm_dma_rvalid, + + output logic iccm_dma_ecc_error, + output logic iccm_dma_rvalid, output logic [63:0] iccm_dma_rdata, output logic iccm_ready, -//`endif +//`endif output logic [1:0] ifu_pmu_instr_aligned, output logic ifu_pmu_align_stall, output logic ifu_pmu_fetch_stall, - -// I$ & ITAG Ports - output logic [31:3] ic_rw_addr, // Read/Write addresss to the Icache. + +// I$ & ITAG Ports + output logic [31:3] ic_rw_addr, // Read/Write addresss to the Icache. output logic [3:0] ic_wr_en, // Icache write enable, when filling the Icache. output logic ic_rd_en, // Icache read enable. `ifdef RV_ICACHE_ECC output logic [83:0] ic_wr_data, // Data to fill to the Icache. With ECC input logic [167:0] ic_rd_data , // Data read from Icache. 2x64bits + parity bits. F2 stage. With ECC - input logic [24:0] ictag_debug_rd_data,// Debug icache tag. - output logic [41:0] ic_debug_wr_data, // Debug wr cache. + input logic [24:0] ictag_debug_rd_data,// Debug icache tag. + output logic [41:0] ic_debug_wr_data, // Debug wr cache. output logic [41:0] ifu_ic_debug_rd_data, -`else +`else output logic [67:0] ic_wr_data, // Data to fill to the Icache. With Parity input logic [135:0] ic_rd_data , // Data read from Icache. 2x64bits + parity bits. F2 stage. With Parity - input logic [20:0] ictag_debug_rd_data,// Debug icache tag. - output logic [33:0] ic_debug_wr_data, // Debug wr cache. + input logic [20:0] ictag_debug_rd_data,// Debug icache tag. + output logic [33:0] ic_debug_wr_data, // Debug wr cache. output logic [33:0] ifu_ic_debug_rd_data, `endif - output logic [127:0] ic_premux_data, // Premux data to be muxed with each way of the Icache. + output logic [127: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 [15:2] ic_debug_addr, // Read/Write addresss to the Icache. + output logic [15:2] 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 [3:0] ic_debug_way, // Debug way. Rd or Wr. - output logic [3:0] ic_tag_valid, // Valid bits when accessing the Icache. One valid bit per way. F2 stage - - input logic [3:0] ic_rd_hit, // Compare hits from Icache tags. Per way. F2 stage + output logic [3:0] ic_tag_valid, // Valid bits when accessing the Icache. One valid bit per way. F2 stage + + input logic [3:0] ic_rd_hit, // Compare hits from Icache tags. Per way. F2 stage input logic ic_tag_perr, // Icache Tag parity error `ifdef RV_ICCM_ENABLE - // ICCM ports + // ICCM ports output logic [`RV_ICCM_BITS-1:2] 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. - + output logic [2:0] iccm_wr_size, // ICCM write location within DW. + input logic [155:0] iccm_rd_data, // Data read from ICCM. `endif // Perf counter sigs output logic ifu_pmu_ic_miss, // ic miss - output logic ifu_pmu_ic_hit, // ic hit + 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_valid, // Instruction 0 valid. From Aligner to Decode - output logic ifu_i1_valid, // Instruction 1 valid. From Aligner to Decode + output logic ifu_i0_valid, // Instruction 0 valid. From Aligner to Decode + output logic ifu_i1_valid, // Instruction 1 valid. From Aligner to Decode output logic ifu_i0_icaf, // Instruction 0 access fault. From Aligner to Decode - output logic ifu_i1_icaf, // Instruction 1 access fault. From Aligner to Decode + output logic ifu_i1_icaf, // Instruction 1 access fault. From Aligner to Decode output logic ifu_i0_icaf_f1, // Instruction 0 has access fault on second fetch group output logic ifu_i1_icaf_f1, // Instruction 1 has access fault on second fetch group output logic ifu_i0_perr, // Instruction 0 parity error. From Aligner to Decode - output logic ifu_i1_perr, // Instruction 1 parity error. From Aligner to Decode + output logic ifu_i1_perr, // Instruction 1 parity error. From Aligner to Decode output logic ifu_i0_sbecc, // Instruction 0 has single bit ecc error output logic ifu_i1_sbecc, // Instruction 1 has single bit ecc error output logic ifu_i0_dbecc, // Instruction 0 has double bit ecc error output logic ifu_i1_dbecc, // Instruction 1 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:0] ifu_i1_instr, // Instruction 1 . From Aligner to Decode - output logic[31:1] ifu_i0_pc, // Instruction 0 pc. From Aligner to Decode + output logic[31:0] ifu_i1_instr, // Instruction 1 . From Aligner to Decode + output logic[31:1] ifu_i0_pc, // Instruction 0 pc. From Aligner to Decode output logic[31:1] ifu_i1_pc, // Instruction 1 pc. From Aligner to Decode output logic ifu_i0_pc4, // Instruction 0 is 4 byte. From Aligner to Decode - output logic ifu_i1_pc4, // Instruction 1 is 4 byte. From Aligner to Decode + output logic ifu_i1_pc4, // Instruction 1 is 4 byte. From Aligner to Decode output logic [15:0] ifu_illegal_inst, // Illegal instruction. output logic ifu_miss_state_idle, // There is no outstanding miss. Cache miss state is idle. @@ -209,7 +209,7 @@ module ifu input br_tlu_pkt_t dec_tlu_br0_wb_pkt, // slot0 update/error pkt input br_tlu_pkt_t dec_tlu_br1_wb_pkt, // slot1 update/error pkt input dec_tlu_flush_lower_wb, - + input rets_pkt_t exu_rets_e1_pkt, // E1 return stack packet input rets_pkt_t exu_rets_e4_pkt, // E4 return stack packet @@ -225,13 +225,13 @@ module ifu output logic [15:0] ifu_i1_cinst, -/// Icache debug +/// Icache debug input cache_debug_pkt_t dec_tlu_ic_diag_pkt , output logic ifu_ic_debug_rd_data_valid, - - input logic scan_mode + + input logic scan_mode ); localparam TAGWIDTH = 2 ; @@ -245,7 +245,7 @@ module ifu logic [31:1] ifu_fetch_pc; // starting pc of fetch logic [31:1] ifc_fetch_addr_f1; - + logic ic_crit_wd_rdy; logic ic_write_stall; logic ic_dma_active; @@ -255,9 +255,9 @@ module ifu logic ic_access_fault_f2; logic ifu_ic_mb_empty; - + logic ic_hit_f2; - + // fetch control ifu_ifc_ctl ifc (.* ); @@ -278,42 +278,42 @@ module ifu logic [7:0] ifu_bp_pc4_f2; // pc4 indication; right justified logic [7:0] ifu_bp_valid_f2; // branch valid, right justified logic [`RV_BHT_GHR_RANGE] ifu_bp_fghr_f2; - + // branch predictor ifu_bp_ctl bp (.*); - + logic [7:0] ic_fetch_val_f2; logic [127:0] ic_data_f2; logic [127:0] ifu_fetch_data; logic ifc_fetch_req_f1_raw, ifc_fetch_req_f1, ifc_fetch_req_f2; - logic ic_rd_parity_final_err; // This fetch has a data_cache or tag parity error. - logic iccm_rd_ecc_single_err; // This fetch has an iccm single error. + logic ic_rd_parity_final_err; // This fetch has a data_cache or tag parity error. + logic iccm_rd_ecc_single_err; // This fetch has an iccm single error. logic iccm_rd_ecc_double_err; // This fetch has an iccm double error. icache_err_pkt_t ic_error_f2; - + logic ifu_icache_fetch_f2 ; logic [16:2] ifu_icache_error_index; // Index with parity error - logic ifu_icache_error_val; // Parity error + logic ifu_icache_error_val; // Parity error logic ifu_icache_sb_error_val; assign ifu_fetch_data[127:0] = ic_data_f2[127:0]; assign ifu_fetch_val[7:0] = ic_fetch_val_f2[7:0]; assign ifu_fetch_pc[31:1] = ifc_fetch_addr_f2[31:1]; - + // aligner ifu_aln_ctl aln (.*); // icache - ifu_mem_ctl mem_ctl + ifu_mem_ctl mem_ctl (.*, .fetch_addr_f1(ifc_fetch_addr_f1), - .ifu_icache_error_index(ifu_icache_error_index[16:6]), + .ifu_icache_error_index(ifu_icache_error_index[16:6]), .ic_hit_f2(ic_hit_f2), .ic_data_f2(ic_data_f2[127:0]) ); - + // Performance debug info @@ -371,26 +371,26 @@ assign tmp_bnk[2:0] = encode8_3(bp.btb_sel_f2[7:0]); `endif $display("RS_CONFIG: %d", `RV_RET_STACK_SIZE); end - if(exu_flush_final & ~(dec_tlu_br0_wb_pkt.br_error | dec_tlu_br0_wb_pkt.br_start_error | dec_tlu_br1_wb_pkt.br_error | dec_tlu_br1_wb_pkt.br_start_error) & (exu_mp_pkt.misp | exu_mp_pkt.ataken)) + if(exu_flush_final & ~(dec_tlu_br0_wb_pkt.br_error | dec_tlu_br0_wb_pkt.br_start_error | dec_tlu_br1_wb_pkt.br_error | dec_tlu_br1_wb_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[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO], exu_mp_bank[1:0], exu_mp_call, exu_mp_ret, exu_mp_ataken, exu_mp_hist[1:0], exu_mp_valid, exu_mp_pkt.btag[`RV_BTB_BTAG_SIZE-1:0], {exu_flush_path_final[31:1], 1'b0}, exu_mp_eghr[`RV_BHT_GHR_RANGE], exu_mp_valid, bp.bht_wr_addr0, mppc[31:0], exu_mp_pkt.way); for(int i = 0; i < 8; i++) begin - if(ifu_bp_valid_f2[i] & ifc_fetch_req_f2) + if(ifu_bp_valid_f2[i] & ifc_fetch_req_f2) $display("%7d BTB_HIT : index: %0h bank: %0h call: %b ret: %b taken: %b strength: %b tag: %h targ: %h ghr: %4b ghr_index: %h way: %h", `DEC.tlu.mcyclel[31:0]+32'ha,btb_rd_addr_f2[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO],encode8_3(bp.btb_sel_f2[7:0]), bp.btb_rd_call_f2, bp.btb_rd_ret_f2, ifu_bp_hist1_f2[tmp_bnk], ifu_bp_hist0_f2[tmp_bnk], bp.fetch_rd_tag_f2[`RV_BTB_BTAG_SIZE-1:0], {ifu_bp_btb_target_f2[31:1], 1'b0}, bp.fghr[`RV_BHT_GHR_RANGE], bp.bht_rd_addr_f1, ifu_bp_way_f2[tmp_bnk]); end `ifdef RV_BTB_48 for(int y = 0; y < 4; y++) begin for(int z = 0; z < 4; z++) begin if(bp.lru_bank_sel[y][z]) - $display("%7d BTB_LRU: index: %0h bank: %0h newlru %h", `DEC.tlu.mcyclel[31:0]+32'ha, z,y,bp.lru_bank_wr_data[y][z]); + $display("%7d BTB_LRU: index: %0h bank: %0h newlru %h", `DEC.tlu.mcyclel[31:0]+32'ha, z,y,bp.lru_bank_wr_data[y][z]); end end -`endif +`endif if(dec_tlu_br0_wb_pkt.valid & ~(dec_tlu_br0_wb_pkt.br_error | dec_tlu_br0_wb_pkt.br_start_error)) - $display("%7d BTB_UPD0: ghr_index: %0h bank: %0h hist: %h way: %h", `DEC.tlu.mcyclel[31:0]+32'ha,bp.br0_hashed_wb[`RV_BHT_ADDR_HI:`RV_BHT_ADDR_LO],{dec_tlu_br0_wb_pkt.bank[1:0],dec_tlu_br0_wb_pkt.middle}, dec_tlu_br0_wb_pkt.hist, dec_tlu_br0_wb_pkt.way); + $display("%7d BTB_UPD0: ghr_index: %0h bank: %0h hist: %h way: %h", `DEC.tlu.mcyclel[31:0]+32'ha,bp.br0_hashed_wb[`RV_BHT_ADDR_HI:`RV_BHT_ADDR_LO],{dec_tlu_br0_wb_pkt.bank[1:0],dec_tlu_br0_wb_pkt.middle}, dec_tlu_br0_wb_pkt.hist, dec_tlu_br0_wb_pkt.way); if(dec_tlu_br1_wb_pkt.valid & ~(dec_tlu_br1_wb_pkt.br_error | dec_tlu_br1_wb_pkt.br_start_error)) - $display("%7d BTB_UPD1: ghr_index: %0h bank: %0h hist: %h way: %h", `DEC.tlu.mcyclel[31:0]+32'ha,bp.br1_hashed_wb[`RV_BHT_ADDR_HI:`RV_BHT_ADDR_LO],{dec_tlu_br1_wb_pkt.bank[1:0],dec_tlu_br1_wb_pkt.middle}, dec_tlu_br1_wb_pkt.hist, dec_tlu_br1_wb_pkt.way); + $display("%7d BTB_UPD1: ghr_index: %0h bank: %0h hist: %h way: %h", `DEC.tlu.mcyclel[31:0]+32'ha,bp.br1_hashed_wb[`RV_BHT_ADDR_HI:`RV_BHT_ADDR_LO],{dec_tlu_br1_wb_pkt.bank[1:0],dec_tlu_br1_wb_pkt.middle}, dec_tlu_br1_wb_pkt.hist, dec_tlu_br1_wb_pkt.way); if(dec_tlu_br0_wb_pkt.br_error | dec_tlu_br0_wb_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,dec_tlu_br0_wb_pkt.index[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO],dec_tlu_br0_wb_pkt.bank[1:0], dec_tlu_br0_wb_pkt.br_start_error, {exu_flush_path_final[31:1], 1'b0}, dec_tlu_br0_wb_pkt.way); + $display("%7d BTB_ERR0: index: %0h bank: %0h start: %b rfpc: %h way: %h", `DEC.tlu.mcyclel[31:0]+32'ha,dec_tlu_br0_wb_pkt.index[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO],dec_tlu_br0_wb_pkt.bank[1:0], dec_tlu_br0_wb_pkt.br_start_error, {exu_flush_path_final[31:1], 1'b0}, dec_tlu_br0_wb_pkt.way); if(dec_tlu_br1_wb_pkt.br_error | dec_tlu_br1_wb_pkt.br_start_error) $display("%7d BTB_ERR1: index: %0h bank: %0h start: %b rfpc: %h way: %h", `DEC.tlu.mcyclel[31:0]+32'ha,dec_tlu_br1_wb_pkt.index[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO],dec_tlu_br1_wb_pkt.bank[1:0], dec_tlu_br1_wb_pkt.br_start_error, {exu_flush_path_final[31:1], 1'b0}, dec_tlu_br1_wb_pkt.way); end // always @ (negedge clk) @@ -401,6 +401,6 @@ assign tmp_bnk[2:0] = encode8_3(bp.btb_sel_f2[7:0]); encode8_3[1] = in[7] | in[6] | in[3] | in[2]; encode8_3[0] = in[7] | in[5] | in[3] | in[1]; - endfunction + endfunction `endif endmodule // ifu diff --git a/design/ifu/ifu_aln_ctl.sv b/design/ifu/ifu_aln_ctl.sv index d34cac6..319d1bb 100644 --- a/design/ifu/ifu_aln_ctl.sv +++ b/design/ifu/ifu_aln_ctl.sv @@ -23,8 +23,8 @@ module ifu_aln_ctl ( input logic active_clk, - - input logic iccm_rd_ecc_single_err, // This fetch has a single ICCM ecc error. + + input logic iccm_rd_ecc_single_err, // This fetch has a single ICCM ecc error. input logic iccm_rd_ecc_double_err, // This fetch has a double ICCM ecc error. input logic ic_rd_parity_final_err, // for tag parity errors @@ -35,7 +35,7 @@ module ifu_aln_ctl input logic [31:1] ifu_bp_btb_target_f2, // predicted RET target input logic [11:0] ifu_bp_poffset_f2, // predicted target offset - input logic [7:0] ifu_bp_hist0_f2, // history counters for all 4 potential branches, bit 1, right justified + input logic [7:0] ifu_bp_hist0_f2, // history counters for all 4 potential branches, bit 1, right justified input logic [7:0] ifu_bp_hist1_f2, // history counters for all 4 potential branches, bit 1, right justified input logic [7:0] ifu_bp_pc4_f2, // pc4 indication, right justified `ifdef RV_BTB_48 @@ -47,30 +47,30 @@ module ifu_aln_ctl input logic [7:0] ifu_bp_ret_f2, // predicted ret indication, right justified input logic exu_flush_final, // Flush from the pipeline. - + input logic dec_ib3_valid_d, // valids for top 2 instruction buffers at decode input logic dec_ib2_valid_d, - input logic dec_ib0_valid_eff_d, // effective valid taking decode into account + input logic dec_ib0_valid_eff_d, // effective valid taking decode into account input logic dec_ib1_valid_eff_d, - - + + input logic [127:0] ifu_fetch_data, // fetch data in memory format - not right justified input icache_err_pkt_t ic_error_f2, // based on configuration: either parity or ecc - + input logic [7:0] ifu_fetch_val, // valids on a 2B boundary, right justified input logic [31:1] ifu_fetch_pc, // starting pc of fetch - + input logic rst_l, input logic clk, input logic dec_tlu_core_ecc_disable, // disable ecc checking and flagging - output logic ifu_i0_valid, // Instruction 0 is valid + output logic ifu_i0_valid, // Instruction 0 is valid output logic ifu_i1_valid, // Instruction 1 is valid - output logic ifu_i0_icaf, // Instruction 0 has access fault + output logic ifu_i0_icaf, // Instruction 0 has access fault output logic ifu_i1_icaf, // Instruction 1 has access fault output logic ifu_i0_icaf_f1, // Instruction 0 has access fault on second fetch group output logic ifu_i1_icaf_f1, // Instruction 1 has access fault on second fetch group @@ -80,14 +80,14 @@ module ifu_aln_ctl output logic ifu_i1_sbecc, // Instruction 1 has single bit ecc error output logic ifu_i0_dbecc, // Instruction 0 has double bit ecc error output logic ifu_i1_dbecc, // Instruction 1 has double bit ecc error - output logic [31:0] ifu_i0_instr, // Instruction 0 + output logic [31:0] ifu_i0_instr, // Instruction 0 output logic [31:0] ifu_i1_instr, // Instruction 1 - output logic [31:1] ifu_i0_pc, // Instruction 0 PC - output logic [31:1] ifu_i1_pc, // Instruction 1 PC + output logic [31:1] ifu_i0_pc, // Instruction 0 PC + output logic [31:1] ifu_i1_pc, // Instruction 1 PC output logic ifu_i0_pc4, - output logic ifu_i1_pc4, - - output logic ifu_fb_consume1, // Consumed one buffer. To fetch control fetch for buffer mass balance + output logic ifu_i1_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 output logic [15:0] ifu_illegal_inst, // Illegal Instruction. @@ -97,35 +97,35 @@ module ifu_aln_ctl output logic [1:0] ifu_pmu_instr_aligned, // number of inst aligned this cycle output logic ifu_pmu_align_stall, // aligner stalled this cycle - output logic [16:2] ifu_icache_error_index, // Icache Error address index + output logic [16:2] ifu_icache_error_index, // Icache Error address index output logic ifu_icache_error_val, // Icache error valid - output logic ifu_icache_sb_error_val, + output logic ifu_icache_sb_error_val, output logic [15:0] ifu_i0_cinst, // 16b compress inst for i0 output logic [15:0] ifu_i1_cinst, // 16b compress inst for i1 input logic scan_mode - - + + ); `include "global.h" - + logic ifvalid; logic shift_f1_f0, shift_f2_f0, shift_f2_f1; logic fetch_to_f0, fetch_to_f1, fetch_to_f2; logic [7:0] f2val_in, f2val; logic [7:0] f1val_in, f1val; - logic [7:0] f0val_in, f0val; - + logic [7:0] f0val_in, f0val; + logic [7:0] sf1val, sf0val; logic [31:1] f2pc_in, f2pc; logic [31:1] f1pc_in, f1pc; - logic [31:1] f0pc_in, f0pc; + logic [31:1] f0pc_in, f0pc; logic [31:1] sf1pc, sf0pc; - + logic [63:0] aligndata; logic first4B, first2B; logic second4B, second2B; @@ -138,45 +138,45 @@ module ifu_aln_ctl logic shift_2B, shift_4B, shift_6B, shift_8B; logic f1_shift_2B, f1_shift_4B, f1_shift_6B; logic f2_valid, sf1_valid, sf0_valid; - + logic [31:0] ifirst, isecond, ithird; logic [31:1] f0pc_plus1, f0pc_plus2, f0pc_plus3, f0pc_plus4; - logic [31:1] f1pc_plus1, f1pc_plus2, f1pc_plus3; + logic [31:1] f1pc_plus1, f1pc_plus2, f1pc_plus3; logic [3:0] alignval; logic [31:1] firstpc, secondpc, thirdpc, fourthpc; - + logic [11:0] f1poffset; - logic [11:0] f0poffset; + logic [11:0] f0poffset; logic [`RV_BHT_GHR_RANGE] f1fghr; - logic [`RV_BHT_GHR_RANGE] f0fghr; + logic [`RV_BHT_GHR_RANGE] f0fghr; logic [7:0] f1hist1; - logic [7:0] f0hist1; + logic [7:0] f0hist1; logic [7:0] f1hist0; - logic [7:0] f0hist0; + logic [7:0] f0hist0; logic [7:0] f1pc4; - logic [7:0] f0pc4; + logic [7:0] f0pc4; logic [7:0] f1ret; - logic [7:0] f0ret; + logic [7:0] f0ret; `ifdef RV_BTB_48 logic [7:0][1:0] f1way; - logic [7:0][1:0] f0way; + logic [7:0][1:0] f0way; `else logic [7:0] f1way; - logic [7:0] f0way; + logic [7:0] f0way; `endif - + logic [7:0] f1brend; - logic [7:0] f0brend; + logic [7:0] f0brend; logic [3:0] alignbrend; logic [3:0] alignpc4; `ifdef RV_ICACHE_ECC - logic [19:0] alignecc; -`else + logic [19:0] alignecc; +`else logic [3:0] alignparity; `endif - logic [3:0] alignret; + logic [3:0] alignret; logic [3:0] alignway; logic [3:0] alignhist1; @@ -197,13 +197,13 @@ module ifu_aln_ctl logic f0icfetch; logic f1icaf; logic f0icaf; - + logic [3:0] alignicfetch; - logic [3:0] aligntagperr; - logic [3:0] aligndataperr; + logic [3:0] aligntagperr; + logic [3:0] aligndataperr; logic [3:0] alignsbecc; logic [3:0] aligndbecc; - logic [3:0] alignicaf; + logic [3:0] alignicaf; logic i0_brp_pc4, i1_brp_pc4; logic [`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO] firstpc_hash, secondpc_hash, thirdpc_hash, fourthpc_hash; @@ -216,34 +216,34 @@ module ifu_aln_ctl logic illegal_lockout_in, illegal_lockout; logic [3:0] alignfinalperr; - + logic f2_wr_en; assign f2_wr_en = fetch_to_f2; - + logic f0_shift_wr_en; assign f0_shift_wr_en = (fetch_to_f0 | shift_f2_f0 | shift_f1_f0 | shift_2B | shift_4B | shift_6B | shift_8B); - + logic f1_shift_wr_en; assign f1_shift_wr_en = (fetch_to_f1 | shift_f2_f1 | f1_shift_2B | f1_shift_4B | f1_shift_6B); logic [1:0] wrptr, wrptr_in; - logic [1:0] rdptr, rdptr_in; + logic [1:0] rdptr, rdptr_in; logic [2:0] qwen; logic [127:0] q2,q1,q0; logic [2:0] first_offset, second_offset; logic [2:0] q2off_eff, q2off_in, q2off; logic [2:0] q1off_eff, q1off_in, q1off; - logic [2:0] q0off_eff, q0off_in, q0off; + logic [2:0] q0off_eff, q0off_in, q0off; logic f0_shift_2B, f0_shift_4B, f0_shift_6B, f0_shift_8B; logic [127:0] q0eff; logic [127:0] q0final; logic [2:0] q0ptr; logic [7:0] q0sel; - + logic [127:0] q1eff; logic [127:0] q1final; logic [2:0] q1ptr; @@ -253,24 +253,24 @@ module ifu_aln_ctl logic consume_fb1, consume_fb0; logic [3:1] icaf_eff; - + `ifdef RV_ICACHE_ECC logic [39:0] q0ecc, q1ecc, q2ecc; - logic [39:0] q0ecceff, q1ecceff; + logic [39:0] q0ecceff, q1ecceff; logic [39:0] q0eccfinal, q1eccfinal; -`else +`else logic [7:0] q0parity, q1parity, q2parity; - logic [7:0] q0parityeff, q1parityeff; + logic [7:0] q0parityeff, q1parityeff; logic [7:0] q0parityfinal, q1parityfinal; `endif // new queue control logic - + assign wrptr_in[1:0] = (({2{wrptr[1:0]==2'b00 & ifvalid}} & 2'b01) | ({2{wrptr[1:0]==2'b01 & ifvalid}} & 2'b10) | ({2{wrptr[1:0]==2'b10 & ifvalid}} & 2'b00) | ({2{~ifvalid}} & wrptr[1:0])) & ~{2{exu_flush_final}}; - + rvdff #(2) wrpff (.*, .clk(active_clk), .din(wrptr_in[1:0]), .dout(wrptr[1:0])); assign rdptr_in[1:0] = (({2{rdptr[1:0]==2'b00 & ifu_fb_consume1}} & 2'b01) | @@ -280,29 +280,29 @@ module ifu_aln_ctl ({2{rdptr[1:0]==2'b01 & ifu_fb_consume2}} & 2'b00) | ({2{rdptr[1:0]==2'b10 & ifu_fb_consume2}} & 2'b01) | ({2{~ifu_fb_consume1&~ifu_fb_consume2}} & rdptr[1:0])) & ~{2{exu_flush_final}}; - + rvdff #(2) rdpff (.*, .clk(active_clk), .din(rdptr_in[1:0]), .dout(rdptr[1:0])); - + assign qren[2:0] = { rdptr[1:0]==2'b10, rdptr[1:0]==2'b01, - rdptr[1:0]==2'b00 + 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 + wrptr[1:0]==2'b00 & ifvalid }; - + assign first_offset[2:0] = {f0_shift_8B, f0_shift_6B|f0_shift_4B, f0_shift_6B|f0_shift_2B }; - + assign second_offset[2:0] = {1'b0, f1_shift_6B|f1_shift_4B, f1_shift_6B|f1_shift_2B }; - - + + assign q2off_eff[2:0] = (rdptr[1:0]==2'd2) ? (q2off[2:0] + first_offset[2:0]) : (rdptr[1:0]==2'd1) ? (q2off[2:0] + second_offset[2:0]) : q2off[2:0]; - + assign q2off_in[2:0] = (qwen[2]) ? ifu_fetch_pc[3:1] : q2off_eff[2:0]; rvdff #(3) q2offsetff (.*, .clk(active_clk), .din(q2off_in[2:0]), .dout(q2off[2:0])); @@ -310,8 +310,8 @@ module ifu_aln_ctl assign q1off_eff[2:0] = (rdptr[1:0]==2'd1) ? (q1off[2:0] + first_offset[2:0]) : (rdptr[1:0]==2'd0) ? (q1off[2:0] + second_offset[2:0]) : q1off[2:0]; - - + + assign q1off_in[2:0] = (qwen[1]) ? ifu_fetch_pc[3:1] : q1off_eff[2:0]; rvdff #(3) q1offsetff (.*, .clk(active_clk), .din(q1off_in[2:0]), .dout(q1off[2:0])); @@ -320,17 +320,17 @@ module ifu_aln_ctl assign q0off_eff[2:0] = (rdptr[1:0]==2'd0) ? (q0off[2:0] + first_offset[2:0]) : (rdptr[1:0]==2'd2) ? (q0off[2:0] + second_offset[2:0]) : q0off[2:0]; - - - assign q0off_in[2:0] = (qwen[0]) ? ifu_fetch_pc[3:1] : q0off_eff[2:0]; - - rvdff #(3) q0offsetff (.*, .clk(active_clk), .din(q0off_in[2:0]), .dout(q0off[2:0])); + + assign q0off_in[2:0] = (qwen[0]) ? ifu_fetch_pc[3:1] : q0off_eff[2:0]; + + + rvdff #(3) q0offsetff (.*, .clk(active_clk), .din(q0off_in[2:0]), .dout(q0off[2:0])); assign q0ptr[2:0] = (({3{rdptr[1:0]==2'b00}} & q0off[2:0]) | ({3{rdptr[1:0]==2'b01}} & q1off[2:0]) | ({3{rdptr[1:0]==2'b10}} & q2off[2:0])); - + assign q1ptr[2:0] = (({3{rdptr[1:0]==2'b00}} & q1off[2:0]) | ({3{rdptr[1:0]==2'b01}} & q2off[2:0]) | ({3{rdptr[1:0]==2'b10}} & q0off[2:0])); @@ -344,7 +344,7 @@ module ifu_aln_ctl q0ptr[2:0]==3'b001, q0ptr[2:0]==3'b000 }; - + assign q1sel[7:0] = { q1ptr[2:0]==3'b111, q1ptr[2:0]==3'b110, q1ptr[2:0]==3'b101, @@ -354,18 +354,18 @@ module ifu_aln_ctl q1ptr[2:0]==3'b001, q1ptr[2:0]==3'b000 }; - + // end new queue control logic - + // misc data that is associated with each fetch buffer localparam MHI = 47+`RV_BHT_GHR_SIZE; localparam MSIZE = 48+`RV_BHT_GHR_SIZE; - + logic [MHI:0] misc_data_in, misc2, misc1, misc0; logic [MHI:0] misc1eff, misc0eff; - + assign misc_data_in[MHI:0] = { iccm_rd_ecc_double_err, iccm_rd_ecc_single_err, ifu_icache_fetch_f2, @@ -378,7 +378,7 @@ module ifu_aln_ctl rvdffe #(MSIZE) misc2ff (.*, .en(qwen[2]), .din(misc_data_in[MHI:0]), .dout(misc2[MHI:0])); rvdffe #(MSIZE) misc1ff (.*, .en(qwen[1]), .din(misc_data_in[MHI:0]), .dout(misc1[MHI:0])); - rvdffe #(MSIZE) misc0ff (.*, .en(qwen[0]), .din(misc_data_in[MHI:0]), .dout(misc0[MHI:0])); + rvdffe #(MSIZE) misc0ff (.*, .en(qwen[0]), .din(misc_data_in[MHI:0]), .dout(misc0[MHI:0])); assign {misc1eff[MHI:0],misc0eff[MHI:0]} = (({MSIZE*2{qren[0]}} & {misc1[MHI:0],misc0[MHI:0]}) | @@ -391,9 +391,9 @@ module ifu_aln_ctl f1icaf, f1prett[31:1], f1poffset[11:0], - f1fghr[`RV_BHT_GHR_RANGE] + f1fghr[`RV_BHT_GHR_RANGE] } = misc1eff[MHI:0]; - + assign { f0dbecc, f0sbecc, f0icfetch, @@ -403,7 +403,7 @@ module ifu_aln_ctl f0poffset[11:0], f0fghr[`RV_BHT_GHR_RANGE] } = misc0eff[MHI:0]; - + `ifdef RV_BTB_48 localparam BRDATA_SIZE=56; @@ -414,8 +414,8 @@ module ifu_aln_ctl `endif logic [BRDATA_SIZE-1:0] brdata_in, brdata2, brdata1, brdata0; logic [BRDATA_SIZE-1:0] brdata1eff, brdata0eff; - logic [BRDATA_SIZE-1:0] brdata1final, brdata0final; - assign brdata_in[BRDATA_SIZE-1:0] = { + logic [BRDATA_SIZE-1:0] brdata1final, brdata0final; + assign brdata_in[BRDATA_SIZE-1:0] = { ifu_bp_hist1_f2[7],ifu_bp_hist0_f2[7],ifu_bp_pc4_f2[7],ifu_bp_way_f2[7],ifu_bp_valid_f2[7],ifu_bp_ret_f2[7], ifu_bp_hist1_f2[6],ifu_bp_hist0_f2[6],ifu_bp_pc4_f2[6],ifu_bp_way_f2[6],ifu_bp_valid_f2[6],ifu_bp_ret_f2[6], ifu_bp_hist1_f2[5],ifu_bp_hist0_f2[5],ifu_bp_pc4_f2[5],ifu_bp_way_f2[5],ifu_bp_valid_f2[5],ifu_bp_ret_f2[5], @@ -425,35 +425,35 @@ module ifu_aln_ctl ifu_bp_hist1_f2[1],ifu_bp_hist0_f2[1],ifu_bp_pc4_f2[1],ifu_bp_way_f2[1],ifu_bp_valid_f2[1],ifu_bp_ret_f2[1], ifu_bp_hist1_f2[0],ifu_bp_hist0_f2[0],ifu_bp_pc4_f2[0],ifu_bp_way_f2[0],ifu_bp_valid_f2[0],ifu_bp_ret_f2[0] }; -// +// rvdffe #(BRDATA_SIZE) brdata2ff (.*, .en(qwen[2]), .din(brdata_in[BRDATA_SIZE-1:0]), .dout(brdata2[BRDATA_SIZE-1:0])); rvdffe #(BRDATA_SIZE) brdata1ff (.*, .en(qwen[1]), .din(brdata_in[BRDATA_SIZE-1:0]), .dout(brdata1[BRDATA_SIZE-1:0])); - rvdffe #(BRDATA_SIZE) brdata0ff (.*, .en(qwen[0]), .din(brdata_in[BRDATA_SIZE-1:0]), .dout(brdata0[BRDATA_SIZE-1:0])); + rvdffe #(BRDATA_SIZE) brdata0ff (.*, .en(qwen[0]), .din(brdata_in[BRDATA_SIZE-1:0]), .dout(brdata0[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[8*6-1:0*6]}) | - ({BRDATA_SIZE{q0sel[1]}} & {{1*BRDATA_WIDTH{1'b0}},brdata0eff[BRDATA_SIZE-1:1*BRDATA_WIDTH]}) | + ({BRDATA_SIZE{q0sel[1]}} & {{1*BRDATA_WIDTH{1'b0}},brdata0eff[BRDATA_SIZE-1:1*BRDATA_WIDTH]}) | ({BRDATA_SIZE{q0sel[2]}} & {{2*BRDATA_WIDTH{1'b0}},brdata0eff[BRDATA_SIZE-1:2*BRDATA_WIDTH]}) | ({BRDATA_SIZE{q0sel[3]}} & {{3*BRDATA_WIDTH{1'b0}},brdata0eff[BRDATA_SIZE-1:3*BRDATA_WIDTH]}) | ({BRDATA_SIZE{q0sel[4]}} & {{4*BRDATA_WIDTH{1'b0}},brdata0eff[BRDATA_SIZE-1:4*BRDATA_WIDTH]}) | ({BRDATA_SIZE{q0sel[5]}} & {{5*BRDATA_WIDTH{1'b0}},brdata0eff[BRDATA_SIZE-1:5*BRDATA_WIDTH]}) | ({BRDATA_SIZE{q0sel[6]}} & {{6*BRDATA_WIDTH{1'b0}},brdata0eff[BRDATA_SIZE-1:6*BRDATA_WIDTH]}) | - ({BRDATA_SIZE{q0sel[7]}} & {{7*BRDATA_WIDTH{1'b0}},brdata0eff[BRDATA_SIZE-1:7*BRDATA_WIDTH]})); - + ({BRDATA_SIZE{q0sel[7]}} & {{7*BRDATA_WIDTH{1'b0}},brdata0eff[BRDATA_SIZE-1:7*BRDATA_WIDTH]})); + assign brdata1final[BRDATA_SIZE-1:0] = (({BRDATA_SIZE{q1sel[0]}} & { brdata1eff[8*6-1:0*6]}) | - ({BRDATA_SIZE{q1sel[1]}} & {{1*BRDATA_WIDTH{1'b0}},brdata1eff[BRDATA_SIZE-1:1*BRDATA_WIDTH]}) | + ({BRDATA_SIZE{q1sel[1]}} & {{1*BRDATA_WIDTH{1'b0}},brdata1eff[BRDATA_SIZE-1:1*BRDATA_WIDTH]}) | ({BRDATA_SIZE{q1sel[2]}} & {{2*BRDATA_WIDTH{1'b0}},brdata1eff[BRDATA_SIZE-1:2*BRDATA_WIDTH]}) | ({BRDATA_SIZE{q1sel[3]}} & {{3*BRDATA_WIDTH{1'b0}},brdata1eff[BRDATA_SIZE-1:3*BRDATA_WIDTH]}) | ({BRDATA_SIZE{q1sel[4]}} & {{4*BRDATA_WIDTH{1'b0}},brdata1eff[BRDATA_SIZE-1:4*BRDATA_WIDTH]}) | ({BRDATA_SIZE{q1sel[5]}} & {{5*BRDATA_WIDTH{1'b0}},brdata1eff[BRDATA_SIZE-1:5*BRDATA_WIDTH]}) | ({BRDATA_SIZE{q1sel[6]}} & {{6*BRDATA_WIDTH{1'b0}},brdata1eff[BRDATA_SIZE-1:6*BRDATA_WIDTH]}) | - ({BRDATA_SIZE{q1sel[7]}} & {{7*BRDATA_WIDTH{1'b0}},brdata1eff[BRDATA_SIZE-1:7*BRDATA_WIDTH]})); + ({BRDATA_SIZE{q1sel[7]}} & {{7*BRDATA_WIDTH{1'b0}},brdata1eff[BRDATA_SIZE-1:7*BRDATA_WIDTH]})); - assign { + assign { f0hist1[7],f0hist0[7],f0pc4[7],f0way[7],f0brend[7],f0ret[7], f0hist1[6],f0hist0[6],f0pc4[6],f0way[6],f0brend[6],f0ret[6], f0hist1[5],f0hist0[5],f0pc4[5],f0way[5],f0brend[5],f0ret[5], @@ -463,8 +463,8 @@ module ifu_aln_ctl f0hist1[1],f0hist0[1],f0pc4[1],f0way[1],f0brend[1],f0ret[1], f0hist1[0],f0hist0[0],f0pc4[0],f0way[0],f0brend[0],f0ret[0] } = brdata0final[BRDATA_SIZE-1:0]; - - assign { + + assign { f1hist1[7],f1hist0[7],f1pc4[7],f1way[7],f1brend[7],f1ret[7], f1hist1[6],f1hist0[6],f1pc4[6],f1way[6],f1brend[6],f1ret[6], f1hist1[5],f1hist0[5],f1pc4[5],f1way[5],f1brend[5],f1ret[5], @@ -474,29 +474,29 @@ module ifu_aln_ctl f1hist1[1],f1hist0[1],f1pc4[1],f1way[1],f1brend[1],f1ret[1], f1hist1[0],f1hist0[0],f1pc4[0],f1way[0],f1brend[0],f1ret[0] } = brdata1final[BRDATA_SIZE-1:0]; - + // possible states of { sf0_valid, sf1_valid, f2_valid } // 000 if->f0 - + // 100 if->f1 - + // 101 illegal - + // 010 f1->f0, if->f1 - + // 110 if->f2 - + // 001 if->f1, f2->f0 - + // 011 f1->f0, f2->f1, if->f2 - + // 111 !if, no shift assign f2_valid = f2val[0]; - assign sf1_valid = sf1val[0]; + assign sf1_valid = sf1val[0]; assign sf0_valid = sf0val[0]; @@ -505,13 +505,13 @@ module ifu_aln_ctl 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 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; @@ -528,9 +528,9 @@ module ifu_aln_ctl ( sf0_valid & sf1_valid & ~f2_valid & ifvalid); // f0 valid states - // + // // 11111111 - // 11111110 + // 11111110 // 11111100 // 11111000 // 11110000 @@ -538,30 +538,30 @@ module ifu_aln_ctl // 11100000 // 11000000 // 10000000 - // 00000000 + // 00000000 // make this two incrementors with some logic on the lower bits - + assign f0pc_plus1[31:1] = f0pc[31:1] + 31'd1; assign f0pc_plus2[31:1] = f0pc[31:1] + 31'd2; assign f0pc_plus3[31:1] = f0pc[31:1] + 31'd3; assign f0pc_plus4[31:1] = f0pc[31:1] + 31'd4; assign f1pc_plus1[31:1] = f1pc[31:1] + 31'd1; - assign f1pc_plus2[31:1] = f1pc[31:1] + 31'd2; - assign f1pc_plus3[31:1] = f1pc[31:1] + 31'd3; + assign f1pc_plus2[31:1] = f1pc[31:1] + 31'd2; + assign f1pc_plus3[31:1] = f1pc[31:1] + 31'd3; assign f2pc_in[31:1] = ifu_fetch_pc[31:1]; - + rvdffe #(31) f2pcff (.*, .en(f2_wr_en), .din(f2pc_in[31:1]), .dout(f2pc[31:1])); assign sf1pc[31:1] = ({31{f1_shift_2B}} & (f1pc_plus1[31:1])) | ({31{f1_shift_4B}} & (f1pc_plus2[31:1])) | ({31{f1_shift_6B}} & (f1pc_plus3[31:1])) | ({31{~f1_shift_2B&~f1_shift_4B&~f1_shift_6B}} & f1pc[31:1]); - + assign f1pc_in[31:1] = ({31{fetch_to_f1}} & ifu_fetch_pc[31:1]) | ({31{shift_f2_f1}} & f2pc[31:1]) | ({31{~fetch_to_f1&~shift_f2_f1}} & sf1pc[31:1]); @@ -572,10 +572,10 @@ module ifu_aln_ctl ({31{shift_4B}} & (f0pc_plus2[31:1])) | ({31{shift_6B}} & (f0pc_plus3[31:1])) | ({31{shift_8B}} & (f0pc_plus4[31:1])); - + assign f0pc_in[31:1] = ({31{fetch_to_f0}} & ifu_fetch_pc[31:1]) | ({31{shift_f2_f0}} & f2pc[31:1]) | - ({31{shift_f1_f0}} & sf1pc[31:1]) | + ({31{shift_f1_f0}} & sf1pc[31:1]) | ({31{~fetch_to_f0&~shift_f2_f0&~shift_f1_f0}} & sf0pc[31:1]); rvdffe #(31) f0pcff (.*, .en(f0_shift_wr_en), .din(f0pc_in[31:1]), .dout(f0pc[31:1])); @@ -593,7 +593,7 @@ module ifu_aln_ctl ({8{f1_shift_4B}} & {2'b0,f1val[7:2]}) | ({8{f1_shift_6B}} & {3'b0,f1val[7:3]}) | ({8{~f1_shift_2B&~f1_shift_4B&~f1_shift_6B}} & f1val[7:0]); - + assign f1val_in[7:0] = (({8{fetch_to_f1}} & ifu_fetch_val[7:0]) | ({8{shift_f2_f1}} & f2val[7:0]) | ({8{~fetch_to_f1&~shift_f2_f1&~shift_f1_f0}} & sf1val[7:0])) & ~{8{exu_flush_final}}; @@ -606,12 +606,12 @@ module ifu_aln_ctl ({8{shift_6B}} & {3'b0,f0val[7:3]}) | ({8{shift_8B}} & {4'b0,f0val[7:4]}) | ({8{~shift_2B&~shift_4B&~shift_6B&~shift_8B}} & f0val[7:0]); - + assign f0val_in[7:0] = (({8{fetch_to_f0}} & ifu_fetch_val[7:0]) | ({8{shift_f2_f0}} & f2val[7:0]) | - ({8{shift_f1_f0}} & sf1val[7:0]) | + ({8{shift_f1_f0}} & sf1val[7:0]) | ({8{~fetch_to_f0&~shift_f2_f0&~shift_f1_f0}} & sf0val[7:0])) & ~{8{exu_flush_final}}; - + rvdff #(8) f0valff (.*, .clk(active_clk), .din(f0val_in[7:0]), .dout(f0val[7:0])); // parity @@ -619,154 +619,154 @@ module ifu_aln_ctl `ifdef RV_ICACHE_ECC rvdffe #(40) q2eccff (.*, .en(qwen[2]), .din(ic_error_f2.ecc[39:0]), .dout(q2ecc[39:0])); rvdffe #(40) q1eccff (.*, .en(qwen[1]), .din(ic_error_f2.ecc[39:0]), .dout(q1ecc[39:0])); - rvdffe #(40) q0eccff (.*, .en(qwen[0]), .din(ic_error_f2.ecc[39:0]), .dout(q0ecc[39:0])); + rvdffe #(40) q0eccff (.*, .en(qwen[0]), .din(ic_error_f2.ecc[39:0]), .dout(q0ecc[39:0])); assign {q1ecceff[39:0],q0ecceff[39:0]} = (({80{qren[0]}} & {q1ecc[39:0],q0ecc[39:0]}) | ({80{qren[1]}} & {q2ecc[39:0],q1ecc[39:0]}) | ({80{qren[2]}} & {q0ecc[39:0],q2ecc[39:0]})); - + assign q0eccfinal[39:0] = (({40{q0sel[0]}} & { q0ecceff[8*5-1:0*5]}) | - ({40{q0sel[1]}} & { 5'b0,q0ecceff[8*5-1:1*5]}) | + ({40{q0sel[1]}} & { 5'b0,q0ecceff[8*5-1:1*5]}) | ({40{q0sel[2]}} & {10'b0,q0ecceff[8*5-1:2*5]}) | ({40{q0sel[3]}} & {15'b0,q0ecceff[8*5-1:3*5]}) | ({40{q0sel[4]}} & {20'b0,q0ecceff[8*5-1:4*5]}) | ({40{q0sel[5]}} & {25'b0,q0ecceff[8*5-1:5*5]}) | ({40{q0sel[6]}} & {30'b0,q0ecceff[8*5-1:6*5]}) | - ({40{q0sel[7]}} & {35'b0,q0ecceff[8*5-1:7*5]})); + ({40{q0sel[7]}} & {35'b0,q0ecceff[8*5-1:7*5]})); assign q1eccfinal[39:0] = (({40{q1sel[0]}} & { q1ecceff[8*5-1:0*5]}) | - ({40{q1sel[1]}} & { 5'b0,q1ecceff[8*5-1:1*5]}) | + ({40{q1sel[1]}} & { 5'b0,q1ecceff[8*5-1:1*5]}) | ({40{q1sel[2]}} & {10'b0,q1ecceff[8*5-1:2*5]}) | ({40{q1sel[3]}} & {15'b0,q1ecceff[8*5-1:3*5]}) | ({40{q1sel[4]}} & {20'b0,q1ecceff[8*5-1:4*5]}) | ({40{q1sel[5]}} & {25'b0,q1ecceff[8*5-1:5*5]}) | ({40{q1sel[6]}} & {30'b0,q1ecceff[8*5-1:6*5]}) | - ({40{q1sel[7]}} & {35'b0,q1ecceff[8*5-1:7*5]})); - -`else + ({40{q1sel[7]}} & {35'b0,q1ecceff[8*5-1:7*5]})); + +`else rvdffe #(8) q2parityff (.*, .en(qwen[2]), .din(ic_error_f2.parity[7:0]), .dout(q2parity[7:0])); rvdffe #(8) q1parityff (.*, .en(qwen[1]), .din(ic_error_f2.parity[7:0]), .dout(q1parity[7:0])); - rvdffe #(8) q0parityff (.*, .en(qwen[0]), .din(ic_error_f2.parity[7:0]), .dout(q0parity[7:0])); + rvdffe #(8) q0parityff (.*, .en(qwen[0]), .din(ic_error_f2.parity[7:0]), .dout(q0parity[7:0])); assign {q1parityeff[7:0],q0parityeff[7:0]} = (({16{qren[0]}} & {q1parity[7:0],q0parity[7:0]}) | ({16{qren[1]}} & {q2parity[7:0],q1parity[7:0]}) | ({16{qren[2]}} & {q0parity[7:0],q2parity[7:0]})); - + assign q0parityfinal[7:0] = (({8{q0sel[0]}} & { q0parityeff[7:0]}) | - ({8{q0sel[1]}} & {1'b0,q0parityeff[7:1]}) | + ({8{q0sel[1]}} & {1'b0,q0parityeff[7:1]}) | ({8{q0sel[2]}} & {2'b0,q0parityeff[7:2]}) | ({8{q0sel[3]}} & {3'b0,q0parityeff[7:3]}) | ({8{q0sel[4]}} & {4'b0,q0parityeff[7:4]}) | ({8{q0sel[5]}} & {5'b0,q0parityeff[7:5]}) | ({8{q0sel[6]}} & {6'b0,q0parityeff[7:6]}) | - ({8{q0sel[7]}} & {7'b0,q0parityeff[7]})); - + ({8{q0sel[7]}} & {7'b0,q0parityeff[7]})); + assign q1parityfinal[7:0] = (({8{q1sel[0]}} & { q1parityeff[7:0]}) | - ({8{q1sel[1]}} & {1'b0,q1parityeff[7:1]}) | + ({8{q1sel[1]}} & {1'b0,q1parityeff[7:1]}) | ({8{q1sel[2]}} & {2'b0,q1parityeff[7:2]}) | ({8{q1sel[3]}} & {3'b0,q1parityeff[7:3]}) | ({8{q1sel[4]}} & {4'b0,q1parityeff[7:4]}) | ({8{q1sel[5]}} & {5'b0,q1parityeff[7:5]}) | ({8{q1sel[6]}} & {6'b0,q1parityeff[7:6]}) | - ({8{q1sel[7]}} & {7'b0,q1parityeff[7]})); + ({8{q1sel[7]}} & {7'b0,q1parityeff[7]})); `endif // !`ifdef RV_ICACHE_ECC - + rvdffe #(128) q2ff (.*, .en(qwen[2]), .din(ifu_fetch_data[127:0]), .dout(q2[127:0])); rvdffe #(128) q1ff (.*, .en(qwen[1]), .din(ifu_fetch_data[127:0]), .dout(q1[127:0])); - rvdffe #(128) q0ff (.*, .en(qwen[0]), .din(ifu_fetch_data[127:0]), .dout(q0[127:0])); + rvdffe #(128) q0ff (.*, .en(qwen[0]), .din(ifu_fetch_data[127:0]), .dout(q0[127:0])); assign {q1eff[127:0],q0eff[127:0]} = (({256{qren[0]}} & {q1[127:0],q0[127:0]}) | ({256{qren[1]}} & {q2[127:0],q1[127:0]}) | ({256{qren[2]}} & {q0[127:0],q2[127:0]})); - + assign q0final[127:0] = (({128{q0sel[0]}} & { q0eff[8*16-1:16*0]}) | - ({128{q0sel[1]}} & {{16*1{1'b0}},q0eff[8*16-1:16*1]}) | + ({128{q0sel[1]}} & {{16*1{1'b0}},q0eff[8*16-1:16*1]}) | ({128{q0sel[2]}} & {{16*2{1'b0}},q0eff[8*16-1:16*2]}) | ({128{q0sel[3]}} & {{16*3{1'b0}},q0eff[8*16-1:16*3]}) | ({128{q0sel[4]}} & {{16*4{1'b0}},q0eff[8*16-1:16*4]}) | ({128{q0sel[5]}} & {{16*5{1'b0}},q0eff[8*16-1:16*5]}) | ({128{q0sel[6]}} & {{16*6{1'b0}},q0eff[8*16-1:16*6]}) | - ({128{q0sel[7]}} & {{16*7{1'b0}},q0eff[8*16-1:16*7]})); - + ({128{q0sel[7]}} & {{16*7{1'b0}},q0eff[8*16-1:16*7]})); + assign q1final[127:0] = (({128{q1sel[0]}} & { q1eff[8*16-1:16*0]}) | - ({128{q1sel[1]}} & {{16*1{1'b0}},q1eff[8*16-1:16*1]}) | + ({128{q1sel[1]}} & {{16*1{1'b0}},q1eff[8*16-1:16*1]}) | ({128{q1sel[2]}} & {{16*2{1'b0}},q1eff[8*16-1:16*2]}) | ({128{q1sel[3]}} & {{16*3{1'b0}},q1eff[8*16-1:16*3]}) | ({128{q1sel[4]}} & {{16*4{1'b0}},q1eff[8*16-1:16*4]}) | ({128{q1sel[5]}} & {{16*5{1'b0}},q1eff[8*16-1:16*5]}) | ({128{q1sel[6]}} & {{16*6{1'b0}},q1eff[8*16-1:16*6]}) | - ({128{q1sel[7]}} & {{16*7{1'b0}},q1eff[8*16-1:16*7]})); - + ({128{q1sel[7]}} & {{16*7{1'b0}},q1eff[8*16-1:16*7]})); - assign aligndata[63:0] = ({64{(f0val[3])}} & {q0final[4*16-1:0]}) | + + assign aligndata[63:0] = ({64{(f0val[3])}} & {q0final[4*16-1:0]}) | ({64{(f0val[2]&~f0val[3])}} & {q1final[1*16-1:0],q0final[3*16-1:0]}) | ({64{(f0val[1]&~f0val[2])}} & {q1final[2*16-1:0],q0final[2*16-1:0]}) | - ({64{(f0val[0]&~f0val[1])}} & {q1final[3*16-1:0],q0final[1*16-1:0]}); - - assign alignval[3:0] = ({4{(f0val[3])}} & 4'b1111) | + ({64{(f0val[0]&~f0val[1])}} & {q1final[3*16-1:0],q0final[1*16-1:0]}); + + assign alignval[3:0] = ({4{(f0val[3])}} & 4'b1111) | ({4{(f0val[2]&~f0val[3])}} & {f1val[0],3'b111}) | ({4{(f0val[1]&~f0val[2])}} & {f1val[1:0],2'b11}) | - ({4{(f0val[0]&~f0val[1])}} & {f1val[2:0],1'b1}); + ({4{(f0val[0]&~f0val[1])}} & {f1val[2:0],1'b1}); - assign alignicaf[3:0] = ({4{(f0val[3])}} & {4{f0icaf}}) | + assign alignicaf[3:0] = ({4{(f0val[3])}} & {4{f0icaf}}) | ({4{(f0val[2]&~f0val[3])}} & {{1{f1icaf}},{3{f0icaf}}}) | ({4{(f0val[1]&~f0val[2])}} & {{2{f1icaf}},{2{f0icaf}}}) | - ({4{(f0val[0]&~f0val[1])}} & {{3{f1icaf}},{1{f0icaf}}}); + ({4{(f0val[0]&~f0val[1])}} & {{3{f1icaf}},{1{f0icaf}}}); - assign alignsbecc[3:0] = ({4{(f0val[3])}} & {4{f0sbecc}}) | + assign alignsbecc[3:0] = ({4{(f0val[3])}} & {4{f0sbecc}}) | ({4{(f0val[2]&~f0val[3])}} & {{1{f1sbecc}},{3{f0sbecc}}}) | ({4{(f0val[1]&~f0val[2])}} & {{2{f1sbecc}},{2{f0sbecc}}}) | - ({4{(f0val[0]&~f0val[1])}} & {{3{f1sbecc}},{1{f0sbecc}}}); + ({4{(f0val[0]&~f0val[1])}} & {{3{f1sbecc}},{1{f0sbecc}}}); - assign aligndbecc[3:0] = ({4{(f0val[3])}} & {4{f0dbecc}}) | + assign aligndbecc[3:0] = ({4{(f0val[3])}} & {4{f0dbecc}}) | ({4{(f0val[2]&~f0val[3])}} & {{1{f1dbecc}},{3{f0dbecc}}}) | ({4{(f0val[1]&~f0val[2])}} & {{2{f1dbecc}},{2{f0dbecc}}}) | - ({4{(f0val[0]&~f0val[1])}} & {{3{f1dbecc}},{1{f0dbecc}}}); + ({4{(f0val[0]&~f0val[1])}} & {{3{f1dbecc}},{1{f0dbecc}}}); // for branch prediction assign alignbrend[3:0] = ({4{(f0val[3])}} & f0brend[3:0]) | - ({4{(f0val[2]&~f0val[3])}} & {f1brend[0],f0brend[2:0]}) | + ({4{(f0val[2]&~f0val[3])}} & {f1brend[0],f0brend[2:0]}) | ({4{(f0val[1]&~f0val[2])}} & {f1brend[1:0],f0brend[1:0]}) | ({4{(f0val[0]&~f0val[1])}} & {f1brend[2:0],f0brend[0]}); - + assign alignpc4[3:0] = ({4{(f0val[3])}} & f0pc4[3:0]) | - ({4{(f0val[2]&~f0val[3])}} & {f1pc4[0],f0pc4[2:0]}) | + ({4{(f0val[2]&~f0val[3])}} & {f1pc4[0],f0pc4[2:0]}) | ({4{(f0val[1]&~f0val[2])}} & {f1pc4[1:0],f0pc4[1:0]}) | ({4{(f0val[0]&~f0val[1])}} & {f1pc4[2:0],f0pc4[0]}); `ifdef RV_ICACHE_ECC assign alignecc[19:0] = ({20{(f0val[3])}} & q0eccfinal[19:0]) | - ({20{(f0val[2]&~f0val[3])}} & {q1eccfinal[4:0], q0eccfinal[14:0]}) | + ({20{(f0val[2]&~f0val[3])}} & {q1eccfinal[4:0], q0eccfinal[14:0]}) | ({20{(f0val[1]&~f0val[2])}} & {q1eccfinal[9:0], q0eccfinal[9:0]}) | ({20{(f0val[0]&~f0val[1])}} & {q1eccfinal[14:0],q0eccfinal[4:0]}); -`else +`else assign alignparity[3:0] = ({4{(f0val[3])}} & q0parityfinal[3:0]) | - ({4{(f0val[2]&~f0val[3])}} & {q1parityfinal[0], q0parityfinal[2:0]}) | + ({4{(f0val[2]&~f0val[3])}} & {q1parityfinal[0], q0parityfinal[2:0]}) | ({4{(f0val[1]&~f0val[2])}} & {q1parityfinal[1:0],q0parityfinal[1:0]}) | ({4{(f0val[0]&~f0val[1])}} & {q1parityfinal[2:0],q0parityfinal[0]}); `endif - assign aligntagperr[3:0] = ({4{(f0val[3])}} & {4{f0perr}}) | + assign aligntagperr[3:0] = ({4{(f0val[3])}} & {4{f0perr}}) | ({4{(f0val[2]&~f0val[3])}} & {{1{f1perr}},{3{f0perr}}}) | ({4{(f0val[1]&~f0val[2])}} & {{2{f1perr}},{2{f0perr}}}) | - ({4{(f0val[0]&~f0val[1])}} & {{3{f1perr}},{1{f0perr}}}); - - assign alignicfetch[3:0] = ({4{(f0val[3])}} & {4{f0icfetch}}) | + ({4{(f0val[0]&~f0val[1])}} & {{3{f1perr}},{1{f0perr}}}); + + assign alignicfetch[3:0] = ({4{(f0val[3])}} & {4{f0icfetch}}) | ({4{(f0val[2]&~f0val[3])}} & {{1{f1icfetch}},{3{f0icfetch}}}) | ({4{(f0val[1]&~f0val[2])}} & {{2{f1icfetch}},{2{f0icfetch}}}) | - ({4{(f0val[0]&~f0val[1])}} & {{3{f1icfetch}},{1{f0icfetch}}}); - - + ({4{(f0val[0]&~f0val[1])}} & {{3{f1icfetch}},{1{f0icfetch}}}); + + assign alignret[3:0] = ({4{(f0val[3])}} & f0ret[3:0]) | - ({4{(f0val[2]&~f0val[3])}} & {f1ret[0],f0ret[2:0]}) | + ({4{(f0val[2]&~f0val[3])}} & {f1ret[0],f0ret[2:0]}) | ({4{(f0val[1]&~f0val[2])}} & {f1ret[1:0],f0ret[1:0]}) | ({4{(f0val[0]&~f0val[1])}} & {f1ret[2:0],f0ret[0]}); - + `ifdef RV_BTB_48 logic [3:0] f0way_b0, f0way_b1, alignway_b0, alignway_b1; @@ -777,41 +777,41 @@ module ifu_aln_ctl assign f1way_b1[2:0] = {f1way[2][1], f1way[1][1], f1way[0][1]}; assign alignway_b0[3:0] = ({4{(f0val[3])}} & f0way_b0[3:0]) | - ({4{(f0val[2]&~f0val[3])}} & {f1way_b0[0], f0way_b0[2:0]}) | + ({4{(f0val[2]&~f0val[3])}} & {f1way_b0[0], f0way_b0[2:0]}) | ({4{(f0val[1]&~f0val[2])}} & {f1way_b0[1:0],f0way_b0[1:0]}) | ({4{(f0val[0]&~f0val[1])}} & {f1way_b0[2:0],f0way_b0[0]}); assign alignway_b1[3:0] = ({4{(f0val[3])}} & f0way_b1[3:0]) | - ({4{(f0val[2]&~f0val[3])}} & {f1way_b1[0], f0way_b1[2:0]}) | + ({4{(f0val[2]&~f0val[3])}} & {f1way_b1[0], f0way_b1[2:0]}) | ({4{(f0val[1]&~f0val[2])}} & {f1way_b1[1:0],f0way_b1[1:0]}) | ({4{(f0val[0]&~f0val[1])}} & {f1way_b1[2:0],f0way_b1[0]}); `else assign alignway[3:0] = ({4{(f0val[3])}} & f0way[3:0]) | - ({4{(f0val[2]&~f0val[3])}} & {f1way[0],f0way[2:0]}) | + ({4{(f0val[2]&~f0val[3])}} & {f1way[0],f0way[2:0]}) | ({4{(f0val[1]&~f0val[2])}} & {f1way[1:0],f0way[1:0]}) | ({4{(f0val[0]&~f0val[1])}} & {f1way[2:0],f0way[0]}); `endif assign alignhist1[3:0] = ({4{(f0val[3])}} & f0hist1[3:0]) | - ({4{(f0val[2]&~f0val[3])}} & {f1hist1[0],f0hist1[2:0]}) | + ({4{(f0val[2]&~f0val[3])}} & {f1hist1[0],f0hist1[2:0]}) | ({4{(f0val[1]&~f0val[2])}} & {f1hist1[1:0],f0hist1[1:0]}) | ({4{(f0val[0]&~f0val[1])}} & {f1hist1[2:0],f0hist1[0]}); assign alignhist0[3:0] = ({4{(f0val[3])}} & f0hist0[3:0]) | - ({4{(f0val[2]&~f0val[3])}} & {f1hist0[0],f0hist0[2:0]}) | + ({4{(f0val[2]&~f0val[3])}} & {f1hist0[0],f0hist0[2:0]}) | ({4{(f0val[1]&~f0val[2])}} & {f1hist0[1:0],f0hist0[1:0]}) | ({4{(f0val[0]&~f0val[1])}} & {f1hist0[2:0],f0hist0[0]}); assign alignfromf1[3:1] = ({3{(f0val[3])}} & 3'b0) | - ({3{(f0val[2]&~f0val[3])}} & {1'b1,2'b0}) | + ({3{(f0val[2]&~f0val[3])}} & {1'b1,2'b0}) | ({3{(f0val[1]&~f0val[2])}} & {2'b11,1'b0}) | ({3{(f0val[0]&~f0val[1])}} & {3'b111}); - - assign { secondpc[31:1], + + assign { secondpc[31:1], thirdpc[31:1], fourthpc[31:1] } = ({3*31{(f0val[3])}} & {f0pc_plus1[31:1], f0pc_plus2[31:1], f0pc_plus3[31:1]}) | - ({3*31{(f0val[2]&~f0val[3])}} & {f0pc_plus1[31:1], f0pc_plus2[31:1], f1pc[31:1]}) | - ({3*31{(f0val[1]&~f0val[2])}} & {f0pc_plus1[31:1], f1pc[31:1], f1pc_plus1[31:1]}) | - ({3*31{(f0val[0]&~f0val[1])}} & {f1pc[31:1], f1pc_plus1[31:1], f1pc_plus2[31:1]}); + ({3*31{(f0val[2]&~f0val[3])}} & {f0pc_plus1[31:1], f0pc_plus2[31:1], f1pc[31:1]}) | + ({3*31{(f0val[1]&~f0val[2])}} & {f0pc_plus1[31:1], f1pc[31:1], f1pc_plus1[31:1]}) | + ({3*31{(f0val[0]&~f0val[1])}} & {f1pc[31:1], f1pc_plus1[31:1], f1pc_plus2[31:1]}); assign ifu_i0_pc[31:1] = f0pc[31:1]; @@ -819,8 +819,8 @@ module ifu_aln_ctl assign firstpc[31:1] = f0pc[31:1]; assign ifu_i1_pc[31:1] = (first2B) ? secondpc[31:1] : thirdpc[31:1]; - - + + assign ifu_i0_pc4 = first4B; assign ifu_i1_pc4 = (first2B & second4B) | @@ -835,7 +835,7 @@ module ifu_aln_ctl logic [3:0] ic_single_ecc_error; logic [3:0] ic_double_ecc_error; logic [3:0] aligneccerr; - + for (genvar i=0; i < 4 ; i++) begin : ic_ecc_error rvecc_decode ecc_decode ( .en(~dec_tlu_core_ecc_disable), @@ -852,9 +852,9 @@ module ifu_aln_ctl assign aligneccerr[i] = ic_single_ecc_error[i] | ic_double_ecc_error[i]; assign aligndataperr[i] = aligneccerr[i] ; end // block: ic_ecc_error - + `else // !`ifdef RV_ICACHE_ECC - + for (genvar i=0; i<4 ; i++) begin : ic_par_error rveven_paritycheck pchk ( .data_in(aligndata[16*(i+1)-1: 16*i]), @@ -862,7 +862,7 @@ module ifu_aln_ctl .parity_err(aligndataperr[i]) ); end - + `endif // !`ifdef RV_ICACHE_ECC @@ -870,9 +870,9 @@ module ifu_aln_ctl assign ifu_i0_cinst[15:0] = aligndata[15:0]; assign ifu_i1_cinst[15:0] = (first4B) ? aligndata[47:32] : aligndata[31:16]; // end trace - + // check on 16B boundaries - // + // assign first4B = aligndata[16*0+1:16*0] == 2'b11; assign first2B = ~first4B; @@ -895,9 +895,9 @@ module ifu_aln_ctl (first2B & alignicaf[0])) & ~exu_flush_final; - + assign icaf_eff[3:1] = alignicaf[3:1] | aligndbecc[3:1]; - + assign ifu_i0_icaf_f1 = first4B & icaf_eff[1] & alignfromf1[1]; assign ifu_i1_icaf = ((first4B & third4B & (|alignicaf[3:2])) | @@ -912,9 +912,9 @@ module ifu_aln_ctl // inst parity error on any byte of inst results in parity error for the inst - + assign alignfinalperr[3:0] = (aligntagperr[3:0] | aligndataperr[3:0]) & alignicfetch[3:0]; - + assign ifu_i0_perr = ((first4B & (|alignfinalperr[1:0])) | (first2B & alignfinalperr[0])) & ~exu_flush_final; @@ -925,7 +925,7 @@ module ifu_aln_ctl assign ifu_i0_sbecc = ((first4B & (|alignsbecc[1:0])) | (first2B & alignsbecc[0])) & ~exu_flush_final; - + assign ifu_i1_sbecc = ((first4B & third4B & (|alignsbecc[3:2])) | (first4B & third2B & alignsbecc[2]) | (first2B & second4B & (|alignsbecc[2:1])) | @@ -943,7 +943,7 @@ module ifu_aln_ctl // parity error is orthogonal to single-bit ecc error; icache vs iccm logic [2:0] alignicerr; - + assign alignicerr[2:0] = alignfinalperr[2:0] | alignsbecc[2:0]; assign ifu_icache_error_index[16:2] = (alignicerr[0]) ? firstpc[16:2] : @@ -953,24 +953,24 @@ module ifu_aln_ctl assign ifu_icache_error_val = (i0_shift & ifu_i0_perr) | (i1_shift & ifu_i1_perr & ~ifu_i0_sbecc); - + assign ifu_icache_sb_error_val = (i0_shift & ifu_i0_sbecc) | (i1_shift & ifu_i1_sbecc & ~ifu_i0_perr); `ifdef ASSERT_ON - assert_ifu_icache_parity_with_sbecc_error: assert #0 ($onehot0({ifu_icache_error_val,ifu_icache_sb_error_val})); -`endif + assert_ifu_icache_parity_with_sbecc_error: assert #0 ($onehot0({ifu_icache_error_val,ifu_icache_sb_error_val})); +`endif // big endian 4B instructions assign ifirst[31:0] = aligndata[2*16-1:0*16]; assign isecond[31:0] = aligndata[3*16-1:1*16]; - + assign ithird[31:0] = aligndata[4*16-1:2*16]; - - - + + + assign ifu_i0_instr[31:0] = ({32{first4B}} & ifirst[31:0]) | ({32{first2B}} & uncompress0[31:0]); @@ -988,7 +988,7 @@ module ifu_aln_ctl rvbtb_addr_hash fourthhash(.pc(fourthpc[31:1]), .hash(fourthpc_hash[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO])); logic [`RV_BTB_BTAG_SIZE-1:0] firstbrtag_hash, secondbrtag_hash, thirdbrtag_hash, fourthbrtag_hash; - + rvbtb_tag_hash first_brhash(.pc(firstpc[31:1]), .hash(firstbrtag_hash[`RV_BTB_BTAG_SIZE-1:0])); rvbtb_tag_hash second_brhash(.pc(secondpc[31:1]), .hash(secondbrtag_hash[`RV_BTB_BTAG_SIZE-1:0])); rvbtb_tag_hash third_brhash(.pc(thirdpc[31:1]), .hash(thirdbrtag_hash[`RV_BTB_BTAG_SIZE-1:0])); @@ -996,41 +996,41 @@ module ifu_aln_ctl // 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]) | + i0_brp.valid = (first2B & alignbrend[0]) | (first4B & alignbrend[1]) | i0_br_start_error; - - i0_brp_pc4 = (first2B & alignpc4[0]) | + + i0_brp_pc4 = (first2B & alignpc4[0]) | (first4B & alignpc4[1]); - i0_brp.ret = (first2B & alignret[0]) | + i0_brp.ret = (first2B & alignret[0]) | (first4B & alignret[1]); `ifdef RV_BTB_48 i0_brp.way = (first2B | alignbrend[0]) ? {alignway_b1[0], alignway_b0[0]} : {alignway_b1[1], alignway_b0[1]}; `else i0_brp.way = (first2B | alignbrend[0]) ? alignway[0] : alignway[1]; -`endif +`endif 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.fghr[`RV_BHT_GHR_RANGE] = (i0_ends_f1) ? f1fghr[`RV_BHT_GHR_RANGE] : f0fghr[`RV_BHT_GHR_RANGE]; - i0_brp.prett[31:1] = (i0_ends_f1) ? f1prett[31:1] : f0prett[31:1]; + i0_brp.prett[31:1] = (i0_ends_f1) ? f1prett[31:1] : f0prett[31:1]; i0_brp.br_start_error = i0_br_start_error; @@ -1042,11 +1042,11 @@ module ifu_aln_ctl i0_brp.bank[1:0] = (first2B | alignbrend[0]) ? firstpc[3:2] : secondpc[3:2]; - - + + i0_brp.br_error = (i0_brp.valid & i0_brp_pc4 & first2B) | (i0_brp.valid & ~i0_brp_pc4 & first4B); - + i1_brp = '0; i1_br_start_error = (first2B & second4B & alignval[2] & alignbrend[1]) | @@ -1062,7 +1062,7 @@ module ifu_aln_ctl (first4B & third4B & alignpc4[3]) | (first2B & second2B & alignpc4[1]) | (first2B & second4B & alignpc4[2]); - + i1_brp.ret = (first4B & third2B & alignret[2]) | (first4B & third4B & alignret[3]) | (first2B & second2B & alignret[1]) | @@ -1070,18 +1070,18 @@ module ifu_aln_ctl `ifdef RV_BTB_48 i1_brp.way = ({2{first4B & third2B }} & {alignway_b1[2], alignway_b0[2]} ) | ({2{first4B & third4B & alignbrend[2] }} & {alignway_b1[2], alignway_b0[2]} ) | - ({2{first4B & third4B & ~alignbrend[2] }} & {alignway_b1[3], alignway_b0[3]} ) | + ({2{first4B & third4B & ~alignbrend[2] }} & {alignway_b1[3], alignway_b0[3]} ) | ({2{first2B & second2B }} & {alignway_b1[1], alignway_b0[1]} ) | ({2{first2B & second4B & alignbrend[1]}} & {alignway_b1[1], alignway_b0[1]} ) | ({2{first2B & second4B & ~alignbrend[1]}} & {alignway_b1[2], alignway_b0[2]} ); -`else +`else i1_brp.way = (first4B & third2B & alignway[2] ) | (first4B & third4B & alignbrend[2] & alignway[2] ) | - (first4B & third4B & ~alignbrend[2] & alignway[3] ) | + (first4B & third4B & ~alignbrend[2] & alignway[3] ) | (first2B & second2B & alignway[1] ) | (first2B & second4B & alignbrend[1] & alignway[1] ) | (first2B & second4B & ~alignbrend[1] & alignway[2] ); -`endif +`endif i1_brp.hist[1] = (first4B & third2B & alignhist1[2]) | (first4B & third4B & alignhist1[3]) | (first2B & second2B & alignhist1[1]) | @@ -1101,29 +1101,29 @@ module ifu_aln_ctl i1_brp.fghr[`RV_BHT_GHR_RANGE] = (i1_ends_f1) ? f1fghr[`RV_BHT_GHR_RANGE] : f0fghr[`RV_BHT_GHR_RANGE]; - i1_brp.prett[31:1] = (i1_ends_f1) ? f1prett[31:1] : f0prett[31:1]; - + i1_brp.prett[31:1] = (i1_ends_f1) ? f1prett[31:1] : f0prett[31:1]; + i1_brp.br_start_error = i1_br_start_error; `define RV_BTB_RANGE `RV_BTB_ADDR_HI-`RV_BTB_ADDR_LO+1 - + i1_brp.index[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO] = ({`RV_BTB_RANGE{first4B & third2B }} & thirdpc_hash[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO] ) | ({`RV_BTB_RANGE{first4B & third4B & alignbrend[2] }} & thirdpc_hash[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO] ) | - ({`RV_BTB_RANGE{first4B & third4B & ~alignbrend[2] }} & fourthpc_hash[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO] ) | + ({`RV_BTB_RANGE{first4B & third4B & ~alignbrend[2] }} & fourthpc_hash[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO] ) | ({`RV_BTB_RANGE{first2B & second2B}} & secondpc_hash[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO] ) | ({`RV_BTB_RANGE{first2B & second4B & alignbrend[1]}} & secondpc_hash[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO] ) | ({`RV_BTB_RANGE{first2B & second4B & ~alignbrend[1]}} & thirdpc_hash[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO] ); - + i1_brp.btag[`RV_BTB_BTAG_SIZE-1:0] = ({`RV_BTB_BTAG_SIZE{first4B & third2B }} & thirdbrtag_hash[`RV_BTB_BTAG_SIZE-1:0] ) | ({`RV_BTB_BTAG_SIZE{first4B & third4B & alignbrend[2] }} & thirdbrtag_hash[`RV_BTB_BTAG_SIZE-1:0] ) | - ({`RV_BTB_BTAG_SIZE{first4B & third4B & ~alignbrend[2] }} & fourthbrtag_hash[`RV_BTB_BTAG_SIZE-1:0] ) | + ({`RV_BTB_BTAG_SIZE{first4B & third4B & ~alignbrend[2] }} & fourthbrtag_hash[`RV_BTB_BTAG_SIZE-1:0] ) | ({`RV_BTB_BTAG_SIZE{first2B & second2B}} & secondbrtag_hash[`RV_BTB_BTAG_SIZE-1:0] ) | ({`RV_BTB_BTAG_SIZE{first2B & second4B & alignbrend[1]}} & secondbrtag_hash[`RV_BTB_BTAG_SIZE-1:0] ) | ({`RV_BTB_BTAG_SIZE{first2B & second4B & ~alignbrend[1]}} & thirdbrtag_hash[`RV_BTB_BTAG_SIZE-1:0] ); i1_brp.bank[1:0] = ({2{first4B & third2B }} & thirdpc[3:2] ) | ({2{first4B & third4B & alignbrend[2] }} & thirdpc[3:2] ) | - ({2{first4B & third4B & ~alignbrend[2] }} & fourthpc[3:2] ) | + ({2{first4B & third4B & ~alignbrend[2] }} & fourthpc[3:2] ) | ({2{first2B & second2B}} & secondpc[3:2] ) | ({2{first2B & second4B & alignbrend[1]}} & secondpc[3:2] ) | ({2{first2B & second4B & ~alignbrend[1]}} & thirdpc[3:2] ); @@ -1132,11 +1132,11 @@ module ifu_aln_ctl (i1_brp.valid & ~i1_brp_pc4 & first4B & third4B ) | (i1_brp.valid & i1_brp_pc4 & first2B & second2B) | (i1_brp.valid & ~i1_brp_pc4 & first2B & second4B); - end + end // figure out 2B illegal insts - - assign i0_illegal = (first2B & ~first_legal); + + assign i0_illegal = (first2B & ~first_legal); assign i1_illegal = (first2B & second2B & ~second_legal) | (first4B & third2B & ~third_legal); @@ -1144,25 +1144,25 @@ module ifu_aln_ctl assign shift_illegal = (i0_shift & i0_illegal) | (i1_shift & i1_illegal); - assign illegal_inst[15:0] = (first2B & ~first_legal) ? aligndata[1*16-1:0*16] : + assign illegal_inst[15:0] = (first2B & ~first_legal) ? aligndata[1*16-1:0*16] : ((first2B & second2B & ~second_legal) ? aligndata[2*16-1:1*16] : aligndata[3*16-1:2*16]); assign illegal_inst_en = shift_illegal & ~illegal_lockout; - + rvdffe #(16) illegal_any_ff (.*, .en(illegal_inst_en), .din(illegal_inst[15:0]), .dout(ifu_illegal_inst[15:0])); assign illegal_lockout_in = (shift_illegal | illegal_lockout) & ~exu_flush_final; - + rvdff #(1) illegal_lockout_any_ff (.*, .clk(active_clk), .din(illegal_lockout_in), .dout(illegal_lockout)); - - + + // decompress ifu_compress_ctl compress0 (.din(aligndata[16*1-1:0*16]), .dout(uncompress0[31:0]), .legal(first_legal) ); ifu_compress_ctl compress1 (.din(aligndata[16*2-1:1*16]), .dout(uncompress1[31:0]), .legal(second_legal) ); - - ifu_compress_ctl compress2 (.din(aligndata[16*3-1:2*16]), .dout(uncompress2[31:0]), .legal(third_legal) ); + + ifu_compress_ctl compress2 (.din(aligndata[16*3-1:2*16]), .dout(uncompress2[31:0]), .legal(third_legal) ); @@ -1170,7 +1170,7 @@ module ifu_aln_ctl assign i1_shift = ifu_i1_valid & ibuffer_room2_more; - if (DEC_INSTBUF_DEPTH==4) begin + if (DEC_INSTBUF_DEPTH==4) begin assign ibuffer_room1_more = ~dec_ib3_valid_d; assign ibuffer_room2_more = ~dec_ib2_valid_d; end @@ -1178,15 +1178,15 @@ module ifu_aln_ctl assign ibuffer_room1_more = ~dec_ib0_valid_eff_d | ~dec_ib1_valid_eff_d; assign ibuffer_room2_more = ~dec_ib0_valid_eff_d & ~dec_ib1_valid_eff_d; end - - + + assign ifu_pmu_instr_aligned[1:0] = { i1_shift, i0_shift }; assign ifu_pmu_align_stall = ifu_i0_valid & ~ibuffer_room1_more; - + // compute how many bytes are being shifted from f0 - + // assign shift_0B = ~i0_shift; assign shift_2B = i0_shift & ~i1_shift & first2B; @@ -1201,24 +1201,24 @@ module ifu_aln_ctl assign shift_8B = i0_shift & i1_shift & first4B & third4B; // exact equations for the queue logic - assign f0_shift_2B = (shift_2B & f0val[0]) | + assign f0_shift_2B = (shift_2B & f0val[0]) | ((shift_4B | shift_6B | shift_8B) & f0val[0] & ~f0val[1]); - assign f0_shift_4B = (shift_4B & f0val[1]) | + assign f0_shift_4B = (shift_4B & f0val[1]) | ((shift_6B & shift_8B) & f0val[1] & ~f0val[2]); - - + + assign f0_shift_6B = (shift_6B & f0val[2]) | (shift_8B & f0val[2] & ~f0val[3]); - + assign f0_shift_8B = shift_8B & f0val[3]; - - - + + + // f0 valid states - // + // // 11111111 - // 11111110 + // 11111110 // 11111100 // 11111000 // 11110000 @@ -1226,20 +1226,20 @@ module ifu_aln_ctl // 11100000 // 11000000 // 10000000 - // 00000000 - + // 00000000 + // assign f1_shift_0B = shift_0B; - + assign f1_shift_2B = (f0val[2] & ~f0val[3] & shift_8B) | (f0val[1] & ~f0val[2] & shift_6B) | (f0val[0] & ~f0val[1] & shift_4B); - + assign f1_shift_4B = (f0val[1] & ~f0val[2] & shift_8B) | (f0val[0] & ~f0val[1] & shift_6B); - + assign f1_shift_6B = (f0val[0] & ~f0val[1] & shift_8B); - - -endmodule + + +endmodule diff --git a/design/ifu/ifu_bp_ctl.sv b/design/ifu/ifu_bp_ctl.sv index d5a449d..bc3687a 100644 --- a/design/ifu/ifu_bp_ctl.sv +++ b/design/ifu/ifu_bp_ctl.sv @@ -17,8 +17,8 @@ //******************************************************************************** // Function: Branch predictor -// Comments: -// +// Comments: +// // // Bank3 : Bank2 : Bank1 : Bank0 // FA C 8 4 0 @@ -27,7 +27,7 @@ module ifu_bp_ctl import swerv_types::*; ( - + input logic clk, input logic active_clk, input logic clk_override, @@ -42,19 +42,19 @@ module ifu_bp_ctl input br_tlu_pkt_t dec_tlu_br0_wb_pkt, // BP commit update packet, includes errors input br_tlu_pkt_t dec_tlu_br1_wb_pkt, // BP commit update packet, includes errors - + 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 logic dec_tlu_bpred_disable, // disable all branch prediction + input logic exu_i0_br_ret_e4, // EX4 ret stack update input logic exu_i1_br_ret_e4, // EX4 ret stack update input logic exu_i0_br_call_e4, // EX4 ret stack update input logic exu_i1_br_call_e4, // EX4 ret stack update input predict_pkt_t exu_mp_pkt, // mispredict packet - + input rets_pkt_t exu_rets_e1_pkt, // EX1 rets packet input rets_pkt_t exu_rets_e4_pkt, // EX4 rets packet @@ -69,7 +69,7 @@ module ifu_bp_ctl input logic exu_flush_final, // all flushes input logic exu_flush_upper_e2, // flush upper, either i0 or i1, cp EX1 RS to F RS - + output logic ifu_bp_kill_next_f2, // kill next fetch, taken target found output logic [31:1] ifu_bp_btb_target_f2, // predicted target PC output logic [7:1] ifu_bp_inst_mask_f2, // tell ic which valids to kill because of a taken branch, right justified @@ -104,7 +104,7 @@ module ifu_bp_ctl localparam NUM_BHT_LOOP_INNER_HI = (`RV_BHT_ARRAY_DEPTH > 16 ) ?`RV_BHT_ADDR_LO+3 : `RV_BHT_ADDR_HI; localparam NUM_BHT_LOOP_OUTER_LO = (`RV_BHT_ARRAY_DEPTH > 16 ) ?`RV_BHT_ADDR_LO+4 : `RV_BHT_ADDR_LO; localparam BHT_NO_ADDR_MATCH = ( `RV_BHT_ARRAY_DEPTH <= 16 ); - + logic exu_mp_valid_write; logic exu_mp_ataken; logic exu_mp_valid; // conditional branch mispredict @@ -126,7 +126,7 @@ module ifu_bp_ctl logic dec_tlu_br0_error_wb; // error; invalidate bank logic dec_tlu_br0_start_error_wb; // error; invalidate all 4 banks in fg logic [`RV_BHT_GHR_RANGE] dec_tlu_br0_fghr_wb; - + logic dec_tlu_br1_v_wb; // WB stage history update logic [1:0] dec_tlu_br1_hist_wb; // new history logic [`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO] dec_tlu_br1_addr_wb; // addr @@ -138,7 +138,7 @@ module ifu_bp_ctl logic [3:0] use_mp_way; logic [`RV_RET_STACK_SIZE-1:0][31:1] rets_out, rets_in, e1_rets_out, e1_rets_in, e4_rets_out, e4_rets_in; logic [`RV_RET_STACK_SIZE-1:0] rsenable; - + logic [11:0] btb_rd_tgt_f2; logic btb_rd_pc4_f2, btb_rd_boffset_f2, btb_rd_call_f2, btb_rd_ret_f2; @@ -152,7 +152,7 @@ module ifu_bp_ctl logic [16+`RV_BTB_BTAG_SIZE:0] btb_wr_data; logic [3:0] btb_wr_en_way0, btb_wr_en_way1; - + logic dec_tlu_error_wb, dec_tlu_all_banks_error_wb, btb_valid, dec_tlu_br0_middle_wb, dec_tlu_br1_middle_wb; logic [`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO] btb_error_addr_wb; logic [1:0] dec_tlu_error_bank_wb; @@ -162,11 +162,11 @@ module ifu_bp_ctl logic [3:0] branch_error_bank_conflict_f1, branch_error_bank_conflict_f2; logic [`RV_BHT_GHR_RANGE] merged_ghr, fghr_ns, fghr; logic [3:0] num_valids; - logic [LRU_SIZE-1:0] btb_lru_b0_f, btb_lru_b0_hold, btb_lru_b0_ns, btb_lru_b1_f, btb_lru_b1_hold, btb_lru_b1_ns, - btb_lru_b2_f, btb_lru_b2_hold, btb_lru_b2_ns, btb_lru_b3_f, btb_lru_b3_hold, btb_lru_b3_ns, + logic [LRU_SIZE-1:0] btb_lru_b0_f, btb_lru_b0_hold, btb_lru_b0_ns, btb_lru_b1_f, btb_lru_b1_hold, btb_lru_b1_ns, + btb_lru_b2_f, btb_lru_b2_hold, btb_lru_b2_ns, btb_lru_b3_f, btb_lru_b3_hold, btb_lru_b3_ns, fetch_wrindex_dec, fetch_wrlru_b0, fetch_wrlru_b1, fetch_wrlru_b2, fetch_wrlru_b3, mp_wrindex_dec, mp_wrlru_b0, mp_wrlru_b1, mp_wrlru_b2, mp_wrlru_b3; - logic [3:0] btb_lru_rd_f2, mp_bank_decoded, mp_bank_decoded_f, lru_update_valid_f2; + logic [3:0] btb_lru_rd_f2, mp_bank_decoded, mp_bank_decoded_f, lru_update_valid_f2; logic [3:0] tag_match_way0_f2, tag_match_way1_f2; logic [7:0] way_raw, bht_dir_f2, btb_sel_f2, wayhit_f2; logic [7:0] btb_sel_mask_f2, bht_valid_f2, bht_force_taken_f2; @@ -177,7 +177,7 @@ module ifu_bp_ctl logic [LRU_SIZE-1:0][16+`RV_BTB_BTAG_SIZE:0] btb_bank1_rd_data_way0_out ; logic [LRU_SIZE-1:0][16+`RV_BTB_BTAG_SIZE:0] btb_bank2_rd_data_way0_out ; logic [LRU_SIZE-1:0][16+`RV_BTB_BTAG_SIZE:0] btb_bank3_rd_data_way0_out ; - + logic [LRU_SIZE-1:0][16+`RV_BTB_BTAG_SIZE:0] btb_bank0_rd_data_way1_out ; logic [LRU_SIZE-1:0][16+`RV_BTB_BTAG_SIZE:0] btb_bank1_rd_data_way1_out ; logic [LRU_SIZE-1:0][16+`RV_BTB_BTAG_SIZE:0] btb_bank2_rd_data_way1_out ; @@ -193,7 +193,7 @@ module ifu_bp_ctl logic [16+`RV_BTB_BTAG_SIZE:0] btb_bank2_rd_data_way1_f2_in ; logic [16+`RV_BTB_BTAG_SIZE:0] btb_bank3_rd_data_way1_f2_in ; - + logic [16+`RV_BTB_BTAG_SIZE:0] btb_bank0_rd_data_way0_f2 ; logic [16+`RV_BTB_BTAG_SIZE:0] btb_bank1_rd_data_way0_f2 ; logic [16+`RV_BTB_BTAG_SIZE:0] btb_bank2_rd_data_way0_f2 ; @@ -225,10 +225,10 @@ module ifu_bp_ctl logic [3:0] btb_wr_en_way2, tag_match_way2_f2, fetch_lru_bank_hit_f2; logic [7:0] tag_match_way2_expanded_f2; - logic [1:0] exu_mp_way, exu_mp_way_f, dec_tlu_br0_way_wb, dec_tlu_br1_way_wb, dec_tlu_way_wb, dec_tlu_way_wb_f; + logic [1:0] exu_mp_way, exu_mp_way_f, dec_tlu_br0_way_wb, dec_tlu_br1_way_wb, dec_tlu_way_wb, dec_tlu_way_wb_f; `else // !`ifdef RV_BTB_48 - logic exu_mp_way, exu_mp_way_f, dec_tlu_br0_way_wb, dec_tlu_br1_way_wb, dec_tlu_way_wb, dec_tlu_way_wb_f; + logic exu_mp_way, exu_mp_way_f, dec_tlu_br0_way_wb, dec_tlu_br1_way_wb, dec_tlu_way_wb, dec_tlu_way_wb_f; `endif logic [16+`RV_BTB_BTAG_SIZE:0] btb_bank0e_rd_data_f2 ; @@ -244,15 +244,15 @@ module ifu_bp_ctl logic [7:0] tag_match_way0_expanded_f2, tag_match_way1_expanded_f2; - logic [1:0] bht_bank0_rd_data_f2 ; - logic [1:0] bht_bank1_rd_data_f2 ; - logic [1:0] bht_bank2_rd_data_f2 ; - logic [1:0] bht_bank3_rd_data_f2 ; - logic [1:0] bht_bank4_rd_data_f2 ; - logic [1:0] bht_bank5_rd_data_f2 ; - logic [1:0] bht_bank6_rd_data_f2 ; - logic [1:0] bht_bank7_rd_data_f2 ; - + logic [1:0] bht_bank0_rd_data_f2 ; + logic [1:0] bht_bank1_rd_data_f2 ; + logic [1:0] bht_bank2_rd_data_f2 ; + logic [1:0] bht_bank3_rd_data_f2 ; + logic [1:0] bht_bank4_rd_data_f2 ; + logic [1:0] bht_bank5_rd_data_f2 ; + logic [1:0] bht_bank6_rd_data_f2 ; + logic [1:0] bht_bank7_rd_data_f2 ; + assign exu_mp_valid = exu_mp_pkt.misp & ~leak_one_f2; // 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 @@ -267,8 +267,8 @@ module ifu_bp_ctl assign exu_mp_btag[`RV_BTB_BTAG_SIZE-1:0] = exu_mp_pkt.btag[`RV_BTB_BTAG_SIZE-1:0] ; // branch tag assign exu_mp_fghr[`RV_BHT_GHR_RANGE] = exu_mp_pkt.fghr[`RV_BHT_GHR_RANGE] ; // original fetch ghr (for bht update) assign exu_mp_ataken = exu_mp_pkt.ataken; - - assign dec_tlu_br0_v_wb = dec_tlu_br0_wb_pkt.valid; + + assign dec_tlu_br0_v_wb = dec_tlu_br0_wb_pkt.valid; assign dec_tlu_br0_hist_wb[1:0] = dec_tlu_br0_wb_pkt.hist[1:0]; assign dec_tlu_br0_addr_wb[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO] = dec_tlu_br0_wb_pkt.index[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO]; assign dec_tlu_br0_bank_wb[1:0] = dec_tlu_br0_wb_pkt.bank[1:0]; @@ -278,7 +278,7 @@ module ifu_bp_ctl assign dec_tlu_br0_start_error_wb = dec_tlu_br0_wb_pkt.br_start_error; assign dec_tlu_br0_fghr_wb[`RV_BHT_GHR_RANGE] = dec_tlu_br0_wb_pkt.fghr[`RV_BHT_GHR_RANGE]; - assign dec_tlu_br1_v_wb = dec_tlu_br1_wb_pkt.valid; + assign dec_tlu_br1_v_wb = dec_tlu_br1_wb_pkt.valid; assign dec_tlu_br1_hist_wb[1:0] = dec_tlu_br1_wb_pkt.hist[1:0]; assign dec_tlu_br1_addr_wb[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO] = dec_tlu_br1_wb_pkt.index[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO]; assign dec_tlu_br1_bank_wb[1:0] = dec_tlu_br1_wb_pkt.bank[1:0]; @@ -299,7 +299,7 @@ module ifu_bp_ctl rvbtb_addr_hash f1hash(.pc(ifc_fetch_addr_f1[31:1]), .hash(btb_rd_addr_f1[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO])); rvbtb_addr_hash f2hash(.pc(ifc_fetch_addr_f2[31:1]), .hash(btb_rd_addr_f2[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO])); - + // based on the fetch group offset(PC[3:2]) and direction bits, findfirst from fetchPC // this sel is zero/onehot // Put the table below in a file and run espresso to generate the btb_sel_f2 and btb_vmask_raw_f2 equations @@ -308,18 +308,18 @@ module ifu_bp_ctl // .i 11 // .o 15 // .ilb ifc_fetch_addr_f2[3] ifc_fetch_addr_f2[2] ifc_fetch_addr_f2[1] bht_dir_f2[7] bht_dir_f2[6] bht_dir_f2[5] bht_dir_f2[4] bht_dir_f2[3] bht_dir_f2[2] bht_dir_f2[1] bht_dir_f2[0] -// .ob btb_sel_f2[7] btb_sel_f2[6] btb_sel_f2[5] btb_sel_f2[4] btb_sel_f2[3] btb_sel_f2[2] btb_sel_f2[1] btb_sel_f2[0] btb_vmask_raw_f2[7] btb_vmask_raw_f2[6] btb_vmask_raw_f2[5] btb_vmask_raw_f2[4] btb_vmask_raw_f2[3] btb_vmask_raw_f2[2] btb_vmask_raw_f2[1] +// .ob btb_sel_f2[7] btb_sel_f2[6] btb_sel_f2[5] btb_sel_f2[4] btb_sel_f2[3] btb_sel_f2[2] btb_sel_f2[1] btb_sel_f2[0] btb_vmask_raw_f2[7] btb_vmask_raw_f2[6] btb_vmask_raw_f2[5] btb_vmask_raw_f2[4] btb_vmask_raw_f2[3] btb_vmask_raw_f2[2] btb_vmask_raw_f2[1] // .type fr // ##faddress[3:1] dir[7:0] sel[7:0] mask[7:1] // 000 -------1 00000001 0000000 // 000 ------10 00000010 0000001 // 000 -----100 00000100 0000010 -// 000 ----1000 00001000 0000100 +// 000 ----1000 00001000 0000100 // 000 ---10000 00010000 0001000 // 000 --100000 00100000 0010000 // 000 -1000000 01000000 0100000 // 000 10000000 10000000 1000000 -// +// // 001 ------1- 00000010 0000000 // 001 -----10- 00000100 0000001 // 001 ----100- 00001000 0000010 @@ -327,32 +327,32 @@ module ifu_bp_ctl // 001 --10000- 00100000 0001000 // 001 -100000- 01000000 0010000 // 001 1000000- 10000000 0110000 -// +// // 010 -----1-- 00000100 0000000 // 010 ----10-- 00001000 0000001 // 010 ---100-- 00010000 0000010 // 010 --1000-- 00100000 0000100 // 010 -10000-- 01000000 0001000 // 010 100000-- 10000000 0010000 -// +// // 011 ----1--- 00001000 0000000 // 011 ---10--- 00010000 0000001 // 011 --100--- 00100000 0000010 // 011 -1000--- 01000000 0000100 // 011 10000--- 10000000 0001000 -// +// // 100 ---1---- 00010000 0000000 // 100 --10---- 00100000 0000001 // 100 -100---- 01000000 0000010 // 100 1000---- 10000000 0000100 -// +// // 101 --1----- 00100000 0000000 // 101 -10----- 01000000 0000001 // 101 100----- 10000000 0000010 -// +// // 110 -1------ 01000000 0000000 // 110 10------ 10000000 0000001 -// +// // 111 1------- 10000000 0000000 @@ -500,7 +500,7 @@ assign btb_vmask_raw_f2[1] = (ifc_fetch_addr_f2[3] & ifc_fetch_addr_f2[2] // end of espresso generated equations - + logic[7:1] btb_vmask_f2; assign btb_vmask_f2[7:1] = {btb_vmask_raw_f2[7], |btb_vmask_raw_f2[7:6], @@ -509,15 +509,15 @@ assign btb_vmask_raw_f2[1] = (ifc_fetch_addr_f2[3] & ifc_fetch_addr_f2[2] |btb_vmask_raw_f2[7:3], |btb_vmask_raw_f2[7:2], |btb_vmask_raw_f2[7:1]}; - + // Errors colliding with fetches must kill the btb/bht hit. assign branch_error_collision_f1 = dec_tlu_error_wb & (btb_error_addr_wb[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO] == btb_rd_addr_f1[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO]); assign branch_error_bank_conflict_f1[3:0] = {4{branch_error_collision_f1}} & (decode2_4(dec_tlu_error_bank_wb[1:0]) | {4{dec_tlu_all_banks_error_wb}}); - - assign fetch_mp_collision_f1 = ( (exu_mp_btag[`RV_BTB_BTAG_SIZE-1:0] == fetch_rd_tag_f1[`RV_BTB_BTAG_SIZE-1:0]) & - exu_mp_valid & ifc_fetch_req_f1 & + + assign fetch_mp_collision_f1 = ( (exu_mp_btag[`RV_BTB_BTAG_SIZE-1:0] == fetch_rd_tag_f1[`RV_BTB_BTAG_SIZE-1:0]) & + exu_mp_valid & ifc_fetch_req_f1 & (exu_mp_addr[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO] == btb_rd_addr_f1[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO]) ); // set on leak one, hold until next flush without leak one @@ -526,49 +526,49 @@ assign btb_vmask_raw_f2[1] = (ifc_fetch_addr_f2[3] & ifc_fetch_addr_f2[2] `ifdef RV_BTB_48 rvdff #(15) coll_ff (.*, .clk(active_clk), `else - rvdff #(13) coll_ff (.*, .clk(active_clk), + rvdff #(13) coll_ff (.*, .clk(active_clk), `endif - .din({branch_error_bank_conflict_f1[3:0], fetch_mp_collision_f1, mp_bank_decoded[3:0], exu_mp_way, dec_tlu_way_wb, leak_one_f1, ifc_fetch_req_f1}), + .din({branch_error_bank_conflict_f1[3:0], fetch_mp_collision_f1, mp_bank_decoded[3:0], exu_mp_way, dec_tlu_way_wb, leak_one_f1, ifc_fetch_req_f1}), .dout({branch_error_bank_conflict_f2[3:0], fetch_mp_collision_f2, mp_bank_decoded_f[3:0], exu_mp_way_f, dec_tlu_way_wb_f, leak_one_f2, ifc_fetch_req_f2_raw})); `ifdef RV_BTB_48 - + // 2 -way SA, figure out the way hit and mux accordingly assign tag_match_way0_f2[3:0] = {btb_bank3_rd_data_way0_f2[BV] & (btb_bank3_rd_data_way0_f2[`TAG] == fetch_rd_tag_f2[`RV_BTB_BTAG_SIZE-1:0]), btb_bank2_rd_data_way0_f2[BV] & (btb_bank2_rd_data_way0_f2[`TAG] == fetch_rd_tag_f2[`RV_BTB_BTAG_SIZE-1:0]), btb_bank1_rd_data_way0_f2[BV] & (btb_bank1_rd_data_way0_f2[`TAG] == fetch_rd_tag_f2[`RV_BTB_BTAG_SIZE-1:0]), - btb_bank0_rd_data_way0_f2[BV] & (btb_bank0_rd_data_way0_f2[`TAG] == fetch_rd_tag_f2[`RV_BTB_BTAG_SIZE-1:0])} & + btb_bank0_rd_data_way0_f2[BV] & (btb_bank0_rd_data_way0_f2[`TAG] == fetch_rd_tag_f2[`RV_BTB_BTAG_SIZE-1:0])} & ~({4{dec_tlu_way_wb_f==2'b0}} & branch_error_bank_conflict_f2[3:0]) & {4{ifc_fetch_req_f2_raw & ~leak_one_f2}}; - + assign tag_match_way1_f2[3:0] = {btb_bank3_rd_data_way1_f2[BV] & (btb_bank3_rd_data_way1_f2[`TAG] == fetch_rd_tag_f2[`RV_BTB_BTAG_SIZE-1:0]), btb_bank2_rd_data_way1_f2[BV] & (btb_bank2_rd_data_way1_f2[`TAG] == fetch_rd_tag_f2[`RV_BTB_BTAG_SIZE-1:0]), btb_bank1_rd_data_way1_f2[BV] & (btb_bank1_rd_data_way1_f2[`TAG] == fetch_rd_tag_f2[`RV_BTB_BTAG_SIZE-1:0]), - btb_bank0_rd_data_way1_f2[BV] & (btb_bank0_rd_data_way1_f2[`TAG] == fetch_rd_tag_f2[`RV_BTB_BTAG_SIZE-1:0])} & + btb_bank0_rd_data_way1_f2[BV] & (btb_bank0_rd_data_way1_f2[`TAG] == fetch_rd_tag_f2[`RV_BTB_BTAG_SIZE-1:0])} & ~({4{dec_tlu_way_wb_f[0]}} & branch_error_bank_conflict_f2[3:0]) & {4{ifc_fetch_req_f2_raw & ~leak_one_f2}}; assign tag_match_way2_f2[3:0] = {btb_bank3_rd_data_way2_f2[BV] & (btb_bank3_rd_data_way2_f2[`TAG] == fetch_rd_tag_f2[`RV_BTB_BTAG_SIZE-1:0]), btb_bank2_rd_data_way2_f2[BV] & (btb_bank2_rd_data_way2_f2[`TAG] == fetch_rd_tag_f2[`RV_BTB_BTAG_SIZE-1:0]), btb_bank1_rd_data_way2_f2[BV] & (btb_bank1_rd_data_way2_f2[`TAG] == fetch_rd_tag_f2[`RV_BTB_BTAG_SIZE-1:0]), - btb_bank0_rd_data_way2_f2[BV] & (btb_bank0_rd_data_way2_f2[`TAG] == fetch_rd_tag_f2[`RV_BTB_BTAG_SIZE-1:0])} & + btb_bank0_rd_data_way2_f2[BV] & (btb_bank0_rd_data_way2_f2[`TAG] == fetch_rd_tag_f2[`RV_BTB_BTAG_SIZE-1:0])} & ~({4{dec_tlu_way_wb_f[1]}} & branch_error_bank_conflict_f2[3:0]) & {4{ifc_fetch_req_f2_raw & ~leak_one_f2}}; -`else +`else // 2 -way SA, figure out the way hit and mux accordingly assign tag_match_way0_f2[3:0] = {btb_bank3_rd_data_way0_f2[BV] & (btb_bank3_rd_data_way0_f2[`TAG] == fetch_rd_tag_f2[`RV_BTB_BTAG_SIZE-1:0]), btb_bank2_rd_data_way0_f2[BV] & (btb_bank2_rd_data_way0_f2[`TAG] == fetch_rd_tag_f2[`RV_BTB_BTAG_SIZE-1:0]), btb_bank1_rd_data_way0_f2[BV] & (btb_bank1_rd_data_way0_f2[`TAG] == fetch_rd_tag_f2[`RV_BTB_BTAG_SIZE-1:0]), - btb_bank0_rd_data_way0_f2[BV] & (btb_bank0_rd_data_way0_f2[`TAG] == fetch_rd_tag_f2[`RV_BTB_BTAG_SIZE-1:0])} & + btb_bank0_rd_data_way0_f2[BV] & (btb_bank0_rd_data_way0_f2[`TAG] == fetch_rd_tag_f2[`RV_BTB_BTAG_SIZE-1:0])} & ~({4{~dec_tlu_way_wb_f}} & branch_error_bank_conflict_f2[3:0]) & {4{ifc_fetch_req_f2_raw & ~leak_one_f2}}; - + assign tag_match_way1_f2[3:0] = {btb_bank3_rd_data_way1_f2[BV] & (btb_bank3_rd_data_way1_f2[`TAG] == fetch_rd_tag_f2[`RV_BTB_BTAG_SIZE-1:0]), btb_bank2_rd_data_way1_f2[BV] & (btb_bank2_rd_data_way1_f2[`TAG] == fetch_rd_tag_f2[`RV_BTB_BTAG_SIZE-1:0]), btb_bank1_rd_data_way1_f2[BV] & (btb_bank1_rd_data_way1_f2[`TAG] == fetch_rd_tag_f2[`RV_BTB_BTAG_SIZE-1:0]), - btb_bank0_rd_data_way1_f2[BV] & (btb_bank0_rd_data_way1_f2[`TAG] == fetch_rd_tag_f2[`RV_BTB_BTAG_SIZE-1:0])} & + btb_bank0_rd_data_way1_f2[BV] & (btb_bank0_rd_data_way1_f2[`TAG] == fetch_rd_tag_f2[`RV_BTB_BTAG_SIZE-1:0])} & ~({4{dec_tlu_way_wb_f}} & branch_error_bank_conflict_f2[3:0]) & {4{ifc_fetch_req_f2_raw & ~leak_one_f2}}; `endif - + // Both ways could hit, use the offset bit to reorder - + assign tag_match_way0_expanded_f2[7:0] = {tag_match_way0_f2[3] & (btb_bank3_rd_data_way0_f2[BOFF] ^ btb_bank3_rd_data_way0_f2[PC4]), tag_match_way0_f2[3] & ~(btb_bank3_rd_data_way0_f2[BOFF] ^ btb_bank3_rd_data_way0_f2[PC4]), tag_match_way0_f2[2] & (btb_bank2_rd_data_way0_f2[BOFF] ^ btb_bank2_rd_data_way0_f2[PC4]), @@ -577,7 +577,7 @@ assign btb_vmask_raw_f2[1] = (ifc_fetch_addr_f2[3] & ifc_fetch_addr_f2[2] tag_match_way0_f2[1] & ~(btb_bank1_rd_data_way0_f2[BOFF] ^ btb_bank1_rd_data_way0_f2[PC4]), tag_match_way0_f2[0] & (btb_bank0_rd_data_way0_f2[BOFF] ^ btb_bank0_rd_data_way0_f2[PC4]), tag_match_way0_f2[0] & ~(btb_bank0_rd_data_way0_f2[BOFF] ^ btb_bank0_rd_data_way0_f2[PC4])}; - + assign tag_match_way1_expanded_f2[7:0] = {tag_match_way1_f2[3] & (btb_bank3_rd_data_way1_f2[BOFF] ^ btb_bank3_rd_data_way1_f2[PC4]), tag_match_way1_f2[3] & ~(btb_bank3_rd_data_way1_f2[BOFF] ^ btb_bank3_rd_data_way1_f2[PC4]), tag_match_way1_f2[2] & (btb_bank2_rd_data_way1_f2[BOFF] ^ btb_bank2_rd_data_way1_f2[PC4]), @@ -663,7 +663,7 @@ assign btb_vmask_raw_f2[1] = (ifc_fetch_addr_f2[3] & ifc_fetch_addr_f2[2] assign mp_bank_decoded[3:0] = decode2_4(exu_mp_bank[1:0]); // create a onehot lru write vector assign mp_wrindex_dec[LRU_SIZE-1:0] = {{LRU_SIZE-1{1'b0}},1'b1} << exu_mp_addr[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO]; - + // fetch assign fetch_wrindex_dec[LRU_SIZE-1:0] = {{LRU_SIZE-1{1'b0}},1'b1} << btb_rd_addr_f2[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO]; @@ -690,17 +690,17 @@ assign btb_vmask_raw_f2[1] = (ifc_fetch_addr_f2[3] & ifc_fetch_addr_f2[2] ((bht_valid_f2[2] & btb_sel_mask_f2[2]) | (bht_valid_f2[3] & btb_sel_mask_f2[3])) & ifc_fetch_req_f2 & ~leak_one_f2, ((bht_valid_f2[0] & btb_sel_mask_f2[0]) | (bht_valid_f2[1] & btb_sel_mask_f2[1])) & ifc_fetch_req_f2 & ~leak_one_f2}; - assign fetch_wrlru_b0[LRU_SIZE-1:0] = fetch_wrindex_dec[LRU_SIZE-1:0] & + assign fetch_wrlru_b0[LRU_SIZE-1:0] = fetch_wrindex_dec[LRU_SIZE-1:0] & {LRU_SIZE{lru_update_valid_f2[0]}}; - assign fetch_wrlru_b1[LRU_SIZE-1:0] = fetch_wrindex_dec[LRU_SIZE-1:0] & + assign fetch_wrlru_b1[LRU_SIZE-1:0] = fetch_wrindex_dec[LRU_SIZE-1:0] & {LRU_SIZE{lru_update_valid_f2[1]}}; - assign fetch_wrlru_b2[LRU_SIZE-1:0] = fetch_wrindex_dec[LRU_SIZE-1:0] & + assign fetch_wrlru_b2[LRU_SIZE-1:0] = fetch_wrindex_dec[LRU_SIZE-1:0] & {LRU_SIZE{lru_update_valid_f2[2]}}; - assign fetch_wrlru_b3[LRU_SIZE-1:0] = fetch_wrindex_dec[LRU_SIZE-1:0] & + assign fetch_wrlru_b3[LRU_SIZE-1:0] = fetch_wrindex_dec[LRU_SIZE-1:0] & {LRU_SIZE{lru_update_valid_f2[3]}}; `endif - + assign btb_lru_b0_hold[LRU_SIZE-1:0] = ~mp_wrlru_b0[LRU_SIZE-1:0] & ~fetch_wrlru_b0[LRU_SIZE-1:0]; assign btb_lru_b1_hold[LRU_SIZE-1:0] = ~mp_wrlru_b1[LRU_SIZE-1:0] & ~fetch_wrlru_b1[LRU_SIZE-1:0]; assign btb_lru_b2_hold[LRU_SIZE-1:0] = ~mp_wrlru_b2[LRU_SIZE-1:0] & ~fetch_wrlru_b2[LRU_SIZE-1:0]; @@ -723,7 +723,7 @@ assign btb_vmask_raw_f2[1] = (ifc_fetch_addr_f2[3] & ifc_fetch_addr_f2[2] fetch_replway_bank0_enc, fetch_replway_bank1_enc, fetch_replway_bank2_enc, fetch_replway_bank3_enc, fetch_replway_bank4_enc, fetch_replway_bank5_enc, fetch_replway_bank6_enc, fetch_replway_bank7_enc; logic [3:0][3:0] [2:0] lru_bank_rd_data_out; - + // // could have 2 ways hit for case where same bank, different offset hit. Update LRU accordingly logic [3:0] two_hits; assign two_hits[3:0] = (tag_match_way0_f2[3:0] & tag_match_way1_f2[3:0]) | @@ -737,7 +737,7 @@ logic [3:0] two_hits; assign fetch_lru_bank_hit_f2[3:0] = lru_update_valid_f2[3:0] & (tag_match_way0_f2[3:0] | tag_match_way1_f2[3:0] | tag_match_way2_f2[3:0]); // banks - for ( i=0; i<4; i++) begin : LRUBANKS + for ( i=0; i<4; i++) begin : LRUBANKS // only 4 indices here // encode the hit way in case the fetch hits assign hitway_enc[i] = tag_match_way1_f2[i] ? 2'b01 : tag_match_way2_f2[i] ? 2'b10 : 'b0; @@ -746,32 +746,32 @@ logic [3:0] two_hits; // index for (j=0 ; j<4 ; j++) begin : LRUFLOPS - + // mux the write data assign lru_bank_wr_data[i][j] = (exu_mp_valid & mp_bank_decoded[i]) ? mp_new_lru[2:0] : fetch_lru_bank_hit_f2[i] ? fetch_new_lru[i] : 'b0; - + // bank enable if there was a fetch hit or a mispredict // simul mp and fetch, mp has priority assign lru_bank_sel[i][j] = (~exu_mp_valid & fetch_lru_bank_hit_f2[i] & (btb_rd_addr_f2[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO] == j)) | ( exu_mp_valid & mp_bank_decoded[i] & (exu_mp_addr[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO] == j)); - - - rvdffs #(3) lru_bank (.*, + + + rvdffs #(3) lru_bank (.*, .clk (active_clk), .en (lru_bank_sel[i][j]), .din (lru_bank_wr_data[i][j]), .dout (lru_bank_rd_data_out[i][j])); - + end // block: LRUFLOPS end // block: LRUBANKS -always_comb begin : LRU_rd_mux - lru_bank0_rd_data_f2_in[2:0] = '0 ; - lru_bank1_rd_data_f2_in[2:0] = '0 ; - lru_bank2_rd_data_f2_in[2:0] = '0 ; +always_comb begin : LRU_rd_mux + lru_bank0_rd_data_f2_in[2:0] = '0 ; + lru_bank1_rd_data_f2_in[2:0] = '0 ; + lru_bank2_rd_data_f2_in[2:0] = '0 ; lru_bank3_rd_data_f2_in[2:0] = '0 ; for (int j=0; j<4; j++) begin - if (btb_rd_addr_f1[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO] == j) begin + if (btb_rd_addr_f1[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO] == j) begin lru_bank0_rd_data_f2_in[2:0] = lru_bank_rd_data_out[0][j]; lru_bank1_rd_data_f2_in[2:0] = lru_bank_rd_data_out[1][j]; lru_bank2_rd_data_f2_in[2:0] = lru_bank_rd_data_out[2][j]; @@ -779,7 +779,7 @@ always_comb begin : LRU_rd_mux end end end // block: LRU_rd_mux - + rvdffe #(12) lru_dataoutf (.*, .en (ifc_fetch_req_f1), .din ({lru_bank0_rd_data_f2_in[2:0], @@ -835,19 +835,19 @@ end // block: LRU_rd_mux `else - + 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_f2[0]}}) ); - + assign btb_lru_b1_ns[LRU_SIZE-1:0] = ( (btb_lru_b1_hold[LRU_SIZE-1:0] & btb_lru_b1_f[LRU_SIZE-1:0]) | (mp_wrlru_b1[LRU_SIZE-1:0] & {LRU_SIZE{~exu_mp_way}}) | (fetch_wrlru_b1[LRU_SIZE-1:0] & {LRU_SIZE{tag_match_way0_f2[1]}}) ); - + assign btb_lru_b2_ns[LRU_SIZE-1:0] = ( (btb_lru_b2_hold[LRU_SIZE-1:0] & btb_lru_b2_f[LRU_SIZE-1:0]) | (mp_wrlru_b2[LRU_SIZE-1:0] & {LRU_SIZE{~exu_mp_way}}) | (fetch_wrlru_b2[LRU_SIZE-1:0] & {LRU_SIZE{tag_match_way0_f2[2]}}) ); - + assign btb_lru_b3_ns[LRU_SIZE-1:0] = ( (btb_lru_b3_hold[LRU_SIZE-1:0] & btb_lru_b3_f[LRU_SIZE-1:0]) | (mp_wrlru_b3[LRU_SIZE-1:0] & {LRU_SIZE{~exu_mp_way}}) | (fetch_wrlru_b3[LRU_SIZE-1:0] & {LRU_SIZE{tag_match_way0_f2[3]}}) ); @@ -859,27 +859,27 @@ end // block: LRU_rd_mux assign way_raw[7:0] = tag_match_way1_expanded_f2[7:0] | (~wayhit_f2[7:0] & {{2{btb_lru_rd_f2[3]}}, {2{btb_lru_rd_f2[2]}}, {2{btb_lru_rd_f2[1]}}, {2{btb_lru_rd_f2[0]}}}); - rvdffe #(LRU_SIZE*4) btb_lru_ff (.*, .en(ifc_fetch_req_f2 | exu_mp_valid), + rvdffe #(LRU_SIZE*4) btb_lru_ff (.*, .en(ifc_fetch_req_f2 | exu_mp_valid), .din({btb_lru_b0_ns[(LRU_SIZE)-1:0], btb_lru_b1_ns[(LRU_SIZE)-1:0], btb_lru_b2_ns[(LRU_SIZE)-1:0], - btb_lru_b3_ns[(LRU_SIZE)-1:0]}), + btb_lru_b3_ns[(LRU_SIZE)-1:0]}), .dout({btb_lru_b0_f[(LRU_SIZE)-1:0], btb_lru_b1_f[(LRU_SIZE)-1:0], btb_lru_b2_f[(LRU_SIZE)-1:0], btb_lru_b3_f[(LRU_SIZE)-1:0]})); `endif // !`ifdef RV_BTB_48 - + // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- - + // 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_f2; assign { - btb_rd_tgt_f2[11:0], - btb_rd_pc4_f2, + btb_rd_tgt_f2[11:0], + btb_rd_pc4_f2, btb_rd_boffset_f2, btb_rd_call_f2, btb_rd_ret_f2} = btb_sel_data_f2[16:1]; @@ -895,10 +895,10 @@ end // block: LRU_rd_mux logic [7:0] bp_valid_f2, bp_hist1_f2; - + // a valid taken target needs to kill the next fetch as we compute the target address assign ifu_bp_kill_next_f2 = |(bp_valid_f2[7:0] & bp_hist1_f2[7:0]) & ifc_fetch_req_f2 & ~leak_one_f2 & ~dec_tlu_bpred_disable; - + // Don't put calls/rets/ja in the predictor, force the bht taken instead assign bht_force_taken_f2[7:0] = {(btb_bank3o_rd_data_f2[CALL] | btb_bank3o_rd_data_f2[RET]), @@ -909,37 +909,37 @@ end // block: LRU_rd_mux (btb_bank1e_rd_data_f2[CALL] | btb_bank1e_rd_data_f2[RET]), (btb_bank0o_rd_data_f2[CALL] | btb_bank0o_rd_data_f2[RET]), (btb_bank0e_rd_data_f2[CALL] | btb_bank0e_rd_data_f2[RET])}; - + // taken and valid, otherwise, branch errors must clear the bht assign bht_valid_f2[7:0] = wayhit_f2[7:0]; - assign bht_dir_f2[7:0] = {(bht_force_taken_f2[7] | bht_bank7_rd_data_f2[1]) & bht_valid_f2[7], - (bht_force_taken_f2[6] | bht_bank6_rd_data_f2[1]) & bht_valid_f2[6], - (bht_force_taken_f2[5] | bht_bank5_rd_data_f2[1]) & bht_valid_f2[5], - (bht_force_taken_f2[4] | bht_bank4_rd_data_f2[1]) & bht_valid_f2[4], - (bht_force_taken_f2[3] | bht_bank3_rd_data_f2[1]) & bht_valid_f2[3], - (bht_force_taken_f2[2] | bht_bank2_rd_data_f2[1]) & bht_valid_f2[2], + assign bht_dir_f2[7:0] = {(bht_force_taken_f2[7] | bht_bank7_rd_data_f2[1]) & bht_valid_f2[7], + (bht_force_taken_f2[6] | bht_bank6_rd_data_f2[1]) & bht_valid_f2[6], + (bht_force_taken_f2[5] | bht_bank5_rd_data_f2[1]) & bht_valid_f2[5], + (bht_force_taken_f2[4] | bht_bank4_rd_data_f2[1]) & bht_valid_f2[4], + (bht_force_taken_f2[3] | bht_bank3_rd_data_f2[1]) & bht_valid_f2[3], + (bht_force_taken_f2[2] | bht_bank2_rd_data_f2[1]) & bht_valid_f2[2], (bht_force_taken_f2[1] | bht_bank1_rd_data_f2[1]) & bht_valid_f2[1], (bht_force_taken_f2[0] | bht_bank0_rd_data_f2[1]) & bht_valid_f2[0]}; - + // final inst_valid_mask. // vmask[7] is a 0, vmask[0] is a 1, initially // (assumes pc2 with boffset 0) // logic minus1, plus1; - + assign plus1 = ( (~btb_rd_pc4_f2 & btb_rd_boffset_f2 & ~ifc_fetch_addr_f2[1]) | ( btb_rd_pc4_f2 & ~btb_rd_boffset_f2 & ~ifc_fetch_addr_f2[1]) ); - + assign minus1 = ( (~btb_rd_pc4_f2 & ~btb_rd_boffset_f2 & ifc_fetch_addr_f2[1]) | ( btb_rd_pc4_f2 & btb_rd_boffset_f2 & ifc_fetch_addr_f2[1]) ); assign ifu_bp_inst_mask_f2[7:1] = ( ({7{ ifu_bp_kill_next_f2}} & btb_vmask_f2[7:1]) | ({7{~ifu_bp_kill_next_f2}} & 7'b1111111) ); - + logic [7:0] hist0_raw, hist1_raw, pc4_raw, pret_raw; - + // Branch prediction info is sent with the 2byte lane associated with the end of the branch. // Cases @@ -952,7 +952,7 @@ end // block: LRU_rd_mux // <------------> : 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[7:0] = bht_force_taken_f2[7:0] | {bht_bank7_rd_data_f2[1], bht_bank6_rd_data_f2[1], @@ -962,7 +962,7 @@ end // block: LRU_rd_mux bht_bank2_rd_data_f2[1], bht_bank1_rd_data_f2[1], bht_bank0_rd_data_f2[1]}; - + assign hist0_raw[7:0] = {bht_bank7_rd_data_f2[0], bht_bank6_rd_data_f2[0], bht_bank5_rd_data_f2[0], @@ -971,28 +971,28 @@ end // block: LRU_rd_mux bht_bank2_rd_data_f2[0], bht_bank1_rd_data_f2[0], bht_bank0_rd_data_f2[0]}; - - - assign pc4_raw[7:0] = {wayhit_f2[7] & btb_bank3o_rd_data_f2[PC4], + + + assign pc4_raw[7:0] = {wayhit_f2[7] & btb_bank3o_rd_data_f2[PC4], wayhit_f2[6] & btb_bank3e_rd_data_f2[PC4], - wayhit_f2[5] & btb_bank2o_rd_data_f2[PC4], - wayhit_f2[4] & btb_bank2e_rd_data_f2[PC4], - wayhit_f2[3] & btb_bank1o_rd_data_f2[PC4], - wayhit_f2[2] & btb_bank1e_rd_data_f2[PC4], - wayhit_f2[1] & btb_bank0o_rd_data_f2[PC4], + wayhit_f2[5] & btb_bank2o_rd_data_f2[PC4], + wayhit_f2[4] & btb_bank2e_rd_data_f2[PC4], + wayhit_f2[3] & btb_bank1o_rd_data_f2[PC4], + wayhit_f2[2] & btb_bank1e_rd_data_f2[PC4], + wayhit_f2[1] & btb_bank0o_rd_data_f2[PC4], wayhit_f2[0] & btb_bank0e_rd_data_f2[PC4]}; - assign pret_raw[7:0] = {wayhit_f2[3] & ~btb_bank3o_rd_data_f2[CALL] & btb_bank3o_rd_data_f2[RET], + assign pret_raw[7:0] = {wayhit_f2[3] & ~btb_bank3o_rd_data_f2[CALL] & btb_bank3o_rd_data_f2[RET], wayhit_f2[3] & ~btb_bank3e_rd_data_f2[CALL] & btb_bank3e_rd_data_f2[RET], - wayhit_f2[2] & ~btb_bank2o_rd_data_f2[CALL] & btb_bank2o_rd_data_f2[RET], - wayhit_f2[2] & ~btb_bank2e_rd_data_f2[CALL] & btb_bank2e_rd_data_f2[RET], - wayhit_f2[1] & ~btb_bank1o_rd_data_f2[CALL] & btb_bank1o_rd_data_f2[RET], - wayhit_f2[1] & ~btb_bank1e_rd_data_f2[CALL] & btb_bank1e_rd_data_f2[RET], - wayhit_f2[0] & ~btb_bank0o_rd_data_f2[CALL] & btb_bank0o_rd_data_f2[RET], + wayhit_f2[2] & ~btb_bank2o_rd_data_f2[CALL] & btb_bank2o_rd_data_f2[RET], + wayhit_f2[2] & ~btb_bank2e_rd_data_f2[CALL] & btb_bank2e_rd_data_f2[RET], + wayhit_f2[1] & ~btb_bank1o_rd_data_f2[CALL] & btb_bank1o_rd_data_f2[RET], + wayhit_f2[1] & ~btb_bank1e_rd_data_f2[CALL] & btb_bank1e_rd_data_f2[RET], + wayhit_f2[0] & ~btb_bank0o_rd_data_f2[CALL] & btb_bank0o_rd_data_f2[RET], wayhit_f2[0] & ~btb_bank0e_rd_data_f2[CALL] & btb_bank0e_rd_data_f2[RET]}; - + // GHR - + // Figure out how many valid branches are in the fetch group assign fgmask_f2[6] = (~ifc_fetch_addr_f2[1]) | (~ifc_fetch_addr_f2[2]) | ( ~ifc_fetch_addr_f2[3]); @@ -1006,13 +1006,13 @@ assign fgmask_f2[1] = (~ifc_fetch_addr_f2[3] & ~ifc_fetch_addr_f2[2]); assign fgmask_f2[0] = (~ifc_fetch_addr_f2[3] & ~ifc_fetch_addr_f2[2] & ~ifc_fetch_addr_f2[1]); - assign btb_sel_mask_f2[7:0] = {btb_sel_f2[7], - |btb_sel_f2[7:6] & fgmask_f2[6], - |btb_sel_f2[7:5] & fgmask_f2[5], - |btb_sel_f2[7:4] & fgmask_f2[4], - |btb_sel_f2[7:3] & fgmask_f2[3], - |btb_sel_f2[7:2] & fgmask_f2[2], - |btb_sel_f2[7:1] & fgmask_f2[1], + assign btb_sel_mask_f2[7:0] = {btb_sel_f2[7], + |btb_sel_f2[7:6] & fgmask_f2[6], + |btb_sel_f2[7:5] & fgmask_f2[5], + |btb_sel_f2[7:4] & fgmask_f2[4], + |btb_sel_f2[7:3] & fgmask_f2[3], + |btb_sel_f2[7:2] & fgmask_f2[2], + |btb_sel_f2[7:1] & fgmask_f2[1], |btb_sel_f2[7:0] & fgmask_f2[0]}; // count the valids with masking based on first taken @@ -1020,18 +1020,18 @@ assign fgmask_f2[0] = (~ifc_fetch_addr_f2[3] & ~ifc_fetch_addr_f2[2] // 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 + // Num valid branches What new GHR must be // >=4 000H // 3 P00H // 2 PP0H // 1 PPPH // 0 PPPP - + assign final_h = |(btb_sel_f2[7:0] & bht_dir_f2[7:0]); - + assign merged_ghr[`RV_BHT_GHR_RANGE] = ( ({`RV_BHT_GHR_SIZE{num_valids[3:0] >= 4'h4}} & {`RV_BHT_GHR_PAD, final_h }) | // 000H ({`RV_BHT_GHR_SIZE{num_valids[3:0] == 4'h3}} & {`RV_BHT_GHR_PAD2, final_h}) | // P00H -`ifdef RV_BHT_GHR_SIZE_2 +`ifdef RV_BHT_GHR_SIZE_2 ({`RV_BHT_GHR_SIZE{num_valids[3:0] == 4'h2}} & { 1'b0, final_h}) | // PP0H `else ({`RV_BHT_GHR_SIZE{num_valids[3:0] == 4'h2}} & {fghr[`RV_BHT_GHR_SIZE-3:0], 1'b0, final_h}) | // PP0H @@ -1041,14 +1041,14 @@ assign fgmask_f2[0] = (~ifc_fetch_addr_f2[3] & ~ifc_fetch_addr_f2[2] logic [`RV_BHT_GHR_RANGE] exu_flush_ghr; assign exu_flush_ghr[`RV_BHT_GHR_RANGE] = exu_mp_fghr[`RV_BHT_GHR_RANGE]; - + assign fghr_ns[`RV_BHT_GHR_RANGE] = ( ({`RV_BHT_GHR_SIZE{exu_flush_final}} & exu_flush_ghr[`RV_BHT_GHR_RANGE]) | ({`RV_BHT_GHR_SIZE{~exu_flush_final & ifc_fetch_req_f2_raw & ~leak_one_f2}} & merged_ghr[`RV_BHT_GHR_RANGE]) | ({`RV_BHT_GHR_SIZE{~exu_flush_final & ~(ifc_fetch_req_f2_raw & ~leak_one_f2)}} & fghr[`RV_BHT_GHR_RANGE])); rvdff #(`RV_BHT_GHR_SIZE) fetchghr (.*, .clk(active_clk), .din(fghr_ns[`RV_BHT_GHR_RANGE]), .dout(fghr[`RV_BHT_GHR_RANGE])); assign ifu_bp_fghr_f2[`RV_BHT_GHR_RANGE] = fghr[`RV_BHT_GHR_RANGE]; - + `ifdef RV_BTB_48 assign ifu_bp_way_f2 = {fetch_replway_bank7_enc[1:0], @@ -1073,44 +1073,44 @@ assign fgmask_f2[0] = (~ifc_fetch_addr_f2[3] & ~ifc_fetch_addr_f2[2] // Truncate taken and valid, used for detecting a taken branch in the fetch group always_comb begin casez(ifc_fetch_addr_f2[3:1]) - 3'b000 : begin + 3'b000 : begin bp_hist1_f2[7:0] = hist1_raw[7:0]; bp_valid_f2[7:0] = wayhit_f2[7:0]; end - 3'b001 : begin + 3'b001 : begin bp_hist1_f2[7:0] = {1'b0, hist1_raw[7:1]}; bp_valid_f2[7:0] = {1'b0, wayhit_f2[7:1]}; end - 3'b010 : begin + 3'b010 : begin bp_hist1_f2[7:0] = {2'b0, hist1_raw[7:2]}; bp_valid_f2[7:0] = {2'b0, wayhit_f2[7:2]}; end - 3'b011 : begin + 3'b011 : begin bp_hist1_f2[7:0] = {3'b0, hist1_raw[7:3]}; bp_valid_f2[7:0] = {3'b0, wayhit_f2[7:3]}; end - 3'b100 : begin + 3'b100 : begin bp_hist1_f2[7:0] = {4'b0, hist1_raw[7:4]}; bp_valid_f2[7:0] = {4'b0, wayhit_f2[7:4]}; end - 3'b101 : begin + 3'b101 : begin bp_hist1_f2[7:0] = {5'b0, hist1_raw[7:5]}; bp_valid_f2[7:0] = {5'b0, wayhit_f2[7:5]}; end - 3'b110 : begin + 3'b110 : begin bp_hist1_f2[7:0] = {6'b0, hist1_raw[7:6]}; bp_valid_f2[7:0] = {6'b0, wayhit_f2[7:6]}; end - 3'b111 : begin + 3'b111 : begin bp_hist1_f2[7:0] = {7'b0, hist1_raw[7]}; bp_valid_f2[7:0] = {7'b0, wayhit_f2[7]}; end default: begin bp_hist1_f2[7:0] = hist1_raw[7:0]; - bp_valid_f2[7:0] = wayhit_f2[7:0]; - end + bp_valid_f2[7:0] = wayhit_f2[7:0]; + end endcase // casex (ifc_fetch_addr_f1[3:2]) - + end // compute target // Form the fetch group offset based on the btb hit location and the location of the branch within the 4 byte chunk @@ -1119,12 +1119,12 @@ assign fgmask_f2[0] = (~ifc_fetch_addr_f2[3] & ~ifc_fetch_addr_f2[2] wire [2:0] btb_sel_f2_enc, btb_sel_f2_enc_shift; assign btb_sel_f2_enc[2:0] = encode8_3(btb_sel_f2[7:0]); assign btb_sel_f2_enc_shift[2:0] = encode8_3({1'b0,btb_sel_f2[7:1]}); - + assign bp_total_branch_offset_f2[3:1] = (({3{ btb_rd_pc4_f2}} & btb_sel_f2_enc_shift[2:0]) | ({3{~btb_rd_pc4_f2}} & btb_sel_f2_enc[2:0]) | ({3{btb_fg_crossing_f2}})); - + logic [31:4] adder_pc_in_f2, ifc_fetch_adder_prior; rvdffe #(28) faddrf2_ff (.*, .en(ifc_fetch_req_f2 & ~ifu_bp_kill_next_f2 & ic_hit_f2), .din(ifc_fetch_addr_f2[31:4]), .dout(ifc_fetch_adder_prior[31:4])); @@ -1132,24 +1132,24 @@ assign fgmask_f2[0] = (~ifc_fetch_addr_f2[3] & ~ifc_fetch_addr_f2[2] assign adder_pc_in_f2[31:4] = ( ({28{ btb_fg_crossing_f2}} & ifc_fetch_adder_prior[31:4]) | ({28{~btb_fg_crossing_f2}} & ifc_fetch_addr_f2[31:4])); - + rvbradder predtgt_addr (.pc({adder_pc_in_f2[31:4], bp_total_branch_offset_f2[3:1]}), .offset(btb_rd_tgt_f2[11:0]), - .dout(bp_btb_target_adder_f2[31:1]) + .dout(bp_btb_target_adder_f2[31:1]) ); // mux in the return stack address here for a predicted return assign ifu_bp_btb_target_f2[31:1] = btb_rd_ret_f2 & ~btb_rd_call_f2 ? rets_out[0][31:1] : bp_btb_target_adder_f2[31:1]; // ---------------------------------------------------------------------- - // Return Stack + // Return Stack // ---------------------------------------------------------------------- rvbradder rs_addr (.pc({adder_pc_in_f2[31:4], bp_total_branch_offset_f2[3:1]}), .offset({10'b0, btb_rd_pc4_f2, ~btb_rd_pc4_f2}), - .dout(bp_rs_call_target_f2[31:1]) + .dout(bp_rs_call_target_f2[31:1]) ); - + // Calls/Rets are always taken, so there shouldn't be a push and pop in the same fetch group logic rs_overpop_correct, rsoverpop_valid_ns, rsoverpop_valid_f; logic [31:1] rsoverpop_ns, rsoverpop_f; @@ -1177,60 +1177,60 @@ assign fgmask_f2[0] = (~ifc_fetch_addr_f2[3] & ~ifc_fetch_addr_f2[2] assign e4_rs_correct = 1'b0; assign rs_correct = 1'b0; `endif - + assign rs_push = ((btb_rd_call_f2 & ~btb_rd_ret_f2 & ifu_bp_kill_next_f2) | (rs_overpop_correct & ~rs_underpop_correct)) & ~rs_correct & ~e4_rs_correct; assign rs_pop = ((btb_rd_ret_f2 & ~btb_rd_call_f2 & ifu_bp_kill_next_f2) | (rs_underpop_correct & ~rs_overpop_correct)) & ~rs_correct & ~e4_rs_correct; assign rs_hold = ~rs_push & ~rs_pop & ~rs_overpop_correct & ~rs_underpop_correct & ~rs_correct & ~e4_rs_correct; - - // Fetch based + + // Fetch based assign rets_in[0][31:1] = ( ({31{rs_overpop_correct & rs_underpop_correct}} & rsoverpop_f[31:1]) | ({31{rs_push & rs_overpop_correct}} & rsoverpop_f[31:1]) | ({31{rs_push & ~rs_overpop_correct}} & bp_rs_call_target_f2[31:1]) | -`ifdef REAL_COMM_RS +`ifdef REAL_COMM_RS ({31{rs_correct}} & e1_rets_out[0][31:1]) | ({31{e4_rs_correct}} & e4_rets_out[0][31:1]) | -`endif +`endif ({31{rs_pop}} & rets_out[1][31:1]) ); assign rsenable[0] = ~rs_hold; - + for (i=0; i<`RV_RET_STACK_SIZE; i++) begin : retstack // for the last entry in the stack, we don't have a pop position - if(i==`RV_RET_STACK_SIZE-1) begin -`ifdef REAL_COMM_RS + if(i==`RV_RET_STACK_SIZE-1) begin +`ifdef REAL_COMM_RS assign rets_in[i][31:1] = ( ({31{rs_push}} & rets_out[i-1][31:1]) | ({31{rs_correct}} & e1_rets_out[i][31:1]) | ({31{e4_rs_correct}} & e4_rets_out[i][31:1]) ); `else assign rets_in[i][31:1] = rets_out[i-1][31:1]; -`endif +`endif assign rsenable[i] = rs_push | rs_correct | e4_rs_correct; end else if(i>0) begin -`ifdef REAL_COMM_RS +`ifdef REAL_COMM_RS assign rets_in[i][31:1] = ( ({31{rs_push}} & rets_out[i-1][31:1]) | ({31{rs_pop}} & rets_out[i+1][31:1]) | ({31{rs_correct}} & e1_rets_out[i][31:1]) | ({31{e4_rs_correct}} & e4_rets_out[i][31:1]) ); -`else +`else assign rets_in[i][31:1] = ( ({31{rs_push}} & rets_out[i-1][31:1]) | ({31{rs_pop}} & rets_out[i+1][31:1]) ); -`endif +`endif assign rsenable[i] = rs_push | rs_pop | rs_correct | e4_rs_correct; - end + end rvdffe #(31) rets_ff (.*, .en(rsenable[i]), .din(rets_in[i][31:1]), .dout(rets_out[i][31:1])); end : retstack - + `ifdef REAL_COMM_RS logic [31:1] e1_rs_call0_target_f2, e1_rs_call1_target_f2, e1_rs_call_target_f2, e4_rs_call0_target_f2, e4_rs_call1_target_f2, e4_rs_call_target_f2; logic e1_null, e1_rs_push1, e1_rs_push2, e1_rs_pop1, e1_rs_pop2, e1_rs_hold; logic e4_null, e4_rs_push1, e4_rs_push2, e4_rs_pop1, e4_rs_pop2, e4_rs_hold; - // E1 based + // E1 based assign e4_rs_correct = dec_tlu_flush_lower_wb; assign e1_null = exu_rets_e1_pkt.pc0_call & exu_rets_e1_pkt.pc1_ret; assign e1_rs_push1 = (exu_rets_e1_pkt.pc0_call ^ exu_rets_e1_pkt.pc1_call) & ~e1_null & ~e4_rs_correct; @@ -1241,15 +1241,15 @@ assign fgmask_f2[0] = (~ifc_fetch_addr_f2[3] & ~ifc_fetch_addr_f2[2] rvbradder e1_rs_addr0 (.pc({exu_i0_pc_e1[31:1]}), .offset({10'b0, exu_rets_e1_pkt.pc0_pc4, ~exu_rets_e1_pkt.pc0_pc4}), - .dout(e1_rs_call0_target_f2[31:1]) + .dout(e1_rs_call0_target_f2[31:1]) ); rvbradder e1_rs_addr1 (.pc({exu_i1_pc_e1[31:1]}), .offset({10'b0, exu_rets_e1_pkt.pc1_pc4, ~exu_rets_e1_pkt.pc1_pc4}), - .dout(e1_rs_call1_target_f2[31:1]) + .dout(e1_rs_call1_target_f2[31:1]) ); assign e1_rs_call_target_f2[31:1] = exu_rets_e1_pkt.pc0_call ? e1_rs_call0_target_f2[31:1] : e1_rs_call1_target_f2[31:1]; - + assign e1_rets_in[0][31:1] = ( ({31{e1_rs_push1}} & e1_rs_call_target_f2[31:1]) | ({31{e1_rs_push2}} & e1_rs_call1_target_f2[31:1]) | ({31{e1_rs_pop1}} & e1_rets_out[1][31:1]) | @@ -1268,7 +1268,7 @@ assign fgmask_f2[0] = (~ifc_fetch_addr_f2[3] & ~ifc_fetch_addr_f2[2] for (i=0; i<`RV_RET_STACK_SIZE; i++) begin : e1_retstack // for the last entry in the stack, we don't have a pop position - if(i==`RV_RET_STACK_SIZE-1) + if(i==`RV_RET_STACK_SIZE-1) assign e1_rets_in[i][31:1] = ( ({31{e1_rs_push1}} & e1_rets_out[i-1][31:1]) | ({31{e1_rs_push2}} & e1_rets_out[i-2][31:1]) | ({31{e4_rs_correct}} & e4_rets_out[i][31:1]) | @@ -1279,7 +1279,7 @@ assign fgmask_f2[0] = (~ifc_fetch_addr_f2[3] & ~ifc_fetch_addr_f2[2] ({31{e1_rs_pop1}} & e1_rets_out[i+1][31:1]) | ({31{e4_rs_correct}} & e4_rets_out[i][31:1]) | ({31{e1_rs_hold}} & e1_rets_out[i][31:1]) ); - + else if(i>1) assign e1_rets_in[i][31:1] = ( ({31{e1_rs_push1}} & e1_rets_out[i-1][31:1]) | ({31{e1_rs_push2}} & e1_rets_out[i-2][31:1]) | @@ -1288,12 +1288,12 @@ assign fgmask_f2[0] = (~ifc_fetch_addr_f2[3] & ~ifc_fetch_addr_f2[2] ({31{e4_rs_correct}} & e4_rets_out[i][31:1]) | ({31{e1_rs_hold}} & e1_rets_out[i][31:1]) ); - + rvdff #(31) e1_rets_ff (.*, .din(e1_rets_in[i][31:1]), .dout(e1_rets_out[i][31:1])); end : e1_retstack - // E4 based + // E4 based assign e4_null = exu_rets_e4_pkt.pc0_call & exu_rets_e4_pkt.pc1_ret; assign e4_rs_push1 = (exu_rets_e4_pkt.pc0_call ^ exu_rets_e4_pkt.pc1_call) & ~e4_null; assign e4_rs_push2 = (exu_rets_e4_pkt.pc0_call & exu_rets_e4_pkt.pc1_call); @@ -1303,15 +1303,15 @@ assign fgmask_f2[0] = (~ifc_fetch_addr_f2[3] & ~ifc_fetch_addr_f2[2] rvbradder e4_rs_addr0 (.pc({dec_tlu_i0_pc_e4[31:1]}), .offset({10'b0, exu_rets_e4_pkt.pc0_pc4, ~exu_rets_e4_pkt.pc0_pc4}), - .dout(e4_rs_call0_target_f2[31:1]) + .dout(e4_rs_call0_target_f2[31:1]) ); rvbradder e4_rs_addr1 (.pc({dec_tlu_i1_pc_e4[31:1]}), .offset({10'b0, exu_rets_e4_pkt.pc1_pc4, ~exu_rets_e4_pkt.pc1_pc4}), - .dout(e4_rs_call1_target_f2[31:1]) + .dout(e4_rs_call1_target_f2[31:1]) ); assign e4_rs_call_target_f2[31:1] = exu_rets_e4_pkt.pc0_call ? e4_rs_call0_target_f2[31:1] : e4_rs_call1_target_f2[31:1]; - + assign e4_rets_in[0][31:1] = ( ({31{e4_rs_push1}} & e4_rs_call_target_f2[31:1]) | ({31{e4_rs_push2}} & e4_rs_call1_target_f2[31:1]) | ({31{e4_rs_pop1}} & e4_rets_out[1][31:1]) | @@ -1328,7 +1328,7 @@ assign fgmask_f2[0] = (~ifc_fetch_addr_f2[3] & ~ifc_fetch_addr_f2[2] for (i=0; i<`RV_RET_STACK_SIZE; i++) begin : e4_retstack // for the last entry in the stack, we don't have a pop position - if(i==`RV_RET_STACK_SIZE-1) + if(i==`RV_RET_STACK_SIZE-1) assign e4_rets_in[i][31:1] = ( ({31{e4_rs_push1}} & e4_rets_out[i-1][31:1]) | ({31{e4_rs_push2}} & e4_rets_out[i-2][31:1]) | ({31{e4_rs_hold}} & e4_rets_out[i][31:1]) ); @@ -1337,7 +1337,7 @@ assign fgmask_f2[0] = (~ifc_fetch_addr_f2[3] & ~ifc_fetch_addr_f2[2] ({31{e4_rs_push2}} & e4_rets_out[i-2][31:1]) | ({31{e4_rs_pop1}} & e4_rets_out[i+1][31:1]) | ({31{e4_rs_hold}} & e4_rets_out[i][31:1]) ); - + else if(i>1) assign e4_rets_in[i][31:1] = ( ({31{e4_rs_push1}} & e4_rets_out[i-1][31:1]) | ({31{e4_rs_push2}} & e4_rets_out[i-2][31:1]) | @@ -1345,47 +1345,47 @@ assign fgmask_f2[0] = (~ifc_fetch_addr_f2[3] & ~ifc_fetch_addr_f2[2] ({31{e4_rs_pop2}} & e4_rets_out[i+2][31:1]) | ({31{e4_rs_hold}} & e4_rets_out[i][31:1]) ); - + rvdff #(31) e4_rets_ff (.*, .din(e4_rets_in[i][31:1]), .dout(e4_rets_out[i][31:1])); end : e4_retstack `endif // `ifdef REAL_COMM_RS - + // ---------------------------------------------------------------------- // WRITE // ---------------------------------------------------------------------- - + assign dec_tlu_error_wb = dec_tlu_br0_start_error_wb | dec_tlu_br0_error_wb | dec_tlu_br1_start_error_wb | dec_tlu_br1_error_wb; assign dec_tlu_all_banks_error_wb = dec_tlu_br0_start_error_wb | (~dec_tlu_br0_error_wb & dec_tlu_br1_start_error_wb); assign dec_tlu_error_bank_wb[1:0] = (dec_tlu_br0_error_wb | dec_tlu_br0_start_error_wb) ? dec_tlu_br0_bank_wb[1:0] : dec_tlu_br1_bank_wb[1:0]; assign btb_error_addr_wb[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO] = (dec_tlu_br0_error_wb | dec_tlu_br0_start_error_wb) ? dec_tlu_br0_addr_wb[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO] : dec_tlu_br1_addr_wb[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO]; - assign dec_tlu_way_wb = (dec_tlu_br0_error_wb | dec_tlu_br0_start_error_wb) ? dec_tlu_br0_way_wb : dec_tlu_br1_way_wb; + assign dec_tlu_way_wb = (dec_tlu_br0_error_wb | dec_tlu_br0_start_error_wb) ? dec_tlu_br0_way_wb : dec_tlu_br1_way_wb; assign btb_valid = exu_mp_valid & ~dec_tlu_error_wb; assign btb_wr_tag[`RV_BTB_BTAG_SIZE-1:0] = exu_mp_btag[`RV_BTB_BTAG_SIZE-1:0]; rvbtb_tag_hash rdtagf1(.hash(fetch_rd_tag_f1[`RV_BTB_BTAG_SIZE-1:0]), .pc({ifc_fetch_addr_f1[31:4], 3'b0})); rvdff #(`RV_BTB_BTAG_SIZE) rdtagf (.*, .clk(active_clk), .din({fetch_rd_tag_f1[`RV_BTB_BTAG_SIZE-1:0]}), .dout({fetch_rd_tag_f2[`RV_BTB_BTAG_SIZE-1:0]})); - + assign btb_wr_data[16+`RV_BTB_BTAG_SIZE:0] = {btb_wr_tag[`RV_BTB_BTAG_SIZE-1:0], exu_mp_tgt[11: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; -`ifdef RV_BTB_48 +`ifdef RV_BTB_48 assign btb_wr_en_way0[3:0] = ( ({4{(exu_mp_way==2'b0) & exu_mp_valid_write & ~dec_tlu_error_wb}} & decode2_4(exu_mp_bank[1:0])) | ({4{(dec_tlu_way_wb==2'b0) & dec_tlu_error_wb & ~dec_tlu_all_banks_error_wb}} & decode2_4(dec_tlu_error_bank_wb[1:0])) | ({4{(dec_tlu_way_wb==2'b0) & dec_tlu_all_banks_error_wb}})); - + assign btb_wr_en_way1[3:0] = ( ({4{exu_mp_way[0] & exu_mp_valid_write & ~dec_tlu_error_wb}} & decode2_4(exu_mp_bank[1:0])) | ({4{dec_tlu_way_wb[0] & dec_tlu_error_wb & ~dec_tlu_all_banks_error_wb}} & decode2_4(dec_tlu_error_bank_wb[1:0])) | ({4{dec_tlu_way_wb[0] & dec_tlu_all_banks_error_wb}})); - + assign btb_wr_en_way2[3:0] = ( ({4{exu_mp_way[1] & exu_mp_valid_write & ~dec_tlu_error_wb}} & decode2_4(exu_mp_bank[1:0])) | ({4{dec_tlu_way_wb[1] & dec_tlu_error_wb & ~dec_tlu_all_banks_error_wb}} & decode2_4(dec_tlu_error_bank_wb[1:0])) | ({4{dec_tlu_way_wb[1] & dec_tlu_all_banks_error_wb}})); @@ -1393,14 +1393,14 @@ assign fgmask_f2[0] = (~ifc_fetch_addr_f2[3] & ~ifc_fetch_addr_f2[2] assign btb_wr_en_way0[3:0] = ( ({4{~exu_mp_way & exu_mp_valid_write & ~dec_tlu_error_wb}} & decode2_4(exu_mp_bank[1:0])) | ({4{~dec_tlu_way_wb & dec_tlu_error_wb & ~dec_tlu_all_banks_error_wb}} & decode2_4(dec_tlu_error_bank_wb[1:0])) | ({4{~dec_tlu_way_wb & dec_tlu_all_banks_error_wb}})); - + assign btb_wr_en_way1[3:0] = ( ({4{exu_mp_way & exu_mp_valid_write & ~dec_tlu_error_wb}} & decode2_4(exu_mp_bank[1:0])) | ({4{dec_tlu_way_wb & dec_tlu_error_wb & ~dec_tlu_all_banks_error_wb}} & decode2_4(dec_tlu_error_bank_wb[1:0])) | ({4{dec_tlu_way_wb & dec_tlu_all_banks_error_wb}})); - - + + `endif - + assign btb_wr_addr[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO] = dec_tlu_error_wb ? btb_error_addr_wb[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO] : exu_mp_addr[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO]; logic [1:0] bht_wr_data0, bht_wr_data1, bht_wr_data2; @@ -1411,10 +1411,10 @@ assign fgmask_f2[0] = (~ifc_fetch_addr_f2[3] & ~ifc_fetch_addr_f2[2] assign bht_wr_en1[7:0] = {8{dec_tlu_br1_v_wb}} & decode3_8({dec_tlu_br1_bank_wb[1:0], dec_tlu_br1_middle_wb}); assign bht_wr_en2[7:0] = {8{dec_tlu_br0_v_wb}} & decode3_8({dec_tlu_br0_bank_wb[1:0], 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 + // 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_data1[1:0] = dec_tlu_br1_hist_wb[1:0]; - assign bht_wr_data2[1:0] = dec_tlu_br0_hist_wb[1:0]; // highest priority + assign bht_wr_data2[1:0] = dec_tlu_br0_hist_wb[1:0]; // highest priority @@ -1431,74 +1431,74 @@ assign fgmask_f2[0] = (~ifc_fetch_addr_f2[3] & ~ifc_fetch_addr_f2[2] assign bht_wr_addr2[`RV_BHT_ADDR_HI:`RV_BHT_ADDR_LO] = br0_hashed_wb[`RV_BHT_ADDR_HI:`RV_BHT_ADDR_LO]; assign bht_rd_addr_f1[`RV_BHT_ADDR_HI:`RV_BHT_ADDR_LO] = bht_rd_addr_hashed_f1[`RV_BHT_ADDR_HI:`RV_BHT_ADDR_LO]; - + // ---------------------------------------------------------------------- - // Structures. Using FLOPS + // Structures. Using FLOPS // ---------------------------------------------------------------------- // BTB // Entry -> tag[`RV_BTB_BTAG_SIZE-1:0], toffset[11:0], pc4, boffset, call, ret, valid - - + + for (j=0 ; j direction, strength - // + // //----------------------------------------------------------------------------- logic [7:0] [(`RV_BHT_ARRAY_DEPTH/NUM_BHT_LOOP)-1:0][NUM_BHT_LOOP-1:0][1:0] bht_bank_wr_data ; logic [7:0] [`RV_BHT_ARRAY_DEPTH-1:0] [1:0] bht_bank_rd_data_out ; - logic [1:0] bht_bank0_rd_data_f2_in, bht_bank1_rd_data_f2_in, bht_bank2_rd_data_f2_in, bht_bank3_rd_data_f2_in; - logic [1:0] bht_bank4_rd_data_f2_in, bht_bank5_rd_data_f2_in, bht_bank6_rd_data_f2_in, bht_bank7_rd_data_f2_in; + logic [1:0] bht_bank0_rd_data_f2_in, bht_bank1_rd_data_f2_in, bht_bank2_rd_data_f2_in, bht_bank3_rd_data_f2_in; + logic [1:0] bht_bank4_rd_data_f2_in, bht_bank5_rd_data_f2_in, bht_bank6_rd_data_f2_in, bht_bank7_rd_data_f2_in; logic [7:0] [(`RV_BHT_ARRAY_DEPTH/NUM_BHT_LOOP)-1:0] bht_bank_clken ; logic [7:0] [(`RV_BHT_ARRAY_DEPTH/NUM_BHT_LOOP)-1:0] bht_bank_clk ; logic [7:0] [(`RV_BHT_ARRAY_DEPTH/NUM_BHT_LOOP)-1:0][NUM_BHT_LOOP-1:0] bht_bank_sel ; - for ( i=0; i<8; i++) begin : BANKS + for ( i=0; i<8; i++) begin : BANKS for (genvar k=0 ; k < (`RV_BHT_ARRAY_DEPTH)/NUM_BHT_LOOP ; k++) begin : BHT_CLK_GROUP - assign bht_bank_clken[i][k] = (bht_wr_en0[i] & ((bht_wr_addr0[`RV_BHT_ADDR_HI: NUM_BHT_LOOP_OUTER_LO]==k) | BHT_NO_ADDR_MATCH)) | - (bht_wr_en1[i] & ((bht_wr_addr1[`RV_BHT_ADDR_HI: NUM_BHT_LOOP_OUTER_LO]==k) | BHT_NO_ADDR_MATCH)) | - (bht_wr_en2[i] & ((bht_wr_addr2[`RV_BHT_ADDR_HI: NUM_BHT_LOOP_OUTER_LO]==k) | BHT_NO_ADDR_MATCH)); + assign bht_bank_clken[i][k] = (bht_wr_en0[i] & ((bht_wr_addr0[`RV_BHT_ADDR_HI: NUM_BHT_LOOP_OUTER_LO]==k) | BHT_NO_ADDR_MATCH)) | + (bht_wr_en1[i] & ((bht_wr_addr1[`RV_BHT_ADDR_HI: NUM_BHT_LOOP_OUTER_LO]==k) | BHT_NO_ADDR_MATCH)) | + (bht_wr_en2[i] & ((bht_wr_addr2[`RV_BHT_ADDR_HI: NUM_BHT_LOOP_OUTER_LO]==k) | BHT_NO_ADDR_MATCH)); rvclkhdr bht_bank_grp_cgc ( .en(bht_bank_clken[i][k]), .l1clk(bht_bank_clk[i][k]), .* ); - + for (j=0 ; j F1 -> F2 -> A //******************************************************************************** -module ifu_mem_ctl +module ifu_mem_ctl import swerv_types::*; ( input logic clk, @@ -29,25 +29,25 @@ module ifu_mem_ctl input logic active_clk, // Active always except during pause input logic rst_l, - input logic exu_flush_final, // Flush from the pipeline. - input logic dec_tlu_flush_err_wb, // Flush from the pipeline due to perr. - + input logic exu_flush_final, // Flush from the pipeline. + input logic dec_tlu_flush_err_wb, // Flush from the pipeline due to perr. + input logic [31:1] fetch_addr_f1, // Fetch Address byte aligned always. F1 stage. input logic ifc_fetch_uncacheable_f1, // The fetch request is uncacheable space. F1 stage input logic ifc_fetch_req_f1, // Fetch request. Comes with the address. F1 stage input logic ifc_fetch_req_f1_raw, // Fetch request without some qualifications. Used for clock-gating. F1 stage - input logic ifc_iccm_access_f1, // This request is to the ICCM. Do not generate misses to the bus. - input logic ifc_region_acc_fault_f1, // 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 ifc_iccm_access_f1, // This request is to the ICCM. Do not generate misses to the bus. + input logic ifc_region_acc_fault_f1, // 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 [16:6] ifu_icache_error_index, // Index with parity/ecc error - input logic ifu_icache_error_val, // Parity/Ecc error - input logic ifu_icache_sb_error_val, // single bit iccm error + input logic ifu_icache_error_val, // Parity/Ecc error + input logic ifu_icache_sb_error_val, // single bit iccm error input logic [7:1] ifu_bp_inst_mask_f2, // 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_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. @@ -57,7 +57,7 @@ module ifu_mem_ctl 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 + output logic ifu_pmu_bus_trxn, // Bus transaction // AXI Write Channels - IFU never writes. So, 0 out mostly output logic ifu_axi_awvalid, @@ -72,19 +72,19 @@ module ifu_mem_ctl 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 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 [`RV_IFU_BUS_TAG-1:0] ifu_axi_bid, - - // AXI Read Channels + + // AXI Read Channels output logic ifu_axi_arvalid, input logic ifu_axi_arready, output logic [`RV_IFU_BUS_TAG-1:0] ifu_axi_arid, @@ -97,7 +97,7 @@ module ifu_mem_ctl output logic [3:0] ifu_axi_arcache, output logic [2:0] ifu_axi_arprot, output logic [3:0] ifu_axi_arqos, - + input logic ifu_axi_rvalid, output logic ifu_axi_rready, input logic [`RV_IFU_BUS_TAG-1:0] ifu_axi_rid, @@ -109,87 +109,87 @@ module ifu_mem_ctl input logic ifu_bus_clk_en, - input logic dma_iccm_req, // dma iccm command (read or write) + 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 - - 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 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 iccm_ready, // iccm ready to accept new command. -// I$ & ITAG Ports - output logic [31:3] ic_rw_addr, // Read/Write addresss to the Icache. +// I$ & ITAG Ports + output logic [31:3] ic_rw_addr, // Read/Write addresss to the Icache. output logic [3:0] ic_wr_en, // Icache write enable, when filling the Icache. output logic ic_rd_en, // Icache read enable. `ifdef RV_ICACHE_ECC output logic [83:0] ic_wr_data, // Data to fill to the Icache. With ECC input logic [167:0] ic_rd_data , // Data read from Icache. 2x64bits + parity bits. F2 stage. With ECC - input logic [24:0] ictag_debug_rd_data,// Debug icache tag. - output logic [41:0] ic_debug_wr_data, // Debug wr cache. + input logic [24:0] ictag_debug_rd_data,// Debug icache tag. + output logic [41:0] ic_debug_wr_data, // Debug wr cache. output logic [41:0] ifu_ic_debug_rd_data, // debug data read -`else +`else output logic [67:0] ic_wr_data, // Data to fill to the Icache. With Parity input logic [135:0] ic_rd_data , // Data read from Icache. 2x64bits + parity bits. F2 stage. With Parity - input logic [20:0] ictag_debug_rd_data,// Debug icache tag. - output logic [33:0] ic_debug_wr_data, // Debug wr cache. + input logic [20:0] ictag_debug_rd_data,// Debug icache tag. + output logic [33:0] ic_debug_wr_data, // Debug wr cache. output logic [33:0] ifu_ic_debug_rd_data, // debug data read `endif - output logic [15:2] ic_debug_addr, // Read/Write addresss to the Icache. + output logic [15:2] 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 [3:0] ic_debug_way, // Debug way. Rd or Wr. - output logic [3:0] ic_tag_valid, // Valid bits when accessing the Icache. One valid bit per way. F2 stage - - input logic [3:0] ic_rd_hit, // Compare hits from Icache tags. Per way. F2 stage + output logic [3:0] ic_tag_valid, // Valid bits when accessing the Icache. One valid bit per way. F2 stage + + input logic [3:0] ic_rd_hit, // Compare hits from Icache tags. Per way. F2 stage input logic ic_tag_perr, // Icache Tag parity error `ifdef RV_ICCM_ENABLE - // ICCM ports + // ICCM ports output logic [`RV_ICCM_BITS-1:2] 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. - + output logic [2:0] iccm_wr_size, // ICCM write location within DW. + input logic [155:0] iccm_rd_data, // Data read from ICCM. `endif - + // IFU control signals - output logic ic_hit_f2, // Hit in Icache(if Icache access) or ICCM access( ICCM always has ic_hit_f2) + output logic ic_hit_f2, // Hit in Icache(if Icache access) or ICCM access( ICCM always has ic_hit_f2) output logic ic_crit_wd_rdy, // Critical fetch is ready to be bypassed. - output logic ic_access_fault_f2, // Access fault (bus error or ICCM access in region but out of offset range). - output logic ic_rd_parity_final_err, // This fetch has an tag parity error. - output logic iccm_rd_ecc_single_err, // This fetch has a single ICCM ecc error. - output logic iccm_rd_ecc_double_err, // This fetch has a double ICCM ecc error. + output logic ic_access_fault_f2, // Access fault (bus error or ICCM access in region but out of offset range). + output logic ic_rd_parity_final_err, // This fetch has an tag parity error. + output logic iccm_rd_ecc_single_err, // This fetch has a single ICCM ecc error. + output logic iccm_rd_ecc_double_err, // This fetch has a double ICCM ecc error. output logic iccm_dma_sb_error, // Single Bit ECC error from a DMA access output logic [7:0] ic_fetch_val_f2, // valid bytes for fetch. To the Aligner. - output logic [127:0] ic_data_f2, // Data read from Icache or ICCM. To the Aligner. - output icache_err_pkt_t ic_error_f2 , // Parity or ECC bits for the Icache Data + output logic [127:0] ic_data_f2, // Data read from Icache or ICCM. To the Aligner. + output icache_err_pkt_t ic_error_f2 , // Parity or ECC bits for the Icache Data output logic ifu_icache_fetch_f2 , - output logic [127:0] ic_premux_data, // Premuxed data to be muxed with Icache data + output logic [127:0] ic_premux_data, // Premuxed data to be muxed with Icache data output logic ic_sel_premux_data, // Select premux data. - -///// Debug + +///// Debug input 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 + input logic dec_tlu_core_ecc_disable, // disable the ecc checking and flagging output logic ifu_ic_debug_rd_data_valid, // debug data valid. - - - input logic scan_mode + + + input logic scan_mode ); `include "global.h" - + // Create different defines for ICACHE and ICCM enable combinations `ifdef RV_ICCM_ENABLE `ifdef RV_ICACHE_ENABLE @@ -204,7 +204,7 @@ module ifu_mem_ctl `define NOT_ICCM_AND_NOT_ICACHE `endif `endif - + localparam NUM_OF_BEATS = 8 ; @@ -227,7 +227,7 @@ module ifu_mem_ctl logic reset_tag_valid_for_miss ; - + logic [2:0] way_status; logic [2:0] way_status_mb_in; logic [2:0] way_status_rep_new; @@ -237,7 +237,7 @@ module ifu_mem_ctl logic [2:0] way_status_new_w_debug; logic [3:0] tagv_mb_in; logic [3:0] tagv_mb_ff; - + logic ifu_wr_data_comb_err ; logic ifu_wr_data_error; @@ -252,17 +252,17 @@ module ifu_mem_ctl logic ifc_iccm_access_f2 ; logic ifc_region_acc_fault_f2; logic ifc_bus_acc_fault_f2; - logic ic_act_miss_f2; - logic ic_miss_under_miss_f2; - logic ic_act_hit_f2; - logic miss_pending; + logic ic_act_miss_f2; + logic ic_miss_under_miss_f2; + logic ic_act_hit_f2; + logic miss_pending; logic [31:1] imb_in , imb_ff ; logic flush_final_f2; logic ifc_fetch_req_f2; logic ifc_fetch_req_f2_raw; logic fetch_req_f2_qual ; logic ifc_fetch_req_qual_f1 ; - logic [3:0] replace_way_mb_any; + logic [3:0] replace_way_mb_any; logic last_beat; logic reset_beat_cnt ; logic [2:0] req_addr_count ; @@ -273,12 +273,12 @@ module ifu_mem_ctl logic ic_crit_wd_rdy_in ; logic crit_wd_byp_ok_ff ; logic ic_crit_wd_rdy_ff; - logic ic_byp_hit_f2 ; + logic ic_byp_hit_f2 ; logic ic_valid ; logic ic_valid_ff; logic reset_all_tags; logic ic_valid_w_debug; - + logic [3:0] ifu_tag_wren,ifu_tag_wren_ff; logic [3:0] ic_debug_tag_wr_en; logic [3:0] ifu_tag_wren_w_debug; @@ -293,7 +293,7 @@ module ifu_mem_ctl logic reset_ic_in ; logic reset_ic_ff ; logic [3:1] vaddr_f2 ; - logic [31:1] ifu_status_wr_addr; + logic [31:1] ifu_status_wr_addr; logic sel_fetch_u_miss; logic sel_fetch_u_miss_ff; logic sel_mb_addr ; @@ -311,9 +311,9 @@ module ifu_mem_ctl logic [1:0] ic_debug_way_enc; logic [127:0] ic_byp_data_only; logic [127:0] ic_rd_data_only; - + logic [`RV_IFU_BUS_TAG-1:0] ifu_axi_rid_ff; - + logic fetch_req_icache_f2; logic fetch_req_iccm_f2; logic ic_iccm_hit_f2; @@ -337,11 +337,11 @@ module ifu_mem_ctl logic debug_data_clk; logic debug_data_clken; logic ifc_region_acc_fault_final_f1, ifc_region_acc_fault_memory, ifc_region_acc_okay; - - -`ifdef RV_ICACHE_ECC - logic [19:0] ic_wr_ecc; - logic [3:0] [1:0] ic_wr_ecc0_unused; // bit 6:5 are not used for a the 16bit sedded + + +`ifdef RV_ICACHE_ECC + logic [19:0] ic_wr_ecc; + logic [3:0] [1:0] ic_wr_ecc0_unused; // bit 6:5 are not used for a the 16bit sedded `else logic [3:0] ic_wr_parity; @@ -360,45 +360,51 @@ module ifu_mem_ctl assign ifu_axi_awburst[1:0] = '0; assign ifu_axi_awqos[3:0] = '0; assign ifu_axi_awlock = '0; - // AXI Write Data Channel + // AXI Write Data Channel assign ifu_axi_wvalid = '0; assign ifu_axi_wdata[63:0] = '0; assign ifu_axi_wstrb[7:0] = '0; assign ifu_axi_wlast = '1; - // AXI Write Response Channel + // AXI Write Response Channel assign ifu_axi_bready = '1; - + // ---- Clock gating section ----- // c1 clock enables - - assign fetch_f1_f2_c1_clken = ifc_fetch_req_f1_raw | ifc_fetch_req_f2 | miss_pending | exu_flush_final ; - assign debug_c1_clken = ic_debug_rd_en | ic_debug_wr_en ; - // C1 - 1 clock pulse for data + + assign fetch_f1_f2_c1_clken = ifc_fetch_req_f1_raw | ifc_fetch_req_f2 | miss_pending | exu_flush_final ; + assign debug_c1_clken = ic_debug_rd_en | ic_debug_wr_en ; + // C1 - 1 clock pulse for data rvclkhdr fetch_f1_f2_c1_cgc ( .en(fetch_f1_f2_c1_clken), .l1clk(fetch_f1_f2_c1_clk), .* ); rvclkhdr debug_c1_cgc ( .en(debug_c1_clken), .l1clk(debug_c1_clk), .* ); - + // ------ end clock gating section ------------------------ - logic [ICCM_BITS-1:2] iccm_ecc_corr_index_ff; + logic [ICCM_BITS-1:2] iccm_ecc_corr_index_ff; logic [38:0] iccm_ecc_corr_data_ff; logic iccm_ecc_write_status ; logic iccm_correct_ecc ; logic iccm_rd_ecc_single_err_ff ; logic perr_state_en; logic [7:0] fetch_mask, ic_fetch_mem_val, bp_mask, ic_bp_mem_mask, ic_fetch_val_mem_f2; + logic dma_iccm_rd_req_f1; + logic dma_iccm_rd_req_f2; + logic [3:0] iccm_single_ecc_error; + + assign dma_iccm_rd_req_f1 = (dma_iccm_req & ~dma_mem_write) ; + rvdff #(1) dma_iccm_req_ff (.*, .clk(free_clk), .din (dma_iccm_rd_req_f1), .dout(dma_iccm_rd_req_f2)); + + assign iccm_dma_sb_error = (|iccm_single_ecc_error ) & dma_iccm_rd_req_f2; - assign iccm_dma_sb_error = iccm_rd_ecc_single_err & ic_dma_active; - typedef enum logic [2:0] {ERR_IDLE=3'b000, PERR_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); + assign ic_dma_active = iccm_correct_ecc | (perr_state == DMA_SB_ERR) | (dec_tlu_flush_err_wb & (perr_state == ECC_WFF)); //////////////////////////////////// Create Miss State Machine /////////////////////// // Create Miss State Machine // // Create Miss State Machine // @@ -419,27 +425,27 @@ module ifu_mem_ctl miss_state_en = ic_act_miss_f2; end CRIT_BYP_OK: begin : crit_byp_ok - miss_nxtstate = ( ic_byp_hit_f2 & ~exu_flush_final & ~(ifu_wr_en_new & last_beat) & ~uncacheable_miss_ff) ? MISS_WAIT : - ( ic_byp_hit_f2 & uncacheable_miss_ff) ? IDLE : - (~ic_byp_hit_f2 & ~exu_flush_final & (ifu_wr_en_new & last_beat) & uncacheable_miss_ff) ? CRIT_WRD_RDY : - ( (ifu_wr_en_new & last_beat) & ~uncacheable_miss_ff) ? IDLE : - ( exu_flush_final & ~(ifu_wr_en_new & last_beat) ) ? HIT_U_MISS : IDLE; + miss_nxtstate = ( ic_byp_hit_f2 & ~exu_flush_final & ~(ifu_wr_en_new & last_beat) & ~uncacheable_miss_ff) ? MISS_WAIT : + ( ic_byp_hit_f2 & uncacheable_miss_ff) ? IDLE : + (~ic_byp_hit_f2 & ~exu_flush_final & (ifu_wr_en_new & last_beat) & uncacheable_miss_ff) ? CRIT_WRD_RDY : + ( (ifu_wr_en_new & last_beat) & ~uncacheable_miss_ff) ? IDLE : + ( exu_flush_final & ~(ifu_wr_en_new & last_beat) ) ? HIT_U_MISS : IDLE; miss_state_en = exu_flush_final | ic_byp_hit_f2 | (ifu_wr_en_new & last_beat) ; end CRIT_WRD_RDY: begin : crit_wrd_rdy - miss_nxtstate = IDLE ; - miss_state_en = exu_flush_final | flush_final_f2 | ic_byp_hit_f2 ; + miss_nxtstate = IDLE ; + miss_state_en = exu_flush_final | flush_final_f2 | ic_byp_hit_f2 ; end MISS_WAIT: begin : miss_wait - miss_nxtstate = (exu_flush_final & ~(ifu_wr_en_new & last_beat)) ? HIT_U_MISS : IDLE ; + miss_nxtstate = (exu_flush_final & ~(ifu_wr_en_new & last_beat)) ? HIT_U_MISS : IDLE ; miss_state_en = exu_flush_final | (ifu_wr_en_new & last_beat) ; end HIT_U_MISS: begin : hit_u_miss - miss_nxtstate = ic_miss_under_miss_f2 & ~(ifu_wr_en_new & last_beat) ? SCND_MISS : IDLE ; + miss_nxtstate = ic_miss_under_miss_f2 & ~(ifu_wr_en_new & last_beat) ? SCND_MISS : IDLE ; miss_state_en = (ifu_wr_en_new & last_beat) | ic_miss_under_miss_f2; end SCND_MISS: begin : scnd_miss - miss_nxtstate = IDLE ; + miss_nxtstate = IDLE ; miss_state_en = (ifu_wr_en_new & last_beat) ; end default: begin : def_case @@ -450,7 +456,7 @@ module ifu_mem_ctl end rvdffs #(($bits(miss_state_t))) miss_state_ff (.clk(free_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_f2); assign sel_hold_imb = (miss_pending & ~(ifu_wr_en_new & last_beat) & ~((miss_state == CRIT_WRD_RDY) & exu_flush_final)) | ic_act_miss_f2 | @@ -461,20 +467,20 @@ module ifu_mem_ctl assign ic_req_addr_bits_5_3[5:3] = req_addr_count[2:0] ; assign ic_wr_addr_bits_5_3[5:3] = ifu_axi_rid_ff[2:0] ; - // NOTE: Cacheline size is 16 bytes in this example. + // NOTE: Cacheline size is 16 bytes in this example. // Tag Index Bank Offset // [31:16] [15:5] [4] [3:0] - + assign fetch_req_icache_f2 = ifc_fetch_req_f2 & ~ifc_iccm_access_f2 & ~ifc_region_acc_fault_f2; assign fetch_req_iccm_f2 = ifc_fetch_req_f2 & ifc_iccm_access_f2; - + assign ic_iccm_hit_f2 = fetch_req_iccm_f2 & (~miss_pending | (miss_state==HIT_U_MISS)); assign ic_byp_hit_f2 = ic_crit_wd_rdy & fetch_req_icache_f2 & miss_pending ; assign ic_act_hit_f2 = (|ic_rd_hit[3:0]) & fetch_req_icache_f2 & ~reset_all_tags & (~miss_pending | (miss_state==HIT_U_MISS)) & ~sel_mb_addr_ff; assign ic_act_miss_f2 = (~(|ic_rd_hit[3:0]) | reset_all_tags) & fetch_req_icache_f2 & ~miss_pending & ~ifc_region_acc_fault_f2; assign ic_miss_under_miss_f2 = (~(|ic_rd_hit[3:0]) | reset_all_tags) & fetch_req_icache_f2 & (miss_state == HIT_U_MISS) ; - assign ic_hit_f2 = ic_act_hit_f2 | ic_byp_hit_f2 | ic_iccm_hit_f2 | (ifc_region_acc_fault_f2 & ifc_fetch_req_f2); + assign ic_hit_f2 = ic_act_hit_f2 | ic_byp_hit_f2 | ic_iccm_hit_f2 | (ifc_region_acc_fault_f2 & ifc_fetch_req_f2 & ~((miss_state == CRIT_BYP_OK) | (miss_state == SCND_MISS))); assign uncacheable_miss_in = sel_hold_imb ? uncacheable_miss_ff : ifc_fetch_uncacheable_f1 ; assign imb_in[31:1] = sel_hold_imb ? imb_ff[31:1] : {fetch_addr_f1[31:1]} ; @@ -486,11 +492,11 @@ module ifu_mem_ctl rvdff #(1) reset_ic_f (.*, .clk(free_clk), .din (reset_ic_in), .dout(reset_ic_ff)); rvdff #(1) uncache_ff (.*, .clk(active_clk), .din (ifc_fetch_uncacheable_f1), .dout(fetch_uncacheable_ff)); - - rvdffe #(31) ifu_fetch_addr_f2_ff (.*, + + rvdffe #(31) ifu_fetch_addr_f2_ff (.*, .en (fetch_f1_f2_c1_clken), - .din ({fetch_addr_f1[31:1]}), + .din ({fetch_addr_f1[31:1]}), .dout({ifu_fetch_addr_int_f2[31:1]})); assign vaddr_f2[3:1] = ifu_fetch_addr_int_f2[3:1] ; @@ -505,14 +511,14 @@ module ifu_mem_ctl rvdff #(1) fetch_req_f2_ff (.*, .clk(active_clk), .din(ifc_fetch_req_qual_f1), .dout(ifc_fetch_req_f2_raw)); assign ifc_fetch_req_f2 = ifc_fetch_req_f2_raw & ~exu_flush_final ; - + rvdff #(1) ifu_iccm_acc_ff (.*, .clk(fetch_f1_f2_c1_clk), .din(ifc_iccm_access_f1), .dout(ifc_iccm_access_f2)); rvdff #(1) ifu_iccm_reg_acc_ff (.*, .clk(fetch_f1_f2_c1_clk), .din(ifc_region_acc_fault_final_f1), .dout(ifc_region_acc_fault_f2)); assign ifu_ic_req_addr_f2[31:3] = {imb_ff[31:6] , ic_req_addr_bits_5_3[5:3] }; assign ifu_ic_mb_empty = ((miss_state == HIT_U_MISS) & ~(ifu_wr_en_new & last_beat)) | ~miss_pending ; - assign ifu_miss_state_idle = (miss_state == IDLE) ; + assign ifu_miss_state_idle = (miss_state == IDLE) ; // four-way set associative - three bits // each bit represents one branch point in a binary decision tree; let 1 @@ -536,32 +542,32 @@ module ifu_mem_ctl - - assign replace_way_mb_any[3] = ( way_status_mb_ff[2] & way_status_mb_ff[0] & (&tagv_mb_ff[3:0])) | - (~tagv_mb_ff[3]& tagv_mb_ff[2] & tagv_mb_ff[1] & tagv_mb_ff[0]) ; - assign replace_way_mb_any[2] = (~way_status_mb_ff[2] & way_status_mb_ff[0] & (&tagv_mb_ff[3:0])) | - (~tagv_mb_ff[2]& tagv_mb_ff[1] & tagv_mb_ff[0]) ; + + assign replace_way_mb_any[3] = ( way_status_mb_ff[2] & way_status_mb_ff[0] & (&tagv_mb_ff[3:0])) | + (~tagv_mb_ff[3]& tagv_mb_ff[2] & tagv_mb_ff[1] & tagv_mb_ff[0]) ; + assign replace_way_mb_any[2] = (~way_status_mb_ff[2] & way_status_mb_ff[0] & (&tagv_mb_ff[3:0])) | + (~tagv_mb_ff[2]& tagv_mb_ff[1] & tagv_mb_ff[0]) ; assign replace_way_mb_any[1] = ( way_status_mb_ff[1] & ~way_status_mb_ff[0] & (&tagv_mb_ff[3:0])) | - (~tagv_mb_ff[1]& tagv_mb_ff[0] ) ; - assign replace_way_mb_any[0] = (~way_status_mb_ff[1] & ~way_status_mb_ff[0] & (&tagv_mb_ff[3:0])) | - (~tagv_mb_ff[0] ) ; + (~tagv_mb_ff[1]& tagv_mb_ff[0] ) ; + assign replace_way_mb_any[0] = (~way_status_mb_ff[1] & ~way_status_mb_ff[0] & (&tagv_mb_ff[3:0])) | + (~tagv_mb_ff[0] ) ; - assign way_status_hit_new[2:0] = ({3{ic_rd_hit[0]}} & {way_status[2] , 1'b1 , 1'b1}) | - ({3{ic_rd_hit[1]}} & {way_status[2] , 1'b0 , 1'b1}) | - ({3{ic_rd_hit[2]}} & {1'b1 ,way_status[1] , 1'b0}) | - ({3{ic_rd_hit[3]}} & {1'b0 ,way_status[1] , 1'b0}) ; + assign way_status_hit_new[2:0] = ({3{ic_rd_hit[0]}} & {way_status[2] , 1'b1 , 1'b1}) | + ({3{ic_rd_hit[1]}} & {way_status[2] , 1'b0 , 1'b1}) | + ({3{ic_rd_hit[2]}} & {1'b1 ,way_status[1] , 1'b0}) | + ({3{ic_rd_hit[3]}} & {1'b0 ,way_status[1] , 1'b0}) ; - assign way_status_rep_new[2:0] = ({3{replace_way_mb_any[0]}} & {way_status_mb_ff[2] , 1'b1 , 1'b1}) | - ({3{replace_way_mb_any[1]}} & {way_status_mb_ff[2] , 1'b0 , 1'b1}) | - ({3{replace_way_mb_any[2]}} & {1'b1 ,way_status_mb_ff[1] , 1'b0}) | - ({3{replace_way_mb_any[3]}} & {1'b0 ,way_status_mb_ff[1] , 1'b0}) ; + assign way_status_rep_new[2:0] = ({3{replace_way_mb_any[0]}} & {way_status_mb_ff[2] , 1'b1 , 1'b1}) | + ({3{replace_way_mb_any[1]}} & {way_status_mb_ff[2] , 1'b0 , 1'b1}) | + ({3{replace_way_mb_any[2]}} & {1'b1 ,way_status_mb_ff[1] , 1'b0}) | + ({3{replace_way_mb_any[3]}} & {1'b0 ,way_status_mb_ff[1] , 1'b0}) ; // Make sure to select the way_status_hit_new even when in hit_under_miss. assign way_status_new[2:0] = (ifu_wr_en_new_q ) ? way_status_rep_new[2:0] : - way_status_hit_new[2:0] ; + way_status_hit_new[2:0] ; - assign way_status_wr_en = (ifu_wr_en_new_q ) | ic_act_hit_f2; + assign way_status_wr_en = (ifu_wr_en_new_q ) | ic_act_hit_f2; @@ -569,31 +575,31 @@ module ifu_mem_ctl rvdff #(1) sel_f_u_m_ff (.*, .clk(free_clk), .din (sel_fetch_u_miss), .dout(sel_fetch_u_miss_ff)); - assign sel_mb_addr = ((miss_pending & ifu_wr_en_new ) | reset_tag_valid_for_miss) ; - assign ifu_ic_rw_int_addr[31:1] = ({31{ sel_mb_addr}} & {imb_ff[31:6] , ic_wr_addr_bits_5_3[5:3] , imb_ff[2:1]}) | + assign sel_mb_addr = ((miss_pending & ifu_wr_en_new ) | reset_tag_valid_for_miss) ; + assign ifu_ic_rw_int_addr[31:1] = ({31{ sel_mb_addr}} & {imb_ff[31:6] , ic_wr_addr_bits_5_3[5:3] , imb_ff[2:1]}) | ({31{~sel_mb_addr}} & fetch_addr_f1[31:1] ) ; - assign ifu_status_wr_addr[31:1] = ({31{ sel_mb_addr}} & {imb_ff[31:6] , ic_wr_addr_bits_5_3[5:3] , imb_ff[2:1]}) | + assign ifu_status_wr_addr[31:1] = ({31{ sel_mb_addr}} & {imb_ff[31:6] , ic_wr_addr_bits_5_3[5:3] , imb_ff[2:1]}) | ({31{~sel_mb_addr}} & ifu_fetch_addr_int_f2[31:1] ) ; - + rvdff #(1) sel_mb_addr_flop (.*, .clk(free_clk), .din({sel_mb_addr}), .dout({sel_mb_addr_ff})); assign ic_rw_addr[31:3] = ifu_ic_rw_int_addr[31:3] ; - + genvar i ; for (i=0 ; i < 4 ; i++) begin : DATA_PGEN - `ifdef RV_ICACHE_ECC + `ifdef RV_ICACHE_ECC rvecc_encode ic_ecc_encode0 ( - .din ({16'b0, ifu_wr_data_new[((16*i)+15):(16*i)]}), - .ecc_out({ ic_wr_ecc0_unused[i],ic_wr_ecc[i*5+4:i*5]})); + .din ({16'b0, ifu_wr_data_new[((16*i)+15):(16*i)]}), + .ecc_out({ ic_wr_ecc0_unused[i],ic_wr_ecc[i*5+4:i*5]})); `else - rveven_paritygen #(16) parlo (.data_in (ifu_wr_data_new[((16*i)+15):(16*i)]), - .parity_out(ic_wr_parity[i])); - + rveven_paritygen #(16) parlo (.data_in (ifu_wr_data_new[((16*i)+15):(16*i)]), + .parity_out(ic_wr_parity[i])); + `endif -end +end assign ifu_wr_data_comb_err = ifu_wr_data_error ; assign ifu_wr_cumulative_err = (ifu_wr_data_comb_err | ifu_wr_data_comb_err_ff) & ~reset_beat_cnt; @@ -601,21 +607,21 @@ end rvdff #(1) cumul_err_ff (.*, .clk(free_clk), .din (ifu_wr_cumulative_err), .dout(ifu_wr_data_comb_err_ff)); -`ifdef RV_ICACHE_ECC +`ifdef RV_ICACHE_ECC assign ic_rd_data_only[127:0] = {ic_rd_data [157:126], ic_rd_data [115:84] , ic_rd_data [73:42],ic_rd_data [31:0]} ; assign ic_error_f2.ecc[39:0] = {ic_rd_data[167:158], ic_rd_data[125:116], ic_rd_data[83:74] ,ic_rd_data[41:32]}; assign ic_wr_data[83:0] = {ic_wr_ecc[19:10], ifu_wr_data_new[63:32], - ic_wr_ecc[9:0], - ifu_wr_data_new[31:0]} ; - + ic_wr_ecc[9:0], + ifu_wr_data_new[31:0]} ; + `else assign ic_rd_data_only[127:0] = {ic_rd_data [133:102], ic_rd_data [99:68] , ic_rd_data [65:34] ,ic_rd_data [31:0]} ; assign ic_error_f2.parity[7:0] = {ic_rd_data[135:134] , ic_rd_data[101:100], ic_rd_data [67:66] ,ic_rd_data [33:32]}; assign ic_wr_data[67:0] = {ic_wr_parity[3:2], ifu_wr_data_new[63:32], - ic_wr_parity[1:0], - ifu_wr_data_new[31:0]} ; + ic_wr_parity[1:0], + ifu_wr_data_new[31:0]} ; `endif @@ -644,7 +650,7 @@ end `endif `ifdef NOT_ICCM_AND_ICACHE - + assign ic_final_data = ({128{sel_byp_data | sel_ic_data}} & {ic_rd_data_only[127:0]} ) ; assign ic_premux_data = ({128{sel_byp_data }} & {ic_byp_data_only[127:0]} ) ; @@ -662,7 +668,7 @@ end assign ifc_bus_acc_fault_f2 = ic_byp_hit_f2 & ifu_byp_data_err ; assign ic_data_f2[127:0] = ic_final_data[127:0]; - + rvdff #(1) flush_final_ff (.*, .clk(free_clk), .din({exu_flush_final}), .dout({flush_final_f2})); assign fetch_req_f2_qual = ic_hit_f2 & ~exu_flush_final; assign ic_access_fault_f2 = (ifc_region_acc_fault_f2 | ifc_bus_acc_fault_f2) & ~exu_flush_final; @@ -676,13 +682,13 @@ assign ic_fetch_val_f2[3] = fetch_req_f2_qual & ifu_bp_inst_mask_f2[3] & ((!vadd assign ic_fetch_val_f2[2] = fetch_req_f2_qual & ifu_bp_inst_mask_f2[2] & ((!vaddr_f2[2]) | (!vaddr_f2[3])); assign ic_fetch_val_f2[1] = fetch_req_f2_qual & ifu_bp_inst_mask_f2[1] & ((!vaddr_f2[1]) | (!vaddr_f2[2]) | (!vaddr_f2[3])) ; assign ic_fetch_val_f2[0] = fetch_req_f2_qual ; - + assign fetch_mask[7:0] = {vaddr_f2[3:1]==3'b111,vaddr_f2[3:1]==3'b110,vaddr_f2[3:1]==3'b101,vaddr_f2[3:1]==3'b100,vaddr_f2[3:1]==3'b011,vaddr_f2[3:1]==3'b010,vaddr_f2[3:1]==3'b001,vaddr_f2[3:1]==3'b000}; assign ic_fetch_mem_val[7:0] = { 1'b1, |fetch_mask[6:0], |fetch_mask[5:0], |fetch_mask[4:0], |fetch_mask[3:0], |fetch_mask[2:0], |fetch_mask[1:0], fetch_mask[0] }; assign bp_mask[7:0] = {ifu_bp_inst_mask_f2[7:1], 1'b1}; - + assign ic_bp_mem_mask[7:0] = ({8{fetch_mask[0]}} & bp_mask[7:0]) | // unrotate the bpmask ({8{fetch_mask[1]}} & {bp_mask[6:0],1'b0}) | ({8{fetch_mask[2]}} & {bp_mask[5:0],2'b0}) | @@ -693,7 +699,7 @@ assign ic_fetch_val_f2[0] = fetch_req_f2_qual ; ({8{fetch_mask[7]}} & {bp_mask[0] ,7'b0}); assign ic_fetch_val_mem_f2[7:0] = {8{fetch_req_f2_qual}} & ic_bp_mem_mask[7:0] & ic_fetch_mem_val[7:0]; - + ///////////////////////////////////////////////////////////////////////////////////// @@ -702,27 +708,27 @@ assign ic_fetch_val_f2[0] = fetch_req_f2_qual ; logic write_byp_first_data ; logic write_byp_second_data ; - + logic [63:0] ifu_byp_data_first_half; logic [63:0] ifu_byp_data_second_half; logic ifu_byp_data_error_first_half_in; logic ifu_byp_data_error_first_half; logic ifu_byp_data_error_second_half_in; logic ifu_byp_data_error_second_half; - logic ifu_byp_data_first_half_valid_in ; - logic ifu_byp_data_first_half_valid ; - logic ifu_byp_data_second_half_valid_in ; - logic ifu_byp_data_second_half_valid ; - logic ic_crit_wd_complete ; + logic ifu_byp_data_first_half_valid_in ; + logic ifu_byp_data_first_half_valid ; + logic ifu_byp_data_second_half_valid_in ; + logic ifu_byp_data_second_half_valid ; + logic ic_crit_wd_complete ; - logic [IFU_BUS_TAG-1:0] byp_tag_ff; + logic [IFU_BUS_TAG-1:0] byp_tag_ff; logic byp_data_first_c1_clken ; logic byp_data_first_c1_clk; logic byp_data_second_c1_clken ; logic byp_data_second_c1_clk; - assign byp_data_first_c1_clken = write_byp_first_data; - assign byp_data_second_c1_clken = write_byp_second_data; + assign byp_data_first_c1_clken = write_byp_first_data; + assign byp_data_second_c1_clken = write_byp_second_data; rvclkhdr byp_data_first_c1_cgc ( .en(byp_data_first_c1_clken), .l1clk(byp_data_first_c1_clk), .* ); rvclkhdr byp_data_second_c1_cgc ( .en(byp_data_second_c1_clken), .l1clk(byp_data_second_c1_clk), .* ); @@ -732,41 +738,41 @@ assign ic_fetch_val_f2[0] = fetch_req_f2_qual ; assign write_byp_second_data = axi_ifu_wr_en_new & ({byp_tag_ff[IFU_BUS_TAG-1:1],1'b1} == ifu_axi_rid_ff[IFU_BUS_TAG-1:0]); // First Half flops - rvdffe #(64) byp_data_first_half (.*, + rvdffe #(64) byp_data_first_half (.*, .en(byp_data_first_c1_clken), - .din (ifu_wr_data_new[63:0]), + .din (ifu_wr_data_new[63:0]), .dout(ifu_byp_data_first_half[63:0])); assign ifu_byp_data_error_first_half_in = write_byp_first_data ? ifu_wr_data_error : (ifu_byp_data_error_first_half & ~ic_act_miss_f2) ; - rvdff #(1) byp_data_first_half_err (.*, + rvdff #(1) byp_data_first_half_err (.*, .clk(free_clk), - .din (ifu_byp_data_error_first_half_in), + .din (ifu_byp_data_error_first_half_in), .dout(ifu_byp_data_error_first_half)); assign ifu_byp_data_first_half_valid_in = write_byp_first_data ? 1'b1 : (ifu_byp_data_first_half_valid & ~ic_act_miss_f2) ; - rvdff #(1) byp_data_first_half_val (.*, + rvdff #(1) byp_data_first_half_val (.*, .clk(free_clk), - .din (ifu_byp_data_first_half_valid_in), + .din (ifu_byp_data_first_half_valid_in), .dout(ifu_byp_data_first_half_valid)); // Second Half flops - rvdffe #(64) byp_data_second_half (.*, + rvdffe #(64) byp_data_second_half (.*, .en(byp_data_second_c1_clken), - .din (ifu_wr_data_new[63:0]), + .din (ifu_wr_data_new[63:0]), .dout(ifu_byp_data_second_half[63:0])); assign ifu_byp_data_error_second_half_in = write_byp_second_data ? ifu_wr_data_error : (ifu_byp_data_error_second_half & ~ic_act_miss_f2) ; - rvdff #(1) byp_data_second_half_err (.*, + rvdff #(1) byp_data_second_half_err (.*, .clk(free_clk), - .din (ifu_byp_data_error_second_half_in), + .din (ifu_byp_data_error_second_half_in), .dout(ifu_byp_data_error_second_half)); assign ifu_byp_data_second_half_valid_in = write_byp_second_data ? 1'b1 : (ifu_byp_data_second_half_valid & ~ic_act_miss_f2) ; - rvdff #(1) byp_data_second_half_val (.*, + rvdff #(1) byp_data_second_half_val (.*, .clk(free_clk), - .din (ifu_byp_data_second_half_valid_in), + .din (ifu_byp_data_second_half_valid_in), .dout(ifu_byp_data_second_half_valid)); assign ic_byp_data_only[127:0] = { ifu_byp_data_second_half[63:0] , ifu_byp_data_first_half[63:0] } ; @@ -774,7 +780,7 @@ assign ic_fetch_val_f2[0] = fetch_req_f2_qual ; // Critical word ready. - assign ic_crit_wd_complete = (write_byp_first_data & ifu_byp_data_second_half_valid) | + assign ic_crit_wd_complete = (write_byp_first_data & ifu_byp_data_second_half_valid) | (write_byp_second_data & ifu_byp_data_first_half_valid) ; assign ic_crit_wd_rdy_in = (ic_crit_wd_complete & crit_wd_byp_ok_ff & ~exu_flush_final ) | @@ -782,10 +788,10 @@ assign ic_fetch_val_f2[0] = fetch_req_f2_qual ; rvdff #(1) crit_wd_ff (.*, .clk(free_clk), .din(ic_crit_wd_rdy_in), .dout(ic_crit_wd_rdy_ff)); ///////////////////////////////////////////////////////////////////////////////////// -// Parity checking logic for Icache logic. // +// Parity checking logic for Icache logic. // ///////////////////////////////////////////////////////////////////////////////////// - + assign ic_rd_parity_final_err = ic_tag_perr & ifu_icache_fetch_f2 ; logic [16:6] ifu_ic_rw_int_addr_f2_Q ; @@ -795,14 +801,14 @@ logic perr_sel_invalidate; logic perr_sb_write_status ; logic ifu_icache_sb_error_val_ff ; - rvdff #(11) ic_index_q (.*, + rvdff #(11) ic_index_q (.*, .clk(active_clk), - .din(ifu_icache_error_index[16:6]), + .din(ifu_icache_error_index[16:6]), .dout(ifu_ic_rw_int_addr_f2_Q[16:6])); - - + + rvdff #((1)) perr_err_ff (.clk(active_clk), .din(ifu_icache_error_val), .dout(ic_rd_parity_final_err_ff), .*); rvdff #((1)) sbiccm_err_ff (.clk(active_clk), .din(ifu_icache_sb_error_val), .dout(ifu_icache_sb_error_val_ff), .*); rvdffs #((11)) perr_dat_ff (.clk(active_clk), .din(ifu_ic_rw_int_addr_f2_Q[16:6]), .dout(perr_ic_index_ff), .en(perr_sb_write_status), .*); @@ -816,7 +822,7 @@ logic ifu_icache_sb_error_val_ff ; //////////////////////////////////// Create Parity Error State Machine /////////////////////// assign iccm_correct_ecc = (perr_state == ECC_CORR); - + // FIFO state machine always_comb begin : ERROR_SM perr_nxtstate = ERR_IDLE; @@ -861,17 +867,16 @@ logic ifu_icache_sb_error_val_ff ; `ifdef RV_ICCM_ENABLE ///////////////////////////////////////////////////////////////////////////////////// -// ECC checking logic for ICCM data. // +// ECC checking logic for ICCM data. // ///////////////////////////////////////////////////////////////////////////////////// logic [3:0] [31:0] iccm_corrected_data; logic [3:0] [06:0] iccm_corrected_ecc; -logic [3:0] iccm_single_ecc_error; logic [3:0] iccm_double_ecc_error; logic [3:0] iccm_ecc_word_enable; -logic [ICCM_BITS-1:4] iccm_rw_addr_f2; +logic [ICCM_BITS-1:4] iccm_rw_addr_f2; logic [31:0] iccm_corrected_data_f2_mux; logic [06:0] iccm_corrected_ecc_f2_mux; @@ -890,7 +895,7 @@ rvecc_decode ecc_decode ( .single_ecc_error(iccm_single_ecc_error[i]), .double_ecc_error(iccm_double_ecc_error[i])); end - + assign iccm_rd_ecc_single_err = (|iccm_single_ecc_error ) & ifc_iccm_access_f2; assign iccm_rd_ecc_double_err = (|iccm_double_ecc_error ) & ifc_iccm_access_f2; @@ -903,20 +908,20 @@ assign iccm_corrected_ecc_f2_mux[06:0] = iccm_single_ecc_error[0] ? iccm_correc iccm_single_ecc_error[1] ? iccm_corrected_ecc[1] : iccm_single_ecc_error[2] ? iccm_corrected_ecc[2] : iccm_corrected_ecc[3] ; - + rvdff #(ICCM_BITS-4) iccm_index_f2 (.*, .clk(free_clk), .din(iccm_rw_addr[ICCM_BITS-1:4]), .dout(iccm_rw_addr_f2[ICCM_BITS-1:4])); - assign iccm_rd_err_f2_mux[1:0] = iccm_single_ecc_error[0] ? 2'b00: - iccm_single_ecc_error[1] ? 2'b01: - iccm_single_ecc_error[2] ? 2'b10: 2'b11 ; + assign iccm_rd_err_f2_mux[1:0] = iccm_single_ecc_error[0] ? 2'b00: + iccm_single_ecc_error[1] ? 2'b01: + iccm_single_ecc_error[2] ? 2'b10: 2'b11 ; + - logic iccm_rd_ecc_single_err_hold_in ; assign iccm_ecc_write_status = ((iccm_rd_ecc_single_err & ~iccm_rd_ecc_single_err_ff) & ~exu_flush_final) | iccm_dma_sb_error; - assign iccm_rd_ecc_single_err_hold_in = (iccm_rd_ecc_single_err | iccm_rd_ecc_single_err_ff) & ~exu_flush_final; - + assign iccm_rd_ecc_single_err_hold_in = (iccm_rd_ecc_single_err | iccm_rd_ecc_single_err_ff) & ~exu_flush_final; + rvdff #((1)) ecc_rr_ff (.clk(free_clk), .din(iccm_rd_ecc_single_err_hold_in), .dout(iccm_rd_ecc_single_err_ff), .*); rvdffs #((32)) ecc_dat0_ff (.clk(free_clk), .din(iccm_corrected_data_f2_mux[31:0]), .dout(iccm_ecc_corr_data_ff[31:0]), .en(iccm_ecc_write_status), .*); rvdffs #((7)) ecc_dat1_ff (.clk(free_clk), .din(iccm_corrected_ecc_f2_mux[6:0]), .dout(iccm_ecc_corr_data_ff[38:32]), .en(iccm_ecc_write_status), .*); @@ -931,6 +936,8 @@ assign iccm_rd_ecc_single_err_ff = 1'b0 ; assign iccm_ecc_corr_index_ff[ICCM_BITS-1:2] = '0; assign iccm_ecc_corr_data_ff[38:0] = '0; assign iccm_ecc_write_status = '0; +assign iccm_single_ecc_error = '0; + `endif @@ -938,18 +945,18 @@ assign iccm_ecc_write_status = '0; logic axiclk_reset; logic axi_ifu_bus_clk_en_ff; logic axi_ifu_bus_clk_en ; - + logic ifc_axi_ic_req_ff_in; - logic ifc_axi_ic_req_ff2 ; + logic ifc_axi_ic_req_ff2 ; - logic axi_inc_data_beat_cnt ; - logic axi_reset_data_beat_cnt ; - logic axi_hold_data_beat_cnt ; + logic axi_inc_data_beat_cnt ; + logic axi_reset_data_beat_cnt ; + logic axi_hold_data_beat_cnt ; - logic axi_inc_cmd_beat_cnt ; - logic axi_reset_cmd_beat_cnt_0 ; - logic axi_reset_cmd_beat_cnt_6 ; - logic axi_hold_cmd_beat_cnt ; + logic axi_inc_cmd_beat_cnt ; + logic axi_reset_cmd_beat_cnt_0 ; + logic axi_reset_cmd_beat_cnt_6 ; + logic axi_hold_cmd_beat_cnt ; logic [2:0] axi_new_data_beat_count ; logic [2:0] axi_data_beat_count ; @@ -966,18 +973,18 @@ assign iccm_ecc_write_status = '0; logic [2:0] axi_rd_addr_count; - logic axi_cmd_sent ; - logic axi_last_data_beat ; - logic axi_wrap_addr ; + logic axi_cmd_sent ; + logic axi_last_data_beat ; + logic axi_wrap_addr ; logic ifu_axi_rvalid_ff ; logic ifu_axi_rvalid_unq_ff ; - logic ifu_axi_arready_unq_ff ; - logic ifu_axi_arvalid_ff ; - logic ifu_axi_arready_ff ; + logic ifu_axi_arready_unq_ff ; + logic ifu_axi_arvalid_ff ; + logic ifu_axi_arready_ff ; logic [63:0] ifu_axi_rdata_ff ; - logic [1:0] ifu_axi_rresp_ff ; + logic [1:0] ifu_axi_rresp_ff ; logic axi_w0_wren ; logic axi_w1_wren ; @@ -996,8 +1003,8 @@ assign iccm_ecc_write_status = '0; logic ifc_dma_access_ok_d; logic ifc_dma_access_ok_prev; - -assign axi_ifu_bus_clk_en = ifu_bus_clk_en ; + +assign axi_ifu_bus_clk_en = ifu_bus_clk_en ; rvclkhdr axi_clk(.en(axi_ifu_bus_clk_en), .l1clk(axiclk), .*); @@ -1007,33 +1014,33 @@ assign axi_ifu_bus_clk_en = ifu_bus_clk_en ; logic axi_cmd_req_in ; logic axi_cmd_req_hold ; - + assign ifc_axi_ic_req_ff_in = (ic_act_miss_f2 | axi_cmd_req_hold | ifc_axi_ic_req_ff2) & ~((axi_cmd_beat_count==3'b111) & ifu_axi_arvalid & ifu_axi_arready & miss_pending); rvdff #(1) axi_ic_req_ff2(.*, .clk(axiclk), .din(ifc_axi_ic_req_ff_in), .dout(ifc_axi_ic_req_ff2)); - + assign axi_cmd_req_in = (ic_act_miss_f2 | axi_cmd_req_hold) & ~axi_cmd_sent ; // hold until first command sent - // changes for making the axi blocking + // changes for making the axi blocking rvdff #(1) axi_cmd_req_ff (.*, .clk(free_clk), .din(axi_cmd_req_in), .dout(axi_cmd_req_hold)); /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // logic axi_cmd_rsp_pend; -// `ifdef RV_BUILD_SVC +// `ifdef RV_BUILD_SVC // rvdffsc axi_cmd_rsp_pend_ff ( .din(ifu_axi_arready), .dout(axi_cmd_rsp_pend), .en(ifu_axi_arvalid), .clear(ifu_axi_rvalid & ifu_axi_rready), .clk(axiclk), .*); -// `elsif RV_BUILD_AXI4 +// `elsif RV_BUILD_AXI4 // rvdffsc axi_cmd_rsp_pend_ff ( .din(ifu_axi_arready), .dout(axi_cmd_rsp_pend), .en(ifu_axi_arvalid), .clear(ifu_axi_rvalid & ifu_axi_rready), .clk(axiclk), .*); // `else -// assign axi_cmd_rsp_pend = 1'b0; +// assign axi_cmd_rsp_pend = 1'b0; // `endif -// assign ifu_axi_arvalid = ifc_axi_ic_req_ff2 & ~axi_cmd_rsp_pend; +// assign ifu_axi_arvalid = ifc_axi_ic_req_ff2 & ~axi_cmd_rsp_pend; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - assign ifu_axi_arvalid = ifc_axi_ic_req_ff2 ; - assign ifu_axi_arid[IFU_BUS_TAG-1:0] = IFU_BUS_TAG'(axi_new_rd_addr_count[2:0]); - assign ifu_axi_araddr[31:0] = {ifu_ic_req_addr_f2[31:3],3'b0} ; + assign ifu_axi_arvalid = ifc_axi_ic_req_ff2 ; + assign ifu_axi_arid[IFU_BUS_TAG-1:0] = IFU_BUS_TAG'(axi_rd_addr_count[2:0]); + assign ifu_axi_araddr[31:0] = {ifu_ic_req_addr_f2[31:3],3'b0} ; assign ifu_axi_rready = 1'b1; assign ifu_axi_arsize[2:0] = 3'b011; assign ifu_axi_arcache[3:0] = 4'b1111; - assign ifu_axi_arprot[2:0] = 3'b100; + assign ifu_axi_arprot[2:0] = 3'b100; assign ifu_axi_arregion[3:0] = ifu_axi_araddr[31:28]; assign ifu_axi_arlen[7:0] = '0; assign ifu_axi_arburst[1:0] = 2'b01; @@ -1047,12 +1054,12 @@ assign axi_ifu_bus_clk_en = ifu_bus_clk_en ; rvdff #(2) scvi_rsp_cmd_ff (.*, .clk(axiclk), .din(ifu_axi_rresp[1:0]), .dout(ifu_axi_rresp_ff[1:0])); rvdff #(IFU_BUS_TAG) scvi_rsp_tag_ff (.*, .clk(axiclk), .din(ifu_axi_rid[IFU_BUS_TAG-1:0]), .dout(ifu_axi_rid_ff[IFU_BUS_TAG-1:0])); rvdff #(64) axi_data_ff (.*, .clk(axiclk), .din(ifu_axi_rdata[63:0]), .dout(ifu_axi_rdata_ff[63:0])); - + assign ifu_axi_arready_ff = ifu_axi_arready_unq_ff & axi_ifu_bus_clk_en_ff ; assign ifu_axi_rvalid_ff = ifu_axi_rvalid_unq_ff & axi_ifu_bus_clk_en_ff ; - assign axi_cmd_sent = ifu_axi_arvalid_ff & ifu_axi_arready_ff & miss_pending; + assign axi_cmd_sent = ifu_axi_arvalid & ifu_axi_arready & miss_pending & axi_ifu_bus_clk_en; assign axi_inc_data_beat_cnt = (axi_ifu_wr_en_new & ~axi_last_data_beat) ; assign axi_reset_data_beat_cnt = ic_act_miss_f2 | (axi_ifu_wr_en_new & axi_last_data_beat) ; assign axi_hold_data_beat_cnt = ~axi_inc_data_beat_cnt & ~axi_reset_data_beat_cnt ; @@ -1069,8 +1076,8 @@ assign axi_ifu_bus_clk_en = ifu_bus_clk_en ; assign axi_hold_rd_addr_cnt = ~axi_inc_rd_addr_cnt & ~axi_set_rd_addr_cnt; assign axi_new_rd_addr_count[2:0] = ~miss_pending ? {imb_ff[5:4],1'b0} : axi_inc_rd_addr_cnt ? (axi_rd_addr_count[2:0] + 3'b001) : axi_rd_addr_count[2:0]; - - rvdffs #(3) axi_rd_addr_ff (.*, .en(~axi_hold_rd_addr_cnt), .clk(free_clk), .din ({axi_new_rd_addr_count[2:0]}), .dout({axi_rd_addr_count[2:0]})); + + rvdffs #(3) axi_rd_addr_ff (.*, .en(1'b1), .clk(axiclk_reset), .din ({axi_new_rd_addr_count[2:0]}), .dout({axi_rd_addr_count[2:0]})); // command beat Count assign axi_inc_cmd_beat_cnt = ifu_axi_arvalid & ifu_axi_arready & miss_pending; @@ -1087,10 +1094,10 @@ assign axi_ifu_bus_clk_en = ifu_bus_clk_en ; .l1clk(axiclk_reset), .*); - rvdff #(3) axi_cmd_beat_ff (.*, .clk(axiclk_reset), .din ({axi_new_cmd_beat_count[2:0]}), + rvdff #(3) axi_cmd_beat_ff (.*, .clk(axiclk_reset), .din ({axi_new_cmd_beat_count[2:0]}), .dout({axi_cmd_beat_count[2:0]})); - assign req_addr_count[2:0] = axi_new_rd_addr_count[2:0] ; + assign req_addr_count[2:0] = axi_rd_addr_count[2:0] ; @@ -1098,30 +1105,30 @@ assign axi_ifu_bus_clk_en = ifu_bus_clk_en ; assign axi_wrap_addr = (axi_rd_addr_count[2:0] == 3'b111); assign axi_ifu_wr_en_new = ifu_axi_rvalid_ff & miss_pending ; - assign axi_ifu_wr_en_new_q = ifu_axi_rvalid_ff & miss_pending & ~uncacheable_miss_ff & ~(|ifu_axi_rresp_ff[1:0]); // qualify with no-error conditions ; - assign axi_ifu_wr_en_new_wo_err = ifu_axi_rvalid_ff & miss_pending & ~uncacheable_miss_ff; + assign axi_ifu_wr_en_new_q = ifu_axi_rvalid_ff & miss_pending & ~uncacheable_miss_ff & ~(|ifu_axi_rresp_ff[1:0]); // qualify with no-error conditions ; + assign axi_ifu_wr_en_new_wo_err = ifu_axi_rvalid_ff & miss_pending & ~uncacheable_miss_ff; assign axi_ifu_wr_data_new[63:0] = ifu_axi_rdata_ff[63:0] ; - assign axi_w0_wren = axi_ifu_wr_en_new_q & (replace_way_mb_any[3:0] == 4'b0001) & miss_pending ; + assign axi_w0_wren = axi_ifu_wr_en_new_q & (replace_way_mb_any[3:0] == 4'b0001) & miss_pending ; assign axi_w1_wren = axi_ifu_wr_en_new_q & (replace_way_mb_any[3:0] == 4'b0010) & miss_pending ; assign axi_w2_wren = axi_ifu_wr_en_new_q & (replace_way_mb_any[3:0] == 4'b0100) & miss_pending ; assign axi_w3_wren = axi_ifu_wr_en_new_q & (replace_way_mb_any[3:0] == 4'b1000) & miss_pending ; - + assign axi_ic_wr_en[3:0] = {axi_w3_wren , axi_w2_wren , axi_w1_wren , axi_w0_wren} ; - + assign axi_w0_wren_last = axi_ifu_wr_en_new_wo_err & (replace_way_mb_any[3:0] == 4'b0001) & miss_pending & axi_last_data_beat; assign axi_w1_wren_last = axi_ifu_wr_en_new_wo_err & (replace_way_mb_any[3:0] == 4'b0010) & miss_pending & axi_last_data_beat; assign axi_w2_wren_last = axi_ifu_wr_en_new_wo_err & (replace_way_mb_any[3:0] == 4'b0100) & miss_pending & axi_last_data_beat; assign axi_w3_wren_last = axi_ifu_wr_en_new_wo_err & (replace_way_mb_any[3:0] == 4'b1000) & miss_pending & axi_last_data_beat; rvdff #(1) act_miss_ff (.*, .clk(free_clk), .din (ic_act_miss_f2), .dout(ic_act_miss_f2_delayed)); - assign reset_tag_valid_for_miss = ic_act_miss_f2_delayed & (miss_state == CRIT_BYP_OK) ; + assign reset_tag_valid_for_miss = ic_act_miss_f2_delayed & (miss_state == CRIT_BYP_OK) ; assign w0_wren_reset_miss = (replace_way_mb_any[3:0] == 4'b0001) & reset_tag_valid_for_miss ; assign w1_wren_reset_miss = (replace_way_mb_any[3:0] == 4'b0010) & reset_tag_valid_for_miss ; assign w2_wren_reset_miss = (replace_way_mb_any[3:0] == 4'b0100) & reset_tag_valid_for_miss ; assign w3_wren_reset_miss = (replace_way_mb_any[3:0] == 4'b1000) & reset_tag_valid_for_miss ; - + assign axi_ifu_wr_data_error = |ifu_axi_rresp_ff[1:0] & ifu_axi_rvalid_ff & miss_pending; rvdff #(1) dma_ok_prev_ff (.*, .clk(free_clk), .din(ifc_dma_access_ok_d), .dout(ifc_dma_access_ok_prev)); @@ -1130,25 +1137,25 @@ assign axi_ifu_bus_clk_en = ifu_bus_clk_en ; assign last_beat = axi_last_data_beat ; assign ifu_wr_data_error = axi_ifu_wr_data_error ; assign reset_beat_cnt = axi_reset_data_beat_cnt ; - + // DMA // Making sure that the dma_access is allowed when we have 2 back to back dma_access_ok. Also gating with current state == idle assign ifc_dma_access_ok_d = ifc_dma_access_ok & ~iccm_correct_ecc; - assign ifc_dma_access_q_ok = ifc_dma_access_ok & ~iccm_correct_ecc & ifc_dma_access_ok_prev & (perr_state == ERR_IDLE) ; + assign ifc_dma_access_q_ok = ifc_dma_access_ok & ~iccm_correct_ecc & ifc_dma_access_ok_prev & (perr_state == ERR_IDLE) ; assign iccm_ready = ifc_dma_access_q_ok ; `ifdef RV_ICCM_ENABLE logic dma_select_upper ; logic iccm_dma_rden ; - + // logic ic_dma_active_in; logic iccm_dma_ecc_error_in; logic [13:0] dma_mem_ecc; logic [63:0] iccm_dma_rdata_in; - + // assign ic_dma_active_in = ifc_dma_access_q_ok & dma_iccm_req ; assign iccm_wren = (ifc_dma_access_q_ok & dma_iccm_req & dma_mem_write) | iccm_correct_ecc; - assign iccm_rden = (ifc_dma_access_q_ok & dma_iccm_req & ~dma_mem_write) | ifc_iccm_access_f1; + assign iccm_rden = (ifc_dma_access_q_ok & dma_iccm_req & ~dma_mem_write) | (ifc_iccm_access_f1 & ifc_fetch_req_f1); assign iccm_dma_rden = (ifc_dma_access_q_ok & dma_iccm_req & ~dma_mem_write) ; assign iccm_wr_size[2:0] = {3{dma_iccm_req & dma_mem_write}} & dma_mem_sz[2:0] ; @@ -1160,31 +1167,31 @@ assign axi_ifu_bus_clk_en = ifu_bus_clk_en ; .din(dma_mem_wdata[63:32]), .ecc_out(dma_mem_ecc[13:7])); - assign iccm_wr_data[38:0] = (iccm_correct_ecc & ~(ifc_dma_access_q_ok & dma_iccm_req)) ? iccm_ecc_corr_data_ff[38:0] : + assign iccm_wr_data[38:0] = (iccm_correct_ecc & ~(ifc_dma_access_q_ok & dma_iccm_req)) ? iccm_ecc_corr_data_ff[38:0] : {dma_mem_ecc[ 6:0],dma_mem_wdata[31:0]}; assign iccm_wr_data[77:39] = (iccm_correct_ecc & ~(ifc_dma_access_q_ok & dma_iccm_req)) ? iccm_ecc_corr_data_ff[38:0] : {dma_mem_ecc[13:7],dma_mem_wdata[63:32]}; assign iccm_dma_rdata_in[63:0] = iccm_dma_ecc_error_in ? {2{dma_mem_addr[31:0]}} : dma_select_upper ? {iccm_corrected_data[3], iccm_corrected_data[2]} : {iccm_corrected_data[1],iccm_corrected_data[0]}; assign iccm_dma_ecc_error_in = dma_select_upper ? |(iccm_double_ecc_error[3:2]) : |(iccm_double_ecc_error[1:0]); - + rvdff #(1) dma_addr_bt3_ff (.*, .clk(free_clk), .din(dma_mem_addr[3]), .dout(dma_select_upper)); rvdff #(1) ccm_rdy_in_ff (.*, .clk(free_clk), .din(iccm_dma_rden), .dout(iccm_dma_rvalid_in)); rvdff #(1) ccm_rdy_ff (.*, .clk(free_clk), .din(iccm_dma_rvalid_in), .dout(iccm_dma_rvalid)); rvdff #(1) ccm_err_ff (.*, .clk(free_clk), .din(iccm_dma_ecc_error_in), .dout(iccm_dma_ecc_error)); rvdff #(64) dma_data_ff (.*, .clk(free_clk), .din(iccm_dma_rdata_in[63:0]), .dout(iccm_dma_rdata[63:0])); - - assign iccm_rw_addr[ICCM_BITS-1:2] = ( ifc_dma_access_q_ok & dma_iccm_req & ~iccm_correct_ecc) ? dma_mem_addr[ICCM_BITS-1:2] : + + assign iccm_rw_addr[ICCM_BITS-1:2] = ( ifc_dma_access_q_ok & dma_iccm_req & ~iccm_correct_ecc) ? dma_mem_addr[ICCM_BITS-1:2] : (~(ifc_dma_access_q_ok & dma_iccm_req) & iccm_correct_ecc) ? iccm_ecc_corr_index_ff[ICCM_BITS-1:2] : fetch_addr_f1[ICCM_BITS-1:2] ; `else assign iccm_dma_rvalid = 1'b0 ; assign iccm_dma_ecc_error = 1'b0 ; - assign iccm_dma_rdata[63:0] = '0 ; + assign iccm_dma_rdata[63:0] = '0 ; `endif ////// ICCM signals - + assign ic_rd_en = ifc_fetch_req_f1 & ~ifc_fetch_uncacheable_f1; assign ifu_tag_wren[0] = axi_w0_wren_last | w0_wren_reset_miss; @@ -1204,24 +1211,24 @@ assign ic_write_stall = ifu_wr_en_new & ~(((miss_state== CRIT_BYP_OK) & ~(ifu_ /////////////////////////////////////////////////////////////// // Icache status and LRU /////////////////////////////////////////////////////////////// -`ifdef RV_ICACHE_ENABLE +`ifdef RV_ICACHE_ENABLE assign ic_valid = ~ifu_wr_cumulative_err_data & ~(reset_ic_in | reset_ic_ff) & ~reset_tag_valid_for_miss; - assign ifu_status_wr_addr_w_debug[ICACHE_TAG_HIGH-1:ICACHE_TAG_LOW] = ((ic_debug_rd_en | ic_debug_wr_en ) & ic_debug_tag_array) ? + assign ifu_status_wr_addr_w_debug[ICACHE_TAG_HIGH-1:ICACHE_TAG_LOW] = ((ic_debug_rd_en | ic_debug_wr_en ) & ic_debug_tag_array) ? ic_debug_addr[ICACHE_TAG_HIGH-1:ICACHE_TAG_LOW] : ifu_status_wr_addr[ICACHE_TAG_HIGH-1:ICACHE_TAG_LOW]; - // status - rvdff #(ICACHE_TAG_HIGH-ICACHE_TAG_LOW) status_wr_addr_ff (.*, .clk(free_clk), .din(ifu_status_wr_addr_w_debug[ICACHE_TAG_HIGH-1:ICACHE_TAG_LOW]), + // status + rvdff #(ICACHE_TAG_HIGH-ICACHE_TAG_LOW) status_wr_addr_ff (.*, .clk(free_clk), .din(ifu_status_wr_addr_w_debug[ICACHE_TAG_HIGH-1:ICACHE_TAG_LOW]), .dout(ifu_status_wr_addr_ff[ICACHE_TAG_HIGH-1:ICACHE_TAG_LOW])); assign way_status_wr_en_w_debug = way_status_wr_en | (ic_debug_wr_en & ic_debug_tag_array); rvdff #(1) status_wren_ff (.*, .clk(free_clk), .din(way_status_wr_en_w_debug), .dout(way_status_wr_en_ff)); - - assign way_status_new_w_debug[2:0] = (ic_debug_wr_en & ic_debug_tag_array) ? ic_debug_wr_data[6:4] : + + assign way_status_new_w_debug[2:0] = (ic_debug_wr_en & ic_debug_tag_array) ? ic_debug_wr_data[6:4] : way_status_new[2:0] ; rvdff #(3) status_data_ff (.*, .clk(free_clk), .din(way_status_new_w_debug[2:0]), .dout(way_status_new_ff[2:0])); - + logic [(ICACHE_TAG_DEPTH/8)-1 : 0] way_status_clken; logic [(ICACHE_TAG_DEPTH/8)-1 : 0] way_status_clk; @@ -1231,39 +1238,39 @@ assign ic_write_stall = ifu_wr_en_new & ~(((miss_state== CRIT_BYP_OK) & ~(ifu_ rvclkhdr way_status_cgc ( .en(way_status_clken[i]), .l1clk(way_status_clk[i]), .* ); for (j=0 ; j<8 ; j++) begin : WAY_STATUS - rvdffs #(3) ic_way_status (.*, + rvdffs #(3) ic_way_status (.*, .clk(way_status_clk[i]), .en(((ifu_status_wr_addr_ff[ICACHE_TAG_LOW+2:ICACHE_TAG_LOW] == j) & way_status_wr_en_ff)), - .din(way_status_new_ff[2:0]), + .din(way_status_new_ff[2:0]), .dout(way_status_out[8*i+j])); end // WAY_STATUS end // CLK_GRP_WAY_STATUS - always_comb begin : way_status_out_mux - way_status[2:0] = 3'b0 ; - for (int j=0; j< ICACHE_TAG_DEPTH; j++) begin : status_mux_loop - if (ifu_ic_rw_int_addr_ff[ICACHE_TAG_HIGH-1:ICACHE_TAG_LOW] == (ICACHE_TAG_HIGH-ICACHE_TAG_LOW)'(j)) begin : mux_out + always_comb begin : way_status_out_mux + way_status[2:0] = 3'b0 ; + for (int j=0; j< ICACHE_TAG_DEPTH; j++) begin : status_mux_loop + if (ifu_ic_rw_int_addr_ff[ICACHE_TAG_HIGH-1:ICACHE_TAG_LOW] == (ICACHE_TAG_HIGH-ICACHE_TAG_LOW)'(j)) begin : mux_out way_status[2:0] = way_status_out[j]; end end end -assign ifu_ic_rw_int_addr_w_debug[ICACHE_TAG_HIGH-1:ICACHE_TAG_LOW] = ((ic_debug_rd_en | ic_debug_wr_en ) & ic_debug_tag_array) ? +assign ifu_ic_rw_int_addr_w_debug[ICACHE_TAG_HIGH-1:ICACHE_TAG_LOW] = ((ic_debug_rd_en | ic_debug_wr_en ) & ic_debug_tag_array) ? ic_debug_addr[ICACHE_TAG_HIGH-1:ICACHE_TAG_LOW] : ifu_ic_rw_int_addr[ICACHE_TAG_HIGH-1:ICACHE_TAG_LOW]; - rvdff #(ICACHE_TAG_HIGH-ICACHE_TAG_LOW) tag_addr_ff (.*, .clk(free_clk), - .din(ifu_ic_rw_int_addr_w_debug[ICACHE_TAG_HIGH-1:ICACHE_TAG_LOW]), + rvdff #(ICACHE_TAG_HIGH-ICACHE_TAG_LOW) tag_addr_ff (.*, .clk(free_clk), + .din(ifu_ic_rw_int_addr_w_debug[ICACHE_TAG_HIGH-1:ICACHE_TAG_LOW]), .dout(ifu_ic_rw_int_addr_ff[ICACHE_TAG_HIGH-1:ICACHE_TAG_LOW])); assign ifu_tag_wren_w_debug[3:0] = ifu_tag_wren[3:0] | ic_debug_tag_wr_en[3:0] ; - rvdff #(4) tag_v_we_ff (.*, .clk(free_clk), - .din(ifu_tag_wren_w_debug[3:0]), + rvdff #(4) tag_v_we_ff (.*, .clk(free_clk), + .din(ifu_tag_wren_w_debug[3:0]), .dout(ifu_tag_wren_ff[3:0])); assign ic_valid_w_debug = (ic_debug_wr_en & ic_debug_tag_array) ? ic_debug_wr_data[0] : ic_valid; - rvdff #(1) tag_v_ff (.*, .clk(free_clk), - .din(ic_valid_w_debug), + rvdff #(1) tag_v_ff (.*, .clk(free_clk), + .din(ic_valid_w_debug), .dout(ic_valid_ff)); logic [3:0] [ICACHE_TAG_DEPTH-1:0] ic_tag_valid_out ; @@ -1278,16 +1285,16 @@ assign ifu_ic_rw_int_addr_w_debug[ICACHE_TAG_HIGH-1:ICACHE_TAG_LOW] = ((ic_debug logic [(ICACHE_TAG_DEPTH/32)-1:0] tag_valid_w2_clk ; logic [(ICACHE_TAG_DEPTH/32)-1:0] tag_valid_w3_clk ; - + for (i=0 ; i ~ifc_fetch_req_f1; endproperty - assert_fetch_stall: assert property (fetch_stall) else - $display("Assertion fetch_stall: ic_debug_rd_en=1'b%b, ic_debug_wr_en=1'b%b, ic_dma_active=1'b%b, ic_write_stall=1'b%b",ic_debug_rd_en,ic_debug_wr_en, ic_dma_active, ic_write_stall); + assert_fetch_stall: assert property (fetch_stall) else + $display("Assertion fetch_stall: ic_debug_rd_en=1'b%b, ic_debug_wr_en=1'b%b, ic_dma_active=1'b%b, ic_write_stall=1'b%b",ic_debug_rd_en,ic_debug_wr_en, ic_dma_active, ic_write_stall); + - assert_perr_one_z_hot: assert #0 ($onehot0({ifu_icache_error_val,ifu_icache_sb_error_val})); `endif diff --git a/design/include/build.h b/design/include/build.h index 0304711..4f9c71e 100644 --- a/design/include/build.h +++ b/design/include/build.h @@ -1,12 +1,12 @@ // 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. diff --git a/design/include/global.h b/design/include/global.h index 4c33dad..6fa40bc 100644 --- a/design/include/global.h +++ b/design/include/global.h @@ -1,12 +1,12 @@ // 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. @@ -38,14 +38,14 @@ localparam ICCM_INDEX_BITS = `RV_ICCM_INDEX_BITS; localparam ICCM_BANK_HI = 4 + (`RV_ICCM_BANK_BITS/4); localparam ICACHE_TAG_HIGH = `RV_ICACHE_TAG_HIGH; -localparam ICACHE_TAG_LOW = `RV_ICACHE_TAG_LOW; -localparam ICACHE_IC_DEPTH = `RV_ICACHE_IC_DEPTH; +localparam ICACHE_TAG_LOW = `RV_ICACHE_TAG_LOW; +localparam ICACHE_IC_DEPTH = `RV_ICACHE_IC_DEPTH; localparam ICACHE_TAG_DEPTH = `RV_ICACHE_TAG_DEPTH; localparam LSU_BUS_TAG = `RV_LSU_BUS_TAG; localparam DMA_BUS_TAG = `RV_DMA_BUS_TAG; localparam SB_BUS_TAG = `RV_SB_BUS_TAG; - + localparam IFU_BUS_TAG = `RV_IFU_BUS_TAG; diff --git a/design/include/swerv_types.sv b/design/include/swerv_types.sv index 65ecafa..bd79c76 100644 --- a/design/include/swerv_types.sv +++ b/design/include/swerv_types.sv @@ -1,12 +1,12 @@ // 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. @@ -18,18 +18,18 @@ package swerv_types; typedef struct packed { logic [2:0] trace_rv_i_valid_ip; logic [95:0] trace_rv_i_insn_ip; - logic [95:0] trace_rv_i_address_ip; + logic [95:0] trace_rv_i_address_ip; logic [2:0] trace_rv_i_exception_ip; - logic [4:0] trace_rv_i_ecause_ip; - logic [2:0] trace_rv_i_interrupt_ip; + logic [4:0] trace_rv_i_ecause_ip; + logic [2:0] trace_rv_i_interrupt_ip; logic [31:0] trace_rv_i_tval_ip; } trace_pkt_t; typedef enum logic [3:0] { NULL = 4'b0000, - MUL = 4'b0001, - LOAD = 4'b0010, + MUL = 4'b0001, + LOAD = 4'b0010, STORE = 4'b0011, ALU = 4'b0100, CSRREAD = 4'b0101, @@ -45,7 +45,7 @@ typedef enum logic [3:0] { } inst_t; typedef struct packed { -`ifdef RV_ICACHE_ECC +`ifdef RV_ICACHE_ECC logic [39:0] ecc; `else logic [7:0] parity; @@ -103,15 +103,15 @@ typedef struct packed { } br_tlu_pkt_t; typedef struct packed { - logic misp; + logic misp; logic ataken; - logic boffset; + logic boffset; logic pc4; - logic [1:0] hist; + logic [1:0] hist; logic [11:0] toffset; - logic [`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO] index; - logic [1:0] bank; - logic valid; + logic [`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO] index; + logic [1:0] bank; + logic valid; logic br_error; logic br_start_error; logic [31:1] prett; @@ -130,7 +130,7 @@ typedef struct packed { typedef struct packed { logic legal; logic icaf; - logic icaf_f1; + logic icaf_f1; logic perr; logic sbecc; logic fence_i; @@ -146,7 +146,7 @@ typedef struct packed { typedef struct packed { logic [4:0] i0rd; - logic i0mul; + logic i0mul; logic i0load; logic i0store; logic i0div; @@ -154,11 +154,11 @@ typedef struct packed { logic i0valid; logic i0secondary; logic [1:0] i0rs1bype2; - logic [1:0] i0rs2bype2; + logic [1:0] i0rs2bype2; logic [3:0] i0rs1bype3; - logic [3:0] i0rs2bype3; + logic [3:0] i0rs2bype3; logic [4:0] i1rd; - logic i1mul; + logic i1mul; logic i1load; logic i1store; logic i1v; @@ -166,11 +166,11 @@ typedef struct packed { logic csrwen; logic csrwonly; logic [11:0] csrwaddr; - logic i1secondary; + logic i1secondary; logic [1:0] i1rs1bype2; - logic [1:0] i1rs2bype2; + logic [1:0] i1rs2bype2; logic [6:0] i1rs1bype3; - logic [6:0] i1rs2bype3; + logic [6:0] i1rs2bype3; } dest_pkt_t; typedef struct packed { @@ -192,7 +192,7 @@ typedef struct packed { logic land; logic lor; logic lxor; - logic sll; + logic sll; logic srl; logic sra; logic beq; @@ -230,13 +230,13 @@ typedef struct packed { } lsu_pkt_t; typedef struct packed { - logic exc_valid; - logic single_ecc_error; - logic inst_type; //0: Load, 1: Store + logic exc_valid; + logic single_ecc_error; + logic inst_type; //0: Load, 1: Store logic inst_pipe; //0: i0, 1: i1 logic dma_valid; - logic exc_type; //0: MisAligned, 1: Access Fault - logic [31:0] addr; + logic exc_type; //0: MisAligned, 1: Access Fault + logic [31:0] addr; } lsu_error_pkt_t; typedef struct packed { @@ -276,7 +276,7 @@ typedef struct packed { logic csr_write; logic csr_imm; logic presync; - logic postsync; + logic postsync; logic ebreak; logic ecall; logic mret; @@ -299,7 +299,7 @@ typedef struct packed { logic rs2_sign; logic low; logic load_mul_rs1_bypass_e1; - logic load_mul_rs2_bypass_e1; + logic load_mul_rs2_bypass_e1; } mul_pkt_t; typedef struct packed { @@ -316,12 +316,12 @@ typedef struct packed { logic load; logic execute; logic m; - logic [31:0] tdata2; + logic [31:0] tdata2; } trigger_pkt_t; - + typedef struct packed { -`ifdef RV_ICACHE_ECC +`ifdef RV_ICACHE_ECC logic [41:0] icache_wrdata; // {dicad0[31:0], dicad1[1:0]} `else logic [33:0] icache_wrdata; // {dicad0[31:0], dicad1[1:0]} diff --git a/design/lib/ahb_to_axi4.sv b/design/lib/ahb_to_axi4.sv index 6f2e43c..6d958b2 100644 --- a/design/lib/ahb_to_axi4.sv +++ b/design/lib/ahb_to_axi4.sv @@ -1,12 +1,12 @@ // 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. @@ -15,8 +15,8 @@ //******************************************************************************** // $Id$ // -// Owner: -// Function: AHB to AXI4 Bridge +// Owner: +// Function: AHB to AXI4 Bridge // Comments: // //******************************************************************************** @@ -24,11 +24,11 @@ module ahb_to_axi4 #(parameter TAG = 1) ( input clk, input rst_l, - input scan_mode, - input bus_clk_en, + input scan_mode, + input bus_clk_en, input clk_override, - - // AXI signals + + // AXI signals // AXI Write Channels output logic axi_awvalid, input logic axi_awready, @@ -37,9 +37,9 @@ module ahb_to_axi4 #(parameter TAG = 1) ( output logic [2:0] axi_awsize, output logic [2:0] axi_awprot, output logic [7:0] axi_awlen, - output logic [1:0] axi_awburst, + output logic [1:0] axi_awburst, - output logic axi_wvalid, + output logic axi_wvalid, input logic axi_wready, output logic [63:0] axi_wdata, output logic [7:0] axi_wstrb, @@ -48,25 +48,25 @@ module ahb_to_axi4 #(parameter TAG = 1) ( input logic axi_bvalid, output logic axi_bready, input logic [1:0] axi_bresp, - input logic [TAG-1:0] axi_bid, + input logic [TAG-1:0] axi_bid, // AXI Read Channels output logic axi_arvalid, input logic axi_arready, output logic [TAG-1:0] axi_arid, - output logic [31:0] axi_araddr, + output logic [31:0] axi_araddr, output logic [2:0] axi_arsize, output logic [2:0] axi_arprot, output logic [7:0] axi_arlen, - output logic [1:0] axi_arburst, + output logic [1:0] axi_arburst, input logic axi_rvalid, output logic axi_rready, input logic [TAG-1:0] axi_rid, input logic [63:0] axi_rdata, - input logic [1:0] axi_rresp, + input logic [1:0] axi_rresp, - // AHB-Lite signals + // AHB-Lite signals input logic [31:0] ahb_haddr, // ahb bus address input logic [2:0] ahb_hburst, // tied to 0 input logic ahb_hmastlock, // tied to 0 @@ -76,9 +76,9 @@ module ahb_to_axi4 #(parameter TAG = 1) ( 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 + 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) @@ -86,29 +86,29 @@ module ahb_to_axi4 #(parameter TAG = 1) ( logic [7:0] master_wstrb; - typedef enum logic [1:0] { IDLE = 2'b00, // Nothing in the buffer. No commands yet recieved + 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 [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 [63:0] ahb_hwdata_q; logic ahb_hresp_q; - + //Miscellaneous signals - logic ahb_addr_in_dccm, ahb_addr_in_iccm, ahb_addr_in_pic; + 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; // 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; @@ -125,21 +125,21 @@ module ahb_to_axi4 #(parameter TAG = 1) ( logic [63:0] cmdbuf_wdata; logic bus_clk; - + // 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_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; + 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); + 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 @@ -148,30 +148,30 @@ module ahb_to_axi4 #(parameter TAG = 1) ( 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. + 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 + 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 #($bits(state_t)) state_reg (.*, .din(buf_nxtstate), .dout({buf_state}), .en(buf_state_en), .clk(ahb_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]; - assign ahb_hresp = ((ahb_htrans_q[1:0] != 2'b0) & (buf_state != IDLE) & + 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 @@ -183,19 +183,19 @@ module ahb_to_axi4 #(parameter TAG = 1) ( // Buffer signals - needed for the read data and ECC error response rvdff #(.WIDTH(64)) buf_rdata_ff (.din(axi_rdata[63:0]), .dout(buf_rdata[63:0]), .clk(buf_rdata_clk), .*); rvdff #(.WIDTH(1)) buf_read_error_ff(.din(buf_read_error_in), .dout(buf_read_error), .clk(ahb_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 #(.WIDTH(1)) hresp_ff (.din(ahb_hresp), .dout(ahb_hresp_q), .clk(ahb_clk), .*); rvdff #(.WIDTH(1)) hready_ff (.din(ahb_hready), .dout(ahb_hready_q), .clk(ahb_clk), .*); rvdff #(.WIDTH(2)) htrans_ff (.din(ahb_htrans_in[1:0]), .dout(ahb_htrans_q[1:0]), .clk(ahb_clk), .*); rvdff #(.WIDTH(3)) hsize_ff (.din(ahb_hsize[2:0]), .dout(ahb_hsize_q[2:0]), .clk(ahb_addr_clk), .*); rvdff #(.WIDTH(1)) hwrite_ff (.din(ahb_hwrite), .dout(ahb_hwrite_q), .clk(ahb_addr_clk), .*); - rvdff #(.WIDTH(32)) haddr_ff (.din(ahb_haddr[31:0]), .dout(ahb_haddr_q[31:0]), .clk(ahb_addr_clk), .*); - + rvdff #(.WIDTH(32)) haddr_ff (.din(ahb_haddr[31:0]), .dout(ahb_haddr_q[31:0]), .clk(ahb_addr_clk), .*); + // Clock header logic assign ahb_bus_addr_clk_en = bus_clk_en & (ahb_hready & ahb_htrans[1]); assign buf_rdata_clk_en = bus_clk_en & buf_rdata_en; - + rvclkhdr ahb_cgc (.en(bus_clk_en), .l1clk(ahb_clk), .*); rvclkhdr ahb_addr_cgc (.en(ahb_bus_addr_clk_en), .l1clk(ahb_addr_clk), .*); rvclkhdr buf_rdata_cgc (.en(buf_rdata_clk_en), .l1clk(buf_rdata_clk), .*); @@ -207,7 +207,7 @@ module ahb_to_axi4 #(parameter TAG = 1) ( .in_range(ahb_addr_in_dccm), .in_region(ahb_addr_in_dccm_region_nc) ); - + // Address check iccm `ifdef RV_ICCM_ENABLE rvrangecheck #(.CCM_SADR(`RV_ICCM_SADR), @@ -220,7 +220,7 @@ module ahb_to_axi4 #(parameter TAG = 1) ( assign ahb_addr_in_iccm = '0; assign ahb_addr_in_iccm_region_nc = '0; `endif - + // PIC memory address check rvrangecheck #(.CCM_SADR(`RV_PIC_BASE_ADDR), .CCM_SIZE(`RV_PIC_SIZE)) addr_pic_rangecheck ( @@ -232,16 +232,16 @@ module ahb_to_axi4 #(parameter TAG = 1) ( // 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 #(.WIDTH(1)) cmdbuf_vldff (.din(1'b1), .dout(cmdbuf_vld), .en(cmdbuf_wr_en), .clear(cmdbuf_rst), .clk(bus_clk), .*); rvdffs #(.WIDTH(1)) cmdbuf_writeff (.din(ahb_hwrite_q), .dout(cmdbuf_write), .en(cmdbuf_wr_en), .clk(bus_clk), .*); rvdffs #(.WIDTH(2)) cmdbuf_sizeff (.din(ahb_hsize_q[1:0]), .dout(cmdbuf_size[1:0]), .en(cmdbuf_wr_en), .clk(bus_clk), .*); rvdffs #(.WIDTH(8)) cmdbuf_wstrbff (.din(master_wstrb[7:0]), .dout(cmdbuf_wstrb[7:0]), .en(cmdbuf_wr_en), .clk(bus_clk), .*); rvdffe #(.WIDTH(32)) cmdbuf_addrff (.din(ahb_haddr_q[31:0]), .dout(cmdbuf_addr[31:0]), .en(cmdbuf_wr_en), .clk(bus_clk), .*); rvdffe #(.WIDTH(64)) cmdbuf_wdataff (.din(ahb_hwdata[63:0]), .dout(cmdbuf_wdata[63:0]), .en(cmdbuf_wr_en), .clk(bus_clk), .*); - + // AXI Write Command Channel - assign axi_awvalid = cmdbuf_vld & cmdbuf_write; + 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]}; @@ -249,7 +249,7 @@ module ahb_to_axi4 #(parameter TAG = 1) ( 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_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; @@ -258,17 +258,17 @@ module ahb_to_axi4 #(parameter TAG = 1) ( // 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_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 rvclkhdr bus_cgc (.en(bus_clk_en), .l1clk(bus_clk), .*); - + `ifdef ASSERT_ON property ahb_error_protocol; @(posedge ahb_clk) (ahb_hready & ahb_hresp) |-> (~$past(ahb_hready) & $past(ahb_hresp)); @@ -277,5 +277,5 @@ module ahb_to_axi4 #(parameter TAG = 1) ( $display("Bus Error with hReady isn't preceded with Bus Error without hready"); `endif - + endmodule // ahb_to_axi4 \ No newline at end of file diff --git a/design/lib/axi4_to_ahb.sv b/design/lib/axi4_to_ahb.sv index ab17e12..20d6a48 100644 --- a/design/lib/axi4_to_ahb.sv +++ b/design/lib/axi4_to_ahb.sv @@ -1,12 +1,12 @@ // 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. @@ -16,8 +16,8 @@ //******************************************************************************** // $Id$ // -// Owner: -// Function: AXI4 -> AHB Bridge +// Owner: +// Function: AXI4 -> AHB Bridge // Comments: // //******************************************************************************** @@ -25,11 +25,11 @@ module axi4_to_ahb #(parameter TAG = 1) ( input clk, input rst_l, - input scan_mode, - input bus_clk_en, + input scan_mode, + input bus_clk_en, input clk_override, - - // AXI signals + + // AXI signals // AXI Write Channels input logic axi_awvalid, output logic axi_awready, @@ -38,7 +38,7 @@ module axi4_to_ahb #(parameter TAG = 1) ( input logic [2:0] axi_awsize, input logic [2:0] axi_awprot, - input logic axi_wvalid, + input logic axi_wvalid, output logic axi_wready, input logic [63:0] axi_wdata, input logic [7:0] axi_wstrb, @@ -53,7 +53,7 @@ module axi4_to_ahb #(parameter TAG = 1) ( input logic axi_arvalid, output logic axi_arready, input logic [TAG-1:0] axi_arid, - input logic [31:0] axi_araddr, + input logic [31:0] axi_araddr, input logic [2:0] axi_arsize, input logic [2:0] axi_arprot, @@ -62,9 +62,9 @@ module axi4_to_ahb #(parameter TAG = 1) ( output logic [TAG-1:0] axi_rid, output logic [63:0] axi_rdata, output logic [1:0] axi_rresp, - output logic axi_rlast, + output logic axi_rlast, - // AHB-Lite signals + // AHB-Lite signals output logic [31:0] ahb_haddr, // ahb bus address output logic [2:0] ahb_hburst, // tied to 0 output logic ahb_hmastlock, // tied to 0 @@ -74,7 +74,7 @@ module axi4_to_ahb #(parameter TAG = 1) ( 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 [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) @@ -100,25 +100,25 @@ module axi4_to_ahb #(parameter TAG = 1) ( logic [31:0] wrbuf_addr; logic [63:0] wrbuf_data; logic [7:0] wrbuf_byteen; - + logic bus_write_clk_en; logic bus_clk, bus_write_clk; - + logic master_valid; logic master_ready; logic [TAG-1:0] master_tag; - logic [31:0] master_addr; + logic [31:0] master_addr; logic [63:0] master_wdata; logic [2:0] master_size; logic [2:0] master_opc; - + // 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 [63:0] buf_data; logic [TAG-1:0] buf_tag; //Miscellaneous signals @@ -130,19 +130,19 @@ module axi4_to_ahb #(parameter TAG = 1) ( 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; @@ -157,9 +157,9 @@ module axi4_to_ahb #(parameter TAG = 1) ( logic slvbuf_error_in; logic slvbuf_wr_en; - logic bypass_en; + logic bypass_en; logic rd_bypass_idle; - + logic last_addr_en; logic [31:0] last_bus_addr; @@ -172,32 +172,32 @@ module axi4_to_ahb #(parameter TAG = 1) ( logic ahbm_clk; logic ahbm_addr_clk; logic ahbm_data_clk; - + // 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'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]; + + 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]; + + return addr[2:0]; endfunction // get_write_size // Function to get the next byte pointer @@ -211,22 +211,22 @@ module axi4_to_ahb #(parameter TAG = 1) ( if (~found) begin get_nxtbyte_ptr[2:0] = 3'(j); found |= (byteen[j] & (3'(j) >= start_ptr[2:0])) ; - end + end end endfunction // get_nextbyte_ptr - + // 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; - + 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_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]; @@ -234,21 +234,21 @@ module axi4_to_ahb #(parameter TAG = 1) ( 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_wdata[63:0] = wrbuf_data[63:0]; - + // AXI response channel signals assign axi_bvalid = slave_valid & slave_ready & slave_opc[3]; - assign axi_bresp[1:0] = slave_opc[0] ? 2'b10 : (slave_opc[1] ? 2'b11 : 2'b0); + 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_ready & (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_rvalid = slave_valid & slave_ready & (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]; + assign axi_rdata[63:0] = slave_rdata[63:0]; assign slave_ready = axi_bready & axi_rready; - + // Clock header logic assign bus_write_clk_en = bus_clk_en & ((axi_awvalid & axi_awready) | (axi_wvalid & axi_wready)); - + rvclkhdr bus_cgc (.en(bus_clk_en), .l1clk(bus_clk), .*); rvclkhdr bus_write_cgc (.en(bus_write_clk_en), .l1clk(bus_write_clk), .*); @@ -265,14 +265,14 @@ module axi4_to_ahb #(parameter TAG = 1) ( 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; + 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; @@ -288,11 +288,11 @@ module axi4_to_ahb #(parameter TAG = 1) ( 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_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; + cmd_done = buf_state_en & ~master_valid; slvbuf_wr_en = buf_state_en; - master_ready = buf_state_en & (buf_nxtstate == STREAM_RD); + 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]; @@ -301,7 +301,7 @@ module axi4_to_ahb #(parameter TAG = 1) ( 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_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; @@ -311,7 +311,7 @@ module axi4_to_ahb #(parameter TAG = 1) ( 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 + 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; @@ -336,15 +336,15 @@ module axi4_to_ahb #(parameter TAG = 1) ( 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) | + 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 & slave_ready; // Ready to accept new command if current command done and no error - buf_nxtstate = (ahb_hresp_q | ~slave_ready) ? DONE : - ((master_valid & master_ready) ? ((master_opc[2:1] == 2'b01) ? CMD_WR : CMD_RD) : IDLE); + buf_nxtstate = (ahb_hresp_q | ~slave_ready) ? DONE : + ((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; @@ -352,7 +352,7 @@ module axi4_to_ahb #(parameter TAG = 1) ( 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) & + 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; @@ -360,7 +360,7 @@ module axi4_to_ahb #(parameter TAG = 1) ( 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) : + 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: begin @@ -374,7 +374,7 @@ module axi4_to_ahb #(parameter TAG = 1) ( assign buf_rst = 1'b0; assign cmd_done_rst = slave_valid_pre; - assign buf_addr_in[2:0] = (buf_aligned_in & (master_opc[2:1] == 2'b01)) ? get_write_addr(wrbuf_byteen[7:0]) : master_addr[2:0]; + assign buf_addr_in[2:0] = (buf_aligned_in & (master_opc[2:1] == 2'b01)) ? get_write_addr(wrbuf_byteen[7:0]) : master_addr[2:0]; assign buf_addr_in[31:3] = master_addr[31:3]; assign buf_tag_in[TAG-1:0] = master_tag[TAG-1:0]; assign buf_byteen_in[7:0] = wrbuf_byteen[7:0]; @@ -382,18 +382,18 @@ module axi4_to_ahb #(parameter TAG = 1) ( assign buf_size_in[1:0] = (buf_aligned_in & (master_size[1:0] == 2'b11) & (master_opc[2:1] == 2'b01)) ? get_write_size(wrbuf_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) & - ((wrbuf_byteen[7:0] == 8'h3) | (wrbuf_byteen[7:0] == 8'hc) | (wrbuf_byteen[7:0] == 8'h30) | (wrbuf_byteen[7:0] == 8'hc0) | + ((master_size[1:0] == 2'b11) & + ((wrbuf_byteen[7:0] == 8'h3) | (wrbuf_byteen[7:0] == 8'hc) | (wrbuf_byteen[7:0] == 8'h30) | (wrbuf_byteen[7:0] == 8'hc0) | (wrbuf_byteen[7:0] == 8'hf) | (wrbuf_byteen[7:0] == 8'hf0) | (wrbuf_byteen[7:0] == 8'hff))); - + // Generate the ahb signals assign ahb_haddr[31:0] = bypass_en ? {master_addr[31:3],buf_cmd_byte_ptr[2:0]} : {buf_addr[31:3],buf_cmd_byte_ptr[2:0]}; - // assign ahb_hsize[2:0] = ((buf_state == CMD_RD) | (buf_state == STREAM_RD) | (buf_state == STREAM_ERR_RD) | rd_bypass_idle) ? 3'b011 : + // assign ahb_hsize[2:0] = ((buf_state == CMD_RD) | (buf_state == STREAM_RD) | (buf_state == STREAM_ERR_RD) | rd_bypass_idle) ? 3'b011 : // 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_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_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; @@ -404,10 +404,10 @@ module axi4_to_ahb #(parameter TAG = 1) ( 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) ? 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 #(.WIDTH(1)) wrbuf_vldff (.din(1'b1), .dout(wrbuf_vld), .en(wrbuf_en), .clear(wrbuf_rst), .clk(bus_clk), .*); rvdffsc #(.WIDTH(1)) wrbuf_data_vldff(.din(1'b1), .dout(wrbuf_data_vld), .en(wrbuf_data_en), .clear(wrbuf_rst), .clk(bus_clk), .*); rvdffs #(.WIDTH(TAG)) wrbuf_tagff (.din(axi_awid[TAG-1:0]), .dout(wrbuf_tag[TAG-1:0]), .en(wrbuf_en), .clk(bus_clk), .*); @@ -417,7 +417,7 @@ module axi4_to_ahb #(parameter TAG = 1) ( rvdffs #(.WIDTH(8)) wrbuf_byteenff (.din(axi_wstrb[7:0]), .dout(wrbuf_byteen[7:0]), .en(wrbuf_data_en), .clk(bus_clk), .*); rvdffs #(.WIDTH(32)) last_bus_addrff (.din(ahb_haddr[31:0]), .dout(last_bus_addr[31:0]), .en(last_addr_en), .clk(ahbm_clk), .*); - + rvdffsc #(.WIDTH($bits(state_t))) buf_state_ff (.din(buf_nxtstate), .dout({buf_state}), .en(buf_state_en), .clear(buf_rst), .clk(ahbm_clk), .*); rvdffs #(.WIDTH(1)) buf_writeff (.din(buf_write_in), .dout(buf_write), .en(buf_wr_en), .clk(buf_clk), .*); rvdffs #(.WIDTH(TAG)) buf_tagff (.din(buf_tag_in[TAG-1:0]), .dout(buf_tag[TAG-1:0]), .en(buf_wr_en), .clk(buf_clk), .*); @@ -426,12 +426,12 @@ module axi4_to_ahb #(parameter TAG = 1) ( rvdffs #(.WIDTH(1)) buf_alignedff (.din(buf_aligned_in), .dout(buf_aligned), .en(buf_wr_en), .clk(buf_clk), .*); rvdffs #(.WIDTH(8)) buf_byteenff (.din(buf_byteen_in[7:0]), .dout(buf_byteen[7:0]), .en(buf_wr_en), .clk(buf_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), .*); - - + + rvdffs #(.WIDTH(1)) slvbuf_writeff (.din(buf_write), .dout(slvbuf_write), .en(slvbuf_wr_en), .clk(buf_clk), .*); rvdffs #(.WIDTH(TAG)) slvbuf_tagff (.din(buf_tag[TAG-1:0]), .dout(slvbuf_tag[TAG-1:0]), .en(slvbuf_wr_en), .clk(buf_clk), .*); rvdffs #(.WIDTH(1)) slvbuf_errorff (.din(slvbuf_error_in), .dout(slvbuf_error), .en(slvbuf_error_en), .clk(ahbm_clk), .*); - + rvdffsc #(.WIDTH(1)) buf_cmd_doneff (.din(1'b1), .en(cmd_done), .dout(cmd_doneQ), .clear(cmd_done_rst), .clk(ahbm_clk), .*); rvdffs #(.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(ahbm_clk), .*); @@ -446,7 +446,7 @@ module axi4_to_ahb #(parameter TAG = 1) ( assign buf_clken = bus_clk_en & (buf_wr_en | slvbuf_wr_en | clk_override); assign ahbm_addr_clken = bus_clk_en & ((ahb_hready & ahb_htrans[1]) | clk_override); assign ahbm_data_clken = bus_clk_en & ((buf_state != IDLE) | clk_override); - + rvclkhdr buf_cgc (.en(buf_clken), .l1clk(buf_clk), .*); rvclkhdr ahbm_cgc (.en(bus_clk_en), .l1clk(ahbm_clk), .*); rvclkhdr ahbm_addr_cgc (.en(ahbm_addr_clken), .l1clk(ahbm_addr_clk), .*); @@ -459,14 +459,14 @@ module axi4_to_ahb #(parameter TAG = 1) ( ((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 + 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 ahbm_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/design/lib/beh_lib.sv b/design/lib/beh_lib.sv index 0540406..ac89b39 100644 --- a/design/lib/beh_lib.sv +++ b/design/lib/beh_lib.sv @@ -1,12 +1,12 @@ // 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. @@ -17,7 +17,7 @@ module rvdff #( parameter WIDTH=1 ) - ( + ( input logic [WIDTH-1:0] din, input logic clk, input logic rst_l, @@ -37,27 +37,27 @@ module rvdff #( parameter WIDTH=1 ) else dout[WIDTH-1:0] <= din[WIDTH-1:0]; end - - -endmodule + + +endmodule // rvdff with 2:1 input mux to flop din iff sel==1 module rvdffs #( parameter WIDTH=1 ) - ( + ( input logic [WIDTH-1:0] din, input logic en, input logic clk, input logic rst_l, output logic [WIDTH-1:0] dout ); - + rvdff #(WIDTH) dffs (.din((en) ? din[WIDTH-1:0] : dout[WIDTH-1:0]), .*); - -endmodule + +endmodule // rvdff with en and clear module rvdffsc #( parameter WIDTH=1 ) - ( + ( input logic [WIDTH-1:0] din, input logic en, input logic clear, @@ -70,24 +70,24 @@ module rvdffsc #( parameter WIDTH=1 ) assign din_new = {WIDTH{~clear}} & (en ? din[WIDTH-1:0] : dout[WIDTH-1:0]); rvdff #(WIDTH) dffsc (.din(din_new[WIDTH-1:0]), .*); -endmodule +endmodule module `TEC_RV_ICG ( input logic TE, E, CP, - output Q + output Q ); logic en_ff; logic enable; - + assign enable = E | TE; `ifdef VERILATOR always @(negedge CP) begin en_ff <= enable; end -`else +`else always @(CP, enable) begin if(!CP) en_ff = enable; @@ -107,7 +107,7 @@ module rvclkhdr logic TE; assign TE = scan_mode; - + `TEC_RV_ICG clkhdr ( .*, .E(en), .CP(clk), .Q(l1clk)); endmodule @@ -126,16 +126,16 @@ module rvoclkhdr `ifdef RV_FPGA_OPTIMIZE assign l1clk = clk; `else - `TEC_RV_ICG clkhdr ( .*, .E(en), .CP(clk), .Q(l1clk)); + `TEC_RV_ICG rvclkhdr ( .*, .E(en), .CP(clk), .Q(l1clk)); `endif endmodule module rvdffe #( parameter WIDTH=1 ) - ( + ( input logic [WIDTH-1:0] din, input logic en, - input logic clk, + input logic clk, input logic rst_l, input logic scan_mode, output logic [WIDTH-1:0] dout @@ -143,7 +143,8 @@ module rvdffe #( parameter WIDTH=1 ) logic l1clk; -`ifndef PHYSICAL + +`ifndef PHYSICAL if (WIDTH >= 8) begin: genblock `endif @@ -156,30 +157,30 @@ module rvdffe #( parameter WIDTH=1 ) `ifndef PHYSICAL end - else + else $error("%m: rvdffe width must be >= 8"); `endif - - + + endmodule // rvdffe module rvsyncss #(parameter WIDTH = 251) - ( + ( input logic clk, input logic rst_l, input logic [WIDTH-1:0] din, - output logic [WIDTH-1:0] dout + 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 rvlsadder - ( + ( input logic [31:0] rs1, input logic [11:0] offset, @@ -188,7 +189,7 @@ module rvlsadder logic cout; logic sign; - + logic [31:12] rs1_inc; logic [31:12] rs1_dec; @@ -203,13 +204,13 @@ module rvlsadder 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, @@ -218,7 +219,7 @@ module rvbradder logic cout; logic sign; - + logic [31:13] pc_inc; logic [31:13] pc_dec; @@ -234,44 +235,44 @@ module rvbradder 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; @@ -280,19 +281,19 @@ module rvfindfirst1 #( parameter WIDTH=32, SHIFT=$clog2(WIDTH) ) 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]; + done |= din[i]; end : find_first_one end endmodule // rvfindfirst1hot @@ -300,25 +301,25 @@ 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 + input logic masken, // when 1 : do mask. 0 : full match + output logic match ); - - logic [WIDTH-1:0] matchvec; + + 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 @@ -328,17 +329,17 @@ module rvbtb_tag_hash ( output logic [`RV_BTB_BTAG_SIZE-1:0] hash ); `ifndef RV_BTB_BTAG_FOLD - assign hash = {(pc[`RV_BTB_ADDR_HI+`RV_BTB_BTAG_SIZE+`RV_BTB_BTAG_SIZE+`RV_BTB_BTAG_SIZE:`RV_BTB_ADDR_HI+`RV_BTB_BTAG_SIZE+`RV_BTB_BTAG_SIZE+1] ^ - pc[`RV_BTB_ADDR_HI+`RV_BTB_BTAG_SIZE+`RV_BTB_BTAG_SIZE:`RV_BTB_ADDR_HI+`RV_BTB_BTAG_SIZE+1] ^ + assign hash = {(pc[`RV_BTB_ADDR_HI+`RV_BTB_BTAG_SIZE+`RV_BTB_BTAG_SIZE+`RV_BTB_BTAG_SIZE:`RV_BTB_ADDR_HI+`RV_BTB_BTAG_SIZE+`RV_BTB_BTAG_SIZE+1] ^ + pc[`RV_BTB_ADDR_HI+`RV_BTB_BTAG_SIZE+`RV_BTB_BTAG_SIZE:`RV_BTB_ADDR_HI+`RV_BTB_BTAG_SIZE+1] ^ pc[`RV_BTB_ADDR_HI+`RV_BTB_BTAG_SIZE:`RV_BTB_ADDR_HI+1])}; `else assign hash = {( - pc[`RV_BTB_ADDR_HI+`RV_BTB_BTAG_SIZE+`RV_BTB_BTAG_SIZE:`RV_BTB_ADDR_HI+`RV_BTB_BTAG_SIZE+1] ^ + pc[`RV_BTB_ADDR_HI+`RV_BTB_BTAG_SIZE+`RV_BTB_BTAG_SIZE:`RV_BTB_ADDR_HI+`RV_BTB_BTAG_SIZE+1] ^ pc[`RV_BTB_ADDR_HI+`RV_BTB_BTAG_SIZE:`RV_BTB_ADDR_HI+1])}; `endif - -// assign hash = {pc[`RV_BTB_ADDR_HI+1],(pc[`RV_BTB_ADDR_HI+13:`RV_BTB_ADDR_HI+10] ^ -// pc[`RV_BTB_ADDR_HI+9:`RV_BTB_ADDR_HI+6] ^ + +// assign hash = {pc[`RV_BTB_ADDR_HI+1],(pc[`RV_BTB_ADDR_HI+13:`RV_BTB_ADDR_HI+10] ^ +// pc[`RV_BTB_ADDR_HI+9:`RV_BTB_ADDR_HI+6] ^ // pc[`RV_BTB_ADDR_HI+5:`RV_BTB_ADDR_HI+2])}; endmodule @@ -348,12 +349,12 @@ module rvbtb_addr_hash ( output logic [`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO] hash ); - assign hash[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO] = pc[`RV_BTB_INDEX1_HI:`RV_BTB_INDEX1_LO] ^ + assign hash[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO] = pc[`RV_BTB_INDEX1_HI:`RV_BTB_INDEX1_LO] ^ -`ifndef RV_BTB_FOLD2_INDEX_HASH - pc[`RV_BTB_INDEX2_HI:`RV_BTB_INDEX2_LO] ^ +`ifndef RV_BTB_FOLD2_INDEX_HASH + pc[`RV_BTB_INDEX2_HI:`RV_BTB_INDEX2_LO] ^ `endif - + pc[`RV_BTB_INDEX3_HI:`RV_BTB_INDEX3_LO]; endmodule @@ -373,10 +374,10 @@ endmodule // Check if the S_ADDR <= addr < E_ADDR module rvrangecheck #(CCM_SADR = 32'h0, - CCM_SIZE = 128) ( + 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 + output logic in_region ); localparam REGION_BITS = 4; @@ -384,42 +385,42 @@ module rvrangecheck #(CCM_SADR = 32'h0, 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]); + 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) ( +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) ( +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]; @@ -448,7 +449,7 @@ module rvecc_decode ( 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]; @@ -461,8 +462,8 @@ module rvecc_decode ( 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 - + 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); @@ -470,9 +471,9 @@ module rvecc_decode ( // 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 diff --git a/design/lib/mem_lib.sv b/design/lib/mem_lib.sv index ccd0961..d9c59b5 100644 --- a/design/lib/mem_lib.sv +++ b/design/lib/mem_lib.sv @@ -1,12 +1,12 @@ // 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. @@ -17,14 +17,14 @@ //=================================== START OF CCM ======================================================================= //============= Possible sram sizes for a 39 bit wide memory ( 4 bytes + 7 bits ECC ) ===================================== //------------------------------------------------------------------------------------------------------------------------- -module ram_32768x39 +module ram_32768x39 ( input logic CLK, input logic [14:0] ADR, input logic [38:0] D, output logic [38:0] Q, input logic WE ); - + // behavior to be replaced by actual SRAM in VLE reg [38:0] ram_core [32767:0]; @@ -35,20 +35,20 @@ module ram_32768x39 Q <= ram_core[ADR]; end - + endmodule // ram_32768x39 -module ram_16384x39 +module ram_16384x39 ( input logic CLK, input logic [13:0] ADR, input logic [38:0] D, output logic [38:0] Q, input logic WE ); - + // behavior to be replaced by actual SRAM in VLE reg [38:0] ram_core [16383:0]; @@ -59,19 +59,19 @@ module ram_16384x39 Q <= ram_core[ADR]; end - + endmodule // ram_16384x39 -module ram_8192x39 +module ram_8192x39 ( input logic CLK, input logic [12:0] ADR, input logic [38:0] D, output logic [38:0] Q, input logic WE ); - + // behavior to be replaced by actual SRAM in VLE reg [38:0] ram_core [8191:0]; @@ -82,19 +82,19 @@ module ram_8192x39 Q <= ram_core[ADR]; end - + endmodule // ram_8192x39 -module ram_4096x39 +module ram_4096x39 ( input logic CLK, input logic [11:0] ADR, input logic [38:0] D, output logic [38:0] Q, input logic WE ); - + // behavior to be replaced by actual SRAM in VLE reg [38:0] ram_core [4095:0]; @@ -105,19 +105,19 @@ module ram_4096x39 Q <= ram_core[ADR]; end - + endmodule // ram_4096x39 -module ram_3072x39 +module ram_3072x39 ( input logic CLK, input logic [11:0] ADR, input logic [38:0] D, output logic [38:0] Q, input logic WE ); - + // behavior to be replaced by actual SRAM in VLE reg [38:0] ram_core [3071:0]; @@ -128,21 +128,21 @@ module ram_3072x39 Q <= ram_core[ADR]; end - + endmodule // ram_3072x39 -module ram_2048x39 +module ram_2048x39 ( input logic CLK, input logic [10:0] ADR, input logic [38:0] D, output logic [38:0] Q, input logic WE ); - + // behavior to be replaced by actual SRAM in VLE reg [38:0] ram_core [2047:0]; @@ -153,7 +153,7 @@ module ram_2048x39 Q <= ram_core[ADR]; end - + endmodule // ram_2048x39 @@ -165,7 +165,7 @@ module ram_1536x39 // need this for the 48KB DCCM option output logic [38:0] Q, input logic WE ); - + // behavior to be replaced by actual SRAM in VLE reg [38:0] ram_core [1535:0]; @@ -176,20 +176,20 @@ module ram_1536x39 // need this for the 48KB DCCM option Q <= ram_core[ADR]; end - + endmodule // ram_1536x39 -module ram_1024x39 +module ram_1024x39 ( input logic CLK, input logic [9:0] ADR, input logic [38:0] D, output logic [38:0] Q, input logic WE ); - + // behavior to be replaced by actual SRAM in VLE reg [38:0] ram_core [1023:0]; @@ -200,19 +200,19 @@ module ram_1024x39 Q <= ram_core[ADR]; end - + endmodule // ram_1024x39 -module ram_768x39 +module ram_768x39 ( input logic CLK, input logic [9:0] ADR, input logic [38:0] D, output logic [38:0] Q, input logic WE ); - + // behavior to be replaced by actual SRAM in VLE reg [38:0] ram_core [767:0]; @@ -223,20 +223,20 @@ module ram_768x39 Q <= ram_core[ADR]; end - + endmodule // ram_768x39 -module ram_512x39 +module ram_512x39 ( input logic CLK, input logic [8:0] ADR, input logic [38:0] D, output logic [38:0] Q, input logic WE ); - + // behavior to be replaced by actual SRAM in VLE reg [38:0] ram_core [511:0]; @@ -247,20 +247,20 @@ module ram_512x39 Q <= ram_core[ADR]; end - + endmodule // ram_512x39 -module ram_256x39 +module ram_256x39 ( input logic CLK, input logic [7:0] ADR, input logic [38:0] D, output logic [38:0] Q, input logic WE ); - + // behavior to be replaced by actual SRAM in VLE reg [38:0] ram_core [255:0]; @@ -271,20 +271,20 @@ module ram_256x39 Q <= ram_core[ADR]; end - + endmodule // ram_512x39 -module ram_128x39 +module ram_128x39 ( input logic CLK, input logic [6:0] ADR, input logic [38:0] D, output logic [38:0] Q, input logic WE ); - + // behavior to be replaced by actual SRAM in VLE reg [38:0] ram_core [127:0]; @@ -295,7 +295,7 @@ module ram_128x39 Q <= ram_core[ADR]; end - + endmodule // ram_128x39 @@ -303,7 +303,7 @@ endmodule // ram_128x39 //========================================================================================================================= //=================================== START OF TAGS ======================================================================= // I CACHE TAGS -module ram_1024x20 +module ram_1024x20 ( input logic CLK, input logic [9:0] ADR, @@ -311,7 +311,7 @@ module ram_1024x20 output logic [19:0] Q, input logic WE ); - + // behavior to be replaced by actual SRAM in VLE reg [19:0] ram_core [1023:0]; @@ -322,18 +322,18 @@ module ram_1024x20 Q <= ram_core[ADR]; end - + endmodule // ram_1024x20 -module ram_512x20 +module ram_512x20 ( input logic CLK, input logic [8:0] ADR, input logic [19:0] D, output logic [19:0] Q, input logic WE ); - + // behavior to be replaced by actual SRAM in VLE reg [19:0] ram_core [511:0]; @@ -349,14 +349,14 @@ module ram_512x20 endmodule // ram_512x20 -module ram_256x20 +module ram_256x20 ( input logic CLK, input logic [7:0] ADR, input logic [19:0] D, output logic [19:0] Q, input logic WE ); - + // behavior to be replaced by actual SRAM in VLE reg [19:0] ram_core [255:0]; @@ -371,14 +371,14 @@ module ram_256x20 endmodule // ram_256x20 -module ram_128x20 +module ram_128x20 ( input logic CLK, input logic [6:0] ADR, input logic [19:0] D, output logic [19:0] Q, input logic WE ); - + // behavior to be replaced by actual SRAM in VLE reg [19:0] ram_core [127:0]; @@ -394,14 +394,14 @@ module ram_128x20 endmodule // ram_128x20 -module ram_64x20 +module ram_64x20 ( input logic CLK, input logic [5:0] ADR, input logic [19:0] D, output logic [19:0] Q, input logic WE ); - + // behavior to be replaced by actual SRAM in VLE reg [19:0] ram_core [63:0]; @@ -421,14 +421,14 @@ endmodule // ram_64x20 // 4096 x 34 -module ram_4096x34 +module ram_4096x34 ( input logic CLK, input logic [11:0] ADR, input logic [33:0] D, output logic [33:0] Q, input logic WE ); - + // behavior to be replaced by actual SRAM in VLE reg [33:0] ram_core [4095:0]; @@ -440,20 +440,20 @@ module ram_4096x34 end - + endmodule // ram_4096x34 -// 2048x34 -module ram_2048x34 +// 2048x34 +module ram_2048x34 ( input logic CLK, input logic [10:0] ADR, input logic [33:0] D, output logic [33:0] Q, input logic WE ); - + // behavior to be replaced by actual SRAM in VLE reg [33:0] ram_core [2047:0]; @@ -465,20 +465,20 @@ module ram_2048x34 end - + endmodule // ram_2048x34 -// 1024x34 -module ram_1024x34 +// 1024x34 +module ram_1024x34 ( input logic CLK, input logic [9:0] ADR, input logic [33:0] D, output logic [33:0] Q, input logic WE ); - + // behavior to be replaced by actual SRAM in VLE reg [33:0] ram_core [1023:0]; @@ -490,20 +490,20 @@ module ram_1024x34 end - + endmodule // ram_1024x34 -// 512x34 -module ram_512x34 +// 512x34 +module ram_512x34 ( input logic CLK, input logic [8:0] ADR, input logic [33:0] D, output logic [33:0] Q, input logic WE ); - + // behavior to be replaced by actual SRAM in VLE reg [33:0] ram_core [511:0]; @@ -515,20 +515,20 @@ module ram_512x34 end - + endmodule // ram_512x34 -// 256x34 -module ram_256x34 +// 256x34 +module ram_256x34 ( input logic CLK, input logic [7:0] ADR, input logic [33:0] D, output logic [33:0] Q, input logic WE ); - + // behavior to be replaced by actual SRAM in VLE reg [33:0] ram_core [255:0]; @@ -540,20 +540,20 @@ module ram_256x34 end - + endmodule // ram_256x34 -// 128x34 -module ram_128x34 +// 128x34 +module ram_128x34 ( input logic CLK, input logic [6:0] ADR, input logic [33:0] D, output logic [33:0] Q, input logic WE ); - + // behavior to be replaced by actual SRAM in VLE reg [33:0] ram_core [127:0]; @@ -569,15 +569,15 @@ module ram_128x34 endmodule // ram_128x34 -// 64x34 -module ram_64x34 +// 64x34 +module ram_64x34 ( input logic CLK, input logic [5:0] ADR, input logic [33:0] D, output logic [33:0] Q, input logic WE ); - + // behavior to be replaced by actual SRAM in VLE reg [33:0] ram_core [63:0]; @@ -595,16 +595,16 @@ endmodule // ram_64x34 // New SRAMS for ECC; ECC on 16b boundaries -// 4096x44 -module ram_4096x42 +// 4096x44 +module ram_4096x42 ( input logic CLK, input logic [11:0] ADR, input logic [41:0] D, output logic [41:0] Q, - + input logic WE ); - + // behavior to be replaced by actual SRAM in VLE reg [41:0] ram_core [4095:0]; @@ -621,15 +621,15 @@ module ram_4096x42 endmodule // ram_4096x42 -// 2048x44 -module ram_2048x42 +// 2048x44 +module ram_2048x42 ( input logic CLK, input logic [10:0] ADR, input logic [41:0] D, output logic [41:0] Q, input logic WE ); - + // behavior to be replaced by actual SRAM in VLE reg [41:0] ram_core [2047:0]; @@ -645,15 +645,15 @@ module ram_2048x42 endmodule // ram_2048x42 -// 1024x44 -module ram_1024x42 +// 1024x44 +module ram_1024x42 ( input logic CLK, input logic [9:0] ADR, input logic [41:0] D, output logic [41:0] Q, input logic WE ); - + // behavior to be replaced by actual SRAM in VLE reg [41:0] ram_core [1023:0]; @@ -669,15 +669,15 @@ module ram_1024x42 endmodule // ram_1024x42 -// 512x44 -module ram_512x42 +// 512x44 +module ram_512x42 ( input logic CLK, input logic [8:0] ADR, input logic [41:0] D, output logic [41:0] Q, input logic WE ); - + // behavior to be replaced by actual SRAM in VLE reg [41:0] ram_core [511:0]; @@ -689,21 +689,21 @@ module ram_512x42 end - + endmodule // ram_512x42 -// 256x42 -module ram_256x42 +// 256x42 +module ram_256x42 ( input logic CLK, input logic [7:0] ADR, input logic [41:0] D, output logic [41:0] Q, input logic WE ); - + // behavior to be replaced by actual SRAM in VLE reg [41:0] ram_core [255:0]; @@ -715,20 +715,20 @@ module ram_256x42 end - + endmodule // ram_256x42 -// 128x42 -module ram_128x42 +// 128x42 +module ram_128x42 ( input logic CLK, input logic [6:0] ADR, input logic [41:0] D, output logic [41:0] Q, input logic WE ); - + // behavior to be replaced by actual SRAM in VLE reg [41:0] ram_core [127:0]; @@ -740,20 +740,20 @@ module ram_128x42 end - + endmodule // ram_128x42 -// 64x42 -module ram_64x42 +// 64x42 +module ram_64x42 ( input logic CLK, input logic [5:0] ADR, input logic [41:0] D, output logic [41:0] Q, input logic WE ); - + // behavior to be replaced by actual SRAM in VLE reg [41:0] ram_core [63:0]; @@ -772,8 +772,8 @@ endmodule // ram_64x42 // START TAGS -// 1024x21 -module ram_1024x21 +// 1024x21 +module ram_1024x21 ( input logic CLK, input logic [9:0] ADR, input logic [20:0] D, @@ -781,7 +781,7 @@ module ram_1024x21 output logic [20:0] Q, input logic WE ); - + // behavior to be replaced by actual SRAM in VLE reg [20:0] ram_core [1023:0]; @@ -796,15 +796,15 @@ module ram_1024x21 endmodule // ram_1024x21 -// 512x21 -module ram_512x21 +// 512x21 +module ram_512x21 ( input logic CLK, input logic [8:0] ADR, input logic [20:0] D, output logic [20:0] Q, input logic WE ); - + // behavior to be replaced by actual SRAM in VLE reg [20:0] ram_core [511:0]; @@ -816,21 +816,21 @@ module ram_512x21 end - + endmodule // ram_512x21 -// 256x21 -module ram_256x21 +// 256x21 +module ram_256x21 ( input logic CLK, input logic [7:0] ADR, input logic [20:0] D, output logic [20:0] Q, input logic WE ); - - // behavior to be replaced by actual SRAM in VLE + + // behavior to be replaced by actual SRAM in VLE reg [20:0] ram_core [255:0]; @@ -841,20 +841,20 @@ module ram_256x21 end - + endmodule // ram_256x21 -// 128x21 -module ram_128x21 +// 128x21 +module ram_128x21 ( input logic CLK, input logic [6:0] ADR, input logic [20:0] D, output logic [20:0] Q, input logic WE ); - + // behavior to be replaced by actual SRAM in VLE reg [20:0] ram_core [127:0]; @@ -866,13 +866,13 @@ module ram_128x21 end - + endmodule // ram_128x21 -// 64x21 -module ram_64x21 +// 64x21 +module ram_64x21 ( input logic CLK, input logic [5:0] ADR, input logic [20:0] D, @@ -893,17 +893,17 @@ module ram_64x21 endmodule // ram_64x21 -// New tag rams for ECC. +// New tag rams for ECC. -// 1024x25 -module ram_1024x25 +// 1024x25 +module ram_1024x25 ( input logic CLK, input logic [9:0] ADR, input logic [24:0] D, output logic [24:0] Q, input logic WE ); - + // behavior to be replaced by actual SRAM in VLE reg [24:0] ram_core [1023:0]; @@ -915,13 +915,13 @@ module ram_1024x25 end - + endmodule // ram_1024x25 -// 512x25 -module ram_512x25 +// 512x25 +module ram_512x25 ( input logic CLK, input logic [8:0] ADR, input logic [24:0] D, @@ -929,7 +929,7 @@ module ram_512x25 output logic [24:0] Q, input logic WE ); - + // behavior to be replaced by actual SRAM in VLE reg [24:0] ram_core [511:0]; @@ -941,13 +941,13 @@ module ram_512x25 end - + endmodule // ram_512x25 -// 256x25 -module ram_256x25 +// 256x25 +module ram_256x25 ( input logic CLK, input logic [7:0] ADR, input logic [24:0] D, @@ -955,8 +955,8 @@ module ram_256x25 output logic [24:0] Q, input logic WE ); - - // behavior to be replaced by actual SRAM in VLE + + // behavior to be replaced by actual SRAM in VLE reg [24:0] ram_core [255:0]; @@ -967,13 +967,13 @@ module ram_256x25 end - + endmodule // ram_256x25 -// 128x25 -module ram_128x25 +// 128x25 +module ram_128x25 ( input logic CLK, input logic [6:0] ADR, input logic [24:0] D, @@ -981,7 +981,7 @@ module ram_128x25 output logic [24:0] Q, input logic WE ); - + // behavior to be replaced by actual SRAM in VLE reg [24:0] ram_core [127:0]; @@ -993,13 +993,13 @@ module ram_128x25 end - + endmodule // ram_128x25 -// 64x25 -module ram_64x25 +// 64x25 +module ram_64x25 ( input logic CLK, input logic [5:0] ADR, input logic [24:0] D, @@ -1019,7 +1019,7 @@ module ram_64x25 end - + endmodule // ram_64x25 diff --git a/design/lsu/lsu.sv b/design/lsu/lsu.sv index f984bc0..127dd06 100644 --- a/design/lsu/lsu.sv +++ b/design/lsu/lsu.sv @@ -1,12 +1,12 @@ // 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. @@ -16,53 +16,55 @@ //******************************************************************************** // $Id$ // -// +// // Function: Top level file for load store unit // Comments: // -// +// // DC1 -> DC2 -> DC3 -> DC4 (Commit) -// +// //******************************************************************************** -module lsu +module lsu import swerv_types::*; ( input logic [31:0] i0_result_e4_eff, // I0 e4 result for e4 -> dc3 store forwarding input logic [31:0] i1_result_e4_eff, // I1 e4 result for e4 -> dc3 store forwarding input logic [31:0] i0_result_e2, // I0 e2 result for e2 -> dc2 store forwarding - - input logic flush_final_e3, // I0/I1 flush in e3 + + input logic flush_final_e3, // I0/I1 flush in e3 input logic i0_flush_final_e3, // I0 flush in e3 input logic dec_tlu_flush_lower_wb, // I0/I1 writeback flush. This is used to flush the old packets only - input logic dec_tlu_i0_kill_writeb_wb, // I0 is flushed, don't writeback any results to arch state - input logic dec_tlu_i1_kill_writeb_wb, // I1 is flushed, don't writeback any results to arch state + input logic dec_tlu_i0_kill_writeb_wb, // I0 is flushed, don't writeback any results to arch state + input logic dec_tlu_i1_kill_writeb_wb, // I1 is flushed, don't writeback any results to arch state input logic dec_tlu_cancel_e4, // cancel the bus load in dc4 and reset the freeze // chicken signals input logic dec_tlu_non_blocking_disable, // disable the non block input logic dec_tlu_wb_coalescing_disable, // disable the write buffer coalesce - input logic dec_tlu_ld_miss_byp_wb_disable, // disable the miss bypass in the write buffer + input logic dec_tlu_ld_miss_byp_wb_disable, // disable the miss bypass in the write buffer input logic dec_tlu_sideeffect_posted_disable, // disable posted writes to sideeffect addr 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 lsu_pkt_t lsu_p, // lsu control packet input logic dec_i0_lsu_decode_d, // lsu is in i0 input logic [31:0] dec_tlu_mrac_ff, // CSR for memory region control output logic [31:0] lsu_result_dc3, // lsu load data + output logic lsu_single_ecc_error_incr, // Increment the counter for Single ECC error output logic [31:0] lsu_result_corr_dc4, // This is the ECC corrected data going to RF output logic lsu_freeze_dc3, // lsu freeze due to load to external 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_load_ecc_stbuf_full_dc3, // Load with ecc error can't allocate to stbuf output logic lsu_idle_any, // lsu buffers are empty and no instruction in the pipeline output logic lsu_halt_idle_any, // This is used to enter halt mode. Exclude DMA - + output lsu_error_pkt_t lsu_error_pkt_dc3, // lsu exception packet output logic lsu_freeze_external_ints_dc3, // freeze due to sideeffects loads need to suppress external interrupt output logic lsu_imprecise_error_load_any, // bus load imprecise error @@ -70,25 +72,25 @@ module lsu output logic [31:0] lsu_imprecise_error_addr_any, // bus store imprecise error address // Non-blocking loads - input logic dec_nonblock_load_freeze_dc2, // + input logic dec_nonblock_load_freeze_dc2, // output logic lsu_nonblock_load_valid_dc3, // there is an external load -> put in the cam output logic [`RV_LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_tag_dc3, // the tag of the external non block load output logic lsu_nonblock_load_inv_dc5, // invalidate signal for the cam entry for non block loads output logic [`RV_LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_inv_tag_dc5, // 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 [`RV_LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_data_tag, // the tag of the non block load sending the data/error + 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 [`RV_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_misaligned_dc3, // PMU : misaligned - output logic lsu_pmu_bus_trxn, // PMU : bus transaction + 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 trigger_pkt_t [3:0] trigger_pkt_any, // Trigger info from the decode - output logic [3:0] lsu_trigger_match_dc3, // lsu trigger hit (one bit per trigger) + output logic [3:0] lsu_trigger_match_dc3, // lsu trigger hit (one bit per trigger) // DCCM ports output logic dccm_wren, // DCCM write enable @@ -97,7 +99,7 @@ module lsu output logic [`RV_DCCM_BITS-1:0] dccm_rd_addr_lo, // DCCM read address low bank output logic [`RV_DCCM_BITS-1:0] dccm_rd_addr_hi, // DCCM read address hi bank (hi and low same if aligned read) output logic [`RV_DCCM_FDATA_WIDTH-1:0] dccm_wr_data, // DCCM write data (this is always aligned) - + input logic [`RV_DCCM_FDATA_WIDTH-1:0] dccm_rd_data_lo, // DCCM read data low bank input logic [`RV_DCCM_FDATA_WIDTH-1:0] dccm_rd_data_hi, // DCCM read data hi bank @@ -122,19 +124,19 @@ module lsu output logic [3:0] lsu_axi_awcache, output logic [2:0] lsu_axi_awprot, output logic [3:0] lsu_axi_awqos, - - output logic lsu_axi_wvalid, + + 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, output logic lsu_axi_bready, input logic [1:0] lsu_axi_bresp, input logic [`RV_LSU_BUS_TAG-1:0] lsu_axi_bid, - - // AXI Read Channels + + // AXI Read Channels output logic lsu_axi_arvalid, input logic lsu_axi_arready, output logic [`RV_LSU_BUS_TAG-1:0] lsu_axi_arid, @@ -147,7 +149,7 @@ module lsu output logic [3:0] lsu_axi_arcache, output logic [2:0] lsu_axi_arprot, output logic [3:0] lsu_axi_arqos, - + input logic lsu_axi_rvalid, output logic lsu_axi_rready, input logic [`RV_LSU_BUS_TAG-1:0] lsu_axi_rid, @@ -156,7 +158,7 @@ module lsu 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 [31:0] dma_mem_addr, // DMA address @@ -171,15 +173,15 @@ module lsu input logic clk_override, // Disable clock gating input logic scan_mode, // scan - input logic clk, + input logic clk, input logic free_clk, input logic rst_l ); - + `include "global.h" - + logic lsu_dccm_rden_dc3; logic [63:0] store_data_dc2; logic [63:0] store_data_dc3; @@ -191,7 +193,7 @@ module lsu logic single_ecc_error_hi_dc3, single_ecc_error_lo_dc3; logic lsu_single_ecc_error_dc3, lsu_single_ecc_error_dc4, lsu_single_ecc_error_dc5; logic lsu_double_ecc_error_dc3; - + logic [31:0] dccm_data_hi_dc3; logic [31:0] dccm_data_lo_dc3; logic [6:0] dccm_data_ecc_hi_dc3; @@ -200,13 +202,13 @@ module lsu logic [31:0] lsu_ld_data_dc3; logic [31:0] lsu_ld_data_corr_dc3; logic [31:0] picm_mask_data_dc3; - + logic [31:0] lsu_addr_dc1, lsu_addr_dc2, lsu_addr_dc3, lsu_addr_dc4, lsu_addr_dc5; logic [31:0] end_addr_dc1, end_addr_dc2, end_addr_dc3, end_addr_dc4, end_addr_dc5; lsu_pkt_t lsu_pkt_dc1, lsu_pkt_dc2, lsu_pkt_dc3, lsu_pkt_dc4, lsu_pkt_dc5; logic lsu_i0_valid_dc1, lsu_i0_valid_dc2, lsu_i0_valid_dc3, lsu_i0_valid_dc4, lsu_i0_valid_dc5; - + // Store Buffer signals logic isldst_dc1, dccm_ldst_dc2, dccm_ldst_dc3; logic store_stbuf_reqvld_dc3; @@ -226,7 +228,7 @@ module lsu logic [LSU_SB_BITS-1:0] stbuf_addr_any; logic [DCCM_DATA_WIDTH-1:0] stbuf_data_any; logic [(DCCM_FDATA_WIDTH-DCCM_DATA_WIDTH-1):0] stbuf_ecc_any; - + logic lsu_cmpen_dc2; logic [DCCM_DATA_WIDTH-1:0] stbuf_fwddata_hi_dc3; logic [DCCM_DATA_WIDTH-1:0] stbuf_fwddata_lo_dc3; @@ -234,7 +236,7 @@ module lsu logic [DCCM_BYTE_WIDTH-1:0] stbuf_fwdbyteen_lo_dc3; logic lsu_stbuf_commit_any; - logic lsu_stbuf_empty_any; + logic lsu_stbuf_empty_any; logic lsu_stbuf_nodma_empty_any; // Store Buffer is empty except dma writes logic lsu_stbuf_full_any; @@ -247,53 +249,53 @@ module lsu logic [31:0] bus_read_data_dc3; logic ld_bus_error_dc3; logic [31:0] ld_bus_error_addr_dc3; - + logic flush_dc2_up, flush_dc3, flush_dc4, flush_dc5, flush_prior_dc5; logic is_sideeffects_dc2, is_sideeffects_dc3; logic ldst_nodma_dc1todc3; // Clocks - logic lsu_c1_dc3_clk, lsu_c1_dc4_clk, lsu_c1_dc5_clk; - logic lsu_c2_dc3_clk, lsu_c2_dc4_clk, lsu_c2_dc5_clk; + logic lsu_c1_dc3_clk, lsu_c1_dc4_clk, lsu_c1_dc5_clk; + logic lsu_c2_dc3_clk, lsu_c2_dc4_clk, lsu_c2_dc5_clk; logic lsu_freeze_c1_dc2_clk, lsu_freeze_c1_dc3_clk; - logic lsu_freeze_c1_dc1_clken, lsu_freeze_c1_dc2_clken, lsu_freeze_c1_dc3_clken; + logic lsu_freeze_c1_dc1_clken, lsu_freeze_c1_dc2_clken, lsu_freeze_c1_dc3_clken; logic lsu_store_c1_dc1_clken, lsu_store_c1_dc2_clken, lsu_store_c1_dc3_clken, lsu_store_c1_dc4_clk, lsu_store_c1_dc5_clk; - - logic lsu_freeze_c2_dc1_clk, lsu_freeze_c2_dc2_clk, lsu_freeze_c2_dc3_clk, lsu_freeze_c2_dc4_clk; + + logic lsu_freeze_c2_dc1_clk, lsu_freeze_c2_dc2_clk, lsu_freeze_c2_dc3_clk, lsu_freeze_c2_dc4_clk; logic lsu_stbuf_c1_clk; logic lsu_bus_ibuf_c1_clk, lsu_bus_obuf_c1_clk, lsu_bus_buf_c1_clk; logic lsu_dccm_c1_dc3_clk, lsu_pic_c1_dc3_clken; logic lsu_busm_clk; logic lsu_free_c2_clk; - + lsu_lsc_ctl 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; assign lsu_load_stall_any = lsu_bus_buffer_full_any; - + // 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 ld/st in dc3-dc5 when dma is in dc2 assign ldst_nodma_dc1todc3 = (lsu_pkt_dc1.valid & ~lsu_pkt_dc1.dma) | (lsu_pkt_dc2.valid & ~lsu_pkt_dc2.dma) | (lsu_pkt_dc3.valid & ~lsu_pkt_dc3.dma); assign dccm_ready = ~(lsu_p.valid | lsu_stbuf_full_any | lsu_freeze_dc3 | ldst_nodma_dc1todc3); - + // Generate per cycle flush signals assign flush_dc2_up = flush_final_e3 | i0_flush_final_e3 | dec_tlu_flush_lower_wb; assign flush_dc3 = (flush_final_e3 & i0_flush_final_e3) | dec_tlu_flush_lower_wb; assign flush_dc4 = dec_tlu_flush_lower_wb; assign flush_dc5 = (dec_tlu_i0_kill_writeb_wb | (dec_tlu_i1_kill_writeb_wb & ~lsu_i0_valid_dc5)); assign flush_prior_dc5 = dec_tlu_i0_kill_writeb_wb & ~lsu_i0_valid_dc5; // Flush is due to i0 instruction and ld/st is in i1 - + // lsu idle - assign lsu_idle_any = ~(lsu_pkt_dc1.valid | lsu_pkt_dc2.valid | lsu_pkt_dc3.valid | lsu_pkt_dc4.valid | lsu_pkt_dc5.valid) & + assign lsu_idle_any = ~(lsu_pkt_dc1.valid | lsu_pkt_dc2.valid | lsu_pkt_dc3.valid | lsu_pkt_dc4.valid | lsu_pkt_dc5.valid) & lsu_bus_buffer_empty_any & lsu_stbuf_empty_any; // lsu halt idle. This is used for entering the halt mode // Indicates non-idle if there is a instruction valid in dc1-dc5 or read/write buffers are non-empty since they can come with error - // Need to make sure bus trxns are done and there are no non-dma writes in store buffer - assign lsu_halt_idle_any = ~((lsu_pkt_dc1.valid & ~lsu_pkt_dc1.dma) | + // Need to make sure bus trxns are done and there are no non-dma writes in store buffer + assign lsu_halt_idle_any = ~((lsu_pkt_dc1.valid & ~lsu_pkt_dc1.dma) | (lsu_pkt_dc2.valid & ~lsu_pkt_dc2.dma) | (lsu_pkt_dc3.valid & ~lsu_pkt_dc3.dma) | (lsu_pkt_dc4.valid & ~lsu_pkt_dc4.dma) | @@ -309,7 +311,7 @@ module lsu assign isldst_dc1 = lsu_pkt_dc1.valid & (lsu_pkt_dc1.load | lsu_pkt_dc1.store); assign dccm_ldst_dc2 = lsu_pkt_dc2.valid & (lsu_pkt_dc2.load | lsu_pkt_dc2.store) & (addr_in_dccm_dc2 | addr_in_pic_dc2); assign dccm_ldst_dc3 = lsu_pkt_dc3.valid & (lsu_pkt_dc3.load | lsu_pkt_dc3.store) & (addr_in_dccm_dc3 | addr_in_pic_dc3); - + // Disable Forwarding for now assign lsu_cmpen_dc2 = lsu_pkt_dc2.valid & (lsu_pkt_dc2.load | lsu_pkt_dc2.store) & (addr_in_dccm_dc2 | addr_in_pic_dc2); @@ -319,14 +321,14 @@ module lsu // PMU signals assign lsu_pmu_misaligned_dc3 = lsu_pkt_dc3.valid & ((lsu_pkt_dc3.half & lsu_addr_dc3[0]) | (lsu_pkt_dc3.word & (|lsu_addr_dc3[1:0]))); - + lsu_dccm_ctl dccm_ctl ( .lsu_addr_dc1(lsu_addr_dc1[31:0]), .end_addr_dc1(end_addr_dc1[DCCM_BITS-1:0]), .lsu_addr_dc3(lsu_addr_dc3[DCCM_BITS-1:0]), .* ); - + lsu_stbuf stbuf( .lsu_addr_dc1(lsu_addr_dc1[LSU_SB_BITS-1:0]), .end_addr_dc1(end_addr_dc1[LSU_SB_BITS-1:0]), @@ -335,9 +337,9 @@ module lsu .lsu_addr_dc3(lsu_addr_dc3[LSU_SB_BITS-1:0]), .end_addr_dc3(end_addr_dc3[LSU_SB_BITS-1:0]), .* - + ); - + lsu_ecc ecc ( .lsu_addr_dc3(lsu_addr_dc3[DCCM_BITS-1:0]), .end_addr_dc3(end_addr_dc3[DCCM_BITS-1:0]), @@ -348,13 +350,13 @@ module lsu .store_data_dc3(store_data_dc3[31:0]), .* ); - + // Clk domain lsu_clkdomain clkdomain (.*); // Bus interface lsu_bus_intf bus_intf (.*); - + //Flops //rvdffs #(1) lsu_i0_valid_dc1ff (.*, .din(dec_i0_lsu_decode_d), .dout(lsu_i0_valid_dc1), .en(~lsu_freeze_dc3)); rvdff #(1) lsu_i0_valid_dc1ff (.*, .din(dec_i0_lsu_decode_d), .dout(lsu_i0_valid_dc1), .clk(lsu_freeze_c2_dc1_clk)); @@ -362,9 +364,9 @@ module lsu rvdff #(1) lsu_i0_valid_dc3ff (.*, .din(lsu_i0_valid_dc2), .dout(lsu_i0_valid_dc3), .clk(lsu_freeze_c2_dc3_clk)); rvdff #(1) lsu_i0_valid_dc4ff (.*, .din(lsu_i0_valid_dc3), .dout(lsu_i0_valid_dc4), .clk(lsu_freeze_c2_dc4_clk)); rvdff #(1) lsu_i0_valid_dc5ff (.*, .din(lsu_i0_valid_dc4), .dout(lsu_i0_valid_dc5), .clk(lsu_c2_dc5_clk)); - rvdff #(1) lsu_single_ecc_err_dc4(.*, .din(lsu_single_ecc_error_dc3), .dout(lsu_single_ecc_error_dc4), .clk(lsu_c2_dc4_clk)); + rvdff #(1) lsu_single_ecc_err_dc4(.*, .din(lsu_single_ecc_error_dc3), .dout(lsu_single_ecc_error_dc4), .clk(lsu_c2_dc4_clk)); rvdff #(1) lsu_single_ecc_err_dc5(.*, .din(lsu_single_ecc_error_dc4), .dout(lsu_single_ecc_error_dc5), .clk(lsu_c2_dc5_clk)); - + `ifdef ASSERT_ON logic [8:0] store_data_bypass_sel; assign store_data_bypass_sel[8:0] = {lsu_p.store_data_bypass_c1, @@ -375,8 +377,8 @@ module lsu lsu_p.store_data_bypass_e4_c3[1:0]}; assert_store_data_bypass_onehot: assert #0 ($onehot0(store_data_bypass_sel[8:0])); - assert_picm_rden_and_wren: assert #0 ($onehot0({(picm_rden | picm_mken),picm_wren})); - assert_picm_rden_and_dccmen: assert #0 ($onehot0({(picm_rden | picm_mken),dccm_rden})); + assert_picm_rden_and_wren: assert #0 ($onehot0({(picm_rden | picm_mken),picm_wren})); + assert_picm_rden_and_dccmen: assert #0 ($onehot0({(picm_rden | picm_mken),dccm_rden})); assert_picm_wren_and_dccmen: assert #0 ($onehot0({picm_wren, dccm_wren})); //assert_no_exceptions: assert #0 (lsu_exc_pkt_dc3.exc_valid == 1'b0); @@ -386,5 +388,5 @@ module lsu assert_exception_no_lsu_flush: assert property (exception_no_lsu_flush) else $display("No flush within 2 cycles of exception"); `endif - + endmodule // lsu diff --git a/design/lsu/lsu_addrcheck.sv b/design/lsu/lsu_addrcheck.sv index 6a7f097..e6bdf10 100644 --- a/design/lsu/lsu_addrcheck.sv +++ b/design/lsu/lsu_addrcheck.sv @@ -1,12 +1,12 @@ // 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. @@ -16,13 +16,13 @@ //******************************************************************************** // $Id$ // -// -// Owner: +// +// Owner: // Function: Checks the memory map for the address -// Comments: +// Comments: // //******************************************************************************** -module lsu_addrcheck +module lsu_addrcheck import swerv_types::*; ( input logic lsu_freeze_c2_dc2_clk, // clock @@ -34,21 +34,21 @@ module lsu_addrcheck input lsu_pkt_t lsu_pkt_dc1, // packet in dc1 input logic [31:0] dec_tlu_mrac_ff, // CSR read - + output logic is_sideeffects_dc2, // is sideffects space - output logic is_sideeffects_dc3, + output logic is_sideeffects_dc3, output logic addr_in_dccm_dc1, // address in dccm output logic addr_in_pic_dc1, // address in pic output logic addr_external_dc1, // address in external output logic access_fault_dc1, // access fault - output logic misaligned_fault_dc1, // misaligned - - input logic scan_mode + output logic misaligned_fault_dc1, // misaligned + + input logic scan_mode ); - + `include "global.h" - + localparam DCCM_REGION = `RV_DCCM_REGION; localparam PIC_REGION = `RV_PIC_REGION; localparam ICCM_REGION = `RV_ICCM_REGION; @@ -58,13 +58,13 @@ module lsu_addrcheck `else localparam ICCM_ENABLE = 1'b0; `endif - + `ifdef RV_DCCM_ENABLE localparam DCCM_ENABLE = 1'b1; `else localparam DCCM_ENABLE = 1'b0; `endif - + logic is_sideeffects_dc1, is_aligned_dc1; logic start_addr_in_dccm_dc1, end_addr_in_dccm_dc1; logic start_addr_in_dccm_region_dc1, end_addr_in_dccm_region_dc1; @@ -73,7 +73,7 @@ module lsu_addrcheck logic [4:0] csr_idx; logic addr_in_iccm; logic non_dccm_access_ok; - + if (DCCM_ENABLE == 1) begin: Gen_dccm_enable // Start address check rvrangecheck #(.CCM_SADR(`RV_DCCM_SADR), @@ -82,7 +82,7 @@ module lsu_addrcheck .in_range(start_addr_in_dccm_dc1), .in_region(start_addr_in_dccm_region_dc1) ); - + // End address check rvrangecheck #(.CCM_SADR(`RV_DCCM_SADR), .CCM_SIZE(`RV_DCCM_SIZE)) end_addr_dccm_rangecheck ( @@ -98,10 +98,10 @@ module lsu_addrcheck end if (ICCM_ENABLE == 1) begin : check_iccm assign addr_in_iccm = (start_addr_dc1[31:28] == ICCM_REGION); - end + end else begin assign addr_in_iccm = 1'b0; - end + end // PIC memory check // Start address check rvrangecheck #(.CCM_SADR(`RV_PIC_BASE_ADDR), @@ -110,7 +110,7 @@ module lsu_addrcheck .in_range(start_addr_in_pic_dc1), .in_region(start_addr_in_pic_region_dc1) ); - + // End address check rvrangecheck #(.CCM_SADR(`RV_PIC_BASE_ADDR), .CCM_SIZE(`RV_PIC_SIZE)) end_addr_pic_rangecheck ( @@ -119,12 +119,12 @@ module lsu_addrcheck .in_region(end_addr_in_pic_region_dc1) ); - assign addr_in_dccm_dc1 = (start_addr_in_dccm_dc1 & end_addr_in_dccm_dc1); - assign addr_in_pic_dc1 = (start_addr_in_pic_dc1 & end_addr_in_pic_dc1); - - assign addr_external_dc1 = ~(addr_in_dccm_dc1 | addr_in_pic_dc1); //~addr_in_dccm_region_dc1; + assign addr_in_dccm_dc1 = (start_addr_in_dccm_dc1 & end_addr_in_dccm_dc1); + assign addr_in_pic_dc1 = (start_addr_in_pic_dc1 & end_addr_in_pic_dc1); + + assign addr_external_dc1 = ~(addr_in_dccm_dc1 | addr_in_pic_dc1); //~addr_in_dccm_region_dc1; assign csr_idx[4:0] = {start_addr_dc1[31:28], 1'b1}; - assign is_sideeffects_dc1 = dec_tlu_mrac_ff[csr_idx] & ~(start_addr_in_dccm_region_dc1 | start_addr_in_pic_region_dc1 | addr_in_iccm); //every region has the 2 LSB indicating ( 1: sideeffects/no_side effects, and 0: cacheable ). Ignored in internal regions + assign is_sideeffects_dc1 = dec_tlu_mrac_ff[csr_idx] & ~(start_addr_in_dccm_region_dc1 | start_addr_in_pic_region_dc1 | addr_in_iccm); //every region has the 2 LSB indicating ( 1: sideeffects/no_side effects, and 0: cacheable ). Ignored in internal regions assign is_aligned_dc1 = (lsu_pkt_dc1.word & (start_addr_dc1[1:0] == 2'b0)) | (lsu_pkt_dc1.half & (start_addr_dc1[0] == 1'b0)) | lsu_pkt_dc1.by; @@ -134,7 +134,7 @@ module lsu_addrcheck (((`RV_DATA_ACCESS_ENABLE0 & ((start_addr_dc1[31:0] | `RV_DATA_ACCESS_MASK0)) == (`RV_DATA_ACCESS_ADDR0 | `RV_DATA_ACCESS_MASK0)) | (`RV_DATA_ACCESS_ENABLE1 & ((start_addr_dc1[31:0] | `RV_DATA_ACCESS_MASK1)) == (`RV_DATA_ACCESS_ADDR1 | `RV_DATA_ACCESS_MASK1)) | (`RV_DATA_ACCESS_ENABLE2 & ((start_addr_dc1[31:0] | `RV_DATA_ACCESS_MASK2)) == (`RV_DATA_ACCESS_ADDR2 | `RV_DATA_ACCESS_MASK2)) | - (`RV_DATA_ACCESS_ENABLE3 & ((start_addr_dc1[31:0] | `RV_DATA_ACCESS_MASK3)) == (`RV_DATA_ACCESS_ADDR3 | `RV_DATA_ACCESS_MASK3)) | + (`RV_DATA_ACCESS_ENABLE3 & ((start_addr_dc1[31:0] | `RV_DATA_ACCESS_MASK3)) == (`RV_DATA_ACCESS_ADDR3 | `RV_DATA_ACCESS_MASK3)) | (`RV_DATA_ACCESS_ENABLE4 & ((start_addr_dc1[31:0] | `RV_DATA_ACCESS_MASK4)) == (`RV_DATA_ACCESS_ADDR4 | `RV_DATA_ACCESS_MASK4)) | (`RV_DATA_ACCESS_ENABLE5 & ((start_addr_dc1[31:0] | `RV_DATA_ACCESS_MASK5)) == (`RV_DATA_ACCESS_ADDR5 | `RV_DATA_ACCESS_MASK5)) | (`RV_DATA_ACCESS_ENABLE6 & ((start_addr_dc1[31:0] | `RV_DATA_ACCESS_MASK6)) == (`RV_DATA_ACCESS_ADDR6 | `RV_DATA_ACCESS_MASK6)) | @@ -156,28 +156,29 @@ module lsu_addrcheck // 4. Ld/St access to picm are not word aligned // 5. Address not in protected space or dccm/pic region if (DCCM_REGION == PIC_REGION) begin - assign access_fault_dc1 = ((start_addr_in_dccm_region_dc1 & ~(start_addr_in_dccm_dc1 | start_addr_in_pic_dc1)) | + assign access_fault_dc1 = ((start_addr_in_dccm_region_dc1 & ~(start_addr_in_dccm_dc1 | start_addr_in_pic_dc1)) | (end_addr_in_dccm_region_dc1 & ~(end_addr_in_dccm_dc1 | end_addr_in_pic_dc1)) | - ((start_addr_dc1[27:18] != end_addr_dc1[27:18]) & start_addr_in_dccm_dc1) | + (start_addr_in_dccm_dc1 & end_addr_in_pic_dc1) | + (start_addr_in_pic_dc1 & end_addr_in_dccm_dc1) | ((addr_in_pic_dc1 & ((start_addr_dc1[1:0] != 2'b0) | ~lsu_pkt_dc1.word))) | (~start_addr_in_dccm_region_dc1 & ~non_dccm_access_ok)) & lsu_pkt_dc1.valid & ~lsu_pkt_dc1.dma; end else begin - assign access_fault_dc1 = ((start_addr_in_dccm_region_dc1 & ~start_addr_in_dccm_dc1) | + assign access_fault_dc1 = ((start_addr_in_dccm_region_dc1 & ~start_addr_in_dccm_dc1) | (end_addr_in_dccm_region_dc1 & ~end_addr_in_dccm_dc1) | - (start_addr_in_pic_region_dc1 & ~start_addr_in_pic_dc1) | + (start_addr_in_pic_region_dc1 & ~start_addr_in_pic_dc1) | (end_addr_in_pic_region_dc1 & ~end_addr_in_pic_dc1) | ((addr_in_pic_dc1 & ((start_addr_dc1[1:0] != 2'b0) | ~lsu_pkt_dc1.word))) | (~start_addr_in_pic_region_dc1 & ~start_addr_in_dccm_region_dc1 & ~non_dccm_access_ok)) & lsu_pkt_dc1.valid & ~lsu_pkt_dc1.dma; end - + // Misaligned happens due to 2 reasons // 1. Region cross // 2. sideeffects access which are not aligned - assign misaligned_fault_dc1 = ((start_addr_dc1[31:28] != end_addr_dc1[31:28]) | + assign misaligned_fault_dc1 = ((start_addr_dc1[31:28] != end_addr_dc1[31:28]) | (is_sideeffects_dc1 & ~is_aligned_dc1)) & addr_external_dc1 & lsu_pkt_dc1.valid & ~lsu_pkt_dc1.dma; rvdff #(.WIDTH(1)) is_sideeffects_dc2ff (.din(is_sideeffects_dc1), .dout(is_sideeffects_dc2), .clk(lsu_freeze_c2_dc2_clk), .*); rvdff #(.WIDTH(1)) is_sideeffects_dc3ff (.din(is_sideeffects_dc2), .dout(is_sideeffects_dc3), .clk(lsu_freeze_c2_dc3_clk), .*); - + endmodule // lsu_addrcheck diff --git a/design/lsu/lsu_bus_buffer.sv b/design/lsu/lsu_bus_buffer.sv index 09df1a6..f494bcf 100644 --- a/design/lsu/lsu_bus_buffer.sv +++ b/design/lsu/lsu_bus_buffer.sv @@ -1,12 +1,12 @@ // 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. @@ -16,8 +16,8 @@ //******************************************************************************** // $Id$ // -// -// Owner: +// +// Owner: // Function: lsu interface with interface queue // Comments: // @@ -30,13 +30,13 @@ function automatic logic [2:0] f_Enc8to3; 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]; + Enc_value[2] = Dec_value[4] | Dec_value[5] | Dec_value[6] | Dec_value[7]; return Enc_value[2:0]; endfunction // f_Enc8to3 -module lsu_bus_buffer +module lsu_bus_buffer import swerv_types::*; ( input logic clk, @@ -46,9 +46,9 @@ module lsu_bus_buffer input logic dec_tlu_wb_coalescing_disable, // disable write buffer coalescing input logic dec_tlu_ld_miss_byp_wb_disable, // disable ld miss bypass of the write buffer input logic dec_tlu_sideeffect_posted_disable, // disable posted writes to sideeffect addr to the bus - + // various clocks needed for the bus reads and writes - input logic lsu_c1_dc3_clk, + input logic lsu_c1_dc3_clk, input logic lsu_c1_dc4_clk, input logic lsu_c1_dc5_clk, input logic lsu_c2_dc3_clk, @@ -63,8 +63,8 @@ module lsu_bus_buffer input logic lsu_bus_buf_c1_clk, input logic lsu_free_c2_clk, input logic lsu_busm_clk, - - + + input lsu_pkt_t lsu_pkt_dc1, // lsu packet flowing down the pipe input lsu_pkt_t lsu_pkt_dc2, // lsu packet flowing down the pipe input lsu_pkt_t lsu_pkt_dc3, // lsu packet flowing down the pipe @@ -84,7 +84,7 @@ module lsu_bus_buffer output logic lsu_busreq_dc4, // bus request is in dc4 output logic lsu_busreq_dc5, // bus request is in dc5 input logic ld_full_hit_dc2, // load can get all its byte from a write buffer entry - input logic flush_dc2_up, // flush + input logic flush_dc2_up, // flush input logic flush_dc3, // flush input logic flush_dc4, // flush input logic flush_dc5, // flush @@ -98,16 +98,16 @@ module lsu_bus_buffer input logic ldst_dual_dc3, // load/store is unaligned at 32 bit boundary input logic ldst_dual_dc4, // load/store is unaligned at 32 bit boundary input logic ldst_dual_dc5, // load/store is unaligned at 32 bit boundary - + input logic [7:0] ldst_byteen_ext_dc2, - + output logic ld_freeze_dc3, // load goes to external and asserts freeze 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 ld_bus_error_dc3, // bus error in dc3 - output logic [31:0] ld_bus_error_addr_dc3, // address of the bus error + output logic [31:0] ld_bus_error_addr_dc3, // address of the bus error output logic [31:0] ld_bus_data_dc3, // the Dc3 load data from bus output logic [3:0] ld_byte_hit_buf_lo, ld_byte_hit_buf_hi, // Byte enables for forwarding data @@ -123,17 +123,17 @@ module lsu_bus_buffer output logic [`RV_LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_tag_dc3, // the tag of the external non block load output logic lsu_nonblock_load_inv_dc5, // invalidate signal for the cam entry for non block loads output logic [`RV_LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_inv_tag_dc5, // 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 [`RV_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_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 [`RV_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, @@ -147,19 +147,19 @@ module lsu_bus_buffer output logic [3:0] lsu_axi_awcache, output logic [2:0] lsu_axi_awprot, output logic [3:0] lsu_axi_awqos, - - output logic lsu_axi_wvalid, + + 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, output logic lsu_axi_bready, input logic [1:0] lsu_axi_bresp, input logic [`RV_LSU_BUS_TAG-1:0] lsu_axi_bid, - - // AXI Read Channels + + // AXI Read Channels output logic lsu_axi_arvalid, input logic lsu_axi_arready, output logic [`RV_LSU_BUS_TAG-1:0] lsu_axi_arid, @@ -172,7 +172,7 @@ module lsu_bus_buffer output logic [3:0] lsu_axi_arcache, output logic [2:0] lsu_axi_arprot, output logic [3:0] lsu_axi_arqos, - + input logic lsu_axi_rvalid, output logic lsu_axi_rready, input logic [`RV_LSU_BUS_TAG-1:0] lsu_axi_rid, @@ -196,7 +196,7 @@ module lsu_bus_buffer localparam TIMER = 8; // This can be only power of 2 localparam TIMER_LOG2 = (TIMER < 2) ? 1 : $clog2(TIMER); localparam TIMER_MAX = (TIMER == 0) ? TIMER_LOG2'(0) : TIMER_LOG2'(TIMER - 1); // Maximum value of timer - + logic [3:0] ldst_byteen_hi_dc2, ldst_byteen_lo_dc2; 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; @@ -210,7 +210,7 @@ module lsu_bus_buffer logic [3:0] ldst_byteen_hi_dc5, ldst_byteen_lo_dc5; logic [31:0] store_data_hi_dc5, store_data_lo_dc5; logic ldst_samedw_dc5; - + logic lsu_nonblock_load_valid_dc4,lsu_nonblock_load_valid_dc5; logic [31:0] lsu_nonblock_load_data_hi, lsu_nonblock_load_data_lo, lsu_nonblock_data_unalgn; logic [1:0] lsu_nonblock_addr_offset; @@ -222,7 +222,7 @@ module lsu_bus_buffer logic ld_precise_bus_error; logic [DEPTH_LOG2-1:0] lsu_imprecise_error_load_tag; logic [31:0] ld_block_bus_data; - + logic [DEPTH-1:0] CmdPtr0Dec, CmdPtr1Dec; logic [DEPTH_LOG2-1:0] CmdPtr0, CmdPtr1; logic [DEPTH_LOG2-1:0] WrPtr0_dc3, WrPtr0_dc4, WrPtr0_dc5; @@ -231,19 +231,19 @@ module lsu_bus_buffer logic [3:0] buf_numvld_any, buf_numvld_wrcmd_any, buf_numvld_pend_any, buf_numvld_cmd_any; logic bus_sideeffect_pend; logic bus_coalescing_disable; - + logic ld_freeze_en, ld_freeze_rst; logic FreezePtrEn; logic [DEPTH_LOG2-1:0] FreezePtr; - logic bus_addr_match_pending; + 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 [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][2:0] buf_state_out; @@ -262,7 +262,7 @@ module lsu_bus_buffer 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, buf_age_temp; - + state_t [DEPTH-1:0] buf_nxtstate; logic [DEPTH-1:0] buf_rst; logic [DEPTH-1:0] buf_state_en; @@ -350,7 +350,7 @@ module lsu_bus_buffer logic obuf_cmd_done_in, obuf_data_done_in; logic [LSU_BUS_TAG-1:0] obuf_tag0_in; logic [LSU_BUS_TAG-1:0] obuf_tag1_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; @@ -363,8 +363,8 @@ module lsu_bus_buffer logic lsu_axi_rvalid_q, lsu_axi_rready_q; logic [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 [63:0] lsu_axi_rdata_q; - + logic [63:0] lsu_axi_rdata_q; + //------------------------------------------------------------------------------ // Load forwarding logic start //------------------------------------------------------------------------------ @@ -379,8 +379,8 @@ module lsu_bus_buffer end for (genvar j=0; j<4; j++) begin - assign ld_byte_hit_buf_lo[j] = |(ld_byte_hitvecfn_lo[j]) | ld_byte_ibuf_hit_lo[j]; - assign ld_byte_hit_buf_hi[j] = |(ld_byte_hitvecfn_hi[j]) | ld_byte_ibuf_hit_hi[j]; + assign ld_byte_hit_buf_lo[j] = |(ld_byte_hitvecfn_lo[j]) | ld_byte_ibuf_hit_lo[j]; + assign ld_byte_hit_buf_hi[j] = |(ld_byte_hitvecfn_hi[j]) | ld_byte_ibuf_hit_hi[j]; 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_dc2 & ~lsu_busreq_dc3 & ~lsu_busreq_dc4 & ~lsu_busreq_dc5 & ~ibuf_valid & (buf_numvld_cmd_any[3:0] == 4'b1) & (lsu_addr_dc2[31:2] != buf_addr[CmdPtr0][31:2]); // Entry in dc2 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) & ~ldst_dual_dc5 & lsu_pkt_dc5.store; - - assign obuf_wr_en = (lsu_bus_clk_en & ((ibuf_buf_byp & lsu_commit_dc5) | - ((buf_state[CmdPtr0] == CMD) & found_cmdptr0 & ~buf_cmd_state_bus_en[CmdPtr0] & - (~(buf_dual[CmdPtr0] & buf_samedw[CmdPtr0] & ~buf_write[CmdPtr0]) | found_cmdptr1 | buf_nomerge[CmdPtr0] | obuf_force_wr_en)))) & + assign ibuf_buf_byp = ibuf_byp & (buf_numvld_pend_any[3:0] == 4'b0) & ~ldst_dual_dc5 & lsu_pkt_dc5.store; + + assign obuf_wr_en = (lsu_bus_clk_en & ((ibuf_buf_byp & lsu_commit_dc5) | + ((buf_state[CmdPtr0] == CMD) & found_cmdptr0 & ~buf_cmd_state_bus_en[CmdPtr0] & + (~(buf_dual[CmdPtr0] & buf_samedw[CmdPtr0] & ~buf_write[CmdPtr0]) | found_cmdptr1 | buf_nomerge[CmdPtr0] | obuf_force_wr_en)))) & (bus_cmd_ready | ~obuf_valid) & ~obuf_wr_wait & ~bus_sideeffect_pend & ~bus_addr_match_pending; assign obuf_rst = bus_cmd_sent & ~obuf_wr_en; assign obuf_write_in = ibuf_buf_byp ? lsu_pkt_dc5.store : buf_write[CmdPtr0]; @@ -513,18 +513,18 @@ module lsu_bus_buffer assign obuf_byteen0_in[7:0] = ibuf_buf_byp ? (lsu_addr_dc5[2] ? {ldst_byteen_lo_dc5[3:0],4'b0} : {4'b0,ldst_byteen_lo_dc5[3:0]}) : (buf_addr[CmdPtr0][2] ? {buf_byteen[CmdPtr0],4'b0} : {4'b0,buf_byteen[CmdPtr0]}); assign obuf_byteen1_in[7: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_dc5[2] ? {store_data_lo_dc5[31:0],32'b0} : {32'b0,store_data_lo_dc5[31:0]}) : + assign obuf_data0_in[63:0] = ibuf_buf_byp ? (lsu_addr_dc5[2] ? {store_data_lo_dc5[31:0],32'b0} : {32'b0,store_data_lo_dc5[31:0]}) : (buf_addr[CmdPtr0][2] ? {buf_data[CmdPtr0],32'b0} : {32'b0,buf_data[CmdPtr0]}); assign obuf_data1_in[63: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] & + 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 - + rvdff #(.WIDTH(1)) obuf_wren_ff (.din(obuf_wr_en), .dout(obuf_wr_enQ), .clk(lsu_busm_clk), .*); rvdff #(.WIDTH(1)) obuf_cmd_done_ff (.din(obuf_cmd_done_in), .dout(obuf_cmd_done), .clk(lsu_busm_clk), .*); rvdff #(.WIDTH(1)) obuf_data_done_ff (.din(obuf_data_done_in), .dout(obuf_data_done), .clk(lsu_busm_clk), .*); @@ -539,7 +539,7 @@ module lsu_bus_buffer rvdffs #(.WIDTH(8)) obuf_byteenff (.din(obuf_byteen_in[7:0]), .dout(obuf_byteen), .en(obuf_wr_en), .clk(lsu_bus_obuf_c1_clk), .*); rvdffe #(.WIDTH(64)) obuf_dataff (.din(obuf_data_in[63:0]), .dout(obuf_data), .en(obuf_wr_en), .*); rvdff #(.WIDTH(TIMER_LOG2)) obuf_timerff (.din(obuf_wr_timer_in), .dout(obuf_wr_timer), .clk(lsu_busm_clk), .*); - + //------------------------------------------------------------------------------ // Output buffer logic ends here //------------------------------------------------------------------------------ @@ -556,7 +556,7 @@ module lsu_bus_buffer if (~found_wrptr0) begin WrPtr0_dc3[DEPTH_LOG2-1:0] = DEPTH_LOG2'(i); found_wrptr0 = (buf_state[i] == IDLE) & ~((ibuf_valid & (ibuf_tag == DEPTH_LOG2'(i))) | - (lsu_busreq_dc4 & ((WrPtr0_dc4 == DEPTH_LOG2'(i)) | (ldst_dual_dc4 & (WrPtr1_dc4 == DEPTH_LOG2'(i))))) | + (lsu_busreq_dc4 & ((WrPtr0_dc4 == DEPTH_LOG2'(i)) | (ldst_dual_dc4 & (WrPtr1_dc4 == DEPTH_LOG2'(i))))) | (lsu_busreq_dc5 & ((WrPtr0_dc5 == DEPTH_LOG2'(i)) | (ldst_dual_dc5 & (WrPtr1_dc5 == DEPTH_LOG2'(i)))))); //found_wrptr = (buf_state[i] == IDLE); end @@ -568,7 +568,7 @@ module lsu_bus_buffer WrPtr1_dc3[DEPTH_LOG2-1:0] = DEPTH_LOG2'(i); found_wrptr1 = (buf_state[i] == IDLE) & ~((ibuf_valid & (ibuf_tag == DEPTH_LOG2'(i))) | (lsu_busreq_dc3 & (WrPtr0_dc3 == DEPTH_LOG2'(i))) | - (lsu_busreq_dc4 & ((WrPtr0_dc4 == DEPTH_LOG2'(i)) | (ldst_dual_dc4 & (WrPtr1_dc4 == DEPTH_LOG2'(i))))) | + (lsu_busreq_dc4 & ((WrPtr0_dc4 == DEPTH_LOG2'(i)) | (ldst_dual_dc4 & (WrPtr1_dc4 == DEPTH_LOG2'(i))))) | (lsu_busreq_dc5 & ((WrPtr0_dc5 == DEPTH_LOG2'(i)) | (ldst_dual_dc5 & (WrPtr1_dc5 == DEPTH_LOG2'(i)))))); //found_wrptr = (buf_state[i] == IDLE); end @@ -590,14 +590,14 @@ module lsu_bus_buffer // Age vector for (genvar i=0; i= (DEPTH-1)); - assign lsu_bus_buffer_empty_any = ~(|buf_state[DEPTH-1:0]) & ~ibuf_valid & ~obuf_valid; + assign lsu_bus_buffer_empty_any = ~(|buf_state[DEPTH-1:0]) & ~ibuf_valid & ~obuf_valid; // Freeze logic assign FreezePtrEn = lsu_busreq_dc3 & lsu_pkt_dc3.load & ld_freeze_dc3; - assign ld_freeze_en = (is_sideeffects_dc2 | dec_nonblock_load_freeze_dc2 | dec_tlu_non_blocking_disable) & lsu_busreq_dc2 & lsu_pkt_dc2.load & ~lsu_freeze_dc3 & ~flush_dc2_up & ~ld_full_hit_dc2; + assign ld_freeze_en = (is_sideeffects_dc2 | dec_nonblock_load_freeze_dc2 | dec_tlu_non_blocking_disable) & lsu_busreq_dc2 & lsu_pkt_dc2.load & ~lsu_freeze_dc3 & ~flush_dc2_up & ~ld_full_hit_dc2; always_comb begin ld_freeze_rst = flush_dc3 | (dec_tlu_cancel_e4 & ld_freeze_dc3); for (int i=0; i> (8*lsu_addr_dc2[1:0]); assign bus_read_data_dc3[31:0] = ld_full_hit_dc3 ? ld_fwddata_dc3[31:0] : ld_bus_data_dc3[31:0]; - + // Fifo flops rvdff #(.WIDTH(1)) lsu_full_hit_dc3ff (.din(ld_full_hit_dc2), .dout(ld_full_hit_dc3), .clk(lsu_freeze_c2_dc3_clk), .*); rvdff #(.WIDTH(32)) lsu_fwddata_dc3ff (.din(ld_fwddata_dc2[31:0]), .dout(ld_fwddata_dc3[31:0]), .clk(lsu_c1_dc3_clk), .*); @@ -398,7 +398,7 @@ module lsu_bus_intf rvdff #(4) lsu_byten_dc3ff (.*, .din(ldst_byteen_dc2[3:0]), .dout(ldst_byteen_dc3[3:0]), .clk(lsu_freeze_c1_dc3_clk)); rvdff #(4) lsu_byten_dc4ff (.*, .din(ldst_byteen_dc3[3:0]), .dout(ldst_byteen_dc4[3:0]), .clk(lsu_c1_dc4_clk)); rvdff #(4) lsu_byten_dc5ff (.*, .din(ldst_byteen_dc4[3:0]), .dout(ldst_byteen_dc5[3:0]), .clk(lsu_c1_dc5_clk)); - + `ifdef ASSERT_ON // Assertion to check ld imprecise error comes with right address // property lsu_ld_imprecise_error_check; diff --git a/design/lsu/lsu_clkdomain.sv b/design/lsu/lsu_clkdomain.sv index d3a7b0f..00f7c3f 100644 --- a/design/lsu/lsu_clkdomain.sv +++ b/design/lsu/lsu_clkdomain.sv @@ -1,12 +1,12 @@ // 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. @@ -16,21 +16,21 @@ //******************************************************************************** // $Id$ // -// -// Owner: +// +// Owner: // Function: Clock Generation Block // Comments: All the clocks are generate here // // //******************************************************************************** -module lsu_clkdomain +module lsu_clkdomain import swerv_types::*; ( input logic clk, // clock input logic free_clk, // clock input logic rst_l, // reset - + // Inputs input logic clk_override, // chciken bit to turn off clock gating input logic lsu_freeze_dc3, // freeze @@ -49,76 +49,76 @@ module lsu_clkdomain //input logic lsu_load_stall_any, // Need to turn on clocks for this case input logic lsu_bus_clk_en, // bus clock enable - - input lsu_pkt_t lsu_p, // lsu packet in decode + + input lsu_pkt_t lsu_p, // lsu packet in decode input lsu_pkt_t lsu_pkt_dc1, // lsu packet in dc1 - input lsu_pkt_t lsu_pkt_dc2, // lsu packet in dc2 + input lsu_pkt_t lsu_pkt_dc2, // lsu packet in dc2 input lsu_pkt_t lsu_pkt_dc3, // lsu packet in dc3 input lsu_pkt_t lsu_pkt_dc4, // lsu packet in dc4 input lsu_pkt_t lsu_pkt_dc5, // lsu packet in dc5 - // Outputs - output logic lsu_c1_dc3_clk, // dc3 pipe single pulse clock - output logic lsu_c1_dc4_clk, // dc4 pipe single pulse clock - output logic lsu_c1_dc5_clk, // dc5 pipe single pulse clock - - output logic lsu_c2_dc3_clk, // dc3 pipe double pulse clock + // Outputs + output logic lsu_c1_dc3_clk, // dc3 pipe single pulse clock + output logic lsu_c1_dc4_clk, // dc4 pipe single pulse clock + output logic lsu_c1_dc5_clk, // dc5 pipe single pulse clock + + output logic lsu_c2_dc3_clk, // dc3 pipe double pulse clock output logic lsu_c2_dc4_clk, // dc4 pipe double pulse clock output logic lsu_c2_dc5_clk, // dc5 pipe double pulse clock - output logic lsu_store_c1_dc1_clken, // store in dc1 + output logic lsu_store_c1_dc1_clken, // store in dc1 output logic lsu_store_c1_dc2_clken, // store in dc2 output logic lsu_store_c1_dc3_clken, // store in dc3 output logic lsu_store_c1_dc4_clk, // store in dc4 output logic lsu_store_c1_dc5_clk, // store in dc5 - output logic lsu_freeze_c1_dc1_clken, // freeze - output logic lsu_freeze_c1_dc2_clken, // freeze - output logic lsu_freeze_c1_dc3_clken, // freeze + output logic lsu_freeze_c1_dc1_clken, // freeze + output logic lsu_freeze_c1_dc2_clken, // freeze + output logic lsu_freeze_c1_dc3_clken, // freeze - output logic lsu_freeze_c1_dc2_clk, // freeze - output logic lsu_freeze_c1_dc3_clk, // freeze + output logic lsu_freeze_c1_dc2_clk, // freeze + output logic lsu_freeze_c1_dc3_clk, // freeze - output logic lsu_freeze_c2_dc1_clk, - output logic lsu_freeze_c2_dc2_clk, - output logic lsu_freeze_c2_dc3_clk, + output logic lsu_freeze_c2_dc1_clk, + output logic lsu_freeze_c2_dc2_clk, + output logic lsu_freeze_c2_dc3_clk, output logic lsu_freeze_c2_dc4_clk, output logic lsu_dccm_c1_dc3_clk, // dccm clock output logic lsu_pic_c1_dc3_clken, // pic clock enable - output logic lsu_stbuf_c1_clk, + 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, - input logic scan_mode + input logic scan_mode ); - logic lsu_c1_dc1_clken, lsu_c1_dc2_clken, lsu_c1_dc3_clken, lsu_c1_dc4_clken, lsu_c1_dc5_clken; - logic lsu_c2_dc3_clken, lsu_c2_dc4_clken, lsu_c2_dc5_clken; - logic lsu_c1_dc1_clken_q, lsu_c1_dc2_clken_q, lsu_c1_dc3_clken_q, lsu_c1_dc4_clken_q, lsu_c1_dc5_clken_q; + logic lsu_c1_dc1_clken, lsu_c1_dc2_clken, lsu_c1_dc3_clken, lsu_c1_dc4_clken, lsu_c1_dc5_clken; + logic lsu_c2_dc3_clken, lsu_c2_dc4_clken, lsu_c2_dc5_clken; + logic lsu_c1_dc1_clken_q, lsu_c1_dc2_clken_q, lsu_c1_dc3_clken_q, lsu_c1_dc4_clken_q, lsu_c1_dc5_clken_q; logic lsu_store_c1_dc4_clken, lsu_store_c1_dc5_clken; - logic lsu_freeze_c1_dc4_clken; - logic lsu_freeze_c2_dc1_clken, lsu_freeze_c2_dc2_clken, lsu_freeze_c2_dc3_clken, lsu_freeze_c2_dc4_clken; - logic lsu_freeze_c1_dc1_clken_q, lsu_freeze_c1_dc2_clken_q, lsu_freeze_c1_dc3_clken_q, lsu_freeze_c1_dc4_clken_q; + logic lsu_freeze_c1_dc4_clken; + logic lsu_freeze_c2_dc1_clken, lsu_freeze_c2_dc2_clken, lsu_freeze_c2_dc3_clken, lsu_freeze_c2_dc4_clken; + logic lsu_freeze_c1_dc1_clken_q, lsu_freeze_c1_dc2_clken_q, lsu_freeze_c1_dc3_clken_q, lsu_freeze_c1_dc4_clken_q; logic lsu_stbuf_c1_clken; logic lsu_bus_ibuf_c1_clken, lsu_bus_obuf_c1_clken, lsu_bus_buf_c1_clken; - + logic lsu_dccm_c1_dc3_clken; - + logic lsu_free_c1_clken, lsu_free_c1_clken_q, lsu_free_c2_clken; logic lsu_bus_valid_clken; - + //------------------------------------------------------------------------------------------- // Clock Enable logic //------------------------------------------------------------------------------------------- - + // Also use the flopped clock enable. We want to turn on the clocks from dc1->dc5 even if there is a freeze assign lsu_c1_dc1_clken = lsu_p.valid | dma_dccm_req | clk_override; assign lsu_c1_dc2_clken = lsu_pkt_dc1.valid | lsu_c1_dc1_clken_q | clk_override; @@ -140,25 +140,25 @@ module lsu_clkdomain assign lsu_freeze_c1_dc2_clken = (lsu_pkt_dc1.valid | clk_override) & ~lsu_freeze_dc3; assign lsu_freeze_c1_dc3_clken = (lsu_pkt_dc2.valid | clk_override) & ~lsu_freeze_dc3; assign lsu_freeze_c1_dc4_clken = (lsu_pkt_dc3.valid | clk_override) & ~lsu_freeze_dc3; - + assign lsu_freeze_c2_dc1_clken = (lsu_freeze_c1_dc1_clken | lsu_freeze_c1_dc1_clken_q | clk_override) & ~lsu_freeze_dc3; assign lsu_freeze_c2_dc2_clken = (lsu_freeze_c1_dc2_clken | lsu_freeze_c1_dc2_clken_q | clk_override) & ~lsu_freeze_dc3; assign lsu_freeze_c2_dc3_clken = (lsu_freeze_c1_dc3_clken | lsu_freeze_c1_dc3_clken_q | clk_override) & ~lsu_freeze_dc3; assign lsu_freeze_c2_dc4_clken = (lsu_freeze_c1_dc4_clken | lsu_freeze_c1_dc4_clken_q | clk_override) & ~lsu_freeze_dc3; - + assign lsu_stbuf_c1_clken = load_stbuf_reqvld_dc3 | store_stbuf_reqvld_dc3 | stbuf_reqvld_any | stbuf_reqvld_flushed_any | clk_override; assign lsu_bus_ibuf_c1_clken = lsu_busreq_dc5 | clk_override; assign lsu_bus_obuf_c1_clken = ((lsu_bus_buffer_pend_any | lsu_busreq_dc5) & lsu_bus_clk_en) | clk_override; assign lsu_bus_buf_c1_clken = ~lsu_bus_buffer_empty_any | lsu_busreq_dc5 | clk_override; - + assign lsu_dccm_c1_dc3_clken = ((lsu_c1_dc3_clken & addr_in_dccm_dc2) | clk_override) & ~lsu_freeze_dc3; assign lsu_pic_c1_dc3_clken = ((lsu_c1_dc3_clken & addr_in_pic_dc2) | clk_override) & ~lsu_freeze_dc3; - assign lsu_free_c1_clken = (lsu_p.valid | lsu_pkt_dc1.valid | lsu_pkt_dc2.valid | lsu_pkt_dc3.valid | lsu_pkt_dc4.valid | lsu_pkt_dc5.valid) | + assign lsu_free_c1_clken = (lsu_p.valid | lsu_pkt_dc1.valid | lsu_pkt_dc2.valid | lsu_pkt_dc3.valid | lsu_pkt_dc4.valid | lsu_pkt_dc5.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(free_clk), .*); @@ -203,11 +203,11 @@ module lsu_clkdomain rvoclkhdr lsu_bus_buf_c1_cgc ( .en(lsu_bus_buf_c1_clken), .l1clk(lsu_bus_buf_c1_clk), .* ); rvclkhdr lsu_busm_cgc (.en(lsu_bus_clk_en), .l1clk(lsu_busm_clk), .*); - + rvclkhdr lsu_dccm_c1dc3_cgc (.en(lsu_dccm_c1_dc3_clken), .l1clk(lsu_dccm_c1_dc3_clk), .*); // rvclkhdr lsu_pic_c1dc3_cgc (.en(lsu_pic_c1_dc3_clken), .l1clk(lsu_pic_c1_dc3_clk), .*); - + rvclkhdr lsu_free_cgc (.en(lsu_free_c2_clken), .l1clk(lsu_free_c2_clk), .*); - + endmodule - + diff --git a/design/lsu/lsu_dccm_ctl.sv b/design/lsu/lsu_dccm_ctl.sv index 4bb553a..5122746 100644 --- a/design/lsu/lsu_dccm_ctl.sv +++ b/design/lsu/lsu_dccm_ctl.sv @@ -1,12 +1,12 @@ // 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. @@ -16,28 +16,28 @@ //******************************************************************************** // $Id$ // -// -// Owner: +// +// Owner: // Function: DCCM for LSU pipe // Comments: Single ported memory // -// +// // DC1 -> DC2 -> DC3 -> DC4 (Commit) -// +// // //******************************************************************************** -module lsu_dccm_ctl +module lsu_dccm_ctl import swerv_types::*; ( input logic lsu_freeze_c2_dc2_clk, // clocks input logic lsu_freeze_c2_dc3_clk, input logic lsu_dccm_c1_dc3_clk, input logic lsu_pic_c1_dc3_clken, - + input logic rst_l, input logic clk, input logic lsu_freeze_dc3, // freze - + input lsu_pkt_t lsu_pkt_dc3, // lsu packets input lsu_pkt_t lsu_pkt_dc1, input logic addr_in_dccm_dc1, // address maps to dccm @@ -50,32 +50,32 @@ module lsu_dccm_ctl input logic stbuf_reqvld_any, // write enable input logic stbuf_addr_in_pic_any, // stbuf is going to pic input logic [`RV_LSU_SB_BITS-1:0] stbuf_addr_any, // stbuf address (aligned) - + input logic [`RV_DCCM_DATA_WIDTH-1:0] stbuf_data_any, // the read out from stbuf - input logic [`RV_DCCM_ECC_WIDTH-1:0] stbuf_ecc_any, // the encoded data with ECC bits + input logic [`RV_DCCM_ECC_WIDTH-1:0] stbuf_ecc_any, // the encoded data with ECC bits input logic [`RV_DCCM_DATA_WIDTH-1:0] stbuf_fwddata_hi_dc3, // stbuf fowarding to load input logic [`RV_DCCM_DATA_WIDTH-1:0] stbuf_fwddata_lo_dc3, // stbuf fowarding to load input logic [`RV_DCCM_BYTE_WIDTH-1:0] stbuf_fwdbyteen_hi_dc3, // stbuf fowarding to load - input logic [`RV_DCCM_BYTE_WIDTH-1:0] stbuf_fwdbyteen_lo_dc3, // stbuf fowarding to load + input logic [`RV_DCCM_BYTE_WIDTH-1:0] stbuf_fwdbyteen_lo_dc3, // stbuf fowarding to load input logic lsu_double_ecc_error_dc3, // lsu has a DED input logic [`RV_DCCM_DATA_WIDTH-1:0] store_ecc_datafn_hi_dc3, // store data - input logic [`RV_DCCM_DATA_WIDTH-1:0] store_ecc_datafn_lo_dc3, // store data + input logic [`RV_DCCM_DATA_WIDTH-1:0] store_ecc_datafn_lo_dc3, // store data output logic [`RV_DCCM_DATA_WIDTH-1:0] dccm_data_hi_dc3, // data from the dccm output logic [`RV_DCCM_DATA_WIDTH-1:0] dccm_data_lo_dc3, // data from the dccm output logic [`RV_DCCM_ECC_WIDTH-1:0] dccm_data_ecc_hi_dc3, // data from the dccm + ecc - output logic [`RV_DCCM_ECC_WIDTH-1:0] dccm_data_ecc_lo_dc3, + output logic [`RV_DCCM_ECC_WIDTH-1:0] dccm_data_ecc_lo_dc3, output logic [`RV_DCCM_DATA_WIDTH-1:0] lsu_ld_data_dc3, // right justified, ie load byte will have data at 7:0 output logic [`RV_DCCM_DATA_WIDTH-1:0] lsu_ld_data_corr_dc3, // right justified, ie load byte will have data at 7:0 output logic [31:0] picm_mask_data_dc3, // pic data to stbuf output logic lsu_stbuf_commit_any, // stbuf wins the dccm port or is to pic output logic lsu_dccm_rden_dc3, // 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 [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 @@ -83,7 +83,7 @@ module lsu_dccm_ctl output logic [`RV_DCCM_BITS-1:0] dccm_rd_addr_lo, // dccm interface -- read address for lo bank output logic [`RV_DCCM_BITS-1:0] dccm_rd_addr_hi, // dccm interface -- read address for hi bank output logic [`RV_DCCM_FDATA_WIDTH-1:0] dccm_wr_data, // dccm write data - + input logic [`RV_DCCM_FDATA_WIDTH-1:0] dccm_rd_data_lo, // dccm read data back from the dccm input logic [`RV_DCCM_FDATA_WIDTH-1:0] dccm_rd_data_hi, // dccm read data back from the dccm @@ -94,12 +94,12 @@ module lsu_dccm_ctl output logic [31:0] picm_addr, // address for pic access - shared between reads and write output logic [31:0] picm_wr_data, // write data input logic [31:0] picm_rd_data, // read data - - input logic scan_mode // scan mode + + input logic scan_mode // scan mode ); `include "global.h" - + `ifdef RV_DCCM_ENABLE localparam DCCM_ENABLE = 1'b1; `else @@ -108,7 +108,7 @@ module lsu_dccm_ctl localparam DCCM_WIDTH_BITS = $clog2(DCCM_BYTE_WIDTH); localparam PIC_BITS =`RV_PIC_BITS; - + logic lsu_dccm_rden_dc1, lsu_dccm_rden_dc2; logic [DCCM_DATA_WIDTH-1:0] dccm_data_hi_dc2, dccm_data_lo_dc2; logic [DCCM_ECC_WIDTH-1:0] dccm_data_ecc_hi_dc2, dccm_data_ecc_lo_dc2; @@ -119,31 +119,31 @@ module lsu_dccm_ctl logic [63:0] picm_rd_data_dc3; logic [31:0] picm_rd_data_lo_dc3; logic [63:32] lsu_ld_data_dc3_nc, lsu_ld_data_corr_dc3_nc; - + assign dccm_dma_rvalid = lsu_pkt_dc3.valid & lsu_pkt_dc3.load & lsu_pkt_dc3.dma; assign dccm_dma_ecc_error = lsu_double_ecc_error_dc3; - assign dccm_dma_rdata[63:0] = lsu_rdata_corr_dc3[63:0]; - - + assign dccm_dma_rdata[63:0] = lsu_pkt_dc3.dword ? lsu_rdata_corr_dc3[63:0] : {2{lsu_rdata_corr_dc3[31:0]}}; // Need to replicate the data for non-dw access since ecc correction is done only in lower word + + assign {lsu_ld_data_dc3_nc[63:32], lsu_ld_data_dc3[31:0]} = lsu_rdata_dc3[63:0] >> 8*lsu_addr_dc3[1:0]; assign {lsu_ld_data_corr_dc3_nc[63:32], lsu_ld_data_corr_dc3[31:0]} = lsu_rdata_corr_dc3[63:0] >> 8*lsu_addr_dc3[1:0]; - + assign dccm_dout_dc3[63:0] = {dccm_data_hi_dc3[DCCM_DATA_WIDTH-1:0], dccm_data_lo_dc3[DCCM_DATA_WIDTH-1:0]}; assign dccm_corr_dout_dc3[63:0] = {store_ecc_datafn_hi_dc3[DCCM_DATA_WIDTH-1:0], store_ecc_datafn_lo_dc3[DCCM_DATA_WIDTH-1:0]}; assign stbuf_fwddata_dc3[63:0] = {stbuf_fwddata_hi_dc3[DCCM_DATA_WIDTH-1:0], stbuf_fwddata_lo_dc3[DCCM_DATA_WIDTH-1:0]}; assign stbuf_fwdbyteen_dc3[7:0] = {stbuf_fwdbyteen_hi_dc3[DCCM_BYTE_WIDTH-1:0], stbuf_fwdbyteen_lo_dc3[DCCM_BYTE_WIDTH-1:0]}; for (genvar i=0; i<8; i++) begin: GenLoop - assign lsu_rdata_dc3[(8*i)+7:8*i] = stbuf_fwdbyteen_dc3[i] ? stbuf_fwddata_dc3[(8*i)+7:8*i] : + assign lsu_rdata_dc3[(8*i)+7:8*i] = stbuf_fwdbyteen_dc3[i] ? stbuf_fwddata_dc3[(8*i)+7:8*i] : (addr_in_pic_dc3 ? picm_rd_data_dc3[(8*i)+7:8*i] : dccm_dout_dc3[(8*i)+7:8*i]); - assign lsu_rdata_corr_dc3[(8*i)+7:8*i] = stbuf_fwdbyteen_dc3[i] ? stbuf_fwddata_dc3[(8*i)+7:8*i] : + assign lsu_rdata_corr_dc3[(8*i)+7:8*i] = stbuf_fwdbyteen_dc3[i] ? stbuf_fwddata_dc3[(8*i)+7:8*i] : (addr_in_pic_dc3 ? picm_rd_data_dc3[(8*i)+7:8*i] : dccm_corr_dout_dc3[(8*i)+7:8*i]); end assign lsu_stbuf_commit_any = stbuf_reqvld_any & ~lsu_freeze_dc3 & ( (~(lsu_dccm_rden_dc1 | picm_rden | picm_mken)) | ((picm_rden | picm_mken) & ~stbuf_addr_in_pic_any) | - (lsu_dccm_rden_dc1 & (stbuf_addr_in_pic_any | (~((stbuf_addr_any[DCCM_WIDTH_BITS+:DCCM_BANK_BITS] == lsu_addr_dc1[DCCM_WIDTH_BITS+:DCCM_BANK_BITS]) | + (lsu_dccm_rden_dc1 & (stbuf_addr_in_pic_any | (~((stbuf_addr_any[DCCM_WIDTH_BITS+:DCCM_BANK_BITS] == lsu_addr_dc1[DCCM_WIDTH_BITS+:DCCM_BANK_BITS]) | (stbuf_addr_any[DCCM_WIDTH_BITS+:DCCM_BANK_BITS] == end_addr_dc1[DCCM_WIDTH_BITS+:DCCM_BANK_BITS])))))); // No need to read for aligned word/dword stores since ECC will come by new data completely @@ -168,14 +168,14 @@ module lsu_dccm_ctl assign picm_wren = lsu_stbuf_commit_any & stbuf_addr_in_pic_any; assign picm_rden = lsu_pkt_dc1.valid & lsu_pkt_dc1.load & addr_in_pic_dc1; assign picm_mken = lsu_pkt_dc1.valid & lsu_pkt_dc1.store & addr_in_pic_dc1; // Get the mask for stores - assign picm_addr[31:0] = (picm_rden | picm_mken) ? (`RV_PIC_BASE_ADDR | {17'b0,lsu_addr_dc1[14:0]}) : (`RV_PIC_BASE_ADDR | {{32-PIC_BITS{1'b0}},stbuf_addr_any[`RV_PIC_BITS-1:0]}); - //assign picm_addr[31:0] = (picm_rden | picm_mken) ? {`RV_PIC_REGION,`RV_PIC_OFFSET,3'b0,lsu_addr_dc1[14:0]} : {`RV_PIC_REGION,`RV_PIC_OFFSET,{18-PIC_BITS{1'b0}},stbuf_addr_any[`RV_PIC_BITS-1:0]}; + assign picm_addr[31:0] = (picm_rden | picm_mken) ? (`RV_PIC_BASE_ADDR | {17'b0,lsu_addr_dc1[14:0]}) : (`RV_PIC_BASE_ADDR | {{32-PIC_BITS{1'b0}},stbuf_addr_any[`RV_PIC_BITS-1:0]}); + //assign picm_addr[31:0] = (picm_rden | picm_mken) ? {`RV_PIC_REGION,`RV_PIC_OFFSET,3'b0,lsu_addr_dc1[14:0]} : {`RV_PIC_REGION,`RV_PIC_OFFSET,{18-PIC_BITS{1'b0}},stbuf_addr_any[`RV_PIC_BITS-1:0]}; assign picm_wr_data[31:0] = stbuf_data_any[31:0]; - - + + // Flops assign picm_mask_data_dc3[31:0] = picm_rd_data_lo_dc3[31:0]; - assign picm_rd_data_dc3[63:0] = {picm_rd_data_lo_dc3[31:0], picm_rd_data_lo_dc3[31:0]} ; + assign picm_rd_data_dc3[63:0] = {picm_rd_data_lo_dc3[31:0], picm_rd_data_lo_dc3[31:0]} ; rvdffe #(32) picm_data_ff (.*, .din(picm_rd_data[31:0]), .dout(picm_rd_data_lo_dc3[31:0]), .en(lsu_pic_c1_dc3_clken)); if (DCCM_ENABLE == 1) begin: Gen_dccm_enable rvdff #(1) dccm_rden_dc2ff (.*, .din(lsu_dccm_rden_dc1), .dout(lsu_dccm_rden_dc2), .clk(lsu_freeze_c2_dc2_clk)); @@ -183,7 +183,7 @@ module lsu_dccm_ctl rvdff #(DCCM_DATA_WIDTH) dccm_data_hi_ff (.*, .din(dccm_data_hi_dc2[DCCM_DATA_WIDTH-1:0]), .dout(dccm_data_hi_dc3[DCCM_DATA_WIDTH-1:0]), .clk(lsu_dccm_c1_dc3_clk)); rvdff #(DCCM_DATA_WIDTH) dccm_data_lo_ff (.*, .din(dccm_data_lo_dc2[DCCM_DATA_WIDTH-1:0]), .dout(dccm_data_lo_dc3[DCCM_DATA_WIDTH-1:0]), .clk(lsu_dccm_c1_dc3_clk)); - + rvdff #(DCCM_ECC_WIDTH) dccm_data_ecc_hi_ff (.*, .din(dccm_data_ecc_hi_dc2[DCCM_ECC_WIDTH-1:0]), .dout(dccm_data_ecc_hi_dc3[DCCM_ECC_WIDTH-1:0]), .clk(lsu_dccm_c1_dc3_clk)); rvdff #(DCCM_ECC_WIDTH) dccm_data_ecc_lo_ff (.*, .din(dccm_data_ecc_lo_dc2[DCCM_ECC_WIDTH-1:0]), .dout(dccm_data_ecc_lo_dc3[DCCM_ECC_WIDTH-1:0]), .clk(lsu_dccm_c1_dc3_clk)); end else begin: Gen_dccm_disable diff --git a/design/lsu/lsu_dccm_mem.sv b/design/lsu/lsu_dccm_mem.sv index e802cfb..9d201a5 100644 --- a/design/lsu/lsu_dccm_mem.sv +++ b/design/lsu/lsu_dccm_mem.sv @@ -1,12 +1,12 @@ // 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. @@ -16,31 +16,31 @@ //******************************************************************************** // $Id$ // -// -// Owner: +// +// Owner: // Function: DCCM for LSU pipe // Comments: Single ported memory // -// +// // DC1 -> DC2 -> DC3 -> DC4 (Commit) -// +// // //******************************************************************************** -module lsu_dccm_mem +module lsu_dccm_mem import swerv_types::*; ( - input logic clk, // clock - input logic rst_l, + input logic clk, // clock + input logic rst_l, input logic lsu_freeze_dc3, // freeze input logic clk_override, // clock override - + input logic dccm_wren, // write enable input logic dccm_rden, // read enable input logic [`RV_DCCM_BITS-1:0] dccm_wr_addr, // write address input logic [`RV_DCCM_BITS-1:0] dccm_rd_addr_lo, // read address input logic [`RV_DCCM_BITS-1:0] dccm_rd_addr_hi, // read address for the upper bank in case of a misaligned access input logic [`RV_DCCM_FDATA_WIDTH-1:0] dccm_wr_data, // write data - + output logic [`RV_DCCM_FDATA_WIDTH-1:0] dccm_rd_data_lo, // read data from the lo bank output logic [`RV_DCCM_FDATA_WIDTH-1:0] dccm_rd_data_hi, // read data from the hi bank @@ -48,10 +48,10 @@ module lsu_dccm_mem ); `include "global.h" - + localparam DCCM_WIDTH_BITS = $clog2(DCCM_BYTE_WIDTH); localparam DCCM_INDEX_BITS = (DCCM_BITS - DCCM_BANK_BITS - DCCM_WIDTH_BITS); - + logic [DCCM_NUM_BANKS-1:0] wren_bank; logic [DCCM_NUM_BANKS-1:0] rden_bank; logic [DCCM_NUM_BANKS-1:0] [DCCM_BITS-1:(DCCM_BANK_BITS+2)] addr_bank; @@ -67,30 +67,30 @@ module lsu_dccm_mem logic [(DCCM_WIDTH_BITS+DCCM_BANK_BITS-1):DCCM_WIDTH_BITS] dccm_rd_addr_lo_q; logic [(DCCM_WIDTH_BITS+DCCM_BANK_BITS-1):DCCM_WIDTH_BITS] dccm_rd_addr_hi_q; - + logic [DCCM_NUM_BANKS-1:0] dccm_clk; logic [DCCM_NUM_BANKS-1:0] dccm_clken; - + assign rd_unaligned = (dccm_rd_addr_lo[DCCM_WIDTH_BITS+:DCCM_BANK_BITS] != dccm_rd_addr_hi[DCCM_WIDTH_BITS+:DCCM_BANK_BITS]); - + // Align the read data assign dccm_rd_data_lo[DCCM_FDATA_WIDTH-1:0] = dccm_bank_dout[dccm_rd_addr_lo_q[DCCM_WIDTH_BITS+:DCCM_BANK_BITS]][DCCM_FDATA_WIDTH-1:0]; assign dccm_rd_data_hi[DCCM_FDATA_WIDTH-1:0] = dccm_bank_dout[dccm_rd_addr_hi_q[DCCM_WIDTH_BITS+:DCCM_BANK_BITS]][DCCM_FDATA_WIDTH-1:0]; // Generate even/odd address - // assign rd_addr_even[(DCCM_BANK_BITS+DCCM_WIDTH_BITS)+:DCCM_INDEX_BITS] = dccm_rd_addr_lo[2] ? dccm_rd_addr_hi[(DCCM_BANK_BITS+DCCM_WIDTH_BITS)+:DCCM_INDEX_BITS] : + // assign rd_addr_even[(DCCM_BANK_BITS+DCCM_WIDTH_BITS)+:DCCM_INDEX_BITS] = dccm_rd_addr_lo[2] ? dccm_rd_addr_hi[(DCCM_BANK_BITS+DCCM_WIDTH_BITS)+:DCCM_INDEX_BITS] : // dccm_rd_addr_lo[(DCCM_BANK_BITS+DCCM_WIDTH_BITS)+:DCCM_INDEX_BITS]; - - // assign rd_addr_odd[(DCCM_BANK_BITS+DCCM_WIDTH_BITS)+:DCCM_INDEX_BITS] = dccm_rd_addr_lo[2] ? dccm_rd_addr_lo[(DCCM_BANK_BITS+DCCM_WIDTH_BITS)+:DCCM_INDEX_BITS] : - // dccm_rd_addr_hi[(DCCM_BANK_BITS+DCCM_WIDTH_BITS)+:DCCM_INDEX_BITS]; - + + // assign rd_addr_odd[(DCCM_BANK_BITS+DCCM_WIDTH_BITS)+:DCCM_INDEX_BITS] = dccm_rd_addr_lo[2] ? dccm_rd_addr_lo[(DCCM_BANK_BITS+DCCM_WIDTH_BITS)+:DCCM_INDEX_BITS] : + // dccm_rd_addr_hi[(DCCM_BANK_BITS+DCCM_WIDTH_BITS)+:DCCM_INDEX_BITS]; + // 8 Banks, 16KB each (2048 x 72) for (genvar i=0; i DC2 -> DC3 -> DC4 (Commit) -// +// //******************************************************************************** -module lsu_ecc +module lsu_ecc import swerv_types::*; ( @@ -41,34 +41,34 @@ module lsu_ecc input logic [`RV_DCCM_BITS-1:0] lsu_addr_dc3, // start address input logic [`RV_DCCM_BITS-1:0] end_addr_dc3, // end address input logic [63:0] store_data_dc3, // store data - input logic [`RV_DCCM_DATA_WIDTH-1:0] stbuf_data_any, + input logic [`RV_DCCM_DATA_WIDTH-1:0] stbuf_data_any, input logic [`RV_DCCM_DATA_WIDTH-1:0] stbuf_fwddata_hi_dc3, // data forward from the store buffer input logic [`RV_DCCM_DATA_WIDTH-1:0] stbuf_fwddata_lo_dc3, // data forward from the store buffer input logic [`RV_DCCM_BYTE_WIDTH-1:0] stbuf_fwdbyteen_hi_dc3,// which bytes from the store buffer are on input logic [`RV_DCCM_BYTE_WIDTH-1:0] stbuf_fwdbyteen_lo_dc3,// which bytes from the store buffer are on - + input logic [`RV_DCCM_DATA_WIDTH-1:0] dccm_data_hi_dc3, // raw data from mem input logic [`RV_DCCM_DATA_WIDTH-1:0] dccm_data_lo_dc3, // raw data from mem input logic [`RV_DCCM_ECC_WIDTH-1:0] dccm_data_ecc_hi_dc3, // ecc read out from mem input logic [`RV_DCCM_ECC_WIDTH-1:0] dccm_data_ecc_lo_dc3, // ecc read out from mem input logic dec_tlu_core_ecc_disable, // disables the ecc computation and error flagging - - output logic [`RV_DCCM_DATA_WIDTH-1:0] store_ecc_datafn_hi_dc3, // final store data either from stbuf or SEC DCCM readout + + output logic [`RV_DCCM_DATA_WIDTH-1:0] store_ecc_datafn_hi_dc3, // final store data either from stbuf or SEC DCCM readout output logic [`RV_DCCM_DATA_WIDTH-1:0] store_ecc_datafn_lo_dc3, - output logic [`RV_DCCM_ECC_WIDTH-1:0] stbuf_ecc_any, + output logic [`RV_DCCM_ECC_WIDTH-1:0] stbuf_ecc_any, output logic single_ecc_error_hi_dc3, // sec detected output logic single_ecc_error_lo_dc3, // sec detected on lower dccm bank output logic lsu_single_ecc_error_dc3, // or of the 2 output logic lsu_double_ecc_error_dc3, // double error detected - - input logic scan_mode + + input logic scan_mode ); `include "global.h" - + `ifdef RV_DCCM_ENABLE localparam DCCM_ENABLE = 1'b1; `else @@ -77,8 +77,8 @@ module lsu_ecc logic [DCCM_DATA_WIDTH-1:0] sec_data_hi_dc3; logic [DCCM_DATA_WIDTH-1:0] sec_data_lo_dc3; - - + + logic double_ecc_error_hi_dc3, double_ecc_error_lo_dc3; logic ldst_dual_dc3; @@ -88,12 +88,12 @@ module lsu_ecc logic [7:0] store_byteen_dc3; logic [7:0] store_byteen_ext_dc3; logic [DCCM_BYTE_WIDTH-1:0] store_byteen_hi_dc3, store_byteen_lo_dc3; - + logic [163:0] store_data_ext_dc3; - logic [DCCM_DATA_WIDTH-1:0] store_data_hi_dc3, store_data_lo_dc3; + logic [DCCM_DATA_WIDTH-1:0] store_data_hi_dc3, store_data_lo_dc3; logic [6:0] ecc_out_hi_nc, ecc_out_lo_nc; - - + + assign ldst_dual_dc3 = (lsu_addr_dc3[2] != end_addr_dc3[2]); assign is_ldst_dc3 = lsu_pkt_dc3.valid & (lsu_pkt_dc3.load | lsu_pkt_dc3.store) & addr_in_dccm_dc3 & lsu_dccm_rden_dc3; assign is_ldst_lo_dc3 = is_ldst_dc3 & ~dec_tlu_core_ecc_disable; @@ -104,7 +104,7 @@ module lsu_ecc ({8{lsu_pkt_dc3.word}} & 8'b0000_1111) | ({8{lsu_pkt_dc3.dword}} & 8'b1111_1111); assign store_byteen_dc3[7:0] = ldst_byteen_dc3[7:0] & {8{lsu_pkt_dc3.store}}; - + assign store_byteen_ext_dc3[7:0] = store_byteen_dc3[7:0] << lsu_addr_dc3[1:0]; assign store_byteen_hi_dc3[DCCM_BYTE_WIDTH-1:0] = store_byteen_ext_dc3[7:4]; assign store_byteen_lo_dc3[DCCM_BYTE_WIDTH-1:0] = store_byteen_ext_dc3[3:0]; @@ -113,7 +113,7 @@ module lsu_ecc assign store_data_hi_dc3[DCCM_DATA_WIDTH-1:0] = store_data_ext_dc3[63:32]; assign store_data_lo_dc3[DCCM_DATA_WIDTH-1:0] = store_data_ext_dc3[31:0]; - + // Merge store data and sec data // This is used for loads as well for ecc error case. store_byteen will be 0 for loads for (genvar i=0; i> {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[63:0] = dma_dccm_req ? dma_mem_wdata_shifted[63:0] : {32'b0,exu_lsu_rs2_d[31:0]}; + assign store_data_d[63:0] = dma_dccm_req ? dma_mem_wdata_shifted[63:0] : {32'b0,exu_lsu_rs2_d[31:0]}; assign store_data_dc2_in[63:32] = store_data_dc1[63:32]; - assign store_data_dc2_in[31:0] = (lsu_pkt_dc1.store_data_bypass_c1) ? lsu_result_dc3[31:0] : + assign store_data_dc2_in[31:0] = (lsu_pkt_dc1.store_data_bypass_c1) ? lsu_result_dc3[31:0] : (lsu_pkt_dc1.store_data_bypass_e4_c1[1]) ? i1_result_e4_eff[31:0] : (lsu_pkt_dc1.store_data_bypass_e4_c1[0]) ? i0_result_e4_eff[31:0] : store_data_dc1[31:0]; - + assign store_data_dc2[63:32] = store_data_pre_dc2[63:32]; assign store_data_dc2[31:0] = (lsu_pkt_dc2.store_data_bypass_i0_e2_c2) ? i0_result_e2[31:0] : - (lsu_pkt_dc2.store_data_bypass_c2) ? lsu_result_dc3[31:0] : + (lsu_pkt_dc2.store_data_bypass_c2) ? lsu_result_dc3[31:0] : (lsu_pkt_dc2.store_data_bypass_e4_c2[1]) ? i1_result_e4_eff[31:0] : (lsu_pkt_dc2.store_data_bypass_e4_c2[0]) ? i0_result_e4_eff[31:0] : store_data_pre_dc2[31:0]; assign store_data_dc3[63:32] = store_data_pre_dc3[63:32]; - assign store_data_dc3[31:0] = (picm_mask_data_dc3[31:0] | {32{~addr_in_pic_dc3}}) & + assign store_data_dc3[31:0] = (picm_mask_data_dc3[31:0] | {32{~addr_in_pic_dc3}}) & ((lsu_pkt_dc3.store_data_bypass_e4_c3[1]) ? i1_result_e4_eff[31:0] : (lsu_pkt_dc3.store_data_bypass_e4_c3[0]) ? i0_result_e4_eff[31:0] : store_data_pre_dc3[31:0]); - + rvdff #(32) lsu_result_corr_dc4ff (.*, .din(lsu_result_corr_dc3[31:0]), .dout(lsu_result_corr_dc4[31:0]), .clk(lsu_c1_dc4_clk)); rvdffe #(64) sddc1ff (.*, .din(store_data_d[63:0]), .dout(store_data_dc1[63:0]), .en(lsu_store_c1_dc1_clken)); rvdffe #(64) sddc2ff (.*, .din(store_data_dc2_in[63:0]), .dout(store_data_pre_dc2[63:0]), .en(lsu_store_c1_dc2_clken)); rvdffe #(64) sddc3ff (.*, .din(store_data_dc2[63:0]), .dout(store_data_pre_dc3[63:0]), .en(~lsu_freeze_dc3 & lsu_store_c1_dc3_clken) ); - + rvdff #(32) sddc4ff (.*, .din(store_data_dc3[31:0]), .dout(store_data_dc4[31:0]), .clk(lsu_store_c1_dc4_clk)); - rvdff #(32) sddc5ff (.*, .din(store_data_dc4[31:0]), .dout(store_data_dc5[31:0]), .clk(lsu_store_c1_dc5_clk)); - + rvdff #(32) sddc5ff (.*, .din(store_data_dc4[31:0]), .dout(store_data_dc5[31:0]), .clk(lsu_store_c1_dc5_clk)); + rvdffe #(32) sadc2ff (.*, .din(lsu_addr_dc1[31:0]), .dout(lsu_addr_dc2[31:0]), .en(lsu_freeze_c1_dc2_clken)); rvdffe #(32) sadc3ff (.*, .din(lsu_addr_dc2[31:0]), .dout(lsu_addr_dc3[31:0]), .en(lsu_freeze_c1_dc3_clken)); rvdff #(32) sadc4ff (.*, .din(lsu_addr_dc3[31:0]), .dout(lsu_addr_dc4[31:0]), .clk(lsu_c1_dc4_clk)); - rvdff #(32) sadc5ff (.*, .din(lsu_addr_dc4[31:0]), .dout(lsu_addr_dc5[31:0]), .clk(lsu_c1_dc5_clk)); - + rvdff #(32) sadc5ff (.*, .din(lsu_addr_dc4[31:0]), .dout(lsu_addr_dc5[31:0]), .clk(lsu_c1_dc5_clk)); + rvdffe #(32) end_addr_dc2ff (.*, .din(end_addr_dc1[31:0]), .dout(end_addr_dc2[31:0]), .en(lsu_freeze_c1_dc2_clken)); rvdffe #(32) end_addr_dc3ff (.*, .din(end_addr_dc2[31:0]), .dout(end_addr_dc3[31:0]), .en(lsu_freeze_c1_dc3_clken)); rvdff #(32) end_addr_dc4ff (.*, .din(end_addr_dc3[31:0]), .dout(end_addr_dc4[31:0]), .clk(lsu_c1_dc4_clk)); - rvdff #(32) end_addr_dc5ff (.*, .din(end_addr_dc4[31:0]), .dout(end_addr_dc5[31:0]), .clk(lsu_c1_dc5_clk)); + rvdff #(32) end_addr_dc5ff (.*, .din(end_addr_dc4[31:0]), .dout(end_addr_dc5[31:0]), .clk(lsu_c1_dc5_clk)); rvdff #(1) addr_in_dccm_dc2ff(.din(addr_in_dccm_dc1), .dout(addr_in_dccm_dc2), .clk(lsu_freeze_c1_dc2_clk), .*); rvdff #(1) addr_in_dccm_dc3ff(.din(addr_in_dccm_dc2), .dout(addr_in_dccm_dc3), .clk(lsu_freeze_c1_dc3_clk), .*); rvdff #(1) addr_in_pic_dc2ff(.din(addr_in_pic_dc1), .dout(addr_in_pic_dc2), .clk(lsu_freeze_c1_dc2_clk), .*); rvdff #(1) addr_in_pic_dc3ff(.din(addr_in_pic_dc2), .dout(addr_in_pic_dc3), .clk(lsu_freeze_c1_dc3_clk), .*); - + rvdff #(1) addr_external_dc2ff(.din(addr_external_dc1), .dout(addr_external_dc2), .clk(lsu_freeze_c1_dc2_clk), .*); rvdff #(1) addr_external_dc3ff(.din(addr_external_dc2), .dout(addr_external_dc3), .clk(lsu_freeze_c1_dc3_clk), .*); rvdff #(1) addr_external_dc4ff(.din(addr_external_dc3), .dout(addr_external_dc4), .clk(lsu_c1_dc4_clk), .*); rvdff #(1) addr_external_dc5ff(.din(addr_external_dc4), .dout(addr_external_dc5), .clk(lsu_c1_dc5_clk), .*); - + rvdff #(1) access_fault_dc2ff(.din(access_fault_dc1), .dout(access_fault_dc2), .clk(lsu_freeze_c1_dc2_clk), .*); rvdff #(1) access_fault_dc3ff(.din(access_fault_dc2), .dout(access_fault_dc3), .clk(lsu_freeze_c1_dc3_clk), .*); rvdff #(1) misaligned_fault_dc2ff(.din(misaligned_fault_dc1), .dout(misaligned_fault_dc2), .clk(lsu_freeze_c1_dc2_clk), .*); diff --git a/design/lsu/lsu_stbuf.sv b/design/lsu/lsu_stbuf.sv index 49a2cf9..318302f 100644 --- a/design/lsu/lsu_stbuf.sv +++ b/design/lsu/lsu_stbuf.sv @@ -1,12 +1,12 @@ // 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. @@ -16,14 +16,14 @@ //******************************************************************************** // $Id$ // -// -// Owner: +// +// Owner: // Function: Store Buffer // Comments: Dual writes and single drain // -// +// // DC1 -> DC2 -> DC3 -> DC4 (Commit) -// +// // //******************************************************************************** @@ -34,11 +34,11 @@ module lsu_stbuf input logic rst_l, // reset input logic lsu_freeze_c2_dc2_clk, // freeze clock - input logic lsu_freeze_c2_dc3_clk, // freeze clock + input logic lsu_freeze_c2_dc3_clk, // freeze clock input logic lsu_freeze_c1_dc2_clk, // freeze clock input logic lsu_freeze_c1_dc3_clk, // freeze clock - input logic lsu_freeze_c1_dc3_clken, + input logic lsu_freeze_c1_dc3_clken, input logic lsu_c1_dc4_clk, // lsu pipe clock input logic lsu_c1_dc5_clk, // lsu pipe clock @@ -46,11 +46,11 @@ module lsu_stbuf input logic lsu_c2_dc5_clk, // lsu pipe clock input logic lsu_stbuf_c1_clk, // stbuf clock input logic lsu_free_c2_clk, // free clk - - // Store Buffer input + + // Store Buffer input input logic load_stbuf_reqvld_dc3, // core instruction goes to stbuf input logic store_stbuf_reqvld_dc3, // core instruction goes to stbuf - //input logic ldst_stbuf_reqvld_dc3, + //input logic ldst_stbuf_reqvld_dc3, input logic addr_in_pic_dc2, // address is in pic input logic addr_in_pic_dc3, // address is in pic input logic addr_in_dccm_dc2, // address is in pic @@ -61,14 +61,14 @@ module lsu_stbuf input logic isldst_dc1, // instruction in dc1 is lsu input logic dccm_ldst_dc2, // instruction in dc2 is lsu input logic dccm_ldst_dc3, // instruction in dc3 is lsu - + input logic single_ecc_error_hi_dc3, // single ecc error in hi bank input logic single_ecc_error_lo_dc3, // single ecc error in lo bank input logic lsu_single_ecc_error_dc5, // single_ecc_error in either bank staged to the dc5 - needed for the load repairs input logic lsu_commit_dc5, // lsu commits input logic lsu_freeze_dc3, // lsu freeze input logic flush_prior_dc5, // Flush is due to i0 and ld/st is in i1 - + // Store Buffer output output logic stbuf_reqvld_any, // stbuf is draining output logic stbuf_reqvld_flushed_any, // Top entry is flushed @@ -81,43 +81,44 @@ module lsu_stbuf output logic lsu_stbuf_full_any, // stbuf is full output logic lsu_stbuf_empty_any, // stbuf is empty output logic lsu_stbuf_nodma_empty_any, // stbuf is empty except dma - + output logic lsu_load_ecc_stbuf_full_dc3, // Load with ecc error can't allocate to stbuf + input logic [`RV_LSU_SB_BITS-1:0] lsu_addr_dc1, // lsu address input logic [`RV_LSU_SB_BITS-1:0] lsu_addr_dc2, input logic [`RV_LSU_SB_BITS-1:0] lsu_addr_dc3, - + input logic [`RV_LSU_SB_BITS-1:0] end_addr_dc1, // lsu end addrress - needed to check unaligned input logic [`RV_LSU_SB_BITS-1:0] end_addr_dc2, input logic [`RV_LSU_SB_BITS-1:0] end_addr_dc3, - + // Forwarding signals input logic lsu_cmpen_dc2, // needed for forwarding stbuf - load input lsu_pkt_t lsu_pkt_dc2, - input lsu_pkt_t lsu_pkt_dc3, - input lsu_pkt_t lsu_pkt_dc5, - + input lsu_pkt_t lsu_pkt_dc3, + input lsu_pkt_t lsu_pkt_dc5, + output logic [`RV_DCCM_DATA_WIDTH-1:0] stbuf_fwddata_hi_dc3, // stbuf data output logic [`RV_DCCM_DATA_WIDTH-1:0] stbuf_fwddata_lo_dc3, output logic [`RV_DCCM_BYTE_WIDTH-1:0] stbuf_fwdbyteen_hi_dc3, output logic [`RV_DCCM_BYTE_WIDTH-1:0] stbuf_fwdbyteen_lo_dc3, - - input logic scan_mode - + + input logic scan_mode + ); `include "global.h" - + localparam DEPTH = LSU_STBUF_DEPTH; localparam DATA_WIDTH = DCCM_DATA_WIDTH; localparam BYTE_WIDTH = DCCM_BYTE_WIDTH; localparam DEPTH_LOG2 = $clog2(DEPTH); - + logic [DEPTH-1:0] stbuf_data_vld; logic [DEPTH-1:0] stbuf_drain_vld; logic [DEPTH-1:0] stbuf_flush_vld; logic [DEPTH-1:0] stbuf_addr_in_pic; logic [DEPTH-1:0] stbuf_dma; - logic [DEPTH-1:0][LSU_SB_BITS-1:0] stbuf_addr; + logic [DEPTH-1:0][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; @@ -131,16 +132,16 @@ module lsu_stbuf logic [DEPTH-1:0][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] ldst_byteen_dc3; logic [7:0] store_byteen_ext_dc3; logic [BYTE_WIDTH-1:0] store_byteen_hi_dc3; logic [BYTE_WIDTH-1:0] store_byteen_lo_dc3; - logic ldst_stbuf_reqvld_dc3; + logic ldst_stbuf_reqvld_dc3; logic dual_ecc_error_dc3; logic dual_stbuf_write_dc3; - + logic WrPtrEn, RdPtrEn; logic [DEPTH_LOG2-1:0] WrPtr, RdPtr; logic [DEPTH_LOG2-1:0] NxtWrPtr, NxtRdPtr; @@ -149,13 +150,13 @@ module lsu_stbuf logic ldst_dual_dc1, ldst_dual_dc2, ldst_dual_dc3, ldst_dual_dc4, ldst_dual_dc5; logic ldst_stbuf_reqvld_dc4, ldst_stbuf_reqvld_dc5; logic dual_stbuf_write_dc4, dual_stbuf_write_dc5; - + logic [3:0] stbuf_numvld_any, stbuf_specvld_any; logic [1:0] stbuf_specvld_dc1, stbuf_specvld_dc2, stbuf_specvld_dc3; logic stbuf_oneavl_any, stbuf_twoavl_any; - + logic cmpen_hi_dc2, cmpen_lo_dc2, jit_in_same_region; - + logic [LSU_SB_BITS-1:$clog2(BYTE_WIDTH)] cmpaddr_hi_dc2, cmpaddr_lo_dc2; logic stbuf_ldmatch_hi_hi, stbuf_ldmatch_hi_lo; @@ -164,7 +165,7 @@ module lsu_stbuf logic [BYTE_WIDTH-1:0] stbuf_fwdbyteen_lo_hi, stbuf_fwdbyteen_lo_lo; logic [DATA_WIDTH-1:0] stbuf_fwddata_hi_hi, stbuf_fwddata_hi_lo; logic [DATA_WIDTH-1:0] stbuf_fwddata_lo_hi, stbuf_fwddata_lo_lo; - + logic [DEPTH-1:0] stbuf_ldmatch_hi, stbuf_ldmatch_lo; logic [DEPTH-1:0][BYTE_WIDTH-1:0] stbuf_fwdbyteenvec_hi, stbuf_fwdbyteenvec_lo; logic [DEPTH-1:0][DATA_WIDTH-1:0] stbuf_fwddatavec_hi, stbuf_fwddatavec_lo; @@ -205,8 +206,8 @@ module lsu_stbuf assign stbuf_data_en[i] = stbuf_wr_en[i]; assign stbuf_drain_or_flush_en[i] = ldst_stbuf_reqvld_dc5 & ~lsu_pkt_dc5.dma & ((i == WrPtr_dc5[DEPTH_LOG2-1:0]) | (i == WrPtrPlus1_dc5[DEPTH_LOG2-1:0] & dual_stbuf_write_dc5)); - assign stbuf_drain_en[i] = (stbuf_drain_or_flush_en[i] & (lsu_commit_dc5 | stbuf_load_repair_dc5)) | (stbuf_wr_en[i] & lsu_pkt_dc3.dma); - assign stbuf_flush_en[i] = stbuf_drain_or_flush_en[i] & ~(lsu_commit_dc5 | stbuf_load_repair_dc5); + assign stbuf_drain_en[i] = (stbuf_drain_or_flush_en[i] & lsu_commit_dc5) | (stbuf_wr_en[i] & lsu_pkt_dc3.dma); + assign stbuf_flush_en[i] = stbuf_drain_or_flush_en[i] & ~lsu_commit_dc5; assign stbuf_reset[i] = (lsu_stbuf_commit_any | stbuf_reqvld_flushed_any) & (i == RdPtr[DEPTH_LOG2-1:0]); // Mux select for start/end address @@ -214,7 +215,7 @@ module lsu_stbuf assign stbuf_addrin[i][LSU_SB_BITS-1:0] = sel_lo[i] ? lsu_addr_dc3[LSU_SB_BITS-1:0] : end_addr_dc3[LSU_SB_BITS-1:0]; assign stbuf_byteenin[i][BYTE_WIDTH-1:0] = sel_lo[i] ? store_byteen_lo_dc3[BYTE_WIDTH-1:0] : store_byteen_hi_dc3[BYTE_WIDTH-1:0]; assign stbuf_datain[i][DATA_WIDTH-1:0] = sel_lo[i] ? store_ecc_datafn_lo_dc3[DATA_WIDTH-1:0] : store_ecc_datafn_hi_dc3[DATA_WIDTH-1:0]; - + rvdffsc #(.WIDTH(1)) stbuf_data_vldff (.din(1'b1), .dout(stbuf_data_vld[i]), .en(stbuf_wr_en[i]), .clear(stbuf_reset[i]), .clk(lsu_stbuf_c1_clk), .*); rvdffsc #(.WIDTH(1)) stbuf_drain_vldff (.din(1'b1), .dout(stbuf_drain_vld[i]), .en(stbuf_drain_en[i]), .clear(stbuf_reset[i]), .clk(lsu_free_c2_clk), .*); rvdffsc #(.WIDTH(1)) stbuf_flush_vldff (.din(1'b1), .dout(stbuf_flush_vld[i]), .en(stbuf_flush_en[i]), .clear(stbuf_reset[i]), .clk(lsu_free_c2_clk), .*); @@ -274,7 +275,8 @@ module lsu_stbuf assign lsu_stbuf_full_any = (stbuf_specvld_any[3:0] > (DEPTH - 2)); assign lsu_stbuf_empty_any = (stbuf_numvld_any[3:0] == 4'b0); assign lsu_stbuf_nodma_empty_any = ~(|(stbuf_data_vld[DEPTH-1:0] & ~stbuf_dma[DEPTH-1:0])); - + assign lsu_load_ecc_stbuf_full_dc3 = load_stbuf_reqvld_dc3 & ~ldst_stbuf_reqvld_dc3; + assign stbuf_oneavl_any = (stbuf_numvld_any[3:0] < DEPTH); assign stbuf_twoavl_any = (stbuf_numvld_any[3:0] < (DEPTH - 1)); @@ -285,7 +287,7 @@ module lsu_stbuf assign cmpen_lo_dc2 = lsu_cmpen_dc2; assign cmpaddr_lo_dc2[LSU_SB_BITS-1:$clog2(BYTE_WIDTH)] = lsu_addr_dc2[LSU_SB_BITS-1:$clog2(BYTE_WIDTH)]; assign jit_in_same_region = (addr_in_pic_dc2 & addr_in_pic_dc3) | (addr_in_dccm_dc2 & addr_in_dccm_dc3); - + // JIT forwarding assign stbuf_ldmatch_hi_hi = (end_addr_dc3[LSU_SB_BITS-1:$clog2(BYTE_WIDTH)] == cmpaddr_hi_dc2[LSU_SB_BITS-1:$clog2(BYTE_WIDTH)]) & ~(cmpen_hi_dc2 & lsu_pkt_dc2.dma & ~lsu_pkt_dc3.dma) & jit_in_same_region; assign stbuf_ldmatch_hi_lo = (lsu_addr_dc3[LSU_SB_BITS-1:$clog2(BYTE_WIDTH)] == cmpaddr_hi_dc2[LSU_SB_BITS-1:$clog2(BYTE_WIDTH)]) & ~(cmpen_hi_dc2 & lsu_pkt_dc2.dma & ~lsu_pkt_dc3.dma) & jit_in_same_region; @@ -297,27 +299,27 @@ module lsu_stbuf assign stbuf_fwdbyteen_hi_lo[i] = stbuf_ldmatch_hi_lo & store_byteen_lo_dc3[i] & ldst_stbuf_reqvld_dc3; assign stbuf_fwdbyteen_lo_hi[i] = stbuf_ldmatch_lo_hi & store_byteen_hi_dc3[i] & ldst_stbuf_reqvld_dc3 & dual_stbuf_write_dc3; assign stbuf_fwdbyteen_lo_lo[i] = stbuf_ldmatch_lo_lo & store_byteen_lo_dc3[i] & ldst_stbuf_reqvld_dc3; - + assign stbuf_fwddata_hi_hi[(8*i)+7:(8*i)] = {8{stbuf_fwdbyteen_hi_hi[i]}} & store_ecc_datafn_hi_dc3[(8*i)+7:(8*i)]; assign stbuf_fwddata_hi_lo[(8*i)+7:(8*i)] = {8{stbuf_fwdbyteen_hi_lo[i]}} & store_ecc_datafn_lo_dc3[(8*i)+7:(8*i)]; assign stbuf_fwddata_lo_hi[(8*i)+7:(8*i)] = {8{stbuf_fwdbyteen_lo_hi[i]}} & store_ecc_datafn_hi_dc3[(8*i)+7:(8*i)]; assign stbuf_fwddata_lo_lo[(8*i)+7:(8*i)] = {8{stbuf_fwdbyteen_lo_lo[i]}} & store_ecc_datafn_lo_dc3[(8*i)+7:(8*i)]; end - + always_comb begin: GenLdFwd stbuf_fwdbyteen_hi_dc2[BYTE_WIDTH-1:0] = '0; stbuf_fwdbyteen_lo_dc2[BYTE_WIDTH-1:0] = '0; for (int i=0; i ##2 (lsu_commit_dc5 == 1'b0); + endproperty + assert_ldecc_stbuffull_commit: assert property (ldecc_stbuffull_commit) else + $display("load with ecc error committed with store buffer full"); `endif - + endmodule - + diff --git a/design/lsu/lsu_trigger.sv b/design/lsu/lsu_trigger.sv index 0868497..67eb7de 100644 --- a/design/lsu/lsu_trigger.sv +++ b/design/lsu/lsu_trigger.sv @@ -1,12 +1,12 @@ // 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. @@ -16,13 +16,13 @@ //******************************************************************************** // $Id$ // -// -// Owner: +// +// Owner: // Function: LSU Trigger logic // Comments: // //******************************************************************************** -module lsu_trigger +module lsu_trigger import swerv_types::*; ( input logic clk, // clock @@ -31,7 +31,7 @@ module lsu_trigger input trigger_pkt_t [3:0] trigger_pkt_any, // trigger packet from dec input lsu_pkt_t lsu_pkt_dc3, // lsu packet - input logic [31:0] lsu_addr_dc3, // address + input logic [31:0] lsu_addr_dc3, // address input logic [31:0] lsu_result_dc3, // load data input logic [31:0] store_data_dc3, // store data @@ -43,13 +43,13 @@ module lsu_trigger logic [31:0] store_data_trigger_dc3; assign store_data_trigger_dc3[31:0] = { ({16{lsu_pkt_dc3.word}} & store_data_dc3[31:16]) , ({8{(lsu_pkt_dc3.half | lsu_pkt_dc3.word)}} & store_data_dc3[15:8]), store_data_dc3[7:0]}; - - + + for (genvar i=0; i<4; i++) begin assign lsu_match_data[i][31:0] = ({32{~trigger_pkt_any[i].select}} & lsu_addr_dc3[31:0]) | ({32{trigger_pkt_any[i].select & trigger_pkt_any[i].store}} & store_data_trigger_dc3[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_dc3[i] = lsu_pkt_dc3.valid & ~lsu_pkt_dc3.dma & @@ -57,5 +57,5 @@ module lsu_trigger lsu_trigger_data_match[i]; end - + endmodule // lsu_trigger diff --git a/design/mem.sv b/design/mem.sv index 8e31380..f406c31 100644 --- a/design/mem.sv +++ b/design/mem.sv @@ -15,7 +15,7 @@ // limitations under the License. //******************************************************************************** -module mem +module mem import swerv_types::*; ( input logic clk, @@ -23,8 +23,8 @@ module mem input logic lsu_freeze_dc3, input logic dccm_clk_override, input logic icm_clk_override, - input logic dec_tlu_core_ecc_disable, - + input logic dec_tlu_core_ecc_disable, + //DCCM ports input logic dccm_wren, input logic dccm_rden, @@ -45,7 +45,7 @@ module mem input logic iccm_rden, input logic [2:0] iccm_wr_size, input logic [77:0] iccm_wr_data, - + output logic [155:0] iccm_rd_data, `endif // Icache and Itag Ports @@ -54,44 +54,44 @@ module mem input logic [3:0] ic_tag_valid, input logic [3:0] ic_wr_en, input logic ic_rd_en, - input logic [127: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 [127:0] ic_premux_data, // Premux data to be muxed with each way of the Icache. + input logic ic_sel_premux_data, // Premux data sel `ifdef RV_ICACHE_ECC input logic [83:0] ic_wr_data, // Data to fill to the Icache. With ECC - input logic [41:0] ic_debug_wr_data, // Debug wr cache. -`else + input logic [41:0] ic_debug_wr_data, // Debug wr cache. +`else input logic [67:0] ic_wr_data, // Data to fill to the Icache. With Parity - input logic [33:0] ic_debug_wr_data, // Debug wr cache. + input logic [33:0] ic_debug_wr_data, // Debug wr cache. `endif - input logic [15:2] ic_debug_addr, // Read/Write addresss to the Icache. + input logic [15:2] 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 [3:0] ic_debug_way, // Debug way. Rd or Wr. `endif - + `ifdef RV_ICACHE_ECC output logic [167:0] ic_rd_data , // Data read from Icache. 2x64bits + parity bits. F2 stage. With ECC - output logic [24:0] ictag_debug_rd_data,// Debug icache tag. -`else + output logic [24:0] ictag_debug_rd_data,// Debug icache tag. +`else output logic [135:0] ic_rd_data , // Data read from Icache. 2x64bits + parity bits. F2 stage. With Parity - output logic [20:0] ictag_debug_rd_data,// Debug icache tag. + output logic [20:0] ictag_debug_rd_data,// Debug icache tag. `endif output logic [3:0] ic_rd_hit, output logic ic_tag_perr, // Icache Tag parity error - - input logic scan_mode - + + input logic scan_mode + ); `include "global.h" - + `ifdef RV_DCCM_ENABLE localparam DCCM_ENABLE = 1'b1; `else @@ -108,8 +108,8 @@ module mem assign dccm_rd_data_lo = '0; assign dccm_rd_data_hi = '0; end - -`ifdef RV_ICACHE_ENABLE + +`ifdef RV_ICACHE_ENABLE ifu_ic_mem icm ( .clk_override(icm_clk_override), .* @@ -128,5 +128,5 @@ module mem .iccm_rd_data(iccm_rd_data[155:0]) ); `endif - + endmodule diff --git a/design/pic_ctrl.sv b/design/pic_ctrl.sv index bf0c16c..fb033f6 100644 --- a/design/pic_ctrl.sv +++ b/design/pic_ctrl.sv @@ -16,8 +16,8 @@ //******************************************************************************** //******************************************************************************** -// Function: Programmable Interrupt Controller -// Comments: +// Function: Programmable Interrupt Controller +// Comments: //******************************************************************************** module pic_ctrl @@ -43,10 +43,10 @@ module pic_ctrl output logic [31:0] picm_rd_data, // Read data of the register output logic mhwakeup, // Wake-up interrupt request input logic scan_mode // scan mode - + ); `include "global.h" - + localparam NUM_LEVELS = $clog2(TOTAL_INT); localparam INTPRIORITY_BASE_ADDR = `RV_PIC_BASE_ADDR ; localparam INTPEND_BASE_ADDR = `RV_PIC_BASE_ADDR + 32'h00001000 ; @@ -55,21 +55,21 @@ localparam EXT_INTR_PIC_CONFIG = `RV_PIC_BASE_ADDR + 32'h00003000 ; localparam EXT_INTR_GW_CONFIG = `RV_PIC_BASE_ADDR + 32'h00004000 ; localparam EXT_INTR_GW_CLEAR = `RV_PIC_BASE_ADDR + 32'h00005000 ; - -localparam INTPEND_SIZE = (TOTAL_INT < 32) ? 32 : + +localparam INTPEND_SIZE = (TOTAL_INT < 32) ? 32 : (TOTAL_INT < 64) ? 64 : (TOTAL_INT < 128) ? 128 : - (TOTAL_INT < 256) ? 256 : + (TOTAL_INT < 256) ? 256 : (TOTAL_INT < 512) ? 512 : 1024 ; localparam INT_GRPS = INTPEND_SIZE / 32 ; localparam INTPRIORITY_BITS = 4 ; localparam ID_BITS = 8 ; -localparam int GW_CONFIG[TOTAL_INT-1:0] = '{default:0} ; +localparam int GW_CONFIG[TOTAL_INT-1:0] = '{default:0} ; -logic addr_intpend_base_match; -logic addr_intenable_base_match; -logic addr_intpriority_base_match; +logic addr_intpend_base_match; +logic addr_intenable_base_match; +logic addr_intpriority_base_match; logic addr_config_pic_match ; logic addr_config_gw_base_match ; logic addr_clear_gw_base_match ; @@ -105,7 +105,7 @@ logic [INT_GRPS-1:0] [31:0] intpend_rd_part_out ; logic config_reg; logic intpriord; -logic config_reg_we ; +logic config_reg_we ; logic config_reg_re ; logic config_reg_in ; logic prithresh_reg_write , prithresh_reg_read; @@ -117,9 +117,9 @@ logic [31:0] picm_addr_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 [ID_BITS-1:0] claimid_in ; +logic [INTPRIORITY_BITS-1:0] pl_in ; +logic [INTPRIORITY_BITS-1:0] pl_in_q ; logic [TOTAL_INT-1:0] extintsrc_req_sync; logic [TOTAL_INT-1:0] extintsrc_req_gw; @@ -130,7 +130,7 @@ logic [TOTAL_INT-1:0] extintsrc_req_gw; logic pic_pri_c1_clken; logic pic_int_c1_clken; logic gw_config_c1_clken; - + // clocks logic pic_addr_c1_clk; logic pic_data_c1_clk; @@ -145,16 +145,16 @@ logic [TOTAL_INT-1:0] extintsrc_req_gw; assign pic_pri_c1_clken = (addr_intpriority_base_match & (picm_wren_ff | picm_rden_ff)) | clk_override; assign pic_int_c1_clken = (addr_intenable_base_match & (picm_wren_ff | picm_rden_ff)) | clk_override; assign gw_config_c1_clken = (addr_config_gw_base_match & (picm_wren_ff | picm_rden_ff)) | clk_override; - - // C1 - 1 clock pulse for data + + // C1 - 1 clock pulse for data rvoclkhdr pic_addr_c1_cgc ( .en(pic_addr_c1_clken), .l1clk(pic_addr_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 addr_intpend_base_match = (picm_addr_ff[31:6] == INTPEND_BASE_ADDR[31:6]) ; assign addr_intenable_base_match = (picm_addr_ff[31:NUM_LEVELS+2] == INTENABLE_BASE_ADDR[31:NUM_LEVELS+2]) ; assign addr_intpriority_base_match = (picm_addr_ff[31:NUM_LEVELS+2] == INTPRIORITY_BASE_ADDR[31:NUM_LEVELS+2]) ; @@ -170,16 +170,16 @@ rvdff #(1) picm_rde_flop (.*, .din (picm_rden), rvdff #(1) picm_mke_flop (.*, .din (picm_mken), .dout(picm_mken_ff), .clk(active_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 #(TOTAL_INT-1) sync_inst +rvsyncss #(TOTAL_INT-1) sync_inst ( .clk (free_clk), .dout(extintsrc_req_sync[TOTAL_INT-1:1]), - .din (extintsrc_req[TOTAL_INT-1:1]), + .din (extintsrc_req[TOTAL_INT-1:1]), .*) ; - + assign extintsrc_req_sync[0] = extintsrc_req[0]; -genvar i ; +genvar i, l, m , j, k; for (i=0; i 0 ) begin : NON_ZERO_INT @@ -206,21 +206,21 @@ for (i=0; i meipt_inv[INTPRIORITY_BITS-1:0]) & +assign mexintpend_in = (( selected_int_priority[INTPRIORITY_BITS-1:0] > 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)); @@ -394,18 +382,18 @@ rvdff #(1) wake_up_ff (.*, .clk(free_clk), .din (mhwakeup_in), .dout(mhwakeup)) // assign atleast_one_int_enabled_in = |intenable_reg[TOTAL_INT-1:0] ; // rvdff #(1) one_int_en_ff (.*, .din (atleast_one_int_enabled_in), .dout(atleast_one_int_enabled)); -// +// // assign mexintpend = mexintpend_unq & atleast_one_int_enabled ; // assign mhwakeup = mhwakeup_unq & atleast_one_int_enabled ; ////////////////////////////////////////////////////////////////////////// -// Reads of register. +// Reads of register. // 1- intpending ////////////////////////////////////////////////////////////////////////// -assign intpend_reg_read = addr_intpend_base_match & picm_rden_ff ; +assign intpend_reg_read = addr_intpend_base_match & picm_rden_ff ; assign intpriority_reg_read = addr_intpriority_base_match & picm_rden_ff; assign intenable_reg_read = addr_intenable_base_match & picm_rden_ff; assign gw_config_reg_read = addr_config_gw_base_match & picm_rden_ff; @@ -416,14 +404,14 @@ assign intpend_reg_extended[INTPEND_SIZE-1:0] = {{INTPEND_SIZE-TOTAL_INT{1'b0}} assign intpend_rd_part_out[i] = (({32{intpend_reg_read & picm_addr_ff[5:2] == i}}) & intpend_reg_extended[((32*i)+31):(32*i)]) ; end - always_comb begin : INTPEND_RD + always_comb begin : INTPEND_RD intpend_rd_out = '0 ; for (int i=0; i AHB Gasket for LSU axi4_to_ahb #(.TAG(LSU_BUS_TAG)) lsu_axi4_to_ahb ( .clk_override(dec_tlu_bus_clk_override), - .bus_clk_en(lsu_bus_clk_en), + .bus_clk_en(lsu_bus_clk_en), // AXI Write Channels .axi_awvalid(lsu_axi_awvalid), @@ -1042,13 +1044,13 @@ module swerv .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_wvalid(lsu_axi_wvalid), .axi_wready(lsu_axi_wready), .axi_wdata(lsu_axi_wdata[63:0]), .axi_wstrb(lsu_axi_wstrb[7:0]), .axi_wlast(lsu_axi_wlast), - + .axi_bvalid(lsu_axi_bvalid), .axi_bready(lsu_axi_bready), .axi_bresp(lsu_axi_bresp[1:0]), @@ -1058,10 +1060,10 @@ module swerv .axi_arvalid(lsu_axi_arvalid), .axi_arready(lsu_axi_arready), .axi_arid(lsu_axi_arid[LSU_BUS_TAG-1:0]), - .axi_araddr(lsu_axi_araddr[31: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), .axi_rready(lsu_axi_rready), .axi_rid(lsu_axi_rid[LSU_BUS_TAG-1:0]), @@ -1081,14 +1083,14 @@ module swerv .ahb_hrdata(lsu_hrdata[63:0]), .ahb_hready(lsu_hready), .ahb_hresp(lsu_hresp), - + .* ); // AXI4 -> AHB Gasket for System Bus axi4_to_ahb #(.TAG(SB_BUS_TAG)) sb_axi4_to_ahb ( .clk_override(dec_tlu_bus_clk_override), - .bus_clk_en(dbg_bus_clk_en), + .bus_clk_en(dbg_bus_clk_en), // AXI Write Channels .axi_awvalid(sb_axi_awvalid), @@ -1097,13 +1099,13 @@ module swerv .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_wvalid(sb_axi_wvalid), .axi_wready(sb_axi_wready), .axi_wdata(sb_axi_wdata[63:0]), .axi_wstrb(sb_axi_wstrb[7:0]), .axi_wlast(sb_axi_wlast), - + .axi_bvalid(sb_axi_bvalid), .axi_bready(sb_axi_bready), .axi_bresp(sb_axi_bresp[1:0]), @@ -1113,10 +1115,10 @@ module swerv .axi_arvalid(sb_axi_arvalid), .axi_arready(sb_axi_arready), .axi_arid(sb_axi_arid[SB_BUS_TAG-1:0]), - .axi_araddr(sb_axi_araddr[31: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), .axi_rready(sb_axi_rready), .axi_rid(sb_axi_rid[SB_BUS_TAG-1:0]), @@ -1136,7 +1138,7 @@ module swerv .ahb_hrdata(sb_hrdata[63:0]), .ahb_hready(sb_hready), .ahb_hresp(sb_hresp), - + .* ); @@ -1144,8 +1146,8 @@ module swerv .clk(clk), .clk_override(dec_tlu_bus_clk_override), .bus_clk_en(ifu_bus_clk_en), - - // AHB-Lite signals + + // AHB-Lite signals .ahb_haddr(haddr[31:0]), .ahb_hburst(hburst), .ahb_hmastlock(hmastlock), @@ -1158,7 +1160,7 @@ module swerv .ahb_hrdata(hrdata[63:0]), .ahb_hready(hready), .ahb_hresp(hresp), - + // AXI Write Channels .axi_awvalid(ifu_axi_awvalid), .axi_awready(ifu_axi_awready), @@ -1166,13 +1168,13 @@ module swerv .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_wvalid(ifu_axi_wvalid), .axi_wready(ifu_axi_wready), .axi_wdata(ifu_axi_wdata[63:0]), .axi_wstrb(ifu_axi_wstrb[7:0]), .axi_wlast(ifu_axi_wlast), - + .axi_bvalid(ifu_axi_bvalid), .axi_bready(ifu_axi_bready), .axi_bresp(ifu_axi_bresp[1:0]), @@ -1182,10 +1184,10 @@ module swerv .axi_arvalid(ifu_axi_arvalid), .axi_arready(ifu_axi_arready), .axi_arid(ifu_axi_arid[IFU_BUS_TAG-1:0]), - .axi_araddr(ifu_axi_araddr[31: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), .axi_rready(ifu_axi_rready), .axi_rid(ifu_axi_rid[IFU_BUS_TAG-1:0]), @@ -1194,7 +1196,7 @@ module swerv .axi_rlast(ifu_axi_rlast), .* ); - + //AHB -> AXI4 Gasket for DMA ahb_to_axi4 #(.TAG(DMA_BUS_TAG)) dma_ahb_to_axi4 ( .clk_override(dec_tlu_bus_clk_override), @@ -1207,35 +1209,35 @@ module swerv .axi_awaddr(dma_axi_awaddr[31:0]), .axi_awsize(dma_axi_awsize[2:0]), .axi_awprot(dma_axi_awprot[2:0]), - .axi_awlen(dma_axi_awlen[7:0]), + .axi_awlen(dma_axi_awlen[7:0]), .axi_awburst(dma_axi_awburst[1:0]), - - .axi_wvalid(dma_axi_wvalid), + + .axi_wvalid(dma_axi_wvalid), .axi_wready(dma_axi_wready), .axi_wdata(dma_axi_wdata[63:0]), .axi_wstrb(dma_axi_wstrb[7:0]), .axi_wlast(dma_axi_wlast), - + .axi_bvalid(dma_axi_bvalid), .axi_bready(dma_axi_bready), .axi_bresp(dma_axi_bresp[1:0]), - .axi_bid(dma_axi_bid[DMA_BUS_TAG-1:0]), - + .axi_bid(dma_axi_bid[DMA_BUS_TAG-1:0]), + // AXI Read Channels .axi_arvalid(dma_axi_arvalid), .axi_arready(dma_axi_arready), .axi_arid(dma_axi_arid[DMA_BUS_TAG-1:0]), - .axi_araddr(dma_axi_araddr[31:0]), + .axi_araddr(dma_axi_araddr[31:0]), .axi_arsize(dma_axi_arsize[2:0]), .axi_arprot(dma_axi_arprot[2:0]), - .axi_arlen(dma_axi_arlen[7:0]), + .axi_arlen(dma_axi_arlen[7:0]), .axi_arburst(dma_axi_arburst[1:0]), - + .axi_rvalid(dma_axi_rvalid), .axi_rready(dma_axi_rready), .axi_rid(dma_axi_rid[DMA_BUS_TAG-1:0]), .axi_rdata(dma_axi_rdata[63:0]), - .axi_rresp(dma_axi_rresp[1:0]), + .axi_rresp(dma_axi_rresp[1:0]), // AHB signals .ahb_haddr(dma_haddr[31:0]), @@ -1249,7 +1251,7 @@ module swerv .ahb_hrdata(dma_hrdata[63:0]), .ahb_hreadyout(dma_hreadyout), - .ahb_hresp(dma_hresp), + .ahb_hresp(dma_hresp), .ahb_hreadyin(dma_hreadyin), .ahb_hsel(dma_hsel), .* @@ -1266,7 +1268,7 @@ module swerv ((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 + 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; @@ -1275,7 +1277,7 @@ module swerv ((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 - //assert_dma_trxn_aligned: assert property (dma_trxn_aligned) else + //assert_dma_trxn_aligned: assert property (dma_trxn_aligned) else // $display("Assertion dma_trxn_aligned failed: dma_htrans=2'h%h, dma_hsize=3'h%h, dma_haddr=32'h%h",dma_htrans[1:0], dma_hsize[2:0], dma_haddr[31:0]); `endif @@ -1284,32 +1286,33 @@ module swerv // unpack packet // also need retires_p==3 - + assign trace_rv_i_insn_ip[63:0] = trace_rv_trace_pkt.trace_rv_i_insn_ip[63:0]; - + assign trace_rv_i_address_ip[63:0] = trace_rv_trace_pkt.trace_rv_i_address_ip[63:0]; - + assign trace_rv_i_valid_ip[2:0] = trace_rv_trace_pkt.trace_rv_i_valid_ip[2:0]; - + assign trace_rv_i_exception_ip[2:0] = trace_rv_trace_pkt.trace_rv_i_exception_ip[2:0]; - + 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[2:0] = trace_rv_trace_pkt.trace_rv_i_interrupt_ip[2:0]; - + assign trace_rv_i_tval_ip[31:0] = trace_rv_trace_pkt.trace_rv_i_tval_ip[31:0]; // constants should be hooked up at platform level // trace_rv_i_context_ip = '0; // trace_rv_i_privilege_ip = {3{4'b0011}}; - // trace_rv_i_status_ip = '0; + // trace_rv_i_status_ip = '0; // trace_rv_i_user_ip = '0; // trace_rv_halted_ip = o_cpu_halt_status; hook this up at platform level - - - + + + endmodule // swerv + diff --git a/design/swerv_wrapper.sv b/design/swerv_wrapper.sv index 712afd9..e49361f 100644 --- a/design/swerv_wrapper.sv +++ b/design/swerv_wrapper.sv @@ -1,12 +1,12 @@ // 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. @@ -17,21 +17,22 @@ // $Id$ // // Function: Top wrapper file with swerv/mem instantiated inside -// Comments: +// Comments: // //******************************************************************************** `include "build.h" //`include "def.sv" -module swerv_wrapper +module swerv_wrapper import swerv_types::*; ( input logic clk, input logic rst_l, + input logic dbg_rst_l, input logic [31:1] rst_vec, input logic nmi_int, - input logic [31:1] nmi_vec, + input logic [31:1] nmi_vec, input logic [31:1] jtag_id, - + output logic [63:0] trace_rv_i_insn_ip, output logic [63:0] trace_rv_i_address_ip, @@ -58,19 +59,19 @@ module swerv_wrapper output logic [3:0] lsu_axi_awcache, output logic [2:0] lsu_axi_awprot, output logic [3:0] lsu_axi_awqos, - - output logic lsu_axi_wvalid, + + 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, output logic lsu_axi_bready, input logic [1:0] lsu_axi_bresp, input logic [`RV_LSU_BUS_TAG-1:0] lsu_axi_bid, - - // AXI Read Channels + + // AXI Read Channels output logic lsu_axi_arvalid, input logic lsu_axi_arready, output logic [`RV_LSU_BUS_TAG-1:0] lsu_axi_arid, @@ -83,14 +84,14 @@ module swerv_wrapper output logic [3:0] lsu_axi_arcache, output logic [2:0] lsu_axi_arprot, output logic [3:0] lsu_axi_arqos, - + input logic lsu_axi_rvalid, output logic lsu_axi_rready, input logic [`RV_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 output logic ifu_axi_awvalid, @@ -105,19 +106,19 @@ module swerv_wrapper 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 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 [`RV_IFU_BUS_TAG-1:0] ifu_axi_bid, - - // AXI Read Channels + + // AXI Read Channels output logic ifu_axi_arvalid, input logic ifu_axi_arready, output logic [`RV_IFU_BUS_TAG-1:0] ifu_axi_arid, @@ -130,7 +131,7 @@ module swerv_wrapper output logic [3:0] ifu_axi_arcache, output logic [2:0] ifu_axi_arprot, output logic [3:0] ifu_axi_arqos, - + input logic ifu_axi_rvalid, output logic ifu_axi_rready, input logic [`RV_IFU_BUS_TAG-1:0] ifu_axi_rid, @@ -152,19 +153,19 @@ module swerv_wrapper output logic [3:0] sb_axi_awcache, output logic [2:0] sb_axi_awprot, output logic [3:0] sb_axi_awqos, - - output logic sb_axi_wvalid, + + 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 [`RV_SB_BUS_TAG-1:0] sb_axi_bid, - - // AXI Read Channels + + // AXI Read Channels output logic sb_axi_arvalid, input logic sb_axi_arready, output logic [`RV_SB_BUS_TAG-1:0] sb_axi_arid, @@ -177,7 +178,7 @@ module swerv_wrapper output logic [3:0] sb_axi_arcache, output logic [2:0] sb_axi_arprot, output logic [3:0] sb_axi_arqos, - + input logic sb_axi_rvalid, output logic sb_axi_rready, input logic [`RV_SB_BUS_TAG-1:0] sb_axi_rid, @@ -197,12 +198,12 @@ module swerv_wrapper input logic [1:0] dma_axi_awburst, - input logic dma_axi_wvalid, + 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, @@ -212,7 +213,7 @@ module swerv_wrapper input logic dma_axi_arvalid, output logic dma_axi_arready, input logic [`RV_DMA_BUS_TAG-1:0] dma_axi_arid, - input logic [31:0] dma_axi_araddr, + 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, @@ -223,8 +224,8 @@ module swerv_wrapper output logic [`RV_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, - + output logic dma_axi_rlast, + `endif `ifdef RV_BUILD_AHB_LITE @@ -263,11 +264,11 @@ module swerv_wrapper 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 [31:0] dma_haddr, input logic [2:0] dma_hburst, @@ -278,8 +279,8 @@ module swerv_wrapper input logic dma_hwrite, input logic [63:0] dma_hwdata, input logic dma_hsel, - input logic dma_hreadyin, - + input logic dma_hreadyin, + output logic [63:0] dma_hrdata, output logic dma_hreadyout, output logic dma_hresp, @@ -291,9 +292,9 @@ module swerv_wrapper 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 + input logic dma_bus_clk_en, // Clock ratio b/w cpu core clk & AHB slave interface + - // input logic ext_int, input logic timer_int, input logic [`RV_PIC_TOTAL_INT:1] extintsrc_req, @@ -303,9 +304,9 @@ module swerv_wrapper output logic [1:0] dec_tlu_perfcnt2, output logic [1:0] dec_tlu_perfcnt3, - // ports added by the soc team + // ports added by the soc team input logic jtag_tck, // JTAG clk - input logic jtag_tms, // JTAG TMS + 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 @@ -324,10 +325,10 @@ module swerv_wrapper input logic i_cpu_run_req, // Async restart req to CPU output logic o_cpu_run_ack, // Core response to run req input logic scan_mode, // To enable scan mode - input logic mbist_mode // to enable mbist + input logic mbist_mode // to enable mbist ); -`include "global.h" +`include "global.h" // DCCM ports logic dccm_wren; @@ -336,7 +337,7 @@ module swerv_wrapper logic [DCCM_BITS-1:0] dccm_rd_addr_lo; logic [DCCM_BITS-1:0] dccm_rd_addr_hi; logic [DCCM_FDATA_WIDTH-1:0] dccm_wr_data; - + logic [DCCM_FDATA_WIDTH-1:0] dccm_rd_data_lo; logic [DCCM_FDATA_WIDTH-1:0] dccm_rd_data_hi; @@ -345,40 +346,40 @@ module swerv_wrapper // PIC ports // Icache & Itag ports - logic [31:3] ic_rw_addr; + logic [31:3] ic_rw_addr; logic [3:0] ic_wr_en ; // Which way to write logic ic_rd_en ; - logic [3:0] ic_tag_valid; // Valid from the I$ tag valid outside (in flops). + logic [3:0] ic_tag_valid; // Valid from the I$ tag valid outside (in flops). logic [3:0] ic_rd_hit; // ic_rd_hit[3:0] logic ic_tag_perr; // Ic tag parity error - logic [15:2] ic_debug_addr; // Read/Write addresss to the Icache. + logic [15:2] 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 [3:0] ic_debug_way; // Debug way. Rd or Wr. `ifdef RV_ICACHE_ECC - logic [24:0] ictag_debug_rd_data;// Debug icache tag. + logic [24:0] ictag_debug_rd_data;// Debug icache tag. logic [83:0] ic_wr_data; // ic_wr_data[135:0] logic [167:0] ic_rd_data; // ic_rd_data[135:0] - logic [41:0] ic_debug_wr_data; // Debug wr cache. + logic [41:0] ic_debug_wr_data; // Debug wr cache. `else - logic [20:0] ictag_debug_rd_data;// Debug icache tag. + logic [20:0] ictag_debug_rd_data;// Debug icache tag. logic [67:0] ic_wr_data; // ic_wr_data[135:0] logic [135:0] ic_rd_data; // ic_rd_data[135:0] - logic [33:0] ic_debug_wr_data; // Debug wr cache. + logic [33:0] ic_debug_wr_data; // Debug wr cache. `endif logic [127:0] ic_premux_data; logic ic_sel_premux_data; -`ifdef RV_ICCM_ENABLE +`ifdef RV_ICCM_ENABLE // ICCM ports - logic [`RV_ICCM_BITS-1:2] iccm_rw_addr; + logic [`RV_ICCM_BITS-1:2] iccm_rw_addr; logic iccm_wren; logic iccm_rden; logic [2:0] iccm_wr_size; @@ -386,13 +387,13 @@ module swerv_wrapper logic [155:0] iccm_rd_data; `endif - logic core_rst_l; // Core reset including rst_l and dbg_rst_l + logic core_rst_l; // Core reset including rst_l and dbg_rst_l logic jtag_tdoEn; - + logic dccm_clk_override; logic icm_clk_override; logic dec_tlu_core_ecc_disable; - + logic dmi_reg_en; logic [6:0] dmi_reg_addr; logic dmi_reg_wr_en; @@ -404,7 +405,7 @@ module swerv_wrapper swerv swerv ( .* ); - + // Instantiate the mem mem mem ( .rst_l(core_rst_l), @@ -424,7 +425,7 @@ module swerv_wrapper .tdoEnable (), // Test Data Output enable // Processor Signals - .core_rst_n (core_rst_l), // Core reset, active low + .core_rst_n (dbg_rst_l), // Primary reset, active low .core_clk (clk), // Core clock .jtag_id (jtag_id), // 32 bit JTAG ID .rd_data (dmi_reg_rdata), // 32 bit Read data from Processor @@ -436,4 +437,4 @@ module swerv_wrapper ); endmodule - + diff --git a/testbench/ahb_sif.sv b/testbench/ahb_sif.sv index e0a3095..871e2a0 100644 --- a/testbench/ahb_sif.sv +++ b/testbench/ahb_sif.sv @@ -1,166 +1,195 @@ // 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. // +`ifdef RV_BUILD_AHB_LITE module ahb_sif ( - input logic [63:0] HWDATA, - input logic HCLK, - input logic HSEL, - input logic [3:0] HPROT, - input logic HWRITE, - input logic [1:0] HTRANS, - input logic [2:0] HSIZE, - input logic HREADY, - input logic HRESETn, - input logic [31:0] HADDR, - input logic [2:0] HBURST, - - output logic HREADYOUT, - output logic HRESP, - output logic [63:0] HRDATA +input logic [63:0] HWDATA, +input logic HCLK, +input logic HSEL, +input logic [3:0] HPROT, +input logic HWRITE, +input logic [1:0] HTRANS, +input logic [2:0] HSIZE, +input logic HREADY, +input logic HRESETn, +input logic [31:0] HADDR, +input logic [2:0] HBURST, +output logic HREADYOUT, +output logic HRESP, +output logic [63:0] HRDATA ); -localparam MEM_SIZE_DW = 8192; -localparam MAILBOX_ADDR = 32'hD0580000; +parameter MEM_SIZE_DW = 8192; +parameter MAILBOX_ADDR = 32'hD0580000; +localparam MEM_SIZE = MEM_SIZE_DW*8; -logic Last_HSEL; -logic NextLast_HSEL; -logic Last_HWRITE; -logic [1:0] Last_HTRANS; -logic [1:0] NextLast_HTRANS; +logic Write; logic [31:0] Last_HADDR; -logic [63:0] Next_HRDATA; -logic [63:0] WriteReadData; -logic [63:0] WriteMask; - -bit [7:0] mem [0:MEM_SIZE_DW-1]; +logic [7:0] strb_lat; +bit [7:0] mem [0:MEM_SIZE-1]; +//bit [7:0] mem [int]; +//int kuku[int]; // Wires -wire [63:0] Next_WriteMask = HSIZE == 3'b000 ? (64'hff << {HADDR[2:0], 3'b000}) : (HSIZE == 3'b001 ? (64'hffff << {HADDR[2], 4'h0}) : (HSIZE == 3'b010 ? (64'hffff_ffff << {HADDR[3],5'h0}) : 64'hffff_ffff_ffff_ffff)); +wire [63:0] WriteData = HWDATA; +wire [7:0] strb = HSIZE == 3'b000 ? 8'h1 << HADDR[2:0] : + HSIZE == 3'b001 ? 8'h3 << {HADDR[2:1],1'b0} : + HSIZE == 3'b010 ? 8'hf << {HADDR[2],2'b0} : 8'hff; -wire [63:0] MaskedWriteData = HWDATA & WriteMask; -wire [63:0] MaskedWriteReadData = WriteReadData & ~WriteMask; -wire [63:0] WriteData = (MaskedWriteData | MaskedWriteReadData ); -wire Write = &{Last_HSEL, Last_HWRITE, Last_HTRANS[1]}; -wire Read = &{ HSEL, ~HWRITE, HTRANS[1]}; +wire[31:0] addr = HADDR & (MEM_SIZE-1); +wire[31:0] laddr = Last_HADDR & (MEM_SIZE-1); -wire mailbox_write = &{Write, Last_HADDR==MAILBOX_ADDR, HRESETn==1}; -wire Next_HWRITE = |{HTRANS} ? HWRITE : Last_HWRITE; -wire [63:0] mem_dout = {mem[{Last_HADDR[12:3],3'b0}+7],mem[{Last_HADDR[12:3],3'b0}+6],mem[{Last_HADDR[12:3],3'b0}+5],mem[{Last_HADDR[12:3],3'b0}+4],mem[{Last_HADDR[12:3],3'b0}+3],mem[{Last_HADDR[12:3],3'b0}+2],mem[{Last_HADDR[12:3],3'b0}+1],mem[{Last_HADDR[12:3],3'b0}]}; +wire mailbox_write = Write && Last_HADDR==MAILBOX_ADDR; + +wire [63:0] mem_dout = {mem[{addr[31:3],3'd7}], + mem[{addr[31:3],3'd6}], + mem[{addr[31:3],3'd5}], + mem[{addr[31:3],3'd4}], + mem[{addr[31:3],3'd3}], + mem[{addr[31:3],3'd2}], + mem[{addr[31:3],3'd1}], + mem[{addr[31:3],3'd0}]}; -always @ (posedge HCLK or negedge HRESETn) begin - if (Write && Last_HADDR == 32'h0) begin - mem[{Last_HADDR[12:3],3'b0}+7] <= #1 { WriteData[63:56] }; - mem[{Last_HADDR[12:3],3'b0}+6] <= #1 { WriteData[55:48] }; - mem[{Last_HADDR[12:3],3'b0}+5] <= #1 { WriteData[47:40] }; - mem[{Last_HADDR[12:3],3'b0}+4] <= #1 { WriteData[39:32] }; - mem[{Last_HADDR[12:3],3'b0}+3] <= #1 { WriteData[31:24] }; - mem[{Last_HADDR[12:3],3'b0}+2] <= #1 { WriteData[23:16] }; - mem[{Last_HADDR[12:3],3'b0}+1] <= #1 { WriteData[15:08] }; - mem[{Last_HADDR[12:3],3'b0}+0] <= #1 { WriteData[07:00] }; +always @ (negedge HCLK ) begin + if (Write) begin + if(strb_lat[7]) mem[{laddr[31:3],3'd7}] = HWDATA[63:56]; + if(strb_lat[6]) mem[{laddr[31:3],3'd6}] = HWDATA[55:48]; + if(strb_lat[5]) mem[{laddr[31:3],3'd5}] = HWDATA[47:40]; + if(strb_lat[4]) mem[{laddr[31:3],3'd4}] = HWDATA[39:32]; + if(strb_lat[3]) mem[{laddr[31:3],3'd3}] = HWDATA[31:24]; + if(strb_lat[2]) mem[{laddr[31:3],3'd2}] = HWDATA[23:16]; + if(strb_lat[1]) mem[{laddr[31:3],3'd1}] = HWDATA[15:08]; + if(strb_lat[0]) mem[{laddr[31:3],3'd0}] = HWDATA[07:00]; end end + +assign HREADYOUT = 1; +assign HRESP = 0; + always @(posedge HCLK or negedge HRESETn) begin if(~HRESETn) begin - HREADYOUT <= #1 1'b0 ; - HRESP <= #1 1'b0; + Last_HADDR <= 32'b0; + Write <= 1'b0; + HRDATA <= '0; end else begin - HREADYOUT <= #1 |HTRANS; - HRESP <= #1 1'b0; - WriteMask <= #1 Next_WriteMask; - end -end - -`ifdef VERILATOR -always @(posedge HCLK or negedge HRESETn) begin -`else -always @(negedge HCLK or negedge HRESETn) begin -`endif - if(~HRESETn) begin - Last_HADDR <= #1 32'b0; - end else begin - Last_HADDR <= #1 |{HTRANS} ? {HADDR[31:2], 2'b00} : Last_HADDR; - end -end - -always @(posedge HCLK or negedge HRESETn) begin - if(~HRESETn) begin - Last_HWRITE <= #1 1'b0; - end else begin - Last_HWRITE <= #1 Next_HWRITE; - end -end - -always @(posedge HCLK or negedge HRESETn) begin - if(~HRESETn) begin - Last_HTRANS <= #1 2'b0; - end else begin - Last_HTRANS <= #1 HTRANS; - end -end - -always @(posedge HCLK or negedge HRESETn) begin - if(~HRESETn) begin - Last_HSEL <= #1 1'b0; - end else begin - Last_HSEL <= #1 HSEL; - end -end - - -`ifndef VERILATOR - -always @(posedge HCLK or negedge HRESETn) begin - if(~HRESETn) begin - HRDATA <= #1 Next_HRDATA ; - end else begin - HRDATA <= #1 Next_HRDATA ; - end -end - -always @* begin - Next_HRDATA = mem_dout; -end - -`else - -always @(posedge HCLK) begin - Next_HRDATA <= mem_dout; -end - -assign HRDATA = mem_dout; - -`endif - - -always @* begin - if(Last_HSEL) begin - WriteReadData[07:00] = mem[{Last_HADDR[12:3],3'b0}]; - WriteReadData[15:08] = mem[{Last_HADDR[12:3],3'b0}+1]; - WriteReadData[23:16] = mem[{Last_HADDR[12:3],3'b0}+2]; - WriteReadData[31:24] = mem[{Last_HADDR[12:3],3'b0}+3]; - WriteReadData[39:32] = mem[{Last_HADDR[12:3],3'b0}+4]; - WriteReadData[47:40] = mem[{Last_HADDR[12:3],3'b0}+5]; - WriteReadData[55:48] = mem[{Last_HADDR[12:3],3'b0}+6]; - WriteReadData[63:56] = mem[{Last_HADDR[12:3],3'b0}+7]; + Last_HADDR <= HADDR; + Write <= HWRITE & |HTRANS; + if(|HTRANS & ~HWRITE) + HRDATA <= mem_dout; + strb_lat <= strb; end end endmodule +`endif + +`ifdef RV_BUILD_AXI4 +module axi_slv #(TAGW=1) ( +input aclk, +input rst_l, +input arvalid, +output reg arready, +input [31:0] araddr, +input [TAGW-1:0] arid, +input [7:0] arlen, +input [1:0] arburst, +input [2:0] arsize, + +output reg rvalid, +input rready, +output reg [63:0] rdata, +output reg [1:0] rresp, +output reg [TAGW-1:0] rid, +output rlast, + +input awvalid, +output awready, +input [31:0] awaddr, +input [TAGW-1:0] awid, +input [7:0] awlen, +input [1:0] awburst, +input [2:0] awsize, + +input [63:0] wdata, +input [7:0] wstrb, +input wvalid, +output wready, + +output reg bvalid, +input bready, +output reg [1:0] bresp, +output reg [TAGW-1:0] bid +); + +parameter MAILBOX_ADDR = 32'hD0580000; +parameter MEM_SIZE_DW = 8192; + +bit [7:0] mem [0:MEM_SIZE_DW*8-1]; +bit [63:0] memdata; +wire [31:0] waddr, raddr; +wire [63:0] WriteData; +wire mailbox_write; + +assign raddr = araddr & (MEM_SIZE_DW*8-1); +assign waddr = awaddr & (MEM_SIZE_DW*8-1); + +assign mailbox_write = awvalid && awaddr==MAILBOX_ADDR && rst_l; +assign WriteData = wdata; + +always @ ( posedge aclk or negedge rst_l) begin + if(!rst_l) begin + rvalid <= 0; + bvalid <= 0; + end + else begin + bid <= awid; + rid <= arid; + rvalid <= arvalid; + bvalid <= awvalid; + rdata <= memdata; + end +end + +always @ ( negedge aclk) begin + if(arvalid) memdata <= {mem[raddr+7], mem[raddr+6], mem[raddr+5], mem[raddr+4], + mem[raddr+3], mem[raddr+2], mem[raddr+1], mem[raddr]}; + if(awvalid) begin + if(wstrb[7]) mem[waddr+7] = wdata[63:56]; + if(wstrb[6]) mem[waddr+6] = wdata[55:48]; + if(wstrb[5]) mem[waddr+5] = wdata[47:40]; + if(wstrb[4]) mem[waddr+4] = wdata[39:32]; + if(wstrb[3]) mem[waddr+3] = wdata[31:24]; + if(wstrb[2]) mem[waddr+2] = wdata[23:16]; + if(wstrb[1]) mem[waddr+1] = wdata[15:08]; + if(wstrb[0]) mem[waddr+0] = wdata[07:00]; + end +end + + +assign arready = 1'b1; +assign awready = 1'b1; +assign wready = 1'b1; +assign rresp = 2'b0; +assign bresp = 2'b0; +assign rlast = 1'b1; + +endmodule +`endif diff --git a/testbench/asm/hello_world.s b/testbench/asm/hello_world.s index d5eae52..4a45444 100644 --- a/testbench/asm/hello_world.s +++ b/testbench/asm/hello_world.s @@ -1,67 +1,72 @@ +// 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. +// + +// Assembly code for Hello World +// Not using only ALU ops for creating the string +#include "defines.h" + +#define STDOUT 0xd0580000 + + +// Code to execute +.section .text .global _start _start: - csrrw x2, 0xb02, x3 - - lui x5, 974848 - ori x5, x5, 0 - csrrw x2, 0x305, x5 - - - lui x6, 382293 - ori x6, x6, 1365 - csrrw x1, 0x7c0, x6 + // Clear minstret + csrw minstret, zero + csrw minstreth, zero - - - - lui x5, 0 - ori x5, x5, 0 - csrrw x2, 0x7f8, x5 - - - - - lui x5, 0 - ori x5, x5, 0 - csrrw x2, 0x7f9, x5 + // Set up MTVEC - not expecting to use it though + li x1, RV_ICCM_SADR + csrw mtvec, x1 - addi x0, x0, 0 - lui x11, 853376 - ori x9, x0, 'H' - sw x9, 0 (x11) - ori x9, x0, 'E' - sw x9, 0 (x11) - ori x9, x0, 'L' - sw x9, 0 (x11) - sw x9, 0 (x11) - ori x9, x0, 'O' - sw x9, 0 (x11) - ori x9, x0, ' ' - sw x9, 0 (x11) - addi x9, x0, 'W' - sw x9, 0 (x11) - ori x9, x0, 'O' - sw x9, 0 (x11) - ori x9, x0, 'R' - sw x9, 0 (x11) - ori x9, x0, 'L' - sw x9, 0 (x11) - ori x9, x0, 'D' - sw x9, 0 (x11) - ori x9, x0, '!' - sw x9, 0 (x11) - ori x9, x0, 255 - sw x9, 0 (x11) - addi x1,x0,0 + // Enable Caches in MRAC + li x1, 0x5f555555 + csrw 0x7c0, x1 -finish: - addi x1,x1,1 - jal x0, finish; - addi x0,x0,0 - addi x0,x0,0 - addi x0,x0,0 - addi x0,x0,0 + // Load string from hw_data + // and write to stdout address + + li x3, STDOUT + la x4, hw_data + +loop: + lb x5, 0(x4) + sb x5, 0(x3) + addi x4, x4, 1 + bnez x5, loop + +// Write 0xff to STDOUT for TB to terminate test. +_finish: + li x3, STDOUT + addi x5, x0, 0xff + sb x5, 0(x3) + beq x0, x0, _finish +.rept 100 + nop +.endr + +.global hw_data +.data +hw_data: +.ascii "----------------------------------\n" +.ascii "Hello World from SweRV EH1 @WDC !!\n" +.ascii "----------------------------------\n" +.byte 0 diff --git a/testbench/link.ld b/testbench/link.ld index ef1ee3a..de779f8 100644 --- a/testbench/link.ld +++ b/testbench/link.ld @@ -4,9 +4,9 @@ ENTRY(_start) SECTIONS { - . = 0x1000; - .data . : { *(.*data) *(.rodata*) } - . = 0x0; - .text . : { *(.text) } + . = 0; + .text : { *(.text*) } _end = .; + . = 0x10000; + .data : ALIGN(0x800) { *(.*data) *(.rodata*) STACK = ALIGN(16) + 0x8000; } } diff --git a/testbench/tb_top.sv b/testbench/tb_top.sv index 29302d9..9d101a2 100644 --- a/testbench/tb_top.sv +++ b/testbench/tb_top.sv @@ -1,378 +1,691 @@ // SPDX-License-Identifier: Apache-2.0 -// Copyright 2019 Western Digital Corporation or its affiliates. -// +// 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. // -`ifndef VERILATOR +`ifdef VERILATOR +module tb_top ( input bit core_clk); +`else module tb_top; -`else -module tb_top ( input logic core_clk, input logic reset_l, output finished); + bit core_clk; `endif + logic rst_l; + logic porst_l; + logic nmi_int; + + logic [31:0] reset_vector; + logic [31:0] nmi_vector; + logic [31:1] jtag_id; + + 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 [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_hrdata; + logic [63:0] lsu_hwdata; + logic lsu_hready; + logic lsu_hresp; + + 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_hrdata; + logic [63:0] sb_hwdata; + logic sb_hready; + logic sb_hresp; + + logic [63:0] trace_rv_i_insn_ip; + logic [63:0] trace_rv_i_address_ip; + logic [2:0] trace_rv_i_valid_ip; + logic [2:0] trace_rv_i_exception_ip; + logic [4:0] trace_rv_i_ecause_ip; + logic [2:0] trace_rv_i_interrupt_ip; + logic [31:0] trace_rv_i_tval_ip; + + logic o_debug_mode_status; + logic [1:0] dec_tlu_perfcnt0; + logic [1:0] dec_tlu_perfcnt1; + logic [1:0] dec_tlu_perfcnt2; + logic [1:0] dec_tlu_perfcnt3; + + + logic jtag_tdo; + 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; + + bit [31:0] cycleCnt; + logic mailbox_data_val; + + wire dma_hready_out; + int commit_count; + + logic wb_valid[1:0]; + logic [4:0] wb_dest[1:0]; + logic [31:0] wb_data[1:0]; + +`ifdef RV_BUILD_AXI4 + //-------------------------- LSU AXI signals-------------------------- + // AXI Write Channels + wire lsu_axi_awvalid; + wire lsu_axi_awready; + wire [`RV_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 [`RV_LSU_BUS_TAG-1:0] lsu_axi_bid; + + // AXI Read Channels + wire lsu_axi_arvalid; + wire lsu_axi_arready; + wire [`RV_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 [`RV_LSU_BUS_TAG-1:0] lsu_axi_rid; + wire [63:0] lsu_axi_rdata; + wire [1:0] lsu_axi_rresp; + wire lsu_axi_rlast; + + //-------------------------- IFU AXI signals-------------------------- + // AXI Write Channels + wire ifu_axi_awvalid; + wire ifu_axi_awready; + wire [`RV_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 [`RV_IFU_BUS_TAG-1:0] ifu_axi_bid; + + // AXI Read Channels + wire ifu_axi_arvalid; + wire ifu_axi_arready; + wire [`RV_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 [`RV_IFU_BUS_TAG-1:0] ifu_axi_rid; + wire [63:0] ifu_axi_rdata; + wire [1:0] ifu_axi_rresp; + wire ifu_axi_rlast; + + //-------------------------- SB AXI signals-------------------------- + // AXI Write Channels + wire sb_axi_awvalid; + wire sb_axi_awready; + wire [`RV_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 [`RV_SB_BUS_TAG-1:0] sb_axi_bid; + + // AXI Read Channels + wire sb_axi_arvalid; + wire sb_axi_arready; + wire [`RV_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 [`RV_SB_BUS_TAG-1:0] sb_axi_rid; + wire [63:0] sb_axi_rdata; + wire [1:0] sb_axi_rresp; + wire sb_axi_rlast; + + //-------------------------- DMA AXI signals-------------------------- + // AXI Write Channels + wire dma_axi_awvalid; + wire dma_axi_awready; + wire [`RV_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; + + wire dma_axi_bvalid; + wire dma_axi_bready; + wire [1:0] dma_axi_bresp; + wire [`RV_DMA_BUS_TAG-1:0] dma_axi_bid; + + // AXI Read Channels + wire dma_axi_arvalid; + wire dma_axi_arready; + wire [`RV_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; + + wire dma_axi_rvalid; + wire dma_axi_rready; + wire [`RV_DMA_BUS_TAG-1:0] dma_axi_rid; + wire [63:0] dma_axi_rdata; + wire [1:0] dma_axi_rresp; + wire dma_axi_rlast; -`ifndef VERILATOR - logic reset_l; - logic core_clk; `endif - logic nmi_int; - - logic [31:0] reset_vector; - logic [31:0] nmi_vector; - logic [31:1] jtag_id; - - 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 [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_hrdata ; - logic [63:0] lsu_hwdata ; - logic lsu_hready ; - logic lsu_hresp ; - - 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_hrdata ; - logic [63:0] sb_hwdata ; - logic sb_hready ; - logic sb_hresp ; - - logic [63:0] trace_rv_i_insn_ip; - logic [63:0] trace_rv_i_address_ip; - logic [2:0] trace_rv_i_valid_ip; - logic [2:0] trace_rv_i_exception_ip; - logic [4:0] trace_rv_i_ecause_ip; - logic [2:0] trace_rv_i_interrupt_ip; - logic [31:0] trace_rv_i_tval_ip; - - logic o_debug_mode_status; - logic [1:0] dec_tlu_perfcnt0; - logic [1:0] dec_tlu_perfcnt1; - logic [1:0] dec_tlu_perfcnt2; - logic [1:0] dec_tlu_perfcnt3; + wire[63:0] WriteData; - logic jtag_tdo; - logic o_cpu_halt_ack; - logic o_cpu_halt_status; - logic o_cpu_run_ack; + assign mailbox_write = lmem.mailbox_write; + assign WriteData = lmem.WriteData; + assign mailbox_data_val = WriteData[7:0] > 8'h5 && WriteData[7:0] < 8'h7f; - logic mailbox_write; - logic [63:0] dma_hrdata ; - logic [63:0] dma_hwdata ; - logic dma_hready ; - logic dma_hresp ; + parameter MAX_CYCLES = 10_000_000; - 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 fd, tp, el; - logic [31:0] cycleCnt ; - logic mailbox_data_val; -`ifndef VERILATOR - logic finished; -`endif - - wire dma_hready_out; - integer commit_count; - - logic wb_valid[1:0]; - logic [4:0] wb_dest[1:0]; - logic [31:0] wb_data[1:0]; - - //assign mailbox_write = &{i_ahb_lsu.Write, i_ahb_lsu.Last_HADDR==32'hD0580000, i_ahb_lsu.HRESETn==1}; - assign mailbox_write = i_ahb_lsu.mailbox_write; - //assign mailbox_write = i_ahb_lsu.mailbox_write & !core_clk; - assign mailbox_data_val = (i_ahb_lsu.WriteData[7:0] > 8'h5) & (i_ahb_lsu.WriteData[7:0] < 8'h7f); - - assign finished = finished | &{i_ahb_lsu.mailbox_write, (i_ahb_lsu.WriteData[7:0] == 8'hff)}; - - assign jtag_id[31:28] = 4'b1; - assign jtag_id[27:12] = '0; - assign jtag_id[11:1] = 11'h45; - - - -`ifndef VERILATOR - `define FORCE force -`else - `define FORCE -`endif - - - integer fd; - initial begin - fd = $fopen("console.log","w"); - commit_count = 0; - end - - integer tp,el; - - always @(posedge core_clk or negedge reset_l) begin - if( reset_l == 0) - cycleCnt <= 0; - else - cycleCnt <= cycleCnt+1; - end - - always @(posedge core_clk) begin - //if(cycleCnt == 32'h800) - if(cycleCnt == 32'h800) begin - $display ("Hit max cycle count.. stopping"); + always @(negedge core_clk) begin + cycleCnt <= cycleCnt+1; + // Test timeout monitor + if(cycleCnt == MAX_CYCLES) begin + $display ("Hit max cycle count (%0d) .. stopping",cycleCnt); $finish; end - end - - -`ifdef VERILATOR - always @(negedge mailbox_write) -`else - always @(posedge mailbox_write) -`endif - if( mailbox_data_val ) begin - $fwrite(fd,"%c", i_ahb_lsu.WriteData[7:0]); - $write("%c", i_ahb_lsu.WriteData[7:0]); - end - - always @(posedge finished) begin - $display("\n\nFinished : minstret = %0d, mcycle = %0d", rvtop.swerv.dec.tlu.minstretl[31:0],rvtop.swerv.dec.tlu.mcyclel[31:0]); - $display("\n\nSee \"exec.log\" for execution trace with register updates..\n"); -`ifndef VERILATOR - $finish; -`endif - end - - always @(posedge core_clk) begin - wb_valid[1:0] <= '{rvtop.swerv.dec.dec_i1_wen_wb & ~rvtop.swerv.dec.decode.dec_tlu_i1_kill_writeb_wb, - rvtop.swerv.dec.decode.wbd.i0v & ~rvtop.swerv.dec.decode.dec_tlu_i0_kill_writeb_wb}; - wb_dest[1:0] <= '{rvtop.swerv.dec.dec_i1_waddr_wb, rvtop.swerv.dec.dec_i0_waddr_wb}; - wb_data[1:0] <= '{rvtop.swerv.dec.dec_i1_wdata_wb, rvtop.swerv.dec.dec_i0_wdata_wb}; - if (rvtop.trace_rv_i_valid_ip !== 0) begin - $fwrite(tp,"%b,%h,%h,%0h,%0h,3,%b,%h,%h,%b\n", rvtop.trace_rv_i_valid_ip, rvtop.trace_rv_i_address_ip[63:32], rvtop.trace_rv_i_address_ip[31:0], rvtop.trace_rv_i_insn_ip[63:32], rvtop.trace_rv_i_insn_ip[31:0],rvtop.trace_rv_i_exception_ip,rvtop.trace_rv_i_ecause_ip,rvtop.trace_rv_i_tval_ip,rvtop.trace_rv_i_interrupt_ip); - // Basic trace - no exception register updates - // #1 0 ee000000 b0201073 c 0b02 00000000 - if (rvtop.trace_rv_i_valid_ip[0]==1) begin - commit_count ++; - $fwrite (el, "%0d : #%0d 0 %0h %0h r %0d %0h\n",$time(), commit_count, rvtop.trace_rv_i_address_ip[31:0], rvtop.trace_rv_i_insn_ip[31:0], wb_dest[0], wb_data[0]); - end - if (rvtop.trace_rv_i_valid_ip[1]==1) begin - commit_count ++; - $fwrite (el, "%0d : #%0d 0 0x%0h 0x%0h r %0d 0x%h\n",$time(), commit_count, rvtop.trace_rv_i_address_ip[63:32], rvtop.trace_rv_i_insn_ip[63:32], wb_dest[1], wb_data[1]); - end + // cansol Monitor + if( mailbox_data_val & mailbox_write) begin + $fwrite(fd,"%c", WriteData[7:0]); + $write("%c", WriteData[7:0]); + end + // End Of test monitor + if(mailbox_write && WriteData[7:0] == 8'hff) begin + $display("\nFinished : minstret = %0d, mcycle = %0d", rvtop.swerv.dec.tlu.minstretl[31:0],rvtop.swerv.dec.tlu.mcyclel[31:0]); + $display("See \"exec.log\" for execution trace with register updates..\n"); + $display("TEST_PASSED"); + $finish; + end + else if(mailbox_write && WriteData[7:0] == 8'h1) begin + $display("TEST_FAILED"); + $finish; end end - initial begin + + // trace monitor + always @(posedge core_clk) begin + wb_valid[1:0] <= '{rvtop.swerv.dec.dec_i1_wen_wb, rvtop.swerv.dec.dec_i0_wen_wb}; + wb_dest[1:0] <= '{rvtop.swerv.dec.dec_i1_waddr_wb, rvtop.swerv.dec.dec_i0_waddr_wb}; + wb_data[1:0] <= '{rvtop.swerv.dec.dec_i1_wdata_wb, rvtop.swerv.dec.dec_i0_wdata_wb}; + if (trace_rv_i_valid_ip !== 0) begin + $fwrite(tp,"%b,%h,%h,%0h,%0h,3,%b,%h,%h,%b\n", trace_rv_i_valid_ip, trace_rv_i_address_ip[63:32], trace_rv_i_address_ip[31:0], + trace_rv_i_insn_ip[63:32], trace_rv_i_insn_ip[31:0],trace_rv_i_exception_ip,trace_rv_i_ecause_ip, + trace_rv_i_tval_ip,trace_rv_i_interrupt_ip); + // Basic trace - no exception register updates + // #1 0 ee000000 b0201073 c 0b02 00000000 + for (int i=0; i<2; i++) + if (trace_rv_i_valid_ip[i]==1) begin + commit_count++; + $fwrite (el, "%10d : %6s 0 %h %h %s\n", cycleCnt, $sformatf("#%0d",commit_count), + trace_rv_i_address_ip[31+i*32 -:32], trace_rv_i_insn_ip[31+i*32-:32], + wb_dest[i] !=0 ? $sformatf("r%0d=%h", wb_dest[i], wb_data[i]) : ""); + end + end + end + + + initial begin + // tie offs + jtag_id[31:28] = 4'b1; + jtag_id[27:12] = '0; + jtag_id[11:1] = 11'h45; + reset_vector = 32'h0; + nmi_vector = 32'hee000000; + nmi_int = 0; + + $readmemh("data.hex", lmem.mem); + $readmemh("program.hex", imem.mem); + tp = $fopen("trace_port.csv","w"); + el = $fopen("exec.log","w"); + $fwrite (el, "//Cycle : #inst 0 pc opcode reg regnum value\n"); + fd = $fopen("console.log","w"); + commit_count = 0; + preload_dccm(); + preload_iccm(); `ifndef VERILATOR - core_clk = 0; - reset_l = 0; + if($test$plusargs("dumpon")) $dumpvars; + forever core_clk = #5 ~core_clk; `endif + end - reset_vector = 32'h80000000; - nmi_vector = 32'hee000000; - nmi_int = 0; -`ifndef VERILATOR - @(posedge core_clk); - reset_l = 0; -`endif - - $readmemh("data.hex", i_ahb_lsu.mem); - $readmemh("program.hex", i_ahb_ic.mem); - tp = $fopen("trace_port.csv","w"); - el = $fopen("exec.log","w"); - $fwrite (el, "//Time : #inst 0 pc opcode reg regnum value\n"); - -`ifndef VERILATOR - repeat (5) @(posedge core_clk); - reset_l = 1; - #100000 $display("");$finish; -`endif - end - -`ifndef VERILATOR -initial begin - forever begin - core_clk = #5 ~core_clk; - end -end -`endif + assign rst_l = cycleCnt > 5; + assign porst_l = cycleCnt >2; //=========================================================================- // RTL instance //=========================================================================- - swerv_wrapper rvtop ( - .rst_l ( reset_l ), - .clk ( core_clk ), - .rst_vec ( 31'h40000000 ), - .nmi_int ( nmi_int ), - .nmi_vec ( 31'h77000000 ), - .jtag_id (jtag_id[31:1]), +swerv_wrapper rvtop ( + .rst_l ( rst_l ), + .dbg_rst_l ( porst_l ), + .clk ( core_clk ), + .rst_vec ( reset_vector[31:1]), + .nmi_int ( nmi_int ), + .nmi_vec ( nmi_vector[31:1]), + .jtag_id ( jtag_id[31:1]), - .haddr ( ic_haddr ), - .hburst ( ic_hburst ), - .hmastlock ( ic_hmastlock ), - .hprot ( ic_hprot ), - .hsize ( ic_hsize ), - .htrans ( ic_htrans ), - .hwrite ( ic_hwrite ), +`ifdef RV_BUILD_AHB_LITE + .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 ), + .hrdata ( ic_hrdata[63:0]), + .hready ( ic_hready ), + .hresp ( ic_hresp ), - //--------------------------------------------------------------- - // Debug AHB Master - //--------------------------------------------------------------- - .sb_haddr ( sb_haddr ), - .sb_hburst ( sb_hburst ), - .sb_hmastlock ( sb_hmastlock ), - .sb_hprot ( sb_hprot ), - .sb_hsize ( sb_hsize ), - .sb_htrans ( sb_htrans ), - .sb_hwrite ( sb_hwrite ), - .sb_hwdata ( sb_hwdata ), + //--------------------------------------------------------------- + // Debug AHB Master + //--------------------------------------------------------------- + .sb_haddr ( sb_haddr ), + .sb_hburst ( sb_hburst ), + .sb_hmastlock ( sb_hmastlock ), + .sb_hprot ( sb_hprot ), + .sb_hsize ( sb_hsize ), + .sb_htrans ( sb_htrans ), + .sb_hwrite ( sb_hwrite ), + .sb_hwdata ( sb_hwdata ), - .sb_hrdata ( sb_hrdata ), - .sb_hready ( sb_hready ), - .sb_hresp ( sb_hresp ), + .sb_hrdata ( sb_hrdata ), + .sb_hready ( sb_hready ), + .sb_hresp ( sb_hresp ), + + //--------------------------------------------------------------- + // LSU AHB Master + //--------------------------------------------------------------- + .lsu_haddr ( lsu_haddr ), + .lsu_hburst ( lsu_hburst ), + .lsu_hmastlock ( lsu_hmastlock ), + .lsu_hprot ( lsu_hprot ), + .lsu_hsize ( lsu_hsize ), + .lsu_htrans ( lsu_htrans ), + .lsu_hwrite ( lsu_hwrite ), + .lsu_hwdata ( lsu_hwdata ), + + .lsu_hrdata ( lsu_hrdata[63:0]), + .lsu_hready ( lsu_hready ), + .lsu_hresp ( lsu_hresp ), + + //--------------------------------------------------------------- + // DMA Slave + //--------------------------------------------------------------- + .dma_haddr ( '0 ), + .dma_hburst ( '0 ), + .dma_hmastlock ( '0 ), + .dma_hprot ( '0 ), + .dma_hsize ( '0 ), + .dma_htrans ( '0 ), + .dma_hwrite ( '0 ), + .dma_hwdata ( '0 ), + + .dma_hrdata ( dma_hrdata ), + .dma_hresp ( dma_hresp ), + .dma_hsel ( 1'b1 ), + .dma_hreadyin ( dma_hready_out ), + .dma_hreadyout ( dma_hready_out ), +`endif +`ifdef RV_BUILD_AXI4 + //-------------------------- LSU AXI signals-------------------------- + // AXI Write Channels + .lsu_axi_awvalid (lsu_axi_awvalid), + .lsu_axi_awready (lsu_axi_awready), + .lsu_axi_awid (lsu_axi_awid), + .lsu_axi_awaddr (lsu_axi_awaddr), + .lsu_axi_awregion (lsu_axi_awregion), + .lsu_axi_awlen (lsu_axi_awlen), + .lsu_axi_awsize (lsu_axi_awsize), + .lsu_axi_awburst (lsu_axi_awburst), + .lsu_axi_awlock (lsu_axi_awlock), + .lsu_axi_awcache (lsu_axi_awcache), + .lsu_axi_awprot (lsu_axi_awprot), + .lsu_axi_awqos (lsu_axi_awqos), + + .lsu_axi_wvalid (lsu_axi_wvalid), + .lsu_axi_wready (lsu_axi_wready), + .lsu_axi_wdata (lsu_axi_wdata), + .lsu_axi_wstrb (lsu_axi_wstrb), + .lsu_axi_wlast (lsu_axi_wlast), + + .lsu_axi_bvalid (lsu_axi_bvalid), + .lsu_axi_bready (lsu_axi_bready), + .lsu_axi_bresp (lsu_axi_bresp), + .lsu_axi_bid (lsu_axi_bid), - //--------------------------------------------------------------- - // LSU AHB Master - //--------------------------------------------------------------- - .lsu_haddr ( lsu_haddr ), - .lsu_hburst ( lsu_hburst ), - .lsu_hmastlock ( lsu_hmastlock ), - .lsu_hprot ( lsu_hprot ), - .lsu_hsize ( lsu_hsize ), - .lsu_htrans ( lsu_htrans ), - .lsu_hwrite ( lsu_hwrite ), - .lsu_hwdata ( lsu_hwdata ), + .lsu_axi_arvalid (lsu_axi_arvalid), + .lsu_axi_arready (lsu_axi_arready), + .lsu_axi_arid (lsu_axi_arid), + .lsu_axi_araddr (lsu_axi_araddr), + .lsu_axi_arregion (lsu_axi_arregion), + .lsu_axi_arlen (lsu_axi_arlen), + .lsu_axi_arsize (lsu_axi_arsize), + .lsu_axi_arburst (lsu_axi_arburst), + .lsu_axi_arlock (lsu_axi_arlock), + .lsu_axi_arcache (lsu_axi_arcache), + .lsu_axi_arprot (lsu_axi_arprot), + .lsu_axi_arqos (lsu_axi_arqos), - .lsu_hrdata ( lsu_hrdata[63:0]), - .lsu_hready ( lsu_hready ), - .lsu_hresp ( lsu_hresp ), + .lsu_axi_rvalid (lsu_axi_rvalid), + .lsu_axi_rready (lsu_axi_rready), + .lsu_axi_rid (lsu_axi_rid), + .lsu_axi_rdata (lsu_axi_rdata), + .lsu_axi_rresp (lsu_axi_rresp), + .lsu_axi_rlast (lsu_axi_rlast), + + //-------------------------- IFU AXI signals-------------------------- + // AXI Write Channels + .ifu_axi_awvalid (ifu_axi_awvalid), + .ifu_axi_awready (ifu_axi_awready), + .ifu_axi_awid (ifu_axi_awid), + .ifu_axi_awaddr (ifu_axi_awaddr), + .ifu_axi_awregion (ifu_axi_awregion), + .ifu_axi_awlen (ifu_axi_awlen), + .ifu_axi_awsize (ifu_axi_awsize), + .ifu_axi_awburst (ifu_axi_awburst), + .ifu_axi_awlock (ifu_axi_awlock), + .ifu_axi_awcache (ifu_axi_awcache), + .ifu_axi_awprot (ifu_axi_awprot), + .ifu_axi_awqos (ifu_axi_awqos), + + .ifu_axi_wvalid (ifu_axi_wvalid), + .ifu_axi_wready (ifu_axi_wready), + .ifu_axi_wdata (ifu_axi_wdata), + .ifu_axi_wstrb (ifu_axi_wstrb), + .ifu_axi_wlast (ifu_axi_wlast), + + .ifu_axi_bvalid (ifu_axi_bvalid), + .ifu_axi_bready (ifu_axi_bready), + .ifu_axi_bresp (ifu_axi_bresp), + .ifu_axi_bid (ifu_axi_bid), + + .ifu_axi_arvalid (ifu_axi_arvalid), + .ifu_axi_arready (ifu_axi_arready), + .ifu_axi_arid (ifu_axi_arid), + .ifu_axi_araddr (ifu_axi_araddr), + .ifu_axi_arregion (ifu_axi_arregion), + .ifu_axi_arlen (ifu_axi_arlen), + .ifu_axi_arsize (ifu_axi_arsize), + .ifu_axi_arburst (ifu_axi_arburst), + .ifu_axi_arlock (ifu_axi_arlock), + .ifu_axi_arcache (ifu_axi_arcache), + .ifu_axi_arprot (ifu_axi_arprot), + .ifu_axi_arqos (ifu_axi_arqos), + + .ifu_axi_rvalid (ifu_axi_rvalid), + .ifu_axi_rready (ifu_axi_rready), + .ifu_axi_rid (ifu_axi_rid), + .ifu_axi_rdata (ifu_axi_rdata), + .ifu_axi_rresp (ifu_axi_rresp), + .ifu_axi_rlast (ifu_axi_rlast), + + //-------------------------- SB AXI signals-------------------------- + // AXI Write Channels + .sb_axi_awvalid (sb_axi_awvalid), + .sb_axi_awready (sb_axi_awready), + .sb_axi_awid (sb_axi_awid), + .sb_axi_awaddr (sb_axi_awaddr), + .sb_axi_awregion (sb_axi_awregion), + .sb_axi_awlen (sb_axi_awlen), + .sb_axi_awsize (sb_axi_awsize), + .sb_axi_awburst (sb_axi_awburst), + .sb_axi_awlock (sb_axi_awlock), + .sb_axi_awcache (sb_axi_awcache), + .sb_axi_awprot (sb_axi_awprot), + .sb_axi_awqos (sb_axi_awqos), + + .sb_axi_wvalid (sb_axi_wvalid), + .sb_axi_wready (sb_axi_wready), + .sb_axi_wdata (sb_axi_wdata), + .sb_axi_wstrb (sb_axi_wstrb), + .sb_axi_wlast (sb_axi_wlast), + + .sb_axi_bvalid (sb_axi_bvalid), + .sb_axi_bready (sb_axi_bready), + .sb_axi_bresp (sb_axi_bresp), + .sb_axi_bid (sb_axi_bid), - //--------------------------------------------------------------- - // DMA Slave - //--------------------------------------------------------------- - .dma_haddr ( '0 ), - .dma_hburst ( '0 ), - .dma_hmastlock ( '0 ), - .dma_hprot ( '0 ), - .dma_hsize ( '0 ), - .dma_htrans ( '0 ), - .dma_hwrite ( '0 ), - .dma_hwdata ( '0 ), + .sb_axi_arvalid (sb_axi_arvalid), + .sb_axi_arready (sb_axi_arready), + .sb_axi_arid (sb_axi_arid), + .sb_axi_araddr (sb_axi_araddr), + .sb_axi_arregion (sb_axi_arregion), + .sb_axi_arlen (sb_axi_arlen), + .sb_axi_arsize (sb_axi_arsize), + .sb_axi_arburst (sb_axi_arburst), + .sb_axi_arlock (sb_axi_arlock), + .sb_axi_arcache (sb_axi_arcache), + .sb_axi_arprot (sb_axi_arprot), + .sb_axi_arqos (sb_axi_arqos), - .dma_hrdata ( dma_hrdata ), - .dma_hresp ( dma_hresp ), - .dma_hsel ( 1'b1 ), - .dma_hreadyin ( dma_hready_out ), - .dma_hreadyout ( dma_hready_out ), + .sb_axi_rvalid (sb_axi_rvalid), + .sb_axi_rready (sb_axi_rready), + .sb_axi_rid (sb_axi_rid), + .sb_axi_rdata (sb_axi_rdata), + .sb_axi_rresp (sb_axi_rresp), + .sb_axi_rlast (sb_axi_rlast), - .timer_int ( 1'b0 ), - `ifdef TB_RESTRUCT - .extintsrc_req ( '0 ), - `else - .extintsrc_req ( '0 ), - `endif - - `ifdef RV_BUILD_AHB_LITE - .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'b0 ),// Clock ratio b/w cpu core clk & AHB Debug master interface - .dma_bus_clk_en ( 1'b0 ),// Clock ratio b/w cpu core clk & AHB slave interface - `endif - - .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), + //-------------------------- DMA AXI signals-------------------------- + // AXI Write Channels + .dma_axi_awvalid (1'b0), + .dma_axi_awready (dma_axi_awready), + .dma_axi_awid (dma_axi_awid), + .dma_axi_awaddr (dma_axi_awaddr), + .dma_axi_awsize (dma_axi_awsize), + .dma_axi_awprot (dma_axi_awprot), + .dma_axi_awlen (dma_axi_awlen), + .dma_axi_awburst (dma_axi_awburst), + .dma_axi_wvalid (1'b0), + .dma_axi_wready (dma_axi_wready), + .dma_axi_wdata (dma_axi_wdata), + .dma_axi_wstrb (dma_axi_wstrb), + .dma_axi_wlast (dma_axi_wlast), + + .dma_axi_bvalid (dma_axi_bvalid), + .dma_axi_bready (1'b0), + .dma_axi_bresp (dma_axi_bresp), + .dma_axi_bid (dma_axi_bid), + .dma_axi_arvalid (1'b0), + .dma_axi_arready (dma_axi_arready), + .dma_axi_arid (dma_axi_arid), + .dma_axi_araddr (dma_axi_araddr), + .dma_axi_arsize (dma_axi_arsize), + .dma_axi_arprot (dma_axi_arprot), + .dma_axi_arlen (dma_axi_arlen), + .dma_axi_arburst (dma_axi_arburst), - .jtag_tck ( 1'b0 ), // JTAG clk - .jtag_tms ( 1'b0 ), // JTAG TMS - .jtag_tdi ( 1'b0 ), // JTAG tdi - .jtag_trst_n ( 1'b0 ), // JTAG Reset - .jtag_tdo ( jtag_tdo ), // JTAG TDO + .dma_axi_rvalid (dma_axi_rvalid), + .dma_axi_rready (1'b0), + .dma_axi_rid (dma_axi_rid), + .dma_axi_rdata (dma_axi_rdata), + .dma_axi_rresp (dma_axi_rresp), + .dma_axi_rlast (dma_axi_rlast), +`endif + .timer_int ( 1'b0 ), + .extintsrc_req ( '0 ), - .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), + .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 - .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 + .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), - .dec_tlu_perfcnt0(dec_tlu_perfcnt0), - .dec_tlu_perfcnt1(dec_tlu_perfcnt1), - .dec_tlu_perfcnt2(dec_tlu_perfcnt2), - .dec_tlu_perfcnt3(dec_tlu_perfcnt3), + .jtag_tck ( 1'b0 ), + .jtag_tms ( 1'b0 ), + .jtag_tdi ( 1'b0 ), + .jtag_trst_n ( 1'b0 ), + .jtag_tdo ( jtag_tdo ), - .scan_mode ( 1'b0 ), // To enable scan mode - .mbist_mode ( 1'b0 ) // to enable mbist + .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 -initial begin - `FORCE rvtop.dccm_rd_data_hi = '0; - `FORCE rvtop.dccm_rd_data_lo = '0; -end + .dec_tlu_perfcnt0 (dec_tlu_perfcnt0), + .dec_tlu_perfcnt1 (dec_tlu_perfcnt1), + .dec_tlu_perfcnt2 (dec_tlu_perfcnt2), + .dec_tlu_perfcnt3 (dec_tlu_perfcnt3), + + .scan_mode ( 1'b0 ), // To enable scan mode + .mbist_mode ( 1'b0 ) // to enable mbist + +); //=========================================================================- // AHB I$ instance //=========================================================================- +`ifdef RV_BUILD_AHB_LITE - ahb_sif i_ahb_ic ( - +ahb_sif imem ( // Inputs .HWDATA(64'h0), .HCLK(core_clk), @@ -382,7 +695,7 @@ end .HTRANS(ic_htrans), .HSIZE(ic_hsize), .HREADY(ic_hready), - .HRESETn(reset_l), + .HRESETn(rst_l), .HADDR(ic_haddr), .HBURST(ic_hburst), @@ -390,12 +703,10 @@ end .HREADYOUT(ic_hready), .HRESP(ic_hresp), .HRDATA(ic_hrdata[63:0]) - - ); +); - ahb_sif i_ahb_lsu ( - +ahb_sif lmem ( // Inputs .HWDATA(lsu_hwdata), .HCLK(core_clk), @@ -405,7 +716,7 @@ end .HTRANS(lsu_htrans), .HSIZE(lsu_hsize), .HREADY(lsu_hready), - .HRESETn(reset_l), + .HRESETn(rst_l), .HADDR(lsu_haddr), .HBURST(lsu_hburst), @@ -413,30 +724,254 @@ end .HREADYOUT(lsu_hready), .HRESP(lsu_hresp), .HRDATA(lsu_hrdata[63:0]) +); - ); +`endif +`ifdef RV_BUILD_AXI4 +axi_slv #(.TAGW(`RV_IFU_BUS_TAG)) imem( + .aclk(core_clk), + .rst_l(rst_l), + .arvalid(ifu_axi_arvalid), + .arready(ifu_axi_arready), + .araddr(ifu_axi_araddr), + .arid(ifu_axi_arid), + .arlen(ifu_axi_arlen), + .arburst(ifu_axi_arburst), + .arsize(ifu_axi_arsize), - ahb_sif i_ahb_sb ( + .rvalid(ifu_axi_rvalid), + .rready(ifu_axi_rready), + .rdata(ifu_axi_rdata), + .rresp(ifu_axi_rresp), + .rid(ifu_axi_rid), + .rlast(ifu_axi_rlast), - // Inputs - .HWDATA(sb_hwdata), - .HCLK(core_clk), - .HSEL(1'b1), - .HPROT(sb_hprot), - .HWRITE(sb_hwrite), - .HTRANS(sb_htrans), - .HSIZE(sb_hsize), - .HREADY(1'b0), - .HRESETn(reset_l), - .HADDR(sb_haddr), - .HBURST(sb_hburst), + .awvalid(1'b0), + .awready(), + .awaddr('0), + .awid('0), + .awlen('0), + .awburst('0), + .awsize('0), - // Outputs - .HREADYOUT(sb_hready), - .HRESP(sb_hresp), - .HRDATA(sb_hrdata[63:0]) + .wdata('0), + .wstrb('0), + .wvalid(1'b0), + .wready(), - ); + .bvalid(), + .bready(1'b0), + .bresp(), + .bid() +); +defparam lmem.TAGW =`RV_LSU_BUS_TAG; + +//axi_slv #(.TAGW(`RV_LSU_BUS_TAG)) lmem( +axi_slv lmem( + .aclk(core_clk), + .rst_l(rst_l), + .arvalid(lsu_axi_arvalid), + .arready(lsu_axi_arready), + .araddr(lsu_axi_araddr), + .arid(lsu_axi_arid), + .arlen(lsu_axi_arlen), + .arburst(lsu_axi_arburst), + .arsize(lsu_axi_arsize), + + .rvalid(lsu_axi_rvalid), + .rready(lsu_axi_rready), + .rdata(lsu_axi_rdata), + .rresp(lsu_axi_rresp), + .rid(lsu_axi_rid), + .rlast(lsu_axi_rlast), + + .awvalid(lsu_axi_awvalid), + .awready(lsu_axi_awready), + .awaddr(lsu_axi_awaddr), + .awid(lsu_axi_awid), + .awlen(lsu_axi_awlen), + .awburst(lsu_axi_awburst), + .awsize(lsu_axi_awsize), + + .wdata(lsu_axi_wdata), + .wstrb(lsu_axi_wstrb), + .wvalid(lsu_axi_wvalid), + .wready(lsu_axi_wready), + + .bvalid(lsu_axi_bvalid), + .bready(lsu_axi_bready), + .bresp(lsu_axi_bresp), + .bid(lsu_axi_bid) +); +`endif + +task preload_iccm; +bit[31:0] data; +bit[31:0] addr, eaddr, saddr, faddr; +int adr; +/* +addresses: + 0xffec - ICCM start address to load + 0xfff0 - ICCM end address to load + 0xfff4 - imem start address +*/ + +addr = 'hffec; +saddr = {lmem.mem[addr+3],lmem.mem[addr+2],lmem.mem[addr+1],lmem.mem[addr]}; +if ( (saddr < `RV_ICCM_SADR) || (saddr > `RV_ICCM_EADR)) return; +`ifndef RV_ICCM_ENABLE + $display("********************************************************"); + $display("ICCM preload: there is no ICCM in SweRV, terminating !!!"); + $display("********************************************************"); + $finish; +`endif +addr = 'hfff0; +eaddr = {lmem.mem[addr+3],lmem.mem[addr+2],lmem.mem[addr+1],lmem.mem[addr]}; +addr = 'hfff4; +faddr = {lmem.mem[addr+3],lmem.mem[addr+2],lmem.mem[addr+1],lmem.mem[addr]}; +$display("ICCM pre-load from %h to %h", saddr, eaddr); + +for(addr= saddr; addr <= eaddr; addr+=4) begin + adr = faddr & 'hffff; + data = {imem.mem[adr+3],imem.mem[adr+2],imem.mem[adr+1],imem.mem[adr]}; + slam_iccm_ram(addr, data == 0 ? 0 : {riscv_ecc32(data),data}); + faddr+=4; +end + +endtask + + +task preload_dccm; +bit[31:0] data; +bit[31:0] addr, eaddr; +int adr; +/* +addresses: + 0xfff8 - DCCM start address to load + 0xfffc - ICCM end address to load + 0x0 - lmem start addres to load from +*/ + +addr = 'hfff8; +eaddr = {lmem.mem[addr+3],lmem.mem[addr+2],lmem.mem[addr+1],lmem.mem[addr]}; +if (eaddr != `RV_DCCM_SADR) return; +`ifndef RV_DCCM_ENABLE + $display("********************************************************"); + $display("DCCM preload: there is no DCCM in SweRV, terminating !!!"); + $display("********************************************************"); + $finish; +`endif +addr = 'hfffc; +eaddr = {lmem.mem[addr+3],lmem.mem[addr+2],lmem.mem[addr+1],lmem.mem[addr]}; +$display("DCCM pre-load from %h to %h", `RV_DCCM_SADR, eaddr); + +for(addr=`RV_DCCM_SADR; addr <= eaddr; addr+=4) begin + adr = addr & 'hffff; + data = {lmem.mem[adr+3],lmem.mem[adr+2],lmem.mem[adr+1],lmem.mem[adr]}; + slam_dccm_ram(addr, data == 0 ? 0 : {riscv_ecc32(data),data}); +end + +endtask + +`define DRAM(bank) \ + rvtop.mem.Gen_dccm_enable.dccm.mem_bank[bank].dccm_bank.ram_core + +`define ICCM_PATH `RV_TOP.mem.iccm +`define IRAM0(bk) `ICCM_PATH.mem_bank[bk].iccm_bank_lo0.ram_core +`define IRAM1(bk) `ICCM_PATH.mem_bank[bk].iccm_bank_lo1.ram_core +`define IRAM2(bk) `ICCM_PATH.mem_bank[bk].iccm_bank_hi0.ram_core +`define IRAM3(bk) `ICCM_PATH.mem_bank[bk].iccm_bank_hi1.ram_core + + +task slam_iccm_ram(input [31:0] addr, input[38:0] data); +int bank, indx; +`ifdef RV_ICCM_ENABLE +bank = get_iccm_bank(addr, indx); +case(bank) +0: `IRAM0(0)[indx] = data; +1: `IRAM1(0)[indx] = data; +2: `IRAM2(0)[indx] = data; +3: `IRAM3(0)[indx] = data; +`ifdef RV_ICCM_NUM_BANKS_8 +4: `IRAM0(1)[indx] = data; +5: `IRAM1(1)[indx] = data; +6: `IRAM2(1)[indx] = data; +7: `IRAM3(1)[indx] = data; +`endif +`ifdef RV_ICCM_NUM_BANKS_16 +8: `IRAM0(2)[indx] = data; +9: `IRAM1(2)[indx] = data; +10: `IRAM2(2)[indx] = data; +11: `IRAM3(2)[indx] = data; +12: `IRAM0(3)[indx] = data; +13: `IRAM1(3)[indx] = data; +14: `IRAM2(3)[indx] = data; +15: `IRAM3(3)[indx] = data; +`endif +endcase +`endif +endtask + +task slam_dccm_ram(input [31:0] addr, input[38:0] data); +int bank, indx; +`ifdef RV_DCCM_ENABLE +bank = get_dccm_bank(addr, indx); +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 +endtask + +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[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 int 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 int addr, output int bank_idx); +`ifdef 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]); +`else + bank_idx = int'(addr[`RV_ICCM_BITS-1:6]); + return int'( addr[5:2]); +`endif +endfunction endmodule diff --git a/testbench/test_tb_top.cpp b/testbench/test_tb_top.cpp index 1ca4fcb..c88bb2b 100644 --- a/testbench/test_tb_top.cpp +++ b/testbench/test_tb_top.cpp @@ -1,12 +1,12 @@ // 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. @@ -22,62 +22,50 @@ #include "verilated_vcd_c.h" -// /* vluint64_t main_time = 0; -double sc_time_stamp () { +double sc_time_stamp () { return main_time; } -// */ -//int main(int argc, char* argv[]) { + int main(int argc, char** argv) { + std::cout << "\nVerilatorTB: Start of sim\n" << std::endl; + + // Check for +dumpon and remove it from argv + bool dumpWaves = false; + int newArgc = 0; + for (int i = 0; i < argc; ++i) + if (strcmp(argv[i], "+dumpon") == 0) + dumpWaves = true; + else + argv[newArgc++] = argv[i]; + argc = newArgc; - std::cout << "\nStart of sim\n" << std::endl; Verilated::commandArgs(argc, argv); Vtb_top* tb = new Vtb_top; - uint32_t clkCnt = 0; // init trace dump Verilated::traceEverOn(true); VerilatedVcdC* tfp = new VerilatedVcdC; tb->trace (tfp, 24); - tfp->open ("sim.vcd"); + if (dumpWaves) + tfp->open ("sim.vcd"); - // Simulate - for(auto i=0; i<200000; ++i){ - clkCnt++; - if(i<10) { - tb->reset_l = 0; - } else { - tb->reset_l = 1; - } - - for (auto clk=0; clk<2; clk++) { - tfp->dump (2*i+clk); + while(!Verilated::gotFinish()){ + if (dumpWaves) + tfp->dump (main_time); + main_time += 5; tb->core_clk = !tb->core_clk; tb->eval(); - } - - if (tb->finished) { - tfp->close(); - break; - } - } - for(auto i=0; i<100; ++i){ - clkCnt++; - for (auto clk=0; clk<2; clk++) { - tfp->dump (2*i+clk); - tb->core_clk = !tb->core_clk; - tb->eval(); - } - } - - std::cout << "\nEnd of sim" << std::endl; + if (dumpWaves) + tfp->close(); + + std::cout << "\nVerilatorTB: End of sim" << std::endl; exit(EXIT_SUCCESS); } diff --git a/tools/JSON.pm b/tools/JSON.pm index f57c555..6fb7a90 100644 --- a/tools/JSON.pm +++ b/tools/JSON.pm @@ -22,8 +22,8 @@ my $XS_Version = '2.27'; # XS and PP common methods my @PublicMethods = qw/ - ascii latin1 utf8 pretty indent space_before space_after relaxed canonical allow_nonref - allow_blessed convert_blessed filter_json_object filter_json_single_key_object + ascii latin1 utf8 pretty indent space_before space_after relaxed canonical allow_nonref + allow_blessed convert_blessed filter_json_object filter_json_single_key_object shrink max_depth max_size encode decode decode_prefix allow_unknown /; @@ -48,7 +48,7 @@ my $_UNIV_CONV_BLESSED = 0; my $_USSING_bpPP = 0; -# Check the environment variable to decide worker module. +# Check the environment variable to decide worker module. unless ($JSON::Backend) { $JSON::DEBUG and Carp::carp("Check used worker module..."); @@ -609,35 +609,35 @@ JSON - JSON (JavaScript Object Notation) encoder/decoder =head1 SYNOPSIS use JSON; # imports encode_json, decode_json, to_json and from_json. - + # simple and fast interfaces (expect/generate UTF-8) - + $utf8_encoded_json_text = encode_json $perl_hash_or_arrayref; $perl_hash_or_arrayref = decode_json $utf8_encoded_json_text; - + # OO-interface - + $json = JSON->new->allow_nonref; - + $json_text = $json->encode( $perl_scalar ); $perl_scalar = $json->decode( $json_text ); - + $pretty_printed = $json->pretty->encode( $perl_scalar ); # pretty-printing - + # If you want to use PP only support features, call with '-support_by_pp' # When XS unsupported feature is enable, using PP (de|en)code instead of XS ones. - + use JSON -support_by_pp; - + # option-acceptable interfaces (expect/generate UNICODE by default) - + $json_text = to_json( $perl_scalar, { ascii => 1, pretty => 1 } ); $perl_scalar = from_json( $json_text, { utf8 => 1 } ); - + # Between (en|de)code_json and (to|from)_json, if you want to write # a code which communicates to an outer world (encoded in UTF-8), # recommend to use (en|de)code_json. - + =head1 VERSION 2.53 @@ -866,7 +866,7 @@ with C enable. And the decoded result will contain UNICODE characters. my $json = JSON->new->utf8; my $json_text = CGI->new->param( 'json_data' ); my $perl_scalar = $json->decode( $json_text ); - + # from file content local $/; open( my $fh, '<', 'json.data' ); @@ -880,7 +880,7 @@ If an outer data is not encoded in UTF-8, firstly you should C it. open( my $fh, '<', 'json.data' ); my $encoding = 'cp932'; my $unicode_json_text = decode( $encoding, <$fh> ); # UNICODE - + # or you can write the below code. # # open( my $fh, "<:encoding($encoding)", 'json.data' ); @@ -918,7 +918,7 @@ Note that the resulted text is a UNICODE string but no problem to print it. # $perl_scalar contains $encoding encoded string values $unicode_json_text = $json->utf8(0)->encode( $perl_scalar ); - # or + # or $unicode_json_text = to_json( $perl_scalar ); # $unicode_json_text consists of characters less than 0x100 print $unicode_json_text; @@ -954,7 +954,7 @@ be chained: =head2 ascii $json = $json->ascii([$enable]) - + $enabled = $json->get_ascii If $enable is true (or missing), then the encode method will not generate characters outside @@ -974,7 +974,7 @@ See to L if the backend is PP. =head2 latin1 $json = $json->latin1([$enable]) - + $enabled = $json->get_latin1 If $enable is true (or missing), then the encode method will encode the resulting JSON @@ -989,7 +989,7 @@ unless required by the JSON syntax or other flags. =head2 utf8 $json = $json->utf8([$enable]) - + $enabled = $json->get_utf8 If $enable is true (or missing), then the encode method will encode the JSON result @@ -1036,7 +1036,7 @@ space length. =head2 indent $json = $json->indent([$enable]) - + $enabled = $json->get_indent If C<$enable> is true (or missing), then the C method will use a multiline @@ -1055,7 +1055,7 @@ With JSON::PP, you can also access C to change indent space lengt =head2 space_before $json = $json->space_before([$enable]) - + $enabled = $json->get_space_before If C<$enable> is true (or missing), then the C method will add an extra @@ -1074,7 +1074,7 @@ Example, space_before enabled, space_after and indent disabled: =head2 space_after $json = $json->space_after([$enable]) - + $enabled = $json->get_space_after If C<$enable> is true (or missing), then the C method will add an extra @@ -1095,7 +1095,7 @@ Example, space_before and indent disabled, space_after enabled: =head2 relaxed $json = $json->relaxed([$enable]) - + $enabled = $json->get_relaxed If C<$enable> is true (or missing), then C will accept some @@ -1145,7 +1145,7 @@ character, after which more white-space and comments are allowed. =head2 canonical $json = $json->canonical([$enable]) - + $enabled = $json->get_canonical If C<$enable> is true (or missing), then the C method will output JSON objects @@ -1165,7 +1165,7 @@ This setting has no effect when decoding JSON texts. =head2 allow_nonref $json = $json->allow_nonref([$enable]) - + $enabled = $json->get_allow_nonref If C<$enable> is true (or missing), then the C method can convert a @@ -1184,7 +1184,7 @@ JSON object or array. =head2 allow_unknown $json = $json->allow_unknown ([$enable]) - + $enabled = $json->get_allow_unknown If $enable is true (or missing), then "encode" will *not* throw an @@ -1203,7 +1203,7 @@ partner. =head2 allow_blessed $json = $json->allow_blessed([$enable]) - + $enabled = $json->get_allow_blessed If C<$enable> is true (or missing), then the C method will not @@ -1220,7 +1220,7 @@ exception when it encounters a blessed object. =head2 convert_blessed $json = $json->convert_blessed([$enable]) - + $enabled = $json->get_convert_blessed If C<$enable> is true (or missing), then C, upon encountering a @@ -1353,7 +1353,7 @@ into the corresponding C<< $WIDGET{} >> object: =head2 shrink $json = $json->shrink([$enable]) - + $enabled = $json->get_shrink With JSON::XS, this flag resizes strings generated by either @@ -1373,7 +1373,7 @@ See to L and L. =head2 max_depth $json = $json->max_depth([$maximum_nesting_depth]) - + $max_depth = $json->get_max_depth Sets the maximum nesting level (default C<512>) accepted while encoding @@ -1402,7 +1402,7 @@ See L for more info on why this is useful. =head2 max_size $json = $json->max_size([$maximum_string_size]) - + $max_size = $json->get_max_size Set the maximum length a JSON text may have (in bytes) where decoding is @@ -1503,9 +1503,9 @@ The following methods implement this incremental parser. =head2 incr_parse $json->incr_parse( [$string] ) # void context - + $obj_or_undef = $json->incr_parse( [$string] ) # scalar context - + @obj_or_empty = $json->incr_parse( [$string] ) # list context This is the central parsing function. It can both append new text and @@ -1596,9 +1596,9 @@ If you use C with additonal C<-support_by_pp>, some methods are available even with JSON::XS. See to L. BEING { $ENV{PERL_JSON_BACKEND} = 'JSON::XS' } - + use JSON -support_by_pp; - + my $json = new JSON; $json->allow_nonref->escape_slash->encode("/"); @@ -1762,7 +1762,7 @@ represent most decimal fractions exactly, and when converting from and to floating point, C only guarantees precision up to but not including the leats significant bit. -If the backend is JSON::PP and C is enable, the big integers +If the backend is JSON::PP and C is enable, the big integers and the numeric can be optionally converted into L and L objects. @@ -1900,7 +1900,7 @@ error to pass those in. =item Big Number -If the backend is JSON::PP and C is enable, +If the backend is JSON::PP and C is enable, C converts C objects and C objects into JSON numbers. @@ -1935,13 +1935,13 @@ returned objects should not be modified. To check the backend module, there are some methods - C, C and C. JSON->backend; # 'JSON::XS' or 'JSON::PP' - + JSON->backend->is_pp: # 0 or 1 - + JSON->backend->is_xs: # 1 or 0 - + $json->is_xs; # 1 or 0 - + $json->is_pp; # 0 or 1 @@ -2164,7 +2164,7 @@ If you want to use with your own sort routine, check the C method. (Only with JSON::PP, even if C<-support_by_pp> is used currently.) $json->sort_by($sort_routine_ref)->encode($perl_scalar) - + $json->sort_by(sub { $JSON::PP::a <=> $JSON::PP::b })->encode($perl_scalar) Can't access C<$a> and C<$b> but C<$JSON::PP::a> and C<$JSON::PP::b>. @@ -2261,7 +2261,7 @@ The relese of this new version owes to the courtesy of Marc Lehmann. Copyright 2005-2011 by Makamaka Hannyaharamitu This library is free software; you can redistribute it and/or modify -it under the same terms as Perl itself. +it under the same terms as Perl itself. =cut diff --git a/tools/Makefile b/tools/Makefile index 74fcfe6..f20b124 100755 --- a/tools/Makefile +++ b/tools/Makefile @@ -1,12 +1,12 @@ # SPDX-License-Identifier: Apache-2.0 -# Copyright 2019 Western Digital Corporation or its affiliates. -# +# 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. @@ -20,110 +20,140 @@ $(error env var RV_ROOT does not point to a valid dir! Exiting!) endif # Allow snapshot override -ifeq ($(strip $(snapshot)),) - snapshot = default -endif +target = default +snapshot = $(target) # Allow tool override SWERV_CONFIG = ${RV_ROOT}/configs/swerv.config IRUN = irun VCS = vcs VERILATOR = verilator +VLOG = qverilog GCC_PREFIX = riscv64-unknown-elf +BUILD_DIR = snapshots/${snapshot} +TBDIR = ${RV_ROOT}/testbench -# Define test name -ifeq ($(strip $(ASM_TEST)),) - ASM_TEST = hello_world2 +# Define default test name +TEST = hello_world + +# Define default test directory +TEST_DIR = $(TBDIR)/asm +HEX_DIR = $(TBDIR)/hex + +ifdef debug + DEBUG_PLUS = +dumpon + IRUN_DEBUG = -access +rc + IRUN_DEBUG_RUN = -input ${RV_ROOT}/testbench/input.tcl + VCS_DEBUG = -debug_access endif -# Define test name -ifeq ($(strip $(ASM_TEST_DIR)),) - ASM_TEST_DIR = ${RV_ROOT}/testbench/asm +# provide specific link file +ifeq (,$(wildcard $(TEST_DIR)/$(TEST).ld)) + LINK = $(TBDIR)/link.ld +else + LINK = $(TEST_DIR)/$(TEST).ld endif -defines = ${RV_ROOT}/configs/snapshots/$(snapshot)/common_defines.vh ${RV_ROOT}/design/include/build.h ${RV_ROOT}/design/include/global.h ${RV_ROOT}/design/include/swerv_types.sv -includes = -I${RV_ROOT}/design/include -I${RV_ROOT}/design/lib -I${RV_ROOT}/design/dmi -I${RV_ROOT}/configs/snapshots/$(snapshot) +VPATH = $(TEST_DIR) $(BUILD_DIR) $(TBDIR) +TBFILES = $(TBDIR)/tb_top.sv $(TBDIR)/ahb_sif.sv + +defines = $(BUILD_DIR)/common_defines.vh ${RV_ROOT}/design/include/swerv_types.sv +includes = -I${RV_ROOT}/design/include -I${RV_ROOT}/design/lib -I${BUILD_DIR} # CFLAGS for verilator generated Makefiles. Without -std=c++11 it complains for `auto` variables CFLAGS += "-std=c++11" # Optimization for better performance; alternative is nothing for slower runtime (faster compiles) # -O2 for faster runtime (slower compiles), or -O for balance. -VERILATOR_MAKE_FLAGS = OPT_FAST="" +VERILATOR_MAKE_FLAGS = OPT_FAST="-O2" # Targets all: clean verilator clean: - rm -rf obj_dir *.hex build ${RV_ROOT}/configs/snapshots/$(snapshot) + rm -rf *.log *.s *.hex *.dis *.tbl irun* vcs* simv* snapshots swerv* \ + verilator* *.exe obj* *.o ucli.key vc_hdrs.h csrc *.csv -verilator: ${RV_ROOT}/configs/snapshots/$(snapshot)/common_defines.vh - echo '`undef ASSERT_ON' >> ${RV_ROOT}/configs/snapshots/$(snapshot)/common_defines.vh - $(VERILATOR) '-UASSERT_ON' --cc -CFLAGS ${CFLAGS} $(defines) $(includes) ${RV_ROOT}/configs/snapshots/$(snapshot)/common_defines.vh \ - -f ${RV_ROOT}/testbench/flist.verilator --top-module swerv_wrapper - $(MAKE) -C obj_dir/ -f Vswerv_wrapper.mk $(VERILATOR_MAKE_FLAGS) +# If define files do not exist, then run swerv.config. +${BUILD_DIR}/defines.h : + BUILD_PATH=${BUILD_DIR} ${SWERV_CONFIG} -target=$(target) $(CONF_PARAMS) -vcs: ${RV_ROOT}/configs/snapshots/$(snapshot)/common_defines.vh - $(VCS) -full64 -assert svaext -sverilog +define+RV_OPENSOURCE +error+500 +incdir+${RV_ROOT}/design/lib +incdir+${RV_ROOT}/design/include \ - ${RV_ROOT}/configs/snapshots/$(snapshot)/common_defines.vh \ - +incdir+${RV_ROOT}/design/dmi +incdir+${RV_ROOT}/configs/snapshots/$(snapshot) +libext+.v ${RV_ROOT}/configs/snapshots/$(snapshot)/common_defines.vh \ - $(defines)-f ${RV_ROOT}/testbench/flist.vcs -l vcs.log - -irun: ${RV_ROOT}/configs/snapshots/$(snapshot)/common_defines.vh - $(IRUN) -64bit -elaborate -ida -access +rw -q -sv -sysv -nowarn CUVIHR -nclibdirpath ${PWD} -nclibdirname swerv.build \ - -incdir ${RV_ROOT}/design/lib -incdir ${RV_ROOT}/design/include -incdir ${RV_ROOT}/design/dmi -vlog_ext +.vh+.h\ - $(defines) -incdir ${RV_ROOT}/configs/snapshots/$(snapshot) -f ${RV_ROOT}/testbench/flist.vcs -elaborate -snapshot default - -${RV_ROOT}/configs/snapshots/$(snapshot)/common_defines.vh: - $(SWERV_CONFIG) -snapshot=$(snapshot) - -verilator-run: program.hex - snapshot=ahb_lite - $(SWERV_CONFIG) -snapshot=$(snapshot) -ahb_lite - echo '`undef ASSERT_ON' >> ${RV_ROOT}/configs/snapshots/$(snapshot)/common_defines.vh - $(VERILATOR) '-UASSERT_ON' --cc -CFLAGS ${CFLAGS} $(defines) $(includes) ${RV_ROOT}/configs/snapshots/$(snapshot)/common_defines.vh \ - ${RV_ROOT}/testbench/tb_top.sv -I${RV_ROOT}/testbench \ - -f ${RV_ROOT}/testbench/flist.verilator --top-module tb_top -exe test_tb_top.cpp --trace --autoflush +verilator-build: ${TBFILES} ${BUILD_DIR}/defines.h test_tb_top.cpp + echo '`undef ASSERT_ON' >> ${BUILD_DIR}/common_defines.vh + $(VERILATOR) '-UASSERT_ON' --cc -CFLAGS ${CFLAGS} $(defines) $(includes) \ + -Wno-UNOPTFLAT \ + -I${RV_ROOT}/testbench \ + -f ${RV_ROOT}/testbench/flist \ + ${TBFILES} \ + --top-module tb_top -exe test_tb_top.cpp --trace --autoflush cp ${RV_ROOT}/testbench/test_tb_top.cpp obj_dir/ $(MAKE) -C obj_dir/ -f Vtb_top.mk $(VERILATOR_MAKE_FLAGS) - ./obj_dir/Vtb_top + touch verilator-build -irun-run: program.hex - snapshot=ahb_lite - $(SWERV_CONFIG) -snapshot=$(snapshot) -ahb_lite - $(IRUN) -64bit -ida -access +rw -q -sv -sysv -nowarn CUVIHR -nclibdirpath ${PWD} -nclibdirname swerv.build \ - -incdir ${RV_ROOT}/design/lib -incdir ${RV_ROOT}/design/include -incdir ${RV_ROOT}/design/dmi -vlog_ext +.vh+.h\ - $(defines) -top tb_top ${RV_ROOT}/testbench/tb_top.sv -I${RV_ROOT}/testbench ${RV_ROOT}/testbench/ahb_sif.sv\ - -incdir ${RV_ROOT}/configs/snapshots/$(snapshot) -f ${RV_ROOT}/testbench/flist.vcs -snapshot default +vcs-build: ${TBFILES} ${BUILD_DIR}/defines.h + $(VCS) -full64 -assert svaext -sverilog +error+500 \ + +incdir+${RV_ROOT}/design/lib \ + +incdir+${RV_ROOT}/design/include \ + +incdir+${BUILD_DIR} +libext+.v\ + $(defines) -f ${RV_ROOT}/testbench/flist\ + ${TBFILES} \ + -l vcs_compile.log + touch vcs-build -vcs-run: program.hex - snapshot=ahb_lite - $(SWERV_CONFIG) -snapshot=$(snapshot) -ahb_lite - cp ${RV_ROOT}/testbench/hex/*.hex . - $(VCS) -full64 -assert svaext -sverilog +define+RV_OPENSOURCE +error+500 +incdir+${RV_ROOT}/design/lib +incdir+${RV_ROOT}/design/include \ - ${RV_ROOT}/configs/snapshots/$(snapshot)/common_defines.vh \ - +incdir+${RV_ROOT}/design/dmi +incdir+${RV_ROOT}/configs/snapshots/$(snapshot) +libext+.v \ - $(defines) -f ${RV_ROOT}/testbench/flist.vcs ${RV_ROOT}/testbench/tb_top.sv -I${RV_ROOT}/testbench ${RV_ROOT}/testbench/ahb_sif.sv -l vcs.log - ./simv +irun-build: ${TBFILES} ${BUILD_DIR}/defines.h + $(IRUN) -64bit -elaborate $(IRUN_DEBUG) -q -sv -sysv -nowarn CUVIHR -nclibdirpath . -nclibdirname swerv.build \ + -incdir ${RV_ROOT}/design/lib -incdir ${RV_ROOT}/design/include -incdir ${BUILD_DIR} -vlog_ext +.vh+.h\ + $(defines) -f ${RV_ROOT}/testbench/flist\ + -top tb_top ${TBFILES} -I${RV_ROOT}/testbench \ + -elaborate -snapshot $(snapshot) + touch irun-build -program.hex: $(ASM_TEST_DIR)/$(ASM_TEST).s ${RV_ROOT}/configs/snapshots/$(snapshot)/common_defines.vh - @echo Building $(ASM_TEST) -ifeq ($(shell which $(GCC_PREFIX)-as),) - @echo " !!! No $(GCC_PREFIX)-as in path, using canned hex files !!" - cp ${RV_ROOT}/testbench/hex/*.hex . +verilator: program.hex verilator-build + ./obj_dir/Vtb_top ${DEBUG_PLUS} + +irun: program.hex irun-build + $(IRUN) -64bit -abvglobalfailurelimit 1 +lic_queue -licqueue -status -nclibdirpath . -nclibdirname swerv.build \ + -snapshot ${snapshot} -r ${snapshot} $(IRUN_DEBUG_RUN) + +vcs: program.hex vcs-build + ./simv $(DEBUG_PLUS) +vcs+lic+wait -l vcs.log + +vlog: program.hex ${TBFILES} ${BUILD_DIR}/defines.h + $(VLOG) -l vlog.log -sv -mfcu +incdir+${BUILD_DIR}+${RV_ROOT}/design/include+${RV_ROOT}/design/lib\ + $(defines) -f ${RV_ROOT}/testbench/flist ${TBFILES} -R ${DEBUG_PLUS} + +ifeq ($(shell which $(GCC_PREFIX)-gcc 2> /dev/null),) +program.hex: ${BUILD_DIR}/defines.h + @echo " !!! No $(GCC_PREFIX)-gcc in path, using canned hex files !!" + cp ${HEX_DIR}/$(TEST).program.hex program.hex + cp ${HEX_DIR}/$(TEST).data.hex data.hex else - cp $(ASM_TEST_DIR)/$(ASM_TEST).s . - $(GCC_PREFIX)-cpp -I${RV_ROOT}/configs/snapshots/$(snapshot) $(ASM_TEST).s > $(ASM_TEST).cpp.s - $(GCC_PREFIX)-as -march=rv32imc $(ASM_TEST).cpp.s -o $(ASM_TEST).o - $(GCC_PREFIX)-ld -m elf32lriscv --discard-none -T${RV_ROOT}/testbench/link.ld -o $(ASM_TEST).exe $(ASM_TEST).o - $(GCC_PREFIX)-objcopy -O verilog --only-section ".data*" --only-section ".rodata*" $(ASM_TEST).exe data.hex - $(GCC_PREFIX)-objcopy -O verilog --only-section ".text*" --set-start=0x0 $(ASM_TEST).exe program.hex - $(GCC_PREFIX)-objdump -dS $(ASM_TEST).exe > $(ASM_TEST).dis - $(GCC_PREFIX)-nm -f posix -C $(ASM_TEST).exe > $(ASM_TEST).tbl - @echo Completed building $(ASM_TEST) +ifneq (,$(wildcard $(TEST_DIR)/$(TEST).makefile)) +program.hex: + $(MAKE) -f $(TEST_DIR)/$(TEST).makefile +else +program.hex: $(TEST).o $(LINK) + @echo Building $(TEST) + $(GCC_PREFIX)-ld -m elf32lriscv --discard-none -T$(LINK) -o $(TEST).exe $(TEST).o + $(GCC_PREFIX)-objcopy -O verilog --only-section ".data*" --change-section-lma .data=0 $(TEST).exe data.hex + $(GCC_PREFIX)-objcopy -O verilog --only-section ".text*" $(TEST).exe program.hex + $(GCC_PREFIX)-objdump -S $(TEST).exe > $(TEST).dis + $(GCC_PREFIX)-nm -f posix -C $(TEST).exe > $(TEST).tbl + @echo Completed building $(TEST) + +%.o : %.s ${BUILD_DIR}/defines.h + $(GCC_PREFIX)-cpp -I${BUILD_DIR} $< > $(TEST).cpp.s + $(GCC_PREFIX)-as -march=rv32gc $(TEST).cpp.s -o $(TEST).o + +TEST_CFLAGS = -g -O3 -funroll-all-loops +ABI = -mabi=ilp32 -march=rv32imc + +%.o : %.c ${BUILD_DIR}/defines.h + $(GCC_PREFIX)-gcc -I${BUILD_DIR} ${TEST_CFLAGS} ${ABI} -nostdlib -c $< -o $@ endif - +endif + help: @echo Make sure the environment variable RV_ROOT is set. - @echo Possible targets: verilator vcs irun help clean all verilator-run irun-run vcs-run program.hex + @echo Possible targets: verilator vcs irun vlog help clean all verilator-build irun-build vcs-build program.hex -.PHONY: help clean verilator vcs irun verilator-run irun-run vcs-run +.PHONY: help clean verilator vcs irun vlog diff --git a/tools/addassign b/tools/addassign index f484e7c..c1b9998 100755 --- a/tools/addassign +++ b/tools/addassign @@ -16,26 +16,26 @@ foreach $line (@in) { if ($line=~/\#/) { next; } - if ($line=~/([^=]+)=/) { - $sig=$1; - $sig=~s/\s+//g; - printf("logic $sig;\n"); - } + if ($line=~/([^=]+)=/) { + $sig=$1; + $sig=~s/\s+//g; + printf("logic $sig;\n"); + } } foreach $line (@in) { if ($line=~/\#/) { next; } - if ($line=~/([^=]+)=\s*;/) { - printf("assign ${prefix}$1 = 1'b0;\n"); - next; - } + if ($line=~/([^=]+)=\s*;/) { + printf("assign ${prefix}$1 = 1'b0;\n"); + next; + } - if ($line=~/([^=]+)=\s*\(\s*\);/) { - printf("assign ${prefix}$1 = 1'b0;\n"); - next; - } + if ($line=~/([^=]+)=\s*\(\s*\);/) { + printf("assign ${prefix}$1 = 1'b0;\n"); + next; + } if ($line =~ /=/) { printf("assign ${prefix}$line"); } else { printf("$line"); } diff --git a/tools/coredecode b/tools/coredecode index b621e60..17e8263 100755 --- a/tools/coredecode +++ b/tools/coredecode @@ -5,9 +5,9 @@ use Getopt::Long; $helpusage = "placeholder"; GetOptions ('legal' => \$legal, - 'in=s' => \$in, - 'out=s' => \$out, - 'view=s' => \$view ) || die("$helpusage"); + 'in=s' => \$in, + 'out=s' => \$out, + 'view=s' => \$view ) || die("$helpusage"); if (!defined($in)) { die("must define -in=input"); } @@ -31,96 +31,96 @@ foreach $line (@in) { #printf("$pstate: $line"); - if ($line=~/^\s*\#/) { #printf("skip $line"); - next; } + if ($line=~/^\s*\#/) { #printf("skip $line"); + next; } if ($gather==1) { - if ($line=~/(\S+)/) { - if ($line=~/}/) { $gather=0; $position=0; next; } - $label=$1; - $label=~s/,//g; - if ($pstate==2) { - if (defined($INPUT{$CVIEW}{$label})) { die("input $label already defined"); } - $INPUT{$CVIEW}{$label}=$position++; - $INPUTLEN{$CVIEW}++; - $INPUTSTR{$CVIEW}.=" $label"; - } - elsif ($pstate==3) { - if (defined($OUTPUT{$CVIEW}{$label})) { die("output $label already defined"); } - $OUTPUT{$CVIEW}{$label}=$position++; - $OUTPUTLEN{$CVIEW}++; - $OUTPUTSTR{$CVIEW}.=" $label"; - } - else { die("unknown pstate $pstate in gather"); } - } + if ($line=~/(\S+)/) { + if ($line=~/}/) { $gather=0; $position=0; next; } + $label=$1; + $label=~s/,//g; + if ($pstate==2) { + if (defined($INPUT{$CVIEW}{$label})) { die("input $label already defined"); } + $INPUT{$CVIEW}{$label}=$position++; + $INPUTLEN{$CVIEW}++; + $INPUTSTR{$CVIEW}.=" $label"; + } + elsif ($pstate==3) { + if (defined($OUTPUT{$CVIEW}{$label})) { die("output $label already defined"); } + $OUTPUT{$CVIEW}{$label}=$position++; + $OUTPUTLEN{$CVIEW}++; + $OUTPUTSTR{$CVIEW}.=" $label"; + } + else { die("unknown pstate $pstate in gather"); } + } } if ($line=~/^.definition/) { - $pstate=1; next; + $pstate=1; next; } if ($pstate==1) { # definition - if ($line!~/^.output/) { - if ($line=~/(\S+)\s*=\s*(\S+)/) { - $key=$1; $value=$2; - $value=~s/\./-/g; - $value=~s/\[//g; - $value=~s/\]//g; - $DEFINITION{$key}=$value; - } - } - else { $pstate=2; next; } + if ($line!~/^.output/) { + if ($line=~/(\S+)\s*=\s*(\S+)/) { + $key=$1; $value=$2; + $value=~s/\./-/g; + $value=~s/\[//g; + $value=~s/\]//g; + $DEFINITION{$key}=$value; + } + } + else { $pstate=2; next; } } if ($line=~/^.input/) { - $pstate=2; next; + $pstate=2; next; } if ($pstate==2) { # input - if ($line=~/(\S+)\s*=\s*\{/) { - $CVIEW=$1; $gather=1; next; - } + if ($line=~/(\S+)\s*=\s*\{/) { + $CVIEW=$1; $gather=1; next; + } } if ($line=~/^.output/) { - $pstate=3; next; + $pstate=3; next; } if ($pstate==3) { # output - if ($line=~/(\S+)\s*=\s*\{/) { - $CVIEW=$1; $gather=1; next; - } + if ($line=~/(\S+)\s*=\s*\{/) { + $CVIEW=$1; $gather=1; next; + } } if ($line=~/^.decode/) { - $pstate=4; next; + $pstate=4; next; } if ($pstate==4) { # decode - if ($line=~/([^\[]+)\[([^\]]+)\]\s+=\s+\{([^\}]+)\}/) { - $dview=$1; $inst=$2; $body=$3; - $dview=~s/\s+//g; - $inst=~s/\s+//g; - #printf("$dview $inst $body\n"); - if ($inst=~/([^\{]+)\{([^-]+)-([^\}]+)\}/) { - $base=$1; $lo=$2; $hi=$3; - $hi++; - for ($i=0; $i<$TIMEOUT && $lo ne $hi; $i++) { - #printf("decode $dview $base$lo\n"); + if ($line=~/([^\[]+)\[([^\]]+)\]\s+=\s+\{([^\}]+)\}/) { + $dview=$1; $inst=$2; $body=$3; + $dview=~s/\s+//g; + $inst=~s/\s+//g; + #printf("$dview $inst $body\n"); + if ($inst=~/([^\{]+)\{([^-]+)-([^\}]+)\}/) { + $base=$1; $lo=$2; $hi=$3; + $hi++; + for ($i=0; $i<$TIMEOUT && $lo ne $hi; $i++) { + #printf("decode $dview $base$lo\n"); - $expand=$base.$lo; - if (!defined($DEFINITION{$expand})) { die("could not find instruction definition for inst $expand"); } + $expand=$base.$lo; + if (!defined($DEFINITION{$expand})) { die("could not find instruction definition for inst $expand"); } - $DECODE{$dview}{$expand}=$body; - $lo++; - } - if ($i == $TIMEOUT) { die("timeout in decode expansion"); } - - } - else { - if (!defined($DEFINITION{$inst})) { die("could not find instruction definition for inst $inst"); } - $DECODE{$dview}{$inst}=$body; - } - } + $DECODE{$dview}{$expand}=$body; + $lo++; + } + if ($i == $TIMEOUT) { die("timeout in decode expansion"); } + + } + else { + if (!defined($DEFINITION{$inst})) { die("could not find instruction definition for inst $inst"); } + $DECODE{$dview}{$inst}=$body; + } + } } } @@ -160,25 +160,25 @@ else { $DEFAULT_TEMPLATE='0'x$OUTPUTLEN{$view}; foreach $inst (sort keys %{ $DECODE{$view} }) { - + $body=$DECODE{$view}{$inst}; @sigs=split(' ',$body); - + $template=$DEFAULT_TEMPLATE; foreach $sig (@sigs) { - if (!defined($OUTPUT{$view}{$sig})) { die("could not find output definition for sig $sig in view $view"); } - $position=$OUTPUT{$view}{$sig}; - substr($template,$position,1,1); + if (!defined($OUTPUT{$view}{$sig})) { die("could not find output definition for sig $sig in view $view"); } + $position=$OUTPUT{$view}{$sig}; + substr($template,$position,1,1); } # if (!defined($DEFINITION{$inst})) { die("could not find instruction defintion for inst $inst"); } printf("# $inst\n"); if (defined($legal)) { - printf("$DEFINITION{$inst} 1\n"); + printf("$DEFINITION{$inst} 1\n"); } else { - printf("$DEFINITION{$inst} $template\n"); + printf("$DEFINITION{$inst} $template\n"); } } diff --git a/tools/picmap b/tools/picmap index 83485b4..06df0d5 100755 --- a/tools/picmap +++ b/tools/picmap @@ -35,9 +35,9 @@ printf("end\n"); sub b2d { my ($v) = @_; - + $v = oct("0b" . $v); - + return($v); } @@ -48,11 +48,11 @@ sub d2b { $v = sprintf "%b",$v; if (length($v)<$LEN) { - $repeat=$LEN-length($v); - $v="0"x$repeat.$v; + $repeat=$LEN-length($v); + $v="0"x$repeat.$v; } elsif (length($v)>$LEN) { - $v=substr($v,length($v)-$LEN,$LEN); + $v=substr($v,length($v)-$LEN,$LEN); } return($v); diff --git a/tools/smalldiv b/tools/smalldiv index 3484100..48495be 100755 --- a/tools/smalldiv +++ b/tools/smalldiv @@ -8,7 +8,7 @@ $helpusage = "placeholder"; GetOptions ('len=s' => \$len, 'num=s' => \$num, - 'den=s' => \$den, + 'den=s' => \$den, 'skip' => \$skip) || die("$helpusage"); if (!defined($len)) { $len=8; } @@ -25,9 +25,9 @@ printf(".ob smallnum[3] smallnum[2] smallnum[1] smallnum[0]\n"); printf(".type fr\n"); for ($q=0; $q<16; $q++) { for ($m=0; $m<16; $m++) { - if ($m==0) { next; } - $result=int($q/$m); - printf("%s %s %s\n",d2bl($q,4),d2bl($m,4),d2bl($result,4)); + if ($m==0) { next; } + $result=int($q/$m); + printf("%s %s %s\n",d2bl($q,4),d2bl($m,4),d2bl($result,4)); } } @@ -49,20 +49,20 @@ for ($i=1; $i<=$LEN; $i++) { $signa = substr($a,0,1); - - + + $a = substr($a.$q,1,$LEN); # new a with q shifted in - + if ($signa==0) { $a=b2d($a)-b2d($m); } else { $a=b2d($a)+b2d($m); } - + $a=d2b($a); - - + + $signa = substr($a,0,1); if ($signa==0) { $q=substr($q,1,$LEN-1)."1"; } else { $q=substr($q,1,$LEN-1)."0"; } - + } @@ -80,9 +80,9 @@ else { printf("\n"); } sub b2d { my ($v) = @_; - + $v = oct("0b" . $v); - + return($v); } @@ -93,11 +93,11 @@ sub d2b { $v = sprintf "%b",$v; if (length($v)<$LEN) { - $repeat=$LEN-length($v); - $v="0"x$repeat.$v; + $repeat=$LEN-length($v); + $v="0"x$repeat.$v; } elsif (length($v)>$LEN) { - $v=substr($v,length($v)-$LEN,$LEN); + $v=substr($v,length($v)-$LEN,$LEN); } return($v); @@ -110,11 +110,11 @@ sub d2bl { $v = sprintf "%b",$v; if (length($v)<$LEN) { - $repeat=$LEN-length($v); - $v="0"x$repeat.$v; + $repeat=$LEN-length($v); + $v="0"x$repeat.$v; } elsif (length($v)>$LEN) { - $v=substr($v,length($v)-$LEN,$LEN); + $v=substr($v,length($v)-$LEN,$LEN); } return($v);