Skip to content

Commit

Permalink
Merge pull request #118 from tomverbeure/issue77
Browse files Browse the repository at this point in the history
Check that boundary nets are connected to a physical pin and nothing else.
  • Loading branch information
gatecat authored Aug 27, 2018
2 parents 969836e + c6085a6 commit c00a141
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 23 deletions.
1 change: 1 addition & 0 deletions src/arachne-pnr.cc
Original file line number Diff line number Diff line change
Expand Up @@ -486,6 +486,7 @@ main(int argc, const char **argv)

*logs << "prune...\n";
d->prune();
d->check_boundary_nets();
#ifndef NDEBUG
d->check();
#endif
Expand Down
89 changes: 66 additions & 23 deletions src/netlist.cc
Original file line number Diff line number Diff line change
Expand Up @@ -467,6 +467,63 @@ Model::add_instance(Model *inst_of)
return new_inst;
}

bool Model::is_physical_port(Models &models, const Port *p) const
{
bool is_phys_port = p
&& isa<Instance>(p->node())
&& ((models.is_tbuf(cast<Instance>(p->node()))
&& p->name() == "Y")
|| (models.is_ioX(cast<Instance>(p->node()))
&& p->name() == "PACKAGE_PIN")
|| (models.is_pllX(cast<Instance>(p->node()))
&& p->name() == "PACKAGEPIN")
|| (models.is_rgba_drv(cast<Instance>(p->node()))
&& (p->name() == "RGB0" || p->name() == "RGB1" || p->name() == "RGB2"))
);

return is_phys_port;
}

// Check that ports which are connected to physical port are
// connected to that port only
void
Model::check_boundary_nets(const Design *d) const
{
Models models(d);

for (Port *p : m_ordered_ports)
{
Net *n = p->connection();
if (!n)
continue;

bool is_boundary_net = false;
Port *physical_port = nullptr;

for(auto i = n->connections().begin(); i != n->connections().end(); ++i)
{
Port *q = *i;
if (p == q)
continue;

if (is_physical_port(models, q))
{
if (is_boundary_net)
fatal(fmt("Top level port '" << p->name() << "' assigned to multiple IO pads: '" <<
physical_port->name() << "' and '" << q->name() << "'"));

is_boundary_net = true;
physical_port = q;
}
}

if (is_boundary_net && n->connections().size() != 2)
fatal(fmt("Top level port '" << p->name() << "' assigned to an IO pad '" << physical_port->name() <<
"' and internal nodes"));

}
}

std::set<Net *, IdLess>
Model::boundary_nets(const Design *d) const
{
Expand All @@ -478,17 +535,7 @@ Model::boundary_nets(const Design *d) const
if (n)
{
Port *q = p->connection_other_port();
if (q
&& isa<Instance>(q->node())
&& ((models.is_tbuf(cast<Instance>(q->node()))
&& q->name() == "Y")
|| (models.is_ioX(cast<Instance>(q->node()))
&& q->name() == "PACKAGE_PIN")
|| (models.is_pllX(cast<Instance>(q->node()))
&& q->name() == "PACKAGEPIN")
|| (models.is_rgba_drv(cast<Instance>(q->node()))
&& (q->name() == "RGB0" || q->name() == "RGB1" || q->name() == "RGB2")
)))
if (is_physical_port(models, q))
extend(bnets, n);
}
}
Expand Down Expand Up @@ -632,16 +679,7 @@ Model::check(const Design *d) const
if (n)
{
Port *q = p->connection_other_port();
assert (q
&& isa<Instance>(q->node())
&& ((models.is_tbuf(cast<Instance>(q->node()))
&& q->name() == "Y")
|| (models.is_ioX(cast<Instance>(q->node()))
&& q->name() == "PACKAGE_PIN")
|| (models.is_pllX(cast<Instance>(q->node()))
&& q->name() == "PACKAGEPIN")
|| (models.is_rgba_drv(cast<Instance>(q->node()))
&& (q->name() == "RGB0" || q->name() == "RGB1" || q->name() == "RGB2"))));
assert(is_physical_port(models, q));
}
}
}
Expand Down Expand Up @@ -1504,12 +1542,17 @@ Design::prune()
p.second->prune();
}

void
Design::check_boundary_nets() const
{
m_top->check_boundary_nets(this);
}

#ifndef NDEBUG
void
Design::check() const
{
for (const auto &p : m_models)
p.second->check(this);
m_top->check(this);
}
#endif

Expand Down
4 changes: 4 additions & 0 deletions src/netlist.hh
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ class Port;
class Node;
class Instance;
class Model;
class Models;
class Design;

class Identified
Expand Down Expand Up @@ -369,6 +370,8 @@ public:

bool has_param(const std::string &pn) { return contains_key(m_params, pn); }

bool is_physical_port(Models &models, const Port *p) const;
void check_boundary_nets(const Design *d) const;
std::set<Net *, IdLess> boundary_nets(const Design *d) const;
std::pair<std::vector<Net *>, std::map<Net *, int, IdLess>>
index_nets() const;
Expand Down Expand Up @@ -411,6 +414,7 @@ public:
void write_verilog(std::ostream &s) const;
void write_blif(std::ostream &s) const;
void dump() const;
void check_boundary_nets() const;
#ifndef NDEBUG
void check() const;
#endif
Expand Down

0 comments on commit c00a141

Please sign in to comment.