96
									
								
								index.html
									
									
									
									
									
								
							
							
						
						
									
										96
									
								
								index.html
									
									
									
									
									
								
							| @@ -134,6 +134,12 @@ | ||||
|  | ||||
| 			<section> | ||||
| 				<h2>Talk Outline</h2> | ||||
| 				<ol> | ||||
| 					<li>How to write HDL Code</li> | ||||
| 					<li>Rationale behind <tt>lxsocdoc</tt></li> | ||||
| 					<li>Examples of <tt>lxsocdoc</tt></li> | ||||
| 					<li>Benefits of this approach</li> | ||||
| 				</ol> | ||||
| 				<aside class="notes"> | ||||
| 					I'll briefly cover various methods of writing HDL code, then cover the rationale | ||||
| 					behind the approach we take with lxsocdoc, then give an example of how to use | ||||
| @@ -144,14 +150,27 @@ | ||||
|  | ||||
| 			<section> | ||||
| 				<h2>Motivation</h2> | ||||
| 				<pre><code class="hljs cpp">// Hardware definitions of the SoC. Also is the main repo of | ||||
| // documentation for the programmer-centric view | ||||
| // of the hardware. | ||||
| /* Start of memory range for the UART peripheral */ | ||||
| #define UART_OFFSET     0x10000000 | ||||
| /* Offset of the data register for the debug UART. A write | ||||
|    here will send the data out of the UART. A write when a | ||||
|    send is going on will halt the processor until the send is | ||||
|    completed. A read will receive any byte that was received | ||||
|    by the UART since the last read, or 0xFFFFFFFF when none | ||||
|    was. There is no receive buffer, so it's possible to miss | ||||
|    data if you don't poll frequently enough. | ||||
|    The debug UART is always configured as 8N1. */ | ||||
| #define UART_DATA_REG   0x00</code></pre> | ||||
|                     <p><tt>mach_defines.h</tt>, Hackaday 2019 Con Badge</p> | ||||
| 			<aside class="notes"> | ||||
| 					Verilog and VHDL are kind of the C or assembly of the FPGA world.  They're universal, | ||||
| 					but somewhat unwieldy to use.  You need to manually set up your address decoders, | ||||
| 					and documentation is very free-form.  Common approaches today involve comments in | ||||
| 					the HDL and/or C header files.  This works, but we can do better.  We just need to | ||||
| 					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> | ||||
|  | ||||
| @@ -170,6 +189,10 @@ | ||||
|  | ||||
| 			<section> | ||||
|                 <h2>LiteX Primitives</h2> | ||||
|                 <pre><code class="python" data-trim>class GPIOOut(Module, AutoCSR): | ||||
|     def __init__(self, signal): | ||||
|         self._out = CSRStorage(len(signal)) | ||||
|         self.comb += signal.eq(self._out.storage)</code></pre> | ||||
| 				<aside class="notes"> | ||||
| 					In LiteX, two of the primitives used to expose hardware registers to the CPU softcore | ||||
| 					are CSRStorage and CSRStatus.  Instead of manually wiring up a crossbar and decoding | ||||
| @@ -221,18 +244,18 @@ dq.o.eq( | ||||
| 			<section> | ||||
| 				<h4>New Register Definition</h4> | ||||
| 				<pre><code class="python" data-trim>self.bitbang = CSRStorage(4, fields=[ | ||||
| 	CSRField("mosi", description="Output value for MOSI pin, valid whenever ``dir`` is ``0``."), | ||||
| 	CSRField("clk", description="Output value for SPI CLK pin."), | ||||
| 	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=[ | ||||
|     CSRField("mosi", description="Output value for MOSI..." | ||||
|     CSRField("clk", description="Output value for SPI CLK..." | ||||
|     CSRField("cs_n", description="Output value for SPI C..." | ||||
|     CSRField("dir", description="Sets the dir...", 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. | ||||
| """)</code></pre> | ||||
| ], 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.""")</code></pre> | ||||
| 				<aside class="notes"> | ||||
| 					This is when I hit upon the idea of `lxsocdoc`.  The basic idea is that | ||||
| 					Python is really good at introspecting Python, so let's add a little bit | ||||
| @@ -267,6 +290,7 @@ dq.o.eq( | ||||
|  | ||||
| 			<section> | ||||
|                 <h2>Generating a Manual</h2> | ||||
|                 <img data-src="img/lxspi_bitbang.png"> | ||||
| 				<aside class="notes"> | ||||
| 					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 | ||||
| @@ -286,8 +310,27 @@ dq.o.eq( | ||||
| 				</aside> | ||||
| 			</section> | ||||
|  | ||||
| 			<section> | ||||
| 				<h2>Undocumented Fields</h2> | ||||
| 				<aside class="notes"> | ||||
| 					It turns out that there is enough information that we can extract that | ||||
| 					even undocumented fields are somewhat useful. | ||||
| 				</aside> | ||||
| 			</section> | ||||
|  | ||||
| 			<section> | ||||
| 				<h2>Interrupts</h2> | ||||
|                 <img data-src="img/interrupts.png"> | ||||
| 				<aside class="notes"> | ||||
| 					We can even extract interrupt information, including which bits inside an | ||||
| 					interrupt register map to which event, and which interrupt number is assigned | ||||
| 					to a given module. | ||||
| 				</aside> | ||||
| 			</section> | ||||
|  | ||||
| 			<section> | ||||
| 				<h2>More Documentation: ModuleDoc</h2> | ||||
|                 <img data-src="img/timer0-doc.png"> | ||||
| 				<aside class="notes"> | ||||
| 					So now we have register documentation.  Can we do better?  Of course we can. | ||||
| 					SoC reference manuals are more than just register definitions.  They also include | ||||
| @@ -299,6 +342,7 @@ dq.o.eq( | ||||
|  | ||||
| 			<section> | ||||
| 				<h2>Protocol Documentation</h2> | ||||
|                 <img data-src="img/usb-wishbone.png"> | ||||
| 				<aside class="notes"> | ||||
| 					We can add additional documentation such as protocol waveforms.  Here | ||||
| 					we use WaveDrom to define the protocol of Wishbone-over-SPI.  There | ||||
| @@ -336,6 +380,36 @@ dq.o.eq( | ||||
| 					what a program is doing. | ||||
| 				</aside> | ||||
| 			</section> | ||||
|  | ||||
| 			<section> | ||||
| 				<h2>Benefits of Higher Level Languages</h2> | ||||
| 				<aside class="notes"> | ||||
| 					By using a higher level language, we are able to describe the hardware | ||||
| 					in greater detail than if we used Verilog or VHDL.  We can add additional | ||||
| 					fields to our register definition fields to provide nice, human-readable | ||||
| 					documentation.  This also allows us to generate machine-readable formats | ||||
| 					such as SVD, which opens up a whole world of software. | ||||
| 				</aside> | ||||
| 			</section> | ||||
|  | ||||
| 			<section> | ||||
| 				<h2>Documentation helps you</h2> | ||||
| 				<h2>Documentation helps others</h2> | ||||
| 				<aside class="notes"> | ||||
| 					Documenting your hardware is important because it is necessary for you to | ||||
| 					write software that interfaces with it today, and it helps you work with | ||||
| 					others when it comes time to share your design with the world.  By | ||||
| 					properly documenting various fields within your module, you make it easier | ||||
| 					on yourself to interact with today, and you make it easier to let others | ||||
| 					get up to speed in the future.  By documenting your hardware, you're helping | ||||
| 					to pay it forward. | ||||
| 				</aside> | ||||
| 			</section> | ||||
|  | ||||
| 			<section> | ||||
| 				<h2>Thank you</h2> | ||||
| 				<h3>Questions</h3> | ||||
| 			</section> | ||||
| 		</div> | ||||
| 	</div> <!-- class="reveal" --> | ||||
| 	<!-- End of main presentation --> | ||||
|   | ||||
		Reference in New Issue
	
	Block a user