|
@ -0,0 +1,3 @@
|
|||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
SUBDIRS = src doc
|
|
@ -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
|
||||
])
|
|
@ -0,0 +1,10 @@
|
|||
|
||||
SUBDIRS = nero
|
||||
|
||||
pdfdir = $(prefix)/doc/pdf
|
||||
pdf_DATA = nero.pdf
|
||||
|
||||
EXTRA_DIST = $(pdf_DATA) \
|
||||
./nero.sgm \
|
||||
./man_nero.sgm
|
||||
|
|
@ -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
|
|
@ -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 :
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para> <filename>netlist</filename> : 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> : 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 :
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para> <userinput>-h</userinput>, <userinput>--help</userinput> :
|
||||
print help.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para> <userinput>-v</userinput>, <userinput>--verbose</userinput> :
|
||||
be verbose.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para> <userinput>-V</userinput>, <userinput>--very-verbose</userinput> :
|
||||
be unbearably verbose.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para> <userinput>-c</userinput>, <userinput>--core-dump</userinput> :
|
||||
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> : 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> :
|
||||
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> :
|
||||
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> :
|
||||
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>
|
|
@ -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 & 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>
|
|
@ -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@
|
|
@ -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"
|
||||
><<< Previous</A
|
||||
></TD
|
||||
><TD
|
||||
WIDTH="80%"
|
||||
ALIGN="center"
|
||||
VALIGN="bottom"
|
||||
></TD
|
||||
><TD
|
||||
WIDTH="10%"
|
||||
ALIGN="right"
|
||||
VALIGN="bottom"
|
||||
> </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 -- 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 & 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"
|
||||
><<< 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"
|
||||
> </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"
|
||||
> </TD
|
||||
></TR
|
||||
></TABLE
|
||||
></DIV
|
||||
></BODY
|
||||
></HTML
|
||||
>
|
|
@ -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 & 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
|
||||
> -- 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"
|
||||
> </TD
|
||||
><TD
|
||||
WIDTH="34%"
|
||||
ALIGN="center"
|
||||
VALIGN="top"
|
||||
> </TD
|
||||
><TD
|
||||
WIDTH="33%"
|
||||
ALIGN="right"
|
||||
VALIGN="top"
|
||||
><A
|
||||
HREF="ref_nero.html"
|
||||
ACCESSKEY="N"
|
||||
>Next >>></A
|
||||
></TD
|
||||
></TR
|
||||
><TR
|
||||
><TD
|
||||
WIDTH="33%"
|
||||
ALIGN="left"
|
||||
VALIGN="top"
|
||||
> </TD
|
||||
><TD
|
||||
WIDTH="34%"
|
||||
ALIGN="center"
|
||||
VALIGN="top"
|
||||
> </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
|
||||
>
|
|
@ -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"
|
||||
><<< 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 >>></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
|
||||
> -- 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"
|
||||
><<< 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 >>></A
|
||||
></TD
|
||||
></TR
|
||||
><TR
|
||||
><TD
|
||||
WIDTH="33%"
|
||||
ALIGN="left"
|
||||
VALIGN="top"
|
||||
>Nero User's Manual</TD
|
||||
><TD
|
||||
WIDTH="34%"
|
||||
ALIGN="center"
|
||||
VALIGN="top"
|
||||
> </TD
|
||||
><TD
|
||||
WIDTH="33%"
|
||||
ALIGN="right"
|
||||
VALIGN="top"
|
||||
>nero</TD
|
||||
></TR
|
||||
></TABLE
|
||||
></DIV
|
||||
></BODY
|
||||
></HTML
|
||||
>
|
After Width: | Height: | Size: 1.0 KiB |
After Width: | Height: | Size: 995 B |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 964 B |
After Width: | Height: | Size: 1.0 KiB |
After Width: | Height: | Size: 944 B |
After Width: | Height: | Size: 1.0 KiB |
After Width: | Height: | Size: 95 B |
After Width: | Height: | Size: 843 B |
After Width: | Height: | Size: 846 B |
After Width: | Height: | Size: 922 B |
After Width: | Height: | Size: 1.0 KiB |
|
@ -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 );
|
||||
}
|
|
@ -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
|
|
@ -0,0 +1,385 @@
|
|||
|
||||
// -*- C++ -*-
|
||||
//
|
||||
// $Id: APri.cpp,v 1.1 2002/10/02 21:23:47 jpc Exp $
|
||||
//
|
||||
// /----------------------------------------------------------------\
|
||||
// | |
|
||||
// | A l l i a n c e C A D S y s t e m |
|
||||
// | S i m p l e R o u t e r |
|
||||
// | |
|
||||
// | Author : Jean-Paul CHAPUT |
|
||||
// | E-mail : alliance-support@asim.lip6.fr |
|
||||
// | ============================================================== |
|
||||
// | C++ Module : "./APri.cpp" |
|
||||
// | ************************************************************** |
|
||||
// | U p d a t e s |
|
||||
// | |
|
||||
// \----------------------------------------------------------------/
|
||||
|
||||
|
||||
|
||||
|
||||
# include "ADefs.h"
|
||||
|
||||
|
||||
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Pre-defined objects.
|
||||
|
||||
// Signal priority map.
|
||||
CMapPri *netpri;
|
||||
|
||||
|
||||
|
||||
|
||||
// /----------------------------------------------------------------\
|
||||
// | Methods Definitions |
|
||||
// \----------------------------------------------------------------/
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Constructor : "CMapPri::CMapPri()".
|
||||
|
||||
CMapPri::CMapPri (CCoordBase *coordBase)
|
||||
{
|
||||
base = coordBase;
|
||||
|
||||
_map = new char [base->XYZ];
|
||||
_mapsize = sizeof (char [base->XYZ]);
|
||||
|
||||
clear();
|
||||
|
||||
::netpri = this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Destructor : "CMapPri::~CMapPri()".
|
||||
|
||||
CMapPri::~CMapPri (void)
|
||||
{
|
||||
delete [] _map;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Method : "CMapPri::operator[]".
|
||||
|
||||
int CMapPri::operator[] (CCoord &coord) throw (primap_clear)
|
||||
{
|
||||
if (cleared) throw primap_clear ();
|
||||
|
||||
if ((coord.x() < 0) || (coord.x() > base->X - 1)) return (0);
|
||||
if ((coord.y() < 0) || (coord.y() > base->Y - 1)) return (0);
|
||||
if ((coord.z() < 1) || (coord.z() > base->Z - 1)) return (0);
|
||||
|
||||
return (offset + (int)(_map[coord.index() - base->XY]));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Method : "CMapPri::map()".
|
||||
|
||||
char *CMapPri::map (CCoord coord)
|
||||
{
|
||||
if ((coord.x() < 0) || (coord.x() > base->X - 1)) return (NULL);
|
||||
if ((coord.y() < 0) || (coord.y() > base->Y - 1)) return (NULL);
|
||||
if ((coord.z() < 1) || (coord.z() > base->Z - 1)) return (NULL);
|
||||
|
||||
return (&(_map[coord.index() - base->XY]));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Method : "CMapPri::map()".
|
||||
|
||||
char *CMapPri::map (int index)
|
||||
{
|
||||
CCoord nodeCoord = CCoord (index);
|
||||
|
||||
return (map(nodeCoord));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Method : "CMapPri::findfree()".
|
||||
|
||||
void CMapPri::findfree (CCoord ¢er)
|
||||
{
|
||||
int radius, i, j, cx, cy;
|
||||
CCoord coord;
|
||||
bool freed;
|
||||
|
||||
|
||||
freed = false;
|
||||
radius = 0;
|
||||
cx = center.x();
|
||||
cy = center.y();
|
||||
|
||||
while (!freed) {
|
||||
radius += 1;
|
||||
|
||||
for (i = cx - radius; i < cx + radius + 1; i++) {
|
||||
for (j = cy - radius; j < cy + radius + 1; j++) {
|
||||
// Proccess only nodes of the ring.
|
||||
// if ( (i > cx - radius) || (i < cx + radius) ) continue;
|
||||
// if ( (j > cy - radius) || (j < cy + radius) ) continue;
|
||||
|
||||
if ( !(*::grid)[coord.set(i,j,2)]->data.obstacle ) freed = true;
|
||||
|
||||
*map (coord.set(i,j,1)) = (char)1;
|
||||
*map (coord.set(i,j,2)) = (char)1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Method : "CMapPri::clear()".
|
||||
|
||||
void CMapPri::clear (void)
|
||||
{
|
||||
//int index;
|
||||
//
|
||||
//for (index = 0; index < base->XYZ; index++) {
|
||||
// _map[index] = (char)0;
|
||||
//}
|
||||
|
||||
memset (_map, (char)0, _mapsize);
|
||||
|
||||
cleared = true;
|
||||
offset = 0;
|
||||
delta = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Method : "CMapPri::nextPri()".
|
||||
|
||||
char CMapPri::nextPri (char curpri)
|
||||
{
|
||||
return ((curpri > 1) ? (curpri >> 1) : 1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Method : "CMapPri::load()".
|
||||
|
||||
void CMapPri::load (CNet &net, bool global, int expand=0)
|
||||
{
|
||||
list<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);
|
||||
}
|
|
@ -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 ();
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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 );
|
||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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);
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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.
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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
|
|
@ -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);
|
||||
}
|
|
@ -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
|
|
@ -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);
|
||||
}
|
|
@ -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();
|
||||
}
|
|
@ -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".
|
||||
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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]);
|
||||
}
|
|
@ -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);
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|