diff --git a/doc/assets/manta_logic_analyzer_architecture.png b/doc/assets/manta_logic_analyzer_architecture.png
new file mode 100644
index 0000000..6e9ea24
Binary files /dev/null and b/doc/assets/manta_logic_analyzer_architecture.png differ
diff --git a/doc/assets/trigger_positions.png b/doc/assets/trigger_positions.png
new file mode 100644
index 0000000..be1ac1a
Binary files /dev/null and b/doc/assets/trigger_positions.png differ
diff --git a/doc/io_core.md b/doc/io_core.md
index 9a13dcb..96f059e 100644
--- a/doc/io_core.md
+++ b/doc/io_core.md
@@ -26,7 +26,7 @@ the_muppets:
This configuration specifies four parameters:
- `name`: The name of the IO core. This name is used to reference the core when working with the API, and can be whatever you'd like.
-- `type`: This signals to the parser that this is an IO core. All cores contain a `type` field, which must be set to `io` to be recognized as an IO core.
+- `type`: This denotes that this is an IO core. All cores contain a `type` field, which must be set to `io` to be recognized as an IO core.
- `inputs`: This lists all inputs from from the FPGA fabric to the host machine. Signals in this list may be read by the host, but ___cannot___ be written to.
- `outputs`: This lists all outputs from the host machine to the FPGA fabric. Signals in this list may be written by the host, but ___can___ also be read from, and doing so returns the value last written to the register.
@@ -78,6 +78,8 @@ A small example is shown below, using the [example configuration](#configuration
>>> import Manta
>>> m = Manta
>>> m.my_io_core.fozzy.set(True)
+>>> m.my_io_core.fozzy.get()
+True
>>> m.my_io_core.gonzo.set(4)
>>> m.my_io_core.scooter.get()
5
@@ -97,14 +99,6 @@ This is done with the architecture shown below:
-. A series of connections are made to the user’s logic. These are called \textit{probes}, and each may be either an input or an output. If the probe is an input, then its value is taken from the user’s logic, and stored in a register that may be read by the host machine. If the probe is an output, then its value is provided to the user’s logic from a register written to by the host. The widths of these probes is arbitrary, and is set by the user at compile-time.
+Each of the probes is mapped to a register of Manta's internal memory. Since Manta's internal registers are 16 bits wide, probes less than 16 bits are mapped to a single register, but probes wider than 16 bits require multiple.
-However, the connection between these probes and the user’s logic is not direct. The state of each probe is buffered, and the buffers are updated when a \textit{strobe} register within the IO core is set by the host machine. During this update, new values for output probes are provided to user logic, and new values for input probes are read from user logic.
-
-This is done to mitigate the possibility of an inconsistent system state. Although users may configure registers of arbitrary width, Manta’s internal bus uses 16-bit data words, meaning operations on probes larger than 16 bits require multiple bus transactions. These transactions occur over some number of clock cycles, with an arbitrary amount of time between each.
-
-This can easily cause data corruption if the signals were unbuffered. For instance, a read operation on an input probe would read 16 bits at a time, but the probe’s value may change in the time that passes between transactions. This would cause the host to read a value for which each 16 bit chunk corresponds to a different moment in time. Taken together, these chunks may represent a value that the input probe never had. Similar corruption would occur when writing to an unbuffered output probe. The value of the output probe would take multiple intermediate values as each 16-bit section is written by the host. During this time the value of the output probe is not equal to either the incoming value from the host, or the value the host had previously written to it. The user logic connected to the output probe has no idea of this, and will dutifully use whatever value it is provided. This can very easily induce undesired behavior in the user’s logic, as it is being provided inputs that the user did not specify.
-
-Buffering the probes mitigates these issues, but slightly modifies the way the host machine uses the core. When the host wishes to read from an input probe, it will set and then clear the strobe register, which pulls the current value of the probe into the buffer. The host then reads from buffer, which is guaranteed to not change as it is being read from. Writing to an output probe is done in much the same way. The host writes a new value to the buffer, which is flushed out to the user’s logic when the strobe register is set and cleared. This updates every bit in the output probe all at once, guaranteeing the user logic does not observe any intermediate values.
-
-These buffers also provide a convenient location to perform clock domain crossing. Each buffer is essentially a two flip-flop synchronizer, which allows the IO core to interact with user logic on a different clock than Manta’s internal bus.
\ No newline at end of file
+Whatever the number of registers required, these are read from and written to by the host machine - but the connection to the user's logic isn't direct. The value of each probe is buffered, and only once the `strobe` register has been set to one will the buffers update. When this happens, output probes provide new values to user logic, and new values for input probes are read from user logic. This provides a convenient place to perform clock domain crossing, and also mitigates the possibility of an inconsistent system state. More details on this can be found in Chapter 3.6 of the [original thesis](thesis.pdf).
\ No newline at end of file
diff --git a/doc/logic_analyzer.md b/doc/logic_analyzer.md
index 21499e6..6e23003 100644
--- a/doc/logic_analyzer.md
+++ b/doc/logic_analyzer.md
@@ -1,11 +1,13 @@
-# Logic Analyzer
+## Overview
-This emulates the look and feel of a logic analyzer, both benchtop and integrated. These work by continuously sampling a set of digital signals, and then when some condition (the _trigger_) is met, recording these signals to memory, which are then read out to the user.
+The Logic Analyzer core allows for debugging logic by capturing a set of digital signals to memory. This is done in response to a ___trigger___ condition, which starts the ___capture___, which continues until the onboard memory is full. The resulting capture is then read out to the user. This pretty much identical to the behavior of a benchtop logic analyzer.
-Manta works exactly the same way, and the behavior of the logic analyzer is defined entirely in the Manta configuration file. Here's an example:
+While this sounds simple, Manta has a few tricks up its sleeve that you may find useful! These are described below:
## Configuration
+Just like the rest of the cores, the Logic Analyzer core is configured via an entry in a project's configuration file. This is easiest to show by example:
+
```yaml
---
cores:
@@ -26,43 +28,65 @@ cores:
There's a few parameters that get configured here, including:
-### Sample Depth
+- `name`: The name of the Logic Analyzer core. This name is used to reference the core when working with the API, and can be whatever you'd like.
+- `type`: This denotes that this is a Logic Analyzer core. All cores contain a `type` field, which must be set to `logic_analyzer` to be recognized as an IO core.
-Which is just how many samples are saved in the capture. Having a larger sample depth will use more resources on the FPGA, but show what your probes are doing over a longer time.
+### Sample Depth
+This refers to the number of samples saved in the capture, and is set with the `sample_depth` entry in the config file. A larger sample depth will use more resources, but show what your probes are doing over a longer time.
### Probes
-
-Probes are the signals you're trying to observe with the Logic Analyzer core. Whatever probes you specify in the configuration will be exposed by the `manta` module, which you then connect to your design in Verilog. Each probe has a name and a width, which is the number of bits wide it is.
+Probes are the signals in your logic that the Logic Analyzer connects to, and are specified in the `probes` entry of the config file. Each probe requires both a name and a width to be specified. These names can be whatever you'd like, however they are referenced in the autogenerated Verilog - so don't use something your synthesis engine won't appreciate.
### Triggers
+Triggers are the conditions that your logic must meet in order to start a capture, and they're specified under the `triggers` entry in the config file. Manta's triggers are reprogrammable, meaning you don't need to rebuild your source code to change the trigger condition - just updating the configuration file is enough. If multiple triggers are provided, any one trigger being met will trigger the entire core.
-Attached to each probe is a little piece of logic that allows you to check if some condition on the probe is true, and triggers the capture if so. These conditions look something like:
-- `curly GEQ 2`
-- `larry EQ 1`
-- `moe NEQ 32`
-- `larry RISING`
-- `moe CHANGING`
-- and so on!
+Each individual trigger is specified with the following structure:
-Each of these contains a trigger, an operation, and an argument.
+`[probe]` `[operation]` `[argument]`
-Triggers are things that will cause the logic analyzer core to capture data from the probes. Any one of them being satisfied is enough to start the capture. Each trigger can
+- __probe__: The probe that the trigger applies to. Each probe only supports one trigger on it. For instance, in the example above we couldn't add a trigger for `curly LEQ 4`, since we've already assigned a trigger to `curly`.
-### Trigger Position
+- __operation__: The logical operation to perform. Manta supports the following operations:
+ - `RISING`, which checks if the probe has increased in value since the last clock cycle.
+ - `FALLING`, which checks if the probe has decreased in value since the last clock cycle.
+ - `CHANGING`, which checks if the probe is changed in value since the last clock cycle.
-The logic analyzer has a programmable _trigger position_, which sets when probe data is captured relative to the trigger condition being met. This is best explained with a picture:
+ These operations only compare a probe's value with itself, but sometimes it is useful to compare a probe's value to a constant. Manta provides a operations for doing such, including:
-_TODO: put a picture here @fischerm_
+ - `GT`, for greater than.
+ - `LT`, for less than.
+ - `GEQ`, for greater than or equal to.
+ - `LEQ`, for less than or equal to.
+ - `EQ`, for equal to.
+ - `NEQ`, for not equal to.
-For instance, setting the trigger position to `100` will cause the logic analyzer to save 100 samples of the probes prior to the trigger condition occuring. Manta uses a default trigger position of `SAMPLE_DEPTH/2`, which positions the data capture window such that the trigger condition is in the middle of it.
+ These operations require a constant to compare against, referred to as an _argument_, which is descirbed below:
-### Operating Modes
+- __argument__: A constant to compare against, if the operation specified requires one. On the FPGA, the argument will have just as many bits as the probe width.
-The logic analyzer can operate in a number of modes, which govern what trigger conditions start the capture of data:
+Lastly, if you're not able to express your desired trigger condition in terms of the operators above, fear not! You can also specifiy an `external_trigger: true` entry in the config file, which exposes an input on Manta's top level for your own trigger.
-* __Single-Shot__: Once the trigger condition is met, record every subsequent sample until `SAMPLE_DEPTH` samples have been acquired. This is the mode most benchtop logic analyzers run in, so the Logic Analyzer Core defaults to this mode unless configured otherwise.
-* __Incremental__: Record samples when the trigger condition is met, and don't record the samples when the trigger condition is not met. This is super useful for applications like audio processing or memory controllers, where there are many system clock cycles between signals of interest.
-* __Immediate__: Read the probe states into memory immediately, regardless of if the trigger condition is met.
+### Trigger Position (optional)
+Sometimes, you care more about what happens before a trigger is met than afterwards, or vice versa. To accomodate this, the logic analyzer has an optional _Trigger Position_ parameter, which sets when probe data is captured relative to the trigger condition being met. This is specified with the `trigger_position` entry in the configuration file, which sets how many samples to save prior to the trigger condition occuring. This is best explained with a picture:
+
+
+
+The windows at the bottom of the diagram show what portions of the timeseries will be captured for different trigger positions. For instance:
+
+- A trigger position of half the sample depth centers the capture window around when the trigger condition is met.
+- A trigger position of zero places the trigger at the zeroth clock cycle of the capture.
+- A trigger position equal to the sample depth causes the trigger to occur on the last sample in the capture.
+
+If `trigger_position` is not specified, Manta will default to centering the capture window around the trigger condition.
+
+### Capture Modes (optional)
+The logic analyzer has a few different ways of capturing data, which are represented by the _capture modes_ below:
+
+- __Single-Shot__: Once the trigger condition is met, record the value of the probes on every clock cycle in a continuous single shot.
+- __Incremental__: Record samples when the trigger condition is met, but __don't__ record the samples when the trigger condition is not met. This is super useful for applications like audio processing or memory controllers, where there are many system clock cycles between signals of interest.
+- __Immediate__: Record the value of the probes on every clock cycle, beginning immediately, and regardless of if the trigger condition is met. This is useful for investigating cases where a trigger condition is never being met (such as latchup or deadlock conditions) or obtaining a random snapshot of the FPGA's state.
+
+Most logic analyzers use a single-shot capture by default, so Manta will do the same if no `capture_mode` entry is provided in the project's configuration file.
## Usage
@@ -70,13 +94,13 @@ The logic analyzer can operate in a number of modes, which govern what trigger c
Once you have your Logic Analyzer core on the FPGA, you can capture data with:
-```
+```bash
manta capture [config file] [LA core] [path] [path]
```
If the file `manta.yaml` contained the configuration above, and you wanted to export a .vcd and .mem of the captured data, you would execute:
-```
+```bash
manta capture manta.yaml my_logic_analyzer capture.vcd capture.mem
```
@@ -87,10 +111,10 @@ Manta will stuff the capture data into as many files as you provide it on the co
### Playback
-The LogicAnalyzerCore has the ability to capture a recording of a set of signals on the FPGA, and then 'play them back' inside a Verilog simulation. This requires generating a small Verilog module that loads a capture from a `.mem` file, which can be done by:
+The Logic Analyzer Core has the ability to capture a recording of a set of signals on the FPGA, and then 'play them back' inside a Verilog simulation. This requires generating a small Verilog module that loads a capture from a `.mem` file, which can be done by:
```
-manta playback [config file] [LA core] [path]
+manta playback [config_file_path] [core_name] [verilog_file_path]
```
If the file `manta.yaml` contained the configuration above, then running:
@@ -101,83 +125,24 @@ manta playback manta.yaml my_logic_analyzer sim/playback.v
Generates a Verilog wrapper at `sim/playback.v`, which can then be instantiated in the testbench in which it is needed. An example instantiation is provided at the top of the output verilog, so a simple copy-paste into the testbench is all that's necessary to use the module. This module is also fully synthesizable, so you can use it in designs that live on the FPGA too, if so you so wish.
-## Examples
+This is useful for two situations in particular:
+
+- _Input Verification._ Designs will often work in simulation, but fail in hardware. In the absence of any build errors, this usually means that the inputs being applied to the logic in simulation don't accurately represent those being applied to the logic in the real world. Playing signals back in simulation allows for easy comparison between simulated and measured input, and provides a nice way to check that the logic downstream is behaves properly.
+
+- _Sparse Sampling_ Sometimes designs will have a small number of inputs, but a huge amount of internal state. In situations like these, it may be more effecient to sample the inputs and simulate the logic, instead of directly sampling the state. For instance, debugging a misbehaving branch predictor in a CPU can be done by recording activity on the address and data busses and playing them back in simulation - which would use less BRAM than sampling the entire pattern history table.
+
+## Python API
-## from thesis
-
-\section{Logic Analyzer Core}
-\subsection{Description}
-\label{logic_analyzer_core_description}
-Central to Manta's design is the ability to debug logic in a manner intuitive and familiar to 6.205 students. As such, Manta includes a logic analyzer tool that allows them to inspect their logic through a waveform display, similar to how it might be inspected through simulation. A typical workflow for using the core consists of the following:
-
-\begin{itemize}
- \item The user describes the signals they would like to probe in the configuration file. The user provides a list of probe names and widths, which are needed to generate suitable Verilog.
- \item The user describes the \textit{trigger conditions} that must be met inside the FPGA fabric for a capture to begin. Triggers are defined as simple logical operations on probes, for instance checking if a probe named \texttt{foo} is equal to the number $3$, or if a probe named \texttt{bar} has just transitioned from high to low. The user also specifies the number of samples to be captured, referred to as the \textit{sample depth} of the core.
- \item Once fully configured, a Manta module is generated and flashed to the target FPGA with the process described in \ref{usage}.
- \item Once flashed, the user initiates the ILA from the host machine. This causes the Logic Analyzer Core to start sampling its inputs, waiting for the trigger condition to be met.
- \item Once met, the core begins saving the values of the probes to an internal block RAM called the \textit{sample memory}. This occurs every clock cycle until a number of samples equal to the sample depth has been captured, and the sample memory is full.
- \item Once complete, the host machine reads out the sample memory and stores it internally. This is then exported as a VCD file for use in a waveform viewer like GTKWave.
-\end{itemize}
-
-\begin{figure}[h!]
-\centering
-\includegraphics[width=\textwidth]{gtkwave.png}
-\caption{A logic analyzer capture displayed in GTKWave.}
-\label{gtkwave}
-\end{figure}
-
-This workflow is very similar to the behavior of the Xilinx ILA or a benchtop logic analyzer. This is intentional. FPGA engineers are familiar with on-chip logic analyzers, and electrical engineers are familiar with external logic analyzers. Very little is intended to be different, although a few extra features deserve mention:
-
-\subsection{Features}
-\subsubsection{Trigger Modes}
-The behavior described in \ref{logic_analyzer_core_description} is referred to as single-shot trigger mode. This means that once the trigger condition is met, data is captured on every clock cycle in a continuous single shot. This is useful and the preferred behavior for most cases, but Manta also supports \textit{Incremental} and \textit{Immediate} trigger modes.
-
-In Incremental mode, samples are only recorded to sample memory \textit{when} the trigger condition is met, not \textit{once} it is met. This allows slower-moving behavior to be captured. For instance, digital audio signals on a FPGA commonly use a 44.1kHz sampling frequency, but are routed through FPGA fabric clocked at hundreds of megahertz. As a result, many thousands of clock cycles may go by before a new audio sample is processed by the FPGA - filling the sample memory of a traditional logic analyzer with redundant data in the meantime. Placing Manta's Logic Analyzer into incremental mode solves this, as audio samples will only be saved to the sample memory when they change, assuming the trigger is configured correctly. In this case, the amount of memory required on the FPGA to capture a fixed number of audio samples is reduced by a thousandfold.
-
-In Immediate mode, the trigger condition is ignored. The core begins filling the sample memory as soon as it is enabled, stopping only once the sample memory is filled. This allows the user to inspect the current state of their probes without a trigger condition. This is especially useful for investigating cases where a trigger condition is never being met, such as latchup or deadlock conditions. This mode is also useful for obtaining a random snapshot of the FGPA's state. The core is enabled by an interface (UART, Ethernet) that is slow relative to the clock speed of the FPGA fabric, meaning that the capture occurs at an effectively random time. Successive captures of this nature can be used to determine the ``average" state of onboard logic - what information is ``usually" on a bus, or what state a module is ``typically" in.
-
-\subsubsection{Configurable Trigger Location}
-
-In the scenario described in \ref{logic_analyzer_core_description}, the sample memory is written to as soon as the trigger condition is met - and not before. This only records the probe values after the trigger, but knowing the state of the FPGA immediately before is also rather useful. To do this, the core can be configured to buffer the last few clock cycles before the trigger condition. During this time the sample memory is used as a FIFO, and once the trigger condition occurs, samples are acquired until the sample memory is filled. The number of cycles to record ahead of the trigger is called the \textit{trigger position}. By default, most logic analyzers place the trigger condition in the middle of the acquisition such that there is equal amounts of data from before and after the trigger condition. To feel as intuitive and familiar as possible, Manta defaults to the same. However, this can be changed by writing to a register in the logic analyzer core.
-
-\begin{figure}[h!]
-\centering
-\includegraphics[width=\textwidth]{trigger_positions.png}
-\caption{Regions captured by the Logic Analyzer Core as trigger position is varied.}
-\label{trigger_location_fig}
-\end{figure}
-
-\subsubsection{Simulator Playback}
-Manta also allows data captured from the Logic Analyzer core to be ``played back'' in simulation. Any obtained capture data can be exported as a \texttt{.mem} file, which can be used in most simulators via the \texttt{readmemh} and \texttt{readmemb} Verilog functions. Manta autogenerates a convenient Verilog wrapper for this, allowing users to simulate logic with signals directly measured from the real world. This is useful for verifying that a testbench is providing the proper inputs to logic under test. This is useful for a few scenarios:
-
-\begin{itemize}
- \item \textit{Input Verification.} This targets the common student experience in 6.205 of designs working in simulation, but failing in hardware. In the absence of any build errors, this usually means that the inputs being applied to the logic in simulation don't accurately represent those being applied to the logic in the real world. \footnote{Sometimes the toolchain will step in and modify the logic specified by the user. For example, if a net is driven by two nets at the same time, Vivado will connect the net to ground, and raise a critical warning. In this case, a valid bitstream is still generated, but it doesn't configure the FGPA in a way that will match simulation.} Playing signals back in simulation allows for easy comparison between simulated and measured input, and the state of the logic downstream.
-
- \item \textit{Sparse Sampling.} When users are debugging, their fundamental concern is the state of their logic. Normally this is obtained by sampling every net of interest with a logic analyzer probe, but for designs with a large amount of internal state sampling many signals requires significant block memory and lots of time to set up. If the design has fewer inputs than state variables, it requires fewer resources to sample the states and simulate the logic than to directly sample the state. For instance, debugging a misbehaving branch predictor in a CPU can be done by recording its address and data busses, playing them back in simulation, and inspecting the branch predictor there. This frees the user from having to sample the entire pattern history table, which would consume significant block memory.
-\end{itemize}
-
-\subsubsection{Reprogrammable Triggers}
-Manta's triggers are reprogrammable, such that rebuilding source code is not necessary to change the trigger condition. Each of the logic analyzer's input probes has a trigger assigned to it, which continuously evaluates some combinational function on the input. This logic can be programmed to check for rising edges, falling edges or any change at all. It can also be programmed to check the result of a logical operation (such as $>$, $\leq$, $=$, $\neq$, etc.) against an \textit{argument}. The operation and argument for each probe's trigger are set with a pair of registers in Manta's memory.
-
-The output of each of the individual triggers is then combined to trigger the logic analyzer core as a whole. These are combined with a $N$-input logic gate (either AND or OR) specified by the user through another register in memory. As a result the entire trigger configuration is specified by the state of Manta's memory, and changes to the configuration require resetting registers, not resynthesizing bitstreams.
-
-However, this greatly restricts the trigger conditions users can specify. To mitigate this, Manta provides an option for an external trigger that allows for more complex triggers. When enabled, Manta adds an input port to the \texttt{manta} Verilog module, and triggers off its value, rather than the internal comparators. This allows users to provide their own Verilog to produce the desired trigger condition.
-
-\subsection{Architecture}
+## How It Works
The Logic Analyzer Core's implementation on the FPGA consists of three primary components:
-\begin{itemize}
- \item The \textit{Finite State Machine (FSM)}, which controls the operation of the core. The FSM's operation is driven by its associated registers, which are placed in a separate module. This permits simple CDC between the bus and user clock domains.
+
- \item The \textit{Trigger Block}, which generates the core's trigger condition. The trigger block contains a trigger for each input probe, and the registers necessary to configure them. It also contains the $N$-logic gate (either AND or OR) that generates the core's trigger from the individual probe triggers. CDC is performed in exactly the same manner as the FSM. If an external trigger is specified, the trigger block is omitted from the Logic Analyzer Core, and the external trigger is routed to the FSM's \texttt{trig} input.
-
- \item The \textit{Sample Memory}, which stores the states of the probes during a capture. This is implemented as a dual-port, dual-clock block memory, with the bus on one port and the probes on the other. The probe-connected port only writes to the memory, with the address and enable pins managed by the FSM. CDC is performed in the block RAM primitive itself.
+- The _Finite State Machine (FSM)_, which controls the operation of the core. The FSM's operation is driven by its associated registers, which are placed in a separate module. This permits simple CDC between the bus and user clock domains.
+- The _Trigger Block_, which generates the core's trigger condition. The trigger block contains a trigger for each input probe, and the registers necessary to configure them. It also contains the $N$-logic gate (either AND or OR) that generates the core's trigger from the individual probe triggers. CDC is performed in exactly the same manner as the FSM. If an external trigger is specified, the trigger block is omitted from the Logic Analyzer Core, and the external trigger is routed to the FSM's `trig` input.
+- The _Sample Memory_, which stores the states of the probes during a capture. This is implemented as a dual-port, dual-clock block memory, with the bus on one port and the probes on the other. The probe-connected port only writes to the memory, with the address and enable pins managed by the FSM. CDC is performed in the block RAM primitive itself.
\end{itemize}
-\begin{figure}[h!]
-\centering
-\includegraphics[width=\textwidth]{manta_logic_analyzer_architecture.png}
-\caption[Block diagram of the Logic Analyzer Core.]{Block diagram of the Logic Analyzer Core. Blocks in blue are clocked on the bus clock, and blocks in orange are clocked on the user clock.}
-\label{manta_logic_analyzer_architecture_fig}
-\end{figure}
+
+
diff --git a/doc/repository_structure.md b/doc/repository_structure.md
index 97767f2..157410a 100644
--- a/doc/repository_structure.md
+++ b/doc/repository_structure.md
@@ -6,7 +6,7 @@
- `.github/` also contains some GitHub Actions configuration for automatically running the SystemVerilog testbenches and building the examples, in addition to automatically rebuilding the site.
## Tools Used
-- Icarus Verilog is used for functional simulation.
-- The Project Icestorm tools and Vivado are used for building bitstreams.
-- Wavedrom is used for for waveform diagrams, and draw.io for block diagrams
-- GitHub Pages is used to serve the documentation site.
\ No newline at end of file
+- [Icarus Verilog](https://github.com/steveicarus/iverilog) is used for functional simulation.
+- The [YosysHQ](https://github.com/YosysHQ) tools and [Vivado](https://www.xilinx.com/products/design-tools/vivado.html) are used for building bitstreams.
+- [Wavedrom](https://wavedrom.com/) is used for for waveform diagrams, and [draw.io](https://app.diagrams.net/) for block diagrams
+- [GitHub Pages](https://pages.github.com/) is used to serve the documentation site.
\ No newline at end of file
diff --git a/mkdocs.yml b/mkdocs.yml
index 941e7b0..fc153e0 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -1,4 +1,4 @@
-site_name: manta
+site_name: "Manta Documentation"
site_description: Manta Documentation
site_author: Fischer Moseley
@@ -63,7 +63,7 @@ nav:
- IO Core: io_core.md
- Logic Analyzer Core: logic_analyzer.md
- Block Memory Core: block_memory.md
- - Ethernet Interface: ethernet.md
- - UART: uart.md
+ # - Ethernet Interface: ethernet.md
+ # - UART: uart.md
- Repository Structure: repository_structure.md
- Roadmap: roadmap.md