diff --git a/sim/hwdbg/DebuggerModuleTestingBRAM/Makefile b/sim/hwdbg/DebuggerModuleTestingBRAM/Makefile index 86631d9..43614f7 100644 --- a/sim/hwdbg/DebuggerModuleTestingBRAM/Makefile +++ b/sim/hwdbg/DebuggerModuleTestingBRAM/Makefile @@ -12,6 +12,7 @@ VERILOG_SOURCES += $(shell pwd)/../../../generated/InterpreterSendVersion.sv VERILOG_SOURCES += $(shell pwd)/../../../generated/InterpreterSendError.sv VERILOG_SOURCES += $(shell pwd)/../../../generated/InterpreterPortInformation.sv VERILOG_SOURCES += $(shell pwd)/../../../generated/ScriptExecutionEngine.sv +VERILOG_SOURCES += $(shell pwd)/../../../generated/ScriptEngineEval.sv TOPLEVEL = DebuggerModuleTestingBRAM MODULE = test_DebuggerModuleTestingBRAM diff --git a/sim/hwdbg/DebuggerModuleTestingBRAM/test_DebuggerModuleTestingBRAM.py b/sim/hwdbg/DebuggerModuleTestingBRAM/test_DebuggerModuleTestingBRAM.py index cc918cc..c2fa60b 100644 --- a/sim/hwdbg/DebuggerModuleTestingBRAM/test_DebuggerModuleTestingBRAM.py +++ b/sim/hwdbg/DebuggerModuleTestingBRAM/test_DebuggerModuleTestingBRAM.py @@ -231,38 +231,38 @@ async def DebuggerModuleTestingBRAM_test(dut): # # Assert initial output is unknown # - assert LogicArray(dut.io_outputPin_0.value) == LogicArray("Z") - assert LogicArray(dut.io_outputPin_1.value) == LogicArray("Z") - assert LogicArray(dut.io_outputPin_2.value) == LogicArray("Z") - assert LogicArray(dut.io_outputPin_3.value) == LogicArray("Z") - assert LogicArray(dut.io_outputPin_4.value) == LogicArray("Z") - assert LogicArray(dut.io_outputPin_5.value) == LogicArray("Z") - assert LogicArray(dut.io_outputPin_6.value) == LogicArray("Z") - assert LogicArray(dut.io_outputPin_7.value) == LogicArray("Z") - assert LogicArray(dut.io_outputPin_8.value) == LogicArray("Z") - assert LogicArray(dut.io_outputPin_9.value) == LogicArray("Z") - assert LogicArray(dut.io_outputPin_10.value) == LogicArray("Z") - assert LogicArray(dut.io_outputPin_11.value) == LogicArray("Z") - assert LogicArray(dut.io_outputPin_12.value) == LogicArray("Z") - assert LogicArray(dut.io_outputPin_13.value) == LogicArray("Z") - assert LogicArray(dut.io_outputPin_14.value) == LogicArray("Z") - assert LogicArray(dut.io_outputPin_15.value) == LogicArray("Z") - assert LogicArray(dut.io_outputPin_16.value) == LogicArray("Z") - assert LogicArray(dut.io_outputPin_17.value) == LogicArray("Z") - assert LogicArray(dut.io_outputPin_18.value) == LogicArray("Z") - assert LogicArray(dut.io_outputPin_19.value) == LogicArray("Z") - assert LogicArray(dut.io_outputPin_20.value) == LogicArray("Z") - assert LogicArray(dut.io_outputPin_21.value) == LogicArray("Z") - assert LogicArray(dut.io_outputPin_22.value) == LogicArray("Z") - assert LogicArray(dut.io_outputPin_23.value) == LogicArray("Z") - assert LogicArray(dut.io_outputPin_24.value) == LogicArray("Z") - assert LogicArray(dut.io_outputPin_25.value) == LogicArray("Z") - assert LogicArray(dut.io_outputPin_26.value) == LogicArray("Z") - assert LogicArray(dut.io_outputPin_27.value) == LogicArray("Z") - assert LogicArray(dut.io_outputPin_28.value) == LogicArray("Z") - assert LogicArray(dut.io_outputPin_29.value) == LogicArray("Z") - assert LogicArray(dut.io_outputPin_30.value) == LogicArray("Z") - assert LogicArray(dut.io_outputPin_31.value) == LogicArray("Z") + 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 diff --git a/src/main/scala/hwdbg/configs/configs.scala b/src/main/scala/hwdbg/configs/configs.scala index 0744e80..0d643c4 100644 --- a/src/main/scala/hwdbg/configs/configs.scala +++ b/src/main/scala/hwdbg/configs/configs.scala @@ -66,10 +66,6 @@ object DebuggerConfigurations { // val BLOCK_RAM_DATA_WIDTH: Int = 32 - // - // Single stage script symbol size (equal to sizeof(SYMBOL)) - // - val SINGLE_STAGE_SCRIPT_SYMBOL_SIZE: Int = 32 } /** diff --git a/src/main/scala/hwdbg/main.scala b/src/main/scala/hwdbg/main.scala index 8d538b0..bcee7d2 100644 --- a/src/main/scala/hwdbg/main.scala +++ b/src/main/scala/hwdbg/main.scala @@ -53,8 +53,8 @@ class DebuggerMain( // // Input/Output signals // - val inputPin = Input(Vec(numberOfPins, UInt((1.W)))) // input pins - val outputPin = Output(Vec(numberOfPins, UInt((1.W)))) // output pins + val inputPin = Input(Vec(numberOfPins, UInt(1.W))) // input pins + val outputPin = Output(Vec(numberOfPins, UInt(1.W))) // output pins // // Interrupt signals (lines) @@ -213,7 +213,7 @@ object DebuggerMain { ) ) - val outputPin = Wire(Vec(numberOfPins, UInt((1.W)))) + val outputPin = Wire(Vec(numberOfPins, UInt(1.W))) val psOutInterrupt = Wire(Bool()) val rdWrAddr = Wire(UInt(bramAddrWidth.W)) val wrEna = Wire(Bool()) diff --git a/src/main/scala/hwdbg/script/eval.scala b/src/main/scala/hwdbg/script/eval.scala new file mode 100644 index 0000000..2e04a84 --- /dev/null +++ b/src/main/scala/hwdbg/script/eval.scala @@ -0,0 +1,110 @@ +/** + * @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.stage._ + +class ScriptEngineEval( + debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG, + numberOfPins: Int = DebuggerConfigurations.NUMBER_OF_PINS, + maximumNumberOfStages: Int = DebuggerConfigurations.MAXIMUM_NUMBER_OF_STAGES, + portsConfiguration: Map[Int, Int] = DebuggerPorts.PORT_PINS_MAP +) extends Module { + + val io = IO(new Bundle { + + // + // Chip signals + // + val en = Input(Bool()) // chip enable signal + + // + // Evaluation symbol + // + val symbol = Input(new SYMBOL) + val nextStage = Output(UInt(log2Ceil(maximumNumberOfStages).W)) + + // + // Input/Output signals + // + val inputPin = Input(Vec(numberOfPins, UInt(1.W))) // input pins + val outputPin = Output(Vec(numberOfPins, UInt(1.W))) // output pins + }) + + // + // Output pins + // + // val outputPin = Wire(Vec(numberOfPins, UInt(1.W))) + // val nextStage = Wire(UInt(log2Ceil(maximumNumberOfStages).W)) + + // + // Connect the output signals + // + // io.nextStage := nextStage + // io.outputPin := outputPin + io.nextStage := 0.U + io.outputPin := io.inputPin + +} + +object ScriptEngineEval { + + def apply( + debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG, + numberOfPins: Int = DebuggerConfigurations.NUMBER_OF_PINS, + maximumNumberOfStages: Int = DebuggerConfigurations.MAXIMUM_NUMBER_OF_STAGES, + portsConfiguration: Map[Int, Int] = DebuggerPorts.PORT_PINS_MAP + )( + en: Bool, + symbol: SYMBOL, + inputPin: Vec[UInt] + ): (UInt, Vec[UInt]) = { + + val scriptEngineEvalModule = Module( + new ScriptEngineEval( + debug, + numberOfPins, + maximumNumberOfStages, + portsConfiguration + ) + ) + + val outputPin = Wire(Vec(numberOfPins, UInt(1.W))) + val nextStage = Wire(UInt(log2Ceil(maximumNumberOfStages).W)) + + // + // Configure the input signals + // + scriptEngineEvalModule.io.en := en + scriptEngineEvalModule.io.symbol := symbol + scriptEngineEvalModule.io.inputPin := inputPin + + // + // Configure the output signals + // + nextStage := scriptEngineEvalModule.io.nextStage + outputPin := scriptEngineEvalModule.io.outputPin + + // + // Return the output result + // + (nextStage, outputPin) + } +} diff --git a/src/main/scala/hwdbg/script/exec.scala b/src/main/scala/hwdbg/script/exec.scala index 5f051f3..1abdecc 100644 --- a/src/main/scala/hwdbg/script/exec.scala +++ b/src/main/scala/hwdbg/script/exec.scala @@ -40,19 +40,19 @@ class ScriptExecutionEngine( // // Input/Output signals // - val inputPin = Input(Vec(numberOfPins, UInt((1.W)))) // input pins - val outputPin = Output(Vec(numberOfPins, UInt((1.W)))) // output pins + val inputPin = Input(Vec(numberOfPins, UInt(1.W))) // input pins + val outputPin = Output(Vec(numberOfPins, UInt(1.W))) // output pins }) // // Output pins // - val outputPin = Wire(Vec(numberOfPins, UInt((1.W)))) + val outputPin = Wire(Vec(numberOfPins, UInt(1.W))) // // Stage registers // - val stageRegs = Reg(new StageRegisters(debug, numberOfPins, maximumNumberOfStages)) + val stageRegs = Reg(Vec(maximumNumberOfStages, new StageRegisters(debug, numberOfPins, maximumNumberOfStages))) // ----------------------------------------------------------------------- // @@ -66,12 +66,12 @@ class ScriptExecutionEngine( // At the first stage, the input registers should be passed to the // first registers set of the stage registers // - stageRegs.pinValues(i) := io.inputPin.asUInt + stageRegs(i).pinValues := io.inputPin // // Each pin start initially start from 0th target stage // - // stageRegs.targetStage(i) := 0.U + stageRegs(i).targetStage := 0.U } else if (i == (maximumNumberOfStages - 1)) { @@ -79,22 +79,37 @@ class ScriptExecutionEngine( // At the last stage, the state registers should be passed to the output // Note: At this stage script symbol is useless // - for (j <- 0 until numberOfPins) { - outputPin(j) := stageRegs.pinValues(i)(j) - } + outputPin := stageRegs(i).pinValues } else { // - // At the normal (middle) stage, the state registers should be passed to + // Instantiate an eval engine for this stage + // + val ( + nextStage, + outputPin + ) = ScriptEngineEval( + debug, + numberOfPins, + maximumNumberOfStages, + portsConfiguration + )( + io.en, + stageRegs(i).scriptSymbol, + stageRegs(i).pinValues + ) + + // + // At the normal (middle) stage, the result of state registers should be passed to // the next level of stage registers // - stageRegs.pinValues(i + 1) := stageRegs.pinValues(i) + stageRegs(i + 1).pinValues := outputPin // // Pass the target stage symbol number to the next stage // - // stageRegs.targetStage(i + 1) := stageRegs.targetStage(i) // Uncomment + stageRegs(i + 1).targetStage := nextStage } } @@ -133,7 +148,7 @@ object ScriptExecutionEngine { ) ) - val outputPin = Wire(Vec(numberOfPins, UInt((1.W)))) + val outputPin = Wire(Vec(numberOfPins, UInt(1.W))) // // Configure the input signals diff --git a/src/main/scala/hwdbg/types/stage.scala b/src/main/scala/hwdbg/types/stage.scala index f1e316f..1f834e8 100644 --- a/src/main/scala/hwdbg/types/stage.scala +++ b/src/main/scala/hwdbg/types/stage.scala @@ -20,14 +20,36 @@ import chisel3.util.log2Ceil import hwdbg.configs._ +// +// Structure in C: +// +// +// typedef struct SYMBOL { +// long long unsigned Type; +// long long unsigned Len; +// long long unsigned VariableType; +// long long unsigned Value; +// } SYMBOL, * PSYMBOL; +// + +/** + * @brief + * The structure of SYMBOL used in script engine of HyperDbg + */ +class SYMBOL extends Bundle { + val Type = UInt(64.W) // long long unsigned is 64 bits + val Len = UInt(64.W) + val VariableType = UInt(64.W) + val Value = UInt(64.W) +} + class StageRegisters( debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG, numberOfPins: Int = DebuggerConfigurations.NUMBER_OF_PINS, - maximumNumberOfStages: Int = DebuggerConfigurations.MAXIMUM_NUMBER_OF_STAGES, - singleStageScriptSymbolSize: Int = DebuggerConfigurations.SINGLE_STAGE_SCRIPT_SYMBOL_SIZE + maximumNumberOfStages: Int = DebuggerConfigurations.MAXIMUM_NUMBER_OF_STAGES ) extends Bundle { - val pinValues = Vec(maximumNumberOfStages, UInt(numberOfPins.W)) // The value of each pin in each stage (should be passed to the next stage) - val scriptSymbol = UInt(singleStageScriptSymbolSize.W) // Interpreted script symbol for the target stage (should NOT be passed to the next stage) + val pinValues = Vec(numberOfPins, UInt(1.W)) // The value of each pin in each stage (should be passed to the next stage) + val scriptSymbol = new SYMBOL // Interpreted script symbol for the target stage (should NOT be passed to the next stage) val targetStage = UInt( log2Ceil(maximumNumberOfStages).W ) // Target stage that needs to be executed for the current pin values (should be passed to the next stage) diff --git a/src/main/scala/top.scala b/src/main/scala/top.scala index 38f73a4..0a7ef79 100644 --- a/src/main/scala/top.scala +++ b/src/main/scala/top.scala @@ -39,8 +39,8 @@ class DebuggerModule( // // Input/Output signals // - val inputPin = Input(Vec(numberOfPins, UInt((1.W)))) // input pins - val outputPin = Output(Vec(numberOfPins, UInt((1.W)))) // output pins + val inputPin = Input(Vec(numberOfPins, UInt(1.W))) // input pins + val outputPin = Output(Vec(numberOfPins, UInt(1.W))) // output pins // // Interrupt signals (lines) diff --git a/src/main/scala/top_test.scala b/src/main/scala/top_test.scala index 8268d29..d2d9c5d 100644 --- a/src/main/scala/top_test.scala +++ b/src/main/scala/top_test.scala @@ -40,8 +40,8 @@ class DebuggerModuleTestingBRAM( // // Input/Output signals // - val inputPin = Input(Vec(numberOfPins, UInt((1.W)))) // input pins - val outputPin = Output(Vec(numberOfPins, UInt((1.W)))) // output pins + val inputPin = Input(Vec(numberOfPins, UInt(1.W))) // input pins + val outputPin = Output(Vec(numberOfPins, UInt(1.W))) // output pins // // Interrupt signals (lines)