mirror of
https://github.com/YosysHQ/nextpnr.git
synced 2026-01-11 23:53:21 +00:00
wip
This commit is contained in:
parent
a530283600
commit
af62a9abbd
@ -87,6 +87,30 @@ struct BitstreamBackend
|
||||
return invert;
|
||||
}
|
||||
|
||||
bool need_switching(CellInfo *cell, IdString port)
|
||||
{
|
||||
PortRef sink;
|
||||
sink.cell = cell;
|
||||
sink.port = port;
|
||||
|
||||
NetInfo *net_info = cell->getPort(port);
|
||||
if (!net_info)
|
||||
return false;
|
||||
|
||||
WireId dst_wire = ctx->getNetinfoSinkWire(net_info, sink, 0);
|
||||
|
||||
WireId cursor = dst_wire;
|
||||
auto it = net_info->wires.find(cursor);
|
||||
|
||||
PipId pip = it->second.pip;
|
||||
const auto &extra_data = *uarch->pip_extra_data(pip);
|
||||
if (extra_data.type == PipExtra::PIP_EXTRA_MUX && (extra_data.flags & MUX_PERMUTATION)) {
|
||||
if (extra_data.value)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void update_cpe_lt(CellInfo *cell, IdString port, IdString init, dict<IdString, Property> ¶ms, bool even)
|
||||
{
|
||||
unsigned init_val = int_or_default(params, init);
|
||||
@ -317,6 +341,14 @@ struct BitstreamBackend
|
||||
case id_CPE_RAMIO.index: {
|
||||
// Update configuration bits based on signal inversion
|
||||
dict<IdString, Property> params = cell.second->params;
|
||||
auto update_param = [&](IdString name) {
|
||||
int x = int_or_default(params, name, 0);
|
||||
// when inputs exchange theier places in LUT2
|
||||
// function changes so bit 1 and bit 2 exchange values
|
||||
int y = x ^ (( ( (x >> 1) ^ (x >> 2) ) & 1 ) << 1)
|
||||
^ (( ( (x >> 1) ^ (x >> 2) ) & 1 ) << 2);
|
||||
params[name] = Property(y ,4);
|
||||
};
|
||||
Loc l = ctx->getBelLocation(cell.second->bel);
|
||||
params.erase(id_L2T4_UPPER);
|
||||
params.erase(id_MULT_INVERT);
|
||||
@ -324,6 +356,13 @@ struct BitstreamBackend
|
||||
int c_i2 = int_or_default(params, id_C_I2, 0);
|
||||
int c_i3 = int_or_default(params, id_C_I3, 0);
|
||||
int c_i4 = int_or_default(params, id_C_I4, 0);
|
||||
|
||||
if (cell.second->type.in(id_CPE_BRIDGE)) {
|
||||
int in = int_or_default(params, id_C_SN, 0);
|
||||
if (need_switching(cell.second.get(), ctx->idf("IN%d", in+1)))
|
||||
params[id_C_SN] = Property(in ^ 1,3);
|
||||
}
|
||||
|
||||
if (cell.second->type.in(id_CPE_L2T4, id_CPE_LT_L, id_CPE_LT_U)) {
|
||||
if (l.z == CPE_LT_U_Z) {
|
||||
update_cpe_lt(cell.second.get(), id_IN1, id_INIT_L00, params, true);
|
||||
@ -337,6 +376,12 @@ struct BitstreamBackend
|
||||
update_cpe_lt(cell.second.get(), id_IN3, id_INIT_L01, params, true);
|
||||
update_cpe_lt(cell.second.get(), c_i4 ? id_PINX : id_IN4, id_INIT_L01, params, false);
|
||||
}
|
||||
if (need_switching(cell.second.get(), id_IN1) || need_switching(cell.second.get(), id_IN2)) {
|
||||
update_param(id_INIT_L00);
|
||||
}
|
||||
if (need_switching(cell.second.get(), id_IN3) || need_switching(cell.second.get(), id_IN4)) {
|
||||
update_param(id_INIT_L01);
|
||||
}
|
||||
}
|
||||
if (l.z == CPE_LT_FULL_Z) {
|
||||
if (!cell.second->type.in(id_CPE_MULT)) {
|
||||
@ -359,6 +404,18 @@ struct BitstreamBackend
|
||||
update_cpe_lt(cell.second.get(), id_IN7, id_INIT_L03, params, true);
|
||||
update_cpe_lt(cell.second.get(), c_i4 ? id_PINX : id_IN8, id_INIT_L03, params, false);
|
||||
}
|
||||
if (need_switching(cell.second.get(), id_IN1) || need_switching(cell.second.get(), id_IN2)) {
|
||||
update_param(id_INIT_L00);
|
||||
}
|
||||
if (need_switching(cell.second.get(), id_IN3) || need_switching(cell.second.get(), id_IN4)) {
|
||||
update_param(id_INIT_L01);
|
||||
}
|
||||
if (need_switching(cell.second.get(), id_IN5) || need_switching(cell.second.get(), id_IN6)) {
|
||||
update_param(id_INIT_L02);
|
||||
}
|
||||
if (need_switching(cell.second.get(), id_IN7) || need_switching(cell.second.get(), id_IN8)) {
|
||||
update_param(id_INIT_L03);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -85,6 +85,7 @@ enum MuxFlags
|
||||
MUX_VISIBLE = 2,
|
||||
MUX_CONFIG = 4,
|
||||
MUX_ROUTING = 8,
|
||||
MUX_PERMUTATION = 16,
|
||||
};
|
||||
|
||||
enum PipExtra
|
||||
|
||||
@ -31,6 +31,7 @@ MUX_INVERT = 1
|
||||
MUX_VISIBLE = 2
|
||||
MUX_CONFIG = 4
|
||||
MUX_ROUTING = 8
|
||||
MUX_PERMUTATION = 16
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("--lib", help="Project Peppercorn python database script path", type=str, required=True)
|
||||
@ -310,6 +311,8 @@ def main():
|
||||
plane = int(mux.name[10:12])
|
||||
if mux.name == "CPE.C_SN":
|
||||
mux_flags |= MUX_ROUTING
|
||||
if mux.name.startswith("CPE.PERM"):
|
||||
mux_flags |= MUX_PERMUTATION
|
||||
pp.extra_data = PipExtraData(PIP_EXTRA_MUX, ch.strs.id(mux.name), mux.bits, mux.value, mux_flags, plane)
|
||||
if type_name in new_wires:
|
||||
for wire in sorted(new_wires[type_name]):
|
||||
|
||||
@ -309,6 +309,16 @@ void GateMatePacker::repack_cpe()
|
||||
if (!cell.second->params.count(id_INIT_L20))
|
||||
cell.second->params[id_INIT_L20] = Property(LUT_D1, 4);
|
||||
}
|
||||
if (cell.second->getPort(id_IN1) && cell.second->getPort(id_IN2)) {
|
||||
if (cell.second->getPort(id_IN1) == cell.second->getPort(id_IN2)) {
|
||||
log_error("Used same signal for IN1 and IN2 in %s\n", cell.second->name.c_str(ctx));
|
||||
}
|
||||
}
|
||||
if (cell.second->getPort(id_IN3) && cell.second->getPort(id_IN4)) {
|
||||
if (cell.second->getPort(id_IN3) == cell.second->getPort(id_IN4)) {
|
||||
log_error("Used same signal for IN3 and IN4 in %s\n", cell.second->name.c_str(ctx));
|
||||
}
|
||||
}
|
||||
cell.second->params[id_L2T4_UPPER] = Property((l.z == CPE_LT_U_Z) ? 1 : 0, 1);
|
||||
} else if (cell.second->type.in(id_CPE_LT_L)) {
|
||||
BelId bel = cell.second->bel;
|
||||
@ -318,6 +328,16 @@ void GateMatePacker::repack_cpe()
|
||||
loc.z = CPE_LT_FULL_Z;
|
||||
ctx->unbindBel(bel);
|
||||
ctx->bindBel(ctx->getBelByLocation(loc), cell.second.get(), strength);
|
||||
if (cell.second->getPort(id_IN1) && cell.second->getPort(id_IN2)) {
|
||||
if (cell.second->getPort(id_IN1) == cell.second->getPort(id_IN2)) {
|
||||
log_error("Used same signal for IN1 and IN2 in %s\n", cell.second->name.c_str(ctx));
|
||||
}
|
||||
}
|
||||
if (cell.second->getPort(id_IN3) && cell.second->getPort(id_IN4)) {
|
||||
if (cell.second->getPort(id_IN3) == cell.second->getPort(id_IN4)) {
|
||||
log_error("Used same signal for IN3 and IN4 in %s\n", cell.second->name.c_str(ctx));
|
||||
}
|
||||
}
|
||||
cell.second->renamePort(id_IN1, id_IN5);
|
||||
cell.second->renamePort(id_IN2, id_IN6);
|
||||
cell.second->renamePort(id_IN3, id_IN7);
|
||||
@ -374,6 +394,17 @@ void GateMatePacker::repack_cpe()
|
||||
upper->movePortTo(id_IN4, cell.second.get(), id_IN4);
|
||||
upper->movePortTo(id_OUT, cell.second.get(), id_OUT2);
|
||||
upper->movePortTo(id_CPOUT, cell.second.get(), id_CPOUT2);
|
||||
if (cell.second->getPort(id_IN1) && cell.second->getPort(id_IN2)) {
|
||||
if (cell.second->getPort(id_IN1) == cell.second->getPort(id_IN2)) {
|
||||
log_error("Used same signal for IN1 and IN2 in %s\n", cell.second->name.c_str(ctx));
|
||||
}
|
||||
}
|
||||
if (cell.second->getPort(id_IN3) && cell.second->getPort(id_IN4)) {
|
||||
if (cell.second->getPort(id_IN3) == cell.second->getPort(id_IN4)) {
|
||||
log_error("Used same signal for IN3 and IN4 in %s\n", cell.second->name.c_str(ctx));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
// Mark for deletion
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user