update docs in response to feedback from Joe

This commit is contained in:
Fischer Moseley 2023-09-11 19:09:42 -07:00
parent c427cee010
commit a1130e8424
8 changed files with 141 additions and 71 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 303 KiB

View File

@ -1,18 +1,16 @@
\section{Ethernet Interface}
\subsection{Description}
!!! warning "This section is under construction!"
The Ethernet interface is just about to get refactored to implement a few performance gains, so what's here represents the Ethernet interface circa April 2023. Hang tight for new stuff!
## Overview
For situations where the onboard UART is not available, Manta provides a 100Mbps Ethernet link for communicating between the host machine and target FPGA. This link implements a L2 MAC on the FPGA, designed to be directly connected to a host machine on a dedicated network adapter. The MAC is controlled by a bridge interface, which performs the exact same function as it does on the UART interface. Incoming packets are parsed into bus transactions, placed on the bus, and any response data is encapsulated into another packet sent to the host.
This is done by interacting with an Ethernet PHY, an onboard transceiver IC that converts between the FPGA's logic-level signaling and the voltages on the cable's twisted pairs. The communication between the Ethernet PHY and the FPGA is done over an interface that's dependent on the speed of the PHY. The 10/100 Mbps interface used on the Nexys A7-100T uses the RMII as defined in IEEE 802.3u. RMII is the second-oldest member in the Media Independent Interface family, with newer revisions of 802.3 supporting faster interfaces.
Manta's bus clock must be equivalent to the PHY's reference clock if Ethernet is to be used - in the case of the 100Mbps RMII PHY on the Nexys A7 used in 6.205, this is 50MHz. This doesn't pose a problem for user logic, which is connected through Manta's cores that perform CDC internally. It does mean that a reference clock for the PHY has to be synthesized outside of Manta itself, and the means by which this is done varies by FPGA vendor and toolchain.
This MAC allows for the usage of packets with the structure shown in Figure \ref{ethernet_packet_structure}. The bus transaction being communicated is placed at the beginning of the packet's payload field, which IEEE 802.3 allows to vary in length from 46 to 1500 bytes. The 46-byte lower limit requires 41 bytes of zero padding to be added to the five bytes used to specify a bus transaction, and only one bus transactions is specified in each Ethernet frame. This abundance of unused space results in all packets being the same length, whether the packet contains a read request, write request, or read response. Packets containing write requests elicit no response from the FPGA, just as write requests delivered over UART produce no response. The justification for this behavior is shared between the Ethernet and UART interfaces, and is provided in Section \ref{uart_justification}.
This MAC allows for the usage of packets with the structure shown below. The bus transaction being communicated is placed at the beginning of the packet's payload field, which IEEE 802.3 allows to vary in length from 46 to 1500 bytes. The 46-byte lower limit requires 41 bytes of zero padding to be added to the five bytes used to specify a bus transaction, and only one bus transactions is specified in each Ethernet frame. This abundance of unused space results in all packets being the same length, whether the packet contains a read request, write request, or read response. Packets containing write requests elicit no response from the FPGA, just as write requests delivered over UART produce no response.
\begin{figure}[h]
\centering
\includegraphics[width=\textwidth]{ethernet_packet.png}
\caption{Structure of the Ethernet packets exchanged between the host and FPGA.}
\label{ethernet_packet_structure}
\end{figure}
![](assets/ethernet_packet.png)
These packets are addressed directly to the host's MAC address, which is obtained during code autogeneration. These packets also use a fixed Ethertype of \texttt{0x88B5}, which is specially reserved for ``public use and for prototype and vendor-specific protocol development'' in IEEE 802.1. This was done to create an Ethernet II frame instead of a legacy 802.3 frame, without having to implement a higher level protocol like TCP or UDP to safely use a fixed Ethertype. This allows the MAC to use modern Ethernet II frames safely, but save FPGA resources.
These packets are addressed directly to the host's MAC address, which is obtained during code autogeneration. These packets also use a fixed Ethertype of `0x88B5`, which is specially reserved for "public use and for prototype and vendor-specific protocol development" in IEEE 802.1. This was done to create an Ethernet II frame instead of a legacy 802.3 frame, without having to implement a higher level protocol like TCP or UDP to safely use a fixed Ethertype. This allows the MAC to use modern Ethernet II frames safely, but save FPGA resources.

