Added MX2 and MX4 support

This commit is contained in:
Miodrag Milanovic 2025-01-09 14:27:21 +01:00
parent 94071078dc
commit e6450a179b
4 changed files with 87 additions and 0 deletions

View File

@ -119,3 +119,13 @@ X(2D_IN)
X(CC_BUFG)
X(BUFG)
X(CC_MX2)
X(CC_MX4)
X(FUNCTION)
X(D0)
X(D1)
X(D2)
X(D3)
X(S0)
X(S1)

View File

@ -149,6 +149,38 @@ void GateMateImpl::postRoute()
}
}
void GateMateImpl::postPlace()
{
log_break();
log_info("Limiting routing...\n");
for (auto &cell : ctx->cells) {
CellInfo &ci = *cell.second;
if (ci.type == id_CPE) {
if (!ci.params.count(id_FUNCTION)) continue;
uint8_t func = int_or_default(ci.params, id_FUNCTION, 0);
if (func!=4) continue; // Skip all that are not MUX
for (int i = 1; i <= 4; i++) {
IdString port = ctx->idf("IN%d", i);
NetInfo *net = ci.getPort(port);
if (!net)
continue;
WireId dwire = ctx->getBelPinWire(ci.bel, port);
for (PipId pip : ctx->getPipsUphill(dwire)) {
const auto extra_data = *reinterpret_cast<const GateMatePipExtraDataPOD *>(
chip_pip_info(ctx->chip_info, pip).extra_data.get());
if (!extra_data.name)
continue;
if (extra_data.type == PipExtra::PIP_EXTRA_MUX && (extra_data.flags & MUX_CPE_INV)) {
blocked_pips.emplace(pip);
}
}
}
}
}
ctx->assignArchInfo();
}
void GateMateImpl::setupArchContext()
{
const ArchArgs &args = ctx->args;

View File

@ -40,6 +40,7 @@ struct GateMateImpl : HimbaechelAPI
void pack() override;
void postPlace() override;
void postRoute() override;
bool isBelLocationValid(BelId bel, bool explain_invalid = false) const override;
@ -50,6 +51,9 @@ struct GateMateImpl : HimbaechelAPI
void write_bitstream(const std::string &device, const std::string &filename);
bool read_bitstream(const std::string &device, const std::string &filename);
bool checkPipAvail(PipId pip) const override { return blocked_pips.count(pip) == 0; }
bool checkPipAvailForNet(PipId pip, const NetInfo *net) const override { return checkPipAvail(pip); };
void parse_ccf(const std::string &filename);
IdString getBelBucketForCellType(IdString cell_type) const;
@ -59,6 +63,8 @@ struct GateMateImpl : HimbaechelAPI
const auto &extra_data = *reinterpret_cast<const GateMatePipExtraDataPOD*>(chip_pip_info(ctx->chip_info, pip).extra_data.get());
return extra_data.type == PipExtra::PIP_EXTRA_MUX && (extra_data.flags & MUX_INVERT);
}
pool<PipId> blocked_pips;
};
NEXTPNR_NAMESPACE_END

View File

@ -316,6 +316,45 @@ void GateMatePacker::pack_cpe()
ci.type = id_CPE;
}
for (auto &cell : ctx->cells) {
CellInfo &ci = *cell.second;
if (!ci.type.in(id_CC_MX2, id_CC_MX4))
continue;
if (ci.type == id_CC_MX2) {
ci.renamePort(id_S0, id_IN6);
ci.renamePort(id_D0, id_IN1);
ci.renamePort(id_D1, id_IN2);
ci.renamePort(id_Y, id_OUT1);
ci.params[id_FUNCTION] = Property(0b100, 3);
ci.params[id_INIT_L02] = Property(0b1100, 4); // IN6
ci.params[id_INIT_L10] = Property(0b0011, 4);
ci.params[id_INIT_L11] = Property(0b0011, 4);
ci.params[id_INIT_L20] = Property(0b0011, 4);
ci.params[id_O1] = Property(0b11, 2);
ci.type = id_CPE;
} else {
ci.renamePort(id_D0, id_IN1);
ci.renamePort(id_D1, id_IN2);
ci.renamePort(id_D2, id_IN3);
ci.renamePort(id_D3, id_IN4);
ci.renamePort(id_S0, id_IN6);
ci.renamePort(id_S1, id_IN8);
ci.renamePort(id_Y, id_OUT1);
ci.params[id_FUNCTION] = Property(0b100, 3);
ci.params[id_INIT_L02] = Property(0b1100, 4); // IN6
ci.params[id_INIT_L03] = Property(0b1100, 4); // IN8
ci.params[id_INIT_L10] = Property(0b1111, 4);
ci.params[id_INIT_L11] = Property(0b0011, 4);
ci.params[id_INIT_L20] = Property(0b1100, 4);
ci.params[id_O1] = Property(0b11, 2);
ci.type = id_CPE;
}
}
for (auto &cell : ctx->cells) {
CellInfo &ci = *cell.second;
if (!ci.type.in(id_CC_DFF))