Schematics

Introduction

High quality schematics can be generated from a netlist using Circuitikz for LaTeX diagrams. This is much easier than writing Circuitikz commands directly in LaTeX.

A semi-automatic component placement is used with hints required to designate component orientation and explicit wires to link nodes of the same potential but with different coordinates.

Here’s an example:
>>> from lcapy import Circuit
>>> cct = Circuit()
>>> cct.add('V 1 0 {V(s)}; down')
>>> cct.add('R 1 2; right')
>>> cct.add('C 2 0_2; down')
>>> cct.add('W 0 0_2; right')
>>> cct.draw('schematic.pdf')

Note, the orientation hints are appended to the netlist strings with a semicolon delimiter. The drawing direction is with respect to the first node. The component W is a wire. Nodes with an underscore in their name are not drawn with a closed blob.

The image generated by this netlist is:

_images/schematic.png
Here’s another example, this time loading the netlist from a file:
>>> from lcapy import Circuit
>>> cct = Circuit('voltage-divider.sch')
>>> cct.draw('voltage-divider.pdf')

Here are the contents of the file ‘voltage-divider.sch’:

Vi 1 0_1; down
R1 1 2; right, size=1.5
R2 2 0; down
P1 2_2 0_2; down, v=V_o
W 2 2_2; right
W 0_1 0; right
W 0 0_2; right

Here, P1 defines a port. This is shown as a pair of open blobs. The wires do not need unique names.

_images/voltage-divider.png

Component orientation

Lcapy uses a semi-automated component layout. Each component requires a specified orientation: up, down, left, or right. In addition, attributes can be added to override color, size, etc.

The drawing direction provides a constraint. For example, the nodes of components with a vertical orientation have the same x coordinate, whereas nodes of horizontal components have the same y coordinate.

The component orientation is specified by a rotation angle. This angle is degrees anticlockwise with zero degrees being along the positive x axis. For example,

>>> cct.add('D1 1 2; rotate=45')

The component orientation can also be specified by a direction keyword:

  • right (0 degrees)
  • left (180 degrees)
  • up (90 degrees)
  • down (-90 degrees)

For example:

D1 1 2;right






_images/Dright.png
D1 1 2;down





_images/Ddown.png

Note, the drawing direction is from the positive node to the negative node.

Here’s an example of how to draw a diode bridge:

D1 2 1; rotate=225, size=1.5
D2 3 2; rotate=-45, size=1.5
D3 3 4; rotate=225, size=1.5
D4 4 1; rotate=-45, size=1.5

_images/Dbridge.png

Components can be mirrored about the x-axis using the mirror attribute. For example, to switch the order of the inverting and non-inverting inputs of an opamp use:

>>> cct.add('E1 1 2 opamp 3 0; right, mirror')

Component size

By default each component has a minimum size of 1. This can be stretched to satisfy a node constraint. The minimum size is specified using the size keyword, for example:

>>> cct.add('R1 1 2; right, size=2')

The size argument is used as a scale factor for the component node spacing. The size can also be specified by adding a value to the left, right, up, or down arguments. For example:

>>> cct.add('R1 1 2; right=2')

Here’s a comparison of resistors of different sizes.

R1 1 2; right
R2 2 3; right=2
R3 3 4; right=3
;help_lines=1

_images/resistors1.png

By default, a component with size 1 has its nodes spaced by 2 units. This can be changed using the node_spacing option of the schematic. For example,

R1 1 2; right
R2 2 3; right=2
R3 3 4; right=3
;node_spacing=1.5, help_lines=1


_images/resistors2.png

Be default, a component has a length of 1.5 units. This can be changed using the cpt_size option of the schematic. For example,

R1 1 2; right
R2 2 3; right=2
R3 3 4; right=3
;cpt_size=1, help_lines=1

_images/resistors3.png
R1 1 2; right
R2 2 3; right=2
R3 3 4; right=3
;cpt_size=1, node_spacing=1, help_lines=1

_images/resistors4.png

The size of components can scaled with the scale attribute:

R1 1 2; right
R2 2 3; right=2, scale=2
R3 3 4; right=3, scale=3
;help_lines=1

_images/resistors6.png

The overall schematic can be scaled with the scale option of the schematic:

R1 1 2; right
R2 2 3; right=2
R3 3 4; right=3
;scale=0.5, help_lines=1

_images/resistors5.png

Nodes

Nodes are shown by a blob. By default, only the primary nodes (those without an underscore in them) are shown by default. This is equivalent to:

>>> cct.draw(draw_nodes='primary')

All nodes can be drawn using:

>>> cct.draw(draw_nodes='all')

Only the nodes where there are more than two branches can be drawn using:

>>> cct.draw(draw_nodes='connections')

No nodes can be drawn using:

>>> cct.draw(draw_nodes=False)

By default, only the primary nodes are labelled. All nodes can be labelled (this is useful for debugging) using:

>>> cct.draw(label_nodes='all')

No nodes can be labelled using:

>>> cct.draw(label_nodes=False)

Only nodes starting with a letter can be labelled using:

>>> cct.draw(label_nodes='alpha')

In this case nodes with names such as in and out will be displayed but not numeric node names.

These options can be stored with the schematic netlist, for example:

C1 1 0 100e-12; down, size=1.5, v={5\,kV}
R1 1 6 1500; right
R2 2 4 1e12; down
C2 3 5 5e-9; down
W 2 3; right
W 0 4; right
W 4 5; right
SW 6 2 no; right, l=, size=1.5
; draw_nodes=connections, label_nodes=False, label_ids=False

Components

Only linear, time-invariant, components can be analyzed.

Diodes

Diodes can be drawn but not simulated. A standard diode is described using:

Dname Np Nm

Other diodes are specified with an additional argument:

Dname Np Nm schottky|led|zener|tunnel|photo

Here’s an example:

D1 1 2; right
D2 2 3 schottky; right
D3 3 4 led; right
D4 4 5 zener; right
D5 5 6 tunnel; right
D6 6 7 photo; right
_images/diodes.png

Integrated circuits

ICs can be drawn but not simulated. Here’s an example:

; draw_nodes=connections, help_lines=1
U1 chip2121 _1 _2 .VSS .PIO1 .PIO2 .VDD; right=2, pins=auto
W U1.VDD VDD; implicit, up=0.2, l=3V3
W U1.VSS 0; implicit, down=0.7, l=0V
R1 U1.PIO1 1; right
D1 1 3 led; down
W 3 0; down=0.1, implicit, l=0V
R2 U1.PIO2 2; right
W 2 5; right
D2 5 4 led; down
W 4 0; down=0.1, implicit, l=0V



_images/ic1.png

In this example, the chip2121 keyword specifies a block with two pins on the left, one on the bottom, two on the right, and one at the top. The pins are enumerated anti-clockwise from top-left. Since the pin names start with a dot the associated node names are prefixed by the name of the chip, for example, U1.PIO1.

With the pins attribute set to auto the pins are labelled with their names unless the pin name starts with an underscore.

The supported chips are:
  • chip1310
  • chip2121
  • chip3131
  • chip4141
  • buffer
  • inverter

Here’s another example where the pin labels are explicitly defined with the pins attribute:

U1 chip2121 ._UNUSED1 ._UNUSED2 .VSS .PWM2 .PWM1 .VDD; right, l=MCU, pins={,,VSS, PWM2, PWM1, VDD}
M1 9 10 11; right
M2 12 13 14; right
W U1.PWM1 10; right=0.1
W U1.PWM2 13; right=0.1
TF1 1 2 3 4 tapcore 5 _6; right, l=1:100
W 9 8; up=0.1
W 8 3; right
W 7 5; right=0.5
W 12 4; up=0.1
W 14 14_1; down=0.1, implicit, l=0V
W 11 11_1; down=1.1, implicit, l=0V
W 7 7_1; up=0.8, implicit, l=3.9V
W U1.VSS _16; down=0.4, implicit, l=0V
W U1.VDD _17; up=0.2, implicit, l=3.3V
W 1 1_1; right=0.5
W 2 2_1; right=0.5
; draw_nodes=connections, label_nodes=alpha





