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 Name nero -- Negotiating Router
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)
+
\ 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
\ 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
\ 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);
+}