Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 29 KiB |
BIN
docs/_static/fomu-block-diagram.png
vendored
Before Width: | Height: | Size: 106 KiB After Width: | Height: | Size: 64 KiB |
1
docs/_static/fomu.drawio
vendored
Normal file
@ -0,0 +1 @@
|
||||
<mxfile host="Electron" modified="2020-11-07T13:50:31.243Z" agent="5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/13.5.7 Chrome/83.0.4103.122 Electron/9.1.2 Safari/537.36" etag="VvqdxijonNfACcLSaJ12" version="13.5.7" type="device"><diagram id="yj2Z-7FWhddFFwL3RGEn" name="Page-1">5Vpbd6o4FP41PtrFLVweWy+nnalrnOOcmfYRISpLBCdiq/31k0CCIUGlFUU7dK2W7ISd5Mv3ZW9CW3pnsfmB3OVsEPswbGmKv2np3ZamAdXCv4lhmxl028gMUxT4mUndGUbBB6RGhVrXgQ9XhYZJHIdJsCwavTiKoJcUbC5C8Xux2SQOi70u3SmUDCPPDWXrP4GfzOgsdEXZVTzCYDqjXRumTR9ZuKw1bbqauX78zpn0XkvvoDhOsrvFpgNDAh4DJnuuv6c2HxmCUVLlgYX398h86T22+72n3+YDL5g/fLS1zMubG67pjFuaGWJ/D2N8MyU3T52eofwagt9ZDe4ir8xbI9HiB29k0smWQmn+uyYzfUjgJmm7YTCNWvo9bhHCSYL/pE/i9YmS9iplAakDy83uQbGD1dKNjg8DD7asITanA6x/zKpyaNCkcWkXlbyomo3r5qTX0fDn/YCbTeb4OiZZBviJEzfZvB8qTfualrx+NIBmY6krz53VbSFx2qwJ9VWzPQ6Ij+5o2Bj5D+5KVed40EnpNlZlklqhaw3F68iHZP8nM3mfBQkcLV2P1L7jcI1ts2QR4pJKBhiEYScOY5Q+q/sutCce4W+C4jnkakzPhuNJ3t8bRBi9vUFJzUMdzhFgvIAJ2uImG5YP0OhI8wOVld930VZlEXTGBVqVRWCXRvhp7nsXA/ENDYOfCIm6FBI7aLtK3FBeHYNwcvD4USvwk8lE80qB982xCcx6gNcqAG+X4G6cC3ZDgv3P0fAJW/qhu5rJ2JPGg5opD6DtG2XI29pYN8+EfA5pU8gDCXkD703KX/Hamy1df1UvuwH5Kd1W0ovulJw9u2rabgAoYJ/n8U1hb0rY//xBQs5zr1sr7FDF5LbKYHdMS3drorZhXBm8lgTvrxGBd7kOw/Wy5m0bmnu2bcsZK0o9CAPtyjYPuxzhOoG1PVgO7NgGBjgTsI3HQ3YCUng1F2BdzdwluZ2EcHNPTjswFjDy6W3Xw5FzFWTQuSiRzRzoGCa0faELlBZeSeEOsGJ3w1d2t3mJndporB+uDDdB8sJ6wPeZT1azc0kKW64whCjAMEJEbQIllPQiTKKLA1jf7JBGpWMrlDP8oC8d+QgkwRjHa+TBA6tD1wJ3OYXJMXnIpONIBUpIxWwIhm4SvBWHW8Y02sMwDtK3D8ZpReC0SNZsmvQp/uhIcKQ5RUeGKjjKcJAcpcTPp32CFtSTtRDFERSFMA5jb75HBuqdooCiFCzHqUUMSkEM4LAYiH9RDanjfkAwZN1ypX1aOa4PXk01asWqqBWtUa2oQmAVKV5VKwAccXRurZQd6Z5XK1yUeC3o4iSV5Mp45QJIuUq+JojGgoddURBWo4LQBR5bXxSE4eCldLir6NZ07hxldwnjPLdY5MOesweWOvOrSxB/J0iyOoU8TtE/nck1kIPpTcpIt4QcDHw1rgg5mCY6OrdU5AO6z0qFyeJ/oJWCTuxbUInRqEpEcn81+xLldvHsSz5MrUUlNMqUZ1+KrfNCUW9HJoUcTzksk7I3oao6aYrXhvAGrotfrSrz2sFpEtibRNkXZrl8bH3utOkWWX6TjLVrYqxhOXcWz1i9WcrKnwKGz88Saz93UB1HjFPppxXcMIimLfZOuu+zucCuTqePr9Z5Pqc7NB5x5Cn/mr6fJyedYrONgYP96Y/TUC/CLK7BNaCuARl19aKoy6+16QdFpYvwzoC+G+sNc89RBYe/cVH85Xelb8h6BxxF/bKsl3Pv74e6IR0DNL3XyLng90e9LK7WhDou7v4nPMt+dv9Zr/f+Aw==</diagram></mxfile>
|
BIN
docs/_static/ice40-arch.png
vendored
Normal file
After Width: | Height: | Size: 222 KiB |
BIN
docs/_static/ice40-lut.png
vendored
Before Width: | Height: | Size: 134 KiB After Width: | Height: | Size: 58 KiB |
BIN
docs/_static/ice40-plb.png
vendored
Normal file
After Width: | Height: | Size: 180 KiB |
BIN
docs/_static/ice40-rgb.jpg
vendored
Before Width: | Height: | Size: 119 KiB |
BIN
docs/_static/ice40-rgb.png
vendored
Normal file
After Width: | Height: | Size: 268 KiB |
BIN
docs/_static/verilog-synthesis.png
vendored
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 21 KiB |
@ -1,29 +1,42 @@
|
||||
.. _background:
|
||||
|
||||
Background
|
||||
----------
|
||||
|
||||
About FPGAs
|
||||
~~~~~~~~~~~
|
||||
|
||||
Field Programmable Gate Arrays (FPGAs) are arrays of gates that are
|
||||
programmable in the field. Unlike most chips you will encounter, which
|
||||
have transistor gates arranged in a fixed order, FPGAs can change their
|
||||
configuration by simply loading new code. Fundamentally, this code
|
||||
programs lookup tables which form the basic building blocks of logic.
|
||||
|
||||
These lookup tables (called LUTs) are so important to the design of an
|
||||
`Field Programmable Gate Arrays (FPGAs) <https://en.wikipedia.org/wiki/Field-programmable_gate_array>`_
|
||||
are integrated circuits containing arrays of gates which are programmable
|
||||
in the field. Most chips you will encounter, have transistor gates arranged
|
||||
in a fixed order, thus providing a fixed functionality. Conversely, FPGAs
|
||||
can change their internal connections by simply loading new configurations.
|
||||
Fundamentally, configurations program lookup tables (LUTs), which form the basic
|
||||
building blocks of logic. These lookup tables are so important to the design and usage of an
|
||||
FPGA that they usually form part of the name of the part. For example,
|
||||
Fomu uses a UP5K, which has about 5000 LUTs. NeTV used an LX9, which had
|
||||
about 9000 LUTs, and NeTV2 uses a XC7A35T that has about 35000 LUTs.
|
||||
Fomu uses a `UP5K <http://www.latticesemi.com/Products/FPGAandCPLD/iCE40UltraPlus>`_,
|
||||
which has about 5000 LUTs. NeTV used an `LX9 <https://www.xilinx.com/products/silicon-devices/fpga/spartan-6.html>`_,
|
||||
which had about 9000 LUTs, and NeTV2 uses a `XC7A35T <https://www.xilinx.com/products/silicon-devices/fpga/artix-7.html>`_
|
||||
that has about 35000 LUTs.
|
||||
|
||||
.. image:: _static/ice40-lut.png
|
||||
:width: 100%
|
||||
FPGA LUTs are almost always *n*-inputs to 1-output. The ICE family of
|
||||
FPGAs from Lattice have 4-input LUTs. Xilinx parts tend to have 5-input or
|
||||
6-input LUTs which generally means they can do more logic in fewer LUTs.
|
||||
Comparing LUT count between FPGAs is a bit like comparing clock speed
|
||||
between different CPUs; not entirely accurate, but certainly a helpful
|
||||
rule of thumb.
|
||||
|
||||
.. figure:: _static/ice40-lut.png
|
||||
:width: 400px
|
||||
:align: center
|
||||
:alt: The ICE40 LUT4 is a basic 4-input 1-output LUT
|
||||
|
||||
This is the ``SB_LUT4``, which is the basic building block of Fomu. It
|
||||
has four inputs and one output. To program Fomu, we must define what
|
||||
each possible input pattern will create on the output.
|
||||
The ICE40 LUT4 is a basic 4-input 1-output function table.
|
||||
|
||||
To do this, we turn to a truth table:
|
||||
The basic building block of Fomu is the ``SB_LUT4``. It
|
||||
has four 1-bit inputs and one 1-bit output. To program Fomu, we must define what
|
||||
each possible input 4-bit pattern will create on the output. To do this, we turn to
|
||||
a `truth table <https://en.wikipedia.org/wiki/Truth_table>`_:
|
||||
|
||||
+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|
||||
| | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
|
||||
@ -40,60 +53,104 @@ To do this, we turn to a truth table:
|
||||
+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|
||||
|
||||
For example, to create a LUT that acted as an AND gate, we would define
|
||||
O to be 0 for everything except the last column. To create a NAND gate,
|
||||
we would define O to be 1 for everything except the last column.
|
||||
|
||||
FPGA LUTs are almost always *n*-inputs to 1-output. The ICE family of
|
||||
FPGAs from Lattice have 4-input LUTs. Xilinx parts tend to have 5- or
|
||||
6-input LUTs which generally means they can do more logic in fewer LUTs.
|
||||
Comparing LUT count between FPGAs is a bit like comparing clock speed
|
||||
between different CPUs - not entirely accurate, but certainly a helpful
|
||||
rule of thumb.
|
||||
|
||||
It is from this simple primitive that we build up the building blocks of
|
||||
``O`` to be 0 for everything except the last column. Conversely, to create
|
||||
a NAND gate, we would define ``O`` to be 1 for everything except the last column.
|
||||
It is from this simple primitive that we create the building logic blocks of
|
||||
FPGA design.
|
||||
|
||||
.. figure:: _static/ice40-plb.png
|
||||
:width: 400px
|
||||
:align: center
|
||||
:alt: PLB Block Diagram (from iCE40 UltraPlus Family Data Sheet)
|
||||
|
||||
Programmable Logic Block (PLB), Block Diagram.
|
||||
|
||||
Modern FPGA devices are no longer composed of arrays of gates (i.e. LUTs) only.
|
||||
Typically, LUTs are grouped with flip-flop registers (DFF) and some carry logic, in
|
||||
so-called Programmable Logic Blocks (PLBs) or Configurable Logic Blocks (CLBs);
|
||||
depending on the vendor. These resources allow combining multiple LUTs for
|
||||
describing larger logical functions and for providing sequential behaviour.
|
||||
|
||||
Furthermore, additional purpose-specific blocks are included in the devices:
|
||||
Block RAMs (BRAMs), Digital Signal Processing (DSP) blocks, high-performance serial
|
||||
transmitters/receivers, etc. Those so-called *hard* blocks allow better
|
||||
area and power usage than LUT-based components. Nevertheless, the behaviour
|
||||
of any of those *hard* blocks can be replicated using PLBs only. At the same time,
|
||||
custom behaviour can only be described through LUTs, because all *hard* blocks
|
||||
are programmable within the pre-fixed functionality only.
|
||||
|
||||
.. _background:code-into-gates:
|
||||
|
||||
Turning code into gates
|
||||
^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Writing lookup tables is hard, so people have come up with abstract
|
||||
Hardware Description Languages (HDLs) we can use to describe them. The
|
||||
Configuring all the LUTs, carry logic and other *hard* blocks manually is
|
||||
hard and very challenging; so people have come up with abstract
|
||||
`Hardware Description Languages (HDLs) <https://en.wikipedia.org/wiki/Hardware_description_language>`_,
|
||||
that allow us to describe the expected behaviour and/or structure. The
|
||||
two most common languages are Verilog and VHDL. However, a modern trend
|
||||
is to embed an HDL inside an existing programming language, such as how
|
||||
Migen is embedded in Python, or SpinalHDL is embedded in Scala.
|
||||
is to achieve hardware description by embedding a Domain Specific Language (DSL)
|
||||
inside an existing programming language, such as how Migen is embedded in Python,
|
||||
Clash is embedded in Haskell, or Chisel and SpinalHDL are embedded in Scala.
|
||||
|
||||
Here is an example of a Verilog module:
|
||||
Here is an example of a counter module with a registered output:
|
||||
|
||||
.. code:: verilog
|
||||
.. tabs::
|
||||
|
||||
module example (output reg [0:5] Q, input C);
|
||||
reg [0:8] counter;
|
||||
always @(posedge C)
|
||||
begin
|
||||
counter <= counter + 1'b1;
|
||||
Q <= counter[3] ^ counter[5] | counter<<2;
|
||||
end
|
||||
endmodule
|
||||
.. group-tab:: Verilog
|
||||
|
||||
We can run this Verilog module through a synthesizer to turn it into
|
||||
``SB_LUT4`` blocks, or we can turn it into a more familiar logic
|
||||
.. code:: verilog
|
||||
|
||||
module example (
|
||||
input C,
|
||||
output reg [0:5] Q
|
||||
);
|
||||
reg [0:8] counter;
|
||||
|
||||
always @(posedge C)
|
||||
begin
|
||||
counter <= counter + 1'b1;
|
||||
end
|
||||
|
||||
always @(posedge C)
|
||||
begin
|
||||
Q <= counter[3] ^ counter[5] | counter<<2;
|
||||
end
|
||||
endmodule
|
||||
|
||||
We can run this HDL module through a synthesizer to turn it into
|
||||
LUT and DFF blocks, or we can turn it into a more familiar logic
|
||||
diagram:
|
||||
|
||||
.. image:: _static/verilog-synthesis.png
|
||||
:width: 100%
|
||||
.. figure:: _static/verilog-synthesis.png
|
||||
:align: center
|
||||
:width: 600px
|
||||
:alt: A syntheis of the above logic into some gates
|
||||
|
||||
If we do decide to synthesize to ``SB_LUT4`` blocks, we will end up with
|
||||
a pile of LUTs that need to be strung together somehow. This is done by
|
||||
a Place-and-Route tool. This performs the job of assigning physical LUTs
|
||||
to each LUT that gets defined by the synthesizer, and then figuring out
|
||||
A syntheis of the above logic into basic blocks.
|
||||
|
||||
Turning gates into a bitstream
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
If we do decide to synthesize to PLBs, we will end up with
|
||||
a pile of LUTs and DFFs that need to be strung together somehow. This is done by
|
||||
a Place-and-Route (PnR) tool. This performs the job of assigning physical PLBs
|
||||
to each LUT and DFF that gets defined by the synthesizer; and then figuring out
|
||||
how to wire it all up.
|
||||
|
||||
Once the place-and-route tool is done, it generates an abstract file
|
||||
that needs to be translated into a format that the hardware can
|
||||
recognize. This is done by a bitstream packing tool. Finally, this
|
||||
bitstream needs to be loaded onto the device somehow, either off of a
|
||||
SPI flash or by manually programming it by toggling wires.
|
||||
Once the PnR tool is done, it generates an abstract file that needs to be
|
||||
translated into a format that the hardware can recognize. This is done by a
|
||||
bitstream packing tool.
|
||||
|
||||
Loading a bitstream into a device
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Finally, the bitstream needs to be loaded onto the device somehow. It can be
|
||||
done manually by toggling wires of the FPGAs programming interface. However,
|
||||
most FPGAs are volatile, which means the the configuration is lost when
|
||||
unplugged. Therefore, most FPGA boards include some flash memory, which is
|
||||
typically programmed through SPI. Then, when the FPGA is plugged again, it loads
|
||||
the configuration from a predefined location in the flash.
|
||||
|
||||
About the ICE40UP5K
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
@ -104,42 +161,57 @@ very nice features:
|
||||
1. 5280 4-input LUTs (LC)
|
||||
2. 16 kilobytes BRAM
|
||||
3. **128 kilobytes “SPRAM”**
|
||||
4. Current-limited 3-channel LED driver
|
||||
5. 2x I2C and 2x SPI
|
||||
6. 8 16-bit DSP units
|
||||
4. 1x Current-limited 3-channel LED driver
|
||||
5. 2x I2C and 2x SPI interfaces
|
||||
6. 8x 16-bit DSP units
|
||||
7. **Warmboot capability**
|
||||
8. **Open toolchain**
|
||||
|
||||
Many FPGAs have what’s called block RAM, or BRAM. This is frequently
|
||||
used to store data such as buffers, CPU register files, and large arrays
|
||||
of data. This type of memory is frequently reused as RAM on many FPGAs.
|
||||
The ICE40UP5K is unusual in that it also as 128 kilobytes of Single
|
||||
Ported RAM that can be used as memory for a softcore (a term used for a
|
||||
CPU core running inside an FPGA, to differentiate it from a ‘hard’ -
|
||||
.. figure:: _static/ice40-arch.png
|
||||
:width: 400px
|
||||
:align: center
|
||||
:alt: iCE40UP5K Device, Top View (from iCE40 UltraPlus Family Data Sheet)
|
||||
|
||||
iCE40UP5K Device, Top View.
|
||||
|
||||
BRAM is frequently used to store data such as buffers, CPU register files,
|
||||
and large arrays of data. This type of memory is frequently reused as RAM on
|
||||
many FPGAs. The ICE40UP5K is unusual in that it also has 128 kilobytes of
|
||||
Single Ported RAM that can be used as memory for a softcore (a term used for
|
||||
a CPU core running inside an FPGA, to differentiate it from a ‘hard’ -
|
||||
i.e. fixed chip - implementation). That means that, unlike other FPGAs,
|
||||
valuable block RAM isn’t taken up by system memory.
|
||||
|
||||
Additionally, the ICE40 family of devices generally supports “warmboot”
|
||||
Additionally, the ICE40 family of devices generally supports *warmboot*
|
||||
capability. This enables us to have multiple designs live on the same
|
||||
FPGA and tell the FPGA to swap between them.
|
||||
|
||||
As always, this workshop wouldn’t be nearly as easy without the open
|
||||
toolchain that enables us to port it to a lot of different platforms.
|
||||
source tools that enable us to port it to a lot of different platforms.
|
||||
|
||||
.. _background:about-fomu:
|
||||
|
||||
About Fomu
|
||||
~~~~~~~~~~
|
||||
|
||||
Fomu is an ICE40UP5K that fits in your USB port. It contains two
|
||||
megabytes of SPI flash memory, four edge buttons, and a three-color LED.
|
||||
|
||||
Unlike most other ICE40 projects, Fomu implements its USB in a softcore.
|
||||
That means that the bitstream that runs on the FPGA must also provide
|
||||
the ability to communicate over USB. This uses up a lot of storage on
|
||||
this small FPGA, but it also enables us to have such a tiny form factor,
|
||||
and lets us do some really cool things with it.
|
||||
|
||||
.. image:: _static/fomu-block-diagram.png
|
||||
:width: 100%
|
||||
.. figure:: _static/fomu-block-diagram.png
|
||||
:align: center
|
||||
:width: 600px
|
||||
:alt: Block diagram of Fomu
|
||||
|
||||
Block diagram of Fomu.
|
||||
|
||||
The ICE40UP5K at the heart of Fomu really controls everything, and this
|
||||
workshop is all about trying to unlock the power of this chip.
|
||||
|
||||
.. NOTE::
|
||||
Some figures in this section were extracted from the `iCE40 UltraPlus Family Data Sheet <https://www.latticesemi.com/view_document?document_id=51968>`_.
|
76
docs/hdl.rst
@ -3,38 +3,64 @@
|
||||
Hardware Description Languages
|
||||
------------------------------
|
||||
|
||||
The two most common **H**\ ardware **D**\ escription **L**\ anguages are
|
||||
Verilog and VHDL.
|
||||
The two most common **H**\ ardware **D**\ escription **L**\ anguages are Verilog and VHDL.
|
||||
As explained in :ref:`background:code-into-gates`, a *synthesis* tool is used for converting
|
||||
the human readable HDL into a netlist representation. The synthesis tool used in the Fomu
|
||||
toolchain is called ``yosys``. Once we have the netlist representation, a tool called
|
||||
``nextpnr`` performs an operation called *place and route* (PnR), which makes it something
|
||||
that will actually run on the FPGA. This is all done for you using the ``Makefiles`` in the
|
||||
subdirectories of any of the following examples: :repo:`verilog <verilog>`,
|
||||
:repo:`vhdl <vhdl>`, :repo:`mixed-hdl <mixed-hdl>`, or :repo:`migen <migen>`.
|
||||
|
||||
.. NOTE:: The pre-built toolchain we are releasing supports Verilog only.
|
||||
However, `GHDL <https://github.com/ghdl>`_ can be usable as a VHDL frontend
|
||||
for Yosys. See `ghdl-yosys-plugin <https://github.com/ghdl/ghdl-yosys-plugin>`_.
|
||||
.. NOTE::
|
||||
``nextpnr`` is timing-driven. This means that a design will be generated with a given
|
||||
clock domain guaranteed to perform fast enough, but sometimes it won't optimise further.
|
||||
When the ``make`` command runs ``nextpnr-ice40`` you will see something similar to the
|
||||
following:
|
||||
|
||||
When writing HDL, a tool called ``yosys`` is used to convert the
|
||||
human readable verilog into a netlist representation, this is called
|
||||
*synthesis*. Once we have the netlist representation, a tool called
|
||||
``nextpnr`` performs an operation called *place and route* (P&R) which
|
||||
makes it something that will actually run on the FPGA. This is all
|
||||
done for you using the ``Makefiles`` in the subdirectories of ``verilog``
|
||||
or ``vhdl``.
|
||||
::
|
||||
|
||||
A big feature of ``nextpnr`` over its predecessor, is the fact that
|
||||
it is timing-driven. This means that a design will be generated with
|
||||
a given clock domain guaranteed to perform fast enough.
|
||||
Info: Max frequency for clock 'clk': 73.26 MHz (PASS at 12.00 MHz)
|
||||
|
||||
When the ``make`` command runs ``nextpnr-ice40`` you will see something
|
||||
similar included in the output:
|
||||
This output example shows that we could run ``clk`` at up to 73.26
|
||||
MHz and it would still be stable (even though we only requested 12.00
|
||||
MHz). Note that there is some variation between designs depending on
|
||||
how the placer and router decided to lay things out, so your exact
|
||||
frequency numbers might be different from the ones shown in the code
|
||||
blocks of this documentation.
|
||||
|
||||
::
|
||||
.. IMPORTANT::
|
||||
As explained in :ref:`background:about-fomu`, Fomu implements its USB in a softcore, and
|
||||
the bitstream that runs on the FPGA must provide the ability to communicate over USB.
|
||||
That is a tradeoff for achieving such a tiny board size, which unfortunately makes
|
||||
it not straightforward to use non-trivial HDL designs. This is because
|
||||
I/O is very limited, hence, it is challenging to actually *see* whether the designs are
|
||||
behaving as expected. Ideally, a USB-to-UART core would be provided for users to instantiate
|
||||
in their HDL designs. Should you be interested in helping achieve it, `let us know! <https://github.com/im-tomu/fomu-workshop/issues/new>`_
|
||||
Meanwhile, :ref:`HDLs:migen` examples provide a working SoC that allows interacting
|
||||
through USB using a Wishbone Bus.
|
||||
|
||||
Info: Max frequency for clock 'clk': 73.26 MHz (PASS at 12.00 MHz)
|
||||
.. figure:: _static/ice40-rgb.png
|
||||
:align: center
|
||||
:width: 600px
|
||||
:alt: iCE40 UltraLite and iCE40 UltraPlus RGB Port Level Diagram
|
||||
|
||||
This output example shows that we could run ``clk`` at up to 73.26
|
||||
MHz and it would still be stable (even though we only requested 12.00
|
||||
MHz). Note that there is some variation between designs depending on
|
||||
how the placer and router decided to lay things out, so your exact
|
||||
frequency numbers might be different from the ones shown in the code
|
||||
blocks of this documentation.
|
||||
iCE40 UltraLite and iCE40 UltraPlus RGB Port Level Diagram.
|
||||
|
||||
Regardless of the HDL language or higher abstraction programming language used for
|
||||
describing the design, all the examples in this workshop do use the *hard* RGB block
|
||||
for driving the LED on the board. It is defined as a Verilog module or VHDL component
|
||||
named ``SB_RGBA_DRV``.
|
||||
As shown in the block diagram from the datasheet, the RGB driver has five inputs
|
||||
(``CURREN``, ``RGBLEDEN``, ``RGB0PWM``, ``RGB1PWM``, and ``RGB2PWM``),
|
||||
and three outputs (``RGB0``, ``RGB1``, and ``RGB2``). It also has four parameters:
|
||||
``CURRENT_MODE``, ``RGB0_CURRENT``, ``RGB1_CURRENT``, and ``RGB2_CURRENT``. As a result,
|
||||
it allows driving the LEDs safely, by specifying the current limit for each of them.
|
||||
More information on this driver can be found in the `ICE40 LED Driver Usage Guide <_static/reference/FPGA-TN-1288-ICE40LEDDriverUsageGuide.pdf>`_.
|
||||
|
||||
.. ATTENTION::
|
||||
Even though it is possible to drive the RGB outputs directly (i.e. without instantiating
|
||||
``SB_RGBA_DRV``), it is strongly discouraged, as it might damage the LEDs.
|
||||
|
||||
Languages and generators
|
||||
========================
|
||||
|
@ -1,13 +1,15 @@
|
||||
==================
|
||||
FPGA Tomu Workshop
|
||||
==================
|
||||
|
||||
.. image:: _static/logo.png
|
||||
:align: center
|
||||
:width: 600px
|
||||
:alt: Fomu logo
|
||||
|
||||
Hi, I’m Fomu! This workshop covers the basics of Fomu in a top-down
|
||||
approach. We’ll start out by learning what Fomu is, how to load software
|
||||
into Fomu, and finally how to write software for Fomu.
|
||||
Hi, I’m `Fomu <https://github.com/im-tomu/fomu-hardware>`_ (FPGA Tomu)!
|
||||
This workshop covers the basics of Fomu in a top-down approach. We’ll
|
||||
start out by learning **what Fomu is**, **how to load software** into Fomu,
|
||||
**how to write software** for Fomu, and finally **how to write hardware** for Fomu.
|
||||
|
||||
FPGAs are complex, weird things, so we’ll take a gentle approach and
|
||||
start out by treating it like a Python interpreter first, and gradually
|
||||
@ -16,10 +18,8 @@ take a break at any time and explore! Stop when you feel the concepts
|
||||
are too unfamiliar, or plough on and dig deep into the world of
|
||||
hardware.
|
||||
|
||||
Table of Contents
|
||||
=================
|
||||
|
||||
.. toctree::
|
||||
:hidden:
|
||||
:maxdepth: 5
|
||||
|
||||
requirements/index
|
||||
|
@ -1,3 +1,5 @@
|
||||
.. _HDLs:migen:
|
||||
|
||||
Migen and LiteX
|
||||
---------------
|
||||
|
||||
@ -128,18 +130,8 @@ Aside from that, there’s not much we can *do* with this design. But
|
||||
there’s a lot of infrastructure there. So let’s add something we can see
|
||||
(``workshop_rgb.py`` contains the completed example).
|
||||
|
||||
.. image:: _static/ice40-rgb.jpg
|
||||
:width: 100%
|
||||
:alt: RGB block
|
||||
|
||||
This is the RGB block from the datasheet. It has five inputs:
|
||||
``CURREN``, ``RGBLEDEN``, ``RGB0PWM``, ``RGB1PWM``, and ``RGB2PWM``. It
|
||||
has three outputs: ``RGB0``, ``RGB1``, and ``RGB2``. It also has four
|
||||
parameters: ``CURRENT_MODE``, ``RGB0_CURRENT``, ``RGB1_CURRENT``, and
|
||||
``RGB2_CURRENT``.
|
||||
|
||||
This block is defined in Verilog (as ``SB_RGBA_DRV``), but we can import it as
|
||||
a Module into Migen:
|
||||
As explained in :ref:`HDLs` the RGB LED driver is defined in Verilog/VHDL
|
||||
(as ``SB_RGBA_DRV``), but we can import it as a Module into Migen:
|
||||
|
||||
.. code:: python
|
||||
|
||||
@ -198,7 +190,7 @@ your ``build/csr.csv`` says) and see them take effect immediately.
|
||||
|
||||
$ wishbone-tool 0x60003000 0x1 # make LED green
|
||||
$ wishbone-tool 0x60003000 0x2 # make LED red
|
||||
$ wishbone-tool 0x60003000 0x3 # make LED yellow
|
||||
$ wishbone-tool 0x60003000 0x3 # make LED yellow
|
||||
$ wishbone-tool 0x60003000 0x4 # make LED blue
|
||||
$ wishbone-tool 0x60003000 0x5 # make LED teal
|
||||
$ wishbone-tool 0x60003000 0x6 # make LED pink
|
||||
|
@ -3,32 +3,26 @@
|
||||
Required Drivers
|
||||
================
|
||||
|
||||
On most systems the Fomu board does **not** need any special drivers.
|
||||
On most systems (such as Windows 10 or newer, or MacOS X), the Fomu board does **not** need any special drivers.
|
||||
|
||||
* On Windows 10 or newer you do not need to install anything.
|
||||
* On Windows systems **earlier** than Windows 10 you will need to
|
||||
:ref:`windows-zadig`.
|
||||
* On MacOS X you do not need to install any drivers.
|
||||
* On Linux you do not need to install any drivers, **however** you may need
|
||||
``sudo`` access unless you :ref:`linux-udev` to grant permission to use the
|
||||
* On GNU/Linux, you do not need to install any drivers, **however**, you may need
|
||||
``sudo`` access unless you :ref:`linux-udev` to grant permission for using the
|
||||
USB device from a non-privileged account.
|
||||
|
||||
* Windows systems **earlier** than Windows 10: you will need to
|
||||
:ref:`install Zadig drivers <windows-zadig>`.
|
||||
|
||||
.. _linux-udev:
|
||||
|
||||
Setup udev rules
|
||||
----------------
|
||||
|
||||
.. warning::
|
||||
.. WARNING::
|
||||
This set up is for GNU/Linux **only**. Setting up these udev rules grants
|
||||
permissions for using the USB device from a non-privileged account.
|
||||
|
||||
This set up is for Linux **only**.
|
||||
|
||||
Setting up these udev rules grant permissions to use the USB device from a
|
||||
non-privileged account.
|
||||
|
||||
In Linux, try running ``dfu-util -l``, and if you get an error message like the
|
||||
following you should add a ``udev`` rule as to give your user permission to the
|
||||
usb device.
|
||||
On GNU/Linux, try running ``dfu-util -l``. If you get an error message like the
|
||||
following, you should add a ``udev`` rule as to give your user permission to the
|
||||
USB device.
|
||||
|
||||
.. session:: shell-session
|
||||
:emphasize-lines: 9
|
||||
@ -45,43 +39,37 @@ usb device.
|
||||
$
|
||||
|
||||
Steps to set up udev rule
|
||||
-------------------------
|
||||
#########################
|
||||
|
||||
#. Add your user to the plugdev group
|
||||
#. Add your user to group ``plugdev``:
|
||||
|
||||
.. session:: shell-session
|
||||
|
||||
$ sudo groupadd plugdev
|
||||
$ sudo usermod -a -G plugdev $USER
|
||||
|
||||
#. Check you are in the ``plugdev`` group with ``id $USER``
|
||||
.. WARNING::
|
||||
You **must** log out and then log in again for the addition to group ``plugdev`` to take affect.
|
||||
|
||||
#. Use ``id $USER`` and/or ``groups`` to check you are in group ``plugdev``:
|
||||
|
||||
.. session:: shell-session
|
||||
|
||||
$ id $USER
|
||||
uid=1000(tim) gid=1000(tim) groups=500(plugdev),997(admin)
|
||||
$
|
||||
|
||||
#. You **will** need to log out and log in again in order to be a member of the ``plugdev`` group.
|
||||
|
||||
.. warning::
|
||||
|
||||
You **must** log out and then log in again for the group addition to take affect.
|
||||
|
||||
#. Check you are in the ``plugdev`` group with ``groups``
|
||||
|
||||
.. session:: shell-session
|
||||
|
||||
$ groups | grep plugdev
|
||||
tim plugdev admin
|
||||
$
|
||||
|
||||
#. Create a file named ``/etc/udev/rules.d/99-fomu.rules`` and add the following:
|
||||
#. Create a file named ``/etc/udev/rules.d/99-fomu.rules`` and add the following.
|
||||
|
||||
.. code:: udev
|
||||
|
||||
SUBSYSTEM=="usb", ATTRS{idVendor}=="1209", ATTRS{idProduct}=="5bf0", MODE="0664", GROUP="plugdev"
|
||||
|
||||
.. NOTE::
|
||||
You need ``sudo`` privileges for creating this file.
|
||||
|
||||
#. Reload the udev-rules using the following:
|
||||
|
||||
.. session:: shell-session
|
||||
@ -101,9 +89,12 @@ Installing Zadig Drivers
|
||||
|
||||
#. Download `Zadig <https://zadig.akeo.ie/>`__.
|
||||
#. Open Zadig.
|
||||
#. Under Options, select "List All Devices".
|
||||
#. In the dropdown, select your Fomu and in the field right of the green arrow
|
||||
choose the `WinUSB` driver and hit Upgrade Driver.
|
||||
#. Under ``Options``, select ``List All Devices``.
|
||||
#. In the dropdown, select your Fomu; in the field right of the green arrow,
|
||||
choose the ``WinUSB`` driver; and hit ``Upgrade Driver``.
|
||||
|
||||
.. image:: ../_static/Zadeg-Setup.PNG
|
||||
:alt: Setup of ZADEG for Updating USBport driver on WIN7
|
||||
.. figure:: ../_static/Zadig-Setup.png
|
||||
:align: center
|
||||
:alt: Setup of Zadig for updating USB port driver on Windows earlier than 10
|
||||
|
||||
Setup of Zadig for updating USB port driver on Windows earlier than 10.
|
||||
|
@ -3,16 +3,15 @@
|
||||
Required Files
|
||||
--------------
|
||||
|
||||
.. note::
|
||||
|
||||
.. NOTE::
|
||||
If you’re attending a workshop that provides USB drives, these files may be
|
||||
available on the USB drive under the ``Workshop`` directory.
|
||||
|
||||
You will need the Workshop files. They are located in the
|
||||
`fomu-workshop <https://github.com/im-tomu/fomu-workshop>`__ Github
|
||||
repository. You can download
|
||||
`master.zip <https://github.com/im-tomu/fomu-workshop/archive/master.zip>`__
|
||||
or clone it from git:
|
||||
`fomu-workshop <https://github.com/im-tomu/fomu-workshop>`_ Github
|
||||
repository. You can clone it with git, or download
|
||||
`master.zip <https://codeload.github.com/im-tomu/fomu-workshop/zip/master>`_ |
|
||||
`master.tar.gz <https://codeload.github.com/im-tomu/fomu-workshop/tar.gz/master>`_.
|
||||
|
||||
.. session:: shell-session
|
||||
|
||||
|
@ -3,54 +3,54 @@
|
||||
Required Hardware
|
||||
#################
|
||||
|
||||
For this workshop, you will need a Fomu board.
|
||||
- For this workshop, you will need a `Fomu board <https://github.com/im-tomu/fomu-hardware>`_.
|
||||
- Aside from that, you need a computer with a USB port that can run the :ref:`required-software`.
|
||||
|
||||
Aside from that, you need a computer with a USB port that can run the
|
||||
:ref:`required-software`.
|
||||
.. NOTE::
|
||||
You should not need any special drivers, though on Linux you may need ``sudo``
|
||||
access, or special ``udev`` rules for granting permission to use the USB device from a
|
||||
non-privileged account.
|
||||
|
||||
You should not need any special drivers, though on Linux you may need sudo
|
||||
access, or special udev rules to grant permission to use the USB device from a
|
||||
non-privileged account.
|
||||
|
||||
This workshop may be competed with any model of Fomu, though there are some
|
||||
parts that require you to identify which model you have. See the
|
||||
:ref:`which-fomu` section.
|
||||
.. ATTENTION::
|
||||
This workshop may be competed with any model of Fomu, though there are some
|
||||
parts that require you to identify which model you have. See the
|
||||
:ref:`which-fomu` below.
|
||||
|
||||
.. _which-fomu:
|
||||
|
||||
Which Fomu do I have?
|
||||
=====================
|
||||
|
||||
+-------------------+-------------------------------------------------------------------------+-------------------------------------------------------------------+
|
||||
| | Hacker | Production |
|
||||
+===================+=========================================================================+===================================================================+
|
||||
| **String** | hacker | pvt |
|
||||
+-------------------+-------------------------------------------------------------------------+-------------------------------------------------------------------+
|
||||
| **Bash Command** | ``export FOMU_REV=hacker`` | ``export FOMU_REV=pvt`` |
|
||||
+-------------------+-------------------------------------------------------------------------+-------------------------------------------------------------------+
|
||||
| **Front** | |Hacker Hardware Front without case| | |Production Hardware Front without case| |
|
||||
+-------------------+-------------------------------------------------------------------------+-------------------------------------------------------------------+
|
||||
| **Back** | |Hacker Hardware Back without case| | |Production Hardware Back without case| |
|
||||
+-------------------+-------------------------------------------------------------------------+-------------------------------------------------------------------+
|
||||
| **In Case** | |Hacker Hardware Back with case| | |Production Hardware Back with case| |
|
||||
+-------------------+-------------------------------------------------------------------------+-------------------------------------------------------------------+
|
||||
| **Parts** | |Hacker Hardware Annotated Diagram| | |Production Hardware Annotated Diagram| |
|
||||
+-------------------+-------------------------------------------------------------------------+-------------------------------------------------------------------+
|
||||
| **Color** | |Dark Blue| | |Cyan Light Blue| |
|
||||
+-------------------+-------------------------------------------------------------------------+-------------------------------------------------------------------+
|
||||
| **Bootloader** | Fomu **Hacker** running DFU Bootloader vX.X.X | Fomu **PVT** running DFU Bootloader vX.X.X |
|
||||
+-------------------+-------------------------------------------------------------------------+-------------------------------------------------------------------+
|
||||
| **Description** | These are the original design and cut corners to make it easier to | If you ordered a Fomu from Crowd Supply, this is the model you'll |
|
||||
| | manufacture. If you received one directly from Tim before 36C3, you | receive. It is small, and fits in a USB port. There is no |
|
||||
| | probably have one of these. Hacker boards have white silkscreen on | silkscreen on it. This model of Fomu has a large silver crystal |
|
||||
| | the back. | oscillator that is the tallest component on the board. |
|
||||
+-------------------+-------------------------------------------------------------------------+-------------------------------------------------------------------+
|
||||
| **Schematic** | `schematic-hacker.pdf <_static/reference/schematic-hacker.pdf>`__ | `schematic-pvt.pdf <_static/reference/schematic-pvt.pdf>`__ |
|
||||
+-------------------+-------------------------------------------------------------------------+-------------------------------------------------------------------+
|
||||
| **Received at** | From Tim at 35C3, CCCamp19, HackADay Supercon 2019 | At RISC-V Summit 2019, 36C3, Crowdsupply, Mouser |
|
||||
+-------------------+-------------------------------------------------------------------------+-------------------------------------------------------------------+
|
||||
| **Buy more** | End of Life | `CrowdSupply <https://j.mp/fomu-cs>`__, |
|
||||
+-------------------+-------------------------------------------------------------------------+-------------------------------------------------------------------+
|
||||
+------------------+---------------------------------------------------------------------+-------------------------------------------------------------------+
|
||||
| | Hacker | Production |
|
||||
+==================+=====================================================================+===================================================================+
|
||||
| **String** | hacker | pvt |
|
||||
+------------------+---------------------------------------------------------------------+-------------------------------------------------------------------+
|
||||
| **Bash Command** | ``export FOMU_REV=hacker`` | ``export FOMU_REV=pvt`` |
|
||||
+------------------+---------------------------------------------------------------------+-------------------------------------------------------------------+
|
||||
| **Front** | |Hacker Hardware Front without case| | |Production Hardware Front without case| |
|
||||
+------------------+---------------------------------------------------------------------+-------------------------------------------------------------------+
|
||||
| **Back** | |Hacker Hardware Back without case| | |Production Hardware Back without case| |
|
||||
+------------------+---------------------------------------------------------------------+-------------------------------------------------------------------+
|
||||
| **In Case** | |Hacker Hardware Back with case| | |Production Hardware Back with case| |
|
||||
+------------------+---------------------------------------------------------------------+-------------------------------------------------------------------+
|
||||
| **Parts** | |Hacker Hardware Annotated Diagram| | |Production Hardware Annotated Diagram| |
|
||||
+------------------+---------------------------------------------------------------------+-------------------------------------------------------------------+
|
||||
| **Color** | |Dark Blue| | |Cyan Light Blue| |
|
||||
+------------------+---------------------------------------------------------------------+-------------------------------------------------------------------+
|
||||
| **Bootloader** | Fomu **Hacker** running DFU Bootloader vX.X.X | Fomu **PVT** running DFU Bootloader vX.X.X |
|
||||
+------------------+---------------------------------------------------------------------+-------------------------------------------------------------------+
|
||||
| **Description** | These are the original design and cut corners to make it easier to | If you ordered a Fomu from Crowd Supply, this is the model you'll |
|
||||
| | manufacture. If you received one directly from Tim before 36C3, you | receive. It is small, and fits in a USB port. There is no |
|
||||
| | probably have one of these. Hacker boards have white silkscreen on | silkscreen on it. This model of Fomu has a large silver crystal |
|
||||
| | the back. | oscillator that is the tallest component on the board. |
|
||||
+------------------+---------------------------------------------------------------------+-------------------------------------------------------------------+
|
||||
| **Schematic** | `schematic-hacker.pdf <_static/reference/schematic-hacker.pdf>`__ | `schematic-pvt.pdf <_static/reference/schematic-pvt.pdf>`__ |
|
||||
+------------------+---------------------------------------------------------------------+-------------------------------------------------------------------+
|
||||
| **Received at** | From Tim at 35C3, CCCamp19, HackADay Supercon 2019 | At RISC-V Summit 2019, 36C3, Crowdsupply, Mouser |
|
||||
+------------------+---------------------------------------------------------------------+-------------------------------------------------------------------+
|
||||
| **Buy more** | End of Life | `CrowdSupply <https://j.mp/fomu-cs>`__, |
|
||||
+------------------+---------------------------------------------------------------------+-------------------------------------------------------------------+
|
||||
|
||||
.. |Dark Blue| raw:: html
|
||||
|
||||
@ -76,4 +76,4 @@ Which Fomu do I have?
|
||||
the Fomu crowd funding campaign. This model of Fomu is about the size
|
||||
of a credit card. It should have the text “Fomu EVT3” written across
|
||||
it in white silkscreen. If you have a different EVT board such as
|
||||
EVT2 or EVT1, they should work also.
|
||||
EVT2 or EVT1, they should also work.
|
||||
|
@ -3,21 +3,18 @@
|
||||
Requirements
|
||||
############
|
||||
|
||||
For this workshop you will need;
|
||||
.. NOTE::
|
||||
If you are at a workshop, please **install the tools first** and then get
|
||||
the hardware from your presenter.
|
||||
|
||||
#. The Fomu workshop files - see :ref:`required-files` section.
|
||||
#. The Fomu toolchain - see :ref:`required-software` section.
|
||||
#. A Fomu board - see :ref:`required-hardware` section.
|
||||
#. Set up drivers - see :ref:`required-drivers` section.
|
||||
For this workshop you will need:
|
||||
|
||||
.. note::
|
||||
|
||||
If you are at a workshop, please **install the tools first** and then get
|
||||
the hardware from your presenter.
|
||||
|
||||
|
||||
.. warning::
|
||||
- :ref:`The Fomu workshop files <required-files>`
|
||||
- :ref:`The Fomu toolchain <required-software>`
|
||||
- :ref:`A Fomu board <required-hardware>`
|
||||
- :ref:`Set up drivers <required-drivers>`
|
||||
|
||||
.. WARNING::
|
||||
Your Fomu should be running Foboot |Foboot Version| or newer.
|
||||
|
||||
You can see what version you are running by typing ``dfu-util -l`` like so;
|
||||
@ -36,7 +33,7 @@ For this workshop you will need;
|
||||
Found DFU: [1209:5bf0] ver=0101, devnum=19, cfg=1, intf=0, path="1-2", alt=0, name="Fomu PVT running DFU Bootloader v2.0.3", serial="UNKNOWN"
|
||||
$
|
||||
|
||||
If your Fomu is running an version older than |Foboot Version| follow the
|
||||
If your Fomu is running an version older than |Foboot Version|, follow the
|
||||
:ref:`bootloader-update` section.
|
||||
|
||||
.. toctree::
|
||||
|
@ -3,8 +3,7 @@
|
||||
Required Software
|
||||
#################
|
||||
|
||||
.. note::
|
||||
|
||||
.. NOTE::
|
||||
If you’re taking this workshop as a class, the toolchains are provided
|
||||
on the USB disk.
|
||||
|
||||
@ -13,7 +12,7 @@ and Windows, via `Fomu Toolchain <https://github.com/im-tomu/fomu-toolchain/rele
|
||||
Debian packages are also `available for Raspberry Pi <https://github.com/im-tomu/fomu-raspbian-packages>`__.
|
||||
|
||||
To install the software, extract it somewhere on your computer, then
|
||||
open up a terminal window and add that directory to your PATH:
|
||||
open up a terminal window and add that directory to your ``PATH``:
|
||||
|
||||
.. tabs::
|
||||
|
||||
@ -37,9 +36,9 @@ open up a terminal window and add that directory to your PATH:
|
||||
|
||||
C:\> PATH=[path-to-toolchain]\bin;%PATH%
|
||||
|
||||
Examples in :ref:`HDLs:VHDL` and :ref:`HDLs:mixed` use ghdl-yosys-plugin, which
|
||||
looks for standard libraries in the path used when GHDL was configured/built.
|
||||
Therefore, when the toolchain is extracted to an arbitrary location, `GHDL_PREFIX`
|
||||
Examples in :ref:`HDLs:VHDL` and :ref:`HDLs:mixed` use `ghdl-yosys-plugin <https://github.com/ghdl/ghdl-yosys-plugin>`_,
|
||||
which looks for standard libraries in the path used when GHDL was configured/built.
|
||||
Therefore, when the toolchain is extracted to an arbitrary location, ``GHDL_PREFIX``
|
||||
needs to be set:
|
||||
|
||||
.. tabs::
|
||||
@ -98,7 +97,6 @@ the following output;
|
||||
|
||||
Type ``exit`` to quit ``yosys``.
|
||||
|
||||
.. note::
|
||||
|
||||
.. NOTE::
|
||||
See the README of `Fomu Toolchain <https://github.com/im-tomu/fomu-toolchain/releases/latest>`_
|
||||
for a complete list of the tools included in the toolchain.
|
||||
|