441 lines
12 KiB
HTML
441 lines
12 KiB
HTML
<!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 "xobs" 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 DFF (output reg Q, input C, D, R);
|
|
always @(posedge C)
|
|
if (~R) begin
|
|
Q <= 1'b0;
|
|
end else begin
|
|
Q <= D;
|
|
end
|
|
endmodule
|
|
</code></pre>
|
|
</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</li>
|
|
<li>2x I2C and 2x SPI</li>
|
|
<li>8 16-bit DSP units</li>
|
|
<li>Warmboot capability</li>
|
|
</ol>
|
|
</section>
|
|
|
|
<section>
|
|
<h2>What is Fomu?</h2>
|
|
<ul>
|
|
<li>ICE40UP5K in your USB port</li>
|
|
<li>2MB flash memory</li>
|
|
<li>Four edge-plated pads</li>
|
|
<li>ESD protection</li>
|
|
<li>USB implemented in HDL</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>
|
|
</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 Machine Model</h2>
|
|
</section>
|
|
|
|
<section>
|
|
<h2>Wishbone Interface</h2>
|
|
</section>
|
|
|
|
<section>
|
|
<h2>Wishbone Bridge</h2>
|
|
</section>
|
|
|
|
<section>
|
|
<h2>Interacting with LEDD directly</h2>
|
|
</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> |