new packer
This commit is contained in:
parent
1d241b1d3f
commit
1c9cf8adb1
135
leuctra/arch.cc
135
leuctra/arch.cc
@ -802,6 +802,141 @@ TimingClockingInfo Arch::getPortClockingInfo(const CellInfo *cell, IdString port
|
|||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: validate bel subtype (SLICEM vs SLICEL, IOBM vs IOBS, ...).
|
||||||
|
bool Arch::isValidBelForCell(CellInfo *cell, BelId bel) const {
|
||||||
|
IdString type = getBelType(bel);
|
||||||
|
bool is_slice = false;
|
||||||
|
if (type == id("LEUCTRA_FF")) {
|
||||||
|
if (cell && !cell->constr_parent) {
|
||||||
|
if (0x924924ull & 1ull << bel.index)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
is_slice = true;
|
||||||
|
}
|
||||||
|
if (type == id("LEUCTRA_LC")) {
|
||||||
|
if (cell) {
|
||||||
|
int mask = cell->attrs[id("LOCMASK")].as_int64();
|
||||||
|
int lci = bel.index / 3 % 4;
|
||||||
|
if (!(mask & 1 << lci))
|
||||||
|
return false;
|
||||||
|
if (cell->attrs[id("NEEDS_L")].as_bool()) {
|
||||||
|
if (!(getBelFlags(bel) & (BelPOD::FLAG_SLICEL | BelPOD::FLAG_SLICEM)))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (cell->attrs[id("NEEDS_M")].as_bool()) {
|
||||||
|
if (!(getBelFlags(bel) & BelPOD::FLAG_SLICEM))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
is_slice = true;
|
||||||
|
}
|
||||||
|
if (type == id("RAMB8BWER") && cell) {
|
||||||
|
BelId obel = bel;
|
||||||
|
obel.index = 2;
|
||||||
|
if (getBoundBelCell(obel))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (type == id("RAMB16BWER") && cell) {
|
||||||
|
BelId obel = bel;
|
||||||
|
obel.index = 0;
|
||||||
|
if (getBoundBelCell(obel))
|
||||||
|
return false;
|
||||||
|
obel.index = 1;
|
||||||
|
if (getBoundBelCell(obel))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (is_slice) {
|
||||||
|
int slice_z = bel.index / 12;
|
||||||
|
NetInfo *clk = nullptr;
|
||||||
|
NetInfo *we = nullptr;
|
||||||
|
NetInfo *ce = nullptr;
|
||||||
|
NetInfo *sr = nullptr;
|
||||||
|
Property ff_mode;
|
||||||
|
Property clk_inv;
|
||||||
|
bool had_ff = false;
|
||||||
|
CellInfo *lcs[4];
|
||||||
|
CellInfo *ffs[8];
|
||||||
|
bool ff_xi_used[4] = {0};
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
BelId obel = bel;
|
||||||
|
obel.index = slice_z * 12 + i * 3;
|
||||||
|
if (obel == bel)
|
||||||
|
lcs[i] = cell;
|
||||||
|
else
|
||||||
|
lcs[i] = getBoundBelCell(obel);
|
||||||
|
obel.index++;
|
||||||
|
if (obel == bel)
|
||||||
|
ffs[2*i] = cell;
|
||||||
|
else
|
||||||
|
ffs[2*i] = getBoundBelCell(obel);
|
||||||
|
ff_xi_used[i] = ffs[2*i] && !ffs[2*i]->constr_parent;
|
||||||
|
obel.index++;
|
||||||
|
if (obel == bel)
|
||||||
|
ffs[2*i+1] = cell;
|
||||||
|
else
|
||||||
|
ffs[2*i+1] = getBoundBelCell(obel);
|
||||||
|
}
|
||||||
|
for (auto ff : ffs) {
|
||||||
|
if (ff) {
|
||||||
|
if (had_ff) {
|
||||||
|
if (clk != ff->ports[id("CLK")].net)
|
||||||
|
return false;
|
||||||
|
if (ce != ff->ports[id("CE")].net)
|
||||||
|
return false;
|
||||||
|
if (sr != ff->ports[id("SR")].net)
|
||||||
|
return false;
|
||||||
|
if (ff_mode != ff->params[id("MODE")])
|
||||||
|
return false;
|
||||||
|
if (clk_inv != ff->params[id("CLKINV")])
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
clk = ff->ports[id("CLK")].net;
|
||||||
|
ce = ff->ports[id("CE")].net;
|
||||||
|
sr = ff->ports[id("SR")].net;
|
||||||
|
ff_mode = ff->params[id("MODE")];
|
||||||
|
clk_inv = ff->params[id("CLKINV")];
|
||||||
|
}
|
||||||
|
had_ff = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
CellInfo *lc = lcs[i];
|
||||||
|
if (!lc)
|
||||||
|
continue;
|
||||||
|
if (lc->ports[id("XI")].net && ff_xi_used[i])
|
||||||
|
return false;
|
||||||
|
if (lc->ports[id("WA7")].net && ff_xi_used[2])
|
||||||
|
return false;
|
||||||
|
if (lc->ports[id("WA8")].net && ff_xi_used[1])
|
||||||
|
return false;
|
||||||
|
if (lc->ports[id("DDI8")].net && ff_xi_used[3])
|
||||||
|
return false;
|
||||||
|
if (lc->ports[id("DDI7")].net && ff_xi_used[i | 1])
|
||||||
|
return false;
|
||||||
|
if (lc->ports[id("CLK")].net) {
|
||||||
|
if (clk) {
|
||||||
|
if (clk != lc->ports[id("CLK")].net)
|
||||||
|
return false;
|
||||||
|
if (clk_inv != lc->params[id("CLKINV")])
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
clk = lc->ports[id("CLK")].net;
|
||||||
|
clk_inv = lc->params[id("CLKINV")];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (lc->ports[id("WE")].net) {
|
||||||
|
if (we) {
|
||||||
|
if (we != lc->ports[id("WE")].net)
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
we = lc->ports[id("WE")].net;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// Assign arch arg info
|
// Assign arch arg info
|
||||||
void Arch::assignArchInfo()
|
void Arch::assignArchInfo()
|
||||||
{
|
{
|
||||||
|
@ -1183,39 +1183,10 @@ struct Arch : BaseCtx
|
|||||||
|
|
||||||
// -------------------------------------------------
|
// -------------------------------------------------
|
||||||
// Placement validity checks
|
// Placement validity checks
|
||||||
// TODO: validate bel subtype (SLICEM vs SLICEL, IOBM vs IOBS, ...).
|
|
||||||
bool isValidBelForCell(CellInfo *cell, BelId bel) const {
|
bool isValidBelForCell(CellInfo *cell, BelId bel) const;
|
||||||
if (cell->type == id("LEUCTRA_FF")) {
|
|
||||||
if (!cell->constr_parent) {
|
|
||||||
if (0x924924ull & 1ull << bel.index)
|
|
||||||
return false;
|
|
||||||
// XXX FIX FIX FIX
|
|
||||||
if (0xffcfffull & 1ull << bel.index)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (cell->type == id("LEUCTRA_LC")) {
|
|
||||||
int mask = cell->attrs[id("LOCMASK")].as_int64();
|
|
||||||
int lci = bel.index / 3 % 4;
|
|
||||||
if (!(mask & 1 << lci))
|
|
||||||
return false;
|
|
||||||
if (cell->attrs[id("NEEDS_L")].as_bool()) {
|
|
||||||
if (!(getBelFlags(bel) & (BelPOD::FLAG_SLICEL | BelPOD::FLAG_SLICEM)))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (cell->attrs[id("NEEDS_M")].as_bool()) {
|
|
||||||
if (!(getBelFlags(bel) & BelPOD::FLAG_SLICEM))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// XXX more?
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
bool isBelLocationValid(BelId bel) const {
|
bool isBelLocationValid(BelId bel) const {
|
||||||
CellInfo *cell = getBoundBelCell(bel);
|
return isValidBelForCell(getBoundBelCell(bel), bel);
|
||||||
if (cell && !isValidBelForCell(cell, bel))
|
|
||||||
return false;
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply UCF constraints to the context
|
// Apply UCF constraints to the context
|
||||||
|
@ -547,6 +547,7 @@ CellInfo *convert_carry4(Context *ctx, CellInfo *c4, CellInfo *link, std::vector
|
|||||||
if (co[i] || xo[i])
|
if (co[i] || xo[i])
|
||||||
num = i + 1;
|
num = i + 1;
|
||||||
}
|
}
|
||||||
|
NetInfo *vcc_net = nullptr;
|
||||||
for (int i = 0; i < num; i++) {
|
for (int i = 0; i < num; i++) {
|
||||||
// XXX more cases
|
// XXX more cases
|
||||||
if (i == 0 && !link) {
|
if (i == 0 && !link) {
|
||||||
@ -607,7 +608,12 @@ CellInfo *convert_carry4(Context *ctx, CellInfo *c4, CellInfo *link, std::vector
|
|||||||
lcs[i]->constr_children.push_back(ff);
|
lcs[i]->constr_children.push_back(ff);
|
||||||
ff->params[ctx->id("MODE")] = Property("COMB");
|
ff->params[ctx->id("MODE")] = Property("COMB");
|
||||||
ff->params[ctx->id("CLKINV")] = Property("CLK_B");
|
ff->params[ctx->id("CLKINV")] = Property("CLK_B");
|
||||||
set_const_port(ctx, ff, ctx->id("CLK"), true, created_cells);
|
if (vcc_net) {
|
||||||
|
connect_port(ctx, vcc_net, ff, ctx->id("CLK"));
|
||||||
|
} else {
|
||||||
|
set_const_port(ctx, ff, ctx->id("CLK"), true, created_cells);
|
||||||
|
vcc_net = ff->ports[ctx->id("CLK")].net;
|
||||||
|
}
|
||||||
connect_ports(ctx, lcs[i], ctx->id("CO"), ff, ctx->id("D"));
|
connect_ports(ctx, lcs[i], ctx->id("CO"), ff, ctx->id("D"));
|
||||||
connect_port(ctx, co[i], ff, ctx->id("Q"));
|
connect_port(ctx, co[i], ff, ctx->id("Q"));
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user