50 std::optional<PortConnection>
51 getConnectionThroughWire(Operation *op,
Port masterPort)
const {
52 LLVM_DEBUG(llvm::dbgs() <<
"Wire:" << *op <<
" "
53 << stringifyWireBundle(masterPort.bundle) <<
" "
54 << masterPort.channel <<
"\n");
55 for (
auto wireOp : device.getOps<WireOp>()) {
56 if (wireOp.getSource().getDefiningOp() == op &&
57 wireOp.getSourceBundle() == masterPort.bundle) {
58 Operation *other = wireOp.getDest().getDefiningOp();
59 Port otherPort = {wireOp.getDestBundle(), masterPort.channel};
60 LLVM_DEBUG(llvm::dbgs() <<
"Connects To:" << *other <<
" "
61 << stringifyWireBundle(otherPort.bundle) <<
" "
62 << otherPort.channel <<
"\n");
66 if (wireOp.getDest().getDefiningOp() == op &&
67 wireOp.getDestBundle() == masterPort.bundle) {
68 Operation *other = wireOp.getSource().getDefiningOp();
69 Port otherPort = {wireOp.getSourceBundle(), masterPort.channel};
70 LLVM_DEBUG(llvm::dbgs() <<
"Connects To:" << *other <<
" "
71 << stringifyWireBundle(otherPort.bundle) <<
" "
72 << otherPort.channel <<
"\n");
76 LLVM_DEBUG(llvm::dbgs() <<
"*** Missing Wire!\n");
80 std::vector<PortMaskValue>
81 getConnectionsThroughSwitchbox(Region &r,
Port sourcePort)
const {
82 LLVM_DEBUG(llvm::dbgs() <<
"Switchbox:\n");
84 std::vector<PortMaskValue> portSet;
85 for (
auto connectOp : b.getOps<ConnectOp>()) {
86 if (connectOp.sourcePort() == sourcePort) {
88 portSet.push_back({connectOp.destPort(), maskValue});
89 LLVM_DEBUG(llvm::dbgs()
90 <<
"To:" << stringifyWireBundle(connectOp.destPort().bundle)
91 <<
" " << connectOp.destPort().channel <<
"\n");
94 for (
auto connectOp : b.getOps<PacketRulesOp>()) {
95 if (connectOp.sourcePort() == sourcePort) {
96 LLVM_DEBUG(llvm::dbgs()
98 << stringifyWireBundle(connectOp.sourcePort().bundle) <<
" "
99 << sourcePort.channel <<
"\n");
100 for (
auto masterSetOp : b.getOps<MasterSetOp>())
101 for (Value amsel : masterSetOp.getAmsels())
103 connectOp.getRules().front().getOps<PacketRuleOp>()) {
104 if (ruleOp.getAmsel() == amsel) {
105 LLVM_DEBUG(llvm::dbgs()
107 << stringifyWireBundle(masterSetOp.destPort().bundle)
108 <<
" " << masterSetOp.destPort().channel <<
"\n");
109 MaskValue maskValue = {ruleOp.maskInt(), ruleOp.valueInt()};
110 portSet.push_back({masterSetOp.destPort(), maskValue});
118 std::vector<PacketConnection>
119 maskSwitchboxConnections(Operation *switchOp,
120 std::vector<PortMaskValue> nextPortMaskValues,
122 std::vector<PacketConnection> worklist;
123 for (
auto &nextPortMaskValue : nextPortMaskValues) {
124 Port nextPort = nextPortMaskValue.port;
125 MaskValue nextMaskValue = nextPortMaskValue.mv;
126 int maskConflicts = nextMaskValue.
mask & maskValue.
mask;
127 LLVM_DEBUG(llvm::dbgs() <<
"Mask: " << maskValue.
mask <<
" "
128 << maskValue.
value <<
"\n");
129 LLVM_DEBUG(llvm::dbgs() <<
"NextMask: " << nextMaskValue.
mask <<
" "
130 << nextMaskValue.
value <<
"\n");
131 LLVM_DEBUG(llvm::dbgs() << maskConflicts <<
"\n");
133 if ((maskConflicts & nextMaskValue.
value) !=
134 (maskConflicts & maskValue.
value)) {
140 (nextMaskValue.
mask & nextMaskValue.
value)};
141 auto nextConnection = getConnectionThroughWire(switchOp, nextPort);
147 worklist.push_back({*nextConnection, newMaskValue});
159 LLVM_DEBUG(llvm::dbgs()
160 <<
"getConnectedTile(" << stringifyWireBundle(
port.bundle) <<
" "
161 <<
port.channel <<
")");
162 LLVM_DEBUG(tileOp.dump());
165 std::vector<PacketConnection> connectedTiles;
168 std::vector<PacketConnection> worklist;
171 auto t = getConnectionThroughWire(tileOp.getOperation(),
port);
175 return connectedTiles;
176 worklist.push_back({*t, {0, 0}});
178 while (!worklist.empty()) {
183 Operation *other = portConnection.
op;
184 Port otherPort = portConnection.
port;
185 if (isa<FlowEndPoint>(other)) {
187 connectedTiles.push_back(t);
188 }
else if (
auto switchOp = dyn_cast_or_null<SwitchboxOp>(other)) {
189 std::vector<PortMaskValue> nextPortMaskValues =
190 getConnectionsThroughSwitchbox(switchOp.getConnections(),
192 std::vector<PacketConnection> newWorkList =
193 maskSwitchboxConnections(switchOp, nextPortMaskValues, maskValue);
195 worklist.insert(worklist.end(), newWorkList.begin(), newWorkList.end());
196 if (!nextPortMaskValues.empty() && newWorkList.empty()) {
199 LLVM_DEBUG(llvm::dbgs() <<
"No rule matched incoming packet here: ");
200 LLVM_DEBUG(other->dump());
202 }
else if (
auto switchOp = dyn_cast_or_null<ShimMuxOp>(other)) {
203 std::vector<PortMaskValue> nextPortMaskValues =
204 getConnectionsThroughSwitchbox(switchOp.getConnections(),
206 std::vector<PacketConnection> newWorkList =
207 maskSwitchboxConnections(switchOp, nextPortMaskValues, maskValue);
209 worklist.insert(worklist.end(), newWorkList.begin(), newWorkList.end());
210 if (!nextPortMaskValues.empty() && newWorkList.empty()) {
213 LLVM_DEBUG(llvm::dbgs() <<
"No rule matched incoming packet here: ");
214 LLVM_DEBUG(other->dump());
217 LLVM_DEBUG(llvm::dbgs()
218 <<
"*** Connection Terminated at unknown operation: ");
219 LLVM_DEBUG(other->dump());
222 return connectedTiles;