index: add some notes

Signed-off-by: Sean Cross <sean@xobs.io>
This commit is contained in:
Sean Cross 2019-08-19 15:26:38 +08:00
parent a01702f0dc
commit 40f22ea04e

View File

@ -37,41 +37,41 @@
/*********************************************
* ZOOM REVERSE TRANSITION (i.e. zoom out)
*********************************************/
.reveal .slides section[data-transition=zoomrev],
.reveal.zoomrev .slides section:not([data-transition]) {
transition-timing-function: ease;
}
.reveal .slides section[data-transition=zoomrev],
.reveal.zoomrev .slides section:not([data-transition]) {
transition-timing-function: ease;
}
.reveal .slides > section[data-transition=zoomrev].past,
.reveal .slides > section[data-transition~=zoomrev-out].past,
.reveal.zoomrev .slides > section:not([data-transition]).past {
visibility: hidden;
-webkit-transform: scale(0.2);
transform: scale(0.2);
}
.reveal .slides>section[data-transition=zoomrev].past,
.reveal .slides>section[data-transition~=zoomrev-out].past,
.reveal.zoomrev .slides>section:not([data-transition]).past {
visibility: hidden;
-webkit-transform: scale(0.2);
transform: scale(0.2);
}
.reveal .slides > section[data-transition=zoomrev].future,
.reveal .slides > section[data-transition~=zoomrev-in].future,
.reveal.zoomrev .slides > section:not([data-transition]).future {
visibility: hidden;
-webkit-transform: scale(16);
transform: scale(16);
}
.reveal .slides>section[data-transition=zoomrev].future,
.reveal .slides>section[data-transition~=zoomrev-in].future,
.reveal.zoomrev .slides>section:not([data-transition]).future {
visibility: hidden;
-webkit-transform: scale(16);
transform: scale(16);
}
.reveal .slides > section > section[data-transition=zoomrev].past,
.reveal .slides > section > section[data-transition~=zoomrev-out].past,
.reveal.zoomrev .slides > section > section:not([data-transition]).past {
-webkit-transform: translate(0, 150%);
transform: translate(0, 150%);
}
.reveal .slides>section>section[data-transition=zoomrev].past,
.reveal .slides>section>section[data-transition~=zoomrev-out].past,
.reveal.zoomrev .slides>section>section:not([data-transition]).past {
-webkit-transform: translate(0, 150%);
transform: translate(0, 150%);
}
.reveal .slides > section > section[data-transition=zoomrev].future,
.reveal .slides > section > section[data-transition~=zoomrev-in].future,
.reveal.zoomrev .slides > section > section:not([data-transition]).future {
-webkit-transform: translate(0, -150%);
transform: translate(0, -150%);
}
</style>
.reveal .slides>section>section[data-transition=zoomrev].future,
.reveal .slides>section>section[data-transition~=zoomrev-in].future,
.reveal.zoomrev .slides>section>section:not([data-transition]).future {
-webkit-transform: translate(0, -150%);
transform: translate(0, -150%);
}
</style>
</head>
@ -80,14 +80,18 @@
<!-- Start of main presentation -->
<div class="reveal">
<div class="footer">
<div class="url">Slides: <a href="https://p.xobs.io/camp19/">p.xobs.io/camp</a> &nbsp; Software: <a href="https://fomu.im/camp19">fomu.im/camp19</a></div>
<div class="url">Slides: <a href="https://p.xobs.io/camp19/">p.xobs.io/camp19</a> &nbsp; Software: <a
href="https://fomu.im/camp19">fomu.im/camp19</a></div>
<span class="theme">CCC Camp 2019</span><span class="hashtag"> | #CCCamp</span><span class="twitter"> |
@tomu_im</span>
</div>
<div class="slides">
<section>
<p>
Download Software from <a href="https://fomu.im/camp19">fomu.im/camp19</a>
Software is available on the USB drive marked "Fomu Workshop"
</p>
<p>
Or, download software from <a href="https://fomu.im/camp19">fomu.im/camp19</a>
</p>
</section>
@ -95,7 +99,8 @@
<h1>Fomu: An FPGA in your USB Port</h1>
<h4>A whirlwind introduction to Fomu; a workshop in three levels</h4>
<p align="right">
<small>Sean Cross - <a href="https://xobs.io/">https://xobs.io/</a> - @xobs</small>
<small>Sean "xobs" Cross - <a href="https://xobs.io/">https://xobs.io/</a> - @xobs</small>
<small>Tim "mithro" Ansell - <a href="https://github.com/timvideos/litex-buildenv/wiki/">https://github.com/timvideos/litex-buildenv/wiki/</a> - @mithro</small>
</p>
</section>
@ -109,6 +114,11 @@
<li>FPGA / HDL</li>
</ol>
</p>
<aside class="notes">
The overarching idea behind Fomu is to take a top-down approach to hardware design. Start at
something familiar, such as Python, and keep drilling down until you are no longer interested in
going further.
</aside>
</section>
<section>
@ -118,6 +128,10 @@
<li>What is an FPGA, and what is Fomu?</li>
<li>Working with Fomu using Python, RISC-V, and HDL</li>
</ol>
<aside class="notes">
Broadly, this workshop will cover three parts: What do you need to get started with Fomu, what is an
FPGA and why is Fomu special, and finally how to work with Fomu at three different levels.
</aside>
</section>
<section>
@ -130,6 +144,11 @@
<li>FPGA Toolchain</li>
<li>Python 3</li>
</ol>
<aside class="notes">
You require all of the software on this list. This software is provided on the USB drive that's
provided, or you can get them from <a
href="https://github.com/im-tomu/fomu-toolchain/releases">https://github.com/im-tomu/fomu-toolchain/releases</a>.
</aside>
</section>
</section>
@ -137,135 +156,143 @@
<section>
<h2>What is an FPGA?</h2>
<img data-src="img/ice40-lut.png" alt="SB_LUT4">
<!--
<p>
An FPGA is a chip that executes logic.
</p>
<p>
FPGAs are measured in resources called LUTs or LCs.
</p>
-->
</section>
<aside clas="notes">
An FPGA is an array of gates that's field-programmable. A more useful definition might be "a
chip you can reconfigure". Most chips are collections of transistors that take two inputs and
have one output. FPGAs have collections of transistors that look like this -- they take multiple
inputs and produce multiple outputs. On Fomu, the basic building block is a 4-input 1-output
lookup table called an "LC4". These are so important to FPGAs that the part number usually
contains how many LUTs there are. The Fomu has a UP5K, which has about 5000 LUTs. The NeTV had
an LX9, which had 9000 LUTs. The NeTV2 has an XC7A35T, which has 35000 LUTs.
</aside>
</section>
<section>
<h2>What is an FPGA?</h2>
<table style="transform: scale(.80) translate(-15%)">
<tr>
<th></th>
<th>0</th>
<th>1</th>
<th>2</th>
<th>3</th>
<th>4</th>
<th>5</th>
<th>6</th>
<th>7</th>
<th>8</th>
<th>9</th>
<th>10</th>
<th>11</th>
<th>12</th>
<th>13</th>
<th>14</th>
<th>15</th>
</tr>
<tr>
<td>IO0</td>
<td>0</td>
<td>0</td>
<td>0</td>
<td>0</td>
<td>0</td>
<td>0</td>
<td>0</td>
<td>0</td>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
</tr>
<tr>
<td>IO1</td>
<td>0</td>
<td>0</td>
<td>0</td>
<td>0</td>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
<td>0</td>
<td>0</td>
<td>0</td>
<td>0</td>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
</tr>
<tr>
<td>IO2</td>
<td>0</td>
<td>0</td>
<td>1</td>
<td>1</td>
<td>0</td>
<td>0</td>
<td>1</td>
<td>1</td>
<td>0</td>
<td>0</td>
<td>1</td>
<td>1</td>
<td>0</td>
<td>0</td>
<td>1</td>
<td>1</td>
</tr>
<tr>
<td>IO3</td>
<td>0</td>
<td>1</td>
<td>0</td>
<td>1</td>
<td>0</td>
<td>1</td>
<td>0</td>
<td>1</td>
<td>0</td>
<td>1</td>
<td>0</td>
<td>1</td>
<td>0</td>
<td>1</td>
<td>0</td>
<td>1</td>
</tr>
<tr>
<td>O</td>
<td>?</td>
<td>?</td>
<td>?</td>
<td>?</td>
<td>?</td>
<td>?</td>
<td>?</td>
<td>?</td>
<td>?</td>
<td>?</td>
<td>?</td>
<td>?</td>
<td>?</td>
<td>?</td>
<td>?</td>
<td>?</td>
</tr>
</table>
</section>
<section>
<h2>What is an FPGA?</h2>
<table style="transform: scale(.80) translate(-15%)">
<tr>
<th></th>
<th>0</th>
<th>1</th>
<th>2</th>
<th>3</th>
<th>4</th>
<th>5</th>
<th>6</th>
<th>7</th>
<th>8</th>
<th>9</th>
<th>10</th>
<th>11</th>
<th>12</th>
<th>13</th>
<th>14</th>
<th>15</th>
</tr>
<tr>
<td>IO0</td>
<td>0</td>
<td>0</td>
<td>0</td>
<td>0</td>
<td>0</td>
<td>0</td>
<td>0</td>
<td>0</td>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
</tr>
<tr>
<td>IO1</td>
<td>0</td>
<td>0</td>
<td>0</td>
<td>0</td>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
<td>0</td>
<td>0</td>
<td>0</td>
<td>0</td>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
</tr>
<tr>
<td>IO2</td>
<td>0</td>
<td>0</td>
<td>1</td>
<td>1</td>
<td>0</td>
<td>0</td>
<td>1</td>
<td>1</td>
<td>0</td>
<td>0</td>
<td>1</td>
<td>1</td>
<td>0</td>
<td>0</td>
<td>1</td>
<td>1</td>
</tr>
<tr>
<td>IO3</td>
<td>0</td>
<td>1</td>
<td>0</td>
<td>1</td>
<td>0</td>
<td>1</td>
<td>0</td>
<td>1</td>
<td>0</td>
<td>1</td>
<td>0</td>
<td>1</td>
<td>0</td>
<td>1</td>
<td>0</td>
<td>1</td>
</tr>
<tr>
<td>O</td>
<td>?</td>
<td>?</td>
<td>?</td>
<td>?</td>
<td>?</td>
<td>?</td>
<td>?</td>
<td>?</td>
<td>?</td>
<td>?</td>
<td>?</td>
<td>?</td>
<td>?</td>
<td>?</td>
<td>?</td>
<td>?</td>
</tr>
</table>
<aside class="notes">
A LUT is a lookup table. The value of the output depends on the value of all the inputs. You can
make arbitrary boolean logic here. For example, we could make a LUT that performs the logical
AND of all the inputs, and set it so that it only outputs a "1" if all of the inputs are 1. Or
we can make a NAND gate by taking the inverse. Each one of those 5000 LUTs in Fomu has a truth
table like this that it evaluates in real time.
</aside>
</section>
<section>
<h2>What is an FPGA?</h2>
@ -280,6 +307,11 @@
endmodule
</code></pre>
<img class="fragment" data-src="img/verilog-synthesis.png" alt="Verilog Synthesis">
<aside class="notes">
It gets really tedious to be thinking about lookup tables all the time, so humans created programming languages to do it for them. This is an example of Verilog code. It makes a simple counter that outputs the xor of some values.
In order to turn this Verilog code into actual LUTs, we run it through a synthesizer. Much like how a compiler turns programming language into CPU opcodes, a synthesizer turns Verilog code into lookup tables
</aside>
</section>
<section>
@ -314,11 +346,11 @@
</section>
<section>
<h2>Fomu Block Design Diagram</h2>
<img data-src="img/fomu-block-diagram.png" alt="Fomu block diagram">
</section>
<h2>Fomu Block Design Diagram</h2>
<img data-src="img/fomu-block-diagram.png" alt="Fomu block diagram">
</section>
<section>
<section>
<h2>What is this PCB?</h2>
<img data-src="img/tomu-fpga-evt-1-small.jpg" alt="Fomu EVT1">
<h3>Fomu EVT1</h3>
@ -344,12 +376,12 @@
</p> -->
</section>
<section>
<h2>Misleading Datasheets</h2>
<img data-src="img/xtal-datasheet-icon.jpg" alt="Footprint from Crystal">
</section>
<section>
<h2>Misleading Datasheets</h2>
<img data-src="img/xtal-datasheet-icon.jpg" alt="Footprint from Crystal">
</section>
<section>
<section>
<h2>What modifications does it have?</h2>
<ul>
<li>Shorting out two zero-ohm resistors (R7, PU)</li>
@ -376,19 +408,19 @@
<section>
<section>
<h2>Working with Fomu</h2>
</section>
</section>
<section>
<h2>FAT Bootloader</h2>
<ul>
<li>Presents itself as a USB disk</li>
<li>Drag and drop files to program</li>
<li>Multiple interpreter support</li>
</ul>
<div>
<img data-src="img/under-construction.gif" class="fragment">
</div>
</section>
<section>
<h2>FAT Bootloader</h2>
<ul>
<li>Presents itself as a USB disk</li>
<li>Drag and drop files to program</li>
<li>Multiple interpreter support</li>
</ul>
<div>
<img data-src="img/under-construction.gif" class="fragment">
</div>
</section>
<section>
<h2>"fail safe" bootloader</h2>
@ -448,28 +480,28 @@ $ dfu-util -D new-image.dfu # Load new program</code></pre>
>>> rgb.mode("error")
>>>
</code></pre>
</section>
</section>
<section>
<h2>Read SPI ID</h2>
<pre><code class="python" data-trim>
<section>
<h2>Read SPI ID</h2>
<pre><code class="python" data-trim>
>>> spi = fomu.spi()
>>> hex(spi.id())
'0xc2152815'
>>>
</code></pre>
</section>
</section>
<section>
<h2>Memory-Mapped Registers</h2>
<pre><code class="cpp">#define CSR_VERSION_MAJOR_ADDR 0xe0007000
<section>
<h2>Memory-Mapped Registers</h2>
<pre><code class="cpp">#define CSR_VERSION_MAJOR_ADDR 0xe0007000
#define CSR_VERSION_MINOR_ADDR 0xe0007004
#define CSR_VERSION_REVISION_ADDR 0xe0007008</code></pre>
<pre class="fragment"><code class="python">>>> import machine
<pre class="fragment"><code class="python">>>> import machine
>>> machine.mem32[0xe0007000]
1
>>></code></pre>
</section>
</section>
<section>
<h2>RGB LED Driver reference</h2>
@ -533,7 +565,7 @@ $ dfu-util -D new-image.dfu # Load new program</code></pre>
#define CSR_VERSION_GITEXTRA_ADDR 0xe000701c
#define CSR_VERSION_GITEXTRA_SIZE 2
</code></pre>
Excerpt from <code>csr.h</code>
Excerpt from <code>csr.h</code>
</section>
<section>
@ -566,9 +598,9 @@ $ wishbone-tool --pid 0x5bf0 0xe0006800 0xff</code></pre>
OBJCOPY riscv-blink.bin
IHEX riscv-blink.ihex
$ </code></pre>
<p>
From <code>riscv-blink</code> directory in <code>teardown2019-workshop</code>
</p>
<p>
From <code>riscv-blink</code> directory in <code>teardown2019-workshop</code>
</p>
</section>
<section>
@ -583,12 +615,12 @@ $ </code></pre>
int i = 0;
while (1) {
i++;</code></pre>
</section>
</section>
<section>
<h2>Other RISC-V Programs</h2>
riscv-usb-cdcacm: echo characters back after adding 1
</section>
<section>
<h2>Other RISC-V Programs</h2>
riscv-usb-cdcacm: echo characters back after adding 1
</section>
</section>
<section>
@ -597,18 +629,18 @@ $ </code></pre>
</section>
<section>
<h2>Yosys and NextPNR</h2>
<ul>
<li>Timing Driven!</li>
</ul>
<pre><code>Max frequency for clock 'clk12': 24.63 MHz (PASS at 12.00 MHz)
<h2>Yosys and NextPNR</h2>
<ul>
<li>Timing Driven!</li>
</ul>
<pre><code>Max frequency for clock 'clk12': 24.63 MHz (PASS at 12.00 MHz)
Max frequency for clock 'clk48_1': 60.66 MHz (PASS at 48.00 MHz)
Max frequency for clock 'clkraw': 228.05 MHz (PASS at 48.00 MHz)</code></pre>
</section>
<section>
<h2>Blinking an LED</h2>
<pre><code>$ make FOMU_REV=evt
<h2>Blinking an LED</h2>
<pre><code>$ make FOMU_REV=evt
...
20 warnings, 0 errors
PACK blink.bin
@ -617,72 +649,72 @@ $ dfu-util -D blink.bin</code></pre>
</section>
<section>
<h2>LiteX and MiGen</h2>
<ol>
<li>Define hardware in Python</li>
<li>Evaluate Python to produce netlist</li>
<li>Synthesize netlist to FPGA</li>
</ol>
<h2>LiteX and MiGen</h2>
<ol>
<li>Define hardware in Python</li>
<li>Evaluate Python to produce netlist</li>
<li>Synthesize netlist to FPGA</li>
</ol>
</section>
<section>
<h2>lxbuildenv.py</h2>
<ol>
<li>Python environment using native interpreter</li>
<li>Very stable, good for hardware projects</li>
<li>Should work with system Python</li>
<li>Runs on Linux, Windows, Raspberry Pi</li>
</ol>
</section>
<section>
<h2>lxbuildenv.py</h2>
<ol>
<li>Python environment using native interpreter</li>
<li>Very stable, good for hardware projects</li>
<li>Should work with system Python</li>
<li>Runs on Linux, Windows, Raspberry Pi</li>
</ol>
</section>
<section>
<h2>Why do we need a CPU?</h2>
<section>
<h2>Why do we need a CPU?</h2>
<img data-src="img/litex-design.png" alt="LiteX Design">
</section>
</section>
<section>
<h2>What if we remove the CPU?</h2>
<ul>
<li>Workshop project has no CPU</li>
<li>DummyUsb module automatically enumerates</li>
<li>Wishbone Debug Bridge still accessible</li>
</ul>
</section>
<section>
<h2>What if we remove the CPU?</h2>
<ul>
<li>Workshop project has no CPU</li>
<li>DummyUsb module automatically enumerates</li>
<li>Wishbone Debug Bridge still accessible</li>
</ul>
</section>
<section>
<h2>Build Workshop Module</h2>
<pre><code>$ python3 workshop.py --placer heap
<section>
<h2>Build Workshop Module</h2>
<pre><code>$ python3 workshop.py --placer heap
...
5 warnings, 0 errors
$ </code></pre>
</section>
</section>
<section>
<h2>Load onto Fomu</h2>
<pre><code>$ dfu-util -D build/gateware/top.bin
<section>
<h2>Load onto Fomu</h2>
<pre><code>$ dfu-util -D build/gateware/top.bin
Download [=========================] 100% 104090 bytes
Download done.
$ </code></pre>
</section>
</section>
<section>
<h2>Write a value to RAM</h2>
<pre><code>$ wishbone-tool --pid 0x5bf0 0x10000000
<section>
<h2>Write a value to RAM</h2>
<pre><code>$ wishbone-tool --pid 0x5bf0 0x10000000
Value at 10000000: 0baf801e
$ wishbone-tool --pid 0x5bf0 0x10000000 0x12345678
$ wishbone-tool --pid 0x5bf0 0x10000000
Value at 10000000: 12345678
$ </code></pre>
</section>
</section>
<section>
<h2>Adding Hardware</h2>
<img data-src="img/ice40-rgb.jpg" alt="Schematic of RGB block">
</section>
<section>
<h2>Adding Hardware</h2>
<img data-src="img/ice40-rgb.jpg" alt="Schematic of RGB block">
</section>
<section>
<h2>Technology Library Reference</h2>
<pre><code class="verilog">// Verilog Instantiation
<section>
<h2>Technology Library Reference</h2>
<pre><code class="verilog">// Verilog Instantiation
SB_RGBA_DRV RGBA_DRIVER (
.CURREN(ENABLE_CURR),
.RGBLEDEN(ENABLE_RGBDRV),
@ -697,11 +729,11 @@ defparam RGBA_DRIVER.CURRENT_MODE = "0b0";
defparam RGBA_DRIVER.RGB0_CURRENT = "0b111111";
defparam RGBA_DRIVER.RGB1_CURRENT = "0b111111" ;
defparam RGBA_DRIVER.RGB2_CURRENT = "0b111111";</code></pre>
<p>SBTICETechnologyLibrary201504.pdf page 147</p>
</section>
<section>
<h2>RGB Block</h2>
<pre><code class="python" style="font-size: 18px; line-height: 22px">class FomuRGB(Module, AutoCSR):
<p>SBTICETechnologyLibrary201504.pdf page 147</p>
</section>
<section>
<h2>RGB Block</h2>
<pre><code class="python" style="font-size: 18px; line-height: 22px">class FomuRGB(Module, AutoCSR):
def __init__(self, pads):
self.output = CSRStorage(3)
self.specials += Instance("SB_RGBA_DRV",
@ -718,11 +750,11 @@ defparam RGBA_DRIVER.RGB2_CURRENT = "0b111111";</code></pre>
p_RGB1_CURRENT = "0b000011",
p_RGB2_CURRENT = "0b000011",
)</code></pre>
</section>
</section>
<section>
<h2>Instantiating FomuRGB</h2>
<pre><code class="diff">@@ -55,6 +75,10 @@ class BaseSoC(SoCCore):
<section>
<h2>Instantiating FomuRGB</h2>
<pre><code class="diff">@@ -55,6 +75,10 @@ class BaseSoC(SoCCore):
with_ctrl=False,
**kwargs)
@ -733,23 +765,23 @@ defparam RGBA_DRIVER.RGB2_CURRENT = "0b111111";</code></pre>
# UP5K has single port RAM....
# Use this as CPU RAM.
spram_size = 128*1024</code></pre>
</section>
</section>
<section>
<h2>Interacting with the CSR</h2>
<pre><code>csr_register,rgb_output,0xe0006800,1,rw</code></pre>
<p>From <code>test/csr.csv</code></p>
</section>
<section>
<h2>Interacting with the CSR</h2>
<pre><code>csr_register,rgb_output,0xe0006800,1,rw</code></pre>
<p>From <code>test/csr.csv</code></p>
</section>
<section>
<section>
<h2>VexRiscv</h2>
</section>
</section>
</section>
<section>
<h2>Thank you</h2>
<h2>Lunch Time!</h2>
</section>
<section>
<h2>Thank you</h2>
<h2>Lunch Time!</h2>
</section>
</div>
</div> <!-- class="reveal" -->
<!-- End of main presentation -->