Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions data/rtl-config-vhdl.json
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,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"
Expand Down
48 changes: 29 additions & 19 deletions experimental/lib/Support/FtdImplementation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -750,15 +750,22 @@ void ftd::addRegenOperandConsumer(PatternRewriter &rewriter,
cstAttr, startValue);
constOp->setAttr(FTD_INIT_MERGE, rewriter.getUnitAttr());

Operation *initOp;
initOp = rewriter.create<handshake::InitOp>(consumerOp->getLoc(),
conditionValue);

initOp->setAttr(FTD_INIT_MERGE, rewriter.getUnitAttr());

// Create the `init` operation
SmallVector<Value> mergeOperands = {constOp.getResult(), conditionValue};
auto initMergeOp = rewriter.create<handshake::MergeOp>(consumerOp->getLoc(),
mergeOperands);
initMergeOp->setAttr(FTD_INIT_MERGE, rewriter.getUnitAttr());
// SmallVector<Value> mergeOperands = {constOp.getResult(), conditionValue};
// auto initMergeOp =
// rewriter.create<handshake::MergeOp>(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<Value> muxOperands = {regeneratedValue, regeneratedValue};
Expand Down Expand Up @@ -1269,28 +1276,31 @@ LogicalResult experimental::ftd::addGsaGates(Region &region,
// 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<Value> mergeOperands;
mergeOperands.push_back(conditionValue);
mergeOperands.push_back(conditionValue);
// SmallVector<Value> mergeOperands;
// mergeOperands.push_back(conditionValue);
// mergeOperands.push_back(conditionValue);

// auto initMergeOp =
// rewriter.create<handshake::MergeOp>(loc, mergeOperands);

auto initMergeOp =
rewriter.create<handshake::MergeOp>(loc, mergeOperands);
Operation *initOp;
initOp = rewriter.create<handshake::InitOp>(loc, conditionValue);

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<handshake::ConstantOp>(
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<handshake::ConstantOp>(
// 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
Expand Down
4 changes: 0 additions & 4 deletions include/dynamatic/Dialect/Handshake/HandshakeOps.td
Original file line number Diff line number Diff line change
Expand Up @@ -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<HandshakeType>(type($operand))
Expand Down
13 changes: 13 additions & 0 deletions lib/Conversion/HandshakeToHW/HandshakeToHW.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -764,6 +764,18 @@ ModuleDiscriminator::ModuleDiscriminator(Operation *op) {
addUnsigned("DATA_WIDTH", resType.getElementTypeBitWidth());
addUnsigned("SIZE", resType.getNumElements());
})
.Case<handshake::InitOp>([&](handshake::InitOp initOp) {
auto paramsAttr =
initOp->getAttrOfType<mlir::DictionaryAttr>("hw.parameters");
if (paramsAttr) {
auto initTokenAttr =
paramsAttr.get("INIT_TOKEN").dyn_cast_or_null<mlir::BoolAttr>();
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.";
Expand Down Expand Up @@ -2142,6 +2154,7 @@ class HandshakeToHWPass
ConvertToHWInstance<handshake::MuxOp>,
ConvertToHWInstance<handshake::JoinOp>,
ConvertToHWInstance<handshake::BlockerOp>,
ConvertToHWInstance<handshake::InitOp>,
ConvertToHWInstance<handshake::SourceOp>,
ConvertToHWInstance<handshake::ConstantOp>,
ConvertToHWInstance<handshake::SinkOp>,
Expand Down
6 changes: 4 additions & 2 deletions lib/Support/RTL/RTL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,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
Expand Down Expand Up @@ -491,7 +492,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

) {
Expand Down
157 changes: 157 additions & 0 deletions tools/unit-generators/vhdl/generators/handshake/init.py
Original file line number Diff line number Diff line change
@@ -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))

1 change: 1 addition & 0 deletions tools/unit-generators/vhdl/vhdl-unit-generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Loading