Merge branch 'master' into make_for_riviera

This commit is contained in:
danielmlynek 2020-02-25 16:53:53 +01:00 committed by GitHub
commit 0070c22195
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
95 changed files with 19538 additions and 7035 deletions

53
.gitignore vendored
View File

@ -1,7 +1,48 @@
configs/snapshots # Exclude/Ignore file for git
work
obj_dir
*.vcd
*.csv
*.hex
*.log *.log
RCS
*~
.*.swp
.*.swo
.DS_Store
*.[oa]
RCS/
snapshots/
.zenconfig
workspace/
workspace/work
# These are derived files
configs/common_defines.vh
configs/pd_defines.vh
configs/perl_configs.pl
configs/whisper.json
verif/diags/env/defines.h
design/include/pic_map_auto.h
design/include/pic_ctrl_verilator_unroll.sv
#codegenerators files
tools/codegenerators/AAPG/randomSeed.txt
tools/codegenerators/AAPG/aapg.pyc
tools/codegenerators/AAPG/baseInstructions.pyc
tools/codegenerators/AAPG/commonStuff.pyc
tools/codegenerators/AAPG/commonVar.pyc
tools/codegenerators/AAPG/config.pyc
tools/codegenerators/AAPG/opcodes.pyc
tools/codegenerators/AAPG/parseObjdump.pyc
tools/codegenerators/AAPG/result
tools/codegenerators/AAPG/standardExtensions.pyc
tools/codegenerators/csmith_run/platform.info
tools/codegenerators/csmith_run/syscalls.echx1
tools/codegenerators/csmith_run/syscalls.spike
tools/codegenerators/csmith_run/testdir_*
tools/codegenerators/riscv-torture/generator/target
tools/codegenerators/riscv-torture/project/target
tools/codegenerators/riscv-torture/testrun/target
verif/diags/C/csmith
verif/diags/reg
verif/vip/sdvt_ahb
tools/codegenerators/riscv-torture/output
tools/codegenerators/AAPG/randomSeed.txt
unit_level_testbench/pic/workspace/simulation/sim
tools/codegenerators/AAPGV2/swerv/asm/out*
tools/codegenerators/AAPGV2/swerv/bin/out*
tools/codegenerators/AAPGV2/swerv/objdump/out*

206
LICENSE
View File

@ -1,201 +1,69 @@
Apache License Apache License
Version 2.0, January 2004 Version 2.0, January 2004
http://www.apache.org/licenses/ http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions. 1. Definitions.
"License" shall mean the terms and conditions for use, reproduction, "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications, "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of 2. Grant of Copyright License.
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the 3. Grant of Patent License.
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices 4. Redistribution.
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its You must give any other recipients of the Work or Derivative Works a copy of this License; and
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and You must cause any modified files to carry prominent notices stating that You changed the files; and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise, You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory, 5. Submission of Contributions.
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS 6. Trademarks.
APPENDIX: How to apply the Apache License to your work. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
To apply the Apache License to your work, attach the following 7. Disclaimer of Warranty.
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner] Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
Licensed under the Apache License, Version 2.0 (the "License"); 8. Limitation of Liability.
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0 In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
Unless required by applicable law or agreed to in writing, software 9. Accepting Warranty or Additional Liability.
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
See the License for the specific language governing permissions and
limitations under the License.

167
README.md
View File

@ -1,7 +1,6 @@
# SweRV RISC-V Core<sup>TM</sup> 1.4 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.3 design RTL. The previous version can be found in [branch 1.3.](https://github.com/chipsalliance/Cores-SweRV/tree/branch1.3) This repository contains the SweRV EH1.5 Core<sup>TM</sup> design RTL
The SweRV 1 series provides a 32-bit, machine-mode only, implementation of the RISC-V ISA including options I (base integer), M (multiply/divide) and C (compressed instructions from I and M).
## License ## License
@ -13,24 +12,26 @@ Files under the [tools](tools/) directory may be available under a different lic
├── configs # Configurations Dir ├── configs # Configurations Dir
│   └── snapshots # Where generated configuration files are created │   └── snapshots # Where generated configuration files are created
├── design # Design root dir ├── design # Design root dir
│   ├── dbg # Debugger │   ├── dbg # Debugger
│   ├── dec # Decode, Registers and Exceptions │   ├── dec # Decode, Registers and Exceptions
│   ├── dmi # DMI block │   ├── dmi # DMI block
│   ├── exu # EXU (ALU/MUL/DIV) │   ├── exu # EXU (ALU/MUL/DIV)
│   ├── ifu # Fetch & Branch Prediction │   ├── ifu # Fetch & Branch Prediction
│   ├── include │   ├── include
│   ├── lib │   ├── lib
│   └── lsu # Load/Store │   └── lsu # Load/Store
├── docs ├── docs
├── tools # Scripts/Makefiles ├── tools # Scripts/Makefiles
└── testbench # (Very) simple testbench └── testbench # (Very) simple testbench
   ├── asm # Example assembly files    ├── asm # Example test files
   └── hex # Canned demo hex files    └── hex # Canned demo hex files
## Dependencies ## Dependencies
- Verilator **(3.926 or later)** must be installed on the system - Verilator **(4.020 or later)** must be installed on the system if running with verilator
- If adding/removing instructions, espresso must be installed. Espresso is a logic minimization tool used in *tools/coredecode*. - If adding/removing instructions, espresso must be installed (used by *tools/coredecode*)
- RISCV tool chain (based on gcc version 7.3 or higher) must be
installed so that it can be used to prepare RISCV binaries to run.
## Quickstart guide ## Quickstart guide
1. Clone the repository 1. Clone the repository
@ -47,14 +48,17 @@ SweRV can be configured by running the `$RV_ROOT/configs/swerv.config` script:
`% $RV_ROOT/configs/swerv.config -h` for detailed help options `% $RV_ROOT/configs/swerv.config -h` for detailed help options
For example to build with a DCCM of size 64 : For example to build with a DCCM of size 64 Kb:
`% $RV_ROOT/configs/swerv.config -dccm_size=64` `% $RV_ROOT/configs/swerv.config -dccm_size=64`
This will update the **default** snapshot in $RV_ROOT/configs/snapshots/default/ with parameters for a 64K DCCM. This will update the **default** snapshot in $PWD/snapshots/default/ with parameters for a 64K DCCM. To **unset** a parameter, use `-unset=PARAM` option to swerv.config.
Add `-snapshot=dccm64`, for example, if you wish to name your build snapshot *dccm64* and refer to it during the build. Add `-snapshot=dccm64`, for example, if you wish to name your build snapshot *dccm64* and refer to it during the build.
There are four predefined target configurations: `default`, `default_ahb`, `default_pd`, `high_perf` that can be selected via
the `-target=name` option to swerv.config.
This script derives the following consistent set of include files : This script derives the following consistent set of include files :
$RV_ROOT/configs/snapshots/default $RV_ROOT/configs/snapshots/default
@ -62,75 +66,134 @@ This script derives the following consistent set of include files :
├── defines.h # #defines for C/assembly headers ├── defines.h # #defines for C/assembly headers
├── pd_defines.vh # `defines for physical design ├── pd_defines.vh # `defines for physical design
├── perl_configs.pl # Perl %configs hash for scripting ├── perl_configs.pl # Perl %configs hash for scripting
├── pic_ctrl_verilator_unroll.sv # Unrolled verilog based on PIC size
├── pic_map_auto.h # PIC memory map based on configure size ├── pic_map_auto.h # PIC memory map based on configure size
└── whisper.json # JSON file for swerv-iss └── whisper.json # JSON file for swerv-iss
### Building a model ### Building a model
1. Set the RV_ROOT environment variable to the root of the SweRV directory structure
`RV_ROOT = /path/to/swerv` while in a work directory:
`export RV_ROOT`
1. Create your configuration 1. Set the RV_ROOT environment variable to the root of the SweRV directory structure.
Example for bash shell:
`export RV_ROOT=/path/to/swerv`
Example for csh or its derivatives:
`setenv RV_ROOT /path/to/swerv`
1. Create your specific configuration
*(Skip if default is sufficient)* *(Skip if default is sufficient)*
*(Name your snapshot to distinguish it from the default. Without an explicit name, it will update/override the **default** snapshot)* *(Name your snapshot to distinguish it from the default. Without an explicit name, it will update/override the __default__ snapshot)*
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.

View File

@ -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.

View File

