update docs

This commit is contained in:
Fischer Moseley 2024-03-07 12:25:30 -08:00
parent 355b5d8c76
commit e0aeb38cdb
10 changed files with 281 additions and 369 deletions

View File

@ -8,5 +8,5 @@ format:
clean:
git clean -Xdf
serve_docs:
preview_site:
mkdocs serve

View File

@ -86,13 +86,19 @@ Each Memory core is actually a set of 16-bit wide BRAMs with their ports concate
Since each $n$-bit wide block memory is actually $ceil(n/16)$ BRAMs under the hood, addressing the BRAMs correctly from Manta's internal bus is important. BRAMs are organized such that each 16-bit slice of a $N$-bit word in the Block Memory core are placed next to each other in bus address space. For instance, a 34-bit wide block memory would exist on Manta's internal bus as:
| Bus Address Space | BRAM Address Space |
| ----------- | -------------------- |
| BASE_ADDR + 0 | address 0, bits 0-15 |
| BASE_ADDR + 1 | address 0, bits 16-31|
| BASE_ADDR + 2 | address 0, bits 32-33|
| BASE_ADDR + 3 | address 1, bits 0-15 |
| BASE_ADDR + 4 | address 1, bits 16-31|
| BASE_ADDR + 5 | address 1, bits 32-33|
| Bus Address Space | BRAM Address Space |
| ----------- | -------------------- |
| BASE_ADDR + 0 | address 0, bits 0-15 |
| BASE_ADDR + 1 | address 1, bits 0-15 |
| BASE_ADDR + n | address n, bits 0-15 |
| ... | ... |
| BASE_ADDR + 0 + DEPTH | address 0, bits 16-31|
| BASE_ADDR + 1 + DEPTH | address 1, bits 16-31|
| BASE_ADDR + n + DEPTH | address n, bits 16-31|
| ... | ... |
| BASE_ADDR + 0 + (2 * DEPTH) | address 0, bits 32-33|
| BASE_ADDR + 1 + (2 * DEPTH) | address 1, bits 32-33|
| BASE_ADDR + n + (2 * DEPTH) | address n, bits 32-33|
| ... | ... |
...and so on.

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 98 KiB

After

Width:  |  Height:  |  Size: 38 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 126 KiB

After

Width:  |  Height:  |  Size: 123 KiB

View File

