- Ajout de l'outil complet a l'arbre CVS.
This commit is contained in:
Jean-Paul Chaput 2002-10-02 21:23:49 +00:00
parent 03db981357
commit 524fb6fd06
49 changed files with 11453 additions and 0 deletions

View File

@ -0,0 +1,3 @@
## Process this file with automake to produce Makefile.in
SUBDIRS = src doc

View File

@ -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
])

View File

@ -0,0 +1,10 @@
SUBDIRS = nero
pdfdir = $(prefix)/doc/pdf
pdf_DATA = nero.pdf
EXTRA_DIST = $(pdf_DATA) \
./nero.sgm \
./man_nero.sgm

124
alliance/src/nero/doc/builddoc.sh Executable file
View File

@ -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

View File

@ -0,0 +1,215 @@
<refentry id="nero">
<?dbhtml filename="man_nero.html">
<refmeta>
<refentrytitle>nero</refentrytitle>
<manvolnum>1</manvolnum>
<refmiscinfo>ASIM/LIP6</refmiscinfo>
</refmeta>
<refnamediv>
<refname> nero </refname>
<refpurpose> Negotiating Router </refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>nero</command>
<arg>-h</arg>
<arg>-v</arg>
<arg>-V</arg>
<arg>-c</arg>
<arg>-2</arg>
<arg>-3</arg>
<arg>-4</arg>
<arg>-5</arg>
<arg>-6</arg>
<arg>-L</arg>
<arg>-G</arg>
<sbr>
<arg>--help</arg>
<arg>--verbose</arg>
<arg>--very-verbose</arg>
<arg>--core-dump</arg>
<arg>--local</arg>
<arg>--global</arg>
<sbr>
<arg>--place <replaceable>placement</replaceable></arg>
<arg choice="req"><replaceable>netlist</replaceable></arg>
<arg choice="req"><replaceable>layout</replaceable></arg>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1>
<title> Description </title>
<para> <literal>nero</literal> is a simple router suited for small
academic designs. Currently it can process designs of size up to
4K gates.
</para>
<refsect2>
<title> Global routing </title>
<para> A design is considered as <emphasis>big</emphasis> if it
contains nets which half perimeter is greater than 800 lambdas.
Global routing is used on big designs.
</para>
<para> In <literal>nero</literal>, "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.
</para>
</refsect2>
</refsect1>
<refsect1>
<title> Invocation </title>
<para> <literal>nero</literal> mandatory arguments&nbsp;:
<itemizedlist>
<listitem>
<para> <filename>netlist</filename>&nbsp;: the name of
the design, whithout any extention. Please note that unless a
<userinput>-p</userinput> <filename>placement</filename> option
is given, the file holding the placement is expected to have the
same name as the netlist file (short of the extention).
</para>
</listitem>
<listitem>
<para> <filename>layout</filename>&nbsp;: 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.
</para>
</listitem>
</itemizedlist>
</para>
<para> <literal>nero</literal> optionnals arguments&nbsp;:
<itemizedlist>
<listitem>
<para> <userinput>-h</userinput>, <userinput>--help</userinput>&nbsp;:
print help.
</para>
</listitem>
<listitem>
<para> <userinput>-v</userinput>, <userinput>--verbose</userinput>&nbsp;:
be verbose.
</para>
</listitem>
<listitem>
<para> <userinput>-V</userinput>, <userinput>--very-verbose</userinput>&nbsp;:
be unbearably verbose.
</para>
</listitem>
<listitem>
<para> <userinput>-c</userinput>, <userinput>--core-dump</userinput>&nbsp;:
do not prevent the generation of core dumps in case of a crash.
Mostly used during the development stage.
</para>
</listitem>
<listitem>
<para> <userinput>-2</userinput>,
<userinput>-3</userinput>,
<userinput>-4</userinput>,
<userinput>-5</userinput>,
<userinput>-6</userinput>&nbsp;: 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.
</para>
</listitem>
<listitem>
<para> <userinput>-L</userinput>, <userinput>--local</userinput>&nbsp;:
turn off the global routing stage, whatever the size of the design.
Be warned that this will enormously slow down the routing process.
</para>
</listitem>
<listitem>
<para> <userinput>-G</userinput>, <userinput>--global</userinput>&nbsp;:
turn on the global routing regardless of the size of the design.
</para>
</listitem>
<listitem>
<para> <userinput>-p</userinput> <filename>placement</filename>,
<userinput>--place</userinput> <filename>placement</filename>&nbsp;:
specify a name for the placement file different from the netlist
name.
</para>
</listitem>
</itemizedlist>
</para>
</refsect1>
<refsect1>
<title> Example </title>
<para> Route the netlist <literal>amd2901_core.vst</literal>, using
the placement file <literal>amd2901_core_p.ap</literal> and store the
result in <literal>amd2901_core_r</literal>.
<screen>
$ <userinput>export MBK_IN_LO=vst</userinput>
$ <userinput>export MBK_IN_PH=ap</userinput>
$ <userinput>export MBK_OUT_PH=ap</userinput>
$ <userinput>nero -V --place amd2901_core_p amd2901_core amd2901_core_r</userinput>
</screen>
</para>
</refsect1>
<refsect1>
<title>See Also</title>
<para>
<citerefentry>
<refentrytitle>MBK_IN_LO</refentrytitle>
<manvolnum>1</manvolnum>
</citerefentry>,
<citerefentry>
<refentrytitle>MBK_OUT_LO</refentrytitle>
<manvolnum>1</manvolnum>
</citerefentry>,
<citerefentry>
<refentrytitle>MBK_IN_PH</refentrytitle>
<manvolnum>1</manvolnum>
</citerefentry>,
<citerefentry>
<refentrytitle>MBK_OUT_PH</refentrytitle>
<manvolnum>1</manvolnum>
</citerefentry>,
<citerefentry>
<refentrytitle>ocp</refentrytitle>
<manvolnum>1</manvolnum>
</citerefentry>,
<citerefentry>
<refentrytitle>ocr</refentrytitle>
<manvolnum>1</manvolnum>
</citerefentry>,
<citerefentry>
<refentrytitle>druc</refentrytitle>
<manvolnum>1</manvolnum>
</citerefentry>,
<citerefentry>
<refentrytitle>cougar</refentrytitle>
<manvolnum>1</manvolnum>
</citerefentry>
</para>
</refsect1>
</refentry>