91
doc/getting_started.md Normal file
View File

@ -0,0 +1,91 @@
## Overview
To use Manta, you'll need a host machine with a FPGA board connected over UART or Ethernet. You'll then:
- _Specify a set of debug cores you wish to include in your design._ This is done by writing a configuration file, typically called `manta.yaml`. Specifying files in JSON is also supported, as long as the hierarchy in the file is equivalent. Just make sure that your YAML files end in `.yaml` or `.yml`, and that JSON files end in `.json`.
- _Invoke Manta to generate Verilog from the configuration provided._ This is done by running `manta gen [config_file] [verilog_file]` at the command line, which generates a Verilog file (typically named `manta.v`) from the provided configuration file. This Verilog file contains a definition for a Verilog module named `manta`, and all its constituent modules.
- _Instantiate `manta` in your design, and connecting it to the logic you'd like to debug._ An example instantiation is provided at the top of `manta.v`, which you can copy-paste into your main source code. You'll connect its ports to the logic you're trying to debug, as well as to whatever interface you're using to communicate with the host. This will be a serial transciever on your development board if you're using UART, or it's RMII PHY if you're using Ethernet.
- _Build and upload the design to your FPGA using your preferred toolchain._
- _Use the debug core(s) through the Python API or the command line._ The functions availble to each core are described in their documentation.
- _Repeat!_ As you debug, you'll probably want to change exactly how Manta is configured. This means tweaking the configuration file, regenerating the Verilog module, and so on.
## Example Configuration
An example config file is provided below. If this file was named `manta.yaml` then running `manta gen manta.yaml manta.v` would generate Verilog for a `manta` module that matched the config file.
```yaml
---
cores:
my_io_core:
type: io
inputs:
probe_0_in: 6
probe_1_in: 12
outputs:
probe_2_out: 20
probe_3_out: 1
my_logic_analyzer:
type: logic_analyzer
sample_depth: 4096
trigger_loc: 1000
probes:
larry: 1
curly: 3
moe: 9
triggers:
- moe RISING
- curly FALLING
uart:
port: "auto"
baudrate: 3000000
clock_freq: 100000000
```
Although it's just an example, this config file shows the two things every Manta configuration needs, namely:
- ___Cores___: A list of the debug cores Manta should place on your FPGA. The behavior and configuration of the cores is described in more detail on their documentation pages, but this list contains each core you'd like included in your `manta` module. This list can have as many entires as your FPGA can support, so long as Manta can address them all. If it can't, it'll throw an error when it tries to generate Verilog.
- ___Interface___: The way data gets on and off the FPGA. At present, Manta only supports UART and Ethernet interfaces. These are described in more detail on their documentation pages, but the interface of choice is specified with either a `uart` or `ethernet` at the end of the configuration file.
This Manta instance has an IO Core and a Logic Analyzer, each containing a number of probes at variable widths. The Manta module itself is provided a 100MHz clock, and communicates with the host over UART running at 3Mbaud. This is just an example, and more details are available in the documentation page for each core.
## Example Instantiation
The Verilog file generated by `manta gen` contains some information at the top of the file. This includes an example instantiation for the `manta` module that's been configured, which you can copy paste into your source code. Here's what that looks like for the configuration above:
```c
/*
This module was generated with Manta v0.0.5 on 11 Sep 2023 at 17:52:28 by fischerm
If this breaks or if you've got spicy formal verification memes, contact fischerm [at] mit.edu
Provided under a GNU GPLv3 license. Go wild.
Here's an example instantiation of the Manta module you configured, feel free to copy-paste
this into your source!
manta manta_inst (
.clk(clk),
.rx(rx),
.tx(tx),
.probe_0_in(probe_0_in),
.probe_1_in(probe_1_in),
.probe_2_out(probe_2_out),
.probe_3_out(probe_3_out),
.larry(larry),
.curly(curly),
.moe(moe));
*/
```

