Compare commits

..

No commits in common. "master" and "v0.8.3" have entirely different histories.

833 changed files with 25399 additions and 108913 deletions

View file

@ -7,13 +7,6 @@ assignees: ''
---
**Note**
We're fortunate to have a community of highly skilled system engineers and reverse engineers contributing to HyperDbg. However, as an open-source, community-driven debugger, our resources and developer time are limited.
Since most HyperDbg users are professional programmers, we encourage you to contribute by submitting pull requests (PRs) whenever possible. While we will address issues created by users, we greatly appreciate your efforts to resolve issues independently and submit PRs. If you're unable to create a PR, please feel free to create an issue, and we'll do our best to address it.
Thank you for reporting issues and for your contributions! ❤️
**Describe the bug**
A clear and concise description of what the bug is.

View file

@ -7,13 +7,6 @@ assignees: ''
---
**Note**
We're fortunate to have a community of highly skilled system engineers and reverse engineers contributing to HyperDbg. However, as an open-source, community-driven debugger, our resources and developer time are limited.
Since most HyperDbg users are professional programmers, we encourage you to contribute by submitting pull requests (PRs) whenever possible. While we will address requests for new features created by users, we greatly appreciate your efforts to add them independently and submit PRs. If you're unable to create a PR, please feel free to create your request, and we'll do our best to address it. You can also create issues or discussions to discuss the possible features that you want to add to HyperDbg.
Thank you for requesting new features and for your contributions! ❤️
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

View file

@ -44,32 +44,6 @@ To remove the effects of `git add .` and `git commit -m "test"` or just `git add
git reset --soft HEAD~1
```
To remove **all uncommitted and untracked changes** in Git and reset your working tree to the last commit:
```bash
git reset --hard
git clean -fd
```
To modify the last pushed commit:
```bash
# Undo the last commit but keep the changes in your working tree
git reset --soft HEAD~1
# Make your additional modifications
# edit files...
# Stage everything
git add .
# Create a new commit
git commit -m "Updated commit message"
# Force-push to replace the remote commit
git push --force-with-lease
```
---------------
## Releasing instructions

View file

@ -1,31 +1,26 @@
name: vs2022-ci
on:
workflow_dispatch:
# Disabled, uncomment the below line and remove the above lines to activate
# on:
# push:
# branches:
# - master
# - dev
# tags:
# - 'v*'
# paths-ignore:
# - '.gitignore'
# - '.gitattributes'
# - '**.cmd'
# - '**.bat'
# - '**.md'
#
# pull_request:
# paths-ignore:
# - '.gitignore'
# - '.gitattributes'
# - '**.cmd'
# - '**.bat'
# - '**.md'
push:
branches:
- master
- dev
tags:
- 'v*'
paths-ignore:
- '.gitignore'
- '.gitattributes'
- '**.cmd'
- '**.bat'
- '**.md'
pull_request:
paths-ignore:
- '.gitignore'
- '.gitattributes'
- '**.cmd'
- '**.bat'
- '**.md'
env:
# WDK for Windows 11, version 22H2
WDK_URL: https://go.microsoft.com/fwlink/?linkid=2196230
@ -78,12 +73,12 @@ jobs:
# working-directory: ${{env.GITHUB_WORKSPACE}}
# run: msbuild /m /p:Configuration="Release MT" /p:Platform=${{matrix.PLATFORM}} /target:zydis /target:zycore /p:OutDir=${{ github.workspace }}/hyperdbg/libraries/zydis/ ${{ github.workspace }}/hyperdbg/dependencies/zydis/msvc/Zydis.sln
- name: Build HyperDbg solution
- name: Build Hyperdbg solution
working-directory: ${{env.GITHUB_WORKSPACE}}
run: msbuild /m /p:Configuration=${{matrix.BUILD_CONFIGURATION}} /p:Platform=${{matrix.PLATFORM}} ${{env.SOLUTION_FILE_PATH}}
- name: Upload build directory
uses: actions/upload-artifact@v4.4.0
uses: actions/upload-artifact@v3
with:
name: build_files_${{matrix.BUILD_CONFIGURATION}}
path: ${{ env.BUILD_BIN_DIR }}
@ -91,12 +86,12 @@ jobs:
deploy-release:
name: Deploy release
needs: win-amd64-build
runs-on: windows-2022
runs-on: windows-2019
if: startsWith(github.ref, 'refs/tags/')
steps:
- name: Download build files from "build" job
uses: actions/download-artifact@v4.1.7
uses: actions/download-artifact@v3
with:
name: build_files_release
path: ${{ env.BUILD_BIN_DIR }}

View file

@ -1,99 +0,0 @@
name: vs2026-ci
on:
push:
branches:
- '**' # matches all branch names, including ones with slashes
tags:
- 'v*'
paths-ignore:
- '.gitignore'
- '.gitattributes'
- '**.cmd'
- '**.bat'
- '**.md'
pull_request:
paths-ignore:
- '.gitignore'
- '.gitattributes'
- '**.cmd'
- '**.bat'
- '**.md'
env:
SOLUTION_FILE_PATH: ./hyperdbg/hyperdbg.sln
RELEASE_ZIP_FILE_NAME: hyperdbg
BUILD_BIN_DIR: ./hyperdbg/build/bin/
jobs:
win-amd64-build:
runs-on: windows-2025-vs2026
strategy:
matrix:
BUILD_CONFIGURATION: [release, debug]
PLATFORM: [x64]
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
submodules: recursive
- name: Checkout submodules recursively
run: git submodule update --init --recursive --remote
- name: Add MSBuild to PATH
uses: microsoft/setup-msbuild@v3
- name: Setup NuGet
uses: NuGet/setup-nuget@v2
- name: Restore NuGet packages
run: nuget restore ${{ env.SOLUTION_FILE_PATH }}
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.x'
- name: Update vcxproj files
run: python utils/replace-sdk-wdk.py
- name: Build HyperDbg solution
working-directory: ${{env.GITHUB_WORKSPACE}}
run: msbuild /m /p:Configuration=${{matrix.BUILD_CONFIGURATION}} /p:Platform=${{matrix.PLATFORM}} ${{env.SOLUTION_FILE_PATH}}
- name: Upload build directory
uses: actions/upload-artifact@v4.4.0
with:
name: build_files_${{matrix.BUILD_CONFIGURATION}}
path: ${{ env.BUILD_BIN_DIR }}
deploy-release:
name: Deploy release
needs: win-amd64-build
runs-on: windows-2025-vs2026
if: startsWith(github.ref, 'refs/tags/')
steps:
- name: Download build files from "build" job
uses: actions/download-artifact@v4.1.7
with:
name: build_files_release
path: ${{ env.BUILD_BIN_DIR }}
- name: Archive release
uses: thedoctor0/zip-release@master
with:
path: ${{ env.BUILD_BIN_DIR }}release/
type: 'zip'
filename: ${{env.RELEASE_ZIP_FILE_NAME}}-${{ github.ref_name }}.zip
- name: Release
uses: softprops/action-gh-release@v1
if: startsWith(github.ref, 'refs/tags/')
with:
files: |
${{env.RELEASE_ZIP_FILE_NAME}}-${{ github.ref_name }}.zip
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

14
.gitignore vendored
View file

@ -377,26 +377,16 @@ MigrationBackup/
!/hyperdbg/libraries/DIA/x84/*
!/hyperdbg/libraries/DIA/x64/*
# kdserial libraries
# KdSerial Libraries
!/hyperdbg/libraries/kdserial/*
!/hyperdbg/libraries/kdserial/x86/*
!/hyperdbg/libraries/kdserial/x64/*
!/hyperdbg/libraries/kdserial/arm/*
!/hyperdbg/libraries/kdserial/arm64/*
# Ignore keystone libraries
!/hyperdbg/libraries/keystone/release/
!/hyperdbg/libraries/keystone/debug/
!/hyperdbg/libraries/keystone/release/*
!/hyperdbg/libraries/keystone/debug/*
# Code review tools
compile_commands.json
StructLayoutSettings.json
*.metaproj
#ignore clion config files
.idea
cmake-build-debug
/hyperdbg/hyperhv/zydis/
*.metaproj

12
.gitmodules vendored
View file

@ -1,12 +1,12 @@
[submodule "hyperdbg/tests/script-engine-test"]
path = hyperdbg/tests/script-engine-test
url = https://github.com/HyperDbg/script-engine-test.git
[submodule "hyperdbg/miscellaneous/constants/pciid"]
path = hyperdbg/miscellaneous/constants/pciid
url = https://github.com/HyperDbg/pciids
[submodule "hyperdbg/dependencies/ia32-doc"]
path = hyperdbg/dependencies/ia32-doc
url = https://github.com/HyperDbg/ia32-doc.git
[submodule "hyperdbg/dependencies/phnt"]
path = hyperdbg/dependencies/phnt
url = https://github.com/HyperDbg/phnt.git
[submodule "hyperdbg/script-engine/modules/script-engine-test"]
path = hyperdbg/script-engine/modules/script-engine-test
url = https://github.com/HyperDbg/script-engine-test
[submodule "hyperdbg/dependencies/pdbex"]
path = hyperdbg/dependencies/pdbex
url = https://github.com/HyperDbg/pdbex.git

View file

@ -4,412 +4,6 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [0.21.0.0] - 2026-07-05
New release of the HyperDbg Debugger.
### Added
- Added structure for the hyperperf (Hardware Performance Counter) project ([link](https://github.com/HyperDbg/HyperDbg/commit/c17ebc09c4d199a642352e66feebb3159582196c))
- The 'unload' command checks whether any module is loaded or not ([link](https://docs.hyperdbg.org/commands/debugging-commands/unload))
- Exported SDK API for checking whether any module is loaded or not ([link](https://github.com/HyperDbg/HyperDbg/commit/19e47c804f50f5dbb698f314e66b7d685a87ac1f))
- Added user mode and kernel mode PT parameter parser ([link](https://github.com/HyperDbg/HyperDbg/pull/631))
- Added thread (TID) and process (PID) helper functions for Intel PT ([link](https://github.com/HyperDbg/HyperDbg/pull/633))
### Changed
- Separated SDK libraries for user mode and kernel mode modules ([link](https://github.com/HyperDbg/HyperDbg/commit/c17ebc09c4d199a642352e66feebb3159582196c))
- Added hypertrace, hyperevade, and hyperperf DLL files to SDK ([link](https://github.com/HyperDbg/HyperDbg/commit/c17ebc09c4d199a642352e66feebb3159582196c))
- Fix pool manager uninitialize list corruption ([link](https://github.com/HyperDbg/HyperDbg/pull/629))
- Fix 'access denied' error on loading all modules using 'load all' ([link](https://docs.hyperdbg.org/commands/debugging-commands/load))([link](https://github.com/HyperDbg/HyperDbg/commit/2b818a5116d80d466aab7b343d4aa9d1d640f082))
- Fix the concatenation error for the "hyperkd" string on the hypertrace project (https://github.com/HyperDbg/HyperDbg/commit/2b0cc18899ff532d9d590a71bf880fee5456c15f))
- Organized header files for the libhyperdbg project ([link](https://github.com/HyperDbg/HyperDbg/pull/632))
## [0.20.0.0-beta] - 2026-06-21
New release of the HyperDbg Debugger.
### Added
- Added the libipt library to the project and the SDK
- Added Intel Processor Trace (PT) example app
- Added Linux distinction and pragmas together with new platform functions ([link](https://github.com/HyperDbg/HyperDbg/commit/9c3e0ed23b5f4bb64bd305e546dd0e86ee1910d9))
- Added interfaces to Linux port for the serial devices ([link](https://github.com/HyperDbg/HyperDbg/commit/31b514f8df40d81d44ae07a2328c02360ce488c3))
- Added platform IOCTL interface ([link](https://github.com/HyperDbg/HyperDbg/pull/619))
- Added typecast for wchar, mismatch on Linux and Windows ([link](https://github.com/HyperDbg/HyperDbg/commit/10576b064a9824ab655e7bea0e35e9556ee68ca4))
- Added missing IOCTLs for Intel PT ([link](https://github.com/HyperDbg/HyperDbg/commit/df12e9fd79851c8f378ec82a45066da510da507a))
- Added NuGet packages for Windows SDK and WDK
- Added Signal handler platform API for Linux ([link](https://github.com/HyperDbg/HyperDbg/pull/627))
- Added contribution guidelines for Linux ([link](https://github.com/HyperDbg/HyperDbg/tree/master/hyperdbg/linux#readme))
### Changed
- Moved to Visual Studio 2026 ([link](https://github.com/HyperDbg/HyperDbg/pull/626))
- Zydis and pdbex submodules are updated to VS2026
- Fix the new form of loading and unloading in the example app and PT app ([link](https://github.com/HyperDbg/HyperDbg/commit/9ad48d30dcf6b409ae86b2d08262584cd06f606e))
- Check whether the top-level hypervisor is Hyper-V and disable/enable VPIDs based on that, thanks to [@Idov31](https://github.com/Idov31) ([link](https://github.com/HyperDbg/HyperDbg/pull/625))
- Fix PT operation IOCTL buffer size ([link](https://github.com/HyperDbg/HyperDbg/commit/dabf132d31503843f90949f35f8dce4601d43126))
- CI/CD updated with NuGet packages for Visual Studio 2026 ([link](https://github.com/HyperDbg/HyperDbg/commit/5a0fad490124268550f955f594d1211d5c74f03d))
## [0.19.0.0-beta] - 2026-06-10
New release of the HyperDbg Debugger.
### Added
- First release of the HyperTrace module ([link](https://url.hyperdbg.org/hypertrace))
- HyperTrace now enables/disables VM-entry/VM-exit controls for Load and Save IA32_DEBUGCTL MSR
- Added Legacy LBR support to the HyperTrace module
- Added Architectural LBR support to the HyperTrace module
- Added the '!lbr' command for performing different Last Branch Record (LBR) operations ([link](https://docs.hyperdbg.org/commands/extension-commands/lbr))
- Added the '!lbrdump' command for dumping saved Last Branch Record (LBR) entries ([link](https://docs.hyperdbg.org/commands/extension-commands/lbrdump))
- Added **lbr_save()** and **lbr_print()** functions in the script engine ([link](https://docs.hyperdbg.org/commands/scripting-language/functions/tracing/lbr/lbr_save))([link](https://docs.hyperdbg.org/commands/scripting-language/functions/tracing/lbr/lbr_print))
- Added mock application for compiling SDK for Linux
- Added '!help' alias for the '.help' command
- Added 'vm' alias for the 'load' command ([link](https://docs.hyperdbg.org/commands/debugging-commands/load))
- Added **lbr_check()** and **lbr_restore()** functions in the script engine ([link](https://docs.hyperdbg.org/commands/scripting-language/functions/tracing/lbr/lbr_check))([link](https://docs.hyperdbg.org/commands/scripting-language/functions/tracing/lbr/lbr_restore))
- Added **lbr_restore_by_filter(filter)** function in the script engine ([link](https://docs.hyperdbg.org/commands/scripting-language/functions/tracing/lbr/lbr_restore_by_filter))
- Added the 'kd' module in the 'load' command ([link](https://docs.hyperdbg.org/commands/debugging-commands/load))
- Added the 'trace' module in the 'load' command ([link](https://docs.hyperdbg.org/commands/debugging-commands/load))
- Exported SDK API for detecting CPU vendors
- Initial codes for the HyperTrace project by using Intel Processor Trace (PT), thanks to [@masoudrahimi01](https://github.com/masoudrahimi01) ([link](https://github.com/HyperDbg/HyperDbg/pull/589))
- Exported SDK APIs for loading and unloading the 'kd' and the 'trace' modules
- Exported SDK APIs for starting (installing) the 'kd' driver
- Exported SDK APIs for loading/unloading all modules
- Added tests for checking PE parser in 'hyperdbg-test' project
- Added example for loading HyperDbg in VMI mode directly from libhyperdbg
- Fix action cleanup list removal in debugger events ([link](https://github.com/HyperDbg/HyperDbg/pull/601))
- Added transparent-mode evade mask selection thanks to [@jtaw5649](https://github.com/jtaw5649) ([link](https://github.com/HyperDbg/HyperDbg/pull/602))
- Added synthetic MSR handling thanks to [@Idov31](https://github.com/Idov31) ([link](https://github.com/HyperDbg/HyperDbg/pull/605))
- Added use of relative RSDS fixture paths when loading PDB symbols, thanks to [@jtaw5649](https://github.com/jtaw5649) ([link](https://github.com/HyperDbg/HyperDbg/pull/607))
### Changed
- Fix the problem of not applying the EAX index in the CPUID event extension command ([link](https://docs.hyperdbg.org/commands/extension-commands/cpuid#parameters))
- Refactoring the IOCTL parameter checks and status routines
- All basic types are now defined for Linux
- VMX instructions are ported to platform-independent files to support Linux
- All CPU-related intrinsic instructions are ported to platform-independent files to support Linux
- HyperDbg SDK now compiles on Linux (GCC) for both user-mode and kernel-mode
- Fix the 'wrmsr' command IOCTL checks by receiving output in the buffer ([link](https://docs.hyperdbg.org/commands/debugging-commands/wrmsr))
- Extensive refactoring of code base (doxygen, variables, function names)
- Building certain modules on Linux and fixing CMake files thanks to [@maxraulea](https://github.com/maxraulea) ([link](https://github.com/HyperDbg/HyperDbg/pull/592))
- Fix the '!hide' command's HyperEvade activation guard thanks to [@jtaw5649](https://github.com/jtaw5649) ([link](https://github.com/HyperDbg/HyperDbg/pull/593))
- Fix synchronous debugger device IOCTL handles thanks to [@jtaw5649](https://github.com/jtaw5649) ([link](https://github.com/HyperDbg/HyperDbg/pull/595))
- PE parser ('.pe' command) now supports richer DOS/NT/COFF/optional-header output, section bounds checking, data directory reporting, import/export parsing, TLS/debug/PDB/load-config metadata, overlay reporting, and malformed metadata warnings thanks to [@jtaw5649](https://github.com/jtaw5649) ([link](https://github.com/HyperDbg/HyperDbg/pull/598))([link](https://docs.hyperdbg.org/commands/meta-commands/.pe))
- Building the script engine module on Linux (GCC) thanks to [@maxraulea](https://github.com/maxraulea) ([link](https://github.com/HyperDbg/HyperDbg/pull/596))
- The pool manager moved from 'hyperhv' to 'hyperkd'
- The 'load' command could load all modules using a new alias 'load all' ([link](https://docs.hyperdbg.org/commands/debugging-commands/load))
- The 'unload' command could remove all modules using two new aliases 'unload all' and 'unload remove all' ([link](https://docs.hyperdbg.org/commands/debugging-commands/unload))
- Change device handle checks with module loading status checks for IOCTLs ([link](https://github.com/HyperDbg/HyperDbg/pull/610))
- Fix standard callbacks for the VMM module ([link](https://github.com/HyperDbg/HyperDbg/pull/610))
- Fix race condition bug within the pool manager
## [0.18.1.0] - 2026-04-09
New release of the HyperDbg Debugger.
### Added
- HyperTrace now works with HyperDbg VMM ([link](https://github.com/HyperDbg/HyperDbg/pull/568))
- Progress on implementing Last Branch Recode (LBR) ([link](https://github.com/HyperDbg/HyperDbg/commit/1dd73675e9cd78737e013ffb35bc712f385f387e))
- Applying LBR registers on the VMCS instead of the DEBUGCTL MSR ([link](https://github.com/HyperDbg/HyperDbg/commit/15f8b3cca15448acd18d7e198740464a19ce4fe2))
### Changed
- Fix the problem of the '!epthook' not finding the PML1 entry ([link](https://docs.hyperdbg.org/commands/extension-commands/epthook))
- Fix the problem of getting the PML1 entry of the target address on Intel Core Ultra processors (#567) ([link](https://github.com/HyperDbg/HyperDbg/issues/567))
- Fix the '.clang-format' formatting error
- Restructure of the HyperTrace project
- Add starting structure for supporting Intel Processor Trace (PT)
## [0.18.0.0] - 2026-02-16
New release of the HyperDbg Debugger.
### Added
- Script engine now supports writing libraries using the '#include' keyword thanks to [@xmaple555](https://github.com/xmaple555) ([link](https://docs.hyperdbg.org/commands/scripting-language/casting-and-inclusion))([link](https://github.com/HyperDbg/HyperDbg/issues/557))([link](https://github.com/HyperDbg/HyperDbg/pull/561))
- Initial codes for the HyperTrace project by using Intel Last Branch Record (LBR) and Branch Trace Store (BTS) thanks to [@harimishal1](https://github.com/harimishal1) ([link](https://github.com/HyperDbg/HyperDbg/tree/master/hyperdbg/hypertrace))
- The HyperTrace project is now linked to the hyperkd
- Initial efforts to port HyperDbg to Linux have started thanks to [@Alish14](https://github.com/Alish14) ([link](https://github.com/HyperDbg/HyperDbg/pull/563))
### Changed
- Fix compilation error in Zydis with the new Windows WDK ([link](https://github.com/HyperDbg/zydis/commit/e61f59332ce49f8853006573ca853e404fafdd08))
## [0.17.0.0] - 2025-11-10
New release of the HyperDbg Debugger. All credit for this release goes to [@xmaple555](https://github.com/xmaple555).
### Added
- Added 1D and 2D arrays (multidimensional arrays) in the script engine ([link](https://docs.hyperdbg.org/commands/scripting-language/variables-and-assignments#multidimensional-array))([link](https://github.com/HyperDbg/HyperDbg/pull/554))
- Added compound assignments in the script engine ([link](https://docs.hyperdbg.org/commands/scripting-language/variables-and-assignments#compound-assignment))([link](https://github.com/HyperDbg/HyperDbg/pull/554))
- Added multiple assignments in the script engine ([link](https://docs.hyperdbg.org/commands/scripting-language/variables-and-assignments#multiple-assignment))([link](https://github.com/HyperDbg/HyperDbg/pull/554))
### Changed
- Fix bugs for interpreting 'db_pa, 'dd_pa', 'eb_pa', and 'ed_pa' keywords in the script engine ([link](https://docs.hyperdbg.org/commands/scripting-language/assumptions-and-evaluations#keywords))([link](https://github.com/HyperDbg/HyperDbg/pull/507))
- Fix variable types in the script engine ([link](https://github.com/HyperDbg/HyperDbg/commit/43b0245fa11b5c73ce4cd21d8b8787b86a05f89d))
- Fix and update array index for boolean expressions in the script engine ([link](https://github.com/HyperDbg/HyperDbg/commit/ba2cec3c12c3ff45ddc0004051884983ff62a0b3))
## [0.16.0.0] - 2025-09-08
New release of the HyperDbg Debugger.
### Added
- The **!xsetbv** event command was added for handling the execution of the XSETBV instruction, thanks to HyperDbg group members ([link](https://docs.hyperdbg.org/commands/extension-commands/xsetbv))
- Display of the number of blocked context switches in the '.switch' command ([link](https://docs.hyperdbg.org/commands/meta-commands/.switch))
- Added support for step-in (the 't' command) in the user debugger ([link](https://docs.hyperdbg.org/commands/debugging-commands/t))
- Added support for step-over (the 'p' command) in the user debugger ([link](https://docs.hyperdbg.org/commands/debugging-commands/p))
- Added support to show all registers or a specific register in the user debugger ([link](https://docs.hyperdbg.org/commands/debugging-commands/r))
- Exported SDK API for running scripts in either the kernel debugger or the user debugger
- Added support to modify registers or a specific register in the user debugger ([link](https://docs.hyperdbg.org/commands/debugging-commands/r))
- Added support to evaluate (run) scripts on the target thread in the user debugger ([link](https://docs.hyperdbg.org/commands/debugging-commands/eval))
- Added an indication of a thread's running or paused state to the HyperDbg signature in the user debugger ([link](https://docs.hyperdbg.org/using-hyperdbg/prerequisites/signatures))
- Added support for the '.formats' command in the user debugger ([link](https://docs.hyperdbg.org/commands/meta-commands/.formats))
- Added support for interpreting parameters based on script engine expressions in the user debugger
- Exported SDK API for evaluating expressions based on the context of the kernel debugger or the user debugger
- Added a new mechanism for showing the 'printf' and the 'print' function messages in the user debugger ([link](https://docs.hyperdbg.org/commands/scripting-language/functions/exports/printf))([link](https://docs.hyperdbg.org/commands/scripting-language/functions/exports/print))
### Changed
- Non-volatile XMM registers are no longer saved/restored on VM-exit handler ([link](https://learn.microsoft.com/en-us/cpp/build/x64-software-conventions?view=msvc-170))
- Fix grammar and spelling errors throughout HyperDbg codebase ([link](https://github.com/HyperDbg/HyperDbg/pull/546))
- Relocate extension command files into their corresponding VS directory
- Fix infinite VM-exit bug for the '!monitor x' command thanks to [@unlockable](https://github.com/unlockable) ([link](https://github.com/HyperDbg/HyperDbg/pull/545))
## [0.15.0.0] - 2025-08-18
New release of the HyperDbg Debugger.
### Added
- Added the '!smi' command for performing operations related to System Management Interrupt (SMI) ([link](https://docs.hyperdbg.org/commands/extension-commands/smi))
- Export the SDK functions for SMI operations ([link](https://docs.hyperdbg.org/commands/extension-commands/smi#sdk))
- Check for Intel CET IBT (indirect branch tracking) support
- Check for Intel CET shadow stack support
- Added support to Intel CET for SYSCALL/SYSRET emulation ([link](https://docs.hyperdbg.org/commands/extension-commands/syscall))([link](https://docs.hyperdbg.org/commands/extension-commands/sysret))
### Changed
- The 'hyperhv' project now has build optimizations enabled
- Reformat VMXOFF restoring routines to restore general-purpose and XMM registers correctly before moving to the previous stack
- Fix unloading (VMXOFF) crash when restoring XMM registers
- Fix the problem with restoring XMM registers (#468) ([link](https://github.com/HyperDbg/HyperDbg/issues/468))
- Enhanced the '.pe' command to support PE Rich Headers thanks to [@Alish14](https://github.com/Alish14) ([link](https://github.com/HyperDbg/HyperDbg/pull/539))
- Updated ia32-doc to fix VMCS PL3 SSP fields ([link](https://github.com/HyperDbg/ia32-doc))
- Fix the terminating process issue of the '!syscall/!sysret' commands on 11 generation (Rocket Lake/Tiger Lake) and newer Intel processors ([link](https://github.com/HyperDbg/HyperDbg/issues/392))
- Re-enable the support for the '.start' command in the Debugger mode ([link](https://docs.hyperdbg.org/commands/meta-commands/.start))
- The '!mode' event command is now compatible with different EPT hook commands (e.g., !epthook, !epthook2, !monitor, .start, and .restart) ([link](https://docs.hyperdbg.org/commands/extension-commands/mode))
- The '!mode' command doesn't need allocating extra EPTPs ([link](https://docs.hyperdbg.org/commands/extension-commands/mode))
## [0.14.1.0] - 2025-07-27
New release of the HyperDbg Debugger.
### Changed
- Restored the previous optimization on the release builds
- Fixed the issue of not properly restoring registers after the 'CPUID' instruction
- Fixed the building issues of the user debugger with the 'bp' and the '.start' commands
## [0.14.0.0] - 2025-07-23
New release of the HyperDbg Debugger.
### Added
- **microsleep(microseconds)** function in the script engine ([link](https://docs.hyperdbg.org/commands/scripting-language/functions/timings/microsleep))
- **rdtsc()** and **rdtscp()** functions in the script engine ([link](https://docs.hyperdbg.org/commands/scripting-language/functions/timings/rdtsc))([link](https://docs.hyperdbg.org/commands/scripting-language/functions/timings/rdtscp))
- Added functions to get system-call number from the running system ([link](https://github.com/HyperDbg/HyperDbg/commit/5d33cb7395c57fd6af170bfed90376598347679c))
- Added the support for the '.start' command in the VMI mode ([link](https://docs.hyperdbg.org/commands/meta-commands/.start))
- Added a new mechanism for finding the system-call number based on the running system ([link](https://github.com/HyperDbg/HyperDbg/commit/5d33cb7395c57fd6af170bfed90376598347679c))
- Added hyperevade transparency project ([link](https://url.hyperdbg.org/hyperevade))
- Added support to the '.attach' and '.detach' in the debugger mode ([link](https://docs.hyperdbg.org/commands/meta-commands/.attach))([link](https://docs.hyperdbg.org/commands/meta-commands/.detach))
- Added support to the '.start' command in the VMI mode for the user debugger ([link](https://docs.hyperdbg.org/commands/meta-commands/.start))
- Added support to setting the breakpoint using the 'bp' command in the VMI mode ([link](https://docs.hyperdbg.org/commands/debugging-commands/bp))
- Added EPT page table support for MMIO addresses above 512 GB
### Changed
- Redesigned the '!mode' extension command without extra EPTP ([link](https://github.com/HyperDbg/HyperDbg/commit/a93b78dfadbf94d2d69f24413170c983ec379f48))
- The user mode debugger now uses MBEC for preventing user-mode code execution ([link](https://github.com/HyperDbg/HyperDbg/commit/6893c1b19f1edaf57d0074bd60abcd518bf77338))
- Apply transparent-mode based on dynamic system-calls ([link](https://github.com/HyperDbg/HyperDbg/commit/1eb960607331fc0c2622804d7aff65702c155649))
- Breakpoint initialization is changed from kernel debugger to the regular debugger ([link](https://github.com/HyperDbg/HyperDbg/commit/e5326f895dcddb1adbc873a9fecede7af7eb7651))
- Fixed the build issue on new Windows SDK for Token structures ([link](https://github.com/HyperDbg/HyperDbg/pull/530))
- Fixed retrieving valid watching process IDs for the execution trap and user-mode execution prevention
- Fixed crashing the driver if the hyperlog memory was not properly allocated
- The target runner image for deploying HyperDbg (CI/CD) changed from Windows Server 2019 to 2022
- Restored the pid and the process name parameters of the '!hide' command ([link](https://docs.hyperdbg.org/commands/extension-commands/hide))
- Fixed crashing Windows when using 'TPAUSE' instruction on bare metal Windows 11 24h2
- Check to avoid putting EPT hooks on physical addresses greater than 512 GB
## [0.13.2.0] - 2025-05-26
New release of the HyperDbg Debugger.
### Added
- Intercepting system-call return results using the TRAP flag for the transparent-mode
- Added optional parameters and context for the transparent-mode system-call return interceptions
### Changed
- Set variable length (stack frames) for showing the callstack ([link](https://docs.hyperdbg.org/commands/debugging-commands/k))
- Fixed VMCS layout corruption due to NMI injection (VMRESUME 0x7 error) in nested-virtualization on Meteor Lake processors
- Restore RDMSR handler for VM-exits
## [0.13.1.0] - 2025-04-14
New release of the HyperDbg Debugger.
### Added
- Added new transparency methods for hiding nested virtualization environments thanks to [@CokeTree3](https://github.com/CokeTree3) ([link](https://github.com/HyperDbg/HyperDbg/pull/515))
### Changed
- Fix '.thread' command crash ([link](https://github.com/HyperDbg/HyperDbg/pull/510))
- Update .clang-format format file based on the new version of LLVM
- Update the list of required contributions
## [0.13.0.0] - 2025-02-25
New release of the HyperDbg Debugger.
### Added
- Added mitigation for the anti-hypervisor method in handling the trap flag for emulated instructions ([link](https://github.com/HyperDbg/HyperDbg/pull/497))
- Export the SDK functions for enabling and disabling transparent mode ([link](https://docs.hyperdbg.org/commands/extension-commands/hide#sdk))([link](https://docs.hyperdbg.org/commands/extension-commands/unhide#sdk))
- New description of changing script engine constants ([link](https://docs.hyperdbg.org/tips-and-tricks/misc/customize-build/change-script-engine-limitations))
- Added the command for interpreting PCI CAM (PCI configuration space) fields ([link](https://docs.hyperdbg.org/commands/extension-commands/pcicam))
- Added the command for dumping PCI CAM (PCI configuration space) memory ([link](https://docs.hyperdbg.org/commands/extension-commands/pcicam))
- Checking for and unloading the older version of the driver (if it exists) ([link](https://github.com/HyperDbg/HyperDbg/pull/503))
- **memcpy_pa()** function in the script engine ([link](https://docs.hyperdbg.org/commands/scripting-language/functions/memory/memcpy_pa))
- **poi_pa**, **hi_pa**, **low_pa**, **db_pa**, **dd_pa**, **dw_pa**, and **dq_pa** keywords in the script engine ([link](https://docs.hyperdbg.org/commands/scripting-language/assumptions-and-evaluations#keywords))
- **eb_pa**, **ed_pa**, and **eq_pa** functions in the script engine ([link](https://docs.hyperdbg.org/commands/scripting-language/functions/memory/eb_pa-ed_pa-eq_pa))
### Changed
- Fix the 'lm' command issue of not showing kernel module addresses (KASLR leak mitigation) introduced in Windows 11 24h2 ([link](https://docs.hyperdbg.org/commands/debugging-commands/lm))
- Deprecated TSC mitigation for the transparent mode ([link](https://docs.hyperdbg.org/commands/extension-commands/measure))
- Changed the parameters of the '!hide' command ([link](https://docs.hyperdbg.org/commands/extension-commands/hide))
- Changed the parameters of the '!unhide' command ([link](https://docs.hyperdbg.org/commands/extension-commands/unhide))
- Fix containing backslash escape character in script strings ([link](https://github.com/HyperDbg/HyperDbg/pull/499))
- Fix reading/writing into devices' physical memory (MMIO region) in VMI Mode ([link](https://github.com/HyperDbg/HyperDbg/pull/500))
- All test cases for command parsing are now passed ([link](https://github.com/HyperDbg/HyperDbg/pull/504))
- The '.sympath' command now requires the symbol server path to be within quotes, although it is not mandatory ([link](https://docs.hyperdbg.org/commands/meta-commands/.sympath))
## [0.12.0.0] - 2025-01-02
New release of the HyperDbg Debugger.
### Added
- Added the PCI tree command ([link](https://docs.hyperdbg.org/commands/extension-commands/pcitree))
- Added the proper handling for the xsetbv VM exits thanks to [@Shtan7](https://github.com/Shtan7) ([link](https://github.com/HyperDbg/HyperDbg/pull/491))
- Added the IDT command for interpreting Interrupt Descriptor Table (IDT) ([link](https://docs.hyperdbg.org/commands/extension-commands/idt))
- Export SDK APIs for getting Interrupt Descriptor Table (IDT) entries
### Changed
- Fix buffer overflow in the symbols path converter thanks to [@binophism](https://github.com/binophism) ([link](https://github.com/HyperDbg/HyperDbg/pull/490))
- Fix script engine's "printf" function to improve safety thanks to [@Reodus](https://github.com/Reodus) ([link](https://github.com/HyperDbg/HyperDbg/pull/489))
## [0.11.0.0] - 2024-12-03
New release of the HyperDbg Debugger.
### Added
- Added the local APIC command (xAPIC and x2APIC modes) ([link](https://docs.hyperdbg.org/commands/extension-commands/apic))
- Added the I/O APIC command ([link](https://docs.hyperdbg.org/commands/extension-commands/ioapic))
- The new link is added to help increase the number of EPT hook breakpoints in a single page ([link](https://docs.hyperdbg.org/tips-and-tricks/misc/customize-build/number-of-ept-hooks-in-one-page))
- Export SDK APIs for Local APIC and X2APIC
### Changed
- The link for changing the communication buffer size is updated ([link](https://docs.hyperdbg.org/tips-and-tricks/misc/customize-build/increase-communication-buffer-size))
- Update Microsoft's DIA SDK and symsrv
## [0.10.2.0] - 2024-10-11
New release of the HyperDbg Debugger.
### Added
- Automated test case parsing and test case compilation (generation) for the hwdbg debugger
- Export hwdbg testing functions
- Automated test case interpretation and emulation of hwdbg hardware scripts
- Create JSON representation of hwdbg configs
### Changed
- Fix main command parser bugs according to test cases
- Improvements in symbol structure, token structure, and stack buffer in the script engine
- Fix compatibility mode program crash when terminating 32-bit process (#479) ([link](https://github.com/HyperDbg/HyperDbg/pull/479))
- Extensive refactor of chip instance info interpretation codes of hwdbg debugger
- Separating functions of hwdbg interpreter and script manager
- Fix synthesize inconsistencies between Icarus iVerilog and Xilinx ISim
- Fix runtime error for deallocating memory from separate DLLs
- Exporting standard functions (import/export) for the script engine
- Exporting standard functions (import/export) for the symbol parser
- Avoid passing signals once the stage is not configured
## [0.10.1.0] - 2024-09-08
New release of the HyperDbg Debugger.
### Added
- Added feature to pause the debuggee immediately upon connection
- The '.debug' command now supports pausing the debuggee at startup ([link](https://docs.hyperdbg.org/commands/meta-commands/.debug))
- Export SDK API for assembling instructions
- The 'struct' command now supports a path as output ([link](https://docs.hyperdbg.org/commands/debugging-commands/struct))
- Export SDK API closing connection to the remote debuggee
- Automated tests for the main command parser
- Export SDK APIs for stepping and tracing instructions
- Export SDK APIs for tracking execution
### Changed
- HyperDbg command-line comment sign is changed from '#' to C-like comments ('//' and '/**/')
- Integrating a new command parser for the regular HyperDbg commands
- Fix showing a list of active outputs using the 'output' command ([link](https://docs.hyperdbg.org/commands/debugging-commands/output))
- Fix the issue of passing arguments to the '.start' command ([link](https://docs.hyperdbg.org/commands/meta-commands/.start))
- Fix the problem with parsing multiple spaces within the events (#420) ([link](https://github.com/HyperDbg/HyperDbg/issues/420))
- Fix the problem with escaping '{' in the command parser (#421) ([link](https://github.com/HyperDbg/HyperDbg/issues/421))
- Fix nested brackets issues in the main command parser
- Fix script engine bugs on order of passing arguments to functions (#453) ([link](https://github.com/HyperDbg/HyperDbg/issues/453))
- Fix the script test case for factorial computation ([link](https://github.com/HyperDbg/script-engine-test/blob/main/semantic-test-cases/manual-test-cases_60-69.ds))
- Fix the script test case for computation iterative Fibonacci ([link](https://github.com/HyperDbg/script-engine-test/blob/main/semantic-test-cases/manual-test-cases_60-69.ds))
- Fix miscomputation of physical address width for physical address validity checks (#469) ([link](https://github.com/HyperDbg/HyperDbg/issues/469))
## [0.10.0.0] - 2024-07-22
New release of the HyperDbg Debugger.
### Added
- Support using assembly conditions and codes in all events ([link](https://docs.hyperdbg.org/using-hyperdbg/prerequisites/how-to-create-a-condition))([link](https://docs.hyperdbg.org/using-hyperdbg/prerequisites/how-to-create-an-action))
- Added support for forwarding events to binary (DLL) modules ([link](https://docs.hyperdbg.org/tips-and-tricks/misc/event-forwarding))([link](https://docs.hyperdbg.org/commands/debugging-commands/output))([link](https://github.com/HyperDbg/event-forwarding-examples))
- Added the assembler command 'a' for virtual memory ([link](https://docs.hyperdbg.org/commands/debugging-commands/a))
- Added the assembler command '!a' for physical memory ([link](https://docs.hyperdbg.org/commands/extension-commands/a))
- Providing a unified SDK API for reading memory in the VMI Mode and the Debugger Mode
- Export SDK APIs for reading/writing into registers in the Debugger Mode
- Export SDK API for writing memory in the VMI Mode and the Debugger Mode
- Export SDK API for getting kernel base address
- Export SDK API for connecting to the debugger and from debuggee in the Debugger Mode
- Export SDK API for starting a new process
- Add and export SDK API for unsetting message callback
- Event commands are coming with more examples regarding scripts and assembly codes
- Add message callback using shared memory
- Add maximum execution limitation to the script IRs (#435) ([link](https://github.com/HyperDbg/HyperDbg/pull/435))
### Changed
- Fix clearing '!monitor' hooks on a different process or if the process is closed (#409) ([link](https://github.com/HyperDbg/HyperDbg/issues/409))
- Fix triggering multiple '!monitor' hooks with different contexts (#415) ([link](https://github.com/HyperDbg/HyperDbg/issues/415))
- Fix the problem of repeating commands once kHyperDbg is disconnected
- Fix step-over hangs if the process terminates/excepts within call instruction (#406) ([link](https://github.com/HyperDbg/HyperDbg/issues/406))
- Fix crash on editing invalid physical addresses (#424) ([link](https://github.com/HyperDbg/HyperDbg/issues/424))
- Fix exporting VMM module load and install it in the SDK
- Fix function interpretation issues and update the parser and the code execution (#435) ([link](https://github.com/HyperDbg/HyperDbg/pull/435))
## [0.9.1.0] - 2024-06-30
New release of the HyperDbg Debugger.
### Added
- Regular port/pin value read and modification in hwdbg
- Conditional statement evaluation in hwdbg
- Added automatic script buffer packet generator for hwdbg
- Added support for @hw_pinX and @hw_portX registers
- Added hwdbg instance information interpreter
- Added stack buffer in vmx-root ([link](https://github.com/HyperDbg/HyperDbg/commit/5df4d2a5268a6b190dc126bf6cfe0527703296eb))
- Exporting functions to support loading drivers with different names
- Exporting function to connect and load HyperDbg drivers
- Exporting function to connect and load HyperDbg drivers
- **$date** and **$time** pseudo-registers are added ([link](https://docs.hyperdbg.org/commands/scripting-language/assumptions-and-evaluations#pseudo-registers))([link](https://github.com/HyperDbg/HyperDbg/issues/397))
### Changed
- Fix using constant WSTRINGs in the **wcsncmp** function ([link](https://docs.hyperdbg.org/commands/scripting-language/functions/strings/wcsncmp))
- Fix `phnt` build error with 24H2 SDK
- `hprdbgctrl.dll` changed to `libhyperdbg.dll`
- `hprdbgkd.sys` changed to `hyperkd.sys`
- `hprdbghv.dll` changed to `hyperhv.dll`
- Dividing user/kernel exported headers in the SDK
## [0.9.0.0] - 2024-06-09
New release of the HyperDbg Debugger.
### Added
- The **!monitor** command now physical address hooking ([link](https://docs.hyperdbg.org/commands/extension-commands/monitor))
- **hwdbg** is merged to HyperDbg codebase ([link](https://hwdbg.hyperdbg.org))
- **strncmp(Str1, Str2, Num)**, and **wcsncmp(WStr1, WStr2, Num)** functions in script engine ([link](https://docs.hyperdbg.org/commands/scripting-language/functions/strings/strncmp))([link](https://docs.hyperdbg.org/commands/scripting-language/functions/strings/wcsncmp))
### Changed
- Using a separate HOST IDT in VMCS (not OS IDT) (fix to this [VM escape](https://www.unknowncheats.me/forum/c-and-c-/390593-vm-escape-via-nmi.html) issues)
- Using a dedicated HOST GDT and TSS Stack
- Checking for race-condition of not locked cores before applying instant-events and switching cores
- The error message for invalid address is changed ([more information](https://docs.hyperdbg.org/tips-and-tricks/considerations/accessing-invalid-address))
- Fix the problem of not locking all cores after running the '.pagein' command
## [0.8.4.0] - 2024-05-10
New release of the HyperDbg Debugger.
### Changed
- Fixed the signedness overflow of the command parser
## [0.8.3.0] - 2024-05-03
New release of the HyperDbg Debugger.

View file

@ -2,19 +2,21 @@
First off, thanks for taking the time to contribute! ❤️
HyperDbg is a large-scale project that requires a lot of time and effort from the community. Given the current number of developers and their limited time and resources, we cannot develop every part simultaneously. Therefore, new developers are warmly welcomed to join and add their contributions to the project. Here, we made a list of potential improvements that you can contribute on. Feel free to open up an issue if you think you have any ideas that would make a good addition to the list.
HyperDbg is a large-scale project that requires a lot of time and effort from the community. Given the current number of developers and their limited time and resources, we cannot develop every part simultaneously. Therefore, new developers are warmly welcomed to join and add their contributions to the project. Here, we made a list of potential improvements that you can contribute on. Feel free to open up an issue if you think you have any ideas that would make a good addition to the list, or if you want to implement one of the below items, or if you'd like to discuss a question you might have.
## Things to Work on
Please make sure to create a [discussion](https://github.com/orgs/HyperDbg/discussions) or an [issue](https://github.com/HyperDbg/HyperDbg/issues), or even better, join the HyperDbg groups ([Telegram](https://t.me/HyperDbg), [Discord](https://discord.gg/anSPsGUtzN), [Matrix](https://matrix.to/#/#hyperdbg-discussion:matrix.org)) on social media. Discuss the way you want to implement your changes and inform developers, because we often see people simultaneously working on the same issue. To avoid this collision, make sure to inform us before you start developing.
- Writing blog posts about use-cases of HyperDbg
- Troubleshooting problems with running on Hyper-V's nested virtualization
- Troubleshooting problems with running on VirtualBox's nested virtualization
- Supporting kdnet (sending data over the net)
- Adding an assembler to the project
- Enhancing HyperDbg's [Transparent Mode](https://docs.hyperdbg.org/using-hyperdbg/prerequisites/operation-modes#transparent-mode), especially anti-hypervisor methods
- Making a SoftICE-style GUI
- Enhancing and adding more features to the ['.pe'](https://docs.hyperdbg.org/commands/meta-commands/.pe) command
- Anything else you might find interesting ;)
### Working on an Idea or a Task
- We have a [wide range of ideas and tasks](https://github.com/orgs/HyperDbg/projects/2) that you might be interested in working on. You can choose a task and start working on it, and if you have any questions or need clarification, feel free to ask. This list will be updated frequently.
### Other Things to Work on
- Writing blog posts and creating videos about use-cases of HyperDbg (make sure to add it to the [awesome](https://github.com/HyperDbg/awesome) repository).
- Fixing unresolved GitHub [issues](https://github.com/HyperDbg/HyperDbg/issues).
- Any other interesting ideas you might find! (Let's have a discussion before working on them.)
This list will be updated frequently.
## Fixing Bugs

View file

@ -4,7 +4,7 @@ The list provided comprises individuals who have made significant contributions
## Credits:
Just so you know the attributions listed on this credits page are acknowledged without any particular order.
The attributions listed on this credits page are acknowledged without any particular order.
- All of the [contributors](https://github.com/HyperDbg/HyperDbg/graphs/contributors)
- Sina Karvandi ([@Intel80x86](https://twitter.com/Intel80x86))
@ -21,10 +21,4 @@ Just so you know the attributions listed on this credits page are acknowledg
- Ddkwork ([@ddkwork](https://github.com/ddkwork)) for making GUI
- Mohammad K. Fallah ([@mkfallah11](https://github.com/mkfallah11)) for implementing the optimization algorithms
- Xandora Team ([xandora.io](https://www.xandora.io)) for [Keystone](https://github.com/keystone-engine/keystone) engine
- xmaple555 ([@xmaple555](https://github.com/xmaple555)) for contributions in HyperDbg core and the script engine
- Abbas Masoumi Gorji ([@AbbasMasoumiG](https://twitter.com/AbbasMasoumiG))
- Björn Ruytenberg ([@0Xiphorus](https://twitter.com/0Xiphorus))
- Marcis Zarins ([@CokeTree3](https://github.com/CokeTree3)) for his works on enhancing HyperEvade project
- Artem Shishkin ([@honorary_bot](https://twitter.com/honorary_bot)) for always answering our hypervisor questions
- unrustled.jimmies for helping us debug and fix issues, and his contributions in HyperDbg
- Hari Mishal ([@harimishal1](https://github.com/harimishal1)) for his works on the hypertrace project for supporting Last Branch Record (LBR)
- xmaple555 ([@xmaple555](https://github.com/xmaple555)) for contributions in HyperDbg core and the script engine

136
README.md
View file

@ -6,40 +6,25 @@
<a href="https://www.gnu.org/licenses/gpl-3.0"><img src="https://raw.githubusercontent.com/HyperDbg/graphics/master/Badges/License-GPLv3-blue.svg" alt="License"></a>
</p>
# HyperDbg Debugger
<a href="https://hyperdbg.org/"><img align="right" width="150" height="150" src="https://github.com/HyperDbg/graphics/raw/master/Art%20Board/HyperDbg-Cat.Circle.Compressed.png" alt="HyperDbg Debugger"></a></br>
**HyperDbg Debugger** is a free (as in free beer), open-source, community-driven, hypervisor-assisted, user-mode, and kernel-mode Windows debugger with a focus on using modern hardware technologies. It is a debugger designed for analyzing, fuzzing, and reversing.
HyperDbg Debugger is an open-source, community-driven, hypervisor-assisted, user-mode, and kernel-mode Windows debugger with a focus on using modern hardware technologies. It is a debugger designed for analyzing, fuzzing, and reversing.
You can follow **HyperDbg** on **[Twitter](https://twitter.com/HyperDbg)** or **[Mastodon](https://infosec.exchange/@hyperdbg)** to get notified about new releases, or join any of the HyperDbg groups, where you can ask developers and open-source reversing enthusiasts for help setting up and using HyperDbg.
- **[Telegram](https://t.me/HyperDbg)**
- **[Discord](https://discord.gg/anSPsGUtzN)**
- **[Matrix](https://matrix.to/#/#hyperdbg-discussion:matrix.org)**
You can follow **HyperDbg** on **[Twitter](https://twitter.com/HyperDbg)** to get notified about new releases, or join the HyperDbg **[Telegram](https://t.me/HyperDbg)** group, where you can ask developers and open-source reversing enthusiasts for help with setting up and running HyperDbg.
## Description
**HyperDbg** is designed with a focus on using modern hardware technologies to provide new features to the debuggers' world. It operates on top of Windows by virtualizing an already running system using Intel VT-x and EPT. This debugger aims not to use any APIs and software debugging mechanisms, but instead, it uses Second Layer Page Table (a.k.a. Extended Page Table or EPT) extensively to monitor both kernel and user executions.
**HyperDbg** is designed with a focus on using modern hardware technologies to provide new features to the debuggers' world. It operates on top of Windows by virtualizing an already running system using Intel VT-x and Intel PT. This debugger aims not to use any APIs and software debugging mechanisms, but instead, it uses Second Layer Page Table (a.k.a. Extended Page Table or EPT) extensively to monitor both kernel and user executions.
<p align="center"><a href="https://hyperdbg.org/"><img align="center" width="600" height="500" src="https://raw.githubusercontent.com/HyperDbg/graphics/master/Art%20Board/Artboard%201.png" alt="HyperDbg Debugger"></a></br>
</p>
HyperDbg comes with features like hidden hooks, which are as fast as old inline hooks, but also stealth. It mimics hardware debug registers for (read & write) to a specific location, but this time invisible for both the Windows kernel and the programs, and of course, without any limitation in size or count!
HyperDbg comes with features like hidden hooks, which are as fast as old inline hooks, but also stealth. It mimics hardware debug registers for (read & write) to a specific location, but this time entirely invisible for both Windows kernel and the programs, and of course, without any limitation in size or count!
Using TLB-splitting and having features such as measuring code coverage and monitoring all mov(s) to/from memory by a function, makes HyperDbg a unique debugger.
Using TLB-splitting, and having features such as measuring code coverage and monitoring all mov(s) to/from memory by a function, makes HyperDbg a unique debugger.
Although it has novel features, HyperDbg tries to be as stealthy as possible. It doesnt use any debugging APIs to debug Windows or any application, so classic anti-debugging methods wont detect it. Also, it resists the exploitation of time delta methods (e.g., RDTSC/RDTSCP) to detect the presence of hypervisors, therefore making it much harder for applications, packers, protectors, malware, anti-cheat engines, etc. to discover the debugger.
## Why HyperDbg?
HyperDbg is harder to set up and use, and also requires deeper low-level system knowledge compared to traditional debuggers. However, it provides two major advantages:
1. **Full System & OS Control**
HyperDbg operates at the hypervisor level, giving you powerful capabilities that are simply not possible with classic debuggers. This allows you to leverage hardware-assisted [features](https://github.com/HyperDbg/HyperDbg?tab=readme-ov-file#unique-features) for advanced reverse engineering and debugging scenarios.
2. **Stealth & Detection Resistance**
Since HyperDbg doesn't rely on standard OS debugging APIs, it is generally much harder (though not impossible) to detect. This makes it a strong choice when working against anti-debugging protections.
These advantages open up entirely new debugging and reverse engineering techniques that go beyond what conventional debuggers can offer.
## Build & Installation
You can download the latest compiled binary files from **[releases](https://github.com/HyperDbg/HyperDbg/releases)**; otherwise, if you want to build HyperDbg, you should clone HyperDbg with the `--recursive` flag.
@ -50,7 +35,7 @@ Please visit **[Build & Install](https://docs.hyperdbg.org/getting-started/build
## Tutorials
The **OpenSecurityTraining2's "Reversing with HyperDbg (Dbg3301)**" tutorial series, available on [**OST2's website**](https://ost2.fyi/Dbg3301) (_preferred_) and [**YouTube**](https://www.youtube.com/playlist?list=PLUFkSN0XLZ-kF1f143wlw8ujlH2A45nZY) is the recommended way to get started with and learn HyperDbg. It guides you through the initial steps of using HyperDbg, covering essential concepts, principles, and debugging functionalities, along with practical examples and numerous reverse engineering methods that are unique to HyperDbg.
The **[OpenSecurityTraining2's "Reversing with HyperDbg (Dbg3301)"](https://ost2.fyi/Dbg3301)** tutorial is the recommended way to get started with and learn HyperDbg, guiding you through the initial steps of using HyperDbg, covering essential concepts, principles, debugging functionalities, along with practical examples and numerous reverse engineering methods that are unique to HyperDbg.
If you're interested in understanding the internal design and architecture of hypervisors and HyperDbg, you can read the [**Hypervisor From Scratch**](https://rayanfam.com/tutorials) tutorials.
@ -69,71 +54,26 @@ In case you use one of **HyperDbg**'s components in your work, please consider c
year={2022}
}
```
<details>
<summary><b>Other paper built upon HyperDbg...</b></summary>
**2. [hwdbg: Debugging Hardware Like Software (EuroSec'25)](https://dl.acm.org/doi/abs/10.1145/3722041.3723101)** [[PDF](https://dl.acm.org/doi/pdf/10.1145/3722041.3723101)]
**2. [The Reversing Machine: Reconstructing Memory Assumptions](https://arxiv.org/pdf/2405.00298)** [[arXiv](https://arxiv.org/abs/2405.00298)]
```
@inproceedings{karvandi2025hwdbg,
title={hwdbg: Debugging Hardware Like Software},
author={Karvandi, Mohammad Sina and Meghdadizanjani, Soroush and Monfared, Saleh Khalaj and van der Kouwe, Erik and Slowinska, Asia},
booktitle={Proceedings of the 18th European Workshop on Systems Security},
pages={56--62},
year={2025}
@misc{karvandi2024reversing,
Author = {Mohammad Sina Karvandi and Soroush Meghdadizanjani and Sima Arasteh and Saleh Khalaj Monfared and Mohammad K. Fallah and Saeid Gorgin and Jeong-A Lee and Erik van der Kouwe},
Title = {The Reversing Machine: Reconstructing Memory Assumptions},
Year = {2024},
Eprint = {arXiv:2405.00298},
}
```
**3. [HyperEvade: Countering Anti-Debugging Techniques and Enhancing Transparency in Nested Virtualization using HyperDbg (DEBT'25)](https://www.jot.fm/contents/issue_2026_01/a8.html)** [[PDF](https://www.jot.fm/issues/issue_2026_01/a8.pdf)]
```
@article{ruytenberg2026hyperevade,
title={HyperEvade: Countering Anti-Debugging Techniques and Enhancing Transparency in Nested Virtualization using HyperDbg},
author={Ruytenberg, Bj{\"o}rn and Karvandi, Mohammad Sina},
journal={Journal of Object Technology},
volume={25},
number={1},
pages={1--3},
year={2026},
publisher={Association Internationale pour les Technologies Objets}
}
```
**4. [Digital Hole: Bypassing Commercial Audio DRM Solutions with DReaMcatcher (EuroSys'26)](https://dl.acm.org/doi/abs/10.1145/3767295.3803583)** [[PDF](https://dl.acm.org/doi/pdf/10.1145/3767295.3803583)]
```
@inproceedings{ruytenberg2026digital,
title={Digital Hole: Bypassing Commercial Audio DRM Solutions with DReaMcatcher},
author={Ruytenberg, Bj{\"o}rn and Karvandi, Mohammad Sina and Bos, Herbert and van der Kouwe, Erik and Slowinska, Asia},
booktitle={Proceedings of the 21st European Conference on Computer Systems},
pages={484--496},
year={2026}
}
```
**5. [TRM: An Efficient Hypervisor-Based Framework For Malware Analysis and Memory Reconstruction (AsiaCCS'26)](https://dl.acm.org/doi/10.1145/3779208.3785293)** [[PDF](https://dl.acm.org/doi/pdf/10.1145/3779208.3785293)]
```
@inproceedings{karvandi2026trm,
title={TRM: An Efficient Hypervisor-Based Framework For Malware Analysis and Memory Reconstruction},
author={Karvandi, Mohammad Sina and Meghdadizanjani, Soroush and Arasteh, Sima and Monfared, Saleh Khalaj and Fallah, Mohammad K and Gorgin, Saeid and Lee, Jeong-A and Slowinska, Asia and van der Kouwe, Erik},
booktitle={Proceedings of the ACM Asia Conference on Computer and Communications Security},
pages={68--82},
year={2026}
}
```
</details>
You can also read [this article](https://research.hyperdbg.org/debugger/kernel-debugger-design/) as it describes the overall architecture, technical difficulties, design decisions, and internals of HyperDbg Debugger, [this article](https://research.hyperdbg.org/vmm/transparency/) about our efforts on vm-exit transparency, [this article](https://research.hyperdbg.org/debugger/chasing-bugs/) about chasing bugs within hypervisors, and [this article](https://research.hyperdbg.org/debugger/gaining-insights/) about new reverse engineering techniques introduced in HyperDbg. More articles, posts, and resources are available at the **[awesome](https://github.com/HyperDbg/awesome)** repo, and in addition, the **[slides](https://github.com/HyperDbg/slides)** repo provides presentation slides for further reference.
You can also read [this article](https://research.hyperdbg.org/debugger/kernel-debugger-design.html) as it describes the overall architecture, technical difficulties, design decisions, and internals of HyperDbg Debugger, [this article](https://research.hyperdbg.org/debugger/transparency.html) about our efforts on vm-exit transparency, and [this article](https://research.hyperdbg.org/debugger/chasing-bugs.html) about chasing bugs within hypervisors. More articles, posts, and resources are available at the **[awesome](https://github.com/HyperDbg/awesome)** repo, and in addition, the **[slides](https://github.com/HyperDbg/slides)** repo provides presentation slides for further reference.
## Unique Features
### First Release (v0.1.0.0)
* Advanced Hypervisor-based Kernel Mode Debugger [<a href="https://docs.hyperdbg.org/using-hyperdbg/kernel-mode-debugging" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/getting-started/attach-to-hyperdbg/debug" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/getting-started/attach-to-hyperdbg/local-debugging" target="_blank">link</a>]
* Classic EPT Hook (Hidden Breakpoint) [<a href="https://docs.hyperdbg.org/commands/extension-commands/epthook" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/design/features/vmm-module/design-of-epthook" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/using-hyperdbg/kernel-mode-debugging/examples/events/hooking-any-function" target="_blank">link</a>]
* Inline EPT Hook (Inline Hook) [<a href="https://docs.hyperdbg.org/commands/extension-commands/epthook2" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/design/features/vmm-module/design-of-epthook2" target="_blank">link</a>]
* Monitor Memory for R/W (Emulating Hardware Debug Registers Without Limitation) [<a href="https://docs.hyperdbg.org/commands/extension-commands/monitor" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/design/features/vmm-module/design-of-monitor" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/using-hyperdbg/kernel-mode-debugging/examples/events/monitoring-accesses-to-structures" target="_blank">link</a>]
* Monitor Memory For R/W (Emulating Hardware Debug Registers Without Limitation) [<a href="https://docs.hyperdbg.org/commands/extension-commands/monitor" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/design/features/vmm-module/design-of-monitor" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/using-hyperdbg/kernel-mode-debugging/examples/events/monitoring-accesses-to-structures" target="_blank">link</a>]
* SYSCALL Hook (Disable EFER & Handle #UD) [<a href="https://docs.hyperdbg.org/commands/extension-commands/syscall" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/design/features/vmm-module/design-of-syscall-and-sysret" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/using-hyperdbg/kernel-mode-debugging/examples/events/intercepting-all-syscalls" target="_blank">link</a>]
* SYSRET Hook (Disable EFER & Handle #UD) [<a href="https://docs.hyperdbg.org/commands/extension-commands/sysret" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/design/features/vmm-module/design-of-syscall-and-sysret" target="_blank">link</a>]
* CPUID Hook & Monitor [<a href="https://docs.hyperdbg.org/commands/extension-commands/cpuid" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/using-hyperdbg/kernel-mode-debugging/examples/events/triggering-special-instructions" target="_blank">link</a>]
@ -143,15 +83,15 @@ You can also read [this article](https://research.hyperdbg.org/debugger/kernel-d
* RDPMC Hook & Monitor [<a href="https://docs.hyperdbg.org/commands/extension-commands/pmc" target="_blank">link</a>]
* VMCALL Hook & Monitor [<a href="https://docs.hyperdbg.org/commands/extension-commands/vmcall" target="_blank">link</a>]
* Debug Registers Hook & Monitor [<a href="https://docs.hyperdbg.org/commands/extension-commands/dr" target="_blank">link</a>]
* I/O Port (IN Instruction) Hook & Monitor [<a href="https://docs.hyperdbg.org/commands/extension-commands/ioin" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/using-hyperdbg/kernel-mode-debugging/examples/events/triggering-special-instructions" target="_blank">link</a>]
* I/O Port (OUT Instruction) Hook & Monitor [<a href="https://docs.hyperdbg.org/commands/extension-commands/ioout" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/using-hyperdbg/kernel-mode-debugging/examples/events/triggering-special-instructions" target="_blank">link</a>]
* I/O Port (In Instruction) Hook & Monitor [<a href="https://docs.hyperdbg.org/commands/extension-commands/ioin" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/using-hyperdbg/kernel-mode-debugging/examples/events/triggering-special-instructions" target="_blank">link</a>]
* I/O Port (Out Instruction) Hook & Monitor [<a href="https://docs.hyperdbg.org/commands/extension-commands/ioout" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/using-hyperdbg/kernel-mode-debugging/examples/events/triggering-special-instructions" target="_blank">link</a>]
* MMIO Monitor [<a href="https://docs.hyperdbg.org/commands/extension-commands/monitor" target="_blank">link</a>]
* Exception (IDT < 32) Monitor [<a href="https://docs.hyperdbg.org/commands/extension-commands/exception" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/design/features/vmm-module/design-of-exception-and-interrupt" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/using-hyperdbg/kernel-mode-debugging/examples/events/identifying-system-behavior" target="_blank">link</a>]
* External-Interrupt (IDT > 32) Monitor [<a href="https://docs.hyperdbg.org/commands/extension-commands/interrupt" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/design/features/vmm-module/design-of-exception-and-interrupt" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/using-hyperdbg/kernel-mode-debugging/examples/events/identifying-system-behavior" target="_blank">link</a>]
* Running Automated Scripts [<a href="https://docs.hyperdbg.org/commands/scripting-language/debugger-script" target="_blank">link</a>]
* Transparent-mode and Hyperevade Project (Anti-debugging and Anti-hypervisor Resistance) [<a href="https://docs.hyperdbg.org/tips-and-tricks/considerations/transparent-mode" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/commands/extension-commands/hide" target="_blank">link</a>][<a href="https://www.vusec.net/projects/hyperevade/" target="_blank">link</a>]
* Running Custom Assembly in Both VMX-root, VMX non-root (Kernel & User) [<a href="https://docs.hyperdbg.org/using-hyperdbg/prerequisites/how-to-create-an-action" target="_blank">link</a>]
* Checking for Custom Conditions [<a href="https://docs.hyperdbg.org/using-hyperdbg/prerequisites/how-to-create-a-condition" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/design/debugger-internals/conditions" target="_blank">link</a>]
* Transparent-mode (Anti-debugging and Anti-hypervisor Resistance) [<a href="https://docs.hyperdbg.org/tips-and-tricks/considerations/transparent-mode" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/using-hyperdbg/kernel-mode-debugging/examples/misc/defeating-anti-debug-and-anti-hypervisor-methods" target="_blank">link</a>]
* Running Custom Assembly In Both VMX-root, VMX non-root (Kernel & User) [<a href="https://docs.hyperdbg.org/using-hyperdbg/prerequisites/how-to-create-an-action" target="_blank">link</a>]
* Checking For Custom Conditions [<a href="https://docs.hyperdbg.org/using-hyperdbg/prerequisites/how-to-create-a-condition" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/design/debugger-internals/conditions" target="_blank">link</a>]
* Process-specific & Thread-specific Debugging [<a href="https://docs.hyperdbg.org/commands/meta-commands/.process" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/commands/meta-commands/.thread" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/using-hyperdbg/user-mode-debugging/examples/basics/switching-to-a-specific-process-or-thread" target="_blank">link</a>]
* VMX-root Compatible Message Tracing [<a href="https://docs.hyperdbg.org/design/features/vmm-module/vmx-root-mode-compatible-message-tracing" target="_blank">link</a>]
* Powerful Kernel Side Scripting Engine [<a href="https://docs.hyperdbg.org/commands/scripting-language" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/design/script-engine" target="_blank">link</a>]
@ -160,26 +100,30 @@ You can also read [this article](https://research.hyperdbg.org/debugger/kernel-d
* Event Forwarding (#DFIR) [<a href="https://docs.hyperdbg.org/tips-and-tricks/misc/event-forwarding" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/commands/debugging-commands/output" target="_blank">link</a>]
* Transparent Breakpoint Handler [<a href="https://docs.hyperdbg.org/commands/debugging-commands/bp" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/using-hyperdbg/kernel-mode-debugging/examples/basics/setting-breakpoints-and-stepping-instructions" target="_blank">link</a>]
* Various Custom Scripts [<a href="https://github.com/HyperDbg/scripts" target="_blank">link</a>]
### Second Release (v0.2.0.0)
* HyperDbg Software Development Kit (SDK) [<a href="https://docs.hyperdbg.org/using-hyperdbg/sdk" target="_blank">link</a>]
### Third Release (v0.3.0.0)
* Event Short-circuiting [<a href="https://docs.hyperdbg.org/tips-and-tricks/misc/event-short-circuiting" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/commands/scripting-language/functions/events/event_sc" target="_blank">link</a>]
* Tracking Records of Function Calls and Return Addresses [<a href="https://docs.hyperdbg.org/commands/extension-commands/track" target="_blank">link</a>]
* Tracking records of function calls and return addresses [<a href="https://docs.hyperdbg.org/commands/extension-commands/track" target="_blank">link</a>]
* Kernel-level Length Disassembler Engine (LDE) [<a href="https://docs.hyperdbg.org/commands/scripting-language/functions/diassembler/disassemble_len" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/commands/scripting-language/functions/diassembler/disassemble_len32" target="_blank">link</a>]
### Fourth Release (v0.4.0.0)
* Memory Execution Monitor & Execution Blocking [<a href="https://docs.hyperdbg.org/commands/extension-commands/monitor" target="_blank">link</a>]
* Custom Page-fault Injection [<a href="https://docs.hyperdbg.org/commands/meta-commands/.pagein" target="_blank">link</a>]
### Fifth Release (v0.5.0.0)
* Different Event Calling Stages [<a href="https://docs.hyperdbg.org/tips-and-tricks/misc/event-calling-stage" target="_blank">link</a>]
### Sixth Release (v0.6.0.0)
* Injecting Custom Interrupts/Exceptions/Faults [<a href="https://docs.hyperdbg.org/commands/scripting-language/functions/events/event_inject" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/commands/scripting-language/functions/events/event_inject_error_code" target="_blank">link</a>]
* Instant Events in the Debugger Mode [<a href="https://docs.hyperdbg.org/tips-and-tricks/misc/instant-events" target="_blank">link</a>]
* Detecting Kernel-to-user and User-to-kernel Transitions [<a href="https://docs.hyperdbg.org/commands/extension-commands/mode" target="_blank">link</a>]
* Physical Memory Monitoring Hooks [<a href="https://docs.hyperdbg.org/commands/extension-commands/monitor" target="_blank">link</a>]
* Enumerating PCI/PCI-e Devices [<a href="https://docs.hyperdbg.org/commands/extension-commands/pcitree" target="_blank">link</a>]
* Interpreting and Dumping PCI/PCI-e Configuration Space (CAM) [<a href="https://docs.hyperdbg.org/commands/extension-commands/pcicam" target="_blank">link</a>]
* Dumping IDT Entries, I/O APIC, and Local APIC in XAPIC and X2APIC Modes [<a href="https://docs.hyperdbg.org/commands/extension-commands/idt" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/commands/extension-commands/ioapic" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/commands/extension-commands/apic" target="_blank">link</a>]
* Triggering and Counting System Management Mode (SMM) Interrupts (SMIs) [<a href="https://docs.hyperdbg.org/commands/extension-commands/smi" target="_blank">link</a>]
* Attaching to the User-mode Process and Preventing Execution [<a href="https://docs.hyperdbg.org/commands/meta-commands/.attach" target="_blank">link</a>]
* Intercepting Execution of XSETBV Instructions [<a href="https://docs.hyperdbg.org/commands/extension-commands/xsetbv" target="_blank">link</a>]
* Writing Library Script Files [<a href="https://docs.hyperdbg.org/commands/scripting-language/casting-and-inclusion" target="_blank">link</a>]
* Enhanced Portable Executable (PE) Parser [<a href="https://docs.hyperdbg.org/commands/meta-commands/.pe" target="_blank">link</a>]
* Tracing Branches using Last Branch Record (LBR) [<a href="https://docs.hyperdbg.org/commands/extension-commands/lbr" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/commands/extension-commands/lbrdump" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/commands/scripting-language/functions/tracing/lbr/lbr_print" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/commands/scripting-language/functions/tracing/lbr/lbr_save" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/commands/scripting-language/functions/tracing/lbr/lbr_check" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/commands/scripting-language/functions/tracing/lbr/lbr_restore" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/commands/scripting-language/functions/tracing/lbr/lbr_restore_by_filter" target="_blank">link</a>]
### Seventh Release (v0.7.0.0)
* Instant events in the Debugger Mode [<a href="https://docs.hyperdbg.org/tips-and-tricks/misc/instant-events" target="_blank">link</a>]
### Eighth Release (v0.8.0.0)
* Detect kernel-to-user and user-to-kernel transitions [<a href="https://docs.hyperdbg.org/commands/extension-commands/mode" target="_blank">link</a>]
## How does it work?
@ -191,17 +135,15 @@ You can read about the internal design of HyperDbg and its features in the [docu
</br>
## Scripts
You can write your **[scripts](https://github.com/HyperDbg/scripts)** to automate your debugging journey. **HyperDbg** has a powerful, fast, and entirely kernel-side implemented [script engine](https://docs.hyperdbg.org/commands/scripting-language).
## Contributing
Contributing to HyperDbg is super appreciated. We have made a list of potential [tasks](https://github.com/HyperDbg/HyperDbg/blob/master/CONTRIBUTING.md#things-to-work-on) that you might be interested in contributing towards.
If you want to contribute to HyperDbg, please read the [Contribution Guide](https://github.com/HyperDbg/HyperDbg/blob/master/CONTRIBUTING.md).
## License
## License
**HyperDbg**, and all its submodules and repos, unless a license is otherwise specified, are licensed under **GPLv3** LICENSE.
Dependencies are licensed by their own.

View file

@ -1,3 +0,0 @@
# User-Mode and Kernel-Mode Examples
Examples for user-mode and kernel-mode are **NOT** yet completed and are currently **under construction**!

View file

@ -1,3 +0,0 @@
NOTE
============
Build it directly from the main HyperDbg solution file. Do not build it independently, as it requires dependency files from the main HyperDbg libraries to be built first.

View file

@ -1,20 +0,0 @@
# Code generated by Visual Studio kit, DO NOT EDIT.
set(SourceFiles
"header/core/Core.h"
"header/driver/Driver.h"
"header/driver/Loader.h"
"header/misc/Global.h"
"header/pch.h"
"code/core/Core.c"
"code/driver/Driver.c"
"code/driver/Ioctl.c"
"code/driver/Loader.c"
)
include_directories(
"../../../hyperdbg/include"
"header"
)
wdk_add_driver(hyperdbg_driver
KMDF 1.15
${SourceFiles}
)

View file

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.Windows.SDK.CPP" version="10.0.28000.1839" targetFramework="native" />
<package id="Microsoft.Windows.SDK.CPP.x64" version="10.0.28000.1839" targetFramework="native" />
<package id="Microsoft.Windows.WDK.x64" version="10.0.28000.1839" targetFramework="native" />
</packages>

View file

@ -1,3 +0,0 @@
NOTE
============
Build it directly from the main HyperDbg solution file. Do not build it independently, as it requires dependency files from the main HyperDbg libraries to be built first.

View file

@ -1,11 +0,0 @@
# Code generated by Visual Studio kit, DO NOT EDIT.
set(SourceFiles
"../../../platform/user/header/Environment.h"
"header/pch.h"
"code/hyperdbg-app.cpp"
)
include_directories(
"../../../hyperdbg/include"
"header"
)
add_executable(hyperdbg_app ${SourceFiles})

View file

@ -1,58 +0,0 @@
#include "pch.h"
static int
ShowMessages(const char * Text)
{
printf("%s", Text);
return 0;
}
static int
LoadVmm()
{
hyperdbg_u_set_text_message_callback((PVOID)ShowMessages);
if (!hyperdbg_u_detect_vmx_support())
{
printf("[-] VT-x (VMX) is not supported / enabled on this processor\n");
return 1;
}
printf("[*] loading HyperDbg VMM...\n");
if (hyperdbg_u_install_kd_driver() == 1 || hyperdbg_u_load_vmm() == 1)
{
printf("[-] cannot load the HyperDbg VMM\n");
return 1;
}
printf("[+] HyperDbg VMM is running\n");
return 0;
}
int
main(int argc, char ** argv)
{
return main2(argc, argv);
if (LoadVmm() != 0)
{
return 1;
}
hyperdbg_u_run_command((CHAR*)"lm");
printf("[*] unloading HyperDbg VMM...\n");
//
// Unload the driver
//
hyperdbg_u_unload_vmm();
hyperdbg_u_unload_kd();
hyperdbg_u_stop_kd_driver();
hyperdbg_u_uninstall_kd_driver();
printf("[+] done\n");
return 0;
}

View file

@ -1,583 +0,0 @@
#include "pch.h"
#include <string.h>
#include <stdlib.h>
#include <dbghelp.h>
#include "../dependencies/libipt/intel-pt.h"
#include <Zydis/Zydis.h>
#pragma comment(lib, "dbghelp.lib")
static UINT64 g_ImageBase = 0;
static UINT64 g_CodeBase = 0;
static UINT64 g_CodeSize = 0;
static UINT8 * g_Code = NULL;
static int
ShowMessages(const char * Text)
{
printf("%s", Text);
return 0;
}
static int
ReadImage(uint8_t * Buffer, size_t Size, const struct pt_asid * Asid, uint64_t Ip, void * Context)
{
(void)Asid;
(void)Context;
if (g_Code == NULL || Ip < g_CodeBase || Ip >= g_CodeBase + g_CodeSize)
return -pte_nomap;
uint64_t Available = g_CodeBase + g_CodeSize - Ip;
size_t Count = (Size < Available) ? Size : (size_t)Available;
memcpy(Buffer, g_Code + (Ip - g_CodeBase), Count);
return (int)Count;
}
typedef struct _PROC_BASIC_INFO
{
LONG ExitStatus;
PVOID PebBaseAddress;
ULONG_PTR Reserved[4];
} PROC_BASIC_INFO;
typedef LONG(NTAPI * PFN_NT_QIP)(HANDLE, ULONG, PVOID, ULONG, PULONG);
static BOOLEAN
CaptureImage(HANDLE Process, UINT64 * TextStart, UINT64 * TextEnd)
{
HMODULE Ntdll = GetModuleHandleA("ntdll.dll");
PFN_NT_QIP NtQip = Ntdll ? (PFN_NT_QIP)GetProcAddress(Ntdll, "NtQueryInformationProcess") : NULL;
PROC_BASIC_INFO Pbi = {0};
ULONG Ret = 0;
SIZE_T Got = 0;
UINT64 Base = 0;
IMAGE_DOS_HEADER Dos;
IMAGE_NT_HEADERS64 Nt;
UINT64 SectionBase;
if (NtQip == NULL || NtQip(Process, 0, &Pbi, sizeof(Pbi), &Ret) < 0 || Pbi.PebBaseAddress == NULL)
return FALSE;
if (!ReadProcessMemory(Process, (PBYTE)Pbi.PebBaseAddress + 0x10, &Base, sizeof(Base), &Got) || Base == 0)
return FALSE;
if (!ReadProcessMemory(Process, (PVOID)Base, &Dos, sizeof(Dos), &Got) || Dos.e_magic != IMAGE_DOS_SIGNATURE)
return FALSE;
if (!ReadProcessMemory(Process, (PBYTE)Base + Dos.e_lfanew, &Nt, sizeof(Nt), &Got) || Nt.Signature != IMAGE_NT_SIGNATURE)
return FALSE;
g_ImageBase = Base;
SectionBase = Base + Dos.e_lfanew + FIELD_OFFSET(IMAGE_NT_HEADERS64, OptionalHeader) + Nt.FileHeader.SizeOfOptionalHeader;
for (WORD i = 0; i < Nt.FileHeader.NumberOfSections; i++)
{
IMAGE_SECTION_HEADER Section;
if (!ReadProcessMemory(Process, (PBYTE)SectionBase + (UINT64)i * sizeof(Section), &Section, sizeof(Section), &Got))
return FALSE;
if (memcmp(Section.Name, ".text", 6) != 0)
continue;
UINT64 Start = Base + Section.VirtualAddress;
UINT64 Size = Section.Misc.VirtualSize ? Section.Misc.VirtualSize : Section.SizeOfRawData;
if (Size == 0)
return FALSE;
g_Code = (UINT8 *)malloc((size_t)Size);
if (g_Code == NULL)
return FALSE;
if (!ReadProcessMemory(Process, (PVOID)Start, g_Code, (SIZE_T)Size, &Got) || Got != Size)
{
free(g_Code);
g_Code = NULL;
return FALSE;
}
g_CodeBase = Start;
g_CodeSize = Size;
*TextStart = Start;
*TextEnd = Start + Size - 1;
return TRUE;
}
return FALSE;
}
static BOOLEAN
ResolveFunction(HANDLE Process, const char * Path, const char * Name, UINT64 * Start, UINT64 * End)
{
union
{
SYMBOL_INFO Info;
BYTE Buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME];
} Symbol = {0};
BOOLEAN Ok = FALSE;
SymSetOptions(SYMOPT_UNDNAME | SYMOPT_DEFERRED_LOADS);
if (!SymInitialize(Process, NULL, FALSE))
return FALSE;
if (SymLoadModuleEx(Process, NULL, Path, NULL, (DWORD64)g_ImageBase, 0, NULL, 0) != 0)
{
Symbol.Info.SizeOfStruct = sizeof(SYMBOL_INFO);
Symbol.Info.MaxNameLen = MAX_SYM_NAME;
if (SymFromName(Process, Name, &Symbol.Info) && Symbol.Info.Address != 0)
{
*Start = Symbol.Info.Address;
*End = Symbol.Info.Address + (Symbol.Info.Size ? Symbol.Info.Size : 0x200) - 1;
Ok = TRUE;
}
}
SymCleanup(Process);
return Ok;
}
static BOOLEAN
PtOperation(HYPERTRACE_PT_OPERATION_REQUEST_TYPE Type)
{
HYPERTRACE_PT_OPERATION_PACKETS Op = {};
Op.PtOperationType = Type;
return hyperdbg_u_pt_operation(&Op);
}
static BOOLEAN
PtFilter(UINT32 ProcessId, UINT64 Start, UINT64 End)
{
HYPERTRACE_PT_OPERATION_PACKETS Op = {};
Op.PtOperationType = HYPERTRACE_PT_OPERATION_REQUEST_TYPE_FILTER;
Op.FilterOptions.TraceUser = 1;
Op.EnableOptions.Pid = ProcessId;
if (End > Start)
{
Op.FilterOptions.NumAddrRanges = 1;
Op.FilterOptions.AddrRanges[0].Start = Start;
Op.FilterOptions.AddrRanges[0].End = End;
}
if (!hyperdbg_u_pt_operation(&Op))
return FALSE;
printf("[+] PT filter: cr3=0x%llx traceuser=%u ranges=%u buffer=0x%llx\n",
(unsigned long long)Op.EnableOptions.Cr3,
Op.FilterOptions.TraceUser,
Op.FilterOptions.NumAddrRanges,
(unsigned long long)Op.BufferSize);
return TRUE;
}
static const char *
PacketName(enum pt_packet_type Type)
{
switch (Type)
{
case ppt_psb: return "PSB"; case ppt_psbend: return "PSBEND"; case ppt_pad: return "PAD";
case ppt_fup: return "FUP"; case ppt_tip: return "TIP"; case ppt_tip_pge: return "TIP.PGE";
case ppt_tip_pgd: return "TIP.PGD"; case ppt_tnt_8: return "TNT8"; case ppt_tnt_64: return "TNT64";
case ppt_mode: return "MODE"; case ppt_pip: return "PIP"; case ppt_vmcs: return "VMCS";
case ppt_cbr: return "CBR"; case ppt_tsc: return "TSC"; case ppt_tma: return "TMA";
case ppt_mtc: return "MTC"; case ppt_cyc: return "CYC"; case ppt_ovf: return "OVF";
case ppt_stop: return "STOP"; case ppt_exstop: return "EXSTOP"; case ppt_mnt: return "MNT";
case ppt_ptw: return "PTW"; default: return "?";
}
}
static uint64_t
ReconstructIp(const struct pt_packet_ip * Packet, uint64_t * LastIp)
{
uint64_t Value = *LastIp;
switch (Packet->ipc)
{
case pt_ipc_update_16: Value = (Value & ~0xffffull) | (Packet->ip & 0xffffull); break;
case pt_ipc_update_32: Value = (Value & ~0xffffffffull) | (Packet->ip & 0xffffffffull); break;
case pt_ipc_update_48: Value = (Value & ~0xffffffffffffull) | (Packet->ip & 0xffffffffffffull); break;
case pt_ipc_sext_48:
Value = Packet->ip & 0xffffffffffffull;
if (Value & 0x800000000000ull)
Value |= 0xffff000000000000ull;
break;
default: Value = Packet->ip; break;
}
*LastIp = Value;
return Value;
}
static UINT64
DecodeCorePackets(UINT32 Cpu, const UINT8 * Buffer, UINT64 Size)
{
struct pt_config Config;
struct pt_packet_decoder * Decoder;
UINT64 Count = 0;
uint64_t LastIp = 0;
int Status;
pt_config_init(&Config);
Config.begin = (uint8_t *)Buffer;
Config.end = (uint8_t *)Buffer + Size;
Decoder = pt_pkt_alloc_decoder(&Config);
if (Decoder == NULL)
{
printf("[-] core %u: cannot allocate packet decoder\n", Cpu);
return 0;
}
for (;;)
{
Status = pt_pkt_sync_forward(Decoder);
if (Status < 0)
break;
for (;;)
{
struct pt_packet Packet;
Status = pt_pkt_next(Decoder, &Packet, sizeof(Packet));
if (Status < 0)
break;
Count++;
switch (Packet.type)
{
case ppt_tnt_8:
case ppt_tnt_64:
printf(" %-8s %2u ", PacketName(Packet.type), Packet.payload.tnt.bit_size);
for (uint8_t Bit = 0; Bit < Packet.payload.tnt.bit_size && Bit < 64; Bit++)
putchar(((Packet.payload.tnt.payload >> (Packet.payload.tnt.bit_size - 1 - Bit)) & 1) ? 'T' : 'N');
putchar('\n');
break;
case ppt_tip:
case ppt_fup:
case ppt_tip_pge:
case ppt_tip_pgd:
if (Packet.payload.ip.ipc == pt_ipc_suppressed)
printf(" %-8s (ip suppressed)\n", PacketName(Packet.type));
else
{
uint64_t Ip = ReconstructIp(&Packet.payload.ip, &LastIp);
printf(" %-8s 0x%016llx exe+0x%llx\n",
PacketName(Packet.type), (unsigned long long)Ip, (unsigned long long)(Ip - g_ImageBase));
}
break;
case ppt_pip:
printf(" %-8s cr3=0x%llx\n", PacketName(Packet.type), (unsigned long long)Packet.payload.pip.cr3);
break;
case ppt_cbr:
//printf(" %-8s ratio=%u\n", PacketName(Packet.type), Packet.payload.cbr.ratio);
break;
case ppt_tsc:
printf(" %-8s tsc=0x%llx\n", PacketName(Packet.type), (unsigned long long)Packet.payload.tsc.tsc);
break;
default:
//printf(" %-8s\n", PacketName(Packet.type));
break;
}
}
}
pt_pkt_free_decoder(Decoder);
return Count;
}
static UINT64
DecodeCore(UINT32 Cpu, const UINT8 * Buffer, UINT64 Size)
{
struct pt_config Config;
struct pt_insn_decoder * Decoder;
struct pt_image * Image;
UINT64 Count = 0;
int Status;
pt_config_init(&Config);
Config.begin = (uint8_t *)Buffer;
Config.end = (uint8_t *)Buffer + Size;
Decoder = pt_insn_alloc_decoder(&Config);
if (Decoder == NULL)
{
printf("[-] core %u: cannot allocate instruction decoder\n", Cpu);
return 0;
}
Image = pt_insn_get_image(Decoder);
pt_image_set_callback(Image, ReadImage, NULL);
for (;;)
{
Status = pt_insn_sync_forward(Decoder);
if (Status < 0)
break;
for (;;)
{
struct pt_insn Insn;
while (Status & pts_event_pending)
{
struct pt_event Event;
Status = pt_insn_event(Decoder, &Event, sizeof(Event));
if (Status < 0)
break;
}
if (Status < 0 || (Status & pts_eos))
break;
Status = pt_insn_next(Decoder, &Insn, sizeof(Insn));
if (Status < 0)
break;
ZydisDisassembledInstruction Disasm;
ZydisMachineMode Mode = (Insn.mode == ptem_32bit) ? ZYDIS_MACHINE_MODE_LEGACY_32 : ZYDIS_MACHINE_MODE_LONG_64;
if (ZYAN_SUCCESS(ZydisDisassembleIntel(Mode, Insn.ip, Insn.raw, Insn.size, &Disasm)))
printf(" 0x%016llx exe+0x%-6llx %s\n",
(unsigned long long)Insn.ip,
(unsigned long long)(Insn.ip - g_ImageBase),
Disasm.text);
else
printf(" 0x%016llx (undecodable)\n", (unsigned long long)Insn.ip);
Count++;
}
if (Status >= 0 && (Status & pts_eos))
break;
}
pt_insn_free_decoder(Decoder);
return Count;
}
static void
RunAndTrace(const char * Path, const char * Function, BOOLEAN Packets, int PinCore)
{
STARTUPINFOA Startup = {0};
PROCESS_INFORMATION Process = {0};
HYPERTRACE_PT_MMAP_PACKETS Mmap = {0};
HYPERTRACE_PT_OPERATION_PACKETS Sizes = {0};
UINT64 TextStart = 0;
UINT64 TextEnd = 0;
UINT64 FilterStart = 0;
UINT64 FilterEnd = 0;
UINT64 Total = 0;
Startup.cb = sizeof(Startup);
if (!CreateProcessA(Path, NULL, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &Startup, &Process))
{
printf("[-] cannot launch '%s' (error 0x%x)\n", Path, GetLastError());
return;
}
printf("[+] launched '%s' (pid %u, suspended)\n", Path, Process.dwProcessId);
if (PinCore >= 0)
{
DWORD_PTR Mask = (DWORD_PTR)1 << PinCore;
if (SetProcessAffinityMask(Process.hProcess, Mask))
printf("[+] pinned target to core %d (all trace should land on this core)\n", PinCore);
else
printf("[!] could not pin to core %d (error 0x%x); running unpinned\n", PinCore, GetLastError());
}
else
{
printf("[*] target unpinned (scheduler may migrate it across cores)\n");
}
if (!CaptureImage(Process.hProcess, &TextStart, &TextEnd))
{
printf("[-] cannot read target image / .text section\n");
TerminateProcess(Process.hProcess, 1);
goto Cleanup;
}
printf("[+] image base 0x%llx, .text 0x%llx-0x%llx (%llu bytes)\n",
(unsigned long long)g_ImageBase,
(unsigned long long)TextStart,
(unsigned long long)TextEnd,
(unsigned long long)g_CodeSize);
FilterStart = TextStart;
FilterEnd = TextEnd;
if (Function != NULL && ResolveFunction(Process.hProcess, Path, Function, &FilterStart, &FilterEnd)) {
printf("[+] IP filter narrowed to '%s' 0x%llx-0x%llx (%llu bytes)\n",
Function,
(unsigned long long)FilterStart,
(unsigned long long)FilterEnd,
(unsigned long long)(FilterEnd - FilterStart + 1));
}
else
{
printf("[!] IP filter: whole .text (symbol '%s' not found - build the target with a PDB)\n",
Function ? Function : "(none)");
}
if (!PtFilter(Process.dwProcessId, FilterStart, FilterEnd) ||
!PtOperation(HYPERTRACE_PT_OPERATION_REQUEST_TYPE_ENABLE))
{
printf("[-] cannot enable Intel PT\n");
TerminateProcess(Process.hProcess, 1);
goto Cleanup;
}
if (!hyperdbg_u_pt_mmap(&Mmap))
{
printf("[-] pt_mmap failed\n");
PtOperation(HYPERTRACE_PT_OPERATION_REQUEST_TYPE_DISABLE);
TerminateProcess(Process.hProcess, 1);
goto Cleanup;
}
printf("[+] PT enabled, %u per-core buffers mapped\n", Mmap.NumCpus);
printf("[*] resuming target and waiting for it to exit...\n");
ResumeThread(Process.hThread);
WaitForSingleObject(Process.hProcess, INFINITE);
printf("[+] target exited, decoding trace\n");
PtOperation(HYPERTRACE_PT_OPERATION_REQUEST_TYPE_PAUSE);
Sizes.PtOperationType = HYPERTRACE_PT_OPERATION_REQUEST_TYPE_SIZE;
if (!hyperdbg_u_pt_operation(&Sizes))
{
printf("[-] cannot query PT sizes\n");
PtOperation(HYPERTRACE_PT_OPERATION_REQUEST_TYPE_DISABLE);
goto Cleanup;
}
for (UINT32 i = 0; i < Mmap.NumCpus; i++)
{
UINT32 Cpu = Mmap.Cpus[i].CpuId;
UINT64 Bytes = (Cpu < Sizes.NumCpus) ? Sizes.BytesPerCpu[Cpu] : 0;
if (Bytes == 0)
continue;
if (Bytes > Mmap.Cpus[i].Size)
Bytes = Mmap.Cpus[i].Size;
printf("\n[*] core %u: %llu bytes of trace\n", Cpu, (unsigned long long)Bytes);
Total += Packets
? DecodeCorePackets(Cpu, (const UINT8 *)(ULONG_PTR)Mmap.Cpus[i].UserVa, Bytes)
: DecodeCore(Cpu, (const UINT8 *)(ULONG_PTR)Mmap.Cpus[i].UserVa, Bytes);
}
printf("\n[+] decoded %llu %s total\n", (unsigned long long)Total, Packets ? "packet(s)" : "instruction(s)");
PtOperation(HYPERTRACE_PT_OPERATION_REQUEST_TYPE_DISABLE);
Cleanup:
if (g_Code != NULL)
{
free(g_Code);
g_Code = NULL;
}
if (Process.hThread != NULL)
CloseHandle(Process.hThread);
if (Process.hProcess != NULL)
CloseHandle(Process.hProcess);
}
static int
LoadVmmAndTrace()
{
hyperdbg_u_set_text_message_callback((PVOID)ShowMessages);
if (!hyperdbg_u_detect_vmx_support())
{
printf("[-] VT-x (VMX) is not supported / enabled on this processor\n");
return 1;
}
printf("[*] loading HyperDbg VMM...\n");
if (hyperdbg_u_install_kd_driver() == 1 || hyperdbg_u_load_vmm() == 1)
{
printf("[-] cannot load the HyperDbg VMM\n");
return 1;
}
printf("[+] HyperDbg VMM is running\n");
printf("[*] loading HyperTrace...\n");
if ( hyperdbg_u_load_hypertrace_module() == 1)
{
printf("[-] cannot load the HyperDbg HyperTrace\n");
return 1;
}
printf("[+] HyperDbg HyperTrace is running\n");
return 0;
}
int
main2(int argc, char ** argv)
{
const char * function = "main";
BOOLEAN packets = FALSE;
int pinCore = 0;
if (argc < 2)
{
printf("HyperDbg Intel PT tracer\n");
printf("usage: %s <path-to-exe-that-exits> [function] [-p] [-c core]\n", argv[0]);
printf(" [function] symbol to IP-filter (default 'main'; pass '*' for whole .text)\n");
printf(" -p dump raw PT packets (TNT/TIP/FUP/PSB/...) instead of instructions\n");
printf(" -c core pin the target to this logical core (default 0; -1 = unpinned)\n");
return 1;
}
for (int i = 2; i < argc; i++)
{
if (strcmp(argv[i], "-p") == 0 || strcmp(argv[i], "--packets") == 0)
packets = TRUE;
else if (strcmp(argv[i], "-c") == 0 && i + 1 < argc)
pinCore = atoi(argv[++i]);
else if (strcmp(argv[i], "*") == 0)
function = NULL;
else
function = argv[i];
}
if (LoadVmmAndTrace() != 0)
{
return 1;
}
RunAndTrace(argv[1], function, packets, pinCore);
printf("[*] unloading HyperDbg VMM...\n");
//
// Unload the driver
//
hyperdbg_u_unload_vmm();
hyperdbg_u_unload_kd();
hyperdbg_u_stop_kd_driver();
hyperdbg_u_uninstall_kd_driver();
printf("[+] done\n");
return 0;
}

View file

@ -1,16 +0,0 @@
/**
* @file example-ipt.h
* @author Sina Karvandi (sina@hyperdbg.org)
* @brief Headers for Intel PT example
* @details
*
* @version 0.20
* @date 2026-06-13
*
* @copyright This project is released under the GNU Public License v3.
*
*/
#pragma once
int
main2(int argc, char** argv);

View file

@ -1,59 +0,0 @@
name: Continuous Integration
on:
push:
tags: ['*']
branches: ['main']
pull_request:
workflow_dispatch:
env:
verilator-version: v5.012
verilator-install-dir: verilator-install
jobs:
ci:
name: ci
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Cleanup
run: sed -i "s/%NAME%/test/g" build.sc
- name: Cache Scala
uses: coursier/cache-action@v6
- name: Setup Scala
uses: coursier/setup-action@v1
with:
jvm: adopt:11
apps: sbt mill
- name: Setup Dependencies
run: |
sudo apt-get install ccache
- name: Get Cached Verilator
id: get-cached-verilator
uses: actions/cache@v4
with:
path: ${{ env.verilator-install-dir }}
key: verilator-${{ env.verilator-version }}
- name: Install Verilator
if: steps.get-cached-verilator.outputs.cache-hit != 'true'
run: |
sudo apt-get install git help2man perl python3 make autoconf g++ flex bison numactl perl-doc libfl-dev
git clone https://github.com/verilator/verilator
unset VERILATOR_ROOT
cd verilator
git checkout ${{ env.verilator-version }}
autoconf
./configure --prefix=$(pwd)/../${{ env.verilator-install-dir }}
make
make install
- name: Set PATH
run: |
echo "$(pwd)/${{ env.verilator-install-dir }}/bin" >> $GITHUB_PATH
echo VERILATOR_ROOT="$(pwd)/${{ env.verilator-install-dir }}/share/verilator" >> $GITHUB_ENV
ln -sf $(pwd)/${{ env.verilator-install-dir }}/bin/verilator_bin $(pwd)/${{ env.verilator-install-dir }}/share/verilator/verilator_bin
- name: SBT Test
run: sbt test
- name: mill Test
run: mill _.test

366
hwdbg/.gitignore vendored
View file

@ -1,366 +0,0 @@
### Project Specific stuff
test_run_dir/*
### XilinxISE template
# intermediate build files
*.bgn
*.bit
*.bld
*.cmd_log
*.drc
*.ll
*.lso
*.msd
*.msk
*.ncd
*.ngc
*.ngd
*.ngr
*.pad
*.par
*.pcf
*.prj
*.ptwx
*.rbb
*.rbd
*.stx
*.syr
*.twr
*.twx
*.unroutes
*.ut
*.xpi
*.xst
*_bitgen.xwbt
*_envsettings.html
*_map.map
*_map.mrp
*_map.ngm
*_map.xrpt
*_ngdbuild.xrpt
*_pad.csv
*_pad.txt
*_par.xrpt
*_summary.html
*_summary.xml
*_usage.xml
*_xst.xrpt
# project-wide generated files
*.gise
par_usage_statistics.html
usage_statistics_webtalk.html
webtalk.log
webtalk_pn.xml
# generated folders
iseconfig/
xlnx_auto_0_xdb/
xst/
_ngo/
_xmsgs/
### Eclipse template
*.pydevproject
.metadata
.gradle
bin/
tmp/
*.tmp
*.bak
*.swp
*~.nib
local.properties
.settings/
.loadpath
# Eclipse Core
.project
# External tool builders
.externalToolBuilders/
# Locally stored "Eclipse launch configurations"
*.launch
# CDT-specific
.cproject
# JDT-specific (Eclipse Java Development Tools)
.classpath
# Java annotation processor (APT)
.factorypath
# PDT-specific
.buildpath
# sbteclipse plugin
.target
# TeXlipse plugin
.texlipse
### C template
# Object files
*.o
*.ko
*.obj
*.elf
# Precompiled Headers
*.gch
*.pch
# Libraries
*.lib
*.a
*.la
*.lo
# Shared objects (inc. Windows DLLs)
*.dll
*.so
*.so.*
*.dylib
# Executables
*.exe
*.out
*.app
*.i*86
*.x86_64
*.hex
# Debug files
*.dSYM/
### SBT template
# Simple Build Tool
# http://www.scala-sbt.org/release/docs/Getting-Started/Directories.html#configuring-version-control
target/
lib_managed/
src_managed/
project/boot/
.history
.cache
### Emacs template
# -*- mode: gitignore; -*-
*~
\#*\#
/.emacs.desktop
/.emacs.desktop.lock
*.elc
auto-save-list
tramp
.\#*
# Org-mode
.org-id-locations
*_archive
# flymake-mode
*_flymake.*
# eshell files
/eshell/history
/eshell/lastdir
# elpa packages
/elpa/
# reftex files
*.rel
# AUCTeX auto folder
/auto/
# cask packages
.cask/
### Vim template
[._]*.s[a-w][a-z]
[._]s[a-w][a-z]
*.un~
Session.vim
.netrwhist
*~
### JetBrains template
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio
*.iml
## Directory-based project format:
.idea/
# if you remove the above rule, at least ignore the following:
# User-specific stuff:
# .idea/workspace.xml
# .idea/tasks.xml
# .idea/dictionaries
# Sensitive or high-churn files:
# .idea/dataSources.ids
# .idea/dataSources.xml
# .idea/sqlDataSources.xml
# .idea/dynamic.xml
# .idea/uiDesigner.xml
# Gradle:
# .idea/gradle.xml
# .idea/libraries
# Mongo Explorer plugin:
# .idea/mongoSettings.xml
## File-based project format:
*.ipr
*.iws
## Plugin-specific files:
# IntelliJ
/out/
# mpeltonen/sbt-idea plugin
.idea_modules/
# JIRA plugin
atlassian-ide-plugin.xml
# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
### C++ template
# Compiled Object files
*.slo
*.lo
*.o
*.obj
# Precompiled Headers
*.gch
*.pch
# Compiled Dynamic libraries
*.so
*.dylib
*.dll
# Fortran module files
*.mod
# Compiled Static libraries
*.lai
*.la
*.a
*.lib
# Executables
*.exe
*.out
*.app
### OSX template
.DS_Store
.AppleDouble
.LSOverride
# Icon must end with two \r
Icon
# Thumbnails
._*
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
### Xcode template
# Xcode
#
# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
## Build generated
build/
DerivedData
## Various settings
*.pbxuser
!default.pbxuser
*.mode1v3
!default.mode1v3
*.mode2v3
!default.mode2v3
*.perspectivev3
!default.perspectivev3
xcuserdata
## Other
*.xccheckout
*.moved-aside
*.xcuserstate
### Scala template
*.class
*.log
/.bsp
# sbt specific
.cache
.history
.lib/
dist/*
target/
lib_managed/
src_managed/
project/boot/
project/plugins/project/
# Scala-IDE specific
.scala_dependencies
.worksheet
### Java template
*.class
# Mobile Tools for Java (J2ME)
.mtj.tmp/
# Package Files #
*.jar
*.war
*.ear
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
# Visual Studio Code
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
!.vscode/*.code-snippets
# Local History for Visual Studio Code
.history/
# Built Visual Studio Code Extensions
*.vsix
# Scala metals
.metals/*
# Scala metals
.bloop/
# Temporary disable the generated verilog files
generated/
# BRAM emulation content
# bram_instance_info.txt

View file

@ -1 +0,0 @@
0.11.5

View file

@ -1,5 +0,0 @@
version = "3.8.1"
runner.dialect = scala213
maxColumn = 150
docstrings.style = Asterisk
docstrings.oneline = unfold

View file

@ -1,76 +0,0 @@
# Contributor Covenant Code of Conduct
## Our Pledge
In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to making participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, sex characteristics, gender identity and expression,
level of experience, education, socio-economic status, nationality, personal
appearance, race, religion, or sexual identity and orientation.
## Our Standards
Examples of behavior that contributes to creating a positive environment
include:
* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or
advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic
address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or
reject comments, commits, code, wiki edits, issues, and other contributions
that are not aligned to this Code of Conduct, or to ban temporarily or
permanently any contributor for other behaviors that they deem inappropriate,
threatening, offensive, or harmful.
## Scope
This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community. Examples of
representing a project or community include using an official project e-mail
address, posting via an official social media account, or acting as an appointed
representative at an online or offline event. Representation of a project may be
further defined and clarified by project maintainers.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at sina@rayanfam.com. All
complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident.
Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by other
members of the project's leadership.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
[homepage]: https://www.contributor-covenant.org
For answers to common questions about this code of conduct, see
https://www.contributor-covenant.org/faq

View file

@ -1,674 +0,0 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
<program> Copyright (C) <year> <name of author>
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<https://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<https://www.gnu.org/licenses/why-not-lgpl.html>.

View file

@ -1,121 +0,0 @@
<p align="center">
<img alt="hwdbg" title="hwdbg" src="https://github.com/HyperDbg/graphics/blob/master/Logos/hwdbg/hwdbg-high-resolution-logo-transparent.png?raw=true" width="300">
</p>
<p align="left">
<a href="https://hwdbg.hyperdbg.org"><img src="https://raw.githubusercontent.com/HyperDbg/graphics/master/Badges/Link-Website-orange.svg" alt="Website"></a>
<a href="https://hwdbg.hyperdbg.org/docs"><img src="https://raw.githubusercontent.com/HyperDbg/graphics/master/Badges/Link-Docs-yellow.svg" alt="Docs"></a>
<a href="https://hwdbg.hyperdbg.org/api"><img src="https://raw.githubusercontent.com/HyperDbg/graphics/master/Badges/Link-API-green.svg" alt="API"></a>
<a href="https://research.hyperdbg.org"><img src="https://raw.githubusercontent.com/HyperDbg/graphics/master/Badges/Link-Research-pink.svg" alt="Published Researches"></a>
<a href="https://www.gnu.org/licenses/gpl-3.0"><img src="https://raw.githubusercontent.com/HyperDbg/graphics/master/Badges/License-GPLv3-blue.svg" alt="License"></a>
</p>
## Description
The **hwdbg** debugger chip generator is a gate-level debugging tool designed to make configurable and synthesizable hardware debuggers for white-box and black-box chip fuzzing, testing, and reverse engineering. The primary goal of **hwdbg** is to provide control over hardware, enabling monitoring and modification of signals down to the granular level of a single clock cycle. It is written in Chisel and Verilog.
- ⚠️ This project is a work in progress and is not yet ready for testing.
**hwdbg** is a highly customizable debugger designed to ease hardware debugging by bringing software debugging concepts into the hardware debugging domain. **hwdbg** aims to help with the complexities associated with debugging hardware, including chips and IP cores. Key features of **hwdbg** include the ability to step through the hardware design at the clock-cycle level, visualize waveforms, inspect values (e.g., like a logical analyzer), and modify signals. Moreover, it is synthesizable into [FPGAs](https://github.com/HyperDbg/hwdbg-fpga) and has the potential for fabrication into physical chips.
```
┏━━━━━━━━━━━━━━━━━━━━━━━┓
_ _ _ ┃
| |_ _ _ _ _| || |_ ___ ┃
| . || | | |/ . || . \/ . | ┃
|_|_||__/_/ \___||___/\_. | ┃
<___'
|、
HyperDbg's chip-level debugger ┃ (˚ˎ 。7
┃ |、 ˜〵
┗━━━━━━━━━━━━━━━━━━━━━━━┛ じしˍ,)
```
## Publications
In case you use **hwdbg** in your work, please consider citing our paper.
**[hwdbg: Debugging Hardware Like Software (EuroSec'25)](https://dl.acm.org/doi/abs/10.1145/3722041.3723101)** [[PDF](https://dl.acm.org/doi/pdf/10.1145/3722041.3723101)]
```
@inproceedings{karvandi2025hwdbg,
title={hwdbg: Debugging Hardware Like Software},
author={Karvandi, Mohammad Sina and Meghdadizanjani, Soroush and Monfared, Saleh Khalaj and van der Kouwe, Erik and Slowinska, Asia},
booktitle={Proceedings of the 18th European Workshop on Systems Security},
pages={56--62},
year={2025}
}
```
## Deployment Board
[This repository](https://github.com/HyperDbg/hwdbg-fpga) contains pre-built TCL files to facilitate project creation for running **hwdbg** on various FPGA development boards.
## Output
For generating SystemVerilog files, you need to install [Chisel](https://www.chisel-lang.org/docs/installation). Once installed, use the following commands:
```sh
$ sbt run
```
This command prompts you to select a component. The `hwdbg.Main` class contains the debugger for synthesis purposes, while the `hwdbg.MainWithInitializedBRAM` class includes a pre-initialized Block RAM (BRAM), primarily for simulation and testing.
After selecting the appropriate class for synthesis (option `1`) or simulation (option `2`), the output should look like this:
```sh
$ sbt run
[info] welcome to sbt 1.9.7 (Eclipse Adoptium Java 17.0.10)
[info] loading settings for project -build-build-build from metals.sbt ...
[info] loading project definition from /home/sina/HyperDbg//project/project/project
[info] loading settings for project -build-build from metals.sbt ...
[info] loading project definition from /home/sina/HyperDbg//project/project
[success] Generated .bloop/-build-build.json
[success] Total time: 1 s, completed Apr 16, 2024, 1:49:05 PM
[info] loading settings for project -build from metals.sbt,plugins.sbt ...
[info] loading project definition from /home/sina/HyperDbg//project
[success] Total time: 0 s, completed Apr 16, 2024, 1:49:05 PM
[info] loading settings for project root from build.sbt ...
[info] set current project to hwdbg (in build file:/home/sina/HyperDbg/hwdbg/)
Multiple main classes detected. Select one to run:
[1] hwdbg.Main
[2] hwdbg.MainWithInitializedBRAM
Enter number: 2
[info] running hwdbg.MainWithInitializedBRAM
```
The generated code for the debugger can be found in the `generated` directory.
## Testbenches
To test **hwdbg**, [cocotb](https://www.cocotb.org/) should be installed. After that, first, run the debugger (generated SystemVerilog files) and then run the following commands:
```sh
cd sim/hwdbg/DebuggerModuleTestingBRAM
./test.sh
```
The above command generates a waves file at `./sim/hwdbg/DebuggerModuleTestingBRAM/sim_build/DebuggerModuleTestingBRAM.fst` which can be read using [GTKWave](https://gtkwave.sourceforge.net/).
```sh
cd sim/hwdbg/DebuggerModuleTestingBRAM
gtkwave ./sim_build/DebuggerModuleTestingBRAM.fst
```
### ModelSim
If you prefer to use ModelSim instead of GTKWave, you can configure the `modelsim.config` file. Please visit <a href="https://github.com/HyperDbg/hwdbg/blob/main/sim/modelsim/README.md">here</a> for more information.
## API
If you want to create the latest version of API documentation, you can run the following command:
```sh
$ sbt doc
```
This will generate documentation at `./target/scala-{version}/api/index.html`.
## License
**hwdbg** and all its submodules and repos, unless a license is otherwise specified, are licensed under **GPLv3** LICENSE.

View file

@ -1,29 +0,0 @@
// See README.md for license details.
ThisBuild / scalaVersion := "2.13.12"
ThisBuild / version := "0.1.0"
ThisBuild / organization := "org.hyperdbg"
val chiselVersion = "6.2.0"
lazy val root = (project in file("."))
.settings(
name := "hwdbg",
libraryDependencies ++= Seq(
"org.chipsalliance" %% "chisel" % chiselVersion,
"org.scalatest" %% "scalatest" % "3.2.16" % "test",
"io.circe" %% "circe-core" % "0.14.3",
"io.circe" %% "circe-generic" % "0.14.3",
"io.circe" %% "circe-parser" % "0.14.3"
),
scalacOptions ++= Seq(
"-language:reflectiveCalls",
"-deprecation",
"-feature",
"-Xcheckinit",
"-Ymacro-annotations"
),
addCompilerPlugin(
"org.chipsalliance" % "chisel-plugin" % chiselVersion cross CrossVersion.full
)
)

View file

@ -1,30 +0,0 @@
// import Mill dependency
import mill._
import mill.define.Sources
import mill.modules.Util
import mill.scalalib.TestModule.ScalaTest
import scalalib._
// support BSP
import mill.bsp._
object hwdbg extends SbtModule { m =>
override def millSourcePath = os.pwd
override def scalaVersion = "2.13.12"
override def scalacOptions = Seq(
"-language:reflectiveCalls",
"-deprecation",
"-feature",
"-Xcheckinit",
)
override def ivyDeps = Agg(
ivy"org.chipsalliance::chisel:6.0.0",
)
override def scalacPluginIvyDeps = Agg(
ivy"org.chipsalliance:::chisel-plugin:6.0.0",
)
object test extends SbtModuleTests with TestModule.ScalaTest {
override def ivyDeps = m.ivyDeps() ++ Agg(
ivy"org.scalatest::scalatest::3.2.16"
)
}
}

View file

@ -1 +0,0 @@
sbt.version = 1.9.7

View file

@ -1,8 +0,0 @@
// format: off
// DO NOT EDIT! This file is auto-generated.
// This file enables sbt-bloop to create bloop config files.
addSbtPlugin("ch.epfl.scala" % "sbt-bloop" % "1.5.18")
// format: on

View file

@ -1 +0,0 @@
logLevel := Level.Warn

View file

@ -1,8 +0,0 @@
// format: off
// DO NOT EDIT! This file is auto-generated.
// This file enables sbt-bloop to create bloop config files.
addSbtPlugin("ch.epfl.scala" % "sbt-bloop" % "1.5.18")
// format: on

View file

@ -1,8 +0,0 @@
// format: off
// DO NOT EDIT! This file is auto-generated.
// This file enables sbt-bloop to create bloop config files.
addSbtPlugin("ch.epfl.scala" % "sbt-bloop" % "1.5.18")
// format: on

164
hwdbg/sim/.gitignore vendored
View file

@ -1,164 +0,0 @@
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
.pybuilder/
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# .python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# poetry
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
# This is especially recommended for binary packages to ensure reproducibility, and is more
# commonly ignored for libraries.
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
#poetry.lock
# pdm
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
#pdm.lock
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
# in version control.
# https://pdm.fming.dev/#use-with-ide
.pdm.toml
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
__pypackages__/
# Celery stuff
celerybeat-schedule
celerybeat.pid
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
# pytype static type analyzer
.pytype/
# Cython debug symbols
cython_debug/
# PyCharm
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/
# cocotb folders and files
sim_build/
results.xml

View file

@ -1,23 +0,0 @@
# Makefile
TOPLEVEL_LANG = verilog
VERILOG_SOURCES += $(shell pwd)/../../../generated/DebuggerModuleTestingBRAM.sv
VERILOG_SOURCES += $(shell pwd)/../../../generated/InitRegMemFromFile.sv
VERILOG_SOURCES += $(shell pwd)/../../../generated/DebuggerMain.sv
VERILOG_SOURCES += $(shell pwd)/../../../generated/SendReceiveSynchronizer.sv
VERILOG_SOURCES += $(shell pwd)/../../../generated/DebuggerPacketReceiver.sv
VERILOG_SOURCES += $(shell pwd)/../../../generated/DebuggerPacketSender.sv
VERILOG_SOURCES += $(shell pwd)/../../../generated/DebuggerPacketInterpreter.sv
VERILOG_SOURCES += $(shell pwd)/../../../generated/InterpreterInstanceInfo.sv
VERILOG_SOURCES += $(shell pwd)/../../../generated/InterpreterSendSuccessOrError.sv
VERILOG_SOURCES += $(shell pwd)/../../../generated/ScriptExecutionEngine.sv
VERILOG_SOURCES += $(shell pwd)/../../../generated/InterpreterScriptBufferHandler.sv
VERILOG_SOURCES += $(shell pwd)/../../../generated/ScriptEngineGetValue.sv
VERILOG_SOURCES += $(shell pwd)/../../../generated/ScriptEngineSetValue.sv
VERILOG_SOURCES += $(shell pwd)/../../../generated/ScriptEngineEval.sv
TOPLEVEL = DebuggerModuleTestingBRAM
MODULE = test_DebuggerModuleTestingBRAM
include $(shell cocotb-config --makefiles)/Makefile.sim

View file

@ -1,261 +0,0 @@
Content of BRAM after emulation:
PS to PL area:
mem_0: 0000005a | Checksum
mem_1: 00000000 | Checksum
mem_2: 52444247 | Indicator
mem_3: 48595045 | Indicator
mem_4: 00000004 | TypeOfThePacket
mem_5: 00000001 | RequestedActionOfThePacket
mem_6: 00000000 | Start of Optional Data
mem_7: 00000000
mem_8: 00000000
mem_9: 00000000
mem_10: 00000000
mem_11: 00000000
mem_12: 00000000
mem_13: 00000000
mem_14: 00000000
mem_15: 00000000
mem_16: 00000000
mem_17: 00000000
mem_18: 00000000
mem_19: 00000000
mem_20: 00000000
mem_21: 00000000
mem_22: 00000000
mem_23: 00000000
mem_24: 00000000
mem_25: 00000000
mem_26: 00000000
mem_27: 00000000
mem_28: 00000000
mem_29: 00000000
mem_30: 00000000
mem_31: 00000000
mem_32: 00000000
mem_33: 00000000
mem_34: 00000000
mem_35: 00000000
mem_36: 00000000
mem_37: 00000000
mem_38: 00000000
mem_39: 00000000
mem_40: 00000000
mem_41: 00000000
mem_42: 00000000
mem_43: 00000000
mem_44: 00000000
mem_45: 00000000
mem_46: 00000000
mem_47: 00000000
mem_48: 00000000
mem_49: 00000000
mem_50: 00000000
mem_51: 00000000
mem_52: 00000000
mem_53: 00000000
mem_54: 00000000
mem_55: 00000000
mem_56: 00000000
mem_57: 00000000
mem_58: 00000000
mem_59: 00000000
mem_60: 00000000
mem_61: 00000000
mem_62: 00000000
mem_63: 00000000
mem_64: 00000000
mem_65: 00000000
mem_66: 00000000
mem_67: 00000000
mem_68: 00000000
mem_69: 00000000
mem_70: 00000000
mem_71: 00000000
mem_72: 00000000
mem_73: 00000000
mem_74: 00000000
mem_75: 00000000
mem_76: 00000000
mem_77: 00000000
mem_78: 00000000
mem_79: 00000000
mem_80: 00000000
mem_81: 00000000
mem_82: 00000000
mem_83: 00000000
mem_84: 00000000
mem_85: 00000000
mem_86: 00000000
mem_87: 00000000
mem_88: 00000000
mem_89: 00000000
mem_90: 00000000
mem_91: 00000000
mem_92: 00000000
mem_93: 00000000
mem_94: 00000000
mem_95: 00000000
mem_96: 00000000
mem_97: 00000000
mem_98: 00000000
mem_99: 00000000
mem_100: 00000000
mem_101: 00000000
mem_102: 00000000
mem_103: 00000000
mem_104: 00000000
mem_105: 00000000
mem_106: 00000000
mem_107: 00000000
mem_108: 00000000
mem_109: 00000000
mem_110: 00000000
mem_111: 00000000
mem_112: 00000000
mem_113: 00000000
mem_114: 00000000
mem_115: 00000000
mem_116: 00000000
mem_117: 00000000
mem_118: 00000000
mem_119: 00000000
mem_120: 00000000
mem_121: 00000000
mem_122: 00000000
mem_123: 00000000
mem_124: 00000000
mem_125: 00000000
mem_126: 00000000
mem_127: 00000000
PL to PS area:
mem_128: 00000000 | Checksum
mem_129: 00000000 | Checksum
mem_130: 52444247 | Indicator
mem_131: 48595045 | Indicator
mem_132: 00000005 | TypeOfThePacket
mem_133: 00000002 | RequestedActionOfThePacket
mem_134: 00000100 | Start of Optional Data
mem_135: 00000020
mem_136: 00000008
mem_137: 00000002
mem_138: 00000002
mem_139: 00000002
mem_140: 00000001
mem_141: 00000400
mem_142: 00000000
mem_143: 00000200
mem_144: 00000020
mem_145: 00000002
mem_146: 01ff9efb
mem_147: 00000000
mem_148: 0000000d
mem_149: 00000020
mem_150: 0000000c
mem_151: 00000014
mem_152: 00000000
mem_153: 00000000
mem_154: 00000000
mem_155: 00000000
mem_156: 00000000
mem_157: 00000000
mem_158: 00000000
mem_159: 00000000
mem_160: 00000000
mem_161: 00000000
mem_162: 00000000
mem_163: 00000000
mem_164: 00000000
mem_165: 00000000
mem_166: 00000000
mem_167: 00000000
mem_168: 00000000
mem_169: 00000000
mem_170: 00000000
mem_171: 00000000
mem_172: 00000000
mem_173: 00000000
mem_174: 00000000
mem_175: 00000000
mem_176: 00000000
mem_177: 00000000
mem_178: 00000000
mem_179: 00000000
mem_180: 00000000
mem_181: 00000000
mem_182: 00000000
mem_183: 00000000
mem_184: 00000000
mem_185: 00000000
mem_186: 00000000
mem_187: 00000000
mem_188: 00000000
mem_189: 00000000
mem_190: 00000000
mem_191: 00000000
mem_192: 00000000
mem_193: 00000000
mem_194: 00000000
mem_195: 00000000
mem_196: 00000000
mem_197: 00000000
mem_198: 00000000
mem_199: 00000000
mem_200: 00000000
mem_201: 00000000
mem_202: 00000000
mem_203: 00000000
mem_204: 00000000
mem_205: 00000000
mem_206: 00000000
mem_207: 00000000
mem_208: 00000000
mem_209: 00000000
mem_210: 00000000
mem_211: 00000000
mem_212: 00000000
mem_213: 00000000
mem_214: 00000000
mem_215: 00000000
mem_216: 00000000
mem_217: 00000000
mem_218: 00000000
mem_219: 00000000
mem_220: 00000000
mem_221: 00000000
mem_222: 00000000
mem_223: 00000000
mem_224: 00000000
mem_225: 00000000
mem_226: 00000000
mem_227: 00000000
mem_228: 00000000
mem_229: 00000000
mem_230: 00000000
mem_231: 00000000
mem_232: 00000000
mem_233: 00000000
mem_234: 00000000
mem_235: 00000000
mem_236: 00000000
mem_237: 00000000
mem_238: 00000000
mem_239: 00000000
mem_240: 00000000
mem_241: 00000000
mem_242: 00000000
mem_243: 00000000
mem_244: 00000000
mem_245: 00000000
mem_246: 00000000
mem_247: 00000000
mem_248: 00000000
mem_249: 00000000
mem_250: 00000000
mem_251: 00000000
mem_252: 00000000
mem_253: 00000000
mem_254: 00000000
mem_255: 00000000

View file

@ -1,261 +0,0 @@
Content of BRAM after emulation:
PS to PL area:
mem_0: 00000017 | Checksum
mem_1: 00000000 | Checksum
mem_2: 52444247 | Indicator
mem_3: 48595045 | Indicator
mem_4: 00000004 | TypeOfThePacket
mem_5: 00000002 | RequestedActionOfThePacket
mem_6: 00000033 | Start of Optional Data
mem_7: 00000006
mem_8: 0000000a
mem_9: 00000003
mem_10: 00000001
mem_11: 0000000f
mem_12: 00000000
mem_13: 0000000f
mem_14: 00000000
mem_15: 00000006
mem_16: 00000013
mem_17: 00000003
mem_18: 00000001
mem_19: 00000004
mem_20: 00000000
mem_21: 00000007
mem_22: 00000000
mem_23: 00000006
mem_24: 00000016
mem_25: 00000003
mem_26: 00000013
mem_27: 00000007
mem_28: 00000000
mem_29: 00000000
mem_30: 00000000
mem_31: 00000006
mem_32: 00000018
mem_33: 00000003
mem_34: 00000000
mem_35: 00000000
mem_36: 00000000
mem_37: 00000004
mem_38: 00000002
mem_39: 00000006
mem_40: 00000018
mem_41: 00000003
mem_42: 00000000
mem_43: 00000000
mem_44: 00000000
mem_45: 00000004
mem_46: 00000003
mem_47: 00000006
mem_48: 00000015
mem_49: 00000003
mem_50: 00000028
mem_51: 00000000
mem_52: 00000000
mem_53: 00000000
mem_54: 00000000
mem_55: 00000006
mem_56: 00000013
mem_57: 00000003
mem_58: 00000001
mem_59: 00000004
mem_60: 00000001
mem_61: 00000007
mem_62: 00000000
mem_63: 00000006
mem_64: 00000016
mem_65: 00000003
mem_66: 00000022
mem_67: 00000007
mem_68: 00000000
mem_69: 00000000
mem_70: 00000000
mem_71: 00000006
mem_72: 00000018
mem_73: 00000003
mem_74: 00000000
mem_75: 00000000
mem_76: 00000000
mem_77: 00000004
mem_78: 00000004
mem_79: 00000006
mem_80: 00000018
mem_81: 00000003
mem_82: 00000000
mem_83: 00000000
mem_84: 00000000
mem_85: 00000004
mem_86: 00000005
mem_87: 00000006
mem_88: 00000015
mem_89: 00000003
mem_90: 00000028
mem_91: 00000000
mem_92: 00000000
mem_93: 00000000
mem_94: 00000000
mem_95: 00000006
mem_96: 00000018
mem_97: 00000003
mem_98: 00000000
mem_99: 00000000
mem_100: 00000000
mem_101: 00000004
mem_102: 00000006
mem_103: 00000006
mem_104: 00000018
mem_105: 00000003
mem_106: 00000000
mem_107: 00000000
mem_108: 00000000
mem_109: 00000004
mem_110: 00000007
mem_111: 00000000
mem_112: 00000000
mem_113: 00000000
mem_114: 00000000
mem_115: 00000000
mem_116: 00000000
mem_117: 00000000
mem_118: 00000000
mem_119: 00000000
mem_120: 00000000
mem_121: 00000000
mem_122: 00000000
mem_123: 00000000
mem_124: 00000000
mem_125: 00000000
mem_126: 00000000
mem_127: 00000000
PL to PS area:
mem_128: 00000000 | Checksum
mem_129: 00000000 | Checksum
mem_130: 52444247 | Indicator
mem_131: 48595045 | Indicator
mem_132: 00000005 | TypeOfThePacket
mem_133: 00000001 | RequestedActionOfThePacket
mem_134: 7fffffff | Start of Optional Data
mem_135: 00000000
mem_136: 00000000
mem_137: 00000000
mem_138: 00000000
mem_139: 00000000
mem_140: 00000000
mem_141: 00000000
mem_142: 00000000
mem_143: 00000000
mem_144: 00000000
mem_145: 00000000
mem_146: 00000000
mem_147: 00000000
mem_148: 00000000
mem_149: 00000000
mem_150: 00000000
mem_151: 00000000
mem_152: 00000000
mem_153: 00000000
mem_154: 00000000
mem_155: 00000000
mem_156: 00000000
mem_157: 00000000
mem_158: 00000000
mem_159: 00000000
mem_160: 00000000
mem_161: 00000000
mem_162: 00000000
mem_163: 00000000
mem_164: 00000000
mem_165: 00000000
mem_166: 00000000
mem_167: 00000000
mem_168: 00000000
mem_169: 00000000
mem_170: 00000000
mem_171: 00000000
mem_172: 00000000
mem_173: 00000000
mem_174: 00000000
mem_175: 00000000
mem_176: 00000000
mem_177: 00000000
mem_178: 00000000
mem_179: 00000000
mem_180: 00000000
mem_181: 00000000
mem_182: 00000000
mem_183: 00000000
mem_184: 00000000
mem_185: 00000000
mem_186: 00000000
mem_187: 00000000
mem_188: 00000000
mem_189: 00000000
mem_190: 00000000
mem_191: 00000000
mem_192: 00000000
mem_193: 00000000
mem_194: 00000000
mem_195: 00000000
mem_196: 00000000
mem_197: 00000000
mem_198: 00000000
mem_199: 00000000
mem_200: 00000000
mem_201: 00000000
mem_202: 00000000
mem_203: 00000000
mem_204: 00000000
mem_205: 00000000
mem_206: 00000000
mem_207: 00000000
mem_208: 00000000
mem_209: 00000000
mem_210: 00000000
mem_211: 00000000
mem_212: 00000000
mem_213: 00000000
mem_214: 00000000
mem_215: 00000000
mem_216: 00000000
mem_217: 00000000
mem_218: 00000000
mem_219: 00000000
mem_220: 00000000
mem_221: 00000000
mem_222: 00000000
mem_223: 00000000
mem_224: 00000000
mem_225: 00000000
mem_226: 00000000
mem_227: 00000000
mem_228: 00000000
mem_229: 00000000
mem_230: 00000000
mem_231: 00000000
mem_232: 00000000
mem_233: 00000000
mem_234: 00000000
mem_235: 00000000
mem_236: 00000000
mem_237: 00000000
mem_238: 00000000
mem_239: 00000000
mem_240: 00000000
mem_241: 00000000
mem_242: 00000000
mem_243: 00000000
mem_244: 00000000
mem_245: 00000000
mem_246: 00000000
mem_247: 00000000
mem_248: 00000000
mem_249: 00000000
mem_250: 00000000
mem_251: 00000000
mem_252: 00000000
mem_253: 00000000
mem_254: 00000000
mem_255: 00000000

View file

@ -1 +0,0 @@
make SIM=icarus WAVES=1

View file

@ -1,570 +0,0 @@
##
# @file test_DebuggerModuleTestingBRAM.py
#
# @author Sina Karvandi (sina@hyperdbg.org)
#
# @brief Testing module for DebuggerModuleTestingBRAM
#
# @details
#
# @version 0.1
#
# @date 2024-04-21
#
# @copyright This project is released under the GNU Public License v3.
#
import random
import re
import cocotb
from cocotb.clock import Clock
from cocotb.triggers import Timer
from cocotb.types import LogicArray
maximum_number_of_clock_cycles = 1000
'''
input clock,
reset,
io_en,
io_inputPin_0,
io_inputPin_1,
io_inputPin_2,
io_inputPin_3,
io_inputPin_4,
io_inputPin_5,
io_inputPin_6,
io_inputPin_7,
io_inputPin_8,
io_inputPin_9,
io_inputPin_10,
io_inputPin_11,
io_inputPin_12,
io_inputPin_13,
io_inputPin_14,
io_inputPin_15,
io_inputPin_16,
io_inputPin_17,
io_inputPin_18,
io_inputPin_19,
io_inputPin_20,
io_inputPin_21,
io_inputPin_22,
io_inputPin_23,
io_inputPin_24,
io_inputPin_25,
io_inputPin_26,
io_inputPin_27,
io_inputPin_28,
io_inputPin_29,
io_inputPin_30,
io_inputPin_31,
output io_outputPin_0,
io_outputPin_1,
io_outputPin_2,
io_outputPin_3,
io_outputPin_4,
io_outputPin_5,
io_outputPin_6,
io_outputPin_7,
io_outputPin_8,
io_outputPin_9,
io_outputPin_10,
io_outputPin_11,
io_outputPin_12,
io_outputPin_13,
io_outputPin_14,
io_outputPin_15,
io_outputPin_16,
io_outputPin_17,
io_outputPin_18,
io_outputPin_19,
io_outputPin_20,
io_outputPin_21,
io_outputPin_22,
io_outputPin_23,
io_outputPin_24,
io_outputPin_25,
io_outputPin_26,
io_outputPin_27,
io_outputPin_28,
io_outputPin_29,
io_outputPin_30,
io_outputPin_31,
input io_plInSignal,
output io_psOutInterrupt
'''
#
# Define a function to extract the numeric part of the string
#
def extract_number(s):
return int(s.split('_')[1])
def print_bram_content(dut):
"""Printing contents of Block RAM and saving them to a file"""
#
# Print the instances and signals (which includes the ports) of the design's toplevel
#
print("===================================================================")
# print("Onstances and signals (which includes the ports) of the design's toplevel:")
# print(dir(dut))
# print("===================================================================")
#
# Print the instances and signals of "inst_sub_block" under the toplevel
# which is the instance name of a Verilog module or VHDL entity/component
#
# print("Onstances and signals of 'dataOut_initRegMemFromFileModule' under the toplevel:")
# print(dir(dut.dataOut_initRegMemFromFileModule))
items_inside_bram_emulator = dir(dut.dataOut_initRegMemFromFileModule)
mem_items = []
for item in items_inside_bram_emulator:
if item.startswith("mem_"):
mem_items.append(item)
#
# Sort the list using the custom key function
#
sorted_list = sorted(mem_items, key=extract_number)
with open("script_buffer_response.txt", "w") as file:
# with open("bram_instance_info.txt", "w") as file:
file.write("Content of BRAM after emulation:\n")
print("Content of BRAM after emulation:")
#
# The second half of the BRAM is used for PL to PS communication
#
address_of_ps_to_pl_communication = "mem_0"
address_of_ps_to_pl_communication_checksum1 = "mem_0"
address_of_ps_to_pl_communication_checksum2 = "mem_1"
address_of_ps_to_pl_communication_indicator1 = "mem_2"
address_of_ps_to_pl_communication_indicator2 = "mem_3"
address_of_ps_to_pl_communication_type_of_packet = "mem_4"
address_of_ps_to_pl_communication_requested_action_of_the_packet = "mem_5"
address_of_ps_to_pl_communication_start_of_data = "mem_6"
len_of_sorted_list_div_by_2 = int(len(sorted_list) / 2)
address_of_pl_to_ps_communication = "mem_" + str(len_of_sorted_list_div_by_2)
address_of_pl_to_ps_communication_checksum1 = "mem_" + str(len_of_sorted_list_div_by_2 + 0)
address_of_pl_to_ps_communication_checksum2 = "mem_" + str(len_of_sorted_list_div_by_2 + 1)
address_of_pl_to_ps_communication_indicator1 = "mem_" + str(len_of_sorted_list_div_by_2 + 2)
address_of_pl_to_ps_communication_indicator2 = "mem_" + str(len_of_sorted_list_div_by_2 + 3)
address_of_pl_to_ps_communication_type_of_packet = "mem_" + str(len_of_sorted_list_div_by_2 + 4)
address_of_pl_to_ps_communication_requested_action_of_the_packet = "mem_" + str(len_of_sorted_list_div_by_2 + 5)
address_of_pl_to_ps_communication_start_of_data = "mem_" + str(len_of_sorted_list_div_by_2 + 6)
print("Address of PL to PS communication: " + address_of_pl_to_ps_communication)
for item in sorted_list:
element = getattr(dut.dataOut_initRegMemFromFileModule, item)
#
# Print the target register in binary format
#
# print(str(element))
#
# Convert binary to int
#
int_content = int(str(element.value), 2)
#
# Convert integer to hexadecimal string with at least 8 characters
#
hex_string = f'{int_content:08x}'
final_string = ""
if len(item) == 5:
final_string = item + ": " + hex_string
elif len(item) == 6:
final_string = item + ": " + hex_string
else:
final_string = item + ": " + hex_string
#
# Make a separation between PS and PL area
#
if item == address_of_ps_to_pl_communication:
file.write("\nPS to PL area:\n")
print("\nPS to PL area:")
elif item == address_of_pl_to_ps_communication:
file.write("\nPL to PS area:\n")
print("\nPL to PS area:")
if item == address_of_ps_to_pl_communication_checksum1 or \
item == address_of_ps_to_pl_communication_checksum2 or \
item == address_of_pl_to_ps_communication_checksum1 or \
item == address_of_pl_to_ps_communication_checksum2:
final_string = final_string + " | Checksum"
elif item == address_of_ps_to_pl_communication_indicator1 or \
item == address_of_ps_to_pl_communication_indicator2 or \
item == address_of_pl_to_ps_communication_indicator1 or \
item == address_of_pl_to_ps_communication_indicator2:
final_string = final_string + " | Indicator"
elif item == address_of_ps_to_pl_communication_type_of_packet or \
item == address_of_pl_to_ps_communication_type_of_packet:
final_string = final_string + " | TypeOfThePacket"
elif item == address_of_ps_to_pl_communication_requested_action_of_the_packet or \
item == address_of_pl_to_ps_communication_requested_action_of_the_packet:
final_string = final_string + " | RequestedActionOfThePacket"
elif item == address_of_ps_to_pl_communication_start_of_data or \
item == address_of_pl_to_ps_communication_start_of_data:
final_string = final_string + " | Start of Optional Data"
#
# Print contents of BRAM
#
file.write(final_string + "\n")
print(final_string)
print("\n===================================================================\n")
#
# Define a function to extract value of symbol
#
def get_symbol_value(dut, value):
element_value = getattr(dut.debuggerMainModule.outputPin_scriptExecutionEngineModule, value)
hex_string_value = ""
try:
int_content_value = int(str(element_value.value), 2)
hex_string_value = f'{int_content_value:x}'
except:
hex_string_value = str(element_value.value)
final_string_value = f'{value}: 0x{hex_string_value}' + " (bin: " + str(element_value.value) + ")"
return final_string_value
#
# Define a function to extract type of symbol
#
def get_symbol_type(dut, type):
element_type = getattr(dut.debuggerMainModule.outputPin_scriptExecutionEngineModule, type)
hex_string_type = ""
try:
int_content_type = int(str(element_type.value), 2)
hex_string_type = f'{int_content_type:x}'
except:
hex_string_type = str(element_type.value)
final_string_type = f'{type} : 0x{hex_string_type}' + " (bin: " + str(element_type.value) + ")"
return final_string_type
#
# Define a function to extract stage index
#
def get_stage_index(dut, stage_index):
stage_index_str = "stageRegs_" + str(stage_index) + "_stageIndex"
element_stage_index = getattr(dut.debuggerMainModule.outputPin_scriptExecutionEngineModule, stage_index_str)
hex_string_stage_index = ""
try:
int_content_stage_index = int(str(element_stage_index.value), 2)
hex_string_stage_index = f'{int_content_stage_index:x}'
except:
hex_string_stage_index = str(element_stage_index.value)
final_string_stage_index = f'{stage_index}: 0x{hex_string_stage_index}' + " (bin: " + str(element_stage_index.value) + ")"
return final_string_stage_index
#
# Define a function to extract content of stages
#
def extract_stage_details(dut):
print("Script Stage Registers Configuration:\n")
all_elements = dir(dut.debuggerMainModule.outputPin_scriptExecutionEngineModule)
#
# Define the pattern to match
#
pattern_value = re.compile(r'stageRegs_\d+_stageSymbol_Value')
pattern_type = re.compile(r'stageRegs_\d+_stageSymbol_Type')
pattern_stage_index = re.compile(r'stageRegs_\d+_stageIndex')
#
# Filter the list using the patterns
#
filtered_strings_values = [s for s in all_elements if pattern_value.match(s)]
filtered_strings_types = [s for s in all_elements if pattern_type.match(s)]
filtered_strings_stage_index = [s for s in all_elements if pattern_stage_index.match(s)]
#
# Sort the lists
#
sorted_values = sorted(filtered_strings_values, key=extract_number)
sorted_types = sorted(filtered_strings_types, key=extract_number)
sorted_stage_index = sorted(filtered_strings_stage_index, key=extract_number)
#
# Print the filtered strings
#
# print(sorted_values)
# print(sorted_types)
# print(sorted_stage_index)
for index, element in enumerate(sorted_values):
try:
final_string_type = get_symbol_type(dut, sorted_types[index])
#
# Print the type
#
print(final_string_type)
except:
print("This stage does not contain a 'type'")
try:
final_string_value = get_symbol_value(dut, sorted_values[index])
#
# Print the value
#
print(final_string_value)
except:
print("Unable to get stage 'value' configuration details")
try:
final_string_stage_index = get_stage_index(dut, index)
#
# Print the stage index
#
print("index: " + final_string_stage_index)
except:
print("index: " + str(index) +": This stage does not contain a 'stage index'")
print("\n")
#
# Check stage enable bit
#
try:
stage_enabled = "stageRegs_" + str(index) + "_stageEnable"
is_stage_enabled = getattr(dut.debuggerMainModule.outputPin_scriptExecutionEngineModule, stage_enabled)
print("\t Stage enabled bit: " + str(is_stage_enabled))
except:
print("\t Stage enabled bit: (unavailable)")
try:
final_string_value = get_symbol_value(dut, "stageRegs_" + str(index) + "_getOperatorSymbol_0_Value")
final_string_type = get_symbol_type(dut, "stageRegs_" + str(index) + "_getOperatorSymbol_0_Type")
print("\t Get (0) | " + final_string_type)
print("\t Get (0) | " + final_string_value)
except:
print("\t stage at:" + str(index) + " does not contain a Get (0) buffer")
print("\n")
try:
final_string_value = get_symbol_value(dut, "stageRegs_" + str(index) + "_getOperatorSymbol_1_Value")
final_string_type = get_symbol_type(dut, "stageRegs_" + str(index) + "_getOperatorSymbol_1_Type")
print("\t Get (1) | " + final_string_type)
print("\t Get (1) | " + final_string_value)
except:
print("\t stage at:" + str(index) + " does not contain a Get (1) buffer")
print("\n")
try:
final_string_value = get_symbol_value(dut, "stageRegs_" + str(index) + "_setOperatorSymbol_0_Value")
final_string_type = get_symbol_type(dut, "stageRegs_" + str(index) + "_setOperatorSymbol_0_Type")
print("\t Set (0) | " + final_string_type)
print("\t Set (0) | " + final_string_value)
except:
print("\t stage at:" + str(index) + " does not contain a Set (0) buffer")
print("\n\n")
def set_input_pins(dut):
dut.io_inputPin_0.value = 1
dut.io_inputPin_1.value = 1
dut.io_inputPin_2.value = 1
dut.io_inputPin_3.value = 1
dut.io_inputPin_4.value = 1
dut.io_inputPin_5.value = 1
dut.io_inputPin_6.value = 1
dut.io_inputPin_7.value = 1
dut.io_inputPin_8.value = 1
dut.io_inputPin_9.value = 1
dut.io_inputPin_10.value = 1
dut.io_inputPin_11.value = 1
dut.io_inputPin_12.value = 1
dut.io_inputPin_13.value = 1
dut.io_inputPin_14.value = 1
dut.io_inputPin_15.value = 1
dut.io_inputPin_16.value = 1
dut.io_inputPin_17.value = 1
dut.io_inputPin_18.value = 1
dut.io_inputPin_19.value = 1
dut.io_inputPin_20.value = 1
dut.io_inputPin_21.value = 1
dut.io_inputPin_22.value = 1
dut.io_inputPin_23.value = 1
dut.io_inputPin_24.value = 1
dut.io_inputPin_25.value = 1
dut.io_inputPin_26.value = 1
dut.io_inputPin_27.value = 1
dut.io_inputPin_28.value = 1
dut.io_inputPin_29.value = 1
dut.io_inputPin_30.value = 1
dut.io_inputPin_31.value = 1
@cocotb.test()
async def DebuggerModuleTestingBRAM_test(dut):
"""Test hwdbg module (with pre-defined BRAM)"""
#
# Assert initial output is unknown
#
assert LogicArray(dut.io_outputPin_0.value) == LogicArray("X")
assert LogicArray(dut.io_outputPin_1.value) == LogicArray("X")
assert LogicArray(dut.io_outputPin_2.value) == LogicArray("X")
assert LogicArray(dut.io_outputPin_3.value) == LogicArray("X")
assert LogicArray(dut.io_outputPin_4.value) == LogicArray("X")
assert LogicArray(dut.io_outputPin_5.value) == LogicArray("X")
assert LogicArray(dut.io_outputPin_6.value) == LogicArray("X")
assert LogicArray(dut.io_outputPin_7.value) == LogicArray("X")
assert LogicArray(dut.io_outputPin_8.value) == LogicArray("X")
assert LogicArray(dut.io_outputPin_9.value) == LogicArray("X")
assert LogicArray(dut.io_outputPin_10.value) == LogicArray("X")
assert LogicArray(dut.io_outputPin_11.value) == LogicArray("X")
assert LogicArray(dut.io_outputPin_12.value) == LogicArray("X")
assert LogicArray(dut.io_outputPin_13.value) == LogicArray("X")
assert LogicArray(dut.io_outputPin_14.value) == LogicArray("X")
assert LogicArray(dut.io_outputPin_15.value) == LogicArray("X")
assert LogicArray(dut.io_outputPin_16.value) == LogicArray("X")
assert LogicArray(dut.io_outputPin_17.value) == LogicArray("X")
assert LogicArray(dut.io_outputPin_18.value) == LogicArray("X")
assert LogicArray(dut.io_outputPin_19.value) == LogicArray("X")
assert LogicArray(dut.io_outputPin_20.value) == LogicArray("X")
assert LogicArray(dut.io_outputPin_21.value) == LogicArray("X")
assert LogicArray(dut.io_outputPin_22.value) == LogicArray("X")
assert LogicArray(dut.io_outputPin_23.value) == LogicArray("X")
assert LogicArray(dut.io_outputPin_24.value) == LogicArray("X")
assert LogicArray(dut.io_outputPin_25.value) == LogicArray("X")
assert LogicArray(dut.io_outputPin_26.value) == LogicArray("X")
assert LogicArray(dut.io_outputPin_27.value) == LogicArray("X")
assert LogicArray(dut.io_outputPin_28.value) == LogicArray("X")
assert LogicArray(dut.io_outputPin_29.value) == LogicArray("X")
assert LogicArray(dut.io_outputPin_30.value) == LogicArray("X")
assert LogicArray(dut.io_outputPin_31.value) == LogicArray("X")
#
# Create a 10ns period clock on port clock
#
clock = Clock(dut.clock, 10, units="ns")
#
# Start the clock. Start it low to avoid issues on the first RisingEdge
#
cocotb.start_soon(clock.start(start_high=False))
dut._log.info("Initialize and reset module")
#
# Initial values
#
dut.io_en.value = 0
dut.io_plInSignal.value = 0
#
# Reset DUT
#
dut.reset.value = 1
for _ in range(10):
await Timer(10, units="ns")
dut.reset.value = 0
dut._log.info("Enabling an interrupting chip to receive commands from BRAM")
#
# Enable chip
#
dut.io_en.value = 1
#
# Set initial input value to prevent it from floating
#
dut._log.info("Initializing input pins")
# set_input_pins(dut)
#
# Tell the hwdbg to receive BRAM results
#
dut.io_plInSignal.value = 1
await Timer(10, units="ns")
dut.io_plInSignal.value = 0
#
# Synchronize with the clock. This will regisiter the initial `inputPinX` value
#
await Timer(10, units="ns")
#
# Wait until the debuggee sends an interrupt to debugger
#
clock_counter = 0
interrupt_not_delivered = False
while str(dut.io_psOutInterrupt) != "1":
# print("State of interrupt: '" + str(dut.io_psOutInterrupt) + "'")
if clock_counter % 10 == 0:
print("Number of clock cycles spent in debuggee (PL): " + str(clock_counter))
clock_counter = clock_counter + 1
await Timer(10, units="ns")
#
# Apply a limitation to the number of clock cycles that
# can be executed to avoid infinite time
#
if (clock_counter >= maximum_number_of_clock_cycles):
interrupt_not_delivered = True
break
#
# Being here means either the debuggee sent an interrupt to the PS
# or the maximum clock cycles reached
#
if interrupt_not_delivered:
print("Maximum clock cycles reached")
else:
print("Debuggee (PL) interrupted Debugger (PS)")
#
# Run one more clock cycle to apply the latest BRAM modifications
#
await Timer(10, units="ns")
#
# Print contents of BRAM
#
print_bram_content(dut)
#
# Print the script stage configuration
#
extract_stage_details(dut)
#
# Check the final input on the next clock and run the circuit for a couple
# of more clock cycles
#
for _ in range(100):
set_input_pins(dut)
await Timer(10, units="ns")

View file

@ -1,8 +0,0 @@
# Makefile
TOPLEVEL_LANG = verilog
VERILOG_SOURCES = $(shell pwd)/../../../../generated/DebuggerPacketReceiver.sv
TOPLEVEL = DebuggerPacketReceiver
MODULE = test_DebuggerPacketReceiver
include $(shell cocotb-config --makefiles)/Makefile.sim

View file

@ -1 +0,0 @@
make SIM=icarus WAVES=1

View file

@ -1,187 +0,0 @@
##
# @file test_DebuggerPacketReceiver.py
#
# @author Sina Karvandi (sina@hyperdbg.org)
#
# @brief Testing module for DebuggerPacketReceiver
#
# @details
#
# @version 0.1
#
# @date 2024-04-22
#
# @copyright This project is released under the GNU Public License v3.
#
import random
import cocotb
from cocotb.clock import Clock
from cocotb.triggers import Timer
from cocotb.types import LogicArray
'''
input clock,
reset,
io_en,
io_plInSignal,
output [12:0] io_rdWrAddr,
input [31:0] io_rdData,
output [31:0] io_requestedActionOfThePacketOutput,
output io_requestedActionOfThePacketOutputValid,
input io_noNewDataReceiver,
io_readNextData,
output io_dataValidOutput,
output [31:0] io_receivingData,
output io_finishedReceivingBuffer
'''
@cocotb.test()
async def DebuggerPacketReceiver_test(dut):
"""Test DebuggerPacketReceiver module"""
#
# Assert initial output is unknown
#
assert LogicArray(dut.io_rdWrAddr.value) == LogicArray("XXXXXXXXXXXXX")
assert LogicArray(dut.io_requestedActionOfThePacketOutput.value) == LogicArray("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
assert LogicArray(dut.io_requestedActionOfThePacketOutputValid.value) == LogicArray("X")
assert LogicArray(dut.io_dataValidOutput.value) == LogicArray("X")
assert LogicArray(dut.io_receivingData.value) == LogicArray("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
assert LogicArray(dut.io_finishedReceivingBuffer.value) == LogicArray("X")
clock = Clock(dut.clock, 10, units="ns") # Create a 10ns period clock on port clock
#
# Start the clock. Start it low to avoid issues on the first RisingEdge
#
cocotb.start_soon(clock.start(start_high=False))
dut._log.info("Initialize and reset module")
#
# Initial values
#
dut.io_en.value = 0
dut.io_readNextData.value = 0
dut.io_noNewDataReceiver.value = 0
dut.io_plInSignal.value = 0
#
# Reset DUT
#
dut.reset.value = 1
for _ in range(10):
await Timer(10, units="ns")
dut.reset.value = 0
dut._log.info("Enabling chip")
#
# Enable chip
#
dut.io_en.value = 1
for test_number in range(10):
dut._log.info("Enable receiving data on the chip (" + str(test_number) + ")")
#
# Tell the receiver to start receiving data (This mainly operates based on
# a rising-edge detector, so we'll need to make it low)
#
dut.io_plInSignal.value = 1
await Timer(10, units="ns")
dut.io_plInSignal.value = 0
#
# Wait until the receive operation is done (finished)
#
for i in range(30):
if (dut.io_finishedReceivingBuffer.value == 1):
break
else:
match dut.io_rdWrAddr.value:
case 0x0: # checksum
dut.io_rdData.value = 0x00001234
case 0x8: # indicator
dut.io_rdData.value = 0x48595045 # first 32 bits of the indicator
case 0x10: # type
dut.io_rdData.value = 0x4 # debugger to hardware packet (DEBUGGER_TO_DEBUGGEE_HARDWARE_LEVEL)
case 0x14: # requested action
dut.io_rdData.value = 0x14141414
case 0x18: # General output
dut.io_rdData.value = 0x18181818
case 0x1c: # General output
dut.io_rdData.value = 0x1c1c1c1c
case 0x20: # General output
dut.io_rdData.value = 0x20202020
case 0x24: # General output
dut.io_rdData.value = 0x24242424
case 0x28: # General output
dut.io_rdData.value = 0x28282828
case 0x2c: # General output
dut.io_rdData.value = 0x2c2c2c2c
case 0x30: # General output
dut.io_rdData.value = 0x30303030
case 0x34: # General output
dut.io_rdData.value = 0x34343434
case 0x38: # General output
dut.io_rdData.value = 0x38383838
case 0x3c: # General output
dut.io_rdData.value = 0x3c3c3c3c
case 0x40: # General output
dut.io_rdData.value = 0x40404040
case 0x44: # General output
dut.io_rdData.value = 0x44444444
case 0x48: # General output
dut.io_rdData.value = 0x48484848
case 0x4c: # General output
dut.io_rdData.value = 0x4c4c4c4c
case 0x50: # General output
dut.io_rdData.value = 0x50505050
case _:
assert "invalid address in the address line"
if dut.io_requestedActionOfThePacketOutputValid.value == 1:
#
# No new data needed to be received
#
if test_number % 3 == 0:
dut.io_noNewDataReceiver.value = 1
await Timer(10, units="ns")
dut.io_noNewDataReceiver.value = 0
else:
#
# Make change to the io_readNextData signal as it operates mainly
# based on a rising-edge detector
#
if dut.io_readNextData.value == 0:
dut.io_readNextData.value = 1
else:
dut.io_readNextData.value = 0
#
# Go to the next clock cycle
#
await Timer(10, units="ns")
if test_number % 3 != 0:
dut.io_noNewDataReceiver.value = 1
await Timer(10, units="ns")
dut.io_noNewDataReceiver.value = 0
#
# Run extra waiting clocks
#
for _ in range(10):
await Timer(10, units="ns")
#
# Check the final input on the next clock
#
await Timer(10, units="ns")

View file

@ -1,8 +0,0 @@
# Makefile
TOPLEVEL_LANG = verilog
VERILOG_SOURCES = $(shell pwd)/../../../../generated/DebuggerPacketSender.sv
TOPLEVEL = DebuggerPacketSender
MODULE = test_DebuggerPacketSender
include $(shell cocotb-config --makefiles)/Makefile.sim

View file

@ -1 +0,0 @@
make SIM=icarus WAVES=1

View file

@ -1,165 +0,0 @@
##
# @file test_DebuggerPacketSender.py
#
# @author Sina Karvandi (sina@hyperdbg.org)
#
# @brief Testing module for DebuggerPacketSender
#
# @details
#
# @version 0.1
#
# @date 2024-04-21
#
# @copyright This project is released under the GNU Public License v3.
#
import random
import cocotb
from cocotb.clock import Clock
from cocotb.triggers import Timer
from cocotb.types import LogicArray
'''
input clock,
reset,
io_en,
output io_psOutInterrupt,
output [12:0] io_rdWrAddr,
output io_wrEna,
output [31:0] io_wrData,
input io_beginSendingBuffer,
io_noNewDataSender,
io_dataValidInput,
output io_sendWaitForBuffer,
io_finishedSendingBuffer,
input [31:0] io_requestedActionOfThePacketInput,
io_sendingData
'''
@cocotb.test()
async def DebuggerPacketSender_test(dut):
"""Test DebuggerPacketSender module"""
#
# Assert initial output is unknown
#
assert LogicArray(dut.io_psOutInterrupt.value) == LogicArray("X")
assert LogicArray(dut.io_rdWrAddr.value) == LogicArray("XXXXXXXXXXXXX")
assert LogicArray(dut.io_wrEna.value) == LogicArray("X")
assert LogicArray(dut.io_wrData.value) == LogicArray("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
assert LogicArray(dut.io_sendWaitForBuffer.value) == LogicArray("X")
assert LogicArray(dut.io_finishedSendingBuffer.value) == LogicArray("X")
clock = Clock(dut.clock, 10, units="ns") # Create a 10ns period clock on port clock
#
# Start the clock. Start it low to avoid issues on the first RisingEdge
#
cocotb.start_soon(clock.start(start_high=False))
dut._log.info("Initialize and reset module")
#
# Initial values
#
dut.io_en.value = 0
dut.io_beginSendingBuffer.value = 0
#
# Reset DUT
#
dut.reset.value = 1
for _ in range(10):
await Timer(10, units="ns")
dut.reset.value = 0
dut._log.info("Enabling chip")
#
# Enable chip
#
dut.io_en.value = 1
for test_number in range(10):
dut._log.info("Enable sending data on the chip (" + str(test_number) + ")")
#
# Still there is data to send
#
dut.io_noNewDataSender.value = 0
#
# Tell the sender to start sending data (This mainly operates based on
# a rising-edge detector, so we'll need to make it low)
#
dut.io_beginSendingBuffer.value = 1
await Timer(10, units="ns")
dut.io_beginSendingBuffer.value = 0
#
# No new data at this stage
#
dut.io_dataValidInput.value = 0
dut.io_sendingData.value = 0
#
# Adjust the requested action of the packet
#
dut.io_requestedActionOfThePacketInput.value = 0x55859555
#
# Synchronize with the clock. This will apply the initial values
#
await Timer(10, units="ns")
#
# This will change the behavior of the data producer to only
# generate extra data for 2 of the test case rounds, the third
# test case doesn't have any extra data
#
if test_number % 3 != 0 :
#
# Run until the module asks for further buffers
#
for i in range(100):
if dut.io_sendWaitForBuffer.value == 1:
val = random.randint(0, 0xffffffff)
#
# Indicate that the data is valid
#
dut.io_dataValidInput.value = 1
#
# Assign the random value to send as the data
#
dut.io_sendingData.value = val
await Timer(10, units="ns")
#
# Now, tell the sender module that there is no longer needed to send data
#
for i in range(100):
if dut.io_sendWaitForBuffer.value == 1:
dut.io_noNewDataSender.value = 1
await Timer(10, units="ns")
dut.io_noNewDataSender.value = 0
break
await Timer(10, units="ns")
#
# Run extra waiting clocks
#
for _ in range(10):
await Timer(10, units="ns")
#
# Check the final input on the next clock
#
await Timer(10, units="ns")

View file

@ -1,10 +0,0 @@
# Makefile
TOPLEVEL_LANG = verilog
VERILOG_SOURCES += $(shell pwd)/../../../../generated/SendReceiveSynchronizer.sv
VERILOG_SOURCES += $(shell pwd)/../../../../generated/DebuggerPacketReceiver.sv
VERILOG_SOURCES += $(shell pwd)/../../../../generated/DebuggerPacketSender.sv
TOPLEVEL = SendReceiveSynchronizer
MODULE = test_SendReceiveSynchronizer
include $(shell cocotb-config --makefiles)/Makefile.sim

View file

@ -1 +0,0 @@
make SIM=icarus WAVES=1

View file

@ -1,352 +0,0 @@
##
# @file test_SendReceiveSynchronizer.py
#
# @author Sina Karvandi (sina@hyperdbg.org)
#
# @brief Testing module for SendReceiveSynchronizer
#
# @details
#
# @version 0.1
#
# @date 2024-04-23
#
# @copyright This project is released under the GNU Public License v3.
#
import random
import cocotb
from cocotb.clock import Clock
from cocotb.triggers import Timer
from cocotb.types import LogicArray
'''
input clock,
reset,
io_en,
io_plInSignal,
output io_psOutInterrupt,
output [12:0] io_rdWrAddr,
input [31:0] io_rdData,
output io_wrEna,
output [31:0] io_wrData,
io_requestedActionOfThePacketOutput,
output io_requestedActionOfThePacketOutputValid,
input io_noNewDataReceiver,
io_readNextData,
output io_dataValidOutput,
output [31:0] io_receivingData,
input io_beginSendingBuffer,
io_noNewDataSender,
io_dataValidInput,
output io_sendWaitForBuffer,
input [31:0] io_requestedActionOfThePacketInput,
io_sendingData
'''
@cocotb.test()
async def SendReceiveSynchronizer_test(dut):
"""Test SendReceiveSynchronizer module"""
global DEFAULT_CONFIGURATION_INITIALIZED_MEMORY_SIZE
#
# Assert initial output is unknown
#
assert LogicArray(dut.io_psOutInterrupt.value) == LogicArray("X")
assert LogicArray(dut.io_rdWrAddr.value) == LogicArray("XXXXXXXXXXXXX")
assert LogicArray(dut.io_wrEna.value) == LogicArray("X")
assert LogicArray(dut.io_wrData.value) == LogicArray("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
assert LogicArray(dut.io_requestedActionOfThePacketOutput.value) == LogicArray("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
assert LogicArray(dut.io_requestedActionOfThePacketOutputValid.value) == LogicArray("X")
assert LogicArray(dut.io_dataValidOutput.value) == LogicArray("X")
assert LogicArray(dut.io_receivingData.value) == LogicArray("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
assert LogicArray(dut.io_sendWaitForBuffer.value) == LogicArray("X")
clock = Clock(dut.clock, 10, units="ns") # Create a 10ns period clock on port clock
#
# Start the clock. Start it low to avoid issues on the first RisingEdge
#
cocotb.start_soon(clock.start(start_high=False))
dut._log.info("Initialize and reset module")
#
# Initial values
#
dut.io_en.value = 0
dut.io_beginSendingBuffer.value = 0
dut.io_noNewDataSender.value = 0
dut.io_dataValidInput.value = 0
dut.io_readNextData.value = 0
dut.io_noNewDataReceiver.value = 0
dut.io_plInSignal.value = 0
dut.io_requestedActionOfThePacketInput.value = 0
dut.io_requestedActionOfThePacketInput.value = 0
#
# Reset DUT
#
dut.reset.value = 1
for _ in range(10):
await Timer(10, units="ns")
dut.reset.value = 0
dut._log.info("Enabling chip")
#
# Enable chip
#
dut.io_en.value = 1
for test_number in range(10):
###############################################################
# #
# Receiving Logic #
# #
###############################################################
dut._log.info("Enable receiving data on the chip (" + str(test_number) + ")")
#
# Tell the receiver to start receiving data (This mainly operates based on
# a rising-edge detector, so we'll need to make it low)
#
dut.io_plInSignal.value = 1
await Timer(10, units="ns")
dut.io_plInSignal.value = 0
#
# Activate sending logic to test whether the chip fails synchronizing signals or not
#
dut.io_beginSendingBuffer.value = 1
await Timer(10, units="ns")
dut.io_beginSendingBuffer.value = 0
#
# Wait until the receive operation is done (finished)
#
for i in range(30):
match dut.io_rdWrAddr.value:
#
# For the PS data range
#
case 0x0: # checksum
dut.io_rdData.value = 0x00001234
case 0x8: # indicator
dut.io_rdData.value = 0x48595045 # first 32 bits of the indicator
case 0x10: # type
dut.io_rdData.value = 0x4 # debugger to hardware packet (DEBUGGER_TO_DEBUGGEE_HARDWARE_LEVEL)
case 0x14: # requested action
dut.io_rdData.value = 0x14141414
case 0x18: # General output
dut.io_rdData.value = 0x18181818
case 0x1c: # General output
dut.io_rdData.value = 0x1c1c1c1c
case 0x20: # General output
dut.io_rdData.value = 0x20202020
case 0x24: # General output
dut.io_rdData.value = 0x24242424
case 0x28: # General output
dut.io_rdData.value = 0x28282828
case 0x2c: # General output
dut.io_rdData.value = 0x2c2c2c2c
case 0x30: # General output
dut.io_rdData.value = 0x30303030
case 0x34: # General output
dut.io_rdData.value = 0x34343434
case 0x38: # General output
dut.io_rdData.value = 0x38383838
case 0x3c: # General output
dut.io_rdData.value = 0x3c3c3c3c
case 0x40: # General output
dut.io_rdData.value = 0x40404040
case 0x44: # General output
dut.io_rdData.value = 0x44444444
case 0x48: # General output
dut.io_rdData.value = 0x48484848
case 0x4c: # General output
dut.io_rdData.value = 0x4c4c4c4c
case 0x50: # General output
dut.io_rdData.value = 0x50505050
#
# For the PL data range
#
case 0x1000: # checksum
dut.io_rdData.value = 0x10001000
case 0x1008: # indicator 1
dut.io_rdData.value = 0x48595045 # The first 32 bits of the indicator
case 0x100c: # indicator 2
dut.io_rdData.value = 0x100c100c # The second 32 bits of the indicator
case 0x1010: # type
dut.io_rdData.value = 0x4 # debugger to hardware packet (DEBUGGER_TO_DEBUGGEE_HARDWARE_LEVEL)
case 0x1014: # requested action
dut.io_rdData.value = 0x10141014
case 0x1018: # General output
dut.io_rdData.value = 0x10181018
case 0x101c: # General output
dut.io_rdData.value = 0x101c101c
case 0x1020: # General output
dut.io_rdData.value = 0x10201020
case 0x1024: # General output
dut.io_rdData.value = 0x10241024
case 0x1028: # General output
dut.io_rdData.value = 0x10281028
case 0x102c: # General output
dut.io_rdData.value = 0x102c102c
case 0x1030: # General output
dut.io_rdData.value = 0x10301030
case 0x1034: # General output
dut.io_rdData.value = 0x10341034
case 0x1038: # General output
dut.io_rdData.value = 0x10381038
case 0x103c: # General output
dut.io_rdData.value = 0x103c103c
case 0x1040: # General output
dut.io_rdData.value = 0x10401040
case 0x1044: # General output
dut.io_rdData.value = 0x10441044
case 0x1048: # General output
dut.io_rdData.value = 0x10481048
case 0x104c: # General output
dut.io_rdData.value = 0x104c104c
case 0x1050: # General output
dut.io_rdData.value = 0x10501050
case _:
assert 1 == 2, "invalid address in the address line"
if dut.io_requestedActionOfThePacketOutputValid.value == 1:
#
# No new data needed to be received
#
if test_number % 3 == 0:
dut.io_noNewDataReceiver.value = 1
await Timer(10, units="ns")
dut.io_noNewDataReceiver.value = 0
else:
#
# Make change to the io_readNextData signal as it operates mainly
# based on a rising-edge detector
#
if dut.io_readNextData.value == 0:
dut.io_readNextData.value = 1
else:
dut.io_readNextData.value = 0
#
# Go to the next clock cycle
#
await Timer(10, units="ns")
if test_number % 3 != 0:
dut.io_noNewDataReceiver.value = 1
await Timer(10, units="ns")
dut.io_noNewDataReceiver.value = 0
#
# Run extra waiting clocks
#
for _ in range(10):
await Timer(10, units="ns")
###############################################################
# #
# Sending Logic #
# #
###############################################################
dut._log.info("Enable sending data on the chip (" + str(test_number) + ")")
#
# There is data to send
#
dut.io_noNewDataSender.value = 0
dut.io_beginSendingBuffer.value = 0
#
# Tell the sender to start sending data (This mainly operates based on
# a rising-edge detector, so we'll need to make it low)
#
dut.io_beginSendingBuffer.value = 1
await Timer(10, units="ns")
dut.io_beginSendingBuffer.value = 0
#
# Activate receiving logic to test whether the chip fails synchronizing signals or not
#
dut.io_plInSignal.value = 1
await Timer(10, units="ns")
dut.io_plInSignal.value = 0
#
# No new data at this stage
#
dut.io_dataValidInput.value = 0
dut.io_sendingData.value = 0
#
# Adjust the requested action of the packet
#
dut.io_requestedActionOfThePacketInput.value = 0x55859555
#
# Synchronize with the clock. This will apply the initial values
#
await Timer(10, units="ns")
#
# This will change the behavior of the data producer to only
# generate extra data for 2 of the test case rounds, the third
# test case doesn't have any extra data
#
if test_number % 3 != 0 :
#
# Run until the module asks for further buffers
#
for i in range(100):
if dut.io_sendWaitForBuffer.value == 1:
val = random.randint(0, 0xffffffff)
#
# Indicate that the data is valid
#
dut.io_dataValidInput.value = 1
#
# Assign the random value to send as the data
#
dut.io_sendingData.value = val
await Timer(10, units="ns")
#
# Now, tell the sender module that there is no longer needed to send data
#
for i in range(100):
if dut.io_sendWaitForBuffer.value == 1:
dut.io_noNewDataSender.value = 1
await Timer(10, units="ns")
dut.io_noNewDataSender.value = 0
break
await Timer(10, units="ns")
#
# Run extra waiting clocks
#
for _ in range(10):
await Timer(10, units="ns")
#
# Check the final input on the next clock
#
await Timer(10, units="ns")

View file

@ -1,32 +0,0 @@
# Automated ModelSim Viewer
First of all, make sure to edit the address of the "ModelSim" directory in **modelsim.py**.
After that, only modify the "modelsim.config" file.
In the "modelsim.config" file, the first line that starts with "module:" is the name of the target module's **Tester** class. The rest of the lines are signals to be shown.
For example:
```
module:DebuggerModuleTest
clock
inputPin
```
If you don't specify the signals to be filtered, then **ALL** signals will be shown.
For example:
```
module:DebuggerModuleTest
```
At last, run it with the following command:
```
python3 modelsim.py
```
or,
```
python3 sim/modelsim.py
```

View file

@ -1,3 +0,0 @@
module:DebuggerModuleTest
io_inputPin
io_outputPin

View file

@ -1,157 +0,0 @@
import os
import subprocess
import glob
MODELSIM = "/home/sina/intelFPGA/20.1/modelsim_ase/bin"
#
# Check modelsim directory
#
if not os.path.exists(MODELSIM):
print("[x] Error: The path does not exist")
exit()
else:
print("[*] Oh, the modelsim path found :)")
MODELSIM_VCD2WLF = MODELSIM + "/vcd2wlf"
MODELSIM_VSIM = MODELSIM + "/vsim"
#
# Config file variables
#
CONFIG_TEST_MODULE_CLASS = ""
CONFIG_SHOW_ALL_WAVES = True
CONFIG_WAVES_LIST = []
#
# Check if user is root or not
#
if os.geteuid() != 0:
print("[x] you should run this script with root (sudo) user permission")
exit()
else:
print("[*] user is root")
#
# Get the current script's directory
#
current_script_path = os.path.dirname(os.path.abspath(__file__))
WAVE_OUTPUT_FILES_PATH = current_script_path + \
"/../test_run_dir/DUT_should_pass/"
CONFIG_FILE_PATH = current_script_path + "/modelsim.config"
print("[*] current script path:", WAVE_OUTPUT_FILES_PATH)
#
# Check config file
#
if os.path.exists(CONFIG_FILE_PATH) == False:
print("[x] config file not found")
exit()
#
# Interpreting config file
#
with open(CONFIG_FILE_PATH, 'r') as file:
for line in file:
if line.lower().startswith("module:") or line.lower().startswith("module :"):
# it's the test module name
CONFIG_TEST_MODULE_CLASS = line.split(":")[1]
print("[*] found module name:", CONFIG_TEST_MODULE_CLASS)
else:
# it's a wave, so no longer need to show all waves
if line.isspace() == False:
CONFIG_SHOW_ALL_WAVES = False
CONFIG_WAVES_LIST.append(line)
print("[*] signal filter for:", line)
#
# Show message if all signals need to be shown
#
if CONFIG_SHOW_ALL_WAVES == True:
print("[*] no signal filter found, assuming all signals to be shown!")
#
# Check if test module is empty or not
#
if CONFIG_TEST_MODULE_CLASS.isspace() == True:
print("[x] main test module not found, please add 'module:' to the config file")
exit()
#
# Set the current working directory
#
os.chdir(current_script_path + "/..")
print("[*] current working directory: " + format(os.getcwd()))
#
# Create TCL config file
#
print("[*] writing to TCL config file: " +
current_script_path + '/modelsim.tcl')
if CONFIG_SHOW_ALL_WAVES:
with open(current_script_path + '/modelsim.tcl', 'w') as f:
# add the clock at top of the signals by default
f.write("add wave -position insertpoint clock\n")
f.write("add wave -position insertpoint *\n")
else:
with open(current_script_path + '/modelsim.tcl', 'w') as f:
for item in CONFIG_WAVES_LIST:
f.write("add wave -position insertpoint {*" + item.replace('\n','').replace('\r', '') + '*}\n')
#
# Remove all the previous *.wlf, *.vcd, *.fir files
#
print("[*] removing previously generated files")
for file_name in os.listdir(WAVE_OUTPUT_FILES_PATH):
if file_name.endswith('.wlf') or file_name.endswith('.vcd') or file_name.endswith('.fir'):
os.remove(os.path.join(WAVE_OUTPUT_FILES_PATH, file_name))
#
# Run the VCD wave generator
#
print("[*] running chisel VCD file generator for module: " +
CONFIG_TEST_MODULE_CLASS)
print("running command: '" + "sbt testOnly " + CONFIG_TEST_MODULE_CLASS + " -- -DwriteVcd=1" + "'")
result = subprocess.run(
["sbt", "testOnly " + CONFIG_TEST_MODULE_CLASS + " -- -DwriteVcd=1"], stdout=subprocess.PIPE)
print(result.stdout.decode())
#
# Get all files in directory
#
files = glob.glob(WAVE_OUTPUT_FILES_PATH + "/*")
#
# Sort files by last modified time
#
files.sort(key=lambda x: os.path.getmtime(x))
#
# Check if the list is empty or not
#
if not files or not files[-1].endswith('.vcd') :
print("[x] there was an error in generating VCD files")
exit()
#
# Get the latest modified file
#
latest_vcd_file = files[-1]
print("[*] latest generated VCD file: " + latest_vcd_file)
#
# Converting VCD to WLF
#
print("[*] converting VCD file to WLF file")
result = subprocess.run(
[MODELSIM_VCD2WLF, latest_vcd_file, latest_vcd_file + ".wlf"], stdout=subprocess.PIPE)
print(result.stdout.decode())
#
# Run the generated WLF file
#
print("[*] opening file in vsim: " + latest_vcd_file + ".wlf")
subprocess.run([MODELSIM_VSIM, latest_vcd_file + ".wlf",
"-do", current_script_path + '/modelsim.tcl'])

View file

@ -1,2 +0,0 @@
add wave -position insertpoint {*io_inputPin*}
add wave -position insertpoint {*io_outputPin*}

View file

@ -1,162 +0,0 @@
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer: Sina Karvandi (sina@hyperdbg.org)
//
// Create Date: 09/18/2024
// Design Name:
// Module Name: PlainSystemVerilogDUT
// Project Name: PlainSystemVerilogDUT
// Target Devices:
// Tool Versions:
// Description: This code is used for plain simulation of the top-level
// design of hwdbg debugger
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module PlainSystemVerilogDUT;
//
// Parameters
//
parameter CLK_PERIOD = 10; // Clock period
//
// Signal Declarations
//
logic clock;
logic reset;
logic io_en;
logic [31:0] io_inputPin; // Array for input pins
logic [31:0] io_outputPin; // Array for output pins
logic io_plInSignal;
logic io_psOutInterrupt;
//
// Instantiate the DUT (Device Under Test)
//
DebuggerModuleTestingBRAM uut (
.clock(clock),
.reset(reset),
.io_en(io_en),
.io_inputPin_0(io_inputPin[0]),
.io_inputPin_1(io_inputPin[1]),
.io_inputPin_2(io_inputPin[2]),
.io_inputPin_3(io_inputPin[3]),
.io_inputPin_4(io_inputPin[4]),
.io_inputPin_5(io_inputPin[5]),
.io_inputPin_6(io_inputPin[6]),
.io_inputPin_7(io_inputPin[7]),
.io_inputPin_8(io_inputPin[8]),
.io_inputPin_9(io_inputPin[9]),
.io_inputPin_10(io_inputPin[10]),
.io_inputPin_11(io_inputPin[11]),
.io_inputPin_12(io_inputPin[12]),
.io_inputPin_13(io_inputPin[13]),
.io_inputPin_14(io_inputPin[14]),
.io_inputPin_15(io_inputPin[15]),
.io_inputPin_16(io_inputPin[16]),
.io_inputPin_17(io_inputPin[17]),
.io_inputPin_18(io_inputPin[18]),
.io_inputPin_19(io_inputPin[19]),
.io_inputPin_20(io_inputPin[20]),
.io_inputPin_21(io_inputPin[21]),
.io_inputPin_22(io_inputPin[22]),
.io_inputPin_23(io_inputPin[23]),
.io_inputPin_24(io_inputPin[24]),
.io_inputPin_25(io_inputPin[25]),
.io_inputPin_26(io_inputPin[26]),
.io_inputPin_27(io_inputPin[27]),
.io_inputPin_28(io_inputPin[28]),
.io_inputPin_29(io_inputPin[29]),
.io_inputPin_30(io_inputPin[30]),
.io_inputPin_31(io_inputPin[31]),
.io_outputPin_0(io_outputPin[0]),
.io_outputPin_1(io_outputPin[1]),
.io_outputPin_2(io_outputPin[2]),
.io_outputPin_3(io_outputPin[3]),
.io_outputPin_4(io_outputPin[4]),
.io_outputPin_5(io_outputPin[5]),
.io_outputPin_6(io_outputPin[6]),
.io_outputPin_7(io_outputPin[7]),
.io_outputPin_8(io_outputPin[8]),
.io_outputPin_9(io_outputPin[9]),
.io_outputPin_10(io_outputPin[10]),
.io_outputPin_11(io_outputPin[11]),
.io_outputPin_12(io_outputPin[12]),
.io_outputPin_13(io_outputPin[13]),
.io_outputPin_14(io_outputPin[14]),
.io_outputPin_15(io_outputPin[15]),
.io_outputPin_16(io_outputPin[16]),
.io_outputPin_17(io_outputPin[17]),
.io_outputPin_18(io_outputPin[18]),
.io_outputPin_19(io_outputPin[19]),
.io_outputPin_20(io_outputPin[20]),
.io_outputPin_21(io_outputPin[21]),
.io_outputPin_22(io_outputPin[22]),
.io_outputPin_23(io_outputPin[23]),
.io_outputPin_24(io_outputPin[24]),
.io_outputPin_25(io_outputPin[25]),
.io_outputPin_26(io_outputPin[26]),
.io_outputPin_27(io_outputPin[27]),
.io_outputPin_28(io_outputPin[28]),
.io_outputPin_29(io_outputPin[29]),
.io_outputPin_30(io_outputPin[30]),
.io_outputPin_31(io_outputPin[31]),
.io_plInSignal(io_plInSignal),
.io_psOutInterrupt(io_psOutInterrupt)
);
//
// Clock generation
//
initial begin
clock = 0;
forever #(CLK_PERIOD / 2) clock = ~clock;
end
//
// Test procedure
//
initial begin
// Initialize signals
reset = 1;
io_en = 1;
io_plInSignal = 0;
io_inputPin = 32'h0; // Initialize all input pins to 0
#100; // Hold reset for 100 ns
// Apply reset
@(posedge clock);
reset = 0; // Release reset
@(posedge clock);
//
// Example input stimulus
//
io_inputPin = 32'hFFFF_FFFF; // Apply some input pattern
//
// Enable PL input signal
//
io_plInSignal = 1;
//
// Wait for a few clock cycles
//
repeat (10000) @(posedge clock);
//
// Finish the simulation after some time
//
repeat (20) @(posedge clock);
$finish;
end
endmodule

View file

@ -1,515 +0,0 @@
/**
* @file
* interpreter.scala
* @author
* Sina Karvandi (sina@hyperdbg.org)
* @brief
* Remote debugger packet interpreter module
* @details
* @version 0.1
* @date
* 2024-04-19
*
* @copyright
* This project is released under the GNU Public License v3.
*/
package hwdbg.communication.interpreter
import chisel3._
import chisel3.util.{switch, is}
import circt.stage.ChiselStage
import hwdbg.configs._
import hwdbg.types._
import hwdbg.script._
object DebuggerPacketInterpreterEnums {
object State extends ChiselEnum {
val sIdle, sNewActionReceived, sSendResponse, sDone = Value
}
}
class DebuggerPacketInterpreter(
debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
instanceInfo: HwdbgInstanceInformation
) extends Module {
//
// Import state enum
//
import DebuggerPacketInterpreterEnums.State
import DebuggerPacketInterpreterEnums.State._
val io = IO(new Bundle {
//
// Chip signals
//
val en = Input(Bool()) // chip enable signal
//
// Receiving signals
//
val requestedActionOfThePacketInput = Input(UInt(new DebuggerRemotePacket().RequestedActionOfThePacket.getWidth.W)) // the requested action
val requestedActionOfThePacketInputValid = Input(Bool()) // whether data on the requested action is valid or not
val noNewDataReceiver = Output(Bool()) // are interpreter expects more data?
val readNextData = Output(Bool()) // whether the next data should be read or not?
val dataValidInput = Input(Bool()) // whether data on the receiving data line is valid or not?
val receivingData = Input(UInt(instanceInfo.bramDataWidth.W)) // data to be received in interpreter
//
// Sending signals
//
val beginSendingBuffer = Output(Bool()) // should sender start sending buffers or not?
val noNewDataSender = Output(Bool()) // should sender finish sending buffers or not?
val dataValidOutput = Output(Bool()) // should sender send next buffer or not?
val sendWaitForBuffer = Input(Bool()) // should the interpreter send next buffer or not?
val requestedActionOfThePacketOutput = Output(UInt(new DebuggerRemotePacket().RequestedActionOfThePacket.getWidth.W)) // the requested action
val sendingData = Output(UInt(instanceInfo.bramDataWidth.W)) // data to be sent to the debugger
//
// Script stage configuration signals
//
val finishedScriptConfiguration = Output(Bool()) // whether script configuration finished or not?
val configureStage = Output(Bool()) // whether the configuration of stage should start or not?
val targetOperator = Output(new HwdbgShortSymbol(instanceInfo.scriptVariableLength)) // Current operator to be configured
})
//
// State registers
//
val state = RegInit(sIdle)
//
// Last error register
//
val lastSuccesOrErrorMessage = RegInit(0.U(instanceInfo.bramDataWidth.W))
//
// Last error register
//
val enablePinOfScriptBufferHandler = RegInit(false.B)
//
// Output pins
//
val noNewDataReceiver = WireInit(false.B)
val readNextData = WireInit(false.B)
val regBeginSendingBuffer = RegInit(false.B)
val noNewDataSender = WireInit(false.B)
val dataValidOutput = WireInit(false.B)
val sendingData = WireInit(0.U(instanceInfo.bramDataWidth.W))
val regRequestedActionOfThePacketOutput = RegInit(0.U(new DebuggerRemotePacket().RequestedActionOfThePacket.getWidth.W))
val finishedScriptConfiguration = WireInit(false.B)
val configureStage = WireInit(false.B)
val initialSymbol = Wire(new HwdbgShortSymbol(instanceInfo.scriptVariableLength))
initialSymbol.Type := 0.U
initialSymbol.Value := 0.U
val targetOperator = WireInit(initialSymbol)
//
// Apply the chip enable signal
//
when(io.en === true.B) {
switch(state) {
is(sIdle) {
//
// Check if the debugger need a new action (a new command is received)
//
when(io.requestedActionOfThePacketInputValid) {
//
// An action is received
//
state := sNewActionReceived
}.otherwise {
//
// Remain at the same state (no action)
//
state := sIdle
}
}
is(sNewActionReceived) {
// -------------------------------------------------------------------------
// Now, the action needs to be dispatched
//
val inputAction = io.requestedActionOfThePacketInput
when(inputAction === HwdbgActionEnums.hwdbgActionSendInstanceInfo.id.U) {
//
// *** Configure sending instance info ***
//
//
// Set the response packet type
//
regRequestedActionOfThePacketOutput := HwdbgResponseEnums.hwdbgResponseInstanceInfo.id.U
//
// This action needs a response
//
state := sSendResponse
}.elsewhen(inputAction === HwdbgActionEnums.hwdbgActionConfigureScriptBuffer.id.U) {
//
// *** Configure the internal buffer with script ***
//
//
// Enable the buffer config module
//
enablePinOfScriptBufferHandler := true.B
val (
moduleReadNextData,
moduleFinishedScriptConfiguration,
moduleConfigureStage,
moduleTargetOperator
) =
InterpreterScriptBufferHandler(
debug,
instanceInfo
)(
enablePinOfScriptBufferHandler,
io.dataValidInput,
io.receivingData
)
//
// Connect the script stage configuration signals
//
readNextData := moduleReadNextData
configureStage := moduleConfigureStage
finishedScriptConfiguration := moduleFinishedScriptConfiguration
targetOperator := moduleTargetOperator
when(moduleFinishedScriptConfiguration === true.B) {
//
// *** Script stage buffer configuration finished! ***
//
//
// Disable the buffer config module
//
enablePinOfScriptBufferHandler := false.B
//
// Set the response packet type
//
regRequestedActionOfThePacketOutput := HwdbgResponseEnums.hwdbgResponseSuccessOrErrorMessage.id.U
//
// Set the success message
//
lastSuccesOrErrorMessage := HwdbgSuccessOrErrorEnums.hwdbgOperationWasSuccessful.id.U
//
// This action needs a response
//
state := sSendResponse
}.otherwise {
//
// *** Script stage buffer configuration NOT finished, read the buffer ***
//
//
// Stay at the same state
//
state := sNewActionReceived
}
}.otherwise {
//
// *** Invalid action ***
//
//
// Set the response packet type
//
regRequestedActionOfThePacketOutput := HwdbgResponseEnums.hwdbgResponseSuccessOrErrorMessage.id.U
//
// Set the latest error
//
lastSuccesOrErrorMessage := HwdbgSuccessOrErrorEnums.hwdbgErrorInvalidPacket.id.U
//
// This action needs a response
//
state := sSendResponse
}
//
// -------------------------------------------------------------------------
//
}
is(sSendResponse) {
//
// Finish the receiving
//
noNewDataReceiver := true.B
//
// Begin sending response
//
regBeginSendingBuffer := true.B
//
// Wait until the sender module is reading to send data
//
when(io.sendWaitForBuffer === true.B) {
// -------------------------------------------------------------------------
// Now, the response needs to be sent
//
when(regRequestedActionOfThePacketOutput === HwdbgResponseEnums.hwdbgResponseInstanceInfo.id.U) {
//
// *** Send instance information ***
//
//
// Instantiate the instance info module
//
val (
noNewDataSenderModule,
dataValidOutputModule,
sendingDataModule
) =
InterpreterInstanceInfo(
debug,
instanceInfo
)(
io.sendWaitForBuffer // send waiting for buffer as an activation signal to the module
)
//
// Set data validity
//
dataValidOutput := dataValidOutputModule
//
// Set data
//
sendingData := sendingDataModule
//
// Once sending data is done, we'll go to the Done state
//
when(noNewDataSenderModule === true.B) {
state := sDone
}
}.elsewhen(regRequestedActionOfThePacketOutput === HwdbgResponseEnums.hwdbgResponseSuccessOrErrorMessage.id.U) {
//
// *** Send result of applying command (and errors) ***
//
//
// Instantiate the invalid packet module
//
val (
noNewDataSenderModule,
dataValidOutputModule,
sendingDataModule
) =
InterpreterSendSuccessOrError(
debug,
instanceInfo
)(
io.sendWaitForBuffer, // send waiting for buffer as an activation signal to the module
lastSuccesOrErrorMessage
)
//
// Set data validity
//
dataValidOutput := dataValidOutputModule
//
// Set data
//
sendingData := sendingDataModule
//
// Once sending data is done, we'll go to the Done state
//
when(noNewDataSenderModule === true.B) {
state := sDone
}
}
//
// -------------------------------------------------------------------------
//
}.otherwise {
//
// The sender module is not ready for sending buffer
// so, we need to stay at this state
//
state := sSendResponse
}
}
is(sDone) {
//
// Finish the receiving, sending communication
//
noNewDataReceiver := true.B
noNewDataSender := true.B
//
// No longer need to begin sending data
//
regBeginSendingBuffer := false.B
//
// Go to the idle state
//
state := sIdle
}
}
}
// ---------------------------------------------------------------------
//
// Connect output pins
//
io.noNewDataReceiver := noNewDataReceiver
io.readNextData := readNextData
io.beginSendingBuffer := regBeginSendingBuffer
io.noNewDataSender := noNewDataSender
io.dataValidOutput := dataValidOutput
io.requestedActionOfThePacketOutput := regRequestedActionOfThePacketOutput
io.sendingData := sendingData
io.configureStage := configureStage
io.finishedScriptConfiguration := finishedScriptConfiguration
io.targetOperator := targetOperator
}
object DebuggerPacketInterpreter {
def apply(
debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
instanceInfo: HwdbgInstanceInformation
)(
en: Bool,
requestedActionOfThePacketInput: UInt,
requestedActionOfThePacketInputValid: Bool,
dataValidInput: Bool,
receivingData: UInt,
sendWaitForBuffer: Bool
): (Bool, Bool, Bool, Bool, Bool, UInt, UInt, Bool, Bool, HwdbgShortSymbol) = {
val debuggerPacketInterpreter = Module(
new DebuggerPacketInterpreter(
debug,
instanceInfo
)
)
val noNewDataReceiver = Wire(Bool())
val readNextData = Wire(Bool())
val beginSendingBuffer = Wire(Bool())
val noNewDataSender = Wire(Bool())
val dataValidOutput = Wire(Bool())
val requestedActionOfThePacketOutput = Wire(UInt(new DebuggerRemotePacket().RequestedActionOfThePacket.getWidth.W))
val sendingData = Wire(UInt(instanceInfo.bramDataWidth.W))
val finishedScriptConfiguration = Wire(Bool())
val configureStage = Wire(Bool())
val targetOperator = Wire(new HwdbgShortSymbol(instanceInfo.scriptVariableLength))
//
// Configure the input signals
//
debuggerPacketInterpreter.io.en := en
//
// Configure the input signals related to the receiving signals
//
debuggerPacketInterpreter.io.requestedActionOfThePacketInput := requestedActionOfThePacketInput
debuggerPacketInterpreter.io.requestedActionOfThePacketInputValid := requestedActionOfThePacketInputValid
debuggerPacketInterpreter.io.dataValidInput := dataValidInput
debuggerPacketInterpreter.io.receivingData := receivingData
//
// Configure the input signals related to the sending signals
//
debuggerPacketInterpreter.io.sendWaitForBuffer := sendWaitForBuffer
//
// Configure the output signals
//
noNewDataReceiver := debuggerPacketInterpreter.io.noNewDataReceiver
readNextData := debuggerPacketInterpreter.io.readNextData
//
// Configure the output signals related to sending packets
//
beginSendingBuffer := debuggerPacketInterpreter.io.beginSendingBuffer
noNewDataSender := debuggerPacketInterpreter.io.noNewDataSender
dataValidOutput := debuggerPacketInterpreter.io.dataValidOutput
//
// Configure the output signals related to received packets
//
requestedActionOfThePacketOutput := debuggerPacketInterpreter.io.requestedActionOfThePacketOutput
sendingData := debuggerPacketInterpreter.io.sendingData
//
// Configure the output signals related to stage configuration
//
finishedScriptConfiguration := debuggerPacketInterpreter.io.finishedScriptConfiguration
configureStage := debuggerPacketInterpreter.io.configureStage
targetOperator := debuggerPacketInterpreter.io.targetOperator
//
// Return the output result
//
(
noNewDataReceiver,
readNextData,
beginSendingBuffer,
noNewDataSender,
dataValidOutput,
requestedActionOfThePacketOutput,
sendingData,
finishedScriptConfiguration,
configureStage,
targetOperator
)
}
}

View file

@ -1,462 +0,0 @@
/**
* @file
* port_information.scala
* @author
* Sina Karvandi (sina@hyperdbg.org)
* @brief
* Send port information (in interpreter)
* @details
* @version 0.1
* @date
* 2024-05-04
*
* @copyright
* This project is released under the GNU Public License v3.
*/
package hwdbg.communication.interpreter
import chisel3._
import chisel3.util.{switch, is, log2Ceil}
import circt.stage.ChiselStage
import hwdbg.configs._
import hwdbg.utils._
object InterpreterInstanceInfoEnums {
object State extends ChiselEnum {
val sIdle, sSendVersion, sSendMaximumNumberOfStages, sSendScriptVariableLength, sSendNumberOfSupportedLocalAndGlobalVariables,
sSendNumberOfSupportedTemporaryVariables, sSendMaximumNumberOfSupportedGetScriptOperators, sSendMaximumNumberOfSupportedSetScriptOperators,
sSendSharedMemorySize, sSendDebuggerAreaOffset, sSendDebuggeeAreaOffset, sSendNumberOfPins, sSendNumberOfPorts, sSendScriptCapabilities1,
sSendScriptCapabilities2, sSendBramAddrWidth, sSendBramDataWidth, sSendPortsConfiguration, sDone = Value
}
}
class InterpreterInstanceInfo(
debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
instanceInfo: HwdbgInstanceInformation
) extends Module {
//
// Import state enum
//
import InterpreterInstanceInfoEnums.State
import InterpreterInstanceInfoEnums.State._
val io = IO(new Bundle {
//
// Chip signals
//
val en = Input(Bool()) // chip enable signal
//
// Sending signals
//
val noNewDataSender = Output(Bool()) // should sender finish sending buffers or not?
val dataValidOutput = Output(Bool()) // should sender send next buffer or not?
val sendingData = Output(UInt(instanceInfo.bramDataWidth.W)) // data to be sent to the debugger
})
//
// State registers
//
val state = RegInit(sIdle)
//
// Get number of input/output ports
//
val numberOfPorts = instanceInfo.portsConfiguration.size
//
// Convert input port pins into vector
//
// val pinsVec = RegInit(VecInit(Seq.fill(numberOfPorts)(0.U(instanceInfo.bramDataWidth.W))))
val pinsVec = VecInit(instanceInfo.portsConfiguration.map(_.U))
//
// Determine the width for numberOfSentPins
//
val numberOfSentPinsWidth = log2Ceil(numberOfPorts)
//
// Registers for keeping track of sent pin details
//
val numberOfSentPins = RegInit(0.U(numberOfSentPinsWidth.W))
//
// Output pins
//
val noNewDataSender = WireInit(false.B)
val dataValidOutput = WireInit(false.B)
val sendingData = WireInit(0.U(instanceInfo.bramDataWidth.W))
//
// Apply the chip enable signal
//
when(io.en === true.B) {
switch(state) {
is(sIdle) {
//
// Going to the next state (sending the version of the debugger)
//
state := sSendVersion
}
is(sSendVersion) {
//
// Set the version
//
sendingData := instanceInfo.version.U
//
// The output is valid
//
dataValidOutput := true.B
state := sSendMaximumNumberOfStages
}
is(sSendMaximumNumberOfStages) {
//
// Set the maximum number of stages supported by this instance of the debugger
//
sendingData := instanceInfo.maximumNumberOfStages.U
//
// The output is valid
//
dataValidOutput := true.B
state := sSendScriptVariableLength
}
is(sSendScriptVariableLength) {
//
// Set the script variable length of this instance of the debugger
//
sendingData := instanceInfo.scriptVariableLength.U
//
// The output is valid
//
dataValidOutput := true.B
state := sSendNumberOfSupportedLocalAndGlobalVariables
}
is(sSendNumberOfSupportedLocalAndGlobalVariables) {
//
// Set the number of supported local variables for this instance of the debugger
//
sendingData := instanceInfo.numberOfSupportedLocalAndGlobalVariables.U
//
// The output is valid
//
dataValidOutput := true.B
state := sSendNumberOfSupportedTemporaryVariables
}
is(sSendNumberOfSupportedTemporaryVariables) {
//
// Set the number of supported temporary variables for this instance of the debugger
//
sendingData := instanceInfo.numberOfSupportedTemporaryVariables.U
//
// The output is valid
//
dataValidOutput := true.B
state := sSendMaximumNumberOfSupportedGetScriptOperators
}
is(sSendMaximumNumberOfSupportedGetScriptOperators) {
//
// Set the maximum number of supported GET operators by this instance of the
// debugger in the script engine
//
sendingData := instanceInfo.maximumNumberOfSupportedGetScriptOperators.U
//
// The output is valid
//
dataValidOutput := true.B
state := sSendMaximumNumberOfSupportedSetScriptOperators
}
is(sSendMaximumNumberOfSupportedSetScriptOperators) {
//
// Set the maximum number of supported SET operators by this instance of the
// debugger in the script engine
//
sendingData := instanceInfo.maximumNumberOfSupportedSetScriptOperators.U
//
// The output is valid
//
dataValidOutput := true.B
state := sSendSharedMemorySize
}
is(sSendSharedMemorySize) {
//
// Set the shared memory size used by this instance of the debugger
//
sendingData := instanceInfo.sharedMemorySize.U
//
// The output is valid
//
dataValidOutput := true.B
state := sSendDebuggerAreaOffset
}
is(sSendDebuggerAreaOffset) {
//
// Set the start offset of the debugger to the debuggee memory for this
// instance of the debugger
//
sendingData := instanceInfo.debuggerAreaOffset.U
//
// The output is valid
//
dataValidOutput := true.B
state := sSendDebuggeeAreaOffset
}
is(sSendDebuggeeAreaOffset) {
//
// Set the start offset of the debuggee to the debugger memory for this
// instance of the debugger
//
sendingData := instanceInfo.debuggeeAreaOffset.U
//
// The output is valid
//
dataValidOutput := true.B
state := sSendNumberOfPins
}
is(sSendNumberOfPins) {
//
// Set the number of pins in this instance of the debugger
//
sendingData := instanceInfo.numberOfPins.U
//
// The output is valid
//
dataValidOutput := true.B
state := sSendNumberOfPorts
}
is(sSendNumberOfPorts) {
//
// Set the number of ports in this instance of the debugger
//
sendingData := instanceInfo.numberOfPorts.U
//
// The output is valid
//
dataValidOutput := true.B
state := sSendScriptCapabilities1
}
is(sSendScriptCapabilities1) {
//
// Set the first bits (most significant) of the supported operators capabilities of this instance
// of the debugger
//
sendingData := BitwiseFunction
.getBitsInRange(instanceInfo.scriptCapabilities, instanceInfo.bramDataWidth, instanceInfo.bramDataWidth + instanceInfo.bramDataWidth - 1)
.U
//
// The output is valid
//
dataValidOutput := true.B
state := sSendScriptCapabilities2
}
is(sSendScriptCapabilities2) {
//
// Set the second bits (least significant) of the supported operators capabilities of this instance
// of the debugger
//
sendingData := BitwiseFunction.getBitsInRange(instanceInfo.scriptCapabilities, 0, instanceInfo.bramDataWidth - 1).U
//
// The output is valid
//
dataValidOutput := true.B
state := sSendBramAddrWidth
}
is(sSendBramAddrWidth) {
//
// Set the BRAM address width in this instance of the debugger
//
sendingData := instanceInfo.bramAddrWidth.U
//
// The output is valid
//
dataValidOutput := true.B
state := sSendBramDataWidth
}
is(sSendBramDataWidth) {
//
// Set the BRAM data width in this instance of the debugger
//
sendingData := instanceInfo.bramDataWidth.U
//
// The output is valid
//
dataValidOutput := true.B
state := sSendPortsConfiguration
}
is(sSendPortsConfiguration) {
//
// Send input port items
//
//
// Adjust data
//
sendingData := pinsVec(numberOfSentPins)
//
// Data is valid
//
dataValidOutput := true.B
when(numberOfSentPins === (numberOfPorts - 1).U) {
//
// Reset the pins sent for sending details
//
numberOfSentPins := 0.U
state := sDone
}.otherwise {
//
// Send next index
//
numberOfSentPins := numberOfSentPins + 1.U
//
// Stay at the same state
//
state := sSendPortsConfiguration
}
}
is(sDone) {
//
// Indicate that sending data is done
//
noNewDataSender := true.B
//
// Goto the idle state
//
state := sIdle
}
}
}
// ---------------------------------------------------------------------
//
// Connect output pins
//
io.noNewDataSender := noNewDataSender
io.dataValidOutput := dataValidOutput
io.sendingData := sendingData
}
object InterpreterInstanceInfo {
def apply(
debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
instanceInfo: HwdbgInstanceInformation
)(
en: Bool
): (Bool, Bool, UInt) = {
val interpreterInstanceInfo = Module(
new InterpreterInstanceInfo(
debug,
instanceInfo
)
)
val noNewDataSender = Wire(Bool())
val dataValidOutput = Wire(Bool())
val sendingData = Wire(UInt(instanceInfo.bramDataWidth.W))
//
// Configure the input signals
//
interpreterInstanceInfo.io.en := en
//
// Configure the output signals
//
noNewDataSender := interpreterInstanceInfo.io.noNewDataSender
dataValidOutput := interpreterInstanceInfo.io.dataValidOutput
sendingData := interpreterInstanceInfo.io.sendingData
//
// Return the output result
//
(
noNewDataSender,
dataValidOutput,
sendingData
)
}
}

View file

@ -1,301 +0,0 @@
/**
* @file
* script_buffer_handler.scala
* @author
* Sina Karvandi (sina@hyperdbg.org)
* @brief
* Configures the script stages from shared memory
* @details
* @version 0.1
* @date
* 2024-06-14
*
* @copyright
* This project is released under the GNU Public License v3.
*/
package hwdbg.communication.interpreter
import chisel3._
import chisel3.util.{switch, is}
import circt.stage.ChiselStage
import hwdbg.configs._
import hwdbg.types._
import hwdbg.script._
object InterpreterScriptBufferHandlerEnums {
object State extends ChiselEnum {
val sIdle, sReadSizeOfBuffer, sReadTypeOfOperator, sReadValueOfOperator, sDone = Value
}
}
class InterpreterScriptBufferHandler(
debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
instanceInfo: HwdbgInstanceInformation
) extends Module {
//
// Import state enum
//
import InterpreterScriptBufferHandlerEnums.State
import InterpreterScriptBufferHandlerEnums.State._
val io = IO(new Bundle {
//
// Chip signals
//
val en = Input(Bool()) // chip enable signal
//
// Receiving signals
//
val readNextData = Output(Bool()) // whether the next data should be read or not?
val dataValidInput = Input(Bool()) // whether data on the receiving data line is valid or not?
val receivingData = Input(UInt(instanceInfo.bramDataWidth.W)) // data to be received in interpreter
//
// Script stage configuration signals
//
val finishedScriptConfiguration = Output(Bool()) // whether configuration finished or not?
val configureStage = Output(Bool()) // whether the configuration of stage should start or not?
val targetOperator = Output(new HwdbgShortSymbol(instanceInfo.scriptVariableLength)) // Current operator to be configured
})
//
// State registers
//
val state = RegInit(sIdle)
//
// Internal registers
//
val regScriptNumberOfSymbols = Reg(UInt(instanceInfo.bramDataWidth.W))
//
// Output pins
//
val readNextData = WireInit(false.B)
val finishedScriptConfiguration = WireInit(false.B)
val configureStage = RegInit(false.B)
val regTargetOperator = Reg(new HwdbgShortSymbol(instanceInfo.scriptVariableLength))
//
// Apply the chip enable signal
//
when(io.en === true.B) {
switch(state) {
is(sIdle) {
//
// Read next data for the size of the buffer
//
readNextData := true.B
//
// Move to the next state
//
state := sReadSizeOfBuffer
}
is(sReadSizeOfBuffer) {
when(io.dataValidInput) {
//
// Data is valid and number of symbols is now available
//
regScriptNumberOfSymbols := io.receivingData
//
// Request next data
//
readNextData := true.B
//
// Move to the configuration state
//
state := sReadTypeOfOperator
}.otherwise {
//
// Stay at the same state since the data is not yet received
//
state := sReadSizeOfBuffer
}
}
is(sReadTypeOfOperator) {
//
// Not valid for configuring yet
//
configureStage := false.B
when(io.dataValidInput) {
//
// Request next data
//
readNextData := true.B
//
// Read the operator's "Type" data
//
regTargetOperator.Type := io.receivingData
//
// Next, we need to read "Value"
//
state := sReadValueOfOperator
}.otherwise {
//
// Stay at the same state since the data is not received yet
//
state := sReadTypeOfOperator
}
}
is(sReadValueOfOperator) {
when(io.dataValidInput) {
//
// Configure the stages
//
configureStage := true.B
//
// Read the operator's "Value" data
//
regTargetOperator.Value := io.receivingData
//
// Decrement the remaining symbols
//
regScriptNumberOfSymbols := regScriptNumberOfSymbols - 1.U
//
// Check if reading is scripts are finished or not
//
when(regScriptNumberOfSymbols === 0.U) {
//
// Configurartion was done
//
state := sDone
}.otherwise {
//
// Request next data
//
readNextData := true.B
//
// Again, read the next type
//
state := sReadTypeOfOperator
}
}.otherwise {
//
// Stay at the same state since the data is not received yet
//
state := sReadValueOfOperator
}
}
is(sDone) {
//
// Not valid for configuring anymore
//
configureStage := false.B
//
// Finished configuration
//
finishedScriptConfiguration := true.B
//
// Move to the idle state
//
state := sIdle
}
}
}
//
// Connect output pins
//
io.readNextData := readNextData
io.finishedScriptConfiguration := finishedScriptConfiguration
io.configureStage := configureStage
io.targetOperator := regTargetOperator
}
object InterpreterScriptBufferHandler {
def apply(
debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
instanceInfo: HwdbgInstanceInformation
)(
en: Bool,
dataValidInput: Bool,
receivingData: UInt
): (Bool, Bool, Bool, HwdbgShortSymbol) = {
val interpreterScriptBufferHandler = Module(
new InterpreterScriptBufferHandler(
debug,
instanceInfo
)
)
val readNextData = Wire(Bool())
val finishedScriptConfiguration = Wire(Bool())
val configureStage = Wire(Bool())
val targetOperator = Wire(new HwdbgShortSymbol(instanceInfo.scriptVariableLength))
//
// Configure the input signals
//
interpreterScriptBufferHandler.io.en := en
//
// Configure the input signals related to the receiving signals
//
interpreterScriptBufferHandler.io.dataValidInput := dataValidInput
interpreterScriptBufferHandler.io.receivingData := receivingData
//
// Configure the output signals
//
readNextData := interpreterScriptBufferHandler.io.readNextData
//
// Configure the output signals related to configuring stage operators
//
finishedScriptConfiguration := interpreterScriptBufferHandler.io.finishedScriptConfiguration
configureStage := interpreterScriptBufferHandler.io.configureStage
targetOperator := interpreterScriptBufferHandler.io.targetOperator
//
// Return the output result
//
(
readNextData,
finishedScriptConfiguration,
configureStage,
targetOperator
)
}
}

View file

@ -1,125 +0,0 @@
/**
* @file
* send_success_or_error.scala
* @author
* Sina Karvandi (sina@hyperdbg.org)
* @brief
* Send an indication of invalid packet error or success message (in the interpreter)
* @details
* @version 0.1
* @date
* 2024-05-04
*
* @copyright
* This project is released under the GNU Public License v3.
*/
package hwdbg.communication.interpreter
import chisel3._
import chisel3.util.{switch, is}
import circt.stage.ChiselStage
import hwdbg.configs._
class InterpreterSendSuccessOrError(
debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
instanceInfo: HwdbgInstanceInformation
) extends Module {
val io = IO(new Bundle {
//
// Chip signals
//
val en = Input(Bool()) // chip enable signal
val lastSuccessOrError = Input(UInt(instanceInfo.bramDataWidth.W)) // input last error
//
// Sending signals
//
val noNewDataSender = Output(Bool()) // should sender finish sending buffers or not?
val dataValidOutput = Output(Bool()) // should sender send next buffer or not?
val sendingData = Output(UInt(instanceInfo.bramDataWidth.W)) // data to be sent to the debugger
})
//
// Output pins
//
val noNewDataSender = WireInit(false.B)
val dataValidOutput = WireInit(false.B)
val sendingData = WireInit(0.U(instanceInfo.bramDataWidth.W))
//
// Apply the chip enable signal
//
when(io.en === true.B) {
//
// Set the version
//
sendingData := io.lastSuccessOrError
//
// Sending the version in one clock cycle
//
noNewDataSender := true.B
dataValidOutput := true.B
}
// ---------------------------------------------------------------------
//
// Connect output pins
//
io.noNewDataSender := noNewDataSender
io.dataValidOutput := dataValidOutput
io.sendingData := sendingData
}
object InterpreterSendSuccessOrError {
def apply(
debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
instanceInfo: HwdbgInstanceInformation
)(
en: Bool,
lastSuccessOrError: UInt
): (Bool, Bool, UInt) = {
val interpreterSendSuccessOrError = Module(
new InterpreterSendSuccessOrError(
debug,
instanceInfo
)
)
val noNewDataSender = Wire(Bool())
val dataValidOutput = Wire(Bool())
val sendingData = Wire(UInt(instanceInfo.bramDataWidth.W))
//
// Configure the input signals
//
interpreterSendSuccessOrError.io.en := en
interpreterSendSuccessOrError.io.lastSuccessOrError := lastSuccessOrError
//
// Configure the output signals
//
noNewDataSender := interpreterSendSuccessOrError.io.noNewDataSender
dataValidOutput := interpreterSendSuccessOrError.io.dataValidOutput
sendingData := interpreterSendSuccessOrError.io.sendingData
//
// Return the output result
//
(
noNewDataSender,
dataValidOutput,
sendingData
)
}
}

View file

@ -1,444 +0,0 @@
/**
* @file
* receiver.scala
* @author
* Sina Karvandi (sina@hyperdbg.org)
* @brief
* Remote debugger packet receiver module
* @details
* @version 0.1
* @date
* 2024-04-08
*
* @copyright
* This project is released under the GNU Public License v3.
*/
package hwdbg.communication
import chisel3._
import chisel3.util.{switch, is}
import circt.stage.ChiselStage
import hwdbg.configs._
import hwdbg.types._
import hwdbg.utils._
import hwdbg.constants._
object DebuggerPacketReceiverEnums {
object State extends ChiselEnum {
val sIdle, sReadChecksum, sReadIndicator, sReadTypeOfThePacket, sReadRequestedActionOfThePacket, sRequestedActionIsValid, sWaitToReadActionBuffer,
sReadActionBuffer, sDone = Value
}
}
class DebuggerPacketReceiver(
debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
instanceInfo: HwdbgInstanceInformation
) extends Module {
//
// Import state enum
//
import DebuggerPacketReceiverEnums.State
import DebuggerPacketReceiverEnums.State._
val io = IO(new Bundle {
//
// Chip signals
//
val en = Input(Bool()) // chip enable signal
//
// Interrupt signals (lines)
// Note: Only PL input signal is received here,
// a separate module will control the PS signal
//
val plInSignal = Input(Bool()) // PS to PL signal
//
// BRAM (Block RAM) ports
//
val rdWrAddr = Output(UInt(instanceInfo.bramAddrWidth.W)) // read/write address
val rdData = Input(UInt(instanceInfo.bramDataWidth.W)) // read data
//
// Receiving signals
//
val requestedActionOfThePacketOutput = Output(UInt(new DebuggerRemotePacket().RequestedActionOfThePacket.getWidth.W)) // the requested action
val requestedActionOfThePacketOutputValid = Output(Bool()) // whether data on the requested action is valid or not
val noNewDataReceiver = Input(Bool()) // receive done or not?
// this contains and edge-detection mechanism, which means reader should make it low after reading the data
val readNextData = Input(Bool()) // whether the next data should be read or not?
val dataValidOutput = Output(Bool()) // whether data on the receiving data line is valid or not?
val receivingData = Output(UInt(instanceInfo.bramDataWidth.W)) // data to be sent to the reader
val finishedReceivingBuffer = Output(Bool()) // Receiving is done or not?
})
//
// State registers
//
val state = RegInit(sIdle)
//
// Output pins
//
val rdWrAddr = WireInit(0.U(instanceInfo.bramAddrWidth.W))
val regRdWrAddr = RegInit(0.U(instanceInfo.bramAddrWidth.W))
val finishedReceivingBuffer = WireInit(false.B)
val regRequestedActionOfThePacketOutput = RegInit(0.U(new DebuggerRemotePacket().RequestedActionOfThePacket.getWidth.W))
val regRequestedActionOfThePacketOutputValid = RegInit(false.B)
val regDataValidOutput = RegInit(false.B)
val regReceivingData = RegInit(0.U(instanceInfo.bramDataWidth.W))
//
// Rising-edge detector for start receiving signal
//
val risingEdgePlInSignal = io.plInSignal & !RegNext(io.plInSignal)
//
// Rising-edge detector for reading next data signal
//
val risingEdgeReadNextData = io.readNextData & !RegNext(io.readNextData)
//
// Structure (as wire) of the received packet buffer
//
val receivedPacketBuffer = WireInit(0.U.asTypeOf(new DebuggerRemotePacket())) // here the wire is not used
//
// Apply the chip enable signal
//
when(io.en === true.B) {
switch(state) {
is(sIdle) {
//
// Create logs from communication structure offsets
//
LogInfo(debug)(f"The offset of Checksum is 0x${receivedPacketBuffer.Offset.checksum}%x")
LogInfo(debug)(f"The offset of Indicator is 0x${receivedPacketBuffer.Offset.indicator}%x")
LogInfo(debug)(f"The offset of TypeOfThePacket is 0x${receivedPacketBuffer.Offset.typeOfThePacket}%x")
LogInfo(debug)(f"The offset of requestedActionOfThePacketOutput is 0x${receivedPacketBuffer.Offset.requestedActionOfThePacket}%x")
//
// Check whether the interrupt from the PS is received or not
//
when(risingEdgePlInSignal === true.B) {
state := sReadChecksum
}
//
// Configure the output pins in case of sIdle
//
rdWrAddr := 0.U
regRequestedActionOfThePacketOutput := 0.U
regRequestedActionOfThePacketOutputValid := false.B
regDataValidOutput := false.B
regReceivingData := 0.U
finishedReceivingBuffer := false.B
}
is(sReadChecksum) {
//
// Adjust address to read Checksum from BRAM (Not Used)
//
rdWrAddr := (instanceInfo.debuggerAreaOffset + receivedPacketBuffer.Offset.checksum).U
//
// Goes to the next section
//
state := sReadIndicator
}
is(sReadIndicator) {
//
// Adjust address to read Indicator from BRAM
//
rdWrAddr := (instanceInfo.debuggerAreaOffset + receivedPacketBuffer.Offset.indicator).U
//
// Goes to the next section
//
state := sReadTypeOfThePacket
}
is(sReadTypeOfThePacket) {
//
// Adjust address to read TypeOfThePacket from BRAM
//
rdWrAddr := (instanceInfo.debuggerAreaOffset + receivedPacketBuffer.Offset.typeOfThePacket).U
//
// Check whether the indicator is valid or not
//
LogInfo(debug)(
f"Comparing first 0x${BitwiseFunction.getBitsInRange(HyperDbgSharedConstants.INDICATOR_OF_HYPERDBG_PACKET, 32, (32 + instanceInfo.bramDataWidth - 1))}%x number of the indicator (little-endian)"
)
when(
io.rdData === BitwiseFunction
.getBitsInRange(HyperDbgSharedConstants.INDICATOR_OF_HYPERDBG_PACKET, 32, (32 + instanceInfo.bramDataWidth - 1))
.U
) {
//
// Indicator of packet is valid
// (Goes to the next section)
//
state := sReadRequestedActionOfThePacket
}.otherwise {
//
// Indicator of packet is not valid
// (Receiving was done but not found a valid packet,
// so, go to the idle state)
//
state := sDone
}
}
is(sReadRequestedActionOfThePacket) {
//
// Adjust address to read RequestedActionOfThePacket from BRAM
//
rdWrAddr := (instanceInfo.debuggerAreaOffset + receivedPacketBuffer.Offset.requestedActionOfThePacket).U
//
// Save the address into a register
//
regRdWrAddr := (instanceInfo.debuggerAreaOffset + receivedPacketBuffer.Offset.requestedActionOfThePacket + (instanceInfo.bramDataWidth >> 3)).U
//
// Check whether the type of the packet is valid or not
//
val packetType: DebuggerRemotePacketType.Value = DebuggerRemotePacketType.DEBUGGER_TO_DEBUGGEE_HARDWARE_LEVEL
LogInfo(debug)(
f"Check packet type with DEBUGGER_TO_DEBUGGEE_HARDWARE_LEVEL (0x${packetType.id}%x)"
)
when(io.rdData === packetType.id.U) {
//
// Type of packet is valid
// (Goes to the next section)
//
state := sRequestedActionIsValid
}.otherwise {
//
// Type of packet is not valid
// (Receiving was done but not found a valid packet,
// so, go to the idle state)
//
state := sDone
}
}
is(sRequestedActionIsValid) {
//
// Read the RequestedActionOfThePacket
//
regRequestedActionOfThePacketOutput := io.rdData
//
// The RequestedActionOfThePacketOutput is valid from now
//
regRequestedActionOfThePacketOutputValid := true.B
//
// Goes to the next section
//
state := sWaitToReadActionBuffer
}
is(sWaitToReadActionBuffer) {
//
// The value of the received buffer is valid here, however,
// in order to make difference when a new value is read, the
// following signals goes to the off state
//
regDataValidOutput := false.B
//
// Check if the caller needs to read the next part of
// the block RAM or the receiving data should be finished
//
when(io.noNewDataReceiver === true.B) {
//
// No new data, the receiving is done
//
state := sDone
}.elsewhen(risingEdgeReadNextData === true.B) {
//
// Adjust address to read next data to BRAM
//
rdWrAddr := regRdWrAddr
regRdWrAddr := regRdWrAddr + (instanceInfo.bramDataWidth >> 3).U
//
// Read the next offset of the buffer
//
state := sReadActionBuffer
}.otherwise {
//
// Stay at the same state
//
state := sWaitToReadActionBuffer
}
}
is(sReadActionBuffer) {
//
// Data outputs are now valid
//
regDataValidOutput := true.B
//
// Adjust the read buffer data
//
regReceivingData := io.rdData
when(io.noNewDataReceiver === true.B) {
//
// No new data, the receiving is done
//
state := sDone
}.otherwise {
//
// Return to the previous state of action
//
state := sWaitToReadActionBuffer
}
}
is(sDone) {
//
// Reset the temporary address holder
//
regRdWrAddr := 0.U
//
// Requested action buffer and the receiving buffer is no longer valid
//
regRequestedActionOfThePacketOutput := 0.U
regRequestedActionOfThePacketOutputValid := false.B
regReceivingData := 0.U
regDataValidOutput := false.B
//
// The receiving is done at this stage, either
// was successful or unsuccessful, we'll release the
// sharing bram resource by indicating that the receiving
// module is no longer using the bram line
//
finishedReceivingBuffer := true.B
//
// Go to the idle state
//
state := sIdle
}
}
}
// ---------------------------------------------------------------------
//
// Connect output pins
//
io.rdWrAddr := rdWrAddr
io.requestedActionOfThePacketOutput := regRequestedActionOfThePacketOutput
io.requestedActionOfThePacketOutputValid := regRequestedActionOfThePacketOutputValid
io.dataValidOutput := regDataValidOutput
io.receivingData := regReceivingData
io.finishedReceivingBuffer := finishedReceivingBuffer
}
object DebuggerPacketReceiver {
def apply(
debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
instanceInfo: HwdbgInstanceInformation
)(
en: Bool,
plInSignal: Bool,
rdData: UInt,
noNewDataReceiver: Bool,
readNextData: Bool
): (UInt, UInt, Bool, Bool, UInt, Bool) = {
val debuggerPacketReceiver = Module(
new DebuggerPacketReceiver(
debug,
instanceInfo
)
)
val rdWrAddr = Wire(UInt(instanceInfo.bramAddrWidth.W))
val requestedActionOfThePacketOutput = Wire(UInt(new DebuggerRemotePacket().RequestedActionOfThePacket.getWidth.W))
val requestedActionOfThePacketOutputValid = Wire(Bool())
val dataValidOutput = Wire(Bool())
val receivingData = Wire(UInt(instanceInfo.bramDataWidth.W))
val finishedReceivingBuffer = Wire(Bool())
//
// Configure the input signals
//
debuggerPacketReceiver.io.en := en
debuggerPacketReceiver.io.plInSignal := plInSignal
debuggerPacketReceiver.io.rdData := rdData
debuggerPacketReceiver.io.noNewDataReceiver := noNewDataReceiver
debuggerPacketReceiver.io.readNextData := readNextData
//
// Configure the output signals
//
rdWrAddr := debuggerPacketReceiver.io.rdWrAddr
//
// Configure the output signals related to received packets
//
requestedActionOfThePacketOutput := debuggerPacketReceiver.io.requestedActionOfThePacketOutput
requestedActionOfThePacketOutputValid := debuggerPacketReceiver.io.requestedActionOfThePacketOutputValid
dataValidOutput := debuggerPacketReceiver.io.dataValidOutput
receivingData := debuggerPacketReceiver.io.receivingData
finishedReceivingBuffer := debuggerPacketReceiver.io.finishedReceivingBuffer
//
// Return the output result
//
(
rdWrAddr,
requestedActionOfThePacketOutput,
requestedActionOfThePacketOutputValid,
dataValidOutput,
receivingData,
finishedReceivingBuffer
)
}
}

View file

@ -1,383 +0,0 @@
/**
* @file
* send_receive_synchronizer.scala
* @author
* Sina Karvandi (sina@hyperdbg.org)
* @brief
* Send and receive synchronizer module
* @details
* @version 0.1
* @date
* 2024-04-17
*
* @copyright
* This project is released under the GNU Public License v3.
*/
package hwdbg.communication
import chisel3._
import chisel3.util.{switch, is}
import circt.stage.ChiselStage
import hwdbg.configs._
import hwdbg.types._
object SendReceiveSynchronizerEnums {
object State extends ChiselEnum {
val sIdle, sReceiver, sSender = Value
}
}
class SendReceiveSynchronizer(
debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
instanceInfo: HwdbgInstanceInformation
) extends Module {
//
// Import state enum
//
import SendReceiveSynchronizerEnums.State
import SendReceiveSynchronizerEnums.State._
val io = IO(new Bundle {
//
// Chip signals
//
val en = Input(Bool()) // chip enable signal
//
// Interrupt signals (lines)
//
val plInSignal = Input(Bool()) // PS to PL signal
val psOutInterrupt = Output(Bool()) // PL to PS interrupt
//
// BRAM (Block RAM) ports
//
val rdWrAddr = Output(UInt(instanceInfo.bramAddrWidth.W)) // read/write address
val rdData = Input(UInt(instanceInfo.bramDataWidth.W)) // read data
val wrEna = Output(Bool()) // enable writing
val wrData = Output(UInt(instanceInfo.bramDataWidth.W)) // write data
//
// Receiver ports
//
val requestedActionOfThePacketOutput = Output(UInt(new DebuggerRemotePacket().RequestedActionOfThePacket.getWidth.W)) // the requested action
val requestedActionOfThePacketOutputValid = Output(Bool()) // whether data on the requested action is valid or not
val noNewDataReceiver = Input(Bool()) // receive done or not?
val readNextData = Input(Bool()) // whether the next data should be read or not?
val dataValidOutput = Output(Bool()) // whether data on the receiving data line is valid or not?
val receivingData = Output(UInt(instanceInfo.bramDataWidth.W)) // data to be sent to the reader
//
// Sender ports
//
val beginSendingBuffer = Input(Bool()) // should sender start sending buffers or not?
val noNewDataSender = Input(Bool()) // should sender finish sending buffers or not?
val dataValidInput = Input(Bool()) // should sender send next buffer or not?
val sendWaitForBuffer = Output(Bool()) // should the external module send next buffer or not?
val requestedActionOfThePacketInput = Input(UInt(new DebuggerRemotePacket().RequestedActionOfThePacket.getWidth.W)) // the requested action
val sendingData = Input(UInt(instanceInfo.bramDataWidth.W)) // data to be sent to the debugger
})
//
// State registers
//
val state = RegInit(sIdle)
//
// Saving state of the controlling pins
//
val regPlInSignal = RegInit(false.B)
val regBeginSendingBuffer = RegInit(false.B)
//
// Shared BRAM pins
//
val sharedRdWrAddr = WireInit(0.U(instanceInfo.bramAddrWidth.W)) // read/write address
val sharedRdData = WireInit(0.U(instanceInfo.bramDataWidth.W)) // read data
val sharedWrEna = WireInit(false.B) // enable writing
val sharedWrData = WireInit(0.U(instanceInfo.bramDataWidth.W)) // write data
//
// Instantiate the packet receiver module
//
val (
receiverRdWrAddr,
requestedActionOfThePacketOutput,
requestedActionOfThePacketOutputValid,
dataValidOutput,
receivingData,
finishedReceivingBuffer
) =
DebuggerPacketReceiver(
debug,
instanceInfo
)(
io.en,
regPlInSignal,
io.rdData,
io.noNewDataReceiver,
io.readNextData
)
//
// Instantiate the packet sender module
//
val (
psOutInterrupt,
senderRdWrAddr,
wrEna,
wrData,
sendWaitForBuffer,
finishedSendingBuffer
) =
DebuggerPacketSender(
debug,
instanceInfo
)(
io.en,
regBeginSendingBuffer,
io.noNewDataSender,
io.dataValidInput,
io.requestedActionOfThePacketInput,
io.sendingData
)
//
// Apply the chip enable signal
//
when(io.en === true.B) {
switch(state) {
is(sIdle) {
//
// Perform the resource separation of shared BRAM
// and apply priority to receive over send
//
when(io.plInSignal === true.B) {
//
// Activate the receiver module
//
regPlInSignal := true.B
//
// Go to the receiver state
//
state := sReceiver
}.elsewhen(io.beginSendingBuffer === true.B && io.plInSignal === false.B) {
//
// Activate the sender module
//
regBeginSendingBuffer := true.B
//
// Go to the sender state
//
state := sSender
}.otherwise {
//
// Stay at the same state as there is no communication
//
state := sIdle
}
}
is(sReceiver) {
//
// Check whether the receiving is finished
//
when(finishedReceivingBuffer === true.B) {
//
// No longer in the receiver state
//
regPlInSignal := false.B
//
// Go to the idle state
//
state := sIdle
}.otherwise {
//
// Connect the address of BRAM reader to the receiver address
//
sharedRdWrAddr := receiverRdWrAddr
//
// On the receiver, writing is not allowed
//
sharedWrEna := false.B
//
// Stay at the same state
//
state := sReceiver
}
}
is(sSender) {
//
// Check whether sending data is finished
//
when(finishedSendingBuffer === true.B) {
//
// No longer in the sender state
//
regBeginSendingBuffer := false.B
//
// Go to the idle state
//
state := sIdle
}.otherwise {
//
// Connect shared BRAM signals to the sender
//
sharedRdWrAddr := senderRdWrAddr
sharedWrEna := wrEna
sharedWrData := wrData
//
// Stay at the same state
//
state := sSender
}
}
}
}
// ---------------------------------------------------------------------
//
// Connect output pins (Interrupt)
//
io.psOutInterrupt := psOutInterrupt
//
// Connect output pins (BRAM)
//
io.rdWrAddr := sharedRdWrAddr
io.wrEna := wrEna
io.wrData := wrData
//
// Connect output pins (Receiver)
//
io.requestedActionOfThePacketOutput := requestedActionOfThePacketOutput
io.requestedActionOfThePacketOutputValid := requestedActionOfThePacketOutputValid
io.dataValidOutput := dataValidOutput
io.receivingData := receivingData
//
// Connect output pins (Sender)
//
io.sendWaitForBuffer := sendWaitForBuffer
}
object SendReceiveSynchronizer {
def apply(
debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
instanceInfo: HwdbgInstanceInformation
)(
en: Bool,
plInSignal: Bool,
rdData: UInt,
noNewDataReceiver: Bool,
readNextData: Bool,
beginSendingBuffer: Bool,
noNewDataSender: Bool,
dataValidInput: Bool,
requestedActionOfThePacketInput: UInt,
sendingData: UInt
): (Bool, UInt, Bool, UInt, UInt, Bool, Bool, UInt, Bool) = {
val sendReceiveSynchronizerModule = Module(
new SendReceiveSynchronizer(
debug,
instanceInfo
)
)
val psOutInterrupt = Wire(Bool())
val rdWrAddr = Wire(UInt(instanceInfo.bramAddrWidth.W))
val wrEna = Wire(Bool())
val wrData = Wire(UInt(instanceInfo.bramDataWidth.W))
val requestedActionOfThePacketOutput = Wire(UInt(new DebuggerRemotePacket().RequestedActionOfThePacket.getWidth.W))
val requestedActionOfThePacketOutputValid = Wire(Bool())
val dataValidOutput = Wire(Bool())
val receivingData = Wire(UInt(instanceInfo.bramDataWidth.W))
val sendWaitForBuffer = Wire(Bool())
//
// Configure the input signals
//
sendReceiveSynchronizerModule.io.en := en
sendReceiveSynchronizerModule.io.plInSignal := plInSignal
sendReceiveSynchronizerModule.io.rdData := rdData
sendReceiveSynchronizerModule.io.noNewDataReceiver := noNewDataReceiver
sendReceiveSynchronizerModule.io.readNextData := readNextData
sendReceiveSynchronizerModule.io.beginSendingBuffer := beginSendingBuffer
sendReceiveSynchronizerModule.io.noNewDataSender := noNewDataSender
sendReceiveSynchronizerModule.io.dataValidInput := dataValidInput
sendReceiveSynchronizerModule.io.requestedActionOfThePacketInput := requestedActionOfThePacketInput
sendReceiveSynchronizerModule.io.sendingData := sendingData
//
// Configure the output signals
//
psOutInterrupt := sendReceiveSynchronizerModule.io.psOutInterrupt
rdWrAddr := sendReceiveSynchronizerModule.io.rdWrAddr
wrEna := sendReceiveSynchronizerModule.io.wrEna
wrData := sendReceiveSynchronizerModule.io.wrData
requestedActionOfThePacketOutput := sendReceiveSynchronizerModule.io.requestedActionOfThePacketOutput
requestedActionOfThePacketOutputValid := sendReceiveSynchronizerModule.io.requestedActionOfThePacketOutputValid
dataValidOutput := sendReceiveSynchronizerModule.io.dataValidOutput
receivingData := sendReceiveSynchronizerModule.io.receivingData
sendWaitForBuffer := sendReceiveSynchronizerModule.io.sendWaitForBuffer
//
// Return the output result
//
(
psOutInterrupt,
rdWrAddr,
wrEna,
wrData,
requestedActionOfThePacketOutput,
requestedActionOfThePacketOutputValid,
dataValidOutput,
receivingData,
sendWaitForBuffer
)
}
}

View file

@ -1,494 +0,0 @@
/**
* @file
* sender.scala
* @author
* Sina Karvandi (sina@hyperdbg.org)
* @brief
* Remote debugger packet sender module
* @details
* @version 0.1
* @date
* 2024-04-16
*
* @copyright
* This project is released under the GNU Public License v3.
*/
package hwdbg.communication
import chisel3._
import chisel3.util.{switch, is, log2Ceil}
import circt.stage.ChiselStage
import hwdbg.configs._
import hwdbg.types._
import hwdbg.constants._
object DebuggerPacketSenderEnums {
object State extends ChiselEnum {
val sIdle, sWriteChecksum, sWriteIndicator, sWriteTypeOfThePacket, sWriteRequestedActionOfThePacket, sWaitToGetData, sSendData, sDone = Value
}
}
class DebuggerPacketSender(
debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
instanceInfo: HwdbgInstanceInformation
) extends Module {
//
// Import state enum
//
import DebuggerPacketSenderEnums.State
import DebuggerPacketSenderEnums.State._
val io = IO(new Bundle {
//
// Chip signals
//
val en = Input(Bool()) // chip enable signal
//
// Interrupt signals (lines)
// Note: Only PS output signal is exported here,
// a separate module will control the PL signal
//
val psOutInterrupt = Output(Bool()) // PL to PS interrupt
//
// BRAM (Block RAM) ports
//
val rdWrAddr = Output(UInt(instanceInfo.bramAddrWidth.W)) // read/write address
val wrEna = Output(Bool()) // enable writing
val wrData = Output(UInt(instanceInfo.bramDataWidth.W)) // write data
//
// Sending signals
//
val beginSendingBuffer = Input(Bool()) // should sender start sending buffers or not?
val noNewDataSender = Input(Bool()) // should sender finish sending buffers or not?
val dataValidInput = Input(Bool()) // should sender send next buffer or not?
val sendWaitForBuffer = Output(Bool()) // should the external module send next buffer or not?
val finishedSendingBuffer = Output(Bool()) // indicate that the sender finished sending buffers and ready to send next packet
val requestedActionOfThePacketInput = Input(UInt(new DebuggerRemotePacket().RequestedActionOfThePacket.getWidth.W)) // the requested action
val sendingData = Input(UInt(instanceInfo.bramDataWidth.W)) // data to be sent to the debugger
})
//
// State registers
//
val state = RegInit(sIdle)
//
// Output pins
//
val psOutInterrupt = WireInit(false.B)
val wrEna = WireInit(false.B)
val wrData = WireInit(0.U(instanceInfo.bramDataWidth.W))
val sendWaitForBuffer = WireInit(false.B)
val finishedSendingBuffer = WireInit(false.B)
val rdWrAddr = WireInit(0.U(instanceInfo.bramAddrWidth.W))
//
// Temporary address and data holder (register)
//
val regRdWrAddr = RegInit(0.U(instanceInfo.bramAddrWidth.W))
val regDataToSend = RegInit(0.U(instanceInfo.bramDataWidth.W))
//
// Rising-edge detector for start sending signal
//
val risingEdgeBeginSendingBuffer = io.beginSendingBuffer & !RegNext(io.beginSendingBuffer)
//
// Keeping the state of whether sending data has been started or not
// Means that if the sender is in the middle of sending the headers
// of the packet or the actual data
//
val regIsSendingDataStarted = RegInit(false.B)
//
// Used to hold the transferred length of the indicator
//
val lengthOfIndicator: Int = new DebuggerRemotePacket().Indicator.getWidth
val regTransferredIndicatorLength = RegInit(0.U((log2Ceil(lengthOfIndicator) + 1).W))
//
// Structure (as wire) of the received packet buffer
//
val sendingPacketBuffer = WireInit(0.U.asTypeOf(new DebuggerRemotePacket()))
//
// Apply the chip enable signal
//
when(io.en === true.B) {
switch(state) {
is(sIdle) {
//
// Check whether the interrupt from the PS is received or not
//
when(risingEdgeBeginSendingBuffer === true.B) {
state := sWriteChecksum
}
//
// Configure the outputs in case of sIdle
//
psOutInterrupt := false.B
rdWrAddr := 0.U
regRdWrAddr := 0.U
wrEna := false.B
wrData := 0.U
sendWaitForBuffer := false.B
finishedSendingBuffer := false.B
//
// Sending data has not been started
//
regIsSendingDataStarted := false.B
}
is(sWriteChecksum) {
//
// Enable writing to the BRAM
//
wrEna := true.B
//
// Adjust address to write Checksum to BRAM (Not Used)
//
rdWrAddr := (instanceInfo.debuggeeAreaOffset + sendingPacketBuffer.Offset.checksum).U
//
// Adjust data to write Checksum
//
wrData := 0.U // Checksum is ignored
//
// Reset the transferred bytes of the indicator
//
regTransferredIndicatorLength := 0.U
//
// Goes to the next section
//
state := sWriteIndicator
}
is(sWriteIndicator) {
if (instanceInfo.bramDataWidth >= lengthOfIndicator) {
//
// Enable writing to the BRAM
//
wrEna := true.B
//
// Adjust address to write Indicator to BRAM
//
rdWrAddr := (instanceInfo.debuggeeAreaOffset + sendingPacketBuffer.Offset.indicator).U
//
// Adjust data to write Indicator
//
wrData := HyperDbgSharedConstants.INDICATOR_OF_HYPERDBG_PACKET.U
//
// Goes to the next section
//
state := sWriteTypeOfThePacket
} else {
//
// Enable writing to the BRAM
//
wrEna := true.B
//
// Adjust address to write Indicator to BRAM (Address granularity is in the byte format so,
// it'll be divided by 8 or shift to right by 3)
//
rdWrAddr := (instanceInfo.debuggeeAreaOffset + sendingPacketBuffer.Offset.indicator).U + (regTransferredIndicatorLength >> 3)
//
// Adjust data to write Indicator
//
wrData := HyperDbgSharedConstants.INDICATOR_OF_HYPERDBG_PACKET.U >> regTransferredIndicatorLength
//
// Add to the transferred length
//
regTransferredIndicatorLength := regTransferredIndicatorLength + instanceInfo.bramDataWidth.U
when(regTransferredIndicatorLength >= lengthOfIndicator.U) {
//
// Disable writing to the BRAM
//
wrEna := false.B
//
// Goes to the next section
//
state := sWriteTypeOfThePacket
}.otherwise {
//
// Stay at the same state
//
state := sWriteIndicator
}
}
}
is(sWriteTypeOfThePacket) {
//
// Enable writing to the BRAM
//
wrEna := true.B
//
// Adjust address to write type of packet to BRAM
//
rdWrAddr := (instanceInfo.debuggeeAreaOffset + sendingPacketBuffer.Offset.typeOfThePacket).U
//
// Adjust data to write type of packet
//
val packetType: DebuggerRemotePacketType.Value = DebuggerRemotePacketType.DEBUGGEE_TO_DEBUGGER_HARDWARE_LEVEL
wrData := packetType.id.U
//
// Goes to the next section
//
state := sWriteRequestedActionOfThePacket
}
is(sWriteRequestedActionOfThePacket) {
//
// Enable writing to the BRAM
//
wrEna := true.B
//
// Adjust address to write requested action of packet to BRAM
//
rdWrAddr := (instanceInfo.debuggeeAreaOffset + sendingPacketBuffer.Offset.requestedActionOfThePacket).U
//
// Adjust data to write requested action of packet
//
wrData := io.requestedActionOfThePacketInput
//
// Goes to the next section
//
state := sWaitToGetData
}
is(sWaitToGetData) {
//
// Disable writing to the BRAM
//
wrEna := false.B
//
// Indicate that the module is waiting for data
//
sendWaitForBuffer := true.B
//
// Check whether sending actual data already started or not
//
when(regIsSendingDataStarted === false.B) {
//
// It's not yet started, so we adjust the address to the start
// of the buffer after the last field of the header
//
regRdWrAddr := (instanceInfo.debuggeeAreaOffset + sendingPacketBuffer.Offset.startOfDataBuffer).U
//
// Indicate that sending data already started
//
regIsSendingDataStarted := true.B
}
//
// Wait to receive the data or check whether sending was done at this state
// (Two states will go us to the 'done' state)
//
when(io.noNewDataSender === true.B) {
//
// Sending data was done
//
state := sDone
}.elsewhen(io.dataValidInput === true.B) {
//
// Store the data to send in a register
//
regDataToSend := io.sendingData
//
// The data is valid, so let's send it
//
state := sSendData
}.otherwise {
//
// Stay in the same state as the data is not ready (valid)
//
state := sWaitToGetData
}
}
is(sSendData) {
//
// Not waiting for the buffer at this state
//
sendWaitForBuffer := false.B
//
// Enable writing to the BRAM
//
wrEna := true.B
//
// Adjust address to write next data to BRAM (Address granularity is in the byte format so,
// it'll be divided by 8 or shift to right by 3)
//
rdWrAddr := regRdWrAddr
regRdWrAddr := regRdWrAddr + (instanceInfo.bramDataWidth >> 3).U
//
// Adjust data to write as the sending data
//
wrData := regDataToSend
//
// Check whether sending was done at this state (Two states will go us to the 'done' state)
//
when(io.noNewDataSender === true.B) {
//
// Sending data was done
//
state := sDone
}.otherwise {
//
// Again go to the state for waiting for new data
//
state := sWaitToGetData
}
}
is(sDone) {
//
// Adjust the output bits
//
finishedSendingBuffer := true.B
//
// Interrupt the PS
//
psOutInterrupt := true.B
//
// Go to the idle state
//
state := sIdle
}
}
}
// ---------------------------------------------------------------------
//
// Connect output pins to internal registers
//
io.psOutInterrupt := psOutInterrupt
io.rdWrAddr := rdWrAddr
io.wrEna := wrEna
io.wrData := wrData
io.sendWaitForBuffer := sendWaitForBuffer
io.finishedSendingBuffer := finishedSendingBuffer
}
object DebuggerPacketSender {
def apply(
debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
instanceInfo: HwdbgInstanceInformation
)(
en: Bool,
beginSendingBuffer: Bool,
noNewDataSender: Bool,
dataValidInput: Bool,
requestedActionOfThePacketInput: UInt,
sendingData: UInt
): (Bool, UInt, Bool, UInt, Bool, Bool) = {
val debuggerPacketSender = Module(
new DebuggerPacketSender(
debug,
instanceInfo
)
)
val psOutInterrupt = Wire(Bool())
val rdWrAddr = Wire(UInt(instanceInfo.bramAddrWidth.W))
val wrEna = Wire(Bool())
val wrData = Wire(UInt(instanceInfo.bramDataWidth.W))
val sendWaitForBuffer = Wire(Bool())
val finishedSendingBuffer = Wire(Bool())
//
// Configure the input signals
//
debuggerPacketSender.io.en := en
debuggerPacketSender.io.beginSendingBuffer := beginSendingBuffer
debuggerPacketSender.io.noNewDataSender := noNewDataSender
debuggerPacketSender.io.dataValidInput := dataValidInput
debuggerPacketSender.io.requestedActionOfThePacketInput := requestedActionOfThePacketInput
debuggerPacketSender.io.sendingData := sendingData
//
// Configure the output signals
//
psOutInterrupt := debuggerPacketSender.io.psOutInterrupt
rdWrAddr := debuggerPacketSender.io.rdWrAddr
wrEna := debuggerPacketSender.io.wrEna
wrData := debuggerPacketSender.io.wrData
//
// Configure the output signals related to sending packets
//
sendWaitForBuffer := debuggerPacketSender.io.sendWaitForBuffer
finishedSendingBuffer := debuggerPacketSender.io.finishedSendingBuffer
//
// Return the output result
//
(psOutInterrupt, rdWrAddr, wrEna, wrData, sendWaitForBuffer, finishedSendingBuffer)
}
}

View file

@ -1,52 +0,0 @@
{
"Version": {
"VERSION_MAJOR": 0,
"VERSION_MINOR": 2,
"VERSION_PATCH": 0
},
"DebuggerConfigurations": {
"ENABLE_DEBUG": true,
"NUMBER_OF_PINS": 32,
"PORT_PINS_MAP": [12, 20]
},
"ScriptEngineConfigurations": {
"MAXIMUM_NUMBER_OF_STAGES": 32,
"MAXIMUM_NUMBER_OF_SUPPORTED_GET_SCRIPT_OPERATORS": 2,
"MAXIMUM_NUMBER_OF_SUPPORTED_SET_SCRIPT_OPERATORS": 1,
"SCRIPT_VARIABLE_LENGTH": 8,
"NUMBER_OF_SUPPORTED_LOCAL_AND_GLOBAL_VARIABLES": 2,
"NUMBER_OF_SUPPORTED_TEMPORARY_VARIABLES": 2,
"SCRIPT_ENGINE_EVAL_CAPABILITIES": [
"assign_local_global_var",
"assign_registers",
"conditional_statements_and_comparison_operators",
"stack_assignments",
"func_or",
"func_xor",
"func_and",
"func_asl",
"func_add",
"func_sub",
"func_mul",
"func_gt",
"func_lt",
"func_egt",
"func_elt",
"func_equal",
"func_neq",
"func_jmp",
"func_jz",
"func_jnz",
"func_mov"
]
},
"MemoryCommunicationConfigurations": {
"BLOCK_RAM_ADDR_WIDTH": 13,
"BLOCK_RAM_DATA_WIDTH": 32,
"ENABLE_BLOCK_RAM_DELAY": true,
"DEFAULT_CONFIGURATION_INITIALIZED_MEMORY_SIZE": 1024,
"BASE_ADDRESS_OF_PS_TO_PL_COMMUNICATION": 0,
"BASE_ADDRESS_OF_PL_TO_PS_COMMUNICATION": 512
}
}

View file

@ -1,500 +0,0 @@
/**
* @file
* configs.scala
* @author
* Sina Karvandi (sina@hyperdbg.org)
* @brief
* Configuration files
* @details
* @version 0.1
* @date
* 2024-04-03
*
* @copyright
* This project is released under the GNU Public License v3.
*/
package hwdbg.configs
import io.circe._
import io.circe.parser._
import io.circe.generic.auto._
import scala.io.Source
import chisel3._
import chisel3.util._
import hwdbg.utils._
/**
* @brief
* Version of hwdbg (Definition and Default Values)
* @warning
* will be checked with HyperDbg
*/
object Version {
//
// Constant version info
//
var VERSION_MAJOR: Int = 0
var VERSION_MINOR: Int = 1
var VERSION_PATCH: Int = 0
def getEncodedVersion: Int = {
(VERSION_MAJOR << 16) | (VERSION_MINOR << 8) | VERSION_PATCH
}
def extractMajor(encodedVersion: Int): Int = {
encodedVersion >> 16
}
def extractMinor(encodedVersion: Int): Int = {
(encodedVersion >> 8) & 0xff // Masking to get only the 8 bits
}
def extractPatch(encodedVersion: Int): Int = {
encodedVersion & 0xff // Masking to get only the 8 bits
}
}
/**
* @brief
* Design constants (Definition and Default Values)
*/
object DebuggerConfigurations {
//
// whether to enable debug or not
//
var ENABLE_DEBUG: Boolean = true
//
// Number of input/output pins
//
var NUMBER_OF_PINS: Int = 32
//
// The configuration of ports and pins
//
// The following constant shows the key value object of the mappings
// of pins to ports (used for inputs/outputs)
// For example,
// port 0 (in) -> contains 12 pins
// port 1 (in) -> contains 20 pins
//
// var PORT_PINS_MAP: Array[Int] = Array(12, 18, 2)
// var PORT_PINS_MAP: Array[Int] = Array(12, 10, 5, 3, 2)
var PORT_PINS_MAP: Array[Int] = Array(12, 20)
}
/**
* @brief
* Design constants for script engine (Definition and Default Values)
*/
object ScriptEngineConfigurations {
//
// Maximum number of stages
//
var MAXIMUM_NUMBER_OF_STAGES: Int = 32
//
// Maximum number of stages
//
var MAXIMUM_NUMBER_OF_SUPPORTED_GET_SCRIPT_OPERATORS: Int = 2 // for get values
//
// Maximum number of stages
//
var MAXIMUM_NUMBER_OF_SUPPORTED_SET_SCRIPT_OPERATORS: Int = 1 // for get value
//
// Script variable length
//
var SCRIPT_VARIABLE_LENGTH: Int = 8
//
// Number supported of local and global variables
//
var NUMBER_OF_SUPPORTED_LOCAL_AND_GLOBAL_VARIABLES: Int = 2
//
// Number supported of temporary variables
//
var NUMBER_OF_SUPPORTED_TEMPORARY_VARIABLES: Int = 2
//
// Define the capabilities you want to enable
//
var SCRIPT_ENGINE_EVAL_CAPABILITIES = Seq(
//
// Statements and expressions
//
HwdbgScriptCapabilities.assign_local_global_var,
HwdbgScriptCapabilities.assign_registers,
// HwdbgScriptCapabilities.assign_pseudo_registers,
HwdbgScriptCapabilities.conditional_statements_and_comparison_operators,
HwdbgScriptCapabilities.stack_assignments,
//
// Operators
//
HwdbgScriptCapabilities.func_or,
HwdbgScriptCapabilities.func_xor,
HwdbgScriptCapabilities.func_and,
HwdbgScriptCapabilities.func_asl,
HwdbgScriptCapabilities.func_add,
HwdbgScriptCapabilities.func_sub,
HwdbgScriptCapabilities.func_mul,
// HwdbgScriptCapabilities.func_div,
// HwdbgScriptCapabilities.func_mod,
HwdbgScriptCapabilities.func_gt,
HwdbgScriptCapabilities.func_lt,
HwdbgScriptCapabilities.func_egt,
HwdbgScriptCapabilities.func_elt,
HwdbgScriptCapabilities.func_equal,
HwdbgScriptCapabilities.func_neq,
HwdbgScriptCapabilities.func_jmp,
HwdbgScriptCapabilities.func_jz,
HwdbgScriptCapabilities.func_jnz,
HwdbgScriptCapabilities.func_mov
// HwdbgScriptCapabilities.func_printf,
)
}
/**
* @brief
* The constants for memory communication (Definition and Default Values)
*/
object MemoryCommunicationConfigurations {
//
// Address width of the Block RAM (BRAM)
//
var BLOCK_RAM_ADDR_WIDTH: Int = 13
//
// Data width of the Block RAM (BRAM)
//
var BLOCK_RAM_DATA_WIDTH: Int = 32
//
// Emulate block RAM by inferring a register to delay one clock cycle
//
var ENABLE_BLOCK_RAM_DELAY: Boolean = true
//
// Default number of bytes used in initialized SRAM memory
//
var DEFAULT_CONFIGURATION_INITIALIZED_MEMORY_SIZE: Int = 8192 / 8 // 8 Kilobits
//
// Base address of PS to PL SRAM communication memory
//
var BASE_ADDRESS_OF_PS_TO_PL_COMMUNICATION: Int = 0
//
// Base address of PL to PS SRAM communication memory
//
var BASE_ADDRESS_OF_PL_TO_PS_COMMUNICATION: Int = DEFAULT_CONFIGURATION_INITIALIZED_MEMORY_SIZE / 2
}
/**
* @brief
* The structure of script capabilities information in hwdbg
* @details
* Same as _HWDBG_INSTANCE_INFORMATION in HyperDbg
*/
case class HwdbgInstanceInformation(
version: Int, // Target version of HyperDbg (same as hwdbg)
maximumNumberOfStages: Int, // Number of stages that this instance of hwdbg supports (NumberOfSupportedStages == 0 means script engine is disabled)
scriptVariableLength: Int, // Maximum length of variables (and other script elements)
numberOfSupportedLocalAndGlobalVariables: Int, // Number of supported local (and global) variables
numberOfSupportedTemporaryVariables: Int, // Number of supported temporary variables
maximumNumberOfSupportedGetScriptOperators: Int, // Maximum supported GET operators in a single func
maximumNumberOfSupportedSetScriptOperators: Int, // Maximum supported SET operators in a single func
sharedMemorySize: Int, // Size of shared memory
debuggerAreaOffset: Int, // The memory offset of debugger
debuggeeAreaOffset: Int, // The memory offset of debuggee
numberOfPins: Int, // Number of pins
numberOfPorts: Int, // Number of ports
scriptCapabilities: Long, // Capabilities bitmask
bramAddrWidth: Int, // BRAM address width
bramDataWidth: Int, // BRAM data width
portsConfiguration: Array[Int] // Port arrangement
)
/**
* @brief
* The script engine capabilities (Definition and Default Values)
*/
object HwdbgScriptCapabilities {
//
// Statements and expressions
//
val assign_local_global_var: Long = 1L << 0
val assign_registers: Long = 1L << 1
val assign_pseudo_registers: Long = 1L << 2
val conditional_statements_and_comparison_operators: Long = 1L << 3
val stack_assignments: Long = 1L << 4
//
// Operators
//
val func_or: Long = 1L << 5
val func_xor: Long = 1L << 6
val func_and: Long = 1L << 7
val func_asr: Long = 1L << 8
val func_asl: Long = 1L << 9
val func_add: Long = 1L << 10
val func_sub: Long = 1L << 11
val func_mul: Long = 1L << 12
val func_div: Long = 1L << 13
val func_mod: Long = 1L << 14
val func_gt: Long = 1L << 15
val func_lt: Long = 1L << 16
val func_egt: Long = 1L << 17
val func_elt: Long = 1L << 18
val func_equal: Long = 1L << 19
val func_neq: Long = 1L << 20
val func_jmp: Long = 1L << 21
val func_jz: Long = 1L << 22
val func_jnz: Long = 1L << 23
val func_mov: Long = 1L << 24
val func_printf: Long = 1L << 25
def allCapabilities: Seq[Long] = Seq(
assign_local_global_var,
assign_registers,
assign_pseudo_registers,
conditional_statements_and_comparison_operators,
stack_assignments,
func_or,
func_xor,
func_and,
func_asr,
func_asl,
func_add,
func_sub,
func_mul,
func_div,
func_mod,
func_gt,
func_lt,
func_egt,
func_elt,
func_equal,
func_neq,
func_jmp,
func_jz,
func_jnz,
func_mov,
func_printf
)
//
// Utility method to create a bitmask from a sequence of capabilities
//
def createCapabilitiesMask(capabilities: Seq[Long]): Long = {
capabilities.foldLeft(0L)(_ | _)
}
//
// Function to check if a capability is supported
//
def isCapabilitySupported(supportedCapabilities: Long, capability: Long): Boolean = {
(supportedCapabilities & capability) != 0
}
}
object HwdbgInstanceInformation {
//
// Function to create an instance of HwdbgInstanceInformation
//
def createInstanceInformation(
version: Int,
maximumNumberOfStages: Int,
scriptVariableLength: Int,
numberOfSupportedLocalAndGlobalVariables: Int,
numberOfSupportedTemporaryVariables: Int,
maximumNumberOfSupportedGetScriptOperators: Int,
maximumNumberOfSupportedSetScriptOperators: Int,
sharedMemorySize: Int,
debuggerAreaOffset: Int,
debuggeeAreaOffset: Int,
numberOfPins: Int,
numberOfPorts: Int,
enabledCapabilities: Seq[Long],
bramAddrWidth: Int,
bramDataWidth: Int,
portsConfiguration: Array[Int]
): HwdbgInstanceInformation = {
val capabilitiesMask = HwdbgScriptCapabilities.createCapabilitiesMask(enabledCapabilities)
//
// Printing the versioning info
//
LogInfo(true)("=======================================================================")
LogInfo(true)(
s"Generating code for hwdbg v${Version.extractMajor(version)}.${Version.extractMinor(version)}.${Version.extractPatch(version)} ($version)"
)
LogInfo(true)("Please visit https://hwdbg.hyperdbg.org/docs for more information...")
LogInfo(true)("hwdbg is released under the GNU Public License v3 (GPLv3).")
LogInfo(true)("=======================================================================")
HwdbgInstanceInformation(
version = version,
maximumNumberOfStages = maximumNumberOfStages,
scriptVariableLength = scriptVariableLength,
numberOfSupportedLocalAndGlobalVariables = numberOfSupportedLocalAndGlobalVariables,
numberOfSupportedTemporaryVariables = numberOfSupportedTemporaryVariables,
maximumNumberOfSupportedGetScriptOperators = maximumNumberOfSupportedGetScriptOperators,
maximumNumberOfSupportedSetScriptOperators = maximumNumberOfSupportedSetScriptOperators,
sharedMemorySize = sharedMemorySize,
debuggerAreaOffset = debuggerAreaOffset,
debuggeeAreaOffset = debuggeeAreaOffset,
numberOfPins = numberOfPins,
numberOfPorts = numberOfPorts,
scriptCapabilities = capabilitiesMask,
bramAddrWidth = bramAddrWidth,
bramDataWidth = bramDataWidth,
portsConfiguration = portsConfiguration
)
}
}
object ConfigLoader {
//
// Case classes for each configuration section
//
case class VersionConfig(
VERSION_MAJOR: Int,
VERSION_MINOR: Int,
VERSION_PATCH: Int
)
case class DebuggerConfigurationsConfig(
ENABLE_DEBUG: Boolean,
NUMBER_OF_PINS: Int,
PORT_PINS_MAP: Array[Int]
)
case class ScriptEngineConfigurationsConfig(
MAXIMUM_NUMBER_OF_STAGES: Int,
MAXIMUM_NUMBER_OF_SUPPORTED_GET_SCRIPT_OPERATORS: Int,
MAXIMUM_NUMBER_OF_SUPPORTED_SET_SCRIPT_OPERATORS: Int,
SCRIPT_VARIABLE_LENGTH: Int,
NUMBER_OF_SUPPORTED_LOCAL_AND_GLOBAL_VARIABLES: Int,
NUMBER_OF_SUPPORTED_TEMPORARY_VARIABLES: Int,
SCRIPT_ENGINE_EVAL_CAPABILITIES: Seq[String]
)
case class MemoryCommunicationConfigurationsConfig(
BLOCK_RAM_ADDR_WIDTH: Int,
BLOCK_RAM_DATA_WIDTH: Int,
ENABLE_BLOCK_RAM_DELAY: Boolean,
DEFAULT_CONFIGURATION_INITIALIZED_MEMORY_SIZE: Int,
BASE_ADDRESS_OF_PS_TO_PL_COMMUNICATION: Int,
BASE_ADDRESS_OF_PL_TO_PS_COMMUNICATION: Int
)
case class FullConfig(
Version: VersionConfig,
DebuggerConfigurations: DebuggerConfigurationsConfig,
ScriptEngineConfigurations: ScriptEngineConfigurationsConfig,
MemoryCommunicationConfigurations: MemoryCommunicationConfigurationsConfig
)
//
// Function to load configuration from a JSON file
//
def loadConfig(filePath: String): Option[FullConfig] = {
val source = Source.fromFile(filePath)
val jsonString = try source.getLines().mkString("\n") finally source.close()
decode[FullConfig](jsonString) match {
case Right(config) => Some(config)
case Left(error) =>
println(s"Failed to parse JSON configuration: $error")
None
}
}
}
object LoadConfiguration {
def loadFromJson(configPath: String): Unit = {
val configOpt = ConfigLoader.loadConfig(configPath)
configOpt.foreach { config =>
//
// *** Set the values in the respective objects ***
//
//
// Read the version
//
Version.VERSION_MAJOR = config.Version.VERSION_MAJOR
Version.VERSION_MINOR = config.Version.VERSION_MINOR
Version.VERSION_PATCH = config.Version.VERSION_PATCH
//
// Read the debugger configurations
//
DebuggerConfigurations.ENABLE_DEBUG = config.DebuggerConfigurations.ENABLE_DEBUG
DebuggerConfigurations.NUMBER_OF_PINS = config.DebuggerConfigurations.NUMBER_OF_PINS
DebuggerConfigurations.PORT_PINS_MAP = config.DebuggerConfigurations.PORT_PINS_MAP
//
// Read the script engine configurations
//
ScriptEngineConfigurations.MAXIMUM_NUMBER_OF_STAGES = config.ScriptEngineConfigurations.MAXIMUM_NUMBER_OF_STAGES
ScriptEngineConfigurations.MAXIMUM_NUMBER_OF_SUPPORTED_GET_SCRIPT_OPERATORS = config.ScriptEngineConfigurations.MAXIMUM_NUMBER_OF_SUPPORTED_GET_SCRIPT_OPERATORS
ScriptEngineConfigurations.MAXIMUM_NUMBER_OF_SUPPORTED_SET_SCRIPT_OPERATORS = config.ScriptEngineConfigurations.MAXIMUM_NUMBER_OF_SUPPORTED_SET_SCRIPT_OPERATORS
ScriptEngineConfigurations.SCRIPT_VARIABLE_LENGTH = config.ScriptEngineConfigurations.SCRIPT_VARIABLE_LENGTH
ScriptEngineConfigurations.NUMBER_OF_SUPPORTED_LOCAL_AND_GLOBAL_VARIABLES = config.ScriptEngineConfigurations.NUMBER_OF_SUPPORTED_LOCAL_AND_GLOBAL_VARIABLES
ScriptEngineConfigurations.NUMBER_OF_SUPPORTED_TEMPORARY_VARIABLES = config.ScriptEngineConfigurations.NUMBER_OF_SUPPORTED_TEMPORARY_VARIABLES
//
// Convert string capability names to the corresponding values in HwdbgScriptCapabilities
//
ScriptEngineConfigurations.SCRIPT_ENGINE_EVAL_CAPABILITIES = config.ScriptEngineConfigurations.SCRIPT_ENGINE_EVAL_CAPABILITIES.flatMap {
case "assign_local_global_var" => Some(HwdbgScriptCapabilities.assign_local_global_var)
case "assign_registers" => Some(HwdbgScriptCapabilities.assign_registers)
case "conditional_statements_and_comparison_operators" => Some(HwdbgScriptCapabilities.conditional_statements_and_comparison_operators)
case "stack_assignments" => Some(HwdbgScriptCapabilities.stack_assignments)
case "func_or" => Some(HwdbgScriptCapabilities.func_or)
case "func_xor" => Some(HwdbgScriptCapabilities.func_xor)
case "func_and" => Some(HwdbgScriptCapabilities.func_and)
case "func_asl" => Some(HwdbgScriptCapabilities.func_asl)
case "func_add" => Some(HwdbgScriptCapabilities.func_add)
case "func_sub" => Some(HwdbgScriptCapabilities.func_sub)
case "func_mul" => Some(HwdbgScriptCapabilities.func_mul)
case "func_gt" => Some(HwdbgScriptCapabilities.func_gt)
case "func_lt" => Some(HwdbgScriptCapabilities.func_lt)
case "func_egt" => Some(HwdbgScriptCapabilities.func_egt)
case "func_elt" => Some(HwdbgScriptCapabilities.func_elt)
case "func_equal" => Some(HwdbgScriptCapabilities.func_equal)
case "func_neq" => Some(HwdbgScriptCapabilities.func_neq)
case "func_jmp" => Some(HwdbgScriptCapabilities.func_jmp)
case "func_jz" => Some(HwdbgScriptCapabilities.func_jz)
case "func_jnz" => Some(HwdbgScriptCapabilities.func_jnz)
case "func_mov" => Some(HwdbgScriptCapabilities.func_mov)
case _ => None
}
//
// Read memory communication configurations
//
MemoryCommunicationConfigurations.BLOCK_RAM_ADDR_WIDTH = config.MemoryCommunicationConfigurations.BLOCK_RAM_ADDR_WIDTH
MemoryCommunicationConfigurations.BLOCK_RAM_DATA_WIDTH = config.MemoryCommunicationConfigurations.BLOCK_RAM_DATA_WIDTH
MemoryCommunicationConfigurations.ENABLE_BLOCK_RAM_DELAY = config.MemoryCommunicationConfigurations.ENABLE_BLOCK_RAM_DELAY
MemoryCommunicationConfigurations.DEFAULT_CONFIGURATION_INITIALIZED_MEMORY_SIZE = config.MemoryCommunicationConfigurations.DEFAULT_CONFIGURATION_INITIALIZED_MEMORY_SIZE
MemoryCommunicationConfigurations.BASE_ADDRESS_OF_PS_TO_PL_COMMUNICATION = config.MemoryCommunicationConfigurations.BASE_ADDRESS_OF_PS_TO_PL_COMMUNICATION
MemoryCommunicationConfigurations.BASE_ADDRESS_OF_PL_TO_PS_COMMUNICATION = config.MemoryCommunicationConfigurations.BASE_ADDRESS_OF_PL_TO_PS_COMMUNICATION
}
}
}

View file

@ -1,68 +0,0 @@
/**
* @file
* constants.scala
* @author
* Sina Karvandi (sina@hyperdbg.org)
* @brief
* Constant values
* @details
* @version 0.1
* @date
* 2024-04-16
*
* @copyright
* This project is released under the GNU Public License v3.
*/
package hwdbg.constants
import chisel3._
import chisel3.util._
/**
* @brief
* Shared value with HyperDbg
* @warning
* used in HyperDbg
*/
object HyperDbgSharedConstants {
//
// Constant indicator of a HyperDbg packet
//
val INDICATOR_OF_HYPERDBG_PACKET: Long = 0x4859504552444247L // HYPERDBG = 0x4859504552444247
}
/**
* @brief
* Enumeration for different packet types in HyperDbg packets (DEBUGGER_REMOTE_PACKET_TYPE)
* @warning
* Used in HyperDbg
*/
object DebuggerRemotePacketType extends Enumeration {
//
// Debugger to debuggee (vmx-root)
//
val DEBUGGER_TO_DEBUGGEE_EXECUTE_ON_VMX_ROOT = Value(1)
//
// Debugger to debuggee (user-mode)
//
val DEBUGGER_TO_DEBUGGEE_EXECUTE_ON_USER_MODE = Value(2)
//
// Debuggee to debugger (user-mode and kernel-mode, vmx-root mode)
//
val DEBUGGEE_TO_DEBUGGER = Value(3)
//
// Debugger to debuggee (hardware), used in hwdbg
//
val DEBUGGER_TO_DEBUGGEE_HARDWARE_LEVEL = Value(4)
//
// Debuggee to debugger (hardware), used in hwdbg
//
val DEBUGGEE_TO_DEBUGGER_HARDWARE_LEVEL = Value(5)
}

View file

@ -1,36 +0,0 @@
/**
* @file
* configs.scala
* @author
* Sina Karvandi (sina@hyperdbg.org)
* @brief
* Configuration files for testing hwdbg
* @details
* @version 0.1
* @date
* 2024-04-15
*
* @copyright
* This project is released under the GNU Public License v3.
*/
package hwdbg.configs
import chisel3._
import chisel3.util._
/**
* @brief
* The configuration constants for testing
*/
object TestingConfigurations {
// val BRAM_INITIALIZATION_FILE_PATH: String = "./src/test/bram/instance_info.hex.txt"
val BRAM_INITIALIZATION_FILE_PATH: String = "./src/test/bram/script_buffer.hex.txt"
// val BRAM_INITIALIZATION_FILE_PATH: String = "./src/test/bram/script_conditional_statements_pins.hex.txt"
// val BRAM_INITIALIZATION_FILE_PATH: String = "./src/test/bram/script_simple_pin_assignments.hex.txt"
// val BRAM_INITIALIZATION_FILE_PATH: String = "./src/test/bram/script_simple_port_assignments.hex.txt"
// val BRAM_INITIALIZATION_FILE_PATH: String = "./src/test/bram/script_conditional_statements_ports.hex.txt"
// val BRAM_INITIALIZATION_FILE_PATH: String = "./src/test/bram/script_conditional_statements_ports_with_port_assignments.hex.txt"
// val BRAM_INITIALIZATION_FILE_PATH: String = "./src/test/bram/script_conditional_statement_global_var.txt"
}

View file

@ -1,105 +0,0 @@
/**
* @file
* init_mem.scala
* @author
* Sina Karvandi (sina@hyperdbg.org)
* @brief
* Initialize SRAM memory from a file
* @details
* @version 0.1
* @date
* 2024-04-03
*
* @copyright
* This project is released under the GNU Public License v3.
*/
package hwdbg.libs.mem
import chisel3._
import chisel3.util.experimental.loadMemoryFromFileInline
import hwdbg.configs._
class InitMemInline(
debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
memoryFile: String,
addrWidth: Int,
width: Int,
size: Int
) extends Module {
val io = IO(new Bundle {
val enable = Input(Bool())
val write = Input(Bool())
val addr = Input(UInt(addrWidth.W))
val dataIn = Input(UInt(width.W))
val dataOut = Output(UInt(width.W))
})
val mem = SyncReadMem(size / width, UInt(width.W))
//
// Initialize memory
//
if (memoryFile.trim().nonEmpty) {
loadMemoryFromFileInline(mem, memoryFile)
}
io.dataOut := DontCare
when(io.enable) {
val rdwrPort = mem(io.addr)
when(io.write) {
rdwrPort := io.dataIn
}.otherwise {
io.dataOut := rdwrPort
}
}
}
object InitMemInline {
def apply(
debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
memoryFile: String,
addrWidth: Int,
width: Int,
size: Int
)(
enable: Bool,
write: Bool,
addr: UInt,
dataIn: UInt
): UInt = {
val initMemInlineModule = Module(
new InitMemInline(
debug,
memoryFile,
addrWidth,
width,
size
)
)
val dataOut = Wire(UInt(width.W))
//
// Configure the input signals
//
initMemInlineModule.io.enable := enable
initMemInlineModule.io.write := write
initMemInlineModule.io.addr := addr
initMemInlineModule.io.dataIn := dataIn
//
// Configure the output signals
//
dataOut := initMemInlineModule.io.dataOut
//
// Return the output result
//
dataOut
}
}

View file

@ -1,159 +0,0 @@
/**
* @file
* init_reg_mem_from_file.scala
* @author
* Sina Karvandi (sina@hyperdbg.org)
* @brief
* Initialize registers from a file
* @details
* @version 0.1
* @date
* 2024-04-14
*
* @copyright
* This project is released under the GNU Public License v3.
*/
package hwdbg.libs.mem
import scala.collection.mutable.ArrayBuffer
import scala.io.Source
import chisel3._
import hwdbg.utils._
import hwdbg.configs._
object InitRegMemFromFileTools {
def readmemh(
debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
path: String,
width: Int
): Seq[UInt] = {
var counter: Int = 0
val buffer = new ArrayBuffer[UInt]
for (line <- Source.fromFile(path).getLines()) {
val tokens: Array[String] = line.split("(//)").map(_.trim)
if (tokens.nonEmpty && tokens.head != "" && tokens.head.split(";")(0).trim != "") {
val i = Integer.parseInt(tokens.head.split(";")(0).trim, 16)
LogInfo(debug)(
f"Initialize memory [${counter}%x]: 0x${i}%x"
)
counter = counter + 4
buffer.append(i.U(width.W))
}
}
buffer.toSeq
}
}
class InitRegMemFromFile(
debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
emulateBlockRamDelay: Boolean,
memoryFile: String,
addrWidth: Int,
width: Int,
size: Int
) extends Module {
val io = IO(new Bundle {
val enable = Input(Bool())
val write = Input(Bool())
val addr = Input(UInt(addrWidth.W))
val dataIn = Input(UInt(width.W))
val dataOut = Output(UInt(width.W))
})
//
// Not needed to show the BRAM information
//
val mem = RegInit(VecInit(InitRegMemFromFileTools.readmemh(false, memoryFile, width)))
val actualAddr = Wire(UInt(addrWidth.W))
val actualData = Wire(UInt(width.W))
val actualWrite = Wire(Bool())
//
// This because the address of the saved registers are using 4 bytes granularities
// E.g., 4 Rsh 2 = 1 | 8 Rsh 2 = 2 | 12 Rsh 2 = 3
//
if (emulateBlockRamDelay) {
//
// In case, if it is an emulation of BRAM, a one clock delay is injected
//
actualAddr := RegNext(io.addr >> 2)
actualData := RegNext(io.dataIn)
actualWrite := RegNext(io.write)
} else {
actualAddr := io.addr >> 2
actualData := io.dataIn
actualWrite := io.write
}
when(io.enable) {
val rdwrPort = mem(actualAddr)
io.dataOut := rdwrPort
when(actualWrite) {
mem(actualAddr) := actualData
}
}.otherwise {
io.dataOut := 0.U
}
}
object InitRegMemFromFile {
def apply(
debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
emulateBlockRamDelay: Boolean,
memoryFile: String,
addrWidth: Int,
width: Int,
size: Int
)(
enable: Bool,
write: Bool,
addr: UInt,
dataIn: UInt
): UInt = {
val initRegMemFromFileModule = Module(
new InitRegMemFromFile(
debug,
emulateBlockRamDelay,
memoryFile,
addrWidth,
width,
size
)
)
val dataOut = Wire(UInt(width.W))
//
// Configure the input signals
//
initRegMemFromFileModule.io.enable := enable
initRegMemFromFileModule.io.write := write
initRegMemFromFileModule.io.addr := addr
initRegMemFromFileModule.io.dataIn := dataIn
//
// Configure the output signals
//
dataOut := initRegMemFromFileModule.io.dataOut
//
// Return the output result
//
dataOut
}
}

View file

@ -1,73 +0,0 @@
/**
* @file
* mux_2_to_1_io.scala
* @author
* Sina Karvandi (sina@hyperdbg.org)
* @brief
* Implementation of MUX 2 to 1 (I/O)
* @details
* @version 0.1
* @date
* 2024-05-05
*
* @copyright
* This project is released under the GNU Public License v3.
*/
package hwdbg.libs.mux
import chisel3._
import hwdbg.configs._
class Mux2To1IO(
debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG
) extends Module {
val io = IO(new Bundle {
val a = Input(Bool())
val b = Input(Bool())
val select = Input(Bool())
val out = Output(Bool())
})
io.out := io.a & io.select | io.b & (~io.select)
}
object Mux2To1IO {
def apply(
debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG
)(
a: Bool,
b: Bool,
select: Bool
): (Bool) = {
val mux2To1IO = Module(
new Mux2To1IO(
debug
)
)
val out = Wire(Bool())
//
// Configure the input signals
//
mux2To1IO.io.a := a
mux2To1IO.io.b := b
mux2To1IO.io.select := select
//
// Configure the output signals
//
out := mux2To1IO.io.out
//
// Return the output result
//
out
}
}

View file

@ -1,80 +0,0 @@
/**
* @file
* mux_2_to_1_lookup.scala
* @author
* Sina Karvandi (sina@hyperdbg.org)
* @brief
* Implementation of MUX 2 to 1 (Mux-Lookup)
* @details
* @version 0.1
* @date
* 2024-05-05
*
* @copyright
* This project is released under the GNU Public License v3.
*/
package hwdbg.libs.mux
import chisel3._
import chisel3.util._
import hwdbg.configs._
class Mux2To1Lookup(
debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG
) extends Module {
val io = IO(new Bundle {
val a = Input(Bool())
val b = Input(Bool())
val select = Input(Bool())
val out = Output(Bool())
})
val inputs = Array(
false.B -> io.a,
true.B -> io.b
)
io.out := MuxLookup(io.select, io.a)(inputs)
}
object Mux2To1Lookup {
def apply(
debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG
)(
a: Bool,
b: Bool,
select: Bool
): (Bool) = {
val mux2To1Lookup = Module(
new Mux2To1Lookup(
debug
)
)
val out = Wire(Bool())
//
// Configure the input signals
//
mux2To1Lookup.io.a := a
mux2To1Lookup.io.b := b
mux2To1Lookup.io.select := select
//
// Configure the output signals
//
out := mux2To1Lookup.io.out
//
// Return the output result
//
out
}
}

View file

@ -1,83 +0,0 @@
/**
* @file
* mux_4_to_1_onehot.scala
* @author
* Sina Karvandi (sina@hyperdbg.org)
* @brief
* Implementation of MUX 4 to 1 (One Hot)
* @details
* @version 0.1
* @date
* 2024-05-05
*
* @copyright
* This project is released under the GNU Public License v3.
*/
package hwdbg.libs.mux
import chisel3._
import chisel3.util._
import hwdbg.configs._
class Mux4To1OneHot(
debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
width: Int = 32
) extends Module {
val io = IO(new Bundle {
val in0 = Input(UInt(width.W))
val in1 = Input(UInt(width.W))
val in2 = Input(UInt(width.W))
val in3 = Input(UInt(width.W))
val sel = Input(UInt(log2Ceil(width).W))
val out = Output(UInt(width.W))
})
io.out := Mux1H(io.sel, Seq(io.in0, io.in1, io.in2, io.in3))
}
object Mux4To1OneHot {
def apply(
debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
width: Int = 32
)(
in0: UInt,
in1: UInt,
in2: UInt,
in3: UInt,
sel: UInt
): (UInt) = {
val mux4To1OneHot = Module(
new Mux4To1OneHot(
debug
)
)
val out = Wire(UInt(width.W))
//
// Configure the input signals
//
mux4To1OneHot.io.in0 := in0
mux4To1OneHot.io.in1 := in1
mux4To1OneHot.io.in2 := in2
mux4To1OneHot.io.in3 := in3
mux4To1OneHot.io.sel := sel
//
// Configure the output signals
//
out := mux4To1OneHot.io.out
//
// Return the output result
//
out
}
}

View file

@ -1,320 +0,0 @@
/**
* @file
* main.scala
* @author
* Sina Karvandi (sina@hyperdbg.org)
* @brief
* hwdbg's main debugger module
* @details
* @version 0.1
* @date
* 2024-04-04
*
* @copyright
* This project is released under the GNU Public License v3.
*/
package hwdbg
import chisel3._
import circt.stage.ChiselStage
import hwdbg.configs._
import hwdbg.types._
import hwdbg.utils._
import hwdbg.script._
import hwdbg.communication._
import hwdbg.communication.interpreter._
class DebuggerMain(
debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
numberOfPins: Int,
maximumNumberOfStages: Int,
maximumNumberOfSupportedGetScriptOperators: Int,
maximumNumberOfSupportedSetScriptOperators: Int,
sharedMemorySize: Int,
debuggerAreaOffset: Int,
debuggeeAreaOffset: Int,
scriptVariableLength: Int,
numberOfSupportedLocalAndGlobalVariables: Int,
numberOfSupportedTemporaryVariables: Int,
scriptCapabilities: Seq[Long],
bramAddrWidth: Int,
bramDataWidth: Int,
portsConfiguration: Array[Int]
) extends Module {
//
// Ensure sum of input port values equals numberOfPins (NUMBER_OF_PINS)
//
require(
portsConfiguration.sum == numberOfPins,
"err, the sum of the portsConfiguration (PORT_PINS_MAP) values must equal the numberOfPins (NUMBER_OF_PINS)."
)
//
// Ensure script variable length is not bigger than BRAM data width
//
require(
bramDataWidth >= scriptVariableLength,
"err, the script variable length should not be bigger than BRAM data width."
)
//
// Ensure the maximum number of stages is not bigger than the maximum number
// that can be stored within the script variable length. This is because
// if a JUMP for conditional statements wants to set the target location,
// it cannot store its destination in a script variable.
//
require(
maximumNumberOfStages < math.pow(2, scriptVariableLength),
"err, the maximum number of stages should be less than 2 to the power of the script variable length."
)
//
// Ensure the number of pin + ports is not bigger than the maximum number
// that can be stored within the script variable length. This is because
// for setting and getting pins/ports values, hwdbg uses an index which
// should fit within a variable size.
//
require(
numberOfPins + portsConfiguration.size < math.pow(2, scriptVariableLength),
"err, the maximum number of pins + ports should be less than 2 to the power of the script variable length."
)
//
// Ensure the number of set operators are equal to 1 since otherwise two variables (local, global and
// temp) might be written simultaneously.
//
require(
maximumNumberOfSupportedSetScriptOperators == 1,
"err, the supported number of SET operators can be only 1."
)
val io = IO(new Bundle {
//
// Chip signals
//
val en = Input(Bool()) // chip enable signal
//
// Input/Output signals
//
val inputPin = Input(Vec(numberOfPins, UInt(1.W))) // input pins
val outputPin = Output(Vec(numberOfPins, UInt(1.W))) // output pins
//
// Interrupt signals (lines)
//
val plInSignal = Input(Bool()) // PS to PL signal
val psOutInterrupt = Output(Bool()) // PL to PS interrupt
//
// BRAM (Block RAM) ports
//
val rdWrAddr = Output(UInt(bramAddrWidth.W)) // read/write address
val rdData = Input(UInt(bramDataWidth.W)) // read data
val wrEna = Output(Bool()) // enable writing
val wrData = Output(UInt(bramDataWidth.W)) // write data
})
//
// *** Create an instance of the debugger ***
//
val instanceInfo = HwdbgInstanceInformation.createInstanceInformation(
version = Version.getEncodedVersion,
maximumNumberOfStages = maximumNumberOfStages,
scriptVariableLength = scriptVariableLength,
numberOfSupportedLocalAndGlobalVariables = numberOfSupportedLocalAndGlobalVariables,
numberOfSupportedTemporaryVariables = numberOfSupportedTemporaryVariables,
maximumNumberOfSupportedGetScriptOperators = maximumNumberOfSupportedGetScriptOperators,
maximumNumberOfSupportedSetScriptOperators = maximumNumberOfSupportedSetScriptOperators,
sharedMemorySize = sharedMemorySize,
debuggerAreaOffset = debuggerAreaOffset,
debuggeeAreaOffset = debuggeeAreaOffset,
numberOfPins = numberOfPins,
numberOfPorts = portsConfiguration.size,
enabledCapabilities = scriptCapabilities,
bramAddrWidth = bramAddrWidth,
bramDataWidth = bramDataWidth,
portsConfiguration = portsConfiguration
)
//
// Wire signals for the synchronizer
//
val requestedActionOfThePacketOutput = Wire(UInt(new DebuggerRemotePacket().RequestedActionOfThePacket.getWidth.W))
val requestedActionOfThePacketOutputValid = Wire(Bool())
val dataValidOutput = Wire(Bool())
val receivingData = Wire(UInt(bramDataWidth.W))
val sendWaitForBuffer = Wire(Bool())
// -----------------------------------------------------------------------
// Create instance from interpreter
//
val (
noNewDataReceiver,
readNextData,
beginSendingBuffer,
noNewDataSender,
dataValidInterpreterOutput,
requestedActionOfThePacketInterpreterOutput,
sendingData,
finishedScriptConfiguration,
configureStage,
targetOperator
) =
DebuggerPacketInterpreter(
debug,
instanceInfo
)(
io.en,
requestedActionOfThePacketOutput,
requestedActionOfThePacketOutputValid,
dataValidOutput,
receivingData,
sendWaitForBuffer
)
// -----------------------------------------------------------------------
// Create instance from script execution engine
//
val (outputPin) =
ScriptExecutionEngine(
debug,
instanceInfo
)(
io.en,
finishedScriptConfiguration,
configureStage,
targetOperator,
io.inputPin
)
// -----------------------------------------------------------------------
// Create instance from synchronizer
//
val (
psOutInterrupt,
rdWrAddr,
wrEna,
wrData,
outRequestedActionOfThePacketOutput,
outRequestedActionOfThePacketOutputValid,
outDataValidOutput,
outReceivingData,
outSendWaitForBuffer
) =
SendReceiveSynchronizer(
debug,
instanceInfo
)(
io.en,
io.plInSignal,
io.rdData,
noNewDataReceiver,
readNextData,
beginSendingBuffer,
noNewDataSender,
dataValidInterpreterOutput,
requestedActionOfThePacketInterpreterOutput,
sendingData
)
// -----------------------------------------------------------------------
// Connect synchronizer signals to wires
//
requestedActionOfThePacketOutput := outRequestedActionOfThePacketOutput
requestedActionOfThePacketOutputValid := outRequestedActionOfThePacketOutputValid
dataValidOutput := outDataValidOutput
receivingData := outReceivingData
sendWaitForBuffer := outSendWaitForBuffer
// -----------------------------------------------------------------------
// Configure the output signals
//
io.wrEna := wrEna
io.wrData := wrData
io.rdWrAddr := rdWrAddr
io.outputPin := outputPin
io.psOutInterrupt := psOutInterrupt
}
object DebuggerMain {
def apply(
debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
numberOfPins: Int,
maximumNumberOfStages: Int,
maximumNumberOfSupportedGetScriptOperators: Int,
maximumNumberOfSupportedSetScriptOperators: Int,
sharedMemorySize: Int,
debuggerAreaOffset: Int,
debuggeeAreaOffset: Int,
scriptVariableLength: Int,
numberOfSupportedLocalAndGlobalVariables: Int,
numberOfSupportedTemporaryVariables: Int,
scriptCapabilities: Seq[Long],
bramAddrWidth: Int,
bramDataWidth: Int,
portsConfiguration: Array[Int]
)(
en: Bool,
inputPin: Vec[UInt],
plInSignal: Bool,
rdData: UInt
): (Vec[UInt], Bool, UInt, Bool, UInt) = {
val debuggerMainModule = Module(
new DebuggerMain(
debug,
numberOfPins,
maximumNumberOfStages,
maximumNumberOfSupportedGetScriptOperators,
maximumNumberOfSupportedSetScriptOperators,
sharedMemorySize,
debuggerAreaOffset,
debuggeeAreaOffset,
scriptVariableLength,
numberOfSupportedLocalAndGlobalVariables,
numberOfSupportedTemporaryVariables,
scriptCapabilities,
bramAddrWidth,
bramDataWidth,
portsConfiguration
)
)
val outputPin = Wire(Vec(numberOfPins, UInt(1.W)))
val psOutInterrupt = Wire(Bool())
val rdWrAddr = Wire(UInt(bramAddrWidth.W))
val wrEna = Wire(Bool())
val wrData = Wire(UInt(bramDataWidth.W))
//
// Configure the input signals
//
debuggerMainModule.io.en := en
debuggerMainModule.io.inputPin := inputPin
debuggerMainModule.io.plInSignal := plInSignal
debuggerMainModule.io.rdData := rdData
//
// Configure the output signals
//
outputPin := debuggerMainModule.io.outputPin
psOutInterrupt := debuggerMainModule.io.psOutInterrupt
rdWrAddr := debuggerMainModule.io.rdWrAddr
wrEna := debuggerMainModule.io.wrEna
wrData := debuggerMainModule.io.wrData
//
// Return the output result
//
(outputPin, psOutInterrupt, rdWrAddr, wrEna, wrData)
}
}

View file

@ -1,507 +0,0 @@
/**
* @file
* eval.scala
* @author
* Sina Karvandi (sina@hyperdbg.org)
* @brief
* Script execution engine
* @details
* @version 0.1
* @date
* 2024-05-17
*
* @copyright
* This project is released under the GNU Public License v3.
*/
package hwdbg.script
import chisel3._
import chisel3.util._
import hwdbg.configs._
import hwdbg.utils._
import hwdbg.stage._
class ScriptEngineEval(
debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
instanceInfo: HwdbgInstanceInformation
) extends Module {
//
// Import operators enum
//
import hwdbg.script.ScriptEvalFunc.ScriptOperators
import hwdbg.script.ScriptEvalFunc.ScriptOperators._
val io = IO(new Bundle {
//
// Chip signals
//
val en = Input(Bool()) // chip enable signal
//
// Stage configuration signals
//
val stageConfig = Input(new Stage(debug, instanceInfo))
val nextStage = Output(
UInt(
log2Ceil(
instanceInfo.maximumNumberOfStages * (instanceInfo.maximumNumberOfSupportedGetScriptOperators + instanceInfo.maximumNumberOfSupportedSetScriptOperators + 1)
).W
)
)
//
// Output signals
//
val outputPin = Output(Vec(instanceInfo.numberOfPins, UInt(1.W))) // output pins
val resultingLocalGlobalVariables = Output(
Vec(instanceInfo.numberOfSupportedLocalAndGlobalVariables, UInt(instanceInfo.scriptVariableLength.W))
) // output of local (and global) variables
val resultingTempVariables =
Output(Vec(instanceInfo.numberOfSupportedTemporaryVariables, UInt(instanceInfo.scriptVariableLength.W))) // output of temporary variables
})
//
// Output pins
//
val nextStage = WireInit(
0.U(
log2Ceil(
instanceInfo.maximumNumberOfStages * (instanceInfo.maximumNumberOfSupportedGetScriptOperators + instanceInfo.maximumNumberOfSupportedSetScriptOperators + 1)
).W
)
)
//
// Assign operator value (split the signal into only usable part)
//
LogInfo(debug)("Usable size of Value in the SYMBOL: " + ScriptOperators().getWidth)
val mainOperatorValue = io.stageConfig.stageSymbol.Value(ScriptOperators().getWidth - 1, 0).asTypeOf(ScriptOperators())
// -------------------------------------------------------------------------
// Get value module
//
val getValueModuleOutput = Wire(Vec(instanceInfo.maximumNumberOfSupportedGetScriptOperators, UInt(instanceInfo.scriptVariableLength.W)))
for (i <- 0 until instanceInfo.maximumNumberOfSupportedGetScriptOperators) {
getValueModuleOutput(i) := ScriptEngineGetValue(
debug,
instanceInfo
)(
io.en,
io.stageConfig.getOperatorSymbol(i),
io.stageConfig.localGlobalVariables,
io.stageConfig.tempVariables,
io.stageConfig.pinValues
)
}
// -------------------------------------------------------------------------
// *** Implementing the evaluation engine ***
//
//
val srcVal = WireInit(VecInit(Seq.fill(instanceInfo.maximumNumberOfSupportedGetScriptOperators)(0.U(instanceInfo.scriptVariableLength.W))))
val desVal = WireInit(VecInit(Seq.fill(instanceInfo.maximumNumberOfSupportedSetScriptOperators)(0.U(instanceInfo.scriptVariableLength.W))))
//
// Apply the chip enable signal
//
when(io.en === true.B) {
switch(mainOperatorValue) {
is(sFuncOr) {
if (HwdbgScriptCapabilities.isCapabilitySupported(instanceInfo.scriptCapabilities, HwdbgScriptCapabilities.func_or) == true) {
srcVal(0) := getValueModuleOutput(0)
srcVal(1) := getValueModuleOutput(1)
desVal(0) := srcVal(0) | srcVal(1)
nextStage := io.stageConfig.stageIndex + 4.U // one main operator + two GET operators + one SET operator
}
}
is(sFuncXor) {
if (HwdbgScriptCapabilities.isCapabilitySupported(instanceInfo.scriptCapabilities, HwdbgScriptCapabilities.func_xor) == true) {
srcVal(0) := getValueModuleOutput(0)
srcVal(1) := getValueModuleOutput(1)
desVal(0) := srcVal(0) ^ srcVal(1)
nextStage := io.stageConfig.stageIndex + 4.U // one main operator + two GET operators + one SET operator
}
}
is(sFuncAnd) {
if (HwdbgScriptCapabilities.isCapabilitySupported(instanceInfo.scriptCapabilities, HwdbgScriptCapabilities.func_and) == true) {
srcVal(0) := getValueModuleOutput(0)
srcVal(1) := getValueModuleOutput(1)
desVal(0) := srcVal(0) & srcVal(1)
nextStage := io.stageConfig.stageIndex + 4.U // one main operator + two GET operators + one SET operator
}
}
is(sFuncAsr) {
if (HwdbgScriptCapabilities.isCapabilitySupported(instanceInfo.scriptCapabilities, HwdbgScriptCapabilities.func_asr) == true) {
srcVal(0) := getValueModuleOutput(0)
srcVal(1) := getValueModuleOutput(1)
desVal(0) := srcVal(0) >> srcVal(1)(log2Ceil(instanceInfo.scriptVariableLength), 0)
nextStage := io.stageConfig.stageIndex + 4.U // one main operator + two GET operators + one SET operator
}
}
is(sFuncAsl) {
if (HwdbgScriptCapabilities.isCapabilitySupported(instanceInfo.scriptCapabilities, HwdbgScriptCapabilities.func_asl) == true) {
srcVal(0) := getValueModuleOutput(0)
srcVal(1) := getValueModuleOutput(1)
desVal(0) := srcVal(0) << srcVal(1)(log2Ceil(instanceInfo.scriptVariableLength), 0)
nextStage := io.stageConfig.stageIndex + 4.U // one main operator + two GET operators + one SET operator
}
}
is(sFuncAdd) {
if (HwdbgScriptCapabilities.isCapabilitySupported(instanceInfo.scriptCapabilities, HwdbgScriptCapabilities.func_add) == true) {
srcVal(0) := getValueModuleOutput(0)
srcVal(1) := getValueModuleOutput(1)
desVal(0) := srcVal(0) + srcVal(1)
nextStage := io.stageConfig.stageIndex + 4.U // one main operator + two GET operators + one SET operator
}
}
is(sFuncSub) {
if (HwdbgScriptCapabilities.isCapabilitySupported(instanceInfo.scriptCapabilities, HwdbgScriptCapabilities.func_sub) == true) {
srcVal(0) := getValueModuleOutput(0)
srcVal(1) := getValueModuleOutput(1)
desVal(0) := srcVal(0) - srcVal(1)
nextStage := io.stageConfig.stageIndex + 4.U // one main operator + two GET operators + one SET operator
}
}
is(sFuncMul) {
if (HwdbgScriptCapabilities.isCapabilitySupported(instanceInfo.scriptCapabilities, HwdbgScriptCapabilities.func_mul) == true) {
srcVal(0) := getValueModuleOutput(0)
srcVal(1) := getValueModuleOutput(1)
desVal(0) := srcVal(0) * srcVal(1)
nextStage := io.stageConfig.stageIndex + 4.U // one main operator + two GET operators + one SET operator
}
}
is(sFuncDiv) {
if (HwdbgScriptCapabilities.isCapabilitySupported(instanceInfo.scriptCapabilities, HwdbgScriptCapabilities.func_div) == true) {
srcVal(0) := getValueModuleOutput(0)
srcVal(1) := getValueModuleOutput(1)
desVal(0) := srcVal(0) / srcVal(1)
nextStage := io.stageConfig.stageIndex + 4.U // one main operator + two GET operators + one SET operator
}
}
is(sFuncMod) {
if (HwdbgScriptCapabilities.isCapabilitySupported(instanceInfo.scriptCapabilities, HwdbgScriptCapabilities.func_mod) == true) {
srcVal(0) := getValueModuleOutput(0)
srcVal(1) := getValueModuleOutput(1)
desVal(0) := srcVal(0) % srcVal(1)
nextStage := io.stageConfig.stageIndex + 4.U // one main operator + two GET operators + one SET operator
}
}
is(sFuncGt) {
if (
HwdbgScriptCapabilities.isCapabilitySupported(instanceInfo.scriptCapabilities, HwdbgScriptCapabilities.func_gt) == true &&
HwdbgScriptCapabilities.isCapabilitySupported(
instanceInfo.scriptCapabilities,
HwdbgScriptCapabilities.conditional_statements_and_comparison_operators
) == true
) {
srcVal(0) := getValueModuleOutput(0)
srcVal(1) := getValueModuleOutput(1)
desVal(0) := srcVal(0) > srcVal(1)
nextStage := io.stageConfig.stageIndex + 4.U // one main operator + two GET operators + one SET operator
}
}
is(sFuncLt) {
if (
HwdbgScriptCapabilities.isCapabilitySupported(instanceInfo.scriptCapabilities, HwdbgScriptCapabilities.func_lt) == true &&
HwdbgScriptCapabilities.isCapabilitySupported(
instanceInfo.scriptCapabilities,
HwdbgScriptCapabilities.conditional_statements_and_comparison_operators
) == true
) {
srcVal(0) := getValueModuleOutput(0)
srcVal(1) := getValueModuleOutput(1)
desVal(0) := srcVal(0) < srcVal(1)
nextStage := io.stageConfig.stageIndex + 4.U // one main operator + two GET operators + one SET operator
}
}
is(sFuncEgt) {
if (
HwdbgScriptCapabilities.isCapabilitySupported(instanceInfo.scriptCapabilities, HwdbgScriptCapabilities.func_egt) == true &&
HwdbgScriptCapabilities.isCapabilitySupported(
instanceInfo.scriptCapabilities,
HwdbgScriptCapabilities.conditional_statements_and_comparison_operators
) == true
) {
srcVal(0) := getValueModuleOutput(0)
srcVal(1) := getValueModuleOutput(1)
desVal(0) := srcVal(0) >= srcVal(1)
nextStage := io.stageConfig.stageIndex + 4.U // one main operator + two GET operators + one SET operator
}
}
is(sFuncElt) {
if (
HwdbgScriptCapabilities.isCapabilitySupported(instanceInfo.scriptCapabilities, HwdbgScriptCapabilities.func_egt) == true &&
HwdbgScriptCapabilities.isCapabilitySupported(
instanceInfo.scriptCapabilities,
HwdbgScriptCapabilities.conditional_statements_and_comparison_operators
) == true
) {
srcVal(0) := getValueModuleOutput(0)
srcVal(1) := getValueModuleOutput(1)
desVal(0) := srcVal(0) <= srcVal(1)
nextStage := io.stageConfig.stageIndex + 4.U // one main operator + two GET operators + one SET operator
}
}
is(sFuncEqual) {
if (
HwdbgScriptCapabilities.isCapabilitySupported(instanceInfo.scriptCapabilities, HwdbgScriptCapabilities.func_equal) == true &&
HwdbgScriptCapabilities.isCapabilitySupported(
instanceInfo.scriptCapabilities,
HwdbgScriptCapabilities.conditional_statements_and_comparison_operators
) == true
) {
srcVal(0) := getValueModuleOutput(0)
srcVal(1) := getValueModuleOutput(1)
desVal(0) := srcVal(0) === srcVal(1)
nextStage := io.stageConfig.stageIndex + 4.U // one main operator + two GET operators + one SET operator
}
}
is(sFuncNeq) {
if (
HwdbgScriptCapabilities.isCapabilitySupported(instanceInfo.scriptCapabilities, HwdbgScriptCapabilities.func_neq) == true &&
HwdbgScriptCapabilities.isCapabilitySupported(
instanceInfo.scriptCapabilities,
HwdbgScriptCapabilities.conditional_statements_and_comparison_operators
) == true
) {
srcVal(0) := getValueModuleOutput(0)
srcVal(1) := getValueModuleOutput(1)
desVal(0) := srcVal(0) =/= srcVal(1)
nextStage := io.stageConfig.stageIndex + 4.U // one main operator + two GET operators + one SET operator
}
}
is(sFuncJmp) {
if (
HwdbgScriptCapabilities.isCapabilitySupported(instanceInfo.scriptCapabilities, HwdbgScriptCapabilities.func_jmp) == true &&
HwdbgScriptCapabilities.isCapabilitySupported(
instanceInfo.scriptCapabilities,
HwdbgScriptCapabilities.conditional_statements_and_comparison_operators
) == true
) {
srcVal(0) := getValueModuleOutput(0)
nextStage := srcVal(0)
}
}
is(sFuncJz) {
if (
HwdbgScriptCapabilities.isCapabilitySupported(instanceInfo.scriptCapabilities, HwdbgScriptCapabilities.func_jz) == true &&
HwdbgScriptCapabilities.isCapabilitySupported(
instanceInfo.scriptCapabilities,
HwdbgScriptCapabilities.conditional_statements_and_comparison_operators
) == true
) {
srcVal(0) := getValueModuleOutput(0)
srcVal(1) := getValueModuleOutput(1)
when(srcVal(1) === 0.U) {
nextStage := srcVal(0)
}.otherwise {
nextStage := io.stageConfig.stageIndex + 3.U // one main operator + two GET operators
}
}
}
is(sFuncJnz) {
if (
HwdbgScriptCapabilities.isCapabilitySupported(instanceInfo.scriptCapabilities, HwdbgScriptCapabilities.func_jnz) == true &&
HwdbgScriptCapabilities.isCapabilitySupported(
instanceInfo.scriptCapabilities,
HwdbgScriptCapabilities.conditional_statements_and_comparison_operators
) == true
) {
srcVal(0) := getValueModuleOutput(0)
srcVal(1) := getValueModuleOutput(1)
when(srcVal(1) =/= 0.U) {
nextStage := srcVal(0)
}.otherwise {
nextStage := io.stageConfig.stageIndex + 3.U // one main operator + two GET operators
}
}
}
is(sFuncMov) {
if (HwdbgScriptCapabilities.isCapabilitySupported(instanceInfo.scriptCapabilities, HwdbgScriptCapabilities.func_mov) == true) {
srcVal(0) := getValueModuleOutput(0)
desVal(0) := srcVal(0)
nextStage := io.stageConfig.stageIndex + 3.U // one main operator + one GET operators + one SET operator
}
}
is(sFuncPrintf) {
if (HwdbgScriptCapabilities.isCapabilitySupported(instanceInfo.scriptCapabilities, HwdbgScriptCapabilities.func_printf) == true) {
//
// To be implemented
//
}
}
}
}
// -------------------------------------------------------------------------
// Set value module
//
val setValueModuleInput = Wire(Vec(instanceInfo.maximumNumberOfSupportedSetScriptOperators, Vec(instanceInfo.numberOfPins, UInt(1.W))))
val outputLocalGlobalVariables = Wire(
Vec(
instanceInfo.maximumNumberOfSupportedSetScriptOperators,
Vec(instanceInfo.numberOfSupportedLocalAndGlobalVariables, UInt(instanceInfo.scriptVariableLength.W))
)
)
val outputTempVariables = Wire(
Vec(
instanceInfo.maximumNumberOfSupportedSetScriptOperators,
Vec(instanceInfo.numberOfSupportedTemporaryVariables, UInt(instanceInfo.scriptVariableLength.W))
)
)
for (i <- 0 until instanceInfo.maximumNumberOfSupportedSetScriptOperators) {
val (
outputPin,
resultingLocalGlobalVariables,
resultingTempVariables
) = ScriptEngineSetValue(
debug,
instanceInfo
)(
io.en,
io.stageConfig.setOperatorSymbol(i),
io.stageConfig.localGlobalVariables,
io.stageConfig.tempVariables,
desVal(i),
io.stageConfig.pinValues
)
//
// Connect SET output pins
//
setValueModuleInput(i) := outputPin
outputLocalGlobalVariables(i) := resultingLocalGlobalVariables
outputTempVariables(i) := resultingTempVariables
}
// ---------------------------------------------------------------------
//
// Connect the output signals
//
io.outputPin := setValueModuleInput(0)
io.resultingLocalGlobalVariables := outputLocalGlobalVariables(0)
io.resultingTempVariables := outputTempVariables(0)
io.nextStage := nextStage
}
object ScriptEngineEval {
def apply(
debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
instanceInfo: HwdbgInstanceInformation
)(
en: Bool,
stageConfig: Stage
): (UInt, Vec[UInt], Vec[UInt], Vec[UInt]) = {
val scriptEngineEvalModule = Module(
new ScriptEngineEval(
debug,
instanceInfo
)
)
val outputPin = Wire(Vec(instanceInfo.numberOfPins, UInt(1.W)))
val resultingLocalGlobalVariables = Wire(Vec(instanceInfo.numberOfSupportedLocalAndGlobalVariables, UInt(instanceInfo.scriptVariableLength.W)))
val resultingTempVariables = Wire(Vec(instanceInfo.numberOfSupportedTemporaryVariables, UInt(instanceInfo.scriptVariableLength.W)))
val nextStage = Wire(
UInt(
log2Ceil(
instanceInfo.maximumNumberOfStages * (instanceInfo.maximumNumberOfSupportedGetScriptOperators + instanceInfo.maximumNumberOfSupportedSetScriptOperators + 1)
).W
)
)
//
// Configure the input signals
//
scriptEngineEvalModule.io.en := en
scriptEngineEvalModule.io.stageConfig := stageConfig
//
// Configure the output signals
//
nextStage := scriptEngineEvalModule.io.nextStage
outputPin := scriptEngineEvalModule.io.outputPin
resultingLocalGlobalVariables := scriptEngineEvalModule.io.resultingLocalGlobalVariables
resultingTempVariables := scriptEngineEvalModule.io.resultingTempVariables
//
// Return the output result
//
(
nextStage,
outputPin,
resultingLocalGlobalVariables,
resultingTempVariables
)
}
}

View file

@ -1,373 +0,0 @@
/**
* @file
* exec.scala
* @author
* Sina Karvandi (sina@hyperdbg.org)
* @brief
* Script execution engine
* @details
* @version 0.1
* @date
* 2024-05-07
*
* @copyright
* This project is released under the GNU Public License v3.
*/
package hwdbg.script
import chisel3._
import chisel3.util._
import hwdbg.configs._
import hwdbg.stage._
object ScriptExecutionEngineConfigStage {
object State extends ChiselEnum {
val sConfigStageSymbol, sConfigGetSymbol, sConfigSetSymbol = Value
}
}
class ScriptExecutionEngine(
debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
instanceInfo: HwdbgInstanceInformation
) extends Module {
//
// Import state enum
//
import ScriptExecutionEngineConfigStage.State
import ScriptExecutionEngineConfigStage.State._
val io = IO(new Bundle {
//
// Chip signals
//
val en = Input(Bool()) // chip enable signal
//
// Script stage configuration signals
//
val finishedScriptConfiguration = Input(Bool()) // whether script configuration finished or not?
val configureStage = Input(Bool()) // whether the configuration of stage should start or not?
val targetOperator = Input(new HwdbgShortSymbol(instanceInfo.scriptVariableLength)) // Current operator to be configured
//
// Input/Output signals
//
val inputPin = Input(Vec(instanceInfo.numberOfPins, UInt(1.W))) // input pins
val outputPin = Output(Vec(instanceInfo.numberOfPins, UInt(1.W))) // output pins
})
//
// Output pins
//
val outputPin = Wire(Vec(instanceInfo.numberOfPins, UInt(1.W)))
//
// Stage registers
//
val stageRegs = Reg(Vec(instanceInfo.maximumNumberOfStages, new Stage(debug, instanceInfo)))
//
// Stage configuration done
// Whether the state are configured or not
//
val stageConfigurationValid = RegInit(false.B)
//
// Stage configuration registers
//
val configState = RegInit(sConfigStageSymbol)
val configStageNumber = RegInit(0.U(log2Ceil(instanceInfo.maximumNumberOfStages).W))
//
// Calculate the maximum of the two values since we only want to use one register for
// both GET and SET
//
val maxOperators = math.max(instanceInfo.maximumNumberOfSupportedGetScriptOperators, instanceInfo.maximumNumberOfSupportedSetScriptOperators)
//
// Create a register with the width based on the maximum value
//
val configGetSetOperatorNumber = RegInit(0.U(log2Ceil(maxOperators).W))
val stageIndex = RegInit(
0.U(
log2Ceil(
instanceInfo.maximumNumberOfStages * (instanceInfo.maximumNumberOfSupportedGetScriptOperators + instanceInfo.maximumNumberOfSupportedSetScriptOperators + 1)
).W
)
)
// -----------------------------------------------------------------------
//
// *** Configure stage buffers ***
//
when(io.configureStage === true.B) {
switch(configState) {
is(sConfigStageSymbol) {
//
// Since the chip is in the configuring status, just pass all the input
// to output since the stage data is not valid at this stage
//
stageConfigurationValid := false.B
//
// Configure the stage symbol (The first symbol is the stage operator)
//
stageRegs(configStageNumber).stageSymbol := io.targetOperator
//
// Set the stage index
//
stageRegs(configStageNumber).stageIndex := stageIndex // store the stage index
stageRegs(configStageNumber).targetStage := 0.U // reset the target stage
stageIndex := stageIndex + 1.U // increment stage index
//
// If it is the very first configuration symbol, then we disable all stages
//
when(configStageNumber === 0.U) {
for (i <- 0 until instanceInfo.maximumNumberOfStages) {
stageRegs(i).stageEnable := false.B
}
}
//
// Going to the next state
//
configState := sConfigGetSymbol
}
is(sConfigGetSymbol) {
//
// Config GET operator
//
stageRegs(configStageNumber).getOperatorSymbol(configGetSetOperatorNumber) := io.targetOperator
configGetSetOperatorNumber := configGetSetOperatorNumber + 1.U
//
// Check whether this stage number should be counted in stage indexes or its empty
//
when(io.targetOperator.Type =/= 0.U) {
stageIndex := stageIndex + 1.U
}
when(configGetSetOperatorNumber === (instanceInfo.maximumNumberOfSupportedGetScriptOperators - 1).U) {
configGetSetOperatorNumber := 0.U // reset the counter
configState := sConfigSetSymbol // go to the next state
}.otherwise {
configState := sConfigGetSymbol // stay at the same state
}
}
is(sConfigSetSymbol) {
//
// Config SET operator
//
stageRegs(configStageNumber).setOperatorSymbol(configGetSetOperatorNumber) := io.targetOperator
stageRegs(configStageNumber).stageEnable := true.B // this stage is enabled
configGetSetOperatorNumber := configGetSetOperatorNumber + 1.U
when(io.targetOperator.Type =/= 0.U) {
stageIndex := stageIndex + 1.U
}
when(configGetSetOperatorNumber === (instanceInfo.maximumNumberOfSupportedSetScriptOperators - 1).U) {
configGetSetOperatorNumber := 0.U // reset the counter
when(io.finishedScriptConfiguration === true.B) {
//
// Not configuring anymore, reset the stage number
//
configStageNumber := 0.U // reset the stage number
stageIndex := 0.U // reset the stage index
configState := sConfigStageSymbol
//
// Stage data is now valid and can be used (scripts can apply from now on)
//
stageConfigurationValid := true.B
}.otherwise {
configStageNumber := configStageNumber + 1.U // Increment the stage number holder of current configuration
configState := sConfigStageSymbol // the next state is again a stage symbol
}
}.otherwise {
configState := sConfigSetSymbol // stay at the same state
}
}
}
}
// -----------------------------------------------------------------------
//
// *** Move each register (input vector) to the next stage at each clock ***
//
for (i <- 0 until instanceInfo.maximumNumberOfStages) {
if (i == 0) {
//
// At the first stage, the input registers should be passed to the
// first registers set of the stage registers
//
stageRegs(0).pinValues := io.inputPin
//
// Each pin start initially start from 0th target stage
//
stageRegs(0).targetStage := 0.U
} else if (i == (instanceInfo.maximumNumberOfStages - 1)) {
//
// At the last stage, the state registers should be passed to the output
// Note: At this stage script symbol is useless
//
outputPin := stageRegs(i - 1).pinValues
} else {
//
// Check if this stage should be ignored (passed to the next stage) or be evaluated
// (i - 1) is because the 0th index registers are used for storing data but the
// script engine assumes that the symbols start from 0, so -1 is used here
//
// Also, if the stage data is valid (configuration applied at least once)
//
when(stageConfigurationValid === true.B && stageRegs(i - 1).stageIndex === stageRegs(i - 1).targetStage && stageRegs(i - 1).stageEnable === true.B) {
//
// *** Based on target stage, this stage needs evaluation ***
//
//
// Instantiate an eval engine for this stage
//
val (
nextStage,
outputPin,
resultingLocalGlobalVariables,
resultingTempVariables
) = ScriptEngineEval(
debug,
instanceInfo
)(
stageRegs(i - 1).stageEnable,
stageRegs(i - 1)
)
//
// At the normal (middle) stage, the result of state registers should be passed to
// the next level of stage registers
//
stageRegs(i).pinValues := outputPin
//
// Pass the target stage symbol number to the next stage
//
stageRegs(i).targetStage := nextStage
//
// Pass the local (and global) and temporary variables to the next stage
//
if (HwdbgScriptCapabilities.isCapabilitySupported(instanceInfo.scriptCapabilities, HwdbgScriptCapabilities.assign_local_global_var) == true) {
stageRegs(i).localGlobalVariables := resultingLocalGlobalVariables
}
if (
HwdbgScriptCapabilities.isCapabilitySupported(
instanceInfo.scriptCapabilities,
HwdbgScriptCapabilities.conditional_statements_and_comparison_operators
) == true
) {
stageRegs(i).tempVariables := resultingTempVariables
}
}.otherwise {
//
// *** Based on target stage, this stage should be ignore ***
//
//
// Just pass all the values to the next stage
//
stageRegs(i).pinValues := stageRegs(i - 1).pinValues
stageRegs(i).targetStage := stageRegs(i - 1).targetStage
if (HwdbgScriptCapabilities.isCapabilitySupported(instanceInfo.scriptCapabilities, HwdbgScriptCapabilities.assign_local_global_var) == true) {
stageRegs(i).localGlobalVariables := stageRegs(i - 1).localGlobalVariables
}
if (
HwdbgScriptCapabilities.isCapabilitySupported(
instanceInfo.scriptCapabilities,
HwdbgScriptCapabilities.conditional_statements_and_comparison_operators
) == true
) {
stageRegs(i).tempVariables := stageRegs(i - 1).tempVariables
}
}
}
}
// -----------------------------------------------------------------------
//
// Connect the output signals
//
io.outputPin := outputPin
}
object ScriptExecutionEngine {
def apply(
debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
instanceInfo: HwdbgInstanceInformation
)(
en: Bool,
finishedScriptConfiguration: Bool,
configureStage: Bool,
targetOperator: HwdbgShortSymbol,
inputPin: Vec[UInt]
): (Vec[UInt]) = {
val scriptExecutionEngineModule = Module(
new ScriptExecutionEngine(
debug,
instanceInfo
)
)
val outputPin = Wire(Vec(instanceInfo.numberOfPins, UInt(1.W)))
//
// Configure the input signals
//
scriptExecutionEngineModule.io.en := en
scriptExecutionEngineModule.io.finishedScriptConfiguration := finishedScriptConfiguration
scriptExecutionEngineModule.io.configureStage := configureStage
scriptExecutionEngineModule.io.targetOperator := targetOperator
scriptExecutionEngineModule.io.inputPin := inputPin
//
// Configure the output signals
//
outputPin := scriptExecutionEngineModule.io.outputPin
//
// Return the output result
//
(outputPin)
}
}

View file

@ -1,238 +0,0 @@
/**
* @file
* get_value.scala
* @author
* Sina Karvandi (sina@hyperdbg.org)
* @brief
* Script engine get value
* @details
* @version 0.1
* @date
* 2024-05-29
*
* @copyright
* This project is released under the GNU Public License v3.
*/
package hwdbg.script
import chisel3._
import chisel3.util._
import hwdbg.configs._
import hwdbg.utils._
import hwdbg.stage._
class ScriptEngineGetValue(
debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
instanceInfo: HwdbgInstanceInformation
) extends Module {
//
// Import script data types enum
//
import hwdbg.script.ScriptConstantTypes.ScriptDataTypes
import hwdbg.script.ScriptConstantTypes.ScriptDataTypes._
val io = IO(new Bundle {
//
// Chip signals
//
val en = Input(Bool()) // chip enable signal
//
// Evaluation operator symbol
//
val operator = Input(new HwdbgShortSymbol(instanceInfo.scriptVariableLength))
//
// Input variables
//
val localGlobalVariables =
Input(Vec(instanceInfo.numberOfSupportedLocalAndGlobalVariables, UInt(instanceInfo.scriptVariableLength.W))) // Local (and Global) variables
val tempVariables = Input(Vec(instanceInfo.numberOfSupportedTemporaryVariables, UInt(instanceInfo.scriptVariableLength.W))) // Temporary variables
//
// Input signals
//
val inputPin = Input(Vec(instanceInfo.numberOfPins, UInt(1.W))) // input pins
//
// Output value
//
val outputValue = Output(UInt(instanceInfo.scriptVariableLength.W)) // output value
})
val outputValue = WireInit(0.U(instanceInfo.scriptVariableLength.W))
//
// Assign operator type (split the signal into only usable part)
//
LogInfo(debug)("Usable size of Type in the SYMBOL: " + ScriptDataTypes().getWidth)
val mainOperatorType = io.operator.Type(ScriptDataTypes().getWidth - 1, 0).asTypeOf(ScriptDataTypes())
//
// *** Implementing the getting data logic ***
//
//
// Apply the chip enable signal
//
when(io.en === true.B) {
switch(mainOperatorType) {
is(symbolGlobalIdType) {
if (HwdbgScriptCapabilities.isCapabilitySupported(instanceInfo.scriptCapabilities, HwdbgScriptCapabilities.assign_local_global_var) == true) {
//
// Set output to local (and global) variables
//
outputValue := io.localGlobalVariables(io.operator.Value)
}
}
is(symbolLocalIdType) {
if (HwdbgScriptCapabilities.isCapabilitySupported(instanceInfo.scriptCapabilities, HwdbgScriptCapabilities.assign_local_global_var) == true) {
//
// Set output to local (and global) variables
//
outputValue := io.localGlobalVariables(io.operator.Value)
}
}
is(symbolNumType) {
//
// Constant value
//
outputValue := io.operator.Value
}
is(symbolRegisterType) {
if (HwdbgScriptCapabilities.isCapabilitySupported(instanceInfo.scriptCapabilities, HwdbgScriptCapabilities.assign_registers) == true) {
//
// Registers are pins and ports
//
when(instanceInfo.numberOfPins.U > io.operator.Value) {
//
// *** Used for getting the pin value ***
//
outputValue := io.inputPin(io.operator.Value)
}.otherwise {
//
// *** Used for getting the port value ***
//
//
// Create a vector of wires
//
val ports = Wire(Vec(instanceInfo.numberOfPorts, UInt(instanceInfo.scriptVariableLength.W)))
var currentPortIndex: Int = 0
var currentPortNum: Int = 0
//
// Iterate based on port configuration
//
for (port <- instanceInfo.portsConfiguration) {
LogInfo(debug)(f"connect port(${currentPortIndex}) to inputPin(${currentPortNum} to ${currentPortNum + port}) for SET")
ports(currentPortIndex) := io.inputPin.asUInt(currentPortNum + port - 1, currentPortNum)
currentPortNum += port
currentPortIndex += 1
}
//
// Set the output
//
outputValue := ports(io.operator.Value - instanceInfo.numberOfPins.U)
}
}
}
is(symbolPseudoRegType) {
if (HwdbgScriptCapabilities.isCapabilitySupported(instanceInfo.scriptCapabilities, HwdbgScriptCapabilities.assign_pseudo_registers) == true) {
//
// To be implemented
//
outputValue := 0.U
}
}
is(symbolStackIndexType) {
if (HwdbgScriptCapabilities.isCapabilitySupported(instanceInfo.scriptCapabilities, HwdbgScriptCapabilities.stack_assignments) == true) {
//
// To be implemented
//
outputValue := 0.U // io.inputPin.asUInt
}
}
is(symbolTempType) {
if (
HwdbgScriptCapabilities.isCapabilitySupported(
instanceInfo.scriptCapabilities,
HwdbgScriptCapabilities.conditional_statements_and_comparison_operators
) == true
) {
//
// Set output to temporary variables
//
outputValue := io.tempVariables(io.operator.Value)
}
}
}
}
//
// Connect the output signals
//
io.outputValue := outputValue
}
object ScriptEngineGetValue {
def apply(
debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
instanceInfo: HwdbgInstanceInformation
)(
en: Bool,
operator: HwdbgShortSymbol,
localGlobalVariables: Vec[UInt],
tempVariables: Vec[UInt],
inputPin: Vec[UInt]
): (UInt) = {
val scriptEngineGetValueModule = Module(
new ScriptEngineGetValue(
debug,
instanceInfo
)
)
val outputValue = Wire(UInt(instanceInfo.scriptVariableLength.W))
//
// Configure the input signals
//
scriptEngineGetValueModule.io.en := en
scriptEngineGetValueModule.io.operator := operator
scriptEngineGetValueModule.io.localGlobalVariables := localGlobalVariables
scriptEngineGetValueModule.io.tempVariables := tempVariables
scriptEngineGetValueModule.io.inputPin := inputPin
//
// Configure the output signal
//
outputValue := scriptEngineGetValueModule.io.outputValue
//
// Return the output result
//
(outputValue)
}
}

View file

@ -1,50 +0,0 @@
package hwdbg.script
import chisel3._
import chisel3.util._
/**
* @brief
* The structure of HWDBG_SHORT_SYMBOL used in script engine of HyperDbg
*/
class HwdbgShortSymbol(
scriptVariableLength: Int
) extends Bundle {
//
// Ensure that the script variable length is at least 8 bits or 1 byte
//
require(
scriptVariableLength >= 8,
f"err, the minimum script variable length is 8 bits (1 byte)."
)
val Type = UInt(scriptVariableLength.W) // long long unsigned is 64 bits but it can be dynamic
val Value = UInt(scriptVariableLength.W) // long long unsigned is 64 bits but it can be dynamic
}
/**
* @brief
* Constant values for the script engine
*/
object ScriptConstants {
val SYMBOL_MEM_VALID_CHECK_MASK = 1 << 31
val INVALID = 0x80000000
val LALR_ACCEPT = 0x7fffffff
}
/**
* @brief
* Constant type values for the script engine
*/
object ScriptConstantTypes {
object ScriptDataTypes extends ChiselEnum {
val symbolUndefined, symbolGlobalIdType, symbolLocalIdType, symbolNumType, symbolRegisterType, symbolPseudoRegType, symbolSemanticRuleType, symbolTempType, symbolStringType, symbolVariableCountType, symbolInvalid, symbolWstringType, symbolFunctionParameterIdType, symbolReturnAddressType, symbolFunctionParameterType, symbolStackIndexType, symbolStackBaseIndexType, symbolReturnValueType = Value
}
}
object ScriptEvalFunc {
object ScriptOperators extends ChiselEnum {
val sFuncUndefined, sFuncInc, sFuncDec, sFuncReference, sFuncOr, sFuncXor, sFuncAnd, sFuncAsr, sFuncAsl, sFuncAdd, sFuncSub, sFuncMul, sFuncDiv, sFuncMod, sFuncGt, sFuncLt, sFuncEgt, sFuncElt, sFuncEqual, sFuncNeq, sFuncJmp, sFuncJz, sFuncJnz, sFuncMov, sFuncStart_of_do_while, sFuncStart_of_do_while_commands, sFuncEnd_of_do_while, sFuncStart_of_for, sFuncFor_inc_dec, sFuncStart_of_for_ommands, sFuncEnd_of_if, sFuncIgnore_lvalue, sFuncPush, sFuncPop, sFuncCall, sFuncRet, sFuncPrint, sFuncFormats, sFuncEvent_enable, sFuncEvent_disable, sFuncEvent_clear, sFuncTest_statement, sFuncSpinlock_lock, sFuncSpinlock_unlock, sFuncEvent_sc, sFuncMicrosleep, sFuncPrintf, sFuncPause, sFuncFlush, sFuncEvent_trace_step, sFuncEvent_trace_step_in, sFuncEvent_trace_step_out, sFuncEvent_trace_instrumentation_step, sFuncEvent_trace_instrumentation_step_in, sFuncRdtsc, sFuncRdtscp, sFuncLbr_save, sFuncLbr_dump, sFuncLbr_print, sFuncLbr_restore, sFuncLbr_check, sFuncSpinlock_lock_custom_wait, sFuncEvent_inject, sFuncPoi, sFuncDb, sFuncDd, sFuncDw, sFuncDq, sFuncNeg, sFuncHi, sFuncLow, sFuncNot, sFuncCheck_address, sFuncDisassemble_len, sFuncDisassemble_len32, sFuncDisassemble_len64, sFuncInterlocked_increment, sFuncInterlocked_decrement, sFuncPhysical_to_virtual, sFuncVirtual_to_physical, sFuncPoi_pa, sFuncHi_pa, sFuncLow_pa, sFuncDb_pa, sFuncDd_pa, sFuncDw_pa, sFuncDq_pa, sFuncLbr_restore_by_filter, sFuncEd, sFuncEb, sFuncEq, sFuncInterlocked_exchange, sFuncInterlocked_exchange_add, sFuncEb_pa, sFuncEd_pa, sFuncEq_pa, sFuncInterlocked_compare_exchange, sFuncStrlen, sFuncStrcmp, sFuncMemcmp, sFuncStrncmp, sFuncWcslen, sFuncWcscmp, sFuncEvent_inject_error_code, sFuncMemcpy, sFuncMemcpy_pa, sFuncWcsncmp = Value
}
}

View file

@ -1,389 +0,0 @@
/**
* @file
* set_value.scala
* @author
* Sina Karvandi (sina@hyperdbg.org)
* @brief
* Script engine set value
* @details
* @version 0.1
* @date
* 2024-05-29
*
* @copyright
* This project is released under the GNU Public License v3.
*/
package hwdbg.script
import chisel3._
import chisel3.util._
import hwdbg.configs._
import hwdbg.utils._
import hwdbg.stage._
class ScriptEngineSetValue(
debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
instanceInfo: HwdbgInstanceInformation
) extends Module {
//
// Import script data types enum
//
import hwdbg.script.ScriptConstantTypes.ScriptDataTypes
import hwdbg.script.ScriptConstantTypes.ScriptDataTypes._
val io = IO(new Bundle {
//
// Chip signals
//
val en = Input(Bool()) // chip enable signal
//
// Evaluation operator symbol
//
val operator = Input(new HwdbgShortSymbol(instanceInfo.scriptVariableLength))
//
// Input variables
//
val inputLocalGlobalVariables =
Input(Vec(instanceInfo.numberOfSupportedLocalAndGlobalVariables, UInt(instanceInfo.scriptVariableLength.W))) // Local (and Global) variables
val inputTempVariables =
Input(Vec(instanceInfo.numberOfSupportedTemporaryVariables, UInt(instanceInfo.scriptVariableLength.W))) // Temporary variables
//
// Input value
//
val inputValue = Input(UInt(instanceInfo.scriptVariableLength.W)) // input value
//
// Output signals
//
val inputPin = Input(Vec(instanceInfo.numberOfPins, UInt(1.W))) // output pins
val outputPin = Output(Vec(instanceInfo.numberOfPins, UInt(1.W))) // output pins
//
// Output variables
//
val outputLocalGlobalVariables =
Output(Vec(instanceInfo.numberOfSupportedLocalAndGlobalVariables, UInt(instanceInfo.scriptVariableLength.W))) // Local (and Global) variables
val outputTempVariables =
Output(Vec(instanceInfo.numberOfSupportedTemporaryVariables, UInt(instanceInfo.scriptVariableLength.W))) // Temporary variables
})
//
// Temp input
//
val inputLocalGlobalVariables = io.inputLocalGlobalVariables
val inputTempVariables = io.inputTempVariables
val inputPin = io.inputPin.asUInt
//
// Output pins
//
val outputPin = WireInit(0.U(instanceInfo.numberOfPins.W))
val outputLocalGlobalVariables = WireInit(
VecInit(Seq.fill(instanceInfo.numberOfSupportedLocalAndGlobalVariables)(0.U(instanceInfo.scriptVariableLength.W)))
) // Local (and Global) variables
val outputTempVariables = WireInit(
VecInit(Seq.fill(instanceInfo.numberOfSupportedTemporaryVariables)(0.U(instanceInfo.scriptVariableLength.W)))
) // Temporary variables
//
// Assign operator type (split the signal into only usable part)
//
LogInfo(debug)("Usable size of Type in the SYMBOL: " + ScriptDataTypes().getWidth)
val mainOperatorType = io.operator.Type(ScriptDataTypes().getWidth - 1, 0).asTypeOf(ScriptDataTypes())
//
// *** Implementing the setting data logic ***
//
//
// Apply the chip enable signal
//
when(io.en === true.B) {
switch(mainOperatorType) {
is(symbolUndefined) {
//
// In case of undefined SET value, just pass every input to the next step
//
outputPin := inputPin
outputLocalGlobalVariables := inputLocalGlobalVariables
outputTempVariables := inputTempVariables
}
is(symbolGlobalIdType) {
if (HwdbgScriptCapabilities.isCapabilitySupported(instanceInfo.scriptCapabilities, HwdbgScriptCapabilities.assign_local_global_var) == true) {
//
// Set the local (and global) variables
//
outputPin := inputPin
outputLocalGlobalVariables := inputLocalGlobalVariables
outputTempVariables := inputTempVariables
//
// Set the target variable
//
outputLocalGlobalVariables(io.operator.Value) := io.inputValue
}
}
is(symbolLocalIdType) {
if (HwdbgScriptCapabilities.isCapabilitySupported(instanceInfo.scriptCapabilities, HwdbgScriptCapabilities.assign_local_global_var) == true) {
//
// Set the target local/global variable
//
outputPin := inputPin
outputLocalGlobalVariables := inputLocalGlobalVariables
outputTempVariables := inputTempVariables
//
// Set the target local/global variable
//
outputLocalGlobalVariables(io.operator.Value) := io.inputValue
}
}
is(symbolRegisterType) {
if (HwdbgScriptCapabilities.isCapabilitySupported(instanceInfo.scriptCapabilities, HwdbgScriptCapabilities.assign_registers) == true) {
when(instanceInfo.numberOfPins.U > io.operator.Value) {
//
// *** Used for setting the pin value ***
//
//
// Registers are pins (set the value based on less significant bit)
//
val tempShiftedBit = (1.U << io.operator.Value)
when(io.inputValue(0) === 1.U) {
outputPin := inputPin | tempShiftedBit; // Set the N-th bit to 1
}.otherwise {
outputPin := inputPin & ~tempShiftedBit; // Clear the N-th bit to 0
}
}.otherwise {
//
// *** Used for setting the port value ***
//
//
// Iterate based on port configuration
//
var currentPortNum: Int = 0
val numPorts = instanceInfo.portsConfiguration.length
for ((port, index) <- instanceInfo.portsConfiguration.zipWithIndex) {
LogInfo(debug)(f"========================= port assignment (${index} - port size: ${port}) =========================")
when(io.operator.Value === (index + instanceInfo.numberOfPins).U) {
//
// If the current port's bit width is bigger than the script variable length,
// we need to append zero
//
val targetInputValue = WireInit(0.U(port.W))
if (port > instanceInfo.scriptVariableLength) {
//
// Since the port size is bigger than the variable size,
// we need to append zeros to the target value
//
LogInfo(debug)(
f"Appending zeros (${port - instanceInfo.scriptVariableLength}) to input variable (targetInputValue) to support port num: ${index}"
)
targetInputValue := Cat(io.inputValue, 0.U((port - instanceInfo.scriptVariableLength).W))
} else {
//
// Since the variable size is bigger than the port size,
// we need only a portion of the input value
//
targetInputValue := io.inputValue(port - 1, 0)
}
//
// Determine the range of bits to be modified
//
val high = currentPortNum + port - 1
val low = currentPortNum
// Create the modified outputPin based on whether it's the first, last or a middle port
val modifiedOutputPin = if (index == 0) {
//
// First port: keep higher bits unchanged, set lower bits to input value
//
LogInfo(debug)(
f"Set connecting index=${index} - inputPin(${instanceInfo.numberOfPins - 1}, ${high + 1}) + targetInputValue(${port - 1}, 0)"
)
Cat(
inputPin(instanceInfo.numberOfPins - 1, high + 1), // Bits above the range to keep unchanged
targetInputValue // New value for the specified range
)
} else if (index == numPorts - 1) {
//
// Last port: keep lower bits unchanged, set higher bits to input value
//
LogInfo(debug)(f"Set connecting index=${index} - targetInputValue(${port - 1}, 0) + inputPin(${low - 1}, 0)")
Cat(
targetInputValue, // New value for the specified range
inputPin(low - 1, 0) // Bits below the range to keep unchanged
)
} else {
//
// Middle port: keep both higher and lower bits unchanged
//
LogInfo(debug)(
f"Set connecting index=${index} - inputPin(${instanceInfo.numberOfPins - 1}, ${high + 1}) + targetInputValue(${port - 1}, 0) + inputPin(${low - 1}, 0)"
)
Cat(
inputPin(instanceInfo.numberOfPins - 1, high + 1), // Bits above the range to keep unchanged
targetInputValue, // New value for the specified range
inputPin(low - 1, 0) // Bits below the range to keep unchanged
)
}
//
// Assign the modified outputPin back to outputPin
//
outputPin := modifiedOutputPin
}
currentPortNum += port
}
}
outputLocalGlobalVariables := inputLocalGlobalVariables
outputTempVariables := inputTempVariables
}
}
is(symbolPseudoRegType) {
if (HwdbgScriptCapabilities.isCapabilitySupported(instanceInfo.scriptCapabilities, HwdbgScriptCapabilities.assign_pseudo_registers) == true) {
//
// To be implemented
//
outputPin := 0.U
outputLocalGlobalVariables := inputLocalGlobalVariables
outputTempVariables := inputTempVariables
}
}
is(symbolStackIndexType) {
if (HwdbgScriptCapabilities.isCapabilitySupported(instanceInfo.scriptCapabilities, HwdbgScriptCapabilities.stack_assignments) == true) {
//
// To be implemented
//
outputPin := inputPin
outputLocalGlobalVariables := inputLocalGlobalVariables
outputTempVariables := inputTempVariables
}
}
is(symbolTempType) {
if (
HwdbgScriptCapabilities.isCapabilitySupported(
instanceInfo.scriptCapabilities,
HwdbgScriptCapabilities.conditional_statements_and_comparison_operators
) == true
) {
//
// Set the temporary variables
//
outputPin := inputPin
outputLocalGlobalVariables := inputLocalGlobalVariables
outputTempVariables := inputTempVariables
//
// Set the target temporary variable
//
outputTempVariables(io.operator.Value) := io.inputValue
}
}
}
}
//
// Connect the output signals
//
io.outputLocalGlobalVariables := outputLocalGlobalVariables
io.outputTempVariables := outputTempVariables
for (i <- 0 until instanceInfo.numberOfPins) {
io.outputPin(i) := outputPin(i)
}
}
object ScriptEngineSetValue {
def apply(
debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
instanceInfo: HwdbgInstanceInformation
)(
en: Bool,
operator: HwdbgShortSymbol,
inputLocalGlobalVariables: Vec[UInt],
inputTempVariables: Vec[UInt],
inputValue: UInt,
inputPin: Vec[UInt]
): (Vec[UInt], Vec[UInt], Vec[UInt]) = {
val scriptEngineSetValueModule = Module(
new ScriptEngineSetValue(
debug,
instanceInfo
)
)
val outputPin = Wire(Vec(instanceInfo.numberOfPins, UInt(1.W)))
val outputLocalGlobalVariables = Wire(Vec(instanceInfo.numberOfSupportedLocalAndGlobalVariables, UInt(instanceInfo.scriptVariableLength.W)))
val outputTempVariables = Wire(Vec(instanceInfo.numberOfSupportedTemporaryVariables, UInt(instanceInfo.scriptVariableLength.W)))
//
// Configure the input signals
//
scriptEngineSetValueModule.io.en := en
scriptEngineSetValueModule.io.operator := operator
scriptEngineSetValueModule.io.inputLocalGlobalVariables := inputLocalGlobalVariables
scriptEngineSetValueModule.io.inputTempVariables := inputTempVariables
scriptEngineSetValueModule.io.inputValue := inputValue
scriptEngineSetValueModule.io.inputPin := inputPin
//
// Configure the output signal
//
outputPin := scriptEngineSetValueModule.io.outputPin
outputLocalGlobalVariables := scriptEngineSetValueModule.io.outputLocalGlobalVariables
outputTempVariables := scriptEngineSetValueModule.io.outputTempVariables
//
// Return the output result
//
(
outputPin,
outputLocalGlobalVariables,
outputTempVariables
)
}
}

View file

@ -1,183 +0,0 @@
/**
* @file
* communication.scala
* @author
* Sina Karvandi (sina@hyperdbg.org)
* @brief
* Data types for the communication
* @details
* @version 0.1
* @date
* 2024-04-08
*
* @copyright
* This project is released under the GNU Public License v3.
*/
package hwdbg.types
import chisel3._
// -----------------------------------------------------------------------
//
// Structure in C:
//
// typedef struct _DEBUGGER_REMOTE_PACKET
// {
// BYTE Checksum;
// UINT64 Indicator; /* Shows the type of the packet */
// DEBUGGER_REMOTE_PACKET_TYPE TypeOfThePacket;
// DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION RequestedActionOfThePacket;
//
// } DEBUGGER_REMOTE_PACKET, *PDEBUGGER_REMOTE_PACKET;
//
/**
* @brief
* The packet used for communication with the remote debugger
*/
class DebuggerRemotePacket() extends Bundle {
//
// Structure fields
//
val Checksum = UInt(8.W) // 1 bytes
val Alignment0 = UInt((64 - 8).W) // 7 bytes
val Indicator = UInt(64.W) // 8 bytes
val TypeOfThePacket = UInt(32.W) // 4 bytes
val RequestedActionOfThePacket = UInt(32.W) // 4 bytes
//
// Offset of structure fields
//
object Offset {
val checksum = (0) / 8
val indicator = (Checksum.getWidth + Alignment0.getWidth) / 8
val typeOfThePacket = (Checksum.getWidth + Alignment0.getWidth + Indicator.getWidth) / 8
val requestedActionOfThePacket = (Checksum.getWidth + Alignment0.getWidth + Indicator.getWidth + TypeOfThePacket.getWidth) / 8
val startOfDataBuffer =
(Checksum.getWidth + Alignment0.getWidth + Indicator.getWidth + TypeOfThePacket.getWidth + RequestedActionOfThePacket.getWidth) / 8
}
}
// -----------------------------------------------------------------------
//
// Structure in C:
//
// typedef struct _HWDBG_PORT_INFORMATION
// {
// UINT32 CountOfPorts;
//
// /*
//
// Here the pin information details will be available.
//
// UINT32
// Port Size
//
// */
//
// } HWDBG_PORT_INFORMATION, *PHWDBG_PORT_INFORMATION;
/**
* @brief
* The structure of port information in hwdbg
*/
class HwdbgPortInformation() extends Bundle {
//
// Structure fields
//
val CountOfPorts = UInt(32.W) // 4 bytes
//
// Offset of structure fields
//
object Offset {
val countOfPorts = (0) / 8
}
}
// -----------------------------------------------------------------------
//
// Structure in C:
//
// typedef struct _HWDBG_PORT_INFORMATION_ITEMS
// {
// UINT32 PortIndex;
//
// } HWDBG_PORT_INFORMATION_ITEMS, *PHWDBG_PORT_INFORMATION_ITEMS;
/**
* @brief
* The structure of port information (each item) in hwdbg
*/
class HwdbgPortInformationItems() extends Bundle {
//
// Structure fields
//
val PortSize = UInt(32.W) // 4 bytes
//
// Offset of structure fields
//
object Offset {
val portSize = (0) / 8
}
}
// -----------------------------------------------------------------------
/**
* @brief
* Different action of hwdbg (SHARED WITH HYPERDBG) (HWDBG_ACTION_ENUMS)
* @warning
* Used in HyperDbg
*/
object HwdbgActionEnums extends Enumeration {
val hwdbgActionSendInstanceInfo = Value(1)
val hwdbgActionConfigureScriptBuffer = Value(2)
}
// -----------------------------------------------------------------------
/**
* @brief
* Different responses of hwdbg (SHARED WITH HYPERDBG) (HWDBG_RESPONSE_ENUMS)
* @warning
* Used in HyperDbg
*/
object HwdbgResponseEnums extends Enumeration {
val hwdbgResponseSuccessOrErrorMessage = Value(1)
val hwdbgResponseInstanceInfo = Value(2)
}
// -----------------------------------------------------------------------
/**
* @brief
* Different responses of hwdbg (SHARED WITH HYPERDBG) (HWDBG_ERROR_ENUMS)
* @warning
*/
object HwdbgSuccessOrErrorEnums extends Enumeration {
val hwdbgOperationWasSuccessful = Value(0x7fffffff)
val hwdbgErrorInvalidPacket = Value(1)
}
// -----------------------------------------------------------------------

View file

@ -1,71 +0,0 @@
/**
* @file
* stage.scala
* @author
* Sina Karvandi (sina@hyperdbg.org)
* @brief
* Data types related to stage registers
* @details
* @version 0.1
* @date
* 2024-05-07
*
* @copyright
* This project is released under the GNU Public License v3.
*/
package hwdbg.stage
import chisel3._
import chisel3.util.log2Ceil
import hwdbg.configs._
import hwdbg.script._
class Stage(
debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
instanceInfo: HwdbgInstanceInformation
) extends Bundle {
val pinValues = Vec(
instanceInfo.numberOfPins,
UInt(1.W)
) // The value of each pin in each stage (should be passed to the next stage)
val stageSymbol = new HwdbgShortSymbol(
instanceInfo.scriptVariableLength
) // Interpreted script symbol for the target stage (should NOT be passed to the next stage)
val getOperatorSymbol = Vec(
instanceInfo.maximumNumberOfSupportedGetScriptOperators,
new HwdbgShortSymbol(instanceInfo.scriptVariableLength)
) // GET symbol operand (should NOT be passed to the next stage)
val setOperatorSymbol = Vec(
instanceInfo.maximumNumberOfSupportedSetScriptOperators,
new HwdbgShortSymbol(instanceInfo.scriptVariableLength)
) // SET symbol operand (should NOT be passed to the next stage)
val targetStage = UInt(
log2Ceil(
instanceInfo.maximumNumberOfStages * (instanceInfo.maximumNumberOfSupportedGetScriptOperators + instanceInfo.maximumNumberOfSupportedSetScriptOperators + 1)
).W
) // Target stage that needs to be executed for the current pin values (should be passed to the next stage)
val tempVariables = Vec(
instanceInfo.numberOfSupportedTemporaryVariables,
UInt(instanceInfo.scriptVariableLength.W)
) // Temporary variables
val localGlobalVariables = Vec(
instanceInfo.numberOfSupportedLocalAndGlobalVariables,
UInt(instanceInfo.scriptVariableLength.W)
) // Local (and Global) variables
val stageIndex = UInt(
log2Ceil(
instanceInfo.maximumNumberOfStages * (instanceInfo.maximumNumberOfSupportedGetScriptOperators + instanceInfo.maximumNumberOfSupportedSetScriptOperators + 1)
).W
) // Target stage index of the current stage (configured with script configuration and remains constant during execution)
val stageEnable = Bool() // Target stage is enabled (configured) or not
}

View file

@ -1,59 +0,0 @@
/**
* @file
* utils.scala
* @author
* Sina Karvandi (sina@hyperdbg.org)
* @brief
* Different utilities and functionalities
* @details
* @version 0.1
* @date
* 2024-04-12
*
* @copyright
* This project is released under the GNU Public License v3.
*/
package hwdbg.utils
import chisel3._
import chisel3.util._
/**
* @brief
* Create logs and debug messages
*/
object LogInfo {
def apply(debug: Boolean)(message: String): Unit = {
if (debug) {
println("[*] debug msg: " + message)
}
}
}
object BitwiseFunction {
def getFirstNBits(num: Long, n: Int): Long = {
val mask = (1L << n) - 1 // Create a bitmask with the first 'n' bits set to 1
val shifted = num >>> (java.lang.Long.SIZE - n) // Shift the bits to the right to keep the first 'n' bits
val firstNBits = shifted & mask // Extract the first 'n' bits by performing a bitwise AND operation
firstNBits
}
def getBitsInRange(num: Long, start: Int, end: Int): Long = {
require(start >= 0 && start <= 63, "Starting point must be between 0 and 63")
require(end >= 0 && end <= 63, "Ending point must be between 0 and 63")
require(start <= end, "Starting point must be less than or equal to ending point")
val numBits = end - start + 1 // Number of bits in the range
val mask = (1L << numBits) - 1 // Create a bitmask with 'numBits' bits set to 1
val shifted = num >>> (java.lang.Long.SIZE - end - 1) // Shift the bits to the right to align the range with the rightmost position
val bitsInRange = shifted & mask // Extract the bits within the specified range
bitsInRange
}
}

View file

@ -1,143 +0,0 @@
/**
* @file
* top.scala
* @author
* Sina Karvandi (sina@hyperdbg.org)
* @brief
* hwdbg's top module
* @details
* @version 0.1
* @date
* 2024-04-03
*
* @copyright
* This project is released under the GNU Public License v3.
*/
package hwdbg
import chisel3._
import circt.stage.ChiselStage
import hwdbg._
import hwdbg.configs._
class DebuggerModule(
debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
numberOfPins: Int,
maximumNumberOfStages: Int,
maximumNumberOfSupportedGetScriptOperators: Int,
maximumNumberOfSupportedSetScriptOperators: Int,
sharedMemorySize: Int,
debuggerAreaOffset: Int,
debuggeeAreaOffset: Int,
scriptVariableLength: Int,
numberOfSupportedLocalAndGlobalVariables: Int,
numberOfSupportedTemporaryVariables: Int,
scriptCapabilities: Seq[Long],
bramAddrWidth: Int,
bramDataWidth: Int,
portsConfiguration: Array[Int]
) extends Module {
val io = IO(new Bundle {
//
// Chip signals
//
val en = Input(Bool()) // chip enable signal
//
// Input/Output signals
//
val inputPin = Input(Vec(numberOfPins, UInt(1.W))) // input pins
val outputPin = Output(Vec(numberOfPins, UInt(1.W))) // output pins
//
// Interrupt signals (lines)
//
val plInSignal = Input(Bool()) // PS to PL signal
val psOutInterrupt = Output(Bool()) // PL to PS interrupt
//
// BRAM (Block RAM) ports
//
val rdWrAddr = Output(UInt(bramAddrWidth.W)) // read/write address
val rdData = Input(UInt(bramDataWidth.W)) // read data
val wrEna = Output(Bool()) // enable writing
val wrData = Output(UInt(bramDataWidth.W)) // write data
})
//
// Instantiate the debugger's main module
//
val (outputPin, psOutInterrupt, rdWrAddr, wrEna, wrData) =
DebuggerMain(
debug,
numberOfPins,
maximumNumberOfStages,
maximumNumberOfSupportedGetScriptOperators,
maximumNumberOfSupportedSetScriptOperators,
sharedMemorySize,
debuggerAreaOffset,
debuggeeAreaOffset,
scriptVariableLength,
numberOfSupportedLocalAndGlobalVariables,
numberOfSupportedTemporaryVariables,
scriptCapabilities,
bramAddrWidth,
bramDataWidth,
portsConfiguration
)(
io.en,
io.inputPin,
io.plInSignal,
io.rdData
)
io.outputPin := outputPin
io.psOutInterrupt := psOutInterrupt
io.rdWrAddr := rdWrAddr
io.wrEna := wrEna
io.wrData := wrData
}
object Main extends App {
//
// Load configuration from JSON file
//
LoadConfiguration.loadFromJson("src/main/scala/hwdbg/configs/config.json")
//
// Generate hwdbg verilog files
//
println(
ChiselStage.emitSystemVerilog(
new DebuggerModule(
DebuggerConfigurations.ENABLE_DEBUG,
DebuggerConfigurations.NUMBER_OF_PINS,
ScriptEngineConfigurations.MAXIMUM_NUMBER_OF_STAGES,
ScriptEngineConfigurations.MAXIMUM_NUMBER_OF_SUPPORTED_GET_SCRIPT_OPERATORS,
ScriptEngineConfigurations.MAXIMUM_NUMBER_OF_SUPPORTED_SET_SCRIPT_OPERATORS,
MemoryCommunicationConfigurations.DEFAULT_CONFIGURATION_INITIALIZED_MEMORY_SIZE,
MemoryCommunicationConfigurations.BASE_ADDRESS_OF_PS_TO_PL_COMMUNICATION,
MemoryCommunicationConfigurations.BASE_ADDRESS_OF_PL_TO_PS_COMMUNICATION,
ScriptEngineConfigurations.SCRIPT_VARIABLE_LENGTH,
ScriptEngineConfigurations.NUMBER_OF_SUPPORTED_LOCAL_AND_GLOBAL_VARIABLES,
ScriptEngineConfigurations.NUMBER_OF_SUPPORTED_TEMPORARY_VARIABLES,
ScriptEngineConfigurations.SCRIPT_ENGINE_EVAL_CAPABILITIES,
MemoryCommunicationConfigurations.BLOCK_RAM_ADDR_WIDTH,
MemoryCommunicationConfigurations.BLOCK_RAM_DATA_WIDTH,
DebuggerConfigurations.PORT_PINS_MAP
),
firtoolOpts = Array(
"-disable-all-randomization",
// "-strip-debug-info",
"--split-verilog", // The intention for this argument (and next argument) is to separate generated files.
"-o",
"generated/"
)
)
)
}

View file

@ -1,176 +0,0 @@
/**
* @file
* top_test.scala
* @author
* Sina Karvandi (sina@hyperdbg.org)
* @brief
* hwdbg's top module (with BRAM) for testing
* @details
* @version 0.1
* @date
* 2024-04-04
*
* @copyright
* This project is released under the GNU Public License v3.
*/
package hwdbg
import chisel3._
import circt.stage.ChiselStage
import hwdbg._
import hwdbg.configs._
import hwdbg.libs.mem._
class DebuggerModuleTestingBRAM(
debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
numberOfPins: Int,
maximumNumberOfStages: Int,
maximumNumberOfSupportedGetScriptOperators: Int,
maximumNumberOfSupportedSetScriptOperators: Int,
sharedMemorySize: Int,
debuggerAreaOffset: Int,
debuggeeAreaOffset: Int,
scriptVariableLength: Int,
numberOfSupportedLocalAndGlobalVariables: Int,
numberOfSupportedTemporaryVariables: Int,
scriptCapabilities: Seq[Long],
bramAddrWidth: Int,
bramDataWidth: Int,
portsConfiguration: Array[Int]
) extends Module {
val io = IO(new Bundle {
//
// Chip signals
//
val en = Input(Bool()) // chip enable signal
//
// Input/Output signals
//
val inputPin = Input(Vec(numberOfPins, UInt(1.W))) // input pins
val outputPin = Output(Vec(numberOfPins, UInt(1.W))) // output pins
//
// Interrupt signals (lines)
//
val plInSignal = Input(Bool()) // PS to PL signal
val psOutInterrupt = Output(Bool()) // PL to PS interrupt
//
// *** BRAM (Block RAM) ports are initialized from an external file ***
//
})
val bramEn = WireInit(false.B)
val bramWrite = WireInit(false.B)
val bramAddr = WireInit(0.U(bramAddrWidth.W))
val bramDataIn = WireInit(0.U(bramDataWidth.W))
val bramDataOut = WireInit(0.U(bramDataWidth.W))
//
// Instantiate the BRAM memory initializer module
//
val dataOut =
InitRegMemFromFile(
debug,
MemoryCommunicationConfigurations.ENABLE_BLOCK_RAM_DELAY,
TestingConfigurations.BRAM_INITIALIZATION_FILE_PATH,
bramAddrWidth,
bramDataWidth,
MemoryCommunicationConfigurations.DEFAULT_CONFIGURATION_INITIALIZED_MEMORY_SIZE
)(
bramEn,
bramWrite,
bramAddr,
bramDataIn
)
bramDataOut := dataOut
//
// Instantiate the debugger's main module
//
val (outputPin, psOutInterrupt, rdWrAddr, wrEna, wrData) =
DebuggerMain(
debug,
numberOfPins,
maximumNumberOfStages,
maximumNumberOfSupportedGetScriptOperators,
maximumNumberOfSupportedSetScriptOperators,
sharedMemorySize,
debuggerAreaOffset,
debuggeeAreaOffset,
scriptVariableLength,
numberOfSupportedLocalAndGlobalVariables,
numberOfSupportedTemporaryVariables,
scriptCapabilities,
bramAddrWidth,
bramDataWidth,
portsConfiguration
)(
io.en,
io.inputPin,
io.plInSignal,
bramDataOut
)
//
// Connect BRAM Pins
//
bramEn := io.en // enable BRAM when the main chip enabled
bramAddr := rdWrAddr
bramWrite := wrEna
bramDataIn := wrData
//
// Connect I/O pins
//
io.outputPin := outputPin
io.psOutInterrupt := psOutInterrupt
}
object MainWithInitializedBRAM extends App {
//
// Load configuration from JSON file
//
LoadConfiguration.loadFromJson("src/main/scala/hwdbg/configs/config.json")
//
// Generate hwdbg verilog files
//
println(
ChiselStage.emitSystemVerilog(
new DebuggerModuleTestingBRAM(
DebuggerConfigurations.ENABLE_DEBUG,
DebuggerConfigurations.NUMBER_OF_PINS,
ScriptEngineConfigurations.MAXIMUM_NUMBER_OF_STAGES,
ScriptEngineConfigurations.MAXIMUM_NUMBER_OF_SUPPORTED_GET_SCRIPT_OPERATORS,
ScriptEngineConfigurations.MAXIMUM_NUMBER_OF_SUPPORTED_SET_SCRIPT_OPERATORS,
MemoryCommunicationConfigurations.DEFAULT_CONFIGURATION_INITIALIZED_MEMORY_SIZE,
MemoryCommunicationConfigurations.BASE_ADDRESS_OF_PS_TO_PL_COMMUNICATION,
MemoryCommunicationConfigurations.BASE_ADDRESS_OF_PL_TO_PS_COMMUNICATION,
ScriptEngineConfigurations.SCRIPT_VARIABLE_LENGTH,
ScriptEngineConfigurations.NUMBER_OF_SUPPORTED_LOCAL_AND_GLOBAL_VARIABLES,
ScriptEngineConfigurations.NUMBER_OF_SUPPORTED_TEMPORARY_VARIABLES,
ScriptEngineConfigurations.SCRIPT_ENGINE_EVAL_CAPABILITIES,
MemoryCommunicationConfigurations.BLOCK_RAM_ADDR_WIDTH,
MemoryCommunicationConfigurations.BLOCK_RAM_DATA_WIDTH,
DebuggerConfigurations.PORT_PINS_MAP
),
firtoolOpts = Array(
"-disable-all-randomization",
// "-strip-debug-info",
"--lowering-options=disallowLocalVariables", // because icarus doesn't support 'automatic logic', this option prevents such logics
"--split-verilog", // The intention for this argument (and next argument) is to separate generated files.
"-o",
"generated/"
)
)
)
}

File diff suppressed because it is too large Load diff

View file

@ -1,64 +0,0 @@
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 03/08/2024 04:39:27 PM
// Design Name:
// Module Name: PL_CORE
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module PL_CORE(
(* clock_buffer_type="none" *) input wire QDR4_CLK_100MHZ_P,
(* clock_buffer_type="none" *) input wire QDR4_CLK_100MHZ_N,
// input wire reg_clk,
input wire uart_rx_line,
// input wire reg_eop,
// input logic SPI_nCS,
// output wire clk_reg_out,
output wire uart_tx_line,
// output logic laser_module_trigger,
output wire [3:0] led_out_ff
);
wire clk_main;
clk_wiz_11 clock_main
(
// Clock out ports
.clk_main(clk_main), // output clk_main
// Status and control signals
.reset(reset), // input reset
.locked(locked), // output locked
// Clock in ports
.clk_in1_p(QDR4_CLK_100MHZ_P), // input clk_in1_p
.clk_in1_n(QDR4_CLK_100MHZ_N) // input clk_in1_n
);
UART_FF UART_FF_INS (
.clk (clk_main),
.rst ('b0),
.reg_clk (clk_main),
.reg_eop (clk_main),
.uart_rx_line (uart_rx_line),
.uart_tx_line (uart_tx_line),
.gpio (gpio),
.led_out_ff (led_out_ff)
);
endmodule

View file

@ -1,89 +0,0 @@
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 11/16/2023 02:48:20 PM
// Design Name:
// Module Name: ff_fanout
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module ff_fanout(
input wire clk,
input wire CE,
input wire rst,
input wire inp,
output reg res
);
//reg rst_em; // input clock on FPGA
//reg[27:0] counter=28'd0;
//parameter DIVISOR = 28'd1;
//// The frequency of the output clk_out
//// = The frequency of the input clk_in divided by DIVISOR
//// For example: Fclk_in = 50Mhz, if you want to get 1Hz signal to blink LEDs
//// You will modify the DIVISOR parameter value to 28'd50.000.000
//// Then the frequency of the output clk_out = 50Mhz/50.000.000 = 1Hz
//always @(posedge rst)
//begin
// counter <= counter + 28'd1;
// if(counter>=(DIVISOR-1))
// counter <= 28'd0;
// rst_em <= (counter<DIVISOR/2)?1'b1:1'b0;
//end
localparam size_i = 256;
(* S = "TRUE" *) (* KEEP = "TRUE" *) wire [size_i-1:0] q_output;
(* S = "TRUE" *) (* KEEP = "TRUE" *) wire [size_i-1:0] d_input;
assign d_input = ({size_i{inp}});
wire CLR;
assign CLR= 1'b0;
always @(posedge clk)begin
res <= &q_output;
end
(* S = "TRUE" *) (* KEEP = "TRUE" *) FDRE #(.INIT(1'b0)) FDRE_inst[size_i-1:0](
.Q(q_output),
.C(clk),
.CE(1'b1),
.R(rst),
.D(d_input)
);
// (* S = "TRUE" *) (* KEEP = "TRUE" *) FDRE #(.INIT(1'b0)) FDRE_inst[size_i-1:0](
// .Q(q_output),
// .C(clk),
// .CE(CE),
// .R(1'b0),
// .D(d_input)
// );
endmodule

View file

@ -1,78 +0,0 @@
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 06/20/2024 10:21:57 AM
// Design Name:
// Module Name: freq_generator
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module freq_generator(
input logic clk_in, // Input clock
input logic reset, // Reset signal
input logic [31:0] div_int, // Integer part of the division factor
input logic [31:0] div_frac, // Fractional part of the division factor (in fixed-point format, e.g., 0.5 = 32'd50000000)
output logic clk_out // Output clock
);
logic [31:0] int_counter;
logic [31:0] frac_counter;
logic frac_tick;
logic clk_out_internal;
// Integer Clock Division Logic
always_ff @(posedge clk_in or posedge reset) begin
if (reset) begin
int_counter <= 32'd0;
clk_out_internal <= 1'b0;
end else begin
if (int_counter >= (div_int - 1)) begin
int_counter <= 32'd0;
clk_out_internal <= ~clk_out_internal;
end else begin
int_counter <= int_counter + 1;
end
end
end
// Fractional Clock Division Logic
always_ff @(posedge clk_in or posedge reset) begin
if (reset) begin
frac_counter <= 32'd0;
frac_tick <= 1'b0;
end else begin
frac_counter <= frac_counter + div_frac;
if (frac_counter >= 32'd100000000) begin // When the counter exceeds 1.0 in fixed-point format
frac_counter <= frac_counter - 32'd100000000;
frac_tick <= 1'b1;
end else begin
frac_tick <= 1'b0;
end
end
end
// Combine Integer and Fractional Divisions
always_ff @(posedge clk_in or posedge reset) begin
if (reset) begin
clk_out <= 1'b0;
end else if (int_counter == 0 && frac_tick) begin
clk_out <= ~clk_out_internal;
end else begin
clk_out <= clk_out_internal;
end
end
endmodule

View file

@ -1,29 +0,0 @@
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 08/29/2023 01:50:41 PM
// Design Name:
// Module Name: inverter
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module inverter(
in_data,out_data
);
input in_data;
output out_data;
(* dont_touch = "yes" *) assign out_data = !in_data;
endmodule

View file

@ -1,43 +0,0 @@
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 09/11/2023 11:01:41 AM
// Design Name:
// Module Name: inverter_chain
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module Chain(
chain_en,
in_data,
out_data
);
parameter N = 2000; //This is the number of inverters in chain
input wire chain_en;
input wire in_data; // This has to be connected to the input pin of the design according to the XDC file
output wire out_data; // make sure to connect it to one of the output pin of the circuit according to the XDC file
(* dont_touch = "yes" *) wire [N-1:0] intermadiate_value; //For D-flip-flop implementation, make it reg instead of wire!
(* dont_touch = "yes" *) inverter inverter_in (.in_data(in_data&chain_en),.out_data(intermadiate_value[0])); // this is just for initiation, for loop chain, you can remove it.
generate
genvar i;
for (i=0; i<N-1 ; i = i + 1) begin
(* dont_touch = "yes" *) inverter inverter_i (.in_data(intermadiate_value[i]),.out_data(intermadiate_value[i+1]));
end
endgenerate
(* dont_touch = "yes" *) inverter inverter_out (.in_data(intermadiate_value[N-1]),.out_data(out_data)); // this is just for output connection, for loop chain, you can remove it.
endmodule

View file

@ -1,60 +0,0 @@
module multibyte_uart_rx
#(
parameter SYSTEMCLOCK = 100_000_000,
parameter BAUDRATE = 115_200,
parameter ELEMENT_WIDTH = 8,
parameter NUMBER_OF_ELEMENTS = 256,
localparam DATA_LENGTH_COUNTER_WIDTH = $clog2(NUMBER_OF_ELEMENTS)
)(
input logic clk,
input logic rst,
input logic rx_line,
input logic rx_empty_buffer,
output logic [NUMBER_OF_ELEMENTS-1:0][ELEMENT_WIDTH-1:0] rx_data,
output logic [DATA_LENGTH_COUNTER_WIDTH:0] rx_data_length,
output logic rx_updated_buffer,
output logic rx_overflow
);
logic [ELEMENT_WIDTH-1:0] uart_rx_data;
logic uart_rx_data_valid;
uart_rx receiver (
.clk(clk),
.rst(rst),
.rx_line(rx_line),
.rx_data(uart_rx_data),
.rx_data_valid(uart_rx_data_valid)
);
defparam receiver.BAUDRATE = BAUDRATE;
defparam receiver.SYSTEMCLOCK = SYSTEMCLOCK;
defparam receiver.ELEMENT_WIDTH = ELEMENT_WIDTH;
always @(posedge clk) begin
if (rst || rx_empty_buffer) begin
rx_data_length <= 'd0;
rx_data <= 'b0;
rx_updated_buffer <= 'b0;
rx_overflow <= 'b0;
end else begin
rx_data_length <= rx_data_length;
rx_data <= rx_data;
rx_updated_buffer <= 'b0;
rx_overflow <= rx_overflow;
if (uart_rx_data_valid) begin
if (rx_data_length < NUMBER_OF_ELEMENTS) begin
rx_data[rx_data_length] <= uart_rx_data;
rx_data_length <= rx_data_length + 1;
rx_updated_buffer <= 'b1;
end else begin
rx_overflow <= 'b1;
end
end
end
end
endmodule

View file

@ -1,103 +0,0 @@
module multibyte_uart_tx
#(
parameter SYSTEMCLOCK = 100_000_000,
parameter BAUDRATE = 115_200,
parameter ELEMENT_WIDTH = 8,
parameter NUMBER_OF_ELEMENTS = 256,
parameter DELAY_WIDTH = 32,
localparam TRANSFER_COUNTER_WIDTH = $clog2(NUMBER_OF_ELEMENTS)
)(
input logic clk,
input logic rst,
input logic tx_en,
input logic [NUMBER_OF_ELEMENTS-1:0][ELEMENT_WIDTH-1:0] tx_data,
input logic [TRANSFER_COUNTER_WIDTH:0] tx_data_length,
input logic [DELAY_WIDTH-1:0] delay_between_tx,
output logic tx_line,
output logic tx_ready
);
logic [ELEMENT_WIDTH-1:0] uart_tx_data;
logic uart_tx_en;
logic uart_tx_ready;
uart_tx sender(
.clk (clk),
.rst (rst),
.tx_en (uart_tx_en),
.tx_data (uart_tx_data),
.tx_line (tx_line),
.tx_ready (uart_tx_ready)
);
defparam sender.BAUDRATE = BAUDRATE;
defparam sender.SYSTEMCLOCK = SYSTEMCLOCK;
defparam sender.ELEMENT_WIDTH = ELEMENT_WIDTH;
typedef enum {
STATE_IDLE,
STATE_TRANSFER,
STATE_WAIT_BEWTEEN_TX
} state_t;
state_t current_state;
state_t state_after_wait;
logic [DELAY_WIDTH-1:0] delay_counter;
logic [TRANSFER_COUNTER_WIDTH-1:0] transfer_counter;
integer i;
always_ff @(posedge clk) begin
if (rst) begin
current_state <= STATE_IDLE;
uart_tx_en <= 'b0;
uart_tx_data <= 'd0;
tx_ready <= 'b0;
delay_counter <= 'd0;
transfer_counter <= 'd0;
end else begin
current_state <= current_state;
uart_tx_en <= 'b0;
uart_tx_data <= uart_tx_data;
tx_ready <= tx_ready;
delay_counter <= delay_counter;
transfer_counter <= transfer_counter;
case (current_state)
STATE_IDLE: begin
if (tx_en && (tx_data_length > 0)) begin
current_state <= STATE_TRANSFER;
transfer_counter <= 'd0;
end else begin
tx_ready <= 'b1;
end
end
STATE_TRANSFER: begin
if (uart_tx_ready) begin
uart_tx_data <= tx_data[transfer_counter];
uart_tx_en <= 'b1;
current_state <= STATE_WAIT_BEWTEEN_TX;
delay_counter <= 'd0;
transfer_counter <= transfer_counter + 1;
end
end
STATE_WAIT_BEWTEEN_TX: begin
if (uart_tx_ready) begin
delay_counter <= delay_counter + 1;
if (delay_counter >= delay_between_tx) begin
if (transfer_counter >= tx_data_length) begin
current_state <= STATE_IDLE;
end else begin
current_state <= STATE_TRANSFER;
end
end
end
end
endcase
end
end
endmodule

View file

@ -1,31 +0,0 @@
`timescale 1ps / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 11/13/2023 05:16:59 PM
// Design Name:
// Module Name: not_gate_simple
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module not_gate_simple(
input wire X,
output wire Y
);
// (* ALLOW_COMBINATORIAL_LOOPS = "yes" *) assign #10 Y = ~X;
(* ALLOW_COMBINATORIAL_LOOPS = "yes" *) assign Y = ~X;
endmodule

View file

@ -1,76 +0,0 @@
`timescale 1ns/1ps
module ro(
// input ck_io41,
// output ck_io33
input wire R_in,
output wire R_out);
wire a /* synthesis keep */;
wire b /* synthesis keep */;
assign b = a & R_in;
//assign b = a ;
wire [2:0] x /* synthesis keep */;
not_gate_simple not0(
.X(b),
.Y(x[0]));
not_gate_simple not1(
.X(x[0]),
.Y(x[1]));
not_gate_simple not2(
.X(x[1]),
.Y(x[2]));
//not_gate_simple not3(
// .X(x[2]),
// .Y(x[3]));
//not_gate_simple not4(
// .X(x[3]),
// .Y(x[4]));
//not_gate_simple not5(
// .X(x[4]),
// .Y(x[5]));
//not_gate_simple not6(
// .X(x[5]),
// .Y(x[6]));
//not_gate_simple not7(
// .X(x[6]),
// .Y(x[7]));
//not_gate_simple not8(
// .X(x[7]),
// .Y(x[8]));
//not_gate_simple not9(
// .X(x[8]),
// .Y(x[9]));
//not_gate_simple not10(
// .X(x[9]),
// .Y(x[10]));
assign R_out = x[2];
assign a = x[2] & R_in;
endmodule

View file

@ -1,60 +0,0 @@
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 12/01/2022 04:46:30 PM
// Design Name:
// Module Name: reg1_core
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module ro_core(
input wire [0:0] in_d,
output wire [0:0] wire_inj
);
// localparam size_i = 127000;
//localparam size_i = 64000;
//localparam size_i = 1000;
//localparam size_i = 128;
localparam size_i = 1;
reg ce1;
reg CLR1;
wire [size_i-1:0] inp_r;
// assign inp_r=in_d[size_i-1:0];
assign inp_r=in_d[size_i-1:0];
(* S = "TRUE" *)(* KEEP = "TRUE" *) wire [size_i-1:0] q_out;
assign wire_inj = q_out;
ro_fanout ro_fanout_ins[size_i-1:0] (
.R_in(inp_r), // 1-bit Enable
.R_out(q_out) // 1-bit Data output
);
endmodule

View file

@ -1,50 +0,0 @@
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 03/15/2024 01:55:18 PM
// Design Name:
// Module Name: ro_fanout
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module ro_fanout(
input wire R_in,
output wire R_out
);
localparam size_i = 1;
(* S = "TRUE" *) (* KEEP = "TRUE" *) wire [size_i-1:0] ro_input;
(* S = "TRUE" *) (* KEEP = "TRUE" *) wire [size_i-1:0] ro_output;
assign R_out = ro_output[0];
assign ro_input = ({size_i{R_in}});
(* S = "TRUE" *) (* KEEP = "TRUE" *) ro ro_inst[size_i-1:0](
.R_in(ro_input),
.R_out(ro_output)
);
// (* S = "TRUE" *) (* KEEP = "TRUE" *) ro_sv #(.INVERTERS_PER_RING(3), .INVERTER_DELAY(1)) ro_inst[size_i-1:0](
// .R_in(ro_input),
// .R_out(ro_output)
// );
endmodule

View file

@ -1,138 +0,0 @@
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 06/17/2024 05:14:28 PM
// Design Name:
// Module Name: ro_sensor
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module ro_sensor
#(parameter integer width_size = 64,
localparam integer width_size_local = width_size)
(
input logic [width_size-1:0]ro_meas_time,
input logic clk,
input logic r_out,
input logic ro_counter_en,
output logic [width_size-1:0]ro_meas_count
);
logic [width_size-1:0] clk_temp_counter;
logic [width_size-1:0] ro_temp_counter;
logic measure_flag;
// RO_Counter Circuit
// State encoding
typedef enum logic [1:0] {
IDLE = 2'b00,
MEASURE = 2'b01,
OUT_READY = 2'b10,
RST_VALS = 2'b11
} state_t;
state_t current_state, next_state;
initial next_state <= IDLE;
// State transition logic
always_ff @(negedge clk ) begin
current_state <= next_state;
end
// Next state logic
always @(posedge clk) begin
case (current_state)
IDLE: begin
for (int i = 0; i < width_size; i++) begin
clk_temp_counter[i] = 1'b0;
end
if (ro_counter_en) begin
next_state = RST_VALS;
end else begin
next_state = IDLE;
end
end
RST_VALS: begin
next_state = MEASURE;
end
MEASURE: begin
if (clk_temp_counter < ro_meas_time) begin
clk_temp_counter = clk_temp_counter+ ('d1);
next_state = MEASURE;
end else begin
for (int i = 0; i < width_size; i++) begin
clk_temp_counter[i] = 1'b0;
end
next_state = OUT_READY;
end
end
OUT_READY: begin
next_state = IDLE;
end
// default: begin
// next_state = IDLE;
// end
endcase
end
// Output logic
// assign state = current_state;
always @( posedge r_out ) begin
if(current_state==MEASURE) begin
ro_temp_counter=ro_temp_counter+ ('d1);
end else if(current_state==OUT_READY) begin
ro_meas_count = ro_temp_counter;
end else if(current_state==RST_VALS) begin
ro_temp_counter = 'h0000000000000000;
end
end
// `define assign_reg(index,reg1_t,reg2_t) \
// assign reg1_t[((index+1)*60)+7:((index)*60)+8]=reg2_t[index];
// `assign_reg(0,aes_ct,fult_count)
// `assign_reg(1,aes_ct,fult_count)
//// `assign_reg(2,aes_ct,fult_count)
//// `assign_reg(3,aes_ct,fult_count)
//// `assign_reg(4,aes_ct,fult_count)
//// `assign_reg(5,aes_ct,fult_count)
//// `assign_reg(6,aes_ct,fult_count)
//// `assign_reg(7,aes_ct,fult_count)
endmodule

File diff suppressed because it is too large Load diff

View file

@ -1,99 +0,0 @@
module uart_rx
#(
parameter SYSTEMCLOCK = 100_000_000,
parameter BAUDRATE = 115_200,
parameter ELEMENT_WIDTH = 8,
localparam ELEMENT_BIT_COUNTER_WIDTH = $clog2(ELEMENT_WIDTH),
localparam CLOCK_COUNTER_WIDTH = 32,
localparam CLOCKS_PER_BAUD = SYSTEMCLOCK / BAUDRATE
)(
input logic clk,
input logic rst,
input logic rx_line,
output logic [ELEMENT_WIDTH-1:0] rx_data,
output logic rx_data_valid
);
typedef enum {
STATE_IDLE,
STATE_START_BIT,
STATE_RECEIVE_ELEMENT,
STATE_CHECK_ELEMENT_RECEIVED,
STATE_STOP_BIT,
STATE_DONE
} state_t;
state_t current_state;
logic [ELEMENT_BIT_COUNTER_WIDTH:0] current_bit;
logic [CLOCK_COUNTER_WIDTH-1:0] clock_counter;
logic clocks_per_baud_reached;
logic half_clocks_per_baud_reached;
assign clocks_per_baud_reached = (clock_counter >= CLOCKS_PER_BAUD);
assign half_clocks_per_baud_reached = (clock_counter >= (CLOCKS_PER_BAUD / 2));
assign rx_data = rx_data;
assign rx_data_valid = current_state == STATE_DONE;
always_ff @(posedge clk) begin
if (rst) begin
current_state <= STATE_IDLE;
current_bit <= 'b0;
rx_data <= 'b0;
clock_counter <= 'd0;
end else begin
current_state <= current_state;
current_bit <= current_bit;
rx_data <= rx_data;
clock_counter <= clock_counter + 1;
case (current_state)
STATE_IDLE: begin
if (rx_line == 'b0) begin
current_state <= STATE_START_BIT;
clock_counter <= 'b0;
end
end
STATE_START_BIT: begin
if (half_clocks_per_baud_reached) begin
current_state <= STATE_RECEIVE_ELEMENT;
clock_counter <= 'b0;
current_bit <= 'b0;
end
end
STATE_RECEIVE_ELEMENT: begin
if (clocks_per_baud_reached) begin
rx_data[current_bit] <= rx_line;
current_bit <= current_bit + 1;
clock_counter <= 'd0;
current_state <= STATE_CHECK_ELEMENT_RECEIVED;
end
end
STATE_CHECK_ELEMENT_RECEIVED: begin
if (current_bit >= ELEMENT_WIDTH) begin
current_state <= STATE_STOP_BIT;
end else begin
current_state <= STATE_RECEIVE_ELEMENT;
end
end
STATE_STOP_BIT: begin
if (clocks_per_baud_reached) begin
current_state <= STATE_DONE;
clock_counter <= 'd0;
end
end
STATE_DONE: begin
current_state <= STATE_IDLE;
end
endcase
end
end
endmodule

View file

@ -1,104 +0,0 @@
module uart_tx
#(
parameter SYSTEMCLOCK = 100_000_000,
parameter BAUDRATE = 115_200,
parameter ELEMENT_WIDTH = 8,
localparam ELEMENT_BIT_COUNTER_WIDTH = $clog2(ELEMENT_WIDTH),
localparam CLOCK_COUNTER_WIDTH = 32,
localparam CLOCKS_PER_BAUD = SYSTEMCLOCK / BAUDRATE
)(
input logic clk,
input logic rst,
input logic tx_en,
input logic [ELEMENT_WIDTH-1:0] tx_data,
output logic tx_line,
output logic tx_ready
);
typedef enum {
STATE_IDLE,
STATE_START_BIT,
STATE_TRANSFER_ELEMENT,
STATE_CHECK_ELEMENT_TRANSFERRED,
STATE_STOP_BIT,
STATE_DONE
} state_t;
state_t current_state;
logic [ELEMENT_BIT_COUNTER_WIDTH:0] bit_counter = 'b0;
logic [CLOCK_COUNTER_WIDTH:0] clock_counter = 'b0;
logic clocks_per_baud_reached;
assign clocks_per_baud_reached = (clock_counter >= CLOCKS_PER_BAUD);
always @(posedge clk) begin
if (rst) begin
current_state <= STATE_IDLE;
bit_counter <= 'd0;
clock_counter <= 'd0;
tx_line <= 'b1;
tx_ready <= 'b0;
end else begin
clock_counter <= clock_counter + 1;
current_state <= current_state;
bit_counter <= bit_counter;
tx_line <= tx_line;
tx_ready <= tx_ready;
case (current_state)
STATE_IDLE: begin
if (tx_en) begin
current_state <= STATE_START_BIT;
tx_line <= 'b0;
tx_ready <= 'b0;
end else begin
tx_line <= 'b1;
tx_ready <= 'b1;
end
end
STATE_START_BIT: begin
current_state <= STATE_TRANSFER_ELEMENT;
bit_counter <= 'd0;
clock_counter <= 'd0;
end
STATE_TRANSFER_ELEMENT: begin
if(clocks_per_baud_reached) begin
clock_counter <= 'b0;
tx_line <= tx_data[bit_counter];
bit_counter <= bit_counter + 1;
current_state <= STATE_CHECK_ELEMENT_TRANSFERRED;
end
end
STATE_CHECK_ELEMENT_TRANSFERRED: begin
if (bit_counter >= ELEMENT_WIDTH) begin
current_state <= STATE_STOP_BIT;
end else begin
current_state <= STATE_TRANSFER_ELEMENT;
end
end
STATE_STOP_BIT: begin
if(clocks_per_baud_reached) begin
tx_line <= 'b1;
clock_counter <= 'd0;
current_state <= STATE_DONE;
end
end
STATE_DONE: begin
if (clocks_per_baud_reached) begin
tx_ready <= 'b1;
current_state <= STATE_IDLE;
end
end
endcase
end
end
endmodule

View file

@ -1,256 +0,0 @@
0000005a ; +0x0 | Checksum
00000000 ; +0x4 | Checksum
52444247 ; +0x8 | Indicator
48595045 ; +0xc | Indicator
00000004 ; +0x10 | TypeOfThePacket - DEBUGGER_TO_DEBUGGEE_HARDWARE_LEVEL (0x4)
00000001 ; +0x14 | RequestedActionOfThePacket - Value (0x1)
00000000 ; +0x18
00000000 ; +0x1c
00000000 ; +0x20
00000000 ; +0x24
00000000 ; +0x28
00000000 ; +0x2c
00000000 ; +0x30
00000000 ; +0x34
00000000 ; +0x38
00000000 ; +0x3c
00000000 ; +0x40
00000000 ; +0x44
00000000 ; +0x48
00000000 ; +0x4c
00000000 ; +0x50
00000000 ; +0x54
00000000 ; +0x58
00000000 ; +0x5c
00000000 ; +0x60
00000000 ; +0x64
00000000 ; +0x68
00000000 ; +0x6c
00000000 ; +0x70
00000000 ; +0x74
00000000 ; +0x78
00000000 ; +0x7c
00000000 ; +0x80
00000000 ; +0x84
00000000 ; +0x88
00000000 ; +0x8c
00000000 ; +0x90
00000000 ; +0x94
00000000 ; +0x98
00000000 ; +0x9c
00000000 ; +0xa0
00000000 ; +0xa4
00000000 ; +0xa8
00000000 ; +0xac
00000000 ; +0xb0
00000000 ; +0xb4
00000000 ; +0xb8
00000000 ; +0xbc
00000000 ; +0xc0
00000000 ; +0xc4
00000000 ; +0xc8
00000000 ; +0xcc
00000000 ; +0xd0
00000000 ; +0xd4
00000000 ; +0xd8
00000000 ; +0xdc
00000000 ; +0xe0
00000000 ; +0xe4
00000000 ; +0xe8
00000000 ; +0xec
00000000 ; +0xf0
00000000 ; +0xf4
00000000 ; +0xf8
00000000 ; +0xfc
00000000 ; +0x100
00000000 ; +0x104
00000000 ; +0x108
00000000 ; +0x10c
00000000 ; +0x110
00000000 ; +0x114
00000000 ; +0x118
00000000 ; +0x11c
00000000 ; +0x120
00000000 ; +0x124
00000000 ; +0x128
00000000 ; +0x12c
00000000 ; +0x130
00000000 ; +0x134
00000000 ; +0x138
00000000 ; +0x13c
00000000 ; +0x140
00000000 ; +0x144
00000000 ; +0x148
00000000 ; +0x14c
00000000 ; +0x150
00000000 ; +0x154
00000000 ; +0x158
00000000 ; +0x15c
00000000 ; +0x160
00000000 ; +0x164
00000000 ; +0x168
00000000 ; +0x16c
00000000 ; +0x170
00000000 ; +0x174
00000000 ; +0x178
00000000 ; +0x17c
00000000 ; +0x180
00000000 ; +0x184
00000000 ; +0x188
00000000 ; +0x18c
00000000 ; +0x190
00000000 ; +0x194
00000000 ; +0x198
00000000 ; +0x19c
00000000 ; +0x1a0
00000000 ; +0x1a4
00000000 ; +0x1a8
00000000 ; +0x1ac
00000000 ; +0x1b0
00000000 ; +0x1b4
00000000 ; +0x1b8
00000000 ; +0x1bc
00000000 ; +0x1c0
00000000 ; +0x1c4
00000000 ; +0x1c8
00000000 ; +0x1cc
00000000 ; +0x1d0
00000000 ; +0x1d4
00000000 ; +0x1d8
00000000 ; +0x1dc
00000000 ; +0x1e0
00000000 ; +0x1e4
00000000 ; +0x1e8
00000000 ; +0x1ec
00000000 ; +0x1f0
00000000 ; +0x1f4
00000000 ; +0x1f8
00000000 ; +0x1fc
00000000 ; +0x200
00000000 ; +0x204
00000000 ; +0x208
00000000 ; +0x20c
00000000 ; +0x210
00000000 ; +0x214
00000000 ; +0x218
00000000 ; +0x21c
00000000 ; +0x220
00000000 ; +0x224
00000000 ; +0x228
00000000 ; +0x22c
00000000 ; +0x230
00000000 ; +0x234
00000000 ; +0x238
00000000 ; +0x23c
00000000 ; +0x240
00000000 ; +0x244
00000000 ; +0x248
00000000 ; +0x24c
00000000 ; +0x250
00000000 ; +0x254
00000000 ; +0x258
00000000 ; +0x25c
00000000 ; +0x260
00000000 ; +0x264
00000000 ; +0x268
00000000 ; +0x26c
00000000 ; +0x270
00000000 ; +0x274
00000000 ; +0x278
00000000 ; +0x27c
00000000 ; +0x280
00000000 ; +0x284
00000000 ; +0x288
00000000 ; +0x28c
00000000 ; +0x290
00000000 ; +0x294
00000000 ; +0x298
00000000 ; +0x29c
00000000 ; +0x2a0
00000000 ; +0x2a4
00000000 ; +0x2a8
00000000 ; +0x2ac
00000000 ; +0x2b0
00000000 ; +0x2b4
00000000 ; +0x2b8
00000000 ; +0x2bc
00000000 ; +0x2c0
00000000 ; +0x2c4
00000000 ; +0x2c8
00000000 ; +0x2cc
00000000 ; +0x2d0
00000000 ; +0x2d4
00000000 ; +0x2d8
00000000 ; +0x2dc
00000000 ; +0x2e0
00000000 ; +0x2e4
00000000 ; +0x2e8
00000000 ; +0x2ec
00000000 ; +0x2f0
00000000 ; +0x2f4
00000000 ; +0x2f8
00000000 ; +0x2fc
00000000 ; +0x300
00000000 ; +0x304
00000000 ; +0x308
00000000 ; +0x30c
00000000 ; +0x310
00000000 ; +0x314
00000000 ; +0x318
00000000 ; +0x31c
00000000 ; +0x320
00000000 ; +0x324
00000000 ; +0x328
00000000 ; +0x32c
00000000 ; +0x330
00000000 ; +0x334
00000000 ; +0x338
00000000 ; +0x33c
00000000 ; +0x340
00000000 ; +0x344
00000000 ; +0x348
00000000 ; +0x34c
00000000 ; +0x350
00000000 ; +0x354
00000000 ; +0x358
00000000 ; +0x35c
00000000 ; +0x360
00000000 ; +0x364
00000000 ; +0x368
00000000 ; +0x36c
00000000 ; +0x370
00000000 ; +0x374
00000000 ; +0x378
00000000 ; +0x37c
00000000 ; +0x380
00000000 ; +0x384
00000000 ; +0x388
00000000 ; +0x38c
00000000 ; +0x390
00000000 ; +0x394
00000000 ; +0x398
00000000 ; +0x39c
00000000 ; +0x3a0
00000000 ; +0x3a4
00000000 ; +0x3a8
00000000 ; +0x3ac
00000000 ; +0x3b0
00000000 ; +0x3b4
00000000 ; +0x3b8
00000000 ; +0x3bc
00000000 ; +0x3c0
00000000 ; +0x3c4
00000000 ; +0x3c8
00000000 ; +0x3cc
00000000 ; +0x3d0
00000000 ; +0x3d4
00000000 ; +0x3d8
00000000 ; +0x3dc
00000000 ; +0x3e0
00000000 ; +0x3e4
00000000 ; +0x3e8
00000000 ; +0x3ec
00000000 ; +0x3f0
00000000 ; +0x3f4
00000000 ; +0x3f8
00000000 ; +0x3fc

View file

@ -1,256 +0,0 @@
000000b9 ; +0x0 | Checksum
00000000 ; +0x4 | Checksum
52444247 ; +0x8 | Indicator
48595045 ; +0xc | Indicator
00000004 ; +0x10 | TypeOfThePacket - DEBUGGER_TO_DEBUGGEE_HARDWARE_LEVEL (0x4)
00000002 ; +0x14 | RequestedActionOfThePacket - Value (0x2)
00000007 ; +0x18 | Start of Optional Data
00000006 ; +0x1c
0000000a ; +0x20
00000003 ; +0x24
00000000 ; +0x28
0000000f ; +0x2c
00000000 ; +0x30
0000000f ; +0x34
00000000 ; +0x38
00000006 ; +0x3c
00000018 ; +0x40
00000003 ; +0x44
00000001 ; +0x48
00000000 ; +0x4c
00000000 ; +0x50
00000004 ; +0x54
00000000 ; +0x58
00000000 ; +0x5c
00000000 ; +0x60
00000000 ; +0x64
00000000 ; +0x68
00000000 ; +0x6c
00000000 ; +0x70
00000000 ; +0x74
00000000 ; +0x78
00000000 ; +0x7c
00000000 ; +0x80
00000000 ; +0x84
00000000 ; +0x88
00000000 ; +0x8c
00000000 ; +0x90
00000000 ; +0x94
00000000 ; +0x98
00000000 ; +0x9c
00000000 ; +0xa0
00000000 ; +0xa4
00000000 ; +0xa8
00000000 ; +0xac
00000000 ; +0xb0
00000000 ; +0xb4
00000000 ; +0xb8
00000000 ; +0xbc
00000000 ; +0xc0
00000000 ; +0xc4
00000000 ; +0xc8
00000000 ; +0xcc
00000000 ; +0xd0
00000000 ; +0xd4
00000000 ; +0xd8
00000000 ; +0xdc
00000000 ; +0xe0
00000000 ; +0xe4
00000000 ; +0xe8
00000000 ; +0xec
00000000 ; +0xf0
00000000 ; +0xf4
00000000 ; +0xf8
00000000 ; +0xfc
00000000 ; +0x100
00000000 ; +0x104
00000000 ; +0x108
00000000 ; +0x10c
00000000 ; +0x110
00000000 ; +0x114
00000000 ; +0x118
00000000 ; +0x11c
00000000 ; +0x120
00000000 ; +0x124
00000000 ; +0x128
00000000 ; +0x12c
00000000 ; +0x130
00000000 ; +0x134
00000000 ; +0x138
00000000 ; +0x13c
00000000 ; +0x140
00000000 ; +0x144
00000000 ; +0x148
00000000 ; +0x14c
00000000 ; +0x150
00000000 ; +0x154
00000000 ; +0x158
00000000 ; +0x15c
00000000 ; +0x160
00000000 ; +0x164
00000000 ; +0x168
00000000 ; +0x16c
00000000 ; +0x170
00000000 ; +0x174
00000000 ; +0x178
00000000 ; +0x17c
00000000 ; +0x180
00000000 ; +0x184
00000000 ; +0x188
00000000 ; +0x18c
00000000 ; +0x190
00000000 ; +0x194
00000000 ; +0x198
00000000 ; +0x19c
00000000 ; +0x1a0
00000000 ; +0x1a4
00000000 ; +0x1a8
00000000 ; +0x1ac
00000000 ; +0x1b0
00000000 ; +0x1b4
00000000 ; +0x1b8
00000000 ; +0x1bc
00000000 ; +0x1c0
00000000 ; +0x1c4
00000000 ; +0x1c8
00000000 ; +0x1cc
00000000 ; +0x1d0
00000000 ; +0x1d4
00000000 ; +0x1d8
00000000 ; +0x1dc
00000000 ; +0x1e0
00000000 ; +0x1e4
00000000 ; +0x1e8
00000000 ; +0x1ec
00000000 ; +0x1f0
00000000 ; +0x1f4
00000000 ; +0x1f8
00000000 ; +0x1fc
00000000 ; +0x200
00000000 ; +0x204
00000000 ; +0x208
00000000 ; +0x20c
00000000 ; +0x210
00000000 ; +0x214
00000000 ; +0x218
00000000 ; +0x21c
00000000 ; +0x220
00000000 ; +0x224
00000000 ; +0x228
00000000 ; +0x22c
00000000 ; +0x230
00000000 ; +0x234
00000000 ; +0x238
00000000 ; +0x23c
00000000 ; +0x240
00000000 ; +0x244
00000000 ; +0x248
00000000 ; +0x24c
00000000 ; +0x250
00000000 ; +0x254
00000000 ; +0x258
00000000 ; +0x25c
00000000 ; +0x260
00000000 ; +0x264
00000000 ; +0x268
00000000 ; +0x26c
00000000 ; +0x270
00000000 ; +0x274
00000000 ; +0x278
00000000 ; +0x27c
00000000 ; +0x280
00000000 ; +0x284
00000000 ; +0x288
00000000 ; +0x28c
00000000 ; +0x290
00000000 ; +0x294
00000000 ; +0x298
00000000 ; +0x29c
00000000 ; +0x2a0
00000000 ; +0x2a4
00000000 ; +0x2a8
00000000 ; +0x2ac
00000000 ; +0x2b0
00000000 ; +0x2b4
00000000 ; +0x2b8
00000000 ; +0x2bc
00000000 ; +0x2c0
00000000 ; +0x2c4
00000000 ; +0x2c8
00000000 ; +0x2cc
00000000 ; +0x2d0
00000000 ; +0x2d4
00000000 ; +0x2d8
00000000 ; +0x2dc
00000000 ; +0x2e0
00000000 ; +0x2e4
00000000 ; +0x2e8
00000000 ; +0x2ec
00000000 ; +0x2f0
00000000 ; +0x2f4
00000000 ; +0x2f8
00000000 ; +0x2fc
00000000 ; +0x300
00000000 ; +0x304
00000000 ; +0x308
00000000 ; +0x30c
00000000 ; +0x310
00000000 ; +0x314
00000000 ; +0x318
00000000 ; +0x31c
00000000 ; +0x320
00000000 ; +0x324
00000000 ; +0x328
00000000 ; +0x32c
00000000 ; +0x330
00000000 ; +0x334
00000000 ; +0x338
00000000 ; +0x33c
00000000 ; +0x340
00000000 ; +0x344
00000000 ; +0x348
00000000 ; +0x34c
00000000 ; +0x350
00000000 ; +0x354
00000000 ; +0x358
00000000 ; +0x35c
00000000 ; +0x360
00000000 ; +0x364
00000000 ; +0x368
00000000 ; +0x36c
00000000 ; +0x370
00000000 ; +0x374
00000000 ; +0x378
00000000 ; +0x37c
00000000 ; +0x380
00000000 ; +0x384
00000000 ; +0x388
00000000 ; +0x38c
00000000 ; +0x390
00000000 ; +0x394
00000000 ; +0x398
00000000 ; +0x39c
00000000 ; +0x3a0
00000000 ; +0x3a4
00000000 ; +0x3a8
00000000 ; +0x3ac
00000000 ; +0x3b0
00000000 ; +0x3b4
00000000 ; +0x3b8
00000000 ; +0x3bc
00000000 ; +0x3c0
00000000 ; +0x3c4
00000000 ; +0x3c8
00000000 ; +0x3cc
00000000 ; +0x3d0
00000000 ; +0x3d4
00000000 ; +0x3d8
00000000 ; +0x3dc
00000000 ; +0x3e0
00000000 ; +0x3e4
00000000 ; +0x3e8
00000000 ; +0x3ec
00000000 ; +0x3f0
00000000 ; +0x3f4
00000000 ; +0x3f8
00000000 ; +0x3fc

View file

@ -1,94 +0,0 @@
# Code generated by Visual Studio kit, DO NOT EDIT.
cmake_minimum_required(VERSION 3.28)
project(hyperdbg C CXX)
set(CMAKE_CXX_STANDARD 23)
enable_language(ASM_MASM)
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
if(LINUX)
message(STATUS "Building on Linux")
elseif(WIN32)
message(STATUS "Building on Windows")
find_package(WDK REQUIRED)
include_directories(
"dependencies/zydis/include"
"dependencies/zydis/src"
"dependencies/zydis/dependencies/zycore/include"
)
file(GLOB ZydisSourceFiles "dependencies/zydis/src/*.c")
file(GLOB ZycoreSourceFiles "dependencies/zydis/dependencies/zycore/*.c")
set(SourceFiles
${ZydisSourceFiles}
${ZycoreSourceFiles}
# examples/ZydisWinKernel.c
)
add_definitions(
-DZYAN_NO_LIBC
-DZYDIS_NO_LIBC
-DZYCORE_STATIC_BUILD
-DZYDIS_STATIC_BUILD
)
wdk_add_library(zydisKernel
KMDF 1.15
${SourceFiles}
)
link_directories(libraries/kdserial/x64)
add_subdirectory(kdserial)
target_link_libraries(kdserial kdserialtransport kdhv kdtelemetry)
add_subdirectory(hyperlog)
link_directories(libraries/zydis/kernel)
add_subdirectory(hyperhv)
target_link_libraries(hyperhv Zycore Zydis)
add_subdirectory(hyperkd)
target_link_libraries(hyperkd hyperlog hyperhv kdserial)
endif()
#add_subdirectory(dependencies/pdbex/Source)
#add_subdirectory(symbol-parser)
#target_link_libraries(symbol-parser pdbex)
#target_link_libraries(script-engine symbol-parser)
#add_subdirectory(hyperdbg-test)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}")
#add_subdirectory(symbol-parser)
#target_link_libraries(symbol-parser pdbex)
#add_subdirectory(script-engine)
#target_link_libraries(script-engine symbol-parser)
add_subdirectory(script-engine)
link_directories(libraries/zydis/user libraries/keystone/release-lib)
add_subdirectory(libhyperdbg)
find_package(Threads REQUIRED)
target_link_libraries(libhyperdbg Zycore Zydis script-engine keystone Threads::Threads)
add_subdirectory(hyperdbg-cli)
target_link_libraries(hyperdbg-cli libhyperdbg)
#set(save_src_dir ${CMAKE_CURRENT_SOURCE_DIR}/examples)
#execute_process( COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR}/../examples ${save_src_dir})
#
#add_subdirectory(examples/kernel/hyperdbg_driver)
#target_link_libraries(hyperdbg_driver hyperlog hyperhv)
#
#
#add_subdirectory(examples/user/hyperdbg_app)
#target_link_libraries(hyperdbg_app libhyperdbg)

Some files were not shown because too many files have changed in this diff Show more