Skip to content

Commit 689cfa1

Browse files
committed
checker writeBlif() now filters dangling bits
1 parent e94fc54 commit 689cfa1

File tree

5 files changed

+145
-27
lines changed

5 files changed

+145
-27
lines changed

planning/src/RS/rsCheck.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -116,9 +116,9 @@ bool do_check_blif(CStr cfn,
116116
if (numWarn)
117117
lprintf(" # WARNINGS= %u", numWarn);
118118
lputs();
119-
if (::getenv("pln_always_write_blif")) {
120-
string outFn = str::concat("PLN_", cfn);
121-
string wr_ok = bfile.writeBlif(outFn, false);
119+
if (numWarn or ::getenv("pln_always_write_blif")) {
120+
string outFn = str::concat("PLN_W", std::to_string(numWarn), "_", cfn);
121+
string wr_ok = bfile.writeBlif(outFn, numWarn);
122122
if (wr_ok.empty())
123123
lprintf("---!! FAILED writeBlif to '%s'\n", outFn.c_str());
124124
else

planning/src/file_io/pln_blif_file.cpp

Lines changed: 110 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,7 @@ void BLIF_file::reset(CStr nm, uint16_t tr) noexcept {
1818
topOutputs_.clear();
1919
fabricNodes_.clear();
2020
fabricRealNodes_.clear();
21-
dang_RAM_outputs_.clear();
22-
dang_DSP_outputs_.clear();
21+
dangOutputs_.clear();
2322
latches_.clear();
2423
constantNodes_.clear();
2524
rd_ok_ = chk_ok_ = false;
@@ -197,6 +196,17 @@ CStr BLIF_file::BNode::cPrimType() const noexcept {
197196
return ptype_ == prim::A_ZERO ? "{e}" : pr_enum2str(ptype_);
198197
}
199198

199+
bool BLIF_file::BNode::isDanglingTerm(uint term) const noexcept {
200+
if (dangTerms_.empty())
201+
return false;
202+
const uint* A = dangTerms_.data();
203+
for (int64_t i = int64_t(dangTerms_.size()) - 1; i >= 0; i--) {
204+
if (A[i] == term)
205+
return true;
206+
}
207+
return false;
208+
}
209+
200210
int BLIF_file::findTermByNet(const vector<string>& D, const string& net) noexcept {
201211
assert(not net.empty());
202212
assert(not D.empty());
@@ -885,9 +895,24 @@ uint BLIF_file::countConstNodes() const noexcept {
885895
}
886896

887897
uint BLIF_file::numWarnings() const noexcept {
888-
assert(dang_RAM_outputs_.size() < size_t(INT_MAX));
889-
assert(dang_DSP_outputs_.size() < size_t(INT_MAX));
890-
return dang_RAM_outputs_.size() + dang_DSP_outputs_.size();
898+
assert(dangOutputs_.size() < size_t(INT_MAX));
899+
return dangOutputs_.size();
900+
}
901+
902+
BLIF_file::NodeDescriptor BLIF_file::hasDanglingBit(uint lnum) const noexcept {
903+
assert(dangOutputs_.size() < size_t(INT_MAX));
904+
NodeDescriptor ret;
905+
if (!lnum or dangOutputs_.empty())
906+
return ret;
907+
908+
// TMP linear
909+
for (const NodeDescriptor& desc : dangOutputs_) {
910+
if (desc.lnum_ == lnum) {
911+
ret = desc;
912+
break;
913+
}
914+
}
915+
return ret;
891916
}
892917

893918
uint BLIF_file::printCarryNodes(std::ostream& os) const noexcept {
@@ -1118,8 +1143,7 @@ bool BLIF_file::createNodes() noexcept {
11181143
topOutputs_.clear();
11191144
fabricNodes_.clear();
11201145
fabricRealNodes_.clear();
1121-
dang_RAM_outputs_.clear();
1122-
dang_DSP_outputs_.clear();
1146+
dangOutputs_.clear();
11231147
latches_.clear();
11241148
constantNodes_.clear();
11251149
if (!rd_ok_) return false;
@@ -1173,7 +1197,7 @@ bool BLIF_file::createNodes() noexcept {
11731197
nodePool_.emplace_back(); // put a fake node
11741198
}
11751199

1176-
char buf[4096] = {};
1200+
char buf[8192] = {};
11771201
V.clear();
11781202
inputs_lnum_ = outputs_lnum_ = 0;
11791203
err_lnum_ = 0;
@@ -1550,8 +1574,6 @@ void BLIF_file::BNode::allInputPins(vector<string>& V) const noexcept {
15501574
return;
15511575
}
15521576

1553-
// void BLIF_file::BNode:: allInputSignals(vector<string>& V) const noexcept;
1554-
15551577
BLIF_file::BNode* BLIF_file::findOutputPort(const string& contact) noexcept {
15561578
assert(not contact.empty());
15571579
if (topOutputs_.empty()) return nullptr;
@@ -1765,10 +1787,7 @@ bool BLIF_file::linkNodes() noexcept {
17651787
lputs();
17661788
}
17671789
realNd.dangTerms_.push_back(dataTerm);
1768-
if (nd.is_RAM())
1769-
dang_RAM_outputs_.emplace_back(realNd.id_, dataTerm);
1770-
else
1771-
dang_DSP_outputs_.emplace_back(realNd.id_, dataTerm);
1790+
dangOutputs_.emplace_back(realNd.lnum_, realNd.id_, dataTerm);
17721791
continue;
17731792
}
17741793
err_msg_ = "dangling cell output: ";
@@ -2228,7 +2247,7 @@ bool BLIF_file::createPinGraph() noexcept {
22282247
}
22292248
uint driver_realId = driver->realId(*this);
22302249

2231-
if (trace_ >= 5) {
2250+
if (trace_ >= 6) {
22322251
lputs();
22332252
lprintf(" from cn#%u %s ",
22342253
cn_realId, cn.cPrimType() );
@@ -2503,29 +2522,99 @@ string BLIF_file::writeBlif(const string& toFn, bool cleanUp) noexcept {
25032522
return {};
25042523
}
25052524

2525+
constexpr uint buf_CAP = 1048574; // 1 MiB
2526+
char buf[buf_CAP + 2] = {};
25062527
size_t cnt = 0, n = lines_.size();
2507-
for (size_t i = 0; i < n; i++) {
2508-
CStr cs = lines_[i];
2509-
if (!cs || !cs[0]) continue;
2510-
::fputs(cs, f);
2528+
if (n < 2) {
2529+
::fclose(f);
2530+
return {};
2531+
}
2532+
bool error = false;
2533+
2534+
::fprintf(f, "### written by PLN %s\n\n", pln_get_version());
2535+
if (::ferror(f)) {
2536+
if (trace_ >= 3) {
2537+
flush_out(true);
2538+
lprintf("ERROR writeBlif() error during writing: %s\n", cnm);
2539+
flush_out(true);
2540+
}
2541+
error = true;
2542+
n = 0; // skips the loop
2543+
}
2544+
2545+
for (size_t lineNum = 0; lineNum < n; lineNum++) {
2546+
CStr cs = lines_[lineNum];
2547+
if (!cs || !cs[0])
2548+
continue;
2549+
2550+
::strncpy(buf, cs, buf_CAP);
2551+
2552+
if (cleanUp) {
2553+
NodeDescriptor ddesc = hasDanglingBit(lineNum);
2554+
if (ddesc.valid()) {
2555+
assert(ddesc.nid_ > 0);
2556+
const BNode& dNode = bnodeRef(ddesc.nid_);
2557+
assert(not dNode.isVirtualMog());
2558+
assert(not dNode.realData_.empty());
2559+
assert(not dNode.dangTerms_.empty());
2560+
// build 'buf' skipping dangling terms
2561+
uint skipCnt = 0;
2562+
buf[0] = 0; buf[1] = 0;
2563+
size_t rdsz = dNode.realData_.size();
2564+
if (trace_ >= 4) {
2565+
lprintf("wrBlif: cell %s at line %zu has dangling bit, filtering..\n",
2566+
dNode.cPrimType(), lineNum);
2567+
if (trace_ >= 5) {
2568+
lprintf(" dangling cell realData_.size()= %zu\n", rdsz);
2569+
}
2570+
}
2571+
char* tail = ::stpcpy(buf, ".subckt");
2572+
for (size_t i = 0; i < rdsz; i++) {
2573+
if (dNode.isDanglingTerm(i)) {
2574+
if (trace_ >= 6)
2575+
lprintf("\t (wrBlif) skipping dangling term %zu\n", i);
2576+
skipCnt++;
2577+
continue;
2578+
}
2579+
CStr ts = dNode.realData_[i].c_str();
2580+
tail = ::stpcpy(tail, " ");
2581+
tail = ::stpcpy(tail, ts);
2582+
}
2583+
if (trace_ >= 4) {
2584+
lprintf("wrBlif: filtered dangling bits (%u) for cell %s at line %zu\n",
2585+
skipCnt, dNode.cPrimType(), lineNum);
2586+
}
2587+
}
2588+
}
2589+
2590+
::fputs(buf, f);
25112591
::fputc('\n', f);
2592+
25122593
if (::ferror(f)) {
25132594
if (trace_ >= 3) {
25142595
flush_out(true);
25152596
lprintf("ERROR writeBlif() error during writing: %s\n", cnm);
25162597
flush_out(true);
25172598
}
2599+
error = true;
25182600
break;
25192601
}
25202602
cnt++;
25212603
}
25222604

25232605
::fclose(f);
25242606

2525-
if (trace_ >= 4) {
2526-
flush_out(trace_ >= 5);
2607+
flush_out(trace_ >= 5);
2608+
2609+
if (error) {
2610+
flush_out(true); err_puts();
2611+
lprintf2("[Error] writeBlif ERROR writing: %s\n", cnm);
2612+
err_puts(); flush_out(true);
2613+
}
2614+
else if (trace_ >= 4) {
25272615
lprintf(" writeBlif OK written #lines= %zu\n", cnt);
25282616
}
2617+
25292618
flush_out(trace_ >= 5);
25302619

25312620
return fn2;

planning/src/file_io/pln_blif_file.h

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,21 @@ using std::vector;
1616

1717
struct BLIF_file : public fio::MMapReader
1818
{
19+
struct NodeDescriptor {
20+
uint lnum_ = 0;
21+
uint nid_ = 0;
22+
int term_ = -1; // index in realData_
23+
24+
NodeDescriptor() noexcept = default;
25+
NodeDescriptor(uint l, uint n, int t) noexcept
26+
: lnum_(l), nid_(n), term_(t)
27+
{}
28+
29+
bool valid() const noexcept { return lnum_; }
30+
void inval() noexcept { lnum_ = 0; term_ = -1; }
31+
void reset() noexcept { lnum_ = 0; nid_ = 0; term_ = -1; }
32+
};
33+
1934
// Nodes are rooted at output ports.
2035
// Input ports are leaves.
2136
// Output ports are roots of fanin cones.
@@ -198,6 +213,8 @@ struct BLIF_file : public fio::MMapReader
198213

199214
CStr cPrimType() const noexcept;
200215

216+
bool isDanglingTerm(uint term) const noexcept;
217+
201218
struct CmpOut {
202219
bool operator()(const BNode* a, const BNode* b) const noexcept {
203220
return a->out_ < b->out_;
@@ -298,6 +315,7 @@ struct BLIF_file : public fio::MMapReader
298315
uint countConstNodes() const noexcept;
299316

300317
uint numWarnings() const noexcept;
318+
NodeDescriptor hasDanglingBit(uint lnum) const noexcept;
301319

302320
uint printInputs(std::ostream& os, CStr spacer = nullptr) const noexcept;
303321
uint printOutputs(std::ostream& os, CStr spacer = nullptr) const noexcept;
@@ -349,8 +367,7 @@ struct BLIF_file : public fio::MMapReader
349367
std::vector<BNode*> fabricNodes_, constantNodes_;
350368
std::vector<BNode*> fabricRealNodes_; // skip virtual SOGs
351369

352-
std::vector<upair> dang_RAM_outputs_; // (nid, dataTerm)
353-
std::vector<upair> dang_DSP_outputs_; // (nid, dataTerm)
370+
std::vector<NodeDescriptor> dangOutputs_; // (lnum, nid, term)
354371

355372
std::vector<BNode*> latches_; // latches are not checked for now
356373

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

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

planning/src/util/pln_log.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,18 @@ inline string concat(const string& a, const string& b, const string& c, const st
150150
z += d;
151151
return z;
152152
}
153+
inline string concat(CStr a, const string& b, CStr c, CStr d) noexcept {
154+
string z;
155+
z.reserve(p_strlen(a) + b.length() + p_strlen(c) + p_strlen(d) + 1);
156+
if (a)
157+
z = a;
158+
z += b;
159+
if (c)
160+
z += c;
161+
if (d)
162+
z += d;
163+
return z;
164+
}
153165
inline string concat(const string& a, CStr b) noexcept { return b ? a + b : a; }
154166

155167
inline string concat(CStr a, const string& b, CStr c = nullptr) noexcept {

0 commit comments

Comments
 (0)