@@ -371,7 +371,9 @@ void RamGen::generate(const int bytes_per_word,
371371 const int read_ports,
372372 dbMaster* storage_cell,
373373 dbMaster* tristate_cell,
374- dbMaster* inv_cell)
374+ dbMaster* inv_cell,
375+ dbMaster* tapcell,
376+ int max_tap_dist)
375377{
376378 const int bits_per_word = bytes_per_word * 8 ;
377379 const std::string ram_name
@@ -382,10 +384,12 @@ void RamGen::generate(const int bytes_per_word,
382384 storage_cell_ = storage_cell;
383385 tristate_cell_ = tristate_cell;
384386 inv_cell_ = inv_cell;
387+ tapcell_ = tapcell;
385388 and2_cell_ = nullptr ;
386389 clock_gate_cell_ = nullptr ;
387390 buffer_cell_ = nullptr ;
388391 findMasters ();
392+ max_tap_dist *= 10 ;
389393
390394 auto chip = db_->getChip ();
391395 if (!chip) {
@@ -503,40 +507,40 @@ void RamGen::generate(const int bytes_per_word,
503507 }
504508
505509 for (int bit = 0 ; bit < 8 ; ++bit) {
506- auto buffer_cell = std::make_unique<Cell>();
507- makeCellInst (buffer_cell .get (),
510+ auto buffer_grid_cell = std::make_unique<Cell>();
511+ makeCellInst (buffer_grid_cell .get (),
508512 " buffer" ,
509513 fmt::format (" in[{}]" , bit),
510514 buffer_cell_,
511515 {{" A" , D_bTerms[bit]->getNet ()}, {" X" , D_nets[bit]}});
512- ram_grid.addCell (std::move (buffer_cell ), bit);
516+ ram_grid.addCell (std::move (buffer_grid_cell ), bit);
513517 }
514518 }
515519
516520 auto cell_inv_layout = std::make_unique<Layout>(odb::vertical);
517521 // check for AND gate, specific case for 2 words
518522 if (num_inputs > 1 ) {
519523 for (int i = num_inputs - 1 ; i >= 0 ; --i) {
520- auto inv_cell = std::make_unique<Cell>();
521- makeCellInst (inv_cell .get (),
524+ auto inv_grid_cell = std::make_unique<Cell>();
525+ makeCellInst (inv_grid_cell .get (),
522526 " decoder" ,
523527 fmt::format (" inv_{}" , i),
524528 inv_cell_,
525529 {{" A" , addr[i]->getNet ()}, {" Y" , inv_addr[i]}});
526- cell_inv_layout->addCell (std::move (inv_cell ));
530+ cell_inv_layout->addCell (std::move (inv_grid_cell ));
527531 for (int filler_count = 0 ; filler_count < num_inputs - 1 ;
528532 ++filler_count) {
529533 cell_inv_layout->addCell (nullptr );
530534 }
531535 }
532536 } else {
533- auto inv_cell = std::make_unique<Cell>();
534- makeCellInst (inv_cell .get (),
537+ auto inv_grid_cell = std::make_unique<Cell>();
538+ makeCellInst (inv_grid_cell .get (),
535539 " decoder" ,
536540 fmt::format (" inv_{}" , 0 ),
537541 inv_cell_,
538542 {{" A" , addr[0 ]->getNet ()}, {" Y" , inv_addr[0 ]}});
539- cell_inv_layout->addCell (std::move (inv_cell ));
543+ cell_inv_layout->addCell (std::move (inv_grid_cell ));
540544 }
541545
542546 ram_grid.addLayout (std::move (cell_inv_layout));
@@ -546,6 +550,44 @@ void RamGen::generate(const int bytes_per_word,
546550 ram_grid.setOrigin (ram_origin);
547551 ram_grid.gridInit ();
548552
553+ if (tapcell_) {
554+ if (ram_grid.getRowWidth () <= max_tap_dist) {
555+ auto tapcell_layout = std::make_unique<Layout>(odb::vertical);
556+ for (int i = 0 ; i < word_count; ++i) {
557+ auto tapcell_cell = std::make_unique<Cell>();
558+ makeCellInst (tapcell_cell.get (),
559+ " tapcell" ,
560+ fmt::format (" cell_{}" , i),
561+ tapcell_,
562+ {});
563+ tapcell_layout->addCell (std::move (tapcell_cell));
564+ }
565+ ram_grid.insertLayout (std::move (tapcell_layout), 0 );
566+ } else {
567+ int nearest_tap = 0 ;
568+ for (int col = 0 ; col < ram_grid.numLayouts (); ++col) {
569+ if (nearest_tap >= max_tap_dist) {
570+ auto tapcell_layout = std::make_unique<Layout>(odb::vertical);
571+ for (int i = 0 ; i < word_count; ++i) {
572+ auto tapcell_cell = std::make_unique<Cell>();
573+ makeCellInst (tapcell_cell.get (),
574+ " tapcell" ,
575+ fmt::format (" cell{}_{}" , col, i),
576+ tapcell_,
577+ {});
578+ tapcell_layout->addCell (std::move (tapcell_cell));
579+ }
580+ ram_grid.insertLayout (std::move (tapcell_layout), col);
581+ ++col;
582+ nearest_tap = 0 ;
583+ }
584+ nearest_tap += ram_grid.getLayoutWidth (col);
585+ }
586+ }
587+ }
588+
589+ ram_grid.gridInit ();
590+
549591 auto db_libs = db_->getLibs ().begin ();
550592 auto db_sites = *(db_libs->getSites ().begin ());
551593 auto sites_width = db_sites->getWidth ();
0 commit comments