Skip to content

Commit 720d7e8

Browse files
committed
checker: better diagnostics for clock-data EDA-3235
1 parent 0807adc commit 720d7e8

File tree

8 files changed

+148
-47
lines changed

8 files changed

+148
-47
lines changed

planning/src/RS/rsCheck.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ bool do_check_blif(CStr cfn,
5959
uint numInp = bfile.numInputs();
6060
uint numOut = bfile.numOutputs();
6161

62-
lprintf(" (blif_file) #inputs= %u #outputs= %u topModel= %s\n",
62+
lprintf(" (blif_file) #inputs= %u #outputs= %u topModel= %s\n",
6363
numInp, numOut, bfile.topModel_.c_str());
6464

6565
if (tr >= 4) {
@@ -115,6 +115,7 @@ bool do_check_blif(CStr cfn,
115115
ls << "----- #TDP_RAM36K= " << nTDP_RAM36K << endl;
116116
ls << "----- #TDP_RAM18KX2= " << nTDP_RAM18K << endl;
117117
ls << "----- #CARRY= " << nCARRY << endl;
118+
ls << "----- #WIREs= " << bfile.countWires() << endl;
118119
}
119120
ls << "-----\n";
120121
ls << "----- PinGraph: " << bfile.pinGraphFile_ << endl;
@@ -173,6 +174,8 @@ bool do_check_blif(CStr cfn,
173174

174175
ls << "[Error] ERROR BLIF is not OK ERROR" << endl;
175176
ls << "[Error] ERROR " << bfile.err_msg_ << endl;
177+
if (not bfile.err_info2_.empty())
178+
ls << "[Error] ERROR " << bfile.err_info2_ << endl;
176179

177180
flush_out(true);
178181
uint errLnum = std::max(bfile.err_lnum_, bfile.err_lnum2_);

planning/src/file_io/pln_blif_file.cpp

Lines changed: 92 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ void BLIF_file::reset(CStr nm, uint16_t tr) noexcept {
2525
inputs_lnum_ = outputs_lnum_ = 0;
2626
err_lnum_ = err_lnum2_ = 0;
2727
err_msg_.clear();
28+
err_info2_.clear();
2829
pg_.clear();
2930
pg2blif_.clear();
3031

@@ -253,6 +254,7 @@ bool BLIF_file::readBlif() noexcept {
253254

254255
rd_ok_ = chk_ok_ = false;
255256
err_msg_.clear();
257+
err_info2_.clear();
256258
trace_ = 0;
257259

258260
{
@@ -779,6 +781,17 @@ uint BLIF_file::countFFs() const noexcept {
779781
return cnt;
780782
}
781783

784+
uint BLIF_file::countWires() const noexcept {
785+
if (numNodes() == 0 or fabricRealNodes_.empty())
786+
return 0;
787+
uint cnt = 0;
788+
for (const BNode* x : fabricRealNodes_) {
789+
if (x->is_WIRE())
790+
cnt++;
791+
}
792+
return cnt;
793+
}
794+
782795
uint BLIF_file::countCBUFs() const noexcept {
783796
uint nn = numNodes();
784797
if (nn == 0)
@@ -1628,24 +1641,24 @@ void BLIF_file::BNode::allInputPins(vector<string>& V) const noexcept {
16281641
return;
16291642
}
16301643

1631-
BLIF_file::BNode* BLIF_file::findOutputPort(const string& contact) noexcept {
1632-
assert(not contact.empty());
1644+
BLIF_file::BNode* BLIF_file::findOutputPort(const string& sig) noexcept {
1645+
assert(not sig.empty());
16331646
if (topOutputs_.empty()) return nullptr;
16341647

16351648
// TMP linear
16361649
for (BNode* x : topOutputs_) {
1637-
if (x->out_ == contact) return x;
1650+
if (x->out_ == sig) return x;
16381651
}
16391652
return nullptr;
16401653
}
16411654

1642-
BLIF_file::BNode* BLIF_file::findInputPort(const string& contact) noexcept {
1643-
assert(not contact.empty());
1655+
BLIF_file::BNode* BLIF_file::findInputPort(const string& sig) noexcept {
1656+
assert(not sig.empty());
16441657
if (topInputs_.empty()) return nullptr;
16451658

16461659
// TMP linear
16471660
for (BNode* x : topInputs_) {
1648-
if (x->out_ == contact) return x;
1661+
if (x->out_ == sig) return x;
16491662
}
16501663
return nullptr;
16511664
}
@@ -2010,7 +2023,7 @@ bool BLIF_file::checkClockSepar(vector<BNode*>& clocked) noexcept {
20102023
}
20112024

20122025
bool color_ok = true;
2013-
CStr viol_prefix = " ===!!! clock-data separation error";
2026+
CStr viol_prefix = " [Error] clock-data separation ERROR";
20142027

20152028
// -- check that end-points of red edges are red
20162029
for (NW::cEI E(pg_); E.valid(); ++E) {
@@ -2039,11 +2052,18 @@ bool BLIF_file::checkClockSepar(vector<BNode*>& clocked) noexcept {
20392052
lprintf("%s: blif lines: %u - %u\n",
20402053
viol_prefix, err_lnum_, err_lnum2_);
20412054
char B[512] = {};
2042-
::sprintf(B, " line %u : %s ", err_lnum_, bnode1.kw_.c_str());
2055+
::sprintf(B, " ERROR line %u : %s ", err_lnum_, bnode1.kw_.c_str());
20432056
logVec(bnode1.data_, B);
2044-
::sprintf(B, " line %u : %s ", err_lnum2_, bnode2.kw_.c_str());
2057+
::sprintf(B, " ERROR line %u : %s ", err_lnum2_, bnode2.kw_.c_str());
20452058
logVec(bnode2.data_, B);
20462059
flush_out(true);
2060+
if (bnode1.isTopInput() and bnode2.is_WIRE()) {
2061+
err_info2_ = str::concat( "clock input port ", bnode1.out_,
2062+
" drives feedthrough wire at line ",
2063+
std::to_string(err_lnum2_) );
2064+
lprintf("error-info: %s\n", err_info2_.c_str());
2065+
flush_out(true);
2066+
}
20472067
}
20482068
break;
20492069
}
@@ -2060,7 +2080,8 @@ bool BLIF_file::checkClockSepar(vector<BNode*>& clocked) noexcept {
20602080

20612081
if (!color_ok) {
20622082
flush_out(true); err_puts();
2063-
lprintf2("[Error] clock-data separation error\n");
2083+
lprintf2("[Error] clock-data separation error: lines %u - %u\n",
2084+
err_lnum_, err_lnum2_);
20642085
err_puts(); flush_out(true);
20652086
return false;
20662087
}
@@ -2097,6 +2118,7 @@ bool BLIF_file::createPinGraph() noexcept {
20972118
if (fabricNodes_.empty()) return false;
20982119

20992120
err_msg_.clear();
2121+
err_info2_.clear();
21002122
uint64_t key = 0;
21012123
uint nid = 0, kid = 0, eid = 0;
21022124
vector<string> INP;
@@ -2146,6 +2168,54 @@ bool BLIF_file::createPinGraph() noexcept {
21462168
vector<qTup> Q;
21472169
Q.reserve(topInputs_.size());
21482170

2171+
// -- link in-ports to out-ports via feedthrough wires
2172+
for (BNode* x : fabricRealNodes_) {
2173+
if (x->is_WIRE()) {
2174+
BNode& w = *x;
2175+
assert(w.data_.size() == 2);
2176+
const string& w_inp = w.data_.front();
2177+
const string& w_out = w.data_.back();
2178+
BNode* iport = findInputPort(w_inp);
2179+
if (!iport)
2180+
continue;
2181+
BNode* oport = findOutputPort(w_out);
2182+
if (!oport)
2183+
continue;
2184+
assert(iport->isTopInput());
2185+
assert(oport->isTopOutput());
2186+
// NW-nodes for i/o ports should exist already
2187+
assert(iport->nw_id_);
2188+
assert(oport->nw_id_);
2189+
assert(pg_.hasNode(iport->nw_id_));
2190+
assert(pg_.hasNode(oport->nw_id_));
2191+
assert(map_pg2blif(iport->nw_id_) == iport->id_);
2192+
assert(map_pg2blif(oport->nw_id_) == oport->id_);
2193+
2194+
// NW keys and nodes for wire pseudo-cell:
2195+
uint64_t w_k1 = hashCantor(w.id_, 1) + max_key1;
2196+
uint64_t w_k2 = hashCantor(w.id_, 2) + max_key1;
2197+
assert(w_k1);
2198+
assert(w_k2);
2199+
assert(w_k1 != w_k2);
2200+
uint w_n1 = pg_.insK(w_k1);
2201+
assert(w_n1);
2202+
uint w_n2 = pg_.insK(w_k2);
2203+
assert(w_n2);
2204+
pg2blif_.emplace(w_n1, w.id_);
2205+
pg2blif_.emplace(w_n2, w.id_);
2206+
pg_.setNodeName4(w_n1, w.id_, w.lnum_, 1, "FTwireI");
2207+
pg_.setNodeName4(w_n2, w.id_, w.lnum_, 2, "FTwireO");
2208+
2209+
// link feedthrough:
2210+
uint ee;
2211+
ee = pg_.linkNodes(iport->nw_id_, w_n1, false);
2212+
ee = pg_.linkNodes(w_n1, w_n2, true);
2213+
ee = pg_.linkNodes(w_n2, oport->nw_id_, false);
2214+
if (trace_ >= 11)
2215+
lprintf("\t\t ee = %u\n", ee);
2216+
}
2217+
}
2218+
21492219
// -- link from input ports to fabric
21502220
for (BNode* p : topInputs_) {
21512221
INP.clear();
@@ -2163,9 +2233,6 @@ bool BLIF_file::createPinGraph() noexcept {
21632233
lprintf(" %s\n", port.cPortName());
21642234
}
21652235

2166-
// if (port.id_ == 24)
2167-
// lputs1();
2168-
21692236
for (const upair& pa : PAR) {
21702237
if (pa.first == port.id_)
21712238
continue;
@@ -2295,12 +2362,12 @@ bool BLIF_file::createPinGraph() noexcept {
22952362
uint cn_realId = cn.realId(*this);
22962363
key = hashCantor(cn_realId, i + 1) + max_key1;
22972364
assert(key);
2298-
// if (key == 110)
2299-
// lputs3();
23002365
kid = pg_.findNode(key);
23012366
if (kid) {
2302-
lprintf("\t\t ___ found nid %u '%s' for key %zu",
2303-
kid, pg_.cnodeName(kid), key);
2367+
if (trace_ >= 8) {
2368+
lprintf("\t\t ___ found nid %u '%s' for key %zu",
2369+
kid, pg_.cnodeName(kid), key);
2370+
}
23042371
}
23052372
else {
23062373
kid = pg_.insK(key);
@@ -2529,7 +2596,8 @@ bool BLIF_file::createPinGraph() noexcept {
25292596

25302597
pg_.setNwName("pin_graph");
25312598

2532-
// writePinGraph("pin_graph_1.dot");
2599+
if (trace_ >= 8)
2600+
writePinGraph("Dpin_graph_1.dot", true, false);
25332601

25342602
#ifndef NDEBUG
25352603
// -- verify that all NW IDs are mapped to BNodes:
@@ -2577,11 +2645,13 @@ string BLIF_file::writePinGraph(CStr fn0, bool nodeTable, bool noDeg0) const noe
25772645
err_puts(); flush_out(true);
25782646
}
25792647

2580-
lprintf("(writePinGraph) status:%s file: %s\n",
2581-
wrDot_ok ? "OK" : "FAIL",
2582-
fn.c_str());
2648+
if (not wrDot_ok or trace_ >= 4) {
2649+
lprintf("(writePinGraph) status:%s file: %s\n\n",
2650+
wrDot_ok ? "OK" : "FAIL",
2651+
fn.c_str());
2652+
}
25832653

2584-
flush_out(true);
2654+
flush_out(false);
25852655
if (wrDot_ok)
25862656
return fn;
25872657
return {};

planning/src/file_io/pln_blif_file.h

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,11 @@ struct BLIF_file : public fio::MMapReader
204204
bool is_CARRY() const noexcept {
205205
return ptype_ == prim::CARRY;
206206
}
207+
bool is_WIRE() const noexcept {
208+
if (ptype_ != prim::A_ZERO or kw_ != ".names")
209+
return false;
210+
return data_.size() == 2;
211+
}
207212

208213
bool canDriveClockNode() const noexcept {
209214
return isTopInput() or is_CLK_BUF() or ptype_ == prim::I_SERDES;
@@ -291,7 +296,7 @@ struct BLIF_file : public fio::MMapReader
291296
size_t inputs_lnum_ = 0, outputs_lnum_ = 0;
292297
mutable uint err_lnum_ = 0, err_lnum2_ = 0;
293298

294-
string err_msg_;
299+
string err_msg_, err_info2_;
295300
uint16_t trace_ = 0;
296301

297302
bool rd_ok_ = false;
@@ -321,6 +326,7 @@ struct BLIF_file : public fio::MMapReader
321326
uint numNodes() const noexcept { return nodePool_.empty() ? 0 : nodePool_.size() - 1; }
322327
uint countLUTs() const noexcept;
323328
uint countFFs() const noexcept;
329+
uint countWires() const noexcept;
324330
uint countCBUFs() const noexcept;
325331
void countBUFs(uint& nIBUF, uint& nOBUF, uint& nCBUF) const noexcept;
326332

@@ -358,8 +364,8 @@ struct BLIF_file : public fio::MMapReader
358364

359365
bool checkClockSepar(vector<BNode*>& clocked) noexcept;
360366

361-
BNode* findOutputPort(const string& contact) noexcept;
362-
BNode* findInputPort(const string& contact) noexcept;
367+
BNode* findOutputPort(const string& sig) noexcept;
368+
BNode* findInputPort(const string& sig) noexcept;
363369

364370
BNode* findFabricParent(uint of, const string& contact, int& pinIndex) noexcept; // searches inputs
365371
BNode* findFabricDriver(uint of, const string& contact) noexcept; // matches out_

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 = "pln0362";
1+
static const char* _pln_VERSION_STR = "pln0363";
22

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

planning/src/util/nw/Nw.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ uint NW::insK(uint64_t k) noexcept {
5151
newNid = nid_at(I - nids_.begin());
5252
ndStor_.pop_back();
5353
nids_.pop_back();
54-
// if (newNid == 36)
54+
// if (newNid == 16)
5555
// lputs4();
5656
} else {
5757
newNid = p->id_;
@@ -62,7 +62,7 @@ uint NW::insK(uint64_t k) noexcept {
6262
}
6363

6464
assert(nodeRef(newNid).key_ == k);
65-
//if (newNid == 36)
65+
// if (newNid == 16)
6666
// lputs4();
6767
return newNid;
6868
}

planning/src/util/nw/Nw.h

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,9 @@ struct NW {
274274
inline uint numE() const noexcept;
275275
uint countRedEdges() const noexcept;
276276

277-
inline upair countRoots() const noexcept;
277+
upair countRoots() const noexcept;
278+
upair countPorts() const noexcept;
279+
278280
bool hasClockNodes() const noexcept;
279281
uint countClockNodes() const noexcept;
280282
uint countRedNodes() const noexcept;
@@ -795,17 +797,6 @@ inline uint NW::linK(uint64_t k1, uint64_t k2) noexcept {
795797
return linkNodes(n1, n2);
796798
}
797799

798-
inline upair NW::countRoots() const noexcept {
799-
uint cnt = 0, mark_cnt = 0;
800-
if (empty()) return {cnt, mark_cnt};
801-
for (cNI I(*this); I.valid(); ++I) {
802-
const Node& nd = *I;
803-
if (nd.isTreeRoot()) cnt++;
804-
if (nd.isFlagRoot()) mark_cnt++;
805-
}
806-
return {cnt, mark_cnt};
807-
}
808-
809800
inline uint NW::getMaxLabel() const noexcept {
810801
if (empty()) return 0;
811802
uint maxLabel = 0;

planning/src/util/nw/Nw_io.cpp

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -372,13 +372,19 @@ void NW::Node::nprint_dot(ostream& os) const noexcept {
372372
}
373373
else {
374374

375-
if (isRed()) {
376-
::strcpy(attrib, "[ shape=octagon, color=purple, fillcolor=pink, style=filled ];");
375+
if (out_flag_) {
376+
CStr cs = isRed() ? "red" : "brown";
377+
::sprintf(attrib, "[ shape=box, color=%s, style=filled ];", cs);
377378
}
378379
else {
379-
::strcpy(attrib, "[ shape=record, style=rounded ];");
380-
if (viol_flag_) {
381-
::strcpy(attrib, "[ shape=doubleoctagon, color=blueviolet, fillcolor=violet, style=filled ];");
380+
if (isRed()) {
381+
::strcpy(attrib, "[ shape=octagon, color=purple, fillcolor=pink, style=filled ];");
382+
}
383+
else {
384+
::strcpy(attrib, "[ shape=record, style=rounded ];");
385+
if (viol_flag_) {
386+
::strcpy(attrib, "[ shape=doubleoctagon, color=blueviolet, fillcolor=violet, style=filled ];");
387+
}
382388
}
383389
}
384390

@@ -504,6 +510,7 @@ uint NW::printSum(ostream& os, uint16_t forDot) const noexcept {
504510
upair mmD = getMinMaxDeg();
505511
upair mmL = getMinMaxLbl();
506512
upair rcnt = countRoots();
513+
upair pcnt = countPorts();
507514
uint numClkNodes = countClockNodes();
508515

509516
dot_comment(os, forDot);
@@ -522,7 +529,9 @@ uint NW::printSum(ostream& os, uint16_t forDot) const noexcept {
522529
numNamedNodes, numRedNodes, numRedEdges);
523530

524531
dot_comment(os, forDot);
525-
os_printf(os, "nr=(%u,%u)\n", rcnt.first, rcnt.second);
532+
os_printf(os, "nr=(%u,%u) #Inp=%u #Out=%u\n",
533+
rcnt.first, rcnt.second,
534+
pcnt.first, pcnt.second);
526535

527536
return size();
528537
}

0 commit comments

Comments
 (0)