diff --git a/alliance/src/nero/Makefile.am b/alliance/src/nero/Makefile.am new file mode 100644 index 00000000..77a6deb6 --- /dev/null +++ b/alliance/src/nero/Makefile.am @@ -0,0 +1,3 @@ +## Process this file with automake to produce Makefile.in + +SUBDIRS = src doc diff --git a/alliance/src/nero/configure.in b/alliance/src/nero/configure.in new file mode 100644 index 00000000..e2a135bd --- /dev/null +++ b/alliance/src/nero/configure.in @@ -0,0 +1,35 @@ +dnl Process this file with autoconf to produce a configure script. +AC_INIT(src/nero.cpp) + +POIRE_MAJOR_VERSION=1 +POIRE_MINOR_VERSION=0 +POIRE_VERSION=$POIRE_MAJOR_VERSION.$POIRE_MINOR_VERSION + +AC_SUBST(POIRE_MAJOR_VERSION) +AC_SUBST(POIRE_MINOR_VERSION) +AC_SUBST(POIRE_VERSION) + +# For automake. +VERSION=$POIRE_VERSION +PACKAGE=nero + +dnl Initialize automake stuff +AM_INIT_AUTOMAKE($PACKAGE, $VERSION) + +dnl Checks for programs. +AC_PROG_CXX +AC_PROG_CC +AC_PROG_RANLIB +AC_PROG_MAKE_SET + +AC_CHECK_LIB(m, pow) + +dnl Checks for typedefs, structures, and compiler characteristics. +AC_C_CONST + +AM_ALLIANCE + +AC_OUTPUT([ +Makefile +src/Makefile +]) diff --git a/alliance/src/nero/doc/Makefile.am b/alliance/src/nero/doc/Makefile.am new file mode 100644 index 00000000..4f86cb27 --- /dev/null +++ b/alliance/src/nero/doc/Makefile.am @@ -0,0 +1,10 @@ + +SUBDIRS = nero + +pdfdir = $(prefix)/doc/pdf +pdf_DATA = nero.pdf + +EXTRA_DIST = $(pdf_DATA) \ + ./nero.sgm \ + ./man_nero.sgm + diff --git a/alliance/src/nero/doc/builddoc.sh b/alliance/src/nero/doc/builddoc.sh new file mode 100755 index 00000000..107b238c --- /dev/null +++ b/alliance/src/nero/doc/builddoc.sh @@ -0,0 +1,124 @@ +#!/bin/sh + + + LOG="builddoc.log" + TOOL="nero" + SGML_DOC="$TOOL.sgm" + + + detect_fail () + { + echo "" >&2 + echo "builddoc.sh ERROR:" >&2 + echo "" >&2 + echo " Cannot find \"$1\"." >&2 + echo "" >&2 + echo " Please check that DocBook is installed on your system." >&2 + echo "" >&2 + + exit 1 + } + + + detect () + { + STR="`which $1 2> /dev/null`" + + if [ -z "$STR" ]; then detect_fail "$1"; fi + + echo "$STR" + } + + + DB2MAN=`detect docbook2man` + DB2PDF=`detect db2pdf` + DB2HTML=`detect db2html` + + + rm -f $LOG + + + echo "" + echo " o Building MAN pages..." + $DB2MAN $SGML_DOC > $LOG 2>&1 + mv *.1 man1 + + echo " - Building Makefile.am for man1 subdir." + MAN_AM="Makefile.am-man" + echo "" > $MAN_AM + echo "" >> $MAN_AM + echo "man_MANS = \\" >> $MAN_AM + FILE_LIST=`(cd man1; find . -name \*.1 -exec echo {} \;)` + set $FILE_LIST + while [ $# -gt 0 ]; do + LINE=" $1" + if [ $# -gt 1 ]; then LINE="$LINE \\"; fi + echo "$LINE" >> $MAN_AM + shift + done + echo "" >> $MAN_AM + echo "EXTRA_DIST = \$(man_MANS)" >> $MAN_AM + mv $MAN_AM man1/Makefile.am + + + echo "" + echo " o Building HTML..." + if [ -d $TOOL ]; then + mv $TOOL/CVS ./CVS-$TOOL + mv $TOOL/stylesheet-images/CVS ./CVS-SS-$TOOL + fi + + $DB2HTML $SGML_DOC >> $LOG 2>&1 + if [ -d $TOOL.junk ]; then rm -r $TOOL.junk; fi + + echo " - Building Makefile.am for html subdir." + DOC_AM="Makefile.am-doc" + echo "" > $DOC_AM + echo "" >> $DOC_AM + echo "pkghtmldir = \$(prefix)/doc/html/@PACKAGE@" >> $DOC_AM + echo "pkghtml_DATA = \\" >> $DOC_AM + FILE_LIST=`(cd $TOOL; find . -name \*.html -exec echo {} \;)` + set $FILE_LIST + while [ $# -gt 0 ]; do + LINE=" $1" + if [ $# -gt 1 ]; then LINE="$LINE \\"; fi + echo "$LINE" >> $DOC_AM + shift + done + echo "" >> $DOC_AM + echo "EXTRA_DIST = \$(pkghtml_DATA)" >> $DOC_AM + echo "" >> $DOC_AM + echo "install-data-hook:" >> $DOC_AM + echo " chmod -R g+w \$(prefix)/doc/html/@PACKAGE@" >> $DOC_AM + + + mv $DOC_AM $TOOL/Makefile.am + + if [ -d ./CVS-$TOOL ]; then + mv ./CVS-$TOOL $TOOL/CVS + mv ./CVS-SS-$TOOL $TOOL/stylesheet-images/CVS + fi + + + echo "" + echo " o Building PDF..." + $DB2PDF $SGML_DOC >> $LOG 2>&1 + + echo " - Building Makefile.am for doc dir." + DOC_AM="Makefile.am" + echo "" > $DOC_AM + echo "SUBDIRS = $TOOL" >> $DOC_AM + echo "" >> $DOC_AM + echo "pdfdir = \$(prefix)/doc/pdf" >> $DOC_AM + echo "pdf_DATA = $TOOL.pdf" >> $DOC_AM + echo "" >> $DOC_AM + echo "EXTRA_DIST = \$(pdf_DATA) \\" >> $DOC_AM + FILE_LIST=`find . -name \*.sgm -exec echo {} \;` + set $FILE_LIST + while [ $# -gt 0 ]; do + LINE=" $1" + if [ $# -gt 1 ]; then LINE="$LINE \\"; fi + echo "$LINE" >> $DOC_AM + shift + done + echo "" >> $DOC_AM diff --git a/alliance/src/nero/doc/man_nero.sgm b/alliance/src/nero/doc/man_nero.sgm new file mode 100644 index 00000000..eb6ecdea --- /dev/null +++ b/alliance/src/nero/doc/man_nero.sgm @@ -0,0 +1,215 @@ + + + + + + + nero + 1 + ASIM/LIP6 + + + + nero + Negotiating Router + + + + + + nero + -h + -v + -V + -c + -2 + -3 + -4 + -5 + -6 + -L + -G + + --help + --verbose + --very-verbose + --core-dump + --local + --global + + --place placement + netlist + layout + + + + + + Description + + nero is a simple router suited for small + academic designs. Currently it can process designs of size up to + 4K gates. + + + + + Global routing + + A design is considered as big if it + contains nets which half perimeter is greater than 800 lambdas. + Global routing is used on big designs. + + In nero, "global routing" means that + the longuests nets are completly routed in a first step with only + routing layers numbers 3 & 4. Then the smaller nets are routed with all + avalaibles layers. This implies that when global routing is + used, the number of routing layers is forced to at least 4. + In each step, the nets are routed from the shortest to the + longuest with the same routing algorithm. + + + + + + + + + Invocation + + nero mandatory arguments : + + + netlist : the name of + the design, whithout any extention. Please note that unless a + -p placement option + is given, the file holding the placement is expected to have the + same name as the netlist file (short of the extention). + + + + layout : the name of + the resulting routed layout. Be careful of not giving the same + name as the netlist, in this case the initial placement will be + silently overwritten. + + + + + + nero optionnals arguments : + + + -h, --help : + print help. + + + + -v, --verbose : + be verbose. + + + + -V, --very-verbose : + be unbearably verbose. + + + + -c, --core-dump : + do not prevent the generation of core dumps in case of a crash. + Mostly used during the development stage. + + + + -2, + -3, + -4, + -5, + -6 : set the numbers of layers + used for routing. The default for small designs is 2 and 4 for big + ones. When global routing took place, the router will uses at least + 4 routing layers. + + + + -L, --local : + turn off the global routing stage, whatever the size of the design. + Be warned that this will enormously slow down the routing process. + + + + -G, --global : + turn on the global routing regardless of the size of the design. + + + + -p placement, + --place placement : + specify a name for the placement file different from the netlist + name. + + + + + + + + + Example + + Route the netlist amd2901_core.vst, using + the placement file amd2901_core_p.ap and store the + result in amd2901_core_r. + +$ export MBK_IN_LO=vst +$ export MBK_IN_PH=ap +$ export MBK_OUT_PH=ap +$ nero -V --place amd2901_core_p amd2901_core amd2901_core_r + + + + + + + + See Also + + + + MBK_IN_LO + 1 + , + + MBK_OUT_LO + 1 + , + + MBK_IN_PH + 1 + , + + MBK_OUT_PH + 1 + , + + ocp + 1 + , + + ocr + 1 + , + + druc + 1 + , + + cougar + 1 + + + + + + + diff --git a/alliance/src/nero/doc/nero.sgm b/alliance/src/nero/doc/nero.sgm new file mode 100644 index 00000000..60901627 --- /dev/null +++ b/alliance/src/nero/doc/nero.sgm @@ -0,0 +1,49 @@ + + + + + +Alliance"> +Nero"> +nero"> + + +]> + + + + + + + Nero User's Manual + September, 27 2002 + + + Jean-Paul + Chaput + + System Administrator + Pierre & Marie Curie University, LIP6 + ASIM Department + + + + September 2002 / 20020924.1 + September 2002 + + + + + + + &Alliance; - &nero; User's Manual + + &man-nero; + + + + + diff --git a/alliance/src/nero/doc/nero/Makefile.am b/alliance/src/nero/doc/nero/Makefile.am new file mode 100644 index 00000000..bf675df8 --- /dev/null +++ b/alliance/src/nero/doc/nero/Makefile.am @@ -0,0 +1,12 @@ + + +pkghtmldir = $(prefix)/doc/html/@PACKAGE@ +pkghtml_DATA = \ + ./nero.html \ + ./ref_nero.html \ + ./man_nero.html + +EXTRA_DIST = $(pkghtml_DATA) + +install-data-hook: + chmod -R g+w $(prefix)/doc/html/@PACKAGE@ diff --git a/alliance/src/nero/doc/nero/man_nero.html b/alliance/src/nero/doc/nero/man_nero.html new file mode 100644 index 00000000..b482b630 --- /dev/null +++ b/alliance/src/nero/doc/nero/man_nero.html @@ -0,0 +1,559 @@ + +nero
Nero User's Manual
<<< Previous 

nero

Name

nero  --  Negotiating Router

Synopsis

nero [-h] [-v] [-V] [-c] [-2] [-3] [-4] [-5] [-6] [-L] [-G]
[--help] [--verbose] [--very-verbose] [--core-dump] [--local] [--global]
[--place placement] {netlist} {layout}

Description

nero is a simple router suited for small + academic designs. Currently it can process designs of size up to + 4K gates. +

Global routing

A design is considered as big if it + contains nets which half perimeter is greater than 800 lambdas. + Global routing is used on big designs. +

In nero, "global routing" means that + the longuests nets are completly routed in a first step with only + routing layers numbers 3 & 4. Then the smaller nets are routed with all + avalaibles layers. This implies that when global routing is + used, the number of routing layers is forced to at least 4. + In each step, the nets are routed from the shortest to the + longuest with the same routing algorithm. +

Invocation

nero mandatory arguments : +

+

nero optionnals arguments : +

+

Example

Route the netlist amd2901_core.vst, using + the placement file amd2901_core_p.ap and store the + result in amd2901_core_r. +
$ export MBK_IN_LO=vst
+$ export MBK_IN_PH=ap
+$ export MBK_OUT_PH=ap
+$ nero -V --place amd2901_core_p amd2901_core amd2901_core_r
+    
+

See Also

MBK_IN_LO(1), + MBK_OUT_LO(1), + MBK_IN_PH(1), + MBK_OUT_PH(1), + ocp(1), + ocr(1), + druc(1), + cougar(1) +


<<< PreviousHome 
Alliance - nero User's ManualUp 
\ No newline at end of file diff --git a/alliance/src/nero/doc/nero/nero.html b/alliance/src/nero/doc/nero/nero.html new file mode 100644 index 00000000..dd88c9ee --- /dev/null +++ b/alliance/src/nero/doc/nero/nero.html @@ -0,0 +1,141 @@ + + Nero User's Manual

Nero User's Manual

Jean-Paul Chaput

System Administrator
Pierre & Marie Curie University, LIP6
ASIM Department
September 2002 / 20020924.1

Table of Contents
I. Alliance - nero User's Manual
nero --  Negotiating Router

  Next >>>
  Alliance - nero User's Manual
\ No newline at end of file diff --git a/alliance/src/nero/doc/nero/ref_nero.html b/alliance/src/nero/doc/nero/ref_nero.html new file mode 100644 index 00000000..9c21f34b --- /dev/null +++ b/alliance/src/nero/doc/nero/ref_nero.html @@ -0,0 +1,161 @@ + +Alliance - nero User's Manual
Nero User's Manual
<<< PreviousNext >>>

I. Alliance - nero User's Manual

Table of Contents
nero --  Negotiating Router