View File

@ -0,0 +1,49 @@
<!DOCTYPE Book PUBLIC "-//OASIS//DTD DocBook V4.1//EN" [
<!ENTITY man-nero SYSTEM "man_nero.sgm">
<!ENTITY Alliance "<emphasis>Alliance</emphasis>">
<!ENTITY Nero "<emphasis>Nero</emphasis>">
<!ENTITY nero "<userinput>nero</userinput>">
]>
<book lang="en">
<?dbhtml filename="nero.html">
<bookinfo>
<title> Nero User's Manual </title>
<date> September, 27 2002 </date>
<authorgroup>
<author>
<firstname> Jean-Paul </firstname>
<surname> Chaput </surname>
<affiliation>
<jobtitle> System Administrator </jobtitle>
<orgname> Pierre &amp; Marie Curie University, LIP6 </orgname>
<orgdiv> ASIM Department </orgdiv>
</affiliation>
</author>
</authorgroup>
<releaseinfo> September 2002 / 20020924.1 </releaseinfo>
<pubdate> September 2002 </pubdate>
</bookinfo>
<reference id="ref-nero">
<?dbhtml filename="ref_nero.html">
<title>&Alliance; - &nero; User's Manual </title>
&man-nero;
</reference>
</book>

View File

@ -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@

View File

