Skip to content

Commit 9925bba

Browse files
committed
Fix EDA-1645 by breaking long carry chains
1 parent 78566b8 commit 9925bba

File tree

2 files changed

+149
-1
lines changed

2 files changed

+149
-1
lines changed

Makefile

+1
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ VERILOG_MODULES = $(COMMON)/cells_sim.v \
5252
$(GENESIS3)/SEC_MODELS/DFFRE.blif \
5353
$(GENESIS3)/FPGA_PRIMITIVES_MODELS/blackbox_models/cell_sim_blackbox.v \
5454
$(GENESIS3)/FPGA_PRIMITIVES_MODELS/sim_models/verilog/CARRY.v \
55+
$(GENESIS3)/FPGA_PRIMITIVES_MODELS/sim_models/verilog/CARRY_BREAK.v \
5556
$(GENESIS3)/cells_sim.vhd \
5657
$(GENESIS3)/brams_sim.v \
5758
$(GENESIS3)/ffs_map.v \

src/synth_rapidsilicon.cc

+148-1
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ PRIVATE_NAMESPACE_BEGIN
4545
#define BLACKBOX_SIM_LIB_FILE cell_sim_blackbox.v
4646
#define BLACKBOX_SIM_LIB_OFAB_FILE cell_ofab_sim_blackbox.v
4747
#define SIM_LIB_CARRY_FILE CARRY.v
48+
#define SIM_LIB_CARRY_BREAK_FILE CARRY_BREAK.v
4849
#define LLATCHES_SIM_FILE llatches_sim.v
4950
#define DSP_SIM_LIB_FILE dsp_sim.v
5051
#define BRAMS_SIM_LIB_FILE brams_sim.v
@@ -5839,6 +5840,111 @@ static void show_sig(const RTLIL::SigSpec &sig)
58395840
}
58405841
}
58415842

