xilinx: Fix BRAM placement, clangformat

Signed-off-by: gatecat <gatecat@ds0.me>
This commit is contained in:
gatecat 2024-09-27 16:24:47 +02:00
parent 38e5faca85
commit d3c0f945da
6 changed files with 50 additions and 35 deletions

View File

@ -316,7 +316,8 @@ void XilinxPacker::pack_dram()
} }
std::vector<NetInfo *> address(cs.wa.begin(), cs.wa.begin() + std::min<size_t>(cs.wa.size(), 6)); std::vector<NetInfo *> address(cs.wa.begin(), cs.wa.begin() + std::min<size_t>(cs.wa.size(), 6));
CellInfo *ram = create_dram_lut(cell->name.str(ctx) + "/ADDR", base, cs, address, cell->getPort(id_D), cell->getPort(id_O), z); CellInfo *ram = create_dram_lut(cell->name.str(ctx) + "/ADDR", base, cs, address, cell->getPort(id_D),
cell->getPort(id_O), z);
if (cell->params.count(id_INIT)) if (cell->params.count(id_INIT))
ram->params[id_INIT] = cell->params[id_INIT]; ram->params[id_INIT] = cell->params[id_INIT];
if (base == nullptr) if (base == nullptr)

View File

@ -28,13 +28,15 @@ NEXTPNR_NAMESPACE_BEGIN
static bool is_cascade_input(const PortInfo &port, const Context *ctx) static bool is_cascade_input(const PortInfo &port, const Context *ctx)
{ {
if(port.name == id_CARRYCASCIN || port.name == id_MULTSIGNIN) return true; if (port.name == id_CARRYCASCIN || port.name == id_MULTSIGNIN)
return true;
const std::string &str = port.name.c_str(ctx); const std::string &str = port.name.c_str(ctx);
return boost::starts_with(str, "ACIN") || boost::starts_with(str, "BCIN") || boost::starts_with(str, "PCIN"); return boost::starts_with(str, "ACIN") || boost::starts_with(str, "BCIN") || boost::starts_with(str, "PCIN");
} }
static bool is_cascade_output(const PortInfo &port, const Context *ctx) static bool is_cascade_output(const PortInfo &port, const Context *ctx)
{ {
if(port.name == id_CARRYCASCOUT || port.name == id_MULTSIGNOUT) return true; if (port.name == id_CARRYCASCOUT || port.name == id_MULTSIGNOUT)
return true;
const std::string &str = port.name.c_str(ctx); const std::string &str = port.name.c_str(ctx);
return boost::starts_with(str, "ACOUT") || boost::starts_with(str, "BCOUT") || boost::starts_with(str, "PCOUT"); return boost::starts_with(str, "ACOUT") || boost::starts_with(str, "BCOUT") || boost::starts_with(str, "PCOUT");
} }
@ -51,16 +53,18 @@ unsigned XC7Packer::walk_dsp(CellInfo *root, CellInfo *current_cell, int constr_
PortRef &user = *ni->users.begin(); PortRef &user = *ni->users.begin();
if (user.cell->type != id_DSP48E1_DSP48E1) if (user.cell->type != id_DSP48E1_DSP48E1)
log_error("User %s of net %s is not a DSP block, but %s", log_error("User %s of net %s is not a DSP block, but %s", user.cell->name.c_str(ctx), ni->name.c_str(ctx),
user.cell->name.c_str(ctx), ni->name.c_str(ctx), user.cell->type.c_str(ctx)); user.cell->type.c_str(ctx));
}; };
// see if any cascade outputs are connected // see if any cascade outputs are connected
for (auto port : current_cell->ports) { for (auto port : current_cell->ports) {
if (!is_cascade_output(port.second, ctx)) continue; if (!is_cascade_output(port.second, ctx))
continue;
NetInfo *cout_net = port.second.net; NetInfo *cout_net = port.second.net;
if (cout_net == nullptr || cout_net->users.empty()) continue; if (cout_net == nullptr || cout_net->users.empty())
continue;
check_illegal_fanout(cout_net, port.first.c_str(ctx)); check_illegal_fanout(cout_net, port.first.c_str(ctx));
PortRef &user = *cout_net->users.begin(); PortRef &user = *cout_net->users.begin();
@ -138,16 +142,13 @@ void XC7Packer::pack_dsps()
// prjxray has extra bits for these ports to hardwire them to VCC/GND // prjxray has extra bits for these ports to hardwire them to VCC/GND
// as these seem to be interal to the tile, // as these seem to be interal to the tile,
// this saves us from having to route those externally // this saves us from having to route those externally
if (boost::starts_with(n, "D") || if (boost::starts_with(n, "D") || boost::starts_with(n, "RSTD") ||
boost::starts_with(n, "RSTD") ||
// TODO: these seem to be inverted for unknown reasons // TODO: these seem to be inverted for unknown reasons
// boost::starts_with(n, "INMODE") || // boost::starts_with(n, "INMODE") ||
// boost::starts_with(n, "ALUMODE2") || // boost::starts_with(n, "ALUMODE2") ||
// boost::starts_with(n, "ALUMODE3") || // boost::starts_with(n, "ALUMODE3") ||
boost::starts_with(n, "CARRYINSEL2") || boost::starts_with(n, "CARRYINSEL2") || boost::starts_with(n, "CED") ||
boost::starts_with(n, "CED") || boost::starts_with(n, "CEAD") || boost::starts_with(n, "CEINMODE") ||
boost::starts_with(n, "CEAD") ||
boost::starts_with(n, "CEINMODE") ||
boost::starts_with(n, "CEALUMODE")) { boost::starts_with(n, "CEALUMODE")) {
add_const_pin(port.second, gnd_pins, n, "$PACKER_GND_NET"); add_const_pin(port.second, gnd_pins, n, "$PACKER_GND_NET");
add_const_pin(port.second, vcc_pins, n, "$PACKER_VCC_NET"); add_const_pin(port.second, vcc_pins, n, "$PACKER_VCC_NET");
@ -164,7 +165,8 @@ void XC7Packer::pack_dsps()
for (auto ci : all_dsps) { for (auto ci : all_dsps) {
bool cascade_input_used = false; bool cascade_input_used = false;
for (auto port : ci->ports) { for (auto port : ci->ports) {
if (!is_cascade_input(port.second, ctx)) continue; if (!is_cascade_input(port.second, ctx))
continue;
if (port.second.net != nullptr) { if (port.second.net != nullptr) {
cascade_input_used = true; cascade_input_used = true;
break; break;

View File

@ -178,7 +178,19 @@ void XilinxImpl::update_logic_bel(BelId bel, CellInfo *cell)
} }
} }
void XilinxImpl::update_bram_bel(BelId bel, CellInfo *cell) {} void XilinxImpl::update_bram_bel(BelId bel, CellInfo *cell)
{
IdString type = ctx->getBelType(bel);
if (!type.in(id_RAMBFIFO18E2_RAMBFIFO18E2, id_RAMBFIFO36E2_RAMBFIFO36E2, id_RAMB18E2_RAMB18E2, id_FIFO36E2_FIFO36E2,
id_RAMBFIFO36E1_RAMBFIFO36E1, id_RAMB36E1_RAMB36E1, id_RAMB18E1_RAMB18E1))
return;
auto &tts = tile_status.at(bel.tile);
if (!tts.bts)
tts.bts = std::make_unique<BRAMTileStatus>();
int z = ctx->getBelLocation(bel).z;
NPNR_ASSERT(z >= 0 && z < 12);
tts.bts->cells[z] = cell;
}
bool XilinxImpl::is_pip_unavail(PipId pip) const bool XilinxImpl::is_pip_unavail(PipId pip) const
{ {