Version 1.5
This commit is contained in:
parent
790c48cd0b
commit
b65d4dd8f1
196
LICENSE
196
LICENSE
|
@ -6,196 +6,64 @@
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
153
README.md
153
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
|
||||||
|
|
||||||
|
@ -24,13 +23,15 @@ Files under the [tools](tools/) directory may be available under a different lic
|
||||||
├── 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)*
|
||||||
|
For example if `mybuild` is the name for the snapshot:
|
||||||
|
|
||||||
|
set BUILD_PATH environment variable:
|
||||||
|
|
||||||
|
`setenv BUILD_PATH snapshots/mybuild`
|
||||||
|
|
||||||
`$RV_ROOT/configs/swerv.config [configuration options..] -snapshot=mybuild`
|
`$RV_ROOT/configs/swerv.config [configuration options..] -snapshot=mybuild`
|
||||||
|
|
||||||
Snapshots are placed in `$RV_ROOT/configs/snapshots/<snapshot name>/` directory
|
Snapshots are placed in `$BUILD_PATH` directory
|
||||||
|
|
||||||
1. Build with **verilator**:
|
|
||||||
|
|
||||||
`make -f $RV_ROOT/tools/Makefile verilator [snapshot=name]`
|
1. Running a simple Hello World program (verilator)
|
||||||
|
|
||||||
This will create and populate the verilator *obj_dir/* in the current work dir.
|
`make -f $RV_ROOT/tools/Makefile`
|
||||||
|
|
||||||
**Other targets supported**:
|
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.
|
||||||
|
|
||||||
vcs (Synopsys)
|
|
||||||
irun (Cadence)
|
|
||||||
|
|
||||||
### Running a simple Hello World program (verilator)
|
The simulation produces output on the screen like:
|
||||||
|
|
||||||
RV_ROOT = /path/to/swerv
|
````
|
||||||
export RV_ROOT
|
VerilatorTB: Start of sim
|
||||||
|
|
||||||
make -f $RV_ROOT/tools/Makefile verilator-run
|
----------------------------------
|
||||||
|
Hello World from SweRV EH1 @WDC !!
|
||||||
|
----------------------------------
|
||||||
|
|
||||||
This will build a verilator model of SweRV with AHB-lite bus, and execute a short sequence of instructions that writes out "HELLO
|
Finished : minstret = 443, mcycle = 1372
|
||||||
WORLD" to the bus.
|
See "exec.log" for execution trace with register updates..
|
||||||
|
|
||||||
You can re-execute using
|
TEST_PASSED
|
||||||
|
````
|
||||||
|
|
||||||
./obj_dir/Vtb_top
|
The simulation generates following files:
|
||||||
|
|
||||||
Start of sim
|
`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:
|
||||||
Hello World from SweRV @WDC !!
|
` ./obj_dir/Vtb_top `
|
||||||
------------------------------
|
or
|
||||||
|
`make -f $RV_ROOT/tools/Makefile verilator`
|
||||||
|
|
||||||
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 simulation run/build command has following generic form:
|
||||||
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 [<simulator>] [debug=1] [snapshot=<snapshot>] [target=<target>] [TEST=<test>] [TEST_DIR=<path_to_test_dir>] [CONF_PARAMS=<swerv.config option>]
|
||||||
|
|
||||||
make -f $RV_ROOT/tools/Makefile verilator-run ASM_TEST=my_hellow_world.s ASM_TEST_DIR=/path/to/dir
|
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.
|
||||||
|
|
|
@ -82,7 +82,7 @@ my @unsets = ();
|
||||||
# : multiple -set/-unset options accepted\n\n";
|
# : multiple -set/-unset options accepted\n\n";
|
||||||
#
|
#
|
||||||
|
|
||||||
$helpusage = "
|
my $helpusage = "
|
||||||
|
|
||||||
Main configuration database for SWERV
|
Main configuration database for SWERV
|
||||||
|
|
||||||
|
@ -91,7 +91,7 @@ This script documents, and generates the {`#} define/include files for verilog/a
|
||||||
|
|
||||||
User options:
|
User options:
|
||||||
|
|
||||||
-target = { default, generic }
|
-target = { default, default_ahb, default_pd, high_perf}
|
||||||
use default settings for one of the targets
|
use default settings for one of the targets
|
||||||
|
|
||||||
-set=var=value
|
-set=var=value
|
||||||
|
@ -246,32 +246,7 @@ my $perlfile = "$build_path/perl_configs.pl";
|
||||||
|
|
||||||
my $no_secondary_alu=0;
|
my $no_secondary_alu=0;
|
||||||
|
|
||||||
if ($target eq "generic") {
|
if ($target eq "default") {
|
||||||
print "$self: Using target \"generic\"\n";
|
|
||||||
if (!defined($ret_stack_size)) { $ret_stack_size=4; }
|
|
||||||
if (!defined($btb_size)) { $btb_size=32; }
|
|
||||||
if (!defined($bht_size)) { $bht_size=128; }
|
|
||||||
if (!defined($dccm_enable)) { $dccm_enable=1; }
|
|
||||||
if (!defined($dccm_region)) { $dccm_region="0xf"; }
|
|
||||||
if (!defined($dccm_offset)) { $dccm_offset="0x80000"; } #1*256*1024
|
|
||||||
if (!defined($dccm_size)) { $dccm_size=512; }
|
|
||||||
if (!defined($dccm_num_banks)) { $dccm_num_banks=8; }
|
|
||||||
if (!defined($iccm_enable)) { $iccm_enable=1; }
|
|
||||||
if (!defined($iccm_region)) { $iccm_region="0xe"; }
|
|
||||||
if (!defined($iccm_offset)) { $iccm_offset="0xe000000"; } #0x380*256*1024
|
|
||||||
if (!defined($iccm_size)) { $iccm_size=512; }
|
|
||||||
if (!defined($iccm_num_banks)) { $iccm_num_banks=8; }
|
|
||||||
if (!defined($icache_enable)) { $icache_enable=0; }
|
|
||||||
if (!defined($icache_ecc)) { $icache_ecc=0; }
|
|
||||||
if (!defined($icache_size)) { $icache_size=16; }
|
|
||||||
if (!defined($pic_2cycle)) { $pic_2cycle=0; }
|
|
||||||
if (!defined($pic_region)) { $pic_region="0xf"; }
|
|
||||||
if (!defined($pic_offset)) { $pic_offset="0x100000"; } # 3*256*1024
|
|
||||||
if (!defined($pic_size)) { $pic_size=32; }
|
|
||||||
if (!defined($pic_total_int)) { $pic_total_int=8; }
|
|
||||||
if (!defined($dec_instbuf_depth)) { $dec_instbuf_depth=2; }
|
|
||||||
}
|
|
||||||
elsif ($target eq "default") {
|
|
||||||
if (!defined($ret_stack_size)) { $ret_stack_size=4; }
|
if (!defined($ret_stack_size)) { $ret_stack_size=4; }
|
||||||
if (!defined($btb_size)) { $btb_size=32; }
|
if (!defined($btb_size)) { $btb_size=32; }
|
||||||
if (!defined($bht_size)) { $bht_size=128; }
|
if (!defined($bht_size)) { $bht_size=128; }
|
||||||
|
@ -296,8 +271,78 @@ elsif ($target eq "default") {
|
||||||
|
|
||||||
# default is AXI bus
|
# default is AXI bus
|
||||||
}
|
}
|
||||||
else {
|
elsif ($target eq "default_ahb") {
|
||||||
die "$self: ERROR! Unsupported target \"$target\". Supported targets are: \"default,generic\"!\n";
|
if (!defined($ret_stack_size)) { $ret_stack_size=4; }
|
||||||
|
if (!defined($btb_size)) { $btb_size=32; }
|
||||||
|
if (!defined($bht_size)) { $bht_size=128; }
|
||||||
|
if (!defined($dccm_enable)) { $dccm_enable=1; }
|
||||||
|
if (!defined($dccm_region)) { $dccm_region="0xf"; }
|
||||||
|
if (!defined($dccm_offset)) { $dccm_offset="0x40000"; } #1*256*1024
|
||||||
|
if (!defined($dccm_size)) { $dccm_size=64; }
|
||||||
|
if (!defined($dccm_num_banks)) { $dccm_num_banks=8; }
|
||||||
|
if (!defined($iccm_enable)) { $iccm_enable=0; }
|
||||||
|
if (!defined($iccm_region)) { $iccm_region="0xe"; }
|
||||||
|
if (!defined($iccm_offset)) { $iccm_offset="0xe000000"; } #0x380*256*1024
|
||||||
|
if (!defined($iccm_size)) { $iccm_size=512; }
|
||||||
|
if (!defined($iccm_num_banks)) { $iccm_num_banks=8; }
|
||||||
|
if (!defined($icache_enable)) { $icache_enable=1; }
|
||||||
|
if (!defined($icache_ecc)) { $icache_ecc=0; }
|
||||||
|
if (!defined($icache_size)) { $icache_size=16; }
|
||||||
|
if (!defined($pic_2cycle)) { $pic_2cycle=0; }
|
||||||
|
if (!defined($pic_region)) { $pic_region="0xf"; }
|
||||||
|
if (!defined($pic_offset)) { $pic_offset="0xc0000"; } # 3*256*1024
|
||||||
|
if (!defined($pic_size)) { $pic_size=32; }
|
||||||
|
if (!defined($pic_total_int)) { $pic_total_int=8; }
|
||||||
|
$ahb_lite = 1;
|
||||||
|
|
||||||
|
} elsif ($target eq "default_pd") {
|
||||||
|
if (!defined($ret_stack_size)) { $ret_stack_size=4; }
|
||||||
|
if (!defined($btb_size)) { $btb_size=32; }
|
||||||
|
if (!defined($bht_size)) { $bht_size=128; }
|
||||||
|
if (!defined($dccm_enable)) { $dccm_enable=1; }
|
||||||
|
if (!defined($dccm_region)) { $dccm_region="0xf"; }
|
||||||
|
if (!defined($dccm_offset)) { $dccm_offset="0x40000"; } #1*256*1024
|
||||||
|
if (!defined($dccm_size)) { $dccm_size=32; }
|
||||||
|
if (!defined($dccm_num_banks)) { $dccm_num_banks=8; }
|
||||||
|
if (!defined($iccm_enable)) { $iccm_enable=0; }
|
||||||
|
if (!defined($iccm_region)) { $iccm_region="0xe"; }
|
||||||
|
if (!defined($iccm_offset)) { $iccm_offset="0xe000000"; } #0x380*256*1024
|
||||||
|
if (!defined($iccm_size)) { $iccm_size=512; }
|
||||||
|
if (!defined($iccm_num_banks)) { $iccm_num_banks=8; }
|
||||||
|
if (!defined($icache_enable)) { $icache_enable=1; }
|
||||||
|
if (!defined($icache_ecc)) { $icache_ecc=0; }
|
||||||
|
if (!defined($icache_size)) { $icache_size=16; }
|
||||||
|
if (!defined($pic_2cycle)) { $pic_2cycle=0; }
|
||||||
|
if (!defined($pic_region)) { $pic_region="0xf"; }
|
||||||
|
if (!defined($pic_offset)) { $pic_offset="0xc0000"; } # 3*256*1024
|
||||||
|
if (!defined($pic_size)) { $pic_size=32; }
|
||||||
|
if (!defined($pic_total_int)) { $pic_total_int=8; }
|
||||||
|
|
||||||
|
} elsif ($target eq "high_perf") {
|
||||||
|
if (!defined($ret_stack_size)) { $ret_stack_size=4; }
|
||||||
|
if (!defined($btb_size)) { $btb_size=512; }
|
||||||
|
if (!defined($bht_size)) { $bht_size=2048; }
|
||||||
|
if (!defined($dccm_enable)) { $dccm_enable=1; }
|
||||||
|
if (!defined($dccm_region)) { $dccm_region="0xf"; }
|
||||||
|
if (!defined($dccm_offset)) { $dccm_offset="0x40000"; } #1*256*1024
|
||||||
|
if (!defined($dccm_size)) { $dccm_size=64; }
|
||||||
|
if (!defined($dccm_num_banks)) { $dccm_num_banks=8; }
|
||||||
|
if (!defined($iccm_enable)) { $iccm_enable=0; }
|
||||||
|
if (!defined($iccm_region)) { $iccm_region="0xe"; }
|
||||||
|
if (!defined($iccm_offset)) { $iccm_offset="0xe000000"; } #0x380*256*1024
|
||||||
|
if (!defined($iccm_size)) { $iccm_size=512; }
|
||||||
|
if (!defined($iccm_num_banks)) { $iccm_num_banks=8; }
|
||||||
|
if (!defined($icache_enable)) { $icache_enable=1; }
|
||||||
|
if (!defined($icache_ecc)) { $icache_ecc=0; }
|
||||||
|
if (!defined($icache_size)) { $icache_size=32; }
|
||||||
|
if (!defined($pic_2cycle)) { $pic_2cycle=0; }
|
||||||
|
if (!defined($pic_region)) { $pic_region="0xf"; }
|
||||||
|
if (!defined($pic_offset)) { $pic_offset="0xc0000"; } # 3*256*1024
|
||||||
|
if (!defined($pic_size)) { $pic_size=32; }
|
||||||
|
if (!defined($pic_total_int)) { $pic_total_int=8; }
|
||||||
|
|
||||||
|
} else {
|
||||||
|
die "$self: ERROR! Unsupported target \"$target\". Supported targets are: \"default, default_ahb, default_pd, high_perf\"!\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
# general stuff - can't set from command line other than -set
|
# general stuff - can't set from command line other than -set
|
||||||
|
@ -366,7 +411,7 @@ our %csr = (#{{{
|
||||||
"exists" => "true",
|
"exists" => "true",
|
||||||
},
|
},
|
||||||
"mimpid" => {
|
"mimpid" => {
|
||||||
"reset" => "0x1",
|
"reset" => "0x2",
|
||||||
"mask" => "0x0",
|
"mask" => "0x0",
|
||||||
"exists" => "true",
|
"exists" => "true",
|
||||||
},
|
},
|
||||||
|
@ -742,7 +787,7 @@ our %config = (#{{{
|
||||||
"CPU_TOP" => "`RV_TOP.swerv",
|
"CPU_TOP" => "`RV_TOP.swerv",
|
||||||
"clock_period" => "100",
|
"clock_period" => "100",
|
||||||
"build_ahb_lite" => "$ahb_lite", # one and only one bus build arg will ever be defined
|
"build_ahb_lite" => "$ahb_lite", # one and only one bus build arg will ever be defined
|
||||||
"build_axi4" => "",
|
"build_axi4" => "1",
|
||||||
"assert_on" => "",
|
"assert_on" => "",
|
||||||
"datawidth" => "64", # deprecate this !! FIXME
|
"datawidth" => "64", # deprecate this !! FIXME
|
||||||
"ext_datawidth" => "64",
|
"ext_datawidth" => "64",
|
||||||
|
@ -905,6 +950,12 @@ else { # default is AXI bus
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Over-ride MFDC reset value for AXI.
|
||||||
|
if (exists($config{"testbench"}{"build_axi_native"}) and
|
||||||
|
$config{"testbench"}{"build_axi_native"} ne "") {
|
||||||
|
$config{csr}{mfdc}{reset} = "0x00070040" if exists $config{csr}{mfdc};
|
||||||
|
}
|
||||||
|
|
||||||
# Over-ride MFDC reset value for AXI.
|
# Over-ride MFDC reset value for AXI.
|
||||||
if (exists($config{"testbench"}{"build_axi_native"}) and
|
if (exists($config{"testbench"}{"build_axi_native"}) and
|
||||||
$config{"testbench"}{"build_axi_native"} ne "") {
|
$config{"testbench"}{"build_axi_native"} ne "") {
|
||||||
|
@ -1254,14 +1305,6 @@ for ($rgn = 15;$rgn >= 0; $rgn--) {
|
||||||
}
|
}
|
||||||
$config{memmap}{debug_sb_mem} = sprintf("0x%08x", $config{memmap}{debug_sb_mem});
|
$config{memmap}{debug_sb_mem} = sprintf("0x%08x", $config{memmap}{debug_sb_mem});
|
||||||
|
|
||||||
# Boot generic from ICCM
|
|
||||||
if ($target eq "generic") {
|
|
||||||
$config{reset_vec} = $config{iccm}{iccm_sadr};
|
|
||||||
$config{testbench}{generic} = 1;
|
|
||||||
print "$self: Setting reset_vec = ICCM start address for Generic\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Output bit-width specifiers for these variables
|
# Output bit-width specifiers for these variables
|
||||||
our %widths = (
|
our %widths = (
|
||||||
|
@ -1296,6 +1339,31 @@ our %widths = (
|
||||||
);
|
);
|
||||||
#}}}
|
#}}}
|
||||||
|
|
||||||
|
|
||||||
|
#-----------------------Reset Vector MPU check-----------------------#
|
||||||
|
$flag_pass=0;
|
||||||
|
if(!(hex($config{reset_vec}) >= ((hex($config{iccm}{iccm_region})<<28) + (hex($config{iccm}{iccm_offset}))) && (hex($config{reset_vec}) < ((hex($config{iccm}{iccm_region})<<28) + (hex($config{iccm}{iccm_offset})) + size($config{iccm}{iccm_size})-1))))
|
||||||
|
{
|
||||||
|
for(my $i=0; $i<8; $i++)
|
||||||
|
{
|
||||||
|
$inst_access_enable = "inst_access_enable$i";
|
||||||
|
$inst_access_addr = "inst_access_addr$i";
|
||||||
|
$inst_access_mask = "inst_access_mask$i";
|
||||||
|
if(hex($config{protection}{$inst_access_enable}))
|
||||||
|
{
|
||||||
|
if((hex($config{reset_vec})>= hex($config{protection}{$inst_access_addr})) && (hex($config{reset_vec})< (hex($config{protection}{$inst_access_addr}) | hex($config{protection}{$inst_access_mask}))))
|
||||||
|
{
|
||||||
|
$flag_pass++;
|
||||||
|
last;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {$enable_check++;}
|
||||||
|
}
|
||||||
|
|
||||||
|
if($flag_pass == 0 & $enable_check < 8) { die("$helpusage\n\nFAIL: RESET_VECTOR not in any of MPU enabled instruction access windows or ICCM !!!\n\n");}
|
||||||
|
}
|
||||||
|
#-----------------------Reset Vector MPU check-----------------------#
|
||||||
|
|
||||||
#print Dumper(\%config);
|
#print Dumper(\%config);
|
||||||
#print Dumper(\%width);
|
#print Dumper(\%width);
|
||||||
|
|
||||||
|
@ -1612,6 +1680,73 @@ sub collect_mem_protection {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Collect memory protection specs (array of address pairs) in the given
|
||||||
|
# resutls array. Tag is either "data" or "inst".
|
||||||
|
sub collect_mem_protection {
|
||||||
|
my ($tag, $config, $results) = @_;
|
||||||
|
return unless exists $config{protection};
|
||||||
|
|
||||||
|
my $prot = $config{protection};
|
||||||
|
|
||||||
|
my $enable_tag = $tag . "_access_enable";
|
||||||
|
my $addr_tag = $tag . "_access_addr";
|
||||||
|
my $mask_tag = $tag . "_access_mask";
|
||||||
|
|
||||||
|
foreach my $key (keys %{$prot}) {
|
||||||
|
next unless $key =~ /^$enable_tag(\d+)$/;
|
||||||
|
my $ix = $1;
|
||||||
|
|
||||||
|
my $enable = $prot->{$key};
|
||||||
|
if ($enable !~ /[01]$/) {
|
||||||
|
warn("Invalid value for protection entry $key: $enable\n");
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
|
||||||
|
next unless ($enable eq "1" or $enable eq "1'b1");
|
||||||
|
|
||||||
|
if (! exists $prot->{"$addr_tag$ix"}) {
|
||||||
|
warn("Missing $addr_tag$ix\n");
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! exists $prot->{"$mask_tag$ix"}) {
|
||||||
|
warn("Missing $mask_tag$ix\n");
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
|
||||||
|
my $addr = $prot->{"$addr_tag$ix"};
|
||||||
|
my $mask = $prot->{"$mask_tag$ix"};
|
||||||
|
|
||||||
|
if ($addr !~ /^0x[0-9a-fA-F]+$/) {
|
||||||
|
warn("Invalid $addr_tag$ix: $addr\n");
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($mask !~ /^0x[0-9a-fA-F]+$/) {
|
||||||
|
warn("Invalid $mask_tag$ix: $mask\n");
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((hex($addr) & hex($mask)) != 0) {
|
||||||
|
warn("Protection mask bits overlap address bits in mask $mask and addr $addr\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($mask !~ /^0x0*[137]?f*$/) {
|
||||||
|
warn("Protection mask ($mask) must have all its one bits to the right of its zero bits\n");
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
|
||||||
|
my $start = hex($addr) & ~hex($mask) & 0xffffffff;
|
||||||
|
my $end = (hex($addr) | hex($mask)) & 0xffffffff;
|
||||||
|
|
||||||
|
$start = sprintf("0x%08x", $start);
|
||||||
|
$end = sprintf("0x%08x", $end);
|
||||||
|
|
||||||
|
push(@{$results}, [ $start, $end ]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
sub dump_whisper_config{#{{{
|
sub dump_whisper_config{#{{{
|
||||||
my ($config, $path) = @_;
|
my ($config, $path) = @_;
|
||||||
|
|
||||||
|
|
|
@ -110,6 +110,7 @@ module dbg (
|
||||||
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
|
||||||
);
|
);
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -240,7 +243,7 @@ module dbg (
|
||||||
// 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
|
||||||
|
@ -266,10 +269,10 @@ module dbg (
|
||||||
|
|
||||||
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);
|
||||||
|
@ -301,13 +304,14 @@ module dbg (
|
||||||
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
|
||||||
|
@ -316,10 +320,12 @@ module dbg (
|
||||||
//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;
|
||||||
|
|
||||||
|
@ -329,6 +335,9 @@ 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));
|
||||||
|
@ -401,19 +410,19 @@ 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
|
||||||
|
@ -426,22 +435,22 @@ module dbg (
|
||||||
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;
|
||||||
|
@ -467,7 +476,7 @@ module dbg (
|
||||||
({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));
|
||||||
|
@ -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];
|
||||||
|
|
|
@ -123,6 +123,9 @@ module dec
|
||||||
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
|
||||||
|
|
|
@ -779,6 +779,7 @@ module dec_decode_ctl
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
assign cam_reset_same_dest_wb = wbd.i0v & wbd.i1v & (wbd.i0rd[4:0] == wbd.i1rd[4:0]) &
|
assign cam_reset_same_dest_wb = wbd.i0v & wbd.i1v & (wbd.i0rd[4:0] == wbd.i1rd[4:0]) &
|
||||||
wbd.i0load & nonblock_load_valid_wb & ~dec_tlu_i0_kill_writeb_wb & ~dec_tlu_i1_kill_writeb_wb;
|
wbd.i0load & nonblock_load_valid_wb & ~dec_tlu_i0_kill_writeb_wb & ~dec_tlu_i1_kill_writeb_wb;
|
||||||
|
|
||||||
|
@ -794,6 +795,7 @@ module dec_decode_ctl
|
||||||
|
|
||||||
assign nonblock_load_rd[4:0] = (e3d.i0load) ? e3d.i0rd[4:0] : e3d.i1rd[4:0]; // rd data
|
assign nonblock_load_rd[4:0] = (e3d.i0load) ? e3d.i0rd[4:0] : e3d.i1rd[4:0]; // rd data
|
||||||
|
|
||||||
|
|
||||||
// checks
|
// checks
|
||||||
|
|
||||||
`ifdef ASSERT_ON
|
`ifdef ASSERT_ON
|
||||||
|
@ -937,6 +939,7 @@ end : cam_array
|
||||||
// pmu start
|
// pmu start
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
assign csr_read = dec_csr_ren_d;
|
assign csr_read = dec_csr_ren_d;
|
||||||
assign csr_write = dec_csr_wen_unq_d;
|
assign csr_write = dec_csr_wen_unq_d;
|
||||||
|
|
||||||
|
@ -1339,7 +1342,6 @@ end : cam_array
|
||||||
|
|
||||||
assign i1_block_d = leak1_i1_stall |
|
assign i1_block_d = leak1_i1_stall |
|
||||||
(i0_jal) | // no i1 after a jal, will flush
|
(i0_jal) | // no i1 after a jal, will flush
|
||||||
( (i0_br_error_all | (|dec_i0_trigger_match_d[3:0]) | ((i0_dp.condbr | i0_dp.jal) & i0_secondary_d)) & i1_dp.load ) | // if branch or branch error then don't allow i1 load
|
|
||||||
i0_presync | i0_postsync |
|
i0_presync | i0_postsync |
|
||||||
i1_dp.presync | i1_dp.postsync |
|
i1_dp.presync | i1_dp.postsync |
|
||||||
i1_icaf_d | // instruction access fault is i0 only
|
i1_icaf_d | // instruction access fault is i0 only
|
||||||
|
@ -1934,6 +1936,7 @@ end : cam_array
|
||||||
assign dec_tlu_i1_valid_e4 = e4d.i1valid & ~flush_lower_wb;
|
assign dec_tlu_i1_valid_e4 = e4d.i1valid & ~flush_lower_wb;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
assign dt.legal = i0_legal_decode_d ;
|
assign dt.legal = i0_legal_decode_d ;
|
||||||
assign dt.icaf = i0_icaf_d & i0_legal_decode_d; // dbecc is icaf exception
|
assign dt.icaf = i0_icaf_d & i0_legal_decode_d; // dbecc is icaf exception
|
||||||
assign dt.icaf_f1 = dec_i0_icaf_f1_d & i0_legal_decode_d; // this includes icaf and dbecc
|
assign dt.icaf_f1 = dec_i0_icaf_f1_d & i0_legal_decode_d; // this includes icaf and dbecc
|
||||||
|
@ -1988,6 +1991,7 @@ end : cam_array
|
||||||
rvdffe #( $bits(trap_pkt_t) ) trap_e4ff (.*, .en(i0_e4_ctl_en), .din(e3t_in), .dout(e4t));
|
rvdffe #( $bits(trap_pkt_t) ) trap_e4ff (.*, .en(i0_e4_ctl_en), .din(e3t_in), .dout(e4t));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
assign freeze_e3 = freeze & ~freeze_before;
|
assign freeze_e3 = freeze & ~freeze_before;
|
||||||
|
|
||||||
rvdff #(1) freeze_before_ff (.*, .clk(active_clk), .din(freeze), .dout(freeze_before));
|
rvdff #(1) freeze_before_ff (.*, .clk(active_clk), .din(freeze), .dout(freeze_before));
|
||||||
|
@ -2025,6 +2029,8 @@ end : cam_array
|
||||||
|
|
||||||
// end tlu stuff
|
// end tlu stuff
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
assign i0_dc.mul = i0_dp.mul & i0_legal_decode_d;
|
assign i0_dc.mul = i0_dp.mul & i0_legal_decode_d;
|
||||||
assign i0_dc.load = i0_dp.load & i0_legal_decode_d;
|
assign i0_dc.load = i0_dp.load & i0_legal_decode_d;
|
||||||
assign i0_dc.sec = i0_dp.alu & i0_secondary_d & i0_legal_decode_d;
|
assign i0_dc.sec = i0_dp.alu & i0_secondary_d & i0_legal_decode_d;
|
||||||
|
@ -2179,6 +2185,7 @@ end : cam_array
|
||||||
assign dec_i1_sec_decode_e3 = e3d.i1secondary & ~i0_flush_final_e3 & ~flush_lower_wb & ~freeze;
|
assign dec_i1_sec_decode_e3 = e3d.i1secondary & ~i0_flush_final_e3 & ~flush_lower_wb & ~freeze;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
rvdffe #( $bits(dest_pkt_t) ) e4ff (.*, .en(i0_e4_ctl_en), .din(e3d_in), .dout(e4d));
|
rvdffe #( $bits(dest_pkt_t) ) e4ff (.*, .en(i0_e4_ctl_en), .din(e3d_in), .dout(e4d));
|
||||||
|
|
||||||
always_comb begin
|
always_comb begin
|
||||||
|
@ -2281,6 +2288,7 @@ end : cam_array
|
||||||
rvdffe #(12) e2brpcff (.*, .en(i0_e2_data_en), .din(last_br_immed_e1[12:1]), .dout(last_br_immed_e2[12:1]));
|
rvdffe #(12) e2brpcff (.*, .en(i0_e2_data_en), .din(last_br_immed_e1[12:1]), .dout(last_br_immed_e2[12:1]));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// trace stuff
|
// trace stuff
|
||||||
|
|
||||||
rvdffe #(32) divinstff (.*, .en(i0_div_decode_d), .din(i0_inst_d[31:0]), .dout(div_inst[31:0]));
|
rvdffe #(32) divinstff (.*, .en(i0_div_decode_d), .din(i0_inst_d[31:0]), .dout(div_inst[31:0]));
|
||||||
|
|
|
@ -74,6 +74,9 @@ module dec_tlu_ctl
|
||||||
input logic iccm_dma_sb_error, // I side dma single bit error
|
input logic iccm_dma_sb_error, // I side dma single bit error
|
||||||
|
|
||||||
input lsu_error_pkt_t lsu_error_pkt_dc3, // lsu precise exception/error packet
|
input lsu_error_pkt_t lsu_error_pkt_dc3, // lsu precise exception/error packet
|
||||||
|
input logic lsu_single_ecc_error_incr, // Increment the counter for Single ECC error
|
||||||
|
|
||||||
|
input logic lsu_load_ecc_stbuf_full_dc3, // STBUF full, ecc errors should be rfpc'd
|
||||||
|
|
||||||
input logic dec_pause_state, // Pause counter not zero
|
input logic dec_pause_state, // Pause counter not zero
|
||||||
input logic lsu_imprecise_error_store_any, // store bus error
|
input logic lsu_imprecise_error_store_any, // store bus error
|
||||||
|
@ -336,11 +339,12 @@ module dec_tlu_ctl
|
||||||
logic [1:0] dec_tlu_br0_bank_e4, dec_tlu_br1_bank_e4;
|
logic [1:0] dec_tlu_br0_bank_e4, dec_tlu_br1_bank_e4;
|
||||||
logic rfpc_i0_e4, rfpc_i1_e4;
|
logic rfpc_i0_e4, rfpc_i1_e4;
|
||||||
logic lsu_i0_rfnpc_dc4, lsu_i1_rfnpc_dc4;
|
logic lsu_i0_rfnpc_dc4, lsu_i1_rfnpc_dc4;
|
||||||
|
logic lsu_i0_rfpc_dc4, lsu_i1_rfpc_dc4;
|
||||||
logic dec_tlu_br0_error_e4, dec_tlu_br0_start_error_e4, dec_tlu_br0_v_e4;
|
logic dec_tlu_br0_error_e4, dec_tlu_br0_start_error_e4, dec_tlu_br0_v_e4;
|
||||||
logic dec_tlu_br1_error_e4, dec_tlu_br1_start_error_e4, dec_tlu_br1_v_e4;
|
logic dec_tlu_br1_error_e4, dec_tlu_br1_start_error_e4, dec_tlu_br1_v_e4;
|
||||||
logic lsu_i0_exc_dc4, lsu_i1_exc_dc4, lsu_i0_exc_dc4_raw, lsu_i1_exc_dc4_raw, lsu_exc_ma_dc4, lsu_exc_acc_dc4, lsu_exc_st_dc4,
|
logic lsu_i0_exc_dc4, lsu_i1_exc_dc4, lsu_i0_exc_dc4_raw, lsu_i1_exc_dc4_raw, lsu_exc_ma_dc4, lsu_exc_acc_dc4, lsu_exc_st_dc4,
|
||||||
lsu_exc_valid_e4, lsu_exc_valid_e4_raw, lsu_exc_valid_wb, lsu_i0_exc_wb,
|
lsu_exc_valid_e4, lsu_exc_valid_e4_raw, lsu_exc_valid_wb, lsu_i0_exc_wb,
|
||||||
block_interrupts, lsu_block_interrupts_dc3, lsu_block_interrupts_e4;
|
block_interrupts, lsu_block_interrupts_dc3, lsu_block_interrupts_e4, lsu_load_ecc_stbuf_full_dc4;
|
||||||
logic tlu_i0_commit_cmt, tlu_i1_commit_cmt;
|
logic tlu_i0_commit_cmt, tlu_i1_commit_cmt;
|
||||||
logic i0_trigger_eval_e4, i1_trigger_eval_e4, lsu_freeze_e4, lsu_freeze_pulse_e3, lsu_freeze_pulse_e4;
|
logic i0_trigger_eval_e4, i1_trigger_eval_e4, lsu_freeze_e4, lsu_freeze_pulse_e3, lsu_freeze_pulse_e4;
|
||||||
|
|
||||||
|
@ -459,7 +463,7 @@ module dec_tlu_ctl
|
||||||
assign mpc_debug_run_req_sync_pulse = mpc_debug_run_req_sync & ~mpc_debug_run_req_sync_f;
|
assign mpc_debug_run_req_sync_pulse = mpc_debug_run_req_sync & ~mpc_debug_run_req_sync_f;
|
||||||
|
|
||||||
// states
|
// states
|
||||||
assign mpc_halt_state_ns = (mpc_halt_state_f | mpc_debug_halt_req_sync_pulse) & ~mpc_debug_run_req_sync;
|
assign mpc_halt_state_ns = (mpc_halt_state_f | mpc_debug_halt_req_sync_pulse | (reset_delayed & ~mpc_reset_run_req)) & ~mpc_debug_run_req_sync;
|
||||||
assign mpc_run_state_ns = (mpc_run_state_f | (mpc_debug_run_req_sync_pulse & ~mpc_debug_run_ack_f)) & (internal_dbg_halt_mode_f & ~dcsr_single_step_running_f);
|
assign mpc_run_state_ns = (mpc_run_state_f | (mpc_debug_run_req_sync_pulse & ~mpc_debug_run_ack_f)) & (internal_dbg_halt_mode_f & ~dcsr_single_step_running_f);
|
||||||
|
|
||||||
// note, MPC halt can allow the jtag debugger to just start sending commands. When that happens, set the interal debugger halt state to prevent
|
// note, MPC halt can allow the jtag debugger to just start sending commands. When that happens, set the interal debugger halt state to prevent
|
||||||
|
@ -722,10 +726,10 @@ module dec_tlu_ctl
|
||||||
// LSU exceptions (LSU responsible for prioritizing simultaneous cases)
|
// LSU exceptions (LSU responsible for prioritizing simultaneous cases)
|
||||||
lsu_error_pkt_t lsu_error_pkt_dc4;
|
lsu_error_pkt_t lsu_error_pkt_dc4;
|
||||||
|
|
||||||
rvdff #( $bits(lsu_error_pkt_t) ) lsu_error_dc4ff (.*, .clk(lsu_e3_e4_clk), .din(lsu_error_pkt_dc3), .dout(lsu_error_pkt_dc4));
|
rvdff #( $bits(lsu_error_pkt_t)+1 ) lsu_error_dc4ff (.*, .clk(lsu_e3_e4_clk), .din({lsu_error_pkt_dc3, lsu_load_ecc_stbuf_full_dc3}), .dout({lsu_error_pkt_dc4, lsu_load_ecc_stbuf_full_dc4}));
|
||||||
|
|
||||||
logic lsu_single_ecc_error_wb_ns;
|
logic lsu_single_ecc_error_wb_ns;
|
||||||
assign lsu_single_ecc_error_wb_ns = lsu_error_pkt_dc4.single_ecc_error;// & ((~lsu_error_pkt_dc4.inst_pipe & tlu_i0_commit_cmt) | (lsu_error_pkt_dc4.inst_pipe & tlu_i1_commit_cmt));
|
assign lsu_single_ecc_error_wb_ns = lsu_single_ecc_error_incr;
|
||||||
rvdff #(2) lsu_dccm_errorff (.*, .clk(free_clk), .din({mdseac_locked_ns, lsu_single_ecc_error_wb_ns}), .dout({mdseac_locked_f, lsu_single_ecc_error_wb}));
|
rvdff #(2) lsu_dccm_errorff (.*, .clk(free_clk), .din({mdseac_locked_ns, lsu_single_ecc_error_wb_ns}), .dout({mdseac_locked_f, lsu_single_ecc_error_wb}));
|
||||||
|
|
||||||
logic [31:0] lsu_error_pkt_addr_dc4, lsu_error_pkt_addr_wb;
|
logic [31:0] lsu_error_pkt_addr_dc4, lsu_error_pkt_addr_wb;
|
||||||
|
@ -746,12 +750,18 @@ module dec_tlu_ctl
|
||||||
assign lsu_exc_acc_dc4 = (lsu_i0_exc_dc4 | lsu_i1_exc_dc4) & lsu_error_pkt_dc4.exc_type;
|
assign lsu_exc_acc_dc4 = (lsu_i0_exc_dc4 | lsu_i1_exc_dc4) & lsu_error_pkt_dc4.exc_type;
|
||||||
assign lsu_exc_st_dc4 = (lsu_i0_exc_dc4 | lsu_i1_exc_dc4) & lsu_error_pkt_dc4.inst_type;
|
assign lsu_exc_st_dc4 = (lsu_i0_exc_dc4 | lsu_i1_exc_dc4) & lsu_error_pkt_dc4.inst_type;
|
||||||
|
|
||||||
|
// If the stbuf is not full, then
|
||||||
// Single bit ECC errors on loads are RFNPC corrected, with the corrected data written to the GPR.
|
// Single bit ECC errors on loads are RFNPC corrected, with the corrected data written to the GPR.
|
||||||
// LSU turns the load into a store and patches the data in the DCCM
|
// LSU turns the load into a store and patches the data in the DCCM
|
||||||
assign lsu_i0_rfnpc_dc4 = dec_tlu_i0_valid_e4 & ~lsu_error_pkt_dc4.inst_pipe & ~lsu_error_pkt_dc4.inst_type &
|
assign lsu_i0_rfnpc_dc4 = dec_tlu_i0_valid_e4 & ~lsu_error_pkt_dc4.inst_pipe & ~lsu_error_pkt_dc4.inst_type &
|
||||||
lsu_error_pkt_dc4.single_ecc_error & ~lsu_error_pkt_dc4.dma_valid & ~i0_trigger_hit_e4;
|
lsu_error_pkt_dc4.single_ecc_error & ~lsu_error_pkt_dc4.dma_valid & ~i0_trigger_hit_e4 & ~lsu_load_ecc_stbuf_full_dc4;
|
||||||
assign lsu_i1_rfnpc_dc4 = dec_tlu_i1_valid_e4 & lsu_error_pkt_dc4.inst_pipe & ~lsu_error_pkt_dc4.inst_type &
|
assign lsu_i1_rfnpc_dc4 = dec_tlu_i1_valid_e4 & lsu_error_pkt_dc4.inst_pipe & ~lsu_error_pkt_dc4.inst_type &
|
||||||
lsu_error_pkt_dc4.single_ecc_error & ~lsu_error_pkt_dc4.dma_valid & ~i0_trigger_hit_e4 & ~i1_trigger_hit_e4;
|
lsu_error_pkt_dc4.single_ecc_error & ~lsu_error_pkt_dc4.dma_valid & ~i0_trigger_hit_e4 & ~i1_trigger_hit_e4 & ~lsu_load_ecc_stbuf_full_dc4;
|
||||||
|
// otherwise, they are rfpcs
|
||||||
|
assign lsu_i0_rfpc_dc4 = dec_tlu_i0_valid_e4 & ~lsu_error_pkt_dc4.inst_pipe & ~lsu_error_pkt_dc4.inst_type &
|
||||||
|
lsu_error_pkt_dc4.single_ecc_error & ~lsu_error_pkt_dc4.dma_valid & lsu_load_ecc_stbuf_full_dc4;
|
||||||
|
assign lsu_i1_rfpc_dc4 = dec_tlu_i1_valid_e4 & lsu_error_pkt_dc4.inst_pipe & ~lsu_error_pkt_dc4.inst_type &
|
||||||
|
lsu_error_pkt_dc4.single_ecc_error & ~lsu_error_pkt_dc4.dma_valid & lsu_load_ecc_stbuf_full_dc4;
|
||||||
|
|
||||||
// Branch prediction updating
|
// Branch prediction updating
|
||||||
assign dec_tlu_br0_addr_e4[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO] = exu_i0_br_index_e4[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO];
|
assign dec_tlu_br0_addr_e4[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO] = exu_i0_br_index_e4[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO];
|
||||||
|
@ -784,10 +794,10 @@ module dec_tlu_ctl
|
||||||
|
|
||||||
// refetch PC, microarch flush
|
// refetch PC, microarch flush
|
||||||
// ic errors only in pipe0
|
// ic errors only in pipe0
|
||||||
assign rfpc_i0_e4 = dec_tlu_i0_valid_e4 & ~tlu_flush_lower_wb & (exu_i0_br_error_e4 | exu_i0_br_start_error_e4 | ic_perr_e4 | iccm_sbecc_e4) & ~i0_trigger_hit_e4;
|
assign rfpc_i0_e4 = dec_tlu_i0_valid_e4 & ~tlu_flush_lower_wb & (exu_i0_br_error_e4 | exu_i0_br_start_error_e4 | ic_perr_e4 | iccm_sbecc_e4 | lsu_i0_rfpc_dc4) & ~i0_trigger_hit_e4;
|
||||||
assign rfpc_i1_e4 = dec_tlu_i1_valid_e4 & ~tlu_flush_lower_wb & ~i0_exception_valid_e4 & ~exu_i0_br_mp_e4 & ~lsu_i0_exc_dc4 & ~lsu_i0_rfnpc_dc4 &
|
assign rfpc_i1_e4 = dec_tlu_i1_valid_e4 & ~tlu_flush_lower_wb & ~i0_exception_valid_e4 & ~exu_i0_br_mp_e4 & ~lsu_i0_exc_dc4 & ~lsu_i0_rfnpc_dc4 &
|
||||||
~(exu_i0_br_error_e4 | exu_i0_br_start_error_e4 | ic_perr_e4 | iccm_sbecc_e4) &
|
~(exu_i0_br_error_e4 | exu_i0_br_start_error_e4 | ic_perr_e4 | iccm_sbecc_e4 | lsu_i0_rfpc_dc4) &
|
||||||
(exu_i1_br_error_e4 | exu_i1_br_start_error_e4) &
|
(exu_i1_br_error_e4 | exu_i1_br_start_error_e4 | lsu_i1_rfpc_dc4) &
|
||||||
~trigger_hit_e4;
|
~trigger_hit_e4;
|
||||||
|
|
||||||
// go ahead and repair the branch error on other flushes, doesn't have to be the rfpc flush
|
// go ahead and repair the branch error on other flushes, doesn't have to be the rfpc flush
|
||||||
|
@ -1050,7 +1060,8 @@ module dec_tlu_ctl
|
||||||
assign dec_csr_wen_wb_mod = dec_csr_wen_wb & ~trigger_hit_wb;
|
assign dec_csr_wen_wb_mod = dec_csr_wen_wb & ~trigger_hit_wb;
|
||||||
assign wr_mstatus_wb = dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[11:0] == `MSTATUS);
|
assign wr_mstatus_wb = dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[11:0] == `MSTATUS);
|
||||||
|
|
||||||
assign mstatus_ns[1:0] = ( ({2{exc_or_int_valid_wb}} & {mstatus[`MSTATUS_MIE], 1'b0}) |
|
assign mstatus_ns[1:0] = ( ({2{~wr_mstatus_wb & exc_or_int_valid_wb}} & {mstatus[`MSTATUS_MIE], 1'b0}) |
|
||||||
|
({2{ wr_mstatus_wb & exc_or_int_valid_wb}} & {dec_csr_wrdata_wb[3], 1'b0}) |
|
||||||
({2{mret_wb & ~exc_or_int_valid_wb}} & {1'b1, mstatus[1]}) |
|
({2{mret_wb & ~exc_or_int_valid_wb}} & {1'b1, mstatus[1]}) |
|
||||||
({2{wr_mstatus_wb & ~exc_or_int_valid_wb}} & {dec_csr_wrdata_wb[7], dec_csr_wrdata_wb[3]}) |
|
({2{wr_mstatus_wb & ~exc_or_int_valid_wb}} & {dec_csr_wrdata_wb[7], dec_csr_wrdata_wb[3]}) |
|
||||||
({2{~wr_mstatus_wb & ~exc_or_int_valid_wb & ~mret_wb}} & mstatus[1:0]) );
|
({2{~wr_mstatus_wb & ~exc_or_int_valid_wb & ~mret_wb}} & mstatus[1:0]) );
|
||||||
|
@ -1148,10 +1159,10 @@ module dec_tlu_ctl
|
||||||
|
|
||||||
assign {minstretl_cout, minstretl_inc[31:0]} = minstretl[31:0] + {31'b0,i0_valid_no_ebreak_ecall_wb} + {31'b0,i1_valid_wb};
|
assign {minstretl_cout, minstretl_inc[31:0]} = minstretl[31:0] + {31'b0,i0_valid_no_ebreak_ecall_wb} + {31'b0,i1_valid_wb};
|
||||||
|
|
||||||
assign minstret_enable = i0_valid_no_ebreak_ecall_wb | i1_valid_wb | wr_minstretl_wb;
|
assign minstret_enable = i0_valid_no_ebreak_ecall_wb | i1_valid_wb;
|
||||||
|
|
||||||
assign minstretl_ns[31:0] = wr_minstretl_wb ? dec_csr_wrdata_wb[31:0] : minstretl_inc[31:0];
|
assign minstretl_ns[31:0] = wr_minstretl_wb ? dec_csr_wrdata_wb[31:0] : minstretl_inc[31:0];
|
||||||
rvdffe #(32) minstretl_ff (.*, .en(minstret_enable), .din(minstretl_ns[31:0]), .dout(minstretl[31:0]));
|
rvdffe #(32) minstretl_ff (.*, .en(minstret_enable | wr_minstretl_wb), .din(minstretl_ns[31:0]), .dout(minstretl[31:0]));
|
||||||
logic minstret_enable_f;
|
logic minstret_enable_f;
|
||||||
rvdff #(2) minstretf_cout_ff (.*, .clk(free_clk), .din({minstret_enable, minstretl_cout & ~wr_minstreth_wb}), .dout({minstret_enable_f, minstretl_cout_f}));
|
rvdff #(2) minstretf_cout_ff (.*, .clk(free_clk), .din({minstret_enable, minstretl_cout & ~wr_minstreth_wb}), .dout({minstret_enable_f, minstretl_cout_f}));
|
||||||
|
|
||||||
|
@ -1405,7 +1416,7 @@ module dec_tlu_ctl
|
||||||
`define MPMC 12'h7c6
|
`define MPMC 12'h7c6
|
||||||
logic wr_mpmc_wb;
|
logic wr_mpmc_wb;
|
||||||
assign wr_mpmc_wb = dec_csr_wrdata_wb[0] & dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[11:0] == `MPMC);
|
assign wr_mpmc_wb = dec_csr_wrdata_wb[0] & dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[11:0] == `MPMC);
|
||||||
assign fw_halt_req = wr_mpmc_wb & ~internal_dbg_halt_mode_f;
|
assign fw_halt_req = wr_mpmc_wb & ~internal_dbg_halt_mode_f & ~interrupt_valid_wb;
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
// MICECT (I-Cache error counter/threshold)
|
// MICECT (I-Cache error counter/threshold)
|
||||||
|
@ -2484,7 +2495,7 @@ assign dec_csr_legal_d = ( dec_csr_any_unq_d &
|
||||||
assign dec_csr_rddata_d[31:0] = ( ({32{csr_misa}} & 32'h40001104) |
|
assign dec_csr_rddata_d[31:0] = ( ({32{csr_misa}} & 32'h40001104) |
|
||||||
({32{csr_mvendorid}} & 32'h00000045) |
|
({32{csr_mvendorid}} & 32'h00000045) |
|
||||||
({32{csr_marchid}} & 32'h0000000b) |
|
({32{csr_marchid}} & 32'h0000000b) |
|
||||||
({32{csr_mimpid}} & 32'h1) |
|
({32{csr_mimpid}} & 32'h2) |
|
||||||
({32{csr_mstatus}} & {19'b0, 2'b11, 3'b0, mstatus[1], 3'b0, mstatus[0], 3'b0}) |
|
({32{csr_mstatus}} & {19'b0, 2'b11, 3'b0, mstatus[1], 3'b0, mstatus[0], 3'b0}) |
|
||||||
({32{csr_mtvec}} & {mtvec[30:1], 1'b0, mtvec[0]}) |
|
({32{csr_mtvec}} & {mtvec[30:1], 1'b0, mtvec[0]}) |
|
||||||
({32{csr_mip}} & {1'b0, mip[3], 18'b0, mip[2], 3'b0, mip[1], 3'b0, mip[0], 3'b0}) |
|
({32{csr_mip}} & {1'b0, mip[3], 18'b0, mip[2], 3'b0, mip[1], 3'b0, mip[0], 3'b0}) |
|
||||||
|
|
|
@ -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};
|
||||||
|
|
|
@ -390,15 +390,21 @@ module ifu_mem_ctl
|
||||||
logic iccm_rd_ecc_single_err_ff ;
|
logic iccm_rd_ecc_single_err_ff ;
|
||||||
logic perr_state_en;
|
logic perr_state_en;
|
||||||
logic [7:0] fetch_mask, ic_fetch_mem_val, bp_mask, ic_bp_mem_mask, ic_fetch_val_mem_f2;
|
logic [7:0] fetch_mask, ic_fetch_mem_val, bp_mask, ic_bp_mem_mask, ic_fetch_val_mem_f2;
|
||||||
|
logic dma_iccm_rd_req_f1;
|
||||||
|
logic dma_iccm_rd_req_f2;
|
||||||
|
logic [3:0] iccm_single_ecc_error;
|
||||||
|
|
||||||
assign iccm_dma_sb_error = iccm_rd_ecc_single_err & ic_dma_active;
|
assign dma_iccm_rd_req_f1 = (dma_iccm_req & ~dma_mem_write) ;
|
||||||
|
rvdff #(1) dma_iccm_req_ff (.*, .clk(free_clk), .din (dma_iccm_rd_req_f1), .dout(dma_iccm_rd_req_f2));
|
||||||
|
|
||||||
|
assign iccm_dma_sb_error = (|iccm_single_ecc_error ) & dma_iccm_rd_req_f2;
|
||||||
|
|
||||||
|
|
||||||
typedef enum logic [2:0] {ERR_IDLE=3'b000, PERR_WFF=3'b001 , ECC_WFF=3'b010 , ECC_CORR=3'b011, DMA_SB_ERR=3'b100} perr_state_t;
|
typedef enum logic [2:0] {ERR_IDLE=3'b000, PERR_WFF=3'b001 , ECC_WFF=3'b010 , ECC_CORR=3'b011, DMA_SB_ERR=3'b100} perr_state_t;
|
||||||
perr_state_t perr_state, perr_nxtstate;
|
perr_state_t perr_state, perr_nxtstate;
|
||||||
|
|
||||||
|
|
||||||
assign ic_dma_active = iccm_correct_ecc | (perr_state == DMA_SB_ERR);
|
assign ic_dma_active = iccm_correct_ecc | (perr_state == DMA_SB_ERR) | (dec_tlu_flush_err_wb & (perr_state == ECC_WFF));
|
||||||
//////////////////////////////////// Create Miss State Machine ///////////////////////
|
//////////////////////////////////// Create Miss State Machine ///////////////////////
|
||||||
// Create Miss State Machine //
|
// Create Miss State Machine //
|
||||||
// Create Miss State Machine //
|
// Create Miss State Machine //
|
||||||
|
@ -474,7 +480,7 @@ module ifu_mem_ctl
|
||||||
assign ic_act_hit_f2 = (|ic_rd_hit[3:0]) & fetch_req_icache_f2 & ~reset_all_tags & (~miss_pending | (miss_state==HIT_U_MISS)) & ~sel_mb_addr_ff;
|
assign ic_act_hit_f2 = (|ic_rd_hit[3:0]) & fetch_req_icache_f2 & ~reset_all_tags & (~miss_pending | (miss_state==HIT_U_MISS)) & ~sel_mb_addr_ff;
|
||||||
assign ic_act_miss_f2 = (~(|ic_rd_hit[3:0]) | reset_all_tags) & fetch_req_icache_f2 & ~miss_pending & ~ifc_region_acc_fault_f2;
|
assign ic_act_miss_f2 = (~(|ic_rd_hit[3:0]) | reset_all_tags) & fetch_req_icache_f2 & ~miss_pending & ~ifc_region_acc_fault_f2;
|
||||||
assign ic_miss_under_miss_f2 = (~(|ic_rd_hit[3:0]) | reset_all_tags) & fetch_req_icache_f2 & (miss_state == HIT_U_MISS) ;
|
assign ic_miss_under_miss_f2 = (~(|ic_rd_hit[3:0]) | reset_all_tags) & fetch_req_icache_f2 & (miss_state == HIT_U_MISS) ;
|
||||||
assign ic_hit_f2 = ic_act_hit_f2 | ic_byp_hit_f2 | ic_iccm_hit_f2 | (ifc_region_acc_fault_f2 & ifc_fetch_req_f2);
|
assign ic_hit_f2 = ic_act_hit_f2 | ic_byp_hit_f2 | ic_iccm_hit_f2 | (ifc_region_acc_fault_f2 & ifc_fetch_req_f2 & ~((miss_state == CRIT_BYP_OK) | (miss_state == SCND_MISS)));
|
||||||
|
|
||||||
assign uncacheable_miss_in = sel_hold_imb ? uncacheable_miss_ff : ifc_fetch_uncacheable_f1 ;
|
assign uncacheable_miss_in = sel_hold_imb ? uncacheable_miss_ff : ifc_fetch_uncacheable_f1 ;
|
||||||
assign imb_in[31:1] = sel_hold_imb ? imb_ff[31:1] : {fetch_addr_f1[31:1]} ;
|
assign imb_in[31:1] = sel_hold_imb ? imb_ff[31:1] : {fetch_addr_f1[31:1]} ;
|
||||||
|
@ -866,7 +872,6 @@ logic ifu_icache_sb_error_val_ff ;
|
||||||
|
|
||||||
logic [3:0] [31:0] iccm_corrected_data;
|
logic [3:0] [31:0] iccm_corrected_data;
|
||||||
logic [3:0] [06:0] iccm_corrected_ecc;
|
logic [3:0] [06:0] iccm_corrected_ecc;
|
||||||
logic [3:0] iccm_single_ecc_error;
|
|
||||||
logic [3:0] iccm_double_ecc_error;
|
logic [3:0] iccm_double_ecc_error;
|
||||||
logic [3:0] iccm_ecc_word_enable;
|
logic [3:0] iccm_ecc_word_enable;
|
||||||
|
|
||||||
|
@ -931,6 +936,8 @@ assign iccm_rd_ecc_single_err_ff = 1'b0 ;
|
||||||
assign iccm_ecc_corr_index_ff[ICCM_BITS-1:2] = '0;
|
assign iccm_ecc_corr_index_ff[ICCM_BITS-1:2] = '0;
|
||||||
assign iccm_ecc_corr_data_ff[38:0] = '0;
|
assign iccm_ecc_corr_data_ff[38:0] = '0;
|
||||||
assign iccm_ecc_write_status = '0;
|
assign iccm_ecc_write_status = '0;
|
||||||
|
assign iccm_single_ecc_error = '0;
|
||||||
|
|
||||||
|
|
||||||
`endif
|
`endif
|
||||||
|
|
||||||
|
@ -1028,7 +1035,7 @@ assign axi_ifu_bus_clk_en = ifu_bus_clk_en ;
|
||||||
// assign ifu_axi_arvalid = ifc_axi_ic_req_ff2 & ~axi_cmd_rsp_pend;
|
// assign ifu_axi_arvalid = ifc_axi_ic_req_ff2 & ~axi_cmd_rsp_pend;
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
assign ifu_axi_arvalid = ifc_axi_ic_req_ff2 ;
|
assign ifu_axi_arvalid = ifc_axi_ic_req_ff2 ;
|
||||||
assign ifu_axi_arid[IFU_BUS_TAG-1:0] = IFU_BUS_TAG'(axi_new_rd_addr_count[2:0]);
|
assign ifu_axi_arid[IFU_BUS_TAG-1:0] = IFU_BUS_TAG'(axi_rd_addr_count[2:0]);
|
||||||
assign ifu_axi_araddr[31:0] = {ifu_ic_req_addr_f2[31:3],3'b0} ;
|
assign ifu_axi_araddr[31:0] = {ifu_ic_req_addr_f2[31:3],3'b0} ;
|
||||||
assign ifu_axi_rready = 1'b1;
|
assign ifu_axi_rready = 1'b1;
|
||||||
assign ifu_axi_arsize[2:0] = 3'b011;
|
assign ifu_axi_arsize[2:0] = 3'b011;
|
||||||
|
@ -1052,7 +1059,7 @@ assign axi_ifu_bus_clk_en = ifu_bus_clk_en ;
|
||||||
|
|
||||||
assign ifu_axi_arready_ff = ifu_axi_arready_unq_ff & axi_ifu_bus_clk_en_ff ;
|
assign ifu_axi_arready_ff = ifu_axi_arready_unq_ff & axi_ifu_bus_clk_en_ff ;
|
||||||
assign ifu_axi_rvalid_ff = ifu_axi_rvalid_unq_ff & axi_ifu_bus_clk_en_ff ;
|
assign ifu_axi_rvalid_ff = ifu_axi_rvalid_unq_ff & axi_ifu_bus_clk_en_ff ;
|
||||||
assign axi_cmd_sent = ifu_axi_arvalid_ff & ifu_axi_arready_ff & miss_pending;
|
assign axi_cmd_sent = ifu_axi_arvalid & ifu_axi_arready & miss_pending & axi_ifu_bus_clk_en;
|
||||||
assign axi_inc_data_beat_cnt = (axi_ifu_wr_en_new & ~axi_last_data_beat) ;
|
assign axi_inc_data_beat_cnt = (axi_ifu_wr_en_new & ~axi_last_data_beat) ;
|
||||||
assign axi_reset_data_beat_cnt = ic_act_miss_f2 | (axi_ifu_wr_en_new & axi_last_data_beat) ;
|
assign axi_reset_data_beat_cnt = ic_act_miss_f2 | (axi_ifu_wr_en_new & axi_last_data_beat) ;
|
||||||
assign axi_hold_data_beat_cnt = ~axi_inc_data_beat_cnt & ~axi_reset_data_beat_cnt ;
|
assign axi_hold_data_beat_cnt = ~axi_inc_data_beat_cnt & ~axi_reset_data_beat_cnt ;
|
||||||
|
@ -1070,7 +1077,7 @@ assign axi_ifu_bus_clk_en = ifu_bus_clk_en ;
|
||||||
|
|
||||||
assign axi_new_rd_addr_count[2:0] = ~miss_pending ? {imb_ff[5:4],1'b0} : axi_inc_rd_addr_cnt ? (axi_rd_addr_count[2:0] + 3'b001) : axi_rd_addr_count[2:0];
|
assign axi_new_rd_addr_count[2:0] = ~miss_pending ? {imb_ff[5:4],1'b0} : axi_inc_rd_addr_cnt ? (axi_rd_addr_count[2:0] + 3'b001) : axi_rd_addr_count[2:0];
|
||||||
|
|
||||||
rvdffs #(3) axi_rd_addr_ff (.*, .en(~axi_hold_rd_addr_cnt), .clk(free_clk), .din ({axi_new_rd_addr_count[2:0]}), .dout({axi_rd_addr_count[2:0]}));
|
rvdffs #(3) axi_rd_addr_ff (.*, .en(1'b1), .clk(axiclk_reset), .din ({axi_new_rd_addr_count[2:0]}), .dout({axi_rd_addr_count[2:0]}));
|
||||||
|
|
||||||
// command beat Count
|
// command beat Count
|
||||||
assign axi_inc_cmd_beat_cnt = ifu_axi_arvalid & ifu_axi_arready & miss_pending;
|
assign axi_inc_cmd_beat_cnt = ifu_axi_arvalid & ifu_axi_arready & miss_pending;
|
||||||
|
@ -1090,7 +1097,7 @@ assign axi_ifu_bus_clk_en = ifu_bus_clk_en ;
|
||||||
rvdff #(3) axi_cmd_beat_ff (.*, .clk(axiclk_reset), .din ({axi_new_cmd_beat_count[2:0]}),
|
rvdff #(3) axi_cmd_beat_ff (.*, .clk(axiclk_reset), .din ({axi_new_cmd_beat_count[2:0]}),
|
||||||
.dout({axi_cmd_beat_count[2:0]}));
|
.dout({axi_cmd_beat_count[2:0]}));
|
||||||
|
|
||||||
assign req_addr_count[2:0] = axi_new_rd_addr_count[2:0] ;
|
assign req_addr_count[2:0] = axi_rd_addr_count[2:0] ;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -1148,7 +1155,7 @@ assign axi_ifu_bus_clk_en = ifu_bus_clk_en ;
|
||||||
|
|
||||||
// assign ic_dma_active_in = ifc_dma_access_q_ok & dma_iccm_req ;
|
// assign ic_dma_active_in = ifc_dma_access_q_ok & dma_iccm_req ;
|
||||||
assign iccm_wren = (ifc_dma_access_q_ok & dma_iccm_req & dma_mem_write) | iccm_correct_ecc;
|
assign iccm_wren = (ifc_dma_access_q_ok & dma_iccm_req & dma_mem_write) | iccm_correct_ecc;
|
||||||
assign iccm_rden = (ifc_dma_access_q_ok & dma_iccm_req & ~dma_mem_write) | ifc_iccm_access_f1;
|
assign iccm_rden = (ifc_dma_access_q_ok & dma_iccm_req & ~dma_mem_write) | (ifc_iccm_access_f1 & ifc_fetch_req_f1);
|
||||||
assign iccm_dma_rden = (ifc_dma_access_q_ok & dma_iccm_req & ~dma_mem_write) ;
|
assign iccm_dma_rden = (ifc_dma_access_q_ok & dma_iccm_req & ~dma_mem_write) ;
|
||||||
assign iccm_wr_size[2:0] = {3{dma_iccm_req & dma_mem_write}} & dma_mem_sz[2:0] ;
|
assign iccm_wr_size[2:0] = {3{dma_iccm_req & dma_mem_write}} & dma_mem_sz[2:0] ;
|
||||||
|
|
||||||
|
|
|
@ -126,7 +126,7 @@ 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
|
||||||
|
@ -143,6 +143,7 @@ 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
|
||||||
|
|
|
@ -56,10 +56,12 @@ module lsu
|
||||||
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
|
||||||
|
|
||||||
|
|
|
@ -158,7 +158,8 @@ module lsu_addrcheck
|
||||||
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
|
||||||
|
|
|
@ -122,7 +122,7 @@ module lsu_dccm_ctl
|
||||||
|
|
||||||
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];
|
||||||
|
|
|
@ -60,6 +60,7 @@ module lsu_lsc_ctl
|
||||||
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,
|
||||||
|
|
||||||
|
@ -102,6 +103,7 @@ module lsu_lsc_ctl
|
||||||
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,
|
||||||
|
@ -199,9 +201,12 @@ module lsu_lsc_ctl
|
||||||
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;
|
||||||
|
|
|
@ -81,6 +81,7 @@ 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,
|
||||||
|
@ -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
|
||||||
|
@ -274,6 +275,7 @@ 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));
|
||||||
|
@ -396,6 +398,12 @@ 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
|
||||||
|
|
|
@ -179,7 +179,7 @@ rvsyncss #(TOTAL_INT-1) sync_inst
|
||||||
|
|
||||||
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
|
||||||
|
@ -256,6 +256,50 @@ end
|
||||||
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;
|
||||||
|
@ -263,86 +307,30 @@ end
|
||||||
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`
|
||||||
|
|
|
@ -25,6 +25,7 @@ module swerv
|
||||||
(
|
(
|
||||||
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,
|
||||||
|
@ -674,12 +675,14 @@ module swerv
|
||||||
logic [31:0] lsu_result_dc3;
|
logic [31:0] lsu_result_dc3;
|
||||||
logic [31:0] lsu_result_corr_dc4; // ECC corrected lsu load data
|
logic [31:0] lsu_result_corr_dc4; // ECC corrected lsu load data
|
||||||
lsu_error_pkt_t lsu_error_pkt_dc3;
|
lsu_error_pkt_t lsu_error_pkt_dc3;
|
||||||
|
logic lsu_single_ecc_error_incr; // Increment the counter for Single ECC error
|
||||||
logic lsu_freeze_external_ints_dc3;
|
logic lsu_freeze_external_ints_dc3;
|
||||||
logic lsu_imprecise_error_load_any;
|
logic lsu_imprecise_error_load_any;
|
||||||
logic lsu_imprecise_error_store_any;
|
logic lsu_imprecise_error_store_any;
|
||||||
logic [31:0] lsu_imprecise_error_addr_any;
|
logic [31:0] lsu_imprecise_error_addr_any;
|
||||||
logic lsu_load_stall_any; // This is for blocking stores
|
logic lsu_load_stall_any; // This is for blocking stores
|
||||||
logic lsu_store_stall_any; // This is for blocking stores
|
logic lsu_store_stall_any; // This is for blocking stores
|
||||||
|
logic lsu_load_ecc_stbuf_full_dc3; // Load with ecc error can't allocate to stbuf
|
||||||
logic lsu_idle_any;
|
logic lsu_idle_any;
|
||||||
logic lsu_halt_idle_any; // This is used to enter halt mode. Exclude DMA
|
logic lsu_halt_idle_any; // This is used to enter halt mode. Exclude DMA
|
||||||
|
|
||||||
|
@ -971,7 +974,6 @@ module swerv
|
||||||
.*
|
.*
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
// ----------------- DEBUG END -----------------------------
|
// ----------------- DEBUG END -----------------------------
|
||||||
|
|
||||||
assign core_rst_l = rst_l & (dbg_core_rst_l | scan_mode);
|
assign core_rst_l = rst_l & (dbg_core_rst_l | scan_mode);
|
||||||
|
@ -1313,3 +1315,4 @@ module swerv
|
||||||
|
|
||||||
|
|
||||||
endmodule // swerv
|
endmodule // swerv
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,7 @@ module swerv_wrapper
|
||||||
(
|
(
|
||||||
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,
|
||||||
|
@ -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
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
// 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,
|
||||||
|
@ -30,137 +31,165 @@ module ahb_sif (
|
||||||
output logic HREADYOUT,
|
output logic HREADYOUT,
|
||||||
output logic HRESP,
|
output logic HRESP,
|
||||||
output logic [63:0] HRDATA
|
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
|
||||||
|
csrw minstret, zero
|
||||||
|
csrw minstreth, zero
|
||||||
|
|
||||||
|
// Set up MTVEC - not expecting to use it though
|
||||||
|
li x1, RV_ICCM_SADR
|
||||||
|
csrw mtvec, x1
|
||||||
|
|
||||||
|
|
||||||
lui x5, 974848
|
// Enable Caches in MRAC
|
||||||
ori x5, x5, 0
|
li x1, 0x5f555555
|
||||||
csrrw x2, 0x305, x5
|
csrw 0x7c0, x1
|
||||||
|
|
||||||
|
// Load string from hw_data
|
||||||
|
// and write to stdout address
|
||||||
|
|
||||||
lui x6, 382293
|
li x3, STDOUT
|
||||||
ori x6, x6, 1365
|
la x4, hw_data
|
||||||
csrrw x1, 0x7c0, x6
|
|
||||||
|
|
||||||
|
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
|
||||||
lui x5, 0
|
.data
|
||||||
ori x5, x5, 0
|
hw_data:
|
||||||
csrrw x2, 0x7f8, x5
|
.ascii "----------------------------------\n"
|
||||||
|
.ascii "Hello World from SweRV EH1 @WDC !!\n"
|
||||||
|
.ascii "----------------------------------\n"
|
||||||
|
.byte 0
|
||||||
|
|
||||||
lui x5, 0
|
|
||||||
ori x5, x5, 0
|
|
||||||
csrrw x2, 0x7f9, x5
|
|
||||||
|
|
||||||
|
|
||||||
addi x0, x0, 0
|
|
||||||
lui x11, 853376
|
|
||||||
ori x9, x0, 'H'
|
|
||||||
sw x9, 0 (x11)
|
|
||||||
ori x9, x0, 'E'
|
|
||||||
sw x9, 0 (x11)
|
|
||||||
ori x9, x0, 'L'
|
|
||||||
sw x9, 0 (x11)
|
|
||||||
sw x9, 0 (x11)
|
|
||||||
ori x9, x0, 'O'
|
|
||||||
sw x9, 0 (x11)
|
|
||||||
ori x9, x0, ' '
|
|
||||||
sw x9, 0 (x11)
|
|
||||||
addi x9, x0, 'W'
|
|
||||||
sw x9, 0 (x11)
|
|
||||||
ori x9, x0, 'O'
|
|
||||||
sw x9, 0 (x11)
|
|
||||||
ori x9, x0, 'R'
|
|
||||||
sw x9, 0 (x11)
|
|
||||||
ori x9, x0, 'L'
|
|
||||||
sw x9, 0 (x11)
|
|
||||||
ori x9, x0, 'D'
|
|
||||||
sw x9, 0 (x11)
|
|
||||||
ori x9, x0, '!'
|
|
||||||
sw x9, 0 (x11)
|
|
||||||
ori x9, x0, 255
|
|
||||||
sw x9, 0 (x11)
|
|
||||||
addi x1,x0,0
|
|
||||||
|
|
||||||
finish:
|
|
||||||
addi x1,x1,1
|
|
||||||
jal x0, finish;
|
|
||||||
addi x0,x0,0
|
|
||||||
addi x0,x0,0
|
|
||||||
addi x0,x0,0
|
|
||||||
addi x0,x0,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; }
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
// 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.
|
||||||
|
@ -13,16 +13,14 @@
|
||||||
// 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.
|
||||||
//
|
//
|
||||||
`ifndef VERILATOR
|
`ifdef VERILATOR
|
||||||
module tb_top;
|
module tb_top ( input bit core_clk);
|
||||||
`else
|
`else
|
||||||
module tb_top ( input logic core_clk, input logic reset_l, output finished);
|
module tb_top;
|
||||||
`endif
|
bit core_clk;
|
||||||
|
|
||||||
`ifndef VERILATOR
|
|
||||||
logic reset_l;
|
|
||||||
logic core_clk;
|
|
||||||
`endif
|
`endif
|
||||||
|
logic rst_l;
|
||||||
|
logic porst_l;
|
||||||
logic nmi_int;
|
logic nmi_int;
|
||||||
|
|
||||||
logic [31:0] reset_vector;
|
logic [31:0] reset_vector;
|
||||||
|
@ -98,149 +96,300 @@ module tb_top ( input logic core_clk, input logic reset_l, output finished);
|
||||||
logic mpc_debug_run_ack;
|
logic mpc_debug_run_ack;
|
||||||
logic debug_brkpt_status;
|
logic debug_brkpt_status;
|
||||||
|
|
||||||
logic [31:0] cycleCnt ;
|
bit [31:0] cycleCnt;
|
||||||
logic mailbox_data_val;
|
logic mailbox_data_val;
|
||||||
`ifndef VERILATOR
|
|
||||||
logic finished;
|
|
||||||
`endif
|
|
||||||
|
|
||||||
wire dma_hready_out;
|
wire dma_hready_out;
|
||||||
integer commit_count;
|
int commit_count;
|
||||||
|
|
||||||
logic wb_valid[1:0];
|
logic wb_valid[1:0];
|
||||||
logic [4:0] wb_dest[1:0];
|
logic [4:0] wb_dest[1:0];
|
||||||
logic [31:0] wb_data[1:0];
|
logic [31:0] wb_data[1:0];
|
||||||
|
|
||||||
//assign mailbox_write = &{i_ahb_lsu.Write, i_ahb_lsu.Last_HADDR==32'hD0580000, i_ahb_lsu.HRESETn==1};
|
`ifdef RV_BUILD_AXI4
|
||||||
assign mailbox_write = i_ahb_lsu.mailbox_write;
|
//-------------------------- LSU AXI signals--------------------------
|
||||||
//assign mailbox_write = i_ahb_lsu.mailbox_write & !core_clk;
|
// AXI Write Channels
|
||||||
assign mailbox_data_val = (i_ahb_lsu.WriteData[7:0] > 8'h5) & (i_ahb_lsu.WriteData[7:0] < 8'h7f);
|
wire lsu_axi_awvalid;
|
||||||
|
wire lsu_axi_awready;
|
||||||
|
wire [`RV_LSU_BUS_TAG-1:0] lsu_axi_awid;
|
||||||
|
wire [31:0] lsu_axi_awaddr;
|
||||||
|
wire [3:0] lsu_axi_awregion;
|
||||||
|
wire [7:0] lsu_axi_awlen;
|
||||||
|
wire [2:0] lsu_axi_awsize;
|
||||||
|
wire [1:0] lsu_axi_awburst;
|
||||||
|
wire lsu_axi_awlock;
|
||||||
|
wire [3:0] lsu_axi_awcache;
|
||||||
|
wire [2:0] lsu_axi_awprot;
|
||||||
|
wire [3:0] lsu_axi_awqos;
|
||||||
|
|
||||||
assign finished = finished | &{i_ahb_lsu.mailbox_write, (i_ahb_lsu.WriteData[7:0] == 8'hff)};
|
wire lsu_axi_wvalid;
|
||||||
|
wire lsu_axi_wready;
|
||||||
|
wire [63:0] lsu_axi_wdata;
|
||||||
|
wire [7:0] lsu_axi_wstrb;
|
||||||
|
wire lsu_axi_wlast;
|
||||||
|
|
||||||
assign jtag_id[31:28] = 4'b1;
|
wire lsu_axi_bvalid;
|
||||||
assign jtag_id[27:12] = '0;
|
wire lsu_axi_bready;
|
||||||
assign jtag_id[11:1] = 11'h45;
|
wire [1:0] lsu_axi_bresp;
|
||||||
|
wire [`RV_LSU_BUS_TAG-1:0] lsu_axi_bid;
|
||||||
|
|
||||||
|
// AXI Read Channels
|
||||||
|
wire lsu_axi_arvalid;
|
||||||
|
wire lsu_axi_arready;
|
||||||
|
wire [`RV_LSU_BUS_TAG-1:0] lsu_axi_arid;
|
||||||
|
wire [31:0] lsu_axi_araddr;
|
||||||
|
wire [3:0] lsu_axi_arregion;
|
||||||
|
wire [7:0] lsu_axi_arlen;
|
||||||
|
wire [2:0] lsu_axi_arsize;
|
||||||
|
wire [1:0] lsu_axi_arburst;
|
||||||
|
wire lsu_axi_arlock;
|
||||||
|
wire [3:0] lsu_axi_arcache;
|
||||||
|
wire [2:0] lsu_axi_arprot;
|
||||||
|
wire [3:0] lsu_axi_arqos;
|
||||||
|
|
||||||
|
wire lsu_axi_rvalid;
|
||||||
|
wire lsu_axi_rready;
|
||||||
|
wire [`RV_LSU_BUS_TAG-1:0] lsu_axi_rid;
|
||||||
|
wire [63:0] lsu_axi_rdata;
|
||||||
|
wire [1:0] lsu_axi_rresp;
|
||||||
|
wire lsu_axi_rlast;
|
||||||
|
|
||||||
|
//-------------------------- IFU AXI signals--------------------------
|
||||||
|
// AXI Write Channels
|
||||||
|
wire ifu_axi_awvalid;
|
||||||
|
wire ifu_axi_awready;
|
||||||
|
wire [`RV_IFU_BUS_TAG-1:0] ifu_axi_awid;
|
||||||
|
wire [31:0] ifu_axi_awaddr;
|
||||||
|
wire [3:0] ifu_axi_awregion;
|
||||||
|
wire [7:0] ifu_axi_awlen;
|
||||||
|
wire [2:0] ifu_axi_awsize;
|
||||||
|
wire [1:0] ifu_axi_awburst;
|
||||||
|
wire ifu_axi_awlock;
|
||||||
|
wire [3:0] ifu_axi_awcache;
|
||||||
|
wire [2:0] ifu_axi_awprot;
|
||||||
|
wire [3:0] ifu_axi_awqos;
|
||||||
|
|
||||||
|
wire ifu_axi_wvalid;
|
||||||
|
wire ifu_axi_wready;
|
||||||
|
wire [63:0] ifu_axi_wdata;
|
||||||
|
wire [7:0] ifu_axi_wstrb;
|
||||||
|
wire ifu_axi_wlast;
|
||||||
|
|
||||||
|
wire ifu_axi_bvalid;
|
||||||
|
wire ifu_axi_bready;
|
||||||
|
wire [1:0] ifu_axi_bresp;
|
||||||
|
wire [`RV_IFU_BUS_TAG-1:0] ifu_axi_bid;
|
||||||
|
|
||||||
|
// AXI Read Channels
|
||||||
|
wire ifu_axi_arvalid;
|
||||||
|
wire ifu_axi_arready;
|
||||||
|
wire [`RV_IFU_BUS_TAG-1:0] ifu_axi_arid;
|
||||||
|
wire [31:0] ifu_axi_araddr;
|
||||||
|
wire [3:0] ifu_axi_arregion;
|
||||||
|
wire [7:0] ifu_axi_arlen;
|
||||||
|
wire [2:0] ifu_axi_arsize;
|
||||||
|
wire [1:0] ifu_axi_arburst;
|
||||||
|
wire ifu_axi_arlock;
|
||||||
|
wire [3:0] ifu_axi_arcache;
|
||||||
|
wire [2:0] ifu_axi_arprot;
|
||||||
|
wire [3:0] ifu_axi_arqos;
|
||||||
|
|
||||||
|
wire ifu_axi_rvalid;
|
||||||
|
wire ifu_axi_rready;
|
||||||
|
wire [`RV_IFU_BUS_TAG-1:0] ifu_axi_rid;
|
||||||
|
wire [63:0] ifu_axi_rdata;
|
||||||
|
wire [1:0] ifu_axi_rresp;
|
||||||
|
wire ifu_axi_rlast;
|
||||||
|
|
||||||
|
//-------------------------- SB AXI signals--------------------------
|
||||||
|
// AXI Write Channels
|
||||||
|
wire sb_axi_awvalid;
|
||||||
|
wire sb_axi_awready;
|
||||||
|
wire [`RV_SB_BUS_TAG-1:0] sb_axi_awid;
|
||||||
|
wire [31:0] sb_axi_awaddr;
|
||||||
|
wire [3:0] sb_axi_awregion;
|
||||||
|
wire [7:0] sb_axi_awlen;
|
||||||
|
wire [2:0] sb_axi_awsize;
|
||||||
|
wire [1:0] sb_axi_awburst;
|
||||||
|
wire sb_axi_awlock;
|
||||||
|
wire [3:0] sb_axi_awcache;
|
||||||
|
wire [2:0] sb_axi_awprot;
|
||||||
|
wire [3:0] sb_axi_awqos;
|
||||||
|
|
||||||
|
wire sb_axi_wvalid;
|
||||||
|
wire sb_axi_wready;
|
||||||
|
wire [63:0] sb_axi_wdata;
|
||||||
|
wire [7:0] sb_axi_wstrb;
|
||||||
|
wire sb_axi_wlast;
|
||||||
|
|
||||||
|
wire sb_axi_bvalid;
|
||||||
|
wire sb_axi_bready;
|
||||||
|
wire [1:0] sb_axi_bresp;
|
||||||
|
wire [`RV_SB_BUS_TAG-1:0] sb_axi_bid;
|
||||||
|
|
||||||
|
// AXI Read Channels
|
||||||
|
wire sb_axi_arvalid;
|
||||||
|
wire sb_axi_arready;
|
||||||
|
wire [`RV_SB_BUS_TAG-1:0] sb_axi_arid;
|
||||||
|
wire [31:0] sb_axi_araddr;
|
||||||
|
wire [3:0] sb_axi_arregion;
|
||||||
|
wire [7:0] sb_axi_arlen;
|
||||||
|
wire [2:0] sb_axi_arsize;
|
||||||
|
wire [1:0] sb_axi_arburst;
|
||||||
|
wire sb_axi_arlock;
|
||||||
|
wire [3:0] sb_axi_arcache;
|
||||||
|
wire [2:0] sb_axi_arprot;
|
||||||
|
wire [3:0] sb_axi_arqos;
|
||||||
|
|
||||||
|
wire sb_axi_rvalid;
|
||||||
|
wire sb_axi_rready;
|
||||||
|
wire [`RV_SB_BUS_TAG-1:0] sb_axi_rid;
|
||||||
|
wire [63:0] sb_axi_rdata;
|
||||||
|
wire [1:0] sb_axi_rresp;
|
||||||
|
wire sb_axi_rlast;
|
||||||
|
|
||||||
|
//-------------------------- DMA AXI signals--------------------------
|
||||||
|
// AXI Write Channels
|
||||||
|
wire dma_axi_awvalid;
|
||||||
|
wire dma_axi_awready;
|
||||||
|
wire [`RV_DMA_BUS_TAG-1:0] dma_axi_awid;
|
||||||
|
wire [31:0] dma_axi_awaddr;
|
||||||
|
wire [2:0] dma_axi_awsize;
|
||||||
|
wire [2:0] dma_axi_awprot;
|
||||||
|
wire [7:0] dma_axi_awlen;
|
||||||
|
wire [1:0] dma_axi_awburst;
|
||||||
|
|
||||||
|
|
||||||
|
wire dma_axi_wvalid;
|
||||||
|
wire dma_axi_wready;
|
||||||
|
wire [63:0] dma_axi_wdata;
|
||||||
|
wire [7:0] dma_axi_wstrb;
|
||||||
|
wire dma_axi_wlast;
|
||||||
|
|
||||||
|
wire dma_axi_bvalid;
|
||||||
|
wire dma_axi_bready;
|
||||||
|
wire [1:0] dma_axi_bresp;
|
||||||
|
wire [`RV_DMA_BUS_TAG-1:0] dma_axi_bid;
|
||||||
|
|
||||||
|
// AXI Read Channels
|
||||||
|
wire dma_axi_arvalid;
|
||||||
|
wire dma_axi_arready;
|
||||||
|
wire [`RV_DMA_BUS_TAG-1:0] dma_axi_arid;
|
||||||
|
wire [31:0] dma_axi_araddr;
|
||||||
|
wire [2:0] dma_axi_arsize;
|
||||||
|
wire [2:0] dma_axi_arprot;
|
||||||
|
wire [7:0] dma_axi_arlen;
|
||||||
|
wire [1:0] dma_axi_arburst;
|
||||||
|
|
||||||
|
wire dma_axi_rvalid;
|
||||||
|
wire dma_axi_rready;
|
||||||
|
wire [`RV_DMA_BUS_TAG-1:0] dma_axi_rid;
|
||||||
|
wire [63:0] dma_axi_rdata;
|
||||||
|
wire [1:0] dma_axi_rresp;
|
||||||
|
wire dma_axi_rlast;
|
||||||
|
|
||||||
`ifndef VERILATOR
|
|
||||||
`define FORCE force
|
|
||||||
`else
|
|
||||||
`define FORCE
|
|
||||||
`endif
|
`endif
|
||||||
|
wire[63:0] WriteData;
|
||||||
|
|
||||||
|
|
||||||
integer fd;
|
assign mailbox_write = lmem.mailbox_write;
|
||||||
initial begin
|
assign WriteData = lmem.WriteData;
|
||||||
fd = $fopen("console.log","w");
|
assign mailbox_data_val = WriteData[7:0] > 8'h5 && WriteData[7:0] < 8'h7f;
|
||||||
commit_count = 0;
|
|
||||||
end
|
|
||||||
|
|
||||||
integer tp,el;
|
parameter MAX_CYCLES = 10_000_000;
|
||||||
|
|
||||||
always @(posedge core_clk or negedge reset_l) begin
|
integer fd, tp, el;
|
||||||
if( reset_l == 0)
|
|
||||||
cycleCnt <= 0;
|
always @(negedge core_clk) begin
|
||||||
else
|
|
||||||
cycleCnt <= cycleCnt+1;
|
cycleCnt <= cycleCnt+1;
|
||||||
|
// Test timeout monitor
|
||||||
|
if(cycleCnt == MAX_CYCLES) begin
|
||||||
|
$display ("Hit max cycle count (%0d) .. stopping",cycleCnt);
|
||||||
|
$finish;
|
||||||
end
|
end
|
||||||
|
// cansol Monitor
|
||||||
always @(posedge core_clk) begin
|
if( mailbox_data_val & mailbox_write) begin
|
||||||
//if(cycleCnt == 32'h800)
|
$fwrite(fd,"%c", WriteData[7:0]);
|
||||||
if(cycleCnt == 32'h800) begin
|
$write("%c", WriteData[7:0]);
|
||||||
$display ("Hit max cycle count.. stopping");
|
end
|
||||||
|
// End Of test monitor
|
||||||
|
if(mailbox_write && WriteData[7:0] == 8'hff) begin
|
||||||
|
$display("\nFinished : minstret = %0d, mcycle = %0d", rvtop.swerv.dec.tlu.minstretl[31:0],rvtop.swerv.dec.tlu.mcyclel[31:0]);
|
||||||
|
$display("See \"exec.log\" for execution trace with register updates..\n");
|
||||||
|
$display("TEST_PASSED");
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
else if(mailbox_write && WriteData[7:0] == 8'h1) begin
|
||||||
|
$display("TEST_FAILED");
|
||||||
$finish;
|
$finish;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
`ifdef VERILATOR
|
// trace monitor
|
||||||
always @(negedge mailbox_write)
|
|
||||||
`else
|
|
||||||
always @(posedge mailbox_write)
|
|
||||||
`endif
|
|
||||||
if( mailbox_data_val ) begin
|
|
||||||
$fwrite(fd,"%c", i_ahb_lsu.WriteData[7:0]);
|
|
||||||
$write("%c", i_ahb_lsu.WriteData[7:0]);
|
|
||||||
end
|
|
||||||
|
|
||||||
always @(posedge finished) begin
|
|
||||||
$display("\n\nFinished : minstret = %0d, mcycle = %0d", rvtop.swerv.dec.tlu.minstretl[31:0],rvtop.swerv.dec.tlu.mcyclel[31:0]);
|
|
||||||
$display("\n\nSee \"exec.log\" for execution trace with register updates..\n");
|
|
||||||
`ifndef VERILATOR
|
|
||||||
$finish;
|
|
||||||
`endif
|
|
||||||
end
|
|
||||||
|
|
||||||
always @(posedge core_clk) begin
|
always @(posedge core_clk) begin
|
||||||
wb_valid[1:0] <= '{rvtop.swerv.dec.dec_i1_wen_wb & ~rvtop.swerv.dec.decode.dec_tlu_i1_kill_writeb_wb,
|
wb_valid[1:0] <= '{rvtop.swerv.dec.dec_i1_wen_wb, rvtop.swerv.dec.dec_i0_wen_wb};
|
||||||
rvtop.swerv.dec.decode.wbd.i0v & ~rvtop.swerv.dec.decode.dec_tlu_i0_kill_writeb_wb};
|
|
||||||
wb_dest[1:0] <= '{rvtop.swerv.dec.dec_i1_waddr_wb, rvtop.swerv.dec.dec_i0_waddr_wb};
|
wb_dest[1:0] <= '{rvtop.swerv.dec.dec_i1_waddr_wb, rvtop.swerv.dec.dec_i0_waddr_wb};
|
||||||
wb_data[1:0] <= '{rvtop.swerv.dec.dec_i1_wdata_wb, rvtop.swerv.dec.dec_i0_wdata_wb};
|
wb_data[1:0] <= '{rvtop.swerv.dec.dec_i1_wdata_wb, rvtop.swerv.dec.dec_i0_wdata_wb};
|
||||||
if (rvtop.trace_rv_i_valid_ip !== 0) begin
|
if (trace_rv_i_valid_ip !== 0) begin
|
||||||
$fwrite(tp,"%b,%h,%h,%0h,%0h,3,%b,%h,%h,%b\n", rvtop.trace_rv_i_valid_ip, rvtop.trace_rv_i_address_ip[63:32], rvtop.trace_rv_i_address_ip[31:0], rvtop.trace_rv_i_insn_ip[63:32], rvtop.trace_rv_i_insn_ip[31:0],rvtop.trace_rv_i_exception_ip,rvtop.trace_rv_i_ecause_ip,rvtop.trace_rv_i_tval_ip,rvtop.trace_rv_i_interrupt_ip);
|
$fwrite(tp,"%b,%h,%h,%0h,%0h,3,%b,%h,%h,%b\n", trace_rv_i_valid_ip, trace_rv_i_address_ip[63:32], trace_rv_i_address_ip[31:0],
|
||||||
|
trace_rv_i_insn_ip[63:32], trace_rv_i_insn_ip[31:0],trace_rv_i_exception_ip,trace_rv_i_ecause_ip,
|
||||||
|
trace_rv_i_tval_ip,trace_rv_i_interrupt_ip);
|
||||||
// Basic trace - no exception register updates
|
// Basic trace - no exception register updates
|
||||||
// #1 0 ee000000 b0201073 c 0b02 00000000
|
// #1 0 ee000000 b0201073 c 0b02 00000000
|
||||||
if (rvtop.trace_rv_i_valid_ip[0]==1) begin
|
for (int i=0; i<2; i++)
|
||||||
|
if (trace_rv_i_valid_ip[i]==1) begin
|
||||||
commit_count++;
|
commit_count++;
|
||||||
$fwrite (el, "%0d : #%0d 0 %0h %0h r %0d %0h\n",$time(), commit_count, rvtop.trace_rv_i_address_ip[31:0], rvtop.trace_rv_i_insn_ip[31:0], wb_dest[0], wb_data[0]);
|
$fwrite (el, "%10d : %6s 0 %h %h %s\n", cycleCnt, $sformatf("#%0d",commit_count),
|
||||||
end
|
trace_rv_i_address_ip[31+i*32 -:32], trace_rv_i_insn_ip[31+i*32-:32],
|
||||||
if (rvtop.trace_rv_i_valid_ip[1]==1) begin
|
wb_dest[i] !=0 ? $sformatf("r%0d=%h", wb_dest[i], wb_data[i]) : "");
|
||||||
commit_count ++;
|
|
||||||
$fwrite (el, "%0d : #%0d 0 0x%0h 0x%0h r %0d 0x%h\n",$time(), commit_count, rvtop.trace_rv_i_address_ip[63:32], rvtop.trace_rv_i_insn_ip[63:32], wb_dest[1], wb_data[1]);
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
initial begin
|
initial begin
|
||||||
|
// tie offs
|
||||||
`ifndef VERILATOR
|
jtag_id[31:28] = 4'b1;
|
||||||
core_clk = 0;
|
jtag_id[27:12] = '0;
|
||||||
reset_l = 0;
|
jtag_id[11:1] = 11'h45;
|
||||||
`endif
|
reset_vector = 32'h0;
|
||||||
|
|
||||||
reset_vector = 32'h80000000;
|
|
||||||
nmi_vector = 32'hee000000;
|
nmi_vector = 32'hee000000;
|
||||||
nmi_int = 0;
|
nmi_int = 0;
|
||||||
|
|
||||||
`ifndef VERILATOR
|
$readmemh("data.hex", lmem.mem);
|
||||||
@(posedge core_clk);
|
$readmemh("program.hex", imem.mem);
|
||||||
reset_l = 0;
|
|
||||||
`endif
|
|
||||||
|
|
||||||
$readmemh("data.hex", i_ahb_lsu.mem);
|
|
||||||
$readmemh("program.hex", i_ahb_ic.mem);
|
|
||||||
tp = $fopen("trace_port.csv","w");
|
tp = $fopen("trace_port.csv","w");
|
||||||
el = $fopen("exec.log","w");
|
el = $fopen("exec.log","w");
|
||||||
$fwrite (el, "//Time : #inst 0 pc opcode reg regnum value\n");
|
$fwrite (el, "//Cycle : #inst 0 pc opcode reg regnum value\n");
|
||||||
|
fd = $fopen("console.log","w");
|
||||||
|
commit_count = 0;
|
||||||
|
preload_dccm();
|
||||||
|
preload_iccm();
|
||||||
|
|
||||||
`ifndef VERILATOR
|
`ifndef VERILATOR
|
||||||
repeat (5) @(posedge core_clk);
|
if($test$plusargs("dumpon")) $dumpvars;
|
||||||
reset_l = 1;
|
forever core_clk = #5 ~core_clk;
|
||||||
#100000 $display("");$finish;
|
|
||||||
`endif
|
`endif
|
||||||
end
|
end
|
||||||
|
|
||||||
`ifndef VERILATOR
|
|
||||||
initial begin
|
assign rst_l = cycleCnt > 5;
|
||||||
forever begin
|
assign porst_l = cycleCnt >2;
|
||||||
core_clk = #5 ~core_clk;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
`endif
|
|
||||||
|
|
||||||
//=========================================================================-
|
//=========================================================================-
|
||||||
// RTL instance
|
// RTL instance
|
||||||
//=========================================================================-
|
//=========================================================================-
|
||||||
swerv_wrapper rvtop (
|
swerv_wrapper rvtop (
|
||||||
.rst_l ( reset_l ),
|
.rst_l ( rst_l ),
|
||||||
|
.dbg_rst_l ( porst_l ),
|
||||||
.clk ( core_clk ),
|
.clk ( core_clk ),
|
||||||
.rst_vec ( 31'h40000000 ),
|
.rst_vec ( reset_vector[31:1]),
|
||||||
.nmi_int ( nmi_int ),
|
.nmi_int ( nmi_int ),
|
||||||
.nmi_vec ( 31'h77000000 ),
|
.nmi_vec ( nmi_vector[31:1]),
|
||||||
.jtag_id ( jtag_id[31:1]),
|
.jtag_id ( jtag_id[31:1]),
|
||||||
|
|
||||||
|
`ifdef RV_BUILD_AHB_LITE
|
||||||
.haddr ( ic_haddr ),
|
.haddr ( ic_haddr ),
|
||||||
.hburst ( ic_hburst ),
|
.hburst ( ic_hburst ),
|
||||||
.hmastlock ( ic_hmastlock ),
|
.hmastlock ( ic_hmastlock ),
|
||||||
|
@ -269,7 +418,6 @@ end
|
||||||
.sb_hready ( sb_hready ),
|
.sb_hready ( sb_hready ),
|
||||||
.sb_hresp ( sb_hresp ),
|
.sb_hresp ( sb_hresp ),
|
||||||
|
|
||||||
|
|
||||||
//---------------------------------------------------------------
|
//---------------------------------------------------------------
|
||||||
// LSU AHB Master
|
// LSU AHB Master
|
||||||
//---------------------------------------------------------------
|
//---------------------------------------------------------------
|
||||||
|
@ -286,7 +434,6 @@ end
|
||||||
.lsu_hready ( lsu_hready ),
|
.lsu_hready ( lsu_hready ),
|
||||||
.lsu_hresp ( lsu_hresp ),
|
.lsu_hresp ( lsu_hresp ),
|
||||||
|
|
||||||
|
|
||||||
//---------------------------------------------------------------
|
//---------------------------------------------------------------
|
||||||
// DMA Slave
|
// DMA Slave
|
||||||
//---------------------------------------------------------------
|
//---------------------------------------------------------------
|
||||||
|
@ -304,20 +451,195 @@ end
|
||||||
.dma_hsel ( 1'b1 ),
|
.dma_hsel ( 1'b1 ),
|
||||||
.dma_hreadyin ( dma_hready_out ),
|
.dma_hreadyin ( dma_hready_out ),
|
||||||
.dma_hreadyout ( dma_hready_out ),
|
.dma_hreadyout ( dma_hready_out ),
|
||||||
|
|
||||||
.timer_int ( 1'b0 ),
|
|
||||||
`ifdef TB_RESTRUCT
|
|
||||||
.extintsrc_req ( '0 ),
|
|
||||||
`else
|
|
||||||
.extintsrc_req ( '0 ),
|
|
||||||
`endif
|
`endif
|
||||||
|
`ifdef RV_BUILD_AXI4
|
||||||
|
//-------------------------- LSU AXI signals--------------------------
|
||||||
|
// AXI Write Channels
|
||||||
|
.lsu_axi_awvalid (lsu_axi_awvalid),
|
||||||
|
.lsu_axi_awready (lsu_axi_awready),
|
||||||
|
.lsu_axi_awid (lsu_axi_awid),
|
||||||
|
.lsu_axi_awaddr (lsu_axi_awaddr),
|
||||||
|
.lsu_axi_awregion (lsu_axi_awregion),
|
||||||
|
.lsu_axi_awlen (lsu_axi_awlen),
|
||||||
|
.lsu_axi_awsize (lsu_axi_awsize),
|
||||||
|
.lsu_axi_awburst (lsu_axi_awburst),
|
||||||
|
.lsu_axi_awlock (lsu_axi_awlock),
|
||||||
|
.lsu_axi_awcache (lsu_axi_awcache),
|
||||||
|
.lsu_axi_awprot (lsu_axi_awprot),
|
||||||
|
.lsu_axi_awqos (lsu_axi_awqos),
|
||||||
|
|
||||||
|
.lsu_axi_wvalid (lsu_axi_wvalid),
|
||||||
|
.lsu_axi_wready (lsu_axi_wready),
|
||||||
|
.lsu_axi_wdata (lsu_axi_wdata),
|
||||||
|
.lsu_axi_wstrb (lsu_axi_wstrb),
|
||||||
|
.lsu_axi_wlast (lsu_axi_wlast),
|
||||||
|
|
||||||
|
.lsu_axi_bvalid (lsu_axi_bvalid),
|
||||||
|
.lsu_axi_bready (lsu_axi_bready),
|
||||||
|
.lsu_axi_bresp (lsu_axi_bresp),
|
||||||
|
.lsu_axi_bid (lsu_axi_bid),
|
||||||
|
|
||||||
|
|
||||||
|
.lsu_axi_arvalid (lsu_axi_arvalid),
|
||||||
|
.lsu_axi_arready (lsu_axi_arready),
|
||||||
|
.lsu_axi_arid (lsu_axi_arid),
|
||||||
|
.lsu_axi_araddr (lsu_axi_araddr),
|
||||||
|
.lsu_axi_arregion (lsu_axi_arregion),
|
||||||
|
.lsu_axi_arlen (lsu_axi_arlen),
|
||||||
|
.lsu_axi_arsize (lsu_axi_arsize),
|
||||||
|
.lsu_axi_arburst (lsu_axi_arburst),
|
||||||
|
.lsu_axi_arlock (lsu_axi_arlock),
|
||||||
|
.lsu_axi_arcache (lsu_axi_arcache),
|
||||||
|
.lsu_axi_arprot (lsu_axi_arprot),
|
||||||
|
.lsu_axi_arqos (lsu_axi_arqos),
|
||||||
|
|
||||||
|
.lsu_axi_rvalid (lsu_axi_rvalid),
|
||||||
|
.lsu_axi_rready (lsu_axi_rready),
|
||||||
|
.lsu_axi_rid (lsu_axi_rid),
|
||||||
|
.lsu_axi_rdata (lsu_axi_rdata),
|
||||||
|
.lsu_axi_rresp (lsu_axi_rresp),
|
||||||
|
.lsu_axi_rlast (lsu_axi_rlast),
|
||||||
|
|
||||||
|
//-------------------------- IFU AXI signals--------------------------
|
||||||
|
// AXI Write Channels
|
||||||
|
.ifu_axi_awvalid (ifu_axi_awvalid),
|
||||||
|
.ifu_axi_awready (ifu_axi_awready),
|
||||||
|
.ifu_axi_awid (ifu_axi_awid),
|
||||||
|
.ifu_axi_awaddr (ifu_axi_awaddr),
|
||||||
|
.ifu_axi_awregion (ifu_axi_awregion),
|
||||||
|
.ifu_axi_awlen (ifu_axi_awlen),
|
||||||
|
.ifu_axi_awsize (ifu_axi_awsize),
|
||||||
|
.ifu_axi_awburst (ifu_axi_awburst),
|
||||||
|
.ifu_axi_awlock (ifu_axi_awlock),
|
||||||
|
.ifu_axi_awcache (ifu_axi_awcache),
|
||||||
|
.ifu_axi_awprot (ifu_axi_awprot),
|
||||||
|
.ifu_axi_awqos (ifu_axi_awqos),
|
||||||
|
|
||||||
|
.ifu_axi_wvalid (ifu_axi_wvalid),
|
||||||
|
.ifu_axi_wready (ifu_axi_wready),
|
||||||
|
.ifu_axi_wdata (ifu_axi_wdata),
|
||||||
|
.ifu_axi_wstrb (ifu_axi_wstrb),
|
||||||
|
.ifu_axi_wlast (ifu_axi_wlast),
|
||||||
|
|
||||||
|
.ifu_axi_bvalid (ifu_axi_bvalid),
|
||||||
|
.ifu_axi_bready (ifu_axi_bready),
|
||||||
|
.ifu_axi_bresp (ifu_axi_bresp),
|
||||||
|
.ifu_axi_bid (ifu_axi_bid),
|
||||||
|
|
||||||
|
.ifu_axi_arvalid (ifu_axi_arvalid),
|
||||||
|
.ifu_axi_arready (ifu_axi_arready),
|
||||||
|
.ifu_axi_arid (ifu_axi_arid),
|
||||||
|
.ifu_axi_araddr (ifu_axi_araddr),
|
||||||
|
.ifu_axi_arregion (ifu_axi_arregion),
|
||||||
|
.ifu_axi_arlen (ifu_axi_arlen),
|
||||||
|
.ifu_axi_arsize (ifu_axi_arsize),
|
||||||
|
.ifu_axi_arburst (ifu_axi_arburst),
|
||||||
|
.ifu_axi_arlock (ifu_axi_arlock),
|
||||||
|
.ifu_axi_arcache (ifu_axi_arcache),
|
||||||
|
.ifu_axi_arprot (ifu_axi_arprot),
|
||||||
|
.ifu_axi_arqos (ifu_axi_arqos),
|
||||||
|
|
||||||
|
.ifu_axi_rvalid (ifu_axi_rvalid),
|
||||||
|
.ifu_axi_rready (ifu_axi_rready),
|
||||||
|
.ifu_axi_rid (ifu_axi_rid),
|
||||||
|
.ifu_axi_rdata (ifu_axi_rdata),
|
||||||
|
.ifu_axi_rresp (ifu_axi_rresp),
|
||||||
|
.ifu_axi_rlast (ifu_axi_rlast),
|
||||||
|
|
||||||
|
//-------------------------- SB AXI signals--------------------------
|
||||||
|
// AXI Write Channels
|
||||||
|
.sb_axi_awvalid (sb_axi_awvalid),
|
||||||
|
.sb_axi_awready (sb_axi_awready),
|
||||||
|
.sb_axi_awid (sb_axi_awid),
|
||||||
|
.sb_axi_awaddr (sb_axi_awaddr),
|
||||||
|
.sb_axi_awregion (sb_axi_awregion),
|
||||||
|
.sb_axi_awlen (sb_axi_awlen),
|
||||||
|
.sb_axi_awsize (sb_axi_awsize),
|
||||||
|
.sb_axi_awburst (sb_axi_awburst),
|
||||||
|
.sb_axi_awlock (sb_axi_awlock),
|
||||||
|
.sb_axi_awcache (sb_axi_awcache),
|
||||||
|
.sb_axi_awprot (sb_axi_awprot),
|
||||||
|
.sb_axi_awqos (sb_axi_awqos),
|
||||||
|
|
||||||
|
.sb_axi_wvalid (sb_axi_wvalid),
|
||||||
|
.sb_axi_wready (sb_axi_wready),
|
||||||
|
.sb_axi_wdata (sb_axi_wdata),
|
||||||
|
.sb_axi_wstrb (sb_axi_wstrb),
|
||||||
|
.sb_axi_wlast (sb_axi_wlast),
|
||||||
|
|
||||||
|
.sb_axi_bvalid (sb_axi_bvalid),
|
||||||
|
.sb_axi_bready (sb_axi_bready),
|
||||||
|
.sb_axi_bresp (sb_axi_bresp),
|
||||||
|
.sb_axi_bid (sb_axi_bid),
|
||||||
|
|
||||||
|
|
||||||
|
.sb_axi_arvalid (sb_axi_arvalid),
|
||||||
|
.sb_axi_arready (sb_axi_arready),
|
||||||
|
.sb_axi_arid (sb_axi_arid),
|
||||||
|
.sb_axi_araddr (sb_axi_araddr),
|
||||||
|
.sb_axi_arregion (sb_axi_arregion),
|
||||||
|
.sb_axi_arlen (sb_axi_arlen),
|
||||||
|
.sb_axi_arsize (sb_axi_arsize),
|
||||||
|
.sb_axi_arburst (sb_axi_arburst),
|
||||||
|
.sb_axi_arlock (sb_axi_arlock),
|
||||||
|
.sb_axi_arcache (sb_axi_arcache),
|
||||||
|
.sb_axi_arprot (sb_axi_arprot),
|
||||||
|
.sb_axi_arqos (sb_axi_arqos),
|
||||||
|
|
||||||
|
.sb_axi_rvalid (sb_axi_rvalid),
|
||||||
|
.sb_axi_rready (sb_axi_rready),
|
||||||
|
.sb_axi_rid (sb_axi_rid),
|
||||||
|
.sb_axi_rdata (sb_axi_rdata),
|
||||||
|
.sb_axi_rresp (sb_axi_rresp),
|
||||||
|
.sb_axi_rlast (sb_axi_rlast),
|
||||||
|
|
||||||
|
//-------------------------- DMA AXI signals--------------------------
|
||||||
|
// AXI Write Channels
|
||||||
|
.dma_axi_awvalid (1'b0),
|
||||||
|
.dma_axi_awready (dma_axi_awready),
|
||||||
|
.dma_axi_awid (dma_axi_awid),
|
||||||
|
.dma_axi_awaddr (dma_axi_awaddr),
|
||||||
|
.dma_axi_awsize (dma_axi_awsize),
|
||||||
|
.dma_axi_awprot (dma_axi_awprot),
|
||||||
|
.dma_axi_awlen (dma_axi_awlen),
|
||||||
|
.dma_axi_awburst (dma_axi_awburst),
|
||||||
|
|
||||||
|
|
||||||
|
.dma_axi_wvalid (1'b0),
|
||||||
|
.dma_axi_wready (dma_axi_wready),
|
||||||
|
.dma_axi_wdata (dma_axi_wdata),
|
||||||
|
.dma_axi_wstrb (dma_axi_wstrb),
|
||||||
|
.dma_axi_wlast (dma_axi_wlast),
|
||||||
|
|
||||||
|
.dma_axi_bvalid (dma_axi_bvalid),
|
||||||
|
.dma_axi_bready (1'b0),
|
||||||
|
.dma_axi_bresp (dma_axi_bresp),
|
||||||
|
.dma_axi_bid (dma_axi_bid),
|
||||||
|
|
||||||
|
|
||||||
|
.dma_axi_arvalid (1'b0),
|
||||||
|
.dma_axi_arready (dma_axi_arready),
|
||||||
|
.dma_axi_arid (dma_axi_arid),
|
||||||
|
.dma_axi_araddr (dma_axi_araddr),
|
||||||
|
.dma_axi_arsize (dma_axi_arsize),
|
||||||
|
.dma_axi_arprot (dma_axi_arprot),
|
||||||
|
.dma_axi_arlen (dma_axi_arlen),
|
||||||
|
.dma_axi_arburst (dma_axi_arburst),
|
||||||
|
|
||||||
|
.dma_axi_rvalid (dma_axi_rvalid),
|
||||||
|
.dma_axi_rready (1'b0),
|
||||||
|
.dma_axi_rid (dma_axi_rid),
|
||||||
|
.dma_axi_rdata (dma_axi_rdata),
|
||||||
|
.dma_axi_rresp (dma_axi_rresp),
|
||||||
|
.dma_axi_rlast (dma_axi_rlast),
|
||||||
|
`endif
|
||||||
|
.timer_int ( 1'b0 ),
|
||||||
|
.extintsrc_req ( '0 ),
|
||||||
|
|
||||||
`ifdef RV_BUILD_AHB_LITE
|
|
||||||
.lsu_bus_clk_en ( 1'b1 ),// Clock ratio b/w cpu core clk & AHB master interface
|
.lsu_bus_clk_en ( 1'b1 ),// Clock ratio b/w cpu core clk & AHB master interface
|
||||||
.ifu_bus_clk_en ( 1'b1 ),// Clock ratio b/w cpu core clk & AHB master interface
|
.ifu_bus_clk_en ( 1'b1 ),// Clock ratio b/w cpu core clk & AHB master interface
|
||||||
.dbg_bus_clk_en ( 1'b0 ),// Clock ratio b/w cpu core clk & AHB Debug master interface
|
.dbg_bus_clk_en ( 1'b1 ),// Clock ratio b/w cpu core clk & AHB Debug master interface
|
||||||
.dma_bus_clk_en ( 1'b0 ),// Clock ratio b/w cpu core clk & AHB slave interface
|
.dma_bus_clk_en ( 1'b1 ),// Clock ratio b/w cpu core clk & AHB slave interface
|
||||||
`endif
|
|
||||||
|
|
||||||
.trace_rv_i_insn_ip (trace_rv_i_insn_ip),
|
.trace_rv_i_insn_ip (trace_rv_i_insn_ip),
|
||||||
.trace_rv_i_address_ip (trace_rv_i_address_ip),
|
.trace_rv_i_address_ip (trace_rv_i_address_ip),
|
||||||
|
@ -327,15 +649,11 @@ end
|
||||||
.trace_rv_i_interrupt_ip(trace_rv_i_interrupt_ip),
|
.trace_rv_i_interrupt_ip(trace_rv_i_interrupt_ip),
|
||||||
.trace_rv_i_tval_ip (trace_rv_i_tval_ip),
|
.trace_rv_i_tval_ip (trace_rv_i_tval_ip),
|
||||||
|
|
||||||
|
.jtag_tck ( 1'b0 ),
|
||||||
|
.jtag_tms ( 1'b0 ),
|
||||||
|
.jtag_tdi ( 1'b0 ),
|
||||||
|
.jtag_trst_n ( 1'b0 ),
|
||||||
.jtag_tck ( 1'b0 ), // JTAG clk
|
.jtag_tdo ( jtag_tdo ),
|
||||||
.jtag_tms ( 1'b0 ), // JTAG TMS
|
|
||||||
.jtag_tdi ( 1'b0 ), // JTAG tdi
|
|
||||||
.jtag_trst_n ( 1'b0 ), // JTAG Reset
|
|
||||||
.jtag_tdo ( jtag_tdo ), // JTAG TDO
|
|
||||||
|
|
||||||
.mpc_debug_halt_ack ( mpc_debug_halt_ack),
|
.mpc_debug_halt_ack ( mpc_debug_halt_ack),
|
||||||
.mpc_debug_halt_req ( 1'b0),
|
.mpc_debug_halt_req ( 1'b0),
|
||||||
|
@ -361,18 +679,13 @@ end
|
||||||
|
|
||||||
);
|
);
|
||||||
|
|
||||||
initial begin
|
|
||||||
`FORCE rvtop.dccm_rd_data_hi = '0;
|
|
||||||
`FORCE rvtop.dccm_rd_data_lo = '0;
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
//=========================================================================-
|
//=========================================================================-
|
||||||
// AHB I$ instance
|
// AHB I$ instance
|
||||||
//=========================================================================-
|
//=========================================================================-
|
||||||
|
`ifdef RV_BUILD_AHB_LITE
|
||||||
|
|
||||||
ahb_sif i_ahb_ic (
|
ahb_sif imem (
|
||||||
|
|
||||||
// Inputs
|
// Inputs
|
||||||
.HWDATA(64'h0),
|
.HWDATA(64'h0),
|
||||||
.HCLK(core_clk),
|
.HCLK(core_clk),
|
||||||
|
@ -382,7 +695,7 @@ end
|
||||||
.HTRANS(ic_htrans),
|
.HTRANS(ic_htrans),
|
||||||
.HSIZE(ic_hsize),
|
.HSIZE(ic_hsize),
|
||||||
.HREADY(ic_hready),
|
.HREADY(ic_hready),
|
||||||
.HRESETn(reset_l),
|
.HRESETn(rst_l),
|
||||||
.HADDR(ic_haddr),
|
.HADDR(ic_haddr),
|
||||||
.HBURST(ic_hburst),
|
.HBURST(ic_hburst),
|
||||||
|
|
||||||
|
@ -390,12 +703,10 @@ end
|
||||||
.HREADYOUT(ic_hready),
|
.HREADYOUT(ic_hready),
|
||||||
.HRESP(ic_hresp),
|
.HRESP(ic_hresp),
|
||||||
.HRDATA(ic_hrdata[63:0])
|
.HRDATA(ic_hrdata[63:0])
|
||||||
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
ahb_sif i_ahb_lsu (
|
ahb_sif lmem (
|
||||||
|
|
||||||
// Inputs
|
// Inputs
|
||||||
.HWDATA(lsu_hwdata),
|
.HWDATA(lsu_hwdata),
|
||||||
.HCLK(core_clk),
|
.HCLK(core_clk),
|
||||||
|
@ -405,7 +716,7 @@ end
|
||||||
.HTRANS(lsu_htrans),
|
.HTRANS(lsu_htrans),
|
||||||
.HSIZE(lsu_hsize),
|
.HSIZE(lsu_hsize),
|
||||||
.HREADY(lsu_hready),
|
.HREADY(lsu_hready),
|
||||||
.HRESETn(reset_l),
|
.HRESETn(rst_l),
|
||||||
.HADDR(lsu_haddr),
|
.HADDR(lsu_haddr),
|
||||||
.HBURST(lsu_hburst),
|
.HBURST(lsu_hburst),
|
||||||
|
|
||||||
|
@ -413,30 +724,254 @@ end
|
||||||
.HREADYOUT(lsu_hready),
|
.HREADYOUT(lsu_hready),
|
||||||
.HRESP(lsu_hresp),
|
.HRESP(lsu_hresp),
|
||||||
.HRDATA(lsu_hrdata[63:0])
|
.HRDATA(lsu_hrdata[63:0])
|
||||||
|
|
||||||
);
|
);
|
||||||
|
|
||||||
ahb_sif i_ahb_sb (
|
`endif
|
||||||
|
`ifdef RV_BUILD_AXI4
|
||||||
|
axi_slv #(.TAGW(`RV_IFU_BUS_TAG)) imem(
|
||||||
|
.aclk(core_clk),
|
||||||
|
.rst_l(rst_l),
|
||||||
|
.arvalid(ifu_axi_arvalid),
|
||||||
|
.arready(ifu_axi_arready),
|
||||||
|
.araddr(ifu_axi_araddr),
|
||||||
|
.arid(ifu_axi_arid),
|
||||||
|
.arlen(ifu_axi_arlen),
|
||||||
|
.arburst(ifu_axi_arburst),
|
||||||
|
.arsize(ifu_axi_arsize),
|
||||||
|
|
||||||
// Inputs
|
.rvalid(ifu_axi_rvalid),
|
||||||
.HWDATA(sb_hwdata),
|
.rready(ifu_axi_rready),
|
||||||
.HCLK(core_clk),
|
.rdata(ifu_axi_rdata),
|
||||||
.HSEL(1'b1),
|
.rresp(ifu_axi_rresp),
|
||||||
.HPROT(sb_hprot),
|
.rid(ifu_axi_rid),
|
||||||
.HWRITE(sb_hwrite),
|
.rlast(ifu_axi_rlast),
|
||||||
.HTRANS(sb_htrans),
|
|
||||||
.HSIZE(sb_hsize),
|
|
||||||
.HREADY(1'b0),
|
|
||||||
.HRESETn(reset_l),
|
|
||||||
.HADDR(sb_haddr),
|
|
||||||
.HBURST(sb_hburst),
|
|
||||||
|
|
||||||
// Outputs
|
.awvalid(1'b0),
|
||||||
.HREADYOUT(sb_hready),
|
.awready(),
|
||||||
.HRESP(sb_hresp),
|
.awaddr('0),
|
||||||
.HRDATA(sb_hrdata[63:0])
|
.awid('0),
|
||||||
|
.awlen('0),
|
||||||
|
.awburst('0),
|
||||||
|
.awsize('0),
|
||||||
|
|
||||||
|
.wdata('0),
|
||||||
|
.wstrb('0),
|
||||||
|
.wvalid(1'b0),
|
||||||
|
.wready(),
|
||||||
|
|
||||||
|
.bvalid(),
|
||||||
|
.bready(1'b0),
|
||||||
|
.bresp(),
|
||||||
|
.bid()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
defparam lmem.TAGW =`RV_LSU_BUS_TAG;
|
||||||
|
|
||||||
|
//axi_slv #(.TAGW(`RV_LSU_BUS_TAG)) lmem(
|
||||||
|
axi_slv lmem(
|
||||||
|
.aclk(core_clk),
|
||||||
|
.rst_l(rst_l),
|
||||||
|
.arvalid(lsu_axi_arvalid),
|
||||||
|
.arready(lsu_axi_arready),
|
||||||
|
.araddr(lsu_axi_araddr),
|
||||||
|
.arid(lsu_axi_arid),
|
||||||
|
.arlen(lsu_axi_arlen),
|
||||||
|
.arburst(lsu_axi_arburst),
|
||||||
|
.arsize(lsu_axi_arsize),
|
||||||
|
|
||||||
|
.rvalid(lsu_axi_rvalid),
|
||||||
|
.rready(lsu_axi_rready),
|
||||||
|
.rdata(lsu_axi_rdata),
|
||||||
|
.rresp(lsu_axi_rresp),
|
||||||
|
.rid(lsu_axi_rid),
|
||||||
|
.rlast(lsu_axi_rlast),
|
||||||
|
|
||||||
|
.awvalid(lsu_axi_awvalid),
|
||||||
|
.awready(lsu_axi_awready),
|
||||||
|
.awaddr(lsu_axi_awaddr),
|
||||||
|
.awid(lsu_axi_awid),
|
||||||
|
.awlen(lsu_axi_awlen),
|
||||||
|
.awburst(lsu_axi_awburst),
|
||||||
|
.awsize(lsu_axi_awsize),
|
||||||
|
|
||||||
|
.wdata(lsu_axi_wdata),
|
||||||
|
.wstrb(lsu_axi_wstrb),
|
||||||
|
.wvalid(lsu_axi_wvalid),
|
||||||
|
.wready(lsu_axi_wready),
|
||||||
|
|
||||||
|
.bvalid(lsu_axi_bvalid),
|
||||||
|
.bready(lsu_axi_bready),
|
||||||
|
.bresp(lsu_axi_bresp),
|
||||||
|
.bid(lsu_axi_bid)
|
||||||
|
);
|
||||||
|
`endif
|
||||||
|
|
||||||
|
task preload_iccm;
|
||||||
|
bit[31:0] data;
|
||||||
|
bit[31:0] addr, eaddr, saddr, faddr;
|
||||||
|
int adr;
|
||||||
|
/*
|
||||||
|
addresses:
|
||||||
|
0xffec - ICCM start address to load
|
||||||
|
0xfff0 - ICCM end address to load
|
||||||
|
0xfff4 - imem start address
|
||||||
|
*/
|
||||||
|
|
||||||
|
addr = 'hffec;
|
||||||
|
saddr = {lmem.mem[addr+3],lmem.mem[addr+2],lmem.mem[addr+1],lmem.mem[addr]};
|
||||||
|
if ( (saddr < `RV_ICCM_SADR) || (saddr > `RV_ICCM_EADR)) return;
|
||||||
|
`ifndef RV_ICCM_ENABLE
|
||||||
|
$display("********************************************************");
|
||||||
|
$display("ICCM preload: there is no ICCM in SweRV, terminating !!!");
|
||||||
|
$display("********************************************************");
|
||||||
|
$finish;
|
||||||
|
`endif
|
||||||
|
addr = 'hfff0;
|
||||||
|
eaddr = {lmem.mem[addr+3],lmem.mem[addr+2],lmem.mem[addr+1],lmem.mem[addr]};
|
||||||
|
addr = 'hfff4;
|
||||||
|
faddr = {lmem.mem[addr+3],lmem.mem[addr+2],lmem.mem[addr+1],lmem.mem[addr]};
|
||||||
|
$display("ICCM pre-load from %h to %h", saddr, eaddr);
|
||||||
|
|
||||||
|
for(addr= saddr; addr <= eaddr; addr+=4) begin
|
||||||
|
adr = faddr & 'hffff;
|
||||||
|
data = {imem.mem[adr+3],imem.mem[adr+2],imem.mem[adr+1],imem.mem[adr]};
|
||||||
|
slam_iccm_ram(addr, data == 0 ? 0 : {riscv_ecc32(data),data});
|
||||||
|
faddr+=4;
|
||||||
|
end
|
||||||
|
|
||||||
|
endtask
|
||||||
|
|
||||||
|
|
||||||
|
task preload_dccm;
|
||||||
|
bit[31:0] data;
|
||||||
|
bit[31:0] addr, eaddr;
|
||||||
|
int adr;
|
||||||
|
/*
|
||||||
|
addresses:
|
||||||
|
0xfff8 - DCCM start address to load
|
||||||
|
0xfffc - ICCM end address to load
|
||||||
|
0x0 - lmem start addres to load from
|
||||||
|
*/
|
||||||
|
|
||||||
|
addr = 'hfff8;
|
||||||
|
eaddr = {lmem.mem[addr+3],lmem.mem[addr+2],lmem.mem[addr+1],lmem.mem[addr]};
|
||||||
|
if (eaddr != `RV_DCCM_SADR) return;
|
||||||
|
`ifndef RV_DCCM_ENABLE
|
||||||
|
$display("********************************************************");
|
||||||
|
$display("DCCM preload: there is no DCCM in SweRV, terminating !!!");
|
||||||
|
$display("********************************************************");
|
||||||
|
$finish;
|
||||||
|
`endif
|
||||||
|
addr = 'hfffc;
|
||||||
|
eaddr = {lmem.mem[addr+3],lmem.mem[addr+2],lmem.mem[addr+1],lmem.mem[addr]};
|
||||||
|
$display("DCCM pre-load from %h to %h", `RV_DCCM_SADR, eaddr);
|
||||||
|
|
||||||
|
for(addr=`RV_DCCM_SADR; addr <= eaddr; addr+=4) begin
|
||||||
|
adr = addr & 'hffff;
|
||||||
|
data = {lmem.mem[adr+3],lmem.mem[adr+2],lmem.mem[adr+1],lmem.mem[adr]};
|
||||||
|
slam_dccm_ram(addr, data == 0 ? 0 : {riscv_ecc32(data),data});
|
||||||
|
end
|
||||||
|
|
||||||
|
endtask
|
||||||
|
|
||||||
|
`define DRAM(bank) \
|
||||||
|
rvtop.mem.Gen_dccm_enable.dccm.mem_bank[bank].dccm_bank.ram_core
|
||||||
|
|
||||||
|
`define ICCM_PATH `RV_TOP.mem.iccm
|
||||||
|
`define IRAM0(bk) `ICCM_PATH.mem_bank[bk].iccm_bank_lo0.ram_core
|
||||||
|
`define IRAM1(bk) `ICCM_PATH.mem_bank[bk].iccm_bank_lo1.ram_core
|
||||||
|
`define IRAM2(bk) `ICCM_PATH.mem_bank[bk].iccm_bank_hi0.ram_core
|
||||||
|
`define IRAM3(bk) `ICCM_PATH.mem_bank[bk].iccm_bank_hi1.ram_core
|
||||||
|
|
||||||
|
|
||||||
|
task slam_iccm_ram(input [31:0] addr, input[38:0] data);
|
||||||
|
int bank, indx;
|
||||||
|
`ifdef RV_ICCM_ENABLE
|
||||||
|
bank = get_iccm_bank(addr, indx);
|
||||||
|
case(bank)
|
||||||
|
0: `IRAM0(0)[indx] = data;
|
||||||
|
1: `IRAM1(0)[indx] = data;
|
||||||
|
2: `IRAM2(0)[indx] = data;
|
||||||
|
3: `IRAM3(0)[indx] = data;
|
||||||
|
`ifdef RV_ICCM_NUM_BANKS_8
|
||||||
|
4: `IRAM0(1)[indx] = data;
|
||||||
|
5: `IRAM1(1)[indx] = data;
|
||||||
|
6: `IRAM2(1)[indx] = data;
|
||||||
|
7: `IRAM3(1)[indx] = data;
|
||||||
|
`endif
|
||||||
|
`ifdef RV_ICCM_NUM_BANKS_16
|
||||||
|
8: `IRAM0(2)[indx] = data;
|
||||||
|
9: `IRAM1(2)[indx] = data;
|
||||||
|
10: `IRAM2(2)[indx] = data;
|
||||||
|
11: `IRAM3(2)[indx] = data;
|
||||||
|
12: `IRAM0(3)[indx] = data;
|
||||||
|
13: `IRAM1(3)[indx] = data;
|
||||||
|
14: `IRAM2(3)[indx] = data;
|
||||||
|
15: `IRAM3(3)[indx] = data;
|
||||||
|
`endif
|
||||||
|
endcase
|
||||||
|
`endif
|
||||||
|
endtask
|
||||||
|
|
||||||
|
task slam_dccm_ram(input [31:0] addr, input[38:0] data);
|
||||||
|
int bank, indx;
|
||||||
|
`ifdef RV_DCCM_ENABLE
|
||||||
|
bank = get_dccm_bank(addr, indx);
|
||||||
|
case(bank)
|
||||||
|
0: `DRAM(0)[indx] = data;
|
||||||
|
1: `DRAM(1)[indx] = data;
|
||||||
|
`ifdef RV_DCCM_NUM_BANKS_4
|
||||||
|
2: `DRAM(2)[indx] = data;
|
||||||
|
3: `DRAM(3)[indx] = data;
|
||||||
|
`endif
|
||||||
|
`ifdef RV_DCCM_NUM_BANKS_8
|
||||||
|
2: `DRAM(2)[indx] = data;
|
||||||
|
3: `DRAM(3)[indx] = data;
|
||||||
|
4: `DRAM(4)[indx] = data;
|
||||||
|
5: `DRAM(5)[indx] = data;
|
||||||
|
6: `DRAM(6)[indx] = data;
|
||||||
|
7: `DRAM(7)[indx] = data;
|
||||||
|
`endif
|
||||||
|
endcase
|
||||||
|
`endif
|
||||||
|
endtask
|
||||||
|
|
||||||
|
function[6:0] riscv_ecc32(input[31:0] data);
|
||||||
|
reg[6:0] synd;
|
||||||
|
synd[0] = ^(data & 32'h56aa_ad5b);
|
||||||
|
synd[1] = ^(data & 32'h9b33_366d);
|
||||||
|
synd[2] = ^(data & 32'he3c3_c78e);
|
||||||
|
synd[3] = ^(data & 32'h03fc_07f0);
|
||||||
|
synd[4] = ^(data & 32'h03ff_f800);
|
||||||
|
synd[5] = ^(data & 32'hfc00_0000);
|
||||||
|
synd[6] = ^{data, synd[5:0]};
|
||||||
|
return synd;
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function int get_dccm_bank(input int addr, output int bank_idx);
|
||||||
|
`ifdef RV_DCCM_NUM_BANKS_2
|
||||||
|
bank_idx = int'(addr[`RV_DCCM_BITS-1:3]);
|
||||||
|
return int'( addr[2]);
|
||||||
|
`elsif RV_DCCM_NUM_BANKS_4
|
||||||
|
bank_idx = int'(addr[`RV_DCCM_BITS-1:4]);
|
||||||
|
return int'(addr[3:2]);
|
||||||
|
`elsif RV_DCCM_NUM_BANKS_8
|
||||||
|
bank_idx = int'(addr[`RV_DCCM_BITS-1:5]);
|
||||||
|
return int'( addr[4:2]);
|
||||||
|
`endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function int get_iccm_bank(input int addr, output int bank_idx);
|
||||||
|
`ifdef RV_ICCM_NUM_BANKS_4
|
||||||
|
bank_idx = int'(addr[`RV_ICCM_BITS-1:4]);
|
||||||
|
return int'( addr[3:2]);
|
||||||
|
`elsif RV_ICCM_NUM_BANKS_8
|
||||||
|
bank_idx = int'(addr[`RV_ICCM_BITS-1:5]);
|
||||||
|
return int'(addr[4:2]);
|
||||||
|
`else
|
||||||
|
bank_idx = int'(addr[`RV_ICCM_BITS-1:6]);
|
||||||
|
return int'( addr[5:2]);
|
||||||
|
`endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
|
@ -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);
|
||||||
|
if (dumpWaves)
|
||||||
tfp->open ("sim.vcd");
|
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) {
|
if (dumpWaves)
|
||||||
tfp->close();
|
tfp->close();
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
std::cout << "\nVerilatorTB: End of sim" << std::endl;
|
||||||
|
|
||||||
for(auto i=0; i<100; ++i){
|
|
||||||
clkCnt++;
|
|
||||||
for (auto clk=0; clk<2; clk++) {
|
|
||||||
tfp->dump (2*i+clk);
|
|
||||||
tb->core_clk = !tb->core_clk;
|
|
||||||
tb->eval();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::cout << "\nEnd of sim" << std::endl;
|
|
||||||
exit(EXIT_SUCCESS);
|
exit(EXIT_SUCCESS);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
176
tools/Makefile
176
tools/Makefile
|
@ -1,5 +1,5 @@
|
||||||
# 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.
|
||||||
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue