From 8ff6e915b71f404978b01d92bac83e7d5a9822e8 Mon Sep 17 00:00:00 2001 From: Yuan Qin Date: Mon, 29 Jun 2026 08:20:59 +0200 Subject: [PATCH 1/3] update --- data/rtl-config-vhdl.json | 10 ++ .../Dialect/Handshake/HandshakeOps.td | 4 - .../HandshakeToHW/HandshakeToHW.cpp | 13 ++ lib/Support/RTL/RTL.cpp | 6 +- .../vhdl/generators/handshake/init.py | 157 ++++++++++++++++++ .../vhdl/vhdl-unit-generator.py | 1 + 6 files changed, 185 insertions(+), 6 deletions(-) create mode 100644 tools/unit-generators/vhdl/generators/handshake/init.py diff --git a/data/rtl-config-vhdl.json b/data/rtl-config-vhdl.json index 3d278943c8..165324dcd2 100644 --- a/data/rtl-config-vhdl.json +++ b/data/rtl-config-vhdl.json @@ -458,6 +458,16 @@ "name": "handshake.shrsi", "generator": "python $DYNAMATIC/tools/unit-generators/vhdl/vhdl-unit-generator.py -n $MODULE_NAME -o $OUTPUT_DIR/$MODULE_NAME.vhd -t shrsi -p bitwidth=$BITWIDTH extra_signals=$EXTRA_SIGNALS" }, + { + "name": "handshake.init", + "parameters": [ + { + "name": "INITIAL_VALUE", + "type": "unsigned" + } + ], + "generator": "python $DYNAMATIC/tools/unit-generators/vhdl/vhdl-unit-generator.py -n $MODULE_NAME -o $OUTPUT_DIR/$MODULE_NAME.vhd -t init -p bitwidth=$BITWIDTH extra_signals=$EXTRA_SIGNALS initial_value=$INITIAL_VALUE" + }, { "name": "handshake.shrui", "generator": "python $DYNAMATIC/tools/unit-generators/vhdl/vhdl-unit-generator.py -n $MODULE_NAME -o $OUTPUT_DIR/$MODULE_NAME.vhd -t shrui -p bitwidth=$BITWIDTH extra_signals=$EXTRA_SIGNALS" diff --git a/include/dynamatic/Dialect/Handshake/HandshakeOps.td b/include/dynamatic/Dialect/Handshake/HandshakeOps.td index d39529a5d3..f957bf1fba 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeOps.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeOps.td @@ -341,10 +341,6 @@ def InitOp : Handshake_Op<"init", [ let arguments = (ins HandshakeType:$operand); let results = (outs HandshakeType:$result); - let extraClassDeclaration = [{ - static constexpr ::llvm::StringLiteral INIT_TOKEN_ATTR_NAME = "INIT_TOKEN", - TIMING_ATTR_NAME = "TIMING"; - }]; let assemblyFormat = [{ $operand attr-dict `:` custom(type($operand)) diff --git a/lib/Conversion/HandshakeToHW/HandshakeToHW.cpp b/lib/Conversion/HandshakeToHW/HandshakeToHW.cpp index 10ea0d80ad..2bab1959af 100644 --- a/lib/Conversion/HandshakeToHW/HandshakeToHW.cpp +++ b/lib/Conversion/HandshakeToHW/HandshakeToHW.cpp @@ -768,6 +768,18 @@ ModuleDiscriminator::ModuleDiscriminator(Operation *op) { addUnsigned("DATA_WIDTH", resType.getElementTypeBitWidth()); addUnsigned("SIZE", resType.getNumElements()); }) + .Case([&](handshake::InitOp initOp) { + auto paramsAttr = + initOp->getAttrOfType("hw.parameters"); + if (paramsAttr) { + auto initTokenAttr = + paramsAttr.get("INIT_TOKEN").dyn_cast_or_null(); + int initialValue = + (initTokenAttr && initTokenAttr.getValue()) ? 1 : 0; + addUnsigned("INITIAL_VALUE", initialValue); + } else + addUnsigned("INITIAL_VALUE", 0); + }) .Default([&](auto) { op->emitError() << "This operation cannot be lowered to RTL " "due to a lack of an RTL implementation for it."; @@ -2181,6 +2193,7 @@ class HandshakeToHWPass ConvertToHWInstance, ConvertToHWInstance, ConvertToHWInstance, + ConvertToHWInstance, ConvertToHWInstance, ConvertToHWInstance, ConvertToHWInstance, diff --git a/lib/Support/RTL/RTL.cpp b/lib/Support/RTL/RTL.cpp index 47a4ae33bf..7b8d80d219 100644 --- a/lib/Support/RTL/RTL.cpp +++ b/lib/Support/RTL/RTL.cpp @@ -337,7 +337,8 @@ LogicalResult RTLMatch::registerBitwidthParameter(hw::HWModuleExternOp &modOp, handshakeOp == "handshake.spec_commit" || handshakeOp == "handshake.spec_save_commit" || handshakeOp == "handshake.sharing_wrapper" || - handshakeOp == "handshake.non_spec" + handshakeOp == "handshake.non_spec" || + handshakeOp == "handshake.init" // clang-format on ) { // Default @@ -493,7 +494,8 @@ RTLMatch::registerExtraSignalParameters(hw::HWModuleExternOp &modOp, handshakeOp == "handshake.load" || handshakeOp == "handshake.store" || handshakeOp == "handshake.spec_commit" || - handshakeOp == "handshake.speculating_branch" + handshakeOp == "handshake.speculating_branch" || + handshakeOp == "handshake.init" // clang-format on ) { diff --git a/tools/unit-generators/vhdl/generators/handshake/init.py b/tools/unit-generators/vhdl/generators/handshake/init.py new file mode 100644 index 0000000000..256c2e988c --- /dev/null +++ b/tools/unit-generators/vhdl/generators/handshake/init.py @@ -0,0 +1,157 @@ +from generators.support.signal_manager import generate_concat_signal_manager +from generators.support.signal_manager.utils.concat import get_concat_extra_signals_bitwidth + + +def generate_init(name, params): + bitwidth = params["bitwidth"] + extra_signals = params.get("extra_signals", None) + # The initial value to use for the buffer + initial_value = params.get("initial_value", 0) + + if extra_signals: + return _generate_init_signal_manager(name, bitwidth, extra_signals, initial_value) + elif bitwidth == 0: + return _generate_init_dataless(name) + else: + return _generate_init(name, bitwidth, initial_value) + + +def _generate_init_dataless(name): + + entity = f""" +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +-- Entity of init_dataless +entity {name} is + port ( + clk, rst : in std_logic; + -- input channel + ins_valid : in std_logic; + ins_ready : out std_logic; + -- output channel + outs_valid : out std_logic; + outs_ready : in std_logic + ); +end entity; +""" + + architecture = f""" +-- Architecture of init_dataless +architecture arch of {name} is + signal fullReg, outputValid : std_logic; +begin + outputValid <= ins_valid or fullReg; + + process (clk) is + begin + if (rising_edge(clk)) then + if (rst = '1') then + fullReg <= '1'; + else + fullReg <= outputValid and not outs_ready; + end if; + end if; + end process; + + ins_ready <= not fullReg; + outs_valid <= outputValid; +end architecture; +""" + + return entity + architecture + + +def _generate_init(name, bitwidth, initial_value): + init_dataless_name = f"{name}_dataless" + + dependencies = _generate_init_dataless( + init_dataless_name) + + dataReg_init = f"'{initial_value}'" + + entity = f""" +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +-- Entity of init +entity {name} is + port ( + clk, rst : in std_logic; + -- input channel + ins : in std_logic_vector({bitwidth} - 1 downto 0); + ins_valid : in std_logic; + ins_ready : out std_logic; + -- output channel + outs : out std_logic_vector({bitwidth} - 1 downto 0); + outs_valid : out std_logic; + outs_ready : in std_logic + ); +end entity; +""" + + architecture = f""" +-- Architecture of init +architecture arch of {name} is + signal regEnable, regNotFull : std_logic; + signal dataReg : std_logic_vector({bitwidth} - 1 downto 0); +begin + regEnable <= regNotFull and ins_valid and not outs_ready; + + control : entity work.{init_dataless_name} + port map( + clk => clk, + rst => rst, + ins_valid => ins_valid, + ins_ready => regNotFull, + outs_valid => outs_valid, + outs_ready => outs_ready + ); + + process (clk) is + begin + if (rising_edge(clk)) then + if (rst = '1') then + dataReg <= (others => {dataReg_init}); + elsif (regEnable) then + dataReg <= ins; + end if; + end if; + end process; + + process (regNotFull, dataReg, ins) is + begin + if (regNotFull) then + outs <= ins; + else + outs <= dataReg; + end if; + end process; + + ins_ready <= regNotFull; + +end architecture; +""" + + return dependencies + entity + architecture + + +def _generate_init_signal_manager(name, bitwidth, extra_signals, initial_value): + extra_signals_bitwidth = get_concat_extra_signals_bitwidth(extra_signals) + return generate_concat_signal_manager( + name, + [{ + "name": "ins", + "bitwidth": bitwidth, + "extra_signals": extra_signals + }], + [{ + "name": "outs", + "bitwidth": bitwidth, + "extra_signals": extra_signals + }], + extra_signals, + lambda name: _generate_init(name, bitwidth + extra_signals_bitwidth, initial_value)) + \ No newline at end of file diff --git a/tools/unit-generators/vhdl/vhdl-unit-generator.py b/tools/unit-generators/vhdl/vhdl-unit-generator.py index 0d1ee570f0..a7ad974e75 100644 --- a/tools/unit-generators/vhdl/vhdl-unit-generator.py +++ b/tools/unit-generators/vhdl/vhdl-unit-generator.py @@ -136,5 +136,6 @@ def main(generators): generators.add("handshake", "remsi") generators.add("handshake", "ram") generators.add("handshake", "sharing_wrapper") + generators.add("handshake", "init") main(generators) From 1746080593792554a750b06315d098b230288674 Mon Sep 17 00:00:00 2001 From: Yuan Qin Date: Mon, 29 Jun 2026 08:43:22 +0200 Subject: [PATCH 2/3] update --- lib/Conversion/HandshakeToHW/HandshakeToHW.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Conversion/HandshakeToHW/HandshakeToHW.cpp b/lib/Conversion/HandshakeToHW/HandshakeToHW.cpp index 2bab1959af..fa0dbde914 100644 --- a/lib/Conversion/HandshakeToHW/HandshakeToHW.cpp +++ b/lib/Conversion/HandshakeToHW/HandshakeToHW.cpp @@ -2193,7 +2193,7 @@ class HandshakeToHWPass ConvertToHWInstance, ConvertToHWInstance, ConvertToHWInstance, - ConvertToHWInstance, + ConvertToHWInstance, ConvertToHWInstance, ConvertToHWInstance, ConvertToHWInstance, From 477b0a197b2ca065dfef4aa5c36729a8bdf91723 Mon Sep 17 00:00:00 2001 From: Yuan Qin Date: Mon, 29 Jun 2026 08:45:08 +0200 Subject: [PATCH 3/3] update --- data/rtl-config-vhdl.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/rtl-config-vhdl.json b/data/rtl-config-vhdl.json index 165324dcd2..69d5fca62a 100644 --- a/data/rtl-config-vhdl.json +++ b/data/rtl-config-vhdl.json @@ -460,7 +460,7 @@ }, { "name": "handshake.init", - "parameters": [ + "parameters": [ { "name": "INITIAL_VALUE", "type": "unsigned"