phanerozoic commited on
Commit
45d0364
Β·
verified Β·
1 Parent(s): 8446da6

Upload folder using huggingface_hub

Browse files
Files changed (4) hide show
  1. README.md +122 -0
  2. config.json +9 -0
  3. model.py +47 -0
  4. model.safetensors +3 -0
README.md ADDED
@@ -0,0 +1,122 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ license: mit
3
+ tags:
4
+ - pytorch
5
+ - safetensors
6
+ - threshold-logic
7
+ - neuromorphic
8
+ - arithmetic
9
+ ---
10
+
11
+ # threshold-ripplecarry8bit
12
+
13
+ Adds two 8-bit numbers with carry-in. Eight cascaded full adders in ripple-carry architecture.
14
+
15
+ ## Circuit
16
+
17
+ ```
18
+ a0 b0 a1 b1 a2 b2 a3 b3 a4 b4 a5 b5 a6 b6 a7 b7
19
+ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚
20
+ β””β”¬β”˜ β””β”¬β”˜ β””β”¬β”˜ β””β”¬β”˜ β””β”¬β”˜ β””β”¬β”˜ β””β”¬β”˜ β””β”¬β”˜
21
+ β–Ό β–Ό β–Ό β–Ό β–Ό β–Ό β–Ό β–Ό
22
+ β”Œβ”€β”€β”€β”€β” c0 β”Œβ”€β”€β”€β”€β” c1 β”Œβ”€β”€β”€β”€β” c2 β”Œβ”€β”€β”€β”€β” c3 β”Œβ”€β”€β”€β”€β” c4 β”Œβ”€β”€β”€β”€β” c5 β”Œβ”€β”€β”€β”€β” c6 β”Œβ”€β”€β”€β”€β”
23
+ β”‚FA0 │────│FA1 │────│FA2 │────│FA3 │────│FA4 │────│FA5 │────│FA6 │────│FA7 │──cout
24
+ β””β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”˜
25
+ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚
26
+ β–Ό β–Ό β–Ό β–Ό β–Ό β–Ό β–Ό β–Ό
27
+ s0 s1 s2 s3 s4 s5 s6 s7
28
+
29
+ cinβ”€β”˜
30
+
31
+
32
+ Input: (a7..a0) + (b7..b0) + cin
33
+ Output: (cout s7..s0)
34
+ ```
35
+
36
+ ## Example
37
+
38
+ ```
39
+ 11111111 (255)
40
+ + 00000001 ( 1)
41
+ ──────────
42
+ 100000000 (256)
43
+ ```
44
+
45
+ 255 + 1 = 256. The sum bits are all 0, cout = 1.
46
+
47
+ ## Architecture
48
+
49
+ | Component | Per FA | Total (8 FAs) |
50
+ |-----------|--------|---------------|
51
+ | Neurons | 9 | 72 |
52
+ | Parameters | 27 | 216 |
53
+ | Layers | 4 | 32 |
54
+
55
+ ## Inputs/Outputs
56
+
57
+ | Name | Bits | Description |
58
+ |------|------|-------------|
59
+ | a | a7..a0 | First 8-bit number (LSB = a0) |
60
+ | b | b7..b0 | Second 8-bit number (LSB = b0) |
61
+ | cin | 1 | Carry in |
62
+ | s | s7..s0 | 8-bit sum (LSB = s0) |
63
+ | cout | 1 | Carry out |
64
+
65
+ ## Critical Path
66
+
67
+ Worst-case: carry propagates through all 8 full adders.
68
+
69
+ ```
70
+ cin β†’ FA0 β†’ FA1 β†’ FA2 β†’ FA3 β†’ FA4 β†’ FA5 β†’ FA6 β†’ FA7 β†’ cout
71
+ ```
72
+
73
+ This is 8 Γ— 4 = 32 layers deep. For a byte-wide ALU, this latency is acceptable. For wider words, carry-lookahead or prefix adders would be preferred.
74
+
75
+ ## Range
76
+
77
+ - Input: 0-255 + 0-255 + 0-1 = 0-511
78
+ - Output: 9 bits (8-bit sum + 1-bit carry)
79
+
80
+ ## Usage
81
+
82
+ ```python
83
+ from safetensors.torch import load_file
84
+
85
+ w = load_file('model.safetensors')
86
+
87
+ def ripple_carry_8bit(a, b, cin):
88
+ """a, b: 8-bit lists [a0..a7] (LSB first)"""
89
+ # See model.py for full implementation
90
+ pass
91
+
92
+ # Example: 200 + 100 = 300 (overflow to 9 bits)
93
+ a = [(200 >> i) & 1 for i in range(8)] # 200 in LSB-first
94
+ b = [(100 >> i) & 1 for i in range(8)] # 100 in LSB-first
95
+ sums, cout = ripple_carry_8bit(a, b, 0)
96
+ result = sum(bit << i for i, bit in enumerate(sums)) + (cout << 8)
97
+ # result = 300
98
+ ```
99
+
100
+ ## Scaling
101
+
102
+ | Bits | Full Adders | Neurons | Parameters | Max Depth |
103
+ |------|-------------|---------|------------|-----------|
104
+ | 2 | 2 | 18 | 54 | 8 |
105
+ | 4 | 4 | 36 | 108 | 16 |
106
+ | 8 | 8 | 72 | 216 | 32 |
107
+ | 16 | 16 | 144 | 432 | 64 |
108
+ | n | n | 9n | 27n | 4n |
109
+
110
+ ## Files
111
+
112
+ ```
113
+ threshold-ripplecarry8bit/
114
+ β”œβ”€β”€ model.safetensors
115
+ β”œβ”€β”€ model.py
116
+ β”œβ”€β”€ config.json
117
+ └── README.md
118
+ ```
119
+
120
+ ## License
121
+
122
+ MIT
config.json ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "threshold-ripplecarry8bit",
3
+ "description": "8-bit ripple carry adder as threshold circuit",
4
+ "inputs": 17,
5
+ "outputs": 9,
6
+ "neurons": 72,
7
+ "layers": 32,
8
+ "parameters": 216
9
+ }
model.py ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ from safetensors.torch import load_file
3
+
4
+ def load_model(path='model.safetensors'):
5
+ return load_file(path)
6
+
7
+ def full_adder(a, b, cin, w, prefix):
8
+ """Single full adder: a + b + cin = (sum, cout)"""
9
+ inp = torch.tensor([float(a), float(b)])
10
+ or_out = (inp * w[f'{prefix}.ha1.sum.layer1.or.weight']).sum() + w[f'{prefix}.ha1.sum.layer1.or.bias'] >= 0
11
+ nand_out = (inp * w[f'{prefix}.ha1.sum.layer1.nand.weight']).sum() + w[f'{prefix}.ha1.sum.layer1.nand.bias'] >= 0
12
+ l1 = torch.tensor([float(or_out), float(nand_out)])
13
+ s1 = float((l1 * w[f'{prefix}.ha1.sum.layer2.weight']).sum() + w[f'{prefix}.ha1.sum.layer2.bias'] >= 0)
14
+ c1 = float((inp * w[f'{prefix}.ha1.carry.weight']).sum() + w[f'{prefix}.ha1.carry.bias'] >= 0)
15
+ inp2 = torch.tensor([s1, float(cin)])
16
+ or_out2 = (inp2 * w[f'{prefix}.ha2.sum.layer1.or.weight']).sum() + w[f'{prefix}.ha2.sum.layer1.or.bias'] >= 0
17
+ nand_out2 = (inp2 * w[f'{prefix}.ha2.sum.layer1.nand.weight']).sum() + w[f'{prefix}.ha2.sum.layer1.nand.bias'] >= 0
18
+ l2 = torch.tensor([float(or_out2), float(nand_out2)])
19
+ s = int((l2 * w[f'{prefix}.ha2.sum.layer2.weight']).sum() + w[f'{prefix}.ha2.sum.layer2.bias'] >= 0)
20
+ c2 = float((inp2 * w[f'{prefix}.ha2.carry.weight']).sum() + w[f'{prefix}.ha2.carry.bias'] >= 0)
21
+ cout = int((torch.tensor([c1, c2]) * w[f'{prefix}.carry_or.weight']).sum() + w[f'{prefix}.carry_or.bias'] >= 0)
22
+ return s, cout
23
+
24
+ def ripple_carry_8bit(a, b, cin, weights):
25
+ """8-bit ripple carry adder.
26
+ a, b: lists of 8 bits each (LSB first)
27
+ cin: carry in
28
+ Returns: (sums, cout) where sums is 8-bit list (LSB first)
29
+ """
30
+ carries = [cin]
31
+ sums = []
32
+ for i in range(8):
33
+ s, c = full_adder(a[i], b[i], carries[i], weights, f'fa{i}')
34
+ sums.append(s)
35
+ carries.append(c)
36
+ return sums, carries[8]
37
+
38
+ if __name__ == '__main__':
39
+ w = load_model()
40
+ print('8-bit Ripple Carry Adder')
41
+ tests = [(255, 1), (127, 128), (100, 55), (200, 200), (0, 0), (128, 128)]
42
+ for a_val, b_val in tests:
43
+ a = [(a_val >> i) & 1 for i in range(8)]
44
+ b = [(b_val >> i) & 1 for i in range(8)]
45
+ sums, cout = ripple_carry_8bit(a, b, 0, w)
46
+ result = sum(bit << i for i, bit in enumerate(sums)) + (cout << 8)
47
+ print(f'{a_val:3d} + {b_val:3d} = {result:3d}')
model.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:9718a7fb5f374d85d929a7f01aa7d695a61c0dce6d09a0350d2d047562227230
3
+ size 12360