meta: add pre-commit, commit changes it makes
|
|
@ -15,7 +15,7 @@ jobs:
|
|||
# Update pip
|
||||
python3 -m pip install -U pip
|
||||
|
||||
# omitting the following commmand causes the version of setuptools
|
||||
# omitting the following command causes the version of setuptools
|
||||
# used by python to get confused, and it doesn't detect the name
|
||||
# or version of the package from pyproject.toml - so the following
|
||||
# workaround is used:
|
||||
|
|
@ -39,4 +39,4 @@ jobs:
|
|||
- name: Upload results to Codecov
|
||||
run: |
|
||||
source venv/bin/activate
|
||||
python3 -m codecov -t ${{ secrets.CODECOV_TOKEN }}
|
||||
python3 -m codecov -t ${{ secrets.CODECOV_TOKEN }}
|
||||
|
|
|
|||
|
|
@ -29,4 +29,4 @@ build/
|
|||
# Yosys/IceStorm files
|
||||
*.asc
|
||||
*.bin
|
||||
*.json
|
||||
*.json
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
repos:
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v5.0.0
|
||||
hooks:
|
||||
- id: check-yaml
|
||||
- id: end-of-file-fixer
|
||||
- id: trailing-whitespace
|
||||
- id: check-added-large-files
|
||||
- id: destroyed-symlinks
|
||||
|
||||
- repo: https://github.com/astral-sh/ruff-pre-commit
|
||||
rev: v0.8.0
|
||||
hooks:
|
||||
- id: ruff
|
||||
args: [--select, I, --fix, --exit-non-zero-on-fix]
|
||||
- id: ruff-format
|
||||
|
||||
- repo: https://github.com/shellcheck-py/shellcheck-py
|
||||
rev: v0.10.0.1
|
||||
hooks:
|
||||
- id: shellcheck
|
||||
|
|
@ -671,4 +671,4 @@ into proprietary programs. If your program is a subroutine library, you
|
|||
may consider it more useful to permit linking proprietary applications with
|
||||
the library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License. But first, please read
|
||||
<https://www.gnu.org/licenses/why-not-lgpl.html>.
|
||||
<https://www.gnu.org/licenses/why-not-lgpl.html>.
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
ignore:
|
||||
- "test/"
|
||||
- "test/"
|
||||
|
|
|
|||
|
|
@ -443,4 +443,4 @@
|
|||
</text>
|
||||
</a>
|
||||
</switch>
|
||||
</svg>
|
||||
</svg>
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 38 KiB |
|
|
@ -394,4 +394,4 @@
|
|||
</text>
|
||||
</a>
|
||||
</switch>
|
||||
</svg>
|
||||
</svg>
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 90 KiB After Width: | Height: | Size: 90 KiB |
|
|
@ -775,4 +775,4 @@
|
|||
</text>
|
||||
</a>
|
||||
</switch>
|
||||
</svg>
|
||||
</svg>
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 123 KiB After Width: | Height: | Size: 123 KiB |
|
|
@ -140,13 +140,13 @@
|
|||
<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
|
||||
doubt
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</foreignObject>
|
||||
<text x="211" y="503" fill="rgb(0, 0, 0)" font-family="Roboto" font-size="11px">
|
||||
dout
|
||||
doubt
|
||||
</text>
|
||||
</switch>
|
||||
</g>
|
||||
|
|
@ -300,13 +300,13 @@
|
|||
<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
|
||||
user_doubt
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</foreignObject>
|
||||
<text x="632" y="314" fill="rgb(0, 0, 0)" font-family="Roboto" font-size="11px">
|
||||
user_dout
|
||||
user_doubt
|
||||
</text>
|
||||
</switch>
|
||||
</g>
|
||||
|
|
@ -372,13 +372,13 @@
|
|||
<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: 319px; 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
|
||||
doubt
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</foreignObject>
|
||||
<text x="211" y="322" fill="rgb(0, 0, 0)" font-family="Roboto" font-size="11px">
|
||||
dout
|
||||
doubt
|
||||
</text>
|
||||
</switch>
|
||||
</g>
|
||||
|
|
@ -495,13 +495,13 @@
|
|||
<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: 149px; 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
|
||||
doubt
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</foreignObject>
|
||||
<text x="211" y="152" fill="rgb(0, 0, 0)" font-family="Roboto" font-size="11px">
|
||||
dout
|
||||
doubt
|
||||
</text>
|
||||
</switch>
|
||||
</g>
|
||||
|
|
@ -665,4 +665,4 @@
|
|||
</text>
|
||||
</a>
|
||||
</switch>
|
||||
</svg>
|
||||
</svg>
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 112 KiB After Width: | Height: | Size: 112 KiB |
|
|
@ -331,7 +331,7 @@
|
|||
</div>
|
||||
</foreignObject>
|
||||
<text x="313" y="119" fill="rgb(0, 0, 0)" font-family="Roboto" font-size="12px" text-anchor="middle">
|
||||
USB-UART Conver...
|
||||
USB-UART Convert...
|
||||
</text>
|
||||
</switch>
|
||||
</g>
|
||||
|
|
@ -344,4 +344,4 @@
|
|||
</text>
|
||||
</a>
|
||||
</switch>
|
||||
</svg>
|
||||
</svg>
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 86 KiB After Width: | Height: | Size: 86 KiB |
|
|
@ -1208,4 +1208,4 @@
|
|||
</text>
|
||||
</a>
|
||||
</switch>
|
||||
</svg>
|
||||
</svg>
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 149 KiB After Width: | Height: | Size: 149 KiB |
|
|
@ -2,20 +2,20 @@
|
|||
signal: [
|
||||
{name: 'clk', wave: 'p...|....'},
|
||||
{},
|
||||
['input port',
|
||||
['input port',
|
||||
{name: 'addr', wave: 'x3x.|....', data: ['A0']},
|
||||
{name: 'data', wave: 'x5x.|....', data: ["D0"]},
|
||||
{name: 'rw', wave: 'x1x.|....'},
|
||||
{name: 'valid', wave: '010.|....'},
|
||||
{name: 'valid', wave: '010.|....'},
|
||||
],
|
||||
|
||||
{}, {},
|
||||
|
||||
['output port',
|
||||
['output port',
|
||||
{name: 'addr', wave: 'x...|.3x.', data: ['A0']},
|
||||
{name: 'data', wave: 'x...|.5x.', data: ['D0']},
|
||||
{name: 'rw', wave: 'x...|.1x.'},
|
||||
{name: 'valid', wave: '0...|.10.'},
|
||||
{name: 'valid', wave: '0...|.10.'},
|
||||
],
|
||||
|
||||
{}, {},
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
## Overview
|
||||
|
||||
For applications where UART is too slow or isn't available, Manta provides the option to run over Ethernet. This is done via UDP, so the FPGA can be anywhere on the same network as the host machine - as opposed to MAC-based Ethernet interfaces, which usually require a point-to-point network connection between the FPGA and the host. Although UDP does not guaruntee reliable, in-order packet delivery, this generally tends to be the case on uncongested networks. In the future, Manta will enforce this at the [application layer](https://github.com/fischermoseley/manta/issues/10).
|
||||
For applications where UART is too slow or isn't available, Manta provides the option to run over Ethernet. This is done via UDP, so the FPGA can be anywhere on the same network as the host machine - as opposed to MAC-based Ethernet interfaces, which usually require a point-to-point network connection between the FPGA and the host. Although UDP does not guarantee reliable, in-order packet delivery, this generally tends to be the case on uncongested networks. In the future, Manta will enforce this at the [application layer](https://github.com/fischermoseley/manta/issues/10).
|
||||
|
||||
!!! info "Not every device is supported!"
|
||||
|
||||
|
|
@ -46,7 +46,7 @@ Inside this configuration, the following parameters may be set:
|
|||
|
||||
- `udp_port` _(optional)_: The UDP port to communicate over. Defaults to 2001.
|
||||
|
||||
Lastly, any additonal arguments provided in the `ethernet` section of the config file will be passed to the LiteEth standalone core generator. As a result, the [examples](https://github.com/enjoy-digital/liteeth/tree/master/examples) provided by LiteEth may be of some service to you if you're bringing up a different FPGA!
|
||||
Lastly, any additional arguments provided in the `ethernet` section of the config file will be passed to the LiteEth standalone core generator. As a result, the [examples](https://github.com/enjoy-digital/liteeth/tree/master/examples) provided by LiteEth may be of some service to you if you're bringing up a different FPGA!
|
||||
|
||||
!!! warning "LiteEth doesn't always generate its own `refclk`!"
|
||||
|
||||
|
|
@ -70,4 +70,4 @@ For more information on the connections between your PHY and FPGA, please refere
|
|||
- set_rmii_phy_io
|
||||
- set_gmii_phy_io
|
||||
- set_rgmii_phy_io
|
||||
- set_sgmii_phy_io
|
||||
- set_sgmii_phy_io
|
||||
|
|
|
|||
|
|
@ -112,4 +112,3 @@ It’s worth noting that this usage represents a slight departure from typical A
|
|||
This is necessary as the `Manta` object contains both HDL needed for build and methods for operating the cores. Saving the `Manta` instance in the class and re-using it later removes the need to define and configure separate instances when elaborating and operating the cores.
|
||||
|
||||
Lastly, including `manta` as an instance variable also allows it to be directly accessed from an interpreter, as shown above. This allows for a more interactive debugging session, as the definition of the `operate` method doesn’t have to change when you wish to use Manta’s cores differently.
|
||||
|
||||
|
|
|
|||
|
|
@ -25,9 +25,10 @@ If you're working on the source, you might want an editable installation with so
|
|||
git clone https://github.com/fischermoseley/manta.git
|
||||
cd manta
|
||||
pip install -e ".[dev]"
|
||||
pre-commit install
|
||||
```
|
||||
|
||||
Manta's hardware-in-the-loop tests rely on Amaranth's build system for programming FPGAs, which in turn rely on the open-source `xc3sprog` and `iceprog` tools for programming Xilinx and ice40 devices, respecitvely. If you'd like to run these tests locally, you may need to install these tools and have them available on your `PATH`.
|
||||
Manta's hardware-in-the-loop tests rely on Amaranth's build system for programming FPGAs, which in turn rely on the open-source `xc3sprog` and `iceprog` tools for programming Xilinx and ice40 devices, respectively. If you'd like to run these tests locally, you may need to install these tools and have them available on your `PATH`.
|
||||
|
||||
If you're on Linux, you may also need to add a new udev rule to give non-superuser accounts access to any connected FTDI devices. This can be done by making a new file at `/etc/udev/rules.d/99-ftdi-devices.rules`, which contains:
|
||||
|
||||
|
|
@ -49,4 +50,4 @@ Although optional, it is convenient to add the `manta` executable to your system
|
|||
|
||||
- macOS/Linux/BSD: `$HOME/.local/bin`, or `path\to\venv\bin` if using a virtual environment.
|
||||
|
||||
This also adds any other Python scripts exposed by your installed packages to your PATH.
|
||||
This also adds any other Python scripts exposed by your installed packages to your PATH.
|
||||
|
|
|
|||
|
|
@ -122,4 +122,4 @@ This is useful for two situations in particular:
|
|||
|
||||
::: manta.LogicAnalyzerCapture
|
||||
|
||||
::: manta.LogicAnalyzerPlayback
|
||||
::: manta.LogicAnalyzerPlayback
|
||||
|
|
|
|||
|
|
@ -9,12 +9,12 @@ Manta won't impose any limit on the width or depth of the memory you instantiate
|
|||
|
||||
!!! warning "Words update 16 bits at a time!"
|
||||
|
||||
Due to the structure of Manta's internal bus, the Memory core only updates 16 bits of a word at a time. For instance, writing a new value to a 33-bit wide memory would update bits 0-15 on one clock cycle, bits 16-31 on another, and bit 32 on another still. Manta makes no guaruntees about the time taken between each of these updates. If this is a problem for your application, consider using an IO Core as a doorbell to signal when the memory is valid, or ping-pong between two Memory Cores.
|
||||
Due to the structure of Manta's internal bus, the Memory core only updates 16 bits of a word at a time. For instance, writing a new value to a 33-bit wide memory would update bits 0-15 on one clock cycle, bits 16-31 on another, and bit 32 on another still. Manta makes no guarantees about the time taken between each of these updates. If this is a problem for your application, consider using an IO Core as a doorbell to signal when the memory is valid, or ping-pong between two Memory Cores.
|
||||
|
||||
|
||||
## On-Chip Implementation
|
||||
|
||||
Manta will make a best-effort attempt to implement the memory in Block RAM, if it is available on the device. This is done by exporting Verilog that synthesis tools should infer as Block RAMs, however this inference is not guarunteed. Depending on your toolchain and the FPGA's architecture, the Verilog produced by Manta may be implemented as FF RAM, LUT (Distributed) RAM, or something else. These memory types are well explained in the [Yosys documentation](https://yosyshq.readthedocs.io/projects/yosys/en/latest/using_yosys/synthesis/memory.html), but be sure to check your toolchain's documentation as well.
|
||||
Manta will make a best-effort attempt to implement the memory in Block RAM, if it is available on the device. This is done by exporting Verilog that synthesis tools should infer as Block RAMs, however this inference is not guaranteed. Depending on your toolchain and the FPGA's architecture, the Verilog produced by Manta may be implemented as FF RAM, LUT (Distributed) RAM, or something else. These memory types are well explained in the [Yosys documentation](https://yosyshq.readthedocs.io/projects/yosys/en/latest/using_yosys/synthesis/memory.html), but be sure to check your toolchain's documentation as well.
|
||||
|
||||
## Configuration
|
||||
|
||||
|
|
|
|||
|
|
@ -5,4 +5,4 @@
|
|||
<a href="{{ '../' ~ base_url }}">
|
||||
<strong>Click here to go to latest.</strong>
|
||||
</a>
|
||||
{% endblock %}
|
||||
{% endblock %}
|
||||
|
|
|
|||
|
|
@ -5,4 +5,4 @@
|
|||
<a href="{{ '../' ~ base_url }}">
|
||||
<strong>Click here to go to latest.</strong>
|
||||
</a>
|
||||
{% endblock %}
|
||||
{% endblock %}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ An embedded logic analyzer written in Migen, primarily for use in LiteX SoC desi
|
|||
|
||||
### GateMate ILA
|
||||
|
||||
An embedded logic analyzer written in Verilog, targeting the GateMate FPGA family from Colonge Chip and the Yosys/NextPNR toolchain. Communication between the host and FPGA is accomplished with SPI, via a FT232 or FT2232 used as a USB-SPI adapter. GateMate is inteneded to be used with GTKWave, so the tool generates `.gtkw` files in addition to VCD files.
|
||||
An embedded logic analyzer written in Verilog, targeting the GateMate FPGA family from Cologne Chip and the Yosys/NextPNR toolchain. Communication between the host and FPGA is accomplished with SPI, via a FT232 or FT2232 used as a USB-SPI adapter. GateMate is intended to be used with GTKWave, so the tool generates `.gtkw` files in addition to VCD files.
|
||||
|
||||
- [Source Code](https://github.com/colognechip/gatemate_ila)
|
||||
|
||||
|
|
@ -28,7 +28,7 @@ A set of embedded debugging modules written by Dan Gisselquist of ZipCPU fame. C
|
|||
|
||||
## Commercial Tools
|
||||
|
||||
### Xilinx Integrated Logic Analzyer
|
||||
### Xilinx Integrated Logic Analyzer
|
||||
|
||||
An embedded logic analyzer for Xilinx FPGAs, provided as part of the Xilinx Vivado development suite. Communication between the host and FPGA is accomplished with JTAG, typically running over a USB cable to the device. Includes an integrated waveform viewer, and VCD and CSV export. Also supports a JTAG-to-AXI mode, which integrates well with Xilinx IP, which uses primarily AXI. Also integrates with the ChipScoPy API, which allows for Python control of the ILA on Versal devices. The ILA was previously known as ChipScope in earlier versions of Vivado.
|
||||
|
||||
|
|
@ -75,4 +75,4 @@ Unlike other entries in this list, Opal Kelly's FrontPanel SDK is not marketed a
|
|||
|
||||
An embedded logic analyzer for Xilinx and Altera FPGAs, provided as part of MATLAB. Communication between the host and FPGA is accomplished with JTAG, but Ethernet is supported for Xilinx FPGAs. Notably, this tool allows for data to be captured and used directly inside MATLAB, which also includes a framework for FPGA-in-the-loop testing. It also provides an AXI manager IP block that allows for reads and writes to an AXI memory map from MATLAB. This IP supports PCI Express on Xilinx FPGAs, in addition to JTAG and Ethernet.
|
||||
|
||||
- [Documentation](https://www.mathworks.com/help/hdlverifier/fpga-data-capture-xilinx.html)
|
||||
- [Documentation](https://www.mathworks.com/help/hdlverifier/fpga-data-capture-xilinx.html)
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
:root {
|
||||
--md-primary-fg-color: #3499f3;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ Inside this configuration, the following parameters may be set:
|
|||
|
||||
- `baudrate` _(required)_: The baudrate of the serial port. Generally, this should be set to the maximum baudrate supported by the USB/UART chip on your dev board for fastest operation. Manta will throw an error if this baudrate is not achievable with your FPGA's clock frequency.
|
||||
|
||||
- `clock_freq` _(required)_: The frequency of the clock provided to the `manta` module, in Hertz (Hz). This is used to calculate an appropriate prescaler onboard the FPGA to acheive the desired baudrate. Manta will throw an error if this clock frequency does not allow you to achieve your desired baudrate.
|
||||
- `clock_freq` _(required)_: The frequency of the clock provided to the `manta` module, in Hertz (Hz). This is used to calculate an appropriate prescaler onboard the FPGA to achieve the desired baudrate. Manta will throw an error if this clock frequency does not allow you to achieve your desired baudrate.
|
||||
|
||||
- `stall_interval` _(optional)_: The number of read requests to send before sending a stall byte. This prevents packets from being dropped if the FPGA's baudrate is less than the USB-Serial adapter's baudrate. This is usually caused by a mismatch between the clock frequency of the USB-Serial adapter and the FPGA fabric. See issue [#18](https://github.com/fischermoseley/manta/issues/18) on GitHub. Defaults to 16, reduce this if Manta reports that bytes are being dropped.
|
||||
|
||||
|
|
@ -36,4 +36,4 @@ Since Amaranth modules are Python objects, the configuration of the IO Core is g
|
|||
|
||||
::: manta.UARTInterface
|
||||
options:
|
||||
members: false
|
||||
members: false
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ You may find this core useful for:
|
|||
|
||||
_More details available on the [full documentation page](./io_core.md)._
|
||||
|
||||
This core presents a series of user-accessbile registers to the FPGA fabric, which may be configured as either inputs or outputs. The value of an input register can be read off the FPGA by the host machine, and the value of an output register on the FPGA may be set by the host machine. This is handy for getting small amounts of information into and out of the FPGA, debugging, configuration, or experimentation. This concept is very similar to the Xilinx [Virtual IO](https://docs.xilinx.com/v/u/en-US/pg159-vio) and Intel [In-System Sources and Probes](https://www.intel.com/content/www/us/en/docs/programmable/683552/18-1/in-system-sources-and-probes-66964.html) tools.
|
||||
This core presents a series of user-accessible registers to the FPGA fabric, which may be configured as either inputs or outputs. The value of an input register can be read off the FPGA by the host machine, and the value of an output register on the FPGA may be set by the host machine. This is handy for getting small amounts of information into and out of the FPGA, debugging, configuration, or experimentation. This concept is very similar to the Xilinx [Virtual IO](https://docs.xilinx.com/v/u/en-US/pg159-vio) and Intel [In-System Sources and Probes](https://www.intel.com/content/www/us/en/docs/programmable/683552/18-1/in-system-sources-and-probes-66964.html) tools.
|
||||
|
||||
You may find this core useful for:
|
||||
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@ class EthernetIOCoreExample(Elaboratable):
|
|||
|
||||
|
||||
# Although Amaranth provides an environment that is almost entirely independent
|
||||
# of FPGA vendor or family, it does not provide any facilites for clock
|
||||
# of FPGA vendor or family, it does not provide any facilities for clock
|
||||
# generation. As a result, this example design includes an external Verilog
|
||||
# snippet containing a clock generator created by Vivado's Clock Wizard.
|
||||
# This uses a MMCM clock generation primitive to make a 50MHz clock from the
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
!divider.sv
|
||||
!divider.sv
|
||||
|
|
|
|||
|
|
@ -190,4 +190,4 @@ wire clk_in2_divider;
|
|||
|
||||
endmodule
|
||||
|
||||
`default_nettype none
|
||||
`default_nettype none
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
!top_level.sv
|
||||
!top_level.sv
|
||||
|
|
|
|||
|
|
@ -4,4 +4,4 @@ set -e
|
|||
python3 -m manta gen manta.yaml manta.v
|
||||
$YOSYS -p 'synth_ice40 -top top_level -json top_level.json' top_level.sv
|
||||
$NEXTPNR_ICE40 --hx1k --json top_level.json --pcf top_level.pcf --asc top_level.asc
|
||||
$ICEPACK top_level.asc top_level.bin
|
||||
$ICEPACK top_level.asc top_level.bin
|
||||
|
|
|
|||
|
|
@ -13,4 +13,4 @@ cores:
|
|||
uart:
|
||||
port: "/dev/ttyUSB3"
|
||||
baudrate: 115200
|
||||
clock_freq: 12000000
|
||||
clock_freq: 12000000
|
||||
|
|
|
|||
|
|
@ -30,4 +30,4 @@ module top_level (
|
|||
.LED4(LED4));
|
||||
endmodule
|
||||
|
||||
`default_nettype wire
|
||||
`default_nettype wire
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
!top_level.sv
|
||||
!top_level.sv
|
||||
|
|
|
|||
|
|
@ -4,4 +4,4 @@ set -e
|
|||
python3 -m manta gen manta.yaml manta.v
|
||||
$YOSYS -p 'synth_ice40 -top top_level -json top_level.json' top_level.sv
|
||||
$NEXTPNR_ICE40 --hx1k --json top_level.json --pcf top_level.pcf --asc top_level.asc
|
||||
$ICEPACK top_level.asc top_level.bin
|
||||
$ICEPACK top_level.asc top_level.bin
|
||||
|
|
|
|||
|
|
@ -17,4 +17,4 @@ cores:
|
|||
uart:
|
||||
port: "/dev/ttyUSB3"
|
||||
baudrate: 115200
|
||||
clock_freq: 12000000
|
||||
clock_freq: 12000000
|
||||
|
|
|
|||
|
|
@ -32,4 +32,4 @@ module top_level (
|
|||
.probe3(probe3));
|
||||
endmodule
|
||||
|
||||
`default_nettype wire
|
||||
`default_nettype wire
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
!top_level.sv
|
||||
!divider.sv
|
||||
!divider.sv
|
||||
|
|
|
|||
|
|
@ -3,4 +3,4 @@ set -e
|
|||
|
||||
python3 -m manta gen manta.yaml manta.v
|
||||
mkdir -p build/
|
||||
$VIVADO -mode batch -source build.tcl
|
||||
$VIVADO -mode batch -source build.tcl
|
||||
|
|
|
|||
|
|
@ -51,4 +51,4 @@ manta manta_inst(
|
|||
.led(led),
|
||||
.sw(sw));
|
||||
|
||||
endmodule
|
||||
endmodule
|
||||
|
|
|
|||
|
|
@ -257,4 +257,3 @@ set_property -dict { PACKAGE_PIN B8 IOSTANDARD LVCMOS33 } [get_ports { eth_in
|
|||
#set_property -dict { PACKAGE_PIN L14 IOSTANDARD LVCMOS33 } [get_ports { qspi_dq[2] }]; #IO_L2P_T0_D02_14 Sch=qspi_dq[2]
|
||||
#set_property -dict { PACKAGE_PIN M14 IOSTANDARD LVCMOS33 } [get_ports { qspi_dq[3] }]; #IO_L2N_T0_D03_14 Sch=qspi_dq[3]
|
||||
#set_property -dict { PACKAGE_PIN L13 IOSTANDARD LVCMOS33 } [get_ports { qspi_csn }]; #IO_L6P_T0_FCS_B_14 Sch=qspi_csn
|
||||
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
!top_level.sv
|
||||
!top_level.sv
|
||||
|
|
|
|||
|
|
@ -3,4 +3,4 @@ set -e
|
|||
|
||||
python3 -m manta gen manta.yaml manta.v
|
||||
mkdir -p build/
|
||||
$VIVADO -mode batch -source build.tcl
|
||||
$VIVADO -mode batch -source build.tcl
|
||||
|
|
|
|||
|
|
@ -9,4 +9,4 @@ cores:
|
|||
uart:
|
||||
port: "/dev/ttyUSB1"
|
||||
baudrate: 115200
|
||||
clock_freq: 100000000
|
||||
clock_freq: 100000000
|
||||
|
|
|
|||
|
|
@ -20,4 +20,4 @@ module top_level (
|
|||
|
||||
endmodule
|
||||
|
||||
`default_nettype wire
|
||||
`default_nettype wire
|
||||
|
|
|
|||
|
|
@ -250,5 +250,3 @@ set_property -dict { PACKAGE_PIN D4 IOSTANDARD LVCMOS33 } [get_ports { uart_r
|
|||
#set_property -dict { PACKAGE_PIN L14 IOSTANDARD LVCMOS33 } [get_ports { qspi_dq[2] }]; #IO_L2P_T0_D02_14 Sch=qspi_dq[2]
|
||||
#set_property -dict { PACKAGE_PIN M14 IOSTANDARD LVCMOS33 } [get_ports { qspi_dq[3] }]; #IO_L2N_T0_D03_14 Sch=qspi_dq[3]
|
||||
#set_property -dict { PACKAGE_PIN L13 IOSTANDARD LVCMOS33 } [get_ports { qspi_csn }]; #IO_L6P_T0_FCS_B_14 Sch=qspi_csn
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
!top_level.sv
|
||||
!top_level.sv
|
||||
|
|
|
|||
|
|
@ -3,4 +3,4 @@ set -e
|
|||
|
||||
python3 -m manta gen manta.yaml manta.v
|
||||
mkdir -p build/
|
||||
$VIVADO -mode batch -source build.tcl
|
||||
$VIVADO -mode batch -source build.tcl
|
||||
|
|
|
|||
|
|
@ -23,4 +23,4 @@ cores:
|
|||
uart:
|
||||
port: "/dev/ttyUSB1"
|
||||
baudrate: 115200
|
||||
clock_freq: 100000000
|
||||
clock_freq: 100000000
|
||||
|
|
|
|||
|
|
@ -46,4 +46,4 @@ module top_level (
|
|||
|
||||
endmodule
|
||||
|
||||
`default_nettype wire
|
||||
`default_nettype wire
|
||||
|
|
|
|||
|
|
@ -250,5 +250,3 @@ set_property -dict { PACKAGE_PIN D4 IOSTANDARD LVCMOS33 } [get_ports { uart_r
|
|||
#set_property -dict { PACKAGE_PIN L14 IOSTANDARD LVCMOS33 } [get_ports { qspi_dq[2] }]; #IO_L2P_T0_D02_14 Sch=qspi_dq[2]
|
||||
#set_property -dict { PACKAGE_PIN M14 IOSTANDARD LVCMOS33 } [get_ports { qspi_dq[3] }]; #IO_L2N_T0_D03_14 Sch=qspi_dq[3]
|
||||
#set_property -dict { PACKAGE_PIN L13 IOSTANDARD LVCMOS33 } [get_ports { qspi_csn }]; #IO_L6P_T0_FCS_B_14 Sch=qspi_csn
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
!top_level.sv
|
||||
!top_level.sv
|
||||
|
|
|
|||
|
|
@ -3,4 +3,4 @@ set -e
|
|||
|
||||
python3 -m manta gen manta.yaml manta.v
|
||||
mkdir -p build/
|
||||
$VIVADO -mode batch -source build.tcl
|
||||
$VIVADO -mode batch -source build.tcl
|
||||
|
|
|
|||
|
|
@ -17,4 +17,4 @@ cores:
|
|||
uart:
|
||||
port: "/dev/ttyUSB1"
|
||||
baudrate: 115200
|
||||
clock_freq: 100000000
|
||||
clock_freq: 100000000
|
||||
|
|
|
|||
|
|
@ -34,4 +34,4 @@ module top_level (
|
|||
|
||||
endmodule
|
||||
|
||||
`default_nettype wire
|
||||
`default_nettype wire
|
||||
|
|
|
|||
|
|
@ -250,5 +250,3 @@ set_property -dict { PACKAGE_PIN B2 IOSTANDARD LVCMOS33 } [get_ports { ps2_da
|
|||
#set_property -dict { PACKAGE_PIN L14 IOSTANDARD LVCMOS33 } [get_ports { qspi_dq[2] }]; #IO_L2P_T0_D02_14 Sch=qspi_dq[2]
|
||||
#set_property -dict { PACKAGE_PIN M14 IOSTANDARD LVCMOS33 } [get_ports { qspi_dq[3] }]; #IO_L2N_T0_D03_14 Sch=qspi_dq[3]
|
||||
#set_property -dict { PACKAGE_PIN L13 IOSTANDARD LVCMOS33 } [get_ports { qspi_csn }]; #IO_L6P_T0_FCS_B_14 Sch=qspi_csn
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ dev = [
|
|||
"pytest",
|
||||
"pytest-cov",
|
||||
"codecov",
|
||||
"pre-commit",
|
||||
"ruff",
|
||||
"mkdocs-material",
|
||||
"mkdocstrings[python]",
|
||||
|
|
|
|||
|
|
@ -275,7 +275,7 @@ class EthernetInterface(Elaboratable):
|
|||
mii_mdio (IOPort): Management Data
|
||||
mii_mdc (IOPort): Management Data Clock
|
||||
mii_rx_dv (IOPort): Receive Data Valid
|
||||
mii_rx_er (IOPort): Recieve Error
|
||||
mii_rx_er (IOPort): Receive Error
|
||||
mii_rx_data (IOPort): Receive Data
|
||||
mii_tx_en (IOPort): Transmit Enable
|
||||
mii_tx_data (IOPort): Transmit Data
|
||||
|
|
|
|||
|
|
@ -171,7 +171,7 @@ class IOCore(MantaCore):
|
|||
|
||||
# Save the last used address, for use later.
|
||||
# Normally we'd just grab this from self._memory_map, but Python
|
||||
# dictionaries don't guaruntee that insertion order is preserved,
|
||||
# dictionaries don't guarantee that insertion order is preserved,
|
||||
# so it's more convenient to just save it now.
|
||||
|
||||
self._max_addr = last_used_addr
|
||||
|
|
|
|||
|
|
@ -234,7 +234,7 @@ class LogicAnalyzerCore(MantaCore):
|
|||
else:
|
||||
raise ValueError(f"Unrecognized trigger mode {trigger_mode} provided.")
|
||||
|
||||
# Peform checks based on trigger mode
|
||||
# Perform checks based on trigger mode
|
||||
if mode == TriggerModes.IMMEDIATE:
|
||||
# Warn on triggers
|
||||
if triggers:
|
||||
|
|
@ -311,7 +311,7 @@ class LogicAnalyzerCore(MantaCore):
|
|||
raw_capture = self._sample_mem.read(addrs)
|
||||
|
||||
# Revolve the memory around the read_pointer, such that all the beginning
|
||||
# of the caputure is at the first element
|
||||
# of the capture is at the first element
|
||||
print(" -> Checking read pointer and revolving memory...")
|
||||
read_pointer = self._fsm.read_register("read_pointer")
|
||||
|
||||
|
|
|
|||
|
|
@ -45,16 +45,16 @@ class LogicAnalyzerCapture:
|
|||
"""
|
||||
|
||||
# Get index of probe with given name
|
||||
indicies = [i for i, p in enumerate(self._probes) if p.name == name]
|
||||
if len(indicies) == 0:
|
||||
indices = [i for i, p in enumerate(self._probes) if p.name == name]
|
||||
if len(indices) == 0:
|
||||
raise ValueError(f"Probe {name} not found in LogicAnalyzerCapture!")
|
||||
|
||||
if len(indicies) > 1:
|
||||
if len(indices) > 1:
|
||||
raise ValueError(
|
||||
f"Probe {name} found multiple times in LogicAnalyzerCapture!"
|
||||
)
|
||||
|
||||
idx = indicies[0]
|
||||
idx = indices[0]
|
||||
|
||||
# Sum up the widths of all the probes below this one
|
||||
lower = sum([len(p) for p in self._probes[:idx]])
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ class LogicAnalyzerPlayback(Elaboratable):
|
|||
with m.Else():
|
||||
m.d.sync += read_port.addr.eq(read_port.addr + 1)
|
||||
|
||||
# Pipeline to accomodate for the 2-cycle latency in the RAM
|
||||
# Pipeline to accommodate for the 2-cycle latency in the RAM
|
||||
m.d.sync += self.valid.eq(busy)
|
||||
|
||||
# Assign the probe values by part-selecting from the data port
|
||||
|
|
|
|||
|
|
@ -238,7 +238,7 @@ class MemoryCore(MantaCore):
|
|||
for i, mem in enumerate(self._mems):
|
||||
m.submodules[f"mem_{i}"] = mem
|
||||
|
||||
# Pipeline the bus to accomodate the two clock-cycle delay in the memories
|
||||
# Pipeline the bus to accommodate the two clock-cycle delay in the memories
|
||||
self._bus_pipe = [Signal(InternalBus()) for _ in range(3)]
|
||||
m.d.sync += self._bus_pipe[0].eq(self.bus_i)
|
||||
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ class UARTInterface(Elaboratable):
|
|||
|
||||
clock_freq (float | int): The frequency of the clock provided to
|
||||
this module, in Hertz (Hz). This is used to calculate an
|
||||
appropriate prescaler onboard the FPGA to acheive the desired
|
||||
appropriate prescaler onboard the FPGA to achieve the desired
|
||||
baudrate.
|
||||
|
||||
stall_interval (Optional[int]): The number of read requests to send
|
||||
|
|
@ -53,7 +53,7 @@ class UARTInterface(Elaboratable):
|
|||
did not work.
|
||||
|
||||
Raises:
|
||||
ValueError: The baudrate is not acheivable with the clock frequency
|
||||
ValueError: The baudrate is not achievable with the clock frequency
|
||||
provided, or the clock frequency or baudrate is invalid.
|
||||
|
||||
"""
|
||||
|
|
@ -213,9 +213,9 @@ class UARTInterface(Elaboratable):
|
|||
# buffer from overflowing and dropping bytes, as the FPGA will send
|
||||
# responses instantly after it's received a request.
|
||||
|
||||
ser = self._get_serial_device()
|
||||
set = self._get_serial_device()
|
||||
addr_chunks = split_into_chunks(addrs, self._chunk_size)
|
||||
datas = []
|
||||
data = []
|
||||
|
||||
for addr_chunk in addr_chunks:
|
||||
# Encode addrs into read requests
|
||||
|
|
@ -226,11 +226,11 @@ class UARTInterface(Elaboratable):
|
|||
bytes_out = split_into_chunks(bytes_out, 7 * self._stall_interval)
|
||||
bytes_out = "\n".join(bytes_out)
|
||||
|
||||
ser.write(bytes_out.encode("ascii"))
|
||||
set.write(bytes_out.encode("ascii"))
|
||||
|
||||
# Read responses have the same length as read requests
|
||||
bytes_expected = 7 * len(addr_chunk)
|
||||
bytes_in = ser.read(bytes_expected)
|
||||
bytes_in = set.read(bytes_expected)
|
||||
|
||||
if len(bytes_in) != bytes_expected:
|
||||
raise ValueError(
|
||||
|
|
@ -240,11 +240,11 @@ class UARTInterface(Elaboratable):
|
|||
# Split received bytes into individual responses and decode
|
||||
responses = split_into_chunks(bytes_in, 7)
|
||||
data_chunk = [self._decode_read_response(r) for r in responses]
|
||||
datas += data_chunk
|
||||
data += data_chunk
|
||||
|
||||
return datas
|
||||
return data
|
||||
|
||||
def write(self, addrs, datas):
|
||||
def write(self, addrs, data):
|
||||
"""
|
||||
Write the provided data into the provided addresses in Manta's internal
|
||||
memory. Addresses and data must be specified as either integers or a
|
||||
|
|
@ -252,11 +252,11 @@ class UARTInterface(Elaboratable):
|
|||
"""
|
||||
|
||||
# Handle a single integer address and data
|
||||
if isinstance(addrs, int) and isinstance(datas, int):
|
||||
return self.write([addrs], [datas])
|
||||
if isinstance(addrs, int) and isinstance(data, int):
|
||||
return self.write([addrs], [data])
|
||||
|
||||
# Make sure address and datas are all integers
|
||||
if not isinstance(addrs, list) or not isinstance(datas, list):
|
||||
# Make sure address and data are all integers
|
||||
if not isinstance(addrs, list) or not isinstance(data, list):
|
||||
raise TypeError(
|
||||
"Write addresses and data must be an integer or list of integers."
|
||||
)
|
||||
|
|
@ -264,17 +264,17 @@ class UARTInterface(Elaboratable):
|
|||
if not all(isinstance(a, int) for a in addrs):
|
||||
raise TypeError("Write addresses must be all be integers.")
|
||||
|
||||
if not all(isinstance(d, int) for d in datas):
|
||||
if not all(isinstance(d, int) for d in data):
|
||||
raise TypeError("Write data must all be integers.")
|
||||
|
||||
# Since the FPGA doesn't issue any responses to write requests, we
|
||||
# the host's input buffer isn't written to, and we don't need to
|
||||
# send the data as chunks as the to avoid overflowing the input buffer.
|
||||
|
||||
# Encode addrs and datas into write requests
|
||||
bytes_out = "".join([f"W{a:04X}{d:04X}\r\n" for a, d in zip(addrs, datas)])
|
||||
ser = self._get_serial_device()
|
||||
ser.write(bytes_out.encode("ascii"))
|
||||
# Encode addrs and data into write requests
|
||||
bytes_out = "".join([f"W{a:04X}{d:04X}\r\n" for a, d in zip(addrs, data)])
|
||||
set = self._get_serial_device()
|
||||
set.write(bytes_out.encode("ascii"))
|
||||
|
||||
def _decode_read_response(self, response_bytes):
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ from amaranth.sim import Simulator
|
|||
|
||||
class MantaCore(ABC, Elaboratable):
|
||||
# These attributes are meant to be settable and gettable, but max_addr and
|
||||
# top_level_ports are indended to be only gettable. Do not implement
|
||||
# top_level_ports are intended to be only gettable. Do not implement
|
||||
# setters for them in subclasses.
|
||||
|
||||
base_addr = None
|
||||
|
|
@ -139,7 +139,7 @@ def value_to_words(data, n_words):
|
|||
|
||||
def check_value_fits_in_bits(value, n_bits):
|
||||
"""
|
||||
Rasies an exception if the provided value isn't an integer that cannot
|
||||
Raises an exception if the provided value isn't an integer that cannot
|
||||
be expressed with the provided number of bits.
|
||||
"""
|
||||
|
||||
|
|
@ -200,7 +200,7 @@ def simulate(top):
|
|||
def jumble(iterable):
|
||||
"""
|
||||
Returns the provided iterable, but with every element moved to a random
|
||||
index. Very similar to random.shuffle, but returns an iteratable, instead
|
||||
index. Very similar to random.shuffle, but returns an iterable, instead
|
||||
of modifying one in-place.
|
||||
"""
|
||||
return sample(iterable, len(iterable))
|
||||
|
|
@ -213,7 +213,7 @@ async def verify_register(module, ctx, addr, expected_data):
|
|||
|
||||
Unfortunately because Amaranth uses generator functions to define processes,
|
||||
this must be a generator function and thus cannot return a value - it must
|
||||
yield the next timestep. This means that the comparision with the expected
|
||||
yield the next timestep. This means that the comparison with the expected
|
||||
value must occur inside this function and not somewhere else, it's not
|
||||
possible to return a value from here, and compare it in the calling
|
||||
function.
|
||||
|
|
|
|||
|
|
@ -134,7 +134,7 @@ class MemoryCoreTests:
|
|||
async def one_bus_write_then_one_user_read(self):
|
||||
for user_addr in self.user_addrs:
|
||||
# Try and set the value at the user address to a given value,
|
||||
# by writing to the appropriate memory locaitons on the bus side
|
||||
# by writing to the appropriate memory locations on the bus side
|
||||
data = getrandbits(self.width)
|
||||
|
||||
words = value_to_words(data, self.n_mems)
|
||||
|
|
|
|||