5843+
// We replace CARRY cells by CARRY_BREAK cells when we encounter carry chains
5844+
// longer than 'max_carry_length'
5845+
//
5846+
// Return 1 if at least one break occured, 0 otherwise.
5847+
//
5848+
int insert_carry_chain_break_cells()
5849+
{
5850+
int break_chain = 0;
5851+
5852+
dict<RTLIL::SigSpec, Cell *> ci2cell;
5853+
dict<Cell *, RTLIL::SigSpec> co2cell;
5854+
std::map<int, std::vector<Cell *>> carry_chains;
5855+
vector<Cell *> carry_chain_head_cells;
5856+
5857+
for (auto cell : _design->top_module()->cells())
5858+
{
5859+
if (cell->type != RTLIL::escape_id("CARRY"))
5860+
continue;
5861+
5862+
// log("Cout = %s, CIN = %s\n",log_signal(cell->getPort(RTLIL::escape_id("COUT"))),log_signal(cell->getPort(RTLIL::escape_id("CIN"))));
5863+
bool noCo = true;
5864+
for (auto &conn : cell->connections())
5865+
{
5866+
IdString portName = conn.first;
5867+
RTLIL::SigSpec actual = conn.second;
5868+
5869+
if (portName == RTLIL::escape_id("CIN"))
5870+
{
5871+
ci2cell[actual] = cell;
5872+
continue;
5873+
}
5874+
5875+
if (portName == RTLIL::escape_id("COUT") && !(actual.empty()))
5876+
{
5877+
noCo = false;
5878+
co2cell[cell] = actual;
5879+
continue;
5880+
}
5881+
}
5882+
if (noCo)
5883+
{
5884+
co2cell[cell] = {};
5885+
carry_chain_head_cells.push_back(cell);
5886+
}
5887+
}
5888+
vector<RTLIL::SigSpec> carry_chain_head_co2cell;
5889+
5890+
int chain = 0;
5891+
for (auto head_cell : carry_chain_head_cells)
5892+
{
5893+
RTLIL::SigSpec signal = head_cell->getPort(RTLIL::escape_id("CIN"));
5894+
chain += 1;
5895+
carry_chains[chain].push_back(head_cell);
5896+
while (!signal.empty())
5897+
{
5898+
bool found = false;
5899+
for (auto &co_signal : co2cell)
5900+
{
5901+
if (co_signal.second == signal)
5902+
{
5903+
carry_chains[chain].push_back(co_signal.first);
5904+
signal = co_signal.first->getPort(RTLIL::escape_id("CIN"));
5905+
found = true;
5906+
break;
5907+
}
5908+
}
5909+
if (!found)
5910+
{
5911+
break;
5912+
}
5913+
}
5914+
}
5915+
5916+
for (auto &chain : carry_chains)
5917+
{
5918+
std::vector<Cell*> original_chain = chain.second;
5919+
5920+
int start = max_carry_length;
5921+
int step = max_carry_length-2;
5922+
5923+
for (long unsigned int i = start; (i > 0) && (i < original_chain.size()); i += step) {
5924+
5925+
Cell* previous_cell = original_chain[i-1];
5926+
Cell* cell = original_chain[i];
5927+
5928+
if (previous_cell->type != RTLIL::escape_id("CARRY")) {
5929+
continue; // should never happen as cells are always CARRY
5930+
}
5931+
if (cell->type != RTLIL::escape_id("CARRY")) {
5932+
continue; // should never happen as cells are always CARRY
5933+
}
5934+
5935+
// Every max length on the chain replace CARRY cell by a
5936+
// CARRY_BREAK cell.
5937+
//
5938+
previous_cell->type = RTLIL::escape_id("CARRY_BREAK");
5939+
log("NOTE: Breaking carry chain at carry cell '%s'\n",
5940+
(previous_cell->name).c_str());
5941+
break_chain = 1;
5942+
}
5943+
}
5944+
5945+
return break_chain;
5946+
}
5947+
58425948
// Force 'keep' attribute on original IO BUF cells instantiated at RTL.
58435949
// (ex: EDA-3307 where one I_BUF is removed by optimizer because input is not used)
58445950
//
@@ -8449,6 +8555,42 @@ void collect_clocks (RTLIL::Module* module,
84498555
log_warning("DSP exceeds the available DSP block limit (%d) on the device; the excess %d DSP blocks will be mapped to LUTs.\n",max_dsp, remaining_sum);
84508556
}
84518557
}
8558+
8559+
// We try to break long carry chains that exceed 'max_carry_length'
8560+
//
8561+
// 0. Extract all carry chains (use 'reportCarryChains' source code)
8562+
// 1. replace CARRY cells by CARRY_BREAK cells every max_carry_length-2
8563+
// 2. techmap CARRY_BREAK cells and replace them by verilog model
8564+
// 3. clean up design after techmap
8565+
//
8566+
void break_carry_chains()
8567+
{
8568+
// Performs 0. and 1.
8569+
//
8570+
int carry_breaks = insert_carry_chain_break_cells();
8571+
8572+
if (!carry_breaks) {
8573+
return;
8574+
}
8575+
8576+
log("NOTE: after inserting carry chain break cells");
8577+
run("stat");
8578+
8579+
// Perform 2.
8580+
8581+
//string rreadArgs = GET_FILE_PATH(GENESIS_3_DIR, carry_break.v);
8582+
string rreadArgs = GET_FILE_PATH_RS_FPGA_SIM(GENESIS_3_DIR, SIM_LIB_CARRY_BREAK_FILE);
8583+
8584+
// tech map the carry_break cells
8585+
//
8586+
run(stringf("techmap -map %s ", rreadArgs.c_str()));
8587+
8588+
// Perform 3.
8589+
//
8590+
run("opt_clean -purge");
8591+
8592+
log("NOTE: after carry chain breaks");
8593+
}
84528594

84538595
void script() override
84548596
{
@@ -8984,8 +9126,13 @@ void collect_clocks (RTLIL::Module* module,
89849126
break;
89859127
}
89869128
}
9129+
9130+
// We try to break long carry chains that exceed 'max_carry_length'
9131+
//
9132+
break_carry_chains();
9133+
89879134
run("stat");
8988-
break;
9135+
break;
89899136
}
89909137
case Technologies::GENERIC: {
89919138
run("techmap");

0 commit comments

Comments
 (0)