View File

@ -1,62 +1,15 @@
## System Architecture
## Overview
To use Manta, you'll need a host machine with a FPGA development board connected to it over UART or Ethernet. The whole system looks like the following:
The whole system looks like the following:
![](assets/manta_architecture.png){:style="width:80%"}
Manta is operated via its Python API, which communicates with the connected FPGA over an interface API like `pySerial` or `Scapy`. These abstract away the OS device drivers, which function differently depending on the host machine's platform. The OS device drivers ultimately send out bytes to the FPGA, across either a USB or Ethernet cable.
Once sent across the wire, bytes are picked up by an interface transciever on the FPGA development board. This is either a USB-UART converter or a RMII PHY depending on if you're using UART or Ethernet. This chip is connected to the FPGA's IO, which routes the signals to the Verilog module generated by Manta. This module parses incoming messages, passes them down a set of daisy-chained cores, and then packetizes it and sends it back to the host. These cores also connect to your logic, and are operated to help you debug your logic. The procedure for this is described below:
Once sent across the wire, bytes are picked up by an interface transciever on the FPGA development board. This is either a USB-UART converter or a RMII PHY depending on if you're using UART or Ethernet. This chip is connected to the FPGA's IO, which routes the signals to the Verilog module generated by Manta. This module parses incoming messages, passes them down a set of daisy-chained cores, and then packetizes it and sends it back to the host.
## Usage
Using Manta consists of the following steps:
## Manta Architecture
- Specifying a set of debug cores you wish to include in your design. This is done with a configuration file, formatted as either JSON or YAML.
- Invoking Manta to generate Verilog from the configuration provided. This is done with `manta gen`, which produces a single file containing a definition for a Verilog module named `manta`.
- Instantiating `manta` in your design, and connecting it to the logic you'd like to debug. You'll also need to connect it to your FPGA's serial transciever if you're using UART, or it's RMII PHY if you're using Ethernet. This permits communication with the host machine.
- Building and uploading the design to your FPGA using your preferred toolchain.
- Operating the debug core(s) through either the Python API, or the command line. The functions availble to each core are described in their documentation.
An example configuration file is provided below:
```yaml
---
cores:
my_io_core:
type: io
inputs:
probe_0_in: 6
probe_1_in: 12
outputs:
probe_2_out: 20
probe_3_out: 1
my_logic_analyzer:
type: logic_analyzer
sample_depth: 4096
trigger_loc: 1000
probes:
larry: 1
curly: 3
moe: 9
triggers:
- moe RISING
- curly FALLING
uart:
port: "auto"
baudrate: 3000000
clock_freq: 100000000
```
This will create a Manta instance with an IO Core and a Logic Analyzer, each containing a number of probes at variable widths. The Manta module itself is provided a 100MHz clock, and communicates with the host over UART running at 3Mbaud.
## System Architecture
The logic Manta places on the FPGA consists of a series of cores connected in a chain along a common bus. Each core provides a unique method for interacting with the users logic, which it connects to by routing signals (called _probes_) between the users logic and the cores that interface with it.
![](assets/bus_architecture.png){:style="width:40%"}

21
doc/uart_interface.md Normal file
View File

