Added MX2 and MX4 support
This commit is contained in:
parent
94071078dc
commit
e6450a179b
@ -119,3 +119,13 @@ X(2D_IN)
|
|||||||
|
|
||||||
X(CC_BUFG)
|
X(CC_BUFG)
|
||||||
X(BUFG)
|
X(BUFG)
|
||||||
|
|
||||||
|
X(CC_MX2)
|
||||||
|
X(CC_MX4)
|
||||||
|
X(FUNCTION)
|
||||||
|
X(D0)
|
||||||
|
X(D1)
|
||||||
|
X(D2)
|
||||||
|
X(D3)
|
||||||
|
X(S0)
|
||||||
|
X(S1)
|
||||||
|
@ -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()
|
void GateMateImpl::setupArchContext()
|
||||||
{
|
{
|
||||||
const ArchArgs &args = ctx->args;
|
const ArchArgs &args = ctx->args;
|
||||||
|
@ -40,6 +40,7 @@ struct GateMateImpl : HimbaechelAPI
|
|||||||
|
|
||||||
void pack() override;
|
void pack() override;
|
||||||
|
|
||||||
|
void postPlace() override;
|
||||||
void postRoute() override;
|
void postRoute() override;
|
||||||
|
|
||||||
bool isBelLocationValid(BelId bel, bool explain_invalid = false) const 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);
|
void write_bitstream(const std::string &device, const std::string &filename);
|
||||||
bool read_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);
|
void parse_ccf(const std::string &filename);
|
||||||
|
|
||||||
IdString getBelBucketForCellType(IdString cell_type) const;
|
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());
|
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);
|
return extra_data.type == PipExtra::PIP_EXTRA_MUX && (extra_data.flags & MUX_INVERT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pool<PipId> blocked_pips;
|
||||||
};
|
};
|
||||||
|
|
||||||
NEXTPNR_NAMESPACE_END
|
NEXTPNR_NAMESPACE_END
|
||||||
|
@ -316,6 +316,45 @@ void GateMatePacker::pack_cpe()
|
|||||||
ci.type = id_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) {
|
for (auto &cell : ctx->cells) {
|
||||||
CellInfo &ci = *cell.second;
|
CellInfo &ci = *cell.second;
|
||||||
if (!ci.type.in(id_CC_DFF))
|
if (!ci.type.in(id_CC_DFF))
|
||||||
|
Loading…
Reference in New Issue
Block a user