@@ -5969,28 +5969,85 @@ static void show_sig(const RTLIL::SigSpec &sig)
59695969 }
59705970 }
59715971
5972- void ofab_insert_NS_rules (RTLIL::Module* top_module, RTLIL::Cell* cell,
5973- string portName, string fabPortName, RTLIL::SigSpec& actual)
5972+ // This function may be ok in term of runtime because we expect the vector
5973+ // 'cells_primitives' to have a small size (few tens) so that the global loop
5974+ // is small and there is no much runtime hit.
5975+ //
5976+ bool isPrimitiveOutput (vector<Cell*>& cells_primitives, RTLIL::SigSpec actual) {
5977+
5978+ for (auto cell : cells_primitives) {
5979+
5980+ for (auto &conn : cell->connections ()) {
5981+
5982+ IdString portName = conn.first ;
5983+ RTLIL::SigSpec out = conn.second ;
5984+
5985+ if (!cell->output (portName)) {
5986+ continue ;
5987+ }
5988+
5989+ if (!out.is_chunk ()) { // If this is a concat of sub-actuals ...
5990+
5991+ for (auto it = out.chunks ().rbegin (); it != out.chunks ().rend (); ++it) {
5992+
5993+ RTLIL::SigSpec sub_actual = *it;
5994+
5995+ if (actual == sub_actual) {
5996+ return true ; // yes 'actual' is the output net of a primitive
5997+ }
5998+ }
5999+
6000+ } else { // or it is a simple signal
6001+
6002+ if (actual == out) {
6003+ return true ; // yes 'actual' is the output net of a primitive
6004+ }
6005+ }
6006+ }
6007+ }
6008+
6009+ return false ;
6010+ }
6011+
6012+ void ofab_insert_NS_rules (RTLIL::Module* top_module, vector<RTLIL::Cell*>& cells_primitives,
6013+ RTLIL::Cell* cell, string portName, string fabPortName,
6014+ RTLIL::SigSpec& actual)
59746015 {
59756016
59766017 if (iofab_map == 2 ) {
59776018 log (" - Inserting O_FAB on cell '%s' (%s) on NS input port '%s'\n " , (cell->name ).c_str (),
59786019 (cell->type ).c_str (), portName.c_str ());
59796020 }
59806021
5981- if (!actual.is_chunk ()) {
6022+ if (!actual.is_chunk ()) { // If this is a concat of sub-actuals ...
59826023
59836024 RTLIL::SigSpec new_sig;
59846025 RTLIL::SigSpec new_sigO;
59856026
5986- // This is an append of sub signals
6027+ // This is a concat of sub signals
59876028 //
59886029 for (auto it = actual.chunks ().rbegin (); it != actual.chunks ().rend (); ++it) {
59896030
59906031 RTLIL::SigSpec sub_actual = *it;
59916032
59926033 RTLIL::Wire *wire = sub_actual[0 ].wire ;
59936034
6035+ // Do not create O_FAB if 'sub_actual' net is driven by a primitive
6036+ //
6037+ if (isPrimitiveOutput (cells_primitives, actual)) {
6038+
6039+ log (" Skip O_FAB insertion on net '%s' (Primitive output)\n " , (wire->name ).c_str ());
6040+
6041+ // Build the new append
6042+ //
6043+ new_sigO.append (sub_actual); // do not create any new net, keep the current
6044+ // 'sub_actual' net
6045+
6046+ new_sig = new_sigO;
6047+
6048+ continue ;
6049+ }
6050+
59946051 if (fabPortName ==" " ) {
59956052 fabPortName = " ofab" ;
59966053 }
@@ -6019,7 +6076,7 @@ static void show_sig(const RTLIL::SigSpec &sig)
60196076
60206077 new_cell->setPort (ID::O, new_sigO);
60216078
6022- // Build the new append
6079+ // Build the new concat
60236080 //
60246081 new_sigO.append (new_sig);
60256082
@@ -6029,14 +6086,24 @@ static void show_sig(const RTLIL::SigSpec &sig)
60296086
60306087 RTLIL::IdString idPortName = RTLIL::escape_id (portName);
60316088
6089+ // replace the former concat by the new built concat 'new_sig'
6090+ //
60326091 cell->unsetPort (idPortName);
60336092
60346093 cell->setPort (idPortName, new_sig);
60356094
6036- } else {
6095+ } else { // else we are processing a simple 'actual' net
60376096
60386097 RTLIL::Wire *wire = actual[0 ].wire ;
60396098
6099+ // Do not create O_FAB if 'actual' net is driven by a primitive
6100+ //
6101+ if (isPrimitiveOutput (cells_primitives, actual)) {
6102+
6103+ log (" Skip O_FAB insertion on net '%s' (Primitive output)\n " , (wire->name ).c_str ());
6104+ return ;
6105+ }
6106+
60406107 if (fabPortName ==" " ) {
60416108 fabPortName = " ofab" ;
60426109 }
@@ -6175,7 +6242,9 @@ static void show_sig(const RTLIL::SigSpec &sig)
61756242 // by a constant. We are in the Non Shared(NS) case which means that
61766243 // we systematically create a I_FAB or O_FAB.
61776244 //
6178- void insert_iofab_NS_rules (RTLIL::Module* top_module, RTLIL::Cell* cell,
6245+ void insert_iofab_NS_rules (RTLIL::Module* top_module,
6246+ vector<RTLIL::Cell*>& cells_primitives,
6247+ RTLIL::Cell* cell,
61796248 string portName, string fabPortName)
61806249 {
61816250 int found = 0 ;
@@ -6220,7 +6289,7 @@ static void show_sig(const RTLIL::SigSpec &sig)
62206289 //
62216290 if (cell->input (RTLIL::escape_id (portName))) {
62226291
6223- ofab_insert_NS_rules (top_module, cell, portName, fabPortName, actual);
6292+ ofab_insert_NS_rules (top_module, cells_primitives, cell, portName, fabPortName, actual);
62246293
62256294 return ;
62266295 }
@@ -7832,11 +7901,11 @@ void collect_clocks (RTLIL::Module* module,
78327901 log (" Getting the rules ...\n " );
78337902 }
78347903
7835- register_rule (" I_BUF" , " EN" , " f2g_in_en_A " , 0 /* not shared */ , all_rules);
7836- register_rule (" I_BUF_DS" , " EN" , " f2g_in_en_A " , 0 , all_rules);
7904+ register_rule (" I_BUF" , " EN" , " f2g_in_en " , 0 /* not shared */ , all_rules);
7905+ register_rule (" I_BUF_DS" , " EN" , " f2g_in_en " , 0 , all_rules);
78377906
7838- register_rule (" O_BUFT" , " T" , " f2g_tx_oe_A " , 0 , all_rules);
7839- register_rule (" O_BUFT_DS" , " T" , " f2g_tx_oe_A " , 0 , all_rules);
7907+ register_rule (" O_BUFT" , " T" , " f2g_tx_oe " , 0 , all_rules);
7908+ register_rule (" O_BUFT_DS" , " T" , " f2g_tx_oe " , 0 , all_rules);
78407909
78417910#if 0
78427911 // SHARED version
@@ -7864,22 +7933,22 @@ void collect_clocks (RTLIL::Module* module,
78647933 register_rule (" O_DELAY" , " DLY_TAP_VALUE" , " f2g_trx_dly_tap" , 0 , all_rules);
78657934#endif
78667935
7867- register_rule (" I_DDR" , " R" , " f2g_trx_reset_n_A " , 0 , all_rules);
7936+ register_rule (" I_DDR" , " R" , " f2g_trx_reset_n " , 0 , all_rules);
78687937 register_rule (" I_DDR" , " E" , " " , 0 , all_rules);
78697938
7870- register_rule (" O_DDR" , " R" , " f2g_trx_reset_n_A " , 0 , all_rules);
7939+ register_rule (" O_DDR" , " R" , " f2g_trx_reset_n " , 0 , all_rules);
78717940 register_rule (" O_DDR" , " E" , " " , 0 , all_rules);
78727941
7873- register_rule (" I_SERDES" , " RST" , " f2g_trx_reset_n_A " , 0 , all_rules);
7942+ register_rule (" I_SERDES" , " RST" , " f2g_trx_reset_n " , 0 , all_rules);
78747943 register_rule (" I_SERDES" , " BITSLIP_ADJ" , " " , 0 , all_rules);
78757944 register_rule (" I_SERDES" , " EN" , " " , 0 , all_rules);
7876- register_rule (" I_SERDES" , " DATA_VALID" , " g2f_rx_dvalid_A " , 0 , all_rules);
7945+ register_rule (" I_SERDES" , " DATA_VALID" , " g2f_rx_dvalid " , 0 , all_rules);
78777946 register_rule (" I_SERDES" , " DPA_LOCK" , " " , 0 , all_rules);
78787947 register_rule (" I_SERDES" , " DPA_ERROR" , " " , 0 , all_rules);
78797948 register_rule (" I_SERDES" , " PLL_LOCK" , " " , 0 , all_rules);
78807949
7881- register_rule (" O_SERDES" , " RST" , " f2g_trx_reset_n_A " , 0 , all_rules);
7882- register_rule (" O_SERDES" , " DATA_VALID" , " f2g_trx_dvalid_A " , 0 , all_rules);
7950+ register_rule (" O_SERDES" , " RST" , " f2g_trx_reset_n " , 0 , all_rules);
7951+ register_rule (" O_SERDES" , " DATA_VALID" , " f2g_trx_dvalid " , 0 , all_rules);
78837952 register_rule (" O_SERDES" , " OE_IN" , " " , 0 , all_rules);
78847953 register_rule (" O_SERDES" , " OE_OUT" , " " , 0 , all_rules);
78857954 register_rule (" O_SERDES" , " CHANNEL_BOND_SYNC_IN" , " " , 0 , all_rules);
@@ -7894,7 +7963,7 @@ void collect_clocks (RTLIL::Module* module,
78947963
78957964 }
78967965
7897- void apply_rules (RTLIL::Module* top_module,
7966+ void apply_rules (RTLIL::Module* top_module, vector<RTLIL::Cell*>& cells_primitives,
78987967 RTLIL::IdString cellName, vector<RTLIL::Cell*>* cells,
78997968 vector<std::tuple<string, string, int >>* rules)
79007969 {
@@ -7927,7 +7996,7 @@ void collect_clocks (RTLIL::Module* module,
79277996 }
79287997
79297998 for (auto cell : *cells) {
7930- insert_iofab_NS_rules (top_module, cell, portName, fabPortName);
7999+ insert_iofab_NS_rules (top_module, cells_primitives, cell, portName, fabPortName);
79318000 }
79328001 }
79338002
@@ -7956,7 +8025,7 @@ void collect_clocks (RTLIL::Module* module,
79568025 //
79578026 void map_iofab () {
79588027
7959- log (" \n Inserting I_FAB/O_FAB cells ...\n\n " );
8028+ log (" Inserting I_FAB/O_FAB cells ...\n\n " );
79608029
79618030 if (iofab_map == 2 ) {
79628031 run (" write_verilog -org-name -noattr -noexpr -nohex before_iofab_map.v" );
@@ -7978,12 +8047,23 @@ void collect_clocks (RTLIL::Module* module,
79788047 //
79798048 dict<RTLIL::IdString, vector<RTLIL::Cell*>*> cells_to_process;
79808049
8050+ vector<RTLIL::Cell*> cells_primitives;
8051+
79818052 if (iofab_map == 2 ) {
79828053 log (" Getting the cells ...\n " );
79838054 }
79848055
79858056 for (auto cell : top_module->cells ()) {
79868057
8058+ if (cell->type .in (ID (I_BUF_DS), ID (O_BUF_DS), ID (O_BUFT_DS), ID (O_SERDES), ID (I_SERDES),
8059+ ID (BOOT_CLOCK), ID (O_DELAY), ID (I_DELAY), ID (O_SERDES_CLK), ID (PLL))) {
8060+
8061+ #if 0
8062+ log("Collect Cell %s\n", (cell->type).c_str());
8063+ #endif
8064+ cells_primitives.push_back (cell);
8065+ }
8066+
79878067 // Ignore the cell if not involved by a rule
79888068 //
79898069 if (!all_rules.count (cell->type )) {
@@ -8013,7 +8093,7 @@ void collect_clocks (RTLIL::Module* module,
80138093 cells->size ());
80148094 }
80158095
8016- apply_rules (top_module, cellName, cells, rules);
8096+ apply_rules (top_module, cells_primitives, cellName, cells, rules);
80178097 }
80188098
80198099 // Dispose all obects
0 commit comments