mirror of
https://github.com/The-OpenROAD-Project/OpenDB.git
synced 2026-03-06 17:31:17 +08:00
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:
@@ -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; }
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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())) {
|
||||
|
||||
@@ -424,7 +424,8 @@ void dbWireGraph::decode(dbWire* wire)
|
||||
break;
|
||||
}
|
||||
|
||||
case dbWireDecoder::BTERM_MAP_ID:
|
||||
case dbWireDecoder::RECT:
|
||||
// ignored
|
||||
break;
|
||||
|
||||
case dbWireDecoder::RULE: {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user