From d4dcf10560dd3fda9f3133cded2a4f77c8899675 Mon Sep 17 00:00:00 2001 From: zeinab Date: Thu, 5 Mar 2026 16:50:15 +0100 Subject: [PATCH 1/6] adding init unit --- data/rtl-config-vhdl.json | 7 ++ .../lib/Support/FtdImplementation.cpp | 79 ++++++++++++++----- .../HandshakeCombineSteeringLogic.cpp | 37 ++++++++- .../Dialect/Handshake/HandshakeOps.td | 4 - .../HandshakeToHW/HandshakeToHW.cpp | 13 +++ lib/Support/RTL/RTL.cpp | 6 +- .../vhdl/vhdl-unit-generator.py | 1 + 7 files changed, 117 insertions(+), 30 deletions(-) diff --git a/data/rtl-config-vhdl.json b/data/rtl-config-vhdl.json index 6d10d8e66b..57e5737354 100644 --- a/data/rtl-config-vhdl.json +++ b/data/rtl-config-vhdl.json @@ -451,6 +451,13 @@ "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/experimental/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 initialized=1 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/experimental/lib/Support/FtdImplementation.cpp b/experimental/lib/Support/FtdImplementation.cpp index 1ac75bd076..56268a0575 100644 --- a/experimental/lib/Support/FtdImplementation.cpp +++ b/experimental/lib/Support/FtdImplementation.cpp @@ -28,6 +28,8 @@ using namespace dynamatic; using namespace dynamatic::experimental; using namespace dynamatic::experimental::boolean; +bool useInit = true; + /// Different types of loop suppression. enum BranchToLoopType { @@ -750,15 +752,27 @@ void ftd::addRegenOperandConsumer(PatternRewriter &rewriter, cstAttr, startValue); constOp->setAttr(FTD_INIT_MERGE, rewriter.getUnitAttr()); + Operation *initOp; + if (useInit) + initOp = rewriter.create(consumerOp->getLoc(), + conditionValue); + else { + SmallVector mergeOperands = {constOp.getResult(), conditionValue}; + initOp = rewriter.create(consumerOp->getLoc(), + mergeOperands); + } + + initOp->setAttr(FTD_INIT_MERGE, rewriter.getUnitAttr()); + // Create the `init` operation - SmallVector mergeOperands = {constOp.getResult(), conditionValue}; - auto initMergeOp = rewriter.create(consumerOp->getLoc(), - mergeOperands); - initMergeOp->setAttr(FTD_INIT_MERGE, rewriter.getUnitAttr()); + // SmallVector mergeOperands = {constOp.getResult(), conditionValue}; + // auto initMergeOp = rewriter.create(consumerOp->getLoc(), + // mergeOperands); + // initMergeOp->setAttr(FTD_INIT_MERGE, rewriter.getUnitAttr()); // The multiplexer is to be fed by the init block, and takes as inputs the // regenerated value and the result itself (to be set after) it was created. - auto selectSignal = initMergeOp.getResult(); + auto selectSignal = initOp.getResult(0); selectSignal.setType(channelifyType(selectSignal.getType())); SmallVector muxOperands = {regeneratedValue, regeneratedValue}; @@ -1269,28 +1283,53 @@ LogicalResult experimental::ftd::addGsaGates(Region ®ion, // The inputs of the merge are the condition value and a `false` // constant driven by the start value of the function. This will // created later on, so we use a dummy value. - SmallVector mergeOperands; - mergeOperands.push_back(conditionValue); - mergeOperands.push_back(conditionValue); - - auto initMergeOp = - rewriter.create(loc, mergeOperands); + // SmallVector mergeOperands; + // mergeOperands.push_back(conditionValue); + // mergeOperands.push_back(conditionValue); + + // auto initMergeOp = + // rewriter.create(loc, mergeOperands); + + Operation *initOp; + if (useInit) + initOp = rewriter.create(loc, conditionValue); + else { + // The inputs of the merge are the condition value and a `false` + // constant driven by the start value of the function. This will + // created later on, so we use a dummy value. + SmallVector mergeOperands; + mergeOperands.push_back(conditionValue); + mergeOperands.push_back(conditionValue); + + initOp = rewriter.create(loc, mergeOperands); + + // Add the activation constant driven by the backedge value, which + // will + // be then updated with the real start value, once available + auto cstType = rewriter.getIntegerType(1); + auto cstAttr = IntegerAttr::get(cstType, 0); + rewriter.setInsertionPointToStart(initOp->getBlock()); + auto constOp = rewriter.create( + initOp->getLoc(), cstAttr, startValue); + constOp->setAttr(FTD_INIT_MERGE, rewriter.getUnitAttr()); + initOp->setOperand(0, constOp.getResult()); + } - initMergeOp->setAttr(FTD_INIT_MERGE, rewriter.getUnitAttr()); + initOp->setAttr(FTD_INIT_MERGE, rewriter.getUnitAttr()); // Replace the new condition value - conditionValue = initMergeOp->getResult(0); + conditionValue = initOp->getResult(0); conditionValue.setType(channelifyType(conditionValue.getType())); // Add the activation constant driven by the backedge value, which will // be then updated with the real start value, once available - auto cstType = rewriter.getIntegerType(1); - auto cstAttr = IntegerAttr::get(cstType, 0); - rewriter.setInsertionPointToStart(initMergeOp->getBlock()); - auto constOp = rewriter.create( - initMergeOp->getLoc(), cstAttr, startValue); - constOp->setAttr(FTD_INIT_MERGE, rewriter.getUnitAttr()); - initMergeOp->setOperand(0, constOp.getResult()); + // auto cstType = rewriter.getIntegerType(1); + // auto cstAttr = IntegerAttr::get(cstType, 0); + // rewriter.setInsertionPointToStart(initMergeOp->getBlock()); + // auto constOp = rewriter.create( + // initMergeOp->getLoc(), cstAttr, startValue); + // constOp->setAttr(FTD_INIT_MERGE, rewriter.getUnitAttr()); + // initMergeOp->setOperand(0, constOp.getResult()); } // When a single input gamma is encountered, a mux is inserted as a diff --git a/experimental/lib/Transforms/HandshakeCombineSteeringLogic.cpp b/experimental/lib/Transforms/HandshakeCombineSteeringLogic.cpp index d8987238c4..6a6182872d 100644 --- a/experimental/lib/Transforms/HandshakeCombineSteeringLogic.cpp +++ b/experimental/lib/Transforms/HandshakeCombineSteeringLogic.cpp @@ -30,10 +30,38 @@ using namespace dynamatic; namespace { + struct CombineInits : public OpRewritePattern { + using OpRewritePattern::OpRewritePattern; + LogicalResult matchAndRewrite(handshake::InitOp init, + PatternRewriter &rewriter) const override { + + if (init->getNumOperands() != 1) + return failure(); + + // If there are other inits fed from the same input + DenseSet redundantInits; + for (auto *user : init->getOperand(0).getUsers()) + if (isa_and_nonnull(user) && user != init) { + handshake::InitOp anotherInit = cast(user); + redundantInits.insert(anotherInit); + } + + if (redundantInits.empty()) + return failure(); + + for (auto redun : redundantInits) { + rewriter.replaceAllUsesWith(redun.getResult(), init.getResult()); + rewriter.eraseOp(redun); + } + + return success(); + } +}; + /// Combine redundant init merges. These merges have one constant input and a /// condition input. If two merges are identical, then one of them can be /// removed -struct CombineInits : public OpRewritePattern { +struct CombineMergeInits : public OpRewritePattern { using OpRewritePattern::OpRewritePattern; LogicalResult matchAndRewrite(handshake::MergeOp mergeOp, PatternRewriter &rewriter) const override { @@ -394,9 +422,10 @@ struct HandshakeCombineSteeringLogicPass config.useTopDownTraversal = true; config.enableRegionSimplification = false; RewritePatternSet patterns(ctx); - patterns.add(ctx); + patterns + .add(ctx); if (failed(applyPatternsAndFoldGreedily(mod, std::move(patterns), config))) return signalPassFailure(); }; diff --git a/include/dynamatic/Dialect/Handshake/HandshakeOps.td b/include/dynamatic/Dialect/Handshake/HandshakeOps.td index d593b00eeb..c3991e077c 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeOps.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeOps.td @@ -299,10 +299,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 f9519792c5..b9144dcc6b 100644 --- a/lib/Conversion/HandshakeToHW/HandshakeToHW.cpp +++ b/lib/Conversion/HandshakeToHW/HandshakeToHW.cpp @@ -756,6 +756,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."; @@ -2133,6 +2145,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 5f01e787dc..301a00974c 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 @@ -492,7 +493,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/vhdl-unit-generator.py b/tools/unit-generators/vhdl/vhdl-unit-generator.py index 21f4088eb1..a7c72dabd3 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 75627465d8b4cd035ca77a258466ba40d9c7f2c5 Mon Sep 17 00:00:00 2001 From: Zeinab Pourgheisari Date: Sat, 7 Mar 2026 13:46:13 +0100 Subject: [PATCH 2/6] tehb --- .../lib/Support/FtdImplementation.cpp | 2 +- .../vhdl/generators/handshake/tehb.py | 158 ++++++++++++++++++ 2 files changed, 159 insertions(+), 1 deletion(-) create mode 100644 tools/unit-generators/vhdl/generators/handshake/tehb.py diff --git a/experimental/lib/Support/FtdImplementation.cpp b/experimental/lib/Support/FtdImplementation.cpp index 56268a0575..ca776ce951 100644 --- a/experimental/lib/Support/FtdImplementation.cpp +++ b/experimental/lib/Support/FtdImplementation.cpp @@ -772,7 +772,7 @@ void ftd::addRegenOperandConsumer(PatternRewriter &rewriter, // The multiplexer is to be fed by the init block, and takes as inputs the // regenerated value and the result itself (to be set after) it was created. - auto selectSignal = initOp.getResult(0); + auto selectSignal = initOp->getResult(0); selectSignal.setType(channelifyType(selectSignal.getType())); SmallVector muxOperands = {regeneratedValue, regeneratedValue}; diff --git a/tools/unit-generators/vhdl/generators/handshake/tehb.py b/tools/unit-generators/vhdl/generators/handshake/tehb.py new file mode 100644 index 0000000000..08dea9e4f2 --- /dev/null +++ b/tools/unit-generators/vhdl/generators/handshake/tehb.py @@ -0,0 +1,158 @@ +from generators.support.signal_manager import generate_signal_manager, get_concat_extra_signals_bitwidth + + +def generate_tehb(name, params): + bitwidth = params["bitwidth"] + extra_signals = params.get("extra_signals", None) + # Flag indicating whether the buffer is initialized when created + initialized = params.get("initialized", 0) + # The initial value to use for the buffer + initial_value = params.get("initial_value", 0) + + if extra_signals: + return _generate_tehb_signal_manager(name, bitwidth, extra_signals, initialized, initial_value) + elif bitwidth == 0: + return _generate_tehb_dataless(name, initialized) + else: + return _generate_tehb(name, bitwidth, initialized, initial_value) + + +def _generate_tehb_dataless(name, initialized): + + entity = f""" +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +-- Entity of tehb_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 tehb_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 <= '{initialized}'; + 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_tehb(name, bitwidth, initialized, initial_value): + tehb_dataless_name = f"{name}_dataless" + + dependencies = _generate_tehb_dataless( + tehb_dataless_name, initialized) + + dataReg_init = f"'{initial_value}'" + + entity = f""" +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +-- Entity of tehb +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 tehb +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.{tehb_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_tehb_signal_manager(name, bitwidth, extra_signals, initialized, initial_value): + extra_signals_bitwidth = get_concat_extra_signals_bitwidth(extra_signals) + return generate_signal_manager(name, { + "type": "concat", + "in_ports": [{ + "name": "ins", + "bitwidth": bitwidth, + "extra_signals": extra_signals + }], + "out_ports": [{ + "name": "outs", + "bitwidth": bitwidth, + "extra_signals": extra_signals + }], + "extra_signals": extra_signals + }, lambda name: _generate_tehb(name, bitwidth + extra_signals_bitwidth, initialized, initial_value)) + \ No newline at end of file From 63a390d24b6ba81b6805fc20490ad6aea032c966 Mon Sep 17 00:00:00 2001 From: Zeinab Pourgheisari Date: Sat, 7 Mar 2026 14:35:51 +0100 Subject: [PATCH 3/6] init.py --- .../generators/handshake/{tehb.py => init.py} | 63 ++++++++++--------- 1 file changed, 33 insertions(+), 30 deletions(-) rename tools/unit-generators/vhdl/generators/handshake/{tehb.py => init.py} (68%) diff --git a/tools/unit-generators/vhdl/generators/handshake/tehb.py b/tools/unit-generators/vhdl/generators/handshake/init.py similarity index 68% rename from tools/unit-generators/vhdl/generators/handshake/tehb.py rename to tools/unit-generators/vhdl/generators/handshake/init.py index 08dea9e4f2..ad268212f5 100644 --- a/tools/unit-generators/vhdl/generators/handshake/tehb.py +++ b/tools/unit-generators/vhdl/generators/handshake/init.py @@ -1,30 +1,33 @@ -from generators.support.signal_manager import generate_signal_manager, get_concat_extra_signals_bitwidth +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_tehb(name, params): +def generate_init(name, params): bitwidth = params["bitwidth"] extra_signals = params.get("extra_signals", None) # Flag indicating whether the buffer is initialized when created initialized = params.get("initialized", 0) + print("hellooooo\n\n") + print(name, initialized) # The initial value to use for the buffer initial_value = params.get("initial_value", 0) if extra_signals: - return _generate_tehb_signal_manager(name, bitwidth, extra_signals, initialized, initial_value) + return _generate_init_signal_manager(name, bitwidth, extra_signals, initialized, initial_value) elif bitwidth == 0: - return _generate_tehb_dataless(name, initialized) + return _generate_init_dataless(name, initialized) else: - return _generate_tehb(name, bitwidth, initialized, initial_value) + return _generate_init(name, bitwidth, initialized, initial_value) -def _generate_tehb_dataless(name, initialized): +def _generate_init_dataless(name, initialized): entity = f""" library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; --- Entity of tehb_dataless +-- Entity of init_dataless entity {name} is port ( clk, rst : in std_logic; @@ -39,7 +42,7 @@ def _generate_tehb_dataless(name, initialized): """ architecture = f""" --- Architecture of tehb_dataless +-- Architecture of init_dataless architecture arch of {name} is signal fullReg, outputValid : std_logic; begin @@ -64,11 +67,11 @@ def _generate_tehb_dataless(name, initialized): return entity + architecture -def _generate_tehb(name, bitwidth, initialized, initial_value): - tehb_dataless_name = f"{name}_dataless" +def _generate_init(name, bitwidth, initialized, initial_value): + init_dataless_name = f"{name}_dataless" - dependencies = _generate_tehb_dataless( - tehb_dataless_name, initialized) + dependencies = _generate_init_dataless( + init_dataless_name, initialized) dataReg_init = f"'{initial_value}'" @@ -77,7 +80,7 @@ def _generate_tehb(name, bitwidth, initialized, initial_value): use ieee.std_logic_1164.all; use ieee.numeric_std.all; --- Entity of tehb +-- Entity of init entity {name} is port ( clk, rst : in std_logic; @@ -94,14 +97,14 @@ def _generate_tehb(name, bitwidth, initialized, initial_value): """ architecture = f""" --- Architecture of tehb +-- 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.{tehb_dataless_name} + control : entity work.{init_dataless_name} port map( clk => clk, rst => rst, @@ -139,20 +142,20 @@ def _generate_tehb(name, bitwidth, initialized, initial_value): return dependencies + entity + architecture -def _generate_tehb_signal_manager(name, bitwidth, extra_signals, initialized, initial_value): +def _generate_init_signal_manager(name, bitwidth, extra_signals, initialized, initial_value): extra_signals_bitwidth = get_concat_extra_signals_bitwidth(extra_signals) - return generate_signal_manager(name, { - "type": "concat", - "in_ports": [{ - "name": "ins", - "bitwidth": bitwidth, - "extra_signals": extra_signals - }], - "out_ports": [{ - "name": "outs", - "bitwidth": bitwidth, - "extra_signals": extra_signals - }], - "extra_signals": extra_signals - }, lambda name: _generate_tehb(name, bitwidth + extra_signals_bitwidth, initialized, initial_value)) + 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, initialized, initial_value)) \ No newline at end of file From b13ded69b6974db4a47bb50cb2f98f7a44e6a23f Mon Sep 17 00:00:00 2001 From: Zeinab Pourgheisari Date: Sat, 7 Mar 2026 14:44:40 +0100 Subject: [PATCH 4/6] examples works --- data/rtl-config-vhdl.json | 2 +- .../vhdl/generators/handshake/init.py | 22 ++++++++----------- 2 files changed, 10 insertions(+), 14 deletions(-) diff --git a/data/rtl-config-vhdl.json b/data/rtl-config-vhdl.json index 57e5737354..f7960c759d 100644 --- a/data/rtl-config-vhdl.json +++ b/data/rtl-config-vhdl.json @@ -456,7 +456,7 @@ "parameters": [ { "name": "INITIAL_VALUE", "type": "unsigned" } ], - "generator": "python $DYNAMATIC/experimental/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 initialized=1 initial_value=$INITIAL_VALUE" + "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", diff --git a/tools/unit-generators/vhdl/generators/handshake/init.py b/tools/unit-generators/vhdl/generators/handshake/init.py index ad268212f5..256c2e988c 100644 --- a/tools/unit-generators/vhdl/generators/handshake/init.py +++ b/tools/unit-generators/vhdl/generators/handshake/init.py @@ -5,22 +5,18 @@ def generate_init(name, params): bitwidth = params["bitwidth"] extra_signals = params.get("extra_signals", None) - # Flag indicating whether the buffer is initialized when created - initialized = params.get("initialized", 0) - print("hellooooo\n\n") - print(name, initialized) # 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, initialized, initial_value) + return _generate_init_signal_manager(name, bitwidth, extra_signals, initial_value) elif bitwidth == 0: - return _generate_init_dataless(name, initialized) + return _generate_init_dataless(name) else: - return _generate_init(name, bitwidth, initialized, initial_value) + return _generate_init(name, bitwidth, initial_value) -def _generate_init_dataless(name, initialized): +def _generate_init_dataless(name): entity = f""" library ieee; @@ -52,7 +48,7 @@ def _generate_init_dataless(name, initialized): begin if (rising_edge(clk)) then if (rst = '1') then - fullReg <= '{initialized}'; + fullReg <= '1'; else fullReg <= outputValid and not outs_ready; end if; @@ -67,11 +63,11 @@ def _generate_init_dataless(name, initialized): return entity + architecture -def _generate_init(name, bitwidth, initialized, initial_value): +def _generate_init(name, bitwidth, initial_value): init_dataless_name = f"{name}_dataless" dependencies = _generate_init_dataless( - init_dataless_name, initialized) + init_dataless_name) dataReg_init = f"'{initial_value}'" @@ -142,7 +138,7 @@ def _generate_init(name, bitwidth, initialized, initial_value): return dependencies + entity + architecture -def _generate_init_signal_manager(name, bitwidth, extra_signals, initialized, initial_value): +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, @@ -157,5 +153,5 @@ def _generate_init_signal_manager(name, bitwidth, extra_signals, initialized, in "extra_signals": extra_signals }], extra_signals, - lambda name: _generate_init(name, bitwidth + extra_signals_bitwidth, initialized, initial_value)) + lambda name: _generate_init(name, bitwidth + extra_signals_bitwidth, initial_value)) \ No newline at end of file From bd10ff774d0d2ffaac69265eb1b562fab6f90808 Mon Sep 17 00:00:00 2001 From: Zeinab Pourgheisari Date: Sat, 7 Mar 2026 15:18:49 +0100 Subject: [PATCH 5/6] clang-format --- data/rtl-config-vhdl.json | 7 +++- .../lib/Support/FtdImplementation.cpp | 39 +++---------------- .../HandshakeCombineSteeringLogic.cpp | 2 +- 3 files changed, 11 insertions(+), 37 deletions(-) diff --git a/data/rtl-config-vhdl.json b/data/rtl-config-vhdl.json index f60ab54cae..74b6fe10b8 100644 --- a/data/rtl-config-vhdl.json +++ b/data/rtl-config-vhdl.json @@ -453,8 +453,11 @@ }, { "name": "handshake.init", - "parameters": [ - { "name": "INITIAL_VALUE", "type": "unsigned" } + "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" }, diff --git a/experimental/lib/Support/FtdImplementation.cpp b/experimental/lib/Support/FtdImplementation.cpp index fc037bfd87..2084010714 100644 --- a/experimental/lib/Support/FtdImplementation.cpp +++ b/experimental/lib/Support/FtdImplementation.cpp @@ -28,8 +28,6 @@ using namespace dynamatic; using namespace dynamatic::experimental; using namespace dynamatic::experimental::boolean; -bool useInit = true; - /// Different types of loop suppression. enum BranchToLoopType { @@ -753,20 +751,15 @@ void ftd::addRegenOperandConsumer(PatternRewriter &rewriter, constOp->setAttr(FTD_INIT_MERGE, rewriter.getUnitAttr()); Operation *initOp; - if (useInit) - initOp = rewriter.create(consumerOp->getLoc(), - conditionValue); - else { - SmallVector mergeOperands = {constOp.getResult(), conditionValue}; - initOp = rewriter.create(consumerOp->getLoc(), - mergeOperands); - } + initOp = rewriter.create(consumerOp->getLoc(), + conditionValue); initOp->setAttr(FTD_INIT_MERGE, rewriter.getUnitAttr()); // Create the `init` operation // SmallVector mergeOperands = {constOp.getResult(), conditionValue}; - // auto initMergeOp = rewriter.create(consumerOp->getLoc(), + // auto initMergeOp = + // rewriter.create(consumerOp->getLoc(), // mergeOperands); // initMergeOp->setAttr(FTD_INIT_MERGE, rewriter.getUnitAttr()); @@ -1291,29 +1284,7 @@ LogicalResult experimental::ftd::addGsaGates(Region ®ion, // rewriter.create(loc, mergeOperands); Operation *initOp; - if (useInit) - initOp = rewriter.create(loc, conditionValue); - else { - // The inputs of the merge are the condition value and a `false` - // constant driven by the start value of the function. This will - // created later on, so we use a dummy value. - SmallVector mergeOperands; - mergeOperands.push_back(conditionValue); - mergeOperands.push_back(conditionValue); - - initOp = rewriter.create(loc, mergeOperands); - - // Add the activation constant driven by the backedge value, which - // will - // be then updated with the real start value, once available - auto cstType = rewriter.getIntegerType(1); - auto cstAttr = IntegerAttr::get(cstType, 0); - rewriter.setInsertionPointToStart(initOp->getBlock()); - auto constOp = rewriter.create( - initOp->getLoc(), cstAttr, startValue); - constOp->setAttr(FTD_INIT_MERGE, rewriter.getUnitAttr()); - initOp->setOperand(0, constOp.getResult()); - } + initOp = rewriter.create(loc, conditionValue); initOp->setAttr(FTD_INIT_MERGE, rewriter.getUnitAttr()); diff --git a/experimental/lib/Transforms/HandshakeCombineSteeringLogic.cpp b/experimental/lib/Transforms/HandshakeCombineSteeringLogic.cpp index 6cec38f90c..d48f2c52bc 100644 --- a/experimental/lib/Transforms/HandshakeCombineSteeringLogic.cpp +++ b/experimental/lib/Transforms/HandshakeCombineSteeringLogic.cpp @@ -39,7 +39,7 @@ using namespace dynamatic; namespace { - struct CombineInits : public OpRewritePattern { +struct CombineInits : public OpRewritePattern { using OpRewritePattern::OpRewritePattern; LogicalResult matchAndRewrite(handshake::InitOp init, PatternRewriter &rewriter) const override { From b76025db8f1db7055d88b6f191acc80354bec3a4 Mon Sep 17 00:00:00 2001 From: Zeinab Pourgheisari Date: Sat, 7 Mar 2026 15:22:24 +0100 Subject: [PATCH 6/6] cleanup --- .../HandshakeCombineSteeringLogic.cpp | 37 ++----------------- 1 file changed, 4 insertions(+), 33 deletions(-) diff --git a/experimental/lib/Transforms/HandshakeCombineSteeringLogic.cpp b/experimental/lib/Transforms/HandshakeCombineSteeringLogic.cpp index d48f2c52bc..36bc9a1e82 100644 --- a/experimental/lib/Transforms/HandshakeCombineSteeringLogic.cpp +++ b/experimental/lib/Transforms/HandshakeCombineSteeringLogic.cpp @@ -39,38 +39,10 @@ using namespace dynamatic; namespace { -struct CombineInits : public OpRewritePattern { - using OpRewritePattern::OpRewritePattern; - LogicalResult matchAndRewrite(handshake::InitOp init, - PatternRewriter &rewriter) const override { - - if (init->getNumOperands() != 1) - return failure(); - - // If there are other inits fed from the same input - DenseSet redundantInits; - for (auto *user : init->getOperand(0).getUsers()) - if (isa_and_nonnull(user) && user != init) { - handshake::InitOp anotherInit = cast(user); - redundantInits.insert(anotherInit); - } - - if (redundantInits.empty()) - return failure(); - - for (auto redun : redundantInits) { - rewriter.replaceAllUsesWith(redun.getResult(), init.getResult()); - rewriter.eraseOp(redun); - } - - return success(); - } -}; - /// Combine redundant init merges. These merges have one constant input and a /// condition input. If two merges are identical, then one of them can be /// removed -struct CombineMergeInits : public OpRewritePattern { +struct CombineInits : public OpRewritePattern { using OpRewritePattern::OpRewritePattern; LogicalResult matchAndRewrite(handshake::MergeOp mergeOp, PatternRewriter &rewriter) const override { @@ -431,10 +403,9 @@ struct HandshakeCombineSteeringLogicPass config.useTopDownTraversal = true; config.enableRegionSimplification = false; RewritePatternSet patterns(ctx); - patterns - .add(ctx); + patterns.add(ctx); if (failed(applyPatternsAndFoldGreedily(mod, std::move(patterns), config))) return signalPassFailure(); };