Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/xtrinch/fpga-bitcoin-miner

FPGA bitcoin miner for the Lattice ECP5 evaluation board.
https://github.com/xtrinch/fpga-bitcoin-miner

bitcoin bitcoin-mining ecp5 fpga

Last synced: 20 days ago
JSON representation

FPGA bitcoin miner for the Lattice ECP5 evaluation board.

Awesome Lists containing this project

README

        

# fpga bitcoin miner

Adaptation of the https://github.com/progranism/Open-Source-FPGA-Bitcoin-Miner for the Lattice ECP5 evaluation board (LFE5UM5G-85F-8BG381). It has been tested on the actual board with the `pc-comm` script found in the `helpers directory`. Tests are provided for most of the modules.

There's a great video on youtube explaining how sha256 works and it can serve as a great reference to this implementation: https://www.youtube.com/watch?v=f9EbD6iY9zI

The implementation pipelines the 64 stages of sha256 calculation. If the calculations are fully unrolled, you will get one hash per clock cycle (ofcourse, you will get the first hash after 64 clock cycles, and one per cycle after that). Since bitcoin uses double sha256 hashing, this is done twice. The first part of the bitcoin header is pre-hashed and sent to the FPGA via the MSG_PUSH_JOB command. FPGA modifies the nonce and calculates the hash of the second part. The resulting hash is then hashed again. If the target is reached, we've successfully mined the block.

## Usage

Test with `make test-top`, `make test-uart`, `make test-miner`. Tests for the top module and the miner module will mine the genesis block.

Build with `make`.

Flash the ECP5evn with `make program`.

Compile C code in `helpers` directory with `gcc pc-comm.c -o pc-comm` and run with `./pc-comm` to observe serial packets.

Send packets to FPGA with bash command:
- Get info: `echo -en '\x08\x00\x00\x00\xf9\xea\x98\x0a' > /dev/ttyUSB2`
- Ping: `echo -en '\x00' > /dev/ttyUSB2`
- Send genesis block mine: `echo -en '\x3C\x00\x00\x02\xFF\xFF\xFF\xFF\x7B\x2B\xAC\x1D\x4A\x5E\x1E\x4B\x49\x5F\xAB\x29\x1d\x00\xFF\xFF\x33\x9A\x90\xBC\xF0\xBF\x58\x63\x7D\xAC\xCC\x90\xA8\xCA\x59\x1E\xE9\xD8\xC8\xC3\xC8\x03\x01\x4F\x36\x87\xB1\x96\x1B\xF9\x19\x47\x77\x15\x4f\x81' > /dev/ttyUSB2`

Both should return either pong or the info you can find harcoded in the `uart_comm` file:
- Pong: `0x01`
- Get info response: `0x10 00 00 00 de ad be ef 13 37 0d 13 00 00 00 00`
- Genesis block send response: `0x01` - acknowledge, `08 00 00 03 1d ac 2b 7c` nonce

## Manual yosys inspection
- `read -vlog2k src/*.v`
- `proc;`

## Todos

- Block headers are currently byte reversed in blocks of 4 bytes for the miner to work correctly. I suspect this is due to the pool's way of calculating midstate. We should be able to circumvent this when calculating our own midstate hashes with minor modifications of the mining code.
- Difficulty should not be hardcoded. It is also incorrect to check for the leading number of zeroes in a hash, when the blocks are byte reversed in blocks of 4 bytes.
- Write the miner "brain" for ESP32/PC

## Utilization on ECP5evn

You can modify how unrolled the SHA calculations are with parameter `LOOP_LOG2` [0, 5]. The larger the value, the smaller and slower the program.

```
LOOP_LOG2=3
Info: Logic utilisation before packing:
Info: Total LUT4s: 32001/83640 38%
Info: logic LUTs: 29309/83640 35%
Info: carry LUTs: 2692/83640 3%
Info: RAM LUTs: 0/41820 0%
Info: RAMW LUTs: 0/20910 0%

Info: Total DFFs: 30482/83640 36%
```

```
LOOP_LOG2=2
Info: Logic utilisation before packing:
Info: Total LUT4s: 61869/83640 73%
Info: logic LUTs: 57065/83640 68%
Info: carry LUTs: 4804/83640 5%
Info: RAM LUTs: 0/41820 0%
Info: RAMW LUTs: 0/20910 0%

Info: Total DFFs: 55056/83640 65%
```

`LOOP_LOG2=1` and `LOOP_LOG2=0` do not fit on the board.

## Images generated by xdot

Command to generate it:

`make generate-image`

![test](https://github.com/xtrinch/fpga-bitcoin-miner/blob/master/images/top-design.jpg)