mirror of
https://github.com/lleene/hugo-site.git
synced 2025-01-23 20:12:21 +01:00
218 lines
6.5 KiB
Markdown
218 lines
6.5 KiB
Markdown
---
|
|
title: "Spice Monkey 💻🐒"
|
|
date: 2021-10-29T18:54:32+02:00
|
|
draft: false
|
|
toc: false
|
|
images:
|
|
tags:
|
|
- spice
|
|
- code
|
|
- verification
|
|
---
|
|
|
|
Netlisting issues can be some of the more frustrating aspects of circuit design
|
|
tool chains primarily because its it all text based and very old fashioned.
|
|
The Cadence tools for example have various command-line utilities but
|
|
documentation is underwhelming to say the least. Quite often though they are
|
|
inevitable when combining different tools, design flows, or handling someone
|
|
else's IP. In order to cope with the usual inconsistencies I rely on the
|
|
scripts below to pre and post process SPICE netlists.
|
|
|
|
### Port Order Reshuffling
|
|
|
|
The default netlister and spice simulators usually connects sub component
|
|
terminals in terms of the order in which they are defined in the spice `.SUBCKT`
|
|
definition. Conflict arises however since IP vendors on the other hand tend
|
|
to sort the port order in someway in the spice netlist but the Cadence
|
|
symbol/schematic definition will usually disregard this order causing
|
|
connectivity issues later.
|
|
|
|
```bash
|
|
function getSortedOrder() {
|
|
local SOURCE=""
|
|
local SORTED=""
|
|
read -a SOURCE <<< "$1"
|
|
SORTED="${SOURCE[@]}"
|
|
if [ -z "${SORTED//*\[*}" ] ; then
|
|
SORTED=($(echo "${SOURCE[@]:2}" | tr " " "\n" | sed -r "s/\[([0-9]+)\]/ \1 /g" \
|
|
| sort -k 1,1 -k2,2nr | sed -r "s/ ([0-9]+) /\[\1\]/g" ))
|
|
else
|
|
SORTED=($(echo "${SOURCE[@]:2}" | tr " " "\n" | sed -r "s/<([0-9]+)>/ \1 /g" \
|
|
| sort -k 1,1 -k2,2nr | sed -r "s/ ([0-9]+) /<\1>/g" ))
|
|
fi
|
|
echo "${SOURCE[@]:0:2} ${SORTED[@]}"
|
|
}
|
|
```
|
|
|
|
Cadence tools will prefer alphabetical ordering. The bash script above will
|
|
replicate this sorting behaviour if you pass it a `.SUBCKT` definition string.
|
|
The purpose here is that when you are given a netlist from a vendor you can
|
|
prepare an internal version that already sorts the ports alphabetically.
|
|
|
|
In order to do this in terms of editing a file however you can use the script
|
|
below which is called as: `updatePortOrder $CKT_NAME $FILE_NAME`. This will
|
|
look for the definition given a `CKT_NAME` in the spice file and create a
|
|
new file `CKT_NAME.cdl` in the current directory.
|
|
|
|
```bash
|
|
function updatePortOrder() {
|
|
local TARGET="$1"
|
|
local CDL_FILE="$2"
|
|
local PORTORDER="$(awk -v target="subckt ${TARGET} " -f "catch.awk" "$CDL_FILE")"
|
|
local PORTREF=$(getSortedOrder "$PORTORDER")
|
|
local SWPDELIMITER=""
|
|
echo $TARGET
|
|
if [ -z "${PORTREF//*\[*}" ] ; then SWPDELIMITER="TRUE" ; fi
|
|
awk -v target="subckt ${TARGET} " -v release="$PORTREF" -v swpdelim="$SWPDELIMITER" \
|
|
-f "release.awk" "$CDL_FILE" > "${TARGET}.cdl"
|
|
[ ! -z "$(grep -m 1 "\[" "${TARGET}.cdl")" ] && [ ! -z "$(grep -m 1 "<" "${TARGET}.cdl")" ] \
|
|
&& echo "Error $CDL_FILE uses mixed delimiters"
|
|
}
|
|
```
|
|
|
|
The second script however relies on some awk-based spice parsing calls to
|
|
properly find and replace the relevant sections in the netlist. `catch.awk`
|
|
simple finds the `SUBCKT` statement relevant and prints it to stdout.
|
|
|
|
```awk
|
|
BEGIN{ hold = ""; IGNORECASE = 1 }
|
|
NF {
|
|
if( $1 == "+" && hold != "")
|
|
{ for(i=2;i<=NF;i++) hold=hold " " $i }
|
|
else if( hold != "") { print hold; hold=""; exit }
|
|
};
|
|
$0 ~ target { hold = $0 };
|
|
```
|
|
|
|
Then `release.awk` helps to insert the definition back into the netlist with
|
|
the option to swap out any delimiters in the port names.
|
|
|
|
```awk
|
|
BEGIN{output="";hold="";IGNORECASE=1};
|
|
NF{if($1!="+")hold=""}
|
|
$0~target{
|
|
hold=$0
|
|
n=split(release,ports," ")
|
|
for(i=n;i>0;i--){
|
|
if(swpdelim!=""){
|
|
gsub("<","[",ports[i])
|
|
gsub(">","]",ports[i])}
|
|
output=ports[i]" "output}
|
|
print output}
|
|
NF{if(hold=="")print $0}
|
|
```
|
|
|
|
### Netlisting Environment:
|
|
|
|
```skill
|
|
;; spice.env
|
|
simStopList = '("auCdl")
|
|
simViewList = '("auCdl" "schematic")
|
|
auCdlDefNetlistProc = "ansCdlSubcktCall"
|
|
globalGndSig = ""
|
|
globalPowerSig = ""
|
|
shrinkFACTOR = 0
|
|
checkScale = "meter"
|
|
preserveDIO = 'nil
|
|
checkDIOAREA = 'nil
|
|
checkDIOPERI = 'nil
|
|
preserveCAP = 'nil
|
|
checkCAPVAL = 'nil
|
|
checkCAPAREA = 'nil
|
|
checkCAPPERI = 'nil
|
|
preserveRES = 'nil
|
|
checkRESVAL = 'nil
|
|
checkRESSIZE ='nil
|
|
resistorModel = ""
|
|
shortRES = 2000
|
|
simNetlistHier = 't
|
|
pinMAP = 'nil
|
|
displayPININFO = 't
|
|
checkLDD = 'nil
|
|
connects = ""
|
|
setEQUIV = ""
|
|
cdlSimViewList = '("auCdl" "schematic")
|
|
cdlSimStopList = '("auCdl")
|
|
simSimulator = "auCdl"
|
|
simRunDir = "$RUN_DIR"
|
|
hnlNetlistFileName = "$CELL.src.net"
|
|
simViewName = "$SCH_VIEW"
|
|
simCellName = "$CELL"
|
|
simLibName = "$LIBRARY"
|
|
incFILE = "$RUN_DIR/source.added"
|
|
auCdlNoForwardSlash = t
|
|
```
|
|
|
|
```skill
|
|
;; simrc
|
|
hnlSetBusDirectionDescending = 't
|
|
simVerilogGenerateSingleNetlistFile = 't
|
|
hnlVerilogPrintSpecparam = nil
|
|
simVerilogNetlistExplicit = 't
|
|
simPrintInhConnAttributes = t
|
|
hnlInhConnUseDefSigName = t
|
|
```
|
|
|
|
```skill
|
|
;; verilog.env
|
|
simLibName = "$LIBRARY"
|
|
simCellName = "$CELL"
|
|
simViewName = "$SCH_VIEW"
|
|
simSimulator = "verilog"
|
|
simNotIncremental = nil
|
|
simReNetlistAll = 't
|
|
simNetlistHier = t
|
|
simVerilogLaiLmsiNetlisting = 'nil
|
|
verilogSimViewList = '("behavioral" "functional" "system" "verilog" "schematic" "symbol")
|
|
simVerilogAutoNetlisting = 't
|
|
simVerilogTestFixtureFlag = 't
|
|
simVerilogTestFixtureTemplate = "All"
|
|
simVerilogNetlistExplicit = 't
|
|
hnlVerilogTermSyncUp = "mergeAll"
|
|
simVerilogFlattenBuses = 'nil
|
|
vtoolsUseUpperCaseFlag = 'nil
|
|
hnlVerilogCreatePM = 'nil
|
|
simVerilogTopLevelModuleName = "verilog_$CELL.top"
|
|
simHierarchyPrefix = "verilog_$CELL.top"
|
|
simNCVerilogHierPrefix = "verilog_$CELL:top"
|
|
verilogSimStopList = '("verilog" "symbol")
|
|
simVerilogPwrNetList = '("$PWRLIST")
|
|
simVerilogGndNetList = '("$GNDLIST")
|
|
vtoolsifForceReNetlisting = 'nil
|
|
simVerilogLibNames = '("$LIBLIST")
|
|
vlogifInternalTestFixtureFlag = 'nil
|
|
simVerilogBusJustificationStr = "U"
|
|
simVerilogTestFixtureTemplate = "All"
|
|
simVerilogDropPortRange = 't
|
|
simVerilogHandleUseLib = 'nil
|
|
simVerilogHandleAliasPort = 't
|
|
simVerilogPrintStimulusNameMappingTable = 'nil
|
|
simVerilogProcessNullPorts = 'nil
|
|
simVerilogIncrementalNetlistConfigList = 'nil
|
|
hnlVerilogNetlistStopCellImplicit = 'nil
|
|
simVerilogOverWriteSchTimeScale = 'nil
|
|
vlogifCompatibilityMode = "4.2"
|
|
simVerilogHandleSwitchRCData = 'nil
|
|
vlogifUseAssignsForAlias = 't
|
|
vlogifDeclareGlobalNetLocal = 'nil
|
|
vlogifSkipTimingInfo = 'nil
|
|
simVerilogEnableEscapeNameMapping = 'nil
|
|
simVerilogStopAfterCompilation = 't
|
|
simVerilogVhdlImport = 'nil
|
|
simVerilogTopCellCounter = 0
|
|
hnlSupportIterInst = 't
|
|
hnlNetlistFileName = "$CELL.v"
|
|
hnlSetBusDirectionDescending = 't
|
|
simVerilogGenerateSingleNetlistFile = 't
|
|
hnlVerilogPrintSpecparam = 'nil
|
|
simPrintInhConnAttributes = 't
|
|
hnlInhConnUseDefSigName = 't
|
|
```
|
|
|
|
### Property Based Removal
|
|
|
|
```
|
|
hnlHonorLxRemoveDevice = 't
|
|
hnlUserShortCVList = list( list("analogLib" "res") list("tsmcN40" "rnpolywo") )
|
|
```
|