@ -1,170 +0,0 @@
// NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE
// This is an automatically generated file by joseph.rahmeh on Tue Oct 15 13:13:16 PDT 2019
//
// cmd: swerv -snapshot=default -ahb_lite
//
`define RV_INST_ACCESS_MASK5 'hffffffff
`define RV_DATA_ACCESS_ENABLE4 1'h0
`define RV_INST_ACCESS_ENABLE3 1'h0
`define RV_INST_ACCESS_ENABLE0 1'h0
`define RV_INST_ACCESS_MASK3 'hffffffff
`define RV_DATA_ACCESS_ENABLE5 1'h0
`define RV_DATA_ACCESS_MASK5 'hffffffff
`define RV_DATA_ACCESS_ADDR3 'h00000000
`define RV_INST_ACCESS_ENABLE7 1'h0
`define RV_DATA_ACCESS_ADDR6 'h00000000
`define RV_INST_ACCESS_MASK7 'hffffffff
`define RV_INST_ACCESS_ENABLE6 1'h0
`define RV_INST_ACCESS_ENABLE5 1'h0
`define RV_DATA_ACCESS_ADDR4 'h00000000
`define RV_DATA_ACCESS_ADDR7 'h00000000
`define RV_DATA_ACCESS_MASK3 'hffffffff
`define RV_INST_ACCESS_MASK4 'hffffffff
`define RV_DATA_ACCESS_ADDR1 'h00000000
`define RV_INST_ACCESS_ADDR4 'h00000000
`define RV_INST_ACCESS_ADDR3 'h00000000
`define RV_DATA_ACCESS_ENABLE1 1'h0
`define RV_DATA_ACCESS_ADDR0 'h00000000
`define RV_DATA_ACCESS_MASK0 'hffffffff
`define RV_DATA_ACCESS_MASK6 'hffffffff
`define RV_INST_ACCESS_ADDR7 'h00000000
`define RV_INST_ACCESS_MASK0 'hffffffff
`define RV_DATA_ACCESS_ADDR5 'h00000000
`define RV_DATA_ACCESS_ADDR2 'h00000000
`define RV_DATA_ACCESS_MASK4 'hffffffff
`define RV_DATA_ACCESS_MASK1 'hffffffff
`define RV_INST_ACCESS_ADDR0 'h00000000
`define RV_INST_ACCESS_ADDR2 'h00000000
`define RV_DATA_ACCESS_ENABLE0 1'h0
`define RV_DATA_ACCESS_ENABLE2 1'h0
`define RV_DATA_ACCESS_ENABLE7 1'h0
`define RV_INST_ACCESS_ENABLE4 1'h0
`define RV_DATA_ACCESS_MASK7 'hffffffff
`define RV_INST_ACCESS_ADDR5 'h00000000
`define RV_INST_ACCESS_ENABLE1 1'h0
`define RV_DATA_ACCESS_MASK2 'hffffffff
`define RV_INST_ACCESS_MASK6 'hffffffff
`define RV_DATA_ACCESS_ENABLE3 1'h0
`define RV_INST_ACCESS_ADDR6 'h00000000
`define RV_INST_ACCESS_MASK2 'hffffffff
`define RV_INST_ACCESS_ENABLE2 1'h0
`define RV_DATA_ACCESS_ENABLE6 1'h0
`define RV_INST_ACCESS_ADDR1 'h00000000
`define RV_INST_ACCESS_MASK1 'hffffffff
`define RV_DEC_INSTBUF_DEPTH 4
`define RV_DMA_BUF_DEPTH 4
`define RV_LSU_NUM_NBLOAD 8
`define RV_LSU_STBUF_DEPTH 8
`define RV_LSU_NUM_NBLOAD_WIDTH 3
`define RV_IFU_BUS_TAG 3
`define RV_LSU_BUS_TAG 4
`define RV_SB_BUS_TAG 1
`define RV_DMA_BUS_TAG 1
`define RV_DCCM_WIDTH_BITS 2
`define RV_DCCM_REGION 4'hf
`define RV_DCCM_RESERVED 'h1000
`define RV_DCCM_SIZE 64
`define RV_DCCM_DATA_WIDTH 32
`define RV_DCCM_NUM_BANKS_8
`define RV_DCCM_FDATA_WIDTH 39
`define RV_DCCM_BYTE_WIDTH 4
`define RV_DCCM_DATA_CELL ram_2048x39
`define RV_DCCM_ENABLE 1
`define RV_DCCM_BITS 16
`define RV_DCCM_OFFSET 28'h40000
`define RV_DCCM_ECC_WIDTH 7
`define RV_DCCM_SIZE_64
`define RV_DCCM_ROWS 2048
`define RV_DCCM_BANK_BITS 3
`define RV_DCCM_NUM_BANKS 8
`define RV_DCCM_INDEX_BITS 11
`define RV_LSU_SB_BITS 16
`define RV_DCCM_EADR 32'hf004ffff
`define RV_DCCM_SADR 32'hf0040000
`define RV_RESET_VEC 'h80000000
`define RV_RET_STACK_SIZE 4
`define RV_XLEN 32
`define RV_TARGET default
`define RV_BTB_BTAG_FOLD 1
`define RV_BTB_INDEX3_HI 9
`define RV_BTB_INDEX1_LO 4
`define RV_BTB_ADDR_HI 5
`define RV_BTB_ADDR_LO 4
`define RV_BTB_INDEX1_HI 5
`define RV_BTB_INDEX2_HI 7
`define RV_BTB_INDEX2_LO 6
`define RV_BTB_ARRAY_DEPTH 4
`define RV_BTB_BTAG_SIZE 9
`define RV_BTB_SIZE 32
`define RV_BTB_INDEX3_LO 8
`define RV_ICCM_NUM_BANKS 8
`define RV_ICCM_BITS 19
`define RV_ICCM_BANK_BITS 3
`define RV_ICCM_ROWS 16384
`define RV_ICCM_OFFSET 10'he000000
`define RV_ICCM_REGION 4'he
`define RV_ICCM_SADR 32'hee000000
`define RV_ICCM_RESERVED 'h1000
`define RV_ICCM_DATA_CELL ram_16384x39
`define RV_ICCM_INDEX_BITS 14
`define RV_ICCM_NUM_BANKS_8
`define RV_ICCM_SIZE 512
`define RV_ICCM_EADR 32'hee07ffff
`define RV_ICCM_SIZE_512
`define RV_ICACHE_SIZE 16
`define RV_ICACHE_TAG_HIGH 12
`define RV_ICACHE_IC_ROWS 256
`define RV_ICACHE_TADDR_HIGH 5
`define RV_ICACHE_TAG_LOW 6
`define RV_ICACHE_TAG_CELL ram_64x21
`define RV_ICACHE_IC_DEPTH 8
`define RV_ICACHE_IC_INDEX 8
`define RV_ICACHE_ENABLE 1
`define RV_ICACHE_DATA_CELL ram_256x34
`define RV_ICACHE_TAG_DEPTH 64
`define RV_EXTERNAL_PROG 'hb0000000
`define RV_EXTERNAL_DATA_1 'h00000000
`define RV_DEBUG_SB_MEM 'hb0580000
`define RV_EXTERNAL_DATA 'hc0580000
`define RV_SERIALIO 'hd0580000
`define RV_NMI_VEC 'h11110000
`define RV_BHT_HASH_STRING {ghr[3:2] ^ {ghr[3+1], {4-1-2{1'b0} } },hashin[5:4]^ghr[2-1:0]}
`define RV_BHT_ADDR_HI 7
`define RV_BHT_GHR_RANGE 4:0
`define RV_BHT_GHR_SIZE 5
`define RV_BHT_GHR_PAD2 fghr[4:3],2'b0
`define RV_BHT_SIZE 128
`define RV_BHT_ADDR_LO 4
`define RV_BHT_ARRAY_DEPTH 16
`define RV_BHT_GHR_PAD fghr[4],3'b0
`define RV_NUMIREGS 32
`define RV_PIC_BITS 15
`define RV_PIC_REGION 4'hf
`define RV_PIC_INT_WORDS 1
`define RV_PIC_TOTAL_INT_PLUS1 9
`define RV_PIC_MEIP_OFFSET 'h1000
`define RV_PIC_BASE_ADDR 32'hf00c0000
`define RV_PIC_MEIGWCTRL_OFFSET 'h4000
`define RV_PIC_MEIPL_OFFSET 'h0000
`define RV_PIC_TOTAL_INT 8
`define RV_PIC_SIZE 32
`define RV_PIC_MEIE_OFFSET 'h2000
`define RV_PIC_OFFSET 10'hc0000
`define RV_PIC_MEIPT_OFFSET 'h3004
`define RV_PIC_MPICCFG_OFFSET 'h3000
`define RV_PIC_MEIGWCLR_OFFSET 'h5000
`define CLOCK_PERIOD 100
`define CPU_TOP `RV_TOP.swerv
`define TOP tb_top
`define RV_BUILD_AHB_LITE 1
`define RV_TOP `TOP.rvtop
`define DATAWIDTH 64
`define RV_STERR_ROLLBACK 0
`define RV_EXT_ADDRWIDTH 32
`define RV_EXT_DATAWIDTH 64
`define SDVT_AHB 1
`define RV_LDERR_ROLLBACK 1
`define ASSERT_ON
`define TEC_RV_ICG clockhdr
`define REGWIDTH 32
`undef ASSERT_ON

View File

@ -1,132 +0,0 @@
// NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE
// This is an automatically generated file by joseph.rahmeh on Tue Oct 15 13:13:16 PDT 2019
//
// cmd: swerv -snapshot=default -ahb_lite
//
#define RV_INST_ACCESS_MASK5 0xffffffff
#define RV_DATA_ACCESS_ENABLE4 0x0
#define RV_INST_ACCESS_ENABLE3 0x0
#define RV_INST_ACCESS_ENABLE0 0x0
#define RV_INST_ACCESS_MASK3 0xffffffff
#define RV_DATA_ACCESS_ENABLE5 0x0
#define RV_DATA_ACCESS_MASK5 0xffffffff
#define RV_DATA_ACCESS_ADDR3 0x00000000
#define RV_INST_ACCESS_ENABLE7 0x0
#define RV_DATA_ACCESS_ADDR6 0x00000000
#define RV_INST_ACCESS_MASK7 0xffffffff
#define RV_INST_ACCESS_ENABLE6 0x0
#define RV_INST_ACCESS_ENABLE5 0x0
#define RV_DATA_ACCESS_ADDR4 0x00000000
#define RV_DATA_ACCESS_ADDR7 0x00000000
#define RV_DATA_ACCESS_MASK3 0xffffffff
#define RV_INST_ACCESS_MASK4 0xffffffff
#define RV_DATA_ACCESS_ADDR1 0x00000000
#define RV_INST_ACCESS_ADDR4 0x00000000
#define RV_INST_ACCESS_ADDR3 0x00000000
#define RV_DATA_ACCESS_ENABLE1 0x0
#define RV_DATA_ACCESS_ADDR0 0x00000000
#define RV_DATA_ACCESS_MASK0 0xffffffff
#define RV_DATA_ACCESS_MASK6 0xffffffff
#define RV_INST_ACCESS_ADDR7 0x00000000
#define RV_INST_ACCESS_MASK0 0xffffffff
#define RV_DATA_ACCESS_ADDR5 0x00000000
#define RV_DATA_ACCESS_ADDR2 0x00000000
#define RV_DATA_ACCESS_MASK4 0xffffffff
#define RV_DATA_ACCESS_MASK1 0xffffffff
#define RV_INST_ACCESS_ADDR0 0x00000000
#define RV_INST_ACCESS_ADDR2 0x00000000
#define RV_DATA_ACCESS_ENABLE0 0x0
#define RV_DATA_ACCESS_ENABLE2 0x0
#define RV_DATA_ACCESS_ENABLE7 0x0
#define RV_INST_ACCESS_ENABLE4 0x0
#define RV_DATA_ACCESS_MASK7 0xffffffff
#define RV_INST_ACCESS_ADDR5 0x00000000
#define RV_INST_ACCESS_ENABLE1 0x0
#define RV_DATA_ACCESS_MASK2 0xffffffff
#define RV_INST_ACCESS_MASK6 0xffffffff
#define RV_DATA_ACCESS_ENABLE3 0x0
#define RV_INST_ACCESS_ADDR6 0x00000000
#define RV_INST_ACCESS_MASK2 0xffffffff
#define RV_INST_ACCESS_ENABLE2 0x0
#define RV_DATA_ACCESS_ENABLE6 0x0
#define RV_INST_ACCESS_ADDR1 0x00000000
#define RV_INST_ACCESS_MASK1 0xffffffff
#define RV_IFU_BUS_TAG 3
#define RV_LSU_BUS_TAG 4
#define RV_SB_BUS_TAG 1
#define RV_DMA_BUS_TAG 1
#define RV_DCCM_WIDTH_BITS 2
#define RV_DCCM_REGION 0xf
#define RV_DCCM_RESERVED 0x1000
#define RV_DCCM_SIZE 64
#define RV_DCCM_DATA_WIDTH 32
#define RV_DCCM_NUM_BANKS_8
#define RV_DCCM_FDATA_WIDTH 39
#define RV_DCCM_BYTE_WIDTH 4
#define RV_DCCM_DATA_CELL ram_2048x39
#define RV_DCCM_ENABLE 1
#define RV_DCCM_BITS 16
#define RV_DCCM_OFFSET 0x40000
#define RV_DCCM_ECC_WIDTH 7
#define RV_DCCM_SIZE_64
#define RV_DCCM_ROWS 2048
#define RV_DCCM_BANK_BITS 3
#define RV_DCCM_NUM_BANKS 8
#define RV_DCCM_INDEX_BITS 11
#define RV_LSU_SB_BITS 16
#define RV_DCCM_EADR 0xf004ffff
#define RV_DCCM_SADR 0xf0040000
#ifndef RV_RESET_VEC
#define RV_RESET_VEC 0x80000000
#endif
#define RV_XLEN 32
#define RV_TARGET default
#define RV_ICCM_NUM_BANKS 8
#define RV_ICCM_BITS 19
#define RV_ICCM_BANK_BITS 3
#define RV_ICCM_ROWS 16384
#define RV_ICCM_OFFSET 0xe000000
#define RV_ICCM_REGION 0xe
#define RV_ICCM_SADR 0xee000000
#define RV_ICCM_RESERVED 0x1000
#define RV_ICCM_DATA_CELL ram_16384x39
#define RV_ICCM_INDEX_BITS 14
#define RV_ICCM_NUM_BANKS_8
#define RV_ICCM_SIZE 512
#define RV_ICCM_EADR 0xee07ffff
#define RV_ICCM_SIZE_512
#define RV_EXTERNAL_PROG 0xb0000000
#define RV_EXTERNAL_DATA_1 0x00000000
#define RV_DEBUG_SB_MEM 0xb0580000
#define RV_EXTERNAL_DATA 0xc0580000
#define RV_SERIALIO 0xd0580000
#ifndef RV_NMI_VEC
#define RV_NMI_VEC 0x11110000
#endif
#define RV_PIC_BITS 15
#define RV_PIC_REGION 0xf
#define RV_PIC_INT_WORDS 1
#define RV_PIC_TOTAL_INT_PLUS1 9
#define RV_PIC_MEIP_OFFSET 0x1000
#define RV_PIC_BASE_ADDR 0xf00c0000
#define RV_PIC_MEIGWCTRL_OFFSET 0x4000
#define RV_PIC_MEIPL_OFFSET 0x0000
#define RV_PIC_TOTAL_INT 8
#define RV_PIC_SIZE 32
#define RV_PIC_MEIE_OFFSET 0x2000
#define RV_PIC_OFFSET 0xc0000
#define RV_PIC_MEIPT_OFFSET 0x3004
#define RV_PIC_MPICCFG_OFFSET 0x3000
#define RV_PIC_MEIGWCLR_OFFSET 0x5000
#define CLOCK_PERIOD 100
#define CPU_TOP `RV_TOP.swerv
#define TOP tb_top
#define RV_BUILD_AHB_LITE 1
#define RV_TOP `TOP.rvtop
#define DATAWIDTH 64
#define RV_STERR_ROLLBACK 0
#define RV_EXT_ADDRWIDTH 32
#define RV_EXT_DATAWIDTH 64
#define SDVT_AHB 1
#define RV_LDERR_ROLLBACK 1
#define ASSERT_ON

View File

@ -1,11 +0,0 @@
// NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE
// This is an automatically generated file by joseph.rahmeh on Tue Oct 15 13:13:16 PDT 2019
//
// cmd: swerv -snapshot=default -ahb_lite
//
`include "common_defines.vh"
`undef ASSERT_ON
`undef TEC_RV_ICG
`define TEC_RV_ICG CKLNQD12BWP35P140
`define PHYSICAL 1

View File

@ -1,566 +0,0 @@
# NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE
# This is an automatically generated file by joseph.rahmeh on Tue Oct 15 13:13:16 PDT 2019
#
# cmd: swerv -snapshot=default -ahb_lite
#
# To use this in a perf script, use 'require $RV_ROOT/configs/config.pl'
# Reference the hash via $config{name}..
%config = (
'protection' => {
'inst_access_mask5' => '0xffffffff',
'data_access_enable4' => '0x0',
'inst_access_enable3' => '0x0',
'inst_access_enable0' => '0x0',
'inst_access_mask3' => '0xffffffff',
'data_access_enable5' => '0x0',
'data_access_mask5' => '0xffffffff',
'data_access_addr3' => '0x00000000',
'inst_access_enable7' => '0x0',
'data_access_addr6' => '0x00000000',
'inst_access_mask7' => '0xffffffff',
'inst_access_enable6' => '0x0',
'inst_access_enable5' => '0x0',
'data_access_addr4' => '0x00000000',
'data_access_addr7' => '0x00000000',
'data_access_mask3' => '0xffffffff',
'inst_access_mask4' => '0xffffffff',
'data_access_addr1' => '0x00000000',
'inst_access_addr4' => '0x00000000',
'inst_access_addr3' => '0x00000000',
'data_access_enable1' => '0x0',
'data_access_addr0' => '0x00000000',
'data_access_mask0' => '0xffffffff',
'data_access_mask6' => '0xffffffff',
'inst_access_addr7' => '0x00000000',
'inst_access_mask0' => '0xffffffff',
'data_access_addr5' => '0x00000000',
'data_access_addr2' => '0x00000000',
'data_access_mask4' => '0xffffffff',
'data_access_mask1' => '0xffffffff',
'inst_access_addr0' => '0x00000000',
'inst_access_addr2' => '0x00000000',
'data_access_enable0' => '0x0',
'data_access_enable2' => '0x0',
'data_access_enable7' => '0x0',
'inst_access_enable4' => '0x0',
'data_access_mask7' => '0xffffffff',
'inst_access_addr5' => '0x00000000',
'inst_access_enable1' => '0x0',
'data_access_mask2' => '0xffffffff',
'inst_access_mask6' => '0xffffffff',
'data_access_enable3' => '0x0',
'inst_access_addr6' => '0x00000000',
'inst_access_mask2' => '0xffffffff',
'inst_access_enable2' => '0x0',
'data_access_enable6' => '0x0',
'inst_access_addr1' => '0x00000000',
'inst_access_mask1' => '0xffffffff'
},
'core' => {
'dec_instbuf_depth' => '4',
'dma_buf_depth' => '4',
'lsu_num_nbload' => '8',
'lsu_stbuf_depth' => '8',
'lsu_num_nbload_width' => '3'
},
'bus' => {
'ifu_bus_tag' => '3',
'lsu_bus_tag' => 4,
'sb_bus_tag' => '1',
'dma_bus_tag' => '1'
},
'dccm' => {
'dccm_width_bits' => 2,
'dccm_region' => '0xf',
'dccm_reserved' => '0x1000',
'dccm_size' => 64,
'dccm_data_width' => 32,
'dccm_num_banks_8' => '',
'dccm_fdata_width' => 39,
'dccm_byte_width' => '4',
'dccm_data_cell' => 'ram_2048x39',
'dccm_enable' => '1',
'dccm_bits' => 16,
'dccm_offset' => '0x40000',
'dccm_ecc_width' => 7,
'dccm_size_64' => '',
'dccm_rows' => '2048',
'dccm_bank_bits' => 3,
'dccm_num_banks' => '8',
'dccm_index_bits' => 11,
'lsu_sb_bits' => 16,
'dccm_eadr' => '0xf004ffff',
'dccm_sadr' => '0xf0040000'
},
'reset_vec' => '0x80000000',
'retstack' => {
'ret_stack_size' => '4'
},
'triggers' => [
{
'poke_mask' => [
'0x081818c7',
'0xffffffff',
'0x00000000'
],
'reset' => [
'0x23e00000',
'0x00000000',
'0x00000000'
],
'mask' => [
'0x081818c7',
'0xffffffff',
'0x00000000'
]
},
{
'poke_mask' => [
'0x081818c7',
'0xffffffff',
'0x00000000'
],
'reset' => [
'0x23e00000',
'0x00000000',
'0x00000000'
],
'mask' => [
'0x081818c7',
'0xffffffff',
'0x00000000'
]
},
{
'poke_mask' => [
'0x081818c7',
'0xffffffff',
'0x00000000'
],
'reset' => [
'0x23e00000',
'0x00000000',
'0x00000000'
],
'mask' => [
'0x081818c7',
'0xffffffff',
'0x00000000'
]
},
{
'poke_mask' => [
'0x081818c7',
'0xffffffff',
'0x00000000'
],
'reset' => [
'0x23e00000',
'0x00000000',
'0x00000000'
],
'mask' => [
'0x081818c7',
'0xffffffff',
'0x00000000'
]
}
],
'xlen' => 32,
'verilator' => '',
'target' => 'default',
'max_mmode_perf_event' => '50',
'btb' => {
'btb_btag_fold' => 1,
'btb_index3_hi' => 9,
'btb_index1_lo' => '4',
'btb_addr_hi' => 5,
'btb_addr_lo' => '4',
'btb_index1_hi' => 5,
'btb_index2_hi' => 7,
'btb_index2_lo' => 6,
'btb_array_depth' => 4,
'btb_btag_size' => 9,
'btb_size' => 32,
'btb_index3_lo' => 8
},
'iccm' => {
'iccm_num_banks' => '8',
'iccm_bits' => 19,
'iccm_bank_bits' => 3,
'iccm_rows' => '16384',
'iccm_offset' => '0xe000000',
'iccm_region' => '0xe',
'iccm_sadr' => '0xee000000',
'iccm_reserved' => '0x1000',
'iccm_data_cell' => 'ram_16384x39',
'iccm_index_bits' => 14,
'iccm_num_banks_8' => '',
'iccm_size' => 512,
'iccm_eadr' => '0xee07ffff',
'iccm_size_512' => ''
},
'icache' => {
'icache_size' => 16,
'icache_tag_high' => 12,
'icache_ic_rows' => '256',
'icache_taddr_high' => 5,
'icache_tag_low' => '6',
'icache_tag_cell' => 'ram_64x21',
'icache_ic_depth' => 8,
'icache_ic_index' => 8,
'icache_enable' => '1',
'icache_data_cell' => 'ram_256x34',
'icache_tag_depth' => 64
},
'physical' => '1',
'memmap' => {
'external_prog' => '0xb0000000',
'external_data_1' => '0x00000000',
'debug_sb_mem' => '0xb0580000',
'external_data' => '0xc0580000',
'serialio' => '0xd0580000'
},
'nmi_vec' => '0x11110000',
'num_mmode_perf_regs' => '4',
'bht' => {
'bht_hash_string' => '{ghr[3:2] ^ {ghr[3+1], {4-1-2{1\'b0} } },hashin[5:4]^ghr[2-1:0]}',
'bht_addr_hi' => 7,
'bht_ghr_range' => '4:0',
'bht_ghr_size' => 5,
'bht_ghr_pad2' => 'fghr[4:3],2\'b0',
'bht_size' => 128,
'bht_addr_lo' => '4',
'bht_array_depth' => 16,
'bht_ghr_pad' => 'fghr[4],3\'b0'
},
'numiregs' => '32',
'even_odd_trigger_chains' => 'true',
'pic' => {
'pic_bits' => 15,
'pic_region' => '0xf',
'pic_int_words' => 1,
'pic_total_int_plus1' => 9,
'pic_meip_offset' => '0x1000',
'pic_base_addr' => '0xf00c0000',
'pic_meigwctrl_offset' => '0x4000',
'pic_meipl_offset' => '0x0000',
'pic_total_int' => 8,
'pic_size' => 32,
'pic_meie_offset' => '0x2000',
'pic_offset' => '0xc0000',
'pic_meipt_offset' => '0x3004',
'pic_mpiccfg_offset' => '0x3000',
'pic_meigwclr_offset' => '0x5000'
},
'testbench' => {
'clock_period' => '100',
'CPU_TOP' => '`RV_TOP.swerv',
'TOP' => 'tb_top',
'build_ahb_lite' => '1',
'RV_TOP' => '`TOP.rvtop',
'datawidth' => '64',
'sterr_rollback' => '0',
'ext_addrwidth' => '32',
'ext_datawidth' => '64',
'SDVT_AHB' => '1',
'lderr_rollback' => '1',
'assert_on' => ''
},
'tec_rv_icg' => 'clockhdr',
'csr' => {
'pmpaddr9' => {
'exists' => 'false'
},
'dicad1' => {
'reset' => '0x0',
'number' => '0x7ca',
'comment' => 'Cache diagnostics.',
'debug' => 'true',
'exists' => 'true',
'mask' => '0x3'
},
'pmpcfg0' => {
'exists' => 'false'
},
'mhpmcounter4h' => {
'reset' => '0x0',
'exists' => 'true',
'mask' => '0xffffffff'
},
'dicago' => {
'reset' => '0x0',
'number' => '0x7cb',
'comment' => 'Cache diagnostics.',
'debug' => 'true',
'exists' => 'true',
'mask' => '0x0'
},
'mie' => {
'reset' => '0x0',
'exists' => 'true',
'mask' => '0x40000888'
},
'misa' => {
'reset' => '0x40001104',
'exists' => 'true',
'mask' => '0x0'
},
'mhpmcounter6h' => {
'reset' => '0x0',
'exists' => 'true',
'mask' => '0xffffffff'
},
'meicpct' => {
'reset' => '0x0',
'number' => '0xbca',
'comment' => 'External claim id/priority capture.',
'exists' => 'true',
'mask' => '0x0'
},
'mimpid' => {
'reset' => '0x1',
'exists' => 'true',
'mask' => '0x0'
},
'mcpc' => {
'reset' => '0x0',
'number' => '0x7c2',
'exists' => 'true',
'mask' => '0x0'
},
'mhpmevent4' => {
'reset' => '0x0',
'exists' => 'true',
'mask' => '0xffffffff'
},
'pmpaddr8' => {
'exists' => 'false'
},
'pmpcfg3' => {
'exists' => 'false'
},
'marchid' => {
'reset' => '0x0000000b',
'exists' => 'true',
'mask' => '0x0'
},
'pmpaddr5' => {
'exists' => 'false'
},
'mfdc' => {
'reset' => '0x00070000',
'number' => '0x7f9',
'exists' => 'true',
'mask' => '0x000707ff'
},
'mhpmevent6' => {
'reset' => '0x0',
'exists' => 'true',
'mask' => '0xffffffff'
},
'mvendorid' => {
'reset' => '0x45',
'exists' => 'true',
'mask' => '0x0'
},
'pmpaddr4' => {
'exists' => 'false'
},
'dcsr' => {
'poke_mask' => '0x00008dcc',
'reset' => '0x40000003',
'exists' => 'true',
'mask' => '0x00008c04'
},
'cycle' => {
'exists' => 'false'
},
'pmpaddr12' => {
'exists' => 'false'
},
'pmpaddr3' => {
'exists' => 'false'
},
'mhpmcounter3h' => {
'reset' => '0x0',
'exists' => 'true',
'mask' => '0xffffffff'
},
'time' => {
'exists' => 'false'
},
'meicidpl' => {
'reset' => '0x0',
'number' => '0xbcb',
'comment' => 'External interrupt claim id priority level.',
'exists' => 'true',
'mask' => '0xf'
},
'pmpaddr14' => {
'exists' => 'false'
},
'pmpaddr13' => {
'exists' => 'false'
},
'pmpaddr1' => {
'exists' => 'false'
},
'mhpmcounter6' => {
'reset' => '0x0',
'exists' => 'true',
'mask' => '0xffffffff'
},
'dicad0' => {
'reset' => '0x0',
'number' => '0x7c9',
'comment' => 'Cache diagnostics.',
'debug' => 'true',
'exists' => 'true',
'mask' => '0xffffffff'
},
'meipt' => {
'reset' => '0x0',
'number' => '0xbc9',
'comment' => 'External interrupt priority threshold.',
'exists' => 'true',
'mask' => '0xf'
},
'pmpaddr15' => {
'exists' => 'false'
},
'mhpmcounter5' => {
'reset' => '0x0',
'exists' => 'true',
'mask' => '0xffffffff'
},
'pmpcfg1' => {
'exists' => 'false'
},
'pmpaddr10' => {
'exists' => 'false'
},
'pmpaddr0' => {
'exists' => 'false'
},
'pmpcfg2' => {
'exists' => 'false'
},
'pmpaddr2' => {
'exists' => 'false'
},
'mpmc' => {
'reset' => '0x0',
'number' => '0x7c6',
'comment' => 'Core pause: Implemented as read only.',
'exists' => 'true',
'mask' => '0x0'
},
'dmst' => {
'reset' => '0x0',
'number' => '0x7c4',
'comment' => 'Memory synch trigger: Flush caches in debug mode.',
'debug' => 'true',
'exists' => 'true',
'mask' => '0x0'
},
'instret' => {
'exists' => 'false'
},
'mhpmevent3' => {
'reset' => '0x0',
'exists' => 'true',
'mask' => '0xffffffff'
},
'dicawics' => {
'reset' => '0x0',
'number' => '0x7c8',
'comment' => 'Cache diagnostics.',
'debug' => 'true',
'exists' => 'true',
'mask' => '0x0130fffc'
},
'mip' => {
'poke_mask' => '0x40000888',
'reset' => '0x0',
'exists' => 'true',
'mask' => '0x0'
},
'mhpmcounter5h' => {
'reset' => '0x0',
'exists' => 'true',
'mask' => '0xffffffff'
},
'micect' => {
'reset' => '0x0',
'number' => '0x7f0',
'exists' => 'true',
'mask' => '0xffffffff'
},
'miccmect' => {
'reset' => '0x0',
'number' => '0x7f1',
'exists' => 'true',
'mask' => '0xffffffff'
},
'mhpmevent5' => {
'reset' => '0x0',
'exists' => 'true',
'mask' => '0xffffffff'
},
'mhpmcounter3' => {
'reset' => '0x0',
'exists' => 'true',
'mask' => '0xffffffff'
},
'pmpaddr6' => {
'exists' => 'false'
},
'pmpaddr11' => {
'exists' => 'false'
},
'mcgc' => {
'poke_mask' => '0x000001ff',
'reset' => '0x0',
'number' => '0x7f8',
'exists' => 'true',
'mask' => '0x000001ff'
},
'mhpmcounter4' => {
'reset' => '0x0',
'exists' => 'true',
'mask' => '0xffffffff'
},
'mdccmect' => {
'reset' => '0x0',
'number' => '0x7f2',
'exists' => 'true',
'mask' => '0xffffffff'
},
'pmpaddr7' => {
'exists' => 'false'
},
'meicurpl' => {
'reset' => '0x0',
'number' => '0xbcc',
'comment' => 'External interrupt current priority level.',
'exists' => 'true',
'mask' => '0xf'
},
'mstatus' => {
'reset' => '0x1800',
'exists' => 'true',
'mask' => '0x88'
},
'tselect' => {
'reset' => '0x0',
'exists' => 'true',
'mask' => '0x3'
}
},
'regwidth' => '32',
'harts' => 1
);
1;

View File

@ -1,173 +0,0 @@
// argv=9
// TOTAL_INT=9 NUM_LEVELS=4
`ifdef RV_PIC_2CYCLE
// LEVEL0
logic [TOTAL_INT+2:0] [INTPRIORITY_BITS-1:0] level_intpend_w_prior_en_1;
logic [TOTAL_INT+2:0] [ID_BITS-1:0] level_intpend_id_1;
for (m=0; m<=(TOTAL_INT)/(2**(1)) ; m++) begin : COMPARE0
if ( m == (TOTAL_INT)/(2**(1))) begin
assign level_intpend_w_prior_en_1[m+1] = '0 ;
assign level_intpend_id_1[m+1] = '0 ;
end
cmp_and_mux #(
.ID_BITS(ID_BITS),
.INTPRIORITY_BITS(INTPRIORITY_BITS)) cmp_l1 (
.a_id(level_intpend_id[0][2*m]),
.a_priority(level_intpend_w_prior_en[0][2*m]),
.b_id(level_intpend_id[0][2*m+1]),
.b_priority(level_intpend_w_prior_en[0][2*m+1]),
.out_id(level_intpend_id_1[m]),
.out_priority(level_intpend_w_prior_en_1[m])) ;
end
// LEVEL1
logic [TOTAL_INT+2:0] [INTPRIORITY_BITS-1:0] level_intpend_w_prior_en_2;
logic [TOTAL_INT+2:0] [ID_BITS-1:0] level_intpend_id_2;
for (m=0; m<=(TOTAL_INT)/(2**(2)) ; m++) begin : COMPARE1
if ( m == (TOTAL_INT)/(2**(2))) begin
assign level_intpend_w_prior_en_2[m+1] = '0 ;
assign level_intpend_id_2[m+1] = '0 ;
end
cmp_and_mux #(
.ID_BITS(ID_BITS),
.INTPRIORITY_BITS(INTPRIORITY_BITS)) cmp_l2 (
.a_id(level_intpend_id_1[2*m]),
.a_priority(level_intpend_w_prior_en_1[2*m]),
.b_id(level_intpend_id_1[2*m+1]),
.b_priority(level_intpend_w_prior_en_1[2*m+1]),
.out_id(level_intpend_id_2[m]),
.out_priority(level_intpend_w_prior_en_2[m])) ;
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_2[i]), .dout(l2_intpend_w_prior_en_ff[i]), .clk(active_clk));
rvdff #(ID_BITS) level2_intpend_id_reg (.*, .din (level_intpend_id_2[i]), .dout(l2_intpend_id_ff[i]), .clk(active_clk));
end
// LEVEL2
logic [TOTAL_INT+2:0] [INTPRIORITY_BITS-1:0] levelx_intpend_w_prior_en_3;
logic [TOTAL_INT+2:0] [ID_BITS-1:0] levelx_intpend_id_3;
for (m=0; m<=(TOTAL_INT)/(2**(3)) ; m++) begin : COMPARE2
if ( m == (TOTAL_INT)/(2**(3))) begin
assign levelx_intpend_w_prior_en_3[m+1] = '0 ;
assign levelx_intpend_id_3[m+1] = '0 ;
end
cmp_and_mux #(
.ID_BITS(ID_BITS),
.INTPRIORITY_BITS(INTPRIORITY_BITS)) cmp_l3 (
.a_id(levelx_intpend_id[2][2*m]),
.a_priority(levelx_intpend_w_prior_en[2][2*m]),
.b_id(levelx_intpend_id[2][2*m+1]),
.b_priority(levelx_intpend_w_prior_en[2][2*m+1]),
.out_id(levelx_intpend_id_3[m]),
.out_priority(levelx_intpend_w_prior_en_3[m])) ;
end
// LEVEL3
logic [TOTAL_INT+2:0] [INTPRIORITY_BITS-1:0] levelx_intpend_w_prior_en_4;
logic [TOTAL_INT+2:0] [ID_BITS-1:0] levelx_intpend_id_4;
for (m=0; m<=(TOTAL_INT)/(2**(4)) ; m++) begin : COMPARE3
if ( m == (TOTAL_INT)/(2**(4))) begin
assign levelx_intpend_w_prior_en_4[m+1] = '0 ;
assign levelx_intpend_id_4[m+1] = '0 ;
end
cmp_and_mux #(
.ID_BITS(ID_BITS),
.INTPRIORITY_BITS(INTPRIORITY_BITS)) cmp_l4 (
.a_id(levelx_intpend_id_3[2*m]),
.a_priority(levelx_intpend_w_prior_en_3[2*m]),
.b_id(levelx_intpend_id_3[2*m+1]),
.b_priority(levelx_intpend_w_prior_en_3[2*m+1]),
.out_id(levelx_intpend_id_4[m]),
.out_priority(levelx_intpend_w_prior_en_4[m])) ;
end
assign claimid_in[ID_BITS-1:0] = levelx_intpend_id_4[0] ; // This is the last level output
assign selected_int_priority[INTPRIORITY_BITS-1:0] = levelx_intpend_w_prior_en_4[0] ;
`else
// LEVEL0
logic [TOTAL_INT+2:0] [INTPRIORITY_BITS-1:0] level_intpend_w_prior_en_1;
logic [TOTAL_INT+2:0] [ID_BITS-1:0] level_intpend_id_1;
for (m=0; m<=(TOTAL_INT)/(2**(1)) ; m++) begin : COMPARE0
if ( m == (TOTAL_INT)/(2**(1))) begin
assign level_intpend_w_prior_en_1[m+1] = '0 ;
assign level_intpend_id_1[m+1] = '0 ;
end
cmp_and_mux #(
.ID_BITS(ID_BITS),
.INTPRIORITY_BITS(INTPRIORITY_BITS)) cmp_l1 (
.a_id(level_intpend_id[0][2*m]),
.a_priority(level_intpend_w_prior_en[0][2*m]),
.b_id(level_intpend_id[0][2*m+1]),
.b_priority(level_intpend_w_prior_en[0][2*m+1]),
.out_id(level_intpend_id_1[m]),
.out_priority(level_intpend_w_prior_en_1[m])) ;
end
// LEVEL1
logic [TOTAL_INT+2:0] [INTPRIORITY_BITS-1:0] level_intpend_w_prior_en_2;
logic [TOTAL_INT+2:0] [ID_BITS-1:0] level_intpend_id_2;
for (m=0; m<=(TOTAL_INT)/(2**(2)) ; m++) begin : COMPARE1
if ( m == (TOTAL_INT)/(2**(2))) begin
assign level_intpend_w_prior_en_2[m+1] = '0 ;
assign level_intpend_id_2[m+1] = '0 ;
end
cmp_and_mux #(
.ID_BITS(ID_BITS),
.INTPRIORITY_BITS(INTPRIORITY_BITS)) cmp_l2 (
.a_id(level_intpend_id_1[2*m]),
.a_priority(level_intpend_w_prior_en_1[2*m]),
.b_id(level_intpend_id_1[2*m+1]),
.b_priority(level_intpend_w_prior_en_1[2*m+1]),
.out_id(level_intpend_id_2[m]),
.out_priority(level_intpend_w_prior_en_2[m])) ;
end
// LEVEL2
logic [TOTAL_INT+2:0] [INTPRIORITY_BITS-1:0] level_intpend_w_prior_en_3;
logic [TOTAL_INT+2:0] [ID_BITS-1:0] level_intpend_id_3;
for (m=0; m<=(TOTAL_INT)/(2**(3)) ; m++) begin : COMPARE2
if ( m == (TOTAL_INT)/(2**(3))) begin
assign level_intpend_w_prior_en_3[m+1] = '0 ;
assign level_intpend_id_3[m+1] = '0 ;
end
cmp_and_mux #(
.ID_BITS(ID_BITS),
.INTPRIORITY_BITS(INTPRIORITY_BITS)) cmp_l3 (
.a_id(level_intpend_id_2[2*m]),
.a_priority(level_intpend_w_prior_en_2[2*m]),
.b_id(level_intpend_id_2[2*m+1]),
.b_priority(level_intpend_w_prior_en_2[2*m+1]),
.out_id(level_intpend_id_3[m]),
.out_priority(level_intpend_w_prior_en_3[m])) ;
end
// LEVEL3
logic [TOTAL_INT+2:0] [INTPRIORITY_BITS-1:0] level_intpend_w_prior_en_4;
logic [TOTAL_INT+2:0] [ID_BITS-1:0] level_intpend_id_4;
for (m=0; m<=(TOTAL_INT)/(2**(4)) ; m++) begin : COMPARE3
if ( m == (TOTAL_INT)/(2**(4))) begin
assign level_intpend_w_prior_en_4[m+1] = '0 ;
assign level_intpend_id_4[m+1] = '0 ;
end
cmp_and_mux #(
.ID_BITS(ID_BITS),
.INTPRIORITY_BITS(INTPRIORITY_BITS)) cmp_l4 (
.a_id(level_intpend_id_3[2*m]),
.a_priority(level_intpend_w_prior_en_3[2*m]),
.b_id(level_intpend_id_3[2*m+1]),
.b_priority(level_intpend_w_prior_en_3[2*m+1]),
.out_id(level_intpend_id_4[m]),
.out_priority(level_intpend_w_prior_en_4[m])) ;
end
assign claimid_in[ID_BITS-1:0] = level_intpend_id_4[0] ; // This is the last level output
assign selected_int_priority[INTPRIORITY_BITS-1:0] = level_intpend_w_prior_en_4[0] ;
`endif

View File

@ -1,31 +0,0 @@
// mask[3:0] = { 4'b1000 - 30b mask,4'b0100 - 31b mask, 4'b0010 - 28b mask, 4'b0001 - 32b mask }
always_comb begin
case (address[14:0])
15'b011000000000000 : mask[3:0] = 4'b0100;
15'b100000000000100 : mask[3:0] = 4'b1000;
15'b100000000001000 : mask[3:0] = 4'b1000;
15'b100000000001100 : mask[3:0] = 4'b1000;
15'b100000000010000 : mask[3:0] = 4'b1000;
15'b100000000010100 : mask[3:0] = 4'b1000;
15'b100000000011000 : mask[3:0] = 4'b1000;
15'b100000000011100 : mask[3:0] = 4'b1000;
15'b100000000100000 : mask[3:0] = 4'b1000;
15'b010000000000100 : mask[3:0] = 4'b0100;
15'b010000000001000 : mask[3:0] = 4'b0100;
15'b010000000001100 : mask[3:0] = 4'b0100;
15'b010000000010000 : mask[3:0] = 4'b0100;
15'b010000000010100 : mask[3:0] = 4'b0100;
15'b010000000011000 : mask[3:0] = 4'b0100;
15'b010000000011100 : mask[3:0] = 4'b0100;
15'b010000000100000 : mask[3:0] = 4'b0100;
15'b000000000000100 : mask[3:0] = 4'b0010;
15'b000000000001000 : mask[3:0] = 4'b0010;
15'b000000000001100 : mask[3:0] = 4'b0010;
15'b000000000010000 : mask[3:0] = 4'b0010;
15'b000000000010100 : mask[3:0] = 4'b0010;
15'b000000000011000 : mask[3:0] = 4'b0010;
15'b000000000011100 : mask[3:0] = 4'b0010;
15'b000000000100000 : mask[3:0] = 4'b0010;
default : mask[3:0] = 4'b0001;
endcase
end

View File

@ -1,395 +0,0 @@
{
"memmap" : {
"cosnoleio" : "0xd0580000"
},
"nmi_vec" : "0x11110000",
"dccm" : {
"region" : "0xf",
"offset" : "0x40000",
"size" : "0x10000"
},
"num_mmode_perf_regs" : "4",
"load_error_rollback" : "1",
"reset_vec" : "0x80000000",
"triggers" : [
{
"poke_mask" : [
"0x081818c7",
"0xffffffff",
"0x00000000"
],
"reset" : [
"0x23e00000",
"0x00000000",
"0x00000000"
],
"mask" : [
"0x081818c7",
"0xffffffff",
"0x00000000"
]
},
{
"poke_mask" : [
"0x081818c7",
"0xffffffff",
"0x00000000"
],
"reset" : [
"0x23e00000",
"0x00000000",
"0x00000000"
],
"mask" : [
"0x081818c7",
"0xffffffff",
"0x00000000"
]
},
{
"poke_mask" : [
"0x081818c7",
"0xffffffff",
"0x00000000"
],
"reset" : [
"0x23e00000",
"0x00000000",
"0x00000000"
],
"mask" : [
"0x081818c7",
"0xffffffff",
"0x00000000"
]
},
{
"poke_mask" : [
"0x081818c7",
"0xffffffff",
"0x00000000"
],
"reset" : [
"0x23e00000",
"0x00000000",
"0x00000000"
],
"mask" : [
"0x081818c7",
"0xffffffff",
"0x00000000"
]
}
],
"xlen" : 32,
"pic" : {
"meigwctrl_offset" : "0x4000",
"region" : "0xf",
"total_int" : 8,
"size" : "0x8000",
"mpiccfg_offset" : "0x3000",
"meigwclr_offset" : "0x5000",
"total_int_plus1" : 9,
"meipt_offset" : "0x3004",
"int_words" : 1,
"meie_offset" : "0x2000",
"bits" : 15,
"meip_offset" : "0x1000",
"meipl_offset" : "0x0000",
"offset" : "0xc0000"
},
"store_error_rollback" : "0",
"even_odd_trigger_chains" : "true",
"max_mmode_perf_event" : "50",
"csr" : {
"pmpaddr9" : {
"exists" : "false"
},
"dicad1" : {
"reset" : "0x0",
"number" : "0x7ca",
"comment" : "Cache diagnostics.",
"debug" : "true",
"exists" : "true",
"mask" : "0x3"
},
"pmpcfg0" : {
"exists" : "false"
},
"mhpmcounter4h" : {
"reset" : "0x0",
"exists" : "true",
"mask" : "0xffffffff"
},
"dicago" : {
"reset" : "0x0",
"number" : "0x7cb",
"comment" : "Cache diagnostics.",
"debug" : "true",
"exists" : "true",
"mask" : "0x0"
},
"mie" : {
"reset" : "0x0",
"exists" : "true",
"mask" : "0x40000888"
},
"misa" : {
"reset" : "0x40001104",
"exists" : "true",
"mask" : "0x0"
},
"mhpmcounter6h" : {
"reset" : "0x0",
"exists" : "true",
"mask" : "0xffffffff"
},
"meicpct" : {
"reset" : "0x0",
"number" : "0xbca",
"comment" : "External claim id/priority capture.",
"exists" : "true",
"mask" : "0x0"
},
"mimpid" : {
"reset" : "0x1",
"exists" : "true",
"mask" : "0x0"
},
"mcpc" : {
"reset" : "0x0",
"number" : "0x7c2",
"exists" : "true",
"mask" : "0x0"
},
"mhpmevent4" : {
"reset" : "0x0",
"exists" : "true",
"mask" : "0xffffffff"
},
"pmpaddr8" : {
"exists" : "false"
},
"pmpcfg3" : {
"exists" : "false"
},
"marchid" : {
"reset" : "0x0000000b",
"exists" : "true",
"mask" : "0x0"
},
"pmpaddr5" : {
"exists" : "false"
},
"mfdc" : {
"reset" : "0x00070000",
"number" : "0x7f9",
"exists" : "true",
"mask" : "0x000707ff"
},
"mhpmevent6" : {
"reset" : "0x0",
"exists" : "true",
"mask" : "0xffffffff"
},
"mvendorid" : {
"reset" : "0x45",
"exists" : "true",
"mask" : "0x0"
},
"pmpaddr4" : {
"exists" : "false"
},
"dcsr" : {
"poke_mask" : "0x00008dcc",
"reset" : "0x40000003",
"exists" : "true",
"mask" : "0x00008c04"
},
"cycle" : {
"exists" : "false"
},
"pmpaddr12" : {
"exists" : "false"
},
"pmpaddr3" : {
"exists" : "false"
},
"mhpmcounter3h" : {
"reset" : "0x0",
"exists" : "true",
"mask" : "0xffffffff"
},
"time" : {
"exists" : "false"
},
"meicidpl" : {
"reset" : "0x0",
"number" : "0xbcb",
"comment" : "External interrupt claim id priority level.",
"exists" : "true",
"mask" : "0xf"
},
"pmpaddr14" : {
"exists" : "false"
},
"pmpaddr13" : {
"exists" : "false"
},
"pmpaddr1" : {
"exists" : "false"
},
"mhpmcounter6" : {
"reset" : "0x0",
"exists" : "true",
"mask" : "0xffffffff"
},
"dicad0" : {
"reset" : "0x0",
"number" : "0x7c9",
"comment" : "Cache diagnostics.",
"debug" : "true",
"exists" : "true",
"mask" : "0xffffffff"
},
"meipt" : {
"reset" : "0x0",
"number" : "0xbc9",
"comment" : "External interrupt priority threshold.",
"exists" : "true",
"mask" : "0xf"
},
"pmpaddr15" : {
"exists" : "false"
},
"mhpmcounter5" : {
"reset" : "0x0",
"exists" : "true",
"mask" : "0xffffffff"
},
"pmpcfg1" : {
"exists" : "false"
},
"pmpaddr10" : {
"exists" : "false"
},
"pmpaddr0" : {
"exists" : "false"
},
"pmpcfg2" : {
"exists" : "false"
},
"pmpaddr2" : {
"exists" : "false"
},
"mpmc" : {
"reset" : "0x0",
"number" : "0x7c6",
"comment" : "Core pause: Implemented as read only.",
"exists" : "true",
"mask" : "0x0"
},
"dmst" : {
"reset" : "0x0",
"number" : "0x7c4",
"comment" : "Memory synch trigger: Flush caches in debug mode.",
"debug" : "true",
"exists" : "true",
"mask" : "0x0"
},
"instret" : {
"exists" : "false"
},
"mhpmevent3" : {
"reset" : "0x0",
"exists" : "true",
"mask" : "0xffffffff"
},
"dicawics" : {
"reset" : "0x0",
"number" : "0x7c8",
"comment" : "Cache diagnostics.",
"debug" : "true",
"exists" : "true",
"mask" : "0x0130fffc"
},
"mip" : {
"poke_mask" : "0x40000888",
"reset" : "0x0",
"exists" : "true",
"mask" : "0x0"
},
"mhpmcounter5h" : {
"reset" : "0x0",
"exists" : "true",
"mask" : "0xffffffff"
},
"micect" : {
"reset" : "0x0",
"number" : "0x7f0",
"exists" : "true",
"mask" : "0xffffffff"
},
"miccmect" : {
"reset" : "0x0",
"number" : "0x7f1",
"exists" : "true",
"mask" : "0xffffffff"
},
"mhpmevent5" : {
"reset" : "0x0",
"exists" : "true",
"mask" : "0xffffffff"
},
"mhpmcounter3" : {
"reset" : "0x0",
"exists" : "true",
"mask" : "0xffffffff"
},
"pmpaddr6" : {
"exists" : "false"
},
"pmpaddr11" : {
"exists" : "false"
},
"mcgc" : {
"poke_mask" : "0x000001ff",
"reset" : "0x0",
"number" : "0x7f8",
"exists" : "true",
"mask" : "0x000001ff"
},
"mhpmcounter4" : {
"reset" : "0x0",
"exists" : "true",
"mask" : "0xffffffff"
},
"mdccmect" : {
"reset" : "0x0",
"number" : "0x7f2",
"exists" : "true",
"mask" : "0xffffffff"
},
"pmpaddr7" : {
"exists" : "false"
},
"meicurpl" : {
"reset" : "0x0",
"number" : "0xbcc",
"comment" : "External interrupt current priority level.",
"exists" : "true",
"mask" : "0xf"
},
"mstatus" : {
"reset" : "0x1800",
"exists" : "true",
"mask" : "0x88"
},
"tselect" : {
"reset" : "0x0",
"exists" : "true",
"mask" : "0x3"
}
},
"harts" : 1
}

View File

@ -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
@ -311,24 +356,24 @@ if (!defined($dec_instbuf_depth)) { $dec_instbuf_depth=4; }
# Configure triggers # Configure triggers
our @triggers = (#{{{ our @triggers = (#{{{
{ {
"reset" => ["0x23e00000", "0x00000000", "0x00000000"], "reset" => ["0x23e00000", "0x00000000", "0x00000000"],
"mask" => ["0x081818c7", "0xffffffff", "0x00000000"],
"poke_mask" => ["0x081818c7", "0xffffffff", "0x00000000"]
},
{
"reset" => ["0x23e00000", "0x00000000", "0x00000000"],
"mask" => ["0x081818c7", "0xffffffff", "0x00000000"], "mask" => ["0x081818c7", "0xffffffff", "0x00000000"],
"poke_mask" => ["0x081818c7", "0xffffffff", "0x00000000"] "poke_mask" => ["0x081818c7", "0xffffffff", "0x00000000"]
}, },
{ {
"reset" => ["0x23e00000", "0x00000000", "0x00000000"], "reset" => ["0x23e00000", "0x00000000", "0x00000000"],
"mask" => ["0x081818c7", "0xffffffff", "0x00000000"], "mask" => ["0x081818c7", "0xffffffff", "0x00000000"],
"poke_mask" => ["0x081818c7", "0xffffffff", "0x00000000"] "poke_mask" => ["0x081818c7", "0xffffffff", "0x00000000"]
}, },
{ {
"reset" => ["0x23e00000", "0x00000000", "0x00000000"], "reset" => ["0x23e00000", "0x00000000", "0x00000000"],
"mask" => ["0x081818c7", "0xffffffff", "0x00000000"], "mask" => ["0x081818c7", "0xffffffff", "0x00000000"],
"poke_mask" => ["0x081818c7", "0xffffffff", "0x00000000"] "poke_mask" => ["0x081818c7", "0xffffffff", "0x00000000"]
},
{
"reset" => ["0x23e00000", "0x00000000", "0x00000000"],
"mask" => ["0x081818c7", "0xffffffff", "0x00000000"],
"poke_mask" => ["0x081818c7", "0xffffffff", "0x00000000"]
}, },
);#}}} );#}}}
@ -342,18 +387,18 @@ our %csr = (#{{{
}, },
"mie" => { "mie" => {
"reset" => "0x0", "reset" => "0x0",
# Only external, timer, local, and software writeable # Only external, timer, local, and software writeable
"mask" => "0x40000888", "mask" => "0x40000888",
"exists" => "true", "exists" => "true",
}, },
"mip" => { "mip" => {
"reset" => "0x0", "reset" => "0x0",
# None of the bits are writeable using CSR instructions # None of the bits are writeable using CSR instructions
"mask" => "0x0", "mask" => "0x0",
# Bits corresponding to error overflow, external, timer and stoftware # Bits corresponding to error overflow, external, timer and stoftware
# interrupts are modifiable # interrupts are modifiable
"poke_mask" => "0x40000888", "poke_mask" => "0x40000888",
"exists" => "true", "exists" => "true",
}, },
"mvendorid" => { "mvendorid" => {
"reset" => "0x45", "reset" => "0x45",
@ -366,7 +411,7 @@ our %csr = (#{{{
"exists" => "true", "exists" => "true",
}, },
"mimpid" => { "mimpid" => {
"reset" => "0x1", "reset" => "0x2",
"mask" => "0x0", "mask" => "0x0",
"exists" => "true", "exists" => "true",
}, },
@ -387,13 +432,13 @@ our %csr = (#{{{
"exists" => "true", "exists" => "true",
}, },
"cycle" => { "cycle" => {
"exists" => "false", "exists" => "false",
}, },
"time" => { "time" => {
"exists" => "false", "exists" => "false",
}, },
"instret" => { "instret" => {
"exists" => "false", "exists" => "false",
}, },
"mhpmcounter3" => { "mhpmcounter3" => {
"reset" => "0x0", "reset" => "0x0",
@ -625,10 +670,10 @@ our %config = (#{{{
"max_mmode_perf_event" => "50", # Whisper only: performance counters event ids will be clamped to this "max_mmode_perf_event" => "50", # Whisper only: performance counters event ids will be clamped to this
"target" => $target, "target" => $target,
"tec_rv_icg" => "clockhdr", "tec_rv_icg" => "clockhdr",
"verilator" => "$verilator", "verilator" => "$verilator",
"retstack" => { "retstack" => {
"ret_stack_size" => "$ret_stack_size", "ret_stack_size" => "$ret_stack_size",
}, },
"btb" => { "btb" => {
@ -653,17 +698,17 @@ our %config = (#{{{
"bht_ghr_range" => "derived", "bht_ghr_range" => "derived",
"bht_ghr_pad" => "derived", "bht_ghr_pad" => "derived",
"bht_ghr_pad2" => "derived", "bht_ghr_pad2" => "derived",
"bht_hash_string" => "derived", "bht_hash_string" => "derived",
}, },
"core" => { "core" => {
"dec_instbuf_depth" => "$dec_instbuf_depth", "dec_instbuf_depth" => "$dec_instbuf_depth",
"lsu_stbuf_depth" => "$lsu_stbuf_depth", "lsu_stbuf_depth" => "$lsu_stbuf_depth",
"dma_buf_depth" => "$dma_buf_depth", "dma_buf_depth" => "$dma_buf_depth",
"lsu_num_nbload" => "$lsu_num_nbload", "lsu_num_nbload" => "$lsu_num_nbload",
"no_secondary_alu" => "$no_secondary_alu", "no_secondary_alu" => "$no_secondary_alu",
"fpga_optimize" => "$fpga_optimize" "fpga_optimize" => "$fpga_optimize"
}, },
"dccm" => { "dccm" => {
@ -695,7 +740,7 @@ our %config = (#{{{
"iccm_offset" => "$iccm_offset", # 256K offset number "iccm_offset" => "$iccm_offset", # 256K offset number
"iccm_size" => "$iccm_size", # Size in Kbytes "iccm_size" => "$iccm_size", # Size in Kbytes
"iccm_num_banks" => "$iccm_num_banks", "iccm_num_banks" => "$iccm_num_banks",
"iccm_bank_bits" => 'derived', "iccm_bank_bits" => 'derived',
"iccm_index_bits" => 'derived', "iccm_index_bits" => 'derived',
"iccm_rows" => 'derived', "iccm_rows" => 'derived',
"iccm_data_cell" => 'derived', "iccm_data_cell" => 'derived',
@ -706,15 +751,15 @@ our %config = (#{{{
"icache" => { "icache" => {
"icache_enable" => "$icache_enable", "icache_enable" => "$icache_enable",
"icache_size" => "$icache_size", "icache_size" => "$icache_size",
"icache_data_cell" => 'derived', "icache_data_cell" => 'derived',
"icache_tag_cell" => 'derived', "icache_tag_cell" => 'derived',
"icache_taddr_high" => 'derived', "icache_taddr_high" => 'derived',
"icache_tag_high" => 'derived', "icache_tag_high" => 'derived',
"icache_tag_depth" => 'derived', "icache_tag_depth" => 'derived',
"icache_ic_depth" => 'derived', "icache_ic_depth" => 'derived',
"icache_ic_rows" => 'derived', "icache_ic_rows" => 'derived',
"icache_ic_index" => 'derived', "icache_ic_index" => 'derived',
"icache_tag_low" => '6', "icache_tag_low" => '6',
"icache_ecc" => "$icache_ecc", "icache_ecc" => "$icache_ecc",
}, },
"pic" => { "pic" => {
@ -728,12 +773,12 @@ our %config = (#{{{
"pic_int_words" => 'derived', # number of 32 bit words for packed registers (Xmax) "pic_int_words" => 'derived', # number of 32 bit words for packed registers (Xmax)
"pic_bits" => 'derived', # of bits needs to address the PICM "pic_bits" => 'derived', # of bits needs to address the PICM
"pic_meipl_offset" => '0x0000', # Offset of meipl relative to pic_base_addr "pic_meipl_offset" => '0x0000', # Offset of meipl relative to pic_base_addr
"pic_meip_offset" => '0x1000', # Offset of meip relative to pic_base_addr "pic_meip_offset" => '0x1000', # Offset of meip relative to pic_base_addr
"pic_meie_offset" => '0x2000', # Offset of meie relative to pic_base_addr "pic_meie_offset" => '0x2000', # Offset of meie relative to pic_base_addr
"pic_mpiccfg_offset" => '0x3000', # Offset of mpiccfg relative to pic_base_addr "pic_mpiccfg_offset" => '0x3000', # Offset of mpiccfg relative to pic_base_addr
"pic_meipt_offset" => '0x3004', # Offset of meipt relative to pic_base_addr -- deprecated "pic_meipt_offset" => '0x3004', # Offset of meipt relative to pic_base_addr -- deprecated
"pic_meigwctrl_offset" => '0x4000', # gateway control regs relative to pic_base_addr "pic_meigwctrl_offset" => '0x4000', # gateway control regs relative to pic_base_addr
"pic_meigwclr_offset" => '0x5000' # gateway clear regs relative to pic_base_addr "pic_meigwclr_offset" => '0x5000' # gateway clear regs relative to pic_base_addr
}, },
"testbench" => { "testbench" => {
@ -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",
@ -752,54 +797,54 @@ our %config = (#{{{
"SDVT_AHB" => "1", "SDVT_AHB" => "1",
}, },
"protection" => { "protection" => {
"inst_access_enable0" => "0x0", "inst_access_enable0" => "0x0",
"inst_access_addr0" => "0x00000000", "inst_access_addr0" => "0x00000000",
"inst_access_mask0" => "0xffffffff", "inst_access_mask0" => "0xffffffff",
"inst_access_enable1" => "0x0", "inst_access_enable1" => "0x0",
"inst_access_addr1" => "0x00000000", "inst_access_addr1" => "0x00000000",
"inst_access_mask1" => "0xffffffff", "inst_access_mask1" => "0xffffffff",
"inst_access_enable2" => "0x0", "inst_access_enable2" => "0x0",
"inst_access_addr2" => "0x00000000", "inst_access_addr2" => "0x00000000",
"inst_access_mask2" => "0xffffffff", "inst_access_mask2" => "0xffffffff",
"inst_access_enable3" => "0x0", "inst_access_enable3" => "0x0",
"inst_access_addr3" => "0x00000000", "inst_access_addr3" => "0x00000000",
"inst_access_mask3" => "0xffffffff", "inst_access_mask3" => "0xffffffff",
"inst_access_enable4" => "0x0", "inst_access_enable4" => "0x0",
"inst_access_addr4" => "0x00000000", "inst_access_addr4" => "0x00000000",
"inst_access_mask4" => "0xffffffff", "inst_access_mask4" => "0xffffffff",
"inst_access_enable5" => "0x0", "inst_access_enable5" => "0x0",
"inst_access_addr5" => "0x00000000", "inst_access_addr5" => "0x00000000",
"inst_access_mask5" => "0xffffffff", "inst_access_mask5" => "0xffffffff",
"inst_access_enable6" => "0x0", "inst_access_enable6" => "0x0",
"inst_access_addr6" => "0x00000000", "inst_access_addr6" => "0x00000000",
"inst_access_mask6" => "0xffffffff", "inst_access_mask6" => "0xffffffff",
"inst_access_enable7" => "0x0", "inst_access_enable7" => "0x0",
"inst_access_addr7" => "0x00000000", "inst_access_addr7" => "0x00000000",
"inst_access_mask7" => "0xffffffff", "inst_access_mask7" => "0xffffffff",
"data_access_enable0" => "0x0", "data_access_enable0" => "0x0",
"data_access_addr0" => "0x00000000", "data_access_addr0" => "0x00000000",
"data_access_mask0" => "0xffffffff", "data_access_mask0" => "0xffffffff",
"data_access_enable1" => "0x0", "data_access_enable1" => "0x0",
"data_access_addr1" => "0x00000000", "data_access_addr1" => "0x00000000",
"data_access_mask1" => "0xffffffff", "data_access_mask1" => "0xffffffff",
"data_access_enable2" => "0x0", "data_access_enable2" => "0x0",
"data_access_addr2" => "0x00000000", "data_access_addr2" => "0x00000000",
"data_access_mask2" => "0xffffffff", "data_access_mask2" => "0xffffffff",
"data_access_enable3" => "0x0", "data_access_enable3" => "0x0",
"data_access_addr3" => "0x00000000", "data_access_addr3" => "0x00000000",
"data_access_mask3" => "0xffffffff", "data_access_mask3" => "0xffffffff",
"data_access_enable4" => "0x0", "data_access_enable4" => "0x0",
"data_access_addr4" => "0x00000000", "data_access_addr4" => "0x00000000",
"data_access_mask4" => "0xffffffff", "data_access_mask4" => "0xffffffff",
"data_access_enable5" => "0x0", "data_access_enable5" => "0x0",
"data_access_addr5" => "0x00000000", "data_access_addr5" => "0x00000000",
"data_access_mask5" => "0xffffffff", "data_access_mask5" => "0xffffffff",
"data_access_enable6" => "0x0", "data_access_enable6" => "0x0",
"data_access_addr6" => "0x00000000", "data_access_addr6" => "0x00000000",
"data_access_mask6" => "0xffffffff", "data_access_mask6" => "0xffffffff",
"data_access_enable7" => "0x0", "data_access_enable7" => "0x0",
"data_access_addr7" => "0x00000000", "data_access_addr7" => "0x00000000",
"data_access_mask7" => "0xffffffff", "data_access_mask7" => "0xffffffff",
}, },
"memmap" => { "memmap" => {
"serialio" => 'derived, overridable', "serialio" => 'derived, overridable',
@ -807,7 +852,7 @@ our %config = (#{{{
"external_prog" => 'derived, overridable', "external_prog" => 'derived, overridable',
"debug_sb_mem" => 'derived, overridable', "debug_sb_mem" => 'derived, overridable',
"external_data_1" => 'derived, overridable', "external_data_1" => 'derived, overridable',
# "consoleio" => 'derived', # Part of serial io. # "consoleio" => 'derived', # Part of serial io.
}, },
"bus" => { "bus" => {
"lsu_bus_tag" => 'derived', "lsu_bus_tag" => 'derived',
@ -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 "") {
@ -971,15 +1022,15 @@ sub ghrhash{
$ghr_start = "{"; $ghr_start = "{";
if($ghr_size > $btb_addr_width){ if($ghr_size > $btb_addr_width){
if($ghr_size-1 == $btb_addr_width){ if($ghr_size-1 == $btb_addr_width){
$string= "{ghr[$ghr_hi:$ghr_lo] ^ ghr[$ghr_hi+1],hashin[$config{btb}{btb_index1_hi}:4]^ghr[$ghr_lo-1:0]}"; $string= "{ghr[$ghr_hi:$ghr_lo] ^ ghr[$ghr_hi+1],hashin[$config{btb}{btb_index1_hi}:4]^ghr[$ghr_lo-1:0]}";
} }
else{ else{
$string = "{ghr[$ghr_hi:$ghr_lo] ^ {ghr[$ghr_hi+1], {$ghr_size-1-$btb_addr_width\{1'b0} } },hashin[$config{btb}{btb_index1_hi}:4]^ghr[$ghr_lo-1:0]}"; $string = "{ghr[$ghr_hi:$ghr_lo] ^ {ghr[$ghr_hi+1], {$ghr_size-1-$btb_addr_width\{1'b0} } },hashin[$config{btb}{btb_index1_hi}:4]^ghr[$ghr_lo-1:0]}";
} }
} }
elsif($ghr_size < $btb_addr_width){ elsif($ghr_size < $btb_addr_width){
$string = "{hashin[$ghr_size+3:4]^ghr[$ghr_size-1:0]^{ghr[$ghr_hi+1], {$ghr_hi\{1'b0} } }}"; $string = "{hashin[$ghr_size+3:4]^ghr[$ghr_size-1:0]^{ghr[$ghr_hi+1], {$ghr_hi\{1'b0} } }}";
} }
else{ $string = "{hashin[$config{btb}{btb_index1_hi}:4]^ghr[$ghr_lo-1:0]^{ghr[$ghr_hi+1], {$btb_addr_width-1\{1'b0} } } }"} else{ $string = "{hashin[$config{btb}{btb_index1_hi}:4]^ghr[$ghr_lo-1:0]^{ghr[$ghr_hi+1], {$btb_addr_width-1\{1'b0} } } }"}
return $string; return $string;
@ -1129,14 +1180,14 @@ $config{dccm}{dccm_data_cell} = "ram_$config{dccm}{dccm_rows}x39";
$config{icache}{icache_tag_high} = (($config{icache}{icache_size}==256) ? 16 : $config{icache}{icache_tag_high} = (($config{icache}{icache_size}==256) ? 16 :
($config{icache}{icache_size}==128) ? 15 : ($config{icache}{icache_size}==128) ? 15 :
($config{icache}{icache_size}==64) ? 14 : ($config{icache}{icache_size}==64) ? 14 :
($config{icache}{icache_size}==32) ? 13 : 12); ($config{icache}{icache_size}==32) ? 13 : 12);
$config{icache}{icache_tag_depth} = (($config{icache}{icache_size}==256) ? 1024 : $config{icache}{icache_tag_depth} = (($config{icache}{icache_size}==256) ? 1024 :
($config{icache}{icache_size}==128) ? 512 : ($config{icache}{icache_size}==128) ? 512 :
($config{icache}{icache_size}==64) ? 256 : ($config{icache}{icache_size}==64) ? 256 :
($config{icache}{icache_size}==32) ? 128 : 64); ($config{icache}{icache_size}==32) ? 128 : 64);
$config{icache}{icache_ic_depth} = log2($config{icache}{icache_size}) + 4; $config{icache}{icache_ic_depth} = log2($config{icache}{icache_size}) + 4;
@ -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);
@ -1434,7 +1502,7 @@ sub gen_define {#{{{
$re = qr/($re)/; $re = qr/($re)/;
#print Dumper($hash); #print Dumper($hash);
foreach my $key (keys %$hash) { foreach my $key (keys %$hash) {
next if $key eq "csr"; next if $key eq "csr";
#print "looking at $key:$matched ($re)\n"; #print "looking at $key:$matched ($re)\n";
if (defined($unsets{$key})) { if (defined($unsets{$key})) {
print "$self:unsetting $key\n"; print "$self:unsetting $key\n";
@ -1559,59 +1627,126 @@ sub collect_mem_protection {
my $mask_tag = $tag . "_access_mask"; my $mask_tag = $tag . "_access_mask";
foreach my $key (keys %{$prot}) { foreach my $key (keys %{$prot}) {
next unless $key =~ /^$enable_tag(\d+)$/; next unless $key =~ /^$enable_tag(\d+)$/;
my $ix = $1; my $ix = $1;
my $enable = $prot->{$key}; my $enable = $prot->{$key};
if ($enable !~ /[01]$/) { if ($enable !~ /[01]$/) {
warn("Invalid value for protection entry $key: $enable\n"); warn("Invalid value for protection entry $key: $enable\n");
next; next;
} }
next unless ($enable eq "1" or $enable eq "1'b1"); next unless ($enable eq "1" or $enable eq "1'b1");
if (! exists $prot->{"$addr_tag$ix"}) { if (! exists $prot->{"$addr_tag$ix"}) {
warn("Missing $addr_tag$ix\n"); warn("Missing $addr_tag$ix\n");
next; next;
} }
if (! exists $prot->{"$mask_tag$ix"}) { if (! exists $prot->{"$mask_tag$ix"}) {
warn("Missing $mask_tag$ix\n"); warn("Missing $mask_tag$ix\n");
next; next;
} }
my $addr = $prot->{"$addr_tag$ix"}; my $addr = $prot->{"$addr_tag$ix"};
my $mask = $prot->{"$mask_tag$ix"}; my $mask = $prot->{"$mask_tag$ix"};
if ($addr !~ /^0x[0-9a-fA-F]+$/) { if ($addr !~ /^0x[0-9a-fA-F]+$/) {
warn("Invalid $addr_tag$ix: $addr\n"); warn("Invalid $addr_tag$ix: $addr\n");
next; next;
} }
if ($mask !~ /^0x[0-9a-fA-F]+$/) { if ($mask !~ /^0x[0-9a-fA-F]+$/) {
warn("Invalid $mask_tag$ix: $mask\n"); warn("Invalid $mask_tag$ix: $mask\n");
next; next;
} }
if ((hex($addr) & hex($mask)) != 0) { if ((hex($addr) & hex($mask)) != 0) {
warn("Protection mask bits overlap address bits in mask $mask and addr $addr\n"); warn("Protection mask bits overlap address bits in mask $mask and addr $addr\n");
} }
if ($mask !~ /^0x0*[137]?f*$/) { if ($mask !~ /^0x0*[137]?f*$/) {
warn("Protection mask ($mask) must have all its one bits to the right of its zero bits\n"); warn("Protection mask ($mask) must have all its one bits to the right of its zero bits\n");
next; next;
} }
my $start = hex($addr) & ~hex($mask) & 0xffffffff; my $start = hex($addr) & ~hex($mask) & 0xffffffff;
my $end = (hex($addr) | hex($mask)) & 0xffffffff; my $end = (hex($addr) | hex($mask)) & 0xffffffff;
$start = sprintf("0x%08x", $start); $start = sprintf("0x%08x", $start);
$end = sprintf("0x%08x", $end); $end = sprintf("0x%08x", $end);
push(@{$results}, [ $start, $end ]); push(@{$results}, [ $start, $end ]);
} }
} }
# Collect memory protection specs (array of address pairs) in the given
# resutls array. Tag is either "data" or "inst".
sub collect_mem_protection {
my ($tag, $config, $results) = @_;
return unless exists $config{protection};
my $prot = $config{protection};
my $enable_tag = $tag . "_access_enable";
my $addr_tag = $tag . "_access_addr";
my $mask_tag = $tag . "_access_mask";
foreach my $key (keys %{$prot}) {
next unless $key =~ /^$enable_tag(\d+)$/;
my $ix = $1;
my $enable = $prot->{$key};
if ($enable !~ /[01]$/) {
warn("Invalid value for protection entry $key: $enable\n");
next;
}
next unless ($enable eq "1" or $enable eq "1'b1");
if (! exists $prot->{"$addr_tag$ix"}) {
warn("Missing $addr_tag$ix\n");
next;
}
if (! exists $prot->{"$mask_tag$ix"}) {
warn("Missing $mask_tag$ix\n");
next;
}
my $addr = $prot->{"$addr_tag$ix"};
my $mask = $prot->{"$mask_tag$ix"};
if ($addr !~ /^0x[0-9a-fA-F]+$/) {
warn("Invalid $addr_tag$ix: $addr\n");
next;
}
if ($mask !~ /^0x[0-9a-fA-F]+$/) {
warn("Invalid $mask_tag$ix: $mask\n");
next;
}
if ((hex($addr) & hex($mask)) != 0) {
warn("Protection mask bits overlap address bits in mask $mask and addr $addr\n");
}
if ($mask !~ /^0x0*[137]?f*$/) {
warn("Protection mask ($mask) must have all its one bits to the right of its zero bits\n");
next;
}
my $start = hex($addr) & ~hex($mask) & 0xffffffff;
my $end = (hex($addr) | hex($mask)) & 0xffffffff;
$start = sprintf("0x%08x", $start);
$end = sprintf("0x%08x", $end);
push(@{$results}, [ $start, $end ]);
}
}
sub dump_whisper_config{#{{{ sub dump_whisper_config{#{{{
my ($config, $path) = @_; my ($config, $path) = @_;
@ -1623,13 +1758,13 @@ sub dump_whisper_config{#{{{
# Collect top-level integer entries. # Collect top-level integer entries.
foreach my $tag (qw( harts xlen )) { foreach my $tag (qw( harts xlen )) {
$jh{$tag} = $config{$tag} + 0 if exists $config{$tag}; $jh{$tag} = $config{$tag} + 0 if exists $config{$tag};
} }
# Collect top-level string/hex entries. # Collect top-level string/hex entries.
foreach my $tag (qw ( reset_vec nmi_vec num_mmode_perf_regs max_mmode_perf_event foreach my $tag (qw ( reset_vec nmi_vec num_mmode_perf_regs max_mmode_perf_event
even_odd_trigger_chains)) { even_odd_trigger_chains)) {
$jh{$tag} = $config{$tag} if exists $config{$tag}; $jh{$tag} = $config{$tag} if exists $config{$tag};
} }
# Collect memory map configs. # Collect memory map configs.
@ -1642,28 +1777,28 @@ sub dump_whisper_config{#{{{
# Collect load/store-error rollback parameter. # Collect load/store-error rollback parameter.
if (exists $config{testbench} and exists $config{testbench}{sterr_rollback}) { if (exists $config{testbench} and exists $config{testbench}{sterr_rollback}) {
$jh{store_error_rollback} = $config{testbench}{sterr_rollback}; $jh{store_error_rollback} = $config{testbench}{sterr_rollback};
} }
if (exists $config{testbench} and exists $config{testbench}{lderr_rollback}) { if (exists $config{testbench} and exists $config{testbench}{lderr_rollback}) {
$jh{load_error_rollback} = $config{testbench}{lderr_rollback}; $jh{load_error_rollback} = $config{testbench}{lderr_rollback};
} }
# Collect dccm configs # Collect dccm configs
if (exists $config{dccm} and exists $config{dccm}{dccm_enable}) { if (exists $config{dccm} and exists $config{dccm}{dccm_enable}) {
$jh{dccm}{region} = $config{dccm}{dccm_region}; $jh{dccm}{region} = $config{dccm}{dccm_region};
$jh{dccm}{size} = 1024*decimal($config{dccm}{dccm_size}); # From 1k to bytes $jh{dccm}{size} = 1024*decimal($config{dccm}{dccm_size}); # From 1k to bytes
$jh{dccm}{offset} = $config{dccm}{dccm_offset}; $jh{dccm}{offset} = $config{dccm}{dccm_offset};
$jh{dccm}{size} = sprintf("0x%x", $jh{dccm}{size}); $jh{dccm}{size} = sprintf("0x%x", $jh{dccm}{size});
} }
# Collect icccm configs. # Collect icccm configs.
if (exists $config{iccm} and exists $config{iccm}{iccm_enable}) { if (exists $config{iccm} and exists $config{iccm}{iccm_enable}) {
$jh{iccm}{region} = $config{iccm}{iccm_region}; $jh{iccm}{region} = $config{iccm}{iccm_region};
$jh{iccm}{size} = 1024*decimal($config{iccm}{iccm_size}); # From 1k to bytes $jh{iccm}{size} = 1024*decimal($config{iccm}{iccm_size}); # From 1k to bytes
$jh{iccm}{offset} = $config{iccm}{iccm_offset}; $jh{iccm}{offset} = $config{iccm}{iccm_offset};
$jh{iccm}{size} = sprintf("0x%x", $jh{iccm}{size}); $jh{iccm}{size} = sprintf("0x%x", $jh{iccm}{size});
} }
# Collect CSRs # Collect CSRs
@ -1672,16 +1807,16 @@ sub dump_whisper_config{#{{{
# Collect pic configs. # Collect pic configs.
if (exists $config{pic}) { if (exists $config{pic}) {
while (my ($k, $v) = each %{$config{pic}}) { while (my ($k, $v) = each %{$config{pic}}) {
next if $k eq 'pic_base_addr'; # derived from region and offset next if $k eq 'pic_base_addr'; # derived from region and offset
if ($k eq 'pic_size') { if ($k eq 'pic_size') {
$v *= 1024; # from kbytes to bytes $v *= 1024; # from kbytes to bytes
$v = sprintf("0x%x", $v); $v = sprintf("0x%x", $v);
} }
$k =~ s/^pic_//o; $k =~ s/^pic_//o;
$v += 0 if $v =~ /^\d+$/o; $v += 0 if $v =~ /^\d+$/o;
$jh{pic}{$k} = $v; $jh{pic}{$k} = $v;
} }
} }
# Collect triggers. # Collect triggers.
@ -1708,9 +1843,9 @@ sub check_addr_align {
$size = 2*$p2 if $size != $p2; $size = 2*$p2 if $size != $p2;
if (($addr % $size) != 0) { if (($addr % $size) != 0) {
printf("Address of $section area(0x%x) is not a multiple of its size (0x%x)\n", printf("Address of $section area(0x%x) is not a multiple of its size (0x%x)\n",
$addr, $size); $addr, $size);
exit(1); exit(1);
} }
} }

View File

@ -0,0 +1,56 @@
#!/usr/bin/env python
from fusesoc.capi2.generator import Generator
import os
import shutil
import subprocess
import sys
import tempfile
if sys.version[0] == '2':
devnull = open(os.devnull, 'w')
else:
from subprocess import DEVNULL as devnull
class SwervConfigGenerator(Generator):
def run(self):
script_root = os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), '..'))
files = [
{"configs/snapshots/default/common_defines.vh" : {
"copyto" : "config/common_defines.vh",
"file_type" : "systemVerilogSource"}},
{"configs/snapshots/default/pic_ctrl_verilator_unroll.sv" : {
"copyto" : "config/pic_ctrl_verilator_unroll.sv",
"is_include_file" : True,
"file_type" : "systemVerilogSource"}},
{"configs/snapshots/default/pic_map_auto.h" : {
"copyto" : "config/pic_map_auto.h",
"is_include_file" : True,
"file_type" : "systemVerilogSource"}}]
tmp_dir = os.path.join(tempfile.mkdtemp(), 'core')
shutil.copytree(script_root, tmp_dir)
cwd = tmp_dir
env = os.environ.copy()
env['RV_ROOT'] = tmp_dir
args = ['configs/swerv.config'] + self.config.get('args', [])
rc = subprocess.call(args, cwd=cwd, env=env, stdout=devnull)
if rc:
exit(1)
filenames = []
for f in files:
for k in f:
filenames.append(k)
for f in filenames:
d = os.path.dirname(f)
if d and not os.path.exists(d):
os.makedirs(d)
shutil.copy2(os.path.join(cwd, f),f)
self.add_files(files)
g = SwervConfigGenerator()
g.run()
g.write()

View File

@ -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];

View File

@ -118,22 +118,22 @@ c.xor = [100011...01...01]
.input .input
rv32c = { rv32c = {
i[15] i[15]
i[14] i[14]
i[13] i[13]
i[12] i[12]
i[11] i[11]
i[10] i[10]
i[9] i[9]
i[8] i[8]
i[7] i[7]
i[6] i[6]
i[5] i[5]
i[4] i[4]
i[3] i[3]
i[2] i[2]
i[1] i[1]
i[0] i[0]
} }
.output .output
@ -145,20 +145,20 @@ rv32c = {
rdprs1 rdprs1
rs2prs2 rs2prs2
rs2prd rs2prd
uimm9_2 uimm9_2
ulwimm6_2 ulwimm6_2
ulwspimm7_2 ulwspimm7_2
rdeq2 rdeq2
rdeq1 rdeq1
rs1eq2 rs1eq2
sbroffset8_1 sbroffset8_1
simm9_4 simm9_4
simm5_0 simm5_0
sjaloffset11_1 sjaloffset11_1
sluimm17_12 sluimm17_12
uimm5_0 uimm5_0
uswimm6_2 uswimm6_2
uswspimm7_2 uswspimm7_2
o[31] o[31]
o[30] o[30]
o[29] o[29]

View File

@ -217,13 +217,13 @@ csr[ csr_dicad1 ] = { csr_dicad1 }
csr[ csr_dicago ] = { csr_dicago } csr[ csr_dicago ] = { csr_dicago }
csr[ csr_perfva ] = { valid_only } csr[ csr_perfva ] = { valid_only }
csr[ csr_perfvb ] = { valid_only } csr[ csr_perfvb ] = { valid_only }
csr[ csr_perfvc ] = { valid_only } csr[ csr_perfvc ] = { valid_only }
csr[ csr_perfvd ] = { valid_only } csr[ csr_perfvd ] = { valid_only }
csr[ csr_perfve ] = { valid_only } csr[ csr_perfve ] = { valid_only }
csr[ csr_perfvf ] = { valid_only } csr[ csr_perfvf ] = { valid_only }
csr[ csr_perfvg ] = { valid_only } csr[ csr_perfvg ] = { valid_only }
csr[ csr_perfvh ] = { valid_only } csr[ csr_perfvh ] = { valid_only }
csr[ csr_perfvi ] = { valid_only } csr[ csr_perfvi ] = { valid_only }
.end .end

View File

@ -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

View File

@ -515,7 +515,7 @@ module dec_decode_ctl
// non block load cam logic // non block load cam logic
logic cam_write, cam_inv_reset, cam_data_reset; logic cam_write, cam_inv_reset, cam_data_reset;
logic [NBLOAD_TAG_MSB:0] cam_write_tag, cam_inv_reset_tag, cam_data_reset_tag; logic [NBLOAD_TAG_MSB:0] cam_write_tag, cam_inv_reset_tag, cam_data_reset_tag;
logic [NBLOAD_SIZE_MSB:0] cam_wen; logic [NBLOAD_SIZE_MSB:0] cam_wen;
@ -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]));

View File

@ -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}) |

View File

@ -120,38 +120,38 @@ remu = [0000001..........111.....0110011]
.input .input
rv32i = { rv32i = {
i[31] i[31]
i[30] i[30]
i[29] i[29]
i[28] i[28]
i[27] i[27]
i[26] i[26]
i[25] i[25]
i[24] i[24]
i[23] i[23]
i[22] i[22]
i[21] i[21]
i[20] i[20]
i[19] i[19]
i[18] i[18]
i[17] i[17]
i[16] i[16]
i[15] i[15]
i[14] i[14]
i[13] i[13]
i[12] i[12]
i[11] i[11]
i[10] i[10]
i[9] i[9]
i[8] i[8]
i[7] i[7]
i[6] i[6]
i[5] i[5]
i[4] i[4]
i[3] i[3]
i[2] i[2]
i[1] i[1]
i[0] i[0]
} }

52
design/flist.questa Normal file
View File

@ -0,0 +1,52 @@
$RV_ROOT/workspace/work/snapshots/default/common_defines.vh
$RV_ROOT/design/include/def.sv
+incdir+$RV_ROOT/workspace/work/snapshots/default
+incdir+$RV_ROOT/design/lib
+incdir+$RV_ROOT/design/include
+incdir+$RV_ROOT/design/dmi
$RV_ROOT/design/swerv_wrapper.sv
$RV_ROOT/design/mem.sv
$RV_ROOT/design/pic_ctrl.sv
$RV_ROOT/design/swerv.sv
$RV_ROOT/design/dma_ctrl.sv
$RV_ROOT/design/ifu/ifu_aln_ctl.sv
$RV_ROOT/design/ifu/ifu_compress_ctl.sv
$RV_ROOT/design/ifu/ifu_ifc_ctl.sv
$RV_ROOT/design/ifu/ifu_bp_ctl.sv
$RV_ROOT/design/ifu/ifu_ic_mem.sv
$RV_ROOT/design/ifu/ifu_mem_ctl.sv
$RV_ROOT/design/ifu/ifu_iccm_mem.sv
$RV_ROOT/design/ifu/ifu.sv
$RV_ROOT/design/dec/dec_decode_ctl.sv
$RV_ROOT/design/dec/dec_gpr_ctl.sv
$RV_ROOT/design/dec/dec_ib_ctl.sv
$RV_ROOT/design/dec/dec_tlu_ctl.sv
$RV_ROOT/design/dec/dec_trigger.sv
$RV_ROOT/design/dec/dec.sv
$RV_ROOT/design/exu/exu_alu_ctl.sv
$RV_ROOT/design/exu/exu_mul_ctl.sv
$RV_ROOT/design/exu/exu_div_ctl.sv
$RV_ROOT/design/exu/exu.sv
$RV_ROOT/design/lsu/lsu.sv
$RV_ROOT/design/lsu/lsu_clkdomain.sv
$RV_ROOT/design/lsu/lsu_addrcheck.sv
$RV_ROOT/design/lsu/lsu_lsc_ctl.sv
$RV_ROOT/design/lsu/lsu_stbuf.sv
$RV_ROOT/design/lsu/lsu_bus_buffer.sv
$RV_ROOT/design/lsu/lsu_bus_intf.sv
$RV_ROOT/design/lsu/lsu_ecc.sv
$RV_ROOT/design/lsu/lsu_dccm_mem.sv
$RV_ROOT/design/lsu/lsu_dccm_ctl.sv
$RV_ROOT/design/lsu/lsu_trigger.sv
$RV_ROOT/design/dbg/dbg.sv
$RV_ROOT/design/dmi/dmi_wrapper.v
$RV_ROOT/design/dmi/dmi_jtag_to_core_sync.v
$RV_ROOT/design/dmi/rvjtag_tap.sv
$RV_ROOT/design/lib/beh_lib.sv
$RV_ROOT/design/lib/mem_lib.sv
$RV_ROOT/design/lib/svci_to_ahb.sv
$RV_ROOT/design/lib/ahb_to_svci.sv
$RV_ROOT/design/lib/svci_to_axi4.sv
$RV_ROOT/design/lib/axi4_to_svci.sv
$RV_ROOT/design/lib/ahb_to_axi4.sv
$RV_ROOT/design/lib/axi4_to_ahb.sv

View File

@ -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] ;

View File

@ -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

208
design/lib/svci_to_axi4.sv Normal file
View File

@ -0,0 +1,208 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright 2018 Western Digital Corporation or it's affiliates.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//********************************************************************************
// $Id$
//
// Owner:
// Function: SVCI to AXI4 Bridge
// Comments:
//
//********************************************************************************
module svci_to_axi4 #(parameter TAG = 1,
ID = 1,
PRTY = 1) (
input logic clk,
input logic rst_l,
input logic scan_mode,
input logic bus_clk_en,
input logic clk_override,
// AXI signals
// AXI Write Channels
output logic axi_awvalid,
input logic axi_awready,
output logic axi_awposted,
output logic [TAG-1:0] axi_awid,
output logic [31:0] axi_awaddr,
output logic [2:0] axi_awsize,
output logic [2:0] axi_awprot,
output logic [7:0] axi_awlen,
output logic [1:0] axi_awburst,
output logic [ID-1:0] axi_awmid,
output logic [PRTY-1:0] axi_awprty,
output logic axi_wvalid,
input logic axi_wready,
output logic [63:0] axi_wdata,
output logic [7:0] axi_wstrb,
output logic axi_wlast,
input logic axi_bvalid,
output logic axi_bready,
input logic axi_bposted,
input logic [1:0] axi_bresp,
input logic [TAG-1:0] axi_bid,
input logic [ID-1:0] axi_bmid,
input logic [PRTY-1:0] axi_bprty,
// AXI Read Channels
output logic axi_arvalid,
input logic axi_arready,
output logic [TAG-1:0] axi_arid,
output logic [31:0] axi_araddr,
output logic [2:0] axi_arsize,
output logic [2:0] axi_arprot,
output logic [7:0] axi_arlen,
output logic [1:0] axi_arburst,
output logic [ID-1:0] axi_armid,
output logic [PRTY-1:0] axi_arprty,
input logic axi_rvalid,
output logic axi_rready,
input logic [TAG-1:0] axi_rid,
input logic [63:0] axi_rdata,
input logic [1:0] axi_rresp,
input logic [ID-1:0] axi_rmid,
input logic [PRTY-1:0] axi_rprty,
// SVCI signals
input logic svci_cmd_valid,
output logic svci_cmd_ready,
input logic [TAG-1:0] svci_cmd_tag,
input logic [ID-1:0] svci_cmd_mid,
input logic [31:0] svci_cmd_addr,
input logic [63:0] svci_cmd_wdata,
input logic [7:0] svci_cmd_wbe,
input logic [2:0] svci_cmd_length,
input logic [2:0] svci_cmd_opc,
input logic [PRTY-1:0] svci_cmd_prty,
input logic dma_slv_algn_err,
output logic svci_rsp_valid,
input logic svci_rsp_ready,
output logic [TAG-1:0] svci_rsp_tag,
output logic [ID-1:0] svci_rsp_mid,
output logic [63:0] svci_rsp_rdata,
output logic [3:0] svci_rsp_opc,
output logic [PRTY-1:0] svci_rsp_prty
);
logic cmdbuf_wr_en, cmdbuf_data_en, cmdbuf_rst, cmdbuf_data_rst;
logic cmdbuf_full;
logic cmdbuf_vld, cmdbuf_data_vld;
logic [2:0] cmdbuf_opc, cmdbuf_size;
logic [7:0] cmdbuf_wstrb;
logic [31:0] cmdbuf_addr;
logic [63:0] cmdbuf_wdata;
logic [TAG-1:0] cmdbuf_tag;
logic [ID-1:0] cmdbuf_mid;
logic [PRTY-1:0] cmdbuf_prty;
logic wrbuf_en, wrbuf_rst;
logic wrbuf_vld;
logic wrbuf_posted;
logic [TAG-1:0] wrbuf_tag;
logic [ID-1:0] wrbuf_mid;
logic [1:0] wrbuf_resp;
logic [63:0] error_address; // SVCI needs the error address back on the rdata.
logic [PRTY-1:0] wrbuf_prty;
logic [1:0] axi_bresp_in; // need to map 2 errors in to 3 errors
logic bus_clk;
// Command buffer
assign cmdbuf_wr_en = svci_cmd_valid & svci_cmd_ready;
assign cmdbuf_data_en = cmdbuf_wr_en & (svci_cmd_opc[2:1] == 2'b01);
assign cmdbuf_rst = ((axi_awvalid & axi_awready) | (axi_arvalid & axi_arready)) & ~cmdbuf_wr_en;
assign cmdbuf_data_rst = (axi_wvalid & axi_wready) & (cmdbuf_opc[2:1] == 2'b01) & ~cmdbuf_data_en;
assign cmdbuf_full = (cmdbuf_vld & ~((axi_awvalid & axi_awready) | (axi_arvalid & axi_arready))) | (cmdbuf_data_vld & ~((axi_wvalid & axi_wready) & (cmdbuf_opc[2:1] == 2'b01)));
rvdffsc #(.WIDTH(1)) cmdbuf_vldff(.din(1'b1), .dout(cmdbuf_vld), .en(cmdbuf_wr_en), .clear(cmdbuf_rst), .clk(bus_clk), .*);
rvdffsc #(.WIDTH(1)) cmdbuf_data_vldff(.din(1'b1), .dout(cmdbuf_data_vld), .en(cmdbuf_data_en), .clear(cmdbuf_data_rst), .clk(bus_clk), .*);
rvdffs #(.WIDTH(3)) cmdbuf_opcff(.din(svci_cmd_opc[2:0]), .dout(cmdbuf_opc[2:0]), .en(cmdbuf_wr_en), .clk(bus_clk), .*);
rvdffs #(.WIDTH(3)) cmdbuf_sizeff(.din(svci_cmd_length[2:0]), .dout(cmdbuf_size[2:0]), .en(cmdbuf_wr_en), .clk(bus_clk), .*);
rvdffe #(.WIDTH(8)) cmdbuf_wstrbff(.din(svci_cmd_wbe[7:0]), .dout(cmdbuf_wstrb[7:0]), .en(cmdbuf_wr_en & bus_clk_en), .*);
rvdffe #(.WIDTH(32)) cmdbuf_addrff(.din(svci_cmd_addr[31:0]), .dout(cmdbuf_addr[31:0]), .en(cmdbuf_wr_en & bus_clk_en), .*);
rvdffe #(.WIDTH(64)) cmdbuf_wdataff(.din(svci_cmd_wdata[63:0]), .dout(cmdbuf_wdata[63:0]), .en(cmdbuf_data_en & bus_clk_en), .*);
rvdffs #(.WIDTH(TAG)) cmdbuf_tagff(.din(svci_cmd_tag[TAG-1:0]), .dout(cmdbuf_tag[TAG-1:0]), .en(cmdbuf_wr_en), .clk(bus_clk), .*);
rvdffs #(.WIDTH(ID)) cmdbuf_midff(.din(svci_cmd_mid[ID-1:0]), .dout(cmdbuf_mid[ID-1:0]), .en(cmdbuf_wr_en), .clk(bus_clk), .*);
rvdffs #(.WIDTH(PRTY)) cmdbuf_prtyff(.din(svci_cmd_prty[PRTY-1:0]), .dout(cmdbuf_prty[PRTY-1:0]), .en(cmdbuf_wr_en), .clk(bus_clk), .*);
// AXI Write Channels
assign axi_awvalid = cmdbuf_vld & (cmdbuf_opc[2:1] == 2'b01);
assign axi_awposted = axi_awvalid & ~cmdbuf_opc[0];
assign axi_awid[TAG-1:0] = cmdbuf_tag[TAG-1:0];
assign axi_awaddr[31:0] = cmdbuf_addr[31:0];
assign axi_awsize[2:0] = cmdbuf_size[2:0];
assign axi_awprot[2:0] = 3'b0;
assign axi_awlen[7:0] = '0;
assign axi_awburst[1:0] = 2'b01;
assign axi_awmid = cmdbuf_mid[ID-1:0];
assign axi_awprty = cmdbuf_prty[PRTY-1:0];
assign axi_wvalid = cmdbuf_data_vld;
assign axi_wdata[63:0] = cmdbuf_wdata[63:0];
assign axi_wstrb[7:0] = cmdbuf_wstrb[7:0];
assign axi_wlast = 1'b1;
assign axi_bready = ~wrbuf_vld | svci_rsp_ready;
// AXI Read Channels
assign axi_arvalid = cmdbuf_vld & (cmdbuf_opc[2:0] == 3'b0);
assign axi_arid[TAG-1:0] = cmdbuf_tag[TAG-1:0];
assign axi_araddr[31:0] = cmdbuf_addr[31:0];
assign axi_arsize[2:0] = cmdbuf_size[2:0];
assign axi_arprot = 3'b0;
assign axi_arlen[7:0] = '0;
assign axi_arburst[1:0] = 2'b01;
assign axi_armid = cmdbuf_mid[ID-1:0];
assign axi_rready = ~wrbuf_vld & svci_rsp_ready;
assign axi_arprty = cmdbuf_prty[PRTY-1:0];
// SVCI_response signals
assign svci_rsp_valid = wrbuf_vld | axi_rvalid;
assign svci_rsp_tag[TAG-1:0] = wrbuf_vld ? wrbuf_tag[TAG-1:0] : axi_rid[TAG-1:0];
assign svci_rsp_mid[ID-1:0] = wrbuf_vld ? wrbuf_mid[ID-1:0] : axi_rmid[ID-1:0];
assign svci_rsp_rdata[63:0] = wrbuf_vld ? {32'b0, error_address[31:0]} : axi_rdata[63:0]; // rdata
assign svci_rsp_opc[3:2] = wrbuf_vld ? {1'b1, ~wrbuf_posted} : 2'b0;
// assign svci_rsp_opc[1:0] = wrbuf_vld ? {wrbuf_resp[1] ? (wrbuf_resp[0] ? 2'b10 : 2'b01) : 2'b0} : // AXI Slave Error -> SVCI Slave Error, AXI Decode Error -> SVCI Address Error
// {axi_rresp[1] ? (axi_rresp[0] ? 2'b10 : 2'b01) : 2'b0};
assign svci_rsp_opc[1:0] = wrbuf_vld ? wrbuf_resp[1:0] : // AXI Slave Error -> SVCI Slave Error, AXI Decode Error -> SVCI Address Error
{axi_rresp[1] ? (axi_rresp[0] ? 2'b10 : {dma_slv_algn_err, 1'b1}) : 2'b0};
assign svci_rsp_prty[PRTY-1:0] = wrbuf_vld ? wrbuf_prty[PRTY-1:0] : axi_rprty[PRTY-1:0];
assign svci_cmd_ready = ~cmdbuf_full;
// Write Response Buffer. Errors for writes need to send the Error address back on the rsp_rdata for SVCI. The address is sent back on axi_rdata bus for both reads and writes that have errors.
// assign wrbuf_en = axi_bvalid & svci_rsp_ready & (~axi_bposted | axi_bresp[1]);
assign wrbuf_en = axi_bvalid & axi_bready & (~axi_bposted | axi_bresp[1]);
assign wrbuf_rst = svci_rsp_valid & svci_rsp_ready & svci_rsp_opc[3] & ~wrbuf_en;
assign axi_bresp_in[1:0] = {axi_bresp[1] ? (axi_bresp[0] ? 2'b10 : {dma_slv_algn_err, 1'b1}) : 2'b0};
rvdffsc #(.WIDTH(1)) wrbuf_vldff (.din(1'b1), .dout(wrbuf_vld), .en(wrbuf_en), .clear(wrbuf_rst), .clk(bus_clk), .*);
rvdffs #(.WIDTH(32)) wrbuf_erroff (.din(axi_rdata[31:0]), .dout(error_address[31:0]), .en(wrbuf_en), .clk(bus_clk), .*);
rvdffs #(.WIDTH(1)) wrbuf_postedff(.din(axi_bposted), .dout(wrbuf_posted), .en(wrbuf_en), .clk(bus_clk), .*);
rvdffs #(.WIDTH(TAG)) wrbuf_tagff (.din(axi_bid[TAG-1:0]), .dout(wrbuf_tag[TAG-1:0]), .en(wrbuf_en), .clk(bus_clk), .*);
rvdffs #(.WIDTH(ID)) wrbuf_midff (.din(axi_bmid[ID-1:0]), .dout(wrbuf_mid[ID-1:0]), .en(wrbuf_en), .clk(bus_clk), .*);
rvdffs #(.WIDTH(PRTY))wrbuf_prtyff (.din(axi_bprty[PRTY-1:0]), .dout(wrbuf_prty[PRTY-1:0]), .en(wrbuf_en), .clk(bus_clk), .*);
rvdffs #(.WIDTH(2)) wrbuf_respff (.din(axi_bresp_in[1:0]), .dout(wrbuf_resp[1:0]), .en(wrbuf_en), .clk(bus_clk), .*);
// Clock header logic
rvclkhdr bus_cgc (.en(bus_clk_en), .l1clk(bus_clk), .*);
endmodule // svci_to_axi4

View File

@ -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

View File

@ -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

View File

@ -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];

View File

@ -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;

View File

@ -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

View File

@ -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`

