Skip to content

Commit

Permalink
Merge pull request #911 from os-fpga/checker_better_diag_4clockdata_E…
Browse files Browse the repository at this point in the history
…3235

checker: better diagnostics for clock-data EDA-3235
  • Loading branch information
serge-dsa authored Oct 31, 2024
2 parents 0807adc + 720d7e8 commit 32c6309
Show file tree
Hide file tree
Showing 8 changed files with 148 additions and 47 deletions.
5 changes: 4 additions & 1 deletion planning/src/RS/rsCheck.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ bool do_check_blif(CStr cfn,
uint numInp = bfile.numInputs();
uint numOut = bfile.numOutputs();

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

if (tr >= 4) {
Expand Down Expand Up @@ -115,6 +115,7 @@ bool do_check_blif(CStr cfn,
ls << "----- #TDP_RAM36K= " << nTDP_RAM36K << endl;
ls << "----- #TDP_RAM18KX2= " << nTDP_RAM18K << endl;
ls << "----- #CARRY= " << nCARRY << endl;
ls << "----- #WIREs= " << bfile.countWires() << endl;
}
ls << "-----\n";
ls << "----- PinGraph: " << bfile.pinGraphFile_ << endl;
Expand Down Expand Up @@ -173,6 +174,8 @@ bool do_check_blif(CStr cfn,

ls << "[Error] ERROR BLIF is not OK ERROR" << endl;
ls << "[Error] ERROR " << bfile.err_msg_ << endl;
if (not bfile.err_info2_.empty())
ls << "[Error] ERROR " << bfile.err_info2_ << endl;

flush_out(true);
uint errLnum = std::max(bfile.err_lnum_, bfile.err_lnum2_);
Expand Down
114 changes: 92 additions & 22 deletions planning/src/file_io/pln_blif_file.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ void BLIF_file::reset(CStr nm, uint16_t tr) noexcept {
inputs_lnum_ = outputs_lnum_ = 0;
err_lnum_ = err_lnum2_ = 0;
err_msg_.clear();
err_info2_.clear();
pg_.clear();
pg2blif_.clear();

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

rd_ok_ = chk_ok_ = false;
err_msg_.clear();
err_info2_.clear();
trace_ = 0;

{
Expand Down Expand Up @@ -779,6 +781,17 @@ uint BLIF_file::countFFs() const noexcept {
return cnt;
}

uint BLIF_file::countWires() const noexcept {
if (numNodes() == 0 or fabricRealNodes_.empty())
return 0;
uint cnt = 0;
for (const BNode* x : fabricRealNodes_) {
if (x->is_WIRE())
cnt++;
}
return cnt;
}

uint BLIF_file::countCBUFs() const noexcept {
uint nn = numNodes();
if (nn == 0)
Expand Down Expand Up @@ -1628,24 +1641,24 @@ void BLIF_file::BNode::allInputPins(vector<string>& V) const noexcept {
return;
}

BLIF_file::BNode* BLIF_file::findOutputPort(const string& contact) noexcept {
assert(not contact.empty());
BLIF_file::BNode* BLIF_file::findOutputPort(const string& sig) noexcept {
assert(not sig.empty());
if (topOutputs_.empty()) return nullptr;

// TMP linear
for (BNode* x : topOutputs_) {
if (x->out_ == contact) return x;
if (x->out_ == sig) return x;
}
return nullptr;
}

BLIF_file::BNode* BLIF_file::findInputPort(const string& contact) noexcept {
assert(not contact.empty());
BLIF_file::BNode* BLIF_file::findInputPort(const string& sig) noexcept {
assert(not sig.empty());
if (topInputs_.empty()) return nullptr;

// TMP linear
for (BNode* x : topInputs_) {
if (x->out_ == contact) return x;
if (x->out_ == sig) return x;
}
return nullptr;
}
Expand Down Expand Up @@ -2010,7 +2023,7 @@ bool BLIF_file::checkClockSepar(vector<BNode*>& clocked) noexcept {
}

bool color_ok = true;
CStr viol_prefix = " ===!!! clock-data separation error";
CStr viol_prefix = " [Error] clock-data separation ERROR";

// -- check that end-points of red edges are red
for (NW::cEI E(pg_); E.valid(); ++E) {
Expand Down Expand Up @@ -2039,11 +2052,18 @@ bool BLIF_file::checkClockSepar(vector<BNode*>& clocked) noexcept {
lprintf("%s: blif lines: %u - %u\n",
viol_prefix, err_lnum_, err_lnum2_);
char B[512] = {};
::sprintf(B, " line %u : %s ", err_lnum_, bnode1.kw_.c_str());
::sprintf(B, " ERROR line %u : %s ", err_lnum_, bnode1.kw_.c_str());
logVec(bnode1.data_, B);
::sprintf(B, " line %u : %s ", err_lnum2_, bnode2.kw_.c_str());
::sprintf(B, " ERROR line %u : %s ", err_lnum2_, bnode2.kw_.c_str());
logVec(bnode2.data_, B);
flush_out(true);
if (bnode1.isTopInput() and bnode2.is_WIRE()) {
err_info2_ = str::concat( "clock input port ", bnode1.out_,
" drives feedthrough wire at line ",
std::to_string(err_lnum2_) );
lprintf("error-info: %s\n", err_info2_.c_str());
flush_out(true);
}
}
break;
}
Expand All @@ -2060,7 +2080,8 @@ bool BLIF_file::checkClockSepar(vector<BNode*>& clocked) noexcept {

if (!color_ok) {
flush_out(true); err_puts();
lprintf2("[Error] clock-data separation error\n");
lprintf2("[Error] clock-data separation error: lines %u - %u\n",
err_lnum_, err_lnum2_);
err_puts(); flush_out(true);
return false;
}
Expand Down Expand Up @@ -2097,6 +2118,7 @@ bool BLIF_file::createPinGraph() noexcept {
if (fabricNodes_.empty()) return false;

err_msg_.clear();
err_info2_.clear();
uint64_t key = 0;
uint nid = 0, kid = 0, eid = 0;
vector<string> INP;
Expand Down Expand Up @@ -2146,6 +2168,54 @@ bool BLIF_file::createPinGraph() noexcept {
vector<qTup> Q;
Q.reserve(topInputs_.size());

// -- link in-ports to out-ports via feedthrough wires
for (BNode* x : fabricRealNodes_) {
if (x->is_WIRE()) {
BNode& w = *x;
assert(w.data_.size() == 2);
const string& w_inp = w.data_.front();
const string& w_out = w.data_.back();
BNode* iport = findInputPort(w_inp);
if (!iport)
continue;
BNode* oport = findOutputPort(w_out);
if (!oport)
continue;
assert(iport->isTopInput());
assert(oport->isTopOutput());
// NW-nodes for i/o ports should exist already
assert(iport->nw_id_);
assert(oport->nw_id_);
assert(pg_.hasNode(iport->nw_id_));
assert(pg_.hasNode(oport->nw_id_));
assert(map_pg2blif(iport->nw_id_) == iport->id_);
assert(map_pg2blif(oport->nw_id_) == oport->id_);

// NW keys and nodes for wire pseudo-cell:
uint64_t w_k1 = hashCantor(w.id_, 1) + max_key1;
uint64_t w_k2 = hashCantor(w.id_, 2) + max_key1;
assert(w_k1);
assert(w_k2);
assert(w_k1 != w_k2);
uint w_n1 = pg_.insK(w_k1);
assert(w_n1);
uint w_n2 = pg_.insK(w_k2);
assert(w_n2);
pg2blif_.emplace(w_n1, w.id_);
pg2blif_.emplace(w_n2, w.id_);
pg_.setNodeName4(w_n1, w.id_, w.lnum_, 1, "FTwireI");
pg_.setNodeName4(w_n2, w.id_, w.lnum_, 2, "FTwireO");

// link feedthrough:
uint ee;
ee = pg_.linkNodes(iport->nw_id_, w_n1, false);
ee = pg_.linkNodes(w_n1, w_n2, true);
ee = pg_.linkNodes(w_n2, oport->nw_id_, false);
if (trace_ >= 11)
lprintf("\t\t ee = %u\n", ee);
}
}

// -- link from input ports to fabric
for (BNode* p : topInputs_) {
INP.clear();
Expand All @@ -2163,9 +2233,6 @@ bool BLIF_file::createPinGraph() noexcept {
lprintf(" %s\n", port.cPortName());
}

// if (port.id_ == 24)
// lputs1();

for (const upair& pa : PAR) {
if (pa.first == port.id_)
continue;
Expand Down Expand Up @@ -2295,12 +2362,12 @@ bool BLIF_file::createPinGraph() noexcept {
uint cn_realId = cn.realId(*this);
key = hashCantor(cn_realId, i + 1) + max_key1;
assert(key);
// if (key == 110)
// lputs3();
kid = pg_.findNode(key);
if (kid) {
lprintf("\t\t ___ found nid %u '%s' for key %zu",
kid, pg_.cnodeName(kid), key);
if (trace_ >= 8) {
lprintf("\t\t ___ found nid %u '%s' for key %zu",
kid, pg_.cnodeName(kid), key);
}
}
else {
kid = pg_.insK(key);
Expand Down Expand Up @@ -2529,7 +2596,8 @@ bool BLIF_file::createPinGraph() noexcept {

pg_.setNwName("pin_graph");

// writePinGraph("pin_graph_1.dot");
if (trace_ >= 8)
writePinGraph("Dpin_graph_1.dot", true, false);

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

lprintf("(writePinGraph) status:%s file: %s\n",
wrDot_ok ? "OK" : "FAIL",
fn.c_str());
if (not wrDot_ok or trace_ >= 4) {
lprintf("(writePinGraph) status:%s file: %s\n\n",
wrDot_ok ? "OK" : "FAIL",
fn.c_str());
}

flush_out(true);
flush_out(false);
if (wrDot_ok)
return fn;
return {};
Expand Down
12 changes: 9 additions & 3 deletions planning/src/file_io/pln_blif_file.h
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,11 @@ struct BLIF_file : public fio::MMapReader
bool is_CARRY() const noexcept {
return ptype_ == prim::CARRY;
}
bool is_WIRE() const noexcept {
if (ptype_ != prim::A_ZERO or kw_ != ".names")
return false;
return data_.size() == 2;
}

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

string err_msg_;
string err_msg_, err_info2_;
uint16_t trace_ = 0;

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

Expand Down Expand Up @@ -358,8 +364,8 @@ struct BLIF_file : public fio::MMapReader

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

BNode* findOutputPort(const string& contact) noexcept;
BNode* findInputPort(const string& contact) noexcept;
BNode* findOutputPort(const string& sig) noexcept;
BNode* findInputPort(const string& sig) noexcept;

BNode* findFabricParent(uint of, const string& contact, int& pinIndex) noexcept; // searches inputs
BNode* findFabricDriver(uint of, const string& contact) noexcept; // matches out_
Expand Down
2 changes: 1 addition & 1 deletion planning/src/main.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
static const char* _pln_VERSION_STR = "pln0362";
static const char* _pln_VERSION_STR = "pln0363";

#include "RS/rsEnv.h"
#include "util/pln_log.h"
Expand Down
4 changes: 2 additions & 2 deletions planning/src/util/nw/Nw.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ uint NW::insK(uint64_t k) noexcept {
newNid = nid_at(I - nids_.begin());
ndStor_.pop_back();
nids_.pop_back();
// if (newNid == 36)
// if (newNid == 16)
// lputs4();
} else {
newNid = p->id_;
Expand All @@ -62,7 +62,7 @@ uint NW::insK(uint64_t k) noexcept {
}

assert(nodeRef(newNid).key_ == k);
//if (newNid == 36)
// if (newNid == 16)
// lputs4();
return newNid;
}
Expand Down
15 changes: 3 additions & 12 deletions planning/src/util/nw/Nw.h
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,9 @@ struct NW {
inline uint numE() const noexcept;
uint countRedEdges() const noexcept;

inline upair countRoots() const noexcept;
upair countRoots() const noexcept;
upair countPorts() const noexcept;

bool hasClockNodes() const noexcept;
uint countClockNodes() const noexcept;
uint countRedNodes() const noexcept;
Expand Down Expand Up @@ -795,17 +797,6 @@ inline uint NW::linK(uint64_t k1, uint64_t k2) noexcept {
return linkNodes(n1, n2);
}

inline upair NW::countRoots() const noexcept {
uint cnt = 0, mark_cnt = 0;
if (empty()) return {cnt, mark_cnt};
for (cNI I(*this); I.valid(); ++I) {
const Node& nd = *I;
if (nd.isTreeRoot()) cnt++;
if (nd.isFlagRoot()) mark_cnt++;
}
return {cnt, mark_cnt};
}

inline uint NW::getMaxLabel() const noexcept {
if (empty()) return 0;
uint maxLabel = 0;
Expand Down
21 changes: 15 additions & 6 deletions planning/src/util/nw/Nw_io.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -372,13 +372,19 @@ void NW::Node::nprint_dot(ostream& os) const noexcept {
}
else {

if (isRed()) {
::strcpy(attrib, "[ shape=octagon, color=purple, fillcolor=pink, style=filled ];");
if (out_flag_) {
CStr cs = isRed() ? "red" : "brown";
::sprintf(attrib, "[ shape=box, color=%s, style=filled ];", cs);
}
else {
::strcpy(attrib, "[ shape=record, style=rounded ];");
if (viol_flag_) {
::strcpy(attrib, "[ shape=doubleoctagon, color=blueviolet, fillcolor=violet, style=filled ];");
if (isRed()) {
::strcpy(attrib, "[ shape=octagon, color=purple, fillcolor=pink, style=filled ];");
}
else {
::strcpy(attrib, "[ shape=record, style=rounded ];");
if (viol_flag_) {
::strcpy(attrib, "[ shape=doubleoctagon, color=blueviolet, fillcolor=violet, style=filled ];");
}
}
}

Expand Down Expand Up @@ -504,6 +510,7 @@ uint NW::printSum(ostream& os, uint16_t forDot) const noexcept {
upair mmD = getMinMaxDeg();
upair mmL = getMinMaxLbl();
upair rcnt = countRoots();
upair pcnt = countPorts();
uint numClkNodes = countClockNodes();

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

dot_comment(os, forDot);
os_printf(os, "nr=(%u,%u)\n", rcnt.first, rcnt.second);
os_printf(os, "nr=(%u,%u) #Inp=%u #Out=%u\n",
rcnt.first, rcnt.second,
pcnt.first, pcnt.second);

return size();
}
Expand Down
Loading

0 comments on commit 32c6309

Please sign in to comment.