Skip to content

Commit 9e32af1

Browse files
authored
Merge pull request #781 from os-fpga/checker_improved_PG_and_dot
checker: improved pinGraph and .dot output
2 parents 880c280 + 4489f94 commit 9e32af1

File tree

5 files changed

+102
-86
lines changed

5 files changed

+102
-86
lines changed

planning/src/RS/rsCheck.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ static void nw_test_01() {
200200
g.dumpDot("g");
201201
std::ofstream fos("g.dot");
202202
if (fos.is_open()) {
203-
g.printDot(fos, nullptr, false);
203+
g.printDot(fos, nullptr, false, false);
204204
lputs(" written g.dot");
205205
fos.close();
206206
} else {

planning/src/file_readers/pln_blif_file.cpp

Lines changed: 31 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1042,10 +1042,16 @@ bool BLIF_file::createNodes() noexcept {
10421042
}
10431043
if (not nd.inSigs_.empty()) {
10441044
std::sort(nd.inSigs_.begin(), nd.inSigs_.end());
1045-
pr_get_inputs(nd.ptype_, nd.inPins_);
1046-
assert(nd.inPins_.size() == nd.inSigs_.size());
1047-
std::sort(nd.inPins_.begin(), nd.inPins_.end());
1048-
// strip everything before '=' in inSigs_, e.g. A[1]=sig_a --> sig_a
1045+
if (0) {
1046+
// if we get inPins_ from Prim-DB, sometimes they won't match
1047+
// the signals. The blif may be generated with an old version
1048+
// of Prim-DB. But the checker should be robust.
1049+
pr_get_inputs(nd.ptype_, nd.inPins_);
1050+
assert(nd.inPins_.size() == nd.inSigs_.size());
1051+
}
1052+
nd.inPins_.clear();
1053+
nd.inPins_.reserve(nd.inSigs_.size());
1054+
// strip the name before '=' in inSigs_, e.g. A[1]=sig_a --> sig_a
10491055
for (string& ss : nd.inSigs_) {
10501056
assert(!ss.empty());
10511057
V.clear();
@@ -1055,8 +1061,13 @@ bool BLIF_file::createNodes() noexcept {
10551061
if (buf[k] == '=') buf[k] = ' ';
10561062
}
10571063
Fio::split_spa(buf, V);
1058-
if (not V.empty()) ss = V.back();
1064+
if (V.size() > 1) {
1065+
ss = V.back();
1066+
nd.inPins_.push_back(V.front());
1067+
}
10591068
}
1069+
assert(nd.inPins_.size() == nd.inSigs_.size());
1070+
// std::sort(nd.inPins_.begin(), nd.inPins_.end());
10601071
}
10611072
}
10621073
fabricNodes_.push_back(&nd);
@@ -1420,59 +1431,6 @@ bool BLIF_file::checkClockSepar(vector<const Node*>& clocked) noexcept {
14201431
err_puts(); flush_out(true);
14211432
}
14221433

1423-
#if 0
1424-
NW g;
1425-
auto& ls = lout();
1426-
char nm_buf[512] = {};
1427-
1428-
for (const Node* np : clocked) {
1429-
const Node& nd = *np;
1430-
if (not pr_num_clocks(nd.ptype_))
1431-
continue;
1432-
if (nd.ptype_ == CLK_BUF)
1433-
continue;
1434-
if (nd.parent_ == 0)
1435-
continue;
1436-
lprintf("...... checking clock-separ for node #%u of type %s\n",
1437-
nd.id_, nd.cPrimType());
1438-
lprintf("\t\t parent= %u\n", nd.parent_);
1439-
1440-
g.clear();
1441-
1442-
uint64_t rhash = nd.hashCode();
1443-
uint g_rid = g.addNode(rhash);
1444-
g.addRoot(g_rid);
1445-
1446-
const Node& par = nodeRef(nd.parent_);
1447-
1448-
uint g_pid = g.insK(par.hashCode());
1449-
g.markSink(g_pid, true);
1450-
1451-
g.linkNodes(g_rid, g_pid, false);
1452-
1453-
::snprintf(nm_buf, 510, "%s_%uL", nd.cPrimType(), nd.lnum_);
1454-
g.setNodeName(g_rid, nm_buf);
1455-
1456-
::snprintf(nm_buf, 510, "%s_%uL", par.cPrimType(), par.lnum_);
1457-
g.setNodeName(g_pid, nm_buf);
1458-
1459-
uint bh_id = g.insK(111);
1460-
g.markSink(bh_id, true);
1461-
g.setNodeName(bh_id, "BH1");
1462-
1463-
g.linkNodes(g_pid, bh_id, false);
1464-
1465-
g.labelDepth();
1466-
1467-
g.dump("\t *** g separ ***");
1468-
lprintf("\t g. numN()= %u numE()= %u\n", g.numN(), g.numE());
1469-
g.printSum(ls, 0);
1470-
1471-
lputs("\n\t***** break; // TMP");
1472-
break; // TMP
1473-
}
1474-
#endif //////////0000000000
1475-
14761434
return true;
14771435
}
14781436

