@@ -30,10 +30,13 @@ struct AegisImpl : ViaductAPI {
3030 int K = 4 ;
3131
3232 // Cached IdStrings
33- IdString id_LUT4, id_DFF, id_IOB, id_INBUF, id_OUTBUF;
33+ IdString id_LUT4, id_DFF, id_IOB, id_INBUF, id_OUTBUF, id_JTAG ;
3434 IdString id_CLK, id_D, id_Q, id_F, id_I, id_O, id_PAD, id_EN;
3535 IdString id_INIT, id_PIP, id_LOCAL;
3636
37+ // JTAG wires (global)
38+ WireId jtag_tdi, jtag_tdo, jtag_shift, jtag_update, jtag_capture, jtag_reset;
39+
3740 dict<std::string, std::string> device_args;
3841
3942 // Per-tile wire storage
@@ -61,6 +64,7 @@ struct AegisImpl : ViaductAPI {
6164 id_IOB = ctx->id (" IOB" );
6265 id_INBUF = ctx->id (" INBUF" );
6366 id_OUTBUF = ctx->id (" OUTBUF" );
67+ id_JTAG = ctx->id (" JTAG" );
6468 id_CLK = ctx->id (" CLK" );
6569 id_D = ctx->id (" D" );
6670 id_Q = ctx->id (" Q" );
@@ -168,6 +172,8 @@ struct AegisImpl : ViaductAPI {
168172
169173 bool isBelLocationValid (BelId bel, bool explain_invalid) const override {
170174 Loc l = ctx->getBelLocation (bel);
175+ if (l.x == 0 && l.y == 0 )
176+ return true ; // JTAG BEL
171177 if (is_io (l.x , l.y ))
172178 return true ;
173179 return slice_valid (l.x , l.y , l.z / 2 );
@@ -242,6 +248,20 @@ struct AegisImpl : ViaductAPI {
242248 tw.track_w .push_back (ctx->addWire (h.xy_id (x, y, ctx->idf (" W%d" , t)),
243249 ctx->id (" ROUTING" ), x, y));
244250 }
251+ } else if (x == 0 && y == 0 ) {
252+ // Bottom-left corner: JTAG BEL site
253+ jtag_tdi = ctx->addWire (h.xy_id (x, y, ctx->id (" JTAG_TDI" )),
254+ ctx->id (" JTAG" ), x, y);
255+ jtag_tdo = ctx->addWire (h.xy_id (x, y, ctx->id (" JTAG_TDO" )),
256+ ctx->id (" JTAG" ), x, y);
257+ jtag_shift = ctx->addWire (h.xy_id (x, y, ctx->id (" JTAG_SHIFT" )),
258+ ctx->id (" JTAG" ), x, y);
259+ jtag_update = ctx->addWire (h.xy_id (x, y, ctx->id (" JTAG_UPDATE" )),
260+ ctx->id (" JTAG" ), x, y);
261+ jtag_capture = ctx->addWire (h.xy_id (x, y, ctx->id (" JTAG_CAPTURE" )),
262+ ctx->id (" JTAG" ), x, y);
263+ jtag_reset = ctx->addWire (h.xy_id (x, y, ctx->id (" JTAG_RESET" )),
264+ ctx->id (" JTAG" ), x, y);
245265 } else if (!is_corner (x, y)) {
246266 // IO tile wires
247267 for (int z = 0 ; z < 2 ; z++) {
@@ -273,9 +293,13 @@ struct AegisImpl : ViaductAPI {
273293 for (int y = 0 ; y < H; y++) {
274294 for (int x = 0 ; x < W; x++) {
275295 if (is_io (x, y)) {
276- if (is_corner (x, y))
296+ if (x == 0 && y == 0 ) {
297+ add_jtag_bel (x, y);
298+ } else if (is_corner (x, y)) {
277299 continue ;
278- add_io_bels (x, y);
300+ } else {
301+ add_io_bels (x, y);
302+ }
279303 } else {
280304 add_logic_bels (x, y);
281305 }
@@ -297,6 +321,17 @@ struct AegisImpl : ViaductAPI {
297321 }
298322 }
299323
324+ void add_jtag_bel (int x, int y) {
325+ BelId b = ctx->addBel (h.xy_id (x, y, ctx->id (" JTAG0" )), id_JTAG,
326+ Loc (x, y, 0 ), false , false );
327+ ctx->addBelOutput (b, ctx->id (" tdi" ), jtag_tdi);
328+ ctx->addBelInput (b, ctx->id (" tdo" ), jtag_tdo);
329+ ctx->addBelOutput (b, ctx->id (" shift" ), jtag_shift);
330+ ctx->addBelOutput (b, ctx->id (" update" ), jtag_update);
331+ ctx->addBelOutput (b, ctx->id (" capture" ), jtag_capture);
332+ ctx->addBelOutput (b, ctx->id (" reset" ), jtag_reset);
333+ }
334+
300335 void add_logic_bels (int x, int y) {
301336 auto &tw = tile_wires[y][x];
302337
@@ -332,6 +367,34 @@ struct AegisImpl : ViaductAPI {
332367 add_inter_tile_pips (x, y);
333368 }
334369 }
370+ add_jtag_pips ();
371+ }
372+
373+ void add_jtag_pips () {
374+ // Connect JTAG wires to the adjacent fabric tile (1,1)
375+ if (W <= 2 || H <= 2 )
376+ return ;
377+ auto &tw = tile_wires[1 ][1 ];
378+ Loc loc (0 , 0 , 0 );
379+
380+ // JTAG outputs -> fabric input tracks (so user designs can read them)
381+ for (int t = 0 ; t < T; t++) {
382+ add_pip (loc, jtag_tdi, tw.track_w [t], 0.05 );
383+ add_pip (loc, jtag_shift, tw.track_w [t], 0.05 );
384+ add_pip (loc, jtag_update, tw.track_w [t], 0.05 );
385+ add_pip (loc, jtag_capture, tw.track_w [t], 0.05 );
386+ add_pip (loc, jtag_reset, tw.track_w [t], 0.05 );
387+ }
388+
389+ // Fabric -> JTAG tdo (so user designs can drive TDO)
390+ for (int t = 0 ; t < T; t++) {
391+ add_pip (loc, tw.track_n [t], jtag_tdo, 0.05 );
392+ add_pip (loc, tw.track_e [t], jtag_tdo, 0.05 );
393+ add_pip (loc, tw.track_s [t], jtag_tdo, 0.05 );
394+ add_pip (loc, tw.track_w [t], jtag_tdo, 0.05 );
395+ }
396+ add_pip (loc, tw.lut_out , jtag_tdo, 0.05 );
397+ add_pip (loc, tw.ff_q , jtag_tdo, 0.05 );
335398 }
336399
337400 void add_logic_pips (int x, int y) {
0 commit comments