View File

@ -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

View File

@ -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

8
docs/README.md Normal file
View File

@ -0,0 +1,8 @@
# RISC-V SweRV EH1 1.5 core from Western Digital
## Documentation
### Contents
Name | Description
---------------------- | ------------------------------
RISC-V_SweRV_EH1_PRM.pdf | Programmer's Reference Manual V1.5 for SweRV EH1 core

Binary file not shown.

BIN
docs/RISC-V_SweRV_EH1_PRM.pdf Executable file

Binary file not shown.

View File

@ -1,3 +1,72 @@
# SweRV RISC-V Core<sup>TM</sup> 1.5 from Western Digital
## Release Notes
This is a bug-fix and performance-improvement release. No new functionality
is added to the SweRV core.
1. Bug fixes:
* Hart incorrectly cleared dmcontrol.dmactive on reset (reported by
Codasip). Note that a separate system power-on-reset signal `dbg_rst_l`
was added to differentiate power-on-reset vs core reset.
* Hart never asserted the dmstatus.allrunning signal on reset which
caused a timeout in OpenOCD (reported by Codasip).
* Debug module failed to auto-increment register on system-bus access
of size 64-bit (reported by Codasip).
* The core_rst_n signal was incorrectly connected (reported by Codasip).
* Module/instance renamed for tool compatibility.
* The program counter was getting corrupted when the load/store unit
indicated both a single-bit and a double-bit error in the same
cycle.
* The MSTATUS register was not being updated as expected when both a
non-maskable-interrupt and an MSTATUS-write happened in the same
cycle.
* Write to SBDATA0 was not starting a system-bus write access when
sbreadonaddr/sbreadondata is set.
* Minstret was incorrectly counting ecall/ebreak instructions.
* The dec_tlu_mpc_halted_only signal was not set for MPC halt after
reset.
* The MEPC register was not being updated when a firmware-halt request
was followed by a timer interrupt.
* The MINSTRETH control register was being incremented when
performance counters were disabled.
* Bus driver contained combinational logic from multiple clock
domains that sometimes caused a glitch.
* System bus reads were always being made with 64-bit size for the
AXI bus which is incorrect for IO access.
* DCCM single-bit errors were counted for instructions that did not
commit.
* ICCM single bit errors were double-counted.
* Load/store unit was not detecting access faults when DCCM and PIC
memories are next to each other.
* Single-bit ECC errors on data load were not always corrected in
the DCCM.
* Single-bit ECC errors were not always corrected in the DCCM for DMA
accesses.
* Single-bit errors detected while reading ICCM through DMA were not
being corrected in memory.
2. Improvements:
* Improved performance by removing redundant term in decode stall
logic.
* Reduced power used by the ICCM memory arrays.
3. Testbench Improvements:
* AXI4 and AHB-Lite support.
* Updated bus memory to be persistent and handle larger programs.
* Makefile supports ability to run with source or pre-generated hex
files.
* Makefile supports targets for CoreMarks benchmark (issue #25).
* Questa support in Makefile (Issue #19).
# SweRV RISC-V Core<sup>TM</sup> 1.4 from Western Digital # SweRV RISC-V Core<sup>TM</sup> 1.4 from Western Digital
## Release Notes ## Release Notes
Move declarations to top of Verilog file to fix fpga compile issues. Move declarations to top of Verilog file to fix fpga compile issues.

143
swerv.core Normal file
View File

@ -0,0 +1,143 @@
CAPI=2:
name : chipsalliance.org:cores:SweRV_EH1:1.5
filesets:
rtl:
files:
- design/include/swerv_types.sv
- design/lib/beh_lib.sv
- design/mem.sv
- design/pic_ctrl.sv
- design/dma_ctrl.sv
- design/ifu/ifu_aln_ctl.sv
- design/ifu/ifu_compress_ctl.sv
- design/ifu/ifu_ifc_ctl.sv
- design/ifu/ifu_bp_ctl.sv
- design/ifu/ifu_ic_mem.sv
- design/ifu/ifu_mem_ctl.sv
- design/ifu/ifu_iccm_mem.sv
- design/ifu/ifu.sv
- design/dec/dec_decode_ctl.sv
- design/dec/dec_gpr_ctl.sv
- design/dec/dec_ib_ctl.sv
- design/dec/dec_tlu_ctl.sv
- design/dec/dec_trigger.sv
- design/dec/dec.sv
- design/exu/exu_alu_ctl.sv
- design/exu/exu_mul_ctl.sv
- design/exu/exu_div_ctl.sv
- design/exu/exu.sv
- design/lsu/lsu.sv
- design/lsu/lsu_bus_buffer.sv
- design/lsu/lsu_clkdomain.sv
- design/lsu/lsu_addrcheck.sv
- design/lsu/lsu_lsc_ctl.sv
- design/lsu/lsu_stbuf.sv
- design/lsu/lsu_bus_intf.sv
- design/lsu/lsu_ecc.sv
- design/lsu/lsu_dccm_mem.sv
- design/lsu/lsu_dccm_ctl.sv
- design/lsu/lsu_trigger.sv
- design/dbg/dbg.sv
- design/dmi/dmi_wrapper.v
- design/dmi/dmi_jtag_to_core_sync.v
- design/dmi/rvjtag_tap.sv
- design/lib/mem_lib.sv
- design/lib/ahb_to_axi4.sv
- design/lib/axi4_to_ahb.sv
- design/swerv.sv
- design/swerv_wrapper.sv
file_type : systemVerilogSource
includes:
files:
- design/include/build.h : {is_include_file : true}
- design/include/global.h : {is_include_file : true}
file_type : systemVerilogSource
mem_init:
files:
- testbench/hex/data.hex : {copyto : data.hex}
- testbench/hex/program.hex : {copyto : program.hex}
file_type : user
tb:
files: [testbench/ahb_sif.sv, testbench/tb_top.sv]
file_type : systemVerilogSource
verilator_tb:
files : [testbench/test_tb_top.cpp : {file_type : cppSource}]
vivado_tcl: {files: [tools/vivado.tcl : {file_type : tclSource}]}
targets:
default:
filesets :
- includes
- rtl
- "tool_vivado ? (vivado_tcl)"
lint:
default_tool: verilator
filesets : [includes, rtl]
generate : [swerv_default_config]
tools:
verilator :
mode : lint-only
toplevel : swerv_wrapper
sim:
default_tool : verilator
filesets :
- includes
- rtl
- mem_init
- tb
- "tool_verilator? (verilator_tb)"
generate : [swerv_ahb_config]
tools:
modelsim:
vlog_options :
- -mfcu
- -cuautoname=du
- config/common_defines.vh
verilator:
verilator_options : [--trace, -Wno-fatal]
toplevel : tb_top
synth:
default_tool : vivado
filesets : [includes, rtl, vivado_tcl]
generate : [swerv_fpga_config]
tools:
vivado:
part : xc7a100tcsg324-1
pnr : none
toplevel : swerv_wrapper
generate:
swerv_ahb_config:
generator: swerv_config
position : first
parameters:
args : ['-ahb_lite', -unset=assert_on]
swerv_default_config:
generator: swerv_config
position : first
parameters:
args : [-unset=assert_on]
swerv_fpga_config:
generator: swerv_config
position : first
parameters:
args : [-unset=assert_on, -set=fpga_optimize=1]
generators:
swerv_config:
interpreter: python
command: configs/swerv_config_gen.py
description : Create a SweRV configuration. Note! Only supports the default config

View File

@ -13,154 +13,183 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
// //
`ifdef RV_BUILD_AHB_LITE
module ahb_sif ( module ahb_sif (
input logic [63:0] HWDATA, input logic [63:0] HWDATA,
input logic HCLK, input logic HCLK,
input logic HSEL, input logic HSEL,
input logic [3:0] HPROT, input logic [3:0] HPROT,
input logic HWRITE, input logic HWRITE,
input logic [1:0] HTRANS, input logic [1:0] HTRANS,
input logic [2:0] HSIZE, input logic [2:0] HSIZE,
input logic HREADY, input logic HREADY,
input logic HRESETn, input logic HRESETn,
input logic [31:0] HADDR, input logic [31:0] HADDR,
input logic [2:0] HBURST, input logic [2:0] HBURST,
output logic HREADYOUT,
output logic HRESP,
output logic [63:0] HRDATA
output logic HREADYOUT,
output logic HRESP,
output logic [63:0] HRDATA
); );
localparam MEM_SIZE_DW = 8192; parameter MEM_SIZE_DW = 8192;
localparam MAILBOX_ADDR = 32'hD0580000; parameter MAILBOX_ADDR = 32'hD0580000;
localparam MEM_SIZE = MEM_SIZE_DW*8;
logic Last_HSEL; logic Write;
logic NextLast_HSEL;
logic Last_HWRITE;
logic [1:0] Last_HTRANS;
logic [1:0] NextLast_HTRANS;
logic [31:0] Last_HADDR; logic [31:0] Last_HADDR;
logic [63:0] Next_HRDATA; logic [7:0] strb_lat;
logic [63:0] WriteReadData;
logic [63:0] WriteMask;
bit [7:0] mem [0:MEM_SIZE_DW-1];
bit [7:0] mem [0:MEM_SIZE-1];
//bit [7:0] mem [int];
//int kuku[int];
// Wires // Wires
wire [63:0] Next_WriteMask = HSIZE == 3'b000 ? (64'hff << {HADDR[2:0], 3'b000}) : (HSIZE == 3'b001 ? (64'hffff << {HADDR[2], 4'h0}) : (HSIZE == 3'b010 ? (64'hffff_ffff << {HADDR[3],5'h0}) : 64'hffff_ffff_ffff_ffff)); wire [63:0] WriteData = HWDATA;
wire [7:0] strb = HSIZE == 3'b000 ? 8'h1 << HADDR[2:0] :
HSIZE == 3'b001 ? 8'h3 << {HADDR[2:1],1'b0} :
HSIZE == 3'b010 ? 8'hf << {HADDR[2],2'b0} : 8'hff;
wire [63:0] MaskedWriteData = HWDATA & WriteMask; wire[31:0] addr = HADDR & (MEM_SIZE-1);
wire [63:0] MaskedWriteReadData = WriteReadData & ~WriteMask; wire[31:0] laddr = Last_HADDR & (MEM_SIZE-1);
wire [63:0] WriteData = (MaskedWriteData | MaskedWriteReadData );
wire Write = &{Last_HSEL, Last_HWRITE, Last_HTRANS[1]};
wire Read = &{ HSEL, ~HWRITE, HTRANS[1]};
wire mailbox_write = &{Write, Last_HADDR==MAILBOX_ADDR, HRESETn==1}; wire mailbox_write = Write && Last_HADDR==MAILBOX_ADDR;
wire Next_HWRITE = |{HTRANS} ? HWRITE : Last_HWRITE;
wire [63:0] mem_dout = {mem[{Last_HADDR[12:3],3'b0}+7],mem[{Last_HADDR[12:3],3'b0}+6],mem[{Last_HADDR[12:3],3'b0}+5],mem[{Last_HADDR[12:3],3'b0}+4],mem[{Last_HADDR[12:3],3'b0}+3],mem[{Last_HADDR[12:3],3'b0}+2],mem[{Last_HADDR[12:3],3'b0}+1],mem[{Last_HADDR[12:3],3'b0}]}; wire [63:0] mem_dout = {mem[{addr[31:3],3'd7}],
mem[{addr[31:3],3'd6}],
mem[{addr[31:3],3'd5}],
mem[{addr[31:3],3'd4}],
mem[{addr[31:3],3'd3}],
mem[{addr[31:3],3'd2}],
mem[{addr[31:3],3'd1}],
mem[{addr[31:3],3'd0}]};
always @ (posedge HCLK or negedge HRESETn) begin always @ (negedge HCLK ) begin
if (Write && Last_HADDR == 32'h0) begin if (Write) begin
mem[{Last_HADDR[12:3],3'b0}+7] <= #1 { WriteData[63:56] }; if(strb_lat[7]) mem[{laddr[31:3],3'd7}] = HWDATA[63:56];
mem[{Last_HADDR[12:3],3'b0}+6] <= #1 { WriteData[55:48] }; if(strb_lat[6]) mem[{laddr[31:3],3'd6}] = HWDATA[55:48];
mem[{Last_HADDR[12:3],3'b0}+5] <= #1 { WriteData[47:40] }; if(strb_lat[5]) mem[{laddr[31:3],3'd5}] = HWDATA[47:40];
mem[{Last_HADDR[12:3],3'b0}+4] <= #1 { WriteData[39:32] }; if(strb_lat[4]) mem[{laddr[31:3],3'd4}] = HWDATA[39:32];
mem[{Last_HADDR[12:3],3'b0}+3] <= #1 { WriteData[31:24] }; if(strb_lat[3]) mem[{laddr[31:3],3'd3}] = HWDATA[31:24];
mem[{Last_HADDR[12:3],3'b0}+2] <= #1 { WriteData[23:16] }; if(strb_lat[2]) mem[{laddr[31:3],3'd2}] = HWDATA[23:16];
mem[{Last_HADDR[12:3],3'b0}+1] <= #1 { WriteData[15:08] }; if(strb_lat[1]) mem[{laddr[31:3],3'd1}] = HWDATA[15:08];
mem[{Last_HADDR[12:3],3'b0}+0] <= #1 { WriteData[07:00] }; if(strb_lat[0]) mem[{laddr[31:3],3'd0}] = HWDATA[07:00];
end end
end end
assign HREADYOUT = 1;
assign HRESP = 0;
always @(posedge HCLK or negedge HRESETn) begin always @(posedge HCLK or negedge HRESETn) begin
if(~HRESETn) begin if(~HRESETn) begin
HREADYOUT <= #1 1'b0 ; Last_HADDR <= 32'b0;
HRESP <= #1 1'b0; Write <= 1'b0;
HRDATA <= '0;
end else begin end else begin
HREADYOUT <= #1 |HTRANS; Last_HADDR <= HADDR;
HRESP <= #1 1'b0; Write <= HWRITE & |HTRANS;
WriteMask <= #1 Next_WriteMask; if(|HTRANS & ~HWRITE)
end HRDATA <= mem_dout;
end strb_lat <= strb;
`ifdef VERILATOR
always @(posedge HCLK or negedge HRESETn) begin
`else
always @(negedge HCLK or negedge HRESETn) begin
`endif
if(~HRESETn) begin
Last_HADDR <= #1 32'b0;
end else begin
Last_HADDR <= #1 |{HTRANS} ? {HADDR[31:2], 2'b00} : Last_HADDR;
end
end
always @(posedge HCLK or negedge HRESETn) begin
if(~HRESETn) begin
Last_HWRITE <= #1 1'b0;
end else begin
Last_HWRITE <= #1 Next_HWRITE;
end
end
always @(posedge HCLK or negedge HRESETn) begin
if(~HRESETn) begin
Last_HTRANS <= #1 2'b0;
end else begin
Last_HTRANS <= #1 HTRANS;
end
end
always @(posedge HCLK or negedge HRESETn) begin
if(~HRESETn) begin
Last_HSEL <= #1 1'b0;
end else begin
Last_HSEL <= #1 HSEL;
end
end
`ifndef VERILATOR
always @(posedge HCLK or negedge HRESETn) begin
if(~HRESETn) begin
HRDATA <= #1 Next_HRDATA ;
end else begin
HRDATA <= #1 Next_HRDATA ;
end
end
always @* begin
Next_HRDATA = mem_dout;
end
`else
always @(posedge HCLK) begin
Next_HRDATA <= mem_dout;
end
assign HRDATA = mem_dout;
`endif
always @* begin
if(Last_HSEL) begin
WriteReadData[07:00] = mem[{Last_HADDR[12:3],3'b0}];
WriteReadData[15:08] = mem[{Last_HADDR[12:3],3'b0}+1];
WriteReadData[23:16] = mem[{Last_HADDR[12:3],3'b0}+2];
WriteReadData[31:24] = mem[{Last_HADDR[12:3],3'b0}+3];
WriteReadData[39:32] = mem[{Last_HADDR[12:3],3'b0}+4];
WriteReadData[47:40] = mem[{Last_HADDR[12:3],3'b0}+5];
WriteReadData[55:48] = mem[{Last_HADDR[12:3],3'b0}+6];
WriteReadData[63:56] = mem[{Last_HADDR[12:3],3'b0}+7];
end end
end end
endmodule endmodule
`endif
`ifdef RV_BUILD_AXI4
module axi_slv #(TAGW=1) (
input aclk,
input rst_l,
input arvalid,
output reg arready,
input [31:0] araddr,
input [TAGW-1:0] arid,
input [7:0] arlen,
input [1:0] arburst,
input [2:0] arsize,
output reg rvalid,
input rready,
output reg [63:0] rdata,
output reg [1:0] rresp,
output reg [TAGW-1:0] rid,
output rlast,
input awvalid,
output awready,
input [31:0] awaddr,
input [TAGW-1:0] awid,
input [7:0] awlen,
input [1:0] awburst,
input [2:0] awsize,
input [63:0] wdata,
input [7:0] wstrb,
input wvalid,
output wready,
output reg bvalid,
input bready,
output reg [1:0] bresp,
output reg [TAGW-1:0] bid
);
parameter MAILBOX_ADDR = 32'hD0580000;
parameter MEM_SIZE_DW = 8192;
bit [7:0] mem [0:MEM_SIZE_DW*8-1];
bit [63:0] memdata;
wire [31:0] waddr, raddr;
wire [63:0] WriteData;
wire mailbox_write;
assign raddr = araddr & (MEM_SIZE_DW*8-1);
assign waddr = awaddr & (MEM_SIZE_DW*8-1);
assign mailbox_write = awvalid && awaddr==MAILBOX_ADDR && rst_l;
assign WriteData = wdata;
always @ ( posedge aclk or negedge rst_l) begin
if(!rst_l) begin
rvalid <= 0;
bvalid <= 0;
end
else begin
bid <= awid;
rid <= arid;
rvalid <= arvalid;
bvalid <= awvalid;
rdata <= memdata;
end
end
always @ ( negedge aclk) begin
if(arvalid) memdata <= {mem[raddr+7], mem[raddr+6], mem[raddr+5], mem[raddr+4],
mem[raddr+3], mem[raddr+2], mem[raddr+1], mem[raddr]};
if(awvalid) begin
if(wstrb[7]) mem[waddr+7] = wdata[63:56];
if(wstrb[6]) mem[waddr+6] = wdata[55:48];
if(wstrb[5]) mem[waddr+5] = wdata[47:40];
if(wstrb[4]) mem[waddr+4] = wdata[39:32];
if(wstrb[3]) mem[waddr+3] = wdata[31:24];
if(wstrb[2]) mem[waddr+2] = wdata[23:16];
if(wstrb[1]) mem[waddr+1] = wdata[15:08];
if(wstrb[0]) mem[waddr+0] = wdata[07:00];
end
end
assign arready = 1'b1;
assign awready = 1'b1;
assign wready = 1'b1;
assign rresp = 2'b0;
assign bresp = 2'b0;
assign rlast = 1'b1;
endmodule
`endif

2403
testbench/asm/cmark.c Normal file

File diff suppressed because it is too large Load Diff

1
testbench/asm/cmark_dccm.c Symbolic link
View File

@ -0,0 +1 @@
cmark.c

1
testbench/asm/cmark_dccm.ld Symbolic link
View File

@ -0,0 +1 @@
hello_world_dccm.ld

2404
testbench/asm/cmark_iccm.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,17 @@
OUTPUT_ARCH( "riscv" )
ENTRY(_start)
MEMORY {
EXTCODE : ORIGIN = 0, LENGTH = 0x10000
EXTDATA : ORIGIN = 0x10000, LENGTH = 0x10000
ICCM : ORIGIN = 0xee000000, LENGTH = 0x80000
DCCM : ORIGIN = 0xf0040000, LENGTH = 0x10000
}
SECTIONS {
.text_init : {*(.text_init)} > EXTCODE
init_end = .;
.data.ctl : AT(0xffec) { LONG(ADDR(.text)); LONG(text_end); LONG(LOADADDR(.text)); LONG(0xf0040000); LONG(STACK)}>EXTDATA
.text : AT(init_end) { *(.text) *(.text.startup)} > ICCM
text_end = .;
.data : AT(0x10000) { *(.*data) *(.rodata*) STACK = ALIGN(16) + 0x8000;} > DCCM
}

View File

@ -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

View File

@ -0,0 +1,12 @@
OUTPUT_ARCH( "riscv" )
ENTRY(_start)
SECTIONS {
.text : { *(.text*) }
_end = .;
. = 0xfff8;
.data.ctl : { LONG(0xf0040000); LONG(STACK) }
. = 0xf0040000;
.data : AT(0x10000) { *(.*data) *(.rodata*) STACK = ALIGN(16) + 0x8000;}
}

View File

@ -0,0 +1 @@
hello_world.s

42
testbench/flist Normal file
View File

@ -0,0 +1,42 @@
$RV_ROOT/design/swerv_wrapper.sv
$RV_ROOT/design/mem.sv
$RV_ROOT/design/pic_ctrl.sv
$RV_ROOT/design/swerv.sv
$RV_ROOT/design/dma_ctrl.sv
$RV_ROOT/design/ifu/ifu_aln_ctl.sv
$RV_ROOT/design/ifu/ifu_compress_ctl.sv
$RV_ROOT/design/ifu/ifu_ifc_ctl.sv
$RV_ROOT/design/ifu/ifu_bp_ctl.sv
$RV_ROOT/design/ifu/ifu_ic_mem.sv
$RV_ROOT/design/ifu/ifu_mem_ctl.sv
$RV_ROOT/design/ifu/ifu_iccm_mem.sv
$RV_ROOT/design/ifu/ifu.sv
$RV_ROOT/design/dec/dec_decode_ctl.sv
$RV_ROOT/design/dec/dec_gpr_ctl.sv
$RV_ROOT/design/dec/dec_ib_ctl.sv
$RV_ROOT/design/dec/dec_tlu_ctl.sv
$RV_ROOT/design/dec/dec_trigger.sv
$RV_ROOT/design/dec/dec.sv
$RV_ROOT/design/exu/exu_alu_ctl.sv
$RV_ROOT/design/exu/exu_mul_ctl.sv
$RV_ROOT/design/exu/exu_div_ctl.sv
$RV_ROOT/design/exu/exu.sv
$RV_ROOT/design/lsu/lsu.sv
$RV_ROOT/design/lsu/lsu_clkdomain.sv
$RV_ROOT/design/lsu/lsu_addrcheck.sv
$RV_ROOT/design/lsu/lsu_lsc_ctl.sv
$RV_ROOT/design/lsu/lsu_stbuf.sv
$RV_ROOT/design/lsu/lsu_bus_buffer.sv
$RV_ROOT/design/lsu/lsu_bus_intf.sv
$RV_ROOT/design/lsu/lsu_ecc.sv
$RV_ROOT/design/lsu/lsu_dccm_mem.sv
$RV_ROOT/design/lsu/lsu_dccm_ctl.sv
$RV_ROOT/design/lsu/lsu_trigger.sv
$RV_ROOT/design/dbg/dbg.sv
$RV_ROOT/design/dmi/dmi_wrapper.v
$RV_ROOT/design/dmi/dmi_jtag_to_core_sync.v
$RV_ROOT/design/dmi/rvjtag_tap.sv
-v $RV_ROOT/design/lib/beh_lib.sv
-v $RV_ROOT/design/lib/mem_lib.sv
-v $RV_ROOT/design/lib/ahb_to_axi4.sv
-v $RV_ROOT/design/lib/axi4_to_ahb.sv

View File

@ -0,0 +1,93 @@
@00000000
A4 05 01 00 AC 05 01 00 B4 05 01 00 96 3F 00 00
96 3F 00 00 D0 3F 00 00 D0 3F 00 00 6C 40 00 00
2E 7A 00 00 0E 7A 00 00 16 7A 00 00 1E 7A 00 00
26 7A 00 00 06 7A 00 00 36 8B 00 00 60 85 00 00
60 85 00 00 60 85 00 00 60 85 00 00 60 85 00 00
60 85 00 00 60 85 00 00 60 85 00 00 60 85 00 00
60 85 00 00 3C 8A 00 00 4A 8A 00 00 60 85 00 00
60 85 00 00 60 85 00 00 60 85 00 00 60 85 00 00
60 85 00 00 60 85 00 00 60 85 00 00 60 85 00 00
60 85 00 00 7C 88 00 00 60 85 00 00 60 85 00 00
60 85 00 00 10 88 00 00 60 85 00 00 24 87 00 00
60 85 00 00 60 85 00 00 36 8B 00 00 84 05 01 00
8C 05 01 00 94 05 01 00 9C 05 01 00 54 05 01 00
60 05 01 00 6C 05 01 00 78 05 01 00 24 05 01 00
30 05 01 00 3C 05 01 00 48 05 01 00 F4 04 01 00
00 05 01 00 0C 05 01 00 18 05 01 00 01 00 00 00
01 00 00 00 66 00 00 00 36 6B 20 70 65 72 66 6F
72 6D 61 6E 63 65 20 72 75 6E 20 70 61 72 61 6D
65 74 65 72 73 20 66 6F 72 20 63 6F 72 65 6D 61
72 6B 2E 0A 00 00 00 00 36 6B 20 76 61 6C 69 64
61 74 69 6F 6E 20 72 75 6E 20 70 61 72 61 6D 65
74 65 72 73 20 66 6F 72 20 63 6F 72 65 6D 61 72
6B 2E 0A 00 50 72 6F 66 69 6C 65 20 67 65 6E 65
72 61 74 69 6F 6E 20 72 75 6E 20 70 61 72 61 6D
65 74 65 72 73 20 66 6F 72 20 63 6F 72 65 6D 61
72 6B 2E 0A 00 00 00 00 32 4B 20 70 65 72 66 6F
72 6D 61 6E 63 65 20 72 75 6E 20 70 61 72 61 6D
65 74 65 72 73 20 66 6F 72 20 63 6F 72 65 6D 61
72 6B 2E 0A 00 00 00 00 32 4B 20 76 61 6C 69 64
61 74 69 6F 6E 20 72 75 6E 20 70 61 72 61 6D 65
74 65 72 73 20 66 6F 72 20 63 6F 72 65 6D 61 72
6B 2E 0A 00 5B 25 75 5D 45 52 52 4F 52 21 20 6C
69 73 74 20 63 72 63 20 30 78 25 30 34 78 20 2D
20 73 68 6F 75 6C 64 20 62 65 20 30 78 25 30 34
78 0A 00 00 5B 25 75 5D 45 52 52 4F 52 21 20 6D
61 74 72 69 78 20 63 72 63 20 30 78 25 30 34 78
20 2D 20 73 68 6F 75 6C 64 20 62 65 20 30 78 25
30 34 78 0A 00 00 00 00 5B 25 75 5D 45 52 52 4F
52 21 20 73 74 61 74 65 20 63 72 63 20 30 78 25
30 34 78 20 2D 20 73 68 6F 75 6C 64 20 62 65 20
30 78 25 30 34 78 0A 00 43 6F 72 65 4D 61 72 6B
20 53 69 7A 65 20 20 20 20 3A 20 25 75 0A 00 00
54 6F 74 61 6C 20 74 69 63 6B 73 20 20 20 20 20
20 3A 20 25 75 0A 00 00 54 6F 74 61 6C 20 74 69
6D 65 20 28 73 65 63 73 29 3A 20 25 64 0A 00 00
45 52 52 4F 52 21 20 4D 75 73 74 20 65 78 65 63
75 74 65 20 66 6F 72 20 61 74 20 6C 65 61 73 74
20 31 30 20 73 65 63 73 20 66 6F 72 20 61 20 76
61 6C 69 64 20 72 65 73 75 6C 74 21 0A 00 00 00
49 74 65 72 61 74 2F 53 65 63 2F 4D 48 7A 20 20
20 3A 20 25 64 2E 25 64 0A 00 00 00 49 74 65 72
61 74 69 6F 6E 73 20 20 20 20 20 20 20 3A 20 25
75 0A 00 00 47 43 43 37 2E 32 2E 30 00 00 00 00
43 6F 6D 70 69 6C 65 72 20 76 65 72 73 69 6F 6E
20 3A 20 25 73 0A 00 00 2D 4F 32 00 43 6F 6D 70
69 6C 65 72 20 66 6C 61 67 73 20 20 20 3A 20 25
73 0A 00 00 53 54 41 54 49 43 00 00 4D 65 6D 6F
72 79 20 6C 6F 63 61 74 69 6F 6E 20 20 3A 20 25
73 0A 00 00 73 65 65 64 63 72 63 20 20 20 20 20
20 20 20 20 20 3A 20 30 78 25 30 34 78 0A 00 00
5B 25 64 5D 63 72 63 6C 69 73 74 20 20 20 20 20
20 20 3A 20 30 78 25 30 34 78 0A 00 5B 25 64 5D
63 72 63 6D 61 74 72 69 78 20 20 20 20 20 3A 20
30 78 25 30 34 78 0A 00 5B 25 64 5D 63 72 63 73
74 61 74 65 20 20 20 20 20 20 3A 20 30 78 25 30
34 78 0A 00 5B 25 64 5D 63 72 63 66 69 6E 61 6C
20 20 20 20 20 20 3A 20 30 78 25 30 34 78 0A 00
43 6F 72 72 65 63 74 20 6F 70 65 72 61 74 69 6F
6E 20 76 61 6C 69 64 61 74 65 64 2E 20 53 65 65
20 72 65 61 64 6D 65 2E 74 78 74 20 66 6F 72 20
72 75 6E 20 61 6E 64 20 72 65 70 6F 72 74 69 6E
67 20 72 75 6C 65 73 2E 0A 00 00 00 45 72 72 6F
72 73 20 64 65 74 65 63 74 65 64 0A 00 00 00 00
43 61 6E 6E 6F 74 20 76 61 6C 69 64 61 74 65 20
6F 70 65 72 61 74 69 6F 6E 20 66 6F 72 20 74 68
65 73 65 20 73 65 65 64 20 76 61 6C 75 65 73 2C
20 70 6C 65 61 73 65 20 63 6F 6D 70 61 72 65 20
77 69 74 68 20 72 65 73 75 6C 74 73 20 6F 6E 20
61 20 6B 6E 6F 77 6E 20 70 6C 61 74 66 6F 72 6D
2E 0A 00 00 54 30 2E 33 65 2D 31 46 00 00 00 00
2D 54 2E 54 2B 2B 54 71 00 00 00 00 31 54 33 2E
34 65 34 7A 00 00 00 00 33 34 2E 30 65 2D 54 5E
00 00 00 00 35 2E 35 30 30 65 2B 33 00 00 00 00
2D 2E 31 32 33 65 2D 32 00 00 00 00 2D 38 37 65
2B 38 33 32 00 00 00 00 2B 30 2E 36 65 2D 31 32
00 00 00 00 33 35 2E 35 34 34 30 30 00 00 00 00
2E 31 32 33 34 35 30 30 00 00 00 00 2D 31 31 30
2E 37 30 30 00 00 00 00 2B 30 2E 36 34 34 30 30
00 00 00 00 35 30 31 32 00 00 00 00 31 32 33 34
00 00 00 00 2D 38 37 34 00 00 00 00 2B 31 32 32
00 00 00 00 53 74 61 74 69 63 00 00 48 65 61 70
00 00 00 00 53 74 61 63 6B 00 00 00

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,95 @@
@00000000
A4 05 04 F0 AC 05 04 F0 B4 05 04 F0 9A 3F 00 00
9A 3F 00 00 D4 3F 00 00 D4 3F 00 00 70 40 00 00
3E 7A 00 00 16 7A 00 00 20 7A 00 00 2A 7A 00 00
34 7A 00 00 0C 7A 00 00 50 8B 00 00 7A 85 00 00
7A 85 00 00 7A 85 00 00 7A 85 00 00 7A 85 00 00
7A 85 00 00 7A 85 00 00 7A 85 00 00 7A 85 00 00
7A 85 00 00 56 8A 00 00 64 8A 00 00 7A 85 00 00
7A 85 00 00 7A 85 00 00 7A 85 00 00 7A 85 00 00
7A 85 00 00 7A 85 00 00 7A 85 00 00 7A 85 00 00
7A 85 00 00 96 88 00 00 7A 85 00 00 7A 85 00 00
7A 85 00 00 2A 88 00 00 7A 85 00 00 3E 87 00 00
7A 85 00 00 7A 85 00 00 50 8B 00 00 84 05 04 F0
8C 05 04 F0 94 05 04 F0 9C 05 04 F0 54 05 04 F0
60 05 04 F0 6C 05 04 F0 78 05 04 F0 24 05 04 F0
30 05 04 F0 3C 05 04 F0 48 05 04 F0 F4 04 04 F0
00 05 04 F0 0C 05 04 F0 18 05 04 F0 01 00 00 00
01 00 00 00 66 00 00 00 36 6B 20 70 65 72 66 6F
72 6D 61 6E 63 65 20 72 75 6E 20 70 61 72 61 6D
65 74 65 72 73 20 66 6F 72 20 63 6F 72 65 6D 61
72 6B 2E 0A 00 00 00 00 36 6B 20 76 61 6C 69 64
61 74 69 6F 6E 20 72 75 6E 20 70 61 72 61 6D 65
74 65 72 73 20 66 6F 72 20 63 6F 72 65 6D 61 72
6B 2E 0A 00 50 72 6F 66 69 6C 65 20 67 65 6E 65
72 61 74 69 6F 6E 20 72 75 6E 20 70 61 72 61 6D
65 74 65 72 73 20 66 6F 72 20 63 6F 72 65 6D 61
72 6B 2E 0A 00 00 00 00 32 4B 20 70 65 72 66 6F
72 6D 61 6E 63 65 20 72 75 6E 20 70 61 72 61 6D
65 74 65 72 73 20 66 6F 72 20 63 6F 72 65 6D 61
72 6B 2E 0A 00 00 00 00 32 4B 20 76 61 6C 69 64
61 74 69 6F 6E 20 72 75 6E 20 70 61 72 61 6D 65
74 65 72 73 20 66 6F 72 20 63 6F 72 65 6D 61 72
6B 2E 0A 00 5B 25 75 5D 45 52 52 4F 52 21 20 6C
69 73 74 20 63 72 63 20 30 78 25 30 34 78 20 2D
20 73 68 6F 75 6C 64 20 62 65 20 30 78 25 30 34
78 0A 00 00 5B 25 75 5D 45 52 52 4F 52 21 20 6D
61 74 72 69 78 20 63 72 63 20 30 78 25 30 34 78
20 2D 20 73 68 6F 75 6C 64 20 62 65 20 30 78 25
30 34 78 0A 00 00 00 00 5B 25 75 5D 45 52 52 4F
52 21 20 73 74 61 74 65 20 63 72 63 20 30 78 25
30 34 78 20 2D 20 73 68 6F 75 6C 64 20 62 65 20
30 78 25 30 34 78 0A 00 43 6F 72 65 4D 61 72 6B
20 53 69 7A 65 20 20 20 20 3A 20 25 75 0A 00 00
54 6F 74 61 6C 20 74 69 63 6B 73 20 20 20 20 20
20 3A 20 25 75 0A 00 00 54 6F 74 61 6C 20 74 69
6D 65 20 28 73 65 63 73 29 3A 20 25 64 0A 00 00
45 52 52 4F 52 21 20 4D 75 73 74 20 65 78 65 63
75 74 65 20 66 6F 72 20 61 74 20 6C 65 61 73 74
20 31 30 20 73 65 63 73 20 66 6F 72 20 61 20 76
61 6C 69 64 20 72 65 73 75 6C 74 21 0A 00 00 00
49 74 65 72 61 74 2F 53 65 63 2F 4D 48 7A 20 20
20 3A 20 25 64 2E 25 64 0A 00 00 00 49 74 65 72
61 74 69 6F 6E 73 20 20 20 20 20 20 20 3A 20 25
75 0A 00 00 47 43 43 37 2E 32 2E 30 00 00 00 00
43 6F 6D 70 69 6C 65 72 20 76 65 72 73 69 6F 6E
20 3A 20 25 73 0A 00 00 2D 4F 32 00 43 6F 6D 70
69 6C 65 72 20 66 6C 61 67 73 20 20 20 3A 20 25
73 0A 00 00 53 54 41 54 49 43 00 00 4D 65 6D 6F
72 79 20 6C 6F 63 61 74 69 6F 6E 20 20 3A 20 25
73 0A 00 00 73 65 65 64 63 72 63 20 20 20 20 20
20 20 20 20 20 3A 20 30 78 25 30 34 78 0A 00 00
5B 25 64 5D 63 72 63 6C 69 73 74 20 20 20 20 20
20 20 3A 20 30 78 25 30 34 78 0A 00 5B 25 64 5D
63 72 63 6D 61 74 72 69 78 20 20 20 20 20 3A 20
30 78 25 30 34 78 0A 00 5B 25 64 5D 63 72 63 73
74 61 74 65 20 20 20 20 20 20 3A 20 30 78 25 30
34 78 0A 00 5B 25 64 5D 63 72 63 66 69 6E 61 6C
20 20 20 20 20 20 3A 20 30 78 25 30 34 78 0A 00
43 6F 72 72 65 63 74 20 6F 70 65 72 61 74 69 6F
6E 20 76 61 6C 69 64 61 74 65 64 2E 20 53 65 65
20 72 65 61 64 6D 65 2E 74 78 74 20 66 6F 72 20
72 75 6E 20 61 6E 64 20 72 65 70 6F 72 74 69 6E
67 20 72 75 6C 65 73 2E 0A 00 00 00 45 72 72 6F
72 73 20 64 65 74 65 63 74 65 64 0A 00 00 00 00
43 61 6E 6E 6F 74 20 76 61 6C 69 64 61 74 65 20
6F 70 65 72 61 74 69 6F 6E 20 66 6F 72 20 74 68
65 73 65 20 73 65 65 64 20 76 61 6C 75 65 73 2C
20 70 6C 65 61 73 65 20 63 6F 6D 70 61 72 65 20
77 69 74 68 20 72 65 73 75 6C 74 73 20 6F 6E 20
61 20 6B 6E 6F 77 6E 20 70 6C 61 74 66 6F 72 6D
2E 0A 00 00 54 30 2E 33 65 2D 31 46 00 00 00 00
2D 54 2E 54 2B 2B 54 71 00 00 00 00 31 54 33 2E
34 65 34 7A 00 00 00 00 33 34 2E 30 65 2D 54 5E
00 00 00 00 35 2E 35 30 30 65 2B 33 00 00 00 00
2D 2E 31 32 33 65 2D 32 00 00 00 00 2D 38 37 65
2B 38 33 32 00 00 00 00 2B 30 2E 36 65 2D 31 32
00 00 00 00 33 35 2E 35 34 34 30 30 00 00 00 00
2E 31 32 33 34 35 30 30 00 00 00 00 2D 31 31 30
2E 37 30 30 00 00 00 00 2B 30 2E 36 34 34 30 30
00 00 00 00 35 30 31 32 00 00 00 00 31 32 33 34
00 00 00 00 2D 38 37 34 00 00 00 00 2B 31 32 32
00 00 00 00 53 74 61 74 69 63 00 00 48 65 61 70
00 00 00 00 53 74 61 63 6B 00 00 00
@0000FFF8
00 00 04 F0 C0 85 04 F0

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,96 @@
@00000000
A4 05 04 F0 AC 05 04 F0 B4 05 04 F0 58 3F 00 EE
58 3F 00 EE 92 3F 00 EE 92 3F 00 EE 2E 40 00 EE
F4 79 00 EE CC 79 00 EE D6 79 00 EE E0 79 00 EE
EA 79 00 EE C2 79 00 EE 06 8B 00 EE 30 85 00 EE
30 85 00 EE 30 85 00 EE 30 85 00 EE 30 85 00 EE
30 85 00 EE 30 85 00 EE 30 85 00 EE 30 85 00 EE
30 85 00 EE 0C 8A 00 EE 1A 8A 00 EE 30 85 00 EE
30 85 00 EE 30 85 00 EE 30 85 00 EE 30 85 00 EE
30 85 00 EE 30 85 00 EE 30 85 00 EE 30 85 00 EE
30 85 00 EE 4C 88 00 EE 30 85 00 EE 30 85 00 EE
30 85 00 EE E0 87 00 EE 30 85 00 EE F4 86 00 EE
30 85 00 EE 30 85 00 EE 06 8B 00 EE 84 05 04 F0
8C 05 04 F0 94 05 04 F0 9C 05 04 F0 54 05 04 F0
60 05 04 F0 6C 05 04 F0 78 05 04 F0 24 05 04 F0
30 05 04 F0 3C 05 04 F0 48 05 04 F0 F4 04 04 F0
00 05 04 F0 0C 05 04 F0 18 05 04 F0 01 00 00 00
01 00 00 00 66 00 00 00 36 6B 20 70 65 72 66 6F
72 6D 61 6E 63 65 20 72 75 6E 20 70 61 72 61 6D
65 74 65 72 73 20 66 6F 72 20 63 6F 72 65 6D 61
72 6B 2E 0A 00 00 00 00 36 6B 20 76 61 6C 69 64
61 74 69 6F 6E 20 72 75 6E 20 70 61 72 61 6D 65
74 65 72 73 20 66 6F 72 20 63 6F 72 65 6D 61 72
6B 2E 0A 00 50 72 6F 66 69 6C 65 20 67 65 6E 65
72 61 74 69 6F 6E 20 72 75 6E 20 70 61 72 61 6D
65 74 65 72 73 20 66 6F 72 20 63 6F 72 65 6D 61
72 6B 2E 0A 00 00 00 00 32 4B 20 70 65 72 66 6F
72 6D 61 6E 63 65 20 72 75 6E 20 70 61 72 61 6D
65 74 65 72 73 20 66 6F 72 20 63 6F 72 65 6D 61
72 6B 2E 0A 00 00 00 00 32 4B 20 76 61 6C 69 64
61 74 69 6F 6E 20 72 75 6E 20 70 61 72 61 6D 65
74 65 72 73 20 66 6F 72 20 63 6F 72 65 6D 61 72
6B 2E 0A 00 5B 25 75 5D 45 52 52 4F 52 21 20 6C
69 73 74 20 63 72 63 20 30 78 25 30 34 78 20 2D
20 73 68 6F 75 6C 64 20 62 65 20 30 78 25 30 34
78 0A 00 00 5B 25 75 5D 45 52 52 4F 52 21 20 6D
61 74 72 69 78 20 63 72 63 20 30 78 25 30 34 78
20 2D 20 73 68 6F 75 6C 64 20 62 65 20 30 78 25
30 34 78 0A 00 00 00 00 5B 25 75 5D 45 52 52 4F
52 21 20 73 74 61 74 65 20 63 72 63 20 30 78 25
30 34 78 20 2D 20 73 68 6F 75 6C 64 20 62 65 20
30 78 25 30 34 78 0A 00 43 6F 72 65 4D 61 72 6B
20 53 69 7A 65 20 20 20 20 3A 20 25 75 0A 00 00
54 6F 74 61 6C 20 74 69 63 6B 73 20 20 20 20 20
20 3A 20 25 75 0A 00 00 54 6F 74 61 6C 20 74 69
6D 65 20 28 73 65 63 73 29 3A 20 25 64 0A 00 00
45 52 52 4F 52 21 20 4D 75 73 74 20 65 78 65 63
75 74 65 20 66 6F 72 20 61 74 20 6C 65 61 73 74
20 31 30 20 73 65 63 73 20 66 6F 72 20 61 20 76
61 6C 69 64 20 72 65 73 75 6C 74 21 0A 00 00 00
49 74 65 72 61 74 2F 53 65 63 2F 4D 48 7A 20 20
20 3A 20 25 64 2E 25 64 0A 00 00 00 49 74 65 72
61 74 69 6F 6E 73 20 20 20 20 20 20 20 3A 20 25
75 0A 00 00 47 43 43 37 2E 32 2E 30 00 00 00 00
43 6F 6D 70 69 6C 65 72 20 76 65 72 73 69 6F 6E
20 3A 20 25 73 0A 00 00 2D 4F 32 00 43 6F 6D 70
69 6C 65 72 20 66 6C 61 67 73 20 20 20 3A 20 25
73 0A 00 00 53 54 41 54 49 43 00 00 4D 65 6D 6F
72 79 20 6C 6F 63 61 74 69 6F 6E 20 20 3A 20 25
73 0A 00 00 73 65 65 64 63 72 63 20 20 20 20 20
20 20 20 20 20 3A 20 30 78 25 30 34 78 0A 00 00
5B 25 64 5D 63 72 63 6C 69 73 74 20 20 20 20 20
20 20 3A 20 30 78 25 30 34 78 0A 00 5B 25 64 5D
63 72 63 6D 61 74 72 69 78 20 20 20 20 20 3A 20
30 78 25 30 34 78 0A 00 5B 25 64 5D 63 72 63 73
74 61 74 65 20 20 20 20 20 20 3A 20 30 78 25 30
34 78 0A 00 5B 25 64 5D 63 72 63 66 69 6E 61 6C
20 20 20 20 20 20 3A 20 30 78 25 30 34 78 0A 00
43 6F 72 72 65 63 74 20 6F 70 65 72 61 74 69 6F
6E 20 76 61 6C 69 64 61 74 65 64 2E 20 53 65 65
20 72 65 61 64 6D 65 2E 74 78 74 20 66 6F 72 20
72 75 6E 20 61 6E 64 20 72 65 70 6F 72 74 69 6E
67 20 72 75 6C 65 73 2E 0A 00 00 00 45 72 72 6F
72 73 20 64 65 74 65 63 74 65 64 0A 00 00 00 00
43 61 6E 6E 6F 74 20 76 61 6C 69 64 61 74 65 20
6F 70 65 72 61 74 69 6F 6E 20 66 6F 72 20 74 68
65 73 65 20 73 65 65 64 20 76 61 6C 75 65 73 2C
20 70 6C 65 61 73 65 20 63 6F 6D 70 61 72 65 20
77 69 74 68 20 72 65 73 75 6C 74 73 20 6F 6E 20
61 20 6B 6E 6F 77 6E 20 70 6C 61 74 66 6F 72 6D
2E 0A 00 00 54 30 2E 33 65 2D 31 46 00 00 00 00
2D 54 2E 54 2B 2B 54 71 00 00 00 00 31 54 33 2E
34 65 34 7A 00 00 00 00 33 34 2E 30 65 2D 54 5E
00 00 00 00 35 2E 35 30 30 65 2B 33 00 00 00 00
2D 2E 31 32 33 65 2D 32 00 00 00 00 2D 38 37 65
2B 38 33 32 00 00 00 00 2B 30 2E 36 65 2D 31 32
00 00 00 00 33 35 2E 35 34 34 30 30 00 00 00 00
2E 31 32 33 34 35 30 30 00 00 00 00 2D 31 31 30
2E 37 30 30 00 00 00 00 2B 30 2E 36 34 34 30 30
00 00 00 00 35 30 31 32 00 00 00 00 31 32 33 34
00 00 00 00 2D 38 37 34 00 00 00 00 2B 31 32 32
00 00 00 00 53 74 61 74 69 63 00 00 48 65 61 70
00 00 00 00 53 74 61 63 6B 00 00 00
@0000FFEC
00 00 00 EE 7A 9B 00 EE 40 00 00 00 00 00 04 F0
C0 85 04 F0

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,8 @@
@00000000
2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D
2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D
2D 2D 0A 48 65 6C 6C 6F 20 57 6F 72 6C 64 20 66
72 6F 6D 20 53 77 65 52 56 20 45 48 31 20 40 57
44 43 20 21 21 0A 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D
2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D
2D 2D 2D 2D 2D 2D 2D 2D 0A 00

View File

@ -0,0 +1,18 @@
@00000000
73 10 20 B0 73 10 20 B8 B7 00 00 EE 73 90 50 30
B7 50 55 5F 93 80 50 55 73 90 00 7C B7 01 58 D0
17 02 01 00 13 02 02 FE 83 02 02 00 23 80 51 00
05 02 E3 9B 02 FE B7 01 58 D0 93 02 F0 0F 23 80
51 00 E3 0A 00 FE 01 00 01 00 01 00 01 00 01 00
01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00
01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00
01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00
01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00
01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00
01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00
01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00
01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00
01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00
01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00
01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00
01 00 01 00 01 00 01 00 01 00 01 00 01 00

View File

@ -0,0 +1,10 @@
@00000000
2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D
2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D
2D 2D 0A 48 65 6C 6C 6F 20 57 6F 72 6C 64 20 66
72 6F 6D 20 53 77 65 52 56 20 45 48 31 20 40 57
44 43 20 21 21 0A 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D
2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D
2D 2D 2D 2D 2D 2D 2D 2D 0A 00
@0000FFF8
00 00 04 F0 70 80 04 F0

View File

@ -0,0 +1,18 @@
@00000000
73 10 20 B0 73 10 20 B8 B7 00 00 EE 73 90 50 30
B7 50 55 5F 93 80 50 55 73 90 00 7C B7 01 58 D0
17 02 04 F0 13 02 02 FE 83 02 02 00 23 80 51 00
05 02 E3 9B 02 FE B7 01 58 D0 93 02 F0 0F 23 80
51 00 E3 0A 00 FE 01 00 01 00 01 00 01 00 01 00
01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00
01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00
01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00
01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00
01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00
01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00
01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00
01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00
01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00
01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00
01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00
01 00 01 00 01 00 01 00 01 00 01 00 01 00

View File

@ -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; }
} }

