@@ -173,6 +173,22 @@ void RamGen::makeCellByte(Grid& ram_grid,
173173 ram_grid.addCell (std::move (sel_cell), (byte_number * 9 ) + 8 );
174174}
175175
176+ std::unique_ptr<Layout> RamGen::generateTapColumn (const int word_count,
177+ const int tapcell_col)
178+ {
179+ auto tapcell_layout = std::make_unique<Layout>(odb::vertical);
180+ for (int i = 0 ; i <= word_count; ++i) {
181+ auto tapcell_cell = std::make_unique<Cell>();
182+ makeCellInst (tapcell_cell.get (),
183+ " tapcell" ,
184+ fmt::format (" cell{}_{}" , tapcell_col, i),
185+ tapcell_,
186+ {});
187+ tapcell_layout->addCell (std::move (tapcell_cell));
188+ }
189+ return tapcell_layout;
190+ }
191+
176192std::unique_ptr<Cell> RamGen::makeDecoder (
177193 const std::string& prefix,
178194 const int num_word,
@@ -371,7 +387,9 @@ void RamGen::generate(const int bytes_per_word,
371387 const int read_ports,
372388 dbMaster* storage_cell,
373389 dbMaster* tristate_cell,
374- dbMaster* inv_cell)
390+ dbMaster* inv_cell,
391+ dbMaster* tapcell,
392+ int max_tap_dist)
375393{
376394 const int bits_per_word = bytes_per_word * 8 ;
377395 const std::string ram_name
@@ -382,6 +400,7 @@ void RamGen::generate(const int bytes_per_word,
382400 storage_cell_ = storage_cell;
383401 tristate_cell_ = tristate_cell;
384402 inv_cell_ = inv_cell;
403+ tapcell_ = tapcell;
385404 and2_cell_ = nullptr ;
386405 clock_gate_cell_ = nullptr ;
387406 buffer_cell_ = nullptr ;
@@ -503,40 +522,40 @@ void RamGen::generate(const int bytes_per_word,
503522 }
504523
505524 for (int bit = 0 ; bit < 8 ; ++bit) {
506- auto buffer_cell = std::make_unique<Cell>();
507- makeCellInst (buffer_cell .get (),
525+ auto buffer_grid_cell = std::make_unique<Cell>();
526+ makeCellInst (buffer_grid_cell .get (),
508527 " buffer" ,
509528 fmt::format (" in[{}]" , bit),
510529 buffer_cell_,
511530 {{" A" , D_bTerms[bit]->getNet ()}, {" X" , D_nets[bit]}});
512- ram_grid.addCell (std::move (buffer_cell ), bit);
531+ ram_grid.addCell (std::move (buffer_grid_cell ), bit);
513532 }
514533 }
515534
516535 auto cell_inv_layout = std::make_unique<Layout>(odb::vertical);
517536 // check for AND gate, specific case for 2 words
518537 if (num_inputs > 1 ) {
519538 for (int i = num_inputs - 1 ; i >= 0 ; --i) {
520- auto inv_cell = std::make_unique<Cell>();
521- makeCellInst (inv_cell .get (),
539+ auto inv_grid_cell = std::make_unique<Cell>();
540+ makeCellInst (inv_grid_cell .get (),
522541 " decoder" ,
523542 fmt::format (" inv_{}" , i),
524543 inv_cell_,
525544 {{" A" , addr[i]->getNet ()}, {" Y" , inv_addr[i]}});
526- cell_inv_layout->addCell (std::move (inv_cell ));
545+ cell_inv_layout->addCell (std::move (inv_grid_cell ));
527546 for (int filler_count = 0 ; filler_count < num_inputs - 1 ;
528547 ++filler_count) {
529548 cell_inv_layout->addCell (nullptr );
530549 }
531550 }
532551 } else {
533- auto inv_cell = std::make_unique<Cell>();
534- makeCellInst (inv_cell .get (),
552+ auto inv_grid_cell = std::make_unique<Cell>();
553+ makeCellInst (inv_grid_cell .get (),
535554 " decoder" ,
536555 fmt::format (" inv_{}" , 0 ),
537556 inv_cell_,
538557 {{" A" , addr[0 ]->getNet ()}, {" Y" , inv_addr[0 ]}});
539- cell_inv_layout->addCell (std::move (inv_cell ));
558+ cell_inv_layout->addCell (std::move (inv_grid_cell ));
540559 }
541560
542561 ram_grid.addLayout (std::move (cell_inv_layout));
@@ -546,6 +565,38 @@ void RamGen::generate(const int bytes_per_word,
546565 ram_grid.setOrigin (ram_origin);
547566 ram_grid.gridInit ();
548567
568+ if (tapcell_) {
569+ // max tap distance specified is greater than the length of ram
570+ if (ram_grid.getRowWidth () <= max_tap_dist) {
571+ auto tapcell_layout = generateTapColumn (word_count, 0 );
572+ ram_grid.insertLayout (std::move (tapcell_layout), 0 );
573+ } else {
574+ // needed this calculation so first cells have right distance
575+ int nearest_tap
576+ = (max_tap_dist / ram_grid.getWidth ()) * ram_grid.getLayoutWidth (0 );
577+ int tapcell_count = 0 ;
578+ // iterates through each of the columns
579+ for (int col = 0 ; col < ram_grid.numLayouts (); ++col) {
580+ if (nearest_tap + ram_grid.getLayoutWidth (col) >= max_tap_dist) {
581+ // if the nearest_tap is too far, generate tap column
582+ auto tapcell_layout = generateTapColumn (word_count, tapcell_count);
583+ ram_grid.insertLayout (std::move (tapcell_layout), col);
584+ ++col; // col adjustment after insertion
585+ nearest_tap = 0 ;
586+ ++tapcell_count;
587+ }
588+ nearest_tap += ram_grid.getLayoutWidth (col);
589+ }
590+ // check for last column in the grid
591+ if (nearest_tap >= max_tap_dist) {
592+ auto tapcell_layout = generateTapColumn (word_count, tapcell_count);
593+ ram_grid.addLayout (std::move (tapcell_layout));
594+ }
595+ }
596+ }
597+
598+ ram_grid.gridInit ();
599+
549600 auto db_libs = db_->getLibs ().begin ();
550601 auto db_sites = *(db_libs->getSites ().begin ());
551602 auto sites_width = db_sites->getWidth ();
0 commit comments