_images/stepup.png

Meters

Here’s an example using a voltmeter and an ammeter:

BAT 1 0 7.2; down=1.5, l={7.2\,V}
AM 1 2; right=1.5
R 2 3; down
W 0 3; right
W 2 2_1; right
W 3 3_1; right
VM 2_1 3_1; down

_images/meters2.png

Opamps

Opamps can be drawn using the opamp argument to a VCCS. For example:

E 1 0 opamp 2 3 A; right
;help_lines=1

_images/opamp1.png

The size can be controlled with the scale and size options. The positions of the inverting and non-inverting inputs can be flipped with the mirror option.

E 1 0 opamp 2 3 A; right, scale=0.75, size=0.75
;help_lines=1


_images/opamp2.png
E 1 0 opamp 2 3 A; right, scale=0.75
;help_lines=1


_images/opamp3.png
E 1 0 opamp 2 3 A; right, scale=0.5
;help_lines=1


_images/opamp4.png

Fully differential opamps can be drawn in a similar manner using the fdopamp argument to a VCCS. For example:

E1 1 0 fdopamp 2 3 A; right
;help_lines=1

_images/fdopamp1.png

Switches

Switches can be drawn but they are ignored for analysis since they make the circuit time-varying.

The general format is:

SWname Np Nm nc|no|push

Here’s an example:

SW1 1 2 no; right
SW2 2 3 nc; right
SW3 3 4 push; right
SW4 4 5 6 spdt; right
_images/switches.png

Transformers

TF1 1 2 3 4; right


_images/TF1.png
TF1 1 2 3 4 core; right
_images/TFcore1.png
TF1 1 2 3 4 tap _5 _6; right
W 5 _5; right=0.5
W _6 6; right=0.5



_images/TFtap1.png
TF1 1 2 3 4 tapcore _5 _6; right
W 5 _5; right=0.5
W _6 6; right=0.5


_images/TFtapcore1.png

Transistors

Transistors (BJT, JFET, and MOSFET) can be drawn but not analyzed. Both are added to the netlist using a syntax similar to that of SPICE. A BJT is described using:

Qname NC NB NE npn|pnp

where NC, NB, and NE denote the collector, base, and emitter nodes. A MOSFET is described using:

Mname ND NG NS nmos|pmos

where ND, NG, and NS denote the drain, gate, and source nodes.

A JFET is described using:

Jname ND NG NS njf|pjf

where ND, NG, and NS denote the drain, gate, and source nodes.

Here’s an example:

Q1 1 2 3 npn; up
Q2 5 4 3 pnp; up
M1 5 6 7 nmos; up
M2 9 8 7 pmos; up
J1 9 10 11 njf; up
J2 13 12 11 pjf; up
_images/transistors.png

Transmission lines

A transmission line is a two-port device. Here’s an example:

U1 buffer ._in ._VSS ._out ._VDD; right
TL1 1 2 U1._out 4; right=2, scale=2, l={50\,$\Omega$}
R 1 2; down
W U1._VDD 9; up=0.1, implicit, l=Vdd
W U1._VSS 11; down
W 11 4; right=0.5
W 11 10; down=0.1, implicit, l=Vss
W 5 U1._in; right=0.5
;draw_nodes=connections, help_lines=0.1


_images/tline3.png

Wires

Components can be directly connected or by using wires. Wires need to be explicitly added to the netlist, for example,

W 1 2; right

Here an anonymous wire is created since it has no identifier.

The line style of wires can be changed, such as dashed or dotted (see Line styles).

Arrows

Arrows can be drawn on wires using the startarrow and endarrow attributes. There are many arrow styles, see the tikz manual. For example,

W 1 2; right, endarrow=tri,
W 2 3; right, endarrow=otri
W 3 4; right, startarrow=open triangle 90, endarrow=open triangle 90
W 4 5; right, startarrow=stealth, endarrow=stealth
; help_lines=1
_images/arrows.png

Implicit wires

Implicit wires are commonly employed for power supply and ground connections. They have the implicit attribute.

