Skip to content

Commit 027a3c5

Browse files
Merge pull request #405 from BessonThierry/main
fix partially EDA-3175, avoid cascade of O_FAB
2 parents 0a65f05 + 955c621 commit 027a3c5

File tree

1 file changed

+102
-22
lines changed

1 file changed

+102
-22
lines changed

src/synth_rapidsilicon.cc

+102-22
Original file line numberDiff line numberDiff line change
@@ -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("\nInserting 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

Comments
 (0)