@ -0,0 +1,559 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<HTML
><HEAD
><TITLE
>nero</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.76b+
"><LINK
REL="HOME"
TITLE=" Nero User's Manual "
HREF="nero.html"><LINK
REL="UP"
TITLE="Alliance - nero User's Manual "
HREF="ref_nero.html"><LINK
REL="PREVIOUS"
TITLE="Alliance - nero User's Manual "
HREF="ref_nero.html"></HEAD
><BODY
CLASS="REFENTRY"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="NAVHEADER"
><TABLE
SUMMARY="Header navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
>Nero User's Manual</TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="ref_nero.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
></TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
>&nbsp;</TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><H1
><A
NAME="NERO">nero</H1
><DIV
CLASS="REFNAMEDIV"
><A
NAME="AEN24"
></A
><H2
>Name</H2
> nero &nbsp;--&nbsp; Negotiating Router </DIV
><DIV
CLASS="REFSYNOPSISDIV"
><A
NAME="AEN27"><H2
>Synopsis</H2
><P
><B
CLASS="COMMAND"
>nero</B
> [-h] [-v] [-V] [-c] [-2] [-3] [-4] [-5] [-6] [-L] [-G]<BR> [--help] [--verbose] [--very-verbose] [--core-dump] [--local] [--global]<BR> [--place <TT
CLASS="REPLACEABLE"
><I
>placement</I
></TT
>] {<TT
CLASS="REPLACEABLE"
><I
>netlist</I
></TT
>} {<TT
CLASS="REPLACEABLE"
><I
>layout</I
></TT
>}</P
></DIV
><DIV
CLASS="REFSECT1"
><A
NAME="AEN55"
></A
><H2
> Description </H2
><P
> <TT
CLASS="LITERAL"
>nero</TT
> is a simple router suited for small
academic designs. Currently it can process designs of size up to
4K gates.
</P
><DIV
CLASS="REFSECT2"
><A
NAME="AEN59"
></A
><H3
> Global routing </H3
><P
> A design is considered as <I
CLASS="EMPHASIS"
>big</I
> if it
contains nets which half perimeter is greater than 800 lambdas.
Global routing is used on big designs.
</P
><P
> In <TT
CLASS="LITERAL"
>nero</TT
>, "global routing" means that
the longuests nets are completly routed in a first step with only
routing layers numbers 3 &#38; 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.
</P
></DIV
></DIV
><DIV
CLASS="REFSECT1"
><A
NAME="AEN65"
></A
><H2
> Invocation </H2
><P
> <TT
CLASS="LITERAL"
>nero</TT
> mandatory arguments :
<P
></P
><UL
><LI
><P
> <TT
CLASS="FILENAME"
>netlist</TT
> : the name of
the design, whithout any extention. Please note that unless a
<TT
CLASS="USERINPUT"
><B
>-p</B
></TT
> <TT
CLASS="FILENAME"
>placement</TT
> option
is given, the file holding the placement is expected to have the
same name as the netlist file (short of the extention).
</P
></LI
><LI
><P
> <TT
CLASS="FILENAME"
>layout</TT
> : 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.
</P
></LI
></UL
>
</P
><P
> <TT
CLASS="LITERAL"
>nero</TT
> optionnals arguments :
<P
></P
><UL
><LI
><P
> <TT
CLASS="USERINPUT"
><B
>-h</B
></TT
>, <TT
CLASS="USERINPUT"
><B
>--help</B
></TT
> :
print help.
</P
></LI
><LI
><P
> <TT
CLASS="USERINPUT"
><B
>-v</B
></TT
>, <TT
CLASS="USERINPUT"
><B
>--verbose</B
></TT
> :
be verbose.
</P
></LI
><LI
><P
> <TT
CLASS="USERINPUT"
><B
>-V</B
></TT
>, <TT
CLASS="USERINPUT"
><B
>--very-verbose</B
></TT
> :
be unbearably verbose.
</P
></LI
><LI
><P
> <TT
CLASS="USERINPUT"
><B
>-c</B
></TT
>, <TT
CLASS="USERINPUT"
><B
>--core-dump</B
></TT
> :
do not prevent the generation of core dumps in case of a crash.
Mostly used during the development stage.
</P
></LI
><LI
><P
> <TT
CLASS="USERINPUT"
><B
>-2</B
></TT
>,
<TT
CLASS="USERINPUT"
><B
>-3</B
></TT
>,
<TT
CLASS="USERINPUT"
><B
>-4</B
></TT
>,
<TT
CLASS="USERINPUT"
><B
>-5</B
></TT
>,
<TT
CLASS="USERINPUT"
><B
>-6</B
></TT
> : 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.
</P
></LI
><LI
><P
> <TT
CLASS="USERINPUT"
><B
>-L</B
></TT
>, <TT
CLASS="USERINPUT"
><B
>--local</B
></TT
> :
turn off the global routing stage, whatever the size of the design.
Be warned that this will enormously slow down the routing process.
</P
></LI
><LI
><P
> <TT
CLASS="USERINPUT"
><B
>-G</B
></TT
>, <TT
CLASS="USERINPUT"
><B
>--global</B
></TT
> :
turn on the global routing regardless of the size of the design.
</P
></LI
><LI
><P
> <TT
CLASS="USERINPUT"
><B
>-p</B
></TT
> <TT
CLASS="FILENAME"
>placement</TT
>,
<TT
CLASS="USERINPUT"
><B
>--place</B
></TT
> <TT
CLASS="FILENAME"
>placement</TT
> :
specify a name for the placement file different from the netlist
name.
</P
></LI
></UL
>
</P
></DIV
><DIV
CLASS="REFSECT1"
><A
NAME="AEN118"
></A
><H2
> Example </H2
><P
> Route the netlist <TT
CLASS="LITERAL"
>amd2901_core.vst</TT
>, using
the placement file <TT
CLASS="LITERAL"
>amd2901_core_p.ap</TT
> and store the
result in <TT
CLASS="LITERAL"
>amd2901_core_r</TT
>.
<TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="SCREEN"
>$ <TT
CLASS="USERINPUT"
><B
>export MBK_IN_LO=vst</B
></TT
>
$ <TT
CLASS="USERINPUT"
><B
>export MBK_IN_PH=ap</B
></TT
>
$ <TT
CLASS="USERINPUT"
><B
>export MBK_OUT_PH=ap</B
></TT
>
$ <TT
CLASS="USERINPUT"
><B
>nero -V --place amd2901_core_p amd2901_core amd2901_core_r</B
></TT
>
</PRE
></TD
></TR
></TABLE
>
</P
></DIV
><DIV
CLASS="REFSECT1"
><A
NAME="AEN129"
></A
><H2
>See Also</H2
><P
> <SPAN
CLASS="CITEREFENTRY"
><SPAN
CLASS="REFENTRYTITLE"
>MBK_IN_LO</SPAN
>(1)</SPAN
>,
<SPAN
CLASS="CITEREFENTRY"
><SPAN
CLASS="REFENTRYTITLE"
>MBK_OUT_LO</SPAN
>(1)</SPAN
>,
<SPAN
CLASS="CITEREFENTRY"
><SPAN
CLASS="REFENTRYTITLE"
>MBK_IN_PH</SPAN
>(1)</SPAN
>,
<SPAN
CLASS="CITEREFENTRY"
><SPAN
CLASS="REFENTRYTITLE"
>MBK_OUT_PH</SPAN
>(1)</SPAN
>,
<SPAN
CLASS="CITEREFENTRY"
><SPAN
CLASS="REFENTRYTITLE"
>ocp</SPAN
>(1)</SPAN
>,
<SPAN
CLASS="CITEREFENTRY"
><SPAN
CLASS="REFENTRYTITLE"
>ocr</SPAN
>(1)</SPAN
>,
<SPAN
CLASS="CITEREFENTRY"
><SPAN
CLASS="REFENTRYTITLE"
>druc</SPAN
>(1)</SPAN
>,
<SPAN
CLASS="CITEREFENTRY"
><SPAN
CLASS="REFENTRYTITLE"
>cougar</SPAN
>(1)</SPAN
>
</P
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="ref_nero.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="nero.html"
ACCESSKEY="H"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
>&nbsp;</TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><I
CLASS="EMPHASIS"
>Alliance</I
> - <TT
CLASS="USERINPUT"
><B
>nero</B
></TT
> User's Manual</TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="ref_nero.html"
ACCESSKEY="U"
>Up</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
>&nbsp;</TD
></TR
></TABLE
></DIV
></BODY
></HTML
>

