Version 1.5
This commit is contained in:
parent
790c48cd0b
commit
b65d4dd8f1
206
LICENSE
206
LICENSE
|
@ -1,201 +1,69 @@
|
||||||
Apache License
|
Apache License
|
||||||
Version 2.0, January 2004
|
Version 2.0, January 2004
|
||||||
http://www.apache.org/licenses/
|
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,
|
"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
|
||||||
and distribution as defined by Sections 1 through 9 of this document.
|
|
||||||
|
|
||||||
"Licensor" shall mean the copyright owner or entity authorized by
|
"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
|
||||||
the copyright owner that is granting the License.
|
|
||||||
|
|
||||||
"Legal Entity" shall mean the union of the acting entity and all
|
"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.
|
||||||
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
|
"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
|
||||||
exercising permissions granted by this License.
|
|
||||||
|
|
||||||
"Source" form shall mean the preferred form for making modifications,
|
"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
|
||||||
including but not limited to software source code, documentation
|
|
||||||
source, and configuration files.
|
|
||||||
|
|
||||||
"Object" form shall mean any form resulting from mechanical
|
"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.
|
||||||
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
|
"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).
|
||||||
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
|
"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.
|
||||||
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
|
"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."
|
||||||
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
|
"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.
|
||||||
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
|
2. Grant of Copyright License.
|
||||||
this License, each Contributor hereby grants to You a perpetual,
|
|
||||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
||||||
copyright license to reproduce, prepare Derivative Works of,
|
|
||||||
publicly display, publicly perform, sublicense, and distribute the
|
|
||||||
Work and such Derivative Works in Source or Object form.
|
|
||||||
|
|
||||||
3. Grant of Patent License. Subject to the terms and conditions of
|
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.
|
||||||
this License, each Contributor hereby grants to You a perpetual,
|
|
||||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
||||||
(except as stated in this section) patent license to make, have made,
|
|
||||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
|
||||||
where such license applies only to those patent claims licensable
|
|
||||||
by such Contributor that are necessarily infringed by their
|
|
||||||
Contribution(s) alone or by combination of their Contribution(s)
|
|
||||||
with the Work to which such Contribution(s) was submitted. If You
|
|
||||||
institute patent litigation against any entity (including a
|
|
||||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
|
||||||
or a Contribution incorporated within the Work constitutes direct
|
|
||||||
or contributory patent infringement, then any patent licenses
|
|
||||||
granted to You under this License for that Work shall terminate
|
|
||||||
as of the date such litigation is filed.
|
|
||||||
|
|
||||||
4. Redistribution. You may reproduce and distribute copies of the
|
3. Grant of Patent License.
|
||||||
Work or Derivative Works thereof in any medium, with or without
|
|
||||||
modifications, and in Source or Object form, provided that You
|
|
||||||
meet the following conditions:
|
|
||||||
|
|
||||||
(a) You must give any other recipients of the Work or
|
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.
|
||||||
Derivative Works a copy of this License; and
|
|
||||||
|
|
||||||
(b) You must cause any modified files to carry prominent notices
|
4. Redistribution.
|
||||||
stating that You changed the files; and
|
|
||||||
|
|
||||||
(c) You must retain, in the Source form of any Derivative Works
|
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:
|
||||||
that You distribute, all copyright, patent, trademark, and
|
|
||||||
attribution notices from the Source form of the Work,
|
|
||||||
excluding those notices that do not pertain to any part of
|
|
||||||
the Derivative Works; and
|
|
||||||
|
|
||||||
(d) If the Work includes a "NOTICE" text file as part of its
|
You must give any other recipients of the Work or Derivative Works a copy of this License; and
|
||||||
distribution, then any Derivative Works that You distribute must
|
|
||||||
include a readable copy of the attribution notices contained
|
|
||||||
within such NOTICE file, excluding those notices that do not
|
|
||||||
pertain to any part of the Derivative Works, in at least one
|
|
||||||
of the following places: within a NOTICE text file distributed
|
|
||||||
as part of the Derivative Works; within the Source form or
|
|
||||||
documentation, if provided along with the Derivative Works; or,
|
|
||||||
within a display generated by the Derivative Works, if and
|
|
||||||
wherever such third-party notices normally appear. The contents
|
|
||||||
of the NOTICE file are for informational purposes only and
|
|
||||||
do not modify the License. You may add Your own attribution
|
|
||||||
notices within Derivative Works that You distribute, alongside
|
|
||||||
or as an addendum to the NOTICE text from the Work, provided
|
|
||||||
that such additional attribution notices cannot be construed
|
|
||||||
as modifying the License.
|
|
||||||
|
|
||||||
You may add Your own copyright statement to Your modifications and
|
You must cause any modified files to carry prominent notices stating that You changed the files; and
|
||||||
may provide additional or different license terms and conditions
|
|
||||||
for use, reproduction, or distribution of Your modifications, or
|
|
||||||
for any such Derivative Works as a whole, provided Your use,
|
|
||||||
reproduction, and distribution of the Work otherwise complies with
|
|
||||||
the conditions stated in this License.
|
|
||||||
|
|
||||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
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
|
||||||
any Contribution intentionally submitted for inclusion in the Work
|
|
||||||
by You to the Licensor shall be under the terms and conditions of
|
|
||||||
this License, without any additional terms or conditions.
|
|
||||||
Notwithstanding the above, nothing herein shall supersede or modify
|
|
||||||
the terms of any separate license agreement you may have executed
|
|
||||||
with Licensor regarding such Contributions.
|
|
||||||
|
|
||||||
6. Trademarks. This License does not grant permission to use the trade
|
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.
|
||||||
names, trademarks, service marks, or product names of the Licensor,
|
|
||||||
except as required for reasonable and customary use in describing the
|
|
||||||
origin of the Work and reproducing the content of the NOTICE file.
|
|
||||||
|
|
||||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
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.
|
||||||
agreed to in writing, Licensor provides the Work (and each
|
|
||||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
||||||
implied, including, without limitation, any warranties or conditions
|
|
||||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
||||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
||||||
appropriateness of using or redistributing the Work and assume any
|
|
||||||
risks associated with Your exercise of permissions under this License.
|
|
||||||
|
|
||||||
8. Limitation of Liability. In no event and under no legal theory,
|
5. Submission of Contributions.
|
||||||
whether in tort (including negligence), contract, or otherwise,
|
|
||||||
unless required by applicable law (such as deliberate and grossly
|
|
||||||
negligent acts) or agreed to in writing, shall any Contributor be
|
|
||||||
liable to You for damages, including any direct, indirect, special,
|
|
||||||
incidental, or consequential damages of any character arising as a
|
|
||||||
result of this License or out of the use or inability to use the
|
|
||||||
Work (including but not limited to damages for loss of goodwill,
|
|
||||||
work stoppage, computer failure or malfunction, or any and all
|
|
||||||
other commercial damages or losses), even if such Contributor
|
|
||||||
has been advised of the possibility of such damages.
|
|
||||||
|
|
||||||
9. Accepting Warranty or Additional Liability. While redistributing
|
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.
|
||||||
the Work or Derivative Works thereof, You may choose to offer,
|
|
||||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
||||||
or other liability obligations and/or rights consistent with this
|
|
||||||
License. However, in accepting such obligations, You may act only
|
|
||||||
on Your own behalf and on Your sole responsibility, not on behalf
|
|
||||||
of any other Contributor, and only if You agree to indemnify,
|
|
||||||
defend, and hold each Contributor harmless for any liability
|
|
||||||
incurred by, or claims asserted against, such Contributor by reason
|
|
||||||
of your accepting any such warranty or additional liability.
|
|
||||||
|
|
||||||
END OF TERMS AND CONDITIONS
|
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
|
7. Disclaimer of Warranty.
|
||||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
|
||||||
replaced with your own identifying information. (Don't include
|
|
||||||
the brackets!) The text should be enclosed in the appropriate
|
|
||||||
comment syntax for the file format. We also recommend that a
|
|
||||||
file or class name and description of purpose be included on the
|
|
||||||
same "printed page" as the copyright notice for easier
|
|
||||||
identification within third-party archives.
|
|
||||||
|
|
||||||
Copyright [yyyy] [name of copyright owner]
|
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");
|
8. Limitation of Liability.
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
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
|
9. Accepting Warranty or Additional Liability.
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
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.
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
|
|
203
README.md
203
README.md
|
@ -1,7 +1,6 @@
|
||||||
# SweRV RISC-V Core<sup>TM</sup> 1.5 from Western Digital
|
# EH1 SweRV RISC-V Core<sup>TM</sup> 1.5 from Western Digital
|
||||||
|
|
||||||
This repository contains the SweRV Core<sup>TM</sup> 1.5 design RTL. The previous version can be found in [branch 1.4.](https://github.com/chipsalliance/Cores-SweRV/tree/branch1.4)
|
This repository contains the SweRV EH1.5 Core<sup>TM</sup> design RTL
|
||||||
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).
|
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
|
@ -13,24 +12,26 @@ Files under the [tools](tools/) directory may be available under a different lic
|
||||||
├── configs # Configurations Dir
|
├── configs # Configurations Dir
|
||||||
│ └── snapshots # Where generated configuration files are created
|
│ └── snapshots # Where generated configuration files are created
|
||||||
├── design # Design root dir
|
├── design # Design root dir
|
||||||
│ ├── dbg # Debugger
|
│ ├── dbg # Debugger
|
||||||
│ ├── dec # Decode, Registers and Exceptions
|
│ ├── dec # Decode, Registers and Exceptions
|
||||||
│ ├── dmi # DMI block
|
│ ├── dmi # DMI block
|
||||||
│ ├── exu # EXU (ALU/MUL/DIV)
|
│ ├── exu # EXU (ALU/MUL/DIV)
|
||||||
│ ├── ifu # Fetch & Branch Prediction
|
│ ├── ifu # Fetch & Branch Prediction
|
||||||
│ ├── include
|
│ ├── include
|
||||||
│ ├── lib
|
│ ├── lib
|
||||||
│ └── lsu # Load/Store
|
│ └── lsu # Load/Store
|
||||||
├── docs
|
├── docs
|
||||||
├── tools # Scripts/Makefiles
|
├── tools # Scripts/Makefiles
|
||||||
└── testbench # (Very) simple testbench
|
└── testbench # (Very) simple testbench
|
||||||
├── asm # Example assembly files
|
├── asm # Example test files
|
||||||
└── hex # Canned demo hex files
|
└── hex # Canned demo hex files
|
||||||
|
|
||||||
## Dependencies
|
## Dependencies
|
||||||
|
|
||||||
- Verilator **(3.926 or later)** must be installed on the system
|
- Verilator **(4.020 or later)** must be installed on the system if running with verilator
|
||||||
- If adding/removing instructions, espresso must be installed. Espresso is a logic minimization tool used in *tools/coredecode*.
|
- 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
|
## Quickstart guide
|
||||||
1. Clone the repository
|
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
|
`% $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`
|
`% $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.
|
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 :
|
This script derives the following consistent set of include files :
|
||||||
|
|
||||||
$RV_ROOT/configs/snapshots/default
|
$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
|
├── defines.h # #defines for C/assembly headers
|
||||||
├── pd_defines.vh # `defines for physical design
|
├── pd_defines.vh # `defines for physical design
|
||||||
├── perl_configs.pl # Perl %configs hash for scripting
|
├── 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
|
├── pic_map_auto.h # PIC memory map based on configure size
|
||||||
└── whisper.json # JSON file for swerv-iss
|
└── whisper.json # JSON file for swerv-iss
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### Building a model
|
### Building a model
|
||||||
1. Set the RV_ROOT environment variable to the root of the SweRV directory structure
|
|
||||||
|
|
||||||
`RV_ROOT = /path/to/swerv`
|
while in a work directory:
|
||||||
`export RV_ROOT`
|
|
||||||
|
|
||||||
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)*
|
*(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)*
|
*(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`
|
For example if `mybuild` is the name for the snapshot:
|
||||||
|
|
||||||
Snapshots are placed in `$RV_ROOT/configs/snapshots/<snapshot name>/` directory
|
set BUILD_PATH environment variable:
|
||||||
|
|
||||||
1. Build with **verilator**:
|
`setenv BUILD_PATH snapshots/mybuild`
|
||||||
|
|
||||||
`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
|
|
||||||
|
|
||||||
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 [<simulator>] [debug=1] [snapshot=<snapshot>] [target=<target>] [TEST=<test>] [TEST_DIR=<path_to_test_dir>] [CONF_PARAMS=<swerv.config option>]
|
||||||
|
|
||||||
|
where:
|
||||||
|
|
||||||
|
<simulator> - 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.
|
||||||
|
<target> - predefined CPU configurations 'default' ( by default), 'default_ahb', 'default_pd', 'high_perf'
|
||||||
|
TEST - allows to run a C (<test>.c) or assembly (<test>.s) test, hello_world is run by default
|
||||||
|
TEST_DIR - alternative to test source directory testbench/asm
|
||||||
|
<snapshot> - 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> [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 `<test_name>.ld` to build the test executable,
|
||||||
|
in the same directory with the test source.
|
||||||
|
|
||||||
|
User also can create a test specific makefile in form `<test_name>.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.
|
||||||
|
|
|
@ -8,7 +8,9 @@ Name | Description
|
||||||
swerv.config | Configuration script for SweRV
|
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.
|
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.
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,12 +1,12 @@
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
// Copyright 2019 Western Digital Corporation or its affiliates.
|
// Copyright 2019 Western Digital Corporation or its affiliates.
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "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 not use this file except in compliance with the License.
|
||||||
// You may obtain a copy of the License at
|
// You may obtain a copy of the License at
|
||||||
//
|
//
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
//
|
//
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
@ -16,10 +16,10 @@
|
||||||
// $Id$
|
// $Id$
|
||||||
//
|
//
|
||||||
// Function: Top level SWERV core file to control the debug mode
|
// 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.
|
// Send the commands/address. sends WrData and Recieve read Data.
|
||||||
// And then Resume the core to do the normal mode
|
// And then Resume the core to do the normal mode
|
||||||
// Author :
|
// Author :
|
||||||
//********************************************************************************
|
//********************************************************************************
|
||||||
module dbg (
|
module dbg (
|
||||||
// outputs to the core for command and data interface
|
// outputs to the core for command and data interface
|
||||||
|
@ -27,10 +27,10 @@ module dbg (
|
||||||
output logic [31:0] dbg_cmd_wrdata,
|
output logic [31:0] dbg_cmd_wrdata,
|
||||||
output logic dbg_cmd_valid,
|
output logic dbg_cmd_valid,
|
||||||
output logic dbg_cmd_write, // 1: write command, 0: read_command
|
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 [1:0] dbg_cmd_size, // size of the abstract mem access debug command
|
||||||
output logic dbg_core_rst_l, // core reset from dm
|
output logic dbg_core_rst_l, // core reset from dm
|
||||||
|
|
||||||
// inputs back from the core/dec
|
// inputs back from the core/dec
|
||||||
input logic [31:0] core_dbg_rddata,
|
input logic [31:0] core_dbg_rddata,
|
||||||
input logic core_dbg_cmd_done, // This will be treated like a valid signal
|
input logic core_dbg_cmd_done, // This will be treated like a valid signal
|
||||||
|
@ -39,25 +39,25 @@ module dbg (
|
||||||
// Signals to dma to get a bubble
|
// Signals to dma to get a bubble
|
||||||
output logic dbg_dma_bubble, // Debug needs a bubble to send a valid
|
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
|
input logic dma_dbg_ready, // DMA is ready to accept debug request
|
||||||
|
|
||||||
// interface with the rest of the core to halt/resume handshaking
|
// interface with the rest of the core to halt/resume handshaking
|
||||||
output logic dbg_halt_req, // This is a pulse
|
output logic dbg_halt_req, // This is a pulse
|
||||||
output logic dbg_resume_req, // Debug sends a resume requests. 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_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_mpc_halted_only, // Only halted due to MPC
|
||||||
input logic dec_tlu_resume_ack, // core sends back an ack for the resume (pulse)
|
input logic dec_tlu_resume_ack, // core sends back an ack for the resume (pulse)
|
||||||
|
|
||||||
// inputs from the JTAG
|
// inputs from the JTAG
|
||||||
input logic dmi_reg_en, // read or write
|
input logic dmi_reg_en, // read or write
|
||||||
input logic [6:0] dmi_reg_addr, // address of DM register
|
input logic [6:0] dmi_reg_addr, // address of DM register
|
||||||
input logic dmi_reg_wr_en, // write instruction
|
input logic dmi_reg_wr_en, // write instruction
|
||||||
input logic [31:0] dmi_reg_wdata, // write data
|
input logic [31:0] dmi_reg_wdata, // write data
|
||||||
// output
|
// output
|
||||||
output logic [31:0] dmi_reg_rdata, // read data
|
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
|
// AXI Write Channels
|
||||||
output logic sb_axi_awvalid,
|
output logic sb_axi_awvalid,
|
||||||
input logic sb_axi_awready,
|
input logic sb_axi_awready,
|
||||||
|
@ -71,19 +71,19 @@ module dbg (
|
||||||
output logic [3:0] sb_axi_awcache,
|
output logic [3:0] sb_axi_awcache,
|
||||||
output logic [2:0] sb_axi_awprot,
|
output logic [2:0] sb_axi_awprot,
|
||||||
output logic [3:0] sb_axi_awqos,
|
output logic [3:0] sb_axi_awqos,
|
||||||
|
|
||||||
output logic sb_axi_wvalid,
|
output logic sb_axi_wvalid,
|
||||||
input logic sb_axi_wready,
|
input logic sb_axi_wready,
|
||||||
output logic [63:0] sb_axi_wdata,
|
output logic [63:0] sb_axi_wdata,
|
||||||
output logic [7:0] sb_axi_wstrb,
|
output logic [7:0] sb_axi_wstrb,
|
||||||
output logic sb_axi_wlast,
|
output logic sb_axi_wlast,
|
||||||
|
|
||||||
input logic sb_axi_bvalid,
|
input logic sb_axi_bvalid,
|
||||||
output logic sb_axi_bready,
|
output logic sb_axi_bready,
|
||||||
input logic [1:0] sb_axi_bresp,
|
input logic [1:0] sb_axi_bresp,
|
||||||
input logic [`RV_SB_BUS_TAG-1:0] sb_axi_bid,
|
input logic [`RV_SB_BUS_TAG-1:0] sb_axi_bid,
|
||||||
|
|
||||||
// AXI Read Channels
|
// AXI Read Channels
|
||||||
output logic sb_axi_arvalid,
|
output logic sb_axi_arvalid,
|
||||||
input logic sb_axi_arready,
|
input logic sb_axi_arready,
|
||||||
output logic [`RV_SB_BUS_TAG-1:0] sb_axi_arid,
|
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 [3:0] sb_axi_arcache,
|
||||||
output logic [2:0] sb_axi_arprot,
|
output logic [2:0] sb_axi_arprot,
|
||||||
output logic [3:0] sb_axi_arqos,
|
output logic [3:0] sb_axi_arqos,
|
||||||
|
|
||||||
input logic sb_axi_rvalid,
|
input logic sb_axi_rvalid,
|
||||||
output logic sb_axi_rready,
|
output logic sb_axi_rready,
|
||||||
input logic [`RV_SB_BUS_TAG-1:0] sb_axi_rid,
|
input logic [`RV_SB_BUS_TAG-1:0] sb_axi_rid,
|
||||||
input logic [63:0] sb_axi_rdata,
|
input logic [63:0] sb_axi_rdata,
|
||||||
input logic [1:0] sb_axi_rresp,
|
input logic [1:0] sb_axi_rresp,
|
||||||
input logic sb_axi_rlast,
|
input logic sb_axi_rlast,
|
||||||
|
|
||||||
input logic dbg_bus_clk_en,
|
input logic dbg_bus_clk_en,
|
||||||
|
|
||||||
// general inputs
|
// general inputs
|
||||||
input logic clk,
|
input logic clk,
|
||||||
input logic free_clk,
|
input logic free_clk,
|
||||||
input logic rst_l,
|
input logic rst_l,
|
||||||
|
input logic dbg_rst_l,
|
||||||
input logic clk_override,
|
input logic clk_override,
|
||||||
input logic scan_mode
|
input logic scan_mode
|
||||||
);
|
);
|
||||||
|
|
||||||
`include "global.h"
|
`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 [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;
|
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;
|
state_t dbg_nxtstate;
|
||||||
logic dbg_state_en;
|
logic dbg_state_en;
|
||||||
// these are the registers that the debug module implements
|
// 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] 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] 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] abstractcs_reg; // bits implemted are [12] - busy and [10:8]= command error
|
||||||
logic [31:0] haltsum0_reg;
|
logic [31:0] haltsum0_reg;
|
||||||
logic [31:0] data0_reg;
|
logic [31:0] data0_reg;
|
||||||
logic [31:0] data1_reg;
|
logic [31:0] data1_reg;
|
||||||
|
|
||||||
// data 0
|
// data 0
|
||||||
logic [31:0] data0_din;
|
logic [31:0] data0_din;
|
||||||
logic data0_reg_wren, data0_reg_wren0, data0_reg_wren1;
|
logic data0_reg_wren, data0_reg_wren0, data0_reg_wren1;
|
||||||
// data 1
|
// data 1
|
||||||
logic [31:0] data1_din;
|
logic [31:0] data1_din;
|
||||||
logic data1_reg_wren, data1_reg_wren0, data1_reg_wren1;
|
logic data1_reg_wren, data1_reg_wren0, data1_reg_wren1;
|
||||||
// abstractcs
|
// abstractcs
|
||||||
|
@ -151,6 +152,8 @@ module dbg (
|
||||||
logic dmstatus_havereset_wren;
|
logic dmstatus_havereset_wren;
|
||||||
logic dmstatus_havereset_rst;
|
logic dmstatus_havereset_rst;
|
||||||
logic dmstatus_resumeack;
|
logic dmstatus_resumeack;
|
||||||
|
logic dmstatus_unavail;
|
||||||
|
logic dmstatus_running;
|
||||||
logic dmstatus_halted;
|
logic dmstatus_halted;
|
||||||
logic dmstatus_havereset;
|
logic dmstatus_havereset;
|
||||||
|
|
||||||
|
@ -160,34 +163,34 @@ module dbg (
|
||||||
logic command_wren;
|
logic command_wren;
|
||||||
// needed to send the read data back for dmi reads
|
// needed to send the read data back for dmi reads
|
||||||
logic [31:0] dmi_reg_rdata_din;
|
logic [31:0] dmi_reg_rdata_din;
|
||||||
|
|
||||||
sb_state_t sb_state;
|
sb_state_t sb_state;
|
||||||
sb_state_t sb_nxtstate;
|
sb_state_t sb_nxtstate;
|
||||||
logic sb_state_en;
|
logic sb_state_en;
|
||||||
|
|
||||||
//System bus section
|
//System bus section
|
||||||
logic sbcs_wren;
|
logic sbcs_wren;
|
||||||
logic sbcs_sbbusy_wren;
|
logic sbcs_sbbusy_wren;
|
||||||
logic sbcs_sbbusy_din;
|
logic sbcs_sbbusy_din;
|
||||||
logic sbcs_sbbusyerror_wren;
|
logic sbcs_sbbusyerror_wren;
|
||||||
logic sbcs_sbbusyerror_din;
|
logic sbcs_sbbusyerror_din;
|
||||||
|
|
||||||
logic sbcs_sberror_wren;
|
logic sbcs_sberror_wren;
|
||||||
logic [2:0] sbcs_sberror_din;
|
logic [2:0] sbcs_sberror_din;
|
||||||
logic sbcs_unaligned;
|
logic sbcs_unaligned;
|
||||||
logic sbcs_illegal_size;
|
logic sbcs_illegal_size;
|
||||||
|
|
||||||
// data
|
// data
|
||||||
logic sbdata0_reg_wren0;
|
logic sbdata0_reg_wren0;
|
||||||
logic sbdata0_reg_wren1;
|
logic sbdata0_reg_wren1;
|
||||||
logic sbdata0_reg_wren;
|
logic sbdata0_reg_wren;
|
||||||
logic [31:0] sbdata0_din;
|
logic [31:0] sbdata0_din;
|
||||||
|
|
||||||
logic sbdata1_reg_wren0;
|
logic sbdata1_reg_wren0;
|
||||||
logic sbdata1_reg_wren1;
|
logic sbdata1_reg_wren1;
|
||||||
logic sbdata1_reg_wren;
|
logic sbdata1_reg_wren;
|
||||||
logic [31:0] sbdata1_din;
|
logic [31:0] sbdata1_din;
|
||||||
|
|
||||||
logic sbaddress0_reg_wren0;
|
logic sbaddress0_reg_wren0;
|
||||||
logic sbaddress0_reg_wren1;
|
logic sbaddress0_reg_wren1;
|
||||||
logic sbaddress0_reg_wren;
|
logic sbaddress0_reg_wren;
|
||||||
|
@ -196,7 +199,7 @@ module dbg (
|
||||||
logic sbreadonaddr_access;
|
logic sbreadonaddr_access;
|
||||||
logic sbreadondata_access;
|
logic sbreadondata_access;
|
||||||
logic sbdata0wr_access;
|
logic sbdata0wr_access;
|
||||||
|
|
||||||
logic sb_axi_awvalid_q, sb_axi_awready_q;
|
logic sb_axi_awvalid_q, sb_axi_awready_q;
|
||||||
logic sb_axi_wvalid_q, sb_axi_wready_q;
|
logic sb_axi_wvalid_q, sb_axi_wready_q;
|
||||||
logic sb_axi_arvalid_q, sb_axi_arready_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 sb_axi_rvalid_q, sb_axi_rready_q;
|
||||||
logic [1:0] sb_axi_bresp_q, sb_axi_rresp_q;
|
logic [1:0] sb_axi_bresp_q, sb_axi_rresp_q;
|
||||||
logic [63:0] sb_axi_rdata_q;
|
logic [63:0] sb_axi_rdata_q;
|
||||||
|
|
||||||
logic [63:0] sb_bus_rdata;
|
logic [63:0] sb_bus_rdata;
|
||||||
|
|
||||||
//registers
|
//registers
|
||||||
|
@ -212,23 +215,23 @@ module dbg (
|
||||||
logic [31:0] sbaddress0_reg;
|
logic [31:0] sbaddress0_reg;
|
||||||
logic [31:0] sbdata0_reg;
|
logic [31:0] sbdata0_reg;
|
||||||
logic [31:0] sbdata1_reg;
|
logic [31:0] sbdata1_reg;
|
||||||
|
|
||||||
logic dbg_dm_rst_l;
|
logic dbg_dm_rst_l;
|
||||||
|
|
||||||
//clken
|
//clken
|
||||||
logic dbg_free_clken;
|
logic dbg_free_clken;
|
||||||
logic dbg_free_clk;
|
logic dbg_free_clk;
|
||||||
|
|
||||||
logic sb_free_clken;
|
logic sb_free_clken;
|
||||||
logic sb_free_clk;
|
logic sb_free_clk;
|
||||||
|
|
||||||
logic bus_clken;
|
logic bus_clken;
|
||||||
logic bus_clk;
|
logic bus_clk;
|
||||||
|
|
||||||
// clocking
|
// 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;
|
assign dbg_free_clken = dmi_reg_en | (dbg_state != IDLE) | dbg_state_en | dec_tlu_dbg_halted | clk_override;
|
||||||
|
|
||||||
// used for the system bus
|
// used for the system bus
|
||||||
assign sb_free_clken = dmi_reg_en | sb_state_en | (sb_state != SBIDLE) | clk_override;
|
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;
|
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 dbg_free_cgc (.en(dbg_free_clken), .l1clk(dbg_free_clk), .*);
|
||||||
rvoclkhdr sb_free_cgc (.en(sb_free_clken), .l1clk(sb_free_clk), .*);
|
rvoclkhdr sb_free_cgc (.en(sb_free_clken), .l1clk(sb_free_clk), .*);
|
||||||
rvclkhdr bus_cgc (.en(bus_clken), .l1clk(bus_clk), .*);
|
rvclkhdr bus_cgc (.en(bus_clken), .l1clk(bus_clk), .*);
|
||||||
|
|
||||||
// end clocking section
|
// end clocking section
|
||||||
|
|
||||||
// Reset logic
|
// Reset logic
|
||||||
assign dbg_dm_rst_l = rst_l & (dmcontrol_reg[0] | scan_mode);
|
assign dbg_dm_rst_l = dbg_rst_l & (dmcontrol_reg[0] | scan_mode);
|
||||||
assign dbg_core_rst_l = ~dmcontrol_reg[1];
|
assign dbg_core_rst_l = ~dmcontrol_reg[1];
|
||||||
|
|
||||||
// system bus register
|
// 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
|
// 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[31:29] = 3'b1;
|
||||||
assign sbcs_reg[28:23] = '0;
|
assign sbcs_reg[28:23] = '0;
|
||||||
assign sbcs_reg[11:5] = 7'h20;
|
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_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]) |
|
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)));
|
((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
|
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_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_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 #(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 #(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));
|
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]) |
|
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'b010) & (|sbaddress0_reg[1:0])) |
|
||||||
((sbcs_reg[19:17] == 3'b011) & (|sbaddress0_reg[2: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 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) |
|
assign sbaddress0_incr[3:0] = ({4{(sbcs_reg[19:17] == 3'h0)}} & 4'b0001) |
|
||||||
({4{(sbcs_reg[19:17] == 3'b001)}} & 4'b0010) |
|
({4{(sbcs_reg[19:17] == 3'h1)}} & 4'b0010) |
|
||||||
({4{(sbcs_reg[19:17] == 3'b010)}} & 4'b0100) |
|
({4{(sbcs_reg[19:17] == 3'h2)}} & 4'b0100) |
|
||||||
({4{(sbcs_reg[19:17] == 3'b100)}} & 4'b1000);
|
({4{(sbcs_reg[19:17] == 3'h3)}} & 4'b1000);
|
||||||
|
|
||||||
// sbdata
|
// 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 == 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_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 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_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 sbdata1_reg_wren = sbdata1_reg_wren0 | sbdata1_reg_wren1;
|
||||||
|
|
||||||
assign sbdata0_din[31:0] = ({32{sbdata0_reg_wren0}} & dmi_reg_wdata[31:0]) |
|
assign sbdata0_din[31:0] = ({32{sbdata0_reg_wren0}} & dmi_reg_wdata[31:0]) |
|
||||||
({32{sbdata0_reg_wren1}} & sb_bus_rdata[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]) |
|
assign sbdata1_din[31:0] = ({32{sbdata1_reg_wren0}} & dmi_reg_wdata[31:0]) |
|
||||||
({32{sbdata1_reg_wren1}} & sb_bus_rdata[63:32]);
|
({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_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));
|
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
|
// sbaddress
|
||||||
assign sbaddress0_reg_wren0 = dmi_reg_en & dmi_reg_wr_en & (dmi_reg_addr == 7'h39);
|
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_wren = sbaddress0_reg_wren0 | sbaddress0_reg_wren1;
|
||||||
assign sbaddress0_reg_din[31:0]= ({32{sbaddress0_reg_wren0}} & dmi_reg_wdata[31:0]) |
|
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));
|
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 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 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
|
// 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
|
// rest all the bits are zeroed out
|
||||||
// dmactive flop is reset based on core rst_l, all other flops use dm_rst_l
|
// 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_wren = (dmi_reg_addr == 7'h10) & dmi_reg_en & dmi_reg_wr_en;
|
||||||
|
assign dmcontrol_reg[29] = '0;
|
||||||
assign dmcontrol_reg[27:2] = '0;
|
assign 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 #(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(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));
|
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
|
// dmstatus register bits that are implemented
|
||||||
// [19:18]-havereset,[17:16]-resume ack, [9:8]-halted, [3:0]-version
|
// [19:18]-havereset,[17:16]-resume ack, [9:8]-halted, [3:0]-version
|
||||||
// rest all the bits are zeroed out
|
// rest all the bits are zeroed out
|
||||||
//assign dmstatus_wren = (dmi_reg_addr == 32'h11) & dmi_reg_en;
|
//assign dmstatus_wren = (dmi_reg_addr == 32'h11) & dmi_reg_en;
|
||||||
assign dmstatus_reg[31:20] = '0;
|
assign dmstatus_reg[31:20] = '0;
|
||||||
assign dmstatus_reg[19:18] = {2{dmstatus_havereset}};
|
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[7] = '1;
|
||||||
assign dmstatus_reg[6:4] = '0;
|
assign dmstatus_reg[6:4] = '0;
|
||||||
assign dmstatus_reg[17:16] = {2{dmstatus_resumeack}};
|
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[9:8] = {2{dmstatus_halted}};
|
||||||
assign dmstatus_reg[3:0] = 4'h2;
|
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_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_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));
|
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));
|
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));
|
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
|
// haltsum0 register
|
||||||
assign haltsum0_reg[31:1] = '0;
|
assign haltsum0_reg[31:1] = '0;
|
||||||
assign haltsum0_reg[0] = dmstatus_halted;
|
assign haltsum0_reg[0] = dmstatus_halted;
|
||||||
|
@ -343,37 +352,37 @@ module dbg (
|
||||||
assign abstractcs_reg[11] = '0;
|
assign abstractcs_reg[11] = '0;
|
||||||
assign abstractcs_reg[7:4] = '0;
|
assign abstractcs_reg[7:4] = '0;
|
||||||
assign abstractcs_reg[3:0] = 4'h2; // One data register
|
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_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_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_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 &
|
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'b001) & data1_reg[0]) |
|
||||||
((dmi_reg_wdata[22:20] == 3'b010) & (|data1_reg[1:0])) |
|
((dmi_reg_wdata[22:20] == 3'b010) & (|data1_reg[1:0])) |
|
||||||
dmi_reg_wdata[22] | (dmi_reg_wdata[22:20] == 3'b011)
|
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_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_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_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_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_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_sel4}} & 3'b111) | // unaligned abstract memory command
|
||||||
({3{abstractcs_error_sel5}} & ~dmi_reg_wdata[10:8] & abstractcs_reg[10:8]) | // W1C
|
({3{abstractcs_error_sel5}} & ~dmi_reg_wdata[10:8] & abstractcs_reg[10:8]) | // W1C
|
||||||
({3{~abstractcs_error_selor}} & abstractcs_reg[10:8]); // hold
|
({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));
|
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));
|
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 register - implemented all the bits in this register
|
||||||
// command[16] = 1: write, 0: read
|
// command[16] = 1: write, 0: read
|
||||||
assign command_wren = (dmi_reg_addr == 7'h17) & dmi_reg_en & dmi_reg_wr_en & (dbg_state == HALTED);
|
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));
|
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
|
// data0 reg
|
||||||
assign data0_reg_wren0 = (dmi_reg_en & dmi_reg_wr_en & (dmi_reg_addr == 7'h4) & (dbg_state == HALTED));
|
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];
|
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]) |
|
assign data0_din[31:0] = ({32{data0_reg_wren0}} & dmi_reg_wdata[31:0]) |
|
||||||
({32{data0_reg_wren1}} & core_dbg_rddata[31:0]);
|
({32{data0_reg_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));
|
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_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_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_reg_wren = data1_reg_wren0 | data1_reg_wren1;
|
||||||
|
|
||||||
assign data1_din[31:0] = ({32{data1_reg_wren0}} & dmi_reg_wdata[31:0]);
|
assign data1_din[31:0] = ({32{data1_reg_wren0}} & dmi_reg_wdata[31:0]);
|
||||||
//({32{data0_reg_wren1}} & core_dbg_rddata[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));
|
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;
|
dbg_state_en = 1'b0;
|
||||||
abstractcs_busy_wren = 1'b0;
|
abstractcs_busy_wren = 1'b0;
|
||||||
abstractcs_busy_din = 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
|
dbg_resume_req = 1'b0; // single pulse output to the core
|
||||||
|
|
||||||
case (dbg_state)
|
case (dbg_state)
|
||||||
IDLE: begin
|
IDLE: begin
|
||||||
dbg_nxtstate = (dmstatus_reg[9] | dec_tlu_mpc_halted_only) ? HALTED : HALTING; // initiate the halt command to the core
|
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_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] & ~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
|
//dbg_halt_req = dmcontrol_reg[31] & ~dec_tlu_debug_mode; // only when jtag has written the halt_req bit in the control
|
||||||
end
|
end
|
||||||
HALTING : begin
|
HALTING : begin
|
||||||
dbg_nxtstate = HALTED; // Goto HALTED once the core sends an ACK
|
dbg_nxtstate = dmcontrol_reg[1] ? IDLE : HALTED; // Goto HALTED once the core sends an ACK
|
||||||
dbg_state_en = dmstatus_reg[9]; // core indicates halted
|
dbg_state_en = dmstatus_reg[9] | dmcontrol_reg[1]; // core indicates halted
|
||||||
end
|
end
|
||||||
HALTED: begin
|
HALTED: begin
|
||||||
// wait for halted to go away before send to resume. Else start of new command
|
// 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
|
(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_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);
|
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_wren = dbg_state_en & (dbg_nxtstate == CMD_START); // write busy when a new command was written by jtag
|
||||||
abstractcs_busy_din = 1'b1;
|
abstractcs_busy_din = 1'b1;
|
||||||
dbg_resume_req = dbg_state_en & (dbg_nxtstate == RESUMING); // single cycle pulse to core if resuming
|
dbg_resume_req = dbg_state_en & (dbg_nxtstate == RESUMING); // single cycle pulse to core if resuming
|
||||||
end
|
end
|
||||||
CMD_START: begin
|
CMD_START: begin
|
||||||
dbg_nxtstate = (|abstractcs_reg[10:8]) ? CMD_DONE : CMD_WAIT; // new command sent to the core
|
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]);
|
dbg_state_en = dbg_cmd_valid | (|abstractcs_reg[10:8]) | dmcontrol_reg[1];
|
||||||
end
|
end
|
||||||
CMD_WAIT: begin
|
CMD_WAIT: begin
|
||||||
dbg_nxtstate = CMD_DONE;
|
dbg_nxtstate = dmcontrol_reg[1] ? IDLE : CMD_DONE;
|
||||||
dbg_state_en = core_dbg_cmd_done; // go to done state for one cycle after completing current command
|
dbg_state_en = core_dbg_cmd_done | dmcontrol_reg[1]; // go to done state for one cycle after completing current command
|
||||||
end
|
end
|
||||||
CMD_DONE: begin
|
CMD_DONE: begin
|
||||||
dbg_nxtstate = HALTED;
|
dbg_nxtstate = dmcontrol_reg[1] ? IDLE : HALTED;
|
||||||
dbg_state_en = 1'b1;
|
dbg_state_en = 1'b1;
|
||||||
abstractcs_busy_wren = dbg_state_en; // remove the busy bit from the abstracts ( bit 12 )
|
abstractcs_busy_wren = dbg_state_en; // remove the busy bit from the abstracts ( bit 12 )
|
||||||
abstractcs_busy_din = 1'b0;
|
abstractcs_busy_din = 1'b0;
|
||||||
end
|
end
|
||||||
RESUMING : begin
|
RESUMING : begin
|
||||||
dbg_nxtstate = IDLE;
|
dbg_nxtstate = IDLE;
|
||||||
dbg_state_en = dmstatus_reg[17]; // resume ack has been updated in the dmstatus register
|
dbg_state_en = dmstatus_reg[17] | dmcontrol_reg[1]; // resume ack has been updated in the dmstatus register
|
||||||
end
|
end
|
||||||
default : begin
|
default : begin
|
||||||
dbg_nxtstate = IDLE;
|
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]) |
|
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'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'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'h17}} & command_reg[31:0]) |
|
||||||
({32{dmi_reg_addr == 7'h40}} & haltsum0_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'h38}} & sbcs_reg[31:0]) |
|
||||||
({32{dmi_reg_addr == 7'h39}} & sbaddress0_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'h3c}} & sbdata0_reg[31:0]) |
|
||||||
({32{dmi_reg_addr == 7'h3d}} & sbdata1_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
|
// 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));
|
// 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));
|
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
|
// 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_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_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_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_type[1:0] = (command_reg[31:24] == 8'h2) ? 2'b10 : {1'b0, (command_reg[15:12] == 4'b0)};
|
||||||
assign dbg_cmd_size[1:0] = command_reg[21:20];
|
assign dbg_cmd_size[1:0] = command_reg[21:20];
|
||||||
|
|
||||||
// Ask DMA to stop taking bus trxns since debug request is done
|
// 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);
|
assign dbg_dma_bubble = ((dbg_state == CMD_START) & ~(|abstractcs_reg[10:8])) | (dbg_state == CMD_WAIT);
|
||||||
|
|
||||||
// system bus FSM
|
// system bus FSM
|
||||||
always_comb begin
|
always_comb begin
|
||||||
sb_nxtstate = SBIDLE;
|
sb_nxtstate = SBIDLE;
|
||||||
|
@ -491,7 +500,7 @@ module dbg (
|
||||||
sbcs_sbbusy_din = 1'b0;
|
sbcs_sbbusy_din = 1'b0;
|
||||||
sbcs_sberror_wren = 1'b0;
|
sbcs_sberror_wren = 1'b0;
|
||||||
sbcs_sberror_din[2:0] = 3'b0;
|
sbcs_sberror_din[2:0] = 3'b0;
|
||||||
sbaddress0_reg_wren1 = 1'b0;
|
sbaddress0_reg_wren1 = 1'b0;
|
||||||
case (sb_state)
|
case (sb_state)
|
||||||
SBIDLE: begin
|
SBIDLE: begin
|
||||||
sb_nxtstate = sbdata0wr_access ? WAIT_WR : WAIT_RD;
|
sb_nxtstate = sbdata0wr_access ? WAIT_WR : WAIT_RD;
|
||||||
|
@ -500,7 +509,7 @@ module dbg (
|
||||||
sbcs_sbbusy_din = 1'b1;
|
sbcs_sbbusy_din = 1'b1;
|
||||||
sbcs_sberror_wren = sbcs_wren & (|dmi_reg_wdata[14:12]); // write to clear the error bits
|
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];
|
sbcs_sberror_din[2:0] = ~dmi_reg_wdata[14:12] & sbcs_reg[14:12];
|
||||||
end
|
end
|
||||||
WAIT_RD: begin
|
WAIT_RD: begin
|
||||||
sb_nxtstate = (sbcs_unaligned | sbcs_illegal_size) ? DONE : CMD_RD;
|
sb_nxtstate = (sbcs_unaligned | sbcs_illegal_size) ? DONE : CMD_RD;
|
||||||
sb_state_en = dbg_bus_clk_en | sbcs_unaligned | sbcs_illegal_size;
|
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_wren = sbcs_unaligned | sbcs_illegal_size;
|
||||||
sbcs_sberror_din[2:0] = sbcs_unaligned ? 3'b011 : 3'b100;
|
sbcs_sberror_din[2:0] = sbcs_unaligned ? 3'b011 : 3'b100;
|
||||||
end
|
end
|
||||||
CMD_RD : begin
|
CMD_RD : begin
|
||||||
sb_nxtstate = RSP_RD;
|
sb_nxtstate = RSP_RD;
|
||||||
sb_state_en = sb_axi_arvalid_q & sb_axi_arready_q & dbg_bus_clk_en;
|
sb_state_en = sb_axi_arvalid_q & sb_axi_arready_q & dbg_bus_clk_en;
|
||||||
end
|
end
|
||||||
CMD_WR : begin
|
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_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;
|
sb_state_en = ((sb_axi_awvalid_q & sb_axi_awready_q) | (sb_axi_wvalid_q & sb_axi_wready_q)) & dbg_bus_clk_en;
|
||||||
end
|
end
|
||||||
CMD_WR_ADDR : begin
|
CMD_WR_ADDR : begin
|
||||||
sb_nxtstate = RSP_WR;
|
sb_nxtstate = RSP_WR;
|
||||||
sb_state_en = sb_axi_awvalid_q & sb_axi_awready_q & dbg_bus_clk_en;
|
sb_state_en = sb_axi_awvalid_q & sb_axi_awready_q & dbg_bus_clk_en;
|
||||||
end
|
end
|
||||||
CMD_WR_DATA : begin
|
CMD_WR_DATA : begin
|
||||||
sb_nxtstate = RSP_WR;
|
sb_nxtstate = RSP_WR;
|
||||||
sb_state_en = sb_axi_wvalid_q & sb_axi_wready_q & dbg_bus_clk_en;
|
sb_state_en = sb_axi_wvalid_q & sb_axi_wready_q & dbg_bus_clk_en;
|
||||||
end
|
end
|
||||||
RSP_RD: begin
|
RSP_RD: begin
|
||||||
sb_nxtstate = DONE;
|
sb_nxtstate = DONE;
|
||||||
sb_state_en = sb_axi_rvalid_q & sb_axi_rready_q & dbg_bus_clk_en;
|
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_wren = sb_state_en & sb_axi_rresp_q[1];
|
||||||
sbcs_sberror_din[2:0] = 3'b010;
|
sbcs_sberror_din[2:0] = 3'b010;
|
||||||
end
|
end
|
||||||
RSP_WR: begin
|
RSP_WR: begin
|
||||||
sb_nxtstate = DONE;
|
sb_nxtstate = DONE;
|
||||||
sb_state_en = sb_axi_bvalid_q & sb_axi_bready_q & dbg_bus_clk_en;
|
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_wren = sb_state_en & sb_axi_bresp_q[1];
|
||||||
sbcs_sberror_din[2:0] = 3'b010;
|
sbcs_sberror_din[2:0] = 3'b010;
|
||||||
end
|
end
|
||||||
DONE: begin
|
DONE: begin
|
||||||
sb_nxtstate = SBIDLE;
|
sb_nxtstate = SBIDLE;
|
||||||
sb_state_en = 1'b1;
|
sb_state_en = 1'b1;
|
||||||
sbcs_sbbusy_wren = 1'b1; // reset the single read
|
sbcs_sbbusy_wren = 1'b1; // reset the single read
|
||||||
sbcs_sbbusy_din = 1'b0;
|
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
|
end
|
||||||
default : begin
|
default : begin
|
||||||
sb_nxtstate = SBIDLE;
|
sb_nxtstate = SBIDLE;
|
||||||
sb_state_en = 1'b0;
|
sb_state_en = 1'b0;
|
||||||
sbcs_sbbusy_wren = 1'b0;
|
sbcs_sbbusy_wren = 1'b0;
|
||||||
sbcs_sbbusy_din = 1'b0;
|
sbcs_sbbusy_din = 1'b0;
|
||||||
sbcs_sberror_wren = 1'b0;
|
sbcs_sberror_wren = 1'b0;
|
||||||
sbcs_sberror_din[2:0] = 3'b0;
|
sbcs_sberror_din[2:0] = 3'b0;
|
||||||
sbaddress0_reg_wren1 = 1'b0;
|
sbaddress0_reg_wren1 = 1'b0;
|
||||||
end
|
end
|
||||||
endcase
|
endcase
|
||||||
end // always_comb begin
|
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));
|
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), .*);
|
//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), .*);
|
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_awburst[1:0] = 2'b01;
|
||||||
assign sb_axi_awqos[3:0] = '0;
|
assign sb_axi_awqos[3:0] = '0;
|
||||||
assign sb_axi_awlock = '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_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]}}) |
|
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]}}) |
|
({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_wlast = '1;
|
||||||
|
|
||||||
assign sb_axi_arvalid = (sb_state == CMD_RD) & ~(sb_axi_arvalid_q & sb_axi_arready_q);
|
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_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_arprot[2:0] = '0;
|
||||||
assign sb_axi_arcache[3:0] = 4'b0;
|
assign sb_axi_arcache[3:0] = 4'b0;
|
||||||
assign sb_axi_arregion[3:0] = sbaddress0_reg[31:28];
|
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'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'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]);
|
({64{sbcs_reg[19:17] == 3'h3}} & sb_axi_rdata_q[63:0]);
|
||||||
|
|
||||||
`ifdef ASSERT_ON
|
`ifdef ASSERT_ON
|
||||||
// assertion.
|
// assertion.
|
||||||
// when the resume_ack is asserted then the dec_tlu_dbg_halted should be 0
|
// 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));
|
dm_check_resume_and_halted: assert property (@(posedge clk) disable iff(~rst_l) (~dec_tlu_resume_ack | ~dec_tlu_dbg_halted));
|
||||||
`endif
|
`endif
|
||||||
endmodule
|
endmodule
|
||||||
|
|
|
@ -116,24 +116,24 @@ c.swsp = [110...........10]
|
||||||
c.xor = [100011...01...01]
|
c.xor = [100011...01...01]
|
||||||
|
|
||||||
|
|
||||||
.input
|
.input
|
||||||
rv32c = {
|
rv32c = {
|
||||||
i[15]
|
i[15]
|
||||||
i[14]
|
i[14]
|
||||||
i[13]
|
i[13]
|
||||||
i[12]
|
i[12]
|
||||||
i[11]
|
i[11]
|
||||||
i[10]
|
i[10]
|
||||||
i[9]
|
i[9]
|
||||||
i[8]
|
i[8]
|
||||||
i[7]
|
i[7]
|
||||||
i[6]
|
i[6]
|
||||||
i[5]
|
i[5]
|
||||||
i[4]
|
i[4]
|
||||||
i[3]
|
i[3]
|
||||||
i[2]
|
i[2]
|
||||||
i[1]
|
i[1]
|
||||||
i[0]
|
i[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
.output
|
.output
|
||||||
|
@ -145,52 +145,52 @@ rv32c = {
|
||||||
rdprs1
|
rdprs1
|
||||||
rs2prs2
|
rs2prs2
|
||||||
rs2prd
|
rs2prd
|
||||||
uimm9_2
|
uimm9_2
|
||||||
ulwimm6_2
|
ulwimm6_2
|
||||||
ulwspimm7_2
|
ulwspimm7_2
|
||||||
rdeq2
|
rdeq2
|
||||||
rdeq1
|
rdeq1
|
||||||
rs1eq2
|
rs1eq2
|
||||||
sbroffset8_1
|
sbroffset8_1
|
||||||
simm9_4
|
simm9_4
|
||||||
simm5_0
|
simm5_0
|
||||||
sjaloffset11_1
|
sjaloffset11_1
|
||||||
sluimm17_12
|
sluimm17_12
|
||||||
uimm5_0
|
uimm5_0
|
||||||
uswimm6_2
|
uswimm6_2
|
||||||
uswspimm7_2
|
uswspimm7_2
|
||||||
o[31]
|
o[31]
|
||||||
o[30]
|
o[30]
|
||||||
o[29]
|
o[29]
|
||||||
o[28]
|
o[28]
|
||||||
o[27]
|
o[27]
|
||||||
o[26]
|
o[26]
|
||||||
o[25]
|
o[25]
|
||||||
o[24]
|
o[24]
|
||||||
o[23]
|
o[23]
|
||||||
o[22]
|
o[22]
|
||||||
o[21]
|
o[21]
|
||||||
o[20]
|
o[20]
|
||||||
o[19]
|
o[19]
|
||||||
o[18]
|
o[18]
|
||||||
o[17]
|
o[17]
|
||||||
o[16]
|
o[16]
|
||||||
o[15]
|
o[15]
|
||||||
o[14]
|
o[14]
|
||||||
o[13]
|
o[13]
|
||||||
o[12]
|
o[12]
|
||||||
o[11]
|
o[11]
|
||||||
o[10]
|
o[10]
|
||||||
o[9]
|
o[9]
|
||||||
o[8]
|
o[8]
|
||||||
o[7]
|
o[7]
|
||||||
o[6]
|
o[6]
|
||||||
o[5]
|
o[5]
|
||||||
o[4]
|
o[4]
|
||||||
o[3]
|
o[3]
|
||||||
o[2]
|
o[2]
|
||||||
o[1]
|
o[1]
|
||||||
o[0]
|
o[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
# assign rs2d[4:0] = i[6:2];
|
# assign rs2d[4:0] = i[6:2];
|
||||||
|
@ -199,7 +199,7 @@ rv32c = {
|
||||||
#
|
#
|
||||||
# assign rdpd[4:0] = {2'b01, i[9:7]};
|
# 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
|
.decode
|
||||||
|
|
||||||
|
|
|
@ -67,7 +67,7 @@ csr_perfvg = [001100100111]
|
||||||
csr_perfvh = [001100101...]
|
csr_perfvh = [001100101...]
|
||||||
csr_perfvi = [00110011....]
|
csr_perfvi = [00110011....]
|
||||||
|
|
||||||
.input
|
.input
|
||||||
|
|
||||||
csr = {
|
csr = {
|
||||||
dec_csr_rdaddr_d[11]
|
dec_csr_rdaddr_d[11]
|
||||||
|
@ -87,23 +87,23 @@ csr = {
|
||||||
.output
|
.output
|
||||||
|
|
||||||
csr = {
|
csr = {
|
||||||
csr_misa
|
csr_misa
|
||||||
csr_mvendorid
|
csr_mvendorid
|
||||||
csr_marchid
|
csr_marchid
|
||||||
csr_mimpid
|
csr_mimpid
|
||||||
csr_mhartid
|
csr_mhartid
|
||||||
csr_mstatus
|
csr_mstatus
|
||||||
csr_mtvec
|
csr_mtvec
|
||||||
csr_mip
|
csr_mip
|
||||||
csr_mie
|
csr_mie
|
||||||
csr_mcyclel
|
csr_mcyclel
|
||||||
csr_mcycleh
|
csr_mcycleh
|
||||||
csr_minstretl
|
csr_minstretl
|
||||||
csr_minstreth
|
csr_minstreth
|
||||||
csr_mscratch
|
csr_mscratch
|
||||||
csr_mepc
|
csr_mepc
|
||||||
csr_mcause
|
csr_mcause
|
||||||
csr_mtval
|
csr_mtval
|
||||||
csr_mrac
|
csr_mrac
|
||||||
csr_dmst
|
csr_dmst
|
||||||
csr_mdeau
|
csr_mdeau
|
||||||
|
@ -120,8 +120,8 @@ csr = {
|
||||||
csr_mcpc
|
csr_mcpc
|
||||||
csr_mfdc
|
csr_mfdc
|
||||||
csr_dpc
|
csr_dpc
|
||||||
csr_mtsel
|
csr_mtsel
|
||||||
csr_mtdata1
|
csr_mtdata1
|
||||||
csr_mtdata2
|
csr_mtdata2
|
||||||
csr_mhpmc3
|
csr_mhpmc3
|
||||||
csr_mhpmc4
|
csr_mhpmc4
|
||||||
|
@ -211,19 +211,19 @@ csr[ csr_mhpme6 ] = { csr_mhpme6 }
|
||||||
csr[ csr_micect ] = { csr_micect }
|
csr[ csr_micect ] = { csr_micect }
|
||||||
csr[ csr_miccmect ] = { csr_miccmect }
|
csr[ csr_miccmect ] = { csr_miccmect }
|
||||||
csr[ csr_mdccmect ] = { csr_mdccmect }
|
csr[ csr_mdccmect ] = { csr_mdccmect }
|
||||||
csr[ csr_dicawics ] = { csr_dicawics }
|
csr[ csr_dicawics ] = { csr_dicawics }
|
||||||
csr[ csr_dicad0 ] = { csr_dicad0 }
|
csr[ csr_dicad0 ] = { csr_dicad0 }
|
||||||
csr[ csr_dicad1 ] = { csr_dicad1 }
|
csr[ csr_dicad1 ] = { csr_dicad1 }
|
||||||
csr[ csr_dicago ] = { csr_dicago }
|
csr[ csr_dicago ] = { csr_dicago }
|
||||||
|
|
||||||
csr[ csr_perfva ] = { valid_only }
|
csr[ csr_perfva ] = { valid_only }
|
||||||
csr[ csr_perfvb ] = { valid_only }
|
csr[ csr_perfvb ] = { valid_only }
|
||||||
csr[ csr_perfvc ] = { valid_only }
|
csr[ csr_perfvc ] = { valid_only }
|
||||||
csr[ csr_perfvd ] = { valid_only }
|
csr[ csr_perfvd ] = { valid_only }
|
||||||
csr[ csr_perfve ] = { valid_only }
|
csr[ csr_perfve ] = { valid_only }
|
||||||
csr[ csr_perfvf ] = { valid_only }
|
csr[ csr_perfvf ] = { valid_only }
|
||||||
csr[ csr_perfvg ] = { valid_only }
|
csr[ csr_perfvg ] = { valid_only }
|
||||||
csr[ csr_perfvh ] = { valid_only }
|
csr[ csr_perfvh ] = { valid_only }
|
||||||
csr[ csr_perfvi ] = { valid_only }
|
csr[ csr_perfvi ] = { valid_only }
|
||||||
|
|
||||||
.end
|
.end
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
// Copyright 2019 Western Digital Corporation or its affiliates.
|
// Copyright 2019 Western Digital Corporation or its affiliates.
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "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 not use this file except in compliance with the License.
|
||||||
// You may obtain a copy of the License at
|
// You may obtain a copy of the License at
|
||||||
//
|
//
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
//
|
//
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
@ -14,19 +14,19 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
// dec: decode unit - decode, bypassing, ARF, interrupts
|
// dec: decode unit - decode, bypassing, ARF, interrupts
|
||||||
//
|
//
|
||||||
//********************************************************************************
|
//********************************************************************************
|
||||||
// $Id$
|
// $Id$
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// Function: Decode
|
// Function: Decode
|
||||||
// Comments: Decode, dependency scoreboard, ARF
|
// Comments: Decode, dependency scoreboard, ARF
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// A -> D -> EX1 ... WB
|
// A -> D -> EX1 ... WB
|
||||||
//
|
//
|
||||||
//********************************************************************************
|
//********************************************************************************
|
||||||
|
|
||||||
module dec
|
module dec
|
||||||
import swerv_types::*;
|
import swerv_types::*;
|
||||||
(
|
(
|
||||||
|
@ -36,12 +36,12 @@ module dec
|
||||||
|
|
||||||
|
|
||||||
output logic dec_pause_state_cg, // pause state for clock-gating
|
output logic dec_pause_state_cg, // pause state for clock-gating
|
||||||
|
|
||||||
input logic rst_l, // reset, active low
|
input logic rst_l, // reset, active low
|
||||||
input logic [31:1] rst_vec, // reset vector, from core pins
|
input logic [31:1] rst_vec, // reset vector, from core pins
|
||||||
|
|
||||||
input logic nmi_int, // NMI pin
|
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_halt_req, // Asynchronous Halt request to CPU
|
||||||
input logic i_cpu_run_req, // Asynchronous Restart 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_halt_ack, // Halt ack
|
||||||
output logic mpc_debug_run_ack, // Run ack
|
output logic mpc_debug_run_ack, // Run ack
|
||||||
output logic debug_brkpt_status, // debug breakpoint
|
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,
|
output logic dec_ib1_valid_eff_d,
|
||||||
|
|
||||||
input logic exu_pmu_i0_br_misp, // slot 0 branch misp
|
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_br_ataken, // slot 0 branch actual taken
|
||||||
input logic exu_pmu_i0_pc4, // slot 0 4 byte branch
|
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_misp, // slot 1 branch misp
|
||||||
input logic exu_pmu_i1_br_ataken, // slot 1 branch actual taken
|
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 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 [`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 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 [`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_valid, // valid nonblock load data back
|
||||||
input logic lsu_nonblock_load_data_error, // nonblock load bus error
|
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 [`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 [31:0] lsu_nonblock_load_data, // nonblock load data
|
||||||
|
|
||||||
input logic lsu_pmu_bus_trxn, // D side bus transaction
|
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_misaligned, // D side bus misaligned
|
||||||
input logic lsu_pmu_bus_error, // D side bus error
|
input logic lsu_pmu_bus_error, // D side bus error
|
||||||
input logic lsu_pmu_bus_busy, // D side bus busy
|
input logic lsu_pmu_bus_busy, // D side bus busy
|
||||||
input logic lsu_pmu_misaligned_dc3, // D side load or store misaligned
|
input logic lsu_pmu_misaligned_dc3, // D side load or store misaligned
|
||||||
|
|
||||||
input logic [1:0] ifu_pmu_instr_aligned, // aligned instructions
|
input logic [1:0] ifu_pmu_instr_aligned, // aligned instructions
|
||||||
input logic ifu_pmu_align_stall, // aligner stalled
|
input logic ifu_pmu_align_stall, // aligner stalled
|
||||||
input logic ifu_pmu_fetch_stall, // fetch unit stalled
|
input logic ifu_pmu_fetch_stall, // fetch unit stalled
|
||||||
input logic ifu_pmu_ic_miss, // icache miss
|
input logic ifu_pmu_ic_miss, // icache miss
|
||||||
input logic ifu_pmu_ic_hit, // icache hit
|
input logic ifu_pmu_ic_hit, // icache hit
|
||||||
input logic ifu_pmu_bus_error, // Instruction side bus error
|
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 ifu_pmu_bus_trxn, // Instruction side bus transaction
|
||||||
|
|
||||||
input logic [3:0] lsu_trigger_match_dc3,
|
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 [1:0] dbg_cmd_type, // command type
|
||||||
input logic [31:0] dbg_cmd_addr, // command address
|
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 [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_i0_icaf_f1, // i0 has access fault on second fetch group
|
||||||
input logic ifu_i1_icaf_f1,
|
input logic ifu_i1_icaf_f1,
|
||||||
input logic ifu_i0_perr, // icache parity error
|
input logic ifu_i0_perr, // icache parity error
|
||||||
input logic ifu_i1_perr,
|
input logic ifu_i1_perr,
|
||||||
input logic ifu_i0_sbecc, // icache/iccm single-bit error
|
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_i0_dbecc, // icache/iccm double-bit error
|
||||||
input logic ifu_i1_dbecc,
|
input logic ifu_i1_dbecc,
|
||||||
|
|
||||||
input logic lsu_freeze_dc3, // freeze pipe: decode -> dc3
|
input logic lsu_freeze_dc3, // freeze pipe: decode -> dc3
|
||||||
input logic lsu_idle_any, // lsu idle for fence instructions
|
input logic lsu_idle_any, // lsu idle for fence instructions
|
||||||
input logic lsu_halt_idle_any, // lsu idle for halting
|
input logic lsu_halt_idle_any, // lsu idle for halting
|
||||||
|
|
||||||
input br_pkt_t i0_brp, // branch packet
|
input br_pkt_t i0_brp, // branch packet
|
||||||
input br_pkt_t i1_brp,
|
input br_pkt_t i1_brp,
|
||||||
|
|
||||||
input lsu_error_pkt_t lsu_error_pkt_dc3, // LSU exception/error packet
|
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_load_any, // LSU imprecise load bus error
|
||||||
input logic lsu_imprecise_error_store_any, // LSU imprecise store bus error
|
input logic lsu_imprecise_error_store_any, // LSU imprecise store bus error
|
||||||
input logic [31:0] lsu_imprecise_error_addr_any, // LSU imprecise bus error address
|
input logic [31:0] 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 [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 [15:0] ifu_illegal_inst, // 16b opcode for illegal inst
|
||||||
|
|
||||||
input logic exu_div_stall, // stall decode for div executing
|
input logic exu_div_stall, // stall decode for div executing
|
||||||
input logic [31:0] exu_div_result, // final div result
|
input logic [31:0] exu_div_result, // final div result
|
||||||
input logic exu_div_finish, // cycle div finishes
|
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_dc3, // load result
|
||||||
input logic [31:0] lsu_result_corr_dc4, // corrected 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_load_stall_any, // This is for blocking loads
|
||||||
input logic lsu_store_stall_any, // This is for blocking stores
|
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_dccm_stall_any, // stall any load/store at decode, pmu event
|
||||||
input logic dma_iccm_stall_any, // iccm stalled, 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 iccm_dma_sb_error, // ICCM DMA single bit error
|
||||||
|
|
||||||
input logic exu_i0_flush_final, // slot0 flush
|
input logic exu_i0_flush_final, // slot0 flush
|
||||||
input logic exu_i1_flush_final, // slot1 flush
|
input logic exu_i1_flush_final, // slot1 flush
|
||||||
|
|
||||||
|
@ -162,10 +165,10 @@ module dec
|
||||||
input logic exu_flush_final, // final flush
|
input logic exu_flush_final, // final flush
|
||||||
|
|
||||||
input logic [31:0] exu_i0_result_e1, // alu result e1
|
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_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
|
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 [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 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_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 mexintpend, // External interrupt pending
|
||||||
input logic timer_int, // Timer interrupt pending (from pin)
|
input logic timer_int, // Timer interrupt pending (from pin)
|
||||||
|
|
||||||
input logic [7:0] pic_claimid, // PIC claimid
|
input logic [7:0] pic_claimid, // PIC claimid
|
||||||
input logic [3:0] pic_pl, // PIC priv level
|
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_meicurpl, // to PIC, Current priv level
|
||||||
output logic [3:0] dec_tlu_meipt, // to PIC
|
output logic [3:0] dec_tlu_meipt, // to PIC
|
||||||
|
@ -192,13 +195,13 @@ module dec
|
||||||
`endif
|
`endif
|
||||||
input logic ifu_ic_debug_rd_data_valid, // diagnostic icache read data valid
|
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
|
output cache_debug_pkt_t dec_tlu_ic_diag_pkt, // packet of DICAWICS, DICAD0/1, DICAGO info for icache diagnostics
|
||||||
|
|
||||||
|
|
||||||
// Debug start
|
// Debug start
|
||||||
input logic dbg_halt_req, // DM requests a halt
|
input logic dbg_halt_req, // DM requests a halt
|
||||||
input logic dbg_resume_req, // DM requests a resume
|
input logic dbg_resume_req, // DM requests a resume
|
||||||
input logic ifu_miss_state_idle, // I-side miss buffer empty
|
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_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_mpc_halted_only, // Core is halted only due to MPC
|
||||||
output logic dec_tlu_dbg_halted, // Core is halted and ready for debug command
|
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_leak_one_wb, // single step
|
||||||
output logic dec_tlu_flush_err_wb, // iside perr/ecc rfpc
|
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_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 dec_debug_wdata_rs1_d, // insert debug write data into rs1 at decode
|
||||||
|
|
||||||
output logic [31:0] dec_dbg_rddata, // debug command read data
|
output logic [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_valid_e4, // valid
|
||||||
input logic exu_i0_br_mp_e4, // mispredict
|
input logic exu_i0_br_mp_e4, // mispredict
|
||||||
input logic exu_i0_br_middle_e4, // middle of bank
|
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
|
// 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 [`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO] exu_i1_br_index_e4, // index
|
||||||
input logic [1:0] exu_i1_br_hist_e4, // history
|
input logic [1:0] exu_i1_br_hist_e4, // history
|
||||||
|
@ -245,22 +248,22 @@ module dec
|
||||||
`ifdef RV_BTB_48
|
`ifdef RV_BTB_48
|
||||||
input logic [1:0] exu_i1_br_way_e4, // way hit or repl
|
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
|
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_i1_br_way_e4, // way hit or repl
|
||||||
input logic exu_i0_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_rs1_d, // gpr rs1 data
|
||||||
output logic [31:0] gpr_i0_rs2_d, // gpr rs2 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_rs1_d,
|
||||||
output logic [31:0] gpr_i1_rs2_d,
|
output logic [31:0] gpr_i1_rs2_d,
|
||||||
|
|
||||||
output logic [31:0] dec_i0_immed_d, // immediate data
|
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_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 i0_ap, // alu packet
|
||||||
output alu_pkt_t i1_ap,
|
output alu_pkt_t i1_ap,
|
||||||
|
|
||||||
|
@ -268,14 +271,14 @@ module dec
|
||||||
output logic dec_i1_alu_decode_d,
|
output logic dec_i1_alu_decode_d,
|
||||||
|
|
||||||
output logic dec_i0_select_pc_d, // select pc onto rs1 for jal's
|
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 [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_rs1_bypass_en_d, // rs1 bypass enable
|
||||||
output logic dec_i0_rs2_bypass_en_d, // rs2 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_rs1_bypass_en_d,
|
||||||
output logic dec_i1_rs2_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_rs1_bypass_data_d, // rs1 bypass data
|
||||||
output logic [31:0] i0_rs2_bypass_data_d, // rs2 bypass data
|
output logic [31:0] i0_rs2_bypass_data_d, // rs2 bypass data
|
||||||
output logic [31:0] i1_rs1_bypass_data_d,
|
output logic [31:0] i1_rs1_bypass_data_d,
|
||||||
|
@ -286,22 +289,22 @@ module dec
|
||||||
output lsu_pkt_t lsu_p, // lsu packet
|
output lsu_pkt_t lsu_p, // lsu packet
|
||||||
output mul_pkt_t mul_p, // mul packet
|
output mul_pkt_t mul_p, // mul packet
|
||||||
output div_pkt_t div_p, // div 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 [11:0] dec_lsu_offset_d, // 12b offset for load/store addresses
|
||||||
output logic dec_i0_lsu_d, // is load/store
|
output logic dec_i0_lsu_d, // is load/store
|
||||||
output logic dec_i1_lsu_d,
|
output logic dec_i1_lsu_d,
|
||||||
|
|
||||||
output logic flush_final_e3, // final flush
|
output logic flush_final_e3, // final flush
|
||||||
output logic i0_flush_final_e3, // final flush from i0
|
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_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 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 [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_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_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_tlu_fence_i_wb, // flush is a fence_i rfnpc, flush icache
|
||||||
|
|
||||||
output logic dec_i0_mul_d, // chose which gpr value to use
|
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_i1_valid_e1, // i1 valid at e1 stage
|
||||||
output logic dec_div_decode_e4, // div at e4 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 [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_rs1_bypass_en_e3, // rs1 bypass enable e3
|
||||||
output logic dec_i0_rs2_bypass_en_e3, // rs2 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_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, // rs1 bypass data 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] 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 [31:0] i1_rs2_bypass_data_e3,
|
||||||
output logic dec_i0_sec_decode_e3, // secondary decode e3
|
output logic dec_i0_sec_decode_e3, // secondary decode e3
|
||||||
output logic dec_i1_sec_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 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 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 dec_i0_lsu_decode_d, // load/store decode
|
||||||
|
|
||||||
output logic [31:0] i0_result_e4_eff, // alu result e4
|
output logic [31:0] i0_result_e4_eff, // alu result e4
|
||||||
output logic [31:0] i1_result_e4_eff,
|
output logic [31:0] i1_result_e4_eff,
|
||||||
|
|
||||||
output logic dec_tlu_i0_valid_e4, // slot 0 instruction is valid at e4
|
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: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_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: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: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
|
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,
|
input logic [15:0] ifu_i1_cinst,
|
||||||
|
|
||||||
output trace_pkt_t trace_rv_trace_pkt, // trace packet
|
output trace_pkt_t trace_rv_trace_pkt, // trace packet
|
||||||
|
|
||||||
// feature disable from mfdc
|
// feature disable from mfdc
|
||||||
output logic dec_tlu_sideeffect_posted_disable, // disable posted writes to side-effect address
|
output logic dec_tlu_sideeffect_posted_disable, // disable posted writes to side-effect address
|
||||||
output logic dec_tlu_core_ecc_disable, // disable core ECC
|
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_dccm_clk_override, // override DCCM clock domain gating
|
||||||
output logic dec_tlu_icm_clk_override, // override ICCM 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;
|
localparam GPR_BANKS = 1;
|
||||||
|
@ -401,7 +404,7 @@ module dec
|
||||||
|
|
||||||
logic dec_tlu_dec_clk_override; // to and from dec blocks
|
logic dec_tlu_dec_clk_override; // to and from dec blocks
|
||||||
logic clk_override;
|
logic clk_override;
|
||||||
|
|
||||||
logic dec_ib1_valid_d;
|
logic dec_ib1_valid_d;
|
||||||
logic dec_ib0_valid_d;
|
logic dec_ib0_valid_d;
|
||||||
|
|
||||||
|
@ -409,55 +412,55 @@ module dec
|
||||||
logic dec_pmu_decode_stall;
|
logic dec_pmu_decode_stall;
|
||||||
logic dec_pmu_presync_stall;
|
logic dec_pmu_presync_stall;
|
||||||
logic dec_pmu_postsync_stall;
|
logic dec_pmu_postsync_stall;
|
||||||
|
|
||||||
logic dec_tlu_wr_pause_wb; // CSR write to pause reg is at WB.
|
logic dec_tlu_wr_pause_wb; // CSR write to pause reg is at WB.
|
||||||
|
|
||||||
logic dec_i0_rs1_en_d;
|
logic dec_i0_rs1_en_d;
|
||||||
logic dec_i0_rs2_en_d;
|
logic dec_i0_rs2_en_d;
|
||||||
logic dec_fence_pending; // tell TLU to stall DMA
|
logic dec_fence_pending; // tell TLU to stall DMA
|
||||||
|
|
||||||
logic [4:0] dec_i0_rs1_d;
|
logic [4:0] dec_i0_rs1_d;
|
||||||
logic [4:0] dec_i0_rs2_d;
|
logic [4:0] dec_i0_rs2_d;
|
||||||
|
|
||||||
|
|
||||||
logic dec_i1_rs1_en_d;
|
logic dec_i1_rs1_en_d;
|
||||||
logic dec_i1_rs2_en_d;
|
logic dec_i1_rs2_en_d;
|
||||||
|
|
||||||
logic [4:0] dec_i1_rs1_d;
|
logic [4:0] dec_i1_rs1_d;
|
||||||
logic [4:0] dec_i1_rs2_d;
|
logic [4:0] dec_i1_rs2_d;
|
||||||
|
|
||||||
|
|
||||||
logic [31:0] dec_i0_instr_d, dec_i1_instr_d;
|
logic [31:0] dec_i0_instr_d, dec_i1_instr_d;
|
||||||
|
|
||||||
logic dec_tlu_pipelining_disable;
|
logic dec_tlu_pipelining_disable;
|
||||||
logic dec_tlu_dual_issue_disable;
|
logic dec_tlu_dual_issue_disable;
|
||||||
|
|
||||||
|
|
||||||
logic [4:0] dec_i0_waddr_wb;
|
logic [4:0] dec_i0_waddr_wb;
|
||||||
logic dec_i0_wen_wb;
|
logic dec_i0_wen_wb;
|
||||||
logic [31:0] dec_i0_wdata_wb;
|
logic [31:0] dec_i0_wdata_wb;
|
||||||
|
|
||||||
logic [4:0] dec_i1_waddr_wb;
|
logic [4:0] dec_i1_waddr_wb;
|
||||||
logic dec_i1_wen_wb;
|
logic dec_i1_wen_wb;
|
||||||
logic [31:0] dec_i1_wdata_wb;
|
logic [31:0] dec_i1_wdata_wb;
|
||||||
|
|
||||||
logic dec_csr_wen_wb; // csr write enable at wb
|
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_rdaddr_d; // read address for csr
|
||||||
logic [11:0] dec_csr_wraddr_wb; // write address for csryes
|
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_wrdata_wb; // csr write data at wb
|
||||||
|
|
||||||
logic [31:0] dec_csr_rddata_d; // csr read 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_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
|
logic dec_csr_stall_int_ff; // csr is mie/mstatus
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
trap_pkt_t dec_tlu_packet_e4;
|
trap_pkt_t dec_tlu_packet_e4;
|
||||||
|
|
||||||
logic dec_i0_pc4_d, dec_i1_pc4_d;
|
logic dec_i0_pc4_d, dec_i1_pc4_d;
|
||||||
logic dec_tlu_presync_d;
|
logic dec_tlu_presync_d;
|
||||||
logic dec_tlu_postsync_d;
|
logic dec_tlu_postsync_d;
|
||||||
|
@ -465,7 +468,7 @@ module dec
|
||||||
|
|
||||||
logic [31:0] dec_illegal_inst;
|
logic [31:0] dec_illegal_inst;
|
||||||
|
|
||||||
|
|
||||||
// GPR Bank ID write signals
|
// GPR Bank ID write signals
|
||||||
logic wen_bank_id;
|
logic wen_bank_id;
|
||||||
logic [GPR_BANKS_LOG2-1:0] wr_bank_id;
|
logic [GPR_BANKS_LOG2-1:0] wr_bank_id;
|
||||||
|
@ -483,11 +486,11 @@ module dec
|
||||||
|
|
||||||
logic dec_i0_decode_d;
|
logic dec_i0_decode_d;
|
||||||
logic dec_i1_decode_d;
|
logic dec_i1_decode_d;
|
||||||
|
|
||||||
logic [3:0] dec_i0_trigger_match_d;
|
logic [3:0] dec_i0_trigger_match_d;
|
||||||
logic [3:0] dec_i1_trigger_match_d;
|
logic [3:0] dec_i1_trigger_match_d;
|
||||||
|
|
||||||
|
|
||||||
logic dec_debug_fence_d;
|
logic dec_debug_fence_d;
|
||||||
|
|
||||||
logic dec_nonblock_load_wen;
|
logic dec_nonblock_load_wen;
|
||||||
|
@ -497,15 +500,15 @@ module dec
|
||||||
logic dec_i0_load_e4;
|
logic dec_i0_load_e4;
|
||||||
|
|
||||||
logic dec_pause_state;
|
logic dec_pause_state;
|
||||||
|
|
||||||
br_pkt_t dec_i0_brp;
|
br_pkt_t dec_i0_brp;
|
||||||
br_pkt_t dec_i1_brp;
|
br_pkt_t dec_i1_brp;
|
||||||
|
|
||||||
assign clk_override = dec_tlu_dec_clk_override;
|
assign clk_override = dec_tlu_dec_clk_override;
|
||||||
|
|
||||||
|
|
||||||
assign dec_dbg_rddata[31:0] = dec_i0_wdata_wb[31:0];
|
assign dec_dbg_rddata[31:0] = dec_i0_wdata_wb[31:0];
|
||||||
|
|
||||||
dec_ib_ctl instbuff (.*
|
dec_ib_ctl instbuff (.*
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -518,7 +521,7 @@ module dec
|
||||||
assign wr_bank_id = '0;
|
assign wr_bank_id = '0;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
dec_gpr_ctl #(.GPR_BANKS(GPR_BANKS),
|
dec_gpr_ctl #(.GPR_BANKS(GPR_BANKS),
|
||||||
.GPR_BANKS_LOG2(GPR_BANKS_LOG2)) arf (.*,
|
.GPR_BANKS_LOG2(GPR_BANKS_LOG2)) arf (.*,
|
||||||
// inputs
|
// inputs
|
||||||
|
@ -526,24 +529,24 @@ module dec
|
||||||
.raddr1(dec_i0_rs2_d[4:0]), .rden1(dec_i0_rs2_en_d),
|
.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),
|
.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),
|
.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]),
|
.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]),
|
.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]),
|
.waddr2(dec_nonblock_load_waddr[4:0]), .wen2(dec_nonblock_load_wen), .wd2(lsu_nonblock_load_data[31:0]),
|
||||||
|
|
||||||
// outputs
|
// outputs
|
||||||
.rd0(gpr_i0_rs1_d[31:0]), .rd1(gpr_i0_rs2_d[31:0]),
|
.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
|
// Trigger
|
||||||
|
|
||||||
dec_trigger dec_trigger (.*);
|
dec_trigger dec_trigger (.*);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// trace
|
// trace
|
||||||
logic [15:0] dec_i0_cinst_d;
|
logic [15:0] dec_i0_cinst_d;
|
||||||
logic [15:0] dec_i1_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;
|
logic dec_tlu_i0_exc_valid_wb1, dec_tlu_i1_exc_valid_wb1;
|
||||||
|
|
||||||
// also need retires_p==3
|
// 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_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 };
|
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_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
|
assign trace_rv_trace_pkt.trace_rv_i_tval_ip = dec_tlu_mtval_wb1[31:0]; // replicate across ports
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// end trace
|
// end trace
|
||||||
|
|
||||||
endmodule // dec
|
endmodule // dec
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,12 +1,12 @@
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
// Copyright 2019 Western Digital Corporation or its affiliates.
|
// Copyright 2019 Western Digital Corporation or its affiliates.
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "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 not use this file except in compliance with the License.
|
||||||
// You may obtain a copy of the License at
|
// You may obtain a copy of the License at
|
||||||
//
|
//
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
//
|
//
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// 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] waddr0, // logical write addresses
|
||||||
input logic [4:0] waddr1,
|
input logic [4:0] waddr1,
|
||||||
input logic [4:0] waddr2,
|
input logic [4:0] waddr2,
|
||||||
|
|
||||||
input logic wen0, // write enables
|
input logic wen0, // write enables
|
||||||
input logic wen1,
|
input logic wen1,
|
||||||
input logic wen2,
|
input logic wen2,
|
||||||
|
|
||||||
input logic [31:0] wd0, // write data
|
input logic [31:0] wd0, // write data
|
||||||
input logic [31:0] wd1,
|
input logic [31:0] wd1,
|
||||||
input logic [31:0] wd2,
|
input logic [31:0] wd2,
|
||||||
|
|
||||||
input logic wen_bank_id, // write enable for banks
|
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 [GPR_BANKS_LOG2-1:0] wr_bank_id, // read enable for banks
|
||||||
|
|
||||||
input logic clk,
|
input logic clk,
|
||||||
input logic rst_l,
|
input logic rst_l,
|
||||||
|
|
||||||
output logic [31:0] rd0, // read data
|
output logic [31:0] rd0, // read data
|
||||||
output logic [31:0] rd1,
|
output logic [31:0] rd1,
|
||||||
output logic [31:0] rd2,
|
output logic [31:0] rd2,
|
||||||
|
@ -59,55 +59,55 @@ module dec_gpr_ctl #(parameter GPR_BANKS = 1,
|
||||||
logic [31:1] gpr_wr_en;
|
logic [31:1] gpr_wr_en;
|
||||||
logic [GPR_BANKS-1:0][31:1] gpr_bank_wr_en;
|
logic [GPR_BANKS-1:0][31:1] gpr_bank_wr_en;
|
||||||
logic [GPR_BANKS_LOG2-1:0] gpr_bank_id;
|
logic [GPR_BANKS_LOG2-1:0] gpr_bank_id;
|
||||||
|
|
||||||
//assign gpr_bank_id[GPR_BANKS_LOG2-1:0] = '0;
|
//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]));
|
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
|
// GPR Write Enables for power savings
|
||||||
assign gpr_wr_en[31:1] = (w0v[31:1] | w1v[31:1] | w2v[31:1]);
|
assign gpr_wr_en[31:1] = (w0v[31:1] | w1v[31:1] | w2v[31:1]);
|
||||||
for (genvar i=0; i<GPR_BANKS; i++) begin: gpr_banks
|
for (genvar i=0; i<GPR_BANKS; i++) begin: gpr_banks
|
||||||
assign gpr_bank_wr_en[i][31:1] = gpr_wr_en[31:1] & {31{gpr_bank_id[GPR_BANKS_LOG2-1:0] == i}};
|
assign gpr_bank_wr_en[i][31:1] = gpr_wr_en[31:1] & {31{gpr_bank_id[GPR_BANKS_LOG2-1:0] == i}};
|
||||||
for ( genvar j=1; j<32; j++ ) begin : gpr
|
for ( genvar j=1; j<32; j++ ) begin : gpr
|
||||||
rvdffe #(32) gprff (.*, .en(gpr_bank_wr_en[i][j]), .din(gpr_in[j][31:0]), .dout(gpr_out[i][j][31:0]));
|
rvdffe #(32) gprff (.*, .en(gpr_bank_wr_en[i][j]), .din(gpr_in[j][31:0]), .dout(gpr_out[i][j][31:0]));
|
||||||
end : gpr
|
end : gpr
|
||||||
end: gpr_banks
|
end: gpr_banks
|
||||||
|
|
||||||
// the read out
|
// the read out
|
||||||
always_comb begin
|
always_comb begin
|
||||||
rd0[31:0] = 32'b0;
|
rd0[31:0] = 32'b0;
|
||||||
rd1[31:0] = 32'b0;
|
rd1[31:0] = 32'b0;
|
||||||
rd2[31:0] = 32'b0;
|
rd2[31:0] = 32'b0;
|
||||||
rd3[31:0] = 32'b0;
|
rd3[31:0] = 32'b0;
|
||||||
w0v[31:1] = 31'b0;
|
w0v[31:1] = 31'b0;
|
||||||
w1v[31:1] = 31'b0;
|
w1v[31:1] = 31'b0;
|
||||||
w2v[31:1] = 31'b0;
|
w2v[31:1] = 31'b0;
|
||||||
gpr_in[31:1] = '0;
|
gpr_in[31:1] = '0;
|
||||||
|
|
||||||
// GPR Read logic
|
// GPR Read logic
|
||||||
for (int i=0; i<GPR_BANKS; i++) begin
|
for (int i=0; i<GPR_BANKS; i++) begin
|
||||||
for (int j=1; j<32; j++ ) begin
|
for (int j=1; j<32; j++ ) begin
|
||||||
rd0[31:0] |= ({32{rden0 & (raddr0[4:0]== 5'(j)) & (gpr_bank_id[GPR_BANKS_LOG2-1:0] == 1'(i))}} & gpr_out[i][j][31:0]);
|
rd0[31:0] |= ({32{rden0 & (raddr0[4:0]== 5'(j)) & (gpr_bank_id[GPR_BANKS_LOG2-1:0] == 1'(i))}} & gpr_out[i][j][31:0]);
|
||||||
rd1[31:0] |= ({32{rden1 & (raddr1[4:0]== 5'(j)) & (gpr_bank_id[GPR_BANKS_LOG2-1:0] == 1'(i))}} & gpr_out[i][j][31:0]);
|
rd1[31:0] |= ({32{rden1 & (raddr1[4:0]== 5'(j)) & (gpr_bank_id[GPR_BANKS_LOG2-1:0] == 1'(i))}} & gpr_out[i][j][31:0]);
|
||||||
rd2[31:0] |= ({32{rden2 & (raddr2[4:0]== 5'(j)) & (gpr_bank_id[GPR_BANKS_LOG2-1:0] == 1'(i))}} & gpr_out[i][j][31:0]);
|
rd2[31:0] |= ({32{rden2 & (raddr2[4:0]== 5'(j)) & (gpr_bank_id[GPR_BANKS_LOG2-1:0] == 1'(i))}} & gpr_out[i][j][31:0]);
|
||||||
rd3[31:0] |= ({32{rden3 & (raddr3[4:0]== 5'(j)) & (gpr_bank_id[GPR_BANKS_LOG2-1:0] == 1'(i))}} & gpr_out[i][j][31:0]);
|
rd3[31:0] |= ({32{rden3 & (raddr3[4:0]== 5'(j)) & (gpr_bank_id[GPR_BANKS_LOG2-1:0] == 1'(i))}} & gpr_out[i][j][31:0]);
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
// GPR Write logic
|
// GPR Write logic
|
||||||
for (int j=1; j<32; j++ ) begin
|
for (int j=1; j<32; j++ ) begin
|
||||||
w0v[j] = wen0 & (waddr0[4:0]== 5'(j) );
|
w0v[j] = wen0 & (waddr0[4:0]== 5'(j) );
|
||||||
w1v[j] = wen1 & (waddr1[4:0]== 5'(j) );
|
w1v[j] = wen1 & (waddr1[4:0]== 5'(j) );
|
||||||
w2v[j] = wen2 & (waddr2[4:0]== 5'(j) );
|
w2v[j] = wen2 & (waddr2[4:0]== 5'(j) );
|
||||||
gpr_in[j] = ({32{w0v[j]}} & wd0[31:0]) |
|
gpr_in[j] = ({32{w0v[j]}} & wd0[31:0]) |
|
||||||
({32{w1v[j]}} & wd1[31:0]) |
|
({32{w1v[j]}} & wd1[31:0]) |
|
||||||
({32{w2v[j]}} & wd2[31:0]);
|
({32{w2v[j]}} & wd2[31:0]);
|
||||||
end
|
end
|
||||||
end // always_comb begin
|
end // always_comb begin
|
||||||
|
|
||||||
`ifdef ASSERT_ON
|
`ifdef ASSERT_ON
|
||||||
// asserting that no 2 ports will write to the same gpr simultaneously
|
// asserting that no 2 ports will write to the same gpr simultaneously
|
||||||
assert_multiple_wen_to_same_gpr: assert #0 (~( ((w0v[31:1] == w1v[31:1]) & wen0 & wen1) | ((w0v[31:1] == w2v[31:1]) & wen0 & wen2) | ((w1v[31:1] == w2v[31:1]) & wen1 & wen2) ) );
|
assert_multiple_wen_to_same_gpr: assert #0 (~( ((w0v[31:1] == w1v[31:1]) & wen0 & wen1) | ((w0v[31:1] == w2v[31:1]) & wen0 & wen2) | ((w1v[31:1] == w2v[31:1]) & wen1 & wen2) ) );
|
||||||
|
|
||||||
`endif
|
`endif
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
// Copyright 2019 Western Digital Corporation or its affiliates.
|
// Copyright 2019 Western Digital Corporation or its affiliates.
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "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 not use this file except in compliance with the License.
|
||||||
// You may obtain a copy of the License at
|
// You may obtain a copy of the License at
|
||||||
//
|
//
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
//
|
//
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
@ -25,25 +25,25 @@ module dec_ib_ctl
|
||||||
input logic [1:0] dbg_cmd_type, // dbg type
|
input logic [1:0] dbg_cmd_type, // dbg type
|
||||||
input logic [1:0] dbg_cmd_size, // 00 - 1B, 01 - 2B, 10 - 4B, 11 - reserved
|
input logic [1:0] dbg_cmd_size, // 00 - 1B, 01 - 2B, 10 - 4B, 11 - reserved
|
||||||
input logic [31:0] dbg_cmd_addr, // expand to 31:0
|
input logic [31:0] dbg_cmd_addr, // expand to 31:0
|
||||||
|
|
||||||
input logic exu_flush_final, // all flush sources: primary/secondary alu's, trap
|
input logic exu_flush_final, // all flush sources: primary/secondary alu's, trap
|
||||||
|
|
||||||
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 dec_ib1_valid_eff_d,
|
||||||
|
|
||||||
input br_pkt_t i0_brp, // i0 branch packet from aligner
|
input br_pkt_t i0_brp, // i0 branch packet from aligner
|
||||||
input br_pkt_t i1_brp,
|
input br_pkt_t i1_brp,
|
||||||
|
|
||||||
input logic ifu_i0_pc4, // i0 is 4B inst else 2B
|
input logic ifu_i0_pc4, // i0 is 4B inst else 2B
|
||||||
input logic ifu_i1_pc4,
|
input logic ifu_i1_pc4,
|
||||||
|
|
||||||
input logic ifu_i0_valid, // i0 valid from ifu
|
input logic ifu_i0_valid, // i0 valid from ifu
|
||||||
input logic ifu_i1_valid,
|
input logic ifu_i1_valid,
|
||||||
|
|
||||||
input logic ifu_i0_icaf, // i0 instruction access fault
|
input logic ifu_i0_icaf, // i0 instruction access fault
|
||||||
input logic ifu_i1_icaf,
|
input logic ifu_i1_icaf,
|
||||||
input logic ifu_i0_icaf_f1, // i0 has access fault on second fetch group
|
input logic ifu_i0_icaf_f1, // i0 has access fault on second fetch group
|
||||||
input logic ifu_i1_icaf_f1,
|
input logic ifu_i1_icaf_f1,
|
||||||
input logic ifu_i0_perr, // i0 instruction parity error
|
input logic ifu_i0_perr, // i0 instruction parity error
|
||||||
input logic ifu_i1_perr,
|
input logic ifu_i1_perr,
|
||||||
input logic ifu_i0_sbecc, // i0 single-bit error
|
input logic ifu_i0_sbecc, // i0 single-bit error
|
||||||
|
@ -59,17 +59,17 @@ module dec_ib_ctl
|
||||||
|
|
||||||
input logic dec_i0_decode_d, // i0 decode
|
input logic dec_i0_decode_d, // i0 decode
|
||||||
input logic dec_i1_decode_d,
|
input logic dec_i1_decode_d,
|
||||||
|
|
||||||
|
|
||||||
input logic rst_l, // test stuff
|
input logic rst_l, // test stuff
|
||||||
input logic clk,
|
input logic clk,
|
||||||
|
|
||||||
|
|
||||||
output logic dec_ib3_valid_d, // ib3 valid
|
output logic dec_ib3_valid_d, // ib3 valid
|
||||||
output logic dec_ib2_valid_d, // ib2 valid
|
output logic dec_ib2_valid_d, // ib2 valid
|
||||||
output logic dec_ib1_valid_d, // ib1 valid
|
output logic dec_ib1_valid_d, // ib1 valid
|
||||||
output logic dec_ib0_valid_d, // ib0 valid
|
output logic dec_ib0_valid_d, // ib0 valid
|
||||||
|
|
||||||
|
|
||||||
output logic [31:0] dec_i0_instr_d, // i0 inst at decode
|
output logic [31:0] dec_i0_instr_d, // i0 inst at decode
|
||||||
output logic [31:0] dec_i1_instr_d, // i1 inst at decode
|
output logic [31:0] dec_i1_instr_d, // i1 inst at decode
|
||||||
|
@ -107,9 +107,9 @@ module dec_ib_ctl
|
||||||
);
|
);
|
||||||
|
|
||||||
`include "global.h"
|
`include "global.h"
|
||||||
|
|
||||||
logic flush_final;
|
logic flush_final;
|
||||||
|
|
||||||
logic [3:0] ibval_in, ibval;
|
logic [3:0] ibval_in, ibval;
|
||||||
|
|
||||||
logic [31:0] ib3_in, ib2_in, ib1_in, ib0_in;
|
logic [31:0] ib3_in, ib2_in, ib1_in, ib0_in;
|
||||||
|
@ -131,14 +131,14 @@ module dec_ib_ctl
|
||||||
logic shift_ib1_ib0, shift_ib2_ib1, shift_ib3_ib2;
|
logic shift_ib1_ib0, shift_ib2_ib1, shift_ib3_ib2;
|
||||||
logic shift_ib2_ib0;
|
logic shift_ib2_ib0;
|
||||||
logic shift_ib3_ib1;
|
logic shift_ib3_ib1;
|
||||||
|
|
||||||
|
|
||||||
logic ifu_i0_val, ifu_i1_val;
|
logic ifu_i0_val, ifu_i1_val;
|
||||||
logic debug_valid;
|
logic debug_valid;
|
||||||
logic [4:0] dreg;
|
logic [4:0] dreg;
|
||||||
logic [11:0] dcsr;
|
logic [11:0] dcsr;
|
||||||
logic [31:0] ib0_debug_in;
|
logic [31:0] ib0_debug_in;
|
||||||
|
|
||||||
// logic debug_read_mem;
|
// logic debug_read_mem;
|
||||||
// logic debug_write_mem;
|
// logic debug_write_mem;
|
||||||
logic debug_read;
|
logic debug_read;
|
||||||
|
@ -147,10 +147,10 @@ module dec_ib_ctl
|
||||||
logic debug_write_gpr;
|
logic debug_write_gpr;
|
||||||
logic debug_read_csr;
|
logic debug_read_csr;
|
||||||
logic debug_write_csr;
|
logic debug_write_csr;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
rvdff #(1) flush_upperff (.*, .clk(free_clk), .din(exu_flush_final), .dout(flush_final));
|
|
||||||
|
rvdff #(1) flush_upperff (.*, .clk(free_clk), .din(exu_flush_final), .dout(flush_final));
|
||||||
|
|
||||||
logic [3:0] ibvalid;
|
logic [3:0] ibvalid;
|
||||||
|
|
||||||
|
@ -158,15 +158,15 @@ module dec_ib_ctl
|
||||||
logic [3:1] i1_wen;
|
logic [3:1] i1_wen;
|
||||||
logic [3:0] shift_ibval;
|
logic [3:0] shift_ibval;
|
||||||
logic [3:0] ibwrite;
|
logic [3:0] ibwrite;
|
||||||
|
|
||||||
assign ibvalid[3:0] = ibval[3:0] | i0_wen[3:0] | {i1_wen[3:1],1'b0};
|
assign ibvalid[3:0] = ibval[3:0] | i0_wen[3:0] | {i1_wen[3:1],1'b0};
|
||||||
|
|
||||||
assign ibval_in[3:0] = (({4{shift0}} & ibvalid[3:0]) |
|
assign ibval_in[3:0] = (({4{shift0}} & ibvalid[3:0]) |
|
||||||
({4{shift1}} & {1'b0, ibvalid[3:1]}) |
|
({4{shift1}} & {1'b0, ibvalid[3:1]}) |
|
||||||
({4{shift2}} & {2'b0, ibvalid[3:2]})) & ~{4{flush_final}};
|
({4{shift2}} & {2'b0, ibvalid[3:2]})) & ~{4{flush_final}};
|
||||||
|
|
||||||
rvdff #(4) ibvalff (.*, .clk(active_clk), .din(ibval_in[3:0]), .dout(ibval[3:0]));
|
rvdff #(4) ibvalff (.*, .clk(active_clk), .din(ibval_in[3:0]), .dout(ibval[3:0]));
|
||||||
|
|
||||||
// only valid if there is room
|
// only valid if there is room
|
||||||
if (DEC_INSTBUF_DEPTH==4) begin
|
if (DEC_INSTBUF_DEPTH==4) begin
|
||||||
assign ifu_i0_val = ifu_i0_valid & ~ibval[3] & ~flush_final;
|
assign ifu_i0_val = ifu_i0_valid & ~ibval[3] & ~flush_final;
|
||||||
|
@ -176,58 +176,58 @@ module dec_ib_ctl
|
||||||
assign ifu_i0_val = ifu_i0_valid & (~dec_ib0_valid_eff_d | ~dec_ib1_valid_eff_d) & ~flush_final;
|
assign ifu_i0_val = ifu_i0_valid & (~dec_ib0_valid_eff_d | ~dec_ib1_valid_eff_d) & ~flush_final;
|
||||||
assign ifu_i1_val = ifu_i1_valid & (~dec_ib0_valid_eff_d & ~dec_ib1_valid_eff_d) & ~flush_final;
|
assign ifu_i1_val = ifu_i1_valid & (~dec_ib0_valid_eff_d & ~dec_ib1_valid_eff_d) & ~flush_final;
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
assign i0_wen[0] = ~ibval[0] & (ifu_i0_val | debug_valid);
|
assign i0_wen[0] = ~ibval[0] & (ifu_i0_val | debug_valid);
|
||||||
assign i0_wen[1] = ibval[0] & ~ibval[1] & ifu_i0_val;
|
assign i0_wen[1] = ibval[0] & ~ibval[1] & ifu_i0_val;
|
||||||
assign i0_wen[2] = ibval[1] & ~ibval[2] & ifu_i0_val;
|
assign i0_wen[2] = ibval[1] & ~ibval[2] & ifu_i0_val;
|
||||||
assign i0_wen[3] = ibval[2] & ~ibval[3] & ifu_i0_val;
|
assign i0_wen[3] = ibval[2] & ~ibval[3] & ifu_i0_val;
|
||||||
|
|
||||||
assign i1_wen[1] = ~ibval[0] & ifu_i1_val;
|
assign i1_wen[1] = ~ibval[0] & ifu_i1_val;
|
||||||
assign i1_wen[2] = ibval[0] & ~ibval[1] & ifu_i1_val;
|
assign i1_wen[2] = ibval[0] & ~ibval[1] & ifu_i1_val;
|
||||||
assign i1_wen[3] = ibval[1] & ~ibval[2] & ifu_i1_val;
|
assign i1_wen[3] = ibval[1] & ~ibval[2] & ifu_i1_val;
|
||||||
|
|
||||||
|
|
||||||
// start trace
|
// start trace
|
||||||
|
|
||||||
if (DEC_INSTBUF_DEPTH==4) begin
|
if (DEC_INSTBUF_DEPTH==4) begin
|
||||||
assign cinst3_in[15:0] = ({16{write_i0_ib3}} & ifu_i0_cinst[15:0]) |
|
assign cinst3_in[15:0] = ({16{write_i0_ib3}} & ifu_i0_cinst[15:0]) |
|
||||||
({16{write_i1_ib3}} & ifu_i1_cinst[15:0]);
|
({16{write_i1_ib3}} & ifu_i1_cinst[15:0]);
|
||||||
|
|
||||||
rvdffe #(16) cinst3ff (.*, .en(ibwrite[3]), .din(cinst3_in[15:0]), .dout(cinst3[15:0]));
|
rvdffe #(16) cinst3ff (.*, .en(ibwrite[3]), .din(cinst3_in[15:0]), .dout(cinst3[15:0]));
|
||||||
|
|
||||||
assign cinst2_in[15:0] = ({16{write_i0_ib2}} & ifu_i0_cinst[15:0]) |
|
assign cinst2_in[15:0] = ({16{write_i0_ib2}} & ifu_i0_cinst[15:0]) |
|
||||||
({16{write_i1_ib2}} & ifu_i1_cinst[15:0]) |
|
({16{write_i1_ib2}} & ifu_i1_cinst[15:0]) |
|
||||||
({16{shift_ib3_ib2}} & cinst3[15:0]);
|
({16{shift_ib3_ib2}} & cinst3[15:0]);
|
||||||
|
|
||||||
rvdffe #(16) cinst2ff (.*, .en(ibwrite[2]), .din(cinst2_in[15:0]), .dout(cinst2[15:0]));
|
rvdffe #(16) cinst2ff (.*, .en(ibwrite[2]), .din(cinst2_in[15:0]), .dout(cinst2[15:0]));
|
||||||
end // if (DEC_INSTBUF_DEPTH==4)
|
end // if (DEC_INSTBUF_DEPTH==4)
|
||||||
else begin
|
else begin
|
||||||
assign cinst3 = '0;
|
assign cinst3 = '0;
|
||||||
assign cinst2 = '0;
|
assign cinst2 = '0;
|
||||||
end
|
end
|
||||||
|
|
||||||
assign cinst1_in[15:0] = ({16{write_i0_ib1}} & ifu_i0_cinst[15:0]) |
|
assign cinst1_in[15:0] = ({16{write_i0_ib1}} & ifu_i0_cinst[15:0]) |
|
||||||
({16{write_i1_ib1}} & ifu_i1_cinst[15:0]) |
|
({16{write_i1_ib1}} & ifu_i1_cinst[15:0]) |
|
||||||
({16{shift_ib2_ib1}} & cinst2[15:0]) |
|
({16{shift_ib2_ib1}} & cinst2[15:0]) |
|
||||||
({16{shift_ib3_ib1}} & cinst3[15:0]);
|
({16{shift_ib3_ib1}} & cinst3[15:0]);
|
||||||
|
|
||||||
rvdffe #(16) cinst1ff (.*, .en(ibwrite[1]), .din(cinst1_in[15:0]), .dout(cinst1[15:0]));
|
rvdffe #(16) cinst1ff (.*, .en(ibwrite[1]), .din(cinst1_in[15:0]), .dout(cinst1[15:0]));
|
||||||
|
|
||||||
|
|
||||||
assign cinst0_in[15:0] = ({16{write_i0_ib0}} & ifu_i0_cinst[15:0]) |
|
assign cinst0_in[15:0] = ({16{write_i0_ib0}} & ifu_i0_cinst[15:0]) |
|
||||||
({16{shift_ib1_ib0}} & cinst1[15:0]) |
|
({16{shift_ib1_ib0}} & cinst1[15:0]) |
|
||||||
({16{shift_ib2_ib0}} & cinst2[15:0]);
|
({16{shift_ib2_ib0}} & cinst2[15:0]);
|
||||||
|
|
||||||
rvdffe #(16) cinst0ff (.*, .en(ibwrite[0]), .din(cinst0_in[15:0]), .dout(cinst0[15:0]));
|
rvdffe #(16) cinst0ff (.*, .en(ibwrite[0]), .din(cinst0_in[15:0]), .dout(cinst0[15:0]));
|
||||||
|
|
||||||
assign dec_i0_cinst_d[15:0] = cinst0[15:0];
|
assign dec_i0_cinst_d[15:0] = cinst0[15:0];
|
||||||
|
|
||||||
assign dec_i1_cinst_d[15:0] = cinst1[15:0];
|
assign dec_i1_cinst_d[15:0] = cinst1[15:0];
|
||||||
|
|
||||||
// end trace
|
// end trace
|
||||||
|
|
||||||
|
|
||||||
// pc tracking
|
// pc tracking
|
||||||
|
|
||||||
|
|
||||||
|
@ -238,97 +238,97 @@ module dec_ib_ctl
|
||||||
};
|
};
|
||||||
|
|
||||||
logic [36:0] ifu_i1_pcdata, ifu_i0_pcdata;
|
logic [36:0] ifu_i1_pcdata, ifu_i0_pcdata;
|
||||||
|
|
||||||
assign ifu_i1_pcdata[36:0] = { ifu_i1_icaf_f1, ifu_i1_dbecc, ifu_i1_sbecc, ifu_i1_perr, ifu_i1_icaf,
|
assign ifu_i1_pcdata[36:0] = { ifu_i1_icaf_f1, ifu_i1_dbecc, ifu_i1_sbecc, ifu_i1_perr, ifu_i1_icaf,
|
||||||
ifu_i1_pc[31:1], ifu_i1_pc4 };
|
ifu_i1_pc[31:1], ifu_i1_pc4 };
|
||||||
assign ifu_i0_pcdata[36:0] = { ifu_i0_icaf_f1, ifu_i0_dbecc, ifu_i0_sbecc, ifu_i0_perr, ifu_i0_icaf,
|
assign ifu_i0_pcdata[36:0] = { ifu_i0_icaf_f1, ifu_i0_dbecc, ifu_i0_sbecc, ifu_i0_perr, ifu_i0_icaf,
|
||||||
ifu_i0_pc[31:1], ifu_i0_pc4 };
|
ifu_i0_pc[31:1], ifu_i0_pc4 };
|
||||||
|
|
||||||
if (DEC_INSTBUF_DEPTH==4) begin
|
if (DEC_INSTBUF_DEPTH==4) begin
|
||||||
assign pc3_in[36:0] = ({37{write_i0_ib3}} & ifu_i0_pcdata[36:0]) |
|
assign pc3_in[36:0] = ({37{write_i0_ib3}} & ifu_i0_pcdata[36:0]) |
|
||||||
({37{write_i1_ib3}} & ifu_i1_pcdata[36:0]);
|
({37{write_i1_ib3}} & ifu_i1_pcdata[36:0]);
|
||||||
|
|
||||||
rvdffe #(37) pc3ff (.*, .en(ibwrite[3]), .din(pc3_in[36:0]), .dout(pc3[36:0]));
|
rvdffe #(37) pc3ff (.*, .en(ibwrite[3]), .din(pc3_in[36:0]), .dout(pc3[36:0]));
|
||||||
|
|
||||||
assign pc2_in[36:0] = ({37{write_i0_ib2}} & ifu_i0_pcdata[36:0]) |
|
assign pc2_in[36:0] = ({37{write_i0_ib2}} & ifu_i0_pcdata[36:0]) |
|
||||||
({37{write_i1_ib2}} & ifu_i1_pcdata[36:0]) |
|
({37{write_i1_ib2}} & ifu_i1_pcdata[36:0]) |
|
||||||
({37{shift_ib3_ib2}} & pc3[36:0]);
|
({37{shift_ib3_ib2}} & pc3[36:0]);
|
||||||
|
|
||||||
rvdffe #(37) pc2ff (.*, .en(ibwrite[2]), .din(pc2_in[36:0]), .dout(pc2[36:0]));
|
rvdffe #(37) pc2ff (.*, .en(ibwrite[2]), .din(pc2_in[36:0]), .dout(pc2[36:0]));
|
||||||
end // if (DEC_INSTBUF_DEPTH==4)
|
end // if (DEC_INSTBUF_DEPTH==4)
|
||||||
else begin
|
else begin
|
||||||
assign pc3 = '0;
|
assign pc3 = '0;
|
||||||
assign pc2 = '0;
|
assign pc2 = '0;
|
||||||
end
|
end
|
||||||
|
|
||||||
assign pc1_in[36:0] = ({37{write_i0_ib1}} & ifu_i0_pcdata[36:0]) |
|
assign pc1_in[36:0] = ({37{write_i0_ib1}} & ifu_i0_pcdata[36:0]) |
|
||||||
({37{write_i1_ib1}} & ifu_i1_pcdata[36:0]) |
|
({37{write_i1_ib1}} & ifu_i1_pcdata[36:0]) |
|
||||||
({37{shift_ib2_ib1}} & pc2[36:0]) |
|
({37{shift_ib2_ib1}} & pc2[36:0]) |
|
||||||
({37{shift_ib3_ib1}} & pc3[36:0]);
|
({37{shift_ib3_ib1}} & pc3[36:0]);
|
||||||
|
|
||||||
rvdffe #(37) pc1ff (.*, .en(ibwrite[1]), .din(pc1_in[36:0]), .dout(pc1[36:0]));
|
rvdffe #(37) pc1ff (.*, .en(ibwrite[1]), .din(pc1_in[36:0]), .dout(pc1[36:0]));
|
||||||
|
|
||||||
|
|
||||||
assign pc0_in[36:0] = ({37{write_i0_ib0}} & ifu_i0_pcdata[36:0]) |
|
assign pc0_in[36:0] = ({37{write_i0_ib0}} & ifu_i0_pcdata[36:0]) |
|
||||||
({37{shift_ib1_ib0}} & pc1[36:0]) |
|
({37{shift_ib1_ib0}} & pc1[36:0]) |
|
||||||
({37{shift_ib2_ib0}} & pc2[36:0]);
|
({37{shift_ib2_ib0}} & pc2[36:0]);
|
||||||
|
|
||||||
rvdffe #(37) pc0ff (.*, .en(ibwrite[0]), .din(pc0_in[36:0]), .dout(pc0[36:0]));
|
rvdffe #(37) pc0ff (.*, .en(ibwrite[0]), .din(pc0_in[36:0]), .dout(pc0[36:0]));
|
||||||
|
|
||||||
assign dec_i0_icaf_f1_d = pc0[36]; // icaf's can only decode as i0
|
assign dec_i0_icaf_f1_d = pc0[36]; // icaf's can only decode as i0
|
||||||
|
|
||||||
assign dec_i1_dbecc_d = pc1[35];
|
assign dec_i1_dbecc_d = pc1[35];
|
||||||
assign dec_i0_dbecc_d = pc0[35];
|
assign dec_i0_dbecc_d = pc0[35];
|
||||||
|
|
||||||
assign dec_i1_sbecc_d = pc1[34];
|
assign dec_i1_sbecc_d = pc1[34];
|
||||||
assign dec_i0_sbecc_d = pc0[34];
|
assign dec_i0_sbecc_d = pc0[34];
|
||||||
|
|
||||||
assign dec_i1_perr_d = pc1[33];
|
assign dec_i1_perr_d = pc1[33];
|
||||||
assign dec_i0_perr_d = pc0[33];
|
assign dec_i0_perr_d = pc0[33];
|
||||||
|
|
||||||
assign dec_i1_icaf_d = pc1[32];
|
assign dec_i1_icaf_d = pc1[32];
|
||||||
assign dec_i0_icaf_d = pc0[32];
|
assign dec_i0_icaf_d = pc0[32];
|
||||||
|
|
||||||
assign dec_i1_pc_d[31:1] = pc1[31:1];
|
assign dec_i1_pc_d[31:1] = pc1[31:1];
|
||||||
assign dec_i0_pc_d[31:1] = pc0[31:1];
|
assign dec_i0_pc_d[31:1] = pc0[31:1];
|
||||||
|
|
||||||
assign dec_i1_pc4_d = pc1[0];
|
assign dec_i1_pc4_d = pc1[0];
|
||||||
assign dec_i0_pc4_d = pc0[0];
|
assign dec_i0_pc4_d = pc0[0];
|
||||||
|
|
||||||
// branch prediction
|
// branch prediction
|
||||||
|
|
||||||
logic [$bits(br_pkt_t)-1:0] bp3_in,bp3,bp2_in,bp2,bp1_in,bp1,bp0_in,bp0;
|
logic [$bits(br_pkt_t)-1:0] bp3_in,bp3,bp2_in,bp2,bp1_in,bp1,bp0_in,bp0;
|
||||||
|
|
||||||
if (DEC_INSTBUF_DEPTH==4) begin
|
if (DEC_INSTBUF_DEPTH==4) begin
|
||||||
assign bp3_in = ({$bits(br_pkt_t){write_i0_ib3}} & i0_brp) |
|
assign bp3_in = ({$bits(br_pkt_t){write_i0_ib3}} & i0_brp) |
|
||||||
({$bits(br_pkt_t){write_i1_ib3}} & i1_brp);
|
({$bits(br_pkt_t){write_i1_ib3}} & i1_brp);
|
||||||
|
|
||||||
rvdffe #($bits(br_pkt_t)) bp3ff (.*, .en(ibwrite[3]), .din(bp3_in), .dout(bp3));
|
rvdffe #($bits(br_pkt_t)) bp3ff (.*, .en(ibwrite[3]), .din(bp3_in), .dout(bp3));
|
||||||
|
|
||||||
assign bp2_in = ({$bits(br_pkt_t){write_i0_ib2}} & i0_brp) |
|
assign bp2_in = ({$bits(br_pkt_t){write_i0_ib2}} & i0_brp) |
|
||||||
({$bits(br_pkt_t){write_i1_ib2}} & i1_brp) |
|
({$bits(br_pkt_t){write_i1_ib2}} & i1_brp) |
|
||||||
({$bits(br_pkt_t){shift_ib3_ib2}} & bp3);
|
({$bits(br_pkt_t){shift_ib3_ib2}} & bp3);
|
||||||
|
|
||||||
rvdffe #($bits(br_pkt_t)) bp2ff (.*, .en(ibwrite[2]), .din(bp2_in), .dout(bp2));
|
rvdffe #($bits(br_pkt_t)) bp2ff (.*, .en(ibwrite[2]), .din(bp2_in), .dout(bp2));
|
||||||
end // if (DEC_INSTBUF_DEPTH==4)
|
end // if (DEC_INSTBUF_DEPTH==4)
|
||||||
else begin
|
else begin
|
||||||
assign bp3 = '0;
|
assign bp3 = '0;
|
||||||
assign bp2 = '0;
|
assign bp2 = '0;
|
||||||
end
|
end
|
||||||
|
|
||||||
assign bp1_in = ({$bits(br_pkt_t){write_i0_ib1}} & i0_brp) |
|
assign bp1_in = ({$bits(br_pkt_t){write_i0_ib1}} & i0_brp) |
|
||||||
({$bits(br_pkt_t){write_i1_ib1}} & i1_brp) |
|
({$bits(br_pkt_t){write_i1_ib1}} & i1_brp) |
|
||||||
({$bits(br_pkt_t){shift_ib2_ib1}} & bp2) |
|
({$bits(br_pkt_t){shift_ib2_ib1}} & bp2) |
|
||||||
({$bits(br_pkt_t){shift_ib3_ib1}} & bp3);
|
({$bits(br_pkt_t){shift_ib3_ib1}} & bp3);
|
||||||
|
|
||||||
rvdffe #($bits(br_pkt_t)) bp1ff (.*, .en(ibwrite[1]), .din(bp1_in), .dout(bp1));
|
rvdffe #($bits(br_pkt_t)) bp1ff (.*, .en(ibwrite[1]), .din(bp1_in), .dout(bp1));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
assign bp0_in = ({$bits(br_pkt_t){write_i0_ib0}} & i0_brp) |
|
assign bp0_in = ({$bits(br_pkt_t){write_i0_ib0}} & i0_brp) |
|
||||||
({$bits(br_pkt_t){shift_ib1_ib0}} & bp1) |
|
({$bits(br_pkt_t){shift_ib1_ib0}} & bp1) |
|
||||||
({$bits(br_pkt_t){shift_ib2_ib0}} & bp2);
|
({$bits(br_pkt_t){shift_ib2_ib0}} & bp2);
|
||||||
|
|
||||||
rvdffe #($bits(br_pkt_t)) bp0ff (.*, .en(ibwrite[0]), .din(bp0_in), .dout(bp0));
|
rvdffe #($bits(br_pkt_t)) bp0ff (.*, .en(ibwrite[0]), .din(bp0_in), .dout(bp0));
|
||||||
|
|
||||||
// instruction buffers
|
// instruction buffers
|
||||||
|
@ -336,25 +336,25 @@ module dec_ib_ctl
|
||||||
if (DEC_INSTBUF_DEPTH==4) begin
|
if (DEC_INSTBUF_DEPTH==4) begin
|
||||||
assign ib3_in[31:0] = ({32{write_i0_ib3}} & ifu_i0_instr[31:0]) |
|
assign ib3_in[31:0] = ({32{write_i0_ib3}} & ifu_i0_instr[31:0]) |
|
||||||
({32{write_i1_ib3}} & ifu_i1_instr[31:0]);
|
({32{write_i1_ib3}} & ifu_i1_instr[31:0]);
|
||||||
|
|
||||||
rvdffe #(32) ib3ff (.*, .en(ibwrite[3]), .din(ib3_in[31:0]), .dout(ib3[31:0]));
|
rvdffe #(32) ib3ff (.*, .en(ibwrite[3]), .din(ib3_in[31:0]), .dout(ib3[31:0]));
|
||||||
|
|
||||||
assign ib2_in[31:0] = ({32{write_i0_ib2}} & ifu_i0_instr[31:0]) |
|
assign ib2_in[31:0] = ({32{write_i0_ib2}} & ifu_i0_instr[31:0]) |
|
||||||
({32{write_i1_ib2}} & ifu_i1_instr[31:0]) |
|
({32{write_i1_ib2}} & ifu_i1_instr[31:0]) |
|
||||||
({32{shift_ib3_ib2}} & ib3[31:0]);
|
({32{shift_ib3_ib2}} & ib3[31:0]);
|
||||||
|
|
||||||
rvdffe #(32) ib2ff (.*, .en(ibwrite[2]), .din(ib2_in[31:0]), .dout(ib2[31:0]));
|
rvdffe #(32) ib2ff (.*, .en(ibwrite[2]), .din(ib2_in[31:0]), .dout(ib2[31:0]));
|
||||||
end // if (DEC_INSTBUF_DEPTH==4)
|
end // if (DEC_INSTBUF_DEPTH==4)
|
||||||
else begin
|
else begin
|
||||||
assign ib3 = '0;
|
assign ib3 = '0;
|
||||||
assign ib2 = '0;
|
assign ib2 = '0;
|
||||||
end
|
end
|
||||||
|
|
||||||
assign ib1_in[31:0] = ({32{write_i0_ib1}} & ifu_i0_instr[31:0]) |
|
assign ib1_in[31:0] = ({32{write_i0_ib1}} & ifu_i0_instr[31:0]) |
|
||||||
({32{write_i1_ib1}} & ifu_i1_instr[31:0]) |
|
({32{write_i1_ib1}} & ifu_i1_instr[31:0]) |
|
||||||
({32{shift_ib2_ib1}} & ib2[31:0]) |
|
({32{shift_ib2_ib1}} & ib2[31:0]) |
|
||||||
({32{shift_ib3_ib1}} & ib3[31:0]);
|
({32{shift_ib3_ib1}} & ib3[31:0]);
|
||||||
|
|
||||||
rvdffe #(32) ib1ff (.*, .en(ibwrite[1]), .din(ib1_in[31:0]), .dout(ib1[31:0]));
|
rvdffe #(32) ib1ff (.*, .en(ibwrite[1]), .din(ib1_in[31:0]), .dout(ib1[31:0]));
|
||||||
|
|
||||||
|
|
||||||
|
@ -375,21 +375,21 @@ module dec_ib_ctl
|
||||||
// put write data on rs1
|
// put write data on rs1
|
||||||
// write -> csrrw %x0, %csr, %x0 {csr[11:0],00000001000001110011}
|
// write -> csrrw %x0, %csr, %x0 {csr[11:0],00000001000001110011}
|
||||||
|
|
||||||
// abstract memory command not done here
|
// abstract memory command not done here
|
||||||
assign debug_valid = dbg_cmd_valid & (dbg_cmd_type[1:0] != 2'h2);
|
assign debug_valid = dbg_cmd_valid & (dbg_cmd_type[1:0] != 2'h2);
|
||||||
|
|
||||||
|
|
||||||
assign debug_read = debug_valid & ~dbg_cmd_write;
|
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_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_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 debug_write_csr = debug_write & (dbg_cmd_type[1:0]==2'h1);
|
||||||
|
|
||||||
assign dreg[4:0] = dbg_cmd_addr[4:0];
|
assign dreg[4:0] = dbg_cmd_addr[4:0];
|
||||||
assign dcsr[11:0] = dbg_cmd_addr[11: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}) |
|
assign ib0_debug_in[31:0] = ({32{debug_read_gpr}} & {12'b000000000000,dreg[4:0],15'b110000000110011}) |
|
||||||
({32{debug_write_gpr}} & {20'b00000000000000000110,dreg[4:0],7'b0110011}) |
|
({32{debug_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
|
// special fence csr for use only in debug mode
|
||||||
|
|
||||||
logic debug_fence_in;
|
logic debug_fence_in;
|
||||||
|
|
||||||
assign debug_fence_in = debug_write_csr & (dcsr[11:0] == 12'h7c4);
|
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])) |
|
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_ib1_ib0}} & ib1[31:0]) |
|
||||||
({32{shift_ib2_ib0}} & ib2[31:0]);
|
({32{shift_ib2_ib0}} & ib2[31:0]);
|
||||||
|
|
||||||
rvdffe #(32) ib0ff (.*, .en(ibwrite[0]), .din(ib0_in[31:0]), .dout(ib0[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_ib3_valid_d = ibval[3];
|
||||||
assign dec_ib2_valid_d = ibval[2];
|
assign dec_ib2_valid_d = ibval[2];
|
||||||
assign dec_ib1_valid_d = ibval[1];
|
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_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_i0_brp = bp0;
|
||||||
assign dec_i1_brp = bp1;
|
assign dec_i1_brp = bp1;
|
||||||
|
|
||||||
|
|
||||||
assign shift1 = dec_i0_decode_d & ~dec_i1_decode_d;
|
assign shift1 = dec_i0_decode_d & ~dec_i1_decode_d;
|
||||||
|
|
||||||
assign shift2 = dec_i0_decode_d & dec_i1_decode_d;
|
assign shift2 = dec_i0_decode_d & dec_i1_decode_d;
|
||||||
|
|
||||||
assign shift0 = ~dec_i0_decode_d;
|
assign shift0 = ~dec_i0_decode_d;
|
||||||
|
|
||||||
|
|
||||||
// compute shifted ib valids to determine where to write
|
// compute shifted ib valids to determine where to write
|
||||||
assign shift_ibval[3:0] = ({4{shift1}} & {1'b0, ibval[3:1] }) |
|
assign shift_ibval[3:0] = ({4{shift1}} & {1'b0, ibval[3:1] }) |
|
||||||
({4{shift2}} & {2'b0, ibval[3:2]}) |
|
({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_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_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_i0_ib3 = shift_ibval[2] & ~shift_ibval[3] & ifu_i0_val;
|
||||||
|
|
||||||
assign write_i1_ib1 = ~shift_ibval[0] & ifu_i1_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_ib2 = shift_ibval[0] & ~shift_ibval[1] & ifu_i1_val;
|
||||||
assign write_i1_ib3 = shift_ibval[1] & ~shift_ibval[2] & 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_ib1_ib0 = shift1 & ibval[1];
|
||||||
assign shift_ib2_ib1 = shift1 & ibval[2];
|
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_ib2_ib0 = shift2 & ibval[2];
|
||||||
assign shift_ib3_ib1 = shift2 & ibval[3];
|
assign shift_ib3_ib1 = shift2 & ibval[3];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,12 +1,12 @@
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
// Copyright 2019 Western Digital Corporation or its affiliates.
|
// Copyright 2019 Western Digital Corporation or its affiliates.
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "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 not use this file except in compliance with the License.
|
||||||
// You may obtain a copy of the License at
|
// You may obtain a copy of the License at
|
||||||
//
|
//
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
//
|
//
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
@ -16,13 +16,13 @@
|
||||||
//********************************************************************************
|
//********************************************************************************
|
||||||
// $Id$
|
// $Id$
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// Owner:
|
// Owner:
|
||||||
// Function: DEC Trigger Logic
|
// Function: DEC Trigger Logic
|
||||||
// Comments:
|
// Comments:
|
||||||
//
|
//
|
||||||
//********************************************************************************
|
//********************************************************************************
|
||||||
module dec_trigger
|
module dec_trigger
|
||||||
import swerv_types::*;
|
import swerv_types::*;
|
||||||
(
|
(
|
||||||
input logic clk,
|
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 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_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_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][31:0] dec_i0_match_data;
|
||||||
logic [3:0] dec_i0_trigger_data_match;
|
logic [3:0] dec_i0_trigger_data_match;
|
||||||
logic [3:0][31:0] dec_i1_match_data;
|
logic [3:0][31:0] dec_i1_match_data;
|
||||||
logic [3:0] dec_i1_trigger_data_match;
|
logic [3:0] dec_i1_trigger_data_match;
|
||||||
|
|
||||||
for (genvar i=0; i<4; i++) begin
|
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_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
|
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]));
|
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];
|
assign dec_i0_trigger_match_d[i] = trigger_pkt_any[i].execute & trigger_pkt_any[i].m & dec_i0_trigger_data_match[i];
|
||||||
|
|
|
@ -3,21 +3,21 @@
|
||||||
|
|
||||||
add = [0000000..........000.....0110011]
|
add = [0000000..........000.....0110011]
|
||||||
addi = [.................000.....0010011]
|
addi = [.................000.....0010011]
|
||||||
|
|
||||||
sub = [0100000..........000.....0110011]
|
sub = [0100000..........000.....0110011]
|
||||||
|
|
||||||
and = [0000000..........111.....0110011]
|
and = [0000000..........111.....0110011]
|
||||||
andi = [.................111.....0010011]
|
andi = [.................111.....0010011]
|
||||||
|
|
||||||
or = [0000000..........110.....0110011]
|
or = [0000000..........110.....0110011]
|
||||||
ori = [.................110.....0010011]
|
ori = [.................110.....0010011]
|
||||||
|
|
||||||
xor = [0000000..........100.....0110011]
|
xor = [0000000..........100.....0110011]
|
||||||
xori = [.................100.....0010011]
|
xori = [.................100.....0010011]
|
||||||
|
|
||||||
sll = [0000000..........001.....0110011]
|
sll = [0000000..........001.....0110011]
|
||||||
slli = [0000000..........001.....0010011]
|
slli = [0000000..........001.....0010011]
|
||||||
|
|
||||||
sra = [0100000..........101.....0110011]
|
sra = [0100000..........101.....0110011]
|
||||||
srai = [0100000..........101.....0010011]
|
srai = [0100000..........101.....0010011]
|
||||||
|
|
||||||
|
@ -26,30 +26,30 @@ srli = [0000000..........101.....0010011]
|
||||||
|
|
||||||
lui = [.........................0110111]
|
lui = [.........................0110111]
|
||||||
auipc= [.........................0010111]
|
auipc= [.........................0010111]
|
||||||
|
|
||||||
slt = [0000000..........010.....0110011]
|
slt = [0000000..........010.....0110011]
|
||||||
sltu = [0000000..........011.....0110011]
|
sltu = [0000000..........011.....0110011]
|
||||||
slti = [.................010.....0010011]
|
slti = [.................010.....0010011]
|
||||||
sltiu= [.................011.....0010011]
|
sltiu= [.................011.....0010011]
|
||||||
|
|
||||||
beq = [.................000.....1100011]
|
beq = [.................000.....1100011]
|
||||||
bne = [.................001.....1100011]
|
bne = [.................001.....1100011]
|
||||||
bge = [.................101.....1100011]
|
bge = [.................101.....1100011]
|
||||||
blt = [.................100.....1100011]
|
blt = [.................100.....1100011]
|
||||||
bgeu = [.................111.....1100011]
|
bgeu = [.................111.....1100011]
|
||||||
bltu = [.................110.....1100011]
|
bltu = [.................110.....1100011]
|
||||||
|
|
||||||
jal = [.........................1101111]
|
jal = [.........................1101111]
|
||||||
jalr = [.................000.....1100111]
|
jalr = [.................000.....1100111]
|
||||||
|
|
||||||
lb = [.................000.....0000011]
|
lb = [.................000.....0000011]
|
||||||
lh = [.................001.....0000011]
|
lh = [.................001.....0000011]
|
||||||
lw = [.................010.....0000011]
|
lw = [.................010.....0000011]
|
||||||
|
|
||||||
sb = [.................000.....0100011]
|
sb = [.................000.....0100011]
|
||||||
sh = [.................001.....0100011]
|
sh = [.................001.....0100011]
|
||||||
sw = [.................010.....0100011]
|
sw = [.................010.....0100011]
|
||||||
|
|
||||||
lbu = [.................100.....0000011]
|
lbu = [.................100.....0000011]
|
||||||
lhu = [.................101.....0000011]
|
lhu = [.................101.....0000011]
|
||||||
|
|
||||||
|
@ -117,41 +117,41 @@ rem = [0000001..........110.....0110011]
|
||||||
remu = [0000001..........111.....0110011]
|
remu = [0000001..........111.....0110011]
|
||||||
|
|
||||||
|
|
||||||
.input
|
.input
|
||||||
|
|
||||||
rv32i = {
|
rv32i = {
|
||||||
i[31]
|
i[31]
|
||||||
i[30]
|
i[30]
|
||||||
i[29]
|
i[29]
|
||||||
i[28]
|
i[28]
|
||||||
i[27]
|
i[27]
|
||||||
i[26]
|
i[26]
|
||||||
i[25]
|
i[25]
|
||||||
i[24]
|
i[24]
|
||||||
i[23]
|
i[23]
|
||||||
i[22]
|
i[22]
|
||||||
i[21]
|
i[21]
|
||||||
i[20]
|
i[20]
|
||||||
i[19]
|
i[19]
|
||||||
i[18]
|
i[18]
|
||||||
i[17]
|
i[17]
|
||||||
i[16]
|
i[16]
|
||||||
i[15]
|
i[15]
|
||||||
i[14]
|
i[14]
|
||||||
i[13]
|
i[13]
|
||||||
i[12]
|
i[12]
|
||||||
i[11]
|
i[11]
|
||||||
i[10]
|
i[10]
|
||||||
i[9]
|
i[9]
|
||||||
i[8]
|
i[8]
|
||||||
i[7]
|
i[7]
|
||||||
i[6]
|
i[6]
|
||||||
i[5]
|
i[5]
|
||||||
i[4]
|
i[4]
|
||||||
i[3]
|
i[3]
|
||||||
i[2]
|
i[2]
|
||||||
i[1]
|
i[1]
|
||||||
i[0]
|
i[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -188,7 +188,7 @@ rv32i = {
|
||||||
by
|
by
|
||||||
half
|
half
|
||||||
word
|
word
|
||||||
csr_read
|
csr_read
|
||||||
csr_clr
|
csr_clr
|
||||||
csr_set
|
csr_set
|
||||||
csr_write
|
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
|
# 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[csrrc_rw{0-4}] = { alu rd csr_read rs1 csr_clr lor presync postsync }
|
||||||
|
|
||||||
rv32i[csrrci_ro] = { alu rd csr_read lor }
|
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[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_ro] = { alu rd csr_read lor }
|
||||||
|
|
||||||
rv32i[csrrs_rw{0-4}] = { alu rd csr_read rs1 csr_set lor presync postsync }
|
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_ro] = { alu rd csr_read lor }
|
||||||
|
|
||||||
rv32i[csrrsi_rw{0-4}] = { alu rd csr_read rs1 csr_set csr_imm lor presync postsync }
|
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[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 }
|
rv32i[csrrwi{0-4}] = { alu rd csr_read rs1 csr_write csr_imm lor presync postsync }
|
||||||
|
|
||||||
# optimize csr write only - pipelined
|
# optimize csr write only - pipelined
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
// Copyright 2019 Western Digital Corporation or its affiliates.
|
// Copyright 2019 Western Digital Corporation or its affiliates.
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "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 not use this file except in compliance with the License.
|
||||||
// You may obtain a copy of the License at
|
// You may obtain a copy of the License at
|
||||||
//
|
//
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
//
|
//
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
@ -17,7 +17,7 @@
|
||||||
// $Id$
|
// $Id$
|
||||||
//
|
//
|
||||||
// Function: Top level SWERV core file
|
// 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 dma_bus_clk_en, // slave bus clock enable
|
||||||
input logic clk_override,
|
input logic clk_override,
|
||||||
|
|
||||||
// AXI signals
|
// AXI signals
|
||||||
// AXI Write Channels
|
// AXI Write Channels
|
||||||
input logic dma_axi_awvalid,
|
input logic dma_axi_awvalid,
|
||||||
output logic dma_axi_awready,
|
output logic dma_axi_awready,
|
||||||
|
@ -39,12 +39,12 @@ module dma_ctrl (
|
||||||
input logic [7:0] dma_axi_awlen,
|
input logic [7:0] dma_axi_awlen,
|
||||||
input logic [1:0] dma_axi_awburst,
|
input logic [1:0] dma_axi_awburst,
|
||||||
|
|
||||||
input logic dma_axi_wvalid,
|
input logic dma_axi_wvalid,
|
||||||
output logic dma_axi_wready,
|
output logic dma_axi_wready,
|
||||||
input logic [63:0] dma_axi_wdata,
|
input logic [63:0] dma_axi_wdata,
|
||||||
input logic [7:0] dma_axi_wstrb,
|
input logic [7:0] dma_axi_wstrb,
|
||||||
input logic dma_axi_wlast,
|
input logic dma_axi_wlast,
|
||||||
|
|
||||||
output logic dma_axi_bvalid,
|
output logic dma_axi_bvalid,
|
||||||
input logic dma_axi_bready,
|
input logic dma_axi_bready,
|
||||||
output logic [1:0] dma_axi_bresp,
|
output logic [1:0] dma_axi_bresp,
|
||||||
|
@ -54,7 +54,7 @@ module dma_ctrl (
|
||||||
input logic dma_axi_arvalid,
|
input logic dma_axi_arvalid,
|
||||||
output logic dma_axi_arready,
|
output logic dma_axi_arready,
|
||||||
input logic [`RV_DMA_BUS_TAG-1:0] dma_axi_arid,
|
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_arsize,
|
||||||
input logic [2:0] dma_axi_arprot,
|
input logic [2:0] dma_axi_arprot,
|
||||||
input logic [7:0] dma_axi_arlen,
|
input logic [7:0] dma_axi_arlen,
|
||||||
|
@ -67,13 +67,13 @@ module dma_ctrl (
|
||||||
output logic [1:0] dma_axi_rresp,
|
output logic [1:0] dma_axi_rresp,
|
||||||
output logic dma_axi_rlast,
|
output logic dma_axi_rlast,
|
||||||
|
|
||||||
output logic dma_slv_algn_err,
|
output logic dma_slv_algn_err,
|
||||||
// Debug signals
|
// Debug signals
|
||||||
input logic [31:0] dbg_cmd_addr,
|
input logic [31:0] dbg_cmd_addr,
|
||||||
input logic [31:0] dbg_cmd_wrdata,
|
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 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 [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
|
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_done,
|
||||||
output logic dma_dbg_cmd_fail,
|
output logic dma_dbg_cmd_fail,
|
||||||
output logic [31:0] dma_dbg_rddata,
|
output logic [31:0] dma_dbg_rddata,
|
||||||
|
|
||||||
// Core side signals
|
// Core side signals
|
||||||
output logic dma_dccm_req, // DMA dccm request (only one of dccm/iccm will be set)
|
output logic dma_dccm_req, // DMA dccm request (only one of dccm/iccm will be set)
|
||||||
output logic dma_iccm_req, // DMA iccm request
|
output logic 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 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 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 [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"
|
`include "global.h"
|
||||||
|
|
||||||
localparam DEPTH = DMA_BUF_DEPTH;
|
localparam DEPTH = DMA_BUF_DEPTH;
|
||||||
localparam DEPTH_PTR = $clog2(DEPTH);
|
localparam DEPTH_PTR = $clog2(DEPTH);
|
||||||
localparam NACK_COUNT = 7;
|
localparam NACK_COUNT = 7;
|
||||||
|
|
||||||
logic [DEPTH-1:0] fifo_valid;
|
logic [DEPTH-1:0] fifo_valid;
|
||||||
logic [DEPTH-1:0][1:0] fifo_error;
|
logic [DEPTH-1:0][1:0] fifo_error;
|
||||||
logic [DEPTH-1:0] fifo_dccm_valid;
|
logic [DEPTH-1:0] fifo_dccm_valid;
|
||||||
|
@ -132,7 +132,7 @@ module dma_ctrl (
|
||||||
logic [DEPTH-1:0] fifo_dbg;
|
logic [DEPTH-1:0] fifo_dbg;
|
||||||
logic [DEPTH-1:0][63:0] fifo_data;
|
logic [DEPTH-1:0][63:0] fifo_data;
|
||||||
logic [DEPTH-1:0][DMA_BUS_TAG-1:0] fifo_tag;
|
logic [DEPTH-1:0][DMA_BUS_TAG-1:0] fifo_tag;
|
||||||
|
|
||||||
logic [DEPTH-1:0] fifo_cmd_en;
|
logic [DEPTH-1:0] fifo_cmd_en;
|
||||||
logic [DEPTH-1:0] fifo_valid_en;
|
logic [DEPTH-1:0] fifo_valid_en;
|
||||||
logic [DEPTH-1:0] fifo_data_en;
|
logic [DEPTH-1:0] fifo_data_en;
|
||||||
|
@ -152,7 +152,7 @@ module dma_ctrl (
|
||||||
logic fifo_dbg_in;
|
logic fifo_dbg_in;
|
||||||
logic [31:0] fifo_addr_in;
|
logic [31:0] fifo_addr_in;
|
||||||
logic [2:0] fifo_sz_in;
|
logic [2:0] fifo_sz_in;
|
||||||
|
|
||||||
logic [DEPTH_PTR-1:0] RspPtr, PrevRspPtr, NxtRspPtr;
|
logic [DEPTH_PTR-1:0] RspPtr, PrevRspPtr, NxtRspPtr;
|
||||||
logic [DEPTH_PTR-1:0] WrPtr, NxtWrPtr;
|
logic [DEPTH_PTR-1:0] WrPtr, NxtWrPtr;
|
||||||
logic [DEPTH_PTR-1:0] RdPtr, NxtRdPtr;
|
logic [DEPTH_PTR-1:0] RdPtr, NxtRdPtr;
|
||||||
|
@ -164,7 +164,7 @@ module dma_ctrl (
|
||||||
|
|
||||||
logic fifo_full, fifo_full_spec, fifo_empty;
|
logic fifo_full, fifo_full_spec, fifo_empty;
|
||||||
logic dma_address_error, dma_alignment_error;
|
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_mem_req;
|
||||||
logic dma_addr_in_dccm;
|
logic dma_addr_in_dccm;
|
||||||
logic dma_addr_in_iccm;
|
logic dma_addr_in_iccm;
|
||||||
|
@ -172,7 +172,7 @@ module dma_ctrl (
|
||||||
logic dma_addr_in_pic_region_nc;
|
logic dma_addr_in_pic_region_nc;
|
||||||
logic dma_addr_in_dccm_region_nc;
|
logic dma_addr_in_dccm_region_nc;
|
||||||
logic dma_addr_in_iccm_region_nc;
|
logic dma_addr_in_iccm_region_nc;
|
||||||
|
|
||||||
logic [2:0] dma_nack_count_csr;
|
logic [2:0] dma_nack_count_csr;
|
||||||
logic [2:0] dma_nack_count, dma_nack_count_d;
|
logic [2:0] dma_nack_count, dma_nack_count_d;
|
||||||
|
|
||||||
|
@ -181,7 +181,7 @@ module dma_ctrl (
|
||||||
logic dma_buffer_c1_clk;
|
logic dma_buffer_c1_clk;
|
||||||
logic dma_free_clk;
|
logic dma_free_clk;
|
||||||
logic dma_bus_clk;
|
logic dma_bus_clk;
|
||||||
|
|
||||||
|
|
||||||
logic wrbuf_en, wrbuf_data_en;
|
logic wrbuf_en, wrbuf_data_en;
|
||||||
logic wrbuf_cmd_sent, wrbuf_rst, wrbuf_data_rst;
|
logic wrbuf_cmd_sent, wrbuf_rst, wrbuf_data_rst;
|
||||||
|
@ -193,7 +193,7 @@ module dma_ctrl (
|
||||||
logic [31:0] wrbuf_addr;
|
logic [31:0] wrbuf_addr;
|
||||||
logic [63:0] wrbuf_data;
|
logic [63:0] wrbuf_data;
|
||||||
logic [7:0] wrbuf_byteen;
|
logic [7:0] wrbuf_byteen;
|
||||||
|
|
||||||
logic rdbuf_en;
|
logic rdbuf_en;
|
||||||
logic rdbuf_cmd_sent, rdbuf_rst;
|
logic rdbuf_cmd_sent, rdbuf_rst;
|
||||||
logic rdbuf_vld;
|
logic rdbuf_vld;
|
||||||
|
@ -210,7 +210,7 @@ module dma_ctrl (
|
||||||
logic [2:0] axi_mstr_size;
|
logic [2:0] axi_mstr_size;
|
||||||
logic [63:0] axi_mstr_wdata;
|
logic [63:0] axi_mstr_wdata;
|
||||||
logic [7:0] axi_mstr_wstrb;
|
logic [7:0] axi_mstr_wstrb;
|
||||||
|
|
||||||
logic axi_mstr_prty_in, axi_mstr_prty_en;
|
logic axi_mstr_prty_in, axi_mstr_prty_en;
|
||||||
logic axi_mstr_priority;
|
logic axi_mstr_priority;
|
||||||
logic axi_mstr_sel;
|
logic axi_mstr_sel;
|
||||||
|
@ -222,7 +222,7 @@ module dma_ctrl (
|
||||||
logic [DMA_BUS_TAG-1:0] axi_slv_tag;
|
logic [DMA_BUS_TAG-1:0] axi_slv_tag;
|
||||||
logic [1:0] axi_slv_error;
|
logic [1:0] axi_slv_error;
|
||||||
logic [63:0] axi_slv_rdata;
|
logic [63:0] axi_slv_rdata;
|
||||||
|
|
||||||
logic dma_bus_clk_en_q;
|
logic dma_bus_clk_en_q;
|
||||||
logic fifo_full_spec_bus;
|
logic fifo_full_spec_bus;
|
||||||
logic dbg_dma_bubble_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_posted_write_in = axi_mstr_valid & axi_mstr_posted_write;
|
||||||
assign fifo_dbg_in = dbg_cmd_valid;
|
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_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]));
|
// (dbg_cmd_valid ? {2{dbg_cmd_wrdata[31:0]}} : axi_mstr_wdata[63:0]));
|
||||||
|
|
||||||
for (genvar i=0 ;i<DEPTH; i++) begin: GenFifo
|
for (genvar i=0 ;i<DEPTH; i++) begin: GenFifo
|
||||||
assign fifo_valid_en[i] = axi_mstr_valid & (i == WrPtr[DEPTH_PTR-1:0]);
|
assign fifo_valid_en[i] = axi_mstr_valid & (i == WrPtr[DEPTH_PTR-1:0]);
|
||||||
assign fifo_cmd_en[i] = ((axi_mstr_valid & dma_bus_clk_en) | (dbg_cmd_valid & dbg_cmd_type[1])) &
|
assign fifo_cmd_en[i] = ((axi_mstr_valid & dma_bus_clk_en) | (dbg_cmd_valid & dbg_cmd_type[1])) &
|
||||||
(i == WrPtr[DEPTH_PTR-1:0]);
|
(i == WrPtr[DEPTH_PTR-1:0]);
|
||||||
assign fifo_data_en[i] = (((axi_mstr_valid & (axi_mstr_write | dma_address_error | dma_alignment_error) & dma_bus_clk_en) |
|
assign fifo_data_en[i] = (((axi_mstr_valid & (axi_mstr_write | dma_address_error | dma_alignment_error) & dma_bus_clk_en) |
|
||||||
(dbg_cmd_valid & dbg_cmd_type[1] & dbg_cmd_write)) & (i == WrPtr[DEPTH_PTR-1:0])) |
|
(dbg_cmd_valid & dbg_cmd_type[1] & dbg_cmd_write)) & (i == WrPtr[DEPTH_PTR-1:0])) |
|
||||||
((dccm_dma_rvalid & (i == RdPtr_Q3[DEPTH_PTR-1:0]))| (iccm_dma_rvalid & (i == RdPtr_Q2[DEPTH_PTR-1:0])));
|
((dccm_dma_rvalid & (i == RdPtr_Q3[DEPTH_PTR-1:0]))| (iccm_dma_rvalid & (i == RdPtr_Q2[DEPTH_PTR-1:0])));
|
||||||
assign fifo_data_bus_en[i] = (fifo_data_en[i] | fifo_data_valid[i]) & dma_bus_clk_en;
|
assign fifo_data_bus_en[i] = (fifo_data_en[i] | fifo_data_valid[i]) & dma_bus_clk_en;
|
||||||
|
@ -256,14 +256,14 @@ module dma_ctrl (
|
||||||
((dccm_dma_rvalid & (i == RdPtr_Q3[DEPTH_PTR-1:0])) | (iccm_dma_rvalid & (i == RdPtr_Q2[DEPTH_PTR-1:0])));
|
((dccm_dma_rvalid & (i == RdPtr_Q3[DEPTH_PTR-1:0])) | (iccm_dma_rvalid & (i == RdPtr_Q2[DEPTH_PTR-1:0])));
|
||||||
assign fifo_done_bus_en[i] = (fifo_done_en[i] | fifo_done[i]) & dma_bus_clk_en;
|
assign fifo_done_bus_en[i] = (fifo_done_en[i] | fifo_done[i]) & dma_bus_clk_en;
|
||||||
//assign fifo_rsp_done_en[i] = fifo_valid[i] & ((axi_slv_sent & dma_bus_clk_en) | dma_dbg_cmd_done) & (i == RspPtr[DEPTH_PTR-1:0]);
|
//assign fifo_rsp_done_en[i] = fifo_valid[i] & ((axi_slv_sent & dma_bus_clk_en) | dma_dbg_cmd_done) & (i == RspPtr[DEPTH_PTR-1:0]);
|
||||||
//assign fifo_reset[i] = (fifo_done[i] | fifo_done_en[i]) & (fifo_rsp_done[i] | fifo_rsp_done_en[i]);
|
//assign fifo_reset[i] = (fifo_done[i] | fifo_done_en[i]) & (fifo_rsp_done[i] | fifo_rsp_done_en[i]);
|
||||||
assign fifo_reset[i] = ((axi_slv_sent & dma_bus_clk_en) | dma_dbg_cmd_done) & (i == RspPtr[DEPTH_PTR-1:0]);
|
assign fifo_reset[i] = ((axi_slv_sent & dma_bus_clk_en) | dma_dbg_cmd_done) & (i == RspPtr[DEPTH_PTR-1:0]);
|
||||||
assign fifo_error_in[i] = (dccm_dma_rvalid & (i == RdPtr_Q3[DEPTH_PTR-1:0])) ? {1'b0,dccm_dma_ecc_error} : (iccm_dma_rvalid & (i == RdPtr_Q2[DEPTH_PTR-1:0])) ? {1'b0,iccm_dma_ecc_error} :
|
assign fifo_error_in[i] = (dccm_dma_rvalid & (i == RdPtr_Q3[DEPTH_PTR-1:0])) ? {1'b0,dccm_dma_ecc_error} : (iccm_dma_rvalid & (i == RdPtr_Q2[DEPTH_PTR-1:0])) ? {1'b0,iccm_dma_ecc_error} :
|
||||||
{(dma_address_error | dma_alignment_error | dma_dbg_cmd_error_in), dma_alignment_error};
|
{(dma_address_error | dma_alignment_error | dma_dbg_cmd_error_in), dma_alignment_error};
|
||||||
assign fifo_data_in[i] = (fifo_error_en[i] & (|fifo_error_in[i])) ? (fifo_cmd_en[i] ? {32'b0,axi_mstr_addr[31:0]} : {32'b0,fifo_addr[i]}) :
|
assign fifo_data_in[i] = (fifo_error_en[i] & (|fifo_error_in[i])) ? (fifo_cmd_en[i] ? {32'b0,axi_mstr_addr[31:0]} : {32'b0,fifo_addr[i]}) :
|
||||||
((dccm_dma_rvalid & (i == RdPtr_Q3[DEPTH_PTR-1:0])) ? dccm_dma_rdata[63:0] : (iccm_dma_rvalid & (i == RdPtr_Q2[DEPTH_PTR-1:0])) ? iccm_dma_rdata[63:0] :
|
((dccm_dma_rvalid & (i == RdPtr_Q3[DEPTH_PTR-1:0])) ? dccm_dma_rdata[63:0] : (iccm_dma_rvalid & (i == RdPtr_Q2[DEPTH_PTR-1:0])) ? iccm_dma_rdata[63:0] :
|
||||||
(dbg_cmd_valid ? {2{dbg_cmd_wrdata[31:0]}} : axi_mstr_wdata[63:0]));
|
(dbg_cmd_valid ? {2{dbg_cmd_wrdata[31:0]}} : axi_mstr_wdata[63:0]));
|
||||||
|
|
||||||
rvdffsc #(1) fifo_valid_dff (.din(1'b1), .dout(fifo_valid[i]), .en(fifo_cmd_en[i]), .clear(fifo_reset[i]), .clk(dma_free_clk), .*);
|
rvdffsc #(1) fifo_valid_dff (.din(1'b1), .dout(fifo_valid[i]), .en(fifo_cmd_en[i]), .clear(fifo_reset[i]), .clk(dma_free_clk), .*);
|
||||||
rvdffsc #(2) fifo_error_dff (.din(fifo_error_in[i]), .dout(fifo_error[i]), .en(fifo_error_en[i]), .clear(fifo_reset[i]), .clk(dma_free_clk), .*);
|
rvdffsc #(2) fifo_error_dff (.din(fifo_error_in[i]), .dout(fifo_error[i]), .en(fifo_error_en[i]), .clear(fifo_reset[i]), .clk(dma_free_clk), .*);
|
||||||
rvdffsc #(1) fifo_error_bus_dff (.din(1'b1), .dout(fifo_error_bus[i]), .en(fifo_error_bus_en[i]), .clear(fifo_reset[i]), .clk(dma_free_clk), .*);
|
rvdffsc #(1) fifo_error_bus_dff (.din(1'b1), .dout(fifo_error_bus[i]), .en(fifo_error_bus_en[i]), .clear(fifo_reset[i]), .clk(dma_free_clk), .*);
|
||||||
|
@ -288,18 +288,18 @@ module dma_ctrl (
|
||||||
assign NxtWrPtr[DEPTH_PTR-1:0] = WrPtr[DEPTH_PTR-1:0] + 1'b1;
|
assign NxtWrPtr[DEPTH_PTR-1:0] = WrPtr[DEPTH_PTR-1:0] + 1'b1;
|
||||||
assign NxtRdPtr[DEPTH_PTR-1:0] = RdPtr[DEPTH_PTR-1:0] + 1'b1;
|
assign NxtRdPtr[DEPTH_PTR-1:0] = RdPtr[DEPTH_PTR-1:0] + 1'b1;
|
||||||
assign NxtRspPtr[DEPTH_PTR-1:0] = RspPtr[DEPTH_PTR-1:0] + 1'b1;
|
assign NxtRspPtr[DEPTH_PTR-1:0] = RspPtr[DEPTH_PTR-1:0] + 1'b1;
|
||||||
|
|
||||||
// Don't increment the ptr for posted writes if 1)fifo error (it will increment only with response) 2) response done (this is the full case)
|
// Don't increment the ptr for posted writes if 1)fifo error (it will increment only with response) 2) response done (this is the full case)
|
||||||
//assign RspPtr[DEPTH_PTR-1:0] = (dma_dbg_cmd_done_q | axi_slv_sent_q) ? (PrevRspPtr[DEPTH_PTR-1:0] + 1'b1) : PrevRspPtr[DEPTH_PTR-1:0];
|
//assign RspPtr[DEPTH_PTR-1:0] = (dma_dbg_cmd_done_q | axi_slv_sent_q) ? (PrevRspPtr[DEPTH_PTR-1:0] + 1'b1) : PrevRspPtr[DEPTH_PTR-1:0];
|
||||||
//assign RspPtr[DEPTH_PTR-1:0] = (dma_dbg_cmd_done_q | axi_slv_sent_q |
|
//assign RspPtr[DEPTH_PTR-1:0] = (dma_dbg_cmd_done_q | axi_slv_sent_q |
|
||||||
// (fifo_valid[PrevRspPtr] & fifo_write[PrevRspPtr] & fifo_posted_write[PrevRspPtr] & ~(|fifo_error[PrevRspPtr]) & ~fifo_rsp_done[PrevRspPtr])) ? (PrevRspPtr[DEPTH_PTR-1:0] + 1'b1) : PrevRspPtr[DEPTH_PTR-1:0];
|
// (fifo_valid[PrevRspPtr] & fifo_write[PrevRspPtr] & fifo_posted_write[PrevRspPtr] & ~(|fifo_error[PrevRspPtr]) & ~fifo_rsp_done[PrevRspPtr])) ? (PrevRspPtr[DEPTH_PTR-1:0] + 1'b1) : PrevRspPtr[DEPTH_PTR-1:0];
|
||||||
|
|
||||||
assign WrPtrEn = |fifo_cmd_en[DEPTH-1:0];
|
assign WrPtrEn = |fifo_cmd_en[DEPTH-1:0];
|
||||||
assign RdPtrEn = (dma_dccm_req | dma_iccm_req) | ((|fifo_error[RdPtr]) & ~fifo_done[RdPtr]);
|
assign RdPtrEn = (dma_dccm_req | dma_iccm_req) | ((|fifo_error[RdPtr]) & ~fifo_done[RdPtr]);
|
||||||
//assign RdPtrEn = |(fifo_done_en[DEPTH-1:0] & ~fifo_done[DEPTH-1:0]);
|
//assign RdPtrEn = |(fifo_done_en[DEPTH-1:0] & ~fifo_done[DEPTH-1:0]);
|
||||||
assign RspPtrEn = (dma_dbg_cmd_done | (axi_slv_sent & dma_bus_clk_en));
|
assign RspPtrEn = (dma_dbg_cmd_done | (axi_slv_sent & dma_bus_clk_en));
|
||||||
//assign RspPtrEn = dma_bus_clk_en | dma_dbg_cmd_done_q;
|
//assign RspPtrEn = dma_bus_clk_en | dma_dbg_cmd_done_q;
|
||||||
|
|
||||||
rvdffs #(DEPTH_PTR) WrPtr_dff(.din(NxtWrPtr[DEPTH_PTR-1:0]), .dout(WrPtr[DEPTH_PTR-1:0]), .en(WrPtrEn), .clk(dma_free_clk), .*);
|
rvdffs #(DEPTH_PTR) WrPtr_dff(.din(NxtWrPtr[DEPTH_PTR-1:0]), .dout(WrPtr[DEPTH_PTR-1:0]), .en(WrPtrEn), .clk(dma_free_clk), .*);
|
||||||
rvdffs #(DEPTH_PTR) RdPtr_dff(.din(NxtRdPtr[DEPTH_PTR-1:0]), .dout(RdPtr[DEPTH_PTR-1:0]), .en(RdPtrEn), .clk(dma_free_clk), .*);
|
rvdffs #(DEPTH_PTR) RdPtr_dff(.din(NxtRdPtr[DEPTH_PTR-1:0]), .dout(RdPtr[DEPTH_PTR-1:0]), .en(RdPtrEn), .clk(dma_free_clk), .*);
|
||||||
rvdffs #(DEPTH_PTR) RspPtr_dff(.din(NxtRspPtr[DEPTH_PTR-1:0]), .dout(RspPtr[DEPTH_PTR-1:0]), .en(RspPtrEn), .clk(dma_free_clk), .*);
|
rvdffs #(DEPTH_PTR) RspPtr_dff(.din(NxtRspPtr[DEPTH_PTR-1:0]), .dout(RspPtr[DEPTH_PTR-1:0]), .en(RspPtrEn), .clk(dma_free_clk), .*);
|
||||||
|
@ -311,7 +311,7 @@ module dma_ctrl (
|
||||||
|
|
||||||
// Miscellaneous signals
|
// Miscellaneous signals
|
||||||
assign fifo_full = fifo_full_spec_bus;
|
assign fifo_full = fifo_full_spec_bus;
|
||||||
|
|
||||||
always_comb begin
|
always_comb begin
|
||||||
num_fifo_vld[3:0] = 4'b0;
|
num_fifo_vld[3:0] = 4'b0;
|
||||||
for (int i=0; i<DEPTH; i++) begin
|
for (int i=0; i<DEPTH; i++) begin
|
||||||
|
@ -319,12 +319,12 @@ module dma_ctrl (
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
assign fifo_full_spec = ((num_fifo_vld[3:0] == DEPTH) & ~(|fifo_reset[DEPTH-1:0]));
|
assign fifo_full_spec = ((num_fifo_vld[3:0] == DEPTH) & ~(|fifo_reset[DEPTH-1:0]));
|
||||||
|
|
||||||
assign dma_fifo_ready = ~(fifo_full | dbg_dma_bubble_bus | dec_tlu_stall_dma_bus);
|
assign dma_fifo_ready = ~(fifo_full | dbg_dma_bubble_bus | dec_tlu_stall_dma_bus);
|
||||||
|
|
||||||
// Error logic
|
// Error logic
|
||||||
assign dma_address_error = axi_mstr_valid & (~(dma_addr_in_dccm | dma_addr_in_iccm)); // request not for ICCM or DCCM
|
assign dma_address_error = axi_mstr_valid & (~(dma_addr_in_dccm | dma_addr_in_iccm)); // request not for ICCM or DCCM
|
||||||
assign dma_alignment_error = axi_mstr_valid & ~dma_address_error &
|
assign dma_alignment_error = axi_mstr_valid & ~dma_address_error &
|
||||||
(((axi_mstr_size[2:0] == 3'h1) & (axi_mstr_addr[0] | (axi_mstr_write & (axi_mstr_wstrb[axi_mstr_addr[2:0]+:2] != 2'b11)))) | // HW size but unaligned
|
(((axi_mstr_size[2:0] == 3'h1) & (axi_mstr_addr[0] | (axi_mstr_write & (axi_mstr_wstrb[axi_mstr_addr[2:0]+:2] != 2'b11)))) | // HW size but unaligned
|
||||||
((axi_mstr_size[2:0] == 3'h2) & ((|axi_mstr_addr[1:0]) | (axi_mstr_write & (axi_mstr_wstrb[axi_mstr_addr[2:0]+:4] != 4'hf)))) | // W size but unaligned
|
((axi_mstr_size[2:0] == 3'h2) & ((|axi_mstr_addr[1:0]) | (axi_mstr_write & (axi_mstr_wstrb[axi_mstr_addr[2:0]+:4] != 4'hf)))) | // W size but unaligned
|
||||||
((axi_mstr_size[2:0] == 3'h3) & ((|axi_mstr_addr[2:0]) | (axi_mstr_write & (axi_mstr_wstrb[7:0] != 8'hff)))) | // DW size but unaligned
|
((axi_mstr_size[2:0] == 3'h3) & ((|axi_mstr_addr[2:0]) | (axi_mstr_write & (axi_mstr_wstrb[7:0] != 8'hff)))) | // DW size but unaligned
|
||||||
|
@ -337,23 +337,23 @@ module dma_ctrl (
|
||||||
assign dma_dbg_rddata[31:0] = fifo_addr[RspPtr][2] ? fifo_data[RspPtr][63:32] : fifo_data[RspPtr][31:0];
|
assign dma_dbg_rddata[31:0] = fifo_addr[RspPtr][2] ? fifo_data[RspPtr][63:32] : fifo_data[RspPtr][31:0];
|
||||||
assign dma_dbg_cmd_fail = |fifo_error[RspPtr];
|
assign dma_dbg_cmd_fail = |fifo_error[RspPtr];
|
||||||
|
|
||||||
assign dma_dbg_cmd_error_in = dbg_cmd_valid & (dbg_cmd_type[1:0] == 2'b10) &
|
assign dma_dbg_cmd_error_in = dbg_cmd_valid & (dbg_cmd_type[1:0] == 2'b10) &
|
||||||
((~(dma_addr_in_dccm | dma_addr_in_iccm | dma_addr_in_pic)) | (dbg_cmd_size[1:0] != 2'b10)); // Only word accesses allowed
|
((~(dma_addr_in_dccm | dma_addr_in_iccm | dma_addr_in_pic)) | (dbg_cmd_size[1:0] != 2'b10)); // Only word accesses allowed
|
||||||
//(dma_addr_in_iccm & ~((dbg_cmd_size[1:0] == 2'b10) | (dbg_cmd_size[1:0] == 2'b11))));
|
//(dma_addr_in_iccm & ~((dbg_cmd_size[1:0] == 2'b10) | (dbg_cmd_size[1:0] == 2'b11))));
|
||||||
|
|
||||||
|
|
||||||
// Block the decode if fifo full
|
// Block the decode if fifo full
|
||||||
assign dma_dccm_stall_any = dma_mem_req & fifo_dccm_valid[RdPtr] & (dma_nack_count >= dma_nack_count_csr);
|
assign dma_dccm_stall_any = dma_mem_req & fifo_dccm_valid[RdPtr] & (dma_nack_count >= dma_nack_count_csr);
|
||||||
assign dma_iccm_stall_any = dma_mem_req & fifo_iccm_valid[RdPtr] & (dma_nack_count >= 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
|
// 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
|
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
|
// 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_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;
|
(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), .*);
|
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
|
// Core outputs
|
||||||
|
@ -372,7 +372,7 @@ module dma_ctrl (
|
||||||
.in_range(dma_addr_in_dccm),
|
.in_range(dma_addr_in_dccm),
|
||||||
.in_region(dma_addr_in_dccm_region_nc)
|
.in_region(dma_addr_in_dccm_region_nc)
|
||||||
);
|
);
|
||||||
|
|
||||||
// Address check iccm
|
// Address check iccm
|
||||||
`ifdef RV_ICCM_ENABLE
|
`ifdef RV_ICCM_ENABLE
|
||||||
rvrangecheck #(.CCM_SADR(`RV_ICCM_SADR),
|
rvrangecheck #(.CCM_SADR(`RV_ICCM_SADR),
|
||||||
|
@ -385,7 +385,7 @@ module dma_ctrl (
|
||||||
assign dma_addr_in_iccm = '0;
|
assign dma_addr_in_iccm = '0;
|
||||||
assign dma_addr_in_iccm_region_nc = '0;
|
assign dma_addr_in_iccm_region_nc = '0;
|
||||||
`endif
|
`endif
|
||||||
|
|
||||||
// PIC memory address check
|
// PIC memory address check
|
||||||
rvrangecheck #(.CCM_SADR(`RV_PIC_BASE_ADDR),
|
rvrangecheck #(.CCM_SADR(`RV_PIC_BASE_ADDR),
|
||||||
.CCM_SIZE(`RV_PIC_SIZE)) addr_pic_rangecheck (
|
.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_buffer_c1cgc ( .en(dma_buffer_c1_clken), .l1clk(dma_buffer_c1_clk), .* );
|
||||||
rvoclkhdr dma_free_cgc (.en(dma_free_clken), .l1clk(dma_free_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), .*);
|
rvclkhdr dma_bus_cgc (.en(dma_bus_clk_en), .l1clk(dma_bus_clk), .*);
|
||||||
|
|
||||||
// Write channel buffer
|
// Write channel buffer
|
||||||
assign wrbuf_en = dma_axi_awvalid & dma_axi_awready;
|
assign wrbuf_en = dma_axi_awvalid & dma_axi_awready;
|
||||||
assign wrbuf_data_en = dma_axi_wvalid & dma_axi_wready;
|
assign wrbuf_data_en = dma_axi_wvalid & dma_axi_wready;
|
||||||
assign wrbuf_cmd_sent = axi_mstr_valid & axi_mstr_write;
|
assign wrbuf_cmd_sent = axi_mstr_valid & axi_mstr_write;
|
||||||
assign wrbuf_rst = wrbuf_cmd_sent & ~wrbuf_en;
|
assign wrbuf_rst = wrbuf_cmd_sent & ~wrbuf_en;
|
||||||
assign wrbuf_data_rst = wrbuf_cmd_sent & ~wrbuf_data_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_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), .*);
|
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), .*);
|
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_en = dma_axi_arvalid & dma_axi_arready;
|
||||||
assign rdbuf_cmd_sent = axi_mstr_valid & ~axi_mstr_write & dma_fifo_ready;
|
assign rdbuf_cmd_sent = axi_mstr_valid & ~axi_mstr_write & dma_fifo_ready;
|
||||||
assign rdbuf_rst = rdbuf_cmd_sent & ~rdbuf_en;
|
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), .*);
|
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(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), .*);
|
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), .*);
|
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_awready = ~(wrbuf_vld & ~wrbuf_cmd_sent);
|
||||||
assign dma_axi_wready = ~(wrbuf_data_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
|
//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_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];
|
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_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_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_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
|
// Sel=1 -> write has higher priority
|
||||||
assign axi_mstr_sel = (wrbuf_vld & wrbuf_data_vld & rdbuf_vld) ? axi_mstr_priority : (wrbuf_vld & wrbuf_data_vld);
|
assign axi_mstr_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_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), .*);
|
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]);
|
// ((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_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_error[RspPtr]) ? {32'b0,fifo_addr[RspPtr]} : fifo_data[RspPtr];
|
||||||
assign axi_slv_rdata[63:0] = fifo_data[RspPtr];
|
assign axi_slv_rdata[63:0] = fifo_data[RspPtr];
|
||||||
assign axi_slv_write = fifo_write[RspPtr];
|
assign axi_slv_write = fifo_write[RspPtr];
|
||||||
assign axi_slv_posted_write = axi_slv_write & fifo_posted_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);
|
assign axi_slv_error[1:0] = fifo_error[RspPtr][0] ? 2'b10 : (fifo_error[RspPtr][1] ? 2'b11 : 2'b0);
|
||||||
|
|
||||||
|
|
||||||
// AXI response channel signals
|
// AXI response channel signals
|
||||||
assign dma_axi_bvalid = axi_slv_valid & axi_slv_write;
|
assign dma_axi_bvalid = axi_slv_valid & axi_slv_write;
|
||||||
assign dma_axi_bresp[1:0] = axi_slv_error[1:0];
|
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_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_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_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_rdata[63:0] = axi_slv_rdata[63:0];
|
||||||
assign dma_axi_rlast = 1'b1;
|
assign dma_axi_rlast = 1'b1;
|
||||||
|
|
||||||
assign axi_slv_sent = (dma_axi_bvalid & dma_axi_bready) | (dma_axi_rvalid & dma_axi_rready);
|
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];
|
assign dma_slv_algn_err = fifo_error[RspPtr][1];
|
||||||
`ifdef ASSERT_ON
|
`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<DEPTH; i++) begin
|
for (genvar i=0; i<DEPTH; i++) begin
|
||||||
//assert_picm_rspdone_and_novalid: assert #0 (~fifo_rsp_done[i] | fifo_valid[i]);
|
//assert_picm_rspdone_and_novalid: assert #0 (~fifo_rsp_done[i] | fifo_valid[i]);
|
||||||
|
@ -497,9 +497,9 @@ module dma_ctrl (
|
||||||
((dma_axi_awsize[2:0] == 3'h2) & (dma_axi_awaddr[1:0] == 2'b0)) |
|
((dma_axi_awsize[2:0] == 3'h2) & (dma_axi_awaddr[1:0] == 2'b0)) |
|
||||||
((dma_axi_awsize[2:0] == 3'h3) & (dma_axi_awaddr[2:0] == 3'b0)));
|
((dma_axi_awsize[2:0] == 3'h3) & (dma_axi_awaddr[2:0] == 3'b0)));
|
||||||
endproperty
|
endproperty
|
||||||
// assert_dma_write_trxn_aligned: assert property (dma_axi_write_trxn_aligned) else
|
// assert_dma_write_trxn_aligned: assert property (dma_axi_write_trxn_aligned) else
|
||||||
// $display("Assertion dma_axi_write_trxn_aligned failed: dma_axi_awvalid=1'b%b, dma_axi_awsize=3'h%h, dma_axi_awaddr=32'h%h",dma_axi_awvalid, dma_axi_awsize[2:0], dma_axi_awaddr[31:0]);
|
// $display("Assertion dma_axi_write_trxn_aligned failed: dma_axi_awvalid=1'b%b, dma_axi_awsize=3'h%h, dma_axi_awaddr=32'h%h",dma_axi_awvalid, dma_axi_awsize[2:0], dma_axi_awaddr[31:0]);
|
||||||
|
|
||||||
// Assertion to check AXI read address is aligned to size
|
// Assertion to check AXI read address is aligned to size
|
||||||
property dma_axi_read_trxn_aligned;
|
property dma_axi_read_trxn_aligned;
|
||||||
@(posedge dma_bus_clk) dma_axi_arvalid |-> ((dma_axi_arsize[2:0] == 3'h0) |
|
@(posedge dma_bus_clk) dma_axi_arvalid |-> ((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'h2) & (dma_axi_araddr[1:0] == 2'b0)) |
|
||||||
((dma_axi_arsize[2:0] == 3'h3) & (dma_axi_araddr[2:0] == 3'b0)));
|
((dma_axi_arsize[2:0] == 3'h3) & (dma_axi_araddr[2:0] == 3'b0)));
|
||||||
endproperty
|
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]);
|
// $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
|
// Assertion to check write size is 8 byte or less
|
||||||
property dma_axi_awsize_check;
|
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);
|
@(posedge dma_bus_clk) disable iff(~rst_l) (dma_axi_awvalid & dma_axi_awready) |-> (dma_axi_awsize[2] == 1'b0);
|
||||||
endproperty
|
endproperty
|
||||||
assert_dma_axi_awsize_check: assert property (dma_axi_awsize_check) else
|
assert_dma_axi_awsize_check: assert property (dma_axi_awsize_check) else
|
||||||
$display("DMA AXI awsize is illegal. Size greater than 8B not supported");
|
$display("DMA AXI awsize is illegal. Size greater than 8B not supported");
|
||||||
|
|
||||||
// Assertion to check there are no burst commands
|
// Assertion to check there are no burst commands
|
||||||
property dma_axi_awlen_check;
|
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);
|
@(posedge dma_bus_clk) disable iff(~rst_l) (dma_axi_awvalid & dma_axi_awready) |-> (dma_axi_awlen[7:0] == 8'b0);
|
||||||
endproperty
|
endproperty
|
||||||
assert_dma_axi_awlen_check: assert property (dma_axi_awlen_check) else
|
assert_dma_axi_awlen_check: assert property (dma_axi_awlen_check) else
|
||||||
$display("DMA AXI awlen is illegal. Length greater than 0 not supported");
|
$display("DMA AXI awlen is illegal. Length greater than 0 not supported");
|
||||||
|
|
||||||
// Assertion to check write size is 8 byte or less
|
// Assertion to check write size is 8 byte or less
|
||||||
property dma_axi_arsize_check;
|
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);
|
@(posedge dma_bus_clk) disable iff(~rst_l) (dma_axi_arvalid & dma_axi_arready) |-> (dma_axi_arsize[2] == 1'b0);
|
||||||
endproperty
|
endproperty
|
||||||
assert_dma_axi_arsize_check: assert property (dma_axi_arsize_check) else
|
assert_dma_axi_arsize_check: assert property (dma_axi_arsize_check) else
|
||||||
$display("DMA AXI arsize is illegal, Size bigger than 8B not supported");
|
$display("DMA AXI arsize is illegal, Size bigger than 8B not supported");
|
||||||
|
|
||||||
// Assertion to check there are no burst commands
|
// Assertion to check there are no burst commands
|
||||||
property dma_axi_arlen_check;
|
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);
|
@(posedge dma_bus_clk) disable iff(~rst_l) (dma_axi_arvalid & dma_axi_arready) |-> (dma_axi_arlen[7:0] == 8'b0);
|
||||||
endproperty
|
endproperty
|
||||||
assert_dma_axi_arlen_check: assert property (dma_axi_arlen_check) else
|
assert_dma_axi_arlen_check: assert property (dma_axi_arlen_check) else
|
||||||
$display("DMA AXI arlen greater than 0 not supported.");
|
$display("DMA AXI arlen greater than 0 not supported.");
|
||||||
|
|
||||||
// Assertion to check cmd valid stays stable during entire bus clock
|
// Assertion to check cmd valid stays stable during entire bus clock
|
||||||
property dma_axi_awvalid_stable;
|
property dma_axi_awvalid_stable;
|
||||||
@(posedge clk) disable iff(~rst_l) (dma_axi_awvalid != $past(dma_axi_awvalid)) |-> $past(dma_bus_clk_en);
|
@(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
|
assert_dma_axi_rid_stable: assert property (dma_axi_rid_stable) else
|
||||||
$display("DMA AXI bid changed in middle of bus clock");
|
$display("DMA AXI bid changed in middle of bus clock");
|
||||||
|
|
||||||
`endif
|
`endif
|
||||||
|
|
||||||
endmodule // dma_ctrl
|
endmodule // dma_ctrl
|
||||||
|
|
|
@ -48,8 +48,8 @@ module dmi_jtag_to_core_sync (
|
||||||
// synchronizers
|
// synchronizers
|
||||||
always @ ( posedge clk or negedge rst_n) begin
|
always @ ( posedge clk or negedge rst_n) begin
|
||||||
if(!rst_n) begin
|
if(!rst_n) begin
|
||||||
rden <= 3'b0;
|
rden <= '0;
|
||||||
wren <= 3'b0;
|
wren <= '0;
|
||||||
end
|
end
|
||||||
else begin
|
else begin
|
||||||
rden <= {rden[1:0], rd_en};
|
rden <= {rden[1:0], rd_en};
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
// Copyright 2019 Western Digital Corporation or its affiliates.
|
// Copyright 2019 Western Digital Corporation or its affiliates.
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "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 not use this file except in compliance with the License.
|
||||||
// You may obtain a copy of the License at
|
// You may obtain a copy of the License at
|
||||||
//
|
//
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
//
|
//
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// 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 [31:1] jtag_id,
|
||||||
input [3:0] version
|
input [3:0] version
|
||||||
);
|
);
|
||||||
|
|
||||||
localparam USER_DR_LENGTH = AWIDTH + 34;
|
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[3:0] state, nstate;
|
||||||
logic [4:0] ir;
|
logic [4:0] ir;
|
||||||
wire jtag_reset;
|
wire jtag_reset;
|
||||||
wire shift_dr;
|
wire shift_dr;
|
||||||
wire pause_dr;
|
wire pause_dr;
|
||||||
wire update_dr;
|
wire update_dr;
|
||||||
wire capture_dr;
|
wire capture_dr;
|
||||||
wire shift_ir;
|
wire shift_ir;
|
||||||
wire pause_ir ;
|
wire pause_ir ;
|
||||||
wire update_ir ;
|
wire update_ir ;
|
||||||
wire capture_ir;
|
wire capture_ir;
|
||||||
wire[1:0] dr_en;
|
wire[1:0] dr_en;
|
||||||
|
@ -94,7 +94,7 @@ always_comb begin
|
||||||
nstate = state;
|
nstate = state;
|
||||||
case(state)
|
case(state)
|
||||||
TEST_LOGIC_RESET_STATE: nstate = tms ? TEST_LOGIC_RESET_STATE : RUN_TEST_IDLE_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;
|
SELECT_DR_SCAN_STATE: nstate = tms ? SELECT_IR_SCAN_STATE : CAPTURE_DR_STATE;
|
||||||
CAPTURE_DR_STATE: nstate = tms ? EXIT1_DR_STATE : SHIFT_DR_STATE;
|
CAPTURE_DR_STATE: nstate = tms ? EXIT1_DR_STATE : SHIFT_DR_STATE;
|
||||||
SHIFT_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 devid_sel = ir == 5'b00001;
|
||||||
assign dr_en[0] = ir == 5'b10000;
|
assign dr_en[0] = ir == 5'b10000;
|
||||||
assign dr_en[1] = ir == 5'b10001;
|
assign dr_en[1] = ir == 5'b10001;
|
||||||
|
|
||||||
///////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////
|
||||||
// Shift register
|
// Shift register
|
||||||
///////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////
|
||||||
|
@ -192,11 +192,11 @@ always @ (posedge tck or negedge trst) begin
|
||||||
if(!trst) begin
|
if(!trst) begin
|
||||||
dmi_hard_reset <= 1'b0;
|
dmi_hard_reset <= 1'b0;
|
||||||
dmi_reset <= 1'b0;
|
dmi_reset <= 1'b0;
|
||||||
end
|
end
|
||||||
else if (update_dr & dr_en[0]) begin
|
else if (update_dr & dr_en[0]) begin
|
||||||
dmi_hard_reset <= sr[17];
|
dmi_hard_reset <= sr[17];
|
||||||
dmi_reset <= sr[16];
|
dmi_reset <= sr[16];
|
||||||
end
|
end
|
||||||
else begin
|
else begin
|
||||||
dmi_hard_reset <= 1'b0;
|
dmi_hard_reset <= 1'b0;
|
||||||
dmi_reset <= 1'b0;
|
dmi_reset <= 1'b0;
|
||||||
|
|
|
@ -176,7 +176,7 @@ module exu
|
||||||
output logic [`RV_BHT_GHR_RANGE] exu_i0_br_fghr_e4, // to DEC I0 branch fghr
|
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_ret_e4, // to DEC I0 branch return
|
||||||
output logic exu_i0_br_call_e4, // to DEC I0 branch call
|
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_hist_e4, // to DEC I1 branch history
|
||||||
output logic [1:0] exu_i1_br_bank_e4, // to DEC I1 branch bank
|
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
|
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]);
|
({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]) |
|
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]);
|
({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] ) |
|
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]})
|
.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),
|
.en(i0_e2_data_en),
|
||||||
.din( {i0_rs1_e1[31:0], i0_rs2_e1[31:0], i0_br_immed_e1[12:1]}),
|
.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]})
|
.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 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}) |
|
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}) |
|
({`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
|
`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}) |
|
({`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 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 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}) |
|
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}) |
|
({`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
|
`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}) |
|
({`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({
|
.din({
|
||||||
exu_i0_flush_path_e1[31:1],
|
exu_i0_flush_path_e1[31:1],
|
||||||
exu_i0_flush_upper_e1}),
|
exu_i0_flush_upper_e1}),
|
||||||
|
|
||||||
.dout({
|
.dout({
|
||||||
i0_flush_path_upper_e2[31:1],
|
i0_flush_path_upper_e2[31:1],
|
||||||
exu_i0_flush_upper_e2})
|
exu_i0_flush_upper_e2})
|
||||||
|
|
|
@ -192,7 +192,7 @@ module exu_alu_ctl
|
||||||
// branch handling
|
// branch handling
|
||||||
|
|
||||||
logic any_jal;
|
logic any_jal;
|
||||||
|
|
||||||
assign any_jal = ap.jal |
|
assign any_jal = ap.jal |
|
||||||
pp_ff.pcall |
|
pp_ff.pcall |
|
||||||
pp_ff.pja |
|
pp_ff.pja |
|
||||||
|
@ -217,7 +217,7 @@ module exu_alu_ctl
|
||||||
// pred_correct is for the npc logic
|
// pred_correct is for the npc logic
|
||||||
// pred_correct indicates not to use the flush_path
|
// pred_correct indicates not to use the flush_path
|
||||||
// for any_jal pred_correct==0
|
// for any_jal pred_correct==0
|
||||||
|
|
||||||
assign pred_correct = ((ap.predict_nt & ~actual_taken) |
|
assign pred_correct = ((ap.predict_nt & ~actual_taken) |
|
||||||
(ap.predict_t & actual_taken)) & ~any_jal;
|
(ap.predict_t & actual_taken)) & ~any_jal;
|
||||||
|
|
||||||
|
@ -242,7 +242,7 @@ module exu_alu_ctl
|
||||||
// .ilb hist[1] hist[0] taken
|
// .ilb hist[1] hist[0] taken
|
||||||
// .ob newhist[1] newhist[0]
|
// .ob newhist[1] newhist[0]
|
||||||
// .type fd
|
// .type fd
|
||||||
//
|
//
|
||||||
// 00 0 01
|
// 00 0 01
|
||||||
// 01 0 01
|
// 01 0 01
|
||||||
// 10 0 00
|
// 10 0 00
|
||||||
|
|
|
@ -59,7 +59,7 @@ module exu_mul_ctl
|
||||||
assign mul_c1_e2_clken = (valid_e1 | clk_override) & ~freeze;
|
assign mul_c1_e2_clken = (valid_e1 | clk_override) & ~freeze;
|
||||||
assign mul_c1_e3_clken = (valid_e2 | 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_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_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));
|
rvclkhdr exu_mul_c1e3_cgc (.*, .en(mul_c1_e3_clken), .l1clk(exu_mul_c1_e3_clk));
|
||||||
|
|
|
@ -30,9 +30,9 @@ module ifu
|
||||||
|
|
||||||
input logic dec_ib3_valid_d, dec_ib2_valid_d, // mass balance for decode buffer
|
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_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_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_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_i1_br_ret_e4, // i1 branch commit is a ret
|
||||||
input logic exu_i0_br_call_e4, // i0 branch commit is a call
|
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 [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_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_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
|
input logic dec_tlu_core_ecc_disable, // disable ecc checking and flagging
|
||||||
|
|
||||||
// AXI Write Channels - IFU never writes. So, 0 out mostly
|
// 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 [3:0] ifu_axi_awcache,
|
||||||
output logic [2:0] ifu_axi_awprot,
|
output logic [2:0] ifu_axi_awprot,
|
||||||
output logic [3:0] ifu_axi_awqos,
|
output logic [3:0] ifu_axi_awqos,
|
||||||
|
|
||||||
output logic ifu_axi_wvalid,
|
output logic ifu_axi_wvalid,
|
||||||
input logic ifu_axi_wready,
|
input logic ifu_axi_wready,
|
||||||
output logic [63:0] ifu_axi_wdata,
|
output logic [63:0] ifu_axi_wdata,
|
||||||
output logic [7:0] ifu_axi_wstrb,
|
output logic [7:0] ifu_axi_wstrb,
|
||||||
output logic ifu_axi_wlast,
|
output logic ifu_axi_wlast,
|
||||||
|
|
||||||
input logic ifu_axi_bvalid,
|
input logic ifu_axi_bvalid,
|
||||||
output logic ifu_axi_bready,
|
output logic ifu_axi_bready,
|
||||||
input logic [1:0] ifu_axi_bresp,
|
input logic [1:0] ifu_axi_bresp,
|
||||||
input logic [`RV_IFU_BUS_TAG-1:0] ifu_axi_bid,
|
input logic [`RV_IFU_BUS_TAG-1:0] ifu_axi_bid,
|
||||||
|
|
||||||
// AXI Read Channels
|
// AXI Read Channels
|
||||||
output logic ifu_axi_arvalid,
|
output logic ifu_axi_arvalid,
|
||||||
input logic ifu_axi_arready,
|
input logic ifu_axi_arready,
|
||||||
output logic [`RV_IFU_BUS_TAG-1:0] ifu_axi_arid,
|
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 [3:0] ifu_axi_arcache,
|
||||||
output logic [2:0] ifu_axi_arprot,
|
output logic [2:0] ifu_axi_arprot,
|
||||||
output logic [3:0] ifu_axi_arqos,
|
output logic [3:0] ifu_axi_arqos,
|
||||||
|
|
||||||
input logic ifu_axi_rvalid,
|
input logic ifu_axi_rvalid,
|
||||||
output logic ifu_axi_rready,
|
output logic ifu_axi_rready,
|
||||||
input logic [`RV_IFU_BUS_TAG-1:0] ifu_axi_rid,
|
input logic [`RV_IFU_BUS_TAG-1:0] ifu_axi_rid,
|
||||||
|
@ -100,101 +100,101 @@ module ifu
|
||||||
input logic ifu_axi_rlast,
|
input logic ifu_axi_rlast,
|
||||||
|
|
||||||
//// AHB LITE BUS
|
//// AHB LITE BUS
|
||||||
//`ifdef RV_BUILD_AHB_LITE
|
//`ifdef RV_BUILD_AHB_LITE
|
||||||
input logic ifu_bus_clk_en,
|
input logic ifu_bus_clk_en,
|
||||||
|
|
||||||
|
|
||||||
input logic dma_iccm_req,
|
input logic dma_iccm_req,
|
||||||
input logic dma_iccm_stall_any,
|
input logic dma_iccm_stall_any,
|
||||||
input logic [31:0] dma_mem_addr,
|
input logic [31:0] dma_mem_addr,
|
||||||
input logic [2:0] dma_mem_sz,
|
input logic [2:0] dma_mem_sz,
|
||||||
input logic dma_mem_write,
|
input logic dma_mem_write,
|
||||||
input logic [63:0] dma_mem_wdata,
|
input logic [63:0] dma_mem_wdata,
|
||||||
|
|
||||||
output logic iccm_dma_ecc_error,
|
output logic iccm_dma_ecc_error,
|
||||||
output logic iccm_dma_rvalid,
|
output logic iccm_dma_rvalid,
|
||||||
output logic [63:0] iccm_dma_rdata,
|
output logic [63:0] iccm_dma_rdata,
|
||||||
output logic iccm_ready,
|
output logic iccm_ready,
|
||||||
|
|
||||||
//`endif
|
//`endif
|
||||||
|
|
||||||
output logic [1:0] ifu_pmu_instr_aligned,
|
output logic [1:0] ifu_pmu_instr_aligned,
|
||||||
output logic ifu_pmu_align_stall,
|
output logic ifu_pmu_align_stall,
|
||||||
output logic ifu_pmu_fetch_stall,
|
output logic ifu_pmu_fetch_stall,
|
||||||
|
|
||||||
// I$ & ITAG Ports
|
// I$ & ITAG Ports
|
||||||
output logic [31:3] ic_rw_addr, // Read/Write addresss to the Icache.
|
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 [3:0] ic_wr_en, // Icache write enable, when filling the Icache.
|
||||||
output logic ic_rd_en, // Icache read enable.
|
output logic ic_rd_en, // Icache read enable.
|
||||||
`ifdef RV_ICACHE_ECC
|
`ifdef RV_ICACHE_ECC
|
||||||
output logic [83:0] ic_wr_data, // Data to fill to the Icache. With 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 [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.
|
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] ic_debug_wr_data, // Debug wr cache.
|
||||||
output logic [41:0] ifu_ic_debug_rd_data,
|
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
|
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 [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.
|
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] ic_debug_wr_data, // Debug wr cache.
|
||||||
output logic [33:0] ifu_ic_debug_rd_data,
|
output logic [33:0] ifu_ic_debug_rd_data,
|
||||||
`endif
|
`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 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_rd_en, // Icache debug rd
|
||||||
output logic ic_debug_wr_en, // Icache debug wr
|
output logic ic_debug_wr_en, // Icache debug wr
|
||||||
output logic ic_debug_tag_array, // Debug tag array
|
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_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
|
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 [3:0] ic_rd_hit, // Compare hits from Icache tags. Per way. F2 stage
|
||||||
input logic ic_tag_perr, // Icache Tag parity error
|
input logic ic_tag_perr, // Icache Tag parity error
|
||||||
|
|
||||||
|
|
||||||
`ifdef RV_ICCM_ENABLE
|
`ifdef RV_ICCM_ENABLE
|
||||||
// ICCM ports
|
// ICCM ports
|
||||||
output logic [`RV_ICCM_BITS-1:2] iccm_rw_addr, // ICCM read/write address.
|
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_wren, // ICCM write enable (through the DMA)
|
||||||
output logic iccm_rden, // ICCM read enable.
|
output logic iccm_rden, // ICCM read enable.
|
||||||
output logic [77:0] iccm_wr_data, // ICCM write data.
|
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.
|
input logic [155:0] iccm_rd_data, // Data read from ICCM.
|
||||||
`endif
|
`endif
|
||||||
|
|
||||||
// Perf counter sigs
|
// Perf counter sigs
|
||||||
output logic ifu_pmu_ic_miss, // ic miss
|
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_error, // iside bus error
|
||||||
output logic ifu_pmu_bus_busy, // iside bus busy
|
output logic ifu_pmu_bus_busy, // iside bus busy
|
||||||
output logic ifu_pmu_bus_trxn, // iside bus transactions
|
output logic ifu_pmu_bus_trxn, // iside bus transactions
|
||||||
|
|
||||||
|
|
||||||
output logic ifu_i0_valid, // Instruction 0 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_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_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_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_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_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_i0_sbecc, // Instruction 0 has single bit ecc error
|
||||||
output logic ifu_i1_sbecc, // Instruction 1 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_i0_dbecc, // Instruction 0 has double bit ecc error
|
||||||
output logic ifu_i1_dbecc, // Instruction 1 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 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_i0_instr, // Instruction 0 . From Aligner to Decode
|
||||||
output logic[31:0] ifu_i1_instr, // Instruction 1 . 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_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[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_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 [15:0] ifu_illegal_inst, // Illegal instruction.
|
||||||
|
|
||||||
output logic ifu_miss_state_idle, // There is no outstanding miss. Cache miss state is idle.
|
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_br0_wb_pkt, // slot0 update/error pkt
|
||||||
input br_tlu_pkt_t dec_tlu_br1_wb_pkt, // slot1 update/error pkt
|
input br_tlu_pkt_t dec_tlu_br1_wb_pkt, // slot1 update/error pkt
|
||||||
input dec_tlu_flush_lower_wb,
|
input dec_tlu_flush_lower_wb,
|
||||||
|
|
||||||
input rets_pkt_t exu_rets_e1_pkt, // E1 return stack packet
|
input rets_pkt_t exu_rets_e1_pkt, // E1 return stack packet
|
||||||
input rets_pkt_t exu_rets_e4_pkt, // E4 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,
|
output logic [15:0] ifu_i1_cinst,
|
||||||
|
|
||||||
|
|
||||||
/// Icache debug
|
/// Icache debug
|
||||||
input cache_debug_pkt_t dec_tlu_ic_diag_pkt ,
|
input cache_debug_pkt_t dec_tlu_ic_diag_pkt ,
|
||||||
output logic ifu_ic_debug_rd_data_valid,
|
output logic ifu_ic_debug_rd_data_valid,
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
input logic scan_mode
|
|
||||||
|
input logic scan_mode
|
||||||
);
|
);
|
||||||
|
|
||||||
localparam TAGWIDTH = 2 ;
|
localparam TAGWIDTH = 2 ;
|
||||||
|
@ -245,7 +245,7 @@ module ifu
|
||||||
logic [31:1] ifu_fetch_pc; // starting pc of fetch
|
logic [31:1] ifu_fetch_pc; // starting pc of fetch
|
||||||
|
|
||||||
logic [31:1] ifc_fetch_addr_f1;
|
logic [31:1] ifc_fetch_addr_f1;
|
||||||
|
|
||||||
logic ic_crit_wd_rdy;
|
logic ic_crit_wd_rdy;
|
||||||
logic ic_write_stall;
|
logic ic_write_stall;
|
||||||
logic ic_dma_active;
|
logic ic_dma_active;
|
||||||
|
@ -255,9 +255,9 @@ module ifu
|
||||||
logic ic_access_fault_f2;
|
logic ic_access_fault_f2;
|
||||||
logic ifu_ic_mb_empty;
|
logic ifu_ic_mb_empty;
|
||||||
|
|
||||||
|
|
||||||
logic ic_hit_f2;
|
logic ic_hit_f2;
|
||||||
|
|
||||||
// fetch control
|
// fetch control
|
||||||
ifu_ifc_ctl ifc (.*
|
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_pc4_f2; // pc4 indication; right justified
|
||||||
logic [7:0] ifu_bp_valid_f2; // branch valid, right justified
|
logic [7:0] ifu_bp_valid_f2; // branch valid, right justified
|
||||||
logic [`RV_BHT_GHR_RANGE] ifu_bp_fghr_f2;
|
logic [`RV_BHT_GHR_RANGE] ifu_bp_fghr_f2;
|
||||||
|
|
||||||
// branch predictor
|
// branch predictor
|
||||||
ifu_bp_ctl bp (.*);
|
ifu_bp_ctl bp (.*);
|
||||||
|
|
||||||
|
|
||||||
logic [7:0] ic_fetch_val_f2;
|
logic [7:0] ic_fetch_val_f2;
|
||||||
logic [127:0] ic_data_f2;
|
logic [127:0] ic_data_f2;
|
||||||
logic [127:0] ifu_fetch_data;
|
logic [127:0] ifu_fetch_data;
|
||||||
logic ifc_fetch_req_f1_raw, ifc_fetch_req_f1, ifc_fetch_req_f2;
|
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 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_single_err; // This fetch has an iccm single error.
|
||||||
logic iccm_rd_ecc_double_err; // This fetch has an iccm double error.
|
logic iccm_rd_ecc_double_err; // This fetch has an iccm double error.
|
||||||
|
|
||||||
icache_err_pkt_t ic_error_f2;
|
icache_err_pkt_t ic_error_f2;
|
||||||
|
|
||||||
logic ifu_icache_fetch_f2 ;
|
logic ifu_icache_fetch_f2 ;
|
||||||
logic [16:2] ifu_icache_error_index; // Index with parity error
|
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;
|
logic ifu_icache_sb_error_val;
|
||||||
|
|
||||||
assign ifu_fetch_data[127:0] = ic_data_f2[127:0];
|
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_val[7:0] = ic_fetch_val_f2[7:0];
|
||||||
assign ifu_fetch_pc[31:1] = ifc_fetch_addr_f2[31:1];
|
assign ifu_fetch_pc[31:1] = ifc_fetch_addr_f2[31:1];
|
||||||
|
|
||||||
// aligner
|
// aligner
|
||||||
ifu_aln_ctl aln (.*);
|
ifu_aln_ctl aln (.*);
|
||||||
|
|
||||||
// icache
|
// icache
|
||||||
ifu_mem_ctl mem_ctl
|
ifu_mem_ctl mem_ctl
|
||||||
(.*,
|
(.*,
|
||||||
.fetch_addr_f1(ifc_fetch_addr_f1),
|
.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_hit_f2(ic_hit_f2),
|
||||||
.ic_data_f2(ic_data_f2[127:0])
|
.ic_data_f2(ic_data_f2[127:0])
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Performance debug info
|
// Performance debug info
|
||||||
|
@ -371,26 +371,26 @@ assign tmp_bnk[2:0] = encode8_3(bp.btb_sel_f2[7:0]);
|
||||||
`endif
|
`endif
|
||||||
$display("RS_CONFIG: %d", `RV_RET_STACK_SIZE);
|
$display("RS_CONFIG: %d", `RV_RET_STACK_SIZE);
|
||||||
end
|
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);
|
$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
|
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]);
|
$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
|
end
|
||||||
`ifdef RV_BTB_48
|
`ifdef RV_BTB_48
|
||||||
for(int y = 0; y < 4; y++) begin
|
for(int y = 0; y < 4; y++) begin
|
||||||
for(int z = 0; z < 4; z++) begin
|
for(int z = 0; z < 4; z++) begin
|
||||||
if(bp.lru_bank_sel[y][z])
|
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
|
||||||
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))
|
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))
|
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)
|
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)
|
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);
|
$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)
|
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[1] = in[7] | in[6] | in[3] | in[2];
|
||||||
encode8_3[0] = in[7] | in[5] | in[3] | in[1];
|
encode8_3[0] = in[7] | in[5] | in[3] | in[1];
|
||||||
|
|
||||||
endfunction
|
endfunction
|
||||||
`endif
|
`endif
|
||||||
endmodule // ifu
|
endmodule // ifu
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -24,18 +24,18 @@ module ifu_compress_ctl
|
||||||
output logic legal
|
output logic legal
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
logic [15:0] i;
|
logic [15:0] i;
|
||||||
|
|
||||||
logic [31:0] o,l1,l2,l3;
|
logic [31:0] o,l1,l2,l3;
|
||||||
|
|
||||||
|
|
||||||
assign i[15:0] = din[15:0];
|
assign i[15:0] = din[15:0];
|
||||||
|
|
||||||
|
|
||||||
logic [4:0] rs2d,rdd,rdpd,rs2pd;
|
logic [4:0] rs2d,rdd,rdpd,rs2pd;
|
||||||
|
|
||||||
logic rdrd;
|
logic rdrd;
|
||||||
logic rdrs1;
|
logic rdrs1;
|
||||||
logic rs2rs2;
|
logic rs2rs2;
|
||||||
|
@ -68,46 +68,46 @@ logic uswspimm7_2;
|
||||||
// c.and rdp 9:7 rs2p 4:2
|
// c.and rdp 9:7 rs2p 4:2
|
||||||
//
|
//
|
||||||
// add rs2 24:20 rs1 19:15 rd 11:7
|
// add rs2 24:20 rs1 19:15 rd 11:7
|
||||||
|
|
||||||
assign rs2d[4:0] = i[6:2];
|
assign rs2d[4:0] = i[6:2];
|
||||||
|
|
||||||
assign rdd[4:0] = i[11:7];
|
assign rdd[4:0] = i[11:7];
|
||||||
|
|
||||||
assign rdpd[4:0] = {2'b01, i[9:7]};
|
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]};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// merge in rd, rs1, rs2
|
// merge in rd, rs1, rs2
|
||||||
|
|
||||||
|
|
||||||
// rd
|
// rd
|
||||||
assign l1[6:0] = o[6:0];
|
assign l1[6:0] = o[6:0];
|
||||||
|
|
||||||
assign l1[11:7] = o[11:7] |
|
assign l1[11:7] = o[11:7] |
|
||||||
({5{rdrd}} & rdd[4:0]) |
|
({5{rdrd}} & rdd[4:0]) |
|
||||||
({5{rdprd}} & rdpd[4:0]) |
|
({5{rdprd}} & rdpd[4:0]) |
|
||||||
({5{rs2prd}} & rs2pd[4:0]) |
|
({5{rs2prd}} & rs2pd[4:0]) |
|
||||||
({5{rdeq1}} & 5'd1) |
|
({5{rdeq1}} & 5'd1) |
|
||||||
({5{rdeq2}} & 5'd2);
|
({5{rdeq2}} & 5'd2);
|
||||||
|
|
||||||
|
|
||||||
// rs1
|
|
||||||
|
// rs1
|
||||||
assign l1[14:12] = o[14:12];
|
assign l1[14:12] = o[14:12];
|
||||||
assign l1[19:15] = o[19:15] |
|
assign l1[19:15] = o[19:15] |
|
||||||
({5{rdrs1}} & rdd[4:0]) |
|
({5{rdrs1}} & rdd[4:0]) |
|
||||||
({5{rdprs1}} & rdpd[4:0]) |
|
({5{rdprs1}} & rdpd[4:0]) |
|
||||||
({5{rs1eq2}} & 5'd2);
|
({5{rs1eq2}} & 5'd2);
|
||||||
|
|
||||||
|
|
||||||
// rs2
|
// rs2
|
||||||
assign l1[24:20] = o[24:20] |
|
assign l1[24:20] = o[24:20] |
|
||||||
({5{rs2rs2}} & rs2d[4:0]) |
|
({5{rs2rs2}} & rs2d[4:0]) |
|
||||||
({5{rs2prs2}} & rs2pd[4:0]);
|
({5{rs2prs2}} & rs2pd[4:0]);
|
||||||
|
|
||||||
assign l1[31:25] = o[31:25];
|
assign l1[31:25] = o[31:25];
|
||||||
|
|
||||||
logic [5:0] simm5d;
|
logic [5:0] simm5d;
|
||||||
logic [9:2] uimm9d;
|
logic [9:2] uimm9d;
|
||||||
|
|
||||||
|
@ -117,8 +117,8 @@ logic uswspimm7_2;
|
||||||
logic [5:0] uimm5d;
|
logic [5:0] uimm5d;
|
||||||
logic [20:1] sjald;
|
logic [20:1] sjald;
|
||||||
|
|
||||||
logic [31:12] sluimmd;
|
logic [31:12] sluimmd;
|
||||||
|
|
||||||
// merge in immediates + jal offset
|
// merge in immediates + jal offset
|
||||||
|
|
||||||
assign simm5d[5:0] = { i[12], i[6:2] };
|
assign simm5d[5:0] = { i[12], i[6:2] };
|
||||||
|
@ -134,15 +134,15 @@ logic uswspimm7_2;
|
||||||
assign uimm5d[5:0] = { i[12], i[6:2] };
|
assign uimm5d[5:0] = { i[12], i[6:2] };
|
||||||
|
|
||||||
assign sjald[11:1] = { i[12], i[8], i[10:9], i[6], i[7], i[2], i[11], i[5:4], i[3] };
|
assign sjald[11:1] = { i[12], i[8], i[10:9], i[6], i[7], i[2], i[11], i[5:4], i[3] };
|
||||||
|
|
||||||
assign sjald[20:12] = {9{i[12]}};
|
assign sjald[20:12] = {9{i[12]}};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
assign sluimmd[31:12] = { {15{i[12]}}, i[6:2] };
|
assign sluimmd[31:12] = { {15{i[12]}}, i[6:2] };
|
||||||
|
|
||||||
|
|
||||||
assign l2[31:20] = ( l1[31:20] ) |
|
assign l2[31:20] = ( l1[31:20] ) |
|
||||||
( {12{simm5_0}} & {{7{simm5d[5]}},simm5d[4:0]} ) |
|
( {12{simm5_0}} & {{7{simm5d[5]}},simm5d[4:0]} ) |
|
||||||
( {12{uimm9_2}} & {2'b0,uimm9d[9:2],2'b0} ) |
|
( {12{uimm9_2}} & {2'b0,uimm9d[9:2],2'b0} ) |
|
||||||
( {12{simm9_4}} & {{3{simm9d[9]}},simm9d[8:4],4'b0} ) |
|
( {12{simm9_4}} & {{3{simm9d[9]}},simm9d[8:4],4'b0} ) |
|
||||||
|
@ -151,46 +151,46 @@ logic uswspimm7_2;
|
||||||
( {12{uimm5_0}} & {6'b0,uimm5d[5:0]} ) |
|
( {12{uimm5_0}} & {6'b0,uimm5d[5:0]} ) |
|
||||||
( {12{sjaloffset11_1}} & {sjald[20],sjald[10:1],sjald[11]} ) |
|
( {12{sjaloffset11_1}} & {sjald[20],sjald[10:1],sjald[11]} ) |
|
||||||
( {12{sluimm17_12}} & sluimmd[31:20] );
|
( {12{sluimm17_12}} & sluimmd[31:20] );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
assign l2[19:12] = ( l1[19:12] ) |
|
assign l2[19:12] = ( l1[19:12] ) |
|
||||||
( {8{sjaloffset11_1}} & sjald[19:12] ) |
|
( {8{sjaloffset11_1}} & sjald[19:12] ) |
|
||||||
( {8{sluimm17_12}} & sluimmd[19:12] );
|
( {8{sluimm17_12}} & sluimmd[19:12] );
|
||||||
|
|
||||||
|
|
||||||
assign l2[11:0] = l1[11:0];
|
assign l2[11:0] = l1[11:0];
|
||||||
|
|
||||||
|
|
||||||
// merge in branch offset and store immediates
|
// merge in branch offset and store immediates
|
||||||
|
|
||||||
logic [8:1] sbr8d;
|
logic [8:1] sbr8d;
|
||||||
logic [6:2] uswimm6d;
|
logic [6:2] uswimm6d;
|
||||||
logic [7:2] uswspimm7d;
|
logic [7:2] uswspimm7d;
|
||||||
|
|
||||||
|
|
||||||
assign sbr8d[8:1] = { i[12], i[6], i[5], i[2], i[11], i[10], i[4], i[3] };
|
assign sbr8d[8:1] = { i[12], i[6], i[5], i[2], i[11], i[10], i[4], i[3] };
|
||||||
|
|
||||||
assign uswimm6d[6:2] = { i[5], i[12:10], i[6] };
|
assign uswimm6d[6:2] = { i[5], i[12:10], i[6] };
|
||||||
|
|
||||||
assign uswspimm7d[7:2] = { i[8:7], i[12:9] };
|
assign uswspimm7d[7:2] = { i[8:7], i[12:9] };
|
||||||
|
|
||||||
assign l3[31:25] = ( l2[31:25] ) |
|
assign l3[31:25] = ( l2[31:25] ) |
|
||||||
( {7{sbroffset8_1}} & { {4{sbr8d[8]}},sbr8d[7:5] } ) |
|
( {7{sbroffset8_1}} & { {4{sbr8d[8]}},sbr8d[7:5] } ) |
|
||||||
( {7{uswimm6_2}} & { 5'b0, uswimm6d[6:5] } ) |
|
( {7{uswimm6_2}} & { 5'b0, uswimm6d[6:5] } ) |
|
||||||
( {7{uswspimm7_2}} & { 4'b0, uswspimm7d[7:5] } );
|
( {7{uswspimm7_2}} & { 4'b0, uswspimm7d[7:5] } );
|
||||||
|
|
||||||
|
|
||||||
assign l3[24:12] = l2[24:12];
|
assign l3[24:12] = l2[24:12];
|
||||||
|
|
||||||
assign l3[11:7] = ( l2[11:7] ) |
|
assign l3[11:7] = ( l2[11:7] ) |
|
||||||
( {5{sbroffset8_1}} & { sbr8d[4:1], sbr8d[8] } ) |
|
( {5{sbroffset8_1}} & { sbr8d[4:1], sbr8d[8] } ) |
|
||||||
( {5{uswimm6_2}} & { uswimm6d[4:2], 2'b0 } ) |
|
( {5{uswimm6_2}} & { uswimm6d[4:2], 2'b0 } ) |
|
||||||
( {5{uswspimm7_2}} & { uswspimm7d[4:2], 2'b0 } );
|
( {5{uswspimm7_2}} & { uswspimm7d[4:2], 2'b0 } );
|
||||||
|
|
||||||
assign l3[6:0] = l2[6:0];
|
assign l3[6:0] = l2[6:0];
|
||||||
|
|
||||||
|
|
||||||
assign dout[31:0] = l3[31:0] & {32{legal}};
|
assign dout[31:0] = l3[31:0] & {32{legal}};
|
||||||
|
|
||||||
|
|
||||||
|
@ -211,8 +211,8 @@ logic uswspimm7_2;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// espresso decodes
|
// espresso decodes
|
||||||
assign rdrd = (!i[14]&i[6]&i[1]) | (!i[15]&i[14]&i[11]&i[0]) | (!i[14]&i[5]&i[1]) | (
|
assign rdrd = (!i[14]&i[6]&i[1]) | (!i[15]&i[14]&i[11]&i[0]) | (!i[14]&i[5]&i[1]) | (
|
||||||
!i[15]&i[14]&i[10]&i[0]) | (!i[14]&i[4]&i[1]) | (!i[15]&i[14]&i[9]
|
!i[15]&i[14]&i[10]&i[0]) | (!i[14]&i[4]&i[1]) | (!i[15]&i[14]&i[9]
|
||||||
|
@ -353,7 +353,7 @@ assign o[2] = (!i[14]&i[12]&i[11]&!i[6]&!i[5]&!i[4]&!i[3]&!i[2]&i[1]) | (!i[14]
|
||||||
&i[9]) | (!i[15]&i[13]&i[10]) | (!i[15]&i[13]&i[11]) | (!i[14]&i[13]);
|
&i[9]) | (!i[15]&i[13]&i[10]) | (!i[15]&i[13]&i[11]) | (!i[14]&i[13]);
|
||||||
|
|
||||||
// 32b instruction has lower two bits 2'b11
|
// 32b instruction has lower two bits 2'b11
|
||||||
|
|
||||||
assign o[1] = 1'b1;
|
assign o[1] = 1'b1;
|
||||||
|
|
||||||
assign o[0] = 1'b1;
|
assign o[0] = 1'b1;
|
||||||
|
@ -374,6 +374,6 @@ assign legal = (!i[13]&!i[12]&i[11]&i[1]&!i[0]) | (!i[13]&!i[12]&i[6]&i[1]&!i[0]
|
||||||
&!i[0]) | (!i[15]&!i[13]&i[12]&!i[1]) | (i[14]&!i[13]&!i[0]);
|
&!i[0]) | (!i[15]&!i[13]&i[12]&!i[1]) | (i[14]&!i[13]&!i[0]);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
|
@ -17,23 +17,23 @@
|
||||||
////////////////////////////////////////////////////
|
////////////////////////////////////////////////////
|
||||||
// ICACHE DATA & TAG MODULE WRAPPER //
|
// ICACHE DATA & TAG MODULE WRAPPER //
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
module ifu_ic_mem
|
module ifu_ic_mem
|
||||||
(
|
(
|
||||||
input logic clk,
|
input logic clk,
|
||||||
input logic rst_l,
|
input logic rst_l,
|
||||||
input logic clk_override,
|
input logic clk_override,
|
||||||
input logic dec_tlu_core_ecc_disable,
|
input logic dec_tlu_core_ecc_disable,
|
||||||
|
|
||||||
input logic [31:3] ic_rw_addr,
|
input logic [31:3] ic_rw_addr,
|
||||||
input logic [3:0] ic_wr_en , // Which way to write
|
input logic [3:0] ic_wr_en , // Which way to write
|
||||||
input logic ic_rd_en , // Read enable
|
input logic ic_rd_en , // Read enable
|
||||||
|
|
||||||
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_rd_en, // Icache debug rd
|
||||||
input logic ic_debug_wr_en, // Icache debug wr
|
input logic ic_debug_wr_en, // Icache debug wr
|
||||||
input logic ic_debug_tag_array, // Debug tag array
|
input logic ic_debug_tag_array, // Debug tag array
|
||||||
input logic [3:0] ic_debug_way, // Debug way. Rd or Wr.
|
input logic [3:0] ic_debug_way, // Debug way. Rd or Wr.
|
||||||
input logic [127:0] ic_premux_data, // Premux data to be muxed with each way of the Icache.
|
input logic [127:0] ic_premux_data, // Premux data to be muxed with each way of the Icache.
|
||||||
input logic ic_sel_premux_data, // Select the pre_muxed data
|
input logic ic_sel_premux_data, // Select the pre_muxed data
|
||||||
|
|
||||||
|
|
||||||
|
@ -41,47 +41,47 @@ module ifu_ic_mem
|
||||||
`ifdef RV_ICACHE_ECC
|
`ifdef RV_ICACHE_ECC
|
||||||
input logic [83:0] ic_wr_data, // Data to fill to the Icache. With ECC
|
input logic [83:0] ic_wr_data, // Data to fill to the Icache. With ECC
|
||||||
output logic [167:0] ic_rd_data , // Data read from Icache. 2x64bits + parity bits. F2 stage. With 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.
|
output logic [24:0] ictag_debug_rd_data,// Debug icache tag.
|
||||||
input logic [41:0] ic_debug_wr_data, // Debug wr cache.
|
input logic [41:0] ic_debug_wr_data, // Debug wr cache.
|
||||||
`else
|
`else
|
||||||
input logic [67:0] ic_wr_data, // Data to fill to the Icache. With Parity
|
input logic [67:0] ic_wr_data, // Data to fill to the Icache. With Parity
|
||||||
output logic [135:0] ic_rd_data , // Data read from Icache. 2x64bits + parity bits. F2 stage. With Parity
|
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.
|
||||||
input logic [33:0] ic_debug_wr_data, // Debug wr cache.
|
input logic [33:0] ic_debug_wr_data, // Debug wr cache.
|
||||||
`endif
|
`endif
|
||||||
|
|
||||||
|
|
||||||
input logic [3:0] ic_tag_valid, // Valid from the I$ tag valid outside (in flops).
|
input logic [3:0] ic_tag_valid, // Valid from the I$ tag valid outside (in flops).
|
||||||
|
|
||||||
output logic [3:0] ic_rd_hit, // ic_rd_hit[3:0]
|
output logic [3:0] ic_rd_hit, // ic_rd_hit[3:0]
|
||||||
output logic ic_tag_perr, // Tag Parity error
|
output logic ic_tag_perr, // Tag Parity error
|
||||||
input logic scan_mode
|
input logic scan_mode
|
||||||
) ;
|
) ;
|
||||||
|
|
||||||
`include "global.h"
|
`include "global.h"
|
||||||
|
|
||||||
IC_TAG #( .ICACHE_TAG_HIGH(ICACHE_TAG_HIGH) ,
|
IC_TAG #( .ICACHE_TAG_HIGH(ICACHE_TAG_HIGH) ,
|
||||||
.ICACHE_TAG_LOW(ICACHE_TAG_LOW) ,
|
.ICACHE_TAG_LOW(ICACHE_TAG_LOW) ,
|
||||||
.ICACHE_TAG_DEPTH(ICACHE_TAG_DEPTH)
|
.ICACHE_TAG_DEPTH(ICACHE_TAG_DEPTH)
|
||||||
) ic_tag_inst
|
) ic_tag_inst
|
||||||
(
|
(
|
||||||
.*,
|
.*,
|
||||||
.ic_wr_en (ic_wr_en[3:0]),
|
.ic_wr_en (ic_wr_en[3:0]),
|
||||||
.ic_debug_addr(ic_debug_addr[ICACHE_TAG_HIGH-1:2]),
|
.ic_debug_addr(ic_debug_addr[ICACHE_TAG_HIGH-1:2]),
|
||||||
.ic_rw_addr (ic_rw_addr[31:3])
|
.ic_rw_addr (ic_rw_addr[31:3])
|
||||||
) ;
|
) ;
|
||||||
|
|
||||||
IC_DATA #( .ICACHE_TAG_HIGH(ICACHE_TAG_HIGH) ,
|
IC_DATA #( .ICACHE_TAG_HIGH(ICACHE_TAG_HIGH) ,
|
||||||
.ICACHE_TAG_LOW(ICACHE_TAG_LOW) ,
|
.ICACHE_TAG_LOW(ICACHE_TAG_LOW) ,
|
||||||
.ICACHE_IC_DEPTH(ICACHE_IC_DEPTH)
|
.ICACHE_IC_DEPTH(ICACHE_IC_DEPTH)
|
||||||
) ic_data_inst
|
) ic_data_inst
|
||||||
(
|
(
|
||||||
.*,
|
.*,
|
||||||
.ic_wr_en (ic_wr_en[3:0]),
|
.ic_wr_en (ic_wr_en[3:0]),
|
||||||
.ic_debug_addr(ic_debug_addr[ICACHE_TAG_HIGH-1:2]),
|
.ic_debug_addr(ic_debug_addr[ICACHE_TAG_HIGH-1:2]),
|
||||||
.ic_rw_addr (ic_rw_addr[ICACHE_TAG_HIGH-1:3])
|
.ic_rw_addr (ic_rw_addr[ICACHE_TAG_HIGH-1:3])
|
||||||
) ;
|
) ;
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
|
|
||||||
|
@ -89,9 +89,9 @@ module ifu_ic_mem
|
||||||
////// ICACHE DATA MODULE ////////////////////
|
////// ICACHE DATA MODULE ////////////////////
|
||||||
/////////////////////////////////////////////////
|
/////////////////////////////////////////////////
|
||||||
module IC_DATA #(parameter ICACHE_TAG_HIGH = 16 ,
|
module IC_DATA #(parameter ICACHE_TAG_HIGH = 16 ,
|
||||||
ICACHE_TAG_LOW=6 ,
|
ICACHE_TAG_LOW=6 ,
|
||||||
ICACHE_IC_DEPTH=1024
|
ICACHE_IC_DEPTH=1024
|
||||||
)
|
)
|
||||||
(
|
(
|
||||||
input logic clk,
|
input logic clk,
|
||||||
input logic rst_l,
|
input logic rst_l,
|
||||||
|
@ -103,28 +103,28 @@ module IC_DATA #(parameter ICACHE_TAG_HIGH = 16 ,
|
||||||
`ifdef RV_ICACHE_ECC
|
`ifdef RV_ICACHE_ECC
|
||||||
input logic [83:0] ic_wr_data, // Data to fill to the Icache. With ECC
|
input logic [83:0] ic_wr_data, // Data to fill to the Icache. With ECC
|
||||||
output logic [167:0] ic_rd_data , // Data read from Icache. 2x64bits + parity bits. F2 stage. With ECC
|
output logic [167:0] ic_rd_data , // Data read from Icache. 2x64bits + parity bits. F2 stage. With ECC
|
||||||
input logic [41:0] ic_debug_wr_data, // Debug wr cache.
|
input logic [41:0] ic_debug_wr_data, // Debug wr cache.
|
||||||
`else
|
`else
|
||||||
input logic [67:0] ic_wr_data, // Data to fill to the Icache. With Parity
|
input logic [67:0] ic_wr_data, // Data to fill to the Icache. With Parity
|
||||||
output logic [135:0] ic_rd_data , // Data read from Icache. 2x64bits + parity bits. F2 stage. With Parity
|
output logic [135:0] ic_rd_data , // Data read from Icache. 2x64bits + parity bits. F2 stage. 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
|
`endif
|
||||||
|
|
||||||
|
|
||||||
input logic [ICACHE_TAG_HIGH-1:2] ic_debug_addr, // Read/Write addresss to the Icache.
|
input logic [ICACHE_TAG_HIGH-1:2] ic_debug_addr, // Read/Write addresss to the Icache.
|
||||||
input logic ic_debug_rd_en, // Icache debug rd
|
input logic ic_debug_rd_en, // Icache debug rd
|
||||||
input logic ic_debug_wr_en, // Icache debug wr
|
input logic ic_debug_wr_en, // Icache debug wr
|
||||||
input logic ic_debug_tag_array, // Debug tag array
|
input logic ic_debug_tag_array, // Debug tag array
|
||||||
input logic [3:0] ic_debug_way, // Debug way. Rd or Wr.
|
input logic [3:0] ic_debug_way, // Debug way. Rd or Wr.
|
||||||
input logic [127:0] ic_premux_data, // Premux data to be muxed with each way of the Icache.
|
input logic [127:0] ic_premux_data, // Premux data to be muxed with each way of the Icache.
|
||||||
input logic ic_sel_premux_data, // Select the pre_muxed data
|
input logic ic_sel_premux_data, // Select the pre_muxed data
|
||||||
|
|
||||||
input logic [3:0] ic_rd_hit,
|
input logic [3:0] ic_rd_hit,
|
||||||
|
|
||||||
input logic scan_mode
|
input logic scan_mode
|
||||||
|
|
||||||
) ;
|
) ;
|
||||||
|
|
||||||
logic [5:4] ic_rw_addr_ff;
|
logic [5:4] ic_rw_addr_ff;
|
||||||
|
|
||||||
|
|
||||||
|
@ -135,17 +135,17 @@ module IC_DATA #(parameter ICACHE_TAG_HIGH = 16 ,
|
||||||
logic ic_debug_sel_sb2 ;
|
logic ic_debug_sel_sb2 ;
|
||||||
logic ic_debug_sel_sb3 ;
|
logic ic_debug_sel_sb3 ;
|
||||||
|
|
||||||
|
|
||||||
`ifdef RV_ICACHE_ECC
|
`ifdef RV_ICACHE_ECC
|
||||||
logic [3:0] [167:0] bank_set_dout;
|
logic [3:0] [167:0] bank_set_dout;
|
||||||
logic [3:0][167:0] wb_dout ; //
|
logic [3:0][167:0] wb_dout ; //
|
||||||
logic [3:0][41:0] ic_sb_wr_data;
|
logic [3:0][41:0] ic_sb_wr_data;
|
||||||
`else
|
`else
|
||||||
logic [3:0] [135:0] bank_set_dout;
|
logic [3:0] [135:0] bank_set_dout;
|
||||||
logic [3:0] [135:0] wb_dout ; // bank , way , size
|
logic [3:0] [135:0] wb_dout ; // bank , way , size
|
||||||
logic [3:0] [33:0] ic_sb_wr_data;
|
logic [3:0] [33:0] ic_sb_wr_data;
|
||||||
`endif
|
`endif
|
||||||
|
|
||||||
logic [3:0] ic_bank_way_clken; // bank , way
|
logic [3:0] ic_bank_way_clken; // bank , way
|
||||||
logic [3:0] ic_bank_way_clk ; // bank , way
|
logic [3:0] ic_bank_way_clk ; // bank , way
|
||||||
logic ic_b_rden;
|
logic ic_b_rden;
|
||||||
|
@ -153,74 +153,74 @@ module IC_DATA #(parameter ICACHE_TAG_HIGH = 16 ,
|
||||||
logic [3:0] ic_debug_rd_way_en_ff; // debug wr_way
|
logic [3:0] ic_debug_rd_way_en_ff; // debug wr_way
|
||||||
logic [3:0] ic_debug_wr_way_en; // debug wr_way
|
logic [3:0] ic_debug_wr_way_en; // debug wr_way
|
||||||
logic [ICACHE_TAG_HIGH-1:4] ic_rw_addr_q;
|
logic [ICACHE_TAG_HIGH-1:4] ic_rw_addr_q;
|
||||||
|
|
||||||
assign ic_debug_rd_way_en[3:0] = {4{ic_debug_rd_en & ~ic_debug_tag_array}} & ic_debug_way[3:0] ;
|
assign ic_debug_rd_way_en[3:0] = {4{ic_debug_rd_en & ~ic_debug_tag_array}} & ic_debug_way[3:0] ;
|
||||||
assign ic_debug_wr_way_en[3:0] = {4{ic_debug_wr_en & ~ic_debug_tag_array}} & ic_debug_way[3:0] ;
|
assign ic_debug_wr_way_en[3:0] = {4{ic_debug_wr_en & ~ic_debug_tag_array}} & ic_debug_way[3:0] ;
|
||||||
|
|
||||||
assign ic_b_sb_wren[0][3:0] = (ic_wr_en[3:0] & {4{~ic_rw_addr[3]}} ) |
|
assign ic_b_sb_wren[0][3:0] = (ic_wr_en[3:0] & {4{~ic_rw_addr[3]}} ) |
|
||||||
(ic_debug_wr_way_en[3:0] & {4{ic_debug_addr[3:2] == 2'b00}}) ;
|
(ic_debug_wr_way_en[3:0] & {4{ic_debug_addr[3:2] == 2'b00}}) ;
|
||||||
assign ic_b_sb_wren[1][3:0] = (ic_wr_en[3:0] & {4{~ic_rw_addr[3]}} ) |
|
assign ic_b_sb_wren[1][3:0] = (ic_wr_en[3:0] & {4{~ic_rw_addr[3]}} ) |
|
||||||
(ic_debug_wr_way_en[3:0] & {4{ic_debug_addr[3:2] == 2'b01}}) ;
|
(ic_debug_wr_way_en[3:0] & {4{ic_debug_addr[3:2] == 2'b01}}) ;
|
||||||
assign ic_b_sb_wren[2][3:0] = (ic_wr_en[3:0] & {4{ic_rw_addr[3]}} ) |
|
assign ic_b_sb_wren[2][3:0] = (ic_wr_en[3:0] & {4{ic_rw_addr[3]}} ) |
|
||||||
(ic_debug_wr_way_en[3:0] & {4{ic_debug_addr[3:2] == 2'b10}}) ;
|
(ic_debug_wr_way_en[3:0] & {4{ic_debug_addr[3:2] == 2'b10}}) ;
|
||||||
assign ic_b_sb_wren[3][3:0] = (ic_wr_en[3:0] & {4{ic_rw_addr[3]}} ) |
|
assign ic_b_sb_wren[3][3:0] = (ic_wr_en[3:0] & {4{ic_rw_addr[3]}} ) |
|
||||||
(ic_debug_wr_way_en[3:0] & {4{ic_debug_addr[3:2] == 2'b11}}) ;
|
(ic_debug_wr_way_en[3:0] & {4{ic_debug_addr[3:2] == 2'b11}}) ;
|
||||||
|
|
||||||
assign ic_debug_sel_sb0 = (ic_debug_addr[3:2] == 2'b00 ) ;
|
assign ic_debug_sel_sb0 = (ic_debug_addr[3:2] == 2'b00 ) ;
|
||||||
assign ic_debug_sel_sb1 = (ic_debug_addr[3:2] == 2'b01 ) ;
|
assign ic_debug_sel_sb1 = (ic_debug_addr[3:2] == 2'b01 ) ;
|
||||||
assign ic_debug_sel_sb2 = (ic_debug_addr[3:2] == 2'b10 ) ;
|
assign ic_debug_sel_sb2 = (ic_debug_addr[3:2] == 2'b10 ) ;
|
||||||
assign ic_debug_sel_sb3 = (ic_debug_addr[3:2] == 2'b11 ) ;
|
assign ic_debug_sel_sb3 = (ic_debug_addr[3:2] == 2'b11 ) ;
|
||||||
|
|
||||||
`ifdef RV_ICACHE_ECC
|
`ifdef RV_ICACHE_ECC
|
||||||
|
|
||||||
assign ic_sb_wr_data[0][41:0] = (ic_debug_sel_sb0 & ic_debug_wr_en) ? {ic_debug_wr_data[41:0]} :
|
assign ic_sb_wr_data[0][41:0] = (ic_debug_sel_sb0 & ic_debug_wr_en) ? {ic_debug_wr_data[41:0]} :
|
||||||
ic_wr_data[41:0] ;
|
ic_wr_data[41:0] ;
|
||||||
assign ic_sb_wr_data[1][41:0] = (ic_debug_sel_sb1 & ic_debug_wr_en) ? {ic_debug_wr_data[41:0]} :
|
assign ic_sb_wr_data[1][41:0] = (ic_debug_sel_sb1 & ic_debug_wr_en) ? {ic_debug_wr_data[41:0]} :
|
||||||
ic_wr_data[83:42] ;
|
ic_wr_data[83:42] ;
|
||||||
assign ic_sb_wr_data[2][41:0] = (ic_debug_sel_sb2 & ic_debug_wr_en) ? {ic_debug_wr_data[41:0]} :
|
assign ic_sb_wr_data[2][41:0] = (ic_debug_sel_sb2 & ic_debug_wr_en) ? {ic_debug_wr_data[41:0]} :
|
||||||
ic_wr_data[41:0] ;
|
ic_wr_data[41:0] ;
|
||||||
assign ic_sb_wr_data[3][41:0] = (ic_debug_sel_sb3 & ic_debug_wr_en) ? {ic_debug_wr_data[41:0]} :
|
assign ic_sb_wr_data[3][41:0] = (ic_debug_sel_sb3 & ic_debug_wr_en) ? {ic_debug_wr_data[41:0]} :
|
||||||
ic_wr_data[83:42] ;
|
ic_wr_data[83:42] ;
|
||||||
`else
|
`else
|
||||||
assign ic_sb_wr_data[0][33:0] = (ic_debug_sel_sb0 & ic_debug_wr_en) ? ic_debug_wr_data[33:0] :
|
assign ic_sb_wr_data[0][33:0] = (ic_debug_sel_sb0 & ic_debug_wr_en) ? ic_debug_wr_data[33:0] :
|
||||||
ic_wr_data[33:0] ;
|
ic_wr_data[33:0] ;
|
||||||
assign ic_sb_wr_data[1][33:0] = (ic_debug_sel_sb1 & ic_debug_wr_en) ? ic_debug_wr_data[33:0] :
|
assign ic_sb_wr_data[1][33:0] = (ic_debug_sel_sb1 & ic_debug_wr_en) ? ic_debug_wr_data[33:0] :
|
||||||
ic_wr_data[67:34] ;
|
ic_wr_data[67:34] ;
|
||||||
assign ic_sb_wr_data[2][33:0] = (ic_debug_sel_sb2 & ic_debug_wr_en) ? ic_debug_wr_data[33:0] :
|
assign ic_sb_wr_data[2][33:0] = (ic_debug_sel_sb2 & ic_debug_wr_en) ? ic_debug_wr_data[33:0] :
|
||||||
ic_wr_data[33:0] ;
|
ic_wr_data[33:0] ;
|
||||||
assign ic_sb_wr_data[3][33:0] = (ic_debug_sel_sb3 & ic_debug_wr_en) ? ic_debug_wr_data[33:0] :
|
assign ic_sb_wr_data[3][33:0] = (ic_debug_sel_sb3 & ic_debug_wr_en) ? ic_debug_wr_data[33:0] :
|
||||||
ic_wr_data[67:34] ;
|
ic_wr_data[67:34] ;
|
||||||
`endif
|
`endif
|
||||||
|
|
||||||
|
|
||||||
// bank read enables
|
// bank read enables
|
||||||
|
|
||||||
assign ic_b_rden = (ic_rd_en | ic_debug_rd_en );
|
assign ic_b_rden = (ic_rd_en | ic_debug_rd_en );
|
||||||
|
|
||||||
assign ic_bank_way_clken[3:0] = ({4{ic_b_rden | clk_override }}) |
|
assign ic_bank_way_clken[3:0] = ({4{ic_b_rden | clk_override }}) |
|
||||||
ic_b_sb_wren[0][3:0] |
|
ic_b_sb_wren[0][3:0] |
|
||||||
ic_b_sb_wren[1][3:0] |
|
ic_b_sb_wren[1][3:0] |
|
||||||
ic_b_sb_wren[2][3:0] |
|
ic_b_sb_wren[2][3:0] |
|
||||||
ic_b_sb_wren[3][3:0] ;
|
ic_b_sb_wren[3][3:0] ;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
assign ic_rw_addr_q[ICACHE_TAG_HIGH-1:4] = (ic_debug_rd_en | ic_debug_wr_en) ?
|
assign ic_rw_addr_q[ICACHE_TAG_HIGH-1:4] = (ic_debug_rd_en | ic_debug_wr_en) ?
|
||||||
ic_debug_addr[ICACHE_TAG_HIGH-1:4] :
|
ic_debug_addr[ICACHE_TAG_HIGH-1:4] :
|
||||||
ic_rw_addr[ICACHE_TAG_HIGH-1:4] ;
|
ic_rw_addr[ICACHE_TAG_HIGH-1:4] ;
|
||||||
|
|
||||||
logic ic_debug_rd_en_ff;
|
logic ic_debug_rd_en_ff;
|
||||||
|
|
||||||
rvdff #(2) adr_ff (.*,
|
rvdff #(2) adr_ff (.*,
|
||||||
.din ({ic_rw_addr_q[5:4]}),
|
.din ({ic_rw_addr_q[5:4]}),
|
||||||
.dout({ic_rw_addr_ff[5:4]}));
|
.dout({ic_rw_addr_ff[5:4]}));
|
||||||
|
|
||||||
rvdff #(5) debug_rd_wy_ff (.*,
|
rvdff #(5) debug_rd_wy_ff (.*,
|
||||||
.din ({ic_debug_rd_way_en[3:0], ic_debug_rd_en}),
|
.din ({ic_debug_rd_way_en[3:0], ic_debug_rd_en}),
|
||||||
.dout({ic_debug_rd_way_en_ff[3:0], ic_debug_rd_en_ff}));
|
.dout({ic_debug_rd_way_en_ff[3:0], ic_debug_rd_en_ff}));
|
||||||
|
|
||||||
localparam NUM_WAYS=4 ;
|
localparam NUM_WAYS=4 ;
|
||||||
localparam NUM_SUBBANKS=4 ;
|
localparam NUM_SUBBANKS=4 ;
|
||||||
|
|
||||||
|
|
||||||
for (genvar i=0; i<NUM_WAYS; i++) begin: WAYS
|
for (genvar i=0; i<NUM_WAYS; i++) begin: WAYS
|
||||||
|
@ -230,7 +230,7 @@ localparam NUM_SUBBANKS=4 ;
|
||||||
for (genvar k=0; k<NUM_SUBBANKS; k++) begin: SUBBANKS // 16B subbank
|
for (genvar k=0; k<NUM_SUBBANKS; k++) begin: SUBBANKS // 16B subbank
|
||||||
|
|
||||||
`ifdef RV_ICACHE_ECC
|
`ifdef RV_ICACHE_ECC
|
||||||
`RV_ICACHE_DATA_CELL ic_bank_sb_way_data (
|
`RV_ICACHE_DATA_CELL ic_bank_sb_way_data (
|
||||||
.CLK(ic_bank_way_clk[i]),
|
.CLK(ic_bank_way_clk[i]),
|
||||||
.WE (ic_b_sb_wren[k][i]),
|
.WE (ic_b_sb_wren[k][i]),
|
||||||
.D (ic_sb_wr_data[k][41:0]),
|
.D (ic_sb_wr_data[k][41:0]),
|
||||||
|
@ -238,7 +238,7 @@ localparam NUM_SUBBANKS=4 ;
|
||||||
.Q (wb_dout[i][(k+1)*42-1:k*42])
|
.Q (wb_dout[i][(k+1)*42-1:k*42])
|
||||||
);
|
);
|
||||||
`else
|
`else
|
||||||
`RV_ICACHE_DATA_CELL ic_bank_sb_way_data (
|
`RV_ICACHE_DATA_CELL ic_bank_sb_way_data (
|
||||||
.CLK(ic_bank_way_clk[i]),
|
.CLK(ic_bank_way_clk[i]),
|
||||||
.WE (ic_b_sb_wren[k][i]),
|
.WE (ic_b_sb_wren[k][i]),
|
||||||
.D (ic_sb_wr_data[k][33:0]),
|
.D (ic_sb_wr_data[k][33:0]),
|
||||||
|
@ -247,16 +247,16 @@ localparam NUM_SUBBANKS=4 ;
|
||||||
);
|
);
|
||||||
`endif
|
`endif
|
||||||
end // block: SUBBANKS
|
end // block: SUBBANKS
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
logic [3:0] ic_rd_hit_q;
|
logic [3:0] ic_rd_hit_q;
|
||||||
assign ic_rd_hit_q[3:0] = ic_debug_rd_en_ff ? ic_debug_rd_way_en_ff[3:0] : ic_rd_hit[3:0] ;
|
assign ic_rd_hit_q[3:0] = ic_debug_rd_en_ff ? ic_debug_rd_way_en_ff[3:0] : ic_rd_hit[3:0] ;
|
||||||
|
|
||||||
// set mux
|
// set mux
|
||||||
`ifdef RV_ICACHE_ECC
|
`ifdef RV_ICACHE_ECC
|
||||||
logic [167:0] ic_premux_data_ext;
|
logic [167:0] ic_premux_data_ext;
|
||||||
logic [3:0] [167:0] wb_dout_way;
|
logic [3:0] [167:0] wb_dout_way;
|
||||||
logic [3:0] [167:0] wb_dout_way_with_premux;
|
logic [3:0] [167:0] wb_dout_way_with_premux;
|
||||||
|
|
||||||
|
@ -278,7 +278,7 @@ localparam NUM_SUBBANKS=4 ;
|
||||||
({168{ic_rd_hit_q[3] | ic_sel_premux_data}} & wb_dout_way_with_premux[3][167:0]) ;
|
({168{ic_rd_hit_q[3] | ic_sel_premux_data}} & wb_dout_way_with_premux[3][167:0]) ;
|
||||||
|
|
||||||
`else
|
`else
|
||||||
logic [135:0] ic_premux_data_ext;
|
logic [135:0] ic_premux_data_ext;
|
||||||
logic [3:0] [135:0] wb_dout_way;
|
logic [3:0] [135:0] wb_dout_way;
|
||||||
logic [3:0] [135:0] wb_dout_way_with_premux;
|
logic [3:0] [135:0] wb_dout_way_with_premux;
|
||||||
|
|
||||||
|
@ -287,7 +287,7 @@ localparam NUM_SUBBANKS=4 ;
|
||||||
assign wb_dout_way[1][135:0] = wb_dout[1][135:0];
|
assign wb_dout_way[1][135:0] = wb_dout[1][135:0];
|
||||||
assign wb_dout_way[2][135:0] = wb_dout[2][135:0];
|
assign wb_dout_way[2][135:0] = wb_dout[2][135:0];
|
||||||
assign wb_dout_way[3][135:0] = wb_dout[3][135:0];
|
assign wb_dout_way[3][135:0] = wb_dout[3][135:0];
|
||||||
|
|
||||||
assign wb_dout_way_with_premux[0][135:0] = ic_sel_premux_data ? ic_premux_data_ext[135:0] : wb_dout_way[0][135:0] ;
|
assign wb_dout_way_with_premux[0][135:0] = ic_sel_premux_data ? ic_premux_data_ext[135:0] : wb_dout_way[0][135:0] ;
|
||||||
assign wb_dout_way_with_premux[1][135:0] = ic_sel_premux_data ? ic_premux_data_ext[135:0] : wb_dout_way[1][135:0] ;
|
assign wb_dout_way_with_premux[1][135:0] = ic_sel_premux_data ? ic_premux_data_ext[135:0] : wb_dout_way[1][135:0] ;
|
||||||
assign wb_dout_way_with_premux[2][135:0] = ic_sel_premux_data ? ic_premux_data_ext[135:0] : wb_dout_way[2][135:0] ;
|
assign wb_dout_way_with_premux[2][135:0] = ic_sel_premux_data ? ic_premux_data_ext[135:0] : wb_dout_way[2][135:0] ;
|
||||||
|
@ -299,7 +299,7 @@ localparam NUM_SUBBANKS=4 ;
|
||||||
({136{ic_rd_hit_q[3] | ic_sel_premux_data}} & wb_dout_way_with_premux[3][135:0]) ;
|
({136{ic_rd_hit_q[3] | ic_sel_premux_data}} & wb_dout_way_with_premux[3][135:0]) ;
|
||||||
|
|
||||||
`endif
|
`endif
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
|
|
||||||
|
@ -307,22 +307,22 @@ localparam NUM_SUBBANKS=4 ;
|
||||||
////// ICACHE TAG MODULE ////////////////////
|
////// ICACHE TAG MODULE ////////////////////
|
||||||
/////////////////////////////////////////////////
|
/////////////////////////////////////////////////
|
||||||
module IC_TAG #(parameter ICACHE_TAG_HIGH = 16 ,
|
module IC_TAG #(parameter ICACHE_TAG_HIGH = 16 ,
|
||||||
ICACHE_TAG_LOW=6 ,
|
ICACHE_TAG_LOW=6 ,
|
||||||
ICACHE_TAG_DEPTH=1024
|
ICACHE_TAG_DEPTH=1024
|
||||||
)
|
)
|
||||||
(
|
(
|
||||||
input logic clk,
|
input logic clk,
|
||||||
input logic rst_l,
|
input logic rst_l,
|
||||||
input logic clk_override,
|
input logic clk_override,
|
||||||
input logic dec_tlu_core_ecc_disable,
|
input logic dec_tlu_core_ecc_disable,
|
||||||
|
|
||||||
input logic [31:3] ic_rw_addr,
|
input logic [31:3] ic_rw_addr,
|
||||||
|
|
||||||
input logic [3:0] ic_wr_en, // way
|
input logic [3:0] ic_wr_en, // way
|
||||||
input logic [3:0] ic_tag_valid,
|
input logic [3:0] ic_tag_valid,
|
||||||
input logic ic_rd_en,
|
input logic ic_rd_en,
|
||||||
|
|
||||||
input logic [ICACHE_TAG_HIGH-1:2] ic_debug_addr, // Read/Write addresss to the Icache.
|
input logic [ICACHE_TAG_HIGH-1:2] ic_debug_addr, // Read/Write addresss to the Icache.
|
||||||
input logic ic_debug_rd_en, // Icache debug rd
|
input logic ic_debug_rd_en, // Icache debug rd
|
||||||
input logic ic_debug_wr_en, // Icache debug wr
|
input logic ic_debug_wr_en, // Icache debug wr
|
||||||
input logic ic_debug_tag_array, // Debug tag array
|
input logic ic_debug_tag_array, // Debug tag array
|
||||||
|
@ -330,20 +330,20 @@ module IC_TAG #(parameter ICACHE_TAG_HIGH = 16 ,
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
`ifdef RV_ICACHE_ECC
|
`ifdef RV_ICACHE_ECC
|
||||||
output logic [24:0] ictag_debug_rd_data,
|
output logic [24:0] ictag_debug_rd_data,
|
||||||
input logic [41:0] ic_debug_wr_data, // Debug wr cache.
|
input logic [41:0] ic_debug_wr_data, // Debug wr cache.
|
||||||
`else
|
`else
|
||||||
output logic [20:0] ictag_debug_rd_data,
|
output logic [20:0] ictag_debug_rd_data,
|
||||||
input logic [33:0] ic_debug_wr_data, // Debug wr cache.
|
input logic [33:0] ic_debug_wr_data, // Debug wr cache.
|
||||||
`endif
|
`endif
|
||||||
output logic [3:0] ic_rd_hit,
|
output logic [3:0] ic_rd_hit,
|
||||||
output logic ic_tag_perr,
|
output logic ic_tag_perr,
|
||||||
input logic scan_mode
|
input logic scan_mode
|
||||||
|
|
||||||
) ;
|
) ;
|
||||||
|
|
||||||
`ifdef RV_ICACHE_ECC
|
`ifdef RV_ICACHE_ECC
|
||||||
logic [3:0] [24:0] ic_tag_data_raw;
|
logic [3:0] [24:0] ic_tag_data_raw;
|
||||||
logic [3:0] [37:ICACHE_TAG_HIGH] w_tout;
|
logic [3:0] [37:ICACHE_TAG_HIGH] w_tout;
|
||||||
|
@ -370,78 +370,78 @@ module IC_TAG #(parameter ICACHE_TAG_HIGH = 16 ,
|
||||||
logic [3:0] ic_tag_clken ;
|
logic [3:0] ic_tag_clken ;
|
||||||
logic [3:0] ic_debug_wr_way_en; // debug wr_way
|
logic [3:0] ic_debug_wr_way_en; // debug wr_way
|
||||||
|
|
||||||
assign ic_tag_wren [3:0] = ic_wr_en[3:0] & {4{ic_rw_addr[5:3] == 3'b111}} ;
|
assign ic_tag_wren [3:0] = ic_wr_en[3:0] & {4{ic_rw_addr[5:3] == 3'b111}} ;
|
||||||
assign ic_tag_clken[3:0] = {4{ic_rd_en | clk_override}} | ic_wr_en[3:0] | ic_debug_wr_way_en[3:0] | ic_debug_rd_way_en[3:0];
|
assign ic_tag_clken[3:0] = {4{ic_rd_en | clk_override}} | ic_wr_en[3:0] | ic_debug_wr_way_en[3:0] | ic_debug_rd_way_en[3:0];
|
||||||
|
|
||||||
rvdff #(32-ICACHE_TAG_HIGH) adr_ff (.*,
|
rvdff #(32-ICACHE_TAG_HIGH) adr_ff (.*,
|
||||||
.din ({ic_rw_addr[31:ICACHE_TAG_HIGH]}),
|
.din ({ic_rw_addr[31:ICACHE_TAG_HIGH]}),
|
||||||
.dout({ic_rw_addr_ff[31:ICACHE_TAG_HIGH]}));
|
.dout({ic_rw_addr_ff[31:ICACHE_TAG_HIGH]}));
|
||||||
|
|
||||||
|
|
||||||
localparam TOP_BITS = 21+ICACHE_TAG_HIGH-33 ;
|
localparam TOP_BITS = 21+ICACHE_TAG_HIGH-33 ;
|
||||||
localparam NUM_WAYS=4 ;
|
localparam NUM_WAYS=4 ;
|
||||||
// tags
|
// tags
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
assign ic_debug_rd_way_en[3:0] = {4{ic_debug_rd_en & ic_debug_tag_array}} & ic_debug_way[3:0] ;
|
assign ic_debug_rd_way_en[3:0] = {4{ic_debug_rd_en & ic_debug_tag_array}} & ic_debug_way[3:0] ;
|
||||||
assign ic_debug_wr_way_en[3:0] = {4{ic_debug_wr_en & ic_debug_tag_array}} & ic_debug_way[3:0] ;
|
assign ic_debug_wr_way_en[3:0] = {4{ic_debug_wr_en & ic_debug_tag_array}} & ic_debug_way[3:0] ;
|
||||||
|
|
||||||
assign ic_tag_wren_q[3:0] = ic_tag_wren[3:0] |
|
assign ic_tag_wren_q[3:0] = ic_tag_wren[3:0] |
|
||||||
ic_debug_wr_way_en[3:0] ;
|
ic_debug_wr_way_en[3:0] ;
|
||||||
|
|
||||||
if (ICACHE_TAG_HIGH == 12) begin: SMALLEST
|
if (ICACHE_TAG_HIGH == 12) begin: SMALLEST
|
||||||
`ifdef RV_ICACHE_ECC
|
`ifdef RV_ICACHE_ECC
|
||||||
logic [6:0] ic_tag_ecc;
|
logic [6:0] ic_tag_ecc;
|
||||||
rvecc_encode tag_ecc_encode (
|
rvecc_encode tag_ecc_encode (
|
||||||
.din ({{ICACHE_TAG_HIGH{1'b0}}, ic_rw_addr[31:ICACHE_TAG_HIGH]}),
|
.din ({{ICACHE_TAG_HIGH{1'b0}}, ic_rw_addr[31:ICACHE_TAG_HIGH]}),
|
||||||
.ecc_out({ ic_tag_ecc[6:0]}));
|
.ecc_out({ ic_tag_ecc[6:0]}));
|
||||||
|
|
||||||
assign ic_tag_wr_data[24:0] = (ic_debug_wr_en & ic_debug_tag_array) ?
|
assign ic_tag_wr_data[24:0] = (ic_debug_wr_en & ic_debug_tag_array) ?
|
||||||
{ic_debug_wr_data[36:32], ic_debug_wr_data[31:12]} :
|
{ic_debug_wr_data[36:32], ic_debug_wr_data[31:12]} :
|
||||||
{ic_tag_ecc[4:0], ic_rw_addr[31:ICACHE_TAG_HIGH]} ;
|
{ic_tag_ecc[4:0], ic_rw_addr[31:ICACHE_TAG_HIGH]} ;
|
||||||
`else
|
`else
|
||||||
logic ic_tag_parity ;
|
logic ic_tag_parity ;
|
||||||
rveven_paritygen #(32-ICACHE_TAG_HIGH) pargen (.data_in (ic_rw_addr[31:ICACHE_TAG_HIGH]),
|
rveven_paritygen #(32-ICACHE_TAG_HIGH) pargen (.data_in (ic_rw_addr[31:ICACHE_TAG_HIGH]),
|
||||||
.parity_out(ic_tag_parity));
|
.parity_out(ic_tag_parity));
|
||||||
|
|
||||||
assign ic_tag_wr_data[20:0] = (ic_debug_wr_en & ic_debug_tag_array) ?
|
assign ic_tag_wr_data[20:0] = (ic_debug_wr_en & ic_debug_tag_array) ?
|
||||||
{ic_debug_wr_data[32], ic_debug_wr_data[31:12]} :
|
{ic_debug_wr_data[32], ic_debug_wr_data[31:12]} :
|
||||||
{ic_tag_parity, ic_rw_addr[31:ICACHE_TAG_HIGH]} ;
|
{ic_tag_parity, ic_rw_addr[31:ICACHE_TAG_HIGH]} ;
|
||||||
`endif
|
`endif
|
||||||
end else begin: OTHERS
|
end else begin: OTHERS
|
||||||
`ifdef RV_ICACHE_ECC
|
`ifdef RV_ICACHE_ECC
|
||||||
logic [6:0] ic_tag_ecc;
|
logic [6:0] ic_tag_ecc;
|
||||||
rvecc_encode tag_ecc_encode (
|
rvecc_encode tag_ecc_encode (
|
||||||
.din ({{ICACHE_TAG_HIGH{1'b0}}, ic_rw_addr[31:ICACHE_TAG_HIGH]}),
|
.din ({{ICACHE_TAG_HIGH{1'b0}}, ic_rw_addr[31:ICACHE_TAG_HIGH]}),
|
||||||
.ecc_out({ ic_tag_ecc[6:0]}));
|
.ecc_out({ ic_tag_ecc[6:0]}));
|
||||||
|
|
||||||
assign ic_tag_wr_data[24:0] = (ic_debug_wr_en & ic_debug_tag_array) ?
|
assign ic_tag_wr_data[24:0] = (ic_debug_wr_en & ic_debug_tag_array) ?
|
||||||
{ic_debug_wr_data[36:32], ic_debug_wr_data[31:12]} :
|
{ic_debug_wr_data[36:32], ic_debug_wr_data[31:12]} :
|
||||||
{ic_tag_ecc[4:0], {TOP_BITS{1'b0}},ic_rw_addr[31:ICACHE_TAG_HIGH]} ;
|
{ic_tag_ecc[4:0], {TOP_BITS{1'b0}},ic_rw_addr[31:ICACHE_TAG_HIGH]} ;
|
||||||
|
|
||||||
`else
|
`else
|
||||||
logic ic_tag_parity ;
|
logic ic_tag_parity ;
|
||||||
rveven_paritygen #(32-ICACHE_TAG_HIGH) pargen (.data_in (ic_rw_addr[31:ICACHE_TAG_HIGH]),
|
rveven_paritygen #(32-ICACHE_TAG_HIGH) pargen (.data_in (ic_rw_addr[31:ICACHE_TAG_HIGH]),
|
||||||
.parity_out(ic_tag_parity));
|
.parity_out(ic_tag_parity));
|
||||||
assign ic_tag_wr_data[20:0] = (ic_debug_wr_en & ic_debug_tag_array) ?
|
assign ic_tag_wr_data[20:0] = (ic_debug_wr_en & ic_debug_tag_array) ?
|
||||||
{ic_debug_wr_data[32], ic_debug_wr_data[31:12]} :
|
{ic_debug_wr_data[32], ic_debug_wr_data[31:12]} :
|
||||||
{ic_tag_parity, {TOP_BITS{1'b0}},ic_rw_addr[31:ICACHE_TAG_HIGH]} ;
|
{ic_tag_parity, {TOP_BITS{1'b0}},ic_rw_addr[31:ICACHE_TAG_HIGH]} ;
|
||||||
`endif
|
`endif
|
||||||
end
|
end
|
||||||
|
|
||||||
assign ic_rw_addr_q[ICACHE_TAG_HIGH-1:6] = (ic_debug_rd_en | ic_debug_wr_en) ?
|
assign ic_rw_addr_q[ICACHE_TAG_HIGH-1:6] = (ic_debug_rd_en | ic_debug_wr_en) ?
|
||||||
ic_debug_addr[ICACHE_TAG_HIGH-1:6] :
|
ic_debug_addr[ICACHE_TAG_HIGH-1:6] :
|
||||||
ic_rw_addr[ICACHE_TAG_HIGH-1:6] ;
|
ic_rw_addr[ICACHE_TAG_HIGH-1:6] ;
|
||||||
|
|
||||||
|
|
||||||
rvdff #(4) tag_rd_wy_ff (.*,
|
rvdff #(4) tag_rd_wy_ff (.*,
|
||||||
.din ({ic_debug_rd_way_en[3:0]}),
|
.din ({ic_debug_rd_way_en[3:0]}),
|
||||||
.dout({ic_debug_rd_way_en_ff[3:0]}));
|
.dout({ic_debug_rd_way_en_ff[3:0]}));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
for (genvar i=0; i<NUM_WAYS; i++) begin: WAYS
|
for (genvar i=0; i<NUM_WAYS; i++) begin: WAYS
|
||||||
rvclkhdr ic_tag_c1_cgc ( .en(ic_tag_clken[i]), .l1clk(ic_tag_clk[i]), .* );
|
rvclkhdr ic_tag_c1_cgc ( .en(ic_tag_clken[i]), .l1clk(ic_tag_clk[i]), .* );
|
||||||
if (ICACHE_TAG_DEPTH == 64 ) begin : ICACHE_SZ_16
|
if (ICACHE_TAG_DEPTH == 64 ) begin : ICACHE_SZ_16
|
||||||
|
@ -453,13 +453,13 @@ end
|
||||||
.ADR(ic_rw_addr_q[ICACHE_TAG_HIGH-1:ICACHE_TAG_LOW]),
|
.ADR(ic_rw_addr_q[ICACHE_TAG_HIGH-1:ICACHE_TAG_LOW]),
|
||||||
.Q (ic_tag_data_raw[i][24:0])
|
.Q (ic_tag_data_raw[i][24:0])
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
assign w_tout[i][31:ICACHE_TAG_HIGH] = ic_tag_data_raw[i][31-ICACHE_TAG_HIGH:0] ;
|
assign w_tout[i][31:ICACHE_TAG_HIGH] = ic_tag_data_raw[i][31-ICACHE_TAG_HIGH:0] ;
|
||||||
assign w_tout[i][36:32] = ic_tag_data_raw[i][24:20] ;
|
assign w_tout[i][36:32] = ic_tag_data_raw[i][24:20] ;
|
||||||
|
|
||||||
rvecc_decode ecc_decode (
|
rvecc_decode ecc_decode (
|
||||||
.en(~dec_tlu_core_ecc_disable),
|
.en(~dec_tlu_core_ecc_disable),
|
||||||
.sed_ded ( 1'b1 ), // 1 : means only detection
|
.sed_ded ( 1'b1 ), // 1 : means only detection
|
||||||
.din({12'b0,ic_tag_data_raw[i][19:0]}),
|
.din({12'b0,ic_tag_data_raw[i][19:0]}),
|
||||||
.ecc_in({2'b0, ic_tag_data_raw[i][24:20]}),
|
.ecc_in({2'b0, ic_tag_data_raw[i][24:20]}),
|
||||||
|
@ -481,14 +481,14 @@ end
|
||||||
assign w_tout[i][31:ICACHE_TAG_HIGH] = ic_tag_data_raw[i][31-ICACHE_TAG_HIGH:0] ;
|
assign w_tout[i][31:ICACHE_TAG_HIGH] = ic_tag_data_raw[i][31-ICACHE_TAG_HIGH:0] ;
|
||||||
assign w_tout[i][32] = ic_tag_data_raw[i][20] ;
|
assign w_tout[i][32] = ic_tag_data_raw[i][20] ;
|
||||||
|
|
||||||
rveven_paritycheck #(32-ICACHE_TAG_HIGH) parcheck(.data_in (w_tout[i][31:ICACHE_TAG_HIGH]),
|
rveven_paritycheck #(32-ICACHE_TAG_HIGH) parcheck(.data_in (w_tout[i][31:ICACHE_TAG_HIGH]),
|
||||||
.parity_in (w_tout[i][32]),
|
.parity_in (w_tout[i][32]),
|
||||||
.parity_err(ic_tag_way_perr[i]));
|
.parity_err(ic_tag_way_perr[i]));
|
||||||
`endif
|
`endif
|
||||||
|
|
||||||
end // block: ICACHE_SZ_16
|
end // block: ICACHE_SZ_16
|
||||||
|
|
||||||
else begin : tag_not_64
|
else begin : tag_not_64
|
||||||
`ifdef RV_ICACHE_ECC
|
`ifdef RV_ICACHE_ECC
|
||||||
`RV_ICACHE_TAG_CELL ic_way_tag (
|
`RV_ICACHE_TAG_CELL ic_way_tag (
|
||||||
.CLK(ic_tag_clk[i]),
|
.CLK(ic_tag_clk[i]),
|
||||||
|
@ -503,7 +503,7 @@ end
|
||||||
|
|
||||||
rvecc_decode ecc_decode (
|
rvecc_decode ecc_decode (
|
||||||
.en(~dec_tlu_core_ecc_disable),
|
.en(~dec_tlu_core_ecc_disable),
|
||||||
.sed_ded ( 1'b1 ), // 1 : if only need detection
|
.sed_ded ( 1'b1 ), // 1 : if only need detection
|
||||||
.din({12'b0,ic_tag_data_raw[i][19:0]}),
|
.din({12'b0,ic_tag_data_raw[i][19:0]}),
|
||||||
.ecc_in({2'b0, ic_tag_data_raw[i][24:20]}),
|
.ecc_in({2'b0, ic_tag_data_raw[i][24:20]}),
|
||||||
.dout(ic_tag_corrected_data_unc[i][31:0]),
|
.dout(ic_tag_corrected_data_unc[i][31:0]),
|
||||||
|
@ -525,27 +525,27 @@ end
|
||||||
assign w_tout[i][31:ICACHE_TAG_HIGH] = ic_tag_data_raw[i][31-ICACHE_TAG_HIGH:0] ;
|
assign w_tout[i][31:ICACHE_TAG_HIGH] = ic_tag_data_raw[i][31-ICACHE_TAG_HIGH:0] ;
|
||||||
assign w_tout[i][32] = ic_tag_data_raw[i][20] ;
|
assign w_tout[i][32] = ic_tag_data_raw[i][20] ;
|
||||||
|
|
||||||
rveven_paritycheck #(32-ICACHE_TAG_HIGH) parcheck(.data_in (w_tout[i][31:ICACHE_TAG_HIGH]),
|
rveven_paritycheck #(32-ICACHE_TAG_HIGH) parcheck(.data_in (w_tout[i][31:ICACHE_TAG_HIGH]),
|
||||||
.parity_in (w_tout[i][32]),
|
.parity_in (w_tout[i][32]),
|
||||||
.parity_err(ic_tag_way_perr[i]));
|
.parity_err(ic_tag_way_perr[i]));
|
||||||
|
|
||||||
`endif
|
`endif
|
||||||
end // block: tag_not_64
|
end // block: tag_not_64
|
||||||
end // block: WAYS
|
end // block: WAYS
|
||||||
|
|
||||||
|
|
||||||
`ifdef RV_ICACHE_ECC
|
`ifdef RV_ICACHE_ECC
|
||||||
assign ictag_debug_rd_data[24:0] = ({25{ic_debug_rd_way_en_ff[0]}} & ic_tag_data_raw[0] ) |
|
assign ictag_debug_rd_data[24:0] = ({25{ic_debug_rd_way_en_ff[0]}} & ic_tag_data_raw[0] ) |
|
||||||
({25{ic_debug_rd_way_en_ff[1]}} & ic_tag_data_raw[1] ) |
|
({25{ic_debug_rd_way_en_ff[1]}} & ic_tag_data_raw[1] ) |
|
||||||
({25{ic_debug_rd_way_en_ff[2]}} & ic_tag_data_raw[2] ) |
|
({25{ic_debug_rd_way_en_ff[2]}} & ic_tag_data_raw[2] ) |
|
||||||
({25{ic_debug_rd_way_en_ff[3]}} & ic_tag_data_raw[3] ) ;
|
({25{ic_debug_rd_way_en_ff[3]}} & ic_tag_data_raw[3] ) ;
|
||||||
|
|
||||||
`else
|
`else
|
||||||
assign ictag_debug_rd_data[20:0] = ({21{ic_debug_rd_way_en_ff[0]}} & ic_tag_data_raw[0] ) |
|
assign ictag_debug_rd_data[20:0] = ({21{ic_debug_rd_way_en_ff[0]}} & ic_tag_data_raw[0] ) |
|
||||||
({21{ic_debug_rd_way_en_ff[1]}} & ic_tag_data_raw[1] ) |
|
({21{ic_debug_rd_way_en_ff[1]}} & ic_tag_data_raw[1] ) |
|
||||||
({21{ic_debug_rd_way_en_ff[2]}} & ic_tag_data_raw[2] ) |
|
({21{ic_debug_rd_way_en_ff[2]}} & ic_tag_data_raw[2] ) |
|
||||||
({21{ic_debug_rd_way_en_ff[3]}} & ic_tag_data_raw[3] ) ;
|
({21{ic_debug_rd_way_en_ff[3]}} & ic_tag_data_raw[3] ) ;
|
||||||
|
|
||||||
`endif
|
`endif
|
||||||
assign ic_rd_hit[0] = (w_tout[0][31:ICACHE_TAG_HIGH] == ic_rw_addr_ff[31:ICACHE_TAG_HIGH]) & ic_tag_valid[0];
|
assign ic_rd_hit[0] = (w_tout[0][31:ICACHE_TAG_HIGH] == ic_rw_addr_ff[31:ICACHE_TAG_HIGH]) & ic_tag_valid[0];
|
||||||
assign ic_rd_hit[1] = (w_tout[1][31:ICACHE_TAG_HIGH] == ic_rw_addr_ff[31:ICACHE_TAG_HIGH]) & ic_tag_valid[1];
|
assign ic_rd_hit[1] = (w_tout[1][31:ICACHE_TAG_HIGH] == ic_rw_addr_ff[31:ICACHE_TAG_HIGH]) & ic_tag_valid[1];
|
||||||
|
|
|
@ -16,10 +16,10 @@
|
||||||
//********************************************************************************
|
//********************************************************************************
|
||||||
|
|
||||||
//********************************************************************************
|
//********************************************************************************
|
||||||
// Icache closely coupled memory --- ICCM
|
// Icache closely coupled memory --- ICCM
|
||||||
//********************************************************************************
|
//********************************************************************************
|
||||||
|
|
||||||
module ifu_iccm_mem
|
module ifu_iccm_mem
|
||||||
import swerv_types::*;
|
import swerv_types::*;
|
||||||
|
|
||||||
(
|
(
|
||||||
|
@ -29,18 +29,18 @@ module ifu_iccm_mem
|
||||||
|
|
||||||
input logic iccm_wren,
|
input logic iccm_wren,
|
||||||
input logic iccm_rden,
|
input logic iccm_rden,
|
||||||
input logic [`RV_ICCM_BITS-1:2] iccm_rw_addr,
|
input logic [`RV_ICCM_BITS-1:2] iccm_rw_addr,
|
||||||
|
|
||||||
input logic [2:0] iccm_wr_size,
|
input logic [2:0] iccm_wr_size,
|
||||||
input logic [77:0] iccm_wr_data,
|
input logic [77:0] iccm_wr_data,
|
||||||
|
|
||||||
|
|
||||||
output logic [155:0] iccm_rd_data,
|
output logic [155:0] iccm_rd_data,
|
||||||
input logic scan_mode
|
input logic scan_mode
|
||||||
|
|
||||||
);
|
);
|
||||||
|
|
||||||
`include "global.h"
|
`include "global.h"
|
||||||
|
|
||||||
|
|
||||||
logic [ICCM_NUM_BANKS/4-1:0] wren_bank;
|
logic [ICCM_NUM_BANKS/4-1:0] wren_bank;
|
||||||
|
@ -60,36 +60,36 @@ module ifu_iccm_mem
|
||||||
logic [ICCM_NUM_BANKS/4-1:0] wren_bank_hi1;
|
logic [ICCM_NUM_BANKS/4-1:0] wren_bank_hi1;
|
||||||
logic [ICCM_NUM_BANKS/4-1:0] wren_bank_lo1;
|
logic [ICCM_NUM_BANKS/4-1:0] wren_bank_lo1;
|
||||||
logic [ICCM_NUM_BANKS/4-1:0] [ICCM_INDEX_BITS-1:0] addr_bank;
|
logic [ICCM_NUM_BANKS/4-1:0] [ICCM_INDEX_BITS-1:0] addr_bank;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
logic [ICCM_NUM_BANKS/4-1:0] [77:0] iccm_bank_dout_hi;
|
logic [ICCM_NUM_BANKS/4-1:0] [77:0] iccm_bank_dout_hi;
|
||||||
logic [ICCM_NUM_BANKS/4-1:0] [77:0] iccm_bank_dout_lo;
|
logic [ICCM_NUM_BANKS/4-1:0] [77:0] iccm_bank_dout_lo;
|
||||||
logic [5:4] iccm_rw_addr_q;
|
logic [5:4] iccm_rw_addr_q;
|
||||||
// assign CLK = clk ;
|
// assign CLK = clk ;
|
||||||
|
|
||||||
|
|
||||||
for (genvar i=0; i<ICCM_NUM_BANKS/4; i++) begin: mem_bank
|
for (genvar i=0; i<ICCM_NUM_BANKS/4; i++) begin: mem_bank
|
||||||
assign wren_bank[i] = iccm_wren & ( (iccm_rw_addr[ICCM_BANK_HI:4] == i) | (ICCM_BANK_BITS == 2));
|
assign wren_bank[i] = iccm_wren & ( (iccm_rw_addr[ICCM_BANK_HI:4] == i) | (ICCM_BANK_BITS == 2));
|
||||||
assign rden_bank[i] = iccm_rden & ( (iccm_rw_addr[ICCM_BANK_HI:4] == i) | (ICCM_BANK_BITS == 2));
|
assign rden_bank[i] = iccm_rden & ( (iccm_rw_addr[ICCM_BANK_HI:4] == i) | (ICCM_BANK_BITS == 2));
|
||||||
assign wren_bank_hi0[i] = wren_bank[i] & iccm_rw_addr[3] & (~iccm_rw_addr[2] | (iccm_wr_size[1:0] == 2'b11));
|
assign wren_bank_hi0[i] = wren_bank[i] & iccm_rw_addr[3] & (~iccm_rw_addr[2] | (iccm_wr_size[1:0] == 2'b11));
|
||||||
assign wren_bank_hi1[i] = wren_bank[i] & iccm_rw_addr[3] & ( iccm_rw_addr[2] | (iccm_wr_size[1:0] == 2'b11));
|
assign wren_bank_hi1[i] = wren_bank[i] & iccm_rw_addr[3] & ( iccm_rw_addr[2] | (iccm_wr_size[1:0] == 2'b11));
|
||||||
assign wren_bank_lo0[i] = wren_bank[i] & ~iccm_rw_addr[3] & (~iccm_rw_addr[2] | (iccm_wr_size[1:0] == 2'b11));
|
assign wren_bank_lo0[i] = wren_bank[i] & ~iccm_rw_addr[3] & (~iccm_rw_addr[2] | (iccm_wr_size[1:0] == 2'b11));
|
||||||
assign wren_bank_lo1[i] = wren_bank[i] & ~iccm_rw_addr[3] & ( iccm_rw_addr[2] | (iccm_wr_size[1:0] == 2'b11));
|
assign wren_bank_lo1[i] = wren_bank[i] & ~iccm_rw_addr[3] & ( iccm_rw_addr[2] | (iccm_wr_size[1:0] == 2'b11));
|
||||||
|
|
||||||
assign iccm_hi0_clken[i] = wren_bank_hi0[i] | (rden_bank[i] | clk_override); // Do not override the writes
|
assign iccm_hi0_clken[i] = wren_bank_hi0[i] | (rden_bank[i] | clk_override); // Do not override the writes
|
||||||
assign iccm_hi1_clken[i] = wren_bank_hi1[i] | (rden_bank[i] | clk_override); // Do not override the writes
|
assign iccm_hi1_clken[i] = wren_bank_hi1[i] | (rden_bank[i] | clk_override); // Do not override the writes
|
||||||
assign iccm_lo0_clken[i] = wren_bank_lo0[i] | (rden_bank[i] | clk_override); // Do not override the writes
|
assign iccm_lo0_clken[i] = wren_bank_lo0[i] | (rden_bank[i] | clk_override); // Do not override the writes
|
||||||
assign iccm_lo1_clken[i] = wren_bank_lo1[i] | (rden_bank[i] | clk_override); // Do not override the writes
|
assign iccm_lo1_clken[i] = wren_bank_lo1[i] | (rden_bank[i] | clk_override); // Do not override the writes
|
||||||
|
|
||||||
rvoclkhdr iccm_hi0_c1_cgc ( .en(iccm_hi0_clken[i]), .l1clk(iccm_hi0_clk[i]), .* );
|
rvoclkhdr iccm_hi0_c1_cgc ( .en(iccm_hi0_clken[i]), .l1clk(iccm_hi0_clk[i]), .* );
|
||||||
rvoclkhdr iccm_hi1_c1_cgc ( .en(iccm_hi1_clken[i]), .l1clk(iccm_hi1_clk[i]), .* );
|
rvoclkhdr iccm_hi1_c1_cgc ( .en(iccm_hi1_clken[i]), .l1clk(iccm_hi1_clk[i]), .* );
|
||||||
rvoclkhdr iccm_lo0_c1_cgc ( .en(iccm_lo0_clken[i]), .l1clk(iccm_lo0_clk[i]), .* );
|
rvoclkhdr iccm_lo0_c1_cgc ( .en(iccm_lo0_clken[i]), .l1clk(iccm_lo0_clk[i]), .* );
|
||||||
rvoclkhdr iccm_lo1_c1_cgc ( .en(iccm_lo1_clken[i]), .l1clk(iccm_lo1_clk[i]), .* );
|
rvoclkhdr iccm_lo1_c1_cgc ( .en(iccm_lo1_clken[i]), .l1clk(iccm_lo1_clk[i]), .* );
|
||||||
|
|
||||||
|
|
||||||
assign addr_bank[i][ICCM_INDEX_BITS-1:0] = iccm_rw_addr[ICCM_BITS-1:(ICCM_BANK_BITS+2)];
|
assign addr_bank[i][ICCM_INDEX_BITS-1:0] = iccm_rw_addr[ICCM_BITS-1:(ICCM_BANK_BITS+2)];
|
||||||
|
|
||||||
`RV_ICCM_DATA_CELL iccm_bank_hi0 (
|
`RV_ICCM_DATA_CELL iccm_bank_hi0 (
|
||||||
// Primary ports
|
// Primary ports
|
||||||
.CLK(iccm_hi0_clk[i]),
|
.CLK(iccm_hi0_clk[i]),
|
||||||
|
@ -122,20 +122,20 @@ module ifu_iccm_mem
|
||||||
.D(iccm_wr_data[77:39]),
|
.D(iccm_wr_data[77:39]),
|
||||||
.Q(iccm_bank_dout_lo[i][77:39])
|
.Q(iccm_bank_dout_lo[i][77:39])
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
end : mem_bank
|
end : mem_bank
|
||||||
|
|
||||||
|
|
||||||
assign iccm_rd_data[155:0] = (ICCM_BANK_BITS == 2) ? {iccm_bank_dout_hi[0][77:0], iccm_bank_dout_lo[0][77:0]} :
|
assign iccm_rd_data[155:0] = (ICCM_BANK_BITS == 2) ? {iccm_bank_dout_hi[0][77:0], iccm_bank_dout_lo[0][77:0]} :
|
||||||
{ iccm_bank_dout_hi[iccm_rw_addr_q[ICCM_BANK_HI:4]][77:0], iccm_bank_dout_lo[iccm_rw_addr_q[ICCM_BANK_HI:4]][77:0] };
|
{ iccm_bank_dout_hi[iccm_rw_addr_q[ICCM_BANK_HI:4]][77:0], iccm_bank_dout_lo[iccm_rw_addr_q[ICCM_BANK_HI:4]][77:0] };
|
||||||
|
|
||||||
|
|
||||||
if (ICCM_BANK_BITS == 2) begin
|
if (ICCM_BANK_BITS == 2) begin
|
||||||
assign iccm_rw_addr_q[5:4] = '0;
|
assign iccm_rw_addr_q[5:4] = '0;
|
||||||
end
|
end
|
||||||
// 8 banks, each bank 8B, we index as 4 banks
|
// 8 banks, each bank 8B, we index as 4 banks
|
||||||
else begin
|
else begin
|
||||||
rvdff #(2) rd_addr_ff (.*, .din(iccm_rw_addr[5:4]), .dout(iccm_rw_addr_q[5:4]) );
|
rvdff #(2) rd_addr_ff (.*, .din(iccm_rw_addr[5:4]), .dout(iccm_rw_addr_q[5:4]) );
|
||||||
end
|
end
|
||||||
endmodule // ifu_iccm_mem
|
endmodule // ifu_iccm_mem
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
// Copyright 2019 Western Digital Corporation or its affiliates.
|
// Copyright 2019 Western Digital Corporation or its affiliates.
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "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 not use this file except in compliance with the License.
|
||||||
// You may obtain a copy of the License at
|
// You may obtain a copy of the License at
|
||||||
//
|
//
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
//
|
//
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
@ -14,7 +14,7 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
//********************************************************************************
|
//********************************************************************************
|
||||||
// ifu_ifc_ctl.sv
|
// ifu_ifc_ctl.sv
|
||||||
// Function: Fetch pipe control
|
// Function: Fetch pipe control
|
||||||
//
|
//
|
||||||
// Comments:
|
// Comments:
|
||||||
|
@ -25,7 +25,7 @@ module ifu_ifc_ctl
|
||||||
input logic clk,
|
input logic clk,
|
||||||
input logic free_clk,
|
input logic free_clk,
|
||||||
input logic active_clk,
|
input logic active_clk,
|
||||||
|
|
||||||
input logic clk_override, // overrides clock gating
|
input logic clk_override, // overrides clock gating
|
||||||
input logic rst_l, // reset enable, from core pin
|
input logic rst_l, // reset enable, from core pin
|
||||||
input logic scan_mode, // scan
|
input logic scan_mode, // scan
|
||||||
|
@ -33,7 +33,7 @@ module ifu_ifc_ctl
|
||||||
input logic ic_hit_f2, // Icache hit
|
input logic ic_hit_f2, // Icache hit
|
||||||
input logic ic_crit_wd_rdy, // Crit word ready to be forwarded
|
input logic ic_crit_wd_rdy, // Crit word ready to be forwarded
|
||||||
input logic ifu_ic_mb_empty, // Miss buffer empty
|
input logic ifu_ic_mb_empty, // Miss buffer empty
|
||||||
|
|
||||||
input logic ifu_fb_consume1, // Aligner consumed 1 fetch buffer
|
input logic ifu_fb_consume1, // Aligner consumed 1 fetch buffer
|
||||||
input logic ifu_fb_consume2, // Aligner consumed 2 fetch buffers
|
input logic ifu_fb_consume2, // Aligner consumed 2 fetch buffers
|
||||||
|
|
||||||
|
@ -66,16 +66,16 @@ module ifu_ifc_ctl
|
||||||
output logic ifc_iccm_access_f1, // fetch to ICCM region
|
output logic ifc_iccm_access_f1, // fetch to ICCM region
|
||||||
output logic ifc_region_acc_fault_f1, // fetch access fault
|
output logic ifc_region_acc_fault_f1, // fetch access fault
|
||||||
output logic ifc_dma_access_ok // fetch is not accessing the ICCM, DMA can proceed
|
output logic ifc_dma_access_ok // fetch is not accessing the ICCM, DMA can proceed
|
||||||
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
logic [31:1] fetch_addr_bf, miss_addr, ifc_fetch_addr_f1_raw;
|
logic [31:1] fetch_addr_bf, miss_addr, ifc_fetch_addr_f1_raw;
|
||||||
logic [31:1] fetch_addr_next;
|
logic [31:1] fetch_addr_next;
|
||||||
logic [31:1] miss_addr_ns;
|
logic [31:1] miss_addr_ns;
|
||||||
logic [4:0] cacheable_select;
|
logic [4:0] cacheable_select;
|
||||||
logic [3:0] fb_write_f1, fb_write_ns;
|
logic [3:0] fb_write_f1, fb_write_ns;
|
||||||
|
|
||||||
logic ifc_fetch_req_bf;
|
logic ifc_fetch_req_bf;
|
||||||
logic overflow_nc;
|
logic overflow_nc;
|
||||||
logic fb_full_f1_ns, fb_full_f1;
|
logic fb_full_f1_ns, fb_full_f1;
|
||||||
|
@ -106,7 +106,7 @@ module ifu_ifc_ctl
|
||||||
|
|
||||||
logic dma_stall;
|
logic dma_stall;
|
||||||
assign dma_stall = ic_dma_active | dma_iccm_stall_any_f;
|
assign dma_stall = ic_dma_active | dma_iccm_stall_any_f;
|
||||||
|
|
||||||
// detect a reset and start fetching the reset vector
|
// detect a reset and start fetching the reset vector
|
||||||
rvdff #(2) reset_ff (.*, .clk(free_clk), .din({1'b1, reset_detect}), .dout({reset_detect, reset_detected}));
|
rvdff #(2) reset_ff (.*, .clk(free_clk), .din({1'b1, reset_detect}), .dout({reset_detect, reset_detected}));
|
||||||
|
|
||||||
|
@ -119,19 +119,19 @@ module ifu_ifc_ctl
|
||||||
|
|
||||||
// For Ifills, we fetch the critical word. Needed for perf and for rom bypass
|
// For Ifills, we fetch the critical word. Needed for perf and for rom bypass
|
||||||
assign fetch_crit_word = ic_crit_wd_rdy_mod & ~ic_crit_wd_rdy_d1 & ~exu_flush_final & ~ic_write_stall;
|
assign fetch_crit_word = ic_crit_wd_rdy_mod & ~ic_crit_wd_rdy_d1 & ~exu_flush_final & ~ic_write_stall;
|
||||||
|
|
||||||
assign missff_en = exu_flush_final | (~ic_hit_f2 & ifc_fetch_req_f2) | ifu_bp_kill_next_f2 | fetch_crit_word_d1 | ifu_bp_kill_next_f2 | (ifc_fetch_req_f2 & ~ifc_fetch_req_f1 & ~fetch_crit_word_d2);
|
assign missff_en = exu_flush_final | (~ic_hit_f2 & ifc_fetch_req_f2) | ifu_bp_kill_next_f2 | fetch_crit_word_d1 | ifu_bp_kill_next_f2 | (ifc_fetch_req_f2 & ~ifc_fetch_req_f1 & ~fetch_crit_word_d2);
|
||||||
assign miss_sel_flush = exu_flush_final & (((wfm | idle) & ~fetch_crit_word_d1) | dma_stall | ic_write_stall);
|
assign miss_sel_flush = exu_flush_final & (((wfm | idle) & ~fetch_crit_word_d1) | dma_stall | ic_write_stall);
|
||||||
assign miss_sel_f2 = ~exu_flush_final & ~ic_hit_f2 & ifc_fetch_req_f2;
|
assign miss_sel_f2 = ~exu_flush_final & ~ic_hit_f2 & ifc_fetch_req_f2;
|
||||||
assign miss_sel_f1 = ~exu_flush_final & ~miss_sel_f2 & ~ifc_fetch_req_f1 & ifc_fetch_req_f2 & ~fetch_crit_word_d2 & ~ifu_bp_kill_next_f2;
|
assign miss_sel_f1 = ~exu_flush_final & ~miss_sel_f2 & ~ifc_fetch_req_f1 & ifc_fetch_req_f2 & ~fetch_crit_word_d2 & ~ifu_bp_kill_next_f2;
|
||||||
assign miss_sel_bf = ~miss_sel_f2 & ~miss_sel_f1 & ~miss_sel_flush;
|
assign miss_sel_bf = ~miss_sel_f2 & ~miss_sel_f1 & ~miss_sel_flush;
|
||||||
|
|
||||||
assign miss_addr_ns[31:1] = ( ({31{miss_sel_flush}} & exu_flush_path_final[31:1]) |
|
assign miss_addr_ns[31:1] = ( ({31{miss_sel_flush}} & exu_flush_path_final[31:1]) |
|
||||||
({31{miss_sel_f2}} & ifc_fetch_addr_f2[31:1]) |
|
({31{miss_sel_f2}} & ifc_fetch_addr_f2[31:1]) |
|
||||||
({31{miss_sel_f1}} & ifc_fetch_addr_f1[31:1]) |
|
({31{miss_sel_f1}} & ifc_fetch_addr_f1[31:1]) |
|
||||||
({31{miss_sel_bf}} & fetch_addr_bf[31:1]));
|
({31{miss_sel_bf}} & fetch_addr_bf[31:1]));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
rvdffe #(31) faddmiss_ff (.*, .en(missff_en), .din(miss_addr_ns[31:1]), .dout(miss_addr[31:1]));
|
rvdffe #(31) faddmiss_ff (.*, .en(missff_en), .din(miss_addr_ns[31:1]), .dout(miss_addr[31:1]));
|
||||||
|
|
||||||
|
@ -146,7 +146,7 @@ module ifu_ifc_ctl
|
||||||
assign sel_btb_addr_bf = ~miss_sel_flush & ifu_bp_kill_next_f2;
|
assign sel_btb_addr_bf = ~miss_sel_flush & ifu_bp_kill_next_f2;
|
||||||
assign sel_next_addr_bf = ~miss_sel_flush & ifc_fetch_req_f1;
|
assign sel_next_addr_bf = ~miss_sel_flush & ifc_fetch_req_f1;
|
||||||
|
|
||||||
|
|
||||||
assign fetch_addr_bf[31:1] = ( ({31{miss_sel_flush}} & exu_flush_path_final[31:1]) | // FLUSH path
|
assign fetch_addr_bf[31:1] = ( ({31{miss_sel_flush}} & exu_flush_path_final[31:1]) | // FLUSH path
|
||||||
({31{sel_miss_addr_bf}} & miss_addr[31:1]) | // MISS path
|
({31{sel_miss_addr_bf}} & miss_addr[31:1]) | // MISS path
|
||||||
({31{sel_btb_addr_bf}} & {ifu_bp_btb_target_f2[31:1]})| // BTB target
|
({31{sel_btb_addr_bf}} & {ifu_bp_btb_target_f2[31:1]})| // BTB target
|
||||||
|
@ -159,14 +159,14 @@ module ifu_ifc_ctl
|
||||||
assign fetch_bf_en = (fetch_ns | fetch_crit_word);
|
assign fetch_bf_en = (fetch_ns | fetch_crit_word);
|
||||||
|
|
||||||
assign miss_f2 = ifc_fetch_req_f2 & ~ic_hit_f2;
|
assign miss_f2 = ifc_fetch_req_f2 & ~ic_hit_f2;
|
||||||
|
|
||||||
assign mb_empty_mod = (ifu_ic_mb_empty | exu_flush_final) & ~dma_stall & ~miss_f2 & ~miss_a;
|
assign mb_empty_mod = (ifu_ic_mb_empty | exu_flush_final) & ~dma_stall & ~miss_f2 & ~miss_a;
|
||||||
|
|
||||||
// Halt flushes and takes us to IDLE
|
// Halt flushes and takes us to IDLE
|
||||||
assign goto_idle = exu_flush_final & dec_tlu_flush_noredir_wb;
|
assign goto_idle = exu_flush_final & dec_tlu_flush_noredir_wb;
|
||||||
// If we're in IDLE, and we get a flush, goto FETCH
|
// If we're in IDLE, and we get a flush, goto FETCH
|
||||||
assign leave_idle = exu_flush_final & ~dec_tlu_flush_noredir_wb & idle;
|
assign leave_idle = exu_flush_final & ~dec_tlu_flush_noredir_wb & idle;
|
||||||
|
|
||||||
//.i 7
|
//.i 7
|
||||||
//.o 2
|
//.o 2
|
||||||
//.ilb state[1] state[0] reset_delayed miss_f2 mb_empty_mod goto_idle leave_idle
|
//.ilb state[1] state[0] reset_delayed miss_f2 mb_empty_mod goto_idle leave_idle
|
||||||
|
@ -178,26 +178,26 @@ module ifu_ifc_ctl
|
||||||
//-- 0--1- 00
|
//-- 0--1- 00
|
||||||
//00 0--00 00
|
//00 0--00 00
|
||||||
//00 0--01 01
|
//00 0--01 01
|
||||||
//
|
//
|
||||||
//01 01-0- 11
|
//01 01-0- 11
|
||||||
//01 00-0- 01
|
//01 00-0- 01
|
||||||
//
|
//
|
||||||
//11 0-10- 01
|
//11 0-10- 01
|
||||||
//11 0-00- 11
|
//11 0-00- 11
|
||||||
|
|
||||||
assign next_state[1] = (~state[1] & state[0] & ~reset_delayed & miss_f2 & ~goto_idle) |
|
assign next_state[1] = (~state[1] & state[0] & ~reset_delayed & miss_f2 & ~goto_idle) |
|
||||||
(state[1] & ~reset_delayed & ~mb_empty_mod & ~goto_idle);
|
(state[1] & ~reset_delayed & ~mb_empty_mod & ~goto_idle);
|
||||||
|
|
||||||
assign next_state[0] = (~goto_idle & leave_idle) | (state[0] & ~goto_idle) |
|
assign next_state[0] = (~goto_idle & leave_idle) | (state[0] & ~goto_idle) |
|
||||||
(reset_delayed);
|
(reset_delayed);
|
||||||
|
|
||||||
assign flush_fb = exu_flush_final;
|
assign flush_fb = exu_flush_final;
|
||||||
|
|
||||||
// model fb write logic to mass balance the fetch buffers
|
// model fb write logic to mass balance the fetch buffers
|
||||||
assign fb_right = (~ifu_fb_consume1 & ~ifu_fb_consume2 & miss_f2) | // F2 cache miss, repair mass balance
|
assign fb_right = (~ifu_fb_consume1 & ~ifu_fb_consume2 & miss_f2) | // F2 cache miss, repair mass balance
|
||||||
( ifu_fb_consume1 & ~ifu_fb_consume2 & ~ifc_fetch_req_f1 & ~miss_f2) | // Consumed and no new fetch
|
( ifu_fb_consume1 & ~ifu_fb_consume2 & ~ifc_fetch_req_f1 & ~miss_f2) | // Consumed and no new fetch
|
||||||
(ifu_fb_consume2 & ifc_fetch_req_f1 & ~miss_f2); // Consumed 2 and new fetch
|
(ifu_fb_consume2 & ifc_fetch_req_f1 & ~miss_f2); // Consumed 2 and new fetch
|
||||||
|
|
||||||
|
|
||||||
assign fb_right2 = (ifu_fb_consume1 & ~ifu_fb_consume2 & miss_f2) | // consume 1 and miss 1
|
assign fb_right2 = (ifu_fb_consume1 & ~ifu_fb_consume2 & miss_f2) | // consume 1 and miss 1
|
||||||
(ifu_fb_consume2 & ~ifc_fetch_req_f1); // Consumed 2 and no new fetch
|
(ifu_fb_consume2 & ~ifc_fetch_req_f1); // Consumed 2 and no new fetch
|
||||||
|
@ -205,7 +205,7 @@ module ifu_ifc_ctl
|
||||||
assign fb_right3 = (ifu_fb_consume2 & miss_f2); // consume 2 and miss
|
assign fb_right3 = (ifu_fb_consume2 & miss_f2); // consume 2 and miss
|
||||||
|
|
||||||
assign fb_left = ifc_fetch_req_f1 & ~(ifu_fb_consume1 | ifu_fb_consume2) & ~miss_f2;
|
assign fb_left = ifc_fetch_req_f1 & ~(ifu_fb_consume1 | ifu_fb_consume2) & ~miss_f2;
|
||||||
|
|
||||||
assign fb_write_ns[3:0] = ( ({4{(flush_fb & ~ifc_fetch_req_f1)}} & 4'b0001) |
|
assign fb_write_ns[3:0] = ( ({4{(flush_fb & ~ifc_fetch_req_f1)}} & 4'b0001) |
|
||||||
({4{(flush_fb & ifc_fetch_req_f1)}} & 4'b0010) |
|
({4{(flush_fb & ifc_fetch_req_f1)}} & 4'b0010) |
|
||||||
({4{~flush_fb & fb_right }} & {1'b0, fb_write_f1[3:1]}) |
|
({4{~flush_fb & fb_right }} & {1'b0, fb_write_f1[3:1]}) |
|
||||||
|
@ -213,28 +213,28 @@ module ifu_ifc_ctl
|
||||||
({4{~flush_fb & fb_right3}} & {3'b0, fb_write_f1[3]} ) |
|
({4{~flush_fb & fb_right3}} & {3'b0, fb_write_f1[3]} ) |
|
||||||
({4{~flush_fb & fb_left }} & {fb_write_f1[2:0], 1'b0}) |
|
({4{~flush_fb & fb_left }} & {fb_write_f1[2:0], 1'b0}) |
|
||||||
({4{~flush_fb & ~fb_right & ~fb_right2 & ~fb_left & ~fb_right3}} & fb_write_f1[3:0]));
|
({4{~flush_fb & ~fb_right & ~fb_right2 & ~fb_left & ~fb_right3}} & fb_write_f1[3:0]));
|
||||||
|
|
||||||
|
|
||||||
assign fb_full_f1_ns = fb_write_ns[3];
|
assign fb_full_f1_ns = fb_write_ns[3];
|
||||||
|
|
||||||
assign idle = state[1:0] == IDLE;
|
assign idle = state[1:0] == IDLE;
|
||||||
assign wfm = state[1:0] == WFM;
|
assign wfm = state[1:0] == WFM;
|
||||||
assign fetch_ns = next_state[1:0] == FETCH;
|
assign fetch_ns = next_state[1:0] == FETCH;
|
||||||
|
|
||||||
rvdff #(2) fsm_ff (.*, .clk(active_clk), .din({next_state[1:0]}), .dout({state[1:0]}));
|
rvdff #(2) fsm_ff (.*, .clk(active_clk), .din({next_state[1:0]}), .dout({state[1:0]}));
|
||||||
rvdff #(5) fbwrite_ff (.*, .clk(active_clk), .din({fb_full_f1_ns, fb_write_ns[3:0]}), .dout({fb_full_f1, fb_write_f1[3:0]}));
|
rvdff #(5) fbwrite_ff (.*, .clk(active_clk), .din({fb_full_f1_ns, fb_write_ns[3:0]}), .dout({fb_full_f1, fb_write_f1[3:0]}));
|
||||||
|
|
||||||
assign ifu_pmu_fetch_stall = wfm |
|
assign ifu_pmu_fetch_stall = wfm |
|
||||||
(ifc_fetch_req_f1_raw &
|
(ifc_fetch_req_f1_raw &
|
||||||
( (fb_full_f1 & ~(ifu_fb_consume2 | ifu_fb_consume1 | exu_flush_final)) |
|
( (fb_full_f1 & ~(ifu_fb_consume2 | ifu_fb_consume1 | exu_flush_final)) |
|
||||||
dma_stall));
|
dma_stall));
|
||||||
// BTB hit kills this fetch
|
// BTB hit kills this fetch
|
||||||
assign ifc_fetch_req_f1 = ( ifc_fetch_req_f1_raw &
|
assign ifc_fetch_req_f1 = ( ifc_fetch_req_f1_raw &
|
||||||
~ifu_bp_kill_next_f2 &
|
~ifu_bp_kill_next_f2 &
|
||||||
~(fb_full_f1 & ~(ifu_fb_consume2 | ifu_fb_consume1 | exu_flush_final)) &
|
~(fb_full_f1 & ~(ifu_fb_consume2 | ifu_fb_consume1 | exu_flush_final)) &
|
||||||
~dma_stall &
|
~dma_stall &
|
||||||
~ic_write_stall &
|
~ic_write_stall &
|
||||||
~dec_tlu_flush_noredir_wb );
|
~dec_tlu_flush_noredir_wb );
|
||||||
|
|
||||||
// kill F2 request if we flush or if the prior fetch missed the cache/mem
|
// kill F2 request if we flush or if the prior fetch missed the cache/mem
|
||||||
assign fetch_req_f2_ns = ifc_fetch_req_f1 & ~miss_f2;
|
assign fetch_req_f2_ns = ifc_fetch_req_f1 & ~miss_f2;
|
||||||
|
@ -242,34 +242,34 @@ module ifu_ifc_ctl
|
||||||
rvdff #(2) req_ff (.*, .clk(active_clk), .din({ifc_fetch_req_bf, fetch_req_f2_ns}), .dout({ifc_fetch_req_f1_raw, ifc_fetch_req_f2_raw}));
|
rvdff #(2) req_ff (.*, .clk(active_clk), .din({ifc_fetch_req_bf, fetch_req_f2_ns}), .dout({ifc_fetch_req_f1_raw, ifc_fetch_req_f2_raw}));
|
||||||
|
|
||||||
assign ifc_fetch_req_f2 = ifc_fetch_req_f2_raw & ~exu_flush_final;
|
assign ifc_fetch_req_f2 = ifc_fetch_req_f2_raw & ~exu_flush_final;
|
||||||
|
|
||||||
rvdffe #(31) faddrf1_ff (.*, .en(fetch_bf_en), .din(fetch_addr_bf[31:1]), .dout(ifc_fetch_addr_f1_raw[31:1]));
|
rvdffe #(31) faddrf1_ff (.*, .en(fetch_bf_en), .din(fetch_addr_bf[31:1]), .dout(ifc_fetch_addr_f1_raw[31:1]));
|
||||||
rvdff #(31) faddrf2_ff (.*, .clk(ifc_f2_clk), .din(ifc_fetch_addr_f1[31:1]), .dout(ifc_fetch_addr_f2[31:1]));
|
rvdff #(31) faddrf2_ff (.*, .clk(ifc_f2_clk), .din(ifc_fetch_addr_f1[31:1]), .dout(ifc_fetch_addr_f2[31:1]));
|
||||||
|
|
||||||
assign ifc_fetch_addr_f1[31:1] = ( ({31{exu_flush_final}} & exu_flush_path_final[31:1]) |
|
assign ifc_fetch_addr_f1[31:1] = ( ({31{exu_flush_final}} & exu_flush_path_final[31:1]) |
|
||||||
({31{~exu_flush_final}} & ifc_fetch_addr_f1_raw[31:1]));
|
({31{~exu_flush_final}} & ifc_fetch_addr_f1_raw[31:1]));
|
||||||
|
|
||||||
rvdff #(3) iccrit_ff (.*, .clk(active_clk), .din({ic_crit_wd_rdy_mod, fetch_crit_word, fetch_crit_word_d1}),
|
rvdff #(3) iccrit_ff (.*, .clk(active_clk), .din({ic_crit_wd_rdy_mod, fetch_crit_word, fetch_crit_word_d1}),
|
||||||
.dout({ic_crit_wd_rdy_d1, fetch_crit_word_d1, fetch_crit_word_d2}));
|
.dout({ic_crit_wd_rdy_d1, fetch_crit_word_d1, fetch_crit_word_d2}));
|
||||||
|
|
||||||
`ifdef RV_ICCM_ENABLE
|
`ifdef RV_ICCM_ENABLE
|
||||||
logic iccm_acc_in_region_f1;
|
logic iccm_acc_in_region_f1;
|
||||||
logic iccm_acc_in_range_f1;
|
logic iccm_acc_in_range_f1;
|
||||||
rvrangecheck #( .CCM_SADR (`RV_ICCM_SADR),
|
rvrangecheck #( .CCM_SADR (`RV_ICCM_SADR),
|
||||||
.CCM_SIZE (`RV_ICCM_SIZE) ) iccm_rangecheck (
|
.CCM_SIZE (`RV_ICCM_SIZE) ) iccm_rangecheck (
|
||||||
.addr ({ifc_fetch_addr_f1[31:1],1'b0}) ,
|
.addr ({ifc_fetch_addr_f1[31:1],1'b0}) ,
|
||||||
.in_range (iccm_acc_in_range_f1) ,
|
.in_range (iccm_acc_in_range_f1) ,
|
||||||
.in_region(iccm_acc_in_region_f1)
|
.in_region(iccm_acc_in_region_f1)
|
||||||
);
|
);
|
||||||
|
|
||||||
assign ifc_iccm_access_f1 = iccm_acc_in_range_f1 ;
|
assign ifc_iccm_access_f1 = iccm_acc_in_range_f1 ;
|
||||||
|
|
||||||
assign ifc_dma_access_ok = ( (~ifc_iccm_access_f1 |
|
assign ifc_dma_access_ok = ( (~ifc_iccm_access_f1 |
|
||||||
(fb_full_f1 & ~(ifu_fb_consume2 | ifu_fb_consume1)) |
|
(fb_full_f1 & ~(ifu_fb_consume2 | ifu_fb_consume1)) |
|
||||||
wfm |
|
wfm |
|
||||||
idle ) & ~exu_flush_final) |
|
idle ) & ~exu_flush_final) |
|
||||||
dma_iccm_stall_any_f;
|
dma_iccm_stall_any_f;
|
||||||
|
|
||||||
assign ifc_region_acc_fault_f1 = ~iccm_acc_in_range_f1 & iccm_acc_in_region_f1 ;
|
assign ifc_region_acc_fault_f1 = ~iccm_acc_in_range_f1 & iccm_acc_in_region_f1 ;
|
||||||
`else
|
`else
|
||||||
assign ifc_iccm_access_f1 = 1'b0 ;
|
assign ifc_iccm_access_f1 = 1'b0 ;
|
||||||
|
@ -279,6 +279,6 @@ module ifu_ifc_ctl
|
||||||
|
|
||||||
assign cacheable_select[4:0] = {ifc_fetch_addr_f1[31:28] , 1'b0 } ;
|
assign cacheable_select[4:0] = {ifc_fetch_addr_f1[31:28] , 1'b0 } ;
|
||||||
assign ifc_fetch_uncacheable_f1 = ~dec_tlu_mrac_ff[cacheable_select] ; // bit 0 of each region description is the cacheable bit
|
assign ifc_fetch_uncacheable_f1 = ~dec_tlu_mrac_ff[cacheable_select] ; // bit 0 of each region description is the cacheable bit
|
||||||
|
|
||||||
endmodule // ifu_ifc_ctl
|
endmodule // ifu_ifc_ctl
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,12 +1,12 @@
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
// Copyright 2019 Western Digital Corporation or its affiliates.
|
// Copyright 2019 Western Digital Corporation or its affiliates.
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "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 not use this file except in compliance with the License.
|
||||||
// You may obtain a copy of the License at
|
// You may obtain a copy of the License at
|
||||||
//
|
//
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
//
|
//
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
// Copyright 2019 Western Digital Corporation or its affiliates.
|
// Copyright 2019 Western Digital Corporation or its affiliates.
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "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 not use this file except in compliance with the License.
|
||||||
// You may obtain a copy of the License at
|
// You may obtain a copy of the License at
|
||||||
//
|
//
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
//
|
//
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// 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 ICCM_BANK_HI = 4 + (`RV_ICCM_BANK_BITS/4);
|
||||||
|
|
||||||
localparam ICACHE_TAG_HIGH = `RV_ICACHE_TAG_HIGH;
|
localparam ICACHE_TAG_HIGH = `RV_ICACHE_TAG_HIGH;
|
||||||
localparam ICACHE_TAG_LOW = `RV_ICACHE_TAG_LOW;
|
localparam ICACHE_TAG_LOW = `RV_ICACHE_TAG_LOW;
|
||||||
localparam ICACHE_IC_DEPTH = `RV_ICACHE_IC_DEPTH;
|
localparam ICACHE_IC_DEPTH = `RV_ICACHE_IC_DEPTH;
|
||||||
localparam ICACHE_TAG_DEPTH = `RV_ICACHE_TAG_DEPTH;
|
localparam ICACHE_TAG_DEPTH = `RV_ICACHE_TAG_DEPTH;
|
||||||
|
|
||||||
localparam LSU_BUS_TAG = `RV_LSU_BUS_TAG;
|
localparam LSU_BUS_TAG = `RV_LSU_BUS_TAG;
|
||||||
localparam DMA_BUS_TAG = `RV_DMA_BUS_TAG;
|
localparam DMA_BUS_TAG = `RV_DMA_BUS_TAG;
|
||||||
localparam SB_BUS_TAG = `RV_SB_BUS_TAG;
|
localparam SB_BUS_TAG = `RV_SB_BUS_TAG;
|
||||||
|
|
||||||
localparam IFU_BUS_TAG = `RV_IFU_BUS_TAG;
|
localparam IFU_BUS_TAG = `RV_IFU_BUS_TAG;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
// Copyright 2019 Western Digital Corporation or its affiliates.
|
// Copyright 2019 Western Digital Corporation or its affiliates.
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "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 not use this file except in compliance with the License.
|
||||||
// You may obtain a copy of the License at
|
// You may obtain a copy of the License at
|
||||||
//
|
//
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
//
|
//
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
@ -18,18 +18,18 @@ package swerv_types;
|
||||||
typedef struct packed {
|
typedef struct packed {
|
||||||
logic [2:0] trace_rv_i_valid_ip;
|
logic [2:0] trace_rv_i_valid_ip;
|
||||||
logic [95:0] trace_rv_i_insn_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 [2:0] trace_rv_i_exception_ip;
|
||||||
logic [4:0] trace_rv_i_ecause_ip;
|
logic [4:0] trace_rv_i_ecause_ip;
|
||||||
logic [2:0] trace_rv_i_interrupt_ip;
|
logic [2:0] trace_rv_i_interrupt_ip;
|
||||||
logic [31:0] trace_rv_i_tval_ip;
|
logic [31:0] trace_rv_i_tval_ip;
|
||||||
} trace_pkt_t;
|
} trace_pkt_t;
|
||||||
|
|
||||||
|
|
||||||
typedef enum logic [3:0] {
|
typedef enum logic [3:0] {
|
||||||
NULL = 4'b0000,
|
NULL = 4'b0000,
|
||||||
MUL = 4'b0001,
|
MUL = 4'b0001,
|
||||||
LOAD = 4'b0010,
|
LOAD = 4'b0010,
|
||||||
STORE = 4'b0011,
|
STORE = 4'b0011,
|
||||||
ALU = 4'b0100,
|
ALU = 4'b0100,
|
||||||
CSRREAD = 4'b0101,
|
CSRREAD = 4'b0101,
|
||||||
|
@ -45,7 +45,7 @@ typedef enum logic [3:0] {
|
||||||
} inst_t;
|
} inst_t;
|
||||||
|
|
||||||
typedef struct packed {
|
typedef struct packed {
|
||||||
`ifdef RV_ICACHE_ECC
|
`ifdef RV_ICACHE_ECC
|
||||||
logic [39:0] ecc;
|
logic [39:0] ecc;
|
||||||
`else
|
`else
|
||||||
logic [7:0] parity;
|
logic [7:0] parity;
|
||||||
|
@ -103,15 +103,15 @@ typedef struct packed {
|
||||||
} br_tlu_pkt_t;
|
} br_tlu_pkt_t;
|
||||||
|
|
||||||
typedef struct packed {
|
typedef struct packed {
|
||||||
logic misp;
|
logic misp;
|
||||||
logic ataken;
|
logic ataken;
|
||||||
logic boffset;
|
logic boffset;
|
||||||
logic pc4;
|
logic pc4;
|
||||||
logic [1:0] hist;
|
logic [1:0] hist;
|
||||||
logic [11:0] toffset;
|
logic [11:0] toffset;
|
||||||
logic [`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO] index;
|
logic [`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO] index;
|
||||||
logic [1:0] bank;
|
logic [1:0] bank;
|
||||||
logic valid;
|
logic valid;
|
||||||
logic br_error;
|
logic br_error;
|
||||||
logic br_start_error;
|
logic br_start_error;
|
||||||
logic [31:1] prett;
|
logic [31:1] prett;
|
||||||
|
@ -130,7 +130,7 @@ typedef struct packed {
|
||||||
typedef struct packed {
|
typedef struct packed {
|
||||||
logic legal;
|
logic legal;
|
||||||
logic icaf;
|
logic icaf;
|
||||||
logic icaf_f1;
|
logic icaf_f1;
|
||||||
logic perr;
|
logic perr;
|
||||||
logic sbecc;
|
logic sbecc;
|
||||||
logic fence_i;
|
logic fence_i;
|
||||||
|
@ -146,7 +146,7 @@ typedef struct packed {
|
||||||
|
|
||||||
typedef struct packed {
|
typedef struct packed {
|
||||||
logic [4:0] i0rd;
|
logic [4:0] i0rd;
|
||||||
logic i0mul;
|
logic i0mul;
|
||||||
logic i0load;
|
logic i0load;
|
||||||
logic i0store;
|
logic i0store;
|
||||||
logic i0div;
|
logic i0div;
|
||||||
|
@ -154,11 +154,11 @@ typedef struct packed {
|
||||||
logic i0valid;
|
logic i0valid;
|
||||||
logic i0secondary;
|
logic i0secondary;
|
||||||
logic [1:0] i0rs1bype2;
|
logic [1:0] i0rs1bype2;
|
||||||
logic [1:0] i0rs2bype2;
|
logic [1:0] i0rs2bype2;
|
||||||
logic [3:0] i0rs1bype3;
|
logic [3:0] i0rs1bype3;
|
||||||
logic [3:0] i0rs2bype3;
|
logic [3:0] i0rs2bype3;
|
||||||
logic [4:0] i1rd;
|
logic [4:0] i1rd;
|
||||||
logic i1mul;
|
logic i1mul;
|
||||||
logic i1load;
|
logic i1load;
|
||||||
logic i1store;
|
logic i1store;
|
||||||
logic i1v;
|
logic i1v;
|
||||||
|
@ -166,11 +166,11 @@ typedef struct packed {
|
||||||
logic csrwen;
|
logic csrwen;
|
||||||
logic csrwonly;
|
logic csrwonly;
|
||||||
logic [11:0] csrwaddr;
|
logic [11:0] csrwaddr;
|
||||||
logic i1secondary;
|
logic i1secondary;
|
||||||
logic [1:0] i1rs1bype2;
|
logic [1:0] i1rs1bype2;
|
||||||
logic [1:0] i1rs2bype2;
|
logic [1:0] i1rs2bype2;
|
||||||
logic [6:0] i1rs1bype3;
|
logic [6:0] i1rs1bype3;
|
||||||
logic [6:0] i1rs2bype3;
|
logic [6:0] i1rs2bype3;
|
||||||
} dest_pkt_t;
|
} dest_pkt_t;
|
||||||
|
|
||||||
typedef struct packed {
|
typedef struct packed {
|
||||||
|
@ -192,7 +192,7 @@ typedef struct packed {
|
||||||
logic land;
|
logic land;
|
||||||
logic lor;
|
logic lor;
|
||||||
logic lxor;
|
logic lxor;
|
||||||
logic sll;
|
logic sll;
|
||||||
logic srl;
|
logic srl;
|
||||||
logic sra;
|
logic sra;
|
||||||
logic beq;
|
logic beq;
|
||||||
|
@ -230,13 +230,13 @@ typedef struct packed {
|
||||||
} lsu_pkt_t;
|
} lsu_pkt_t;
|
||||||
|
|
||||||
typedef struct packed {
|
typedef struct packed {
|
||||||
logic exc_valid;
|
logic exc_valid;
|
||||||
logic single_ecc_error;
|
logic single_ecc_error;
|
||||||
logic inst_type; //0: Load, 1: Store
|
logic inst_type; //0: Load, 1: Store
|
||||||
logic inst_pipe; //0: i0, 1: i1
|
logic inst_pipe; //0: i0, 1: i1
|
||||||
logic dma_valid;
|
logic dma_valid;
|
||||||
logic exc_type; //0: MisAligned, 1: Access Fault
|
logic exc_type; //0: MisAligned, 1: Access Fault
|
||||||
logic [31:0] addr;
|
logic [31:0] addr;
|
||||||
} lsu_error_pkt_t;
|
} lsu_error_pkt_t;
|
||||||
|
|
||||||
typedef struct packed {
|
typedef struct packed {
|
||||||
|
@ -276,7 +276,7 @@ typedef struct packed {
|
||||||
logic csr_write;
|
logic csr_write;
|
||||||
logic csr_imm;
|
logic csr_imm;
|
||||||
logic presync;
|
logic presync;
|
||||||
logic postsync;
|
logic postsync;
|
||||||
logic ebreak;
|
logic ebreak;
|
||||||
logic ecall;
|
logic ecall;
|
||||||
logic mret;
|
logic mret;
|
||||||
|
@ -299,7 +299,7 @@ typedef struct packed {
|
||||||
logic rs2_sign;
|
logic rs2_sign;
|
||||||
logic low;
|
logic low;
|
||||||
logic load_mul_rs1_bypass_e1;
|
logic load_mul_rs1_bypass_e1;
|
||||||
logic load_mul_rs2_bypass_e1;
|
logic load_mul_rs2_bypass_e1;
|
||||||
} mul_pkt_t;
|
} mul_pkt_t;
|
||||||
|
|
||||||
typedef struct packed {
|
typedef struct packed {
|
||||||
|
@ -316,12 +316,12 @@ typedef struct packed {
|
||||||
logic load;
|
logic load;
|
||||||
logic execute;
|
logic execute;
|
||||||
logic m;
|
logic m;
|
||||||
logic [31:0] tdata2;
|
logic [31:0] tdata2;
|
||||||
} trigger_pkt_t;
|
} trigger_pkt_t;
|
||||||
|
|
||||||
|
|
||||||
typedef struct packed {
|
typedef struct packed {
|
||||||
`ifdef RV_ICACHE_ECC
|
`ifdef RV_ICACHE_ECC
|
||||||
logic [41:0] icache_wrdata; // {dicad0[31:0], dicad1[1:0]}
|
logic [41:0] icache_wrdata; // {dicad0[31:0], dicad1[1:0]}
|
||||||
`else
|
`else
|
||||||
logic [33:0] icache_wrdata; // {dicad0[31:0], dicad1[1:0]}
|
logic [33:0] icache_wrdata; // {dicad0[31:0], dicad1[1:0]}
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
// Copyright 2019 Western Digital Corporation or its affiliates.
|
// Copyright 2019 Western Digital Corporation or its affiliates.
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "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 not use this file except in compliance with the License.
|
||||||
// You may obtain a copy of the License at
|
// You may obtain a copy of the License at
|
||||||
//
|
//
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
//
|
//
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
@ -15,8 +15,8 @@
|
||||||
//********************************************************************************
|
//********************************************************************************
|
||||||
// $Id$
|
// $Id$
|
||||||
//
|
//
|
||||||
// Owner:
|
// Owner:
|
||||||
// Function: AHB to AXI4 Bridge
|
// Function: AHB to AXI4 Bridge
|
||||||
// Comments:
|
// Comments:
|
||||||
//
|
//
|
||||||
//********************************************************************************
|
//********************************************************************************
|
||||||
|
@ -24,11 +24,11 @@ module ahb_to_axi4 #(parameter TAG = 1) (
|
||||||
|
|
||||||
input clk,
|
input clk,
|
||||||
input rst_l,
|
input rst_l,
|
||||||
input scan_mode,
|
input scan_mode,
|
||||||
input bus_clk_en,
|
input bus_clk_en,
|
||||||
input clk_override,
|
input clk_override,
|
||||||
|
|
||||||
// AXI signals
|
// AXI signals
|
||||||
// AXI Write Channels
|
// AXI Write Channels
|
||||||
output logic axi_awvalid,
|
output logic axi_awvalid,
|
||||||
input logic axi_awready,
|
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_awsize,
|
||||||
output logic [2:0] axi_awprot,
|
output logic [2:0] axi_awprot,
|
||||||
output logic [7:0] axi_awlen,
|
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,
|
input logic axi_wready,
|
||||||
output logic [63:0] axi_wdata,
|
output logic [63:0] axi_wdata,
|
||||||
output logic [7:0] axi_wstrb,
|
output logic [7:0] axi_wstrb,
|
||||||
|
@ -48,25 +48,25 @@ module ahb_to_axi4 #(parameter TAG = 1) (
|
||||||
input logic axi_bvalid,
|
input logic axi_bvalid,
|
||||||
output logic axi_bready,
|
output logic axi_bready,
|
||||||
input logic [1:0] axi_bresp,
|
input logic [1:0] axi_bresp,
|
||||||
input logic [TAG-1:0] axi_bid,
|
input logic [TAG-1:0] axi_bid,
|
||||||
|
|
||||||
// AXI Read Channels
|
// AXI Read Channels
|
||||||
output logic axi_arvalid,
|
output logic axi_arvalid,
|
||||||
input logic axi_arready,
|
input logic axi_arready,
|
||||||
output logic [TAG-1:0] axi_arid,
|
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_arsize,
|
||||||
output logic [2:0] axi_arprot,
|
output logic [2:0] axi_arprot,
|
||||||
output logic [7:0] axi_arlen,
|
output logic [7:0] axi_arlen,
|
||||||
output logic [1:0] axi_arburst,
|
output logic [1:0] axi_arburst,
|
||||||
|
|
||||||
input logic axi_rvalid,
|
input logic axi_rvalid,
|
||||||
output logic axi_rready,
|
output logic axi_rready,
|
||||||
input logic [TAG-1:0] axi_rid,
|
input logic [TAG-1:0] axi_rid,
|
||||||
input logic [63:0] axi_rdata,
|
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 [31:0] ahb_haddr, // ahb bus address
|
||||||
input logic [2:0] ahb_hburst, // tied to 0
|
input logic [2:0] ahb_hburst, // tied to 0
|
||||||
input logic ahb_hmastlock, // 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 ahb_hwrite, // ahb bus write
|
||||||
input logic [63:0] ahb_hwdata, // ahb bus write data
|
input logic [63:0] ahb_hwdata, // ahb bus write data
|
||||||
input logic ahb_hsel, // this slave was selected
|
input logic ahb_hsel, // this slave was selected
|
||||||
input logic ahb_hreadyin, // previous hready was accepted or not
|
input logic ahb_hreadyin, // previous hready was accepted or not
|
||||||
|
|
||||||
output logic [63:0] ahb_hrdata, // ahb bus read data
|
output logic [63:0] ahb_hrdata, // ahb bus read data
|
||||||
output logic ahb_hreadyout, // slave ready to accept transaction
|
output logic ahb_hreadyout, // slave ready to accept transaction
|
||||||
output logic ahb_hresp // slave response (high indicates erro)
|
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;
|
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
|
WR = 2'b01, // Write Command recieved
|
||||||
RD = 2'b10, // Read Command recieved
|
RD = 2'b10, // Read Command recieved
|
||||||
PEND = 2'b11 // Waiting on Read Data from core
|
PEND = 2'b11 // Waiting on Read Data from core
|
||||||
} state_t;
|
} state_t;
|
||||||
state_t buf_state, buf_nxtstate;
|
state_t buf_state, buf_nxtstate;
|
||||||
logic buf_state_en;
|
logic buf_state_en;
|
||||||
|
|
||||||
// Buffer signals (one entry buffer)
|
// Buffer signals (one entry buffer)
|
||||||
logic buf_read_error_in, buf_read_error;
|
logic buf_read_error_in, buf_read_error;
|
||||||
logic [63:0] buf_rdata;
|
logic [63:0] buf_rdata;
|
||||||
|
|
||||||
logic ahb_hready;
|
logic ahb_hready;
|
||||||
logic ahb_hready_q;
|
logic ahb_hready_q;
|
||||||
logic [1:0] ahb_htrans_in, ahb_htrans_q;
|
logic [1:0] ahb_htrans_in, ahb_htrans_q;
|
||||||
logic [2:0] ahb_hsize_q;
|
logic [2:0] ahb_hsize_q;
|
||||||
logic ahb_hwrite_q;
|
logic ahb_hwrite_q;
|
||||||
logic [31:0] ahb_haddr_q;
|
logic [31:0] ahb_haddr_q;
|
||||||
logic [63:0] ahb_hwdata_q;
|
logic [63:0] ahb_hwdata_q;
|
||||||
logic ahb_hresp_q;
|
logic ahb_hresp_q;
|
||||||
|
|
||||||
//Miscellaneous signals
|
//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;
|
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
|
// signals needed for the read data coming back from the core and to block any further commands as AHB is a blocking bus
|
||||||
logic buf_rdata_en;
|
logic buf_rdata_en;
|
||||||
|
@ -125,21 +125,21 @@ module ahb_to_axi4 #(parameter TAG = 1) (
|
||||||
logic [63:0] cmdbuf_wdata;
|
logic [63:0] cmdbuf_wdata;
|
||||||
|
|
||||||
logic bus_clk;
|
logic bus_clk;
|
||||||
|
|
||||||
// FSM to control the bus states and when to block the hready and load the command buffer
|
// FSM to control the bus states and when to block the hready and load the command buffer
|
||||||
always_comb begin
|
always_comb begin
|
||||||
buf_nxtstate = IDLE;
|
buf_nxtstate = IDLE;
|
||||||
buf_state_en = 1'b0;
|
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
|
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
|
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)
|
case (buf_state)
|
||||||
IDLE: begin // No commands recieved
|
IDLE: begin // No commands recieved
|
||||||
buf_nxtstate = ahb_hwrite ? WR : RD;
|
buf_nxtstate = ahb_hwrite ? WR : RD;
|
||||||
buf_state_en = ahb_hready & ahb_htrans[1] & ahb_hsel; // only transition on a valid hrtans
|
buf_state_en = ahb_hready & ahb_htrans[1] & ahb_hsel; // only transition on a valid hrtans
|
||||||
end
|
end
|
||||||
WR: begin // Write command recieved last cycle
|
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_nxtstate = (ahb_hresp | (ahb_htrans[1:0] == 2'b0) | ~ahb_hsel) ? IDLE : (ahb_hwrite ? WR : RD);
|
||||||
buf_state_en = (~cmdbuf_full | ahb_hresp) ;
|
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.
|
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
|
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
|
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
|
cmdbuf_wr_en = ~ahb_hresp & ~cmdbuf_full; // send command only when no error
|
||||||
end
|
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_nxtstate = IDLE; // go back for next command and present data next cycle
|
||||||
buf_state_en = axi_rvalid & ~cmdbuf_write; // read data is back
|
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_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 )
|
buf_read_error_in = buf_state_en & |axi_rresp[1:0]; // buffer error flag if return has Error ( ECC )
|
||||||
end
|
end
|
||||||
endcase
|
endcase
|
||||||
end // always_comb begin
|
end // always_comb begin
|
||||||
|
|
||||||
rvdffs #($bits(state_t)) state_reg (.*, .din(buf_nxtstate), .dout({buf_state}), .en(buf_state_en), .clk(ahb_clk));
|
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])) |
|
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'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'b10}} & (8'b1111 << ahb_haddr_q[2:0])) |
|
||||||
({8{ahb_hsize_q[2:0] == 3'b11}} & 8'b1111_1111);
|
({8{ahb_hsize_q[2:0] == 3'b11}} & 8'b1111_1111);
|
||||||
|
|
||||||
// AHB signals
|
// AHB signals
|
||||||
assign ahb_hreadyout = ahb_hresp ? (ahb_hresp_q & ~ahb_hready_q) :
|
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);
|
((~cmdbuf_full | (buf_state == IDLE)) & ~(buf_state == RD | buf_state == PEND) & ~buf_read_error);
|
||||||
|
|
||||||
assign ahb_hready = ahb_hreadyout & ahb_hreadyin;
|
assign ahb_hready = ahb_hreadyout & ahb_hreadyin;
|
||||||
assign ahb_htrans_in[1:0] = {2{ahb_hsel}} & ahb_htrans[1:0];
|
assign ahb_htrans_in[1:0] = {2{ahb_hsel}} & ahb_htrans[1:0];
|
||||||
assign ahb_hrdata[63:0] = buf_rdata[63: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_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_addr_in_iccm | (ahb_addr_in_dccm & ahb_hwrite_q)) & ~((ahb_hsize_q[1:0] == 2'b10) | (ahb_hsize_q[1:0] == 2'b11))) | // ICCM Rd/Wr OR DCCM Wr not the right size
|
||||||
((ahb_hsize_q[2:0] == 3'h1) & ahb_haddr_q[0]) | // HW size but unaligned
|
((ahb_hsize_q[2:0] == 3'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
|
// 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(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
|
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.
|
// 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)) 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(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(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(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(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
|
// Clock header logic
|
||||||
assign ahb_bus_addr_clk_en = bus_clk_en & (ahb_hready & ahb_htrans[1]);
|
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;
|
assign buf_rdata_clk_en = bus_clk_en & buf_rdata_en;
|
||||||
|
|
||||||
rvclkhdr ahb_cgc (.en(bus_clk_en), .l1clk(ahb_clk), .*);
|
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 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), .*);
|
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_range(ahb_addr_in_dccm),
|
||||||
.in_region(ahb_addr_in_dccm_region_nc)
|
.in_region(ahb_addr_in_dccm_region_nc)
|
||||||
);
|
);
|
||||||
|
|
||||||
// Address check iccm
|
// Address check iccm
|
||||||
`ifdef RV_ICCM_ENABLE
|
`ifdef RV_ICCM_ENABLE
|
||||||
rvrangecheck #(.CCM_SADR(`RV_ICCM_SADR),
|
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 = '0;
|
||||||
assign ahb_addr_in_iccm_region_nc = '0;
|
assign ahb_addr_in_iccm_region_nc = '0;
|
||||||
`endif
|
`endif
|
||||||
|
|
||||||
// PIC memory address check
|
// PIC memory address check
|
||||||
rvrangecheck #(.CCM_SADR(`RV_PIC_BASE_ADDR),
|
rvrangecheck #(.CCM_SADR(`RV_PIC_BASE_ADDR),
|
||||||
.CCM_SIZE(`RV_PIC_SIZE)) addr_pic_rangecheck (
|
.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.
|
// 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_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)));
|
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), .*);
|
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(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(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), .*);
|
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(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), .*);
|
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
|
// 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_awid[TAG-1:0] = '0;
|
||||||
assign axi_awaddr[31:0] = cmdbuf_addr[31:0];
|
assign axi_awaddr[31:0] = cmdbuf_addr[31:0];
|
||||||
assign axi_awsize[2:0] = {1'b0, cmdbuf_size[1: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_awlen[7:0] = '0;
|
||||||
assign axi_awburst[1:0] = 2'b01;
|
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.
|
// 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_wdata[63:0] = cmdbuf_wdata[63:0];
|
||||||
assign axi_wstrb[7:0] = cmdbuf_wstrb[7:0];
|
assign axi_wstrb[7:0] = cmdbuf_wstrb[7:0];
|
||||||
assign axi_wlast = 1'b1;
|
assign axi_wlast = 1'b1;
|
||||||
|
@ -258,17 +258,17 @@ module ahb_to_axi4 #(parameter TAG = 1) (
|
||||||
// AXI Read Channels
|
// AXI Read Channels
|
||||||
assign axi_arvalid = cmdbuf_vld & ~cmdbuf_write;
|
assign axi_arvalid = cmdbuf_vld & ~cmdbuf_write;
|
||||||
assign axi_arid[TAG-1:0] = '0;
|
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_arsize[2:0] = {1'b0, cmdbuf_size[1:0]};
|
||||||
assign axi_arprot = 3'b0;
|
assign axi_arprot = 3'b0;
|
||||||
assign axi_arlen[7:0] = '0;
|
assign axi_arlen[7:0] = '0;
|
||||||
assign axi_arburst[1:0] = 2'b01;
|
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.
|
// 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;
|
assign axi_rready = 1'b1;
|
||||||
|
|
||||||
// Clock header logic
|
// Clock header logic
|
||||||
rvclkhdr bus_cgc (.en(bus_clk_en), .l1clk(bus_clk), .*);
|
rvclkhdr bus_cgc (.en(bus_clk_en), .l1clk(bus_clk), .*);
|
||||||
|
|
||||||
`ifdef ASSERT_ON
|
`ifdef ASSERT_ON
|
||||||
property ahb_error_protocol;
|
property ahb_error_protocol;
|
||||||
@(posedge ahb_clk) (ahb_hready & ahb_hresp) |-> (~$past(ahb_hready) & $past(ahb_hresp));
|
@(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");
|
$display("Bus Error with hReady isn't preceded with Bus Error without hready");
|
||||||
|
|
||||||
`endif
|
`endif
|
||||||
|
|
||||||
endmodule // ahb_to_axi4
|
endmodule // ahb_to_axi4
|
|
@ -1,12 +1,12 @@
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
// Copyright 2019 Western Digital Corporation or its affiliates.
|
// Copyright 2019 Western Digital Corporation or its affiliates.
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "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 not use this file except in compliance with the License.
|
||||||
// You may obtain a copy of the License at
|
// You may obtain a copy of the License at
|
||||||
//
|
//
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
//
|
//
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
@ -16,8 +16,8 @@
|
||||||
//********************************************************************************
|
//********************************************************************************
|
||||||
// $Id$
|
// $Id$
|
||||||
//
|
//
|
||||||
// Owner:
|
// Owner:
|
||||||
// Function: AXI4 -> AHB Bridge
|
// Function: AXI4 -> AHB Bridge
|
||||||
// Comments:
|
// Comments:
|
||||||
//
|
//
|
||||||
//********************************************************************************
|
//********************************************************************************
|
||||||
|
@ -25,11 +25,11 @@ module axi4_to_ahb #(parameter TAG = 1) (
|
||||||
|
|
||||||
input clk,
|
input clk,
|
||||||
input rst_l,
|
input rst_l,
|
||||||
input scan_mode,
|
input scan_mode,
|
||||||
input bus_clk_en,
|
input bus_clk_en,
|
||||||
input clk_override,
|
input clk_override,
|
||||||
|
|
||||||
// AXI signals
|
// AXI signals
|
||||||
// AXI Write Channels
|
// AXI Write Channels
|
||||||
input logic axi_awvalid,
|
input logic axi_awvalid,
|
||||||
output logic axi_awready,
|
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_awsize,
|
||||||
input logic [2:0] axi_awprot,
|
input logic [2:0] axi_awprot,
|
||||||
|
|
||||||
input logic axi_wvalid,
|
input logic axi_wvalid,
|
||||||
output logic axi_wready,
|
output logic axi_wready,
|
||||||
input logic [63:0] axi_wdata,
|
input logic [63:0] axi_wdata,
|
||||||
input logic [7:0] axi_wstrb,
|
input logic [7:0] axi_wstrb,
|
||||||
|
@ -53,7 +53,7 @@ module axi4_to_ahb #(parameter TAG = 1) (
|
||||||
input logic axi_arvalid,
|
input logic axi_arvalid,
|
||||||
output logic axi_arready,
|
output logic axi_arready,
|
||||||
input logic [TAG-1:0] axi_arid,
|
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_arsize,
|
||||||
input logic [2:0] axi_arprot,
|
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 [TAG-1:0] axi_rid,
|
||||||
output logic [63:0] axi_rdata,
|
output logic [63:0] axi_rdata,
|
||||||
output logic [1:0] axi_rresp,
|
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 [31:0] ahb_haddr, // ahb bus address
|
||||||
output logic [2:0] ahb_hburst, // tied to 0
|
output logic [2:0] ahb_hburst, // tied to 0
|
||||||
output logic ahb_hmastlock, // 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 ahb_hwrite, // ahb bus write
|
||||||
output logic [63:0] ahb_hwdata, // ahb bus write data
|
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_hready, // slave ready to accept transaction
|
||||||
input logic ahb_hresp // slave response (high indicates erro)
|
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 [31:0] wrbuf_addr;
|
||||||
logic [63:0] wrbuf_data;
|
logic [63:0] wrbuf_data;
|
||||||
logic [7:0] wrbuf_byteen;
|
logic [7:0] wrbuf_byteen;
|
||||||
|
|
||||||
logic bus_write_clk_en;
|
logic bus_write_clk_en;
|
||||||
logic bus_clk, bus_write_clk;
|
logic bus_clk, bus_write_clk;
|
||||||
|
|
||||||
logic master_valid;
|
logic master_valid;
|
||||||
logic master_ready;
|
logic master_ready;
|
||||||
logic [TAG-1:0] master_tag;
|
logic [TAG-1:0] master_tag;
|
||||||
logic [31:0] master_addr;
|
logic [31:0] master_addr;
|
||||||
logic [63:0] master_wdata;
|
logic [63:0] master_wdata;
|
||||||
logic [2:0] master_size;
|
logic [2:0] master_size;
|
||||||
logic [2:0] master_opc;
|
logic [2:0] master_opc;
|
||||||
|
|
||||||
// Buffer signals (one entry buffer)
|
// Buffer signals (one entry buffer)
|
||||||
logic [31:0] buf_addr;
|
logic [31:0] buf_addr;
|
||||||
logic [1:0] buf_size;
|
logic [1:0] buf_size;
|
||||||
logic buf_write;
|
logic buf_write;
|
||||||
logic [7:0] buf_byteen;
|
logic [7:0] buf_byteen;
|
||||||
logic buf_aligned;
|
logic buf_aligned;
|
||||||
logic [63:0] buf_data;
|
logic [63:0] buf_data;
|
||||||
logic [TAG-1:0] buf_tag;
|
logic [TAG-1:0] buf_tag;
|
||||||
|
|
||||||
//Miscellaneous signals
|
//Miscellaneous signals
|
||||||
|
@ -130,19 +130,19 @@ module axi4_to_ahb #(parameter TAG = 1) (
|
||||||
logic buf_write_in;
|
logic buf_write_in;
|
||||||
logic buf_aligned_in;
|
logic buf_aligned_in;
|
||||||
logic [2:0] buf_size_in;
|
logic [2:0] buf_size_in;
|
||||||
|
|
||||||
logic buf_state_en;
|
logic buf_state_en;
|
||||||
logic buf_wr_en;
|
logic buf_wr_en;
|
||||||
logic buf_data_wr_en;
|
logic buf_data_wr_en;
|
||||||
logic slvbuf_error_en;
|
logic slvbuf_error_en;
|
||||||
logic wr_cmd_vld;
|
logic wr_cmd_vld;
|
||||||
|
|
||||||
logic cmd_done_rst, cmd_done, cmd_doneQ;
|
logic cmd_done_rst, cmd_done, cmd_doneQ;
|
||||||
logic trxn_done;
|
logic trxn_done;
|
||||||
logic [2:0] buf_cmd_byte_ptr, buf_cmd_byte_ptrQ, buf_cmd_nxtbyte_ptr;
|
logic [2:0] buf_cmd_byte_ptr, buf_cmd_byte_ptrQ, buf_cmd_nxtbyte_ptr;
|
||||||
logic buf_cmd_byte_ptr_en;
|
logic buf_cmd_byte_ptr_en;
|
||||||
logic found;
|
logic found;
|
||||||
|
|
||||||
logic slave_valid_pre;
|
logic slave_valid_pre;
|
||||||
logic ahb_hready_q;
|
logic ahb_hready_q;
|
||||||
logic ahb_hresp_q;
|
logic ahb_hresp_q;
|
||||||
|
@ -157,9 +157,9 @@ module axi4_to_ahb #(parameter TAG = 1) (
|
||||||
|
|
||||||
logic slvbuf_error_in;
|
logic slvbuf_error_in;
|
||||||
logic slvbuf_wr_en;
|
logic slvbuf_wr_en;
|
||||||
logic bypass_en;
|
logic bypass_en;
|
||||||
logic rd_bypass_idle;
|
logic rd_bypass_idle;
|
||||||
|
|
||||||
logic last_addr_en;
|
logic last_addr_en;
|
||||||
logic [31:0] last_bus_addr;
|
logic [31:0] last_bus_addr;
|
||||||
|
|
||||||
|
@ -172,32 +172,32 @@ module axi4_to_ahb #(parameter TAG = 1) (
|
||||||
logic ahbm_clk;
|
logic ahbm_clk;
|
||||||
logic ahbm_addr_clk;
|
logic ahbm_addr_clk;
|
||||||
logic ahbm_data_clk;
|
logic ahbm_data_clk;
|
||||||
|
|
||||||
// Function to get the length from byte enable
|
// Function to get the length from byte enable
|
||||||
function automatic logic [1:0] get_write_size;
|
function automatic logic [1:0] get_write_size;
|
||||||
input logic [7:0] byteen;
|
input logic [7:0] byteen;
|
||||||
|
|
||||||
logic [1:0] size;
|
logic [1:0] size;
|
||||||
|
|
||||||
size[1:0] = (2'b11 & {2{(byteen[7:0] == 8'hff)}}) |
|
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))}});
|
(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
|
endfunction // get_write_size
|
||||||
|
|
||||||
// Function to get the length from byte enable
|
// Function to get the length from byte enable
|
||||||
function automatic logic [2:0] get_write_addr;
|
function automatic logic [2:0] get_write_addr;
|
||||||
input logic [7:0] byteen;
|
input logic [7:0] byteen;
|
||||||
|
|
||||||
logic [2:0] addr;
|
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))}}) |
|
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'h2 & {3{(byteen[7:0] == 8'h0c)}}) |
|
||||||
(3'h4 & {3{((byteen[7:0] == 8'hf0) | (byteen[7:0] == 8'h03))}}) |
|
(3'h4 & {3{((byteen[7:0] == 8'hf0) | (byteen[7:0] == 8'h03))}}) |
|
||||||
(3'h6 & {3{(byteen[7:0] == 8'hc0)}});
|
(3'h6 & {3{(byteen[7:0] == 8'hc0)}});
|
||||||
|
|
||||||
return addr[2:0];
|
return addr[2:0];
|
||||||
endfunction // get_write_size
|
endfunction // get_write_size
|
||||||
|
|
||||||
// Function to get the next byte pointer
|
// Function to get the next byte pointer
|
||||||
|
@ -211,22 +211,22 @@ module axi4_to_ahb #(parameter TAG = 1) (
|
||||||
if (~found) begin
|
if (~found) begin
|
||||||
get_nxtbyte_ptr[2:0] = 3'(j);
|
get_nxtbyte_ptr[2:0] = 3'(j);
|
||||||
found |= (byteen[j] & (3'(j) >= start_ptr[2:0])) ;
|
found |= (byteen[j] & (3'(j) >= start_ptr[2:0])) ;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
endfunction // get_nextbyte_ptr
|
endfunction // get_nextbyte_ptr
|
||||||
|
|
||||||
|
|
||||||
// Write buffer
|
// Write buffer
|
||||||
assign wrbuf_en = axi_awvalid & axi_awready & master_ready;
|
assign wrbuf_en = axi_awvalid & axi_awready & master_ready;
|
||||||
assign wrbuf_data_en = axi_wvalid & axi_wready & 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_cmd_sent = master_valid & master_ready & (master_opc[2:1] == 2'b01);
|
||||||
assign wrbuf_rst = wrbuf_cmd_sent & ~wrbuf_en;
|
assign wrbuf_rst = wrbuf_cmd_sent & ~wrbuf_en;
|
||||||
|
|
||||||
assign axi_awready = ~(wrbuf_vld & ~wrbuf_cmd_sent) & master_ready;
|
assign axi_awready = ~(wrbuf_vld & ~wrbuf_cmd_sent) & master_ready;
|
||||||
assign axi_wready = ~(wrbuf_data_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 axi_rlast = 1'b1;
|
||||||
|
|
||||||
assign wr_cmd_vld = (wrbuf_vld & wrbuf_data_vld);
|
assign wr_cmd_vld = (wrbuf_vld & wrbuf_data_vld);
|
||||||
assign master_valid = wr_cmd_vld | axi_arvalid;
|
assign master_valid = wr_cmd_vld | axi_arvalid;
|
||||||
assign master_tag[TAG-1:0] = wr_cmd_vld ? wrbuf_tag[TAG-1:0] : axi_arid[TAG-1:0];
|
assign master_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_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_size[2:0] = wr_cmd_vld ? wrbuf_size[2:0] : axi_arsize[2:0];
|
||||||
assign master_wdata[63:0] = wrbuf_data[63:0];
|
assign master_wdata[63:0] = wrbuf_data[63:0];
|
||||||
|
|
||||||
// AXI response channel signals
|
// AXI response channel signals
|
||||||
assign axi_bvalid = slave_valid & slave_ready & slave_opc[3];
|
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_bid[TAG-1:0] = slave_tag[TAG-1:0];
|
||||||
|
|
||||||
assign axi_rvalid = slave_valid & slave_ready & (slave_opc[3:2] == 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_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_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;
|
assign slave_ready = axi_bready & axi_rready;
|
||||||
|
|
||||||
// Clock header logic
|
// Clock header logic
|
||||||
assign bus_write_clk_en = bus_clk_en & ((axi_awvalid & axi_awready) | (axi_wvalid & axi_wready));
|
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_cgc (.en(bus_clk_en), .l1clk(bus_clk), .*);
|
||||||
rvclkhdr bus_write_cgc (.en(bus_write_clk_en), .l1clk(bus_write_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;
|
cmd_done = 1'b0;
|
||||||
trxn_done = 1'b0;
|
trxn_done = 1'b0;
|
||||||
buf_cmd_byte_ptr_en = 1'b0;
|
buf_cmd_byte_ptr_en = 1'b0;
|
||||||
buf_cmd_byte_ptr[2:0] = '0;
|
buf_cmd_byte_ptr[2:0] = '0;
|
||||||
slave_valid_pre = 1'b0;
|
slave_valid_pre = 1'b0;
|
||||||
master_ready = 1'b0;
|
master_ready = 1'b0;
|
||||||
ahb_htrans[1:0] = 2'b0;
|
ahb_htrans[1:0] = 2'b0;
|
||||||
slvbuf_wr_en = 1'b0;
|
slvbuf_wr_en = 1'b0;
|
||||||
bypass_en = 1'b0;
|
bypass_en = 1'b0;
|
||||||
rd_bypass_idle = 1'b0;
|
rd_bypass_idle = 1'b0;
|
||||||
|
|
||||||
case (buf_state)
|
case (buf_state)
|
||||||
IDLE: begin
|
IDLE: begin
|
||||||
master_ready = 1'b1;
|
master_ready = 1'b1;
|
||||||
|
@ -288,11 +288,11 @@ module axi4_to_ahb #(parameter TAG = 1) (
|
||||||
ahb_htrans[1:0] = {2{bypass_en}} & 2'b10;
|
ahb_htrans[1:0] = {2{bypass_en}} & 2'b10;
|
||||||
end
|
end
|
||||||
CMD_RD: begin
|
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;
|
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;
|
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;
|
buf_wr_en = master_ready;
|
||||||
bypass_en = master_ready & master_valid;
|
bypass_en = master_ready & master_valid;
|
||||||
buf_cmd_byte_ptr[2:0] = bypass_en ? master_addr[2:0] : buf_addr[2:0];
|
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
|
STREAM_RD: begin
|
||||||
master_ready = (ahb_hready_q & ~ahb_hresp_q) & ~(master_valid & master_opc[2:1] == 2'b01);
|
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_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_state_en = (ahb_hready_q | ahb_hresp_q);
|
||||||
buf_data_wr_en = buf_state_en;
|
buf_data_wr_en = buf_state_en;
|
||||||
slvbuf_error_in = ahb_hresp_q;
|
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;
|
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];
|
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)}};
|
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
|
end // case: STREAM_RD
|
||||||
STREAM_ERR_RD: begin
|
STREAM_ERR_RD: begin
|
||||||
buf_nxtstate = DATA_RD;
|
buf_nxtstate = DATA_RD;
|
||||||
|
@ -336,15 +336,15 @@ module axi4_to_ahb #(parameter TAG = 1) (
|
||||||
buf_cmd_byte_ptr_en = buf_state_en;
|
buf_cmd_byte_ptr_en = buf_state_en;
|
||||||
slvbuf_wr_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;
|
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));
|
(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;
|
ahb_htrans[1:0] = {2{~(cmd_done | cmd_doneQ)}} & 2'b10;
|
||||||
end
|
end
|
||||||
DATA_WR: begin
|
DATA_WR: begin
|
||||||
buf_state_en = (cmd_doneQ & ahb_hready_q) | ahb_hresp_q;
|
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
|
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 :
|
buf_nxtstate = (ahb_hresp_q | ~slave_ready) ? DONE :
|
||||||
((master_valid & master_ready) ? ((master_opc[2:1] == 2'b01) ? CMD_WR : CMD_RD) : IDLE);
|
((master_valid & master_ready) ? ((master_opc[2:1] == 2'b01) ? CMD_WR : CMD_RD) : IDLE);
|
||||||
slvbuf_error_in = ahb_hresp_q;
|
slvbuf_error_in = ahb_hresp_q;
|
||||||
slvbuf_error_en = buf_state_en;
|
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_wr_en = buf_state_en & ((buf_nxtstate == CMD_WR) | (buf_nxtstate == CMD_RD));
|
||||||
buf_data_wr_en = buf_wr_en;
|
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))));
|
((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
|
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;
|
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);
|
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_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;
|
trxn_done ? get_nxtbyte_ptr(buf_cmd_byte_ptrQ[2:0],buf_byteen[7:0],1'b1) : buf_cmd_byte_ptrQ;
|
||||||
end
|
end
|
||||||
DONE: begin
|
DONE: begin
|
||||||
|
@ -374,7 +374,7 @@ module axi4_to_ahb #(parameter TAG = 1) (
|
||||||
|
|
||||||
assign buf_rst = 1'b0;
|
assign buf_rst = 1'b0;
|
||||||
assign cmd_done_rst = slave_valid_pre;
|
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_addr_in[31:3] = master_addr[31:3];
|
||||||
assign buf_tag_in[TAG-1:0] = master_tag[TAG-1:0];
|
assign buf_tag_in[TAG-1:0] = master_tag[TAG-1:0];
|
||||||
assign buf_byteen_in[7:0] = wrbuf_byteen[7:0];
|
assign buf_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_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
|
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'b0) | (master_size[1:0] == 2'b01) | (master_size[1:0] == 2'b10) | // Always aligned for Byte/HW/Word since they can be only for non-idempotent. IFU/SB are always aligned
|
||||||
((master_size[1:0] == 2'b11) &
|
((master_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'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)));
|
(wrbuf_byteen[7:0] == 8'hf) | (wrbuf_byteen[7:0] == 8'hf0) | (wrbuf_byteen[7:0] == 8'hff)));
|
||||||
|
|
||||||
// Generate the ahb signals
|
// 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_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])} :
|
// 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
|
// {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])} :
|
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
|
{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_hmastlock = 1'b0;
|
||||||
assign ahb_hprot[3:0] = {3'b001,~axi_arprot[2]};
|
assign ahb_hprot[3:0] = {3'b001,~axi_arprot[2]};
|
||||||
assign ahb_hwrite = bypass_en ? (master_opc[2:1] == 2'b01) : buf_write;
|
assign ahb_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_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_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 slave_tag[TAG-1:0] = slvbuf_tag[TAG-1:0];
|
||||||
|
|
||||||
assign last_addr_en = (ahb_htrans[1:0] != 2'b0) & ahb_hready & ahb_hwrite ;
|
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_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), .*);
|
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), .*);
|
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(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), .*);
|
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), .*);
|
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(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), .*);
|
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(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), .*);
|
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), .*);
|
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(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(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), .*);
|
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), .*);
|
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), .*);
|
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 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_addr_clken = bus_clk_en & ((ahb_hready & ahb_htrans[1]) | clk_override);
|
||||||
assign ahbm_data_clken = bus_clk_en & ((buf_state != IDLE) | clk_override);
|
assign ahbm_data_clken = bus_clk_en & ((buf_state != IDLE) | clk_override);
|
||||||
|
|
||||||
rvclkhdr buf_cgc (.en(buf_clken), .l1clk(buf_clk), .*);
|
rvclkhdr buf_cgc (.en(buf_clken), .l1clk(buf_clk), .*);
|
||||||
rvclkhdr ahbm_cgc (.en(bus_clk_en), .l1clk(ahbm_clk), .*);
|
rvclkhdr ahbm_cgc (.en(bus_clk_en), .l1clk(ahbm_clk), .*);
|
||||||
rvclkhdr ahbm_addr_cgc (.en(ahbm_addr_clken), .l1clk(ahbm_addr_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'h2) & (ahb_haddr[1:0] == 2'b0)) |
|
||||||
((ahb_hsize[2:0] == 3'h3) & (ahb_haddr[2:0] == 3'b0)));
|
((ahb_hsize[2:0] == 3'h3) & (ahb_haddr[2:0] == 3'b0)));
|
||||||
endproperty
|
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]);
|
$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;
|
property ahb_error_protocol;
|
||||||
@(posedge ahbm_clk) (ahb_hready & ahb_hresp) |-> (~$past(ahb_hready) & $past(ahb_hresp));
|
@(posedge ahbm_clk) (ahb_hready & ahb_hresp) |-> (~$past(ahb_hready) & $past(ahb_hresp));
|
||||||
endproperty
|
endproperty
|
||||||
assert_ahb_error_protocol: assert property (ahb_error_protocol) else
|
assert_ahb_error_protocol: assert property (ahb_error_protocol) else
|
||||||
$display("Bus Error with hReady isn't preceded with Bus Error without hready");
|
$display("Bus Error with hReady isn't preceded with Bus Error without hready");
|
||||||
`endif
|
`endif
|
||||||
|
|
||||||
endmodule // axi4_to_ahb
|
endmodule // axi4_to_ahb
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
// Copyright 2019 Western Digital Corporation or its affiliates.
|
// Copyright 2019 Western Digital Corporation or its affiliates.
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "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 not use this file except in compliance with the License.
|
||||||
// You may obtain a copy of the License at
|
// You may obtain a copy of the License at
|
||||||
//
|
//
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
//
|
//
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
@ -17,7 +17,7 @@
|
||||||
|
|
||||||
|
|
||||||
module rvdff #( parameter WIDTH=1 )
|
module rvdff #( parameter WIDTH=1 )
|
||||||
(
|
(
|
||||||
input logic [WIDTH-1:0] din,
|
input logic [WIDTH-1:0] din,
|
||||||
input logic clk,
|
input logic clk,
|
||||||
input logic rst_l,
|
input logic rst_l,
|
||||||
|
@ -37,27 +37,27 @@ module rvdff #( parameter WIDTH=1 )
|
||||||
else
|
else
|
||||||
dout[WIDTH-1:0] <= din[WIDTH-1:0];
|
dout[WIDTH-1:0] <= din[WIDTH-1:0];
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
// rvdff with 2:1 input mux to flop din iff sel==1
|
// rvdff with 2:1 input mux to flop din iff sel==1
|
||||||
module rvdffs #( parameter WIDTH=1 )
|
module rvdffs #( parameter WIDTH=1 )
|
||||||
(
|
(
|
||||||
input logic [WIDTH-1:0] din,
|
input logic [WIDTH-1:0] din,
|
||||||
input logic en,
|
input logic en,
|
||||||
input logic clk,
|
input logic clk,
|
||||||
input logic rst_l,
|
input logic rst_l,
|
||||||
output logic [WIDTH-1:0] dout
|
output logic [WIDTH-1:0] dout
|
||||||
);
|
);
|
||||||
|
|
||||||
rvdff #(WIDTH) dffs (.din((en) ? din[WIDTH-1:0] : dout[WIDTH-1:0]), .*);
|
rvdff #(WIDTH) dffs (.din((en) ? din[WIDTH-1:0] : dout[WIDTH-1:0]), .*);
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
// rvdff with en and clear
|
// rvdff with en and clear
|
||||||
module rvdffsc #( parameter WIDTH=1 )
|
module rvdffsc #( parameter WIDTH=1 )
|
||||||
(
|
(
|
||||||
input logic [WIDTH-1:0] din,
|
input logic [WIDTH-1:0] din,
|
||||||
input logic en,
|
input logic en,
|
||||||
input logic clear,
|
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]);
|
assign din_new = {WIDTH{~clear}} & (en ? din[WIDTH-1:0] : dout[WIDTH-1:0]);
|
||||||
rvdff #(WIDTH) dffsc (.din(din_new[WIDTH-1:0]), .*);
|
rvdff #(WIDTH) dffsc (.din(din_new[WIDTH-1:0]), .*);
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
module `TEC_RV_ICG
|
module `TEC_RV_ICG
|
||||||
(
|
(
|
||||||
input logic TE, E, CP,
|
input logic TE, E, CP,
|
||||||
output Q
|
output Q
|
||||||
);
|
);
|
||||||
|
|
||||||
logic en_ff;
|
logic en_ff;
|
||||||
logic enable;
|
logic enable;
|
||||||
|
|
||||||
assign enable = E | TE;
|
assign enable = E | TE;
|
||||||
|
|
||||||
`ifdef VERILATOR
|
`ifdef VERILATOR
|
||||||
always @(negedge CP) begin
|
always @(negedge CP) begin
|
||||||
en_ff <= enable;
|
en_ff <= enable;
|
||||||
end
|
end
|
||||||
`else
|
`else
|
||||||
always @(CP, enable) begin
|
always @(CP, enable) begin
|
||||||
if(!CP)
|
if(!CP)
|
||||||
en_ff = enable;
|
en_ff = enable;
|
||||||
|
@ -107,7 +107,7 @@ module rvclkhdr
|
||||||
|
|
||||||
logic TE;
|
logic TE;
|
||||||
assign TE = scan_mode;
|
assign TE = scan_mode;
|
||||||
|
|
||||||
`TEC_RV_ICG clkhdr ( .*, .E(en), .CP(clk), .Q(l1clk));
|
`TEC_RV_ICG clkhdr ( .*, .E(en), .CP(clk), .Q(l1clk));
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
@ -126,16 +126,16 @@ module rvoclkhdr
|
||||||
`ifdef RV_FPGA_OPTIMIZE
|
`ifdef RV_FPGA_OPTIMIZE
|
||||||
assign l1clk = clk;
|
assign l1clk = clk;
|
||||||
`else
|
`else
|
||||||
`TEC_RV_ICG clkhdr ( .*, .E(en), .CP(clk), .Q(l1clk));
|
`TEC_RV_ICG rvclkhdr ( .*, .E(en), .CP(clk), .Q(l1clk));
|
||||||
`endif
|
`endif
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
module rvdffe #( parameter WIDTH=1 )
|
module rvdffe #( parameter WIDTH=1 )
|
||||||
(
|
(
|
||||||
input logic [WIDTH-1:0] din,
|
input logic [WIDTH-1:0] din,
|
||||||
input logic en,
|
input logic en,
|
||||||
input logic clk,
|
input logic clk,
|
||||||
input logic rst_l,
|
input logic rst_l,
|
||||||
input logic scan_mode,
|
input logic scan_mode,
|
||||||
output logic [WIDTH-1:0] dout
|
output logic [WIDTH-1:0] dout
|
||||||
|
@ -143,7 +143,8 @@ module rvdffe #( parameter WIDTH=1 )
|
||||||
|
|
||||||
logic l1clk;
|
logic l1clk;
|
||||||
|
|
||||||
`ifndef PHYSICAL
|
|
||||||
|
`ifndef PHYSICAL
|
||||||
if (WIDTH >= 8) begin: genblock
|
if (WIDTH >= 8) begin: genblock
|
||||||
`endif
|
`endif
|
||||||
|
|
||||||
|
@ -156,30 +157,30 @@ module rvdffe #( parameter WIDTH=1 )
|
||||||
|
|
||||||
`ifndef PHYSICAL
|
`ifndef PHYSICAL
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
$error("%m: rvdffe width must be >= 8");
|
$error("%m: rvdffe width must be >= 8");
|
||||||
`endif
|
`endif
|
||||||
|
|
||||||
|
|
||||||
endmodule // rvdffe
|
endmodule // rvdffe
|
||||||
|
|
||||||
module rvsyncss #(parameter WIDTH = 251)
|
module rvsyncss #(parameter WIDTH = 251)
|
||||||
(
|
(
|
||||||
input logic clk,
|
input logic clk,
|
||||||
input logic rst_l,
|
input logic rst_l,
|
||||||
input logic [WIDTH-1:0] din,
|
input logic [WIDTH-1:0] din,
|
||||||
output logic [WIDTH-1:0] dout
|
output logic [WIDTH-1:0] dout
|
||||||
);
|
);
|
||||||
|
|
||||||
logic [WIDTH-1:0] din_ff1;
|
logic [WIDTH-1:0] din_ff1;
|
||||||
|
|
||||||
rvdff #(WIDTH) sync_ff1 (.*, .din (din[WIDTH-1:0]), .dout(din_ff1[WIDTH-1:0]));
|
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]));
|
rvdff #(WIDTH) sync_ff2 (.*, .din (din_ff1[WIDTH-1:0]), .dout(dout[WIDTH-1:0]));
|
||||||
|
|
||||||
endmodule // rvsyncss
|
endmodule // rvsyncss
|
||||||
|
|
||||||
module rvlsadder
|
module rvlsadder
|
||||||
(
|
(
|
||||||
input logic [31:0] rs1,
|
input logic [31:0] rs1,
|
||||||
input logic [11:0] offset,
|
input logic [11:0] offset,
|
||||||
|
|
||||||
|
@ -188,7 +189,7 @@ module rvlsadder
|
||||||
|
|
||||||
logic cout;
|
logic cout;
|
||||||
logic sign;
|
logic sign;
|
||||||
|
|
||||||
logic [31:12] rs1_inc;
|
logic [31:12] rs1_inc;
|
||||||
logic [31:12] rs1_dec;
|
logic [31:12] rs1_dec;
|
||||||
|
|
||||||
|
@ -203,13 +204,13 @@ module rvlsadder
|
||||||
assign dout[31:12] = ({20{ sign ^~ cout}} & rs1[31:12]) |
|
assign dout[31:12] = ({20{ sign ^~ cout}} & rs1[31:12]) |
|
||||||
({20{ ~sign & cout}} & rs1_inc[31:12]) |
|
({20{ ~sign & cout}} & rs1_inc[31:12]) |
|
||||||
({20{ sign & ~cout}} & rs1_dec[31:12]);
|
({20{ sign & ~cout}} & rs1_dec[31:12]);
|
||||||
|
|
||||||
endmodule // rvlsadder
|
endmodule // rvlsadder
|
||||||
|
|
||||||
// assume we only maintain pc[31:1] in the pipe
|
// assume we only maintain pc[31:1] in the pipe
|
||||||
|
|
||||||
module rvbradder
|
module rvbradder
|
||||||
(
|
(
|
||||||
input [31:1] pc,
|
input [31:1] pc,
|
||||||
input [12:1] offset,
|
input [12:1] offset,
|
||||||
|
|
||||||
|
@ -218,7 +219,7 @@ module rvbradder
|
||||||
|
|
||||||
logic cout;
|
logic cout;
|
||||||
logic sign;
|
logic sign;
|
||||||
|
|
||||||
logic [31:13] pc_inc;
|
logic [31:13] pc_inc;
|
||||||
logic [31:13] pc_dec;
|
logic [31:13] pc_dec;
|
||||||
|
|
||||||
|
@ -234,44 +235,44 @@ module rvbradder
|
||||||
assign dout[31:13] = ({19{ sign ^~ cout}} & pc[31:13]) |
|
assign dout[31:13] = ({19{ sign ^~ cout}} & pc[31:13]) |
|
||||||
({19{ ~sign & cout}} & pc_inc[31:13]) |
|
({19{ ~sign & cout}} & pc_inc[31:13]) |
|
||||||
({19{ sign & ~cout}} & pc_dec[31:13]);
|
({19{ sign & ~cout}} & pc_dec[31:13]);
|
||||||
|
|
||||||
|
|
||||||
endmodule // rvbradder
|
endmodule // rvbradder
|
||||||
|
|
||||||
|
|
||||||
// 2s complement circuit
|
// 2s complement circuit
|
||||||
module rvtwoscomp #( parameter WIDTH=32 )
|
module rvtwoscomp #( parameter WIDTH=32 )
|
||||||
(
|
(
|
||||||
input logic [WIDTH-1:0] din,
|
input logic [WIDTH-1:0] din,
|
||||||
|
|
||||||
output logic [WIDTH-1:0] dout
|
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
|
logic [WIDTH-1:1] dout_temp; // holding for all other bits except for the lsb. LSB is always din
|
||||||
|
|
||||||
genvar i;
|
genvar i;
|
||||||
|
|
||||||
for ( i = 1; i < WIDTH; i++ ) begin : flip_after_first_one
|
for ( i = 1; i < WIDTH; i++ ) begin : flip_after_first_one
|
||||||
assign dout_temp[i] = (|din[i-1:0]) ? ~din[i] : din[i];
|
assign dout_temp[i] = (|din[i-1:0]) ? ~din[i] : din[i];
|
||||||
end : flip_after_first_one
|
end : flip_after_first_one
|
||||||
|
|
||||||
assign dout[WIDTH-1:0] = { dout_temp[WIDTH-1:1], din[0] };
|
assign dout[WIDTH-1:0] = { dout_temp[WIDTH-1:1], din[0] };
|
||||||
|
|
||||||
endmodule // 2'scomp
|
endmodule // 2'scomp
|
||||||
|
|
||||||
// find first
|
// find first
|
||||||
module rvfindfirst1 #( parameter WIDTH=32, SHIFT=$clog2(WIDTH) )
|
module rvfindfirst1 #( parameter WIDTH=32, SHIFT=$clog2(WIDTH) )
|
||||||
(
|
(
|
||||||
input logic [WIDTH-1:0] din,
|
input logic [WIDTH-1:0] din,
|
||||||
|
|
||||||
output logic [SHIFT-1:0] dout
|
output logic [SHIFT-1:0] dout
|
||||||
);
|
);
|
||||||
logic done;
|
logic done;
|
||||||
|
|
||||||
always_comb begin
|
always_comb begin
|
||||||
dout[SHIFT-1:0] = {SHIFT{1'b0}};
|
dout[SHIFT-1:0] = {SHIFT{1'b0}};
|
||||||
done = 1'b0;
|
done = 1'b0;
|
||||||
|
|
||||||
for ( int i = WIDTH-1; i > 0; i-- ) begin : find_first_one
|
for ( int i = WIDTH-1; i > 0; i-- ) begin : find_first_one
|
||||||
done |= din[i];
|
done |= din[i];
|
||||||
dout[SHIFT-1:0] += done ? 1'b0 : 1'b1;
|
dout[SHIFT-1:0] += done ? 1'b0 : 1'b1;
|
||||||
|
@ -280,19 +281,19 @@ module rvfindfirst1 #( parameter WIDTH=32, SHIFT=$clog2(WIDTH) )
|
||||||
endmodule // rvfindfirst1
|
endmodule // rvfindfirst1
|
||||||
|
|
||||||
module rvfindfirst1hot #( parameter WIDTH=32 )
|
module rvfindfirst1hot #( parameter WIDTH=32 )
|
||||||
(
|
(
|
||||||
input logic [WIDTH-1:0] din,
|
input logic [WIDTH-1:0] din,
|
||||||
|
|
||||||
output logic [WIDTH-1:0] dout
|
output logic [WIDTH-1:0] dout
|
||||||
);
|
);
|
||||||
logic done;
|
logic done;
|
||||||
|
|
||||||
always_comb begin
|
always_comb begin
|
||||||
dout[WIDTH-1:0] = {WIDTH{1'b0}};
|
dout[WIDTH-1:0] = {WIDTH{1'b0}};
|
||||||
done = 1'b0;
|
done = 1'b0;
|
||||||
for ( int i = 0; i < WIDTH; i++ ) begin : find_first_one
|
for ( int i = 0; i < WIDTH; i++ ) begin : find_first_one
|
||||||
dout[i] = ~done & din[i];
|
dout[i] = ~done & din[i];
|
||||||
done |= din[i];
|
done |= din[i];
|
||||||
end : find_first_one
|
end : find_first_one
|
||||||
end
|
end
|
||||||
endmodule // rvfindfirst1hot
|
endmodule // rvfindfirst1hot
|
||||||
|
@ -300,25 +301,25 @@ endmodule // rvfindfirst1hot
|
||||||
// mask and match function matches bits after finding the first 0 position
|
// 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
|
// find first starting from LSB. Skip that location and match the rest of the bits
|
||||||
module rvmaskandmatch #( parameter WIDTH=32 )
|
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] 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 [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
|
input logic masken, // when 1 : do mask. 0 : full match
|
||||||
output logic match
|
output logic match
|
||||||
);
|
);
|
||||||
|
|
||||||
logic [WIDTH-1:0] matchvec;
|
logic [WIDTH-1:0] matchvec;
|
||||||
logic masken_or_fullmask;
|
logic masken_or_fullmask;
|
||||||
|
|
||||||
assign masken_or_fullmask = masken & ~(&mask[WIDTH-1:0]);
|
assign masken_or_fullmask = masken & ~(&mask[WIDTH-1:0]);
|
||||||
|
|
||||||
assign matchvec[0] = masken_or_fullmask | (mask[0] == data[0]);
|
assign matchvec[0] = masken_or_fullmask | (mask[0] == data[0]);
|
||||||
genvar i;
|
genvar i;
|
||||||
|
|
||||||
for ( i = 1; i < WIDTH; i++ ) begin : match_after_first_zero
|
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]);
|
assign matchvec[i] = (&mask[i-1:0] & masken_or_fullmask) ? 1'b1 : (mask[i] == data[i]);
|
||||||
end : match_after_first_zero
|
end : match_after_first_zero
|
||||||
|
|
||||||
assign match = &matchvec[WIDTH-1:0]; // all bits either matched or were masked off
|
assign match = &matchvec[WIDTH-1:0]; // all bits either matched or were masked off
|
||||||
|
|
||||||
endmodule // rvmaskandmatch
|
endmodule // rvmaskandmatch
|
||||||
|
@ -328,17 +329,17 @@ module rvbtb_tag_hash (
|
||||||
output logic [`RV_BTB_BTAG_SIZE-1:0] hash
|
output logic [`RV_BTB_BTAG_SIZE-1:0] hash
|
||||||
);
|
);
|
||||||
`ifndef RV_BTB_BTAG_FOLD
|
`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] ^
|
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_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])};
|
pc[`RV_BTB_ADDR_HI+`RV_BTB_BTAG_SIZE:`RV_BTB_ADDR_HI+1])};
|
||||||
`else
|
`else
|
||||||
assign hash = {(
|
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])};
|
pc[`RV_BTB_ADDR_HI+`RV_BTB_BTAG_SIZE:`RV_BTB_ADDR_HI+1])};
|
||||||
`endif
|
`endif
|
||||||
|
|
||||||
// assign hash = {pc[`RV_BTB_ADDR_HI+1],(pc[`RV_BTB_ADDR_HI+13:`RV_BTB_ADDR_HI+10] ^
|
// 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+9:`RV_BTB_ADDR_HI+6] ^
|
||||||
// pc[`RV_BTB_ADDR_HI+5:`RV_BTB_ADDR_HI+2])};
|
// pc[`RV_BTB_ADDR_HI+5:`RV_BTB_ADDR_HI+2])};
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
@ -348,12 +349,12 @@ module rvbtb_addr_hash (
|
||||||
output logic [`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO] 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
|
`ifndef RV_BTB_FOLD2_INDEX_HASH
|
||||||
pc[`RV_BTB_INDEX2_HI:`RV_BTB_INDEX2_LO] ^
|
pc[`RV_BTB_INDEX2_HI:`RV_BTB_INDEX2_LO] ^
|
||||||
`endif
|
`endif
|
||||||
|
|
||||||
pc[`RV_BTB_INDEX3_HI:`RV_BTB_INDEX3_LO];
|
pc[`RV_BTB_INDEX3_HI:`RV_BTB_INDEX3_LO];
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
@ -373,10 +374,10 @@ endmodule
|
||||||
|
|
||||||
// Check if the S_ADDR <= addr < E_ADDR
|
// Check if the S_ADDR <= addr < E_ADDR
|
||||||
module rvrangecheck #(CCM_SADR = 32'h0,
|
module rvrangecheck #(CCM_SADR = 32'h0,
|
||||||
CCM_SIZE = 128) (
|
CCM_SIZE = 128) (
|
||||||
input logic [31:0] addr, // Address to be checked for range
|
input logic [31:0] addr, // Address to be checked for range
|
||||||
output logic in_range, // S_ADDR <= start_addr < E_ADDR
|
output logic in_range, // S_ADDR <= start_addr < E_ADDR
|
||||||
output logic in_region
|
output logic in_region
|
||||||
);
|
);
|
||||||
|
|
||||||
localparam REGION_BITS = 4;
|
localparam REGION_BITS = 4;
|
||||||
|
@ -384,42 +385,42 @@ module rvrangecheck #(CCM_SADR = 32'h0,
|
||||||
|
|
||||||
logic [31:0] start_addr;
|
logic [31:0] start_addr;
|
||||||
logic [3:0] region;
|
logic [3:0] region;
|
||||||
|
|
||||||
assign start_addr[31:0] = CCM_SADR;
|
assign start_addr[31:0] = CCM_SADR;
|
||||||
assign region[REGION_BITS-1:0] = start_addr[31:(32-REGION_BITS)];
|
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)
|
if (CCM_SIZE == 48)
|
||||||
assign in_range = (addr[31:MASK_BITS] == start_addr[31:MASK_BITS]) & ~(&addr[MASK_BITS-1 : MASK_BITS-2]);
|
assign in_range = (addr[31:MASK_BITS] == start_addr[31:MASK_BITS]) & ~(&addr[MASK_BITS-1 : MASK_BITS-2]);
|
||||||
else
|
else
|
||||||
assign in_range = (addr[31:MASK_BITS] == start_addr[31:MASK_BITS]);
|
assign in_range = (addr[31:MASK_BITS] == start_addr[31:MASK_BITS]);
|
||||||
|
|
||||||
endmodule // rvrangechecker
|
endmodule // rvrangechecker
|
||||||
|
|
||||||
// 16 bit even parity generator
|
// 16 bit even parity generator
|
||||||
module rveven_paritygen #(WIDTH = 16) (
|
module rveven_paritygen #(WIDTH = 16) (
|
||||||
input logic [WIDTH-1:0] data_in, // Data
|
input logic [WIDTH-1:0] data_in, // Data
|
||||||
output logic parity_out // generated even parity
|
output logic parity_out // generated even parity
|
||||||
);
|
);
|
||||||
|
|
||||||
assign parity_out = ^(data_in[WIDTH-1:0]) ;
|
assign parity_out = ^(data_in[WIDTH-1:0]) ;
|
||||||
|
|
||||||
endmodule // rveven_paritygen
|
endmodule // rveven_paritygen
|
||||||
|
|
||||||
module rveven_paritycheck #(WIDTH = 16) (
|
module rveven_paritycheck #(WIDTH = 16) (
|
||||||
input logic [WIDTH-1:0] data_in, // Data
|
input logic [WIDTH-1:0] data_in, // Data
|
||||||
input logic parity_in,
|
input logic parity_in,
|
||||||
output logic parity_err // Parity error
|
output logic parity_err // Parity error
|
||||||
);
|
);
|
||||||
|
|
||||||
assign parity_err = ^(data_in[WIDTH-1:0]) ^ parity_in ;
|
assign parity_err = ^(data_in[WIDTH-1:0]) ^ parity_in ;
|
||||||
|
|
||||||
endmodule // rveven_paritycheck
|
endmodule // rveven_paritycheck
|
||||||
|
|
||||||
module rvecc_encode (
|
module rvecc_encode (
|
||||||
input [31:0] din,
|
input [31:0] din,
|
||||||
output [6:0] ecc_out
|
output [6:0] ecc_out
|
||||||
);
|
);
|
||||||
logic [5:0] ecc_out_temp;
|
logic [5:0] ecc_out_temp;
|
||||||
|
|
||||||
assign ecc_out_temp[0] = din[0]^din[1]^din[3]^din[4]^din[6]^din[8]^din[10]^din[11]^din[13]^din[15]^din[17]^din[19]^din[21]^din[23]^din[25]^din[26]^din[28]^din[30];
|
assign ecc_out_temp[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 [6:0] ecc_check;
|
||||||
logic [38:0] error_mask;
|
logic [38:0] error_mask;
|
||||||
logic [38:0] din_plus_parity, dout_plus_parity;
|
logic [38:0] din_plus_parity, dout_plus_parity;
|
||||||
|
|
||||||
// Generate the ecc bits
|
// 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[0] = ecc_in[0]^din[0]^din[1]^din[3]^din[4]^din[6]^din[8]^din[10]^din[11]^din[13]^din[15]^din[17]^din[19]^din[21]^din[23]^din[25]^din[26]^din[28]^din[30];
|
||||||
assign ecc_check[1] = ecc_in[1]^din[0]^din[2]^din[3]^din[5]^din[6]^din[9]^din[10]^din[12]^din[13]^din[16]^din[17]^din[20]^din[21]^din[24]^din[25]^din[27]^din[28]^din[31];
|
assign ecc_check[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 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 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
|
// Generate the mask for error correctiong
|
||||||
for (genvar i=1; i<40; i++) begin
|
for (genvar i=1; i<40; i++) begin
|
||||||
assign error_mask[i-1] = (ecc_check[5:0] == i);
|
assign error_mask[i-1] = (ecc_check[5:0] == i);
|
||||||
|
@ -470,9 +471,9 @@ module rvecc_decode (
|
||||||
|
|
||||||
// Generate the corrected data
|
// 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 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_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 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]};
|
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
|
endmodule // rvecc_decode
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
// Copyright 2019 Western Digital Corporation or its affiliates.
|
// Copyright 2019 Western Digital Corporation or its affiliates.
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "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 not use this file except in compliance with the License.
|
||||||
// You may obtain a copy of the License at
|
// You may obtain a copy of the License at
|
||||||
//
|
//
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
//
|
//
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
@ -17,14 +17,14 @@
|
||||||
//=================================== START OF CCM =======================================================================
|
//=================================== START OF CCM =======================================================================
|
||||||
//============= Possible sram sizes for a 39 bit wide memory ( 4 bytes + 7 bits ECC ) =====================================
|
//============= 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 CLK,
|
||||||
input logic [14:0] ADR,
|
input logic [14:0] ADR,
|
||||||
input logic [38:0] D,
|
input logic [38:0] D,
|
||||||
|
|
||||||
output logic [38:0] Q,
|
output logic [38:0] Q,
|
||||||
input logic WE );
|
input logic WE );
|
||||||
|
|
||||||
// behavior to be replaced by actual SRAM in VLE
|
// behavior to be replaced by actual SRAM in VLE
|
||||||
|
|
||||||
reg [38:0] ram_core [32767:0];
|
reg [38:0] ram_core [32767:0];
|
||||||
|
@ -35,20 +35,20 @@ module ram_32768x39
|
||||||
Q <= ram_core[ADR];
|
Q <= ram_core[ADR];
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
endmodule // ram_32768x39
|
endmodule // ram_32768x39
|
||||||
|
|
||||||
|
|
||||||
module ram_16384x39
|
module ram_16384x39
|
||||||
( input logic CLK,
|
( input logic CLK,
|
||||||
input logic [13:0] ADR,
|
input logic [13:0] ADR,
|
||||||
input logic [38:0] D,
|
input logic [38:0] D,
|
||||||
|
|
||||||
output logic [38:0] Q,
|
output logic [38:0] Q,
|
||||||
input logic WE );
|
input logic WE );
|
||||||
|
|
||||||
// behavior to be replaced by actual SRAM in VLE
|
// behavior to be replaced by actual SRAM in VLE
|
||||||
|
|
||||||
reg [38:0] ram_core [16383:0];
|
reg [38:0] ram_core [16383:0];
|
||||||
|
@ -59,19 +59,19 @@ module ram_16384x39
|
||||||
Q <= ram_core[ADR];
|
Q <= ram_core[ADR];
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
endmodule // ram_16384x39
|
endmodule // ram_16384x39
|
||||||
|
|
||||||
module ram_8192x39
|
module ram_8192x39
|
||||||
( input logic CLK,
|
( input logic CLK,
|
||||||
input logic [12:0] ADR,
|
input logic [12:0] ADR,
|
||||||
input logic [38:0] D,
|
input logic [38:0] D,
|
||||||
|
|
||||||
output logic [38:0] Q,
|
output logic [38:0] Q,
|
||||||
input logic WE );
|
input logic WE );
|
||||||
|
|
||||||
// behavior to be replaced by actual SRAM in VLE
|
// behavior to be replaced by actual SRAM in VLE
|
||||||
|
|
||||||
reg [38:0] ram_core [8191:0];
|
reg [38:0] ram_core [8191:0];
|
||||||
|
@ -82,19 +82,19 @@ module ram_8192x39
|
||||||
Q <= ram_core[ADR];
|
Q <= ram_core[ADR];
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
endmodule // ram_8192x39
|
endmodule // ram_8192x39
|
||||||
|
|
||||||
module ram_4096x39
|
module ram_4096x39
|
||||||
( input logic CLK,
|
( input logic CLK,
|
||||||
input logic [11:0] ADR,
|
input logic [11:0] ADR,
|
||||||
input logic [38:0] D,
|
input logic [38:0] D,
|
||||||
|
|
||||||
output logic [38:0] Q,
|
output logic [38:0] Q,
|
||||||
input logic WE );
|
input logic WE );
|
||||||
|
|
||||||
// behavior to be replaced by actual SRAM in VLE
|
// behavior to be replaced by actual SRAM in VLE
|
||||||
|
|
||||||
reg [38:0] ram_core [4095:0];
|
reg [38:0] ram_core [4095:0];
|
||||||
|
@ -105,19 +105,19 @@ module ram_4096x39
|
||||||
Q <= ram_core[ADR];
|
Q <= ram_core[ADR];
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
endmodule // ram_4096x39
|
endmodule // ram_4096x39
|
||||||
|
|
||||||
module ram_3072x39
|
module ram_3072x39
|
||||||
( input logic CLK,
|
( input logic CLK,
|
||||||
input logic [11:0] ADR,
|
input logic [11:0] ADR,
|
||||||
input logic [38:0] D,
|
input logic [38:0] D,
|
||||||
|
|
||||||
output logic [38:0] Q,
|
output logic [38:0] Q,
|
||||||
input logic WE );
|
input logic WE );
|
||||||
|
|
||||||
// behavior to be replaced by actual SRAM in VLE
|
// behavior to be replaced by actual SRAM in VLE
|
||||||
|
|
||||||
reg [38:0] ram_core [3071:0];
|
reg [38:0] ram_core [3071:0];
|
||||||
|
@ -128,21 +128,21 @@ module ram_3072x39
|
||||||
Q <= ram_core[ADR];
|
Q <= ram_core[ADR];
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
endmodule // ram_3072x39
|
endmodule // ram_3072x39
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
module ram_2048x39
|
module ram_2048x39
|
||||||
( input logic CLK,
|
( input logic CLK,
|
||||||
input logic [10:0] ADR,
|
input logic [10:0] ADR,
|
||||||
input logic [38:0] D,
|
input logic [38:0] D,
|
||||||
|
|
||||||
output logic [38:0] Q,
|
output logic [38:0] Q,
|
||||||
input logic WE );
|
input logic WE );
|
||||||
|
|
||||||
// behavior to be replaced by actual SRAM in VLE
|
// behavior to be replaced by actual SRAM in VLE
|
||||||
|
|
||||||
reg [38:0] ram_core [2047:0];
|
reg [38:0] ram_core [2047:0];
|
||||||
|
@ -153,7 +153,7 @@ module ram_2048x39
|
||||||
Q <= ram_core[ADR];
|
Q <= ram_core[ADR];
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
endmodule // ram_2048x39
|
endmodule // ram_2048x39
|
||||||
|
@ -165,7 +165,7 @@ module ram_1536x39 // need this for the 48KB DCCM option
|
||||||
|
|
||||||
output logic [38:0] Q,
|
output logic [38:0] Q,
|
||||||
input logic WE );
|
input logic WE );
|
||||||
|
|
||||||
// behavior to be replaced by actual SRAM in VLE
|
// behavior to be replaced by actual SRAM in VLE
|
||||||
|
|
||||||
reg [38:0] ram_core [1535:0];
|
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];
|
Q <= ram_core[ADR];
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
endmodule // ram_1536x39
|
endmodule // ram_1536x39
|
||||||
|
|
||||||
|
|
||||||
module ram_1024x39
|
module ram_1024x39
|
||||||
( input logic CLK,
|
( input logic CLK,
|
||||||
input logic [9:0] ADR,
|
input logic [9:0] ADR,
|
||||||
input logic [38:0] D,
|
input logic [38:0] D,
|
||||||
|
|
||||||
output logic [38:0] Q,
|
output logic [38:0] Q,
|
||||||
input logic WE );
|
input logic WE );
|
||||||
|
|
||||||
// behavior to be replaced by actual SRAM in VLE
|
// behavior to be replaced by actual SRAM in VLE
|
||||||
|
|
||||||
reg [38:0] ram_core [1023:0];
|
reg [38:0] ram_core [1023:0];
|
||||||
|
@ -200,19 +200,19 @@ module ram_1024x39
|
||||||
Q <= ram_core[ADR];
|
Q <= ram_core[ADR];
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
endmodule // ram_1024x39
|
endmodule // ram_1024x39
|
||||||
|
|
||||||
module ram_768x39
|
module ram_768x39
|
||||||
( input logic CLK,
|
( input logic CLK,
|
||||||
input logic [9:0] ADR,
|
input logic [9:0] ADR,
|
||||||
input logic [38:0] D,
|
input logic [38:0] D,
|
||||||
|
|
||||||
output logic [38:0] Q,
|
output logic [38:0] Q,
|
||||||
input logic WE );
|
input logic WE );
|
||||||
|
|
||||||
// behavior to be replaced by actual SRAM in VLE
|
// behavior to be replaced by actual SRAM in VLE
|
||||||
|
|
||||||
reg [38:0] ram_core [767:0];
|
reg [38:0] ram_core [767:0];
|
||||||
|
@ -223,20 +223,20 @@ module ram_768x39
|
||||||
Q <= ram_core[ADR];
|
Q <= ram_core[ADR];
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
endmodule // ram_768x39
|
endmodule // ram_768x39
|
||||||
|
|
||||||
|
|
||||||
module ram_512x39
|
module ram_512x39
|
||||||
( input logic CLK,
|
( input logic CLK,
|
||||||
input logic [8:0] ADR,
|
input logic [8:0] ADR,
|
||||||
input logic [38:0] D,
|
input logic [38:0] D,
|
||||||
|
|
||||||
output logic [38:0] Q,
|
output logic [38:0] Q,
|
||||||
input logic WE );
|
input logic WE );
|
||||||
|
|
||||||
// behavior to be replaced by actual SRAM in VLE
|
// behavior to be replaced by actual SRAM in VLE
|
||||||
|
|
||||||
reg [38:0] ram_core [511:0];
|
reg [38:0] ram_core [511:0];
|
||||||
|
@ -247,20 +247,20 @@ module ram_512x39
|
||||||
Q <= ram_core[ADR];
|
Q <= ram_core[ADR];
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
endmodule // ram_512x39
|
endmodule // ram_512x39
|
||||||
|
|
||||||
|
|
||||||
module ram_256x39
|
module ram_256x39
|
||||||
( input logic CLK,
|
( input logic CLK,
|
||||||
input logic [7:0] ADR,
|
input logic [7:0] ADR,
|
||||||
input logic [38:0] D,
|
input logic [38:0] D,
|
||||||
|
|
||||||
output logic [38:0] Q,
|
output logic [38:0] Q,
|
||||||
input logic WE );
|
input logic WE );
|
||||||
|
|
||||||
// behavior to be replaced by actual SRAM in VLE
|
// behavior to be replaced by actual SRAM in VLE
|
||||||
|
|
||||||
reg [38:0] ram_core [255:0];
|
reg [38:0] ram_core [255:0];
|
||||||
|
@ -271,20 +271,20 @@ module ram_256x39
|
||||||
Q <= ram_core[ADR];
|
Q <= ram_core[ADR];
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
endmodule // ram_512x39
|
endmodule // ram_512x39
|
||||||
|
|
||||||
|
|
||||||
module ram_128x39
|
module ram_128x39
|
||||||
( input logic CLK,
|
( input logic CLK,
|
||||||
input logic [6:0] ADR,
|
input logic [6:0] ADR,
|
||||||
input logic [38:0] D,
|
input logic [38:0] D,
|
||||||
|
|
||||||
output logic [38:0] Q,
|
output logic [38:0] Q,
|
||||||
input logic WE );
|
input logic WE );
|
||||||
|
|
||||||
// behavior to be replaced by actual SRAM in VLE
|
// behavior to be replaced by actual SRAM in VLE
|
||||||
|
|
||||||
reg [38:0] ram_core [127:0];
|
reg [38:0] ram_core [127:0];
|
||||||
|
@ -295,7 +295,7 @@ module ram_128x39
|
||||||
Q <= ram_core[ADR];
|
Q <= ram_core[ADR];
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
endmodule // ram_128x39
|
endmodule // ram_128x39
|
||||||
|
@ -303,7 +303,7 @@ endmodule // ram_128x39
|
||||||
//=========================================================================================================================
|
//=========================================================================================================================
|
||||||
//=================================== START OF TAGS =======================================================================
|
//=================================== START OF TAGS =======================================================================
|
||||||
// I CACHE TAGS
|
// I CACHE TAGS
|
||||||
module ram_1024x20
|
module ram_1024x20
|
||||||
( input logic CLK,
|
( input logic CLK,
|
||||||
|
|
||||||
input logic [9:0] ADR,
|
input logic [9:0] ADR,
|
||||||
|
@ -311,7 +311,7 @@ module ram_1024x20
|
||||||
|
|
||||||
output logic [19:0] Q,
|
output logic [19:0] Q,
|
||||||
input logic WE );
|
input logic WE );
|
||||||
|
|
||||||
// behavior to be replaced by actual SRAM in VLE
|
// behavior to be replaced by actual SRAM in VLE
|
||||||
|
|
||||||
reg [19:0] ram_core [1023:0];
|
reg [19:0] ram_core [1023:0];
|
||||||
|
@ -322,18 +322,18 @@ module ram_1024x20
|
||||||
Q <= ram_core[ADR];
|
Q <= ram_core[ADR];
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
endmodule // ram_1024x20
|
endmodule // ram_1024x20
|
||||||
|
|
||||||
module ram_512x20
|
module ram_512x20
|
||||||
( input logic CLK,
|
( input logic CLK,
|
||||||
input logic [8:0] ADR,
|
input logic [8:0] ADR,
|
||||||
input logic [19:0] D,
|
input logic [19:0] D,
|
||||||
|
|
||||||
output logic [19:0] Q,
|
output logic [19:0] Q,
|
||||||
input logic WE );
|
input logic WE );
|
||||||
|
|
||||||
// behavior to be replaced by actual SRAM in VLE
|
// behavior to be replaced by actual SRAM in VLE
|
||||||
|
|
||||||
reg [19:0] ram_core [511:0];
|
reg [19:0] ram_core [511:0];
|
||||||
|
@ -349,14 +349,14 @@ module ram_512x20
|
||||||
|
|
||||||
endmodule // ram_512x20
|
endmodule // ram_512x20
|
||||||
|
|
||||||
module ram_256x20
|
module ram_256x20
|
||||||
( input logic CLK,
|
( input logic CLK,
|
||||||
input logic [7:0] ADR,
|
input logic [7:0] ADR,
|
||||||
input logic [19:0] D,
|
input logic [19:0] D,
|
||||||
|
|
||||||
output logic [19:0] Q,
|
output logic [19:0] Q,
|
||||||
input logic WE );
|
input logic WE );
|
||||||
|
|
||||||
// behavior to be replaced by actual SRAM in VLE
|
// behavior to be replaced by actual SRAM in VLE
|
||||||
|
|
||||||
reg [19:0] ram_core [255:0];
|
reg [19:0] ram_core [255:0];
|
||||||
|
@ -371,14 +371,14 @@ module ram_256x20
|
||||||
|
|
||||||
endmodule // ram_256x20
|
endmodule // ram_256x20
|
||||||
|
|
||||||
module ram_128x20
|
module ram_128x20
|
||||||
( input logic CLK,
|
( input logic CLK,
|
||||||
input logic [6:0] ADR,
|
input logic [6:0] ADR,
|
||||||
input logic [19:0] D,
|
input logic [19:0] D,
|
||||||
|
|
||||||
output logic [19:0] Q,
|
output logic [19:0] Q,
|
||||||
input logic WE );
|
input logic WE );
|
||||||
|
|
||||||
// behavior to be replaced by actual SRAM in VLE
|
// behavior to be replaced by actual SRAM in VLE
|
||||||
|
|
||||||
reg [19:0] ram_core [127:0];
|
reg [19:0] ram_core [127:0];
|
||||||
|
@ -394,14 +394,14 @@ module ram_128x20
|
||||||
|
|
||||||
endmodule // ram_128x20
|
endmodule // ram_128x20
|
||||||
|
|
||||||
module ram_64x20
|
module ram_64x20
|
||||||
( input logic CLK,
|
( input logic CLK,
|
||||||
input logic [5:0] ADR,
|
input logic [5:0] ADR,
|
||||||
input logic [19:0] D,
|
input logic [19:0] D,
|
||||||
|
|
||||||
output logic [19:0] Q,
|
output logic [19:0] Q,
|
||||||
input logic WE );
|
input logic WE );
|
||||||
|
|
||||||
// behavior to be replaced by actual SRAM in VLE
|
// behavior to be replaced by actual SRAM in VLE
|
||||||
|
|
||||||
reg [19:0] ram_core [63:0];
|
reg [19:0] ram_core [63:0];
|
||||||
|
@ -421,14 +421,14 @@ endmodule // ram_64x20
|
||||||
|
|
||||||
|
|
||||||
// 4096 x 34
|
// 4096 x 34
|
||||||
module ram_4096x34
|
module ram_4096x34
|
||||||
( input logic CLK,
|
( input logic CLK,
|
||||||
input logic [11:0] ADR,
|
input logic [11:0] ADR,
|
||||||
input logic [33:0] D,
|
input logic [33:0] D,
|
||||||
|
|
||||||
output logic [33:0] Q,
|
output logic [33:0] Q,
|
||||||
input logic WE );
|
input logic WE );
|
||||||
|
|
||||||
// behavior to be replaced by actual SRAM in VLE
|
// behavior to be replaced by actual SRAM in VLE
|
||||||
|
|
||||||
reg [33:0] ram_core [4095:0];
|
reg [33:0] ram_core [4095:0];
|
||||||
|
@ -440,20 +440,20 @@ module ram_4096x34
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
endmodule // ram_4096x34
|
endmodule // ram_4096x34
|
||||||
|
|
||||||
// 2048x34
|
// 2048x34
|
||||||
module ram_2048x34
|
module ram_2048x34
|
||||||
( input logic CLK,
|
( input logic CLK,
|
||||||
input logic [10:0] ADR,
|
input logic [10:0] ADR,
|
||||||
input logic [33:0] D,
|
input logic [33:0] D,
|
||||||
|
|
||||||
output logic [33:0] Q,
|
output logic [33:0] Q,
|
||||||
input logic WE );
|
input logic WE );
|
||||||
|
|
||||||
// behavior to be replaced by actual SRAM in VLE
|
// behavior to be replaced by actual SRAM in VLE
|
||||||
|
|
||||||
reg [33:0] ram_core [2047:0];
|
reg [33:0] ram_core [2047:0];
|
||||||
|
@ -465,20 +465,20 @@ module ram_2048x34
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
endmodule // ram_2048x34
|
endmodule // ram_2048x34
|
||||||
|
|
||||||
// 1024x34
|
// 1024x34
|
||||||
module ram_1024x34
|
module ram_1024x34
|
||||||
( input logic CLK,
|
( input logic CLK,
|
||||||
input logic [9:0] ADR,
|
input logic [9:0] ADR,
|
||||||
input logic [33:0] D,
|
input logic [33:0] D,
|
||||||
|
|
||||||
output logic [33:0] Q,
|
output logic [33:0] Q,
|
||||||
input logic WE );
|
input logic WE );
|
||||||
|
|
||||||
// behavior to be replaced by actual SRAM in VLE
|
// behavior to be replaced by actual SRAM in VLE
|
||||||
|
|
||||||
reg [33:0] ram_core [1023:0];
|
reg [33:0] ram_core [1023:0];
|
||||||
|
@ -490,20 +490,20 @@ module ram_1024x34
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
endmodule // ram_1024x34
|
endmodule // ram_1024x34
|
||||||
|
|
||||||
// 512x34
|
// 512x34
|
||||||
module ram_512x34
|
module ram_512x34
|
||||||
( input logic CLK,
|
( input logic CLK,
|
||||||
input logic [8:0] ADR,
|
input logic [8:0] ADR,
|
||||||
input logic [33:0] D,
|
input logic [33:0] D,
|
||||||
|
|
||||||
output logic [33:0] Q,
|
output logic [33:0] Q,
|
||||||
input logic WE );
|
input logic WE );
|
||||||
|
|
||||||
// behavior to be replaced by actual SRAM in VLE
|
// behavior to be replaced by actual SRAM in VLE
|
||||||
|
|
||||||
reg [33:0] ram_core [511:0];
|
reg [33:0] ram_core [511:0];
|
||||||
|
@ -515,20 +515,20 @@ module ram_512x34
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
endmodule // ram_512x34
|
endmodule // ram_512x34
|
||||||
|
|
||||||
// 256x34
|
// 256x34
|
||||||
module ram_256x34
|
module ram_256x34
|
||||||
( input logic CLK,
|
( input logic CLK,
|
||||||
input logic [7:0] ADR,
|
input logic [7:0] ADR,
|
||||||
input logic [33:0] D,
|
input logic [33:0] D,
|
||||||
|
|
||||||
output logic [33:0] Q,
|
output logic [33:0] Q,
|
||||||
input logic WE );
|
input logic WE );
|
||||||
|
|
||||||
// behavior to be replaced by actual SRAM in VLE
|
// behavior to be replaced by actual SRAM in VLE
|
||||||
|
|
||||||
reg [33:0] ram_core [255:0];
|
reg [33:0] ram_core [255:0];
|
||||||
|
@ -540,20 +540,20 @@ module ram_256x34
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
endmodule // ram_256x34
|
endmodule // ram_256x34
|
||||||
|
|
||||||
// 128x34
|
// 128x34
|
||||||
module ram_128x34
|
module ram_128x34
|
||||||
( input logic CLK,
|
( input logic CLK,
|
||||||
input logic [6:0] ADR,
|
input logic [6:0] ADR,
|
||||||
input logic [33:0] D,
|
input logic [33:0] D,
|
||||||
|
|
||||||
output logic [33:0] Q,
|
output logic [33:0] Q,
|
||||||
input logic WE );
|
input logic WE );
|
||||||
|
|
||||||
// behavior to be replaced by actual SRAM in VLE
|
// behavior to be replaced by actual SRAM in VLE
|
||||||
|
|
||||||
reg [33:0] ram_core [127:0];
|
reg [33:0] ram_core [127:0];
|
||||||
|
@ -569,15 +569,15 @@ module ram_128x34
|
||||||
|
|
||||||
endmodule // ram_128x34
|
endmodule // ram_128x34
|
||||||
|
|
||||||
// 64x34
|
// 64x34
|
||||||
module ram_64x34
|
module ram_64x34
|
||||||
( input logic CLK,
|
( input logic CLK,
|
||||||
input logic [5:0] ADR,
|
input logic [5:0] ADR,
|
||||||
input logic [33:0] D,
|
input logic [33:0] D,
|
||||||
|
|
||||||
output logic [33:0] Q,
|
output logic [33:0] Q,
|
||||||
input logic WE );
|
input logic WE );
|
||||||
|
|
||||||
// behavior to be replaced by actual SRAM in VLE
|
// behavior to be replaced by actual SRAM in VLE
|
||||||
|
|
||||||
reg [33:0] ram_core [63:0];
|
reg [33:0] ram_core [63:0];
|
||||||
|
@ -595,16 +595,16 @@ endmodule // ram_64x34
|
||||||
|
|
||||||
// New SRAMS for ECC; ECC on 16b boundaries
|
// New SRAMS for ECC; ECC on 16b boundaries
|
||||||
|
|
||||||
// 4096x44
|
// 4096x44
|
||||||
module ram_4096x42
|
module ram_4096x42
|
||||||
( input logic CLK,
|
( input logic CLK,
|
||||||
input logic [11:0] ADR,
|
input logic [11:0] ADR,
|
||||||
input logic [41:0] D,
|
input logic [41:0] D,
|
||||||
|
|
||||||
output logic [41:0] Q,
|
output logic [41:0] Q,
|
||||||
|
|
||||||
input logic WE );
|
input logic WE );
|
||||||
|
|
||||||
// behavior to be replaced by actual SRAM in VLE
|
// behavior to be replaced by actual SRAM in VLE
|
||||||
|
|
||||||
reg [41:0] ram_core [4095:0];
|
reg [41:0] ram_core [4095:0];
|
||||||
|
@ -621,15 +621,15 @@ module ram_4096x42
|
||||||
endmodule // ram_4096x42
|
endmodule // ram_4096x42
|
||||||
|
|
||||||
|
|
||||||
// 2048x44
|
// 2048x44
|
||||||
module ram_2048x42
|
module ram_2048x42
|
||||||
( input logic CLK,
|
( input logic CLK,
|
||||||
input logic [10:0] ADR,
|
input logic [10:0] ADR,
|
||||||
input logic [41:0] D,
|
input logic [41:0] D,
|
||||||
|
|
||||||
output logic [41:0] Q,
|
output logic [41:0] Q,
|
||||||
input logic WE );
|
input logic WE );
|
||||||
|
|
||||||
// behavior to be replaced by actual SRAM in VLE
|
// behavior to be replaced by actual SRAM in VLE
|
||||||
|
|
||||||
reg [41:0] ram_core [2047:0];
|
reg [41:0] ram_core [2047:0];
|
||||||
|
@ -645,15 +645,15 @@ module ram_2048x42
|
||||||
|
|
||||||
endmodule // ram_2048x42
|
endmodule // ram_2048x42
|
||||||
|
|
||||||
// 1024x44
|
// 1024x44
|
||||||
module ram_1024x42
|
module ram_1024x42
|
||||||
( input logic CLK,
|
( input logic CLK,
|
||||||
input logic [9:0] ADR,
|
input logic [9:0] ADR,
|
||||||
input logic [41:0] D,
|
input logic [41:0] D,
|
||||||
|
|
||||||
output logic [41:0] Q,
|
output logic [41:0] Q,
|
||||||
input logic WE );
|
input logic WE );
|
||||||
|
|
||||||
// behavior to be replaced by actual SRAM in VLE
|
// behavior to be replaced by actual SRAM in VLE
|
||||||
|
|
||||||
reg [41:0] ram_core [1023:0];
|
reg [41:0] ram_core [1023:0];
|
||||||
|
@ -669,15 +669,15 @@ module ram_1024x42
|
||||||
endmodule // ram_1024x42
|
endmodule // ram_1024x42
|
||||||
|
|
||||||
|
|
||||||
// 512x44
|
// 512x44
|
||||||
module ram_512x42
|
module ram_512x42
|
||||||
( input logic CLK,
|
( input logic CLK,
|
||||||
input logic [8:0] ADR,
|
input logic [8:0] ADR,
|
||||||
input logic [41:0] D,
|
input logic [41:0] D,
|
||||||
|
|
||||||
output logic [41:0] Q,
|
output logic [41:0] Q,
|
||||||
input logic WE );
|
input logic WE );
|
||||||
|
|
||||||
// behavior to be replaced by actual SRAM in VLE
|
// behavior to be replaced by actual SRAM in VLE
|
||||||
|
|
||||||
reg [41:0] ram_core [511:0];
|
reg [41:0] ram_core [511:0];
|
||||||
|
@ -689,21 +689,21 @@ module ram_512x42
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
endmodule // ram_512x42
|
endmodule // ram_512x42
|
||||||
|
|
||||||
|
|
||||||
// 256x42
|
// 256x42
|
||||||
module ram_256x42
|
module ram_256x42
|
||||||
( input logic CLK,
|
( input logic CLK,
|
||||||
input logic [7:0] ADR,
|
input logic [7:0] ADR,
|
||||||
input logic [41:0] D,
|
input logic [41:0] D,
|
||||||
|
|
||||||
output logic [41:0] Q,
|
output logic [41:0] Q,
|
||||||
input logic WE );
|
input logic WE );
|
||||||
|
|
||||||
// behavior to be replaced by actual SRAM in VLE
|
// behavior to be replaced by actual SRAM in VLE
|
||||||
|
|
||||||
reg [41:0] ram_core [255:0];
|
reg [41:0] ram_core [255:0];
|
||||||
|
@ -715,20 +715,20 @@ module ram_256x42
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
endmodule // ram_256x42
|
endmodule // ram_256x42
|
||||||
|
|
||||||
// 128x42
|
// 128x42
|
||||||
module ram_128x42
|
module ram_128x42
|
||||||
( input logic CLK,
|
( input logic CLK,
|
||||||
input logic [6:0] ADR,
|
input logic [6:0] ADR,
|
||||||
input logic [41:0] D,
|
input logic [41:0] D,
|
||||||
|
|
||||||
output logic [41:0] Q,
|
output logic [41:0] Q,
|
||||||
input logic WE );
|
input logic WE );
|
||||||
|
|
||||||
// behavior to be replaced by actual SRAM in VLE
|
// behavior to be replaced by actual SRAM in VLE
|
||||||
|
|
||||||
reg [41:0] ram_core [127:0];
|
reg [41:0] ram_core [127:0];
|
||||||
|
@ -740,20 +740,20 @@ module ram_128x42
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
endmodule // ram_128x42
|
endmodule // ram_128x42
|
||||||
|
|
||||||
// 64x42
|
// 64x42
|
||||||
module ram_64x42
|
module ram_64x42
|
||||||
( input logic CLK,
|
( input logic CLK,
|
||||||
input logic [5:0] ADR,
|
input logic [5:0] ADR,
|
||||||
input logic [41:0] D,
|
input logic [41:0] D,
|
||||||
|
|
||||||
output logic [41:0] Q,
|
output logic [41:0] Q,
|
||||||
input logic WE );
|
input logic WE );
|
||||||
|
|
||||||
// behavior to be replaced by actual SRAM in VLE
|
// behavior to be replaced by actual SRAM in VLE
|
||||||
|
|
||||||
reg [41:0] ram_core [63:0];
|
reg [41:0] ram_core [63:0];
|
||||||
|
@ -772,8 +772,8 @@ endmodule // ram_64x42
|
||||||
|
|
||||||
// START TAGS
|
// START TAGS
|
||||||
|
|
||||||
// 1024x21
|
// 1024x21
|
||||||
module ram_1024x21
|
module ram_1024x21
|
||||||
( input logic CLK,
|
( input logic CLK,
|
||||||
input logic [9:0] ADR,
|
input logic [9:0] ADR,
|
||||||
input logic [20:0] D,
|
input logic [20:0] D,
|
||||||
|
@ -781,7 +781,7 @@ module ram_1024x21
|
||||||
output logic [20:0] Q,
|
output logic [20:0] Q,
|
||||||
|
|
||||||
input logic WE );
|
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 [1023:0];
|
reg [20:0] ram_core [1023:0];
|
||||||
|
@ -796,15 +796,15 @@ module ram_1024x21
|
||||||
|
|
||||||
endmodule // ram_1024x21
|
endmodule // ram_1024x21
|
||||||
|
|
||||||
// 512x21
|
// 512x21
|
||||||
module ram_512x21
|
module ram_512x21
|
||||||
( input logic CLK,
|
( input logic CLK,
|
||||||
input logic [8:0] ADR,
|
input logic [8:0] ADR,
|
||||||
input logic [20:0] D,
|
input logic [20:0] D,
|
||||||
|
|
||||||
output logic [20:0] Q,
|
output logic [20:0] Q,
|
||||||
input logic WE );
|
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 [511:0];
|
reg [20:0] ram_core [511:0];
|
||||||
|
@ -816,21 +816,21 @@ module ram_512x21
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
endmodule // ram_512x21
|
endmodule // ram_512x21
|
||||||
|
|
||||||
// 256x21
|
// 256x21
|
||||||
module ram_256x21
|
module ram_256x21
|
||||||
( input logic CLK,
|
( input logic CLK,
|
||||||
input logic [7:0] ADR,
|
input logic [7:0] ADR,
|
||||||
input logic [20:0] D,
|
input logic [20:0] D,
|
||||||
|
|
||||||
output logic [20:0] Q,
|
output logic [20:0] Q,
|
||||||
input logic WE );
|
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];
|
reg [20:0] ram_core [255:0];
|
||||||
|
|
||||||
|
@ -841,20 +841,20 @@ module ram_256x21
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
endmodule // ram_256x21
|
endmodule // ram_256x21
|
||||||
|
|
||||||
// 128x21
|
// 128x21
|
||||||
module ram_128x21
|
module ram_128x21
|
||||||
( input logic CLK,
|
( input logic CLK,
|
||||||
input logic [6:0] ADR,
|
input logic [6:0] ADR,
|
||||||
input logic [20:0] D,
|
input logic [20:0] D,
|
||||||
|
|
||||||
output logic [20:0] Q,
|
output logic [20:0] Q,
|
||||||
input logic WE );
|
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 [127:0];
|
reg [20:0] ram_core [127:0];
|
||||||
|
@ -866,13 +866,13 @@ module ram_128x21
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
endmodule // ram_128x21
|
endmodule // ram_128x21
|
||||||
|
|
||||||
// 64x21
|
// 64x21
|
||||||
module ram_64x21
|
module ram_64x21
|
||||||
( input logic CLK,
|
( input logic CLK,
|
||||||
input logic [5:0] ADR,
|
input logic [5:0] ADR,
|
||||||
input logic [20:0] D,
|
input logic [20:0] D,
|
||||||
|
@ -893,17 +893,17 @@ module ram_64x21
|
||||||
|
|
||||||
endmodule // ram_64x21
|
endmodule // ram_64x21
|
||||||
|
|
||||||
// New tag rams for ECC.
|
// New tag rams for ECC.
|
||||||
|
|
||||||
// 1024x25
|
// 1024x25
|
||||||
module ram_1024x25
|
module ram_1024x25
|
||||||
( input logic CLK,
|
( input logic CLK,
|
||||||
input logic [9:0] ADR,
|
input logic [9:0] ADR,
|
||||||
input logic [24:0] D,
|
input logic [24:0] D,
|
||||||
|
|
||||||
output logic [24:0] Q,
|
output logic [24:0] Q,
|
||||||
input logic WE );
|
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 [1023:0];
|
reg [24:0] ram_core [1023:0];
|
||||||
|
@ -915,13 +915,13 @@ module ram_1024x25
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
endmodule // ram_1024x25
|
endmodule // ram_1024x25
|
||||||
|
|
||||||
// 512x25
|
// 512x25
|
||||||
module ram_512x25
|
module ram_512x25
|
||||||
( input logic CLK,
|
( input logic CLK,
|
||||||
input logic [8:0] ADR,
|
input logic [8:0] ADR,
|
||||||
input logic [24:0] D,
|
input logic [24:0] D,
|
||||||
|
@ -929,7 +929,7 @@ module ram_512x25
|
||||||
output logic [24:0] Q,
|
output logic [24:0] Q,
|
||||||
|
|
||||||
input logic WE );
|
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 [511:0];
|
reg [24:0] ram_core [511:0];
|
||||||
|
@ -941,13 +941,13 @@ module ram_512x25
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
endmodule // ram_512x25
|
endmodule // ram_512x25
|
||||||
|
|
||||||
// 256x25
|
// 256x25
|
||||||
module ram_256x25
|
module ram_256x25
|
||||||
( input logic CLK,
|
( input logic CLK,
|
||||||
input logic [7:0] ADR,
|
input logic [7:0] ADR,
|
||||||
input logic [24:0] D,
|
input logic [24:0] D,
|
||||||
|
@ -955,8 +955,8 @@ module ram_256x25
|
||||||
output logic [24:0] Q,
|
output logic [24:0] Q,
|
||||||
|
|
||||||
input logic WE );
|
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];
|
reg [24:0] ram_core [255:0];
|
||||||
|
|
||||||
|
@ -967,13 +967,13 @@ module ram_256x25
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
endmodule // ram_256x25
|
endmodule // ram_256x25
|
||||||
|
|
||||||
// 128x25
|
// 128x25
|
||||||
module ram_128x25
|
module ram_128x25
|
||||||
( input logic CLK,
|
( input logic CLK,
|
||||||
input logic [6:0] ADR,
|
input logic [6:0] ADR,
|
||||||
input logic [24:0] D,
|
input logic [24:0] D,
|
||||||
|
@ -981,7 +981,7 @@ module ram_128x25
|
||||||
output logic [24:0] Q,
|
output logic [24:0] Q,
|
||||||
|
|
||||||
input logic WE );
|
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 [127:0];
|
reg [24:0] ram_core [127:0];
|
||||||
|
@ -993,13 +993,13 @@ module ram_128x25
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
endmodule // ram_128x25
|
endmodule // ram_128x25
|
||||||
|
|
||||||
// 64x25
|
// 64x25
|
||||||
module ram_64x25
|
module ram_64x25
|
||||||
( input logic CLK,
|
( input logic CLK,
|
||||||
input logic [5:0] ADR,
|
input logic [5:0] ADR,
|
||||||
input logic [24:0] D,
|
input logic [24:0] D,
|
||||||
|
@ -1019,7 +1019,7 @@ module ram_64x25
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
endmodule // ram_64x25
|
endmodule // ram_64x25
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
// Copyright 2019 Western Digital Corporation or its affiliates.
|
// Copyright 2019 Western Digital Corporation or its affiliates.
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "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 not use this file except in compliance with the License.
|
||||||
// You may obtain a copy of the License at
|
// You may obtain a copy of the License at
|
||||||
//
|
//
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
//
|
//
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
@ -16,53 +16,55 @@
|
||||||
//********************************************************************************
|
//********************************************************************************
|
||||||
// $Id$
|
// $Id$
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// Function: Top level file for load store unit
|
// Function: Top level file for load store unit
|
||||||
// Comments:
|
// Comments:
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// DC1 -> DC2 -> DC3 -> DC4 (Commit)
|
// DC1 -> DC2 -> DC3 -> DC4 (Commit)
|
||||||
//
|
//
|
||||||
//********************************************************************************
|
//********************************************************************************
|
||||||
|
|
||||||
module lsu
|
module lsu
|
||||||
import swerv_types::*;
|
import swerv_types::*;
|
||||||
(
|
(
|
||||||
|
|
||||||
input logic [31:0] i0_result_e4_eff, // I0 e4 result for e4 -> dc3 store forwarding
|
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] 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 [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 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_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_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_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
|
input logic dec_tlu_cancel_e4, // cancel the bus load in dc4 and reset the freeze
|
||||||
|
|
||||||
// chicken signals
|
// chicken signals
|
||||||
input logic dec_tlu_non_blocking_disable, // disable the non block
|
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_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_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 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_rs1_d, // address rs operand
|
||||||
input logic [31:0] exu_lsu_rs2_d, // store data
|
input logic [31:0] exu_lsu_rs2_d, // store data
|
||||||
input logic [11:0] dec_lsu_offset_d, // address offset operand
|
input logic [11:0] dec_lsu_offset_d, // address offset operand
|
||||||
|
|
||||||
input lsu_pkt_t lsu_p, // lsu control packet
|
input lsu_pkt_t lsu_p, // lsu control packet
|
||||||
input logic dec_i0_lsu_decode_d, // lsu is in i0
|
input logic dec_i0_lsu_decode_d, // lsu is in i0
|
||||||
input logic [31:0] dec_tlu_mrac_ff, // CSR for memory region control
|
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 [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 [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_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_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_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_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 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 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_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
|
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
|
output logic [31:0] lsu_imprecise_error_addr_any, // bus store imprecise error address
|
||||||
|
|
||||||
// Non-blocking loads
|
// 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 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 [`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 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 [`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_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 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 [`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 [31:0] lsu_nonblock_load_data, // Data of the non block load
|
||||||
|
|
||||||
output logic lsu_pmu_misaligned_dc3, // PMU : misaligned
|
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_misaligned, // PMU : misaligned access going to the bus
|
||||||
output logic lsu_pmu_bus_error, // PMU : bus sending error back
|
output logic lsu_pmu_bus_error, // PMU : bus sending error back
|
||||||
output logic lsu_pmu_bus_busy, // PMU : bus is not ready
|
output logic lsu_pmu_bus_busy, // PMU : bus is not ready
|
||||||
|
|
||||||
// Trigger signals
|
// Trigger signals
|
||||||
input trigger_pkt_t [3:0] trigger_pkt_any, // Trigger info from the decode
|
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
|
// DCCM ports
|
||||||
output logic dccm_wren, // DCCM write enable
|
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_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_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)
|
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_lo, // DCCM read data low bank
|
||||||
input logic [`RV_DCCM_FDATA_WIDTH-1:0] dccm_rd_data_hi, // DCCM read data hi 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 [3:0] lsu_axi_awcache,
|
||||||
output logic [2:0] lsu_axi_awprot,
|
output logic [2:0] lsu_axi_awprot,
|
||||||
output logic [3:0] lsu_axi_awqos,
|
output logic [3:0] lsu_axi_awqos,
|
||||||
|
|
||||||
output logic lsu_axi_wvalid,
|
output logic lsu_axi_wvalid,
|
||||||
input logic lsu_axi_wready,
|
input logic lsu_axi_wready,
|
||||||
output logic [63:0] lsu_axi_wdata,
|
output logic [63:0] lsu_axi_wdata,
|
||||||
output logic [7:0] lsu_axi_wstrb,
|
output logic [7:0] lsu_axi_wstrb,
|
||||||
output logic lsu_axi_wlast,
|
output logic lsu_axi_wlast,
|
||||||
|
|
||||||
input logic lsu_axi_bvalid,
|
input logic lsu_axi_bvalid,
|
||||||
output logic lsu_axi_bready,
|
output logic lsu_axi_bready,
|
||||||
input logic [1:0] lsu_axi_bresp,
|
input logic [1:0] lsu_axi_bresp,
|
||||||
input logic [`RV_LSU_BUS_TAG-1:0] lsu_axi_bid,
|
input logic [`RV_LSU_BUS_TAG-1:0] lsu_axi_bid,
|
||||||
|
|
||||||
// AXI Read Channels
|
// AXI Read Channels
|
||||||
output logic lsu_axi_arvalid,
|
output logic lsu_axi_arvalid,
|
||||||
input logic lsu_axi_arready,
|
input logic lsu_axi_arready,
|
||||||
output logic [`RV_LSU_BUS_TAG-1:0] lsu_axi_arid,
|
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 [3:0] lsu_axi_arcache,
|
||||||
output logic [2:0] lsu_axi_arprot,
|
output logic [2:0] lsu_axi_arprot,
|
||||||
output logic [3:0] lsu_axi_arqos,
|
output logic [3:0] lsu_axi_arqos,
|
||||||
|
|
||||||
input logic lsu_axi_rvalid,
|
input logic lsu_axi_rvalid,
|
||||||
output logic lsu_axi_rready,
|
output logic lsu_axi_rready,
|
||||||
input logic [`RV_LSU_BUS_TAG-1:0] lsu_axi_rid,
|
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_axi_rlast,
|
||||||
|
|
||||||
input logic lsu_bus_clk_en, // external drives a clock_en to control bus ratio
|
input logic lsu_bus_clk_en, // external drives a clock_en to control bus ratio
|
||||||
|
|
||||||
// DMA slave
|
// DMA slave
|
||||||
input logic dma_dccm_req, // DMA read/write to dccm
|
input logic dma_dccm_req, // DMA read/write to dccm
|
||||||
input logic [31:0] dma_mem_addr, // DMA address
|
input logic [31:0] dma_mem_addr, // DMA address
|
||||||
|
@ -171,15 +173,15 @@ module lsu
|
||||||
|
|
||||||
input logic clk_override, // Disable clock gating
|
input logic clk_override, // Disable clock gating
|
||||||
input logic scan_mode, // scan
|
input logic scan_mode, // scan
|
||||||
input logic clk,
|
input logic clk,
|
||||||
input logic free_clk,
|
input logic free_clk,
|
||||||
input logic rst_l
|
input logic rst_l
|
||||||
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
`include "global.h"
|
`include "global.h"
|
||||||
|
|
||||||
logic lsu_dccm_rden_dc3;
|
logic lsu_dccm_rden_dc3;
|
||||||
logic [63:0] store_data_dc2;
|
logic [63:0] store_data_dc2;
|
||||||
logic [63:0] store_data_dc3;
|
logic [63:0] store_data_dc3;
|
||||||
|
@ -191,7 +193,7 @@ module lsu
|
||||||
logic single_ecc_error_hi_dc3, single_ecc_error_lo_dc3;
|
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_single_ecc_error_dc3, lsu_single_ecc_error_dc4, lsu_single_ecc_error_dc5;
|
||||||
logic lsu_double_ecc_error_dc3;
|
logic lsu_double_ecc_error_dc3;
|
||||||
|
|
||||||
logic [31:0] dccm_data_hi_dc3;
|
logic [31:0] dccm_data_hi_dc3;
|
||||||
logic [31:0] dccm_data_lo_dc3;
|
logic [31:0] dccm_data_lo_dc3;
|
||||||
logic [6:0] dccm_data_ecc_hi_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_dc3;
|
||||||
logic [31:0] lsu_ld_data_corr_dc3;
|
logic [31:0] lsu_ld_data_corr_dc3;
|
||||||
logic [31:0] picm_mask_data_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] 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;
|
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;
|
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;
|
logic lsu_i0_valid_dc1, lsu_i0_valid_dc2, lsu_i0_valid_dc3, lsu_i0_valid_dc4, lsu_i0_valid_dc5;
|
||||||
|
|
||||||
// Store Buffer signals
|
// Store Buffer signals
|
||||||
logic isldst_dc1, dccm_ldst_dc2, dccm_ldst_dc3;
|
logic isldst_dc1, dccm_ldst_dc2, dccm_ldst_dc3;
|
||||||
logic store_stbuf_reqvld_dc3;
|
logic store_stbuf_reqvld_dc3;
|
||||||
|
@ -226,7 +228,7 @@ module lsu
|
||||||
logic [LSU_SB_BITS-1:0] stbuf_addr_any;
|
logic [LSU_SB_BITS-1:0] stbuf_addr_any;
|
||||||
logic [DCCM_DATA_WIDTH-1:0] stbuf_data_any;
|
logic [DCCM_DATA_WIDTH-1:0] stbuf_data_any;
|
||||||
logic [(DCCM_FDATA_WIDTH-DCCM_DATA_WIDTH-1):0] stbuf_ecc_any;
|
logic [(DCCM_FDATA_WIDTH-DCCM_DATA_WIDTH-1):0] stbuf_ecc_any;
|
||||||
|
|
||||||
logic lsu_cmpen_dc2;
|
logic lsu_cmpen_dc2;
|
||||||
logic [DCCM_DATA_WIDTH-1:0] stbuf_fwddata_hi_dc3;
|
logic [DCCM_DATA_WIDTH-1:0] stbuf_fwddata_hi_dc3;
|
||||||
logic [DCCM_DATA_WIDTH-1:0] stbuf_fwddata_lo_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 [DCCM_BYTE_WIDTH-1:0] stbuf_fwdbyteen_lo_dc3;
|
||||||
|
|
||||||
logic lsu_stbuf_commit_any;
|
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_nodma_empty_any; // Store Buffer is empty except dma writes
|
||||||
logic lsu_stbuf_full_any;
|
logic lsu_stbuf_full_any;
|
||||||
|
|
||||||
|
@ -247,53 +249,53 @@ module lsu
|
||||||
logic [31:0] bus_read_data_dc3;
|
logic [31:0] bus_read_data_dc3;
|
||||||
logic ld_bus_error_dc3;
|
logic ld_bus_error_dc3;
|
||||||
logic [31:0] ld_bus_error_addr_dc3;
|
logic [31:0] ld_bus_error_addr_dc3;
|
||||||
|
|
||||||
logic flush_dc2_up, flush_dc3, flush_dc4, flush_dc5, flush_prior_dc5;
|
logic flush_dc2_up, flush_dc3, flush_dc4, flush_dc5, flush_prior_dc5;
|
||||||
logic is_sideeffects_dc2, is_sideeffects_dc3;
|
logic is_sideeffects_dc2, is_sideeffects_dc3;
|
||||||
logic ldst_nodma_dc1todc3;
|
logic ldst_nodma_dc1todc3;
|
||||||
|
|
||||||
|
|
||||||
// Clocks
|
// Clocks
|
||||||
logic lsu_c1_dc3_clk, lsu_c1_dc4_clk, lsu_c1_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_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_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_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_stbuf_c1_clk;
|
||||||
logic lsu_bus_ibuf_c1_clk, lsu_bus_obuf_c1_clk, lsu_bus_buf_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_dccm_c1_dc3_clk, lsu_pic_c1_dc3_clken;
|
||||||
logic lsu_busm_clk;
|
logic lsu_busm_clk;
|
||||||
logic lsu_free_c2_clk;
|
logic lsu_free_c2_clk;
|
||||||
|
|
||||||
|
|
||||||
lsu_lsc_ctl lsu_lsc_ctl(.*);
|
lsu_lsc_ctl lsu_lsc_ctl(.*);
|
||||||
|
|
||||||
// block stores in decode - for either bus or stbuf reasons
|
// 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_store_stall_any = lsu_stbuf_full_any | lsu_bus_buffer_full_any;
|
||||||
assign lsu_load_stall_any = lsu_bus_buffer_full_any;
|
assign lsu_load_stall_any = lsu_bus_buffer_full_any;
|
||||||
|
|
||||||
// Ready to accept dma trxns
|
// 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
|
// 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 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);
|
assign dccm_ready = ~(lsu_p.valid | lsu_stbuf_full_any | lsu_freeze_dc3 | ldst_nodma_dc1todc3);
|
||||||
|
|
||||||
// Generate per cycle flush signals
|
// Generate per cycle flush signals
|
||||||
assign flush_dc2_up = flush_final_e3 | i0_flush_final_e3 | dec_tlu_flush_lower_wb;
|
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_dc3 = (flush_final_e3 & i0_flush_final_e3) | dec_tlu_flush_lower_wb;
|
||||||
assign flush_dc4 = 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_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
|
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
|
// 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_bus_buffer_empty_any & lsu_stbuf_empty_any;
|
||||||
|
|
||||||
// lsu halt idle. This is used for entering the halt mode
|
// 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
|
// 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
|
// 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) |
|
assign lsu_halt_idle_any = ~((lsu_pkt_dc1.valid & ~lsu_pkt_dc1.dma) |
|
||||||
(lsu_pkt_dc2.valid & ~lsu_pkt_dc2.dma) |
|
(lsu_pkt_dc2.valid & ~lsu_pkt_dc2.dma) |
|
||||||
(lsu_pkt_dc3.valid & ~lsu_pkt_dc3.dma) |
|
(lsu_pkt_dc3.valid & ~lsu_pkt_dc3.dma) |
|
||||||
(lsu_pkt_dc4.valid & ~lsu_pkt_dc4.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 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_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);
|
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
|
// 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);
|
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
|
// 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])));
|
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_dccm_ctl dccm_ctl (
|
||||||
.lsu_addr_dc1(lsu_addr_dc1[31:0]),
|
.lsu_addr_dc1(lsu_addr_dc1[31:0]),
|
||||||
.end_addr_dc1(end_addr_dc1[DCCM_BITS-1:0]),
|
.end_addr_dc1(end_addr_dc1[DCCM_BITS-1:0]),
|
||||||
.lsu_addr_dc3(lsu_addr_dc3[DCCM_BITS-1:0]),
|
.lsu_addr_dc3(lsu_addr_dc3[DCCM_BITS-1:0]),
|
||||||
.*
|
.*
|
||||||
);
|
);
|
||||||
|
|
||||||
lsu_stbuf stbuf(
|
lsu_stbuf stbuf(
|
||||||
.lsu_addr_dc1(lsu_addr_dc1[LSU_SB_BITS-1:0]),
|
.lsu_addr_dc1(lsu_addr_dc1[LSU_SB_BITS-1:0]),
|
||||||
.end_addr_dc1(end_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]),
|
.lsu_addr_dc3(lsu_addr_dc3[LSU_SB_BITS-1:0]),
|
||||||
.end_addr_dc3(end_addr_dc3[LSU_SB_BITS-1:0]),
|
.end_addr_dc3(end_addr_dc3[LSU_SB_BITS-1:0]),
|
||||||
.*
|
.*
|
||||||
|
|
||||||
);
|
);
|
||||||
|
|
||||||
lsu_ecc ecc (
|
lsu_ecc ecc (
|
||||||
.lsu_addr_dc3(lsu_addr_dc3[DCCM_BITS-1:0]),
|
.lsu_addr_dc3(lsu_addr_dc3[DCCM_BITS-1:0]),
|
||||||
.end_addr_dc3(end_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]),
|
.store_data_dc3(store_data_dc3[31:0]),
|
||||||
.*
|
.*
|
||||||
);
|
);
|
||||||
|
|
||||||
// Clk domain
|
// Clk domain
|
||||||
lsu_clkdomain clkdomain (.*);
|
lsu_clkdomain clkdomain (.*);
|
||||||
|
|
||||||
// Bus interface
|
// Bus interface
|
||||||
lsu_bus_intf bus_intf (.*);
|
lsu_bus_intf bus_intf (.*);
|
||||||
|
|
||||||
//Flops
|
//Flops
|
||||||
//rvdffs #(1) lsu_i0_valid_dc1ff (.*, .din(dec_i0_lsu_decode_d), .dout(lsu_i0_valid_dc1), .en(~lsu_freeze_dc3));
|
//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));
|
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_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_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_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));
|
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
|
`ifdef ASSERT_ON
|
||||||
logic [8:0] store_data_bypass_sel;
|
logic [8:0] store_data_bypass_sel;
|
||||||
assign store_data_bypass_sel[8:0] = {lsu_p.store_data_bypass_c1,
|
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]};
|
lsu_p.store_data_bypass_e4_c3[1:0]};
|
||||||
assert_store_data_bypass_onehot: assert #0 ($onehot0(store_data_bypass_sel[8: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_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_dccmen: assert #0 ($onehot0({(picm_rden | picm_mken),dccm_rden}));
|
||||||
assert_picm_wren_and_dccmen: assert #0 ($onehot0({picm_wren, dccm_wren}));
|
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);
|
//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
|
assert_exception_no_lsu_flush: assert property (exception_no_lsu_flush) else
|
||||||
$display("No flush within 2 cycles of exception");
|
$display("No flush within 2 cycles of exception");
|
||||||
`endif
|
`endif
|
||||||
|
|
||||||
endmodule // lsu
|
endmodule // lsu
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
// Copyright 2019 Western Digital Corporation or its affiliates.
|
// Copyright 2019 Western Digital Corporation or its affiliates.
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "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 not use this file except in compliance with the License.
|
||||||
// You may obtain a copy of the License at
|
// You may obtain a copy of the License at
|
||||||
//
|
//
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
//
|
//
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
@ -16,13 +16,13 @@
|
||||||
//********************************************************************************
|
//********************************************************************************
|
||||||
// $Id$
|
// $Id$
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// Owner:
|
// Owner:
|
||||||
// Function: Checks the memory map for the address
|
// Function: Checks the memory map for the address
|
||||||
// Comments:
|
// Comments:
|
||||||
//
|
//
|
||||||
//********************************************************************************
|
//********************************************************************************
|
||||||
module lsu_addrcheck
|
module lsu_addrcheck
|
||||||
import swerv_types::*;
|
import swerv_types::*;
|
||||||
(
|
(
|
||||||
input logic lsu_freeze_c2_dc2_clk, // clock
|
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 lsu_pkt_t lsu_pkt_dc1, // packet in dc1
|
||||||
input logic [31:0] dec_tlu_mrac_ff, // CSR read
|
input logic [31:0] dec_tlu_mrac_ff, // CSR read
|
||||||
|
|
||||||
|
|
||||||
output logic is_sideeffects_dc2, // is sideffects space
|
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_dccm_dc1, // address in dccm
|
||||||
output logic addr_in_pic_dc1, // address in pic
|
output logic addr_in_pic_dc1, // address in pic
|
||||||
output logic addr_external_dc1, // address in external
|
output logic addr_external_dc1, // address in external
|
||||||
|
|
||||||
output logic access_fault_dc1, // access fault
|
output logic access_fault_dc1, // access fault
|
||||||
output logic misaligned_fault_dc1, // misaligned
|
output logic misaligned_fault_dc1, // misaligned
|
||||||
|
|
||||||
input logic scan_mode
|
input logic scan_mode
|
||||||
);
|
);
|
||||||
|
|
||||||
`include "global.h"
|
`include "global.h"
|
||||||
|
|
||||||
localparam DCCM_REGION = `RV_DCCM_REGION;
|
localparam DCCM_REGION = `RV_DCCM_REGION;
|
||||||
localparam PIC_REGION = `RV_PIC_REGION;
|
localparam PIC_REGION = `RV_PIC_REGION;
|
||||||
localparam ICCM_REGION = `RV_ICCM_REGION;
|
localparam ICCM_REGION = `RV_ICCM_REGION;
|
||||||
|
@ -58,13 +58,13 @@ module lsu_addrcheck
|
||||||
`else
|
`else
|
||||||
localparam ICCM_ENABLE = 1'b0;
|
localparam ICCM_ENABLE = 1'b0;
|
||||||
`endif
|
`endif
|
||||||
|
|
||||||
`ifdef RV_DCCM_ENABLE
|
`ifdef RV_DCCM_ENABLE
|
||||||
localparam DCCM_ENABLE = 1'b1;
|
localparam DCCM_ENABLE = 1'b1;
|
||||||
`else
|
`else
|
||||||
localparam DCCM_ENABLE = 1'b0;
|
localparam DCCM_ENABLE = 1'b0;
|
||||||
`endif
|
`endif
|
||||||
|
|
||||||
logic is_sideeffects_dc1, is_aligned_dc1;
|
logic is_sideeffects_dc1, is_aligned_dc1;
|
||||||
logic start_addr_in_dccm_dc1, end_addr_in_dccm_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;
|
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 [4:0] csr_idx;
|
||||||
logic addr_in_iccm;
|
logic addr_in_iccm;
|
||||||
logic non_dccm_access_ok;
|
logic non_dccm_access_ok;
|
||||||
|
|
||||||
if (DCCM_ENABLE == 1) begin: Gen_dccm_enable
|
if (DCCM_ENABLE == 1) begin: Gen_dccm_enable
|
||||||
// Start address check
|
// Start address check
|
||||||
rvrangecheck #(.CCM_SADR(`RV_DCCM_SADR),
|
rvrangecheck #(.CCM_SADR(`RV_DCCM_SADR),
|
||||||
|
@ -82,7 +82,7 @@ module lsu_addrcheck
|
||||||
.in_range(start_addr_in_dccm_dc1),
|
.in_range(start_addr_in_dccm_dc1),
|
||||||
.in_region(start_addr_in_dccm_region_dc1)
|
.in_region(start_addr_in_dccm_region_dc1)
|
||||||
);
|
);
|
||||||
|
|
||||||
// End address check
|
// End address check
|
||||||
rvrangecheck #(.CCM_SADR(`RV_DCCM_SADR),
|
rvrangecheck #(.CCM_SADR(`RV_DCCM_SADR),
|
||||||
.CCM_SIZE(`RV_DCCM_SIZE)) end_addr_dccm_rangecheck (
|
.CCM_SIZE(`RV_DCCM_SIZE)) end_addr_dccm_rangecheck (
|
||||||
|
@ -98,10 +98,10 @@ module lsu_addrcheck
|
||||||
end
|
end
|
||||||
if (ICCM_ENABLE == 1) begin : check_iccm
|
if (ICCM_ENABLE == 1) begin : check_iccm
|
||||||
assign addr_in_iccm = (start_addr_dc1[31:28] == ICCM_REGION);
|
assign addr_in_iccm = (start_addr_dc1[31:28] == ICCM_REGION);
|
||||||
end
|
end
|
||||||
else begin
|
else begin
|
||||||
assign addr_in_iccm = 1'b0;
|
assign addr_in_iccm = 1'b0;
|
||||||
end
|
end
|
||||||
// PIC memory check
|
// PIC memory check
|
||||||
// Start address check
|
// Start address check
|
||||||
rvrangecheck #(.CCM_SADR(`RV_PIC_BASE_ADDR),
|
rvrangecheck #(.CCM_SADR(`RV_PIC_BASE_ADDR),
|
||||||
|
@ -110,7 +110,7 @@ module lsu_addrcheck
|
||||||
.in_range(start_addr_in_pic_dc1),
|
.in_range(start_addr_in_pic_dc1),
|
||||||
.in_region(start_addr_in_pic_region_dc1)
|
.in_region(start_addr_in_pic_region_dc1)
|
||||||
);
|
);
|
||||||
|
|
||||||
// End address check
|
// End address check
|
||||||
rvrangecheck #(.CCM_SADR(`RV_PIC_BASE_ADDR),
|
rvrangecheck #(.CCM_SADR(`RV_PIC_BASE_ADDR),
|
||||||
.CCM_SIZE(`RV_PIC_SIZE)) end_addr_pic_rangecheck (
|
.CCM_SIZE(`RV_PIC_SIZE)) end_addr_pic_rangecheck (
|
||||||
|
@ -119,12 +119,12 @@ module lsu_addrcheck
|
||||||
.in_region(end_addr_in_pic_region_dc1)
|
.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_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_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_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 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)) |
|
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.half & (start_addr_dc1[0] == 1'b0)) |
|
||||||
lsu_pkt_dc1.by;
|
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_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_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_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_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_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)) |
|
(`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
|
// 4. Ld/St access to picm are not word aligned
|
||||||
// 5. Address not in protected space or dccm/pic region
|
// 5. Address not in protected space or dccm/pic region
|
||||||
if (DCCM_REGION == PIC_REGION) begin
|
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)) |
|
(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))) |
|
((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;
|
(~start_addr_in_dccm_region_dc1 & ~non_dccm_access_ok)) & lsu_pkt_dc1.valid & ~lsu_pkt_dc1.dma;
|
||||||
end else begin
|
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) |
|
(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) |
|
(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))) |
|
((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;
|
(~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
|
end
|
||||||
|
|
||||||
// Misaligned happens due to 2 reasons
|
// Misaligned happens due to 2 reasons
|
||||||
// 1. Region cross
|
// 1. Region cross
|
||||||
// 2. sideeffects access which are not aligned
|
// 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;
|
(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_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), .*);
|
rvdff #(.WIDTH(1)) is_sideeffects_dc3ff (.din(is_sideeffects_dc2), .dout(is_sideeffects_dc3), .clk(lsu_freeze_c2_dc3_clk), .*);
|
||||||
|
|
||||||
endmodule // lsu_addrcheck
|
endmodule // lsu_addrcheck
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
// Copyright 2019 Western Digital Corporation or its affiliates.
|
// Copyright 2019 Western Digital Corporation or its affiliates.
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "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 not use this file except in compliance with the License.
|
||||||
// You may obtain a copy of the License at
|
// You may obtain a copy of the License at
|
||||||
//
|
//
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
//
|
//
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
@ -16,8 +16,8 @@
|
||||||
//********************************************************************************
|
//********************************************************************************
|
||||||
// $Id$
|
// $Id$
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// Owner:
|
// Owner:
|
||||||
// Function: lsu interface with interface queue
|
// Function: lsu interface with interface queue
|
||||||
// Comments:
|
// Comments:
|
||||||
//
|
//
|
||||||
|
@ -30,13 +30,13 @@ function automatic logic [2:0] f_Enc8to3;
|
||||||
logic [2:0] Enc_value;
|
logic [2:0] Enc_value;
|
||||||
Enc_value[0] = Dec_value[1] | Dec_value[3] | Dec_value[5] | Dec_value[7];
|
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[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];
|
return Enc_value[2:0];
|
||||||
endfunction // f_Enc8to3
|
endfunction // f_Enc8to3
|
||||||
|
|
||||||
|
|
||||||
module lsu_bus_buffer
|
module lsu_bus_buffer
|
||||||
import swerv_types::*;
|
import swerv_types::*;
|
||||||
(
|
(
|
||||||
input logic clk,
|
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_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_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
|
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
|
// 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_dc4_clk,
|
||||||
input logic lsu_c1_dc5_clk,
|
input logic lsu_c1_dc5_clk,
|
||||||
input logic lsu_c2_dc3_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_bus_buf_c1_clk,
|
||||||
input logic lsu_free_c2_clk,
|
input logic lsu_free_c2_clk,
|
||||||
input logic lsu_busm_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_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_dc2, // lsu packet flowing down the pipe
|
||||||
input lsu_pkt_t lsu_pkt_dc3, // 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_dc4, // bus request is in dc4
|
||||||
output logic lsu_busreq_dc5, // bus request is in dc5
|
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 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_dc3, // flush
|
||||||
input logic flush_dc4, // flush
|
input logic flush_dc4, // flush
|
||||||
input logic flush_dc5, // 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_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_dc4, // load/store is unaligned at 32 bit boundary
|
||||||
input logic ldst_dual_dc5, // 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,
|
input logic [7:0] ldst_byteen_ext_dc2,
|
||||||
|
|
||||||
output logic ld_freeze_dc3, // load goes to external and asserts freeze
|
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_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_full_any, // bus buffer is full
|
||||||
output logic lsu_bus_buffer_empty_any, // bus buffer is empty
|
output logic lsu_bus_buffer_empty_any, // bus buffer is empty
|
||||||
|
|
||||||
output logic ld_bus_error_dc3, // bus error in dc3
|
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 [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
|
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 [`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 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 [`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_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 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 [`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 [31:0] lsu_nonblock_load_data, // Data of the non block load
|
||||||
|
|
||||||
// PMU events
|
// PMU events
|
||||||
output logic lsu_pmu_bus_trxn,
|
output logic lsu_pmu_bus_trxn,
|
||||||
output logic lsu_pmu_bus_misaligned,
|
output logic lsu_pmu_bus_misaligned,
|
||||||
output logic lsu_pmu_bus_error,
|
output logic lsu_pmu_bus_error,
|
||||||
output logic lsu_pmu_bus_busy,
|
output logic lsu_pmu_bus_busy,
|
||||||
|
|
||||||
// AXI Write Channels
|
// AXI Write Channels
|
||||||
output logic lsu_axi_awvalid,
|
output logic lsu_axi_awvalid,
|
||||||
input logic lsu_axi_awready,
|
input logic lsu_axi_awready,
|
||||||
|
@ -147,19 +147,19 @@ module lsu_bus_buffer
|
||||||
output logic [3:0] lsu_axi_awcache,
|
output logic [3:0] lsu_axi_awcache,
|
||||||
output logic [2:0] lsu_axi_awprot,
|
output logic [2:0] lsu_axi_awprot,
|
||||||
output logic [3:0] lsu_axi_awqos,
|
output logic [3:0] lsu_axi_awqos,
|
||||||
|
|
||||||
output logic lsu_axi_wvalid,
|
output logic lsu_axi_wvalid,
|
||||||
input logic lsu_axi_wready,
|
input logic lsu_axi_wready,
|
||||||
output logic [63:0] lsu_axi_wdata,
|
output logic [63:0] lsu_axi_wdata,
|
||||||
output logic [7:0] lsu_axi_wstrb,
|
output logic [7:0] lsu_axi_wstrb,
|
||||||
output logic lsu_axi_wlast,
|
output logic lsu_axi_wlast,
|
||||||
|
|
||||||
input logic lsu_axi_bvalid,
|
input logic lsu_axi_bvalid,
|
||||||
output logic lsu_axi_bready,
|
output logic lsu_axi_bready,
|
||||||
input logic [1:0] lsu_axi_bresp,
|
input logic [1:0] lsu_axi_bresp,
|
||||||
input logic [`RV_LSU_BUS_TAG-1:0] lsu_axi_bid,
|
input logic [`RV_LSU_BUS_TAG-1:0] lsu_axi_bid,
|
||||||
|
|
||||||
// AXI Read Channels
|
// AXI Read Channels
|
||||||
output logic lsu_axi_arvalid,
|
output logic lsu_axi_arvalid,
|
||||||
input logic lsu_axi_arready,
|
input logic lsu_axi_arready,
|
||||||
output logic [`RV_LSU_BUS_TAG-1:0] lsu_axi_arid,
|
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 [3:0] lsu_axi_arcache,
|
||||||
output logic [2:0] lsu_axi_arprot,
|
output logic [2:0] lsu_axi_arprot,
|
||||||
output logic [3:0] lsu_axi_arqos,
|
output logic [3:0] lsu_axi_arqos,
|
||||||
|
|
||||||
input logic lsu_axi_rvalid,
|
input logic lsu_axi_rvalid,
|
||||||
output logic lsu_axi_rready,
|
output logic lsu_axi_rready,
|
||||||
input logic [`RV_LSU_BUS_TAG-1:0] lsu_axi_rid,
|
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 = 8; // This can be only power of 2
|
||||||
localparam TIMER_LOG2 = (TIMER < 2) ? 1 : $clog2(TIMER);
|
localparam TIMER_LOG2 = (TIMER < 2) ? 1 : $clog2(TIMER);
|
||||||
localparam TIMER_MAX = (TIMER == 0) ? TIMER_LOG2'(0) : TIMER_LOG2'(TIMER - 1); // Maximum value of 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 [3:0] ldst_byteen_hi_dc2, ldst_byteen_lo_dc2;
|
||||||
logic [DEPTH-1:0] ld_addr_hitvec_lo, ld_addr_hitvec_hi;
|
logic [DEPTH-1:0] ld_addr_hitvec_lo, ld_addr_hitvec_hi;
|
||||||
logic [3:0][DEPTH-1:0] ld_byte_hitvec_lo, ld_byte_hitvec_hi;
|
logic [3:0][DEPTH-1:0] ld_byte_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 [3:0] ldst_byteen_hi_dc5, ldst_byteen_lo_dc5;
|
||||||
logic [31:0] store_data_hi_dc5, store_data_lo_dc5;
|
logic [31:0] store_data_hi_dc5, store_data_lo_dc5;
|
||||||
logic ldst_samedw_dc5;
|
logic ldst_samedw_dc5;
|
||||||
|
|
||||||
logic lsu_nonblock_load_valid_dc4,lsu_nonblock_load_valid_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 [31:0] lsu_nonblock_load_data_hi, lsu_nonblock_load_data_lo, lsu_nonblock_data_unalgn;
|
||||||
logic [1:0] lsu_nonblock_addr_offset;
|
logic [1:0] lsu_nonblock_addr_offset;
|
||||||
|
@ -222,7 +222,7 @@ module lsu_bus_buffer
|
||||||
logic ld_precise_bus_error;
|
logic ld_precise_bus_error;
|
||||||
logic [DEPTH_LOG2-1:0] lsu_imprecise_error_load_tag;
|
logic [DEPTH_LOG2-1:0] lsu_imprecise_error_load_tag;
|
||||||
logic [31:0] ld_block_bus_data;
|
logic [31:0] ld_block_bus_data;
|
||||||
|
|
||||||
logic [DEPTH-1:0] CmdPtr0Dec, CmdPtr1Dec;
|
logic [DEPTH-1:0] CmdPtr0Dec, CmdPtr1Dec;
|
||||||
logic [DEPTH_LOG2-1:0] CmdPtr0, CmdPtr1;
|
logic [DEPTH_LOG2-1:0] CmdPtr0, CmdPtr1;
|
||||||
logic [DEPTH_LOG2-1:0] WrPtr0_dc3, WrPtr0_dc4, WrPtr0_dc5;
|
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 [3:0] buf_numvld_any, buf_numvld_wrcmd_any, buf_numvld_pend_any, buf_numvld_cmd_any;
|
||||||
logic bus_sideeffect_pend;
|
logic bus_sideeffect_pend;
|
||||||
logic bus_coalescing_disable;
|
logic bus_coalescing_disable;
|
||||||
|
|
||||||
logic ld_freeze_en, ld_freeze_rst;
|
logic ld_freeze_en, ld_freeze_rst;
|
||||||
logic FreezePtrEn;
|
logic FreezePtrEn;
|
||||||
logic [DEPTH_LOG2-1:0] FreezePtr;
|
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_cmd_sent, bus_cmd_ready;
|
||||||
logic bus_wcmd_sent, bus_wdata_sent;
|
logic bus_wcmd_sent, bus_wdata_sent;
|
||||||
logic bus_rsp_read, bus_rsp_write;
|
logic bus_rsp_read, bus_rsp_write;
|
||||||
logic [LSU_BUS_TAG-1:0] bus_rsp_read_tag, bus_rsp_write_tag;
|
logic [LSU_BUS_TAG-1:0] bus_rsp_read_tag, bus_rsp_write_tag;
|
||||||
logic bus_rsp_read_error, bus_rsp_write_error;
|
logic bus_rsp_read_error, bus_rsp_write_error;
|
||||||
logic [63:0] bus_rsp_rdata;
|
logic [63:0] bus_rsp_rdata;
|
||||||
|
|
||||||
// Bus buffer signals
|
// Bus buffer signals
|
||||||
state_t [DEPTH-1:0] buf_state;
|
state_t [DEPTH-1:0] buf_state;
|
||||||
logic [DEPTH-1:0][2:0] buf_state_out;
|
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] buf_error;
|
||||||
logic [DEPTH-1:0][31:0] buf_data;
|
logic [DEPTH-1:0][31:0] buf_data;
|
||||||
logic [DEPTH-1:0][DEPTH-1:0] buf_age, buf_age_younger, buf_age_temp;
|
logic [DEPTH-1:0][DEPTH-1:0] buf_age, buf_age_younger, buf_age_temp;
|
||||||
|
|
||||||
state_t [DEPTH-1:0] buf_nxtstate;
|
state_t [DEPTH-1:0] buf_nxtstate;
|
||||||
logic [DEPTH-1:0] buf_rst;
|
logic [DEPTH-1:0] buf_rst;
|
||||||
logic [DEPTH-1:0] buf_state_en;
|
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 obuf_cmd_done_in, obuf_data_done_in;
|
||||||
logic [LSU_BUS_TAG-1:0] obuf_tag0_in;
|
logic [LSU_BUS_TAG-1:0] obuf_tag0_in;
|
||||||
logic [LSU_BUS_TAG-1:0] obuf_tag1_in;
|
logic [LSU_BUS_TAG-1:0] obuf_tag1_in;
|
||||||
|
|
||||||
logic obuf_merge_en;
|
logic obuf_merge_en;
|
||||||
logic [TIMER_LOG2-1:0] obuf_wr_timer, obuf_wr_timer_in;
|
logic [TIMER_LOG2-1:0] obuf_wr_timer, obuf_wr_timer_in;
|
||||||
logic [7:0] obuf_byteen0_in, obuf_byteen1_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_axi_rvalid_q, lsu_axi_rready_q;
|
||||||
logic [LSU_BUS_TAG-1:0] lsu_axi_bid_q, lsu_axi_rid_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 [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
|
// Load forwarding logic start
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
@ -379,8 +379,8 @@ module lsu_bus_buffer
|
||||||
end
|
end
|
||||||
|
|
||||||
for (genvar j=0; j<4; j++) begin
|
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_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_hi[j] = |(ld_byte_hitvecfn_hi[j]) | ld_byte_ibuf_hit_hi[j];
|
||||||
for (genvar i=0; i<DEPTH; i++) begin
|
for (genvar i=0; i<DEPTH; i++) begin
|
||||||
assign ld_byte_hitvec_lo[j][i] = ld_addr_hitvec_lo[i] & buf_byteen[i][j] & ldst_byteen_lo_dc2[j];
|
assign ld_byte_hitvec_lo[j][i] = ld_addr_hitvec_lo[i] & buf_byteen[i][j] & ldst_byteen_lo_dc2[j];
|
||||||
assign ld_byte_hitvec_hi[j][i] = ld_addr_hitvec_hi[i] & buf_byteen[i][j] & ldst_byteen_hi_dc2[j];
|
assign ld_byte_hitvec_hi[j][i] = ld_addr_hitvec_hi[i] & buf_byteen[i][j] & ldst_byteen_hi_dc2[j];
|
||||||
|
@ -393,7 +393,7 @@ module lsu_bus_buffer
|
||||||
// Hit in the ibuf
|
// Hit in the ibuf
|
||||||
assign ld_addr_ibuf_hit_lo = (lsu_addr_dc2[31:2] == ibuf_addr[31:2]) & ibuf_write & ibuf_valid & lsu_busreq_dc2;
|
assign ld_addr_ibuf_hit_lo = (lsu_addr_dc2[31:2] == ibuf_addr[31:2]) & ibuf_write & ibuf_valid & lsu_busreq_dc2;
|
||||||
assign ld_addr_ibuf_hit_hi = (end_addr_dc2[31:2] == ibuf_addr[31:2]) & ibuf_write & ibuf_valid & lsu_busreq_dc2;
|
assign ld_addr_ibuf_hit_hi = (end_addr_dc2[31:2] == ibuf_addr[31:2]) & ibuf_write & ibuf_valid & lsu_busreq_dc2;
|
||||||
|
|
||||||
for (genvar i=0; i<4; i++) begin
|
for (genvar i=0; i<4; i++) begin
|
||||||
assign ld_byte_ibuf_hit_lo[i] = ld_addr_ibuf_hit_lo & ibuf_byteen[i] & ldst_byteen_lo_dc2[i];
|
assign ld_byte_ibuf_hit_lo[i] = ld_addr_ibuf_hit_lo & ibuf_byteen[i] & ldst_byteen_lo_dc2[i];
|
||||||
assign ld_byte_ibuf_hit_hi[i] = ld_addr_ibuf_hit_hi & ibuf_byteen[i] & ldst_byteen_hi_dc2[i];
|
assign ld_byte_ibuf_hit_hi[i] = ld_addr_ibuf_hit_hi & ibuf_byteen[i] & ldst_byteen_hi_dc2[i];
|
||||||
|
@ -414,7 +414,7 @@ module lsu_bus_buffer
|
||||||
ld_fwddata_buf_hi[31:24] |= {8{ld_byte_hitvecfn_hi[3][i]}} & buf_data[i][31:24];
|
ld_fwddata_buf_hi[31:24] |= {8{ld_byte_hitvecfn_hi[3][i]}} & buf_data[i][31:24];
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Load forwarding logic end
|
// Load forwarding logic end
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
@ -424,16 +424,16 @@ module lsu_bus_buffer
|
||||||
`else
|
`else
|
||||||
assign bus_coalescing_disable = dec_tlu_wb_coalescing_disable;
|
assign bus_coalescing_disable = dec_tlu_wb_coalescing_disable;
|
||||||
`endif
|
`endif
|
||||||
|
|
||||||
// Get the hi/lo byte enable
|
// Get the hi/lo byte enable
|
||||||
assign ldst_byteen_dc5[3:0] = ({4{lsu_pkt_dc5.by}} & 4'b0001) |
|
assign ldst_byteen_dc5[3:0] = ({4{lsu_pkt_dc5.by}} & 4'b0001) |
|
||||||
({4{lsu_pkt_dc5.half}} & 4'b0011) |
|
({4{lsu_pkt_dc5.half}} & 4'b0011) |
|
||||||
({4{lsu_pkt_dc5.word}} & 4'b1111);
|
({4{lsu_pkt_dc5.word}} & 4'b1111);
|
||||||
|
|
||||||
assign {ldst_byteen_hi_dc5[3:0], ldst_byteen_lo_dc5[3:0]} = {4'b0,ldst_byteen_dc5[3:0]} << lsu_addr_dc5[1:0];
|
assign {ldst_byteen_hi_dc5[3:0], ldst_byteen_lo_dc5[3:0]} = {4'b0,ldst_byteen_dc5[3:0]} << lsu_addr_dc5[1:0];
|
||||||
assign {store_data_hi_dc5[31:0], store_data_lo_dc5[31:0]} = {32'b0,store_data_dc5[31:0]} << {lsu_addr_dc5[1:0],3'b0};
|
assign {store_data_hi_dc5[31:0], store_data_lo_dc5[31:0]} = {32'b0,store_data_dc5[31:0]} << {lsu_addr_dc5[1:0],3'b0};
|
||||||
assign ldst_samedw_dc5 = (lsu_addr_dc5[3] == end_addr_dc5[3]);
|
assign ldst_samedw_dc5 = (lsu_addr_dc5[3] == end_addr_dc5[3]);
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Input buffer logic starts here
|
// Input buffer logic starts here
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
@ -442,8 +442,8 @@ module lsu_bus_buffer
|
||||||
assign ibuf_wr_en = lsu_busreq_dc5 & (lsu_commit_dc5 | lsu_freeze_dc3) & ~ibuf_byp;
|
assign ibuf_wr_en = lsu_busreq_dc5 & (lsu_commit_dc5 | lsu_freeze_dc3) & ~ibuf_byp;
|
||||||
assign ibuf_rst = ibuf_drain_vld & ~ibuf_wr_en;
|
assign ibuf_rst = ibuf_drain_vld & ~ibuf_wr_en;
|
||||||
assign ibuf_force_drain = lsu_busreq_dc2 & ~lsu_busreq_dc3 & ~lsu_busreq_dc4 & ~lsu_busreq_dc5 & ibuf_valid & (lsu_pkt_dc2.load | (ibuf_addr[31:2] != lsu_addr_dc2[31:2])); // Move the ibuf to buf if there is a non-colaescable ld/st in dc2 but nothing in dc3/dc4/dc5
|
assign ibuf_force_drain = lsu_busreq_dc2 & ~lsu_busreq_dc3 & ~lsu_busreq_dc4 & ~lsu_busreq_dc5 & ibuf_valid & (lsu_pkt_dc2.load | (ibuf_addr[31:2] != lsu_addr_dc2[31:2])); // Move the ibuf to buf if there is a non-colaescable ld/st in dc2 but nothing in dc3/dc4/dc5
|
||||||
assign ibuf_drain_vld = ibuf_valid & (((ibuf_wr_en | (ibuf_timer == TIMER_MAX)) & ~(ibuf_merge_en & ibuf_merge_in)) | ibuf_byp | ibuf_force_drain | ibuf_sideeffect | ~ibuf_write | bus_coalescing_disable);
|
assign ibuf_drain_vld = ibuf_valid & (((ibuf_wr_en | (ibuf_timer == TIMER_MAX)) & ~(ibuf_merge_en & ibuf_merge_in)) | ibuf_byp | ibuf_force_drain | ibuf_sideeffect | ~ibuf_write | bus_coalescing_disable);
|
||||||
assign ibuf_tag_in[DEPTH_LOG2-1:0] = (ibuf_merge_en & ibuf_merge_in) ? ibuf_tag[DEPTH_LOG2-1:0] : (ldst_dual_dc5 ? WrPtr1_dc5 : WrPtr0_dc5);
|
assign ibuf_tag_in[DEPTH_LOG2-1:0] = (ibuf_merge_en & ibuf_merge_in) ? ibuf_tag[DEPTH_LOG2-1:0] : (ldst_dual_dc5 ? WrPtr1_dc5 : WrPtr0_dc5);
|
||||||
assign ibuf_dualtag_in[DEPTH_LOG2-1:0] = WrPtr0_dc5;
|
assign ibuf_dualtag_in[DEPTH_LOG2-1:0] = WrPtr0_dc5;
|
||||||
assign ibuf_sz_in[1:0] = {lsu_pkt_dc5.word, lsu_pkt_dc5.half}; // NOTE: Make sure lsu_pkt_dc3/dc4 are flopped in case of freeze (except the valid)
|
assign ibuf_sz_in[1:0] = {lsu_pkt_dc5.word, lsu_pkt_dc5.half}; // NOTE: Make sure lsu_pkt_dc3/dc4 are flopped in case of freeze (except the valid)
|
||||||
assign ibuf_addr_in[31:0] = ldst_dual_dc5 ? end_addr_dc5[31:0] : lsu_addr_dc5[31:0];
|
assign ibuf_addr_in[31:0] = ldst_dual_dc5 ? end_addr_dc5[31:0] : lsu_addr_dc5[31:0];
|
||||||
|
@ -454,9 +454,9 @@ module lsu_bus_buffer
|
||||||
end
|
end
|
||||||
assign ibuf_timer_in = ibuf_wr_en ? '0 : (ibuf_timer < TIMER_MAX) ? (ibuf_timer + 1'b1) : ibuf_timer;
|
assign ibuf_timer_in = ibuf_wr_en ? '0 : (ibuf_timer < TIMER_MAX) ? (ibuf_timer + 1'b1) : ibuf_timer;
|
||||||
|
|
||||||
assign ibuf_merge_en = lsu_busreq_dc5 & lsu_commit_dc5 & lsu_pkt_dc5.store & ibuf_valid & ibuf_write & (lsu_addr_dc5[31:2] == ibuf_addr[31:2]) & ~is_sideeffects_dc5 & ~bus_coalescing_disable;
|
assign ibuf_merge_en = lsu_busreq_dc5 & lsu_commit_dc5 & lsu_pkt_dc5.store & ibuf_valid & ibuf_write & (lsu_addr_dc5[31:2] == ibuf_addr[31:2]) & ~is_sideeffects_dc5 & ~bus_coalescing_disable;
|
||||||
assign ibuf_merge_in = ~ldst_dual_dc5; // If it's a unaligned store, merge needs to happen on the way out of ibuf
|
assign ibuf_merge_in = ~ldst_dual_dc5; // If it's a unaligned store, merge needs to happen on the way out of ibuf
|
||||||
|
|
||||||
// ibuf signals going to bus buffer after merging
|
// ibuf signals going to bus buffer after merging
|
||||||
for (genvar i=0; i<4; i++) begin
|
for (genvar i=0; i<4; i++) begin
|
||||||
assign ibuf_byteen_out[i] = (ibuf_merge_en & ~ibuf_merge_in) ? (ibuf_byteen[i] | ldst_byteen_lo_dc5[i]) : ibuf_byteen[i];
|
assign ibuf_byteen_out[i] = (ibuf_merge_en & ~ibuf_merge_in) ? (ibuf_byteen[i] | ldst_byteen_lo_dc5[i]) : ibuf_byteen[i];
|
||||||
|
@ -492,11 +492,11 @@ module lsu_bus_buffer
|
||||||
assign obuf_wr_wait = (buf_numvld_wrcmd_any[3:0] == 4'b1) & (buf_numvld_cmd_any[3:0] == 4'b1) & (obuf_wr_timer != TIMER_MAX) & ~bus_coalescing_disable & ~buf_nomerge[CmdPtr0] & ~obuf_force_wr_en;
|
assign obuf_wr_wait = (buf_numvld_wrcmd_any[3:0] == 4'b1) & (buf_numvld_cmd_any[3:0] == 4'b1) & (obuf_wr_timer != TIMER_MAX) & ~bus_coalescing_disable & ~buf_nomerge[CmdPtr0] & ~obuf_force_wr_en;
|
||||||
assign obuf_wr_timer_in = obuf_wr_en ? 3'b0: (((buf_numvld_cmd_any > 4'b0) & (obuf_wr_timer < TIMER_MAX)) ? (obuf_wr_timer + 1'b1) : obuf_wr_timer);
|
assign obuf_wr_timer_in = obuf_wr_en ? 3'b0: (((buf_numvld_cmd_any > 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 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 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) |
|
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_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)))) &
|
(~(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;
|
(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_rst = bus_cmd_sent & ~obuf_wr_en;
|
||||||
assign obuf_write_in = ibuf_buf_byp ? lsu_pkt_dc5.store : buf_write[CmdPtr0];
|
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]}) :
|
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]});
|
(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_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]});
|
(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]};
|
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
|
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_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)];
|
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
|
end
|
||||||
|
|
||||||
// No store obuf merging for AXI since all stores are sent non-posted. Can't track the second id right now
|
// 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
|
(~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_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_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), .*);
|
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), .*);
|
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), .*);
|
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), .*);
|
rvdff #(.WIDTH(TIMER_LOG2)) obuf_timerff (.din(obuf_wr_timer_in), .dout(obuf_wr_timer), .clk(lsu_busm_clk), .*);
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Output buffer logic ends here
|
// Output buffer logic ends here
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
@ -556,7 +556,7 @@ module lsu_bus_buffer
|
||||||
if (~found_wrptr0) begin
|
if (~found_wrptr0) begin
|
||||||
WrPtr0_dc3[DEPTH_LOG2-1:0] = DEPTH_LOG2'(i);
|
WrPtr0_dc3[DEPTH_LOG2-1:0] = DEPTH_LOG2'(i);
|
||||||
found_wrptr0 = (buf_state[i] == IDLE) & ~((ibuf_valid & (ibuf_tag == 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))))));
|
(lsu_busreq_dc5 & ((WrPtr0_dc5 == DEPTH_LOG2'(i)) | (ldst_dual_dc5 & (WrPtr1_dc5 == DEPTH_LOG2'(i))))));
|
||||||
//found_wrptr = (buf_state[i] == IDLE);
|
//found_wrptr = (buf_state[i] == IDLE);
|
||||||
end
|
end
|
||||||
|
@ -568,7 +568,7 @@ module lsu_bus_buffer
|
||||||
WrPtr1_dc3[DEPTH_LOG2-1:0] = DEPTH_LOG2'(i);
|
WrPtr1_dc3[DEPTH_LOG2-1:0] = DEPTH_LOG2'(i);
|
||||||
found_wrptr1 = (buf_state[i] == IDLE) & ~((ibuf_valid & (ibuf_tag == 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_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))))));
|
(lsu_busreq_dc5 & ((WrPtr0_dc5 == DEPTH_LOG2'(i)) | (ldst_dual_dc5 & (WrPtr1_dc5 == DEPTH_LOG2'(i))))));
|
||||||
//found_wrptr = (buf_state[i] == IDLE);
|
//found_wrptr = (buf_state[i] == IDLE);
|
||||||
end
|
end
|
||||||
|
@ -590,14 +590,14 @@ module lsu_bus_buffer
|
||||||
// Age vector
|
// Age vector
|
||||||
for (genvar i=0; i<DEPTH; i++) begin: GenAgeVec
|
for (genvar i=0; i<DEPTH; i++) begin: GenAgeVec
|
||||||
for (genvar j=0; j<DEPTH; j++) begin
|
for (genvar j=0; j<DEPTH; j++) begin
|
||||||
assign buf_age_in[i][j] = (((buf_state[i] == IDLE) & buf_state_en[i]) &
|
assign buf_age_in[i][j] = (((buf_state[i] == IDLE) & buf_state_en[i]) &
|
||||||
(((buf_state[j] == WAIT) | ((buf_state[j] == CMD) & ~buf_cmd_state_bus_en[j])) | // Set age bit for older entries
|
(((buf_state[j] == WAIT) | ((buf_state[j] == CMD) & ~buf_cmd_state_bus_en[j])) | // Set age bit for older entries
|
||||||
(ibuf_drain_vld & lsu_busreq_dc5 & (ibuf_byp | ldst_dual_dc5) & (DEPTH_LOG2'(i) == WrPtr0_dc5) & (DEPTH_LOG2'(j) == ibuf_tag)) | // Set case for dual lo
|
(ibuf_drain_vld & lsu_busreq_dc5 & (ibuf_byp | ldst_dual_dc5) & (DEPTH_LOG2'(i) == WrPtr0_dc5) & (DEPTH_LOG2'(j) == ibuf_tag)) | // Set case for dual lo
|
||||||
(ibuf_byp & lsu_busreq_dc5 & ldst_dual_dc5 & (DEPTH_LOG2'(i) == WrPtr1_dc5) & (DEPTH_LOG2'(j) == WrPtr0_dc5)))) | // ibuf bypass case
|
(ibuf_byp & lsu_busreq_dc5 & ldst_dual_dc5 & (DEPTH_LOG2'(i) == WrPtr1_dc5) & (DEPTH_LOG2'(j) == WrPtr0_dc5)))) | // ibuf bypass case
|
||||||
buf_age[i][j];
|
buf_age[i][j];
|
||||||
assign buf_age[i][j] = buf_ageQ[i][j] & ~((buf_state[j] == CMD) & buf_cmd_state_bus_en[j]); // Reset case
|
assign buf_age[i][j] = buf_ageQ[i][j] & ~((buf_state[j] == CMD) & buf_cmd_state_bus_en[j]); // Reset case
|
||||||
|
|
||||||
assign buf_age_younger[i][j] = (i == j) ? 1'b0: (~buf_age[i][j] & (buf_state[j] != IDLE)); // Younger entries
|
assign buf_age_younger[i][j] = (i == j) ? 1'b0: (~buf_age[i][j] & (buf_state[j] != IDLE)); // Younger entries
|
||||||
assign buf_age_temp[i][j] = buf_age[i][j] & ~(CmdPtr0 == DEPTH_LOG2'(j)); // Used to determine CmdPtr1
|
assign buf_age_temp[i][j] = buf_age[i][j] & ~(CmdPtr0 == DEPTH_LOG2'(j)); // Used to determine CmdPtr1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -634,7 +634,7 @@ module lsu_bus_buffer
|
||||||
buf_data_in[i] = '0;
|
buf_data_in[i] = '0;
|
||||||
buf_data_en[i] = '0;
|
buf_data_en[i] = '0;
|
||||||
buf_error_en[i] = '0;
|
buf_error_en[i] = '0;
|
||||||
buf_rst[i] = '0;
|
buf_rst[i] = '0;
|
||||||
|
|
||||||
case (buf_state[i])
|
case (buf_state[i])
|
||||||
IDLE: begin
|
IDLE: begin
|
||||||
|
@ -671,7 +671,7 @@ module lsu_bus_buffer
|
||||||
buf_nxtstate[i] = IDLE;
|
buf_nxtstate[i] = IDLE;
|
||||||
buf_rst[i] = lsu_bus_clk_en_q & (buf_write[i] | ~buf_dual[i] | (buf_state[buf_dualtag[i]] == DONE));
|
buf_rst[i] = lsu_bus_clk_en_q & (buf_write[i] | ~buf_dual[i] | (buf_state[buf_dualtag[i]] == DONE));
|
||||||
buf_state_en[i] = buf_rst[i];
|
buf_state_en[i] = buf_rst[i];
|
||||||
end
|
end
|
||||||
default : begin
|
default : begin
|
||||||
buf_nxtstate[i] = IDLE;
|
buf_nxtstate[i] = IDLE;
|
||||||
buf_state_en[i] = '0;
|
buf_state_en[i] = '0;
|
||||||
|
@ -682,7 +682,7 @@ module lsu_bus_buffer
|
||||||
buf_data_in[i] = '0;
|
buf_data_in[i] = '0;
|
||||||
buf_data_en[i] = '0;
|
buf_data_en[i] = '0;
|
||||||
buf_error_en[i] = '0;
|
buf_error_en[i] = '0;
|
||||||
buf_rst[i] = '0;
|
buf_rst[i] = '0;
|
||||||
end
|
end
|
||||||
endcase
|
endcase
|
||||||
end
|
end
|
||||||
|
@ -706,13 +706,13 @@ module lsu_bus_buffer
|
||||||
rvdffsc #(.WIDTH(1)) buf_errorff (.din(1'b1), .dout(buf_error[i]), .en(buf_error_en[i]), .clear(buf_rst[i]), .clk(lsu_bus_buf_c1_clk), .*);
|
rvdffsc #(.WIDTH(1)) buf_errorff (.din(1'b1), .dout(buf_error[i]), .en(buf_error_en[i]), .clear(buf_rst[i]), .clk(lsu_bus_buf_c1_clk), .*);
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
// buffer full logic
|
// buffer full logic
|
||||||
always_comb begin
|
always_comb begin
|
||||||
buf_numvld_any[3:0] = ({3'b0,(lsu_pkt_dc1.valid & ~lsu_pkt_dc1.dma)} << (lsu_pkt_dc1.valid & ldst_dual_dc1)) +
|
buf_numvld_any[3:0] = ({3'b0,(lsu_pkt_dc1.valid & ~lsu_pkt_dc1.dma)} << (lsu_pkt_dc1.valid & ldst_dual_dc1)) +
|
||||||
({3'b0,lsu_busreq_dc2} << ldst_dual_dc2) +
|
({3'b0,lsu_busreq_dc2} << ldst_dual_dc2) +
|
||||||
({3'b0,lsu_busreq_dc3} << ldst_dual_dc3) +
|
({3'b0,lsu_busreq_dc3} << ldst_dual_dc3) +
|
||||||
({3'b0,lsu_busreq_dc4} << ldst_dual_dc4) +
|
({3'b0,lsu_busreq_dc4} << ldst_dual_dc4) +
|
||||||
({3'b0,lsu_busreq_dc5} << ldst_dual_dc5) +
|
({3'b0,lsu_busreq_dc5} << ldst_dual_dc5) +
|
||||||
{3'b0,ibuf_valid};
|
{3'b0,ibuf_valid};
|
||||||
buf_numvld_wrcmd_any[3:0] = 4'b0;
|
buf_numvld_wrcmd_any[3:0] = 4'b0;
|
||||||
|
@ -728,11 +728,11 @@ module lsu_bus_buffer
|
||||||
|
|
||||||
assign lsu_bus_buffer_pend_any = (buf_numvld_pend_any != 0);
|
assign lsu_bus_buffer_pend_any = (buf_numvld_pend_any != 0);
|
||||||
assign lsu_bus_buffer_full_any = (buf_numvld_any[3:0] >= (DEPTH-1));
|
assign lsu_bus_buffer_full_any = (buf_numvld_any[3:0] >= (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
|
// Freeze logic
|
||||||
assign FreezePtrEn = lsu_busreq_dc3 & lsu_pkt_dc3.load & ld_freeze_dc3;
|
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
|
always_comb begin
|
||||||
ld_freeze_rst = flush_dc3 | (dec_tlu_cancel_e4 & ld_freeze_dc3);
|
ld_freeze_rst = flush_dc3 | (dec_tlu_cancel_e4 & ld_freeze_dc3);
|
||||||
for (int i=0; i<DEPTH; i++) begin
|
for (int i=0; i<DEPTH; i++) begin
|
||||||
|
@ -794,7 +794,7 @@ module lsu_bus_buffer
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
// Imprecise bus errors
|
// Imprecise bus errors
|
||||||
assign lsu_imprecise_error_load_any = lsu_nonblock_load_data_error; // This is to make sure we send only one imprecise error for loads
|
assign lsu_imprecise_error_load_any = lsu_nonblock_load_data_error; // This is to make sure we send only one imprecise error for loads
|
||||||
|
|
||||||
|
|
||||||
|
@ -802,7 +802,7 @@ module lsu_bus_buffer
|
||||||
always_comb begin
|
always_comb begin
|
||||||
bus_addr_match_pending = '0;
|
bus_addr_match_pending = '0;
|
||||||
for (int i=0; i<DEPTH; i++) begin
|
for (int i=0; i<DEPTH; i++) begin
|
||||||
bus_addr_match_pending |= (obuf_valid & (obuf_addr[31:3] == buf_addr[i][31:3]) & (buf_state[i] == RESP) & ~((obuf_tag0 == LSU_BUS_TAG'(i)) | (obuf_merge & (obuf_tag1 == LSU_BUS_TAG'(i)))));
|
bus_addr_match_pending |= (obuf_valid & (obuf_addr[31:3] == buf_addr[i][31:3]) & (buf_state[i] == RESP) & ~((obuf_tag0 == LSU_BUS_TAG'(i)) | (obuf_merge & (obuf_tag1 == LSU_BUS_TAG'(i)))));
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -817,17 +817,17 @@ module lsu_bus_buffer
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
assign lsu_imprecise_error_addr_any[31:0] = lsu_imprecise_error_load_any ? buf_addr[lsu_nonblock_load_data_tag] : buf_addr[lsu_imprecise_error_store_tag];
|
assign lsu_imprecise_error_addr_any[31:0] = lsu_imprecise_error_load_any ? buf_addr[lsu_nonblock_load_data_tag] : buf_addr[lsu_imprecise_error_store_tag];
|
||||||
|
|
||||||
// Generic bus signals
|
// Generic bus signals
|
||||||
assign bus_cmd_ready = obuf_write ? ((obuf_cmd_done | obuf_data_done) ? (obuf_cmd_done ? lsu_axi_wready : lsu_axi_awready) : (lsu_axi_awready & lsu_axi_wready)) : lsu_axi_arready;
|
assign bus_cmd_ready = obuf_write ? ((obuf_cmd_done | obuf_data_done) ? (obuf_cmd_done ? lsu_axi_wready : lsu_axi_awready) : (lsu_axi_awready & lsu_axi_wready)) : lsu_axi_arready;
|
||||||
assign bus_wcmd_sent = lsu_axi_awvalid & lsu_axi_awready;
|
assign bus_wcmd_sent = lsu_axi_awvalid & lsu_axi_awready;
|
||||||
assign bus_wdata_sent = lsu_axi_wvalid & lsu_axi_wready;
|
assign bus_wdata_sent = lsu_axi_wvalid & lsu_axi_wready;
|
||||||
assign bus_cmd_sent = ((obuf_cmd_done | bus_wcmd_sent) & (obuf_data_done | bus_wdata_sent)) | (lsu_axi_arvalid & lsu_axi_arready);
|
assign bus_cmd_sent = ((obuf_cmd_done | bus_wcmd_sent) & (obuf_data_done | bus_wdata_sent)) | (lsu_axi_arvalid & lsu_axi_arready);
|
||||||
|
|
||||||
assign bus_rsp_read = lsu_axi_rvalid_q & lsu_axi_rready_q;
|
assign bus_rsp_read = lsu_axi_rvalid_q & lsu_axi_rready_q;
|
||||||
assign bus_rsp_write = lsu_axi_bvalid_q & lsu_axi_bready_q;
|
assign bus_rsp_write = lsu_axi_bvalid_q & lsu_axi_bready_q;
|
||||||
assign bus_rsp_read_tag[LSU_BUS_TAG-1:0] = lsu_axi_rid_q[LSU_BUS_TAG-1:0];
|
assign bus_rsp_read_tag[LSU_BUS_TAG-1:0] = lsu_axi_rid_q[LSU_BUS_TAG-1:0];
|
||||||
assign bus_rsp_write_tag[LSU_BUS_TAG-1:0] = lsu_axi_bid_q[LSU_BUS_TAG-1:0];
|
assign bus_rsp_write_tag[LSU_BUS_TAG-1:0] = lsu_axi_bid_q[LSU_BUS_TAG-1:0];
|
||||||
assign bus_rsp_write_error = bus_rsp_write & (lsu_axi_bresp_q[1:0] != 2'b0);
|
assign bus_rsp_write_error = bus_rsp_write & (lsu_axi_bresp_q[1:0] != 2'b0);
|
||||||
assign bus_rsp_read_error = bus_rsp_read & (lsu_axi_rresp_q[1:0] != 2'b0);
|
assign bus_rsp_read_error = bus_rsp_read & (lsu_axi_rresp_q[1:0] != 2'b0);
|
||||||
assign bus_rsp_rdata[63:0] = lsu_axi_rdata_q[63:0];
|
assign bus_rsp_rdata[63:0] = lsu_axi_rdata_q[63:0];
|
||||||
|
@ -838,7 +838,7 @@ module lsu_bus_buffer
|
||||||
assign lsu_axi_awaddr[31:0] = obuf_sideeffect ? obuf_addr[31:0] : {obuf_addr[31:3],3'b0};
|
assign lsu_axi_awaddr[31:0] = obuf_sideeffect ? obuf_addr[31:0] : {obuf_addr[31:3],3'b0};
|
||||||
assign lsu_axi_awsize[2:0] = obuf_sideeffect ? {1'b0, obuf_sz[1:0]} : 3'b011;
|
assign lsu_axi_awsize[2:0] = obuf_sideeffect ? {1'b0, obuf_sz[1:0]} : 3'b011;
|
||||||
assign lsu_axi_awprot[2:0] = '0;
|
assign lsu_axi_awprot[2:0] = '0;
|
||||||
assign lsu_axi_awcache[3:0] = obuf_sideeffect ? 4'b0 : 4'b1111;
|
assign lsu_axi_awcache[3:0] = obuf_sideeffect ? 4'b0 : 4'b1111;
|
||||||
assign lsu_axi_awregion[3:0] = obuf_addr[31:28];
|
assign lsu_axi_awregion[3:0] = obuf_addr[31:28];
|
||||||
assign lsu_axi_awlen[7:0] = '0;
|
assign lsu_axi_awlen[7:0] = '0;
|
||||||
assign lsu_axi_awburst[1:0] = 2'b01;
|
assign lsu_axi_awburst[1:0] = 2'b01;
|
||||||
|
@ -855,13 +855,13 @@ module lsu_bus_buffer
|
||||||
assign lsu_axi_araddr[31:0] = obuf_sideeffect ? obuf_addr[31:0] : {obuf_addr[31:3],3'b0};
|
assign lsu_axi_araddr[31:0] = obuf_sideeffect ? obuf_addr[31:0] : {obuf_addr[31:3],3'b0};
|
||||||
assign lsu_axi_arsize[2:0] = obuf_sideeffect ? {1'b0, obuf_sz[1:0]} : 3'b011;
|
assign lsu_axi_arsize[2:0] = obuf_sideeffect ? {1'b0, obuf_sz[1:0]} : 3'b011;
|
||||||
assign lsu_axi_arprot[2:0] = '0;
|
assign lsu_axi_arprot[2:0] = '0;
|
||||||
assign lsu_axi_arcache[3:0] = obuf_sideeffect ? 4'b0 : 4'b1111;
|
assign lsu_axi_arcache[3:0] = obuf_sideeffect ? 4'b0 : 4'b1111;
|
||||||
assign lsu_axi_arregion[3:0] = obuf_addr[31:28];
|
assign lsu_axi_arregion[3:0] = obuf_addr[31:28];
|
||||||
assign lsu_axi_arlen[7:0] = '0;
|
assign lsu_axi_arlen[7:0] = '0;
|
||||||
assign lsu_axi_arburst[1:0] = 2'b01;
|
assign lsu_axi_arburst[1:0] = 2'b01;
|
||||||
assign lsu_axi_arqos[3:0] = '0;
|
assign lsu_axi_arqos[3:0] = '0;
|
||||||
assign lsu_axi_arlock = '0;
|
assign lsu_axi_arlock = '0;
|
||||||
|
|
||||||
assign lsu_axi_bready = 1;
|
assign lsu_axi_bready = 1;
|
||||||
assign lsu_axi_rready = 1;
|
assign lsu_axi_rready = 1;
|
||||||
|
|
||||||
|
@ -870,7 +870,7 @@ module lsu_bus_buffer
|
||||||
assign lsu_pmu_bus_misaligned = lsu_busreq_dc2 & ldst_dual_dc2;
|
assign lsu_pmu_bus_misaligned = lsu_busreq_dc2 & ldst_dual_dc2;
|
||||||
assign lsu_pmu_bus_error = ld_bus_error_dc3 | lsu_imprecise_error_load_any | lsu_imprecise_error_store_any;
|
assign lsu_pmu_bus_error = ld_bus_error_dc3 | lsu_imprecise_error_load_any | lsu_imprecise_error_store_any;
|
||||||
assign lsu_pmu_bus_busy = (lsu_axi_awvalid_q & ~lsu_axi_awready_q) | (lsu_axi_wvalid_q & ~lsu_axi_wready_q) | (lsu_axi_arvalid_q & ~lsu_axi_arready_q);
|
assign lsu_pmu_bus_busy = (lsu_axi_awvalid_q & ~lsu_axi_awready_q) | (lsu_axi_wvalid_q & ~lsu_axi_wready_q) | (lsu_axi_arvalid_q & ~lsu_axi_arready_q);
|
||||||
|
|
||||||
rvdff #(.WIDTH(1)) lsu_axi_awvalid_ff (.din(lsu_axi_awvalid), .dout(lsu_axi_awvalid_q), .clk(lsu_busm_clk), .*);
|
rvdff #(.WIDTH(1)) lsu_axi_awvalid_ff (.din(lsu_axi_awvalid), .dout(lsu_axi_awvalid_q), .clk(lsu_busm_clk), .*);
|
||||||
rvdff #(.WIDTH(1)) lsu_axi_awready_ff (.din(lsu_axi_awready), .dout(lsu_axi_awready_q), .clk(lsu_busm_clk), .*);
|
rvdff #(.WIDTH(1)) lsu_axi_awready_ff (.din(lsu_axi_awready), .dout(lsu_axi_awready_q), .clk(lsu_busm_clk), .*);
|
||||||
rvdff #(.WIDTH(1)) lsu_axi_wvalid_ff (.din(lsu_axi_wvalid), .dout(lsu_axi_wvalid_q), .clk(lsu_busm_clk), .*);
|
rvdff #(.WIDTH(1)) lsu_axi_wvalid_ff (.din(lsu_axi_wvalid), .dout(lsu_axi_wvalid_q), .clk(lsu_busm_clk), .*);
|
||||||
|
@ -888,7 +888,7 @@ module lsu_bus_buffer
|
||||||
rvdff #(.WIDTH(1)) lsu_axi_rready_ff (.din(lsu_axi_rready), .dout(lsu_axi_rready_q), .clk(lsu_busm_clk), .*);
|
rvdff #(.WIDTH(1)) lsu_axi_rready_ff (.din(lsu_axi_rready), .dout(lsu_axi_rready_q), .clk(lsu_busm_clk), .*);
|
||||||
rvdff #(.WIDTH(2)) lsu_axi_rresp_ff (.din(lsu_axi_rresp[1:0]), .dout(lsu_axi_rresp_q[1:0]), .clk(lsu_busm_clk), .*);
|
rvdff #(.WIDTH(2)) lsu_axi_rresp_ff (.din(lsu_axi_rresp[1:0]), .dout(lsu_axi_rresp_q[1:0]), .clk(lsu_busm_clk), .*);
|
||||||
rvdff #(.WIDTH(LSU_BUS_TAG)) lsu_axi_rid_ff (.din(lsu_axi_rid[LSU_BUS_TAG-1:0]), .dout(lsu_axi_rid_q[LSU_BUS_TAG-1:0]), .clk(lsu_busm_clk), .*);
|
rvdff #(.WIDTH(LSU_BUS_TAG)) lsu_axi_rid_ff (.din(lsu_axi_rid[LSU_BUS_TAG-1:0]), .dout(lsu_axi_rid_q[LSU_BUS_TAG-1:0]), .clk(lsu_busm_clk), .*);
|
||||||
|
|
||||||
// General flops
|
// General flops
|
||||||
rvdffsc #(.WIDTH(1)) ld_freezeff (.din(1'b1), .dout(ld_freeze_dc3), .en(ld_freeze_en), .clear(ld_freeze_rst), .clk(lsu_free_c2_clk), .*);
|
rvdffsc #(.WIDTH(1)) ld_freezeff (.din(1'b1), .dout(ld_freeze_dc3), .en(ld_freeze_en), .clear(ld_freeze_rst), .clk(lsu_free_c2_clk), .*);
|
||||||
rvdffs #(.WIDTH(DEPTH_LOG2)) lsu_FreezePtrff (.din(WrPtr0_dc3), .dout(FreezePtr), .en(FreezePtrEn), .clk(lsu_free_c2_clk), .*);
|
rvdffs #(.WIDTH(DEPTH_LOG2)) lsu_FreezePtrff (.din(WrPtr0_dc3), .dout(FreezePtr), .en(FreezePtrEn), .clk(lsu_free_c2_clk), .*);
|
||||||
|
@ -914,10 +914,10 @@ module lsu_bus_buffer
|
||||||
assert_ld_byte_hitvecfn_lo_onehot: assert #0 ($onehot0(ld_byte_hitvecfn_lo[i][DEPTH-1:0]));
|
assert_ld_byte_hitvecfn_lo_onehot: assert #0 ($onehot0(ld_byte_hitvecfn_lo[i][DEPTH-1:0]));
|
||||||
assert_ld_byte_hitvecfn_hi_onehot: assert #0 ($onehot0(ld_byte_hitvecfn_hi[i][DEPTH-1:0]));
|
assert_ld_byte_hitvecfn_hi_onehot: assert #0 ($onehot0(ld_byte_hitvecfn_hi[i][DEPTH-1:0]));
|
||||||
end
|
end
|
||||||
|
|
||||||
assert_CmdPtr0Dec_onehot: assert #0 ($onehot0(CmdPtr0Dec[DEPTH-1:0]));
|
assert_CmdPtr0Dec_onehot: assert #0 ($onehot0(CmdPtr0Dec[DEPTH-1:0]));
|
||||||
assert_CmdPtr1Dec_onehot: assert #0 ($onehot0(CmdPtr1Dec[DEPTH-1:0]));
|
assert_CmdPtr1Dec_onehot: assert #0 ($onehot0(CmdPtr1Dec[DEPTH-1:0]));
|
||||||
|
|
||||||
`endif
|
`endif
|
||||||
|
|
||||||
endmodule // lsu_bus_buffer
|
endmodule // lsu_bus_buffer
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
// Copyright 2019 Western Digital Corporation or its affiliates.
|
// Copyright 2019 Western Digital Corporation or its affiliates.
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "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 not use this file except in compliance with the License.
|
||||||
// You may obtain a copy of the License at
|
// You may obtain a copy of the License at
|
||||||
//
|
//
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
//
|
//
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
@ -16,13 +16,13 @@
|
||||||
//********************************************************************************
|
//********************************************************************************
|
||||||
// $Id$
|
// $Id$
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// Owner:
|
// Owner:
|
||||||
// Function: lsu interface with interface queue
|
// Function: lsu interface with interface queue
|
||||||
// Comments:
|
// Comments:
|
||||||
//
|
//
|
||||||
//********************************************************************************
|
//********************************************************************************
|
||||||
module lsu_bus_intf
|
module lsu_bus_intf
|
||||||
import swerv_types::*;
|
import swerv_types::*;
|
||||||
(
|
(
|
||||||
input logic clk,
|
input logic clk,
|
||||||
|
@ -32,9 +32,9 @@ module lsu_bus_intf
|
||||||
input logic dec_tlu_wb_coalescing_disable, // disable write buffer coalescing
|
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_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
|
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
|
// 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_dc4_clk,
|
||||||
input logic lsu_c1_dc5_clk,
|
input logic lsu_c1_dc5_clk,
|
||||||
input logic lsu_c2_dc3_clk,
|
input logic lsu_c2_dc3_clk,
|
||||||
|
@ -50,9 +50,9 @@ module lsu_bus_intf
|
||||||
input logic lsu_free_c2_clk,
|
input logic lsu_free_c2_clk,
|
||||||
input logic free_clk,
|
input logic free_clk,
|
||||||
input logic lsu_busm_clk,
|
input logic lsu_busm_clk,
|
||||||
|
|
||||||
input logic lsu_busreq_dc2, // bus request is in dc2
|
input logic lsu_busreq_dc2, // bus request is in dc2
|
||||||
|
|
||||||
input lsu_pkt_t lsu_pkt_dc1, // lsu packet flowing down the pipe
|
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_dc2, // lsu packet flowing down the pipe
|
||||||
input lsu_pkt_t lsu_pkt_dc3, // lsu packet flowing down the pipe
|
input lsu_pkt_t lsu_pkt_dc3, // lsu packet flowing down the pipe
|
||||||
|
@ -71,7 +71,7 @@ module lsu_bus_intf
|
||||||
input logic [31:0] end_addr_dc4, // lsu address flowing down the pipe
|
input logic [31:0] end_addr_dc4, // lsu address flowing down the pipe
|
||||||
input logic [31:0] end_addr_dc5, // lsu address flowing down the pipe
|
input logic [31:0] end_addr_dc5, // lsu address flowing down the pipe
|
||||||
|
|
||||||
input logic addr_external_dc2, // lsu instruction going to external
|
input logic addr_external_dc2, // lsu instruction going to external
|
||||||
input logic addr_external_dc3, // lsu instruction going to external
|
input logic addr_external_dc3, // lsu instruction going to external
|
||||||
input logic addr_external_dc4, // lsu instruction going to external
|
input logic addr_external_dc4, // lsu instruction going to external
|
||||||
input logic addr_external_dc5, // lsu instruction going to external
|
input logic addr_external_dc5, // lsu instruction going to external
|
||||||
|
@ -84,7 +84,7 @@ module lsu_bus_intf
|
||||||
input logic lsu_commit_dc5, // lsu instruction in dc5 commits
|
input logic lsu_commit_dc5, // lsu instruction in dc5 commits
|
||||||
input logic is_sideeffects_dc2, // lsu attribute is side_effects
|
input logic is_sideeffects_dc2, // lsu attribute is side_effects
|
||||||
input logic is_sideeffects_dc3, // lsu attribute is side_effects
|
input logic is_sideeffects_dc3, // lsu attribute is side_effects
|
||||||
input logic flush_dc2_up, // flush
|
input logic flush_dc2_up, // flush
|
||||||
input logic flush_dc3, // flush
|
input logic flush_dc3, // flush
|
||||||
input logic flush_dc4, // flush
|
input logic flush_dc4, // flush
|
||||||
input logic flush_dc5, // flush
|
input logic flush_dc5, // flush
|
||||||
|
@ -98,7 +98,7 @@ module lsu_bus_intf
|
||||||
output logic [31:0] bus_read_data_dc3, // the bus return data
|
output logic [31:0] bus_read_data_dc3, // the bus return data
|
||||||
|
|
||||||
output logic ld_bus_error_dc3, // bus error in dc3
|
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 lsu_imprecise_error_load_any, // imprecise load bus error
|
output logic lsu_imprecise_error_load_any, // imprecise load bus error
|
||||||
output logic lsu_imprecise_error_store_any, // imprecise store bus error
|
output logic lsu_imprecise_error_store_any, // imprecise store bus error
|
||||||
|
@ -110,17 +110,17 @@ module lsu_bus_intf
|
||||||
output logic [`RV_LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_tag_dc3, // the tag of the external non block load
|
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 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 [`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_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 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 [`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 [31:0] lsu_nonblock_load_data, // Data of the non block load
|
||||||
|
|
||||||
// PMU events
|
// PMU events
|
||||||
output logic lsu_pmu_bus_trxn,
|
output logic lsu_pmu_bus_trxn,
|
||||||
output logic lsu_pmu_bus_misaligned,
|
output logic lsu_pmu_bus_misaligned,
|
||||||
output logic lsu_pmu_bus_error,
|
output logic lsu_pmu_bus_error,
|
||||||
output logic lsu_pmu_bus_busy,
|
output logic lsu_pmu_bus_busy,
|
||||||
|
|
||||||
// AXI Write Channels
|
// AXI Write Channels
|
||||||
output logic lsu_axi_awvalid,
|
output logic lsu_axi_awvalid,
|
||||||
input logic lsu_axi_awready,
|
input logic lsu_axi_awready,
|
||||||
|
@ -134,19 +134,19 @@ module lsu_bus_intf
|
||||||
output logic [3:0] lsu_axi_awcache,
|
output logic [3:0] lsu_axi_awcache,
|
||||||
output logic [2:0] lsu_axi_awprot,
|
output logic [2:0] lsu_axi_awprot,
|
||||||
output logic [3:0] lsu_axi_awqos,
|
output logic [3:0] lsu_axi_awqos,
|
||||||
|
|
||||||
output logic lsu_axi_wvalid,
|
output logic lsu_axi_wvalid,
|
||||||
input logic lsu_axi_wready,
|
input logic lsu_axi_wready,
|
||||||
output logic [63:0] lsu_axi_wdata,
|
output logic [63:0] lsu_axi_wdata,
|
||||||
output logic [7:0] lsu_axi_wstrb,
|
output logic [7:0] lsu_axi_wstrb,
|
||||||
output logic lsu_axi_wlast,
|
output logic lsu_axi_wlast,
|
||||||
|
|
||||||
input logic lsu_axi_bvalid,
|
input logic lsu_axi_bvalid,
|
||||||
output logic lsu_axi_bready,
|
output logic lsu_axi_bready,
|
||||||
input logic [1:0] lsu_axi_bresp,
|
input logic [1:0] lsu_axi_bresp,
|
||||||
input logic [`RV_LSU_BUS_TAG-1:0] lsu_axi_bid,
|
input logic [`RV_LSU_BUS_TAG-1:0] lsu_axi_bid,
|
||||||
|
|
||||||
// AXI Read Channels
|
// AXI Read Channels
|
||||||
output logic lsu_axi_arvalid,
|
output logic lsu_axi_arvalid,
|
||||||
input logic lsu_axi_arready,
|
input logic lsu_axi_arready,
|
||||||
output logic [`RV_LSU_BUS_TAG-1:0] lsu_axi_arid,
|
output logic [`RV_LSU_BUS_TAG-1:0] lsu_axi_arid,
|
||||||
|
@ -159,7 +159,7 @@ module lsu_bus_intf
|
||||||
output logic [3:0] lsu_axi_arcache,
|
output logic [3:0] lsu_axi_arcache,
|
||||||
output logic [2:0] lsu_axi_arprot,
|
output logic [2:0] lsu_axi_arprot,
|
||||||
output logic [3:0] lsu_axi_arqos,
|
output logic [3:0] lsu_axi_arqos,
|
||||||
|
|
||||||
input logic lsu_axi_rvalid,
|
input logic lsu_axi_rvalid,
|
||||||
output logic lsu_axi_rready,
|
output logic lsu_axi_rready,
|
||||||
input logic [`RV_LSU_BUS_TAG-1:0] lsu_axi_rid,
|
input logic [`RV_LSU_BUS_TAG-1:0] lsu_axi_rid,
|
||||||
|
@ -173,27 +173,27 @@ module lsu_bus_intf
|
||||||
|
|
||||||
`include "global.h"
|
`include "global.h"
|
||||||
|
|
||||||
logic ld_freeze_dc3;
|
logic ld_freeze_dc3;
|
||||||
|
|
||||||
logic lsu_bus_clk_en_q;
|
logic lsu_bus_clk_en_q;
|
||||||
logic ldst_dual_dc1, ldst_dual_dc2, ldst_dual_dc3, ldst_dual_dc4, ldst_dual_dc5;
|
logic ldst_dual_dc1, ldst_dual_dc2, ldst_dual_dc3, ldst_dual_dc4, ldst_dual_dc5;
|
||||||
logic lsu_busreq_dc3, lsu_busreq_dc4;
|
logic lsu_busreq_dc3, lsu_busreq_dc4;
|
||||||
|
|
||||||
logic [3:0] ldst_byteen_dc2, ldst_byteen_dc3, ldst_byteen_dc4, ldst_byteen_dc5;
|
logic [3:0] ldst_byteen_dc2, ldst_byteen_dc3, ldst_byteen_dc4, ldst_byteen_dc5;
|
||||||
logic [7:0] ldst_byteen_ext_dc2, ldst_byteen_ext_dc3, ldst_byteen_ext_dc4, ldst_byteen_ext_dc5;
|
logic [7:0] ldst_byteen_ext_dc2, ldst_byteen_ext_dc3, ldst_byteen_ext_dc4, ldst_byteen_ext_dc5;
|
||||||
logic [3:0] ldst_byteen_hi_dc2, ldst_byteen_hi_dc3, ldst_byteen_hi_dc4, ldst_byteen_hi_dc5;
|
logic [3:0] ldst_byteen_hi_dc2, ldst_byteen_hi_dc3, ldst_byteen_hi_dc4, ldst_byteen_hi_dc5;
|
||||||
logic [3:0] ldst_byteen_lo_dc2, ldst_byteen_lo_dc3, ldst_byteen_lo_dc4, ldst_byteen_lo_dc5;
|
logic [3:0] ldst_byteen_lo_dc2, ldst_byteen_lo_dc3, ldst_byteen_lo_dc4, ldst_byteen_lo_dc5;
|
||||||
logic is_sideeffects_dc4, is_sideeffects_dc5;
|
logic is_sideeffects_dc4, is_sideeffects_dc5;
|
||||||
|
|
||||||
|
|
||||||
logic [63:0] store_data_ext_dc3, store_data_ext_dc4, store_data_ext_dc5;
|
logic [63:0] store_data_ext_dc3, store_data_ext_dc4, store_data_ext_dc5;
|
||||||
logic [31:0] store_data_hi_dc3, store_data_hi_dc4, store_data_hi_dc5;
|
logic [31:0] store_data_hi_dc3, store_data_hi_dc4, store_data_hi_dc5;
|
||||||
logic [31:0] store_data_lo_dc3, store_data_lo_dc4, store_data_lo_dc5;
|
logic [31:0] store_data_lo_dc3, store_data_lo_dc4, store_data_lo_dc5;
|
||||||
|
|
||||||
logic addr_match_dw_lo_dc5_dc4, addr_match_dw_lo_dc5_dc3, addr_match_dw_lo_dc5_dc2;
|
logic addr_match_dw_lo_dc5_dc4, addr_match_dw_lo_dc5_dc3, addr_match_dw_lo_dc5_dc2;
|
||||||
logic addr_match_word_lo_dc5_dc4, addr_match_word_lo_dc5_dc3, addr_match_word_lo_dc5_dc2;
|
logic addr_match_word_lo_dc5_dc4, addr_match_word_lo_dc5_dc3, addr_match_word_lo_dc5_dc2;
|
||||||
logic no_word_merge_dc5, no_dword_merge_dc5;
|
logic no_word_merge_dc5, no_dword_merge_dc5;
|
||||||
|
|
||||||
logic ld_addr_dc3hit_lo_lo, ld_addr_dc3hit_hi_lo, ld_addr_dc3hit_lo_hi, ld_addr_dc3hit_hi_hi;
|
logic ld_addr_dc3hit_lo_lo, ld_addr_dc3hit_hi_lo, ld_addr_dc3hit_lo_hi, ld_addr_dc3hit_hi_hi;
|
||||||
logic ld_addr_dc4hit_lo_lo, ld_addr_dc4hit_hi_lo, ld_addr_dc4hit_lo_hi, ld_addr_dc4hit_hi_hi;
|
logic ld_addr_dc4hit_lo_lo, ld_addr_dc4hit_hi_lo, ld_addr_dc4hit_lo_hi, ld_addr_dc4hit_hi_hi;
|
||||||
logic ld_addr_dc5hit_lo_lo, ld_addr_dc5hit_hi_lo, ld_addr_dc5hit_lo_hi, ld_addr_dc5hit_hi_hi;
|
logic ld_addr_dc5hit_lo_lo, ld_addr_dc5hit_hi_lo, ld_addr_dc5hit_lo_hi, ld_addr_dc5hit_hi_hi;
|
||||||
|
@ -210,20 +210,20 @@ module lsu_bus_intf
|
||||||
|
|
||||||
logic [3:0] ld_byte_hit_buf_lo, ld_byte_hit_buf_hi;
|
logic [3:0] ld_byte_hit_buf_lo, ld_byte_hit_buf_hi;
|
||||||
logic [31:0] ld_fwddata_buf_lo, ld_fwddata_buf_hi;
|
logic [31:0] ld_fwddata_buf_lo, ld_fwddata_buf_hi;
|
||||||
|
|
||||||
logic ld_hit_rdbuf_hi, ld_hit_rdbuf_lo;
|
logic ld_hit_rdbuf_hi, ld_hit_rdbuf_lo;
|
||||||
logic [31:0] ld_fwddata_rdbuf_hi, ld_fwddata_rdbuf_lo;
|
logic [31:0] ld_fwddata_rdbuf_hi, ld_fwddata_rdbuf_lo;
|
||||||
|
|
||||||
logic [63:0] ld_fwddata_lo, ld_fwddata_hi;
|
logic [63:0] ld_fwddata_lo, ld_fwddata_hi;
|
||||||
logic [31:0] ld_fwddata_dc2, ld_fwddata_dc3;
|
logic [31:0] ld_fwddata_dc2, ld_fwddata_dc3;
|
||||||
logic [31:0] ld_bus_data_dc3;
|
logic [31:0] ld_bus_data_dc3;
|
||||||
|
|
||||||
logic ld_full_hit_hi_dc2, ld_full_hit_lo_dc2;
|
logic ld_full_hit_hi_dc2, ld_full_hit_lo_dc2;
|
||||||
logic ld_hit_dc2, ld_full_hit_dc2, ld_full_hit_dc3;
|
logic ld_hit_dc2, ld_full_hit_dc2, ld_full_hit_dc3;
|
||||||
logic is_aligned_dc5;
|
logic is_aligned_dc5;
|
||||||
|
|
||||||
logic [63:32] ld_fwddata_dc2_nc;
|
logic [63:32] ld_fwddata_dc2_nc;
|
||||||
|
|
||||||
logic lsu_write_buffer_empty_any;
|
logic lsu_write_buffer_empty_any;
|
||||||
assign lsu_write_buffer_empty_any = 1'b1;
|
assign lsu_write_buffer_empty_any = 1'b1;
|
||||||
|
|
||||||
|
@ -232,7 +232,7 @@ module lsu_bus_intf
|
||||||
({4{lsu_pkt_dc2.word}} & 4'b1111);
|
({4{lsu_pkt_dc2.word}} & 4'b1111);
|
||||||
assign ldst_dual_dc1 = (lsu_addr_dc1[2] != end_addr_dc1[2]);
|
assign ldst_dual_dc1 = (lsu_addr_dc1[2] != end_addr_dc1[2]);
|
||||||
assign lsu_freeze_dc3 = ld_freeze_dc3 & ~(flush_dc4 | flush_dc5);
|
assign lsu_freeze_dc3 = ld_freeze_dc3 & ~(flush_dc4 | flush_dc5);
|
||||||
|
|
||||||
// Determine if the packet is word aligned
|
// Determine if the packet is word aligned
|
||||||
assign is_aligned_dc5 = (lsu_pkt_dc5.word & (lsu_addr_dc5[1:0] == 2'b0)) |
|
assign is_aligned_dc5 = (lsu_pkt_dc5.word & (lsu_addr_dc5[1:0] == 2'b0)) |
|
||||||
(lsu_pkt_dc5.half & (lsu_addr_dc5[0] == 1'b0));
|
(lsu_pkt_dc5.half & (lsu_addr_dc5[0] == 1'b0));
|
||||||
|
@ -247,16 +247,16 @@ module lsu_bus_intf
|
||||||
assign addr_match_dw_lo_dc5_dc3 = (lsu_addr_dc5[31:3] == lsu_addr_dc3[31:3]);
|
assign addr_match_dw_lo_dc5_dc3 = (lsu_addr_dc5[31:3] == lsu_addr_dc3[31:3]);
|
||||||
assign addr_match_dw_lo_dc5_dc2 = (lsu_addr_dc5[31:3] == lsu_addr_dc2[31:3]);
|
assign addr_match_dw_lo_dc5_dc2 = (lsu_addr_dc5[31:3] == lsu_addr_dc2[31:3]);
|
||||||
|
|
||||||
assign addr_match_word_lo_dc5_dc4 = addr_match_dw_lo_dc5_dc4 & ~(lsu_addr_dc5[2]^lsu_addr_dc4[2]);
|
assign addr_match_word_lo_dc5_dc4 = addr_match_dw_lo_dc5_dc4 & ~(lsu_addr_dc5[2]^lsu_addr_dc4[2]);
|
||||||
assign addr_match_word_lo_dc5_dc3 = addr_match_dw_lo_dc5_dc3 & ~(lsu_addr_dc5[2]^lsu_addr_dc3[2]);
|
assign addr_match_word_lo_dc5_dc3 = addr_match_dw_lo_dc5_dc3 & ~(lsu_addr_dc5[2]^lsu_addr_dc3[2]);
|
||||||
assign addr_match_word_lo_dc5_dc2 = addr_match_dw_lo_dc5_dc2 & ~(lsu_addr_dc5[2]^lsu_addr_dc2[2]);
|
assign addr_match_word_lo_dc5_dc2 = addr_match_dw_lo_dc5_dc2 & ~(lsu_addr_dc5[2]^lsu_addr_dc2[2]);
|
||||||
|
|
||||||
assign no_word_merge_dc5 = lsu_busreq_dc5 & ~ldst_dual_dc5 &
|
assign no_word_merge_dc5 = lsu_busreq_dc5 & ~ldst_dual_dc5 &
|
||||||
((lsu_busreq_dc4 & (lsu_pkt_dc4.load | ~addr_match_word_lo_dc5_dc4)) |
|
((lsu_busreq_dc4 & (lsu_pkt_dc4.load | ~addr_match_word_lo_dc5_dc4)) |
|
||||||
(lsu_busreq_dc3 & ~lsu_busreq_dc4 & (lsu_pkt_dc3.load | ~addr_match_word_lo_dc5_dc3)) |
|
(lsu_busreq_dc3 & ~lsu_busreq_dc4 & (lsu_pkt_dc3.load | ~addr_match_word_lo_dc5_dc3)) |
|
||||||
(lsu_busreq_dc2 & ~lsu_busreq_dc3 & ~lsu_busreq_dc4 & (lsu_pkt_dc2.load | ~addr_match_word_lo_dc5_dc2)));
|
(lsu_busreq_dc2 & ~lsu_busreq_dc3 & ~lsu_busreq_dc4 & (lsu_pkt_dc2.load | ~addr_match_word_lo_dc5_dc2)));
|
||||||
|
|
||||||
assign no_dword_merge_dc5 = lsu_busreq_dc5 & ~ldst_dual_dc5 &
|
assign no_dword_merge_dc5 = lsu_busreq_dc5 & ~ldst_dual_dc5 &
|
||||||
((lsu_busreq_dc4 & (lsu_pkt_dc4.load | ~addr_match_dw_lo_dc5_dc4)) |
|
((lsu_busreq_dc4 & (lsu_pkt_dc4.load | ~addr_match_dw_lo_dc5_dc4)) |
|
||||||
(lsu_busreq_dc3 & ~lsu_busreq_dc4 & (lsu_pkt_dc3.load | ~addr_match_dw_lo_dc5_dc3)) |
|
(lsu_busreq_dc3 & ~lsu_busreq_dc4 & (lsu_pkt_dc3.load | ~addr_match_dw_lo_dc5_dc3)) |
|
||||||
(lsu_busreq_dc2 & ~lsu_busreq_dc3 & ~lsu_busreq_dc4 & (lsu_pkt_dc2.load | ~addr_match_dw_lo_dc5_dc2)));
|
(lsu_busreq_dc2 & ~lsu_busreq_dc3 & ~lsu_busreq_dc4 & (lsu_pkt_dc2.load | ~addr_match_dw_lo_dc5_dc2)));
|
||||||
|
@ -270,7 +270,7 @@ module lsu_bus_intf
|
||||||
assign store_data_ext_dc3[63:0] = {32'b0,store_data_dc3[31:0]} << {lsu_addr_dc3[1:0],3'b0};
|
assign store_data_ext_dc3[63:0] = {32'b0,store_data_dc3[31:0]} << {lsu_addr_dc3[1:0],3'b0};
|
||||||
assign store_data_ext_dc4[63:0] = {32'b0,store_data_dc4[31:0]} << {lsu_addr_dc4[1:0],3'b0};
|
assign store_data_ext_dc4[63:0] = {32'b0,store_data_dc4[31:0]} << {lsu_addr_dc4[1:0],3'b0};
|
||||||
assign store_data_ext_dc5[63:0] = {32'b0,store_data_dc5[31:0]} << {lsu_addr_dc5[1:0],3'b0};
|
assign store_data_ext_dc5[63:0] = {32'b0,store_data_dc5[31:0]} << {lsu_addr_dc5[1:0],3'b0};
|
||||||
|
|
||||||
assign ldst_byteen_hi_dc2[3:0] = ldst_byteen_ext_dc2[7:4];
|
assign ldst_byteen_hi_dc2[3:0] = ldst_byteen_ext_dc2[7:4];
|
||||||
assign ldst_byteen_lo_dc2[3:0] = ldst_byteen_ext_dc2[3:0];
|
assign ldst_byteen_lo_dc2[3:0] = ldst_byteen_ext_dc2[3:0];
|
||||||
assign ldst_byteen_hi_dc3[3:0] = ldst_byteen_ext_dc3[7:4];
|
assign ldst_byteen_hi_dc3[3:0] = ldst_byteen_ext_dc3[7:4];
|
||||||
|
@ -286,7 +286,7 @@ module lsu_bus_intf
|
||||||
assign store_data_lo_dc4[31:0] = store_data_ext_dc4[31:0];
|
assign store_data_lo_dc4[31:0] = store_data_ext_dc4[31:0];
|
||||||
assign store_data_hi_dc5[31:0] = store_data_ext_dc5[63:32];
|
assign store_data_hi_dc5[31:0] = store_data_ext_dc5[63:32];
|
||||||
assign store_data_lo_dc5[31:0] = store_data_ext_dc5[31:0];
|
assign store_data_lo_dc5[31:0] = store_data_ext_dc5[31:0];
|
||||||
|
|
||||||
assign ld_addr_dc3hit_lo_lo = (lsu_addr_dc2[31:2] == lsu_addr_dc3[31:2]) & lsu_pkt_dc3.valid & lsu_pkt_dc3.store & lsu_busreq_dc2;
|
assign ld_addr_dc3hit_lo_lo = (lsu_addr_dc2[31:2] == lsu_addr_dc3[31:2]) & lsu_pkt_dc3.valid & lsu_pkt_dc3.store & lsu_busreq_dc2;
|
||||||
assign ld_addr_dc3hit_lo_hi = (end_addr_dc2[31:2] == lsu_addr_dc3[31:2]) & lsu_pkt_dc3.valid & lsu_pkt_dc3.store & lsu_busreq_dc2;
|
assign ld_addr_dc3hit_lo_hi = (end_addr_dc2[31:2] == lsu_addr_dc3[31:2]) & lsu_pkt_dc3.valid & lsu_pkt_dc3.store & lsu_busreq_dc2;
|
||||||
assign ld_addr_dc3hit_hi_lo = (lsu_addr_dc2[31:2] == end_addr_dc3[31:2]) & lsu_pkt_dc3.valid & lsu_pkt_dc3.store & lsu_busreq_dc2;
|
assign ld_addr_dc3hit_hi_lo = (lsu_addr_dc2[31:2] == end_addr_dc3[31:2]) & lsu_pkt_dc3.valid & lsu_pkt_dc3.store & lsu_busreq_dc2;
|
||||||
|
@ -356,7 +356,7 @@ module lsu_bus_intf
|
||||||
ld_byte_dc4hit_lo[i] ? ld_fwddata_dc4pipe_lo[(8*i)+7:(8*i)] :
|
ld_byte_dc4hit_lo[i] ? ld_fwddata_dc4pipe_lo[(8*i)+7:(8*i)] :
|
||||||
ld_byte_dc5hit_lo[i] ? ld_fwddata_dc5pipe_lo[(8*i)+7:(8*i)] :
|
ld_byte_dc5hit_lo[i] ? ld_fwddata_dc5pipe_lo[(8*i)+7:(8*i)] :
|
||||||
ld_fwddata_buf_lo[(8*i)+7:(8*i)];
|
ld_fwddata_buf_lo[(8*i)+7:(8*i)];
|
||||||
|
|
||||||
assign ld_fwddata_hi[(8*i)+7:(8*i)] = ld_byte_dc3hit_hi[i] ? ld_fwddata_dc3pipe_hi[(8*i)+7:(8*i)] :
|
assign ld_fwddata_hi[(8*i)+7:(8*i)] = ld_byte_dc3hit_hi[i] ? ld_fwddata_dc3pipe_hi[(8*i)+7:(8*i)] :
|
||||||
ld_byte_dc4hit_hi[i] ? ld_fwddata_dc4pipe_hi[(8*i)+7:(8*i)] :
|
ld_byte_dc4hit_hi[i] ? ld_fwddata_dc4pipe_hi[(8*i)+7:(8*i)] :
|
||||||
ld_byte_dc5hit_hi[i] ? ld_fwddata_dc5pipe_hi[(8*i)+7:(8*i)] :
|
ld_byte_dc5hit_hi[i] ? ld_fwddata_dc5pipe_hi[(8*i)+7:(8*i)] :
|
||||||
|
@ -364,7 +364,7 @@ module lsu_bus_intf
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
always_comb begin
|
always_comb begin
|
||||||
ld_full_hit_lo_dc2 = 1'b1;
|
ld_full_hit_lo_dc2 = 1'b1;
|
||||||
ld_full_hit_hi_dc2 = 1'b1;
|
ld_full_hit_hi_dc2 = 1'b1;
|
||||||
for (int i=0; i<4; i++) begin
|
for (int i=0; i<4; i++) begin
|
||||||
|
@ -381,7 +381,7 @@ module lsu_bus_intf
|
||||||
|
|
||||||
assign {ld_fwddata_dc2_nc[63:32], ld_fwddata_dc2[31:0]} = {ld_fwddata_hi[31:0], ld_fwddata_lo[31:0]} >> (8*lsu_addr_dc2[1:0]);
|
assign {ld_fwddata_dc2_nc[63:32], ld_fwddata_dc2[31:0]} = {ld_fwddata_hi[31:0], ld_fwddata_lo[31:0]} >> (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];
|
assign bus_read_data_dc3[31:0] = ld_full_hit_dc3 ? ld_fwddata_dc3[31:0] : ld_bus_data_dc3[31:0];
|
||||||
|
|
||||||
// Fifo flops
|
// 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(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), .*);
|
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_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_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));
|
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
|
`ifdef ASSERT_ON
|
||||||
// Assertion to check ld imprecise error comes with right address
|
// Assertion to check ld imprecise error comes with right address
|
||||||
// property lsu_ld_imprecise_error_check;
|
// property lsu_ld_imprecise_error_check;
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
// Copyright 2019 Western Digital Corporation or its affiliates.
|
// Copyright 2019 Western Digital Corporation or its affiliates.
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "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 not use this file except in compliance with the License.
|
||||||
// You may obtain a copy of the License at
|
// You may obtain a copy of the License at
|
||||||
//
|
//
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
//
|
//
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
@ -16,21 +16,21 @@
|
||||||
//********************************************************************************
|
//********************************************************************************
|
||||||
// $Id$
|
// $Id$
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// Owner:
|
// Owner:
|
||||||
// Function: Clock Generation Block
|
// Function: Clock Generation Block
|
||||||
// Comments: All the clocks are generate here
|
// Comments: All the clocks are generate here
|
||||||
//
|
//
|
||||||
// //********************************************************************************
|
// //********************************************************************************
|
||||||
|
|
||||||
|
|
||||||
module lsu_clkdomain
|
module lsu_clkdomain
|
||||||
import swerv_types::*;
|
import swerv_types::*;
|
||||||
(
|
(
|
||||||
input logic clk, // clock
|
input logic clk, // clock
|
||||||
input logic free_clk, // clock
|
input logic free_clk, // clock
|
||||||
input logic rst_l, // reset
|
input logic rst_l, // reset
|
||||||
|
|
||||||
// Inputs
|
// Inputs
|
||||||
input logic clk_override, // chciken bit to turn off clock gating
|
input logic clk_override, // chciken bit to turn off clock gating
|
||||||
input logic lsu_freeze_dc3, // freeze
|
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_load_stall_any, // Need to turn on clocks for this case
|
||||||
|
|
||||||
input logic lsu_bus_clk_en, // bus clock enable
|
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_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_dc3, // lsu packet in dc3
|
||||||
input lsu_pkt_t lsu_pkt_dc4, // lsu packet in dc4
|
input lsu_pkt_t lsu_pkt_dc4, // lsu packet in dc4
|
||||||
input lsu_pkt_t lsu_pkt_dc5, // lsu packet in dc5
|
input lsu_pkt_t lsu_pkt_dc5, // lsu packet in dc5
|
||||||
|
|
||||||
// Outputs
|
// Outputs
|
||||||
output logic lsu_c1_dc3_clk, // dc3 pipe single pulse clock
|
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_dc4_clk, // dc4 pipe single pulse clock
|
||||||
output logic lsu_c1_dc5_clk, // dc5 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_dc3_clk, // dc3 pipe double pulse clock
|
||||||
output logic lsu_c2_dc4_clk, // dc4 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_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_dc2_clken, // store in dc2
|
||||||
output logic lsu_store_c1_dc3_clken, // store in dc3
|
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_dc4_clk, // store in dc4
|
||||||
output logic lsu_store_c1_dc5_clk, // store in dc5
|
output logic lsu_store_c1_dc5_clk, // store in dc5
|
||||||
|
|
||||||
output logic lsu_freeze_c1_dc1_clken, // freeze
|
output logic lsu_freeze_c1_dc1_clken, // freeze
|
||||||
output logic lsu_freeze_c1_dc2_clken, // freeze
|
output logic lsu_freeze_c1_dc2_clken, // freeze
|
||||||
output logic lsu_freeze_c1_dc3_clken, // freeze
|
output logic lsu_freeze_c1_dc3_clken, // freeze
|
||||||
|
|
||||||
output logic lsu_freeze_c1_dc2_clk, // freeze
|
output logic lsu_freeze_c1_dc2_clk, // freeze
|
||||||
output logic lsu_freeze_c1_dc3_clk, // freeze
|
output logic lsu_freeze_c1_dc3_clk, // freeze
|
||||||
|
|
||||||
output logic lsu_freeze_c2_dc1_clk,
|
output logic lsu_freeze_c2_dc1_clk,
|
||||||
output logic lsu_freeze_c2_dc2_clk,
|
output logic lsu_freeze_c2_dc2_clk,
|
||||||
output logic lsu_freeze_c2_dc3_clk,
|
output logic lsu_freeze_c2_dc3_clk,
|
||||||
output logic lsu_freeze_c2_dc4_clk,
|
output logic lsu_freeze_c2_dc4_clk,
|
||||||
|
|
||||||
output logic lsu_dccm_c1_dc3_clk, // dccm clock
|
output logic lsu_dccm_c1_dc3_clk, // dccm clock
|
||||||
output logic lsu_pic_c1_dc3_clken, // pic clock enable
|
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_obuf_c1_clk, // ibuf clock
|
||||||
output logic lsu_bus_ibuf_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_bus_buf_c1_clk, // ibuf clock
|
||||||
output logic lsu_busm_clk, // bus clock
|
output logic lsu_busm_clk, // bus clock
|
||||||
|
|
||||||
output logic lsu_free_c2_clk,
|
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_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_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_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_store_c1_dc4_clken, lsu_store_c1_dc5_clken;
|
||||||
|
|
||||||
logic lsu_freeze_c1_dc4_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_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_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_stbuf_c1_clken;
|
||||||
logic lsu_bus_ibuf_c1_clken, lsu_bus_obuf_c1_clken, lsu_bus_buf_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_dccm_c1_dc3_clken;
|
||||||
|
|
||||||
logic lsu_free_c1_clken, lsu_free_c1_clken_q, lsu_free_c2_clken;
|
logic lsu_free_c1_clken, lsu_free_c1_clken_q, lsu_free_c2_clken;
|
||||||
logic lsu_bus_valid_clken;
|
logic lsu_bus_valid_clken;
|
||||||
|
|
||||||
//-------------------------------------------------------------------------------------------
|
//-------------------------------------------------------------------------------------------
|
||||||
// Clock Enable logic
|
// 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
|
// 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_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;
|
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_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_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_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_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_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_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_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_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_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_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_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_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_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;
|
~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;
|
assign lsu_free_c2_clken = lsu_free_c1_clken | lsu_free_c1_clken_q | clk_override;
|
||||||
|
|
||||||
// Flops
|
// Flops
|
||||||
rvdff #(1) lsu_free_c1_clkenff (.din(lsu_free_c1_clken), .dout(lsu_free_c1_clken_q), .clk(free_clk), .*);
|
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), .* );
|
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_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_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_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), .*);
|
rvclkhdr lsu_free_cgc (.en(lsu_free_c2_clken), .l1clk(lsu_free_c2_clk), .*);
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
// Copyright 2019 Western Digital Corporation or its affiliates.
|
// Copyright 2019 Western Digital Corporation or its affiliates.
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "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 not use this file except in compliance with the License.
|
||||||
// You may obtain a copy of the License at
|
// You may obtain a copy of the License at
|
||||||
//
|
//
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
//
|
//
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
@ -16,28 +16,28 @@
|
||||||
//********************************************************************************
|
//********************************************************************************
|
||||||
// $Id$
|
// $Id$
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// Owner:
|
// Owner:
|
||||||
// Function: DCCM for LSU pipe
|
// Function: DCCM for LSU pipe
|
||||||
// Comments: Single ported memory
|
// Comments: Single ported memory
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// DC1 -> DC2 -> DC3 -> DC4 (Commit)
|
// DC1 -> DC2 -> DC3 -> DC4 (Commit)
|
||||||
//
|
//
|
||||||
// //********************************************************************************
|
// //********************************************************************************
|
||||||
|
|
||||||
module lsu_dccm_ctl
|
module lsu_dccm_ctl
|
||||||
import swerv_types::*;
|
import swerv_types::*;
|
||||||
(
|
(
|
||||||
input logic lsu_freeze_c2_dc2_clk, // clocks
|
input logic lsu_freeze_c2_dc2_clk, // clocks
|
||||||
input logic lsu_freeze_c2_dc3_clk,
|
input logic lsu_freeze_c2_dc3_clk,
|
||||||
input logic lsu_dccm_c1_dc3_clk,
|
input logic lsu_dccm_c1_dc3_clk,
|
||||||
input logic lsu_pic_c1_dc3_clken,
|
input logic lsu_pic_c1_dc3_clken,
|
||||||
|
|
||||||
input logic rst_l,
|
input logic rst_l,
|
||||||
input logic clk,
|
input logic clk,
|
||||||
input logic lsu_freeze_dc3, // freze
|
input logic lsu_freeze_dc3, // freze
|
||||||
|
|
||||||
input lsu_pkt_t lsu_pkt_dc3, // lsu packets
|
input lsu_pkt_t lsu_pkt_dc3, // lsu packets
|
||||||
input lsu_pkt_t lsu_pkt_dc1,
|
input lsu_pkt_t lsu_pkt_dc1,
|
||||||
input logic addr_in_dccm_dc1, // address maps to dccm
|
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_reqvld_any, // write enable
|
||||||
input logic stbuf_addr_in_pic_any, // stbuf is going to pic
|
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_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_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_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_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_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 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_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_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_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_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_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 [`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 [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_stbuf_commit_any, // stbuf wins the dccm port or is to pic
|
||||||
output logic lsu_dccm_rden_dc3, // dccm read
|
output logic lsu_dccm_rden_dc3, // dccm read
|
||||||
|
|
||||||
output logic dccm_dma_rvalid, // dccm serviving the dma load
|
output logic dccm_dma_rvalid, // dccm serviving the dma load
|
||||||
output logic dccm_dma_ecc_error, // DMA load had ecc error
|
output logic dccm_dma_ecc_error, // DMA load had ecc error
|
||||||
output logic [63:0] dccm_dma_rdata, // dccm data to dma request
|
output logic [63:0] dccm_dma_rdata, // dccm data to dma request
|
||||||
|
|
||||||
// DCCM ports
|
// DCCM ports
|
||||||
output logic dccm_wren, // dccm interface -- write
|
output logic dccm_wren, // dccm interface -- write
|
||||||
output logic dccm_rden, // 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_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_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
|
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_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
|
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_addr, // address for pic access - shared between reads and write
|
||||||
output logic [31:0] picm_wr_data, // write data
|
output logic [31:0] picm_wr_data, // write data
|
||||||
input logic [31:0] picm_rd_data, // read 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"
|
`include "global.h"
|
||||||
|
|
||||||
`ifdef RV_DCCM_ENABLE
|
`ifdef RV_DCCM_ENABLE
|
||||||
localparam DCCM_ENABLE = 1'b1;
|
localparam DCCM_ENABLE = 1'b1;
|
||||||
`else
|
`else
|
||||||
|
@ -108,7 +108,7 @@ module lsu_dccm_ctl
|
||||||
|
|
||||||
localparam DCCM_WIDTH_BITS = $clog2(DCCM_BYTE_WIDTH);
|
localparam DCCM_WIDTH_BITS = $clog2(DCCM_BYTE_WIDTH);
|
||||||
localparam PIC_BITS =`RV_PIC_BITS;
|
localparam PIC_BITS =`RV_PIC_BITS;
|
||||||
|
|
||||||
logic lsu_dccm_rden_dc1, lsu_dccm_rden_dc2;
|
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_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;
|
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 [63:0] picm_rd_data_dc3;
|
||||||
logic [31:0] picm_rd_data_lo_dc3;
|
logic [31:0] picm_rd_data_lo_dc3;
|
||||||
logic [63:32] lsu_ld_data_dc3_nc, lsu_ld_data_corr_dc3_nc;
|
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_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_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_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 {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_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 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_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]};
|
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
|
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]);
|
(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]);
|
(addr_in_pic_dc3 ? picm_rd_data_dc3[(8*i)+7:8*i] : dccm_corr_dout_dc3[(8*i)+7:8*i]);
|
||||||
end
|
end
|
||||||
|
|
||||||
assign lsu_stbuf_commit_any = stbuf_reqvld_any & ~lsu_freeze_dc3 & (
|
assign lsu_stbuf_commit_any = stbuf_reqvld_any & ~lsu_freeze_dc3 & (
|
||||||
(~(lsu_dccm_rden_dc1 | picm_rden | picm_mken)) |
|
(~(lsu_dccm_rden_dc1 | picm_rden | picm_mken)) |
|
||||||
((picm_rden | picm_mken) & ~stbuf_addr_in_pic_any) |
|
((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]))))));
|
(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
|
// 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_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_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_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_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_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];
|
assign picm_wr_data[31:0] = stbuf_data_any[31:0];
|
||||||
|
|
||||||
|
|
||||||
// Flops
|
// Flops
|
||||||
assign picm_mask_data_dc3[31:0] = picm_rd_data_lo_dc3[31:0];
|
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));
|
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
|
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));
|
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_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_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_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));
|
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
|
end else begin: Gen_dccm_disable
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
// Copyright 2019 Western Digital Corporation or its affiliates.
|
// Copyright 2019 Western Digital Corporation or its affiliates.
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "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 not use this file except in compliance with the License.
|
||||||
// You may obtain a copy of the License at
|
// You may obtain a copy of the License at
|
||||||
//
|
//
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
//
|
//
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
@ -16,31 +16,31 @@
|
||||||
//********************************************************************************
|
//********************************************************************************
|
||||||
// $Id$
|
// $Id$
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// Owner:
|
// Owner:
|
||||||
// Function: DCCM for LSU pipe
|
// Function: DCCM for LSU pipe
|
||||||
// Comments: Single ported memory
|
// Comments: Single ported memory
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// DC1 -> DC2 -> DC3 -> DC4 (Commit)
|
// DC1 -> DC2 -> DC3 -> DC4 (Commit)
|
||||||
//
|
//
|
||||||
// //********************************************************************************
|
// //********************************************************************************
|
||||||
|
|
||||||
module lsu_dccm_mem
|
module lsu_dccm_mem
|
||||||
import swerv_types::*;
|
import swerv_types::*;
|
||||||
(
|
(
|
||||||
input logic clk, // clock
|
input logic clk, // clock
|
||||||
input logic rst_l,
|
input logic rst_l,
|
||||||
input logic lsu_freeze_dc3, // freeze
|
input logic lsu_freeze_dc3, // freeze
|
||||||
input logic clk_override, // clock override
|
input logic clk_override, // clock override
|
||||||
|
|
||||||
input logic dccm_wren, // write enable
|
input logic dccm_wren, // write enable
|
||||||
input logic dccm_rden, // read 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_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_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_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
|
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_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
|
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"
|
`include "global.h"
|
||||||
|
|
||||||
localparam DCCM_WIDTH_BITS = $clog2(DCCM_BYTE_WIDTH);
|
localparam DCCM_WIDTH_BITS = $clog2(DCCM_BYTE_WIDTH);
|
||||||
localparam DCCM_INDEX_BITS = (DCCM_BITS - DCCM_BANK_BITS - DCCM_WIDTH_BITS);
|
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] wren_bank;
|
||||||
logic [DCCM_NUM_BANKS-1:0] rden_bank;
|
logic [DCCM_NUM_BANKS-1:0] rden_bank;
|
||||||
logic [DCCM_NUM_BANKS-1:0] [DCCM_BITS-1:(DCCM_BANK_BITS+2)] addr_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_lo_q;
|
||||||
logic [(DCCM_WIDTH_BITS+DCCM_BANK_BITS-1):DCCM_WIDTH_BITS] dccm_rd_addr_hi_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_clk;
|
||||||
logic [DCCM_NUM_BANKS-1:0] dccm_clken;
|
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]);
|
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
|
// 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_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];
|
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
|
// 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];
|
// 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] :
|
// 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];
|
// dccm_rd_addr_hi[(DCCM_BANK_BITS+DCCM_WIDTH_BITS)+:DCCM_INDEX_BITS];
|
||||||
|
|
||||||
// 8 Banks, 16KB each (2048 x 72)
|
// 8 Banks, 16KB each (2048 x 72)
|
||||||
for (genvar i=0; i<DCCM_NUM_BANKS; i++) begin: mem_bank
|
for (genvar i=0; i<DCCM_NUM_BANKS; i++) begin: mem_bank
|
||||||
assign wren_bank[i] = dccm_wren & (dccm_wr_addr[2+:DCCM_BANK_BITS] == i);
|
assign wren_bank[i] = dccm_wren & (dccm_wr_addr[2+:DCCM_BANK_BITS] == i);
|
||||||
assign rden_bank[i] = dccm_rden & ((dccm_rd_addr_hi[2+:DCCM_BANK_BITS] == i) | (dccm_rd_addr_lo[2+:DCCM_BANK_BITS] == i));
|
assign rden_bank[i] = dccm_rden & ((dccm_rd_addr_hi[2+:DCCM_BANK_BITS] == i) | (dccm_rd_addr_lo[2+:DCCM_BANK_BITS] == i));
|
||||||
assign addr_bank[i][(DCCM_BANK_BITS+DCCM_WIDTH_BITS)+:DCCM_INDEX_BITS] = wren_bank[i] ? dccm_wr_addr[(DCCM_BANK_BITS+DCCM_WIDTH_BITS)+:DCCM_INDEX_BITS] :
|
assign addr_bank[i][(DCCM_BANK_BITS+DCCM_WIDTH_BITS)+:DCCM_INDEX_BITS] = wren_bank[i] ? dccm_wr_addr[(DCCM_BANK_BITS+DCCM_WIDTH_BITS)+:DCCM_INDEX_BITS] :
|
||||||
(((dccm_rd_addr_hi[2+:DCCM_BANK_BITS] == i) & rd_unaligned) ?
|
(((dccm_rd_addr_hi[2+:DCCM_BANK_BITS] == i) & rd_unaligned) ?
|
||||||
dccm_rd_addr_hi[(DCCM_BANK_BITS+DCCM_WIDTH_BITS)+:DCCM_INDEX_BITS] :
|
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]);
|
dccm_rd_addr_lo[(DCCM_BANK_BITS+DCCM_WIDTH_BITS)+:DCCM_INDEX_BITS]);
|
||||||
|
|
||||||
// if (i%2 == 0) begin
|
// if (i%2 == 0) begin
|
||||||
|
@ -100,11 +100,11 @@ module lsu_dccm_mem
|
||||||
// assign addr_bank[i][(DCCM_BANK_BITS+DCCM_WIDTH_BITS)+:DCCM_INDEX_BITS] = wren_bank[i] ? dccm_wr_addr[(DCCM_BANK_BITS+DCCM_WIDTH_BITS)+:DCCM_INDEX_BITS] :
|
// assign addr_bank[i][(DCCM_BANK_BITS+DCCM_WIDTH_BITS)+:DCCM_INDEX_BITS] = wren_bank[i] ? dccm_wr_addr[(DCCM_BANK_BITS+DCCM_WIDTH_BITS)+:DCCM_INDEX_BITS] :
|
||||||
// rd_addr_odd[(DCCM_BANK_BITS+DCCM_WIDTH_BITS)+:DCCM_INDEX_BITS];
|
// rd_addr_odd[(DCCM_BANK_BITS+DCCM_WIDTH_BITS)+:DCCM_INDEX_BITS];
|
||||||
// end
|
// end
|
||||||
|
|
||||||
// clock gating section
|
// clock gating section
|
||||||
assign dccm_clken[i] = (wren_bank[i] | rden_bank[i] | clk_override) & ~lsu_freeze_dc3;
|
assign dccm_clken[i] = (wren_bank[i] | rden_bank[i] | clk_override) & ~lsu_freeze_dc3;
|
||||||
rvclkhdr lsu_dccm_cgc (.en(dccm_clken[i]), .l1clk(dccm_clk[i]), .*);
|
rvclkhdr lsu_dccm_cgc (.en(dccm_clken[i]), .l1clk(dccm_clk[i]), .*);
|
||||||
// end clock gating section
|
// end clock gating section
|
||||||
|
|
||||||
`RV_DCCM_DATA_CELL dccm_bank (
|
`RV_DCCM_DATA_CELL dccm_bank (
|
||||||
// Primary ports
|
// Primary ports
|
||||||
|
@ -115,9 +115,9 @@ module lsu_dccm_mem
|
||||||
.Q(dccm_bank_dout[i][DCCM_FDATA_WIDTH-1:0])
|
.Q(dccm_bank_dout[i][DCCM_FDATA_WIDTH-1:0])
|
||||||
|
|
||||||
);
|
);
|
||||||
|
|
||||||
end : mem_bank
|
end : mem_bank
|
||||||
|
|
||||||
// Flops
|
// Flops
|
||||||
rvdffs #(DCCM_BANK_BITS) rd_addr_lo_ff (.*, .din(dccm_rd_addr_lo[DCCM_WIDTH_BITS+:DCCM_BANK_BITS]), .dout(dccm_rd_addr_lo_q[DCCM_WIDTH_BITS+:DCCM_BANK_BITS]), .en(~lsu_freeze_dc3));
|
rvdffs #(DCCM_BANK_BITS) rd_addr_lo_ff (.*, .din(dccm_rd_addr_lo[DCCM_WIDTH_BITS+:DCCM_BANK_BITS]), .dout(dccm_rd_addr_lo_q[DCCM_WIDTH_BITS+:DCCM_BANK_BITS]), .en(~lsu_freeze_dc3));
|
||||||
rvdffs #(DCCM_BANK_BITS) rd_addr_hi_ff (.*, .din(dccm_rd_addr_hi[DCCM_WIDTH_BITS+:DCCM_BANK_BITS]), .dout(dccm_rd_addr_hi_q[DCCM_WIDTH_BITS+:DCCM_BANK_BITS]), .en(~lsu_freeze_dc3));
|
rvdffs #(DCCM_BANK_BITS) rd_addr_hi_ff (.*, .din(dccm_rd_addr_hi[DCCM_WIDTH_BITS+:DCCM_BANK_BITS]), .dout(dccm_rd_addr_hi_q[DCCM_WIDTH_BITS+:DCCM_BANK_BITS]), .en(~lsu_freeze_dc3));
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
// Copyright 2019 Western Digital Corporation or its affiliates.
|
// Copyright 2019 Western Digital Corporation or its affiliates.
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "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 not use this file except in compliance with the License.
|
||||||
// You may obtain a copy of the License at
|
// You may obtain a copy of the License at
|
||||||
//
|
//
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
//
|
//
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
@ -16,16 +16,16 @@
|
||||||
//********************************************************************************
|
//********************************************************************************
|
||||||
// $Id$
|
// $Id$
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// Owner:
|
// Owner:
|
||||||
// Function: Top level file for load store unit
|
// Function: Top level file for load store unit
|
||||||
// Comments:
|
// Comments:
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// DC1 -> DC2 -> DC3 -> DC4 (Commit)
|
// DC1 -> DC2 -> DC3 -> DC4 (Commit)
|
||||||
//
|
//
|
||||||
//********************************************************************************
|
//********************************************************************************
|
||||||
module lsu_ecc
|
module lsu_ecc
|
||||||
import swerv_types::*;
|
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] lsu_addr_dc3, // start address
|
||||||
input logic [`RV_DCCM_BITS-1:0] end_addr_dc3, // end address
|
input logic [`RV_DCCM_BITS-1:0] end_addr_dc3, // end address
|
||||||
input logic [63:0] store_data_dc3, // store data
|
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_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_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_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_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_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_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_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 [`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
|
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_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_hi_dc3, // sec detected
|
||||||
output logic single_ecc_error_lo_dc3, // sec detected on lower dccm bank
|
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_single_ecc_error_dc3, // or of the 2
|
||||||
output logic lsu_double_ecc_error_dc3, // double error detected
|
output logic lsu_double_ecc_error_dc3, // double error detected
|
||||||
|
|
||||||
input logic scan_mode
|
input logic scan_mode
|
||||||
);
|
);
|
||||||
|
|
||||||
`include "global.h"
|
`include "global.h"
|
||||||
|
|
||||||
`ifdef RV_DCCM_ENABLE
|
`ifdef RV_DCCM_ENABLE
|
||||||
localparam DCCM_ENABLE = 1'b1;
|
localparam DCCM_ENABLE = 1'b1;
|
||||||
`else
|
`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_hi_dc3;
|
||||||
logic [DCCM_DATA_WIDTH-1:0] sec_data_lo_dc3;
|
logic [DCCM_DATA_WIDTH-1:0] sec_data_lo_dc3;
|
||||||
|
|
||||||
|
|
||||||
logic double_ecc_error_hi_dc3, double_ecc_error_lo_dc3;
|
logic double_ecc_error_hi_dc3, double_ecc_error_lo_dc3;
|
||||||
|
|
||||||
logic ldst_dual_dc3;
|
logic ldst_dual_dc3;
|
||||||
|
@ -88,12 +88,12 @@ module lsu_ecc
|
||||||
logic [7:0] store_byteen_dc3;
|
logic [7:0] store_byteen_dc3;
|
||||||
logic [7:0] store_byteen_ext_dc3;
|
logic [7:0] store_byteen_ext_dc3;
|
||||||
logic [DCCM_BYTE_WIDTH-1:0] store_byteen_hi_dc3, store_byteen_lo_dc3;
|
logic [DCCM_BYTE_WIDTH-1:0] store_byteen_hi_dc3, store_byteen_lo_dc3;
|
||||||
|
|
||||||
logic [163:0] store_data_ext_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;
|
logic [6:0] ecc_out_hi_nc, ecc_out_lo_nc;
|
||||||
|
|
||||||
|
|
||||||
assign ldst_dual_dc3 = (lsu_addr_dc3[2] != end_addr_dc3[2]);
|
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_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;
|
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.word}} & 8'b0000_1111) |
|
||||||
({8{lsu_pkt_dc3.dword}} & 8'b1111_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_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_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_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];
|
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_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];
|
assign store_data_lo_dc3[DCCM_DATA_WIDTH-1:0] = store_data_ext_dc3[31:0];
|
||||||
|
|
||||||
|
|
||||||
// Merge store data and sec data
|
// Merge store data and sec data
|
||||||
// This is used for loads as well for ecc error case. store_byteen will be 0 for loads
|
// This is used for loads as well for ecc error case. store_byteen will be 0 for loads
|
||||||
for (genvar i=0; i<DCCM_BYTE_WIDTH; i++) begin
|
for (genvar i=0; i<DCCM_BYTE_WIDTH; i++) begin
|
||||||
|
@ -133,26 +133,26 @@ module lsu_ecc
|
||||||
.ecc_in(dccm_data_ecc_hi_dc3[DCCM_ECC_WIDTH-1:0]),
|
.ecc_in(dccm_data_ecc_hi_dc3[DCCM_ECC_WIDTH-1:0]),
|
||||||
// Outputs
|
// Outputs
|
||||||
.dout(sec_data_hi_dc3[DCCM_DATA_WIDTH-1:0]),
|
.dout(sec_data_hi_dc3[DCCM_DATA_WIDTH-1:0]),
|
||||||
.ecc_out (ecc_out_hi_nc[6:0]),
|
.ecc_out (ecc_out_hi_nc[6:0]),
|
||||||
.single_ecc_error(single_ecc_error_hi_dc3),
|
.single_ecc_error(single_ecc_error_hi_dc3),
|
||||||
.double_ecc_error(double_ecc_error_hi_dc3),
|
.double_ecc_error(double_ecc_error_hi_dc3),
|
||||||
.*
|
.*
|
||||||
);
|
);
|
||||||
|
|
||||||
rvecc_decode lsu_ecc_decode_lo (
|
rvecc_decode lsu_ecc_decode_lo (
|
||||||
// Inputs
|
// Inputs
|
||||||
.en(is_ldst_lo_dc3),
|
.en(is_ldst_lo_dc3),
|
||||||
.sed_ded (1'b0), // 1 : means only detection
|
.sed_ded (1'b0), // 1 : means only detection
|
||||||
.din(dccm_data_lo_dc3[DCCM_DATA_WIDTH-1:0] ),
|
.din(dccm_data_lo_dc3[DCCM_DATA_WIDTH-1:0] ),
|
||||||
.ecc_in(dccm_data_ecc_lo_dc3[DCCM_ECC_WIDTH-1:0]),
|
.ecc_in(dccm_data_ecc_lo_dc3[DCCM_ECC_WIDTH-1:0]),
|
||||||
// Outputs
|
// Outputs
|
||||||
.dout(sec_data_lo_dc3[DCCM_DATA_WIDTH-1:0]),
|
.dout(sec_data_lo_dc3[DCCM_DATA_WIDTH-1:0]),
|
||||||
.ecc_out (ecc_out_lo_nc[6:0]),
|
.ecc_out (ecc_out_lo_nc[6:0]),
|
||||||
.single_ecc_error(single_ecc_error_lo_dc3),
|
.single_ecc_error(single_ecc_error_lo_dc3),
|
||||||
.double_ecc_error(double_ecc_error_lo_dc3),
|
.double_ecc_error(double_ecc_error_lo_dc3),
|
||||||
.*
|
.*
|
||||||
);
|
);
|
||||||
|
|
||||||
// Generate the ECC bits for store buffer drain
|
// Generate the ECC bits for store buffer drain
|
||||||
rvecc_encode lsu_ecc_encode (
|
rvecc_encode lsu_ecc_encode (
|
||||||
//Inputs
|
//Inputs
|
||||||
|
@ -171,15 +171,15 @@ module lsu_ecc
|
||||||
|
|
||||||
assign stbuf_ecc_any[DCCM_ECC_WIDTH-1:0] = '0;
|
assign stbuf_ecc_any[DCCM_ECC_WIDTH-1:0] = '0;
|
||||||
end
|
end
|
||||||
|
|
||||||
assign lsu_single_ecc_error_dc3 = single_ecc_error_hi_dc3 | single_ecc_error_lo_dc3;
|
assign lsu_single_ecc_error_dc3 = single_ecc_error_hi_dc3 | single_ecc_error_lo_dc3;
|
||||||
assign lsu_double_ecc_error_dc3 = double_ecc_error_hi_dc3 | double_ecc_error_lo_dc3;
|
assign lsu_double_ecc_error_dc3 = double_ecc_error_hi_dc3 | double_ecc_error_lo_dc3;
|
||||||
|
|
||||||
|
|
||||||
`ifdef ASSERT_ON
|
`ifdef ASSERT_ON
|
||||||
|
|
||||||
// ecc_check: assert property (@(posedge clk) ~(single_ecc_error_lo_dc3 | single_ecc_error_hi_dc3));
|
// ecc_check: assert property (@(posedge clk) ~(single_ecc_error_lo_dc3 | single_ecc_error_hi_dc3));
|
||||||
|
|
||||||
`endif
|
`endif
|
||||||
|
|
||||||
endmodule // lsu_ecc
|
endmodule // lsu_ecc
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
// Copyright 2019 Western Digital Corporation or its affiliates.
|
// Copyright 2019 Western Digital Corporation or its affiliates.
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "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 not use this file except in compliance with the License.
|
||||||
// You may obtain a copy of the License at
|
// You may obtain a copy of the License at
|
||||||
//
|
//
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
//
|
//
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
@ -16,65 +16,66 @@
|
||||||
//********************************************************************************
|
//********************************************************************************
|
||||||
// $Id$
|
// $Id$
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// Owner:
|
// Owner:
|
||||||
// Function: LSU control
|
// Function: LSU control
|
||||||
// Comments:
|
// Comments:
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// DC1 -> DC2 -> DC3 -> DC4 (Commit)
|
// DC1 -> DC2 -> DC3 -> DC4 (Commit)
|
||||||
//
|
//
|
||||||
//********************************************************************************
|
//********************************************************************************
|
||||||
module lsu_lsc_ctl
|
module lsu_lsc_ctl
|
||||||
import swerv_types::*;
|
import swerv_types::*;
|
||||||
(
|
(
|
||||||
input logic rst_l,
|
input logic rst_l,
|
||||||
input logic clk,
|
input logic clk,
|
||||||
|
|
||||||
// clocks per pipe
|
// clocks per pipe
|
||||||
input logic lsu_c1_dc4_clk,
|
input logic lsu_c1_dc4_clk,
|
||||||
input logic lsu_c1_dc5_clk,
|
input logic lsu_c1_dc5_clk,
|
||||||
input logic lsu_c2_dc4_clk,
|
input logic lsu_c2_dc4_clk,
|
||||||
input logic lsu_c2_dc5_clk,
|
input logic lsu_c2_dc5_clk,
|
||||||
// freez clocks per pipe
|
// freez clocks per pipe
|
||||||
input logic lsu_freeze_c1_dc1_clken,
|
input logic lsu_freeze_c1_dc1_clken,
|
||||||
input logic lsu_freeze_c1_dc2_clken,
|
input logic lsu_freeze_c1_dc2_clken,
|
||||||
input logic lsu_freeze_c1_dc2_clk,
|
input logic lsu_freeze_c1_dc2_clk,
|
||||||
input logic lsu_freeze_c1_dc3_clken,
|
input logic lsu_freeze_c1_dc3_clken,
|
||||||
input logic lsu_freeze_c1_dc3_clk,
|
input logic lsu_freeze_c1_dc3_clk,
|
||||||
input logic lsu_freeze_c2_dc1_clk,
|
input logic lsu_freeze_c2_dc1_clk,
|
||||||
input logic lsu_freeze_c2_dc2_clk,
|
input logic lsu_freeze_c2_dc2_clk,
|
||||||
input logic lsu_freeze_c2_dc3_clk,
|
input logic lsu_freeze_c2_dc3_clk,
|
||||||
|
|
||||||
input logic lsu_store_c1_dc1_clken,
|
input logic lsu_store_c1_dc1_clken,
|
||||||
input logic lsu_store_c1_dc2_clken,
|
input logic lsu_store_c1_dc2_clken,
|
||||||
input logic lsu_store_c1_dc3_clken,
|
input logic lsu_store_c1_dc3_clken,
|
||||||
input logic lsu_store_c1_dc4_clk,
|
input logic lsu_store_c1_dc4_clk,
|
||||||
input logic lsu_store_c1_dc5_clk,
|
input logic lsu_store_c1_dc5_clk,
|
||||||
|
|
||||||
input logic [31:0] i0_result_e4_eff,
|
input logic [31:0] i0_result_e4_eff,
|
||||||
input logic [31:0] i1_result_e4_eff,
|
input logic [31:0] i1_result_e4_eff,
|
||||||
|
|
||||||
input logic [31:0] i0_result_e2,
|
input logic [31:0] i0_result_e2,
|
||||||
|
|
||||||
input logic ld_bus_error_dc3,
|
input logic ld_bus_error_dc3,
|
||||||
input logic [31:0] ld_bus_error_addr_dc3,
|
input logic [31:0] ld_bus_error_addr_dc3,
|
||||||
input logic lsu_single_ecc_error_dc3,
|
input logic lsu_single_ecc_error_dc3,
|
||||||
|
input logic lsu_single_ecc_error_dc5,
|
||||||
input logic lsu_double_ecc_error_dc3,
|
input logic lsu_double_ecc_error_dc3,
|
||||||
input logic lsu_freeze_dc3,
|
input logic lsu_freeze_dc3,
|
||||||
|
|
||||||
input logic lsu_i0_valid_dc3,
|
input logic lsu_i0_valid_dc3,
|
||||||
input logic flush_dc2_up,
|
input logic flush_dc2_up,
|
||||||
input logic flush_dc3,
|
input logic flush_dc3,
|
||||||
input logic flush_dc4,
|
input logic flush_dc4,
|
||||||
input logic flush_dc5,
|
input logic flush_dc5,
|
||||||
|
|
||||||
input logic [31:0] exu_lsu_rs1_d, // address
|
input logic [31:0] exu_lsu_rs1_d, // address
|
||||||
input logic [31:0] exu_lsu_rs2_d, // store data
|
input logic [31:0] exu_lsu_rs2_d, // store data
|
||||||
|
|
||||||
input lsu_pkt_t lsu_p, // lsu control packet
|
input lsu_pkt_t lsu_p, // lsu control packet
|
||||||
input logic [11:0] dec_lsu_offset_d,
|
input logic [11:0] dec_lsu_offset_d,
|
||||||
|
|
||||||
input logic [31:0] picm_mask_data_dc3,
|
input logic [31:0] picm_mask_data_dc3,
|
||||||
input logic [31:0] lsu_ld_data_dc3,
|
input logic [31:0] lsu_ld_data_dc3,
|
||||||
input logic [31:0] lsu_ld_data_corr_dc3,
|
input logic [31:0] lsu_ld_data_corr_dc3,
|
||||||
|
@ -98,14 +99,15 @@ module lsu_lsc_ctl
|
||||||
output logic [63:0] store_data_dc3,
|
output logic [63:0] store_data_dc3,
|
||||||
output logic [31:0] store_data_dc4,
|
output logic [31:0] store_data_dc4,
|
||||||
output logic [31:0] store_data_dc5,
|
output logic [31:0] store_data_dc5,
|
||||||
|
|
||||||
input logic [31:0] dec_tlu_mrac_ff,
|
input logic [31:0] dec_tlu_mrac_ff,
|
||||||
output logic lsu_exc_dc2,
|
output logic lsu_exc_dc2,
|
||||||
output lsu_error_pkt_t lsu_error_pkt_dc3,
|
output lsu_error_pkt_t lsu_error_pkt_dc3,
|
||||||
|
output logic lsu_single_ecc_error_incr, // Increment the counter for Single ECC error
|
||||||
output logic lsu_freeze_external_ints_dc3,
|
output logic lsu_freeze_external_ints_dc3,
|
||||||
output logic is_sideeffects_dc2,
|
output logic is_sideeffects_dc2,
|
||||||
output logic is_sideeffects_dc3,
|
output logic is_sideeffects_dc3,
|
||||||
output logic lsu_commit_dc5,
|
output logic lsu_commit_dc5,
|
||||||
// address in dccm/pic/external per pipe stage
|
// address in dccm/pic/external per pipe stage
|
||||||
output logic addr_in_dccm_dc1,
|
output logic addr_in_dccm_dc1,
|
||||||
output logic addr_in_dccm_dc2,
|
output logic addr_in_dccm_dc2,
|
||||||
|
@ -117,9 +119,9 @@ module lsu_lsc_ctl
|
||||||
output logic addr_external_dc3,
|
output logic addr_external_dc3,
|
||||||
output logic addr_external_dc4,
|
output logic addr_external_dc4,
|
||||||
output logic addr_external_dc5,
|
output logic addr_external_dc5,
|
||||||
|
|
||||||
// DMA slave
|
// DMA slave
|
||||||
input logic dma_dccm_req,
|
input logic dma_dccm_req,
|
||||||
input logic [31:0] dma_mem_addr,
|
input logic [31:0] dma_mem_addr,
|
||||||
input logic [2:0] dma_mem_sz,
|
input logic [2:0] dma_mem_sz,
|
||||||
input logic dma_mem_write,
|
input logic dma_mem_write,
|
||||||
|
@ -133,7 +135,7 @@ module lsu_lsc_ctl
|
||||||
output lsu_pkt_t lsu_pkt_dc5,
|
output lsu_pkt_t lsu_pkt_dc5,
|
||||||
|
|
||||||
input logic scan_mode
|
input logic scan_mode
|
||||||
|
|
||||||
);
|
);
|
||||||
|
|
||||||
`include "global.h"
|
`include "global.h"
|
||||||
|
@ -149,21 +151,21 @@ module lsu_lsc_ctl
|
||||||
logic [31:0] lsu_ld_datafn_corr_dc3;
|
logic [31:0] lsu_ld_datafn_corr_dc3;
|
||||||
logic [31:0] lsu_result_corr_dc3;
|
logic [31:0] lsu_result_corr_dc3;
|
||||||
logic [2:0] addr_offset_dc1;
|
logic [2:0] addr_offset_dc1;
|
||||||
|
|
||||||
logic [63:0] dma_mem_wdata_shifted;
|
logic [63:0] dma_mem_wdata_shifted;
|
||||||
logic addr_external_dc1;
|
logic addr_external_dc1;
|
||||||
logic access_fault_dc1, misaligned_fault_dc1;
|
logic access_fault_dc1, misaligned_fault_dc1;
|
||||||
logic access_fault_dc2, misaligned_fault_dc2;
|
logic access_fault_dc2, misaligned_fault_dc2;
|
||||||
logic access_fault_dc3, misaligned_fault_dc3;
|
logic access_fault_dc3, misaligned_fault_dc3;
|
||||||
|
|
||||||
logic [63:0] store_data_d;
|
logic [63:0] store_data_d;
|
||||||
logic [63:0] store_data_dc1;
|
logic [63:0] store_data_dc1;
|
||||||
logic [63:0] store_data_pre_dc2;
|
logic [63:0] store_data_pre_dc2;
|
||||||
logic [63:0] store_data_pre_dc3;
|
logic [63:0] store_data_pre_dc3;
|
||||||
logic [63:0] store_data_dc2_in;
|
logic [63:0] store_data_dc2_in;
|
||||||
|
|
||||||
logic [31:0] rs1_dc1_raw;
|
logic [31:0] rs1_dc1_raw;
|
||||||
|
|
||||||
lsu_pkt_t dma_pkt_d;
|
lsu_pkt_t dma_pkt_d;
|
||||||
lsu_pkt_t lsu_pkt_dc1_in, lsu_pkt_dc2_in, lsu_pkt_dc3_in, lsu_pkt_dc4_in, lsu_pkt_dc5_in;
|
lsu_pkt_t lsu_pkt_dc1_in, lsu_pkt_dc2_in, lsu_pkt_dc3_in, lsu_pkt_dc4_in, lsu_pkt_dc5_in;
|
||||||
|
|
||||||
|
@ -175,22 +177,22 @@ module lsu_lsc_ctl
|
||||||
rvdffe #(12) offsetff (.*, .din(lsu_offset_d[11:0]), .dout(offset_dc1[11:0]), .en(lsu_freeze_c1_dc1_clken));
|
rvdffe #(12) offsetff (.*, .din(lsu_offset_d[11:0]), .dout(offset_dc1[11:0]), .en(lsu_freeze_c1_dc1_clken));
|
||||||
|
|
||||||
assign rs1_dc1[31:0] = (lsu_pkt_dc1.load_ldst_bypass_c1) ? lsu_result_dc3[31:0] : rs1_dc1_raw[31:0];
|
assign rs1_dc1[31:0] = (lsu_pkt_dc1.load_ldst_bypass_c1) ? lsu_result_dc3[31:0] : rs1_dc1_raw[31:0];
|
||||||
|
|
||||||
|
|
||||||
// generate the ls address
|
// generate the ls address
|
||||||
// need to refine this is memory is only 128KB
|
// need to refine this is memory is only 128KB
|
||||||
rvlsadder lsadder (.rs1(rs1_dc1[31:0]),
|
rvlsadder lsadder (.rs1(rs1_dc1[31:0]),
|
||||||
.offset(offset_dc1[11:0]),
|
.offset(offset_dc1[11:0]),
|
||||||
.dout(full_addr_dc1[31:0])
|
.dout(full_addr_dc1[31:0])
|
||||||
);
|
);
|
||||||
|
|
||||||
// Module to generate the memory map of the address
|
// Module to generate the memory map of the address
|
||||||
lsu_addrcheck addrcheck (
|
lsu_addrcheck addrcheck (
|
||||||
.start_addr_dc1(full_addr_dc1[31:0]),
|
.start_addr_dc1(full_addr_dc1[31:0]),
|
||||||
.end_addr_dc1(full_end_addr_dc1[31:0]),
|
.end_addr_dc1(full_end_addr_dc1[31:0]),
|
||||||
.*
|
.*
|
||||||
);
|
);
|
||||||
|
|
||||||
// Calculate start/end address for load/store
|
// Calculate start/end address for load/store
|
||||||
assign addr_offset_dc1[2:0] = ({3{lsu_pkt_dc1.half}} & 3'b01) | ({3{lsu_pkt_dc1.word}} & 3'b11) | ({3{lsu_pkt_dc1.dword}} & 3'b111);
|
assign addr_offset_dc1[2:0] = ({3{lsu_pkt_dc1.half}} & 3'b01) | ({3{lsu_pkt_dc1.word}} & 3'b11) | ({3{lsu_pkt_dc1.dword}} & 3'b111);
|
||||||
assign end_addr_offset_dc1[12:0] = {offset_dc1[11],offset_dc1[11:0]} + {9'b0,addr_offset_dc1[2:0]};
|
assign end_addr_offset_dc1[12:0] = {offset_dc1[11],offset_dc1[11:0]} + {9'b0,addr_offset_dc1[2:0]};
|
||||||
|
@ -198,17 +200,20 @@ module lsu_lsc_ctl
|
||||||
assign end_addr_dc1[31:0] = full_end_addr_dc1[31:0];
|
assign end_addr_dc1[31:0] = full_end_addr_dc1[31:0];
|
||||||
assign lsu_exc_dc2 = access_fault_dc2 | misaligned_fault_dc2;
|
assign lsu_exc_dc2 = access_fault_dc2 | misaligned_fault_dc2;
|
||||||
assign lsu_freeze_external_ints_dc3 = lsu_freeze_dc3 & is_sideeffects_dc3;
|
assign lsu_freeze_external_ints_dc3 = lsu_freeze_dc3 & is_sideeffects_dc3;
|
||||||
|
|
||||||
|
// Increment the single bit ecc counter
|
||||||
|
assign lsu_single_ecc_error_incr = lsu_single_ecc_error_dc5 & (lsu_commit_dc5 | lsu_pkt_dc5.dma);
|
||||||
|
|
||||||
// Generate exception packet
|
// Generate exception packet
|
||||||
assign lsu_error_pkt_dc3.exc_valid = (access_fault_dc3 | misaligned_fault_dc3 | ld_bus_error_dc3 | lsu_double_ecc_error_dc3) & lsu_pkt_dc3.valid & ~lsu_pkt_dc3.dma & ~flush_dc3;
|
assign lsu_error_pkt_dc3.exc_valid = (access_fault_dc3 | misaligned_fault_dc3 | ld_bus_error_dc3 | lsu_double_ecc_error_dc3) & lsu_pkt_dc3.valid & ~lsu_pkt_dc3.dma & ~flush_dc3;
|
||||||
assign lsu_error_pkt_dc3.single_ecc_error = lsu_single_ecc_error_dc3;
|
assign lsu_error_pkt_dc3.single_ecc_error = lsu_single_ecc_error_dc3 & ~(access_fault_dc3 | misaligned_fault_dc3 | lsu_double_ecc_error_dc3);
|
||||||
assign lsu_error_pkt_dc3.inst_type = lsu_pkt_dc3.store;
|
assign lsu_error_pkt_dc3.inst_type = lsu_pkt_dc3.store;
|
||||||
assign lsu_error_pkt_dc3.dma_valid = lsu_pkt_dc3.dma;
|
assign lsu_error_pkt_dc3.dma_valid = lsu_pkt_dc3.dma;
|
||||||
assign lsu_error_pkt_dc3.inst_pipe = ~lsu_i0_valid_dc3;
|
assign lsu_error_pkt_dc3.inst_pipe = ~lsu_i0_valid_dc3;
|
||||||
assign lsu_error_pkt_dc3.exc_type = ~misaligned_fault_dc3;
|
assign lsu_error_pkt_dc3.exc_type = ~misaligned_fault_dc3;
|
||||||
// assign lsu_error_pkt_dc3.addr[31:0] = (access_fault_dc3 | misaligned_fault_dc3) ? lsu_addr_dc3[31:0] : ld_bus_error_addr_dc3[31:0];
|
// assign lsu_error_pkt_dc3.addr[31:0] = (access_fault_dc3 | misaligned_fault_dc3) ? lsu_addr_dc3[31:0] : ld_bus_error_addr_dc3[31:0];
|
||||||
assign lsu_error_pkt_dc3.addr[31:0] = lsu_addr_dc3[31:0];
|
assign lsu_error_pkt_dc3.addr[31:0] = lsu_addr_dc3[31:0];
|
||||||
|
|
||||||
|
|
||||||
//Create DMA packet
|
//Create DMA packet
|
||||||
assign dma_pkt_d.valid = dma_dccm_req;
|
assign dma_pkt_d.valid = dma_dccm_req;
|
||||||
|
@ -223,38 +228,38 @@ module lsu_lsc_ctl
|
||||||
assign dma_pkt_d.load_ldst_bypass_c1 = '0;
|
assign dma_pkt_d.load_ldst_bypass_c1 = '0;
|
||||||
assign dma_pkt_d.store_data_bypass_c1 = '0;
|
assign dma_pkt_d.store_data_bypass_c1 = '0;
|
||||||
assign dma_pkt_d.store_data_bypass_c2 = '0;
|
assign dma_pkt_d.store_data_bypass_c2 = '0;
|
||||||
assign dma_pkt_d.store_data_bypass_i0_e2_c2 = '0;
|
assign dma_pkt_d.store_data_bypass_i0_e2_c2 = '0;
|
||||||
assign dma_pkt_d.store_data_bypass_e4_c1 = '0;
|
assign dma_pkt_d.store_data_bypass_e4_c1 = '0;
|
||||||
assign dma_pkt_d.store_data_bypass_e4_c2 = '0;
|
assign dma_pkt_d.store_data_bypass_e4_c2 = '0;
|
||||||
assign dma_pkt_d.store_data_bypass_e4_c3 = '0;
|
assign dma_pkt_d.store_data_bypass_e4_c3 = '0;
|
||||||
|
|
||||||
always_comb begin
|
always_comb begin
|
||||||
lsu_pkt_dc1_in = dma_dccm_req ? dma_pkt_d : lsu_p;
|
lsu_pkt_dc1_in = dma_dccm_req ? dma_pkt_d : lsu_p;
|
||||||
lsu_pkt_dc2_in = lsu_pkt_dc1;
|
lsu_pkt_dc2_in = lsu_pkt_dc1;
|
||||||
lsu_pkt_dc3_in = lsu_pkt_dc2;
|
lsu_pkt_dc3_in = lsu_pkt_dc2;
|
||||||
lsu_pkt_dc4_in = lsu_pkt_dc3;
|
lsu_pkt_dc4_in = lsu_pkt_dc3;
|
||||||
lsu_pkt_dc5_in = lsu_pkt_dc4;
|
lsu_pkt_dc5_in = lsu_pkt_dc4;
|
||||||
|
|
||||||
lsu_pkt_dc1_in.valid = (lsu_p.valid & ~flush_dc2_up) | dma_dccm_req;
|
lsu_pkt_dc1_in.valid = (lsu_p.valid & ~flush_dc2_up) | dma_dccm_req;
|
||||||
lsu_pkt_dc2_in.valid = lsu_pkt_dc1.valid & ~(flush_dc2_up & ~lsu_pkt_dc1.dma);
|
lsu_pkt_dc2_in.valid = lsu_pkt_dc1.valid & ~(flush_dc2_up & ~lsu_pkt_dc1.dma);
|
||||||
lsu_pkt_dc3_in.valid = lsu_pkt_dc2.valid & ~(flush_dc2_up & ~lsu_pkt_dc2.dma);
|
lsu_pkt_dc3_in.valid = lsu_pkt_dc2.valid & ~(flush_dc2_up & ~lsu_pkt_dc2.dma);
|
||||||
lsu_pkt_dc4_in.valid = lsu_pkt_dc3.valid & ~(flush_dc3 & ~lsu_pkt_dc3.dma) & ~lsu_freeze_dc3;
|
lsu_pkt_dc4_in.valid = lsu_pkt_dc3.valid & ~(flush_dc3 & ~lsu_pkt_dc3.dma) & ~lsu_freeze_dc3;
|
||||||
lsu_pkt_dc5_in.valid = lsu_pkt_dc4.valid & ~(flush_dc4 & ~lsu_pkt_dc4.dma);
|
lsu_pkt_dc5_in.valid = lsu_pkt_dc4.valid & ~(flush_dc4 & ~lsu_pkt_dc4.dma);
|
||||||
end
|
end
|
||||||
|
|
||||||
// C2 clock for valid and C1 for other bits of packet
|
// C2 clock for valid and C1 for other bits of packet
|
||||||
rvdff #(1) lsu_pkt_vlddc1ff (.*, .din(lsu_pkt_dc1_in.valid), .dout(lsu_pkt_dc1.valid), .clk(lsu_freeze_c2_dc1_clk));
|
rvdff #(1) lsu_pkt_vlddc1ff (.*, .din(lsu_pkt_dc1_in.valid), .dout(lsu_pkt_dc1.valid), .clk(lsu_freeze_c2_dc1_clk));
|
||||||
rvdff #(1) lsu_pkt_vlddc2ff (.*, .din(lsu_pkt_dc2_in.valid), .dout(lsu_pkt_dc2.valid), .clk(lsu_freeze_c2_dc2_clk));
|
rvdff #(1) lsu_pkt_vlddc2ff (.*, .din(lsu_pkt_dc2_in.valid), .dout(lsu_pkt_dc2.valid), .clk(lsu_freeze_c2_dc2_clk));
|
||||||
rvdff #(1) lsu_pkt_vlddc3ff (.*, .din(lsu_pkt_dc3_in.valid), .dout(lsu_pkt_dc3.valid), .clk(lsu_freeze_c2_dc3_clk));
|
rvdff #(1) lsu_pkt_vlddc3ff (.*, .din(lsu_pkt_dc3_in.valid), .dout(lsu_pkt_dc3.valid), .clk(lsu_freeze_c2_dc3_clk));
|
||||||
rvdff #(1) lsu_pkt_vlddc4ff (.*, .din(lsu_pkt_dc4_in.valid), .dout(lsu_pkt_dc4.valid), .clk(lsu_c2_dc4_clk));
|
rvdff #(1) lsu_pkt_vlddc4ff (.*, .din(lsu_pkt_dc4_in.valid), .dout(lsu_pkt_dc4.valid), .clk(lsu_c2_dc4_clk));
|
||||||
rvdff #(1) lsu_pkt_vlddc5ff (.*, .din(lsu_pkt_dc5_in.valid), .dout(lsu_pkt_dc5.valid), .clk(lsu_c2_dc5_clk));
|
rvdff #(1) lsu_pkt_vlddc5ff (.*, .din(lsu_pkt_dc5_in.valid), .dout(lsu_pkt_dc5.valid), .clk(lsu_c2_dc5_clk));
|
||||||
|
|
||||||
rvdffe #($bits(lsu_pkt_t)-1) lsu_pkt_dc1ff (.*, .din(lsu_pkt_dc1_in[$bits(lsu_pkt_t)-1:1]), .dout(lsu_pkt_dc1[$bits(lsu_pkt_t)-1:1]), .en(lsu_freeze_c1_dc1_clken));
|
rvdffe #($bits(lsu_pkt_t)-1) lsu_pkt_dc1ff (.*, .din(lsu_pkt_dc1_in[$bits(lsu_pkt_t)-1:1]), .dout(lsu_pkt_dc1[$bits(lsu_pkt_t)-1:1]), .en(lsu_freeze_c1_dc1_clken));
|
||||||
rvdffe #($bits(lsu_pkt_t)-1) lsu_pkt_dc2ff (.*, .din(lsu_pkt_dc2_in[$bits(lsu_pkt_t)-1:1]), .dout(lsu_pkt_dc2[$bits(lsu_pkt_t)-1:1]), .en(lsu_freeze_c1_dc2_clken));
|
rvdffe #($bits(lsu_pkt_t)-1) lsu_pkt_dc2ff (.*, .din(lsu_pkt_dc2_in[$bits(lsu_pkt_t)-1:1]), .dout(lsu_pkt_dc2[$bits(lsu_pkt_t)-1:1]), .en(lsu_freeze_c1_dc2_clken));
|
||||||
rvdffe #($bits(lsu_pkt_t)-1) lsu_pkt_dc3ff (.*, .din(lsu_pkt_dc3_in[$bits(lsu_pkt_t)-1:1]), .dout(lsu_pkt_dc3[$bits(lsu_pkt_t)-1:1]), .en(lsu_freeze_c1_dc3_clken));
|
rvdffe #($bits(lsu_pkt_t)-1) lsu_pkt_dc3ff (.*, .din(lsu_pkt_dc3_in[$bits(lsu_pkt_t)-1:1]), .dout(lsu_pkt_dc3[$bits(lsu_pkt_t)-1:1]), .en(lsu_freeze_c1_dc3_clken));
|
||||||
rvdff #($bits(lsu_pkt_t)-1) lsu_pkt_dc4ff (.*, .din(lsu_pkt_dc4_in[$bits(lsu_pkt_t)-1:1]), .dout(lsu_pkt_dc4[$bits(lsu_pkt_t)-1:1]), .clk(lsu_c1_dc4_clk));
|
rvdff #($bits(lsu_pkt_t)-1) lsu_pkt_dc4ff (.*, .din(lsu_pkt_dc4_in[$bits(lsu_pkt_t)-1:1]), .dout(lsu_pkt_dc4[$bits(lsu_pkt_t)-1:1]), .clk(lsu_c1_dc4_clk));
|
||||||
rvdff #($bits(lsu_pkt_t)-1) lsu_pkt_dc5ff (.*, .din(lsu_pkt_dc5_in[$bits(lsu_pkt_t)-1:1]), .dout(lsu_pkt_dc5[$bits(lsu_pkt_t)-1:1]), .clk(lsu_c1_dc5_clk));
|
rvdff #($bits(lsu_pkt_t)-1) lsu_pkt_dc5ff (.*, .din(lsu_pkt_dc5_in[$bits(lsu_pkt_t)-1:1]), .dout(lsu_pkt_dc5[$bits(lsu_pkt_t)-1:1]), .clk(lsu_c1_dc5_clk));
|
||||||
|
|
||||||
assign lsu_ld_datafn_dc3[31:0] = addr_external_dc3 ? bus_read_data_dc3[31:0] : lsu_ld_data_dc3[31:0];
|
assign lsu_ld_datafn_dc3[31:0] = addr_external_dc3 ? bus_read_data_dc3[31:0] : lsu_ld_data_dc3[31:0];
|
||||||
assign lsu_ld_datafn_corr_dc3[31:0] = addr_external_dc3 ? bus_read_data_dc3[31:0] : lsu_ld_data_corr_dc3[31:0];
|
assign lsu_ld_datafn_corr_dc3[31:0] = addr_external_dc3 ? bus_read_data_dc3[31:0] : lsu_ld_data_corr_dc3[31:0];
|
||||||
|
|
||||||
|
@ -271,61 +276,61 @@ module lsu_lsc_ctl
|
||||||
({32{~lsu_pkt_dc3.unsign & lsu_pkt_dc3.half}} & {{16{ lsu_ld_datafn_corr_dc3[15]}},lsu_ld_datafn_corr_dc3[15:0]}) |
|
({32{~lsu_pkt_dc3.unsign & lsu_pkt_dc3.half}} & {{16{ lsu_ld_datafn_corr_dc3[15]}},lsu_ld_datafn_corr_dc3[15:0]}) |
|
||||||
({32{lsu_pkt_dc3.word}} & lsu_ld_datafn_corr_dc3[31:0]);
|
({32{lsu_pkt_dc3.word}} & lsu_ld_datafn_corr_dc3[31:0]);
|
||||||
|
|
||||||
|
|
||||||
// absence load/store all 0's
|
// absence load/store all 0's
|
||||||
assign lsu_addr_dc1[31:0] = full_addr_dc1[31:0];
|
assign lsu_addr_dc1[31:0] = full_addr_dc1[31:0];
|
||||||
|
|
||||||
// Interrupt as a flush source allows the WB to occur
|
// Interrupt as a flush source allows the WB to occur
|
||||||
assign lsu_commit_dc5 = lsu_pkt_dc5.valid & (lsu_pkt_dc5.store | lsu_pkt_dc5.load) & ~flush_dc5 & ~lsu_pkt_dc5.dma;
|
assign lsu_commit_dc5 = lsu_pkt_dc5.valid & (lsu_pkt_dc5.store | lsu_pkt_dc5.load) & ~flush_dc5 & ~lsu_pkt_dc5.dma;
|
||||||
|
|
||||||
assign dma_mem_wdata_shifted[63:0] = dma_mem_wdata[63:0] >> {dma_mem_addr[2:0], 3'b000}; // Shift the dma data to lower bits to make it consistent to lsu stores
|
assign dma_mem_wdata_shifted[63:0] = dma_mem_wdata[63:0] >> {dma_mem_addr[2:0], 3'b000}; // Shift the dma data to lower bits to make it consistent to lsu stores
|
||||||
assign store_data_d[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[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[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];
|
(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[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] :
|
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[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];
|
(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[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[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]);
|
(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));
|
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) 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) 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) );
|
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) 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) 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));
|
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) 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_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));
|
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_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_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_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_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_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_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_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_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) 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_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) 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), .*);
|
rvdff #(1) misaligned_fault_dc2ff(.din(misaligned_fault_dc1), .dout(misaligned_fault_dc2), .clk(lsu_freeze_c1_dc2_clk), .*);
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
// Copyright 2019 Western Digital Corporation or its affiliates.
|
// Copyright 2019 Western Digital Corporation or its affiliates.
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "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 not use this file except in compliance with the License.
|
||||||
// You may obtain a copy of the License at
|
// You may obtain a copy of the License at
|
||||||
//
|
//
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
//
|
//
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
@ -16,14 +16,14 @@
|
||||||
//********************************************************************************
|
//********************************************************************************
|
||||||
// $Id$
|
// $Id$
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// Owner:
|
// Owner:
|
||||||
// Function: Store Buffer
|
// Function: Store Buffer
|
||||||
// Comments: Dual writes and single drain
|
// Comments: Dual writes and single drain
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// DC1 -> DC2 -> DC3 -> DC4 (Commit)
|
// DC1 -> DC2 -> DC3 -> DC4 (Commit)
|
||||||
//
|
//
|
||||||
// //********************************************************************************
|
// //********************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
@ -34,11 +34,11 @@ module lsu_stbuf
|
||||||
input logic rst_l, // reset
|
input logic rst_l, // reset
|
||||||
|
|
||||||
input logic lsu_freeze_c2_dc2_clk, // freeze clock
|
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_dc2_clk, // freeze clock
|
||||||
input logic lsu_freeze_c1_dc3_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_dc4_clk, // lsu pipe clock
|
||||||
input logic lsu_c1_dc5_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_c2_dc5_clk, // lsu pipe clock
|
||||||
input logic lsu_stbuf_c1_clk, // stbuf clock
|
input logic lsu_stbuf_c1_clk, // stbuf clock
|
||||||
input logic lsu_free_c2_clk, // free clk
|
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 load_stbuf_reqvld_dc3, // core instruction goes to stbuf
|
||||||
input logic store_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_dc2, // address is in pic
|
||||||
input logic addr_in_pic_dc3, // address is in pic
|
input logic addr_in_pic_dc3, // address is in pic
|
||||||
input logic addr_in_dccm_dc2, // 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 isldst_dc1, // instruction in dc1 is lsu
|
||||||
input logic dccm_ldst_dc2, // instruction in dc2 is lsu
|
input logic dccm_ldst_dc2, // instruction in dc2 is lsu
|
||||||
input logic dccm_ldst_dc3, // instruction in dc3 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_hi_dc3, // single ecc error in hi bank
|
||||||
input logic single_ecc_error_lo_dc3, // single ecc error in lo 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_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_commit_dc5, // lsu commits
|
||||||
input logic lsu_freeze_dc3, // lsu freeze
|
input logic lsu_freeze_dc3, // lsu freeze
|
||||||
input logic flush_prior_dc5, // Flush is due to i0 and ld/st is in i1
|
input logic flush_prior_dc5, // Flush is due to i0 and ld/st is in i1
|
||||||
|
|
||||||
// Store Buffer output
|
// Store Buffer output
|
||||||
output logic stbuf_reqvld_any, // stbuf is draining
|
output logic stbuf_reqvld_any, // stbuf is draining
|
||||||
output logic stbuf_reqvld_flushed_any, // Top entry is flushed
|
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_full_any, // stbuf is full
|
||||||
output logic lsu_stbuf_empty_any, // stbuf is empty
|
output logic lsu_stbuf_empty_any, // stbuf is empty
|
||||||
output logic lsu_stbuf_nodma_empty_any, // stbuf is empty except dma
|
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_dc1, // lsu address
|
||||||
input logic [`RV_LSU_SB_BITS-1:0] lsu_addr_dc2,
|
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] 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_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_dc2,
|
||||||
input logic [`RV_LSU_SB_BITS-1:0] end_addr_dc3,
|
input logic [`RV_LSU_SB_BITS-1:0] end_addr_dc3,
|
||||||
|
|
||||||
// Forwarding signals
|
// Forwarding signals
|
||||||
input logic lsu_cmpen_dc2, // needed for forwarding stbuf - load
|
input logic lsu_cmpen_dc2, // needed for forwarding stbuf - load
|
||||||
input lsu_pkt_t lsu_pkt_dc2,
|
input lsu_pkt_t lsu_pkt_dc2,
|
||||||
input lsu_pkt_t lsu_pkt_dc3,
|
input lsu_pkt_t lsu_pkt_dc3,
|
||||||
input lsu_pkt_t lsu_pkt_dc5,
|
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_hi_dc3, // stbuf data
|
||||||
output logic [`RV_DCCM_DATA_WIDTH-1:0] stbuf_fwddata_lo_dc3,
|
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_hi_dc3,
|
||||||
output logic [`RV_DCCM_BYTE_WIDTH-1:0] stbuf_fwdbyteen_lo_dc3,
|
output logic [`RV_DCCM_BYTE_WIDTH-1:0] stbuf_fwdbyteen_lo_dc3,
|
||||||
|
|
||||||
input logic scan_mode
|
input logic scan_mode
|
||||||
|
|
||||||
);
|
);
|
||||||
|
|
||||||
`include "global.h"
|
`include "global.h"
|
||||||
|
|
||||||
localparam DEPTH = LSU_STBUF_DEPTH;
|
localparam DEPTH = LSU_STBUF_DEPTH;
|
||||||
localparam DATA_WIDTH = DCCM_DATA_WIDTH;
|
localparam DATA_WIDTH = DCCM_DATA_WIDTH;
|
||||||
localparam BYTE_WIDTH = DCCM_BYTE_WIDTH;
|
localparam BYTE_WIDTH = DCCM_BYTE_WIDTH;
|
||||||
localparam DEPTH_LOG2 = $clog2(DEPTH);
|
localparam DEPTH_LOG2 = $clog2(DEPTH);
|
||||||
|
|
||||||
logic [DEPTH-1:0] stbuf_data_vld;
|
logic [DEPTH-1:0] stbuf_data_vld;
|
||||||
logic [DEPTH-1:0] stbuf_drain_vld;
|
logic [DEPTH-1:0] stbuf_drain_vld;
|
||||||
logic [DEPTH-1:0] stbuf_flush_vld;
|
logic [DEPTH-1:0] stbuf_flush_vld;
|
||||||
logic [DEPTH-1:0] stbuf_addr_in_pic;
|
logic [DEPTH-1:0] stbuf_addr_in_pic;
|
||||||
logic [DEPTH-1:0] stbuf_dma;
|
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][BYTE_WIDTH-1:0] stbuf_byteen;
|
||||||
logic [DEPTH-1:0][DATA_WIDTH-1:0] stbuf_data;
|
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][LSU_SB_BITS-1:0] stbuf_addrin;
|
||||||
logic [DEPTH-1:0][DATA_WIDTH-1:0] stbuf_datain;
|
logic [DEPTH-1:0][DATA_WIDTH-1:0] stbuf_datain;
|
||||||
logic [DEPTH-1:0][BYTE_WIDTH-1:0] stbuf_byteenin;
|
logic [DEPTH-1:0][BYTE_WIDTH-1:0] stbuf_byteenin;
|
||||||
|
|
||||||
logic [7:0] ldst_byteen_dc3;
|
logic [7:0] ldst_byteen_dc3;
|
||||||
logic [7:0] store_byteen_ext_dc3;
|
logic [7:0] store_byteen_ext_dc3;
|
||||||
logic [BYTE_WIDTH-1:0] store_byteen_hi_dc3;
|
logic [BYTE_WIDTH-1:0] store_byteen_hi_dc3;
|
||||||
logic [BYTE_WIDTH-1:0] store_byteen_lo_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_ecc_error_dc3;
|
||||||
logic dual_stbuf_write_dc3;
|
logic dual_stbuf_write_dc3;
|
||||||
|
|
||||||
logic WrPtrEn, RdPtrEn;
|
logic WrPtrEn, RdPtrEn;
|
||||||
logic [DEPTH_LOG2-1:0] WrPtr, RdPtr;
|
logic [DEPTH_LOG2-1:0] WrPtr, RdPtr;
|
||||||
logic [DEPTH_LOG2-1:0] NxtWrPtr, NxtRdPtr;
|
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_dual_dc1, ldst_dual_dc2, ldst_dual_dc3, ldst_dual_dc4, ldst_dual_dc5;
|
||||||
logic ldst_stbuf_reqvld_dc4, ldst_stbuf_reqvld_dc5;
|
logic ldst_stbuf_reqvld_dc4, ldst_stbuf_reqvld_dc5;
|
||||||
logic dual_stbuf_write_dc4, dual_stbuf_write_dc5;
|
logic dual_stbuf_write_dc4, dual_stbuf_write_dc5;
|
||||||
|
|
||||||
logic [3:0] stbuf_numvld_any, stbuf_specvld_any;
|
logic [3:0] stbuf_numvld_any, stbuf_specvld_any;
|
||||||
logic [1:0] stbuf_specvld_dc1, stbuf_specvld_dc2, stbuf_specvld_dc3;
|
logic [1:0] stbuf_specvld_dc1, stbuf_specvld_dc2, stbuf_specvld_dc3;
|
||||||
logic stbuf_oneavl_any, stbuf_twoavl_any;
|
logic stbuf_oneavl_any, stbuf_twoavl_any;
|
||||||
|
|
||||||
logic cmpen_hi_dc2, cmpen_lo_dc2, jit_in_same_region;
|
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 [LSU_SB_BITS-1:$clog2(BYTE_WIDTH)] cmpaddr_hi_dc2, cmpaddr_lo_dc2;
|
||||||
|
|
||||||
logic stbuf_ldmatch_hi_hi, stbuf_ldmatch_hi_lo;
|
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 [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_hi_hi, stbuf_fwddata_hi_lo;
|
||||||
logic [DATA_WIDTH-1:0] stbuf_fwddata_lo_hi, stbuf_fwddata_lo_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] stbuf_ldmatch_hi, stbuf_ldmatch_lo;
|
||||||
logic [DEPTH-1:0][BYTE_WIDTH-1:0] stbuf_fwdbyteenvec_hi, stbuf_fwdbyteenvec_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;
|
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_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]) |
|
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));
|
(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_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 | stbuf_load_repair_dc5);
|
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]);
|
assign stbuf_reset[i] = (lsu_stbuf_commit_any | stbuf_reqvld_flushed_any) & (i == RdPtr[DEPTH_LOG2-1:0]);
|
||||||
|
|
||||||
// Mux select for start/end address
|
// 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_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_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];
|
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_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_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), .*);
|
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_full_any = (stbuf_specvld_any[3:0] > (DEPTH - 2));
|
||||||
assign lsu_stbuf_empty_any = (stbuf_numvld_any[3:0] == 4'b0);
|
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_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_oneavl_any = (stbuf_numvld_any[3:0] < DEPTH);
|
||||||
assign stbuf_twoavl_any = (stbuf_numvld_any[3:0] < (DEPTH - 1));
|
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 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 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);
|
assign jit_in_same_region = (addr_in_pic_dc2 & addr_in_pic_dc3) | (addr_in_dccm_dc2 & addr_in_dccm_dc3);
|
||||||
|
|
||||||
// JIT forwarding
|
// 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_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;
|
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_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_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_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_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_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_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)];
|
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
|
end
|
||||||
|
|
||||||
|
|
||||||
always_comb begin: GenLdFwd
|
always_comb begin: GenLdFwd
|
||||||
stbuf_fwdbyteen_hi_dc2[BYTE_WIDTH-1:0] = '0;
|
stbuf_fwdbyteen_hi_dc2[BYTE_WIDTH-1:0] = '0;
|
||||||
stbuf_fwdbyteen_lo_dc2[BYTE_WIDTH-1:0] = '0;
|
stbuf_fwdbyteen_lo_dc2[BYTE_WIDTH-1:0] = '0;
|
||||||
for (int i=0; i<DEPTH; i++) begin
|
for (int i=0; i<DEPTH; i++) begin
|
||||||
stbuf_ldmatch_hi[i] = (stbuf_addr[i][LSU_SB_BITS-1:$clog2(BYTE_WIDTH)] == cmpaddr_hi_dc2[LSU_SB_BITS-1:$clog2(BYTE_WIDTH)]) &
|
stbuf_ldmatch_hi[i] = (stbuf_addr[i][LSU_SB_BITS-1:$clog2(BYTE_WIDTH)] == cmpaddr_hi_dc2[LSU_SB_BITS-1:$clog2(BYTE_WIDTH)]) &
|
||||||
(stbuf_drain_vld[i] | ~lsu_pkt_dc2.dma) & ~stbuf_flush_vld[i] & ((stbuf_addr_in_pic[i] & addr_in_pic_dc2) | (~stbuf_addr_in_pic[i] & addr_in_dccm_dc2));
|
(stbuf_drain_vld[i] | ~lsu_pkt_dc2.dma) & ~stbuf_flush_vld[i] & ((stbuf_addr_in_pic[i] & addr_in_pic_dc2) | (~stbuf_addr_in_pic[i] & addr_in_dccm_dc2));
|
||||||
stbuf_ldmatch_lo[i] = (stbuf_addr[i][LSU_SB_BITS-1:$clog2(BYTE_WIDTH)] == cmpaddr_lo_dc2[LSU_SB_BITS-1:$clog2(BYTE_WIDTH)]) &
|
stbuf_ldmatch_lo[i] = (stbuf_addr[i][LSU_SB_BITS-1:$clog2(BYTE_WIDTH)] == cmpaddr_lo_dc2[LSU_SB_BITS-1:$clog2(BYTE_WIDTH)]) &
|
||||||
(stbuf_drain_vld[i] | ~lsu_pkt_dc2.dma) & ~stbuf_flush_vld[i] & ((stbuf_addr_in_pic[i] & addr_in_pic_dc2) | (~stbuf_addr_in_pic[i] & addr_in_dccm_dc2));
|
(stbuf_drain_vld[i] | ~lsu_pkt_dc2.dma) & ~stbuf_flush_vld[i] & ((stbuf_addr_in_pic[i] & addr_in_pic_dc2) | (~stbuf_addr_in_pic[i] & addr_in_dccm_dc2));
|
||||||
|
|
||||||
for (int j=0; j<BYTE_WIDTH; j++) begin
|
for (int j=0; j<BYTE_WIDTH; j++) begin
|
||||||
stbuf_fwdbyteenvec_hi[i][j] = stbuf_ldmatch_hi[i] & stbuf_byteen[i][j] & stbuf_data_vld[i];
|
stbuf_fwdbyteenvec_hi[i][j] = stbuf_ldmatch_hi[i] & stbuf_byteen[i][j] & stbuf_data_vld[i];
|
||||||
stbuf_fwdbyteen_hi_dc2[j] |= stbuf_fwdbyteenvec_hi[i][j];
|
stbuf_fwdbyteen_hi_dc2[j] |= stbuf_fwdbyteenvec_hi[i][j];
|
||||||
|
|
||||||
stbuf_fwdbyteenvec_lo[i][j] = stbuf_ldmatch_lo[i] & stbuf_byteen[i][j] & stbuf_data_vld[i];
|
stbuf_fwdbyteenvec_lo[i][j] = stbuf_ldmatch_lo[i] & stbuf_byteen[i][j] & stbuf_data_vld[i];
|
||||||
stbuf_fwdbyteen_lo_dc2[j] |= stbuf_fwdbyteenvec_lo[i][j];
|
stbuf_fwdbyteen_lo_dc2[j] |= stbuf_fwdbyteenvec_lo[i][j];
|
||||||
end
|
end
|
||||||
|
@ -325,7 +327,7 @@ module lsu_stbuf
|
||||||
end // block: GenLdFwd
|
end // block: GenLdFwd
|
||||||
|
|
||||||
for (genvar i=0; i<DEPTH; i++) begin
|
for (genvar i=0; i<DEPTH; i++) begin
|
||||||
for (genvar j=0; j<BYTE_WIDTH; j++) begin
|
for (genvar j=0; j<BYTE_WIDTH; j++) begin
|
||||||
assign stbuf_fwddatavec_hi[i][(8*j)+7:(8*j)] = {8{stbuf_fwdbyteenvec_hi[i][j]}} & stbuf_data[i][(8*j)+7:(8*j)];
|
assign stbuf_fwddatavec_hi[i][(8*j)+7:(8*j)] = {8{stbuf_fwdbyteenvec_hi[i][j]}} & stbuf_data[i][(8*j)+7:(8*j)];
|
||||||
assign stbuf_fwddatavec_lo[i][(8*j)+7:(8*j)] = {8{stbuf_fwdbyteenvec_lo[i][j]}} & stbuf_data[i][(8*j)+7:(8*j)];
|
assign stbuf_fwddatavec_lo[i][(8*j)+7:(8*j)] = {8{stbuf_fwdbyteenvec_lo[i][j]}} & stbuf_data[i][(8*j)+7:(8*j)];
|
||||||
end
|
end
|
||||||
|
@ -373,10 +375,10 @@ module lsu_stbuf
|
||||||
assign stbuf_fwdbyteen_hi_fn_dc2[i] = stbuf_fwdbyteen_hi_hi[i] | stbuf_fwdbyteen_hi_lo[i] | stbuf_fwdbyteen_hi_dc2[i];
|
assign stbuf_fwdbyteen_hi_fn_dc2[i] = stbuf_fwdbyteen_hi_hi[i] | stbuf_fwdbyteen_hi_lo[i] | stbuf_fwdbyteen_hi_dc2[i];
|
||||||
assign stbuf_fwdbyteen_lo_fn_dc2[i] = stbuf_fwdbyteen_lo_hi[i] | stbuf_fwdbyteen_lo_lo[i] | stbuf_fwdbyteen_lo_dc2[i];
|
assign stbuf_fwdbyteen_lo_fn_dc2[i] = stbuf_fwdbyteen_lo_hi[i] | stbuf_fwdbyteen_lo_lo[i] | stbuf_fwdbyteen_lo_dc2[i];
|
||||||
|
|
||||||
assign stbuf_fwddata_hi_fn_dc2[(8*i)+7:(8*i)] = (stbuf_fwdbyteen_hi_hi[i] | stbuf_fwdbyteen_hi_lo[i]) ?
|
assign stbuf_fwddata_hi_fn_dc2[(8*i)+7:(8*i)] = (stbuf_fwdbyteen_hi_hi[i] | stbuf_fwdbyteen_hi_lo[i]) ?
|
||||||
(stbuf_fwddata_hi_hi[(8*i)+7:(8*i)] | stbuf_fwddata_hi_lo[(8*i)+7:(8*i)]) :
|
(stbuf_fwddata_hi_hi[(8*i)+7:(8*i)] | stbuf_fwddata_hi_lo[(8*i)+7:(8*i)]) :
|
||||||
stbuf_fwddata_hi_dc2[(8*i)+7:(8*i)];
|
stbuf_fwddata_hi_dc2[(8*i)+7:(8*i)];
|
||||||
assign stbuf_fwddata_lo_fn_dc2[(8*i)+7:(8*i)] = (stbuf_fwdbyteen_lo_hi[i] | stbuf_fwdbyteen_lo_lo[i]) ?
|
assign stbuf_fwddata_lo_fn_dc2[(8*i)+7:(8*i)] = (stbuf_fwdbyteen_lo_hi[i] | stbuf_fwdbyteen_lo_lo[i]) ?
|
||||||
(stbuf_fwddata_lo_hi[(8*i)+7:(8*i)] | stbuf_fwddata_lo_lo[(8*i)+7:(8*i)]) :
|
(stbuf_fwddata_lo_hi[(8*i)+7:(8*i)] | stbuf_fwddata_lo_lo[(8*i)+7:(8*i)]) :
|
||||||
stbuf_fwddata_lo_dc2[(8*i)+7:(8*i)];
|
stbuf_fwddata_lo_dc2[(8*i)+7:(8*i)];
|
||||||
end
|
end
|
||||||
|
@ -395,8 +397,14 @@ module lsu_stbuf
|
||||||
|
|
||||||
assert_drainorflushvld_notvld: assert #0 (~(|((stbuf_drain_vld[DEPTH-1:0] | stbuf_flush_vld[DEPTH-1:0]) & ~stbuf_data_vld[DEPTH-1:0])));
|
assert_drainorflushvld_notvld: assert #0 (~(|((stbuf_drain_vld[DEPTH-1:0] | stbuf_flush_vld[DEPTH-1:0]) & ~stbuf_data_vld[DEPTH-1:0])));
|
||||||
assert_drainAndflushvld: assert #0 (~(|(stbuf_drain_vld[DEPTH-1:0] & stbuf_flush_vld[DEPTH-1:0])));
|
assert_drainAndflushvld: assert #0 (~(|(stbuf_drain_vld[DEPTH-1:0] & stbuf_flush_vld[DEPTH-1:0])));
|
||||||
assert_stbufempty: assert #0 (~lsu_stbuf_empty_any | lsu_stbuf_nodma_empty_any);
|
assert_stbufempty: assert #0 (~lsu_stbuf_empty_any | lsu_stbuf_nodma_empty_any);
|
||||||
|
|
||||||
|
property ldecc_stbuffull_commit;
|
||||||
|
@(posedge clk) disable iff(~rst_l) (load_stbuf_reqvld_dc3 & lsu_load_ecc_stbuf_full_dc3) |-> ##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
|
`endif
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
// Copyright 2019 Western Digital Corporation or its affiliates.
|
// Copyright 2019 Western Digital Corporation or its affiliates.
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "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 not use this file except in compliance with the License.
|
||||||
// You may obtain a copy of the License at
|
// You may obtain a copy of the License at
|
||||||
//
|
//
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
//
|
//
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
@ -16,13 +16,13 @@
|
||||||
//********************************************************************************
|
//********************************************************************************
|
||||||
// $Id$
|
// $Id$
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// Owner:
|
// Owner:
|
||||||
// Function: LSU Trigger logic
|
// Function: LSU Trigger logic
|
||||||
// Comments:
|
// Comments:
|
||||||
//
|
//
|
||||||
//********************************************************************************
|
//********************************************************************************
|
||||||
module lsu_trigger
|
module lsu_trigger
|
||||||
import swerv_types::*;
|
import swerv_types::*;
|
||||||
(
|
(
|
||||||
input logic clk, // clock
|
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 trigger_pkt_t [3:0] trigger_pkt_any, // trigger packet from dec
|
||||||
input lsu_pkt_t lsu_pkt_dc3, // lsu packet
|
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] lsu_result_dc3, // load data
|
||||||
input logic [31:0] store_data_dc3, // store data
|
input logic [31:0] store_data_dc3, // store data
|
||||||
|
|
||||||
|
@ -43,13 +43,13 @@ module lsu_trigger
|
||||||
logic [31:0] store_data_trigger_dc3;
|
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]};
|
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
|
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]) |
|
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]);
|
({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]));
|
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 &
|
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];
|
lsu_trigger_data_match[i];
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
endmodule // lsu_trigger
|
endmodule // lsu_trigger
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
//********************************************************************************
|
//********************************************************************************
|
||||||
|
|
||||||
module mem
|
module mem
|
||||||
import swerv_types::*;
|
import swerv_types::*;
|
||||||
(
|
(
|
||||||
input logic clk,
|
input logic clk,
|
||||||
|
@ -23,8 +23,8 @@ module mem
|
||||||
input logic lsu_freeze_dc3,
|
input logic lsu_freeze_dc3,
|
||||||
input logic dccm_clk_override,
|
input logic dccm_clk_override,
|
||||||
input logic icm_clk_override,
|
input logic icm_clk_override,
|
||||||
input logic dec_tlu_core_ecc_disable,
|
input logic dec_tlu_core_ecc_disable,
|
||||||
|
|
||||||
//DCCM ports
|
//DCCM ports
|
||||||
input logic dccm_wren,
|
input logic dccm_wren,
|
||||||
input logic dccm_rden,
|
input logic dccm_rden,
|
||||||
|
@ -45,7 +45,7 @@ module mem
|
||||||
input logic iccm_rden,
|
input logic iccm_rden,
|
||||||
input logic [2:0] iccm_wr_size,
|
input logic [2:0] iccm_wr_size,
|
||||||
input logic [77:0] iccm_wr_data,
|
input logic [77:0] iccm_wr_data,
|
||||||
|
|
||||||
output logic [155:0] iccm_rd_data,
|
output logic [155:0] iccm_rd_data,
|
||||||
`endif
|
`endif
|
||||||
// Icache and Itag Ports
|
// Icache and Itag Ports
|
||||||
|
@ -54,44 +54,44 @@ module mem
|
||||||
input logic [3:0] ic_tag_valid,
|
input logic [3:0] ic_tag_valid,
|
||||||
input logic [3:0] ic_wr_en,
|
input logic [3:0] ic_wr_en,
|
||||||
input logic ic_rd_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 [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 ic_sel_premux_data, // Premux data sel
|
||||||
|
|
||||||
`ifdef RV_ICACHE_ECC
|
`ifdef RV_ICACHE_ECC
|
||||||
input logic [83:0] ic_wr_data, // Data to fill to the Icache. With 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.
|
input logic [41:0] ic_debug_wr_data, // Debug wr cache.
|
||||||
`else
|
`else
|
||||||
input logic [67:0] ic_wr_data, // Data to fill to the Icache. With Parity
|
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
|
`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_rd_en, // Icache debug rd
|
||||||
input logic ic_debug_wr_en, // Icache debug wr
|
input logic ic_debug_wr_en, // Icache debug wr
|
||||||
input logic ic_debug_tag_array, // Debug tag array
|
input logic ic_debug_tag_array, // Debug tag array
|
||||||
input logic [3:0] ic_debug_way, // Debug way. Rd or Wr.
|
input logic [3:0] ic_debug_way, // Debug way. Rd or Wr.
|
||||||
|
|
||||||
`endif
|
`endif
|
||||||
|
|
||||||
`ifdef RV_ICACHE_ECC
|
`ifdef RV_ICACHE_ECC
|
||||||
output logic [167:0] ic_rd_data , // Data read from Icache. 2x64bits + parity bits. F2 stage. With 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.
|
output logic [24:0] ictag_debug_rd_data,// Debug icache tag.
|
||||||
`else
|
`else
|
||||||
output logic [135:0] ic_rd_data , // Data read from Icache. 2x64bits + parity bits. F2 stage. With Parity
|
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
|
`endif
|
||||||
|
|
||||||
output logic [3:0] ic_rd_hit,
|
output logic [3:0] ic_rd_hit,
|
||||||
output logic ic_tag_perr, // Icache Tag parity error
|
output logic ic_tag_perr, // Icache Tag parity error
|
||||||
|
|
||||||
|
|
||||||
input logic scan_mode
|
input logic scan_mode
|
||||||
|
|
||||||
);
|
);
|
||||||
`include "global.h"
|
`include "global.h"
|
||||||
|
|
||||||
`ifdef RV_DCCM_ENABLE
|
`ifdef RV_DCCM_ENABLE
|
||||||
localparam DCCM_ENABLE = 1'b1;
|
localparam DCCM_ENABLE = 1'b1;
|
||||||
`else
|
`else
|
||||||
|
@ -108,8 +108,8 @@ module mem
|
||||||
assign dccm_rd_data_lo = '0;
|
assign dccm_rd_data_lo = '0;
|
||||||
assign dccm_rd_data_hi = '0;
|
assign dccm_rd_data_hi = '0;
|
||||||
end
|
end
|
||||||
|
|
||||||
`ifdef RV_ICACHE_ENABLE
|
`ifdef RV_ICACHE_ENABLE
|
||||||
ifu_ic_mem icm (
|
ifu_ic_mem icm (
|
||||||
.clk_override(icm_clk_override),
|
.clk_override(icm_clk_override),
|
||||||
.*
|
.*
|
||||||
|
@ -128,5 +128,5 @@ module mem
|
||||||
.iccm_rd_data(iccm_rd_data[155:0])
|
.iccm_rd_data(iccm_rd_data[155:0])
|
||||||
);
|
);
|
||||||
`endif
|
`endif
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
|
@ -16,8 +16,8 @@
|
||||||
//********************************************************************************
|
//********************************************************************************
|
||||||
|
|
||||||
//********************************************************************************
|
//********************************************************************************
|
||||||
// Function: Programmable Interrupt Controller
|
// Function: Programmable Interrupt Controller
|
||||||
// Comments:
|
// Comments:
|
||||||
//********************************************************************************
|
//********************************************************************************
|
||||||
|
|
||||||
module pic_ctrl
|
module pic_ctrl
|
||||||
|
@ -43,10 +43,10 @@ module pic_ctrl
|
||||||
output logic [31:0] picm_rd_data, // Read data of the register
|
output logic [31:0] picm_rd_data, // Read data of the register
|
||||||
output logic mhwakeup, // Wake-up interrupt request
|
output logic mhwakeup, // Wake-up interrupt request
|
||||||
input logic scan_mode // scan mode
|
input logic scan_mode // scan mode
|
||||||
|
|
||||||
);
|
);
|
||||||
`include "global.h"
|
`include "global.h"
|
||||||
|
|
||||||
localparam NUM_LEVELS = $clog2(TOTAL_INT);
|
localparam NUM_LEVELS = $clog2(TOTAL_INT);
|
||||||
localparam INTPRIORITY_BASE_ADDR = `RV_PIC_BASE_ADDR ;
|
localparam INTPRIORITY_BASE_ADDR = `RV_PIC_BASE_ADDR ;
|
||||||
localparam INTPEND_BASE_ADDR = `RV_PIC_BASE_ADDR + 32'h00001000 ;
|
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_CONFIG = `RV_PIC_BASE_ADDR + 32'h00004000 ;
|
||||||
localparam EXT_INTR_GW_CLEAR = `RV_PIC_BASE_ADDR + 32'h00005000 ;
|
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 < 64) ? 64 :
|
||||||
(TOTAL_INT < 128) ? 128 :
|
(TOTAL_INT < 128) ? 128 :
|
||||||
(TOTAL_INT < 256) ? 256 :
|
(TOTAL_INT < 256) ? 256 :
|
||||||
(TOTAL_INT < 512) ? 512 : 1024 ;
|
(TOTAL_INT < 512) ? 512 : 1024 ;
|
||||||
|
|
||||||
localparam INT_GRPS = INTPEND_SIZE / 32 ;
|
localparam INT_GRPS = INTPEND_SIZE / 32 ;
|
||||||
localparam INTPRIORITY_BITS = 4 ;
|
localparam INTPRIORITY_BITS = 4 ;
|
||||||
localparam ID_BITS = 8 ;
|
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_intpend_base_match;
|
||||||
logic addr_intenable_base_match;
|
logic addr_intenable_base_match;
|
||||||
logic addr_intpriority_base_match;
|
logic addr_intpriority_base_match;
|
||||||
logic addr_config_pic_match ;
|
logic addr_config_pic_match ;
|
||||||
logic addr_config_gw_base_match ;
|
logic addr_config_gw_base_match ;
|
||||||
logic addr_clear_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 config_reg;
|
||||||
logic intpriord;
|
logic intpriord;
|
||||||
logic config_reg_we ;
|
logic config_reg_we ;
|
||||||
logic config_reg_re ;
|
logic config_reg_re ;
|
||||||
logic config_reg_in ;
|
logic config_reg_in ;
|
||||||
logic prithresh_reg_write , prithresh_reg_read;
|
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 [31:0] picm_wr_data_ff;
|
||||||
logic [3:0] mask;
|
logic [3:0] mask;
|
||||||
logic picm_mken_ff;
|
logic picm_mken_ff;
|
||||||
logic [ID_BITS-1:0] claimid_in ;
|
logic [ID_BITS-1:0] claimid_in ;
|
||||||
logic [INTPRIORITY_BITS-1:0] pl_in ;
|
logic [INTPRIORITY_BITS-1:0] pl_in ;
|
||||||
logic [INTPRIORITY_BITS-1:0] pl_in_q ;
|
logic [INTPRIORITY_BITS-1:0] pl_in_q ;
|
||||||
|
|
||||||
logic [TOTAL_INT-1:0] extintsrc_req_sync;
|
logic [TOTAL_INT-1:0] extintsrc_req_sync;
|
||||||
logic [TOTAL_INT-1:0] extintsrc_req_gw;
|
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_pri_c1_clken;
|
||||||
logic pic_int_c1_clken;
|
logic pic_int_c1_clken;
|
||||||
logic gw_config_c1_clken;
|
logic gw_config_c1_clken;
|
||||||
|
|
||||||
// clocks
|
// clocks
|
||||||
logic pic_addr_c1_clk;
|
logic pic_addr_c1_clk;
|
||||||
logic pic_data_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_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 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;
|
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_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_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_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 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), .* );
|
rvoclkhdr gw_config_c1_cgc ( .en(gw_config_c1_clken), .l1clk(gw_config_c1_clk), .* );
|
||||||
|
|
||||||
// ------ end clock gating section ------------------------
|
// ------ end clock gating section ------------------------
|
||||||
|
|
||||||
assign addr_intpend_base_match = (picm_addr_ff[31:6] == INTPEND_BASE_ADDR[31:6]) ;
|
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_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]) ;
|
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 #(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));
|
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),
|
.clk (free_clk),
|
||||||
.dout(extintsrc_req_sync[TOTAL_INT-1:1]),
|
.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];
|
assign extintsrc_req_sync[0] = extintsrc_req[0];
|
||||||
|
|
||||||
genvar i ;
|
genvar i, l, m , j, k;
|
||||||
for (i=0; i<TOTAL_INT ; i++) begin : SETREG
|
for (i=0; i<TOTAL_INT ; i++) begin : SETREG
|
||||||
|
|
||||||
if (i > 0 ) begin : NON_ZERO_INT
|
if (i > 0 ) begin : NON_ZERO_INT
|
||||||
|
@ -206,21 +206,21 @@ for (i=0; i<TOTAL_INT ; i++) begin : SETREG
|
||||||
.meigwctrl_polarity(gw_config_reg[i][0]) ,
|
.meigwctrl_polarity(gw_config_reg[i][0]) ,
|
||||||
.meigwctrl_type(gw_config_reg[i][1]) ,
|
.meigwctrl_type(gw_config_reg[i][1]) ,
|
||||||
.meigwclr(gw_clear_reg_we[i]) ,
|
.meigwclr(gw_clear_reg_we[i]) ,
|
||||||
.extintsrc_req_config(extintsrc_req_gw[i])
|
.extintsrc_req_config(extintsrc_req_gw[i])
|
||||||
);
|
);
|
||||||
// end else begin
|
// end else begin
|
||||||
// assign extintsrc_req_gw[i] = extintsrc_req_sync[i] ;
|
// assign extintsrc_req_gw[i] = extintsrc_req_sync[i] ;
|
||||||
// assign gw_config_reg[i] = '0 ;
|
// assign gw_config_reg[i] = '0 ;
|
||||||
// end
|
// end
|
||||||
|
|
||||||
|
|
||||||
end else begin : INT_ZERO
|
end else begin : INT_ZERO
|
||||||
assign intpriority_reg_we[i] = 1'b0 ;
|
assign intpriority_reg_we[i] = 1'b0 ;
|
||||||
assign intpriority_reg_re[i] = 1'b0 ;
|
assign intpriority_reg_re[i] = 1'b0 ;
|
||||||
assign intenable_reg_we[i] = 1'b0 ;
|
assign intenable_reg_we[i] = 1'b0 ;
|
||||||
assign intenable_reg_re[i] = 1'b0 ;
|
assign intenable_reg_re[i] = 1'b0 ;
|
||||||
|
|
||||||
assign gw_config_reg_we[i] = 1'b0 ;
|
assign gw_config_reg_we[i] = 1'b0 ;
|
||||||
assign gw_config_reg_re[i] = 1'b0 ;
|
assign gw_config_reg_re[i] = 1'b0 ;
|
||||||
assign gw_clear_reg_we[i] = 1'b0 ;
|
assign gw_clear_reg_we[i] = 1'b0 ;
|
||||||
|
|
||||||
|
@ -230,10 +230,10 @@ for (i=0; i<TOTAL_INT ; i++) begin : SETREG
|
||||||
assign intenable_reg[i] = 1'b0 ;
|
assign intenable_reg[i] = 1'b0 ;
|
||||||
assign extintsrc_req_gw[i] = 1'b0 ;
|
assign extintsrc_req_gw[i] = 1'b0 ;
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
assign intpriority_reg_inv[i] = intpriord ? ~intpriority_reg[i] : intpriority_reg[i] ;
|
assign intpriority_reg_inv[i] = intpriord ? ~intpriority_reg[i] : intpriority_reg[i] ;
|
||||||
|
|
||||||
assign intpend_w_prior_en[i] = {INTPRIORITY_BITS{(extintsrc_req_gw[i] & intenable_reg[i])}} & intpriority_reg_inv[i] ;
|
assign intpend_w_prior_en[i] = {INTPRIORITY_BITS{(extintsrc_req_gw[i] & intenable_reg[i])}} & intpriority_reg_inv[i] ;
|
||||||
assign intpend_id[i] = i ;
|
assign intpend_id[i] = i ;
|
||||||
end
|
end
|
||||||
|
@ -242,127 +242,115 @@ end
|
||||||
assign pl_in[INTPRIORITY_BITS-1:0] = selected_int_priority[INTPRIORITY_BITS-1:0] ;
|
assign pl_in[INTPRIORITY_BITS-1:0] = selected_int_priority[INTPRIORITY_BITS-1:0] ;
|
||||||
|
|
||||||
`ifdef RV_PIC_2CYCLE
|
`ifdef RV_PIC_2CYCLE
|
||||||
logic [NUM_LEVELS/2:0] [TOTAL_INT+2:0] [INTPRIORITY_BITS-1:0] level_intpend_w_prior_en;
|
logic [NUM_LEVELS/2:0] [TOTAL_INT+2:0] [INTPRIORITY_BITS-1:0] level_intpend_w_prior_en;
|
||||||
logic [NUM_LEVELS/2:0] [TOTAL_INT+2:0] [ID_BITS-1:0] level_intpend_id;
|
logic [NUM_LEVELS/2:0] [TOTAL_INT+2:0] [ID_BITS-1:0] level_intpend_id;
|
||||||
logic [NUM_LEVELS:NUM_LEVELS/2] [(TOTAL_INT/2**(NUM_LEVELS/2))+1:0] [INTPRIORITY_BITS-1:0] levelx_intpend_w_prior_en;
|
logic [NUM_LEVELS:NUM_LEVELS/2] [(TOTAL_INT/2**(NUM_LEVELS/2))+1:0] [INTPRIORITY_BITS-1:0] levelx_intpend_w_prior_en;
|
||||||
logic [NUM_LEVELS:NUM_LEVELS/2] [(TOTAL_INT/2**(NUM_LEVELS/2))+1:0] [ID_BITS-1:0] levelx_intpend_id;
|
logic [NUM_LEVELS:NUM_LEVELS/2] [(TOTAL_INT/2**(NUM_LEVELS/2))+1:0] [ID_BITS-1:0] levelx_intpend_id;
|
||||||
|
|
||||||
assign level_intpend_w_prior_en[0][TOTAL_INT+2:0] = {4'b0,4'b0,4'b0,intpend_w_prior_en[TOTAL_INT-1:0]} ;
|
assign level_intpend_w_prior_en[0][TOTAL_INT+2:0] = {4'b0,4'b0,4'b0,intpend_w_prior_en[TOTAL_INT-1:0]} ;
|
||||||
assign level_intpend_id[0][TOTAL_INT+2:0] = {8'b0,8'b0,8'b0,intpend_id[TOTAL_INT-1:0]} ;
|
assign level_intpend_id[0][TOTAL_INT+2:0] = {8'b0,8'b0,8'b0,intpend_id[TOTAL_INT-1:0]} ;
|
||||||
|
|
||||||
logic [(TOTAL_INT/2**(NUM_LEVELS/2)):0] [INTPRIORITY_BITS-1:0] l2_intpend_w_prior_en_ff;
|
logic [(TOTAL_INT/2**(NUM_LEVELS/2)):0] [INTPRIORITY_BITS-1:0] l2_intpend_w_prior_en_ff;
|
||||||
logic [(TOTAL_INT/2**(NUM_LEVELS/2)):0] [ID_BITS-1:0] l2_intpend_id_ff;
|
logic [(TOTAL_INT/2**(NUM_LEVELS/2)):0] [ID_BITS-1:0] l2_intpend_id_ff;
|
||||||
|
|
||||||
assign levelx_intpend_w_prior_en[NUM_LEVELS/2][(TOTAL_INT/2**(NUM_LEVELS/2))+1:0] = {{1*INTPRIORITY_BITS{1'b0}},l2_intpend_w_prior_en_ff[(TOTAL_INT/2**(NUM_LEVELS/2)):0]} ;
|
assign levelx_intpend_w_prior_en[NUM_LEVELS/2][(TOTAL_INT/2**(NUM_LEVELS/2))+1:0] = {{1*INTPRIORITY_BITS{1'b0}},l2_intpend_w_prior_en_ff[(TOTAL_INT/2**(NUM_LEVELS/2)):0]} ;
|
||||||
assign levelx_intpend_id[NUM_LEVELS/2][(TOTAL_INT/2**(NUM_LEVELS/2))+1:0] = {{1*ID_BITS{1'b1}},l2_intpend_id_ff[(TOTAL_INT/2**(NUM_LEVELS/2)):0]} ;
|
assign levelx_intpend_id[NUM_LEVELS/2][(TOTAL_INT/2**(NUM_LEVELS/2))+1:0] = {{1*ID_BITS{1'b1}},l2_intpend_id_ff[(TOTAL_INT/2**(NUM_LEVELS/2)):0]} ;
|
||||||
|
|
||||||
|
///////// Do the prioritization of the interrupts here ////////////
|
||||||
|
for (l=0; l<NUM_LEVELS/2 ; l++) begin : TOP_LEVEL
|
||||||
|
for (m=0; m<=(TOTAL_INT)/(2**(l+1)) ; m++) begin : COMPARE
|
||||||
|
if ( m == (TOTAL_INT)/(2**(l+1))) begin
|
||||||
|
assign level_intpend_w_prior_en[l+1][m+1] = '0 ;
|
||||||
|
assign level_intpend_id[l+1][m+1] = '0 ;
|
||||||
|
end
|
||||||
|
cmp_and_mux #(.ID_BITS(ID_BITS),
|
||||||
|
.INTPRIORITY_BITS(INTPRIORITY_BITS)) cmp_l1 (
|
||||||
|
.a_id(level_intpend_id[l][2*m]),
|
||||||
|
.a_priority(level_intpend_w_prior_en[l][2*m]),
|
||||||
|
.b_id(level_intpend_id[l][2*m+1]),
|
||||||
|
.b_priority(level_intpend_w_prior_en[l][2*m+1]),
|
||||||
|
.out_id(level_intpend_id[l+1][m]),
|
||||||
|
.out_priority(level_intpend_w_prior_en[l+1][m])) ;
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
for (i=0; i<=TOTAL_INT/2**(NUM_LEVELS/2) ; i++) begin : MIDDLE_FLOPS
|
||||||
|
rvdff #(INTPRIORITY_BITS) level2_intpend_prior_reg (.*, .din (level_intpend_w_prior_en[NUM_LEVELS/2][i]), .dout(l2_intpend_w_prior_en_ff[i]), .clk(free_clk));
|
||||||
|
rvdff #(ID_BITS) level2_intpend_id_reg (.*, .din (level_intpend_id[NUM_LEVELS/2][i]), .dout(l2_intpend_id_ff[i]), .clk(free_clk));
|
||||||
|
end
|
||||||
|
|
||||||
|
for (j=NUM_LEVELS/2; j<NUM_LEVELS ; j++) begin : BOT_LEVELS
|
||||||
|
for (k=0; k<=(TOTAL_INT)/(2**(j+1)) ; k++) begin : COMPARE
|
||||||
|
if ( k == (TOTAL_INT)/(2**(j+1))) begin
|
||||||
|
assign levelx_intpend_w_prior_en[j+1][k+1] = '0 ;
|
||||||
|
assign levelx_intpend_id[j+1][k+1] = '0 ;
|
||||||
|
end
|
||||||
|
cmp_and_mux #(.ID_BITS(ID_BITS),
|
||||||
|
.INTPRIORITY_BITS(INTPRIORITY_BITS))
|
||||||
|
cmp_l1 (
|
||||||
|
.a_id(levelx_intpend_id[j][2*k]),
|
||||||
|
.a_priority(levelx_intpend_w_prior_en[j][2*k]),
|
||||||
|
.b_id(levelx_intpend_id[j][2*k+1]),
|
||||||
|
.b_priority(levelx_intpend_w_prior_en[j][2*k+1]),
|
||||||
|
.out_id(levelx_intpend_id[j+1][k]),
|
||||||
|
.out_priority(levelx_intpend_w_prior_en[j+1][k])) ;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
assign claimid_in[ID_BITS-1:0] = levelx_intpend_id[NUM_LEVELS][0] ; // This is the last level output
|
||||||
|
assign selected_int_priority[INTPRIORITY_BITS-1:0] = levelx_intpend_w_prior_en[NUM_LEVELS][0] ;
|
||||||
|
|
||||||
`else
|
`else
|
||||||
logic [NUM_LEVELS:0] [TOTAL_INT+1:0] [INTPRIORITY_BITS-1:0] level_intpend_w_prior_en;
|
logic [NUM_LEVELS:0] [TOTAL_INT+1:0] [INTPRIORITY_BITS-1:0] level_intpend_w_prior_en;
|
||||||
logic [NUM_LEVELS:0] [TOTAL_INT+1:0] [ID_BITS-1:0] level_intpend_id;
|
logic [NUM_LEVELS:0] [TOTAL_INT+1:0] [ID_BITS-1:0] level_intpend_id;
|
||||||
|
|
||||||
assign level_intpend_w_prior_en[0][TOTAL_INT+1:0] = {{2*INTPRIORITY_BITS{1'b0}},intpend_w_prior_en[TOTAL_INT-1:0]} ;
|
assign level_intpend_w_prior_en[0][TOTAL_INT+1:0] = {{2*INTPRIORITY_BITS{1'b0}},intpend_w_prior_en[TOTAL_INT-1:0]} ;
|
||||||
assign level_intpend_id[0][TOTAL_INT+1:0] = {{2*ID_BITS{1'b1}},intpend_id[TOTAL_INT-1:0]} ;
|
assign level_intpend_id[0][TOTAL_INT+1:0] = {{2*ID_BITS{1'b1}},intpend_id[TOTAL_INT-1:0]} ;
|
||||||
|
|
||||||
|
////////// Do the prioritization of the interrupts here ////////////
|
||||||
|
///////// genvar l, m , j, k; already declared outside ifdef
|
||||||
|
for (l=0; l<NUM_LEVELS ; l++) begin : LEVEL
|
||||||
|
for (m=0; m<=(TOTAL_INT)/(2**(l+1)) ; m++) begin : COMPARE
|
||||||
|
if ( m == (TOTAL_INT)/(2**(l+1))) begin
|
||||||
|
assign level_intpend_w_prior_en[l+1][m+1] = '0 ;
|
||||||
|
assign level_intpend_id[l+1][m+1] = '0 ;
|
||||||
|
end
|
||||||
|
cmp_and_mux #(.ID_BITS(ID_BITS),
|
||||||
|
.INTPRIORITY_BITS(INTPRIORITY_BITS)) cmp_l1 (
|
||||||
|
.a_id(level_intpend_id[l][2*m]),
|
||||||
|
.a_priority(level_intpend_w_prior_en[l][2*m]),
|
||||||
|
.b_id(level_intpend_id[l][2*m+1]),
|
||||||
|
.b_priority(level_intpend_w_prior_en[l][2*m+1]),
|
||||||
|
.out_id(level_intpend_id[l+1][m]),
|
||||||
|
.out_priority(level_intpend_w_prior_en[l+1][m])) ;
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
assign claimid_in[ID_BITS-1:0] = level_intpend_id[NUM_LEVELS][0] ; // This is the last level output
|
||||||
|
assign selected_int_priority[INTPRIORITY_BITS-1:0] = level_intpend_w_prior_en[NUM_LEVELS][0] ;
|
||||||
|
|
||||||
`endif
|
`endif
|
||||||
|
|
||||||
genvar l, m , j, k;
|
|
||||||
|
|
||||||
// `ifdef VERILATOR
|
|
||||||
`include "pic_ctrl_verilator_unroll.sv"
|
|
||||||
// `else
|
|
||||||
// `ifdef RV_PIC_2CYCLE
|
|
||||||
// /// Do the prioritization of the interrupts here ////////////
|
|
||||||
// for (l=0; l<NUM_LEVELS/2 ; l++) begin : TOP_LEVEL
|
|
||||||
// for (m=0; m<=(TOTAL_INT)/(2**(l+1)) ; m++) begin : COMPARE
|
|
||||||
// if ( m == (TOTAL_INT)/(2**(l+1))) begin
|
|
||||||
// assign level_intpend_w_prior_en[l+1][m+1] = '0 ;
|
|
||||||
// assign level_intpend_id[l+1][m+1] = '0 ;
|
|
||||||
// end
|
|
||||||
// cmp_and_mux #(.ID_BITS(ID_BITS),
|
|
||||||
// .INTPRIORITY_BITS(INTPRIORITY_BITS)) cmp_l1 (
|
|
||||||
// .a_id(level_intpend_id[l][2*m]),
|
|
||||||
// .a_priority(level_intpend_w_prior_en[l][2*m]),
|
|
||||||
// .b_id(level_intpend_id[l][2*m+1]),
|
|
||||||
// .b_priority(level_intpend_w_prior_en[l][2*m+1]),
|
|
||||||
// .out_id(level_intpend_id[l+1][m]),
|
|
||||||
// .out_priority(level_intpend_w_prior_en[l+1][m])) ;
|
|
||||||
//
|
|
||||||
// end
|
|
||||||
// end
|
|
||||||
//
|
|
||||||
// for (i=0; i<=TOTAL_INT/2**(NUM_LEVELS/2) ; i++) begin : MIDDLE_FLOPS
|
|
||||||
// rvdff #(INTPRIORITY_BITS) level2_intpend_prior_reg (.*, .din (level_intpend_w_prior_en[NUM_LEVELS/2][i]), .dout(l2_intpend_w_prior_en_ff[i]), .clk(free_clk));
|
|
||||||
// rvdff #(ID_BITS) level2_intpend_id_reg (.*, .din (level_intpend_id[NUM_LEVELS/2][i]), .dout(l2_intpend_id_ff[i]), .clk(free_clk));
|
|
||||||
// end
|
|
||||||
//
|
|
||||||
// for (j=NUM_LEVELS/2; j<NUM_LEVELS ; j++) begin : BOT_LEVELS
|
|
||||||
// for (k=0; k<=(TOTAL_INT)/(2**(j+1)) ; k++) begin : COMPARE
|
|
||||||
// if ( k == (TOTAL_INT)/(2**(j+1))) begin
|
|
||||||
// assign levelx_intpend_w_prior_en[j+1][k+1] = '0 ;
|
|
||||||
// assign levelx_intpend_id[j+1][k+1] = '0 ;
|
|
||||||
// end
|
|
||||||
// cmp_and_mux #(.ID_BITS(ID_BITS),
|
|
||||||
// .INTPRIORITY_BITS(INTPRIORITY_BITS))
|
|
||||||
// cmp_l1 (
|
|
||||||
// .a_id(levelx_intpend_id[j][2*k]),
|
|
||||||
// .a_priority(levelx_intpend_w_prior_en[j][2*k]),
|
|
||||||
// .b_id(levelx_intpend_id[j][2*k+1]),
|
|
||||||
// .b_priority(levelx_intpend_w_prior_en[j][2*k+1]),
|
|
||||||
// .out_id(levelx_intpend_id[j+1][k]),
|
|
||||||
// .out_priority(levelx_intpend_w_prior_en[j+1][k])) ;
|
|
||||||
// end
|
|
||||||
// end
|
|
||||||
// assign claimid_in[ID_BITS-1:0] = levelx_intpend_id[NUM_LEVELS][0] ; // This is the last level output
|
|
||||||
// assign selected_int_priority[INTPRIORITY_BITS-1:0] = levelx_intpend_w_prior_en[NUM_LEVELS][0] ;
|
|
||||||
//
|
|
||||||
// `else
|
|
||||||
//
|
|
||||||
// /// Do the prioritization of the interrupts here ////////////
|
|
||||||
// // genvar l, m , j, k; already declared outside ifdef
|
|
||||||
// for (l=0; l<NUM_LEVELS ; l++) begin : LEVEL
|
|
||||||
// for (m=0; m<=(TOTAL_INT)/(2**(l+1)) ; m++) begin : COMPARE
|
|
||||||
// if ( m == (TOTAL_INT)/(2**(l+1))) begin
|
|
||||||
// assign level_intpend_w_prior_en[l+1][m+1] = '0 ;
|
|
||||||
// assign level_intpend_id[l+1][m+1] = '0 ;
|
|
||||||
// end
|
|
||||||
// cmp_and_mux #(.ID_BITS(ID_BITS),
|
|
||||||
// .INTPRIORITY_BITS(INTPRIORITY_BITS)) cmp_l1 (
|
|
||||||
// .a_id(level_intpend_id[l][2*m]),
|
|
||||||
// .a_priority(level_intpend_w_prior_en[l][2*m]),
|
|
||||||
// .b_id(level_intpend_id[l][2*m+1]),
|
|
||||||
// .b_priority(level_intpend_w_prior_en[l][2*m+1]),
|
|
||||||
// .out_id(level_intpend_id[l+1][m]),
|
|
||||||
// .out_priority(level_intpend_w_prior_en[l+1][m])) ;
|
|
||||||
//
|
|
||||||
// end
|
|
||||||
// end
|
|
||||||
// assign claimid_in[ID_BITS-1:0] = level_intpend_id[NUM_LEVELS][0] ; // This is the last level output
|
|
||||||
// assign selected_int_priority[INTPRIORITY_BITS-1:0] = level_intpend_w_prior_en[NUM_LEVELS][0] ;
|
|
||||||
//
|
|
||||||
// `endif
|
|
||||||
// `endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////
|
||||||
// Config Reg`
|
// Config Reg`
|
||||||
///////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////
|
||||||
assign config_reg_we = addr_config_pic_match & picm_wren_ff;
|
assign config_reg_we = addr_config_pic_match & picm_wren_ff;
|
||||||
assign config_reg_re = addr_config_pic_match & picm_rden_ff;
|
assign config_reg_re = addr_config_pic_match & picm_rden_ff;
|
||||||
|
|
||||||
assign config_reg_in = picm_wr_data_ff[0] ; //
|
assign config_reg_in = picm_wr_data_ff[0] ; //
|
||||||
rvdffs #(1) config_reg_ff (.*, .clk(free_clk), .en(config_reg_we), .din (config_reg_in), .dout(config_reg));
|
rvdffs #(1) config_reg_ff (.*, .clk(free_clk), .en(config_reg_we), .din (config_reg_in), .dout(config_reg));
|
||||||
|
|
||||||
assign intpriord = config_reg ;
|
assign intpriord = config_reg ;
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////
|
||||||
// Thresh-hold Reg`
|
// Thresh-hold Reg`
|
||||||
///////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////
|
||||||
//assign prithresh_reg_write = addr_prithresh_match & picm_wren_ff;
|
//assign prithresh_reg_write = addr_prithresh_match & picm_wren_ff;
|
||||||
//assign prithresh_reg_read = addr_prithresh_match & picm_rden_ff;
|
//assign prithresh_reg_read = addr_prithresh_match & picm_rden_ff;
|
||||||
//
|
//
|
||||||
//assign prithresh_reg_in[INTPRIORITY_BITS-1:0] = picm_wr_data_ff[INTPRIORITY_BITS-1:0] ; // Thresh-hold priority.
|
//assign prithresh_reg_in[INTPRIORITY_BITS-1:0] = picm_wr_data_ff[INTPRIORITY_BITS-1:0] ; // Thresh-hold priority.
|
||||||
//rvdffs #(INTPRIORITY_BITS) prithresh_reg_ff (.*, .en(prithresh_reg_write), .din (prithresh_reg_in[INTPRIORITY_BITS-1:0]), .dout(prithresh_reg[INTPRIORITY_BITS-1:0]));
|
//rvdffs #(INTPRIORITY_BITS) prithresh_reg_ff (.*, .en(prithresh_reg_write), .din (prithresh_reg_in[INTPRIORITY_BITS-1:0]), .dout(prithresh_reg[INTPRIORITY_BITS-1:0]));
|
||||||
//
|
//
|
||||||
|
|
||||||
|
@ -372,10 +360,10 @@ assign intpriord = config_reg ;
|
||||||
///////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////
|
||||||
/// ClaimId Reg and Corresponding PL
|
/// ClaimId Reg and Corresponding PL
|
||||||
///////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////
|
||||||
// logic atleast_one_int_enabled_in,atleast_one_int_enabled ;
|
// logic atleast_one_int_enabled_in,atleast_one_int_enabled ;
|
||||||
// logic mexintpend_unq ;
|
// logic mexintpend_unq ;
|
||||||
// logic mhwakeup_unq ;
|
// logic mhwakeup_unq ;
|
||||||
//
|
//
|
||||||
assign pl_in_q[INTPRIORITY_BITS-1:0] = intpriord ? ~pl_in : pl_in ;
|
assign pl_in_q[INTPRIORITY_BITS-1:0] = intpriord ? ~pl_in : pl_in ;
|
||||||
rvdff #(ID_BITS) claimid_ff (.*, .din (claimid_in[ID_BITS-1:00]), .dout(claimid[ID_BITS-1:00]), .clk(free_clk));
|
rvdff #(ID_BITS) claimid_ff (.*, .din (claimid_in[ID_BITS-1:00]), .dout(claimid[ID_BITS-1:00]), .clk(free_clk));
|
||||||
rvdff #(INTPRIORITY_BITS) pl_ff (.*, .din (pl_in_q[INTPRIORITY_BITS-1:0]), .dout(pl[INTPRIORITY_BITS-1:0]), .clk(free_clk));
|
rvdff #(INTPRIORITY_BITS) pl_ff (.*, .din (pl_in_q[INTPRIORITY_BITS-1:0]), .dout(pl[INTPRIORITY_BITS-1:0]), .clk(free_clk));
|
||||||
|
@ -383,7 +371,7 @@ rvdff #(INTPRIORITY_BITS) pl_ff (.*, .din (pl_in_q[INTPRIORITY_BITS-1:0]),
|
||||||
logic [INTPRIORITY_BITS-1:0] meipt_inv , meicurpl_inv ;
|
logic [INTPRIORITY_BITS-1:0] meipt_inv , meicurpl_inv ;
|
||||||
assign meipt_inv[INTPRIORITY_BITS-1:0] = intpriord ? ~meipt[INTPRIORITY_BITS-1:0] : meipt[INTPRIORITY_BITS-1:0] ;
|
assign meipt_inv[INTPRIORITY_BITS-1:0] = intpriord ? ~meipt[INTPRIORITY_BITS-1:0] : meipt[INTPRIORITY_BITS-1:0] ;
|
||||||
assign meicurpl_inv[INTPRIORITY_BITS-1:0] = intpriord ? ~meicurpl[INTPRIORITY_BITS-1:0] : meicurpl[INTPRIORITY_BITS-1:0] ;
|
assign meicurpl_inv[INTPRIORITY_BITS-1:0] = intpriord ? ~meicurpl[INTPRIORITY_BITS-1:0] : meicurpl[INTPRIORITY_BITS-1:0] ;
|
||||||
assign mexintpend_in = (( selected_int_priority[INTPRIORITY_BITS-1:0] > 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]) );
|
( 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));
|
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] ;
|
// 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));
|
// 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 mexintpend = mexintpend_unq & atleast_one_int_enabled ;
|
||||||
// assign mhwakeup = mhwakeup_unq & atleast_one_int_enabled ;
|
// assign mhwakeup = mhwakeup_unq & atleast_one_int_enabled ;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
// Reads of register.
|
// Reads of register.
|
||||||
// 1- intpending
|
// 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 intpriority_reg_read = addr_intpriority_base_match & picm_rden_ff;
|
||||||
assign intenable_reg_read = addr_intenable_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;
|
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)]) ;
|
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
|
end
|
||||||
|
|
||||||
always_comb begin : INTPEND_RD
|
always_comb begin : INTPEND_RD
|
||||||
intpend_rd_out = '0 ;
|
intpend_rd_out = '0 ;
|
||||||
for (int i=0; i<INT_GRPS; i++) begin
|
for (int i=0; i<INT_GRPS; i++) begin
|
||||||
intpend_rd_out |= intpend_rd_part_out[i] ;
|
intpend_rd_out |= intpend_rd_part_out[i] ;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
always_comb begin : INTEN_RD
|
always_comb begin : INTEN_RD
|
||||||
intenable_rd_out = '0 ;
|
intenable_rd_out = '0 ;
|
||||||
intpriority_rd_out = '0 ;
|
intpriority_rd_out = '0 ;
|
||||||
gw_config_rd_out = '0 ;
|
gw_config_rd_out = '0 ;
|
||||||
|
@ -439,28 +427,28 @@ assign intpend_reg_extended[INTPEND_SIZE-1:0] = {{INTPEND_SIZE-TOTAL_INT{1'b0}}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
assign picm_rd_data_in[31:0] = ({32{intpend_reg_read }} & intpend_rd_out ) |
|
|
||||||
({32{intpriority_reg_read }} & {{32-INTPRIORITY_BITS{1'b0}}, intpriority_rd_out } ) |
|
assign picm_rd_data_in[31:0] = ({32{intpend_reg_read }} & intpend_rd_out ) |
|
||||||
|
({32{intpriority_reg_read }} & {{32-INTPRIORITY_BITS{1'b0}}, intpriority_rd_out } ) |
|
||||||
({32{intenable_reg_read }} & {31'b0 , intenable_rd_out } ) |
|
({32{intenable_reg_read }} & {31'b0 , intenable_rd_out } ) |
|
||||||
({32{gw_config_reg_read }} & {30'b0 , gw_config_rd_out } ) |
|
({32{gw_config_reg_read }} & {30'b0 , gw_config_rd_out } ) |
|
||||||
({32{config_reg_re }} & {31'b0 , config_reg } ) |
|
({32{config_reg_re }} & {31'b0 , config_reg } ) |
|
||||||
({32{picm_mken_ff & mask[3]}} & {30'b0 , 2'b11 } ) |
|
({32{picm_mken_ff & mask[3]}} & {30'b0 , 2'b11 } ) |
|
||||||
({32{picm_mken_ff & mask[2]}} & {31'b0 , 1'b1 } ) |
|
({32{picm_mken_ff & mask[2]}} & {31'b0 , 1'b1 } ) |
|
||||||
({32{picm_mken_ff & mask[1]}} & {28'b0 , 4'b1111 } ) |
|
({32{picm_mken_ff & mask[1]}} & {28'b0 , 4'b1111 } ) |
|
||||||
({32{picm_mken_ff & mask[0]}} & 32'b0 ) ;
|
({32{picm_mken_ff & mask[0]}} & 32'b0 ) ;
|
||||||
|
|
||||||
|
|
||||||
assign picm_rd_data[31:0] = picm_rd_data_in[31:0] ;
|
assign picm_rd_data[31:0] = picm_rd_data_in[31:0] ;
|
||||||
|
|
||||||
logic [14:0] address;
|
logic [14:0] address;
|
||||||
|
|
||||||
assign address[14:0] = picm_addr_ff[14:0];
|
assign address[14:0] = picm_addr_ff[14:0];
|
||||||
|
|
||||||
`include "pic_map_auto.h"
|
`include "pic_map_auto.h"
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
|
|
||||||
module cmp_and_mux #(parameter ID_BITS=8,
|
module cmp_and_mux #(parameter ID_BITS=8,
|
||||||
|
@ -468,26 +456,26 @@ module cmp_and_mux #(parameter ID_BITS=8,
|
||||||
(
|
(
|
||||||
input logic [ID_BITS-1:0] a_id,
|
input logic [ID_BITS-1:0] a_id,
|
||||||
input logic [INTPRIORITY_BITS-1:0] a_priority,
|
input logic [INTPRIORITY_BITS-1:0] a_priority,
|
||||||
|
|
||||||
input logic [ID_BITS-1:0] b_id,
|
input logic [ID_BITS-1:0] b_id,
|
||||||
input logic [INTPRIORITY_BITS-1:0] b_priority,
|
input logic [INTPRIORITY_BITS-1:0] b_priority,
|
||||||
|
|
||||||
output logic [ID_BITS-1:0] out_id,
|
output logic [ID_BITS-1:0] out_id,
|
||||||
output logic [INTPRIORITY_BITS-1:0] out_priority
|
output logic [INTPRIORITY_BITS-1:0] out_priority
|
||||||
|
|
||||||
);
|
);
|
||||||
|
|
||||||
logic a_is_lt_b ;
|
logic a_is_lt_b ;
|
||||||
|
|
||||||
assign a_is_lt_b = ( a_priority[INTPRIORITY_BITS-1:0] < b_priority[INTPRIORITY_BITS-1:0] ) ;
|
assign a_is_lt_b = ( a_priority[INTPRIORITY_BITS-1:0] < b_priority[INTPRIORITY_BITS-1:0] ) ;
|
||||||
// assign a_is_eq_b = ( a_priority[INTPRIORITY_BITS-1:0] == b_priority[INTPRIORITY_BITS-1:0]) ;
|
// assign a_is_eq_b = ( a_priority[INTPRIORITY_BITS-1:0] == b_priority[INTPRIORITY_BITS-1:0]) ;
|
||||||
|
|
||||||
assign out_id[ID_BITS-1:0] = a_is_lt_b ? b_id[ID_BITS-1:0] :
|
assign out_id[ID_BITS-1:0] = a_is_lt_b ? b_id[ID_BITS-1:0] :
|
||||||
a_id[ID_BITS-1:0] ;
|
a_id[ID_BITS-1:0] ;
|
||||||
assign out_priority[INTPRIORITY_BITS-1:0] = a_is_lt_b ? b_priority[INTPRIORITY_BITS-1:0] :
|
assign out_priority[INTPRIORITY_BITS-1:0] = a_is_lt_b ? b_priority[INTPRIORITY_BITS-1:0] :
|
||||||
a_priority[INTPRIORITY_BITS-1:0] ;
|
a_priority[INTPRIORITY_BITS-1:0] ;
|
||||||
endmodule // cmp_and_mux
|
endmodule // cmp_and_mux
|
||||||
|
|
||||||
|
|
||||||
module configurable_gw (
|
module configurable_gw (
|
||||||
input logic clk,
|
input logic clk,
|
||||||
|
@ -497,10 +485,10 @@ module configurable_gw (
|
||||||
input logic meigwctrl_polarity ,
|
input logic meigwctrl_polarity ,
|
||||||
input logic meigwctrl_type ,
|
input logic meigwctrl_type ,
|
||||||
input logic meigwclr ,
|
input logic meigwclr ,
|
||||||
|
|
||||||
output logic extintsrc_req_config
|
output logic extintsrc_req_config
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
logic gw_int_pending_in , gw_int_pending ;
|
logic gw_int_pending_in , gw_int_pending ;
|
||||||
|
|
||||||
|
|
433
design/swerv.sv
433
design/swerv.sv
File diff suppressed because it is too large
Load Diff
|
@ -1,12 +1,12 @@
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
// Copyright 2019 Western Digital Corporation or its affiliates.
|
// Copyright 2019 Western Digital Corporation or its affiliates.
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "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 not use this file except in compliance with the License.
|
||||||
// You may obtain a copy of the License at
|
// You may obtain a copy of the License at
|
||||||
//
|
//
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
//
|
//
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
@ -17,21 +17,22 @@
|
||||||
// $Id$
|
// $Id$
|
||||||
//
|
//
|
||||||
// Function: Top wrapper file with swerv/mem instantiated inside
|
// Function: Top wrapper file with swerv/mem instantiated inside
|
||||||
// Comments:
|
// Comments:
|
||||||
//
|
//
|
||||||
//********************************************************************************
|
//********************************************************************************
|
||||||
`include "build.h"
|
`include "build.h"
|
||||||
//`include "def.sv"
|
//`include "def.sv"
|
||||||
module swerv_wrapper
|
module swerv_wrapper
|
||||||
import swerv_types::*;
|
import swerv_types::*;
|
||||||
(
|
(
|
||||||
input logic clk,
|
input logic clk,
|
||||||
input logic rst_l,
|
input logic rst_l,
|
||||||
|
input logic dbg_rst_l,
|
||||||
input logic [31:1] rst_vec,
|
input logic [31:1] rst_vec,
|
||||||
input logic nmi_int,
|
input logic nmi_int,
|
||||||
input logic [31:1] nmi_vec,
|
input logic [31:1] nmi_vec,
|
||||||
input logic [31:1] jtag_id,
|
input logic [31:1] jtag_id,
|
||||||
|
|
||||||
|
|
||||||
output logic [63:0] trace_rv_i_insn_ip,
|
output logic [63:0] trace_rv_i_insn_ip,
|
||||||
output logic [63:0] trace_rv_i_address_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 [3:0] lsu_axi_awcache,
|
||||||
output logic [2:0] lsu_axi_awprot,
|
output logic [2:0] lsu_axi_awprot,
|
||||||
output logic [3:0] lsu_axi_awqos,
|
output logic [3:0] lsu_axi_awqos,
|
||||||
|
|
||||||
output logic lsu_axi_wvalid,
|
output logic lsu_axi_wvalid,
|
||||||
input logic lsu_axi_wready,
|
input logic lsu_axi_wready,
|
||||||
output logic [63:0] lsu_axi_wdata,
|
output logic [63:0] lsu_axi_wdata,
|
||||||
output logic [7:0] lsu_axi_wstrb,
|
output logic [7:0] lsu_axi_wstrb,
|
||||||
output logic lsu_axi_wlast,
|
output logic lsu_axi_wlast,
|
||||||
|
|
||||||
input logic lsu_axi_bvalid,
|
input logic lsu_axi_bvalid,
|
||||||
output logic lsu_axi_bready,
|
output logic lsu_axi_bready,
|
||||||
input logic [1:0] lsu_axi_bresp,
|
input logic [1:0] lsu_axi_bresp,
|
||||||
input logic [`RV_LSU_BUS_TAG-1:0] lsu_axi_bid,
|
input logic [`RV_LSU_BUS_TAG-1:0] lsu_axi_bid,
|
||||||
|
|
||||||
// AXI Read Channels
|
// AXI Read Channels
|
||||||
output logic lsu_axi_arvalid,
|
output logic lsu_axi_arvalid,
|
||||||
input logic lsu_axi_arready,
|
input logic lsu_axi_arready,
|
||||||
output logic [`RV_LSU_BUS_TAG-1:0] lsu_axi_arid,
|
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 [3:0] lsu_axi_arcache,
|
||||||
output logic [2:0] lsu_axi_arprot,
|
output logic [2:0] lsu_axi_arprot,
|
||||||
output logic [3:0] lsu_axi_arqos,
|
output logic [3:0] lsu_axi_arqos,
|
||||||
|
|
||||||
input logic lsu_axi_rvalid,
|
input logic lsu_axi_rvalid,
|
||||||
output logic lsu_axi_rready,
|
output logic lsu_axi_rready,
|
||||||
input logic [`RV_LSU_BUS_TAG-1:0] lsu_axi_rid,
|
input logic [`RV_LSU_BUS_TAG-1:0] lsu_axi_rid,
|
||||||
input logic [63:0] lsu_axi_rdata,
|
input logic [63:0] lsu_axi_rdata,
|
||||||
input logic [1:0] lsu_axi_rresp,
|
input logic [1:0] lsu_axi_rresp,
|
||||||
input logic lsu_axi_rlast,
|
input logic lsu_axi_rlast,
|
||||||
|
|
||||||
//-------------------------- IFU AXI signals--------------------------
|
//-------------------------- IFU AXI signals--------------------------
|
||||||
// AXI Write Channels
|
// AXI Write Channels
|
||||||
output logic ifu_axi_awvalid,
|
output logic ifu_axi_awvalid,
|
||||||
|
@ -105,19 +106,19 @@ module swerv_wrapper
|
||||||
output logic [3:0] ifu_axi_awcache,
|
output logic [3:0] ifu_axi_awcache,
|
||||||
output logic [2:0] ifu_axi_awprot,
|
output logic [2:0] ifu_axi_awprot,
|
||||||
output logic [3:0] ifu_axi_awqos,
|
output logic [3:0] ifu_axi_awqos,
|
||||||
|
|
||||||
output logic ifu_axi_wvalid,
|
output logic ifu_axi_wvalid,
|
||||||
input logic ifu_axi_wready,
|
input logic ifu_axi_wready,
|
||||||
output logic [63:0] ifu_axi_wdata,
|
output logic [63:0] ifu_axi_wdata,
|
||||||
output logic [7:0] ifu_axi_wstrb,
|
output logic [7:0] ifu_axi_wstrb,
|
||||||
output logic ifu_axi_wlast,
|
output logic ifu_axi_wlast,
|
||||||
|
|
||||||
input logic ifu_axi_bvalid,
|
input logic ifu_axi_bvalid,
|
||||||
output logic ifu_axi_bready,
|
output logic ifu_axi_bready,
|
||||||
input logic [1:0] ifu_axi_bresp,
|
input logic [1:0] ifu_axi_bresp,
|
||||||
input logic [`RV_IFU_BUS_TAG-1:0] ifu_axi_bid,
|
input logic [`RV_IFU_BUS_TAG-1:0] ifu_axi_bid,
|
||||||
|
|
||||||
// AXI Read Channels
|
// AXI Read Channels
|
||||||
output logic ifu_axi_arvalid,
|
output logic ifu_axi_arvalid,
|
||||||
input logic ifu_axi_arready,
|
input logic ifu_axi_arready,
|
||||||
output logic [`RV_IFU_BUS_TAG-1:0] ifu_axi_arid,
|
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 [3:0] ifu_axi_arcache,
|
||||||
output logic [2:0] ifu_axi_arprot,
|
output logic [2:0] ifu_axi_arprot,
|
||||||
output logic [3:0] ifu_axi_arqos,
|
output logic [3:0] ifu_axi_arqos,
|
||||||
|
|
||||||
input logic ifu_axi_rvalid,
|
input logic ifu_axi_rvalid,
|
||||||
output logic ifu_axi_rready,
|
output logic ifu_axi_rready,
|
||||||
input logic [`RV_IFU_BUS_TAG-1:0] ifu_axi_rid,
|
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 [3:0] sb_axi_awcache,
|
||||||
output logic [2:0] sb_axi_awprot,
|
output logic [2:0] sb_axi_awprot,
|
||||||
output logic [3:0] sb_axi_awqos,
|
output logic [3:0] sb_axi_awqos,
|
||||||
|
|
||||||
output logic sb_axi_wvalid,
|
output logic sb_axi_wvalid,
|
||||||
input logic sb_axi_wready,
|
input logic sb_axi_wready,
|
||||||
output logic [63:0] sb_axi_wdata,
|
output logic [63:0] sb_axi_wdata,
|
||||||
output logic [7:0] sb_axi_wstrb,
|
output logic [7:0] sb_axi_wstrb,
|
||||||
output logic sb_axi_wlast,
|
output logic sb_axi_wlast,
|
||||||
|
|
||||||
input logic sb_axi_bvalid,
|
input logic sb_axi_bvalid,
|
||||||
output logic sb_axi_bready,
|
output logic sb_axi_bready,
|
||||||
input logic [1:0] sb_axi_bresp,
|
input logic [1:0] sb_axi_bresp,
|
||||||
input logic [`RV_SB_BUS_TAG-1:0] sb_axi_bid,
|
input logic [`RV_SB_BUS_TAG-1:0] sb_axi_bid,
|
||||||
|
|
||||||
// AXI Read Channels
|
// AXI Read Channels
|
||||||
output logic sb_axi_arvalid,
|
output logic sb_axi_arvalid,
|
||||||
input logic sb_axi_arready,
|
input logic sb_axi_arready,
|
||||||
output logic [`RV_SB_BUS_TAG-1:0] sb_axi_arid,
|
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 [3:0] sb_axi_arcache,
|
||||||
output logic [2:0] sb_axi_arprot,
|
output logic [2:0] sb_axi_arprot,
|
||||||
output logic [3:0] sb_axi_arqos,
|
output logic [3:0] sb_axi_arqos,
|
||||||
|
|
||||||
input logic sb_axi_rvalid,
|
input logic sb_axi_rvalid,
|
||||||
output logic sb_axi_rready,
|
output logic sb_axi_rready,
|
||||||
input logic [`RV_SB_BUS_TAG-1:0] sb_axi_rid,
|
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 [1:0] dma_axi_awburst,
|
||||||
|
|
||||||
|
|
||||||
input logic dma_axi_wvalid,
|
input logic dma_axi_wvalid,
|
||||||
output logic dma_axi_wready,
|
output logic dma_axi_wready,
|
||||||
input logic [63:0] dma_axi_wdata,
|
input logic [63:0] dma_axi_wdata,
|
||||||
input logic [7:0] dma_axi_wstrb,
|
input logic [7:0] dma_axi_wstrb,
|
||||||
input logic dma_axi_wlast,
|
input logic dma_axi_wlast,
|
||||||
|
|
||||||
output logic dma_axi_bvalid,
|
output logic dma_axi_bvalid,
|
||||||
input logic dma_axi_bready,
|
input logic dma_axi_bready,
|
||||||
output logic [1:0] dma_axi_bresp,
|
output logic [1:0] dma_axi_bresp,
|
||||||
|
@ -212,7 +213,7 @@ module swerv_wrapper
|
||||||
input logic dma_axi_arvalid,
|
input logic dma_axi_arvalid,
|
||||||
output logic dma_axi_arready,
|
output logic dma_axi_arready,
|
||||||
input logic [`RV_DMA_BUS_TAG-1:0] dma_axi_arid,
|
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_arsize,
|
||||||
input logic [2:0] dma_axi_arprot,
|
input logic [2:0] dma_axi_arprot,
|
||||||
input logic [7:0] dma_axi_arlen,
|
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 [`RV_DMA_BUS_TAG-1:0] dma_axi_rid,
|
||||||
output logic [63:0] dma_axi_rdata,
|
output logic [63:0] dma_axi_rdata,
|
||||||
output logic [1:0] dma_axi_rresp,
|
output logic [1:0] dma_axi_rresp,
|
||||||
output logic dma_axi_rlast,
|
output logic dma_axi_rlast,
|
||||||
|
|
||||||
`endif
|
`endif
|
||||||
|
|
||||||
`ifdef RV_BUILD_AHB_LITE
|
`ifdef RV_BUILD_AHB_LITE
|
||||||
|
@ -263,11 +264,11 @@ module swerv_wrapper
|
||||||
output logic [1:0] sb_htrans,
|
output logic [1:0] sb_htrans,
|
||||||
output logic sb_hwrite,
|
output logic sb_hwrite,
|
||||||
output logic [63:0] sb_hwdata,
|
output logic [63:0] sb_hwdata,
|
||||||
|
|
||||||
input logic [63:0] sb_hrdata,
|
input logic [63:0] sb_hrdata,
|
||||||
input logic sb_hready,
|
input logic sb_hready,
|
||||||
input logic sb_hresp,
|
input logic sb_hresp,
|
||||||
|
|
||||||
// DMA Slave
|
// DMA Slave
|
||||||
input logic [31:0] dma_haddr,
|
input logic [31:0] dma_haddr,
|
||||||
input logic [2:0] dma_hburst,
|
input logic [2:0] dma_hburst,
|
||||||
|
@ -278,8 +279,8 @@ module swerv_wrapper
|
||||||
input logic dma_hwrite,
|
input logic dma_hwrite,
|
||||||
input logic [63:0] dma_hwdata,
|
input logic [63:0] dma_hwdata,
|
||||||
input logic dma_hsel,
|
input logic dma_hsel,
|
||||||
input logic dma_hreadyin,
|
input logic dma_hreadyin,
|
||||||
|
|
||||||
output logic [63:0] dma_hrdata,
|
output logic [63:0] dma_hrdata,
|
||||||
output logic dma_hreadyout,
|
output logic dma_hreadyout,
|
||||||
output logic dma_hresp,
|
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 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 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 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 ext_int,
|
||||||
input logic timer_int,
|
input logic timer_int,
|
||||||
input logic [`RV_PIC_TOTAL_INT:1] extintsrc_req,
|
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_perfcnt2,
|
||||||
output logic [1:0] dec_tlu_perfcnt3,
|
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_tck, // JTAG clk
|
||||||
input logic jtag_tms, // JTAG TMS
|
input logic jtag_tms, // JTAG TMS
|
||||||
input logic jtag_tdi, // JTAG tdi
|
input logic jtag_tdi, // JTAG tdi
|
||||||
input logic jtag_trst_n, // JTAG Reset
|
input logic jtag_trst_n, // JTAG Reset
|
||||||
output logic jtag_tdo, // JTAG TDO
|
output logic jtag_tdo, // JTAG TDO
|
||||||
|
@ -324,10 +325,10 @@ module swerv_wrapper
|
||||||
input logic i_cpu_run_req, // Async restart req to CPU
|
input logic i_cpu_run_req, // Async restart req to CPU
|
||||||
output logic o_cpu_run_ack, // Core response to run req
|
output logic o_cpu_run_ack, // Core response to run req
|
||||||
input logic scan_mode, // To enable scan mode
|
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
|
// DCCM ports
|
||||||
logic dccm_wren;
|
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_lo;
|
||||||
logic [DCCM_BITS-1:0] dccm_rd_addr_hi;
|
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_wr_data;
|
||||||
|
|
||||||
logic [DCCM_FDATA_WIDTH-1:0] dccm_rd_data_lo;
|
logic [DCCM_FDATA_WIDTH-1:0] dccm_rd_data_lo;
|
||||||
logic [DCCM_FDATA_WIDTH-1:0] dccm_rd_data_hi;
|
logic [DCCM_FDATA_WIDTH-1:0] dccm_rd_data_hi;
|
||||||
|
|
||||||
|
@ -345,40 +346,40 @@ module swerv_wrapper
|
||||||
// PIC ports
|
// PIC ports
|
||||||
|
|
||||||
// Icache & Itag 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 [3:0] ic_wr_en ; // Which way to write
|
||||||
logic ic_rd_en ;
|
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 [3:0] ic_rd_hit; // ic_rd_hit[3:0]
|
||||||
logic ic_tag_perr; // Ic tag parity error
|
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_rd_en; // Icache debug rd
|
||||||
logic ic_debug_wr_en; // Icache debug wr
|
logic ic_debug_wr_en; // Icache debug wr
|
||||||
logic ic_debug_tag_array; // Debug tag array
|
logic ic_debug_tag_array; // Debug tag array
|
||||||
logic [3:0] ic_debug_way; // Debug way. Rd or Wr.
|
logic [3:0] ic_debug_way; // Debug way. Rd or Wr.
|
||||||
|
|
||||||
`ifdef RV_ICACHE_ECC
|
`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 [83:0] ic_wr_data; // ic_wr_data[135:0]
|
||||||
logic [167:0] ic_rd_data; // ic_rd_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
|
`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 [67:0] ic_wr_data; // ic_wr_data[135:0]
|
||||||
logic [135:0] ic_rd_data; // ic_rd_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
|
`endif
|
||||||
|
|
||||||
logic [127:0] ic_premux_data;
|
logic [127:0] ic_premux_data;
|
||||||
logic ic_sel_premux_data;
|
logic ic_sel_premux_data;
|
||||||
|
|
||||||
`ifdef RV_ICCM_ENABLE
|
`ifdef RV_ICCM_ENABLE
|
||||||
// ICCM ports
|
// 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_wren;
|
||||||
logic iccm_rden;
|
logic iccm_rden;
|
||||||
logic [2:0] iccm_wr_size;
|
logic [2:0] iccm_wr_size;
|
||||||
|
@ -386,13 +387,13 @@ module swerv_wrapper
|
||||||
logic [155:0] iccm_rd_data;
|
logic [155:0] iccm_rd_data;
|
||||||
`endif
|
`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 jtag_tdoEn;
|
||||||
|
|
||||||
logic dccm_clk_override;
|
logic dccm_clk_override;
|
||||||
logic icm_clk_override;
|
logic icm_clk_override;
|
||||||
logic dec_tlu_core_ecc_disable;
|
logic dec_tlu_core_ecc_disable;
|
||||||
|
|
||||||
logic dmi_reg_en;
|
logic dmi_reg_en;
|
||||||
logic [6:0] dmi_reg_addr;
|
logic [6:0] dmi_reg_addr;
|
||||||
logic dmi_reg_wr_en;
|
logic dmi_reg_wr_en;
|
||||||
|
@ -404,7 +405,7 @@ module swerv_wrapper
|
||||||
swerv swerv (
|
swerv swerv (
|
||||||
.*
|
.*
|
||||||
);
|
);
|
||||||
|
|
||||||
// Instantiate the mem
|
// Instantiate the mem
|
||||||
mem mem (
|
mem mem (
|
||||||
.rst_l(core_rst_l),
|
.rst_l(core_rst_l),
|
||||||
|
@ -424,7 +425,7 @@ module swerv_wrapper
|
||||||
.tdoEnable (), // Test Data Output enable
|
.tdoEnable (), // Test Data Output enable
|
||||||
|
|
||||||
// Processor Signals
|
// 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
|
.core_clk (clk), // Core clock
|
||||||
.jtag_id (jtag_id), // 32 bit JTAG ID
|
.jtag_id (jtag_id), // 32 bit JTAG ID
|
||||||
.rd_data (dmi_reg_rdata), // 32 bit Read data from Processor
|
.rd_data (dmi_reg_rdata), // 32 bit Read data from Processor
|
||||||
|
@ -436,4 +437,4 @@ module swerv_wrapper
|
||||||
);
|
);
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
|
|
|
@ -1,166 +1,195 @@
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
// Copyright 2019 Western Digital Corporation or its affiliates.
|
// Copyright 2019 Western Digital Corporation or its affiliates.
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "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 not use this file except in compliance with the License.
|
||||||
// You may obtain a copy of the License at
|
// You may obtain a copy of the License at
|
||||||
//
|
//
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
//
|
//
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
//
|
//
|
||||||
|
`ifdef RV_BUILD_AHB_LITE
|
||||||
|
|
||||||
module ahb_sif (
|
module ahb_sif (
|
||||||
input logic [63:0] HWDATA,
|
input logic [63:0] HWDATA,
|
||||||
input logic HCLK,
|
input logic HCLK,
|
||||||
input logic HSEL,
|
input logic HSEL,
|
||||||
input logic [3:0] HPROT,
|
input logic [3:0] HPROT,
|
||||||
input logic HWRITE,
|
input logic HWRITE,
|
||||||
input logic [1:0] HTRANS,
|
input logic [1:0] HTRANS,
|
||||||
input logic [2:0] HSIZE,
|
input logic [2:0] HSIZE,
|
||||||
input logic HREADY,
|
input logic HREADY,
|
||||||
input logic HRESETn,
|
input logic HRESETn,
|
||||||
input logic [31:0] HADDR,
|
input logic [31:0] HADDR,
|
||||||
input logic [2:0] HBURST,
|
input logic [2:0] HBURST,
|
||||||
|
|
||||||
output logic HREADYOUT,
|
|
||||||
output logic HRESP,
|
|
||||||
output logic [63:0] HRDATA
|
|
||||||
|
|
||||||
|
output logic HREADYOUT,
|
||||||
|
output logic HRESP,
|
||||||
|
output logic [63:0] HRDATA
|
||||||
);
|
);
|
||||||
|
|
||||||
localparam MEM_SIZE_DW = 8192;
|
parameter MEM_SIZE_DW = 8192;
|
||||||
localparam MAILBOX_ADDR = 32'hD0580000;
|
parameter MAILBOX_ADDR = 32'hD0580000;
|
||||||
|
localparam MEM_SIZE = MEM_SIZE_DW*8;
|
||||||
|
|
||||||
logic Last_HSEL;
|
logic Write;
|
||||||
logic NextLast_HSEL;
|
|
||||||
logic Last_HWRITE;
|
|
||||||
logic [1:0] Last_HTRANS;
|
|
||||||
logic [1:0] NextLast_HTRANS;
|
|
||||||
logic [31:0] Last_HADDR;
|
logic [31:0] Last_HADDR;
|
||||||
logic [63:0] Next_HRDATA;
|
logic [7:0] strb_lat;
|
||||||
logic [63:0] WriteReadData;
|
|
||||||
logic [63:0] WriteMask;
|
|
||||||
|
|
||||||
bit [7:0] mem [0:MEM_SIZE_DW-1];
|
|
||||||
|
|
||||||
|
bit [7:0] mem [0:MEM_SIZE-1];
|
||||||
|
//bit [7:0] mem [int];
|
||||||
|
//int kuku[int];
|
||||||
|
|
||||||
// Wires
|
// 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[31:0] addr = HADDR & (MEM_SIZE-1);
|
||||||
wire [63:0] MaskedWriteReadData = WriteReadData & ~WriteMask;
|
wire[31:0] laddr = Last_HADDR & (MEM_SIZE-1);
|
||||||
wire [63:0] WriteData = (MaskedWriteData | MaskedWriteReadData );
|
|
||||||
wire Write = &{Last_HSEL, Last_HWRITE, Last_HTRANS[1]};
|
|
||||||
wire Read = &{ HSEL, ~HWRITE, HTRANS[1]};
|
|
||||||
|
|
||||||
wire mailbox_write = &{Write, Last_HADDR==MAILBOX_ADDR, HRESETn==1};
|
wire mailbox_write = Write && Last_HADDR==MAILBOX_ADDR;
|
||||||
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 [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
|
always @ (negedge HCLK ) begin
|
||||||
if (Write && Last_HADDR == 32'h0) begin
|
if (Write) begin
|
||||||
mem[{Last_HADDR[12:3],3'b0}+7] <= #1 { WriteData[63:56] };
|
if(strb_lat[7]) mem[{laddr[31:3],3'd7}] = HWDATA[63:56];
|
||||||
mem[{Last_HADDR[12:3],3'b0}+6] <= #1 { WriteData[55:48] };
|
if(strb_lat[6]) mem[{laddr[31:3],3'd6}] = HWDATA[55:48];
|
||||||
mem[{Last_HADDR[12:3],3'b0}+5] <= #1 { WriteData[47:40] };
|
if(strb_lat[5]) mem[{laddr[31:3],3'd5}] = HWDATA[47:40];
|
||||||
mem[{Last_HADDR[12:3],3'b0}+4] <= #1 { WriteData[39:32] };
|
if(strb_lat[4]) mem[{laddr[31:3],3'd4}] = HWDATA[39:32];
|
||||||
mem[{Last_HADDR[12:3],3'b0}+3] <= #1 { WriteData[31:24] };
|
if(strb_lat[3]) mem[{laddr[31:3],3'd3}] = HWDATA[31:24];
|
||||||
mem[{Last_HADDR[12:3],3'b0}+2] <= #1 { WriteData[23:16] };
|
if(strb_lat[2]) mem[{laddr[31:3],3'd2}] = HWDATA[23:16];
|
||||||
mem[{Last_HADDR[12:3],3'b0}+1] <= #1 { WriteData[15:08] };
|
if(strb_lat[1]) mem[{laddr[31:3],3'd1}] = HWDATA[15:08];
|
||||||
mem[{Last_HADDR[12:3],3'b0}+0] <= #1 { WriteData[07:00] };
|
if(strb_lat[0]) mem[{laddr[31:3],3'd0}] = HWDATA[07:00];
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
assign HREADYOUT = 1;
|
||||||
|
assign HRESP = 0;
|
||||||
|
|
||||||
always @(posedge HCLK or negedge HRESETn) begin
|
always @(posedge HCLK or negedge HRESETn) begin
|
||||||
if(~HRESETn) begin
|
if(~HRESETn) begin
|
||||||
HREADYOUT <= #1 1'b0 ;
|
Last_HADDR <= 32'b0;
|
||||||
HRESP <= #1 1'b0;
|
Write <= 1'b0;
|
||||||
|
HRDATA <= '0;
|
||||||
end else begin
|
end else begin
|
||||||
HREADYOUT <= #1 |HTRANS;
|
Last_HADDR <= HADDR;
|
||||||
HRESP <= #1 1'b0;
|
Write <= HWRITE & |HTRANS;
|
||||||
WriteMask <= #1 Next_WriteMask;
|
if(|HTRANS & ~HWRITE)
|
||||||
end
|
HRDATA <= mem_dout;
|
||||||
end
|
strb_lat <= strb;
|
||||||
|
|
||||||
`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];
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
endmodule
|
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
|
||||||
|
|
|
@ -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
|
.global _start
|
||||||
_start:
|
_start:
|
||||||
csrrw x2, 0xb02, x3
|
|
||||||
|
|
||||||
|
// Clear minstret
|
||||||
lui x5, 974848
|
csrw minstret, zero
|
||||||
ori x5, x5, 0
|
csrw minstreth, zero
|
||||||
csrrw x2, 0x305, x5
|
|
||||||
|
|
||||||
|
|
||||||
lui x6, 382293
|
|
||||||
ori x6, x6, 1365
|
|
||||||
csrrw x1, 0x7c0, x6
|
|
||||||
|
|
||||||
|
// Set up MTVEC - not expecting to use it though
|
||||||
|
li x1, RV_ICCM_SADR
|
||||||
|
csrw mtvec, x1
|
||||||
lui x5, 0
|
|
||||||
ori x5, x5, 0
|
|
||||||
csrrw x2, 0x7f8, x5
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
lui x5, 0
|
|
||||||
ori x5, x5, 0
|
|
||||||
csrrw x2, 0x7f9, x5
|
|
||||||
|
|
||||||
|
|
||||||
addi x0, x0, 0
|
// Enable Caches in MRAC
|
||||||
lui x11, 853376
|
li x1, 0x5f555555
|
||||||
ori x9, x0, 'H'
|
csrw 0x7c0, x1
|
||||||
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
|
|
||||||
|
|
||||||
finish:
|
// Load string from hw_data
|
||||||
addi x1,x1,1
|
// and write to stdout address
|
||||||
jal x0, finish;
|
|
||||||
addi x0,x0,0
|
li x3, STDOUT
|
||||||
addi x0,x0,0
|
la x4, hw_data
|
||||||
addi x0,x0,0
|
|
||||||
addi x0,x0,0
|
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
|
||||||
|
|
|
@ -4,9 +4,9 @@ ENTRY(_start)
|
||||||
|
|
||||||
SECTIONS
|
SECTIONS
|
||||||
{
|
{
|
||||||
. = 0x1000;
|
. = 0;
|
||||||
.data . : { *(.*data) *(.rodata*) }
|
.text : { *(.text*) }
|
||||||
. = 0x0;
|
|
||||||
.text . : { *(.text) }
|
|
||||||
_end = .;
|
_end = .;
|
||||||
|
. = 0x10000;
|
||||||
|
.data : ALIGN(0x800) { *(.*data) *(.rodata*) STACK = ALIGN(16) + 0x8000; }
|
||||||
}
|
}
|
||||||
|
|
1211
testbench/tb_top.sv
1211
testbench/tb_top.sv
File diff suppressed because it is too large
Load Diff
|
@ -1,12 +1,12 @@
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
// Copyright 2019 Western Digital Corporation or its affiliates.
|
// Copyright 2019 Western Digital Corporation or its affiliates.
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "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 not use this file except in compliance with the License.
|
||||||
// You may obtain a copy of the License at
|
// You may obtain a copy of the License at
|
||||||
//
|
//
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
//
|
//
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
@ -22,62 +22,50 @@
|
||||||
#include "verilated_vcd_c.h"
|
#include "verilated_vcd_c.h"
|
||||||
|
|
||||||
|
|
||||||
// /*
|
|
||||||
vluint64_t main_time = 0;
|
vluint64_t main_time = 0;
|
||||||
|
|
||||||
double sc_time_stamp () {
|
double sc_time_stamp () {
|
||||||
return main_time;
|
return main_time;
|
||||||
}
|
}
|
||||||
// */
|
|
||||||
|
|
||||||
//int main(int argc, char* argv[]) {
|
|
||||||
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);
|
Verilated::commandArgs(argc, argv);
|
||||||
|
|
||||||
Vtb_top* tb = new Vtb_top;
|
Vtb_top* tb = new Vtb_top;
|
||||||
uint32_t clkCnt = 0;
|
|
||||||
|
|
||||||
// init trace dump
|
// init trace dump
|
||||||
Verilated::traceEverOn(true);
|
Verilated::traceEverOn(true);
|
||||||
VerilatedVcdC* tfp = new VerilatedVcdC;
|
VerilatedVcdC* tfp = new VerilatedVcdC;
|
||||||
tb->trace (tfp, 24);
|
tb->trace (tfp, 24);
|
||||||
tfp->open ("sim.vcd");
|
if (dumpWaves)
|
||||||
|
tfp->open ("sim.vcd");
|
||||||
|
|
||||||
|
|
||||||
// Simulate
|
// Simulate
|
||||||
for(auto i=0; i<200000; ++i){
|
while(!Verilated::gotFinish()){
|
||||||
clkCnt++;
|
if (dumpWaves)
|
||||||
if(i<10) {
|
tfp->dump (main_time);
|
||||||
tb->reset_l = 0;
|
main_time += 5;
|
||||||
} else {
|
|
||||||
tb->reset_l = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto clk=0; clk<2; clk++) {
|
|
||||||
tfp->dump (2*i+clk);
|
|
||||||
tb->core_clk = !tb->core_clk;
|
tb->core_clk = !tb->core_clk;
|
||||||
tb->eval();
|
tb->eval();
|
||||||
}
|
|
||||||
|
|
||||||
if (tb->finished) {
|
|
||||||
tfp->close();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for(auto i=0; i<100; ++i){
|
if (dumpWaves)
|
||||||
clkCnt++;
|
tfp->close();
|
||||||
for (auto clk=0; clk<2; clk++) {
|
|
||||||
tfp->dump (2*i+clk);
|
std::cout << "\nVerilatorTB: End of sim" << std::endl;
|
||||||
tb->core_clk = !tb->core_clk;
|
|
||||||
tb->eval();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::cout << "\nEnd of sim" << std::endl;
|
|
||||||
exit(EXIT_SUCCESS);
|
exit(EXIT_SUCCESS);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,8 +22,8 @@ my $XS_Version = '2.27';
|
||||||
# XS and PP common methods
|
# XS and PP common methods
|
||||||
|
|
||||||
my @PublicMethods = qw/
|
my @PublicMethods = qw/
|
||||||
ascii latin1 utf8 pretty indent space_before space_after relaxed canonical allow_nonref
|
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
|
allow_blessed convert_blessed filter_json_object filter_json_single_key_object
|
||||||
shrink max_depth max_size encode decode decode_prefix allow_unknown
|
shrink max_depth max_size encode decode decode_prefix allow_unknown
|
||||||
/;
|
/;
|
||||||
|
|
||||||
|
@ -48,7 +48,7 @@ my $_UNIV_CONV_BLESSED = 0;
|
||||||
my $_USSING_bpPP = 0;
|
my $_USSING_bpPP = 0;
|
||||||
|
|
||||||
|
|
||||||
# Check the environment variable to decide worker module.
|
# Check the environment variable to decide worker module.
|
||||||
|
|
||||||
unless ($JSON::Backend) {
|
unless ($JSON::Backend) {
|
||||||
$JSON::DEBUG and Carp::carp("Check used worker module...");
|
$JSON::DEBUG and Carp::carp("Check used worker module...");
|
||||||
|
@ -609,35 +609,35 @@ JSON - JSON (JavaScript Object Notation) encoder/decoder
|
||||||
=head1 SYNOPSIS
|
=head1 SYNOPSIS
|
||||||
|
|
||||||
use JSON; # imports encode_json, decode_json, to_json and from_json.
|
use JSON; # imports encode_json, decode_json, to_json and from_json.
|
||||||
|
|
||||||
# simple and fast interfaces (expect/generate UTF-8)
|
# simple and fast interfaces (expect/generate UTF-8)
|
||||||
|
|
||||||
$utf8_encoded_json_text = encode_json $perl_hash_or_arrayref;
|
$utf8_encoded_json_text = encode_json $perl_hash_or_arrayref;
|
||||||
$perl_hash_or_arrayref = decode_json $utf8_encoded_json_text;
|
$perl_hash_or_arrayref = decode_json $utf8_encoded_json_text;
|
||||||
|
|
||||||
# OO-interface
|
# OO-interface
|
||||||
|
|
||||||
$json = JSON->new->allow_nonref;
|
$json = JSON->new->allow_nonref;
|
||||||
|
|
||||||
$json_text = $json->encode( $perl_scalar );
|
$json_text = $json->encode( $perl_scalar );
|
||||||
$perl_scalar = $json->decode( $json_text );
|
$perl_scalar = $json->decode( $json_text );
|
||||||
|
|
||||||
$pretty_printed = $json->pretty->encode( $perl_scalar ); # pretty-printing
|
$pretty_printed = $json->pretty->encode( $perl_scalar ); # pretty-printing
|
||||||
|
|
||||||
# If you want to use PP only support features, call with '-support_by_pp'
|
# 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.
|
# When XS unsupported feature is enable, using PP (de|en)code instead of XS ones.
|
||||||
|
|
||||||
use JSON -support_by_pp;
|
use JSON -support_by_pp;
|
||||||
|
|
||||||
# option-acceptable interfaces (expect/generate UNICODE by default)
|
# option-acceptable interfaces (expect/generate UNICODE by default)
|
||||||
|
|
||||||
$json_text = to_json( $perl_scalar, { ascii => 1, pretty => 1 } );
|
$json_text = to_json( $perl_scalar, { ascii => 1, pretty => 1 } );
|
||||||
$perl_scalar = from_json( $json_text, { utf8 => 1 } );
|
$perl_scalar = from_json( $json_text, { utf8 => 1 } );
|
||||||
|
|
||||||
# Between (en|de)code_json and (to|from)_json, if you want to write
|
# 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),
|
# a code which communicates to an outer world (encoded in UTF-8),
|
||||||
# recommend to use (en|de)code_json.
|
# recommend to use (en|de)code_json.
|
||||||
|
|
||||||
=head1 VERSION
|
=head1 VERSION
|
||||||
|
|
||||||
2.53
|
2.53
|
||||||
|
@ -866,7 +866,7 @@ with C<utf8> enable. And the decoded result will contain UNICODE characters.
|
||||||
my $json = JSON->new->utf8;
|
my $json = JSON->new->utf8;
|
||||||
my $json_text = CGI->new->param( 'json_data' );
|
my $json_text = CGI->new->param( 'json_data' );
|
||||||
my $perl_scalar = $json->decode( $json_text );
|
my $perl_scalar = $json->decode( $json_text );
|
||||||
|
|
||||||
# from file content
|
# from file content
|
||||||
local $/;
|
local $/;
|
||||||
open( my $fh, '<', 'json.data' );
|
open( my $fh, '<', 'json.data' );
|
||||||
|
@ -880,7 +880,7 @@ If an outer data is not encoded in UTF-8, firstly you should C<decode> it.
|
||||||
open( my $fh, '<', 'json.data' );
|
open( my $fh, '<', 'json.data' );
|
||||||
my $encoding = 'cp932';
|
my $encoding = 'cp932';
|
||||||
my $unicode_json_text = decode( $encoding, <$fh> ); # UNICODE
|
my $unicode_json_text = decode( $encoding, <$fh> ); # UNICODE
|
||||||
|
|
||||||
# or you can write the below code.
|
# or you can write the below code.
|
||||||
#
|
#
|
||||||
# open( my $fh, "<:encoding($encoding)", 'json.data' );
|
# 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
|
# $perl_scalar contains $encoding encoded string values
|
||||||
$unicode_json_text = $json->utf8(0)->encode( $perl_scalar );
|
$unicode_json_text = $json->utf8(0)->encode( $perl_scalar );
|
||||||
# or
|
# or
|
||||||
$unicode_json_text = to_json( $perl_scalar );
|
$unicode_json_text = to_json( $perl_scalar );
|
||||||
# $unicode_json_text consists of characters less than 0x100
|
# $unicode_json_text consists of characters less than 0x100
|
||||||
print $unicode_json_text;
|
print $unicode_json_text;
|
||||||
|
@ -954,7 +954,7 @@ be chained:
|
||||||
=head2 ascii
|
=head2 ascii
|
||||||
|
|
||||||
$json = $json->ascii([$enable])
|
$json = $json->ascii([$enable])
|
||||||
|
|
||||||
$enabled = $json->get_ascii
|
$enabled = $json->get_ascii
|
||||||
|
|
||||||
If $enable is true (or missing), then the encode method will not generate characters outside
|
If $enable is true (or missing), then the encode method will not generate characters outside
|
||||||
|
@ -974,7 +974,7 @@ See to L<JSON::PP/UNICODE HANDLING ON PERLS> if the backend is PP.
|
||||||
=head2 latin1
|
=head2 latin1
|
||||||
|
|
||||||
$json = $json->latin1([$enable])
|
$json = $json->latin1([$enable])
|
||||||
|
|
||||||
$enabled = $json->get_latin1
|
$enabled = $json->get_latin1
|
||||||
|
|
||||||
If $enable is true (or missing), then the encode method will encode the resulting JSON
|
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
|
=head2 utf8
|
||||||
|
|
||||||
$json = $json->utf8([$enable])
|
$json = $json->utf8([$enable])
|
||||||
|
|
||||||
$enabled = $json->get_utf8
|
$enabled = $json->get_utf8
|
||||||
|
|
||||||
If $enable is true (or missing), then the encode method will encode the JSON result
|
If $enable is true (or missing), then the encode method will encode the JSON result
|
||||||
|
@ -1036,7 +1036,7 @@ space length.
|
||||||
=head2 indent
|
=head2 indent
|
||||||
|
|
||||||
$json = $json->indent([$enable])
|
$json = $json->indent([$enable])
|
||||||
|
|
||||||
$enabled = $json->get_indent
|
$enabled = $json->get_indent
|
||||||
|
|
||||||
If C<$enable> is true (or missing), then the C<encode> method will use a multiline
|
If C<$enable> is true (or missing), then the C<encode> method will use a multiline
|
||||||
|
@ -1055,7 +1055,7 @@ With JSON::PP, you can also access C<indent_length> to change indent space lengt
|
||||||
=head2 space_before
|
=head2 space_before
|
||||||
|
|
||||||
$json = $json->space_before([$enable])
|
$json = $json->space_before([$enable])
|
||||||
|
|
||||||
$enabled = $json->get_space_before
|
$enabled = $json->get_space_before
|
||||||
|
|
||||||
If C<$enable> is true (or missing), then the C<encode> method will add an extra
|
If C<$enable> is true (or missing), then the C<encode> method will add an extra
|
||||||
|
@ -1074,7 +1074,7 @@ Example, space_before enabled, space_after and indent disabled:
|
||||||
=head2 space_after
|
=head2 space_after
|
||||||
|
|
||||||
$json = $json->space_after([$enable])
|
$json = $json->space_after([$enable])
|
||||||
|
|
||||||
$enabled = $json->get_space_after
|
$enabled = $json->get_space_after
|
||||||
|
|
||||||
If C<$enable> is true (or missing), then the C<encode> method will add an extra
|
If C<$enable> is true (or missing), then the C<encode> method will add an extra
|
||||||
|
@ -1095,7 +1095,7 @@ Example, space_before and indent disabled, space_after enabled:
|
||||||
=head2 relaxed
|
=head2 relaxed
|
||||||
|
|
||||||
$json = $json->relaxed([$enable])
|
$json = $json->relaxed([$enable])
|
||||||
|
|
||||||
$enabled = $json->get_relaxed
|
$enabled = $json->get_relaxed
|
||||||
|
|
||||||
If C<$enable> is true (or missing), then C<decode> will accept some
|
If C<$enable> is true (or missing), then C<decode> will accept some
|
||||||
|
@ -1145,7 +1145,7 @@ character, after which more white-space and comments are allowed.
|
||||||
=head2 canonical
|
=head2 canonical
|
||||||
|
|
||||||
$json = $json->canonical([$enable])
|
$json = $json->canonical([$enable])
|
||||||
|
|
||||||
$enabled = $json->get_canonical
|
$enabled = $json->get_canonical
|
||||||
|
|
||||||
If C<$enable> is true (or missing), then the C<encode> method will output JSON objects
|
If C<$enable> is true (or missing), then the C<encode> method will output JSON objects
|
||||||
|
@ -1165,7 +1165,7 @@ This setting has no effect when decoding JSON texts.
|
||||||
=head2 allow_nonref
|
=head2 allow_nonref
|
||||||
|
|
||||||
$json = $json->allow_nonref([$enable])
|
$json = $json->allow_nonref([$enable])
|
||||||
|
|
||||||
$enabled = $json->get_allow_nonref
|
$enabled = $json->get_allow_nonref
|
||||||
|
|
||||||
If C<$enable> is true (or missing), then the C<encode> method can convert a
|
If C<$enable> is true (or missing), then the C<encode> method can convert a
|
||||||
|
@ -1184,7 +1184,7 @@ JSON object or array.
|
||||||
=head2 allow_unknown
|
=head2 allow_unknown
|
||||||
|
|
||||||
$json = $json->allow_unknown ([$enable])
|
$json = $json->allow_unknown ([$enable])
|
||||||
|
|
||||||
$enabled = $json->get_allow_unknown
|
$enabled = $json->get_allow_unknown
|
||||||
|
|
||||||
If $enable is true (or missing), then "encode" will *not* throw an
|
If $enable is true (or missing), then "encode" will *not* throw an
|
||||||
|
@ -1203,7 +1203,7 @@ partner.
|
||||||
=head2 allow_blessed
|
=head2 allow_blessed
|
||||||
|
|
||||||
$json = $json->allow_blessed([$enable])
|
$json = $json->allow_blessed([$enable])
|
||||||
|
|
||||||
$enabled = $json->get_allow_blessed
|
$enabled = $json->get_allow_blessed
|
||||||
|
|
||||||
If C<$enable> is true (or missing), then the C<encode> method will not
|
If C<$enable> is true (or missing), then the C<encode> method will not
|
||||||
|
@ -1220,7 +1220,7 @@ exception when it encounters a blessed object.
|
||||||
=head2 convert_blessed
|
=head2 convert_blessed
|
||||||
|
|
||||||
$json = $json->convert_blessed([$enable])
|
$json = $json->convert_blessed([$enable])
|
||||||
|
|
||||||
$enabled = $json->get_convert_blessed
|
$enabled = $json->get_convert_blessed
|
||||||
|
|
||||||
If C<$enable> is true (or missing), then C<encode>, upon encountering a
|
If C<$enable> is true (or missing), then C<encode>, upon encountering a
|
||||||
|
@ -1353,7 +1353,7 @@ into the corresponding C<< $WIDGET{<id>} >> object:
|
||||||
=head2 shrink
|
=head2 shrink
|
||||||
|
|
||||||
$json = $json->shrink([$enable])
|
$json = $json->shrink([$enable])
|
||||||
|
|
||||||
$enabled = $json->get_shrink
|
$enabled = $json->get_shrink
|
||||||
|
|
||||||
With JSON::XS, this flag resizes strings generated by either
|
With JSON::XS, this flag resizes strings generated by either
|
||||||
|
@ -1373,7 +1373,7 @@ See to L<JSON::XS/OBJECT-ORIENTED INTERFACE> and L<JSON::PP/METHODS>.
|
||||||
=head2 max_depth
|
=head2 max_depth
|
||||||
|
|
||||||
$json = $json->max_depth([$maximum_nesting_depth])
|
$json = $json->max_depth([$maximum_nesting_depth])
|
||||||
|
|
||||||
$max_depth = $json->get_max_depth
|
$max_depth = $json->get_max_depth
|
||||||
|
|
||||||
Sets the maximum nesting level (default C<512>) accepted while encoding
|
Sets the maximum nesting level (default C<512>) accepted while encoding
|
||||||
|
@ -1402,7 +1402,7 @@ See L<JSON::XS/SECURITY CONSIDERATIONS> for more info on why this is useful.
|
||||||
=head2 max_size
|
=head2 max_size
|
||||||
|
|
||||||
$json = $json->max_size([$maximum_string_size])
|
$json = $json->max_size([$maximum_string_size])
|
||||||
|
|
||||||
$max_size = $json->get_max_size
|
$max_size = $json->get_max_size
|
||||||
|
|
||||||
Set the maximum length a JSON text may have (in bytes) where decoding is
|
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
|
=head2 incr_parse
|
||||||
|
|
||||||
$json->incr_parse( [$string] ) # void context
|
$json->incr_parse( [$string] ) # void context
|
||||||
|
|
||||||
$obj_or_undef = $json->incr_parse( [$string] ) # scalar context
|
$obj_or_undef = $json->incr_parse( [$string] ) # scalar context
|
||||||
|
|
||||||
@obj_or_empty = $json->incr_parse( [$string] ) # list context
|
@obj_or_empty = $json->incr_parse( [$string] ) # list context
|
||||||
|
|
||||||
This is the central parsing function. It can both append new text and
|
This is the central parsing function. It can both append new text and
|
||||||
|
@ -1596,9 +1596,9 @@ If you use C<JSON> with additonal C<-support_by_pp>, some methods
|
||||||
are available even with JSON::XS. See to L<USE PP FEATURES EVEN THOUGH XS BACKEND>.
|
are available even with JSON::XS. See to L<USE PP FEATURES EVEN THOUGH XS BACKEND>.
|
||||||
|
|
||||||
BEING { $ENV{PERL_JSON_BACKEND} = 'JSON::XS' }
|
BEING { $ENV{PERL_JSON_BACKEND} = 'JSON::XS' }
|
||||||
|
|
||||||
use JSON -support_by_pp;
|
use JSON -support_by_pp;
|
||||||
|
|
||||||
my $json = new JSON;
|
my $json = new JSON;
|
||||||
$json->allow_nonref->escape_slash->encode("/");
|
$json->allow_nonref->escape_slash->encode("/");
|
||||||
|
|
||||||
|
@ -1762,7 +1762,7 @@ represent most decimal fractions exactly, and when converting from and to
|
||||||
floating point, C<JSON> only guarantees precision up to but not including
|
floating point, C<JSON> only guarantees precision up to but not including
|
||||||
the leats significant bit.
|
the leats significant bit.
|
||||||
|
|
||||||
If the backend is JSON::PP and C<allow_bignum> is enable, the big integers
|
If the backend is JSON::PP and C<allow_bignum> is enable, the big integers
|
||||||
and the numeric can be optionally converted into L<Math::BigInt> and
|
and the numeric can be optionally converted into L<Math::BigInt> and
|
||||||
L<Math::BigFloat> objects.
|
L<Math::BigFloat> objects.
|
||||||
|
|
||||||
|
@ -1900,7 +1900,7 @@ error to pass those in.
|
||||||
|
|
||||||
=item Big Number
|
=item Big Number
|
||||||
|
|
||||||
If the backend is JSON::PP and C<allow_bignum> is enable,
|
If the backend is JSON::PP and C<allow_bignum> is enable,
|
||||||
C<encode> converts C<Math::BigInt> objects and C<Math::BigFloat>
|
C<encode> converts C<Math::BigInt> objects and C<Math::BigFloat>
|
||||||
objects into JSON numbers.
|
objects into JSON numbers.
|
||||||
|
|
||||||
|
@ -1935,13 +1935,13 @@ returned objects should not be modified.
|
||||||
To check the backend module, there are some methods - C<backend>, C<is_pp> and C<is_xs>.
|
To check the backend module, there are some methods - C<backend>, C<is_pp> and C<is_xs>.
|
||||||
|
|
||||||
JSON->backend; # 'JSON::XS' or 'JSON::PP'
|
JSON->backend; # 'JSON::XS' or 'JSON::PP'
|
||||||
|
|
||||||
JSON->backend->is_pp: # 0 or 1
|
JSON->backend->is_pp: # 0 or 1
|
||||||
|
|
||||||
JSON->backend->is_xs: # 1 or 0
|
JSON->backend->is_xs: # 1 or 0
|
||||||
|
|
||||||
$json->is_xs; # 1 or 0
|
$json->is_xs; # 1 or 0
|
||||||
|
|
||||||
$json->is_pp; # 0 or 1
|
$json->is_pp; # 0 or 1
|
||||||
|
|
||||||
|
|
||||||
|
@ -2164,7 +2164,7 @@ If you want to use with your own sort routine, check the C<sort_by> method.
|
||||||
(Only with JSON::PP, even if C<-support_by_pp> is used currently.)
|
(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($sort_routine_ref)->encode($perl_scalar)
|
||||||
|
|
||||||
$json->sort_by(sub { $JSON::PP::a <=> $JSON::PP::b })->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>.
|
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
|
Copyright 2005-2011 by Makamaka Hannyaharamitu
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or modify
|
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
|
=cut
|
||||||
|
|
||||||
|
|
184
tools/Makefile
184
tools/Makefile
|
@ -1,12 +1,12 @@
|
||||||
# SPDX-License-Identifier: Apache-2.0
|
# 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");
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
# you may not use this file except in compliance with the License.
|
# you may not use this file except in compliance with the License.
|
||||||
# You may obtain a copy of the License at
|
# You may obtain a copy of the License at
|
||||||
#
|
#
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
#
|
#
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
# 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
|
endif
|
||||||
|
|
||||||
# Allow snapshot override
|
# Allow snapshot override
|
||||||
ifeq ($(strip $(snapshot)),)
|
target = default
|
||||||
snapshot = default
|
snapshot = $(target)
|
||||||
endif
|
|
||||||
|
|
||||||
# Allow tool override
|
# Allow tool override
|
||||||
SWERV_CONFIG = ${RV_ROOT}/configs/swerv.config
|
SWERV_CONFIG = ${RV_ROOT}/configs/swerv.config
|
||||||
IRUN = irun
|
IRUN = irun
|
||||||
VCS = vcs
|
VCS = vcs
|
||||||
VERILATOR = verilator
|
VERILATOR = verilator
|
||||||
|
VLOG = qverilog
|
||||||
GCC_PREFIX = riscv64-unknown-elf
|
GCC_PREFIX = riscv64-unknown-elf
|
||||||
|
BUILD_DIR = snapshots/${snapshot}
|
||||||
|
TBDIR = ${RV_ROOT}/testbench
|
||||||
|
|
||||||
# Define test name
|
# Define default test name
|
||||||
ifeq ($(strip $(ASM_TEST)),)
|
TEST = hello_world
|
||||||
ASM_TEST = hello_world2
|
|
||||||
|
# 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
|
endif
|
||||||
|
|
||||||
# Define test name
|
# provide specific link file
|
||||||
ifeq ($(strip $(ASM_TEST_DIR)),)
|
ifeq (,$(wildcard $(TEST_DIR)/$(TEST).ld))
|
||||||
ASM_TEST_DIR = ${RV_ROOT}/testbench/asm
|
LINK = $(TBDIR)/link.ld
|
||||||
|
else
|
||||||
|
LINK = $(TEST_DIR)/$(TEST).ld
|
||||||
endif
|
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
|
VPATH = $(TEST_DIR) $(BUILD_DIR) $(TBDIR)
|
||||||
includes = -I${RV_ROOT}/design/include -I${RV_ROOT}/design/lib -I${RV_ROOT}/design/dmi -I${RV_ROOT}/configs/snapshots/$(snapshot)
|
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 for verilator generated Makefiles. Without -std=c++11 it complains for `auto` variables
|
||||||
CFLAGS += "-std=c++11"
|
CFLAGS += "-std=c++11"
|
||||||
# Optimization for better performance; alternative is nothing for slower runtime (faster compiles)
|
# Optimization for better performance; alternative is nothing for slower runtime (faster compiles)
|
||||||
# -O2 for faster runtime (slower compiles), or -O for balance.
|
# -O2 for faster runtime (slower compiles), or -O for balance.
|
||||||
VERILATOR_MAKE_FLAGS = OPT_FAST=""
|
VERILATOR_MAKE_FLAGS = OPT_FAST="-O2"
|
||||||
|
|
||||||
# Targets
|
# Targets
|
||||||
all: clean verilator
|
all: clean verilator
|
||||||
|
|
||||||
clean:
|
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
|
# If define files do not exist, then run swerv.config.
|
||||||
echo '`undef ASSERT_ON' >> ${RV_ROOT}/configs/snapshots/$(snapshot)/common_defines.vh
|
${BUILD_DIR}/defines.h :
|
||||||
$(VERILATOR) '-UASSERT_ON' --cc -CFLAGS ${CFLAGS} $(defines) $(includes) ${RV_ROOT}/configs/snapshots/$(snapshot)/common_defines.vh \
|
BUILD_PATH=${BUILD_DIR} ${SWERV_CONFIG} -target=$(target) $(CONF_PARAMS)
|
||||||
-f ${RV_ROOT}/testbench/flist.verilator --top-module swerv_wrapper
|
|
||||||
$(MAKE) -C obj_dir/ -f Vswerv_wrapper.mk $(VERILATOR_MAKE_FLAGS)
|
|
||||||
|
|
||||||
vcs: ${RV_ROOT}/configs/snapshots/$(snapshot)/common_defines.vh
|
verilator-build: ${TBFILES} ${BUILD_DIR}/defines.h test_tb_top.cpp
|
||||||
$(VCS) -full64 -assert svaext -sverilog +define+RV_OPENSOURCE +error+500 +incdir+${RV_ROOT}/design/lib +incdir+${RV_ROOT}/design/include \
|
echo '`undef ASSERT_ON' >> ${BUILD_DIR}/common_defines.vh
|
||||||
${RV_ROOT}/configs/snapshots/$(snapshot)/common_defines.vh \
|
$(VERILATOR) '-UASSERT_ON' --cc -CFLAGS ${CFLAGS} $(defines) $(includes) \
|
||||||
+incdir+${RV_ROOT}/design/dmi +incdir+${RV_ROOT}/configs/snapshots/$(snapshot) +libext+.v ${RV_ROOT}/configs/snapshots/$(snapshot)/common_defines.vh \
|
-Wno-UNOPTFLAT \
|
||||||
$(defines)-f ${RV_ROOT}/testbench/flist.vcs -l vcs.log
|
-I${RV_ROOT}/testbench \
|
||||||
|
-f ${RV_ROOT}/testbench/flist \
|
||||||
irun: ${RV_ROOT}/configs/snapshots/$(snapshot)/common_defines.vh
|
${TBFILES} \
|
||||||
$(IRUN) -64bit -elaborate -ida -access +rw -q -sv -sysv -nowarn CUVIHR -nclibdirpath ${PWD} -nclibdirname swerv.build \
|
--top-module tb_top -exe test_tb_top.cpp --trace --autoflush
|
||||||
-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
|
|
||||||
cp ${RV_ROOT}/testbench/test_tb_top.cpp obj_dir/
|
cp ${RV_ROOT}/testbench/test_tb_top.cpp obj_dir/
|
||||||
$(MAKE) -C obj_dir/ -f Vtb_top.mk $(VERILATOR_MAKE_FLAGS)
|
$(MAKE) -C obj_dir/ -f Vtb_top.mk $(VERILATOR_MAKE_FLAGS)
|
||||||
./obj_dir/Vtb_top
|
touch verilator-build
|
||||||
|
|
||||||
irun-run: program.hex
|
vcs-build: ${TBFILES} ${BUILD_DIR}/defines.h
|
||||||
snapshot=ahb_lite
|
$(VCS) -full64 -assert svaext -sverilog +error+500 \
|
||||||
$(SWERV_CONFIG) -snapshot=$(snapshot) -ahb_lite
|
+incdir+${RV_ROOT}/design/lib \
|
||||||
$(IRUN) -64bit -ida -access +rw -q -sv -sysv -nowarn CUVIHR -nclibdirpath ${PWD} -nclibdirname swerv.build \
|
+incdir+${RV_ROOT}/design/include \
|
||||||
-incdir ${RV_ROOT}/design/lib -incdir ${RV_ROOT}/design/include -incdir ${RV_ROOT}/design/dmi -vlog_ext +.vh+.h\
|
+incdir+${BUILD_DIR} +libext+.v\
|
||||||
$(defines) -top tb_top ${RV_ROOT}/testbench/tb_top.sv -I${RV_ROOT}/testbench ${RV_ROOT}/testbench/ahb_sif.sv\
|
$(defines) -f ${RV_ROOT}/testbench/flist\
|
||||||
-incdir ${RV_ROOT}/configs/snapshots/$(snapshot) -f ${RV_ROOT}/testbench/flist.vcs -snapshot default
|
${TBFILES} \
|
||||||
|
-l vcs_compile.log
|
||||||
|
touch vcs-build
|
||||||
|
|
||||||
vcs-run: program.hex
|
irun-build: ${TBFILES} ${BUILD_DIR}/defines.h
|
||||||
snapshot=ahb_lite
|
$(IRUN) -64bit -elaborate $(IRUN_DEBUG) -q -sv -sysv -nowarn CUVIHR -nclibdirpath . -nclibdirname swerv.build \
|
||||||
$(SWERV_CONFIG) -snapshot=$(snapshot) -ahb_lite
|
-incdir ${RV_ROOT}/design/lib -incdir ${RV_ROOT}/design/include -incdir ${BUILD_DIR} -vlog_ext +.vh+.h\
|
||||||
cp ${RV_ROOT}/testbench/hex/*.hex .
|
$(defines) -f ${RV_ROOT}/testbench/flist\
|
||||||
$(VCS) -full64 -assert svaext -sverilog +define+RV_OPENSOURCE +error+500 +incdir+${RV_ROOT}/design/lib +incdir+${RV_ROOT}/design/include \
|
-top tb_top ${TBFILES} -I${RV_ROOT}/testbench \
|
||||||
${RV_ROOT}/configs/snapshots/$(snapshot)/common_defines.vh \
|
-elaborate -snapshot $(snapshot)
|
||||||
+incdir+${RV_ROOT}/design/dmi +incdir+${RV_ROOT}/configs/snapshots/$(snapshot) +libext+.v \
|
touch irun-build
|
||||||
$(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
|
|
||||||
|
|
||||||
program.hex: $(ASM_TEST_DIR)/$(ASM_TEST).s ${RV_ROOT}/configs/snapshots/$(snapshot)/common_defines.vh
|
verilator: program.hex verilator-build
|
||||||
@echo Building $(ASM_TEST)
|
./obj_dir/Vtb_top ${DEBUG_PLUS}
|
||||||
ifeq ($(shell which $(GCC_PREFIX)-as),)
|
|
||||||
@echo " !!! No $(GCC_PREFIX)-as in path, using canned hex files !!"
|
irun: program.hex irun-build
|
||||||
cp ${RV_ROOT}/testbench/hex/*.hex .
|
$(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
|
else
|
||||||
cp $(ASM_TEST_DIR)/$(ASM_TEST).s .
|
ifneq (,$(wildcard $(TEST_DIR)/$(TEST).makefile))
|
||||||
$(GCC_PREFIX)-cpp -I${RV_ROOT}/configs/snapshots/$(snapshot) $(ASM_TEST).s > $(ASM_TEST).cpp.s
|
program.hex:
|
||||||
$(GCC_PREFIX)-as -march=rv32imc $(ASM_TEST).cpp.s -o $(ASM_TEST).o
|
$(MAKE) -f $(TEST_DIR)/$(TEST).makefile
|
||||||
$(GCC_PREFIX)-ld -m elf32lriscv --discard-none -T${RV_ROOT}/testbench/link.ld -o $(ASM_TEST).exe $(ASM_TEST).o
|
else
|
||||||
$(GCC_PREFIX)-objcopy -O verilog --only-section ".data*" --only-section ".rodata*" $(ASM_TEST).exe data.hex
|
program.hex: $(TEST).o $(LINK)
|
||||||
$(GCC_PREFIX)-objcopy -O verilog --only-section ".text*" --set-start=0x0 $(ASM_TEST).exe program.hex
|
@echo Building $(TEST)
|
||||||
$(GCC_PREFIX)-objdump -dS $(ASM_TEST).exe > $(ASM_TEST).dis
|
$(GCC_PREFIX)-ld -m elf32lriscv --discard-none -T$(LINK) -o $(TEST).exe $(TEST).o
|
||||||
$(GCC_PREFIX)-nm -f posix -C $(ASM_TEST).exe > $(ASM_TEST).tbl
|
$(GCC_PREFIX)-objcopy -O verilog --only-section ".data*" --change-section-lma .data=0 $(TEST).exe data.hex
|
||||||
@echo Completed building $(ASM_TEST)
|
$(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
|
||||||
|
endif
|
||||||
|
|
||||||
help:
|
help:
|
||||||
@echo Make sure the environment variable RV_ROOT is set.
|
@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
|
||||||
|
|
|
@ -16,26 +16,26 @@ foreach $line (@in) {
|
||||||
|
|
||||||
if ($line=~/\#/) { next; }
|
if ($line=~/\#/) { next; }
|
||||||
|
|
||||||
if ($line=~/([^=]+)=/) {
|
if ($line=~/([^=]+)=/) {
|
||||||
$sig=$1;
|
$sig=$1;
|
||||||
$sig=~s/\s+//g;
|
$sig=~s/\s+//g;
|
||||||
printf("logic $sig;\n");
|
printf("logic $sig;\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach $line (@in) {
|
foreach $line (@in) {
|
||||||
|
|
||||||
if ($line=~/\#/) { next; }
|
if ($line=~/\#/) { next; }
|
||||||
|
|
||||||
if ($line=~/([^=]+)=\s*;/) {
|
if ($line=~/([^=]+)=\s*;/) {
|
||||||
printf("assign ${prefix}$1 = 1'b0;\n");
|
printf("assign ${prefix}$1 = 1'b0;\n");
|
||||||
next;
|
next;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($line=~/([^=]+)=\s*\(\s*\);/) {
|
if ($line=~/([^=]+)=\s*\(\s*\);/) {
|
||||||
printf("assign ${prefix}$1 = 1'b0;\n");
|
printf("assign ${prefix}$1 = 1'b0;\n");
|
||||||
next;
|
next;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($line =~ /=/) { printf("assign ${prefix}$line"); }
|
if ($line =~ /=/) { printf("assign ${prefix}$line"); }
|
||||||
else { printf("$line"); }
|
else { printf("$line"); }
|
||||||
|
|
146
tools/coredecode
146
tools/coredecode
|
@ -5,9 +5,9 @@ use Getopt::Long;
|
||||||
$helpusage = "placeholder";
|
$helpusage = "placeholder";
|
||||||
|
|
||||||
GetOptions ('legal' => \$legal,
|
GetOptions ('legal' => \$legal,
|
||||||
'in=s' => \$in,
|
'in=s' => \$in,
|
||||||
'out=s' => \$out,
|
'out=s' => \$out,
|
||||||
'view=s' => \$view ) || die("$helpusage");
|
'view=s' => \$view ) || die("$helpusage");
|
||||||
|
|
||||||
|
|
||||||
if (!defined($in)) { die("must define -in=input"); }
|
if (!defined($in)) { die("must define -in=input"); }
|
||||||
|
@ -31,96 +31,96 @@ foreach $line (@in) {
|
||||||
|
|
||||||
#printf("$pstate: $line");
|
#printf("$pstate: $line");
|
||||||
|
|
||||||
if ($line=~/^\s*\#/) { #printf("skip $line");
|
if ($line=~/^\s*\#/) { #printf("skip $line");
|
||||||
next; }
|
next; }
|
||||||
|
|
||||||
if ($gather==1) {
|
if ($gather==1) {
|
||||||
if ($line=~/(\S+)/) {
|
if ($line=~/(\S+)/) {
|
||||||
if ($line=~/}/) { $gather=0; $position=0; next; }
|
if ($line=~/}/) { $gather=0; $position=0; next; }
|
||||||
$label=$1;
|
$label=$1;
|
||||||
$label=~s/,//g;
|
$label=~s/,//g;
|
||||||
if ($pstate==2) {
|
if ($pstate==2) {
|
||||||
if (defined($INPUT{$CVIEW}{$label})) { die("input $label already defined"); }
|
if (defined($INPUT{$CVIEW}{$label})) { die("input $label already defined"); }
|
||||||
$INPUT{$CVIEW}{$label}=$position++;
|
$INPUT{$CVIEW}{$label}=$position++;
|
||||||
$INPUTLEN{$CVIEW}++;
|
$INPUTLEN{$CVIEW}++;
|
||||||
$INPUTSTR{$CVIEW}.=" $label";
|
$INPUTSTR{$CVIEW}.=" $label";
|
||||||
}
|
}
|
||||||
elsif ($pstate==3) {
|
elsif ($pstate==3) {
|
||||||
if (defined($OUTPUT{$CVIEW}{$label})) { die("output $label already defined"); }
|
if (defined($OUTPUT{$CVIEW}{$label})) { die("output $label already defined"); }
|
||||||
$OUTPUT{$CVIEW}{$label}=$position++;
|
$OUTPUT{$CVIEW}{$label}=$position++;
|
||||||
$OUTPUTLEN{$CVIEW}++;
|
$OUTPUTLEN{$CVIEW}++;
|
||||||
$OUTPUTSTR{$CVIEW}.=" $label";
|
$OUTPUTSTR{$CVIEW}.=" $label";
|
||||||
}
|
}
|
||||||
else { die("unknown pstate $pstate in gather"); }
|
else { die("unknown pstate $pstate in gather"); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($line=~/^.definition/) {
|
if ($line=~/^.definition/) {
|
||||||
$pstate=1; next;
|
$pstate=1; next;
|
||||||
}
|
}
|
||||||
if ($pstate==1) { # definition
|
if ($pstate==1) { # definition
|
||||||
if ($line!~/^.output/) {
|
if ($line!~/^.output/) {
|
||||||
if ($line=~/(\S+)\s*=\s*(\S+)/) {
|
if ($line=~/(\S+)\s*=\s*(\S+)/) {
|
||||||
$key=$1; $value=$2;
|
$key=$1; $value=$2;
|
||||||
$value=~s/\./-/g;
|
$value=~s/\./-/g;
|
||||||
$value=~s/\[//g;
|
$value=~s/\[//g;
|
||||||
$value=~s/\]//g;
|
$value=~s/\]//g;
|
||||||
$DEFINITION{$key}=$value;
|
$DEFINITION{$key}=$value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else { $pstate=2; next; }
|
else { $pstate=2; next; }
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($line=~/^.input/) {
|
if ($line=~/^.input/) {
|
||||||
$pstate=2; next;
|
$pstate=2; next;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($pstate==2) { # input
|
if ($pstate==2) { # input
|
||||||
if ($line=~/(\S+)\s*=\s*\{/) {
|
if ($line=~/(\S+)\s*=\s*\{/) {
|
||||||
$CVIEW=$1; $gather=1; next;
|
$CVIEW=$1; $gather=1; next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($line=~/^.output/) {
|
if ($line=~/^.output/) {
|
||||||
$pstate=3; next;
|
$pstate=3; next;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($pstate==3) { # output
|
if ($pstate==3) { # output
|
||||||
if ($line=~/(\S+)\s*=\s*\{/) {
|
if ($line=~/(\S+)\s*=\s*\{/) {
|
||||||
$CVIEW=$1; $gather=1; next;
|
$CVIEW=$1; $gather=1; next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($line=~/^.decode/) {
|
if ($line=~/^.decode/) {
|
||||||
$pstate=4; next;
|
$pstate=4; next;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($pstate==4) { # decode
|
if ($pstate==4) { # decode
|
||||||
if ($line=~/([^\[]+)\[([^\]]+)\]\s+=\s+\{([^\}]+)\}/) {
|
if ($line=~/([^\[]+)\[([^\]]+)\]\s+=\s+\{([^\}]+)\}/) {
|
||||||
$dview=$1; $inst=$2; $body=$3;
|
$dview=$1; $inst=$2; $body=$3;
|
||||||
$dview=~s/\s+//g;
|
$dview=~s/\s+//g;
|
||||||
$inst=~s/\s+//g;
|
$inst=~s/\s+//g;
|
||||||
#printf("$dview $inst $body\n");
|
#printf("$dview $inst $body\n");
|
||||||
if ($inst=~/([^\{]+)\{([^-]+)-([^\}]+)\}/) {
|
if ($inst=~/([^\{]+)\{([^-]+)-([^\}]+)\}/) {
|
||||||
$base=$1; $lo=$2; $hi=$3;
|
$base=$1; $lo=$2; $hi=$3;
|
||||||
$hi++;
|
$hi++;
|
||||||
for ($i=0; $i<$TIMEOUT && $lo ne $hi; $i++) {
|
for ($i=0; $i<$TIMEOUT && $lo ne $hi; $i++) {
|
||||||
#printf("decode $dview $base$lo\n");
|
#printf("decode $dview $base$lo\n");
|
||||||
|
|
||||||
$expand=$base.$lo;
|
$expand=$base.$lo;
|
||||||
if (!defined($DEFINITION{$expand})) { die("could not find instruction definition for inst $expand"); }
|
if (!defined($DEFINITION{$expand})) { die("could not find instruction definition for inst $expand"); }
|
||||||
|
|
||||||
$DECODE{$dview}{$expand}=$body;
|
$DECODE{$dview}{$expand}=$body;
|
||||||
$lo++;
|
$lo++;
|
||||||
}
|
}
|
||||||
if ($i == $TIMEOUT) { die("timeout in decode expansion"); }
|
if ($i == $TIMEOUT) { die("timeout in decode expansion"); }
|
||||||
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (!defined($DEFINITION{$inst})) { die("could not find instruction definition for inst $inst"); }
|
if (!defined($DEFINITION{$inst})) { die("could not find instruction definition for inst $inst"); }
|
||||||
$DECODE{$dview}{$inst}=$body;
|
$DECODE{$dview}{$inst}=$body;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -160,25 +160,25 @@ else {
|
||||||
$DEFAULT_TEMPLATE='0'x$OUTPUTLEN{$view};
|
$DEFAULT_TEMPLATE='0'x$OUTPUTLEN{$view};
|
||||||
|
|
||||||
foreach $inst (sort keys %{ $DECODE{$view} }) {
|
foreach $inst (sort keys %{ $DECODE{$view} }) {
|
||||||
|
|
||||||
$body=$DECODE{$view}{$inst};
|
$body=$DECODE{$view}{$inst};
|
||||||
@sigs=split(' ',$body);
|
@sigs=split(' ',$body);
|
||||||
|
|
||||||
$template=$DEFAULT_TEMPLATE;
|
$template=$DEFAULT_TEMPLATE;
|
||||||
foreach $sig (@sigs) {
|
foreach $sig (@sigs) {
|
||||||
if (!defined($OUTPUT{$view}{$sig})) { die("could not find output definition for sig $sig in view $view"); }
|
if (!defined($OUTPUT{$view}{$sig})) { die("could not find output definition for sig $sig in view $view"); }
|
||||||
$position=$OUTPUT{$view}{$sig};
|
$position=$OUTPUT{$view}{$sig};
|
||||||
substr($template,$position,1,1);
|
substr($template,$position,1,1);
|
||||||
}
|
}
|
||||||
|
|
||||||
# if (!defined($DEFINITION{$inst})) { die("could not find instruction defintion for inst $inst"); }
|
# if (!defined($DEFINITION{$inst})) { die("could not find instruction defintion for inst $inst"); }
|
||||||
|
|
||||||
printf("# $inst\n");
|
printf("# $inst\n");
|
||||||
if (defined($legal)) {
|
if (defined($legal)) {
|
||||||
printf("$DEFINITION{$inst} 1\n");
|
printf("$DEFINITION{$inst} 1\n");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
printf("$DEFINITION{$inst} $template\n");
|
printf("$DEFINITION{$inst} $template\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
10
tools/picmap
10
tools/picmap
|
@ -35,9 +35,9 @@ printf("end\n");
|
||||||
|
|
||||||
sub b2d {
|
sub b2d {
|
||||||
my ($v) = @_;
|
my ($v) = @_;
|
||||||
|
|
||||||
$v = oct("0b" . $v);
|
$v = oct("0b" . $v);
|
||||||
|
|
||||||
return($v);
|
return($v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,11 +48,11 @@ sub d2b {
|
||||||
|
|
||||||
$v = sprintf "%b",$v;
|
$v = sprintf "%b",$v;
|
||||||
if (length($v)<$LEN) {
|
if (length($v)<$LEN) {
|
||||||
$repeat=$LEN-length($v);
|
$repeat=$LEN-length($v);
|
||||||
$v="0"x$repeat.$v;
|
$v="0"x$repeat.$v;
|
||||||
}
|
}
|
||||||
elsif (length($v)>$LEN) {
|
elsif (length($v)>$LEN) {
|
||||||
$v=substr($v,length($v)-$LEN,$LEN);
|
$v=substr($v,length($v)-$LEN,$LEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
return($v);
|
return($v);
|
||||||
|
|
|
@ -8,7 +8,7 @@ $helpusage = "placeholder";
|
||||||
|
|
||||||
GetOptions ('len=s' => \$len,
|
GetOptions ('len=s' => \$len,
|
||||||
'num=s' => \$num,
|
'num=s' => \$num,
|
||||||
'den=s' => \$den,
|
'den=s' => \$den,
|
||||||
'skip' => \$skip) || die("$helpusage");
|
'skip' => \$skip) || die("$helpusage");
|
||||||
|
|
||||||
if (!defined($len)) { $len=8; }
|
if (!defined($len)) { $len=8; }
|
||||||
|
@ -25,9 +25,9 @@ printf(".ob smallnum[3] smallnum[2] smallnum[1] smallnum[0]\n");
|
||||||
printf(".type fr\n");
|
printf(".type fr\n");
|
||||||
for ($q=0; $q<16; $q++) {
|
for ($q=0; $q<16; $q++) {
|
||||||
for ($m=0; $m<16; $m++) {
|
for ($m=0; $m<16; $m++) {
|
||||||
if ($m==0) { next; }
|
if ($m==0) { next; }
|
||||||
$result=int($q/$m);
|
$result=int($q/$m);
|
||||||
printf("%s %s %s\n",d2bl($q,4),d2bl($m,4),d2bl($result,4));
|
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);
|
$signa = substr($a,0,1);
|
||||||
|
|
||||||
|
|
||||||
$a = substr($a.$q,1,$LEN); # new a with q shifted in
|
$a = substr($a.$q,1,$LEN); # new a with q shifted in
|
||||||
|
|
||||||
if ($signa==0) { $a=b2d($a)-b2d($m); }
|
if ($signa==0) { $a=b2d($a)-b2d($m); }
|
||||||
else { $a=b2d($a)+b2d($m); }
|
else { $a=b2d($a)+b2d($m); }
|
||||||
|
|
||||||
$a=d2b($a);
|
$a=d2b($a);
|
||||||
|
|
||||||
|
|
||||||
$signa = substr($a,0,1);
|
$signa = substr($a,0,1);
|
||||||
if ($signa==0) { $q=substr($q,1,$LEN-1)."1"; }
|
if ($signa==0) { $q=substr($q,1,$LEN-1)."1"; }
|
||||||
else { $q=substr($q,1,$LEN-1)."0"; }
|
else { $q=substr($q,1,$LEN-1)."0"; }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -80,9 +80,9 @@ else { printf("\n"); }
|
||||||
|
|
||||||
sub b2d {
|
sub b2d {
|
||||||
my ($v) = @_;
|
my ($v) = @_;
|
||||||
|
|
||||||
$v = oct("0b" . $v);
|
$v = oct("0b" . $v);
|
||||||
|
|
||||||
return($v);
|
return($v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,11 +93,11 @@ sub d2b {
|
||||||
|
|
||||||
$v = sprintf "%b",$v;
|
$v = sprintf "%b",$v;
|
||||||
if (length($v)<$LEN) {
|
if (length($v)<$LEN) {
|
||||||
$repeat=$LEN-length($v);
|
$repeat=$LEN-length($v);
|
||||||
$v="0"x$repeat.$v;
|
$v="0"x$repeat.$v;
|
||||||
}
|
}
|
||||||
elsif (length($v)>$LEN) {
|
elsif (length($v)>$LEN) {
|
||||||
$v=substr($v,length($v)-$LEN,$LEN);
|
$v=substr($v,length($v)-$LEN,$LEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
return($v);
|
return($v);
|
||||||
|
@ -110,11 +110,11 @@ sub d2bl {
|
||||||
|
|
||||||
$v = sprintf "%b",$v;
|
$v = sprintf "%b",$v;
|
||||||
if (length($v)<$LEN) {
|
if (length($v)<$LEN) {
|
||||||
$repeat=$LEN-length($v);
|
$repeat=$LEN-length($v);
|
||||||
$v="0"x$repeat.$v;
|
$v="0"x$repeat.$v;
|
||||||
}
|
}
|
||||||
elsif (length($v)>$LEN) {
|
elsif (length($v)>$LEN) {
|
||||||
$v=substr($v,length($v)-$LEN,$LEN);
|
$v=substr($v,length($v)-$LEN,$LEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
return($v);
|
return($v);
|
||||||
|
|
Loading…
Reference in New Issue