@@ -1488,6 +1446,7 @@ bool BLIF_file::createPinGraph() noexcept {
14881446
uint nid = 0, kid = 0, eid = 0;
14891447
vector<string> INP;
14901448
vector<upair> PAR;
1449+
char nm_buf[512] = {};
14911450

14921451
// -- create pg-nodes for topInputs_
14931452
for (const Node* p : topInputs_) {
@@ -1496,6 +1455,7 @@ bool BLIF_file::createPinGraph() noexcept {
14961455
nid = pg_.insK(port.id_);
14971456
assert(nid);
14981457
pg_.setNodeName(nid, port.out_);
1458+
pg_.nodeRef(nid).markInp(true);
14991459
}
15001460

15011461
// -- create pg-nodes for topOutputs_
@@ -1505,6 +1465,7 @@ bool BLIF_file::createPinGraph() noexcept {
15051465
nid = pg_.insK(port.id_);
15061466
assert(nid);
15071467
pg_.setNodeName(nid, port.out_);
1468+
pg_.nodeRef(nid).markOut(true);
15081469
}
15091470

15101471
// -- link from input ports to fabric
@@ -1524,6 +1485,8 @@ bool BLIF_file::createPinGraph() noexcept {
15241485
}
15251486

15261487
for (const upair& pa : PAR) {
1488+
if (pa.first == port.id_)
1489+
continue;
15271490
const Node& par = nodeRef(pa.first);
15281491
uint pinIndex = pa.second;
15291492

@@ -1541,10 +1504,18 @@ bool BLIF_file::createPinGraph() noexcept {
15411504
assert(par.cell_hc_);
15421505
key = hashComb(par.cell_hc_, pinIndex);
15431506
assert(key);
1507+
assert(not pg_.hasKey(key));
15441508
kid = pg_.insK(key);
15451509
assert(kid);
1510+
assert(key != port.id_); // bc port.id_ is a key for port
1511+
assert(pg_.hasKey(port.id_)); //
1512+
1513+
pg_.nodeRef(kid).setCid(par.id_);
1514+
::snprintf(nm_buf, 510, "%s_%uL",
1515+
par.hasPrimType() ? par.cPrimType() : "NP", par.lnum_);
1516+
pg_.setNodeName(kid, nm_buf);
15461517

1547-
eid = pg_.linK(port.id_, kid);
1518+
eid = pg_.linK(port.id_, key);
15481519
assert(eid);
15491520
}
15501521
}
@@ -1560,7 +1531,7 @@ bool BLIF_file::createPinGraph() noexcept {
15601531
pg_.dumpEdges("|edges|");
15611532
lputs();
15621533

1563-
bool wrDot_ok = pg_.writeDot("pinGraph.dot", nullptr, true);
1534+
bool wrDot_ok = pg_.writeDot("pinGraph.dot", nullptr, true, true);
15641535
lprintf("wrDot_ok:%i\n", wrDot_ok);
15651536

15661537
}

planning/src/main.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
static const char* _pln_VERSION_STR = "pln0295";
1+
static const char* _pln_VERSION_STR = "pln0299";
22

33
#include "RS/rsEnv.h"
44
#include "util/pln_log.h"

planning/src/util/nw/Nw.cpp

Lines changed: 53 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,19 @@ upair NW::getMinMaxLbl() const noexcept {
238238
return L;
239239
}
240240

241+
uint NW::findNode(uint64_t k) const noexcept {
242+
assert(k);
243+
if (!k) return 0;
244+
245+
// TMP. LINEAR.
246+
for (cNI I(*this); I.valid(); ++I) {
247+
const Node& nd = *I;
248+
if (nd.key_ == k)
249+
return nd.id_;
250+
}
251+
return 0;
252+
}
253+
241254
// ==== DEBUG
242255

243256
void NW::dot_comment(ostream& os, uint16_t dotMode, CStr msg) noexcept {
@@ -291,27 +304,44 @@ void NW::Node::print(ostream& os) const noexcept {
291304
os << endl;
292305
}
293306

307+
static void replace_bus_for_dot(char* buf) noexcept {
308+
assert(buf);
309+
// replace [] by __
310+
for (char* p = buf; *p; p++) {
311+
if (*p == '[' or *p == ']')
312+
*p = '_';
313+
}
314+
}
315+
294316
void NW::Node::nprint_dot(ostream& os) const noexcept {
295-
os << " " << getName();
317+
char buf[2048] = {};
318+
getName(buf);
319+
replace_bus_for_dot(buf);
296320

297-
os_printf(os, " // deg= %u;\n", degree());
321+
CStr attrib = "[ shape=record, style=rounded ];";
322+
if (inp_flag_)
323+
attrib = "[ shape=box, color=gray, style=filled ];";
324+
325+
os_printf(os, "%s %s // deg= %u;\n",
326+
buf, attrib, degree());
298327
}
299328

300329
void NW::Edge::eprint_dot(ostream& os, char arrow, const NW& g) const noexcept {
301330
assert(arrow == '>' or arrow == '-');
331+
char buf[2048] = {};
332+
g.nodeRef(n1_).getName(buf);
333+
replace_bus_for_dot(buf);
334+
os_printf(os, "%s -%c ", buf, arrow);
302335

303-
os << g.nodeRef(n1_).getName();
304-
305-
os << " -" << arrow << ' ';
306-
307-
os << g.nodeRef(n2_).getName();
336+
buf[0] = 0;
337+
g.nodeRef(n2_).getName(buf);
338+
replace_bus_for_dot(buf);
339+
os << buf;
308340

309341
if (inCell_) {
310-
os << " [ style=dashed";
311-
os << " ] ";
342+
os_printf(os, " [ style=dashed ] ");
312343
}
313-
314-
os << ";\n";
344+
os_printf(os, ";\n");
315345
}
316346

317347
uint NW::print(ostream& os, CStr msg) const noexcept {
@@ -388,6 +418,7 @@ uint NW::printSum(ostream& os, uint16_t forDot) const noexcept {
388418
upair mmL = getMinMaxLbl();
389419
upair rcnt = countRoots();
390420

421+
dot_comment(os, forDot);
391422
os_printf(os, "nn= %u ne= %u nr= %zu r0= %u",
392423
numN(), numE(), rids_.size(), first_rid());
393424

@@ -443,7 +474,7 @@ bool NW::writeMetis(CStr fn, bool nodeTable) const noexcept {
443474
return (ok and status > 0);
444475
}
445476

446-
uint NW::printDot(ostream& os, CStr nwNm, bool nodeTable) const noexcept {
477+
uint NW::printDot(ostream& os, CStr nwNm, bool nodeTable, bool noDeg0) const noexcept {
447478
if (!printSum(os, 1)) return 0;
448479
if (nodeTable) {
449480
printNodes(os, nullptr, 1);
@@ -454,13 +485,17 @@ uint NW::printDot(ostream& os, CStr nwNm, bool nodeTable) const noexcept {
454485
if (not nw_name_.empty())
455486
nwNm = nw_name_.c_str();
456487
}
457-
os_printf(os, "digraph %s {\n", (nwNm and nwNm[0]) ? nwNm : "G");
488+
os_printf(os, "\ndigraph %s {\n", (nwNm and nwNm[0]) ? nwNm : "G");
489+
os_printf(os, " label=\"%s\";\n", (nwNm and nwNm[0]) ? nwNm : "G");
458490

459491
// os << " node [rankdir=LR];\n";
460-
os << " node [shape = circle];\n";
492+
os << " node [shape = record];\n";
461493

462494
for (cNI I(*this); I.valid(); ++I) {
463-
I->nprint_dot(os);
495+
const Node& ii = *I;
496+
if (noDeg0 and ii.degree() == 0)
497+
continue;
498+
ii.nprint_dot(os);
464499
}
465500
os << std::endl;
466501

@@ -471,9 +506,9 @@ uint NW::printDot(ostream& os, CStr nwNm, bool nodeTable) const noexcept {
471506
os_printf(os, "}\n");
472507
return size();
473508
}
474-
uint NW::dumpDot(CStr nwNm) const noexcept { return printDot(lout(), nwNm, false); }
509+
uint NW::dumpDot(CStr nwNm) const noexcept { return printDot(lout(), nwNm, false, false); }
475510

476-
bool NW::writeDot(CStr fn, CStr nwNm, bool nodeTable) const noexcept {
511+
bool NW::writeDot(CStr fn, CStr nwNm, bool nodeTable, bool noDeg0) const noexcept {
477512
assert(fn);
478513
if (!fn or !fn[0]) return false;
479514
if (empty()) return false;
@@ -483,7 +518,7 @@ bool NW::writeDot(CStr fn, CStr nwNm, bool nodeTable) const noexcept {
483518

484519
std::ofstream f(fn);
485520
if (f.is_open()) {
486-
status = printDot(f, nwNm, nodeTable);
521+
status = printDot(f, nwNm, nodeTable, noDeg0);
487522
if (trace_ >= 3) lprintf(" written %s status: %u\n\n", fn, status);
488523
f.close();
489524
} else {

planning/src/util/nw/Nw.h

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,14 @@ struct NW {
8585
}
8686
return name_;
8787
}
88+
void getName(char* buf) const noexcept {
89+
if (!buf) return;
90+
if (name_.empty()) {
91+
::sprintf(buf, "nd_%u", id_);
92+
} else {
93+
::strncpy(buf, name_.c_str(), 2000);
94+
}
95+
}
8896

8997
const XY& xy() const noexcept { return *this; }
9098
bool hasCoord() const noexcept { return valid() ? XY::valid() : false; }
@@ -121,6 +129,8 @@ struct NW {
121129
bool isFlagRoot() const noexcept { return root_flag_; }
122130
void markRoot(bool val) noexcept { root_flag_ = val; }
123131
void markSink(bool val) noexcept { sink_flag_ = val; }
132+
void markInp(bool val) noexcept { inp_flag_ = val; }
133+
void markOut(bool val) noexcept { out_flag_ = val; }
124134
bool terminal() const noexcept { return sink_flag_ or root_flag_; }
125135

126136
void print(ostream& os) const noexcept;
@@ -144,6 +154,8 @@ struct NW {
144154
// DATA:
145155
bool root_flag_ = false;
146156
bool sink_flag_ = false;
157+
bool inp_flag_ = false;
158+
bool out_flag_ = false;
147159
string name_;
148160
};
149161

@@ -385,10 +397,8 @@ struct NW {
385397

386398
inline uint findEdge(uint a, uint b) const noexcept;
387399

388-
uint findNode(uint64_t k) const noexcept {
389-
assert(0);
390-
return 0;
391-
}
400+
uint findNode(uint64_t k) const noexcept;
401+
bool hasKey(uint64_t k) const noexcept { return findNode(k); }
392402

393403
uint cid(const Edge& e) const noexcept {
394404
assert(e.n1_ and e.n2_);
@@ -433,9 +443,9 @@ struct NW {
433443
uint dumpMetis(bool nodeTable) const noexcept;
434444
bool writeMetis(CStr fn, bool nodeTable) const noexcept;
435445

436-
uint printDot(ostream& os, CStr nwNm, bool nodeTable = false) const noexcept;
446+
uint printDot(ostream& os, CStr nwNm, bool nodeTable, bool noDeg0) const noexcept;
437447
uint dumpDot(CStr nwNm) const noexcept;
438-
bool writeDot(CStr fn, CStr nwNm, bool nodeTable = false) const noexcept;
448+
bool writeDot(CStr fn, CStr nwNm, bool nodeTable, bool noDeg0) const noexcept;
439449

440450
void beComplete() noexcept;
441451

0 commit comments

Comments
 (0)