cccamp-2019/index.html

473 lines
14 KiB
HTML
Raw Normal View History

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Fomu: An FPGA in your USB Port</title>
<meta name="description" content="A framework for easily creating beautiful presentations using HTML">
<meta name="author" content="Sean &quot;xobs&quot; Cross">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<link rel="stylesheet" href="css/reveal.css">
<link rel="stylesheet" href="css/theme/solarized.css" id="theme">
<!-- Theme used for syntax highlighting of code -->
<link rel="stylesheet" href="lib/css/zenburn.css">
<!-- Printing and PDF exports -->
<script>
var link = document.createElement('link');
link.rel = 'stylesheet';
link.type = 'text/css';
link.href = window.location.search.match(/print-pdf/gi) ? 'css/print/pdf.css' : 'css/print/paper.css';
document.getElementsByTagName('head')[0].appendChild(link);
</script>
<!--[if lt IE 9]>
<script src="lib/js/html5shiv.js"></script>
<![endif]-->
<style>
/*********************************************
* 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].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 > 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>
</head>
<body>
<!-- Start of main presentation -->
<div class="reveal">
<div class="footer">
<a class="url" href="https://p.xobs.io/td19/">p.xobs.io/td19</a>
<span class="theme">Teardown 2019</span><span class="hashtag"> | #teardown2019</span><span class="twitter"> |
@teardown</span>
</div>
<div class="slides">
<section>
<h2>Fomu: an FPGA in your USB Port</h2>
<img src="img/tomu-fomu-case-superwide.jpg">
<p>
Pre-order now on Crowd Supply! <a href="https://t.xobs.io/fomu">t.xobs.io/fomu</a>
</p>
</section>
<section data-background-image="css/theme/lca2019-title-bg-transparent.svg">
<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>
</p>
</section>
<section>
<h2>Levels of Fomu</h2>
<p>
Fomu aims to be accessable on three levels:
<ol>
<li>Python / Interpreted</li>
<li>RISC-V</li>
<li>Verilog / FPGA</li>
</ol>
</p>
</section>
<section>
<h2>Workshop Outline</h2>
<ol>
<li>What do I need to get started?</li>
<li>What is an FPGA, and what is Fomu?</li>
<li>What makes Fomu special?</li>
<li>What can I do with Fomu?</li>
</ol>
</section>
<section>
<section>
<h2>What do I need to get started?</h2>
<ol>
<li>DFU utilities</li>
<li>Serial console</li>
<li>RISC-V toolchain</li>
<li>Synthesis</li>
<li>Place-and-Route</li>
<li>Packer</li>
<li>Python 3</li>
</ol>
</section>
</section>
<section>
<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>
<section>
<h2>What is an FPGA?</h2>
<pre><code class="verilog" data-trim>
module example (output reg [0:5] Q, input C);
reg [0:8] counter;
always @(posedge C)
begin
counter <= counter + 1'b1;
Q = counter[7] ^ counter[5] | counter<<2;
end
endmodule
</code></pre>
<img class="fragment" data-src="img/verilog-synthesis.png" alt="Verilog Synthesis">
</section>
<section>
<h2>About the ICE40UP5K</h2>
<ol>
<li>5280 4-input LUTs (LC)</li>
<li>16 kilobytes BRAM</li>
<li class="fragment highlight-blue">128 kilobytes "SPRAM"</li>
<li>Current-limited 3-channel LED driver</li>
<li>2x I2C and 2x SPI</li>
<li>8 16-bit DSP units</li>
<li class="fragment highlight-blue">Warmboot capability</li>
</ol>
</section>
<section>
<h2>What is Fomu?</h2>
<ul>
<li>ICE40UP5K</li>
<li>2MB flash memory</li>
<li>Four edge-plated pads</li>
<li>ESD protection</li>
<li>USB implemented in HDL</li>
<li class="fragment highlight-blue">Fits in your USB port</li>
</ul>
<!-- <p>
Fomu is an FPGA that fits in your USB port. It has foru buttons, 2 MB of SPI flash, an RGB LED, and an ICE40UP5K with 5280 LCs. It also has 128 kB of dedicated RAM, not counting the block RAM.
Unlike many other PCBs, Fomu does not have a separate USB controller chip. This means that any projects that want to use the USB port must include a USB softcore.
</p> -->
</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>
<!-- <p>
This is Fomu EVT1. This is the original stretch prototype of Fomu. The schematics are the same, but much has changed:
* Name changed from Tomu-FPGA to Fomu
* Package changed from SG48 to WLCSP32
Additionally, some patches were needed to get this PCB working:
* SO-8 for SPI flash was too small
* Crystal footprint was upside-down
These are yours to take home with you!
Differences between EVT1 and EVT3:
* Silkscreen on Raspberry Pi header
* Populate Raspberry Pi header
* Add PMOD pins to touchpads
* Swap PMODa pins for I3C
</p> -->
</section>
<section>
<h2>What modifications does it have?</h2>
<ul>
<li>Shorting out two zero-ohm resistors (R7, PU)</li>
<li>Programming SPI flash</li>
<li>Bending SPI flash pins inward (U4)</li>
<li>Mounting crystal on its side (U7)</li>
<li>Attaching power to crystal</li>
</ul>
</section>
<section>
<h2>Fomu Block Design Diagram</h2>
<img data-src="img/fomu-block-diagram.png" alt="Fomu block diagram">
</section>
<section>
<h2>Fomu SPI Flash Layout</h2>
<img data-src="img/fomu-memory-layout.png" alt="Fomu memory layout">
<!-- <ol>
<li>Bootloader</li>
<li>Recovery</li>
<li>Magic constants</li>
<li>Interpreters</li>
<li>Updates</li>
</ol> -->
</section>
</section>
<section>
<section>
<h2>Working with Fomu</h2>
</section>
<section>
<h2>"fail safe" bootloader</h2>
Using dfu
</section>
<section>
<h2>Updating Fomu</h2>
<pre><code>$ dfu-util -l
Found DFU: [1209:5bf0] name="Fomu DFU Bootloader v1.7.2"
$ dfu-util -D evt-installable.dfu
Download [========= ] 36% 38912 bytes
Download done.
$ dfu-util -l
Found DFU: [1209:5bf0] name="Fomu DFU Bootloader v1.8.1"
$</code></pre>
</section>
</section>
<section>
<section>
<h2>Python / Interpreted</h2>
<ol>
<li><strong>Goal:</strong> Multiple interpreters, auto-reload, USB disk interface</li>
<li><strong>Now:</strong> MicroPython binary</li>
</ol>
</section>
<section>
<h2>Loading Programs onto Fomu</h2>
<pre><code>
$ dfu-util -l
Found DFU: [1209:5bf0] name="Fomu DFU Bootloader v1.8.1"
$ dfu-util -e # Boot current program
$ dfu-util -D new-image.dfu # Load new program</code></pre>
<h3 class="fragment">u<code>5b f0</code>mu</h3>
</section>
<section>
<h2>Loading MicroPython</h2>
<pre><code>$ dfu-util -D micropython-fomu.dfu</code></pre>
</section>
<section>
<h2>Connecting via serial</h2>
<pre class="fragment"><code>screen /dev/cu.usbserial*</code></pre>
<pre class="fragment"><code>screen /dev/ttyACM*</code></pre>
<pre class="fragment"><code>Teraterm</code></pre>
<pre class="fragment"><code>MicroPython v1.10-296-g0a5a77a on 2019-06-18; fomu with vexriscv
>>></code></pre>
</section>
<section>
<h2>Interacting with Fomu</h2>
<pre><code class="python" data-trim>
>>> import fomu
>>> rgb = fomu.rgb()
>>> rgb.mode("error")
>>>
</code></pre>
</section>
<section>
<h2>RGB LEDD reference</h2>
<img data-src="img/ice40-ledd.png" alt="ICE40 LEDD registers">
<pre class="fragment"><code class="python" data-trim>>>> rgb.write_raw(0b0001, 255)
>>> rgb.write_raw(0b1010, 14)
>>> rgb.write_raw(0b1011, 1)
>>>
</code></pre>
</section>
<section>
<h2>Future Work</h2>
CircuitPython, etc.
</section>
</section>
<section>
<section>
<h2>RISC-V code</h2>
</section>
<section>
<h2>LiteX Model</h2>
<img data-src="img/litex-design.png" alt="LiteX Design">
</section>
<section>
<h2>Wishbone Bridge</h2>
<img data-src="img/wishbone-usb-debug-bridge.png" alt="Wishbone bridge">
</section>
<section>
<h2>CSR Access</h2>
<pre><code class="cpp">#define CSR_VERSION_MAJOR_ADDR 0xe0007000L
#define CSR_VERSION_MAJOR_SIZE 1
#define CSR_VERSION_MINOR_ADDR 0xe0007004L
#define CSR_VERSION_MINOR_SIZE 1
#define CSR_VERSION_REVISION_ADDR 0xe0007008L
#define CSR_VERSION_REVISION_SIZE 1
#define CSR_VERSION_GITREV_ADDR 0xe000700cL
#define CSR_VERSION_GITREV_SIZE 4
#define CSR_VERSION_GITEXTRA_ADDR 0xe000701cL
#define CSR_VERSION_GITEXTRA_SIZE 2
</code></pre>
Excerpt from <code>csr.h</code>
</section>
<section>
<h2>Reading CPU Version</h2>
<pre><code class="sh">$ wishbone-tool --pid 0x5bf0 0xe0007000
Value at e0007000: 00000001
$ wishbone-tool --pid 0x5bf0 0xe0007004
Value at e0007004: 00000008
$ wishbone-tool --pid 0x5bf0 0xe0007008
Value at e0007008: 00000001</code></pre>
</section>
<section>
<h2>Interacting with LEDD directly</h2>
<img data-src="img/ice40-ledd.png" alt="ICE40 LEDD registers">
<pre class="fragment"><code class="cpp">#define CSR_RGB_DAT_ADDR 0xe0006800L
#define CSR_RGB_ADDR_ADDR 0xe0006804L</code></pre>
<pre class="fragment"><code>$ wishbone-tool --pid 0x5bf0 0xe0006804 1
$ wishbone-tool --pid 0x5bf0 0xe0006800 0xff</code></pre>
</section>
<section>
<h2>Writing RISC-V Code</h2>
</section>
</section>
<section>
<section>
<h2>Hardware Description Language</h2>
</section>
<section>
<h2>Yosys and NextPNR</h2>
</section>
<section>
<h2>Blinking an LED</h2>
</section>
<section>
<h2>LiteX and MiGen</h2>
</section>
<section>
<h2>VexRiscv</h2>
</section>
</section>
</div>
</div> <!-- class="reveal" -->
<!-- End of main presentation -->
<!-- Start of configuration section -->
<script src="lib/js/head.min.js"></script>
<script src="js/reveal.js"></script>
<script>
var presenter = !!Reveal.getQueryHash().s;
// More info https://github.com/hakimel/reveal.js#configuration
Reveal.initialize({
controls: presenter ? false : true,
progress: true,
history: true,
center: true,
controlsTutorial: presenter ? false : true,
slideNumber: presenter ? null : 'c/t',
// The "normal" size of the presentation, aspect ratio will be preserved
// when the presentation is scaled to fit different resolutions. Can be
// specified using percentage units.
width: 960,
height: 700,
// Factor of the display size that should remain empty around the content
margin: 0.1,
multiplex: {
url: 'https://p.xobs.io/',
id: 'cbd6556886c2825d',
secret: Reveal.getQueryHash().s || null
},
// Bounds for smallest/largest possible scale to apply to content
minScale: 0.02,
maxScale: 5.5,
transition: 'slide', // none/fade/slide/convex/concave/zoom
// More info https://github.com/hakimel/reveal.js#dependencies
dependencies: [
{ src: 'lib/js/classList.js', condition: function () { return !document.body.classList; } },
{ src: 'plugin/markdown/marked.js', condition: function () { return !!document.querySelector('[data-markdown]'); } },
{ src: 'plugin/markdown/markdown.js', condition: function () { return !!document.querySelector('[data-markdown]'); } },
{ src: 'plugin/highlight/highlight.js', async: true, callback: function () { hljs.initHighlightingOnLoad(); } },
{ src: 'plugin/search/search.js', async: true },
{ src: 'plugin/zoom-js/zoom.js', async: true },
{ src: 'plugin/notes/notes.js', async: true },
{ src: 'lib/js/socket.io.js', async: true },
{
src: presenter ?
'plugin/multiplex/master.js' :
'plugin/multiplex/client.js', async: true
},
]
});
</script>
</body>
</html>