mirror of
https://github.com/YosysHQ/yosys
synced 2026-07-18 05:05:45 +00:00
WIP
This commit is contained in:
parent
015ab4e45b
commit
f592f2f3af
203 changed files with 4575 additions and 4481 deletions
|
|
@ -79,9 +79,9 @@ static void fix_carry_chain(Module *module)
|
|||
SigBit canonical_bit = sigmap(bit_ci);
|
||||
auto bit = mapping_bits.at(canonical_bit);
|
||||
log("Fixing %s cell named %s breaking carry chain.\n", cell->type.unescape(), cell);
|
||||
Cell *c = module->addCell(NEW_ID, ID(AL_MAP_ADDER));
|
||||
SigBit new_bit = module->addWire(NEW_ID);
|
||||
SigBit dummy_bit = module->addWire(NEW_ID);
|
||||
Cell *c = module->addCell(NEW_TWINE, ID(AL_MAP_ADDER));
|
||||
SigBit new_bit = module->addWire(NEW_TWINE);
|
||||
SigBit dummy_bit = module->addWire(NEW_TWINE);
|
||||
SigSpec bits;
|
||||
bits.append(dummy_bit);
|
||||
bits.append(new_bit);
|
||||
|
|
|
|||
|
|
@ -1088,7 +1088,7 @@ parameter CONFIG = 4'b0000;
|
|||
parameter CONFIG_WIDTH = 4;
|
||||
|
||||
// In the terms used for this cell, there's mixed meanings for the term "port". To disambiguate:
|
||||
// A cell port is for example the A input (it is constructed in C++ as cell->setPort(ID::A, ...))
|
||||
// A cell port is for example the A input (it is constructed in C++ as cell->setPort(TW::A, ...))
|
||||
// Multiplier ports are pairs of multiplier inputs ("factors").
|
||||
// If the second signal in such a pair is zero length, no multiplication is necessary, and the first signal is just added to the sum.
|
||||
input [A_WIDTH-1:0] A; // Cell port A is the concatenation of all arithmetic ports
|
||||
|
|
|
|||
|
|
@ -136,7 +136,7 @@ struct Coolrunner2FixupPass : public Pass {
|
|||
if (cell->type.in(ID(FDCP), ID(FDCP_N), ID(FDDCP), ID(LDCP), ID(LDCP_N),
|
||||
ID(FTCP), ID(FTCP_N), ID(FTDCP), ID(FDCPE), ID(FDCPE_N), ID(FDDCPE)))
|
||||
{
|
||||
auto output = sigmap(cell->getPort(ID::Q)[0]);
|
||||
auto output = sigmap(cell->getPort(TW::Q)[0]);
|
||||
sig_fed_by_ff.insert(output);
|
||||
}
|
||||
}
|
||||
|
|
@ -159,7 +159,7 @@ struct Coolrunner2FixupPass : public Pass {
|
|||
if (cell->type.in(ID(IBUF), ID(IOBUFE)))
|
||||
{
|
||||
if (cell->hasPort(ID::O)) {
|
||||
auto output = sigmap(cell->getPort(ID::O)[0]);
|
||||
auto output = sigmap(cell->getPort(TW::O)[0]);
|
||||
sig_fed_by_io.insert(output);
|
||||
}
|
||||
}
|
||||
|
|
@ -182,7 +182,7 @@ struct Coolrunner2FixupPass : public Pass {
|
|||
{
|
||||
if (cell->type == ID(BUFG))
|
||||
{
|
||||
auto output = sigmap(cell->getPort(ID::O)[0]);
|
||||
auto output = sigmap(cell->getPort(TW::O)[0]);
|
||||
sig_fed_by_bufg.insert(output);
|
||||
}
|
||||
}
|
||||
|
|
@ -193,7 +193,7 @@ struct Coolrunner2FixupPass : public Pass {
|
|||
{
|
||||
if (cell->type == ID(BUFGSR))
|
||||
{
|
||||
auto output = sigmap(cell->getPort(ID::O)[0]);
|
||||
auto output = sigmap(cell->getPort(TW::O)[0]);
|
||||
sig_fed_by_bufgsr.insert(output);
|
||||
}
|
||||
}
|
||||
|
|
@ -204,7 +204,7 @@ struct Coolrunner2FixupPass : public Pass {
|
|||
{
|
||||
if (cell->type == ID(BUFGTS))
|
||||
{
|
||||
auto output = sigmap(cell->getPort(ID::O)[0]);
|
||||
auto output = sigmap(cell->getPort(TW::O)[0]);
|
||||
sig_fed_by_bufgts.insert(output);
|
||||
}
|
||||
}
|
||||
|
|
@ -215,7 +215,7 @@ struct Coolrunner2FixupPass : public Pass {
|
|||
{
|
||||
if (cell->type == ID(IBUF))
|
||||
{
|
||||
auto output = sigmap(cell->getPort(ID::O)[0]);
|
||||
auto output = sigmap(cell->getPort(TW::O)[0]);
|
||||
sig_fed_by_ibuf.insert(output);
|
||||
}
|
||||
}
|
||||
|
|
@ -259,10 +259,10 @@ struct Coolrunner2FixupPass : public Pass {
|
|||
{
|
||||
SigBit input;
|
||||
if (maybe_ff_cell->type.in(ID(FTCP), ID(FTCP_N), ID(FTDCP)))
|
||||
input = sigmap(maybe_ff_cell->getPort(ID::T)[0]);
|
||||
input = sigmap(maybe_ff_cell->getPort(TW::T)[0]);
|
||||
else
|
||||
input = sigmap(maybe_ff_cell->getPort(ID::D)[0]);
|
||||
SigBit output = sigmap(maybe_ff_cell->getPort(ID::Q)[0]);
|
||||
input = sigmap(maybe_ff_cell->getPort(TW::D)[0]);
|
||||
SigBit output = sigmap(maybe_ff_cell->getPort(TW::Q)[0]);
|
||||
|
||||
if (input == ibuf_out_wire)
|
||||
{
|
||||
|
|
@ -287,9 +287,9 @@ struct Coolrunner2FixupPass : public Pass {
|
|||
// to be inserted.
|
||||
SigBit input;
|
||||
if (cell->type.in(ID(FTCP), ID(FTCP_N), ID(FTDCP)))
|
||||
input = sigmap(cell->getPort(ID::T)[0]);
|
||||
input = sigmap(cell->getPort(TW::T)[0]);
|
||||
else
|
||||
input = sigmap(cell->getPort(ID::D)[0]);
|
||||
input = sigmap(cell->getPort(TW::D)[0]);
|
||||
|
||||
// If the input wasn't an XOR nor an IO, then a buffer
|
||||
// definitely needs to be added.
|
||||
|
|
@ -303,9 +303,9 @@ struct Coolrunner2FixupPass : public Pass {
|
|||
auto xor_to_ff_wire = makexorbuffer(module, input, cell->name.c_str());
|
||||
|
||||
if (cell->type.in(ID(FTCP), ID(FTCP_N), ID(FTDCP)))
|
||||
cell->setPort(ID::T, xor_to_ff_wire);
|
||||
cell->setPort(TW::T, xor_to_ff_wire);
|
||||
else
|
||||
cell->setPort(ID::D, xor_to_ff_wire);
|
||||
cell->setPort(TW::D, xor_to_ff_wire);
|
||||
}
|
||||
|
||||
// Buffering FF clocks. FF clocks can only come from either
|
||||
|
|
@ -314,9 +314,9 @@ struct Coolrunner2FixupPass : public Pass {
|
|||
// AND-ing two signals) but not in all cases.
|
||||
SigBit clock;
|
||||
if (cell->type.in(ID(LDCP), ID(LDCP_N)))
|
||||
clock = sigmap(cell->getPort(ID::G)[0]);
|
||||
clock = sigmap(cell->getPort(TW::G)[0]);
|
||||
else
|
||||
clock = sigmap(cell->getPort(ID::C)[0]);
|
||||
clock = sigmap(cell->getPort(TW::C)[0]);
|
||||
|
||||
if (!sig_fed_by_pterm[clock] && !sig_fed_by_bufg[clock])
|
||||
{
|
||||
|
|
@ -325,9 +325,9 @@ struct Coolrunner2FixupPass : public Pass {
|
|||
auto pterm_to_ff_wire = makeptermbuffer(module, clock);
|
||||
|
||||
if (cell->type.in(ID(LDCP), ID(LDCP_N)))
|
||||
cell->setPort(ID::G, pterm_to_ff_wire);
|
||||
cell->setPort(TW::G, pterm_to_ff_wire);
|
||||
else
|
||||
cell->setPort(ID::C, pterm_to_ff_wire);
|
||||
cell->setPort(TW::C, pterm_to_ff_wire);
|
||||
}
|
||||
|
||||
// Buffering FF set/reset. This can only come from either
|
||||
|
|
@ -347,7 +347,7 @@ struct Coolrunner2FixupPass : public Pass {
|
|||
}
|
||||
|
||||
SigBit reset;
|
||||
reset = sigmap(cell->getPort(ID::CLR)[0]);
|
||||
reset = sigmap(cell->getPort(TW::CLR)[0]);
|
||||
if (reset != SigBit(false))
|
||||
{
|
||||
if (!sig_fed_by_pterm[reset] && !sig_fed_by_bufgsr[reset])
|
||||
|
|
@ -356,7 +356,7 @@ struct Coolrunner2FixupPass : public Pass {
|
|||
|
||||
auto pterm_to_ff_wire = makeptermbuffer(module, reset);
|
||||
|
||||
cell->setPort(ID::CLR, pterm_to_ff_wire);
|
||||
cell->setPort(TW::CLR, pterm_to_ff_wire);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -384,7 +384,7 @@ struct Coolrunner2FixupPass : public Pass {
|
|||
if (cell->type == ID(IOBUFE))
|
||||
{
|
||||
// Buffer IOBUFE inputs. This can only be fed from an XOR or FF.
|
||||
SigBit input = sigmap(cell->getPort(ID::I)[0]);
|
||||
SigBit input = sigmap(cell->getPort(TW::I)[0]);
|
||||
|
||||
if ((!sig_fed_by_xor[input] && !sig_fed_by_ff[input]) ||
|
||||
packed_reg_out[input])
|
||||
|
|
@ -393,7 +393,7 @@ struct Coolrunner2FixupPass : public Pass {
|
|||
|
||||
auto xor_to_io_wire = makexorbuffer(module, input, cell->name.c_str());
|
||||
|
||||
cell->setPort(ID::I, xor_to_io_wire);
|
||||
cell->setPort(TW::I, xor_to_io_wire);
|
||||
}
|
||||
|
||||
// Buffer IOBUFE enables. This can only be fed from a pterm
|
||||
|
|
@ -401,14 +401,14 @@ struct Coolrunner2FixupPass : public Pass {
|
|||
if (cell->hasPort(ID::E))
|
||||
{
|
||||
SigBit oe;
|
||||
oe = sigmap(cell->getPort(ID::E)[0]);
|
||||
oe = sigmap(cell->getPort(TW::E)[0]);
|
||||
if (!sig_fed_by_pterm[oe] && !sig_fed_by_bufgts[oe])
|
||||
{
|
||||
log("Buffering output enable to \"%s\"\n", cell->name);
|
||||
|
||||
auto pterm_to_oe_wire = makeptermbuffer(module, oe);
|
||||
|
||||
cell->setPort(ID::E, pterm_to_oe_wire);
|
||||
cell->setPort(TW::E, pterm_to_oe_wire);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,8 +49,8 @@ struct Coolrunner2SopPass : public Pass {
|
|||
{
|
||||
if (cell->type == ID($_NOT_))
|
||||
{
|
||||
auto not_input = sigmap(cell->getPort(ID::A)[0]);
|
||||
auto not_output = sigmap(cell->getPort(ID::Y)[0]);
|
||||
auto not_input = sigmap(cell->getPort(TW::A)[0]);
|
||||
auto not_output = sigmap(cell->getPort(TW::Y)[0]);
|
||||
not_cells[not_input] = tuple<SigBit, Cell*>(not_output, cell);
|
||||
}
|
||||
}
|
||||
|
|
@ -67,17 +67,17 @@ struct Coolrunner2SopPass : public Pass {
|
|||
special_pterms_no_inv[sigmap(cell->getPort(ID(PRE))[0])].insert(
|
||||
make_tuple(cell, ID(PRE)));
|
||||
if (cell->hasPort(ID::CLR))
|
||||
special_pterms_no_inv[sigmap(cell->getPort(ID::CLR)[0])].insert(
|
||||
special_pterms_no_inv[sigmap(cell->getPort(TW::CLR)[0])].insert(
|
||||
make_tuple(cell, ID::CLR));
|
||||
if (cell->hasPort(ID(CE)))
|
||||
special_pterms_no_inv[sigmap(cell->getPort(ID(CE))[0])].insert(
|
||||
make_tuple(cell, ID(CE)));
|
||||
|
||||
if (cell->hasPort(ID::C))
|
||||
special_pterms_inv[sigmap(cell->getPort(ID::C)[0])].insert(
|
||||
special_pterms_inv[sigmap(cell->getPort(TW::C)[0])].insert(
|
||||
make_tuple(cell, ID::C));
|
||||
if (cell->hasPort(ID::G))
|
||||
special_pterms_inv[sigmap(cell->getPort(ID::G)[0])].insert(
|
||||
special_pterms_inv[sigmap(cell->getPort(TW::G)[0])].insert(
|
||||
make_tuple(cell, ID::G));
|
||||
}
|
||||
}
|
||||
|
|
@ -88,8 +88,8 @@ struct Coolrunner2SopPass : public Pass {
|
|||
if (cell->type == ID($sop))
|
||||
{
|
||||
// Read the inputs/outputs/parameters of the $sop cell
|
||||
auto sop_inputs = sigmap(cell->getPort(ID::A));
|
||||
auto sop_output = sigmap(cell->getPort(ID::Y))[0];
|
||||
auto sop_inputs = sigmap(cell->getPort(TW::A));
|
||||
auto sop_output = sigmap(cell->getPort(TW::Y))[0];
|
||||
auto sop_depth = cell->getParam(ID::DEPTH).as_int();
|
||||
auto sop_width = cell->getParam(ID::WIDTH).as_int();
|
||||
auto sop_table = cell->getParam(ID::TABLE);
|
||||
|
|
|
|||
|
|
@ -43,8 +43,8 @@ static void fix_carry_chain(Module *module)
|
|||
SigBit bit_i0 = get_bit_or_zero(cell->getPort(ID(I0)));
|
||||
SigBit bit_i1 = get_bit_or_zero(cell->getPort(ID(I1)));
|
||||
if (bit_i0 == State::S0 && bit_i1== State::S0) {
|
||||
SigBit bit_ci = get_bit_or_zero(cell->getPort(ID::CI));
|
||||
SigBit bit_o = sigmap(cell->getPort(ID::O));
|
||||
SigBit bit_ci = get_bit_or_zero(cell->getPort(TW::CI));
|
||||
SigBit bit_o = sigmap(cell->getPort(TW::O));
|
||||
ci_bits.insert(bit_ci);
|
||||
mapping_bits[bit_ci] = bit_o;
|
||||
}
|
||||
|
|
@ -55,7 +55,7 @@ static void fix_carry_chain(Module *module)
|
|||
for (auto cell : module->cells())
|
||||
{
|
||||
if (cell->type == ID(EFX_ADD)) {
|
||||
SigBit bit_ci = get_bit_or_zero(cell->getPort(ID::CI));
|
||||
SigBit bit_ci = get_bit_or_zero(cell->getPort(TW::CI));
|
||||
SigBit bit_i0 = get_bit_or_zero(cell->getPort(ID(I0)));
|
||||
SigBit bit_i1 = get_bit_or_zero(cell->getPort(ID(I1)));
|
||||
SigBit canonical_bit = sigmap(bit_ci);
|
||||
|
|
@ -71,20 +71,20 @@ static void fix_carry_chain(Module *module)
|
|||
|
||||
for (auto cell : adders_to_fix_cells)
|
||||
{
|
||||
SigBit bit_ci = get_bit_or_zero(cell->getPort(ID::CI));
|
||||
SigBit bit_ci = get_bit_or_zero(cell->getPort(TW::CI));
|
||||
SigBit canonical_bit = sigmap(bit_ci);
|
||||
auto bit = mapping_bits.at(canonical_bit);
|
||||
log("Fixing %s cell named %s breaking carry chain.\n", cell->type.unescape(), cell);
|
||||
Cell *c = module->addCell(NEW_ID, ID(EFX_ADD));
|
||||
SigBit new_bit = module->addWire(NEW_ID);
|
||||
Cell *c = module->addCell(NEW_TWINE, ID(EFX_ADD));
|
||||
SigBit new_bit = module->addWire(NEW_TWINE);
|
||||
c->setParam(ID(I0_POLARITY), State::S1);
|
||||
c->setParam(ID(I1_POLARITY), State::S1);
|
||||
c->setPort(ID(I0), bit);
|
||||
c->setPort(ID(I1), State::S1);
|
||||
c->setPort(ID::CI, State::S0);
|
||||
c->setPort(ID::CO, new_bit);
|
||||
c->setPort(TW::CI, State::S0);
|
||||
c->setPort(TW::CO, new_bit);
|
||||
|
||||
cell->setPort(ID::CI, new_bit);
|
||||
cell->setPort(TW::CI, new_bit);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -70,8 +70,8 @@ struct FoldInvWorker {
|
|||
for (auto cell : module->selected_cells()) {
|
||||
if (cell->type != ID($__CC_NOT))
|
||||
continue;
|
||||
SigBit a = sigmap(cell->getPort(ID::A)[0]);
|
||||
SigBit y = sigmap(cell->getPort(ID::Y)[0]);
|
||||
SigBit a = sigmap(cell->getPort(TW::A)[0]);
|
||||
SigBit y = sigmap(cell->getPort(TW::Y)[0]);
|
||||
inverted_bits[y] = a;
|
||||
inverter_input[a] = cell;
|
||||
}
|
||||
|
|
@ -143,7 +143,7 @@ struct FoldInvWorker {
|
|||
continue;
|
||||
if (!cell->hasPort(ID::O))
|
||||
continue;
|
||||
auto o_sig = cell->getPort(ID::O);
|
||||
auto o_sig = cell->getPort(TW::O);
|
||||
if (GetSize(o_sig) == 0)
|
||||
continue;
|
||||
SigBit o = sigmap(o_sig[0]);
|
||||
|
|
@ -156,15 +156,15 @@ struct FoldInvWorker {
|
|||
Cell *orig_lut = pair.first;
|
||||
Cell *inv = pair.second;
|
||||
// Find the inverter output
|
||||
SigBit inv_y = sigmap(inv->getPort(ID::Y)[0]);
|
||||
SigBit inv_y = sigmap(inv->getPort(TW::Y)[0]);
|
||||
// Inverter output might not actually be used; if all users were folded into inputs already
|
||||
if (!used_bits.count(inv_y))
|
||||
continue;
|
||||
// Create a duplicate of the LUT with an inverted output
|
||||
// (if the uninverted version becomes unused it will be swept away)
|
||||
Cell *dup_lut = module->addCell(NEW_ID, orig_lut->type);
|
||||
inv->unsetPort(ID::Y);
|
||||
dup_lut->setPort(ID::O, inv_y);
|
||||
Cell *dup_lut = module->addCell(NEW_TWINE, orig_lut->type);
|
||||
inv->unsetPort(TW::Y);
|
||||
dup_lut->setPort(TW::O, inv_y);
|
||||
for (auto conn : orig_lut->connections()) {
|
||||
if (conn.first == ID::O)
|
||||
continue;
|
||||
|
|
|
|||
|
|
@ -71,12 +71,12 @@ void invert_gp_dff(Cell *cell, bool invert_input)
|
|||
}
|
||||
|
||||
if (cell_type_i) {
|
||||
cell->setPort(ID::Q, cell->getPort(ID(nQ)));
|
||||
cell->setPort(TW::Q, cell->getPort(ID(nQ)));
|
||||
cell->unsetPort(ID(nQ));
|
||||
cell_type_i = false;
|
||||
} else {
|
||||
cell->setPort(ID(nQ), cell->getPort(ID::Q));
|
||||
cell->unsetPort(ID::Q);
|
||||
cell->setPort(ID(nQ), cell->getPort(TW::Q));
|
||||
cell->unsetPort(TW::Q);
|
||||
cell_type_i = true;
|
||||
}
|
||||
|
||||
|
|
@ -175,15 +175,15 @@ struct Greenpak4DffInvPass : public Pass {
|
|||
|
||||
for (auto cell : dff_cells)
|
||||
{
|
||||
SigBit d_bit = sigmap(cell->getPort(ID::D));
|
||||
SigBit q_bit = sigmap(cell->hasPort(ID::Q) ? cell->getPort(ID::Q) : cell->getPort(ID(nQ)));
|
||||
SigBit d_bit = sigmap(cell->getPort(TW::D));
|
||||
SigBit q_bit = sigmap(cell->hasPort(ID::Q) ? cell->getPort(TW::Q) : cell->getPort(ID(nQ)));
|
||||
|
||||
while (inv_out2in.count(d_bit))
|
||||
{
|
||||
sig_use_cnt[d_bit]--;
|
||||
invert_gp_dff(cell, true);
|
||||
d_bit = inv_out2in.at(d_bit);
|
||||
cell->setPort(ID::D, d_bit);
|
||||
cell->setPort(TW::D, d_bit);
|
||||
sig_use_cnt[d_bit]++;
|
||||
}
|
||||
|
||||
|
|
@ -198,7 +198,7 @@ struct Greenpak4DffInvPass : public Pass {
|
|||
|
||||
invert_gp_dff(cell, false);
|
||||
if (cell->hasPort(ID::Q))
|
||||
cell->setPort(ID::Q, new_q_bit);
|
||||
cell->setPort(TW::Q, new_q_bit);
|
||||
else
|
||||
cell->setPort(ID(nQ), new_q_bit);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ void create_ice40_dsp(ice40_dsp_pm &pm)
|
|||
if (cell->type == ID($mul)) {
|
||||
log(" replacing %s with SB_MAC16 cell.\n", st.mul->type.unescape());
|
||||
|
||||
cell = pm.module->addCell(NEW_ID, ID(SB_MAC16));
|
||||
cell = pm.module->addCell(NEW_TWINE, ID(SB_MAC16));
|
||||
pm.module->swap_names(cell, st.mul);
|
||||
}
|
||||
else log_assert(cell->type == ID(SB_MAC16));
|
||||
|
|
@ -86,10 +86,10 @@ void create_ice40_dsp(ice40_dsp_pm &pm)
|
|||
else
|
||||
log_assert(GetSize(CD) == 32);
|
||||
|
||||
cell->setPort(ID::A, A);
|
||||
cell->setPort(ID::B, B);
|
||||
cell->setPort(ID::C, CD.extract(16, 16));
|
||||
cell->setPort(ID::D, CD.extract(0, 16));
|
||||
cell->setPort(TW::A, A);
|
||||
cell->setPort(TW::B, B);
|
||||
cell->setPort(TW::C, CD.extract(16, 16));
|
||||
cell->setPort(TW::D, CD.extract(0, 16));
|
||||
|
||||
cell->setParam(ID(A_REG), st.ffA ? State::S1 : State::S0);
|
||||
cell->setParam(ID(B_REG), st.ffB ? State::S1 : State::S0);
|
||||
|
|
@ -98,15 +98,15 @@ void create_ice40_dsp(ice40_dsp_pm &pm)
|
|||
|
||||
SigSpec AHOLD, BHOLD, CDHOLD;
|
||||
if (st.ffA && st.ffA->hasPort(ID::EN))
|
||||
AHOLD = st.ffA->getParam(ID::EN_POLARITY).as_bool() ? pm.module->Not(NEW_ID, st.ffA->getPort(ID::EN)) : st.ffA->getPort(ID::EN);
|
||||
AHOLD = st.ffA->getParam(ID::EN_POLARITY).as_bool() ? pm.module->Not(NEW_ID, st.ffA->getPort(TW::EN)) : st.ffA->getPort(TW::EN);
|
||||
else
|
||||
AHOLD = State::S0;
|
||||
if (st.ffB && st.ffB->hasPort(ID::EN))
|
||||
BHOLD = st.ffB->getParam(ID::EN_POLARITY).as_bool() ? pm.module->Not(NEW_ID, st.ffB->getPort(ID::EN)) : st.ffB->getPort(ID::EN);
|
||||
BHOLD = st.ffB->getParam(ID::EN_POLARITY).as_bool() ? pm.module->Not(NEW_ID, st.ffB->getPort(TW::EN)) : st.ffB->getPort(TW::EN);
|
||||
else
|
||||
BHOLD = State::S0;
|
||||
if (st.ffCD && st.ffCD->hasPort(ID::EN))
|
||||
CDHOLD = st.ffCD->getParam(ID::EN_POLARITY).as_bool() ? pm.module->Not(NEW_ID, st.ffCD->getPort(ID::EN)) : st.ffCD->getPort(ID::EN);
|
||||
CDHOLD = st.ffCD->getParam(ID::EN_POLARITY).as_bool() ? pm.module->Not(NEW_ID, st.ffCD->getPort(TW::EN)) : st.ffCD->getPort(TW::EN);
|
||||
else
|
||||
CDHOLD = State::S0;
|
||||
cell->setPort(ID(AHOLD), AHOLD);
|
||||
|
|
@ -116,11 +116,11 @@ void create_ice40_dsp(ice40_dsp_pm &pm)
|
|||
|
||||
SigSpec IRSTTOP, IRSTBOT;
|
||||
if (st.ffA && st.ffA->hasPort(ID::ARST))
|
||||
IRSTTOP = st.ffA->getParam(ID::ARST_POLARITY).as_bool() ? st.ffA->getPort(ID::ARST) : pm.module->Not(NEW_ID, st.ffA->getPort(ID::ARST));
|
||||
IRSTTOP = st.ffA->getParam(ID::ARST_POLARITY).as_bool() ? st.ffA->getPort(TW::ARST) : pm.module->Not(NEW_ID, st.ffA->getPort(TW::ARST));
|
||||
else
|
||||
IRSTTOP = State::S0;
|
||||
if (st.ffB && st.ffB->hasPort(ID::ARST))
|
||||
IRSTBOT = st.ffB->getParam(ID::ARST_POLARITY).as_bool() ? st.ffB->getPort(ID::ARST) : pm.module->Not(NEW_ID, st.ffB->getPort(ID::ARST));
|
||||
IRSTBOT = st.ffB->getParam(ID::ARST_POLARITY).as_bool() ? st.ffB->getPort(TW::ARST) : pm.module->Not(NEW_ID, st.ffB->getPort(TW::ARST));
|
||||
else
|
||||
IRSTBOT = State::S0;
|
||||
cell->setPort(ID(IRSTTOP), IRSTTOP);
|
||||
|
|
@ -128,7 +128,7 @@ void create_ice40_dsp(ice40_dsp_pm &pm)
|
|||
|
||||
if (st.clock != SigBit())
|
||||
{
|
||||
cell->setPort(ID::CLK, st.clock);
|
||||
cell->setPort(TW::CLK, st.clock);
|
||||
cell->setPort(ID(CE), State::S1);
|
||||
cell->setParam(ID(NEG_TRIGGER), st.clock_pol ? State::S0 : State::S1);
|
||||
|
||||
|
|
@ -156,7 +156,7 @@ void create_ice40_dsp(ice40_dsp_pm &pm)
|
|||
}
|
||||
else
|
||||
{
|
||||
cell->setPort(ID::CLK, State::S0);
|
||||
cell->setPort(TW::CLK, State::S0);
|
||||
cell->setPort(ID(CE), State::S0);
|
||||
cell->setParam(ID(NEG_TRIGGER), State::S0);
|
||||
}
|
||||
|
|
@ -164,12 +164,12 @@ void create_ice40_dsp(ice40_dsp_pm &pm)
|
|||
// SB_MAC16 Cascade Interface
|
||||
|
||||
cell->setPort(ID(SIGNEXTIN), State::Sx);
|
||||
cell->setPort(ID(SIGNEXTOUT), pm.module->addWire(NEW_ID));
|
||||
cell->setPort(ID(SIGNEXTOUT), pm.module->addWire(NEW_TWINE));
|
||||
|
||||
cell->setPort(ID::CI, State::Sx);
|
||||
cell->setPort(TW::CI, State::Sx);
|
||||
|
||||
cell->setPort(ID(ACCUMCI), State::Sx);
|
||||
cell->setPort(ID(ACCUMCO), pm.module->addWire(NEW_ID));
|
||||
cell->setPort(ID(ACCUMCO), pm.module->addWire(NEW_TWINE));
|
||||
|
||||
// SB_MAC16 Output Interface
|
||||
|
||||
|
|
@ -181,16 +181,16 @@ void create_ice40_dsp(ice40_dsp_pm &pm)
|
|||
if (st.add->getParam(ID::A_SIGNED).as_bool() && st.add->getParam(ID::B_SIGNED).as_bool())
|
||||
pm.module->connect(O[32], O[31]);
|
||||
else
|
||||
cell->setPort(ID::CO, O[32]);
|
||||
cell->setPort(TW::CO, O[32]);
|
||||
O.remove(O_width-1);
|
||||
}
|
||||
else
|
||||
cell->setPort(ID::CO, pm.module->addWire(NEW_ID));
|
||||
cell->setPort(TW::CO, pm.module->addWire(NEW_TWINE));
|
||||
log_assert(GetSize(O) <= 32);
|
||||
if (GetSize(O) < 32)
|
||||
O.append(pm.module->addWire(NEW_ID, 32-GetSize(O)));
|
||||
O.append(pm.module->addWire(NEW_TWINE, 32-GetSize(O)));
|
||||
|
||||
cell->setPort(ID::O, O);
|
||||
cell->setPort(TW::O, O);
|
||||
|
||||
bool accum = false;
|
||||
if (st.add) {
|
||||
|
|
@ -208,7 +208,7 @@ void create_ice40_dsp(ice40_dsp_pm &pm)
|
|||
|
||||
SigSpec OHOLD;
|
||||
if (st.ffO && st.ffO->hasPort(ID::EN))
|
||||
OHOLD = st.ffO->getParam(ID::EN_POLARITY).as_bool() ? pm.module->Not(NEW_ID, st.ffO->getPort(ID::EN)) : st.ffO->getPort(ID::EN);
|
||||
OHOLD = st.ffO->getParam(ID::EN_POLARITY).as_bool() ? pm.module->Not(NEW_ID, st.ffO->getPort(TW::EN)) : st.ffO->getPort(TW::EN);
|
||||
else
|
||||
OHOLD = State::S0;
|
||||
cell->setPort(ID(OHOLDTOP), OHOLD);
|
||||
|
|
@ -216,7 +216,7 @@ void create_ice40_dsp(ice40_dsp_pm &pm)
|
|||
|
||||
SigSpec ORST;
|
||||
if (st.ffO && st.ffO->hasPort(ID::ARST))
|
||||
ORST = st.ffO->getParam(ID::ARST_POLARITY).as_bool() ? st.ffO->getPort(ID::ARST) : pm.module->Not(NEW_ID, st.ffO->getPort(ID::ARST));
|
||||
ORST = st.ffO->getParam(ID::ARST_POLARITY).as_bool() ? st.ffO->getPort(TW::ARST) : pm.module->Not(NEW_ID, st.ffO->getPort(TW::ARST));
|
||||
else
|
||||
ORST = State::S0;
|
||||
cell->setPort(ID(ORSTTOP), ORST);
|
||||
|
|
@ -225,11 +225,11 @@ void create_ice40_dsp(ice40_dsp_pm &pm)
|
|||
SigSpec acc_reset = State::S0;
|
||||
if (st.mux) {
|
||||
if (st.muxAB == ID::A)
|
||||
acc_reset = st.mux->getPort(ID::S);
|
||||
acc_reset = st.mux->getPort(TW::S);
|
||||
else
|
||||
acc_reset = pm.module->Not(NEW_ID, st.mux->getPort(ID::S));
|
||||
acc_reset = pm.module->Not(NEW_ID, st.mux->getPort(TW::S));
|
||||
} else if (st.ffO && st.ffO->hasPort(ID::SRST)) {
|
||||
acc_reset = st.ffO->getParam(ID::SRST_POLARITY).as_bool() ? st.ffO->getPort(ID::SRST) : pm.module->Not(NEW_ID, st.ffO->getPort(ID::SRST));
|
||||
acc_reset = st.ffO->getParam(ID::SRST_POLARITY).as_bool() ? st.ffO->getPort(TW::SRST) : pm.module->Not(NEW_ID, st.ffO->getPort(TW::SRST));
|
||||
}
|
||||
cell->setPort(ID(OLOADTOP), acc_reset);
|
||||
cell->setPort(ID(OLOADBOT), acc_reset);
|
||||
|
|
@ -259,7 +259,7 @@ void create_ice40_dsp(ice40_dsp_pm &pm)
|
|||
else
|
||||
cell->setParam(ID(TOPOUTPUT_SELECT), Const(1, 2));
|
||||
|
||||
st.ffO->connections_.at(ID::Q).replace(O, pm.module->addWire(NEW_ID, GetSize(O)));
|
||||
st.ffO->connections_.at(ID::Q).replace(O, pm.module->addWire(NEW_TWINE, GetSize(O)));
|
||||
cell->setParam(ID(BOTOUTPUT_SELECT), Const(1, 2));
|
||||
}
|
||||
else {
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ code sigA sigB sigH
|
|||
wire_width++;
|
||||
else {
|
||||
if (wire_width) { // add empty wires for bit offset if needed
|
||||
sigH.append(module->addWire(NEW_ID, wire_width));
|
||||
sigH.append(module->addWire(NEW_TWINE, wire_width));
|
||||
wire_width = 0;
|
||||
}
|
||||
sigH.append(O[j]);
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ static void run_ice40_opts(Module *module)
|
|||
SigBit inbit[3] = {
|
||||
get_bit_or_zero(cell->getPort(ID(I0))),
|
||||
get_bit_or_zero(cell->getPort(ID(I1))),
|
||||
get_bit_or_zero(cell->getPort(ID::CI))
|
||||
get_bit_or_zero(cell->getPort(TW::CI))
|
||||
};
|
||||
for (int i = 0; i < 3; i++)
|
||||
if (inbit[i].wire == nullptr) {
|
||||
|
|
@ -79,8 +79,8 @@ static void run_ice40_opts(Module *module)
|
|||
replacement_output = non_const_inputs;
|
||||
|
||||
if (GetSize(replacement_output)) {
|
||||
optimized_co.insert(sigmap(cell->getPort(ID::CO)[0]));
|
||||
module->connect(cell->getPort(ID::CO)[0], replacement_output);
|
||||
optimized_co.insert(sigmap(cell->getPort(TW::CO)[0]));
|
||||
module->connect(cell->getPort(TW::CO)[0], replacement_output);
|
||||
module->design->scratchpad_set_bool("opt.did_something", true);
|
||||
log("Optimized away SB_CARRY cell %s.%s: CO=%s\n",
|
||||
module, cell, log_signal(replacement_output));
|
||||
|
|
@ -95,9 +95,9 @@ static void run_ice40_opts(Module *module)
|
|||
int count_zeros = 0, count_ones = 0;
|
||||
|
||||
SigBit inbit[3] = {
|
||||
cell->getPort(ID::A),
|
||||
cell->getPort(ID::B),
|
||||
cell->getPort(ID::CI)
|
||||
cell->getPort(TW::A),
|
||||
cell->getPort(TW::B),
|
||||
cell->getPort(TW::CI)
|
||||
};
|
||||
for (int i = 0; i < 3; i++)
|
||||
if (inbit[i].wire == nullptr) {
|
||||
|
|
@ -116,7 +116,7 @@ static void run_ice40_opts(Module *module)
|
|||
replacement_output = non_const_inputs;
|
||||
|
||||
if (GetSize(replacement_output)) {
|
||||
optimized_co.insert(sigmap(cell->getPort(ID::CO)[0]));
|
||||
optimized_co.insert(sigmap(cell->getPort(TW::CO)[0]));
|
||||
auto it = cell->attributes.find(IdString{"\\SB_LUT4.name"});
|
||||
if (it != cell->attributes.end()) {
|
||||
module->rename(cell, it->second.decode_string());
|
||||
|
|
@ -134,20 +134,20 @@ static void run_ice40_opts(Module *module)
|
|||
log_abort();
|
||||
cell->attributes = std::move(new_attr);
|
||||
}
|
||||
module->connect(cell->getPort(ID::CO)[0], replacement_output);
|
||||
module->connect(cell->getPort(TW::CO)[0], replacement_output);
|
||||
module->design->scratchpad_set_bool("opt.did_something", true);
|
||||
log("Optimized $__ICE40_CARRY_WRAPPER cell back to logic (without SB_CARRY) %s.%s: CO=%s\n",
|
||||
module, cell, log_signal(replacement_output));
|
||||
cell->type = ID($lut);
|
||||
auto I3 = get_bit_or_zero(cell->getPort(cell->getParam(ID(I3_IS_CI)).as_bool() ? ID::CI : ID(I3)));
|
||||
cell->setPort(ID::A, { I3, inbit[1], inbit[0], get_bit_or_zero(cell->getPort(ID(I0))) });
|
||||
cell->setPort(ID::Y, cell->getPort(ID::O));
|
||||
cell->unsetPort(ID::B);
|
||||
cell->unsetPort(ID::CI);
|
||||
cell->setPort(TW::A, { I3, inbit[1], inbit[0], get_bit_or_zero(cell->getPort(ID(I0))) });
|
||||
cell->setPort(TW::Y, cell->getPort(TW::O));
|
||||
cell->unsetPort(TW::B);
|
||||
cell->unsetPort(TW::CI);
|
||||
cell->unsetPort(ID(I0));
|
||||
cell->unsetPort(ID(I3));
|
||||
cell->unsetPort(ID::CO);
|
||||
cell->unsetPort(ID::O);
|
||||
cell->unsetPort(TW::CO);
|
||||
cell->unsetPort(TW::O);
|
||||
cell->setParam(ID::WIDTH, 4);
|
||||
cell->unsetParam(ID(I3_IS_CI));
|
||||
}
|
||||
|
|
@ -182,18 +182,18 @@ static void run_ice40_opts(Module *module)
|
|||
cell->setParam(ID::LUT, cell->getParam(ID(LUT_INIT)));
|
||||
cell->unsetParam(ID(LUT_INIT));
|
||||
|
||||
cell->setPort(ID::A, SigSpec({
|
||||
cell->setPort(TW::A, SigSpec({
|
||||
get_bit_or_zero(cell->getPort(ID(I3))),
|
||||
get_bit_or_zero(cell->getPort(ID(I2))),
|
||||
get_bit_or_zero(cell->getPort(ID(I1))),
|
||||
get_bit_or_zero(cell->getPort(ID(I0)))
|
||||
}));
|
||||
cell->setPort(ID::Y, cell->getPort(ID::O)[0]);
|
||||
cell->setPort(TW::Y, cell->getPort(TW::O)[0]);
|
||||
cell->unsetPort(ID(I0));
|
||||
cell->unsetPort(ID(I1));
|
||||
cell->unsetPort(ID(I2));
|
||||
cell->unsetPort(ID(I3));
|
||||
cell->unsetPort(ID::O);
|
||||
cell->unsetPort(TW::O);
|
||||
|
||||
cell->check();
|
||||
simplemap_lut(module, cell);
|
||||
|
|
|
|||
|
|
@ -37,14 +37,14 @@ void create_ice40_wrapcarry(ice40_wrapcarry_pm &pm)
|
|||
|
||||
log(" replacing SB_LUT + SB_CARRY with $__ICE40_CARRY_WRAPPER cell.\n");
|
||||
|
||||
Cell *cell = pm.module->addCell(NEW_ID, ID($__ICE40_CARRY_WRAPPER));
|
||||
Cell *cell = pm.module->addCell(NEW_TWINE, ID($__ICE40_CARRY_WRAPPER));
|
||||
pm.module->swap_names(cell, st.carry);
|
||||
|
||||
cell->setPort(ID::A, st.carry->getPort(ID(I0)));
|
||||
cell->setPort(ID::B, st.carry->getPort(ID(I1)));
|
||||
auto CI = st.carry->getPort(ID::CI);
|
||||
cell->setPort(ID::CI, CI);
|
||||
cell->setPort(ID::CO, st.carry->getPort(ID::CO));
|
||||
cell->setPort(TW::A, st.carry->getPort(ID(I0)));
|
||||
cell->setPort(TW::B, st.carry->getPort(ID(I1)));
|
||||
auto CI = st.carry->getPort(TW::CI);
|
||||
cell->setPort(TW::CI, CI);
|
||||
cell->setPort(TW::CO, st.carry->getPort(TW::CO));
|
||||
|
||||
cell->setPort(ID(I0), st.lut->getPort(ID(I0)));
|
||||
auto I3 = st.lut->getPort(ID(I3));
|
||||
|
|
@ -55,7 +55,7 @@ void create_ice40_wrapcarry(ice40_wrapcarry_pm &pm)
|
|||
else
|
||||
cell->setParam(ID(I3_IS_CI), State::S0);
|
||||
cell->setPort(ID(I3), I3);
|
||||
cell->setPort(ID::O, st.lut->getPort(ID::O));
|
||||
cell->setPort(TW::O, st.lut->getPort(TW::O));
|
||||
cell->setParam(ID::LUT, st.lut->getParam(ID(LUT_INIT)));
|
||||
|
||||
for (const auto &a : st.carry->attributes)
|
||||
|
|
@ -134,19 +134,19 @@ struct Ice40WrapCarryPass : public Pass {
|
|||
if (cell->type != ID($__ICE40_CARRY_WRAPPER))
|
||||
continue;
|
||||
|
||||
auto carry = module->addCell(NEW_ID, ID(SB_CARRY));
|
||||
carry->setPort(ID(I0), cell->getPort(ID::A));
|
||||
carry->setPort(ID(I1), cell->getPort(ID::B));
|
||||
carry->setPort(ID::CI, cell->getPort(ID::CI));
|
||||
carry->setPort(ID::CO, cell->getPort(ID::CO));
|
||||
auto carry = module->addCell(NEW_TWINE, ID(SB_CARRY));
|
||||
carry->setPort(ID(I0), cell->getPort(TW::A));
|
||||
carry->setPort(ID(I1), cell->getPort(TW::B));
|
||||
carry->setPort(TW::CI, cell->getPort(TW::CI));
|
||||
carry->setPort(TW::CO, cell->getPort(TW::CO));
|
||||
module->swap_names(carry, cell);
|
||||
auto lut_name = cell->attributes.at(IdString{"\\SB_LUT4.name"}, Const(NEW_ID.str())).decode_string();
|
||||
auto lut = module->addCell(lut_name, ID($lut));
|
||||
lut->setParam(ID::WIDTH, 4);
|
||||
lut->setParam(ID::LUT, cell->getParam(ID::LUT));
|
||||
auto I3 = cell->getPort(cell->getParam(ID(I3_IS_CI)).as_bool() ? ID::CI : ID(I3));
|
||||
lut->setPort(ID::A, { I3, cell->getPort(ID::B), cell->getPort(ID::A), cell->getPort(ID(I0)) });
|
||||
lut->setPort(ID::Y, cell->getPort(ID::O));
|
||||
lut->setPort(TW::A, { I3, cell->getPort(TW::B), cell->getPort(TW::A), cell->getPort(ID(I0)) });
|
||||
lut->setPort(TW::Y, cell->getPort(TW::O));
|
||||
|
||||
std::string carry_src, lut_src, fallback_src;
|
||||
if (cell->src_id() != Twine::Null)
|
||||
|
|
|
|||
|
|
@ -102,7 +102,7 @@ struct LatticeGsrPass : public Pass {
|
|||
{
|
||||
if (cell->type != ID($_NOT_))
|
||||
continue;
|
||||
SigSpec sig_a = cell->getPort(ID::A), sig_y = cell->getPort(ID::Y);
|
||||
SigSpec sig_a = cell->getPort(TW::A), sig_y = cell->getPort(TW::Y);
|
||||
if (GetSize(sig_a) < 1 || GetSize(sig_y) < 1)
|
||||
continue;
|
||||
SigBit a = sigmap(sig_a[0]);
|
||||
|
|
|
|||
|
|
@ -135,11 +135,11 @@ struct MicrochipDffOptPass : public Pass {
|
|||
if (cell->get_bool_attribute(ID::keep))
|
||||
continue;
|
||||
if (cell->type == ID(INV)) {
|
||||
SigBit sigout = sigmap(cell->getPort(ID::Y));
|
||||
SigBit sigin = sigmap(cell->getPort(ID::A));
|
||||
SigBit sigout = sigmap(cell->getPort(TW::Y));
|
||||
SigBit sigin = sigmap(cell->getPort(TW::A));
|
||||
bit_to_lut[sigout] = make_pair(LutData(Const(1, 2), {sigin}), cell); // INIT = 01
|
||||
} else if (cell->type.in(ID(CFG1), ID(CFG2), ID(CFG3), ID(CFG4))) {
|
||||
SigBit sigout = sigmap(cell->getPort(ID::Y));
|
||||
SigBit sigout = sigmap(cell->getPort(TW::Y));
|
||||
const Const &init = cell->getParam(ID::INIT);
|
||||
std::vector<SigBit> sigin;
|
||||
sigin.push_back(sigmap(cell->getPort(ID(A))));
|
||||
|
|
@ -182,7 +182,7 @@ struct MicrochipDffOptPass : public Pass {
|
|||
log_assert(!(has_s && has_r));
|
||||
|
||||
// Don't bother if D has more than one use.
|
||||
SigBit sig_D = sigmap(cell->getPort(ID::D));
|
||||
SigBit sig_D = sigmap(cell->getPort(TW::D));
|
||||
if (bit_uses[sig_D] > 2)
|
||||
continue;
|
||||
|
||||
|
|
@ -201,7 +201,7 @@ struct MicrochipDffOptPass : public Pass {
|
|||
bool worthy_post_r = false;
|
||||
|
||||
// First, unmap CE.
|
||||
SigBit sig_Q = sigmap(cell->getPort(ID::Q));
|
||||
SigBit sig_Q = sigmap(cell->getPort(TW::Q));
|
||||
SigBit sig_CE = sigmap(cell->getPort(ID(EN)));
|
||||
LutData lut_ce = LutData(Const(2, 2), {sig_CE}); // INIT = 10
|
||||
auto it_CE = bit_to_lut.find(sig_CE);
|
||||
|
|
@ -309,25 +309,25 @@ struct MicrochipDffOptPass : public Pass {
|
|||
Cell *lut_cell = nullptr;
|
||||
switch (GetSize(final_lut.second)) {
|
||||
case 1:
|
||||
lut_cell = module->addCell(NEW_ID, ID(CFG1));
|
||||
lut_cell = module->addCell(NEW_TWINE, ID(CFG1));
|
||||
break;
|
||||
case 2:
|
||||
lut_cell = module->addCell(NEW_ID, ID(CFG2));
|
||||
lut_cell = module->addCell(NEW_TWINE, ID(CFG2));
|
||||
break;
|
||||
case 3:
|
||||
lut_cell = module->addCell(NEW_ID, ID(CFG3));
|
||||
lut_cell = module->addCell(NEW_TWINE, ID(CFG3));
|
||||
break;
|
||||
case 4:
|
||||
lut_cell = module->addCell(NEW_ID, ID(CFG4));
|
||||
lut_cell = module->addCell(NEW_TWINE, ID(CFG4));
|
||||
break;
|
||||
default:
|
||||
log_assert(!"unknown lut size");
|
||||
}
|
||||
lut_cell->attributes = cell_d->attributes;
|
||||
Wire *lut_out = module->addWire(NEW_ID);
|
||||
Wire *lut_out = module->addWire(NEW_TWINE);
|
||||
lut_cell->setParam(ID::INIT, final_lut.first);
|
||||
cell->setPort(ID::D, lut_out);
|
||||
lut_cell->setPort(ID::Y, lut_out);
|
||||
cell->setPort(TW::D, lut_out);
|
||||
lut_cell->setPort(TW::Y, lut_out);
|
||||
lut_cell->setPort(ID(A), final_lut.second[0]);
|
||||
if (GetSize(final_lut.second) >= 2)
|
||||
lut_cell->setPort(ID(B), final_lut.second[1]);
|
||||
|
|
|
|||
|
|
@ -43,10 +43,10 @@ void microchip_dsp_pack(microchip_dsp_pm &pm)
|
|||
st.sigB.extend_u0(18, B_SIGNED);
|
||||
st.sigD.extend_u0(18, D_SIGNED);
|
||||
if (st.moveBtoA) {
|
||||
cell->setPort(ID::A, st.sigA); // if pre-adder feeds into A, original sigB will be moved to port A
|
||||
cell->setPort(TW::A, st.sigA); // if pre-adder feeds into A, original sigB will be moved to port A
|
||||
}
|
||||
cell->setPort(ID::B, st.sigB);
|
||||
cell->setPort(ID::D, st.sigD);
|
||||
cell->setPort(TW::B, st.sigB);
|
||||
cell->setPort(TW::D, st.sigD);
|
||||
// MACC_PA supports both addition and subtraction with the pre-adder.
|
||||
// Affects the sign of the 'D' port.
|
||||
if (st.preAdderStatic->type == ID($add))
|
||||
|
|
@ -75,7 +75,7 @@ void microchip_dsp_pack(microchip_dsp_pm &pm)
|
|||
cell->setPort(ID(CDIN_FDBK_SEL), {State::S0, State::S1});
|
||||
} else {
|
||||
st.sigC.extend_u0(48, st.postAdderStatic->getParam(ID::A_SIGNED).as_bool());
|
||||
cell->setPort(ID::C, st.sigC);
|
||||
cell->setPort(TW::C, st.sigC);
|
||||
}
|
||||
|
||||
pm.autoremove(st.postAdderStatic);
|
||||
|
|
@ -83,24 +83,24 @@ void microchip_dsp_pack(microchip_dsp_pm &pm)
|
|||
|
||||
// pack registers
|
||||
if (st.clock != SigBit()) {
|
||||
cell->setPort(ID::CLK, st.clock);
|
||||
cell->setPort(TW::CLK, st.clock);
|
||||
|
||||
// function to absorb a register
|
||||
auto f = [&pm, cell](SigSpec &A, Cell *ff, IdString ceport, IdString rstport, IdString bypass) {
|
||||
// input/output ports
|
||||
SigSpec D = ff->getPort(ID::D);
|
||||
SigSpec Q = (*pm.sigmap)(ff->getPort(ID::Q));
|
||||
SigSpec D = ff->getPort(TW::D);
|
||||
SigSpec Q = (*pm.sigmap)(ff->getPort(TW::Q));
|
||||
|
||||
if (!A.empty())
|
||||
A.replace(Q, D);
|
||||
if (rstport != IdString()) {
|
||||
if (ff->type.in(ID($sdff), ID($sdffe))) {
|
||||
SigSpec srst = ff->getPort(ID::SRST);
|
||||
SigSpec srst = ff->getPort(TW::SRST);
|
||||
bool rstpol_n = !ff->getParam(ID::SRST_POLARITY).as_bool();
|
||||
// active low sync rst
|
||||
cell->setPort(rstport, rstpol_n ? srst : pm.module->Not(NEW_ID, srst));
|
||||
} else if (ff->type.in(ID($adff), ID($adffe))) {
|
||||
SigSpec arst = ff->getPort(ID::ARST);
|
||||
SigSpec arst = ff->getPort(TW::ARST);
|
||||
bool rstpol_n = !ff->getParam(ID::ARST_POLARITY).as_bool();
|
||||
// active low async rst
|
||||
cell->setPort(rstport, rstpol_n ? arst : pm.module->Not(NEW_ID, arst));
|
||||
|
|
@ -110,7 +110,7 @@ void microchip_dsp_pack(microchip_dsp_pm &pm)
|
|||
}
|
||||
}
|
||||
if (ff->type.in(ID($dffe), ID($sdffe), ID($adffe))) {
|
||||
SigSpec ce = ff->getPort(ID::EN);
|
||||
SigSpec ce = ff->getPort(TW::EN);
|
||||
bool cepol = ff->getParam(ID::EN_POLARITY).as_bool();
|
||||
// enables are all active high
|
||||
cell->setPort(ceport, cepol ? ce : pm.module->Not(NEW_ID, ce));
|
||||
|
|
@ -136,23 +136,23 @@ void microchip_dsp_pack(microchip_dsp_pm &pm)
|
|||
// NOTE: flops are not autoremoved because it is possible that they
|
||||
// are only partially absorbed into DSP, or have fanouts.
|
||||
if (st.ffA) {
|
||||
SigSpec A = cell->getPort(ID::A);
|
||||
SigSpec A = cell->getPort(TW::A);
|
||||
if (st.ffA) {
|
||||
f(A, st.ffA, ID(A_EN), ID(A_SRST_N), ID(A_BYPASS));
|
||||
}
|
||||
pm.add_siguser(A, cell);
|
||||
cell->setPort(ID::A, A);
|
||||
cell->setPort(TW::A, A);
|
||||
}
|
||||
if (st.ffB) {
|
||||
SigSpec B = cell->getPort(ID::B);
|
||||
SigSpec B = cell->getPort(TW::B);
|
||||
if (st.ffB) {
|
||||
f(B, st.ffB, ID(B_EN), ID(B_SRST_N), ID(B_BYPASS));
|
||||
}
|
||||
pm.add_siguser(B, cell);
|
||||
cell->setPort(ID::B, B);
|
||||
cell->setPort(TW::B, B);
|
||||
}
|
||||
if (st.ffD) {
|
||||
SigSpec D = cell->getPort(ID::D);
|
||||
SigSpec D = cell->getPort(TW::D);
|
||||
if (st.ffD->type.in(ID($adff), ID($adffe))) {
|
||||
f(D, st.ffD, ID(D_EN), ID(D_ARST_N), ID(D_BYPASS));
|
||||
} else {
|
||||
|
|
@ -160,12 +160,12 @@ void microchip_dsp_pack(microchip_dsp_pm &pm)
|
|||
}
|
||||
|
||||
pm.add_siguser(D, cell);
|
||||
cell->setPort(ID::D, D);
|
||||
cell->setPort(TW::D, D);
|
||||
}
|
||||
if (st.ffP) {
|
||||
SigSpec P; // unused
|
||||
f(P, st.ffP, ID(P_EN), ID(P_SRST_N), ID(P_BYPASS));
|
||||
st.ffP->connections_.at(ID::Q).replace(st.sigP, pm.module->addWire(NEW_ID, GetSize(st.sigP)));
|
||||
st.ffP->connections_.at(ID::Q).replace(st.sigP, pm.module->addWire(NEW_TWINE, GetSize(st.sigP)));
|
||||
}
|
||||
|
||||
log(" clock: %s (%s)\n", log_signal(st.clock), "posedge");
|
||||
|
|
@ -183,8 +183,8 @@ void microchip_dsp_pack(microchip_dsp_pm &pm)
|
|||
|
||||
SigSpec P = st.sigP;
|
||||
if (GetSize(P) < 48)
|
||||
P.append(pm.module->addWire(NEW_ID, 48 - GetSize(P)));
|
||||
cell->setPort(ID::P, P);
|
||||
P.append(pm.module->addWire(NEW_TWINE, 48 - GetSize(P)));
|
||||
cell->setPort(TW::P, P);
|
||||
|
||||
pm.blacklist(cell);
|
||||
}
|
||||
|
|
@ -200,23 +200,23 @@ void microchip_dsp_packC(microchip_dsp_CREG_pm &pm)
|
|||
Cell *cell = st.dsp;
|
||||
|
||||
if (st.clock != SigBit()) {
|
||||
cell->setPort(ID::CLK, st.clock);
|
||||
cell->setPort(TW::CLK, st.clock);
|
||||
|
||||
// same function as above, used for the last CREG we need to absorb
|
||||
auto f = [&pm, cell](SigSpec &A, Cell *ff, IdString ceport, IdString rstport, IdString bypass) {
|
||||
// input/output ports
|
||||
SigSpec D = ff->getPort(ID::D);
|
||||
SigSpec Q = (*pm.sigmap)(ff->getPort(ID::Q));
|
||||
SigSpec D = ff->getPort(TW::D);
|
||||
SigSpec Q = (*pm.sigmap)(ff->getPort(TW::Q));
|
||||
if (!A.empty())
|
||||
A.replace(Q, D);
|
||||
if (rstport != IdString()) {
|
||||
if (ff->type.in(ID($sdff), ID($sdffe))) {
|
||||
SigSpec srst = ff->getPort(ID::SRST);
|
||||
SigSpec srst = ff->getPort(TW::SRST);
|
||||
bool rstpol_n = !ff->getParam(ID::SRST_POLARITY).as_bool();
|
||||
// active low sync rst
|
||||
cell->setPort(rstport, rstpol_n ? srst : pm.module->Not(NEW_ID, srst));
|
||||
} else if (ff->type.in(ID($adff), ID($adffe))) {
|
||||
SigSpec arst = ff->getPort(ID::ARST);
|
||||
SigSpec arst = ff->getPort(TW::ARST);
|
||||
bool rstpol_n = !ff->getParam(ID::ARST_POLARITY).as_bool();
|
||||
// active low async rst
|
||||
cell->setPort(rstport, rstpol_n ? arst : pm.module->Not(NEW_ID, arst));
|
||||
|
|
@ -226,7 +226,7 @@ void microchip_dsp_packC(microchip_dsp_CREG_pm &pm)
|
|||
}
|
||||
}
|
||||
if (ff->type.in(ID($dffe), ID($sdffe), ID($adffe))) {
|
||||
SigSpec ce = ff->getPort(ID::EN);
|
||||
SigSpec ce = ff->getPort(TW::EN);
|
||||
bool cepol = ff->getParam(ID::EN_POLARITY).as_bool();
|
||||
// enables are all active high
|
||||
cell->setPort(ceport, cepol ? ce : pm.module->Not(NEW_ID, ce));
|
||||
|
|
@ -250,7 +250,7 @@ void microchip_dsp_packC(microchip_dsp_CREG_pm &pm)
|
|||
};
|
||||
|
||||
if (st.ffC) {
|
||||
SigSpec C = cell->getPort(ID::C);
|
||||
SigSpec C = cell->getPort(TW::C);
|
||||
|
||||
if (st.ffC->type.in(ID($adff), ID($adffe))) {
|
||||
f(C, st.ffC, ID(C_EN), ID(C_ARST_N), ID(C_BYPASS));
|
||||
|
|
@ -258,7 +258,7 @@ void microchip_dsp_packC(microchip_dsp_CREG_pm &pm)
|
|||
f(C, st.ffC, ID(C_EN), ID(C_SRST_N), ID(C_BYPASS));
|
||||
}
|
||||
pm.add_siguser(C, cell);
|
||||
cell->setPort(ID::C, C);
|
||||
cell->setPort(TW::C, C);
|
||||
}
|
||||
|
||||
log(" clock: %s (%s)", log_signal(st.clock), "posedge");
|
||||
|
|
|
|||
|
|
@ -112,7 +112,7 @@ finally
|
|||
|
||||
// Chain length exceeds the maximum cascade length, must split it up
|
||||
if (i % MAX_DSP_CASCADE > 0) {
|
||||
Wire *cascade = module->addWire(NEW_ID, 48);
|
||||
Wire *cascade = module->addWire(NEW_TWINE, 48);
|
||||
|
||||
// zero port C and move wire to cascade
|
||||
dsp_pcin->setPort(\C, Const(0, 48));
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ static void nx_carry_chain(Module *module)
|
|||
IdString names_B[] = { ID(B1), ID(B2), ID(B3), ID(B4) };
|
||||
IdString names_S[] = { ID(S1), ID(S2), ID(S3), ID(S4) };
|
||||
if (!c.second.at(0)->getPort(ID(CI)).is_fully_const()) {
|
||||
cell = module->addCell(NEW_ID, ID(NX_CY));
|
||||
cell = module->addCell(NEW_TWINE, ID(NX_CY));
|
||||
cell->setParam(ID(add_carry), Const(1,2));
|
||||
cell->setPort(ID(CI), State::S1);
|
||||
|
||||
|
|
@ -92,7 +92,7 @@ static void nx_carry_chain(Module *module)
|
|||
|
||||
for (size_t i=0 ; i<c.second.size(); i++) {
|
||||
if (j==0) {
|
||||
cell = module->addCell(NEW_ID, ID(NX_CY));
|
||||
cell = module->addCell(NEW_TWINE, ID(NX_CY));
|
||||
SigBit ci = c.second.at(i)->getPort(ID(CI)).as_bit();
|
||||
cell->setPort(ID(CI), ci);
|
||||
if (ci.is_wire()) {
|
||||
|
|
@ -106,11 +106,11 @@ static void nx_carry_chain(Module *module)
|
|||
}
|
||||
if (j==3) {
|
||||
if (cnt !=0 && (cnt % 24 == 0)) {
|
||||
SigBit new_co = module->addWire(NEW_ID);
|
||||
SigBit new_co = module->addWire(NEW_TWINE);
|
||||
cell->setPort(ID(A4), State::S0);
|
||||
cell->setPort(ID(B4), State::S0);
|
||||
cell->setPort(ID(S4), new_co);
|
||||
cell = module->addCell(NEW_ID, ID(NX_CY));
|
||||
cell = module->addCell(NEW_TWINE, ID(NX_CY));
|
||||
cell->setParam(ID(add_carry), Const(1,2));
|
||||
cell->setPort(ID(CI), State::S1);
|
||||
cell->setPort(ID(A1), new_co);
|
||||
|
|
|
|||
|
|
@ -127,7 +127,7 @@ struct QlBramMergeWorker {
|
|||
const RTLIL::IdString merged_cell_type = ID($__QLF_TDP36K_MERGED);
|
||||
|
||||
// Create the new cell
|
||||
RTLIL::Cell* merged = module->addCell(NEW_ID, merged_cell_type);
|
||||
RTLIL::Cell* merged = module->addCell(NEW_TWINE, merged_cell_type);
|
||||
log_debug("Merging split BRAM cells %s and %s -> %s\n", bram1->name.unescape(), bram2->name.unescape(), merged->name.unescape());
|
||||
|
||||
for (auto &it : param_map(false))
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ static void create_ql_macc_dsp(ql_dsp_macc_pm &pm)
|
|||
log(" %s (%s)\n", cell, cell->type.unescape());
|
||||
|
||||
// Add the DSP cell
|
||||
RTLIL::Cell *cell = pm.module->addCell(NEW_ID, type);
|
||||
RTLIL::Cell *cell = pm.module->addCell(NEW_TWINE, type);
|
||||
|
||||
// Set attributes
|
||||
cell->set_bool_attribute(ID(is_inferred), true);
|
||||
|
|
@ -102,7 +102,7 @@ static void create_ql_macc_dsp(ql_dsp_macc_pm &pm)
|
|||
|
||||
// Connect output data port, pad if needed
|
||||
if ((size_t) GetSize(sig_z) < tgt_z_width) {
|
||||
auto *wire = pm.module->addWire(NEW_ID, tgt_z_width - GetSize(sig_z));
|
||||
auto *wire = pm.module->addWire(NEW_TWINE, tgt_z_width - GetSize(sig_z));
|
||||
sig_z.append(wire);
|
||||
}
|
||||
cell->setPort(ID(z_o), sig_z);
|
||||
|
|
|
|||
|
|
@ -148,7 +148,7 @@ struct QlDspSimdPass : public Pass {
|
|||
Cell *dsp_b = group[i + 1];
|
||||
|
||||
// Create the new cell
|
||||
Cell *simd = module->addCell(NEW_ID, m_SimdDspType);
|
||||
Cell *simd = module->addCell(NEW_TWINE, m_SimdDspType);
|
||||
|
||||
log(" SIMD: %s (%s) + %s (%s) => %s (%s)\n", dsp_a, dsp_a->type.unescape(),
|
||||
dsp_b, dsp_b->type.unescape(), simd, simd->type.unescape());
|
||||
|
|
@ -182,7 +182,7 @@ struct QlDspSimdPass : public Pass {
|
|||
if (!isOutput)
|
||||
sigspec.append(RTLIL::SigSpec(RTLIL::Sx, padding));
|
||||
else
|
||||
sigspec.append(module->addWire(NEW_ID, padding));
|
||||
sigspec.append(module->addWire(NEW_TWINE, padding));
|
||||
}
|
||||
return sigspec;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -46,16 +46,16 @@ struct QlIoffPass : public Pass {
|
|||
for (auto cell : module->selected_cells()) {
|
||||
if (cell->type.in(ID(dffsre), ID(sdffsre))) {
|
||||
log_debug("Checking cell %s.\n", cell->name);
|
||||
bool e_const = cell->getPort(ID::E).is_fully_ones();
|
||||
bool r_const = cell->getPort(ID::R).is_fully_ones();
|
||||
bool s_const = cell->getPort(ID::S).is_fully_ones();
|
||||
bool e_const = cell->getPort(TW::E).is_fully_ones();
|
||||
bool r_const = cell->getPort(TW::R).is_fully_ones();
|
||||
bool s_const = cell->getPort(TW::S).is_fully_ones();
|
||||
|
||||
if (!(e_const && r_const && s_const)) {
|
||||
log_debug("not promoting: E, R, or S is used\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
SigSpec d = cell->getPort(ID::D);
|
||||
SigSpec d = cell->getPort(TW::D);
|
||||
log_assert(GetSize(d) == 1);
|
||||
if (modwalker.has_inputs(d)) {
|
||||
log_debug("Cell %s is potentially eligible for promotion to input IOFF.\n", cell->name);
|
||||
|
|
@ -70,7 +70,7 @@ struct QlIoffPass : public Pass {
|
|||
continue; // prefer input FFs over output FFs
|
||||
}
|
||||
|
||||
SigSpec q = cell->getPort(ID::Q);
|
||||
SigSpec q = cell->getPort(TW::Q);
|
||||
log_assert(GetSize(q) == 1);
|
||||
if (modwalker.has_outputs(q) && !modwalker.has_consumers(q)) {
|
||||
log_debug("Cell %s is potentially eligible for promotion to output IOFF.\n", cell->name);
|
||||
|
|
@ -84,17 +84,17 @@ struct QlIoffPass : public Pass {
|
|||
}
|
||||
|
||||
for (auto cell : input_ffs) {
|
||||
log("Promoting register %s to input IOFF.\n", log_signal(cell->getPort(ID::Q)));
|
||||
log("Promoting register %s to input IOFF.\n", log_signal(cell->getPort(TW::Q)));
|
||||
cell->type = ID(dff);
|
||||
cell->unsetPort(ID::E);
|
||||
cell->unsetPort(ID::R);
|
||||
cell->unsetPort(ID::S);
|
||||
cell->unsetPort(TW::E);
|
||||
cell->unsetPort(TW::R);
|
||||
cell->unsetPort(TW::S);
|
||||
}
|
||||
for (auto & [old_port_output, ioff_cells] : output_ffs) {
|
||||
if (std::any_of(ioff_cells.begin(), ioff_cells.end(), [](Cell * c) { return c != nullptr; }))
|
||||
{
|
||||
// create replacement output wire
|
||||
RTLIL::Wire* new_port_output = module->addWire(NEW_ID, old_port_output->width);
|
||||
RTLIL::Wire* new_port_output = module->addWire(NEW_TWINE, old_port_output->width);
|
||||
new_port_output->start_offset = old_port_output->start_offset;
|
||||
module->swap_names(old_port_output, new_port_output);
|
||||
std::swap(old_port_output->port_id, new_port_output->port_id);
|
||||
|
|
@ -111,10 +111,10 @@ struct QlIoffPass : public Pass {
|
|||
if (ioff_cells[i]) {
|
||||
log("Promoting %s to output IOFF.\n", log_signal(sig_n[i]));
|
||||
|
||||
RTLIL::Cell *new_cell = module->addCell(NEW_ID, ID(dff));
|
||||
new_cell->setPort(ID::C, ioff_cells[i]->getPort(ID::C));
|
||||
new_cell->setPort(ID::D, ioff_cells[i]->getPort(ID::D));
|
||||
new_cell->setPort(ID::Q, sig_n[i]);
|
||||
RTLIL::Cell *new_cell = module->addCell(NEW_TWINE, ID(dff));
|
||||
new_cell->setPort(TW::C, ioff_cells[i]->getPort(TW::C));
|
||||
new_cell->setPort(TW::D, ioff_cells[i]->getPort(TW::D));
|
||||
new_cell->setPort(TW::Q, sig_n[i]);
|
||||
new_cell->set_bool_attribute(ID::keep);
|
||||
} else {
|
||||
module->connect(sig_n[i], sig_o[i]);
|
||||
|
|
|
|||
|
|
@ -146,11 +146,11 @@ struct XilinxDffOptPass : public Pass {
|
|||
if (cell->get_bool_attribute(ID::keep))
|
||||
continue;
|
||||
if (cell->type == ID(INV)) {
|
||||
SigBit sigout = sigmap(cell->getPort(ID::O));
|
||||
SigBit sigin = sigmap(cell->getPort(ID::I));
|
||||
SigBit sigout = sigmap(cell->getPort(TW::O));
|
||||
SigBit sigin = sigmap(cell->getPort(TW::I));
|
||||
bit_to_lut[sigout] = make_pair(LutData(Const(1, 2), {sigin}), cell);
|
||||
} else if (cell->type.in(ID(LUT1), ID(LUT2), ID(LUT3), ID(LUT4), ID(LUT5), ID(LUT6))) {
|
||||
SigBit sigout = sigmap(cell->getPort(ID::O));
|
||||
SigBit sigout = sigmap(cell->getPort(TW::O));
|
||||
const Const &init = cell->getParam(ID::INIT);
|
||||
std::vector<SigBit> sigin;
|
||||
sigin.push_back(sigmap(cell->getPort(ID(I0))));
|
||||
|
|
@ -199,7 +199,7 @@ lut_sigin_done:
|
|||
continue;
|
||||
|
||||
// Don't bother if D has more than one use.
|
||||
SigBit sig_D = sigmap(cell->getPort(ID::D));
|
||||
SigBit sig_D = sigmap(cell->getPort(TW::D));
|
||||
if (bit_uses[sig_D] > 2)
|
||||
continue;
|
||||
|
||||
|
|
@ -223,7 +223,7 @@ lut_sigin_done:
|
|||
bool worthy_post_r = false;
|
||||
|
||||
// First, unmap CE.
|
||||
SigBit sig_Q = sigmap(cell->getPort(ID::Q));
|
||||
SigBit sig_Q = sigmap(cell->getPort(TW::Q));
|
||||
SigBit sig_CE = sigmap(cell->getPort(ID(CE)));
|
||||
LutData lut_ce = LutData(Const(2, 2), {sig_CE});
|
||||
auto it_CE = bit_to_lut.find(sig_CE);
|
||||
|
|
@ -247,7 +247,7 @@ lut_sigin_done:
|
|||
// Second, unmap S, if any.
|
||||
lut_d_post_s = lut_d_post_ce;
|
||||
if (has_s) {
|
||||
SigBit sig_S = sigmap(cell->getPort(ID::S));
|
||||
SigBit sig_S = sigmap(cell->getPort(TW::S));
|
||||
LutData lut_s = LutData(Const(2, 2), {sig_S});
|
||||
bool inv_s = cell->hasParam(ID(IS_S_INVERTED)) && cell->getParam(ID(IS_S_INVERTED)).as_bool();
|
||||
auto it_S = bit_to_lut.find(sig_S);
|
||||
|
|
@ -269,7 +269,7 @@ lut_sigin_done:
|
|||
// Third, unmap R, if any.
|
||||
lut_d_post_r = lut_d_post_s;
|
||||
if (has_r) {
|
||||
SigBit sig_R = sigmap(cell->getPort(ID::R));
|
||||
SigBit sig_R = sigmap(cell->getPort(TW::R));
|
||||
LutData lut_r = LutData(Const(2, 2), {sig_R});
|
||||
bool inv_r = cell->hasParam(ID(IS_R_INVERTED)) && cell->getParam(ID(IS_R_INVERTED)).as_bool();
|
||||
auto it_R = bit_to_lut.find(sig_R);
|
||||
|
|
@ -310,11 +310,11 @@ unmap:
|
|||
// Okay, we're doing it. Unmap ports.
|
||||
if (worthy_post_r) {
|
||||
cell->unsetParam(ID(IS_R_INVERTED));
|
||||
cell->setPort(ID::R, Const(0, 1));
|
||||
cell->setPort(TW::R, Const(0, 1));
|
||||
}
|
||||
if (has_s && (worthy_post_r || worthy_post_s)) {
|
||||
cell->unsetParam(ID(IS_S_INVERTED));
|
||||
cell->setPort(ID::S, Const(0, 1));
|
||||
cell->setPort(TW::S, Const(0, 1));
|
||||
}
|
||||
cell->setPort(ID(CE), Const(1, 1));
|
||||
cell->unsetParam(ID(IS_D_INVERTED));
|
||||
|
|
@ -323,31 +323,31 @@ unmap:
|
|||
Cell *lut_cell = 0;
|
||||
switch (GetSize(final_lut.second)) {
|
||||
case 1:
|
||||
lut_cell = module->addCell(NEW_ID, ID(LUT1));
|
||||
lut_cell = module->addCell(NEW_TWINE, ID(LUT1));
|
||||
break;
|
||||
case 2:
|
||||
lut_cell = module->addCell(NEW_ID, ID(LUT2));
|
||||
lut_cell = module->addCell(NEW_TWINE, ID(LUT2));
|
||||
break;
|
||||
case 3:
|
||||
lut_cell = module->addCell(NEW_ID, ID(LUT3));
|
||||
lut_cell = module->addCell(NEW_TWINE, ID(LUT3));
|
||||
break;
|
||||
case 4:
|
||||
lut_cell = module->addCell(NEW_ID, ID(LUT4));
|
||||
lut_cell = module->addCell(NEW_TWINE, ID(LUT4));
|
||||
break;
|
||||
case 5:
|
||||
lut_cell = module->addCell(NEW_ID, ID(LUT5));
|
||||
lut_cell = module->addCell(NEW_TWINE, ID(LUT5));
|
||||
break;
|
||||
case 6:
|
||||
lut_cell = module->addCell(NEW_ID, ID(LUT6));
|
||||
lut_cell = module->addCell(NEW_TWINE, ID(LUT6));
|
||||
break;
|
||||
default:
|
||||
log_assert(!"unknown lut size");
|
||||
}
|
||||
lut_cell->attributes = cell_d->attributes;
|
||||
Wire *lut_out = module->addWire(NEW_ID);
|
||||
Wire *lut_out = module->addWire(NEW_TWINE);
|
||||
lut_cell->setParam(ID::INIT, final_lut.first);
|
||||
cell->setPort(ID::D, lut_out);
|
||||
lut_cell->setPort(ID::O, lut_out);
|
||||
cell->setPort(TW::D, lut_out);
|
||||
lut_cell->setPort(TW::O, lut_out);
|
||||
lut_cell->setPort(ID(I0), final_lut.second[0]);
|
||||
if (GetSize(final_lut.second) >= 2)
|
||||
lut_cell->setPort(ID(I1), final_lut.second[1]);
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ PRIVATE_NAMESPACE_BEGIN
|
|||
#include "techlibs/xilinx/xilinx_dsp_cascade_pm.h"
|
||||
|
||||
static Cell* addDsp(Module *module) {
|
||||
Cell *cell = module->addCell(NEW_ID, ID(DSP48E1));
|
||||
Cell *cell = module->addCell(NEW_TWINE, ID(DSP48E1));
|
||||
cell->setParam(ID(ACASCREG), 0);
|
||||
cell->setParam(ID(ADREG), 0);
|
||||
cell->setParam(ID(A_INPUT), Const("DIRECT"));
|
||||
|
|
@ -52,7 +52,7 @@ static Cell* addDsp(Module *module) {
|
|||
cell->setParam(ID(USE_SIMD), Const("ONE48"));
|
||||
cell->setParam(ID(USE_DPORT), Const("FALSE"));
|
||||
|
||||
cell->setPort(ID::D, Const(0, 25));
|
||||
cell->setPort(TW::D, Const(0, 25));
|
||||
cell->setPort(ID(INMODE), Const(0, 5));
|
||||
cell->setPort(ID(ALUMODE), Const(0, 4));
|
||||
cell->setPort(ID(OPMODE), Const(0, 7));
|
||||
|
|
@ -117,13 +117,13 @@ void xilinx_simd_pack(Module *module, SigMap* sigmap, const std::vector<Cell*> &
|
|||
for (auto cell : selected_cells) {
|
||||
if (!cell->type.in(ID($add), ID($sub)))
|
||||
continue;
|
||||
SigSpec Y = cell->getPort(ID::Y);
|
||||
SigSpec Y = cell->getPort(TW::Y);
|
||||
if (!is_allowed(Y, simds))
|
||||
continue;
|
||||
if (GetSize(Y) > 25)
|
||||
continue;
|
||||
SigSpec A = cell->getPort(ID::A);
|
||||
SigSpec B = cell->getPort(ID::B);
|
||||
SigSpec A = cell->getPort(TW::A);
|
||||
SigSpec B = cell->getPort(TW::B);
|
||||
if (GetSize(Y) <= 13) {
|
||||
if (GetSize(A) > 12)
|
||||
continue;
|
||||
|
|
@ -149,15 +149,15 @@ void xilinx_simd_pack(Module *module, SigMap* sigmap, const std::vector<Cell*> &
|
|||
}
|
||||
|
||||
auto f12 = [module](SigSpec &AB, SigSpec &C, SigSpec &P, SigSpec &CARRYOUT, Cell *lane) {
|
||||
SigSpec A = lane->getPort(ID::A);
|
||||
SigSpec B = lane->getPort(ID::B);
|
||||
SigSpec Y = lane->getPort(ID::Y);
|
||||
SigSpec A = lane->getPort(TW::A);
|
||||
SigSpec B = lane->getPort(TW::B);
|
||||
SigSpec Y = lane->getPort(TW::Y);
|
||||
A.extend_u0(12, lane->getParam(ID::A_SIGNED).as_bool());
|
||||
B.extend_u0(12, lane->getParam(ID::B_SIGNED).as_bool());
|
||||
AB.append(A);
|
||||
C.append(B);
|
||||
if (GetSize(Y) < 13)
|
||||
Y.append(module->addWire(NEW_ID, 13-GetSize(Y)));
|
||||
Y.append(module->addWire(NEW_TWINE, 13-GetSize(Y)));
|
||||
else
|
||||
log_assert(GetSize(Y) == 13);
|
||||
P.append(Y.extract(0, 12));
|
||||
|
|
@ -203,24 +203,24 @@ void xilinx_simd_pack(Module *module, SigMap* sigmap, const std::vector<Cell*> &
|
|||
else {
|
||||
AB.append(Const(0, 12));
|
||||
C.append(Const(0, 12));
|
||||
P.append(module->addWire(NEW_ID, 12));
|
||||
CARRYOUT.append(module->addWire(NEW_ID, 1));
|
||||
P.append(module->addWire(NEW_TWINE, 12));
|
||||
CARRYOUT.append(module->addWire(NEW_TWINE, 1));
|
||||
}
|
||||
}
|
||||
else {
|
||||
AB.append(Const(0, 24));
|
||||
C.append(Const(0, 24));
|
||||
P.append(module->addWire(NEW_ID, 24));
|
||||
CARRYOUT.append(module->addWire(NEW_ID, 2));
|
||||
P.append(module->addWire(NEW_TWINE, 24));
|
||||
CARRYOUT.append(module->addWire(NEW_TWINE, 2));
|
||||
}
|
||||
log_assert(GetSize(AB) == 48);
|
||||
log_assert(GetSize(C) == 48);
|
||||
log_assert(GetSize(P) == 48);
|
||||
log_assert(GetSize(CARRYOUT) == 4);
|
||||
cell->setPort(ID::A, AB.extract(18, 30));
|
||||
cell->setPort(ID::B, AB.extract(0, 18));
|
||||
cell->setPort(ID::C, C);
|
||||
cell->setPort(ID::P, P);
|
||||
cell->setPort(TW::A, AB.extract(18, 30));
|
||||
cell->setPort(TW::B, AB.extract(0, 18));
|
||||
cell->setPort(TW::C, C);
|
||||
cell->setPort(TW::P, P);
|
||||
cell->setPort(ID(CARRYOUT), CARRYOUT);
|
||||
if (lane1->type == ID($sub))
|
||||
cell->setPort(ID(ALUMODE), Const::from_string("0011"));
|
||||
|
|
@ -237,19 +237,19 @@ void xilinx_simd_pack(Module *module, SigMap* sigmap, const std::vector<Cell*> &
|
|||
g12(simd12_sub);
|
||||
|
||||
auto f24 = [module](SigSpec &AB, SigSpec &C, SigSpec &P, SigSpec &CARRYOUT, Cell *lane) {
|
||||
SigSpec A = lane->getPort(ID::A);
|
||||
SigSpec B = lane->getPort(ID::B);
|
||||
SigSpec Y = lane->getPort(ID::Y);
|
||||
SigSpec A = lane->getPort(TW::A);
|
||||
SigSpec B = lane->getPort(TW::B);
|
||||
SigSpec Y = lane->getPort(TW::Y);
|
||||
A.extend_u0(24, lane->getParam(ID::A_SIGNED).as_bool());
|
||||
B.extend_u0(24, lane->getParam(ID::B_SIGNED).as_bool());
|
||||
C.append(A);
|
||||
AB.append(B);
|
||||
if (GetSize(Y) < 25)
|
||||
Y.append(module->addWire(NEW_ID, 25-GetSize(Y)));
|
||||
Y.append(module->addWire(NEW_TWINE, 25-GetSize(Y)));
|
||||
else
|
||||
log_assert(GetSize(Y) == 25);
|
||||
P.append(Y.extract(0, 24));
|
||||
CARRYOUT.append(module->addWire(NEW_ID)); // TWO24 uses every other bit
|
||||
CARRYOUT.append(module->addWire(NEW_TWINE)); // TWO24 uses every other bit
|
||||
CARRYOUT.append(Y[24]);
|
||||
};
|
||||
auto g24 = [&f24,module](std::deque<Cell*> &simd24) {
|
||||
|
|
@ -281,10 +281,10 @@ void xilinx_simd_pack(Module *module, SigMap* sigmap, const std::vector<Cell*> &
|
|||
log_assert(GetSize(C) == 48);
|
||||
log_assert(GetSize(P) == 48);
|
||||
log_assert(GetSize(CARRYOUT) == 4);
|
||||
cell->setPort(ID::A, AB.extract(18, 30));
|
||||
cell->setPort(ID::B, AB.extract(0, 18));
|
||||
cell->setPort(ID::C, C);
|
||||
cell->setPort(ID::P, P);
|
||||
cell->setPort(TW::A, AB.extract(18, 30));
|
||||
cell->setPort(TW::B, AB.extract(0, 18));
|
||||
cell->setPort(TW::C, C);
|
||||
cell->setPort(TW::P, P);
|
||||
cell->setPort(ID(CARRYOUT), CARRYOUT);
|
||||
if (lane1->type == ID($sub))
|
||||
cell->setPort(ID(ALUMODE), Const::from_string("0011"));
|
||||
|
|
@ -328,12 +328,12 @@ void xilinx_dsp_pack(xilinx_dsp_pm &pm)
|
|||
log(" preadder %s (%s)\n", preAdder, preAdder->type.unescape());
|
||||
bool A_SIGNED = preAdder->getParam(ID::A_SIGNED).as_bool();
|
||||
bool D_SIGNED = preAdder->getParam(ID::B_SIGNED).as_bool();
|
||||
if (st.sigA == preAdder->getPort(ID::B))
|
||||
if (st.sigA == preAdder->getPort(TW::B))
|
||||
std::swap(A_SIGNED, D_SIGNED);
|
||||
st.sigA.extend_u0(30, A_SIGNED);
|
||||
st.sigD.extend_u0(25, D_SIGNED);
|
||||
cell->setPort(ID::A, st.sigA);
|
||||
cell->setPort(ID::D, st.sigD);
|
||||
cell->setPort(TW::A, st.sigA);
|
||||
cell->setPort(TW::D, st.sigD);
|
||||
if (preAdder->type == ID($add))
|
||||
cell->setPort(ID(INMODE), Const::from_string("00100"));
|
||||
else
|
||||
|
|
@ -342,7 +342,7 @@ void xilinx_dsp_pack(xilinx_dsp_pm &pm)
|
|||
if (st.ffAD) {
|
||||
if (st.ffAD->type.in(ID($dffe), ID($sdffe))) {
|
||||
bool pol = st.ffAD->getParam(ID::EN_POLARITY).as_bool();
|
||||
SigSpec S = st.ffAD->getPort(ID::EN);
|
||||
SigSpec S = st.ffAD->getPort(TW::EN);
|
||||
cell->setPort(ID(CEAD), pol ? S : pm.module->Not(NEW_ID, S));
|
||||
}
|
||||
else
|
||||
|
|
@ -360,7 +360,7 @@ void xilinx_dsp_pack(xilinx_dsp_pm &pm)
|
|||
SigSpec &opmode = cell->connections_.at(ID(OPMODE));
|
||||
if (st.postAddMux) {
|
||||
log_assert(st.ffP);
|
||||
opmode[4] = st.postAddMux->getPort(ID::S);
|
||||
opmode[4] = st.postAddMux->getPort(TW::S);
|
||||
pm.autoremove(st.postAddMux);
|
||||
}
|
||||
else if (st.ffP && st.sigC == st.sigP)
|
||||
|
|
@ -375,7 +375,7 @@ void xilinx_dsp_pack(xilinx_dsp_pm &pm)
|
|||
st.sigC.extend_u0(48, st.postAdd->getParam(ID::B_SIGNED).as_bool());
|
||||
else
|
||||
st.sigC.extend_u0(48, st.postAdd->getParam(ID::A_SIGNED).as_bool());
|
||||
cell->setPort(ID::C, st.sigC);
|
||||
cell->setPort(TW::C, st.sigC);
|
||||
}
|
||||
|
||||
pm.autoremove(st.postAdd);
|
||||
|
|
@ -387,7 +387,7 @@ void xilinx_dsp_pack(xilinx_dsp_pm &pm)
|
|||
cell->setParam(ID(SEL_MASK), Const("MASK"));
|
||||
|
||||
if (st.overflow->type == ID($ge)) {
|
||||
Const B = st.overflow->getPort(ID::B).as_const();
|
||||
Const B = st.overflow->getPort(TW::B).as_const();
|
||||
log_assert(std::count(B.begin(), B.end(), State::S1) == 1);
|
||||
// Since B is an exact power of 2, subtract 1
|
||||
// by inverting all bits up until hitting
|
||||
|
|
@ -402,7 +402,7 @@ void xilinx_dsp_pack(xilinx_dsp_pm &pm)
|
|||
|
||||
cell->setParam(ID(MASK), B);
|
||||
cell->setParam(ID(PATTERN), Const(0, 48));
|
||||
cell->setPort(ID(OVERFLOW), st.overflow->getPort(ID::Y));
|
||||
cell->setPort(ID(OVERFLOW), st.overflow->getPort(TW::Y));
|
||||
}
|
||||
else log_abort();
|
||||
|
||||
|
|
@ -411,16 +411,16 @@ void xilinx_dsp_pack(xilinx_dsp_pm &pm)
|
|||
|
||||
if (st.clock != SigBit())
|
||||
{
|
||||
cell->setPort(ID::CLK, st.clock);
|
||||
cell->setPort(TW::CLK, st.clock);
|
||||
|
||||
auto f = [&pm,cell](SigSpec &A, Cell* ff, IdString ceport, IdString rstport) {
|
||||
SigSpec D = ff->getPort(ID::D);
|
||||
SigSpec Q = (*pm.sigmap)(ff->getPort(ID::Q));
|
||||
SigSpec D = ff->getPort(TW::D);
|
||||
SigSpec Q = (*pm.sigmap)(ff->getPort(TW::Q));
|
||||
if (!A.empty())
|
||||
A.replace(Q, D);
|
||||
if (rstport != IdString()) {
|
||||
if (ff->type.in(ID($sdff), ID($sdffe))) {
|
||||
SigSpec srst = ff->getPort(ID::SRST);
|
||||
SigSpec srst = ff->getPort(TW::SRST);
|
||||
bool rstpol = ff->getParam(ID::SRST_POLARITY).as_bool();
|
||||
cell->setPort(rstport, rstpol ? srst : pm.module->Not(NEW_ID, srst));
|
||||
} else {
|
||||
|
|
@ -428,7 +428,7 @@ void xilinx_dsp_pack(xilinx_dsp_pm &pm)
|
|||
}
|
||||
}
|
||||
if (ff->type.in(ID($dffe), ID($sdffe))) {
|
||||
SigSpec ce = ff->getPort(ID::EN);
|
||||
SigSpec ce = ff->getPort(TW::EN);
|
||||
bool cepol = ff->getParam(ID::EN_POLARITY).as_bool();
|
||||
cell->setPort(ceport, cepol ? ce : pm.module->Not(NEW_ID, ce));
|
||||
}
|
||||
|
|
@ -447,7 +447,7 @@ void xilinx_dsp_pack(xilinx_dsp_pm &pm)
|
|||
};
|
||||
|
||||
if (st.ffA2) {
|
||||
SigSpec A = cell->getPort(ID::A);
|
||||
SigSpec A = cell->getPort(TW::A);
|
||||
f(A, st.ffA2, ID(CEA2), ID(RSTA));
|
||||
if (st.ffA1) {
|
||||
f(A, st.ffA1, ID(CEA1), IdString());
|
||||
|
|
@ -459,10 +459,10 @@ void xilinx_dsp_pack(xilinx_dsp_pm &pm)
|
|||
cell->setParam(ID(ACASCREG), 1);
|
||||
}
|
||||
pm.add_siguser(A, cell);
|
||||
cell->setPort(ID::A, A);
|
||||
cell->setPort(TW::A, A);
|
||||
}
|
||||
if (st.ffB2) {
|
||||
SigSpec B = cell->getPort(ID::B);
|
||||
SigSpec B = cell->getPort(TW::B);
|
||||
f(B, st.ffB2, ID(CEB2), ID(RSTB));
|
||||
if (st.ffB1) {
|
||||
f(B, st.ffB1, ID(CEB1), IdString());
|
||||
|
|
@ -474,25 +474,25 @@ void xilinx_dsp_pack(xilinx_dsp_pm &pm)
|
|||
cell->setParam(ID(BCASCREG), 1);
|
||||
}
|
||||
pm.add_siguser(B, cell);
|
||||
cell->setPort(ID::B, B);
|
||||
cell->setPort(TW::B, B);
|
||||
}
|
||||
if (st.ffD) {
|
||||
SigSpec D = cell->getPort(ID::D);
|
||||
SigSpec D = cell->getPort(TW::D);
|
||||
f(D, st.ffD, ID(CED), ID(RSTD));
|
||||
pm.add_siguser(D, cell);
|
||||
cell->setPort(ID::D, D);
|
||||
cell->setPort(TW::D, D);
|
||||
cell->setParam(ID(DREG), 1);
|
||||
}
|
||||
if (st.ffM) {
|
||||
SigSpec M; // unused
|
||||
f(M, st.ffM, ID(CEM), ID(RSTM));
|
||||
st.ffM->connections_.at(ID::Q).replace(st.sigM, pm.module->addWire(NEW_ID, GetSize(st.sigM)));
|
||||
st.ffM->connections_.at(ID::Q).replace(st.sigM, pm.module->addWire(NEW_TWINE, GetSize(st.sigM)));
|
||||
cell->setParam(ID(MREG), State::S1);
|
||||
}
|
||||
if (st.ffP) {
|
||||
SigSpec P; // unused
|
||||
f(P, st.ffP, ID(CEP), ID(RSTP));
|
||||
st.ffP->connections_.at(ID::Q).replace(st.sigP, pm.module->addWire(NEW_ID, GetSize(st.sigP)));
|
||||
st.ffP->connections_.at(ID::Q).replace(st.sigP, pm.module->addWire(NEW_TWINE, GetSize(st.sigP)));
|
||||
cell->setParam(ID(PREG), State::S1);
|
||||
}
|
||||
|
||||
|
|
@ -526,8 +526,8 @@ void xilinx_dsp_pack(xilinx_dsp_pm &pm)
|
|||
|
||||
SigSpec P = st.sigP;
|
||||
if (GetSize(P) < 48)
|
||||
P.append(pm.module->addWire(NEW_ID, 48-GetSize(P)));
|
||||
cell->setPort(ID::P, P);
|
||||
P.append(pm.module->addWire(NEW_TWINE, 48-GetSize(P)));
|
||||
cell->setPort(TW::P, P);
|
||||
|
||||
pm.blacklist(cell);
|
||||
}
|
||||
|
|
@ -559,8 +559,8 @@ void xilinx_dsp48a_pack(xilinx_dsp48a_pm &pm)
|
|||
bool B_SIGNED = st.preAdd->getParam(ID::B_SIGNED).as_bool();
|
||||
st.sigB.extend_u0(18, B_SIGNED);
|
||||
st.sigD.extend_u0(18, D_SIGNED);
|
||||
cell->setPort(ID::B, st.sigB);
|
||||
cell->setPort(ID::D, st.sigD);
|
||||
cell->setPort(TW::B, st.sigB);
|
||||
cell->setPort(TW::D, st.sigD);
|
||||
opmode[4] = State::S1;
|
||||
if (st.preAdd->type == ID($add))
|
||||
opmode[6] = State::S0;
|
||||
|
|
@ -576,7 +576,7 @@ void xilinx_dsp48a_pack(xilinx_dsp48a_pm &pm)
|
|||
|
||||
if (st.postAddMux) {
|
||||
log_assert(st.ffP);
|
||||
opmode[2] = st.postAddMux->getPort(ID::S);
|
||||
opmode[2] = st.postAddMux->getPort(TW::S);
|
||||
pm.autoremove(st.postAddMux);
|
||||
}
|
||||
else if (st.ffP && st.sigC == st.sigP)
|
||||
|
|
@ -590,7 +590,7 @@ void xilinx_dsp48a_pack(xilinx_dsp48a_pm &pm)
|
|||
st.sigC.extend_u0(48, st.postAdd->getParam(ID::B_SIGNED).as_bool());
|
||||
else
|
||||
st.sigC.extend_u0(48, st.postAdd->getParam(ID::A_SIGNED).as_bool());
|
||||
cell->setPort(ID::C, st.sigC);
|
||||
cell->setPort(TW::C, st.sigC);
|
||||
}
|
||||
|
||||
pm.autoremove(st.postAdd);
|
||||
|
|
@ -598,16 +598,16 @@ void xilinx_dsp48a_pack(xilinx_dsp48a_pm &pm)
|
|||
|
||||
if (st.clock != SigBit())
|
||||
{
|
||||
cell->setPort(ID::CLK, st.clock);
|
||||
cell->setPort(TW::CLK, st.clock);
|
||||
|
||||
auto f = [&pm,cell](SigSpec &A, Cell* ff, IdString ceport, IdString rstport) {
|
||||
SigSpec D = ff->getPort(ID::D);
|
||||
SigSpec Q = (*pm.sigmap)(ff->getPort(ID::Q));
|
||||
SigSpec D = ff->getPort(TW::D);
|
||||
SigSpec Q = (*pm.sigmap)(ff->getPort(TW::Q));
|
||||
if (!A.empty())
|
||||
A.replace(Q, D);
|
||||
if (rstport != IdString()) {
|
||||
if (ff->type.in(ID($sdff), ID($sdffe))) {
|
||||
SigSpec srst = ff->getPort(ID::SRST);
|
||||
SigSpec srst = ff->getPort(TW::SRST);
|
||||
bool rstpol = ff->getParam(ID::SRST_POLARITY).as_bool();
|
||||
cell->setPort(rstport, rstpol ? srst : pm.module->Not(NEW_ID, srst));
|
||||
} else {
|
||||
|
|
@ -615,7 +615,7 @@ void xilinx_dsp48a_pack(xilinx_dsp48a_pm &pm)
|
|||
}
|
||||
}
|
||||
if (ff->type.in(ID($dffe), ID($sdffe))) {
|
||||
SigSpec ce = ff->getPort(ID::EN);
|
||||
SigSpec ce = ff->getPort(TW::EN);
|
||||
bool cepol = ff->getParam(ID::EN_POLARITY).as_bool();
|
||||
cell->setPort(ceport, cepol ? ce : pm.module->Not(NEW_ID, ce));
|
||||
}
|
||||
|
|
@ -634,7 +634,7 @@ void xilinx_dsp48a_pack(xilinx_dsp48a_pm &pm)
|
|||
};
|
||||
|
||||
if (st.ffA0 || st.ffA1) {
|
||||
SigSpec A = cell->getPort(ID::A);
|
||||
SigSpec A = cell->getPort(TW::A);
|
||||
if (st.ffA1) {
|
||||
f(A, st.ffA1, ID(CEA), ID(RSTA));
|
||||
cell->setParam(ID(A1REG), 1);
|
||||
|
|
@ -644,10 +644,10 @@ void xilinx_dsp48a_pack(xilinx_dsp48a_pm &pm)
|
|||
cell->setParam(ID(A0REG), 1);
|
||||
}
|
||||
pm.add_siguser(A, cell);
|
||||
cell->setPort(ID::A, A);
|
||||
cell->setPort(TW::A, A);
|
||||
}
|
||||
if (st.ffB0 || st.ffB1) {
|
||||
SigSpec B = cell->getPort(ID::B);
|
||||
SigSpec B = cell->getPort(TW::B);
|
||||
if (st.ffB1) {
|
||||
f(B, st.ffB1, ID(CEB), ID(RSTB));
|
||||
cell->setParam(ID(B1REG), 1);
|
||||
|
|
@ -657,25 +657,25 @@ void xilinx_dsp48a_pack(xilinx_dsp48a_pm &pm)
|
|||
cell->setParam(ID(B0REG), 1);
|
||||
}
|
||||
pm.add_siguser(B, cell);
|
||||
cell->setPort(ID::B, B);
|
||||
cell->setPort(TW::B, B);
|
||||
}
|
||||
if (st.ffD) {
|
||||
SigSpec D = cell->getPort(ID::D);
|
||||
SigSpec D = cell->getPort(TW::D);
|
||||
f(D, st.ffD, ID(CED), ID(RSTD));
|
||||
pm.add_siguser(D, cell);
|
||||
cell->setPort(ID::D, D);
|
||||
cell->setPort(TW::D, D);
|
||||
cell->setParam(ID(DREG), 1);
|
||||
}
|
||||
if (st.ffM) {
|
||||
SigSpec M; // unused
|
||||
f(M, st.ffM, ID(CEM), ID(RSTM));
|
||||
st.ffM->connections_.at(ID::Q).replace(st.sigM, pm.module->addWire(NEW_ID, GetSize(st.sigM)));
|
||||
st.ffM->connections_.at(ID::Q).replace(st.sigM, pm.module->addWire(NEW_TWINE, GetSize(st.sigM)));
|
||||
cell->setParam(ID(MREG), State::S1);
|
||||
}
|
||||
if (st.ffP) {
|
||||
SigSpec P; // unused
|
||||
f(P, st.ffP, ID(CEP), ID(RSTP));
|
||||
st.ffP->connections_.at(ID::Q).replace(st.sigP, pm.module->addWire(NEW_ID, GetSize(st.sigP)));
|
||||
st.ffP->connections_.at(ID::Q).replace(st.sigP, pm.module->addWire(NEW_TWINE, GetSize(st.sigP)));
|
||||
cell->setParam(ID(PREG), State::S1);
|
||||
}
|
||||
|
||||
|
|
@ -704,8 +704,8 @@ void xilinx_dsp48a_pack(xilinx_dsp48a_pm &pm)
|
|||
|
||||
SigSpec P = st.sigP;
|
||||
if (GetSize(P) < 48)
|
||||
P.append(pm.module->addWire(NEW_ID, 48-GetSize(P)));
|
||||
cell->setPort(ID::P, P);
|
||||
P.append(pm.module->addWire(NEW_TWINE, 48-GetSize(P)));
|
||||
cell->setPort(TW::P, P);
|
||||
|
||||
pm.blacklist(cell);
|
||||
}
|
||||
|
|
@ -721,16 +721,16 @@ void xilinx_dsp_packC(xilinx_dsp_CREG_pm &pm)
|
|||
|
||||
if (st.clock != SigBit())
|
||||
{
|
||||
cell->setPort(ID::CLK, st.clock);
|
||||
cell->setPort(TW::CLK, st.clock);
|
||||
|
||||
auto f = [&pm,cell](SigSpec &A, Cell* ff, IdString ceport, IdString rstport) {
|
||||
SigSpec D = ff->getPort(ID::D);
|
||||
SigSpec Q = (*pm.sigmap)(ff->getPort(ID::Q));
|
||||
SigSpec D = ff->getPort(TW::D);
|
||||
SigSpec Q = (*pm.sigmap)(ff->getPort(TW::Q));
|
||||
if (!A.empty())
|
||||
A.replace(Q, D);
|
||||
if (rstport != IdString()) {
|
||||
if (ff->type.in(ID($sdff), ID($sdffe))) {
|
||||
SigSpec srst = ff->getPort(ID::SRST);
|
||||
SigSpec srst = ff->getPort(TW::SRST);
|
||||
bool rstpol = ff->getParam(ID::SRST_POLARITY).as_bool();
|
||||
cell->setPort(rstport, rstpol ? srst : pm.module->Not(NEW_ID, srst));
|
||||
} else {
|
||||
|
|
@ -738,7 +738,7 @@ void xilinx_dsp_packC(xilinx_dsp_CREG_pm &pm)
|
|||
}
|
||||
}
|
||||
if (ff->type.in(ID($dffe), ID($sdffe))) {
|
||||
SigSpec ce = ff->getPort(ID::EN);
|
||||
SigSpec ce = ff->getPort(TW::EN);
|
||||
bool cepol = ff->getParam(ID::EN_POLARITY).as_bool();
|
||||
cell->setPort(ceport, cepol ? ce : pm.module->Not(NEW_ID, ce));
|
||||
}
|
||||
|
|
@ -757,10 +757,10 @@ void xilinx_dsp_packC(xilinx_dsp_CREG_pm &pm)
|
|||
};
|
||||
|
||||
if (st.ffC) {
|
||||
SigSpec C = cell->getPort(ID::C);
|
||||
SigSpec C = cell->getPort(TW::C);
|
||||
f(C, st.ffC, ID(CEC), ID(RSTC));
|
||||
pm.add_siguser(C, cell);
|
||||
cell->setPort(ID::C, C);
|
||||
cell->setPort(TW::C, C);
|
||||
cell->setParam(ID(CREG), 1);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -89,7 +89,7 @@ finally
|
|||
|
||||
if (i % MAX_DSP_CASCADE > 0) {
|
||||
if (P >= 0) {
|
||||
Wire *cascade = module->addWire(NEW_ID, 48);
|
||||
Wire *cascade = module->addWire(NEW_TWINE, 48);
|
||||
dsp_pcin->setPort(\C, Const(0, 48));
|
||||
dsp_pcin->setPort(\PCIN, cascade);
|
||||
dsp->setPort(\PCOUT, cascade);
|
||||
|
|
@ -117,7 +117,7 @@ finally
|
|||
log_debug("PCOUT -> PCIN cascade for %s -> %s\n", dsp, dsp_pcin);
|
||||
}
|
||||
if (AREG >= 0) {
|
||||
Wire *cascade = module->addWire(NEW_ID, 30);
|
||||
Wire *cascade = module->addWire(NEW_TWINE, 30);
|
||||
dsp_pcin->setPort(\A, Const(0, 30));
|
||||
dsp_pcin->setPort(\ACIN, cascade);
|
||||
dsp->setPort(\ACOUT, cascade);
|
||||
|
|
@ -131,7 +131,7 @@ finally
|
|||
log_debug("ACOUT -> ACIN cascade for %s -> %s\n", dsp, dsp_pcin);
|
||||
}
|
||||
if (BREG >= 0) {
|
||||
Wire *cascade = module->addWire(NEW_ID, 18);
|
||||
Wire *cascade = module->addWire(NEW_TWINE, 18);
|
||||
if (dsp->type.in(\DSP48A, \DSP48A1)) {
|
||||
// According to UG389 p9 [https://www.xilinx.com/support/documentation/user_guides/ug389.pdf]
|
||||
// "The DSP48A1 component uses this input when cascading
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ void run_fixed(xilinx_srl_pm &pm)
|
|||
for (auto cell : ud.longest_chain) {
|
||||
log_debug(" %s\n", cell);
|
||||
if (cell->type.in(ID($_DFF_N_), ID($_DFF_P_), ID($_DFFE_NN_), ID($_DFFE_NP_), ID($_DFFE_PN_), ID($_DFFE_PP_))) {
|
||||
SigBit Q = cell->getPort(ID::Q);
|
||||
SigBit Q = cell->getPort(TW::Q);
|
||||
log_assert(Q.wire);
|
||||
auto it = Q.wire->attributes.find(ID::init);
|
||||
if (it != Q.wire->attributes.end()) {
|
||||
|
|
@ -59,7 +59,7 @@ void run_fixed(xilinx_srl_pm &pm)
|
|||
|
||||
auto first_cell = ud.longest_chain.back();
|
||||
auto last_cell = ud.longest_chain.front();
|
||||
Cell *c = pm.module->addCell(NEW_ID, ID($__XILINX_SHREG_));
|
||||
Cell *c = pm.module->addCell(NEW_TWINE, ID($__XILINX_SHREG_));
|
||||
pm.module->swap_names(c, first_cell);
|
||||
|
||||
if (first_cell->type.in(ID($_DFF_N_), ID($_DFF_P_), ID($_DFFE_NN_), ID($_DFFE_NP_), ID($_DFFE_PN_), ID($_DFFE_PP_), ID(FDRE), ID(FDRE_1))) {
|
||||
|
|
@ -84,16 +84,16 @@ void run_fixed(xilinx_srl_pm &pm)
|
|||
else
|
||||
c->setParam(ID(ENPOL), 2);
|
||||
|
||||
c->setPort(ID::C, first_cell->getPort(ID::C));
|
||||
c->setPort(ID::D, first_cell->getPort(ID::D));
|
||||
c->setPort(ID::Q, last_cell->getPort(ID::Q));
|
||||
c->setPort(ID::L, GetSize(ud.longest_chain)-1);
|
||||
c->setPort(TW::C, first_cell->getPort(TW::C));
|
||||
c->setPort(TW::D, first_cell->getPort(TW::D));
|
||||
c->setPort(TW::Q, last_cell->getPort(TW::Q));
|
||||
c->setPort(TW::L, GetSize(ud.longest_chain)-1);
|
||||
if (first_cell->type.in(ID($_DFF_N_), ID($_DFF_P_)))
|
||||
c->setPort(ID::E, State::S1);
|
||||
c->setPort(TW::E, State::S1);
|
||||
else if (first_cell->type.in(ID($_DFFE_NN_), ID($_DFFE_NP_), ID($_DFFE_PN_), ID($_DFFE_PP_)))
|
||||
c->setPort(ID::E, first_cell->getPort(ID::E));
|
||||
c->setPort(TW::E, first_cell->getPort(TW::E));
|
||||
else if (first_cell->type.in(ID(FDRE), ID(FDRE_1)))
|
||||
c->setPort(ID::E, first_cell->getPort(ID(CE)));
|
||||
c->setPort(TW::E, first_cell->getPort(ID(CE)));
|
||||
else
|
||||
log_abort();
|
||||
}
|
||||
|
|
@ -116,7 +116,7 @@ void run_variable(xilinx_srl_pm &pm)
|
|||
auto slice = i.second;
|
||||
log_debug(" %s\n", cell);
|
||||
if (cell->type.in(ID($_DFF_N_), ID($_DFF_P_), ID($_DFFE_NN_), ID($_DFFE_NP_), ID($_DFFE_PN_), ID($_DFFE_PP_), ID($dff), ID($dffe))) {
|
||||
SigBit Q = cell->getPort(ID::Q)[slice];
|
||||
SigBit Q = cell->getPort(TW::Q)[slice];
|
||||
log_assert(Q.wire);
|
||||
auto it = Q.wire->attributes.find(ID::init);
|
||||
if (it != Q.wire->attributes.end()) {
|
||||
|
|
@ -134,7 +134,7 @@ void run_variable(xilinx_srl_pm &pm)
|
|||
auto first_cell = ud.chain.back().first;
|
||||
auto first_slice = ud.chain.back().second;
|
||||
|
||||
Cell *c = pm.module->addCell(NEW_ID, ID($__XILINX_SHREG_));
|
||||
Cell *c = pm.module->addCell(NEW_TWINE, ID($__XILINX_SHREG_));
|
||||
pm.module->swap_names(c, first_cell);
|
||||
|
||||
if (first_cell->type.in(ID($_DFF_N_), ID($_DFF_P_), ID($_DFFE_NN_), ID($_DFFE_NP_), ID($_DFFE_PN_), ID($_DFFE_PP_), ID($dff), ID($dffe))) {
|
||||
|
|
@ -161,20 +161,20 @@ void run_variable(xilinx_srl_pm &pm)
|
|||
c->setParam(ID(ENPOL), enpol);
|
||||
|
||||
if (first_cell->type.in(ID($_DFF_N_), ID($_DFF_P_), ID($_DFFE_NN_), ID($_DFFE_NP_), ID($_DFFE_PN_), ID($_DFFE_PP_)))
|
||||
c->setPort(ID::C, first_cell->getPort(ID::C));
|
||||
c->setPort(TW::C, first_cell->getPort(TW::C));
|
||||
else if (first_cell->type.in(ID($dff), ID($dffe)))
|
||||
c->setPort(ID::C, first_cell->getPort(ID::CLK));
|
||||
c->setPort(TW::C, first_cell->getPort(TW::CLK));
|
||||
else
|
||||
log_abort();
|
||||
c->setPort(ID::D, first_cell->getPort(ID::D)[first_slice]);
|
||||
c->setPort(ID::Q, st.shiftx->getPort(ID::Y));
|
||||
c->setPort(ID::L, st.shiftx->getPort(ID::B));
|
||||
c->setPort(TW::D, first_cell->getPort(TW::D)[first_slice]);
|
||||
c->setPort(TW::Q, st.shiftx->getPort(TW::Y));
|
||||
c->setPort(TW::L, st.shiftx->getPort(TW::B));
|
||||
if (first_cell->type.in(ID($_DFF_N_), ID($_DFF_P_), ID($dff)))
|
||||
c->setPort(ID::E, State::S1);
|
||||
c->setPort(TW::E, State::S1);
|
||||
else if (first_cell->type.in(ID($_DFFE_NN_), ID($_DFFE_NP_), ID($_DFFE_PN_), ID($_DFFE_PP_)))
|
||||
c->setPort(ID::E, first_cell->getPort(ID::E));
|
||||
c->setPort(TW::E, first_cell->getPort(TW::E));
|
||||
else if (first_cell->type.in(ID($dffe)))
|
||||
c->setPort(ID::E, first_cell->getPort(ID::EN));
|
||||
c->setPort(TW::E, first_cell->getPort(TW::EN));
|
||||
else
|
||||
log_abort();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,22 +18,22 @@ match first
|
|||
select !first->type.in(\FDRE, \FDRE_1) || port(first, \R, State::S0).is_fully_zero()
|
||||
filter !non_first_cells.count(first)
|
||||
generate
|
||||
SigSpec C = module->addWire(NEW_ID);
|
||||
SigSpec D = module->addWire(NEW_ID);
|
||||
SigSpec Q = module->addWire(NEW_ID);
|
||||
SigSpec C = module->addWire(NEW_TWINE);
|
||||
SigSpec D = module->addWire(NEW_TWINE);
|
||||
SigSpec Q = module->addWire(NEW_TWINE);
|
||||
auto r = rng(8);
|
||||
Cell* cell;
|
||||
switch (r)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
cell = module->addCell(NEW_ID, \FDRE);
|
||||
cell = module->addCell(NEW_TWINE, \FDRE);
|
||||
cell->setPort(\C, C);
|
||||
cell->setPort(\D, D);
|
||||
cell->setPort(\Q, Q);
|
||||
cell->setPort(\CE, module->addWire(NEW_ID));
|
||||
cell->setPort(\CE, module->addWire(NEW_TWINE));
|
||||
if (r & 1)
|
||||
cell->setPort(\R, module->addWire(NEW_ID));
|
||||
cell->setPort(\R, module->addWire(NEW_TWINE));
|
||||
else {
|
||||
if (rng(2) == 0)
|
||||
cell->setPort(\R, State::S0);
|
||||
|
|
@ -47,7 +47,7 @@ generate
|
|||
case 5:
|
||||
case 6:
|
||||
case 7:
|
||||
cell = module->addDffeGate(NEW_ID, C, module->addWire(NEW_ID), D, Q, r & 1, r & 2);
|
||||
cell = module->addDffeGate(NEW_ID, C, module->addWire(NEW_TWINE), D, Q, r & 1, r & 2);
|
||||
break;
|
||||
default: log_abort();
|
||||
}
|
||||
|
|
@ -143,9 +143,9 @@ match next
|
|||
filter !first->type.in(\FDRE) || param(next, \IS_R_INVERTED).as_bool() == param(first, \IS_R_INVERTED).as_bool()
|
||||
filter !first->type.in(\FDRE, \FDRE_1) || port(next, \R, State::S0).is_fully_zero()
|
||||
generate
|
||||
Cell *cell = module->addCell(NEW_ID, chain.back()->type);
|
||||
Cell *cell = module->addCell(NEW_TWINE, chain.back()->type);
|
||||
cell->setPort(\C, chain.back()->getPort(\C));
|
||||
cell->setPort(\D, module->addWire(NEW_ID));
|
||||
cell->setPort(\D, module->addWire(NEW_TWINE));
|
||||
cell->setPort(\Q, chain.back()->getPort(\D));
|
||||
if (cell->type == \FDRE) {
|
||||
if (rng(2) == 0)
|
||||
|
|
@ -191,7 +191,7 @@ match shiftx
|
|||
filter param(shiftx, \A_WIDTH).as_int() >= minlen
|
||||
generate
|
||||
minlen = 3;
|
||||
module->addShiftx(NEW_ID, module->addWire(NEW_ID, rng(6)+minlen), module->addWire(NEW_ID, 3), module->addWire(NEW_ID));
|
||||
module->addShiftx(NEW_ID, module->addWire(NEW_TWINE, rng(6)+minlen), module->addWire(NEW_TWINE, 3), module->addWire(NEW_TWINE));
|
||||
endmatch
|
||||
|
||||
code shiftx_width
|
||||
|
|
@ -207,10 +207,10 @@ match first
|
|||
index <SigBit> port(first, \Q)[idx] === port(shiftx, \A)[shiftx_width-1]
|
||||
set slice idx
|
||||
generate
|
||||
SigSpec C = module->addWire(NEW_ID);
|
||||
SigSpec C = module->addWire(NEW_TWINE);
|
||||
auto WIDTH = rng(3)+1;
|
||||
SigSpec D = module->addWire(NEW_ID, WIDTH);
|
||||
SigSpec Q = module->addWire(NEW_ID, WIDTH);
|
||||
SigSpec D = module->addWire(NEW_TWINE, WIDTH);
|
||||
SigSpec Q = module->addWire(NEW_TWINE, WIDTH);
|
||||
auto r = rng(8);
|
||||
Cell *cell = nullptr;
|
||||
switch (r)
|
||||
|
|
@ -223,7 +223,7 @@ generate
|
|||
case 3:
|
||||
case 4:
|
||||
case 5:
|
||||
//cell = module->addDffe(NEW_ID, C, module->addWire(NEW_ID), D, Q, r & 1, r & 4);
|
||||
//cell = module->addDffe(NEW_ID, C, module->addWire(NEW_TWINE), D, Q, r & 1, r & 4);
|
||||
//break;
|
||||
case 6:
|
||||
case 7:
|
||||
|
|
@ -295,7 +295,7 @@ generate
|
|||
back->connections_.at(\D)[slice] = port(back, \Q)[new_slice];
|
||||
}
|
||||
else {
|
||||
auto D = module->addWire(NEW_ID, WIDTH);
|
||||
auto D = module->addWire(NEW_TWINE, WIDTH);
|
||||
if (back->type == $dff)
|
||||
module->addDff(NEW_ID, port(back, \CLK), D, port(back, \D), param(back, \CLK_POLARITY).as_bool());
|
||||
else if (back->type == $dffe)
|
||||
|
|
@ -305,9 +305,9 @@ generate
|
|||
}
|
||||
}
|
||||
else if (back->type.begins_with("$_DFF_")) {
|
||||
Cell *cell = module->addCell(NEW_ID, back->type);
|
||||
Cell *cell = module->addCell(NEW_TWINE, back->type);
|
||||
cell->setPort(\C, back->getPort(\C));
|
||||
cell->setPort(\D, module->addWire(NEW_ID));
|
||||
cell->setPort(\D, module->addWire(NEW_TWINE));
|
||||
cell->setPort(\Q, back->getPort(\D));
|
||||
}
|
||||
else
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue