1
0
mirror of https://github.com/YosysHQ/nextpnr.git synced 2026-02-15 20:36:31 +00:00

CPE mapping improvements

This commit is contained in:
Miodrag Milanovic
2025-06-19 19:15:12 +02:00
parent bf7eb65dea
commit bee4aa0e55
9 changed files with 218 additions and 83 deletions

View File

@@ -181,7 +181,7 @@ struct BitstreamBackend
l.z = 0;
BelId cpe_bel = ctx->getBelByLocation(l);
// Only if switchbox is inside core (same as sharing location with CPE)
if (cpe_bel != BelId() && ctx->getBelType(cpe_bel).in(id_CPE_HALF_L, id_CPE_HALF_U)) {
if (cpe_bel != BelId() && ctx->getBelType(cpe_bel).in(id_CPE_LT_L, id_CPE_LT_U)) {
// Bitstream data for certain SB_DRIVES is located in other tiles
switch (word[14]) {
case '3':
@@ -241,18 +241,23 @@ struct BitstreamBackend
cc.tiles[loc].add_word(stringf("GPIO.%s", p.first.c_str(ctx)), p.second.as_bits());
}
break;
case id_CPE_HALF_U.index:
case id_CPE_HALF_L.index: {
case id_CPE_L2T4.index:
case id_CPE_L2T5.index:
case id_CPE_RAMI.index:
case id_CPE_RAMO.index:
case id_CPE_RAMIO.index:
case id_CPE_LT_U.index:
case id_CPE_LT_L.index: {
// Update configuration bits based on signal inversion
dict<IdString, Property> params = cell.second->params;
uint8_t func = int_or_default(cell.second->params, id_C_FUNCTION, 0);
if (cell.second->type.in(id_CPE_HALF_U) && func != C_MX4) {
if (cell.second->type.in(id_CPE_LT_U) && func != C_MX4) {
update_cpe_lt(cell.second.get(), id_IN1, id_INIT_L00, params);
update_cpe_lt(cell.second.get(), id_IN2, id_INIT_L00, params);
update_cpe_lt(cell.second.get(), id_IN3, id_INIT_L01, params);
update_cpe_lt(cell.second.get(), id_IN4, id_INIT_L01, params);
}
if (cell.second->type.in(id_CPE_HALF_L)) {
if (cell.second->type.in(id_CPE_LT_L)) {
update_cpe_lt(cell.second.get(), id_IN1, id_INIT_L02, params);
update_cpe_lt(cell.second.get(), id_IN2, id_INIT_L02, params);
update_cpe_lt(cell.second.get(), id_IN3, id_INIT_L03, params);
@@ -264,7 +269,7 @@ struct BitstreamBackend
update_cpe_mux(cell.second.get(), id_IN4, id_INIT_L11, 3, params);
}
}
if (cell.second->type.in(id_CPE_HALF_U, id_CPE_HALF_L)) {
if (cell.second->type.in(id_CPE_FF_U, id_CPE_FF_L)) {
update_cpe_inv(cell.second.get(), id_CLK, id_C_CPE_CLK, params);
update_cpe_inv(cell.second.get(), id_EN, id_C_CPE_EN, params);
bool set = int_or_default(params, id_C_EN_SR, 0) == 1;

View File

@@ -33,7 +33,7 @@ CellInfo *GateMatePacker::create_cell_ptr(IdString type, IdString name)
cell->ports[id].name = id;
cell->ports[id].type = dir;
};
if (type.in(id_CPE_HALF, id_CPE_HALF_U, id_CPE_HALF_L)) {
if (type.in(id_CPE_LT, id_CPE_LT_U, id_CPE_LT_L, id_CPE_L2T4, id_CPE_L2T5_U, id_CPE_L2T5_L)) {
add_port(id_I1, PORT_IN);
add_port(id_I2, PORT_IN);
add_port(id_I3, PORT_IN);
@@ -44,7 +44,7 @@ CellInfo *GateMatePacker::create_cell_ptr(IdString type, IdString name)
add_port(id_EN, PORT_IN);
add_port(id_CLK, PORT_IN);
add_port(id_SR, PORT_IN);
if (type == id_CPE_HALF_L) {
if (type == id_CPE_LT_L) {
add_port(id_COUTY1, PORT_OUT);
}
} else if (type.in(id_CLKIN)) {
@@ -68,6 +68,11 @@ CellInfo *GateMatePacker::create_cell_ptr(IdString type, IdString name)
} else if (type.in(id_CC_BUFG)) {
add_port(id_I, PORT_IN);
add_port(id_O, PORT_OUT);
} else if (type.in(id_CPE_RAMIO, id_CPE_RAMI, id_CPE_RAMO)) {
add_port(id_I, PORT_IN);
add_port(id_RAM_I, PORT_IN);
add_port(id_RAM_O, PORT_OUT);
add_port(id_OUT, PORT_OUT);
} else {
log_error("Trying to create unknown cell type %s\n", type.c_str(ctx));
}

View File

@@ -903,33 +903,75 @@ X(VALID)
X(CC_USR_RSTN)
X(USR_RSTN)
// hardware primitive CPE_HALF_U
X(CPE_HALF_U)
// CPE_HALF_U pins
X(RAM_I)
// hardware primitive CPE_LT_U
X(CPE_LT_U)
// CPE_LT_U pins
X(IN1)
X(IN2)
X(IN3)
X(IN4)
X(OUT)
// hardware primitive CPE_FF_U
X(CPE_FF_U)
// CPE_FF_U pins
X(DIN)
//X(CLK)
//X(EN)
//X(SR)
X(OUT)
X(DOUT)
// hardware primitive CPE_RAMIO_U
X(CPE_RAMIO_U)
// CPE_RAMIO_U pins
X(RAM_I)
//X(I)
//X(OUT)
X(RAM_O)
// hardware primitive CPE_HALF_L
X(CPE_HALF_L)
// CPE_HALF_L pins
//X(RAM_I)
// hardware primitive CPE_LT_L
X(CPE_LT_L)
// CPE_LT_L pins
//X(IN1)
//X(IN2)
//X(IN3)
//X(IN4)
//X(OUT)
// hardware primitive CPE_FF_L
X(CPE_FF_L)
// CPE_FF_L pins
//X(DIN)
//X(CLK)
//X(EN)
//X(SR)
//X(DOUT)
// hardware primitive CPE_RAMIO_L
X(CPE_RAMIO_L)
// CPE_RAMIO_L pins
//X(RAM_I)
//X(I)
//X(OUT)
//X(RAM_O)
// hardware primitive CPE_LT_FULL
X(CPE_LT_FULL)
// CPE_LT_FULL pins
//X(IN1)
//X(IN2)
//X(IN3)
//X(IN4)
X(IN5)
X(IN6)
X(IN7)
X(IN8)
X(OUT1)
X(OUT2)
// hardware primitive CPE_LINES
X(CPE_LINES)
// CPE_LINES pins
X(CINX)
X(PINX)
X(CINY1)
@@ -948,8 +990,8 @@ X(GPIO)
// GPIO pins
//X(IN1)
//X(IN2)
X(OUT1)
X(OUT2)
//X(OUT1)
//X(OUT2)
X(OUT3)
X(OUT4)
//X(DDR)
@@ -2055,7 +2097,11 @@ X(LVDS_EN)
X(LVDS_IE)
//X(LVDS_RTERM)
X(CPE_HALF)
X(CPE_LT)
X(CPE_FF)
X(CPE_RAMIO)
X(CPE_RAMI)
X(CPE_RAMO)
X(RAM_I1)
X(RAM_I2)
X(RAM_O1)
@@ -2170,3 +2216,8 @@ X(CPE_LVDS_IBUF)
X(CPE_LVDS_OBUF)
X(CPE_LVDS_TOBUF)
X(CPE_LVDS_IOBUF)
X(CPE_L2T4)
X(CPE_L2T5)
X(CPE_L2T5_U)
X(CPE_L2T5_L)

View File

@@ -91,7 +91,7 @@ bool GateMateImpl::isBelLocationValid(BelId bel, bool explain_invalid) const
if (cell->belStrength != PlaceStrength::STRENGTH_FIXED && tile_extra_data(bel.tile)->die != preferred_die)
return false;
if (ctx->getBelType(bel).in(id_CPE_HALF, id_CPE_HALF_L, id_CPE_HALF_U)) {
if (ctx->getBelType(bel).in(id_CPE_LT, id_CPE_LT_L, id_CPE_LT_U)) {
Loc loc = ctx->getBelLocation(bel);
const CellInfo *adj_half = ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x, loc.y, loc.z == 1 ? 0 : 1)));
if (adj_half) {
@@ -193,28 +193,69 @@ void GateMateImpl::postPlace()
{
ctx->assignArchInfo();
for (auto &cell : ctx->cells) {
if (cell.second->type.in(id_CPE_HALF, id_CPE_HALF_U, id_CPE_HALF_L)) {
if (getBelBucketForCellType(cell.second->type) == id_CPE_LT) {
Loc l = ctx->getBelLocation(cell.second->bel);
if (l.z == 0) { // CPE_HALF_U
if (cell.second->params.count(id_C_O) && int_or_default(cell.second->params, id_C_O, 0) == 0)
cell.second->params[id_C_2D_IN] = Property(1, 1);
rename_param(cell.second.get(), id_C_O, id_C_O2, 2);
rename_param(cell.second.get(), id_C_RAM_I, id_C_RAM_I2, 1);
rename_param(cell.second.get(), id_C_RAM_O, id_C_RAM_O2, 1);
cell.second->type = id_CPE_HALF_U;
//if (cell.second->params.count(id_C_O) && int_or_default(cell.second->params, id_C_O, 0) == 0)
//cell.second->params[id_C_2D_IN] = Property(1, 1);
//cell.second->type = id_CPE_HALF_U;
} else { // CPE_HALF_L
if (!cell.second->params.count(id_INIT_L20))
cell.second->params[id_INIT_L20] = Property(0b1100, 4);
rename_param(cell.second.get(), id_C_O, id_C_O1, 2);
rename_param(cell.second.get(), id_INIT_L00, id_INIT_L02, 4);
rename_param(cell.second.get(), id_INIT_L01, id_INIT_L03, 4);
rename_param(cell.second.get(), id_INIT_L10, id_INIT_L11, 4);
//cell.second->type = id_CPE_HALF_L;
}
}
if (getBelBucketForCellType(cell.second->type) == id_CPE_RAMIO) {
Loc l = ctx->getBelLocation(cell.second->bel);
if (l.z == 4) { // CPE_RAMIO_U
rename_param(cell.second.get(), id_C_RAM_I, id_C_RAM_I2, 1);
rename_param(cell.second.get(), id_C_RAM_O, id_C_RAM_O2, 1);
//cell.second->type = id_CPE_RAMIO_U;
} else { // CPE_HALF_L
rename_param(cell.second.get(), id_C_RAM_I, id_C_RAM_I1, 1);
rename_param(cell.second.get(), id_C_RAM_O, id_C_RAM_O1, 1);
cell.second->type = id_CPE_HALF_L;
//cell.second->type = id_CPE_RAMIO_L;
}
}
}
std::vector<IdString> delete_cells;
for (auto &cell : ctx->cells) {
if (cell.second->type == id_CPE_L2T5_L) {
BelId bel = cell.second->bel;
PlaceStrength strength = cell.second->belStrength;
Loc loc = ctx->getBelLocation(bel);
loc.z = 7; // CPE_LT_FULL
ctx->unbindBel(bel);
cell.second->type = id_CPE_L2T5;
ctx->bindBel(ctx->getBelByLocation(loc), cell.second.get(), strength);
cell.second->renamePort(id_IN1, id_IN5);
cell.second->renamePort(id_IN2, id_IN6);
cell.second->renamePort(id_IN3, id_IN7);
cell.second->renamePort(id_IN4, id_IN8);
cell.second->renamePort(id_OUT, id_OUT1);
loc.z = 0;
CellInfo *upper = ctx->getBoundBelCell(ctx->getBelByLocation(loc));
cell.second->params[id_INIT_L00] = upper->params[id_INIT_L00];
cell.second->params[id_INIT_L10] = upper->params[id_INIT_L10];
upper->movePortTo(id_IN1, cell.second.get(), id_IN1);
}
// Mark for deletion
if (cell.second->type == id_CPE_L2T5_U) {
delete_cells.push_back(cell.second->name);
}
}
for (auto pcell : delete_cells) {
for (auto &port : ctx->cells[pcell]->ports) {
ctx->cells[pcell]->disconnectPort(port.first);
}
ctx->cells.erase(pcell);
}
delete_cells.clear();
ctx->assignArchInfo();
}
void GateMateImpl::preRoute() { route_clock(); }
@@ -242,7 +283,7 @@ void GateMateImpl::assign_cell_info()
for (auto &cell : ctx->cells) {
CellInfo *ci = cell.second.get();
auto &fc = fast_cell_info.at(ci->flat_index);
if (ci->type.in(id_CPE_HALF, id_CPE_HALF_U, id_CPE_HALF_L)) {
if (getBelBucketForCellType(ci->type) == id_CPE_LT) {
fc.signal_used = int_or_default(ci->params, id_C_O, -1);
fc.ff_en = ci->getPort(id_EN);
fc.ff_clk = ci->getPort(id_CLK);
@@ -274,8 +315,12 @@ IdString GateMateImpl::getBelBucketForCellType(IdString cell_type) const
if (cell_type.in(id_CPE_IBUF, id_CPE_OBUF, id_CPE_TOBUF, id_CPE_IOBUF, id_CPE_LVDS_IBUF, id_CPE_LVDS_TOBUF,
id_CPE_LVDS_OBUF, id_CPE_LVDS_IOBUF))
return id_GPIO;
else if (cell_type.in(id_CPE_HALF_U, id_CPE_HALF_L, id_CPE_HALF))
return id_CPE_HALF;
else if (cell_type.in(id_CPE_LT_U, id_CPE_LT_L, id_CPE_LT, id_CPE_L2T4, id_CPE_L2T5_L, id_CPE_L2T5_U))
return id_CPE_LT;
else if (cell_type.in(id_CPE_FF_U, id_CPE_FF_L, id_CPE_FF))
return id_CPE_FF;
else if (cell_type.in(id_CPE_RAMIO, id_CPE_RAMI, id_CPE_RAMO))
return id_CPE_RAMIO;
else
return cell_type;
}
@@ -283,8 +328,12 @@ IdString GateMateImpl::getBelBucketForCellType(IdString cell_type) const
BelBucketId GateMateImpl::getBelBucketForBel(BelId bel) const
{
IdString bel_type = ctx->getBelType(bel);
if (bel_type.in(id_CPE_HALF_U, id_CPE_HALF_L))
return id_CPE_HALF;
if (bel_type.in(id_CPE_LT_U, id_CPE_LT_L, id_CPE_L2T4, id_CPE_L2T5_U, id_CPE_L2T5_L))
return id_CPE_LT;
else if (bel_type.in(id_CPE_FF_U, id_CPE_FF_L))
return id_CPE_FF;
else if (bel_type.in(id_CPE_RAMIO_U, id_CPE_RAMIO_L))
return id_CPE_RAMIO;
return bel_type;
}
@@ -294,10 +343,16 @@ bool GateMateImpl::isValidBelForCellType(IdString cell_type, BelId bel) const
if (bel_type == id_GPIO)
return cell_type.in(id_CPE_IBUF, id_CPE_OBUF, id_CPE_TOBUF, id_CPE_IOBUF, id_CPE_LVDS_IBUF, id_CPE_LVDS_TOBUF,
id_CPE_LVDS_OBUF, id_CPE_LVDS_IOBUF);
else if (bel_type == id_CPE_HALF_U)
return cell_type.in(id_CPE_HALF_U, id_CPE_HALF);
else if (bel_type == id_CPE_HALF_L)
return cell_type.in(id_CPE_HALF_L, id_CPE_HALF);
else if (bel_type == id_CPE_LT_U)
return cell_type.in(id_CPE_LT_U, id_CPE_LT, id_CPE_L2T4, id_CPE_L2T5_U);
else if (bel_type == id_CPE_LT_L)
return cell_type.in(id_CPE_LT_L, id_CPE_LT, id_CPE_L2T4, id_CPE_L2T5_L);
else if (bel_type == id_CPE_FF_U)
return cell_type.in(id_CPE_FF_U, id_CPE_FF);
else if (bel_type == id_CPE_FF_L)
return cell_type.in(id_CPE_FF_L, id_CPE_FF);
else if (bel_type.in(id_CPE_RAMIO_U,id_CPE_RAMIO_L))
return cell_type.in(id_CPE_RAMIO, id_CPE_RAMI, id_CPE_RAMO);
else
return (bel_type == cell_type);
}

View File

@@ -34,14 +34,14 @@ void GateMateImpl::drawBel(std::vector<GraphicElement> &g, GraphicElement::style
el.type = GraphicElement::TYPE_BOX;
el.style = style;
switch (bel_type.index) {
case id_CPE_HALF_L.index:
case id_CPE_LT_L.index:
el.x1 = loc.x + 0.20;
el.x2 = el.x1 + 0.20;
el.y1 = loc.y + 0.25;
el.y2 = el.y1 + 0.20;
g.push_back(el);
break;
case id_CPE_HALF_U.index:
case id_CPE_LT_U.index:
el.x1 = loc.x + 0.20;
el.x2 = el.x1 + 0.20;
el.y1 = loc.y + 0.55;

View File

@@ -47,12 +47,12 @@ void GateMatePacker::disconnect_if_gnd(CellInfo *cell, IdString input)
}
}
CellInfo *GateMatePacker::move_ram_i(CellInfo *cell, IdString origPort, bool place)
CellInfo *GateMatePacker::move_ram_i(CellInfo *cell, IdString origPort, bool place, Loc fixed)
{
CellInfo *cpe_half = nullptr;
NetInfo *net = cell->getPort(origPort);
if (net) {
cpe_half = create_cell_ptr(id_CPE_HALF, ctx->idf("%s$%s_cpe_half", cell->name.c_str(ctx), origPort.c_str(ctx)));
cpe_half = create_cell_ptr(id_CPE_RAMI, ctx->idf("%s$%s_cpe_half", cell->name.c_str(ctx), origPort.c_str(ctx)));
if (place) {
cell->constr_children.push_back(cpe_half);
cpe_half->cluster = cell->cluster;
@@ -69,17 +69,23 @@ CellInfo *GateMatePacker::move_ram_i(CellInfo *cell, IdString origPort, bool pla
return cpe_half;
}
CellInfo *GateMatePacker::move_ram_o(CellInfo *cell, IdString origPort, bool place)
CellInfo *GateMatePacker::move_ram_o(CellInfo *cell, IdString origPort, bool place, Loc fixed)
{
CellInfo *cpe_half = nullptr;
NetInfo *net = cell->getPort(origPort);
Loc cpe_loc;
if (net) {
cpe_half = create_cell_ptr(id_CPE_HALF, ctx->idf("%s$%s_cpe_half", cell->name.c_str(ctx), origPort.c_str(ctx)));
cpe_half = create_cell_ptr(id_CPE_L2T4, ctx->idf("%s$%s_cpe_half", cell->name.c_str(ctx), origPort.c_str(ctx)));
if (place) {
cell->constr_children.push_back(cpe_half);
cpe_half->cluster = cell->cluster;
cpe_half->constr_abs_z = false;
cpe_half->constr_z = PLACE_DB_CONSTR + origPort.index;
} else {
cpe_loc = uarch->getRelativeConstraint(fixed, origPort);
BelId b = ctx->getBelByLocation(cpe_loc);
printf("CPE_L2T4 %d,%d,%d\n",cpe_loc.x, cpe_loc.y, cpe_loc.z);
ctx->bindBel(b, cpe_half, PlaceStrength::STRENGTH_FIXED);
}
if (net->name == ctx->id("$PACKER_GND")) {
cpe_half->params[id_INIT_L00] = Property(0b0000, 4);
@@ -92,12 +98,29 @@ CellInfo *GateMatePacker::move_ram_o(CellInfo *cell, IdString origPort, bool pla
cell->movePortTo(origPort, cpe_half, id_IN1);
}
cpe_half->params[id_INIT_L10] = Property(0b1010, 4);
cpe_half->params[id_C_O] = Property(0b11, 2);
cpe_half->params[id_C_RAM_O] = Property(1, 1);
//cpe_half->params[id_C_O] = Property(0b11, 2);
CellInfo *cpe_ramio = create_cell_ptr(id_CPE_RAMO, ctx->idf("%s$%s_cpe_ramio", cell->name.c_str(ctx), origPort.c_str(ctx)));
if (place) {
cpe_half->constr_children.push_back(cpe_ramio);
cpe_ramio->cluster = cell->cluster;
cpe_ramio->constr_abs_z = true;
cpe_ramio->constr_z = +4;
} else {
cpe_loc.z += 4;
printf("CPE_RAMIO %d,%d,%d\n",cpe_loc.x, cpe_loc.y, cpe_loc.z);
BelId b = ctx->getBelByLocation(cpe_loc);
ctx->bindBel(b, cpe_ramio, PlaceStrength::STRENGTH_FIXED);
}
cpe_ramio->params[id_C_RAM_O] = Property(1, 1);
NetInfo *ram_o = ctx->createNet(ctx->idf("%s$ram_o", cpe_half->name.c_str(ctx)));
cell->connectPort(origPort, ram_o);
cpe_half->connectPort(id_RAM_O, ram_o);
cpe_ramio->connectPort(id_RAM_O, ram_o);
NetInfo *out = ctx->createNet(ctx->idf("%s$out", cpe_half->name.c_str(ctx)));
cpe_half->connectPort(id_OUT, out);
cpe_ramio->connectPort(id_I, out);
}
return cpe_half;
}
@@ -114,11 +137,7 @@ CellInfo *GateMatePacker::move_ram_i_fixed(CellInfo *cell, IdString origPort, Lo
CellInfo *GateMatePacker::move_ram_o_fixed(CellInfo *cell, IdString origPort, Loc fixed)
{
CellInfo *cpe = move_ram_o(cell, origPort, false);
if (cpe) {
BelId b = ctx->getBelByLocation(uarch->getRelativeConstraint(fixed, origPort));
ctx->bindBel(b, cpe, PlaceStrength::STRENGTH_FIXED);
}
CellInfo *cpe = move_ram_o(cell, origPort, false, fixed);
return cpe;
}
@@ -130,7 +149,7 @@ CellInfo *GateMatePacker::move_ram_io(CellInfo *cell, IdString iPort, IdString o
if (!i_net && !o_net)
return cpe_half;
cpe_half = create_cell_ptr(id_CPE_HALF, ctx->idf("%s$%s_cpe_half", cell->name.c_str(ctx), oPort.c_str(ctx)));
cpe_half = create_cell_ptr(id_CPE_LT, ctx->idf("%s$%s_cpe_half", cell->name.c_str(ctx), oPort.c_str(ctx)));
if (place) {
cell->constr_children.push_back(cpe_half);
cpe_half->cluster = cell->cluster;

View File

@@ -53,8 +53,8 @@ struct GateMatePacker
PllCfgRecord get_pll_settings(double f_ref, double f_core, int mode, int low_jitter, bool pdiv0_mux, bool feedback);
CellInfo *move_ram_i(CellInfo *cell, IdString origPort, bool place = true);
CellInfo *move_ram_o(CellInfo *cell, IdString origPort, bool place = true);
CellInfo *move_ram_i(CellInfo *cell, IdString origPort, bool place = true, Loc fixed = Loc());
CellInfo *move_ram_o(CellInfo *cell, IdString origPort, bool place = true, Loc fixed = Loc());
CellInfo *move_ram_i_fixed(CellInfo *cell, IdString origPort, Loc fixed);
CellInfo *move_ram_o_fixed(CellInfo *cell, IdString origPort, Loc fixed);
CellInfo *move_ram_io(CellInfo *cell, IdString iPort, IdString oPort, bool place = true);

View File

@@ -132,7 +132,7 @@ void GateMatePacker::dff_to_cpe(CellInfo *dff, CellInfo *cpe)
dff->unsetParam(id_INIT);
}
cpe->timing_index = ctx->get_cell_timing_idx(id_CPE_DFF);
cpe->params[id_C_O] = Property(0b00, 2);
// cpe->params[id_C_O] = Property(0b00, 2);
}
void GateMatePacker::pack_cpe()
@@ -152,10 +152,10 @@ void GateMatePacker::pack_cpe()
ci.renamePort(id_O, id_OUT);
ci.params[id_C_O] = Property(0b11, 2);
ci.type = id_CPE_HALF_L;
//ci.params[id_C_O] = Property(0b11, 2);
ci.type = id_CPE_L2T5_L;
} else if (ci.type == id_CC_MX2) {
ci.params[id_C_O] = Property(0b11, 2);
//ci.params[id_C_O] = Property(0b11, 2);
ci.renamePort(id_D1, id_IN1);
NetInfo *sel = ci.getPort(id_S0);
ci.renamePort(id_S0, id_IN2);
@@ -168,14 +168,14 @@ void GateMatePacker::pack_cpe()
ci.params[id_INIT_L01] = Property(0b0100, 4); // AND inv D0
ci.params[id_INIT_L10] = Property(0b1110, 4); // OR
ci.renamePort(id_Y, id_OUT);
ci.type = id_CPE_HALF;
ci.type = id_CPE_L2T4;
} else {
ci.renamePort(id_I0, id_IN1);
ci.renamePort(id_I1, id_IN2);
ci.renamePort(id_I2, id_IN3);
ci.renamePort(id_I3, id_IN4);
ci.renamePort(id_O, id_OUT);
ci.params[id_C_O] = Property(0b11, 2);
///ci.params[id_C_O] = Property(0b11, 2);
if (ci.type.in(id_CC_LUT1, id_CC_LUT2)) {
uint8_t val = int_or_default(ci.params, id_INIT, 0);
if (ci.type == id_CC_LUT1)
@@ -184,7 +184,7 @@ void GateMatePacker::pack_cpe()
ci.unsetParam(id_INIT);
ci.params[id_INIT_L10] = Property(0b1010, 4);
}
ci.type = id_CPE_HALF;
ci.type = id_CPE_L2T4;
}
NetInfo *o = ci.getPort(id_OUT);
if (o) {
@@ -207,7 +207,7 @@ void GateMatePacker::pack_cpe()
}
for (auto ci : l2t5_list) {
CellInfo *upper = create_cell_ptr(id_CPE_HALF_U, ctx->idf("%s$upper", ci->name.c_str(ctx)));
CellInfo *upper = create_cell_ptr(id_CPE_L2T5_U, ctx->idf("%s$upper", ci->name.c_str(ctx)));
upper->cluster = ci->name;
upper->constr_abs_z = false;
upper->constr_z = -1;
@@ -255,10 +255,10 @@ void GateMatePacker::pack_cpe()
ci.params[id_INIT_L03] = Property(0b1100, 4); // IN8
ci.params[id_INIT_L11] = Property(invert, 4); // Inversion bits
// ci.params[id_INIT_L20] = Property(0b1100, 4); // Always D1
ci.params[id_C_O] = Property(0b11, 2);
ci.type = id_CPE_HALF_L;
//ci.params[id_C_O] = Property(0b11, 2);
ci.type = id_CPE_LT_L;
CellInfo *upper = create_cell_ptr(id_CPE_HALF_U, ctx->idf("%s$upper", ci.name.c_str(ctx)));
CellInfo *upper = create_cell_ptr(id_CPE_LT_U, ctx->idf("%s$upper", ci.name.c_str(ctx)));
upper->cluster = ci.name;
upper->constr_abs_z = false;
upper->constr_z = -1;
@@ -291,7 +291,7 @@ void GateMatePacker::pack_cpe()
ci.params[id_INIT_L10] = Property(0b1010, 4);
ci.renamePort(id_D, id_IN1);
dff_to_cpe(&ci, &ci);
ci.type = id_CPE_HALF;
ci.type = id_CPE_LT;
}
}
@@ -385,19 +385,19 @@ void GateMatePacker::pack_addf()
CellInfo *root = grp.front();
root->cluster = root->name;
CellInfo *ci_upper = create_cell_ptr(id_CPE_HALF_U, ctx->idf("%s$ci_upper", root->name.c_str(ctx)));
CellInfo *ci_upper = create_cell_ptr(id_CPE_LT_U, ctx->idf("%s$ci_upper", root->name.c_str(ctx)));
root->constr_children.push_back(ci_upper);
ci_upper->cluster = root->name;
ci_upper->constr_abs_z = false;
ci_upper->constr_z = -1;
ci_upper->constr_y = -1;
CellInfo *ci_lower = create_cell_ptr(id_CPE_HALF_L, ctx->idf("%s$ci_lower", root->name.c_str(ctx)));
CellInfo *ci_lower = create_cell_ptr(id_CPE_LT_L, ctx->idf("%s$ci_lower", root->name.c_str(ctx)));
root->constr_children.push_back(ci_lower);
ci_lower->cluster = root->name;
ci_lower->constr_abs_z = false;
ci_lower->constr_y = -1;
ci_lower->params[id_C_O] = Property(0b11, 2);
//ci_lower->params[id_C_O] = Property(0b11, 2);
ci_lower->params[id_C_SELY1] = Property(1, 1);
ci_lower->params[id_C_CY1_I] = Property(1, 1);
ci_lower->params[id_INIT_L10] = Property(0b1010, 4); // D0
@@ -464,10 +464,10 @@ void GateMatePacker::pack_addf()
cy->params[id_INIT_L20] = Property(0b0110, 4); // XOR
}
cy->params[id_C_FUNCTION] = Property(merged ? C_ADDF2 : C_ADDF, 3);
cy->params[id_C_O] = Property(0b11, 2);
cy->type = id_CPE_HALF_L;
//cy->params[id_C_O] = Property(0b11, 2);
cy->type = id_CPE_LT_L;
CellInfo *upper = create_cell_ptr(id_CPE_HALF_U, ctx->idf("%s$upper", cy->name.c_str(ctx)));
CellInfo *upper = create_cell_ptr(id_CPE_LT_U, ctx->idf("%s$upper", cy->name.c_str(ctx)));
upper->cluster = root->name;
root->constr_children.push_back(upper);
upper->constr_abs_z = false;
@@ -475,7 +475,7 @@ void GateMatePacker::pack_addf()
upper->constr_z = -1;
if (merged) {
cy->movePortTo(id_S, upper, id_OUT);
upper->params[id_C_O] = Property(0b11, 2);
//upper->params[id_C_O] = Property(0b11, 2);
} else {
cy->renamePort(id_S, id_OUT);
}
@@ -509,18 +509,18 @@ void GateMatePacker::pack_addf()
if (i == grp.size() - 1) {
if (!cy->getPort(id_CO))
break;
CellInfo *co_upper = create_cell_ptr(id_CPE_HALF_U, ctx->idf("%s$co_upper", cy->name.c_str(ctx)));
CellInfo *co_upper = create_cell_ptr(id_CPE_LT_U, ctx->idf("%s$co_upper", cy->name.c_str(ctx)));
co_upper->cluster = root->name;
root->constr_children.push_back(co_upper);
co_upper->constr_abs_z = false;
co_upper->constr_z = -1;
co_upper->constr_y = +i + 1;
CellInfo *co_lower = create_cell_ptr(id_CPE_HALF_L, ctx->idf("%s$co_lower", cy->name.c_str(ctx)));
CellInfo *co_lower = create_cell_ptr(id_CPE_LT_L, ctx->idf("%s$co_lower", cy->name.c_str(ctx)));
co_lower->cluster = root->name;
root->constr_children.push_back(co_lower);
co_lower->constr_abs_z = false;
co_lower->constr_y = +i + 1;
co_lower->params[id_C_O] = Property(0b11, 2);
//co_lower->params[id_C_O] = Property(0b11, 2);
co_lower->params[id_C_FUNCTION] = Property(C_EN_CIN, 3);
co_lower->params[id_INIT_L11] = Property(0b1100, 4);
co_lower->params[id_INIT_L20] = Property(0b1100, 4);
@@ -551,7 +551,7 @@ void GateMatePacker::pack_addf()
break;
}
}
upper->params[id_C_O] = Property(0b10, 2);
//upper->params[id_C_O] = Property(0b10, 2);
cy->movePortTo(id_CO, upper, id_OUT);
}
}
@@ -563,10 +563,10 @@ void GateMatePacker::pack_constants()
{
log_info("Packing constants..\n");
// Replace constants with LUTs
const dict<IdString, Property> vcc_params = {{id_INIT_L10, Property(0b1111, 4)}, {id_C_O, Property(0b11, 2)}};
const dict<IdString, Property> gnd_params = {{id_INIT_L10, Property(0b0000, 4)}, {id_C_O, Property(0b11, 2)}};
const dict<IdString, Property> vcc_params = {{id_INIT_L10, Property(0b1111, 4)}};
const dict<IdString, Property> gnd_params = {{id_INIT_L10, Property(0b0000, 4)}};
h.replace_constants(CellTypePort(id_CPE_HALF, id_OUT), CellTypePort(id_CPE_HALF, id_OUT), vcc_params, gnd_params);
h.replace_constants(CellTypePort(id_CPE_LT, id_OUT), CellTypePort(id_CPE_LT, id_OUT), vcc_params, gnd_params);
}
void GateMatePacker::remove_constants()

View File

@@ -49,7 +49,7 @@ void GateMateImpl::route_clock()
auto reserved_wires = dict<WireId, IdString>{};
auto feeds_clk_port = [](PortRef &port) {
return port.cell->type.in(id_CPE_HALF, id_CPE_HALF_L, id_CPE_HALF_U) && port.port.in(id_CLK);
return port.cell->type.in(id_CPE_LT, id_CPE_LT_L, id_CPE_LT_U) && port.port.in(id_CLK);
};
auto feeds_ddr_port = [&](NetInfo *net, PortRef &port) {