@ -0,0 +1,21 @@
## Overview
Manta needs an interface to pass data between the host machine and FPGA, and UART is a convenient option. When configured to use UART, Manta will shuffle data back and forth using generic 8N1 serial with no flow control. This happens through a series of read and write transactions, which are specified using a messaging format described [here](../how_it_works/#message-format).
## Configuration
The configuration of the UART interface is best shown by example:
```yaml
uart:
port: "auto"
baudrate: 3000000
clock_freq: 100000000
```
This snippet defines the interface, and lives at the bottom of a Manta configuration file. Three parameters must be set:
- `port` _(required)_: The name of the serial port on the host machine that's connected to the FPGA. Depending on your platform, this could be `/dev/ttyUSBXX`, `/dev/tty.usbserialXXX`, or `COMX`. If set to `auto`, then Manta will try to find the right serial port by looking for a USB device with the same VID and PID as a FT2232 - a USB/UART converter chip that's super popular on FPGA dev boards. This doesn't always work, but it's super convenient when it does. If your port isn't automatically detected, then just specify the port manually.
- `baudrate` _(required)_: The baudrate of the serial port. Generally you want to configure this at the maximum speed of your USB/UART chip such that data transfers as fast as possible. The ubiquitous FT2232 supports up to 3Mbaud.
- `clock_freq` _(required)_: The frequency of the clock being provided to the `manta` module, in Hertz (Hz). This speed doesn't matter much to the logic itself, it's only used to calculate the correct baud timing for the provided baudrate. However, this frequency does have to be fast enough to ensure a good agreement between the onboard prescaler and the requested baudrate - and Manta will throw an error during code generation if that is not the case.

View File

@ -58,9 +58,13 @@ nav:
- Home: index.md
- Installation: installation.md
- Reference:
- How It Works: how_it_works.md
- Getting Started: getting_started.md
- IO Core: io_core.md
- Logic Analyzer Core: logic_analyzer_core.md
- Block Memory Core: block_memory_core.md
- Repository Structure: repository_structure.md
- Roadmap: https://github.com/fischermoseley/manta/milestones
- UART Interace: uart_interface.md
- Ethernet Interface: ethernet_interface.md
- For Developers:
- Repository Structure: repository_structure.md
- How It Works: how_it_works.md
- Roadmap: https://github.com/fischermoseley/manta/milestones

View File

@ -52,6 +52,9 @@ class Manta:
else:
raise ValueError(f"Unrecognized core type specified for {core_name}.")
# make sure we're not out of address space
assert new_core.max_addr < (2**16)-1, f"Ran out of address space to allocate to core {core_name}."
# make the next core's base address start one address after the previous one's
base_addr = new_core.max_addr + 1
@ -313,11 +316,11 @@ def main():
\033[96m '-....-' \033[00m
Supported commands:
gen [config file] [path] generate a verilog module with the given configuration, and save to the provided path
capture [config file] [LA core] [path] [path] start a capture on the specified core, and save the results to a .mem or .vcd file at the provided path(s)
playback [config file] [LA core] [path] generate a verilog module that plays back a capture from a given logic analyzer core, and save to the provided path
ports list all available serial ports
help, ray display this splash screen (hehe...splash screen)
gen [config_file] [verilog_file] generate a verilog file specifying the Manta module from a given configuration file, and save to the provided path
capture [config_file] [LA_core_name] [vcd_file] [mem_file] start a capture on the specified core, and save the results to a .mem or .vcd file at the provided path(s)
playback [config file] [LA_core_name] [verilog_file] generate a verilog module that plays back a capture from a given logic analyzer core, and save to the provided path
ports list all available serial ports
help, ray display this splash screen (hehe...splash screen)
"""
)

View File

@ -1,7 +1,7 @@
/*
This playback module was generated with Manta /* VERSION */ on /* TIMESTAMP */ by /* USER */
This module was generated with Manta /* VERSION */ on /* TIMESTAMP */ by /* USER */
If this breaks or if you've got dank formal verification memes, contact fischerm [at] mit.edu
If this breaks or if you've got spicy formal verification memes, contact fischerm [at] mit.edu
Provided under a GNU GPLv3 license. Go wild.