|
| 1 | +# FPGA |
| 2 | + |
| 3 | +TODO: |
| 4 | + |
| 5 | + Makefile |
| 6 | + leds_icestick.v |
| 7 | + leds_bx.v |
| 8 | + button.v |
| 9 | + oled |
| 10 | + |
| 11 | +## Setup |
| 12 | + |
| 13 | +You will need Verilog setup from the [previous step](../verilog/README.md). |
| 14 | + |
| 15 | +Then, install the [Icestorm toolchain](http://www.clifford.at/icestorm/). The |
| 16 | +easiest way is using the [apio](https://github.com/FPGAwars/apio) project: |
| 17 | + |
| 18 | + pip3 install --user apio |
| 19 | + apio install icestorm |
| 20 | + |
| 21 | +This will download and unpack the necessary software in your home directory |
| 22 | +(under `~/.apio`). If you want to run the tools directly (not only from |
| 23 | +Makefile), add the toolchain to your `PATH`, for instance in your `.bashrc`: |
| 24 | + |
| 25 | + export PATH="$HOME/.apio/packages/toolchain-icestorm/bin/:$PATH" |
| 26 | + |
| 27 | +Under Linux, add yourself to the `dialout` group so that you can connect to |
| 28 | +the chip without sudo: |
| 29 | + |
| 30 | + sudo usermod -a -G dialout $USER |
| 31 | + |
| 32 | +For the TinyFPGA BX board, you need to additionally do the following: |
| 33 | + |
| 34 | + pip3 install --user tinyprog |
| 35 | + apio drivers --serial-enable |
| 36 | + |
| 37 | +## Building and flashing |
| 38 | + |
| 39 | +To upload a design, use `make flash`. For example: |
| 40 | + |
| 41 | + make flash V=leds_icestick.v |
| 42 | + |
| 43 | +For the TinyFPGA BX module, you need to set `BOARD=bx` flag: |
| 44 | + |
| 45 | + make flash V=leds_bx.v BOARD=bx |
| 46 | + |
| 47 | +The build process has the following steps: |
| 48 | + |
| 49 | +1. Logic synthesis, using `yosys`. This produces a `.blif` file with your |
| 50 | + design compiled down to components available on the FPGA chip (look-up |
| 51 | + tables, flip-flops, block RAMs, etc.) |
| 52 | +2. Place and route, using `arachne-pnr`. This produces `.asc` and then `.bin` |
| 53 | + files containing the final chip configuration (a bitstream). |
| 54 | +3. Programming the chip, using `iceprog` / `tinyprog`. This uploads the `.bin` |
| 55 | + to the chip over USB. |
| 56 | + |
| 57 | +## Pins |
| 58 | + |
| 59 | +You can find the available pins in [icestick.pcf](icestick.pcf) and |
| 60 | +[bx.pcf](bx.pcf) files. Your module will reference these. |
| 61 | + |
| 62 | +Here are the pinouts for reference: |
| 63 | + |
| 64 | +- [iCEstick pinout](http://www.pighixxx.net/portfolio-items/icestick/) |
| 65 | +- [TinyFPGA BX pinout](https://www.crowdsupply.com/tinyfpga/tinyfpga-bx/updates/manufacturing-continues) |
| 66 | + |
| 67 | +## Ideas |
| 68 | + |
| 69 | +Here is a list of ideas that you can implement. You will find some hints |
| 70 | +regarding different parts in the next section. |
| 71 | + |
| 72 | +- **Counter**: Implement a counter that increases every second. The Icestick |
| 73 | + has 5 LEDs, you can use them to show an increasing 5-bit number. |
| 74 | + - Try connecting the segment display. |
| 75 | + - Connect a button. Make the counter increase not with time, but every time |
| 76 | + the button is pressed. Add a reset button. |
| 77 | +- **Traffic lights**: Implement the traffic lights example from the previous |
| 78 | + chapter. You will need three LEDs (don't forget the resistors!) and a button. |
| 79 | +- **Fade LEDs in and out** by implementing pulse-width modulation. |
| 80 | +- **Serial link**: Use the chip to communicate with computer over the serial |
| 81 | + link. You can send a simple "Hello, world" first. |
| 82 | + - Memory buffer: Implement a chip that has a small memory buffer and responds |
| 83 | + to "read" and "write" commands. |
| 84 | +- **Screens**: Draw something on the screen. Create an animation. Send a |
| 85 | + picture over the serial link and draw it. |
| 86 | + - Pong game? |
| 87 | + - Game of Life demo. |
| 88 | + - Display text. [Unscii 8x8 bitmap fonts](http://pelulamu.net/unscii/) might |
| 89 | + come in handy, you can download the fonts in a hex format which is |
| 90 | + basically a one byte, one row bitmap. And here is a font [converted to |
| 91 | + column-by-column](https://github.com/pwmarcz/fpga-experiments/blob/master/font.mem) |
| 92 | + already. |
| 93 | + |
| 94 | +## Parts |
| 95 | + |
| 96 | +Here are some parts you can use in your projects. |
| 97 | + |
| 98 | +### Clock |
| 99 | + |
| 100 | +The Icestick has a 12 MHz clock signal, the BX a 16 MHz one. You will need to |
| 101 | +divide it to create a slower. See the `leds` example. |
| 102 | + |
| 103 | +It's also possible to [get a faster clock using a |
| 104 | +PLL](https://stackoverflow.com/questions/43890771/how-to-get-a-faster-clock-in-verilog-on-a-lattice-icestick), |
| 105 | +but I haven't tried that yet. The `icetime` tool should tell you the maximum |
| 106 | +frequency for your design. |
| 107 | + |
| 108 | +### LEDs |
| 109 | + |
| 110 | +The Icestick has 5 LEDs, the BX has one. You can turn them on and off just by |
| 111 | +specifying the pins in module output. |
| 112 | + |
| 113 | +You can connect your own LEDs as well, just make sure to connect the right |
| 114 | +resistors. The Icestick outputs are 3.3 V, the BX ones are 1.2 V (TODO check). |
| 115 | + |
| 116 | +### Buttons and switches |
| 117 | + |
| 118 | +You will need a pull-down or pull-up resistor. See for instance the [button |
| 119 | +example for Arduino](https://www.arduino.cc/en/Tutorial/Button). |
| 120 | + |
| 121 | +You can also use a an internal pull-up from FPGA. See `button.v` on how to do |
| 122 | +that. |
| 123 | + |
| 124 | +### Seven-segment display |
| 125 | + |
| 126 | +Here is a [spec sheet for the |
| 127 | +display](https://botland.com.pl/index.php?controller=attachment&id_attachment=1629). Ours |
| 128 | +has a common anode for all 4 digits. You will need to display the digits one at a time. Here is [a blog post on multiplexing 7 segment display](https://www.electronicsblog.net/4-digits-7-segments-led-display-multiplexing-with-arduino/). |
| 129 | + |
| 130 | +(TODO add more info once we try that) |
| 131 | + |
| 132 | +### OLED displays |
| 133 | + |
| 134 | +I have two OLED screens: |
| 135 | + |
| 136 | +- "Two-color" (actually monochrome) 128x64 screen. The data is laid out in 8 |
| 137 | + "pages" of 128 bytes each. Each page describes a 128x8 strip, each byte is a |
| 138 | + 1x8 segment. |
| 139 | +- 65536-color 96x64 screen. Each pixel is 16 bits. Note that this is more |
| 140 | + memory that Icestick has on board (12 KB; the Icestick's block RAMs hold 8 KB |
| 141 | + total). |
| 142 | + |
| 143 | +(TODO get the color display running) |
| 144 | + |
| 145 | +See `oled_mono.v` and `oled_color.v` for details on how to use. |
| 146 | + |
| 147 | +## Links |
| 148 | + |
| 149 | +- [open-fpga-verilog-tutorial](https://github.com/Obijuan/open-fpga-verilog-tutorial/wiki/Chapter-0%3A-you-are-leaving-the-private-sector) - |
| 150 | + an excellent tutorial series, translated from Spanish |
| 151 | +- [ice40-examples](https://github.com/nesl/ice40_examples) |
| 152 | +- [migen](https://github.com/m-labs/migen) - a circuit generator in Python |
| 153 | +- [Lattice iCE40 LP/HX Family Data Sheet](http://www.latticesemi.com/view_document?document_id=49312) |
| 154 | +- [fpga4fun](https://www.fpga4fun.com/) - projects and information |
0 commit comments