2:1 multiplexer. The fundamental building block for data selection, routing one of two inputs to the output based on a select signal.
d0 d1
│ │
│ │ s (select)
│ │ │
├───────┼───────┤
│ │ │
▼ │ │
┌───────┐ │ │
│ sel0 │◄──┼───────┤
│d0∧¬s │ │ │
└───────┘ │ │
│ ▼ │
│ ┌───────┐ │
│ │ sel1 │◄──┘
│ │ d1∧s │
│ └───────┘
│ │
└───┬───┘
▼
┌───────┐
│ OR │
└───────┘
│
▼
output
The circuit uses two AND-with-complement gates that fire only when their respective data input is selected:
Simple OR gate combines the two selection paths.
MUX4 = MUX2(MUX2(d0,d1,s0), MUX2(d2,d3,s0), s1)
MUX8 = MUX2(MUX4(d0-d3), MUX4(d4-d7), s2)
MUX16 = MUX2(MUX8(d0-d7), MUX8(d8-d15), s3)
Each doubling adds one layer of MUX2 gates.
1from safetensors.torch import load_file
2import torch
3
4w = load_file('model.safetensors')
5
6def mux2(d0, d1, s):
7 inp = torch.tensor([float(d0), float(d1), float(s)])
8
9 # Layer 1: Selection
10 sel0 = int((inp @ w['sel0.weight'].T + w['sel0.bias'] >= 0).item())
11 sel1 = int((inp @ w['sel1.weight'].T + w['sel1.bias'] >= 0).item())
12
13 # Layer 2: Combine
14 l1 = torch.tensor([float(sel0), float(sel1)])
15 return int((l1 @ w['or.weight'].T + w['or.bias'] >= 0).item())
16
17# Examples
18print(mux2(1, 0, 0)) # 1 (selects d0)
19print(mux2(1, 0, 1)) # 0 (selects d1)
20print(mux2(0, 1, 1)) # 1 (selects d1)
threshold-mux2/
├── model.safetensors
├── model.py
├── create_safetensors.py
├── config.json
└── README.md