blob: 9b1ee7fef64ff1dfcf69a82c2ca9e062e59211ec (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
|
#include <assert.h>
#include <string>
#include "log.h"
#include "nextpnr.h"
NEXTPNR_NAMESPACE_BEGIN
bool check_all_nets_driven(Context *ctx)
{
const bool debug = false;
log_info("Rule checker, Verifying pre-placed design\n");
for (auto cell_entry : ctx->cells) {
CellInfo *cell = cell_entry.second;
if (debug)
log_info(" Examining cell \'%s\', of type \'%s\'\n",
cell->name.c_str(ctx), cell->type.c_str(ctx));
for (auto port_entry : cell->ports) {
PortInfo &port = port_entry.second;
if (debug)
log_info(" Checking name of port \'%s\' "
"against \'%s\'\n",
port_entry.first.c_str(ctx), port.name.c_str(ctx));
assert(port.name == port_entry.first);
assert(!port.name.empty());
if (port.net == NULL) {
if (debug)
log_warning(
" Port \'%s\' in cell \'%s\' is unconnected\n",
port.name.c_str(ctx), cell->name.c_str(ctx));
} else {
assert(port.net);
if (debug)
log_info(" Checking for a net named \'%s\'\n",
port.net->name.c_str(ctx));
assert(ctx->nets.count(port.net->name) > 0);
}
}
}
for (auto net_entry : ctx->nets) {
NetInfo *net = net_entry.second;
assert(net->name == net_entry.first);
if ((net->driver.cell != NULL) &&
(net->driver.cell->type != ctx->id("GND")) &&
(net->driver.cell->type != ctx->id("VCC"))) {
if (debug)
log_info(" Checking for a driver cell named \'%s\'\n",
net->driver.cell->name.c_str(ctx));
assert(ctx->cells.count(net->driver.cell->name) > 0);
}
for (auto user : net->users) {
if ((user.cell != NULL) && (user.cell->type != ctx->id("GND")) &&
(user.cell->type != ctx->id("VCC"))) {
if (debug)
log_info(" Checking for a user cell named \'%s\'\n",
user.cell->name.c_str(ctx));
assert(ctx->cells.count(user.cell->name) > 0);
}
}
}
if (debug)
log_info(" Verified!\n");
return true;
}
NEXTPNR_NAMESPACE_END
|