NeRo is now able to route a full chip.

Plus some goodies for Graham Petley.
This commit is contained in:
Jean-Paul Chaput 2005-10-10 15:34:06 +00:00
parent 7b7fb1015a
commit 2806047b85
13 changed files with 442 additions and 183 deletions

View File

@ -2,7 +2,7 @@ dnl Process this file with autoconf to produce a configure script.
AC_INIT(src/nero.cpp)
NERO_MAJOR_VERSION=1
NERO_MINOR_VERSION=0
NERO_MINOR_VERSION=1
NERO_VERSION=$NERO_MAJOR_VERSION.$NERO_MINOR_VERSION
AC_SUBST(NERO_MAJOR_VERSION)
@ -21,6 +21,7 @@ AC_PROG_CXX
AC_PROG_CC
AM_PROG_LIBTOOL
AC_PROG_MAKE_SET
AM_WITH_REGEX
ALC_CXX_PROBLEMATIC_OLD_VERSION
AC_CHECK_LIB(m, pow)

View File

@ -1,7 +1,7 @@
// -*- C++ -*-
//
// $Id: ASimple.cpp,v 1.3 2004/12/14 19:02:07 jpc Exp $
// $Id: ASimple.cpp,v 1.4 2005/10/10 15:34:05 jpc Exp $
//
// /----------------------------------------------------------------\
// | |
@ -38,8 +38,11 @@ void CASimple::CQueue::load (MNet *nets, bool rglobal, bool global)
MNet::iterator itNet, endNet;
endNet = nets->end();
endNet = nets->end();
for (itNet = nets->begin(); itNet != endNet; itNet++) {
// Already routed signal.
if ( itNet->second->fixed ) continue;
// Global routing stage.
if ( global && (itNet->second->global(rglobal)) )
push (itNet->second);
@ -56,11 +59,12 @@ void CASimple::CQueue::load (MNet *nets, bool rglobal, bool global)
// -------------------------------------------------------------------
// Constructor : "CASimple::CASimple()".
CASimple::CASimple (MNet *mNets, CDRGrid *drgrid) : _astar(drgrid, this)
CASimple::CASimple (MNet *mNets, CDRGrid *drgrid)
: _astar(drgrid, this)
, nets(mNets)
, iterations_route(0)
, iterations_reroute(0)
{
nets = mNets;
iterations_route = 0;
iterations_reroute = 0;
}

View File

@ -1,7 +1,7 @@
// -*- C++ -*-
//
// $Id: MDRGrid.cpp,v 1.5 2005/02/17 15:34:44 jpc Exp $
// $Id: MDRGrid.cpp,v 1.6 2005/10/10 15:34:05 jpc Exp $
//
// /----------------------------------------------------------------\
// | |
@ -324,22 +324,20 @@ int CDRGrid::iterator::manhattan (iterator &other)
// -------------------------------------------------------------------
// Constructor : "CDRGrid::CDRGrid()".
CDRGrid::CDRGrid (int x, int y, int z, int zup) throw (e_zupper)
CDRGrid::CDRGrid (int xoff, int yoff, int x, int y, int z, int zup)
throw (e_zupper)
: xoffset(xoff)
, yoffset(yoff)
, X(x)
, Y(y)
, Z(z)
, XY(X*Y)
, XYZ(XY*Z)
, size(XY*(Z-1))
, zupper(zup)
{
int index;
X = x;
Y = y;
Z = z;
XY = X * Y;
XYZ = XY * Z;
size = XY * (Z - 1);
zupper = zup;
if (zupper < 4) throw e_zupper (zupper);
nodes = new CMatrixNodes (this);
pri = new CMatrixPri (this);

View File

@ -1,7 +1,7 @@
// -*- C++ -*-
//
// $Id: MDefs.h,v 1.7 2004/12/14 19:02:07 jpc Exp $
// $Id: MDefs.h,v 1.8 2005/10/10 15:34:05 jpc Exp $
//
// /-----------------------------------------------------------------\
// | |
@ -298,6 +298,8 @@
// Matrix class ----------------------------------------------
// Attributes.
public: int xoffset;
public: int yoffset;
public: int X;
public: int Y;
public: int Z;
@ -316,13 +318,13 @@
public: CMatrixNodes *nodes;
// Constructor.
public: CDRGrid (int x, int y, int z, int zup) throw (e_zupper);
public: CDRGrid (int xoff, int yoff, int x, int y, int z, int zup) throw (e_zupper);
// Destructor.
public: ~CDRGrid (void);
// Modifiers.
public: void costs (int x_hor, int x_ver, int y_hor, int y_ver, int z);
public: void costs (int x_hor, int x_ver, int y_hor, int y_ver, int z);
// Utilities.
public: int x (int index) { return ( index % X); }
@ -673,6 +675,7 @@
public: CBB bb;
public: int size;
public: bool external;
public: bool fixed;
public: CDRGrid *_drgrid;
// Constructor.

View File

@ -1,7 +1,7 @@
// -*- C++ -*-
//
// $Id: MMBK.cpp,v 1.5 2005/04/07 14:56:18 jpc Exp $
// $Id: MMBK.cpp,v 1.6 2005/10/10 15:34:05 jpc Exp $
//
// /-----------------------------------------------------------------\
// | |
@ -48,11 +48,8 @@ namespace MBK {
// -------------------------------------------------------------------
// Constructor : "CXRect::CXRect()".
CXRect::CXRect (long xab1, long yab1)
{
XAB1 = xab1;
YAB1 = yab1;
}
CXRect::CXRect ( CDRGrid* agrid ) : drgrid(agrid)
{ }
@ -125,14 +122,37 @@ void CXRect::seg2rect (void)
void CXRect::rect2grid (void)
{
grid.x1 = (rect.x1 - XAB1) / env.grid_dx;
grid.y1 = (rect.y1 - YAB1) / env.grid_dy;
grid.x1 = (rect.x1 - drgrid->xoffset) / env.grid_dx;
grid.y1 = (rect.y1 - drgrid->yoffset) / env.grid_dy;
grid.x2 = (rect.x2 - XAB1) / env.grid_dx;
grid.y2 = (rect.y2 - YAB1) / env.grid_dy;
grid.x2 = (rect.x2 - drgrid->xoffset) / env.grid_dx;
grid.y2 = (rect.y2 - drgrid->yoffset) / env.grid_dy;
if (((rect.x2 - XAB1) % env.grid_dx) != 0) grid.x2 += 1;
if (((rect.y2 - XAB1) % env.grid_dy) != 0) grid.y2 += 1;
if (((rect.x2 - drgrid->xoffset) % env.grid_dx) != 0) grid.x2 += 1;
if (((rect.y2 - drgrid->yoffset) % env.grid_dy) != 0) grid.y2 += 1;
if ( (grid.x2 < 0) || (grid.x1 >= drgrid->X)
|| (grid.y2 < 0) || (grid.y1 >= drgrid->Y) ) {
grid.x1 = -1;
} else {
if (grid.x1 < 0 ) grid.x1 = 0;
if (grid.y1 < 0 ) grid.y1 = 0;
if (grid.x2 > drgrid->X-1) grid.x2 = drgrid->X - 1;
if (grid.y2 > drgrid->Y-1) grid.y2 = drgrid->Y - 1;
}
}
// -------------------------------------------------------------------
// Method : "CXRect::isInGrid()".
bool CXRect::isInGrid ()
{
if (grid.x1 < 0) return false;
return true;
}
@ -230,6 +250,8 @@ CEnv::CEnv (void)
ALU2Z[TALU5] = 4;
ALU2Z[TALU6] = 5;
ALU2Z[TALU7] = 6;
regcomp(&pxLibRegex,"p.*px",REG_EXTENDED|REG_NOSUB);
}
@ -538,15 +560,15 @@ void CPhfig::rflatten (char concat, char catal)
// -------------------------------------------------------------------
// Method : "CPhfig::onslice()".
bool CPhfig::onslice (long Y)
bool CPhfig::onslice (long Y, long yoff)
{
if (Y < fig->YAB1) return (false);
if (Y > fig->YAB2) return (false);
if (!(((Y - D::WIDTH_VDD / 2) - fig->YAB1) % D::Y_SLICE)) return (true);
if (!(((Y + D::WIDTH_VDD / 2) - fig->YAB1) % D::Y_SLICE)) return (true);
if (!(((Y - D::WIDTH_VSS / 2) - fig->YAB1) % D::Y_SLICE)) return (true);
if (!(((Y + D::WIDTH_VSS / 2) - fig->YAB1) % D::Y_SLICE)) return (true);
if (!(((Y - D::WIDTH_VDD / 2) - yoff ) % D::Y_SLICE)) return (true);
if (!(((Y + D::WIDTH_VDD / 2) - yoff ) % D::Y_SLICE)) return (true);
if (!(((Y - D::WIDTH_VSS / 2) - yoff ) % D::Y_SLICE)) return (true);
if (!(((Y + D::WIDTH_VSS / 2) - yoff ) % D::Y_SLICE)) return (true);
return (false);
}
@ -770,19 +792,21 @@ CFig::~CFig (void)
// -------------------------------------------------------------------
// Method : "CFig::addphseg()".
void CFig::addphseg (phseg_list &seg, bool isTerm )
void CFig::addphseg (phseg_list &seg, bool isTerm, bool isChip )
{
MBK::addphseg ( phfig.fig
, seg.LAYER
, seg.WIDTH
, seg.X1
, seg.Y1
, seg.X2
, seg.Y2
, seg.NAME
);
if ( !isChip || !isobs(seg.LAYER) ) {
MBK::addphseg ( phfig.fig
, seg.LAYER
, seg.WIDTH
, seg.X1
, seg.Y1
, seg.X2
, seg.Y2
, seg.NAME
);
}
if ( !isTerm ) {
if ( !isTerm && !isChip ) {
MBK::addphseg ( phfig.fig
, layer2TALU(seg.LAYER)
, seg.WIDTH
@ -1166,13 +1190,20 @@ long cmpALU (char layer1, char layer2)
char topVIALayer (char type)
{
switch (type) {
case CONT_VIA: return (ALU1); break;
case CONT_VIA2: return (ALU2); break;
case CONT_VIA3: return (ALU3); break;
case CONT_VIA4: return (ALU4); break;
case CONT_VIA5: return (ALU5); break;
case CONT_VIA6: return (ALU6); break;
case CONT_VIA7: return (ALU7); break;
case CONT_VIA: return (ALU1); break;
case CONT_VIA2: return (ALU2); break;
case CONT_VIA3: return (ALU3); break;
case CONT_VIA4: return (ALU4); break;
case CONT_VIA5: return (ALU5); break;
case CONT_VIA6: return (ALU6); break;
case CONT_VIA7: return (ALU7); break;
case CONT_TURN1: return (ALU1); break;
case CONT_TURN2: return (ALU2); break;
case CONT_TURN3: return (ALU3); break;
case CONT_TURN4: return (ALU4); break;
case CONT_TURN5: return (ALU5); break;
case CONT_TURN6: return (ALU6); break;
case CONT_TURN7: return (ALU7); break;
}
return (ALU8);
@ -1188,13 +1219,20 @@ char topVIALayer (char type)
char bottomVIALayer (char type)
{
switch (type) {
case CONT_VIA: return (ALU2); break;
case CONT_VIA2: return (ALU3); break;
case CONT_VIA3: return (ALU4); break;
case CONT_VIA4: return (ALU5); break;
case CONT_VIA5: return (ALU6); break;
case CONT_VIA6: return (ALU7); break;
case CONT_VIA7: return (ALU8); break;
case CONT_VIA: return (ALU2); break;
case CONT_VIA2: return (ALU3); break;
case CONT_VIA3: return (ALU4); break;
case CONT_VIA4: return (ALU5); break;
case CONT_VIA5: return (ALU6); break;
case CONT_VIA6: return (ALU7); break;
case CONT_VIA7: return (ALU8); break;
case CONT_TURN1: return (ALU1); break;
case CONT_TURN2: return (ALU2); break;
case CONT_TURN3: return (ALU3); break;
case CONT_TURN4: return (ALU4); break;
case CONT_TURN5: return (ALU5); break;
case CONT_TURN6: return (ALU6); break;
case CONT_TURN7: return (ALU7); break;
}
return (ALU9);
@ -1203,6 +1241,17 @@ char bottomVIALayer (char type)
// -------------------------------------------------------------------
// Function : "isPxLib()".
bool IsPxLib ( phfig_list* model )
{
return regexec(&env.pxLibRegex,model->NAME,0,NULL,0) == 0;
}
// -------------------------------------------------------------------
// End of MBK namespace.

View File

@ -1,7 +1,7 @@
// -*- C++ -*-
//
// $Id: MMBK.h,v 1.3 2005/04/07 14:56:18 jpc Exp $
// $Id: MMBK.h,v 1.4 2005/10/10 15:34:05 jpc Exp $
//
// /-----------------------------------------------------------------\
// | |
@ -24,6 +24,8 @@
#define __UMBK__ 1
# include <regex.h>
// -------------------------------------------------------------------
// MBK namespace.
@ -106,14 +108,16 @@ namespace MBK {
class CXRect {
// Attributes.
public: long XAB1; // MBK coordinates origin;
public: long YAB1;
public: phseg_list seg; // MBK segment.
public: CRect rect; // Rectangle (MBK coordinates).
public: CRect grid; // Rectangle (routing grid units).
public: CDRGrid* drgrid; // Associated grid, to check limits.
public: phseg_list seg; // MBK segment.
public: CRect rect; // Rectangle (MBK coordinates).
public: CRect grid; // Rectangle (routing grid units).
// Contructor.
public: CXRect (long xab1, long yab1);
public: CXRect (CDRGrid* agrid);
// Predicate.
public: bool isInGrid ();
// Modifiers.
public: void setSeg (phseg_list &rSeg);
@ -134,10 +138,11 @@ namespace MBK {
struct CEnv {
// Attributes.
long grid_dx;
long grid_dy;
MLayer ALU2W;
MLayer ALU2Z;
long grid_dx;
long grid_dy;
MLayer ALU2W;
MLayer ALU2Z;
regex_t pxLibRegex;
// Constructor.
CEnv (void);
@ -202,7 +207,7 @@ namespace MBK {
// Modifiers.
void rflatten (char concat=YES, char catal=YES);
bool onslice (long Y);
bool onslice (long Y, long xoff);
void save (void);
void saveas (string &name);
@ -268,7 +273,7 @@ namespace MBK {
losig_list *LOSIG (void) { return (lofig.fig->LOSIG); }
// Modifiers.
void addphseg (phseg_list &seg, bool isTerm=false );
void addphseg (phseg_list &seg, bool isTerm=false, bool isChip=false );
void addphvia (phvia_list &VIA);
void addphcon (phcon_list &con);
@ -276,6 +281,14 @@ namespace MBK {
// ---------------------------------------------------------------
// MBK level Utilities functions.
bool IsPxLib ( phfig_list* model );
// ---------------------------------------------------------------
// Pre-defined objects.
@ -329,6 +342,8 @@ namespace MBK {
struct CPowers {
// Attributes.
long xoffset;
long yoffset;
char type;
char layer;
long width;
@ -337,7 +352,7 @@ namespace MBK {
LPower powerLines;
// Constructor.
CPowers (CFig*, char, int, long) throw (except_done);
CPowers (CFig*, long xoff, long yoff, char, int, long) throw (except_done);
// Methods.
void dump (CFig *fig);

View File

@ -1,7 +1,7 @@
// -*- C++ -*-
//
// $Id: MNet.cpp,v 1.8 2005/02/17 14:47:27 jpc Exp $
// $Id: MNet.cpp,v 1.9 2005/10/10 15:34:05 jpc Exp $
//
// /----------------------------------------------------------------\
// | |
@ -391,13 +391,16 @@ ostream &operator<< (ostream &o, CTerm &self)
// Constructor : "CNet::CNet()".
CNet::CNet (CDRGrid *drgrid, string netName)
: pri(0)
, name(netName)
, terms()
, rtree(NULL)
, bb()
, size(0)
, external(false)
, fixed(false)
, _drgrid(drgrid)
{
name = netName;
external = false;
pri = 0;
size = 0;
rtree = NULL;
_drgrid = drgrid;
}

View File

@ -1,7 +1,7 @@
// -*- C++ -*-
//
// $Id: MPower.cpp,v 1.3 2005/04/07 14:56:18 jpc Exp $
// $Id: MPower.cpp,v 1.4 2005/10/10 15:34:05 jpc Exp $
//
// /-----------------------------------------------------------------\
// | |
@ -70,10 +70,14 @@ ostream &operator<< (ostream &o, CPower &self)
// Constructor : "CPowers::CPowers ()".
CPowers::CPowers ( CFig *fig
, long xoff
, long yoff
, char atype
, int alayer
, long awidth
) throw (except_done)
: xoffset(xoff)
, yoffset(yoff)
{
LPower::iterator itLine, beginLine, endLine;
phins_list *ins;
@ -178,7 +182,7 @@ CPowers::CPowers ( CFig *fig
}
if ( (cmpALU (alayer, CALU1) & F_CALU)
&& !fig->phfig.onslice (flatSeg.Y1)) {
&& !fig->phfig.onslice (flatSeg.Y1,yoffset)) {
cerr << hwarn ("");
cerr << " " << layer2a (layer) << " \"" << seg->NAME
<<"\" segment at ("

View File

@ -1,7 +1,7 @@
// -*- C++ -*-
//
// $Id: RBox.cpp,v 1.3 2002/11/04 14:43:08 jpc Exp $
// $Id: RBox.cpp,v 1.4 2005/10/10 15:34:06 jpc Exp $
//
// /----------------------------------------------------------------\
// | |
@ -83,7 +83,7 @@ CRBox::CRBox (int rtype, bool debug)
// Creating routing matrix.
cdebug << " Routing matrix size := (10, 15, 5)\n";
drgrid = new CDRGrid (X, Y, Z, 4);
drgrid = new CDRGrid (0, 0, X, Y, Z, 4);
// Adding signal "sig_one".

View File

@ -1,7 +1,7 @@
// -*- C++ -*-
//
// $Id: RDefs.h,v 1.3 2002/11/04 14:43:08 jpc Exp $
// $Id: RDefs.h,v 1.4 2005/10/10 15:34:06 jpc Exp $
//
// /-----------------------------------------------------------------\
// | |
@ -41,10 +41,13 @@
// Attributes.
public: CASimple *netsched;
public: CDRGrid *drgrid;
public: long xoffsetgrid;
public: long yoffsetgrid;
public: MNet nets;
public: bool loaded;
public: bool insave;
public: bool rglobal;
public: bool ischip;
// MBK dedicated Attributes.
public: MBK::CFig *fig;
@ -62,7 +65,12 @@
public: CNet *findnet (char *signame);
public: CNet *getnet (string &signame);
public: CNet *getnet (char *signame);
public: void mbkload (MBK::CFig *mbkfig, int z, int zup, int rtype);
public: void mbkload (MBK::CFig *mbkfig
, int z
, int zup
, int rtype
, bool halfpitch
, bool rotate );
public: void mbksave (string &name) throw (except_done);
public: void route (void);

View File

@ -1,7 +1,7 @@
// -*- C++ -*-
//
// $Id: RMBK.cpp,v 1.9 2005/04/08 10:15:45 jpc Exp $
// $Id: RMBK.cpp,v 1.10 2005/10/10 15:34:06 jpc Exp $
//
// /----------------------------------------------------------------\
// | |
@ -33,12 +33,20 @@
// -------------------------------------------------------------------
// Modifier : "CRBox::mbkload()".
void CRBox::mbkload (MBK::CFig *mbkfig, int z, int zup, int rtype)
void CRBox::mbkload (MBK::CFig *mbkfig
, int z
, int zup
, int rtype
, bool halfpitch
, bool rotate )
{
MBK::MIns::iterator itIns, endInstances, endOrphans;
MBK::MLosig::iterator endSig;
long mX, mY, mZ, x, y, zz;
long mX, mY, mZ, x, y, zz, xadjust, yadjust, yoffsetslice;
long XRW1, YRW1, XRW2, YRW2;
bool use_global;
long northPad, southPad, eastPad, westPad;
long xoffsettrack, yoffsettrack;
MBK::chain_list *pChain;
MBK::locon_list *pLocon;
MBK::phcon_list *pPhcon;
@ -48,6 +56,7 @@ void CRBox::mbkload (MBK::CFig *mbkfig, int z, int zup, int rtype)
MBK::phfig_list *pModel;
MBK::CXRect *rect;
MBK::CIns *pIns;
MNet routeds;
CNet *pNet;
string sig_name, term_name, ins_name;
CDRGrid::iterator coord;
@ -57,15 +66,126 @@ void CRBox::mbkload (MBK::CFig *mbkfig, int z, int zup, int rtype)
cmess1 << "\n";
cmess1 << " o Loading design into grid...\n";
fig = mbkfig;
ischip = false;
fig = mbkfig;
endInstances = fig->instances.end ();
endOrphans = fig->orphans.end ();
endSig = fig->lofig.signals.end ();
northPad = 0;
southPad = 0;
westPad = 0;
eastPad = 0;
xoffsettrack = 0;
yoffsettrack = 0;
// Half pitch offset.
if ( halfpitch ) {
xoffsettrack = D::X_GRID / 2;
yoffsettrack = D::Y_GRID / 2;
}
// Search for pads.
for (itIns = fig->instances.begin(); itIns != endInstances; itIns++) {
pModel = itIns->second->getmodel ();
if ( MBK::IsPxLib(pModel) ) {
switch ( itIns->second->phins->TRANSF ) {
case NOSYM:
ischip = true;
if ( northPad == 0 ) {
cmess2 << " o North pad found.\n";
northPad = pModel->YAB2 - pModel->YAB1 - MBK::SCALE(15);
}
break;
case SYM_Y:
ischip = true;
if ( southPad == 0 ) {
cmess2 << " o South pad found.\n";
southPad = pModel->YAB2 - pModel->YAB1 - MBK::SCALE(15);
}
break;
case ROT_P:
ischip = true;
if ( eastPad == 0 ) {
cmess2 << " o East pad found.\n";
eastPad = pModel->XAB2 - pModel->XAB1 - MBK::SCALE(15);
}
break;
case SY_RP:
ischip = true;
if ( westPad == 0 ) {
cmess2 << " o West pad found.\n";
westPad = pModel->XAB2 - pModel->XAB1 - MBK::SCALE(15);
}
break;
default:
cerr << hwarn ("")
<< " Pad " << itIns->second->phins->INSNAME
<< " have an invalid orientation.\n";
break;
}
}
}
//southPad = northPad = westPad = eastPad = MBK::SCALE(50);
//westPad = MBK::SCALE(100);
// Default Routing Widow size : the AB.
XRW1 = fig->XAB1 () + westPad;
YRW1 = fig->YAB1 () + southPad;
XRW2 = fig->XAB2 () - eastPad;
YRW2 = fig->YAB2 () - northPad;
// Find the a seed cell (one either from sxlib or dp_sxlib to
// track adjust the grid).
for (itIns = fig->instances.begin(); ; itIns++) {
if (itIns == endInstances) {
xadjust = xoffsettrack;
yadjust = yoffsettrack;
yoffsetslice = 0;
cout << hwarn ("")
<< " Unable to found a seed cell (i.e. belonging to either\n"
<< " sxlib or dp_sxlib) grid could be misplaced.\n";
break;
}
pModel = itIns->second->getmodel ();
if ( !MBK::IsPxLib(pModel) ) {
cmess2 << " o Using seed cell \"" << itIns->first
<< "\" (model \"" << pModel->NAME << "\").\n";
xadjust = abs((itIns->second->phins->XINS - XRW1) % D::X_GRID ) + xoffsettrack;
yadjust = abs((itIns->second->phins->YINS - YRW1) % D::Y_GRID ) + yoffsettrack;
yoffsetslice = abs((itIns->second->phins->YINS - YRW1) % D::Y_SLICE) + YRW1;
break;
}
}
xoffsetgrid = XRW1 + xadjust;
yoffsetgrid = YRW1 + yadjust;
cmess2 << " o Grid offset : ("
<< MBK::UNSCALE(xoffsetgrid) << ","
<< MBK::UNSCALE(yoffsetgrid) << ")"
<< " [adjust ("
<< MBK::UNSCALE(xadjust) << ","
<< MBK::UNSCALE(yadjust) << ")]\n";
// Compute the routing grid size.
mX = (fig->XAB2 () - fig->XAB1 ()) / D::X_GRID + 1;
mY = (fig->YAB2 () - fig->YAB1 ()) / D::Y_GRID + 1;
mX = (XRW2 - XRW1) / D::X_GRID + ((xadjust==0)?1:0);
mY = (YRW2 - YRW1) / D::Y_GRID + ((yadjust==0)?1:0);
mZ = z;
// Is the design a complete chip.
if (ischip)
cmess2 << " o Design have pads, treated as a complete chip.\n";
// Selecting the whether to use global routing.
use_global = (mX + mY) > (2 * D::GLOBAL_HP);
if (rtype == D::ROUTING_CHOOSE) {
@ -105,10 +225,10 @@ void CRBox::mbkload (MBK::CFig *mbkfig, int z, int zup, int rtype)
<< mX << "," << mY << "," << mZ << "].\n";
// Allocating the routing grid.
drgrid = new CDRGrid (mX, mY, mZ, zup);
drgrid = new CDRGrid (xoffsetgrid, yoffsetgrid, mX, mY, mZ, zup);
rect = new MBK::CXRect (fig->XAB1(), fig->YAB1());
rect = new MBK::CXRect (drgrid);
cmess2 << " o Loading external terminals.\n";
@ -141,10 +261,19 @@ void CRBox::mbkload (MBK::CFig *mbkfig, int z, int zup, int rtype)
rect->setSeg (flatSeg);
pNet->newaccess ( term_name
, rect->grid
, MBK::env.layer2z (pPhcon->LAYER)
);
if ( rect->isInGrid() ) {
pNet->newaccess ( term_name
, rect->grid
, MBK::env.layer2z (pPhcon->LAYER)
);
} else {
cerr << hwarn ("")
<< " The terminal \"" << pPhcon->NAME << "\" at ("
<< MBK::UNSCALE (pPhcon->XCON) << ","
<< MBK::UNSCALE (pPhcon->YCON) << ") layer "
<< MBK::layer2a (pPhcon->LAYER) << "\n"
<< " is outside the routing grid : ignored.\n";
}
}
@ -152,11 +281,6 @@ void CRBox::mbkload (MBK::CFig *mbkfig, int z, int zup, int rtype)
cmess2 << " o Finding obstacles.\n";
endInstances = fig->instances.end ();
endOrphans = fig->orphans.end ();
endSig = fig->lofig.signals.end ();
// Browse father for obstacles (powers are obstacles) and already
// routed or partially routed signals.
for (pSeg = fig->phfig.fig->PHSEG; pSeg != NULL; pSeg = pSeg->NEXT) {
@ -203,16 +327,33 @@ void CRBox::mbkload (MBK::CFig *mbkfig, int z, int zup, int rtype)
}
pNet = getnet (pSeg->NAME);
if ( !pNet->fixed ) {
cmess2 << " o Signal " << pNet->name << " is assumed to be routed.\n";
pNet->fixed = true;
}
rect->setSeg (*pSeg);
pNet->newaccess ( pSeg->NAME
, rect->grid
, MBK::env.layer2z (pSeg->LAYER)
);
if ( rect->isInGrid() ) {
//pNet->newaccess ( pSeg->NAME
// , rect->grid
// , MBK::env.layer2z (pSeg->LAYER)
// );
drgrid->nodes->obstacle (rect->grid, MBK::env.layer2z (pSeg->LAYER));
} else {
cerr << hwarn ("")
<< " The segment \"" << pSeg->NAME << "\" at ("
<< MBK::UNSCALE (pSeg->X1) << ","
<< MBK::UNSCALE (pSeg->Y1) << ") ("
<< MBK::UNSCALE (pSeg->X2) << ","
<< MBK::UNSCALE (pSeg->Y2) << ") layer "
<< MBK::layer2a (pSeg->LAYER) << "\n"
<< " is outside the routing grid : ignored.";
}
}
cerr << "VIAs" << endl;
// Browse for obstacle VIAs.
for (pVIA = fig->phfig.fig->PHVIA; pVIA != NULL; pVIA = pVIA->NEXT) {
// Only power VIAs must be obstacles.
@ -236,6 +377,8 @@ void CRBox::mbkload (MBK::CFig *mbkfig, int z, int zup, int rtype)
flatSeg.Y2 = pVIA->YVIA;
flatSeg.WIDTH = pVIA->DY;
cerr << pVIA->XVIA << " " << pVIA->YVIA << " " << (int)flatSeg.LAYER << endl;
rect->setSeg (flatSeg);
//cerr << "+ Top VIA obstacle (" << pVIA->XVIA << "," << pVIA->YVIA << ")" << endl;
@ -243,6 +386,7 @@ void CRBox::mbkload (MBK::CFig *mbkfig, int z, int zup, int rtype)
}
cerr << "Instances" << endl;
// Browse instances & orphans for obstacles.
for (itIns = fig->instances.begin(); ; itIns++) {
if (itIns == endInstances) itIns = fig->orphans.begin ();
@ -269,7 +413,7 @@ void CRBox::mbkload (MBK::CFig *mbkfig, int z, int zup, int rtype)
drgrid->nodes->obstacle (rect->grid, MBK::env.layer2z (pSeg->LAYER));
if ( !MBK::ISVDD (pSeg->NAME) && !MBK::ISVSS (pSeg->NAME) )
fig->addphseg ( flatSeg, true );
fig->addphseg ( flatSeg, true, ischip );
}
}
}
@ -326,10 +470,25 @@ void CRBox::mbkload (MBK::CFig *mbkfig, int z, int zup, int rtype)
pIns->flatseg (flatSeg, *pSeg);
rect->setSeg (flatSeg);
pNet->newaccess ( term_name
, rect->grid
, MBK::env.layer2z (pSeg->LAYER)
);
if (rect->isInGrid()) {
if ( pNet->fixed ) {
drgrid->nodes->obstacle (rect->grid, MBK::env.layer2z (pSeg->LAYER));
} else {
pNet->newaccess ( term_name
, rect->grid
, MBK::env.layer2z (pSeg->LAYER)
);
}
} else {
cerr << hwarn ("")
<< " The connector segment \"" << pSeg->NAME << "\" at ("
<< MBK::UNSCALE (pSeg->X1) << ","
<< MBK::UNSCALE (pSeg->Y1) << ") ("
<< MBK::UNSCALE (pSeg->X2) << ","
<< MBK::UNSCALE (pSeg->Y2) << ") layer "
<< MBK::layer2a (pSeg->LAYER) << "\n"
<< " is outside of the grid : ignored.";
}
}
} // End of "pChain" (terminal) loop.
@ -347,12 +506,16 @@ void CRBox::mbkload (MBK::CFig *mbkfig, int z, int zup, int rtype)
// Rebuild the power grid from the instances.
cmess2 << " o Reading power grid.\n";
powers[MBK::CALU1] = new MBK::CPowers ( fig
, C_HORIZONTAL
, MBK::ALU1
, D::WIDTH_VDD
);
if ( !ischip ) {
cmess2 << " o Reading power grid.\n";
powers[MBK::CALU1] = new MBK::CPowers ( fig
, xadjust - xoffsettrack
, yoffsetslice
, C_HORIZONTAL
, MBK::ALU1
, D::WIDTH_VDD
);
}
// Forbid the use of the edges of the routing box (only allow
@ -360,30 +523,34 @@ void CRBox::mbkload (MBK::CFig *mbkfig, int z, int zup, int rtype)
coord = drgrid->origin;
// Left & Right vertical edges.
for (x = 0; x < mX; x += mX - 1) {
for (y = 0; y < mY; y++) {
for (zz = 1; zz < mZ; zz++) {
node = &( coord.set(x,y,zz).node() );
if ( !node->terminal() ) node->data.obstacle = true;
if ( xadjust == 0 ) {
for (x = 0; x < mX; x += mX - 1) {
for (y = 0; y < mY; y++) {
for (zz = 1; zz < mZ; zz++) {
node = &( coord.set(x,y,zz).node() );
if ( !node->terminal() ) node->data.obstacle = true;
}
}
}
}
// Bottom & top horizontal edges.
for (y = 0; y < mY; y += mY - 1) {
for (x = 0; x < mX; x++) {
for (zz = 1; zz < mZ; zz++) {
node = &( coord.set(x,y,zz).node() );
if ( !node->terminal() ) node->data.obstacle = true;
if ( xadjust == 0 ) {
for (y = 0; y < mY; y += mY - 1) {
for (x = 0; x < mX; x++) {
for (zz = 1; zz < mZ; zz++) {
node = &( coord.set(x,y,zz).node() );
if ( !node->terminal() ) node->data.obstacle = true;
}
}
}
}
// On routing level above zupper (ALU4), use only half of the tracks.
for (zz = zup; zz < mZ; zz++) {
switch (zz % 2) {
switch ((zz+rotate) % 2) {
case 0:
// Vertical tracks.
for (x = 2; x < mX; x += 2) {
@ -471,11 +638,11 @@ void CRBox::mbkload (MBK::CFig *mbkfig, int z, int zup, int rtype)
// Dump the current one.
if (seg.X1 < seg.X2) {
// This is not a "dot" segment (i.e a VIA).
fig->addphseg (seg,pNet->external);
fig->addphseg (seg,pNet->external,ischip);
} else if (z % 2) {
char layer = seg.LAYER;
seg.LAYER = MBK::layer2TALU (seg.LAYER);
fig->addphseg (seg,false);
fig->addphseg (seg,false,ischip);
seg.LAYER = layer;
}
@ -490,28 +657,28 @@ void CRBox::mbkload (MBK::CFig *mbkfig, int z, int zup, int rtype)
// We encounter the left edge of a segment.
inseg = true;
seg.X1 = fig->XAB1() + x * D::X_GRID;
seg.Y1 = fig->YAB1() + y * D::Y_GRID;
seg.Y2 = fig->YAB1() + y * D::Y_GRID;
seg.X1 = xoffsetgrid + x * D::X_GRID;
seg.Y1 = yoffsetgrid + y * D::Y_GRID;
seg.Y2 = yoffsetgrid + y * D::Y_GRID;
seg.NAME = MBK::namealloc(pNet->name.c_str ());
seg.WIDTH = MBK::env.z2width (z);
if (pNet->external) seg.LAYER = MBK::env.z2calu (z);
else seg.LAYER = MBK::env.z2alu (z);
if (pNet->external && !ischip) seg.LAYER = MBK::env.z2calu (z);
else seg.LAYER = MBK::env.z2alu (z);
}
// Update the right edge.
seg.X2 = fig->XAB1() + x * D::X_GRID;
seg.X2 = xoffsetgrid + x * D::X_GRID;
} else {
if (inseg) {
// Dump the current one.
if (seg.X1 < seg.X2) {
// This is not a "dot" segment (i.e a VIA).
fig->addphseg (seg,pNet->external);
fig->addphseg (seg,pNet->external,ischip);
} else if (z % 2) {
char layer = seg.LAYER;
seg.LAYER = MBK::layer2TALU (seg.LAYER);
fig->addphseg (seg,false);
fig->addphseg (seg,false,ischip);
seg.LAYER = layer;
}
}
@ -525,11 +692,11 @@ void CRBox::mbkload (MBK::CFig *mbkfig, int z, int zup, int rtype)
// This segment touch the AB.
if (seg.X1 < seg.X2) {
// This is not a "dot" segment (i.e a VIA).
fig->addphseg (seg,pNet->external);
fig->addphseg (seg,pNet->external,ischip);
} else if (z % 2 ) {
char layer = seg.LAYER;
seg.LAYER = MBK::layer2TALU (seg.LAYER);
fig->addphseg (seg,false);
fig->addphseg (seg,false,ischip);
seg.LAYER = layer;
}
}
@ -551,11 +718,11 @@ void CRBox::mbkload (MBK::CFig *mbkfig, int z, int zup, int rtype)
// Dump the current one.
if (seg.Y1 < seg.Y2) {
// This is not a "dot" segment (i.e a VIA).
fig->addphseg (seg,pNet->external);
fig->addphseg (seg,pNet->external,ischip);
} else if (! (z % 2)) {
char layer = seg.LAYER;
seg.LAYER = MBK::layer2TALU (seg.LAYER);
fig->addphseg (seg,false);
fig->addphseg (seg,false,ischip);
seg.LAYER = layer;
}
@ -570,29 +737,29 @@ void CRBox::mbkload (MBK::CFig *mbkfig, int z, int zup, int rtype)
// We encounter the left edge of a segment.
inseg = true;
seg.X1 = fig->XAB1() + x * D::X_GRID;
seg.X2 = fig->XAB1() + x * D::X_GRID;
seg.Y1 = fig->YAB1() + y * D::Y_GRID;
seg.X1 = xoffsetgrid + x * D::X_GRID;
seg.X2 = xoffsetgrid + x * D::X_GRID;
seg.Y1 = yoffsetgrid + y * D::Y_GRID;
seg.NAME = MBK::namealloc(pNet->name.c_str ());
seg.WIDTH = MBK::env.z2width (z);
if (pNet->external) seg.LAYER = MBK::env.z2calu (z);
else seg.LAYER = MBK::env.z2alu (z);
if (pNet->external && !ischip) seg.LAYER = MBK::env.z2calu (z);
else seg.LAYER = MBK::env.z2alu (z);
}
// Update the right edge.
seg.Y2 = fig->YAB1() + y * D::Y_GRID;
seg.Y2 = yoffsetgrid + y * D::Y_GRID;
} else {
if (inseg) {
// Dump the current one.
if (seg.Y1 < seg.Y2) {
// This is not a "dot" segment (i.e a VIA).
fig->addphseg (seg,pNet->external);
fig->addphseg (seg,pNet->external,ischip);
} else if (! (z % 2)) {
char layer = seg.LAYER;
seg.LAYER = MBK::layer2TALU (seg.LAYER);
fig->addphseg (seg,false);
fig->addphseg (seg,false,ischip);
seg.LAYER = layer;
}
}
@ -606,11 +773,11 @@ void CRBox::mbkload (MBK::CFig *mbkfig, int z, int zup, int rtype)
// This segment touch the AB.
if (seg.Y1 < seg.Y2) {
// This is not a "dot" segment (i.e a VIA).
fig->addphseg (seg,pNet->external);
fig->addphseg (seg,pNet->external,ischip);
} else if (! (z % 2)) {
char layer = seg.LAYER;
seg.LAYER = MBK::layer2TALU (seg.LAYER);
fig->addphseg (seg,false);
fig->addphseg (seg,false,ischip);
seg.LAYER = layer;
}
}
@ -650,8 +817,8 @@ void CRBox::mbkload (MBK::CFig *mbkfig, int z, int zup, int rtype)
if (spaceVIA < pitch) continue;
via.TYPE = MBK::env.z2via (z);
via.XVIA = fig->XAB1() + x * D::X_GRID;
via.YVIA = fig->YAB1() + y * D::Y_GRID;
via.XVIA = xoffsetgrid + x * D::X_GRID;
via.YVIA = yoffsetgrid + y * D::Y_GRID;
via.NAME = MBK::namealloc(pNetTop->name.c_str ());
fig->addphvia (via);
@ -681,8 +848,8 @@ void CRBox::mbkload (MBK::CFig *mbkfig, int z, int zup, int rtype)
if (spaceVIA < pitch) continue;
via.TYPE = MBK::env.z2via (z);
via.XVIA = fig->XAB1() + x * D::X_GRID;
via.YVIA = fig->YAB1() + y * D::Y_GRID;
via.XVIA = xoffsetgrid + x * D::X_GRID;
via.YVIA = yoffsetgrid + y * D::Y_GRID;
via.NAME = MBK::namealloc(pNetTop->name.c_str ());
fig->addphvia (via);
@ -733,20 +900,20 @@ void CRBox::mbkload (MBK::CFig *mbkfig, int z, int zup, int rtype)
rect = itNet->second->terms[0]->rects.front ();
seg.X1 = fig->XAB1() + rect.x1 * D::X_GRID;
seg.X2 = fig->XAB1() + rect.x2 * D::X_GRID;
seg.Y1 = fig->YAB1() + rect.y1 * D::Y_GRID;
seg.Y2 = fig->YAB1() + rect.y2 * D::Y_GRID;
seg.X1 = xoffsetgrid + rect.x1 * D::X_GRID;
seg.X2 = xoffsetgrid + rect.x2 * D::X_GRID;
seg.Y1 = yoffsetgrid + rect.y1 * D::Y_GRID;
seg.Y2 = yoffsetgrid + rect.y2 * D::Y_GRID;
seg.NAME = MBK::namealloc(itNet->second->name.c_str ());
seg.WIDTH = MBK::env.z2width (0);
seg.LAYER = MBK::env.z2calu (0);
fig->addphseg (seg,itNet->second->external);
fig->addphseg (seg,itNet->second->external,ischip);
}
// Add powers lines.
powers[MBK::CALU1]->dump (fig);
if ( !ischip ) powers[MBK::CALU1]->dump (fig);
cmess1 << " o Saving MBK figure \"" << name << "\".\n";

View File

@ -1,7 +1,7 @@
// -*- C++ -*-
//
// $Id: UGrid.cpp,v 1.1 2002/10/02 21:23:48 jpc Exp $
// $Id: UGrid.cpp,v 1.2 2005/10/10 15:34:06 jpc Exp $
//
// /----------------------------------------------------------------\
// | |
@ -356,14 +356,12 @@ int CDRGrid::iterator::manhattan (iterator &other)
// -------------------------------------------------------------------
// Constructor : "CDRGrid::CDRGrid()".
CDRGrid::CDRGrid (int x, int y, int z)
CDRGrid::CDRGrid (int xoff, int yoff, int x, int y, int z)
: xoffset(xoff), yoffset(yoff), X(x), Y(y), Z(z)
{
int index;
X = x;
Y = y;
Z = z;
XY = X * Y;
XYZ = XY * Z;
size = XY * (Z - 1);

View File

@ -1,7 +1,7 @@
// -*- C++ -*-
//
// $Id: nero.cpp,v 1.8 2005/04/07 14:56:18 jpc Exp $
// $Id: nero.cpp,v 1.9 2005/10/10 15:34:06 jpc Exp $
//
// /----------------------------------------------------------------\
// | |
@ -58,11 +58,11 @@ static void help (void)
{
cout << "\n"
<< " o Usage : \"nero [-h] [-v] [-V] [-c] [-2] [-3] [-4] [-5] [-6]\n"
<< " [-L] [-G] [-p <placement>] <netlist> <layout>"
<< " [-H] [-L] [-G] [-p <placement>] <netlist> <layout>"
<< "\"\n\n"
<< " \"nero [--help] [--verbose] [--very-verbose]\n"
<< " [--core-dump] [--global] [--local]\n"
<< " [--place <placement>] <netlist> <layout>\n"
<< " [--core-dump] [--half-pitch] [--rotate] [--global]"
<< " [--local] [--place <placement>] <netlist> <layout>\n"
<< " \"\n\n"
<< " o Options :\n"
<< " [-h|--help] := Print this message.\n"
@ -70,6 +70,8 @@ static void help (void)
<< " [-V|--very-verbose] := Be much more verbose...\n"
<< " [-c|--core-dump] := Generate core dump if an internal "
<< "error occurs.\n"
<< " [-H|--half-pitch] := First track is at half pitch (both X & Y).\n"
<< " [-R|--rotate] := Exchange preferred routing directions.\n"
<< " [-2|--layers-2] := Use only 2 routing layers.\n"
<< " [-3|--layers-3] := Use only 3 routing layers.\n"
<< " [-4|--layers-4] := Use only 4 routing layers.\n"
@ -94,7 +96,7 @@ static void help (void)
static void serial (void)
{
cout << " S/N 20050406.1\n";
cout << " S/N 20051006.1\n";
}
@ -145,6 +147,8 @@ int main (int argc, char *argv[])
options.add ("V", "very-verbose");
options.add ("h", "help");
options.add ("c", "coredump");
options.add ("H", "half-pitch");
options.add ("R", "rotate");
options.add ("2", "layers-2");
options.add ("3", "layers-3");
options.add ("4", "layers-4");
@ -217,7 +221,12 @@ int main (int argc, char *argv[])
crbox = new CRBox ();
//crbox = new CRBox (global, true);
//cdebug.on ();
crbox->mbkload (fig, layers, 4, global);
crbox->mbkload ( fig
, layers
, 4
, global
, options["H"]->parsed
, options["R"]->parsed );
crbox->route ();
//cdebug.off ();
crbox->mbksave (name_routed);