Skip to content

Digital Logic Examples

Design digital circuits with Verilog HDL export for synthesis and simulation.

Coming soon

Rendered SVG visuals for the Digital profile are coming soon. The DSL snippets below are accurate, and parser support for digital { ... } modules is in progress. Once available, this page will include side-by-side rendered diagrams.

Half Adder

Basic combinational circuit that adds two single bits.

DSL Code

runiq
digital "Half Adder" {
  # Inputs
  input A, B

  # Outputs
  output SUM, CARRY

  # Logic gates
  gate U1 type:XOR inputs:(A,B) output:SUM
  gate U2 type:AND inputs:(A,B) output:CARRY
}

Truth Table

ABSUMCARRY
0000
0110
1010
1101

Logic Equations

$$\text{SUM} = A \oplus B$$ $$\text{CARRY} = A \cdot B$$

Exported Verilog

verilog
// Half Adder
// Generated by Runiq

module half_adder(
  input wire A,
  input wire B,
  output wire SUM,
  output wire CARRY
);

  xor U1(SUM, A, B);
  and U2(CARRY, A, B);

endmodule

Full Adder

Adds three bits (two inputs plus carry-in).

DSL Code

runiq
digital "Full Adder" {
  # Inputs
  input A, B, CIN

  # Outputs
  output SUM, COUT

  # Internal nets
  wire SUM1, CARRY1, CARRY2

  # First half adder
  gate U1 type:XOR inputs:(A,B) output:SUM1
  gate U2 type:AND inputs:(A,B) output:CARRY1

  # Second half adder
  gate U3 type:XOR inputs:(SUM1,CIN) output:SUM
  gate U4 type:AND inputs:(SUM1,CIN) output:CARRY2

  # Carry out
  gate U5 type:OR inputs:(CARRY1,CARRY2) output:COUT
}

Truth Table

ABCINSUMCOUT
00000
00110
01010
01101
10010
10101
11001
11111

Logic Equations

$$\text{SUM} = A \oplus B \oplus C_{IN}$$ $$C_{OUT} = AB + (A \oplus B)C_{IN}$$

2-to-1 Multiplexer

Selects one of two inputs based on a select signal.

DSL Code

runiq
digital "2-to-1 Multiplexer" {
  # Inputs
  input D0, D1, SEL

  # Output
  output Y

  # Internal nets
  wire SEL_N, T0, T1

  # Invert select
  gate U1 type:NOT inputs:(SEL) output:SEL_N

  # AND gates for selection
  gate U2 type:AND inputs:(D0,SEL_N) output:T0
  gate U3 type:AND inputs:(D1,SEL) output:T1

  # OR gate for output
  gate U4 type:OR inputs:(T0,T1) output:Y
}

Truth Table

SELD0D1Y
00X0
01X1
1X00
1X11

Logic Equation

$$Y = \overline{\text{SEL}} \cdot D_0 + \text{SEL} \cdot D_1$$

CMOS Inverter

Complementary MOSFET inverter - the basic building block of digital logic.

DSL Code

runiq
electrical "CMOS Inverter" {
  net VDD, IN, OUT, GND

  # Power supply: 5V
  part VDD type:V source:"DC 5" pins:(VDD,GND)

  # Input signal: pulse from 0 to 5V
  part VIN type:V source:"PULSE(0 5 0 1n 1n 10n 20n)" pins:(IN,GND)

  # PMOS pull-up (on when input is low)
  part MP type:M model:"PMOS" pins:(VDD,IN,OUT)

  # NMOS pull-down (on when input is high)
  part MN type:M model:"NMOS" pins:(OUT,IN,GND)

  # Output load capacitance
  part CL type:C value:"1p" pins:(OUT,GND)

  # Transient analysis
  analysis tran "0 100n"
}

Generated SVG

CMOS Inverter

Operation

Input (VIN)PMOSNMOSOutput (VOUT)
LOW (0V)ONOFFHIGH (VDD)
HIGH (VDD)OFFONLOW (0V)

Power Consumption: Only during switching (dynamic power)

Use Cases:

  • NOT gate implementation
  • Buffer circuits
  • Basic logic building block
  • Low-power digital design