Block diagrams

Block diagrams can be constructed with the following components:
  • TF transfer function
  • SPpp, SPpm, SPppp, SPpmm, SPppm summing points
  • MX mixer
  • box rectangular box
  • circle circle (or ellipse)

Here’s an example showing negative feedback:

W 1 14; right=0.5, endarrow=tri, l=V{in}
SP1 pm 14 9 13; right, l={}
W 13 10; endarrow=tri, l=Vd
TR1 10 11 A; right=1.5, l=Open-loop gain (A)
W 11 2; right, l=V{out}
W 2 3; down
TR2 8 12 B; left=1.5, l=Attenuator $\beta$
W 3 8; left, endarrow=tri
W 12 4; left
W 4 9; up, endarrow=tri
W 2 5; right=0.5, endarrow=tri
; draw_nodes=false, label_nodes=false
_images/negative-feedback3.png

Summing points

There are a number of summing point varieties: SPpp, SPpm, SPppp, SPpmm, SPppm. The p suffix stands for plus, the m suffix stands for minus. The other variations can be generated using the mirror attribute.

Here’s an example:

SP1 pp ._1 ._2 ._3; down
W 1 SP1._1; down=0.5, endarrow=tri
W 2 SP1._2; right=0.5, endarrow=tri
W SP1._3 3; down=0.5, endarrow=tri
; draw_nodes=false

_images/SP4.png

Mixers

Here’s a example of a mixer:

MX1 ._1 ._2 ._3; right
W MX1._1 1; right=0.5, endarrow=tri
W 2 MX1._2; right=0.5, endarrow=tri
W 3 MX1._3; up=0.5, endarrow=tri



_images/MX1.png

Boxes and circles

box and circle have default anchor nodes based on the centre (c) and sixteen directions of the compass: n, nne, ne, ene, e, ese, se, sse, s, ssw, sw, wsw, w, wnw, nw, nww.

The aspect ratio of a box can be controlled with the aspect attribute.

Here’s an example of their use:

W x 1; right
W 1 S1.w; right=0.5, endarrow=tri
S1 box; right=0.5, l=$z^{-1}$
S2 circle; right=0.5, l=$\times$
S3 circle; right=0.5, l=$\times$
S4 circle; right=0.5, l=$+$
W S1.e 2; right=0.5
W 3 S4.w; right=1.25, endarrow=tri
W 1 S2.n; down
W S2.s 3; down
W a0 S2.w; right=0.5, endarrow=tri
W 2 S3.n; down, endarrow=tri
W S3.s S4.n; down, endarrow=tri
W a1 S3.w; right=0.5, endarrow=tri
W S4.e y; right=0.5, endarrow=tri
# Align multipliers
O S2.w S3.w; right
; draw_nodes=false, label_nodes=alpha
_images/fir5.png

The label can be replaced by an image, using the image keyword. For example,

S1 box; right=4, image=cmos1.png

Annotation

Schematics can be annotated using additional tikz commands in the netlist. These are delimited by a line starting with two semicolons, for example:

C1 1 0 100e-12;down
R1 1 6 1500;right
R2 2 4 1e12;down
C2 3 5 5e-9;down
W 2 3;right
W 0 4;right
W 4 5;right
SW 6 2 no;right, l=
;draw_nodes=connections, label_nodes=False, label_ids=False
;;\node[blue,draw,dashed,inner sep=5mm,anchor=north, fit=(1) (6) (0), label=Human body model] {};
;;\node[blue,draw,dashed,inner sep=5mm, fit=(2) (3) (4) (5), label=CMOS input model]{};

This example draws dashed boxes around the nodes 0, 1, and 6 and 2, 3, 4, and 5:

_images/fit1.png

Alternatively, the boxes can be fit around named components, for example:

;;\node[blue,draw,dashed,inner sep=5mm, fit=(R2) (C2), label=CMOS input model]{};

Styles

Three component styles are supported: american (default), british, and european. The style is set by a style argument to the draw method or by a schematic option. For example,

