From 05240805be358cec55e58bfac2322dce0e9f8134 Mon Sep 17 00:00:00 2001
From: Sina Karvandi
Date: Tue, 16 Apr 2024 14:08:57 +0900
Subject: [PATCH] update README.md
---
README.md | 76 ++++++++++++++-----
src/main/scala/hwdbg/configs/constants.scala | 33 ++++++++
.../scala/hwdbg/interpreter/interpreter.scala | 55 ++++++++++++--
.../libs/mem/init_reg_mem_from_file.scala | 10 ++-
src/main/scala/hwdbg/main.scala | 47 +++++++++++-
5 files changed, 195 insertions(+), 26 deletions(-)
create mode 100644 src/main/scala/hwdbg/configs/constants.scala
diff --git a/README.md b/README.md
index b630afe..2672aae 100644
--- a/README.md
+++ b/README.md
@@ -2,38 +2,78 @@
+
+
+
+
+
+
+
## 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 here 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 here 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.
\ No newline at end of file
diff --git a/src/main/scala/hwdbg/configs/constants.scala b/src/main/scala/hwdbg/configs/constants.scala
new file mode 100644
index 0000000..eb8f925
--- /dev/null
+++ b/src/main/scala/hwdbg/configs/constants.scala
@@ -0,0 +1,33 @@
+/** @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
+
+}
diff --git a/src/main/scala/hwdbg/interpreter/interpreter.scala b/src/main/scala/hwdbg/interpreter/interpreter.scala
index 9fe68f3..fd295bb 100644
--- a/src/main/scala/hwdbg/interpreter/interpreter.scala
+++ b/src/main/scala/hwdbg/interpreter/interpreter.scala
@@ -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 {
@@ -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
//
@@ -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
}
@@ -175,6 +181,7 @@ class DebuggerPacketInterpreter(
// Goes to the next section
//
state := sReadTypeOfThePacket
+
}
is(sReadTypeOfThePacket) {
@@ -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) {
@@ -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) {
diff --git a/src/main/scala/hwdbg/libs/mem/init_reg_mem_from_file.scala b/src/main/scala/hwdbg/libs/mem/init_reg_mem_from_file.scala
index 59bcfd2..87e45f6 100644
--- a/src/main/scala/hwdbg/libs/mem/init_reg_mem_from_file.scala
+++ b/src/main/scala/hwdbg/libs/mem/init_reg_mem_from_file.scala
@@ -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
diff --git a/src/main/scala/hwdbg/main.scala b/src/main/scala/hwdbg/main.scala
index dc1b117..14fb288 100644
--- a/src/main/scala/hwdbg/main.scala
+++ b/src/main/scala/hwdbg/main.scala
@@ -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)
}