D Flip-Flop

Basic sequential element with clock.

DSL Code

runiq
digital "D Flip-Flop" {
  # Inputs
  input D, CLK, RST

  # Outputs
  output Q, Q_N

  # Master-slave structure
  wire M_Q, M_Q_N, S_D

  # Master latch (active on clock high)
  gate U1 type:DFF inputs:(D,CLK,RST) output:M_Q
  gate U2 type:NOT inputs:(M_Q) output:M_Q_N

  # Slave latch (active on clock low)
  gate U3 type:DFF inputs:(M_Q,CLK,RST) output:Q
  gate U4 type:NOT inputs:(Q) output:Q_N
}

Operation

  • D: Data input
  • CLK: Clock signal (rising edge triggered)
  • RST: Asynchronous reset (active high)
  • Q: Output follows D on clock rising edge
  • Q_N: Inverted output

Timing Diagram

CLK: ___/‾\___/‾\___/‾\___
D:   ___/‾‾‾\___/‾‾‾‾‾‾‾
Q:   _______/‾‾‾\___/‾‾‾

4-Bit Counter

Sequential circuit that counts from 0 to 15.

DSL Code

runiq
digital "4-Bit Counter" {
  # Inputs
  input CLK, RST, EN

  # Outputs (4-bit count)
  output Q0, Q1, Q2, Q3

  # Internal carry signals
  wire C0, C1, C2

  # Bit 0 (LSB) - toggles every clock
  gate FF0 type:TFF inputs:(EN,CLK,RST) output:Q0
  gate A0 type:AND inputs:(Q0,EN) output:C0

  # Bit 1 - toggles when Q0=1
  gate FF1 type:TFF inputs:(C0,CLK,RST) output:Q1
  gate A1 type:AND inputs:(Q1,C0) output:C1

  # Bit 2 - toggles when Q1=Q0=1
  gate FF2 type:TFF inputs:(C1,CLK,RST) output:Q2
  gate A2 type:AND inputs:(Q2,C1) output:C2

  # Bit 3 (MSB) - toggles when Q2=Q1=Q0=1
  gate FF3 type:TFF inputs:(C2,CLK,RST) output:Q3
}

Count Sequence

CLKQ3Q2Q1Q0Decimal
000000
100011
200102
300113
..................
15111115
1600000 (wrap)

Supported Gate Types

Runiq supports standard digital logic gates:

Basic Gates

GateTypeInputsFunction
NOTNOT1$Y = \overline{A}$
ANDAND2+$Y = A \cdot B$
OROR2+$Y = A + B$
NANDNAND2+$Y = \overline{A \cdot B}$
NORNOR2+$Y = \overline{A + B}$
XORXOR2$Y = A \oplus B$
XNORXNOR2$Y = \overline{A \oplus B}$

Sequential Elements

ElementTypeDescription
D Flip-FlopDFFData flip-flop (edge-triggered)
T Flip-FlopTFFToggle flip-flop
JK Flip-FlopJKFFJK flip-flop (most versatile)
SR LatchSRSet-reset latch (level-sensitive)

Syntax

runiq
# Combinational gate
gate <ID> type:<TYPE> inputs:(<in1>,<in2>,...) output:<out>

# Sequential element
gate <ID> type:<TYPE> inputs:(<D>,<CLK>,<RST>) output:<Q>

# Multi-output
gate <ID> type:<TYPE> inputs:(...) outputs:(<Q>,<Q_N>)

Complete Examples

4-Bit ALU (Arithmetic Logic Unit)