View File

@ -0,0 +1,141 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<HTML
><HEAD
><TITLE
> Nero User's Manual </TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.76b+
"><LINK
REL="NEXT"
TITLE="Alliance - nero User's Manual "
HREF="ref_nero.html"></HEAD
><BODY
CLASS="BOOK"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="BOOK"
><A
NAME="AEN1"><DIV
CLASS="TITLEPAGE"
><H1
CLASS="TITLE"
><A
NAME="AEN2">Nero User's Manual</H1
><H3
CLASS="AUTHOR"
><A
NAME="AEN6"> Jean-Paul Chaput </H3
><DIV
CLASS="AFFILIATION"
><SPAN
CLASS="JOBTITLE"
> System Administrator <BR></SPAN
><SPAN
CLASS="ORGNAME"
> Pierre &#38; Marie Curie University, LIP6 <BR></SPAN
><SPAN
CLASS="ORGDIV"
> ASIM Department <BR></SPAN
></DIV
><SPAN
CLASS="RELEASEINFO"
> September 2002 / 20020924.1 <BR></SPAN
><HR></DIV
><DIV
CLASS="TOC"
><DL
><DT
><B
>Table of Contents</B
></DT
><DT
>I. <A
HREF="ref_nero.html"
><I
CLASS="EMPHASIS"
>Alliance</I
> - <TT
CLASS="USERINPUT"
><B
>nero</B
></TT
> User's Manual</A
></DT
><DD
><DL
><DT
><A
HREF="man_nero.html"
>nero</A
>&nbsp;--&nbsp; Negotiating Router </DT
></DL
></DD
></DL
></DIV
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
>&nbsp;</TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
>&nbsp;</TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="ref_nero.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
>&nbsp;</TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
>&nbsp;</TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><I
CLASS="EMPHASIS"
>Alliance</I
> - <TT
CLASS="USERINPUT"
><B
>nero</B
></TT
> User's Manual</TD
></TR
></TABLE
></DIV
></BODY
></HTML
>