@ -1,4 +1,4 @@
<svg host="65bd71144e" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="731px" height="571px" viewBox="-0.5 -0.5 731 571" content="&lt;mxfile&gt;&lt;diagram id=&quot;Ll6ry4-GvlTqEIQv3LLv&quot; name=&quot;Page-1&quot;&gt;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&lt;/diagram&gt;&lt;/mxfile&gt;">
<svg host="65bd71144e" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="731px" height="571px" viewBox="-0.5 -0.5 731 571" content="&lt;mxfile&gt;&lt;diagram id=&quot;Ll6ry4-GvlTqEIQv3LLv&quot; name=&quot;Page-1&quot;&gt;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&lt;/diagram&gt;&lt;/mxfile&gt;">
<defs>
<style type="text/css">
/* cyrillic-ext */
@ -69,13 +69,13 @@
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 238px; height: 1px; padding-top: 490px; margin-left: 251px;">
<div data-drawio-colors="color: #333333; " style="box-sizing: border-box; font-size: 0px; text-align: center;">
<div style="display: inline-block; font-size: 12px; font-family: Roboto; color: rgb(51, 51, 51); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">
block RAM
RAM
</div>
</div>
</div>
</foreignObject>
<text x="370" y="494" fill="#333333" font-family="Roboto" font-size="12px" text-anchor="middle">
block RAM
RAM
</text>
</switch>
</g>
@ -101,7 +101,7 @@
<g transform="translate(-0.5 -0.5)">
<switch>
<foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-start; width: 1px; height: 1px; padding-top: 460px; margin-left: 212px;">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-start; width: 1px; height: 1px; padding-top: 461px; margin-left: 212px;">
<div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: left;">
<div style="display: inline-block; font-size: 11px; font-family: Roboto; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">
addr
@ -119,7 +119,7 @@
<g transform="translate(-0.5 -0.5)">
<switch>
<foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-start; width: 1px; height: 1px; padding-top: 480px; margin-left: 211px;">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-start; width: 1px; height: 1px; padding-top: 481px; margin-left: 212px;">
<div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: left;">
<div style="display: inline-block; font-size: 11px; font-family: Roboto; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">
din
@ -127,7 +127,7 @@
</div>
</div>
</foreignObject>
<text x="211" y="484" fill="rgb(0, 0, 0)" font-family="Roboto" font-size="11px">
<text x="212" y="484" fill="rgb(0, 0, 0)" font-family="Roboto" font-size="11px">
din
</text>
</switch>
@ -137,7 +137,7 @@
<g transform="translate(-0.5 -0.5)">
<switch>
<foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-start; width: 1px; height: 1px; padding-top: 499px; margin-left: 211px;">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-start; width: 1px; height: 1px; padding-top: 500px; margin-left: 211px;">
<div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: left;">
<div style="display: inline-block; font-size: 11px; font-family: Roboto; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">
dout
@ -155,7 +155,7 @@
<g transform="translate(-0.5 -0.5)">
<switch>
<foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-start; width: 1px; height: 1px; padding-top: 521px; margin-left: 211px;">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-start; width: 1px; height: 1px; padding-top: 522px; margin-left: 211px;">
<div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: left;">
<div style="display: inline-block; font-size: 11px; font-family: Roboto; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">
we
@ -209,13 +209,13 @@
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 238px; height: 1px; padding-top: 310px; margin-left: 251px;">
<div data-drawio-colors="color: #333333; " style="box-sizing: border-box; font-size: 0px; text-align: center;">
<div style="display: inline-block; font-size: 12px; font-family: Roboto; color: rgb(51, 51, 51); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">
block RAM
RAM
</div>
</div>
</div>
</foreignObject>
<text x="370" y="314" fill="#333333" font-family="Roboto" font-size="12px" text-anchor="middle">
block RAM
RAM
</text>
</switch>
</g>
@ -261,7 +261,7 @@
<g transform="translate(-0.5 -0.5)">
<switch>
<foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-start; width: 1px; height: 1px; padding-top: 270px; margin-left: 632px;">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-start; width: 1px; height: 1px; padding-top: 271px; margin-left: 632px;">
<div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: left;">
<div style="display: inline-block; font-size: 11px; font-family: Roboto; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">
user_addr
@ -274,8 +274,8 @@
</text>
</switch>
</g>
<path d="M 720 290 L 616.46 289.69" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/>
<path d="M 611.21 289.67 L 618.22 286.19 L 616.46 289.69 L 618.2 293.19 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/>
<path d="M 720 289.7 L 616.45 289.67" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/>
<path d="M 611.2 289.67 L 618.2 286.17 L 616.45 289.67 L 618.2 293.17 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/>
<g transform="translate(-0.5 -0.5)">
<switch>
<foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;">
@ -287,7 +287,7 @@
</div>
</div>
</foreignObject>
<text x="632" y="294" fill="rgb(0, 0, 0)" font-family="Roboto" font-size="11px">
<text x="632" y="293" fill="rgb(0, 0, 0)" font-family="Roboto" font-size="11px">
user_din
</text>
</switch>
@ -297,7 +297,7 @@
<g transform="translate(-0.5 -0.5)">
<switch>
<foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-start; width: 1px; height: 1px; padding-top: 310px; margin-left: 632px;">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-start; width: 1px; height: 1px; padding-top: 311px; margin-left: 632px;">
<div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: left;">
<div style="display: inline-block; font-size: 11px; font-family: Roboto; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">
user_dout
@ -310,8 +310,8 @@
</text>
</switch>
</g>
<path d="M 720 330 L 640 330.05 L 616.45 329.88" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/>
<path d="M 611.2 329.84 L 618.22 326.39 L 616.45 329.88 L 618.17 333.39 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/>
<path d="M 720 330 L 640 330 L 616.45 329.87" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/>
<path d="M 611.2 329.84 L 618.22 326.38 L 616.45 329.87 L 618.18 333.38 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/>
<g transform="translate(-0.5 -0.5)">
<switch>
<foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;">
@ -351,7 +351,7 @@
<g transform="translate(-0.5 -0.5)">
<switch>
<foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-start; width: 1px; height: 1px; padding-top: 300px; margin-left: 211px;">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-start; width: 1px; height: 1px; padding-top: 300px; margin-left: 212px;">
<div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: left;">
<div style="display: inline-block; font-size: 11px; font-family: Roboto; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">
din
@ -359,7 +359,7 @@
</div>
</div>
</foreignObject>
<text x="211" y="303" fill="rgb(0, 0, 0)" font-family="Roboto" font-size="11px">
<text x="212" y="303" fill="rgb(0, 0, 0)" font-family="Roboto" font-size="11px">
din
</text>
</switch>
@ -407,13 +407,13 @@
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 238px; height: 1px; padding-top: 140px; margin-left: 251px;">
<div data-drawio-colors="color: #333333; " style="box-sizing: border-box; font-size: 0px; text-align: center;">
<div style="display: inline-block; font-size: 12px; font-family: Roboto; color: rgb(51, 51, 51); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">
block RAM
RAM
</div>
</div>
</div>
</foreignObject>
<text x="370" y="144" fill="#333333" font-family="Roboto" font-size="12px" text-anchor="middle">
block RAM
RAM
</text>
</switch>
</g>
@ -474,7 +474,7 @@
<g transform="translate(-0.5 -0.5)">
<switch>
<foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-start; width: 1px; height: 1px; padding-top: 130px; margin-left: 211px;">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-start; width: 1px; height: 1px; padding-top: 130px; margin-left: 212px;">
<div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: left;">
<div style="display: inline-block; font-size: 11px; font-family: Roboto; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">
din
@ -482,7 +482,7 @@
</div>
</div>
</foreignObject>
<text x="211" y="133" fill="rgb(0, 0, 0)" font-family="Roboto" font-size="11px">
<text x="212" y="133" fill="rgb(0, 0, 0)" font-family="Roboto" font-size="11px">
din
</text>
</switch>
@ -601,12 +601,12 @@
</text>
</switch>
</g>
<path d="M 79.98 80.01 L 30.1 80.05 L 10 80" fill="none" stroke="rgb(0, 0, 0)" stroke-width="3" stroke-miterlimit="10" pointer-events="stroke"/>
<path d="M 86.73 80 L 77.73 84.51 L 79.98 80.01 L 77.72 75.51 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-width="3" stroke-miterlimit="10" pointer-events="all"/>
<path d="M 79.98 80 L 30.1 80 L 10 80" fill="none" stroke="rgb(0, 0, 0)" stroke-width="3" stroke-miterlimit="10" pointer-events="stroke"/>
<path d="M 86.73 80 L 77.73 84.5 L 79.98 80 L 77.73 75.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-width="3" stroke-miterlimit="10" pointer-events="all"/>
<g transform="translate(-0.5 -0.5)">
<switch>
<foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 81px; margin-left: 20px;">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 81px; margin-left: 21px;">
<div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;">
<div style="display: inline-block; font-size: 11px; font-family: Roboto; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">
bus
@ -614,17 +614,17 @@
</div>
</div>
</foreignObject>
<text x="20" y="84" fill="rgb(0, 0, 0)" font-family="Roboto" font-size="11px" text-anchor="middle">
<text x="21" y="84" fill="rgb(0, 0, 0)" font-family="Roboto" font-size="11px" text-anchor="middle">
bus
</text>
</switch>
</g>
<path d="M 90.08 520 L 30.1 520.05 L 20.1 520.02" fill="none" stroke="rgb(0, 0, 0)" stroke-width="3" stroke-miterlimit="10" pointer-events="stroke"/>
<path d="M 13.35 520.01 L 22.36 515.53 L 20.1 520.02 L 22.34 524.53 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-width="3" stroke-miterlimit="10" pointer-events="all"/>
<path d="M 90.08 520 L 30.1 520 L 20.1 520" fill="none" stroke="rgb(0, 0, 0)" stroke-width="3" stroke-miterlimit="10" pointer-events="stroke"/>
<path d="M 13.35 520 L 22.35 515.5 L 20.1 520 L 22.35 524.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-width="3" stroke-miterlimit="10" pointer-events="all"/>
<g transform="translate(-0.5 -0.5)">
<switch>
<foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 521px; margin-left: 43px;">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 521px; margin-left: 44px;">
<div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;">
<div style="display: inline-block; font-size: 11px; font-family: Roboto; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">
bus
@ -632,7 +632,7 @@
</div>
</div>
</foreignObject>
<text x="43" y="524" fill="rgb(0, 0, 0)" font-family="Roboto" font-size="11px" text-anchor="middle">
<text x="44" y="524" fill="rgb(0, 0, 0)" font-family="Roboto" font-size="11px" text-anchor="middle">
bus
</text>
</switch>