runiq
digital "4-Bit ALU" {
  # Inputs (4-bit operands)
  input A[3:0], B[3:0]
  input OP[1:0]  # Operation select

  # Outputs
  output Y[3:0]  # Result
  output ZERO    # Zero flag
  output CARRY   # Carry out

  # Internal signals
  wire ADD_Y[3:0], SUB_Y[3:0], AND_Y[3:0], OR_Y[3:0]
  wire C[3:0]    # Carry chain

  # Adder
  gate ADD0 type:FULL_ADD inputs:(A[0],B[0],0) outputs:(ADD_Y[0],C[0])
  gate ADD1 type:FULL_ADD inputs:(A[1],B[1],C[0]) outputs:(ADD_Y[1],C[1])
  gate ADD2 type:FULL_ADD inputs:(A[2],B[2],C[1]) outputs:(ADD_Y[2],C[2])
  gate ADD3 type:FULL_ADD inputs:(A[3],B[3],C[2]) outputs:(ADD_Y[3],CARRY)

  # Bitwise AND
  gate AND0 type:AND inputs:(A[0],B[0]) output:AND_Y[0]
  gate AND1 type:AND inputs:(A[1],B[1]) output:AND_Y[1]
  gate AND2 type:AND inputs:(A[2],B[2]) output:AND_Y[2]
  gate AND3 type:AND inputs:(A[3],B[3]) output:AND_Y[3]

  # Bitwise OR
  gate OR0 type:OR inputs:(A[0],B[0]) output:OR_Y[0]
  gate OR1 type:OR inputs:(A[1],B[1]) output:OR_Y[1]
  gate OR2 type:OR inputs:(A[2],B[2]) output:OR_Y[2]
  gate OR3 type:OR inputs:(A[3],B[3]) output:OR_Y[3]

  # Multiplexer for operation select
  mux MUX type:MUX4 select:OP[1:0] inputs:(ADD_Y,SUB_Y,AND_Y,OR_Y) output:Y[3:0]

  # Zero detection
  gate ZERO_DET type:NOR inputs:(Y[0],Y[1],Y[2],Y[3]) output:ZERO
}

8-Bit Shift Register

runiq
digital "8-Bit Shift Register" {
  # Inputs
  input DATA_IN, CLK, RST
  input SHIFT_EN

  # Outputs (parallel)
  output Q[7:0]
  output SERIAL_OUT

  # Flip-flop chain
  gate FF0 type:DFF inputs:(DATA_IN,CLK,RST) output:Q[0]
  gate FF1 type:DFF inputs:(Q[0],CLK,RST) output:Q[1]
  gate FF2 type:DFF inputs:(Q[1],CLK,RST) output:Q[2]
  gate FF3 type:DFF inputs:(Q[2],CLK,RST) output:Q[3]
  gate FF4 type:DFF inputs:(Q[3],CLK,RST) output:Q[4]
  gate FF5 type:DFF inputs:(Q[4],CLK,RST) output:Q[5]
  gate FF6 type:DFF inputs:(Q[5],CLK,RST) output:Q[6]
  gate FF7 type:DFF inputs:(Q[6],CLK,RST) output:Q[7]

  # Serial output is MSB
  assign SERIAL_OUT = Q[7]
}

Best Practices

Gate Naming

  • Use descriptive IDs: U_AND_GATE, FF_DATA, MUX_SELECT
  • Number related gates: ADD0, ADD1, ADD2, etc.
  • Indicate function: INV_CLK, OR_OUT, DFF_Q0

Bus Notation

Use bit vectors for multi-bit signals:

runiq
input DATA[7:0]    # 8-bit input
output ADDR[15:0]  # 16-bit output
wire TEMP[3:0]     # 4-bit internal signal

Clock and Reset

  • Always include CLK for sequential circuits
  • Add RST (reset) for initialization
  • Use consistent names: CLK, RST, EN (enable)

Export to Verilog

Generate Verilog HDL for:

  • Simulation: ModelSim, Icarus Verilog, Verilator
  • Synthesis: Vivado (Xilinx), Quartus (Intel), Yosys
  • FPGA Programming: Deploy to real hardware
bash
# Generate Verilog
runiq half-adder.runiq --export verilog -o half_adder.v

# Simulate with Icarus Verilog
iverilog -o half_adder half_adder.v half_adder_tb.v
vvp half_adder

Verification

Always verify your designs with:

  1. Truth tables - Enumerate all input combinations
  2. Timing diagrams - Check sequential behavior
  3. Testbenches - Write Verilog testbenches
  4. Simulation - Run with HDL simulator
  5. Synthesis - Check for optimization opportunities

Next Steps


Download Examples

All example .runiq files are available in the GitHub repository.

bash
git clone https://github.com/jgreywolf/runiq.git
cd runiq/examples/digital

Released under the MIT License.