Logic gate diagram
Combinational and sequential logic gates with automatic DAG layout and Manhattan wiring. IEEE 91 ANSI distinctive shapes or IEC 60617 rectangular symbols.
Dual-standard support: IEEE Std 91-1984/91a-1991 (ANSI distinctive shapes) + IEC 60617-12 (rectangular symbols).
Primary References:
- IEEE Std 91-1984 / ANSI Y32.14: Logic Symbol Standard (Distinctive-Shape)
- IEEE Std 91a-1991: Supplement for distinctive-shape symbols
- IEC 60617-12: Graphical symbols for diagrams — binary logic elements
- Schemdraw Logic module: https://schemdraw.readthedocs.io/en/stable/classes/logic.html
1. Gate Symbol Set
1.1 Symbol Style Options
Both standards are supported; Schematex selects between them via the render config style parameter:
| Style | Standard | Characteristic | Primary Use |
|---|---|---|---|
ansi (default) | IEEE 91 | Distinctive curved shapes | US education + industry |
iec | IEC 60617-12 | Uniform rectangles + symbol | International + Europe |
1.2 Combinational Gate Symbols (ANSI Distinctive Shape)
All coordinates are based on a 100×60px normalized space (width×height), scalable via the scale parameter.
AND Gate
- Shape: Flat back (left) + semicircle front (right), D-shape
- SVG Path:
M 20,60 L 20,0 Q 80,0 80,30 Q 80,60 20,60 Z - Input Pin 1:
(20, 15)— left edge, upper - Input Pin 2:
(20, 45)— left edge, lower - Output Pin:
(80, 30)— right center - Wire extension: inputs extend 10px left, output extends 10px right
- IEC Symbol: Rectangle
(10,5)→(90,55)+ centered&label
OR Gate
- Shape: Curved back (left) + pointed front (right), crescent shape
- SVG Path:
M 15,60 Q 10,30 15,0 Q 30,15 70,30 Q 30,45 15,60 Z - Input Pin 1:
(15, 15)— curved left, upper - Input Pin 2:
(15, 45)— curved left, lower - Output Pin:
(70, 30)— right point - IEC Symbol: Rectangle +
≥1label
NOT Gate (Inverter)
- Shape: Triangle + output bubble circle
- SVG Path:
M 10,55 L 55,30 L 10,5 Z(triangle) - Bubble:
<circle cx="60" cy="30" r="5"/> - Input Pin:
(10, 30)— left - Output Pin:
(65, 30)— after bubble - IEC Symbol: Rectangle +
1label + output bubble circle
NAND Gate
- AND Gate shape + output bubble
- Output Pin:
(85, 30)(AND output + bubble radius 5) - IEC Symbol: Rectangle +
&+ output bubble
NOR Gate
- OR Gate shape + output bubble
- Output Pin:
(75, 30)(OR output + bubble radius 5) - IEC Symbol: Rectangle +
≥1+ output bubble
XOR Gate
- OR Gate + extra curved back line (parallel to back curve)
- Extra path:
M 8,60 Q 3,30 8,0(parallel arc, offset 7px left of OR back) - Input Pin 1:
(8, 15)— from extra arc - Input Pin 2:
(8, 45)— from extra arc - Output Pin:
(70, 30)— same as OR - IEC Symbol: Rectangle +
=1
XNOR Gate
- XOR Gate + output bubble
- IEC Symbol: Rectangle +
=1+ output bubble
Buffer (Non-inverting)
- Triangle (no bubble)
- SVG Path:
M 10,55 L 55,30 L 10,5 Z - Input Pin:
(10, 30), Output Pin:(55, 30) - IEC Symbol: Rectangle +
1(no bubble)
Tri-State Buffer
- Buffer + enable input (bottom control line)
- Enable Input Pin:
(30, 55)— bottom center - When enable = 0, output is Z (high-impedance)
1.3 3-Input Gate Variants
The 3-input variant adds a third pin at center height:
- AND3 Pin 3:
(20, 30)— left edge, center - OR3 Pin 3:
(15, 30)— curved left, center - 4-input follows the same pattern (evenly distributed along the left edge)
1.4 Bubble (Active-Low) Notation
Input bubble = active-low input; the circle is placed between the pin and the gate body:
<circle cx="x_pin_end" cy="y_pin" r="4" fill="white" stroke="#333" stroke-width="1.5"/>The input pin extends an extra 8px (bubble diameter); the wire enters from (x_pin_end - 4, y_pin).
1.5 Clock Input Triangle
In flip-flop elements, the clock input is marked with a small triangle:
<!-- Triangle pointing right, at clock pin position (x_clk, y_clk) -->
<polygon points="x_clk,y_clk-5 x_clk+8,y_clk x_clk,y_clk+5"
fill="#333" stroke="none"/>2. Sequential Logic Symbols
2.1 D Flip-Flop
Rectangle box (0,0)→(60,80) + the following pins:
| Pin | Position | Symbol | Direction |
|---|---|---|---|
| D (Data) | (0, 20) | D | Input |
| CLK (Clock) | (0, 40) | ▷ triangle | Input |
| S (Set, optional) | (30, 0) | S | Input active-low |
| R (Reset, optional) | (30, 80) | R | Input active-low |
| Q | (60, 20) | Q | Output |
| Q̄ (Q-not) | (60, 60) | Q̄ + bubble | Output |
Clock triangle SVG (on the left side of the box, at CLK pin position):
<polygon points="0,35 8,40 0,45" fill="#333"/>Q̄ bubble (on the right side of the box, at Q̄ pin position):
<circle cx="64" cy="60" r="4" fill="white" stroke="#333" stroke-width="1.5"/>2.2 JK Flip-Flop
Rectangle box (0,0)→(60,80) + the following pins:
| Pin | Position | Symbol |
|---|---|---|
| J | (0, 15) | J |
| K | (0, 55) | K |
| CLK | (0, 35) | triangle |
| S, R | top / bottom | active-low |
| Q, Q̄ | right side | same as DFF |
2.3 SR Latch (no clock)
Rectangle box (0,0)→(50,60) + pins:
| Pin | Position |
|---|---|
| S | (0, 15) |
| R | (0, 45) |
| Q | (50, 15) |
| Q̄ | (50, 45) + bubble |
2.4 T Flip-Flop
Rectangle box (0,0)→(60,60):
| Pin | Position |
|---|---|
| T | (0, 20) |
| CLK | (0, 40) + triangle |
| Q | (60, 20) |
| Q̄ | (60, 50) + bubble |
2.5 Register (N-bit)
Larger rectangle box, height scales with bit width:
- Input bus: left side, with
/Nbus annotation - CLK: left side, triangle marker
- Output bus: right side, with
/Nannotation - Bus lines use thick stroke (stroke-width: 3) + slash annotation for bit width
3. Connection & Wiring Conventions
3.1 Wire Routing
- Orthogonal routing (Manhattan routing): all wires are horizontal or vertical, never diagonal
- Signal flow direction: left → right (inputs on the left, outputs on the right)
- Feedback paths: routed above or below the main signal flow
3.2 Junction & Crossing
| Case | Visual | SVG |
|---|---|---|
| T-junction (connected) | Solid dot | <circle r="3" fill="#333"/> |
| Cross-over (not connected) | No dot, lines pass over each other | Two independent <line> elements |
| Bridge (one line crosses another) | White gap | Overlay white rect on bottom line, then draw top line |
<!-- Junction dot at (x, y) -->
<circle cx="x" cy="y" r="3" fill="#333" class="lt-junction"/>
<!-- Bridge: bottom line has gap at crossing -->
<!-- 1. Draw bottom line with gap (two segments) -->
<line x1="x1" y1="y" x2="x_cross-5" y2="y" stroke="#333" stroke-width="2"/>
<line x1="x_cross+5" y1="y" x2="x2" y2="y" stroke="#333" stroke-width="2"/>
<!-- 2. Draw top line continuously -->
<line x1="x" y1="y1" x2="x" y2="y2" stroke="#333" stroke-width="2"/>3.3 Bus Notation
Multi-bit buses use thick lines + slash annotation:
<!-- Bus line (thick) -->
<line x1="x1" y1="y" x2="x2" y2="y" stroke="#333" stroke-width="4"/>
<!-- Bit-width annotation slash + text -->
<line x1="x_mid-6" y1="y+8" x2="x_mid+6" y2="y-8" stroke="#333" stroke-width="1.5"/>
<text x="x_mid+8" y="y-6" font-size="9">8</text>3.4 Signal Labels on Wires
Wire labels are placed 5px above the midpoint of the wire segment:
<text x="x_mid" y="y_wire-6" font-size="10" text-anchor="middle"
class="lt-wire-label">SIGNAL_NAME</text>3.5 Power Symbols
<!-- VCC (power, pointing up) -->
<polygon points="x,y x-6,y+10 x+6,y+10" fill="#333"/>
<text x="x" y="y+20" font-size="9" text-anchor="middle">VCC</text>
<!-- GND (ground, pointing down) -->
<line x1="x" y1="y" x2="x" y2="y+10" stroke="#333" stroke-width="2"/>
<line x1="x-10" y1="y+10" x2="x+10" y2="y+10" stroke="#333" stroke-width="2"/>
<line x1="x-6" y1="y+14" x2="x+6" y2="y+14" stroke="#333" stroke-width="2"/>
<line x1="x-2" y1="y+18" x2="x+2" y2="y+18" stroke="#333" stroke-width="2"/>4. Layout Conventions
4.1 Signal Flow Direction
- Primary axis: left → right (inputs at the far left, outputs at the far right)
- Vertical axis: signals arranged by logic depth (inputs above/below, outputs in the middle)
- Feedback: routed above or below the main signal path, without overlapping it
4.2 Gate Placement
- Horizontal spacing: center-to-center distance between adjacent gates ≥ 120px (100px gate + 20px wire)
- Vertical spacing: center-to-center distance between adjacent gates ≥ 80px
- Depth alignment: gates at the same logic depth are aligned in the same vertical column
4.3 Layout Algorithm (DAG-based)
Logic gate diagram layout is a DAG (directed acyclic graph) topological sort problem:
- Topological sort: layer by signal dependency (depth = layer index)
- Layer assignment: each gate is assigned to its maximum depth layer (critical path)
- Vertical arrangement: gates in the same layer are arranged top to bottom, evenly spaced
- Coordinate assignment:
x = layer × 120 + name_column_width,y = position_in_layer × 80 - Wire routing: Manhattan routing, routed around gate boundaries
4.4 Label Positioning
- Gate type labels (e.g., AND, OR): centered inside the gate, 10px sans-serif
- Pin labels (D, J, K, Q): beside the pin, 9px, 5px from pin
- Wire labels: 6px above the midpoint of the wire segment, 10px, centered
5. DSL Grammar (Logic Gate Diagram)
document = header statement*
header = "logic" quoted_string? props? NEWLINE
props = "[" prop ("," prop)* "]"
prop = "style:" ("ansi" | "iec")
| "scale:" FLOAT
statement = comment | input_def | output_def | gate_def | wire_def
comment = "#" [^\n]* NEWLINE
input_def = "input" id_list NEWLINE
id_list = IDENTIFIER ("," IDENTIFIER)*
output_def = "output" id_list NEWLINE
gate_def = IDENTIFIER "=" gate_type "(" input_list ")" NEWLINE
gate_type = "and" | "or" | "not" | "nand" | "nor" | "xor" | "xnor"
| "buf" | "tri"
| "and3" | "or3" | "and4" | "or4"
| "dff" | "jkff" | "srff" | "tff"
gate_type_3 = "and3" | "or3" | "nand3" | "nor3" | "xor3"
input_list = (IDENTIFIER | neg_input) ("," (IDENTIFIER | neg_input))*
neg_input = "~" IDENTIFIER # active-low / inverted input
wire_def = IDENTIFIER "->" IDENTIFIER label_clause? NEWLINE
| IDENTIFIER "~>" IDENTIFIER label_clause? # bus connection
label_clause = "[" quoted_string "]"
IDENTIFIER = /[a-zA-Z][a-zA-Z0-9_]*/
FLOAT = /[0-9]+(\.[0-9]+)?/
INT = /[0-9]+/
quoted_string = '"' /[^"]*/ '"'
NEWLINE = /\n/DSL Example (Full Adder):
logic "1-bit Full Adder" [style: ansi]
input A, B, Cin
output Sum, Cout
# First XOR for sum intermediate
s1 = xor(A, B)
# Second XOR for final sum
Sum = xor(s1, Cin)
# AND gates for carry
c1 = and(A, B)
c2 = and(s1, Cin)
# OR for carry out
Cout = or(c1, c2)DSL Example (D Flip-Flop with enable):
logic "D FF with Enable"
input D, CLK, EN
output Q
# Gate-level enable logic
d_in = and(D, EN)
Q = dff(d_in, CLK)6. SVG Structure
<svg class="lt-logic" data-diagram-type="logic">
<defs>
<style>
.lt-gate-body { fill: white; stroke: #333; stroke-width: 2; }
.lt-gate-label { font: bold 10px sans-serif; fill: #333; }
.lt-pin-label { font: 9px sans-serif; fill: #555; }
.lt-wire { stroke: #333; stroke-width: 2; fill: none; }
.lt-bus { stroke: #333; stroke-width: 4; fill: none; }
.lt-wire-label { font: 10px sans-serif; fill: #333; }
.lt-junction { fill: #333; }
.lt-bubble { fill: white; stroke: #333; stroke-width: 1.5; }
.lt-clock-tri { fill: #333; }
</style>
<!-- Arrowhead for signal direction (optional) -->
<marker id="lt-logic-arrow" markerWidth="6" markerHeight="6"
refX="5" refY="3" orient="auto">
<polygon points="0 0, 6 3, 0 6" fill="#333"/>
</marker>
</defs>
<title>Logic Gate Diagram — [name]</title>
<desc>[description]</desc>
<!-- Gates -->
<g id="lt-gates">
<g id="gate-AND1" data-type="and" data-id="AND1" transform="translate(x, y)">
<path class="lt-gate-body" d="..."/>
<!-- pin wires -->
<line class="lt-wire" .../>
</g>
</g>
<!-- Wires -->
<g id="lt-wires">
<path class="lt-wire" d="M x1,y1 L x_bend,y1 L x_bend,y2 L x2,y2" .../>
</g>
<!-- Labels -->
<g id="lt-labels">...</g>
<!-- Junctions -->
<g id="lt-junctions">
<circle class="lt-junction" cx="x" cy="y" r="3"
data-signals="A,B" />
</g>
</svg>7. Test Cases
Case 1: Simple AND Gate
logic
input A, B
output Y
Y = and(A, B)Verify: AND gate is centered, two input wires from the left, output wire to the right, coordinates correct.
Case 2: Half Adder
logic "Half Adder"
input A, B
output S, C
S = xor(A, B)
C = and(A, B)Verify: XOR and AND are side by side, both sharing inputs A and B (with junction dots).
Case 3: Full Adder
logic "Full Adder"
input A, B, Cin
output Sum, Cout
s1 = xor(A, B)
Sum = xor(s1, Cin)
c1 = and(A, B)
c2 = and(s1, Cin)
Cout = or(c1, c2)Verify: 5 gates, signal reuse correct, s1 fans out to two gates (junction dot).
Case 4: D Flip-Flop
logic
input D, CLK
output Q
Q = dff(D, CLK)Verify: DFF rectangle box renders correctly, clock triangle at CLK pin, Q̄ has a bubble.
Case 5: IEC Style
logic [style: iec]
input A, B
output Y
Y = nand(A, B)Verify: NAND gate renders as rectangle + "&" label + output bubble (IEC style).
Case 6: Active-Low Input
logic
input A, ~B
output Y
Y = and(A, ~B)Verify: input B has a bubble at the input pin, wire enters from the left of the bubble.
8. Implementation Priority
| Priority | Feature | Complexity | User Value |
|---|---|---|---|
| P0 (MVP) | AND, OR, NOT, NAND, NOR, XOR, XNOR (ANSI style) | Medium | Core — basic digital logic |
| P0 | Manhattan wire routing + junction dots | Medium | Core |
| P0 | DAG layout (topological sort + layer assignment) | Medium | Core |
| P1 | Buffer, Tri-state buffer | Low | High |
| P1 | 3-input gate variants | Low | High |
| P1 | Active-low bubble on inputs | Low | High |
| P1 | D Flip-Flop | Medium | High — required for sequential logic |
| P2 | JK/SR/T Flip-Flops | Medium | Medium |
| P2 | IEC rectangular style | Low | Medium |
| P2 | Bus notation (thick line + slash) | Low | Medium |
| P2 | N-bit Register | Medium | Medium |
| P3 | Feedback path routing (above/below main path) | High | Medium |
| P3 | Complex IC box (MUX, DEMUX) | Medium | Low |
6. Extended Symbol Library (v2): Special Buffers, Latches & Complex Elements
The following extends the v1 standard, covering variants frequently used in real engineering digital circuits. All symbols follow IEEE Std 91-1984 ANSI style (ANSI primary; IEC equivalents given in parentheses).
6.1 Tri-State Buffer (TRISTATE_BUF)
- IEEE 91 description: Buffer with control input (EN/OE); output = Z (high-impedance) when disabled
- Pins:
A(data in),EN(enable, active-high),Y(output) - Active-low enable: add bubble at EN pin →
~EN - ANSI symbol: Buffer triangle + extra enable pin entering from the bottom
/* Buffer triangle (same as BUF) */ M 0,20 V 40 M 0,40 L 35,30 L 0,20 /* triangle body */ M -20,30 H 0 /* data input A */ M 35,30 H 55 /* output Y */ /* Enable input from below */ M 15,50 V 36 /* EN pin wire */ /* EN label at (15, 55) */ - IEC symbol: Rectangle body with "EN" label and "1" function designation
- Output Z-state indicator: renderer sets data-tristate="true", shown as a dashed output line
6.2 Tri-State Inverter (TRISTATE_INV)
- Pins:
A(data in),EN(enable),Y(inverted output) - ANSI symbol: NOT triangle + bubble at output + enable pin
/* NOT triangle body */ M 0,20 V 40 M 0,40 L 35,30 L 0,20 /* inversion bubble */ <circle cx="38" cy="30" r="4" fill="white" stroke-width="1.5"/> /* EN pin from below at body midpoint */ M 12,50 V 36
6.3 Open-Drain Buffer (OPEN_DRAIN)
- Description: Output transistor pulls to GND when active; high state requires external pull-up
- Pins:
A(input),Y(open-drain output) - ANSI symbol: Buffer triangle + special output symbol (triangle pointing toward GND)
/* Buffer triangle */ M 0,20 V 40 M 0,40 L 30,30 L 0,20 /* Open-drain indicator: downward triangle at output */ M 30,30 L 42,24 L 42,36 Z fill="none" stroke-width="1.5" /* implied: external pull-up resistor on output line */ - Note: when the
[pullup: "10k"]attr is set in DSL, the renderer additionally draws a pull-up resistor symbol
6.4 Schmitt Trigger (SCHMITT)
- IEEE 91 description: Hysteresis symbol (square-wave shape) inside buffer triangle
- Pins:
A(input),Y(output) - ANSI symbol: Buffer triangle + hysteresis square-wave symbol (small S-shape)
/* Buffer triangle */ M 0,20 V 40 M 0,40 L 35,30 L 0,20 /* Hysteresis symbol inside at (15, 30): miniature square-wave hysteresis curve */ M 10,32 H 14 V 28 H 18 V 32 H 22 /* step symbol */ /* input/output wires */ M -20,30 H 0 M 35,30 H 55 - Inverting variant: add bubble at the output
6.5 SR Latch (LATCH_SR)
- IEEE 91 description: Level-sensitive (not clocked), no clock pin. Set/Reset asynchronous.
- Distinction from SRFF: no clock triangle; responds directly to S/R levels
- Pins:
S(set),R(reset),Q,~Q - ANSI symbol: Rectangle 60×60px + S/R left, Q/~Q right, no clock
M 0,0 H 60 V 60 H 0 Z /* body */ /* Inputs on left */ M -20,15 H 0 /* S pin */ M -20,45 H 0 /* R pin */ /* Outputs on right */ M 60,15 H 80 /* Q pin */ M 60,45 H 80 /* ~Q pin */ /* bubble on ~Q output */ <circle cx="63" cy="45" r="4" fill="white" stroke-width="1.5"/> /* Pin labels: "S" (5,14), "R" (5,44), "Q" (52,14), "Q̄" (52,44) */ - IEC symbol: Same rect with "SR" inside
6.6 D Latch (LATCH_D)
- IEEE 91 description: Level-sensitive (transparent when E=1); edge-triggered version = DFF
- Pins:
D(data),EorEN(enable/gate),Q,~Q - ANSI symbol: DFF-style rectangle but without clock triangle
M 0,0 H 60 V 60 H 0 Z /* body */ /* D input (left top) */ M -20,15 H 0 /* E input (left bottom) */ M -20,45 H 0 /* NO clock triangle (key distinction from DFF — this is the D Latch) */ /* Outputs right */ M 60,15 H 80 /* Q */ M 60,45 H 80 /* ~Q + bubble */ /* Pin labels: "D", "E", "Q", "Q̄" */ - Note: when DSL writes
G3 = LATCH_D(D=A, E=CLK_EN), no clock triangle is drawn
6.7 Counter (COUNTER)
- IEEE 91 description: Binary counter, generic representation
- Pins:
CLK,RESET/CLR(inputs);Q0,Q1,Q2,Q3(outputs) - Optional pins:
EN(enable),LOAD(parallel load),D0–D3(preset data),CO(carry out) - ANSI symbol: Larger rectangle (60×80px) + "CTR" label
M 0,0 H 60 V 80 H 0 Z /* body */ /* CLK input (left, with clock triangle) */ M -20,25 H 0 <polygon points="0,20 8,25 0,30"/> /* clock triangle */ /* CLR input */ M -20,55 H 0 /* Q outputs (right): Q0 at y=15, Q1 at y=30, Q2 at y=45, Q3 at y=60 */ M 60,15 H 80 M 60,30 H 80 M 60,45 H 80 M 60,60 H 80 /* CO (carry out) at right bottom */ M 60,72 H 80 /* "CTR" label centered in body */ /* Pin labels: CLK, CLR, Q0-Q3, CO */ - attrs in DSL:
[bits: 4](default 4),[mode: up|down|updown]
6.8 Shift Register (SHIFT_REG)
- IEEE 91 description: Generic shift register, serial or parallel I/O
- Pins:
CLK,SER(serial in),SHIFT/LOAD,Q0–Q7(parallel out),SER_OUT(serial out) - ANSI symbol: Large rectangle (60×100px) + "SRG" label
M 0,0 H 60 V 100 H 0 Z /* body */ /* CLK (left, clock triangle) */ M -20,20 H 0 <polygon points="0,15 8,20 0,25"/> /* SER in */ M -20,40 H 0 /* SHIFT/LOAD control */ M -20,60 H 0 /* Q0-Q7 outputs on right (8 outputs, 10px spacing) */ /* SER_OUT at bottom-right */ /* "SRG" label in body */ /* attrs: [bits: 8], [mode: SIPO|PISO|PIPO] */
6.9 Pin Annotation: Active-Low and Edge-Triggered Notation
| Notation | Meaning | SVG Implementation |
|---|---|---|
~ID prefix in DSL | Active-low input | Bubble at pin (<circle r=4>) |
| Clock triangle | Edge-triggered (rising) | <polygon points="0,y-5 8,y 0,y+5"/> |
CLK_N or ~CLK | Falling-edge trigger | Bubble before clock triangle |
OE / EN pin | Output enable / enable | Normal pin, no special rendering |
6.10 Updated Implementation Priority (v2)
| Priority | Symbols Added | Hours |
|---|---|---|
| P0 | AND, OR, NOT, NAND, NOR, XOR, XNOR, BUF (existing) | 2h |
| P0 | DFF, JKFF, SRFF, TFF (existing) | 1h |
| P0 | MUX, DEMUX, DECODER, ENCODER (existing) | 1h |
| P1 | TRISTATE_BUF, TRISTATE_INV | 0.5h |
| P1 | OPEN_DRAIN, SCHMITT | 0.5h |
| P1 | LATCH_SR, LATCH_D | 0.5h |
| P2 | COUNTER (CTR, 4-bit) | 0.75h |
| P2 | SHIFT_REG (SRG, 8-bit) | 0.75h |
Total logic gate symbols (v2): 24 (P0: 16, P1: 6, P2: 2)
Timing diagram
Digital waveforms with clock pulses, bus segments, high-impedance states, group labels. WaveDrom-compatible signal language. For hardware design, protocol specification, and digital systems teaching.
Circuit schematic
Analog and digital circuit schematics from SPICE-style netlist or positional DSL. Auto-routed power/ground rails, orthogonal signal wiring, IEEE standard component symbols.