mirror of
https://github.com/lleene/hugo-site.git
synced 2025-01-23 03:52:21 +01:00
Content update Oct.
This commit is contained in:
parent
14afbc60a6
commit
48b63baa25
@ -47,5 +47,3 @@ my long term projects which is related to image classification based on
|
||||
structural decomposition rather than textural features. The main idea here is
|
||||
to analyse and extract structure in an image before performing in-depth analysis
|
||||
such that said analysis is most specific to its context.
|
||||
|
||||
![small_sip](/images/sip.gif)
|
||||
|
@ -1,5 +1,5 @@
|
||||
---
|
||||
title: "Building With SVG"
|
||||
title: "Building With SVG 🖼"
|
||||
date: 2021-08-28T11:53:54+02:00
|
||||
draft: false
|
||||
toc: true
|
||||
@ -10,19 +10,17 @@ tags:
|
||||
- golang
|
||||
---
|
||||
|
||||
# SVG Tools and Hugo Integration
|
||||
SVG is generally my image format of choice having used it for illustrations,
|
||||
chip diagrams, device specifications, and visual outputs generated by code.
|
||||
SVG is plain text-baesd xml that is structured with some top level
|
||||
object/properties followed by standardized objects that draw lines and shapes.
|
||||
|
||||
SVG is generally the image container of choice having used it for illustrations,
|
||||
chip or device specifications, and visual outputs generated by code. SVG is
|
||||
plain xml that is structured with some top level object/properties followed by
|
||||
standardized objects that draw lines and shapes.
|
||||
The hope here is that we can call a predefined go procedure that parses
|
||||
some section of markdown source code and instantiates the corresponding svg file
|
||||
under our static folder that is then referenced.
|
||||
|
||||
``` go
|
||||
{{/* a comment */}}
|
||||
```
|
||||
On a few occasions, I have scripted the generation of some SVG illustration
|
||||
where some parameters are extracted from a database that are then visualized.
|
||||
These scripts are generally quite simple since you just define some
|
||||
pre-formatted shapes and place them inside the drawing region. Besides this
|
||||
I think it useful to highlight some of the automated tools and libraries
|
||||
that are useful with similar functionality.
|
||||
|
||||
## KGT: Kate's Grammar Tool
|
||||
|
||||
@ -90,3 +88,59 @@ added directly to KGT as a feature in future releases.
|
||||
The final result is shown below.
|
||||
|
||||
![example_kgt.svg](/images/example_kgt.svg)
|
||||
|
||||
## Tabatkins Railroad Diagrams
|
||||
|
||||
On the topic of rail-road diagrams there is also a repository from
|
||||
[tabatkins](https://github.com/tabatkins/railroad-diagrams) which is a python
|
||||
based code-base for generating similar SVG diagrams as KGT but without having
|
||||
to deal with building or running binaries. I prefer monochrome diagrams with
|
||||
plan formatting so again we are overriding the default style.
|
||||
|
||||
``` python
|
||||
style = ( ''
|
||||
+'\tsvg.railroad-diagram {\n\t\tbackground-color:none;\n\t}\n'
|
||||
+'\tsvg.railroad-diagram path {\n\t\tstroke-width:1.5;\n\t\tstroke:white;\n\t\tfill:rgba(0,0,0,0);\n\t}\n'
|
||||
+'\tsvg.railroad-diagram text {\n\t\tfont:bold 14px monospace;\n\t\tfill: white;\n\t\ttext-anchor:middle;\n\t}\n'
|
||||
+'\tsvg.railroad-diagram text.label{\n\t\ttext-anchor:start;\n\t}\n'
|
||||
+'\tsvg.railroad-diagram text.comment{\n\t\tfont:italic 12px monospace;\n\t}\n'
|
||||
+'\tsvg.railroad-diagram rect{\n\t\tstroke-width:1.5;\n\t\tstroke:white;\n\t\tfill:none;\n\t}\n'
|
||||
+'\tsvg.railroad-diagram rect.group-box {\n\t\tstroke: gray;\n\t\tstroke-dasharray: 10 5;\n\t\tfill: none;\n\t}\n'
|
||||
)
|
||||
```
|
||||
|
||||
Styling is best done on a case to case basis with various color-schemes such as
|
||||
using white text/lines for dark themes. Since this is all handeled in python
|
||||
the overall interface. Possibly including some kind of command-line utility
|
||||
here would be quite good but it depends on the final flow for figure generation.
|
||||
Using the style definition shown above, generating a similar example as before
|
||||
would look like this:
|
||||
|
||||
``` python
|
||||
import railroad
|
||||
with open("./test.svg","w+") as file:
|
||||
obj = railroad.Diagram("foo", railroad.Choice(0, "bar", "baz"), css=style)
|
||||
obj.writeSvg(file.write)
|
||||
```
|
||||
|
||||
The final result is shown below.
|
||||
|
||||
![example_kgt.svg](/images/example_trd.svg)
|
||||
|
||||
Note that this figure is quite a bit more compact but adding additional labels
|
||||
or customizations outside the scope of the library will probably require
|
||||
quite a bit of manual work. This could be a fun side project though.
|
||||
|
||||
## Mermaid CLI
|
||||
|
||||
|
||||
|
||||
# Hugo Integration
|
||||
|
||||
The hope here is that we can call a predefined go procedure that parses
|
||||
some section of markdown source code and instantiates the corresponding svg file
|
||||
under our static folder that is then referenced.
|
||||
|
||||
``` go
|
||||
{{/* a comment */}}
|
||||
```
|
||||
|
@ -1,5 +1,5 @@
|
||||
---
|
||||
title: "Calibre Physical Verification Hacks"
|
||||
title: "Calibre Physical Verification Hacks 🐛🐛"
|
||||
date: 2021-09-14T11:30:11+02:00
|
||||
draft: false
|
||||
toc: true
|
||||
@ -9,42 +9,74 @@ tags:
|
||||
- verification
|
||||
---
|
||||
|
||||
This is a list of 'modifications' to the standard Calibre verification flow I
|
||||
have used in the past to either modify the checks performed by Calibre or input
|
||||
data bases.
|
||||
|
||||
# DRC
|
||||
This page details a variety of 'modifications' to the standard Calibre
|
||||
verification flow I have used in the past to either modify the checks performed
|
||||
tools in the physical verification flow. None of which are particularly clean
|
||||
since they depart from what is usually an approved rule deck / verification
|
||||
flow. Designs do need to pass the verification process in a meaningful way at
|
||||
the end of the day so your mileage may vary.
|
||||
|
||||
## Extended Device Checks
|
||||
|
||||
It is generally good practice to be able to check for internal design
|
||||
conventions when it comes to layout. Making a custom set of rules that does
|
||||
exactly this is highly advised to yield better quality designs. For example
|
||||
it could be required that varactor or mosfet primitives should never have
|
||||
overlapping shapes with other devices of the same type. The rule below
|
||||
will check for exactly this and report it as a "NVA0.VAR_OVLP" violation.
|
||||
|
||||
```tvf
|
||||
NVA0.VAR_OVLP { @ Varactors / Tiles should not overlap
|
||||
VARi AND > 1
|
||||
}
|
||||
```
|
||||
|
||||
There are other rules that are required or suggested by the DRM that simply
|
||||
don't have a good DRC rule. For example requiring tear-shaped geometries on
|
||||
the RDL layer near flip-chip balls. Getting an approximate rule check that
|
||||
catches the more obvious issues is worthwhile including.
|
||||
|
||||
```tvf
|
||||
NVA1.Cu_PPI.TEAR { @ Shape of Cu_PP I pad (under PM2 area): tear shape required
|
||||
X0 = EXT Cu_PPIi <1 ABUT <125 INTERSECTING ONLY REGION
|
||||
X1 = EXT Cu_PPIi <1 ABUT <180 INTERSECTING ONLY REGION
|
||||
X2 = INT Cu_PPIi <1 ABUT <180 INTERSECTING ONLY REGION
|
||||
NVA0.RDL.TEAR { @ Shape of RDL near pad: tear shape required
|
||||
X0 = EXT RDL <1 ABUT <125 INTERSECTING ONLY REGION
|
||||
X1 = EXT RDL <1 ABUT <180 INTERSECTING ONLY REGION
|
||||
X2 = INT RDL <1 ABUT <180 INTERSECTING ONLY REGION
|
||||
X3 = EXPAND EDGE (X1 NOT TOUCH INSIDE EDGE X0) BY 1 EXTEND BY 50
|
||||
X4 = EXPAND EDGE (X2 NOT TOUCH INSIDE EDGE X0) BY 1 EXTEND BY 50
|
||||
(X3 AND X0) OR (X4 AND X0)
|
||||
}
|
||||
```
|
||||
|
||||
The above rule finds regions with acute angles (internal and external)
|
||||
near regions with obtuse angles where the latter is generally the rounded
|
||||
RDL landing pad for the ball.
|
||||
|
||||
## Layer / Device Aliasing
|
||||
|
||||
Layer aliasing or remapping is another way to add indirection to the DRC rule
|
||||
deck that will allow you to both run your own checks and device recognition
|
||||
without interfering with the standard flow.
|
||||
|
||||
```tvf
|
||||
LAYER MAP 107 DATATYPE 0 746
|
||||
```
|
||||
|
||||
# LVS
|
||||
In the above scenario we allocated an additional layer in the Cadence design
|
||||
to designate inductor recognition beside the standard inductors. This was
|
||||
required since the standard inductors also implied metallization free regions
|
||||
which is not always be acceptable. By adding this layer and mapping it to
|
||||
the same inductor recognition data type during LVS these inductors would still
|
||||
be recognized but did not trigger the associated metallization rules during DRC.
|
||||
|
||||
## Adding New Device Primitives
|
||||
|
||||
Another good know how is the process behind device recognition when you run
|
||||
the Calibre LVS process. The code snippets below take us through a process of
|
||||
defining a new device for LVS recognition that is bound together with a spice
|
||||
definition to produce the extracted netlist. This should allow you to define
|
||||
custom layers and define custom devices on those layers while still getting
|
||||
LVS clean at the end of the day. This example will define a custom resistor.
|
||||
|
||||
```tvf
|
||||
LAYER RESLYR 450
|
||||
LAYER MAP 215 DATATYPE 21 450 // layer to form memresistor
|
||||
@ -54,10 +86,18 @@ CONNECT metal4 MEMRESLYRT
|
||||
DEVICE XDEVICE XCDTR XTERM(PORT1) XTERM(PORT2) netlist model xdevice
|
||||
```
|
||||
|
||||
```spice
|
||||
.SUBCKT xdevice PORT1 PORT2
|
||||
.ENDS
|
||||
```
|
||||
The section of code above are LVS rule statements that first define a named
|
||||
layer `RESLYR` and then map a data type onto that layer. The data type should
|
||||
correspond to what ever you new layer you used to define the device in the
|
||||
layout editor. Then we define the terminals of this device when ever this layer
|
||||
overlaps and connects with metal 4 otherwise it is the resistive section.
|
||||
Finally you specify a device in terms of the relevant layers and how they map
|
||||
to the actual model.
|
||||
|
||||
Notice the device maps to a netlist model called `xdevice` with named ports.
|
||||
This model is defined below. Note that we haven´t extracted any parameters
|
||||
but this could be done in the rule deck definition. Also note that here
|
||||
we also specify the mapping of this `xdevice` to a cell in the design library.
|
||||
|
||||
```lisp
|
||||
(xdevice
|
||||
@ -73,8 +113,24 @@ DEVICE XDEVICE XCDTR XTERM(PORT1) XTERM(PORT2) netlist model xdevice
|
||||
)
|
||||
```
|
||||
|
||||
Finally a spice definition must also be included in order to run the netlist
|
||||
comparison. Assuming the cell in the design library correctly netlists with a
|
||||
auCDL view. The spice definition below presumes both the layout and schematic
|
||||
perform black-boxed comparison of this new resistor.
|
||||
|
||||
```spice
|
||||
.SUBCKT xdevice PORT1 PORT2
|
||||
.ENDS
|
||||
```
|
||||
|
||||
## Extending Connectivity Layers
|
||||
|
||||
In some occasions it could be that certain extra layers are defined in the DRC
|
||||
deck but not in the LVS deck. For example there are optional metallization
|
||||
layers for your process. Adding connectivity is rather strait forward.
|
||||
The main challenge here is to choose the correct data type mappings as to
|
||||
avoid conflicts with the original rule statements.
|
||||
|
||||
```tvf
|
||||
LAYER PM1i 5001
|
||||
LAYER MAP 5 DATATYPE 1 5001
|
||||
@ -88,6 +144,15 @@ VIA8 = COPY CB2
|
||||
metal9 = COPY Cu_PPIi
|
||||
VIA9 = COPY PM2i
|
||||
metal10 = COPY UBM
|
||||
```
|
||||
|
||||
Once these layers are defined we can go ahead and specify the order of
|
||||
connectivity. Notice that we can´t directly operate / manipulate layer
|
||||
definitions so simply running a `COPY` statement resolves this. Below we
|
||||
see also that adding ports and text labels connectivity for the relevant
|
||||
layers is also needed for your pins to connect.
|
||||
|
||||
``` tvf
|
||||
CONNECT metal9 metal8 BY VIA8
|
||||
CONNECT metal10 metal9 BY VIA9
|
||||
TEXT LAYER 140 ATTACH 140 metal9
|
||||
@ -100,70 +165,14 @@ PORT LAYER TEXT 125
|
||||
|
||||
## Hot fixing LVS comparison
|
||||
|
||||
Finally the rule statements below are global deck adjustments. They are
|
||||
for the most part self explanatory except for `CULL` which actually
|
||||
removes empty spice sub-circuits that are identified by a hierarchical LVS run
|
||||
but does not actually contain active devices (i.e. a dummy digital filler cell).
|
||||
|
||||
```tvf
|
||||
LVS SPICE CULL PRIMITIVE SUBCIRCUITS YES
|
||||
VIRTUAL CONNECT NAME "POWER"
|
||||
TEXT "POWER" LOCX LOCY DATATYPE
|
||||
TEXT "NET_NAME" LOCX LOCY DATATYPE
|
||||
LAYOUT RENAME TEXT "/DATA\\[(.*)\\]/DATA<-1>/M-"
|
||||
```
|
||||
|
||||
|
||||
|
||||
# SPICE
|
||||
|
||||
## Port Order Reshuffling
|
||||
|
||||
```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[@]}"
|
||||
}
|
||||
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"
|
||||
}
|
||||
```
|
||||
|
||||
```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 };
|
||||
```
|
||||
|
||||
```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}
|
||||
```
|
||||
|
@ -1,5 +1,5 @@
|
||||
---
|
||||
title: "Binding QML with Python: PyViewer"
|
||||
title: "Binding QML with Python: PyViewer 👾"
|
||||
date: 2021-08-29T12:53:19+02:00
|
||||
draft: false
|
||||
toc: true
|
||||
|
69
content/posts/spice-monkey.md
Normal file
69
content/posts/spice-monkey.md
Normal file
@ -0,0 +1,69 @@
|
||||
---
|
||||
title: "Spice Monkey 💻🐒"
|
||||
date: 2021-10-29T18:54:32+02:00
|
||||
draft: false
|
||||
toc: false
|
||||
images:
|
||||
tags:
|
||||
- spice
|
||||
- code
|
||||
- verification
|
||||
---
|
||||
|
||||
|
||||
## Port Order Reshuffling
|
||||
|
||||
```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[@]}"
|
||||
}
|
||||
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"
|
||||
}
|
||||
```
|
||||
|
||||
```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 };
|
||||
```
|
||||
|
||||
```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}
|
||||
```
|
40
static/images/example_trd.svg
Normal file
40
static/images/example_trd.svg
Normal file
@ -0,0 +1,40 @@
|
||||
<svg class="railroad-diagram" height="92" viewBox="0 0 231.0 92" width="231.0" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g transform="translate(.5 .5)">
|
||||
<style>/* <![CDATA[ */
|
||||
svg.railroad-diagram {
|
||||
background-color:none;
|
||||
}
|
||||
svg.railroad-diagram path {
|
||||
stroke-width:1.5;
|
||||
stroke:white;
|
||||
fill:rgba(0,0,0,0);
|
||||
}
|
||||
svg.railroad-diagram text {
|
||||
font:bold 14px monospace;
|
||||
fill: white;
|
||||
text-anchor:middle;
|
||||
}
|
||||
svg.railroad-diagram text.label{
|
||||
text-anchor:start;
|
||||
}
|
||||
svg.railroad-diagram text.comment{
|
||||
font:italic 12px monospace;
|
||||
}
|
||||
svg.railroad-diagram rect{
|
||||
stroke-width:1.5;
|
||||
stroke:white;
|
||||
fill:none;
|
||||
}
|
||||
svg.railroad-diagram rect.group-box {
|
||||
stroke: gray;
|
||||
stroke-dasharray: 10 5;
|
||||
fill: none;
|
||||
}
|
||||
|
||||
/* ]]> */
|
||||
</style><g>
|
||||
<path d="M20 21v20m10 -20v20m-10 -10h20"></path></g><path d="M40 31h10"></path><g class="terminal ">
|
||||
<path d="M50 31h0.0"></path><path d="M95.5 31h0.0"></path><rect height="22" rx="10" ry="10" width="45.5" x="50.0" y="20"></rect><text x="72.75" y="35">foo</text></g><path d="M95.5 31h10"></path><g>
|
||||
<path d="M105.5 31h0.0"></path><path d="M191.0 31h0.0"></path><path d="M105.5 31h20"></path><g class="terminal ">
|
||||
<path d="M125.5 31h0.0"></path><path d="M171.0 31h0.0"></path><rect height="22" rx="10" ry="10" width="45.5" x="125.5" y="20"></rect><text x="148.25" y="35">bar</text></g><path d="M171.0 31h20"></path><path d="M105.5 31a10 10 0 0 1 10 10v10a10 10 0 0 0 10 10"></path><g class="terminal ">
|
||||
<path d="M125.5 61h0.0"></path><path d="M171.0 61h0.0"></path><rect height="22" rx="10" ry="10" width="45.5" x="125.5" y="50"></rect><text x="148.25" y="65">baz</text></g><path d="M171.0 61a10 10 0 0 0 10 -10v-10a10 10 0 0 1 10 -10"></path></g><path d="M 191.0 31 h 20 m -10 -10 v 20 m 10 -20 v 20"></path></g></svg>
|
After Width: | Height: | Size: 1.8 KiB |
Binary file not shown.
Before Width: | Height: | Size: 2.7 MiB |
Loading…
x
Reference in New Issue
Block a user