Skip to content

Commit 22928be

Browse files
committed
checker: developing clock-data
1 parent d7d4b1f commit 22928be

File tree

6 files changed

+253
-109
lines changed

6 files changed

+253
-109
lines changed

planning/src/RS/rsCheck.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ static bool do_check_blif(CStr cfn) {
8787
ls << "[Error] !!! " << bfile.err_msg_ << endl;
8888

8989
flush_out(true);
90-
lprintf2("ERROR: BLIF verification failed at %s:%zu\n",
90+
lprintf2("ERROR: BLIF verification failed at %s:%u\n",
9191
bfile.fnm_.c_str(), bfile.err_lnum_);
9292

9393
return false;

planning/src/file_readers/pln_blif_file.cpp

Lines changed: 99 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -378,7 +378,7 @@ bool BLIF_file::checkBlif() noexcept {
378378
}
379379

380380
bool link_ok = linkNodes();
381-
if (!link_ok) {
381+
if (not link_ok) {
382382
string tmp = err_msg_;
383383
err_msg_ = "link failed at line ";
384384
err_msg_ += std::to_string(err_lnum_);
@@ -420,17 +420,28 @@ bool BLIF_file::checkBlif() noexcept {
420420

421421
// 6. clock-data separation
422422
if (!topInputs_.empty() and !topOutputs_.empty()) {
423-
NW pinG;
424-
pinG.trace_ = trace_;
425-
for (const Node* port : topOutputs_) {
426-
assert(port->isRoot());
427-
assert(port->inDeg() == 0);
428-
pinG.insK(port->hashCode());
423+
vector<const Node*> clocked;
424+
collectClockedNodes(clocked);
425+
uint clocked_sz = clocked.size();
426+
if (trace_ >= 3) {
427+
lprintf("(clock-data separation) num_nodes= %u num_clocked= %u\n",
428+
numNodes(), clocked_sz);
429429
}
430-
if (trace_ >= 14) {
431-
flush_out(true);
432-
pinG.printSum(ls, 0);
430+
if (clocked_sz) {
431+
bool separ_ok = checkClockSepar(clocked);
432+
if (not separ_ok) {
433+
string tmp = err_msg_;
434+
err_msg_ = "clock-data separation issue at line ";
435+
err_msg_ += std::to_string(err_lnum_);
436+
err_msg_ += " ";
437+
err_msg_ += tmp;
438+
flush_out(true);
439+
return false;
440+
}
441+
if (trace_ >= 4)
442+
lputs("(clock-data separation) checked OK.");
433443
}
444+
flush_out(true);
434445
}
435446

436447
chk_ok_ = true;
@@ -531,7 +542,7 @@ uint BLIF_file::printPrimitives(std::ostream& os, bool instCounts) const noexcep
531542
}
532543
if (n_clocks and IC[t]) {
533544
::sprintf(ncs_buf, " #clock_pins= %u", n_clocks);
534-
n_clock_inst++;
545+
n_clock_inst += IC[t];
535546
}
536547
os_printf(os, " [%u] %s %s%s\n",
537548
t, pn, ic_buf, ncs_buf);
@@ -560,6 +571,24 @@ uint BLIF_file::printPrimitives(std::ostream& os, bool instCounts) const noexcep
560571
return Prim_MAX_ID;
561572
}
562573

574+
void BLIF_file::collectClockedNodes(vector<const Node*>& V) noexcept {
575+
V.clear();
576+
uint nn = numNodes();
577+
if (nn == 0)
578+
return;
579+
580+
V.reserve(20);
581+
for (uint i = 1; i <= nn; i++) {
582+
const Node& nd = nodePool_[i];
583+
uint t = nd.ptype_;
584+
if (!t or t >= Prim_MAX_ID)
585+
continue;
586+
uint n_clocks = pr_num_clocks(nd.ptype_);
587+
if (n_clocks)
588+
V.push_back(&nd);
589+
}
590+
}
591+
563592
std::array<uint, Prim_MAX_ID> BLIF_file::countTypes() const noexcept {
564593
std::array<uint, Prim_MAX_ID> A;
565594
for (uint t = 0; t < Prim_MAX_ID; t++)
@@ -1258,7 +1287,6 @@ bool BLIF_file::linkNodes() noexcept {
12581287
continue;
12591288
Node* drv_cell = findFabricDriver(nd.id_, inp1);
12601289
if (!drv_cell) {
1261-
// lputs9();
12621290
err_msg_ = "undriven cell input: ";
12631291
err_msg_ += inp1;
12641292
if (trace_ >= 2) {
@@ -1273,4 +1301,63 @@ bool BLIF_file::linkNodes() noexcept {
12731301
return true;
12741302
}
12751303

1304+
bool BLIF_file::checkClockSepar(vector<const Node*>& clocked) const noexcept {
1305+
if (1|| clocked.empty())
1306+
return true;
1307+
1308+
NW g;
1309+
auto& ls = lout();
1310+
char nm_buf[512] = {};
1311+
1312+
for (const Node* np : clocked) {
1313+
const Node& nd = *np;
1314+
if (not pr_num_clocks(nd.ptype_))
1315+
continue;
1316+
if (nd.ptype_ == CLK_BUF)
1317+
continue;
1318+
if (nd.parent_ == 0)
1319+
continue;
1320+
lprintf("...... checking clock-separ for node #%u of type %s\n",
1321+
nd.id_, nd.cPrimType());
1322+
lprintf("\t\t parent= %u\n", nd.parent_);
1323+
1324+
g.clear();
1325+
1326+
uint64_t rhash = nd.hashCode();
1327+
uint g_rid = g.addNode(rhash);
1328+
g.addRoot(g_rid);
1329+
1330+
const Node& par = nodeRef(nd.parent_);
1331+
1332+
uint g_pid = g.insK(par.hashCode());
1333+
g.markSink(g_pid, true);
1334+
1335+
g.linkNodes(g_rid, g_pid, false);
1336+
1337+
::snprintf(nm_buf, 510, "%s_%uL", nd.cPrimType(), nd.lnum_);
1338+
g.setNodeName(g_rid, nm_buf);
1339+
1340+
::snprintf(nm_buf, 510, "%s_%uL", par.cPrimType(), par.lnum_);
1341+
g.setNodeName(g_pid, nm_buf);
1342+
1343+
uint bh_id = g.insK(111);
1344+
g.markSink(bh_id, true);
1345+
g.setNodeName(bh_id, "BH1");
1346+
1347+
g.linkNodes(g_pid, bh_id, false);
1348+
1349+
g.labelDepth();
1350+
1351+
g.dump("\t *** g separ ***");
1352+
lprintf("\t g. numN()= %u numE()= %u\n", g.numN(), g.numE());
1353+
g.printSum(ls, 0);
1354+
1355+
lputs("\n\t***** break; // TMP");
1356+
break; // TMP
1357+
}
1358+
1359+
return true;
12761360
}
1361+
1362+
}
1363+

planning/src/file_readers/pln_blif_file.h

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,12 +148,22 @@ struct BLIF_file : public fio::MMapReader
148148

149149
}; // Node
150150

151+
Node& nodeRef(uint id) noexcept {
152+
assert(id > 0 and id < nodePool_.size());
153+
return nodePool_[id];
154+
}
155+
const Node& nodeRef(uint id) const noexcept {
156+
assert(id > 0 and id < nodePool_.size());
157+
return nodePool_[id];
158+
}
159+
151160
string topModel_;
152161

153162
vector<string> inputs_;
154163
vector<string> outputs_;
155164

156-
size_t inputs_lnum_ = 0, outputs_lnum_ = 0, err_lnum_ = 0;
165+
size_t inputs_lnum_ = 0, outputs_lnum_ = 0;
166+
mutable uint err_lnum_ = 0;
157167

158168
string err_msg_;
159169
uint16_t trace_ = 0;
@@ -178,6 +188,7 @@ struct BLIF_file : public fio::MMapReader
178188
uint numOutputs() const noexcept { return outputs_.size(); }
179189
uint numNodes() const noexcept { return nodePool_.empty() ? 0 : nodePool_.size() - 1; }
180190

191+
void collectClockedNodes(vector<const Node*>& V) noexcept;
181192
std::array<uint, prim::Prim_MAX_ID> countTypes() const noexcept;
182193

183194
uint printInputs(std::ostream& os, CStr spacer = nullptr) const noexcept;
@@ -193,6 +204,8 @@ struct BLIF_file : public fio::MMapReader
193204
bool linkNodes() noexcept;
194205
void link(Node& from, Node& to) noexcept;
195206

207+
bool checkClockSepar(vector<const Node*>& clocked) const noexcept;
208+
196209
Node* findOutputPort(const string& contact) noexcept;
197210
Node* findInputPort(const string& contact) noexcept;
198211

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

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

planning/src/util/nw/Nw.cpp

Lines changed: 102 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -158,8 +158,98 @@ uint NW::getRadius() noexcept {
158158
return ml >= 0 ? ml : 0;
159159
}
160160

161+
using Nd = NW::Node;
162+
163+
static void dfs_setD(NW& g, const Nd& fr, Nd& to) noexcept {
164+
assert(to.lbl_ == UINT_MAX);
165+
assert(fr.lbl_ != UINT_MAX);
166+
assert(to.par_ > 0 and to.par_ == fr.id_);
167+
168+
to.lbl_ = fr.lbl_ + 1;
169+
170+
for (int i = to.degree() - 1; i >= 0; i--) {
171+
uint ei = to.edges_[i];
172+
NW::Edge& e = g.edgeRef(ei);
173+
Nd& other = g.nodeRef(to.otherSide(e));
174+
if (other.id_ == fr.id_) continue;
175+
dfs_setD(g, to, other);
176+
}
177+
}
178+
179+
void NW::labelDepth() noexcept {
180+
assert(not empty());
181+
uint rootId = first_rid();
182+
assert(rootId);
183+
assert(verifyOneRoot());
184+
185+
Node& root = nodeRefCk(rootId);
186+
187+
for (NI I(*this); I.valid(); ++I) I->lbl_ = UINT_MAX;
188+
root.lbl_ = 0;
189+
if (size() == 1) {
190+
return;
191+
}
192+
if (size() == 2) {
193+
for (NI I(*this); I.valid(); ++I) {
194+
Node& nd = *I;
195+
if (nd.id_ != rootId)
196+
nd.lbl_ = 1;
197+
}
198+
return;
199+
}
200+
201+
for (int i = root.degree() - 1; i >= 0; i--) {
202+
Edge& e = edStor_[root.edges_[i]];
203+
Node& to = ndStor_[root.otherSide(e)];
204+
dfs_setD(*this, root, to);
205+
}
206+
}
207+
208+
upair NW::getMinMaxDeg() const noexcept {
209+
upair dg{0, 0};
210+
if (empty()) return dg;
211+
212+
const Node& n0 = nodeRefCk(nids_[0]);
213+
dg.first = n0.degree();
214+
dg.second = dg.first;
215+
for (cNI I(*this); I.valid(); ++I) {
216+
const Node& nd = *I;
217+
uint d = nd.degree();
218+
if (d < dg.first) dg.first = d;
219+
if (d > dg.second) dg.second = d;
220+
}
221+
return dg;
222+
}
223+
224+
upair NW::getMinMaxLbl() const noexcept {
225+
upair L{0, 0};
226+
if (empty()) return L;
227+
228+
const Node& n0 = nodeRefCk(nids_[0]);
229+
L.first = n0.lbl_;
230+
L.second = n0.lbl_;
231+
for (cNI I(*this); I.valid(); ++I) {
232+
const Node& nd = *I;
233+
uint x = nd.lbl_;
234+
if (x < L.first) L.first = x;
235+
if (x > L.second) L.second = x;
236+
}
237+
return L;
238+
}
239+
161240
// ==== DEBUG
162241

242+
void NW::dot_comment(ostream& os, uint16_t dotMode, CStr msg) noexcept {
243+
if (!dotMode) return;
244+
if (dotMode == 1) {
245+
os << s_dotComment;
246+
} else {
247+
assert(dotMode == 2);
248+
os << s_metisComment;
249+
}
250+
if (msg) os << msg;
251+
}
252+
163253
bool NW::verifyOneRoot() const noexcept {
164254
if (empty()) return true;
165255
assert(!rids_.empty());
@@ -194,21 +284,15 @@ void NW::Node::print(ostream& os) const noexcept {
194284
os << " r-";
195285
}
196286
if (sink_flag_) os << " S";
197-
os << " par=" << par_;
198-
os << " lbl=" << lbl_;
287+
os_printf(os, " par=%u lbl=%u", par_, lbl_);
288+
if (not name_.empty())
289+
os << " nm= " << name_;
199290
os << endl;
200291
}
201292

202293
void NW::Node::nprint_dot(ostream& os) const noexcept {
203294
os << " " << getName();
204-
if (isCell()) {
205-
if (0) {
206-
} else {
207-
os << " [ shape=box";
208-
}
209-
os << " ] ";
210-
} else if (0) {
211-
}
295+
212296
os_printf(os, " // deg= %u;\n", degree());
213297
}
214298

@@ -276,19 +360,21 @@ uint NW::printNodes(ostream& os, CStr msg, uint16_t forDot) const noexcept {
276360
uint NW::dumpNodes(CStr msg) const noexcept { return printNodes(lout(), msg, 0); }
277361

278362
uint NW::printSum(ostream& os, uint16_t forDot) const noexcept {
279-
using std::endl;
280363
dot_comment(os, forDot);
281364
if (empty()) {
282-
os << "(empty NW)" << endl;
365+
os_printf(os, "(empty NW)\n)");
283366
return 0;
284367
}
285368

286-
ipair mmD = getMinMaxDeg();
287-
ipair mmL = getMinMaxLbl();
369+
upair mmD = getMinMaxDeg();
370+
upair mmL = getMinMaxLbl();
288371
upair rcnt = countRoots();
289372

290-
os_printf(os, "nn= %u ne= %u nr= %zu r0= %u", numN(), numE(), rids_.size(), first_rid());
291-
os << " mm-deg: " << mmD << " mm-lbl: " << mmL << endl;
373+
os_printf(os, "nn= %u ne= %u nr= %zu r0= %u",
374+
numN(), numE(), rids_.size(), first_rid());
375+
376+
os_printf(os, " mm-deg: (%u,%u)", mmD.first, mmD.second);
377+
os_printf(os, " mm-lbl: (%u,%u)\n", mmL.first, mmL.second);
292378

293379
dot_comment(os, forDot);
294380
os_printf(os, "nr=(%u,%u)\n", rcnt.first, rcnt.second);

0 commit comments

Comments
 (0)