<<< PreviousHomeNext >>>
Nero User's Manual nero
\ No newline at end of file diff --git a/alliance/src/nero/doc/nero/stylesheet-images/caution.gif b/alliance/src/nero/doc/nero/stylesheet-images/caution.gif new file mode 100644 index 00000000..9cc2e155 Binary files /dev/null and b/alliance/src/nero/doc/nero/stylesheet-images/caution.gif differ diff --git a/alliance/src/nero/doc/nero/stylesheet-images/home.gif b/alliance/src/nero/doc/nero/stylesheet-images/home.gif new file mode 100644 index 00000000..55e1d599 Binary files /dev/null and b/alliance/src/nero/doc/nero/stylesheet-images/home.gif differ diff --git a/alliance/src/nero/doc/nero/stylesheet-images/important.gif b/alliance/src/nero/doc/nero/stylesheet-images/important.gif new file mode 100644 index 00000000..25e40c76 Binary files /dev/null and b/alliance/src/nero/doc/nero/stylesheet-images/important.gif differ diff --git a/alliance/src/nero/doc/nero/stylesheet-images/next.gif b/alliance/src/nero/doc/nero/stylesheet-images/next.gif new file mode 100644 index 00000000..8c502e74 Binary files /dev/null and b/alliance/src/nero/doc/nero/stylesheet-images/next.gif differ diff --git a/alliance/src/nero/doc/nero/stylesheet-images/note.gif b/alliance/src/nero/doc/nero/stylesheet-images/note.gif new file mode 100644 index 00000000..7322e8e4 Binary files /dev/null and b/alliance/src/nero/doc/nero/stylesheet-images/note.gif differ diff --git a/alliance/src/nero/doc/nero/stylesheet-images/prev.gif b/alliance/src/nero/doc/nero/stylesheet-images/prev.gif new file mode 100644 index 00000000..0894d9ec Binary files /dev/null and b/alliance/src/nero/doc/nero/stylesheet-images/prev.gif differ diff --git a/alliance/src/nero/doc/nero/stylesheet-images/tip.gif b/alliance/src/nero/doc/nero/stylesheet-images/tip.gif new file mode 100644 index 00000000..f062955f Binary files /dev/null and b/alliance/src/nero/doc/nero/stylesheet-images/tip.gif differ diff --git a/alliance/src/nero/doc/nero/stylesheet-images/toc-blank.gif b/alliance/src/nero/doc/nero/stylesheet-images/toc-blank.gif new file mode 100644 index 00000000..6c65e3a1 Binary files /dev/null and b/alliance/src/nero/doc/nero/stylesheet-images/toc-blank.gif differ diff --git a/alliance/src/nero/doc/nero/stylesheet-images/toc-minus.gif b/alliance/src/nero/doc/nero/stylesheet-images/toc-minus.gif new file mode 100644 index 00000000..40ebe61e Binary files /dev/null and b/alliance/src/nero/doc/nero/stylesheet-images/toc-minus.gif differ diff --git a/alliance/src/nero/doc/nero/stylesheet-images/toc-plus.gif b/alliance/src/nero/doc/nero/stylesheet-images/toc-plus.gif new file mode 100644 index 00000000..3e9e7d55 Binary files /dev/null and b/alliance/src/nero/doc/nero/stylesheet-images/toc-plus.gif differ diff --git a/alliance/src/nero/doc/nero/stylesheet-images/up.gif b/alliance/src/nero/doc/nero/stylesheet-images/up.gif new file mode 100644 index 00000000..e899a272 Binary files /dev/null and b/alliance/src/nero/doc/nero/stylesheet-images/up.gif differ diff --git a/alliance/src/nero/doc/nero/stylesheet-images/warning.gif b/alliance/src/nero/doc/nero/stylesheet-images/warning.gif new file mode 100644 index 00000000..a5870799 Binary files /dev/null and b/alliance/src/nero/doc/nero/stylesheet-images/warning.gif differ diff --git a/alliance/src/nero/src/AAstar.cpp b/alliance/src/nero/src/AAstar.cpp new file mode 100644 index 00000000..9141c936 --- /dev/null +++ b/alliance/src/nero/src/AAstar.cpp @@ -0,0 +1,846 @@ + +// -*- C++ -*- +// +// $Id: AAstar.cpp,v 1.1 2002/10/02 21:23:47 jpc Exp $ +// +// /----------------------------------------------------------------\ +// | | +// | A l l i a n c e C A D S y s t e m | +// | S i m p l e R o u t e r | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : alliance-support@asim.lip6.fr | +// | ============================================================== | +// | C++ Module : "./AAStar.cpp" | +// | ************************************************************** | +// | U p d a t e s | +// | | +// \----------------------------------------------------------------/ + + + + +# include "ADefs.h" + + + + +// /----------------------------------------------------------------\ +// | Methods Definitions | +// \----------------------------------------------------------------/ + + +// ------------------------------------------------------------------- +// Constructor : "CAStar::CNodeASSet::CNodeASSet()". + +CAStar::CNodeASSet::CNodeASSet (void) +{ + _maxalloc = 0; + _maxchunk = 0; + _maxused = 0; + target = NULL; +} + + + + +// ------------------------------------------------------------------- +// Destructor : "CAStar::CNodeASSet::~CNodeASSet()". +// +// Remove all allocated CNodeAS objects. + +CAStar::CNodeASSet::~CNodeASSet (void) +{ + int chunk, index, maxindex; + + + for (chunk = 0; chunk < _maxchunk; chunk++) { + if (chunk > _maxalloc / D::CHUNK_SIZE) { + maxindex = 0; + } else { + if (chunk == _maxalloc / D::CHUNK_SIZE) + maxindex = _maxalloc % D::CHUNK_SIZE; + else + maxindex = D::CHUNK_SIZE; + } + + for (index = 0; index < maxindex; index++) { + _chunks[chunk][index].point.node().algo = NULL; + } + + free ((void*)_chunks[chunk]); + } + + _maxalloc = 0; + _maxused = 0; + _maxchunk = 0; + _chunks.clear (); +} + + + + +// ------------------------------------------------------------------- +// Allocator : "CAStar::CNodeASSet::check()". +// +// Check all allocated CNodeAS objects. + +void CAStar::CNodeASSet::check (void) +{ + int chunk, index, maxindex; + + + //cdebug << "+ Check all CNodeAS (" << _maxalloc << ")\n"; + + for (chunk = 0; chunk < _maxchunk; chunk++) { + if (chunk > _maxalloc / D::CHUNK_SIZE) { + maxindex = 0; + } else { + if (chunk == _maxalloc / D::CHUNK_SIZE) + maxindex = _maxalloc % D::CHUNK_SIZE; + else + maxindex = D::CHUNK_SIZE; + } + + for (index = 0; index < maxindex; index++) { + if ( _chunks[chunk][index].point.inside() ) { + //cdebug << "+ Not reset CNodeAS found (id := " + // << _chunks[chunk][index].id + // << " (point := " << ")" + // << _chunks[chunk][index].point + // << endl; + } + } + } +} + + + + +// ------------------------------------------------------------------- +// Allocator : "CAStar::CNodeASSet::reset()". +// +// Reset all CNodeAS objects after an algorithm pass. + +void CAStar::CNodeASSet::reset (void) +{ + int chunk, maxchunk, index, maxindex, maxused_div, maxused_mod; + + + //cdebug << "+ CAStar::CNodeAS::resetall()." << endl; + //cdebug << "+ _maxused := " << _maxused << endl; + //cdebug << "+ _maxalloc := " << _maxalloc << endl; + //cdebug << "+ _maxchunk := " << _maxchunk << endl; + + + if (_maxused > 0) { + maxused_div = (_maxused - 1) / D::CHUNK_SIZE; + maxused_mod = (_maxused - 1) % D::CHUNK_SIZE; + + maxchunk = maxused_div + ( (maxused_mod) ? 1 : 0 ); + } else { + maxchunk = 0; + } + + for (chunk = 0; chunk < maxchunk; chunk++) { + maxindex = D::CHUNK_SIZE - 1; + + // Incomplete last chunk. + if ( (chunk == maxchunk - 1) && (maxused_mod != 0) ) + maxindex = maxused_mod; + + //cdebug << "+ Index range := [" << chunk * D::CHUNK_SIZE + // << "," << chunk * D::CHUNK_SIZE + maxindex << "]" + // << " (chunk := " << chunk << ", maxindex := " << maxindex << ")" + // << endl; + + for (index = 0; index <= maxindex; index++) { + //cdebug << "+ index := " << index + // << " (" << &_chunks[chunk][index] << ")" + // << endl; + _chunks[chunk][index].reset (); + } + } + + _maxused = 0; +} + + + + +// ------------------------------------------------------------------- +// Constructor : "CAStar::CNodeAS::CNodeAS()". + +CAStar::CNodeAS::CNodeAS (CDRGrid::iterator &pos) +{ + point = pos; + point.node().algo = (void*)this; + + back = NULL; + distance = 0; + remains = LONG_MAX; + queued = false; + tagged = false; + intree = false; + + //cdebug << "+ new CNodeAS (id := " << id << ", " << point << ")" << endl; +} + + + + +// ------------------------------------------------------------------- +// Operator : "CAStar::CNodeAS::operator<". + +bool CAStar::CNodeAS::operator< (const CNodeAS &other) const +{ + if (D::optim_AStar_order) { + if (this->distance == other.distance) + return (this->remains > other.remains); + } + + return (this->distance > other.distance); +} + + + + +// ------------------------------------------------------------------- +// Allocator : "CAStar::CNodeAS::operator new ()". + +void *CAStar::CNodeAS::operator new (size_t size, CNodeASSet &NS) +{ + int chunk, index; + bool new_chunk; + + + new_chunk = false; + + // Return first element not part of the tree (flag "intree" set). + do { + chunk = NS._maxused / D::CHUNK_SIZE; + index = NS._maxused % D::CHUNK_SIZE; + + // Allocate a new chunk. + if (NS._maxchunk <= chunk) { + NS._chunks.push_back ((CNodeAS*)malloc (sizeof (CNodeAS) * D::CHUNK_SIZE)); + + NS._maxchunk++; + new_chunk = true; + } + + // Use a new element. + NS._maxused++; + + } while (!new_chunk && + (NS._maxused <= NS._maxalloc) && + NS._chunks[chunk][index].intree ); + + NS._maxalloc = max (NS._maxalloc, NS._maxused); + NS._chunks[chunk][index].id = NS._maxused - 1; + + + return ( (void*)( &(NS._chunks[chunk][index]) ) ); +} + + + + +// ------------------------------------------------------------------- +// Method : "CAStar::CNodeAS::reset()". + +void CAStar::CNodeAS::reset (void) +{ + back = NULL; + distance = 0; + remains = LONG_MAX; + queued = false; + tagged = false; + + //CDRGrid::iterator old_point; + + if ( !intree ) { + if ( point.inside() ) { + //cdebug << "+ reset CNodeAS (" << this + // << ") id := " << id << ", point " << point + // << " (node := " << &point.node() << ")" + // << endl; + //old_point = point; + point.node().algo = NULL; + point.unlink (); + + //old_point.node().check (); + //} else { + // cdebug << "+ reset CNodeAS id := " << id << " has point outside!." << endl; + } + //} else { + // cdebug << "+ reset CNodeAS id := " << id << " is in tree." << endl; + } +} + + + + +// ------------------------------------------------------------------- +// Method : "CAStar::CNodeAS::successors()". + +void CAStar::CNodeAS::successors (CNodeASSet &NS, CNet *net, CNodeAS *(*success)[6]) +{ + CDRGrid::iterator neighbor; + CNet *pNet; + CNodeAS *pNodeAS; + + int cost_x, cost_y, cost_z, cost, edge; + long new_distance, new_remains; + + + + //cdebug << "+ CAStar::CNodeAS::successors()." << endl; + + cost_z = D::cost_VIA; + // Alternate costs of edges : + // - z = 0 : ALU1 (unused). + // - z = 1 : ALU2 (horizontal). + // - z = 2 : ALU3 (vertical). + // ... + if (point.z() % 2) { + cost_x = D::cost_ALU2_X; + cost_y = D::cost_ALU2_Y; + } else { + cost_x = D::cost_ALU3_X; + cost_y = D::cost_ALU3_Y; + } + + for (edge = 0; edge < 6; edge++) { + neighbor = point; + switch (edge) { + case 0: cost = cost_x; neighbor.left(); break; + case 1: cost = cost_x; neighbor.right(); break; + case 2: cost = cost_y; neighbor.down(); break; + case 3: cost = cost_y; neighbor.up(); break; + case 4: cost = cost_z; neighbor.bottom(); break; + case 5: cost = cost_z; neighbor.top(); break; + } + + (*success)[edge] = NULL; + + if (neighbor.inside() && !neighbor.isnodehole()) { + //cdebug << "+ " << neighbor << endl; + + pNodeAS = AS (neighbor); + if (!pNodeAS) { + //cdebug << "+ new CNodeAS." << endl; + pNodeAS = new (NS) CNodeAS (neighbor); + } + + // Check if the node is an obstacle. + if (neighbor.node().data.obstacle) continue; + + // Check the tag map (already reached if tagged.) + if (pNodeAS->tagged) continue; + + if (neighbor.z()) { + // Check if the current net can take the node. + if (!neighbor.take (neighbor.node().data.pri)) continue; + } + + // Case of locked nodes : belongs to global nets, never use it. + if ( (neighbor.node().data.owner != net) + && (neighbor.node().locked() ) ) continue; + + // Case of terminal nets : look if it belongs to the net. + if ( (neighbor.node().data.owner != net) + && neighbor.node().terminal() ) continue; + + // Check if the node is an already reached part of the + // partially built routing tree. + if (pNodeAS->isintree ()) continue; + + // Compute new node distance. + new_remains = neighbor.manhattan (*NS.target); + new_distance = distance + cost + new_remains - point.manhattan (*NS.target); + + // If the node is in the priority queue (i.e. has not been popped + // yet) and the new distance is shorter, push it a second time, + // with the new priority. + + if ( !pNodeAS->queued + || (pNodeAS->distance > new_distance) + || ( (pNodeAS->distance == new_distance) + && (pNodeAS->remains < new_remains ))) { + // Set backtracking & cost information. + pNodeAS->back = this; + pNodeAS->distance = new_distance; + pNodeAS->remains = new_remains; + + // Tag the node here : prevent double write in queue. + if (!D::optim_AStar_queue) pNodeAS->tagged = true; + + //cdebug << "+ Added to successor list." << endl; + (*success)[edge] = pNodeAS; + } + } + } +} + + + + +// ------------------------------------------------------------------- +// Method : "CAStar::CTree::addterm()". + +void CAStar::CTree::addterm (CTerm &term) +{ + list::iterator endNode, itNode; + CNodeAS* pNodeAS; + + + //cdebug << "+ Adding terminal nodes to the tree." << endl; + + endNode = term.nodes.end (); + for (itNode = term.nodes.begin (); itNode != endNode; itNode++) { + pNodeAS = AS(*itNode); + if (!pNodeAS) + pNodeAS = new (*_NS) CNodeAS (*itNode); + + addnode (pNodeAS); + pNodeAS->reset(); + + } + + //cdebug << "+ Done." << endl; + + reached.insert (term.id); +} + + + + +// ------------------------------------------------------------------- +// Method : "CAStar::CTree::settarget()". + +void CAStar::CTree::settarget (CDRGrid::iterator &node) +{ + LNodeAS::iterator endNodeAS, itNodeAS; + + + endNodeAS = nodes.end (); + for (itNodeAS = nodes.begin (); itNodeAS != endNodeAS; itNodeAS++) { + (*itNodeAS)->distance = + (*itNodeAS)->remains = node.manhattan ((*itNodeAS)->point); + } + + // Set the target for all CNodeAS objets. I don't like it. + _NS->target = &node; +} + + + + +// ------------------------------------------------------------------- +// Method : "CAStar::CTree::clear()". + +void CAStar::CTree::clear (void) +{ + LNodeAS::iterator endNodeAS, itNodeAS; + + + endNodeAS = nodes.end (); + for (itNodeAS = nodes.begin (); itNodeAS != endNodeAS; itNodeAS++) { + //cdebug << "+ Removing from tree id := " << (*itNodeAS)->id << endl; + (*itNodeAS)->unsettree (); + (*itNodeAS)->reset (); + } + + reached.clear(); + nodes.clear(); +} + + + + +// ------------------------------------------------------------------- +// Method : "CAStar::CQueue::load()". + +void CAStar::CQueue::load (CTree &tree, bool start) +{ + LNodeAS::iterator endNodeAS, itNodeAS; + + + endNodeAS = tree.nodes.end (); + for (itNodeAS = tree.nodes.begin (); itNodeAS != endNodeAS; itNodeAS++) { + if (!start && ((*itNodeAS)->point.z() == 0)) continue; + + push (*itNodeAS); + } +} + + + + +// ------------------------------------------------------------------- +// Constructor : "CAStar::CAStar()". + +CAStar::CAStar (CDRGrid *drgrid, CASimple *netsched) +{ + _drgrid = drgrid; + _netsched = netsched; + + _tree._NS = &_NS; +} + + + + +// ------------------------------------------------------------------- +// Modifiers : "CAStar::clear()". + +void CAStar::clear (void) +{ + if (_skip) { return; } + + net = NULL; + iterations = 0; + + _skip = false; + _trapped = false; + _reached = NULL; + + _drgrid->pri->clear (); + _queue.reset (); + _tree.clear (); + _NS.reset (); +} + + + + +// ------------------------------------------------------------------- +// Modifiers : "CAStar::load()". + +void CAStar::load (CNet *pNet, int delta=0, int expand=0) +{ + net = pNet; + + _skip = false; + if (net->size < 2) { _skip = true; return; } + + _drgrid->pri->load (*pNet, _netsched->rglobal && pNet->global(), expand); + _drgrid->pri->delta = delta; + + net->unroute (); + _tree.addterm (*(net->terms[0])); +} + + + + +// ------------------------------------------------------------------- +// Method : "CAStar::step()". + +bool CAStar::step (void) throw (trapped_astar) +{ + CNodeAS *successors[6], *pNodeAS; + int edge; + + + //cdebug << "+ CAStar::step()." << endl; + + iterations++; + + // Pop node until : + // 1. - The queue is emptied : we cannot route the signal. + // 2. - An untagged node is found, that is a node which is not + // a duplicata of an already processed node. + do { + if (_queue.empty()) { + //emergency (); exit (1); + throw trapped_astar(net); + } + + pNodeAS = _queue.pop (); + + } while ( pNodeAS->tagged && D::optim_AStar_queue ); + + //cdebug << "+ " << pNodeAS->point << endl; + + // We process the node : tag it. + if (D::optim_AStar_queue) pNodeAS->tagged = true; + + pNodeAS->successors (_NS, net, &successors); + + for (edge = 0; edge < 6; edge++) { + if (successors[edge] == NULL) continue; + + //cdebug << "+ " << successors[edge]->point << endl; + // The successor belongs to the current net. + // (it may be not the actual target). + if ( (successors[edge]->point.node().data.owner == net) + && (_tree.reached.find (successors[edge]->point.node().getid()) + == _tree.reached.end())) { + _reached = successors[edge]; + return (false); + } + + // Otherwise, put it into the queue. + _queue.push (successors[edge]); + } + + //cdebug << "+ Successors processed." << endl; + + + return (true); +} + + + + +// ------------------------------------------------------------------- +// Method : "CAStar::nexttarget()". + +bool CAStar::nexttarget (void) +{ + int i; + set::iterator endSet; + + // Are all targets reacheds? + if (_tree.reached.size () >= net->size) return (false); + + // Reset all the nodeAS objects. + _NS.reset (); + + //CNodeAS::checkall (); + //net->_drgrid->nodes->check (); + + // Select the next target. + endSet = _tree.reached.end (); + for (i = 0; i < net->size; i++) { + if (_tree.reached.find (i) == endSet) { + _tree.settarget ( net->terms[i]->lowest() ); + break; + } + } + + // Reset & init the queue. + _queue.reset (); + _queue.load (_tree, (_tree.reached.size() == 1)); + + + return (true); +} + + + + +// ------------------------------------------------------------------- +// Method : "CAStar::backtrack()". + +void CAStar::backtrack (void) +{ + CNodeAS *node, *node_prev; + CNet *del_net; + + + //cdebug << "+ Backtracking." << endl; + + // Do the backtracking. + node = _reached->back; + + while (node->back != NULL) { + if (node->point.node().data.pri > 0) { + del_net = node->point.node().data.owner; + del_net->unroute (); + _netsched->queue (del_net); + } + + _tree.addnode (node); + + node_prev = node; + node = node->back; + + node_prev->reset (); + } + + + // Add the reached terminal to the tree. + _tree.addterm ( *( net->terms[_reached->point.node().getid()] ) ); + + //cdebug << "+ Done." << endl; +} + + + + +// ------------------------------------------------------------------- +// Method : "CAStar::search()". + +bool CAStar::search (void) +{ + if (_skip) return (false); + + try { + if (_drgrid->pri->delta) { + cmess2 << " > Re-routing with pri := " + << _drgrid->pri->delta << ".\n"; + } + + while ( nexttarget() ) { + for (; step(); ); + + backtrack (); + } + + //CNodeAS::checkall (); + //net->_drgrid->nodes->check (); + + return (false); + } + + catch (trapped_astar &e) { + abort (); + cmess2 << " > AStar unable to found a path.\n"; + + //CNodeAS::checkall (); + //net->_drgrid->nodes->check (); + } + + return (true); +} + + + +// ------------------------------------------------------------------- +// Method : "CAStar::abort()". + +void CAStar::abort (void) +{ + _tree.clear(); +} + + + +// ------------------------------------------------------------------- +// Method : "CAStar::dump()". + +void CAStar::dump (void) +{ + LNodeAS::iterator endNode, itNode; + CDRGrid::iterator point; + int num_nodes; + + + if (_skip) return; + + num_nodes = 0; + endNode = _tree.nodes.end (); + for (itNode = _tree.nodes.begin (); itNode != endNode; itNode++) { + point = (*itNode)->point; + point.node().grab (net, point.pri() + _drgrid->pri->delta, point); + num_nodes++; + } + + _tree.clear(); +} + + + +// ------------------------------------------------------------------- +// Method : "CAStar::route()". + +void CAStar::route (CNet *pNet) +{ + int pri; + int increase, expand; + bool hysteresis, routed; + long *iterations_kind; + + + hysteresis = false; + increase = 0; + expand = 0; + iterations_route = 0; + iterations_reroute = 0; + iterations_kind = &iterations_route; + + //if (pNet->name == "ctl.seq_ep_30") cdebug.on (); + + do { + if (hysteresis) { + clear (); + + pri = 255 + (1 << increase++); + + if (increase > 1) expand = 200; + + iterations_kind = &iterations_reroute; + } + else + pri = 0; + + load (pNet, pri, expand); + + routed = !search (); + *iterations_kind += iterations; + + hysteresis = true; + } while ((increase < 15) && !routed); + + if (routed) dump(); + + clear (); + + //CNodeAS::checkall (); + //pNet->_drgrid->nodes->check (); + + //if (pNet->name == "ctl.seq_ep_30") exit (0); +} + + + + +// ------------------------------------------------------------------- +// Method : "CMatrixNodes::check()". + +void CMatrixNodes::check (void) +{ + int index; + + + cdebug << "+ Check routing DB.\n"; + for (index = 0; index < _drgrid->XYZ; index++) { + if ( &(*this)[index] == &hole ) continue; + + if ( ! (*this)[index].check() ) + cdebug << " (point := (" << _drgrid->x(index) + << "," << _drgrid->y(index) + << "," << _drgrid->z(index) << "))\n"; + + } +} + + + + +// ------------------------------------------------------------------- +// Method : "CNode::check()". + +bool CNode::check (void) +{ + CAStar::CNodeAS *nodeAS; + + + if ( algo != NULL ) { + cdebug << "+ Residual algo structure found!\n"; + + nodeAS = (CAStar::CNodeAS*) algo; + + if ( nodeAS->point.outside() ) { + cdebug << "+ Incoherent algo structure found (node := " + << this << ") : " + << nodeAS << " (id := " << nodeAS->id << ")"; + return ( false ); + } + } + + return ( true ); +} diff --git a/alliance/src/nero/src/ADefs.h b/alliance/src/nero/src/ADefs.h new file mode 100644 index 00000000..e210822b --- /dev/null +++ b/alliance/src/nero/src/ADefs.h @@ -0,0 +1,350 @@ + +// -*- C++ -*- +// +// $Id: ADefs.h,v 1.1 2002/10/02 21:23:47 jpc Exp $ +// +// /-----------------------------------------------------------------\ +// | | +// | A l l i a n c e C A D S y s t e m | +// | S i m p l e R o u t e r | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : alliance-support@asim.lip6.fr | +// | =============================================================== | +// | C++ Header : "./ADefs.h" | +// | *************************************************************** | +// | U p d a t e s | +// | | +// \-----------------------------------------------------------------/ + + + + +# ifndef __ADefs__ +# define __ADefs__ 1 + + +# include "MDefs.h" + + + + +// ------------------------------------------------------------------- +// Class declaration. + + class CAStar; + class CASimple; + + + +// ------------------------------------------------------------------- +// Module : "AAstar.cpp". + + + // --------------------------------------------------------------- + // AStar trapped exception. + + class trapped_astar : public except_done { + + // Attributes. + public: CNet *net; + + // Constructor. + public: trapped_astar (CNet *pNet) { net = pNet; } + + // Overridables. + public: const char* what () const throw () { + return ((char*)"AStar algorithm can't find a path."); + } + }; + + + + + // --------------------------------------------------------------- + // Unable to route exception. + + class no_route : public except_done { + + // Attributes. + public: CNet *net; + + // Constructor. + public: no_route (CNet *pNet) { net = pNet; } + + // Overridables. + public: const char* what () const throw () { + return ((char*)"No route."); + } + }; + + + + + // --------------------------------------------------------------- + // AStar algorithm class. + // + // This class includes all subclasses it needs. + + class CAStar { + + public: class CNodeAS; + class CNodeASSet; + class CTree; + class CQueue; + + + typedef list LNodeAS; + + + // Additionnal datas needed on nodes. ------------------------ + public: class CNodeAS { + + // Attributes. + public: CDRGrid::iterator point; + public: CNodeAS *back; + public: long distance; + public: long remains; + public: bool queued; + public: bool tagged; + public: bool intree; + public: int id; + + // Operator. + public: bool operator< (const CNodeAS &other) const; + + // Constructor. + public: CNodeAS (CDRGrid::iterator &pos); + + // Allocators. + private: static void *operator new (size_t size); + private: static void operator delete (void *zone); + public: static void *operator new (size_t size, CNodeASSet &NS); + + // Modifiers. + public: void reset (void); + public: void settree (void) { intree = true; } + public: void unsettree (void) { intree = false; } + + // Accessors. + public: void successors (CNodeASSet &NS, CNet *net, CNodeAS *(*success)[6]); + public: bool isintree (void) { return (intree); } + + }; + + + inline static CNodeAS *AS (CDRGrid::iterator point) + { return ((CNodeAS*)(point.node().algo)); } + + + // Heap Allocator for CNodeAS. ------------------------------- + class CNodeASSet { + + // Internal attributes. + private: vector _chunks; + private: int _maxchunk; + private: int _maxalloc; + private: int _maxused; + + // Shared attribute (ugly one). + public: CDRGrid::iterator *target; + + // Constructor. + public: CNodeASSet (void); + + // Destructor. + public: ~CNodeASSet (void); + + // Modifiers. + public: void reset (void); + public: void check (void); + + // Friend class (for CNodeAS allocator). + friend class CNodeAS; + + }; + + + // Partially build routing tree. ----------------------------- + class CTree { + + // Internal attributes. + public: CNodeASSet *_NS; + + // Attributes. + public: LNodeAS nodes; + public: set reached; + + // Modifiers. + public: void addnode (CNodeAS *node) { + node->settree (); + nodes.push_back (node); + } + public: void addterm (CTerm &term); + public: void settarget (CDRGrid::iterator &node); + public: int size (void) { return (reached.size()); } + public: void clear (void); + + }; + + + + + // Priority queue. ------------------------------------------- + class CQueue { + + // Queue element class. + class CQelem { + + // Attributes. + public: CNodeAS *node; + + // Constructor. + public: CQelem (CNodeAS *pNode=NULL) { node = pNode; } + + // Operator : ordering function. + public: bool operator< (const CQelem &other) const { + return ((*this->node) < (*other.node)); + } + }; + + // Attribute. + private: priority_queue queue; + + // Accessors. + public: CNodeAS* pop (void) { + CQelem elem; + + elem = queue.top (); + elem.node->queued = false; + queue.pop (); + + return (elem.node); + } + public: void push (CNodeAS *node) { + node->queued = true; + + queue.push(CQelem (node)); + } + public: bool empty (void) { return (queue.empty()); } + public: void reset (void) { while (!empty()) pop(); } + public: void load (CTree &tree, bool start); + + }; + + + + + // Internal CAStar attributes : the state of the algorithm. + private: CNodeASSet _NS; + private: CTree _tree; + private: CQueue _queue; + private: bool _skip; + private: bool _trapped; + private: CNodeAS *_reached; + + // Attributes. + public: CNet *net; + public: long iterations; + public: long iterations_route; + public: long iterations_reroute; + public: CDRGrid *_drgrid; + public: CASimple *_netsched; + + // Constructor. + public: CAStar (CDRGrid *drgrid, CASimple *netsched); + + // Modifiers. + private: bool step (void) throw (trapped_astar); + private: bool nexttarget (void); + private: void backtrack (void); + private: void abort (void); + public: void dump (void); + public: void clear (void); + public: void load (CNet *pNet, int delta=0, int expand=0); + public: bool search (void); + public: void route (CNet *pNet); + + }; + + + + +// ------------------------------------------------------------------- +// Module : "ASimple.cpp". + + + // --------------------------------------------------------------- + // ASimple algorithm class. + // + // This class includes all subclasses it needs. + + class CASimple { + + + // Priority queue. ------------------------------------------- + class CQueue { + + // Queue element class. + class CQelem { + + // Attributes. + public: CNet *net; + + // Constructor. + public: CQelem (CNet *pNet=NULL) { net = pNet; } + + // Operator : ordering function. + public: bool operator< (const CQelem &other) const { + return ((*this->net) < (*other.net)); + } + }; + + // Attribute. + public: priority_queue queue; + + // Accessors. + public: CNet* pop (void) { + CQelem elem; + + elem = queue.top (); + queue.pop (); + + return (elem.net); + } + public: void push (CNet *net) { queue.push(CQelem (net)); } + public: bool empty (void) { return (queue.empty()); } + public: void reset (void) { while (!empty()) pop(); } + public: void load (MNet *nets, bool rglobal, bool global); + + }; + + + // Internal CASimple attributes : the state of the algorithm. + public: CQueue _queue; + public: CAStar _astar; + public: CDRGrid *_drgrid; + public: bool rglobal; + + // Attributes. + public: MNet *nets; + public: long iterations_route; + public: long iterations_reroute; + + // Constructor. + public: CASimple (MNet *mNets, CDRGrid *drgrid); + + // Modifiers. + public: void queue (CNet *net) { _queue.push (net); } + public: bool step (void); + public: void global (void); + public: void local (void); + public: void stats (void); + public: void run (bool rtype); + + }; + + + + +# endif diff --git a/alliance/src/nero/src/APri.cpp b/alliance/src/nero/src/APri.cpp new file mode 100644 index 00000000..5d028ede --- /dev/null +++ b/alliance/src/nero/src/APri.cpp @@ -0,0 +1,385 @@ + +// -*- C++ -*- +// +// $Id: APri.cpp,v 1.1 2002/10/02 21:23:47 jpc Exp $ +// +// /----------------------------------------------------------------\ +// | | +// | A l l i a n c e C A D S y s t e m | +// | S i m p l e R o u t e r | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : alliance-support@asim.lip6.fr | +// | ============================================================== | +// | C++ Module : "./APri.cpp" | +// | ************************************************************** | +// | U p d a t e s | +// | | +// \----------------------------------------------------------------/ + + + + +# include "ADefs.h" + + + + + // --------------------------------------------------------------- + // Pre-defined objects. + + // Signal priority map. + CMapPri *netpri; + + + + +// /----------------------------------------------------------------\ +// | Methods Definitions | +// \----------------------------------------------------------------/ + + +// ------------------------------------------------------------------- +// Constructor : "CMapPri::CMapPri()". + +CMapPri::CMapPri (CCoordBase *coordBase) +{ + base = coordBase; + + _map = new char [base->XYZ]; + _mapsize = sizeof (char [base->XYZ]); + + clear(); + + ::netpri = this; +} + + + + +// ------------------------------------------------------------------- +// Destructor : "CMapPri::~CMapPri()". + +CMapPri::~CMapPri (void) +{ + delete [] _map; +} + + + + +// ------------------------------------------------------------------- +// Method : "CMapPri::operator[]". + +int CMapPri::operator[] (CCoord &coord) throw (primap_clear) +{ + if (cleared) throw primap_clear (); + + if ((coord.x() < 0) || (coord.x() > base->X - 1)) return (0); + if ((coord.y() < 0) || (coord.y() > base->Y - 1)) return (0); + if ((coord.z() < 1) || (coord.z() > base->Z - 1)) return (0); + + return (offset + (int)(_map[coord.index() - base->XY])); +} + + + + +// ------------------------------------------------------------------- +// Method : "CMapPri::map()". + +char *CMapPri::map (CCoord coord) +{ + if ((coord.x() < 0) || (coord.x() > base->X - 1)) return (NULL); + if ((coord.y() < 0) || (coord.y() > base->Y - 1)) return (NULL); + if ((coord.z() < 1) || (coord.z() > base->Z - 1)) return (NULL); + + return (&(_map[coord.index() - base->XY])); +} + + + + +// ------------------------------------------------------------------- +// Method : "CMapPri::map()". + +char *CMapPri::map (int index) +{ + CCoord nodeCoord = CCoord (index); + + return (map(nodeCoord)); +} + + + + +// ------------------------------------------------------------------- +// Method : "CMapPri::findfree()". + +void CMapPri::findfree (CCoord ¢er) +{ + int radius, i, j, cx, cy; + CCoord coord; + bool freed; + + + freed = false; + radius = 0; + cx = center.x(); + cy = center.y(); + + while (!freed) { + radius += 1; + + for (i = cx - radius; i < cx + radius + 1; i++) { + for (j = cy - radius; j < cy + radius + 1; j++) { + // Proccess only nodes of the ring. + // if ( (i > cx - radius) || (i < cx + radius) ) continue; + // if ( (j > cy - radius) || (j < cy + radius) ) continue; + + if ( !(*::grid)[coord.set(i,j,2)]->data.obstacle ) freed = true; + + *map (coord.set(i,j,1)) = (char)1; + *map (coord.set(i,j,2)) = (char)1; + } + } + } +} + + + + +// ------------------------------------------------------------------- +// Method : "CMapPri::clear()". + +void CMapPri::clear (void) +{ + //int index; + // + //for (index = 0; index < base->XYZ; index++) { + // _map[index] = (char)0; + //} + + memset (_map, (char)0, _mapsize); + + cleared = true; + offset = 0; + delta = 0; +} + + + + +// ------------------------------------------------------------------- +// Method : "CMapPri::nextPri()". + +char CMapPri::nextPri (char curpri) +{ + return ((curpri > 1) ? (curpri >> 1) : 1); +} + + + + +// ------------------------------------------------------------------- +// Method : "CMapPri::load()". + +void CMapPri::load (CNet &net, bool global, int expand=0) +{ + list::iterator itNode, beginNode, endNode; + + queue queue1, queue2; + queue *currentBorder, *nextBorder; + + CCoord *pCoord, nodeCoord; + char currentPri, *pmap; + int x, y, z, nx, ny, nz, edge, id, ex, ey; + bool breakLoop; + + + clear (); + + offset = net.pri; + delta = 0; + + currentBorder = &queue1; + nextBorder = &queue2; + currentPri = 64; + + + // Expand the original BB if too small. + ex = 0; + ey = 0; + + if (net.bb.x2 - net.bb.x1 < 5) ex = 5; + if (net.bb.y2 - net.bb.y1 < 5) ey = 5; + + if (expand) ex = ey = expand; + + _bb.x1 = max (0 , net.bb.x1 - ex); + _bb.x2 = min (base->X - 1, net.bb.x2 + ex); + _bb.y1 = max (0 , net.bb.y1 - ey); + _bb.y2 = min (base->Y - 1, net.bb.y2 + ey); + + + // Build the initials border lists : coordinates of the terminals. + // The table doesn't have a z = 0 layer (never used for routing), + // so when a terminal on layer 0 is encountered, we queue the + // the coordinate on top in the next border queue. + // That is, in the first step of the algorithm we fill both queue + // at the same time. + // In the case of the map of a global signal (i.e. using z=3&4 for + // the time beeing, set to one the map points above the terminal + // in z=1&2, as they will not be set by the _bb loop. + + for (id = 0; id < net.size; id++) { + beginNode = (net.terms[id])->nodes.begin (); + endNode = (net.terms[id])->nodes.end (); + + for (itNode = beginNode; itNode != endNode; itNode++) { + nodeCoord = (*itNode)->coord; + + // Initial queues filling. + if (nodeCoord.z() > 0) { + *(map (nodeCoord)) = currentPri; + currentBorder->push (new CCoord (nodeCoord)); + + // Enable z=1 (in case of global signal, no effet otherwise). + if (nodeCoord.z() < base->Z - 1) *(map (nodeCoord.dz(1))) = (char)1; + + continue; + } + + *(map (nodeCoord.dz(1))) = nextPri (currentPri); + nextBorder->push (new CCoord (nodeCoord)); + + // Enable z=2 (in case of global signal, no effet otherwise). + *(map (nodeCoord.dz(1))) = (char)1; + + // Look if the upper node is blocked, in that case expand the + // allowed zone till a non-blocked node is found. + if ((*::grid)[nodeCoord]->data.obstacle) findfree (nodeCoord); + } + } + + + // Set to one all the points inside the enclosing box. + // (except those in the initial queues) + for (x = _bb.x1; x <= _bb.x2; x++) { + for (y = _bb.y1; y <= _bb.y2; y++) { + for (z = (global) ? 3 : 1; z < base->Z; z++) { + pmap = map (nodeCoord.set (x, y, z)); + if (pmap && (!(*pmap))) *pmap = (char)1; + } + } + } + + + breakLoop = false; + currentPri = nextPri (currentPri); + + // And here we go! + while (true) { + // Checks if the current border is finished. If so swap it with the + // nextBorder. If the current border is still empty, we are done. + if (currentBorder->empty ()) { + currentPri = nextPri (currentPri); + swap (currentBorder, nextBorder); + + if (currentBorder->empty ()) { + breakLoop = true; + } + } + if (breakLoop) break; + + pCoord = currentBorder->front (); + currentBorder->pop (); + + x = pCoord->x (); + y = pCoord->y (); + z = pCoord->z (); + + delete pCoord; + + for (edge = 0; edge < 6; edge++) { + nx = x; ny = y; nz =z; + + // Look at all six neighbors. + switch (edge) { + case 0: nx -= 1; break; + case 1: nx += 1; break; + case 2: ny -= 1; break; + case 3: ny += 1; break; + case 4: nz -= 1; break; + case 5: nz += 1; break; + } + + try { pmap = map (nodeCoord.set (nx, ny, nz)); } + catch (coord_outbound &e) { continue; } + + // Usable nodes have been set to at least one, if not skip it. + if ( (pmap == NULL) || (*pmap == (char)0) ) continue; + + if (*pmap == (char)1) { + *pmap = currentPri; + // Push only nodes that are not of minimal priority. + if (currentPri > (char)1) + nextBorder->push (new CCoord (nodeCoord)); + } + } + + } + + + cleared = false; +} + + + + +// ------------------------------------------------------------------- +// Method : "CMapPri::cmp()". + +bool CMapPri::cmp (int pri, CCoord &coord) +{ + char mappri; + + + mappri = (*this)[coord]; + + if (!mappri) return (true); + if (!pri) return (false); + + return (pri + 256 >= mappri + delta); +} + + + + +// ------------------------------------------------------------------- +// Friend : "&operator<<()". + +ostream &operator<< (ostream &o, CMapPri *self) +{ + int x, y, z; + CCoord nodeCoord; + + o << "cleared := " << self->cleared << "\n" + << "offset := " << self->offset << "\n" + << "delta := " << self->delta << "\n"; + + for (z = 1; z < self->base->Z; z++) { + o << " (layer) z := " << z << "\n"; + + for (y = 1; y <= self->base->Y; y++) { + o << " "; + for (x = 0; x < self->base->X; x++) { + o << setw(5) << (int)((*self)[ + nodeCoord.set (x, self->base->Y - y, z)]); + } + o << "\n"; + } + } + + return (o); +} diff --git a/alliance/src/nero/src/ASimple.cpp b/alliance/src/nero/src/ASimple.cpp new file mode 100644 index 00000000..8fed4449 --- /dev/null +++ b/alliance/src/nero/src/ASimple.cpp @@ -0,0 +1,168 @@ + +// -*- C++ -*- +// +// $Id: ASimple.cpp,v 1.1 2002/10/02 21:23:47 jpc Exp $ +// +// /----------------------------------------------------------------\ +// | | +// | A l l i a n c e C A D S y s t e m | +// | S i m p l e R o u t e r | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : alliance-support@asim.lip6.fr | +// | ============================================================== | +// | C++ Module : "./ASimple.cpp" | +// | ************************************************************** | +// | U p d a t e s | +// | | +// \----------------------------------------------------------------/ + + + + +# include "ADefs.h" + + + + +// /----------------------------------------------------------------\ +// | Methods Definitions | +// \----------------------------------------------------------------/ + + +// ------------------------------------------------------------------- +// Method : "CASimple::CQueue::load()". + +void CASimple::CQueue::load (MNet *nets, bool rglobal, bool global) +{ + MNet::iterator itNet, endNet; + + + endNet = nets->end(); + for (itNet = nets->begin(); itNet != endNet; itNet++) { + // Global routing stage. + if ( rglobal && global && (itNet->second->global()) ) + push (itNet->second); + + // Local routing stage. + if ( !rglobal || ( !global && !(itNet->second->global()) ) ) + push (itNet->second); + } +} + + + + +// ------------------------------------------------------------------- +// Constructor : "CASimple::CASimple()". + +CASimple::CASimple (MNet *mNets, CDRGrid *drgrid) : _astar(drgrid, this) +{ + nets = mNets; + iterations_route = 0; + iterations_reroute = 0; +} + + + + +// ------------------------------------------------------------------- +// Method : "CASimple::step()". + +bool CASimple::step (void) +{ + CNet *net; + + + if (_queue.empty()) return (false); + + //if (_queue.queue.size() <= 14) { emergency(); exit(1); } + + net = _queue.pop (); + + cmess2 << " - [" << setw(4) << _queue.queue.size() + << "] \"" << net->name << "\" (" + << net->bb << ")\n"; + + _astar.route (net); + iterations_route += _astar.iterations_route; + iterations_reroute += _astar.iterations_reroute; + + return (true); +} + + + + +// ------------------------------------------------------------------- +// Method : "CASimple::global()". + +void CASimple::global (void) +{ + MNet::iterator itNet, endNet; + + + cmess2 << "\n"; + cmess1 << " o Global routing stage.\n"; + + _queue.load (nets, rglobal, true); + + while ( step() ); + + + // Locking global signals. + endNet = nets->end(); + for (itNet = nets->begin(); itNet != endNet; itNet++) { + if ( itNet->second->global() ) itNet->second->locktree(); + } +} + + + + +// ------------------------------------------------------------------- +// Method : "CASimple::local()". + +void CASimple::local (void) +{ + cmess2 << "\n"; + cmess1 << " o Local routing stage.\n"; + + _queue.load (nets, rglobal, false); + + while ( step() ); +} + + + + +// ------------------------------------------------------------------- +// Method : "CASimple::stats()". + +void CASimple::stats (void) +{ + cmess2 << "\n"; + cmess2 << " o Routing stats :\n"; + cmess2 << " - routing iterations := " << iterations_route << "\n"; + cmess2 << " - re-routing iterations := " << iterations_reroute << "\n"; + cmess2 << " - ratio := " + << ((float)iterations_reroute / + (float)(iterations_reroute + iterations_route)) * 100.0 + << "%.\n"; +} + + + + +// ------------------------------------------------------------------- +// Method : "CASimple::run()". + +void CASimple::run (bool rtype) +{ + rglobal = rtype; + + if (rglobal) global (); + + local (); + stats (); +} diff --git a/alliance/src/nero/src/ATag.cpp b/alliance/src/nero/src/ATag.cpp new file mode 100644 index 00000000..2696581e --- /dev/null +++ b/alliance/src/nero/src/ATag.cpp @@ -0,0 +1,124 @@ + +// -*- C++ -*- +// +// $Id: ATag.cpp,v 1.1 2002/10/02 21:23:47 jpc Exp $ +// +// /----------------------------------------------------------------\ +// | | +// | A l l i a n c e C A D S y s t e m | +// | S i m p l e R o u t e r | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : alliance-support@asim.lip6.fr | +// | ============================================================== | +// | C++ Module : "./ATag.cpp" | +// | ************************************************************** | +// | U p d a t e s | +// | | +// \----------------------------------------------------------------/ + + + + +# include "ADefs.h" + + + + + // --------------------------------------------------------------- + // Pre-defined objects. + + // Global tag map. + CMapTag *nettag; + + + + +// /----------------------------------------------------------------\ +// | Methods Definitions | +// \----------------------------------------------------------------/ + + +// ------------------------------------------------------------------- +// Constructor : "CMapTag::CMapTag()". + +CMapTag::CMapTag (CCoordBase *coordBase) +{ + base = coordBase; + + _map = new bool [base->XYZ]; + _mapsize = sizeof (bool [base->XYZ]); + + clear(); + + ::nettag = this; +} + + + + +// ------------------------------------------------------------------- +// Destructor : "CMapTag::~CMapTag()". + +CMapTag::~CMapTag (void) +{ + delete [] _map; +} + + + + +// ------------------------------------------------------------------- +// Method : "CMapTag::&operator[]". + +bool &CMapTag::operator[] (CCoord &coord) +{ + static bool outbound; + + outbound = false; + + if ((coord.x() < 0) || (coord.x() > base->X - 1)) return (outbound); + if ((coord.y() < 0) || (coord.y() > base->Y - 1)) return (outbound); + if ((coord.z() < 1) || (coord.z() > base->Z - 1)) return (outbound); + + return (_map[coord.index() - base->XY]); +} + + + + +// ------------------------------------------------------------------- +// Method : "CMapTag::clear()". + +void CMapTag::clear (void) +{ + memset (_map, (char)0, _mapsize); +} + + + + +// ------------------------------------------------------------------- +// Friend : "&operator<<()". + +ostream &operator<< (ostream &o, CMapTag *self) +{ + int x, y, z; + CCoord nodeCoord; + + o << "Map Tag state := \n"; + + for (z = 1; z < self->base->Z; z++) { + o << " (layer) z := " << z << "\n"; + + for (y = 1; y <= self->base->Y; y++) { + o << " "; + for (x = 0; x < self->base->X; x++) { + o << (*self)[nodeCoord.set (x, self->base->Y - y, z)]; + } + o << "\n"; + } + } + + return (o); +} diff --git a/alliance/src/nero/src/MDRGrid.cpp b/alliance/src/nero/src/MDRGrid.cpp new file mode 100644 index 00000000..08c5b6f8 --- /dev/null +++ b/alliance/src/nero/src/MDRGrid.cpp @@ -0,0 +1,548 @@ + +// -*- C++ -*- +// +// $Id: MDRGrid.cpp,v 1.1 2002/10/02 21:23:47 jpc Exp $ +// +// /----------------------------------------------------------------\ +// | | +// | A l l i a n c e C A D S y s t e m | +// | S i m p l e R o u t e r | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : alliance-support@asim.lip6.fr | +// | ============================================================== | +// | C++ Module : "./MDRGrid.cpp" | +// | ************************************************************** | +// | U p d a t e s | +// | | +// \----------------------------------------------------------------/ + + + + +# include "MDefs.h" + + + + +// /----------------------------------------------------------------\ +// | Methods Definitions | +// \----------------------------------------------------------------/ + + +// ------------------------------------------------------------------- +// Friend of "CRect" : "&operator<<()". + +ostream &operator<< (ostream &o, const CRect *rect) +{ + o << "(" + << rect->x1 << ", " + << rect->y1 << "), (" + << rect->x2 << ", " + << rect->y2 << ")"; + + return (o); +} + + + + +// ------------------------------------------------------------------- +// Constructor : "CBB::CBB()". + +CBB::CBB (void) +{ + x1 = INT_MAX; + y1 = INT_MAX; + x2 = 0; + y2 = 0; + hp = 0; +} + + + + +// ------------------------------------------------------------------- +// Method : "CBB::merge()". + +void CBB::merge (CCoord &coord) +{ + x1 = min (x1, coord.x); + y1 = min (y1, coord.y); + x2 = max (x2, coord.x); + y2 = max (y2, coord.y); + + hp = (x2 - x1) + (y2 - y1); +} + + + + +// ------------------------------------------------------------------- +// Friend of "CBB" : "&operator<<()". + +ostream &operator<< (ostream &o, CBB &self) +{ + o << "CBB (" << self.x1 << "," << self.y1 << ") (" + << self.x2 << "," << self.y2 << ") HP := " << self.hp; + + return (o); +} + + + + + + +// ------------------------------------------------------------------- +// Constructor : "CDRGrid::iterator::iterator ()". + +CDRGrid::iterator::iterator (void) +{ + _drgrid = NULL; + _index = INT_MAX; +} + + + + +// ------------------------------------------------------------------- +// Constructor : "CDRGrid::iterator::iterator ()". + +CDRGrid::iterator::iterator (const CDRGrid::iterator &other) +{ + _drgrid = other._drgrid; + _index = other._index; +} + + + + +// ------------------------------------------------------------------- +// Method : "CDRGrid::iterator::valid ()". + +void CDRGrid::iterator::valid (bool validindex) + throw (e_matrix_iterator) +{ + if (_drgrid == NULL) { + throw e_matrix_iterator ("Attempt to use an unitialized grid iterator."); + } + + if ( (validindex) && (_index == INT_MAX) ) + throw e_matrix_iterator ("Attempt to use iterator outside the matrix."); +} + + + + +// ------------------------------------------------------------------- +// Method : "CDRGrid::iterator::set ()". + +CDRGrid::iterator &CDRGrid::iterator::set (int x, int y, int z) +{ + valid (false); + + _index = _drgrid->dx (0 , x); + _index = _drgrid->dy (_index, y); + _index = _drgrid->dz (_index, z); + + return ( *this ); +} + + + + +// ------------------------------------------------------------------- +// Method : "CDRGrid::iterator::dx ()". + +CDRGrid::iterator &CDRGrid::iterator::dx (int d) +{ + valid (false); + + _index = _drgrid->dx (_index, d); + + return ( *this ); +} + + + + +// ------------------------------------------------------------------- +// Method : "CDRGrid::iterator::dy ()". + +CDRGrid::iterator &CDRGrid::iterator::dy (int d) +{ + valid (false); + + _index = _drgrid->dy (_index, d); + + return ( *this ); +} + + + + +// ------------------------------------------------------------------- +// Method : "CDRGrid::iterator::dz ()". + +CDRGrid::iterator &CDRGrid::iterator::dz (int d) +{ + valid (false); + + _index = _drgrid->dz (_index, d); + + return ( *this ); +} + + + + +// ------------------------------------------------------------------- +// Accessor : "CDRGrid::iterator::pri". + +char &CDRGrid::iterator::pri (void) +{ + valid (false); + + return ( (*(_drgrid->pri))[*this] ); +} + + + + +// ------------------------------------------------------------------- +// Accessor : "CDRGrid::iterator::node". + +CNode &CDRGrid::iterator::node (void) +{ + valid (false); + + return ( (*(_drgrid->nodes))[*this] ); +} + + + + +// ------------------------------------------------------------------- +// Modifier : "CDRGrid::iterator::addnode ()". + +CNode &CDRGrid::iterator::addnode (void) +{ + valid (true); + + return ( _drgrid->nodes->add (this->_index) ); +} + + + + +// ------------------------------------------------------------------- +// Accessor : "CDRGrid::iterator::isnodehole ()". + +bool CDRGrid::iterator::isnodehole (void) +{ + return ( &(*_drgrid->nodes)[ *this ] == &(_drgrid->nodes->hole) ); +} + + + + +// ------------------------------------------------------------------- +// Accessor : "CDRGrid::iterator::isprihole ()". + +bool CDRGrid::iterator::isprihole (void) +{ + return ( &(*_drgrid->pri)[ *this ] == &(_drgrid->pri->hole) ); +} + + + + +// ------------------------------------------------------------------- +// Accessor : "CDRGrid::iterator::take ()". + +bool CDRGrid::iterator::take (int pri) +{ + valid(false); + + return (_drgrid->pri->take (pri, *this)); +} + + + + +// ------------------------------------------------------------------- +// Friend : "CDRGrid::iterator::operator<< ()". + +ostream &operator<< (ostream &o, CDRGrid::iterator &self) +{ + o << "it(_drgrid := " << self._drgrid + << ", _index := "; + + if (self._index != INT_MAX) { + o << self._index + << " (" << self.x() << "," << self.y() << "," << self.z() << ")"; + } else { + o << "INT_MAX )"; + } + + return ( o ); +} + + + + +// ------------------------------------------------------------------- +// Method : "CDRGrid::iterator::manhattan ()". + +int CDRGrid::iterator::manhattan (iterator &other) + throw (e_matrix_iterator) +{ + long manhattan; + + + valid (true); + other.valid (true); + + if (_drgrid != other._drgrid) + throw (e_matrix_iterator ("Attempt to use iterators from different grids.")); + + manhattan = abs (x() - other.x()) * _drgrid->cost_x_hor; + manhattan += abs (y() - other.y()) * _drgrid->cost_y_ver; + manhattan += abs (z() - other.z()) * _drgrid->cost_z; + + // As we never use ALU1 layer, add the cost of VIA. + if (z() == 0) manhattan += _drgrid->cost_z; + if (other.z() == 0) manhattan += _drgrid->cost_z; + + return (manhattan); +} + + + + +// ------------------------------------------------------------------- +// Constructor : "CDRGrid::CDRGrid()". + +CDRGrid::CDRGrid (int x, int y, int z) +{ + int index; + + + X = x; + Y = y; + Z = z; + XY = X * Y; + XYZ = XY * Z; + size = XY * (Z - 1); + + nodes = new CMatrixNodes (this); + pri = new CMatrixPri (this); + + cost_x_hor = cost_y_ver = cost_z = 1; + cost_x_ver = cost_y_hor = 2; + + // Reference iterator initialisation. + origin._drgrid = this; + origin._index = XY; +} + + + + +// ------------------------------------------------------------------- +// Destructor : "CDRGrid::~CDRGrid()". + +CDRGrid::~CDRGrid (void) +{ + delete nodes; + delete pri; +} + + + + +// ------------------------------------------------------------------- +// Modifier : "CDRGrid::costs ()". + +void CDRGrid::costs (int x_hor, int x_ver, int y_hor, int y_ver, int z) +{ + cost_x_hor = x_hor; + cost_x_ver = x_ver; + cost_y_hor = y_hor; + cost_y_ver = y_ver; + cost_z = z; +} + + + + +// ------------------------------------------------------------------- +// Modifier : "CDRGrid::dx ()". + +int CDRGrid::dx (int index, int d) +{ + if ( (index == INT_MAX) || (x(index) + d < 0) || (x(index) + d >= X) ) + return (INT_MAX); + + return (index + d); +} + + + + +// ------------------------------------------------------------------- +// Modifier : "CDRGrid::dy ()". + +int CDRGrid::dy (int index, int d) +{ + if ( (index == INT_MAX) || (y(index) + d < 0) || (y(index) + d >= Y) ) + return (INT_MAX); + + return (index + d*X); +} + + + + +// ------------------------------------------------------------------- +// Modifier : "CDRGrid::dz ()". + +int CDRGrid::dz (int index, int d) +{ + if ( (index == INT_MAX) || (z(index) + d < 0) || (z(index) + d >= Z) ) + return (INT_MAX); + + return (index + d*XY); +} + + + + +// ------------------------------------------------------------------- +// Destructor : "TMatrix::_CHollow::~_CHollow()". + +template +TMatrix<__CNode__>::_CHollow::~_CHollow (void) +{ + _CRow::iterator itRow; + _CLayer::iterator itLayer; + + + for (itLayer = nodes.begin (); + itLayer != nodes.end (); itLayer++) { + for (itRow = itLayer->second.begin (); + itRow != itLayer->second.end (); itRow++) { + delete itRow->second; + } + } +} + + + + +// ------------------------------------------------------------------- +// Method : "TMatrix::_CHollow::add()". + +template +__CNode__ &TMatrix<__CNode__>::_CHollow::add (int x, int y) +{ + _CRow::iterator itRow; + _CLayer::iterator itLayer; + + + itLayer = nodes.find (x); + if (itLayer == nodes.end ()) { nodes[x] = _CRow (); } + + itRow = nodes[x].find (y); + if (itRow == nodes[x].end ()) { nodes[x][y] = new __CNode__ (); } + + return (*(nodes[x][y])); +} + + + + +// ------------------------------------------------------------------- +// Method : "TMatrix::_CHollow::get()". + +template +__CNode__ *TMatrix<__CNode__>::_CHollow::get (int x, int y) +{ + _CRow::iterator itRow; + _CLayer::iterator itLayer; + + + itLayer = nodes.find (x); + if (itLayer == nodes.end ()) { return (NULL); } + + itRow = nodes[x].find (y); + if (itRow == nodes[x].end ()) { return (NULL); } + + return ((*itRow).second); +} + + + + +// ------------------------------------------------------------------- +// Constructor : "TMatrix::TMatrix()". + +template +TMatrix<__CNode__>::TMatrix (CDRGrid *drgrid) +{ + _drgrid = drgrid; + _grid = new (__CNode__) [_drgrid->size]; +} + + + + +// ------------------------------------------------------------------- +// Destructor : "~TMatrix::TMatrix()". + +template +TMatrix<__CNode__>::~TMatrix (void) +{ + delete [] _grid; +} + + + + +// ------------------------------------------------------------------- +// Accessor : "TMatrix::&operator[]". + +template +__CNode__ &TMatrix<__CNode__>::operator[] (int index) +{ + __CNode__ *node; + + + if (index < _drgrid->XY ) { + node = _zero.get (_drgrid->x(index), _drgrid->y(index)) ; + if ( node != NULL ) return ( *node ); + } else { + if (index < _drgrid->XYZ) return ( _grid[index - _drgrid->XY] ); + } + + return ( hole ); +} + + + + +// ------------------------------------------------------------------- +// Modifier : "TMatrix::add ()". + +template +__CNode__ &TMatrix<__CNode__>::add (int index) +{ + if (index < _drgrid->XY) { + return ( _zero.add (_drgrid->x(index), _drgrid->y(index)) ); + } else { + if (index < _drgrid->XYZ) return ( (*this)[index] ); + } + + return ( hole ); +} diff --git a/alliance/src/nero/src/MDefs.h b/alliance/src/nero/src/MDefs.h new file mode 100644 index 00000000..9a8e1674 --- /dev/null +++ b/alliance/src/nero/src/MDefs.h @@ -0,0 +1,639 @@ + +// -*- C++ -*- +// +// $Id: MDefs.h,v 1.1 2002/10/02 21:23:47 jpc Exp $ +// +// /-----------------------------------------------------------------\ +// | | +// | A l l i a n c e C A D S y s t e m | +// | S i m p l e R o u t e r | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : alliance-support@asim.lip6.fr | +// | =============================================================== | +// | C++ Header : "./MDefs.h" | +// | *************************************************************** | +// | U p d a t e s | +// | | +// \-----------------------------------------------------------------/ + + + + +# ifndef __MDefs__ +# define __MDefs__ 1 + + +# include "UDefs.h" + + + + +// ------------------------------------------------------------------- +// Class declarations. + + class CCoord; + class CNode; + class CNodeData; + class CMatrixPri; + class CMatrixNodes; + class CDRGrid; + class CNet; + + + + +// ------------------------------------------------------------------- +// Module : "MDRGrid.cpp". + + + // --------------------------------------------------------------- + // Rectangle class. + + struct CRect { + + // Attributes. + long x1; + long y1; + long x2; + long y2; + + // Friend. + friend ostream &operator<< (ostream &, const CRect *); + + }; + + + + + // --------------------------------------------------------------- + // Bounding Box class. + + class CBB { + + // Attributes. + public: int x1; + public: int y1; + public: int x2; + public: int y2; + public: int hp; + + // Constructor. + public: CBB (void); + + // Modifiers. + public: void merge (CCoord &coord); + + // Friends. + public: friend ostream &operator<< (ostream &o, CBB &self); + }; + + + + + // --------------------------------------------------------------- + // Coordinate class. + + class CCoord { + + public: int x; + public: int y; + public: int z; + + // Constructors. + public: CCoord (void) { x = y = z = 0; } + public: CCoord (int i, int j, int k) { x = i; y = j; z = k; } + + // Modifiers. + public: CCoord &set (int i, int j, int k) + { x = i; y = j; z = k; return (*this); } + + // Friends. + public: friend ostream &operator<< (ostream &o, CCoord &self) { + o << "(" << self.x + << "," << self.y + << "," << self.z << ")"; + + return (o); + } + + }; + + + + + // --------------------------------------------------------------- + // Matrix iterator exception class. + + class e_matrix_iterator : public except_done { + + // Attributes. + string message; + + // Constructor. + public: e_matrix_iterator (string msg) { message = msg; } + + // Destructor. + public: ~e_matrix_iterator (void) throw () { }; + + // Overridables. + public: const char* what () const throw () { return (message.c_str()); } + + }; + + + + + // --------------------------------------------------------------- + // Detailed Routing Matrix Class. + + template class TMatrix { + + // Matrix hollow level class --------------------------------- + + public: struct _CHollow { + + typedef map _CRow; + typedef map _CLayer; + + // Attributes. + public: _CLayer nodes; + + // Destructor. + ~_CHollow (void); + + // Modifier. + public: __CNode__ &add (int x, int y); + + // Accessor. + public: __CNode__ *get (int x, int y); + + }; + + + // Internal attributes. + public: CDRGrid *_drgrid; + public: _CHollow _zero; + public: __CNode__ *_grid; + public: __CNode__ hole; + + + // Constructor. + public: TMatrix (CDRGrid *drgrid); + + // Destructor. + public: ~TMatrix (void); + + // Accessors. + public: __CNode__ &operator[] (int index); + + // Modifiers. + public: __CNode__ &add (int index); + + }; + + + + + // --------------------------------------------------------------- + // Detailed Routing Grid Class. + + class CDRGrid { + + // Matrix common iterator class ------------------------------ + + public: class iterator { + + // Attributes. + public: int _index; + public: CDRGrid *_drgrid; + + // Constructors. + public: iterator (void); + public: iterator (const iterator &other); + + // Accessors. + public: operator int (void) { return ( _index ); } + public: operator CCoord (void) + { return ( CCoord (x(), y(), z()) ); } + public: bool operator== (iterator &other) + { return ( (_drgrid == other._drgrid) + && (_index == other._index ) ); } + + // Accessors for matrix objects. + public: char &pri (void); + public: bool isprihole (void); + public: CNode &node (void); + public: CNode &addnode (void); + public: bool isnodehole (void); + public: bool take (int pri); + + public: friend ostream &operator<< (ostream &o, iterator &self); + + public: void valid (bool validindex) throw (e_matrix_iterator); + public: int x (void) { return ( _drgrid->x (_index) ); } + public: int y (void) { return ( _drgrid->y (_index) ); } + public: int z (void) { return ( _drgrid->z (_index) ); } + public: bool outside (void) { return ( _index == INT_MAX ); } + public: bool inside (void) { return ( !outside() ); } + public: int manhattan (iterator &other) throw (e_matrix_iterator); + + // Modifiers. + public: void unlink (void) + { _index = INT_MAX; _drgrid = NULL; } + public: iterator &set (int x, int y, int z); + public: iterator &set (CCoord &coord) + { return ( set(coord.x, coord.y, coord.z) ); } + public: iterator &dx (int d); + public: iterator &dy (int d); + public: iterator &dz (int d); + public: iterator &left (void) { return ( dx(-1) ); }; + public: iterator &right (void) { return ( dx(+1) ); }; + public: iterator &down (void) { return ( dy(-1) ); }; + public: iterator &up (void) { return ( dy(+1) ); }; + public: iterator &bottom (void) { return ( dz(-1) ); }; + public: iterator &top (void) { return ( dz(+1) ); }; + + }; + + + // Matrix class ---------------------------------------------- + + // Attributes. + public: int X; + public: int Y; + public: int Z; + public: int XY; + public: int XYZ; + public: int size; + public: int cost_x_hor; + public: int cost_x_ver; + public: int cost_y_hor; + public: int cost_y_ver; + public: int cost_z; + + public: iterator origin; + public: CMatrixPri *pri; + public: CMatrixNodes *nodes; + + // Constructor. + public: CDRGrid (int x, int y, int z); + + // Destructor. + public: ~CDRGrid (void); + + // Modifiers. + 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); } + public: int y (int index) { return ((index / X ) % Y); } + public: int z (int index) { return ((index / XY) % Z); } + public: int dx (int index, int d); + public: int dy (int index, int d); + public: int dz (int index, int d); + public: int id (int x, int y, int z) + { return ( x + (X * (y + (Y * z))) ); } + + }; + + + + +// ------------------------------------------------------------------- +// Module : "MNodes.cpp". + + + // --------------------------------------------------------------- + // Node grabbing exception. + + class bad_grab : public except_done { + + // Attributes. + public: int x; + public: int y; + public: int z; + public: string ownerName; + public: string netName; + public: int pri; + public: int nodepri; + public: bool terminal; + public: int ident; + + // Constructor. + public: bad_grab ( string owner + , string net + , int i + , int j + , int k + , int p + , int np + , bool term + , int id + ) { + x = i; + y = j; + z = k; + pri = p; + nodepri = np; + terminal = term; + ident = id; + ownerName = owner; + netName = net; + } + + // Destructor. + public: ~bad_grab (void) throw () { }; + + // Overridables. + public: const char* what () const throw () { + return ((char*)"Attempt to grab a non-free node."); + } + + }; + + + + + // --------------------------------------------------------------- + // Node data class. + + class CNodeData { + + // Attributes. + public: int pri; + public: CNet *owner; + public: CNode *rtree; + public: int ident; + public: bool obstacle; + public: bool lock; + + // Constructor. + CNodeData (void); + + }; + + + + + // --------------------------------------------------------------- + // Node class. + + class CNode { + + // Attributes. + public: CNodeData data; + public: void *algo; + + // Constructor. + CNode (); + + // Modifiers. + public: inline int setid (int id) { return (data.ident = id + 1); } + public: void grab ( CNet *net + , int pri + , CDRGrid::iterator &coord + ) throw (bad_grab); + public: void ungrab (void); + public: void lock (void) { data.lock = true; } + public: void unlock (void) { data.lock = false; } + + // Accessors. + public: inline int getid (void) { return (data.ident - 1); } + public: inline bool terminal (void) { return (data.ident != 0); } + public: inline bool locked (void) { return (data.lock); } + public: bool check (void); + + }; + + + + + // --------------------------------------------------------------- + // Matrix Node class (derived from TMatrix template). + + class CMatrixNodes : public TMatrix { + + // Constructor. + public: CMatrixNodes (CDRGrid *drgrid) : TMatrix(drgrid) { } + + // Modifiers. + public: void obstacle (CRect &rect, int z); + public: void check (void); + + }; + + + + +// ------------------------------------------------------------------- +// Module : "MPri.cpp". + + + // --------------------------------------------------------------- + // Matrix Priority class (derived from TMatrix template). + + class CMatrixPri : public TMatrix { + + // Internal attributes. + protected: CBB _bb; + + // Attributes. + public: int offset; + public: int delta; + public: bool cleared; + + + // Constructor. + public: CMatrixPri (CDRGrid *drgrid) : TMatrix(drgrid) { } + + // Modifiers. + public: void clear (void); + public: void load (CNet &net, bool global, int expand=0); + public: bool take (int pri, int index); + public: void findfree (int index); + + // Internal methods. + private: char nextPri (char curpri); + + // Friends. + public: friend ostream &operator<< (ostream &o, CMatrixPri &self); + + }; + + + + +// ------------------------------------------------------------------- +// Module : "MNet.cpp". + + + // --------------------------------------------------------------- + // Duplicate terminal node exception. + + class dup_term : public except_done { + + // Attributes. + public: string name; + public: CDRGrid::iterator node; + + // Constructor. + public: dup_term (string termName, CDRGrid::iterator &dupNode) { + name = termName; + node = dupNode; + } + + // Destructor. + public: ~dup_term (void) throw () { }; + + // Overridables. + public: const char* what () const throw () { + return ((char*)"Duplicated terminal node."); + } + }; + + + + + // --------------------------------------------------------------- + // Terminal class. + + class CTerm { + + // Attributes. + public: int id; + public: string name; + public: list nodes; + public: list rects; + + // Constructor. + public: CTerm (string termName, int ident); + + // Destructor. + public: ~CTerm (void); + + // Accessors. + public: int distance (CTerm &other); + public: CTerm &nearest (CTerm &term1, CTerm &term2); + public: CDRGrid::iterator &lowest (void); + + // Modifiers. + public: CNode *newaccess (int x, int y, int z, int ident, CNet *net) throw (dup_term); + public: void newaccess (CRect &rect, int z, int ident, CNet *net); + public: void lockalone (bool global=false); + public: void setid (int ident); + + // Friends. + public: friend ostream &operator<< (ostream &o, CTerm &self); + + }; + + + + + // --------------------------------------------------------------- + // Duplicate net exception. + + class dup_net : public except_done { + + // Attributes. + public: string name; + + // Constructor. + public: dup_net (string netName) { name = netName; } + + // Destructor. + public: ~dup_net (void) throw () { }; + + // Overridables. + public: const char* what () const throw () { + return ((char*)"Duplicated net."); + } + }; + + + + + // --------------------------------------------------------------- + // Unknown terminal exception. + + class term_unknown : public except_done { + + // Attributes. + public: string netName; + public: string termName; + + // Constructor. + public: term_unknown (string nName, string tName) { + netName = nName; + termName = tName; + } + + // Destructor. + public: ~term_unknown (void) throw () { }; + + // Overridables. + public: virtual const char* what () const throw () { + return ((char*)"Unkown terminal."); + } + }; + + + + + // --------------------------------------------------------------- + // Net class. + + class CNet { + + // Attributes. + public: int pri; + public: string name; + public: vector terms; + public: CNode* rtree; + public: CBB bb; + public: int size; + public: bool external; + public: CDRGrid *_drgrid; + + // Constructor. + public: CNet (CDRGrid *drgrid, string netName="noname"); + + // Destructor. + public: ~CNet (void); + + // Operator. + public: bool operator< (CNet &other); + + // Accessor. + public: bool global (void) { return (bb.hp >= D::GLOBAL_HP); } + + // Modifiers. + public: void newaccess (string termName, int x, int y, int z); + public: void newaccess (string termName, CRect &rect, int z); + public: void order (void); + public: void lockalone (void); + public: void locktree (void); + public: void unroute (void); + + // Friends. + public: friend ostream &print (ostream &o, CNet *self); + public: friend ostream &operator<< (ostream &o, CNet *self); + + }; + + typedef map MNet; + + + + +// ------------------------------------------------------------------- +// Module : "MMBK.h". + + +# include "MMBK.h" + + + + +#endif diff --git a/alliance/src/nero/src/MMBK.cpp b/alliance/src/nero/src/MMBK.cpp new file mode 100644 index 00000000..e1f44fed --- /dev/null +++ b/alliance/src/nero/src/MMBK.cpp @@ -0,0 +1,1080 @@ + +// -*- C++ -*- +// +// $Id: MMBK.cpp,v 1.1 2002/10/02 21:23:47 jpc Exp $ +// +// /-----------------------------------------------------------------\ +// | | +// | A l l i a n c e C A D S y s t e m | +// | S i m p l e R o u t e r | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : alliance-support@asim.lip6.fr | +// | =============================================================== | +// | C++ Module : "./UMBK.cpp" | +// | *************************************************************** | +// | U p d a t e s | +// | | +// \-----------------------------------------------------------------/ + + + + +# include "MDefs.h" + + + + +// ------------------------------------------------------------------- +// MBK namespace. + +namespace MBK { + + + // --------------------------------------------------------------- + // Pre-defined objects. + + // The creation of this object loads the MBK environment. + CEnv env; + + + + +// /----------------------------------------------------------------\ +// | Methods Definitions | +// \----------------------------------------------------------------/ + + +// ------------------------------------------------------------------- +// Constructor : "CXRect::CXRect()". + +CXRect::CXRect (long xab1, long yab1) +{ + XAB1 = xab1; + YAB1 = yab1; +} + + + + +// ------------------------------------------------------------------- +// Method : "CXRect::setSeg()". + +void CXRect::setSeg (phseg_list &rSeg) +{ + seg.NAME = rSeg.NAME; + seg.LAYER = rSeg.LAYER; + seg.WIDTH = rSeg.WIDTH; + seg.X1 = rSeg.X1; + seg.Y1 = rSeg.Y1; + seg.X2 = rSeg.X2; + seg.Y2 = rSeg.Y2; + seg.TYPE = rSeg.TYPE; + + seg2rect (); + rect2grid (); +} + + + + +// ------------------------------------------------------------------- +// Method : "CXRect::seg2rect()". + +void CXRect::seg2rect (void) +{ + long width; + + + width = env.layer2width (seg.LAYER); + + // Special case of "point like" segments. + if ((seg.X1 == seg.X2) && (seg.Y1 == seg.Y2)) { + rect.x1 = seg.X1; + rect.y1 = seg.Y1; + rect.x2 = seg.X2; + rect.y2 = seg.Y2; + + return; + } + + switch (seg.TYPE) { + case UP: + case DOWN: + rect.x1 = seg.X1 - (seg.WIDTH - width) / 2; + rect.x2 = seg.X2 + (seg.WIDTH - width) / 2; + rect.y1 = seg.Y1; + rect.y2 = seg.Y2; + break; + case LEFT: + case RIGHT: + default: + rect.x1 = seg.X1; + rect.x2 = seg.X2; + rect.y1 = seg.Y1 - (seg.WIDTH - width) / 2; + rect.y2 = seg.Y2 + (seg.WIDTH - width) / 2; + break; + } +} + + + + +// ------------------------------------------------------------------- +// Method : "CXRect::rect2grid()". + +void CXRect::rect2grid (void) +{ + grid.x1 = (rect.x1 - XAB1) / env.grid_dx; + grid.y1 = (rect.y1 - YAB1) / env.grid_dy; + + grid.x2 = (rect.x2 - XAB1) / env.grid_dx; + grid.y2 = (rect.y2 - YAB1) / 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; +} + + + + +// ------------------------------------------------------------------- +// Function (friend CXRect) : "operator<<()". + +ostream &operator<< (ostream &o, const CXRect *rect) +{ + o << "+ CXRect::seg (" + << rect->seg.X1 << ", " + << rect->seg.Y1 << "), (" + << rect->seg.X2 << ", " + << rect->seg.Y2 << ")\n"; + + o << "+ CXRect::rect(" << &(rect->rect) << ")\n"; + o << "+ CXRect::grid(" << &(rect->grid) << ")\n"; + + return (o); +} + + + + +// ------------------------------------------------------------------- +// Constructor : "CEnv::CEnv()". + +CEnv::CEnv (void) +{ + // Load the UNIX environmment for MBK. + mbkenv (); + + // Copy constants values from constants namespace ("D::"). + // Routing constants, loaded now that we have SCALE_X. + D::X_GRID = ::MBK::SCALE (D::_X_GRID); + D::Y_GRID = ::MBK::SCALE (D::_Y_GRID); + D::WIDTH_VSS = ::MBK::SCALE (D::_WIDTH_VSS); + D::WIDTH_VDD = ::MBK::SCALE (D::_WIDTH_VDD); + D::Y_SLICE = ::MBK::SCALE (D::_Y_SLICE); + D::TRACK_WIDTH_ALU1 = ::MBK::SCALE (D::_TRACK_WIDTH_ALU1); + D::TRACK_WIDTH_ALU2 = ::MBK::SCALE (D::_TRACK_WIDTH_ALU2); + D::TRACK_WIDTH_ALU3 = ::MBK::SCALE (D::_TRACK_WIDTH_ALU3); + D::TRACK_WIDTH_ALU4 = ::MBK::SCALE (D::_TRACK_WIDTH_ALU4); + D::TRACK_WIDTH_ALU5 = ::MBK::SCALE (D::_TRACK_WIDTH_ALU5); + D::TRACK_WIDTH_ALU6 = ::MBK::SCALE (D::_TRACK_WIDTH_ALU6); + + // Grid spacing. + grid_dx = D::X_GRID; + grid_dy = D::Y_GRID; + + // Layers minimal width. + ALU2W[ALU1] = D::TRACK_WIDTH_ALU1; + ALU2W[ALU2] = D::TRACK_WIDTH_ALU2; + ALU2W[ALU3] = D::TRACK_WIDTH_ALU3; + ALU2W[ALU4] = D::TRACK_WIDTH_ALU4; + ALU2W[ALU5] = D::TRACK_WIDTH_ALU5; + ALU2W[ALU6] = D::TRACK_WIDTH_ALU6; + ALU2W[CALU1] = D::TRACK_WIDTH_ALU1; + ALU2W[CALU2] = D::TRACK_WIDTH_ALU2; + ALU2W[CALU3] = D::TRACK_WIDTH_ALU3; + ALU2W[CALU4] = D::TRACK_WIDTH_ALU4; + ALU2W[CALU5] = D::TRACK_WIDTH_ALU5; + ALU2W[CALU6] = D::TRACK_WIDTH_ALU6; + ALU2W[TALU1] = D::TRACK_WIDTH_ALU1; + ALU2W[TALU2] = D::TRACK_WIDTH_ALU2; + ALU2W[TALU3] = D::TRACK_WIDTH_ALU3; + ALU2W[TALU4] = D::TRACK_WIDTH_ALU4; + ALU2W[TALU5] = D::TRACK_WIDTH_ALU5; + ALU2W[TALU6] = D::TRACK_WIDTH_ALU6; + + // Layer to Z translation table. + ALU2Z[ALU1] = 0; + ALU2Z[ALU2] = 1; + ALU2Z[ALU3] = 2; + ALU2Z[ALU4] = 3; + ALU2Z[ALU5] = 4; + ALU2Z[ALU6] = 5; + ALU2Z[CALU1] = 0; + ALU2Z[CALU2] = 1; + ALU2Z[CALU3] = 2; + ALU2Z[CALU4] = 3; + ALU2Z[CALU5] = 4; + ALU2Z[CALU6] = 5; + ALU2Z[TALU1] = 0; + ALU2Z[TALU2] = 1; + ALU2Z[TALU3] = 2; + ALU2Z[TALU4] = 3; + ALU2Z[TALU5] = 4; + ALU2Z[TALU6] = 5; +} + + + + +// ------------------------------------------------------------------- +// Method : "CEnv::layer2width()". + +long CEnv::layer2width (char layer) throw (except_done) +{ + MLayer::iterator itLayer; + + + if ((itLayer = ALU2W.find (layer)) == ALU2W.end ()) { + cerr << herr ("CEnv::layer2width ():\n"); + cerr << " Layer id " << (int)layer << " is not supported.\n"; + throw except_done (); + } + + return (itLayer->second); +} + + + + +// ------------------------------------------------------------------- +// Method : "CEnv::layer2z()". + +long CEnv::layer2z (char layer) throw (except_done) +{ + MLayer::iterator itLayer; + + + if ((itLayer = ALU2Z.find (layer)) == ALU2Z.end ()) { + cerr << herr ("CEnv::layer2z ():\n"); + cerr << " Layer id " << (int)layer << " is not supported.\n"; + throw except_done (); + } + + return (itLayer->second); +} + + + + +// ------------------------------------------------------------------- +// Method : "CEnv::z2alu()". + +char CEnv::z2alu (int z) throw (except_done) +{ + MLayer::iterator itLayer, endLayer; + + + endLayer = ALU2Z.end (); + for (itLayer = ALU2Z.begin(); itLayer != endLayer; itLayer++) { + if (isALU(itLayer->first) && (itLayer->second == z)) + return (itLayer->first); + } + + cerr << herr ("CEnv::z2alu ():\n"); + cerr << " Z index " << z << " is out of bound.\n"; + + throw except_done (); +} + + + + +// ------------------------------------------------------------------- +// Method : "CEnv::z2calu()". + +char CEnv::z2calu (int z) throw (except_done) +{ + MLayer::iterator itLayer, endLayer; + + + endLayer = ALU2Z.end (); + for (itLayer = ALU2Z.begin(); itLayer != endLayer; itLayer++) { + if (isCALU(itLayer->first) && (itLayer->second == z)) + return (itLayer->first); + } + + cerr << herr ("CEnv::z2calu ():\n"); + cerr << " Z index " << z << " is out of bound.\n"; + + throw except_done (); +} + + + + +// ------------------------------------------------------------------- +// Method : "CEnv::z2via()". + +char CEnv::z2via (int z) throw (except_done) +{ + char viaType; + + + switch (z) { + case 1: viaType = CONT_VIA; break; + case 2: viaType = CONT_VIA2; break; + case 3: viaType = CONT_VIA3; break; + case 4: viaType = CONT_VIA4; break; + case 5: viaType = CONT_VIA5; break; + case 6: viaType = CONT_VIA6; break; + default: + cerr << herr ("CEnv::z2via ():\n"); + cerr << " Z index " << z << " is out of bound.\n"; + throw except_done (); + } + + return (viaType); +} + + + + +// ------------------------------------------------------------------- +// Friend of "CEnv" : "&operator<<()". + +ostream &operator<< (ostream &o, const CEnv &self) +{ + int i; + + o << "\n" + << " o MBK environment :\n\n" + << " MBK_IN_LO := " << IN_LO << "\n" + << " MBK_OUT_LO := " << OUT_LO << "\n" + << " MBK_IN_PH := " << IN_PH << "\n" + << " MBK_OUT_PH := " << OUT_PH << "\n" + << " MBK_WORK_LIB := " << WORK_LIB << "\n"; + + for(i = 0; CATA_LIB[i] != (char *)NULL; i++) { + if (i == 0) o << " MBK_CATA_LIB := "; + else o << " "; + o << CATA_LIB[i] << "\n"; + } + + o << " MBK_CATAL_NAME := " << CATAL << "\n" + << " MBK_VDD := " << VDD << "\n" + << " MBK_VSS := " << VSS << "\n" + << " MBK_SEPAR := " << SEPAR << "\n" + << "\n"; + + return (o); +} + + + + +// ------------------------------------------------------------------- +// Constructor : "CLofig::CLofig()". + +CLofig::CLofig (string &name) +{ + loins_list *pLoins; + losig_list *pLosig; + + + cmess1 << " o Loading netlist \"" << name << "\"...\n"; + fig = getlofig ((char *)name.c_str (), 'A'); + + // Build the instances dictionnary (map). + for (pLoins = fig->LOINS; pLoins != NULL; pLoins = pLoins->NEXT) { + instances[pLoins->INSNAME] = pLoins; + } + + // Build the signal dictionnary. + for (pLosig = fig->LOSIG; pLosig != NULL; pLosig = pLosig->NEXT) { + signals[getsigname(pLosig)] = pLosig; + } +} + + + + +// ------------------------------------------------------------------- +// Destructor : "~CLofig::CLofig()". + +CLofig::~CLofig (void) +{ + dellofig (fig->NAME); +} + + + + +// ------------------------------------------------------------------- +// Method : "CLofig::rflatten()". + +void CLofig::rflatten (char concat=YES, char catal=YES) +{ + loins_list *pLoins; + + + cmess2 << " o Flattening netlist...\n"; + rflattenlofig (fig, concat, catal); + + // Rebuild the instances dictionnary (map). + instances.clear (); + for (pLoins = fig->LOINS; pLoins != NULL; pLoins = pLoins->NEXT) { + instances[pLoins->INSNAME] = pLoins; + } +} + + + + +// ------------------------------------------------------------------- +// Method : "CLofig::chain()". + +void CLofig::chain (void) +{ + cmess2 << " o Building netlist dual representation (lofigchain)...\n"; + lofigchain (fig); +} + + + + +// ------------------------------------------------------------------- +// Method : "CLofig::save()". + +void CLofig::save (void) +{ + cmess1 << " o Saving netlist \"" << fig->NAME << "\"...\n"; + savelofig (fig); +} + + + + +// ------------------------------------------------------------------- +// Method : "CLofig::saveas()". + +void CLofig::saveas (string &name) +{ + char *current_name; + + cmess1 << " o Saving netlist as \"" << name << "\"...\n"; + + current_name = fig->NAME; + fig->NAME = namealloc ((char*)name.c_str ()); + + savelofig (fig); + + fig->NAME = current_name; +} + + + + +// ------------------------------------------------------------------- +// Constructor : "CPhfig::CPhfig()". + +CPhfig::CPhfig (string &name) +{ + phins_list *pPhins; + + + cmess1 << " o Loading layout \"" << name << "\"...\n"; + fig = getphfig ((char *)name.c_str (), 'A'); + + // Build the instances dictionnary (map). + for (pPhins = fig->PHINS; pPhins != NULL; pPhins = pPhins->NEXT) { + instances[pPhins->INSNAME] = pPhins; + } +} + + + + +// ------------------------------------------------------------------- +// Destructor : "~CPhfig::CPhfig()". + +CPhfig::~CPhfig (void) +{ + delphfig (fig->NAME); +} + + + + +// ------------------------------------------------------------------- +// Method : "CPhfig::rflatten()". + +void CPhfig::rflatten (char concat=YES, char catal=YES) +{ + phins_list *pPhins; + + + cmess2 << " o Flattening layout...\n"; + rflattenphfig (fig, concat, catal); + + // Rebuild the instances dictionnary (map). + instances.clear (); + for (pPhins = fig->PHINS; pPhins != NULL; pPhins = pPhins->NEXT) { + instances[pPhins->INSNAME] = pPhins; + } +} + + + + +// ------------------------------------------------------------------- +// Method : "CPhfig::onslice()". + +bool CPhfig::onslice (long Y) +{ + 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); + + return (false); +} + + + + +// ------------------------------------------------------------------- +// Method : "CPhfig::save()". + +void CPhfig::save (void) +{ + cmess1 << " o Saving layout \"" << fig->NAME << "\"...\n"; + savephfig (fig); +} + + + + +// ------------------------------------------------------------------- +// Method : "CPhfig::saveas()". + +void CPhfig::saveas (string &name) +{ + char *current_name; + + cmess1 << " o Saving layout as \"" << name << "\"...\n"; + + current_name = fig->NAME; + fig->NAME = namealloc ((char*)name.c_str ()); + + savephfig (fig); + + fig->NAME = current_name; +} + + + + +// ------------------------------------------------------------------- +// Constructor : "CIns::CIns()". + +CIns::CIns ( loins_list *lo + , phins_list *ph + , phfig_list *mod=NULL + , phfig_list *fig=NULL + ) +{ + loins = lo; + phins = ph; + model = mod; + phfig = fig; +} + + + + +// ------------------------------------------------------------------- +// Method : "CIns::getmodel()". + +phfig_list *CIns::getmodel (void) +{ + if (!model) model = getphfig (phins->FIGNAME, 'A'); + + return (model); +} + + + + +// ------------------------------------------------------------------- +// Method : "CIns::flatseg()". + +phseg_list &CIns::flatseg (phseg_list &flatSeg, phseg_list &seg) +{ + flatSeg.NAME = seg.NAME; + flatSeg.LAYER = seg.LAYER; + flatSeg.WIDTH = seg.WIDTH; + + + xyflat ( &flatSeg.X1, &flatSeg.Y1 + , seg.X1, seg.Y1 + , phins->XINS, phins->YINS + , model->XAB1, model->YAB1 + , model->XAB2, model->YAB2 + , phins->TRANSF + ); + + xyflat ( &flatSeg.X2 , &flatSeg.Y2 + , seg.X2 , seg.Y2 + , phins->XINS, phins->YINS + , model->XAB1, model->YAB1 + , model->XAB2, model->YAB2 + , phins->TRANSF + ); + + // Ensure that (X1,Y1) < (X2,Y2) and type is correct. + if (flatSeg.X1 > flatSeg.X2) { swap (flatSeg.X1, flatSeg.X2); } + if (flatSeg.Y1 > flatSeg.Y2) { swap (flatSeg.Y1, flatSeg.Y2); } + + if (flatSeg.Y1 == flatSeg.Y2) { + if (flatSeg.X1 < flatSeg.X2) flatSeg.TYPE = LEFT; + else flatSeg.TYPE = RIGHT; + } else { + if (flatSeg.Y1 < flatSeg.Y2) flatSeg.TYPE = UP; + else flatSeg.TYPE = DOWN; + } + + // Return the flattened segment; + return (flatSeg); +} + + + + +// ------------------------------------------------------------------- +// Constructor : "CFig::CFig()". + +CFig::CFig (string &nameLofig, string &namePhfig) throw (except_done): + lofig (nameLofig), phfig (namePhfig) +{ + MLoins::iterator itLoins, endLoins; + MPhins::iterator itPhins, endPhins; + long errors; + + + // Flatten both views & build dual representation. + phfig.rflatten (); + lofig.rflatten (); + lofig.chain (); + + cmess2 << " o Binding logical & physical views...\n"; + + errors = 0; + endLoins = lofig.instances.end (); + endPhins = phfig.instances.end (); + + // Match loins with phins. + for (itLoins = lofig.instances.begin(); itLoins != endLoins; itLoins++) { + // Find the matched phins. + itPhins = phfig.instances.find (itLoins->first); + + if (itPhins == endPhins) { + errors += 1; + + cerr << herr (""); + cerr << " logical instance \"" << itLoins->second->INSNAME << "\""; + cerr << " of model \"" << itLoins->second->FIGNAME << "\""; + cerr << " doesn't appear in physical view.\n"; + continue; + } + + instances[itLoins->first] = new CIns ( itLoins->second + , itPhins->second + , NULL + , phfig.fig + ); + } + + // If the match is not complete, do a reverse one to find + // unmatched phins (mostly feedthrough cells). + if ( (errors > 0) + || ( lofig.instances.size() != phfig.instances.size() ) ) { + for (itPhins = phfig.instances.begin(); itPhins != endPhins; itPhins++) { + // Add feedthrough cells to the orphan list. + if (incatalogfeed (itPhins->second->FIGNAME) != 0) { + orphans[itPhins->first] = new CIns ( NULL + , itPhins->second + , NULL + , this->phfig.fig + ); + + continue; + } + + // Find the matched loins. + itLoins = lofig.instances.find (itPhins->first); + + if (itLoins == endLoins) { + errors += 1; + + cerr << herr (""); + cerr << " physical instance \"" << itPhins->second->INSNAME << "\""; + cerr << " of model \"" << itPhins->second->FIGNAME << "\""; + cerr << " doesn't appear in logical view."; + continue; + } + } + } + + // The nelist and lofig doesn't match. + if (errors > 0) throw except_done (); +} + + + + +// ------------------------------------------------------------------- +// Destructor : "CFig::~CFig()". + +CFig::~CFig (void) +{ + MIns::iterator itIns, beginIns, endIns; + + + cmess2 << " o Deleting CFig..."; + + // Delete the CIns structures used in the map. + endIns = instances.end (); + for (itIns = instances.begin(); itIns != endIns; itIns++) + delete itIns->second; + + endIns = orphans.end (); + for (itIns = orphans.begin(); itIns != endIns; itIns++) + delete itIns->second; +} + + + + +// ------------------------------------------------------------------- +// Method : "CFig::addphseg()". + +void CFig::addphseg (phseg_list &seg) +{ + MBK::addphseg ( phfig.fig + , seg.LAYER + , seg.WIDTH + , seg.X1 + , seg.Y1 + , seg.X2 + , seg.Y2 + , seg.NAME + ); +} + + +// ------------------------------------------------------------------- +// Method : "CFig::addphvia()". + +void CFig::addphvia (phvia_list &VIA) +{ + MBK::addphvia ( phfig.fig + , VIA.TYPE + , VIA.XVIA + , VIA.YVIA + , VIA.DX + , VIA.DY + , VIA.NAME + ); +} + + +// ------------------------------------------------------------------- +// Method : "CFig::addphcon()". + +void CFig::addphcon (phcon_list &con) +{ + MBK::addphcon ( phfig.fig + , con.ORIENT + , con.NAME + , con.XCON + , con.YCON + , con.LAYER + , con.WIDTH + ); +} + + + + +// ------------------------------------------------------------------- +// Function : "layer2a()". + +extern char *layer2a(char layer) +{ + switch (layer) { + case ALU1: return ("ALU1"); + case ALU2: return ("ALU2"); + case ALU3: return ("ALU3"); + case ALU4: return ("ALU4"); + case ALU5: return ("ALU5"); + case ALU6: return ("ALU6"); + case ALU7: return ("ALU7"); + case ALU8: return ("ALU8"); + case ALU9: return ("ALU9"); + case CALU1: return ("CALU1"); + case CALU2: return ("CALU2"); + case CALU3: return ("CALU3"); + case CALU4: return ("CALU4"); + case CALU5: return ("CALU5"); + case CALU6: return ("CALU6"); + case CALU7: return ("CALU7"); + case CALU8: return ("CALU8"); + case CALU9: return ("CALU9"); + case TALU1: return ("TALU1"); + case TALU2: return ("TALU2"); + case TALU3: return ("TALU3"); + case TALU4: return ("TALU4"); + case TALU5: return ("TALU5"); + case TALU6: return ("TALU6"); + case TALU7: return ("TALU7"); + case TALU8: return ("TALU8"); + case TALU9: return ("TALU9"); + } + + return ("unknown layer"); +} + + + + +// ------------------------------------------------------------------- +// Function : "isobs()". + +extern bool isobs(char layer) +{ + switch (layer) { + case TALU1: + case TALU2: + case TALU3: + case TALU4: + case TALU5: + case TALU6: + case TALU7: + case TALU8: + case TALU9: + return (true); + } + + return (false); +} + + + + +// ------------------------------------------------------------------- +// Function : "isALU()". + +extern bool isALU(char layer) +{ + switch (layer) { + case ALU1: + case ALU2: + case ALU3: + case ALU4: + case ALU5: + case ALU6: + case ALU7: + case ALU8: + case ALU9: return (true); + } +} + + + + +// ------------------------------------------------------------------- +// Function : "isCALU()". + +bool isCALU (char layer) +{ + switch (layer) { + case CALU1: + case CALU2: + case CALU3: + case CALU4: + case CALU5: + case CALU6: + case CALU7: + case CALU8: + case CALU9: return (true); + } + + + return (false); +} + + + + +// ------------------------------------------------------------------- +// Function : "layer2CALU()". + +char layer2CALU (char layer) +{ + switch (layer) { + case ALU1: + case TALU1: + return (CALU1); + case ALU2: + case TALU2: + return (CALU2); + case ALU3: + case TALU3: + return (CALU3); + case ALU4: + case TALU4: + return (CALU4); + case ALU5: + case TALU5: + return (CALU5); + case ALU6: + case TALU6: + return (CALU6); + case TALU7: + case ALU7: + return (CALU7); + case TALU8: + case ALU8: + return (CALU8); + case TALU9: + case ALU9: + return (CALU9); + } + + return (CALU1); +} + + + + +// ------------------------------------------------------------------- +// Function : "layer2ALU()". + +char layer2ALU (char layer) +{ + switch (layer) { + case ALU1: + case CALU1: + case TALU1: + return (ALU1); + case ALU2: + case CALU2: + case TALU2: + return (ALU2); + case ALU3: + case CALU3: + case TALU3: + return (ALU3); + case ALU4: + case CALU4: + case TALU4: + return (ALU4); + case ALU5: + case CALU5: + case TALU5: + return (ALU5); + case ALU6: + case CALU6: + case TALU6: + return (ALU6); + case TALU7: + case CALU7: + case ALU7: + return (ALU7); + case TALU8: + case CALU8: + case ALU8: + return (ALU8); + case TALU9: + case CALU9: + case ALU9: + return (ALU9); + } + + return (CALU1); +} + + + + + +// ------------------------------------------------------------------- +// Function : "cmpALU()". + +long cmpALU (char layer1, char layer2) +{ + switch(layer1) { + case ALU1: + switch(layer2) { + case ALU1: return(F_EQUAL_M); + case CALU1: return(F_EQUAL_C); + case TALU1: return(F_EQUAL_T); + } + break; + + case ALU2: + switch(layer2) { + case ALU2: return(F_EQUAL_M); + case CALU2: return(F_EQUAL_C); + case TALU2: return(F_EQUAL_T); + } + break; + + case ALU3: + switch(layer2) { + case ALU3: return(F_EQUAL_M); + case CALU3: return(F_EQUAL_C); + case TALU3: return(F_EQUAL_T); + } + break; + + case ALU4: + switch(layer2) { + case ALU4: return(F_EQUAL_M); + case CALU4: return(F_EQUAL_C); + case TALU4: return(F_EQUAL_T); + } + break; + + case ALU5: + switch(layer2) { + case ALU5: return(F_EQUAL_M); + case CALU5: return(F_EQUAL_C); + case TALU5: return(F_EQUAL_T); + } + break; + + case ALU6: + switch(layer2) { + case ALU6: return(F_EQUAL_M); + case CALU6: return(F_EQUAL_C); + case TALU6: return(F_EQUAL_T); + } + break; + } + + return(0); +} + + + + +// ------------------------------------------------------------------- +// End of MBK namespace. + +} diff --git a/alliance/src/nero/src/MMBK.h b/alliance/src/nero/src/MMBK.h new file mode 100644 index 00000000..e77e42e6 --- /dev/null +++ b/alliance/src/nero/src/MMBK.h @@ -0,0 +1,358 @@ + +// -*- C++ -*- +// +// $Id: MMBK.h,v 1.1 2002/10/02 21:23:47 jpc Exp $ +// +// /-----------------------------------------------------------------\ +// | | +// | A l l i a n c e C A D S y s t e m | +// | S i m p l e R o u t e r | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : alliance-support@asim.lip6.fr | +// | =============================================================== | +// | C++ Header : "./UMBK.h" | +// | *************************************************************** | +// | U p d a t e s | +// | | +// \-----------------------------------------------------------------/ + + + + +#ifndef __UMBK__ +#define __UMBK__ 1 + + + +// ------------------------------------------------------------------- +// MBK namespace. + +namespace MBK { + +# include +# include +# include +# include +# include +# include +# include +# include +# include + + + + +// ------------------------------------------------------------------- +// Module : "UMBK.cpp". + + + // --------------------------------------------------------------- + // Constants. + + + +# define F_EQUAL (1L) +# define F_CALU (2L) +# define F_TALU (4L) +# define F_EQUAL_M (F_EQUAL) +# define F_EQUAL_C (F_EQUAL | F_CALU) +# define F_EQUAL_T (F_EQUAL | F_TALU) + + + + + // --------------------------------------------------------------- + // Types. + + typedef map MLoins; + typedef map MLosig; + typedef map MPhins; + typedef map MLayer; + + + + + // --------------------------------------------------------------- + // Inline functions. + + inline long SCALE (long x) { return (x * SCALE_X); } + inline long UNSCALE (long x) { return (x / SCALE_X); } + inline char *ISVSS (char *s) { return (instr ((s), VSS, SEPAR)); } + inline char *ISVDD (char *s) { return (instr ((s), VDD, SEPAR)); } + + + + + // --------------------------------------------------------------- + // Functions. + + extern char *layer2a (char layer); + extern bool isobs (char layer); + extern bool isALU(char layer); + extern bool isCALU(char layer); + extern char layer2ALU(char layer); + extern char layer2CALU(char layer); + extern long cmpALU(char layer1, char layer2); + + + + // --------------------------------------------------------------- + // Extended rectangle class. + + 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). + + // Contructor. + public: CXRect (long xab1, long yab1); + + // Modifiers. + public: void setSeg (phseg_list &rSeg); + private: void seg2rect (void); + private: void rect2grid (void); + + // Friend. + friend ostream &operator<< (ostream &, const CXRect *); + + }; + + + + + // --------------------------------------------------------------- + // MBK env wrapper class. + + struct CEnv { + + // Attributes. + long grid_dx; + long grid_dy; + MLayer ALU2W; + MLayer ALU2Z; + + // Constructor. + CEnv (void); + + // Accessors. + long layer2width (char layer) throw (except_done); + long layer2z (char layer) throw (except_done); + char z2calu (int z) throw (except_done); + char z2alu (int z) throw (except_done); + char z2via (int z) throw (except_done); + long z2width (int z) { return (layer2width (z2alu(z))); } + + + // Friends. + friend ostream &operator<< (ostream &o, const CEnv &self); + }; + + + + + // --------------------------------------------------------------- + // MBK Loins wrapper class. + + struct CLofig { + + // Attributes. + lofig_list *fig; + MLoins instances; + MLosig signals; + + // Constructor. + CLofig (string &name); + + // Destructor. + ~CLofig (void); + + // Modifiers. + void rflatten (char concat=YES, char catal=YES); + void chain (void); + void save (void); + void saveas (string &name); + + }; + + + + + // --------------------------------------------------------------- + // MBK Phfig wrapper class. + + struct CPhfig { + + // Attributes. + phfig_list *fig; + MPhins instances; + + // Constructor. + CPhfig (string &name); + + // Destructor. + ~CPhfig (void); + + // Modifiers. + void rflatten (char concat=YES, char catal=YES); + bool onslice (long Y); + void save (void); + void saveas (string &name); + + }; + + + + + // --------------------------------------------------------------- + // MBK loins+phins+model wrapper class. + + struct CIns { + + // Attributes. + loins_list *loins; + phins_list *phins; + phfig_list *model; + phfig_list *phfig; + + // Constructor. + CIns ( loins_list *lo + , phins_list *ph + , phfig_list *mod=NULL + , phfig_list *fig=NULL + ); + + // Accessor. + phseg_list &flatseg (phseg_list &flatSeg, phseg_list &seg); + + // Modifier. + phfig_list *getmodel (void); + + }; + + + typedef map MIns; + + + + + // --------------------------------------------------------------- + // MBK lofig+phfig wrapper class. + + struct CFig { + + // Attributes. + CLofig lofig; + CPhfig phfig; + MIns instances; + MIns orphans; + + // Constructor. + CFig (string &nameLofig, string &namePhfig) throw (except_done); + + // Destructor. + ~CFig (void); + + // Accessors. + long XAB1 (void) { return (phfig.fig->XAB1); } + long YAB1 (void) { return (phfig.fig->YAB1); } + long XAB2 (void) { return (phfig.fig->XAB2); } + long YAB2 (void) { return (phfig.fig->YAB2); } + losig_list *LOSIG (void) { return (lofig.fig->LOSIG); } + + // Modifiers. + void addphseg (phseg_list &seg); + void addphvia (phvia_list &VIA); + void addphcon (phcon_list &con); + + }; + + + + // --------------------------------------------------------------- + // Pre-defined objects. + + // The creation of this object loads the MBK environment. + extern CEnv env; + + + + +// ------------------------------------------------------------------- +// Module : "UPower.cpp". + + + // --------------------------------------------------------------- + // Constants. + + +# define C_POWER_NONE ((char)0) +# define C_POWER_VDD ((char)1) +# define C_POWER_VSS ((char)2) +# define C_VERTICAL ((char)1) +# define C_HORIZONTAL ((char)2) + + + + + // --------------------------------------------------------------- + // Power line class. + + struct CPower : public LInter { + + // Attributes. + long type; + + // Constructors. + CPower (void); + + // Friends. + friend ostream &operator<< (ostream &o, const CPower &self); + + }; + + typedef map LPower; + + + + + // --------------------------------------------------------------- + // Power line set class. + + struct CPowers { + + // Attributes. + char type; + char layer; + long width; + long AB1; + long AB2; + LPower powerLines; + + // Constructor. + CPowers (CFig*, char, int, long) throw (except_done); + + // Methods. + void dump (CFig *fig); + + // Friends. + friend ostream &operator<< (ostream &o, CPowers &self); + + }; + + typedef map MPowers; + + + + +// ------------------------------------------------------------------- +// End of MBK namespace. + +} + + +#endif diff --git a/alliance/src/nero/src/MNet.cpp b/alliance/src/nero/src/MNet.cpp new file mode 100644 index 00000000..b06b628c --- /dev/null +++ b/alliance/src/nero/src/MNet.cpp @@ -0,0 +1,518 @@ + +// -*- C++ -*- +// +// $Id: MNet.cpp,v 1.1 2002/10/02 21:23:47 jpc Exp $ +// +// /----------------------------------------------------------------\ +// | | +// | A l l i a n c e C A D S y s t e m | +// | S i m p l e R o u t e r | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : alliance-support@asim.lip6.fr | +// | ============================================================== | +// | C++ Module : "./MNet.cpp" | +// | ************************************************************** | +// | U p d a t e s | +// | | +// \----------------------------------------------------------------/ + + + + +# include "MDefs.h" + + + + +// /----------------------------------------------------------------\ +// | Methods Definitions | +// \----------------------------------------------------------------/ + + +// ------------------------------------------------------------------- +// Constructor : "CTerm::CTerm()". + +CTerm::CTerm (string termName, int ident) +{ + id = ident; + name = termName; +} + + + + +// ------------------------------------------------------------------- +// Destructor : "CTerm::~CTerm()". + +CTerm::~CTerm (void) +{ + //list::iterator pNode; + + + //for (pNode = nodes.begin (); pNode != nodes.end (); pNode++) { + // if ((*pNode)->coord.z() == 0) delete (*pNode); + //} + + nodes.clear (); +} + + + + +// ------------------------------------------------------------------- +// Method : "CTerm::distance()". + +int CTerm::distance (CTerm &other) +{ + list::iterator itNode1, itNode2, endNode1, endNode2; + + int minimum; + + + minimum = INT_MAX; + endNode1 = nodes.end (); + endNode2 = other.nodes.end (); + + for (itNode1 = nodes.begin (); itNode1 != endNode1; itNode1++) { + for (itNode2 = other.nodes.begin (); itNode2 != endNode2; itNode2++) { + minimum = min (minimum, (*itNode1).manhattan (*itNode2)); + } + } + + return (minimum); +} + + + + +// ------------------------------------------------------------------- +// Method : "CTerm::nearest()". + +CTerm &CTerm::nearest (CTerm &term1, CTerm &term2) +{ + if (distance(term1) < distance(term2)) return (term1); + + return (term2); +} + + + + +// ------------------------------------------------------------------- +// Method : "CTerm::lowest()". + +CDRGrid::iterator &CTerm::lowest (void) +{ + list::iterator itNode, itLowest; + CDRGrid::iterator Top; + + int lowpri; + + + itNode = nodes.begin (); + itLowest = itNode; + + if ( !(*itNode).z() ) lowpri = (*itNode).pri (); + else lowpri = INT_MAX; + + // Find the lowest priority node above the terminals. + for (; itNode != nodes.end (); itNode++) { + if ( !(*itNode).z() ) { + Top = *itNode; + Top.top (); + + if (Top.pri() < lowpri) { + itLowest = itNode; + lowpri = Top.pri (); + } + } + } + + return (*itLowest); +} + + + + +// ------------------------------------------------------------------- +// Method : "CTerm::newaccess()". + +CNode *CTerm::newaccess (int x, int y, int z, int ident, CNet *net) throw (dup_term) +{ + list::iterator itNode; + CDRGrid::iterator coord; + + CNode *pNode; + + + coord = net->_drgrid->origin; + coord.set (x, y, z); + + // Check if the node is already in the list... + for (itNode = nodes.begin (); itNode != nodes.end (); itNode++) { + if (*itNode == coord) { + throw dup_term (name, *itNode); + } + } + + pNode = &coord.node (); + if ((z == 0) && coord.isnodehole()) { + pNode = &coord.addnode (); + } + + pNode->data.owner = net; + pNode->setid (ident); + nodes.push_back (coord); + + return (pNode); +} + + + + +// ------------------------------------------------------------------- +// Method : "CTerm::newaccess()". + +void CTerm::newaccess (CRect &rect, int z, int ident, CNet *net) +{ + int x, y; + + + for (x = rect.x1; x <= rect.x2; x++) { + for (y = rect.y1; y <= rect.y2; y++) { + newaccess (x, y, z, ident, net); + } + } + + if (z > 0) return; + + // Only z=0 rectangles are stored (ALU1 is not in the grid). + //if ((rect.x1 != rect.x2) || (rect.y1 != rect.y2)) + // No! Store all ALU1 rectangles. + rects.push_back (rect); +} + + + + +// ------------------------------------------------------------------- +// Method : "CTerm::lockalone()". + +void CTerm::lockalone (bool global=false) +{ + CDRGrid::iterator coord; + int zCoord, zMax, z; + + + if (nodes.size() != 1) return; + + coord = nodes.back (); + zCoord = coord.z(); + zMax = min(coord._drgrid->Z - 1, 3); + + if ( (zCoord > 0) && !global ) return; + + for (z = (global) ? zMax : 1; z > zCoord; z--) { + newaccess ( coord.x() + , coord.y() + , z + , coord.node().getid() + , coord.node().data.owner + ); + } +} + + + + +// ------------------------------------------------------------------- +// Method : "CTerm::setid()". + +void CTerm::setid (int ident) +{ + list::iterator itNode; + + + id = ident; + + // Reset the id on all the nodes. + for (itNode = nodes.begin (); itNode != nodes.end (); itNode++) { + (*itNode).node().setid (ident); + } +} + + + + +// ------------------------------------------------------------------- +// Friend : "operator<<()". + +ostream &operator<< (ostream &o, CTerm &self) +{ + list::iterator endPoint, itPoint; + + + o << " term \"" << self.name << "\", id := " << self.id << " :\n"; + + endPoint = self.nodes.end (); + for (itPoint = self.nodes.begin (); itPoint != endPoint; itPoint++) + o << " " << *itPoint << "\n"; + + return (o); +} + + + + +// ------------------------------------------------------------------- +// Constructor : "CNet::CNet()". + +CNet::CNet (CDRGrid *drgrid, string netName="noname") +{ + name = netName; + external = false; + pri = 0; + size = 0; + rtree = NULL; + _drgrid = drgrid; +} + + + + +// ------------------------------------------------------------------- +// Destructor : "CNet::~CNet()". + +CNet::~CNet (void) +{ + int i; + + + for (i = 0; i < size; i++) { + delete (terms[i]); + } +} + + + + +// ------------------------------------------------------------------- +// Operator : "CNet::operator<()". + +bool CNet::operator< (CNet &other) +{ + return (this->bb.hp > other.bb.hp); +} + + + + +// ------------------------------------------------------------------- +// Method : "CNet::newaccess()". + +void CNet::newaccess (string termName, int x, int y, int z) +{ + CRect rect; + + + rect.x1 = rect.x2 = x; + rect.y1 = rect.y2 = y; + + newaccess (termName, rect, z); +} + + + + +// ------------------------------------------------------------------- +// Method : "CNet::newaccess()". + +void CNet::newaccess (string termName, CRect &rect, int z) +{ + CCoord coord; + int id; + + + // Find the terminal in the table. + for (id = 0; id < size; id++) { + if (terms[id]->name.compare (termName)) continue; + + break; + } + + // Terminal not found : add a new one. + if (id == size) { + terms.push_back (new CTerm (termName, size)); + size += 1; + } + + // Add the access to the terminal & update the bounding box. + terms[id]->newaccess (rect, z, id, this); + + // Update the bounding box. + bb.merge (coord.set (rect.x1, rect.y1, z)); + bb.merge (coord.set (rect.x2, rect.y2, z)); + +} + + + + + +// ------------------------------------------------------------------- +// Method : "CNet::lockalone()". + +void CNet::lockalone (void) +{ + int id; + + + for (id = 0; id < size; id++) terms[id]->lockalone (global()); +} + + + + + +// ------------------------------------------------------------------- +// Method : "CNet::locktree()". + +void CNet::locktree (void) +{ + CNode *node; + + + for (node = rtree; node != NULL; node = node->data.rtree) node->lock (); +} + + + + + +// ------------------------------------------------------------------- +// Method : "CNet::order()". + +void CNet::order (void) +{ + vector::iterator itTerm, endTerm, itUnord, endUnord, itNearest; + vector unordered; + int ident; + + + // Do not sort less than 3 terminals. + if (size < 3) return; + + ident = 0; + + terms.swap (unordered); + terms.push_back (unordered.back()); + unordered.pop_back (); + + terms[ident]->setid (ident); ident++; + + while (unordered.size() > 0) { + endTerm = terms.end (); + endUnord = unordered.end (); + + for (itTerm = terms.begin(); itTerm != endTerm; itTerm++) { + itNearest = unordered.begin (); + itUnord = itNearest + 1; + + for (; itUnord != endUnord; itUnord++) { + if ( (*itTerm)->distance (*(*itUnord)) + < (*itTerm)->distance (*(*itNearest))) + itNearest = itUnord; + } + } + + terms.push_back (*itNearest); + unordered.erase ( itNearest); + + terms[ident]->setid (ident); ident++; + } +} + + + + + +// ------------------------------------------------------------------- +// Method : "CNet::unroute()". + +void CNet::unroute (void) +{ + CNode *node, *next_node; + + + node = rtree; + while (node != NULL) { + next_node = node->data.rtree; + + node->ungrab (); + + node = next_node; + } + + rtree = NULL; +} + + + + +// ------------------------------------------------------------------- +// Friend : "print()". + +ostream &print (ostream &o, CNet *self) +{ + CDRGrid::iterator coord; + int x, y, z, layer; + + + coord = self->_drgrid->origin; + + o << " +"; + for (x = 1; x <= self->_drgrid->X; x++) o << "-"; + o << "+\n"; + + for (y = 1; y <= self->_drgrid->Y; y++) { + o << " |"; + for (x = 0; x < self->_drgrid->X; x++) { + layer = 0; + + for (z = 1; z < self->_drgrid->Z; z++) { + coord.set (x, self->_drgrid->Y - y, z); + if (coord.node().data.owner == self) + layer = z + 1; + } + + if (layer) o << (char)('A' + layer - 1); + else o << ' '; + } + o << "|\n"; + } + + o << " +"; + for (x = 0; x < self->_drgrid->X; x++) o << "-"; + o << "+\n"; + + return (o); +} + + + + +// ------------------------------------------------------------------- +// Friend : "operator<<()". + +ostream &operator<< (ostream &o, CNet *self) +{ + int id; + + + o << "net \"" << self->name << "\", size := " << self->size << " :\n"; + + for (id = 0; id < self->size; id++) o << *( self->terms[id] ); + + return (o); +} diff --git a/alliance/src/nero/src/MNodes.cpp b/alliance/src/nero/src/MNodes.cpp new file mode 100644 index 00000000..e69e283a --- /dev/null +++ b/alliance/src/nero/src/MNodes.cpp @@ -0,0 +1,127 @@ + +// -*- C++ -*- +// +// $Id: MNodes.cpp,v 1.1 2002/10/02 21:23:47 jpc Exp $ +// +// /----------------------------------------------------------------\ +// | | +// | A l l i a n c e C A D S y s t e m | +// | S i m p l e R o u t e r | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : alliance-support@asim.lip6.fr | +// | ============================================================== | +// | C++ Module : "./MNodes.cpp" | +// | ************************************************************** | +// | U p d a t e s | +// | | +// \----------------------------------------------------------------/ + + + + +# include "MDefs.h" + + + + +// /----------------------------------------------------------------\ +// | Methods Definitions | +// \----------------------------------------------------------------/ + + +// ------------------------------------------------------------------- +// Constructor : "CNodeData::CNodeData()". + +CNodeData::CNodeData (void) +{ + pri = 0; + + owner = NULL; + rtree = NULL; + ident = 0; + obstacle = false; + lock = false; +} + + + + +// ------------------------------------------------------------------- +// Constructor : "CNode::CNode()". + +CNode::CNode (void) +{ + algo = NULL; +} + + + + +// ------------------------------------------------------------------- +// Method : "CNode::grab()". + +void CNode::grab (CNet *net, int pri, CDRGrid::iterator &coord) + throw (bad_grab) +{ + if (data.owner && (data.owner != net)) + throw bad_grab ( data.owner->terms[getid()]->name + , net->name + , coord.x() + , coord.y() + , coord.z() + , pri + , data.pri + , terminal() + , data.ident + ); + + // Update the net tree chaining datas. + data.rtree = net->rtree; + net->rtree = this; + + data.owner = net; + data.pri = pri; +} + + + + +// ------------------------------------------------------------------- +// Method : "CNode::ungrab()". + +void CNode::ungrab (void) +{ + + if (!terminal ()) { + data.owner = NULL; + data.rtree = NULL; + } + data.pri = 0; +} + + + + +// ------------------------------------------------------------------- +// Modifier : "CMatrixNodes::obstacle()". + +void CMatrixNodes::obstacle (CRect &rect, int z) +{ + CDRGrid::iterator coord; + int x, y, X, Y; + + + if (!z) return; + + coord = _drgrid->origin; + + X = (_drgrid->X == rect.x2) ? rect.x2 - 1 : rect.x2; + Y = (_drgrid->Y == rect.y2) ? rect.y2 - 1 : rect.y2; + + for (x = rect.x1; x <= X; x++) { + for (y = rect.y1; y <= Y; y++) { + (*this)[ coord.set (x, y, z) ].data.obstacle = true; + } + } +} diff --git a/alliance/src/nero/src/MPower.cpp b/alliance/src/nero/src/MPower.cpp new file mode 100644 index 00000000..3520c352 --- /dev/null +++ b/alliance/src/nero/src/MPower.cpp @@ -0,0 +1,375 @@ + +// -*- C++ -*- +// +// $Id: MPower.cpp,v 1.1 2002/10/02 21:23:48 jpc Exp $ +// +// /-----------------------------------------------------------------\ +// | | +// | A l l i a n c e C A D S y s t e m | +// | S i m p l e R o u t e r | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : alliance-support@asim.lip6.fr | +// | =============================================================== | +// | C++ Module : "./UPower.cpp" | +// | *************************************************************** | +// | U p d a t e s | +// | | +// \-----------------------------------------------------------------/ + + + + +# include "MDefs.h" + + + + +// ------------------------------------------------------------------- +// MBK namespace. + +namespace MBK { + + +// /----------------------------------------------------------------\ +// | Methods Definitions | +// \----------------------------------------------------------------/ + + +// ------------------------------------------------------------------- +// Constructor : "CPower::CPower ()". + +CPower::CPower (void) +{ + type = 0; +} + + + + +// ------------------------------------------------------------------- +// Function (friend "CPower") : "operator<< ()". + +ostream &operator<< (ostream &o, CPower &self) +{ + LInter *inter; + + + if (self.type == C_POWER_VDD) o << "vdd "; + else o << "vss "; + + inter = static_cast(&self); + + return (o << *inter); +} + + + + +// ------------------------------------------------------------------- +// Constructor : "CPowers::CPowers ()". + +CPowers::CPowers ( CFig *fig + , char atype + , int alayer + , long awidth + ) throw (except_done) +{ + LPower::iterator itLine, beginLine, endLine; + phins_list *ins; + phfig_list *model; + phseg_list *seg, flatSeg; + string mess1, mess2; + char ORIENT1, ORIENT2; + char segType; + long lbound, rbound, key; + + + type = atype; + width = awidth; + layer = layer2CALU (alayer); + + switch (type) { + default: + case C_HORIZONTAL: + mess1 = "horizontal"; + mess2 = "EAST/WEST"; + ORIENT1 = EAST; + ORIENT2 = WEST; + + AB1 = fig->XAB1 (); + AB2 = fig->XAB2 (); + break; + case C_VERTICAL: + mess1 = "vertical"; + mess2 = "NORTH/SOUTH"; + ORIENT1 = NORTH; + ORIENT2 = SOUTH; + + AB1 = fig->YAB1 (); + AB2 = fig->YAB2 (); + break; + } + + + // Loop over all the instances. + for (ins = fig->phfig.fig->PHINS; ins != NULL; ins = ins->NEXT) { + model = getphfig (ins->FIGNAME, 'A'); + + // Find the power segments (CALUx). + for (seg = model->PHSEG; seg != NULL; seg = seg->NEXT) { + + // Skip no power segments. + if (!(cmpALU (alayer, seg->LAYER) & F_CALU)) continue; + segType = C_POWER_NONE; + if (ISVDD (seg->NAME)) segType = C_POWER_VDD; + if (ISVSS (seg->NAME)) segType = C_POWER_VSS; + if (segType == C_POWER_NONE) continue; + + xyflat ( &(flatSeg.X1), &(flatSeg.Y1) + , seg->X1, seg->Y1 + , ins->XINS, ins->YINS + , model->XAB1, model->YAB1 + , model->XAB2, model->YAB2 + , ins->TRANSF + ); + + xyflat ( &(flatSeg.X2), &(flatSeg.Y2) + , seg->X2, seg->Y2 + , ins->XINS, ins->YINS + , model->XAB1, model->YAB1 + , model->XAB2, model->YAB2 + , ins->TRANSF + ); + + // Check the segment width. + if (seg->WIDTH != width) { + cerr << hwarn (""); + cerr << " " << layer2a (layer) << " \"" << flatSeg.NAME + <<"\" segment at (" + << UNSCALE (seg->X1) << "," + << UNSCALE (seg->Y1) << ") doesn't have the rigth witdth :" + << UNSCALE (seg->WIDTH) << " instead of " + << UNSCALE (width) << ".\n"; + cerr << " (instance \"" << ins->INSNAME << "\" of model \"" + << model->NAME << "\")\n"; + + continue; + } + + // Check the segment direction & position. + switch (type) { + default: + case C_HORIZONTAL: + lbound = flatSeg.X1; + rbound = flatSeg.X2; + key = flatSeg.Y1; + + if (flatSeg.Y1 != flatSeg.Y2) { + cerr << hwarn (""); + cerr << " " << layer2a (layer) << " \"" << flatSeg.NAME + <<"\" segment at (" + << UNSCALE (seg->X1) << "," + << UNSCALE (seg->Y1) << ") is not " << mess1; + cerr << " (instance \"" << ins->INSNAME << "\" of model \"" + << model->NAME << "\")\n"; + + continue; + } + + if ( (cmpALU (alayer, CALU1) & F_CALU) + && !fig->phfig.onslice (flatSeg.Y1)) { + cerr << hwarn (""); + cerr << " " << layer2a (layer) << " \"" << flatSeg.NAME + <<"\" segment at (" + << UNSCALE (seg->X1) << "," + << UNSCALE (seg->Y1) << ") is not on a slice boundary.\n"; + cerr << " (instance \"" << ins->INSNAME << "\" of model \"" + << model->NAME << "\")\n"; + cerr << " (valide slices boundaries are" + << " ((n * " << D::Y_SLICE << ") - " << D::WIDTH_VSS / 2 << ") or" + << " ((n * " << D::Y_SLICE << ") + " << D::WIDTH_VSS / 2 << ") )\n"; + + continue; + } + break; + + case C_VERTICAL: + lbound = flatSeg.Y1; + rbound = flatSeg.Y2; + key = flatSeg.X1; + + if (flatSeg.X1 != flatSeg.X2) { + cerr << hwarn (""); + cerr << " " << layer2a (layer) << " \"" << flatSeg.NAME + <<"\" segment at (" + << UNSCALE (seg->X1) << "," + << UNSCALE (seg->Y1) << ") is not " << mess1; + cerr << " (instance \"" << ins->INSNAME << "\" of model \"" + << model->NAME << "\")\n"; + + continue; + } + break; + } + + + beginLine = powerLines.begin (); + endLine = powerLines.end (); + + + // Check if the power line is of the same type. + // (no short circuits between VDD & VSS. + itLine = powerLines.find (key); + if (itLine != endLine) { + if (itLine->second.type != segType) { + cerr << herr (""); + cerr << " " << layer2a (layer) << " \"" << flatSeg.NAME + <<"\" segment at (" + << UNSCALE (seg->X1) << "," + << UNSCALE (seg->Y1) << ") conflict with power line at" + << UNSCALE (key) << ".\n"; + + throw except_done (); + } + } + + + // Merge the segment with the power line (at long last...). + powerLines[key].add (lbound, rbound); + powerLines[key].type = segType; + } + } +} + + + + +// ------------------------------------------------------------------- +// Method : "CPowers::dump ()". + +void CPowers::dump (CFig *fig) +{ + LPower::iterator itLine, beginLine, endLine; + LInter::iterator iInter, beginInter, endInter; + phseg_list seg; + phcon_list con1, con2; + + + seg.LAYER = layer; + seg.WIDTH = width; + con1.LAYER = MBK::layer2ALU(layer); + con1.WIDTH = width; + con2.LAYER = MBK::layer2ALU(layer); + con2.WIDTH = width; + + beginLine = powerLines.begin (); + endLine = powerLines.end (); + + // Transform power lines into CALUx segments. + for (itLine = beginLine; itLine != endLine; itLine++) { + beginInter = itLine->second.begin (); + endInter = itLine->second.end (); + + for (iInter = beginInter; iInter != endInter; iInter++) { + switch (itLine->second.type) { + default: + case C_POWER_VDD: seg.NAME = (char*)"vdd"; break; + case C_POWER_VSS: seg.NAME = (char*)"vss"; break; + } + con1.NAME = seg.NAME; + con1.ORIENT = (char)0; + con2.NAME = seg.NAME; + con2.ORIENT = (char)0; + + switch (this->type) { + default: + case C_HORIZONTAL: + seg.X1 = iInter->first; + seg.X2 = iInter->second; + seg.Y1 = itLine->first; + seg.Y2 = itLine->first; + + // Add power terminals at end of power lines. + if (iInter->first == AB1) { + con1.XCON = AB1; + con1.YCON = itLine->first; + con1.ORIENT = WEST; + } + + if (iInter->second == AB2) { + con2.XCON = AB2; + con2.YCON = itLine->first; + con2.ORIENT = EAST; + } + + break; + case C_VERTICAL: + seg.X1 = itLine->first; + seg.X2 = itLine->first; + seg.Y1 = iInter->first; + seg.Y2 = iInter->second; + break; + + // Add power terminals at end of power lines. + if (iInter->first == AB1) { + con1.XCON = itLine->first; + con1.YCON = AB1; + con1.ORIENT = SOUTH; + } + + if (iInter->second == AB2) { + con2.XCON = itLine->first; + con2.YCON = AB2; + con2.ORIENT = NORTH; + } + } + + fig->addphseg (seg); + + if (con1.ORIENT != (char)0) fig->addphcon (con1); + if (con2.ORIENT != (char)0) fig->addphcon (con2); + } + } + + cdebug << *this; +} + + + + +// ------------------------------------------------------------------- +// Friend of "CPowers" : "&operator<<()". + +ostream &operator<< (ostream &o, CPowers &self) +{ + LPower::iterator itLine, beginLine, endLine; + + + o << "+ CPowers:\n"; + o << "+ "; + + if (self.type == C_HORIZONTAL) o << "horizontal"; + else o << "vertical "; + + o << " " << layer2a (self.layer) << " " << UNSCALE (self.width); + o << " [" << UNSCALE (self.AB1) + << "," << UNSCALE (self.AB2) << "]\n"; + + beginLine = self.powerLines.begin (); + endLine = self.powerLines.end (); + + for (itLine = beginLine; itLine != endLine; itLine++) { + o << "+ " << itLine->first << " " << itLine->second << "\n"; + } + + return (o); +} + + + + +// ------------------------------------------------------------------- +// End of MBK namespace. + +} diff --git a/alliance/src/nero/src/MPri.cpp b/alliance/src/nero/src/MPri.cpp new file mode 100644 index 00000000..389f8b89 --- /dev/null +++ b/alliance/src/nero/src/MPri.cpp @@ -0,0 +1,300 @@ + +// -*- C++ -*- +// +// $Id: MPri.cpp,v 1.1 2002/10/02 21:23:48 jpc Exp $ +// +// /----------------------------------------------------------------\ +// | | +// | A l l i a n c e C A D S y s t e m | +// | S i m p l e R o u t e r | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : alliance-support@asim.lip6.fr | +// | ============================================================== | +// | C++ Module : "./MPri.cpp" | +// | ************************************************************** | +// | U p d a t e s | +// | | +// \----------------------------------------------------------------/ + + + + +# include "MDefs.h" + + + + +// /----------------------------------------------------------------\ +// | Methods Definitions | +// \----------------------------------------------------------------/ + + +// ------------------------------------------------------------------- +// Method : "CMatrixPri::findfree()". + +void CMatrixPri::findfree (int index) +{ + CDRGrid::iterator coord; + int radius, i, j, cx, cy; + bool freed; + + + freed = false; + radius = 0; + cx = _drgrid->x(index); + cy = _drgrid->y(index); + coord = _drgrid->origin; + + while (!freed) { + radius += 1; + + for (i = cx - radius; i < cx + radius + 1; i++) { + for (j = cy - radius; j < cy + radius + 1; j++) { + // Proccess only nodes of the ring. + // if ( (i > cx - radius) || (i < cx + radius) ) continue; + // if ( (j > cy - radius) || (j < cy + radius) ) continue; + + if ( !( (*_drgrid->nodes)[ coord.set(i,j,2) ].data.obstacle ) ) freed = true; + + (*this)[ coord.set(i,j,1) ] = (char)1; + (*this)[ coord.set(i,j,2) ] = (char)1; + } + } + } +} + + + + +// ------------------------------------------------------------------- +// Method : "CMatrixPri::clear()". + +void CMatrixPri::clear (void) +{ + memset (_grid, (char)0, _drgrid->size); + + cleared = true; + offset = 0; + delta = 0; +} + + + + +// ------------------------------------------------------------------- +// Method : "CMatrixPri::nextPri()". + +char CMatrixPri::nextPri (char curpri) +{ + return ((curpri > 1) ? (curpri >> 1) : 1); +} + + + + +// ------------------------------------------------------------------- +// Method : "CMatrixPri::load()". + +void CMatrixPri::load (CNet &net, bool global, int expand=0) +{ + list::iterator itNode, beginNode, endNode; + queue queue1, queue2; + queue *currentBorder, *nextBorder; + CDRGrid::iterator *pCoord, coord; + + char currentPri, *pmap; + int x, y, z, nx, ny, nz, edge, id, ex, ey; + bool breakLoop; + + + clear (); + + offset = net.pri; + delta = 0; + + currentBorder = &queue1; + nextBorder = &queue2; + currentPri = 64; + + + // Expand the original BB if too small. + ex = 0; + ey = 0; + + if (net.bb.x2 - net.bb.x1 < 5) ex = 5; + if (net.bb.y2 - net.bb.y1 < 5) ey = 5; + + if (expand) ex = ey = expand; + + _bb.x1 = max (0 , net.bb.x1 - ex); + _bb.x2 = min (_drgrid->X - 1, net.bb.x2 + ex); + _bb.y1 = max (0 , net.bb.y1 - ey); + _bb.y2 = min (_drgrid->Y - 1, net.bb.y2 + ey); + + + // Build the initials border lists : coordinates of the terminals. + // The table doesn't have a z = 0 layer (never used for routing), + // so when a terminal on layer 0 is encountered, we queue the + // the coordinate on top in the next border queue. + // That is, in the first step of the algorithm we fill both queue + // at the same time. + // In the case of the map of a global signal (i.e. using z=3&4 for + // the time beeing, set to one the map points above the terminal + // in z=1&2, as they will not be set by the _bb loop. + + for (id = 0; id < net.size; id++) { + beginNode = (net.terms[id])->nodes.begin (); + endNode = (net.terms[id])->nodes.end (); + + for (itNode = beginNode; itNode != endNode; itNode++) { + coord = *itNode; + + // Initial queues filling. + if (coord.z() > 0) { + (*this)[ coord ] = currentPri; + currentBorder->push (new CDRGrid::iterator (coord)); + + // Enable z=1 (in case of global signal, no effet otherwise). + if (coord.z() < _drgrid->Z - 1) (*this)[ coord.dz(1) ] = (char)1; + + continue; + } + + (*this)[ coord.dz(1) ] = nextPri (currentPri); + nextBorder->push (new CDRGrid::iterator (coord)); + + // Enable z=2 (in case of global signal, no effet otherwise). + (*this)[ coord.dz(1) ] = (char)1; + + // Look if the upper node is blocked, in that case expand the + // allowed zone till a non-blocked node is found. + + if ( (*_drgrid->nodes)[ coord ].data.obstacle ) findfree (coord); + } + } + + + // Set to one all the points inside the enclosing box. + // (except those in the initial queues) + for (x = _bb.x1; x <= _bb.x2; x++) { + for (y = _bb.y1; y <= _bb.y2; y++) { + for (z = (global) ? 3 : 1; z < _drgrid->Z; z++) { + pmap = & ( (*this)[ coord.set (x, y, z) ] ); + if (pmap && (!(*pmap))) *pmap = (char)1; + } + } + } + + + breakLoop = false; + currentPri = nextPri (currentPri); + + // And here we go! + while (true) { + // Checks if the current border is finished. If so swap it with the + // nextBorder. If the current border is still empty, we are done. + if (currentBorder->empty ()) { + currentPri = nextPri (currentPri); + swap (currentBorder, nextBorder); + + if (currentBorder->empty ()) { + breakLoop = true; + } + } + if (breakLoop) break; + + pCoord = currentBorder->front (); + currentBorder->pop (); + + x = pCoord->x (); + y = pCoord->y (); + z = pCoord->z (); + + delete pCoord; + + for (edge = 0; edge < 6; edge++) { + nx = x; ny = y; nz =z; + + // Look at all six neighbors. + switch (edge) { + case 0: nx -= 1; break; + case 1: nx += 1; break; + case 2: ny -= 1; break; + case 3: ny += 1; break; + case 4: nz -= 1; break; + case 5: nz += 1; break; + } + + pmap = & ( (*this)[ coord.set (nx, ny, nz) ] ); + if (pmap == &(this->hole)) { continue; } + + // Usable nodes have been set to at least one, if not skip it. + if ( (pmap == NULL) || (*pmap == (char)0) ) continue; + + if (*pmap == (char)1) { + *pmap = currentPri; + // Push only nodes that are not of minimal priority. + if (currentPri > (char)1) + nextBorder->push (new CDRGrid::iterator (coord)); + } + } + + } + + + cleared = false; +} + + + + +// ------------------------------------------------------------------- +// Method : "CMatrixPri::take()". + +bool CMatrixPri::take (int pri, int index) +{ + char *mappri; + + + mappri = &(*this)[index]; + + if (mappri == &hole) return (false); + if (!*mappri) return (false); + if (!pri) return (true); + + return (pri + 256 < *mappri + delta); +} + + + + +// ------------------------------------------------------------------- +// Friend : "&operator<<()". + +ostream &operator<< (ostream &o, CMatrixPri &self) +{ + CDRGrid::iterator coord; + int x, y, z; + + o << "cleared := " << self.cleared << "\n" + << "offset := " << self.offset << "\n" + << "delta := " << self.delta << "\n"; + + coord = self._drgrid->origin; + + for (z = 1; z < self._drgrid->Z; z++) { + o << " (layer) z := " << z << "\n"; + + for (y = 1; y <= self._drgrid->Y; y++) { + o << " "; + for (x = 0; x < self._drgrid->X; x++) { + o << setw(5) << (int)(self[ + coord.set (x, self._drgrid->Y - y, z)]); + } + o << "\n"; + } + } + + return (o); +} diff --git a/alliance/src/nero/src/Makefile.am b/alliance/src/nero/src/Makefile.am new file mode 100644 index 00000000..008c4505 --- /dev/null +++ b/alliance/src/nero/src/Makefile.am @@ -0,0 +1,69 @@ +## Process this file with automake to produce Makefile.in + +#CXXFLAGS = -g -pg -O2 +CXXFLAGS = -g -O2 +#CXXFLAGS = -O2 +AM_CXXFLAGS = @ALLIANCE_CFLAGS@ +AM_CFLAGS = @ALLIANCE_CFLAGS@ + + +bin_PROGRAMS = nero pdv +#noinst_PROGRAMS = debug + +nero_LDADD = @ALLIANCE_LIBS@ \ + $(top_builddir)/src/libU.a \ + -lMpu -lMlu \ + -lMcl -lMcp \ + -lMal -lMap \ + -lMsl \ + -lMel -lMgl \ + -lMhl \ + -lMvg \ + -lMmg \ + -lMlo \ + -lMph -lMut \ + -lRcn \ + -lAut + +noinst_LIBRARIES = libU.a + + +libU_a_SOURCES = UConst.cpp \ + USys.cpp \ + UOpts.cpp \ + UInter.cpp \ + UDefs.h \ + MMBK.cpp \ + MPower.cpp \ + MMBK.h \ + MDRGrid.cpp \ + MNodes.cpp \ + MPri.cpp \ + MNet.cpp \ + MDefs.h \ + AAstar.cpp \ + ASimple.cpp \ + ADefs.h \ + RBox.cpp \ + RMBK.cpp \ + RDefs.h + +nero_SOURCES = nero.cpp + +pdv_LDADD = @ALLIANCE_LIBS@ \ + -lMpu -lMlu \ + -lMcl -lMcp \ + -lMal -lMap \ + -lMsl \ + -lMel -lMgl \ + -lMhl \ + -lMvg \ + -lMmg \ + -lMlo \ + -lMph -lMut \ + -lRcn \ + -lAut + +pdv_SOURCES = pdv.c + +#debug_SOURCES = debug.cpp diff --git a/alliance/src/nero/src/RBox.cpp b/alliance/src/nero/src/RBox.cpp new file mode 100644 index 00000000..e439b949 --- /dev/null +++ b/alliance/src/nero/src/RBox.cpp @@ -0,0 +1,205 @@ + +// -*- C++ -*- +// +// $Id: RBox.cpp,v 1.1 2002/10/02 21:23:48 jpc Exp $ +// +// /----------------------------------------------------------------\ +// | | +// | A l l i a n c e C A D S y s t e m | +// | S i m p l e R o u t e r | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : alliance-support@asim.lip6.fr | +// | ============================================================== | +// | C++ Module : "./RBox.cpp" | +// | ************************************************************** | +// | U p d a t e s | +// | | +// \----------------------------------------------------------------/ + + + + +# include "RDefs.h" + + + + +// /----------------------------------------------------------------\ +// | Methods Definitions | +// \----------------------------------------------------------------/ + + +// ------------------------------------------------------------------- +// Destructor : "CRBox::~CRBox()". + +CRBox::~CRBox (void) +{ + MNet::iterator itNet, endNet; + + + endNet = nets.end (); + for (itNet = nets.begin (); itNet != endNet; itNet++) + delete itNet->second; + + delete netsched; + delete drgrid; +} + + + + +// ------------------------------------------------------------------- +// Constructor : "CRBox::CRBox()". + +CRBox::CRBox (void) +{ + drgrid = NULL; + netsched = NULL; + loaded = false; +} + + + + +// ------------------------------------------------------------------- +// Constructor : "CRBox::CRBox()". + +CRBox::CRBox (int rtype, bool debug) +{ + int X, Y, Z; + CNet *pNet; + CTerm *pTerm; + //CCoord coord; + + + cdebug << "ENTERING: CRBox::CRBox ()\n"; + X = 10 ; //10; + Y = 15 ; //15; + Z = 3; + + + // Creating routing matrix. + cdebug << " Routing matrix size := (10, 15, 5)\n"; + + drgrid = new CDRGrid (X, Y, Z); + + + // Adding signal "sig_one". + cdebug << " Creating net \"sig_one\".\n"; + pNet = getnet ("sig_one"); + + + // Adding terminal "i0" of "sig_one". + cdebug << " Adding terminal \"i0\".\n"; + cdebug << " Adding CA \"(0,0,0)\".\n"; + pNet->newaccess ("i0", 0, 0, 0); + //cdebug << " Adding CA \"(0,0,1)\".\n"; + //nets["sig_one"]->newaccess ("i0", 0, 0, 1); + //cdebug << " Adding CA \"(0,1,1)\".\n"; + //nets["sig_one"]->newaccess ("i0", 0, 1, 1); + + + // Adding terminal "i1" of "sig_one". + cdebug << " Adding terminal \"i1\".\n"; + cdebug << " Adding CA \"(9,0,0)\".\n"; + pNet->newaccess ("i1", 9, 0, 0); + + + // Adding terminal "o" of "sig_one". + cdebug << " Adding terminal \"o\".\n"; + //cdebug << " Adding CA \"(5,10,0)\".\n"; + //nets["sig_one"]->newaccess ("o", 5, 10, 0); + + //cdebug << " Adding CA \"(7,12,0)\".\n"; + //nets["sig_one"]->newaccess ("o", 7, 12, 0); + + + // Adding signal "sig_two". + //cdebug << " Creating net \"sig_two\".\n"; + //nets["sig_two"] = new CNet ("sig_two"); + + + // Adding terminal "i0" of "sig_two". + //cdebug << " Adding terminal \"i0\".\n"; + //cdebug << " Adding CA \"(4,1,0)\".\n"; + //nets["sig_two"]->newaccess ("i0", 4, 1, 0); + + + // Adding terminal "o" of "sig_two". + //cdebug << " Adding terminal \"o\".\n"; + //cdebug << " Adding CA \"(4,11,0)\".\n"; + //nets["sig_two"]->newaccess ("o", 4, 11, 0); + + + //{ + // int j; + + // for (j = 0; j < Y; j++) { + // (*::grid)[coord.set (160, j, 1)]->data.pri = 128; + // (*::grid)[coord.set (160, j, 2)]->data.pri = 128; + // } + //} + // Putting obstacles. + //(*::grid)[coord.set (5, 5, 2)]->data.pri = 128; + //(*::grid)[coord.set (6, 5, 2)]->data.pri = 128; + //(*::grid)[coord.set (7, 5, 2)]->data.pri = 128; + //(*::grid)[coord.set (8, 5, 2)]->data.pri = 128; + //(*::grid)[coord.set (9, 5, 2)]->data.pri = 128; + + + netsched = new CASimple (&nets, drgrid); + + cdebug << "EXITING: CRBox::CRBox ()\n"; +} + + + + +// ------------------------------------------------------------------- +// Method : "CRBox::route()". + +void CRBox::route (void) +{ + netsched->run (rglobal); +} + + + + +// ------------------------------------------------------------------- +// Method : "CRBox::getnet()". + +CNet *CRBox::getnet (char *signame) +{ + string name; + + + name = signame; + + return (getnet(name)); +} + + + + +// ------------------------------------------------------------------- +// Method : "CRBox::getnet()". + +CNet *CRBox::getnet (string &signame) +{ + MNet::iterator itNet, endNet; + CNet *pNet; + + + endNet = nets.end (); + itNet = nets.find (signame); + + if (itNet == endNet) { + pNet = nets[signame] = new CNet (drgrid, signame); + } else + pNet = itNet->second; + + + return (pNet); +} diff --git a/alliance/src/nero/src/RDefs.h b/alliance/src/nero/src/RDefs.h new file mode 100644 index 00000000..c7590dc4 --- /dev/null +++ b/alliance/src/nero/src/RDefs.h @@ -0,0 +1,70 @@ + +// -*- C++ -*- +// +// $Id: RDefs.h,v 1.1 2002/10/02 21:23:48 jpc Exp $ +// +// /-----------------------------------------------------------------\ +// | | +// | A l l i a n c e C A D S y s t e m | +// | S i m p l e R o u t e r | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : alliance-support@asim.lip6.fr | +// | =============================================================== | +// | C++ Header : "./RDefs.h" | +// | *************************************************************** | +// | U p d a t e s | +// | | +// \-----------------------------------------------------------------/ + + + + +# ifndef __RDefs__ +# define __RDefs__ 1 + + +# include "ADefs.h" + + + + +// ------------------------------------------------------------------- +// Module : "RBox.cpp". + + + // --------------------------------------------------------------- + // Routing box class. + + class CRBox { + + // Attributes. + public: CASimple *netsched; + public: CDRGrid *drgrid; + public: MNet nets; + public: bool loaded; + public: bool rglobal; + + // MBK dedicated Attributes. + public: MBK::CFig *fig; + public: MBK::MPowers powers; + + // Constructor. + public: CRBox (void); + public: CRBox (int rtype, bool debug); + + // Destructor. + public: ~CRBox (void); + + // Modifiers. + public: CNet *getnet (string &signame); + public: CNet *getnet (char *signame); + public: void mbkload (MBK::CFig *mbkfig, int z, int rtype); + public: void mbksave (string &name); + public: void route (void); + + }; + + + +# endif diff --git a/alliance/src/nero/src/RMBK.cpp b/alliance/src/nero/src/RMBK.cpp new file mode 100644 index 00000000..e9ae57a2 --- /dev/null +++ b/alliance/src/nero/src/RMBK.cpp @@ -0,0 +1,570 @@ + +// -*- C++ -*- +// +// $Id: RMBK.cpp,v 1.1 2002/10/02 21:23:48 jpc Exp $ +// +// /----------------------------------------------------------------\ +// | | +// | A l l i a n c e C A D S y s t e m | +// | S i m p l e R o u t e r | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : alliance-support@asim.lip6.fr | +// | ============================================================== | +// | C++ Module : "./RMBK.cpp" | +// | ************************************************************** | +// | U p d a t e s | +// | | +// \----------------------------------------------------------------/ + + + + +# include "RDefs.h" + + + + +// /----------------------------------------------------------------\ +// | Methods Definitions | +// \----------------------------------------------------------------/ + + +// ------------------------------------------------------------------- +// Modifier : "CRBox::mbkload()". + +void CRBox::mbkload (MBK::CFig *mbkfig, int z, int rtype) +{ + MBK::MIns::iterator itIns, endInstances, endOrphans; + MBK::MLosig::iterator endSig; + long mX, mY, mZ, x, y, zz; + bool use_global; + MBK::chain_list *pChain; + MBK::locon_list *pLocon; + MBK::phcon_list *pPhcon; + MBK::losig_list *pSig; + MBK::phseg_list *pSeg, flatSeg; + MBK::phfig_list *pModel; + MBK::CXRect *rect; + MBK::CIns *pIns; + CNet *pNet; + string sig_name, term_name, ins_name; + CDRGrid::iterator coord; + CNode *node; + + + cmess1 << "\n"; + cmess1 << " o Loading design into grid...\n"; + + fig = mbkfig; + + + // Compute the routing grid size. + mX = (fig->XAB2 () - fig->XAB1 ()) / D::X_GRID + 1; + mY = (fig->YAB2 () - fig->YAB1 ()) / D::Y_GRID + 1; + mZ = z; + + + // Selecting the whether to use global routing. + use_global = (mX + mY) > (2 * D::GLOBAL_HP); + if (rtype == D::ROUTING_CHOOSE) { + if (use_global) { + cmess2 << " o Big design, global routing enabled.\n"; + rglobal = true; + + if (z < 5) { + cmess2 << " - Forcing 4 routing layers.\n"; + mZ = z = 5; + } + } else { + cmess2 << " o Small design, global routing disabled.\n"; + rglobal = false; + } + } else { + if (rtype == D::ROUTING_GLOBAL) { + rglobal = true; + if (!use_global) { + cout << hwarn ("") + << " You have enabled global routing on a small design,\n" + << " this will waste upper routing layers.\n"; + } + } + if (rtype == D::ROUTING_LOCAL ) { + rglobal = false; + if (use_global) { + cout << hwarn ("") + << " You have disabled global routing on a big design,\n" + << " this will slow down the routing.\n"; + } + } + } + + + cmess2 << " o Allocating grid size [" + << mX << "," << mY << "," << mZ << "].\n"; + + // Allocating the routing grid. + drgrid = new CDRGrid (mX, mY, mZ); + + + rect = new MBK::CXRect (fig->XAB1(), fig->YAB1()); + + + 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) { + // There must not be obstacle in the father! + if (MBK::isobs (pSeg->LAYER)) { + cerr << hwarn ("") + << " An obstacle has been found at design top level, ignored.\n"; + + continue; + } + + // Power grid. + if (( MBK::ISVDD (pSeg->NAME) + || MBK::ISVSS (pSeg->NAME)) && (pSeg->LAYER != MBK::CALU1)) { + rect->setSeg (*pSeg); + + drgrid->nodes->obstacle (rect->grid, MBK::env.layer2z (pSeg->LAYER)); + + continue; + } + + // Unnamed signals : ignored. + if (pSeg->NAME == NULL) { + cerr << hwarn ("") + << " An unnamed segment has been found at design top level, ignored.\n"; + + continue; + } + + // Partially routed signals. + if (fig->lofig.signals.find(pSeg->NAME) == endSig) { + 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" + << " do not not belong to any logical signal : ignored."; + + continue; + } + + pNet = getnet (pSeg->NAME); + + rect->setSeg (*pSeg); + + pNet->newaccess ( pSeg->NAME + , rect->grid + , MBK::env.layer2z (pSeg->LAYER) + ); + } + + + // Browse layout for terminals. + for (pPhcon = fig->phfig.fig->PHCON; pPhcon != NULL; pPhcon = pPhcon->NEXT) { + if (fig->lofig.signals.find(pPhcon->NAME) == endSig) { + cerr << hwarn ("") + << " The terminal \"" << pPhcon->NAME << "\" at (" + << MBK::UNSCALE (pPhcon->XCON) << "," + << MBK::UNSCALE (pPhcon->YCON) << ") layer " + << MBK::layer2a (pPhcon->LAYER) << "\n" + << " do not not belong to any logical signal : ignored.\n"; + + continue; + } + + pNet = getnet (pPhcon->NAME); + + term_name = "external."; + term_name += pPhcon->NAME; + + flatSeg.X1 = pPhcon->XCON; + flatSeg.Y1 = pPhcon->YCON; + flatSeg.X2 = pPhcon->XCON; + flatSeg.Y2 = pPhcon->YCON; + flatSeg.WIDTH = MBK::env.layer2width (pPhcon->LAYER); + flatSeg.LAYER = pPhcon->LAYER; + flatSeg.NAME = pPhcon->NAME; + + rect->setSeg (flatSeg); + + pNet->newaccess ( term_name + , rect->grid + , MBK::env.layer2z (pPhcon->LAYER) + ); + + } + + + // Browse instances & orphans for obstacles. + for (itIns = fig->instances.begin(); ; itIns++) { + if (itIns == endInstances) itIns = fig->orphans.begin (); + if (itIns == endOrphans ) break; + + pModel = itIns->second->getmodel (); + + cdebug << "+ - \"" << itIns->first + << "\" (model \"" << pModel->NAME << "\").\n"; + + + // Find the obstacles in the current instance : + // 1. - TALUx segments. + // 2. - Power Terminals (vdd & vss), in CALUx layers & not CALU1. + for (pSeg = pModel->PHSEG; pSeg != NULL; pSeg = pSeg->NEXT) { + if ( MBK::isobs (pSeg->LAYER) + || (( MBK::ISVDD (pSeg->NAME) + || MBK::ISVSS (pSeg->NAME)) && MBK::isCALU (pSeg->LAYER) + && (pSeg->LAYER != MBK::CALU1))) { + itIns->second->flatseg (flatSeg, *pSeg); + rect->setSeg (flatSeg); + + drgrid->nodes->obstacle (rect->grid, MBK::env.layer2z (pSeg->LAYER)); + } + } + } + + + cmess2 << " o Loading nets into grid.\n"; + + // Process the signals. + for (pSig = fig->LOSIG (); pSig != NULL; pSig = pSig->NEXT) { + sig_name = MBK::getsigname (pSig); + + cdebug << "+ - Signal \"" << sig_name << "\".\n"; + + // Do not process power nets. + if ( (MBK::ISVDD ((char*)sig_name.c_str ()) != 0) + || (MBK::ISVSS ((char*)sig_name.c_str ()) != 0)) continue; + + pNet = getnet (sig_name); + + // Process each terminal of the signal. + pChain = (MBK::chain_list*)(MBK::getptype (pSig->USER, LOFIGCHAIN)->DATA); + + for (; pChain != NULL; pChain = pChain->NEXT) { + pLocon = (MBK::locon_list *)(pChain->DATA); + + if (pLocon->TYPE == EXTERNAL) { + pNet->external = true; + + + continue; + } + + ins_name = ((MBK::loins_list*)(pLocon->ROOT))->INSNAME; + pIns = fig->instances[ins_name]; + + term_name = ins_name + "." + pLocon->NAME; + + // Find physical segments / CA of the terminal. + for (pSeg = pIns->model->PHSEG; pSeg != NULL; pSeg = pSeg->NEXT) { + if (!MBK::isCALU (pSeg->LAYER)) continue; + if (pLocon->NAME != pSeg->NAME) continue; + + pIns->flatseg (flatSeg, *pSeg); + rect->setSeg (flatSeg); + + pNet->newaccess ( term_name + , rect->grid + , MBK::env.layer2z (pSeg->LAYER) + ); + } + } // End of "pChain" (terminal) loop. + + // Reorder terminals (nearest). + pNet->order (); + pNet->lockalone (); + + cdebug << "+ " << pNet->bb << ".\n"; + } // End of "pSig" (signal) loop. + + + // Allocate the net scheduler. + cmess2 << " o Allocating the net scheduler.\n"; + netsched = new CASimple (&nets, drgrid); + + + // 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 + ); + + + // Forbid the use of the edges of the routing box (only allow + // peripheral terminals). + 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; + } + } + } + + // 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; + } + } + } + + + + // This flag ensure that a figure has been successfully loaded. + loaded = true; + + + delete rect; +} + + + +// ------------------------------------------------------------------- +// Modifier : "CRBox::mbksave()". + +void CRBox::mbksave (string &name) +{ + int x, y, z, mX, mY, mZ; + bool inseg; + CRect rect; + CDRGrid::iterator coord; + CNode *node; + CNet *pNextNet, *pNet; + MBK::phseg_list seg; + MBK::phvia_list via; + MNet::iterator itNet, endNet; + + + if (!loaded) { + cerr << hwarn ("") + << "\n The MBK figure has not been loaded into the grid yet, nothing" + << "\n to save at this point.\n"; + + return; + } + cmess2 << "\n"; + cmess1 << " o Dumping routing grid.\n"; + + mX = drgrid->X; + mY = drgrid->Y; + mZ = drgrid->Z; + coord = drgrid->origin; + + + // Horizontal planes loop in both directions. + for (z = 1; z < mZ; z++) { + + // Loop for horizontal segments. + for (y = 0; y < mY; y++) { + + inseg = false; + pNet = NULL; + + for (x = 0; x < mX; x++) { + node = & ( coord.set(x,y,z).node() ); + pNextNet = node->data.owner; + + if (inseg && (pNextNet != pNet)) { + // We are changing of segment owner. + // Dump the current one. + if (seg.X1 < seg.X2) { + // This is not a "dot" segment (i.e a VIA). + fig->addphseg (seg); + } + + // Force segment restarting. + inseg = false; + } + + pNet = pNextNet; + + if (pNet) { + if (!inseg) { + // 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.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); + } + + // Update the right edge. + seg.X2 = fig->XAB1() + 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); + } + } + + // We encounter the right edge of a segment. + inseg = false; + } + } // End of "x" loop. + + if (inseg) { + // This segment touch the AB. + if (seg.X1 < seg.X2) { + // This is not a "dot" segment (i.e a VIA). + fig->addphseg (seg); + } + } + + } // End of "y" loop (horizontal segments). + + // Loop for vertical segments. + for (x = 0; x < mX; x++) { + + inseg = false; + pNet = NULL; + + for (y = 0; y < mY; y++) { + node = & ( coord.set(x,y,z).node() ); + pNextNet = node->data.owner; + + if (inseg && (pNextNet != pNet)) { + // We are changing of segment owner. + // Dump the current one. + if (seg.Y1 < seg.Y2) { + // This is not a "dot" segment (i.e a VIA). + fig->addphseg (seg); + } + + // Force segment restarting. + inseg = false; + } + + pNet = pNextNet; + + if (pNet) { + if (!inseg) { + // 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.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); + + } + + // Update the right edge. + seg.Y2 = fig->YAB1() + 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); + } + } + + // We encounter the right edge of a segment. + inseg = false; + } + } // End of "y" loop. + + if (inseg) { + // This segment touch the AB. + if (seg.Y1 < seg.Y2) { + // This is not a "dot" segment (i.e a VIA). + fig->addphseg (seg); + } + } + + } // End of "x" loop (vertical segments). + + } // End of "z" loop (planes). + + + via.DX = 0; + via.DY = 0; + + // Plane loop for VIAs. + for (x = 0; x < mX; x++) { + for (y = 0; y < mY; y++) { + + // Loop on Z axis. + for (z = 1; z < mZ; z++) { + node = & ( coord.set(x,y,z).node() ); + if (coord.inside()) pNet = node->data.owner; + else pNet = NULL; + + node = & ( coord.set(x,y,z-1).node() ); + if (coord.inside()) pNextNet = node->data.owner; + + if (pNet && (pNet == pNextNet)) { + via.TYPE = MBK::env.z2via (z); + via.XVIA = fig->XAB1() + x * D::X_GRID; + via.YVIA = fig->YAB1() + y * D::Y_GRID; + via.NAME = MBK::namealloc(pNet->name.c_str ()); + + fig->addphvia (via); + } + } // End of Z axis loop. + } + } // End of plane loop for VIAs. + + + // Special case of nets with only one terminal. + endNet = nets.end (); + for (itNet = nets.begin(); itNet != endNet; itNet++) { + if (!itNet->second->external) continue; + if (itNet->second->size != 1) continue; + if (itNet->second->terms[0]->rects.size() < 1) continue; + + 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.NAME = MBK::namealloc(itNet->second->name.c_str ()); + seg.WIDTH = MBK::env.z2width (0); + seg.LAYER = MBK::env.z2calu (0); + + fig->addphseg (seg); + } + + + // Add powers lines. + powers[MBK::CALU1]->dump (fig); + + + cmess1 << " o Saving MBK figure \"" << name << "\".\n"; + fig->phfig.saveas (name); +} diff --git a/alliance/src/nero/src/RNet.cpp b/alliance/src/nero/src/RNet.cpp new file mode 100644 index 00000000..b7113d70 --- /dev/null +++ b/alliance/src/nero/src/RNet.cpp @@ -0,0 +1,64 @@ + +// -*- C++ -*- +// +// $Id: RNet.cpp,v 1.1 2002/10/02 21:23:48 jpc Exp $ +// +// /----------------------------------------------------------------\ +// | | +// | A l l i a n c e C A D S y s t e m | +// | S i m p l e R o u t e r | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : alliance-support@asim.lip6.fr | +// | ============================================================== | +// | C++ Module : "./RNet.cpp" | +// | ************************************************************** | +// | U p d a t e s | +// | | +// \----------------------------------------------------------------/ + + + + +# include "RDefs.h" + + + + +// /----------------------------------------------------------------\ +// | Methods Definitions | +// \----------------------------------------------------------------/ + + +// ------------------------------------------------------------------- +// Modifier : "CNet::route()". + +void CNet::route (void) +{ + int pri; + int increase, expand; + bool hysteresis, routed; + + + hysteresis = false; + increase = 0; + expand = 0; + + do { + if (hysteresis) { + pri = 255 + (1 << increase++); + + if (increase > 1) expand = 200; + } + else pri = 0; + + ::astar->clear (); + ::astar->load (this, pri, expand); + + routed = !::astar->search (); + + hysteresis = true; + } while ((increase < 15) && !routed); + + if (routed) ::astar->dump(); +} diff --git a/alliance/src/nero/src/UConst.cpp b/alliance/src/nero/src/UConst.cpp new file mode 100644 index 00000000..ebef34c9 --- /dev/null +++ b/alliance/src/nero/src/UConst.cpp @@ -0,0 +1,85 @@ + +// -*- C++ -*- +// +// $Id: UConst.cpp,v 1.1 2002/10/02 21:23:48 jpc Exp $ +// +// /-----------------------------------------------------------------\ +// | | +// | A l l i a n c e C A D S y s t e m | +// | S i m p l e R o u t e r | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : alliance-support@asim.lip6.fr | +// | =============================================================== | +// | C++ Module : "./UConst.cpp" | +// | *************************************************************** | +// | U p d a t e s | +// | | +// \-----------------------------------------------------------------/ + + + + +# include "UDefs.h" + + + +// ------------------------------------------------------------------- +// Namespace : "D". + + +namespace D { + + + // --------------------------------------------------------------- + // Pre-defined objects. + + const int CHUNK_SIZE = 4096; + + + const int cost_ALU2_X = 2; + const int cost_ALU2_Y = 6; + const int cost_ALU3_X = 6; + const int cost_ALU3_Y = 2; + const int cost_VIA = 1; + const bool optim_AStar_queue = true; + const bool optim_AStar_order = true; + const int GLOBAL_HP = 400; + + const int ROUTING_CHOOSE = 1; + const int ROUTING_GLOBAL = 2; + const int ROUTING_LOCAL = 3; + + + // MBK Routing related constants. + const long _X_GRID = 5; + const long _Y_GRID = 5; + const long _Y_SLICE = 50; + const long _WIDTH_VSS = 6; + const long _WIDTH_VDD = 6; + const long _TRACK_WIDTH_ALU1 = 2; + const long _TRACK_WIDTH_ALU2 = 2; + const long _TRACK_WIDTH_ALU3 = 2; + const long _TRACK_WIDTH_ALU4 = 2; + const long _TRACK_WIDTH_ALU5 = 2; + const long _TRACK_WIDTH_ALU6 = 2; + + long X_GRID; + long Y_GRID; + long WIDTH_VSS; + long WIDTH_VDD; + long Y_SLICE; + long TRACK_WIDTH_ALU1; + long TRACK_WIDTH_ALU2; + long TRACK_WIDTH_ALU3; + long TRACK_WIDTH_ALU4; + long TRACK_WIDTH_ALU5; + long TRACK_WIDTH_ALU6; + + + + +// ------------------------------------------------------------------- +// End of namespace "D". + +} diff --git a/alliance/src/nero/src/UDefs.h b/alliance/src/nero/src/UDefs.h new file mode 100644 index 00000000..31a6ab4a --- /dev/null +++ b/alliance/src/nero/src/UDefs.h @@ -0,0 +1,385 @@ + +// -*- C++ -*- +// +// $Id: UDefs.h,v 1.1 2002/10/02 21:23:48 jpc Exp $ +// +// /-----------------------------------------------------------------\ +// | | +// | A l l i a n c e C A D S y s t e m | +// | S i m p l e R o u t e r | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : alliance-support@asim.lip6.fr | +// | =============================================================== | +// | C++ Header : "./UDefs.h" | +// | *************************************************************** | +// | U p d a t e s | +// | | +// \-----------------------------------------------------------------/ + + + + +# ifndef __UDefs__ +# define __UDefs__ 1 + + + +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include + +# include + + + + +// ------------------------------------------------------------------- +// Load "std" namespace. + +using namespace std; + + + + +// ------------------------------------------------------------------- +// Namespace : "D". + +namespace D { + + extern const int CHUNK_SIZE; + + extern const int cost_ALU2_X; + extern const int cost_ALU2_Y; + extern const int cost_ALU3_X; + extern const int cost_ALU3_Y; + extern const int cost_VIA; + extern const bool optim_AStar_queue; + extern const bool optim_AStar_order; + extern const int GLOBAL_HP; + + extern const int ROUTING_CHOOSE; + extern const int ROUTING_GLOBAL; + extern const int ROUTING_LOCAL; + + + // MBK Routing related constants. + extern const long _X_GRID; + extern const long _Y_GRID; + extern const long _Y_SLICE; + extern const long _WIDTH_VSS; + extern const long _WIDTH_VDD; + extern const long _TRACK_WIDTH_ALU1; + extern const long _TRACK_WIDTH_ALU2; + extern const long _TRACK_WIDTH_ALU3; + extern const long _TRACK_WIDTH_ALU4; + extern const long _TRACK_WIDTH_ALU5; + extern const long _TRACK_WIDTH_ALU6; + + extern long X_GRID; + extern long Y_GRID; + extern long WIDTH_VSS; + extern long WIDTH_VDD; + extern long Y_SLICE; + extern long TRACK_WIDTH_ALU1; + extern long TRACK_WIDTH_ALU2; + extern long TRACK_WIDTH_ALU3; + extern long TRACK_WIDTH_ALU4; + extern long TRACK_WIDTH_ALU5; + extern long TRACK_WIDTH_ALU6; + +} + + + +// ------------------------------------------------------------------- +// Module : "USys.cpp". + + + // --------------------------------------------------------------- + // Message header class. + + class CHeader { + + // Internal attributes. + protected: string _header; + protected: string _message; + + // Constructor. + public: CHeader (string h); + + // Operators. + public: CHeader operator() (string m); + + // Friends. + public: friend ostream &operator<< (ostream &o, const CHeader &self); + }; + + + + + // --------------------------------------------------------------- + // Message stream class (write on "cout"). + + class CMess { + + // Internal attributes. + protected: static long _state; + protected: long _level; + + // Constructor. + public: CMess (long level) { _level = level; } + + // Modifiers. + public: void setVL (long state) { _state = state; } + + // Accessor. + public: long getVL (void) { return (_state); } + + public: template + CMess &operator<< (T s) { + if (_state >= _level) { cout << s; cout.flush (); } + return (*this); + } + + }; + + + + + // --------------------------------------------------------------- + // Debug stream class (write on "cerr"). + + class CDebug { + + // Internal attributes. + protected: bool _state; + + // Constructor. + public: CDebug (bool state) { _state = state; } + + // Modifiers. + public: void on () { _state = true; } + public: void off () { _state = false; } + + public: template + CDebug &operator<< (T s) { + if (_state) { cerr << s; cerr.flush (); } + return (*this); + } + }; + + + + + // --------------------------------------------------------------- + // Signal interrupt handler class (async). + + class CInterrupt { + + // Modifiable attributes. + public: bool coredump; + + // Constructor. + public: CInterrupt (void); + }; + + + + + // --------------------------------------------------------------- + // Software interrupt class (exception). + + class except_done : public exception { + + // Overridables. + public: const char* what () const throw () { + return ((char*)"This exception has already been processed."); + } + }; + + + + + // --------------------------------------------------------------- + // Pre-defined objects. + + // Output stream manipulators (header writing). + extern CHeader herr; + extern CHeader hwarn; + extern CHeader herrmbk; + extern CHeader hwarnmbk; + + // Messages stream of corresponding to various verbosity levels. + extern CMess cmess0; + extern CMess cmess1; + extern CMess cmess2; + + // Debug stream. + extern CDebug cdebug; + + // Interrupt handler. + extern CInterrupt interrupt; + + + + +// ------------------------------------------------------------------- +// Module : "UOpts.cpp". + + + // --------------------------------------------------------------- + // Command line options class. + + class COpts { + + // Internal objects. + public: struct COpt { + + // Attributes. + bool found; + bool parsed; + bool has_arg; + string value; + + // Constructor. + COpt (bool arg=false, string val="") { + parsed = false; + has_arg = arg; + value = value; + } + + // Friends. + public: friend ostream &operator<< (ostream &o, const COpt &self); + public: friend ostream &operator<< (ostream &o, const COpt *self); + }; + + // Internal types. + typedef map MOpt; + typedef vector TOpt; + + // Attributes. + private: MOpt tDict; + private: TOpt tList; + private: string tShort; + public: vector tVals; + + // Constructor. + COpts (void) { tShort = "+"; } + + // Modifiers. + public: void getopts (int argc, char *argv[]) throw (except_done); + public: void add ( string key_short + , string key_long + , bool arg=false + , string val="" + ) throw (except_done); + + // Operators. + private: long operator() (string key) throw (except_done); + public: struct COpt *operator[] (string key); + + }; + + + + +// ------------------------------------------------------------------ +// Module : "UInter.cpp". + + +# define SHIFT_MAX 8 +# define F_MIN_IN 0x00000001 +# define F_MIN_LOWER 0x00000002 +# define F_MIN_GREATER 0x00000004 +# define F_MAX_IN ((F_MIN_IN) << SHIFT_MAX) +# define F_MAX_LOWER ((F_MIN_LOWER) << SHIFT_MAX) +# define F_MAX_GREATER ((F_MIN_GREATER) << SHIFT_MAX) +# define C_INTER_LOWER (F_MIN_LOWER | F_MAX_LOWER ) +# define C_INTER_CROSS_MIN (F_MIN_LOWER | F_MAX_IN ) +# define C_INTER_IN (F_MIN_IN | F_MAX_IN ) +# define C_INTER_CROSS_MAX (F_MIN_IN | F_MAX_GREATER) +# define C_INTER_GREATER (F_MIN_GREATER | F_MAX_GREATER) +# define C_INTER_OUT (F_MIN_LOWER | F_MAX_GREATER) + + + + + // --------------------------------------------------------------- + // Interval class. + + struct CInter : pair { + + // Supplemental methods. + public: long cmp (CInter &); + + // Friends. + friend ostream &operator<< (ostream &o, const CInter &self); + + }; + + + + + // --------------------------------------------------------------- + // Interval list class. + + struct LInter : public list { + + // Attributes. + long bmin; // Lower bound of the whole list. + long bmax; // Upper bound of the whole list. + + // Methods. + void add (long, long); + + // Friends. + friend ostream &operator<< (ostream &o, LInter &self); + + }; + + + + +// ------------------------------------------------------------------- +// Miscellaneous. + + +//template inline T min (T a, T b) { return ((a < b) ? a : b); } +//template inline T max (T a, T b) { return ((a > b) ? a : b); } +//template inline void swap (T a, T b) { +// T tmp; +// +// tmp = a; a = b; b = tmp; +// } + + + + +// ------------------------------------------------------------------- +// Module : "nero.cpp". + + + // --------------------------------------------------------------- + // Functions. + + + void emergency (void); + + + + +#endif diff --git a/alliance/src/nero/src/UGrid.cpp b/alliance/src/nero/src/UGrid.cpp new file mode 100644 index 00000000..8d3d2a65 --- /dev/null +++ b/alliance/src/nero/src/UGrid.cpp @@ -0,0 +1,604 @@ + +// -*- C++ -*- +// +// $Id: UGrid.cpp,v 1.1 2002/10/02 21:23:48 jpc Exp $ +// +// /----------------------------------------------------------------\ +// | | +// | A l l i a n c e C A D S y s t e m | +// | S i m p l e R o u t e r | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : alliance-support@asim.lip6.fr | +// | ============================================================== | +// | C++ Module : "./UGrid.cpp" | +// | ************************************************************** | +// | U p d a t e s | +// | | +// \----------------------------------------------------------------/ + + + + +# include "UDefs.h" + + + + +// /----------------------------------------------------------------\ +// | Methods Definitions | +// \----------------------------------------------------------------/ + + +// ------------------------------------------------------------------- +// Friend of "CRect" : "&operator<<()". + +ostream &operator<< (ostream &o, const CRect *rect) +{ + o << "(" + << rect->x1 << ", " + << rect->y1 << "), (" + << rect->x2 << ", " + << rect->y2 << ")"; + + return (o); +} + + + + +// ------------------------------------------------------------------- +// Constructor : "CBB::CBB()". + +CBB::CBB (void) +{ + x1 = INT_MAX; + y1 = INT_MAX; + x2 = 0; + y2 = 0; + hp = 0; +} + + + + +// ------------------------------------------------------------------- +// Method : "CBB::merge()". + +void CBB::merge (CCoord &coord) +{ + x1 = min (x1, coord.x); + y1 = min (y1, coord.y); + x2 = max (x2, coord.x); + y2 = max (y2, coord.y); + + hp = (x2 - x1) + (y2 - y1); +} + + + + +// ------------------------------------------------------------------- +// Friend of "CBB" : "&operator<<()". + +ostream &operator<< (ostream &o, CBB &self) +{ + o << "CBB (" << self.x1 << "," << self.y1 << ") (" + << self.x2 << "," << self.y2 << ") HP := " << self.hp; + + return (o); +} + + + + +// ------------------------------------------------------------------- +// Constructor : "CNodeData::CNodeData()". + +CNodeData::CNodeData (void) +{ + pri = 0; + + owner = NULL; + rtree = NULL; + ident = 0; + obstacle = false; + lock = false; +} + + + + +// ------------------------------------------------------------------- +// Constructor : "CNode::CNode()". + +CNode::CNode (void) +{ + algo = NULL; +} + + + + +// ------------------------------------------------------------------- +// Method : "CNode::grab()". + +void CNode::grab (CNet *net, int pri) +{ + if (data.owner && (data.owner != net)) + throw bad_grab ( data.owner->name + , net->name + , coord.x() + , coord.y() + , coord.z() + , pri + , terminal() + , data.ident + ); + + // Update the net tree chaining datas. + data.rtree = net->rtree; + net->rtree = this; + + data.owner = net; + data.pri = pri; + + + //cerr << "net \"" << net->name << "\" has grab node " << coord + // << " with pri := " << data.pri << endl; +} + + + + +// ------------------------------------------------------------------- +// Method : "CNode::ungrab()". + +void CNode::ungrab (void) +{ + + if (!terminal ()) { + data.owner = NULL; + data.rtree = NULL; + } + data.pri = 0; +} + + + + +// ------------------------------------------------------------------- +// Constructor : "CDRGrid::iterator::iterator ()". + +CDRGrid::iterator::iterator (void) +{ + _drgrid = NULL; + _index = INT_MAX; +} + + + + +// ------------------------------------------------------------------- +// Constructor : "CDRGrid::iterator::iterator ()". + +CDRGrid::iterator::iterator (CDRGrid::iterator &other) +{ + _drgrid = other._drgrid; + _index = other._index; +} + + + + +// ------------------------------------------------------------------- +// Method : "CDRGrid::iterator::valid ()". + +void CDRGrid::iterator::valid (bool validindex) + throw (e_matrix_iterator) +{ + if (_drgrid == NULL) { + throw e_matrix_iterator ("Attempt to use an unitialized grid iterator."); + } + + if ( (validindex) && (_index == INT_MAX) ) + throw e_matrix_iterator ("Attempt to use iterator outside the matrix."); +} + + + + +// ------------------------------------------------------------------- +// Method : "CDRGrid::iterator::set ()". + +CDRGrid::iterator &CDRGrid::iterator::set (int x, int y, int z) +{ + valid (false); + + _index = _drgrid->dx (_index, x); + _index = _drgrid->dy (_index, y); + _index = _drgrid->dz (_index, z); + + return ( *this ); +} + + + + +// ------------------------------------------------------------------- +// Method : "CDRGrid::iterator::dx ()". + +CDRGrid::iterator &CDRGrid::iterator::dx (int d) +{ + valid (false); + + _index = _drgrid->dx (_index, d); + + return ( *this ); +} + + + + +// ------------------------------------------------------------------- +// Method : "CDRGrid::iterator::dy ()". + +CDRGrid::iterator &CDRGrid::iterator::dy (int d) +{ + valid (false); + + _index = _drgrid->dy (_index, d); + + return ( *this ); +} + + + + +// ------------------------------------------------------------------- +// Method : "CDRGrid::iterator::dz ()". + +CDRGrid::iterator &CDRGrid::iterator::dz (int d) +{ + valid (false); + + _index = _drgrid->dz (_index, d); + + return ( *this ); +} + + + + +// ------------------------------------------------------------------- +// Accessor : "CDRGrid::iterator::pri". + +char &CDRGrid::iterator::pri (void) +{ + valid (false); + + return ( (*(_drgrid->pri))[*this] ); +} + + + + +// ------------------------------------------------------------------- +// Accessor : "CDRGrid::iterator::node". + +CNode &CDRGrid::iterator::node (void) +{ + valid (false); + + return ( (*(_drgrid->nodes))[*this] ); +} + + + + +// ------------------------------------------------------------------- +// Modifier : "CDRGrid::iterator::addnode". + +CNode &CDRGrid::iterator::addnode (void) +{ + valid (true); + + return ( _drgrid->nodes->add (this->_index) ); +} + + + + +// ------------------------------------------------------------------- +// Friend : "CDRGrid::iterator::operator<< ()". + +ostream &operator<< (ostream &o, CDRGrid::iterator &self) +{ + o << "CDRGrid<>::iterator (_drgrid := " << self._drgrid + << ", _index := " << self._index + << " (" << self.x() << "," << self.y() << "," << self.z() << "))"; + + return ( o ); +} + + + + +// ------------------------------------------------------------------- +// Method : "CDRGrid::iterator::manhattan ()". + +int CDRGrid::iterator::manhattan (iterator &other) + throw (e_matrix_iterator) +{ + long manhattan; + + + valid (true); + other.valid (true); + + if (_drgrid != other._drgrid) + throw (e_matrix_iterator ("Attempt to use iterators from different grids.")); + + manhattan = abs (x() - other.x()) * _drgrid->cost_x_hor; + manhattan += abs (y() - other.y()) * _drgrid->cost_y_ver; + manhattan += abs (z() - other.z()) * _drgrid->cost_z; + + // As we never use ALU1 layer, add the cost of VIA. + if (z() == 0) manhattan += _drgrid->cost_z; + if (other.z() == 0) manhattan += _drgrid->cost_z; + + return (manhattan); +} + + + + +// ------------------------------------------------------------------- +// Constructor : "CDRGrid::CDRGrid()". + +CDRGrid::CDRGrid (int x, int y, int z) +{ + int index; + + + X = x; + Y = y; + Z = z; + XY = X * Y; + XYZ = XY * Z; + size = XY * (Z - 1); + + nodes = new CMatrixNodes (this); + pri = new CMatrixPri (this); + + cost_x_hor = cost_y_ver = cost_z = 1; + cost_x_ver = cost_y_hor = 2; + + // Reference iterator initialisation. + origin._drgrid = this; + origin._index = XY; +} + + + + +// ------------------------------------------------------------------- +// Destructor : "CDRGrid::~CDRGrid()". + +CDRGrid::~CDRGrid (void) +{ + delete [] nodes; + delete [] pri; +} + + + + +// ------------------------------------------------------------------- +// Modifier : "CDRGrid::costs ()". + +void CDRGrid::costs (int x_hor, int x_ver, int y_hor, int y_ver, int z) +{ + cost_x_hor = x_hor; + cost_x_ver = x_ver; + cost_y_hor = y_hor; + cost_y_ver = y_ver; + cost_z = z; +} + + + + +// ------------------------------------------------------------------- +// Modifier : "CDRGrid::dx ()". + +int CDRGrid::dx (int index, int d) +{ + if ( (index == INT_MAX) || (x(index) + d < 0) || (x(index) + d >= X) ) + return (INT_MAX); + + return (index + d); +} + + + + +// ------------------------------------------------------------------- +// Modifier : "CDRGrid::dy ()". + +int CDRGrid::dy (int index, int d) +{ + if ( (index == INT_MAX) || (y(index) + d < 0) || (y(index) + d >= Y) ) + return (INT_MAX); + + return (index + d*X); +} + + + + +// ------------------------------------------------------------------- +// Modifier : "CDRGrid::dz ()". + +int CDRGrid::dz (int index, int d) +{ + if ( (index == INT_MAX) || (z(index) + d < 0) || (z(index) + d >= Z) ) + return (INT_MAX); + + return (index + d*XY); +} + + + + +// ------------------------------------------------------------------- +// Destructor : "TMatrix::_CHollow::~_CHollow()". + +template +TMatrix<__CNode__>::_CHollow::~_CHollow (void) +{ + _CRow::iterator itRow; + _CLayer::iterator itLayer; + + + for (itLayer = nodes.begin (); + itLayer != nodes.end (); itLayer++) { + for (itRow = itLayer->second.begin (); + itRow != itLayer->second.end (); itRow++) { + delete itRow->second; + } + } +} + + + + +// ------------------------------------------------------------------- +// Method : "TMatrix::_CHollow::add()". + +template +__CNode__ &TMatrix<__CNode__>::_CHollow::add (int x, int y) +{ + _CRow::iterator itRow; + _CLayer::iterator itLayer; + + + itLayer = nodes.find (x); + if (itLayer == nodes.end ()) { nodes[x] = _CRow (); } + + itRow = nodes[x].find (y); + if (itRow == nodes[x].end ()) { nodes[x][y] = new __CNode__ (); } + + return (*(nodes[x][y])); +} + + + + +// ------------------------------------------------------------------- +// Method : "TMatrix::_CHollow::get()". + +template +__CNode__ *TMatrix<__CNode__>::_CHollow::get (int x, int y) +{ + _CRow::iterator itRow; + _CLayer::iterator itLayer; + + + itLayer = nodes.find (x); + if (itLayer == nodes.end ()) { return (NULL); } + + itRow = nodes[x].find (y); + if (itRow == nodes[x].end ()) { return (NULL); } + + return ((*itRow).second); +} + + + + +// ------------------------------------------------------------------- +// Constructor : "TMatrix::TMatrix()". + +template +TMatrix<__CNode__>::TMatrix (CDRGrid *drgrid) +{ + _drgrid = drgrid; + _grid = new (__CNode__) [_drgrid->size]; +} + + + + +// ------------------------------------------------------------------- +// Destructor : "~TMatrix::TMatrix()". + +template +TMatrix<__CNode__>::~TMatrix (void) +{ + delete [] _grid; +} + + + + +// ------------------------------------------------------------------- +// Accessor : "TMatrix::&operator[]". + +template +__CNode__ &TMatrix<__CNode__>::operator[] (int index) +{ + __CNode__ *node; + + + if (index < _drgrid->XY ) { + node = _zero->get (_drgrid->x(index), _drgrid->y(index)) ; + if ( node != NULL ) return ( *node ); + } else { + if (index < _drgrid->XYZ) return ( _grid[index - _drgrid->XY] ); + } + + return ( hole ); +} + + + + +// ------------------------------------------------------------------- +// Modifier : "TMatrix::add ()". + +template +__CNode__ &TMatrix<__CNode__>::add (int index) +{ + if (index < _drgrid->XY) { + return ( _zero->add (_drgrid->x(index), _drgrid->y(index)) ); + } else { + if (index < _drgrid->XYZ) return ( (*this)[index] ); + } + + return ( hole ); +} + + + + +// ------------------------------------------------------------------- +// Modifier : "CMatrixNodes::obstacle()". + +void CMatrixNodes::obstacle (CRect &rect, int z) +{ + CDRgrid::iterator coord; + int x, y, X, Y; + + + if (!z) return; + + X = (_drgrid->X == rect.x2) ? rect.x2 - 1 : rect.x2; + Y = (_drgrid->Y == rect.y2) ? rect.y2 - 1 : rect.y2; + + for (x = rect.x1; x <= X; x++) { + for (y = rect.y1; y <= Y; y++) { + (*this)[ coord.set (x, y, z) ].data.obstacle = true; + } + } +} diff --git a/alliance/src/nero/src/UInter.cpp b/alliance/src/nero/src/UInter.cpp new file mode 100644 index 00000000..d4da4f77 --- /dev/null +++ b/alliance/src/nero/src/UInter.cpp @@ -0,0 +1,230 @@ + +// -*- C++ -*- +// +// $Id: UInter.cpp,v 1.1 2002/10/02 21:23:48 jpc Exp $ +// +// /----------------------------------------------------------------\ +// | | +// | A l l i a n c e C A D S y s t e m | +// | S i m p l e R o u t e r | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : alliance-support@asim.lip6.fr | +// | ============================================================== | +// | C++ Module : "./UInter.cpp" | +// | ************************************************************** | +// | U p d a t e s | +// | | +// \----------------------------------------------------------------/ + + + + +# include "UDefs.h" + + + + +// ------------------------------------------------------------------- +// Local Namespace (i.e. internal functions). + +namespace { + + + // --------------------------------------------------------------- + // Local functions. + + static long inbounds (long lbound, long rbound, long value); + inline long INBOUNDS (CInter &i, long v) + { return (inbounds (i.first, i.second, v)); } + + // /------------------------------------------------------------\ + // | Functions Definitions | + // \------------------------------------------------------------/ + + +// ------------------------------------------------------------------- +// Function : "inbounds()". + +static long inbounds (long lbound, long rbound, long value) +{ + if ((value >= lbound) && (value <= rbound)) return (F_MIN_IN); + if (value < lbound) return (F_MIN_LOWER); + + return (F_MIN_GREATER); +} + + + + +// ------------------------------------------------------------------- +// End of Local Namespace. + +} + + + + +// /----------------------------------------------------------------\ +// | Methods Definitions | +// \----------------------------------------------------------------/ + + +// ------------------------------------------------------------------- +// Function (friend CInter) : "operator<<()". + +ostream &operator<< (ostream &o, const CInter &self) +{ + return (o << "[" << self.first << "," << self.second << "]"); +} + + + + +// ------------------------------------------------------------------- +// Method : "CInter::cmp()". + +long CInter::cmp(CInter &b) +{ + long state; + + state = INBOUNDS(*this, b.first ); + state |= INBOUNDS(*this, b.second) << SHIFT_MAX; + + return (state); +} + + + + +// ------------------------------------------------------------------- +// Friend of "LInter" : "&operator<<()". + +ostream &operator<< (ostream &o, LInter &self) +{ + LInter::iterator itInter, beginInter, endInter; + + + beginInter = self.begin (); + endInter = self.end (); + + o << "("; + for (itInter = beginInter; itInter != endInter; itInter++) { + if (itInter != beginInter) o << " "; + + o << *itInter; + } + o << ")"; + + return (o); +} + + + + +// ------------------------------------------------------------------- +// Method : "LInter::add()". + +void LInter::add (long lbound, long rbound) +{ + LInter::iterator itInter, beginInter, endInter, mergeInter; + CInter element; + + + beginInter = begin (); + endInter = end (); + mergeInter = endInter; + + element.first = min (lbound, rbound); + element.second = max (lbound, rbound); + + + // The list is empty : just add the new element. + if (beginInter == endInter) { + bmin = lbound; + bmax = rbound; + insert (beginInter, element); + + return; + } + + + // Update the whole list bounds. + bmin = min (bmin, lbound); + bmax = max (bmax, rbound); + + + // Swept through the interval list for add or merge. + for (itInter = beginInter; itInter != endInter;) { + switch (element.cmp (*itInter)) { + // "itInter" is strictly lower than "element". Let's see the next + // interval. + case C_INTER_LOWER: break; + case C_INTER_OUT: break; + + // The upper bound of "itInter" is inside "element" : + // Update the upper bound of "itInter". "element" is now + // merged with the list. + case C_INTER_CROSS_MIN: + itInter->second = element.second; + mergeInter = itInter; + break; + + // "itInter" is completly inside "element". + // - If "element" has not been merged yet (mergeInter == endInter), + // resize "itInter" to fit element. "element" merged. + // - "element" is already merged : delete "itInter". + // Immediatly process the next element. + case C_INTER_IN: + if (mergeInter == endInter) { + itInter->first = element.first; + itInter->second = element.second; + mergeInter = itInter; + } else { + itInter = erase (itInter); + continue; + } + break; + + // The lower bound of "itInter" is inside "element" : + // - If "element" has not been merged yet (mergeInter == endInter), + // Update the lower bound of "itInter". "element" merged. + // - "element" is aleady merged : we have to update the upper + // bounds of "mergeInter" & "element" as it's used as the + // reference element for the next comparisons. Then delete + // "itInter". + case C_INTER_CROSS_MAX: + if (mergeInter == endInter) { + itInter->first = element.first; + mergeInter = itInter; + } else { + mergeInter->second = itInter->second; + element.second = itInter->second; + + itInter = erase (itInter); + continue; + } + break; + + // "itInter" is strictly greater than "element" (and element + // is not included in any lower interval : add a new element + // before "itInter" then break the loop. + case C_INTER_GREATER: + if (mergeInter == endInter) { + itInter = insert (itInter, element); + mergeInter = itInter; + itInter = endInter; + continue; + } + break; + } + + // Proceed the next "itInter". + itInter++; + } + + + // If the element is not merged here i's greater than any element + // in the list. Add it in tail. + if (mergeInter == endInter) push_back (element); +} diff --git a/alliance/src/nero/src/UOpts.cpp b/alliance/src/nero/src/UOpts.cpp new file mode 100644 index 00000000..1b732f14 --- /dev/null +++ b/alliance/src/nero/src/UOpts.cpp @@ -0,0 +1,202 @@ + +// -*- C++ -*- +// +// $Id: UOpts.cpp,v 1.1 2002/10/02 21:23:49 jpc Exp $ +// +// /----------------------------------------------------------------\ +// | | +// | A l l i a n c e C A D S y s t e m | +// | S i m p l e R o u t e r | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : alliance-support@asim.lip6.fr | +// | ============================================================== | +// | C++ Module : "./UOpts.cpp" | +// | ************************************************************** | +// | U p d a t e s | +// | | +// \----------------------------------------------------------------/ + + + + +# include "unistd.h" +# include "UDefs.h" + + + + +// /----------------------------------------------------------------\ +// | Methods Definitions | +// \----------------------------------------------------------------/ + +// ------------------------------------------------------------------- +// COpt Friend : "&operator<<()". + +ostream &operator<< (ostream &o, const COpts::COpt &self) +{ + cout << " COpt.parsed = " << self.parsed << "\n"; + cout << " COpt.has_arg = " << self.has_arg << "\n"; + cout << " COpt.value = " << self.value << "\n"; + + return (o); +} + +// ------------------------------------------------------------------- +// COpt Friend : "*operator<<()". + +ostream &operator<< (ostream &o, const COpts::COpt *self) +{ + cout << " COpt.parsed = " << self->parsed << "\n"; + cout << " COpt.has_arg = " << self->has_arg << "\n"; + cout << " COpt.value = " << self->value << "\n"; + + return (o); +} + + +// ------------------------------------------------------------------- +// Modifier : "COpts::add()". + +void COpts::add ( string key_short + , string key_long + , bool arg=false + , string val="" + ) throw (except_done) +{ + long key_index; + + + // Coherency checks. + if (key_short.size() != 1) { + cerr << herr (" COpts::add() :\n") + << " Bad short argument : \"" << key_short << "\",\n" + << " Short arguments must be excatly one character long.\n" + << "\n\n"; + throw except_done(); + } + + if (key_long.size() < 2) { + cerr << herr (" COpts::add() :\n") + << " Bad long argument : \"" << key_long << "\",\n" + << " Long arguments must be more than one character long.\n" + << "\n\n"; + throw except_done(); + } + + if ((*this)[key_short] != NULL) { + cerr << herr (" COpts::add() :\n") + << " Duplicate short argument : \"" << key_short << "\".\n" + << "\n\n"; + throw except_done(); + } + + if ((*this)[key_long] != NULL) { + cerr << herr (" COpts::add() :\n") + << " Duplicate long argument : \"" << key_long << "\".\n" + << "\n\n"; + throw except_done(); + } + + + // Add to the option list & dictionnary. + tList.push_back (new COpt (arg, val)); + key_index = tList.size() - 1; + + tDict[key_short] = key_index; + tDict[key_long ] = key_index; + + // Add to the short option string. + tShort += key_short; + if (arg) tShort += ":"; +} + + +// ------------------------------------------------------------------- +// Modifier : "COpts::getopts()". + +void COpts::getopts (int argc, char *argv[]) throw (except_done) +{ + extern int opterr; + extern int optopt; + extern int optind; + extern char *optarg; + int key; + long key_index; + string key_string; + const char *short_format; + + + opterr = 0; + + short_format = tShort.c_str(); + + // Loop over getopt. + while (true) { + key = getopt (argc, argv, short_format); + + if (key == -1) break; + + if (key == (int)'?') { + cerr << herr (" COpts::getopts() :\n") + << " Unrecognized short argument : \"-" + << (char)optopt << "\".\n" + << "\n\n"; + throw except_done (); + } + + // Update the option status. + key_string = (char)key; + key_index = (*this)(key_string); + tList[key_index]->parsed = true; + + // Get any optionnal argument. + if (tList[key_index]->has_arg) { + tList[key_index]->value = optarg; + } + } + + + // Store non options arguments into "tArg". + for (key = optind; key < argc; key++) { + tVals.push_back (argv[key]); + } +} + + +// ------------------------------------------------------------------- +// Operator : "COpts::operator()". + +long COpts::operator() (string key) throw (except_done) +{ + long key_index; + MOpt::iterator iter; + + + iter = tDict.find (key); + + if (iter == tDict.end ()) { + cerr << herr (" COpts::operator() :\n") + << " Option not found : \"" << key << "\".\n" + << "\n\n"; + throw except_done (); + } + + return ((*iter).second); +} + + +// ------------------------------------------------------------------- +// Operator : "COpts::operator[]". + +struct COpts::COpt *COpts::operator[] (string key) +{ + MOpt::iterator iter; + + + iter = tDict.find (key); + + if (iter == tDict.end ()) { return (NULL); } + + return (tList[(*iter).second]); +} diff --git a/alliance/src/nero/src/USys.cpp b/alliance/src/nero/src/USys.cpp new file mode 100644 index 00000000..7f8d4ef6 --- /dev/null +++ b/alliance/src/nero/src/USys.cpp @@ -0,0 +1,206 @@ + +// -*- C++ -*- +// +// $Id: USys.cpp,v 1.1 2002/10/02 21:23:49 jpc Exp $ +// +// /----------------------------------------------------------------\ +// | | +// | A l l i a n c e C A D S y s t e m | +// | S i m p l e R o u t e r | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : alliance-support@asim.lip6.fr | +// | ============================================================== | +// | C++ Module : "./USys.cpp" | +// | ************************************************************** | +// | U p d a t e s | +// | | +// \----------------------------------------------------------------/ + + + + +# include +# include +# include "UDefs.h" + + + +# define SIGTFLT 1 + + + +// ------------------------------------------------------------------- +// Local Namespace. + +namespace { + + // --------------------------------------------------------------- + // Local Types. + + + + + // --------------------------------------------------------------- + // Local functions. + + static void trap_sig(int aSig); + + + +// /----------------------------------------------------------------\ +// | Functions Definitions | +// \----------------------------------------------------------------/ + +// ------------------------------------------------------------------- +// Function : "trap_sig()". + +static void trap_sig(int aSig) +{ + switch (aSig) + { + case SIGINT: + // User interrupt with CTRL-C. + emergency (); + break; + + case SIGTERM: + // This occurs on MBK errors. + cerr << herr(""); + cerr << "\n An error have occur in the MBK data-base."; + cerr << "\n Please check your Alliance environment."; + cerr << "\n\n"; + cerr << "\n program terminated."; + cerr << "\n" ; + break; + + case SIGFPE: + case SIGBUS: + case SIGSEGV: + emergency (); + + // Ouch !! This may result from a program bug. + cerr << "\n An program internal bug have occur "; + + if (aSig == SIGFPE ) cerr << "(SIGFPE)."; + if (aSig == SIGBUS ) cerr << "(SIGBUS)."; + if (aSig == SIGSEGV) cerr << "(SIGSEGV)."; + + cerr << "\n Please e-mail to \"alliance-support@asim.lip6.fr\"."; + cerr << "\n\n"; + cerr << "\n program terminated "; + + if (!interrupt.coredump) { + cerr << "(core not dumped).\n"; + exit (1); + } + else { + cerr << "(core will be dumped).\n"; + if ( (signal(SIGFPE , SIG_DFL) == SIG_ERR) + || (signal(SIGBUS , SIG_DFL) == SIG_ERR) + || (signal(SIGSEGV, SIG_DFL) == SIG_ERR)) + exit (1); + else { + kill (getpid(), aSig); + return; + } + } + break; + + default: + /* Unexpected signal. */ + cerr << "USys"; + cerr << "\n Unexpected signal \'" << aSig << "\' in trap function.\n"; + break; + } + + exit (1); +} + + + // --------------------------------------------------------------- + // End of Local Namespace. + +} + + + // --------------------------------------------------------------- + // Pre-defined objects. + + // Output stream manipulators (header writing). + CHeader herr ("\n*** error ***:"); + CHeader hwarn ("\n*** warning ***:"); + CHeader herrmbk ("\n*** MBK error ***:"); + CHeader hwarnmbk ("\n*** MBK warning ***:"); + + // Messages stream of corresponding to various verbosity levels. + CMess cmess0 (0); + CMess cmess1 (1); + CMess cmess2 (2); + + long CMess::_state = 0; + + // Debug stream. + CDebug cdebug (false); + + // Interrupt handler. + CInterrupt interrupt; + + + +// /----------------------------------------------------------------\ +// | Methods Definitions | +// \----------------------------------------------------------------/ + +// ------------------------------------------------------------------- +// Constructor : "CHeader::CHeader()". + +CHeader::CHeader (string h) +{ + _header = h; +} + + +// ------------------------------------------------------------------- +// Operator overload : "()". + +CHeader CHeader::operator() (string m) +{ + _message = m; + + return (*this); +} + + +// ------------------------------------------------------------------- +// Function (friend) : "operator<<()". + +inline ostream &operator<< (ostream &o, const CHeader &self) +{ + o << self._header; + if (self._message.size ()) + o << self._message; + + return (o); +} + + +// ------------------------------------------------------------------- +// Constructor : "CInterrupt::CInterrupt()". + +CInterrupt::CInterrupt (void) +{ + coredump = false; + + // Set the trap function for SIGTERM signal (sent by MBK errors). + if (signal(SIGTERM, trap_sig) == SIG_ERR) { trap_sig (SIGTFLT); } + + // Set the trap function for the SIGINT signal (CTRL-C). + if (signal(SIGINT, trap_sig) == SIG_ERR) { trap_sig (SIGTFLT); } + + // Set the trap function for SIGFPE, SIGBUS and SIGSEGV signals. + if ( (signal(SIGFPE , trap_sig) == SIG_ERR) + || (signal(SIGBUS , trap_sig) == SIG_ERR) + || (signal(SIGSEGV, trap_sig) == SIG_ERR)) trap_sig (SIGTFLT); + +} diff --git a/alliance/src/nero/src/debug.cpp b/alliance/src/nero/src/debug.cpp new file mode 100644 index 00000000..b185c178 --- /dev/null +++ b/alliance/src/nero/src/debug.cpp @@ -0,0 +1,1253 @@ + +// -*- C++ -*- + +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include + +# include + + + + + + // --------------------------------------------------------------- + // Use of a cleared priority map exception. + + class primap_clear : public exception { + + // Overridables. + public: virtual const char* what () const { + return ((char*)"Use of cleared signal priority map."); + } + }; + + + + + // --------------------------------------------------------------- + // Coordinate class. + + class CCoord { + + public: int x; + public: int y; + public: int z; + + // Constructors. + public: CCoord (void) { x = y = z = 0; } + public: CCoord (int i, int j, int k) { x = i; y = j; z = k; } + + }; + + + + + // --------------------------------------------------------------- + // Rectangle class. + + struct CRect { + + // Attributes. + long x1; + long y1; + long x2; + long y2; + + // Friend. + friend ostream &operator<< (ostream &, const CRect *); + + }; + + + class CNode; + class CNet; + + + class CNodeData { + + // Attributes. + public: int pri; + public: CNet *owner; + public: CNode *rtree; + public: int ident; + public: bool obstacle; + public: bool lock; + + }; + + + class CNode { + + public: CNodeData data; + + }; + + + + + // --------------------------------------------------------------- + // Bounding Box class. + + class CBB { + + // Attributes. + public: int x1; + public: int y1; + public: int x2; + public: int y2; + public: int hp; + + // Constructor. + public: CBB (void); + + // Modifiers. + public: void merge (CCoord &coord); + + // Friends. + public: friend ostream &operator<< (ostream &o, CBB &self); + }; + + + + + // --------------------------------------------------------------- + // Matrix iterator exception class. + + class e_matrix_iterator : public exception { + + // Attributes. + string message; + + // Constructor. + public: e_matrix_iterator (string msg) { message = msg; } + + // Overridables. + public: virtual const char* what () const { return (message.c_str()); } + + }; + + + + + class CDRGrid; + + + + + // --------------------------------------------------------------- + // Detailed Routing Matrix Class. + + template class TMatrix { + + // Matrix hollow level class --------------------------------- + + public: struct _CHollow { + + typedef map _CRow; + typedef map _CLayer; + + // Attributes. + public: _CLayer nodes; + + // Destructor. + ~_CHollow (void); + + // Modifier. + public: __CNode__ &add (int x, int y); + + // Accessor. + public: __CNode__ *get (int x, int y); + + }; + + + // Internal attributes. + public: CDRGrid *_drgrid; + public: _CHollow *_zero; + public: __CNode__ *_grid; + public: __CNode__ hole; + + + // Constructor. + public: TMatrix (CDRGrid *drgrid); + + // Destructor. + public: ~TMatrix (void); + + // Accessors. + public: __CNode__ &operator[] (int index); + + // Modifiers. + public: __CNode__ &add (int index); + + }; + + + typedef TMatrix CMatrixNodes; + + + class CMatrixPri : public TMatrix { + + // Internal attributes. + protected: CBB _bb; + + // Attributes. + public: int offset; + public: int delta; + public: bool cleared; + + + // Constructor. + public: CMatrixPri (CDRGrid *drgrid) : TMatrix(drgrid) { } + + // Modifiers. + public: void clear (void); + public: void load (CNet &net, bool global, int expand=0); + public: bool cmp (int pri, int index); + public: void findfree (int index); + + // Internal methods. + private: char nextPri (char curpri); + + // Friends. + public: friend ostream &operator<< (ostream &o, CMatrixPri &self); + + }; + + + + + // --------------------------------------------------------------- + // Detailed Routing Grid Class. + + class CDRGrid { + + // Matrix common iterator class ------------------------------ + + public: class iterator { + + // Attributes. + public: int _index; + public: CDRGrid *_drgrid; + + // Constructors. + public: iterator (void); + public: iterator (iterator &other); + + // Accessors. + public: operator int (void) { return ( _index ); } + public: operator CCoord (void) + { return ( CCoord (x(), y(), z()) ); } + public: bool operator== (iterator &other) + { return ( (_drgrid == other._drgrid) + && (_index == other._index ) ); } + public: char &pri (void); + public: CNode &node (void); + public: CNode &addnode (void); + + public: friend ostream &operator<< (ostream &o, iterator &self); + + public: void valid (bool validindex) throw (e_matrix_iterator); + public: int x (void) { return ( _drgrid->x (_index) ); } + public: int y (void) { return ( _drgrid->y (_index) ); } + public: int z (void) { return ( _drgrid->z (_index) ); } + public: bool outside (void) { return ( _index == INT_MAX ); } + public: bool inside (void) { return ( !outside() ); } + public: int manhattan (iterator &other) throw (e_matrix_iterator); + + // Modifiers. + public: iterator &set (int x, int y, int z); + public: iterator &set (CCoord &coord) + { return ( set(coord.x, coord.y, coord.z) ); } + public: iterator &dx (int d); + public: iterator &dy (int d); + public: iterator &dz (int d); + public: iterator &left (void) { return ( dx(-1) ); }; + public: iterator &right (void) { return ( dx(+1) ); }; + public: iterator &down (void) { return ( dy(-1) ); }; + public: iterator &up (void) { return ( dy(+1) ); }; + public: iterator &bottom (void) { return ( dz(-1) ); }; + public: iterator &top (void) { return ( dz(+1) ); }; + + }; + + + // Matrix class ---------------------------------------------- + + // Attributes. + public: int X; + public: int Y; + public: int Z; + public: int XY; + public: int XYZ; + public: int size; + public: int cost_x_hor; + public: int cost_x_ver; + public: int cost_y_hor; + public: int cost_y_ver; + public: int cost_z; + + public: iterator origin; + public: CMatrixPri *pri; + public: CMatrixNodes *nodes; + + // Constructor. + public: CDRGrid (int x, int y, int z); + + // Destructor. + public: ~CDRGrid (void); + + // Modifiers. + 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); } + public: int y (int index) { return ((index / X ) % Y); } + public: int z (int index) { return ((index / XY) % Z); } + public: int dx (int index, int d); + public: int dy (int index, int d); + public: int dz (int index, int d); + public: int id (int x, int y, int z) + { return ( x + (X * (y + (Y * z))) ); } + + }; + + + + +// ------------------------------------------------------------------- +// Constructor : "CDRGrid::iterator::iterator ()". + +CDRGrid::iterator::iterator (void) +{ + _drgrid = NULL; + _index = INT_MAX; +} + + + + +// ------------------------------------------------------------------- +// Constructor : "CDRGrid::iterator::iterator ()". + +CDRGrid::iterator::iterator (CDRGrid::iterator &other) +{ + _drgrid = other._drgrid; + _index = other._index; +} + + + + +// ------------------------------------------------------------------- +// Method : "CDRGrid::iterator::valid ()". + +void CDRGrid::iterator::valid (bool validindex) + throw (e_matrix_iterator) +{ + if (_drgrid == NULL) { + throw e_matrix_iterator ("Attempt to use an unitialized grid iterator."); + } + + if ( (validindex) && (_index == INT_MAX) ) + throw e_matrix_iterator ("Attempt to use iterator outside the matrix."); +} + + + + +// ------------------------------------------------------------------- +// Method : "CDRGrid::iterator::set ()". + +CDRGrid::iterator &CDRGrid::iterator::set (int x, int y, int z) +{ + valid (false); + + _index = _drgrid->dx (_index, x); + _index = _drgrid->dy (_index, y); + _index = _drgrid->dz (_index, z); + + return ( *this ); +} + + + + +// ------------------------------------------------------------------- +// Method : "CDRGrid::iterator::dx ()". + +CDRGrid::iterator &CDRGrid::iterator::dx (int d) +{ + valid (false); + + _index = _drgrid->dx (_index, d); + + return ( *this ); +} + + + + +// ------------------------------------------------------------------- +// Method : "CDRGrid::iterator::dy ()". + +CDRGrid::iterator &CDRGrid::iterator::dy (int d) +{ + valid (false); + + _index = _drgrid->dy (_index, d); + + return ( *this ); +} + + + + +// ------------------------------------------------------------------- +// Method : "CDRGrid::iterator::dz ()". + +CDRGrid::iterator &CDRGrid::iterator::dz (int d) +{ + valid (false); + + _index = _drgrid->dz (_index, d); + + return ( *this ); +} + + + + +// ------------------------------------------------------------------- +// Accessor : "CDRGrid::iterator::pri". + +char &CDRGrid::iterator::pri (void) +{ + valid (false); + + return ( (*(_drgrid->pri))[*this] ); +} + + + + +// ------------------------------------------------------------------- +// Accessor : "CDRGrid::iterator::node". + +CNode &CDRGrid::iterator::node (void) +{ + valid (false); + + return ( (*(_drgrid->nodes))[*this] ); +} + + + + +// ------------------------------------------------------------------- +// Modifier : "CDRGrid::iterator::addnode". + +CNode &CDRGrid::iterator::addnode (void) +{ + valid (true); + + return ( _drgrid->nodes->add (this->_index) ); +} + + + + +// ------------------------------------------------------------------- +// Friend : "CDRGrid::iterator::operator<< ()". + +ostream &operator<< (ostream &o, CDRGrid::iterator &self) +{ + o << "CDRGrid<>::iterator (_drgrid := " << self._drgrid + << ", _index := " << self._index + << " (" << self.x() << "," << self.y() << "," << self.z() << "))"; + + return ( o ); +} + + + + +// ------------------------------------------------------------------- +// Method : "CDRGrid::iterator::manhattan ()". + +int CDRGrid::iterator::manhattan (iterator &other) + throw (e_matrix_iterator) +{ + long manhattan; + + + valid (true); + other.valid (true); + + if (_drgrid != other._drgrid) + throw (e_matrix_iterator ("Attempt to use iterators from different grids.")); + + manhattan = abs (x() - other.x()) * _drgrid->cost_x_hor; + manhattan += abs (y() - other.y()) * _drgrid->cost_y_ver; + manhattan += abs (z() - other.z()) * _drgrid->cost_z; + + // As we never use ALU1 layer, add the cost of VIA. + if (z() == 0) manhattan += _drgrid->cost_z; + if (other.z() == 0) manhattan += _drgrid->cost_z; + + return (manhattan); +} + + + + +// ------------------------------------------------------------------- +// Constructor : "CDRGrid::CDRGrid()". + +CDRGrid::CDRGrid (int x, int y, int z) +{ + int index; + + + X = x; + Y = y; + Z = z; + XY = X * Y; + XYZ = XY * Z; + size = XY * (Z - 1); + + nodes = new CMatrixNodes (this); + pri = new CMatrixPri (this); + + cost_x_hor = cost_y_ver = cost_z = 1; + cost_x_ver = cost_y_hor = 2; + + // Reference iterator initialisation. + origin._drgrid = this; + origin._index = XY; +} + + + + +// ------------------------------------------------------------------- +// Destructor : "CDRGrid::~CDRGrid()". + +CDRGrid::~CDRGrid (void) +{ + delete [] nodes; + delete [] pri; +} + + + + +// ------------------------------------------------------------------- +// Modifier : "CDRGrid::costs ()". + +void CDRGrid::costs (int x_hor, int x_ver, int y_hor, int y_ver, int z) +{ + cost_x_hor = x_hor; + cost_x_ver = x_ver; + cost_y_hor = y_hor; + cost_y_ver = y_ver; + cost_z = z; +} + + + + +// ------------------------------------------------------------------- +// Modifier : "CDRGrid::dx ()". + +int CDRGrid::dx (int index, int d) +{ + if ( (index == INT_MAX) || (x(index) + d < 0) || (x(index) + d >= X) ) + return (INT_MAX); + + return (index + d); +} + + + + +// ------------------------------------------------------------------- +// Modifier : "CDRGrid::dy ()". + +int CDRGrid::dy (int index, int d) +{ + if ( (index == INT_MAX) || (y(index) + d < 0) || (y(index) + d >= Y) ) + return (INT_MAX); + + return (index + d*X); +} + + + + +// ------------------------------------------------------------------- +// Modifier : "CDRGrid::dz ()". + +int CDRGrid::dz (int index, int d) +{ + if ( (index == INT_MAX) || (z(index) + d < 0) || (z(index) + d >= Z) ) + return (INT_MAX); + + return (index + d*XY); +} + + + + +// ------------------------------------------------------------------- +// Destructor : "TMatrix::_CHollow::~_CHollow()". + +template +TMatrix<__CNode__>::_CHollow::~_CHollow (void) +{ + _CRow::iterator itRow; + _CLayer::iterator itLayer; + + + for (itLayer = nodes.begin (); + itLayer != nodes.end (); itLayer++) { + for (itRow = itLayer->second.begin (); + itRow != itLayer->second.end (); itRow++) { + delete itRow->second; + } + } +} + + + + +// ------------------------------------------------------------------- +// Method : "TMatrix::_CHollow::add()". + +template +__CNode__ &TMatrix<__CNode__>::_CHollow::add (int x, int y) +{ + _CRow::iterator itRow; + _CLayer::iterator itLayer; + + + itLayer = nodes.find (x); + if (itLayer == nodes.end ()) { nodes[x] = _CRow (); } + + itRow = nodes[x].find (y); + if (itRow == nodes[x].end ()) { nodes[x][y] = new __CNode__ (); } + + return (*(nodes[x][y])); +} + + + + +// ------------------------------------------------------------------- +// Method : "TMatrix::_CHollow::get()". + +template +__CNode__ *TMatrix<__CNode__>::_CHollow::get (int x, int y) +{ + _CRow::iterator itRow; + _CLayer::iterator itLayer; + + + itLayer = nodes.find (x); + if (itLayer == nodes.end ()) { return (NULL); } + + itRow = nodes[x].find (y); + if (itRow == nodes[x].end ()) { return (NULL); } + + return ((*itRow).second); +} + + + + +// ------------------------------------------------------------------- +// Constructor : "TMatrix::TMatrix()". + +template +TMatrix<__CNode__>::TMatrix (CDRGrid *drgrid) +{ + _drgrid = drgrid; + _grid = new (__CNode__) [_drgrid->size]; +} + + + + +// ------------------------------------------------------------------- +// Destructor : "~TMatrix::TMatrix()". + +template +TMatrix<__CNode__>::~TMatrix (void) +{ + delete [] _grid; +} + + + + +// ------------------------------------------------------------------- +// Accessor : "TMatrix::&operator[]". + +template +__CNode__ &TMatrix<__CNode__>::operator[] (int index) +{ + __CNode__ *node; + + + if (index < _drgrid->XY ) { + node = _zero->get (_drgrid->x(index), _drgrid->y(index)) ; + if ( node != NULL ) return ( *node ); + } else { + if (index < _drgrid->XYZ) return ( _grid[index - _drgrid->XY] ); + } + + return ( hole ); +} + + + + +// ------------------------------------------------------------------- +// Modifier : "TMatrix::add ()". + +template +__CNode__ &TMatrix<__CNode__>::add (int index) +{ + if (index < _drgrid->XY) { + return ( _zero->add (_drgrid->x(index), _drgrid->y(index)) ); + } else { + if (index < _drgrid->XYZ) return ( (*this)[index] ); + } + + return ( hole ); +} + + + + +// ------------------------------------------------------------------- +// Module : "UNet.cpp". + + + // --------------------------------------------------------------- + // Duplicate terminal node exception. + + class dup_term : public exception { + + // Attributes. + public: string name; + public: CNode *node; + + // Constructor. + public: dup_term (string termName, CNode *dupNode) { + name = termName; + node = dupNode; + } + + // Overridables. + public: virtual const char* what () const { + return ((char*)"Duplicated terminal node."); + } + }; + + + + + // --------------------------------------------------------------- + // Terminal class. + + class CTerm { + + // Attributes. + public: int id; + public: string name; + public: list nodes; + public: list rects; + + // Constructor. + public: CTerm (string termName, int ident); + + // Destructor. + public: ~CTerm (void); + + // Accessors. + public: int distance (CTerm &other); + public: CTerm &nearest (CTerm &term1, CTerm &term2); + public: CNode &lowest (void); + + // Modifiers. + public: CNode *newaccess (int x, int y, int z, int ident, CNet *net) throw (dup_term); + public: void newaccess (CRect &rect, int z, int ident, CNet *net); + public: void lockalone (bool global=false); + public: void setid (int ident); + + }; + + + + + // --------------------------------------------------------------- + // Duplicate net exception. + + class dup_net : public exception { + + // Attributes. + public: string name; + + // Constructor. + public: dup_net (string netName) { name = netName; } + + // Overridables. + public: virtual const char* what () const { + return ((char*)"Duplicated net."); + } + }; + + + + + // --------------------------------------------------------------- + // Unknown terminal exception. + + class term_unknown : public exception { + + // Attributes. + public: string netName; + public: string termName; + + // Constructor. + public: term_unknown (string nName, string tName) { + netName = nName; + termName = tName; + } + + // Overridables. + public: virtual const char* what () const { + return ((char*)"Unkown terminal."); + } + }; + + + + + // --------------------------------------------------------------- + // Net class. + + class CNet { + + // Attributes. + public: int pri; + public: string name; + public: vector terms; + public: CNode* rtree; + public: CBB bb; + public: int size; + public: bool external; + + // Constructor. + public: CNet (string netName="noname"); + + // Destructor. + public: ~CNet (void); + + // Operator. + public: bool operator< (CNet &other); + + // Accessor. + public: bool global (void) { return (bb.hp >= 400); } + + // Modifiers. + public: void newaccess (string termName, int x, int y, int z); + public: void newaccess (string termName, CRect &rect, int z); + public: void order (void); + public: void lockalone (void); + public: void locktree (void); + public: void route (void); + public: void unroute (void); + + // Friends. + public: friend ostream &operator<< (ostream &o, CNet *self); + + }; + + typedef map MNet; + + + + +// ------------------------------------------------------------------- +// Constructor : "CBB::CBB()". + +CBB::CBB (void) +{ + x1 = INT_MAX; + y1 = INT_MAX; + x2 = 0; + y2 = 0; + hp = 0; +} + + + + +// ------------------------------------------------------------------- +// Method : "CBB::merge()". + +void CBB::merge (CCoord &coord) +{ + x1 = min (x1, coord.x); + y1 = min (y1, coord.y); + x2 = max (x2, coord.x); + y2 = max (y2, coord.y); + + hp = (x2 - x1) + (y2 - y1); +} + + + + +// ------------------------------------------------------------------- +// Friend of "CBB" : "&operator<<()". + +ostream &operator<< (ostream &o, CBB &self) +{ + o << "CBB (" << self.x1 << "," << self.y1 << ") (" + << self.x2 << "," << self.y2 << ") HP := " << self.hp; + + return (o); +} + + + + +// ------------------------------------------------------------------- +// Method : "CMatrixPri::findfree()". + +void CMatrixPri::findfree (int index) +{ + CDRGrid::iterator coord; + int radius, i, j, cx, cy; + bool freed; + + + freed = false; + radius = 0; + cx = _drgrid->x(index); + cy = _drgrid->y(index); + coord = _drgrid->origin; + + while (!freed) { + radius += 1; + + for (i = cx - radius; i < cx + radius + 1; i++) { + for (j = cy - radius; j < cy + radius + 1; j++) { + // Proccess only nodes of the ring. + // if ( (i > cx - radius) || (i < cx + radius) ) continue; + // if ( (j > cy - radius) || (j < cy + radius) ) continue; + + if ( !( (*_drgrid->nodes)[ coord.set(i,j,2) ].data.obstacle ) ) freed = true; + + (*this)[ coord.set(i,j,1) ] = (char)1; + (*this)[ coord.set(i,j,2) ] = (char)1; + } + } + } +} + + + + +// ------------------------------------------------------------------- +// Method : "CMatrixPri::clear()". + +void CMatrixPri::clear (void) +{ + memset (_grid, (char)0, _drgrid->size); + + cleared = true; + offset = 0; + delta = 0; +} + + + + +// ------------------------------------------------------------------- +// Method : "CMatrixPri::nextPri()". + +char CMatrixPri::nextPri (char curpri) +{ + return ((curpri > 1) ? (curpri >> 1) : 1); +} + + + + +// ------------------------------------------------------------------- +// Method : "CMatrixPri::load()". + +void CMatrixPri::load (CNet &net, bool global, int expand=0) +{ + list::iterator itNode, beginNode, endNode; + queue queue1, queue2; + queue *currentBorder, *nextBorder; + CDRGrid::iterator *pCoord, coord; + + char currentPri, *pmap; + int x, y, z, nx, ny, nz, edge, id, ex, ey; + bool breakLoop; + + + clear (); + + offset = net.pri; + delta = 0; + + currentBorder = &queue1; + nextBorder = &queue2; + currentPri = 64; + + + // Expand the original BB if too small. + ex = 0; + ey = 0; + + if (net.bb.x2 - net.bb.x1 < 5) ex = 5; + if (net.bb.y2 - net.bb.y1 < 5) ey = 5; + + if (expand) ex = ey = expand; + + _bb.x1 = max (0 , net.bb.x1 - ex); + _bb.x2 = min (_drgrid->X - 1, net.bb.x2 + ex); + _bb.y1 = max (0 , net.bb.y1 - ey); + _bb.y2 = min (_drgrid->Y - 1, net.bb.y2 + ey); + + + // Build the initials border lists : coordinates of the terminals. + // The table doesn't have a z = 0 layer (never used for routing), + // so when a terminal on layer 0 is encountered, we queue the + // the coordinate on top in the next border queue. + // That is, in the first step of the algorithm we fill both queue + // at the same time. + // In the case of the map of a global signal (i.e. using z=3&4 for + // the time beeing, set to one the map points above the terminal + // in z=1&2, as they will not be set by the _bb loop. + + for (id = 0; id < net.size; id++) { + beginNode = (net.terms[id])->nodes.begin (); + endNode = (net.terms[id])->nodes.end (); + + for (itNode = beginNode; itNode != endNode; itNode++) { + coord = *itNode; + + // Initial queues filling. + if (coord.z() > 0) { + (*this)[ coord ] = currentPri; + currentBorder->push (new CDRGrid::iterator (coord)); + + // Enable z=1 (in case of global signal, no effet otherwise). + if (coord.z() < _drgrid->Z - 1) (*this)[ coord.dz(1) ] = (char)1; + + continue; + } + + (*this)[ coord.dz(1) ] = nextPri (currentPri); + nextBorder->push (new CDRGrid::iterator (coord)); + + // Enable z=2 (in case of global signal, no effet otherwise). + (*this)[ coord.dz(1) ] = (char)1; + + // Look if the upper node is blocked, in that case expand the + // allowed zone till a non-blocked node is found. + + if ( (*_drgrid->nodes)[ coord ].data.obstacle ) findfree (coord); + } + } + + + // Set to one all the points inside the enclosing box. + // (except those in the initial queues) + for (x = _bb.x1; x <= _bb.x2; x++) { + for (y = _bb.y1; y <= _bb.y2; y++) { + for (z = (global) ? 3 : 1; z < _drgrid->Z; z++) { + pmap = & ( (*this)[ coord.set (x, y, z) ] ); + if (pmap && (!(*pmap))) *pmap = (char)1; + } + } + } + + + breakLoop = false; + currentPri = nextPri (currentPri); + + // And here we go! + while (true) { + // Checks if the current border is finished. If so swap it with the + // nextBorder. If the current border is still empty, we are done. + if (currentBorder->empty ()) { + currentPri = nextPri (currentPri); + swap (currentBorder, nextBorder); + + if (currentBorder->empty ()) { + breakLoop = true; + } + } + if (breakLoop) break; + + pCoord = currentBorder->front (); + currentBorder->pop (); + + x = pCoord->x (); + y = pCoord->y (); + z = pCoord->z (); + + delete pCoord; + + for (edge = 0; edge < 6; edge++) { + nx = x; ny = y; nz =z; + + // Look at all six neighbors. + switch (edge) { + case 0: nx -= 1; break; + case 1: nx += 1; break; + case 2: ny -= 1; break; + case 3: ny += 1; break; + case 4: nz -= 1; break; + case 5: nz += 1; break; + } + + pmap = & ( (*this)[ coord.set (nx, ny, nz) ] ); + if (pmap == &(this->hole)) { continue; } + + // Usable nodes have been set to at least one, if not skip it. + if ( (pmap == NULL) || (*pmap == (char)0) ) continue; + + if (*pmap == (char)1) { + *pmap = currentPri; + // Push only nodes that are not of minimal priority. + if (currentPri > (char)1) + nextBorder->push (new CDRGrid::iterator (coord)); + } + } + + } + + + cleared = false; +} + + + + +// ------------------------------------------------------------------- +// Method : "CMatrixPri::cmp()". + +bool CMatrixPri::cmp (int pri, int index) +{ + char mappri; + + + mappri = (*this)[index]; + + if (!mappri) return (true); + if (!pri) return (false); + + return (pri + 256 >= mappri + delta); +} + + + + +// ------------------------------------------------------------------- +// Friend : "&operator<<()". + +ostream &operator<< (ostream &o, CMatrixPri &self) +{ + CDRGrid::iterator coord; + int x, y, z; + + o << "cleared := " << self.cleared << "\n" + << "offset := " << self.offset << "\n" + << "delta := " << self.delta << "\n"; + + coord = self._drgrid->origin; + + for (z = 1; z < self._drgrid->Z; z++) { + o << " (layer) z := " << z << "\n"; + + for (y = 1; y <= self._drgrid->Y; y++) { + o << " "; + for (x = 0; x < self._drgrid->X; x++) { + o << setw(5) << (int)(self[ + coord.set (x, self._drgrid->Y - y, z)]); + } + o << "\n"; + } + } + + return (o); +} + + + +int main (int argc, char *argv[]) +{ + + CDRGrid *grid; + CDRGrid::iterator itNode, itNode2; + + try { + //cout << &(*itNode) << endl; + + grid = new CDRGrid (10, 5, 3); + + itNode = grid->origin; + itNode2 = grid->origin; + + cout << "Browsing a row." << endl; + + for (; itNode.inside (); itNode.right ()) { + cout << " " << itNode + << "\n distance from origin := " + << itNode.manhattan (itNode2) << endl; + } + + cout << "Browsing a column." << endl; + + itNode = grid->origin; + for (; itNode.inside (); itNode.up ()) { + cout << " " << itNode << endl; + } + + cout << "Browsing layers." << endl; + + itNode = grid->origin; + for (; itNode.inside (); itNode.top ()) { + cout << " " << itNode << endl; + } + + itNode.manhattan (itNode2); + } + + catch (e_matrix_iterator &e) { + cerr << e.what () << endl; + } +} diff --git a/alliance/src/nero/src/nero.cpp b/alliance/src/nero/src/nero.cpp new file mode 100644 index 00000000..7268efa9 --- /dev/null +++ b/alliance/src/nero/src/nero.cpp @@ -0,0 +1,257 @@ + +// -*- C++ -*- +// +// $Id: nero.cpp,v 1.1 2002/10/02 21:23:49 jpc Exp $ +// +// /----------------------------------------------------------------\ +// | | +// | A l l i a n c e C A D S y s t e m | +// | S i m p l e R o u t e r | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : alliance-support@asim.lip6.fr | +// | ============================================================== | +// | C++ Module : "./nero.cpp" | +// | ************************************************************** | +// | U p d a t e s | +// | | +// \----------------------------------------------------------------/ + + + + +# include "RDefs.h" + + + + +// ------------------------------------------------------------------- +// Local Namespace. + +namespace { + + + // --------------------------------------------------------------- + // Local variables. + + static CRBox *crbox = NULL; + + + // --------------------------------------------------------------- + // Local functions. + + static void print_help (void); + + + + +// /----------------------------------------------------------------\ +// | Functions Definitions | +// \----------------------------------------------------------------/ + + +// ------------------------------------------------------------------- +// Function : "print_help()". + +static void print_help (void) +{ + cout << "\n" + << " o Usage : \"nero [-h] [-v] [-V] [-c] [-2] [-3] [-4] [-5] [-6]\n" + << " [-L] [-G] [-p ] " + << "\"\n\n" + << " \"nero [--help] [--verbose] [--very-verbose]\n" + << " [--core-dump] [--global] [--local]\n" + << " [--place ] \n" + << " \"\n\n" + << " o Options :\n" + << " [-h|--help] := Print this message.\n" + << " [-v|--verbose] := Be verbose.\n" + << " [-V|--very-verbose] := Be much more verbose...\n" + << " [-c|--core-dump] := Generate core dump if an internal " + << "error occurs.\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" + << " [-5|--layers-5] := Use only 5 routing layers.\n" + << " [-6|--layers-6] := Use only 6 routing layers.\n" + << " [-G|--global] := Force use of global routing.\n" + << " [-L|--local] := Disable use of global routing.\n" + << " [-p|--place ] :=\n" + << " Name of the layout file holding the placement, without\n" + << " extention. If ommited the layout file is assumed to have\n" + << " the same name as the netlist file .\n" + << " := Name of the netlist file (mandatory).\n" + << " := Name of the output layout file (mandatory).\n" + << "\n"; +} + + + // --------------------------------------------------------------- + // End of Local Namespace. + +} + + + + +// ------------------------------------------------------------------- +// Function : "emergency()". + +void emergency (void) +{ + string name = "emergency"; + + + if (crbox) crbox->mbksave (name); +} + + + + +// ------------------------------------------------------------------- +// Function : "main()". + +int main (int argc, char *argv[]) +{ + COpts options; + MBK::CFig *fig; + string name_lofig, name_placed, name_routed; + int layers, global; + + + try { + options.add ("v", "verbose"); + options.add ("V", "very-verbose"); + options.add ("h", "help"); + options.add ("c", "coredump"); + options.add ("2", "layers-2"); + options.add ("3", "layers-3"); + options.add ("4", "layers-4"); + options.add ("5", "layers-5"); + options.add ("6", "layers-6"); + options.add ("G", "global"); + options.add ("L", "local"); + options.add ("p", "place", true); + options.getopts (argc, argv); + + if (options["c"]->parsed) interrupt.coredump = true; + + cmess0.setVL (0); + if (options["v"]->parsed) cmess0.setVL (1); + if (options["V"]->parsed) cmess0.setVL (2); + + if ((cmess0.getVL () > 0) || options["h"]->parsed ) { + MBK::alliancebanner ( "NeRo" + , VERSION + , "Negotiating Router" + , "2002" + , ALLIANCE_VERSION + ); + cmess1 << "\n"; + } + + if (options["h"]->parsed) { + print_help (); + exit (0); + } + + if (options.tVals.size() < 2) { + cerr << herr ("nero:\n"); + cerr << " Missing mandatory argument or (or both)\n"; + cerr << "\n"; + + print_help (); + + throw except_done (); + } + + name_lofig = options.tVals[0]; + name_routed = options.tVals[1]; + + if (options["p"]->parsed) { + name_placed = options["p"]->value; + } else { + name_placed = name_lofig; + } + + layers = 3; + if (options["2"]->parsed) layers = 3; + if (options["3"]->parsed) layers = 4; + if (options["4"]->parsed) layers = 5; + if (options["5"]->parsed) layers = 6; + if (options["6"]->parsed) layers = 7; + + global = D::ROUTING_CHOOSE; + if (options["L"]->parsed) { global = D::ROUTING_LOCAL; } + if (options["G"]->parsed) { + global = D::ROUTING_GLOBAL; + + if (layers < 5) layers = 5; + } + + cmess1 << MBK::env; + + fig = new MBK::CFig (name_lofig, name_placed); + crbox = new CRBox (); + //crbox = new CRBox (global, true); + //cdebug.on (); + crbox->mbkload (fig, layers, global); + crbox->route (); + //cdebug.off (); + crbox->mbksave (name_routed); + } + + + catch (bad_grab &e) { + cerr << herr ("\n"); + cerr << " Net \"" << e.netName << "\" attempt to grab node (" + << e.x << "," << e.y << "," << e.z << "),\n" + << " which belongs to net \"" << e.ownerName << "\".\n" << endl; + cerr << " (nodepri := " << e.nodepri + << " , pri := " << e.pri << ", terminal := " << e.terminal + << ", ident := " << e.ident << ")\n" << endl; + + emergency (); + exit (1); + } + //catch (coord_outbound &e) { + // cerr << herr ("\n"); + // cerr << " Atempt to use outbound coordinates := (" + // << e.x << "," << e.y << "," << e.z << ") real := (" + // << MBK::UNSCALE (crbox->fig->XAB1() + e.x * D::X_GRID) << "," + // << MBK::UNSCALE (crbox->fig->YAB1() + e.y * D::Y_GRID) << "," + // << MBK::layer2a (MBK::env.z2alu (e.z)) << ")\n" + // << endl; + // + // emergency (); + // exit (1); + //} + // Case of exceptions that have already been processed. + catch (dup_term &e) { + cerr << " Duplicated terminal node for " << e.name + << " at " << e.node << endl; + + exit (1); + } + catch (except_done &e) { + cerr << e.what () << endl; + + emergency (); + exit (1); + } + + // Case of unexpected (undefined) exceptions. + catch (...) { + cerr << herr ("\n"); + cerr << " An unexpected exception have occurs.\n\n"; + cerr << " This is a bug. Please e-mail to \"alliance-support@asim.lip6.fr\".\n\n"; + + exit (1); + } + + + // This is the End. + cmess1 << "\n\n"; + + exit (0); +} diff --git a/alliance/src/nero/src/pdv.c b/alliance/src/nero/src/pdv.c new file mode 100644 index 00000000..fe58ea7a --- /dev/null +++ b/alliance/src/nero/src/pdv.c @@ -0,0 +1,126 @@ + + +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include + + +# define _ALU2_ 0 +# define _ALU3_ 1 +# define _ALU4_ 2 +# define _ALU5_ 3 +# define _ALU6_ 4 +# define _ALU7_ 5 +# define _ALU8_ 6 +# define _MAX_ALU_ 7 + + + +int main (int argc, char *argv[]) +{ + phfig_list *pFig; + phseg_list *pSeg; + phvia_list *pVIA; + + long length[_MAX_ALU_]; + long number[_MAX_ALU_]; + long total_length; + long total_number; + long total_VIA; + int i; + + + mbkenv (); + alliancebanner ( "PdV" + , "0.1" + , "Pot de Vin - Routing Evaluator" + , "2002" + , "5.0" + ); + + + if (argc < 2) { + fprintf (stderr, "Usage : pdv \n"); + + exit (1); + } + + + pFig = getphfig (argv[1], 'A'); + + for (i = 0; i < _MAX_ALU_; i++) { + length[i] = 0; + number[i] = 0; + } + + for (pSeg = pFig->PHSEG; pSeg != NULL; pSeg = pSeg->NEXT) { + switch (pSeg->LAYER) { + case ALU2: + case CALU2: i = _ALU2_; break; + case ALU3: + case CALU3: i = _ALU3_; break; + case ALU4: + case CALU4: i = _ALU4_; break; + case ALU5: + case CALU5: i = _ALU5_; break; + case ALU6: + case CALU6: i = _ALU6_; break; + case ALU7: + case CALU7: i = _ALU7_; break; + case ALU8: + case CALU8: i = _ALU8_; break; + default: continue; + } + + number[i]++; + + if (pSeg->X1 == pSeg->X2) { + /* Horizontal segments. */ + length[i] += (pSeg->Y2 - pSeg->Y1) / SCALE_X; + } else { + /* Vertical segments. */ + length[i] += (pSeg->X2 - pSeg->X1) / SCALE_X; + } + } + + for (i = 0; i < _MAX_ALU_; i++) { if (number[i] == 0) number[i]++; } + + + total_VIA = 0; + for (pVIA = pFig->PHVIA; pVIA != NULL; pVIA = pVIA->NEXT) { + total_VIA++; + } + + + + printf ("\n\n"); + printf (" Routing statistics :\n\n"); + + total_length = 0; + total_number = 0; + for (i = 0; i < _MAX_ALU_; i++) { + printf (" - ALU%d length := %10d", i+2, length[i]); + printf (" (average length := %d)\n", length[i] / number[i]); + + total_length += length[i]; + total_number += number[i]; + } + + printf ("\n"); + printf (" - Total length := %10d" , total_length); + printf (" (average length := %d)\n", total_length / total_number); + + printf ("\n"); + printf (" - Total VIA := %10d\n" , total_VIA); + printf ("\n\n"); + + + exit (0); +}