@@ -5969,28 +5969,85 @@ static void show_sig(const RTLIL::SigSpec &sig)
5969
5969
}
5970
5970
}
5971
5971
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)
5974
6015
{
5975
6016
5976
6017
if (iofab_map == 2 ) {
5977
6018
log (" - Inserting O_FAB on cell '%s' (%s) on NS input port '%s'\n " , (cell->name ).c_str (),
5978
6019
(cell->type ).c_str (), portName.c_str ());
5979
6020
}
5980
6021
5981
- if (!actual.is_chunk ()) {
6022
+ if (!actual.is_chunk ()) { // If this is a concat of sub-actuals ...
5982
6023
5983
6024
RTLIL::SigSpec new_sig;
5984
6025
RTLIL::SigSpec new_sigO;
5985
6026
5986
- // This is an append of sub signals
6027
+ // This is a concat of sub signals
5987
6028
//
5988
6029
for (auto it = actual.chunks ().rbegin (); it != actual.chunks ().rend (); ++it) {
5989
6030
5990
6031
RTLIL::SigSpec sub_actual = *it;
5991
6032
5992
6033
RTLIL::Wire *wire = sub_actual[0 ].wire ;
5993
6034
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
+
5994
6051
if (fabPortName ==" " ) {
5995
6052
fabPortName = " ofab" ;
5996
6053
}
@@ -6019,7 +6076,7 @@ static void show_sig(const RTLIL::SigSpec &sig)
6019
6076
6020
6077
new_cell->setPort (ID::O, new_sigO);
6021
6078
6022
- // Build the new append
6079
+ // Build the new concat
6023
6080
//
6024
6081
new_sigO.append (new_sig);
6025
6082
@@ -6029,14 +6086,24 @@ static void show_sig(const RTLIL::SigSpec &sig)
6029
6086
6030
6087
RTLIL::IdString idPortName = RTLIL::escape_id (portName);
6031
6088
6089
+ // replace the former concat by the new built concat 'new_sig'
6090
+ //
6032
6091
cell->unsetPort (idPortName);
6033
6092
6034
6093
cell->setPort (idPortName, new_sig);
6035
6094
6036
- } else {
6095
+ } else { // else we are processing a simple 'actual' net
6037
6096
6038
6097
RTLIL::Wire *wire = actual[0 ].wire ;
6039
6098
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
+
6040
6107
if (fabPortName ==" " ) {
6041
6108
fabPortName = " ofab" ;
6042
6109
}
@@ -6175,7 +6242,9 @@ static void show_sig(const RTLIL::SigSpec &sig)
6175
6242
// by a constant. We are in the Non Shared(NS) case which means that
6176
6243
// we systematically create a I_FAB or O_FAB.
6177
6244
//
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,
6179
6248
string portName, string fabPortName)
6180
6249
{
6181
6250
int found = 0 ;
@@ -6220,7 +6289,7 @@ static void show_sig(const RTLIL::SigSpec &sig)
6220
6289
//
6221
6290
if (cell->input (RTLIL::escape_id (portName))) {
6222
6291
6223
- ofab_insert_NS_rules (top_module, cell, portName, fabPortName, actual);
6292
+ ofab_insert_NS_rules (top_module, cells_primitives, cell, portName, fabPortName, actual);
6224
6293
6225
6294
return ;
6226
6295
}
@@ -7832,11 +7901,11 @@ void collect_clocks (RTLIL::Module* module,
7832
7901
log (" Getting the rules ...\n " );
7833
7902
}
7834
7903
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);
7837
7906
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);
7840
7909
7841
7910
#if 0
7842
7911
// SHARED version
@@ -7864,22 +7933,22 @@ void collect_clocks (RTLIL::Module* module,
7864
7933
register_rule (" O_DELAY" , " DLY_TAP_VALUE" , " f2g_trx_dly_tap" , 0 , all_rules);
7865
7934
#endif
7866
7935
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);
7868
7937
register_rule (" I_DDR" , " E" , " " , 0 , all_rules);
7869
7938
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);
7871
7940
register_rule (" O_DDR" , " E" , " " , 0 , all_rules);
7872
7941
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);
7874
7943
register_rule (" I_SERDES" , " BITSLIP_ADJ" , " " , 0 , all_rules);
7875
7944
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);
7877
7946
register_rule (" I_SERDES" , " DPA_LOCK" , " " , 0 , all_rules);
7878
7947
register_rule (" I_SERDES" , " DPA_ERROR" , " " , 0 , all_rules);
7879
7948
register_rule (" I_SERDES" , " PLL_LOCK" , " " , 0 , all_rules);
7880
7949
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);
7883
7952
register_rule (" O_SERDES" , " OE_IN" , " " , 0 , all_rules);
7884
7953
register_rule (" O_SERDES" , " OE_OUT" , " " , 0 , all_rules);
7885
7954
register_rule (" O_SERDES" , " CHANNEL_BOND_SYNC_IN" , " " , 0 , all_rules);
@@ -7894,7 +7963,7 @@ void collect_clocks (RTLIL::Module* module,
7894
7963
7895
7964
}
7896
7965
7897
- void apply_rules (RTLIL::Module* top_module,
7966
+ void apply_rules (RTLIL::Module* top_module, vector<RTLIL::Cell*>& cells_primitives,
7898
7967
RTLIL::IdString cellName, vector<RTLIL::Cell*>* cells,
7899
7968
vector<std::tuple<string, string, int >>* rules)
7900
7969
{
@@ -7927,7 +7996,7 @@ void collect_clocks (RTLIL::Module* module,
7927
7996
}
7928
7997
7929
7998
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);
7931
8000
}
7932
8001
}
7933
8002
@@ -7956,7 +8025,7 @@ void collect_clocks (RTLIL::Module* module,
7956
8025
//
7957
8026
void map_iofab () {
7958
8027
7959
- log (" \n Inserting I_FAB/O_FAB cells ...\n\n " );
8028
+ log (" Inserting I_FAB/O_FAB cells ...\n\n " );
7960
8029
7961
8030
if (iofab_map == 2 ) {
7962
8031
run (" write_verilog -org-name -noattr -noexpr -nohex before_iofab_map.v" );
@@ -7978,12 +8047,23 @@ void collect_clocks (RTLIL::Module* module,
7978
8047
//
7979
8048
dict<RTLIL::IdString, vector<RTLIL::Cell*>*> cells_to_process;
7980
8049
8050
+ vector<RTLIL::Cell*> cells_primitives;
8051
+
7981
8052
if (iofab_map == 2 ) {
7982
8053
log (" Getting the cells ...\n " );
7983
8054
}
7984
8055
7985
8056
for (auto cell : top_module->cells ()) {
7986
8057
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
+
7987
8067
// Ignore the cell if not involved by a rule
7988
8068
//
7989
8069
if (!all_rules.count (cell->type )) {
@@ -8013,7 +8093,7 @@ void collect_clocks (RTLIL::Module* module,
8013
8093
cells->size ());
8014
8094
}
8015
8095
8016
- apply_rules (top_module, cellName, cells, rules);
8096
+ apply_rules (top_module, cells_primitives, cellName, cells, rules);
8017
8097
}
8018
8098
8019
8099
// Dispose all obects
0 commit comments