Skip to content

Commit 0c3a837

Browse files
committed
adding fix for EDA-1645
1 parent ae0c43b commit 0c3a837

File tree

3 files changed

+104
-3
lines changed

3 files changed

+104
-3
lines changed

genesis3/all_arith_map.v

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ module _80_rs_alu (A, B, CI, BI, X, Y, CO);
2323
output [Y_WIDTH-1:0] CO;
2424

2525

26-
wire _TECHMAP_FAIL_ = Y_WIDTH <= 2 || Y_WIDTH > `MAX_CARRY_CHAIN;
26+
wire _TECHMAP_FAIL_ = Y_WIDTH <= 2;
2727

2828
(* force_downto *)
2929
wire [Y_WIDTH-1:0] A_buf, B_buf;

genesis3/arith_map.v

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ module _80_rs_alu (A, B, CI, BI, X, Y, CO);
2727
output [Y_WIDTH-1:0] CO;
2828

2929

30-
wire _TECHMAP_FAIL_ = Y_WIDTH <= 16 || Y_WIDTH > `MAX_CARRY_CHAIN;
30+
wire _TECHMAP_FAIL_ = Y_WIDTH <= 16;
3131

3232
(* force_downto *)
3333
wire [Y_WIDTH-1:0] A_buf, B_buf;

src/synth_rapidsilicon.cc

Lines changed: 102 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)