Skip to content

Commit

Permalink
clock checker: allow port feedthrough EDA-3235
Browse files Browse the repository at this point in the history
  • Loading branch information
serge-rs committed Nov 26, 2024
1 parent 964124f commit f5a27f8
Show file tree
Hide file tree
Showing 5 changed files with 120 additions and 56 deletions.
136 changes: 84 additions & 52 deletions planning/src/file_io/pln_blif_file.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1199,12 +1199,6 @@ bool BLIF_file::createNodes() noexcept {
if (not starts_w_subckt(cs + 1, len - 1))
continue;
Fio::split_spa(lines_[L], V);
//if (L == 48) {
// string delWire1151 = "$delete_wire$1151";
// lputs8();
// int dTerm = findTermByNet(V, delWire1151);
// lprintf(" dTerm= %i\n", dTerm);
//}
if (V.size() > 1 and V.front() == ".subckt") {
Prim_t pt = pr_str2enum( V[1].c_str() );
if (pr_is_MOG(pt)) {
Expand Down Expand Up @@ -1997,7 +1991,35 @@ bool BLIF_file::checkClockSepar(vector<BNode*>& clocked) noexcept {
}
}

if (trace_ >= 6) {
// -- paint top-output nodes (and their incoming wires) Black
for (BNode* p : topOutputs_) {
const BNode& port = *p;
assert(!port.out_.empty());
assert(port.nw_id_);
if (!port.nw_id_)
continue;
NW::Node& nd = pg_.nodeRefCk(port.nw_id_);
nd.paintBlack();
uint par = port.parent_;
while (par) {
const BNode& parBn = bnodeRef(par);
assert(parBn.nw_id_);
if (!parBn.nw_id_)
break;
if (!parBn.is_WIRE())
break;
NW::Node& nwn = pg_.nodeRefCk(parBn.nw_id_);
nwn.paintBlack();
if (nwn.parent()) {
NW::Node& nwp = pg_.nodeRefCk(nwn.parent());
if (map_pg2blif(nwp.id_) == parBn.id_)
nwp.paintBlack();
}
par = parBn.parent_;
}
}

if (trace_ >= 5) {
lputs(" (Pin Graph) *** summary after B ***");
pg_.printSum(ls, 0);
lputs();
Expand Down Expand Up @@ -2025,13 +2047,16 @@ bool BLIF_file::checkClockSepar(vector<BNode*>& clocked) noexcept {
bool color_ok = true;
CStr viol_prefix = " [Error] clock-data separation ERROR";

// -- check that end-points of red edges are red
// -- check that end-points of red edges are red,
// the destination node may be black (output port)
for (NW::cEI E(pg_); E.valid(); ++E) {
const NW::Edge& ed = *E;
if (not ed.isRed())
continue;
NW::Node& p1 = pg_.nodeRef(ed.n1_);
NW::Node& p2 = pg_.nodeRef(ed.n2_);
if (p2.isBlack())
continue;
if (!p1.isRed() or !p2.isRed()) {
color_ok = false;
p1.markViol(true);
Expand Down Expand Up @@ -2170,50 +2195,57 @@ bool BLIF_file::createPinGraph() noexcept {

// -- 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);
}
BNode& w = *x;
if (not w.is_WIRE())
continue;
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_);
w.nw_id_ = w_n2;
pg_.nodeRef(w_n1).markWire(true);
pg_.nodeRef(w_n2).markWire(true);
pg_.setNodeName4(w_n1, w.id_, w.lnum_, 1, "FTwireI");
pg_.setNodeName4(w_n2, w.id_, w.lnum_, 2, "FTwireO");

// make sure BNode::parent_ links are set
oport->parent_ = w.id_;
w.parent_ = iport->id_;

// 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
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 = "pln0366";
static const char* _pln_VERSION_STR = "pln0367";

#include "RS/rsEnv.h"
#include "RS/rsDeal.h"
Expand Down
20 changes: 20 additions & 0 deletions planning/src/util/nw/Nw.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,26 @@ uint NW::countRedNodes() const noexcept {
return cnt;
}

uint NW::countBlackNodes() const noexcept {
uint cnt = 0;
if (empty()) return 0;
for (cNI I(*this); I.valid(); ++I) {
if (I->isBlack())
cnt++;
}
return cnt;
}

uint NW::countWireNodes() const noexcept {
uint cnt = 0;
if (empty()) return 0;
for (cNI I(*this); I.valid(); ++I) {
if (I->wire_flag_)
cnt++;
}
return cnt;
}

bool NW::hasClockNodes() const noexcept {
if (empty()) return false;
for (cNI I(*this); I.valid(); ++I) {
Expand Down
11 changes: 10 additions & 1 deletion planning/src/util/nw/Nw.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ struct NW {
static constexpr uint c_darkorchid4 = 13;
static constexpr uint c_cyan = 14;
static constexpr uint c_goldenrod3 = 15;
static constexpr uint c_MAX_COLOR = 15;
static constexpr uint c_Black = 16;
static constexpr uint c_MAX_COLOR = 16;

struct Edge {
uint id_ = 0;
Expand All @@ -64,6 +65,8 @@ struct NW {
void paint(uint col) noexcept { color_ = col; }
void paintRed() noexcept { color_ = c_Red; }
bool isRed() const noexcept { return color_ == c_Red; }
void paintBlack() noexcept { color_ = c_Black; }
bool isBlack() const noexcept { return color_ == c_Black; }

bool valid() const noexcept { return n1_; }
void inval() noexcept { ::memset(this, 0, sizeof(*this)); }
Expand Down Expand Up @@ -156,6 +159,7 @@ struct NW {
void markOut(bool val) noexcept { out_flag_ = val; }
void markClk(bool val) noexcept { clk_flag_ = val; }
void markViol(bool val) noexcept { viol_flag_ = val; }
void markWire(bool val) noexcept { wire_flag_ = val; }
void markPrim(uint16_t pt) noexcept { prim_ = pt; }

bool isClk() const noexcept { return clk_flag_; }
Expand All @@ -170,6 +174,8 @@ struct NW {
void paint(uint col) noexcept { color_ = col; }
void paintRed() noexcept { color_ = c_Red; }
bool isRed() const noexcept { return color_ == c_Red; }
void paintBlack() noexcept { color_ = c_Black; }
bool isBlack() const noexcept { return color_ == c_Black; }

// DATA:
vecu edges_;
Expand All @@ -192,6 +198,7 @@ struct NW {
bool out_flag_ = false;
bool clk_flag_ = false;
bool viol_flag_ = false;
bool wire_flag_ = false;
string name_;
};

Expand Down Expand Up @@ -280,6 +287,8 @@ struct NW {
bool hasClockNodes() const noexcept;
uint countClockNodes() const noexcept;
uint countRedNodes() const noexcept;
uint countBlackNodes() const noexcept;
uint countWireNodes() const noexcept;
uint countNamedNodes() const noexcept;

void getNodes(vecu& V) const noexcept { V = nids_; }
Expand Down
7 changes: 5 additions & 2 deletions planning/src/util/nw/Nw_io.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -523,10 +523,13 @@ uint NW::printSum(ostream& os, uint16_t forDot) const noexcept {
uint numNamedNodes = countNamedNodes();
uint numRedNodes = countRedNodes();
uint numRedEdges = countRedEdges();
uint numBlackNodes = countBlackNodes();
uint numWireNodes = countWireNodes();

dot_comment(os, forDot);
os_printf(os, "#NamedNodes=%u #RedNodes= %u #RedEdges= %u\n",
numNamedNodes, numRedNodes, numRedEdges);
os_printf(os,
"#NamedNodes=%u #RedN= %u #RedE= %u #BlackN= %u #WireN= %u\n",
numNamedNodes, numRedNodes, numRedEdges, numBlackNodes, numWireNodes);

dot_comment(os, forDot);
os_printf(os, "nr=(%u,%u) #Inp=%u #Out=%u\n",
Expand Down

0 comments on commit f5a27f8

Please sign in to comment.