@@ -2199,6 +2199,106 @@ struct SynthRapidSiliconPass : public ScriptPass {
21992199 return nb;
22002200 }
22012201
2202+ void carry_2_gate ()
2203+ {
2204+
2205+ dict<RTLIL::SigSpec, Cell *> ci2cell;
2206+ dict<Cell *, RTLIL::SigSpec> co2cell;
2207+ std::map<int , std::vector<Cell *>> carry_chains;
2208+ vector<Cell *> carry_chain_head_cells;
2209+
2210+ for (auto cell : _design->top_module ()->cells ())
2211+ {
2212+ if (cell->type != RTLIL::escape_id (" CARRY" ))
2213+ continue ;
2214+
2215+ bool noCo = true ;
2216+ for (auto &conn : cell->connections ())
2217+ {
2218+ IdString portName = conn.first ;
2219+ RTLIL::SigSpec actual = conn.second ;
2220+
2221+ if (portName == RTLIL::escape_id (" CIN" ))
2222+ {
2223+ ci2cell[actual] = cell;
2224+ continue ;
2225+ }
2226+
2227+ if (portName == RTLIL::escape_id (" COUT" ) && !(actual.empty ()))
2228+ {
2229+ noCo = false ;
2230+ co2cell[cell] = actual;
2231+ continue ;
2232+ }
2233+ }
2234+ if (noCo)
2235+ {
2236+ co2cell[cell] = {};
2237+ carry_chain_head_cells.push_back (cell);
2238+ }
2239+ }
2240+ vector<RTLIL::SigSpec> carry_chain_head_co2cell;
2241+
2242+ int chain = 0 ;
2243+ for (auto head_cell : carry_chain_head_cells)
2244+ {
2245+ RTLIL::SigSpec signal = head_cell->getPort (RTLIL::escape_id (" CIN" ));
2246+ chain += 1 ;
2247+ carry_chains[chain].push_back (head_cell);
2248+ while (!signal.empty ())
2249+ {
2250+ bool found = false ;
2251+ for (auto &co_signal : co2cell)
2252+ {
2253+ if (co_signal.second == signal)
2254+ {
2255+ carry_chains[chain].push_back (co_signal.first );
2256+ signal = co_signal.first ->getPort (RTLIL::escape_id (" CIN" ));
2257+ found = true ;
2258+ break ;
2259+ }
2260+ }
2261+ if (!found)
2262+ {
2263+ break ;
2264+ }
2265+ }
2266+ }
2267+
2268+ for (auto &chain : carry_chains)
2269+ {
2270+ const std::vector<Cell *> &chain_ = chain.second ;
2271+ int extra_carry = chain_.size () - max_carry_length;
2272+ if (extra_carry > 0 )
2273+ {
2274+ std::vector<Cell *> ExcessCarry;
2275+ ExcessCarry.reserve (extra_carry);
2276+ std::copy (chain_.begin (), chain_.begin () + extra_carry, std::back_inserter (ExcessCarry));
2277+
2278+ for (auto it = ExcessCarry.begin (); it != ExcessCarry.end ();)
2279+ {
2280+ Cell *ec = *it;
2281+
2282+ log (" Converting %s to logic.\n " , log_id (ec->name ));
2283+ RTLIL::Module *top_module = _design->top_module ();
2284+ RTLIL::SigSpec np = top_module->addWire (NEW_ID, 1 );
2285+ RTLIL::SigSpec and1 = top_module->addWire (NEW_ID, 1 );
2286+ RTLIL::SigSpec and2 = top_module->addWire (NEW_ID, 1 );
2287+ RTLIL::SigSpec c_out = top_module->addWire (NEW_ID, 1 );
2288+ top_module->addXor (NEW_ID, ec->getPort (RTLIL::escape_id (" P" )), ec->getPort (RTLIL::escape_id (" CIN" )), ec->getPort (RTLIL::escape_id (" O" )));
2289+ top_module->addNot (NEW_ID, ec->getPort (RTLIL::escape_id (" P" )), np);
2290+ top_module->addAnd (NEW_ID, ec->getPort (RTLIL::escape_id (" P" )), ec->getPort (RTLIL::escape_id (" CIN" )), and1);
2291+ top_module->addAnd (NEW_ID, np, ec->getPort (RTLIL::escape_id (" G" )), and2);
2292+ top_module->addOr (NEW_ID, and1, and2, ec->getPort (RTLIL::escape_id (" COUT" )));
2293+
2294+ top_module->remove (ec);
2295+ it = ExcessCarry.erase (it);
2296+ }
2297+ ExcessCarry.clear ();
2298+ }
2299+ }
2300+ }
2301+
22022302 int getNumberOfGenericREGs () {
22032303
22042304 int nb = 0 ;
@@ -8941,7 +9041,8 @@ void collect_clocks (RTLIL::Module* module,
89419041 break ;
89429042 }
89439043 }
8944-
9044+ // Awais: Convert Carry to logic if carry in a chain exceed max carry length limit in a chain.
9045+ carry_2_gate ();
89459046 if (cec) {
89469047 run (" write_verilog -noexpr -noattr -nohex after_tech_map.v" );
89479048 }
0 commit comments