View File

@ -0,0 +1,161 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<HTML
><HEAD
><TITLE
>Alliance - nero User's Manual </TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.76b+
"><LINK
REL="HOME"
TITLE=" Nero User's Manual "
HREF="nero.html"><LINK
REL="PREVIOUS"
TITLE=" Nero User's Manual "
HREF="nero.html"><LINK
REL="NEXT"
TITLE="nero"
HREF="man_nero.html"></HEAD
><BODY
CLASS="REFERENCE"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="NAVHEADER"
><TABLE
SUMMARY="Header navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
>Nero User's Manual</TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="nero.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
></TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="man_nero.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="REFERENCE"
><A
NAME="REF-NERO"><DIV
CLASS="TITLEPAGE"
><H1
CLASS="TITLE"
>I. <I
CLASS="EMPHASIS"
>Alliance</I
> - <TT
CLASS="USERINPUT"
><B
>nero</B
></TT
> User's Manual </H1
><DIV
CLASS="TOC"
><DL
><DT
><B
>Table of Contents</B
></DT
><DT
><A
HREF="man_nero.html"
>nero</A
>&nbsp;--&nbsp; Negotiating Router </DT
></DL
></DIV
></DIV
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="nero.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="nero.html"
ACCESSKEY="H"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="man_nero.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
>Nero User's Manual</TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
>&nbsp;</TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
>nero</TD
></TR
></TABLE
></DIV
></BODY
></HTML
>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 995 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 964 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 944 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 95 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 843 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 846 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 922 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -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<CDRGrid::iterator>::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<int>::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 );
}

View File

@ -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<CNodeAS*> 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<CNodeAS*> _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<int> 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<CQelem> 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<CQelem> 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

View File

@ -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 &center)
{
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<CNode*>::iterator itNode, beginNode, endNode;
queue<CCoord*> queue1, queue2;
queue<CCoord*> *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);
}

View File

@ -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 ();
}

View File

@ -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);
}

View File

@ -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<class __CNode__>
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<class __CNode__>
__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<class __CNode__>
__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<class __CNode__>
TMatrix<__CNode__>::TMatrix (CDRGrid *drgrid)
{
_drgrid = drgrid;
_grid = new (__CNode__) [_drgrid->size];
}
// -------------------------------------------------------------------
// Destructor : "~TMatrix::TMatrix()".
template<class __CNode__>
TMatrix<__CNode__>::~TMatrix (void)
{
delete [] _grid;
}
// -------------------------------------------------------------------
// Accessor : "TMatrix::&operator[]".
template<class __CNode__>
__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<class __CNode__>
__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 );
}

View File

