machxo2: Fix packing for directly-connected DFFs.
This commit is contained in:
parent
e625876949
commit
41d09f7187
@ -154,7 +154,7 @@ void lut_to_lc(const Context *ctx, CellInfo *lut, CellInfo *lc, bool no_dff)
|
||||
replace_port(lut, ctx->id("Z"), lc, ctx->id("F0"));
|
||||
}
|
||||
|
||||
void dff_to_lc(Context *ctx, CellInfo *dff, CellInfo *lc, bool pass_thru_lut)
|
||||
void dff_to_lc(Context *ctx, CellInfo *dff, CellInfo *lc, LutType lut_type)
|
||||
{
|
||||
// FIXME: This will have to change once we support FFs with reset value of 1.
|
||||
lc->params[ctx->id("REG0_REGSET")] = std::string("RESET");
|
||||
@ -163,14 +163,21 @@ void dff_to_lc(Context *ctx, CellInfo *dff, CellInfo *lc, bool pass_thru_lut)
|
||||
replace_port(dff, ctx->id("LSR"), lc, ctx->id("LSR"));
|
||||
replace_port(dff, ctx->id("Q"), lc, ctx->id("Q0"));
|
||||
|
||||
// If a register's DI port is fed by a constant, options for placing are
|
||||
// limited. Use the LUT to get around this.
|
||||
if (pass_thru_lut) {
|
||||
if (lut_type == LutType::PassThru) {
|
||||
// If a register's DI port is fed by a constant, options for placing are
|
||||
// limited. Use the LUT to get around this.
|
||||
// LUT output will go to F0, which will feed back to DI0 input.
|
||||
lc->params[ctx->id("LUT0_INITVAL")] = Property(0xAAAA, 16);
|
||||
;
|
||||
replace_port(dff, ctx->id("DI"), lc, ctx->id("A0"));
|
||||
connect_ports(ctx, lc, ctx->id("F0"), lc, ctx->id("DI0"));
|
||||
} else if (lut_type == LutType::None) {
|
||||
// If there is no LUT, use the M0 input because DI0 requires
|
||||
// going through the LUTs.
|
||||
lc->params[ctx->id("REG0_SD")] = std::string("0");
|
||||
replace_port(dff, ctx->id("DI"), lc, ctx->id("M0"));
|
||||
} else {
|
||||
// Otherwise, there's a LUT being used in the slice and mapping DI to
|
||||
// DI0 input is fine.
|
||||
replace_port(dff, ctx->id("DI"), lc, ctx->id("DI0"));
|
||||
}
|
||||
}
|
||||
|
@ -25,6 +25,16 @@
|
||||
|
||||
NEXTPNR_NAMESPACE_BEGIN
|
||||
|
||||
// When packing DFFs, we need context of how it's connected to a LUT to
|
||||
// properly map DFF ports to FACADE_SLICEs; DI0 input muxes F0 and OFX0,
|
||||
// and a DFF inside a slice can use either DI0 or M0 as an input.
|
||||
enum class LutType
|
||||
{
|
||||
None,
|
||||
Normal,
|
||||
PassThru,
|
||||
};
|
||||
|
||||
// Create a MachXO2 arch cell and return it
|
||||
// Name will be automatically assigned if not specified
|
||||
std::unique_ptr<CellInfo> create_machxo2_cell(Context *ctx, IdString type, std::string name = "");
|
||||
@ -46,7 +56,7 @@ void lut_to_lc(const Context *ctx, CellInfo *lut, CellInfo *lc, bool no_dff = tr
|
||||
// and reconnecting signals as necessary. If pass_thru_lut is True, the LUT will
|
||||
// be configured as pass through and D connected to I0, otherwise D will be
|
||||
// ignored
|
||||
void dff_to_lc(Context *ctx, CellInfo *dff, CellInfo *lc, bool pass_thru_lut = false);
|
||||
void dff_to_lc(Context *ctx, CellInfo *dff, CellInfo *lc, LutType lut_type = LutType::Normal);
|
||||
|
||||
// Convert a nextpnr IO buffer to a GENERIC_IOB
|
||||
void nxio_to_iob(Context *ctx, CellInfo *nxio, CellInfo *sbio, pool<IdString> &todelete_cells);
|
||||
|
@ -62,7 +62,7 @@ static void pack_lut_lutffs(Context *ctx)
|
||||
// Locations don't match, can't pack
|
||||
} else {
|
||||
lut_to_lc(ctx, ci, packed.get(), false);
|
||||
dff_to_lc(ctx, dff, packed.get(), false);
|
||||
dff_to_lc(ctx, dff, packed.get(), LutType::Normal);
|
||||
if (dff_bel != dff->attrs.end())
|
||||
packed->attrs[ctx->id("BEL")] = dff_bel->second;
|
||||
packed_cells.insert(dff->name);
|
||||
@ -105,7 +105,9 @@ static void pack_remaining_ffs(Context *ctx)
|
||||
packed->attrs[attr.first] = attr.second;
|
||||
|
||||
auto dff_bel = ci->attrs.find(ctx->id("BEL"));
|
||||
dff_to_lc(ctx, ci, packed.get(), false);
|
||||
|
||||
dff_to_lc(ctx, ci, packed.get(), LutType::None);
|
||||
|
||||
if (dff_bel != ci->attrs.end())
|
||||
packed->attrs[ctx->id("BEL")] = dff_bel->second;
|
||||
packed_cells.insert(ci->name);
|
||||
@ -146,7 +148,7 @@ static void set_net_constant(Context *ctx, NetInfo *orig, NetInfo *constnet, boo
|
||||
for (auto &attr : uc->attrs)
|
||||
lc->attrs[attr.first] = attr.second;
|
||||
|
||||
dff_to_lc(ctx, uc, lc.get(), true);
|
||||
dff_to_lc(ctx, uc, lc.get(), LutType::PassThru);
|
||||
packed_cells.insert(uc->name);
|
||||
|
||||
lc->ports[id_A0].net = constnet;
|
||||
|
Loading…
Reference in New Issue
Block a user