Skip to content
This repository has been archived by the owner on May 28, 2024. It is now read-only.

Commit

Permalink
update README.md
Browse files Browse the repository at this point in the history
  • Loading branch information
SinaKarvandi committed Apr 16, 2024
1 parent b74f605 commit 0524080
Show file tree
Hide file tree
Showing 5 changed files with 195 additions and 26 deletions.
76 changes: 58 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,38 +2,78 @@
<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://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
**hwdbg** is a chip-level debugger written in chisel. (This is a work in progress and not yet ready for testing!).

## Test
**hwdbg** is a chip-level debugger designed for black-box chip fuzzing and reverse engineering. It is written in Chisel and Verilog. (⚠️ This project is a work in progress and is not yet ready for testing.)

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

You should now have a working Chisel3 project.
For generating SystemVerilog files, you need to install [Chisel](https://www.chisel-lang.org/docs/installation). Once installed, use the following commands:

You can run the included test with:
```sh
sbt test
$ sbt run
```

Alternatively, if you use Mill:
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
mill hwdbg.test
```
$ sbt run
[info] welcome to sbt 1.9.7 (Eclipse Adoptium Java 17.0.10)
[info] loading settings for project hwdbg-build-build-build from metals.sbt ...
[info] loading project definition from /home/sina/HyperDbg/hwdbg/project/project/project
[info] loading settings for project hwdbg-build-build from metals.sbt ...
[info] loading project definition from /home/sina/HyperDbg/hwdbg/project/project
[success] Generated .bloop/hwdbg-build-build.json
[success] Total time: 1 s, completed Apr 16, 2024, 1:49:05 PM
[info] loading settings for project hwdbg-build from metals.sbt,plugins.sbt ...
[info] loading project definition from /home/sina/HyperDbg/hwdbg/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/)

You should see a whole bunch of output that ends with something like the following lines
Multiple main classes detected. Select one to run:
[1] hwdbg.Main
[2] hwdbg.MainWithInitializedBRAM

Enter number: 2
[info] running hwdbg.MainWithInitializedBRAM
```
[info] Tests: succeeded 1, failed 0, canceled 0, ignored 0, pending 0
[info] All tests passed.
[success] Total time: 5 s, completed Dec 16, 2020 12:18:44 PM

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
./test_module.sh
```
If you see the above then the test was successful.

### ModelSim
The above command generates a waves file at `./sim/sim_build/DebuggerModuleTestingBRAM.fst` which can be read using [GTKWave](https://gtkwave.sourceforge.net/).

If you want 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/README.md">here</a> for more information.
```sh
cd sim
gtkwave ./sim_build/DebuggerModuleTestingBRAM.fst
```

## Output
### ModelSim

The final generated codes for fuzzy controllers are available in the `generated` directory.
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.

## License
**hwdbg** and all its submodules and repos, unless a license is otherwise specified, are licensed under **GPLv3** LICENSE.

**hwdbg** and all its submodules and repos, unless a license is otherwise specified, are licensed under **GPLv3** LICENSE.
33 changes: 33 additions & 0 deletions src/main/scala/hwdbg/configs/constants.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/** @file
* constants.scala
* @author
* Sina Karvandi ([email protected])
* @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

}
55 changes: 50 additions & 5 deletions src/main/scala/hwdbg/interpreter/interpreter.scala
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import circt.stage.ChiselStage
import hwdbg.configs._
import hwdbg.types._
import hwdbg.utils._
import hwdbg.constants._

object DebuggerPacketInterpreterEnums {
object State extends ChiselEnum {
Expand Down Expand Up @@ -82,6 +83,11 @@ class DebuggerPacketInterpreter(
val regInterpretationDone = RegInit(false.B)
val regFoundValidPacket = RegInit(false.B)

//
// Rising-edge detector for interpretation signal
//
val risingEdgePlInSignal = io.plInSignal & !RegNext(io.plInSignal)

//
// Structure (as register) of the received packet buffer
//
Expand Down Expand Up @@ -117,7 +123,7 @@ class DebuggerPacketInterpreter(
//
// Check whether the interrupt from the PS is received or not
//
when(io.plInSignal === true.B) {
when(risingEdgePlInSignal === true.B) {
state := sInit
}

Expand Down Expand Up @@ -175,6 +181,7 @@ class DebuggerPacketInterpreter(
// Goes to the next section
//
state := sReadTypeOfThePacket

}
is(sReadTypeOfThePacket) {

Expand All @@ -189,9 +196,28 @@ class DebuggerPacketInterpreter(
regRdWrAddr := regReceivedPacketBuffer.Offset.requestedActionOfThePacket.U

//
// Goes to the next section
// Check whether the indicator is valid or not
//
state := sReadRequestedActionOfThePacket
when(
regReceivedPacketBuffer.Indicator === HyperDbgSharedConstants.INDICATOR_OF_HYPERDBG_PACKET.U
) {

//
// Indicator of packet is valid
// (Goes to the next section)
//
state := sReadRequestedActionOfThePacket
}.otherwise {

//
// Type of packet is not valid
// (interpretation was done but not found a valid packet,
// so, go to the idle state)
//
regInterpretationDone := true.B
state := sIdle
}

}
is(sReadRequestedActionOfThePacket) {

Expand All @@ -201,9 +227,28 @@ class DebuggerPacketInterpreter(
regReceivedPacketBuffer.RequestedActionOfThePacket := io.rdData

//
// Reading all values
// Check whether the type of the packet is valid or not
//
state := sDone
when(
regReceivedPacketBuffer.Indicator === HyperDbgSharedConstants.INDICATOR_OF_HYPERDBG_PACKET.U
) {

//
// Type of packet is valid
// All the values are now valid
// (Goes to the next section)
//
state := sDone
}.otherwise {

//
// Type of packet is not valid
// (interpretation was done but not found a valid packet,
// so, go to the idle state)
//
regInterpretationDone := true.B
state := sIdle
}
}
is(sDone) {

Expand Down
10 changes: 8 additions & 2 deletions src/main/scala/hwdbg/libs/mem/init_reg_mem_from_file.scala
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,18 @@ class InitRegMemFromFile(
VecInit(InitRegMemFromFileTools.readmemh(debug, memoryFile, width))
)

//
// 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
//
val actualAddr = io.addr >> 2

when(io.enable) {
val rdwrPort = mem(io.addr)
val rdwrPort = mem(actualAddr)
io.dataOut := rdwrPort

when(io.write) {
mem(io.addr) := io.dataIn
mem(actualAddr) := io.dataIn
}
}.otherwise {
io.dataOut := 0.U
Expand Down
47 changes: 46 additions & 1 deletion src/main/scala/hwdbg/main.scala
Original file line number Diff line number Diff line change
Expand Up @@ -94,10 +94,55 @@ class DebuggerMain(
io.rdData
)

//
// Assign to the output (for testing)
//
when(interpretationDone === true.B && foundValidPacket === true.B) {

when(requestedActionOfThePacket === 0x12345678.U) {

io.outputPin(0) := 1.U
io.outputPin(1) := 0.U
io.outputPin(2) := 0.U
io.outputPin(3) := 0.U
}.elsewhen(requestedActionOfThePacket === 0x12345670.U) {

io.outputPin(0) := 1.U
io.outputPin(1) := 1.U
io.outputPin(2) := 0.U
io.outputPin(3) := 0.U
}.elsewhen(requestedActionOfThePacket === 0x12345600.U) {

io.outputPin(0) := 1.U
io.outputPin(1) := 1.U
io.outputPin(2) := 1.U
io.outputPin(3) := 0.U
}.elsewhen(requestedActionOfThePacket === 0x12345000.U) {

io.outputPin(0) := 1.U
io.outputPin(1) := 1.U
io.outputPin(2) := 1.U
io.outputPin(3) := 1.U
}.otherwise {

io.outputPin(0) := 0.U
io.outputPin(1) := 0.U
io.outputPin(2) := 0.U
io.outputPin(3) := 0.U
}
}
.otherwise {

io.outputPin(0) := 0.U
io.outputPin(1) := 0.U
io.outputPin(2) := 0.U
io.outputPin(3) := 0.U
}

//
// Configure the output signals
//
for (i <- 0 until numberOfOutputPins) {
for (i <- 4 until numberOfOutputPins) {
io.outputPin(i) := requestedActionOfThePacket(i)
}

Expand Down

0 comments on commit 0524080

Please sign in to comment.