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

203
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)
The SweRV 1 series provides a 32-bit, machine-mode only, implementation of the RISC-V ISA including options I (base integer), M (multiply/divide) and C (compressed instructions from I and M).
This repository contains the SweRV EH1.5 Core<sup>TM</sup> design RTL
## License
@ -13,24 +12,26 @@ Files under the [tools](tools/) directory may be available under a different lic
├── configs # Configurations Dir
│   └── snapshots # Where generated configuration files are created
├── design # Design root dir
│   ├── dbg # Debugger
│   ├── dec # Decode, Registers and Exceptions
│   ├── dmi # DMI block
│   ├── exu # EXU (ALU/MUL/DIV)
│   ├── ifu # Fetch & Branch Prediction
│   ├── dbg # Debugger
│   ├── dec # Decode, Registers and Exceptions
│   ├── dmi # DMI block
│   ├── exu # EXU (ALU/MUL/DIV)
│   ├── ifu # Fetch & Branch Prediction
│   ├── include
│   ├── lib
│   └── lsu # Load/Store
│   └── lsu # Load/Store
├── docs
├── tools # Scripts/Makefiles
└── testbench # (Very) simple testbench
   ├── asm # Example assembly files
   └── hex # Canned demo hex files
   ├── asm # Example test files
   └── hex # Canned demo hex files
## Dependencies
- Verilator **(3.926 or later)** must be installed on the system
- If adding/removing instructions, espresso must be installed. Espresso is a logic minimization tool used in *tools/coredecode*.
- Verilator **(4.020 or later)** must be installed on the system if running with verilator
- If adding/removing instructions, espresso must be installed (used by *tools/coredecode*)
- RISCV tool chain (based on gcc version 7.3 or higher) must be
installed so that it can be used to prepare RISCV binaries to run.
## Quickstart guide
1. Clone the repository
@ -47,14 +48,17 @@ SweRV can be configured by running the `$RV_ROOT/configs/swerv.config` script:
`% $RV_ROOT/configs/swerv.config -h` for detailed help options
For example to build with a DCCM of size 64 :
For example to build with a DCCM of size 64 Kb:
`% $RV_ROOT/configs/swerv.config -dccm_size=64`
This will update the **default** snapshot in $RV_ROOT/configs/snapshots/default/ with parameters for a 64K DCCM.
This will update the **default** snapshot in $PWD/snapshots/default/ with parameters for a 64K DCCM. To **unset** a parameter, use `-unset=PARAM` option to swerv.config.
Add `-snapshot=dccm64`, for example, if you wish to name your build snapshot *dccm64* and refer to it during the build.
There are four predefined target configurations: `default`, `default_ahb`, `default_pd`, `high_perf` that can be selected via
the `-target=name` option to swerv.config.
This script derives the following consistent set of include files :
$RV_ROOT/configs/snapshots/default
@ -62,75 +66,134 @@ This script derives the following consistent set of include files :
├── defines.h # #defines for C/assembly headers
├── pd_defines.vh # `defines for physical design
├── perl_configs.pl # Perl %configs hash for scripting
├── pic_ctrl_verilator_unroll.sv # Unrolled verilog based on PIC size
├── pic_map_auto.h # PIC memory map based on configure size
└── whisper.json # JSON file for swerv-iss
### Building a model
1. Set the RV_ROOT environment variable to the root of the SweRV directory structure
`RV_ROOT = /path/to/swerv`
`export RV_ROOT`
while in a work directory:
1. Create your configuration
1. Set the RV_ROOT environment variable to the root of the SweRV directory structure.
Example for bash shell:
`export RV_ROOT=/path/to/swerv`
Example for csh or its derivatives:
`setenv RV_ROOT /path/to/swerv`
1. Create your specific configuration
*(Skip if default is sufficient)*
*(Name your snapshot to distinguish it from the default. Without an explicit name, it will update/override the **default** snapshot)*
`$RV_ROOT/configs/swerv.config [configuration options..] -snapshot=mybuild`
*(Name your snapshot to distinguish it from the default. Without an explicit name, it will update/override the __default__ snapshot)*
For example if `mybuild` is the name for the snapshot:
Snapshots are placed in `$RV_ROOT/configs/snapshots/<snapshot name>/` directory
1. Build with **verilator**:
`make -f $RV_ROOT/tools/Makefile verilator [snapshot=name]`
This will create and populate the verilator *obj_dir/* in the current work dir.
**Other targets supported**:
vcs (Synopsys)
irun (Cadence)
### Running a simple Hello World program (verilator)
RV_ROOT = /path/to/swerv
export RV_ROOT
make -f $RV_ROOT/tools/Makefile verilator-run
This will build a verilator model of SweRV with AHB-lite bus, and execute a short sequence of instructions that writes out "HELLO
WORLD" to the bus.
You can re-execute using
./obj_dir/Vtb_top
Start of sim
------------------------------
Hello World from SweRV @WDC !!
------------------------------
Finished : minstret = 389, mcycle = 1658
End of sim
A vcd file `sim.vcd` is created which can be browsed by gtkwave or similar waveform viewers. `trace_port.csv` contains a log of
the trace port. `exec.log` contains a basic execution trace showing PC, opcode and GPR writes.
The Makefile allows you to specify different assembly files from command line
set BUILD_PATH environment variable:
`setenv BUILD_PATH snapshots/mybuild`
make -f $RV_ROOT/tools/Makefile verilator-run ASM_TEST=my_hellow_world.s ASM_TEST_DIR=/path/to/dir
`$RV_ROOT/configs/swerv.config [configuration options..] -snapshot=mybuild`
Snapshots are placed in `$BUILD_PATH` directory
1. Running a simple Hello World program (verilator)
`make -f $RV_ROOT/tools/Makefile`
This command will build a verilator model of SweRV EH1 with AXI bus, and
execute a short sequence of instructions that writes out "HELLO WORLD"
to the bus.
The simulation produces output on the screen like:
````
VerilatorTB: Start of sim
----------------------------------
Hello World from SweRV EH1 @WDC !!
----------------------------------
Finished : minstret = 443, mcycle = 1372
See "exec.log" for execution trace with register updates..
TEST_PASSED
````
The simulation generates following files:
`console.log` contains what the cpu writes to the console address of 0xd0580000.
`exec.log` shows instruction trace with GPR updates.
`trace_port.csv` contains a log of the trace port.
When `debug=1` is provided, a vcd file `sim.vcd` is created and can be browsed by
gtkwave or similar waveform viewers.
You can re-execute simulation using:
` ./obj_dir/Vtb_top `
or
`make -f $RV_ROOT/tools/Makefile verilator`
The simulation run/build command has following generic form:
```
make -f $RV_ROOT/tools/Makefile [<simulator>] [debug=1] [snapshot=<snapshot>] [target=<target>] [TEST=<test>] [TEST_DIR=<path_to_test_dir>] [CONF_PARAMS=<swerv.config option>]
where:
<simulator> - can be 'verilator' (by default) 'irun' - Cadence xrun, 'vcs' - Synopsys VCS, 'vlog' Mentor Questa
if not provided, 'make' cleans work directory, builds verilator executable and runs a test.
debug=1 - allows VCD generation for verilator and VCS and SHM waves for irun option.
<target> - predefined CPU configurations 'default' ( by default), 'default_ahb', 'default_pd', 'high_perf'
TEST - allows to run a C (<test>.c) or assembly (<test>.s) test, hello_world is run by default
TEST_DIR - alternative to test source directory testbench/asm
<snapshot> - run and build executable model of custom CPU configuration, remember to provide 'snapshot' argument
for runs on custom configurations.
CONF_PARAMS - configuration parameter for swerv.config : ex: 'CONF_PARAMS=-unset=dccm_enable' to build with no DCCM
```
Example:
make -f $RV_ROOT/tools/Makefile verilator TEST=cmark
will simulate testbench/asm/cmark.c program with verilator on default target
If you want to compile a test only, you can run:
make -f $RV_ROOT/tools/Makefile program.hex TEST=<test> [TEST_DIR=/path/to/dir]
The Makefile uses `$RV_ROOT/testbench/link.ld` file by default to build test executable.
User can provide test specific linker file in form `<test_name>.ld` to build the test executable,
in the same directory with the test source.
User also can create a test specific makefile in form `<test_name>.makefile`, contaning building instructions
how to create `program.hex`, `data.hex` files used by simulation. The private makefile should be in the same directory
as the test source.
*(`program.hex` file is loaded to instruction bus memory slave and `data.hex` file is loaded to LSU bus memory slave and
optionally to DCCM at the beginning of simulation)*.
Note: You may need to delete `program.hex` file from work directory, when run a new test.
The `$RV_ROOT/testbench/asm` directory contains following tests ready to simulate:
```
hello_world - default test to run, prints Hello World message to screen and console.log
hello_world_dccm - the same as above, but takes the string from preloaded DCCM.
cmark - coremark benchmark running with code and data in external memories
cmark_dccm - the same as above, running data and stack from DCCM (faster)
cmark_iccm - the same as above, but with code preloaded to iccm - runs only on CPU with ICCM
use CONF_PARAMS=-set=iccm_enable argument to `make` to build CPU with ICCM
```
The `$RV_ROOT/testbench/hex` directory contains precompiled hex files of the tests, ready for simulation in case RISCV SW tools are not installed.
If you change only the assembly files, you do not need to rebuild verilator, just specify the target as `program.hex` :
make -f $RV_ROOT/tools/Makefile program.hex ASM_TEST=my_hello_world.s ASM_TEST_DIR=/path/to/dir
./obj_dir/Vtb_top
### SweRV CoreMark Benchmarking
We ran [CoreMark](https://www.eembc.org/coremark/) benchmark on Nexys4 board and achieved CoreMark score of **4.94**. Please see the [document](https://github.com/chipsalliance/Cores-SweRV/blob/master/docs/SweRV_CoreMark_Benchmarking.pdf) for details.
----
Western Digital, the Western Digital logo, G-Technology, SanDisk, Tegile, Upthere, WD, SweRV Core, SweRV ISS, and OmniXtend are registered trademarks or trademarks of Western Digital Corporation or its affiliates in the US and/or other countries. All other marks are the property of their respective owners.
Western Digital, the Western Digital logo, G-Technology, SanDisk, Tegile, Upthere, WD, SweRV Core, SweRV ISS,
and OmniXtend are registered trademarks or trademarks of Western Digital Corporation or its affiliates in the US
and/or other countries. All other marks are the property of their respective owners.

View File

@ -8,7 +8,9 @@ Name | Description
swerv.config | Configuration script for SweRV
This script will generate a consistent st of `defines/#defines needed for the design and testbench.
This script will generate a consistent set of `defines/#defines needed for the design and testbench.
A perl hash (*perl_configs.pl*) and a JSON format for SweRV-iss are also generated.
While the defines fines may be modified by hand, it is recommended that this script be used to generate a consistent set.
`$RV_ROOT/configs/swerv.config -h` will provide options for the script.
While the defines files may be modified by hand, it is recommended that this script be used to generate a consistent set.

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
}

File diff suppressed because it is too large Load Diff

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

@ -1,12 +1,12 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright 2019 Western Digital Corporation or its affiliates.
//
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//
// http://www.apache.org/licenses/LICENSE-2.0
//
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -16,10 +16,10 @@
// $Id$
//
// Function: Top level SWERV core file to control the debug mode
// Comments: Responsible to put the rest of the core in quiesce mode,
// Comments: Responsible to put the rest of the core in quiesce mode,
// Send the commands/address. sends WrData and Recieve read Data.
// And then Resume the core to do the normal mode
// Author :
// And then Resume the core to do the normal mode
// Author :
//********************************************************************************
module dbg (
// outputs to the core for command and data interface
@ -27,10 +27,10 @@ module dbg (
output logic [31:0] dbg_cmd_wrdata,
output logic dbg_cmd_valid,
output logic dbg_cmd_write, // 1: write command, 0: read_command
output logic [1:0] dbg_cmd_type, // 0:gpr 1:csr 2: memory
output logic [1:0] dbg_cmd_type, // 0:gpr 1:csr 2: memory
output logic [1:0] dbg_cmd_size, // size of the abstract mem access debug command
output logic dbg_core_rst_l, // core reset from dm
// inputs back from the core/dec
input logic [31:0] core_dbg_rddata,
input logic core_dbg_cmd_done, // This will be treated like a valid signal
@ -39,25 +39,25 @@ module dbg (
// Signals to dma to get a bubble
output logic dbg_dma_bubble, // Debug needs a bubble to send a valid
input logic dma_dbg_ready, // DMA is ready to accept debug request
// interface with the rest of the core to halt/resume handshaking
output logic dbg_halt_req, // This is a pulse
output logic dbg_resume_req, // Debug sends a resume requests. Pulse
input logic dec_tlu_debug_mode, // Core is in debug mode
input logic dec_tlu_dbg_halted, // The core has finished the queiscing sequence. Core is halted now
input logic dec_tlu_dbg_halted, // The core has finished the queiscing sequence. Core is halted now
input logic dec_tlu_mpc_halted_only, // Only halted due to MPC
input logic dec_tlu_resume_ack, // core sends back an ack for the resume (pulse)
// inputs from the JTAG
input logic dmi_reg_en, // read or write
input logic [6:0] dmi_reg_addr, // address of DM register
input logic dmi_reg_wr_en, // write instruction
input logic [31:0] dmi_reg_wdata, // write data
// output
// output
output logic [31:0] dmi_reg_rdata, // read data
// output logic dmi_reg_ack,
// output logic dmi_reg_ack,
// AXI signals
// AXI signals
// AXI Write Channels
output logic sb_axi_awvalid,
input logic sb_axi_awready,
@ -71,19 +71,19 @@ module dbg (
output logic [3:0] sb_axi_awcache,
output logic [2:0] sb_axi_awprot,
output logic [3:0] sb_axi_awqos,
output logic sb_axi_wvalid,
output logic sb_axi_wvalid,
input logic sb_axi_wready,
output logic [63:0] sb_axi_wdata,
output logic [7:0] sb_axi_wstrb,
output logic sb_axi_wlast,
input logic sb_axi_bvalid,
output logic sb_axi_bready,
input logic [1:0] sb_axi_bresp,
input logic [`RV_SB_BUS_TAG-1:0] sb_axi_bid,
// AXI Read Channels
// AXI Read Channels
output logic sb_axi_arvalid,
input logic sb_axi_arready,
output logic [`RV_SB_BUS_TAG-1:0] sb_axi_arid,
@ -96,45 +96,46 @@ module dbg (
output logic [3:0] sb_axi_arcache,
output logic [2:0] sb_axi_arprot,
output logic [3:0] sb_axi_arqos,
input logic sb_axi_rvalid,
output logic sb_axi_rready,
input logic [`RV_SB_BUS_TAG-1:0] sb_axi_rid,
input logic [63:0] sb_axi_rdata,
input logic [1:0] sb_axi_rresp,
input logic sb_axi_rlast,
input logic dbg_bus_clk_en,
// general inputs
// general inputs
input logic clk,
input logic free_clk,
input logic rst_l,
input logic dbg_rst_l,
input logic clk_override,
input logic scan_mode
);
`include "global.h"
typedef enum logic [2:0] {IDLE=3'b000, HALTING=3'b001, HALTED=3'b010, CMD_START=3'b011, CMD_WAIT=3'b100, CMD_DONE=3'b101, RESUMING=3'b110} state_t;
typedef enum logic [3:0] {SBIDLE=4'h0, WAIT_RD=4'h1, WAIT_WR=4'h2, CMD_RD=4'h3, CMD_WR=4'h4, CMD_WR_ADDR=4'h5, CMD_WR_DATA=4'h6, RSP_RD=4'h7, RSP_WR=4'h8, DONE=4'h9} sb_state_t;
state_t dbg_state;
state_t dbg_state;
state_t dbg_nxtstate;
logic dbg_state_en;
// these are the registers that the debug module implements
logic [31:0] dmstatus_reg; // [26:24]-dmerr, [17:16]-resume ack, [9:8]-halted, [3:0]-version
logic [31:0] dmcontrol_reg; // dmcontrol register has only 6 bits implemented. 31: haltreq, 30: resumereq, 29: haltreset, 28: ackhavereset, 1: ndmreset, 0: dmactive.
logic [31:0] command_reg;
logic [31:0] command_reg;
logic [31:0] abstractcs_reg; // bits implemted are [12] - busy and [10:8]= command error
logic [31:0] haltsum0_reg;
logic [31:0] data0_reg;
logic [31:0] data1_reg;
// data 0
// data 0
logic [31:0] data0_din;
logic data0_reg_wren, data0_reg_wren0, data0_reg_wren1;
// data 1
logic data0_reg_wren, data0_reg_wren0, data0_reg_wren1;
// data 1
logic [31:0] data1_din;
logic data1_reg_wren, data1_reg_wren0, data1_reg_wren1;
// abstractcs
@ -151,6 +152,8 @@ module dbg (
logic dmstatus_havereset_wren;
logic dmstatus_havereset_rst;
logic dmstatus_resumeack;
logic dmstatus_unavail;
logic dmstatus_running;
logic dmstatus_halted;
logic dmstatus_havereset;
@ -160,34 +163,34 @@ module dbg (
logic command_wren;
// needed to send the read data back for dmi reads
logic [31:0] dmi_reg_rdata_din;
sb_state_t sb_state;
sb_state_t sb_nxtstate;
logic sb_state_en;
//System bus section
logic sbcs_wren;
logic sbcs_wren;
logic sbcs_sbbusy_wren;
logic sbcs_sbbusy_din;
logic sbcs_sbbusyerror_wren;
logic sbcs_sbbusyerror_din;
logic sbcs_sberror_wren;
logic [2:0] sbcs_sberror_din;
logic sbcs_unaligned;
logic sbcs_illegal_size;
// data
logic sbdata0_reg_wren0;
logic sbdata0_reg_wren1;
logic sbdata0_reg_wren1;
logic sbdata0_reg_wren;
logic [31:0] sbdata0_din;
logic sbdata1_reg_wren0;
logic sbdata1_reg_wren1;
logic sbdata1_reg_wren1;
logic sbdata1_reg_wren;
logic [31:0] sbdata1_din;
logic sbaddress0_reg_wren0;
logic sbaddress0_reg_wren1;
logic sbaddress0_reg_wren;
@ -196,7 +199,7 @@ module dbg (
logic sbreadonaddr_access;
logic sbreadondata_access;
logic sbdata0wr_access;
logic sb_axi_awvalid_q, sb_axi_awready_q;
logic sb_axi_wvalid_q, sb_axi_wready_q;
logic sb_axi_arvalid_q, sb_axi_arready_q;
@ -204,7 +207,7 @@ module dbg (
logic sb_axi_rvalid_q, sb_axi_rready_q;
logic [1:0] sb_axi_bresp_q, sb_axi_rresp_q;
logic [63:0] sb_axi_rdata_q;
logic [63:0] sb_bus_rdata;
//registers
@ -212,23 +215,23 @@ module dbg (
logic [31:0] sbaddress0_reg;
logic [31:0] sbdata0_reg;
logic [31:0] sbdata1_reg;
logic dbg_dm_rst_l;
//clken
logic dbg_free_clken;
logic dbg_free_clk;
logic sb_free_clken;
logic sb_free_clk;
logic bus_clken;
logic bus_clk;
// clocking
// used for the abstract commands.
// used for the abstract commands.
assign dbg_free_clken = dmi_reg_en | (dbg_state != IDLE) | dbg_state_en | dec_tlu_dbg_halted | clk_override;
// used for the system bus
assign sb_free_clken = dmi_reg_en | sb_state_en | (sb_state != SBIDLE) | clk_override;
assign bus_clken = (sb_axi_awvalid | sb_axi_wvalid | sb_axi_arvalid | sb_axi_bvalid | sb_axi_rvalid | clk_override) & dbg_bus_clk_en;
@ -236,90 +239,93 @@ module dbg (
rvoclkhdr dbg_free_cgc (.en(dbg_free_clken), .l1clk(dbg_free_clk), .*);
rvoclkhdr sb_free_cgc (.en(sb_free_clken), .l1clk(sb_free_clk), .*);
rvclkhdr bus_cgc (.en(bus_clken), .l1clk(bus_clk), .*);
// end clocking section
// end clocking section
// Reset logic
assign dbg_dm_rst_l = rst_l & (dmcontrol_reg[0] | scan_mode);
assign dbg_core_rst_l = ~dmcontrol_reg[1];
assign dbg_dm_rst_l = dbg_rst_l & (dmcontrol_reg[0] | scan_mode);
assign dbg_core_rst_l = ~dmcontrol_reg[1];
// system bus register
// sbcs[31:29], sbcs - [22]:sbbusyerror, [21]: sbbusy, [20]:sbreadonaddr, [19:17]:sbaccess, [16]:sbautoincrement, [15]:sbreadondata, [14:12]:sberror, sbsize=32, 128=0, 64/32/16/8 are legal
assign sbcs_reg[31:29] = 3'b1;
assign sbcs_reg[28:23] = '0;
assign sbcs_reg[11:5] = 7'h20;
assign sbcs_reg[4:0] = 5'b01111;
assign sbcs_reg[4:0] = 5'b01111;
assign sbcs_wren = (dmi_reg_addr == 7'h38) & dmi_reg_en & dmi_reg_wr_en & (sb_state == SBIDLE); // & (sbcs_reg[14:12] == 3'b000);
assign sbcs_sbbusyerror_wren = (sbcs_wren & dmi_reg_wdata[22]) |
((sb_state != SBIDLE) & dmi_reg_en & ((dmi_reg_addr == 7'h39) | (dmi_reg_addr == 7'h3c) | (dmi_reg_addr == 7'h3d)));
assign sbcs_sbbusyerror_din = ~(sbcs_wren & dmi_reg_wdata[22]); // Clear when writing one
rvdffs #(1) sbcs_sbbusyerror_reg (.din(sbcs_sbbusyerror_din), .dout(sbcs_reg[22]), .en(sbcs_sbbusyerror_wren), .rst_l(dbg_dm_rst_l), .clk(sb_free_clk));
rvdffs #(1) sbcs_sbbusy_reg (.din(sbcs_sbbusy_din), .dout(sbcs_reg[21]), .en(sbcs_sbbusy_wren), .rst_l(dbg_dm_rst_l), .clk(sb_free_clk));
rvdffs #(1) sbcs_sbreadonaddr_reg (.din(dmi_reg_wdata[20]), .dout(sbcs_reg[20]), .en(sbcs_wren), .rst_l(dbg_dm_rst_l), .clk(sb_free_clk));
rvdffs #(5) sbcs_misc_reg (.din(dmi_reg_wdata[19:15]), .dout(sbcs_reg[19:15]), .en(sbcs_wren), .rst_l(dbg_dm_rst_l), .clk(sb_free_clk));
rvdffs #(3) sbcs_error_reg (.din(sbcs_sberror_din[2:0]), .dout(sbcs_reg[14:12]), .en(sbcs_sberror_wren), .rst_l(dbg_dm_rst_l), .clk(sb_free_clk));
assign sbcs_unaligned = ((sbcs_reg[19:17] == 3'b001) & sbaddress0_reg[0]) |
((sbcs_reg[19:17] == 3'b010) & (|sbaddress0_reg[1:0])) |
assign sbcs_unaligned = ((sbcs_reg[19:17] == 3'b001) & sbaddress0_reg[0]) |
((sbcs_reg[19:17] == 3'b010) & (|sbaddress0_reg[1:0])) |
((sbcs_reg[19:17] == 3'b011) & (|sbaddress0_reg[2:0]));
assign sbcs_illegal_size = sbcs_reg[19]; // Anything bigger than 64 bits is illegal
assign sbaddress0_incr[3:0] = ({4{(sbcs_reg[19:17] == 3'b000)}} & 4'b0001) |
({4{(sbcs_reg[19:17] == 3'b001)}} & 4'b0010) |
({4{(sbcs_reg[19:17] == 3'b010)}} & 4'b0100) |
({4{(sbcs_reg[19:17] == 3'b100)}} & 4'b1000);
// sbdata
assign sbaddress0_incr[3:0] = ({4{(sbcs_reg[19:17] == 3'h0)}} & 4'b0001) |
({4{(sbcs_reg[19:17] == 3'h1)}} & 4'b0010) |
({4{(sbcs_reg[19:17] == 3'h2)}} & 4'b0100) |
({4{(sbcs_reg[19:17] == 3'h3)}} & 4'b1000);
// sbdata
//assign sbdata0_reg_wren0 = dmi_reg_en & dmi_reg_wr_en & (dmi_reg_addr == 32'h3c);
assign sbdata0_reg_wren0 = dmi_reg_en & dmi_reg_wr_en & (dmi_reg_addr == 7'h3c); // write data only when single read is 0
assign sbdata0_reg_wren1 = (sb_state == RSP_RD) & sb_state_en & ~sbcs_sberror_wren;
assign sbdata0_reg_wren1 = (sb_state == RSP_RD) & sb_state_en & ~sbcs_sberror_wren;
assign sbdata0_reg_wren = sbdata0_reg_wren0 | sbdata0_reg_wren1;
assign sbdata1_reg_wren0 = dmi_reg_en & dmi_reg_wr_en & (dmi_reg_addr == 7'h3d); // write data only when single read is 0;
assign sbdata1_reg_wren1 = (sb_state == RSP_RD) & sb_state_en & ~sbcs_sberror_wren;
assign sbdata1_reg_wren1 = (sb_state == RSP_RD) & sb_state_en & ~sbcs_sberror_wren;
assign sbdata1_reg_wren = sbdata1_reg_wren0 | sbdata1_reg_wren1;
assign sbdata0_din[31:0] = ({32{sbdata0_reg_wren0}} & dmi_reg_wdata[31:0]) |
({32{sbdata0_reg_wren1}} & sb_bus_rdata[31:0]);
assign sbdata1_din[31:0] = ({32{sbdata1_reg_wren0}} & dmi_reg_wdata[31:0]) |
({32{sbdata1_reg_wren1}} & sb_bus_rdata[63:32]);
rvdffe #(32) dbg_sbdata0_reg (.*, .din(sbdata0_din[31:0]), .dout(sbdata0_reg[31:0]), .en(sbdata0_reg_wren), .rst_l(dbg_dm_rst_l));
rvdffe #(32) dbg_sbdata1_reg (.*, .din(sbdata1_din[31:0]), .dout(sbdata1_reg[31:0]), .en(sbdata1_reg_wren), .rst_l(dbg_dm_rst_l));
// sbaddress
assign sbaddress0_reg_wren0 = dmi_reg_en & dmi_reg_wr_en & (dmi_reg_addr == 7'h39);
assign sbaddress0_reg_wren = sbaddress0_reg_wren0 | sbaddress0_reg_wren1;
assign sbaddress0_reg_din[31:0]= ({32{sbaddress0_reg_wren0}} & dmi_reg_wdata[31:0]) |
({32{sbaddress0_reg_wren1}} & (sbaddress0_reg[31:0] + {28'b0,sbaddress0_incr[3:0]}));
({32{sbaddress0_reg_wren1}} & (sbaddress0_reg[31:0] + {28'b0,sbaddress0_incr[3:0]}));
rvdffe #(32) dbg_sbaddress0_reg (.*, .din(sbaddress0_reg_din[31:0]), .dout(sbaddress0_reg[31:0]), .en(sbaddress0_reg_wren), .rst_l(dbg_dm_rst_l));
assign sbreadonaddr_access = dmi_reg_en & dmi_reg_wr_en & (dmi_reg_addr == 7'h39) & sbcs_reg[20]; // if readonaddr is set the next command will start upon writing of addr0
assign sbreadondata_access = dmi_reg_en & ~dmi_reg_wr_en & (dmi_reg_addr == 7'h3c) & sbcs_reg[15]; // if readondata is set the next command will start upon reading of data0
assign sbdata0wr_access = dmi_reg_en & dmi_reg_wr_en & (dmi_reg_addr == 7'h3c); // write to sbdata0 will start write command to system bus
assign sbdata0wr_access = dmi_reg_en & dmi_reg_wr_en & (dmi_reg_addr == 7'h3c); // write to sbdata0 will start write command to system bus
// memory mapped registers
// dmcontrol register has only 6 bits implemented. 31: haltreq, 30: resumereq, 29: haltreset, 28: ackhavereset, 1: ndmreset, 0: dmactive.
// dmcontrol register has only 6 bits implemented. 31: haltreq, 30: resumereq, 28: ackhavereset, 1: ndmreset, 0: dmactive.
// rest all the bits are zeroed out
// dmactive flop is reset based on core rst_l, all other flops use dm_rst_l
assign dmcontrol_wren = (dmi_reg_addr == 7'h10) & dmi_reg_en & dmi_reg_wr_en;
assign dmcontrol_reg[29] = '0;
assign dmcontrol_reg[27:2] = '0;
rvdffs #(5) dmcontrolff (.din({dmi_reg_wdata[31:28],dmi_reg_wdata[1]}), .dout({dmcontrol_reg[31:28], dmcontrol_reg[1]}), .en(dmcontrol_wren), .rst_l(dbg_dm_rst_l), .clk(dbg_free_clk));
rvdffs #(1) dmcontrol_dmactive_ff (.din(dmi_reg_wdata[0]), .dout(dmcontrol_reg[0]), .en(dmcontrol_wren), .rst_l(rst_l), .clk(dbg_free_clk));
rvdffs #(4) dmcontrolff (.din({dmi_reg_wdata[31:30],dmi_reg_wdata[28],dmi_reg_wdata[1]}), .dout({dmcontrol_reg[31:30], dmcontrol_reg[28], dmcontrol_reg[1]}), .en(dmcontrol_wren), .rst_l(dbg_dm_rst_l), .clk(dbg_free_clk));
rvdffs #(1) dmcontrol_dmactive_ff (.din(dmi_reg_wdata[0]), .dout(dmcontrol_reg[0]), .en(dmcontrol_wren), .rst_l(dbg_rst_l), .clk(dbg_free_clk));
rvdff #(1) dmcontrol_wrenff(.din(dmcontrol_wren), .dout(dmcontrol_wren_Q), .rst_l(dbg_dm_rst_l), .clk(dbg_free_clk));
// dmstatus register bits that are implemented
// [19:18]-havereset,[17:16]-resume ack, [9:8]-halted, [3:0]-version
// rest all the bits are zeroed out
//assign dmstatus_wren = (dmi_reg_addr == 32'h11) & dmi_reg_en;
assign dmstatus_reg[31:20] = '0;
assign dmstatus_reg[19:18] = {2{dmstatus_havereset}};
assign dmstatus_reg[15:10] = '0;
assign dmstatus_reg[15:14] = '0;
assign dmstatus_reg[7] = '1;
assign dmstatus_reg[6:4] = '0;
assign dmstatus_reg[17:16] = {2{dmstatus_resumeack}};
assign dmstatus_reg[13:12] = {2{dmstatus_unavail}};
assign dmstatus_reg[11:10] = {2{dmstatus_running}};
assign dmstatus_reg[9:8] = {2{dmstatus_halted}};
assign dmstatus_reg[3:0] = 4'h2;
@ -328,11 +334,14 @@ module dbg (
assign dmstatus_havereset_wren = (dmi_reg_addr == 7'h10) & dmi_reg_wdata[1] & dmi_reg_en & dmi_reg_wr_en;
assign dmstatus_havereset_rst = (dmi_reg_addr == 7'h10) & dmi_reg_wdata[28] & dmi_reg_en & dmi_reg_wr_en;
assign dmstatus_unavail = dmcontrol_reg[1] | ~rst_l;
assign dmstatus_running = ~(dmstatus_unavail | dmstatus_halted);
rvdffs #(1) dmstatus_resumeack_reg (.din(dmstatus_resumeack_din), .dout(dmstatus_resumeack), .en(dmstatus_resumeack_wren), .rst_l(dbg_dm_rst_l), .clk(dbg_free_clk));
rvdff #(1) dmstatus_halted_reg (.din(dec_tlu_dbg_halted & ~dec_tlu_mpc_halted_only), .dout(dmstatus_halted), .rst_l(dbg_dm_rst_l), .clk(dbg_free_clk));
rvdffsc #(1) dmstatus_havereset_reg (.din(1'b1), .dout(dmstatus_havereset), .en(dmstatus_havereset_wren), .clear(dmstatus_havereset_rst), .rst_l(dbg_dm_rst_l), .clk(dbg_free_clk));
// haltsum0 register
assign haltsum0_reg[31:1] = '0;
assign haltsum0_reg[0] = dmstatus_halted;
@ -343,37 +352,37 @@ module dbg (
assign abstractcs_reg[11] = '0;
assign abstractcs_reg[7:4] = '0;
assign abstractcs_reg[3:0] = 4'h2; // One data register
assign abstractcs_error_sel0 = abstractcs_reg[12] & dmi_reg_en & ((dmi_reg_wr_en & ( (dmi_reg_addr == 7'h16) | (dmi_reg_addr == 7'h17))) | (dmi_reg_addr == 7'h4));
assign abstractcs_error_sel0 = abstractcs_reg[12] & dmi_reg_en & ((dmi_reg_wr_en & ( (dmi_reg_addr == 7'h16) | (dmi_reg_addr == 7'h17))) | (dmi_reg_addr == 7'h4));
assign abstractcs_error_sel1 = dmi_reg_en & dmi_reg_wr_en & (dmi_reg_addr == 7'h17) & ~((dmi_reg_wdata[31:24] == 8'b0) | (dmi_reg_wdata[31:24] == 8'h2));
assign abstractcs_error_sel2 = core_dbg_cmd_done & core_dbg_cmd_fail;
assign abstractcs_error_sel3 = dmi_reg_en & dmi_reg_wr_en & (dmi_reg_addr == 7'h17) & (dbg_state != HALTED);
assign abstractcs_error_sel4 = (dmi_reg_addr == 7'h17) & dmi_reg_en & dmi_reg_wr_en &
( ((dmi_reg_wdata[22:20] == 3'b001) & data1_reg[0]) |
((dmi_reg_wdata[22:20] == 3'b010) & (|data1_reg[1:0])) |
assign abstractcs_error_sel4 = (dmi_reg_addr == 7'h17) & dmi_reg_en & dmi_reg_wr_en &
( ((dmi_reg_wdata[22:20] == 3'b001) & data1_reg[0]) |
((dmi_reg_wdata[22:20] == 3'b010) & (|data1_reg[1:0])) |
dmi_reg_wdata[22] | (dmi_reg_wdata[22:20] == 3'b011)
);
assign abstractcs_error_sel5 = (dmi_reg_addr == 7'h16) & dmi_reg_en & dmi_reg_wr_en;
assign abstractcs_error_selor = abstractcs_error_sel0 | abstractcs_error_sel1 | abstractcs_error_sel2 | abstractcs_error_sel3 | abstractcs_error_sel4 | abstractcs_error_sel5;
assign abstractcs_error_din[2:0] = ({3{abstractcs_error_sel0}} & 3'b001) | // writing command or abstractcs while a command was executing. Or accessing data0
assign abstractcs_error_din[2:0] = ({3{abstractcs_error_sel0}} & 3'b001) | // writing command or abstractcs while a command was executing. Or accessing data0
({3{abstractcs_error_sel1}} & 3'b010) | // writing a non-zero command to cmd field of command
({3{abstractcs_error_sel2}} & 3'b011) | // exception while running command
({3{abstractcs_error_sel3}} & 3'b100) | // writing a comnand when not in the halted state
({3{abstractcs_error_sel4}} & 3'b111) | // unaligned abstract memory command
({3{abstractcs_error_sel5}} & ~dmi_reg_wdata[10:8] & abstractcs_reg[10:8]) | // W1C
({3{~abstractcs_error_selor}} & abstractcs_reg[10:8]); // hold
rvdffs #(1) dmabstractcs_busy_reg (.din(abstractcs_busy_din), .dout(abstractcs_reg[12]), .en(abstractcs_busy_wren), .rst_l(dbg_dm_rst_l), .clk(dbg_free_clk));
rvdff #(3) dmabstractcs_error_reg (.din(abstractcs_error_din[2:0]), .dout(abstractcs_reg[10:8]), .rst_l(dbg_dm_rst_l), .clk(dbg_free_clk));
// command register - implemented all the bits in this register
// command[16] = 1: write, 0: read
assign command_wren = (dmi_reg_addr == 7'h17) & dmi_reg_en & dmi_reg_wr_en & (dbg_state == HALTED);
rvdffe #(32) dmcommand_reg (.*, .din(dmi_reg_wdata[31:0]), .dout(command_reg[31:0]), .en(command_wren), .rst_l(dbg_dm_rst_l));
// data0 reg
assign data0_reg_wren0 = (dmi_reg_en & dmi_reg_wr_en & (dmi_reg_addr == 7'h4) & (dbg_state == HALTED));
assign data0_reg_wren1 = core_dbg_cmd_done & (dbg_state == CMD_WAIT) & ~command_reg[16];
@ -381,17 +390,17 @@ module dbg (
assign data0_din[31:0] = ({32{data0_reg_wren0}} & dmi_reg_wdata[31:0]) |
({32{data0_reg_wren1}} & core_dbg_rddata[31:0]);
rvdffe #(32) dbg_data0_reg (.*, .din(data0_din[31:0]), .dout(data0_reg[31:0]), .en(data0_reg_wren), .rst_l(dbg_dm_rst_l));
// data 1
// data 1
assign data1_reg_wren0 = (dmi_reg_en & dmi_reg_wr_en & (dmi_reg_addr == 7'h5) & (dbg_state == HALTED));
assign data1_reg_wren1 = 1'b0; // core_dbg_cmd_done & (dbg_state == CMD_WAIT) & ~command_reg[16];
assign data1_reg_wren = data1_reg_wren0 | data1_reg_wren1;
assign data1_din[31:0] = ({32{data1_reg_wren0}} & dmi_reg_wdata[31:0]);
//({32{data0_reg_wren1}} & core_dbg_rddata[31:0]);
rvdffe #(32) dbg_data1_reg (.*, .din(data1_din[31:0]), .dout(data1_reg[31:0]), .en(data1_reg_wren), .rst_l(dbg_dm_rst_l));
@ -401,47 +410,47 @@ module dbg (
dbg_state_en = 1'b0;
abstractcs_busy_wren = 1'b0;
abstractcs_busy_din = 1'b0;
dbg_halt_req = dmcontrol_wren_Q & dmcontrol_reg[31]; // single pulse output to the core
dbg_halt_req = dmcontrol_wren_Q & dmcontrol_reg[31] & ~dmcontrol_reg[1]; // single pulse output to the core. Need to drive every time this register is written since core might be halted due to MPC
dbg_resume_req = 1'b0; // single pulse output to the core
case (dbg_state)
IDLE: begin
dbg_nxtstate = (dmstatus_reg[9] | dec_tlu_mpc_halted_only) ? HALTED : HALTING; // initiate the halt command to the core
dbg_state_en = ((dmcontrol_reg[31] & ~dec_tlu_debug_mode) | dmstatus_reg[9] | dec_tlu_mpc_halted_only) & ~dmcontrol_reg[1]; // when the jtag writes the halt bit in the DM register, OR when the status indicates Halted
dbg_halt_req = dmcontrol_reg[31]; // Removed debug mode qualification during MPC changes
//dbg_halt_req = dmcontrol_reg[31] & ~dec_tlu_debug_mode; // only when jtag has written the halt_req bit in the control
dbg_state_en = ((dmcontrol_reg[31] & ~dec_tlu_debug_mode) | dmstatus_reg[9] | dec_tlu_mpc_halted_only) & ~dmcontrol_reg[1]; // when the jtag writes the halt bit in the DM register, OR when the status indicates Halted
dbg_halt_req = dmcontrol_reg[31] & ~dmcontrol_reg[1]; // Removed debug mode qualification during MPC changes
//dbg_halt_req = dmcontrol_reg[31] & ~dec_tlu_debug_mode; // only when jtag has written the halt_req bit in the control
end
HALTING : begin
dbg_nxtstate = HALTED; // Goto HALTED once the core sends an ACK
dbg_state_en = dmstatus_reg[9]; // core indicates halted
dbg_nxtstate = dmcontrol_reg[1] ? IDLE : HALTED; // Goto HALTED once the core sends an ACK
dbg_state_en = dmstatus_reg[9] | dmcontrol_reg[1]; // core indicates halted
end
HALTED: begin
// wait for halted to go away before send to resume. Else start of new command
dbg_nxtstate = (dmstatus_reg[9] & ~dmcontrol_reg[1]) ? ((dmcontrol_reg[30] & ~dmcontrol_reg[31]) ? RESUMING : CMD_START) :
dbg_nxtstate = (dmstatus_reg[9] & ~dmcontrol_reg[1]) ? ((dmcontrol_reg[30] & ~dmcontrol_reg[31]) ? RESUMING : CMD_START) :
(dmcontrol_reg[31] ? HALTING : IDLE); // This is MPC halted case
//dbg_nxtstate = dmcontrol_reg[1] ? IDLE : (dmcontrol_reg[30] & ~dmcontrol_reg[31]) ? RESUMING : CMD_START; // wait for halted to go away before send to resume. Else start of new command
dbg_state_en = (dmstatus_reg[9] & dmcontrol_reg[30] & ~dmcontrol_reg[31] & dmcontrol_wren_Q) | command_wren | dmcontrol_reg[1] | ~(dmstatus_reg[9] | dec_tlu_mpc_halted_only);
abstractcs_busy_wren = dbg_state_en & (dbg_nxtstate == CMD_START); // write busy when a new command was written by jtag
abstractcs_busy_din = 1'b1;
dbg_resume_req = dbg_state_en & (dbg_nxtstate == RESUMING); // single cycle pulse to core if resuming
abstractcs_busy_din = 1'b1;
dbg_resume_req = dbg_state_en & (dbg_nxtstate == RESUMING); // single cycle pulse to core if resuming
end
CMD_START: begin
dbg_nxtstate = (|abstractcs_reg[10:8]) ? CMD_DONE : CMD_WAIT; // new command sent to the core
dbg_state_en = dbg_cmd_valid | (|abstractcs_reg[10:8]);
end
dbg_nxtstate = dmcontrol_reg[1] ? IDLE : (|abstractcs_reg[10:8]) ? CMD_DONE : CMD_WAIT; // new command sent to the core
dbg_state_en = dbg_cmd_valid | (|abstractcs_reg[10:8]) | dmcontrol_reg[1];
end
CMD_WAIT: begin
dbg_nxtstate = CMD_DONE;
dbg_state_en = core_dbg_cmd_done; // go to done state for one cycle after completing current command
dbg_nxtstate = dmcontrol_reg[1] ? IDLE : CMD_DONE;
dbg_state_en = core_dbg_cmd_done | dmcontrol_reg[1]; // go to done state for one cycle after completing current command
end
CMD_DONE: begin
dbg_nxtstate = HALTED;
dbg_nxtstate = dmcontrol_reg[1] ? IDLE : HALTED;
dbg_state_en = 1'b1;
abstractcs_busy_wren = dbg_state_en; // remove the busy bit from the abstracts ( bit 12 )
abstractcs_busy_din = 1'b0;
end
RESUMING : begin
dbg_nxtstate = IDLE;
dbg_state_en = dmstatus_reg[17]; // resume ack has been updated in the dmstatus register
dbg_nxtstate = IDLE;
dbg_state_en = dmstatus_reg[17] | dmcontrol_reg[1]; // resume ack has been updated in the dmstatus register
end
default : begin
dbg_nxtstate = IDLE;
@ -456,33 +465,33 @@ module dbg (
assign dmi_reg_rdata_din[31:0] = ({32{dmi_reg_addr == 7'h4}} & data0_reg[31:0]) |
({32{dmi_reg_addr == 7'h5}} & data1_reg[31:0]) |
({32{dmi_reg_addr == 7'h10}} & dmcontrol_reg[31:0]) |
({32{dmi_reg_addr == 7'h10}} & dmcontrol_reg[31:0]) |
({32{dmi_reg_addr == 7'h11}} & dmstatus_reg[31:0]) |
({32{dmi_reg_addr == 7'h16}} & abstractcs_reg[31:0]) |
({32{dmi_reg_addr == 7'h16}} & abstractcs_reg[31:0]) |
({32{dmi_reg_addr == 7'h17}} & command_reg[31:0]) |
({32{dmi_reg_addr == 7'h40}} & haltsum0_reg[31:0]) |
({32{dmi_reg_addr == 7'h38}} & sbcs_reg[31:0]) |
({32{dmi_reg_addr == 7'h39}} & sbaddress0_reg[31:0]) |
({32{dmi_reg_addr == 7'h3c}} & sbdata0_reg[31:0]) |
({32{dmi_reg_addr == 7'h39}} & sbaddress0_reg[31:0]) |
({32{dmi_reg_addr == 7'h3c}} & sbdata0_reg[31:0]) |
({32{dmi_reg_addr == 7'h3d}} & sbdata1_reg[31:0]);
rvdffs #($bits(state_t)) dbg_state_reg (.din(dbg_nxtstate), .dout({dbg_state}), .en(dbg_state_en), .rst_l(dbg_dm_rst_l), .clk(dbg_free_clk));
rvdffs #($bits(state_t)) dbg_state_reg (.din(dbg_nxtstate), .dout({dbg_state}), .en(dbg_state_en), .rst_l(dbg_dm_rst_l & rst_l), .clk(dbg_free_clk)); // Reset for both core/dbg reset
// Ack will use the power on reset only otherwise there won't be any ack until dmactive is 1
// rvdff #(1) dmi_ack_reg (.din(dmi_reg_en), .dout(dmi_reg_ack), .rst_l(rst_l), .clk(free_clk));
rvdffs #(32) dmi_rddata_reg(.din(dmi_reg_rdata_din), .dout(dmi_reg_rdata), .en(dmi_reg_en), .rst_l(dbg_dm_rst_l), .clk(dbg_free_clk));
// interface for the core
assign dbg_cmd_addr[31:0] = (command_reg[31:24] == 8'h2) ? {data1_reg[31:2],2'b0} : {20'b0, command_reg[11:0]}; // Only word addresses for abstract memory
assign dbg_cmd_wrdata[31:0] = data0_reg[31:0];
assign dbg_cmd_valid = (dbg_state == CMD_START) & ~(|abstractcs_reg[10:8]) & dma_dbg_ready;
assign dbg_cmd_valid = (dbg_state == CMD_START) & ~(|abstractcs_reg[10:8]) & dma_dbg_ready;
assign dbg_cmd_write = command_reg[16];
assign dbg_cmd_type[1:0] = (command_reg[31:24] == 8'h2) ? 2'b10 : {1'b0, (command_reg[15:12] == 4'b0)};
assign dbg_cmd_size[1:0] = command_reg[21:20];
// Ask DMA to stop taking bus trxns since debug request is done
assign dbg_dma_bubble = ((dbg_state == CMD_START) & ~(|abstractcs_reg[10:8])) | (dbg_state == CMD_WAIT);
// system bus FSM
always_comb begin
sb_nxtstate = SBIDLE;
@ -491,7 +500,7 @@ module dbg (
sbcs_sbbusy_din = 1'b0;
sbcs_sberror_wren = 1'b0;
sbcs_sberror_din[2:0] = 3'b0;
sbaddress0_reg_wren1 = 1'b0;
sbaddress0_reg_wren1 = 1'b0;
case (sb_state)
SBIDLE: begin
sb_nxtstate = sbdata0wr_access ? WAIT_WR : WAIT_RD;
@ -500,7 +509,7 @@ module dbg (
sbcs_sbbusy_din = 1'b1;
sbcs_sberror_wren = sbcs_wren & (|dmi_reg_wdata[14:12]); // write to clear the error bits
sbcs_sberror_din[2:0] = ~dmi_reg_wdata[14:12] & sbcs_reg[14:12];
end
end
WAIT_RD: begin
sb_nxtstate = (sbcs_unaligned | sbcs_illegal_size) ? DONE : CMD_RD;
sb_state_en = dbg_bus_clk_en | sbcs_unaligned | sbcs_illegal_size;
@ -513,55 +522,55 @@ module dbg (
sbcs_sberror_wren = sbcs_unaligned | sbcs_illegal_size;
sbcs_sberror_din[2:0] = sbcs_unaligned ? 3'b011 : 3'b100;
end
CMD_RD : begin
sb_nxtstate = RSP_RD;
CMD_RD : begin
sb_nxtstate = RSP_RD;
sb_state_en = sb_axi_arvalid_q & sb_axi_arready_q & dbg_bus_clk_en;
end
CMD_WR : begin
sb_nxtstate = (sb_axi_awready_q & sb_axi_wready_q) ? RSP_WR : (sb_axi_awready_q ? CMD_WR_DATA : CMD_WR_ADDR);
end
CMD_WR : begin
sb_nxtstate = (sb_axi_awready_q & sb_axi_wready_q) ? RSP_WR : (sb_axi_awready_q ? CMD_WR_DATA : CMD_WR_ADDR);
sb_state_en = ((sb_axi_awvalid_q & sb_axi_awready_q) | (sb_axi_wvalid_q & sb_axi_wready_q)) & dbg_bus_clk_en;
end
CMD_WR_ADDR : begin
sb_nxtstate = RSP_WR;
end
CMD_WR_ADDR : begin
sb_nxtstate = RSP_WR;
sb_state_en = sb_axi_awvalid_q & sb_axi_awready_q & dbg_bus_clk_en;
end
CMD_WR_DATA : begin
sb_nxtstate = RSP_WR;
end
CMD_WR_DATA : begin
sb_nxtstate = RSP_WR;
sb_state_en = sb_axi_wvalid_q & sb_axi_wready_q & dbg_bus_clk_en;
end
RSP_RD: begin
end
RSP_RD: begin
sb_nxtstate = DONE;
sb_state_en = sb_axi_rvalid_q & sb_axi_rready_q & dbg_bus_clk_en;
sbcs_sberror_wren = sb_state_en & sb_axi_rresp_q[1];
sbcs_sberror_din[2:0] = 3'b010;
end
RSP_WR: begin
end
RSP_WR: begin
sb_nxtstate = DONE;
sb_state_en = sb_axi_bvalid_q & sb_axi_bready_q & dbg_bus_clk_en;
sbcs_sberror_wren = sb_state_en & sb_axi_bresp_q[1];
sbcs_sberror_din[2:0] = 3'b010;
end
DONE: begin
end
DONE: begin
sb_nxtstate = SBIDLE;
sb_state_en = 1'b1;
sbcs_sbbusy_wren = 1'b1; // reset the single read
sbcs_sbbusy_din = 1'b0;
sbaddress0_reg_wren1 = sbcs_reg[16]; // auto increment was set. Update to new address after completing the current command
sbaddress0_reg_wren1 = sbcs_reg[16]; // auto increment was set. Update to new address after completing the current command
end
default : begin
default : begin
sb_nxtstate = SBIDLE;
sb_state_en = 1'b0;
sbcs_sbbusy_wren = 1'b0;
sbcs_sbbusy_din = 1'b0;
sbcs_sberror_wren = 1'b0;
sbcs_sberror_din[2:0] = 3'b0;
sbaddress0_reg_wren1 = 1'b0;
end
sbaddress0_reg_wren1 = 1'b0;
end
endcase
end // always_comb begin
rvdffs #($bits(sb_state_t)) sb_state_reg (.din(sb_nxtstate), .dout({sb_state}), .en(sb_state_en), .rst_l(dbg_dm_rst_l), .clk(sb_free_clk));
//rvdff #(.WIDTH(1)) bus_clken_ff (.din(dbg_bus_clk_en), .dout(dbg_bus_clk_en_q), .rst_l(dbg_dm_rst_l), .clk(dbg_sb_c2_free_clk), .*);
rvdffs #(.WIDTH(1)) axi_awvalid_ff (.din(sb_axi_awvalid), .dout(sb_axi_awvalid_q), .en(dbg_bus_clk_en), .rst_l(dbg_dm_rst_l), .clk(sb_free_clk), .*);
@ -591,7 +600,7 @@ module dbg (
assign sb_axi_awburst[1:0] = 2'b01;
assign sb_axi_awqos[3:0] = '0;
assign sb_axi_awlock = '0;
assign sb_axi_wvalid = ((sb_state == CMD_WR) | (sb_state == CMD_WR_DATA)) & ~(sb_axi_wvalid_q & sb_axi_wready_q);
assign sb_axi_wdata[63:0] = ({64{(sbcs_reg[19:17] == 3'h0)}} & {8{sbdata0_reg[7:0]}}) |
({64{(sbcs_reg[19:17] == 3'h1)}} & {4{sbdata0_reg[15:0]}}) |
@ -604,9 +613,9 @@ module dbg (
assign sb_axi_wlast = '1;
assign sb_axi_arvalid = (sb_state == CMD_RD) & ~(sb_axi_arvalid_q & sb_axi_arready_q);
assign sb_axi_araddr[31:0] = {sbaddress0_reg[31:3],3'b0};
assign sb_axi_araddr[31:0] = sbaddress0_reg[31:0];
assign sb_axi_arid[SB_BUS_TAG-1:0] = '0;
assign sb_axi_arsize[2:0] = 3'b011;
assign sb_axi_arsize[2:0] = sbcs_reg[19:17];
assign sb_axi_arprot[2:0] = '0;
assign sb_axi_arcache[3:0] = 4'b0;
assign sb_axi_arregion[3:0] = sbaddress0_reg[31:28];
@ -623,10 +632,10 @@ module dbg (
({64{sbcs_reg[19:17] == 3'h1}} & ((sb_axi_rdata_q[63:0] >> 16*sbaddress0_reg[2:1]) & 64'hffff)) |
({64{sbcs_reg[19:17] == 3'h2}} & ((sb_axi_rdata_q[63:0] >> 32*sbaddress0_reg[2]) & 64'hffff_ffff)) |
({64{sbcs_reg[19:17] == 3'h3}} & sb_axi_rdata_q[63:0]);
`ifdef ASSERT_ON
// assertion.
// when the resume_ack is asserted then the dec_tlu_dbg_halted should be 0
// assertion.
// when the resume_ack is asserted then the dec_tlu_dbg_halted should be 0
dm_check_resume_and_halted: assert property (@(posedge clk) disable iff(~rst_l) (~dec_tlu_resume_ack | ~dec_tlu_dbg_halted));
`endif
endmodule

View File

@ -116,24 +116,24 @@ c.swsp = [110...........10]
c.xor = [100011...01...01]
.input
.input
rv32c = {
i[15]
i[14]
i[13]
i[12]
i[11]
i[10]
i[9]
i[8]
i[7]
i[6]
i[5]
i[4]
i[3]
i[2]
i[1]
i[0]
i[15]
i[14]
i[13]
i[12]
i[11]
i[10]
i[9]
i[8]
i[7]
i[6]
i[5]
i[4]
i[3]
i[2]
i[1]
i[0]
}
.output
@ -145,52 +145,52 @@ rv32c = {
rdprs1
rs2prs2
rs2prd
uimm9_2
ulwimm6_2
ulwspimm7_2
rdeq2
rdeq1
rs1eq2
sbroffset8_1
simm9_4
simm5_0
sjaloffset11_1
sluimm17_12
uimm5_0
uswimm6_2
uswspimm7_2
o[31]
o[30]
o[29]
o[28]
o[27]
o[26]
o[25]
o[24]
o[23]
o[22]
o[21]
o[20]
o[19]
o[18]
o[17]
o[16]
o[15]
o[14]
o[13]
o[12]
o[11]
o[10]
o[9]
o[8]
o[7]
o[6]
o[5]
o[4]
o[3]
o[2]
o[1]
o[0]
uimm9_2
ulwimm6_2
ulwspimm7_2
rdeq2
rdeq1
rs1eq2
sbroffset8_1
simm9_4
simm5_0
sjaloffset11_1
sluimm17_12
uimm5_0
uswimm6_2
uswspimm7_2
o[31]
o[30]
o[29]
o[28]
o[27]
o[26]
o[25]
o[24]
o[23]
o[22]
o[21]
o[20]
o[19]
o[18]
o[17]
o[16]
o[15]
o[14]
o[13]
o[12]
o[11]
o[10]
o[9]
o[8]
o[7]
o[6]
o[5]
o[4]
o[3]
o[2]
o[1]
o[0]
}
# assign rs2d[4:0] = i[6:2];
@ -199,7 +199,7 @@ rv32c = {
#
# assign rdpd[4:0] = {2'b01, i[9:7]};
#
# assign rs2pd[4:0] = {2'b01, i[4:2]};
# assign rs2pd[4:0] = {2'b01, i[4:2]};
.decode

View File

@ -67,7 +67,7 @@ csr_perfvg = [001100100111]
csr_perfvh = [001100101...]
csr_perfvi = [00110011....]
.input
.input
csr = {
dec_csr_rdaddr_d[11]
@ -87,23 +87,23 @@ csr = {
.output
csr = {
csr_misa
csr_mvendorid
csr_marchid
csr_mimpid
csr_mhartid
csr_mstatus
csr_mtvec
csr_mip
csr_mie
csr_mcyclel
csr_mcycleh
csr_minstretl
csr_minstreth
csr_mscratch
csr_mepc
csr_mcause
csr_mtval
csr_misa
csr_mvendorid
csr_marchid
csr_mimpid
csr_mhartid
csr_mstatus
csr_mtvec
csr_mip
csr_mie
csr_mcyclel
csr_mcycleh
csr_minstretl
csr_minstreth
csr_mscratch
csr_mepc
csr_mcause
csr_mtval
csr_mrac
csr_dmst
csr_mdeau
@ -120,8 +120,8 @@ csr = {
csr_mcpc
csr_mfdc
csr_dpc
csr_mtsel
csr_mtdata1
csr_mtsel
csr_mtdata1
csr_mtdata2
csr_mhpmc3
csr_mhpmc4
@ -211,19 +211,19 @@ csr[ csr_mhpme6 ] = { csr_mhpme6 }
csr[ csr_micect ] = { csr_micect }
csr[ csr_miccmect ] = { csr_miccmect }
csr[ csr_mdccmect ] = { csr_mdccmect }
csr[ csr_dicawics ] = { csr_dicawics }
csr[ csr_dicad0 ] = { csr_dicad0 }
csr[ csr_dicad1 ] = { csr_dicad1 }
csr[ csr_dicago ] = { csr_dicago }
csr[ csr_dicawics ] = { csr_dicawics }
csr[ csr_dicad0 ] = { csr_dicad0 }
csr[ csr_dicad1 ] = { csr_dicad1 }
csr[ csr_dicago ] = { csr_dicago }
csr[ csr_perfva ] = { valid_only }
csr[ csr_perfvb ] = { valid_only }
csr[ csr_perfvc ] = { valid_only }
csr[ csr_perfvd ] = { valid_only }
csr[ csr_perfve ] = { valid_only }
csr[ csr_perfvf ] = { valid_only }
csr[ csr_perfvg ] = { valid_only }
csr[ csr_perfvh ] = { valid_only }
csr[ csr_perfvb ] = { valid_only }
csr[ csr_perfvc ] = { valid_only }
csr[ csr_perfvd ] = { valid_only }
csr[ csr_perfve ] = { valid_only }
csr[ csr_perfvf ] = { valid_only }
csr[ csr_perfvg ] = { valid_only }
csr[ csr_perfvh ] = { valid_only }
csr[ csr_perfvi ] = { valid_only }
.end

View File

@ -1,12 +1,12 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright 2019 Western Digital Corporation or its affiliates.
//
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//
// http://www.apache.org/licenses/LICENSE-2.0
//
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -14,19 +14,19 @@
// limitations under the License.
// dec: decode unit - decode, bypassing, ARF, interrupts
//
//
//********************************************************************************
// $Id$
//
//
// Function: Decode
//
// Function: Decode
// Comments: Decode, dependency scoreboard, ARF
//
//
//
// A -> D -> EX1 ... WB
//
//
//********************************************************************************
module dec
import swerv_types::*;
(
@ -36,12 +36,12 @@ module dec
output logic dec_pause_state_cg, // pause state for clock-gating
input logic rst_l, // reset, active low
input logic [31:1] rst_vec, // reset vector, from core pins
input logic nmi_int, // NMI pin
input logic [31:1] nmi_vec, // NMI vector, from pins
input logic [31:1] nmi_vec, // NMI vector, from pins
input logic i_cpu_halt_req, // Asynchronous Halt request to CPU
input logic i_cpu_run_req, // Asynchronous Restart request to CPU
@ -58,41 +58,41 @@ module dec
output logic mpc_debug_halt_ack, // Halt ack
output logic mpc_debug_run_ack, // Run ack
output logic debug_brkpt_status, // debug breakpoint
output logic dec_ib0_valid_eff_d, // effective valid taking decode into account
output logic dec_ib0_valid_eff_d, // effective valid taking decode into account
output logic dec_ib1_valid_eff_d,
input logic exu_pmu_i0_br_misp, // slot 0 branch misp
input logic exu_pmu_i0_br_ataken, // slot 0 branch actual taken
input logic exu_pmu_i0_pc4, // slot 0 4 byte branch
input logic exu_pmu_i1_br_misp, // slot 1 branch misp
input logic exu_pmu_i0_pc4, // slot 0 4 byte branch
input logic exu_pmu_i1_br_misp, // slot 1 branch misp
input logic exu_pmu_i1_br_ataken, // slot 1 branch actual taken
input logic exu_pmu_i1_pc4, // slot 1 4 byte branch
input logic exu_pmu_i1_pc4, // slot 1 4 byte branch
input logic lsu_nonblock_load_valid_dc3, // valid nonblock load at dc3
input logic [`RV_LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_tag_dc3, // -> corresponding tag
input logic lsu_nonblock_load_inv_dc5, // invalidate request for nonblock load dc5
input logic [`RV_LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_inv_tag_dc5, // -> corresponding tag
input logic lsu_nonblock_load_data_valid, // valid nonblock load data back
input logic lsu_nonblock_load_data_error, // nonblock load bus error
input logic [`RV_LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_data_tag, // -> corresponding tag
input logic lsu_nonblock_load_valid_dc3, // valid nonblock load at dc3
input logic [`RV_LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_tag_dc3, // -> corresponding tag
input logic lsu_nonblock_load_inv_dc5, // invalidate request for nonblock load dc5
input logic [`RV_LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_inv_tag_dc5, // -> corresponding tag
input logic lsu_nonblock_load_data_valid, // valid nonblock load data back
input logic lsu_nonblock_load_data_error, // nonblock load bus error
input logic [`RV_LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_data_tag, // -> corresponding tag
input logic [31:0] lsu_nonblock_load_data, // nonblock load data
input logic lsu_pmu_bus_trxn, // D side bus transaction
input logic lsu_pmu_bus_misaligned, // D side bus misaligned
input logic lsu_pmu_bus_error, // D side bus error
input logic lsu_pmu_bus_busy, // D side bus busy
input logic lsu_pmu_misaligned_dc3, // D side load or store misaligned
input logic [1:0] ifu_pmu_instr_aligned, // aligned instructions
input logic ifu_pmu_align_stall, // aligner stalled
input logic ifu_pmu_fetch_stall, // fetch unit stalled
input logic ifu_pmu_ic_miss, // icache miss
input logic ifu_pmu_ic_hit, // icache hit
input logic ifu_pmu_bus_error, // Instruction side bus error
input logic ifu_pmu_bus_busy, // Instruction side bus busy
input logic ifu_pmu_bus_busy, // Instruction side bus busy
input logic ifu_pmu_bus_trxn, // Instruction side bus transaction
input logic [3:0] lsu_trigger_match_dc3,
@ -102,28 +102,31 @@ module dec
input logic [1:0] dbg_cmd_type, // command type
input logic [31:0] dbg_cmd_addr, // command address
input logic [1:0] dbg_cmd_wrdata, // command write data, for fence/fence_i
input logic ifu_i0_icaf, // icache access fault
input logic ifu_i1_icaf,
input logic ifu_i0_icaf, // icache access fault
input logic ifu_i1_icaf,
input logic ifu_i0_icaf_f1, // i0 has access fault on second fetch group
input logic ifu_i1_icaf_f1,
input logic ifu_i0_perr, // icache parity error
input logic ifu_i1_perr,
input logic ifu_i1_icaf_f1,
input logic ifu_i0_perr, // icache parity error
input logic ifu_i1_perr,
input logic ifu_i0_sbecc, // icache/iccm single-bit error
input logic ifu_i1_sbecc,
input logic ifu_i1_sbecc,
input logic ifu_i0_dbecc, // icache/iccm double-bit error
input logic ifu_i1_dbecc,
input logic lsu_freeze_dc3, // freeze pipe: decode -> dc3
input logic lsu_idle_any, // lsu idle for fence instructions
input logic lsu_halt_idle_any, // lsu idle for halting
input br_pkt_t i0_brp, // branch packet
input br_pkt_t i1_brp,
input lsu_error_pkt_t lsu_error_pkt_dc3, // LSU exception/error packet
input logic lsu_single_ecc_error_incr, // Increment the counter for Single ECC error
input logic lsu_load_ecc_stbuf_full_dc3, // STBUF full, ecc errors should be rfpc'd
input logic lsu_imprecise_error_load_any, // LSU imprecise load bus error
input logic lsu_imprecise_error_store_any, // LSU imprecise store bus error
input logic [31:0] lsu_imprecise_error_addr_any, // LSU imprecise bus error address
@ -135,7 +138,7 @@ module dec
input logic [31:1] exu_i1_flush_path_e4, // slot 1 flush target for mp
input logic [15:0] ifu_illegal_inst, // 16b opcode for illegal inst
input logic exu_div_stall, // stall decode for div executing
input logic [31:0] exu_div_result, // final div result
input logic exu_div_finish, // cycle div finishes
@ -146,14 +149,14 @@ module dec
input logic [31:0] lsu_result_dc3, // load result
input logic [31:0] lsu_result_corr_dc4, // corrected load result
input logic lsu_load_stall_any, // This is for blocking loads
input logic lsu_store_stall_any, // This is for blocking stores
input logic dma_dccm_stall_any, // stall any load/store at decode, pmu event
input logic dma_iccm_stall_any, // iccm stalled, pmu event
input logic iccm_dma_sb_error, // ICCM DMA single bit error
input logic exu_i0_flush_final, // slot0 flush
input logic exu_i1_flush_final, // slot1 flush
@ -162,10 +165,10 @@ module dec
input logic exu_flush_final, // final flush
input logic [31:0] exu_i0_result_e1, // alu result e1
input logic [31:0] exu_i1_result_e1,
input logic [31:0] exu_i1_result_e1,
input logic [31:0] exu_i0_result_e4, // alu result e4
input logic [31:0] exu_i1_result_e4,
input logic [31:0] exu_i1_result_e4,
input logic ifu_i0_valid, ifu_i1_valid, // fetch valids to instruction buffer
@ -173,14 +176,14 @@ module dec
input logic [31:1] ifu_i0_pc, ifu_i1_pc, // pc's for instruction buffer
input logic ifu_i0_pc4, ifu_i1_pc4, // indication of 4B or 2B for corresponding inst
input logic [31:1] exu_i0_pc_e1, // pc's for e1 from the alu's
input logic [31:1] exu_i1_pc_e1,
input logic [31:1] exu_i1_pc_e1,
input logic mexintpend, // External interrupt pending
input logic timer_int, // Timer interrupt pending (from pin)
input logic [7:0] pic_claimid, // PIC claimid
input logic [3:0] pic_pl, // PIC priv level
input logic mhwakeup, // High priority wakeup
input logic mhwakeup, // High priority wakeup
output logic [3:0] dec_tlu_meicurpl, // to PIC, Current priv level
output logic [3:0] dec_tlu_meipt, // to PIC
@ -192,13 +195,13 @@ module dec
`endif
input logic ifu_ic_debug_rd_data_valid, // diagnostic icache read data valid
output cache_debug_pkt_t dec_tlu_ic_diag_pkt, // packet of DICAWICS, DICAD0/1, DICAGO info for icache diagnostics
// Debug start
input logic dbg_halt_req, // DM requests a halt
input logic dbg_resume_req, // DM requests a resume
input logic ifu_miss_state_idle, // I-side miss buffer empty
output logic dec_tlu_flush_noredir_wb , // Tell fetch to idle on this flush
output logic dec_tlu_mpc_halted_only, // Core is halted only due to MPC
output logic dec_tlu_dbg_halted, // Core is halted and ready for debug command
@ -208,7 +211,7 @@ module dec
output logic dec_tlu_flush_leak_one_wb, // single step
output logic dec_tlu_flush_err_wb, // iside perr/ecc rfpc
output logic dec_tlu_stall_dma, // stall dma access when there's a halt request
output logic dec_debug_wdata_rs1_d, // insert debug write data into rs1 at decode
output logic [31:0] dec_dbg_rddata, // debug command read data
@ -228,8 +231,8 @@ module dec
input logic exu_i0_br_valid_e4, // valid
input logic exu_i0_br_mp_e4, // mispredict
input logic exu_i0_br_middle_e4, // middle of bank
input logic [`RV_BHT_GHR_RANGE] exu_i0_br_fghr_e4, // FGHR when predicted
input logic [`RV_BHT_GHR_RANGE] exu_i0_br_fghr_e4, // FGHR when predicted
// branch info from pipe1 for errors or counter updates
input logic [`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO] exu_i1_br_index_e4, // index
input logic [1:0] exu_i1_br_hist_e4, // history
@ -245,22 +248,22 @@ module dec
`ifdef RV_BTB_48
input logic [1:0] exu_i1_br_way_e4, // way hit or repl
input logic [1:0] exu_i0_br_way_e4, // way hit or repl
`else
`else
input logic exu_i1_br_way_e4, // way hit or repl
input logic exu_i0_br_way_e4, // way hit or repl
`endif
`endif
output logic [31:0] gpr_i0_rs1_d, // gpr rs1 data
output logic [31:0] gpr_i0_rs2_d, // gpr rs2 data
output logic [31:0] gpr_i1_rs1_d,
output logic [31:0] gpr_i1_rs2_d,
output logic [31:0] gpr_i1_rs1_d,
output logic [31:0] gpr_i1_rs2_d,
output logic [31:0] dec_i0_immed_d, // immediate data
output logic [31:0] dec_i1_immed_d,
output logic [31:0] dec_i1_immed_d,
output logic [12:1] dec_i0_br_immed_d, // br immediate data
output logic [12:1] dec_i1_br_immed_d,
output logic [12:1] dec_i1_br_immed_d,
output alu_pkt_t i0_ap, // alu packet
output alu_pkt_t i1_ap,
@ -268,14 +271,14 @@ module dec
output logic dec_i1_alu_decode_d,
output logic dec_i0_select_pc_d, // select pc onto rs1 for jal's
output logic dec_i1_select_pc_d,
output logic dec_i1_select_pc_d,
output logic [31:1] dec_i0_pc_d, dec_i1_pc_d, // pc's at decode
output logic dec_i0_rs1_bypass_en_d, // rs1 bypass enable
output logic dec_i0_rs2_bypass_en_d, // rs2 bypass enable
output logic dec_i1_rs1_bypass_en_d,
output logic dec_i1_rs2_bypass_en_d,
output logic [31:0] i0_rs1_bypass_data_d, // rs1 bypass data
output logic [31:0] i0_rs2_bypass_data_d, // rs2 bypass data
output logic [31:0] i1_rs1_bypass_data_d,
@ -286,22 +289,22 @@ module dec
output lsu_pkt_t lsu_p, // lsu packet
output mul_pkt_t mul_p, // mul packet
output div_pkt_t div_p, // div packet
output logic [11:0] dec_lsu_offset_d, // 12b offset for load/store addresses
output logic dec_i0_lsu_d, // is load/store
output logic dec_i1_lsu_d,
output logic flush_final_e3, // final flush
output logic i0_flush_final_e3, // final flush from i0
output logic dec_csr_ren_d, // csr read enable
output logic dec_csr_ren_d, // csr read enable
output logic dec_tlu_cancel_e4, // Cancel lsu op at DC4 due to future trigger hit
output logic dec_tlu_flush_lower_wb, // tlu flush due to late mp, exception, rfpc, or int
output logic [31:1] dec_tlu_flush_path_wb, // tlu flush target
output logic dec_tlu_i0_kill_writeb_wb, // I0 is flushed, don't writeback any results to arch state
output logic dec_tlu_i1_kill_writeb_wb, // I1 is flushed, don't writeback any results to arch state
output logic dec_tlu_i0_kill_writeb_wb, // I0 is flushed, don't writeback any results to arch state
output logic dec_tlu_i1_kill_writeb_wb, // I1 is flushed, don't writeback any results to arch state
output logic dec_tlu_fence_i_wb, // flush is a fence_i rfnpc, flush icache
output logic dec_i0_mul_d, // chose which gpr value to use
@ -311,14 +314,14 @@ module dec
output logic dec_i1_valid_e1, // i1 valid at e1 stage
output logic dec_div_decode_e4, // div at e4 stage
output logic [31:1] pred_correct_npc_e2, // npc if prediction is correct at e2 stage
output logic dec_i0_rs1_bypass_en_e3, // rs1 bypass enable e3
output logic dec_i0_rs2_bypass_en_e3, // rs2 bypass enable e3
output logic dec_i1_rs1_bypass_en_e3,
output logic dec_i1_rs2_bypass_en_e3,
output logic [31:0] i0_rs1_bypass_data_e3, // rs1 bypass data e3
output logic dec_i1_rs1_bypass_en_e3,
output logic dec_i1_rs2_bypass_en_e3,
output logic [31:0] i0_rs1_bypass_data_e3, // rs1 bypass data e3
output logic [31:0] i0_rs2_bypass_data_e3, // rs2 bypass data e3
output logic [31:0] i1_rs1_bypass_data_e3,
output logic [31:0] i1_rs1_bypass_data_e3,
output logic [31:0] i1_rs2_bypass_data_e3,
output logic dec_i0_sec_decode_e3, // secondary decode e3
output logic dec_i1_sec_decode_e3,
@ -343,11 +346,11 @@ module dec
output logic [1:0] dec_tlu_perfcnt3, // toggles when perf counter 3 has an event inc
output predict_pkt_t i0_predict_p_d, // prediction packet to alus
output predict_pkt_t i1_predict_p_d,
output predict_pkt_t i1_predict_p_d,
output logic dec_i0_lsu_decode_d, // load/store decode
output logic [31:0] i0_result_e4_eff, // alu result e4
output logic dec_i0_lsu_decode_d, // load/store decode
output logic [31:0] i0_result_e4_eff, // alu result e4
output logic [31:0] i1_result_e4_eff,
output logic dec_tlu_i0_valid_e4, // slot 0 instruction is valid at e4
@ -357,12 +360,12 @@ module dec
output logic [31:0] dec_tlu_mrac_ff, // CSR for memory region control
output logic [31:1] dec_tlu_i0_pc_e4, // pc e4
output logic [31:1] dec_tlu_i1_pc_e4,
output logic [31:1] dec_tlu_i1_pc_e4,
output logic [4:2] dec_i0_data_en, // clock-gate control logic
output logic [4:1] dec_i0_ctl_en,
output logic [4:1] dec_i0_ctl_en,
output logic [4:2] dec_i1_data_en,
output logic [4:1] dec_i1_ctl_en,
output logic [4:1] dec_i1_ctl_en,
output logic dec_nonblock_load_freeze_dc2, // lsu must freeze nonblock load due to younger dependency in pipe
@ -370,7 +373,7 @@ module dec
input logic [15:0] ifu_i1_cinst,
output trace_pkt_t trace_rv_trace_pkt, // trace packet
// feature disable from mfdc
output logic dec_tlu_sideeffect_posted_disable, // disable posted writes to side-effect address
output logic dec_tlu_core_ecc_disable, // disable core ECC
@ -392,8 +395,8 @@ module dec
output logic dec_tlu_dccm_clk_override, // override DCCM clock domain gating
output logic dec_tlu_icm_clk_override, // override ICCM clock domain gating
input logic scan_mode
input logic scan_mode
);
localparam GPR_BANKS = 1;
@ -401,7 +404,7 @@ module dec
logic dec_tlu_dec_clk_override; // to and from dec blocks
logic clk_override;
logic dec_ib1_valid_d;
logic dec_ib0_valid_d;
@ -409,55 +412,55 @@ module dec
logic dec_pmu_decode_stall;
logic dec_pmu_presync_stall;
logic dec_pmu_postsync_stall;
logic dec_tlu_wr_pause_wb; // CSR write to pause reg is at WB.
logic dec_i0_rs1_en_d;
logic dec_i0_rs2_en_d;
logic dec_fence_pending; // tell TLU to stall DMA
logic [4:0] dec_i0_rs1_d;
logic [4:0] dec_i0_rs2_d;
logic dec_i1_rs1_en_d;
logic dec_i1_rs2_en_d;
logic [4:0] dec_i1_rs1_d;
logic [4:0] dec_i1_rs2_d;
logic [31:0] dec_i0_instr_d, dec_i1_instr_d;
logic dec_tlu_pipelining_disable;
logic dec_tlu_dual_issue_disable;
logic [4:0] dec_i0_waddr_wb;
logic dec_i0_wen_wb;
logic [31:0] dec_i0_wdata_wb;
logic [4:0] dec_i1_waddr_wb;
logic dec_i1_wen_wb;
logic [31:0] dec_i1_wdata_wb;
logic dec_csr_wen_wb; // csr write enable at wb
logic [11:0] dec_csr_rdaddr_d; // read address for csr
logic dec_csr_wen_wb; // csr write enable at wb
logic [11:0] dec_csr_rdaddr_d; // read address for csr
logic [11:0] dec_csr_wraddr_wb; // write address for csryes
logic [31:0] dec_csr_wrdata_wb; // csr write data at wb
logic [31:0] dec_csr_rddata_d; // csr read data at wb
logic dec_csr_legal_d; // csr indicates legal operation
logic dec_csr_legal_d; // csr indicates legal operation
logic dec_csr_wen_unq_d; // valid csr with write - for csr legal
logic dec_csr_any_unq_d; // valid csr - for csr legal
logic dec_csr_any_unq_d; // valid csr - for csr legal
logic dec_csr_stall_int_ff; // csr is mie/mstatus
trap_pkt_t dec_tlu_packet_e4;
logic dec_i0_pc4_d, dec_i1_pc4_d;
logic dec_tlu_presync_d;
logic dec_tlu_postsync_d;
@ -465,7 +468,7 @@ module dec
logic [31:0] dec_illegal_inst;
// GPR Bank ID write signals
logic wen_bank_id;
logic [GPR_BANKS_LOG2-1:0] wr_bank_id;
@ -483,11 +486,11 @@ module dec
logic dec_i0_decode_d;
logic dec_i1_decode_d;
logic [3:0] dec_i0_trigger_match_d;
logic [3:0] dec_i1_trigger_match_d;
logic dec_debug_fence_d;
logic dec_nonblock_load_wen;
@ -497,15 +500,15 @@ module dec
logic dec_i0_load_e4;
logic dec_pause_state;
br_pkt_t dec_i0_brp;
br_pkt_t dec_i1_brp;
assign clk_override = dec_tlu_dec_clk_override;
assign dec_dbg_rddata[31:0] = dec_i0_wdata_wb[31:0];
dec_ib_ctl instbuff (.*
);
@ -518,7 +521,7 @@ module dec
assign wr_bank_id = '0;
dec_gpr_ctl #(.GPR_BANKS(GPR_BANKS),
.GPR_BANKS_LOG2(GPR_BANKS_LOG2)) arf (.*,
// inputs
@ -526,24 +529,24 @@ module dec
.raddr1(dec_i0_rs2_d[4:0]), .rden1(dec_i0_rs2_en_d),
.raddr2(dec_i1_rs1_d[4:0]), .rden2(dec_i1_rs1_en_d),
.raddr3(dec_i1_rs2_d[4:0]), .rden3(dec_i1_rs2_en_d),
.waddr0(dec_i0_waddr_wb[4:0]), .wen0(dec_i0_wen_wb), .wd0(dec_i0_wdata_wb[31:0]),
.waddr1(dec_i1_waddr_wb[4:0]), .wen1(dec_i1_wen_wb), .wd1(dec_i1_wdata_wb[31:0]),
.waddr2(dec_nonblock_load_waddr[4:0]), .wen2(dec_nonblock_load_wen), .wd2(lsu_nonblock_load_data[31:0]),
.waddr1(dec_i1_waddr_wb[4:0]), .wen1(dec_i1_wen_wb), .wd1(dec_i1_wdata_wb[31:0]),
.waddr2(dec_nonblock_load_waddr[4:0]), .wen2(dec_nonblock_load_wen), .wd2(lsu_nonblock_load_data[31:0]),
// outputs
.rd0(gpr_i0_rs1_d[31:0]), .rd1(gpr_i0_rs2_d[31:0]),
.rd2(gpr_i1_rs1_d[31:0]), .rd3(gpr_i1_rs2_d[31:0])
.rd2(gpr_i1_rs1_d[31:0]), .rd3(gpr_i1_rs2_d[31:0])
);
// Trigger
dec_trigger dec_trigger (.*);
// trace
logic [15:0] dec_i0_cinst_d;
logic [15:0] dec_i1_cinst_d;
@ -558,7 +561,7 @@ module dec
logic dec_tlu_i0_exc_valid_wb1, dec_tlu_i1_exc_valid_wb1;
// also need retires_p==3
assign trace_rv_trace_pkt.trace_rv_i_insn_ip = { 32'b0, dec_i1_inst_wb1[31:0], dec_i0_inst_wb1[31:0] };
assign trace_rv_trace_pkt.trace_rv_i_address_ip = { 32'b0, dec_i1_pc_wb1[31:1], 1'b0, dec_i0_pc_wb1[31:1], 1'b0 };
@ -571,9 +574,9 @@ module dec
assign trace_rv_trace_pkt.trace_rv_i_interrupt_ip = {dec_tlu_int_valid_wb1,2'b0};
assign trace_rv_trace_pkt.trace_rv_i_tval_ip = dec_tlu_mtval_wb1[31:0]; // replicate across ports
// end trace
endmodule // dec

File diff suppressed because it is too large Load Diff

View File

@ -1,12 +1,12 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright 2019 Western Digital Corporation or its affiliates.
//
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//
// http://www.apache.org/licenses/LICENSE-2.0
//
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -29,22 +29,22 @@ module dec_gpr_ctl #(parameter GPR_BANKS = 1,
input logic [4:0] waddr0, // logical write addresses
input logic [4:0] waddr1,
input logic [4:0] waddr2,
input logic [4:0] waddr2,
input logic wen0, // write enables
input logic wen1,
input logic wen1,
input logic wen2,
input logic [31:0] wd0, // write data
input logic [31:0] wd1,
input logic [31:0] wd2,
input logic wen_bank_id, // write enable for banks
input logic [GPR_BANKS_LOG2-1:0] wr_bank_id, // read enable for banks
input logic clk,
input logic rst_l,
output logic [31:0] rd0, // read data
output logic [31:0] rd1,
output logic [31:0] rd2,
@ -59,55 +59,55 @@ module dec_gpr_ctl #(parameter GPR_BANKS = 1,
logic [31:1] gpr_wr_en;
logic [GPR_BANKS-1:0][31:1] gpr_bank_wr_en;
logic [GPR_BANKS_LOG2-1:0] gpr_bank_id;
//assign gpr_bank_id[GPR_BANKS_LOG2-1:0] = '0;
rvdffs #(GPR_BANKS_LOG2) bankid_ff (.*, .clk(active_clk), .en(wen_bank_id), .din(wr_bank_id[GPR_BANKS_LOG2-1:0]), .dout(gpr_bank_id[GPR_BANKS_LOG2-1:0]));
// GPR Write Enables for power savings
rvdffs #(GPR_BANKS_LOG2) bankid_ff (.*, .clk(active_clk), .en(wen_bank_id), .din(wr_bank_id[GPR_BANKS_LOG2-1:0]), .dout(gpr_bank_id[GPR_BANKS_LOG2-1:0]));
// GPR Write Enables for power savings
assign gpr_wr_en[31:1] = (w0v[31:1] | w1v[31:1] | w2v[31:1]);
for (genvar i=0; i<GPR_BANKS; i++) begin: gpr_banks
assign gpr_bank_wr_en[i][31:1] = gpr_wr_en[31:1] & {31{gpr_bank_id[GPR_BANKS_LOG2-1:0] == i}};
for ( genvar j=1; j<32; j++ ) begin : gpr
rvdffe #(32) gprff (.*, .en(gpr_bank_wr_en[i][j]), .din(gpr_in[j][31:0]), .dout(gpr_out[i][j][31:0]));
rvdffe #(32) gprff (.*, .en(gpr_bank_wr_en[i][j]), .din(gpr_in[j][31:0]), .dout(gpr_out[i][j][31:0]));
end : gpr
end: gpr_banks
// the read out
always_comb begin
rd0[31:0] = 32'b0;
rd1[31:0] = 32'b0;
rd2[31:0] = 32'b0;
rd3[31:0] = 32'b0;
rd3[31:0] = 32'b0;
w0v[31:1] = 31'b0;
w1v[31:1] = 31'b0;
w2v[31:1] = 31'b0;
gpr_in[31:1] = '0;
// GPR Read logic
for (int i=0; i<GPR_BANKS; i++) begin
for (int j=1; j<32; j++ ) begin
rd0[31:0] |= ({32{rden0 & (raddr0[4:0]== 5'(j)) & (gpr_bank_id[GPR_BANKS_LOG2-1:0] == 1'(i))}} & gpr_out[i][j][31:0]);
rd1[31:0] |= ({32{rden1 & (raddr1[4:0]== 5'(j)) & (gpr_bank_id[GPR_BANKS_LOG2-1:0] == 1'(i))}} & gpr_out[i][j][31:0]);
rd2[31:0] |= ({32{rden2 & (raddr2[4:0]== 5'(j)) & (gpr_bank_id[GPR_BANKS_LOG2-1:0] == 1'(i))}} & gpr_out[i][j][31:0]);
rd3[31:0] |= ({32{rden3 & (raddr3[4:0]== 5'(j)) & (gpr_bank_id[GPR_BANKS_LOG2-1:0] == 1'(i))}} & gpr_out[i][j][31:0]);
rd3[31:0] |= ({32{rden3 & (raddr3[4:0]== 5'(j)) & (gpr_bank_id[GPR_BANKS_LOG2-1:0] == 1'(i))}} & gpr_out[i][j][31:0]);
end
end
end
// GPR Write logic
for (int j=1; j<32; j++ ) begin
w0v[j] = wen0 & (waddr0[4:0]== 5'(j) );
w1v[j] = wen1 & (waddr1[4:0]== 5'(j) );
w2v[j] = wen2 & (waddr2[4:0]== 5'(j) );
gpr_in[j] = ({32{w0v[j]}} & wd0[31:0]) |
({32{w1v[j]}} & wd1[31:0]) |
({32{w2v[j]}} & wd2[31:0]);
end
gpr_in[j] = ({32{w0v[j]}} & wd0[31:0]) |
({32{w1v[j]}} & wd1[31:0]) |
({32{w2v[j]}} & wd2[31:0]);
end
end // always_comb begin
`ifdef ASSERT_ON
// asserting that no 2 ports will write to the same gpr simultaneously
assert_multiple_wen_to_same_gpr: assert #0 (~( ((w0v[31:1] == w1v[31:1]) & wen0 & wen1) | ((w0v[31:1] == w2v[31:1]) & wen0 & wen2) | ((w1v[31:1] == w2v[31:1]) & wen1 & wen2) ) );
`endif
endmodule

View File

@ -1,12 +1,12 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright 2019 Western Digital Corporation or its affiliates.
//
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//
// http://www.apache.org/licenses/LICENSE-2.0
//
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -25,25 +25,25 @@ module dec_ib_ctl
input logic [1:0] dbg_cmd_type, // dbg type
input logic [1:0] dbg_cmd_size, // 00 - 1B, 01 - 2B, 10 - 4B, 11 - reserved
input logic [31:0] dbg_cmd_addr, // expand to 31:0
input logic exu_flush_final, // all flush sources: primary/secondary alu's, trap
input logic dec_ib0_valid_eff_d, // effective valid taking decode into account
input logic dec_ib0_valid_eff_d, // effective valid taking decode into account
input logic dec_ib1_valid_eff_d,
input br_pkt_t i0_brp, // i0 branch packet from aligner
input br_pkt_t i1_brp,
input logic ifu_i0_pc4, // i0 is 4B inst else 2B
input logic ifu_i1_pc4,
input logic ifu_i0_valid, // i0 valid from ifu
input logic ifu_i1_valid,
input logic ifu_i0_icaf, // i0 instruction access fault
input logic ifu_i1_icaf,
input logic ifu_i0_icaf_f1, // i0 has access fault on second fetch group
input logic ifu_i1_icaf_f1,
input logic ifu_i1_icaf_f1,
input logic ifu_i0_perr, // i0 instruction parity error
input logic ifu_i1_perr,
input logic ifu_i0_sbecc, // i0 single-bit error
@ -59,17 +59,17 @@ module dec_ib_ctl
input logic dec_i0_decode_d, // i0 decode
input logic dec_i1_decode_d,
input logic rst_l, // test stuff
input logic clk,
output logic dec_ib3_valid_d, // ib3 valid
output logic dec_ib2_valid_d, // ib2 valid
output logic dec_ib1_valid_d, // ib1 valid
output logic dec_ib0_valid_d, // ib0 valid
output logic [31:0] dec_i0_instr_d, // i0 inst at decode
output logic [31:0] dec_i1_instr_d, // i1 inst at decode
@ -107,9 +107,9 @@ module dec_ib_ctl
);
`include "global.h"
logic flush_final;
logic [3:0] ibval_in, ibval;
logic [31:0] ib3_in, ib2_in, ib1_in, ib0_in;
@ -131,14 +131,14 @@ module dec_ib_ctl
logic shift_ib1_ib0, shift_ib2_ib1, shift_ib3_ib2;
logic shift_ib2_ib0;
logic shift_ib3_ib1;
logic ifu_i0_val, ifu_i1_val;
logic debug_valid;
logic [4:0] dreg;
logic [11:0] dcsr;
logic [31:0] ib0_debug_in;
// logic debug_read_mem;
// logic debug_write_mem;
logic debug_read;
@ -147,10 +147,10 @@ module dec_ib_ctl
logic debug_write_gpr;
logic debug_read_csr;
logic debug_write_csr;
rvdff #(1) flush_upperff (.*, .clk(free_clk), .din(exu_flush_final), .dout(flush_final));
rvdff #(1) flush_upperff (.*, .clk(free_clk), .din(exu_flush_final), .dout(flush_final));
logic [3:0] ibvalid;
@ -158,15 +158,15 @@ module dec_ib_ctl
logic [3:1] i1_wen;
logic [3:0] shift_ibval;
logic [3:0] ibwrite;
assign ibvalid[3:0] = ibval[3:0] | i0_wen[3:0] | {i1_wen[3:1],1'b0};
assign ibval_in[3:0] = (({4{shift0}} & ibvalid[3:0]) |
({4{shift1}} & {1'b0, ibvalid[3:1]}) |
({4{shift2}} & {2'b0, ibvalid[3:2]})) & ~{4{flush_final}};
rvdff #(4) ibvalff (.*, .clk(active_clk), .din(ibval_in[3:0]), .dout(ibval[3:0]));
// only valid if there is room
if (DEC_INSTBUF_DEPTH==4) begin
assign ifu_i0_val = ifu_i0_valid & ~ibval[3] & ~flush_final;
@ -176,58 +176,58 @@ module dec_ib_ctl
assign ifu_i0_val = ifu_i0_valid & (~dec_ib0_valid_eff_d | ~dec_ib1_valid_eff_d) & ~flush_final;
assign ifu_i1_val = ifu_i1_valid & (~dec_ib0_valid_eff_d & ~dec_ib1_valid_eff_d) & ~flush_final;
end
assign i0_wen[0] = ~ibval[0] & (ifu_i0_val | debug_valid);
assign i0_wen[1] = ibval[0] & ~ibval[1] & ifu_i0_val;
assign i0_wen[2] = ibval[1] & ~ibval[2] & ifu_i0_val;
assign i0_wen[3] = ibval[2] & ~ibval[3] & ifu_i0_val;
assign i1_wen[1] = ~ibval[0] & ifu_i1_val;
assign i1_wen[2] = ibval[0] & ~ibval[1] & ifu_i1_val;
assign i1_wen[3] = ibval[1] & ~ibval[2] & ifu_i1_val;
// start trace
if (DEC_INSTBUF_DEPTH==4) begin
assign cinst3_in[15:0] = ({16{write_i0_ib3}} & ifu_i0_cinst[15:0]) |
({16{write_i1_ib3}} & ifu_i1_cinst[15:0]);
rvdffe #(16) cinst3ff (.*, .en(ibwrite[3]), .din(cinst3_in[15:0]), .dout(cinst3[15:0]));
assign cinst2_in[15:0] = ({16{write_i0_ib2}} & ifu_i0_cinst[15:0]) |
({16{write_i1_ib2}} & ifu_i1_cinst[15:0]) |
({16{shift_ib3_ib2}} & cinst3[15:0]);
rvdffe #(16) cinst2ff (.*, .en(ibwrite[2]), .din(cinst2_in[15:0]), .dout(cinst2[15:0]));
end // if (DEC_INSTBUF_DEPTH==4)
else begin
assign cinst3 = '0;
assign cinst2 = '0;
end
assign cinst1_in[15:0] = ({16{write_i0_ib1}} & ifu_i0_cinst[15:0]) |
({16{write_i1_ib1}} & ifu_i1_cinst[15:0]) |
({16{shift_ib2_ib1}} & cinst2[15:0]) |
({16{shift_ib3_ib1}} & cinst3[15:0]);
rvdffe #(16) cinst1ff (.*, .en(ibwrite[1]), .din(cinst1_in[15:0]), .dout(cinst1[15:0]));
assign cinst0_in[15:0] = ({16{write_i0_ib0}} & ifu_i0_cinst[15:0]) |
({16{shift_ib1_ib0}} & cinst1[15:0]) |
({16{shift_ib2_ib0}} & cinst2[15:0]);
rvdffe #(16) cinst0ff (.*, .en(ibwrite[0]), .din(cinst0_in[15:0]), .dout(cinst0[15:0]));
assign dec_i0_cinst_d[15:0] = cinst0[15:0];
assign dec_i1_cinst_d[15:0] = cinst1[15:0];
assign dec_i1_cinst_d[15:0] = cinst1[15:0];
// end trace
// pc tracking
@ -238,97 +238,97 @@ module dec_ib_ctl
};
logic [36:0] ifu_i1_pcdata, ifu_i0_pcdata;
assign ifu_i1_pcdata[36:0] = { ifu_i1_icaf_f1, ifu_i1_dbecc, ifu_i1_sbecc, ifu_i1_perr, ifu_i1_icaf,
ifu_i1_pc[31:1], ifu_i1_pc4 };
assign ifu_i0_pcdata[36:0] = { ifu_i0_icaf_f1, ifu_i0_dbecc, ifu_i0_sbecc, ifu_i0_perr, ifu_i0_icaf,
assign ifu_i1_pcdata[36:0] = { ifu_i1_icaf_f1, ifu_i1_dbecc, ifu_i1_sbecc, ifu_i1_perr, ifu_i1_icaf,
ifu_i1_pc[31:1], ifu_i1_pc4 };
assign ifu_i0_pcdata[36:0] = { ifu_i0_icaf_f1, ifu_i0_dbecc, ifu_i0_sbecc, ifu_i0_perr, ifu_i0_icaf,
ifu_i0_pc[31:1], ifu_i0_pc4 };
if (DEC_INSTBUF_DEPTH==4) begin
assign pc3_in[36:0] = ({37{write_i0_ib3}} & ifu_i0_pcdata[36:0]) |
({37{write_i1_ib3}} & ifu_i1_pcdata[36:0]);
rvdffe #(37) pc3ff (.*, .en(ibwrite[3]), .din(pc3_in[36:0]), .dout(pc3[36:0]));
assign pc2_in[36:0] = ({37{write_i0_ib2}} & ifu_i0_pcdata[36:0]) |
({37{write_i1_ib2}} & ifu_i1_pcdata[36:0]) |
({37{shift_ib3_ib2}} & pc3[36:0]);
rvdffe #(37) pc2ff (.*, .en(ibwrite[2]), .din(pc2_in[36:0]), .dout(pc2[36:0]));
end // if (DEC_INSTBUF_DEPTH==4)
else begin
assign pc3 = '0;
assign pc2 = '0;
end
assign pc1_in[36:0] = ({37{write_i0_ib1}} & ifu_i0_pcdata[36:0]) |
({37{write_i1_ib1}} & ifu_i1_pcdata[36:0]) |
({37{shift_ib2_ib1}} & pc2[36:0]) |
({37{shift_ib3_ib1}} & pc3[36:0]);
rvdffe #(37) pc1ff (.*, .en(ibwrite[1]), .din(pc1_in[36:0]), .dout(pc1[36:0]));
assign pc0_in[36:0] = ({37{write_i0_ib0}} & ifu_i0_pcdata[36:0]) |
({37{shift_ib1_ib0}} & pc1[36:0]) |
({37{shift_ib2_ib0}} & pc2[36:0]);
rvdffe #(37) pc0ff (.*, .en(ibwrite[0]), .din(pc0_in[36:0]), .dout(pc0[36:0]));
assign dec_i0_icaf_f1_d = pc0[36]; // icaf's can only decode as i0
assign dec_i1_dbecc_d = pc1[35];
assign dec_i0_dbecc_d = pc0[35];
assign dec_i0_dbecc_d = pc0[35];
assign dec_i1_sbecc_d = pc1[34];
assign dec_i0_sbecc_d = pc0[34];
assign dec_i0_sbecc_d = pc0[34];
assign dec_i1_perr_d = pc1[33];
assign dec_i0_perr_d = pc0[33];
assign dec_i0_perr_d = pc0[33];
assign dec_i1_icaf_d = pc1[32];
assign dec_i0_icaf_d = pc0[32];
assign dec_i1_pc_d[31:1] = pc1[31:1];
assign dec_i0_icaf_d = pc0[32];
assign dec_i1_pc_d[31:1] = pc1[31:1];
assign dec_i0_pc_d[31:1] = pc0[31:1];
assign dec_i1_pc4_d = pc1[0];
assign dec_i1_pc4_d = pc1[0];
assign dec_i0_pc4_d = pc0[0];
// branch prediction
logic [$bits(br_pkt_t)-1:0] bp3_in,bp3,bp2_in,bp2,bp1_in,bp1,bp0_in,bp0;
if (DEC_INSTBUF_DEPTH==4) begin
if (DEC_INSTBUF_DEPTH==4) begin
assign bp3_in = ({$bits(br_pkt_t){write_i0_ib3}} & i0_brp) |
({$bits(br_pkt_t){write_i1_ib3}} & i1_brp);
rvdffe #($bits(br_pkt_t)) bp3ff (.*, .en(ibwrite[3]), .din(bp3_in), .dout(bp3));
assign bp2_in = ({$bits(br_pkt_t){write_i0_ib2}} & i0_brp) |
({$bits(br_pkt_t){write_i1_ib2}} & i1_brp) |
({$bits(br_pkt_t){shift_ib3_ib2}} & bp3);
rvdffe #($bits(br_pkt_t)) bp2ff (.*, .en(ibwrite[2]), .din(bp2_in), .dout(bp2));
end // if (DEC_INSTBUF_DEPTH==4)
else begin
assign bp3 = '0;
assign bp2 = '0;
end
assign bp1_in = ({$bits(br_pkt_t){write_i0_ib1}} & i0_brp) |
({$bits(br_pkt_t){write_i1_ib1}} & i1_brp) |
({$bits(br_pkt_t){shift_ib2_ib1}} & bp2) |
({$bits(br_pkt_t){shift_ib3_ib1}} & bp3);
rvdffe #($bits(br_pkt_t)) bp1ff (.*, .en(ibwrite[1]), .din(bp1_in), .dout(bp1));
assign bp0_in = ({$bits(br_pkt_t){write_i0_ib0}} & i0_brp) |
({$bits(br_pkt_t){shift_ib1_ib0}} & bp1) |
({$bits(br_pkt_t){shift_ib2_ib0}} & bp2);
rvdffe #($bits(br_pkt_t)) bp0ff (.*, .en(ibwrite[0]), .din(bp0_in), .dout(bp0));
// instruction buffers
@ -336,25 +336,25 @@ module dec_ib_ctl
if (DEC_INSTBUF_DEPTH==4) begin
assign ib3_in[31:0] = ({32{write_i0_ib3}} & ifu_i0_instr[31:0]) |
({32{write_i1_ib3}} & ifu_i1_instr[31:0]);
rvdffe #(32) ib3ff (.*, .en(ibwrite[3]), .din(ib3_in[31:0]), .dout(ib3[31:0]));
assign ib2_in[31:0] = ({32{write_i0_ib2}} & ifu_i0_instr[31:0]) |
({32{write_i1_ib2}} & ifu_i1_instr[31:0]) |
({32{shift_ib3_ib2}} & ib3[31:0]);
rvdffe #(32) ib2ff (.*, .en(ibwrite[2]), .din(ib2_in[31:0]), .dout(ib2[31:0]));
end // if (DEC_INSTBUF_DEPTH==4)
else begin
assign ib3 = '0;
assign ib2 = '0;
end
assign ib1_in[31:0] = ({32{write_i0_ib1}} & ifu_i0_instr[31:0]) |
({32{write_i1_ib1}} & ifu_i1_instr[31:0]) |
({32{shift_ib2_ib1}} & ib2[31:0]) |
({32{shift_ib3_ib1}} & ib3[31:0]);
rvdffe #(32) ib1ff (.*, .en(ibwrite[1]), .din(ib1_in[31:0]), .dout(ib1[31:0]));
@ -375,21 +375,21 @@ module dec_ib_ctl
// put write data on rs1
// write -> csrrw %x0, %csr, %x0 {csr[11:0],00000001000001110011}
// abstract memory command not done here
assign debug_valid = dbg_cmd_valid & (dbg_cmd_type[1:0] != 2'h2);
// abstract memory command not done here
assign debug_valid = dbg_cmd_valid & (dbg_cmd_type[1:0] != 2'h2);
assign debug_read = debug_valid & ~dbg_cmd_write;
assign debug_write = debug_valid & dbg_cmd_write;
assign debug_write = debug_valid & dbg_cmd_write;
assign debug_read_gpr = debug_read & (dbg_cmd_type[1:0]==2'h0);
assign debug_write_gpr = debug_write & (dbg_cmd_type[1:0]==2'h0);
assign debug_write_gpr = debug_write & (dbg_cmd_type[1:0]==2'h0);
assign debug_read_csr = debug_read & (dbg_cmd_type[1:0]==2'h1);
assign debug_write_csr = debug_write & (dbg_cmd_type[1:0]==2'h1);
assign dreg[4:0] = dbg_cmd_addr[4:0];
assign dcsr[11:0] = dbg_cmd_addr[11:0];
assign dreg[4:0] = dbg_cmd_addr[4:0];
assign dcsr[11:0] = dbg_cmd_addr[11:0];
assign ib0_debug_in[31:0] = ({32{debug_read_gpr}} & {12'b000000000000,dreg[4:0],15'b110000000110011}) |
({32{debug_write_gpr}} & {20'b00000000000000000110,dreg[4:0],7'b0110011}) |
@ -404,38 +404,38 @@ module dec_ib_ctl
// special fence csr for use only in debug mode
logic debug_fence_in;
assign debug_fence_in = debug_write_csr & (dcsr[11:0] == 12'h7c4);
rvdff #(1) debug_fence_ff (.*, .clk(free_clk), .din(debug_fence_in), .dout(dec_debug_fence_d));
rvdff #(1) debug_fence_ff (.*, .clk(free_clk), .din(debug_fence_in), .dout(dec_debug_fence_d));
assign ib0_in[31:0] = ({32{write_i0_ib0}} & ((debug_valid) ? ib0_debug_in[31:0] : ifu_i0_instr[31:0])) |
({32{shift_ib1_ib0}} & ib1[31:0]) |
({32{shift_ib2_ib0}} & ib2[31:0]);
rvdffe #(32) ib0ff (.*, .en(ibwrite[0]), .din(ib0_in[31:0]), .dout(ib0[31:0]));
assign dec_ib3_valid_d = ibval[3];
assign dec_ib2_valid_d = ibval[2];
assign dec_ib1_valid_d = ibval[1];
assign dec_ib0_valid_d = ibval[0];
assign dec_ib0_valid_d = ibval[0];
assign dec_i0_instr_d[31:0] = ib0[31:0];
assign dec_i1_instr_d[31:0] = ib1[31:0];
assign dec_i1_instr_d[31:0] = ib1[31:0];
assign dec_i0_brp = bp0;
assign dec_i1_brp = bp1;
assign dec_i1_brp = bp1;
assign shift1 = dec_i0_decode_d & ~dec_i1_decode_d;
assign shift2 = dec_i0_decode_d & dec_i1_decode_d;
assign shift0 = ~dec_i0_decode_d;
// compute shifted ib valids to determine where to write
assign shift_ibval[3:0] = ({4{shift1}} & {1'b0, ibval[3:1] }) |
({4{shift2}} & {2'b0, ibval[3:2]}) |
@ -445,7 +445,7 @@ module dec_ib_ctl
assign write_i0_ib1 = shift_ibval[0] & ~shift_ibval[1] & ifu_i0_val;
assign write_i0_ib2 = shift_ibval[1] & ~shift_ibval[2] & ifu_i0_val;
assign write_i0_ib3 = shift_ibval[2] & ~shift_ibval[3] & ifu_i0_val;
assign write_i1_ib1 = ~shift_ibval[0] & ifu_i1_val;
assign write_i1_ib2 = shift_ibval[0] & ~shift_ibval[1] & ifu_i1_val;
assign write_i1_ib3 = shift_ibval[1] & ~shift_ibval[2] & ifu_i1_val;
@ -453,11 +453,11 @@ module dec_ib_ctl
assign shift_ib1_ib0 = shift1 & ibval[1];
assign shift_ib2_ib1 = shift1 & ibval[2];
assign shift_ib3_ib2 = shift1 & ibval[3];
assign shift_ib3_ib2 = shift1 & ibval[3];
assign shift_ib2_ib0 = shift2 & ibval[2];
assign shift_ib3_ib1 = shift2 & ibval[3];
endmodule

File diff suppressed because it is too large Load Diff

View File

@ -1,12 +1,12 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright 2019 Western Digital Corporation or its affiliates.
//
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//
// http://www.apache.org/licenses/LICENSE-2.0
//
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -16,13 +16,13 @@
//********************************************************************************
// $Id$
//
//
// Owner:
//
// Owner:
// Function: DEC Trigger Logic
// Comments:
//
//********************************************************************************
module dec_trigger
module dec_trigger
import swerv_types::*;
(
input logic clk,
@ -30,23 +30,23 @@ module dec_trigger
input trigger_pkt_t [3:0] trigger_pkt_any, // Packet from tlu. 'select':0-pc,1-Opcode 'Execute' needs to be set for dec triggers to fire. 'match'-1 do mask, 0: full match
input logic [31:1] dec_i0_pc_d, // i0 pc
input logic [31:1] dec_i1_pc_d, // i1 pc
input logic [31:1] dec_i1_pc_d, // i1 pc
output logic [3:0] dec_i0_trigger_match_d,
output logic [3:0] dec_i1_trigger_match_d
output logic [3:0] dec_i1_trigger_match_d
);
logic [3:0][31:0] dec_i0_match_data;
logic [3:0] dec_i0_trigger_data_match;
logic [3:0][31:0] dec_i1_match_data;
logic [3:0] dec_i1_trigger_data_match;
for (genvar i=0; i<4; i++) begin
assign dec_i0_match_data[i][31:0] = ({32{~trigger_pkt_any[i].select & trigger_pkt_any[i].execute}} & {dec_i0_pc_d[31:1], trigger_pkt_any[i].tdata2[0]}); // select=0; do a PC match
assign dec_i1_match_data[i][31:0] = ({32{~trigger_pkt_any[i].select & trigger_pkt_any[i].execute}} & {dec_i1_pc_d[31:1], trigger_pkt_any[i].tdata2[0]} ); // select=0; do a PC match
rvmaskandmatch trigger_i0_match (.mask(trigger_pkt_any[i].tdata2[31:0]), .data(dec_i0_match_data[i][31:0]), .masken(trigger_pkt_any[i].match), .match(dec_i0_trigger_data_match[i]));
rvmaskandmatch trigger_i0_match (.mask(trigger_pkt_any[i].tdata2[31:0]), .data(dec_i0_match_data[i][31:0]), .masken(trigger_pkt_any[i].match), .match(dec_i0_trigger_data_match[i]));
rvmaskandmatch trigger_i1_match (.mask(trigger_pkt_any[i].tdata2[31:0]), .data(dec_i1_match_data[i][31:0]), .masken(trigger_pkt_any[i].match), .match(dec_i1_trigger_data_match[i]));
assign dec_i0_trigger_match_d[i] = trigger_pkt_any[i].execute & trigger_pkt_any[i].m & dec_i0_trigger_data_match[i];

View File

@ -3,21 +3,21 @@
add = [0000000..........000.....0110011]
addi = [.................000.....0010011]
sub = [0100000..........000.....0110011]
and = [0000000..........111.....0110011]
andi = [.................111.....0010011]
or = [0000000..........110.....0110011]
ori = [.................110.....0010011]
xor = [0000000..........100.....0110011]
xori = [.................100.....0010011]
sll = [0000000..........001.....0110011]
slli = [0000000..........001.....0010011]
sra = [0100000..........101.....0110011]
srai = [0100000..........101.....0010011]
@ -26,30 +26,30 @@ srli = [0000000..........101.....0010011]
lui = [.........................0110111]
auipc= [.........................0010111]
slt = [0000000..........010.....0110011]
sltu = [0000000..........011.....0110011]
slti = [.................010.....0010011]
sltiu= [.................011.....0010011]
beq = [.................000.....1100011]
bne = [.................001.....1100011]
bge = [.................101.....1100011]
blt = [.................100.....1100011]
bgeu = [.................111.....1100011]
bltu = [.................110.....1100011]
jal = [.........................1101111]
jalr = [.................000.....1100111]
lb = [.................000.....0000011]
lh = [.................001.....0000011]
lw = [.................010.....0000011]
sb = [.................000.....0100011]
sh = [.................001.....0100011]
sw = [.................010.....0100011]
lbu = [.................100.....0000011]
lhu = [.................101.....0000011]
@ -117,41 +117,41 @@ rem = [0000001..........110.....0110011]
remu = [0000001..........111.....0110011]
.input
.input
rv32i = {
i[31]
i[30]
i[29]
i[28]
i[27]
i[26]
i[25]
i[24]
i[23]
i[22]
i[21]
i[20]
i[19]
i[18]
i[17]
i[16]
i[15]
i[14]
i[13]
i[12]
i[11]
i[10]
i[9]
i[8]
i[7]
i[6]
i[5]
i[4]
i[3]
i[2]
i[1]
i[0]
i[31]
i[30]
i[29]
i[28]
i[27]
i[26]
i[25]
i[24]
i[23]
i[22]
i[21]
i[20]
i[19]
i[18]
i[17]
i[16]
i[15]
i[14]
i[13]
i[12]
i[11]
i[10]
i[9]
i[8]
i[7]
i[6]
i[5]
i[4]
i[3]
i[2]
i[1]
i[0]
}
@ -188,7 +188,7 @@ rv32i = {
by
half
word
csr_read
csr_read
csr_clr
csr_set
csr_write
@ -294,22 +294,22 @@ rv32i[csrrc_ro] = { alu rd csr_read lor }
# put csr on rs2 and make rs1 0's into alu. Save rs1 for csr_clr later
rv32i[csrrc_rw{0-4}] = { alu rd csr_read rs1 csr_clr lor presync postsync }
rv32i[csrrci_ro] = { alu rd csr_read lor }
rv32i[csrrci_rw{0-4}] = { alu rd csr_read rs1 csr_clr csr_imm lor presync postsync }
rv32i[csrrs_ro] = { alu rd csr_read lor }
rv32i[csrrs_rw{0-4}] = { alu rd csr_read rs1 csr_set lor presync postsync }
rv32i[csrrsi_ro] = { alu rd csr_read lor }
rv32i[csrrsi_rw{0-4}] = { alu rd csr_read rs1 csr_set csr_imm lor presync postsync }
rv32i[csrrw{0-4}] = { alu rd csr_read rs1 csr_write lor presync postsync }
rv32i[csrrwi{0-4}] = { alu rd csr_read rs1 csr_write csr_imm lor presync postsync }
# optimize csr write only - pipelined

View File

@ -1,12 +1,12 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright 2019 Western Digital Corporation or its affiliates.
//
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//
// http://www.apache.org/licenses/LICENSE-2.0
//
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -17,7 +17,7 @@
// $Id$
//
// Function: Top level SWERV core file
// Comments:
// Comments:
//
//********************************************************************************
@ -28,7 +28,7 @@ module dma_ctrl (
input logic dma_bus_clk_en, // slave bus clock enable
input logic clk_override,
// AXI signals
// AXI signals
// AXI Write Channels
input logic dma_axi_awvalid,
output logic dma_axi_awready,
@ -39,12 +39,12 @@ module dma_ctrl (
input logic [7:0] dma_axi_awlen,
input logic [1:0] dma_axi_awburst,
input logic dma_axi_wvalid,
input logic dma_axi_wvalid,
output logic dma_axi_wready,
input logic [63:0] dma_axi_wdata,
input logic [7:0] dma_axi_wstrb,
input logic dma_axi_wlast,
output logic dma_axi_bvalid,
input logic dma_axi_bready,
output logic [1:0] dma_axi_bresp,
@ -54,7 +54,7 @@ module dma_ctrl (
input logic dma_axi_arvalid,
output logic dma_axi_arready,
input logic [`RV_DMA_BUS_TAG-1:0] dma_axi_arid,
input logic [31:0] dma_axi_araddr,
input logic [31:0] dma_axi_araddr,
input logic [2:0] dma_axi_arsize,
input logic [2:0] dma_axi_arprot,
input logic [7:0] dma_axi_arlen,
@ -67,13 +67,13 @@ module dma_ctrl (
output logic [1:0] dma_axi_rresp,
output logic dma_axi_rlast,
output logic dma_slv_algn_err,
output logic dma_slv_algn_err,
// Debug signals
input logic [31:0] dbg_cmd_addr,
input logic [31:0] dbg_cmd_wrdata,
input logic dbg_cmd_valid,
input logic dbg_cmd_valid,
input logic dbg_cmd_write, // 1: write command, 0: read_command
input logic [1:0] dbg_cmd_type, // 0:gpr 1:csr 2: memory
input logic [1:0] dbg_cmd_type, // 0:gpr 1:csr 2: memory
input logic [1:0] dbg_cmd_size, // size of the abstract mem access debug command
input logic dbg_dma_bubble, // Debug needs a bubble to send a valid
@ -82,7 +82,7 @@ module dma_ctrl (
output logic dma_dbg_cmd_done,
output logic dma_dbg_cmd_fail,
output logic [31:0] dma_dbg_rddata,
// Core side signals
output logic dma_dccm_req, // DMA dccm request (only one of dccm/iccm will be set)
output logic dma_iccm_req, // DMA iccm request
@ -104,16 +104,16 @@ module dma_ctrl (
input logic iccm_ready, // iccm ready to accept DMA request
input logic dec_tlu_stall_dma, // stall dma accesses, tlu is attempting to enter halt/debug mode
input logic [2:0] dec_tlu_dma_qos_prty, // DMA QoS priority coming from MFDC [18:15]
input logic scan_mode
input logic scan_mode
);
`include "global.h"
localparam DEPTH = DMA_BUF_DEPTH;
localparam DEPTH_PTR = $clog2(DEPTH);
localparam NACK_COUNT = 7;
logic [DEPTH-1:0] fifo_valid;
logic [DEPTH-1:0][1:0] fifo_error;
logic [DEPTH-1:0] fifo_dccm_valid;
@ -132,7 +132,7 @@ module dma_ctrl (
logic [DEPTH-1:0] fifo_dbg;
logic [DEPTH-1:0][63:0] fifo_data;
logic [DEPTH-1:0][DMA_BUS_TAG-1:0] fifo_tag;
logic [DEPTH-1:0] fifo_cmd_en;
logic [DEPTH-1:0] fifo_valid_en;
logic [DEPTH-1:0] fifo_data_en;
@ -152,7 +152,7 @@ module dma_ctrl (
logic fifo_dbg_in;
logic [31:0] fifo_addr_in;
logic [2:0] fifo_sz_in;
logic [DEPTH_PTR-1:0] RspPtr, PrevRspPtr, NxtRspPtr;
logic [DEPTH_PTR-1:0] WrPtr, NxtWrPtr;
logic [DEPTH_PTR-1:0] RdPtr, NxtRdPtr;
@ -164,7 +164,7 @@ module dma_ctrl (
logic fifo_full, fifo_full_spec, fifo_empty;
logic dma_address_error, dma_alignment_error;
logic [3:0] num_fifo_vld;
logic [3:0] num_fifo_vld;
logic dma_mem_req;
logic dma_addr_in_dccm;
logic dma_addr_in_iccm;
@ -172,7 +172,7 @@ module dma_ctrl (
logic dma_addr_in_pic_region_nc;
logic dma_addr_in_dccm_region_nc;
logic dma_addr_in_iccm_region_nc;
logic [2:0] dma_nack_count_csr;
logic [2:0] dma_nack_count, dma_nack_count_d;
@ -181,7 +181,7 @@ module dma_ctrl (
logic dma_buffer_c1_clk;
logic dma_free_clk;
logic dma_bus_clk;
logic wrbuf_en, wrbuf_data_en;
logic wrbuf_cmd_sent, wrbuf_rst, wrbuf_data_rst;
@ -193,7 +193,7 @@ module dma_ctrl (
logic [31:0] wrbuf_addr;
logic [63:0] wrbuf_data;
logic [7:0] wrbuf_byteen;
logic rdbuf_en;
logic rdbuf_cmd_sent, rdbuf_rst;
logic rdbuf_vld;
@ -210,7 +210,7 @@ module dma_ctrl (
logic [2:0] axi_mstr_size;
logic [63:0] axi_mstr_wdata;
logic [7:0] axi_mstr_wstrb;
logic axi_mstr_prty_in, axi_mstr_prty_en;
logic axi_mstr_priority;
logic axi_mstr_sel;
@ -222,7 +222,7 @@ module dma_ctrl (
logic [DMA_BUS_TAG-1:0] axi_slv_tag;
logic [1:0] axi_slv_error;
logic [63:0] axi_slv_rdata;
logic dma_bus_clk_en_q;
logic fifo_full_spec_bus;
logic dbg_dma_bubble_bus;
@ -238,14 +238,14 @@ module dma_ctrl (
assign fifo_posted_write_in = axi_mstr_valid & axi_mstr_posted_write;
assign fifo_dbg_in = dbg_cmd_valid;
//assign fifo_error_in[1:0] = dccm_dma_rvalid ? {1'b0,dccm_dma_ecc_error} : iccm_dma_rvalid ? {1'b0,iccm_dma_ecc_error} : {(dma_address_error | dma_alignment_error | dma_dbg_cmd_error_in), dma_alignment_error};
//assign fifo_data_in[63:0] = dccm_dma_rvalid ? dccm_dma_rdata[63:0] : (iccm_dma_rvalid ? iccm_dma_rdata[63:0] :
//assign fifo_data_in[63:0] = dccm_dma_rvalid ? dccm_dma_rdata[63:0] : (iccm_dma_rvalid ? iccm_dma_rdata[63:0] :
// (dbg_cmd_valid ? {2{dbg_cmd_wrdata[31:0]}} : axi_mstr_wdata[63:0]));
for (genvar i=0 ;i<DEPTH; i++) begin: GenFifo
assign fifo_valid_en[i] = axi_mstr_valid & (i == WrPtr[DEPTH_PTR-1:0]);
assign fifo_cmd_en[i] = ((axi_mstr_valid & dma_bus_clk_en) | (dbg_cmd_valid & dbg_cmd_type[1])) &
assign fifo_cmd_en[i] = ((axi_mstr_valid & dma_bus_clk_en) | (dbg_cmd_valid & dbg_cmd_type[1])) &
(i == WrPtr[DEPTH_PTR-1:0]);
assign fifo_data_en[i] = (((axi_mstr_valid & (axi_mstr_write | dma_address_error | dma_alignment_error) & dma_bus_clk_en) |
assign fifo_data_en[i] = (((axi_mstr_valid & (axi_mstr_write | dma_address_error | dma_alignment_error) & dma_bus_clk_en) |
(dbg_cmd_valid & dbg_cmd_type[1] & dbg_cmd_write)) & (i == WrPtr[DEPTH_PTR-1:0])) |
((dccm_dma_rvalid & (i == RdPtr_Q3[DEPTH_PTR-1:0]))| (iccm_dma_rvalid & (i == RdPtr_Q2[DEPTH_PTR-1:0])));
assign fifo_data_bus_en[i] = (fifo_data_en[i] | fifo_data_valid[i]) & dma_bus_clk_en;
@ -256,14 +256,14 @@ module dma_ctrl (
((dccm_dma_rvalid & (i == RdPtr_Q3[DEPTH_PTR-1:0])) | (iccm_dma_rvalid & (i == RdPtr_Q2[DEPTH_PTR-1:0])));
assign fifo_done_bus_en[i] = (fifo_done_en[i] | fifo_done[i]) & dma_bus_clk_en;
//assign fifo_rsp_done_en[i] = fifo_valid[i] & ((axi_slv_sent & dma_bus_clk_en) | dma_dbg_cmd_done) & (i == RspPtr[DEPTH_PTR-1:0]);
//assign fifo_reset[i] = (fifo_done[i] | fifo_done_en[i]) & (fifo_rsp_done[i] | fifo_rsp_done_en[i]);
assign fifo_reset[i] = ((axi_slv_sent & dma_bus_clk_en) | dma_dbg_cmd_done) & (i == RspPtr[DEPTH_PTR-1:0]);
//assign fifo_reset[i] = (fifo_done[i] | fifo_done_en[i]) & (fifo_rsp_done[i] | fifo_rsp_done_en[i]);
assign fifo_reset[i] = ((axi_slv_sent & dma_bus_clk_en) | dma_dbg_cmd_done) & (i == RspPtr[DEPTH_PTR-1:0]);
assign fifo_error_in[i] = (dccm_dma_rvalid & (i == RdPtr_Q3[DEPTH_PTR-1:0])) ? {1'b0,dccm_dma_ecc_error} : (iccm_dma_rvalid & (i == RdPtr_Q2[DEPTH_PTR-1:0])) ? {1'b0,iccm_dma_ecc_error} :
{(dma_address_error | dma_alignment_error | dma_dbg_cmd_error_in), dma_alignment_error};
assign fifo_data_in[i] = (fifo_error_en[i] & (|fifo_error_in[i])) ? (fifo_cmd_en[i] ? {32'b0,axi_mstr_addr[31:0]} : {32'b0,fifo_addr[i]}) :
((dccm_dma_rvalid & (i == RdPtr_Q3[DEPTH_PTR-1:0])) ? dccm_dma_rdata[63:0] : (iccm_dma_rvalid & (i == RdPtr_Q2[DEPTH_PTR-1:0])) ? iccm_dma_rdata[63:0] :
assign fifo_data_in[i] = (fifo_error_en[i] & (|fifo_error_in[i])) ? (fifo_cmd_en[i] ? {32'b0,axi_mstr_addr[31:0]} : {32'b0,fifo_addr[i]}) :
((dccm_dma_rvalid & (i == RdPtr_Q3[DEPTH_PTR-1:0])) ? dccm_dma_rdata[63:0] : (iccm_dma_rvalid & (i == RdPtr_Q2[DEPTH_PTR-1:0])) ? iccm_dma_rdata[63:0] :
(dbg_cmd_valid ? {2{dbg_cmd_wrdata[31:0]}} : axi_mstr_wdata[63:0]));
rvdffsc #(1) fifo_valid_dff (.din(1'b1), .dout(fifo_valid[i]), .en(fifo_cmd_en[i]), .clear(fifo_reset[i]), .clk(dma_free_clk), .*);
rvdffsc #(2) fifo_error_dff (.din(fifo_error_in[i]), .dout(fifo_error[i]), .en(fifo_error_en[i]), .clear(fifo_reset[i]), .clk(dma_free_clk), .*);
rvdffsc #(1) fifo_error_bus_dff (.din(1'b1), .dout(fifo_error_bus[i]), .en(fifo_error_bus_en[i]), .clear(fifo_reset[i]), .clk(dma_free_clk), .*);
@ -288,18 +288,18 @@ module dma_ctrl (
assign NxtWrPtr[DEPTH_PTR-1:0] = WrPtr[DEPTH_PTR-1:0] + 1'b1;
assign NxtRdPtr[DEPTH_PTR-1:0] = RdPtr[DEPTH_PTR-1:0] + 1'b1;
assign NxtRspPtr[DEPTH_PTR-1:0] = RspPtr[DEPTH_PTR-1:0] + 1'b1;
// Don't increment the ptr for posted writes if 1)fifo error (it will increment only with response) 2) response done (this is the full case)
//assign RspPtr[DEPTH_PTR-1:0] = (dma_dbg_cmd_done_q | axi_slv_sent_q) ? (PrevRspPtr[DEPTH_PTR-1:0] + 1'b1) : PrevRspPtr[DEPTH_PTR-1:0];
//assign RspPtr[DEPTH_PTR-1:0] = (dma_dbg_cmd_done_q | axi_slv_sent_q |
//assign RspPtr[DEPTH_PTR-1:0] = (dma_dbg_cmd_done_q | axi_slv_sent_q |
// (fifo_valid[PrevRspPtr] & fifo_write[PrevRspPtr] & fifo_posted_write[PrevRspPtr] & ~(|fifo_error[PrevRspPtr]) & ~fifo_rsp_done[PrevRspPtr])) ? (PrevRspPtr[DEPTH_PTR-1:0] + 1'b1) : PrevRspPtr[DEPTH_PTR-1:0];
assign WrPtrEn = |fifo_cmd_en[DEPTH-1:0];
assign RdPtrEn = (dma_dccm_req | dma_iccm_req) | ((|fifo_error[RdPtr]) & ~fifo_done[RdPtr]);
//assign RdPtrEn = |(fifo_done_en[DEPTH-1:0] & ~fifo_done[DEPTH-1:0]);
assign RspPtrEn = (dma_dbg_cmd_done | (axi_slv_sent & dma_bus_clk_en));
//assign RspPtrEn = dma_bus_clk_en | dma_dbg_cmd_done_q;
rvdffs #(DEPTH_PTR) WrPtr_dff(.din(NxtWrPtr[DEPTH_PTR-1:0]), .dout(WrPtr[DEPTH_PTR-1:0]), .en(WrPtrEn), .clk(dma_free_clk), .*);
rvdffs #(DEPTH_PTR) RdPtr_dff(.din(NxtRdPtr[DEPTH_PTR-1:0]), .dout(RdPtr[DEPTH_PTR-1:0]), .en(RdPtrEn), .clk(dma_free_clk), .*);
rvdffs #(DEPTH_PTR) RspPtr_dff(.din(NxtRspPtr[DEPTH_PTR-1:0]), .dout(RspPtr[DEPTH_PTR-1:0]), .en(RspPtrEn), .clk(dma_free_clk), .*);
@ -311,7 +311,7 @@ module dma_ctrl (
// Miscellaneous signals
assign fifo_full = fifo_full_spec_bus;
always_comb begin
num_fifo_vld[3:0] = 4'b0;
for (int i=0; i<DEPTH; i++) begin
@ -319,12 +319,12 @@ module dma_ctrl (
end
end
assign fifo_full_spec = ((num_fifo_vld[3:0] == DEPTH) & ~(|fifo_reset[DEPTH-1:0]));
assign dma_fifo_ready = ~(fifo_full | dbg_dma_bubble_bus | dec_tlu_stall_dma_bus);
// Error logic
assign dma_address_error = axi_mstr_valid & (~(dma_addr_in_dccm | dma_addr_in_iccm)); // request not for ICCM or DCCM
assign dma_alignment_error = axi_mstr_valid & ~dma_address_error &
assign dma_alignment_error = axi_mstr_valid & ~dma_address_error &
(((axi_mstr_size[2:0] == 3'h1) & (axi_mstr_addr[0] | (axi_mstr_write & (axi_mstr_wstrb[axi_mstr_addr[2:0]+:2] != 2'b11)))) | // HW size but unaligned
((axi_mstr_size[2:0] == 3'h2) & ((|axi_mstr_addr[1:0]) | (axi_mstr_write & (axi_mstr_wstrb[axi_mstr_addr[2:0]+:4] != 4'hf)))) | // W size but unaligned
((axi_mstr_size[2:0] == 3'h3) & ((|axi_mstr_addr[2:0]) | (axi_mstr_write & (axi_mstr_wstrb[7:0] != 8'hff)))) | // DW size but unaligned
@ -337,23 +337,23 @@ module dma_ctrl (
assign dma_dbg_rddata[31:0] = fifo_addr[RspPtr][2] ? fifo_data[RspPtr][63:32] : fifo_data[RspPtr][31:0];
assign dma_dbg_cmd_fail = |fifo_error[RspPtr];
assign dma_dbg_cmd_error_in = dbg_cmd_valid & (dbg_cmd_type[1:0] == 2'b10) &
((~(dma_addr_in_dccm | dma_addr_in_iccm | dma_addr_in_pic)) | (dbg_cmd_size[1:0] != 2'b10)); // Only word accesses allowed
assign dma_dbg_cmd_error_in = dbg_cmd_valid & (dbg_cmd_type[1:0] == 2'b10) &
((~(dma_addr_in_dccm | dma_addr_in_iccm | dma_addr_in_pic)) | (dbg_cmd_size[1:0] != 2'b10)); // Only word accesses allowed
//(dma_addr_in_iccm & ~((dbg_cmd_size[1:0] == 2'b10) | (dbg_cmd_size[1:0] == 2'b11))));
// Block the decode if fifo full
assign dma_dccm_stall_any = dma_mem_req & fifo_dccm_valid[RdPtr] & (dma_nack_count >= dma_nack_count_csr);
assign dma_iccm_stall_any = dma_mem_req & fifo_iccm_valid[RdPtr] & (dma_nack_count >= dma_nack_count_csr);
// Used to indicate ready to debug
assign fifo_empty = ~(|(fifo_valid_en[DEPTH-1:0] | fifo_valid[DEPTH-1:0]) | axi_mstr_valid | axi_slv_sent_q); // We want RspPtr to settle before accepting debug command
// Nack counter, stall the lsu pipe if 7 nacks
assign dma_nack_count_csr[2:0] = dec_tlu_dma_qos_prty[2:0];
assign dma_nack_count_d[2:0] = (dma_nack_count[2:0] >= dma_nack_count_csr[2:0]) ? ({3{~(dma_dccm_req | dma_iccm_req)}} & dma_nack_count[2:0]) :
assign dma_nack_count_d[2:0] = (dma_nack_count[2:0] >= dma_nack_count_csr[2:0]) ? ({3{~(dma_dccm_req | dma_iccm_req)}} & dma_nack_count[2:0]) :
(dma_mem_req & ~(dma_dccm_req | dma_iccm_req)) ? (dma_nack_count[2:0] + 1'b1) : 3'b0;
rvdffs #(3) nack_count_dff(.din(dma_nack_count_d[2:0]), .dout(dma_nack_count[2:0]), .en(dma_mem_req), .clk(dma_free_clk), .*);
// Core outputs
@ -372,7 +372,7 @@ module dma_ctrl (
.in_range(dma_addr_in_dccm),
.in_region(dma_addr_in_dccm_region_nc)
);
// Address check iccm
`ifdef RV_ICCM_ENABLE
rvrangecheck #(.CCM_SADR(`RV_ICCM_SADR),
@ -385,7 +385,7 @@ module dma_ctrl (
assign dma_addr_in_iccm = '0;
assign dma_addr_in_iccm_region_nc = '0;
`endif
// PIC memory address check
rvrangecheck #(.CCM_SADR(`RV_PIC_BASE_ADDR),
.CCM_SIZE(`RV_PIC_SIZE)) addr_pic_rangecheck (
@ -408,14 +408,14 @@ module dma_ctrl (
rvoclkhdr dma_buffer_c1cgc ( .en(dma_buffer_c1_clken), .l1clk(dma_buffer_c1_clk), .* );
rvoclkhdr dma_free_cgc (.en(dma_free_clken), .l1clk(dma_free_clk), .*);
rvclkhdr dma_bus_cgc (.en(dma_bus_clk_en), .l1clk(dma_bus_clk), .*);
// Write channel buffer
assign wrbuf_en = dma_axi_awvalid & dma_axi_awready;
assign wrbuf_data_en = dma_axi_wvalid & dma_axi_wready;
assign wrbuf_cmd_sent = axi_mstr_valid & axi_mstr_write;
assign wrbuf_rst = wrbuf_cmd_sent & ~wrbuf_en;
assign wrbuf_data_rst = wrbuf_cmd_sent & ~wrbuf_data_en;
rvdffsc #(.WIDTH(1)) wrbuf_vldff(.din(1'b1), .dout(wrbuf_vld), .en(wrbuf_en), .clear(wrbuf_rst), .clk(dma_bus_clk), .*);
rvdffsc #(.WIDTH(1)) wrbuf_data_vldff(.din(1'b1), .dout(wrbuf_data_vld), .en(wrbuf_data_en), .clear(wrbuf_data_rst), .clk(dma_bus_clk), .*);
rvdffs #(.WIDTH(1)) wrbuf_postedff(.din(1'b0), .dout(wrbuf_posted), .en(wrbuf_en), .clk(dma_bus_clk), .*);
@ -428,16 +428,16 @@ module dma_ctrl (
assign rdbuf_en = dma_axi_arvalid & dma_axi_arready;
assign rdbuf_cmd_sent = axi_mstr_valid & ~axi_mstr_write & dma_fifo_ready;
assign rdbuf_rst = rdbuf_cmd_sent & ~rdbuf_en;
rvdffsc #(.WIDTH(1)) rdbuf_vldff(.din(1'b1), .dout(rdbuf_vld), .en(rdbuf_en), .clear(rdbuf_rst), .clk(dma_bus_clk), .*);
rvdffs #(.WIDTH(DMA_BUS_TAG)) rdbuf_tagff(.din(dma_axi_arid[DMA_BUS_TAG-1:0]), .dout(rdbuf_tag[DMA_BUS_TAG-1:0]), .en(rdbuf_en), .clk(dma_bus_clk), .*);
rvdffs #(.WIDTH(3)) rdbuf_sizeff(.din(dma_axi_arsize[2:0]), .dout(rdbuf_size[2:0]), .en(rdbuf_en), .clk(dma_bus_clk), .*);
rvdffe #(.WIDTH(32)) rdbuf_addrff(.din(dma_axi_araddr[31:0]), .dout(rdbuf_addr[31:0]), .en(rdbuf_en & dma_bus_clk_en), .*);
assign dma_axi_awready = ~(wrbuf_vld & ~wrbuf_cmd_sent);
assign dma_axi_wready = ~(wrbuf_data_vld & ~wrbuf_cmd_sent);
assign dma_axi_arready = ~(rdbuf_vld & ~rdbuf_cmd_sent);
assign dma_axi_arready = ~(rdbuf_vld & ~rdbuf_cmd_sent);
//Generate a single request from read/write channel
assign axi_mstr_valid = ((wrbuf_vld & wrbuf_data_vld) | rdbuf_vld) & dma_fifo_ready;
assign axi_mstr_tag[DMA_BUS_TAG-1:0] = axi_mstr_sel ? wrbuf_tag[DMA_BUS_TAG-1:0] : rdbuf_tag[DMA_BUS_TAG-1:0];
@ -446,7 +446,7 @@ module dma_ctrl (
assign axi_mstr_addr[31:0] = axi_mstr_sel ? wrbuf_addr[31:0] : rdbuf_addr[31:0];
assign axi_mstr_size[2:0] = axi_mstr_sel ? wrbuf_size[2:0] : rdbuf_size[2:0];
assign axi_mstr_wdata[63:0] = wrbuf_data[63:0];
assign axi_mstr_wstrb[7:0] = wrbuf_byteen[7:0];
assign axi_mstr_wstrb[7:0] = wrbuf_byteen[7:0];
// Sel=1 -> write has higher priority
assign axi_mstr_sel = (wrbuf_vld & wrbuf_data_vld & rdbuf_vld) ? axi_mstr_priority : (wrbuf_vld & wrbuf_data_vld);
@ -457,33 +457,33 @@ module dma_ctrl (
rvdff #(.WIDTH(1)) axi_mstr_validff (.din(axi_mstr_valid), .dout(axi_mstr_valid_q), .clk(dma_bus_clk), .*);
rvdff #(.WIDTH(1)) axi_slv_sentff (.din(axi_slv_sent), .dout(axi_slv_sent_q), .clk(dma_bus_clk), .*);
//assign axi_slv_valid = fifo_valid[RspPtr] & ~fifo_rsp_done[RspPtr] & ~fifo_dbg[RspPtr] &
//assign axi_slv_valid = fifo_valid[RspPtr] & ~fifo_rsp_done[RspPtr] & ~fifo_dbg[RspPtr] &
// ((fifo_write[RspPtr] & fifo_done_bus[RspPtr]) | (~fifo_write[RspPtr] & fifo_data_bus_valid[RspPtr]) | fifo_error_bus[RspPtr]);
assign axi_slv_valid = fifo_valid[RspPtr] & ~fifo_dbg[RspPtr] & fifo_done_bus[RspPtr];
assign axi_slv_tag[DMA_BUS_TAG-1:0] = fifo_tag[RspPtr];
assign axi_slv_tag[DMA_BUS_TAG-1:0] = fifo_tag[RspPtr];
//assign axi_slv_rdata[63:0] = (|fifo_error[RspPtr]) ? {32'b0,fifo_addr[RspPtr]} : fifo_data[RspPtr];
assign axi_slv_rdata[63:0] = fifo_data[RspPtr];
assign axi_slv_write = fifo_write[RspPtr];
assign axi_slv_posted_write = axi_slv_write & fifo_posted_write[RspPtr];
assign axi_slv_error[1:0] = fifo_error[RspPtr][0] ? 2'b10 : (fifo_error[RspPtr][1] ? 2'b11 : 2'b0);
// AXI response channel signals
assign dma_axi_bvalid = axi_slv_valid & axi_slv_write;
assign dma_axi_bresp[1:0] = axi_slv_error[1:0];
assign dma_axi_bid[DMA_BUS_TAG-1:0] = axi_slv_tag[DMA_BUS_TAG-1:0];
assign dma_axi_rvalid = axi_slv_valid & ~axi_slv_write;
assign dma_axi_rresp[1:0] = axi_slv_error;
assign dma_axi_rresp[1:0] = axi_slv_error;
assign dma_axi_rid[DMA_BUS_TAG-1:0] = axi_slv_tag[DMA_BUS_TAG-1:0];
assign dma_axi_rdata[63:0] = axi_slv_rdata[63:0];
assign dma_axi_rlast = 1'b1;
assign axi_slv_sent = (dma_axi_bvalid & dma_axi_bready) | (dma_axi_rvalid & dma_axi_rready);
assign dma_slv_algn_err = fifo_error[RspPtr][1];
`ifdef ASSERT_ON
//assert_nack_count: assert #0 (dma_nack_count[2:0] < 3'h4);
//assert_nack_count: assert #0 (dma_nack_count[2:0] < 3'h4);
for (genvar i=0; i<DEPTH; i++) begin
//assert_picm_rspdone_and_novalid: assert #0 (~fifo_rsp_done[i] | fifo_valid[i]);
@ -497,9 +497,9 @@ module dma_ctrl (
((dma_axi_awsize[2:0] == 3'h2) & (dma_axi_awaddr[1:0] == 2'b0)) |
((dma_axi_awsize[2:0] == 3'h3) & (dma_axi_awaddr[2:0] == 3'b0)));
endproperty
// assert_dma_write_trxn_aligned: assert property (dma_axi_write_trxn_aligned) else
// assert_dma_write_trxn_aligned: assert property (dma_axi_write_trxn_aligned) else
// $display("Assertion dma_axi_write_trxn_aligned failed: dma_axi_awvalid=1'b%b, dma_axi_awsize=3'h%h, dma_axi_awaddr=32'h%h",dma_axi_awvalid, dma_axi_awsize[2:0], dma_axi_awaddr[31:0]);
// Assertion to check AXI read address is aligned to size
property dma_axi_read_trxn_aligned;
@(posedge dma_bus_clk) dma_axi_arvalid |-> ((dma_axi_arsize[2:0] == 3'h0) |
@ -507,37 +507,37 @@ module dma_ctrl (
((dma_axi_arsize[2:0] == 3'h2) & (dma_axi_araddr[1:0] == 2'b0)) |
((dma_axi_arsize[2:0] == 3'h3) & (dma_axi_araddr[2:0] == 3'b0)));
endproperty
// assert_dma_read_trxn_aligned: assert property (dma_axi_read_trxn_aligned) else
// assert_dma_read_trxn_aligned: assert property (dma_axi_read_trxn_aligned) else
// $display("Assertion dma_axi_read_trxn_aligned failed: dma_axi_arvalid=1'b%b, dma_axi_arsize=3'h%h, dma_axi_araddr=32'h%h",dma_axi_arvalid, dma_axi_arsize[2:0], dma_axi_araddr[31:0]);
// Assertion to check write size is 8 byte or less
property dma_axi_awsize_check;
@(posedge dma_bus_clk) disable iff(~rst_l) (dma_axi_awvalid & dma_axi_awready) |-> (dma_axi_awsize[2] == 1'b0);
endproperty
assert_dma_axi_awsize_check: assert property (dma_axi_awsize_check) else
$display("DMA AXI awsize is illegal. Size greater than 8B not supported");
// Assertion to check there are no burst commands
property dma_axi_awlen_check;
@(posedge dma_bus_clk) disable iff(~rst_l) (dma_axi_awvalid & dma_axi_awready) |-> (dma_axi_awlen[7:0] == 8'b0);
endproperty
assert_dma_axi_awlen_check: assert property (dma_axi_awlen_check) else
$display("DMA AXI awlen is illegal. Length greater than 0 not supported");
// Assertion to check write size is 8 byte or less
property dma_axi_arsize_check;
@(posedge dma_bus_clk) disable iff(~rst_l) (dma_axi_arvalid & dma_axi_arready) |-> (dma_axi_arsize[2] == 1'b0);
endproperty
assert_dma_axi_arsize_check: assert property (dma_axi_arsize_check) else
$display("DMA AXI arsize is illegal, Size bigger than 8B not supported");
// Assertion to check there are no burst commands
property dma_axi_arlen_check;
@(posedge dma_bus_clk) disable iff(~rst_l) (dma_axi_arvalid & dma_axi_arready) |-> (dma_axi_arlen[7:0] == 8'b0);
endproperty
assert_dma_axi_arlen_check: assert property (dma_axi_arlen_check) else
$display("DMA AXI arlen greater than 0 not supported.");
// Assertion to check cmd valid stays stable during entire bus clock
property dma_axi_awvalid_stable;
@(posedge clk) disable iff(~rst_l) (dma_axi_awvalid != $past(dma_axi_awvalid)) |-> $past(dma_bus_clk_en);
@ -692,6 +692,6 @@ module dma_ctrl (
assert_dma_axi_rid_stable: assert property (dma_axi_rid_stable) else
$display("DMA AXI bid changed in middle of bus clock");
`endif
`endif
endmodule // dma_ctrl

View File

@ -1,12 +1,12 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright 2019 Western Digital Corporation or its affiliates.
//
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//
// http://www.apache.org/licenses/LICENSE-2.0
//
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -46,7 +46,7 @@ input [1:0] dmi_stat,
input [31:1] jtag_id,
input [3:0] version
);
localparam USER_DR_LENGTH = AWIDTH + 34;
@ -57,13 +57,13 @@ reg [USER_DR_LENGTH-1:0] sr, nsr, dr;
///////////////////////////////////////////////////////
logic[3:0] state, nstate;
logic [4:0] ir;
wire jtag_reset;
wire shift_dr;
wire pause_dr;
wire update_dr;
wire jtag_reset;
wire shift_dr;
wire pause_dr;
wire update_dr;
wire capture_dr;
wire shift_ir;
wire pause_ir ;
wire shift_ir;
wire pause_ir ;
wire update_ir ;
wire capture_ir;
wire[1:0] dr_en;
@ -94,7 +94,7 @@ always_comb begin
nstate = state;
case(state)
TEST_LOGIC_RESET_STATE: nstate = tms ? TEST_LOGIC_RESET_STATE : RUN_TEST_IDLE_STATE;
RUN_TEST_IDLE_STATE: nstate = tms ? SELECT_DR_SCAN_STATE : RUN_TEST_IDLE_STATE;
RUN_TEST_IDLE_STATE: nstate = tms ? SELECT_DR_SCAN_STATE : RUN_TEST_IDLE_STATE;
SELECT_DR_SCAN_STATE: nstate = tms ? SELECT_IR_SCAN_STATE : CAPTURE_DR_STATE;
CAPTURE_DR_STATE: nstate = tms ? EXIT1_DR_STATE : SHIFT_DR_STATE;
SHIFT_DR_STATE: nstate = tms ? EXIT1_DR_STATE : SHIFT_DR_STATE;
@ -146,7 +146,7 @@ end
assign devid_sel = ir == 5'b00001;
assign dr_en[0] = ir == 5'b10000;
assign dr_en[1] = ir == 5'b10001;
///////////////////////////////////////////////////////
// Shift register
///////////////////////////////////////////////////////
@ -192,11 +192,11 @@ always @ (posedge tck or negedge trst) begin
if(!trst) begin
dmi_hard_reset <= 1'b0;
dmi_reset <= 1'b0;
end
end
else if (update_dr & dr_en[0]) begin
dmi_hard_reset <= sr[17];
dmi_reset <= sr[16];
end
end
else begin
dmi_hard_reset <= 1'b0;
dmi_reset <= 1'b0;

View File

@ -176,7 +176,7 @@ module exu
output logic [`RV_BHT_GHR_RANGE] exu_i0_br_fghr_e4, // to DEC I0 branch fghr
output logic exu_i0_br_ret_e4, // to DEC I0 branch return
output logic exu_i0_br_call_e4, // to DEC I0 branch call
output logic [1:0] exu_i1_br_hist_e4, // to DEC I1 branch history
output logic [1:0] exu_i1_br_bank_e4, // to DEC I1 branch bank
output logic exu_i1_br_error_e4, // to DEC I1 branch error
@ -292,7 +292,7 @@ module exu
({32{ dec_i1_rs1_bypass_en_d}} & i1_rs1_bypass_data_d[31:0]);
assign i1_rs2_d[31:0] = ({32{~dec_i1_rs2_bypass_en_d}} & gpr_i1_rs2_d[31:0]) |
({32{~dec_i1_rs2_bypass_en_d}} & dec_i1_immed_d[31:0]) |
({32{~dec_i1_rs2_bypass_en_d}} & dec_i1_immed_d[31:0]) |
({32{ dec_i1_rs2_bypass_en_d}} & i1_rs2_bypass_data_d[31:0]);
assign exu_lsu_rs1_d[31:0] = ({32{ ~dec_i0_rs1_bypass_en_d & dec_i0_lsu_d }} & gpr_i0_rs1_d[31:0] ) |
@ -477,7 +477,7 @@ module exu
.dout({i0_rs1_e1[31:0], i0_rs2_e1[31:0], i0_br_immed_e1[12:1]})
);
rvdffe #(76) i0_src_e2_ff (.*,
rvdffe #(76) i0_src_e2_ff (.*,
.en(i0_e2_data_en),
.din( {i0_rs1_e1[31:0], i0_rs2_e1[31:0], i0_br_immed_e1[12:1]}),
.dout({i0_rs1_e2[31:0], i0_rs2_e2[31:0], i0_br_immed_e2[12:1]})
@ -538,7 +538,7 @@ module exu
assign i1_taken_e1= (i1_ataken_e1 & dec_i1_alu_decode_e1) | (i1_predict_p_e1.hist[1] & ~dec_i1_alu_decode_e1);
assign ghr_e1_ns[`RV_BHT_GHR_RANGE] = ( ({`RV_BHT_GHR_SIZE{~dec_tlu_flush_lower_wb & i0_valid_e1 & (i0_predict_p_e1.misp | ~i1_valid_e1)}} & {ghr_e1[`RV_BHT_GHR_SIZE-2:0], i0_taken_e1}) |
`ifdef RV_BHT_GHR_SIZE_2
`ifdef RV_BHT_GHR_SIZE_2
({`RV_BHT_GHR_SIZE{~dec_tlu_flush_lower_wb & i0_valid_e1 & ~i0_predict_p_e1.misp & i1_valid_e1}} & { i0_taken_e1, i1_taken_e1}) |
`else
({`RV_BHT_GHR_SIZE{~dec_tlu_flush_lower_wb & i0_valid_e1 & ~i0_predict_p_e1.misp & i1_valid_e1}} & {ghr_e1[`RV_BHT_GHR_SIZE-3:0], i0_taken_e1, i1_taken_e1}) |
@ -556,7 +556,7 @@ module exu
assign i0_valid_e4 = dec_tlu_i0_valid_e4 & ((i0_predict_p_e4.valid) | i0_predict_p_e4.misp);
assign i1_pred_valid_e4 = dec_tlu_i1_valid_e4 & ((i1_predict_p_e4.valid) | i1_predict_p_e4.misp) & ~exu_i0_flush_upper_e4;
assign ghr_e4_ns[`RV_BHT_GHR_RANGE] = ( ({`RV_BHT_GHR_SIZE{i0_valid_e4 & (i0_predict_p_e4.misp | ~i1_pred_valid_e4)}} & {ghr_e4[`RV_BHT_GHR_SIZE-2:0], i0_predict_p_e4.ataken}) |
`ifdef RV_BHT_GHR_SIZE_2
`ifdef RV_BHT_GHR_SIZE_2
({`RV_BHT_GHR_SIZE{i0_valid_e4 & ~i0_predict_p_e4.misp & i1_pred_valid_e4}} & { i0_predict_p_e4.ataken, i1_predict_p_e4.ataken}) |
`else
({`RV_BHT_GHR_SIZE{i0_valid_e4 & ~i0_predict_p_e4.misp & i1_pred_valid_e4}} & {ghr_e4[`RV_BHT_GHR_SIZE-3:0], i0_predict_p_e4.ataken, i1_predict_p_e4.ataken}) |
@ -715,7 +715,7 @@ module exu
.din({
exu_i0_flush_path_e1[31:1],
exu_i0_flush_upper_e1}),
.dout({
i0_flush_path_upper_e2[31:1],
exu_i0_flush_upper_e2})

View File

@ -192,7 +192,7 @@ module exu_alu_ctl
// branch handling
logic any_jal;
assign any_jal = ap.jal |
pp_ff.pcall |
pp_ff.pja |
@ -217,7 +217,7 @@ module exu_alu_ctl
// pred_correct is for the npc logic
// pred_correct indicates not to use the flush_path
// for any_jal pred_correct==0
assign pred_correct = ((ap.predict_nt & ~actual_taken) |
(ap.predict_t & actual_taken)) & ~any_jal;
@ -242,7 +242,7 @@ module exu_alu_ctl
// .ilb hist[1] hist[0] taken
// .ob newhist[1] newhist[0]
// .type fd
//
//
// 00 0 01
// 01 0 01
// 10 0 00

View File

@ -59,7 +59,7 @@ module exu_mul_ctl
assign mul_c1_e2_clken = (valid_e1 | clk_override) & ~freeze;
assign mul_c1_e3_clken = (valid_e2 | clk_override) & ~freeze;
// C1 - 1 clock pulse for data
// C1 - 1 clock pulse for data
rvclkhdr exu_mul_c1e1_cgc (.*, .en(mul_c1_e1_clken), .l1clk(exu_mul_c1_e1_clk));
rvclkhdr exu_mul_c1e2_cgc (.*, .en(mul_c1_e2_clken), .l1clk(exu_mul_c1_e2_clk));
rvclkhdr exu_mul_c1e3_cgc (.*, .en(mul_c1_e3_clken), .l1clk(exu_mul_c1_e3_clk));

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

@ -30,9 +30,9 @@ module ifu
input logic dec_ib3_valid_d, dec_ib2_valid_d, // mass balance for decode buffer
input logic dec_ib0_valid_eff_d, // effective valid taking decode into account
input logic dec_ib1_valid_eff_d, // effective valid taking decode into account
input logic dec_ib0_valid_eff_d, // effective valid taking decode into account
input logic dec_ib1_valid_eff_d, // effective valid taking decode into account
input logic exu_i0_br_ret_e4, // i0 branch commit is a ret
input logic exu_i1_br_ret_e4, // i1 branch commit is a ret
input logic exu_i0_br_call_e4, // i0 branch commit is a call
@ -49,8 +49,8 @@ module ifu
input logic [31:0] dec_tlu_mrac_ff ,// Side_effect , cacheable for each region
input logic dec_tlu_fence_i_wb, // fence.i, invalidate icache, validated with exu_flush_final
input logic dec_tlu_flush_leak_one_wb, // ignore bp for leak one fetches
input logic dec_tlu_bpred_disable, // disable all branch prediction
input logic dec_tlu_bpred_disable, // disable all branch prediction
input logic dec_tlu_core_ecc_disable, // disable ecc checking and flagging
// AXI Write Channels - IFU never writes. So, 0 out mostly
@ -66,19 +66,19 @@ module ifu
output logic [3:0] ifu_axi_awcache,
output logic [2:0] ifu_axi_awprot,
output logic [3:0] ifu_axi_awqos,
output logic ifu_axi_wvalid,
output logic ifu_axi_wvalid,
input logic ifu_axi_wready,
output logic [63:0] ifu_axi_wdata,
output logic [7:0] ifu_axi_wstrb,
output logic ifu_axi_wlast,
input logic ifu_axi_bvalid,
output logic ifu_axi_bready,
input logic [1:0] ifu_axi_bresp,
input logic [`RV_IFU_BUS_TAG-1:0] ifu_axi_bid,
// AXI Read Channels
// AXI Read Channels
output logic ifu_axi_arvalid,
input logic ifu_axi_arready,
output logic [`RV_IFU_BUS_TAG-1:0] ifu_axi_arid,
@ -91,7 +91,7 @@ module ifu
output logic [3:0] ifu_axi_arcache,
output logic [2:0] ifu_axi_arprot,
output logic [3:0] ifu_axi_arqos,
input logic ifu_axi_rvalid,
output logic ifu_axi_rready,
input logic [`RV_IFU_BUS_TAG-1:0] ifu_axi_rid,
@ -100,101 +100,101 @@ module ifu
input logic ifu_axi_rlast,
//// AHB LITE BUS
//`ifdef RV_BUILD_AHB_LITE
//`ifdef RV_BUILD_AHB_LITE
input logic ifu_bus_clk_en,
input logic dma_iccm_req,
input logic dma_iccm_stall_any,
input logic dma_iccm_req,
input logic dma_iccm_stall_any,
input logic [31:0] dma_mem_addr,
input logic [2:0] dma_mem_sz,
input logic dma_mem_write,
input logic [63:0] dma_mem_wdata,
output logic iccm_dma_ecc_error,
output logic iccm_dma_rvalid,
output logic iccm_dma_ecc_error,
output logic iccm_dma_rvalid,
output logic [63:0] iccm_dma_rdata,
output logic iccm_ready,
//`endif
//`endif
output logic [1:0] ifu_pmu_instr_aligned,
output logic ifu_pmu_align_stall,
output logic ifu_pmu_fetch_stall,
// I$ & ITAG Ports
output logic [31:3] ic_rw_addr, // Read/Write addresss to the Icache.
// I$ & ITAG Ports
output logic [31:3] ic_rw_addr, // Read/Write addresss to the Icache.
output logic [3:0] ic_wr_en, // Icache write enable, when filling the Icache.
output logic ic_rd_en, // Icache read enable.
`ifdef RV_ICACHE_ECC
output logic [83:0] ic_wr_data, // Data to fill to the Icache. With ECC
input logic [167:0] ic_rd_data , // Data read from Icache. 2x64bits + parity bits. F2 stage. With ECC
input logic [24:0] ictag_debug_rd_data,// Debug icache tag.
output logic [41:0] ic_debug_wr_data, // Debug wr cache.
input logic [24:0] ictag_debug_rd_data,// Debug icache tag.
output logic [41:0] ic_debug_wr_data, // Debug wr cache.
output logic [41:0] ifu_ic_debug_rd_data,
`else
`else
output logic [67:0] ic_wr_data, // Data to fill to the Icache. With Parity
input logic [135:0] ic_rd_data , // Data read from Icache. 2x64bits + parity bits. F2 stage. With Parity
input logic [20:0] ictag_debug_rd_data,// Debug icache tag.
output logic [33:0] ic_debug_wr_data, // Debug wr cache.
input logic [20:0] ictag_debug_rd_data,// Debug icache tag.
output logic [33:0] ic_debug_wr_data, // Debug wr cache.
output logic [33:0] ifu_ic_debug_rd_data,
`endif
output logic [127:0] ic_premux_data, // Premux data to be muxed with each way of the Icache.
output logic [127:0] ic_premux_data, // Premux data to be muxed with each way of the Icache.
output logic ic_sel_premux_data, // Select the premux data.
output logic [15:2] ic_debug_addr, // Read/Write addresss to the Icache.
output logic [15:2] ic_debug_addr, // Read/Write addresss to the Icache.
output logic ic_debug_rd_en, // Icache debug rd
output logic ic_debug_wr_en, // Icache debug wr
output logic ic_debug_tag_array, // Debug tag array
output logic [3:0] ic_debug_way, // Debug way. Rd or Wr.
output logic [3:0] ic_tag_valid, // Valid bits when accessing the Icache. One valid bit per way. F2 stage
input logic [3:0] ic_rd_hit, // Compare hits from Icache tags. Per way. F2 stage
output logic [3:0] ic_tag_valid, // Valid bits when accessing the Icache. One valid bit per way. F2 stage
input logic [3:0] ic_rd_hit, // Compare hits from Icache tags. Per way. F2 stage
input logic ic_tag_perr, // Icache Tag parity error
`ifdef RV_ICCM_ENABLE
// ICCM ports
// ICCM ports
output logic [`RV_ICCM_BITS-1:2] iccm_rw_addr, // ICCM read/write address.
output logic iccm_wren, // ICCM write enable (through the DMA)
output logic iccm_rden, // ICCM read enable.
output logic [77:0] iccm_wr_data, // ICCM write data.
output logic [2:0] iccm_wr_size, // ICCM write location within DW.
output logic [2:0] iccm_wr_size, // ICCM write location within DW.
input logic [155:0] iccm_rd_data, // Data read from ICCM.
`endif
// Perf counter sigs
output logic ifu_pmu_ic_miss, // ic miss
output logic ifu_pmu_ic_hit, // ic hit
output logic ifu_pmu_ic_hit, // ic hit
output logic ifu_pmu_bus_error, // iside bus error
output logic ifu_pmu_bus_busy, // iside bus busy
output logic ifu_pmu_bus_trxn, // iside bus transactions
output logic ifu_i0_valid, // Instruction 0 valid. From Aligner to Decode
output logic ifu_i1_valid, // Instruction 1 valid. From Aligner to Decode
output logic ifu_i0_valid, // Instruction 0 valid. From Aligner to Decode
output logic ifu_i1_valid, // Instruction 1 valid. From Aligner to Decode
output logic ifu_i0_icaf, // Instruction 0 access fault. From Aligner to Decode
output logic ifu_i1_icaf, // Instruction 1 access fault. From Aligner to Decode
output logic ifu_i1_icaf, // Instruction 1 access fault. From Aligner to Decode
output logic ifu_i0_icaf_f1, // Instruction 0 has access fault on second fetch group
output logic ifu_i1_icaf_f1, // Instruction 1 has access fault on second fetch group
output logic ifu_i0_perr, // Instruction 0 parity error. From Aligner to Decode
output logic ifu_i1_perr, // Instruction 1 parity error. From Aligner to Decode
output logic ifu_i1_perr, // Instruction 1 parity error. From Aligner to Decode
output logic ifu_i0_sbecc, // Instruction 0 has single bit ecc error
output logic ifu_i1_sbecc, // Instruction 1 has single bit ecc error
output logic ifu_i0_dbecc, // Instruction 0 has double bit ecc error
output logic ifu_i1_dbecc, // Instruction 1 has double bit ecc error
output logic iccm_dma_sb_error, // Single Bit ECC error from a DMA access
output logic[31:0] ifu_i0_instr, // Instruction 0 . From Aligner to Decode
output logic[31:0] ifu_i1_instr, // Instruction 1 . From Aligner to Decode
output logic[31:1] ifu_i0_pc, // Instruction 0 pc. From Aligner to Decode
output logic[31:0] ifu_i1_instr, // Instruction 1 . From Aligner to Decode
output logic[31:1] ifu_i0_pc, // Instruction 0 pc. From Aligner to Decode
output logic[31:1] ifu_i1_pc, // Instruction 1 pc. From Aligner to Decode
output logic ifu_i0_pc4, // Instruction 0 is 4 byte. From Aligner to Decode
output logic ifu_i1_pc4, // Instruction 1 is 4 byte. From Aligner to Decode
output logic ifu_i1_pc4, // Instruction 1 is 4 byte. From Aligner to Decode
output logic [15:0] ifu_illegal_inst, // Illegal instruction.
output logic ifu_miss_state_idle, // There is no outstanding miss. Cache miss state is idle.
@ -209,7 +209,7 @@ module ifu
input br_tlu_pkt_t dec_tlu_br0_wb_pkt, // slot0 update/error pkt
input br_tlu_pkt_t dec_tlu_br1_wb_pkt, // slot1 update/error pkt
input dec_tlu_flush_lower_wb,
input rets_pkt_t exu_rets_e1_pkt, // E1 return stack packet
input rets_pkt_t exu_rets_e4_pkt, // E4 return stack packet
@ -225,13 +225,13 @@ module ifu
output logic [15:0] ifu_i1_cinst,
/// Icache debug
/// Icache debug
input cache_debug_pkt_t dec_tlu_ic_diag_pkt ,
output logic ifu_ic_debug_rd_data_valid,
input logic scan_mode
input logic scan_mode
);
localparam TAGWIDTH = 2 ;
@ -245,7 +245,7 @@ module ifu
logic [31:1] ifu_fetch_pc; // starting pc of fetch
logic [31:1] ifc_fetch_addr_f1;
logic ic_crit_wd_rdy;
logic ic_write_stall;
logic ic_dma_active;
@ -255,9 +255,9 @@ module ifu
logic ic_access_fault_f2;
logic ifu_ic_mb_empty;
logic ic_hit_f2;
// fetch control
ifu_ifc_ctl ifc (.*
);
@ -278,42 +278,42 @@ module ifu
logic [7:0] ifu_bp_pc4_f2; // pc4 indication; right justified
logic [7:0] ifu_bp_valid_f2; // branch valid, right justified
logic [`RV_BHT_GHR_RANGE] ifu_bp_fghr_f2;
// branch predictor
ifu_bp_ctl bp (.*);
logic [7:0] ic_fetch_val_f2;
logic [127:0] ic_data_f2;
logic [127:0] ifu_fetch_data;
logic ifc_fetch_req_f1_raw, ifc_fetch_req_f1, ifc_fetch_req_f2;
logic ic_rd_parity_final_err; // This fetch has a data_cache or tag parity error.
logic iccm_rd_ecc_single_err; // This fetch has an iccm single error.
logic ic_rd_parity_final_err; // This fetch has a data_cache or tag parity error.
logic iccm_rd_ecc_single_err; // This fetch has an iccm single error.
logic iccm_rd_ecc_double_err; // This fetch has an iccm double error.
icache_err_pkt_t ic_error_f2;
logic ifu_icache_fetch_f2 ;
logic [16:2] ifu_icache_error_index; // Index with parity error
logic ifu_icache_error_val; // Parity error
logic ifu_icache_error_val; // Parity error
logic ifu_icache_sb_error_val;
assign ifu_fetch_data[127:0] = ic_data_f2[127:0];
assign ifu_fetch_val[7:0] = ic_fetch_val_f2[7:0];
assign ifu_fetch_pc[31:1] = ifc_fetch_addr_f2[31:1];
// aligner
ifu_aln_ctl aln (.*);
// icache
ifu_mem_ctl mem_ctl
ifu_mem_ctl mem_ctl
(.*,
.fetch_addr_f1(ifc_fetch_addr_f1),
.ifu_icache_error_index(ifu_icache_error_index[16:6]),
.ifu_icache_error_index(ifu_icache_error_index[16:6]),
.ic_hit_f2(ic_hit_f2),
.ic_data_f2(ic_data_f2[127:0])
);
// Performance debug info
@ -371,26 +371,26 @@ assign tmp_bnk[2:0] = encode8_3(bp.btb_sel_f2[7:0]);
`endif
$display("RS_CONFIG: %d", `RV_RET_STACK_SIZE);
end
if(exu_flush_final & ~(dec_tlu_br0_wb_pkt.br_error | dec_tlu_br0_wb_pkt.br_start_error | dec_tlu_br1_wb_pkt.br_error | dec_tlu_br1_wb_pkt.br_start_error) & (exu_mp_pkt.misp | exu_mp_pkt.ataken))
if(exu_flush_final & ~(dec_tlu_br0_wb_pkt.br_error | dec_tlu_br0_wb_pkt.br_start_error | dec_tlu_br1_wb_pkt.br_error | dec_tlu_br1_wb_pkt.br_start_error) & (exu_mp_pkt.misp | exu_mp_pkt.ataken))
$display("%7d BTB_MP : index: %0h bank: %0h call: %b ret: %b ataken: %b hist: %h valid: %b tag: %h targ: %h eghr: %b pred: %b ghr_index: %h brpc: %h way: %h", `DEC.tlu.mcyclel[31:0]+32'ha, exu_mp_addr[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO], exu_mp_bank[1:0], exu_mp_call, exu_mp_ret, exu_mp_ataken, exu_mp_hist[1:0], exu_mp_valid, exu_mp_pkt.btag[`RV_BTB_BTAG_SIZE-1:0], {exu_flush_path_final[31:1], 1'b0}, exu_mp_eghr[`RV_BHT_GHR_RANGE], exu_mp_valid, bp.bht_wr_addr0, mppc[31:0], exu_mp_pkt.way);
for(int i = 0; i < 8; i++) begin
if(ifu_bp_valid_f2[i] & ifc_fetch_req_f2)
if(ifu_bp_valid_f2[i] & ifc_fetch_req_f2)
$display("%7d BTB_HIT : index: %0h bank: %0h call: %b ret: %b taken: %b strength: %b tag: %h targ: %h ghr: %4b ghr_index: %h way: %h", `DEC.tlu.mcyclel[31:0]+32'ha,btb_rd_addr_f2[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO],encode8_3(bp.btb_sel_f2[7:0]), bp.btb_rd_call_f2, bp.btb_rd_ret_f2, ifu_bp_hist1_f2[tmp_bnk], ifu_bp_hist0_f2[tmp_bnk], bp.fetch_rd_tag_f2[`RV_BTB_BTAG_SIZE-1:0], {ifu_bp_btb_target_f2[31:1], 1'b0}, bp.fghr[`RV_BHT_GHR_RANGE], bp.bht_rd_addr_f1, ifu_bp_way_f2[tmp_bnk]);
end
`ifdef RV_BTB_48
for(int y = 0; y < 4; y++) begin
for(int z = 0; z < 4; z++) begin
if(bp.lru_bank_sel[y][z])
$display("%7d BTB_LRU: index: %0h bank: %0h newlru %h", `DEC.tlu.mcyclel[31:0]+32'ha, z,y,bp.lru_bank_wr_data[y][z]);
$display("%7d BTB_LRU: index: %0h bank: %0h newlru %h", `DEC.tlu.mcyclel[31:0]+32'ha, z,y,bp.lru_bank_wr_data[y][z]);
end
end
`endif
`endif
if(dec_tlu_br0_wb_pkt.valid & ~(dec_tlu_br0_wb_pkt.br_error | dec_tlu_br0_wb_pkt.br_start_error))
$display("%7d BTB_UPD0: ghr_index: %0h bank: %0h hist: %h way: %h", `DEC.tlu.mcyclel[31:0]+32'ha,bp.br0_hashed_wb[`RV_BHT_ADDR_HI:`RV_BHT_ADDR_LO],{dec_tlu_br0_wb_pkt.bank[1:0],dec_tlu_br0_wb_pkt.middle}, dec_tlu_br0_wb_pkt.hist, dec_tlu_br0_wb_pkt.way);
$display("%7d BTB_UPD0: ghr_index: %0h bank: %0h hist: %h way: %h", `DEC.tlu.mcyclel[31:0]+32'ha,bp.br0_hashed_wb[`RV_BHT_ADDR_HI:`RV_BHT_ADDR_LO],{dec_tlu_br0_wb_pkt.bank[1:0],dec_tlu_br0_wb_pkt.middle}, dec_tlu_br0_wb_pkt.hist, dec_tlu_br0_wb_pkt.way);
if(dec_tlu_br1_wb_pkt.valid & ~(dec_tlu_br1_wb_pkt.br_error | dec_tlu_br1_wb_pkt.br_start_error))
$display("%7d BTB_UPD1: ghr_index: %0h bank: %0h hist: %h way: %h", `DEC.tlu.mcyclel[31:0]+32'ha,bp.br1_hashed_wb[`RV_BHT_ADDR_HI:`RV_BHT_ADDR_LO],{dec_tlu_br1_wb_pkt.bank[1:0],dec_tlu_br1_wb_pkt.middle}, dec_tlu_br1_wb_pkt.hist, dec_tlu_br1_wb_pkt.way);
$display("%7d BTB_UPD1: ghr_index: %0h bank: %0h hist: %h way: %h", `DEC.tlu.mcyclel[31:0]+32'ha,bp.br1_hashed_wb[`RV_BHT_ADDR_HI:`RV_BHT_ADDR_LO],{dec_tlu_br1_wb_pkt.bank[1:0],dec_tlu_br1_wb_pkt.middle}, dec_tlu_br1_wb_pkt.hist, dec_tlu_br1_wb_pkt.way);
if(dec_tlu_br0_wb_pkt.br_error | dec_tlu_br0_wb_pkt.br_start_error)
$display("%7d BTB_ERR0: index: %0h bank: %0h start: %b rfpc: %h way: %h", `DEC.tlu.mcyclel[31:0]+32'ha,dec_tlu_br0_wb_pkt.index[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO],dec_tlu_br0_wb_pkt.bank[1:0], dec_tlu_br0_wb_pkt.br_start_error, {exu_flush_path_final[31:1], 1'b0}, dec_tlu_br0_wb_pkt.way);
$display("%7d BTB_ERR0: index: %0h bank: %0h start: %b rfpc: %h way: %h", `DEC.tlu.mcyclel[31:0]+32'ha,dec_tlu_br0_wb_pkt.index[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO],dec_tlu_br0_wb_pkt.bank[1:0], dec_tlu_br0_wb_pkt.br_start_error, {exu_flush_path_final[31:1], 1'b0}, dec_tlu_br0_wb_pkt.way);
if(dec_tlu_br1_wb_pkt.br_error | dec_tlu_br1_wb_pkt.br_start_error)
$display("%7d BTB_ERR1: index: %0h bank: %0h start: %b rfpc: %h way: %h", `DEC.tlu.mcyclel[31:0]+32'ha,dec_tlu_br1_wb_pkt.index[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO],dec_tlu_br1_wb_pkt.bank[1:0], dec_tlu_br1_wb_pkt.br_start_error, {exu_flush_path_final[31:1], 1'b0}, dec_tlu_br1_wb_pkt.way);
end // always @ (negedge clk)
@ -401,6 +401,6 @@ assign tmp_bnk[2:0] = encode8_3(bp.btb_sel_f2[7:0]);
encode8_3[1] = in[7] | in[6] | in[3] | in[2];
encode8_3[0] = in[7] | in[5] | in[3] | in[1];
endfunction
endfunction
`endif
endmodule // ifu

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -24,18 +24,18 @@ module ifu_compress_ctl
output logic legal
);
logic [15:0] i;
logic [31:0] o,l1,l2,l3;
assign i[15:0] = din[15:0];
logic [4:0] rs2d,rdd,rdpd,rs2pd;
logic rdrd;
logic rdrs1;
logic rs2rs2;
@ -68,46 +68,46 @@ logic uswspimm7_2;
// c.and rdp 9:7 rs2p 4:2
//
// add rs2 24:20 rs1 19:15 rd 11:7
assign rs2d[4:0] = i[6:2];
assign rdd[4:0] = i[11:7];
assign rdpd[4:0] = {2'b01, i[9:7]};
assign rs2pd[4:0] = {2'b01, i[4:2]};
assign rs2pd[4:0] = {2'b01, i[4:2]};
// merge in rd, rs1, rs2
// rd
assign l1[6:0] = o[6:0];
assign l1[11:7] = o[11:7] |
assign l1[11:7] = o[11:7] |
({5{rdrd}} & rdd[4:0]) |
({5{rdprd}} & rdpd[4:0]) |
({5{rs2prd}} & rs2pd[4:0]) |
({5{rdeq1}} & 5'd1) |
({5{rdeq2}} & 5'd2);
// rs1
// rs1
assign l1[14:12] = o[14:12];
assign l1[19:15] = o[19:15] |
assign l1[19:15] = o[19:15] |
({5{rdrs1}} & rdd[4:0]) |
({5{rdprs1}} & rdpd[4:0]) |
({5{rs1eq2}} & 5'd2);
// rs2
assign l1[24:20] = o[24:20] |
assign l1[24:20] = o[24:20] |
({5{rs2rs2}} & rs2d[4:0]) |
({5{rs2prs2}} & rs2pd[4:0]);
assign l1[31:25] = o[31:25];
logic [5:0] simm5d;
logic [9:2] uimm9d;
@ -117,8 +117,8 @@ logic uswspimm7_2;
logic [5:0] uimm5d;
logic [20:1] sjald;
logic [31:12] sluimmd;
logic [31:12] sluimmd;
// merge in immediates + jal offset
assign simm5d[5:0] = { i[12], i[6:2] };
@ -134,15 +134,15 @@ logic uswspimm7_2;
assign uimm5d[5:0] = { i[12], i[6:2] };
assign sjald[11:1] = { i[12], i[8], i[10:9], i[6], i[7], i[2], i[11], i[5:4], i[3] };
assign sjald[20:12] = {9{i[12]}};
assign sluimmd[31:12] = { {15{i[12]}}, i[6:2] };
assign l2[31:20] = ( l1[31:20] ) |
assign l2[31:20] = ( l1[31:20] ) |
( {12{simm5_0}} & {{7{simm5d[5]}},simm5d[4:0]} ) |
( {12{uimm9_2}} & {2'b0,uimm9d[9:2],2'b0} ) |
( {12{simm9_4}} & {{3{simm9d[9]}},simm9d[8:4],4'b0} ) |
@ -151,46 +151,46 @@ logic uswspimm7_2;
( {12{uimm5_0}} & {6'b0,uimm5d[5:0]} ) |
( {12{sjaloffset11_1}} & {sjald[20],sjald[10:1],sjald[11]} ) |
( {12{sluimm17_12}} & sluimmd[31:20] );
assign l2[19:12] = ( l1[19:12] ) |
( {8{sjaloffset11_1}} & sjald[19:12] ) |
( {8{sluimm17_12}} & sluimmd[19:12] );
assign l2[11:0] = l1[11:0];
// merge in branch offset and store immediates
logic [8:1] sbr8d;
logic [6:2] uswimm6d;
logic [7:2] uswspimm7d;
assign sbr8d[8:1] = { i[12], i[6], i[5], i[2], i[11], i[10], i[4], i[3] };
assign uswimm6d[6:2] = { i[5], i[12:10], i[6] };
assign uswspimm7d[7:2] = { i[8:7], i[12:9] };
assign l3[31:25] = ( l2[31:25] ) |
assign l3[31:25] = ( l2[31:25] ) |
( {7{sbroffset8_1}} & { {4{sbr8d[8]}},sbr8d[7:5] } ) |
( {7{uswimm6_2}} & { 5'b0, uswimm6d[6:5] } ) |
( {7{uswspimm7_2}} & { 4'b0, uswspimm7d[7:5] } );
assign l3[24:12] = l2[24:12];
assign l3[11:7] = ( l2[11:7] ) |
( {5{sbroffset8_1}} & { sbr8d[4:1], sbr8d[8] } ) |
( {5{uswimm6_2}} & { uswimm6d[4:2], 2'b0 } ) |
( {5{uswspimm7_2}} & { uswspimm7d[4:2], 2'b0 } );
assign l3[6:0] = l2[6:0];
assign dout[31:0] = l3[31:0] & {32{legal}};
@ -211,8 +211,8 @@ logic uswspimm7_2;
// espresso decodes
assign rdrd = (!i[14]&i[6]&i[1]) | (!i[15]&i[14]&i[11]&i[0]) | (!i[14]&i[5]&i[1]) | (
!i[15]&i[14]&i[10]&i[0]) | (!i[14]&i[4]&i[1]) | (!i[15]&i[14]&i[9]
@ -353,7 +353,7 @@ assign o[2] = (!i[14]&i[12]&i[11]&!i[6]&!i[5]&!i[4]&!i[3]&!i[2]&i[1]) | (!i[14]
&i[9]) | (!i[15]&i[13]&i[10]) | (!i[15]&i[13]&i[11]) | (!i[14]&i[13]);
// 32b instruction has lower two bits 2'b11
assign o[1] = 1'b1;
assign o[0] = 1'b1;
@ -374,6 +374,6 @@ assign legal = (!i[13]&!i[12]&i[11]&i[1]&!i[0]) | (!i[13]&!i[12]&i[6]&i[1]&!i[0]
&!i[0]) | (!i[15]&!i[13]&i[12]&!i[1]) | (i[14]&!i[13]&!i[0]);
endmodule

View File

@ -17,23 +17,23 @@
////////////////////////////////////////////////////
// ICACHE DATA & TAG MODULE WRAPPER //
/////////////////////////////////////////////////////
module ifu_ic_mem
module ifu_ic_mem
(
input logic clk,
input logic rst_l,
input logic clk_override,
input logic dec_tlu_core_ecc_disable,
input logic dec_tlu_core_ecc_disable,
input logic [31:3] ic_rw_addr,
input logic [31:3] ic_rw_addr,
input logic [3:0] ic_wr_en , // Which way to write
input logic ic_rd_en , // Read enable
input logic [15:2] ic_debug_addr, // Read/Write addresss to the Icache.
input logic [15:2] ic_debug_addr, // Read/Write addresss to the Icache.
input logic ic_debug_rd_en, // Icache debug rd
input logic ic_debug_wr_en, // Icache debug wr
input logic ic_debug_tag_array, // Debug tag array
input logic [3:0] ic_debug_way, // Debug way. Rd or Wr.
input logic [127:0] ic_premux_data, // Premux data to be muxed with each way of the Icache.
input logic [127:0] ic_premux_data, // Premux data to be muxed with each way of the Icache.
input logic ic_sel_premux_data, // Select the pre_muxed data
@ -41,47 +41,47 @@ module ifu_ic_mem
`ifdef RV_ICACHE_ECC
input logic [83:0] ic_wr_data, // Data to fill to the Icache. With ECC
output logic [167:0] ic_rd_data , // Data read from Icache. 2x64bits + parity bits. F2 stage. With ECC
output logic [24:0] ictag_debug_rd_data,// Debug icache tag.
input logic [41:0] ic_debug_wr_data, // Debug wr cache.
`else
output logic [24:0] ictag_debug_rd_data,// Debug icache tag.
input logic [41:0] ic_debug_wr_data, // Debug wr cache.
`else
input logic [67:0] ic_wr_data, // Data to fill to the Icache. With Parity
output logic [135:0] ic_rd_data , // Data read from Icache. 2x64bits + parity bits. F2 stage. With Parity
output logic [20:0] ictag_debug_rd_data,// Debug icache tag.
input logic [33:0] ic_debug_wr_data, // Debug wr cache.
output logic [20:0] ictag_debug_rd_data,// Debug icache tag.
input logic [33:0] ic_debug_wr_data, // Debug wr cache.
`endif
input logic [3:0] ic_tag_valid, // Valid from the I$ tag valid outside (in flops).
input logic [3:0] ic_tag_valid, // Valid from the I$ tag valid outside (in flops).
output logic [3:0] ic_rd_hit, // ic_rd_hit[3:0]
output logic ic_tag_perr, // Tag Parity error
input logic scan_mode
input logic scan_mode
) ;
`include "global.h"
`include "global.h"
IC_TAG #( .ICACHE_TAG_HIGH(ICACHE_TAG_HIGH) ,
.ICACHE_TAG_LOW(ICACHE_TAG_LOW) ,
.ICACHE_TAG_DEPTH(ICACHE_TAG_DEPTH)
.ICACHE_TAG_LOW(ICACHE_TAG_LOW) ,
.ICACHE_TAG_DEPTH(ICACHE_TAG_DEPTH)
) ic_tag_inst
(
.*,
.ic_wr_en (ic_wr_en[3:0]),
.ic_wr_en (ic_wr_en[3:0]),
.ic_debug_addr(ic_debug_addr[ICACHE_TAG_HIGH-1:2]),
.ic_rw_addr (ic_rw_addr[31:3])
) ;
IC_DATA #( .ICACHE_TAG_HIGH(ICACHE_TAG_HIGH) ,
.ICACHE_TAG_LOW(ICACHE_TAG_LOW) ,
.ICACHE_IC_DEPTH(ICACHE_IC_DEPTH)
.ICACHE_TAG_LOW(ICACHE_TAG_LOW) ,
.ICACHE_IC_DEPTH(ICACHE_IC_DEPTH)
) ic_data_inst
(
.*,
.ic_wr_en (ic_wr_en[3:0]),
.ic_wr_en (ic_wr_en[3:0]),
.ic_debug_addr(ic_debug_addr[ICACHE_TAG_HIGH-1:2]),
.ic_rw_addr (ic_rw_addr[ICACHE_TAG_HIGH-1:3])
) ;
endmodule
@ -89,9 +89,9 @@ module ifu_ic_mem
////// ICACHE DATA MODULE ////////////////////
/////////////////////////////////////////////////
module IC_DATA #(parameter ICACHE_TAG_HIGH = 16 ,
ICACHE_TAG_LOW=6 ,
ICACHE_IC_DEPTH=1024
)
ICACHE_TAG_LOW=6 ,
ICACHE_IC_DEPTH=1024
)
(
input logic clk,
input logic rst_l,
@ -103,28 +103,28 @@ module IC_DATA #(parameter ICACHE_TAG_HIGH = 16 ,
`ifdef RV_ICACHE_ECC
input logic [83:0] ic_wr_data, // Data to fill to the Icache. With ECC
output logic [167:0] ic_rd_data , // Data read from Icache. 2x64bits + parity bits. F2 stage. With ECC
input logic [41:0] ic_debug_wr_data, // Debug wr cache.
`else
input logic [41:0] ic_debug_wr_data, // Debug wr cache.
`else
input logic [67:0] ic_wr_data, // Data to fill to the Icache. With Parity
output logic [135:0] ic_rd_data , // Data read from Icache. 2x64bits + parity bits. F2 stage. With Parity
input logic [33:0] ic_debug_wr_data, // Debug wr cache.
input logic [33:0] ic_debug_wr_data, // Debug wr cache.
`endif
input logic [ICACHE_TAG_HIGH-1:2] ic_debug_addr, // Read/Write addresss to the Icache.
input logic [ICACHE_TAG_HIGH-1:2] ic_debug_addr, // Read/Write addresss to the Icache.
input logic ic_debug_rd_en, // Icache debug rd
input logic ic_debug_wr_en, // Icache debug wr
input logic ic_debug_tag_array, // Debug tag array
input logic [3:0] ic_debug_way, // Debug way. Rd or Wr.
input logic [127:0] ic_premux_data, // Premux data to be muxed with each way of the Icache.
input logic [127:0] ic_premux_data, // Premux data to be muxed with each way of the Icache.
input logic ic_sel_premux_data, // Select the pre_muxed data
input logic [3:0] ic_rd_hit,
input logic scan_mode
) ;
logic [5:4] ic_rw_addr_ff;
@ -135,17 +135,17 @@ module IC_DATA #(parameter ICACHE_TAG_HIGH = 16 ,
logic ic_debug_sel_sb2 ;
logic ic_debug_sel_sb3 ;
`ifdef RV_ICACHE_ECC
logic [3:0] [167:0] bank_set_dout;
logic [3:0][167:0] wb_dout ; //
logic [3:0][41:0] ic_sb_wr_data;
`else
logic [3:0] [135:0] bank_set_dout;
logic [3:0] [135:0] wb_dout ; // bank , way , size
logic [3:0] [135:0] wb_dout ; // bank , way , size
logic [3:0] [33:0] ic_sb_wr_data;
`endif
logic [3:0] ic_bank_way_clken; // bank , way
logic [3:0] ic_bank_way_clk ; // bank , way
logic ic_b_rden;
@ -153,74 +153,74 @@ module IC_DATA #(parameter ICACHE_TAG_HIGH = 16 ,
logic [3:0] ic_debug_rd_way_en_ff; // debug wr_way
logic [3:0] ic_debug_wr_way_en; // debug wr_way
logic [ICACHE_TAG_HIGH-1:4] ic_rw_addr_q;
assign ic_debug_rd_way_en[3:0] = {4{ic_debug_rd_en & ~ic_debug_tag_array}} & ic_debug_way[3:0] ;
assign ic_debug_wr_way_en[3:0] = {4{ic_debug_wr_en & ~ic_debug_tag_array}} & ic_debug_way[3:0] ;
assign ic_b_sb_wren[0][3:0] = (ic_wr_en[3:0] & {4{~ic_rw_addr[3]}} ) |
(ic_debug_wr_way_en[3:0] & {4{ic_debug_addr[3:2] == 2'b00}}) ;
assign ic_b_sb_wren[1][3:0] = (ic_wr_en[3:0] & {4{~ic_rw_addr[3]}} ) |
(ic_debug_wr_way_en[3:0] & {4{ic_debug_addr[3:2] == 2'b01}}) ;
assign ic_b_sb_wren[2][3:0] = (ic_wr_en[3:0] & {4{ic_rw_addr[3]}} ) |
(ic_debug_wr_way_en[3:0] & {4{ic_debug_addr[3:2] == 2'b10}}) ;
assign ic_b_sb_wren[3][3:0] = (ic_wr_en[3:0] & {4{ic_rw_addr[3]}} ) |
(ic_debug_wr_way_en[3:0] & {4{ic_debug_addr[3:2] == 2'b11}}) ;
assign ic_b_sb_wren[0][3:0] = (ic_wr_en[3:0] & {4{~ic_rw_addr[3]}} ) |
(ic_debug_wr_way_en[3:0] & {4{ic_debug_addr[3:2] == 2'b00}}) ;
assign ic_b_sb_wren[1][3:0] = (ic_wr_en[3:0] & {4{~ic_rw_addr[3]}} ) |
(ic_debug_wr_way_en[3:0] & {4{ic_debug_addr[3:2] == 2'b01}}) ;
assign ic_b_sb_wren[2][3:0] = (ic_wr_en[3:0] & {4{ic_rw_addr[3]}} ) |
(ic_debug_wr_way_en[3:0] & {4{ic_debug_addr[3:2] == 2'b10}}) ;
assign ic_b_sb_wren[3][3:0] = (ic_wr_en[3:0] & {4{ic_rw_addr[3]}} ) |
(ic_debug_wr_way_en[3:0] & {4{ic_debug_addr[3:2] == 2'b11}}) ;
assign ic_debug_sel_sb0 = (ic_debug_addr[3:2] == 2'b00 ) ;
assign ic_debug_sel_sb1 = (ic_debug_addr[3:2] == 2'b01 ) ;
assign ic_debug_sel_sb2 = (ic_debug_addr[3:2] == 2'b10 ) ;
assign ic_debug_sel_sb3 = (ic_debug_addr[3:2] == 2'b11 ) ;
assign ic_debug_sel_sb0 = (ic_debug_addr[3:2] == 2'b00 ) ;
assign ic_debug_sel_sb1 = (ic_debug_addr[3:2] == 2'b01 ) ;
assign ic_debug_sel_sb2 = (ic_debug_addr[3:2] == 2'b10 ) ;
assign ic_debug_sel_sb3 = (ic_debug_addr[3:2] == 2'b11 ) ;
`ifdef RV_ICACHE_ECC
assign ic_sb_wr_data[0][41:0] = (ic_debug_sel_sb0 & ic_debug_wr_en) ? {ic_debug_wr_data[41:0]} :
assign ic_sb_wr_data[0][41:0] = (ic_debug_sel_sb0 & ic_debug_wr_en) ? {ic_debug_wr_data[41:0]} :
ic_wr_data[41:0] ;
assign ic_sb_wr_data[1][41:0] = (ic_debug_sel_sb1 & ic_debug_wr_en) ? {ic_debug_wr_data[41:0]} :
assign ic_sb_wr_data[1][41:0] = (ic_debug_sel_sb1 & ic_debug_wr_en) ? {ic_debug_wr_data[41:0]} :
ic_wr_data[83:42] ;
assign ic_sb_wr_data[2][41:0] = (ic_debug_sel_sb2 & ic_debug_wr_en) ? {ic_debug_wr_data[41:0]} :
assign ic_sb_wr_data[2][41:0] = (ic_debug_sel_sb2 & ic_debug_wr_en) ? {ic_debug_wr_data[41:0]} :
ic_wr_data[41:0] ;
assign ic_sb_wr_data[3][41:0] = (ic_debug_sel_sb3 & ic_debug_wr_en) ? {ic_debug_wr_data[41:0]} :
assign ic_sb_wr_data[3][41:0] = (ic_debug_sel_sb3 & ic_debug_wr_en) ? {ic_debug_wr_data[41:0]} :
ic_wr_data[83:42] ;
`else
assign ic_sb_wr_data[0][33:0] = (ic_debug_sel_sb0 & ic_debug_wr_en) ? ic_debug_wr_data[33:0] :
`else
assign ic_sb_wr_data[0][33:0] = (ic_debug_sel_sb0 & ic_debug_wr_en) ? ic_debug_wr_data[33:0] :
ic_wr_data[33:0] ;
assign ic_sb_wr_data[1][33:0] = (ic_debug_sel_sb1 & ic_debug_wr_en) ? ic_debug_wr_data[33:0] :
assign ic_sb_wr_data[1][33:0] = (ic_debug_sel_sb1 & ic_debug_wr_en) ? ic_debug_wr_data[33:0] :
ic_wr_data[67:34] ;
assign ic_sb_wr_data[2][33:0] = (ic_debug_sel_sb2 & ic_debug_wr_en) ? ic_debug_wr_data[33:0] :
assign ic_sb_wr_data[2][33:0] = (ic_debug_sel_sb2 & ic_debug_wr_en) ? ic_debug_wr_data[33:0] :
ic_wr_data[33:0] ;
assign ic_sb_wr_data[3][33:0] = (ic_debug_sel_sb3 & ic_debug_wr_en) ? ic_debug_wr_data[33:0] :
assign ic_sb_wr_data[3][33:0] = (ic_debug_sel_sb3 & ic_debug_wr_en) ? ic_debug_wr_data[33:0] :
ic_wr_data[67:34] ;
`endif
// bank read enables
assign ic_b_rden = (ic_rd_en | ic_debug_rd_en );
assign ic_bank_way_clken[3:0] = ({4{ic_b_rden | clk_override }}) |
assign ic_b_rden = (ic_rd_en | ic_debug_rd_en );
assign ic_bank_way_clken[3:0] = ({4{ic_b_rden | clk_override }}) |
ic_b_sb_wren[0][3:0] |
ic_b_sb_wren[1][3:0] |
ic_b_sb_wren[2][3:0] |
ic_b_sb_wren[3][3:0] ;
assign ic_rw_addr_q[ICACHE_TAG_HIGH-1:4] = (ic_debug_rd_en | ic_debug_wr_en) ?
ic_debug_addr[ICACHE_TAG_HIGH-1:4] :
ic_debug_addr[ICACHE_TAG_HIGH-1:4] :
ic_rw_addr[ICACHE_TAG_HIGH-1:4] ;
logic ic_debug_rd_en_ff;
rvdff #(2) adr_ff (.*,
.din ({ic_rw_addr_q[5:4]}),
rvdff #(2) adr_ff (.*,
.din ({ic_rw_addr_q[5:4]}),
.dout({ic_rw_addr_ff[5:4]}));
rvdff #(5) debug_rd_wy_ff (.*,
.din ({ic_debug_rd_way_en[3:0], ic_debug_rd_en}),
rvdff #(5) debug_rd_wy_ff (.*,
.din ({ic_debug_rd_way_en[3:0], ic_debug_rd_en}),
.dout({ic_debug_rd_way_en_ff[3:0], ic_debug_rd_en_ff}));
localparam NUM_WAYS=4 ;
localparam NUM_SUBBANKS=4 ;
localparam NUM_SUBBANKS=4 ;
for (genvar i=0; i<NUM_WAYS; i++) begin: WAYS
@ -230,7 +230,7 @@ localparam NUM_SUBBANKS=4 ;
for (genvar k=0; k<NUM_SUBBANKS; k++) begin: SUBBANKS // 16B subbank
`ifdef RV_ICACHE_ECC
`RV_ICACHE_DATA_CELL ic_bank_sb_way_data (
`RV_ICACHE_DATA_CELL ic_bank_sb_way_data (
.CLK(ic_bank_way_clk[i]),
.WE (ic_b_sb_wren[k][i]),
.D (ic_sb_wr_data[k][41:0]),
@ -238,7 +238,7 @@ localparam NUM_SUBBANKS=4 ;
.Q (wb_dout[i][(k+1)*42-1:k*42])
);
`else
`RV_ICACHE_DATA_CELL ic_bank_sb_way_data (
`RV_ICACHE_DATA_CELL ic_bank_sb_way_data (
.CLK(ic_bank_way_clk[i]),
.WE (ic_b_sb_wren[k][i]),
.D (ic_sb_wr_data[k][33:0]),
@ -247,16 +247,16 @@ localparam NUM_SUBBANKS=4 ;
);
`endif
end // block: SUBBANKS
end
end
logic [3:0] ic_rd_hit_q;
assign ic_rd_hit_q[3:0] = ic_debug_rd_en_ff ? ic_debug_rd_way_en_ff[3:0] : ic_rd_hit[3:0] ;
// set mux
`ifdef RV_ICACHE_ECC
logic [167:0] ic_premux_data_ext;
logic [167:0] ic_premux_data_ext;
logic [3:0] [167:0] wb_dout_way;
logic [3:0] [167:0] wb_dout_way_with_premux;
@ -278,7 +278,7 @@ localparam NUM_SUBBANKS=4 ;
({168{ic_rd_hit_q[3] | ic_sel_premux_data}} & wb_dout_way_with_premux[3][167:0]) ;
`else
logic [135:0] ic_premux_data_ext;
logic [135:0] ic_premux_data_ext;
logic [3:0] [135:0] wb_dout_way;
logic [3:0] [135:0] wb_dout_way_with_premux;
@ -287,7 +287,7 @@ localparam NUM_SUBBANKS=4 ;
assign wb_dout_way[1][135:0] = wb_dout[1][135:0];
assign wb_dout_way[2][135:0] = wb_dout[2][135:0];
assign wb_dout_way[3][135:0] = wb_dout[3][135:0];
assign wb_dout_way_with_premux[0][135:0] = ic_sel_premux_data ? ic_premux_data_ext[135:0] : wb_dout_way[0][135:0] ;
assign wb_dout_way_with_premux[1][135:0] = ic_sel_premux_data ? ic_premux_data_ext[135:0] : wb_dout_way[1][135:0] ;
assign wb_dout_way_with_premux[2][135:0] = ic_sel_premux_data ? ic_premux_data_ext[135:0] : wb_dout_way[2][135:0] ;
@ -299,7 +299,7 @@ localparam NUM_SUBBANKS=4 ;
({136{ic_rd_hit_q[3] | ic_sel_premux_data}} & wb_dout_way_with_premux[3][135:0]) ;
`endif
endmodule
@ -307,22 +307,22 @@ localparam NUM_SUBBANKS=4 ;
////// ICACHE TAG MODULE ////////////////////
/////////////////////////////////////////////////
module IC_TAG #(parameter ICACHE_TAG_HIGH = 16 ,
ICACHE_TAG_LOW=6 ,
ICACHE_TAG_DEPTH=1024
)
ICACHE_TAG_LOW=6 ,
ICACHE_TAG_DEPTH=1024
)
(
input logic clk,
input logic rst_l,
input logic clk_override,
input logic dec_tlu_core_ecc_disable,
input logic dec_tlu_core_ecc_disable,
input logic [31:3] ic_rw_addr,
input logic [3:0] ic_wr_en, // way
input logic [3:0] ic_tag_valid,
input logic ic_rd_en,
input logic [ICACHE_TAG_HIGH-1:2] ic_debug_addr, // Read/Write addresss to the Icache.
input logic [ICACHE_TAG_HIGH-1:2] ic_debug_addr, // Read/Write addresss to the Icache.
input logic ic_debug_rd_en, // Icache debug rd
input logic ic_debug_wr_en, // Icache debug wr
input logic ic_debug_tag_array, // Debug tag array
@ -330,20 +330,20 @@ module IC_TAG #(parameter ICACHE_TAG_HIGH = 16 ,
`ifdef RV_ICACHE_ECC
output logic [24:0] ictag_debug_rd_data,
input logic [41:0] ic_debug_wr_data, // Debug wr cache.
input logic [41:0] ic_debug_wr_data, // Debug wr cache.
`else
output logic [20:0] ictag_debug_rd_data,
input logic [33:0] ic_debug_wr_data, // Debug wr cache.
input logic [33:0] ic_debug_wr_data, // Debug wr cache.
`endif
output logic [3:0] ic_rd_hit,
output logic ic_tag_perr,
input logic scan_mode
output logic ic_tag_perr,
input logic scan_mode
) ;
`ifdef RV_ICACHE_ECC
logic [3:0] [24:0] ic_tag_data_raw;
logic [3:0] [37:ICACHE_TAG_HIGH] w_tout;
@ -370,78 +370,78 @@ module IC_TAG #(parameter ICACHE_TAG_HIGH = 16 ,
logic [3:0] ic_tag_clken ;
logic [3:0] ic_debug_wr_way_en; // debug wr_way
assign ic_tag_wren [3:0] = ic_wr_en[3:0] & {4{ic_rw_addr[5:3] == 3'b111}} ;
assign ic_tag_wren [3:0] = ic_wr_en[3:0] & {4{ic_rw_addr[5:3] == 3'b111}} ;
assign ic_tag_clken[3:0] = {4{ic_rd_en | clk_override}} | ic_wr_en[3:0] | ic_debug_wr_way_en[3:0] | ic_debug_rd_way_en[3:0];
rvdff #(32-ICACHE_TAG_HIGH) adr_ff (.*,
.din ({ic_rw_addr[31:ICACHE_TAG_HIGH]}),
rvdff #(32-ICACHE_TAG_HIGH) adr_ff (.*,
.din ({ic_rw_addr[31:ICACHE_TAG_HIGH]}),
.dout({ic_rw_addr_ff[31:ICACHE_TAG_HIGH]}));
localparam TOP_BITS = 21+ICACHE_TAG_HIGH-33 ;
localparam NUM_WAYS=4 ;
// tags
// tags
assign ic_debug_rd_way_en[3:0] = {4{ic_debug_rd_en & ic_debug_tag_array}} & ic_debug_way[3:0] ;
assign ic_debug_wr_way_en[3:0] = {4{ic_debug_wr_en & ic_debug_tag_array}} & ic_debug_way[3:0] ;
assign ic_tag_wren_q[3:0] = ic_tag_wren[3:0] |
assign ic_tag_wren_q[3:0] = ic_tag_wren[3:0] |
ic_debug_wr_way_en[3:0] ;
if (ICACHE_TAG_HIGH == 12) begin: SMALLEST
`ifdef RV_ICACHE_ECC
logic [6:0] ic_tag_ecc;
rvecc_encode tag_ecc_encode (
.din ({{ICACHE_TAG_HIGH{1'b0}}, ic_rw_addr[31:ICACHE_TAG_HIGH]}),
.ecc_out({ ic_tag_ecc[6:0]}));
.din ({{ICACHE_TAG_HIGH{1'b0}}, ic_rw_addr[31:ICACHE_TAG_HIGH]}),
.ecc_out({ ic_tag_ecc[6:0]}));
assign ic_tag_wr_data[24:0] = (ic_debug_wr_en & ic_debug_tag_array) ?
{ic_debug_wr_data[36:32], ic_debug_wr_data[31:12]} :
assign ic_tag_wr_data[24:0] = (ic_debug_wr_en & ic_debug_tag_array) ?
{ic_debug_wr_data[36:32], ic_debug_wr_data[31:12]} :
{ic_tag_ecc[4:0], ic_rw_addr[31:ICACHE_TAG_HIGH]} ;
`else
logic ic_tag_parity ;
rveven_paritygen #(32-ICACHE_TAG_HIGH) pargen (.data_in (ic_rw_addr[31:ICACHE_TAG_HIGH]),
.parity_out(ic_tag_parity));
logic ic_tag_parity ;
rveven_paritygen #(32-ICACHE_TAG_HIGH) pargen (.data_in (ic_rw_addr[31:ICACHE_TAG_HIGH]),
.parity_out(ic_tag_parity));
assign ic_tag_wr_data[20:0] = (ic_debug_wr_en & ic_debug_tag_array) ?
{ic_debug_wr_data[32], ic_debug_wr_data[31:12]} :
assign ic_tag_wr_data[20:0] = (ic_debug_wr_en & ic_debug_tag_array) ?
{ic_debug_wr_data[32], ic_debug_wr_data[31:12]} :
{ic_tag_parity, ic_rw_addr[31:ICACHE_TAG_HIGH]} ;
`endif
end else begin: OTHERS
`ifdef RV_ICACHE_ECC
logic [6:0] ic_tag_ecc;
rvecc_encode tag_ecc_encode (
.din ({{ICACHE_TAG_HIGH{1'b0}}, ic_rw_addr[31:ICACHE_TAG_HIGH]}),
.ecc_out({ ic_tag_ecc[6:0]}));
.din ({{ICACHE_TAG_HIGH{1'b0}}, ic_rw_addr[31:ICACHE_TAG_HIGH]}),
.ecc_out({ ic_tag_ecc[6:0]}));
assign ic_tag_wr_data[24:0] = (ic_debug_wr_en & ic_debug_tag_array) ?
{ic_debug_wr_data[36:32], ic_debug_wr_data[31:12]} :
assign ic_tag_wr_data[24:0] = (ic_debug_wr_en & ic_debug_tag_array) ?
{ic_debug_wr_data[36:32], ic_debug_wr_data[31:12]} :
{ic_tag_ecc[4:0], {TOP_BITS{1'b0}},ic_rw_addr[31:ICACHE_TAG_HIGH]} ;
`else
logic ic_tag_parity ;
rveven_paritygen #(32-ICACHE_TAG_HIGH) pargen (.data_in (ic_rw_addr[31:ICACHE_TAG_HIGH]),
.parity_out(ic_tag_parity));
assign ic_tag_wr_data[20:0] = (ic_debug_wr_en & ic_debug_tag_array) ?
{ic_debug_wr_data[32], ic_debug_wr_data[31:12]} :
logic ic_tag_parity ;
rveven_paritygen #(32-ICACHE_TAG_HIGH) pargen (.data_in (ic_rw_addr[31:ICACHE_TAG_HIGH]),
.parity_out(ic_tag_parity));
assign ic_tag_wr_data[20:0] = (ic_debug_wr_en & ic_debug_tag_array) ?
{ic_debug_wr_data[32], ic_debug_wr_data[31:12]} :
{ic_tag_parity, {TOP_BITS{1'b0}},ic_rw_addr[31:ICACHE_TAG_HIGH]} ;
`endif
end
assign ic_rw_addr_q[ICACHE_TAG_HIGH-1:6] = (ic_debug_rd_en | ic_debug_wr_en) ?
ic_debug_addr[ICACHE_TAG_HIGH-1:6] :
ic_debug_addr[ICACHE_TAG_HIGH-1:6] :
ic_rw_addr[ICACHE_TAG_HIGH-1:6] ;
rvdff #(4) tag_rd_wy_ff (.*,
.din ({ic_debug_rd_way_en[3:0]}),
rvdff #(4) tag_rd_wy_ff (.*,
.din ({ic_debug_rd_way_en[3:0]}),
.dout({ic_debug_rd_way_en_ff[3:0]}));
for (genvar i=0; i<NUM_WAYS; i++) begin: WAYS
rvclkhdr ic_tag_c1_cgc ( .en(ic_tag_clken[i]), .l1clk(ic_tag_clk[i]), .* );
if (ICACHE_TAG_DEPTH == 64 ) begin : ICACHE_SZ_16
@ -453,13 +453,13 @@ end
.ADR(ic_rw_addr_q[ICACHE_TAG_HIGH-1:ICACHE_TAG_LOW]),
.Q (ic_tag_data_raw[i][24:0])
);
assign w_tout[i][31:ICACHE_TAG_HIGH] = ic_tag_data_raw[i][31-ICACHE_TAG_HIGH:0] ;
assign w_tout[i][36:32] = ic_tag_data_raw[i][24:20] ;
rvecc_decode ecc_decode (
.en(~dec_tlu_core_ecc_disable),
.en(~dec_tlu_core_ecc_disable),
.sed_ded ( 1'b1 ), // 1 : means only detection
.din({12'b0,ic_tag_data_raw[i][19:0]}),
.ecc_in({2'b0, ic_tag_data_raw[i][24:20]}),
@ -481,14 +481,14 @@ end
assign w_tout[i][31:ICACHE_TAG_HIGH] = ic_tag_data_raw[i][31-ICACHE_TAG_HIGH:0] ;
assign w_tout[i][32] = ic_tag_data_raw[i][20] ;
rveven_paritycheck #(32-ICACHE_TAG_HIGH) parcheck(.data_in (w_tout[i][31:ICACHE_TAG_HIGH]),
rveven_paritycheck #(32-ICACHE_TAG_HIGH) parcheck(.data_in (w_tout[i][31:ICACHE_TAG_HIGH]),
.parity_in (w_tout[i][32]),
.parity_err(ic_tag_way_perr[i]));
.parity_err(ic_tag_way_perr[i]));
`endif
end // block: ICACHE_SZ_16
else begin : tag_not_64
else begin : tag_not_64
`ifdef RV_ICACHE_ECC
`RV_ICACHE_TAG_CELL ic_way_tag (
.CLK(ic_tag_clk[i]),
@ -503,7 +503,7 @@ end
rvecc_decode ecc_decode (
.en(~dec_tlu_core_ecc_disable),
.sed_ded ( 1'b1 ), // 1 : if only need detection
.sed_ded ( 1'b1 ), // 1 : if only need detection
.din({12'b0,ic_tag_data_raw[i][19:0]}),
.ecc_in({2'b0, ic_tag_data_raw[i][24:20]}),
.dout(ic_tag_corrected_data_unc[i][31:0]),
@ -525,27 +525,27 @@ end
assign w_tout[i][31:ICACHE_TAG_HIGH] = ic_tag_data_raw[i][31-ICACHE_TAG_HIGH:0] ;
assign w_tout[i][32] = ic_tag_data_raw[i][20] ;
rveven_paritycheck #(32-ICACHE_TAG_HIGH) parcheck(.data_in (w_tout[i][31:ICACHE_TAG_HIGH]),
rveven_paritycheck #(32-ICACHE_TAG_HIGH) parcheck(.data_in (w_tout[i][31:ICACHE_TAG_HIGH]),
.parity_in (w_tout[i][32]),
.parity_err(ic_tag_way_perr[i]));
.parity_err(ic_tag_way_perr[i]));
`endif
end // block: tag_not_64
end // block: WAYS
`ifdef RV_ICACHE_ECC
assign ictag_debug_rd_data[24:0] = ({25{ic_debug_rd_way_en_ff[0]}} & ic_tag_data_raw[0] ) |
({25{ic_debug_rd_way_en_ff[1]}} & ic_tag_data_raw[1] ) |
({25{ic_debug_rd_way_en_ff[2]}} & ic_tag_data_raw[2] ) |
({25{ic_debug_rd_way_en_ff[3]}} & ic_tag_data_raw[3] ) ;
`else
`else
assign ictag_debug_rd_data[20:0] = ({21{ic_debug_rd_way_en_ff[0]}} & ic_tag_data_raw[0] ) |
({21{ic_debug_rd_way_en_ff[1]}} & ic_tag_data_raw[1] ) |
({21{ic_debug_rd_way_en_ff[2]}} & ic_tag_data_raw[2] ) |
({21{ic_debug_rd_way_en_ff[3]}} & ic_tag_data_raw[3] ) ;
`endif
assign ic_rd_hit[0] = (w_tout[0][31:ICACHE_TAG_HIGH] == ic_rw_addr_ff[31:ICACHE_TAG_HIGH]) & ic_tag_valid[0];
assign ic_rd_hit[1] = (w_tout[1][31:ICACHE_TAG_HIGH] == ic_rw_addr_ff[31:ICACHE_TAG_HIGH]) & ic_tag_valid[1];

View File

@ -16,10 +16,10 @@
//********************************************************************************
//********************************************************************************
// Icache closely coupled memory --- ICCM
// Icache closely coupled memory --- ICCM
//********************************************************************************
module ifu_iccm_mem
module ifu_iccm_mem
import swerv_types::*;
(
@ -29,18 +29,18 @@ module ifu_iccm_mem
input logic iccm_wren,
input logic iccm_rden,
input logic [`RV_ICCM_BITS-1:2] iccm_rw_addr,
input logic [`RV_ICCM_BITS-1:2] iccm_rw_addr,
input logic [2:0] iccm_wr_size,
input logic [77:0] iccm_wr_data,
output logic [155:0] iccm_rd_data,
input logic scan_mode
);
`include "global.h"
`include "global.h"
logic [ICCM_NUM_BANKS/4-1:0] wren_bank;
@ -60,36 +60,36 @@ module ifu_iccm_mem
logic [ICCM_NUM_BANKS/4-1:0] wren_bank_hi1;
logic [ICCM_NUM_BANKS/4-1:0] wren_bank_lo1;
logic [ICCM_NUM_BANKS/4-1:0] [ICCM_INDEX_BITS-1:0] addr_bank;
logic [ICCM_NUM_BANKS/4-1:0] [77:0] iccm_bank_dout_hi;
logic [ICCM_NUM_BANKS/4-1:0] [77:0] iccm_bank_dout_lo;
logic [ICCM_NUM_BANKS/4-1:0] [77:0] iccm_bank_dout_lo;
logic [5:4] iccm_rw_addr_q;
// assign CLK = clk ;
// assign CLK = clk ;
for (genvar i=0; i<ICCM_NUM_BANKS/4; i++) begin: mem_bank
assign wren_bank[i] = iccm_wren & ( (iccm_rw_addr[ICCM_BANK_HI:4] == i) | (ICCM_BANK_BITS == 2));
assign rden_bank[i] = iccm_rden & ( (iccm_rw_addr[ICCM_BANK_HI:4] == i) | (ICCM_BANK_BITS == 2));
for (genvar i=0; i<ICCM_NUM_BANKS/4; i++) begin: mem_bank
assign wren_bank[i] = iccm_wren & ( (iccm_rw_addr[ICCM_BANK_HI:4] == i) | (ICCM_BANK_BITS == 2));
assign rden_bank[i] = iccm_rden & ( (iccm_rw_addr[ICCM_BANK_HI:4] == i) | (ICCM_BANK_BITS == 2));
assign wren_bank_hi0[i] = wren_bank[i] & iccm_rw_addr[3] & (~iccm_rw_addr[2] | (iccm_wr_size[1:0] == 2'b11));
assign wren_bank_hi1[i] = wren_bank[i] & iccm_rw_addr[3] & ( iccm_rw_addr[2] | (iccm_wr_size[1:0] == 2'b11));
assign wren_bank_lo0[i] = wren_bank[i] & ~iccm_rw_addr[3] & (~iccm_rw_addr[2] | (iccm_wr_size[1:0] == 2'b11));
assign wren_bank_lo1[i] = wren_bank[i] & ~iccm_rw_addr[3] & ( iccm_rw_addr[2] | (iccm_wr_size[1:0] == 2'b11));
assign iccm_hi0_clken[i] = wren_bank_hi0[i] | (rden_bank[i] | clk_override); // Do not override the writes
assign iccm_hi1_clken[i] = wren_bank_hi1[i] | (rden_bank[i] | clk_override); // Do not override the writes
assign iccm_lo0_clken[i] = wren_bank_lo0[i] | (rden_bank[i] | clk_override); // Do not override the writes
assign iccm_lo1_clken[i] = wren_bank_lo1[i] | (rden_bank[i] | clk_override); // Do not override the writes
assign iccm_hi0_clken[i] = wren_bank_hi0[i] | (rden_bank[i] | clk_override); // Do not override the writes
assign iccm_hi1_clken[i] = wren_bank_hi1[i] | (rden_bank[i] | clk_override); // Do not override the writes
assign iccm_lo0_clken[i] = wren_bank_lo0[i] | (rden_bank[i] | clk_override); // Do not override the writes
assign iccm_lo1_clken[i] = wren_bank_lo1[i] | (rden_bank[i] | clk_override); // Do not override the writes
rvoclkhdr iccm_hi0_c1_cgc ( .en(iccm_hi0_clken[i]), .l1clk(iccm_hi0_clk[i]), .* );
rvoclkhdr iccm_hi1_c1_cgc ( .en(iccm_hi1_clken[i]), .l1clk(iccm_hi1_clk[i]), .* );
rvoclkhdr iccm_lo0_c1_cgc ( .en(iccm_lo0_clken[i]), .l1clk(iccm_lo0_clk[i]), .* );
rvoclkhdr iccm_lo1_c1_cgc ( .en(iccm_lo1_clken[i]), .l1clk(iccm_lo1_clk[i]), .* );
assign addr_bank[i][ICCM_INDEX_BITS-1:0] = iccm_rw_addr[ICCM_BITS-1:(ICCM_BANK_BITS+2)];
`RV_ICCM_DATA_CELL iccm_bank_hi0 (
// Primary ports
.CLK(iccm_hi0_clk[i]),
@ -122,20 +122,20 @@ module ifu_iccm_mem
.D(iccm_wr_data[77:39]),
.Q(iccm_bank_dout_lo[i][77:39])
);
end : mem_bank
assign iccm_rd_data[155:0] = (ICCM_BANK_BITS == 2) ? {iccm_bank_dout_hi[0][77:0], iccm_bank_dout_lo[0][77:0]} :
{ iccm_bank_dout_hi[iccm_rw_addr_q[ICCM_BANK_HI:4]][77:0], iccm_bank_dout_lo[iccm_rw_addr_q[ICCM_BANK_HI:4]][77:0] };
if (ICCM_BANK_BITS == 2) begin
assign iccm_rw_addr_q[5:4] = '0;
end
end
// 8 banks, each bank 8B, we index as 4 banks
else begin
else begin
rvdff #(2) rd_addr_ff (.*, .din(iccm_rw_addr[5:4]), .dout(iccm_rw_addr_q[5:4]) );
end
endmodule // ifu_iccm_mem

View File

@ -1,12 +1,12 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright 2019 Western Digital Corporation or its affiliates.
//
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//
// http://www.apache.org/licenses/LICENSE-2.0
//
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -14,7 +14,7 @@
// limitations under the License.
//********************************************************************************
// ifu_ifc_ctl.sv
// ifu_ifc_ctl.sv
// Function: Fetch pipe control
//
// Comments:
@ -25,7 +25,7 @@ module ifu_ifc_ctl
input logic clk,
input logic free_clk,
input logic active_clk,
input logic clk_override, // overrides clock gating
input logic rst_l, // reset enable, from core pin
input logic scan_mode, // scan
@ -33,7 +33,7 @@ module ifu_ifc_ctl
input logic ic_hit_f2, // Icache hit
input logic ic_crit_wd_rdy, // Crit word ready to be forwarded
input logic ifu_ic_mb_empty, // Miss buffer empty
input logic ifu_fb_consume1, // Aligner consumed 1 fetch buffer
input logic ifu_fb_consume2, // Aligner consumed 2 fetch buffers
@ -66,16 +66,16 @@ module ifu_ifc_ctl
output logic ifc_iccm_access_f1, // fetch to ICCM region
output logic ifc_region_acc_fault_f1, // fetch access fault
output logic ifc_dma_access_ok // fetch is not accessing the ICCM, DMA can proceed
);
logic [31:1] fetch_addr_bf, miss_addr, ifc_fetch_addr_f1_raw;
logic [31:1] fetch_addr_next;
logic [31:1] miss_addr_ns;
logic [4:0] cacheable_select;
logic [3:0] fb_write_f1, fb_write_ns;
logic ifc_fetch_req_bf;
logic overflow_nc;
logic fb_full_f1_ns, fb_full_f1;
@ -106,7 +106,7 @@ module ifu_ifc_ctl
logic dma_stall;
assign dma_stall = ic_dma_active | dma_iccm_stall_any_f;
// detect a reset and start fetching the reset vector
rvdff #(2) reset_ff (.*, .clk(free_clk), .din({1'b1, reset_detect}), .dout({reset_detect, reset_detected}));
@ -119,19 +119,19 @@ module ifu_ifc_ctl
// For Ifills, we fetch the critical word. Needed for perf and for rom bypass
assign fetch_crit_word = ic_crit_wd_rdy_mod & ~ic_crit_wd_rdy_d1 & ~exu_flush_final & ~ic_write_stall;
assign missff_en = exu_flush_final | (~ic_hit_f2 & ifc_fetch_req_f2) | ifu_bp_kill_next_f2 | fetch_crit_word_d1 | ifu_bp_kill_next_f2 | (ifc_fetch_req_f2 & ~ifc_fetch_req_f1 & ~fetch_crit_word_d2);
assign miss_sel_flush = exu_flush_final & (((wfm | idle) & ~fetch_crit_word_d1) | dma_stall | ic_write_stall);
assign miss_sel_f2 = ~exu_flush_final & ~ic_hit_f2 & ifc_fetch_req_f2;
assign miss_sel_f1 = ~exu_flush_final & ~miss_sel_f2 & ~ifc_fetch_req_f1 & ifc_fetch_req_f2 & ~fetch_crit_word_d2 & ~ifu_bp_kill_next_f2;
assign miss_sel_bf = ~miss_sel_f2 & ~miss_sel_f1 & ~miss_sel_flush;
assign miss_addr_ns[31:1] = ( ({31{miss_sel_flush}} & exu_flush_path_final[31:1]) |
({31{miss_sel_f2}} & ifc_fetch_addr_f2[31:1]) |
({31{miss_sel_f1}} & ifc_fetch_addr_f1[31:1]) |
({31{miss_sel_bf}} & fetch_addr_bf[31:1]));
rvdffe #(31) faddmiss_ff (.*, .en(missff_en), .din(miss_addr_ns[31:1]), .dout(miss_addr[31:1]));
@ -146,7 +146,7 @@ module ifu_ifc_ctl
assign sel_btb_addr_bf = ~miss_sel_flush & ifu_bp_kill_next_f2;
assign sel_next_addr_bf = ~miss_sel_flush & ifc_fetch_req_f1;
assign fetch_addr_bf[31:1] = ( ({31{miss_sel_flush}} & exu_flush_path_final[31:1]) | // FLUSH path
({31{sel_miss_addr_bf}} & miss_addr[31:1]) | // MISS path
({31{sel_btb_addr_bf}} & {ifu_bp_btb_target_f2[31:1]})| // BTB target
@ -159,14 +159,14 @@ module ifu_ifc_ctl
assign fetch_bf_en = (fetch_ns | fetch_crit_word);
assign miss_f2 = ifc_fetch_req_f2 & ~ic_hit_f2;
assign mb_empty_mod = (ifu_ic_mb_empty | exu_flush_final) & ~dma_stall & ~miss_f2 & ~miss_a;
// Halt flushes and takes us to IDLE
assign goto_idle = exu_flush_final & dec_tlu_flush_noredir_wb;
// If we're in IDLE, and we get a flush, goto FETCH
assign leave_idle = exu_flush_final & ~dec_tlu_flush_noredir_wb & idle;
//.i 7
//.o 2
//.ilb state[1] state[0] reset_delayed miss_f2 mb_empty_mod goto_idle leave_idle
@ -178,26 +178,26 @@ module ifu_ifc_ctl
//-- 0--1- 00
//00 0--00 00
//00 0--01 01
//
//
//01 01-0- 11
//01 00-0- 01
//
//
//11 0-10- 01
//11 0-00- 11
assign next_state[1] = (~state[1] & state[0] & ~reset_delayed & miss_f2 & ~goto_idle) |
assign next_state[1] = (~state[1] & state[0] & ~reset_delayed & miss_f2 & ~goto_idle) |
(state[1] & ~reset_delayed & ~mb_empty_mod & ~goto_idle);
assign next_state[0] = (~goto_idle & leave_idle) | (state[0] & ~goto_idle) |
assign next_state[0] = (~goto_idle & leave_idle) | (state[0] & ~goto_idle) |
(reset_delayed);
assign flush_fb = exu_flush_final;
// model fb write logic to mass balance the fetch buffers
assign fb_right = (~ifu_fb_consume1 & ~ifu_fb_consume2 & miss_f2) | // F2 cache miss, repair mass balance
assign fb_right = (~ifu_fb_consume1 & ~ifu_fb_consume2 & miss_f2) | // F2 cache miss, repair mass balance
( ifu_fb_consume1 & ~ifu_fb_consume2 & ~ifc_fetch_req_f1 & ~miss_f2) | // Consumed and no new fetch
(ifu_fb_consume2 & ifc_fetch_req_f1 & ~miss_f2); // Consumed 2 and new fetch
assign fb_right2 = (ifu_fb_consume1 & ~ifu_fb_consume2 & miss_f2) | // consume 1 and miss 1
(ifu_fb_consume2 & ~ifc_fetch_req_f1); // Consumed 2 and no new fetch
@ -205,7 +205,7 @@ module ifu_ifc_ctl
assign fb_right3 = (ifu_fb_consume2 & miss_f2); // consume 2 and miss
assign fb_left = ifc_fetch_req_f1 & ~(ifu_fb_consume1 | ifu_fb_consume2) & ~miss_f2;
assign fb_write_ns[3:0] = ( ({4{(flush_fb & ~ifc_fetch_req_f1)}} & 4'b0001) |
({4{(flush_fb & ifc_fetch_req_f1)}} & 4'b0010) |
({4{~flush_fb & fb_right }} & {1'b0, fb_write_f1[3:1]}) |
@ -213,28 +213,28 @@ module ifu_ifc_ctl
({4{~flush_fb & fb_right3}} & {3'b0, fb_write_f1[3]} ) |
({4{~flush_fb & fb_left }} & {fb_write_f1[2:0], 1'b0}) |
({4{~flush_fb & ~fb_right & ~fb_right2 & ~fb_left & ~fb_right3}} & fb_write_f1[3:0]));
assign fb_full_f1_ns = fb_write_ns[3];
assign idle = state[1:0] == IDLE;
assign wfm = state[1:0] == WFM;
assign fetch_ns = next_state[1:0] == FETCH;
rvdff #(2) fsm_ff (.*, .clk(active_clk), .din({next_state[1:0]}), .dout({state[1:0]}));
rvdff #(5) fbwrite_ff (.*, .clk(active_clk), .din({fb_full_f1_ns, fb_write_ns[3:0]}), .dout({fb_full_f1, fb_write_f1[3:0]}));
assign ifu_pmu_fetch_stall = wfm |
(ifc_fetch_req_f1_raw &
assign ifu_pmu_fetch_stall = wfm |
(ifc_fetch_req_f1_raw &
( (fb_full_f1 & ~(ifu_fb_consume2 | ifu_fb_consume1 | exu_flush_final)) |
dma_stall));
// BTB hit kills this fetch
assign ifc_fetch_req_f1 = ( ifc_fetch_req_f1_raw &
~ifu_bp_kill_next_f2 &
~(fb_full_f1 & ~(ifu_fb_consume2 | ifu_fb_consume1 | exu_flush_final)) &
assign ifc_fetch_req_f1 = ( ifc_fetch_req_f1_raw &
~ifu_bp_kill_next_f2 &
~(fb_full_f1 & ~(ifu_fb_consume2 | ifu_fb_consume1 | exu_flush_final)) &
~dma_stall &
~ic_write_stall &
~dec_tlu_flush_noredir_wb );
~dec_tlu_flush_noredir_wb );
// kill F2 request if we flush or if the prior fetch missed the cache/mem
assign fetch_req_f2_ns = ifc_fetch_req_f1 & ~miss_f2;
@ -242,34 +242,34 @@ module ifu_ifc_ctl
rvdff #(2) req_ff (.*, .clk(active_clk), .din({ifc_fetch_req_bf, fetch_req_f2_ns}), .dout({ifc_fetch_req_f1_raw, ifc_fetch_req_f2_raw}));
assign ifc_fetch_req_f2 = ifc_fetch_req_f2_raw & ~exu_flush_final;
rvdffe #(31) faddrf1_ff (.*, .en(fetch_bf_en), .din(fetch_addr_bf[31:1]), .dout(ifc_fetch_addr_f1_raw[31:1]));
rvdff #(31) faddrf2_ff (.*, .clk(ifc_f2_clk), .din(ifc_fetch_addr_f1[31:1]), .dout(ifc_fetch_addr_f2[31:1]));
assign ifc_fetch_addr_f1[31:1] = ( ({31{exu_flush_final}} & exu_flush_path_final[31:1]) |
({31{~exu_flush_final}} & ifc_fetch_addr_f1_raw[31:1]));
({31{~exu_flush_final}} & ifc_fetch_addr_f1_raw[31:1]));
rvdff #(3) iccrit_ff (.*, .clk(active_clk), .din({ic_crit_wd_rdy_mod, fetch_crit_word, fetch_crit_word_d1}),
rvdff #(3) iccrit_ff (.*, .clk(active_clk), .din({ic_crit_wd_rdy_mod, fetch_crit_word, fetch_crit_word_d1}),
.dout({ic_crit_wd_rdy_d1, fetch_crit_word_d1, fetch_crit_word_d2}));
`ifdef RV_ICCM_ENABLE
logic iccm_acc_in_region_f1;
logic iccm_acc_in_range_f1;
rvrangecheck #( .CCM_SADR (`RV_ICCM_SADR),
.CCM_SIZE (`RV_ICCM_SIZE) ) iccm_rangecheck (
.addr ({ifc_fetch_addr_f1[31:1],1'b0}) ,
.in_range (iccm_acc_in_range_f1) ,
.CCM_SIZE (`RV_ICCM_SIZE) ) iccm_rangecheck (
.addr ({ifc_fetch_addr_f1[31:1],1'b0}) ,
.in_range (iccm_acc_in_range_f1) ,
.in_region(iccm_acc_in_region_f1)
);
assign ifc_iccm_access_f1 = iccm_acc_in_range_f1 ;
assign ifc_iccm_access_f1 = iccm_acc_in_range_f1 ;
assign ifc_dma_access_ok = ( (~ifc_iccm_access_f1 |
(fb_full_f1 & ~(ifu_fb_consume2 | ifu_fb_consume1)) |
wfm |
assign ifc_dma_access_ok = ( (~ifc_iccm_access_f1 |
(fb_full_f1 & ~(ifu_fb_consume2 | ifu_fb_consume1)) |
wfm |
idle ) & ~exu_flush_final) |
dma_iccm_stall_any_f;
assign ifc_region_acc_fault_f1 = ~iccm_acc_in_range_f1 & iccm_acc_in_region_f1 ;
`else
assign ifc_iccm_access_f1 = 1'b0 ;
@ -279,6 +279,6 @@ module ifu_ifc_ctl
assign cacheable_select[4:0] = {ifc_fetch_addr_f1[31:28] , 1'b0 } ;
assign ifc_fetch_uncacheable_f1 = ~dec_tlu_mrac_ff[cacheable_select] ; // bit 0 of each region description is the cacheable bit
endmodule // ifu_ifc_ctl

File diff suppressed because it is too large Load Diff

View File

@ -1,12 +1,12 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright 2019 Western Digital Corporation or its affiliates.
//
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//
// http://www.apache.org/licenses/LICENSE-2.0
//
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

View File

@ -1,12 +1,12 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright 2019 Western Digital Corporation or its affiliates.
//
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//
// http://www.apache.org/licenses/LICENSE-2.0
//
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -38,14 +38,14 @@ localparam ICCM_INDEX_BITS = `RV_ICCM_INDEX_BITS;
localparam ICCM_BANK_HI = 4 + (`RV_ICCM_BANK_BITS/4);
localparam ICACHE_TAG_HIGH = `RV_ICACHE_TAG_HIGH;
localparam ICACHE_TAG_LOW = `RV_ICACHE_TAG_LOW;
localparam ICACHE_IC_DEPTH = `RV_ICACHE_IC_DEPTH;
localparam ICACHE_TAG_LOW = `RV_ICACHE_TAG_LOW;
localparam ICACHE_IC_DEPTH = `RV_ICACHE_IC_DEPTH;
localparam ICACHE_TAG_DEPTH = `RV_ICACHE_TAG_DEPTH;
localparam LSU_BUS_TAG = `RV_LSU_BUS_TAG;
localparam DMA_BUS_TAG = `RV_DMA_BUS_TAG;
localparam SB_BUS_TAG = `RV_SB_BUS_TAG;
localparam IFU_BUS_TAG = `RV_IFU_BUS_TAG;

View File

@ -1,12 +1,12 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright 2019 Western Digital Corporation or its affiliates.
//
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//
// http://www.apache.org/licenses/LICENSE-2.0
//
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -18,18 +18,18 @@ package swerv_types;
typedef struct packed {
logic [2:0] trace_rv_i_valid_ip;
logic [95:0] trace_rv_i_insn_ip;
logic [95:0] trace_rv_i_address_ip;
logic [95:0] trace_rv_i_address_ip;
logic [2:0] trace_rv_i_exception_ip;
logic [4:0] trace_rv_i_ecause_ip;
logic [2:0] trace_rv_i_interrupt_ip;
logic [4:0] trace_rv_i_ecause_ip;
logic [2:0] trace_rv_i_interrupt_ip;
logic [31:0] trace_rv_i_tval_ip;
} trace_pkt_t;
typedef enum logic [3:0] {
NULL = 4'b0000,
MUL = 4'b0001,
LOAD = 4'b0010,
MUL = 4'b0001,
LOAD = 4'b0010,
STORE = 4'b0011,
ALU = 4'b0100,
CSRREAD = 4'b0101,
@ -45,7 +45,7 @@ typedef enum logic [3:0] {
} inst_t;
typedef struct packed {
`ifdef RV_ICACHE_ECC
`ifdef RV_ICACHE_ECC
logic [39:0] ecc;
`else
logic [7:0] parity;
@ -103,15 +103,15 @@ typedef struct packed {
} br_tlu_pkt_t;
typedef struct packed {
logic misp;
logic misp;
logic ataken;
logic boffset;
logic boffset;
logic pc4;
logic [1:0] hist;
logic [1:0] hist;
logic [11:0] toffset;
logic [`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO] index;
logic [1:0] bank;
logic valid;
logic [`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO] index;
logic [1:0] bank;
logic valid;
logic br_error;
logic br_start_error;
logic [31:1] prett;
@ -130,7 +130,7 @@ typedef struct packed {
typedef struct packed {
logic legal;
logic icaf;
logic icaf_f1;
logic icaf_f1;
logic perr;
logic sbecc;
logic fence_i;
@ -146,7 +146,7 @@ typedef struct packed {
typedef struct packed {
logic [4:0] i0rd;
logic i0mul;
logic i0mul;
logic i0load;
logic i0store;
logic i0div;
@ -154,11 +154,11 @@ typedef struct packed {
logic i0valid;
logic i0secondary;
logic [1:0] i0rs1bype2;
logic [1:0] i0rs2bype2;
logic [1:0] i0rs2bype2;
logic [3:0] i0rs1bype3;
logic [3:0] i0rs2bype3;
logic [3:0] i0rs2bype3;
logic [4:0] i1rd;
logic i1mul;
logic i1mul;
logic i1load;
logic i1store;
logic i1v;
@ -166,11 +166,11 @@ typedef struct packed {
logic csrwen;
logic csrwonly;
logic [11:0] csrwaddr;
logic i1secondary;
logic i1secondary;
logic [1:0] i1rs1bype2;
logic [1:0] i1rs2bype2;
logic [1:0] i1rs2bype2;
logic [6:0] i1rs1bype3;
logic [6:0] i1rs2bype3;
logic [6:0] i1rs2bype3;
} dest_pkt_t;
typedef struct packed {
@ -192,7 +192,7 @@ typedef struct packed {
logic land;
logic lor;
logic lxor;
logic sll;
logic sll;
logic srl;
logic sra;
logic beq;
@ -230,13 +230,13 @@ typedef struct packed {
} lsu_pkt_t;
typedef struct packed {
logic exc_valid;
logic single_ecc_error;
logic inst_type; //0: Load, 1: Store
logic exc_valid;
logic single_ecc_error;
logic inst_type; //0: Load, 1: Store
logic inst_pipe; //0: i0, 1: i1
logic dma_valid;
logic exc_type; //0: MisAligned, 1: Access Fault
logic [31:0] addr;
logic exc_type; //0: MisAligned, 1: Access Fault
logic [31:0] addr;
} lsu_error_pkt_t;
typedef struct packed {
@ -276,7 +276,7 @@ typedef struct packed {
logic csr_write;
logic csr_imm;
logic presync;
logic postsync;
logic postsync;
logic ebreak;
logic ecall;
logic mret;
@ -299,7 +299,7 @@ typedef struct packed {
logic rs2_sign;
logic low;
logic load_mul_rs1_bypass_e1;
logic load_mul_rs2_bypass_e1;
logic load_mul_rs2_bypass_e1;
} mul_pkt_t;
typedef struct packed {
@ -316,12 +316,12 @@ typedef struct packed {
logic load;
logic execute;
logic m;
logic [31:0] tdata2;
logic [31:0] tdata2;
} trigger_pkt_t;
typedef struct packed {
`ifdef RV_ICACHE_ECC
`ifdef RV_ICACHE_ECC
logic [41:0] icache_wrdata; // {dicad0[31:0], dicad1[1:0]}
`else
logic [33:0] icache_wrdata; // {dicad0[31:0], dicad1[1:0]}

View File

@ -1,12 +1,12 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright 2019 Western Digital Corporation or its affiliates.
//
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//
// http://www.apache.org/licenses/LICENSE-2.0
//
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -15,8 +15,8 @@
//********************************************************************************
// $Id$
//
// Owner:
// Function: AHB to AXI4 Bridge
// Owner:
// Function: AHB to AXI4 Bridge
// Comments:
//
//********************************************************************************
@ -24,11 +24,11 @@ module ahb_to_axi4 #(parameter TAG = 1) (
input clk,
input rst_l,
input scan_mode,
input bus_clk_en,
input scan_mode,
input bus_clk_en,
input clk_override,
// AXI signals
// AXI signals
// AXI Write Channels
output logic axi_awvalid,
input logic axi_awready,
@ -37,9 +37,9 @@ module ahb_to_axi4 #(parameter TAG = 1) (
output logic [2:0] axi_awsize,
output logic [2:0] axi_awprot,
output logic [7:0] axi_awlen,
output logic [1:0] axi_awburst,
output logic [1:0] axi_awburst,
output logic axi_wvalid,
output logic axi_wvalid,
input logic axi_wready,
output logic [63:0] axi_wdata,
output logic [7:0] axi_wstrb,
@ -48,25 +48,25 @@ module ahb_to_axi4 #(parameter TAG = 1) (
input logic axi_bvalid,
output logic axi_bready,
input logic [1:0] axi_bresp,
input logic [TAG-1:0] axi_bid,
input logic [TAG-1:0] axi_bid,
// AXI Read Channels
output logic axi_arvalid,
input logic axi_arready,
output logic [TAG-1:0] axi_arid,
output logic [31:0] axi_araddr,
output logic [31:0] axi_araddr,
output logic [2:0] axi_arsize,
output logic [2:0] axi_arprot,
output logic [7:0] axi_arlen,
output logic [1:0] axi_arburst,
output logic [1:0] axi_arburst,
input logic axi_rvalid,
output logic axi_rready,
input logic [TAG-1:0] axi_rid,
input logic [63:0] axi_rdata,
input logic [1:0] axi_rresp,
input logic [1:0] axi_rresp,
// AHB-Lite signals
// AHB-Lite signals
input logic [31:0] ahb_haddr, // ahb bus address
input logic [2:0] ahb_hburst, // tied to 0
input logic ahb_hmastlock, // tied to 0
@ -76,9 +76,9 @@ module ahb_to_axi4 #(parameter TAG = 1) (
input logic ahb_hwrite, // ahb bus write
input logic [63:0] ahb_hwdata, // ahb bus write data
input logic ahb_hsel, // this slave was selected
input logic ahb_hreadyin, // previous hready was accepted or not
output logic [63:0] ahb_hrdata, // ahb bus read data
input logic ahb_hreadyin, // previous hready was accepted or not
output logic [63:0] ahb_hrdata, // ahb bus read data
output logic ahb_hreadyout, // slave ready to accept transaction
output logic ahb_hresp // slave response (high indicates erro)
@ -86,29 +86,29 @@ module ahb_to_axi4 #(parameter TAG = 1) (
logic [7:0] master_wstrb;
typedef enum logic [1:0] { IDLE = 2'b00, // Nothing in the buffer. No commands yet recieved
typedef enum logic [1:0] { IDLE = 2'b00, // Nothing in the buffer. No commands yet recieved
WR = 2'b01, // Write Command recieved
RD = 2'b10, // Read Command recieved
PEND = 2'b11 // Waiting on Read Data from core
} state_t;
state_t buf_state, buf_nxtstate;
logic buf_state_en;
// Buffer signals (one entry buffer)
logic buf_read_error_in, buf_read_error;
logic [63:0] buf_rdata;
logic ahb_hready;
logic ahb_hready_q;
logic [63:0] buf_rdata;
logic ahb_hready;
logic ahb_hready_q;
logic [1:0] ahb_htrans_in, ahb_htrans_q;
logic [2:0] ahb_hsize_q;
logic ahb_hwrite_q;
logic [31:0] ahb_haddr_q;
logic [63:0] ahb_hwdata_q;
logic ahb_hresp_q;
//Miscellaneous signals
logic ahb_addr_in_dccm, ahb_addr_in_iccm, ahb_addr_in_pic;
logic ahb_addr_in_dccm, ahb_addr_in_iccm, ahb_addr_in_pic;
logic ahb_addr_in_dccm_region_nc, ahb_addr_in_iccm_region_nc, ahb_addr_in_pic_region_nc;
// signals needed for the read data coming back from the core and to block any further commands as AHB is a blocking bus
logic buf_rdata_en;
@ -125,21 +125,21 @@ module ahb_to_axi4 #(parameter TAG = 1) (
logic [63:0] cmdbuf_wdata;
logic bus_clk;
// FSM to control the bus states and when to block the hready and load the command buffer
always_comb begin
buf_nxtstate = IDLE;
buf_state_en = 1'b0;
buf_rdata_en = 1'b0; // signal to load the buffer when the core sends read data back
buf_rdata_en = 1'b0; // signal to load the buffer when the core sends read data back
buf_read_error_in = 1'b0; // signal indicating that an error came back with the read from the core
cmdbuf_wr_en = 1'b0; // all clear from the gasket to load the buffer with the command for reads, command/dat for writes
case (buf_state)
IDLE: begin // No commands recieved
buf_nxtstate = ahb_hwrite ? WR : RD;
IDLE: begin // No commands recieved
buf_nxtstate = ahb_hwrite ? WR : RD;
buf_state_en = ahb_hready & ahb_htrans[1] & ahb_hsel; // only transition on a valid hrtans
end
WR: begin // Write command recieved last cycle
buf_nxtstate = (ahb_hresp | (ahb_htrans[1:0] == 2'b0) | ~ahb_hsel) ? IDLE : (ahb_hwrite ? WR : RD);
WR: begin // Write command recieved last cycle
buf_nxtstate = (ahb_hresp | (ahb_htrans[1:0] == 2'b0) | ~ahb_hsel) ? IDLE : (ahb_hwrite ? WR : RD);
buf_state_en = (~cmdbuf_full | ahb_hresp) ;
cmdbuf_wr_en = ~cmdbuf_full & ~(ahb_hresp | ((ahb_htrans[1:0] == 2'b01) & ahb_hsel)); // Dont send command to the buffer in case of an error or when the master is not ready with the data now.
end
@ -148,30 +148,30 @@ module ahb_to_axi4 #(parameter TAG = 1) (
buf_state_en = (~cmdbuf_full | ahb_hresp); // only when command can go, or if its an error
cmdbuf_wr_en = ~ahb_hresp & ~cmdbuf_full; // send command only when no error
end
PEND: begin // Read Command has been sent. Waiting on Data.
PEND: begin // Read Command has been sent. Waiting on Data.
buf_nxtstate = IDLE; // go back for next command and present data next cycle
buf_state_en = axi_rvalid & ~cmdbuf_write; // read data is back
buf_rdata_en = buf_state_en; // buffer the read data coming back from core
buf_read_error_in = buf_state_en & |axi_rresp[1:0]; // buffer error flag if return has Error ( ECC )
end
buf_read_error_in = buf_state_en & |axi_rresp[1:0]; // buffer error flag if return has Error ( ECC )
end
endcase
end // always_comb begin
rvdffs #($bits(state_t)) state_reg (.*, .din(buf_nxtstate), .dout({buf_state}), .en(buf_state_en), .clk(ahb_clk));
assign master_wstrb[7:0] = ({8{ahb_hsize_q[2:0] == 3'b0}} & (8'b1 << ahb_haddr_q[2:0])) |
({8{ahb_hsize_q[2:0] == 3'b1}} & (8'b11 << ahb_haddr_q[2:0])) |
({8{ahb_hsize_q[2:0] == 3'b10}} & (8'b1111 << ahb_haddr_q[2:0])) |
({8{ahb_hsize_q[2:0] == 3'b11}} & 8'b1111_1111);
// AHB signals
assign ahb_hreadyout = ahb_hresp ? (ahb_hresp_q & ~ahb_hready_q) :
((~cmdbuf_full | (buf_state == IDLE)) & ~(buf_state == RD | buf_state == PEND) & ~buf_read_error);
assign ahb_hready = ahb_hreadyout & ahb_hreadyin;
assign ahb_htrans_in[1:0] = {2{ahb_hsel}} & ahb_htrans[1:0];
assign ahb_hrdata[63:0] = buf_rdata[63:0];
assign ahb_hresp = ((ahb_htrans_q[1:0] != 2'b0) & (buf_state != IDLE) &
assign ahb_hresp = ((ahb_htrans_q[1:0] != 2'b0) & (buf_state != IDLE) &
((~(ahb_addr_in_dccm | ahb_addr_in_iccm)) | // request not for ICCM or DCCM
((ahb_addr_in_iccm | (ahb_addr_in_dccm & ahb_hwrite_q)) & ~((ahb_hsize_q[1:0] == 2'b10) | (ahb_hsize_q[1:0] == 2'b11))) | // ICCM Rd/Wr OR DCCM Wr not the right size
((ahb_hsize_q[2:0] == 3'h1) & ahb_haddr_q[0]) | // HW size but unaligned
@ -183,19 +183,19 @@ module ahb_to_axi4 #(parameter TAG = 1) (
// Buffer signals - needed for the read data and ECC error response
rvdff #(.WIDTH(64)) buf_rdata_ff (.din(axi_rdata[63:0]), .dout(buf_rdata[63:0]), .clk(buf_rdata_clk), .*);
rvdff #(.WIDTH(1)) buf_read_error_ff(.din(buf_read_error_in), .dout(buf_read_error), .clk(ahb_clk), .*); // buf_read_error will be high only one cycle
// All the Master signals are captured before presenting it to the command buffer. We check for Hresp before sending it to the cmd buffer.
rvdff #(.WIDTH(1)) hresp_ff (.din(ahb_hresp), .dout(ahb_hresp_q), .clk(ahb_clk), .*);
rvdff #(.WIDTH(1)) hready_ff (.din(ahb_hready), .dout(ahb_hready_q), .clk(ahb_clk), .*);
rvdff #(.WIDTH(2)) htrans_ff (.din(ahb_htrans_in[1:0]), .dout(ahb_htrans_q[1:0]), .clk(ahb_clk), .*);
rvdff #(.WIDTH(3)) hsize_ff (.din(ahb_hsize[2:0]), .dout(ahb_hsize_q[2:0]), .clk(ahb_addr_clk), .*);
rvdff #(.WIDTH(1)) hwrite_ff (.din(ahb_hwrite), .dout(ahb_hwrite_q), .clk(ahb_addr_clk), .*);
rvdff #(.WIDTH(32)) haddr_ff (.din(ahb_haddr[31:0]), .dout(ahb_haddr_q[31:0]), .clk(ahb_addr_clk), .*);
rvdff #(.WIDTH(32)) haddr_ff (.din(ahb_haddr[31:0]), .dout(ahb_haddr_q[31:0]), .clk(ahb_addr_clk), .*);
// Clock header logic
assign ahb_bus_addr_clk_en = bus_clk_en & (ahb_hready & ahb_htrans[1]);
assign buf_rdata_clk_en = bus_clk_en & buf_rdata_en;
rvclkhdr ahb_cgc (.en(bus_clk_en), .l1clk(ahb_clk), .*);
rvclkhdr ahb_addr_cgc (.en(ahb_bus_addr_clk_en), .l1clk(ahb_addr_clk), .*);
rvclkhdr buf_rdata_cgc (.en(buf_rdata_clk_en), .l1clk(buf_rdata_clk), .*);
@ -207,7 +207,7 @@ module ahb_to_axi4 #(parameter TAG = 1) (
.in_range(ahb_addr_in_dccm),
.in_region(ahb_addr_in_dccm_region_nc)
);
// Address check iccm
`ifdef RV_ICCM_ENABLE
rvrangecheck #(.CCM_SADR(`RV_ICCM_SADR),
@ -220,7 +220,7 @@ module ahb_to_axi4 #(parameter TAG = 1) (
assign ahb_addr_in_iccm = '0;
assign ahb_addr_in_iccm_region_nc = '0;
`endif
// PIC memory address check
rvrangecheck #(.CCM_SADR(`RV_PIC_BASE_ADDR),
.CCM_SIZE(`RV_PIC_SIZE)) addr_pic_rangecheck (
@ -232,16 +232,16 @@ module ahb_to_axi4 #(parameter TAG = 1) (
// Command Buffer - Holding for the commands to be sent for the AXI. It will be converted to the AXI signals.
assign cmdbuf_rst = (((axi_awvalid & axi_awready) | (axi_arvalid & axi_arready)) & ~cmdbuf_wr_en) | (ahb_hresp & ~cmdbuf_write);
assign cmdbuf_full = (cmdbuf_vld & ~((axi_awvalid & axi_awready) | (axi_arvalid & axi_arready)));
rvdffsc #(.WIDTH(1)) cmdbuf_vldff (.din(1'b1), .dout(cmdbuf_vld), .en(cmdbuf_wr_en), .clear(cmdbuf_rst), .clk(bus_clk), .*);
rvdffs #(.WIDTH(1)) cmdbuf_writeff (.din(ahb_hwrite_q), .dout(cmdbuf_write), .en(cmdbuf_wr_en), .clk(bus_clk), .*);
rvdffs #(.WIDTH(2)) cmdbuf_sizeff (.din(ahb_hsize_q[1:0]), .dout(cmdbuf_size[1:0]), .en(cmdbuf_wr_en), .clk(bus_clk), .*);
rvdffs #(.WIDTH(8)) cmdbuf_wstrbff (.din(master_wstrb[7:0]), .dout(cmdbuf_wstrb[7:0]), .en(cmdbuf_wr_en), .clk(bus_clk), .*);
rvdffe #(.WIDTH(32)) cmdbuf_addrff (.din(ahb_haddr_q[31:0]), .dout(cmdbuf_addr[31:0]), .en(cmdbuf_wr_en), .clk(bus_clk), .*);
rvdffe #(.WIDTH(64)) cmdbuf_wdataff (.din(ahb_hwdata[63:0]), .dout(cmdbuf_wdata[63:0]), .en(cmdbuf_wr_en), .clk(bus_clk), .*);
// AXI Write Command Channel
assign axi_awvalid = cmdbuf_vld & cmdbuf_write;
assign axi_awvalid = cmdbuf_vld & cmdbuf_write;
assign axi_awid[TAG-1:0] = '0;
assign axi_awaddr[31:0] = cmdbuf_addr[31:0];
assign axi_awsize[2:0] = {1'b0, cmdbuf_size[1:0]};
@ -249,7 +249,7 @@ module ahb_to_axi4 #(parameter TAG = 1) (
assign axi_awlen[7:0] = '0;
assign axi_awburst[1:0] = 2'b01;
// AXI Write Data Channel - This is tied to the command channel as we only write the command buffer once we have the data.
assign axi_wvalid = cmdbuf_vld & cmdbuf_write;
assign axi_wvalid = cmdbuf_vld & cmdbuf_write;
assign axi_wdata[63:0] = cmdbuf_wdata[63:0];
assign axi_wstrb[7:0] = cmdbuf_wstrb[7:0];
assign axi_wlast = 1'b1;
@ -258,17 +258,17 @@ module ahb_to_axi4 #(parameter TAG = 1) (
// AXI Read Channels
assign axi_arvalid = cmdbuf_vld & ~cmdbuf_write;
assign axi_arid[TAG-1:0] = '0;
assign axi_araddr[31:0] = cmdbuf_addr[31:0];
assign axi_araddr[31:0] = cmdbuf_addr[31:0];
assign axi_arsize[2:0] = {1'b0, cmdbuf_size[1:0]};
assign axi_arprot = 3'b0;
assign axi_arlen[7:0] = '0;
assign axi_arburst[1:0] = 2'b01;
// AXI Read Response Channel - Always ready as AHB reads are blocking and the the buffer is available for the read coming back always.
assign axi_rready = 1'b1;
// Clock header logic
rvclkhdr bus_cgc (.en(bus_clk_en), .l1clk(bus_clk), .*);
`ifdef ASSERT_ON
property ahb_error_protocol;
@(posedge ahb_clk) (ahb_hready & ahb_hresp) |-> (~$past(ahb_hready) & $past(ahb_hresp));
@ -277,5 +277,5 @@ module ahb_to_axi4 #(parameter TAG = 1) (
$display("Bus Error with hReady isn't preceded with Bus Error without hready");
`endif
endmodule // ahb_to_axi4

View File

@ -1,12 +1,12 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright 2019 Western Digital Corporation or its affiliates.
//
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//
// http://www.apache.org/licenses/LICENSE-2.0
//
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -16,8 +16,8 @@
//********************************************************************************
// $Id$
//
// Owner:
// Function: AXI4 -> AHB Bridge
// Owner:
// Function: AXI4 -> AHB Bridge
// Comments:
//
//********************************************************************************
@ -25,11 +25,11 @@ module axi4_to_ahb #(parameter TAG = 1) (
input clk,
input rst_l,
input scan_mode,
input bus_clk_en,
input scan_mode,
input bus_clk_en,
input clk_override,
// AXI signals
// AXI signals
// AXI Write Channels
input logic axi_awvalid,
output logic axi_awready,
@ -38,7 +38,7 @@ module axi4_to_ahb #(parameter TAG = 1) (
input logic [2:0] axi_awsize,
input logic [2:0] axi_awprot,
input logic axi_wvalid,
input logic axi_wvalid,
output logic axi_wready,
input logic [63:0] axi_wdata,
input logic [7:0] axi_wstrb,
@ -53,7 +53,7 @@ module axi4_to_ahb #(parameter TAG = 1) (
input logic axi_arvalid,
output logic axi_arready,
input logic [TAG-1:0] axi_arid,
input logic [31:0] axi_araddr,
input logic [31:0] axi_araddr,
input logic [2:0] axi_arsize,
input logic [2:0] axi_arprot,
@ -62,9 +62,9 @@ module axi4_to_ahb #(parameter TAG = 1) (
output logic [TAG-1:0] axi_rid,
output logic [63:0] axi_rdata,
output logic [1:0] axi_rresp,
output logic axi_rlast,
output logic axi_rlast,
// AHB-Lite signals
// AHB-Lite signals
output logic [31:0] ahb_haddr, // ahb bus address
output logic [2:0] ahb_hburst, // tied to 0
output logic ahb_hmastlock, // tied to 0
@ -74,7 +74,7 @@ module axi4_to_ahb #(parameter TAG = 1) (
output logic ahb_hwrite, // ahb bus write
output logic [63:0] ahb_hwdata, // ahb bus write data
input logic [63:0] ahb_hrdata, // ahb bus read data
input logic [63:0] ahb_hrdata, // ahb bus read data
input logic ahb_hready, // slave ready to accept transaction
input logic ahb_hresp // slave response (high indicates erro)
@ -100,25 +100,25 @@ module axi4_to_ahb #(parameter TAG = 1) (
logic [31:0] wrbuf_addr;
logic [63:0] wrbuf_data;
logic [7:0] wrbuf_byteen;
logic bus_write_clk_en;
logic bus_clk, bus_write_clk;
logic master_valid;
logic master_ready;
logic [TAG-1:0] master_tag;
logic [31:0] master_addr;
logic [31:0] master_addr;
logic [63:0] master_wdata;
logic [2:0] master_size;
logic [2:0] master_opc;
// Buffer signals (one entry buffer)
logic [31:0] buf_addr;
logic [1:0] buf_size;
logic buf_write;
logic [7:0] buf_byteen;
logic buf_aligned;
logic [63:0] buf_data;
logic [63:0] buf_data;
logic [TAG-1:0] buf_tag;
//Miscellaneous signals
@ -130,19 +130,19 @@ module axi4_to_ahb #(parameter TAG = 1) (
logic buf_write_in;
logic buf_aligned_in;
logic [2:0] buf_size_in;
logic buf_state_en;
logic buf_wr_en;
logic buf_data_wr_en;
logic slvbuf_error_en;
logic wr_cmd_vld;
logic cmd_done_rst, cmd_done, cmd_doneQ;
logic trxn_done;
logic [2:0] buf_cmd_byte_ptr, buf_cmd_byte_ptrQ, buf_cmd_nxtbyte_ptr;
logic buf_cmd_byte_ptr_en;
logic found;
logic slave_valid_pre;
logic ahb_hready_q;
logic ahb_hresp_q;
@ -157,9 +157,9 @@ module axi4_to_ahb #(parameter TAG = 1) (
logic slvbuf_error_in;
logic slvbuf_wr_en;
logic bypass_en;
logic bypass_en;
logic rd_bypass_idle;
logic last_addr_en;
logic [31:0] last_bus_addr;
@ -172,32 +172,32 @@ module axi4_to_ahb #(parameter TAG = 1) (
logic ahbm_clk;
logic ahbm_addr_clk;
logic ahbm_data_clk;
// Function to get the length from byte enable
function automatic logic [1:0] get_write_size;
input logic [7:0] byteen;
logic [1:0] size;
size[1:0] = (2'b11 & {2{(byteen[7:0] == 8'hff)}}) |
(2'b10 & {2{((byteen[7:0] == 8'hf0) | (byteen[7:0] == 8'h0f))}}) |
(2'b10 & {2{((byteen[7:0] == 8'hf0) | (byteen[7:0] == 8'h0f))}}) |
(2'b01 & {2{((byteen[7:0] == 8'hc0) | (byteen[7:0] == 8'h30) | (byteen[7:0] == 8'h0c) | (byteen[7:0] == 8'h03))}});
return size[1:0];
return size[1:0];
endfunction // get_write_size
// Function to get the length from byte enable
function automatic logic [2:0] get_write_addr;
input logic [7:0] byteen;
logic [2:0] addr;
addr[2:0] = (3'h0 & {3{((byteen[7:0] == 8'hff) | (byteen[7:0] == 8'h0f) | (byteen[7:0] == 8'h03))}}) |
(3'h2 & {3{(byteen[7:0] == 8'h0c)}}) |
(3'h4 & {3{((byteen[7:0] == 8'hf0) | (byteen[7:0] == 8'h03))}}) |
(3'h6 & {3{(byteen[7:0] == 8'hc0)}});
return addr[2:0];
return addr[2:0];
endfunction // get_write_size
// Function to get the next byte pointer
@ -211,22 +211,22 @@ module axi4_to_ahb #(parameter TAG = 1) (
if (~found) begin
get_nxtbyte_ptr[2:0] = 3'(j);
found |= (byteen[j] & (3'(j) >= start_ptr[2:0])) ;
end
end
end
endfunction // get_nextbyte_ptr
// Write buffer
assign wrbuf_en = axi_awvalid & axi_awready & master_ready;
assign wrbuf_data_en = axi_wvalid & axi_wready & master_ready;
assign wrbuf_cmd_sent = master_valid & master_ready & (master_opc[2:1] == 2'b01);
assign wrbuf_rst = wrbuf_cmd_sent & ~wrbuf_en;
assign axi_awready = ~(wrbuf_vld & ~wrbuf_cmd_sent) & master_ready;
assign axi_wready = ~(wrbuf_data_vld & ~wrbuf_cmd_sent) & master_ready;
assign axi_arready = ~(wrbuf_vld & wrbuf_data_vld) & master_ready;
assign axi_arready = ~(wrbuf_vld & wrbuf_data_vld) & master_ready;
assign axi_rlast = 1'b1;
assign wr_cmd_vld = (wrbuf_vld & wrbuf_data_vld);
assign master_valid = wr_cmd_vld | axi_arvalid;
assign master_tag[TAG-1:0] = wr_cmd_vld ? wrbuf_tag[TAG-1:0] : axi_arid[TAG-1:0];
@ -234,21 +234,21 @@ module axi4_to_ahb #(parameter TAG = 1) (
assign master_addr[31:0] = wr_cmd_vld ? wrbuf_addr[31:0] : axi_araddr[31:0];
assign master_size[2:0] = wr_cmd_vld ? wrbuf_size[2:0] : axi_arsize[2:0];
assign master_wdata[63:0] = wrbuf_data[63:0];
// AXI response channel signals
assign axi_bvalid = slave_valid & slave_ready & slave_opc[3];
assign axi_bresp[1:0] = slave_opc[0] ? 2'b10 : (slave_opc[1] ? 2'b11 : 2'b0);
assign axi_bresp[1:0] = slave_opc[0] ? 2'b10 : (slave_opc[1] ? 2'b11 : 2'b0);
assign axi_bid[TAG-1:0] = slave_tag[TAG-1:0];
assign axi_rvalid = slave_valid & slave_ready & (slave_opc[3:2] == 2'b0);
assign axi_rresp[1:0] = slave_opc[0] ? 2'b10 : (slave_opc[1] ? 2'b11 : 2'b0);
assign axi_rvalid = slave_valid & slave_ready & (slave_opc[3:2] == 2'b0);
assign axi_rresp[1:0] = slave_opc[0] ? 2'b10 : (slave_opc[1] ? 2'b11 : 2'b0);
assign axi_rid[TAG-1:0] = slave_tag[TAG-1:0];
assign axi_rdata[63:0] = slave_rdata[63:0];
assign axi_rdata[63:0] = slave_rdata[63:0];
assign slave_ready = axi_bready & axi_rready;
// Clock header logic
assign bus_write_clk_en = bus_clk_en & ((axi_awvalid & axi_awready) | (axi_wvalid & axi_wready));
rvclkhdr bus_cgc (.en(bus_clk_en), .l1clk(bus_clk), .*);
rvclkhdr bus_write_cgc (.en(bus_write_clk_en), .l1clk(bus_write_clk), .*);
@ -265,14 +265,14 @@ module axi4_to_ahb #(parameter TAG = 1) (
cmd_done = 1'b0;
trxn_done = 1'b0;
buf_cmd_byte_ptr_en = 1'b0;
buf_cmd_byte_ptr[2:0] = '0;
slave_valid_pre = 1'b0;
buf_cmd_byte_ptr[2:0] = '0;
slave_valid_pre = 1'b0;
master_ready = 1'b0;
ahb_htrans[1:0] = 2'b0;
slvbuf_wr_en = 1'b0;
bypass_en = 1'b0;
rd_bypass_idle = 1'b0;
case (buf_state)
IDLE: begin
master_ready = 1'b1;
@ -288,11 +288,11 @@ module axi4_to_ahb #(parameter TAG = 1) (
ahb_htrans[1:0] = {2{bypass_en}} & 2'b10;
end
CMD_RD: begin
buf_nxtstate = (master_valid & (master_opc[2:0] == 3'b000))? STREAM_RD : DATA_RD;
buf_nxtstate = (master_valid & (master_opc[2:0] == 3'b000))? STREAM_RD : DATA_RD;
buf_state_en = ahb_hready_q & (ahb_htrans_q[1:0] != 2'b0) & ~ahb_hwrite_q;
cmd_done = buf_state_en & ~master_valid;
cmd_done = buf_state_en & ~master_valid;
slvbuf_wr_en = buf_state_en;
master_ready = buf_state_en & (buf_nxtstate == STREAM_RD);
master_ready = buf_state_en & (buf_nxtstate == STREAM_RD);
buf_wr_en = master_ready;
bypass_en = master_ready & master_valid;
buf_cmd_byte_ptr[2:0] = bypass_en ? master_addr[2:0] : buf_addr[2:0];
@ -301,7 +301,7 @@ module axi4_to_ahb #(parameter TAG = 1) (
STREAM_RD: begin
master_ready = (ahb_hready_q & ~ahb_hresp_q) & ~(master_valid & master_opc[2:1] == 2'b01);
buf_wr_en = (master_valid & master_ready & (master_opc[2:0] == 3'b000)); // update the fifo if we are streaming the read commands
buf_nxtstate = ahb_hresp_q ? STREAM_ERR_RD : (buf_wr_en ? STREAM_RD : DATA_RD); // assuming that the master accpets the slave response right away.
buf_nxtstate = ahb_hresp_q ? STREAM_ERR_RD : (buf_wr_en ? STREAM_RD : DATA_RD); // assuming that the master accpets the slave response right away.
buf_state_en = (ahb_hready_q | ahb_hresp_q);
buf_data_wr_en = buf_state_en;
slvbuf_error_in = ahb_hresp_q;
@ -311,7 +311,7 @@ module axi4_to_ahb #(parameter TAG = 1) (
bypass_en = master_ready & master_valid & (buf_nxtstate == STREAM_RD) & buf_state_en;
buf_cmd_byte_ptr[2:0] = bypass_en ? master_addr[2:0] : buf_addr[2:0];
ahb_htrans[1:0] = 2'b10 & {2{~((buf_nxtstate != STREAM_RD) & buf_state_en)}};
slvbuf_wr_en = buf_wr_en; // shifting the contents from the buf to slv_buf for streaming cases
slvbuf_wr_en = buf_wr_en; // shifting the contents from the buf to slv_buf for streaming cases
end // case: STREAM_RD
STREAM_ERR_RD: begin
buf_nxtstate = DATA_RD;
@ -336,15 +336,15 @@ module axi4_to_ahb #(parameter TAG = 1) (
buf_cmd_byte_ptr_en = buf_state_en;
slvbuf_wr_en = buf_state_en;
buf_cmd_byte_ptr = trxn_done ? get_nxtbyte_ptr(buf_cmd_byte_ptrQ[2:0],buf_byteen[7:0],1'b1) : buf_cmd_byte_ptrQ;
cmd_done = trxn_done & (buf_aligned | (buf_cmd_byte_ptrQ == 3'b111) |
cmd_done = trxn_done & (buf_aligned | (buf_cmd_byte_ptrQ == 3'b111) |
(buf_byteen[get_nxtbyte_ptr(buf_cmd_byte_ptrQ[2:0],buf_byteen[7:0],1'b1)] == 1'b0));
ahb_htrans[1:0] = {2{~(cmd_done | cmd_doneQ)}} & 2'b10;
end
DATA_WR: begin
buf_state_en = (cmd_doneQ & ahb_hready_q) | ahb_hresp_q;
master_ready = buf_state_en & ~ahb_hresp_q & slave_ready; // Ready to accept new command if current command done and no error
buf_nxtstate = (ahb_hresp_q | ~slave_ready) ? DONE :
((master_valid & master_ready) ? ((master_opc[2:1] == 2'b01) ? CMD_WR : CMD_RD) : IDLE);
buf_nxtstate = (ahb_hresp_q | ~slave_ready) ? DONE :
((master_valid & master_ready) ? ((master_opc[2:1] == 2'b01) ? CMD_WR : CMD_RD) : IDLE);
slvbuf_error_in = ahb_hresp_q;
slvbuf_error_en = buf_state_en;
@ -352,7 +352,7 @@ module axi4_to_ahb #(parameter TAG = 1) (
buf_wr_en = buf_state_en & ((buf_nxtstate == CMD_WR) | (buf_nxtstate == CMD_RD));
buf_data_wr_en = buf_wr_en;
cmd_done = (ahb_hresp_q | (ahb_hready_q & (ahb_htrans_q[1:0] != 2'b0) &
cmd_done = (ahb_hresp_q | (ahb_hready_q & (ahb_htrans_q[1:0] != 2'b0) &
((buf_cmd_byte_ptrQ == 3'b111) | (buf_byteen[get_nxtbyte_ptr(buf_cmd_byte_ptrQ[2:0],buf_byteen[7:0],1'b1)] == 1'b0))));
bypass_en = buf_state_en & buf_write_in & (buf_nxtstate == CMD_WR); // Only bypass for writes for the time being
ahb_htrans[1:0] = {2{(~(cmd_done | cmd_doneQ) | bypass_en)}} & 2'b10;
@ -360,7 +360,7 @@ module axi4_to_ahb #(parameter TAG = 1) (
trxn_done = ahb_hready_q & ahb_hwrite_q & (ahb_htrans_q[1:0] != 2'b0);
buf_cmd_byte_ptr_en = trxn_done | bypass_en;
buf_cmd_byte_ptr = bypass_en ? get_nxtbyte_ptr(3'b0,buf_byteen_in[7:0],1'b0) :
buf_cmd_byte_ptr = bypass_en ? get_nxtbyte_ptr(3'b0,buf_byteen_in[7:0],1'b0) :
trxn_done ? get_nxtbyte_ptr(buf_cmd_byte_ptrQ[2:0],buf_byteen[7:0],1'b1) : buf_cmd_byte_ptrQ;
end
DONE: begin
@ -374,7 +374,7 @@ module axi4_to_ahb #(parameter TAG = 1) (
assign buf_rst = 1'b0;
assign cmd_done_rst = slave_valid_pre;
assign buf_addr_in[2:0] = (buf_aligned_in & (master_opc[2:1] == 2'b01)) ? get_write_addr(wrbuf_byteen[7:0]) : master_addr[2:0];
assign buf_addr_in[2:0] = (buf_aligned_in & (master_opc[2:1] == 2'b01)) ? get_write_addr(wrbuf_byteen[7:0]) : master_addr[2:0];
assign buf_addr_in[31:3] = master_addr[31:3];
assign buf_tag_in[TAG-1:0] = master_tag[TAG-1:0];
assign buf_byteen_in[7:0] = wrbuf_byteen[7:0];
@ -382,18 +382,18 @@ module axi4_to_ahb #(parameter TAG = 1) (
assign buf_size_in[1:0] = (buf_aligned_in & (master_size[1:0] == 2'b11) & (master_opc[2:1] == 2'b01)) ? get_write_size(wrbuf_byteen[7:0]) : master_size[1:0];
assign buf_aligned_in = (master_opc[2:0] == 3'b0) | // reads are always aligned since they are either DW or sideeffects
(master_size[1:0] == 2'b0) | (master_size[1:0] == 2'b01) | (master_size[1:0] == 2'b10) | // Always aligned for Byte/HW/Word since they can be only for non-idempotent. IFU/SB are always aligned
((master_size[1:0] == 2'b11) &
((wrbuf_byteen[7:0] == 8'h3) | (wrbuf_byteen[7:0] == 8'hc) | (wrbuf_byteen[7:0] == 8'h30) | (wrbuf_byteen[7:0] == 8'hc0) |
((master_size[1:0] == 2'b11) &
((wrbuf_byteen[7:0] == 8'h3) | (wrbuf_byteen[7:0] == 8'hc) | (wrbuf_byteen[7:0] == 8'h30) | (wrbuf_byteen[7:0] == 8'hc0) |
(wrbuf_byteen[7:0] == 8'hf) | (wrbuf_byteen[7:0] == 8'hf0) | (wrbuf_byteen[7:0] == 8'hff)));
// Generate the ahb signals
assign ahb_haddr[31:0] = bypass_en ? {master_addr[31:3],buf_cmd_byte_ptr[2:0]} : {buf_addr[31:3],buf_cmd_byte_ptr[2:0]};
// assign ahb_hsize[2:0] = ((buf_state == CMD_RD) | (buf_state == STREAM_RD) | (buf_state == STREAM_ERR_RD) | rd_bypass_idle) ? 3'b011 :
// assign ahb_hsize[2:0] = ((buf_state == CMD_RD) | (buf_state == STREAM_RD) | (buf_state == STREAM_ERR_RD) | rd_bypass_idle) ? 3'b011 :
// bypass_en ? {1'b0, ({2{buf_aligned_in}} & buf_size_in[1:0])} :
// {1'b0, ({2{buf_aligned}} & buf_size[1:0])}; // Send the full size for aligned trxn
assign ahb_hsize[2:0] = bypass_en ? {1'b0, ({2{buf_aligned_in}} & buf_size_in[1:0])} :
{1'b0, ({2{buf_aligned}} & buf_size[1:0])}; // Send the full size for aligned trxn
assign ahb_hburst[2:0] = 3'b0;
assign ahb_hburst[2:0] = 3'b0;
assign ahb_hmastlock = 1'b0;
assign ahb_hprot[3:0] = {3'b001,~axi_arprot[2]};
assign ahb_hwrite = bypass_en ? (master_opc[2:1] == 2'b01) : buf_write;
@ -404,10 +404,10 @@ module axi4_to_ahb #(parameter TAG = 1) (
assign slave_opc[1:0] = {2{slvbuf_error}} & 2'b10;
assign slave_rdata[63:0] = slvbuf_error ? {2{last_bus_addr[31:0]}} : ((buf_state == DONE) ? buf_data[63:0] : ahb_hrdata_q[63:0]);
assign slave_tag[TAG-1:0] = slvbuf_tag[TAG-1:0];
assign last_addr_en = (ahb_htrans[1:0] != 2'b0) & ahb_hready & ahb_hwrite ;
rvdffsc #(.WIDTH(1)) wrbuf_vldff (.din(1'b1), .dout(wrbuf_vld), .en(wrbuf_en), .clear(wrbuf_rst), .clk(bus_clk), .*);
rvdffsc #(.WIDTH(1)) wrbuf_data_vldff(.din(1'b1), .dout(wrbuf_data_vld), .en(wrbuf_data_en), .clear(wrbuf_rst), .clk(bus_clk), .*);
rvdffs #(.WIDTH(TAG)) wrbuf_tagff (.din(axi_awid[TAG-1:0]), .dout(wrbuf_tag[TAG-1:0]), .en(wrbuf_en), .clk(bus_clk), .*);
@ -417,7 +417,7 @@ module axi4_to_ahb #(parameter TAG = 1) (
rvdffs #(.WIDTH(8)) wrbuf_byteenff (.din(axi_wstrb[7:0]), .dout(wrbuf_byteen[7:0]), .en(wrbuf_data_en), .clk(bus_clk), .*);
rvdffs #(.WIDTH(32)) last_bus_addrff (.din(ahb_haddr[31:0]), .dout(last_bus_addr[31:0]), .en(last_addr_en), .clk(ahbm_clk), .*);
rvdffsc #(.WIDTH($bits(state_t))) buf_state_ff (.din(buf_nxtstate), .dout({buf_state}), .en(buf_state_en), .clear(buf_rst), .clk(ahbm_clk), .*);
rvdffs #(.WIDTH(1)) buf_writeff (.din(buf_write_in), .dout(buf_write), .en(buf_wr_en), .clk(buf_clk), .*);
rvdffs #(.WIDTH(TAG)) buf_tagff (.din(buf_tag_in[TAG-1:0]), .dout(buf_tag[TAG-1:0]), .en(buf_wr_en), .clk(buf_clk), .*);
@ -426,12 +426,12 @@ module axi4_to_ahb #(parameter TAG = 1) (
rvdffs #(.WIDTH(1)) buf_alignedff (.din(buf_aligned_in), .dout(buf_aligned), .en(buf_wr_en), .clk(buf_clk), .*);
rvdffs #(.WIDTH(8)) buf_byteenff (.din(buf_byteen_in[7:0]), .dout(buf_byteen[7:0]), .en(buf_wr_en), .clk(buf_clk), .*);
rvdffe #(.WIDTH(64)) buf_dataff (.din(buf_data_in[63:0]), .dout(buf_data[63:0]), .en(buf_data_wr_en & bus_clk_en), .*);
rvdffs #(.WIDTH(1)) slvbuf_writeff (.din(buf_write), .dout(slvbuf_write), .en(slvbuf_wr_en), .clk(buf_clk), .*);
rvdffs #(.WIDTH(TAG)) slvbuf_tagff (.din(buf_tag[TAG-1:0]), .dout(slvbuf_tag[TAG-1:0]), .en(slvbuf_wr_en), .clk(buf_clk), .*);
rvdffs #(.WIDTH(1)) slvbuf_errorff (.din(slvbuf_error_in), .dout(slvbuf_error), .en(slvbuf_error_en), .clk(ahbm_clk), .*);
rvdffsc #(.WIDTH(1)) buf_cmd_doneff (.din(1'b1), .en(cmd_done), .dout(cmd_doneQ), .clear(cmd_done_rst), .clk(ahbm_clk), .*);
rvdffs #(.WIDTH(3)) buf_cmd_byte_ptrff (.din(buf_cmd_byte_ptr[2:0]), .dout(buf_cmd_byte_ptrQ[2:0]), .en(buf_cmd_byte_ptr_en), .clk(ahbm_clk), .*);
@ -446,7 +446,7 @@ module axi4_to_ahb #(parameter TAG = 1) (
assign buf_clken = bus_clk_en & (buf_wr_en | slvbuf_wr_en | clk_override);
assign ahbm_addr_clken = bus_clk_en & ((ahb_hready & ahb_htrans[1]) | clk_override);
assign ahbm_data_clken = bus_clk_en & ((buf_state != IDLE) | clk_override);
rvclkhdr buf_cgc (.en(buf_clken), .l1clk(buf_clk), .*);
rvclkhdr ahbm_cgc (.en(bus_clk_en), .l1clk(ahbm_clk), .*);
rvclkhdr ahbm_addr_cgc (.en(ahbm_addr_clken), .l1clk(ahbm_addr_clk), .*);
@ -459,14 +459,14 @@ module axi4_to_ahb #(parameter TAG = 1) (
((ahb_hsize[2:0] == 3'h2) & (ahb_haddr[1:0] == 2'b0)) |
((ahb_hsize[2:0] == 3'h3) & (ahb_haddr[2:0] == 3'b0)));
endproperty
assert_ahb_trxn_aligned: assert property (ahb_trxn_aligned) else
assert_ahb_trxn_aligned: assert property (ahb_trxn_aligned) else
$display("Assertion ahb_trxn_aligned failed: ahb_htrans=2'h%h, ahb_hsize=3'h%h, ahb_haddr=32'h%h",ahb_htrans[1:0], ahb_hsize[2:0], ahb_haddr[31:0]);
property ahb_error_protocol;
@(posedge ahbm_clk) (ahb_hready & ahb_hresp) |-> (~$past(ahb_hready) & $past(ahb_hresp));
endproperty
assert_ahb_error_protocol: assert property (ahb_error_protocol) else
$display("Bus Error with hReady isn't preceded with Bus Error without hready");
`endif
endmodule // axi4_to_ahb

View File

@ -1,12 +1,12 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright 2019 Western Digital Corporation or its affiliates.
//
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//
// http://www.apache.org/licenses/LICENSE-2.0
//
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -17,7 +17,7 @@
module rvdff #( parameter WIDTH=1 )
(
(
input logic [WIDTH-1:0] din,
input logic clk,
input logic rst_l,
@ -37,27 +37,27 @@ module rvdff #( parameter WIDTH=1 )
else
dout[WIDTH-1:0] <= din[WIDTH-1:0];
end
endmodule
endmodule
// rvdff with 2:1 input mux to flop din iff sel==1
module rvdffs #( parameter WIDTH=1 )
(
(
input logic [WIDTH-1:0] din,
input logic en,
input logic clk,
input logic rst_l,
output logic [WIDTH-1:0] dout
);
rvdff #(WIDTH) dffs (.din((en) ? din[WIDTH-1:0] : dout[WIDTH-1:0]), .*);
endmodule
endmodule
// rvdff with en and clear
module rvdffsc #( parameter WIDTH=1 )
(
(
input logic [WIDTH-1:0] din,
input logic en,
input logic clear,
@ -70,24 +70,24 @@ module rvdffsc #( parameter WIDTH=1 )
assign din_new = {WIDTH{~clear}} & (en ? din[WIDTH-1:0] : dout[WIDTH-1:0]);
rvdff #(WIDTH) dffsc (.din(din_new[WIDTH-1:0]), .*);
endmodule
endmodule
module `TEC_RV_ICG
(
input logic TE, E, CP,
output Q
output Q
);
logic en_ff;
logic enable;
assign enable = E | TE;
`ifdef VERILATOR
always @(negedge CP) begin
en_ff <= enable;
end
`else
`else
always @(CP, enable) begin
if(!CP)
en_ff = enable;
@ -107,7 +107,7 @@ module rvclkhdr
logic TE;
assign TE = scan_mode;
`TEC_RV_ICG clkhdr ( .*, .E(en), .CP(clk), .Q(l1clk));
endmodule
@ -126,16 +126,16 @@ module rvoclkhdr
`ifdef RV_FPGA_OPTIMIZE
assign l1clk = clk;
`else
`TEC_RV_ICG clkhdr ( .*, .E(en), .CP(clk), .Q(l1clk));
`TEC_RV_ICG rvclkhdr ( .*, .E(en), .CP(clk), .Q(l1clk));
`endif
endmodule
module rvdffe #( parameter WIDTH=1 )
(
(
input logic [WIDTH-1:0] din,
input logic en,
input logic clk,
input logic clk,
input logic rst_l,
input logic scan_mode,
output logic [WIDTH-1:0] dout
@ -143,7 +143,8 @@ module rvdffe #( parameter WIDTH=1 )
logic l1clk;
`ifndef PHYSICAL
`ifndef PHYSICAL
if (WIDTH >= 8) begin: genblock
`endif
@ -156,30 +157,30 @@ module rvdffe #( parameter WIDTH=1 )
`ifndef PHYSICAL
end
else
else
$error("%m: rvdffe width must be >= 8");
`endif
endmodule // rvdffe
module rvsyncss #(parameter WIDTH = 251)
(
(
input logic clk,
input logic rst_l,
input logic [WIDTH-1:0] din,
output logic [WIDTH-1:0] dout
output logic [WIDTH-1:0] dout
);
logic [WIDTH-1:0] din_ff1;
rvdff #(WIDTH) sync_ff1 (.*, .din (din[WIDTH-1:0]), .dout(din_ff1[WIDTH-1:0]));
rvdff #(WIDTH) sync_ff2 (.*, .din (din_ff1[WIDTH-1:0]), .dout(dout[WIDTH-1:0]));
endmodule // rvsyncss
module rvlsadder
(
(
input logic [31:0] rs1,
input logic [11:0] offset,
@ -188,7 +189,7 @@ module rvlsadder
logic cout;
logic sign;
logic [31:12] rs1_inc;
logic [31:12] rs1_dec;
@ -203,13 +204,13 @@ module rvlsadder
assign dout[31:12] = ({20{ sign ^~ cout}} & rs1[31:12]) |
({20{ ~sign & cout}} & rs1_inc[31:12]) |
({20{ sign & ~cout}} & rs1_dec[31:12]);
endmodule // rvlsadder
// assume we only maintain pc[31:1] in the pipe
module rvbradder
(
(
input [31:1] pc,
input [12:1] offset,
@ -218,7 +219,7 @@ module rvbradder
logic cout;
logic sign;
logic [31:13] pc_inc;
logic [31:13] pc_dec;
@ -234,44 +235,44 @@ module rvbradder
assign dout[31:13] = ({19{ sign ^~ cout}} & pc[31:13]) |
({19{ ~sign & cout}} & pc_inc[31:13]) |
({19{ sign & ~cout}} & pc_dec[31:13]);
endmodule // rvbradder
// 2s complement circuit
module rvtwoscomp #( parameter WIDTH=32 )
(
(
input logic [WIDTH-1:0] din,
output logic [WIDTH-1:0] dout
);
logic [WIDTH-1:1] dout_temp; // holding for all other bits except for the lsb. LSB is always din
genvar i;
for ( i = 1; i < WIDTH; i++ ) begin : flip_after_first_one
assign dout_temp[i] = (|din[i-1:0]) ? ~din[i] : din[i];
end : flip_after_first_one
assign dout[WIDTH-1:0] = { dout_temp[WIDTH-1:1], din[0] };
endmodule // 2'scomp
// find first
module rvfindfirst1 #( parameter WIDTH=32, SHIFT=$clog2(WIDTH) )
(
(
input logic [WIDTH-1:0] din,
output logic [SHIFT-1:0] dout
);
logic done;
always_comb begin
dout[SHIFT-1:0] = {SHIFT{1'b0}};
done = 1'b0;
for ( int i = WIDTH-1; i > 0; i-- ) begin : find_first_one
done |= din[i];
dout[SHIFT-1:0] += done ? 1'b0 : 1'b1;
@ -280,19 +281,19 @@ module rvfindfirst1 #( parameter WIDTH=32, SHIFT=$clog2(WIDTH) )
endmodule // rvfindfirst1
module rvfindfirst1hot #( parameter WIDTH=32 )
(
(
input logic [WIDTH-1:0] din,
output logic [WIDTH-1:0] dout
);
logic done;
always_comb begin
dout[WIDTH-1:0] = {WIDTH{1'b0}};
done = 1'b0;
for ( int i = 0; i < WIDTH; i++ ) begin : find_first_one
dout[i] = ~done & din[i];
done |= din[i];
done |= din[i];
end : find_first_one
end
endmodule // rvfindfirst1hot
@ -300,25 +301,25 @@ endmodule // rvfindfirst1hot
// mask and match function matches bits after finding the first 0 position
// find first starting from LSB. Skip that location and match the rest of the bits
module rvmaskandmatch #( parameter WIDTH=32 )
(
(
input logic [WIDTH-1:0] mask, // this will have the mask in the lower bit positions
input logic [WIDTH-1:0] data, // this is what needs to be matched on the upper bits with the mask's upper bits
input logic masken, // when 1 : do mask. 0 : full match
output logic match
input logic masken, // when 1 : do mask. 0 : full match
output logic match
);
logic [WIDTH-1:0] matchvec;
logic [WIDTH-1:0] matchvec;
logic masken_or_fullmask;
assign masken_or_fullmask = masken & ~(&mask[WIDTH-1:0]);
assign matchvec[0] = masken_or_fullmask | (mask[0] == data[0]);
genvar i;
for ( i = 1; i < WIDTH; i++ ) begin : match_after_first_zero
assign matchvec[i] = (&mask[i-1:0] & masken_or_fullmask) ? 1'b1 : (mask[i] == data[i]);
end : match_after_first_zero
assign match = &matchvec[WIDTH-1:0]; // all bits either matched or were masked off
endmodule // rvmaskandmatch
@ -328,17 +329,17 @@ module rvbtb_tag_hash (
output logic [`RV_BTB_BTAG_SIZE-1:0] hash
);
`ifndef RV_BTB_BTAG_FOLD
assign hash = {(pc[`RV_BTB_ADDR_HI+`RV_BTB_BTAG_SIZE+`RV_BTB_BTAG_SIZE+`RV_BTB_BTAG_SIZE:`RV_BTB_ADDR_HI+`RV_BTB_BTAG_SIZE+`RV_BTB_BTAG_SIZE+1] ^
pc[`RV_BTB_ADDR_HI+`RV_BTB_BTAG_SIZE+`RV_BTB_BTAG_SIZE:`RV_BTB_ADDR_HI+`RV_BTB_BTAG_SIZE+1] ^
assign hash = {(pc[`RV_BTB_ADDR_HI+`RV_BTB_BTAG_SIZE+`RV_BTB_BTAG_SIZE+`RV_BTB_BTAG_SIZE:`RV_BTB_ADDR_HI+`RV_BTB_BTAG_SIZE+`RV_BTB_BTAG_SIZE+1] ^
pc[`RV_BTB_ADDR_HI+`RV_BTB_BTAG_SIZE+`RV_BTB_BTAG_SIZE:`RV_BTB_ADDR_HI+`RV_BTB_BTAG_SIZE+1] ^
pc[`RV_BTB_ADDR_HI+`RV_BTB_BTAG_SIZE:`RV_BTB_ADDR_HI+1])};
`else
assign hash = {(
pc[`RV_BTB_ADDR_HI+`RV_BTB_BTAG_SIZE+`RV_BTB_BTAG_SIZE:`RV_BTB_ADDR_HI+`RV_BTB_BTAG_SIZE+1] ^
pc[`RV_BTB_ADDR_HI+`RV_BTB_BTAG_SIZE+`RV_BTB_BTAG_SIZE:`RV_BTB_ADDR_HI+`RV_BTB_BTAG_SIZE+1] ^
pc[`RV_BTB_ADDR_HI+`RV_BTB_BTAG_SIZE:`RV_BTB_ADDR_HI+1])};
`endif
// assign hash = {pc[`RV_BTB_ADDR_HI+1],(pc[`RV_BTB_ADDR_HI+13:`RV_BTB_ADDR_HI+10] ^
// pc[`RV_BTB_ADDR_HI+9:`RV_BTB_ADDR_HI+6] ^
// assign hash = {pc[`RV_BTB_ADDR_HI+1],(pc[`RV_BTB_ADDR_HI+13:`RV_BTB_ADDR_HI+10] ^
// pc[`RV_BTB_ADDR_HI+9:`RV_BTB_ADDR_HI+6] ^
// pc[`RV_BTB_ADDR_HI+5:`RV_BTB_ADDR_HI+2])};
endmodule
@ -348,12 +349,12 @@ module rvbtb_addr_hash (
output logic [`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO] hash
);
assign hash[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO] = pc[`RV_BTB_INDEX1_HI:`RV_BTB_INDEX1_LO] ^
assign hash[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO] = pc[`RV_BTB_INDEX1_HI:`RV_BTB_INDEX1_LO] ^
`ifndef RV_BTB_FOLD2_INDEX_HASH
pc[`RV_BTB_INDEX2_HI:`RV_BTB_INDEX2_LO] ^
`ifndef RV_BTB_FOLD2_INDEX_HASH
pc[`RV_BTB_INDEX2_HI:`RV_BTB_INDEX2_LO] ^
`endif
pc[`RV_BTB_INDEX3_HI:`RV_BTB_INDEX3_LO];
endmodule
@ -373,10 +374,10 @@ endmodule
// Check if the S_ADDR <= addr < E_ADDR
module rvrangecheck #(CCM_SADR = 32'h0,
CCM_SIZE = 128) (
CCM_SIZE = 128) (
input logic [31:0] addr, // Address to be checked for range
output logic in_range, // S_ADDR <= start_addr < E_ADDR
output logic in_region
output logic in_region
);
localparam REGION_BITS = 4;
@ -384,42 +385,42 @@ module rvrangecheck #(CCM_SADR = 32'h0,
logic [31:0] start_addr;
logic [3:0] region;
assign start_addr[31:0] = CCM_SADR;
assign region[REGION_BITS-1:0] = start_addr[31:(32-REGION_BITS)];
assign in_region = (addr[31:(32-REGION_BITS)] == region[REGION_BITS-1:0]);
assign in_region = (addr[31:(32-REGION_BITS)] == region[REGION_BITS-1:0]);
if (CCM_SIZE == 48)
assign in_range = (addr[31:MASK_BITS] == start_addr[31:MASK_BITS]) & ~(&addr[MASK_BITS-1 : MASK_BITS-2]);
else
assign in_range = (addr[31:MASK_BITS] == start_addr[31:MASK_BITS]);
endmodule // rvrangechecker
// 16 bit even parity generator
module rveven_paritygen #(WIDTH = 16) (
module rveven_paritygen #(WIDTH = 16) (
input logic [WIDTH-1:0] data_in, // Data
output logic parity_out // generated even parity
);
assign parity_out = ^(data_in[WIDTH-1:0]) ;
endmodule // rveven_paritygen
module rveven_paritycheck #(WIDTH = 16) (
module rveven_paritycheck #(WIDTH = 16) (
input logic [WIDTH-1:0] data_in, // Data
input logic parity_in,
output logic parity_err // Parity error
);
assign parity_err = ^(data_in[WIDTH-1:0]) ^ parity_in ;
endmodule // rveven_paritycheck
module rvecc_encode (
input [31:0] din,
output [6:0] ecc_out
);
);
logic [5:0] ecc_out_temp;
assign ecc_out_temp[0] = din[0]^din[1]^din[3]^din[4]^din[6]^din[8]^din[10]^din[11]^din[13]^din[15]^din[17]^din[19]^din[21]^din[23]^din[25]^din[26]^din[28]^din[30];
@ -448,7 +449,7 @@ module rvecc_decode (
logic [6:0] ecc_check;
logic [38:0] error_mask;
logic [38:0] din_plus_parity, dout_plus_parity;
// Generate the ecc bits
assign ecc_check[0] = ecc_in[0]^din[0]^din[1]^din[3]^din[4]^din[6]^din[8]^din[10]^din[11]^din[13]^din[15]^din[17]^din[19]^din[21]^din[23]^din[25]^din[26]^din[28]^din[30];
assign ecc_check[1] = ecc_in[1]^din[0]^din[2]^din[3]^din[5]^din[6]^din[9]^din[10]^din[12]^din[13]^din[16]^din[17]^din[20]^din[21]^din[24]^din[25]^din[27]^din[28]^din[31];
@ -461,8 +462,8 @@ module rvecc_decode (
assign ecc_check[6] = ((^din[31:0])^(^ecc_in[6:0])) & ~sed_ded;
assign single_ecc_error = en & (ecc_check[6:0] != 0) & ecc_check[6]; // this will never be on for sed_ded
assign double_ecc_error = en & (ecc_check[6:0] != 0) & ~ecc_check[6]; // all errors in the sed_ded case will be recorded as DE
assign double_ecc_error = en & (ecc_check[6:0] != 0) & ~ecc_check[6]; // all errors in the sed_ded case will be recorded as DE
// Generate the mask for error correctiong
for (genvar i=1; i<40; i++) begin
assign error_mask[i-1] = (ecc_check[5:0] == i);
@ -470,9 +471,9 @@ module rvecc_decode (
// Generate the corrected data
assign din_plus_parity[38:0] = {ecc_in[6], din[31:26], ecc_in[5], din[25:11], ecc_in[4], din[10:4], ecc_in[3], din[3:1], ecc_in[2], din[0], ecc_in[1:0]};
assign dout_plus_parity[38:0] = single_ecc_error ? (error_mask[38:0] ^ din_plus_parity[38:0]) : din_plus_parity[38:0];
assign dout[31:0] = {dout_plus_parity[37:32], dout_plus_parity[30:16], dout_plus_parity[14:8], dout_plus_parity[6:4], dout_plus_parity[2]};
assign ecc_out[6:0] = {(dout_plus_parity[38] ^ (ecc_check[6:0] == 7'b1000000)), dout_plus_parity[31], dout_plus_parity[15], dout_plus_parity[7], dout_plus_parity[3], dout_plus_parity[1:0]};
endmodule // rvecc_decode

View File

@ -1,12 +1,12 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright 2019 Western Digital Corporation or its affiliates.
//
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//
// http://www.apache.org/licenses/LICENSE-2.0
//
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -17,14 +17,14 @@
//=================================== START OF CCM =======================================================================
//============= Possible sram sizes for a 39 bit wide memory ( 4 bytes + 7 bits ECC ) =====================================
//-------------------------------------------------------------------------------------------------------------------------
module ram_32768x39
module ram_32768x39
( input logic CLK,
input logic [14:0] ADR,
input logic [38:0] D,
output logic [38:0] Q,
input logic WE );
// behavior to be replaced by actual SRAM in VLE
reg [38:0] ram_core [32767:0];
@ -35,20 +35,20 @@ module ram_32768x39
Q <= ram_core[ADR];
end
endmodule // ram_32768x39
module ram_16384x39
module ram_16384x39
( input logic CLK,
input logic [13:0] ADR,
input logic [38:0] D,
output logic [38:0] Q,
input logic WE );
// behavior to be replaced by actual SRAM in VLE
reg [38:0] ram_core [16383:0];
@ -59,19 +59,19 @@ module ram_16384x39
Q <= ram_core[ADR];
end
endmodule // ram_16384x39
module ram_8192x39
module ram_8192x39
( input logic CLK,
input logic [12:0] ADR,
input logic [38:0] D,
output logic [38:0] Q,
input logic WE );
// behavior to be replaced by actual SRAM in VLE
reg [38:0] ram_core [8191:0];
@ -82,19 +82,19 @@ module ram_8192x39
Q <= ram_core[ADR];
end
endmodule // ram_8192x39
module ram_4096x39
module ram_4096x39
( input logic CLK,
input logic [11:0] ADR,
input logic [38:0] D,
output logic [38:0] Q,
input logic WE );
// behavior to be replaced by actual SRAM in VLE
reg [38:0] ram_core [4095:0];
@ -105,19 +105,19 @@ module ram_4096x39
Q <= ram_core[ADR];
end
endmodule // ram_4096x39
module ram_3072x39
module ram_3072x39
( input logic CLK,
input logic [11:0] ADR,
input logic [38:0] D,
output logic [38:0] Q,
input logic WE );
// behavior to be replaced by actual SRAM in VLE
reg [38:0] ram_core [3071:0];
@ -128,21 +128,21 @@ module ram_3072x39
Q <= ram_core[ADR];
end
endmodule // ram_3072x39
module ram_2048x39
module ram_2048x39
( input logic CLK,
input logic [10:0] ADR,
input logic [38:0] D,
output logic [38:0] Q,
input logic WE );
// behavior to be replaced by actual SRAM in VLE
reg [38:0] ram_core [2047:0];
@ -153,7 +153,7 @@ module ram_2048x39
Q <= ram_core[ADR];
end
endmodule // ram_2048x39
@ -165,7 +165,7 @@ module ram_1536x39 // need this for the 48KB DCCM option
output logic [38:0] Q,
input logic WE );
// behavior to be replaced by actual SRAM in VLE
reg [38:0] ram_core [1535:0];
@ -176,20 +176,20 @@ module ram_1536x39 // need this for the 48KB DCCM option
Q <= ram_core[ADR];
end
endmodule // ram_1536x39
module ram_1024x39
module ram_1024x39
( input logic CLK,
input logic [9:0] ADR,
input logic [38:0] D,
output logic [38:0] Q,
input logic WE );
// behavior to be replaced by actual SRAM in VLE
reg [38:0] ram_core [1023:0];
@ -200,19 +200,19 @@ module ram_1024x39
Q <= ram_core[ADR];
end
endmodule // ram_1024x39
module ram_768x39
module ram_768x39
( input logic CLK,
input logic [9:0] ADR,
input logic [38:0] D,
output logic [38:0] Q,
input logic WE );
// behavior to be replaced by actual SRAM in VLE
reg [38:0] ram_core [767:0];
@ -223,20 +223,20 @@ module ram_768x39
Q <= ram_core[ADR];
end
endmodule // ram_768x39
module ram_512x39
module ram_512x39
( input logic CLK,
input logic [8:0] ADR,
input logic [38:0] D,
output logic [38:0] Q,
input logic WE );
// behavior to be replaced by actual SRAM in VLE
reg [38:0] ram_core [511:0];
@ -247,20 +247,20 @@ module ram_512x39
Q <= ram_core[ADR];
end
endmodule // ram_512x39
module ram_256x39
module ram_256x39
( input logic CLK,
input logic [7:0] ADR,
input logic [38:0] D,
output logic [38:0] Q,
input logic WE );
// behavior to be replaced by actual SRAM in VLE
reg [38:0] ram_core [255:0];
@ -271,20 +271,20 @@ module ram_256x39
Q <= ram_core[ADR];
end
endmodule // ram_512x39
module ram_128x39
module ram_128x39
( input logic CLK,
input logic [6:0] ADR,
input logic [38:0] D,
output logic [38:0] Q,
input logic WE );
// behavior to be replaced by actual SRAM in VLE
reg [38:0] ram_core [127:0];
@ -295,7 +295,7 @@ module ram_128x39
Q <= ram_core[ADR];
end
endmodule // ram_128x39
@ -303,7 +303,7 @@ endmodule // ram_128x39
//=========================================================================================================================
//=================================== START OF TAGS =======================================================================
// I CACHE TAGS
module ram_1024x20
module ram_1024x20
( input logic CLK,
input logic [9:0] ADR,
@ -311,7 +311,7 @@ module ram_1024x20
output logic [19:0] Q,
input logic WE );
// behavior to be replaced by actual SRAM in VLE
reg [19:0] ram_core [1023:0];
@ -322,18 +322,18 @@ module ram_1024x20
Q <= ram_core[ADR];
end
endmodule // ram_1024x20
module ram_512x20
module ram_512x20
( input logic CLK,
input logic [8:0] ADR,
input logic [19:0] D,
output logic [19:0] Q,
input logic WE );
// behavior to be replaced by actual SRAM in VLE
reg [19:0] ram_core [511:0];
@ -349,14 +349,14 @@ module ram_512x20
endmodule // ram_512x20
module ram_256x20
module ram_256x20
( input logic CLK,
input logic [7:0] ADR,
input logic [19:0] D,
output logic [19:0] Q,
input logic WE );
// behavior to be replaced by actual SRAM in VLE
reg [19:0] ram_core [255:0];
@ -371,14 +371,14 @@ module ram_256x20
endmodule // ram_256x20
module ram_128x20
module ram_128x20
( input logic CLK,
input logic [6:0] ADR,
input logic [19:0] D,
output logic [19:0] Q,
input logic WE );
// behavior to be replaced by actual SRAM in VLE
reg [19:0] ram_core [127:0];
@ -394,14 +394,14 @@ module ram_128x20
endmodule // ram_128x20
module ram_64x20
module ram_64x20
( input logic CLK,
input logic [5:0] ADR,
input logic [19:0] D,
output logic [19:0] Q,
input logic WE );
// behavior to be replaced by actual SRAM in VLE
reg [19:0] ram_core [63:0];
@ -421,14 +421,14 @@ endmodule // ram_64x20
// 4096 x 34
module ram_4096x34
module ram_4096x34
( input logic CLK,
input logic [11:0] ADR,
input logic [33:0] D,
output logic [33:0] Q,
input logic WE );
// behavior to be replaced by actual SRAM in VLE
reg [33:0] ram_core [4095:0];
@ -440,20 +440,20 @@ module ram_4096x34
end
endmodule // ram_4096x34
// 2048x34
module ram_2048x34
// 2048x34
module ram_2048x34
( input logic CLK,
input logic [10:0] ADR,
input logic [33:0] D,
output logic [33:0] Q,
input logic WE );
// behavior to be replaced by actual SRAM in VLE
reg [33:0] ram_core [2047:0];
@ -465,20 +465,20 @@ module ram_2048x34
end
endmodule // ram_2048x34
// 1024x34
module ram_1024x34
// 1024x34
module ram_1024x34
( input logic CLK,
input logic [9:0] ADR,
input logic [33:0] D,
output logic [33:0] Q,
input logic WE );
// behavior to be replaced by actual SRAM in VLE
reg [33:0] ram_core [1023:0];
@ -490,20 +490,20 @@ module ram_1024x34
end
endmodule // ram_1024x34
// 512x34
module ram_512x34
// 512x34
module ram_512x34
( input logic CLK,
input logic [8:0] ADR,
input logic [33:0] D,
output logic [33:0] Q,
input logic WE );
// behavior to be replaced by actual SRAM in VLE
reg [33:0] ram_core [511:0];
@ -515,20 +515,20 @@ module ram_512x34
end
endmodule // ram_512x34
// 256x34
module ram_256x34
// 256x34
module ram_256x34
( input logic CLK,
input logic [7:0] ADR,
input logic [33:0] D,
output logic [33:0] Q,
input logic WE );
// behavior to be replaced by actual SRAM in VLE
reg [33:0] ram_core [255:0];
@ -540,20 +540,20 @@ module ram_256x34
end
endmodule // ram_256x34
// 128x34
module ram_128x34
// 128x34
module ram_128x34
( input logic CLK,
input logic [6:0] ADR,
input logic [33:0] D,
output logic [33:0] Q,
input logic WE );
// behavior to be replaced by actual SRAM in VLE
reg [33:0] ram_core [127:0];
@ -569,15 +569,15 @@ module ram_128x34
endmodule // ram_128x34
// 64x34
module ram_64x34
// 64x34
module ram_64x34
( input logic CLK,
input logic [5:0] ADR,
input logic [33:0] D,
output logic [33:0] Q,
input logic WE );
// behavior to be replaced by actual SRAM in VLE
reg [33:0] ram_core [63:0];
@ -595,16 +595,16 @@ endmodule // ram_64x34
// New SRAMS for ECC; ECC on 16b boundaries
// 4096x44
module ram_4096x42
// 4096x44
module ram_4096x42
( input logic CLK,
input logic [11:0] ADR,
input logic [41:0] D,
output logic [41:0] Q,
input logic WE );
// behavior to be replaced by actual SRAM in VLE
reg [41:0] ram_core [4095:0];
@ -621,15 +621,15 @@ module ram_4096x42
endmodule // ram_4096x42
// 2048x44
module ram_2048x42
// 2048x44
module ram_2048x42
( input logic CLK,
input logic [10:0] ADR,
input logic [41:0] D,
output logic [41:0] Q,
input logic WE );
// behavior to be replaced by actual SRAM in VLE
reg [41:0] ram_core [2047:0];
@ -645,15 +645,15 @@ module ram_2048x42
endmodule // ram_2048x42
// 1024x44
module ram_1024x42
// 1024x44
module ram_1024x42
( input logic CLK,
input logic [9:0] ADR,
input logic [41:0] D,
output logic [41:0] Q,
input logic WE );
// behavior to be replaced by actual SRAM in VLE
reg [41:0] ram_core [1023:0];
@ -669,15 +669,15 @@ module ram_1024x42
endmodule // ram_1024x42
// 512x44
module ram_512x42
// 512x44
module ram_512x42
( input logic CLK,
input logic [8:0] ADR,
input logic [41:0] D,
output logic [41:0] Q,
input logic WE );
// behavior to be replaced by actual SRAM in VLE
reg [41:0] ram_core [511:0];
@ -689,21 +689,21 @@ module ram_512x42
end
endmodule // ram_512x42
// 256x42
module ram_256x42
// 256x42
module ram_256x42
( input logic CLK,
input logic [7:0] ADR,
input logic [41:0] D,
output logic [41:0] Q,
input logic WE );
// behavior to be replaced by actual SRAM in VLE
reg [41:0] ram_core [255:0];
@ -715,20 +715,20 @@ module ram_256x42
end
endmodule // ram_256x42
// 128x42
module ram_128x42
// 128x42
module ram_128x42
( input logic CLK,
input logic [6:0] ADR,
input logic [41:0] D,
output logic [41:0] Q,
input logic WE );
// behavior to be replaced by actual SRAM in VLE
reg [41:0] ram_core [127:0];
@ -740,20 +740,20 @@ module ram_128x42
end
endmodule // ram_128x42
// 64x42
module ram_64x42
// 64x42
module ram_64x42
( input logic CLK,
input logic [5:0] ADR,
input logic [41:0] D,
output logic [41:0] Q,
input logic WE );
// behavior to be replaced by actual SRAM in VLE
reg [41:0] ram_core [63:0];
@ -772,8 +772,8 @@ endmodule // ram_64x42
// START TAGS
// 1024x21
module ram_1024x21
// 1024x21
module ram_1024x21
( input logic CLK,
input logic [9:0] ADR,
input logic [20:0] D,
@ -781,7 +781,7 @@ module ram_1024x21
output logic [20:0] Q,
input logic WE );
// behavior to be replaced by actual SRAM in VLE
reg [20:0] ram_core [1023:0];
@ -796,15 +796,15 @@ module ram_1024x21
endmodule // ram_1024x21
// 512x21
module ram_512x21
// 512x21
module ram_512x21
( input logic CLK,
input logic [8:0] ADR,
input logic [20:0] D,
output logic [20:0] Q,
input logic WE );
// behavior to be replaced by actual SRAM in VLE
reg [20:0] ram_core [511:0];
@ -816,21 +816,21 @@ module ram_512x21
end
endmodule // ram_512x21
// 256x21
module ram_256x21
// 256x21
module ram_256x21
( input logic CLK,
input logic [7:0] ADR,
input logic [20:0] D,
output logic [20:0] Q,
input logic WE );
// behavior to be replaced by actual SRAM in VLE
// behavior to be replaced by actual SRAM in VLE
reg [20:0] ram_core [255:0];
@ -841,20 +841,20 @@ module ram_256x21
end
endmodule // ram_256x21
// 128x21
module ram_128x21
// 128x21
module ram_128x21
( input logic CLK,
input logic [6:0] ADR,
input logic [20:0] D,
output logic [20:0] Q,
input logic WE );
// behavior to be replaced by actual SRAM in VLE
reg [20:0] ram_core [127:0];
@ -866,13 +866,13 @@ module ram_128x21
end
endmodule // ram_128x21
// 64x21
module ram_64x21
// 64x21
module ram_64x21
( input logic CLK,
input logic [5:0] ADR,
input logic [20:0] D,
@ -893,17 +893,17 @@ module ram_64x21
endmodule // ram_64x21
// New tag rams for ECC.
// New tag rams for ECC.
// 1024x25
module ram_1024x25
// 1024x25
module ram_1024x25
( input logic CLK,
input logic [9:0] ADR,
input logic [24:0] D,
output logic [24:0] Q,
input logic WE );
// behavior to be replaced by actual SRAM in VLE
reg [24:0] ram_core [1023:0];
@ -915,13 +915,13 @@ module ram_1024x25
end
endmodule // ram_1024x25
// 512x25
module ram_512x25
// 512x25
module ram_512x25
( input logic CLK,
input logic [8:0] ADR,
input logic [24:0] D,
@ -929,7 +929,7 @@ module ram_512x25
output logic [24:0] Q,
input logic WE );
// behavior to be replaced by actual SRAM in VLE
reg [24:0] ram_core [511:0];
@ -941,13 +941,13 @@ module ram_512x25
end
endmodule // ram_512x25
// 256x25
module ram_256x25
// 256x25
module ram_256x25
( input logic CLK,
input logic [7:0] ADR,
input logic [24:0] D,
@ -955,8 +955,8 @@ module ram_256x25
output logic [24:0] Q,
input logic WE );
// behavior to be replaced by actual SRAM in VLE
// behavior to be replaced by actual SRAM in VLE
reg [24:0] ram_core [255:0];
@ -967,13 +967,13 @@ module ram_256x25
end
endmodule // ram_256x25
// 128x25
module ram_128x25
// 128x25
module ram_128x25
( input logic CLK,
input logic [6:0] ADR,
input logic [24:0] D,
@ -981,7 +981,7 @@ module ram_128x25
output logic [24:0] Q,
input logic WE );
// behavior to be replaced by actual SRAM in VLE
reg [24:0] ram_core [127:0];
@ -993,13 +993,13 @@ module ram_128x25
end
endmodule // ram_128x25
// 64x25
module ram_64x25
// 64x25
module ram_64x25
( input logic CLK,
input logic [5:0] ADR,
input logic [24:0] D,
@ -1019,7 +1019,7 @@ module ram_64x25
end
endmodule // ram_64x25

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

@ -1,12 +1,12 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright 2019 Western Digital Corporation or its affiliates.
//
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//
// http://www.apache.org/licenses/LICENSE-2.0
//
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -16,53 +16,55 @@
//********************************************************************************
// $Id$
//
//
//
// Function: Top level file for load store unit
// Comments:
//
//
//
// DC1 -> DC2 -> DC3 -> DC4 (Commit)
//
//
//********************************************************************************
module lsu
module lsu
import swerv_types::*;
(
input logic [31:0] i0_result_e4_eff, // I0 e4 result for e4 -> dc3 store forwarding
input logic [31:0] i1_result_e4_eff, // I1 e4 result for e4 -> dc3 store forwarding
input logic [31:0] i0_result_e2, // I0 e2 result for e2 -> dc2 store forwarding
input logic flush_final_e3, // I0/I1 flush in e3
input logic flush_final_e3, // I0/I1 flush in e3
input logic i0_flush_final_e3, // I0 flush in e3
input logic dec_tlu_flush_lower_wb, // I0/I1 writeback flush. This is used to flush the old packets only
input logic dec_tlu_i0_kill_writeb_wb, // I0 is flushed, don't writeback any results to arch state
input logic dec_tlu_i1_kill_writeb_wb, // I1 is flushed, don't writeback any results to arch state
input logic dec_tlu_i0_kill_writeb_wb, // I0 is flushed, don't writeback any results to arch state
input logic dec_tlu_i1_kill_writeb_wb, // I1 is flushed, don't writeback any results to arch state
input logic dec_tlu_cancel_e4, // cancel the bus load in dc4 and reset the freeze
// chicken signals
input logic dec_tlu_non_blocking_disable, // disable the non block
input logic dec_tlu_wb_coalescing_disable, // disable the write buffer coalesce
input logic dec_tlu_ld_miss_byp_wb_disable, // disable the miss bypass in the write buffer
input logic dec_tlu_ld_miss_byp_wb_disable, // disable the miss bypass in the write buffer
input logic dec_tlu_sideeffect_posted_disable, // disable posted writes to sideeffect addr to the bus
input logic dec_tlu_core_ecc_disable, // disable the generation of the ecc
input logic [31:0] exu_lsu_rs1_d, // address rs operand
input logic [31:0] exu_lsu_rs2_d, // store data
input logic [11:0] dec_lsu_offset_d, // address offset operand
input lsu_pkt_t lsu_p, // lsu control packet
input logic dec_i0_lsu_decode_d, // lsu is in i0
input logic [31:0] dec_tlu_mrac_ff, // CSR for memory region control
output logic [31:0] lsu_result_dc3, // lsu load data
output logic lsu_single_ecc_error_incr, // Increment the counter for Single ECC error
output logic [31:0] lsu_result_corr_dc4, // This is the ECC corrected data going to RF
output logic lsu_freeze_dc3, // lsu freeze due to load to external
output logic lsu_load_stall_any, // This is for blocking loads in the decode
output logic lsu_store_stall_any, // This is for blocking stores in the decode
output logic lsu_load_ecc_stbuf_full_dc3, // Load with ecc error can't allocate to stbuf
output logic lsu_idle_any, // lsu buffers are empty and no instruction in the pipeline
output logic lsu_halt_idle_any, // This is used to enter halt mode. Exclude DMA
output lsu_error_pkt_t lsu_error_pkt_dc3, // lsu exception packet
output logic lsu_freeze_external_ints_dc3, // freeze due to sideeffects loads need to suppress external interrupt
output logic lsu_imprecise_error_load_any, // bus load imprecise error
@ -70,25 +72,25 @@ module lsu
output logic [31:0] lsu_imprecise_error_addr_any, // bus store imprecise error address
// Non-blocking loads
input logic dec_nonblock_load_freeze_dc2, //
input logic dec_nonblock_load_freeze_dc2, //
output logic lsu_nonblock_load_valid_dc3, // there is an external load -> put in the cam
output logic [`RV_LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_tag_dc3, // the tag of the external non block load
output logic lsu_nonblock_load_inv_dc5, // invalidate signal for the cam entry for non block loads
output logic [`RV_LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_inv_tag_dc5, // tag of the enrty which needs to be invalidated
output logic lsu_nonblock_load_data_valid, // the non block is valid - sending information back to the cam
output logic lsu_nonblock_load_data_error, // non block load has an error
output logic [`RV_LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_data_tag, // the tag of the non block load sending the data/error
output logic lsu_nonblock_load_data_valid, // the non block is valid - sending information back to the cam
output logic lsu_nonblock_load_data_error, // non block load has an error
output logic [`RV_LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_data_tag, // the tag of the non block load sending the data/error
output logic [31:0] lsu_nonblock_load_data, // Data of the non block load
output logic lsu_pmu_misaligned_dc3, // PMU : misaligned
output logic lsu_pmu_bus_trxn, // PMU : bus transaction
output logic lsu_pmu_bus_trxn, // PMU : bus transaction
output logic lsu_pmu_bus_misaligned, // PMU : misaligned access going to the bus
output logic lsu_pmu_bus_error, // PMU : bus sending error back
output logic lsu_pmu_bus_busy, // PMU : bus is not ready
// Trigger signals
input trigger_pkt_t [3:0] trigger_pkt_any, // Trigger info from the decode
output logic [3:0] lsu_trigger_match_dc3, // lsu trigger hit (one bit per trigger)
output logic [3:0] lsu_trigger_match_dc3, // lsu trigger hit (one bit per trigger)
// DCCM ports
output logic dccm_wren, // DCCM write enable
@ -97,7 +99,7 @@ module lsu
output logic [`RV_DCCM_BITS-1:0] dccm_rd_addr_lo, // DCCM read address low bank
output logic [`RV_DCCM_BITS-1:0] dccm_rd_addr_hi, // DCCM read address hi bank (hi and low same if aligned read)
output logic [`RV_DCCM_FDATA_WIDTH-1:0] dccm_wr_data, // DCCM write data (this is always aligned)
input logic [`RV_DCCM_FDATA_WIDTH-1:0] dccm_rd_data_lo, // DCCM read data low bank
input logic [`RV_DCCM_FDATA_WIDTH-1:0] dccm_rd_data_hi, // DCCM read data hi bank
@ -122,19 +124,19 @@ module lsu
output logic [3:0] lsu_axi_awcache,
output logic [2:0] lsu_axi_awprot,
output logic [3:0] lsu_axi_awqos,
output logic lsu_axi_wvalid,
output logic lsu_axi_wvalid,
input logic lsu_axi_wready,
output logic [63:0] lsu_axi_wdata,
output logic [7:0] lsu_axi_wstrb,
output logic lsu_axi_wlast,
input logic lsu_axi_bvalid,
output logic lsu_axi_bready,
input logic [1:0] lsu_axi_bresp,
input logic [`RV_LSU_BUS_TAG-1:0] lsu_axi_bid,
// AXI Read Channels
// AXI Read Channels
output logic lsu_axi_arvalid,
input logic lsu_axi_arready,
output logic [`RV_LSU_BUS_TAG-1:0] lsu_axi_arid,
@ -147,7 +149,7 @@ module lsu
output logic [3:0] lsu_axi_arcache,
output logic [2:0] lsu_axi_arprot,
output logic [3:0] lsu_axi_arqos,
input logic lsu_axi_rvalid,
output logic lsu_axi_rready,
input logic [`RV_LSU_BUS_TAG-1:0] lsu_axi_rid,
@ -156,7 +158,7 @@ module lsu
input logic lsu_axi_rlast,
input logic lsu_bus_clk_en, // external drives a clock_en to control bus ratio
// DMA slave
input logic dma_dccm_req, // DMA read/write to dccm
input logic [31:0] dma_mem_addr, // DMA address
@ -171,15 +173,15 @@ module lsu
input logic clk_override, // Disable clock gating
input logic scan_mode, // scan
input logic clk,
input logic clk,
input logic free_clk,
input logic rst_l
);
`include "global.h"
logic lsu_dccm_rden_dc3;
logic [63:0] store_data_dc2;
logic [63:0] store_data_dc3;
@ -191,7 +193,7 @@ module lsu
logic single_ecc_error_hi_dc3, single_ecc_error_lo_dc3;
logic lsu_single_ecc_error_dc3, lsu_single_ecc_error_dc4, lsu_single_ecc_error_dc5;
logic lsu_double_ecc_error_dc3;
logic [31:0] dccm_data_hi_dc3;
logic [31:0] dccm_data_lo_dc3;
logic [6:0] dccm_data_ecc_hi_dc3;
@ -200,13 +202,13 @@ module lsu
logic [31:0] lsu_ld_data_dc3;
logic [31:0] lsu_ld_data_corr_dc3;
logic [31:0] picm_mask_data_dc3;
logic [31:0] lsu_addr_dc1, lsu_addr_dc2, lsu_addr_dc3, lsu_addr_dc4, lsu_addr_dc5;
logic [31:0] end_addr_dc1, end_addr_dc2, end_addr_dc3, end_addr_dc4, end_addr_dc5;
lsu_pkt_t lsu_pkt_dc1, lsu_pkt_dc2, lsu_pkt_dc3, lsu_pkt_dc4, lsu_pkt_dc5;
logic lsu_i0_valid_dc1, lsu_i0_valid_dc2, lsu_i0_valid_dc3, lsu_i0_valid_dc4, lsu_i0_valid_dc5;
// Store Buffer signals
logic isldst_dc1, dccm_ldst_dc2, dccm_ldst_dc3;
logic store_stbuf_reqvld_dc3;
@ -226,7 +228,7 @@ module lsu
logic [LSU_SB_BITS-1:0] stbuf_addr_any;
logic [DCCM_DATA_WIDTH-1:0] stbuf_data_any;
logic [(DCCM_FDATA_WIDTH-DCCM_DATA_WIDTH-1):0] stbuf_ecc_any;
logic lsu_cmpen_dc2;
logic [DCCM_DATA_WIDTH-1:0] stbuf_fwddata_hi_dc3;
logic [DCCM_DATA_WIDTH-1:0] stbuf_fwddata_lo_dc3;
@ -234,7 +236,7 @@ module lsu
logic [DCCM_BYTE_WIDTH-1:0] stbuf_fwdbyteen_lo_dc3;
logic lsu_stbuf_commit_any;
logic lsu_stbuf_empty_any;
logic lsu_stbuf_empty_any;
logic lsu_stbuf_nodma_empty_any; // Store Buffer is empty except dma writes
logic lsu_stbuf_full_any;
@ -247,53 +249,53 @@ module lsu
logic [31:0] bus_read_data_dc3;
logic ld_bus_error_dc3;
logic [31:0] ld_bus_error_addr_dc3;
logic flush_dc2_up, flush_dc3, flush_dc4, flush_dc5, flush_prior_dc5;
logic is_sideeffects_dc2, is_sideeffects_dc3;
logic ldst_nodma_dc1todc3;
// Clocks
logic lsu_c1_dc3_clk, lsu_c1_dc4_clk, lsu_c1_dc5_clk;
logic lsu_c2_dc3_clk, lsu_c2_dc4_clk, lsu_c2_dc5_clk;
logic lsu_c1_dc3_clk, lsu_c1_dc4_clk, lsu_c1_dc5_clk;
logic lsu_c2_dc3_clk, lsu_c2_dc4_clk, lsu_c2_dc5_clk;
logic lsu_freeze_c1_dc2_clk, lsu_freeze_c1_dc3_clk;
logic lsu_freeze_c1_dc1_clken, lsu_freeze_c1_dc2_clken, lsu_freeze_c1_dc3_clken;
logic lsu_freeze_c1_dc1_clken, lsu_freeze_c1_dc2_clken, lsu_freeze_c1_dc3_clken;
logic lsu_store_c1_dc1_clken, lsu_store_c1_dc2_clken, lsu_store_c1_dc3_clken, lsu_store_c1_dc4_clk, lsu_store_c1_dc5_clk;
logic lsu_freeze_c2_dc1_clk, lsu_freeze_c2_dc2_clk, lsu_freeze_c2_dc3_clk, lsu_freeze_c2_dc4_clk;
logic lsu_freeze_c2_dc1_clk, lsu_freeze_c2_dc2_clk, lsu_freeze_c2_dc3_clk, lsu_freeze_c2_dc4_clk;
logic lsu_stbuf_c1_clk;
logic lsu_bus_ibuf_c1_clk, lsu_bus_obuf_c1_clk, lsu_bus_buf_c1_clk;
logic lsu_dccm_c1_dc3_clk, lsu_pic_c1_dc3_clken;
logic lsu_busm_clk;
logic lsu_free_c2_clk;
lsu_lsc_ctl lsu_lsc_ctl(.*);
// block stores in decode - for either bus or stbuf reasons
assign lsu_store_stall_any = lsu_stbuf_full_any | lsu_bus_buffer_full_any;
assign lsu_load_stall_any = lsu_bus_buffer_full_any;
// Ready to accept dma trxns
// There can't be any inpipe forwarding from non-dma packet to dma packet since they can be flushed so we can't have ld/st in dc3-dc5 when dma is in dc2
assign ldst_nodma_dc1todc3 = (lsu_pkt_dc1.valid & ~lsu_pkt_dc1.dma) | (lsu_pkt_dc2.valid & ~lsu_pkt_dc2.dma) | (lsu_pkt_dc3.valid & ~lsu_pkt_dc3.dma);
assign dccm_ready = ~(lsu_p.valid | lsu_stbuf_full_any | lsu_freeze_dc3 | ldst_nodma_dc1todc3);
// Generate per cycle flush signals
assign flush_dc2_up = flush_final_e3 | i0_flush_final_e3 | dec_tlu_flush_lower_wb;
assign flush_dc3 = (flush_final_e3 & i0_flush_final_e3) | dec_tlu_flush_lower_wb;
assign flush_dc4 = dec_tlu_flush_lower_wb;
assign flush_dc5 = (dec_tlu_i0_kill_writeb_wb | (dec_tlu_i1_kill_writeb_wb & ~lsu_i0_valid_dc5));
assign flush_prior_dc5 = dec_tlu_i0_kill_writeb_wb & ~lsu_i0_valid_dc5; // Flush is due to i0 instruction and ld/st is in i1
// lsu idle
assign lsu_idle_any = ~(lsu_pkt_dc1.valid | lsu_pkt_dc2.valid | lsu_pkt_dc3.valid | lsu_pkt_dc4.valid | lsu_pkt_dc5.valid) &
assign lsu_idle_any = ~(lsu_pkt_dc1.valid | lsu_pkt_dc2.valid | lsu_pkt_dc3.valid | lsu_pkt_dc4.valid | lsu_pkt_dc5.valid) &
lsu_bus_buffer_empty_any & lsu_stbuf_empty_any;
// lsu halt idle. This is used for entering the halt mode
// Indicates non-idle if there is a instruction valid in dc1-dc5 or read/write buffers are non-empty since they can come with error
// Need to make sure bus trxns are done and there are no non-dma writes in store buffer
assign lsu_halt_idle_any = ~((lsu_pkt_dc1.valid & ~lsu_pkt_dc1.dma) |
// Need to make sure bus trxns are done and there are no non-dma writes in store buffer
assign lsu_halt_idle_any = ~((lsu_pkt_dc1.valid & ~lsu_pkt_dc1.dma) |
(lsu_pkt_dc2.valid & ~lsu_pkt_dc2.dma) |
(lsu_pkt_dc3.valid & ~lsu_pkt_dc3.dma) |
(lsu_pkt_dc4.valid & ~lsu_pkt_dc4.dma) |
@ -309,7 +311,7 @@ module lsu
assign isldst_dc1 = lsu_pkt_dc1.valid & (lsu_pkt_dc1.load | lsu_pkt_dc1.store);
assign dccm_ldst_dc2 = lsu_pkt_dc2.valid & (lsu_pkt_dc2.load | lsu_pkt_dc2.store) & (addr_in_dccm_dc2 | addr_in_pic_dc2);
assign dccm_ldst_dc3 = lsu_pkt_dc3.valid & (lsu_pkt_dc3.load | lsu_pkt_dc3.store) & (addr_in_dccm_dc3 | addr_in_pic_dc3);
// Disable Forwarding for now
assign lsu_cmpen_dc2 = lsu_pkt_dc2.valid & (lsu_pkt_dc2.load | lsu_pkt_dc2.store) & (addr_in_dccm_dc2 | addr_in_pic_dc2);
@ -319,14 +321,14 @@ module lsu
// PMU signals
assign lsu_pmu_misaligned_dc3 = lsu_pkt_dc3.valid & ((lsu_pkt_dc3.half & lsu_addr_dc3[0]) | (lsu_pkt_dc3.word & (|lsu_addr_dc3[1:0])));
lsu_dccm_ctl dccm_ctl (
.lsu_addr_dc1(lsu_addr_dc1[31:0]),
.end_addr_dc1(end_addr_dc1[DCCM_BITS-1:0]),
.lsu_addr_dc3(lsu_addr_dc3[DCCM_BITS-1:0]),
.*
);
lsu_stbuf stbuf(
.lsu_addr_dc1(lsu_addr_dc1[LSU_SB_BITS-1:0]),
.end_addr_dc1(end_addr_dc1[LSU_SB_BITS-1:0]),
@ -335,9 +337,9 @@ module lsu
.lsu_addr_dc3(lsu_addr_dc3[LSU_SB_BITS-1:0]),
.end_addr_dc3(end_addr_dc3[LSU_SB_BITS-1:0]),
.*
);
lsu_ecc ecc (
.lsu_addr_dc3(lsu_addr_dc3[DCCM_BITS-1:0]),
.end_addr_dc3(end_addr_dc3[DCCM_BITS-1:0]),
@ -348,13 +350,13 @@ module lsu
.store_data_dc3(store_data_dc3[31:0]),
.*
);
// Clk domain
lsu_clkdomain clkdomain (.*);
// Bus interface
lsu_bus_intf bus_intf (.*);
//Flops
//rvdffs #(1) lsu_i0_valid_dc1ff (.*, .din(dec_i0_lsu_decode_d), .dout(lsu_i0_valid_dc1), .en(~lsu_freeze_dc3));
rvdff #(1) lsu_i0_valid_dc1ff (.*, .din(dec_i0_lsu_decode_d), .dout(lsu_i0_valid_dc1), .clk(lsu_freeze_c2_dc1_clk));
@ -362,9 +364,9 @@ module lsu
rvdff #(1) lsu_i0_valid_dc3ff (.*, .din(lsu_i0_valid_dc2), .dout(lsu_i0_valid_dc3), .clk(lsu_freeze_c2_dc3_clk));
rvdff #(1) lsu_i0_valid_dc4ff (.*, .din(lsu_i0_valid_dc3), .dout(lsu_i0_valid_dc4), .clk(lsu_freeze_c2_dc4_clk));
rvdff #(1) lsu_i0_valid_dc5ff (.*, .din(lsu_i0_valid_dc4), .dout(lsu_i0_valid_dc5), .clk(lsu_c2_dc5_clk));
rvdff #(1) lsu_single_ecc_err_dc4(.*, .din(lsu_single_ecc_error_dc3), .dout(lsu_single_ecc_error_dc4), .clk(lsu_c2_dc4_clk));
rvdff #(1) lsu_single_ecc_err_dc4(.*, .din(lsu_single_ecc_error_dc3), .dout(lsu_single_ecc_error_dc4), .clk(lsu_c2_dc4_clk));
rvdff #(1) lsu_single_ecc_err_dc5(.*, .din(lsu_single_ecc_error_dc4), .dout(lsu_single_ecc_error_dc5), .clk(lsu_c2_dc5_clk));
`ifdef ASSERT_ON
logic [8:0] store_data_bypass_sel;
assign store_data_bypass_sel[8:0] = {lsu_p.store_data_bypass_c1,
@ -375,8 +377,8 @@ module lsu
lsu_p.store_data_bypass_e4_c3[1:0]};
assert_store_data_bypass_onehot: assert #0 ($onehot0(store_data_bypass_sel[8:0]));
assert_picm_rden_and_wren: assert #0 ($onehot0({(picm_rden | picm_mken),picm_wren}));
assert_picm_rden_and_dccmen: assert #0 ($onehot0({(picm_rden | picm_mken),dccm_rden}));
assert_picm_rden_and_wren: assert #0 ($onehot0({(picm_rden | picm_mken),picm_wren}));
assert_picm_rden_and_dccmen: assert #0 ($onehot0({(picm_rden | picm_mken),dccm_rden}));
assert_picm_wren_and_dccmen: assert #0 ($onehot0({picm_wren, dccm_wren}));
//assert_no_exceptions: assert #0 (lsu_exc_pkt_dc3.exc_valid == 1'b0);
@ -386,5 +388,5 @@ module lsu
assert_exception_no_lsu_flush: assert property (exception_no_lsu_flush) else
$display("No flush within 2 cycles of exception");
`endif
endmodule // lsu

View File

@ -1,12 +1,12 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright 2019 Western Digital Corporation or its affiliates.
//
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//
// http://www.apache.org/licenses/LICENSE-2.0
//
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -16,13 +16,13 @@
//********************************************************************************
// $Id$
//
//
// Owner:
//
// Owner:
// Function: Checks the memory map for the address
// Comments:
// Comments:
//
//********************************************************************************
module lsu_addrcheck
module lsu_addrcheck
import swerv_types::*;
(
input logic lsu_freeze_c2_dc2_clk, // clock
@ -34,21 +34,21 @@ module lsu_addrcheck
input lsu_pkt_t lsu_pkt_dc1, // packet in dc1
input logic [31:0] dec_tlu_mrac_ff, // CSR read
output logic is_sideeffects_dc2, // is sideffects space
output logic is_sideeffects_dc3,
output logic is_sideeffects_dc3,
output logic addr_in_dccm_dc1, // address in dccm
output logic addr_in_pic_dc1, // address in pic
output logic addr_external_dc1, // address in external
output logic access_fault_dc1, // access fault
output logic misaligned_fault_dc1, // misaligned
input logic scan_mode
output logic misaligned_fault_dc1, // misaligned
input logic scan_mode
);
`include "global.h"
localparam DCCM_REGION = `RV_DCCM_REGION;
localparam PIC_REGION = `RV_PIC_REGION;
localparam ICCM_REGION = `RV_ICCM_REGION;
@ -58,13 +58,13 @@ module lsu_addrcheck
`else
localparam ICCM_ENABLE = 1'b0;
`endif
`ifdef RV_DCCM_ENABLE
localparam DCCM_ENABLE = 1'b1;
`else
localparam DCCM_ENABLE = 1'b0;
`endif
logic is_sideeffects_dc1, is_aligned_dc1;
logic start_addr_in_dccm_dc1, end_addr_in_dccm_dc1;
logic start_addr_in_dccm_region_dc1, end_addr_in_dccm_region_dc1;
@ -73,7 +73,7 @@ module lsu_addrcheck
logic [4:0] csr_idx;
logic addr_in_iccm;
logic non_dccm_access_ok;
if (DCCM_ENABLE == 1) begin: Gen_dccm_enable
// Start address check
rvrangecheck #(.CCM_SADR(`RV_DCCM_SADR),
@ -82,7 +82,7 @@ module lsu_addrcheck
.in_range(start_addr_in_dccm_dc1),
.in_region(start_addr_in_dccm_region_dc1)
);
// End address check
rvrangecheck #(.CCM_SADR(`RV_DCCM_SADR),
.CCM_SIZE(`RV_DCCM_SIZE)) end_addr_dccm_rangecheck (
@ -98,10 +98,10 @@ module lsu_addrcheck
end
if (ICCM_ENABLE == 1) begin : check_iccm
assign addr_in_iccm = (start_addr_dc1[31:28] == ICCM_REGION);
end
end
else begin
assign addr_in_iccm = 1'b0;
end
end
// PIC memory check
// Start address check
rvrangecheck #(.CCM_SADR(`RV_PIC_BASE_ADDR),
@ -110,7 +110,7 @@ module lsu_addrcheck
.in_range(start_addr_in_pic_dc1),
.in_region(start_addr_in_pic_region_dc1)
);
// End address check
rvrangecheck #(.CCM_SADR(`RV_PIC_BASE_ADDR),
.CCM_SIZE(`RV_PIC_SIZE)) end_addr_pic_rangecheck (
@ -119,12 +119,12 @@ module lsu_addrcheck
.in_region(end_addr_in_pic_region_dc1)
);
assign addr_in_dccm_dc1 = (start_addr_in_dccm_dc1 & end_addr_in_dccm_dc1);
assign addr_in_pic_dc1 = (start_addr_in_pic_dc1 & end_addr_in_pic_dc1);
assign addr_external_dc1 = ~(addr_in_dccm_dc1 | addr_in_pic_dc1); //~addr_in_dccm_region_dc1;
assign addr_in_dccm_dc1 = (start_addr_in_dccm_dc1 & end_addr_in_dccm_dc1);
assign addr_in_pic_dc1 = (start_addr_in_pic_dc1 & end_addr_in_pic_dc1);
assign addr_external_dc1 = ~(addr_in_dccm_dc1 | addr_in_pic_dc1); //~addr_in_dccm_region_dc1;
assign csr_idx[4:0] = {start_addr_dc1[31:28], 1'b1};
assign is_sideeffects_dc1 = dec_tlu_mrac_ff[csr_idx] & ~(start_addr_in_dccm_region_dc1 | start_addr_in_pic_region_dc1 | addr_in_iccm); //every region has the 2 LSB indicating ( 1: sideeffects/no_side effects, and 0: cacheable ). Ignored in internal regions
assign is_sideeffects_dc1 = dec_tlu_mrac_ff[csr_idx] & ~(start_addr_in_dccm_region_dc1 | start_addr_in_pic_region_dc1 | addr_in_iccm); //every region has the 2 LSB indicating ( 1: sideeffects/no_side effects, and 0: cacheable ). Ignored in internal regions
assign is_aligned_dc1 = (lsu_pkt_dc1.word & (start_addr_dc1[1:0] == 2'b0)) |
(lsu_pkt_dc1.half & (start_addr_dc1[0] == 1'b0)) |
lsu_pkt_dc1.by;
@ -134,7 +134,7 @@ module lsu_addrcheck
(((`RV_DATA_ACCESS_ENABLE0 & ((start_addr_dc1[31:0] | `RV_DATA_ACCESS_MASK0)) == (`RV_DATA_ACCESS_ADDR0 | `RV_DATA_ACCESS_MASK0)) |
(`RV_DATA_ACCESS_ENABLE1 & ((start_addr_dc1[31:0] | `RV_DATA_ACCESS_MASK1)) == (`RV_DATA_ACCESS_ADDR1 | `RV_DATA_ACCESS_MASK1)) |
(`RV_DATA_ACCESS_ENABLE2 & ((start_addr_dc1[31:0] | `RV_DATA_ACCESS_MASK2)) == (`RV_DATA_ACCESS_ADDR2 | `RV_DATA_ACCESS_MASK2)) |
(`RV_DATA_ACCESS_ENABLE3 & ((start_addr_dc1[31:0] | `RV_DATA_ACCESS_MASK3)) == (`RV_DATA_ACCESS_ADDR3 | `RV_DATA_ACCESS_MASK3)) |
(`RV_DATA_ACCESS_ENABLE3 & ((start_addr_dc1[31:0] | `RV_DATA_ACCESS_MASK3)) == (`RV_DATA_ACCESS_ADDR3 | `RV_DATA_ACCESS_MASK3)) |
(`RV_DATA_ACCESS_ENABLE4 & ((start_addr_dc1[31:0] | `RV_DATA_ACCESS_MASK4)) == (`RV_DATA_ACCESS_ADDR4 | `RV_DATA_ACCESS_MASK4)) |
(`RV_DATA_ACCESS_ENABLE5 & ((start_addr_dc1[31:0] | `RV_DATA_ACCESS_MASK5)) == (`RV_DATA_ACCESS_ADDR5 | `RV_DATA_ACCESS_MASK5)) |
(`RV_DATA_ACCESS_ENABLE6 & ((start_addr_dc1[31:0] | `RV_DATA_ACCESS_MASK6)) == (`RV_DATA_ACCESS_ADDR6 | `RV_DATA_ACCESS_MASK6)) |
@ -156,28 +156,29 @@ module lsu_addrcheck
// 4. Ld/St access to picm are not word aligned
// 5. Address not in protected space or dccm/pic region
if (DCCM_REGION == PIC_REGION) begin
assign access_fault_dc1 = ((start_addr_in_dccm_region_dc1 & ~(start_addr_in_dccm_dc1 | start_addr_in_pic_dc1)) |
assign access_fault_dc1 = ((start_addr_in_dccm_region_dc1 & ~(start_addr_in_dccm_dc1 | start_addr_in_pic_dc1)) |
(end_addr_in_dccm_region_dc1 & ~(end_addr_in_dccm_dc1 | end_addr_in_pic_dc1)) |
((start_addr_dc1[27:18] != end_addr_dc1[27:18]) & start_addr_in_dccm_dc1) |
(start_addr_in_dccm_dc1 & end_addr_in_pic_dc1) |
(start_addr_in_pic_dc1 & end_addr_in_dccm_dc1) |
((addr_in_pic_dc1 & ((start_addr_dc1[1:0] != 2'b0) | ~lsu_pkt_dc1.word))) |
(~start_addr_in_dccm_region_dc1 & ~non_dccm_access_ok)) & lsu_pkt_dc1.valid & ~lsu_pkt_dc1.dma;
end else begin
assign access_fault_dc1 = ((start_addr_in_dccm_region_dc1 & ~start_addr_in_dccm_dc1) |
assign access_fault_dc1 = ((start_addr_in_dccm_region_dc1 & ~start_addr_in_dccm_dc1) |
(end_addr_in_dccm_region_dc1 & ~end_addr_in_dccm_dc1) |
(start_addr_in_pic_region_dc1 & ~start_addr_in_pic_dc1) |
(start_addr_in_pic_region_dc1 & ~start_addr_in_pic_dc1) |
(end_addr_in_pic_region_dc1 & ~end_addr_in_pic_dc1) |
((addr_in_pic_dc1 & ((start_addr_dc1[1:0] != 2'b0) | ~lsu_pkt_dc1.word))) |
(~start_addr_in_pic_region_dc1 & ~start_addr_in_dccm_region_dc1 & ~non_dccm_access_ok)) & lsu_pkt_dc1.valid & ~lsu_pkt_dc1.dma;
end
// Misaligned happens due to 2 reasons
// 1. Region cross
// 2. sideeffects access which are not aligned
assign misaligned_fault_dc1 = ((start_addr_dc1[31:28] != end_addr_dc1[31:28]) |
assign misaligned_fault_dc1 = ((start_addr_dc1[31:28] != end_addr_dc1[31:28]) |
(is_sideeffects_dc1 & ~is_aligned_dc1)) & addr_external_dc1 & lsu_pkt_dc1.valid & ~lsu_pkt_dc1.dma;
rvdff #(.WIDTH(1)) is_sideeffects_dc2ff (.din(is_sideeffects_dc1), .dout(is_sideeffects_dc2), .clk(lsu_freeze_c2_dc2_clk), .*);
rvdff #(.WIDTH(1)) is_sideeffects_dc3ff (.din(is_sideeffects_dc2), .dout(is_sideeffects_dc3), .clk(lsu_freeze_c2_dc3_clk), .*);
endmodule // lsu_addrcheck

View File

@ -1,12 +1,12 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright 2019 Western Digital Corporation or its affiliates.
//
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//
// http://www.apache.org/licenses/LICENSE-2.0
//
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -16,8 +16,8 @@
//********************************************************************************
// $Id$
//
//
// Owner:
//
// Owner:
// Function: lsu interface with interface queue
// Comments:
//
@ -30,13 +30,13 @@ function automatic logic [2:0] f_Enc8to3;
logic [2:0] Enc_value;
Enc_value[0] = Dec_value[1] | Dec_value[3] | Dec_value[5] | Dec_value[7];
Enc_value[1] = Dec_value[2] | Dec_value[3] | Dec_value[6] | Dec_value[7];
Enc_value[2] = Dec_value[4] | Dec_value[5] | Dec_value[6] | Dec_value[7];
Enc_value[2] = Dec_value[4] | Dec_value[5] | Dec_value[6] | Dec_value[7];
return Enc_value[2:0];
endfunction // f_Enc8to3
module lsu_bus_buffer
module lsu_bus_buffer
import swerv_types::*;
(
input logic clk,
@ -46,9 +46,9 @@ module lsu_bus_buffer
input logic dec_tlu_wb_coalescing_disable, // disable write buffer coalescing
input logic dec_tlu_ld_miss_byp_wb_disable, // disable ld miss bypass of the write buffer
input logic dec_tlu_sideeffect_posted_disable, // disable posted writes to sideeffect addr to the bus
// various clocks needed for the bus reads and writes
input logic lsu_c1_dc3_clk,
input logic lsu_c1_dc3_clk,
input logic lsu_c1_dc4_clk,
input logic lsu_c1_dc5_clk,
input logic lsu_c2_dc3_clk,
@ -63,8 +63,8 @@ module lsu_bus_buffer
input logic lsu_bus_buf_c1_clk,
input logic lsu_free_c2_clk,
input logic lsu_busm_clk,
input lsu_pkt_t lsu_pkt_dc1, // lsu packet flowing down the pipe
input lsu_pkt_t lsu_pkt_dc2, // lsu packet flowing down the pipe
input lsu_pkt_t lsu_pkt_dc3, // lsu packet flowing down the pipe
@ -84,7 +84,7 @@ module lsu_bus_buffer
output logic lsu_busreq_dc4, // bus request is in dc4
output logic lsu_busreq_dc5, // bus request is in dc5
input logic ld_full_hit_dc2, // load can get all its byte from a write buffer entry
input logic flush_dc2_up, // flush
input logic flush_dc2_up, // flush
input logic flush_dc3, // flush
input logic flush_dc4, // flush
input logic flush_dc5, // flush
@ -98,16 +98,16 @@ module lsu_bus_buffer
input logic ldst_dual_dc3, // load/store is unaligned at 32 bit boundary
input logic ldst_dual_dc4, // load/store is unaligned at 32 bit boundary
input logic ldst_dual_dc5, // load/store is unaligned at 32 bit boundary
input logic [7:0] ldst_byteen_ext_dc2,
output logic ld_freeze_dc3, // load goes to external and asserts freeze
output logic lsu_bus_buffer_pend_any, // bus buffer has a pending bus entry
output logic lsu_bus_buffer_full_any, // bus buffer is full
output logic lsu_bus_buffer_empty_any, // bus buffer is empty
output logic ld_bus_error_dc3, // bus error in dc3
output logic [31:0] ld_bus_error_addr_dc3, // address of the bus error
output logic [31:0] ld_bus_error_addr_dc3, // address of the bus error
output logic [31:0] ld_bus_data_dc3, // the Dc3 load data from bus
output logic [3:0] ld_byte_hit_buf_lo, ld_byte_hit_buf_hi, // Byte enables for forwarding data
@ -123,17 +123,17 @@ module lsu_bus_buffer
output logic [`RV_LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_tag_dc3, // the tag of the external non block load
output logic lsu_nonblock_load_inv_dc5, // invalidate signal for the cam entry for non block loads
output logic [`RV_LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_inv_tag_dc5, // tag of the enrty which needs to be invalidated
output logic lsu_nonblock_load_data_valid, // the non block is valid - sending information back to the cam
output logic lsu_nonblock_load_data_error, // non block load has an error
output logic [`RV_LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_data_tag, // the tag of the non block load sending the data/error
output logic [31:0] lsu_nonblock_load_data, // Data of the non block load
output logic lsu_nonblock_load_data_valid, // the non block is valid - sending information back to the cam
output logic lsu_nonblock_load_data_error, // non block load has an error
output logic [`RV_LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_data_tag, // the tag of the non block load sending the data/error
output logic [31:0] lsu_nonblock_load_data, // Data of the non block load
// PMU events
output logic lsu_pmu_bus_trxn,
output logic lsu_pmu_bus_misaligned,
output logic lsu_pmu_bus_error,
output logic lsu_pmu_bus_busy,
// AXI Write Channels
output logic lsu_axi_awvalid,
input logic lsu_axi_awready,
@ -147,19 +147,19 @@ module lsu_bus_buffer
output logic [3:0] lsu_axi_awcache,
output logic [2:0] lsu_axi_awprot,
output logic [3:0] lsu_axi_awqos,
output logic lsu_axi_wvalid,
output logic lsu_axi_wvalid,
input logic lsu_axi_wready,
output logic [63:0] lsu_axi_wdata,
output logic [7:0] lsu_axi_wstrb,
output logic lsu_axi_wlast,
input logic lsu_axi_bvalid,
output logic lsu_axi_bready,
input logic [1:0] lsu_axi_bresp,
input logic [`RV_LSU_BUS_TAG-1:0] lsu_axi_bid,
// AXI Read Channels
// AXI Read Channels
output logic lsu_axi_arvalid,
input logic lsu_axi_arready,
output logic [`RV_LSU_BUS_TAG-1:0] lsu_axi_arid,
@ -172,7 +172,7 @@ module lsu_bus_buffer
output logic [3:0] lsu_axi_arcache,
output logic [2:0] lsu_axi_arprot,
output logic [3:0] lsu_axi_arqos,
input logic lsu_axi_rvalid,
output logic lsu_axi_rready,
input logic [`RV_LSU_BUS_TAG-1:0] lsu_axi_rid,
@ -196,7 +196,7 @@ module lsu_bus_buffer
localparam TIMER = 8; // This can be only power of 2
localparam TIMER_LOG2 = (TIMER < 2) ? 1 : $clog2(TIMER);
localparam TIMER_MAX = (TIMER == 0) ? TIMER_LOG2'(0) : TIMER_LOG2'(TIMER - 1); // Maximum value of timer
logic [3:0] ldst_byteen_hi_dc2, ldst_byteen_lo_dc2;
logic [DEPTH-1:0] ld_addr_hitvec_lo, ld_addr_hitvec_hi;
logic [3:0][DEPTH-1:0] ld_byte_hitvec_lo, ld_byte_hitvec_hi;
@ -210,7 +210,7 @@ module lsu_bus_buffer
logic [3:0] ldst_byteen_hi_dc5, ldst_byteen_lo_dc5;
logic [31:0] store_data_hi_dc5, store_data_lo_dc5;
logic ldst_samedw_dc5;
logic lsu_nonblock_load_valid_dc4,lsu_nonblock_load_valid_dc5;
logic [31:0] lsu_nonblock_load_data_hi, lsu_nonblock_load_data_lo, lsu_nonblock_data_unalgn;
logic [1:0] lsu_nonblock_addr_offset;
@ -222,7 +222,7 @@ module lsu_bus_buffer
logic ld_precise_bus_error;
logic [DEPTH_LOG2-1:0] lsu_imprecise_error_load_tag;
logic [31:0] ld_block_bus_data;
logic [DEPTH-1:0] CmdPtr0Dec, CmdPtr1Dec;
logic [DEPTH_LOG2-1:0] CmdPtr0, CmdPtr1;
logic [DEPTH_LOG2-1:0] WrPtr0_dc3, WrPtr0_dc4, WrPtr0_dc5;
@ -231,19 +231,19 @@ module lsu_bus_buffer
logic [3:0] buf_numvld_any, buf_numvld_wrcmd_any, buf_numvld_pend_any, buf_numvld_cmd_any;
logic bus_sideeffect_pend;
logic bus_coalescing_disable;
logic ld_freeze_en, ld_freeze_rst;
logic FreezePtrEn;
logic [DEPTH_LOG2-1:0] FreezePtr;
logic bus_addr_match_pending;
logic bus_addr_match_pending;
logic bus_cmd_sent, bus_cmd_ready;
logic bus_wcmd_sent, bus_wdata_sent;
logic bus_rsp_read, bus_rsp_write;
logic [LSU_BUS_TAG-1:0] bus_rsp_read_tag, bus_rsp_write_tag;
logic bus_rsp_read_error, bus_rsp_write_error;
logic [63:0] bus_rsp_rdata;
// Bus buffer signals
state_t [DEPTH-1:0] buf_state;
logic [DEPTH-1:0][2:0] buf_state_out;
@ -262,7 +262,7 @@ module lsu_bus_buffer
logic [DEPTH-1:0] buf_error;
logic [DEPTH-1:0][31:0] buf_data;
logic [DEPTH-1:0][DEPTH-1:0] buf_age, buf_age_younger, buf_age_temp;
state_t [DEPTH-1:0] buf_nxtstate;
logic [DEPTH-1:0] buf_rst;
logic [DEPTH-1:0] buf_state_en;
@ -350,7 +350,7 @@ module lsu_bus_buffer
logic obuf_cmd_done_in, obuf_data_done_in;
logic [LSU_BUS_TAG-1:0] obuf_tag0_in;
logic [LSU_BUS_TAG-1:0] obuf_tag1_in;
logic obuf_merge_en;
logic [TIMER_LOG2-1:0] obuf_wr_timer, obuf_wr_timer_in;
logic [7:0] obuf_byteen0_in, obuf_byteen1_in;
@ -363,8 +363,8 @@ module lsu_bus_buffer
logic lsu_axi_rvalid_q, lsu_axi_rready_q;
logic [LSU_BUS_TAG-1:0] lsu_axi_bid_q, lsu_axi_rid_q;
logic [1:0] lsu_axi_bresp_q, lsu_axi_rresp_q;
logic [63:0] lsu_axi_rdata_q;
logic [63:0] lsu_axi_rdata_q;
//------------------------------------------------------------------------------
// Load forwarding logic start
//------------------------------------------------------------------------------
@ -379,8 +379,8 @@ module lsu_bus_buffer
end
for (genvar j=0; j<4; j++) begin
assign ld_byte_hit_buf_lo[j] = |(ld_byte_hitvecfn_lo[j]) | ld_byte_ibuf_hit_lo[j];
assign ld_byte_hit_buf_hi[j] = |(ld_byte_hitvecfn_hi[j]) | ld_byte_ibuf_hit_hi[j];
assign ld_byte_hit_buf_lo[j] = |(ld_byte_hitvecfn_lo[j]) | ld_byte_ibuf_hit_lo[j];
assign ld_byte_hit_buf_hi[j] = |(ld_byte_hitvecfn_hi[j]) | ld_byte_ibuf_hit_hi[j];
for (genvar i=0; i<DEPTH; i++) begin
assign ld_byte_hitvec_lo[j][i] = ld_addr_hitvec_lo[i] & buf_byteen[i][j] & ldst_byteen_lo_dc2[j];
assign ld_byte_hitvec_hi[j][i] = ld_addr_hitvec_hi[i] & buf_byteen[i][j] & ldst_byteen_hi_dc2[j];
@ -393,7 +393,7 @@ module lsu_bus_buffer
// Hit in the ibuf
assign ld_addr_ibuf_hit_lo = (lsu_addr_dc2[31:2] == ibuf_addr[31:2]) & ibuf_write & ibuf_valid & lsu_busreq_dc2;
assign ld_addr_ibuf_hit_hi = (end_addr_dc2[31:2] == ibuf_addr[31:2]) & ibuf_write & ibuf_valid & lsu_busreq_dc2;
for (genvar i=0; i<4; i++) begin
assign ld_byte_ibuf_hit_lo[i] = ld_addr_ibuf_hit_lo & ibuf_byteen[i] & ldst_byteen_lo_dc2[i];
assign ld_byte_ibuf_hit_hi[i] = ld_addr_ibuf_hit_hi & ibuf_byteen[i] & ldst_byteen_hi_dc2[i];
@ -414,7 +414,7 @@ module lsu_bus_buffer
ld_fwddata_buf_hi[31:24] |= {8{ld_byte_hitvecfn_hi[3][i]}} & buf_data[i][31:24];
end
end
//------------------------------------------------------------------------------
// Load forwarding logic end
//------------------------------------------------------------------------------
@ -424,16 +424,16 @@ module lsu_bus_buffer
`else
assign bus_coalescing_disable = dec_tlu_wb_coalescing_disable;
`endif
// Get the hi/lo byte enable
assign ldst_byteen_dc5[3:0] = ({4{lsu_pkt_dc5.by}} & 4'b0001) |
({4{lsu_pkt_dc5.half}} & 4'b0011) |
({4{lsu_pkt_dc5.word}} & 4'b1111);
assign {ldst_byteen_hi_dc5[3:0], ldst_byteen_lo_dc5[3:0]} = {4'b0,ldst_byteen_dc5[3:0]} << lsu_addr_dc5[1:0];
assign {ldst_byteen_hi_dc5[3:0], ldst_byteen_lo_dc5[3:0]} = {4'b0,ldst_byteen_dc5[3:0]} << lsu_addr_dc5[1:0];
assign {store_data_hi_dc5[31:0], store_data_lo_dc5[31:0]} = {32'b0,store_data_dc5[31:0]} << {lsu_addr_dc5[1:0],3'b0};
assign ldst_samedw_dc5 = (lsu_addr_dc5[3] == end_addr_dc5[3]);
//------------------------------------------------------------------------------
// Input buffer logic starts here
//------------------------------------------------------------------------------
@ -442,8 +442,8 @@ module lsu_bus_buffer
assign ibuf_wr_en = lsu_busreq_dc5 & (lsu_commit_dc5 | lsu_freeze_dc3) & ~ibuf_byp;
assign ibuf_rst = ibuf_drain_vld & ~ibuf_wr_en;
assign ibuf_force_drain = lsu_busreq_dc2 & ~lsu_busreq_dc3 & ~lsu_busreq_dc4 & ~lsu_busreq_dc5 & ibuf_valid & (lsu_pkt_dc2.load | (ibuf_addr[31:2] != lsu_addr_dc2[31:2])); // Move the ibuf to buf if there is a non-colaescable ld/st in dc2 but nothing in dc3/dc4/dc5
assign ibuf_drain_vld = ibuf_valid & (((ibuf_wr_en | (ibuf_timer == TIMER_MAX)) & ~(ibuf_merge_en & ibuf_merge_in)) | ibuf_byp | ibuf_force_drain | ibuf_sideeffect | ~ibuf_write | bus_coalescing_disable);
assign ibuf_tag_in[DEPTH_LOG2-1:0] = (ibuf_merge_en & ibuf_merge_in) ? ibuf_tag[DEPTH_LOG2-1:0] : (ldst_dual_dc5 ? WrPtr1_dc5 : WrPtr0_dc5);
assign ibuf_drain_vld = ibuf_valid & (((ibuf_wr_en | (ibuf_timer == TIMER_MAX)) & ~(ibuf_merge_en & ibuf_merge_in)) | ibuf_byp | ibuf_force_drain | ibuf_sideeffect | ~ibuf_write | bus_coalescing_disable);
assign ibuf_tag_in[DEPTH_LOG2-1:0] = (ibuf_merge_en & ibuf_merge_in) ? ibuf_tag[DEPTH_LOG2-1:0] : (ldst_dual_dc5 ? WrPtr1_dc5 : WrPtr0_dc5);
assign ibuf_dualtag_in[DEPTH_LOG2-1:0] = WrPtr0_dc5;
assign ibuf_sz_in[1:0] = {lsu_pkt_dc5.word, lsu_pkt_dc5.half}; // NOTE: Make sure lsu_pkt_dc3/dc4 are flopped in case of freeze (except the valid)
assign ibuf_addr_in[31:0] = ldst_dual_dc5 ? end_addr_dc5[31:0] : lsu_addr_dc5[31:0];
@ -454,9 +454,9 @@ module lsu_bus_buffer
end
assign ibuf_timer_in = ibuf_wr_en ? '0 : (ibuf_timer < TIMER_MAX) ? (ibuf_timer + 1'b1) : ibuf_timer;
assign ibuf_merge_en = lsu_busreq_dc5 & lsu_commit_dc5 & lsu_pkt_dc5.store & ibuf_valid & ibuf_write & (lsu_addr_dc5[31:2] == ibuf_addr[31:2]) & ~is_sideeffects_dc5 & ~bus_coalescing_disable;
assign ibuf_merge_en = lsu_busreq_dc5 & lsu_commit_dc5 & lsu_pkt_dc5.store & ibuf_valid & ibuf_write & (lsu_addr_dc5[31:2] == ibuf_addr[31:2]) & ~is_sideeffects_dc5 & ~bus_coalescing_disable;
assign ibuf_merge_in = ~ldst_dual_dc5; // If it's a unaligned store, merge needs to happen on the way out of ibuf
// ibuf signals going to bus buffer after merging
for (genvar i=0; i<4; i++) begin
assign ibuf_byteen_out[i] = (ibuf_merge_en & ~ibuf_merge_in) ? (ibuf_byteen[i] | ldst_byteen_lo_dc5[i]) : ibuf_byteen[i];
@ -492,11 +492,11 @@ module lsu_bus_buffer
assign obuf_wr_wait = (buf_numvld_wrcmd_any[3:0] == 4'b1) & (buf_numvld_cmd_any[3:0] == 4'b1) & (obuf_wr_timer != TIMER_MAX) & ~bus_coalescing_disable & ~buf_nomerge[CmdPtr0] & ~obuf_force_wr_en;
assign obuf_wr_timer_in = obuf_wr_en ? 3'b0: (((buf_numvld_cmd_any > 4'b0) & (obuf_wr_timer < TIMER_MAX)) ? (obuf_wr_timer + 1'b1) : obuf_wr_timer);
assign obuf_force_wr_en = lsu_busreq_dc2 & ~lsu_busreq_dc3 & ~lsu_busreq_dc4 & ~lsu_busreq_dc5 & ~ibuf_valid & (buf_numvld_cmd_any[3:0] == 4'b1) & (lsu_addr_dc2[31:2] != buf_addr[CmdPtr0][31:2]); // Entry in dc2 can't merge with entry going to obuf and there is no entry in between
assign ibuf_buf_byp = ibuf_byp & (buf_numvld_pend_any[3:0] == 4'b0) & ~ldst_dual_dc5 & lsu_pkt_dc5.store;
assign obuf_wr_en = (lsu_bus_clk_en & ((ibuf_buf_byp & lsu_commit_dc5) |
((buf_state[CmdPtr0] == CMD) & found_cmdptr0 & ~buf_cmd_state_bus_en[CmdPtr0] &
(~(buf_dual[CmdPtr0] & buf_samedw[CmdPtr0] & ~buf_write[CmdPtr0]) | found_cmdptr1 | buf_nomerge[CmdPtr0] | obuf_force_wr_en)))) &
assign ibuf_buf_byp = ibuf_byp & (buf_numvld_pend_any[3:0] == 4'b0) & ~ldst_dual_dc5 & lsu_pkt_dc5.store;
assign obuf_wr_en = (lsu_bus_clk_en & ((ibuf_buf_byp & lsu_commit_dc5) |
((buf_state[CmdPtr0] == CMD) & found_cmdptr0 & ~buf_cmd_state_bus_en[CmdPtr0] &
(~(buf_dual[CmdPtr0] & buf_samedw[CmdPtr0] & ~buf_write[CmdPtr0]) | found_cmdptr1 | buf_nomerge[CmdPtr0] | obuf_force_wr_en)))) &
(bus_cmd_ready | ~obuf_valid) & ~obuf_wr_wait & ~bus_sideeffect_pend & ~bus_addr_match_pending;
assign obuf_rst = bus_cmd_sent & ~obuf_wr_en;
assign obuf_write_in = ibuf_buf_byp ? lsu_pkt_dc5.store : buf_write[CmdPtr0];
@ -513,18 +513,18 @@ module lsu_bus_buffer
assign obuf_byteen0_in[7:0] = ibuf_buf_byp ? (lsu_addr_dc5[2] ? {ldst_byteen_lo_dc5[3:0],4'b0} : {4'b0,ldst_byteen_lo_dc5[3:0]}) :
(buf_addr[CmdPtr0][2] ? {buf_byteen[CmdPtr0],4'b0} : {4'b0,buf_byteen[CmdPtr0]});
assign obuf_byteen1_in[7:0] = buf_addr[CmdPtr1][2] ? {buf_byteen[CmdPtr1],4'b0} : {4'b0,buf_byteen[CmdPtr1]};
assign obuf_data0_in[63:0] = ibuf_buf_byp ? (lsu_addr_dc5[2] ? {store_data_lo_dc5[31:0],32'b0} : {32'b0,store_data_lo_dc5[31:0]}) :
assign obuf_data0_in[63:0] = ibuf_buf_byp ? (lsu_addr_dc5[2] ? {store_data_lo_dc5[31:0],32'b0} : {32'b0,store_data_lo_dc5[31:0]}) :
(buf_addr[CmdPtr0][2] ? {buf_data[CmdPtr0],32'b0} : {32'b0,buf_data[CmdPtr0]});
assign obuf_data1_in[63:0] = buf_addr[CmdPtr1][2] ? {buf_data[CmdPtr1],32'b0} : {32'b0,buf_data[CmdPtr1]};
for (genvar i=0 ;i<8; i++) begin
assign obuf_byteen_in[i] = obuf_byteen0_in[i] | (obuf_merge_en & obuf_byteen1_in[i]);
assign obuf_data_in[(8*i)+7:(8*i)] = (obuf_merge_en & obuf_byteen1_in[i]) ? obuf_data1_in[(8*i)+7:(8*i)] : obuf_data0_in[(8*i)+7:(8*i)];
end
// No store obuf merging for AXI since all stores are sent non-posted. Can't track the second id right now
assign obuf_merge_en = (CmdPtr0 != CmdPtr1) & found_cmdptr0 & found_cmdptr1 & (buf_state[CmdPtr0] == CMD) & (buf_state[CmdPtr1] == CMD) & ~buf_cmd_state_bus_en[CmdPtr0] & ~buf_sideeffect[CmdPtr0] &
assign obuf_merge_en = (CmdPtr0 != CmdPtr1) & found_cmdptr0 & found_cmdptr1 & (buf_state[CmdPtr0] == CMD) & (buf_state[CmdPtr1] == CMD) & ~buf_cmd_state_bus_en[CmdPtr0] & ~buf_sideeffect[CmdPtr0] &
(~buf_write[CmdPtr0] & buf_dual[CmdPtr0] & ~buf_dualhi[CmdPtr0] & buf_samedw[CmdPtr0]); // CmdPtr0/CmdPtr1 are for same load which is within a DW
rvdff #(.WIDTH(1)) obuf_wren_ff (.din(obuf_wr_en), .dout(obuf_wr_enQ), .clk(lsu_busm_clk), .*);
rvdff #(.WIDTH(1)) obuf_cmd_done_ff (.din(obuf_cmd_done_in), .dout(obuf_cmd_done), .clk(lsu_busm_clk), .*);
rvdff #(.WIDTH(1)) obuf_data_done_ff (.din(obuf_data_done_in), .dout(obuf_data_done), .clk(lsu_busm_clk), .*);
@ -539,7 +539,7 @@ module lsu_bus_buffer
rvdffs #(.WIDTH(8)) obuf_byteenff (.din(obuf_byteen_in[7:0]), .dout(obuf_byteen), .en(obuf_wr_en), .clk(lsu_bus_obuf_c1_clk), .*);
rvdffe #(.WIDTH(64)) obuf_dataff (.din(obuf_data_in[63:0]), .dout(obuf_data), .en(obuf_wr_en), .*);
rvdff #(.WIDTH(TIMER_LOG2)) obuf_timerff (.din(obuf_wr_timer_in), .dout(obuf_wr_timer), .clk(lsu_busm_clk), .*);
//------------------------------------------------------------------------------
// Output buffer logic ends here
//------------------------------------------------------------------------------
@ -556,7 +556,7 @@ module lsu_bus_buffer
if (~found_wrptr0) begin
WrPtr0_dc3[DEPTH_LOG2-1:0] = DEPTH_LOG2'(i);
found_wrptr0 = (buf_state[i] == IDLE) & ~((ibuf_valid & (ibuf_tag == DEPTH_LOG2'(i))) |
(lsu_busreq_dc4 & ((WrPtr0_dc4 == DEPTH_LOG2'(i)) | (ldst_dual_dc4 & (WrPtr1_dc4 == DEPTH_LOG2'(i))))) |
(lsu_busreq_dc4 & ((WrPtr0_dc4 == DEPTH_LOG2'(i)) | (ldst_dual_dc4 & (WrPtr1_dc4 == DEPTH_LOG2'(i))))) |
(lsu_busreq_dc5 & ((WrPtr0_dc5 == DEPTH_LOG2'(i)) | (ldst_dual_dc5 & (WrPtr1_dc5 == DEPTH_LOG2'(i))))));
//found_wrptr = (buf_state[i] == IDLE);
end
@ -568,7 +568,7 @@ module lsu_bus_buffer
WrPtr1_dc3[DEPTH_LOG2-1:0] = DEPTH_LOG2'(i);
found_wrptr1 = (buf_state[i] == IDLE) & ~((ibuf_valid & (ibuf_tag == DEPTH_LOG2'(i))) |
(lsu_busreq_dc3 & (WrPtr0_dc3 == DEPTH_LOG2'(i))) |
(lsu_busreq_dc4 & ((WrPtr0_dc4 == DEPTH_LOG2'(i)) | (ldst_dual_dc4 & (WrPtr1_dc4 == DEPTH_LOG2'(i))))) |
(lsu_busreq_dc4 & ((WrPtr0_dc4 == DEPTH_LOG2'(i)) | (ldst_dual_dc4 & (WrPtr1_dc4 == DEPTH_LOG2'(i))))) |
(lsu_busreq_dc5 & ((WrPtr0_dc5 == DEPTH_LOG2'(i)) | (ldst_dual_dc5 & (WrPtr1_dc5 == DEPTH_LOG2'(i))))));
//found_wrptr = (buf_state[i] == IDLE);
end
@ -590,14 +590,14 @@ module lsu_bus_buffer
// Age vector
for (genvar i=0; i<DEPTH; i++) begin: GenAgeVec
for (genvar j=0; j<DEPTH; j++) begin
assign buf_age_in[i][j] = (((buf_state[i] == IDLE) & buf_state_en[i]) &
assign buf_age_in[i][j] = (((buf_state[i] == IDLE) & buf_state_en[i]) &
(((buf_state[j] == WAIT) | ((buf_state[j] == CMD) & ~buf_cmd_state_bus_en[j])) | // Set age bit for older entries
(ibuf_drain_vld & lsu_busreq_dc5 & (ibuf_byp | ldst_dual_dc5) & (DEPTH_LOG2'(i) == WrPtr0_dc5) & (DEPTH_LOG2'(j) == ibuf_tag)) | // Set case for dual lo
(ibuf_byp & lsu_busreq_dc5 & ldst_dual_dc5 & (DEPTH_LOG2'(i) == WrPtr1_dc5) & (DEPTH_LOG2'(j) == WrPtr0_dc5)))) | // ibuf bypass case
buf_age[i][j];
assign buf_age[i][j] = buf_ageQ[i][j] & ~((buf_state[j] == CMD) & buf_cmd_state_bus_en[j]); // Reset case
assign buf_age_younger[i][j] = (i == j) ? 1'b0: (~buf_age[i][j] & (buf_state[j] != IDLE)); // Younger entries
assign buf_age_younger[i][j] = (i == j) ? 1'b0: (~buf_age[i][j] & (buf_state[j] != IDLE)); // Younger entries
assign buf_age_temp[i][j] = buf_age[i][j] & ~(CmdPtr0 == DEPTH_LOG2'(j)); // Used to determine CmdPtr1
end
end
@ -634,7 +634,7 @@ module lsu_bus_buffer
buf_data_in[i] = '0;
buf_data_en[i] = '0;
buf_error_en[i] = '0;
buf_rst[i] = '0;
buf_rst[i] = '0;
case (buf_state[i])
IDLE: begin
@ -671,7 +671,7 @@ module lsu_bus_buffer
buf_nxtstate[i] = IDLE;
buf_rst[i] = lsu_bus_clk_en_q & (buf_write[i] | ~buf_dual[i] | (buf_state[buf_dualtag[i]] == DONE));
buf_state_en[i] = buf_rst[i];
end
end
default : begin
buf_nxtstate[i] = IDLE;
buf_state_en[i] = '0;
@ -682,7 +682,7 @@ module lsu_bus_buffer
buf_data_in[i] = '0;
buf_data_en[i] = '0;
buf_error_en[i] = '0;
buf_rst[i] = '0;
buf_rst[i] = '0;
end
endcase
end
@ -706,13 +706,13 @@ module lsu_bus_buffer
rvdffsc #(.WIDTH(1)) buf_errorff (.din(1'b1), .dout(buf_error[i]), .en(buf_error_en[i]), .clear(buf_rst[i]), .clk(lsu_bus_buf_c1_clk), .*);
end
// buffer full logic
always_comb begin
buf_numvld_any[3:0] = ({3'b0,(lsu_pkt_dc1.valid & ~lsu_pkt_dc1.dma)} << (lsu_pkt_dc1.valid & ldst_dual_dc1)) +
({3'b0,lsu_busreq_dc2} << ldst_dual_dc2) +
({3'b0,lsu_busreq_dc3} << ldst_dual_dc3) +
({3'b0,lsu_busreq_dc4} << ldst_dual_dc4) +
buf_numvld_any[3:0] = ({3'b0,(lsu_pkt_dc1.valid & ~lsu_pkt_dc1.dma)} << (lsu_pkt_dc1.valid & ldst_dual_dc1)) +
({3'b0,lsu_busreq_dc2} << ldst_dual_dc2) +
({3'b0,lsu_busreq_dc3} << ldst_dual_dc3) +
({3'b0,lsu_busreq_dc4} << ldst_dual_dc4) +
({3'b0,lsu_busreq_dc5} << ldst_dual_dc5) +
{3'b0,ibuf_valid};
buf_numvld_wrcmd_any[3:0] = 4'b0;
@ -728,11 +728,11 @@ module lsu_bus_buffer
assign lsu_bus_buffer_pend_any = (buf_numvld_pend_any != 0);
assign lsu_bus_buffer_full_any = (buf_numvld_any[3:0] >= (DEPTH-1));
assign lsu_bus_buffer_empty_any = ~(|buf_state[DEPTH-1:0]) & ~ibuf_valid & ~obuf_valid;
assign lsu_bus_buffer_empty_any = ~(|buf_state[DEPTH-1:0]) & ~ibuf_valid & ~obuf_valid;
// Freeze logic
assign FreezePtrEn = lsu_busreq_dc3 & lsu_pkt_dc3.load & ld_freeze_dc3;
assign ld_freeze_en = (is_sideeffects_dc2 | dec_nonblock_load_freeze_dc2 | dec_tlu_non_blocking_disable) & lsu_busreq_dc2 & lsu_pkt_dc2.load & ~lsu_freeze_dc3 & ~flush_dc2_up & ~ld_full_hit_dc2;
assign ld_freeze_en = (is_sideeffects_dc2 | dec_nonblock_load_freeze_dc2 | dec_tlu_non_blocking_disable) & lsu_busreq_dc2 & lsu_pkt_dc2.load & ~lsu_freeze_dc3 & ~flush_dc2_up & ~ld_full_hit_dc2;
always_comb begin
ld_freeze_rst = flush_dc3 | (dec_tlu_cancel_e4 & ld_freeze_dc3);
for (int i=0; i<DEPTH; i++) begin
@ -794,7 +794,7 @@ module lsu_bus_buffer
end
// Imprecise bus errors
// Imprecise bus errors
assign lsu_imprecise_error_load_any = lsu_nonblock_load_data_error; // This is to make sure we send only one imprecise error for loads
@ -802,7 +802,7 @@ module lsu_bus_buffer
always_comb begin
bus_addr_match_pending = '0;
for (int i=0; i<DEPTH; i++) begin
bus_addr_match_pending |= (obuf_valid & (obuf_addr[31:3] == buf_addr[i][31:3]) & (buf_state[i] == RESP) & ~((obuf_tag0 == LSU_BUS_TAG'(i)) | (obuf_merge & (obuf_tag1 == LSU_BUS_TAG'(i)))));
bus_addr_match_pending |= (obuf_valid & (obuf_addr[31:3] == buf_addr[i][31:3]) & (buf_state[i] == RESP) & ~((obuf_tag0 == LSU_BUS_TAG'(i)) | (obuf_merge & (obuf_tag1 == LSU_BUS_TAG'(i)))));
end
end
@ -817,17 +817,17 @@ module lsu_bus_buffer
end
end
assign lsu_imprecise_error_addr_any[31:0] = lsu_imprecise_error_load_any ? buf_addr[lsu_nonblock_load_data_tag] : buf_addr[lsu_imprecise_error_store_tag];
// Generic bus signals
assign bus_cmd_ready = obuf_write ? ((obuf_cmd_done | obuf_data_done) ? (obuf_cmd_done ? lsu_axi_wready : lsu_axi_awready) : (lsu_axi_awready & lsu_axi_wready)) : lsu_axi_arready;
assign bus_wcmd_sent = lsu_axi_awvalid & lsu_axi_awready;
assign bus_wdata_sent = lsu_axi_wvalid & lsu_axi_wready;
assign bus_cmd_sent = ((obuf_cmd_done | bus_wcmd_sent) & (obuf_data_done | bus_wdata_sent)) | (lsu_axi_arvalid & lsu_axi_arready);
assign bus_rsp_read = lsu_axi_rvalid_q & lsu_axi_rready_q;
assign bus_rsp_write = lsu_axi_bvalid_q & lsu_axi_bready_q;
assign bus_rsp_read_tag[LSU_BUS_TAG-1:0] = lsu_axi_rid_q[LSU_BUS_TAG-1:0];
assign bus_rsp_write_tag[LSU_BUS_TAG-1:0] = lsu_axi_bid_q[LSU_BUS_TAG-1:0];
assign bus_rsp_write = lsu_axi_bvalid_q & lsu_axi_bready_q;
assign bus_rsp_read_tag[LSU_BUS_TAG-1:0] = lsu_axi_rid_q[LSU_BUS_TAG-1:0];
assign bus_rsp_write_tag[LSU_BUS_TAG-1:0] = lsu_axi_bid_q[LSU_BUS_TAG-1:0];
assign bus_rsp_write_error = bus_rsp_write & (lsu_axi_bresp_q[1:0] != 2'b0);
assign bus_rsp_read_error = bus_rsp_read & (lsu_axi_rresp_q[1:0] != 2'b0);
assign bus_rsp_rdata[63:0] = lsu_axi_rdata_q[63:0];
@ -838,7 +838,7 @@ module lsu_bus_buffer
assign lsu_axi_awaddr[31:0] = obuf_sideeffect ? obuf_addr[31:0] : {obuf_addr[31:3],3'b0};
assign lsu_axi_awsize[2:0] = obuf_sideeffect ? {1'b0, obuf_sz[1:0]} : 3'b011;
assign lsu_axi_awprot[2:0] = '0;
assign lsu_axi_awcache[3:0] = obuf_sideeffect ? 4'b0 : 4'b1111;
assign lsu_axi_awcache[3:0] = obuf_sideeffect ? 4'b0 : 4'b1111;
assign lsu_axi_awregion[3:0] = obuf_addr[31:28];
assign lsu_axi_awlen[7:0] = '0;
assign lsu_axi_awburst[1:0] = 2'b01;
@ -855,13 +855,13 @@ module lsu_bus_buffer
assign lsu_axi_araddr[31:0] = obuf_sideeffect ? obuf_addr[31:0] : {obuf_addr[31:3],3'b0};
assign lsu_axi_arsize[2:0] = obuf_sideeffect ? {1'b0, obuf_sz[1:0]} : 3'b011;
assign lsu_axi_arprot[2:0] = '0;
assign lsu_axi_arcache[3:0] = obuf_sideeffect ? 4'b0 : 4'b1111;
assign lsu_axi_arcache[3:0] = obuf_sideeffect ? 4'b0 : 4'b1111;
assign lsu_axi_arregion[3:0] = obuf_addr[31:28];
assign lsu_axi_arlen[7:0] = '0;
assign lsu_axi_arburst[1:0] = 2'b01;
assign lsu_axi_arqos[3:0] = '0;
assign lsu_axi_arlock = '0;
assign lsu_axi_bready = 1;
assign lsu_axi_rready = 1;
@ -870,7 +870,7 @@ module lsu_bus_buffer
assign lsu_pmu_bus_misaligned = lsu_busreq_dc2 & ldst_dual_dc2;
assign lsu_pmu_bus_error = ld_bus_error_dc3 | lsu_imprecise_error_load_any | lsu_imprecise_error_store_any;
assign lsu_pmu_bus_busy = (lsu_axi_awvalid_q & ~lsu_axi_awready_q) | (lsu_axi_wvalid_q & ~lsu_axi_wready_q) | (lsu_axi_arvalid_q & ~lsu_axi_arready_q);
rvdff #(.WIDTH(1)) lsu_axi_awvalid_ff (.din(lsu_axi_awvalid), .dout(lsu_axi_awvalid_q), .clk(lsu_busm_clk), .*);
rvdff #(.WIDTH(1)) lsu_axi_awready_ff (.din(lsu_axi_awready), .dout(lsu_axi_awready_q), .clk(lsu_busm_clk), .*);
rvdff #(.WIDTH(1)) lsu_axi_wvalid_ff (.din(lsu_axi_wvalid), .dout(lsu_axi_wvalid_q), .clk(lsu_busm_clk), .*);
@ -888,7 +888,7 @@ module lsu_bus_buffer
rvdff #(.WIDTH(1)) lsu_axi_rready_ff (.din(lsu_axi_rready), .dout(lsu_axi_rready_q), .clk(lsu_busm_clk), .*);
rvdff #(.WIDTH(2)) lsu_axi_rresp_ff (.din(lsu_axi_rresp[1:0]), .dout(lsu_axi_rresp_q[1:0]), .clk(lsu_busm_clk), .*);
rvdff #(.WIDTH(LSU_BUS_TAG)) lsu_axi_rid_ff (.din(lsu_axi_rid[LSU_BUS_TAG-1:0]), .dout(lsu_axi_rid_q[LSU_BUS_TAG-1:0]), .clk(lsu_busm_clk), .*);
// General flops
rvdffsc #(.WIDTH(1)) ld_freezeff (.din(1'b1), .dout(ld_freeze_dc3), .en(ld_freeze_en), .clear(ld_freeze_rst), .clk(lsu_free_c2_clk), .*);
rvdffs #(.WIDTH(DEPTH_LOG2)) lsu_FreezePtrff (.din(WrPtr0_dc3), .dout(FreezePtr), .en(FreezePtrEn), .clk(lsu_free_c2_clk), .*);
@ -914,10 +914,10 @@ module lsu_bus_buffer
assert_ld_byte_hitvecfn_lo_onehot: assert #0 ($onehot0(ld_byte_hitvecfn_lo[i][DEPTH-1:0]));
assert_ld_byte_hitvecfn_hi_onehot: assert #0 ($onehot0(ld_byte_hitvecfn_hi[i][DEPTH-1:0]));
end
assert_CmdPtr0Dec_onehot: assert #0 ($onehot0(CmdPtr0Dec[DEPTH-1:0]));
assert_CmdPtr1Dec_onehot: assert #0 ($onehot0(CmdPtr1Dec[DEPTH-1:0]));
`endif
endmodule // lsu_bus_buffer

View File

@ -1,12 +1,12 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright 2019 Western Digital Corporation or its affiliates.
//
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//
// http://www.apache.org/licenses/LICENSE-2.0
//
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -16,13 +16,13 @@
//********************************************************************************
// $Id$
//
//
// Owner:
//
// Owner:
// Function: lsu interface with interface queue
// Comments:
//
//********************************************************************************
module lsu_bus_intf
module lsu_bus_intf
import swerv_types::*;
(
input logic clk,
@ -32,9 +32,9 @@ module lsu_bus_intf
input logic dec_tlu_wb_coalescing_disable, // disable write buffer coalescing
input logic dec_tlu_ld_miss_byp_wb_disable, // disable ld miss bypass of the write buffer
input logic dec_tlu_sideeffect_posted_disable, // disable posted writes to sideeffect addr to the bus
// various clocks needed for the bus reads and writes
input logic lsu_c1_dc3_clk,
input logic lsu_c1_dc3_clk,
input logic lsu_c1_dc4_clk,
input logic lsu_c1_dc5_clk,
input logic lsu_c2_dc3_clk,
@ -50,9 +50,9 @@ module lsu_bus_intf
input logic lsu_free_c2_clk,
input logic free_clk,
input logic lsu_busm_clk,
input logic lsu_busreq_dc2, // bus request is in dc2
input lsu_pkt_t lsu_pkt_dc1, // lsu packet flowing down the pipe
input lsu_pkt_t lsu_pkt_dc2, // lsu packet flowing down the pipe
input lsu_pkt_t lsu_pkt_dc3, // lsu packet flowing down the pipe
@ -71,7 +71,7 @@ module lsu_bus_intf
input logic [31:0] end_addr_dc4, // lsu address flowing down the pipe
input logic [31:0] end_addr_dc5, // lsu address flowing down the pipe
input logic addr_external_dc2, // lsu instruction going to external
input logic addr_external_dc2, // lsu instruction going to external
input logic addr_external_dc3, // lsu instruction going to external
input logic addr_external_dc4, // lsu instruction going to external
input logic addr_external_dc5, // lsu instruction going to external
@ -84,7 +84,7 @@ module lsu_bus_intf
input logic lsu_commit_dc5, // lsu instruction in dc5 commits
input logic is_sideeffects_dc2, // lsu attribute is side_effects
input logic is_sideeffects_dc3, // lsu attribute is side_effects
input logic flush_dc2_up, // flush
input logic flush_dc2_up, // flush
input logic flush_dc3, // flush
input logic flush_dc4, // flush
input logic flush_dc5, // flush
@ -98,7 +98,7 @@ module lsu_bus_intf
output logic [31:0] bus_read_data_dc3, // the bus return data
output logic ld_bus_error_dc3, // bus error in dc3
output logic [31:0] ld_bus_error_addr_dc3, // address of the bus error
output logic [31:0] ld_bus_error_addr_dc3, // address of the bus error
output logic lsu_imprecise_error_load_any, // imprecise load bus error
output logic lsu_imprecise_error_store_any, // imprecise store bus error
@ -110,17 +110,17 @@ module lsu_bus_intf
output logic [`RV_LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_tag_dc3, // the tag of the external non block load
output logic lsu_nonblock_load_inv_dc5, // invalidate signal for the cam entry for non block loads
output logic [`RV_LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_inv_tag_dc5, // tag of the enrty which needs to be invalidated
output logic lsu_nonblock_load_data_valid, // the non block is valid - sending information back to the cam
output logic lsu_nonblock_load_data_error, // non block load has an error
output logic [`RV_LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_data_tag, // the tag of the non block load sending the data/error
output logic [31:0] lsu_nonblock_load_data, // Data of the non block load
output logic lsu_nonblock_load_data_valid, // the non block is valid - sending information back to the cam
output logic lsu_nonblock_load_data_error, // non block load has an error
output logic [`RV_LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_data_tag, // the tag of the non block load sending the data/error
output logic [31:0] lsu_nonblock_load_data, // Data of the non block load
// PMU events
output logic lsu_pmu_bus_trxn,
output logic lsu_pmu_bus_misaligned,
output logic lsu_pmu_bus_error,
output logic lsu_pmu_bus_busy,
// AXI Write Channels
output logic lsu_axi_awvalid,
input logic lsu_axi_awready,
@ -134,19 +134,19 @@ module lsu_bus_intf
output logic [3:0] lsu_axi_awcache,
output logic [2:0] lsu_axi_awprot,
output logic [3:0] lsu_axi_awqos,
output logic lsu_axi_wvalid,
output logic lsu_axi_wvalid,
input logic lsu_axi_wready,
output logic [63:0] lsu_axi_wdata,
output logic [7:0] lsu_axi_wstrb,
output logic lsu_axi_wlast,
input logic lsu_axi_bvalid,
output logic lsu_axi_bready,
input logic [1:0] lsu_axi_bresp,
input logic [`RV_LSU_BUS_TAG-1:0] lsu_axi_bid,
// AXI Read Channels
// AXI Read Channels
output logic lsu_axi_arvalid,
input logic lsu_axi_arready,
output logic [`RV_LSU_BUS_TAG-1:0] lsu_axi_arid,
@ -159,7 +159,7 @@ module lsu_bus_intf
output logic [3:0] lsu_axi_arcache,
output logic [2:0] lsu_axi_arprot,
output logic [3:0] lsu_axi_arqos,
input logic lsu_axi_rvalid,
output logic lsu_axi_rready,
input logic [`RV_LSU_BUS_TAG-1:0] lsu_axi_rid,
@ -173,27 +173,27 @@ module lsu_bus_intf
`include "global.h"
logic ld_freeze_dc3;
logic ld_freeze_dc3;
logic lsu_bus_clk_en_q;
logic ldst_dual_dc1, ldst_dual_dc2, ldst_dual_dc3, ldst_dual_dc4, ldst_dual_dc5;
logic lsu_busreq_dc3, lsu_busreq_dc4;
logic [3:0] ldst_byteen_dc2, ldst_byteen_dc3, ldst_byteen_dc4, ldst_byteen_dc5;
logic [7:0] ldst_byteen_ext_dc2, ldst_byteen_ext_dc3, ldst_byteen_ext_dc4, ldst_byteen_ext_dc5;
logic [3:0] ldst_byteen_hi_dc2, ldst_byteen_hi_dc3, ldst_byteen_hi_dc4, ldst_byteen_hi_dc5;
logic [3:0] ldst_byteen_lo_dc2, ldst_byteen_lo_dc3, ldst_byteen_lo_dc4, ldst_byteen_lo_dc5;
logic is_sideeffects_dc4, is_sideeffects_dc5;
logic [63:0] store_data_ext_dc3, store_data_ext_dc4, store_data_ext_dc5;
logic [31:0] store_data_hi_dc3, store_data_hi_dc4, store_data_hi_dc5;
logic [31:0] store_data_lo_dc3, store_data_lo_dc4, store_data_lo_dc5;
logic addr_match_dw_lo_dc5_dc4, addr_match_dw_lo_dc5_dc3, addr_match_dw_lo_dc5_dc2;
logic addr_match_word_lo_dc5_dc4, addr_match_word_lo_dc5_dc3, addr_match_word_lo_dc5_dc2;
logic no_word_merge_dc5, no_dword_merge_dc5;
logic ld_addr_dc3hit_lo_lo, ld_addr_dc3hit_hi_lo, ld_addr_dc3hit_lo_hi, ld_addr_dc3hit_hi_hi;
logic ld_addr_dc4hit_lo_lo, ld_addr_dc4hit_hi_lo, ld_addr_dc4hit_lo_hi, ld_addr_dc4hit_hi_hi;
logic ld_addr_dc5hit_lo_lo, ld_addr_dc5hit_hi_lo, ld_addr_dc5hit_lo_hi, ld_addr_dc5hit_hi_hi;
@ -210,20 +210,20 @@ module lsu_bus_intf
logic [3:0] ld_byte_hit_buf_lo, ld_byte_hit_buf_hi;
logic [31:0] ld_fwddata_buf_lo, ld_fwddata_buf_hi;
logic ld_hit_rdbuf_hi, ld_hit_rdbuf_lo;
logic [31:0] ld_fwddata_rdbuf_hi, ld_fwddata_rdbuf_lo;
logic [63:0] ld_fwddata_lo, ld_fwddata_hi;
logic [31:0] ld_fwddata_dc2, ld_fwddata_dc3;
logic [31:0] ld_bus_data_dc3;
logic ld_full_hit_hi_dc2, ld_full_hit_lo_dc2;
logic ld_hit_dc2, ld_full_hit_dc2, ld_full_hit_dc3;
logic is_aligned_dc5;
logic [63:32] ld_fwddata_dc2_nc;
logic lsu_write_buffer_empty_any;
assign lsu_write_buffer_empty_any = 1'b1;
@ -232,7 +232,7 @@ module lsu_bus_intf
({4{lsu_pkt_dc2.word}} & 4'b1111);
assign ldst_dual_dc1 = (lsu_addr_dc1[2] != end_addr_dc1[2]);
assign lsu_freeze_dc3 = ld_freeze_dc3 & ~(flush_dc4 | flush_dc5);
// Determine if the packet is word aligned
assign is_aligned_dc5 = (lsu_pkt_dc5.word & (lsu_addr_dc5[1:0] == 2'b0)) |
(lsu_pkt_dc5.half & (lsu_addr_dc5[0] == 1'b0));
@ -247,16 +247,16 @@ module lsu_bus_intf
assign addr_match_dw_lo_dc5_dc3 = (lsu_addr_dc5[31:3] == lsu_addr_dc3[31:3]);
assign addr_match_dw_lo_dc5_dc2 = (lsu_addr_dc5[31:3] == lsu_addr_dc2[31:3]);
assign addr_match_word_lo_dc5_dc4 = addr_match_dw_lo_dc5_dc4 & ~(lsu_addr_dc5[2]^lsu_addr_dc4[2]);
assign addr_match_word_lo_dc5_dc3 = addr_match_dw_lo_dc5_dc3 & ~(lsu_addr_dc5[2]^lsu_addr_dc3[2]);
assign addr_match_word_lo_dc5_dc2 = addr_match_dw_lo_dc5_dc2 & ~(lsu_addr_dc5[2]^lsu_addr_dc2[2]);
assign no_word_merge_dc5 = lsu_busreq_dc5 & ~ldst_dual_dc5 &
assign addr_match_word_lo_dc5_dc4 = addr_match_dw_lo_dc5_dc4 & ~(lsu_addr_dc5[2]^lsu_addr_dc4[2]);
assign addr_match_word_lo_dc5_dc3 = addr_match_dw_lo_dc5_dc3 & ~(lsu_addr_dc5[2]^lsu_addr_dc3[2]);
assign addr_match_word_lo_dc5_dc2 = addr_match_dw_lo_dc5_dc2 & ~(lsu_addr_dc5[2]^lsu_addr_dc2[2]);
assign no_word_merge_dc5 = lsu_busreq_dc5 & ~ldst_dual_dc5 &
((lsu_busreq_dc4 & (lsu_pkt_dc4.load | ~addr_match_word_lo_dc5_dc4)) |
(lsu_busreq_dc3 & ~lsu_busreq_dc4 & (lsu_pkt_dc3.load | ~addr_match_word_lo_dc5_dc3)) |
(lsu_busreq_dc2 & ~lsu_busreq_dc3 & ~lsu_busreq_dc4 & (lsu_pkt_dc2.load | ~addr_match_word_lo_dc5_dc2)));
assign no_dword_merge_dc5 = lsu_busreq_dc5 & ~ldst_dual_dc5 &
assign no_dword_merge_dc5 = lsu_busreq_dc5 & ~ldst_dual_dc5 &
((lsu_busreq_dc4 & (lsu_pkt_dc4.load | ~addr_match_dw_lo_dc5_dc4)) |
(lsu_busreq_dc3 & ~lsu_busreq_dc4 & (lsu_pkt_dc3.load | ~addr_match_dw_lo_dc5_dc3)) |
(lsu_busreq_dc2 & ~lsu_busreq_dc3 & ~lsu_busreq_dc4 & (lsu_pkt_dc2.load | ~addr_match_dw_lo_dc5_dc2)));
@ -270,7 +270,7 @@ module lsu_bus_intf
assign store_data_ext_dc3[63:0] = {32'b0,store_data_dc3[31:0]} << {lsu_addr_dc3[1:0],3'b0};
assign store_data_ext_dc4[63:0] = {32'b0,store_data_dc4[31:0]} << {lsu_addr_dc4[1:0],3'b0};
assign store_data_ext_dc5[63:0] = {32'b0,store_data_dc5[31:0]} << {lsu_addr_dc5[1:0],3'b0};
assign ldst_byteen_hi_dc2[3:0] = ldst_byteen_ext_dc2[7:4];
assign ldst_byteen_lo_dc2[3:0] = ldst_byteen_ext_dc2[3:0];
assign ldst_byteen_hi_dc3[3:0] = ldst_byteen_ext_dc3[7:4];
@ -286,7 +286,7 @@ module lsu_bus_intf
assign store_data_lo_dc4[31:0] = store_data_ext_dc4[31:0];
assign store_data_hi_dc5[31:0] = store_data_ext_dc5[63:32];
assign store_data_lo_dc5[31:0] = store_data_ext_dc5[31:0];
assign ld_addr_dc3hit_lo_lo = (lsu_addr_dc2[31:2] == lsu_addr_dc3[31:2]) & lsu_pkt_dc3.valid & lsu_pkt_dc3.store & lsu_busreq_dc2;
assign ld_addr_dc3hit_lo_hi = (end_addr_dc2[31:2] == lsu_addr_dc3[31:2]) & lsu_pkt_dc3.valid & lsu_pkt_dc3.store & lsu_busreq_dc2;
assign ld_addr_dc3hit_hi_lo = (lsu_addr_dc2[31:2] == end_addr_dc3[31:2]) & lsu_pkt_dc3.valid & lsu_pkt_dc3.store & lsu_busreq_dc2;
@ -356,7 +356,7 @@ module lsu_bus_intf
ld_byte_dc4hit_lo[i] ? ld_fwddata_dc4pipe_lo[(8*i)+7:(8*i)] :
ld_byte_dc5hit_lo[i] ? ld_fwddata_dc5pipe_lo[(8*i)+7:(8*i)] :
ld_fwddata_buf_lo[(8*i)+7:(8*i)];
assign ld_fwddata_hi[(8*i)+7:(8*i)] = ld_byte_dc3hit_hi[i] ? ld_fwddata_dc3pipe_hi[(8*i)+7:(8*i)] :
ld_byte_dc4hit_hi[i] ? ld_fwddata_dc4pipe_hi[(8*i)+7:(8*i)] :
ld_byte_dc5hit_hi[i] ? ld_fwddata_dc5pipe_hi[(8*i)+7:(8*i)] :
@ -364,7 +364,7 @@ module lsu_bus_intf
end
always_comb begin
always_comb begin
ld_full_hit_lo_dc2 = 1'b1;
ld_full_hit_hi_dc2 = 1'b1;
for (int i=0; i<4; i++) begin
@ -381,7 +381,7 @@ module lsu_bus_intf
assign {ld_fwddata_dc2_nc[63:32], ld_fwddata_dc2[31:0]} = {ld_fwddata_hi[31:0], ld_fwddata_lo[31:0]} >> (8*lsu_addr_dc2[1:0]);
assign bus_read_data_dc3[31:0] = ld_full_hit_dc3 ? ld_fwddata_dc3[31:0] : ld_bus_data_dc3[31:0];
// Fifo flops
rvdff #(.WIDTH(1)) lsu_full_hit_dc3ff (.din(ld_full_hit_dc2), .dout(ld_full_hit_dc3), .clk(lsu_freeze_c2_dc3_clk), .*);
rvdff #(.WIDTH(32)) lsu_fwddata_dc3ff (.din(ld_fwddata_dc2[31:0]), .dout(ld_fwddata_dc3[31:0]), .clk(lsu_c1_dc3_clk), .*);
@ -398,7 +398,7 @@ module lsu_bus_intf
rvdff #(4) lsu_byten_dc3ff (.*, .din(ldst_byteen_dc2[3:0]), .dout(ldst_byteen_dc3[3:0]), .clk(lsu_freeze_c1_dc3_clk));
rvdff #(4) lsu_byten_dc4ff (.*, .din(ldst_byteen_dc3[3:0]), .dout(ldst_byteen_dc4[3:0]), .clk(lsu_c1_dc4_clk));
rvdff #(4) lsu_byten_dc5ff (.*, .din(ldst_byteen_dc4[3:0]), .dout(ldst_byteen_dc5[3:0]), .clk(lsu_c1_dc5_clk));
`ifdef ASSERT_ON
// Assertion to check ld imprecise error comes with right address
// property lsu_ld_imprecise_error_check;

View File

@ -1,12 +1,12 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright 2019 Western Digital Corporation or its affiliates.
//
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//
// http://www.apache.org/licenses/LICENSE-2.0
//
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -16,21 +16,21 @@
//********************************************************************************
// $Id$
//
//
// Owner:
//
// Owner:
// Function: Clock Generation Block
// Comments: All the clocks are generate here
//
// //********************************************************************************
module lsu_clkdomain
module lsu_clkdomain
import swerv_types::*;
(
input logic clk, // clock
input logic free_clk, // clock
input logic rst_l, // reset
// Inputs
input logic clk_override, // chciken bit to turn off clock gating
input logic lsu_freeze_dc3, // freeze
@ -49,76 +49,76 @@ module lsu_clkdomain
//input logic lsu_load_stall_any, // Need to turn on clocks for this case
input logic lsu_bus_clk_en, // bus clock enable
input lsu_pkt_t lsu_p, // lsu packet in decode
input lsu_pkt_t lsu_p, // lsu packet in decode
input lsu_pkt_t lsu_pkt_dc1, // lsu packet in dc1
input lsu_pkt_t lsu_pkt_dc2, // lsu packet in dc2
input lsu_pkt_t lsu_pkt_dc2, // lsu packet in dc2
input lsu_pkt_t lsu_pkt_dc3, // lsu packet in dc3
input lsu_pkt_t lsu_pkt_dc4, // lsu packet in dc4
input lsu_pkt_t lsu_pkt_dc5, // lsu packet in dc5
// Outputs
output logic lsu_c1_dc3_clk, // dc3 pipe single pulse clock
output logic lsu_c1_dc4_clk, // dc4 pipe single pulse clock
output logic lsu_c1_dc5_clk, // dc5 pipe single pulse clock
output logic lsu_c2_dc3_clk, // dc3 pipe double pulse clock
// Outputs
output logic lsu_c1_dc3_clk, // dc3 pipe single pulse clock
output logic lsu_c1_dc4_clk, // dc4 pipe single pulse clock
output logic lsu_c1_dc5_clk, // dc5 pipe single pulse clock
output logic lsu_c2_dc3_clk, // dc3 pipe double pulse clock
output logic lsu_c2_dc4_clk, // dc4 pipe double pulse clock
output logic lsu_c2_dc5_clk, // dc5 pipe double pulse clock
output logic lsu_store_c1_dc1_clken, // store in dc1
output logic lsu_store_c1_dc1_clken, // store in dc1
output logic lsu_store_c1_dc2_clken, // store in dc2
output logic lsu_store_c1_dc3_clken, // store in dc3
output logic lsu_store_c1_dc4_clk, // store in dc4
output logic lsu_store_c1_dc5_clk, // store in dc5
output logic lsu_freeze_c1_dc1_clken, // freeze
output logic lsu_freeze_c1_dc2_clken, // freeze
output logic lsu_freeze_c1_dc3_clken, // freeze
output logic lsu_freeze_c1_dc1_clken, // freeze
output logic lsu_freeze_c1_dc2_clken, // freeze
output logic lsu_freeze_c1_dc3_clken, // freeze
output logic lsu_freeze_c1_dc2_clk, // freeze
output logic lsu_freeze_c1_dc3_clk, // freeze
output logic lsu_freeze_c1_dc2_clk, // freeze
output logic lsu_freeze_c1_dc3_clk, // freeze
output logic lsu_freeze_c2_dc1_clk,
output logic lsu_freeze_c2_dc2_clk,
output logic lsu_freeze_c2_dc3_clk,
output logic lsu_freeze_c2_dc1_clk,
output logic lsu_freeze_c2_dc2_clk,
output logic lsu_freeze_c2_dc3_clk,
output logic lsu_freeze_c2_dc4_clk,
output logic lsu_dccm_c1_dc3_clk, // dccm clock
output logic lsu_pic_c1_dc3_clken, // pic clock enable
output logic lsu_stbuf_c1_clk,
output logic lsu_stbuf_c1_clk,
output logic lsu_bus_obuf_c1_clk, // ibuf clock
output logic lsu_bus_ibuf_c1_clk, // ibuf clock
output logic lsu_bus_buf_c1_clk, // ibuf clock
output logic lsu_busm_clk, // bus clock
output logic lsu_free_c2_clk,
input logic scan_mode
input logic scan_mode
);
logic lsu_c1_dc1_clken, lsu_c1_dc2_clken, lsu_c1_dc3_clken, lsu_c1_dc4_clken, lsu_c1_dc5_clken;
logic lsu_c2_dc3_clken, lsu_c2_dc4_clken, lsu_c2_dc5_clken;
logic lsu_c1_dc1_clken_q, lsu_c1_dc2_clken_q, lsu_c1_dc3_clken_q, lsu_c1_dc4_clken_q, lsu_c1_dc5_clken_q;
logic lsu_c1_dc1_clken, lsu_c1_dc2_clken, lsu_c1_dc3_clken, lsu_c1_dc4_clken, lsu_c1_dc5_clken;
logic lsu_c2_dc3_clken, lsu_c2_dc4_clken, lsu_c2_dc5_clken;
logic lsu_c1_dc1_clken_q, lsu_c1_dc2_clken_q, lsu_c1_dc3_clken_q, lsu_c1_dc4_clken_q, lsu_c1_dc5_clken_q;
logic lsu_store_c1_dc4_clken, lsu_store_c1_dc5_clken;
logic lsu_freeze_c1_dc4_clken;
logic lsu_freeze_c2_dc1_clken, lsu_freeze_c2_dc2_clken, lsu_freeze_c2_dc3_clken, lsu_freeze_c2_dc4_clken;
logic lsu_freeze_c1_dc1_clken_q, lsu_freeze_c1_dc2_clken_q, lsu_freeze_c1_dc3_clken_q, lsu_freeze_c1_dc4_clken_q;
logic lsu_freeze_c1_dc4_clken;
logic lsu_freeze_c2_dc1_clken, lsu_freeze_c2_dc2_clken, lsu_freeze_c2_dc3_clken, lsu_freeze_c2_dc4_clken;
logic lsu_freeze_c1_dc1_clken_q, lsu_freeze_c1_dc2_clken_q, lsu_freeze_c1_dc3_clken_q, lsu_freeze_c1_dc4_clken_q;
logic lsu_stbuf_c1_clken;
logic lsu_bus_ibuf_c1_clken, lsu_bus_obuf_c1_clken, lsu_bus_buf_c1_clken;
logic lsu_dccm_c1_dc3_clken;
logic lsu_free_c1_clken, lsu_free_c1_clken_q, lsu_free_c2_clken;
logic lsu_bus_valid_clken;
//-------------------------------------------------------------------------------------------
// Clock Enable logic
//-------------------------------------------------------------------------------------------
// Also use the flopped clock enable. We want to turn on the clocks from dc1->dc5 even if there is a freeze
assign lsu_c1_dc1_clken = lsu_p.valid | dma_dccm_req | clk_override;
assign lsu_c1_dc2_clken = lsu_pkt_dc1.valid | lsu_c1_dc1_clken_q | clk_override;
@ -140,25 +140,25 @@ module lsu_clkdomain
assign lsu_freeze_c1_dc2_clken = (lsu_pkt_dc1.valid | clk_override) & ~lsu_freeze_dc3;
assign lsu_freeze_c1_dc3_clken = (lsu_pkt_dc2.valid | clk_override) & ~lsu_freeze_dc3;
assign lsu_freeze_c1_dc4_clken = (lsu_pkt_dc3.valid | clk_override) & ~lsu_freeze_dc3;
assign lsu_freeze_c2_dc1_clken = (lsu_freeze_c1_dc1_clken | lsu_freeze_c1_dc1_clken_q | clk_override) & ~lsu_freeze_dc3;
assign lsu_freeze_c2_dc2_clken = (lsu_freeze_c1_dc2_clken | lsu_freeze_c1_dc2_clken_q | clk_override) & ~lsu_freeze_dc3;
assign lsu_freeze_c2_dc3_clken = (lsu_freeze_c1_dc3_clken | lsu_freeze_c1_dc3_clken_q | clk_override) & ~lsu_freeze_dc3;
assign lsu_freeze_c2_dc4_clken = (lsu_freeze_c1_dc4_clken | lsu_freeze_c1_dc4_clken_q | clk_override) & ~lsu_freeze_dc3;
assign lsu_stbuf_c1_clken = load_stbuf_reqvld_dc3 | store_stbuf_reqvld_dc3 | stbuf_reqvld_any | stbuf_reqvld_flushed_any | clk_override;
assign lsu_bus_ibuf_c1_clken = lsu_busreq_dc5 | clk_override;
assign lsu_bus_obuf_c1_clken = ((lsu_bus_buffer_pend_any | lsu_busreq_dc5) & lsu_bus_clk_en) | clk_override;
assign lsu_bus_buf_c1_clken = ~lsu_bus_buffer_empty_any | lsu_busreq_dc5 | clk_override;
assign lsu_dccm_c1_dc3_clken = ((lsu_c1_dc3_clken & addr_in_dccm_dc2) | clk_override) & ~lsu_freeze_dc3;
assign lsu_pic_c1_dc3_clken = ((lsu_c1_dc3_clken & addr_in_pic_dc2) | clk_override) & ~lsu_freeze_dc3;
assign lsu_free_c1_clken = (lsu_p.valid | lsu_pkt_dc1.valid | lsu_pkt_dc2.valid | lsu_pkt_dc3.valid | lsu_pkt_dc4.valid | lsu_pkt_dc5.valid) |
assign lsu_free_c1_clken = (lsu_p.valid | lsu_pkt_dc1.valid | lsu_pkt_dc2.valid | lsu_pkt_dc3.valid | lsu_pkt_dc4.valid | lsu_pkt_dc5.valid) |
~lsu_bus_buffer_empty_any | ~lsu_stbuf_empty_any | clk_override;
assign lsu_free_c2_clken = lsu_free_c1_clken | lsu_free_c1_clken_q | clk_override;
// Flops
rvdff #(1) lsu_free_c1_clkenff (.din(lsu_free_c1_clken), .dout(lsu_free_c1_clken_q), .clk(free_clk), .*);
@ -203,11 +203,11 @@ module lsu_clkdomain
rvoclkhdr lsu_bus_buf_c1_cgc ( .en(lsu_bus_buf_c1_clken), .l1clk(lsu_bus_buf_c1_clk), .* );
rvclkhdr lsu_busm_cgc (.en(lsu_bus_clk_en), .l1clk(lsu_busm_clk), .*);
rvclkhdr lsu_dccm_c1dc3_cgc (.en(lsu_dccm_c1_dc3_clken), .l1clk(lsu_dccm_c1_dc3_clk), .*);
// rvclkhdr lsu_pic_c1dc3_cgc (.en(lsu_pic_c1_dc3_clken), .l1clk(lsu_pic_c1_dc3_clk), .*);
rvclkhdr lsu_free_cgc (.en(lsu_free_c2_clken), .l1clk(lsu_free_c2_clk), .*);
endmodule

View File

@ -1,12 +1,12 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright 2019 Western Digital Corporation or its affiliates.
//
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//
// http://www.apache.org/licenses/LICENSE-2.0
//
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -16,28 +16,28 @@
//********************************************************************************
// $Id$
//
//
// Owner:
//
// Owner:
// Function: DCCM for LSU pipe
// Comments: Single ported memory
//
//
//
// DC1 -> DC2 -> DC3 -> DC4 (Commit)
//
//
// //********************************************************************************
module lsu_dccm_ctl
module lsu_dccm_ctl
import swerv_types::*;
(
input logic lsu_freeze_c2_dc2_clk, // clocks
input logic lsu_freeze_c2_dc3_clk,
input logic lsu_dccm_c1_dc3_clk,
input logic lsu_pic_c1_dc3_clken,
input logic rst_l,
input logic clk,
input logic lsu_freeze_dc3, // freze
input lsu_pkt_t lsu_pkt_dc3, // lsu packets
input lsu_pkt_t lsu_pkt_dc1,
input logic addr_in_dccm_dc1, // address maps to dccm
@ -50,32 +50,32 @@ module lsu_dccm_ctl
input logic stbuf_reqvld_any, // write enable
input logic stbuf_addr_in_pic_any, // stbuf is going to pic
input logic [`RV_LSU_SB_BITS-1:0] stbuf_addr_any, // stbuf address (aligned)
input logic [`RV_DCCM_DATA_WIDTH-1:0] stbuf_data_any, // the read out from stbuf
input logic [`RV_DCCM_ECC_WIDTH-1:0] stbuf_ecc_any, // the encoded data with ECC bits
input logic [`RV_DCCM_ECC_WIDTH-1:0] stbuf_ecc_any, // the encoded data with ECC bits
input logic [`RV_DCCM_DATA_WIDTH-1:0] stbuf_fwddata_hi_dc3, // stbuf fowarding to load
input logic [`RV_DCCM_DATA_WIDTH-1:0] stbuf_fwddata_lo_dc3, // stbuf fowarding to load
input logic [`RV_DCCM_BYTE_WIDTH-1:0] stbuf_fwdbyteen_hi_dc3, // stbuf fowarding to load
input logic [`RV_DCCM_BYTE_WIDTH-1:0] stbuf_fwdbyteen_lo_dc3, // stbuf fowarding to load
input logic [`RV_DCCM_BYTE_WIDTH-1:0] stbuf_fwdbyteen_lo_dc3, // stbuf fowarding to load
input logic lsu_double_ecc_error_dc3, // lsu has a DED
input logic [`RV_DCCM_DATA_WIDTH-1:0] store_ecc_datafn_hi_dc3, // store data
input logic [`RV_DCCM_DATA_WIDTH-1:0] store_ecc_datafn_lo_dc3, // store data
input logic [`RV_DCCM_DATA_WIDTH-1:0] store_ecc_datafn_lo_dc3, // store data
output logic [`RV_DCCM_DATA_WIDTH-1:0] dccm_data_hi_dc3, // data from the dccm
output logic [`RV_DCCM_DATA_WIDTH-1:0] dccm_data_lo_dc3, // data from the dccm
output logic [`RV_DCCM_ECC_WIDTH-1:0] dccm_data_ecc_hi_dc3, // data from the dccm + ecc
output logic [`RV_DCCM_ECC_WIDTH-1:0] dccm_data_ecc_lo_dc3,
output logic [`RV_DCCM_ECC_WIDTH-1:0] dccm_data_ecc_lo_dc3,
output logic [`RV_DCCM_DATA_WIDTH-1:0] lsu_ld_data_dc3, // right justified, ie load byte will have data at 7:0
output logic [`RV_DCCM_DATA_WIDTH-1:0] lsu_ld_data_corr_dc3, // right justified, ie load byte will have data at 7:0
output logic [31:0] picm_mask_data_dc3, // pic data to stbuf
output logic lsu_stbuf_commit_any, // stbuf wins the dccm port or is to pic
output logic lsu_dccm_rden_dc3, // dccm read
output logic dccm_dma_rvalid, // dccm serviving the dma load
output logic dccm_dma_ecc_error, // DMA load had ecc error
output logic [63:0] dccm_dma_rdata, // dccm data to dma request
// DCCM ports
output logic dccm_wren, // dccm interface -- write
output logic dccm_rden, // dccm interface -- write
@ -83,7 +83,7 @@ module lsu_dccm_ctl
output logic [`RV_DCCM_BITS-1:0] dccm_rd_addr_lo, // dccm interface -- read address for lo bank
output logic [`RV_DCCM_BITS-1:0] dccm_rd_addr_hi, // dccm interface -- read address for hi bank
output logic [`RV_DCCM_FDATA_WIDTH-1:0] dccm_wr_data, // dccm write data
input logic [`RV_DCCM_FDATA_WIDTH-1:0] dccm_rd_data_lo, // dccm read data back from the dccm
input logic [`RV_DCCM_FDATA_WIDTH-1:0] dccm_rd_data_hi, // dccm read data back from the dccm
@ -94,12 +94,12 @@ module lsu_dccm_ctl
output logic [31:0] picm_addr, // address for pic access - shared between reads and write
output logic [31:0] picm_wr_data, // write data
input logic [31:0] picm_rd_data, // read data
input logic scan_mode // scan mode
input logic scan_mode // scan mode
);
`include "global.h"
`ifdef RV_DCCM_ENABLE
localparam DCCM_ENABLE = 1'b1;
`else
@ -108,7 +108,7 @@ module lsu_dccm_ctl
localparam DCCM_WIDTH_BITS = $clog2(DCCM_BYTE_WIDTH);
localparam PIC_BITS =`RV_PIC_BITS;
logic lsu_dccm_rden_dc1, lsu_dccm_rden_dc2;
logic [DCCM_DATA_WIDTH-1:0] dccm_data_hi_dc2, dccm_data_lo_dc2;
logic [DCCM_ECC_WIDTH-1:0] dccm_data_ecc_hi_dc2, dccm_data_ecc_lo_dc2;
@ -119,31 +119,31 @@ module lsu_dccm_ctl
logic [63:0] picm_rd_data_dc3;
logic [31:0] picm_rd_data_lo_dc3;
logic [63:32] lsu_ld_data_dc3_nc, lsu_ld_data_corr_dc3_nc;
assign dccm_dma_rvalid = lsu_pkt_dc3.valid & lsu_pkt_dc3.load & lsu_pkt_dc3.dma;
assign dccm_dma_ecc_error = lsu_double_ecc_error_dc3;
assign dccm_dma_rdata[63:0] = lsu_rdata_corr_dc3[63:0];
assign dccm_dma_rdata[63:0] = lsu_pkt_dc3.dword ? lsu_rdata_corr_dc3[63:0] : {2{lsu_rdata_corr_dc3[31:0]}}; // Need to replicate the data for non-dw access since ecc correction is done only in lower word
assign {lsu_ld_data_dc3_nc[63:32], lsu_ld_data_dc3[31:0]} = lsu_rdata_dc3[63:0] >> 8*lsu_addr_dc3[1:0];
assign {lsu_ld_data_corr_dc3_nc[63:32], lsu_ld_data_corr_dc3[31:0]} = lsu_rdata_corr_dc3[63:0] >> 8*lsu_addr_dc3[1:0];
assign dccm_dout_dc3[63:0] = {dccm_data_hi_dc3[DCCM_DATA_WIDTH-1:0], dccm_data_lo_dc3[DCCM_DATA_WIDTH-1:0]};
assign dccm_corr_dout_dc3[63:0] = {store_ecc_datafn_hi_dc3[DCCM_DATA_WIDTH-1:0], store_ecc_datafn_lo_dc3[DCCM_DATA_WIDTH-1:0]};
assign stbuf_fwddata_dc3[63:0] = {stbuf_fwddata_hi_dc3[DCCM_DATA_WIDTH-1:0], stbuf_fwddata_lo_dc3[DCCM_DATA_WIDTH-1:0]};
assign stbuf_fwdbyteen_dc3[7:0] = {stbuf_fwdbyteen_hi_dc3[DCCM_BYTE_WIDTH-1:0], stbuf_fwdbyteen_lo_dc3[DCCM_BYTE_WIDTH-1:0]};
for (genvar i=0; i<8; i++) begin: GenLoop
assign lsu_rdata_dc3[(8*i)+7:8*i] = stbuf_fwdbyteen_dc3[i] ? stbuf_fwddata_dc3[(8*i)+7:8*i] :
assign lsu_rdata_dc3[(8*i)+7:8*i] = stbuf_fwdbyteen_dc3[i] ? stbuf_fwddata_dc3[(8*i)+7:8*i] :
(addr_in_pic_dc3 ? picm_rd_data_dc3[(8*i)+7:8*i] : dccm_dout_dc3[(8*i)+7:8*i]);
assign lsu_rdata_corr_dc3[(8*i)+7:8*i] = stbuf_fwdbyteen_dc3[i] ? stbuf_fwddata_dc3[(8*i)+7:8*i] :
assign lsu_rdata_corr_dc3[(8*i)+7:8*i] = stbuf_fwdbyteen_dc3[i] ? stbuf_fwddata_dc3[(8*i)+7:8*i] :
(addr_in_pic_dc3 ? picm_rd_data_dc3[(8*i)+7:8*i] : dccm_corr_dout_dc3[(8*i)+7:8*i]);
end
assign lsu_stbuf_commit_any = stbuf_reqvld_any & ~lsu_freeze_dc3 & (
(~(lsu_dccm_rden_dc1 | picm_rden | picm_mken)) |
((picm_rden | picm_mken) & ~stbuf_addr_in_pic_any) |
(lsu_dccm_rden_dc1 & (stbuf_addr_in_pic_any | (~((stbuf_addr_any[DCCM_WIDTH_BITS+:DCCM_BANK_BITS] == lsu_addr_dc1[DCCM_WIDTH_BITS+:DCCM_BANK_BITS]) |
(lsu_dccm_rden_dc1 & (stbuf_addr_in_pic_any | (~((stbuf_addr_any[DCCM_WIDTH_BITS+:DCCM_BANK_BITS] == lsu_addr_dc1[DCCM_WIDTH_BITS+:DCCM_BANK_BITS]) |
(stbuf_addr_any[DCCM_WIDTH_BITS+:DCCM_BANK_BITS] == end_addr_dc1[DCCM_WIDTH_BITS+:DCCM_BANK_BITS]))))));
// No need to read for aligned word/dword stores since ECC will come by new data completely
@ -168,14 +168,14 @@ module lsu_dccm_ctl
assign picm_wren = lsu_stbuf_commit_any & stbuf_addr_in_pic_any;
assign picm_rden = lsu_pkt_dc1.valid & lsu_pkt_dc1.load & addr_in_pic_dc1;
assign picm_mken = lsu_pkt_dc1.valid & lsu_pkt_dc1.store & addr_in_pic_dc1; // Get the mask for stores
assign picm_addr[31:0] = (picm_rden | picm_mken) ? (`RV_PIC_BASE_ADDR | {17'b0,lsu_addr_dc1[14:0]}) : (`RV_PIC_BASE_ADDR | {{32-PIC_BITS{1'b0}},stbuf_addr_any[`RV_PIC_BITS-1:0]});
//assign picm_addr[31:0] = (picm_rden | picm_mken) ? {`RV_PIC_REGION,`RV_PIC_OFFSET,3'b0,lsu_addr_dc1[14:0]} : {`RV_PIC_REGION,`RV_PIC_OFFSET,{18-PIC_BITS{1'b0}},stbuf_addr_any[`RV_PIC_BITS-1:0]};
assign picm_addr[31:0] = (picm_rden | picm_mken) ? (`RV_PIC_BASE_ADDR | {17'b0,lsu_addr_dc1[14:0]}) : (`RV_PIC_BASE_ADDR | {{32-PIC_BITS{1'b0}},stbuf_addr_any[`RV_PIC_BITS-1:0]});
//assign picm_addr[31:0] = (picm_rden | picm_mken) ? {`RV_PIC_REGION,`RV_PIC_OFFSET,3'b0,lsu_addr_dc1[14:0]} : {`RV_PIC_REGION,`RV_PIC_OFFSET,{18-PIC_BITS{1'b0}},stbuf_addr_any[`RV_PIC_BITS-1:0]};
assign picm_wr_data[31:0] = stbuf_data_any[31:0];
// Flops
assign picm_mask_data_dc3[31:0] = picm_rd_data_lo_dc3[31:0];
assign picm_rd_data_dc3[63:0] = {picm_rd_data_lo_dc3[31:0], picm_rd_data_lo_dc3[31:0]} ;
assign picm_rd_data_dc3[63:0] = {picm_rd_data_lo_dc3[31:0], picm_rd_data_lo_dc3[31:0]} ;
rvdffe #(32) picm_data_ff (.*, .din(picm_rd_data[31:0]), .dout(picm_rd_data_lo_dc3[31:0]), .en(lsu_pic_c1_dc3_clken));
if (DCCM_ENABLE == 1) begin: Gen_dccm_enable
rvdff #(1) dccm_rden_dc2ff (.*, .din(lsu_dccm_rden_dc1), .dout(lsu_dccm_rden_dc2), .clk(lsu_freeze_c2_dc2_clk));
@ -183,7 +183,7 @@ module lsu_dccm_ctl
rvdff #(DCCM_DATA_WIDTH) dccm_data_hi_ff (.*, .din(dccm_data_hi_dc2[DCCM_DATA_WIDTH-1:0]), .dout(dccm_data_hi_dc3[DCCM_DATA_WIDTH-1:0]), .clk(lsu_dccm_c1_dc3_clk));
rvdff #(DCCM_DATA_WIDTH) dccm_data_lo_ff (.*, .din(dccm_data_lo_dc2[DCCM_DATA_WIDTH-1:0]), .dout(dccm_data_lo_dc3[DCCM_DATA_WIDTH-1:0]), .clk(lsu_dccm_c1_dc3_clk));
rvdff #(DCCM_ECC_WIDTH) dccm_data_ecc_hi_ff (.*, .din(dccm_data_ecc_hi_dc2[DCCM_ECC_WIDTH-1:0]), .dout(dccm_data_ecc_hi_dc3[DCCM_ECC_WIDTH-1:0]), .clk(lsu_dccm_c1_dc3_clk));
rvdff #(DCCM_ECC_WIDTH) dccm_data_ecc_lo_ff (.*, .din(dccm_data_ecc_lo_dc2[DCCM_ECC_WIDTH-1:0]), .dout(dccm_data_ecc_lo_dc3[DCCM_ECC_WIDTH-1:0]), .clk(lsu_dccm_c1_dc3_clk));
end else begin: Gen_dccm_disable

View File

@ -1,12 +1,12 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright 2019 Western Digital Corporation or its affiliates.
//
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//
// http://www.apache.org/licenses/LICENSE-2.0
//
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -16,31 +16,31 @@
//********************************************************************************
// $Id$
//
//
// Owner:
//
// Owner:
// Function: DCCM for LSU pipe
// Comments: Single ported memory
//
//
//
// DC1 -> DC2 -> DC3 -> DC4 (Commit)
//
//
// //********************************************************************************
module lsu_dccm_mem
module lsu_dccm_mem
import swerv_types::*;
(
input logic clk, // clock
input logic rst_l,
input logic clk, // clock
input logic rst_l,
input logic lsu_freeze_dc3, // freeze
input logic clk_override, // clock override
input logic dccm_wren, // write enable
input logic dccm_rden, // read enable
input logic [`RV_DCCM_BITS-1:0] dccm_wr_addr, // write address
input logic [`RV_DCCM_BITS-1:0] dccm_rd_addr_lo, // read address
input logic [`RV_DCCM_BITS-1:0] dccm_rd_addr_hi, // read address for the upper bank in case of a misaligned access
input logic [`RV_DCCM_FDATA_WIDTH-1:0] dccm_wr_data, // write data
output logic [`RV_DCCM_FDATA_WIDTH-1:0] dccm_rd_data_lo, // read data from the lo bank
output logic [`RV_DCCM_FDATA_WIDTH-1:0] dccm_rd_data_hi, // read data from the hi bank
@ -48,10 +48,10 @@ module lsu_dccm_mem
);
`include "global.h"
localparam DCCM_WIDTH_BITS = $clog2(DCCM_BYTE_WIDTH);
localparam DCCM_INDEX_BITS = (DCCM_BITS - DCCM_BANK_BITS - DCCM_WIDTH_BITS);
logic [DCCM_NUM_BANKS-1:0] wren_bank;
logic [DCCM_NUM_BANKS-1:0] rden_bank;
logic [DCCM_NUM_BANKS-1:0] [DCCM_BITS-1:(DCCM_BANK_BITS+2)] addr_bank;
@ -67,30 +67,30 @@ module lsu_dccm_mem
logic [(DCCM_WIDTH_BITS+DCCM_BANK_BITS-1):DCCM_WIDTH_BITS] dccm_rd_addr_lo_q;
logic [(DCCM_WIDTH_BITS+DCCM_BANK_BITS-1):DCCM_WIDTH_BITS] dccm_rd_addr_hi_q;
logic [DCCM_NUM_BANKS-1:0] dccm_clk;
logic [DCCM_NUM_BANKS-1:0] dccm_clken;
assign rd_unaligned = (dccm_rd_addr_lo[DCCM_WIDTH_BITS+:DCCM_BANK_BITS] != dccm_rd_addr_hi[DCCM_WIDTH_BITS+:DCCM_BANK_BITS]);
// Align the read data
assign dccm_rd_data_lo[DCCM_FDATA_WIDTH-1:0] = dccm_bank_dout[dccm_rd_addr_lo_q[DCCM_WIDTH_BITS+:DCCM_BANK_BITS]][DCCM_FDATA_WIDTH-1:0];
assign dccm_rd_data_hi[DCCM_FDATA_WIDTH-1:0] = dccm_bank_dout[dccm_rd_addr_hi_q[DCCM_WIDTH_BITS+:DCCM_BANK_BITS]][DCCM_FDATA_WIDTH-1:0];
// Generate even/odd address
// assign rd_addr_even[(DCCM_BANK_BITS+DCCM_WIDTH_BITS)+:DCCM_INDEX_BITS] = dccm_rd_addr_lo[2] ? dccm_rd_addr_hi[(DCCM_BANK_BITS+DCCM_WIDTH_BITS)+:DCCM_INDEX_BITS] :
// assign rd_addr_even[(DCCM_BANK_BITS+DCCM_WIDTH_BITS)+:DCCM_INDEX_BITS] = dccm_rd_addr_lo[2] ? dccm_rd_addr_hi[(DCCM_BANK_BITS+DCCM_WIDTH_BITS)+:DCCM_INDEX_BITS] :
// dccm_rd_addr_lo[(DCCM_BANK_BITS+DCCM_WIDTH_BITS)+:DCCM_INDEX_BITS];
// assign rd_addr_odd[(DCCM_BANK_BITS+DCCM_WIDTH_BITS)+:DCCM_INDEX_BITS] = dccm_rd_addr_lo[2] ? dccm_rd_addr_lo[(DCCM_BANK_BITS+DCCM_WIDTH_BITS)+:DCCM_INDEX_BITS] :
// dccm_rd_addr_hi[(DCCM_BANK_BITS+DCCM_WIDTH_BITS)+:DCCM_INDEX_BITS];
// assign rd_addr_odd[(DCCM_BANK_BITS+DCCM_WIDTH_BITS)+:DCCM_INDEX_BITS] = dccm_rd_addr_lo[2] ? dccm_rd_addr_lo[(DCCM_BANK_BITS+DCCM_WIDTH_BITS)+:DCCM_INDEX_BITS] :
// dccm_rd_addr_hi[(DCCM_BANK_BITS+DCCM_WIDTH_BITS)+:DCCM_INDEX_BITS];
// 8 Banks, 16KB each (2048 x 72)
for (genvar i=0; i<DCCM_NUM_BANKS; i++) begin: mem_bank
assign wren_bank[i] = dccm_wren & (dccm_wr_addr[2+:DCCM_BANK_BITS] == i);
assign rden_bank[i] = dccm_rden & ((dccm_rd_addr_hi[2+:DCCM_BANK_BITS] == i) | (dccm_rd_addr_lo[2+:DCCM_BANK_BITS] == i));
assign rden_bank[i] = dccm_rden & ((dccm_rd_addr_hi[2+:DCCM_BANK_BITS] == i) | (dccm_rd_addr_lo[2+:DCCM_BANK_BITS] == i));
assign addr_bank[i][(DCCM_BANK_BITS+DCCM_WIDTH_BITS)+:DCCM_INDEX_BITS] = wren_bank[i] ? dccm_wr_addr[(DCCM_BANK_BITS+DCCM_WIDTH_BITS)+:DCCM_INDEX_BITS] :
(((dccm_rd_addr_hi[2+:DCCM_BANK_BITS] == i) & rd_unaligned) ?
dccm_rd_addr_hi[(DCCM_BANK_BITS+DCCM_WIDTH_BITS)+:DCCM_INDEX_BITS] :
(((dccm_rd_addr_hi[2+:DCCM_BANK_BITS] == i) & rd_unaligned) ?
dccm_rd_addr_hi[(DCCM_BANK_BITS+DCCM_WIDTH_BITS)+:DCCM_INDEX_BITS] :
dccm_rd_addr_lo[(DCCM_BANK_BITS+DCCM_WIDTH_BITS)+:DCCM_INDEX_BITS]);
// if (i%2 == 0) begin
@ -100,11 +100,11 @@ module lsu_dccm_mem
// assign addr_bank[i][(DCCM_BANK_BITS+DCCM_WIDTH_BITS)+:DCCM_INDEX_BITS] = wren_bank[i] ? dccm_wr_addr[(DCCM_BANK_BITS+DCCM_WIDTH_BITS)+:DCCM_INDEX_BITS] :
// rd_addr_odd[(DCCM_BANK_BITS+DCCM_WIDTH_BITS)+:DCCM_INDEX_BITS];
// end
// clock gating section
assign dccm_clken[i] = (wren_bank[i] | rden_bank[i] | clk_override) & ~lsu_freeze_dc3;
rvclkhdr lsu_dccm_cgc (.en(dccm_clken[i]), .l1clk(dccm_clk[i]), .*);
// end clock gating section
// end clock gating section
`RV_DCCM_DATA_CELL dccm_bank (
// Primary ports
@ -115,9 +115,9 @@ module lsu_dccm_mem
.Q(dccm_bank_dout[i][DCCM_FDATA_WIDTH-1:0])
);
end : mem_bank
// Flops
rvdffs #(DCCM_BANK_BITS) rd_addr_lo_ff (.*, .din(dccm_rd_addr_lo[DCCM_WIDTH_BITS+:DCCM_BANK_BITS]), .dout(dccm_rd_addr_lo_q[DCCM_WIDTH_BITS+:DCCM_BANK_BITS]), .en(~lsu_freeze_dc3));
rvdffs #(DCCM_BANK_BITS) rd_addr_hi_ff (.*, .din(dccm_rd_addr_hi[DCCM_WIDTH_BITS+:DCCM_BANK_BITS]), .dout(dccm_rd_addr_hi_q[DCCM_WIDTH_BITS+:DCCM_BANK_BITS]), .en(~lsu_freeze_dc3));

View File

@ -1,12 +1,12 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright 2019 Western Digital Corporation or its affiliates.
//
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//
// http://www.apache.org/licenses/LICENSE-2.0
//
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -16,16 +16,16 @@
//********************************************************************************
// $Id$
//
//
// Owner:
//
// Owner:
// Function: Top level file for load store unit
// Comments:
//
//
//
// DC1 -> DC2 -> DC3 -> DC4 (Commit)
//
//
//********************************************************************************
module lsu_ecc
module lsu_ecc
import swerv_types::*;
(
@ -41,34 +41,34 @@ module lsu_ecc
input logic [`RV_DCCM_BITS-1:0] lsu_addr_dc3, // start address
input logic [`RV_DCCM_BITS-1:0] end_addr_dc3, // end address
input logic [63:0] store_data_dc3, // store data
input logic [`RV_DCCM_DATA_WIDTH-1:0] stbuf_data_any,
input logic [`RV_DCCM_DATA_WIDTH-1:0] stbuf_data_any,
input logic [`RV_DCCM_DATA_WIDTH-1:0] stbuf_fwddata_hi_dc3, // data forward from the store buffer
input logic [`RV_DCCM_DATA_WIDTH-1:0] stbuf_fwddata_lo_dc3, // data forward from the store buffer
input logic [`RV_DCCM_BYTE_WIDTH-1:0] stbuf_fwdbyteen_hi_dc3,// which bytes from the store buffer are on
input logic [`RV_DCCM_BYTE_WIDTH-1:0] stbuf_fwdbyteen_lo_dc3,// which bytes from the store buffer are on
input logic [`RV_DCCM_DATA_WIDTH-1:0] dccm_data_hi_dc3, // raw data from mem
input logic [`RV_DCCM_DATA_WIDTH-1:0] dccm_data_lo_dc3, // raw data from mem
input logic [`RV_DCCM_ECC_WIDTH-1:0] dccm_data_ecc_hi_dc3, // ecc read out from mem
input logic [`RV_DCCM_ECC_WIDTH-1:0] dccm_data_ecc_lo_dc3, // ecc read out from mem
input logic dec_tlu_core_ecc_disable, // disables the ecc computation and error flagging
output logic [`RV_DCCM_DATA_WIDTH-1:0] store_ecc_datafn_hi_dc3, // final store data either from stbuf or SEC DCCM readout
output logic [`RV_DCCM_DATA_WIDTH-1:0] store_ecc_datafn_hi_dc3, // final store data either from stbuf or SEC DCCM readout
output logic [`RV_DCCM_DATA_WIDTH-1:0] store_ecc_datafn_lo_dc3,
output logic [`RV_DCCM_ECC_WIDTH-1:0] stbuf_ecc_any,
output logic [`RV_DCCM_ECC_WIDTH-1:0] stbuf_ecc_any,
output logic single_ecc_error_hi_dc3, // sec detected
output logic single_ecc_error_lo_dc3, // sec detected on lower dccm bank
output logic lsu_single_ecc_error_dc3, // or of the 2
output logic lsu_double_ecc_error_dc3, // double error detected
input logic scan_mode
input logic scan_mode
);
`include "global.h"
`ifdef RV_DCCM_ENABLE
localparam DCCM_ENABLE = 1'b1;
`else
@ -77,8 +77,8 @@ module lsu_ecc
logic [DCCM_DATA_WIDTH-1:0] sec_data_hi_dc3;
logic [DCCM_DATA_WIDTH-1:0] sec_data_lo_dc3;
logic double_ecc_error_hi_dc3, double_ecc_error_lo_dc3;
logic ldst_dual_dc3;
@ -88,12 +88,12 @@ module lsu_ecc
logic [7:0] store_byteen_dc3;
logic [7:0] store_byteen_ext_dc3;
logic [DCCM_BYTE_WIDTH-1:0] store_byteen_hi_dc3, store_byteen_lo_dc3;
logic [163:0] store_data_ext_dc3;
logic [DCCM_DATA_WIDTH-1:0] store_data_hi_dc3, store_data_lo_dc3;
logic [DCCM_DATA_WIDTH-1:0] store_data_hi_dc3, store_data_lo_dc3;
logic [6:0] ecc_out_hi_nc, ecc_out_lo_nc;
assign ldst_dual_dc3 = (lsu_addr_dc3[2] != end_addr_dc3[2]);
assign is_ldst_dc3 = lsu_pkt_dc3.valid & (lsu_pkt_dc3.load | lsu_pkt_dc3.store) & addr_in_dccm_dc3 & lsu_dccm_rden_dc3;
assign is_ldst_lo_dc3 = is_ldst_dc3 & ~dec_tlu_core_ecc_disable;
@ -104,7 +104,7 @@ module lsu_ecc
({8{lsu_pkt_dc3.word}} & 8'b0000_1111) |
({8{lsu_pkt_dc3.dword}} & 8'b1111_1111);
assign store_byteen_dc3[7:0] = ldst_byteen_dc3[7:0] & {8{lsu_pkt_dc3.store}};
assign store_byteen_ext_dc3[7:0] = store_byteen_dc3[7:0] << lsu_addr_dc3[1:0];
assign store_byteen_hi_dc3[DCCM_BYTE_WIDTH-1:0] = store_byteen_ext_dc3[7:4];
assign store_byteen_lo_dc3[DCCM_BYTE_WIDTH-1:0] = store_byteen_ext_dc3[3:0];
@ -113,7 +113,7 @@ module lsu_ecc
assign store_data_hi_dc3[DCCM_DATA_WIDTH-1:0] = store_data_ext_dc3[63:32];
assign store_data_lo_dc3[DCCM_DATA_WIDTH-1:0] = store_data_ext_dc3[31:0];
// Merge store data and sec data
// This is used for loads as well for ecc error case. store_byteen will be 0 for loads
for (genvar i=0; i<DCCM_BYTE_WIDTH; i++) begin
@ -133,26 +133,26 @@ module lsu_ecc
.ecc_in(dccm_data_ecc_hi_dc3[DCCM_ECC_WIDTH-1:0]),
// Outputs
.dout(sec_data_hi_dc3[DCCM_DATA_WIDTH-1:0]),
.ecc_out (ecc_out_hi_nc[6:0]),
.single_ecc_error(single_ecc_error_hi_dc3),
.double_ecc_error(double_ecc_error_hi_dc3),
.ecc_out (ecc_out_hi_nc[6:0]),
.single_ecc_error(single_ecc_error_hi_dc3),
.double_ecc_error(double_ecc_error_hi_dc3),
.*
);
rvecc_decode lsu_ecc_decode_lo (
// Inputs
// Inputs
.en(is_ldst_lo_dc3),
.sed_ded (1'b0), // 1 : means only detection
.din(dccm_data_lo_dc3[DCCM_DATA_WIDTH-1:0] ),
.ecc_in(dccm_data_ecc_lo_dc3[DCCM_ECC_WIDTH-1:0]),
// Outputs
.dout(sec_data_lo_dc3[DCCM_DATA_WIDTH-1:0]),
.dout(sec_data_lo_dc3[DCCM_DATA_WIDTH-1:0]),
.ecc_out (ecc_out_lo_nc[6:0]),
.single_ecc_error(single_ecc_error_lo_dc3),
.double_ecc_error(double_ecc_error_lo_dc3),
.single_ecc_error(single_ecc_error_lo_dc3),
.double_ecc_error(double_ecc_error_lo_dc3),
.*
);
// Generate the ECC bits for store buffer drain
rvecc_encode lsu_ecc_encode (
//Inputs
@ -171,15 +171,15 @@ module lsu_ecc
assign stbuf_ecc_any[DCCM_ECC_WIDTH-1:0] = '0;
end
assign lsu_single_ecc_error_dc3 = single_ecc_error_hi_dc3 | single_ecc_error_lo_dc3;
assign lsu_double_ecc_error_dc3 = double_ecc_error_hi_dc3 | double_ecc_error_lo_dc3;
assign lsu_single_ecc_error_dc3 = single_ecc_error_hi_dc3 | single_ecc_error_lo_dc3;
assign lsu_double_ecc_error_dc3 = double_ecc_error_hi_dc3 | double_ecc_error_lo_dc3;
`ifdef ASSERT_ON
// ecc_check: assert property (@(posedge clk) ~(single_ecc_error_lo_dc3 | single_ecc_error_hi_dc3));
`endif
endmodule // lsu_ecc

View File

@ -1,12 +1,12 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright 2019 Western Digital Corporation or its affiliates.
//
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//
// http://www.apache.org/licenses/LICENSE-2.0
//
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -16,65 +16,66 @@
//********************************************************************************
// $Id$
//
//
// Owner:
//
// Owner:
// Function: LSU control
// Comments:
//
//
//
// DC1 -> DC2 -> DC3 -> DC4 (Commit)
//
//
//********************************************************************************
module lsu_lsc_ctl
module lsu_lsc_ctl
import swerv_types::*;
(
input logic rst_l,
input logic clk,
// clocks per pipe
input logic lsu_c1_dc4_clk,
input logic lsu_c1_dc5_clk,
input logic lsu_c2_dc4_clk,
input logic lsu_c1_dc4_clk,
input logic lsu_c1_dc5_clk,
input logic lsu_c2_dc4_clk,
input logic lsu_c2_dc5_clk,
// freez clocks per pipe
input logic lsu_freeze_c1_dc1_clken,
// freez clocks per pipe
input logic lsu_freeze_c1_dc1_clken,
input logic lsu_freeze_c1_dc2_clken,
input logic lsu_freeze_c1_dc2_clk,
input logic lsu_freeze_c1_dc2_clk,
input logic lsu_freeze_c1_dc3_clken,
input logic lsu_freeze_c1_dc3_clk,
input logic lsu_freeze_c2_dc1_clk,
input logic lsu_freeze_c2_dc2_clk,
input logic lsu_freeze_c2_dc3_clk,
input logic lsu_freeze_c1_dc3_clk,
input logic lsu_freeze_c2_dc1_clk,
input logic lsu_freeze_c2_dc2_clk,
input logic lsu_freeze_c2_dc3_clk,
input logic lsu_store_c1_dc1_clken,
input logic lsu_store_c1_dc2_clken,
input logic lsu_store_c1_dc3_clken,
input logic lsu_store_c1_dc4_clk,
input logic lsu_store_c1_dc5_clk,
input logic [31:0] i0_result_e4_eff,
input logic [31:0] i1_result_e4_eff,
input logic [31:0] i0_result_e2,
input logic [31:0] i0_result_e2,
input logic ld_bus_error_dc3,
input logic [31:0] ld_bus_error_addr_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_freeze_dc3,
input logic lsu_i0_valid_dc3,
input logic flush_dc2_up,
input logic flush_dc3,
input logic flush_dc4,
input logic flush_dc5,
input logic [31:0] exu_lsu_rs1_d, // address
input logic [31:0] exu_lsu_rs2_d, // store data
input lsu_pkt_t lsu_p, // lsu control packet
input logic [11:0] dec_lsu_offset_d,
input logic [31:0] picm_mask_data_dc3,
input logic [31:0] lsu_ld_data_dc3,
input logic [31:0] lsu_ld_data_corr_dc3,
@ -98,14 +99,15 @@ module lsu_lsc_ctl
output logic [63:0] store_data_dc3,
output logic [31:0] store_data_dc4,
output logic [31:0] store_data_dc5,
input logic [31:0] dec_tlu_mrac_ff,
output logic lsu_exc_dc2,
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 is_sideeffects_dc2,
output logic is_sideeffects_dc3,
output logic lsu_commit_dc5,
output logic lsu_commit_dc5,
// address in dccm/pic/external per pipe stage
output logic addr_in_dccm_dc1,
output logic addr_in_dccm_dc2,
@ -117,9 +119,9 @@ module lsu_lsc_ctl
output logic addr_external_dc3,
output logic addr_external_dc4,
output logic addr_external_dc5,
// DMA slave
input logic dma_dccm_req,
input logic dma_dccm_req,
input logic [31:0] dma_mem_addr,
input logic [2:0] dma_mem_sz,
input logic dma_mem_write,
@ -133,7 +135,7 @@ module lsu_lsc_ctl
output lsu_pkt_t lsu_pkt_dc5,
input logic scan_mode
);
`include "global.h"
@ -149,21 +151,21 @@ module lsu_lsc_ctl
logic [31:0] lsu_ld_datafn_corr_dc3;
logic [31:0] lsu_result_corr_dc3;
logic [2:0] addr_offset_dc1;
logic [63:0] dma_mem_wdata_shifted;
logic addr_external_dc1;
logic access_fault_dc1, misaligned_fault_dc1;
logic access_fault_dc2, misaligned_fault_dc2;
logic access_fault_dc3, misaligned_fault_dc3;
logic [63:0] store_data_d;
logic [63:0] store_data_d;
logic [63:0] store_data_dc1;
logic [63:0] store_data_pre_dc2;
logic [63:0] store_data_pre_dc3;
logic [63:0] store_data_pre_dc3;
logic [63:0] store_data_dc2_in;
logic [31:0] rs1_dc1_raw;
lsu_pkt_t dma_pkt_d;
lsu_pkt_t lsu_pkt_dc1_in, lsu_pkt_dc2_in, lsu_pkt_dc3_in, lsu_pkt_dc4_in, lsu_pkt_dc5_in;
@ -175,22 +177,22 @@ module lsu_lsc_ctl
rvdffe #(12) offsetff (.*, .din(lsu_offset_d[11:0]), .dout(offset_dc1[11:0]), .en(lsu_freeze_c1_dc1_clken));
assign rs1_dc1[31:0] = (lsu_pkt_dc1.load_ldst_bypass_c1) ? lsu_result_dc3[31:0] : rs1_dc1_raw[31:0];
// generate the ls address
// need to refine this is memory is only 128KB
rvlsadder lsadder (.rs1(rs1_dc1[31:0]),
.offset(offset_dc1[11:0]),
.dout(full_addr_dc1[31:0])
);
// Module to generate the memory map of the address
lsu_addrcheck addrcheck (
.start_addr_dc1(full_addr_dc1[31:0]),
.end_addr_dc1(full_end_addr_dc1[31:0]),
.*
);
// Calculate start/end address for load/store
assign addr_offset_dc1[2:0] = ({3{lsu_pkt_dc1.half}} & 3'b01) | ({3{lsu_pkt_dc1.word}} & 3'b11) | ({3{lsu_pkt_dc1.dword}} & 3'b111);
assign end_addr_offset_dc1[12:0] = {offset_dc1[11],offset_dc1[11:0]} + {9'b0,addr_offset_dc1[2:0]};
@ -198,17 +200,20 @@ module lsu_lsc_ctl
assign end_addr_dc1[31:0] = full_end_addr_dc1[31:0];
assign lsu_exc_dc2 = access_fault_dc2 | misaligned_fault_dc2;
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
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.dma_valid = lsu_pkt_dc3.dma;
assign lsu_error_pkt_dc3.inst_pipe = ~lsu_i0_valid_dc3;
assign lsu_error_pkt_dc3.exc_type = ~misaligned_fault_dc3;
// assign lsu_error_pkt_dc3.addr[31:0] = (access_fault_dc3 | misaligned_fault_dc3) ? lsu_addr_dc3[31:0] : ld_bus_error_addr_dc3[31:0];
assign lsu_error_pkt_dc3.addr[31:0] = lsu_addr_dc3[31:0];
//Create DMA packet
assign dma_pkt_d.valid = dma_dccm_req;
@ -223,38 +228,38 @@ module lsu_lsc_ctl
assign dma_pkt_d.load_ldst_bypass_c1 = '0;
assign dma_pkt_d.store_data_bypass_c1 = '0;
assign dma_pkt_d.store_data_bypass_c2 = '0;
assign dma_pkt_d.store_data_bypass_i0_e2_c2 = '0;
assign dma_pkt_d.store_data_bypass_i0_e2_c2 = '0;
assign dma_pkt_d.store_data_bypass_e4_c1 = '0;
assign dma_pkt_d.store_data_bypass_e4_c2 = '0;
assign dma_pkt_d.store_data_bypass_e4_c3 = '0;
assign dma_pkt_d.store_data_bypass_e4_c3 = '0;
always_comb begin
lsu_pkt_dc1_in = dma_dccm_req ? dma_pkt_d : lsu_p;
lsu_pkt_dc2_in = lsu_pkt_dc1;
lsu_pkt_dc3_in = lsu_pkt_dc2;
lsu_pkt_dc4_in = lsu_pkt_dc3;
lsu_pkt_dc5_in = lsu_pkt_dc4;
lsu_pkt_dc1_in.valid = (lsu_p.valid & ~flush_dc2_up) | dma_dccm_req;
lsu_pkt_dc2_in.valid = lsu_pkt_dc1.valid & ~(flush_dc2_up & ~lsu_pkt_dc1.dma);
lsu_pkt_dc3_in.valid = lsu_pkt_dc2.valid & ~(flush_dc2_up & ~lsu_pkt_dc2.dma);
lsu_pkt_dc4_in.valid = lsu_pkt_dc3.valid & ~(flush_dc3 & ~lsu_pkt_dc3.dma) & ~lsu_freeze_dc3;
lsu_pkt_dc5_in.valid = lsu_pkt_dc4.valid & ~(flush_dc4 & ~lsu_pkt_dc4.dma);
end
end
// C2 clock for valid and C1 for other bits of packet
rvdff #(1) lsu_pkt_vlddc1ff (.*, .din(lsu_pkt_dc1_in.valid), .dout(lsu_pkt_dc1.valid), .clk(lsu_freeze_c2_dc1_clk));
rvdff #(1) lsu_pkt_vlddc2ff (.*, .din(lsu_pkt_dc2_in.valid), .dout(lsu_pkt_dc2.valid), .clk(lsu_freeze_c2_dc2_clk));
rvdff #(1) lsu_pkt_vlddc3ff (.*, .din(lsu_pkt_dc3_in.valid), .dout(lsu_pkt_dc3.valid), .clk(lsu_freeze_c2_dc3_clk));
rvdff #(1) lsu_pkt_vlddc4ff (.*, .din(lsu_pkt_dc4_in.valid), .dout(lsu_pkt_dc4.valid), .clk(lsu_c2_dc4_clk));
rvdff #(1) lsu_pkt_vlddc5ff (.*, .din(lsu_pkt_dc5_in.valid), .dout(lsu_pkt_dc5.valid), .clk(lsu_c2_dc5_clk));
rvdff #(1) lsu_pkt_vlddc5ff (.*, .din(lsu_pkt_dc5_in.valid), .dout(lsu_pkt_dc5.valid), .clk(lsu_c2_dc5_clk));
rvdffe #($bits(lsu_pkt_t)-1) lsu_pkt_dc1ff (.*, .din(lsu_pkt_dc1_in[$bits(lsu_pkt_t)-1:1]), .dout(lsu_pkt_dc1[$bits(lsu_pkt_t)-1:1]), .en(lsu_freeze_c1_dc1_clken));
rvdffe #($bits(lsu_pkt_t)-1) lsu_pkt_dc2ff (.*, .din(lsu_pkt_dc2_in[$bits(lsu_pkt_t)-1:1]), .dout(lsu_pkt_dc2[$bits(lsu_pkt_t)-1:1]), .en(lsu_freeze_c1_dc2_clken));
rvdffe #($bits(lsu_pkt_t)-1) lsu_pkt_dc3ff (.*, .din(lsu_pkt_dc3_in[$bits(lsu_pkt_t)-1:1]), .dout(lsu_pkt_dc3[$bits(lsu_pkt_t)-1:1]), .en(lsu_freeze_c1_dc3_clken));
rvdff #($bits(lsu_pkt_t)-1) lsu_pkt_dc4ff (.*, .din(lsu_pkt_dc4_in[$bits(lsu_pkt_t)-1:1]), .dout(lsu_pkt_dc4[$bits(lsu_pkt_t)-1:1]), .clk(lsu_c1_dc4_clk));
rvdff #($bits(lsu_pkt_t)-1) lsu_pkt_dc5ff (.*, .din(lsu_pkt_dc5_in[$bits(lsu_pkt_t)-1:1]), .dout(lsu_pkt_dc5[$bits(lsu_pkt_t)-1:1]), .clk(lsu_c1_dc5_clk));
rvdff #($bits(lsu_pkt_t)-1) lsu_pkt_dc5ff (.*, .din(lsu_pkt_dc5_in[$bits(lsu_pkt_t)-1:1]), .dout(lsu_pkt_dc5[$bits(lsu_pkt_t)-1:1]), .clk(lsu_c1_dc5_clk));
assign lsu_ld_datafn_dc3[31:0] = addr_external_dc3 ? bus_read_data_dc3[31:0] : lsu_ld_data_dc3[31:0];
assign lsu_ld_datafn_corr_dc3[31:0] = addr_external_dc3 ? bus_read_data_dc3[31:0] : lsu_ld_data_corr_dc3[31:0];
@ -271,61 +276,61 @@ module lsu_lsc_ctl
({32{~lsu_pkt_dc3.unsign & lsu_pkt_dc3.half}} & {{16{ lsu_ld_datafn_corr_dc3[15]}},lsu_ld_datafn_corr_dc3[15:0]}) |
({32{lsu_pkt_dc3.word}} & lsu_ld_datafn_corr_dc3[31:0]);
// absence load/store all 0's
// absence load/store all 0's
assign lsu_addr_dc1[31:0] = full_addr_dc1[31:0];
// Interrupt as a flush source allows the WB to occur
assign lsu_commit_dc5 = lsu_pkt_dc5.valid & (lsu_pkt_dc5.store | lsu_pkt_dc5.load) & ~flush_dc5 & ~lsu_pkt_dc5.dma;
assign dma_mem_wdata_shifted[63:0] = dma_mem_wdata[63:0] >> {dma_mem_addr[2:0], 3'b000}; // Shift the dma data to lower bits to make it consistent to lsu stores
assign store_data_d[63:0] = dma_dccm_req ? dma_mem_wdata_shifted[63:0] : {32'b0,exu_lsu_rs2_d[31:0]};
assign store_data_d[63:0] = dma_dccm_req ? dma_mem_wdata_shifted[63:0] : {32'b0,exu_lsu_rs2_d[31:0]};
assign store_data_dc2_in[63:32] = store_data_dc1[63:32];
assign store_data_dc2_in[31:0] = (lsu_pkt_dc1.store_data_bypass_c1) ? lsu_result_dc3[31:0] :
assign store_data_dc2_in[31:0] = (lsu_pkt_dc1.store_data_bypass_c1) ? lsu_result_dc3[31:0] :
(lsu_pkt_dc1.store_data_bypass_e4_c1[1]) ? i1_result_e4_eff[31:0] :
(lsu_pkt_dc1.store_data_bypass_e4_c1[0]) ? i0_result_e4_eff[31:0] : store_data_dc1[31:0];
assign store_data_dc2[63:32] = store_data_pre_dc2[63:32];
assign store_data_dc2[31:0] = (lsu_pkt_dc2.store_data_bypass_i0_e2_c2) ? i0_result_e2[31:0] :
(lsu_pkt_dc2.store_data_bypass_c2) ? lsu_result_dc3[31:0] :
(lsu_pkt_dc2.store_data_bypass_c2) ? lsu_result_dc3[31:0] :
(lsu_pkt_dc2.store_data_bypass_e4_c2[1]) ? i1_result_e4_eff[31:0] :
(lsu_pkt_dc2.store_data_bypass_e4_c2[0]) ? i0_result_e4_eff[31:0] : store_data_pre_dc2[31:0];
assign store_data_dc3[63:32] = store_data_pre_dc3[63:32];
assign store_data_dc3[31:0] = (picm_mask_data_dc3[31:0] | {32{~addr_in_pic_dc3}}) &
assign store_data_dc3[31:0] = (picm_mask_data_dc3[31:0] | {32{~addr_in_pic_dc3}}) &
((lsu_pkt_dc3.store_data_bypass_e4_c3[1]) ? i1_result_e4_eff[31:0] :
(lsu_pkt_dc3.store_data_bypass_e4_c3[0]) ? i0_result_e4_eff[31:0] : store_data_pre_dc3[31:0]);
rvdff #(32) lsu_result_corr_dc4ff (.*, .din(lsu_result_corr_dc3[31:0]), .dout(lsu_result_corr_dc4[31:0]), .clk(lsu_c1_dc4_clk));
rvdffe #(64) sddc1ff (.*, .din(store_data_d[63:0]), .dout(store_data_dc1[63:0]), .en(lsu_store_c1_dc1_clken));
rvdffe #(64) sddc2ff (.*, .din(store_data_dc2_in[63:0]), .dout(store_data_pre_dc2[63:0]), .en(lsu_store_c1_dc2_clken));
rvdffe #(64) sddc3ff (.*, .din(store_data_dc2[63:0]), .dout(store_data_pre_dc3[63:0]), .en(~lsu_freeze_dc3 & lsu_store_c1_dc3_clken) );
rvdff #(32) sddc4ff (.*, .din(store_data_dc3[31:0]), .dout(store_data_dc4[31:0]), .clk(lsu_store_c1_dc4_clk));
rvdff #(32) sddc5ff (.*, .din(store_data_dc4[31:0]), .dout(store_data_dc5[31:0]), .clk(lsu_store_c1_dc5_clk));
rvdff #(32) sddc5ff (.*, .din(store_data_dc4[31:0]), .dout(store_data_dc5[31:0]), .clk(lsu_store_c1_dc5_clk));
rvdffe #(32) sadc2ff (.*, .din(lsu_addr_dc1[31:0]), .dout(lsu_addr_dc2[31:0]), .en(lsu_freeze_c1_dc2_clken));
rvdffe #(32) sadc3ff (.*, .din(lsu_addr_dc2[31:0]), .dout(lsu_addr_dc3[31:0]), .en(lsu_freeze_c1_dc3_clken));
rvdff #(32) sadc4ff (.*, .din(lsu_addr_dc3[31:0]), .dout(lsu_addr_dc4[31:0]), .clk(lsu_c1_dc4_clk));
rvdff #(32) sadc5ff (.*, .din(lsu_addr_dc4[31:0]), .dout(lsu_addr_dc5[31:0]), .clk(lsu_c1_dc5_clk));
rvdff #(32) sadc5ff (.*, .din(lsu_addr_dc4[31:0]), .dout(lsu_addr_dc5[31:0]), .clk(lsu_c1_dc5_clk));
rvdffe #(32) end_addr_dc2ff (.*, .din(end_addr_dc1[31:0]), .dout(end_addr_dc2[31:0]), .en(lsu_freeze_c1_dc2_clken));
rvdffe #(32) end_addr_dc3ff (.*, .din(end_addr_dc2[31:0]), .dout(end_addr_dc3[31:0]), .en(lsu_freeze_c1_dc3_clken));
rvdff #(32) end_addr_dc4ff (.*, .din(end_addr_dc3[31:0]), .dout(end_addr_dc4[31:0]), .clk(lsu_c1_dc4_clk));
rvdff #(32) end_addr_dc5ff (.*, .din(end_addr_dc4[31:0]), .dout(end_addr_dc5[31:0]), .clk(lsu_c1_dc5_clk));
rvdff #(32) end_addr_dc5ff (.*, .din(end_addr_dc4[31:0]), .dout(end_addr_dc5[31:0]), .clk(lsu_c1_dc5_clk));
rvdff #(1) addr_in_dccm_dc2ff(.din(addr_in_dccm_dc1), .dout(addr_in_dccm_dc2), .clk(lsu_freeze_c1_dc2_clk), .*);
rvdff #(1) addr_in_dccm_dc3ff(.din(addr_in_dccm_dc2), .dout(addr_in_dccm_dc3), .clk(lsu_freeze_c1_dc3_clk), .*);
rvdff #(1) addr_in_pic_dc2ff(.din(addr_in_pic_dc1), .dout(addr_in_pic_dc2), .clk(lsu_freeze_c1_dc2_clk), .*);
rvdff #(1) addr_in_pic_dc3ff(.din(addr_in_pic_dc2), .dout(addr_in_pic_dc3), .clk(lsu_freeze_c1_dc3_clk), .*);
rvdff #(1) addr_external_dc2ff(.din(addr_external_dc1), .dout(addr_external_dc2), .clk(lsu_freeze_c1_dc2_clk), .*);
rvdff #(1) addr_external_dc3ff(.din(addr_external_dc2), .dout(addr_external_dc3), .clk(lsu_freeze_c1_dc3_clk), .*);
rvdff #(1) addr_external_dc4ff(.din(addr_external_dc3), .dout(addr_external_dc4), .clk(lsu_c1_dc4_clk), .*);
rvdff #(1) addr_external_dc5ff(.din(addr_external_dc4), .dout(addr_external_dc5), .clk(lsu_c1_dc5_clk), .*);
rvdff #(1) access_fault_dc2ff(.din(access_fault_dc1), .dout(access_fault_dc2), .clk(lsu_freeze_c1_dc2_clk), .*);
rvdff #(1) access_fault_dc3ff(.din(access_fault_dc2), .dout(access_fault_dc3), .clk(lsu_freeze_c1_dc3_clk), .*);
rvdff #(1) misaligned_fault_dc2ff(.din(misaligned_fault_dc1), .dout(misaligned_fault_dc2), .clk(lsu_freeze_c1_dc2_clk), .*);

View File

@ -1,12 +1,12 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright 2019 Western Digital Corporation or its affiliates.
//
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//
// http://www.apache.org/licenses/LICENSE-2.0
//
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -16,14 +16,14 @@
//********************************************************************************
// $Id$
//
//
// Owner:
//
// Owner:
// Function: Store Buffer
// Comments: Dual writes and single drain
//
//
//
// DC1 -> DC2 -> DC3 -> DC4 (Commit)
//
//
// //********************************************************************************
@ -34,11 +34,11 @@ module lsu_stbuf
input logic rst_l, // reset
input logic lsu_freeze_c2_dc2_clk, // freeze clock
input logic lsu_freeze_c2_dc3_clk, // freeze clock
input logic lsu_freeze_c2_dc3_clk, // freeze clock
input logic lsu_freeze_c1_dc2_clk, // freeze clock
input logic lsu_freeze_c1_dc3_clk, // freeze clock
input logic lsu_freeze_c1_dc3_clken,
input logic lsu_freeze_c1_dc3_clken,
input logic lsu_c1_dc4_clk, // lsu pipe clock
input logic lsu_c1_dc5_clk, // lsu pipe clock
@ -46,11 +46,11 @@ module lsu_stbuf
input logic lsu_c2_dc5_clk, // lsu pipe clock
input logic lsu_stbuf_c1_clk, // stbuf clock
input logic lsu_free_c2_clk, // free clk
// Store Buffer input
// Store Buffer input
input logic load_stbuf_reqvld_dc3, // core instruction goes to stbuf
input logic store_stbuf_reqvld_dc3, // core instruction goes to stbuf
//input logic ldst_stbuf_reqvld_dc3,
//input logic ldst_stbuf_reqvld_dc3,
input logic addr_in_pic_dc2, // address is in pic
input logic addr_in_pic_dc3, // address is in pic
input logic addr_in_dccm_dc2, // address is in pic
@ -61,14 +61,14 @@ module lsu_stbuf
input logic isldst_dc1, // instruction in dc1 is lsu
input logic dccm_ldst_dc2, // instruction in dc2 is lsu
input logic dccm_ldst_dc3, // instruction in dc3 is lsu
input logic single_ecc_error_hi_dc3, // single ecc error in hi bank
input logic single_ecc_error_lo_dc3, // single ecc error in lo bank
input logic lsu_single_ecc_error_dc5, // single_ecc_error in either bank staged to the dc5 - needed for the load repairs
input logic lsu_commit_dc5, // lsu commits
input logic lsu_freeze_dc3, // lsu freeze
input logic flush_prior_dc5, // Flush is due to i0 and ld/st is in i1
// Store Buffer output
output logic stbuf_reqvld_any, // stbuf is draining
output logic stbuf_reqvld_flushed_any, // Top entry is flushed
@ -81,43 +81,44 @@ module lsu_stbuf
output logic lsu_stbuf_full_any, // stbuf is full
output logic lsu_stbuf_empty_any, // stbuf is empty
output logic lsu_stbuf_nodma_empty_any, // stbuf is empty except dma
output logic lsu_load_ecc_stbuf_full_dc3, // Load with ecc error can't allocate to stbuf
input logic [`RV_LSU_SB_BITS-1:0] lsu_addr_dc1, // lsu address
input logic [`RV_LSU_SB_BITS-1:0] lsu_addr_dc2,
input logic [`RV_LSU_SB_BITS-1:0] lsu_addr_dc3,
input logic [`RV_LSU_SB_BITS-1:0] end_addr_dc1, // lsu end addrress - needed to check unaligned
input logic [`RV_LSU_SB_BITS-1:0] end_addr_dc2,
input logic [`RV_LSU_SB_BITS-1:0] end_addr_dc3,
// Forwarding signals
input logic lsu_cmpen_dc2, // needed for forwarding stbuf - load
input lsu_pkt_t lsu_pkt_dc2,
input lsu_pkt_t lsu_pkt_dc3,
input lsu_pkt_t lsu_pkt_dc5,
input lsu_pkt_t lsu_pkt_dc3,
input lsu_pkt_t lsu_pkt_dc5,
output logic [`RV_DCCM_DATA_WIDTH-1:0] stbuf_fwddata_hi_dc3, // stbuf data
output logic [`RV_DCCM_DATA_WIDTH-1:0] stbuf_fwddata_lo_dc3,
output logic [`RV_DCCM_BYTE_WIDTH-1:0] stbuf_fwdbyteen_hi_dc3,
output logic [`RV_DCCM_BYTE_WIDTH-1:0] stbuf_fwdbyteen_lo_dc3,
input logic scan_mode
input logic scan_mode
);
`include "global.h"
localparam DEPTH = LSU_STBUF_DEPTH;
localparam DATA_WIDTH = DCCM_DATA_WIDTH;
localparam BYTE_WIDTH = DCCM_BYTE_WIDTH;
localparam DEPTH_LOG2 = $clog2(DEPTH);
logic [DEPTH-1:0] stbuf_data_vld;
logic [DEPTH-1:0] stbuf_drain_vld;
logic [DEPTH-1:0] stbuf_flush_vld;
logic [DEPTH-1:0] stbuf_addr_in_pic;
logic [DEPTH-1:0] stbuf_dma;
logic [DEPTH-1:0][LSU_SB_BITS-1:0] stbuf_addr;
logic [DEPTH-1:0][LSU_SB_BITS-1:0] stbuf_addr;
logic [DEPTH-1:0][BYTE_WIDTH-1:0] stbuf_byteen;
logic [DEPTH-1:0][DATA_WIDTH-1:0] stbuf_data;
@ -131,16 +132,16 @@ module lsu_stbuf
logic [DEPTH-1:0][LSU_SB_BITS-1:0] stbuf_addrin;
logic [DEPTH-1:0][DATA_WIDTH-1:0] stbuf_datain;
logic [DEPTH-1:0][BYTE_WIDTH-1:0] stbuf_byteenin;
logic [7:0] ldst_byteen_dc3;
logic [7:0] store_byteen_ext_dc3;
logic [BYTE_WIDTH-1:0] store_byteen_hi_dc3;
logic [BYTE_WIDTH-1:0] store_byteen_lo_dc3;
logic ldst_stbuf_reqvld_dc3;
logic ldst_stbuf_reqvld_dc3;
logic dual_ecc_error_dc3;
logic dual_stbuf_write_dc3;
logic WrPtrEn, RdPtrEn;
logic [DEPTH_LOG2-1:0] WrPtr, RdPtr;
logic [DEPTH_LOG2-1:0] NxtWrPtr, NxtRdPtr;
@ -149,13 +150,13 @@ module lsu_stbuf
logic ldst_dual_dc1, ldst_dual_dc2, ldst_dual_dc3, ldst_dual_dc4, ldst_dual_dc5;
logic ldst_stbuf_reqvld_dc4, ldst_stbuf_reqvld_dc5;
logic dual_stbuf_write_dc4, dual_stbuf_write_dc5;
logic [3:0] stbuf_numvld_any, stbuf_specvld_any;
logic [1:0] stbuf_specvld_dc1, stbuf_specvld_dc2, stbuf_specvld_dc3;
logic stbuf_oneavl_any, stbuf_twoavl_any;
logic cmpen_hi_dc2, cmpen_lo_dc2, jit_in_same_region;
logic [LSU_SB_BITS-1:$clog2(BYTE_WIDTH)] cmpaddr_hi_dc2, cmpaddr_lo_dc2;
logic stbuf_ldmatch_hi_hi, stbuf_ldmatch_hi_lo;
@ -164,7 +165,7 @@ module lsu_stbuf
logic [BYTE_WIDTH-1:0] stbuf_fwdbyteen_lo_hi, stbuf_fwdbyteen_lo_lo;
logic [DATA_WIDTH-1:0] stbuf_fwddata_hi_hi, stbuf_fwddata_hi_lo;
logic [DATA_WIDTH-1:0] stbuf_fwddata_lo_hi, stbuf_fwddata_lo_lo;
logic [DEPTH-1:0] stbuf_ldmatch_hi, stbuf_ldmatch_lo;
logic [DEPTH-1:0][BYTE_WIDTH-1:0] stbuf_fwdbyteenvec_hi, stbuf_fwdbyteenvec_lo;
logic [DEPTH-1:0][DATA_WIDTH-1:0] stbuf_fwddatavec_hi, stbuf_fwddatavec_lo;
@ -205,8 +206,8 @@ module lsu_stbuf
assign stbuf_data_en[i] = stbuf_wr_en[i];
assign stbuf_drain_or_flush_en[i] = ldst_stbuf_reqvld_dc5 & ~lsu_pkt_dc5.dma & ((i == WrPtr_dc5[DEPTH_LOG2-1:0]) |
(i == WrPtrPlus1_dc5[DEPTH_LOG2-1:0] & dual_stbuf_write_dc5));
assign stbuf_drain_en[i] = (stbuf_drain_or_flush_en[i] & (lsu_commit_dc5 | stbuf_load_repair_dc5)) | (stbuf_wr_en[i] & lsu_pkt_dc3.dma);
assign stbuf_flush_en[i] = stbuf_drain_or_flush_en[i] & ~(lsu_commit_dc5 | stbuf_load_repair_dc5);
assign stbuf_drain_en[i] = (stbuf_drain_or_flush_en[i] & lsu_commit_dc5) | (stbuf_wr_en[i] & lsu_pkt_dc3.dma);
assign stbuf_flush_en[i] = stbuf_drain_or_flush_en[i] & ~lsu_commit_dc5;
assign stbuf_reset[i] = (lsu_stbuf_commit_any | stbuf_reqvld_flushed_any) & (i == RdPtr[DEPTH_LOG2-1:0]);
// Mux select for start/end address
@ -214,7 +215,7 @@ module lsu_stbuf
assign stbuf_addrin[i][LSU_SB_BITS-1:0] = sel_lo[i] ? lsu_addr_dc3[LSU_SB_BITS-1:0] : end_addr_dc3[LSU_SB_BITS-1:0];
assign stbuf_byteenin[i][BYTE_WIDTH-1:0] = sel_lo[i] ? store_byteen_lo_dc3[BYTE_WIDTH-1:0] : store_byteen_hi_dc3[BYTE_WIDTH-1:0];
assign stbuf_datain[i][DATA_WIDTH-1:0] = sel_lo[i] ? store_ecc_datafn_lo_dc3[DATA_WIDTH-1:0] : store_ecc_datafn_hi_dc3[DATA_WIDTH-1:0];
rvdffsc #(.WIDTH(1)) stbuf_data_vldff (.din(1'b1), .dout(stbuf_data_vld[i]), .en(stbuf_wr_en[i]), .clear(stbuf_reset[i]), .clk(lsu_stbuf_c1_clk), .*);
rvdffsc #(.WIDTH(1)) stbuf_drain_vldff (.din(1'b1), .dout(stbuf_drain_vld[i]), .en(stbuf_drain_en[i]), .clear(stbuf_reset[i]), .clk(lsu_free_c2_clk), .*);
rvdffsc #(.WIDTH(1)) stbuf_flush_vldff (.din(1'b1), .dout(stbuf_flush_vld[i]), .en(stbuf_flush_en[i]), .clear(stbuf_reset[i]), .clk(lsu_free_c2_clk), .*);
@ -274,7 +275,8 @@ module lsu_stbuf
assign lsu_stbuf_full_any = (stbuf_specvld_any[3:0] > (DEPTH - 2));
assign lsu_stbuf_empty_any = (stbuf_numvld_any[3:0] == 4'b0);
assign lsu_stbuf_nodma_empty_any = ~(|(stbuf_data_vld[DEPTH-1:0] & ~stbuf_dma[DEPTH-1:0]));
assign lsu_load_ecc_stbuf_full_dc3 = load_stbuf_reqvld_dc3 & ~ldst_stbuf_reqvld_dc3;
assign stbuf_oneavl_any = (stbuf_numvld_any[3:0] < DEPTH);
assign stbuf_twoavl_any = (stbuf_numvld_any[3:0] < (DEPTH - 1));
@ -285,7 +287,7 @@ module lsu_stbuf
assign cmpen_lo_dc2 = lsu_cmpen_dc2;
assign cmpaddr_lo_dc2[LSU_SB_BITS-1:$clog2(BYTE_WIDTH)] = lsu_addr_dc2[LSU_SB_BITS-1:$clog2(BYTE_WIDTH)];
assign jit_in_same_region = (addr_in_pic_dc2 & addr_in_pic_dc3) | (addr_in_dccm_dc2 & addr_in_dccm_dc3);
// JIT forwarding
assign stbuf_ldmatch_hi_hi = (end_addr_dc3[LSU_SB_BITS-1:$clog2(BYTE_WIDTH)] == cmpaddr_hi_dc2[LSU_SB_BITS-1:$clog2(BYTE_WIDTH)]) & ~(cmpen_hi_dc2 & lsu_pkt_dc2.dma & ~lsu_pkt_dc3.dma) & jit_in_same_region;
assign stbuf_ldmatch_hi_lo = (lsu_addr_dc3[LSU_SB_BITS-1:$clog2(BYTE_WIDTH)] == cmpaddr_hi_dc2[LSU_SB_BITS-1:$clog2(BYTE_WIDTH)]) & ~(cmpen_hi_dc2 & lsu_pkt_dc2.dma & ~lsu_pkt_dc3.dma) & jit_in_same_region;
@ -297,27 +299,27 @@ module lsu_stbuf
assign stbuf_fwdbyteen_hi_lo[i] = stbuf_ldmatch_hi_lo & store_byteen_lo_dc3[i] & ldst_stbuf_reqvld_dc3;
assign stbuf_fwdbyteen_lo_hi[i] = stbuf_ldmatch_lo_hi & store_byteen_hi_dc3[i] & ldst_stbuf_reqvld_dc3 & dual_stbuf_write_dc3;
assign stbuf_fwdbyteen_lo_lo[i] = stbuf_ldmatch_lo_lo & store_byteen_lo_dc3[i] & ldst_stbuf_reqvld_dc3;
assign stbuf_fwddata_hi_hi[(8*i)+7:(8*i)] = {8{stbuf_fwdbyteen_hi_hi[i]}} & store_ecc_datafn_hi_dc3[(8*i)+7:(8*i)];
assign stbuf_fwddata_hi_lo[(8*i)+7:(8*i)] = {8{stbuf_fwdbyteen_hi_lo[i]}} & store_ecc_datafn_lo_dc3[(8*i)+7:(8*i)];
assign stbuf_fwddata_lo_hi[(8*i)+7:(8*i)] = {8{stbuf_fwdbyteen_lo_hi[i]}} & store_ecc_datafn_hi_dc3[(8*i)+7:(8*i)];
assign stbuf_fwddata_lo_lo[(8*i)+7:(8*i)] = {8{stbuf_fwdbyteen_lo_lo[i]}} & store_ecc_datafn_lo_dc3[(8*i)+7:(8*i)];
end
always_comb begin: GenLdFwd
stbuf_fwdbyteen_hi_dc2[BYTE_WIDTH-1:0] = '0;
stbuf_fwdbyteen_lo_dc2[BYTE_WIDTH-1:0] = '0;
for (int i=0; i<DEPTH; i++) begin
stbuf_ldmatch_hi[i] = (stbuf_addr[i][LSU_SB_BITS-1:$clog2(BYTE_WIDTH)] == cmpaddr_hi_dc2[LSU_SB_BITS-1:$clog2(BYTE_WIDTH)]) &
stbuf_ldmatch_hi[i] = (stbuf_addr[i][LSU_SB_BITS-1:$clog2(BYTE_WIDTH)] == cmpaddr_hi_dc2[LSU_SB_BITS-1:$clog2(BYTE_WIDTH)]) &
(stbuf_drain_vld[i] | ~lsu_pkt_dc2.dma) & ~stbuf_flush_vld[i] & ((stbuf_addr_in_pic[i] & addr_in_pic_dc2) | (~stbuf_addr_in_pic[i] & addr_in_dccm_dc2));
stbuf_ldmatch_lo[i] = (stbuf_addr[i][LSU_SB_BITS-1:$clog2(BYTE_WIDTH)] == cmpaddr_lo_dc2[LSU_SB_BITS-1:$clog2(BYTE_WIDTH)]) &
stbuf_ldmatch_lo[i] = (stbuf_addr[i][LSU_SB_BITS-1:$clog2(BYTE_WIDTH)] == cmpaddr_lo_dc2[LSU_SB_BITS-1:$clog2(BYTE_WIDTH)]) &
(stbuf_drain_vld[i] | ~lsu_pkt_dc2.dma) & ~stbuf_flush_vld[i] & ((stbuf_addr_in_pic[i] & addr_in_pic_dc2) | (~stbuf_addr_in_pic[i] & addr_in_dccm_dc2));
for (int j=0; j<BYTE_WIDTH; j++) begin
stbuf_fwdbyteenvec_hi[i][j] = stbuf_ldmatch_hi[i] & stbuf_byteen[i][j] & stbuf_data_vld[i];
stbuf_fwdbyteen_hi_dc2[j] |= stbuf_fwdbyteenvec_hi[i][j];
stbuf_fwdbyteenvec_lo[i][j] = stbuf_ldmatch_lo[i] & stbuf_byteen[i][j] & stbuf_data_vld[i];
stbuf_fwdbyteen_lo_dc2[j] |= stbuf_fwdbyteenvec_lo[i][j];
end
@ -325,7 +327,7 @@ module lsu_stbuf
end // block: GenLdFwd
for (genvar i=0; i<DEPTH; i++) begin
for (genvar j=0; j<BYTE_WIDTH; j++) begin
for (genvar j=0; j<BYTE_WIDTH; j++) begin
assign stbuf_fwddatavec_hi[i][(8*j)+7:(8*j)] = {8{stbuf_fwdbyteenvec_hi[i][j]}} & stbuf_data[i][(8*j)+7:(8*j)];
assign stbuf_fwddatavec_lo[i][(8*j)+7:(8*j)] = {8{stbuf_fwdbyteenvec_lo[i][j]}} & stbuf_data[i][(8*j)+7:(8*j)];
end
@ -373,10 +375,10 @@ module lsu_stbuf
assign stbuf_fwdbyteen_hi_fn_dc2[i] = stbuf_fwdbyteen_hi_hi[i] | stbuf_fwdbyteen_hi_lo[i] | stbuf_fwdbyteen_hi_dc2[i];
assign stbuf_fwdbyteen_lo_fn_dc2[i] = stbuf_fwdbyteen_lo_hi[i] | stbuf_fwdbyteen_lo_lo[i] | stbuf_fwdbyteen_lo_dc2[i];
assign stbuf_fwddata_hi_fn_dc2[(8*i)+7:(8*i)] = (stbuf_fwdbyteen_hi_hi[i] | stbuf_fwdbyteen_hi_lo[i]) ?
assign stbuf_fwddata_hi_fn_dc2[(8*i)+7:(8*i)] = (stbuf_fwdbyteen_hi_hi[i] | stbuf_fwdbyteen_hi_lo[i]) ?
(stbuf_fwddata_hi_hi[(8*i)+7:(8*i)] | stbuf_fwddata_hi_lo[(8*i)+7:(8*i)]) :
stbuf_fwddata_hi_dc2[(8*i)+7:(8*i)];
assign stbuf_fwddata_lo_fn_dc2[(8*i)+7:(8*i)] = (stbuf_fwdbyteen_lo_hi[i] | stbuf_fwdbyteen_lo_lo[i]) ?
assign stbuf_fwddata_lo_fn_dc2[(8*i)+7:(8*i)] = (stbuf_fwdbyteen_lo_hi[i] | stbuf_fwdbyteen_lo_lo[i]) ?
(stbuf_fwddata_lo_hi[(8*i)+7:(8*i)] | stbuf_fwddata_lo_lo[(8*i)+7:(8*i)]) :
stbuf_fwddata_lo_dc2[(8*i)+7:(8*i)];
end
@ -395,8 +397,14 @@ module lsu_stbuf
assert_drainorflushvld_notvld: assert #0 (~(|((stbuf_drain_vld[DEPTH-1:0] | stbuf_flush_vld[DEPTH-1:0]) & ~stbuf_data_vld[DEPTH-1:0])));
assert_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
endmodule

View File

@ -1,12 +1,12 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright 2019 Western Digital Corporation or its affiliates.
//
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//
// http://www.apache.org/licenses/LICENSE-2.0
//
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -16,13 +16,13 @@
//********************************************************************************
// $Id$
//
//
// Owner:
//
// Owner:
// Function: LSU Trigger logic
// Comments:
//
//********************************************************************************
module lsu_trigger
module lsu_trigger
import swerv_types::*;
(
input logic clk, // clock
@ -31,7 +31,7 @@ module lsu_trigger
input trigger_pkt_t [3:0] trigger_pkt_any, // trigger packet from dec
input lsu_pkt_t lsu_pkt_dc3, // lsu packet
input logic [31:0] lsu_addr_dc3, // address
input logic [31:0] lsu_addr_dc3, // address
input logic [31:0] lsu_result_dc3, // load data
input logic [31:0] store_data_dc3, // store data
@ -43,13 +43,13 @@ module lsu_trigger
logic [31:0] store_data_trigger_dc3;
assign store_data_trigger_dc3[31:0] = { ({16{lsu_pkt_dc3.word}} & store_data_dc3[31:16]) , ({8{(lsu_pkt_dc3.half | lsu_pkt_dc3.word)}} & store_data_dc3[15:8]), store_data_dc3[7:0]};
for (genvar i=0; i<4; i++) begin
assign lsu_match_data[i][31:0] = ({32{~trigger_pkt_any[i].select}} & lsu_addr_dc3[31:0]) |
({32{trigger_pkt_any[i].select & trigger_pkt_any[i].store}} & store_data_trigger_dc3[31:0]);
rvmaskandmatch trigger_match (.mask(trigger_pkt_any[i].tdata2[31:0]), .data(lsu_match_data[i][31:0]), .masken(trigger_pkt_any[i].match), .match(lsu_trigger_data_match[i]));
assign lsu_trigger_match_dc3[i] = lsu_pkt_dc3.valid & ~lsu_pkt_dc3.dma &
@ -57,5 +57,5 @@ module lsu_trigger
lsu_trigger_data_match[i];
end
endmodule // lsu_trigger

View File

@ -15,7 +15,7 @@
// limitations under the License.
//********************************************************************************
module mem
module mem
import swerv_types::*;
(
input logic clk,
@ -23,8 +23,8 @@ module mem
input logic lsu_freeze_dc3,
input logic dccm_clk_override,
input logic icm_clk_override,
input logic dec_tlu_core_ecc_disable,
input logic dec_tlu_core_ecc_disable,
//DCCM ports
input logic dccm_wren,
input logic dccm_rden,
@ -45,7 +45,7 @@ module mem
input logic iccm_rden,
input logic [2:0] iccm_wr_size,
input logic [77:0] iccm_wr_data,
output logic [155:0] iccm_rd_data,
`endif
// Icache and Itag Ports
@ -54,44 +54,44 @@ module mem
input logic [3:0] ic_tag_valid,
input logic [3:0] ic_wr_en,
input logic ic_rd_en,
input logic [127:0] ic_premux_data, // Premux data to be muxed with each way of the Icache.
input logic ic_sel_premux_data, // Premux data sel
input logic [127:0] ic_premux_data, // Premux data to be muxed with each way of the Icache.
input logic ic_sel_premux_data, // Premux data sel
`ifdef RV_ICACHE_ECC
input logic [83:0] ic_wr_data, // Data to fill to the Icache. With ECC
input logic [41:0] ic_debug_wr_data, // Debug wr cache.
`else
input logic [41:0] ic_debug_wr_data, // Debug wr cache.
`else
input logic [67:0] ic_wr_data, // Data to fill to the Icache. With Parity
input logic [33:0] ic_debug_wr_data, // Debug wr cache.
input logic [33:0] ic_debug_wr_data, // Debug wr cache.
`endif
input logic [15:2] ic_debug_addr, // Read/Write addresss to the Icache.
input logic [15:2] ic_debug_addr, // Read/Write addresss to the Icache.
input logic ic_debug_rd_en, // Icache debug rd
input logic ic_debug_wr_en, // Icache debug wr
input logic ic_debug_tag_array, // Debug tag array
input logic [3:0] ic_debug_way, // Debug way. Rd or Wr.
`endif
`ifdef RV_ICACHE_ECC
output logic [167:0] ic_rd_data , // Data read from Icache. 2x64bits + parity bits. F2 stage. With ECC
output logic [24:0] ictag_debug_rd_data,// Debug icache tag.
`else
output logic [24:0] ictag_debug_rd_data,// Debug icache tag.
`else
output logic [135:0] ic_rd_data , // Data read from Icache. 2x64bits + parity bits. F2 stage. With Parity
output logic [20:0] ictag_debug_rd_data,// Debug icache tag.
output logic [20:0] ictag_debug_rd_data,// Debug icache tag.
`endif
output logic [3:0] ic_rd_hit,
output logic ic_tag_perr, // Icache Tag parity error
input logic scan_mode
input logic scan_mode
);
`include "global.h"
`ifdef RV_DCCM_ENABLE
localparam DCCM_ENABLE = 1'b1;
`else
@ -108,8 +108,8 @@ module mem
assign dccm_rd_data_lo = '0;
assign dccm_rd_data_hi = '0;
end
`ifdef RV_ICACHE_ENABLE
`ifdef RV_ICACHE_ENABLE
ifu_ic_mem icm (
.clk_override(icm_clk_override),
.*
@ -128,5 +128,5 @@ module mem
.iccm_rd_data(iccm_rd_data[155:0])
);
`endif
endmodule

View File

@ -16,8 +16,8 @@
//********************************************************************************
//********************************************************************************
// Function: Programmable Interrupt Controller
// Comments:
// Function: Programmable Interrupt Controller
// Comments:
//********************************************************************************
module pic_ctrl
@ -43,10 +43,10 @@ module pic_ctrl
output logic [31:0] picm_rd_data, // Read data of the register
output logic mhwakeup, // Wake-up interrupt request
input logic scan_mode // scan mode
);
`include "global.h"
localparam NUM_LEVELS = $clog2(TOTAL_INT);
localparam INTPRIORITY_BASE_ADDR = `RV_PIC_BASE_ADDR ;
localparam INTPEND_BASE_ADDR = `RV_PIC_BASE_ADDR + 32'h00001000 ;
@ -55,21 +55,21 @@ localparam EXT_INTR_PIC_CONFIG = `RV_PIC_BASE_ADDR + 32'h00003000 ;
localparam EXT_INTR_GW_CONFIG = `RV_PIC_BASE_ADDR + 32'h00004000 ;
localparam EXT_INTR_GW_CLEAR = `RV_PIC_BASE_ADDR + 32'h00005000 ;
localparam INTPEND_SIZE = (TOTAL_INT < 32) ? 32 :
localparam INTPEND_SIZE = (TOTAL_INT < 32) ? 32 :
(TOTAL_INT < 64) ? 64 :
(TOTAL_INT < 128) ? 128 :
(TOTAL_INT < 256) ? 256 :
(TOTAL_INT < 256) ? 256 :
(TOTAL_INT < 512) ? 512 : 1024 ;
localparam INT_GRPS = INTPEND_SIZE / 32 ;
localparam INTPRIORITY_BITS = 4 ;
localparam ID_BITS = 8 ;
localparam int GW_CONFIG[TOTAL_INT-1:0] = '{default:0} ;
localparam int GW_CONFIG[TOTAL_INT-1:0] = '{default:0} ;
logic addr_intpend_base_match;
logic addr_intenable_base_match;
logic addr_intpriority_base_match;
logic addr_intpend_base_match;
logic addr_intenable_base_match;
logic addr_intpriority_base_match;
logic addr_config_pic_match ;
logic addr_config_gw_base_match ;
logic addr_clear_gw_base_match ;
@ -105,7 +105,7 @@ logic [INT_GRPS-1:0] [31:0] intpend_rd_part_out ;
logic config_reg;
logic intpriord;
logic config_reg_we ;
logic config_reg_we ;
logic config_reg_re ;
logic config_reg_in ;
logic prithresh_reg_write , prithresh_reg_read;
@ -117,9 +117,9 @@ logic [31:0] picm_addr_ff;
logic [31:0] picm_wr_data_ff;
logic [3:0] mask;
logic picm_mken_ff;
logic [ID_BITS-1:0] claimid_in ;
logic [INTPRIORITY_BITS-1:0] pl_in ;
logic [INTPRIORITY_BITS-1:0] pl_in_q ;
logic [ID_BITS-1:0] claimid_in ;
logic [INTPRIORITY_BITS-1:0] pl_in ;
logic [INTPRIORITY_BITS-1:0] pl_in_q ;
logic [TOTAL_INT-1:0] extintsrc_req_sync;
logic [TOTAL_INT-1:0] extintsrc_req_gw;
@ -130,7 +130,7 @@ logic [TOTAL_INT-1:0] extintsrc_req_gw;
logic pic_pri_c1_clken;
logic pic_int_c1_clken;
logic gw_config_c1_clken;
// clocks
logic pic_addr_c1_clk;
logic pic_data_c1_clk;
@ -145,16 +145,16 @@ logic [TOTAL_INT-1:0] extintsrc_req_gw;
assign pic_pri_c1_clken = (addr_intpriority_base_match & (picm_wren_ff | picm_rden_ff)) | clk_override;
assign pic_int_c1_clken = (addr_intenable_base_match & (picm_wren_ff | picm_rden_ff)) | clk_override;
assign gw_config_c1_clken = (addr_config_gw_base_match & (picm_wren_ff | picm_rden_ff)) | clk_override;
// C1 - 1 clock pulse for data
// C1 - 1 clock pulse for data
rvoclkhdr pic_addr_c1_cgc ( .en(pic_addr_c1_clken), .l1clk(pic_addr_c1_clk), .* );
rvoclkhdr pic_data_c1_cgc ( .en(pic_data_c1_clken), .l1clk(pic_data_c1_clk), .* );
rvoclkhdr pic_pri_c1_cgc ( .en(pic_pri_c1_clken), .l1clk(pic_pri_c1_clk), .* );
rvoclkhdr pic_int_c1_cgc ( .en(pic_int_c1_clken), .l1clk(pic_int_c1_clk), .* );
rvoclkhdr gw_config_c1_cgc ( .en(gw_config_c1_clken), .l1clk(gw_config_c1_clk), .* );
// ------ end clock gating section ------------------------
assign addr_intpend_base_match = (picm_addr_ff[31:6] == INTPEND_BASE_ADDR[31:6]) ;
assign addr_intenable_base_match = (picm_addr_ff[31:NUM_LEVELS+2] == INTENABLE_BASE_ADDR[31:NUM_LEVELS+2]) ;
assign addr_intpriority_base_match = (picm_addr_ff[31:NUM_LEVELS+2] == INTPRIORITY_BASE_ADDR[31:NUM_LEVELS+2]) ;
@ -170,16 +170,16 @@ rvdff #(1) picm_rde_flop (.*, .din (picm_rden),
rvdff #(1) picm_mke_flop (.*, .din (picm_mken), .dout(picm_mken_ff), .clk(active_clk));
rvdff #(32) picm_dat_flop (.*, .din (picm_wr_data[31:0]), .dout(picm_wr_data_ff[31:0]), .clk(pic_data_c1_clk));
rvsyncss #(TOTAL_INT-1) sync_inst
rvsyncss #(TOTAL_INT-1) sync_inst
(
.clk (free_clk),
.dout(extintsrc_req_sync[TOTAL_INT-1:1]),
.din (extintsrc_req[TOTAL_INT-1:1]),
.din (extintsrc_req[TOTAL_INT-1:1]),
.*) ;
assign extintsrc_req_sync[0] = extintsrc_req[0];
genvar i ;
genvar i, l, m , j, k;
for (i=0; i<TOTAL_INT ; i++) begin : SETREG
if (i > 0 ) begin : NON_ZERO_INT
@ -206,21 +206,21 @@ for (i=0; i<TOTAL_INT ; i++) begin : SETREG
.meigwctrl_polarity(gw_config_reg[i][0]) ,
.meigwctrl_type(gw_config_reg[i][1]) ,
.meigwclr(gw_clear_reg_we[i]) ,
.extintsrc_req_config(extintsrc_req_gw[i])
.extintsrc_req_config(extintsrc_req_gw[i])
);
// end else begin
// assign extintsrc_req_gw[i] = extintsrc_req_sync[i] ;
// assign gw_config_reg[i] = '0 ;
// end
end else begin : INT_ZERO
assign intpriority_reg_we[i] = 1'b0 ;
assign intpriority_reg_re[i] = 1'b0 ;
assign intenable_reg_we[i] = 1'b0 ;
assign intenable_reg_re[i] = 1'b0 ;
assign gw_config_reg_we[i] = 1'b0 ;
assign gw_config_reg_we[i] = 1'b0 ;
assign gw_config_reg_re[i] = 1'b0 ;
assign gw_clear_reg_we[i] = 1'b0 ;
@ -230,10 +230,10 @@ for (i=0; i<TOTAL_INT ; i++) begin : SETREG
assign intenable_reg[i] = 1'b0 ;
assign extintsrc_req_gw[i] = 1'b0 ;
end
assign intpriority_reg_inv[i] = intpriord ? ~intpriority_reg[i] : intpriority_reg[i] ;
assign intpend_w_prior_en[i] = {INTPRIORITY_BITS{(extintsrc_req_gw[i] & intenable_reg[i])}} & intpriority_reg_inv[i] ;
assign intpend_id[i] = i ;
end
@ -242,127 +242,115 @@ end
assign pl_in[INTPRIORITY_BITS-1:0] = selected_int_priority[INTPRIORITY_BITS-1:0] ;
`ifdef RV_PIC_2CYCLE
logic [NUM_LEVELS/2:0] [TOTAL_INT+2:0] [INTPRIORITY_BITS-1:0] level_intpend_w_prior_en;
logic [NUM_LEVELS/2:0] [TOTAL_INT+2:0] [ID_BITS-1:0] level_intpend_id;
logic [NUM_LEVELS:NUM_LEVELS/2] [(TOTAL_INT/2**(NUM_LEVELS/2))+1:0] [INTPRIORITY_BITS-1:0] levelx_intpend_w_prior_en;
logic [NUM_LEVELS:NUM_LEVELS/2] [(TOTAL_INT/2**(NUM_LEVELS/2))+1:0] [ID_BITS-1:0] levelx_intpend_id;
logic [NUM_LEVELS/2:0] [TOTAL_INT+2:0] [INTPRIORITY_BITS-1:0] level_intpend_w_prior_en;
logic [NUM_LEVELS/2:0] [TOTAL_INT+2:0] [ID_BITS-1:0] level_intpend_id;
logic [NUM_LEVELS:NUM_LEVELS/2] [(TOTAL_INT/2**(NUM_LEVELS/2))+1:0] [INTPRIORITY_BITS-1:0] levelx_intpend_w_prior_en;
logic [NUM_LEVELS:NUM_LEVELS/2] [(TOTAL_INT/2**(NUM_LEVELS/2))+1:0] [ID_BITS-1:0] levelx_intpend_id;
assign level_intpend_w_prior_en[0][TOTAL_INT+2:0] = {4'b0,4'b0,4'b0,intpend_w_prior_en[TOTAL_INT-1:0]} ;
assign level_intpend_id[0][TOTAL_INT+2:0] = {8'b0,8'b0,8'b0,intpend_id[TOTAL_INT-1:0]} ;
assign level_intpend_w_prior_en[0][TOTAL_INT+2:0] = {4'b0,4'b0,4'b0,intpend_w_prior_en[TOTAL_INT-1:0]} ;
assign level_intpend_id[0][TOTAL_INT+2:0] = {8'b0,8'b0,8'b0,intpend_id[TOTAL_INT-1:0]} ;
logic [(TOTAL_INT/2**(NUM_LEVELS/2)):0] [INTPRIORITY_BITS-1:0] l2_intpend_w_prior_en_ff;
logic [(TOTAL_INT/2**(NUM_LEVELS/2)):0] [ID_BITS-1:0] l2_intpend_id_ff;
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_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]} ;
///////// 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
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] [INTPRIORITY_BITS-1:0] level_intpend_w_prior_en;
logic [NUM_LEVELS:0] [TOTAL_INT+1:0] [ID_BITS-1:0] level_intpend_id;
assign level_intpend_w_prior_en[0][TOTAL_INT+1:0] = {{2*INTPRIORITY_BITS{1'b0}},intpend_w_prior_en[TOTAL_INT-1:0]} ;
assign level_intpend_id[0][TOTAL_INT+1:0] = {{2*ID_BITS{1'b1}},intpend_id[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]} ;
////////// 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
genvar l, m , j, k;
// `ifdef VERILATOR
`include "pic_ctrl_verilator_unroll.sv"
// `else
// `ifdef RV_PIC_2CYCLE
// /// Do the prioritization of the interrupts here ////////////
// for (l=0; l<NUM_LEVELS/2 ; l++) begin : TOP_LEVEL
// for (m=0; m<=(TOTAL_INT)/(2**(l+1)) ; m++) begin : COMPARE
// if ( m == (TOTAL_INT)/(2**(l+1))) begin
// assign level_intpend_w_prior_en[l+1][m+1] = '0 ;
// assign level_intpend_id[l+1][m+1] = '0 ;
// end
// cmp_and_mux #(.ID_BITS(ID_BITS),
// .INTPRIORITY_BITS(INTPRIORITY_BITS)) cmp_l1 (
// .a_id(level_intpend_id[l][2*m]),
// .a_priority(level_intpend_w_prior_en[l][2*m]),
// .b_id(level_intpend_id[l][2*m+1]),
// .b_priority(level_intpend_w_prior_en[l][2*m+1]),
// .out_id(level_intpend_id[l+1][m]),
// .out_priority(level_intpend_w_prior_en[l+1][m])) ;
//
// end
// end
//
// for (i=0; i<=TOTAL_INT/2**(NUM_LEVELS/2) ; i++) begin : MIDDLE_FLOPS
// rvdff #(INTPRIORITY_BITS) level2_intpend_prior_reg (.*, .din (level_intpend_w_prior_en[NUM_LEVELS/2][i]), .dout(l2_intpend_w_prior_en_ff[i]), .clk(free_clk));
// rvdff #(ID_BITS) level2_intpend_id_reg (.*, .din (level_intpend_id[NUM_LEVELS/2][i]), .dout(l2_intpend_id_ff[i]), .clk(free_clk));
// end
//
// for (j=NUM_LEVELS/2; j<NUM_LEVELS ; j++) begin : BOT_LEVELS
// for (k=0; k<=(TOTAL_INT)/(2**(j+1)) ; k++) begin : COMPARE
// if ( k == (TOTAL_INT)/(2**(j+1))) begin
// assign levelx_intpend_w_prior_en[j+1][k+1] = '0 ;
// assign levelx_intpend_id[j+1][k+1] = '0 ;
// end
// cmp_and_mux #(.ID_BITS(ID_BITS),
// .INTPRIORITY_BITS(INTPRIORITY_BITS))
// cmp_l1 (
// .a_id(levelx_intpend_id[j][2*k]),
// .a_priority(levelx_intpend_w_prior_en[j][2*k]),
// .b_id(levelx_intpend_id[j][2*k+1]),
// .b_priority(levelx_intpend_w_prior_en[j][2*k+1]),
// .out_id(levelx_intpend_id[j+1][k]),
// .out_priority(levelx_intpend_w_prior_en[j+1][k])) ;
// end
// end
// assign claimid_in[ID_BITS-1:0] = levelx_intpend_id[NUM_LEVELS][0] ; // This is the last level output
// assign selected_int_priority[INTPRIORITY_BITS-1:0] = levelx_intpend_w_prior_en[NUM_LEVELS][0] ;
//
// `else
//
// /// Do the prioritization of the interrupts here ////////////
// // genvar l, m , j, k; already declared outside ifdef
// for (l=0; l<NUM_LEVELS ; l++) begin : LEVEL
// for (m=0; m<=(TOTAL_INT)/(2**(l+1)) ; m++) begin : COMPARE
// if ( m == (TOTAL_INT)/(2**(l+1))) begin
// assign level_intpend_w_prior_en[l+1][m+1] = '0 ;
// assign level_intpend_id[l+1][m+1] = '0 ;
// end
// cmp_and_mux #(.ID_BITS(ID_BITS),
// .INTPRIORITY_BITS(INTPRIORITY_BITS)) cmp_l1 (
// .a_id(level_intpend_id[l][2*m]),
// .a_priority(level_intpend_w_prior_en[l][2*m]),
// .b_id(level_intpend_id[l][2*m+1]),
// .b_priority(level_intpend_w_prior_en[l][2*m+1]),
// .out_id(level_intpend_id[l+1][m]),
// .out_priority(level_intpend_w_prior_en[l+1][m])) ;
//
// end
// end
// assign claimid_in[ID_BITS-1:0] = level_intpend_id[NUM_LEVELS][0] ; // This is the last level output
// assign selected_int_priority[INTPRIORITY_BITS-1:0] = level_intpend_w_prior_en[NUM_LEVELS][0] ;
//
// `endif
// `endif
///////////////////////////////////////////////////////////////////////
// Config Reg`
// Config Reg`
///////////////////////////////////////////////////////////////////////
assign config_reg_we = addr_config_pic_match & picm_wren_ff;
assign config_reg_re = addr_config_pic_match & picm_rden_ff;
assign config_reg_we = addr_config_pic_match & picm_wren_ff;
assign config_reg_re = addr_config_pic_match & picm_rden_ff;
assign config_reg_in = picm_wr_data_ff[0] ; //
assign config_reg_in = picm_wr_data_ff[0] ; //
rvdffs #(1) config_reg_ff (.*, .clk(free_clk), .en(config_reg_we), .din (config_reg_in), .dout(config_reg));
assign intpriord = config_reg ;
///////////////////////////////////////////////////////////////////////
// Thresh-hold Reg`
// Thresh-hold Reg`
///////////////////////////////////////////////////////////////////////
//assign prithresh_reg_write = addr_prithresh_match & picm_wren_ff;
//assign prithresh_reg_read = addr_prithresh_match & picm_rden_ff;
//assign prithresh_reg_write = addr_prithresh_match & picm_wren_ff;
//assign prithresh_reg_read = addr_prithresh_match & picm_rden_ff;
//
//assign prithresh_reg_in[INTPRIORITY_BITS-1:0] = picm_wr_data_ff[INTPRIORITY_BITS-1:0] ; // Thresh-hold priority.
//assign prithresh_reg_in[INTPRIORITY_BITS-1:0] = picm_wr_data_ff[INTPRIORITY_BITS-1:0] ; // Thresh-hold priority.
//rvdffs #(INTPRIORITY_BITS) prithresh_reg_ff (.*, .en(prithresh_reg_write), .din (prithresh_reg_in[INTPRIORITY_BITS-1:0]), .dout(prithresh_reg[INTPRIORITY_BITS-1:0]));
//
@ -372,10 +360,10 @@ assign intpriord = config_reg ;
///////////////////////////////////////////////////////////
/// ClaimId Reg and Corresponding PL
///////////////////////////////////////////////////////////
// logic atleast_one_int_enabled_in,atleast_one_int_enabled ;
// logic mexintpend_unq ;
// logic mhwakeup_unq ;
//
// logic atleast_one_int_enabled_in,atleast_one_int_enabled ;
// logic mexintpend_unq ;
// logic mhwakeup_unq ;
//
assign pl_in_q[INTPRIORITY_BITS-1:0] = intpriord ? ~pl_in : pl_in ;
rvdff #(ID_BITS) claimid_ff (.*, .din (claimid_in[ID_BITS-1:00]), .dout(claimid[ID_BITS-1:00]), .clk(free_clk));
rvdff #(INTPRIORITY_BITS) pl_ff (.*, .din (pl_in_q[INTPRIORITY_BITS-1:0]), .dout(pl[INTPRIORITY_BITS-1:0]), .clk(free_clk));
@ -383,7 +371,7 @@ rvdff #(INTPRIORITY_BITS) pl_ff (.*, .din (pl_in_q[INTPRIORITY_BITS-1:0]),
logic [INTPRIORITY_BITS-1:0] meipt_inv , meicurpl_inv ;
assign meipt_inv[INTPRIORITY_BITS-1:0] = intpriord ? ~meipt[INTPRIORITY_BITS-1:0] : meipt[INTPRIORITY_BITS-1:0] ;
assign meicurpl_inv[INTPRIORITY_BITS-1:0] = intpriord ? ~meicurpl[INTPRIORITY_BITS-1:0] : meicurpl[INTPRIORITY_BITS-1:0] ;
assign mexintpend_in = (( selected_int_priority[INTPRIORITY_BITS-1:0] > meipt_inv[INTPRIORITY_BITS-1:0]) &
assign mexintpend_in = (( selected_int_priority[INTPRIORITY_BITS-1:0] > meipt_inv[INTPRIORITY_BITS-1:0]) &
( selected_int_priority[INTPRIORITY_BITS-1:0] > meicurpl_inv[INTPRIORITY_BITS-1:0]) );
rvdff #(1) mexintpend_ff (.*, .clk(free_clk), .din (mexintpend_in), .dout(mexintpend));
@ -394,18 +382,18 @@ rvdff #(1) wake_up_ff (.*, .clk(free_clk), .din (mhwakeup_in), .dout(mhwakeup))
// assign atleast_one_int_enabled_in = |intenable_reg[TOTAL_INT-1:0] ;
// rvdff #(1) one_int_en_ff (.*, .din (atleast_one_int_enabled_in), .dout(atleast_one_int_enabled));
//
//
// assign mexintpend = mexintpend_unq & atleast_one_int_enabled ;
// assign mhwakeup = mhwakeup_unq & atleast_one_int_enabled ;
//////////////////////////////////////////////////////////////////////////
// Reads of register.
// Reads of register.
// 1- intpending
//////////////////////////////////////////////////////////////////////////
assign intpend_reg_read = addr_intpend_base_match & picm_rden_ff ;
assign intpend_reg_read = addr_intpend_base_match & picm_rden_ff ;
assign intpriority_reg_read = addr_intpriority_base_match & picm_rden_ff;
assign intenable_reg_read = addr_intenable_base_match & picm_rden_ff;
assign gw_config_reg_read = addr_config_gw_base_match & picm_rden_ff;
@ -416,14 +404,14 @@ assign intpend_reg_extended[INTPEND_SIZE-1:0] = {{INTPEND_SIZE-TOTAL_INT{1'b0}}
assign intpend_rd_part_out[i] = (({32{intpend_reg_read & picm_addr_ff[5:2] == i}}) & intpend_reg_extended[((32*i)+31):(32*i)]) ;
end
always_comb begin : INTPEND_RD
always_comb begin : INTPEND_RD
intpend_rd_out = '0 ;
for (int i=0; i<INT_GRPS; i++) begin
intpend_rd_out |= intpend_rd_part_out[i] ;
end
end
always_comb begin : INTEN_RD
always_comb begin : INTEN_RD
intenable_rd_out = '0 ;
intpriority_rd_out = '0 ;
gw_config_rd_out = '0 ;
@ -439,28 +427,28 @@ assign intpend_reg_extended[INTPEND_SIZE-1:0] = {{INTPEND_SIZE-TOTAL_INT{1'b0}}
end
end
end
assign picm_rd_data_in[31:0] = ({32{intpend_reg_read }} & intpend_rd_out ) |
({32{intpriority_reg_read }} & {{32-INTPRIORITY_BITS{1'b0}}, intpriority_rd_out } ) |
assign picm_rd_data_in[31:0] = ({32{intpend_reg_read }} & intpend_rd_out ) |
({32{intpriority_reg_read }} & {{32-INTPRIORITY_BITS{1'b0}}, intpriority_rd_out } ) |
({32{intenable_reg_read }} & {31'b0 , intenable_rd_out } ) |
({32{gw_config_reg_read }} & {30'b0 , gw_config_rd_out } ) |
({32{config_reg_re }} & {31'b0 , config_reg } ) |
({32{config_reg_re }} & {31'b0 , config_reg } ) |
({32{picm_mken_ff & mask[3]}} & {30'b0 , 2'b11 } ) |
({32{picm_mken_ff & mask[2]}} & {31'b0 , 1'b1 } ) |
({32{picm_mken_ff & mask[1]}} & {28'b0 , 4'b1111 } ) |
({32{picm_mken_ff & mask[0]}} & 32'b0 ) ;
({32{picm_mken_ff & mask[0]}} & 32'b0 ) ;
assign picm_rd_data[31:0] = picm_rd_data_in[31:0] ;
logic [14:0] address;
assign address[14:0] = picm_addr_ff[14:0];
`include "pic_map_auto.h"
endmodule
endmodule
module cmp_and_mux #(parameter ID_BITS=8,
@ -468,26 +456,26 @@ module cmp_and_mux #(parameter ID_BITS=8,
(
input logic [ID_BITS-1:0] a_id,
input logic [INTPRIORITY_BITS-1:0] a_priority,
input logic [ID_BITS-1:0] b_id,
input logic [INTPRIORITY_BITS-1:0] b_priority,
output logic [ID_BITS-1:0] out_id,
output logic [INTPRIORITY_BITS-1:0] out_priority
output logic [INTPRIORITY_BITS-1:0] out_priority
);
logic a_is_lt_b ;
assign a_is_lt_b = ( a_priority[INTPRIORITY_BITS-1:0] < b_priority[INTPRIORITY_BITS-1:0] ) ;
// assign a_is_eq_b = ( a_priority[INTPRIORITY_BITS-1:0] == b_priority[INTPRIORITY_BITS-1:0]) ;
assign out_id[ID_BITS-1:0] = a_is_lt_b ? b_id[ID_BITS-1:0] :
assign out_id[ID_BITS-1:0] = a_is_lt_b ? b_id[ID_BITS-1:0] :
a_id[ID_BITS-1:0] ;
assign out_priority[INTPRIORITY_BITS-1:0] = a_is_lt_b ? b_priority[INTPRIORITY_BITS-1:0] :
assign out_priority[INTPRIORITY_BITS-1:0] = a_is_lt_b ? b_priority[INTPRIORITY_BITS-1:0] :
a_priority[INTPRIORITY_BITS-1:0] ;
endmodule // cmp_and_mux
module configurable_gw (
input logic clk,
@ -497,10 +485,10 @@ module configurable_gw (
input logic meigwctrl_polarity ,
input logic meigwctrl_type ,
input logic meigwclr ,
output logic extintsrc_req_config
output logic extintsrc_req_config
);
logic gw_int_pending_in , gw_int_pending ;

File diff suppressed because it is too large Load Diff

View File

@ -1,12 +1,12 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright 2019 Western Digital Corporation or its affiliates.
//
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//
// http://www.apache.org/licenses/LICENSE-2.0
//
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -17,21 +17,22 @@
// $Id$
//
// Function: Top wrapper file with swerv/mem instantiated inside
// Comments:
// Comments:
//
//********************************************************************************
`include "build.h"
//`include "def.sv"
module swerv_wrapper
module swerv_wrapper
import swerv_types::*;
(
input logic clk,
input logic rst_l,
input logic dbg_rst_l,
input logic [31:1] rst_vec,
input logic nmi_int,
input logic [31:1] nmi_vec,
input logic [31:1] nmi_vec,
input logic [31:1] jtag_id,
output logic [63:0] trace_rv_i_insn_ip,
output logic [63:0] trace_rv_i_address_ip,
@ -58,19 +59,19 @@ module swerv_wrapper
output logic [3:0] lsu_axi_awcache,
output logic [2:0] lsu_axi_awprot,
output logic [3:0] lsu_axi_awqos,
output logic lsu_axi_wvalid,
output logic lsu_axi_wvalid,
input logic lsu_axi_wready,
output logic [63:0] lsu_axi_wdata,
output logic [7:0] lsu_axi_wstrb,
output logic lsu_axi_wlast,
input logic lsu_axi_bvalid,
output logic lsu_axi_bready,
input logic [1:0] lsu_axi_bresp,
input logic [`RV_LSU_BUS_TAG-1:0] lsu_axi_bid,
// AXI Read Channels
// AXI Read Channels
output logic lsu_axi_arvalid,
input logic lsu_axi_arready,
output logic [`RV_LSU_BUS_TAG-1:0] lsu_axi_arid,
@ -83,14 +84,14 @@ module swerv_wrapper
output logic [3:0] lsu_axi_arcache,
output logic [2:0] lsu_axi_arprot,
output logic [3:0] lsu_axi_arqos,
input logic lsu_axi_rvalid,
output logic lsu_axi_rready,
input logic [`RV_LSU_BUS_TAG-1:0] lsu_axi_rid,
input logic [63:0] lsu_axi_rdata,
input logic [1:0] lsu_axi_rresp,
input logic lsu_axi_rlast,
//-------------------------- IFU AXI signals--------------------------
// AXI Write Channels
output logic ifu_axi_awvalid,
@ -105,19 +106,19 @@ module swerv_wrapper
output logic [3:0] ifu_axi_awcache,
output logic [2:0] ifu_axi_awprot,
output logic [3:0] ifu_axi_awqos,
output logic ifu_axi_wvalid,
output logic ifu_axi_wvalid,
input logic ifu_axi_wready,
output logic [63:0] ifu_axi_wdata,
output logic [7:0] ifu_axi_wstrb,
output logic ifu_axi_wlast,
input logic ifu_axi_bvalid,
output logic ifu_axi_bready,
input logic [1:0] ifu_axi_bresp,
input logic [`RV_IFU_BUS_TAG-1:0] ifu_axi_bid,
// AXI Read Channels
// AXI Read Channels
output logic ifu_axi_arvalid,
input logic ifu_axi_arready,
output logic [`RV_IFU_BUS_TAG-1:0] ifu_axi_arid,
@ -130,7 +131,7 @@ module swerv_wrapper
output logic [3:0] ifu_axi_arcache,
output logic [2:0] ifu_axi_arprot,
output logic [3:0] ifu_axi_arqos,
input logic ifu_axi_rvalid,
output logic ifu_axi_rready,
input logic [`RV_IFU_BUS_TAG-1:0] ifu_axi_rid,
@ -152,19 +153,19 @@ module swerv_wrapper
output logic [3:0] sb_axi_awcache,
output logic [2:0] sb_axi_awprot,
output logic [3:0] sb_axi_awqos,
output logic sb_axi_wvalid,
output logic sb_axi_wvalid,
input logic sb_axi_wready,
output logic [63:0] sb_axi_wdata,
output logic [7:0] sb_axi_wstrb,
output logic sb_axi_wlast,
input logic sb_axi_bvalid,
output logic sb_axi_bready,
input logic [1:0] sb_axi_bresp,
input logic [`RV_SB_BUS_TAG-1:0] sb_axi_bid,
// AXI Read Channels
// AXI Read Channels
output logic sb_axi_arvalid,
input logic sb_axi_arready,
output logic [`RV_SB_BUS_TAG-1:0] sb_axi_arid,
@ -177,7 +178,7 @@ module swerv_wrapper
output logic [3:0] sb_axi_arcache,
output logic [2:0] sb_axi_arprot,
output logic [3:0] sb_axi_arqos,
input logic sb_axi_rvalid,
output logic sb_axi_rready,
input logic [`RV_SB_BUS_TAG-1:0] sb_axi_rid,
@ -197,12 +198,12 @@ module swerv_wrapper
input logic [1:0] dma_axi_awburst,
input logic dma_axi_wvalid,
input logic dma_axi_wvalid,
output logic dma_axi_wready,
input logic [63:0] dma_axi_wdata,
input logic [7:0] dma_axi_wstrb,
input logic dma_axi_wlast,
output logic dma_axi_bvalid,
input logic dma_axi_bready,
output logic [1:0] dma_axi_bresp,
@ -212,7 +213,7 @@ module swerv_wrapper
input logic dma_axi_arvalid,
output logic dma_axi_arready,
input logic [`RV_DMA_BUS_TAG-1:0] dma_axi_arid,
input logic [31:0] dma_axi_araddr,
input logic [31:0] dma_axi_araddr,
input logic [2:0] dma_axi_arsize,
input logic [2:0] dma_axi_arprot,
input logic [7:0] dma_axi_arlen,
@ -223,8 +224,8 @@ module swerv_wrapper
output logic [`RV_DMA_BUS_TAG-1:0] dma_axi_rid,
output logic [63:0] dma_axi_rdata,
output logic [1:0] dma_axi_rresp,
output logic dma_axi_rlast,
output logic dma_axi_rlast,
`endif
`ifdef RV_BUILD_AHB_LITE
@ -263,11 +264,11 @@ module swerv_wrapper
output logic [1:0] sb_htrans,
output logic sb_hwrite,
output logic [63:0] sb_hwdata,
input logic [63:0] sb_hrdata,
input logic sb_hready,
input logic sb_hresp,
// DMA Slave
input logic [31:0] dma_haddr,
input logic [2:0] dma_hburst,
@ -278,8 +279,8 @@ module swerv_wrapper
input logic dma_hwrite,
input logic [63:0] dma_hwdata,
input logic dma_hsel,
input logic dma_hreadyin,
input logic dma_hreadyin,
output logic [63:0] dma_hrdata,
output logic dma_hreadyout,
output logic dma_hresp,
@ -291,9 +292,9 @@ module swerv_wrapper
input logic lsu_bus_clk_en, // Clock ratio b/w cpu core clk & AHB master interface
input logic ifu_bus_clk_en, // Clock ratio b/w cpu core clk & AHB master interface
input logic dbg_bus_clk_en, // Clock ratio b/w cpu core clk & AHB master interface
input logic dma_bus_clk_en, // Clock ratio b/w cpu core clk & AHB slave interface
input logic dma_bus_clk_en, // Clock ratio b/w cpu core clk & AHB slave interface
// input logic ext_int,
input logic timer_int,
input logic [`RV_PIC_TOTAL_INT:1] extintsrc_req,
@ -303,9 +304,9 @@ module swerv_wrapper
output logic [1:0] dec_tlu_perfcnt2,
output logic [1:0] dec_tlu_perfcnt3,
// ports added by the soc team
// ports added by the soc team
input logic jtag_tck, // JTAG clk
input logic jtag_tms, // JTAG TMS
input logic jtag_tms, // JTAG TMS
input logic jtag_tdi, // JTAG tdi
input logic jtag_trst_n, // JTAG Reset
output logic jtag_tdo, // JTAG TDO
@ -324,10 +325,10 @@ module swerv_wrapper
input logic i_cpu_run_req, // Async restart req to CPU
output logic o_cpu_run_ack, // Core response to run req
input logic scan_mode, // To enable scan mode
input logic mbist_mode // to enable mbist
input logic mbist_mode // to enable mbist
);
`include "global.h"
`include "global.h"
// DCCM ports
logic dccm_wren;
@ -336,7 +337,7 @@ module swerv_wrapper
logic [DCCM_BITS-1:0] dccm_rd_addr_lo;
logic [DCCM_BITS-1:0] dccm_rd_addr_hi;
logic [DCCM_FDATA_WIDTH-1:0] dccm_wr_data;
logic [DCCM_FDATA_WIDTH-1:0] dccm_rd_data_lo;
logic [DCCM_FDATA_WIDTH-1:0] dccm_rd_data_hi;
@ -345,40 +346,40 @@ module swerv_wrapper
// PIC ports
// Icache & Itag ports
logic [31:3] ic_rw_addr;
logic [31:3] ic_rw_addr;
logic [3:0] ic_wr_en ; // Which way to write
logic ic_rd_en ;
logic [3:0] ic_tag_valid; // Valid from the I$ tag valid outside (in flops).
logic [3:0] ic_tag_valid; // Valid from the I$ tag valid outside (in flops).
logic [3:0] ic_rd_hit; // ic_rd_hit[3:0]
logic ic_tag_perr; // Ic tag parity error
logic [15:2] ic_debug_addr; // Read/Write addresss to the Icache.
logic [15:2] ic_debug_addr; // Read/Write addresss to the Icache.
logic ic_debug_rd_en; // Icache debug rd
logic ic_debug_wr_en; // Icache debug wr
logic ic_debug_tag_array; // Debug tag array
logic [3:0] ic_debug_way; // Debug way. Rd or Wr.
`ifdef RV_ICACHE_ECC
logic [24:0] ictag_debug_rd_data;// Debug icache tag.
logic [24:0] ictag_debug_rd_data;// Debug icache tag.
logic [83:0] ic_wr_data; // ic_wr_data[135:0]
logic [167:0] ic_rd_data; // ic_rd_data[135:0]
logic [41:0] ic_debug_wr_data; // Debug wr cache.
logic [41:0] ic_debug_wr_data; // Debug wr cache.
`else
logic [20:0] ictag_debug_rd_data;// Debug icache tag.
logic [20:0] ictag_debug_rd_data;// Debug icache tag.
logic [67:0] ic_wr_data; // ic_wr_data[135:0]
logic [135:0] ic_rd_data; // ic_rd_data[135:0]
logic [33:0] ic_debug_wr_data; // Debug wr cache.
logic [33:0] ic_debug_wr_data; // Debug wr cache.
`endif
logic [127:0] ic_premux_data;
logic ic_sel_premux_data;
`ifdef RV_ICCM_ENABLE
`ifdef RV_ICCM_ENABLE
// ICCM ports
logic [`RV_ICCM_BITS-1:2] iccm_rw_addr;
logic [`RV_ICCM_BITS-1:2] iccm_rw_addr;
logic iccm_wren;
logic iccm_rden;
logic [2:0] iccm_wr_size;
@ -386,13 +387,13 @@ module swerv_wrapper
logic [155:0] iccm_rd_data;
`endif
logic core_rst_l; // Core reset including rst_l and dbg_rst_l
logic core_rst_l; // Core reset including rst_l and dbg_rst_l
logic jtag_tdoEn;
logic dccm_clk_override;
logic icm_clk_override;
logic dec_tlu_core_ecc_disable;
logic dmi_reg_en;
logic [6:0] dmi_reg_addr;
logic dmi_reg_wr_en;
@ -404,7 +405,7 @@ module swerv_wrapper
swerv swerv (
.*
);
// Instantiate the mem
mem mem (
.rst_l(core_rst_l),
@ -424,7 +425,7 @@ module swerv_wrapper
.tdoEnable (), // Test Data Output enable
// Processor Signals
.core_rst_n (core_rst_l), // Core reset, active low
.core_rst_n (dbg_rst_l), // Primary reset, active low
.core_clk (clk), // Core clock
.jtag_id (jtag_id), // 32 bit JTAG ID
.rd_data (dmi_reg_rdata), // 32 bit Read data from Processor
@ -436,4 +437,4 @@ module swerv_wrapper
);
endmodule

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
## Release Notes
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

@ -1,166 +1,195 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright 2019 Western Digital Corporation or its affiliates.
//
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//
// http://www.apache.org/licenses/LICENSE-2.0
//
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
`ifdef RV_BUILD_AHB_LITE
module ahb_sif (
input logic [63:0] HWDATA,
input logic HCLK,
input logic HSEL,
input logic [3:0] HPROT,
input logic HWRITE,
input logic [1:0] HTRANS,
input logic [2:0] HSIZE,
input logic HREADY,
input logic HRESETn,
input logic [31:0] HADDR,
input logic [2:0] HBURST,
output logic HREADYOUT,
output logic HRESP,
output logic [63:0] HRDATA
input logic [63:0] HWDATA,
input logic HCLK,
input logic HSEL,
input logic [3:0] HPROT,
input logic HWRITE,
input logic [1:0] HTRANS,
input logic [2:0] HSIZE,
input logic HREADY,
input logic HRESETn,
input logic [31:0] HADDR,
input logic [2:0] HBURST,
output logic HREADYOUT,
output logic HRESP,
output logic [63:0] HRDATA
);
localparam MEM_SIZE_DW = 8192;
localparam MAILBOX_ADDR = 32'hD0580000;
parameter MEM_SIZE_DW = 8192;
parameter MAILBOX_ADDR = 32'hD0580000;
localparam MEM_SIZE = MEM_SIZE_DW*8;
logic Last_HSEL;
logic NextLast_HSEL;
logic Last_HWRITE;
logic [1:0] Last_HTRANS;
logic [1:0] NextLast_HTRANS;
logic Write;
logic [31:0] Last_HADDR;
logic [63:0] Next_HRDATA;
logic [63:0] WriteReadData;
logic [63:0] WriteMask;
bit [7:0] mem [0:MEM_SIZE_DW-1];
logic [7:0] strb_lat;
bit [7:0] mem [0:MEM_SIZE-1];
//bit [7:0] mem [int];
//int kuku[int];
// Wires
wire [63:0] Next_WriteMask = HSIZE == 3'b000 ? (64'hff << {HADDR[2:0], 3'b000}) : (HSIZE == 3'b001 ? (64'hffff << {HADDR[2], 4'h0}) : (HSIZE == 3'b010 ? (64'hffff_ffff << {HADDR[3],5'h0}) : 64'hffff_ffff_ffff_ffff));
wire [63:0] WriteData = HWDATA;
wire [7:0] strb = HSIZE == 3'b000 ? 8'h1 << HADDR[2:0] :
HSIZE == 3'b001 ? 8'h3 << {HADDR[2:1],1'b0} :
HSIZE == 3'b010 ? 8'hf << {HADDR[2],2'b0} : 8'hff;
wire [63:0] MaskedWriteData = HWDATA & WriteMask;
wire [63:0] MaskedWriteReadData = WriteReadData & ~WriteMask;
wire [63:0] WriteData = (MaskedWriteData | MaskedWriteReadData );
wire Write = &{Last_HSEL, Last_HWRITE, Last_HTRANS[1]};
wire Read = &{ HSEL, ~HWRITE, HTRANS[1]};
wire[31:0] addr = HADDR & (MEM_SIZE-1);
wire[31:0] laddr = Last_HADDR & (MEM_SIZE-1);
wire mailbox_write = &{Write, Last_HADDR==MAILBOX_ADDR, HRESETn==1};
wire Next_HWRITE = |{HTRANS} ? HWRITE : Last_HWRITE;
wire [63:0] mem_dout = {mem[{Last_HADDR[12:3],3'b0}+7],mem[{Last_HADDR[12:3],3'b0}+6],mem[{Last_HADDR[12:3],3'b0}+5],mem[{Last_HADDR[12:3],3'b0}+4],mem[{Last_HADDR[12:3],3'b0}+3],mem[{Last_HADDR[12:3],3'b0}+2],mem[{Last_HADDR[12:3],3'b0}+1],mem[{Last_HADDR[12:3],3'b0}]};
wire mailbox_write = Write && Last_HADDR==MAILBOX_ADDR;
wire [63:0] mem_dout = {mem[{addr[31:3],3'd7}],
mem[{addr[31:3],3'd6}],
mem[{addr[31:3],3'd5}],
mem[{addr[31:3],3'd4}],
mem[{addr[31:3],3'd3}],
mem[{addr[31:3],3'd2}],
mem[{addr[31:3],3'd1}],
mem[{addr[31:3],3'd0}]};
always @ (posedge HCLK or negedge HRESETn) begin
if (Write && Last_HADDR == 32'h0) begin
mem[{Last_HADDR[12:3],3'b0}+7] <= #1 { WriteData[63:56] };
mem[{Last_HADDR[12:3],3'b0}+6] <= #1 { WriteData[55:48] };
mem[{Last_HADDR[12:3],3'b0}+5] <= #1 { WriteData[47:40] };
mem[{Last_HADDR[12:3],3'b0}+4] <= #1 { WriteData[39:32] };
mem[{Last_HADDR[12:3],3'b0}+3] <= #1 { WriteData[31:24] };
mem[{Last_HADDR[12:3],3'b0}+2] <= #1 { WriteData[23:16] };
mem[{Last_HADDR[12:3],3'b0}+1] <= #1 { WriteData[15:08] };
mem[{Last_HADDR[12:3],3'b0}+0] <= #1 { WriteData[07:00] };
always @ (negedge HCLK ) begin
if (Write) begin
if(strb_lat[7]) mem[{laddr[31:3],3'd7}] = HWDATA[63:56];
if(strb_lat[6]) mem[{laddr[31:3],3'd6}] = HWDATA[55:48];
if(strb_lat[5]) mem[{laddr[31:3],3'd5}] = HWDATA[47:40];
if(strb_lat[4]) mem[{laddr[31:3],3'd4}] = HWDATA[39:32];
if(strb_lat[3]) mem[{laddr[31:3],3'd3}] = HWDATA[31:24];
if(strb_lat[2]) mem[{laddr[31:3],3'd2}] = HWDATA[23:16];
if(strb_lat[1]) mem[{laddr[31:3],3'd1}] = HWDATA[15:08];
if(strb_lat[0]) mem[{laddr[31:3],3'd0}] = HWDATA[07:00];
end
end
assign HREADYOUT = 1;
assign HRESP = 0;
always @(posedge HCLK or negedge HRESETn) begin
if(~HRESETn) begin
HREADYOUT <= #1 1'b0 ;
HRESP <= #1 1'b0;
Last_HADDR <= 32'b0;
Write <= 1'b0;
HRDATA <= '0;
end else begin
HREADYOUT <= #1 |HTRANS;
HRESP <= #1 1'b0;
WriteMask <= #1 Next_WriteMask;
end
end
`ifdef VERILATOR
always @(posedge HCLK or negedge HRESETn) begin
`else
always @(negedge HCLK or negedge HRESETn) begin
`endif
if(~HRESETn) begin
Last_HADDR <= #1 32'b0;
end else begin
Last_HADDR <= #1 |{HTRANS} ? {HADDR[31:2], 2'b00} : Last_HADDR;
end
end
always @(posedge HCLK or negedge HRESETn) begin
if(~HRESETn) begin
Last_HWRITE <= #1 1'b0;
end else begin
Last_HWRITE <= #1 Next_HWRITE;
end
end
always @(posedge HCLK or negedge HRESETn) begin
if(~HRESETn) begin
Last_HTRANS <= #1 2'b0;
end else begin
Last_HTRANS <= #1 HTRANS;
end
end
always @(posedge HCLK or negedge HRESETn) begin
if(~HRESETn) begin
Last_HSEL <= #1 1'b0;
end else begin
Last_HSEL <= #1 HSEL;
end
end
`ifndef VERILATOR
always @(posedge HCLK or negedge HRESETn) begin
if(~HRESETn) begin
HRDATA <= #1 Next_HRDATA ;
end else begin
HRDATA <= #1 Next_HRDATA ;
end
end
always @* begin
Next_HRDATA = mem_dout;
end
`else
always @(posedge HCLK) begin
Next_HRDATA <= mem_dout;
end
assign HRDATA = mem_dout;
`endif
always @* begin
if(Last_HSEL) begin
WriteReadData[07:00] = mem[{Last_HADDR[12:3],3'b0}];
WriteReadData[15:08] = mem[{Last_HADDR[12:3],3'b0}+1];
WriteReadData[23:16] = mem[{Last_HADDR[12:3],3'b0}+2];
WriteReadData[31:24] = mem[{Last_HADDR[12:3],3'b0}+3];
WriteReadData[39:32] = mem[{Last_HADDR[12:3],3'b0}+4];
WriteReadData[47:40] = mem[{Last_HADDR[12:3],3'b0}+5];
WriteReadData[55:48] = mem[{Last_HADDR[12:3],3'b0}+6];
WriteReadData[63:56] = mem[{Last_HADDR[12:3],3'b0}+7];
Last_HADDR <= HADDR;
Write <= HWRITE & |HTRANS;
if(|HTRANS & ~HWRITE)
HRDATA <= mem_dout;
strb_lat <= strb;
end
end
endmodule
`endif
`ifdef RV_BUILD_AXI4
module axi_slv #(TAGW=1) (
input aclk,
input rst_l,
input arvalid,
output reg arready,
input [31:0] araddr,
input [TAGW-1:0] arid,
input [7:0] arlen,
input [1:0] arburst,
input [2:0] arsize,
output reg rvalid,
input rready,
output reg [63:0] rdata,
output reg [1:0] rresp,
output reg [TAGW-1:0] rid,
output rlast,
input awvalid,
output awready,
input [31:0] awaddr,
input [TAGW-1:0] awid,
input [7:0] awlen,
input [1:0] awburst,
input [2:0] awsize,
input [63:0] wdata,
input [7:0] wstrb,
input wvalid,
output wready,
output reg bvalid,
input bready,
output reg [1:0] bresp,
output reg [TAGW-1:0] bid
);
parameter MAILBOX_ADDR = 32'hD0580000;
parameter MEM_SIZE_DW = 8192;
bit [7:0] mem [0:MEM_SIZE_DW*8-1];
bit [63:0] memdata;
wire [31:0] waddr, raddr;
wire [63:0] WriteData;
wire mailbox_write;
assign raddr = araddr & (MEM_SIZE_DW*8-1);
assign waddr = awaddr & (MEM_SIZE_DW*8-1);
assign mailbox_write = awvalid && awaddr==MAILBOX_ADDR && rst_l;
assign WriteData = wdata;
always @ ( posedge aclk or negedge rst_l) begin
if(!rst_l) begin
rvalid <= 0;
bvalid <= 0;
end
else begin
bid <= awid;
rid <= arid;
rvalid <= arvalid;
bvalid <= awvalid;
rdata <= memdata;
end
end
always @ ( negedge aclk) begin
if(arvalid) memdata <= {mem[raddr+7], mem[raddr+6], mem[raddr+5], mem[raddr+4],
mem[raddr+3], mem[raddr+2], mem[raddr+1], mem[raddr]};
if(awvalid) begin
if(wstrb[7]) mem[waddr+7] = wdata[63:56];
if(wstrb[6]) mem[waddr+6] = wdata[55:48];
if(wstrb[5]) mem[waddr+5] = wdata[47:40];
if(wstrb[4]) mem[waddr+4] = wdata[39:32];
if(wstrb[3]) mem[waddr+3] = wdata[31:24];
if(wstrb[2]) mem[waddr+2] = wdata[23:16];
if(wstrb[1]) mem[waddr+1] = wdata[15:08];
if(wstrb[0]) mem[waddr+0] = wdata[07:00];
end
end
assign arready = 1'b1;
assign awready = 1'b1;
assign wready = 1'b1;
assign rresp = 2'b0;
assign bresp = 2'b0;
assign rlast = 1'b1;
endmodule
`endif

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
_start:
csrrw x2, 0xb02, x3
lui x5, 974848
ori x5, x5, 0
csrrw x2, 0x305, x5
lui x6, 382293
ori x6, x6, 1365
csrrw x1, 0x7c0, x6
// Clear minstret
csrw minstret, zero
csrw minstreth, zero
lui x5, 0
ori x5, x5, 0
csrrw x2, 0x7f8, x5
lui x5, 0
ori x5, x5, 0
csrrw x2, 0x7f9, x5
// Set up MTVEC - not expecting to use it though
li x1, RV_ICCM_SADR
csrw mtvec, x1
addi x0, x0, 0
lui x11, 853376
ori x9, x0, 'H'
sw x9, 0 (x11)
ori x9, x0, 'E'
sw x9, 0 (x11)
ori x9, x0, 'L'
sw x9, 0 (x11)
sw x9, 0 (x11)
ori x9, x0, 'O'
sw x9, 0 (x11)
ori x9, x0, ' '
sw x9, 0 (x11)
addi x9, x0, 'W'
sw x9, 0 (x11)
ori x9, x0, 'O'
sw x9, 0 (x11)
ori x9, x0, 'R'
sw x9, 0 (x11)
ori x9, x0, 'L'
sw x9, 0 (x11)
ori x9, x0, 'D'
sw x9, 0 (x11)
ori x9, x0, '!'
sw x9, 0 (x11)
ori x9, x0, 255
sw x9, 0 (x11)
addi x1,x0,0
// Enable Caches in MRAC
li x1, 0x5f555555
csrw 0x7c0, x1
finish:
addi x1,x1,1
jal x0, finish;
addi x0,x0,0
addi x0,x0,0
addi x0,x0,0
addi x0,x0,0
// Load string from hw_data
// and write to stdout address
li x3, STDOUT
la x4, hw_data
loop:
lb x5, 0(x4)
sb x5, 0(x3)
addi x4, x4, 1
bnez x5, loop
// Write 0xff to STDOUT for TB to terminate test.
_finish:
li x3, STDOUT
addi x5, x0, 0xff
sb x5, 0(x3)
beq x0, x0, _finish
.rept 100
nop
.endr
.global hw_data
.data
hw_data:
.ascii "----------------------------------\n"
.ascii "Hello World from SweRV EH1 @WDC !!\n"
.ascii "----------------------------------\n"
.byte 0

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
{
. = 0x1000;
.data . : { *(.*data) *(.rodata*) }
. = 0x0;
.text . : { *(.text) }
. = 0;
.text : { *(.text*) }
_end = .;
. = 0x10000;
.data : ALIGN(0x800) { *(.*data) *(.rodata*) STACK = ALIGN(16) + 0x8000; }
}

File diff suppressed because it is too large Load Diff

View File

@ -1,12 +1,12 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright 2019 Western Digital Corporation or its affiliates.
//
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//
// http://www.apache.org/licenses/LICENSE-2.0
//
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -22,62 +22,50 @@
#include "verilated_vcd_c.h"
// /*
vluint64_t main_time = 0;
double sc_time_stamp () {
double sc_time_stamp () {
return main_time;
}
// */
//int main(int argc, char* argv[]) {
int main(int argc, char** argv) {
std::cout << "\nVerilatorTB: Start of sim\n" << std::endl;
// Check for +dumpon and remove it from argv
bool dumpWaves = false;
int newArgc = 0;
for (int i = 0; i < argc; ++i)
if (strcmp(argv[i], "+dumpon") == 0)
dumpWaves = true;
else
argv[newArgc++] = argv[i];
argc = newArgc;
std::cout << "\nStart of sim\n" << std::endl;
Verilated::commandArgs(argc, argv);
Vtb_top* tb = new Vtb_top;
uint32_t clkCnt = 0;
// init trace dump
Verilated::traceEverOn(true);
VerilatedVcdC* tfp = new VerilatedVcdC;
tb->trace (tfp, 24);
tfp->open ("sim.vcd");
if (dumpWaves)
tfp->open ("sim.vcd");
// Simulate
for(auto i=0; i<200000; ++i){
clkCnt++;
if(i<10) {
tb->reset_l = 0;
} else {
tb->reset_l = 1;
}
for (auto clk=0; clk<2; clk++) {
tfp->dump (2*i+clk);
while(!Verilated::gotFinish()){
if (dumpWaves)
tfp->dump (main_time);
main_time += 5;
tb->core_clk = !tb->core_clk;
tb->eval();
}
if (tb->finished) {
tfp->close();
break;
}
}
for(auto i=0; i<100; ++i){
clkCnt++;
for (auto clk=0; clk<2; clk++) {
tfp->dump (2*i+clk);
tb->core_clk = !tb->core_clk;
tb->eval();
}
}
std::cout << "\nEnd of sim" << std::endl;
if (dumpWaves)
tfp->close();
std::cout << "\nVerilatorTB: End of sim" << std::endl;
exit(EXIT_SUCCESS);
}

View File

@ -22,8 +22,8 @@ my $XS_Version = '2.27';
# XS and PP common methods
my @PublicMethods = qw/
ascii latin1 utf8 pretty indent space_before space_after relaxed canonical allow_nonref
allow_blessed convert_blessed filter_json_object filter_json_single_key_object
ascii latin1 utf8 pretty indent space_before space_after relaxed canonical allow_nonref
allow_blessed convert_blessed filter_json_object filter_json_single_key_object
shrink max_depth max_size encode decode decode_prefix allow_unknown
/;
@ -48,7 +48,7 @@ my $_UNIV_CONV_BLESSED = 0;
my $_USSING_bpPP = 0;
# Check the environment variable to decide worker module.
# Check the environment variable to decide worker module.
unless ($JSON::Backend) {
$JSON::DEBUG and Carp::carp("Check used worker module...");
@ -609,35 +609,35 @@ JSON - JSON (JavaScript Object Notation) encoder/decoder
=head1 SYNOPSIS
use JSON; # imports encode_json, decode_json, to_json and from_json.
# simple and fast interfaces (expect/generate UTF-8)
$utf8_encoded_json_text = encode_json $perl_hash_or_arrayref;
$perl_hash_or_arrayref = decode_json $utf8_encoded_json_text;
# OO-interface
$json = JSON->new->allow_nonref;
$json_text = $json->encode( $perl_scalar );
$perl_scalar = $json->decode( $json_text );
$pretty_printed = $json->pretty->encode( $perl_scalar ); # pretty-printing
# If you want to use PP only support features, call with '-support_by_pp'
# When XS unsupported feature is enable, using PP (de|en)code instead of XS ones.
use JSON -support_by_pp;
# option-acceptable interfaces (expect/generate UNICODE by default)
$json_text = to_json( $perl_scalar, { ascii => 1, pretty => 1 } );
$perl_scalar = from_json( $json_text, { utf8 => 1 } );
# Between (en|de)code_json and (to|from)_json, if you want to write
# a code which communicates to an outer world (encoded in UTF-8),
# recommend to use (en|de)code_json.
=head1 VERSION
2.53
@ -866,7 +866,7 @@ with C<utf8> enable. And the decoded result will contain UNICODE characters.
my $json = JSON->new->utf8;
my $json_text = CGI->new->param( 'json_data' );
my $perl_scalar = $json->decode( $json_text );
# from file content
local $/;
open( my $fh, '<', 'json.data' );
@ -880,7 +880,7 @@ If an outer data is not encoded in UTF-8, firstly you should C<decode> it.
open( my $fh, '<', 'json.data' );
my $encoding = 'cp932';
my $unicode_json_text = decode( $encoding, <$fh> ); # UNICODE
# or you can write the below code.
#
# open( my $fh, "<:encoding($encoding)", 'json.data' );
@ -918,7 +918,7 @@ Note that the resulted text is a UNICODE string but no problem to print it.
# $perl_scalar contains $encoding encoded string values
$unicode_json_text = $json->utf8(0)->encode( $perl_scalar );
# or
# or
$unicode_json_text = to_json( $perl_scalar );
# $unicode_json_text consists of characters less than 0x100
print $unicode_json_text;
@ -954,7 +954,7 @@ be chained:
=head2 ascii
$json = $json->ascii([$enable])
$enabled = $json->get_ascii
If $enable is true (or missing), then the encode method will not generate characters outside
@ -974,7 +974,7 @@ See to L<JSON::PP/UNICODE HANDLING ON PERLS> if the backend is PP.
=head2 latin1
$json = $json->latin1([$enable])
$enabled = $json->get_latin1
If $enable is true (or missing), then the encode method will encode the resulting JSON
@ -989,7 +989,7 @@ unless required by the JSON syntax or other flags.
=head2 utf8
$json = $json->utf8([$enable])
$enabled = $json->get_utf8
If $enable is true (or missing), then the encode method will encode the JSON result
@ -1036,7 +1036,7 @@ space length.
=head2 indent
$json = $json->indent([$enable])
$enabled = $json->get_indent
If C<$enable> is true (or missing), then the C<encode> method will use a multiline
@ -1055,7 +1055,7 @@ With JSON::PP, you can also access C<indent_length> to change indent space lengt
=head2 space_before
$json = $json->space_before([$enable])
$enabled = $json->get_space_before
If C<$enable> is true (or missing), then the C<encode> method will add an extra
@ -1074,7 +1074,7 @@ Example, space_before enabled, space_after and indent disabled:
=head2 space_after
$json = $json->space_after([$enable])
$enabled = $json->get_space_after
If C<$enable> is true (or missing), then the C<encode> method will add an extra
@ -1095,7 +1095,7 @@ Example, space_before and indent disabled, space_after enabled:
=head2 relaxed
$json = $json->relaxed([$enable])
$enabled = $json->get_relaxed
If C<$enable> is true (or missing), then C<decode> will accept some
@ -1145,7 +1145,7 @@ character, after which more white-space and comments are allowed.
=head2 canonical
$json = $json->canonical([$enable])
$enabled = $json->get_canonical
If C<$enable> is true (or missing), then the C<encode> method will output JSON objects
@ -1165,7 +1165,7 @@ This setting has no effect when decoding JSON texts.
=head2 allow_nonref
$json = $json->allow_nonref([$enable])
$enabled = $json->get_allow_nonref
If C<$enable> is true (or missing), then the C<encode> method can convert a
@ -1184,7 +1184,7 @@ JSON object or array.
=head2 allow_unknown
$json = $json->allow_unknown ([$enable])
$enabled = $json->get_allow_unknown
If $enable is true (or missing), then "encode" will *not* throw an
@ -1203,7 +1203,7 @@ partner.
=head2 allow_blessed
$json = $json->allow_blessed([$enable])
$enabled = $json->get_allow_blessed
If C<$enable> is true (or missing), then the C<encode> method will not
@ -1220,7 +1220,7 @@ exception when it encounters a blessed object.
=head2 convert_blessed
$json = $json->convert_blessed([$enable])
$enabled = $json->get_convert_blessed
If C<$enable> is true (or missing), then C<encode>, upon encountering a
@ -1353,7 +1353,7 @@ into the corresponding C<< $WIDGET{<id>} >> object:
=head2 shrink
$json = $json->shrink([$enable])
$enabled = $json->get_shrink
With JSON::XS, this flag resizes strings generated by either
@ -1373,7 +1373,7 @@ See to L<JSON::XS/OBJECT-ORIENTED INTERFACE> and L<JSON::PP/METHODS>.
=head2 max_depth
$json = $json->max_depth([$maximum_nesting_depth])
$max_depth = $json->get_max_depth
Sets the maximum nesting level (default C<512>) accepted while encoding
@ -1402,7 +1402,7 @@ See L<JSON::XS/SECURITY CONSIDERATIONS> for more info on why this is useful.
=head2 max_size
$json = $json->max_size([$maximum_string_size])
$max_size = $json->get_max_size
Set the maximum length a JSON text may have (in bytes) where decoding is
@ -1503,9 +1503,9 @@ The following methods implement this incremental parser.
=head2 incr_parse
$json->incr_parse( [$string] ) # void context
$obj_or_undef = $json->incr_parse( [$string] ) # scalar context
@obj_or_empty = $json->incr_parse( [$string] ) # list context
This is the central parsing function. It can both append new text and
@ -1596,9 +1596,9 @@ If you use C<JSON> with additonal C<-support_by_pp>, some methods
are available even with JSON::XS. See to L<USE PP FEATURES EVEN THOUGH XS BACKEND>.
BEING { $ENV{PERL_JSON_BACKEND} = 'JSON::XS' }
use JSON -support_by_pp;
my $json = new JSON;
$json->allow_nonref->escape_slash->encode("/");
@ -1762,7 +1762,7 @@ represent most decimal fractions exactly, and when converting from and to
floating point, C<JSON> only guarantees precision up to but not including
the leats significant bit.
If the backend is JSON::PP and C<allow_bignum> is enable, the big integers
If the backend is JSON::PP and C<allow_bignum> is enable, the big integers
and the numeric can be optionally converted into L<Math::BigInt> and
L<Math::BigFloat> objects.
@ -1900,7 +1900,7 @@ error to pass those in.
=item Big Number
If the backend is JSON::PP and C<allow_bignum> is enable,
If the backend is JSON::PP and C<allow_bignum> is enable,
C<encode> converts C<Math::BigInt> objects and C<Math::BigFloat>
objects into JSON numbers.
@ -1935,13 +1935,13 @@ returned objects should not be modified.
To check the backend module, there are some methods - C<backend>, C<is_pp> and C<is_xs>.
JSON->backend; # 'JSON::XS' or 'JSON::PP'
JSON->backend->is_pp: # 0 or 1
JSON->backend->is_xs: # 1 or 0
$json->is_xs; # 1 or 0
$json->is_pp; # 0 or 1
@ -2164,7 +2164,7 @@ If you want to use with your own sort routine, check the C<sort_by> method.
(Only with JSON::PP, even if C<-support_by_pp> is used currently.)
$json->sort_by($sort_routine_ref)->encode($perl_scalar)
$json->sort_by(sub { $JSON::PP::a <=> $JSON::PP::b })->encode($perl_scalar)
Can't access C<$a> and C<$b> but C<$JSON::PP::a> and C<$JSON::PP::b>.
@ -2261,7 +2261,7 @@ The relese of this new version owes to the courtesy of Marc Lehmann.
Copyright 2005-2011 by Makamaka Hannyaharamitu
This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself.
it under the same terms as Perl itself.
=cut

View File

@ -1,12 +1,12 @@
# SPDX-License-Identifier: Apache-2.0
# Copyright 2019 Western Digital Corporation or its affiliates.
#
# Copyright 2020 Western Digital Corporation or its affiliates.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#
# http://www.apache.org/licenses/LICENSE-2.0
#
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -20,124 +20,157 @@ $(error env var RV_ROOT does not point to a valid dir! Exiting!)
endif
# Allow snapshot override
ifeq ($(strip $(snapshot)),)
snapshot = default
endif
target = default
snapshot = $(target)
# Allow tool override
SWERV_CONFIG = ${RV_ROOT}/configs/swerv.config
IRUN = irun
VCS = vcs
VERILATOR = verilator
VLOG = qverilog
RIVIERA = riviera
GCC_PREFIX = riscv64-unknown-elf
BUILD_DIR = snapshots/${snapshot}
TBDIR = ${RV_ROOT}/testbench
# Define test name
ifeq ($(strip $(ASM_TEST)),)
ASM_TEST = hello_world2
# Define default test name
TEST = hello_world
# Define default test directory
TEST_DIR = $(TBDIR)/asm
HEX_DIR = $(TBDIR)/hex
ifdef debug
DEBUG_PLUS = +dumpon
IRUN_DEBUG = -access +rc
IRUN_DEBUG_RUN = -input ${RV_ROOT}/testbench/input.tcl
VCS_DEBUG = -debug_access
RIVIERA_DEBUG = +access +r
endif
# Define test name
ifeq ($(strip $(ASM_TEST_DIR)),)
ASM_TEST_DIR = ${RV_ROOT}/testbench/asm
# provide specific link file
ifeq (,$(wildcard $(TEST_DIR)/$(TEST).ld))
LINK = $(TBDIR)/link.ld
else
LINK = $(TEST_DIR)/$(TEST).ld
endif
defines = ${RV_ROOT}/configs/snapshots/$(snapshot)/common_defines.vh ${RV_ROOT}/design/include/build.h ${RV_ROOT}/design/include/global.h ${RV_ROOT}/design/include/swerv_types.sv
includes = -I${RV_ROOT}/design/include -I${RV_ROOT}/design/lib -I${RV_ROOT}/design/dmi -I${RV_ROOT}/configs/snapshots/$(snapshot)
VPATH = $(TEST_DIR) $(BUILD_DIR) $(TBDIR)
TBFILES = $(TBDIR)/tb_top.sv $(TBDIR)/ahb_sif.sv
defines = $(BUILD_DIR)/common_defines.vh ${RV_ROOT}/design/include/swerv_types.sv
includes = -I${RV_ROOT}/design/include -I${RV_ROOT}/design/lib -I${BUILD_DIR}
# CFLAGS for verilator generated Makefiles. Without -std=c++11 it complains for `auto` variables
CFLAGS += "-std=c++11"
# Optimization for better performance; alternative is nothing for slower runtime (faster compiles)
# -O2 for faster runtime (slower compiles), or -O for balance.
VERILATOR_MAKE_FLAGS = OPT_FAST=""
VERILATOR_MAKE_FLAGS = OPT_FAST="-O2"
# Targets
all: clean verilator
clean:
rm -rf obj_dir *.hex build ${RV_ROOT}/configs/snapshots/$(snapshot) 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
echo '`undef ASSERT_ON' >> ${RV_ROOT}/configs/snapshots/$(snapshot)/common_defines.vh
$(VERILATOR) '-UASSERT_ON' --cc -CFLAGS ${CFLAGS} $(defines) $(includes) ${RV_ROOT}/configs/snapshots/$(snapshot)/common_defines.vh \
-f ${RV_ROOT}/testbench/flist.verilator --top-module swerv_wrapper
$(MAKE) -C obj_dir/ -f Vswerv_wrapper.mk $(VERILATOR_MAKE_FLAGS)
# If define files do not exist, then run swerv.config.
${BUILD_DIR}/defines.h :
BUILD_PATH=${BUILD_DIR} ${SWERV_CONFIG} -target=$(target) $(CONF_PARAMS)
vcs: ${RV_ROOT}/configs/snapshots/$(snapshot)/common_defines.vh
$(VCS) -full64 -assert svaext -sverilog +define+RV_OPENSOURCE +error+500 +incdir+${RV_ROOT}/design/lib +incdir+${RV_ROOT}/design/include \
${RV_ROOT}/configs/snapshots/$(snapshot)/common_defines.vh \
+incdir+${RV_ROOT}/design/dmi +incdir+${RV_ROOT}/configs/snapshots/$(snapshot) +libext+.v ${RV_ROOT}/configs/snapshots/$(snapshot)/common_defines.vh \
$(defines)-f ${RV_ROOT}/testbench/flist.vcs -l vcs.log
irun: ${RV_ROOT}/configs/snapshots/$(snapshot)/common_defines.vh
$(IRUN) -64bit -elaborate -ida -access +rw -q -sv -sysv -nowarn CUVIHR -nclibdirpath ${PWD} -nclibdirname swerv.build \
-incdir ${RV_ROOT}/design/lib -incdir ${RV_ROOT}/design/include -incdir ${RV_ROOT}/design/dmi -vlog_ext +.vh+.h\
$(defines) -incdir ${RV_ROOT}/configs/snapshots/$(snapshot) -f ${RV_ROOT}/testbench/flist.vcs -elaborate -snapshot default
${RV_ROOT}/configs/snapshots/$(snapshot)/common_defines.vh:
$(SWERV_CONFIG) -snapshot=$(snapshot)
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
verilator-build: ${TBFILES} ${BUILD_DIR}/defines.h test_tb_top.cpp
echo '`undef ASSERT_ON' >> ${BUILD_DIR}/common_defines.vh
$(VERILATOR) '-UASSERT_ON' --cc -CFLAGS ${CFLAGS} $(defines) $(includes) \
-Wno-UNOPTFLAT \
-I${RV_ROOT}/testbench \
-f ${RV_ROOT}/testbench/flist \
${TBFILES} \
--top-module tb_top -exe test_tb_top.cpp --trace --autoflush
cp ${RV_ROOT}/testbench/test_tb_top.cpp obj_dir/
$(MAKE) -C obj_dir/ -f Vtb_top.mk $(VERILATOR_MAKE_FLAGS)
./obj_dir/Vtb_top
touch verilator-build
irun-run: program.hex
snapshot=ahb_lite
$(SWERV_CONFIG) -snapshot=$(snapshot) -ahb_lite
$(IRUN) -64bit -ida -access +rw -q -sv -sysv -nowarn CUVIHR -nclibdirpath ${PWD} -nclibdirname swerv.build \
-incdir ${RV_ROOT}/design/lib -incdir ${RV_ROOT}/design/include -incdir ${RV_ROOT}/design/dmi -vlog_ext +.vh+.h\
$(defines) -top tb_top ${RV_ROOT}/testbench/tb_top.sv -I${RV_ROOT}/testbench ${RV_ROOT}/testbench/ahb_sif.sv\
-incdir ${RV_ROOT}/configs/snapshots/$(snapshot) -f ${RV_ROOT}/testbench/flist.vcs -snapshot default
vcs-build: ${TBFILES} ${BUILD_DIR}/defines.h
$(VCS) -full64 -assert svaext -sverilog +error+500 \
+incdir+${RV_ROOT}/design/lib \
+incdir+${RV_ROOT}/design/include \
+incdir+${BUILD_DIR} +libext+.v\
$(defines) -f ${RV_ROOT}/testbench/flist\
${TBFILES} \
-l vcs_compile.log
touch vcs-build
vcs-run: program.hex
snapshot=ahb_lite
$(SWERV_CONFIG) -snapshot=$(snapshot) -ahb_lite
cp ${RV_ROOT}/testbench/hex/*.hex .
$(VCS) -full64 -assert svaext -sverilog +define+RV_OPENSOURCE +error+500 +incdir+${RV_ROOT}/design/lib +incdir+${RV_ROOT}/design/include \
${RV_ROOT}/configs/snapshots/$(snapshot)/common_defines.vh \
+incdir+${RV_ROOT}/design/dmi +incdir+${RV_ROOT}/configs/snapshots/$(snapshot) +libext+.v \
$(defines) -f ${RV_ROOT}/testbench/flist.vcs ${RV_ROOT}/testbench/tb_top.sv -I${RV_ROOT}/testbench ${RV_ROOT}/testbench/ahb_sif.sv -l vcs.log
./simv
irun-build: ${TBFILES} ${BUILD_DIR}/defines.h
$(IRUN) -64bit -elaborate $(IRUN_DEBUG) -q -sv -sysv -nowarn CUVIHR -nclibdirpath . -nclibdirname swerv.build \
-incdir ${RV_ROOT}/design/lib -incdir ${RV_ROOT}/design/include -incdir ${BUILD_DIR} -vlog_ext +.vh+.h\
$(defines) -f ${RV_ROOT}/testbench/flist\
-top tb_top ${TBFILES} -I${RV_ROOT}/testbench \
-elaborate -snapshot $(snapshot)
touch irun-build
riviera-run: program.hex
snapshot=ahb_lite
$(SWERV_CONFIG) -snapshot=$(snapshot) -ahb_lite
vsim -lib work -c +access +r tb_top -do "run -all; exit"
program.hex: $(ASM_TEST_DIR)/$(ASM_TEST).s ${RV_ROOT}/configs/snapshots/$(snapshot)/common_defines.vh
@echo Building $(ASM_TEST)
ifeq ($(shell which $(GCC_PREFIX)-as),)
@echo " !!! No $(GCC_PREFIX)-as in path, using canned hex files !!"
cp ${RV_ROOT}/testbench/hex/*.hex .
riviera-build: ${TBFILES} ${BUILD_DIR}/defines.h
vlib work
vlog -work work \
-l riviera_compile.log -err VCP2694 W1 \
+incdir+${RV_ROOT}/design/lib \
+incdir+${RV_ROOT}/design/include \
+incdir+${BUILD_DIR} +libext+.v $(defines) \
-f ${RV_ROOT}/testbench/flist \
${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
cp $(ASM_TEST_DIR)/$(ASM_TEST).s .
$(GCC_PREFIX)-cpp -I${RV_ROOT}/configs/snapshots/$(snapshot) $(ASM_TEST).s > $(ASM_TEST).cpp.s
$(GCC_PREFIX)-as -march=rv32imc $(ASM_TEST).cpp.s -o $(ASM_TEST).o
$(GCC_PREFIX)-ld -m elf32lriscv --discard-none -T${RV_ROOT}/testbench/link.ld -o $(ASM_TEST).exe $(ASM_TEST).o
$(GCC_PREFIX)-objcopy -O verilog --only-section ".data*" --only-section ".rodata*" $(ASM_TEST).exe data.hex
$(GCC_PREFIX)-objcopy -O verilog --only-section ".text*" --set-start=0x0 $(ASM_TEST).exe program.hex
$(GCC_PREFIX)-objdump -dS $(ASM_TEST).exe > $(ASM_TEST).dis
$(GCC_PREFIX)-nm -f posix -C $(ASM_TEST).exe > $(ASM_TEST).tbl
@echo Completed building $(ASM_TEST)
ifneq (,$(wildcard $(TEST_DIR)/$(TEST).makefile))
program.hex:
$(MAKE) -f $(TEST_DIR)/$(TEST).makefile
else
program.hex: $(TEST).o $(LINK)
@echo Building $(TEST)
$(GCC_PREFIX)-ld -m elf32lriscv --discard-none -T$(LINK) -o $(TEST).exe $(TEST).o
$(GCC_PREFIX)-objcopy -O verilog --only-section ".data*" --change-section-lma .data=0 $(TEST).exe data.hex
$(GCC_PREFIX)-objcopy -O verilog --only-section ".text*" $(TEST).exe program.hex
$(GCC_PREFIX)-objdump -S $(TEST).exe > $(TEST).dis
$(GCC_PREFIX)-nm -f posix -C $(TEST).exe > $(TEST).tbl
@echo Completed building $(TEST)
%.o : %.s ${BUILD_DIR}/defines.h
$(GCC_PREFIX)-cpp -I${BUILD_DIR} $< > $(TEST).cpp.s
$(GCC_PREFIX)-as -march=rv32gc $(TEST).cpp.s -o $(TEST).o
TEST_CFLAGS = -g -O3 -funroll-all-loops
ABI = -mabi=ilp32 -march=rv32imc
%.o : %.c ${BUILD_DIR}/defines.h
$(GCC_PREFIX)-gcc -I${BUILD_DIR} ${TEST_CFLAGS} ${ABI} -nostdlib -c $< -o $@
endif
endif
help:
@echo Make sure the environment variable RV_ROOT is set.
@echo Possible targets: verilator vcs irun help clean all verilator-run irun-run vcs-run program.hex
@echo Possible targets: verilator vcs irun vlog 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

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

View File

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

View File

@ -35,9 +35,9 @@ printf("end\n");
sub b2d {
my ($v) = @_;
$v = oct("0b" . $v);
return($v);
}
@ -48,11 +48,11 @@ sub d2b {
$v = sprintf "%b",$v;
if (length($v)<$LEN) {
$repeat=$LEN-length($v);
$v="0"x$repeat.$v;
$repeat=$LEN-length($v);
$v="0"x$repeat.$v;
}
elsif (length($v)>$LEN) {
$v=substr($v,length($v)-$LEN,$LEN);
$v=substr($v,length($v)-$LEN,$LEN);
}
return($v);

View File

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

1
tools/vivado.tcl Normal file
View File

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