196 DeviceOp device = getOperation();
197 OpBuilder builder(device.getBody()->getTerminator());
199 SmallVector<HerdOp, 4> herds;
200 SmallVector<Operation *, 4> placeOps;
201 SmallVector<Operation *, 4> routeOps;
202 DenseMap<std::pair<Operation *, Operation *>, std::pair<int, int>>
204 SmallVector<std::pair<std::pair<int, int>, std::pair<int, int>>, 4> routes;
205 DenseMap<std::pair<Operation *, TileID>, SmallVector<Connect, 8>>
208 for (
auto herd : device.getOps<HerdOp>())
209 herds.push_back(herd);
211 for (
auto placeOp : device.getOps<PlaceOp>()) {
212 placeOps.push_back(placeOp);
213 Operation *sourceHerd = placeOp.getSourceHerd().getDefiningOp();
214 Operation *destHerd = placeOp.getDestHerd().getDefiningOp();
215 int distX = placeOp.getDistXValue();
216 int distY = placeOp.getDistYValue();
217 distances[std::make_pair(sourceHerd, destHerd)] =
218 std::make_pair(distX, distY);
223 for (
auto routeOp : device.getOps<RouteOp>()) {
224 routeOps.push_back(routeOp);
227 dyn_cast<SelectOp>(routeOp.getSourceHerds().getDefiningOp());
229 dyn_cast<SelectOp>(routeOp.getDestHerds().getDefiningOp());
230 WireBundle sourceBundle = routeOp.getSourceBundle();
231 WireBundle destBundle = routeOp.getDestBundle();
232 int sourceChannel = routeOp.getSourceChannelValue();
233 int destChannel = routeOp.getDestChannelValue();
236 dyn_cast<HerdOp>(sourceHerds.getStartHerd().getDefiningOp());
238 dyn_cast<IterOp>(sourceHerds.getIterX().getDefiningOp());
240 dyn_cast<IterOp>(sourceHerds.getIterY().getDefiningOp());
243 dyn_cast<HerdOp>(destHerds.getStartHerd().getDefiningOp());
244 IterOp destIterX = dyn_cast<IterOp>(destHerds.getIterX().getDefiningOp());
245 IterOp destIterY = dyn_cast<IterOp>(destHerds.getIterY().getDefiningOp());
247 int sourceStartX = sourceIterX.getStartValue();
248 int sourceEndX = sourceIterX.getEndValue();
249 int sourceStrideX = sourceIterX.getStrideValue();
250 int sourceStartY = sourceIterY.getStartValue();
251 int sourceEndY = sourceIterY.getEndValue();
252 int sourceStrideY = sourceIterY.getStrideValue();
254 int destStartX = destIterX.getStartValue();
255 int destEndX = destIterX.getEndValue();
256 int destStrideX = destIterX.getStrideValue();
257 int destStartY = destIterY.getStartValue();
258 int destEndY = destIterY.getEndValue();
259 int destStrideY = destIterY.getStrideValue();
261 assert(distances.count(std::make_pair(sourceHerd, destHerd)) == 1);
263 auto [distX, distY] = distances[std::make_pair(sourceHerd, destHerd)];
265 for (
int xSrc = sourceStartX; xSrc < sourceEndX; xSrc += sourceStrideX)
266 for (
int ySrc = sourceStartY; ySrc < sourceEndY; ySrc += sourceStrideY)
267 for (
int xDst = destStartX; xDst < destEndX; xDst += destStrideX)
268 for (
int yDst = destStartY; yDst < destEndY; yDst += destStrideY) {
274 if (destIterX == sourceIterX)
276 if (destIterY == sourceIterX)
278 if (destIterX == sourceIterY)
280 if (destIterY == sourceIterY)
283 auto route = std::make_pair(
284 std::make_pair(x0, y0),
285 std::make_pair(distX + x1 - x0, distY + y1 - y0));
286 if (std::find(routes.begin(), routes.end(), route) !=
290 buildRoute(x0, y0, x1 + distX, y1 + distY, sourceBundle,
291 sourceChannel, destBundle, destChannel, sourceHerd,
294 routes.push_back(route);
298 for (
const auto &swboxCfg : switchboxes) {
299 Operation *herdOp = swboxCfg.first.first;
300 int x = swboxCfg.first.second.col;
301 int y = swboxCfg.first.second.row;
302 auto connects = swboxCfg.second;
303 HerdOp herd = dyn_cast<HerdOp>(herdOp);
305 builder.setInsertionPoint(device.getBody()->getTerminator());
308 IterOp::create(builder, builder.getUnknownLoc(), x, x + 1, 1);
310 IterOp::create(builder, builder.getUnknownLoc(), y, y + 1, 1);
311 auto sel = SelectOp::create(builder, builder.getUnknownLoc(), herd, iterx,
313 auto swbox = SwitchboxOp::create(builder, builder.getUnknownLoc(), sel);
314 SwitchboxOp::ensureTerminator(swbox.getConnections(), builder,
315 builder.getUnknownLoc());
316 Block &b = swbox.getConnections().front();
317 builder.setInsertionPoint(b.getTerminator());
319 for (
auto [sourcePort, destPort] : connects) {
320 WireBundle sourceBundle = sourcePort.bundle;
321 int sourceChannel = sourcePort.channel;
322 WireBundle destBundle = destPort.bundle;
323 int destChannel = destPort.channel;
325 ConnectOp::create(builder, builder.getUnknownLoc(), sourceBundle,
326 sourceChannel, destBundle, destChannel);
330 ConversionTarget target(getContext());
332 RewritePatternSet patterns(&getContext());
334 device.getContext());
336 if (failed(applyPartialConversion(device, target, std::move(patterns))))