Vi 1 0_1; down
Rs 1 2; right=1.5
C 2 0; down
W 0_1 0; right
W 0 0_2; right
Rin 2_2 0_2; down, v=V_{in}
W 2 2_2; right
E1 3 0_3 2 0 A; down, l=A V_{in}
Rout 3 4; right=1.5
RL 4 0_4; down, v=V_o
W 0_2 0_3; size=1.2
W 0_3 0_4
P1 4 0_4; down
; style=european
_images/lpf1-buffer-loaded3.png

Colors

By default the components are drawn in black. This can be overridden with the color attribute, for example:

>>> cct.add('R1 1 2; right, color=blue')

Line styles

The line style of wires can be changed using the tikz attributes, dashed, dotted, thick, ultra thick, line width, and many others. For example,

W 1 2; right
W 2 3; right, dashed
W 3 4; right, dotted
W 4 5; right, thick
W 5 6; right, ultra thick
W 6 7; right, ultra thick, dashed
W 7 8; right, line width=4pt
; help_lines=1


_images/wirestyles.png

Labels

Each component has a component identifier label and a value label. These can be augmented by explicit voltage and current labels.

  • i=label – annotate current through component with label
  • v=label – annotate voltage across component with label
  • l=label – component label

The label name can be displayed using LaTeX math mode by enclosing the name between dollar signs. Thus superscripts and subscripts can be employed. For example,

>>> cct.add('R1 1 2; right, i=$I_1$, v=$V_{R_1}$')

The label position, current and voltage direction can be controlled with attributes _ ^ < and >, for example i^<=I_1. See the Circuitikz manual for details.

By default, if a component has a value label it is displayed, otherwise the component identifier is displayed. Both can be displayed using:

>>> cct.draw(label_ids=True, label_values=True)

Schematic options are separated using a comma. If you need a comma, say in a label, enclose the field in braces. For example:

>>> C1 1 0 100e-12; down, size=1.5, v={5\,kV}

Math-mode labels need to be enclosed in $...$. There is an experimental feature that is activated when the label starts with a single un-matched $. In this case, Lcapy tries to generate a nice LaTeX label. For example, words in sub- and superscripts are converted into a roman font using mathrm. This feature is also activated if the label is not enclosed in $...$ but includes an ^ or _.

Voltage labels can be annotated between pairs of nodes using an open-circuit component. For example,

>>> O1 1 0; down, v=V_1

Component attributes

  • size: scale factor for distance between component’s nodes
  • scale: scale factor for length of component
  • rotate: angle in degrees to rotate component anti-clockwise
  • mirror: mirror component in x-axis (opamps, transistors)
  • invisible: do not draw
  • color: component color
  • variable: for variable resistors, inductors, and capacitors
  • fixed: do not stretch
  • aspect: set aspect ratio for boxes
  • pins: define pin labels for ICs

Here’s an example using the variable attribute:

V 1 0 ac; down=1.5
L 1 2; right=1.5, variable
R 2 3; down, variable
W 0 3; right
W 2 2_1; right
W 3 3_1; right
C 2_1 3_1; down, variable


_images/variable1.png

Schematic attributes

  • node_spacing: scale factor for distance between component nodes (default 2)
  • cpt_size: length of component (default 1.5)
  • scale: scale factor (default 1)
  • help_lines: spacing between help lines (default 0 to disable)
  • draw_nodes: specifies which nodes to draw (default primary). Its argument can either be all, connections (nodes that connect at least two components), none, or primary (node names without an underscore).
  • label_nodes: specifies which nodes to label (default primary). Its argument can either be all, alpha (node names starting with a letter), none, or primary (node names without an underscore).
  • label_ids: specifies whether component ids are drawn (default true)
  • label_values: specifies whether component values are drawn (default true)
  • style: specifies the component style. This is either american, british, or european (default american).

Schematic attributes apply to the whole schematic. They can be specified by starting a netlist with a semicolon, for example,

;help_lines=1, draw_nodes=connections

The schematic attributes can be overridden using arguments to the draw method. For example,

>>> sch.draw(draw_nodes='alpha')

Includes

Large schematics can be composed by including smaller schematics using the .include directive, for example:

.include part1.sch
.include part2.sch

Each of the smaller schematics can be included into their own namespace to avoid conflicts, for example:

.include LC1.sch as s1
.include LC1.sch as s2
W s1.2 s2.1; right=0.1
W s1.3 s2.0; right=0.1

Namespaces

Hierarchical namespaces are supported, for example:

a.R1 1 2; right
b.R1 1 2; right

This creates two resistors: a.R1 with nodes a.1 and a.2 and b.R1 with nodes b.1 and a.2. They can be joined using:

W a.2 b.1; right

When node names start with a dot, they are defined relative to the name of the component, for example:

R1 .p .m; right
W 1 R1.p; right
W R1.m 2; right

Examples

P1 1 0_1; down
R1 1 2; right
R2 2_1 3_1; right
E1 3_2 0_3 opamp 2_0 2 A; mirror
W 0_1 0; right
W 2_0 0; down
W 3_2 3; right
W 0 0_3; right
P2 3 0_3; down
W 2_1 2; down
W 3_1 3_2; down
_images/opamp-inverting-amplifier.png
P1 1 0_1; down
W 2_1 2; down
R1 2 0; down
R2 2 3_1; right
W 3_2 3_1; down
E1 3_2 0_3 opamp 1_1 2_1 A;
W 0_1 0; right
W 3_2 3; right
W 0 0_3; right
P2 3 0_3; down
W 1 1_1; right

_images/opamp-noninverting-amplifier.png
P1 1 0_1; down
R 1 2; right
C 2_1 3_1; right
E1 3_2 0_3 opamp 2_0 2 A; mirror
W 0_1 0; right
W 2_0 0; down
W 3_2 3; right
W 0 0_3; right
P2 3 0_3; down
W 2_1 2; down
W 3_1 3_2; down
_images/opamp-inverting-integrator.png
M1 3_c 2_p Vdd pmos P; right
M2 3_c 2_n 0 nmos N; right
W 2_p 2_c; down=0.5
W 2_c 2_n; down=0.5
W in 2_c; right
W 3_c out; right
P1 in 0_2; down
P2 out 0_3; down
W 0_2 0;right
W 0 0_3;right

_images/cmos1.png
D1 1 2; left=1.5
D2 3 4; right
D3 1 4; down=1.5
D4 3 2; up

_images/D4.png
P1 1 0_1
R1 1 3; right
L1 3 2; right
C1 3 4; down
L2 4 0; down
P2 2 0_2
W 0_1 0; right
W 0 0_2; right

_images/pic6.png
L1 1 0 0.1; down
L2 2 3 1; down=1.5
K1 L1 L2; size=1.5
;label_ids=false
_images/K1.png
V1 1 0; down
R1 1 2; left=2, i=I_1, v=V_{R_1}
R2 1 3; right=2, i=I_2, v=V_{R_2}
L1 2 0_1; down=2, i=I_1, v=V_{L_1}
L2 3 0_3; down=2, i=I_2, v=V_{L_2}
W 0 0_3; right
W 0 0_1; left



_images/VRL2.png
Vi 1 0_1; down
Rs 1 2; right=1.5
C 2 0; down
W 0_1 0; right
W 0 0_2; right
Rin 2_2 0_2; down, v=V_{in}
W 2 2_2; right
E1 3 0_3 2 0 A; down, l=A V_{in}
Rout 3 4; right=1.5
RL 4 0_4; down, v=V_o
W 0_2 0_3; size=1.2
W 0_3 0_4
P1 4 0_4; down

_images/lpf1-buffer-loaded2.png
P 1 0; down, v=v_{in}(t)
R1 1 2; right
R2 2 3; right
C1 2 4; up
C2 3 9; down
W 4 5; right
W 5 6; right
W 6 7; down=0
W 7 8; right=0.5
E 7 0 opamp 3 11 A; right, mirror, scale=0.75, size=0.75
W 5 11; down=0.5
P 8 10; down, v^=v_{out}(t)
W 0 9; right
W 9 10; right
;draw_nodes=connections, label_nodes=False, help_lines=1


