theme: add lca2020 theme

Signed-off-by: Sean Cross <sean@xobs.io>
This commit is contained in:
Sean Cross 2020-01-02 14:46:03 +08:00
parent 6f8dcb1827
commit 0737480489
2 changed files with 600 additions and 125 deletions

422
css/theme/lca2020.css Normal file
View File

@ -0,0 +1,422 @@
/**
* Black theme for reveal.js. This is the opposite of the 'white' theme.
*
* By Hakim El Hattab, http://hakim.se
*/
@import url(../../lib/font/space-mono/space-mono.css);
section.has-light-background,
section.has-light-background h1,
section.has-light-background h2,
section.has-light-background h3,
section.has-light-background h4,
section.has-light-background h5,
section.has-light-background h6 {
color: #222;
}
/*********************************************
* GLOBAL STYLES
*********************************************/
body {
background: #387A3B;
background-color: #387A3B;
}
.reveal .footer {
position: absolute;
bottom: 1em;
right: 2em;
text-align: right;
font-size: 0.5em;
width: 100%;
height: 96px;
background-image: url("lca2019-logo.svg");
background-repeat: no-repeat;
display: flex;
justify-content: flex-end;
align-items: flex-end;
z-index: 1;
}
.reveal .footer .url {
position: absolute;
padding-bottom: 30px;
}
.reveal .footer .theme {
padding-right: 80px;
}
.reveal .footer .hashtag {
padding-right: 80px;
}
@media only screen and (max-width:800px) {
.reveal .footer .url {
display: none;
}
}
@media only screen and (max-width:550px) {
.reveal .footer {
background-image: none;
}
}
@media only screen and (max-width:750px) {
.reveal .footer .twitter {
display: none;
}
}
@media only screen and (max-width:1050px) {
.reveal .footer .theme {
display: none;
}
}
@media only screen and (max-width:1300px) {
.reveal .footer .hashtag {
display: none;
}
}
.reveal {
font-family: "Space Mono", Helvetica, sans-serif;
font-size: 42px;
font-weight: normal;
color: #fff;
}
::selection {
color: #fff;
background: #bee4fd;
text-shadow: none;
}
::-moz-selection {
color: #fff;
background: #bee4fd;
text-shadow: none;
}
.reveal .slides section,
.reveal .slides section>section {
line-height: 1.3;
font-weight: inherit;
}
/*********************************************
* HEADERS
*********************************************/
.reveal h1,
.reveal h2,
.reveal h3,
.reveal h4,
.reveal h5,
.reveal h6 {
margin: 0 0 20px 0;
color: #fff;
font-family: "Space Mono", Helvetica, sans-serif;
font-weight: 600;
line-height: 1.2;
letter-spacing: normal;
text-transform: uppercase;
text-shadow: none;
word-wrap: break-word;
}
.reveal h1 {
font-size: 2.5em;
}
.reveal h2 {
font-size: 1.6em;
}
.reveal h3 {
font-size: 1.3em;
}
.reveal h4 {
font-size: 1em;
}
.reveal h1 {
text-shadow: none;
}
/*********************************************
* OTHER
*********************************************/
.reveal p {
margin: 20px 0;
line-height: 1.3;
}
/* Ensure certain elements are never larger than the slide itself */
.reveal img,
.reveal video,
.reveal iframe {
max-width: 95%;
max-height: 95%;
}
.reveal strong,
.reveal b {
font-weight: bold;
}
.reveal em {
font-style: italic;
}
.reveal ol,
.reveal dl,
.reveal ul {
display: inline-block;
text-align: left;
margin: 0 0 0 1em;
}
.reveal ol {
list-style-type: decimal;
}
.reveal ul {
list-style-type: disc;
}
.reveal ul ul {
list-style-type: square;
}
.reveal ul ul ul {
list-style-type: circle;
}
.reveal ul ul,
.reveal ul ol,
.reveal ol ol,
.reveal ol ul {
display: block;
margin-left: 40px;
}
.reveal dt {
font-weight: bold;
}
.reveal dd {
margin-left: 40px;
}
.reveal blockquote {
display: block;
position: relative;
width: 70%;
margin: 20px auto;
padding: 5px;
font-style: italic;
background: rgba(255, 255, 255, 0.05);
box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.2);
}
.reveal blockquote p:first-child,
.reveal blockquote p:last-child {
display: inline-block;
}
.reveal q {
font-style: italic;
}
.reveal pre {
display: block;
position: relative;
width: 90%;
margin: 20px auto;
text-align: left;
font-size: 0.55em;
font-family: monospace;
line-height: 1.2em;
word-wrap: break-word;
box-shadow: 0px 0px 6px rgba(0, 0, 0, 0.3);
}
.reveal code {
font-family: monospace;
text-transform: none;
}
.reveal pre code {
display: block;
padding: 5px;
overflow: auto;
max-height: 400px;
word-wrap: normal;
}
.reveal table {
margin: auto;
border-collapse: collapse;
border-spacing: 0;
}
.reveal table th {
font-weight: bold;
}
.reveal table th,
.reveal table td {
text-align: left;
padding: 0.2em 0.5em 0.2em 0.5em;
border-bottom: 1px solid;
}
.reveal table th[align="center"],
.reveal table td[align="center"] {
text-align: center;
}
.reveal table th[align="right"],
.reveal table td[align="right"] {
text-align: right;
}
.reveal table tbody tr:last-child th,
.reveal table tbody tr:last-child td {
border-bottom: none;
}
.reveal sup {
vertical-align: super;
font-size: smaller;
}
.reveal sub {
vertical-align: sub;
font-size: smaller;
}
.reveal small {
display: inline-block;
font-size: 0.6em;
line-height: 1.2em;
vertical-align: top;
}
.reveal small * {
vertical-align: top;
}
/*********************************************
* LINKS
*********************************************/
.reveal a {
color: #42affa;
text-decoration: none;
-webkit-transition: color .15s ease;
-moz-transition: color .15s ease;
transition: color .15s ease;
}
.reveal a:hover {
color: #8dcffc;
text-shadow: none;
border: none;
}
.reveal .roll span:after {
color: #fff;
background: #068de9;
}
/*********************************************
* IMAGES
*********************************************/
.reveal section img {
margin: 15px 0px;
background: rgba(255, 255, 255, 0.12);
border: 4px solid #fff;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
}
.reveal section img.plain {
border: 0;
box-shadow: none;
}
.reveal a img {
-webkit-transition: all .15s linear;
-moz-transition: all .15s linear;
transition: all .15s linear;
}
.reveal a:hover img {
background: rgba(255, 255, 255, 0.2);
border-color: #42affa;
box-shadow: 0 0 20px rgba(0, 0, 0, 0.55);
}
/*********************************************
* VIDEOS
*********************************************/
.reveal section video {
margin: 15px 0px;
background: rgba(255, 255, 255, 0.12);
border: 4px solid #fff;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
}
.reveal section video.plain {
border: 0;
box-shadow: none;
}
.reveal a video {
-webkit-transition: all .15s linear;
-moz-transition: all .15s linear;
transition: all .15s linear;
}
/*********************************************
* NAVIGATION CONTROLS
*********************************************/
.reveal .controls {
color: #42affa;
}
/*********************************************
* PROGRESS BAR
*********************************************/
.reveal .progress {
background: rgba(0, 0, 0, 0.2);
color: #42affa;
}
.reveal .progress span {
-webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
-moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
}
/*********************************************
* PRINT BACKGROUND
*********************************************/
@media print {
.backgrounds {
background-color: #222;
}
}

