frontend/generic: Fix regressions

Signed-off-by: David Shah <dave@ds0.me>
This commit is contained in:
David Shah 2019-11-18 15:07:19 +00:00
parent c9a0033c5c
commit 28279b18fe
4 changed files with 32 additions and 22 deletions

View File

@ -538,6 +538,7 @@ template <typename FrontendType> struct GenericFrontend
auto drv = net->driver;
if (drv.cell != nullptr) {
disconnect_port(ctx, drv.cell, drv.port);
drv.cell->ports[drv.port].net = nullptr;
connect_port(ctx, split_iobuf_i, drv.cell, drv.port);
}
connect_port(ctx, split_iobuf_i, iobuf, ctx->id("I"));
@ -557,25 +558,32 @@ template <typename FrontendType> struct GenericFrontend
// Import ports of the top level module
void import_toplevel_ports(HierModuleState &m, const mod_dat_t &data)
{
impl.foreach_port(data, [&](const std::string &portname, const mod_port_dat_t &pd) {
const auto &port_bv = impl.get_port_bits(pd);
int offset = impl.get_array_offset(pd);
bool is_upto = impl.is_array_upto(pd);
int width = impl.get_vector_length(port_bv);
PortType dir = impl.get_port_dir(pd);
for (int i = 0; i < width; i++) {
std::string pbit_name = get_bit_name(portname, i, width, offset, is_upto);
NetInfo *port_net = nullptr;
if (impl.is_vector_bit_constant(port_bv, i)) {
// Port bit is constant. Need to create a new constant net.
port_net = create_constant_net(m, pbit_name + "$const", impl.get_vector_bit_constval(port_bv, i));
} else {
// Port bit is a signal. Need to create/get the associated net
port_net = create_or_get_net(m, impl.get_vector_bit_signal(port_bv, i));
// For correct handling of inout ports driving other ports
// first import non-inouts then import inouts so that they bifurcate correctly
for (bool inout : {false, true}) {
impl.foreach_port(data, [&](const std::string &portname, const mod_port_dat_t &pd) {
const auto &port_bv = impl.get_port_bits(pd);
int offset = impl.get_array_offset(pd);
bool is_upto = impl.is_array_upto(pd);
int width = impl.get_vector_length(port_bv);
PortType dir = impl.get_port_dir(pd);
if ((dir == PORT_INOUT) != inout)
return;
for (int i = 0; i < width; i++) {
std::string pbit_name = get_bit_name(portname, i, width, offset, is_upto);
NetInfo *port_net = nullptr;
if (impl.is_vector_bit_constant(port_bv, i)) {
// Port bit is constant. Need to create a new constant net.
port_net =
create_constant_net(m, pbit_name + "$const", impl.get_vector_bit_constval(port_bv, i));
} else {
// Port bit is a signal. Need to create/get the associated net
port_net = create_or_get_net(m, impl.get_vector_bit_signal(port_bv, i));
}
create_iobuf(port_net, dir, pbit_name);
}
create_iobuf(port_net, dir, pbit_name);
}
});
});
}
}
// Add a constant-driving VCC or GND cell to make a net constant
@ -688,4 +696,4 @@ template <typename FrontendType> struct GenericFrontend
};
} // namespace
NEXTPNR_NAMESPACE_END
NEXTPNR_NAMESPACE_END

View File

@ -190,4 +190,4 @@ bool parse_json(std::istream &in, const std::string &filename, Context *ctx)
return true;
}
NEXTPNR_NAMESPACE_END
NEXTPNR_NAMESPACE_END

View File

@ -23,4 +23,4 @@ NEXTPNR_NAMESPACE_BEGIN
bool parse_json(std::istream &in, const std::string &filename, Context *ctx);
NEXTPNR_NAMESPACE_END
NEXTPNR_NAMESPACE_END

View File

@ -527,7 +527,9 @@ static void pack_io(Context *ctx)
std::copy(ci->attrs.begin(), ci->attrs.end(), std::inserter(sb->attrs, sb->attrs.begin()));
} else if (is_sb_io(ctx, ci) || is_sb_gb_io(ctx, ci)) {
NetInfo *net = ci->ports.at(ctx->id("PACKAGE_PIN")).net;
if ((net != nullptr) && (net->users.size() > 1))
if ((net != nullptr) && ((net->users.size() > 2) ||
(net->driver.cell != nullptr &&
net->driver.cell->type == ctx->id("$nextpnr_obuf") && net->users.size() > 1)))
log_error("PACKAGE_PIN of %s '%s' connected to more than a single top level IO.\n", ci->type.c_str(ctx),
ci->name.c_str(ctx));
}