@@ -572,6 +572,8 @@ struct LibertyFrontend : public Frontend {
572572 for (auto &attr : attributes)
573573 module ->attributes [attr] = 1 ;
574574
575+ bool simple_comb_cell = true , has_outputs = false ;
576+
575577 for (auto node : cell->children )
576578 {
577579 if (node->id == " pin" && node->args .size () == 1 ) {
@@ -613,6 +615,8 @@ struct LibertyFrontend : public Frontend {
613615 if (!dir || (dir->value != " input" && dir->value != " output" && dir->value != " inout" && dir->value != " internal" ))
614616 log_error (" Missing or invalid direction for bus %s on cell %s.\n " , node->args .at (0 ).c_str (), log_id (module ->name ));
615617
618+ simple_comb_cell = false ;
619+
616620 if (dir->value == " internal" )
617621 continue ;
618622
@@ -660,6 +664,9 @@ struct LibertyFrontend : public Frontend {
660664 {
661665 const LibertyAst *dir = node->find (" direction" );
662666
667+ if (dir->value == " internal" || dir->value == " inout" )
668+ simple_comb_cell = false ;
669+
663670 if (flag_lib && dir->value == " internal" )
664671 continue ;
665672
@@ -680,8 +687,10 @@ struct LibertyFrontend : public Frontend {
680687 continue ;
681688 }
682689
683- if (dir && dir->value == " output" )
690+ if (dir && dir->value == " output" ) {
691+ has_outputs = true ;
684692 wire->port_output = true ;
693+ }
685694
686695 if (flag_lib)
687696 continue ;
@@ -699,36 +708,35 @@ struct LibertyFrontend : public Frontend {
699708 goto skip_cell;
700709 }
701710 }
711+ simple_comb_cell = false ;
702712 } else {
703713 RTLIL::SigSpec out_sig = parse_func_expr (module , func->value .c_str ());
704714 const LibertyAst *three_state = node->find (" three_state" );
705715 if (three_state) {
706716 out_sig = create_tristate (module , out_sig, three_state->value .c_str ());
717+ simple_comb_cell = false ;
707718 }
708719 module ->connect (RTLIL::SigSig (wire, out_sig));
709720 }
721+ }
710722
711- if (flag_unit_delay) {
712- pool<Wire *> done;
713-
714- for (auto timing : node->children )
715- if (timing->id == " timing" && timing->args .empty ()) {
716- auto type = timing->find (" timing_type" );
717- auto related_pin = timing->find (" related_pin" );
718- if (!type || type->value != " combinational" || !related_pin)
719- continue ;
720-
721- Wire *related = module ->wire (RTLIL::escape_id (related_pin->value ));
722- if (!related)
723- log_error (" Failed to find related pin %s for timing of pin %s on %s\n " ,
724- related_pin->value .c_str (), log_id (wire), log_id (module ));
723+ if (node->id == " ff" || node->id == " ff_bank" ||
724+ node->id == " latch" || node->id == " latch_bank" ||
725+ node->id == " statetable" )
726+ simple_comb_cell = false ;
727+ }
725728
726- if (done. count (related))
727- continue ;
729+ if (simple_comb_cell && has_outputs) {
730+ module -> set_bool_attribute (ID::abc9_box) ;
728731
732+ if (flag_unit_delay) {
733+ for (auto wi : module ->wires ())
734+ if (wi->port_input ) {
735+ for (auto wo : module ->wires ())
736+ if (wo->port_output ) {
729737 RTLIL::Cell *spec = module ->addCell (NEW_ID, ID ($specify2));
730- spec->setParam (ID::SRC_WIDTH, 1 );
731- spec->setParam (ID::DST_WIDTH, 1 );
738+ spec->setParam (ID::SRC_WIDTH, wi-> width );
739+ spec->setParam (ID::DST_WIDTH, wo-> width );
732740 spec->setParam (ID::T_FALL_MAX, 1000 );
733741 spec->setParam (ID::T_FALL_TYP, 1000 );
734742 spec->setParam (ID::T_FALL_MIN, 1000 );
@@ -737,11 +745,10 @@ struct LibertyFrontend : public Frontend {
737745 spec->setParam (ID::T_RISE_MIN, 1000 );
738746 spec->setParam (ID::SRC_DST_POL, false );
739747 spec->setParam (ID::SRC_DST_PEN, false );
740- spec->setParam (ID::FULL, false );
748+ spec->setParam (ID::FULL, true );
741749 spec->setPort (ID::EN, Const (1 , 1 ));
742- spec->setPort (ID::SRC, related);
743- spec->setPort (ID::DST, wire);
744- done.insert (related);
750+ spec->setPort (ID::SRC, wi);
751+ spec->setPort (ID::DST, wo);
745752 }
746753 }
747754 }
0 commit comments