_images/sallen-key-lpf1.png
U1 inverter ._IN ._VSS ._OUT ._VDD; right=2, l={}
U2 inverter ._IN ._VSS ._OUT ._VDD; right=2, l={}
W U1._OUT U2._IN; right=1
W U1._VSS 4_2; down=0.3, implicit, l=0V
W U2._VSS 4_3; down=0.3, implicit, l=0V
W U1._VDD 3_2; up=0.3, implicit, l=V_{DD1}
W U2._VDD 3_3; up=0.3, implicit, l=V_{DD2}
W U2._IN 7_1; right=0.25, dashed, fixed, color=red
D 7_1 6_1; up=0.25, scale=0.5, l=, color=red
D 6_2 7_1; up=0.25, scale=0.5, l=
W 6_1 U2._VDD; right=0.6, dashed, color=red
W 6_2 U2._VSS; right=0.6, dashed
M1 1 2 3 pmos; right=0.25, scale=0.25, l={}, color=red
M2 1 4 5 nmos; right=0.25, scale=0.25, l={}
W 3 3_1; up=0.0, color=red
W 3_1 U1._VDD; right=0.2, dashed, color=red
W 5 5_1; down=0.0
W 5_1 U1._VSS; right=0.2, dashed
W 1 U1._OUT; right, dashed, color=red
;draw_nodes=connections,label_nodes=false,thickness=2

_images/cmos-backdrive2.png
U1 inverter .in .VSS .out .VDD; right
W 5 U1.in; right=0.5
W U1.out 6; right=0.5
W 6 9; right=0.5
R1 7 8; right
W 5 1; down=0.75
W 6 2; down=0.75
W 5 7; up=0.75
W 6 8; up=0.75
XT1 1 2; right
C1  1 4; down=0.8
C2  2 3; down=0.8
W 4 0; down=0.1, implicit, l=GND
W 3 0; down=0.1, implicit, l=GND
; draw_nodes=connections, label_nodes=False
_images/pierce-oscillator.png

File formats

Lcapy uses the filename extension to determine the file format to produce. This must be one of tex, schtex, png, svg, or pdf. The schtex format is useful for including schematics into LaTeX documents. The tex format generates a standalone LaTeX file. If no filename is specified, the schematic is displayed on the screen.

schtex.py

schtex.py is a Python script that will generate a schematic from a netlist file. For example, here’s how a PNG file can be generated:

>>> schtex.py Dbridge.sch Dbridge.png

The generated stand-alone LaTeX file can be obtained using:

>>> schtex.py Dbridge.sch Dbridge.tex

If you wish to include the schematic into a LaTeX file use:

>>> schtex.py Dbridge.sch Dbridge.schtex

and then include the file with \input{Dbridge.schtex}.

schtex.py has many command line options to configure the drawing. These override the options specified in the netlist file. For example:

>>> schtex.py --draw_nodes=connections --label_nodes=false --cpt-size=1 --help_lines=1 Dbridge.sch Dbridge.pdf

Drawing tips

Lcapy uses a semi-automated approach to component layout. For each component it needs its orientation and size. By default the size is 1. This is the minimum distance between its nodes (for a one-port device). If the component can be stretched, Lcapy will increase but never decrease this distance.

The x and y positions of nodes are computed independently using a graph. An error can occur if components have the wrong orientation since this makes the graph inconsistent. Unfortunately, it is not trivial to find the offending component so it is best to draw a schematic incrementally and to test it as you go. A sketch on a piece of paper showing the nodes is useful.

Problems can occur using components, such as integrated circuits and opamps, that cannot be stretched. Usually this is due to a conflict between constraints. A solution is to reduce the size of the component if it can be stretched, such as a wire or resistor. Sometimes it is necessary to add a short interconnecting wire.

The stretching of components can be prevented by specifying the fixed attribute.

Additional constraints can be supplied by using an invisible component, for example, an open-circuit.

Grid lines can be added to a schematic using some Tikz markup. For example:

;;\draw[help lines] (0,0) grid [xstep=0.1, ystep=0.1] (10,5);