Before

Width:  |  Height:  |  Size: 112 KiB

After

Width:  |  Height:  |  Size: 112 KiB

View File

@ -5,7 +5,7 @@ To use Manta, you'll need a host machine with a FPGA board connected over UART,
- _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.
- _Instantiate `manta` in your design, and connecting it to the logic you'd like to debug._ Manta will provide an example instantiation if you run `manta inst [config_file]`, which you can copy-paste into your 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.
@ -58,12 +58,12 @@ This Manta instance has an IO Core and a Logic Analyzer, each containing a numbe
## Example Instantiation
Lastly, we Manta can automatically generate a copy-pasteable Verilog snippet to instantiate Manta in your design. This is done by running `manta inst` with the path to the configuration file describing the Manta core you'd like to instantiate. For example, the following snippet is generated for the configuration above:
Lastly, we Manta can automatically generate a copy-pasteable Verilog snippet to instantiate Manta in your design by running `manta inst [config_file]`. For example, the following snippet is generated for the configuration above:
```verilog
manta manta_inst (
.clk(clk),
.rst(rst)
.rst(rst),
.rx(rx),
.tx(tx),
.probe_0_in(probe_0_in),

View File

@ -43,22 +43,26 @@ Inside this configuration, the following parameters may be configured:
## Python API
The IO core functionality is stored in the `Manta.IOCore`, `Manta.InputProbe`, and `Manta.OutputProbe` classes in [src/manta/io_core/\_\_init\_\_.py](https://github.com/fischermoseley/manta/blob/main/src/manta/io_core/__init__.py), and it may be controlled with the two functions:
`Manta.IOCoreProbe.set(data)`
- [`int`, `bool`] _data_: The value to write to an output probe. May be signed or unsigned, but will raise an exception if the value is too large for the width of the port.
- _returns_: None
This method is blocking. When called it will dispatch a request to the FPGA, and wait until a response has been received.
The IO core functionality is stored in the `Manta.IOCore` class in [src/manta/io_core/\_\_init\_\_.py](https://github.com/fischermoseley/manta/blob/main/src/manta/io_core.py), and it may be controlled with the two functions:
---
`Manta.IOCoreProbe.get()`
`Manta.IOCore.set_probe(name, data)`
- [`string`] _name_: The probe to write to. Must not be an output port, and must match the name provided in the config file.
- [`int`, `bool`] _data_: The value to write to an output probe. May be signed or unsigned, but will raise an exception if the value is too large for the width of the port.
- _returns_: None
This method is blocking. When called it will dispatch a request to the FPGA, and halt execution until the request has been sent.
---
`Manta.IOCore.get_probe(name)`
- [`string`] _name_: The probe to read from. May be either an input or an output port, and must match the name provided in the config file.
- _returns_: The value of an input or output probe. In the case of an output probe, the value returned will be the last value written to the probe.
This method is blocking. When called it will dispatch a request to the FPGA, and wait until a response has been received.
This method is blocking. When called it will dispatch a request to the FPGA, and halt execution until the request has been sent and a response has been received.
---
@ -70,11 +74,11 @@ A small example is shown below, using the [example configuration](#configuration
```python
>>> import Manta
>>> m = Manta
>>> m.my_io_core.fozzy.set(True)
>>> m.my_io_core.fozzy.get()
>>> m.my_io_core.set_probe("fozzy", True)
>>> m.my_io_core.get_probe("fozzy")
True
>>> m.my_io_core.gonzo.set(4)
>>> m.my_io_core.scooter.get()
>>> m.my_io_core.set_probe("gonzo", 4)
>>> m.my_io_core.get_probe("scooter")
5
```

View File

@ -67,17 +67,9 @@ Each individual trigger is specified with the following structure:
Lastly, if you're not able to express your desired trigger condition in terms of the operators above, fear not! You can also specify an `external_trigger: true` entry in the config file, which exposes an input on Manta's top level for your own trigger.
### Trigger Position (optional)
Sometimes, you care more about what happens before a trigger is met than afterwards, or vice versa. To accommodate 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 occurring. This is best explained with a picture:
Sometimes, you care more about what happens before a trigger is met than afterwards, or vice versa. To accommodate 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 occurring. This is similar to a "holdoff" option on a traditional oscilloscope or logic analyzer.
![](assets/trigger_positions.png){style="width:90%"}
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.
If `trigger_position` is not specified, Manta will default to centering the capture window around the trigger condition. This results in just as many samples before the trigger as after.
### Capture Modes (optional)
The logic analyzer has a few different ways of capturing data, which are represented by the _capture modes_ below:
@ -125,5 +117,5 @@ This is useful for two situations in particular:
- _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 efficient 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 FPGA resources than sampling the entire pattern history table.
## Python API
The Logic Analyzer core functionality is stored in the `Manta.LogicAnalyzerCore` class in [src/manta/la_core/\_\_init\_\_.py](https://github.com/fischermoseley/manta/blob/main/src/manta/la_core/__init__.py). This class contains methods for capturing data, and exporting `.vcd` and `.v` files.
The Logic Analyzer core functionality is stored in the `Manta.LogicAnalyzerCore` class in [src/manta/la_core/\_\_init\_\_.py](https://github.com/fischermoseley/manta/blob/main/src/manta/la_core/__init__.py). This class contains methods for capturing data, exporting it as `.vcd`, `.v` or `.csv` files, or as a Python list.

View File

@ -1,18 +1,19 @@
## Overview
Block Memory (also called Block RAM, or BRAM) is the de facto means of storing data on FPGAs when the space needed exceeds a few registers. As a result, Manta provides a Block Memory core, which instantiates a dual-port BRAM on the FPGA. One port is provided to the host, and the other is connected to your logic with the standard BRAM interface (`addr`, `din`, `dout`, `wea`). This allows the host to provide reasonably large amounts of data to user logic - or the other way around, or a mix of both!
Memory is the de facto means of storing data on FPGAs when the space needed exceeds a few registers. As a result, Manta provides a Memory core, which instantiates a dual-port RAM on the FPGA. One port is provided to the host, and the other is connected to your logic with the standard RAM interface (`addr`, `data_in`, `data_out`, `write_enable`). This allows the host to provide reasonably large amounts of data to user logic - or the other way around, or a mix of both!
This is a very, very simple task - and while configuration is straightforward, there are a few caveats. More on both topics below:
## Configuration
Just like the rest of the cores, the Block Memory core is configured via an entry in a project's configuration file. This is easiest to show by example:
Just like the rest of the cores, the Memory core is configured via an entry in a project's configuration file. This is easiest to show by example:
```yaml
---
cores:
my_block_memory:
type: block_memory
my_memory:
type: memory
mode: bidirectional
width: 12
depth: 16384
@ -20,34 +21,38 @@ cores:
There's a few parameters that get configured here, including:
- `name`: The name of the Block Memory 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 Block Memory core. All cores contain a `type` field, which must be set to `block_memory` to be recognized as an Block Memory core.
- `name`: The name of the Memory 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 Memory core. All cores contain a `type` field, which must be set to `memory` to be recognized as an Memory core.
- `mode`: The mode for the Memory core to operate in. This must be one of `bidirectional`, `host_to_fpga`, or `fpga_to_host`. Bidirectional memories can be both read or written to by the host and FPGA, but they require the use of a True Dual Port RAM, which is not available on all platforms (most notably, the ice40). Host-to-fpga and fpga-to-host RAMs only require a Simple Dual Port RAM, which is available on nearly all platforms.
- `width`: The width of the Memory core, in bits.
- `depth`: The depth of the Memory core, in entries.
### Dimensions
The dimensions of the block memory are specified in the config file with the `width` and `depth` entries.
Manta won't impose any limit on the width or depth of the memory you instantiate, but since Manta instantiates BRAM primitives on the FPGA, you will be limited by what your FPGA can support. It helps to know your particular FPGA's architecture here.
Manta won't impose any limit on the width or depth of the block memory you instantiate, but since Manta instantiates BRAM primitives on the FPGA, you will be limited by what your FPGA can support. It helps to know your particular FPGA's architecture here.
!!! warning "Bidirectional memories are currently broken on Xilinx platforms."
Due to a bug in Amaranth, trying to use a bidirectional memory on a Xilinx platform will cause Vivado to throw an `Unable to infer RAMs due to unsupported pattern.` error. This is a known issue, and has been reported [here](https://github.com/amaranth-lang/amaranth/issues/1011). In the meantime, if you have a Xilinx device, consider if your data flow is unidirectional, and you could use the `host_to_fpga` or `fpga_to_host` modes. Other platforms with dual-port RAM capability (such as the Lattice ECP5) appear to not be affected by this issue.
If your BRAM is more than 16 bits wide, check out the section on [Synchronicity](#synchronicity) and make sure your project will tolerate how Manta writes to the block memory.
### On-Chip Implementation
For most use cases, Manta will choose to implement the memory in Block RAM, if it is available on the device. However, the Verilog produced by Manta may be inferred to a number of memory types, including FF RAM or LUT (Distributed) RAM. For more information on how this is chosen, please refer to the [Yosys documentation](https://yosyshq.readthedocs.io/projects/yosys/en/latest/CHAPTER_Memorymap.html).
### Python API
The Block Memory core functionality is stored in the `Manta.IOCore` and `Manta.IOCoreProbe` classes in [src/manta/io_core/\_\_init\_\_.py](https://github.com/fischermoseley/manta/blob/main/src/manta/io_core/__init__.py), and it may be controlled with the two functions:
The Memory core functionality is stored in the `Manta.MemoryCore` classes in [src/manta/memory_core.py](https://github.com/fischermoseley/manta/blob/main/src/manta/memory_core.py), and it may be controlled with the two functions:
Just like with the other cores, interfacing with the BRAM with the Python API is simple:
Just like with the other cores, interfacing with the Memory with the Python API is simple:
```python
from manta import Manta
m = manta('manta.yaml')
m.my_block_memory.write(addr=38, data=600)
m.my_block_memory.write(addr=0x1234, data = 0b100011101011)
m.my_block_memory.write(0x0612, 0x2001)
m.my_memory.write(addr=38, data=600)
m.my_memory.write(addr=0x1234, data = 0b100011101011)
m.my_memory.write(0x0612, 0x2001)
foo = m.my_block_memory.write(addr=38)
foo = m.my_block_memory.write(addr=1234)
foo = m.my_block_memory.write(0x0612)
foo = m.my_memory.write(addr=38)
foo = m.my_memory.write(addr=1234)
foo = m.my_memory.write(0x0612)
```
Reading/writing in batches is also supported. This is recommended where possible, as reads are massively sped up by performing them in bulk:
@ -55,19 +60,15 @@ Reading/writing in batches is also supported. This is recommended where possible
```python
addrs = list(range(0, 1234))
datas = list(range(1234, 2468))
m.my_block_memory.write(addrs, datas)
m.my_memory.write(addrs, datas)
foo = m.my_block_memory.read(addrs)
foo = m.my_memory.read(addrs)
```
### Examples
A Block Memory core is used in the [video_sprite](https://github.com/fischermoseley/manta/blob/main/examples/nexys_a7/video_sprite) example. This uses the core to store a 128x128 image sprite in 12-bit color, and outputs it to a VGA display at 1024x768. The sprite contents can be filled with an arbitrary image using the [send_image.py](https://github.com/fischermoseley/manta/blob/main/examples/nexys_a7/video_sprite/send_image.py) python script.
### Synchronicity
Since Manta's [data bus](architecture.md#data-bus) is only 16-bits wide, it's only possible to manipulate the BRAM core in 16-bit increments. This means that if you have a BRAM that's ≤16 bits wide, you'll only need to issue a single bus transaction to read/write one entry in the BRAM. However, if you have a BRAM that's ≥16 bits wide, you'll need to issue a bus transaction to update each 16-bit slice of it. For instance, updating a single entry in a 33-bit wide BRAM would require sending 3 messages to the FPGA: one for bits 1-16, another for bits 17-32, and one for bit 33. If your application expects each BRAM entry to update instantaneously, this could be problematic.
Since Manta's [data bus](architecture.md#data-bus) is only 16-bits wide, it's only possible to manipulate the Memory core in 16-bit increments. This means that if you have a RAM that's ≤16 bits wide, you'll only need to issue a single bus transaction to read/write one entry in the RAM. However, if you have a RAM that's ≥16 bits wide, you'll need to issue a bus transaction to update each 16-bit slice of it. For instance, updating a single entry in a 33-bit wide RAM would require sending 3 messages to the FPGA: one for bits 1-16, another for bits 17-32, and one for bit 33. If your application expects each RAM entry to update instantaneously, this could be problematic.
There's a few different ways to solve this - you could use an IO core to signal when a BRAM's contents or valid - or you could ping-pong between two BRAMs while one is being modified. The choice is yours, and Manta makes no attempt to prescribe any particular approach.
There's a few different ways to solve this - you could use an IO core to signal when a RAM's contents or valid - or you could ping-pong between two RAMs while one is being modified. The choice is yours, and Manta makes no attempt to prescribe any particular approach.
Lastly, the interface you use (and to a lesser extent, your operating system) will determine the space between bus transactions. For instance, 100Mbit Ethernet is a thousand times faster than 115200bps UART, so the time where the BRAM is invalid is a thousand times smaller.
Lastly, the interface you use (and to a lesser extent, your operating system) will determine the space between bus transactions. For instance, 100Mbit Ethernet is a thousand times faster than 115200bps UART, so the time where the RAM is invalid is a thousand times smaller.

View File

@ -1,15 +1,15 @@
## Repository Structure
- `src/manta/` contains the Python and Verilog source needed to generate and run the cores.
- `test/` contains testbenchs for HDL. Manta is written in Verilog 2001, but the testbenches are written in SystemVerilog 2012. These are simulated using Icarus Verilog, which produces `.vcd` files, viewable with your favorite waveform viewer, like GTKWave.
- `doc/` contains the documentation you're reading right now! It's built into a nice static site by Material for MkDocs, which automatically rebuilds the site on every commit to `main`. This is done with a GitHub Action configured in `.github/`
- `examples/` is exactly what it sounds like. It contains examples for both the Digilent Nexys 4 DDR/Nexys A7 with thier onboard Series-7, as well as the Icestick with its onboard iCE40.
- `.github/` also contains some GitHub Actions configuration for automatically running the SystemVerilog testbenches and building the examples, in addition to automatically rebuilding the site.
- `src/manta/` contains the Python source needed to generate and run the cores.
- `test/` contains Manta's tests, which are a mix of functional simulations and hardware-in-the-loop testing. These tests leverage the `pytest` testing framework.
- `doc/` contains the documentation you're reading right now!
- `examples/` contains examples for both the Digilent Nexys 4 DDR/Nexys A7 with thier onboard Series-7, as well as the Icestick with its onboard iCE40.
- `.github/` contains GitHub Actions workflows for automatically running the tests and building the documentation site on every commit.
## Tools Used
- 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
- [draw.io](https://app.diagrams.net/) is used for block diagrams.
- [GitHub Pages](https://pages.github.com/) is used to serve the documentation site, which is built with [Material for MkDocs](https://squidfunk.github.io/mkdocs-material/).
- [GitHub Actions](https://docs.github.com/en/actions) is used for continuous integration.
## GitHub Actions Setup
Since Vivado is large and requires individual licenses it's run on a private server, which is configured as a self-hosted runner in GitHub Actions. This is a virtual server hosted with KVM/QEMU and managed by libvirt, which is configured as transient so that it reloads its state from a snapshot periodically. A Nexys A7 and Icestick are connected to the physical machine and passthrough-ed to this VM so that continuous integration can check against real hardware.
Since Vivado is large and requires individual licenses, it is run on a private server, which is configured as a self-hosted runner in GitHub Actions. This is a virtual server hosted with KVM/QEMU and managed by libvirt, which is configured as transient so that it reloads its state from a snapshot periodically. A Nexys A7 and Icestick are connected to the physical machine and passthrough-ed to this VM so that continuous integration can check against real hardware.