|
Download tapeout/docs/info.md from Snapkitty/bit-string-accelerator: direct link, hf CLI and curl.
- Browser
- Download file 3.03 kB
-
https://huggingface.co/Snapkitty/bit-string-accelerator/resolve/main/tapeout/docs/info.md
- Command line
-
hf download hf://Snapkitty/bit-string-accelerator/tapeout/docs/info.md
-
curl -L -o info.md https://huggingface.co/Snapkitty/bit-string-accelerator/resolve/main/tapeout/docs/info.md
3.03 kB
| ## How it works | |
| A small hardware accelerator for single-bit operations on 64-bit words. It | |
| computes the bit's address and performs a read-modify-write when needed. | |
| effective bit = (base * 8) + offset (64-bit arithmetic) | |
| word = effective bit / 64 | |
| bit index = effective bit mod 64 | |
| | Opcode | Operation | Writes | Result bit | | |
| |---|---|---|---| | |
| | 0 | GET | no | the bit | | |
| | 1 | TEST | no | the bit | | |
| | 2 | SET | yes | 1 | | |
| | 3 | CLEAR | yes | 0 | | |
| | 4 | TOGGLE | yes | the new bit | | |
| | 5-7 | undefined | no | error | | |
| The chip holds 4 words of RAM (byte addresses 0-31). An address outside that | |
| range ends the operation with an error and never writes. | |
| Everything is driven over a UART (8 data bits, no parity, 1 stop bit). All | |
| multi-byte fields are little-endian: | |
| | Host sends | Chip replies | | | |
| |---|---|---| | |
| | `P` | `B` | ping | | |
| | `W` idx data[8] | `K` | write word idx (0-3) | | |
| | `R` idx | data[8] | read word idx | | |
| | `X` op base[8] offset[8] | `0xA0` + 2·error + bit | run one operation | | |
| | anything else | `?` | | | |
| The design is the `bit_accelerator` core from | |
| https://github.com/SNAPKITTYAGENT9NOVA/bit-string-accelerator. Before | |
| hardening it was checked as follows: | |
| - a self-checking testbench, with random backpressure, read latency and fault injection | |
| - Why3 proofs of the address arithmetic | |
| - the same RTL running on iCE40 and ECP5 FPGAs | |
| - a formal equivalence proof of its sky130 netlist | |
| ## How to test | |
| 1. Set the clock, and set the UART divisor pins to match it. The chip uses | |
| `4 × d` clocks per bit, where `d = {ui[7:4], ui[2:0]}`. With all divisor | |
| pins low it uses 104 clocks per bit, which is 115200 baud at a 12 MHz clock. | |
| Other examples: | |
| | Clock | Baud | d | ui[7:4] | ui[2:0] | | |
| |---|---|---|---|---| | |
| | 12 MHz | 115200 | 0 (default) | 0000 | 000 | | |
| | 25 MHz | 115200 | 54 (216 clocks) | 0110 | 110 | | |
| | 50 MHz | 115200 | 108 (432 clocks) | 1101 | 100 | | |
| 2. Connect a 3.3 V USB-UART adapter: adapter TX to `ui[3]` (RX), adapter RX to | |
| `uo[4]` (TX). | |
| 3. Reset the design. `uo[0]` is high while an operation runs. `uo[1]` is the | |
| last operation's error flag. `uo[2]` is its result bit. | |
| 4. Use the host tool from the repository (`fpga/host`, Rust): | |
| bitacc --port /dev/ttyUSB0 --words 4 ping # pong | |
| bitacc --port /dev/ttyUSB0 --words 4 write 0 0x8000000000000001 | |
| bitacc --port /dev/ttyUSB0 --words 4 exec get 0 63 # 1 | |
| bitacc --port /dev/ttyUSB0 --words 4 exec toggle 0 5 # 1 | |
| bitacc --port /dev/ttyUSB0 --words 4 read 0 # 0x8000000000000021 | |
| bitacc --port /dev/ttyUSB0 --words 4 exec get 32 0 # error (outside RAM) | |
| bitacc --port /dev/ttyUSB0 --words 4 selftest 10000 # 0 mismatches | |
| `selftest` runs random operations, including faults and undefined opcodes, | |
| and checks every reply and the final RAM contents against a model of the | |
| design. | |
| ## External hardware | |
| A 3.3 V USB-UART adapter (for example an FTDI or CP2102 cable) on `ui[3]`/`uo[4]`. | |