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:
@@ -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;
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user