@ -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 __CNode__> class TMatrix {
// Matrix hollow level class ---------------------------------
public: struct _CHollow {
typedef map<int, __CNode__*> _CRow;
typedef map<int, _CRow> _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<CNode> {
// Constructor.
public: CMatrixNodes (CDRGrid *drgrid) : TMatrix<CNode>(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<char> {
// Internal attributes.
protected: CBB _bb;
// Attributes.
public: int offset;
public: int delta;
public: bool cleared;
// Constructor.
public: CMatrixPri (CDRGrid *drgrid) : TMatrix<char>(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<CDRGrid::iterator> nodes;
public: list<CRect> 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<CTerm*> 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<string, CNet*> MNet;
// -------------------------------------------------------------------
// Module : "MMBK.h".
# include "MMBK.h"
#endif

File diff suppressed because it is too large Load Diff

View File

@ -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 <mut.h>
# include <mlo.h>
# include <mlu.h>
# include <mph.h>
# include <mpu.h>
# include <mgn.h>
# include <abl.h>
# include <aut.h>
# include <beh.h>
// -------------------------------------------------------------------
// 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<string, loins_list*> MLoins;
typedef map<string, losig_list*> MLosig;
typedef map<string, phins_list*> MPhins;
typedef map<char, long> 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<string, CIns*> 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<long, CPower> 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<int, CPowers*> MPowers;
// -------------------------------------------------------------------
// End of MBK namespace.
}
#endif

View File

@ -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<CNode*>::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<CDRGrid::iterator>::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<CDRGrid::iterator>::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<CDRGrid::iterator>::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<CDRGrid::iterator>::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<CDRGrid::iterator>::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<CTerm*>::iterator itTerm, endTerm, itUnord, endUnord, itNearest;
vector<CTerm*> 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);
}

View File

@ -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;
}
}
}

View File

@ -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<LInter *>(&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.
}

View File

@ -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<CDRGrid::iterator>::iterator itNode, beginNode, endNode;
queue<CDRGrid::iterator*> queue1, queue2;
queue<CDRGrid::iterator*> *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);
}

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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);
}

View File

@ -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();
}

View File

@ -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".
}

View File

@ -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 <iostream>
# include <iomanip>
# include <fstream>
# include <sstream>
# include <exception>
# include <iterator>
# include <utility>
# include <string>
# include <vector>
# include <queue>
# include <list>
# include <map>
# include <set>
# include <stdexcept>
# include <cstdlib>
# include <cmath>
# include <unistd.h>
// -------------------------------------------------------------------
// 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<class T>
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<class T>
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<string, long> MOpt;
typedef vector<COpt*> TOpt;
// Attributes.
private: MOpt tDict;
private: TOpt tList;
private: string tShort;
public: vector<string> 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<long, long> {
// Supplemental methods.
public: long cmp (CInter &);
// Friends.
friend ostream &operator<< (ostream &o, const CInter &self);
};
// ---------------------------------------------------------------
// Interval list class.
struct LInter : public list<CInter> {
// 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<class T> inline T min (T a, T b) { return ((a < b) ? a : b); }
//template<class T> inline T max (T a, T b) { return ((a > b) ? a : b); }
//template<class T> inline void swap (T a, T b) {
// T tmp;
//
// tmp = a; a = b; b = tmp;
// }
// -------------------------------------------------------------------
// Module : "nero.cpp".
// ---------------------------------------------------------------
// Functions.
void emergency (void);
#endif

View File

@ -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<class __CNode__>
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<class __CNode__>
__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<class __CNode__>
__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<class __CNode__>
TMatrix<__CNode__>::TMatrix (CDRGrid *drgrid)
{
_drgrid = drgrid;
_grid = new (__CNode__) [_drgrid->size];
}
// -------------------------------------------------------------------
// Destructor : "~TMatrix::TMatrix()".
template<class __CNode__>
TMatrix<__CNode__>::~TMatrix (void)
{
delete [] _grid;
}
// -------------------------------------------------------------------
// Accessor : "TMatrix::&operator[]".
template<class __CNode__>
__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<class __CNode__>
__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;
}
}
}

View File

@ -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);
}

View File

@ -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]);
}

View File

@ -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 <csignal>
# include <unistd.h>
# 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);
}

File diff suppressed because it is too large Load Diff

View File

@ -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 <placement>] <netlist> <layout>"
<< "\"\n\n"
<< " \"nero [--help] [--verbose] [--very-verbose]\n"
<< " [--core-dump] [--global] [--local]\n"
<< " [--place <placement>] <netlist> <layout>\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 <placement>] :=\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 <netlist>.\n"
<< " <netlist> := Name of the netlist file (mandatory).\n"
<< " <layout> := 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 <netlist> or <routed> (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);
}

126
alliance/src/nero/src/pdv.c Normal file
View File

@ -0,0 +1,126 @@
# include <mut.h>
# include <mlo.h>
# include <mlu.h>
# include <mph.h>
# include <mpu.h>
# include <mgn.h>
# include <abl.h>
# include <aut.h>
# include <beh.h>
# include <stdio.h>
# 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 <layout>\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);
}