booth: Make more use of appropriate helpers

Use the `addFa` helper, do not misuse `new_id` and make other changes
to the transformation code.
This commit is contained in:
Martin Povišer 2023-09-25 13:54:24 +02:00
parent d641dfaec2
commit cde2a0b926
1 changed files with 150 additions and 258 deletions

View File

@ -687,20 +687,15 @@ struct BoothPassWorker {
// End Case // End Case
else if (n == s_vec.size() - 1) { else if (n == s_vec.size() - 1) {
// Make the carry results.. Two extra bits after fa. // Make the carry results.. Two extra bits after fa.
std::string fa_name = "cpa_" + std::to_string(cpa_id) + "_fa_" + std::to_string(n); SigBit carry_out = module->addWire(NEW_ID, 1);
module->addFa(NEW_ID_SUFFIX(stringf("cpa_%d_fa_%d", cpa_id, n)),
auto fa_cell = module->addCell(new_id(fa_name, __LINE__, ""), ID($fa)); /* A */ s_vec[n],
fa_cell->setParam(ID::WIDTH, 1); /* B */ c_vec[n - 1],
carry_name = "cpa_" + std::to_string(cpa_id) + "carry_" + std::to_string(n); /* C */ carry,
fa_cell->setPort(ID::A, s_vec[n]); /* X */ carry_out,
fa_cell->setPort(ID::B, c_vec[n - 1]); /* Y */ result[n]
fa_cell->setPort(ID::C, carry); );
// wire in result and carry out carry = carry_out;
fa_cell->setPort(ID::Y, result[n]);
// make a new carry bit for carry out...
carry = module->addWire(new_id(carry_name, __LINE__, ""), 1);
fa_cell->setPort(ID::X, carry);
#ifdef DEBUG_CPA #ifdef DEBUG_CPA
printf("CPA bit [%d] Cell %s IPs [%s] [%s] [%s]\n", n, fa_cell->name.c_str(), s_vec[n]->name.c_str(), printf("CPA bit [%d] Cell %s IPs [%s] [%s] [%s]\n", n, fa_cell->name.c_str(), s_vec[n]->name.c_str(),
@ -720,20 +715,15 @@ struct BoothPassWorker {
} }
// Step case // Step case
else { else {
std::string fa_name = "cpa_" + std::to_string(cpa_id) + "_fa_" + std::to_string(n); SigBit carry_out = module->addWire(NEW_ID_SUFFIX(stringf("cpa_%d_carry_%d", cpa_id, n)), 1);
auto fa_cell = module->addCell(new_id(fa_name, __LINE__, ""), ID($fa)); module->addFa(NEW_ID_SUFFIX(stringf("cpa_%d_fa_%d", cpa_id, n)),
fa_cell->setParam(ID::WIDTH, 1); /* A */ s_vec[n],
/* B */ c_vec[n - 1],
carry_name = "cpa_" + std::to_string(cpa_id) + "carry_" + std::to_string(n); /* C */ carry,
fa_cell->setPort(ID::A, s_vec[n]); /* X */ carry_out,
fa_cell->setPort(ID::B, c_vec[n - 1]); /* Y */ result[n]
fa_cell->setPort(ID::C, carry); );
// wire in result and carry out carry = carry_out;
fa_cell->setPort(ID::Y, result[n]);
// make a new carry bit for carry out...
carry = module->addWire(new_id(carry_name, __LINE__, ""), 1);
fa_cell->setPort(ID::X, carry);
#ifdef DEBUG_CPA #ifdef DEBUG_CPA
printf("CPA bit [%d] Cell %s IPs [%s] [%s] [%s]\n", n, fa_cell->name.c_str(), s_vec[n]->name.c_str(), printf("CPA bit [%d] Cell %s IPs [%s] [%s] [%s]\n", n, fa_cell->name.c_str(), s_vec[n]->name.c_str(),
c_vec[n - 1]->name.c_str(), carry->name.c_str()); c_vec[n - 1]->name.c_str(), carry->name.c_str());
@ -752,9 +742,6 @@ struct BoothPassWorker {
int csa_ix = 0; int csa_ix = 0;
int column_size = column_bits.size(); int column_size = column_bits.size();
static int unique_id = 0;
unique_id++;
if (column_size > 0) { if (column_size > 0) {
int var_ix = 0; int var_ix = 0;
@ -767,38 +754,23 @@ struct BoothPassWorker {
if (first_csa_ips.size() > 0) { if (first_csa_ips.size() > 0) {
// build the first csa // build the first csa
std::string csa_name = auto s_wire = module->addWire(NEW_ID_SUFFIX(stringf("csa_%d_%d_s", column_ix, csa_ix + 1)), 1);
"csa_" + std::to_string(column_ix) + "_" + std::to_string(csa_ix) + "_" + std::to_string(unique_id) + "_"; auto c_wire = module->addWire(NEW_ID_SUFFIX(stringf("csa_%d_%d_c", column_ix, csa_ix + 1)), 1);
auto csa = module->addCell(NEW_ID,
// new_id(csa_name, auto csa = module->addFa(NEW_ID_SUFFIX(stringf("csa_%d_%d", column_ix, csa_ix)),
// __LINE__, /* A */ first_csa_ips[0],
// ""), /* B */ first_csa_ips.size() > 1 ? first_csa_ips[1] : State::S0,
ID($fa)); /* C */ first_csa_ips.size() > 2 ? first_csa_ips[2] : State::S0,
csa->setParam(ID::WIDTH, 1); /* X */ c_wire,
/* Y */ s_wire
);
s_result = s_wire;
c_result = c_wire;
debug_csa_trees[column_ix].push_back(csa); debug_csa_trees[column_ix].push_back(csa);
csa_ix++; csa_ix++;
csa->setPort(ID::A, first_csa_ips[0]);
if (first_csa_ips.size() > 1)
csa->setPort(ID::B, first_csa_ips[1]);
else
csa->setPort(ID::B, State::S0);
if (first_csa_ips.size() > 2)
csa->setPort(ID::C, first_csa_ips[2]);
else
csa->setPort(ID::C, State::S0);
std::string sum_wire_name = "csa_" + std::to_string(column_ix) + "_" + std::to_string(csa_ix) + "_s";
auto s_wire = module->addWire(new_id(sum_wire_name, __LINE__, ""), 1);
csa->setPort(ID::Y, s_wire);
s_result = s_wire;
std::string carry_wire_name = "csa_" + std::to_string(column_ix) + "_" + std::to_string(csa_ix) + "_c";
auto c_wire = module->addWire(new_id(carry_wire_name, __LINE__, ""), 1);
csa->setPort(ID::X, c_wire);
c_result = c_wire;
if (var_ix <= column_bits.size() - 1) if (var_ix <= column_bits.size() - 1)
carry_bits_to_sum.append(c_wire); carry_bits_to_sum.append(c_wire);
@ -814,32 +786,23 @@ struct BoothPassWorker {
} }
if (csa_ips.size() > 0) { if (csa_ips.size() > 0) {
csa_name = "csa_" + std::to_string(column_ix) + "_" + std::to_string(csa_ix); auto c_wire = module->addWire(NEW_ID_SUFFIX(stringf("csa_%d_%d_c", column_ix, csa_ix + 1)), 1);
auto csa = module->addCell(new_id(csa_name, __LINE__, ""), ID($fa)); auto s_wire = module->addWire(NEW_ID_SUFFIX(stringf("csa_%d_%d_s", column_ix, csa_ix + 1)), 1);
csa->setParam(ID::WIDTH, 1);
auto csa = module->addFa(NEW_ID_SUFFIX(stringf("csa_%d_%d", column_ix, csa_ix)),
/* A */ s_result,
/* B */ csa_ips[0],
/* C */ csa_ips.size() > 1 ? csa_ips[1] : State::S0,
/* X */ c_wire,
/* Y */ s_wire
);
debug_csa_trees[column_ix].push_back(csa); debug_csa_trees[column_ix].push_back(csa);
csa_ix++; csa_ix++;
// prior level
csa->setPort(ID::A, s_wire);
csa->setPort(ID::B, csa_ips[0]);
if (csa_ips.size() > 1)
csa->setPort(ID::C, csa_ips[1]);
else
csa->setPort(ID::C, State::S0);
carry_wire_name = "csa_" + std::to_string(column_ix) + "_" + std::to_string(csa_ix) + "_c";
c_wire = module->addWire(new_id(carry_wire_name, __LINE__, ""), 1);
if (var_ix <= column_bits.size() - 1) if (var_ix <= column_bits.size() - 1)
carry_bits_to_sum.append(c_wire); carry_bits_to_sum.append(c_wire);
sum_wire_name = "csa_" + std::to_string(column_ix) + "_" + std::to_string(csa_ix) + "_s";
s_wire = module->addWire(new_id(sum_wire_name, __LINE__, ""), 1);
csa->setPort(ID::X, c_wire);
csa->setPort(ID::Y, s_wire);
s_result = s_wire; s_result = s_wire;
c_result = c_wire; c_result = c_wire;
} }
@ -854,22 +817,14 @@ struct BoothPassWorker {
int y_sz = GetSize(Y); int y_sz = GetSize(Y);
for (int y_ix = 0; y_ix < y_sz;) { for (int y_ix = 0; y_ix < y_sz;) {
std::string enc_name = "bur_enc_" + std::to_string(encoder_ix) + "_"; std::string enc_name = stringf("bur_enc_%d", encoder_ix);
std::string two_name = "two_int" + std::to_string(encoder_ix); two_int.append(module->addWire(NEW_ID_SUFFIX(stringf("two_int_%d", encoder_ix)), 1));
two_int.append(module->addWire(new_id(two_name, __LINE__, ""), 1)); one_int.append(module->addWire(NEW_ID_SUFFIX(stringf("one_int_%d", encoder_ix)), 1));
s_int.append(module->addWire(NEW_ID_SUFFIX(stringf("s_int_%d", encoder_ix)), 1));
std::string one_name = "one_int" + std::to_string(encoder_ix); sb_int.append(module->addWire(NEW_ID_SUFFIX(stringf("sb_int_%d", encoder_ix)), 1));
one_int.append(module->addWire(new_id(one_name, __LINE__, ""), 1));
std::string s_name = "s_int" + std::to_string(encoder_ix);
s_int.append(module->addWire(new_id(s_name, __LINE__, ""), 1));
std::string sb_name = "sb_int" + std::to_string(encoder_ix);
sb_int.append(module->addWire(new_id(sb_name, __LINE__, ""), 1));
if (y_ix == 0) { if (y_ix == 0) {
BuildBur4e(enc_name, State::S0, Y[y_ix], BuildBur4e(enc_name, State::S0, Y[y_ix],
Y[y_ix + 1], one_int[encoder_ix], two_int[encoder_ix], s_int[encoder_ix], Y[y_ix + 1], one_int[encoder_ix], two_int[encoder_ix], s_int[encoder_ix],
sb_int[encoder_ix]); sb_int[encoder_ix]);
@ -919,23 +874,15 @@ struct BoothPassWorker {
encoder_ix++; encoder_ix++;
if (need_padded_cell == true) { if (need_padded_cell == true) {
// make extra encoder cell // make extra encoder cell
// y_ix at y0, rest 0 // y_ix at y0, rest 0
std::string enc_name = "br_enc_pad" + std::to_string(encoder_ix) + "_"; std::string enc_name = stringf("br_enc_pad_%d", encoder_ix);
std::string two_name = "two_int" + std::to_string(encoder_ix); two_int.append(module->addWire(NEW_ID_SUFFIX(stringf("two_int_%d", encoder_ix)), 1));
two_int.append(module->addWire(new_id(two_name, __LINE__, ""), 1)); one_int.append(module->addWire(NEW_ID_SUFFIX(stringf("one_int_%d", encoder_ix)), 1));
s_int.append(module->addWire(NEW_ID_SUFFIX(stringf("s_int_%d", encoder_ix)), 1));
std::string one_name = "one_int" + std::to_string(encoder_ix); sb_int.append(module->addWire(NEW_ID_SUFFIX(stringf("sb_int_%d", encoder_ix)), 1));
one_int.append(module->addWire(new_id(two_name, __LINE__, ""), 1));
std::string s_name = "s_int" + std::to_string(encoder_ix);
s_int.append(module->addWire(new_id(s_name, __LINE__, ""), 1));
std::string sb_name = "sb_int" + std::to_string(encoder_ix);
sb_int.append(module->addWire(new_id(sb_name, __LINE__, ""), 1));
SigBit one_o_int, two_o_int, s_o_int, sb_o_int; SigBit one_o_int, two_o_int, s_o_int, sb_o_int;
BuildBur4e(enc_name, Y[y_ix], State::S0, BuildBur4e(enc_name, Y[y_ix], State::S0,
@ -977,18 +924,13 @@ struct BoothPassWorker {
cori_n_int.extend_u0(enc_count); cori_n_int.extend_u0(enc_count);
for (unsigned encoder_ix = 1; encoder_ix <= enc_count; encoder_ix++) { for (unsigned encoder_ix = 1; encoder_ix <= enc_count; encoder_ix++) {
std::string enc_name = "enc_" + std::to_string(encoder_ix) + "_"; std::string enc_name = stringf("enc_%d", encoder_ix);
std::string negi_name = "negi_n_int" + std::to_string(encoder_ix) + "_"; negi_n_int[encoder_ix - 1] = module->addWire(NEW_ID_SUFFIX(stringf("negi_n_int_%d", encoder_ix)), 1);
negi_n_int[encoder_ix - 1] = module->addWire(new_id(negi_name, __LINE__, ""), 1); twoi_n_int[encoder_ix - 1] = module->addWire(NEW_ID_SUFFIX(stringf("twoi_n_int_%d", encoder_ix)), 1);
std::string twoi_name = "twoi_n_int_" + std::to_string(encoder_ix) + "_"; onei_n_int[encoder_ix - 1] = module->addWire(NEW_ID_SUFFIX(stringf("onei_n_int_%d", encoder_ix)), 1);
twoi_n_int[encoder_ix - 1] = module->addWire(new_id(twoi_name, __LINE__, ""), 1); cori_n_int[encoder_ix - 1] = module->addWire(NEW_ID_SUFFIX(stringf("cori_n_int_%d", encoder_ix)), 1);
std::string onei_name = "onei_n_int_" + std::to_string(encoder_ix) + "_";
onei_n_int[encoder_ix - 1] = module->addWire(new_id(onei_name, __LINE__, ""), 1);
std::string cori_name = "cori_n_int_" + std::to_string(encoder_ix) + "_";
cori_n_int[encoder_ix - 1] = module->addWire(new_id(cori_name, __LINE__, ""), 1);
if (encoder_ix == 1) { if (encoder_ix == 1) {
BuildBr4e(enc_name, State::S0, Y[0], Y[1], BuildBr4e(enc_name, State::S0, Y[0], Y[1],
negi_n_int[encoder_ix - 1], twoi_n_int[encoder_ix - 1], onei_n_int[encoder_ix - 1], negi_n_int[encoder_ix - 1], twoi_n_int[encoder_ix - 1], onei_n_int[encoder_ix - 1],
cori_n_int[encoder_ix - 1]); cori_n_int[encoder_ix - 1]);
@ -1020,22 +962,18 @@ struct BoothPassWorker {
for (int encoder_ix = 1; encoder_ix <= (int)enc_count; encoder_ix++) { for (int encoder_ix = 1; encoder_ix <= (int)enc_count; encoder_ix++) {
for (int decoder_ix = 1; decoder_ix <= dec_count; decoder_ix++) { for (int decoder_ix = 1; decoder_ix <= dec_count; decoder_ix++) {
std::string ppij_name = "ppij_" + std::to_string(encoder_ix) + "_" + std::to_string(decoder_ix) + "_"; PPij[((encoder_ix - 1) * dec_count) + decoder_ix - 1] =
PPij[((encoder_ix - 1) * dec_count) + decoder_ix - 1] = module->addWire(new_id(ppij_name, __LINE__, ""), 1); module->addWire(NEW_ID_SUFFIX(stringf("ppij_%d_%d", encoder_ix, decoder_ix)), 1);
std::string nxj_name;
if (decoder_ix == 1)
nxj_name = "nxj_pre_dec" + std::to_string(encoder_ix) + "_" + std::to_string(decoder_ix) + "_";
else
nxj_name = "nxj_" + std::to_string(encoder_ix) + "_" + std::to_string(decoder_ix) + "_";
nxj[((encoder_ix - 1) * dec_count) + decoder_ix - 1] = module->addWire(new_id(nxj_name, __LINE__, ""), 1); nxj[((encoder_ix - 1) * dec_count) + decoder_ix - 1] =
module->addWire(NEW_ID_SUFFIX(stringf("nxj_%s%d_%d", decoder_ix == 1 ? "pre_dec_" : "",
encoder_ix, decoder_ix)), 1);
} }
} }
// //
// build decoder array // build decoder array
// //
for (int encoder_ix = 1; encoder_ix <= (int)enc_count; encoder_ix++) { for (int encoder_ix = 1; encoder_ix <= (int)enc_count; encoder_ix++) {
// pre-decoder // pre-decoder
std::string pre_dec_name = "pre_dec_" + std::to_string(encoder_ix) + "_"; std::string pre_dec_name = "pre_dec_" + std::to_string(encoder_ix) + "_";
@ -1043,10 +981,10 @@ struct BoothPassWorker {
if (encoder_ix == 1) { if (encoder_ix == 1) {
// quadrant 1 optimization // quadrant 1 optimization
} else { } else {
auto cell = module->addCell(new_id(pre_dec_name, __LINE__, ""), ID($_NOT_)); module->addNotGate(NEW_ID_SUFFIX(stringf("pre_dec_%d", encoder_ix)),
cell->add_strpool_attribute(ID::src, cell->get_strpool_attribute(ID::src)); negi_n_int[encoder_ix - 1],
cell->setPort(ID::A, negi_n_int[encoder_ix - 1]); nxj[(encoder_ix - 1) * dec_count]
cell->setPort(ID::Y, nxj[(encoder_ix - 1) * dec_count]); );
} }
for (int decoder_ix = 1; decoder_ix < dec_count; decoder_ix++) { for (int decoder_ix = 1; decoder_ix < dec_count; decoder_ix++) {
@ -1056,8 +994,7 @@ struct BoothPassWorker {
if ((decoder_ix == 1 || decoder_ix == 2) && encoder_ix == 1) if ((decoder_ix == 1 || decoder_ix == 2) && encoder_ix == 1)
continue; continue;
std::string dec_name = "dec_" + std::to_string(encoder_ix) + "_" + std::to_string(decoder_ix) + "_"; std::string dec_name = stringf("dec_%d_%d", encoder_ix, decoder_ix);
BuildBr4d(dec_name, nxj[((encoder_ix - 1) * dec_count) + decoder_ix - 1], twoi_n_int[encoder_ix - 1], BuildBr4d(dec_name, nxj[((encoder_ix - 1) * dec_count) + decoder_ix - 1], twoi_n_int[encoder_ix - 1],
X[decoder_ix - 1], negi_n_int[encoder_ix - 1], onei_n_int[encoder_ix - 1], X[decoder_ix - 1], negi_n_int[encoder_ix - 1], onei_n_int[encoder_ix - 1],
PPij[((encoder_ix - 1) * dec_count) + decoder_ix - 1], nxj[((encoder_ix - 1) * dec_count) + decoder_ix]); PPij[((encoder_ix - 1) * dec_count) + decoder_ix - 1], nxj[((encoder_ix - 1) * dec_count) + decoder_ix]);
@ -1065,7 +1002,7 @@ struct BoothPassWorker {
// duplicate end for sign fix // duplicate end for sign fix
// applies to 9th decoder (xsz+1 decoder). // applies to 9th decoder (xsz+1 decoder).
std::string dec_name = "dec_" + std::to_string(encoder_ix) + "_" + std::to_string(x_sz + 1) + "_"; std::string dec_name = stringf("dec_%d_%d", encoder_ix, x_sz + 1);
SigBit unused_op; SigBit unused_op;
BuildBr4d(dec_name, nxj[((encoder_ix - 1) * dec_count) + dec_count - 1], twoi_n_int[encoder_ix - 1], BuildBr4d(dec_name, nxj[((encoder_ix - 1) * dec_count) + dec_count - 1], twoi_n_int[encoder_ix - 1],
X[dec_count - 2], negi_n_int[encoder_ix - 1], onei_n_int[encoder_ix - 1], X[dec_count - 2], negi_n_int[encoder_ix - 1], onei_n_int[encoder_ix - 1],
@ -1083,11 +1020,10 @@ struct BoothPassWorker {
for (fa_row_ix = 0; fa_row_ix < fa_row_count; fa_row_ix++) { for (fa_row_ix = 0; fa_row_ix < fa_row_count; fa_row_ix++) {
for (fa_el_ix = 0; fa_el_ix < fa_count; fa_el_ix++) { for (fa_el_ix = 0; fa_el_ix < fa_count; fa_el_ix++) {
fa_sum_n[(fa_row_ix * fa_count) + fa_el_ix] =
std::string fa_sum_name = "fa_sum_n_" + std::to_string(fa_row_ix) + "_" + std::to_string(fa_el_ix) + "_"; module->addWire(NEW_ID_SUFFIX(stringf("fa_sum_n_%d_%d", fa_row_ix, fa_el_ix)), 1);
fa_sum_n[(fa_row_ix * fa_count) + fa_el_ix] = module->addWire(new_id(fa_sum_name, __LINE__, ""), 1); fa_carry_n[(fa_row_ix * fa_count) + fa_el_ix] =
std::string fa_carry_name = "fa_carry_n" + std::to_string(fa_row_ix) + "_" + std::to_string(fa_el_ix) + "_"; module->addWire(NEW_ID_SUFFIX(stringf("fa_carry_n_%d_%d", fa_row_ix, fa_el_ix)), 1);
fa_carry_n[(fa_row_ix * fa_count) + fa_el_ix] = module->addWire(new_id(fa_carry_name, __LINE__, ""), 1);
} }
} }
@ -1110,67 +1046,52 @@ struct BoothPassWorker {
// step case // step case
else if (fa_el_ix >= 2 && fa_el_ix <= x_sz) { else if (fa_el_ix >= 2 && fa_el_ix <= x_sz) {
// middle (2...x_sz cells) // middle (2...x_sz cells)
bfa_name = "bfa_0_step_" + std::to_string(fa_row_ix) + "_" + std::to_string(fa_el_ix) + "_L"; module->addFa(NEW_ID_SUFFIX(stringf("bfa_0_step_%d_%d_L", fa_row_ix, fa_el_ix)),
auto cell = module->addCell(new_id(bfa_name, __LINE__, ""), ID($fa)); /* A */ PPij[(0 * dec_count) + fa_el_ix],
cell->setParam(ID::WIDTH, 1); /* B */ PPij[(1 * dec_count) + fa_el_ix - 2],
cell->setPort(ID::A, PPij[(0 * dec_count) + fa_el_ix]); /* C */ fa_carry_n[(fa_row_ix * fa_count) + fa_el_ix - 1],
cell->setPort(ID::B, PPij[(1 * dec_count) + fa_el_ix - 2]); /* X */ fa_carry_n[(fa_row_ix * fa_count) + fa_el_ix],
cell->setPort(ID::C, fa_carry_n[(fa_row_ix * fa_count) + fa_el_ix - 1]); /* Y */ fa_sum_n[(fa_row_ix * fa_count) + fa_el_ix]
cell->setPort(ID::X, fa_carry_n[(fa_row_ix * fa_count) + fa_el_ix]); );
cell->setPort(ID::Y, fa_sum_n[(fa_row_ix * fa_count) + fa_el_ix]);
} }
// end 3 cells: x_sz+1.2.3 // end 3 cells: x_sz+1.2.3
// //
else { else {
// fa_el_ix = x_sz+1 // fa_el_ix = x_sz+1
bfa_name = "bfa_0_se_0" + std::to_string(fa_row_ix) + "_" + std::to_string(fa_el_ix) + "_L"; module->addFa(NEW_ID_SUFFIX(stringf("bfa_0_se_0_%d_%d_L", fa_row_ix, fa_el_ix)),
auto cell1 = module->addCell(new_id(bfa_name, __LINE__, ""), ID($fa)); /* A */ PPij[(0 * dec_count) + x_sz],
cell1->setParam(ID::WIDTH, 1); /* B */ PPij[(1 * dec_count) + fa_el_ix - 2],
cell1->setPort(ID::A, PPij[(0 * dec_count) + x_sz]); /* C */ fa_carry_n[(fa_row_ix * fa_count) + fa_el_ix - 1],
cell1->setPort(ID::B, PPij[(1 * dec_count) + fa_el_ix - 2]); /* X */ fa_carry_n[(fa_row_ix * fa_count) + fa_el_ix],
cell1->setPort(ID::C, fa_carry_n[(fa_row_ix * fa_count) + fa_el_ix - 1]); /* Y */ fa_sum_n[(fa_row_ix * fa_count) + fa_el_ix]
cell1->setPort(ID::X, fa_carry_n[(fa_row_ix * fa_count) + fa_el_ix]); );
cell1->setPort(ID::Y, fa_sum_n[(fa_row_ix * fa_count) + fa_el_ix]);
// exception:invert ppi // exception:invert ppi
fa_el_ix++; fa_el_ix++;
exc_inv_name = "bfa_0_exc_inv1_" + std::to_string(fa_row_ix) + "_" + std::to_string(fa_el_ix) + "_L"; SigBit d08_inv = module->NotGate(NEW_ID_SUFFIX(stringf("bfa_0_exc_inv1_%d_%d_L", fa_row_ix, fa_el_ix)),
auto cellinv1 = module->addCell(new_id(exc_inv_name, __LINE__, ""), ID($_NOT_)); PPij[(0 * dec_count) + dec_count - 1]);
cellinv1->add_strpool_attribute(ID::src, cellinv1->get_strpool_attribute(ID::src));
RTLIL::Wire *d08_inv = module->addWire(NEW_ID, 1); SigBit d18_inv = module->NotGate(NEW_ID_SUFFIX(stringf("bfa_0_exc_inv2_%d_%d_L", fa_row_ix, fa_el_ix)),
PPij[(1 * dec_count) + dec_count - 1]);
cellinv1->setPort(ID::A, PPij[(0 * dec_count) + dec_count - 1]); module->addFa(NEW_ID_SUFFIX(stringf("bfa_0_se_1_%d_%d_L", fa_row_ix, fa_el_ix)),
cellinv1->setPort(ID::Y, d08_inv); /* A */ d08_inv,
/* B */ d18_inv,
exc_inv_name = "bfa_0_exc_inv2_" + std::to_string(fa_row_ix) + "_" + std::to_string(fa_el_ix) + "_L"; /* C */ fa_carry_n[(fa_row_ix * fa_count) + fa_el_ix - 1],
/* X */ fa_carry_n[(fa_row_ix * fa_count) + fa_el_ix],
auto cellinv2 = module->addCell(new_id(exc_inv_name, __LINE__, ""), ID($_NOT_)); /* Y */ fa_sum_n[(fa_row_ix * fa_count) + fa_el_ix]
cellinv2->add_strpool_attribute(ID::src, cellinv2->get_strpool_attribute(ID::src)); );
RTLIL::Wire *d18_inv = module->addWire(NEW_ID, 1);
cellinv2->setPort(ID::A, PPij[(1 * dec_count) + dec_count - 1]);
cellinv2->setPort(ID::Y, d18_inv);
bfa_name = "bfa_0_se_1_" + std::to_string(fa_row_ix) + "_" + std::to_string(fa_el_ix) + "_L";
auto cell2 = module->addCell(new_id(bfa_name, __LINE__, ""), ID($fa));
cell2->setParam(ID::WIDTH, 1);
cell2->setPort(ID::A, d08_inv);
cell2->setPort(ID::B, d18_inv);
cell2->setPort(ID::C, fa_carry_n[(fa_row_ix * fa_count) + fa_el_ix - 1]);
cell2->setPort(ID::X, fa_carry_n[(fa_row_ix * fa_count) + fa_el_ix]);
cell2->setPort(ID::Y, fa_sum_n[(fa_row_ix * fa_count) + fa_el_ix]);
// sign extension // sign extension
fa_el_ix++; fa_el_ix++;
bfa_name = "bfa_0_se_2_" + std::to_string(fa_row_ix) + "_" + std::to_string(fa_el_ix) + "_L";
auto cell3 = module->addCell(new_id(bfa_name, __LINE__, ""), ID($fa)); module->addFa(NEW_ID_SUFFIX(stringf("bfa_0_se_2_%d_%d_L", fa_row_ix, fa_el_ix)),
cell3->setParam(ID::WIDTH, 1); /* A */ State::S0,
cell3->setPort(ID::A, State::S0); /* B */ State::S1,
cell3->setPort(ID::B, State::S1); /* C */ fa_carry_n[(fa_row_ix * fa_count) + fa_el_ix - 1],
cell3->setPort(ID::C, fa_carry_n[(fa_row_ix * fa_count) + fa_el_ix - 1]); /* X */ fa_carry_n[(fa_row_ix * fa_count) + fa_el_ix],
cell3->setPort(ID::X, fa_carry_n[(fa_row_ix * fa_count) + fa_el_ix]); /* Y */ fa_sum_n[(fa_row_ix * fa_count) + fa_el_ix]
cell3->setPort(ID::Y, fa_sum_n[(fa_row_ix * fa_count) + fa_el_ix]); );
} }
} }
@ -1181,74 +1102,59 @@ struct BoothPassWorker {
if (fa_el_ix == 0) { if (fa_el_ix == 0) {
// first two cells: have B input hooked to 0. // first two cells: have B input hooked to 0.
// column is offset by row_ix*2 // column is offset by row_ix*2
bfa_name = "bfa_" + std::to_string(fa_row_ix) + "_base_" + std::to_string(fa_row_ix) + "_" +
std::to_string(fa_el_ix) + "_L"; module->addFa(NEW_ID_SUFFIX(stringf("bfa_base_%d_%d_L", fa_row_ix, fa_el_ix)),
auto cell1 = module->addCell(new_id(bfa_name, __LINE__, ""), ID($fa)); /* A */ fa_sum_n[(fa_row_ix - 1) * fa_count + 2],
cell1->setParam(ID::WIDTH, 1); /* B */ State::S0,
cell1->setPort(ID::A, fa_sum_n[(fa_row_ix - 1) * fa_count + 2]); // from prior full adder row /* C */ cori_n_int[fa_row_ix],
cell1->setPort(ID::B, State::S0); /* X */ fa_carry_n[(fa_row_ix * fa_count) + fa_el_ix],
cell1->setPort(ID::C, cori_n_int[fa_row_ix]); /* Y */ fa_sum_n[(fa_row_ix * fa_count) + fa_el_ix]
cell1->setPort(ID::X, fa_carry_n[(fa_row_ix * fa_count) + fa_el_ix]); );
cell1->setPort(ID::Y, fa_sum_n[(fa_row_ix * fa_count) + fa_el_ix]);
fa_el_ix++; fa_el_ix++;
bfa_name = "bfa_" + std::to_string(fa_row_ix) + "_base_" + std::to_string(fa_row_ix) + "_" + module->addFa(NEW_ID_SUFFIX(stringf("bfa_base_%d_%d_L", fa_row_ix, fa_el_ix)),
std::to_string(fa_el_ix) + "_L"; /* A */ fa_sum_n[(fa_row_ix - 1) * fa_count + 3], // from prior full adder row
auto cell2 = module->addCell(new_id(bfa_name, __LINE__, ""), ID($fa)); /* B */ State::S0,
cell2->setParam(ID::WIDTH, 1); /* C */ fa_carry_n[(fa_row_ix * fa_count) + fa_el_ix - 1],
cell2->setPort(ID::A, /* X */ fa_carry_n[(fa_row_ix * fa_count) + fa_el_ix],
fa_sum_n[(fa_row_ix - 1) * fa_count + 3]); // from prior full adder row /* Y */ fa_sum_n[(fa_row_ix * fa_count) + fa_el_ix]
cell2->setPort(ID::B, State::S0); );
cell2->setPort(ID::C, fa_carry_n[(fa_row_ix * fa_count) + fa_el_ix - 1]);
cell2->setPort(ID::X, fa_carry_n[(fa_row_ix * fa_count) + fa_el_ix]);
cell2->setPort(ID::Y, fa_sum_n[(fa_row_ix * fa_count) + fa_el_ix]);
} }
else if (fa_el_ix >= 2 && fa_el_ix <= x_sz + 1) { else if (fa_el_ix >= 2 && fa_el_ix <= x_sz + 1) {
// middle (2...x_sz+1 cells) // middle (2...x_sz+1 cells)
bfa_name = "bfa_" + std::to_string(fa_row_ix) + "_step_" + std::to_string(fa_row_ix) + "_" + module->addFa(NEW_ID_SUFFIX(stringf("bfa_step_%d_%d_L", fa_row_ix, fa_el_ix)),
std::to_string(fa_el_ix) + "_L"; /* A */ fa_sum_n[(fa_row_ix - 1) * fa_count + fa_el_ix + 2],
auto cell = module->addCell(new_id(bfa_name, __LINE__, ""), ID($fa)); /* B */ PPij[(fa_row_ix + 1) * dec_count + fa_el_ix - 2],
cell->setParam(ID::WIDTH, 1); /* C */ fa_carry_n[(fa_row_ix * fa_count) + fa_el_ix - 1],
cell->setPort(ID::A, fa_sum_n[(fa_row_ix - 1) * fa_count + fa_el_ix + 2]); /* X */ fa_carry_n[(fa_row_ix * fa_count) + fa_el_ix],
cell->setPort(ID::B, PPij[(fa_row_ix + 1) * dec_count + fa_el_ix - 2]); /* Y */ fa_sum_n[(fa_row_ix * fa_count) + fa_el_ix]
cell->setPort(ID::C, fa_carry_n[(fa_row_ix * fa_count) + fa_el_ix - 1]); );
cell->setPort(ID::X, fa_carry_n[(fa_row_ix * fa_count) + fa_el_ix]);
cell->setPort(ID::Y, fa_sum_n[(fa_row_ix * fa_count) + fa_el_ix]);
} }
else if (fa_el_ix > x_sz + 1) { else if (fa_el_ix > x_sz + 1) {
// end two bits: sign extension // end two bits: sign extension
std::string se_inv_name; SigBit d_inv = module->NotGate(NEW_ID_SUFFIX(stringf("bfa_se_inv_%d_%d_L", fa_row_ix, fa_el_ix)),
se_inv_name = "bfa_" + std::to_string(fa_row_ix) + "_se_inv_" + std::to_string(fa_row_ix) + "_" + PPij[((fa_row_ix + 1) * dec_count) + dec_count - 1]);
std::to_string(fa_el_ix) + "_L";
auto cellinv = module->addCell(new_id(se_inv_name, __LINE__, ""), ID($_NOT_));
cellinv->add_strpool_attribute(ID::src, cellinv->get_strpool_attribute(ID::src));
RTLIL::Wire *d_inv = module->addWire(NEW_ID, 1);
cellinv->setPort(ID::A, PPij[((fa_row_ix + 1) * dec_count) + dec_count - 1]);
cellinv->setPort(ID::Y, d_inv);
bfa_name = "bfa_" + std::to_string(fa_row_ix) + "_se_" + std::to_string(fa_row_ix) + "_" + module->addFa(NEW_ID_SUFFIX(stringf("bfa_se_%d_%d_L", fa_row_ix, fa_el_ix)),
std::to_string(fa_el_ix) + "_L"; /* A */ fa_carry_n[((fa_row_ix - 1) * fa_count) + fa_count - 1],
auto cell1 = module->addCell(new_id(bfa_name, __LINE__, ""), ID($fa)); /* B */ d_inv,
cell1->setParam(ID::WIDTH, 1); /* C */ fa_carry_n[(fa_row_ix * fa_count) + fa_el_ix - 1],
cell1->setPort(ID::A, fa_carry_n[((fa_row_ix - 1) * fa_count) + fa_count - 1]); /* X */ fa_carry_n[(fa_row_ix * fa_count) + fa_el_ix],
cell1->setPort(ID::B, d_inv); /* Y */ fa_sum_n[(fa_row_ix * fa_count) + fa_el_ix]
cell1->setPort(ID::C, fa_carry_n[(fa_row_ix * fa_count) + fa_el_ix - 1]); );
cell1->setPort(ID::X, fa_carry_n[(fa_row_ix * fa_count) + fa_el_ix]);
cell1->setPort(ID::Y, fa_sum_n[(fa_row_ix * fa_count) + fa_el_ix]);
fa_el_ix++; fa_el_ix++;
// sign extension // sign extension
bfa_name = "bfa_" + std::to_string(fa_row_ix) + "_se_" + std::to_string(fa_row_ix) + "_" + module->addFa(NEW_ID_SUFFIX(stringf("bfa_se_%d_%d_L", fa_row_ix, fa_el_ix)),
std::to_string(fa_el_ix) + "_L"; /* A */ State::S0,
auto cell2 = module->addCell(new_id(bfa_name, __LINE__, ""), ID($fa)); /* B */ State::S1,
cell2->setParam(ID::WIDTH, 1); /* C */ fa_carry_n[(fa_row_ix * fa_count) + fa_el_ix - 1],
cell2->setPort(ID::A, State::S0); /* X */ fa_carry_n[(fa_row_ix * fa_count) + fa_el_ix],
cell2->setPort(ID::B, State::S1); /* Y */ fa_sum_n[(fa_row_ix * fa_count) + fa_el_ix]
cell2->setPort(ID::C, fa_carry_n[(fa_row_ix * fa_count) + fa_el_ix - 1]); );
cell2->setPort(ID::X, fa_carry_n[(fa_row_ix * fa_count) + fa_el_ix]);
cell2->setPort(ID::Y, fa_sum_n[(fa_row_ix * fa_count) + fa_el_ix]);
} }
} }
} }
@ -1257,13 +1163,10 @@ struct BoothPassWorker {
// instantiate the cpa // instantiate the cpa
SigSpec cpa_carry; SigSpec cpa_carry;
for (int cix = 0; cix < z_sz; cix++) { for (int cix = 0; cix < z_sz; cix++)
std::string cpa_cix_name = "cpa_carry_" + std::to_string(cix) + "_"; cpa_carry.append(module->addWire(NEW_ID_SUFFIX(stringf("cpa_carry_%d", cix)), 1));
cpa_carry.append(module->addWire(new_id(cpa_cix_name, __LINE__, ""), 1));
}
for (int cpa_ix = 0; cpa_ix < z_sz; cpa_ix++) { for (int cpa_ix = 0; cpa_ix < z_sz; cpa_ix++) {
// The end case where we pass the last two summands // The end case where we pass the last two summands
// from prior row directly to product output // from prior row directly to product output
// without using a cpa cell. This is always // without using a cpa cell. This is always
@ -1271,27 +1174,16 @@ struct BoothPassWorker {
if (cpa_ix <= fa_row_count * 2 - 1) { if (cpa_ix <= fa_row_count * 2 - 1) {
int fa_row_ix = cpa_ix / 2; int fa_row_ix = cpa_ix / 2;
std::string buf_name = module->addBufGate(NEW_ID_SUFFIX(stringf("pp_buf_%d_driven_by_fa_row_%d", cpa_ix, fa_row_ix)),
"pp_buf_" + std::to_string(cpa_ix) + "_" + "driven_by_fa_row_" + std::to_string(fa_row_ix) + "_"; fa_sum_n[(fa_row_ix * fa_count) + 0], Z[cpa_ix]);
auto buf = module->addCell(new_id(buf_name, __LINE__, ""), ID($pos));
buf->setPort(ID::A, fa_sum_n[(fa_row_ix * fa_count) + 0]);
buf->setParam(ID::A_WIDTH, 1);
buf->setParam(ID::Y_WIDTH, 1);
buf->setParam(ID::A_SIGNED, true);
buf->setPort(ID::Y, Z[cpa_ix]);
cpa_ix++; cpa_ix++;
buf_name = "pp_buf_" + std::to_string(cpa_ix) + "_" + "driven_by_fa_row_" + std::to_string(fa_row_ix) + "_"; module->addBufGate(NEW_ID_SUFFIX(stringf("pp_buf_%d_driven_by_fa_row_%d", cpa_ix, fa_row_ix)),
buf = module->addCell(new_id(buf_name, __LINE__, ""), ID($pos)); fa_sum_n[(fa_row_ix * fa_count) + 1], Z[cpa_ix]);
buf->setPort(ID::A, fa_sum_n[(fa_row_ix * fa_count) + 1]);
buf->setParam(ID::A_WIDTH, 1);
buf->setParam(ID::Y_WIDTH, 1);
buf->setParam(ID::A_SIGNED, true);
buf->setPort(ID::Y, Z[cpa_ix]);
} else { } else {
int offset = fa_row_count * 2; int offset = fa_row_count * 2;
bool base_case = cpa_ix - offset == 0 ? true : false; bool base_case = cpa_ix - offset == 0 ? true : false;
std::string cpa_name = "cpa_" + std::to_string(cpa_ix - offset) + "_"; std::string cpa_name = stringf("cpa_%d", cpa_ix - offset);
SigBit ci; SigBit ci;
if (base_case) if (base_case)