Fully support RECT in DEF net routing

The wire encoder/decode now has a WOP_RECT opcode to store these shapes.
They are exposed in the decoder & dbWireShapeItr but not in the
higher level dbRtTree dbWireGraph classes.
This commit is contained in:
Matt Liberty
2020-03-30 13:32:47 -07:00
parent dfe7d78469
commit b4b41644eb
17 changed files with 225 additions and 242 deletions

View File

@@ -113,7 +113,6 @@ class dbRtNode
dbRtEdge* _tail;
DListEntry<dbRtNode> _rt_node;
bool _visited;
int _bterm_map_id;
void add_edge(dbRtEdge* edge)
{
@@ -159,8 +158,7 @@ class dbRtNode
_rt_tree(NULL),
_head(NULL),
_tail(NULL),
_visited(false),
_bterm_map_id(-1)
_visited(false)
{
}
@@ -218,12 +216,6 @@ class dbRtNode
// Set the value of the visited flag.
void setVisited(bool value) { _visited = value; }
// Get the bterm-map-id
int getBTermMapId() const { return _bterm_map_id; }
// Set the bterm-map-id
void setBTermMapId(int id) { _bterm_map_id = id; }
// returns true if this node has no edges
bool isOrphan() const { return _head == NULL; }

View File

@@ -63,6 +63,8 @@ class dbRtVWire;
//
// The graph is undirected and cannot contain cycles.
//
// Patch wires (rects) are not exposed in the tree.
//
class dbRtTree
{
public:

View File

@@ -33,12 +33,12 @@
#pragma once
#include "ZException.h"
#include "odb.h"
#include "dbObject.h"
#include "dbSet.h"
#include "dbTransform.h"
#include "dbWireCodec.h"
#include "geom.h"
#include "odb.h"
namespace odb {
@@ -121,6 +121,8 @@ class dbShape
int dw,
dbTechLayer* layer);
void setSegmentFromRect(int x1, int y1, int x2, int y2, dbTechLayer* layer);
void setVia(dbVia* via, const Rect& r)
{
_type = VIA;
@@ -260,6 +262,8 @@ class dbShape
///
/// dbWireShapeItr - Iterate the shapes of a dbWire.
///
/// RECT in the dbWire are treats as segments for convenience
///
class dbWireShapeItr
{
public:
@@ -298,7 +302,7 @@ class dbWireShapeItr
struct dbWirePath
{
int junction_id; // junction id of this point
Point point; // starting point of path
Point point; // starting point of path
dbTechLayer* layer; // starting layer of path
dbBTerm* bterm; // dbBTerm connected at this point, otherwise NULL
dbITerm* iterm; // dbITerm connected at this point, otherwise NULL
@@ -313,7 +317,7 @@ struct dbWirePath
struct dbWirePathShape
{
int junction_id; // junction id of this point
Point point; // starting point of path
Point point; // starting point of path
dbTechLayer* layer; // layer of shape, or exit layer of via
dbBTerm* bterm; // dbBTerm connected at this point, otherwise NULL
dbITerm* iterm; // dbITerm connected at this point, otherwise NULL
@@ -673,11 +677,21 @@ inline void dbShape::setSegment(int prev_x,
_via = NULL;
}
inline void dbShape::setSegmentFromRect(int x1,
int y1,
int x2,
int y2,
dbTechLayer* layer)
{
_type = dbShape::SEGMENT;
_rect.reset(x1, y1, x2, y2);
_layer = layer;
_via = nullptr;
}
//
// Print utilities declared here
//
void dumpWirePaths4Net(dbNet* innet, const char* module_name, const char* tag);
} // namespace odb

View File

@@ -34,8 +34,8 @@
#include <vector>
#include "odb.h"
#include "dbTypes.h"
#include "odb.h"
namespace odb {
@@ -346,6 +346,11 @@ class dbWireEncoder
///
int addTechVia(dbTechVia* via);
///
/// Add a rect (aka patch wire) relative the previous point
///
void addRect(int deltaX1, int deltaY1, int deltaX2, int deltaY2);
///
/// Connect an iterm to the previous point.
///
@@ -440,11 +445,6 @@ class dbWireEncoder
///
void clear();
///
/// For internal use only.
///
void addBTermMapId(int id);
////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Depreciated methods:
@@ -501,9 +501,9 @@ class dbWireDecoder
POINT_EXT, /// A point on a path with an extension.
VIA, /// A VIA instance on a path.
TECH_VIA, /// A TECH-VIA instance on a path with an extension.
RECT, /// A rect / patch wire
ITERM, /// A dbITerm connected to the previous point/via
BTERM, /// A dbBTerm connected to the previous point/via
BTERM_MAP_ID, /// (For internal use only) Mapping id to hierarchical bterm
RULE, /// Use non-default rule
END_DECODE /// No more path elements to decode.
};
@@ -525,6 +525,10 @@ class dbWireDecoder
int _point_cnt;
OpCode _opcode;
uint _property;
int _deltaX1;
int _deltaY1;
int _deltaX2;
int _deltaY2;
unsigned char nextOp(int& value);
unsigned char nextOp(uint& value);
@@ -590,6 +594,11 @@ class dbWireDecoder
///
dbTechVia* getTechVia() const;
///
/// Get deltas of the RECT.
///
void getRect(int& deltaX1, int& deltaY1, int& deltaX2, int& deltaY2) const;
///
/// Get value of the ITERM OpCode.
///
@@ -622,11 +631,6 @@ class dbWireDecoder
/// junction-id of the previous point from which this branch emerges.
///
int getJunctionValue() const;
///
/// Get the bterm map id
///
int getBTermMapId() const;
};
///
@@ -636,5 +640,3 @@ void dumpDecoder(dbBlock* inblk, const char* net_name_or_id);
void dumpDecoder4Net(dbNet* innet);
} // namespace odb

View File

@@ -66,6 +66,9 @@ class dbWireEncoder;
//
// This graph may be edited and encoded back to the wire.
//
// Patch wires (rects) are not exposed in the graph.
//
//
class dbWireGraph
{
public:

View File

@@ -813,23 +813,7 @@ void dbFlatten::fixWire(dbVector<unsigned char>& opcodes,
}
case WOP_BTERM: {
if (bterm_map == NULL) {
opcodes[i] = WOP_NOP;
data[i] = 0;
} else {
dbBTerm* bterm = dbBTerm::getBTerm(src, data[i]);
std::string name = bterm->getName();
dbIntProperty::create(bterm_map, name.c_str(), _next_bterm_map_id);
opcodes[i] = WOP_BTERM_MAP;
data[i] = _next_bterm_map_id;
;
++_next_bterm_map_id;
}
break;
}
case WOP_BTERM_MAP: {
assert(bterm_map == NULL);
opcodes[i] = WOP_NOP;
data[i] = 0;
break;

View File

@@ -137,9 +137,6 @@ void dbRtTree::addObjects(dbWireEncoder& encoder, dbRtNode* node)
encoder.addBTerm((dbBTerm*) obj);
}
}
if (node->_bterm_map_id != -1)
encoder.addBTermMapId(node->_bterm_map_id);
}
void dbRtVia::getBBox(Rect& bbox)
@@ -692,6 +689,10 @@ void dbRtTree::decode(dbWire* wire, bool decode_bterms_iterms)
break;
}
case dbWireDecoder::RECT: {
// ignored
break;
}
case dbWireDecoder::ITERM: {
if (decode_bterms_iterms)
prev->addObject((dbObject*) decoder.getITerm());
@@ -704,13 +705,6 @@ void dbRtTree::decode(dbWire* wire, bool decode_bterms_iterms)
break;
}
case dbWireDecoder::BTERM_MAP_ID: {
assert(prev->_bterm_map_id == -1);
if (decode_bterms_iterms)
prev->_bterm_map_id = decoder.getBTermMapId();
break;
}
case dbWireDecoder::RULE: {
cur_rule = decoder.getRule();
break;

View File

@@ -288,7 +288,7 @@ uint dbWire::equal(dbWire* target)
if (src_op != tgt_op)
return (1 + pjunction);
if (src_op == WOP_ITERM || src_op == WOP_BTERM || src_op == WOP_BTERM_MAP)
if (src_op == WOP_ITERM || src_op == WOP_BTERM)
continue;
if (src->_data[idx] != tgt->_data[idx])
@@ -403,8 +403,7 @@ void dbWire::donateWireSeg(dbWire* w1, dbRSeg** new_rsegs)
opcode = wire->_opcodes[jj];
opcd = opcode & WOP_OPCODE_MASK;
data = wire->_data[jj];
if (opcd == WOP_ITERM || opcd == WOP_BTERM || opcd == WOP_BTERM_MAP
|| opcd == WOP_NOP)
if (opcd == WOP_ITERM || opcd == WOP_BTERM || opcd == WOP_NOP)
continue;
if (opcd == WOP_JUNCTION) {
data = destid[data];
@@ -468,8 +467,7 @@ void dbWire::shuffleWireSeg(dbNet** newNets, dbRSeg** new_rsegs)
for (jj = 0; jj < wlen; jj++) {
opcode = wire->_opcodes[jj];
opcd = opcode & WOP_OPCODE_MASK;
if (opcd == WOP_ITERM || opcd == WOP_BTERM || opcd == WOP_BTERM_MAP
|| opcd == WOP_NOP)
if (opcd == WOP_ITERM || opcd == WOP_BTERM || opcd == WOP_NOP)
continue;
data = wire->_data[jj];
switch (opcd) {
@@ -864,8 +862,8 @@ void dbWire::printWire(FILE* fp, int fid, int tid)
fprintf(fp, "WOP_BTERM :");
break;
}
case WOP_BTERM_MAP: {
fprintf(fp, "WOP_BTERM_MAP :");
case WOP_RECT: {
fprintf(fp, "WOP_RECT :");
break;
}
case WOP_OPERAND: {
@@ -1718,8 +1716,7 @@ void dbWire::copy(dbWire* dst_,
for (i = 0; i < n; ++i) {
unsigned char opcode = dst->_opcodes[i] & WOP_OPCODE_MASK;
if (opcode == WOP_ITERM || opcode == WOP_BTERM
|| opcode == WOP_BTERM_MAP) {
if (opcode == WOP_ITERM || opcode == WOP_BTERM) {
dst->_opcodes[i] = WOP_NOP;
dst->_data[i] = 0;
}

View File

@@ -30,8 +30,6 @@
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
#include "dbWireCodec.h"
#include <ctype.h>
#include "db.h"
@@ -41,6 +39,7 @@
#include "dbTech.h"
#include "dbTechLayerRule.h"
#include "dbWire.h"
#include "dbWireCodec.h"
#include "dbWireOpcode.h"
#include "logger.h"
@@ -384,6 +383,16 @@ int dbWireEncoder::addTechVia(dbTechVia* via)
return jct_id;
}
void dbWireEncoder::addRect(int deltaX1, int deltaY1, int deltaX2, int deltaY2)
{
// order must match dbWireDecoder::next
ZASSERT(_point_cnt != 0);
addOp(WOP_RECT, deltaX1);
addOp(WOP_OPERAND, deltaY1);
addOp(WOP_OPERAND, deltaX2);
addOp(WOP_OPERAND, deltaY2);
}
void dbWireEncoder::addITerm(dbITerm* iterm)
{
ZASSERT(_point_cnt != 0);
@@ -396,12 +405,6 @@ void dbWireEncoder::addBTerm(dbBTerm* bterm)
addOp(WOP_BTERM, bterm->getImpl()->getOID());
}
void dbWireEncoder::addBTermMapId(int id)
{
ZASSERT(_point_cnt != 0);
addOp(WOP_BTERM_MAP, id);
}
void dbWireEncoder::newPath(dbTechLayer* layer, dbWireType type)
{
initPath(layer, type);
@@ -634,6 +637,10 @@ void dbWireDecoder::begin(dbWire* wire)
_wire_type = dbWireType::NONE;
_point_cnt = 0;
_property = 0;
_deltaX1 = 0;
_deltaY1 = 0;
_deltaX2 = 0;
_deltaY2 = 0;
}
inline unsigned char dbWireDecoder::nextOp(int& value)
@@ -713,8 +720,8 @@ nextOpCode:
case WOP_BTERM:
return BTERM;
case WOP_BTERM_MAP:
return BTERM_MAP_ID;
case WOP_RECT:
return RECT;
case WOP_VWIRE:
return VWIRE;
@@ -942,6 +949,14 @@ nextOpCode:
return _opcode = TECH_VIA;
}
case WOP_RECT:
// order matches dbWireEncoder::addRect
_deltaX1 = _operand;
nextOp(_deltaY1);
nextOp(_deltaX2);
nextOp(_deltaY2);
return _opcode = RECT;
case WOP_ITERM:
return _opcode = ITERM;
@@ -987,9 +1002,6 @@ nextOpCode:
return _opcode = VWIRE;
}
case WOP_BTERM_MAP:
return _opcode = BTERM_MAP_ID;
case WOP_NOP:
goto nextOpCode;
@@ -1050,6 +1062,18 @@ dbTechVia* dbWireDecoder::getTechVia() const
return via;
}
void dbWireDecoder::getRect(int& deltaX1,
int& deltaY1,
int& deltaX2,
int& deltaY2) const
{
ZASSERT(_opcode == RECT);
deltaX1 = _deltaX1;
deltaY1 = _deltaY1;
deltaX2 = _deltaX2;
deltaY2 = _deltaY2;
}
dbITerm* dbWireDecoder::getITerm() const
{
ZASSERT(_opcode == ITERM);
@@ -1064,12 +1088,6 @@ dbBTerm* dbWireDecoder::getBTerm() const
return bterm;
}
int dbWireDecoder::getBTermMapId() const
{
ZASSERT(_opcode == BTERM_MAP_ID);
return _operand;
}
dbWireType dbWireDecoder::getWireType() const
{
ZASSERT((_opcode == PATH) || (_opcode == JUNCTION) || (_opcode == SHORT)
@@ -1268,20 +1286,26 @@ void dumpDecoder4Net(dbNet* innet)
break;
}
case dbWireDecoder::RECT: {
int deltaX1;
int deltaY1;
int deltaX2;
int deltaY2;
decoder.getRect(deltaX1, deltaY1, deltaX2, deltaY2);
break;
}
case dbWireDecoder::ITERM: {
notice(0, "%s Found Iterm\n", prfx);
break;
}
case dbWireDecoder::BTERM: {
notice(0, "%s Found Bterm\n", prfx);
break;
}
case dbWireDecoder::BTERM_MAP_ID: {
notice(0, "%s Found Bterm-map-id\n", prfx);
break;
}
case dbWireDecoder::RULE: {
case dbWireDecoder::RULE: {
if (strcmp(
lyr_rule->getNonDefaultRule()->getName().c_str(),
(decoder.getRule())->getNonDefaultRule()->getName().c_str())) {

View File

@@ -424,7 +424,8 @@ void dbWireGraph::decode(dbWire* wire)
break;
}
case dbWireDecoder::BTERM_MAP_ID:
case dbWireDecoder::RECT:
// ignored
break;
case dbWireDecoder::RULE: {

View File

@@ -69,7 +69,7 @@ namespace odb {
#define WOP_OPERAND 11 // X X X X 1 0 1 1 : operand = integer operand
#define WOP_PROPERTY 12 // X X X X 1 1 0 0 : operand = integer operand
#define WOP_VWIRE 13 // W W W X 1 1 0 1 : operand = integer operand
#define WOP_BTERM_MAP 14 // X X X X 1 1 1 0 : operand = bterm-map-id
#define WOP_RECT 14 // X X X X 1 1 1 0 : operand = first offset
#define WOP_NOP 15 // X X X X 1 1 1 1 : operand = 0
// opcode-flags

View File

@@ -315,9 +315,24 @@ nextOpCode:
return true;
}
case WOP_RECT: {
int deltaX1 = operand;
int deltaY1;
int deltaX2;
int deltaY2;
nextOp(deltaY1);
nextOp(deltaX2);
nextOp(deltaY2);
shape.setSegmentFromRect(_prev_x + deltaX1,
_prev_y + deltaY1,
_prev_x + deltaX2,
_prev_y + deltaY2,
_layer);
return true;
}
case WOP_ITERM:
case WOP_BTERM:
case WOP_BTERM_MAP:
case WOP_OPERAND:
case WOP_PROPERTY:
case WOP_NOP:

View File

@@ -315,9 +315,9 @@ void print_encoding(dbWire* wire)
break;
}
case dbWireDecoder::RECT:
case dbWireDecoder::ITERM:
case dbWireDecoder::BTERM:
case dbWireDecoder::BTERM_MAP_ID:
case dbWireDecoder::RULE:
break;

View File

@@ -573,6 +573,12 @@ void definNet::pathVia(const char* via_name)
}
}
void definNet::pathRect(int deltaX1, int deltaY1, int deltaX2, int deltaY2)
{
_wire_encoder.addRect(
dbdist(deltaX1), dbdist(deltaY1), dbdist(deltaX2), dbdist(deltaY2));
}
void definNet::pathEnd()
{
_cur_layer = NULL;

View File

@@ -35,9 +35,9 @@
#include <map>
#include <string>
#include "odb.h"
#include "dbWireCodec.h"
#include "definBase.h"
#include "odb.h"
namespace odb {
@@ -95,6 +95,7 @@ class definNet : public definBase
void pathPoint(int x, int y, int ext);
void pathVia(const char* via);
void pathVia(const char* via, dbOrientType orient);
void pathRect(int deltaX1, int deltaY1, int deltaX2, int deltaY2);
void pathEnd();
void wireEnd();
void source(dbSourceType source);
@@ -115,11 +116,11 @@ class definNet : public definBase
definNet();
virtual ~definNet();
virtual void init() override;
void skipWires() { _skip_wires = true; }
void skipConnections() { _skip_signal_connections = true; }
void replaceWires() { _replace_wires = true; }
void setAssemblyMode() { _assembly_mode = true; }
void namesAreDBIDs() { _names_are_ids = true; }
void skipWires() { _skip_wires = true; }
void skipConnections() { _skip_signal_connections = true; }
void replaceWires() { _replace_wires = true; }
void setAssemblyMode() { _assembly_mode = true; }
void namesAreDBIDs() { _names_are_ids = true; }
};
} // namespace odb

View File

@@ -317,7 +317,7 @@ int definReader::blockageCallback(defrCallbackType_e /* unused: type */,
}
for (int i = 0; i < blockage->numPolygons(); ++i) {
defiPoints defPoints = blockage->getPolygon(i);
defiPoints defPoints = blockage->getPolygon(i);
std::vector<Point> points;
reader->translate(defPoints, points);
blockageR->blockageRoutingPolygon(points);
@@ -348,8 +348,8 @@ int definReader::blockageCallback(defrCallbackType_e /* unused: type */,
}
int definReader::componentsCallback(defrCallbackType_e /* unused: type */,
defiComponent* comp,
defiUserData data)
defiComponent* comp,
defiUserData data)
{
definReader* reader = (definReader*) data;
definComponent* componentR = reader->_componentR;
@@ -398,9 +398,9 @@ int definReader::componentsCallback(defrCallbackType_e /* unused: type */,
}
int definReader::componentMaskShiftCallback(
defrCallbackType_e /* unused: type */,
defiComponentMaskShiftLayer* /* unused: shiftLayers */,
defiUserData data)
defrCallbackType_e /* unused: type */,
defiComponentMaskShiftLayer* /* unused: shiftLayers */,
defiUserData data)
{
definReader* reader = (definReader*) data;
reader->error("COMPONENTMASKSHIFT is unsupported");
@@ -408,8 +408,8 @@ int definReader::componentMaskShiftCallback(
}
int definReader::dieAreaCallback(defrCallbackType_e /* unused: type */,
defiBox* box,
defiUserData data)
defiBox* box,
defiUserData data)
{
definReader* reader = (definReader*) data;
@@ -434,16 +434,16 @@ int definReader::dieAreaCallback(defrCallbackType_e /* unused: type */,
notice(0,
"warning: Polygon DIEAREA statement not supported. The bounding "
"box will be used instead\n");
int xmin = INT_MAX;
int ymin = INT_MAX;
int xmax = INT_MIN;
int ymax = INT_MIN;
int xmin = INT_MAX;
int ymin = INT_MAX;
int xmax = INT_MIN;
int ymax = INT_MIN;
std::vector<Point>::iterator itr;
for (itr = P.begin(); itr != P.end(); ++itr) {
Point& p = *itr;
int x = p.getX();
int y = p.getY();
int x = p.getX();
int y = p.getY();
if (x < xmin)
xmin = x;
@@ -466,8 +466,8 @@ int definReader::dieAreaCallback(defrCallbackType_e /* unused: type */,
}
int definReader::extensionCallback(defrCallbackType_e /* unused: type */,
const char* /* unused: extension */,
defiUserData data)
const char* /* unused: extension */,
defiUserData data)
{
definReader* reader = (definReader*) data;
reader->error("Syntax extensions (BEGINEXT/ENDEXT) are unsupported");
@@ -475,8 +475,8 @@ int definReader::extensionCallback(defrCallbackType_e /* unused: type */,
}
int definReader::fillsCallback(defrCallbackType_e /* unused: type */,
int /* unused: count */,
defiUserData data)
int /* unused: count */,
defiUserData data)
{
definReader* reader = (definReader*) data;
@@ -488,8 +488,8 @@ int definReader::fillsCallback(defrCallbackType_e /* unused: type */,
// This is incomplete but won't be reached because of the
// fillsCallback
int definReader::fillCallback(defrCallbackType_e /* unused: type */,
defiFill* fill,
defiUserData data)
defiFill* fill,
defiUserData data)
{
definReader* reader = (definReader*) data;
definFill* fillR = reader->_fillR;
@@ -506,7 +506,7 @@ int definReader::fillCallback(defrCallbackType_e /* unused: type */,
}
for (int i = 0; i < fill->numPolygons(); ++i) {
defiPoints defPoints = fill->getPolygon(i);
defiPoints defPoints = fill->getPolygon(i);
std::vector<Point> points;
reader->translate(defPoints, points);
@@ -519,8 +519,8 @@ int definReader::fillCallback(defrCallbackType_e /* unused: type */,
}
int definReader::gcellGridCallback(defrCallbackType_e /* unused: type */,
defiGcellGrid* grid,
defiUserData data)
defiGcellGrid* grid,
defiUserData data)
{
definReader* reader = (definReader*) data;
defDirection dir = (grid->macro()[0] == 'X') ? DEF_X : DEF_Y;
@@ -531,8 +531,8 @@ int definReader::gcellGridCallback(defrCallbackType_e /* unused: type */,
}
int definReader::groupNameCallback(defrCallbackType_e /* unused: type */,
const char* name,
defiUserData data)
const char* name,
defiUserData data)
{
definReader* reader = (definReader*) data;
reader->_regionR->begin(name, /* group */ true);
@@ -540,8 +540,8 @@ int definReader::groupNameCallback(defrCallbackType_e /* unused: type */,
}
int definReader::groupMemberCallback(defrCallbackType_e /* unused: type */,
const char* member,
defiUserData data)
const char* member,
defiUserData data)
{
definReader* reader = (definReader*) data;
reader->_regionR->inst(member);
@@ -549,8 +549,8 @@ int definReader::groupMemberCallback(defrCallbackType_e /* unused: type */,
}
int definReader::groupCallback(defrCallbackType_e /* unused: type */,
defiGroup* group,
defiUserData data)
defiGroup* group,
defiUserData data)
{
definReader* reader = (definReader*) data;
definRegion* regionR = reader->_regionR;
@@ -565,87 +565,17 @@ int definReader::groupCallback(defrCallbackType_e /* unused: type */,
}
int definReader::historyCallback(defrCallbackType_e /* unused: type */,
const char* /* unused: extension */,
defiUserData data)
const char* /* unused: extension */,
defiUserData data)
{
definReader* reader = (definReader*) data;
reader->error("HISTORY is unsupported");
return PARSE_ERROR;
}
// This is a ugly workaround. We handle precisely the case that a
// path consists of a single layer/point/rect sequence of min width
// and nothing more. This is all TritonRoute writes to DEF currently
// so that is all we support (used for min area violations). Anything
// else will generate a parser error.
static bool handleRectPath(defiPath* path, definNet* netR)
{
const char* layerName = nullptr;
bool hasPoint = false;
bool hasRect = false;
int x;
int y;
int deltaX1;
int deltaY1;
int deltaX2;
int deltaY2;
path->initTraverse();
int pathId;
while ((pathId = path->next()) != DEFIPATH_DONE) {
switch (pathId) {
case DEFIPATH_LAYER: {
layerName = path->getLayer();
break;
}
case DEFIPATH_POINT: {
if (hasPoint) {
return false;
}
hasPoint = true;
path->getPoint(&x, &y);
break;
}
case DEFIPATH_RECT: {
if (hasRect) {
return false;
}
hasRect = true;
path->getViaRect(&deltaX1, &deltaY1, &deltaX2, &deltaY2);
break;
}
default:
return false;
}
}
netR->path(layerName);
int minWidth = netR->getLayer()->getWidth();
int ext = minWidth / 2;
if (deltaX2 - deltaX1 == minWidth) { // vertical
if (-deltaX1 != deltaX2) { // must be centered on this point
return false;
}
netR->pathPoint(x, y + deltaY1 + ext);
netR->pathPoint(x, y + deltaY2 - ext);
} else if (deltaY2 - deltaY1 == minWidth) { // horizontal
if (-deltaY1 != deltaY2) { // must be centered on this point
return false;
}
netR->pathPoint(x + deltaX1 + ext, y);
netR->pathPoint(x + deltaX2 - ext, y);
} else {
return false;
}
netR->pathEnd();
return true;
}
int definReader::netCallback(defrCallbackType_e /* unused: type */,
defiNet* net,
defiUserData data)
defiNet* net,
defiUserData data)
{
definReader* reader = (definReader*) data;
definNet* netR = reader->_netR;
@@ -732,10 +662,6 @@ int definReader::netCallback(defrCallbackType_e /* unused: type */,
for (int j = 0; j < wire->numPaths(); ++j) {
defiPath* path = wire->path(j);
if (handleRectPath(path, netR)) {
continue;
}
path->initTraverse();
int pathId;
@@ -793,7 +719,12 @@ int definReader::netCallback(defrCallbackType_e /* unused: type */,
break;
case DEFIPATH_RECT: {
return PARSE_ERROR;
int deltaX1;
int deltaY1;
int deltaX2;
int deltaY2;
path->getViaRect(&deltaX1, &deltaY1, &deltaX2, &deltaY2);
netR->pathRect(deltaX1, deltaY1, deltaX2, deltaY2);
break;
}
@@ -825,8 +756,8 @@ int definReader::netCallback(defrCallbackType_e /* unused: type */,
}
int definReader::nonDefaultRuleCallback(defrCallbackType_e /* unused: type */,
defiNonDefault* rule,
defiUserData data)
defiNonDefault* rule,
defiUserData data)
{
definReader* reader = (definReader*) data;
definNonDefaultRule* ruleR = reader->_non_default_ruleR;
@@ -876,8 +807,8 @@ int definReader::nonDefaultRuleCallback(defrCallbackType_e /* unused: type */,
}
int definReader::pinCallback(defrCallbackType_e /* unused: type */,
defiPin* pin,
defiUserData data)
defiPin* pin,
defiUserData data)
{
definReader* reader = (definReader*) data;
definPin* pinR = reader->_pinR;
@@ -979,8 +910,8 @@ int definReader::pinCallback(defrCallbackType_e /* unused: type */,
}
int definReader::pinsEndCallback(defrCallbackType_e /* unused: type */,
void* /* unused: v */,
defiUserData data)
void* /* unused: v */,
defiUserData data)
{
definReader* reader = (definReader*) data;
reader->_pinR->pinsEnd();
@@ -988,8 +919,8 @@ int definReader::pinsEndCallback(defrCallbackType_e /* unused: type */,
}
int definReader::pinPropCallback(defrCallbackType_e /* unused: type */,
defiPinProp* prop,
defiUserData data)
defiPinProp* prop,
defiUserData data)
{
definReader* reader = (definReader*) data;
definPinProps* propR = reader->_pin_propsR;
@@ -1002,8 +933,8 @@ int definReader::pinPropCallback(defrCallbackType_e /* unused: type */,
}
int definReader::pinsStartCallback(defrCallbackType_e /* unused: type */,
int number,
defiUserData data)
int number,
defiUserData data)
{
definReader* reader = (definReader*) data;
reader->_pinR->pinsBegin(number);
@@ -1011,8 +942,8 @@ int definReader::pinsStartCallback(defrCallbackType_e /* unused: type */,
}
int definReader::propCallback(defrCallbackType_e /* unused: type */,
defiProp* prop,
defiUserData data)
defiProp* prop,
defiUserData data)
{
definReader* reader = (definReader*) data;
definPropDefs* prop_defsR = reader->_prop_defsR;
@@ -1078,8 +1009,8 @@ int definReader::propCallback(defrCallbackType_e /* unused: type */,
}
int definReader::propEndCallback(defrCallbackType_e /* unused: type */,
void* /* unused: v */,
defiUserData data)
void* /* unused: v */,
defiUserData data)
{
definReader* reader = (definReader*) data;
reader->_prop_defsR->endDefinitions();
@@ -1087,8 +1018,8 @@ int definReader::propEndCallback(defrCallbackType_e /* unused: type */,
}
int definReader::propStartCallback(defrCallbackType_e /* unused: type */,
void* /* unused: v */,
defiUserData data)
void* /* unused: v */,
defiUserData data)
{
definReader* reader = (definReader*) data;
reader->_prop_defsR->beginDefinitions();
@@ -1096,8 +1027,8 @@ int definReader::propStartCallback(defrCallbackType_e /* unused: type */,
}
int definReader::regionCallback(defrCallbackType_e /* unused: type */,
defiRegion* region,
defiUserData data)
defiRegion* region,
defiUserData data)
{
definReader* reader = (definReader*) data;
definRegion* regionR = reader->_regionR;
@@ -1127,8 +1058,8 @@ int definReader::regionCallback(defrCallbackType_e /* unused: type */,
}
int definReader::rowCallback(defrCallbackType_e /* unused: type */,
defiRow* row,
defiUserData data)
defiRow* row,
defiUserData data)
{
definReader* reader = (definReader*) data;
definRow* rowR = reader->_rowR;
@@ -1170,8 +1101,8 @@ int definReader::rowCallback(defrCallbackType_e /* unused: type */,
}
int definReader::scanchainsCallback(defrCallbackType_e /* unused: type */,
int /* unused: count */,
defiUserData data)
int /* unused: count */,
defiUserData data)
{
definReader* reader = (definReader*) data;
reader->error("SCANCHAINS are unsupported");
@@ -1179,8 +1110,8 @@ int definReader::scanchainsCallback(defrCallbackType_e /* unused: type */,
}
int definReader::slotsCallback(defrCallbackType_e /* unused: type */,
int /* unused: count */,
defiUserData data)
int /* unused: count */,
defiUserData data)
{
definReader* reader = (definReader*) data;
reader->error("SLOTS are unsupported");
@@ -1188,8 +1119,8 @@ int definReader::slotsCallback(defrCallbackType_e /* unused: type */,
}
int definReader::stylesCallback(defrCallbackType_e /* unused: type */,
int /* unused: count */,
defiUserData data)
int /* unused: count */,
defiUserData data)
{
definReader* reader = (definReader*) data;
reader->error("STYLES are unsupported");
@@ -1197,8 +1128,8 @@ int definReader::stylesCallback(defrCallbackType_e /* unused: type */,
}
int definReader::technologyCallback(defrCallbackType_e /* unused: type */,
const char* /* unused: name */,
defiUserData data)
const char* /* unused: name */,
defiUserData data)
{
definReader* reader = (definReader*) data;
reader->error("TECHNOLOGY is unsupported");
@@ -1206,8 +1137,8 @@ int definReader::technologyCallback(defrCallbackType_e /* unused: type */,
}
int definReader::trackCallback(defrCallbackType_e /* unused: type */,
defiTrack* track,
defiUserData data)
defiTrack* track,
defiUserData data)
{
definReader* reader = (definReader*) data;
@@ -1255,8 +1186,8 @@ int definReader::unitsCallback(defrCallbackType_e, double d, defiUserData data)
}
int definReader::viaCallback(defrCallbackType_e /* unused: type */,
defiVia* via,
defiUserData data)
defiVia* via,
defiUserData data)
{
definReader* reader = (definReader*) data;
definVia* viaR = reader->_viaR;
@@ -1350,8 +1281,8 @@ int definReader::viaCallback(defrCallbackType_e /* unused: type */,
}
int definReader::specialNetCallback(defrCallbackType_e /* unused: type */,
defiNet* net,
defiUserData data)
defiNet* net,
defiUserData data)
{
definReader* reader = (definReader*) data;
definSNet* snetR = reader->_snetR;

View File

@@ -896,7 +896,7 @@ void defout_impl::writeBTerm(dbBTerm* bterm)
const char* sig_type = defSigType(bterm->getSigType());
fprintf(_out, " + USE %s", sig_type);
fprintf(_out, " ;\n");
} else
notice(0,
@@ -1452,7 +1452,6 @@ void defout_impl::writeWire(dbWire* wire)
case dbWireDecoder::ITERM:
case dbWireDecoder::BTERM:
case dbWireDecoder::BTERM_MAP_ID:
break;
case dbWireDecoder::RULE: {
@@ -1471,6 +1470,24 @@ void defout_impl::writeWire(dbWire* wire)
break;
}
case dbWireDecoder::RECT: {
if ((++point_cnt & 7) == 0)
fprintf(_out, "\n ");
int deltaX1;
int deltaY1;
int deltaX2;
int deltaY2;
decode.getRect(deltaX1, deltaY1, deltaX2, deltaY2);
deltaX1 = defdist(deltaX1);
deltaY1 = defdist(deltaY1);
deltaX2 = defdist(deltaX2);
deltaY2 = defdist(deltaY2);
fprintf(
_out, " RECT ( %d %d %d %d ) ", deltaX1, deltaY1, deltaX2, deltaY2);
break;
}
case dbWireDecoder::END_DECODE:
return;
}