@@ -229,22 +229,16 @@ static bool parse_pin(const LibertyAst *cell, const LibertyAst *attr, std::strin
229229 return false ;
230230}
231231
232- static void find_cell (const LibertyAst *ast , IdString cell_type, bool clkpol, bool has_reset, bool rstpol, bool rstval, bool has_enable, bool enapol, std::vector<std::string> &dont_use_cells)
232+ static void find_cell (std::vector< const LibertyAst *> cells , IdString cell_type, bool clkpol, bool has_reset, bool rstpol, bool rstval, bool has_enable, bool enapol, std::vector<std::string> &dont_use_cells)
233233{
234234 const LibertyAst *best_cell = nullptr ;
235235 std::map<std::string, char > best_cell_ports;
236236 int best_cell_pins = 0 ;
237237 bool best_cell_noninv = false ;
238238 double best_cell_area = 0 ;
239239
240- if (ast->id != " library" )
241- log_error (" Format error in liberty file.\n " );
242-
243- for (auto cell : ast->children )
240+ for (auto cell : cells)
244241 {
245- if (cell->id != " cell" || cell->args .size () != 1 )
246- continue ;
247-
248242 const LibertyAst *dn = cell->find (" dont_use" );
249243 if (dn != nullptr && dn->value == " true" )
250244 continue ;
@@ -355,7 +349,7 @@ static void find_cell(const LibertyAst *ast, IdString cell_type, bool clkpol, bo
355349 }
356350}
357351
358- static void find_cell_sr (const LibertyAst *ast , IdString cell_type, bool clkpol, bool setpol, bool clrpol, bool has_enable, bool enapol, std::vector<std::string> &dont_use_cells)
352+ static void find_cell_sr (std::vector< const LibertyAst *> cells , IdString cell_type, bool clkpol, bool setpol, bool clrpol, bool has_enable, bool enapol, std::vector<std::string> &dont_use_cells)
359353{
360354 const LibertyAst *best_cell = nullptr ;
361355 std::map<std::string, char > best_cell_ports;
@@ -365,14 +359,8 @@ static void find_cell_sr(const LibertyAst *ast, IdString cell_type, bool clkpol,
365359
366360 log_assert (!enapol && " set/reset cell with enable is unimplemented due to lack of cells for testing" );
367361
368- if (ast->id != " library" )
369- log_error (" Format error in liberty file.\n " );
370-
371- for (auto cell : ast->children )
362+ for (auto cell : cells)
372363 {
373- if (cell->id != " cell" || cell->args .size () != 1 )
374- continue ;
375-
376364 const LibertyAst *dn = cell->find (" dont_use" );
377365 if (dn != nullptr && dn->value == " true" )
378366 continue ;
@@ -561,7 +549,7 @@ struct DfflibmapPass : public Pass {
561549 log (" dfflibmap [-prepare] [-map-only] [-info] [-dont_use <cell_name>] -liberty <file> [selection]\n " );
562550 log (" \n " );
563551 log (" Map internal flip-flop cells to the flip-flop cells in the technology\n " );
564- log (" library specified in the given liberty file .\n " );
552+ log (" library specified in the given liberty files .\n " );
565553 log (" \n " );
566554 log (" This pass may add inverters as needed. Therefore it is recommended to\n " );
567555 log (" first run this pass and then map the logic paths to the target technology.\n " );
@@ -590,20 +578,21 @@ struct DfflibmapPass : public Pass {
590578 log_header (design, " Executing DFFLIBMAP pass (mapping DFF cells to sequential cells from liberty file).\n " );
591579 log_push ();
592580
593- std::string liberty_file;
594581 bool prepare_mode = false ;
595582 bool map_only_mode = false ;
596583 bool info_mode = false ;
597584
585+ std::vector<std::string> liberty_files;
598586 std::vector<std::string> dont_use_cells;
599587
600588 size_t argidx;
601589 for (argidx = 1 ; argidx < args.size (); argidx++)
602590 {
603591 std::string arg = args[argidx];
604592 if (arg == " -liberty" && argidx+1 < args.size ()) {
605- liberty_file = args[++argidx];
593+ std::string liberty_file = args[++argidx];
606594 rewrite_filename (liberty_file);
595+ liberty_files.push_back (liberty_file);
607596 continue ;
608597 }
609598 if (arg == " -prepare" ) {
@@ -636,41 +625,45 @@ struct DfflibmapPass : public Pass {
636625 if (modes > 1 )
637626 log_cmd_error (" Only one of -prepare, -map-only, or -info options should be given!\n " );
638627
639- if (liberty_file .empty ())
628+ if (liberty_files .empty ())
640629 log_cmd_error (" Missing `-liberty liberty_file' option!\n " );
641630
642- std::ifstream f;
643- f.open (liberty_file.c_str ());
644- if (f.fail ())
645- log_cmd_error (" Can't open liberty file `%s': %s\n " , liberty_file.c_str (), strerror (errno));
646- LibertyParser libparser (f);
647- f.close ();
648-
649- find_cell (libparser.ast , ID ($_DFF_N_), false , false , false , false , false , false , dont_use_cells);
650- find_cell (libparser.ast , ID ($_DFF_P_), true , false , false , false , false , false , dont_use_cells);
651-
652- find_cell (libparser.ast , ID ($_DFF_NN0_), false , true , false , false , false , false , dont_use_cells);
653- find_cell (libparser.ast , ID ($_DFF_NN1_), false , true , false , true , false , false , dont_use_cells);
654- find_cell (libparser.ast , ID ($_DFF_NP0_), false , true , true , false , false , false , dont_use_cells);
655- find_cell (libparser.ast , ID ($_DFF_NP1_), false , true , true , true , false , false , dont_use_cells);
656- find_cell (libparser.ast , ID ($_DFF_PN0_), true , true , false , false , false , false , dont_use_cells);
657- find_cell (libparser.ast , ID ($_DFF_PN1_), true , true , false , true , false , false , dont_use_cells);
658- find_cell (libparser.ast , ID ($_DFF_PP0_), true , true , true , false , false , false , dont_use_cells);
659- find_cell (libparser.ast , ID ($_DFF_PP1_), true , true , true , true , false , false , dont_use_cells);
660-
661- find_cell (libparser.ast , ID ($_DFFE_NN_), false , false , false , false , true , false , dont_use_cells);
662- find_cell (libparser.ast , ID ($_DFFE_NP_), false , false , false , false , true , true , dont_use_cells);
663- find_cell (libparser.ast , ID ($_DFFE_PN_), true , false , false , false , true , false , dont_use_cells);
664- find_cell (libparser.ast , ID ($_DFFE_PP_), true , false , false , false , true , true , dont_use_cells);
665-
666- find_cell_sr (libparser.ast , ID ($_DFFSR_NNN_), false , false , false , false , false , dont_use_cells);
667- find_cell_sr (libparser.ast , ID ($_DFFSR_NNP_), false , false , true , false , false , dont_use_cells);
668- find_cell_sr (libparser.ast , ID ($_DFFSR_NPN_), false , true , false , false , false , dont_use_cells);
669- find_cell_sr (libparser.ast , ID ($_DFFSR_NPP_), false , true , true , false , false , dont_use_cells);
670- find_cell_sr (libparser.ast , ID ($_DFFSR_PNN_), true , false , false , false , false , dont_use_cells);
671- find_cell_sr (libparser.ast , ID ($_DFFSR_PNP_), true , false , true , false , false , dont_use_cells);
672- find_cell_sr (libparser.ast , ID ($_DFFSR_PPN_), true , true , false , false , false , dont_use_cells);
673- find_cell_sr (libparser.ast , ID ($_DFFSR_PPP_), true , true , true , false , false , dont_use_cells);
631+ LibertyMergedCells merged;
632+ for (auto path : liberty_files) {
633+ std::ifstream f;
634+ f.open (path.c_str ());
635+ if (f.fail ())
636+ log_cmd_error (" Can't open liberty file `%s': %s\n " , path.c_str (), strerror (errno));
637+ LibertyParser p (f);
638+ merged.merge (p);
639+ f.close ();
640+ }
641+
642+ find_cell (merged.cells , ID ($_DFF_N_), false , false , false , false , false , false , dont_use_cells);
643+ find_cell (merged.cells , ID ($_DFF_P_), true , false , false , false , false , false , dont_use_cells);
644+
645+ find_cell (merged.cells , ID ($_DFF_NN0_), false , true , false , false , false , false , dont_use_cells);
646+ find_cell (merged.cells , ID ($_DFF_NN1_), false , true , false , true , false , false , dont_use_cells);
647+ find_cell (merged.cells , ID ($_DFF_NP0_), false , true , true , false , false , false , dont_use_cells);
648+ find_cell (merged.cells , ID ($_DFF_NP1_), false , true , true , true , false , false , dont_use_cells);
649+ find_cell (merged.cells , ID ($_DFF_PN0_), true , true , false , false , false , false , dont_use_cells);
650+ find_cell (merged.cells , ID ($_DFF_PN1_), true , true , false , true , false , false , dont_use_cells);
651+ find_cell (merged.cells , ID ($_DFF_PP0_), true , true , true , false , false , false , dont_use_cells);
652+ find_cell (merged.cells , ID ($_DFF_PP1_), true , true , true , true , false , false , dont_use_cells);
653+
654+ find_cell (merged.cells , ID ($_DFFE_NN_), false , false , false , false , true , false , dont_use_cells);
655+ find_cell (merged.cells , ID ($_DFFE_NP_), false , false , false , false , true , true , dont_use_cells);
656+ find_cell (merged.cells , ID ($_DFFE_PN_), true , false , false , false , true , false , dont_use_cells);
657+ find_cell (merged.cells , ID ($_DFFE_PP_), true , false , false , false , true , true , dont_use_cells);
658+
659+ find_cell_sr (merged.cells , ID ($_DFFSR_NNN_), false , false , false , false , false , dont_use_cells);
660+ find_cell_sr (merged.cells , ID ($_DFFSR_NNP_), false , false , true , false , false , dont_use_cells);
661+ find_cell_sr (merged.cells , ID ($_DFFSR_NPN_), false , true , false , false , false , dont_use_cells);
662+ find_cell_sr (merged.cells , ID ($_DFFSR_NPP_), false , true , true , false , false , dont_use_cells);
663+ find_cell_sr (merged.cells , ID ($_DFFSR_PNN_), true , false , false , false , false , dont_use_cells);
664+ find_cell_sr (merged.cells , ID ($_DFFSR_PNP_), true , false , true , false , false , dont_use_cells);
665+ find_cell_sr (merged.cells , ID ($_DFFSR_PPN_), true , true , false , false , false , dont_use_cells);
666+ find_cell_sr (merged.cells , ID ($_DFFSR_PPP_), true , true , true , false , false , dont_use_cells);
674667
675668 log (" final dff cell mappings:\n " );
676669 logmap_all ();
0 commit comments