File diff suppressed because it is too large Load Diff

View File

@ -22,62 +22,50 @@
#include "verilated_vcd_c.h" #include "verilated_vcd_c.h"
// /*
vluint64_t main_time = 0; vluint64_t main_time = 0;
double sc_time_stamp () { double sc_time_stamp () {
return main_time; return main_time;
} }
// */
//int main(int argc, char* argv[]) {
int main(int argc, char** argv) { int main(int argc, char** argv) {
std::cout << "\nVerilatorTB: Start of sim\n" << std::endl;
// Check for +dumpon and remove it from argv
bool dumpWaves = false;
int newArgc = 0;
for (int i = 0; i < argc; ++i)
if (strcmp(argv[i], "+dumpon") == 0)
dumpWaves = true;
else
argv[newArgc++] = argv[i];
argc = newArgc;
std::cout << "\nStart of sim\n" << std::endl;
Verilated::commandArgs(argc, argv); Verilated::commandArgs(argc, argv);
Vtb_top* tb = new Vtb_top; Vtb_top* tb = new Vtb_top;
uint32_t clkCnt = 0;
// init trace dump // init trace dump
Verilated::traceEverOn(true); Verilated::traceEverOn(true);
VerilatedVcdC* tfp = new VerilatedVcdC; VerilatedVcdC* tfp = new VerilatedVcdC;
tb->trace (tfp, 24); tb->trace (tfp, 24);
tfp->open ("sim.vcd"); if (dumpWaves)
tfp->open ("sim.vcd");
// Simulate // Simulate
for(auto i=0; i<200000; ++i){ while(!Verilated::gotFinish()){
clkCnt++; if (dumpWaves)
if(i<10) { tfp->dump (main_time);
tb->reset_l = 0; main_time += 5;
} else {
tb->reset_l = 1;
}
for (auto clk=0; clk<2; clk++) {
tfp->dump (2*i+clk);
tb->core_clk = !tb->core_clk; tb->core_clk = !tb->core_clk;
tb->eval(); tb->eval();
}
if (tb->finished) {
tfp->close();
break;
}
} }
for(auto i=0; i<100; ++i){ if (dumpWaves)
clkCnt++; tfp->close();
for (auto clk=0; clk<2; clk++) {
tfp->dump (2*i+clk);
tb->core_clk = !tb->core_clk;
tb->eval();
}
}
std::cout << "\nEnd of sim" << std::endl; std::cout << "\nVerilatorTB: End of sim" << std::endl;
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);
} }