View File

@ -15,7 +15,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"> <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/reveal.css">
<link rel="stylesheet" href="css/theme/lca2019.css" id="theme"> <link rel="stylesheet" href="css/theme/lca2020.css" id="theme">
<!-- Theme used for syntax highlighting of code --> <!-- Theme used for syntax highlighting of code -->
<link rel="stylesheet" href="lib/css/zenburn.css"> <link rel="stylesheet" href="lib/css/zenburn.css">
@ -92,152 +92,205 @@
<small>Sean Cross - <a href="https://xobs.io/">https://xobs.io/</a> - @xobs</small> <small>Sean Cross - <a href="https://xobs.io/">https://xobs.io/</a> - @xobs</small>
</p> </p>
</section> </section>
<section> <section>
<h1>Hardware is different</h1> <aside class="notes">
<ol> This is the Open ISA miniconf, which today tends to mean FPGAs. This means that
<li>Massively Parallel</li> hardware and software are both extensible, and developers will be able to extend
</ol> the hardware in addition to making modifications to your software package.
</aside>
</section> </section>
This is the Open ISA miniconf, which today tends to mean FPGAs. This means that
hardware and software are both extensible, and developers will be able to extend
the hardware in addition to making modifications to your software package.
Undocumented hardware is bad. There are all sorts of quirks, and even if you have <section>
the source code, it can be very difficult to read. I'm the primary developer for <aside class="notes">
the Fomu project, and this talk will cover some of the issues I've run into with Undocumented hardware is bad. There are all sorts of quirks, and even if you have
respect to documentation. It is most directly related to the LiteX and Migen the source code, it can be very difficult to read. I'm the primary developer for
projects, but the concepts will carry over into any other Hardware Description the Fomu project, and this talk will cover some of the issues I've run into with
Language you may use. respect to documentation. It is most directly related to the LiteX and Migen
projects, but the concepts will carry over into any other Hardware Description
Language you may use.
</aside>
</section>
I'll briefly cover various methods of writing HDL code, then cover the rationale <section>
behind the approach we take with lxsocdoc, then give an example of how to use <aside class="notes">
lxsocdoc and how you might apply it to your language. Finally, I'll cover the I'll briefly cover various methods of writing HDL code, then cover the rationale
implications of having documented hardware and how this will help you pay it forward. behind the approach we take with lxsocdoc, then give an example of how to use
lxsocdoc and how you might apply it to your language. Finally, I'll cover the
implications of having documented hardware and how this will help you pay it forward.
</aside>
</section>
Verilog and VHDL are kind of the C or assembly of the FPGA world. They're universal, <section>
but somewhat unwieldy to use. You need to manually set up your address decoders, <aside class="notes">
and documentation is very free-form. Common approaches today involve comments in Verilog and VHDL are kind of the C or assembly of the FPGA world. They're universal,
the HDL and/or C header files. This works, but we can do better. We just need to but somewhat unwieldy to use. You need to manually set up your address decoders,
describe the hardware better. and documentation is very free-form. Common approaches today involve comments in
```//Hardware definitions of the SoC. Also is the main repo of documentation for the the HDL and/or C header files. This works, but we can do better. We just need to
//programmer-centric view of the hardware.``` describe the hardware better.
```//Hardware definitions of the SoC. Also is the main repo of documentation for the
//programmer-centric view of the hardware.```
</aside>
</section>
Fomu uses LiteX, which is related to Migen. This is a hardware description language <section>
written in Python. You write Python code and run the program, and it generates <aside class="notes">
a design file -- either Verilog code, or a Yosys netlist. There are many other Fomu uses LiteX, which is related to Migen. This is a hardware description language
alternatives such as SpinalHDL or Chisel. By writing in Python as opposed to written in Python. You write Python code and run the program, and it generates
direct Verilog, we get a lot of nice primitives. The examples from this talk a design file -- either Verilog code, or a Yosys netlist. There are many other
are taken from lxsocdoc and LiteX, but most higher-level hardware description alternatives such as SpinalHDL or Chisel. By writing in Python as opposed to
languages can take similar approaches to documentation. direct Verilog, we get a lot of nice primitives. The examples from this talk
are taken from lxsocdoc and LiteX, but most higher-level hardware description
languages can take similar approaches to documentation.
</aside>
</section>
In LiteX, two of the primitives used to expose hardware registers to the CPU softcore <section>
are CSRStorage and CSRStatus. Instead of manually wiring up a crossbar and decoding <aside class="notes">
the addresses ourselves, we just need to write `self.regname = CSRStatus(8)`, In LiteX, two of the primitives used to expose hardware registers to the CPU softcore
and the build system will wire up 8 bits of read-only memory to the target CPU. are CSRStorage and CSRStatus. Instead of manually wiring up a crossbar and decoding
Similarly, `self.othername = CSRStorage(8)` will give 8-bits of write-only memory. the addresses ourselves, we just need to write `self.regname = CSRStatus(8)`,
and the build system will wire up 8 bits of read-only memory to the target CPU.
Similarly, `self.othername = CSRStorage(8)` will give 8-bits of write-only memory.
</aside>
</section>
This works well, but exposes a new problem: Documentation. As an example, I was <section>
working with the SPI Flash block in litex, and wanted to know how the bitbang <h4>SPI Bitbang Module</h4>
driver worked. There wasn't any documentation except the source, which looked <pre><code class="python" data-trim>self.bitbang = CSRStorage(4)
like this: If(self.bitbang.storage[3],
dq.oe.eq(0)
).Else(
dq.oe.eq(1)
),
If(self.bitbang.storage[1], # CPOL=0/CPHA=0 or CPOL=1/CPHA=1 only.
self.miso.status.eq(dq.i[1])
),
dq.o.eq(Cat(self.bitbang.storage[0], Replicate(1, spi_width-1)))</code></pre>
<aside class="notes">
This works well, but exposes a new problem: Documentation. As an example, I was
working with the SPI Flash block in litex, and wanted to know how the bitbang
driver worked. There wasn't any documentation except the source, which looked
like this.
self.bitbang = CSRStorage(4) You can kind of understand it, but it does take a lot of mental power to
If(self.bitbang.storage[3], work through it. I started by creating aliases for the various elements
dq.oe.eq(0) in the storage array, but then I thought: There has to be a better way!
).Else( </aside>
dq.oe.eq(1) </section>
),
If(self.bitbang.storage[1], # CPOL=0/CPHA=0 or CPOL=1/CPHA=1 only.
self.miso.status.eq(dq.i[1])
),
dq.o.eq(Cat(self.bitbang.storage[0], Replicate(1, spi_width-1)))
You can kind of understand it, but it does take a lot of mental power to <section>
work through it. I started by creating aliases for the various elements <aside class="notes">
in the storage array, but then I thought: There has to be a better way! As an aside, Python has something called Pydoc and Docstrings. These are
comments that go at the top of functions and classes that let you describe
what a Python object is and how to use it. This is almost what we want,
except once the final SoC is generated we don't really care so much about
things like constructor arguments or method properties. Documentation for
the end user is different from documentation for the module developer.
</aside>
</section>
As an aside, Python has something called Pydoc and Docstrings. These are <section>
comments that go at the top of functions and classes that let you describe <aside class="notes">
what a Python object is and how to use it. This is almost what we want, This is when I hit upon the idea of `lxsocdoc`. The basic idea is that
except once the final SoC is generated we don't really care so much about Python is really good at introspecting Python, so let's add a little bit
things like constructor arguments or method properties. Documentation for more information to the CSR objects to make our life easier. And so, after
the end user is different from documentation for the module developer. working with the LiteX creator Florent, we refactored the bitbang
definition to this:
This is when I hit upon the idea of `lxsocdoc`. The basic idea is that self.bitbang = CSRStorage(4, fields=[
Python is really good at introspecting Python, so let's add a little bit CSRField("mosi", description="Output value for MOSI pin, valid whenever ``dir`` is ``0``."),
more information to the CSR objects to make our life easier. And so, after CSRField("clk", description="Output value for SPI CLK pin."),
working with the LiteX creator Florent, we refactored the bitbang CSRField("cs_n", description="Output value for SPI CSn pin."),
definition to this: CSRField("dir", description="Sets the direction for *ALL* SPI data pins except CLK and CSn.", values=[
("0", "OUT", "SPI pins are all output"),
("1", "IN", "SPI pins are all input"),
])
], description="""
Bitbang controls for SPI output. Only standard 1x SPI is supported, and as
a result all four wires are ganged together. This means that it is only possible
to perform half-duplex operations, using this SPI core.
""")
</aside>
</section>
self.bitbang = CSRStorage(4, fields=[ <section>
CSRField("mosi", description="Output value for MOSI pin, valid whenever ``dir`` is ``0``."), <aside class="notes">
CSRField("clk", description="Output value for SPI CLK pin."), Now the actual bitbang logic looks like:
CSRField("cs_n", description="Output value for SPI CSn pin."),
CSRField("dir", description="Sets the direction for *ALL* SPI data pins except CLK and CSn.", values=[
("0", "OUT", "SPI pins are all output"),
("1", "IN", "SPI pins are all input"),
])
], description="""
Bitbang controls for SPI output. Only standard 1x SPI is supported, and as
a result all four wires are ganged together. This means that it is only possible
to perform half-duplex operations, using this SPI core.
""")
Now the actual bitbang logic looks like: If(self.bitbang.fields.dir,
dq.oe.eq(0)
).Else(
dq.oe.eq(1)
),
If(self.bitbang.fields.clk, # CPOL=0/CPHA=0 or CPOL=1/CPHA=1 only.
self.miso.status.eq(dq.i[1])
),
dq.o.eq(Cat(self.bitbang.fields.mosi, Replicate(1, spi_width-1)))
If(self.bitbang.fields.dir, This is a little bit easier to understand -- no longer are we looking at indices
dq.oe.eq(0) in an array to determine what field does what. Instead we get actual named fields.
).Else( But because Python can introspect Python very easily, this is just the beginning.
dq.oe.eq(1) </aside>
), </section>
If(self.bitbang.fields.clk, # CPOL=0/CPHA=0 or CPOL=1/CPHA=1 only.
self.miso.status.eq(dq.i[1])
),
dq.o.eq(Cat(self.bitbang.fields.mosi, Replicate(1, spi_width-1)))
This is a little bit easier to understand -- no longer are we looking at indices <section>
in an array to determine what field does what. Instead we get actual named fields. <aside class="notes">
But because Python can introspect Python very easily, this is just the beginning. After the design is elaborated and the output file is generated, we can iterate
through the resulting tree and pick out any CSR objects and using any additional
information. We can actually generate a full reference manual, just like one you
would receive from a SoC Vendor.
After the design is elaborated and the output file is generated, we can iterate For example, this is what the start of the Fomu SPI Flash documentation looks like:
through the resulting tree and pick out any CSR objects and using any additional [Register Listing for LXSPI]
information. We can actually generate a full reference manual, just like one you
would receive from a SoC Vendor.
For example, this is what the start of the Fomu SPI Flash documentation looks like: This is already pretty useful. You can hand this file to someone and show them
[Register Listing for LXSPI] how your design works. But the title of this talk is called "Paying it Forward",
and I can tell you from experience that having such a reference manual for yourself
while developing software for your own hardware is still invaluable. Hardware
designs are complex things, and not having to decode bitfield offsets in your
head or constantly referring to various sections of code to see how it's implemented
saves valuable time.
</aside>
</section>
This is already pretty useful. You can hand this file to someone and show them <section>
how your design works. But the title of this talk is called "Paying it Forward", <aside class="notes">
and I can tell you from experience that having such a reference manual for yourself So now we have register documentation. Can we do better? Of course we can.
while developing software for your own hardware is still invaluable. Hardware SoC reference manuals are more than just register definitions. They also include
designs are complex things, and not having to decode bitfield offsets in your background information on protocols, as well as more elaboration on how the block
head or constantly referring to various sections of code to see how it's implemented works. We can take a cue from CSRs themselves, and add module documentation
saves valuable time. in a similar fashion.
</aside>
</section>
---ModuleDoc---
So now we have register documentation. Can we do better? Of course we can. <section>
SoC reference manuals are more than just register definitions. They also include <aside class="notes">
background information on protocols, as well as more elaboration on how the block Having documentation for humans is great, but we can go one step further and
works. We can take a cue from CSRs themselves, and add module documentation make documentation for computers. SVD is an XML format defined by ARM that
in a similar fashion. defines various aspects about a chip, including memory layout, interrupt map,
and register sets. SVD includes information such as default values and field
bits, all information we have thanks to the introspectability of Python.
</aside>
</section>
---ModuleDoc--- <section>
<aside class="notes">
Having documentation for humans is great, but we can go one step further and In addition to generating a reference manual for humans, we can generate an SVD
make documentation for computers. SVD is an XML format defined by ARM that file that's usable in a wide variety of areas. For example, we can turn an SVD
defines various aspects about a chip, including memory layout, interrupt map, file into a Rust Peripheral Access Crate (PAC) using `SVD2Rust`, giving us an
and register sets. SVD includes information such as default values and field easy way to safely access all peripherals on a device.
bits, all information we have thanks to the introspectability of Python. </aside>
</section>
In addition to generating a reference manual for humans, we can generate an SVD
file that's usable in a wide variety of areas. For example, we can turn an SVD
file into a Rust Peripheral Access Crate (PAC) using `SVD2Rust`, giving us an
easy way to safely access all peripherals on a device.
We can also import this SVD file into an emulator such as Renode, which will
print out fields and flags that get accessed, giving us greater visibility into
what a program is doing.
<section>
<aside class="notes">
We can also import this SVD file into an emulator such as Renode, which will
print out fields and flags that get accessed, giving us greater visibility into
what a program is doing.
</aside>
</section>
lxsocdoc lxsocdoc
intro to litex/migen intro to litex/migen
concept of mixins concept of mixins