Contents
Hurricane Rémy Escassut & Christian Masson
Etesian Gabriel Gouvine
Stratus Sophie Belloeil
Knik Damien Dupuis
Kite, Unicorn Jean-Paul Chaput
The Hurricane data-base is copyright© Bull 2000-2015 and is released under the terms of the lgpl license. All other tools are copyright© upmc 2008-2015 and released under the gpl license.
Others important contributors to Coriolis are Christophe Alexandre, Hugo Clement, Marek Sroka and Wu Yifei.
The Knik router makes use of the Flute software, which is copyright© Chris C. N. Chu from the Iowa State University (http://home.eng.iastate.edu/~cnchu/).
This is the first preliminary release of the Coriolis 2 framework.
This release mainly ships the global router Knik and the detailed router
Kite. Together they aim to replace the Alliance Nero router.
Unlike Nero, Kite is based on an innovating routing modeling and ad-hoc
algorithm. Although it is released under gpl license, the source code
will be avalaible later.
Contents of this release:
Supported input/output formats:
Release 1963 is alpha. All the tools from Coriolis 1 have been ported into this release.
Contents of this release:
Release 2049 is Alpha.
Changes of this release:
Note
As the sources are being released, the binary packaging is dropped. You still may find older version here: http://asim.lip6.fr/pub/coriolis/2.0 .
In a nutshell, building source consist in pulling the git repository then running the ccb installer.
Main building prerequisites:
Building documentation prerequisites:
Optional libraries:
The Coloquinte component requires the lemon component from coin-or (Coin Or Home). A repository of coin-or packages backported from Fedora 21 is available here:
For other distributions, refer to their own packaging system.
In order to simplificate the work of the ccb installer, the source, build and installation tree is fixed. To successfully compile Coriolis you must follow it exactly. The tree is relative to the home directory of the user building it (noted ~/ or $HOME/). Only the source directory needs to be manually created by the user, all others will be automatically created either by ccb or the build system.
Sources | |
Sources root
under git
|
~/coriolis-2.x/src
~/coriolis-2.x/src/coriolis
|
Architecture Dependant Build | |
Linux, SL 7, 64 bits
Linux, SL 6, 32 bits
Linux, SL 6, 64 bits
Linux, Fedora, 64 bits
Linux, Fedora, 32 bits
FreeBSD 8, 32 bits
FreeBSD 8, 64 bits
Windows 7, 32 bits
Windows 7, 64 bits
Windows 8.x, 32 bits
Windows 8.x, 64 bits
|
~/coriolis-2.x/Linux.el7_64/Release.Shared/build/<tool>
~/coriolis-2.x/Linux.slsoc6x/Release.Shared/build/<tool>
~/coriolis-2.x/Linux.slsoc6x_64/Release.Shared/build/<tool>
~/coriolis-2.x/Linux.fc_64/Release.Shared/build/<tool>
~/coriolis-2.x/Linux.fc/Release.Shared/build/<tool>
~/coriolis-2.x/FreeBSD.8x.i386/Release.Shared/build/<tool>
~/coriolis-2.x/FreeBSD.8x.amd64/Release.Shared/build/<tool>
~/coriolis-2.x/Cygwin.W7/Release.Shared/build/<tool>
~/coriolis-2.x/Cygwin.W7_64/Release.Shared/build/<tool>
~/coriolis-2.x/Cygwin.W8/Release.Shared/build/<tool>
~/coriolis-2.x/Cygwin.W8_64/Release.Shared/build/<tool>
|
Architecture Dependant Install | |
Linux, SL 6, 32 bits | ~/coriolis-2.x/Linux.slsoc6x/Release.Shared/install/ |
FHS Compliant Structure under Install | |
Binaries
Libraries (Python)
Include by tool
Configuration files
Doc, by tool
|
.../install/bin
.../install/lib
.../install/include/coriolis2/<project>/<tool>
.../install/etc/coriolis2/
.../install/share/doc/coriolis2/en/html/<tool>
|
Note
Alternate build types: the Release.Shared means an optimized build with shared libraries. But there are also available Static instead of Shared and Debug instead of Release and any combination of them.
Static do not work because I don't know yet to mix statically linked binaries and Python modules (which must be dynamic).
The first step is to create the source directory and pull the git repository:
dummy@lepka:~$ mkdir -p ~/coriolis-2.x/src dummy@lepka:~$ cd ~/coriolis-2.x/src dummy@lepka:~$ git clone https://www-soc.lip6.fr/git/coriolis.git
Second and final step, build & install:
dummy@lepka:src$ ./bootstrap/ccp.py --project=coriolis \ --make="-j4 install" dummy@lepka:src$ ./bootstrap/ccb.py --project=coriolis \ --doc --make="-j1 install"
We need two steps because the documentation do not support to be generated with a parallel build. So we compile & install in a first step in -j4 (or whatever) then we generate the documentation in -j1
Under rhel6 or clones, you must build using the devtoolset2:
dummy@lepka:src$ ./bootstrap/ccp.py --project=coriolis \ --devtoolset-2 --make="-j4 install"
If you want to uses Qt 5 instead of Qt 4, you may add the --qt5 argument.
The complete list of ccb functionalities can be accessed with the --help argument. It also may be run in graphical mode (--gui).
In the Coriolis git repository, two branches are present:
The master branch, which contains the latest stable version. This is the one used by default if you follow the above instructions.
The devel branch, which obviously contains the latest commits from the development team. To use it instead of the master one, do the following command just after the first step:
dummy@lepka:~$ git checkout devel dummy@lepka:src$ ./bootstrap/ccp.py --project=coriolis \ --make="-j4 install" --debug
Be aware that it may requires newer versions of the dependencies and may introduce incompatibilites with the stable version.
In the (unlikely) event of a crash of cgt, as it is a Python script, the right command to run gdb on it is:
dummy@lepka:work$ gdb python core.XXXX
Coriolis make uses of the boost::python module, but the MacPorts boost seems unable to work with the Python bundled with MacOS. So you have to install both of them from MacPorts:
dummy@macos:~$ port install boost +python27 dummy@macos:~$ port select python python27 dummy@macos:-$ export DYLD_FRAMEWORK_PATH=/opt/local/Library/Frameworks
The last two lines tell MacOS to use the Python from MacPorts and not from the system.
Then proceed with the generic install instructions.
Packager should not uses ccb, instead bootstrap/Makefile.package is provided to emulate a top-level autotool makefile. Just copy it in the root of the Coriolis git repository (~/corriolis-2.x/src/coriolis/) and build.
Sligthly outaded packaging configuration files can also be found under bootstrap/:
Coriolis relies on Alliance for the cell libraries. So after installing or packaging, you must configure it so that it can found those libraries.
This is done by editing the one variable cellsTop in the Alliance helper (see Alliance Helper). This variable must point to the directory of the cells libraries. In a typical installation, this is generally /usr/share/alliance/cells.
To simplify the tedious task of configuring your environment, a helper is provided in the bootstrap source directory (also installed in the directory .../install/etc/coriolis2/) :
~/coriolis-2.x/src/coriolis/bootstrap/coriolisEnv.py
Use it like this:
dummy@lepka:~> eval `~/coriolis-2.x/src/coriolis/bootstrap/coriolisEnv.py`
Note
Do not call that script in your environement initialisation. When used under rhel6 or clones, it needs to be run in the devtoolset2 environement. The script then launch a new shell, which may cause an infinite loop if it's called again in, say ~/.bashrc.
Instead you may want to create an alias:
alias c2r='eval "`~/coriolis-2.x/src/coriolis/bootstrap/coriolisEnv.py`"'
The general index of the documentation for the various parts of Coriolis are avalaibles here Coriolis Tools Documentation.
Note
Python Documentation: Most of the documentation is related to the C++ API and implemetation of the tools. However, the Python bindings have been created so they mimic as closely as possible the C++ interface, so the documentation applies to both languages with only minor syntactic changes.
Coriolis has been build with respect of the classical paradigm that the computational instensive parts have been written in C++, and almost everything else in Python. To build the Python interface we used two methods:
All configuration & initialization files are Python scripts, despite their
.conf extention. From a syntactic point of view, there is no difference
between the system-wide configuration files and the user's configuration,
they may use the same Python helpers.
Configuration is done in two stages:
The initialization process is done by executing, in order, the following file(s):
Order | Meaning | File |
---|---|---|
1 | The system setting | /etc/coriolis2/techno.conf |
2 | The user's global setting | ${HOME}/.coriolis2/techno.py |
3 | The user's local setting | <CWD>/.coriolis2/techno.py |
Thoses files must provides only two variables, the name of the symbolic technology and the one of the real technology. For example:
# -*- Mode:Python -*- symbolicTechno = 'cmos' realTechno = 'hcmos9'
The TECHNO variable is set by the first stage and it's the name of the symbolic technology. A directory of that name, with all the configuration files, must exists in the configuration directory. In addition to the technology-specific directories, a common/ directory is there to provides a trunk for all the identical datas across the various technologies. The initialization process is done by executing, in order, the following file(s):
Order | Meaning | File |
---|---|---|
1 | The system initialization | /etc/coriolis2/<TECHNO>/<TOOL>.conf |
2 | The user's global initialization | ${HOME}/.coriolis2/settings.py |
3 | The user's local initialization | <CWD>/.coriolis2/settings.py |
Note
The loading policy is not hard-coded. It is implemented at Python level in /etc/coriolis2/coriolisInit.py, and thus may be easily be amended to whatever site policy.
The truly mandatory requirement is the existence of coriolisInit.py which must contain a coriolisConfigure() function with no argument.
To ease the writing of configuration files, a set of small helpers is available. They allow to setup the configuration parameters through simple assembly of tuples. The helpers are installed under the directory:
<install>/etc/coriolis2/
Where <install>/ is the root of the installation.
The configuration file must provide a allianceConfig tuple of the form:
cellsTop = '/usr/share/alliance/cells/' allianceConfig = \ ( ( 'SYMBOLIC_TECHNOLOGY', helpers.sysConfDir+'/technology.symbolic.xml' ) , ( 'REAL_TECHNOLOGY' , helpers.sysConfDir+'/technology.cmos130.s2r.xml') , ( 'DISPLAY' , helpers.sysConfDir+'/display.xml' ) , ( 'CATALOG' , 'CATAL') , ( 'WORKING_LIBRARY' , '.') , ( 'SYSTEM_LIBRARY' , ( (cellsTop+'sxlib' , Environment.Append) , (cellsTop+'dp_sxlib', Environment.Append) , (cellsTop+'ramlib' , Environment.Append) , (cellsTop+'romlib' , Environment.Append) , (cellsTop+'rflib' , Environment.Append) , (cellsTop+'rf2lib' , Environment.Append) , (cellsTop+'pxlib' , Environment.Append) ) ) , ( 'SCALE_X' , 100) , ( 'IN_LO' , 'vst') , ( 'IN_PH' , 'ap') , ( 'OUT_LO' , 'vst') , ( 'OUT_PH' , 'ap') , ( 'POWER' , 'vdd') , ( 'GROUND' , 'vss') , ( 'CLOCK' , '^ck.*') , ( 'BLOCKAGE' , '^blockageNet*') )
The example above shows the system configuration file, with all the available settings. Some important remarks about thoses settings:
In it's configuration file, the user do not need to redefine all the settings, just the one he wants to change. In most of the cases, the SYSTEM_LIBRARY, the WORKING_LIBRARY and the special net names (at this point there is not much alternatives for the others settings).
SYSTEM_LIBRARY setting: Setting up the library search path. Each library entry in the tuple will be added to the search path according to the second parameter:
A library is identified by it's name, this name is the last component of the path name. For instance: /soc/alliance/sxlib will be named sxlib. Implementing the Alliance specification, when looking for a Cell name, the system will browse sequentially trought the library list and returns the first Cell whose name match.
For POWER, GROUND, CLOCK and BLOCKAGE net names, a regular expression (gnu regexp) is expected.
The helpers.sysConfDir variable is supplied by the helpers, it is the directory in which the system-wide configuration files are locateds. For a standard installation it would be: /soc/coriolis2.
A typical user's configuration file would be:
import os homeDir = os.getenv('HOME') allianceConfig = \ ( ('WORKING_LIBRARY' , homeDir+'/worklib') , ('SYSTEM_LIBRARY' , ( (homeDir+'/mylib', Environment.Append) ) ) , ('POWER' , 'vdd.*') , ('GROUND' , 'vss.*') )
All the tools uses the same helper to load their configuration (a.k.a. Configuration Helper). Currently the following configuration system-wide configuration files are defined:
Here is the contents of etesian.conf:
# Etesian parameters. parametersTable = \ ( ('etesian.aspectRatio' , TypePercentage, 100 , { 'min':10, 'max':1000 } ) , ('etesian.spaceMargin' , TypePercentage, 5 ) , ('etesian.uniformDensity' , TypeBool , False ) , ('etesian.routingDriven' , TypeBool , False ) , ("etesian.effort" , TypeEnumerate , 2 , { 'values':( ("Fast" , 1) , ("Standard", 2) , ("High" , 3) , ("Extreme" , 4) ) } ) , ("etesian.graphics" , TypeEnumerate , 2 , { 'values':( ("Show every step" , 1) , ("Show lower bound" , 2) , ("Show result only" , 3) ) } ) ) layoutTable = \ ( (TypeTab , 'Etesian', 'etesian') , (TypeTitle , 'Placement area') , (TypeOption, "etesian.aspectRatio" , "Aspect Ratio, X/Y (%)", 0 ) , (TypeOption, "etesian.spaceMargin" , "Space Margin" , 1 ) , (TypeRule ,) , (TypeTitle , 'Etesian - Placer') , (TypeOption, "etesian.uniformDensity", "Uniform density" , 0 ) , (TypeOption, "etesian.routingDriven" , "Routing driven" , 0 ) , (TypeOption, "etesian.effort" , "Placement effort" , 1 ) , (TypeOption, "etesian.graphics" , "Placement view" , 1 ) , (TypeRule ,) )
Taxonomy of the file:
Asides from the symbols that gets used by the configuration helpers like allianceConfig or parametersTable, you can put pretty much anything in <CWD>/.coriolis2/settings.py (that is, written in Python).
For example:
# -*- Mode:Python -*- defaultStyle = 'Alliance.Classic [black]' # Regular Coriolis configuration. parametersTable = \ ( ('misc.catchCore' , TypeBool , False ) , ('misc.info' , TypeBool , False ) , ('misc.paranoid' , TypeBool , False ) , ('misc.bug' , TypeBool , False ) , ('misc.logMode' , TypeBool , True ) , ('misc.verboseLevel1' , TypeBool , False ) , ('misc.verboseLevel2' , TypeBool , True ) , ('misc.traceLevel' , TypeInt , 1000 ) ) # Some ordinary Python script... import os print ' o Cleaning up ClockTree previous run.' for fileName in os.listdir('.'): if fileName.endswith('.ap') or (fileName.find('_clocked.') >= 0): print ' - <%s>' % fileName os.unlink(fileName)
See Python Interface to Coriolis for more details those capabilities.
The Coriolis graphical interface is split up into two windows.
Features are detailed in Viewer & Tools.
Stratus is the replacement for GenLib procedural netlist capture language. It is designed as a set of Python classes, and comes with it's own documentation (Stratus Documentation)
The Alliance flow is based on the mbk data-base, which has one data-structure for each view. That is, Lofig for the logical view and Phfig for the physical view. The place and route tools were responsible for maintaining (or not) the coherency between views. Reflecting this weak coupling between views, each one was stored in a separate file with a specific format. The logical view is stored in a vst file in vhdl format and the physical in an ap file in an ad-hoc format.
The Coriolis flow is based on the Hurricane data-base, which has a unified structure for logical and physical view. That data structure is the Cell object. The Cell can have any state between pure netlist and completly placed and routed design. Although the memory representation of the views has deeply changed we still use the Alliance files format, but they now really represent views of the same object. The point is that one must be very careful about view coherency when going to and from Coriolis.
As for the second release, Coriolis can be used only for three purposes :
Coriolis supports several file formats. It can load all file format from the Alliance toolchain (.ap for layout, behavioural and structural vhdl .vbe and .vst), BLIF netlist format as well as benchmark formats from the ISPD contests.
It can be compiled with LEF/DEF support, although it requires acceptance of the SI2 license and may not be compiled in your version of the software.
You can create a BLIF file from the Yosys synthetizer, which can be imported under Coriolis. Most libraries are specified as a .lib liberty file and a .lef LEF file. Yosys opens most .lib files with minor modifications, but LEF support in Coriolis relies on SI2. If Coriolis hasn't been compiled against it, the library is given in Alliance .ap format. Some free libraries already provide both .ap and .lib files.
Once you have installed a common library under Yosys and Coriolis, just synthetize your design with Yosys and import it (as Blif without the extension) under Coriolis to perform place&route.
Alliance is an older toolchain but has been extensively used for years. Coriolis can import and write Alliance designs and libraries directly.
The Etesian placer is a state of the art (as of 2015) analytical placer. It is within 5% of other placers' solutions, but is normally a bit worse than ePlace. This Coriolis tool is actually an encapsulation of Coloquinte which is the placer.
Note
Instance Uniquification Unsupported: a same logical instance cannot have two different placements. So, either you manually make a clone of it or you supply a placement for it. We need to implement uniquification in the Hurricane database.
Hierarchical Placement
The placement area is defined by the top cell abutment box.
When placing a complete hierarchy, the abutment boxes of the cells (models) other than the top cell are sets identical to the one of the top cell and their instances are all placed at position (0,0,ID). That is, all the abutments boxes, whatever the hierarchical level, defines the same area (they are exactly superposed).
We choose this scheme because the placer will see all the instances as virtually flattened, so they can be placed anywhere inside the top-cell abutment box.
Computing the Placement Area
The placement area is computed using the etesian.aspectRatio and etesian.spaceMargin parameters only if the top-cell has an empty abutment box. If the top-cell abutment box has to be set, then it is propagated to all the instances models recursively.
Reseting the Placement
Once a placement has been done, the placer cannot reset it (will be implemented later). To perform a new placement, you must restart cgt. In addition, if you have saved the placement on disk, you must erase any .ap file, which are automatically reloaded along with the netlist (.vst).
Limitations
Etesian supports standard cells and fixed macros. As for the Coriolis 2.1 version, it doesn't support movable macros, and you must place every macro beforehand. Timing and routability analysis are not included either, and the returned placement may be unroutable.
Parameter Identifier | Type | Default |
---|---|---|
Etesian Parameters | ||
etesian.aspectRatio | TypePercentage | 100 |
Define the height on width H/W aspect ratio, can be comprised between 10 and 1000 | ||
etesian.spaceMargin | TypePercentage | 5 |
The extra white space added to the total area of the standard cells | ||
etesian.uniformDensity | TypeBool | False |
Whether the cells will be spread envenly across the area or allowed to form denser clusters | ||
etesian.effort | TypeInt | 2 |
Sets the balance between the speed of the placer and the solution quality | ||
etesian.routingDriven | TypeBool | False |
Whether the tool will try routing iterations and whitespace allocation to improve routability; to be implemented | ||
etesian.graphics | TypeInt | 2 |
How often the display will be refreshed More refreshing slows the placer.
|
The quality of Knik global routing solutions are equivalent to those of FGR 1.0. For an in-depth description of Knik algorithms, you may download the thesis of D. Dupuis avalaible from here~: Knik Thesis.
The global router is (not yet) deterministic. To circumvent this limitation, a global routing solution can be saved to disk and reloaded for later uses.
A global routing is saved into a file with the same name as the design and a kgr extention. It is in Box Router output format.
Menus:
Kite no longer suffers from the limitations of Nero. It can route big designs
as its runtime and memory footprint is almost linear (with respect to the number
of gates). It has successfully routed design of more than 150K gates.
However, this first release comes with the temporary the following restrictions:
Note
Slow Layer Assignment. Most of the time, the layer assignment stage is fast (less than a dozen seconds), but in some instances it can take more than a dozen minutes. This is a known bug and will be corrected in later releases.
After each run, Kite displays a set of completion ratios which must all be equal to 100% if the detailed routing has been successfull. In the event of a failure, on a saturated design, you may decrease the edge saturation ratio (argument --edge) to balance more evenly the design saturation. That is, the maximum saturation decrease at the price of a wider saturated area and increased wirelength. This is the saturation of the global router Knik, and you may increase/decrease by steps of 5%, which represent one track. The maximum capacity of the SxLib gauge is 10 tracks in two layers, that makes 20 tracks by Knik edge.
Routing a design is done in four ordered steps:
It is possible to supply to the router a complete wiring for some nets that the user's wants to be routed according to a specific topology. The supplied topology must respect the building rules of the Katabatic database (contacts must be, terminals, turns, h-tee & v-tee only). During the first step Detailed Pre-Route the router will solve overlaps between the segments, without making any dogleg. If no pre-routed topologies are present, this step may be ommited. Any net routed at this step is then fixed and become unmovable for the later stages.
After the detailed routing step the Kite data-structure is still active (the Hurricane wiring is decorated). The finalize step performs the removal of the Kite data-structure, and it is not advisable to save the design before that step.
You may visualize the density (saturation) of either Knik (on edges) or Kite (on GCells) until the routing is finalized. Special layers appears to that effect in the The Layers&Go Tab.
As Knik is only called through Kite, it's parameters also have the kite. prefix.
The Katabatic parameters control the layer assignment step.
All the defaults value given below are from the default Alliance technology (cmos and SxLib cell gauge/routing gauge).
Parameter Identifier | Type | Default |
---|---|---|
Katabatic Parameters | ||
katabatic.topRoutingLayer | TypeString | METAL5 |
Define the highest metal layer that will be used for routing (inclusive). | ||
katabatic.globalLengthThreshold | TypeInt | 1450 |
This parameter is used by a layer assignment method which is no longer used (did not give good results) | ||
katabatic.saturateRatio | TypePercentage | 80 |
If M(x) density is above this ratio, move up feedthru global segments up from depth x to x+2 | ||
katabatic.saturateRp | TypeInt | 8 |
If a GCell contains more terminals (RoutingPad) than that number, force a move up of the connecting segments to those in excess | ||
Knik Parameters | ||
kite.hTracksReservedLocal | TypeInt | 3 |
To take account the tracks needed inside a GCell to build the local routing, decrease the capacity of the edges of the global router. Horizontal and vertical locally reserved capacity can be distinguished for more accuracy. | ||
kite.vTracksReservedLocal | TypeInt | 3 |
cf. kite.hTracksReservedLocal | ||
Kite Parameters | ||
kite.eventsLimit | TypeInt | 4000002 |
The maximum number of segment displacements, this is a last ditch safety against infinite loop. It's perhaps a little too low for big designs | ||
kite.ripupCost | TypeInt | 3 |
Differential introduced between two ripup cost to avoid a loop between two ripped up segments | ||
kite.strapRipupLimit | TypeInt | 16 |
Maximum number of ripup for strap segments | ||
kite.localRipupLimit | TypeInt | 9 |
Maximum number of ripup for local segments | ||
kite.globalRipupLimit | TypeInt | 5 |
Maximum number of ripup for global segments, when this limit is reached, triggers topologic modification | ||
kite.longGlobalRipupLimit | TypeInt | 5 |
Maximum number of ripup for long global segments, when this limit is reached, triggers topological modification |
Python/Stratus scripts can be executed either in text or graphical mode.
Note
How Cgt Locates Python Scripts: cgt uses the Python import mechanism to load Python scripts. So you must give the name of your script whitout .py extention and it must be reachable through the PYTHONPATH. You may uses the dotted module notation.
A Python/Stratus script must contains a function called ScriptMain() with one optional argument, the graphical editor into which it may be running (will be set to None in text mode). The Python interface to the editor (type: CellViewer) is limited to basic capabilities only.
Any script given on the command line will be run immediatly after the initializations and before any other argument is processed.
For more explanation on Python scripts see Python Interface to Coriolis.
Printing or saving into a pdf is fairly simple, just uses the File -> Print menu or the CTRL+P shortcut to open the dialog box.
The print functionality uses exactly the same rendering mechanism as for the screen, beeing almost WYSIWYG. Thus, to obtain the best results it is advisable to select the Coriolis.Printer look (in the Controller), which uses a white background and much suited for high resolutions 32x32 pixels patterns
There is also two mode of printing selectable through the Controller Settings -> Misc -> Printer/Snapshot Mode:
Mode | DPI (approx.) | Intended Usage |
Cell Mode | 150 | For single Cell printing or very small designs. Patterns will be bigger and more readable. |
Design Mode | 300 | For designs (mostly commposed of wires and cells outlines). |
Note
The pdf file size Be aware that the generated pdf files are indeed only pixmaps. So they can grew very large if you select paper format above A2 or similar.
Saving into an image is subject to the same remarks as for pdf.
The main application binary is cgt.
Category | Keys | Action |
---|---|---|
Moves | Up,
Down
Left,
Right
|
Shift the view in the according direction |
Fit | f | Fit to the Cell abutment box |
Refresh | CTRL+L | Triggers a complete display redraw |
Goto | g | apperture is the minimum side of the area displayed around the point to go to. It's an alternative way of setting the zoom level |
Zoom | z, m | Respectively zoom by a 2 factor and unzoom by a 2 factor |
Area Zoom
|
You can perform a zoom to an area. Define the zoom area by holding down the left mouse button while moving the mouse. | |
Selection | Area Selection
|
You can select displayed objects under an area. Define the selection area by holding down the right mouse button while moving the mouse. |
Toggle Selection
|
You can toggle the selection of one object under the mouse position by pressing CTRL and pressing down the right mouse button. A popup list of what's under the position shows up into which you can toggle the selection state of one item. | |
S | Toggle the selection visibility | |
Controller | CTRL+I | Show/hide the controller window. It's the Swiss Army Knife of the viewer. From it, you can fine-control the display and inspect almost everything in your design. |
Rulers | k, ESC | One stroke on k enters the ruler mode, in which you can draw one ruler. You can exit the ruler mode by pressing ESC. Once in ruler mode, the first click on the left mouse button sets the ruler's starting point and the second click the ruler's end point. The second click exits automatically the ruler mode. |
K | Clears all the drawn rulers | |
CTRL+P | Currently rather crude. It's a direct copy of what's displayed in pixels. So the resulting picture will be a little blurred due to anti-aliasing mechanism. | |
Open/Close | CTRL+O | Opens a new design. The design name must be given without path or extention. |
CTRL+W | Close the current viewer window, but do not quit the application. | |
CTRL+Q | CTRL+Q quit the application (closing all windows). | |
Hierarchy | CTRL+Down | Go one hierarchy level down. That is, if there is an instance under the cursor position, load it's model Cell in place of the current one. |
CTRL+Up | Go one hierarchy level up. if we have entered the current model through CTRL+Down reload the previous model (the one in which this model is instanciated). |
Appart from the obvious --text options, all can be used for text and graphical mode.
Arguments | Meaning |
---|---|
-t|--text | Instruct cgt to run in text mode. |
-L|--log-mode | Disable the uses of ansi escape sequence on the tty. Useful when the output is redirected to a file. |
-c <cell>|--cell=<cell> | The name of the design to load, without leading path or extention. |
-g|--load-global | Reload a global routing solution from disk. The file containing the solution must be named <cell>.kgr. |
--save-global | Save the global routing solution, into a file named <design>.kgr. |
-e <ratio>|--edge=<ratio> | Change the edge capacity for the global router, between 0 and 1 (Knik). |
-G|--global-route | Run the global router (Knik). |
-R|--detailed-route | Run the detailed router (Kite). |
-s|--save-design=<routed> | The design into which the routed layout will be saved. It is strongly recommanded to choose a different name from the source (unrouted) design. |
--events-limit=<count> | The maximal number of events after which the router will stops. This is mainly a failsafe against looping. The limit is sets to 4 millions of iteration which should suffice to any design of 100K. gates. For bigger designs you may wants to increase this limit. |
--stratus-script=<module> | Run the Python/Stratus script module. See Python Scripts in Cgt. |
Some Examples :
Run both global and detailed router, then save the routed design :
> cgt -v -t -G -R --cell=design --save-design=design_kite
Load a previous global solution, run the detailed router, then save the routed design :
> cgt -v -t --load-global -R --cell=design --save-design=design_kite
Run the global router, then save the global routing solution :
> cgt -v -t -G --save-global --cell=design
Parameter Identifier | Type | Default |
---|---|---|
Verbosity/Log Parameters | ||
misc.info | TypeBool | False |
Enable display of info level message (cinfo stream) | ||
misc.bug | TypeBool | False |
Enable display of bug level message (cbug stream), messages can be a little scarry | ||
misc.logMode | TypeBool | False |
If enabled, assume that the output device is not a tty and suppress any escaped sequences | ||
misc.verboseLevel1 | TypeBool | True |
First level of verbosity, disable level 2 | ||
misc.verboseLevel2 | TypeBool | False |
Second level of verbosity | ||
Development/Debug Parameters | ||
misc.traceLevel | TypeInt | 0 |
Display trace information below that level (ltrace stream) | ||
misc.catchCore | TypeBool | False |
By default, cgt do not dump core. To generate one set this flag to True |
The Controller window is composed of seven tabs:
You can select how the layout will be displayed. There is a special one Printer.Coriolis specifically designed for Printing & Snapshots. You should select it prior to calling the print or snapshot dialog boxes.
The filter tab let you select what hierarchical levels of your design will be displayed. Hierarchy level are numbered top-down: the level 0 correspond to the top-level cell, the level one to the instances of the top-level Cell and so on.
There are also check boxes to enable/disable the processing of Terminal Cell, Master Cells and Compnents. The processing of Terminal Cell (hierarchy leaf cells) is disabled by default when you load a hierarchical design and enabled when you load a single Cell.
You can choose what kind of form to give to the rubbers and the type of unit used to display coordinates.
Note
What are Rubbers: Hurricane uses Rubbers to materialize physical gaps in net topology. That is, if some wires are missing to connect two or more parts of net, a rubber will be drawn between them to signal the gap.
For example, after the detailed routing no rubbers should remains. They have been made very visibles as big violet lines...
Control the individual display of all layers and Gos.
For each layer/Go there are two check boxes:
The Netlist tab shows the list of nets... By default the tab is not synched with the displayed Cell. To see the nets you must check the Sync Netlist checkbox. You can narrow the set of displayed nets by using the filter pattern (supports regular expressions).
An very useful feature is to enable the Sync Selection, which will automatically select all the components of the selected net(s). You can select multiple nets. In the figure the net auxsc35 is selected and is highlited in the Viewer.
The Selection tab list all the components currently selecteds. They can be filtered thanks to the filter pattern.
Used in conjunction with the Netlist Sync Selection you will all see all the components part of net.
In this list, you can toggle individually the selection of component by pressing the t key. When unselected in this way a component is not removed from the the selection list but instead displayed in red italic. To see where a component is you may make it blink by repeatedly press the t key...
This tab is very useful, but mostly for Coriolis developpers. It allows to browse through the live DataBase. The Inspector provide three entry points:
Once an entry point has been activated, you may recursively expore all it's fields using the right/left arrows.
Note
Do not put your fingers in the socket: when inspecting anything, do not modify the DataBase. If any object under inspection is deleted, you will crash the application...
Note
Implementation Detail: the inspector support is done with Slot, Record and getString().
The (almost) complete interface of Hurricane is exported as a Python module and some part of the other components of Coriolis (each one in a separate module). The interface has been made to mirror as closely as possible the C++ one, so the C++ doxygen documentation could be used to write code with either languages.
Summary of the C++ Documentation
A script could be run directly in text mode from the command line or through the graphical interface (see Python Scripts in Cgt).
Asides for this requirement, the python script can contain anything valid in Python, so don't hesitate to use any package or extention.
Small example of Python/Stratus script:
from Hurricane import * from Stratus import * def doSomething (): # ... return def ScriptMain ( **kw ): editor = None if kw.has_key('editor') and kw['editor']: editor = kw['editor'] stratus.setEditor( editor ) doSomething() return if __name__ == "__main__" : kw = {} success = ScriptMain( **kw ) shellSuccess = 0 if not success: shellSuccess = 1 sys.exit( shellSuccess ) ScriptMain ()
This typical script can be executed in two ways:
Run directly as a Python script, thanks to the
if __name__ == "__main__" :
part (this is standart Python). It is a simple adapter that will calls ScriptMain().
Through cgt, either in text or graphical mode. In that case, the ScriptMain() is directly called trough a sub-interpreter. The arguments of the script are passed through the **kw dictionnary.
**kw Dictionnary | |
---|---|
Parameter Key/Name | Contents type |
'cell' | A Hurricane cell on which to work. Depending on the context, it may be None. For example, when run from cgt, it the cell currently loaded in the viewer, if any. |
'editor' | The viewer from which the script is run, when lauched through cgt. |
Plugins are Python scripts specially crafted to integrate with cgt. Their entry point is a ScriptMain() method as described in Python Interface to Coriolis. They can be called by user scripts through this method.
Automatically perform the placement of a complete chip. This plugin, as well as the other P&R tools expect a specific top-level hierarchy for the design. The top-level hierarchy must contains the instances of all the I/O pads and exactly one instance of the chip's core model.
The designer must provide a configuration file that define the rules for the placement of the top-level hierarchy (that is, the pads and the core). This file must be named after the chip's name, by appending _chip.py (obviously, it is a Python file). For instance if the chip netlist file is called amd2901_crl.vst, then the configuration file must be named amd2901_crl_chip.vst.
Example of chip placement configuration file (for AM2901):
chip = \ { 'pads.south' : [ 'p_a3' , 'p_a2' , 'p_a1' , 'p_r0' , 'p_vddick0', 'p_vssick0', 'p_a0' , 'p_i6' , 'p_i8' , 'p_i7' , 'p_r3' ] , 'pads.east' : [ 'p_zero' , 'p_i0' , 'p_i1' , 'p_i2' , 'p_vddeck0', 'p_vsseck0', 'p_q3' , 'p_b0' , 'p_b1' , 'p_b2' , 'p_b3' ] , 'pads.north' : [ 'p_noe' , 'p_y3' , 'p_y2' , 'p_y1' , 'p_y0' , 'p_vddeck1', 'p_vsseck1', 'p_np' , 'p_ovr' , 'p_cout' , 'p_ng' ] , 'pads.west' : [ 'p_cin' , 'p_i4' , 'p_i5' , 'p_i3' , 'p_ck' , 'p_d0' , 'p_d1' , 'p_d2' , 'p_d3' , 'p_q0' , 'p_f3' ] , 'core.size' : ( 1500, 1500 ) , 'chip.size' : ( 3000, 3000 ) , 'chip.clockTree' : True }
The file must contain one dictionnary named chip.
Chip Dictionnary | |
---|---|
Parameter Key/Name | Value/Contents type |
'pad.south' | Ordered list (left to right) of pad instances names to put on the south side of the chip |
'pad.east' | Ordered list (down to up) of pad instances names to put on the east side of the chip |
'pad.north' | Ordered list (left to right) of pad instances names to put on the north side of the chip |
'pad.west' | Ordered list (down to up) of pad instances names to put on the west side of the chip |
'core.size' | The size of the core (to be used by the placer) |
'chip.size' | The size of the whole chip. The sides must be great enough to accomodate all the pads |
'chip.clockTree' | Whether to generate a clock tree or not. This calls the ClockTree plugin |
Configuration parameters, defaults are defined in etc/coriolis2/<STECHNO>/plugins.conf.
Parameter Identifier | Type | Default |
---|---|---|
Chip Plugin Parameters | ||
chip.block.rails.count | TypeInt | 5 |
The minimum number of rails around the core block. Must be odd and suppérior to 5. One rail for the clock and at least two pairs of power/grounds | ||
chip.block.rails.hWidth | TypeInt | 12 |
The horizontal with of the rails | ||
chip.block.rails.vWidth | TypeInt | 12 |
The vertical with of the rails | ||
chip.block.rails.hSpacing | TypeInt | 6 |
The spacing, edge to edge of two adjacent horizontal rails | ||
chip.block.rails.vSpacing | TypeInt | 6 |
The spacing, edge to edge of two adjacent vertical rails | ||
chip.pad.pck | TypeString | pck_px |
The model name of the pad connected to the chip external clock | ||
chip.pad.pvddeck | TypeString | pvddeck_px |
The model name of the pad connected to the vdde (external power) and suppling it to the core | ||
chip.pad.pvsseck | TypeString | pvsseck_px |
The model name of the pad connected to the vsse (external ground) and suppling it to the core | ||
chip.pad.pvddick | TypeString | pvddick_px |
The model name of the pad connected to the vddi (internal power) and suppling it to the core | ||
chip.pad.pvssick | TypeString | pvssick_px |
The model name of the pad connected to the vssi (internal ground) and suppling it to the core |
Note
If no clock tree is generated, then the clock rail is not created. So even if the requested number of rails chip.block.rails.count is, say 5, only four rails (2* power, 2* ground) will be generateds.
Insert a clock tree into a block. The clock tree uses the H strategy. The clock net is splitted into sub-nets, one for each branch of the tree.
On chips design, the sub-nets are createds in the model of the core block (then trans-hierarchically flattened to be shown at chip level).
On blocks, the sub nets are created directly in the top block.
The sub-nets are named according to a simple geometrical scheme. A common prefix ck_htree, then one postfix by level telling on which quarter of plane the sub-clock is located:
We can have ck_htree_bl, ck_htree_bl_bl, ch_htree_bl_tl and so on.
The clock tree plugin works in four steps:
Netlist reorganisation:
Note
If you are to re-run the clock tree plugin on a netlist, be careful to erase any previously generated _clocked file (both netlist and layout: rm *.clocked.{ap,vst}). And restart cgt to clear it's memory cache.
Configuration parameters, defaults are defined in etc/coriolis2/<STECHNO>/plugins.conf.
Parameter Identifier | Type | Default |
---|---|---|
ClockTree Plugin Parameters | ||
clockTree.minimumSide | TypeInt | 300 |
The minimum size below which the clock tree will stop to perform quadri-partitions | ||
clockTree.buffer | TypeString | buf_x2 |
The buffer model to use to drive sub-nets | ||
clockTree.placerEngine | TypeString | Etesian |
The placer to use. Other value is Mauka the simulated annealing placer which will go into retirement very soon |
Perform a recursive top down save of all the models from the top cell loaded in cgt. Force a write of any non-terminal model. This plugin is used by the clock tree plugin after the netlist clock sub-nets creation.
To illustrate the capabilities of Coriolis tools and Python scripting, a small example, derived from the Alliance AM2901 is supplied.
This example contains only the synthetized netlists and the doChip.py script which perform the whole P&R of the design.
You can generate the chip using one of the following method:
Command line mode: directly run the script:
dummy@lepka:AM2901$ ./doChip -V --cell=amd2901
Graphic mode: launch cgt, load chip netlist amd2901 (the top cell) then run the Python script doChip.py.
Note
Between two consecutive run, be sure to erase the netlist/layout generateds:
dummy@lepka:AM2901$ rm *_clocked*.vst *.ap