View File

@ -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,124 +20,157 @@ $(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
RIVIERA = riviera RIVIERA = riviera
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
RIVIERA_DEBUG = +access +r
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) work dataset.asdb library.cfg rm -rf *.log *.s *.hex *.dis *.tbl irun* vcs* simv* snapshots swerv* \
verilator* *.exe obj* *.o ucli.key vc_hdrs.h csrc *.csv \
work dataset.asdb library.cfg
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)
riviera:
vlib work
vlog -work work +define+RV_OPENSOURCE \
+incdir+${RV_ROOT}/design/lib/ +incdir+${RV_ROOT}/design/include/ +incdir+${RV_ROOT}/design/dmi/ +incdir+${RV_ROOT}/configs/snapshots/default/ +incdir+${RV_ROOT}/testbench/ \
+libext+.v ${RV_ROOT}/configs/snapshots/default/common_defines.vh ${RV_ROOT}/design/include/build.h ${RV_ROOT}/design/include/global.h ${RV_ROOT}/design/include/swerv_types.sv \
-f ${RV_ROOT}/testbench/flist.riviera \
${RV_ROOT}/testbench/tb_top.sv ${RV_ROOT}/testbench/ahb_sif.sv \
-err VCP2694 W1
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
riviera-run: program.hex riviera-build: ${TBFILES} ${BUILD_DIR}/defines.h
snapshot=ahb_lite vlib work
$(SWERV_CONFIG) -snapshot=$(snapshot) -ahb_lite vlog -work work \
vsim -lib work -c +access +r tb_top -do "run -all; exit" -l riviera_compile.log -err VCP2694 W1 \
program.hex: $(ASM_TEST_DIR)/$(ASM_TEST).s ${RV_ROOT}/configs/snapshots/$(snapshot)/common_defines.vh +incdir+${RV_ROOT}/design/lib \
@echo Building $(ASM_TEST) +incdir+${RV_ROOT}/design/include \
ifeq ($(shell which $(GCC_PREFIX)-as),) +incdir+${BUILD_DIR} +libext+.v $(defines) \
@echo " !!! No $(GCC_PREFIX)-as in path, using canned hex files !!" -f ${RV_ROOT}/testbench/flist \
cp ${RV_ROOT}/testbench/hex/*.hex . ${TBFILES}
touch riviera-build
verilator: program.hex verilator-build
./obj_dir/Vtb_top ${DEBUG_PLUS}
irun: program.hex irun-build
$(IRUN) -64bit -abvglobalfailurelimit 1 +lic_queue -licqueue -status -nclibdirpath . -nclibdirname swerv.build \
-snapshot ${snapshot} -r ${snapshot} $(IRUN_DEBUG_RUN)
vcs: program.hex vcs-build
./simv $(DEBUG_PLUS) +vcs+lic+wait -l vcs.log
vlog: program.hex ${TBFILES} ${BUILD_DIR}/defines.h
$(VLOG) -l vlog.log -sv -mfcu +incdir+${BUILD_DIR}+${RV_ROOT}/design/include+${RV_ROOT}/design/lib\
$(defines) -f ${RV_ROOT}/testbench/flist ${TBFILES} -R ${DEBUG_PLUS}
riviera: program.hex riviera-build
vsim -c -lib work ${DEBUG_PLUS} ${RIVIERA_DEBUG} tb_top -do "run -all; exit" -l riviera.log
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 riviera help clean all verilator-build irun-build vcs-build riviera-build program.hex
.PHONY: help clean verilator vcs irun riviera verilator-run irun-run vcs-run riviera-run .PHONY: help clean verilator vcs irun vlog riviera

View File

@ -17,9 +17,9 @@ foreach $line (@in) {
if ($line=~/\#/) { next; } if ($line=~/\#/) { next; }
if ($line=~/([^=]+)=/) { if ($line=~/([^=]+)=/) {
$sig=$1; $sig=$1;
$sig=~s/\s+//g; $sig=~s/\s+//g;
printf("logic $sig;\n"); printf("logic $sig;\n");
} }
} }
@ -28,13 +28,13 @@ foreach $line (@in) {
if ($line=~/\#/) { next; } if ($line=~/\#/) { next; }
if ($line=~/([^=]+)=\s*;/) { if ($line=~/([^=]+)=\s*;/) {
printf("assign ${prefix}$1 = 1'b0;\n"); printf("assign ${prefix}$1 = 1'b0;\n");
next; next;
} }
if ($line=~/([^=]+)=\s*\(\s*\);/) { if ($line=~/([^=]+)=\s*\(\s*\);/) {
printf("assign ${prefix}$1 = 1'b0;\n"); printf("assign ${prefix}$1 = 1'b0;\n");
next; next;
} }
if ($line =~ /=/) { printf("assign ${prefix}$line"); } if ($line =~ /=/) { printf("assign ${prefix}$line"); }

View File

@ -5,9 +5,9 @@ use Getopt::Long;
$helpusage = "placeholder"; $helpusage = "placeholder";
GetOptions ('legal' => \$legal, GetOptions ('legal' => \$legal,
'in=s' => \$in, 'in=s' => \$in,
'out=s' => \$out, 'out=s' => \$out,
'view=s' => \$view ) || die("$helpusage"); 'view=s' => \$view ) || die("$helpusage");
if (!defined($in)) { die("must define -in=input"); } if (!defined($in)) { die("must define -in=input"); }
@ -32,95 +32,95 @@ foreach $line (@in) {
#printf("$pstate: $line"); #printf("$pstate: $line");
if ($line=~/^\s*\#/) { #printf("skip $line"); if ($line=~/^\s*\#/) { #printf("skip $line");
next; } next; }
if ($gather==1) { if ($gather==1) {
if ($line=~/(\S+)/) { if ($line=~/(\S+)/) {
if ($line=~/}/) { $gather=0; $position=0; next; } if ($line=~/}/) { $gather=0; $position=0; next; }
$label=$1; $label=$1;
$label=~s/,//g; $label=~s/,//g;
if ($pstate==2) { if ($pstate==2) {
if (defined($INPUT{$CVIEW}{$label})) { die("input $label already defined"); } if (defined($INPUT{$CVIEW}{$label})) { die("input $label already defined"); }
$INPUT{$CVIEW}{$label}=$position++; $INPUT{$CVIEW}{$label}=$position++;
$INPUTLEN{$CVIEW}++; $INPUTLEN{$CVIEW}++;
$INPUTSTR{$CVIEW}.=" $label"; $INPUTSTR{$CVIEW}.=" $label";
} }
elsif ($pstate==3) { elsif ($pstate==3) {
if (defined($OUTPUT{$CVIEW}{$label})) { die("output $label already defined"); } if (defined($OUTPUT{$CVIEW}{$label})) { die("output $label already defined"); }
$OUTPUT{$CVIEW}{$label}=$position++; $OUTPUT{$CVIEW}{$label}=$position++;
$OUTPUTLEN{$CVIEW}++; $OUTPUTLEN{$CVIEW}++;
$OUTPUTSTR{$CVIEW}.=" $label"; $OUTPUTSTR{$CVIEW}.=" $label";
} }
else { die("unknown pstate $pstate in gather"); } else { die("unknown pstate $pstate in gather"); }
} }
} }
if ($line=~/^.definition/) { if ($line=~/^.definition/) {
$pstate=1; next; $pstate=1; next;
} }
if ($pstate==1) { # definition if ($pstate==1) { # definition
if ($line!~/^.output/) { if ($line!~/^.output/) {
if ($line=~/(\S+)\s*=\s*(\S+)/) { if ($line=~/(\S+)\s*=\s*(\S+)/) {
$key=$1; $value=$2; $key=$1; $value=$2;
$value=~s/\./-/g; $value=~s/\./-/g;
$value=~s/\[//g; $value=~s/\[//g;
$value=~s/\]//g; $value=~s/\]//g;
$DEFINITION{$key}=$value; $DEFINITION{$key}=$value;
} }
} }
else { $pstate=2; next; } else { $pstate=2; next; }
} }
if ($line=~/^.input/) { if ($line=~/^.input/) {
$pstate=2; next; $pstate=2; next;
} }
if ($pstate==2) { # input if ($pstate==2) { # input
if ($line=~/(\S+)\s*=\s*\{/) { if ($line=~/(\S+)\s*=\s*\{/) {
$CVIEW=$1; $gather=1; next; $CVIEW=$1; $gather=1; next;
} }
} }
if ($line=~/^.output/) { if ($line=~/^.output/) {
$pstate=3; next; $pstate=3; next;
} }
if ($pstate==3) { # output if ($pstate==3) { # output
if ($line=~/(\S+)\s*=\s*\{/) { if ($line=~/(\S+)\s*=\s*\{/) {
$CVIEW=$1; $gather=1; next; $CVIEW=$1; $gather=1; next;
} }
} }
if ($line=~/^.decode/) { if ($line=~/^.decode/) {
$pstate=4; next; $pstate=4; next;
} }
if ($pstate==4) { # decode if ($pstate==4) { # decode
if ($line=~/([^\[]+)\[([^\]]+)\]\s+=\s+\{([^\}]+)\}/) { if ($line=~/([^\[]+)\[([^\]]+)\]\s+=\s+\{([^\}]+)\}/) {
$dview=$1; $inst=$2; $body=$3; $dview=$1; $inst=$2; $body=$3;
$dview=~s/\s+//g; $dview=~s/\s+//g;
$inst=~s/\s+//g; $inst=~s/\s+//g;
#printf("$dview $inst $body\n"); #printf("$dview $inst $body\n");
if ($inst=~/([^\{]+)\{([^-]+)-([^\}]+)\}/) { if ($inst=~/([^\{]+)\{([^-]+)-([^\}]+)\}/) {
$base=$1; $lo=$2; $hi=$3; $base=$1; $lo=$2; $hi=$3;
$hi++; $hi++;
for ($i=0; $i<$TIMEOUT && $lo ne $hi; $i++) { for ($i=0; $i<$TIMEOUT && $lo ne $hi; $i++) {
#printf("decode $dview $base$lo\n"); #printf("decode $dview $base$lo\n");
$expand=$base.$lo; $expand=$base.$lo;
if (!defined($DEFINITION{$expand})) { die("could not find instruction definition for inst $expand"); } if (!defined($DEFINITION{$expand})) { die("could not find instruction definition for inst $expand"); }
$DECODE{$dview}{$expand}=$body; $DECODE{$dview}{$expand}=$body;
$lo++; $lo++;
} }
if ($i == $TIMEOUT) { die("timeout in decode expansion"); } if ($i == $TIMEOUT) { die("timeout in decode expansion"); }
} }
else { else {
if (!defined($DEFINITION{$inst})) { die("could not find instruction definition for inst $inst"); } if (!defined($DEFINITION{$inst})) { die("could not find instruction definition for inst $inst"); }
$DECODE{$dview}{$inst}=$body; $DECODE{$dview}{$inst}=$body;
} }
} }
} }
} }
@ -166,19 +166,19 @@ foreach $inst (sort keys %{ $DECODE{$view} }) {
$template=$DEFAULT_TEMPLATE; $template=$DEFAULT_TEMPLATE;
foreach $sig (@sigs) { foreach $sig (@sigs) {
if (!defined($OUTPUT{$view}{$sig})) { die("could not find output definition for sig $sig in view $view"); } if (!defined($OUTPUT{$view}{$sig})) { die("could not find output definition for sig $sig in view $view"); }
$position=$OUTPUT{$view}{$sig}; $position=$OUTPUT{$view}{$sig};
substr($template,$position,1,1); substr($template,$position,1,1);
} }
# if (!defined($DEFINITION{$inst})) { die("could not find instruction defintion for inst $inst"); } # if (!defined($DEFINITION{$inst})) { die("could not find instruction defintion for inst $inst"); }
printf("# $inst\n"); printf("# $inst\n");
if (defined($legal)) { if (defined($legal)) {
printf("$DEFINITION{$inst} 1\n"); printf("$DEFINITION{$inst} 1\n");
} }
else { else {
printf("$DEFINITION{$inst} $template\n"); printf("$DEFINITION{$inst} $template\n");
} }
} }

View File

@ -48,11 +48,11 @@ sub d2b {
$v = sprintf "%b",$v; $v = sprintf "%b",$v;
if (length($v)<$LEN) { if (length($v)<$LEN) {
$repeat=$LEN-length($v); $repeat=$LEN-length($v);
$v="0"x$repeat.$v; $v="0"x$repeat.$v;
} }
elsif (length($v)>$LEN) { elsif (length($v)>$LEN) {
$v=substr($v,length($v)-$LEN,$LEN); $v=substr($v,length($v)-$LEN,$LEN);
} }
return($v); return($v);

View File

@ -8,7 +8,7 @@ $helpusage = "placeholder";
GetOptions ('len=s' => \$len, GetOptions ('len=s' => \$len,
'num=s' => \$num, 'num=s' => \$num,
'den=s' => \$den, 'den=s' => \$den,
'skip' => \$skip) || die("$helpusage"); 'skip' => \$skip) || die("$helpusage");
if (!defined($len)) { $len=8; } if (!defined($len)) { $len=8; }
@ -25,9 +25,9 @@ printf(".ob smallnum[3] smallnum[2] smallnum[1] smallnum[0]\n");
printf(".type fr\n"); printf(".type fr\n");
for ($q=0; $q<16; $q++) { for ($q=0; $q<16; $q++) {
for ($m=0; $m<16; $m++) { for ($m=0; $m<16; $m++) {
if ($m==0) { next; } if ($m==0) { next; }
$result=int($q/$m); $result=int($q/$m);
printf("%s %s %s\n",d2bl($q,4),d2bl($m,4),d2bl($result,4)); printf("%s %s %s\n",d2bl($q,4),d2bl($m,4),d2bl($result,4));
} }
} }
@ -93,11 +93,11 @@ sub d2b {
$v = sprintf "%b",$v; $v = sprintf "%b",$v;
if (length($v)<$LEN) { if (length($v)<$LEN) {
$repeat=$LEN-length($v); $repeat=$LEN-length($v);
$v="0"x$repeat.$v; $v="0"x$repeat.$v;
} }
elsif (length($v)>$LEN) { elsif (length($v)>$LEN) {
$v=substr($v,length($v)-$LEN,$LEN); $v=substr($v,length($v)-$LEN,$LEN);
} }
return($v); return($v);
@ -110,11 +110,11 @@ sub d2bl {
$v = sprintf "%b",$v; $v = sprintf "%b",$v;
if (length($v)<$LEN) { if (length($v)<$LEN) {
$repeat=$LEN-length($v); $repeat=$LEN-length($v);
$v="0"x$repeat.$v; $v="0"x$repeat.$v;
} }
elsif (length($v)>$LEN) { elsif (length($v)>$LEN) {
$v=substr($v,length($v)-$LEN,$LEN); $v=substr($v,length($v)-$LEN,$LEN);
} }
return($v); return($v);

1
tools/vivado.tcl Normal file
View File

@ -0,0 +1 @@
set_property is_global_include true [get_files config/common_defines.vh]