mirror of https://github.com/YosysHQ/nextpnr.git
wip
This commit is contained in:
parent
7466773f11
commit
80886ce53b
|
|
@ -448,6 +448,27 @@ void GateMateImpl::postRoute()
|
|||
}
|
||||
log_info("Check CPEs..\n");
|
||||
dict<IdString,int> cfg;
|
||||
dict<IdString,IdString> port_mapping;
|
||||
auto add_input = [&](IdString orig_port, IdString port) {
|
||||
static dict<IdString,IdString> convert_port = {
|
||||
{ctx->id("CPE.IN1"),id_IN1},
|
||||
{ctx->id("CPE.IN2"),id_IN2},
|
||||
{ctx->id("CPE.IN3"),id_IN3},
|
||||
{ctx->id("CPE.IN4"),id_IN4},
|
||||
{ctx->id("CPE.IN5"),id_IN1},
|
||||
{ctx->id("CPE.IN6"),id_IN2},
|
||||
{ctx->id("CPE.IN7"),id_IN3},
|
||||
{ctx->id("CPE.IN8"),id_IN4},
|
||||
{ctx->id("CPE.PINY1"),id_PINY1},
|
||||
{ctx->id("CPE.CINX"),id_CINX},
|
||||
{ctx->id("CPE.PINX"),id_PINX}
|
||||
};
|
||||
if (convert_port.count(port)) {
|
||||
printf("CONVERTED %s %s\n",orig_port.c_str(ctx), port.c_str(ctx));
|
||||
port_mapping.emplace(orig_port, convert_port[port]);
|
||||
};
|
||||
|
||||
};
|
||||
auto check_input = [&](CellInfo *cell, IdString port) {
|
||||
if (cell->getPort(port)) {
|
||||
NetInfo *net = cell->getPort(port);
|
||||
|
|
@ -462,6 +483,7 @@ void GateMateImpl::postRoute()
|
|||
if (extra_data.type == PipExtra::PIP_EXTRA_MUX) {
|
||||
printf("name:%s %d\n",IdString(extra_data.name).c_str(ctx),extra_data.value);
|
||||
cfg.emplace(IdString(extra_data.name),extra_data.value);
|
||||
add_input(port, ctx->getWireName(src)[1]);
|
||||
}
|
||||
|
||||
if (net->wires.count(src)) {
|
||||
|
|
@ -474,6 +496,7 @@ void GateMateImpl::postRoute()
|
|||
if (extra_data.type == PipExtra::PIP_EXTRA_MUX) {
|
||||
printf("name:%s %d\n",IdString(extra_data.name).c_str(ctx),extra_data.value);
|
||||
cfg.emplace(IdString(extra_data.name),extra_data.value);
|
||||
add_input(port, ctx->getWireName(src)[1]);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -487,6 +510,7 @@ void GateMateImpl::postRoute()
|
|||
if (extra_data.type == PipExtra::PIP_EXTRA_MUX) {
|
||||
printf("name:%s %d\n",IdString(extra_data.name).c_str(ctx),extra_data.value);
|
||||
cfg.emplace(IdString(extra_data.name),extra_data.value);
|
||||
add_input(port, ctx->getWireName(src)[1]);
|
||||
}
|
||||
|
||||
} else {
|
||||
|
|
@ -508,10 +532,12 @@ void GateMateImpl::postRoute()
|
|||
((lut & 0b0100) >> 1) | // b2 -> bit 1
|
||||
((lut & 0b0001)); // b0 -> bit 0
|
||||
};
|
||||
|
||||
for (auto &cell : ctx->cells) {
|
||||
if (cell.second->type.in(id_CPE_L2T4,id_CPE_ADDF, id_CPE_ADDF2)) {
|
||||
if (cell.second->type.in(id_CPE_L2T4)) {
|
||||
printf("\n");
|
||||
cfg.clear();
|
||||
port_mapping.clear();
|
||||
printf("type:%s name:%s\n",cell.second->type.c_str(ctx),cell.second->name.c_str(ctx));
|
||||
int l00 = int_or_default(cell.second->params, id_INIT_L00, 0);
|
||||
int l01 = int_or_default(cell.second->params, id_INIT_L01, 0);
|
||||
|
|
@ -525,91 +551,59 @@ void GateMateImpl::postRoute()
|
|||
check_input(cell.second.get(), id_D1_01);
|
||||
check_input(cell.second.get(), id_D0_10);
|
||||
check_input(cell.second.get(), id_D1_10);
|
||||
if (cfg.count(ctx->id("CPE.D0_11")) || cfg.count(ctx->id("CPE.D0_10"))) {
|
||||
if (cfg.count(ctx->id("LUT2_11")) || cfg.count(ctx->id("LUT2_10"))) {
|
||||
printf("LUT2 like\n");
|
||||
|
||||
if (cfg.count(ctx->id("CPE.D0_11"))) { //lower
|
||||
printf("lower\n");
|
||||
if (cfg.at(ctx->id("CPE.D0_11"))==1)
|
||||
l10 = swap_lut2_inputs(l10);
|
||||
if (cfg.count(ctx->id("CPE.D0_02"))) { // 1st LUT2
|
||||
l00 = 0b1010; // LUT_D0 - we propagate only
|
||||
if (cfg.at(ctx->id("CPE.D0_02"))==1) {
|
||||
l00 = swap_lut2_inputs(l00);
|
||||
if (cfg.count(ctx->id("CPE.C_I3"))) {
|
||||
printf("D0_10 -> PINY1\n");
|
||||
cell.second->renamePort(id_D0_10, id_PINY1);
|
||||
} else {
|
||||
printf("D0_10 -> IN2\n");
|
||||
cell.second->renamePort(id_D0_10, id_IN2);
|
||||
}
|
||||
printf("D1_10 -> IN1\n");
|
||||
cell.second->renamePort(id_D1_10, id_IN1);
|
||||
} else {
|
||||
printf("D0_10 -> IN1\n");
|
||||
cell.second->renamePort(id_D0_10, id_IN1);
|
||||
if (cfg.count(ctx->id("CPE.C_I3"))) {
|
||||
printf("D1_10 -> PINY1\n");
|
||||
cell.second->renamePort(id_D1_10, id_PINY1);
|
||||
} else {
|
||||
printf("D1_10 -> IN2\n");
|
||||
cell.second->renamePort(id_D1_10, id_IN2);
|
||||
}
|
||||
if (cfg.count(ctx->id("LUT2_11"))) { //lower
|
||||
if (cfg.count(ctx->id("LUT2_02")) && !cfg.count(ctx->id("LUT2_03"))) {
|
||||
// both inputs on 02
|
||||
l00 = l10; // config is now in 02
|
||||
l10 = 0b1010; // LUT_D0 - we propagate only
|
||||
} else if (!cfg.count(ctx->id("LUT2_02")) && cfg.count(ctx->id("LUT2_03"))) {
|
||||
// both inputs on 03
|
||||
l01 = l10; // config is now in 03
|
||||
l10 = 0b1010; // LUT_D0 - we propagate only
|
||||
} else {
|
||||
// one input on 02, other on 03 (or LUT1)
|
||||
if (cfg.count(ctx->id("LUT2_02"))) {
|
||||
l00 = 0b1010; // LUT_D0 - we propagate only
|
||||
}
|
||||
} else { //second LUT2
|
||||
l01 = 0b1010; // LUT_D0 - we propagate only
|
||||
if (cfg.at(ctx->id("CPE.D0_03"))==1) {
|
||||
l01 = swap_lut2_inputs(l01);
|
||||
if (cfg.count(ctx->id("CPE.C_I4"))) {
|
||||
printf("D0_10 -> PINX\n");
|
||||
cell.second->renamePort(id_D0_10, id_PINX);
|
||||
} else {
|
||||
printf("D0_10 -> IN4\n");
|
||||
cell.second->renamePort(id_D0_10, id_IN4);
|
||||
}
|
||||
printf("D1_10 -> IN3\n");
|
||||
cell.second->renamePort(id_D1_10, id_IN3);
|
||||
} else {
|
||||
printf("D0_10 -> IN3\n");
|
||||
cell.second->renamePort(id_D0_10, id_IN3);
|
||||
if (cfg.count(ctx->id("CPE.C_I4"))) {
|
||||
printf("D1_10 -> PINX\n");
|
||||
cell.second->renamePort(id_D1_10, id_PINX);
|
||||
}
|
||||
else {
|
||||
printf("D1_10 -> IN4\n");
|
||||
cell.second->renamePort(id_D1_10, id_IN4);
|
||||
}
|
||||
if (cfg.count(ctx->id("LUT2_03"))) {
|
||||
l01 = 0b1010; // LUT_D0 - we propagate only
|
||||
}
|
||||
}
|
||||
|
||||
if (cfg.at(ctx->id("LUT2_11"))==1)
|
||||
l10 = swap_lut2_inputs(l10);
|
||||
if (cfg.count(ctx->id("LUT2_02")) && (cfg.at(ctx->id("LUT2_02"))==1))
|
||||
l00 = swap_lut2_inputs(l00);
|
||||
if (cfg.count(ctx->id("LUT2_03")) && (cfg.at(ctx->id("LUT2_03"))==1))
|
||||
l01 = swap_lut2_inputs(l01);
|
||||
} else { // upper part
|
||||
printf("upper\n");
|
||||
if (cfg.at(ctx->id("CPE.D0_10"))==1) {
|
||||
printf("SWAP L10");
|
||||
l10 = swap_lut2_inputs(l10);
|
||||
}
|
||||
if (cfg.count(ctx->id("CPE.D0_00"))) { // 1st LUT2
|
||||
l00 = 0b1010; // LUT_D0 - we propagate only
|
||||
if (cfg.at(ctx->id("CPE.D0_00"))==1) {
|
||||
l00 = swap_lut2_inputs(l00);
|
||||
cell.second->renamePort(id_D0_10, id_IN2);
|
||||
cell.second->renamePort(id_D1_10, id_IN1);
|
||||
} else {
|
||||
cell.second->renamePort(id_D0_10, id_IN1);
|
||||
cell.second->renamePort(id_D1_10, id_IN2);
|
||||
if (cfg.count(ctx->id("LUT2_00")) && !cfg.count(ctx->id("LUT2_01"))) {
|
||||
// both inputs on 02
|
||||
l00 = l10; // config is now in 02
|
||||
l10 = 0b1010; // LUT_D0 - we propagate only
|
||||
} else if (!cfg.count(ctx->id("LUT2_00")) && cfg.count(ctx->id("LUT2_01"))) {
|
||||
// both inputs on 03
|
||||
l01 = l10; // config is now in 03
|
||||
l10 = 0b1010; // LUT_D0 - we propagate only
|
||||
} else {
|
||||
// one input on 02, other on 03 (or LUT1)
|
||||
if (cfg.count(ctx->id("LUT2_00"))) {
|
||||
l00 = 0b1010; // LUT_D0 - we propagate only
|
||||
}
|
||||
if (cfg.count(ctx->id("LUT2_01"))) {
|
||||
l01 = 0b1010; // LUT_D0 - we propagate only
|
||||
}
|
||||
}
|
||||
|
||||
if (cfg.at(ctx->id("LUT2_10"))==1)
|
||||
l10 = swap_lut2_inputs(l10);
|
||||
if (cfg.count(ctx->id("LUT2_00")) && (cfg.at(ctx->id("LUT2_00"))==1))
|
||||
l00 = swap_lut2_inputs(l00);
|
||||
if (cfg.count(ctx->id("LUT2_01")) && (cfg.at(ctx->id("LUT2_01"))==1))
|
||||
l01 = swap_lut2_inputs(l01);
|
||||
|
||||
} else { //second LUT2
|
||||
l01 = 0b1010; // LUT_D0 - we propagate only
|
||||
if (cfg.at(ctx->id("CPE.D0_01"))==1) {
|
||||
l01 = swap_lut2_inputs(l01);
|
||||
cell.second->renamePort(id_D0_10, id_IN4);
|
||||
cell.second->renamePort(id_D1_10, id_IN3);
|
||||
} else {
|
||||
cell.second->renamePort(id_D0_10, id_IN3);
|
||||
cell.second->renamePort(id_D1_10, id_IN4);
|
||||
}
|
||||
}
|
||||
}
|
||||
printf("updated\n=========\n");
|
||||
printf("L00 %04b\n",l00);
|
||||
|
|
@ -618,66 +612,31 @@ void GateMateImpl::postRoute()
|
|||
cell.second->params[id_INIT_L00] = Property(l00,4);
|
||||
cell.second->params[id_INIT_L01] = Property(l01,4);
|
||||
cell.second->params[id_INIT_L10] = Property(l10,4);
|
||||
if (cfg.count(ctx->id("CPE.C_I1")))
|
||||
cell.second->renamePort(id_IN2, id_PINY1);
|
||||
if (cfg.count(ctx->id("CPE.C_I2")))
|
||||
cell.second->renamePort(id_IN4, id_PINX);
|
||||
if (cfg.count(ctx->id("CPE.C_I3")))
|
||||
cell.second->renamePort(id_IN2, id_PINY1);
|
||||
if (cfg.count(ctx->id("CPE.C_I4")))
|
||||
cell.second->renamePort(id_IN4, id_CINX);
|
||||
|
||||
|
||||
cell.second->renamePort(id_D0_10, port_mapping[id_D0_10]);
|
||||
cell.second->renamePort(id_D1_10, port_mapping[id_D1_10]);
|
||||
} else {
|
||||
if ((cfg.count(ctx->id("CPE.D0_00")) && cfg.at(ctx->id("CPE.D0_00"))==1) ||
|
||||
(cfg.count(ctx->id("CPE.D1_00")) && cfg.at(ctx->id("CPE.D1_00"))==1)) {
|
||||
if (cfg.count(ctx->id("LUT2_00")) && cfg.at(ctx->id("LUT2_00"))==1) {
|
||||
l00 = swap_lut2_inputs(l00);
|
||||
cell.second->renamePort(id_D0_00, id_IN2);
|
||||
cell.second->renamePort(id_D1_00, id_IN1);
|
||||
} else {
|
||||
cell.second->renamePort(id_D0_00, id_IN1);
|
||||
cell.second->renamePort(id_D1_00, id_IN2);
|
||||
}
|
||||
|
||||
|
||||
if ((cfg.count(ctx->id("CPE.D0_01")) && cfg.at(ctx->id("CPE.D0_01"))==1) ||
|
||||
(cfg.count(ctx->id("CPE.D1_01")) && cfg.at(ctx->id("CPE.D1_01"))==1)) {
|
||||
}
|
||||
if (cfg.count(ctx->id("LUT2_01")) && cfg.at(ctx->id("LUT2_01"))==1) {
|
||||
l01 = swap_lut2_inputs(l01);
|
||||
cell.second->renamePort(id_D0_01, id_IN4);
|
||||
cell.second->renamePort(id_D1_01, id_IN3);
|
||||
} else {
|
||||
cell.second->renamePort(id_D0_01, id_IN3);
|
||||
cell.second->renamePort(id_D1_01, id_IN4);
|
||||
}
|
||||
|
||||
if ((cfg.count(ctx->id("CPE.D0_02")) && cfg.at(ctx->id("CPE.D0_02"))==1) ||
|
||||
(cfg.count(ctx->id("CPE.D1_02")) && cfg.at(ctx->id("CPE.D1_02"))==1)) {
|
||||
if (cfg.count(ctx->id("LUT2_02")) && cfg.at(ctx->id("LUT2_02"))==1) {
|
||||
l00 = swap_lut2_inputs(l00);
|
||||
|
||||
cell.second->renamePort(id_D0_00, id_IN2);
|
||||
cell.second->renamePort(id_D1_00, id_IN1);
|
||||
} else {
|
||||
cell.second->renamePort(id_D0_00, id_IN1);
|
||||
cell.second->renamePort(id_D1_00, id_IN2);
|
||||
}
|
||||
|
||||
if ((cfg.count(ctx->id("CPE.D0_03")) && cfg.at(ctx->id("CPE.D0_03"))==1) ||
|
||||
(cfg.count(ctx->id("CPE.D1_03")) && cfg.at(ctx->id("CPE.D1_03"))==1)) {
|
||||
if (cfg.count(ctx->id("LUT2_03")) && cfg.at(ctx->id("LUT2_03"))==1) {
|
||||
l01 = swap_lut2_inputs(l01);
|
||||
cell.second->renamePort(id_D0_01, id_IN4);
|
||||
cell.second->renamePort(id_D1_01, id_IN3);
|
||||
} else {
|
||||
cell.second->renamePort(id_D0_01, id_IN3);
|
||||
cell.second->renamePort(id_D1_01, id_IN4);
|
||||
}
|
||||
if (cfg.count(ctx->id("CPE.C_I1")))
|
||||
cell.second->renamePort(id_IN2, id_PINY1);
|
||||
if (cfg.count(ctx->id("CPE.C_I2")))
|
||||
cell.second->renamePort(id_IN4, id_PINX);
|
||||
if (cfg.count(ctx->id("CPE.C_I3")))
|
||||
cell.second->renamePort(id_IN2, id_PINY1);
|
||||
if (cfg.count(ctx->id("CPE.C_I4")))
|
||||
cell.second->renamePort(id_IN4, id_CINX);
|
||||
|
||||
cell.second->params[id_INIT_L00] = Property(l00,4);
|
||||
cell.second->params[id_INIT_L01] = Property(l01,4);
|
||||
cell.second->params[id_INIT_L10] = Property(l10,4);
|
||||
|
||||
cell.second->renamePort(id_D0_00, port_mapping[id_D0_00]);
|
||||
cell.second->renamePort(id_D1_00, port_mapping[id_D1_00]);
|
||||
cell.second->renamePort(id_D0_01, port_mapping[id_D0_01]);
|
||||
cell.second->renamePort(id_D1_01, port_mapping[id_D1_01]);
|
||||
}
|
||||
if (cfg.count(ctx->id("CPE.C_I1")))
|
||||
cell.second->params[id_C_I1] = Property(1,1);
|
||||
|
|
|
|||
|
|
@ -131,8 +131,43 @@ void GateMatePacker::count_cell(CellInfo &ci)
|
|||
count++;
|
||||
}
|
||||
|
||||
inline int lut2_apply_constant_inputs(int init, int d0_const, int d1_const)
|
||||
{
|
||||
int b0 = (init >> 0) & 1;
|
||||
int b1 = (init >> 1) & 1;
|
||||
int b2 = (init >> 2) & 1;
|
||||
int b3 = (init >> 3) & 1;
|
||||
|
||||
int out[4];
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
int D1 = (i >> 1) & 1;
|
||||
int D0 = (i >> 0) & 1;
|
||||
|
||||
// Apply constants if present
|
||||
if (d0_const != -1) D0 = d0_const;
|
||||
if (d1_const != -1) D1 = d1_const;
|
||||
|
||||
int src = (D1 << 1) | D0;
|
||||
out[i] =
|
||||
(src == 0) ? b0 :
|
||||
(src == 1) ? b1 :
|
||||
(src == 2) ? b2 :
|
||||
b3;
|
||||
}
|
||||
|
||||
return (out[3] << 3) | (out[2] << 2) | (out[1] << 1) | out[0];
|
||||
}
|
||||
|
||||
void GateMatePacker::optimize_lut()
|
||||
{
|
||||
auto lut2_same_inputs = [&](int lut) -> int {
|
||||
int b0 = lut & 1; // bit 0
|
||||
int b3 = (lut >> 3) & 1; // bit 3
|
||||
|
||||
return (b3 << 3) | (b3 << 2) | (b0 << 1) | b0;
|
||||
};
|
||||
|
||||
for (auto &cell : ctx->cells) {
|
||||
CellInfo &ci = *cell.second;
|
||||
if (!ci.type.in(id_CC_LUT1, id_CC_LUT2))
|
||||
|
|
@ -148,6 +183,23 @@ void GateMatePacker::optimize_lut()
|
|||
uint8_t val = int_or_default(ci.params, id_INIT, 0);
|
||||
if (ci.type == id_CC_LUT1)
|
||||
val = val << 2 | val;
|
||||
else {
|
||||
int d0_const = -1;
|
||||
int d1_const = -1;
|
||||
if (ci.getPort(id_I0) && ci.getPort(id_I0)==net_PACKER_GND) { d0_const = 0; ci.disconnectPort(id_I0); }
|
||||
if (ci.getPort(id_I0) && ci.getPort(id_I0)==net_PACKER_VCC) { d0_const = 1; ci.disconnectPort(id_I0); }
|
||||
if (ci.getPort(id_I1) && ci.getPort(id_I1)==net_PACKER_GND) { d1_const = 0; ci.disconnectPort(id_I1); }
|
||||
if (ci.getPort(id_I1) && ci.getPort(id_I1)==net_PACKER_VCC) { d1_const = 1; ci.disconnectPort(id_I1); }
|
||||
|
||||
val = lut2_apply_constant_inputs(val, d0_const, d1_const);
|
||||
|
||||
if (ci.getPort(id_I0)==ci.getPort(id_I1)) {
|
||||
printf("LUT2 with same inputs %s\n",ci.name.c_str(ctx));
|
||||
val = lut2_same_inputs(val);
|
||||
ci.params[id_INIT] = Property(val,4);
|
||||
ci.disconnectPort(id_I1);
|
||||
}
|
||||
}
|
||||
switch (val) {
|
||||
case LUT_ZERO: // constant 0
|
||||
move_connections(o_net, net_PACKER_GND);
|
||||
|
|
|
|||
|
|
@ -401,7 +401,7 @@ void GateMatePacker::pack_cpe()
|
|||
ci.disconnectPort(id_D);
|
||||
} else {
|
||||
lt->params[id_INIT_L10] = Property(LUT_D0, 4);
|
||||
ci.movePortTo(id_D, lt, id_D0_00);
|
||||
ci.movePortTo(id_D, lt, id_D0_10);
|
||||
}
|
||||
ci.type = (ci.type == id_CC_DLT) ? id_CPE_LATCH : id_CPE_FF;
|
||||
NetInfo *conn = ctx->createNet(ctx->idf("%s$di", ci.name.c_str(ctx)));
|
||||
|
|
|
|||
Loading…
Reference in New Issue