| | ---
|
| | license: mit
|
| | tags:
|
| | - pytorch
|
| | - safetensors
|
| | - threshold-logic
|
| | - neuromorphic
|
| | - multiplexer
|
| | ---
|
| |
|
| | # threshold-mux2
|
| |
|
| | 2:1 multiplexer. The fundamental building block for data selection, routing one of two inputs to the output based on a select signal.
|
| |
|
| | ## Circuit
|
| |
|
| | ```
|
| | d0 d1
|
| | β β
|
| | β β s (select)
|
| | β β β
|
| | βββββββββΌββββββββ€
|
| | β β β
|
| | βΌ β β
|
| | βββββββββ β β
|
| | β sel0 βββββΌββββββββ€
|
| | βd0β§Β¬s β β β
|
| | βββββββββ β β
|
| | β βΌ β
|
| | β βββββββββ β
|
| | β β sel1 βββββ
|
| | β β d1β§s β
|
| | β βββββββββ
|
| | β β
|
| | βββββ¬ββββ
|
| | βΌ
|
| | βββββββββ
|
| | β OR β
|
| | βββββββββ
|
| | β
|
| | βΌ
|
| | output
|
| | ```
|
| |
|
| | ## Truth Table
|
| |
|
| | | s | d0 | d1 | out | Description |
|
| | |---|----|----|-----|-------------|
|
| | | 0 | 0 | 0 | 0 | Select d0 (0) |
|
| | | 0 | 0 | 1 | 0 | Select d0 (0) |
|
| | | 0 | 1 | 0 | 1 | Select d0 (1) |
|
| | | 0 | 1 | 1 | 1 | Select d0 (1) |
|
| | | 1 | 0 | 0 | 0 | Select d1 (0) |
|
| | | 1 | 0 | 1 | 1 | Select d1 (1) |
|
| | | 1 | 1 | 0 | 0 | Select d1 (0) |
|
| | | 1 | 1 | 1 | 1 | Select d1 (1) |
|
| |
|
| | Formula: `out = (d0 AND NOT s) OR (d1 AND s)`
|
| |
|
| | ## Mechanism
|
| |
|
| | **Layer 1 - Selection Gates:**
|
| |
|
| | The circuit uses two AND-with-complement gates that fire only when their respective data input is selected:
|
| |
|
| | | Gate | Weights [d0, d1, s] | Bias | Function |
|
| | |------|---------------------|------|----------|
|
| | | sel0 | [1, 0, -1] | -1 | d0 AND NOT(s) |
|
| | | sel1 | [0, 1, 1] | -2 | d1 AND s |
|
| |
|
| | **sel0** fires when d0=1 AND s=0:
|
| | - The negative weight on s means s=1 inhibits firing
|
| | - Bias -1 requires d0=1 to reach threshold when s=0
|
| |
|
| | **sel1** fires when d1=1 AND s=1:
|
| | - Both d1 and s must be 1 to overcome bias -2
|
| |
|
| | **Layer 2 - Output:**
|
| |
|
| | Simple OR gate combines the two selection paths.
|
| |
|
| | ## Architecture
|
| |
|
| | | Component | Weights | Bias | Function |
|
| | |-----------|---------|------|----------|
|
| | | sel0 | [1, 0, -1] | -1 | d0 AND NOT(s) |
|
| | | sel1 | [0, 1, 1] | -2 | d1 AND s |
|
| | | or | [1, 1] | -1 | OR(sel0, sel1) |
|
| |
|
| | ## Parameters
|
| |
|
| | | | |
|
| | |---|---|
|
| | | Inputs | 3 (d0, d1, s) |
|
| | | Outputs | 1 |
|
| | | Neurons | 3 |
|
| | | Layers | 2 |
|
| | | Parameters | 11 |
|
| | | Magnitude | 10 |
|
| |
|
| | ## Building Larger Multiplexers
|
| |
|
| | The MUX2 is the primitive for constructing larger multiplexers:
|
| |
|
| | ```
|
| | 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.
|
| |
|
| | ## Usage
|
| |
|
| | ```python
|
| | from safetensors.torch import load_file
|
| | import torch
|
| |
|
| | w = load_file('model.safetensors')
|
| |
|
| | def mux2(d0, d1, s):
|
| | inp = torch.tensor([float(d0), float(d1), float(s)])
|
| |
|
| | # Layer 1: Selection
|
| | sel0 = int((inp @ w['sel0.weight'].T + w['sel0.bias'] >= 0).item())
|
| | sel1 = int((inp @ w['sel1.weight'].T + w['sel1.bias'] >= 0).item())
|
| |
|
| | # Layer 2: Combine
|
| | l1 = torch.tensor([float(sel0), float(sel1)])
|
| | return int((l1 @ w['or.weight'].T + w['or.bias'] >= 0).item())
|
| |
|
| | # Examples
|
| | print(mux2(1, 0, 0)) # 1 (selects d0)
|
| | print(mux2(1, 0, 1)) # 0 (selects d1)
|
| | print(mux2(0, 1, 1)) # 1 (selects d1)
|
| | ```
|
| |
|
| | ## Applications
|
| |
|
| | - Data routing in ALUs
|
| | - Register file read ports
|
| | - Conditional assignment in hardware
|
| | - Building blocks for barrel shifters
|
| | - Crossbar switches
|
| |
|
| | ## Files
|
| |
|
| | ```
|
| | threshold-mux2/
|
| | βββ model.safetensors
|
| | βββ model.py
|
| | βββ create_safetensors.py
|
| | βββ config.json
|
| | βββ README.md
|
| | ```
|
| |
|
| | ## License
|
| |
|
| | MIT
|
| |
|