Merge pull request #16 from fischermoseley/amaranth_rewrite

Rewrite Manta in Amaranth HDL
This commit is contained in:
Fischer Moseley 2024-03-07 13:31:59 -07:00 committed by GitHub
commit 8efbad4dd8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
204 changed files with 10024 additions and 8697 deletions

View File

@ -1,4 +1,4 @@
name: build_docs
name: docs_site
on:
push:
branches:
@ -17,5 +17,5 @@ jobs:
with:
key: ${{ github.ref }}
path: .cache
- run: pip install mkdocs-material
- run: pip install mkdocs-material
- run: mkdocs gh-deploy --force

View File

@ -1,25 +0,0 @@
name: build_examples
on: [push]
jobs:
examples:
runs-on: self-hosted
steps:
- uses: actions/checkout@v3
- name: Install Manta from source
run: |
pip install setuptools --upgrade
# omitting the following commmand 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:
# https://github.com/pypa/setuptools/issues/3269#issuecomment-1254507377
export DEB_PYTHON_INSTALL_LAYOUT=deb_system
python3 -m pip install .
- name: Build Nexys A7 examples
run: make nexys_a7
- name: Build Icestick examples
run: make icestick

View File

@ -1,29 +0,0 @@
name: formal_verification
on: [push]
jobs:
all:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Install Manta from Source
run: |
pip install setuptools --upgrade
# omitting the following commmand 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:
# https://github.com/pypa/setuptools/issues/3269#issuecomment-1254507377
export DEB_PYTHON_INSTALL_LAYOUT=deb_system
python3 -m pip install .
- name: Install oss-cad-suite
run: |
wget --no-verbose https://github.com/YosysHQ/oss-cad-suite-build/releases/download/2023-02-23/oss-cad-suite-linux-x64-20230223.tgz
tar -xzf oss-cad-suite-linux-x64-20230223.tgz
echo "$(pwd)/oss-cad-suite/bin" >> $GITHUB_PATH
- name: Run formal verification
run: make formal

View File

@ -1,29 +0,0 @@
name: functional_simulation
on: [push]
jobs:
all:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Install Manta from Source
run: |
pip install setuptools --upgrade
# omitting the following commmand 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:
# https://github.com/pypa/setuptools/issues/3269#issuecomment-1254507377
export DEB_PYTHON_INSTALL_LAYOUT=deb_system
python3 -m pip install .
- name: Install oss-cad-suite
run: |
wget --no-verbose https://github.com/YosysHQ/oss-cad-suite-build/releases/download/2023-02-23/oss-cad-suite-linux-x64-20230223.tgz
tar -xzf oss-cad-suite-linux-x64-20230223.tgz
echo "$(pwd)/oss-cad-suite/bin" >> $GITHUB_PATH
- name: Run functional simulations
run: make sim

32
.github/workflows/run_tests.yml vendored Normal file
View File

@ -0,0 +1,32 @@
name: run_tests
on: [push]
jobs:
all:
runs-on: self-hosted
steps:
- uses: actions/checkout@v4
- name: Install Manta from Source
run: |
# Make venv
python3 -m venv venv/
source venv/bin/activate
# Update pip
python3 -m pip install -U pip
# omitting the following commmand 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:
# https://github.com/pypa/setuptools/issues/3269#issuecomment-1254507377
export DEB_PYTHON_INSTALL_LAYOUT=deb_system
# Install Manta, with optional dev-only dependencies
python3 -m pip install ".[dev]"
- name: Run tests
run: |
source ./environment.sh
source venv/bin/activate
make test

38
.gitignore vendored
View File

@ -2,32 +2,30 @@
.DS_Store
*.vscode/
# Python outputs
# Python files
venv/
dist/
build/
*.egg-info
manta.egg-info/
.pytest_cache
__pycache__/
build/
# Vivado output products
*.Xil/
# Miscellaneous file types
*.v
*.sv
*.vcd
*.out
*.csv
# Vivado files
*.log
*.jou
*.rpt
*.bit
cpu_impl_netlist.v
# IceStorm output products
*.bin
# iVerilog output products
*.vcd
*.bit
*.out
.Xil/
# Formal outputs
test/formal_verification/*_basic
test/formal_verification/*_cover
# Manta output products
manta.v
*.mem
# Yosys/IceStorm files
*.asc
*.bin
*.json

123
Makefile
View File

@ -1,123 +1,12 @@
# Tool Paths
VIVADO=/tools/Xilinx/Vivado/2023.1/bin/vivado
YOSYS=/tools/oss-cad-suite/bin/yosys
NEXTPNR_ICE40=/tools/oss-cad-suite/bin/nextpnr-ice40
ICEPACK=/tools/oss-cad-suite/bin/icepack
.PHONY: test format clean serve_docs
test:
python3 -m pytest
test: auto_gen sim formal
examples: icestick nexys_a7
format:
python3 -m black .
clean:
@echo "Deleting everything matched by .gitignore"
git clean -Xdf
serve_docs:
preview_site:
mkdocs serve
# Python Operations
python_build:
python3 -m build
pypi_upload: build
python3 -m twine upload --repository testpypi dist/*
python_lint:
python3 -m black src/manta/__init__.py
python3 -m black src/manta/__main__.py
# API Generation Tests
auto_gen:
python3 test/auto_gen/run_tests.py
# Build Examples
NEXYS_A7_EXAMPLES := io_core_ether io_core_uart ps2_logic_analyzer video_sprite_ether video_sprite_uart block_mem_uart logic_analyzer_uart large_io_core_uart
.PHONY: nexys_a7 $(NEXYS_A7_EXAMPLES)
nexys_a7: $(NEXYS_A7_EXAMPLES)
$(NEXYS_A7_EXAMPLES):
cd examples/nexys_a7/$@; \
python3 -m manta gen manta.yaml src/manta.v; \
rm -rf obj; \
mkdir -p obj; \
$(VIVADO) -mode batch \
-source ../build.tcl \
-log obj/build.log \
-jou obj/build.jou; \
rm -rf .Xil;
ICESTICK_EXAMPLES := io_core
.PHONY: icestick $(ICESTICK_EXAMPLES)
icestick: $(ICESTICK_EXAMPLES)
$(ICESTICK_EXAMPLES):
cd examples/icestick/$@; \
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; \
rm -f *.json; \
rm -f *.asc;
# Formal Verification
formal:
sby -f test/formal_verification/bridge_rx.sby
# Functional Simulation
sim: ethernet_tx_tb ethernet_rx_tb mac_tb block_memory_tb io_core_tb logic_analyzer_tb bridge_rx_tb bridge_tx_tb block_memory_tb
ethernet_tx_tb:
iverilog -g2012 -o sim.out -y src/manta/ether_iface test/functional_sim/ethernet_tx_tb.sv
vvp sim.out
rm sim.out
ethernet_rx_tb:
iverilog -g2012 -o sim.out -y src/manta/ether_iface test/functional_sim/ethernet_rx_tb.sv
vvp sim.out
rm sim.out
mac_tb:
iverilog -g2012 -o sim.out -y src/manta/ether_iface test/functional_sim/mac_tb.sv
vvp sim.out
rm sim.out
block_memory_tb:
iverilog -g2012 -o sim.out -y src/manta/block_mem_core test/functional_sim/block_memory_tb.sv
vvp sim.out
rm sim.out
io_core_tb:
iverilog -g2012 -o sim.out \
test/functional_sim/io_core_tb/io_core_tb.sv \
test/functional_sim/io_core_tb/io_core.v
vvp sim.out
rm sim.out
logic_analyzer_tb:
cd test/functional_sim/logic_analyzer_tb; \
python3 -m manta gen manta.yaml manta.v; \
iverilog -g2012 -o sim.out logic_analyzer_tb.sv manta.v; \
vvp sim.out; \
rm sim.out
bridge_rx_tb:
iverilog -g2012 -o sim.out -y src/manta/uart_iface test/functional_sim/bridge_rx_tb.sv
vvp sim.out
rm sim.out
bridge_tx_tb:
iverilog -g2012 -o sim.out -y src/manta/uart_iface test/functional_sim/bridge_tx_tb.sv
vvp sim.out
rm sim.out
uart_rx_tb:
iverilog -g2012 -o sim.out -y src/manta/uart_iface test/functional_sim/uart_rx_tb.sv
vvp sim.out
rm sim.out
uart_tx_tb:
iverilog -g2012 -o sim.out -y src/manta/uart_iface test/functional_sim/uart_tx_tb.sv
vvp sim.out
rm sim.out

View File

@ -1,11 +1,8 @@
![](doc/assets/logo.png)
## Manta: A Configurable and Approachable Tool for FPGA Debugging and Rapid Prototyping
![functional_simulation](https://github.com/fischermoseley/manta/actions/workflows/functional_simulation.yml/badge.svg)
![formal_verification](https://github.com/fischermoseley/manta/actions/workflows/formal_verification.yml/badge.svg)
![build_examples](https://github.com/fischermoseley/manta/actions/workflows/build_examples.yml/badge.svg)
![run_tests](https://github.com/fischermoseley/manta/actions/workflows/run_tests.yml/badge.svg)
![build_docs](https://github.com/fischermoseley/manta/actions/workflows/build_docs.yml/badge.svg)
[![License: GPL v3](https://img.shields.io/badge/License-GPLv3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0)
[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)

74
doc/alternatives.md Normal file
View File

@ -0,0 +1,74 @@
There's quite a few FPGA debugging tools out there, and it may happen that your needs are better met by another tool! This section aims to provide a list of alternatives, in hopes that you're able to be confident in your debugging flow.
## Open Source Tools
### LiteScope
An embedded logic analyzer written in Migen, primarily for use in LiteX SoC designs. Also includes IO peek and poke, as well as UART, Ethernet, and PCIe interfaces with a host machine. Includes VCD, Sigrok, CSV, and Python data export.
- [Source Code](https://github.com/enjoy-digital/litescope)
- [Documentation](https://github.com/enjoy-digital/litex/wiki/Use-LiteScope-To-Debug-A-SoC)
### 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.
- [Source Code](https://github.com/colognechip/gatemate_ila)
### ZipCPU Debugger
A set of embedded debugging modules written by Dan Gisselquist of ZipCPU fame. Communication between the host and FPGA is accomplished with UART, and control of the debugger is performed with a C++ API on the host. A wishbone interface is provided on the FPGA side to connect to other Wishbone-based debugging tools that can provide control of user registers, block RAM, and an embedded logic analyzer. Supports dumping of signals to a VCD file.
- [Source Code](https://github.com/ZipCPU/dbgbus)
- [Documentation](https://zipcpu.com/topics.html), under the _How to Debug an FPGA_ section.
## Commercial Tools
### Xilinx Integrated Logic Analzyer
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.
- [ILA Documentation](https://docs.xilinx.com/v/u/en-US/pg172-ila)
- [ILA User's Guide](https://docs.xilinx.com/r/en-US/ug936-vivado-tutorial-programming-debugging/Using-the-Vivado-Logic-Analyzer-to-Debug-Hardware)
- [ChipScoPy API](https://github.com/Xilinx/chipscopy)
### Xilinx Virtual IO
A tool for reading and writing to individual registers on the FPGA, provided as part of the Xilinx Vivado development suite. Just like the ILA, communication between the host and FPGA is done over JTAG. Control over the registers is done through the Vivado GUI or through the Tcl interpreter. In the case of Versal devices, the ChipScoPy API can also control the registers.
- [Virtual IO Documentation](https://docs.xilinx.com/v/u/en-US/pg159-vio)
- [ChipScoPy API](https://github.com/Xilinx/chipscopy)
### Intel Signal Tap
An embedded logic analyzer for Intel/Altera FPGAs, provided as part of the Quartus development suite. Communication between the host and FPGA is accomplished with JTAG, and a programmable interface is provided via Tcl. Signal Tap is notable for providing a significant amount of configurability in the trigger conditions, and provides a small scripting language called _Trigger Flow_ that allows users to define triggers as state machines. Signal Tap also allows for _Simulation-Aware nodes_, which allows for running simulations with data captured from the real world. At the time of writing, this feature is only available in the most recent and full-featured version of the Quartus suite, Quartus Prime Pro Edition 22.4.
- [Documentation](https://www.intel.com/content/www/us/en/docs/programmable/683552/18-1/design-debugging-with-the-logic-analyzer-69524.html)
### Intel In-System Sources and Probes
A tool for reading and writing to individual registers on the FPGA, provided for Intel/Altera FPGAs as part of the Quartus development suite. Just like Signal Tap, communication between the host and FPGA is accomplished with JTAG.
- [Documentation](https://www.intel.com/content/www/us/en/docs/programmable/683552/18-1/design-debugging-using-in-system-sources-45607.html)
### Lattice Reveal
An embedded logic analyzer for Lattice FPGAs, provided as part of the Diamond development suite. Communication between the host and FPGA is accomplished with JTAG. Reveal is notable for providing a significant amount of configurability in the trigger conditions, and supports trigger conditions formed with a mix of combinational and sequential logic. Reveal also provides special support for Wishbone buses, and for controlling SERDES modules on ECP5 devices.
- [Documentation](https://www.latticesemi.com/~/media/328D471BF2C74EB1907832FAA6FB344B.ashx)
### Opal Kelly FrontPanel SDK
Unlike other entries in this list, Opal Kelly's FrontPanel SDK is not marketed as a debugger (although it can be used as such). Instead, it's designed to provide a host computer with a real time interface to FPGA signals, and present them on a graphical “front panel". These front panels exist as a GUI window on the host, and contain buttons, knobs, and indicators, much like a LabVIEW virtual instrument. Communication between the host and FPGA is accomplished with either USB or PCIe. Bindings for hosts running Windows, macOS, and Linux are provided, and target C, C++, C#, Python, Java, Ruby, and MATLAB. The FrontPanel SDK differs from other debuggers in that it provides a skeleton module into which the user logic is instantiated, instead of being instantiated inside the user's logic.
- [Documentation](https://docs.opalkelly.com/fpsdk/)
- [User's Guide](https://assets00.opalkelly.com/library/FrontPanel-UM.pdf)
### MATLAB FPGA Data Capture
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)

View File

@ -2,19 +2,17 @@
The whole system looks like the following:
![](assets/manta_architecture.png){:style="width:80%"}
<center><img src="../assets/system_architecture.drawio.svg"></center>
Manta is operated via its Python API, which communicates with the connected FPGA over an interface API like `pySerial` or `Scapy`. These abstract away the OS device drivers, which function differently depending on the host machine's platform. The OS device drivers ultimately send out bytes to the FPGA, across either a USB or Ethernet cable.
Once sent across the wire, bytes are picked up by an interface transciever on the FPGA development board. This is either a USB-UART converter or a RMII PHY depending on if you're using UART or Ethernet. This chip is connected to the FPGA's IO, which routes the signals to the Verilog module generated by Manta. This module parses incoming messages, passes them down a set of daisy-chained cores, and then packetizes it and sends it back to the host.
Manta consists of two parts - a Python API running on a host machine, and an autogenerated block of RTL that's included with your logic on a FPGA. Either UART or Ethernet is used for communication, which allows the host machine to operate the debugging cores on the FPGA.
## Manta Architecture
The logic Manta places on the FPGA consists of a series of cores connected in a chain along a common bus. Each core provides a unique method for interacting with the users logic, which it connects to by routing signals (called _probes_) between the users logic and the cores that interface with it.
![](assets/bus_architecture.png){:style="width:40%"}
<center><img src="../assets/bus_architecture.drawio.svg"></center>
These probes are presented as addressable memory, and are be controlled by reading and writing to their corresponing memory - not unlike registers on a microcontroller. Each core is allotted a section of address space at compile time, and operations addressed to a cores address space control the behavior of the core. These cores are then daisy-chained along an internal bus, which permits a chain arbitrarily many cores to be placed on the bus.
These probes are presented as addressable memory, and are be controlled by reading and writing to their corresponding memory - not unlike registers on a microcontroller. Each core is allotted a section of address space at compile time, and operations addressed to a cores address space control the behavior of the core. These cores are then daisy-chained along an internal bus, which permits a chain arbitrarily many cores to be placed on the bus.
At the beginning of this chain is a module called a _receive bridge_, which converts incoming UART/Ethernet communication from the host into read and write requests, which are placed on the bus. These are called _bus transactions_, and once placed on the bus, they travel through each core before reaching the _transmit bridge_ at the end of the chain. This module places the result of the bus transaction back on the UART/Ethernet interface, and sends it back to the host. This produces a request-response style of communication between the host machine and the FPGA.
@ -37,7 +35,7 @@ Each core has a bus input and output port, so that cores can be daisy-chained to
Ethernet and UART both allow a stream of bytes to be sent between the host and FPGA, but since they're just interfaces, they don't define how these bytes are structured. As a result, Manta implements its own messaging format, with the following structure:
![](assets/uart.png){:style="width:85%"}
<center><img src="../assets/uart_packets.drawio.svg"></center>
Each of these messages is a string of ASCII characters consisting of a preamble, optional address and data fields, and an End of Line (EOL). The preamble denotes the type of operation, _R_ for a read and _W_ for a write. The address and data fields are encoded as hexadecimal digits, represented with the characters 0-9 and A-F in ASCII. As a result, four characters are needed to encode a 16-bit address or 16-bits of data. If the message specifies a write request, then it will contain a data field after the address field. Both request types will conclude with an End of Line, which consists of the two ASCII characters indicating a Carriage Return (CR) and a Line Feed (LF).
@ -56,4 +54,51 @@ An example of some bus traffic is provided below:
| 5 | FPGA → Host: RBEEF(CR)(LF) | Read 0xBEEF from 0xF00D |
| 6 | Host → FPGA: W12340000(CR)(LF) | Write 0x0000 to 0x1234 |
When UART is used, these bytes are transmitted directly across the wire, but when Ethernet is used, they're packed into the packet's payload field.
When UART is used, these bytes are transmitted directly across the wire, but when Ethernet is used, they're packed into the packet's payload field.
# Cores
## IO Core
This is done with the architecture shown below:
<center><img src="../assets/io_core_architecture.drawio.svg" width="60%"></center>
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.
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. This is explained in more detail in Chapter 3.6 of the [original thesis](thesis.pdf).
## Logic Analyzer
The Logic Analyzer Core's implementation on the FPGA consists of three primary components:
<center><img src="../assets/logic_analyzer_architecture.drawio.svg" width="85%"></center>
- 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.
## Memory Core
Each Memory core is actually a set of 16-bit wide BRAMs with their ports concatenated together, with any spare bits masked off. Here's a diagram:
<center><img src="../assets/memory_architecture.drawio.svg" width="85%"></center>
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 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.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 653 KiB

View File

@ -0,0 +1,446 @@
<svg host="65bd71144e" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="388px" height="521px" viewBox="-0.5 -0.5 388 521" content="&lt;mxfile&gt;&lt;diagram id=&quot;KwYhoRQM-apOM2V7J7uL&quot; name=&quot;Page-1&quot;&gt;7VzBcqM4EP0aH+0ChAQcJ8lk9jBblarZqt09pWSQbXYwcgl54szXr4SFsSQcE0e2SWZ8SEwjhHjd/dR6KBmB2+XmC8OrxZ80I8Uo8LLNCNyNgiAOgPgpDc9bAwRwa5izPNua/NbwLf9JlNFT1nWekUpryCkteL7SjSktS5JyzYYZo096sxkt9Luu8JxYhm8pLmzr33nGF+qxoNfa/yD5fNHc2ffUmSVuGitDtcAZfdozgc8jcMso5dtvy80tKSR2DS7b6+4PnN0NjJGS97kgVuP4gYu1ejg1MP7cPC2j6zIj8gJvBG6eFjkn31Y4lWefhHuFbcGXhTjyxdeKM/qd3NKCMmEpaSma3dijUgP9QRgnmz2TGuUXQpeEs2fRRJ0NkBqpChk/UsdPrQNAY1vsgQ8bqLFy+nzXd4uL+KKg6YYp9F3D1Phdts1wtagv9NXBA+acsFJYYnGP2IJ1FACv/ogzK8Jy8TyEyZvl5Vz1OWc4ywXchidmeVGcwTmx4ZykwzmwyzmeC+cEV3bOARecB2vg6VjvSHEP6ySZBNBGO0Qu0AYW2tN1ZQFOMsGY6pAyvqBzWuLic2u90V3StvlK6UrB/R/h/FnRP15zqrvpIJgVXbNUjQMiNT9gNidN1EVbmxxjH8i9iQooRgrM8x/6LNAFpurqgeZiaG0TOptVYhAm2rs79nNAeDzcB4N+YqPfBOFR9Huj3Tt0Ye/Q/YqnomTRHhgX+VxmfSoemIicvpE5m4ui4JM6scyzbIstqfKfeFr3V1O0DIN63PBmBO86wWu8qkoWdXVbKPQnCG/ix03UDyNgUUfAooJLeMWQ0Fx+W+KS48YsemzPWP4ROPAeRUcH/VY7fobt0V91wI+DQxMDFdDPino+WAgPk9LKHhes7vtHWT3umEBDF4we9fDP/cOXT6LNPZ6yPP11/RSaZWhHpeOjczkqHvzU23dKHXsTID5vY6kmd6A3Sbz2o2cSiA3kt/OT6mN/afSqbkPf6HY7xb3QrVtOTT5mKCh0x76zyIjRQRe+JTIOdwuvGxmwx4r+XYSFjuoYOokIU0YIEDwxBgL/5Y4u7PUugQLhpZwYy2klf7GNaemMi4tXvk3Avr3yHUvC9kMngTIO9SvceOkqqUg2Of9Hlk7eRHLV1vCv7G8SBpE6vtuoG9QHz81BKZ5td23cWNTFCDaG9ur6SLv8oVFH9m5g2vqyhb66RG9dOHa7Pox0jgjBqfNE7L/c0QGOOCWybFXGzPa8XK35o/dWEijIjDungMAhBXgJhBrsbmqJsek8N4wQXpMRdDKA/ahAMkGgMwEE6BQm6J/1mn50nqy3ktUUS/tmvUUfZkcOs94WtMz0pmsu094fZNo71Lw8HyVu8jyIzpHntgYm6zFvynIZ66Yz2gz3j7+u2BdQRgHIMIlnqaW2iDMojcl05kiwMutfaAshXTqIyaKn6CDQFqwKOm9lqSlrNCksWPH5pyAcGWTMLc6zGUFpJ85ZlEw9V8KggTPoEAa7cI5c4GzrTTn9OFCGl4SyQ68paPpdmJZkSethfhBYYU9YTfXlFFiRLXbwD0WrKLgcrSJbQ1hXNXcqdnWIJvEzSKIuNBMUAYzcoLkLxRfIM0lsNN3E5lUX+yeV9q1C0Nb2Edot+19T21eiyuWf5F4rYUgLXFV52pjv82I33DJrGql3P8Kizg9+iQCDE8VDc4lgdeRuiYBsYUAm9SPOMtYZnxdeAzRZ4mQNEOhvEVwt/KOuXp0uD9B1ZIAzqXu7LpFGQnEQvExD700YhOZL3VOFQasjh/lvSwR1/meY48e8HAQFDFIGAOd4AYC6tsK8syJBJnaic0UcDUD/a2NA6pMuYsBKUxhOYpC0H0ez/8vdXvZFIrK1lZYv6JoPgjDQIAlDLxPGZ6kT4ndHF11riiQ4aU3hli9ck4MpE51MB2ZHDosBW4Wqk/uJibX7IynrTBpCgsdDTPBm57vTjG6cfZ2M9l6R0X2zz32mmZoYEPMltLZfvTbvdm8s+nXrLguj43t1+ED36jTR6uRFfeAB3bGO1ut+915Ct2l71bp99wp+l7p+AF4xHf+iG3lAKDI8eHP9bs78R7p1SBzHN/msGJ2SR8s8hEm9SZlhTermX4e6YYer7uqpUxzo9BAlv+nhKD2cuuPHIoTz7fiJju/42VIAGCQFDFLp8w3CdkMB6OoUEGsU4P3e6XucAVzt9LU6csgAnX+t18EAg9zyFw1SujsPA7w/ra5ja28Y+6ekfv80v4hUF2jZGcqCHTrQ8f3XdOuQAmwZ78C230Hu9o8Gqe652PYrDtt/3bNt3v7/I/D5fw==&lt;/diagram&gt;&lt;/mxfile&gt;">
<defs/>
<g>
<rect x="17" y="0" width="370" height="520" fill="rgb(255, 255, 255)" stroke="none" pointer-events="all"/>
<rect x="37" y="20" width="350" height="500" fill="none" stroke="#000000" stroke-dasharray="8 8" pointer-events="all"/>
<rect x="57" y="40" width="99.25" height="460" fill="none" stroke="rgb(0, 0, 0)" stroke-dasharray="8 8" pointer-events="all"/>
<path d="M 108 110 L 108 129.96 L 108 119.96 L 108 133.63" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/>
<path d="M 108 138.88 L 104.5 131.88 L 108 133.63 L 111.5 131.88 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;">
<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: 120px; margin-left: 108px;">
<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: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">
bus
</div>
</div>
</div>
</foreignObject>
<text x="108" y="124" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="11px" text-anchor="middle">
bus
</text>
</switch>
</g>
<path d="M 108 420 L 108 440.04 L 108 430.04 L 108 443.63" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/>
<path d="M 108 448.88 L 104.5 441.88 L 108 443.63 L 111.5 441.88 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;">
<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: 431px; margin-left: 108px;">
<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: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">
bus
</div>
</div>
</div>
</foreignObject>
<text x="108" y="434" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="11px" text-anchor="middle">
bus
</text>
</switch>
</g>
<rect x="68" y="40" width="80" height="40" fill="none" stroke="none" 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 flex-start; justify-content: unsafe flex-start; width: 72px; height: 1px; padding-top: 30px; margin-left: 73px;">
<div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: left; max-height: 50px; overflow: hidden;">
<div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">
<h1>
manta
</h1>
</div>
</div>
</div>
</foreignObject>
<text x="73" y="42" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px">
manta
</text>
</switch>
</g>
<rect x="217" y="20" width="160" height="40" fill="none" stroke="none" 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 flex-start; justify-content: unsafe flex-start; width: 152px; height: 1px; padding-top: 10px; margin-left: 222px;">
<div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: left; max-height: 50px; overflow: hidden;">
<div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">
<h1>
FPGA Fabric
</h1>
</div>
</div>
</div>
</foreignObject>
<text x="222" y="22" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px">
FPGA Fabric
</text>
</switch>
</g>
<path d="M 107.9 210 L 107.9 233.63" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/>
<path d="M 107.9 238.88 L 104.4 231.88 L 107.9 233.63 L 111.4 231.88 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;">
<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: 220px; margin-left: 108px;">
<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: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">
bus
</div>
</div>
</div>
</foreignObject>
<text x="108" y="224" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="11px" text-anchor="middle">
bus
</text>
</switch>
</g>
<path d="M 107.86 310 L 107.86 333.63" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/>
<path d="M 107.86 338.88 L 104.36 331.88 L 107.86 333.63 L 111.36 331.88 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;">
<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: 320px; margin-left: 107px;">
<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: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">
bus
</div>
</div>
</div>
</foreignObject>
<text x="107" y="324" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="11px" text-anchor="middle">
bus
</text>
</switch>
</g>
<path d="M 17 95 L 71.63 95" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/>
<path d="M 76.88 95 L 69.88 98.5 L 71.63 95 L 69.88 91.5 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;">
<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: 95px; margin-left: 16px;">
<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: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">
rx
</div>
</div>
</div>
</foreignObject>
<text x="16" y="99" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="11px" text-anchor="middle">
rx
</text>
</switch>
</g>
<path d="M 266.9 259.56 L 202.52 259.61 L 144.37 259.96" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/>
<path d="M 139.12 259.99 L 146.1 256.45 L 144.37 259.96 L 146.14 263.45 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;">
<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: 261px; margin-left: 181px;">
<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: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">
input_0
</div>
</div>
</div>
</foreignObject>
<text x="181" y="264" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="11px">
input_0
</text>
</switch>
</g>
<path d="M 138 290 L 202.52 290.04 L 260.83 290.08" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/>
<path d="M 266.08 290.08 L 259.08 293.58 L 260.83 290.08 L 259.08 286.58 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;">
<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: 291px; margin-left: 179px;">
<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: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">
output_1
</div>
</div>
</div>
</foreignObject>
<text x="179" y="294" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="11px">
output_1
</text>
</switch>
</g>
<rect x="78" y="80" width="60" height="30" rx="4.5" ry="4.5" fill="#dae8fc" stroke="#6c8ebf" 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: 58px; height: 1px; padding-top: 95px; margin-left: 79px;">
<div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;">
<div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">
rx bridge
</div>
</div>
</div>
</foreignObject>
<text x="108" y="99" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">
rx bridge
</text>
</switch>
</g>
<rect x="78" y="140" width="60" height="70" rx="9" ry="9" fill="#ffe6cc" stroke="#d79b00" 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: 58px; height: 1px; padding-top: 175px; margin-left: 79px;">
<div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;">
<div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">
logic
<br/>
analyzer core
</div>
</div>
</div>
</foreignObject>
<text x="108" y="179" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">
logic...
</text>
</switch>
</g>
<rect x="78" y="240" width="60" height="70" rx="9" ry="9" fill="#ffe6cc" stroke="#d79b00" 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: 58px; height: 1px; padding-top: 275px; margin-left: 79px;">
<div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;">
<div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">
io core
</div>
</div>
</div>
</foreignObject>
<text x="108" y="279" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">
io core
</text>
</switch>
</g>
<rect x="78" y="340" width="60" height="80" rx="9" ry="9" fill="#ffe6cc" stroke="#d79b00" 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: 58px; height: 1px; padding-top: 380px; margin-left: 79px;">
<div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;">
<div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">
block memory core
</div>
</div>
</div>
</foreignObject>
<text x="108" y="384" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">
block memo...
</text>
</switch>
</g>
<rect x="78" y="450" width="60" height="30" rx="4.5" ry="4.5" fill="#dae8fc" stroke="#6c8ebf" 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: 58px; height: 1px; padding-top: 465px; margin-left: 79px;">
<div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;">
<div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">
tx bridge
</div>
</div>
</div>
</foreignObject>
<text x="108" y="469" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">
tx bridge
</text>
</switch>
</g>
<rect x="267" y="140" width="99" height="280" rx="14.85" ry="14.85" fill="#e1d5e7" stroke="#9673a6" 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: 97px; height: 1px; padding-top: 280px; margin-left: 268px;">
<div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;">
<div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">
user logic
</div>
</div>
</div>
</foreignObject>
<text x="317" y="284" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">
user logic
</text>
</switch>
</g>
<path d="M 144.37 355 L 266.9 355.04" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/>
<path d="M 139.12 355 L 146.12 351.5 L 144.37 355 L 146.12 358.5 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;">
<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: 355px; margin-left: 169px;">
<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: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">
user_addr
</div>
</div>
</div>
</foreignObject>
<text x="169" y="359" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="11px">
user_addr
</text>
</switch>
</g>
<path d="M 266.41 370.16 L 202.52 370.22 L 144.37 370.02" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/>
<path d="M 139.12 370 L 146.13 366.53 L 144.37 370.02 L 146.11 373.53 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;">
<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: 370px; margin-left: 169px;">
<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: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">
user_data_in
</div>
</div>
</div>
</foreignObject>
<text x="169" y="374" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="11px">
user_data_in
</text>
</switch>
</g>
<path d="M 138 384.84 L 202.52 384.83 L 261.52 385.24" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/>
<path d="M 266.77 385.27 L 259.75 388.72 L 261.52 385.24 L 259.8 381.72 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;">
<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: 385px; margin-left: 169px;">
<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: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">
user_data_out
</div>
</div>
</div>
</foreignObject>
<text x="169" y="388" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="11px">
user_data_out
</text>
</switch>
</g>
<path d="M 138 400 L 202.52 400.04 L 260.53 399.86" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/>
<path d="M 265.78 399.84 L 258.79 403.37 L 260.53 399.86 L 258.77 396.37 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;">
<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: 400px; margin-left: 163px;">
<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: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">
user_write_enable
</div>
</div>
</div>
</foreignObject>
<text x="163" y="404" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="11px">
user_write_enable
</text>
</switch>
</g>
<path d="M 78 464.85 L 13.37 464.85" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/>
<path d="M 8.12 464.85 L 15.12 461.35 L 13.37 464.85 L 15.12 468.35 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;">
<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: 465px; margin-left: 37px;">
<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: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">
tx
</div>
</div>
</div>
</foreignObject>
<text x="37" y="469" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="11px" text-anchor="middle">
tx
</text>
</switch>
</g>
<path d="M 267.2 174.44 L 202.52 174.39 L 144.37 174.79" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/>
<path d="M 139.12 174.82 L 146.09 171.27 L 144.37 174.79 L 146.14 178.27 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;">
<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: 175px; margin-left: 184px;">
<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: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">
probe_2
</div>
</div>
</div>
</foreignObject>
<text x="184" y="179" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="11px">
probe_2
</text>
</switch>
</g>
<path d="M 266.7 190.12 L 202.52 190.13 L 144.37 190.01" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/>
<path d="M 139.12 190 L 146.13 186.52 L 144.37 190.01 L 146.11 193.52 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;">
<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: 190px; margin-left: 185px;">
<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: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">
probe_3
</div>
</div>
</div>
</foreignObject>
<text x="185" y="194" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="11px">
probe_3
</text>
</switch>
</g>
<path d="M 266.21 159.6 L 202.52 159.61 L 144.37 159.96" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/>
<path d="M 139.12 159.99 L 146.1 156.45 L 144.37 159.96 L 146.14 163.45 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;">
<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: 160px; margin-left: 184px;">
<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: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">
probe_1
</div>
</div>
</div>
</foreignObject>
<text x="184" y="164" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="11px">
probe_1
</text>
</switch>
</g>
<path d="M 139 274.86 L 203.04 274.91 L 260.83 274.7" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/>
<path d="M 266.08 274.68 L 259.09 278.21 L 260.83 274.7 L 259.07 271.21 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;">
<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: 275px; margin-left: 179px;">
<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: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">
output_0
</div>
</div>
</div>
</foreignObject>
<text x="179" y="278" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="11px">
output_0
</text>
</switch>
</g>
</g>
<switch>
<g requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"/>
<a transform="translate(0,-5)" xlink:href="https://www.diagrams.net/doc/faq/svg-export-text-problems" target="_blank">
<text text-anchor="middle" font-size="10px" x="50%" y="100%">
Text is not SVG - cannot display
</text>
</a>
</switch>
</svg>

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 352 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 303 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 234 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 123 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 589 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 483 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 112 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 437 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 149 KiB

View File

@ -1,96 +0,0 @@
## 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!
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:
```yaml
---
cores:
my_block_memory:
type: block_memory
width: 12
depth: 16384
```
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.
### 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 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.
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.
### 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:
Just like with the other cores, interfacing with the BRAM 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)
foo = m.my_block_memory.write(addr=38)
foo = m.my_block_memory.write(addr=1234)
foo = m.my_block_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:
```python
addrs = list(range(0, 1234))
datas = list(range(1234, 2468))
m.my_block_memory.write(addrs, datas)
foo = m.my_block_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.
## Under the Hood
Each Block Memory core is actually a set of 16-bit wide BRAMs with their ports concatenated together, with any spare bits masked off. Here's a diagram:
![](assets/block_memory_architecture.png)
This has one major consequence: if the core doesn't have a width that's an exact multiple of 16, synthesis engines (Vivado in particular) will throw some warnings as they optimize out the unused bits. This is expected behavior, and while the warnings are a little annoying, not having to manually deal with the unused bits simplifies the implementation immensely. No Python is needed to generate the core, and it'll configure itself just based on Verilog parameters. This turns the block memory core from a complicated conditionally-instantiated beast to a simple ~_100 line_ [Verilog file](https://github.com/fischermoseley/manta/blob/main/src/manta/block_memory.v).
### Address Assignment
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|
...and so on.
### Synchronicity
Since Manta's [data bus](../system_architecture) 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.
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 presribe 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.

View File

@ -1,16 +1,45 @@
!!! warning "This section is under construction!"
The Ethernet interface is just about to get refactored to implement a few performance gains, so what's here represents the Ethernet interface circa April 2023. Hang tight for new stuff!
## Overview
For situations where the onboard UART is not available, Manta provides a 100Mbps Ethernet link for communicating between the host machine and target FPGA. This link implements a L2 MAC on the FPGA, designed to be directly connected to a host machine on a dedicated network adapter. The MAC is controlled by a bridge interface, which performs the exact same function as it does on the UART interface. Incoming packets are parsed into bus transactions, placed on the bus, and any response data is encapsulated into another packet sent to the host.
For scenarios where UART is not available or higher bandwidth is desired, Manta provides an Ethernet interface for communicating between the host and FPGA. This interface uses UDP for communication, and leverages the builtin Python `sockets` module on the host side, and the open-source [LiteEth](https://github.com/enjoy-digital/liteeth) Ethernet core on the FPGA side.
This is done by interacting with an Ethernet PHY, an onboard transceiver IC that converts between the FPGA's logic-level signaling and the voltages on the cable's twisted pairs. The communication between the Ethernet PHY and the FPGA is done over an interface that's dependent on the speed of the PHY. The 10/100 Mbps interface used on the Nexys A7-100T uses the RMII as defined in IEEE 802.3u. RMII is the second-oldest member in the Media Independent Interface family, with newer revisions of 802.3 supporting faster interfaces.
!!! info "Not every device is supported!"
Manta's bus clock must be equivalent to the PHY's reference clock if Ethernet is to be used - in the case of the 100Mbps RMII PHY on the Nexys A7 used in 6.205, this is 50MHz. This doesn't pose a problem for user logic, which is connected through Manta's cores that perform CDC internally. It does mean that a reference clock for the PHY has to be synthesized outside of Manta itself, and the means by which this is done varies by FPGA vendor and toolchain.
Although Manta aims to be as platform-agnostic as possible, Ethernet PHYs and FPGA clock primitives are very particular devices. As a result, the supported devices are loosely restricted to those on [this list](https://github.com/enjoy-digital/liteeth?tab=readme-ov-file#-features). If a device you'd like to use isn't on the list, the community would love your help!
This MAC allows for the usage of packets with the structure shown below. The bus transaction being communicated is placed at the beginning of the packet's payload field, which IEEE 802.3 allows to vary in length from 46 to 1500 bytes. The 46-byte lower limit requires 41 bytes of zero padding to be added to the five bytes used to specify a bus transaction, and only one bus transactions is specified in each Ethernet frame. This abundance of unused space results in all packets being the same length, whether the packet contains a read request, write request, or read response. Packets containing write requests elicit no response from the FPGA, just as write requests delivered over UART produce no response.
Although UDP does not guarantee reliable packet delivery, this usually doesn't pose an issue in practice. Manta will throw a runtime error if packets are dropped, and the UDP checksum and Ethernet FCS guarantee that any data delivered is not corrupted. Together, these two behaviors prevent corrupted data from being provided to the user, as Manta will error before returning invalid data. As long as your network is not terribly congested, Manta will operate without issue.
![](assets/ethernet_packet.png)
## Configuration
These packets are addressed directly to the host's MAC address, which is obtained during code autogeneration. These packets also use a fixed Ethertype of `0x88B5`, which is specially reserved for "public use and for prototype and vendor-specific protocol development" in IEEE 802.1. This was done to create an Ethernet II frame instead of a legacy 802.3 frame, without having to implement a higher level protocol like TCP or UDP to safely use a fixed Ethertype. This allows the MAC to use modern Ethernet II frames safely, but save FPGA resources.
The configuration of the Ethernet core is best shown by example:
```yaml
ethernet:
phy: LiteEthPHYRMII
vendor: xilinx
toolchain: vivado
clk_freq: 50e6
refclk_freq: 50e6
fpga_ip_addr: "192.168.0.110"
host_ip_addr: "192.168.0.100"
```
This snippet at the end of the configuration file defines the interface. The following parameters must be set:
- `phy` _(required)_: The name of the LiteEth PHY class to use. Valid values consist of any of the names in [this list](https://github.com/enjoy-digital/liteeth/blob/b4e28506238c5340f2ade7899c2223424cabd410/liteeth/phy/__init__.py#L25-L45). Select the appropriate one for your FPGA vendor and family.
- `vendor` _(required)_: The vendor of the FPGA being designed for. Currently only values of `xilinx` and `lattice` are supported. Used to generate timing constraints files, which are currently unused.
- `toolchain` _(required)_: The toolchain being used. Currently only values of `vivado` and `diamond` are supported.
- `clk_freq` _(required)_: The frequency of the clock provided to the Manta instance.
- `refclk_freq` _(required)_: The frequency of the reference clock to be provided to the Ethernet PHY. This frequency must match the MII variant supported by the PHY, as well as speed that the PHY is being operated at. For instance, a RGMII PHY may be operated at either 125MHz in Gigabit mode, or 25MHz in 100Mbps mode.
- `fpga_ip_addr` _(required)_: The IP address the FPGA will attempt to claim. Upon power-on, the FPGA will issue a DHCP request for this IP address. The easiest way to check if this was successful is by pinging the FPGA's IP, but if you have access to your network's router it may report a list of connected devices.
- `host_ip_addr` _(required)_: The IP address of the host machine, which the FPGA will send packets back to.
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!
!!! warning "LiteEth doesn't always generate its own `refclk`!"
Although LitEth is built on Migen and LiteX which support PLLs and other clock generation primitives, I haven't seen it instantiate one to synthesize a suitable `refclk` at the appropriate frequency from the input clock. As a result, for now it's recommended to generate your `refclk` outside Manta, and then use it to clock your Manta instance.

View File

@ -1,11 +1,11 @@
## Overview
To use Manta, you'll need a host machine with a FPGA board connected over UART or Ethernet. You'll then:
To use Manta, you'll need a host machine with a FPGA board connected over UART, or a FPGA board connected to the same network via Ethernet. You'll then:
- _Specify a set of debug cores you wish to include in your design._ This is done by writing a configuration file, typically called `manta.yaml`. Specifying files in JSON is also supported, as long as the hierarchy in the file is equivalent. Just make sure that your YAML files end in `.yaml` or `.yml`, and that JSON files end in `.json`.
- _Invoke Manta to generate Verilog from the configuration provided._ This is done by running `manta gen [config_file] [verilog_file]` at the command line, which generates a Verilog file (typically named `manta.v`) from the provided configuration file. This Verilog file contains a definition for a Verilog module named `manta`, and all its constituent modules.
- _Instantiate `manta` in your design, and connecting it to the logic you'd like to debug._ An example instantiation is provided at the top of `manta.v`, which you can copy-paste into your main source code. You'll connect its ports to the logic you're trying to debug, as well as to whatever interface you're using to communicate with the host. This will be a serial transciever on your development board if you're using UART, or it's RMII PHY if you're using Ethernet.
- _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.
@ -31,7 +31,7 @@ cores:
my_logic_analyzer:
type: logic_analyzer
sample_depth: 4096
trigger_loc: 1000
trigger_location: 1000
probes:
larry: 1
@ -58,34 +58,19 @@ This Manta instance has an IO Core and a Logic Analyzer, each containing a numbe
## Example Instantiation
The Verilog file generated by `manta gen` contains some information at the top of the file. This includes an example instantiation for the `manta` module that's been configured, which you can copy paste into your source code. Here's what that looks like for the configuration above:
```c
/*
This module was generated with Manta v0.0.5 on 11 Sep 2023 at 17:52:28 by fischerm
If this breaks or if you've got spicy formal verification memes, contact fischerm [at] mit.edu
Provided under a GNU GPLv3 license. Go wild.
Here's an example instantiation of the Manta module you configured, feel free to copy-paste
this into your source!
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),
.rx(rx),
.tx(tx),
.probe_0_in(probe_0_in),
.probe_1_in(probe_1_in),
.probe_2_out(probe_2_out),
.probe_3_out(probe_3_out),
.larry(larry),
.curly(curly),
.moe(moe));
*/
```

View File

@ -2,7 +2,13 @@
## Manta: A Configurable and Approachable Tool for FPGA Debugging and Rapid Prototyping
Manta is a tool for getting information into and out of FPGAs over UART or Ethernet. It's primarily intended for debugging and experimentation, but it's robust enough to be a simple, reliable transport layer between a FPGA and a host machine. It works by letting you configure a series of cores, which live as digital logic on the FPGA and are represented with vendor-agnostic Verilog-2001. The information and behavior of these cores are accessible to the host machine, which presents a Python API to the user. Manta includes the following cores, any number and combination of which may be used at once:
Manta is a tool for moving data between a host machine and a FPGA over UART or Ethernet. It's primarily intended for debugging and rapid prototyping of FPGA designs, but it's robust enough to be used as a simple, reliable transport layer.
Manta works by generating a number of cores that are instantiated in the FPGA design. These allow for a variety of functions, such as reading and writing to registers and memory, or capturing data with a logic analyzer. These cores are operated by the connected host machine through either the Manta CLI, or a simple Python API.
Manta is written in Amaranth HDL, and the generated designs may be used natively in other Amaranth designs, or exported to vendor-agnostic Verilog-2001. All dependencies are cross-platform, so Manta can be used on any machine that has at least Python 3.8 or newer installed.
Manta's capabilities are best reflected in its cores, for which a brief description of each is provided below:
### __Logic Analyzer Core__
@ -28,9 +34,9 @@ You may find this core useful for:
* _Making dashboards_ - you'd like to get some telemetry out of your existing FPGA design and display it nicely, but you don't want to implement an interface, design a packetization scheme, and write a library.
### __Block Memory Cores__
### __Memory Cores__
_More details available on the [full documentation page](./block_memory_core.md)._
_More details available on the [full documentation page](./memory_core.md)._
This core creates a two-port block memory on the FPGA, and gives one port to the host machine, and the other to your logic on the FPGA. The width and depth of this block memory is configurable, allowing large chunks of arbitrarily-sized data to be shuffled onto and off of the FPGA by the host machine, via the Python API. This lets you establish a transport layer between the host and FPGA, that treats the data as exactly how it exists on the FPGA.
@ -40,14 +46,10 @@ You may find this core useful for:
* _Hand-tuning ROMs_ - you're designing a digital filter for a DSP project and would like to tune it in real-time, or you're developing a soft processor and want to upload program code without rebuilding a bitstream.
## Dependencies
Manta is written in Python, and generates Verilog-2001 HDL. It's cross-platform, and its only strict dependency is pyYAML. However, [pySerial](https://github.com/pyserial/pyserial) is required for using UART, [scapy](https://github.com/secdev/scapy) is required for using Ethernet, and [pyvcd](https://github.com/westerndigitalcorporation/pyvcd) is required if you want to export a waveform from the Logic Analyzer core to a `.vcd` file.
## About
Manta and its source code are released under a [GPLv3 license](https://github.com/fischermoseley/manta/blob/main/LICENSE.txt), and it was originally developed as part of my [Master's Thesis at MIT](https://hdl.handle.net/1721.1/151223) in 2023, done under the supervision of [Dr. Joe Steinmeyer](https://www.jodalyst.com/). The thesis itself is copyrighted by Fischer Moseley (me!), but feel free to use the following Bibtex if you'd like to cite it:
```
```bibtex
@misc{manta2023,
author={Fischer Moseley},
title={Manta: An In-Situ Debugging Tool for Programmable Hardware},

View File

@ -1,32 +1,43 @@
## Dependencies
Manta requires the following dependencies:
Before installing, make sure to upgrade your `pip` to the latest version:
- pyYAML, which is used for parsing configuration files written in YAML.
- pySerial, used for communicating with the FPGA over UART.
- Scapy, used for communicating with FPGA over Ethernet.
- pyVCD, used for writing waveforms captured by the Logic Analyzer Core to standard Value Change Dump (VCD) files.
```bash
pip install --upgrade pip
```
All of these dependencies are technically optional. If you're comfortable writing configuration files in JSON, then you don't need pyYAML. If you're using UART exclusively in your project, then you won't need Scapy. That said, Manta will try to install (or use an existing copy of) pyYAML, pySerial, and pyVCD during its own installation to cover all use cases.
## Installation
## Latest Version
You can install the latest version of Manta directly from source with:
```
pip install git+https://github.com/fischermoseley/manta.git
```bash
pip install --upgrade git+https://github.com/fischermoseley/manta.git
```
!!! warning "Note for Ubuntu users:"
## Editable Development Install
If you're working on the source, you might want an editable installation with some extra dependencies used for development:
If you're on Ubuntu, you'll probably need to run this first to dodge
a bug in the current version of Python's `setuptools`:
```
export DEB_PYTHON_INSTALL_LAYOUT=deb_system
```
Do this before installing Manta. If you've already installed it, just
uninstall, run the above command, and then reinstall.
```bash
git clone https://github.com/fischermoseley/manta.git
cd manta
pip install -e ".[dev]"
```
## Adding Manta to Path (Recommended)
It's recommended to place Manta on your system path by adding `export PATH="~/.local/bin:$PATH"` to your `.bashrc` or `.zshrc`. This isn't strictly necessary, but it means that Manta (and any other executable Python modules) can be run as just `manta` on the command line, instead of `python3 -m manta`. If you're on Windows, this location will likely be different.
Feel free to install Manta within a virtual environment (venv, Conda, and so on) if you'd like!
Later Manta will be availabe on the PyPI lists, and you'll be able to just `pip install mantaray`, but that's not configured quite yet.
Later Manta will be availabe on the PyPI lists, and you'll be able to just `pip install mantaray`, but that's not configured quite yet.
## Dependencies
Manta requires the following dependencies:
- [Amaranth HDL](https://amaranth-lang.org/docs/amaranth/latest/), which comes with it's own built-in copy of Yosys.
- [LiteEth](https://github.com/enjoy-digital/liteeth), for sending and receiving UDP packets on the FPGA.
- [pySerial](https://pyserial.readthedocs.io/en/latest/index.html), for communicating with the FPGA over UART.
- [pyYAML](https://pyyaml.org/), for parsing configuration files written in YAML.
- [pyVCD](https://github.com/westerndigitalcorporation/pyvcd), for writing waveforms captured by the Logic Analyzer Core to standard Value Change Dump (VCD) files.
As well as these dependencies for development, which are installed with the `[dev]` argument:
- [Pytest](https://pytest.org/), for unit testing.
- [Black](https://black.readthedocs.io/en/stable/), for formatting the Python source.
- [mkdocs-material](https://squidfunk.github.io/mkdocs-material/), for generating the documentation site.
- [amaranth_boards](https://github.com/amaranth-lang/amaranth-boards), for building designs for hardware-in-the-loop testing done by the CI.

View File

@ -32,7 +32,7 @@ Inside this configuration, the following parameters may be configured:
- `name` _(required)_: 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` _(required)_: 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` _(optional)_: 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. Technically specifying input probes is totally optional - it's perfectly fine to have an IO core with only output probes.
- `outputs` _(optional)_: This lists all outputs from the host machine to the FPGA fabric. Signals in this list are usually written to by the host, but they can also be read from. Doing so returns the value last written to the register. Just like the `inputs` parameter, this list is techically optional, and it's perfectly valid to have an IO core with input probes only.
- `outputs` _(optional)_: This lists all outputs from the host machine to the FPGA fabric. Signals in this list are usually written to by the host, but they can also be read from. Doing so returns the value last written to the register. Just like the `inputs` parameter, this list is technically optional, and it's perfectly valid to have an IO core with input probes only.
- `initial_value` _(optional)_: This sets an initial value for an output probe to take after the FPGA powers on. This is done with an `initial` statement in Manta's Verilog, and is independent of the input clock or resets elsewhere in the FPGA. This parameter is optional, and if it isn't provided the probe will initialize to zero.
- `user_clock` _(optional)_: If set to True, an extra input port will be added to the `manta` module for an clock input to run the IO core on. This lets the IO Core handle clock domain crossing through its internal buffers. If set to False, Manta will run the IO core from its internal clock (the one provided through `manta`'s `clk` port). More information on this is available in the [diagram](#how-it-works) below. This parameter is optional, and defaults to False.
@ -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 receieved.
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 receieved.
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,28 +74,18 @@ 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
```
## Caveats
## Limitations
While the IO core performs a very, very simple task, it carries a few caveats.
- First, __it's not instantaneous__. Manta has designed to be as fast as possible, but setting and querying registers relies on passing messages between the host and FPGA, which is slow relative to FPGA clock speeds! If you're trying to set values in your design with cycle-accurate timing, this will not do that for you. However, the [Logic Analyzer's playback feature](./logic_analyzer.md#playback) might be helpful.
- First, __it's not instantaneous__. Manta has designed to be as fast as possible, but setting and querying registers relies on passing messages between the host and FPGA, which is slow relative to FPGA clock speeds! If you're trying to set values in your design with cycle-accurate timing, this will not do that for you. However, the [Logic Analyzer's playback feature](./logic_analyzer_core.md#playback) might be helpful.
- Second, __the API methods are blocking__, and will wait for a response from the FPGA before resuming program execution. Depending on your application, you might want to run your IO Core operations in a seperate thread, but you can also decrease the execution time by using a faster interface between the host and FPGA. This means using a higher UART baudrate, or using Ethernet.
## How It Works
This is done with the architecture shown below:
![](assets/io_core_architecture.png){:style="width:49%"}
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.
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. This is explained in more detail in Chapter 3.6 of the [original thesis](thesis.pdf).
- Second, __the API methods are blocking__, and will wait for a response from the FPGA before resuming program execution. Depending on your application, you might want to run your IO Core operations in a separate thread, but you can also decrease the execution time by using a faster interface between the host and FPGA. This means using a higher UART baudrate, or using Ethernet.

View File

@ -14,7 +14,7 @@ cores:
my_logic_analyzer:
type: logic_analyzer
sample_depth: 4096
trigger_loc: 1000
trigger_location: 1000
probes:
larry: 1
@ -60,24 +60,16 @@ Each individual trigger is specified with the following structure:
- `EQ`, for equal to.
- `NEQ`, for not equal to.
These operations require a constant to compare against, referred to as an _argument_, which is descirbed below:
These operations require a constant to compare against, referred to as an _argument_, which is described below:
- __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.
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.
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 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:
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:
@ -101,50 +93,29 @@ 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
manta capture manta.yaml my_logic_analyzer capture.vcd capture.v
```
This will reset your logic analyzer, configure it with the triggers specified in `manta.yaml`, and perform a capture. The resulting .vcd file can be opened in a waveform viewer like [GTKWave](https://gtkwave.sourceforge.net/), and the `.mem` file can be used for playback as described in the following section.
Manta will stuff the capture data into as many files as you provide it on the command line, so if you don't want the `.mem` or `.vcd` file, just omit their paths.
This will reset your logic analyzer, configure it with the triggers specified in `manta.yaml`, and perform a capture. The resulting .vcd file can be opened in a waveform viewer like [GTKWave](https://gtkwave.sourceforge.net/). Manta will stuff the capture data into as many files as you provide it on the command line, so if you don't want the `.mem` or `.vcd` file, just omit their paths.
### Playback
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_path] [core_name] [verilog_file_path]
```
Manta has the ability to generate a module that _plays back_ a set of data captured from a Logic Analyzer core. This module has a set of outputs matching the inputs of the Logic Analyzer, which when enabled, will take the exact values captured by the logic analyzer. This module is synthesizable, and can either be used in simulation or included in the FPGA design. This is handy for
If the file `manta.yaml` contained the configuration above, then running:
```
manta playback manta.yaml my_logic_analyzer sim/playback.v
```bash
manta capture manta.yaml my_logic_analyzer capture.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.
Generates a Verilog module at `capture.v` which can then be instantiated in the testbench or FPGA design in which it is needed.
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.
- _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).
At present, this class contains methods used really only for capturing data, and exporting `.vcd` and `.mem` files. It'd be super handy to expose the data from the logic analyzer core in a Pythonic way - which is why the feature is on the [roadmap](https://github.com/fischermoseley/manta/milestones)!
## How It Works
The Logic Analyzer Core's implementation on the FPGA consists of three primary components:
![](assets/logic_analyzer_architecture.png){style="width:85%"}
- 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}
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.

74
doc/memory_core.md Normal file
View File

@ -0,0 +1,74 @@
## Overview
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 Memory core is configured via an entry in a project's configuration file. This is easiest to show by example:
```yaml
---
cores:
my_memory:
type: memory
mode: bidirectional
width: 12
depth: 16384
```
There's a few parameters that get configured here, including:
- `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.
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.
!!! 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.
### 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 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 Memory with the Python API is simple:
```python
from manta import Manta
m = manta('manta.yaml')
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_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:
```python
addrs = list(range(0, 1234))
datas = list(range(1234, 2468))
m.my_memory.write(addrs, datas)
foo = m.my_memory.read(addrs)
```
### Synchronicity
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 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 RAM is invalid is a thousand times smaller.

View File

@ -1,16 +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
- [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
- [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.

View File

@ -1,6 +1,6 @@
## Overview
Manta needs an interface to pass data between the host machine and FPGA, and UART is a convenient option. When configured to use UART, Manta will shuffle data back and forth using generic 8N1 serial with no flow control. This happens through a series of read and write transactions, which are specified using a messaging format described [here](../how_it_works/#message-format).
Manta needs an interface to pass data between the host machine and FPGA, and UART is a convenient option. When configured to use UART, Manta will shuffle data back and forth using generic 8N1 serial with no flow control. This happens through a series of read and write transactions, which are specified using a messaging format described [here](architecture.md#message-format).
## Configuration
@ -12,7 +12,7 @@ uart:
baudrate: 3000000
clock_freq: 100000000
```
This snippet defines the interface, and lives at the bottom of a Manta configuration file. Three parameters must be set:
This snippet at the end of the configuration file defines the interface. The following parameters must be set:
- `port` _(required)_: The name of the serial port on the host machine that's connected to the FPGA. Depending on your platform, this could be `/dev/ttyUSBXX`, `/dev/tty.usbserialXXX`, or `COMX`. If set to `auto`, then Manta will try to find the right serial port by looking for a USB device with the same VID and PID as a FT2232 - a USB/UART converter chip that's super popular on FPGA dev boards. This doesn't always work, but it's super convenient when it does. If your port isn't automatically detected, then just specify the port manually.

11
environment.sh Normal file
View File

@ -0,0 +1,11 @@
#!/usr/bin/env bash
export VIVADO=/tools/Xilinx/Vivado/2023.1/bin/vivado
export YOSYS=/tools/oss-cad-suite/bin/yosys
export NEXTPNR_ICE40=/tools/oss-cad-suite/bin/nextpnr-ice40
export ICEPACK=/tools/oss-cad-suite/bin/icepack
export ICEPROG=/tools/oss-cad-suite/bin/iceprog
export NEXYS4DDR_PORT=/dev/serial/by-id/usb-Digilent_Digilent_USB_Device_210292696307-if01-port0
export ICESTICK_PORT=/dev/serial/by-id/usb-Lattice_Lattice_FTUSB_Interface_Cable-if01-port0

View File

@ -1,45 +0,0 @@
from manta import Manta
from time import sleep
m = Manta('manta.yaml')
i = 0
while True:
i = (i+1) % 5
if(i==0):
m.my_io_core.LED0.set(1)
m.my_io_core.LED1.set(0)
m.my_io_core.LED2.set(0)
m.my_io_core.LED3.set(0)
m.my_io_core.LED4.set(0)
if(i==1):
m.my_io_core.LED0.set(0)
m.my_io_core.LED1.set(1)
m.my_io_core.LED2.set(0)
m.my_io_core.LED3.set(0)
m.my_io_core.LED4.set(0)
if(i==2):
m.my_io_core.LED0.set(0)
m.my_io_core.LED1.set(0)
m.my_io_core.LED2.set(1)
m.my_io_core.LED3.set(0)
m.my_io_core.LED4.set(0)
if(i==3):
m.my_io_core.LED0.set(0)
m.my_io_core.LED1.set(0)
m.my_io_core.LED2.set(0)
m.my_io_core.LED3.set(1)
m.my_io_core.LED4.set(0)
if(i==4):
m.my_io_core.LED0.set(0)
m.my_io_core.LED1.set(0)
m.my_io_core.LED2.set(0)
m.my_io_core.LED3.set(0)
m.my_io_core.LED4.set(1)
sleep(0.1)

View File

@ -1,18 +0,0 @@
from manta import Manta
from time import sleep
from random import randint
m = Manta('manta.yaml')
for addr in range(1024):
number = randint(0,65535)
m.my_block_memory.write(addr, number)
readback = m.my_block_memory.read(addr)
if readback == number:
print(f"Success! Wrote and read back {hex(number)} from {hex(addr)}")
else:
print(f"Failure! Wrote {hex(number)} to {hex(addr)}, but received {hex(readback)}")
exit()

View File

@ -1,11 +0,0 @@
---
cores:
my_block_memory:
type: block_memory
width: 16
depth: 1024
uart:
port: "/dev/ttyUSB1"
baudrate: 2000000
clock_freq: 100000000

View File

@ -1,40 +0,0 @@
from manta import Manta
from time import sleep
m = Manta('manta.yaml')
i = 0
direction = "left"
while True:
if direction == "left":
if i == 15:
direction = "right"
i = i - 1
m.my_io_core.led16_r.set(1)
m.my_io_core.led16_g.set(0)
m.my_io_core.led16_b.set(1)
else:
i = i + 1
if direction == "right":
if i == 0:
direction = "left"
i = i + 1
m.my_io_core.led16_r.set(0)
m.my_io_core.led16_g.set(1)
m.my_io_core.led16_b.set(0)
else:
i = i - 1
m.my_io_core.led.set(2**i)
print(f"Input Ports:")
print(f" btnu: {m.my_io_core.btnu.get()}")
print(f" btnd: {m.my_io_core.btnd.get()}")
print(f" btnr: {m.my_io_core.btnr.get()}")
print(f" btnl: {m.my_io_core.btnl.get()}")
print(f" btnc: {m.my_io_core.btnc.get()}")
print(f" sw: {m.my_io_core.sw.get()}\n")
sleep(0.5)

View File

@ -1,25 +0,0 @@
---
cores:
my_io_core:
type: io
inputs:
btnu: 1
btnd: 1
btnl: 1
btnr: 1
btnc: 1
sw: 16
outputs:
led: 16
led16_b: 1
led16_g: 1
led16_r: 1
led17_b: 1
led17_g: 1
led17_r: 1
ethernet:
interface: "en8"
host_mac: "12:34:56:78:90:ab"

View File

@ -1,61 +0,0 @@
`default_nettype none
`timescale 1ns / 1ps
module top_level (
input wire clk,
input wire eth_crsdv,
input wire [1:0] eth_rxd,
output logic [1:0] eth_txd,
output logic eth_txen,
output logic eth_refclk,
output logic eth_rstn,
input wire btnu,
input wire btnd,
input wire btnl,
input wire btnr,
input wire btnc,
input wire [15:0] sw,
output logic [15:0] led,
output logic led16_b,
output logic led16_g,
output logic led16_r,
output logic led17_b,
output logic led17_g,
output logic led17_r);
// 50MHz clock generation for the RMII
logic ethclk;
divider div (
.clk(clk),
.ethclk(ethclk));
assign eth_rstn = 1;
assign eth_refclk = ethclk;
manta manta_inst (
.clk(ethclk),
.crsdv(eth_crsdv),
.rxd(eth_rxd),
.txen(eth_txen),
.txd(eth_txd),
.btnu(btnu),
.btnd(btnd),
.btnl(btnl),
.btnr(btnr),
.btnc(btnc),
.sw(sw),
.led(led),
.led16_b(led16_b),
.led16_g(led16_g),
.led16_r(led16_r),
.led17_b(led17_b),
.led17_g(led17_g),
.led17_r(led17_r));
endmodule
`default_nettype wire

View File

@ -1,40 +0,0 @@
from manta import Manta
from time import sleep
m = Manta('manta.yaml')
i = 0
direction = "left"
while True:
if direction == "left":
if i == 15:
direction = "right"
i = i - 1
m.my_io_core.led16_r.set(1)
m.my_io_core.led16_g.set(0)
m.my_io_core.led16_b.set(1)
else:
i = i + 1
if direction == "right":
if i == 0:
direction = "left"
i = i + 1
m.my_io_core.led16_r.set(0)
m.my_io_core.led16_g.set(1)
m.my_io_core.led16_b.set(0)
else:
i = i - 1
m.my_io_core.led.set(2**i)
print(f"Input Ports:")
print(f" btnu: {m.my_io_core.btnu.get()}")
print(f" btnd: {m.my_io_core.btnd.get()}")
print(f" btnr: {m.my_io_core.btnr.get()}")
print(f" btnl: {m.my_io_core.btnl.get()}")
print(f" btnc: {m.my_io_core.btnc.get()}")
print(f" sw: {m.my_io_core.sw.get()}\n")
sleep(0.5)

View File

@ -1,23 +0,0 @@
---
cores:
io_core:
type: io
inputs:
probe0: 1
probe1: 2
probe2: 8
probe3: 20
outputs:
probe4:
width: 1
initial_value: 1
probe5: 2
probe6: 8
probe7: 20
uart:
port: "auto"
baudrate: 3000000
clock_freq: 100000000

View File

@ -1,32 +0,0 @@
`default_nettype none
`timescale 1ns / 1ps
module top_level (
input wire clk,
input wire uart_txd_in,
output logic uart_rxd_out);
logic probe0;
logic [1:0] probe1;
logic [7:0] probe2;
logic [19:0] probe3;
manta manta_inst (
.clk(clk),
.rx(uart_txd_in),
.tx(uart_rxd_out),
.probe0(probe0),
.probe1(probe1),
.probe2(probe2),
.probe3(probe3),
.probe4(probe0),
.probe5(probe1),
.probe6(probe2),
.probe7(probe3));
endmodule
`default_nettype wire

View File

@ -1,26 +0,0 @@
from manta import Manta
from random import randint
m = Manta('manta.yaml')
n_tests = 100
for i in range(n_tests):
print(f"-> Beginning test {i} of {n_tests}")
probe4 = randint(0, 1)
m.io_core.probe4.set(probe4)
assert m.io_core.probe4.get() == probe4
assert m.io_core.probe0.get() == probe4
probe5 = randint(0, 3)
m.io_core.probe5.set(probe5)
assert m.io_core.probe5.get() == probe5
assert m.io_core.probe1.get() == probe5
probe6 = randint(0, 255)
m.io_core.probe6.set(probe6)
assert m.io_core.probe6.get() == probe6
assert m.io_core.probe2.get() == probe6
probe7 = randint(0, (2**20)-1)
m.io_core.probe7.set(probe7)
assert m.io_core.probe7.get() == probe7
assert m.io_core.probe3.get() == probe7

View File

@ -1,254 +0,0 @@
## This file is a general .xdc for the Nexys4 DDR Rev. C
## To use it in a project:
## - uncomment the lines corresponding to used pins
## - rename the used ports (in each line, after get_ports) according to the top level signal names in the project
## This file has been modified from the default .xdc provided by Digilent for the Nexys A7
## Clock signal - uncomment _both_ of these lines to create clk_100mhz
set_property -dict { PACKAGE_PIN E3 IOSTANDARD LVCMOS33 } [get_ports { clk }]; #IO_L12P_T1_MRCC_35 Sch=clk
create_clock -add -name sys_clk_pin -period 10.00 -waveform {0 5} [get_ports {clk}];
##Switches
#set_property -dict { PACKAGE_PIN J15 IOSTANDARD LVCMOS33 } [get_ports { sw[0] }]; #IO_L24N_T3_RS0_15 Sch=sw[0]
#set_property -dict { PACKAGE_PIN L16 IOSTANDARD LVCMOS33 } [get_ports { sw[1] }]; #IO_L3N_T0_DQS_EMCCLK_14 Sch=sw[1]
#set_property -dict { PACKAGE_PIN M13 IOSTANDARD LVCMOS33 } [get_ports { sw[2] }]; #IO_L6N_T0_D08_VREF_14 Sch=sw[2]
#set_property -dict { PACKAGE_PIN R15 IOSTANDARD LVCMOS33 } [get_ports { sw[3] }]; #IO_L13N_T2_MRCC_14 Sch=sw[3]
#set_property -dict { PACKAGE_PIN R17 IOSTANDARD LVCMOS33 } [get_ports { sw[4] }]; #IO_L12N_T1_MRCC_14 Sch=sw[4]
#set_property -dict { PACKAGE_PIN T18 IOSTANDARD LVCMOS33 } [get_ports { sw[5] }]; #IO_L7N_T1_D10_14 Sch=sw[5]
#set_property -dict { PACKAGE_PIN U18 IOSTANDARD LVCMOS33 } [get_ports { sw[6] }]; #IO_L17N_T2_A13_D29_14 Sch=sw[6]
#set_property -dict { PACKAGE_PIN R13 IOSTANDARD LVCMOS33 } [get_ports { sw[7] }]; #IO_L5N_T0_D07_14 Sch=sw[7]
#set_property -dict { PACKAGE_PIN T8 IOSTANDARD LVCMOS18 } [get_ports { sw[8] }]; #IO_L24N_T3_34 Sch=sw[8]
#set_property -dict { PACKAGE_PIN U8 IOSTANDARD LVCMOS18 } [get_ports { sw[9] }]; #IO_25_34 Sch=sw[9]
#set_property -dict { PACKAGE_PIN R16 IOSTANDARD LVCMOS33 } [get_ports { sw[10] }]; #IO_L15P_T2_DQS_RDWR_B_14 Sch=sw[10]
#set_property -dict { PACKAGE_PIN T13 IOSTANDARD LVCMOS33 } [get_ports { sw[11] }]; #IO_L23P_T3_A03_D19_14 Sch=sw[11]
#set_property -dict { PACKAGE_PIN H6 IOSTANDARD LVCMOS33 } [get_ports { sw[12] }]; #IO_L24P_T3_35 Sch=sw[12]
#set_property -dict { PACKAGE_PIN U12 IOSTANDARD LVCMOS33 } [get_ports { sw[13] }]; #IO_L20P_T3_A08_D24_14 Sch=sw[13]
#set_property -dict { PACKAGE_PIN U11 IOSTANDARD LVCMOS33 } [get_ports { sw[14] }]; #IO_L19N_T3_A09_D25_VREF_14 Sch=sw[14]
#set_property -dict { PACKAGE_PIN V10 IOSTANDARD LVCMOS33 } [get_ports { sw[15] }]; #IO_L21P_T3_DQS_14 Sch=sw[15]
## LEDs
#set_property -dict { PACKAGE_PIN H17 IOSTANDARD LVCMOS33 } [get_ports { led[0] }]; #IO_L18P_T2_A24_15 Sch=led[0]
#set_property -dict { PACKAGE_PIN K15 IOSTANDARD LVCMOS33 } [get_ports { led[1] }]; #IO_L24P_T3_RS1_15 Sch=led[1]
#set_property -dict { PACKAGE_PIN J13 IOSTANDARD LVCMOS33 } [get_ports { led[2] }]; #IO_L17N_T2_A25_15 Sch=led[2]
#set_property -dict { PACKAGE_PIN N14 IOSTANDARD LVCMOS33 } [get_ports { led[3] }]; #IO_L8P_T1_D11_14 Sch=led[3]
#set_property -dict { PACKAGE_PIN R18 IOSTANDARD LVCMOS33 } [get_ports { led[4] }]; #IO_L7P_T1_D09_14 Sch=led[4]
#set_property -dict { PACKAGE_PIN V17 IOSTANDARD LVCMOS33 } [get_ports { led[5] }]; #IO_L18N_T2_A11_D27_14 Sch=led[5]
#set_property -dict { PACKAGE_PIN U17 IOSTANDARD LVCMOS33 } [get_ports { led[6] }]; #IO_L17P_T2_A14_D30_14 Sch=led[6]
#set_property -dict { PACKAGE_PIN U16 IOSTANDARD LVCMOS33 } [get_ports { led[7] }]; #IO_L18P_T2_A12_D28_14 Sch=led[7]
#set_property -dict { PACKAGE_PIN V16 IOSTANDARD LVCMOS33 } [get_ports { led[8] }]; #IO_L16N_T2_A15_D31_14 Sch=led[8]
#set_property -dict { PACKAGE_PIN T15 IOSTANDARD LVCMOS33 } [get_ports { led[9] }]; #IO_L14N_T2_SRCC_14 Sch=led[9]
#set_property -dict { PACKAGE_PIN U14 IOSTANDARD LVCMOS33 } [get_ports { led[10] }]; #IO_L22P_T3_A05_D21_14 Sch=led[10]
#set_property -dict { PACKAGE_PIN T16 IOSTANDARD LVCMOS33 } [get_ports { led[11] }]; #IO_L15N_T2_DQS_DOUT_CSO_B_14 Sch=led[11]
#set_property -dict { PACKAGE_PIN V15 IOSTANDARD LVCMOS33 } [get_ports { led[12] }]; #IO_L16P_T2_CSI_B_14 Sch=led[12]
#set_property -dict { PACKAGE_PIN V14 IOSTANDARD LVCMOS33 } [get_ports { led[13] }]; #IO_L22N_T3_A04_D20_14 Sch=led[13]
#set_property -dict { PACKAGE_PIN V12 IOSTANDARD LVCMOS33 } [get_ports { led[14] }]; #IO_L20N_T3_A07_D23_14 Sch=led[14]
#set_property -dict { PACKAGE_PIN V11 IOSTANDARD LVCMOS33 } [get_ports { led[15] }]; #IO_L21N_T3_DQS_A06_D22_14 Sch=led[15]
#
#set_property -dict { PACKAGE_PIN R12 IOSTANDARD LVCMOS33 } [get_ports { led16_b }]; #IO_L5P_T0_D06_14 Sch=led16_b
#set_property -dict { PACKAGE_PIN M16 IOSTANDARD LVCMOS33 } [get_ports { led16_g }]; #IO_L10P_T1_D14_14 Sch=led16_g
#set_property -dict { PACKAGE_PIN N15 IOSTANDARD LVCMOS33 } [get_ports { led16_r }]; #IO_L11P_T1_SRCC_14 Sch=led16_r
#set_property -dict { PACKAGE_PIN G14 IOSTANDARD LVCMOS33 } [get_ports { led17_b }]; #IO_L15N_T2_DQS_ADV_B_15 Sch=led17_b
#set_property -dict { PACKAGE_PIN R11 IOSTANDARD LVCMOS33 } [get_ports { led17_g }]; #IO_0_14 Sch=led17_g
#set_property -dict { PACKAGE_PIN N16 IOSTANDARD LVCMOS33 } [get_ports { led17_r }]; #IO_L11N_T1_SRCC_14 Sch=led17_r
##7 segment display
#set_property -dict { PACKAGE_PIN T10 IOSTANDARD LVCMOS33 } [get_ports { ca }]; #IO_L24N_T3_A00_D16_14 Sch=ca
#set_property -dict { PACKAGE_PIN R10 IOSTANDARD LVCMOS33 } [get_ports { cb }]; #IO_25_14 Sch=cb
#set_property -dict { PACKAGE_PIN K16 IOSTANDARD LVCMOS33 } [get_ports { cc }]; #IO_25_15 Sch=cc
#set_property -dict { PACKAGE_PIN K13 IOSTANDARD LVCMOS33 } [get_ports { cd }]; #IO_L17P_T2_A26_15 Sch=cd
#set_property -dict { PACKAGE_PIN P15 IOSTANDARD LVCMOS33 } [get_ports { ce }]; #IO_L13P_T2_MRCC_14 Sch=ce
#set_property -dict { PACKAGE_PIN T11 IOSTANDARD LVCMOS33 } [get_ports { cf }]; #IO_L19P_T3_A10_D26_14 Sch=cf
#set_property -dict { PACKAGE_PIN L18 IOSTANDARD LVCMOS33 } [get_ports { cg }]; #IO_L4P_T0_D04_14 Sch=cg
#set_property -dict { PACKAGE_PIN H15 IOSTANDARD LVCMOS33 } [get_ports { dp }]; #IO_L19N_T3_A21_VREF_15 Sch=dp
#set_property -dict { PACKAGE_PIN J17 IOSTANDARD LVCMOS33 } [get_ports { an[0] }]; #IO_L23P_T3_FOE_B_15 Sch=an[0]
#set_property -dict { PACKAGE_PIN J18 IOSTANDARD LVCMOS33 } [get_ports { an[1] }]; #IO_L23N_T3_FWE_B_15 Sch=an[1]
#set_property -dict { PACKAGE_PIN T9 IOSTANDARD LVCMOS33 } [get_ports { an[2] }]; #IO_L24P_T3_A01_D17_14 Sch=an[2]
#set_property -dict { PACKAGE_PIN J14 IOSTANDARD LVCMOS33 } [get_ports { an[3] }]; #IO_L19P_T3_A22_15 Sch=an[3]
#set_property -dict { PACKAGE_PIN P14 IOSTANDARD LVCMOS33 } [get_ports { an[4] }]; #IO_L8N_T1_D12_14 Sch=an[4]
#set_property -dict { PACKAGE_PIN T14 IOSTANDARD LVCMOS33 } [get_ports { an[5] }]; #IO_L14P_T2_SRCC_14 Sch=an[5]
#set_property -dict { PACKAGE_PIN K2 IOSTANDARD LVCMOS33 } [get_ports { an[6] }]; #IO_L23P_T3_35 Sch=an[6]
#set_property -dict { PACKAGE_PIN U13 IOSTANDARD LVCMOS33 } [get_ports { an[7] }]; #IO_L23N_T3_A02_D18_14 Sch=an[7]
##Buttons
#set_property -dict { PACKAGE_PIN C12 IOSTANDARD LVCMOS33 } [get_ports { cpu_resetn }]; #IO_L3P_T0_DQS_AD1P_15 Sch=cpu_resetn
#set_property -dict { PACKAGE_PIN N17 IOSTANDARD LVCMOS33 } [get_ports { btnc }]; #IO_L9P_T1_DQS_14 Sch=btnc
#set_property -dict { PACKAGE_PIN M18 IOSTANDARD LVCMOS33 } [get_ports { btnu }]; #IO_L4N_T0_D05_14 Sch=btnu
#set_property -dict { PACKAGE_PIN P17 IOSTANDARD LVCMOS33 } [get_ports { btnl }]; #IO_L12P_T1_MRCC_14 Sch=btnl
#set_property -dict { PACKAGE_PIN M17 IOSTANDARD LVCMOS33 } [get_ports { btnr }]; #IO_L10N_T1_D15_14 Sch=btnr
#set_property -dict { PACKAGE_PIN P18 IOSTANDARD LVCMOS33 } [get_ports { btnd }]; #IO_L9N_T1_DQS_D13_14 Sch=btnd
##Pmod Headers
##Pmod Header JA
#set_property -dict { PACKAGE_PIN C17 IOSTANDARD LVCMOS33 } [get_ports { ja[0] }]; #IO_L20N_T3_A19_15 Sch=ja[1]
#set_property -dict { PACKAGE_PIN D18 IOSTANDARD LVCMOS33 } [get_ports { ja[1] }]; #IO_L21N_T3_DQS_A18_15 Sch=ja[2]
#set_property -dict { PACKAGE_PIN E18 IOSTANDARD LVCMOS33 } [get_ports { ja[2] }]; #IO_L21P_T3_DQS_15 Sch=ja[3]
#set_property -dict { PACKAGE_PIN G17 IOSTANDARD LVCMOS33 } [get_ports { ja[3] }]; #IO_L18N_T2_A23_15 Sch=ja[4]
#set_property -dict { PACKAGE_PIN D17 IOSTANDARD LVCMOS33 } [get_ports { ja[4] }]; #IO_L16N_T2_A27_15 Sch=ja[7]
#set_property -dict { PACKAGE_PIN E17 IOSTANDARD LVCMOS33 } [get_ports { ja[5] }]; #IO_L16P_T2_A28_15 Sch=ja[8]
#set_property -dict { PACKAGE_PIN F18 IOSTANDARD LVCMOS33 } [get_ports { ja[6] }]; #IO_L22N_T3_A16_15 Sch=ja[9]
#set_property -dict { PACKAGE_PIN G18 IOSTANDARD LVCMOS33 } [get_ports { ja[7] }]; #IO_L22P_T3_A17_15 Sch=ja[10]
##Pmod Header JB
#set_property -dict { PACKAGE_PIN D14 IOSTANDARD LVCMOS33 } [get_ports { jb[0] }]; #IO_L1P_T0_AD0P_15 Sch=jb[1]
#set_property -dict { PACKAGE_PIN F16 IOSTANDARD LVCMOS33 } [get_ports { jb[1] }]; #IO_L14N_T2_SRCC_15 Sch=jb[2]
#set_property -dict { PACKAGE_PIN G16 IOSTANDARD LVCMOS33 } [get_ports { jb[2] }]; #IO_L13N_T2_MRCC_15 Sch=jb[3]
#set_property -dict { PACKAGE_PIN H14 IOSTANDARD LVCMOS33 } [get_ports { jb[3] }]; #IO_L15P_T2_DQS_15 Sch=jb[4]
#set_property -dict { PACKAGE_PIN E16 IOSTANDARD LVCMOS33 } [get_ports { jb[4] }]; #IO_L11N_T1_SRCC_15 Sch=jb[7]
#set_property -dict { PACKAGE_PIN F13 IOSTANDARD LVCMOS33 } [get_ports { jb[5] }]; #IO_L5P_T0_AD9P_15 Sch=jb[8]
#set_property -dict { PACKAGE_PIN G13 IOSTANDARD LVCMOS33 } [get_ports { jb[6] }]; #IO_0_15 Sch=jb[9]
#set_property -dict { PACKAGE_PIN H16 IOSTANDARD LVCMOS33 } [get_ports { jb[7] }]; #IO_L13P_T2_MRCC_15 Sch=jb[10]
##Pmod Header JC
#set_property -dict { PACKAGE_PIN K1 IOSTANDARD LVCMOS33 } [get_ports { jc[0] }]; #IO_L23N_T3_35 Sch=jc[1]
#set_property -dict { PACKAGE_PIN F6 IOSTANDARD LVCMOS33 } [get_ports { jc[1] }]; #IO_L19N_T3_VREF_35 Sch=jc[2]
#set_property -dict { PACKAGE_PIN J2 IOSTANDARD LVCMOS33 } [get_ports { jc[2] }]; #IO_L22N_T3_35 Sch=jc[3]
#set_property -dict { PACKAGE_PIN G6 IOSTANDARD LVCMOS33 } [get_ports { jc[3] }]; #IO_L19P_T3_35 Sch=jc[4]
#set_property -dict { PACKAGE_PIN E7 IOSTANDARD LVCMOS33 } [get_ports { jc[4] }]; #IO_L6P_T0_35 Sch=jc[7]
#set_property -dict { PACKAGE_PIN J3 IOSTANDARD LVCMOS33 } [get_ports { jc[5] }]; #IO_L22P_T3_35 Sch=jc[8]
#set_property -dict { PACKAGE_PIN J4 IOSTANDARD LVCMOS33 } [get_ports { jc[6] }]; #IO_L21P_T3_DQS_35 Sch=jc[9]
#set_property -dict { PACKAGE_PIN E6 IOSTANDARD LVCMOS33 } [get_ports { jc[7] }]; #IO_L5P_T0_AD13P_35 Sch=jc[10]
##Pmod Header JD
#set_property -dict { PACKAGE_PIN H4 IOSTANDARD LVCMOS33 } [get_ports { jd[0] }]; #IO_L21N_T3_DQS_35 Sch=jd[1]
#set_property -dict { PACKAGE_PIN H1 IOSTANDARD LVCMOS33 } [get_ports { jd[1] }]; #IO_L17P_T2_35 Sch=jd[2]
#set_property -dict { PACKAGE_PIN G1 IOSTANDARD LVCMOS33 } [get_ports { jd[2] }]; #IO_L17N_T2_35 Sch=jd[3]
#set_property -dict { PACKAGE_PIN G3 IOSTANDARD LVCMOS33 } [get_ports { jd[3] }]; #IO_L20N_T3_35 Sch=jd[4]
#set_property -dict { PACKAGE_PIN H2 IOSTANDARD LVCMOS33 } [get_ports { jd[4] }]; #IO_L15P_T2_DQS_35 Sch=jd[7]
#set_property -dict { PACKAGE_PIN G4 IOSTANDARD LVCMOS33 } [get_ports { jd[5] }]; #IO_L20P_T3_35 Sch=jd[8]
#set_property -dict { PACKAGE_PIN G2 IOSTANDARD LVCMOS33 } [get_ports { jd[6] }]; #IO_L15N_T2_DQS_35 Sch=jd[9]
#set_property -dict { PACKAGE_PIN F3 IOSTANDARD LVCMOS33 } [get_ports { jd[7] }]; #IO_L13N_T2_MRCC_35 Sch=jd[10]
##Pmod Header JXADC
#set_property -dict { PACKAGE_PIN A14 IOSTANDARD LVDS } [get_ports { xa_n[0] }]; #IO_L9N_T1_DQS_AD3N_15 Sch=xa_n[1]
#set_property -dict { PACKAGE_PIN A13 IOSTANDARD LVDS } [get_ports { xa_p[0] }]; #IO_L9P_T1_DQS_AD3P_15 Sch=xa_p[1]
#set_property -dict { PACKAGE_PIN A16 IOSTANDARD LVDS } [get_ports { xa_n[1] }]; #IO_L8N_T1_AD10N_15 Sch=xa_n[2]
#set_property -dict { PACKAGE_PIN A15 IOSTANDARD LVDS } [get_ports { xa_p[1] }]; #IO_L8P_T1_AD10P_15 Sch=xa_p[2]
#set_property -dict { PACKAGE_PIN B17 IOSTANDARD LVDS } [get_ports { xa_n[2] }]; #IO_L7N_T1_AD2N_15 Sch=xa_n[3]
#set_property -dict { PACKAGE_PIN B16 IOSTANDARD LVDS } [get_ports { xa_p[2] }]; #IO_L7P_T1_AD2P_15 Sch=xa_p[3]
#set_property -dict { PACKAGE_PIN A18 IOSTANDARD LVDS } [get_ports { xa_n[3] }]; #IO_L10N_T1_AD11N_15 Sch=xa_n[4]
#set_property -dict { PACKAGE_PIN B18 IOSTANDARD LVDS } [get_ports { xa_p[3] }]; #IO_L10P_T1_AD11P_15 Sch=xa_p[4]
##VGA Connector
#set_property -dict { PACKAGE_PIN A3 IOSTANDARD LVCMOS33 } [get_ports { vga_r[0] }]; #IO_L8N_T1_AD14N_35 Sch=vga_r[0]
#set_property -dict { PACKAGE_PIN B4 IOSTANDARD LVCMOS33 } [get_ports { vga_r[1] }]; #IO_L7N_T1_AD6N_35 Sch=vga_r[1]
#set_property -dict { PACKAGE_PIN C5 IOSTANDARD LVCMOS33 } [get_ports { vga_r[2] }]; #IO_L1N_T0_AD4N_35 Sch=vga_r[2]
#set_property -dict { PACKAGE_PIN A4 IOSTANDARD LVCMOS33 } [get_ports { vga_r[3] }]; #IO_L8P_T1_AD14P_35 Sch=vga_r[3]
#
#set_property -dict { PACKAGE_PIN C6 IOSTANDARD LVCMOS33 } [get_ports { vga_g[0] }]; #IO_L1P_T0_AD4P_35 Sch=vga_g[0]
#set_property -dict { PACKAGE_PIN A5 IOSTANDARD LVCMOS33 } [get_ports { vga_g[1] }]; #IO_L3N_T0_DQS_AD5N_35 Sch=vga_g[1]
#set_property -dict { PACKAGE_PIN B6 IOSTANDARD LVCMOS33 } [get_ports { vga_g[2] }]; #IO_L2N_T0_AD12N_35 Sch=vga_g[2]
#set_property -dict { PACKAGE_PIN A6 IOSTANDARD LVCMOS33 } [get_ports { vga_g[3] }]; #IO_L3P_T0_DQS_AD5P_35 Sch=vga_g[3]
#
#set_property -dict { PACKAGE_PIN B7 IOSTANDARD LVCMOS33 } [get_ports { vga_b[0] }]; #IO_L2P_T0_AD12P_35 Sch=vga_b[0]
#set_property -dict { PACKAGE_PIN C7 IOSTANDARD LVCMOS33 } [get_ports { vga_b[1] }]; #IO_L4N_T0_35 Sch=vga_b[1]
#set_property -dict { PACKAGE_PIN D7 IOSTANDARD LVCMOS33 } [get_ports { vga_b[2] }]; #IO_L6N_T0_VREF_35 Sch=vga_b[2]
#set_property -dict { PACKAGE_PIN D8 IOSTANDARD LVCMOS33 } [get_ports { vga_b[3] }]; #IO_L4P_T0_35 Sch=vga_b[3]
#set_property -dict { PACKAGE_PIN B11 IOSTANDARD LVCMOS33 } [get_ports { vga_hs }]; #IO_L4P_T0_15 Sch=vga_hs
#set_property -dict { PACKAGE_PIN B12 IOSTANDARD LVCMOS33 } [get_ports { vga_vs }]; #IO_L3N_T0_DQS_AD1N_15 Sch=vga_vs
##Micro SD Connector
#set_property -dict { PACKAGE_PIN E2 IOSTANDARD LVCMOS33 } [get_ports { sd_reset }]; #IO_L14P_T2_SRCC_35 Sch=sd_reset
#set_property -dict { PACKAGE_PIN A1 IOSTANDARD LVCMOS33 } [get_ports { sd_cd }]; #IO_L9N_T1_DQS_AD7N_35 Sch=sd_cd
#set_property -dict { PACKAGE_PIN B1 IOSTANDARD LVCMOS33 } [get_ports { sd_sck }]; #IO_L9P_T1_DQS_AD7P_35 Sch=sd_sck
#set_property -dict { PACKAGE_PIN C1 IOSTANDARD LVCMOS33 } [get_ports { sd_cmd }]; #IO_L16N_T2_35 Sch=sd_cmd
#set_property -dict { PACKAGE_PIN C2 IOSTANDARD LVCMOS33 } [get_ports { sd_dat[0] }]; #IO_L16P_T2_35 Sch=sd_dat[0]
#set_property -dict { PACKAGE_PIN E1 IOSTANDARD LVCMOS33 } [get_ports { sd_dat[1] }]; #IO_L18N_T2_35 Sch=sd_dat[1]
#set_property -dict { PACKAGE_PIN F1 IOSTANDARD LVCMOS33 } [get_ports { sd_dat[2] }]; #IO_L18P_T2_35 Sch=sd_dat[2]
#set_property -dict { PACKAGE_PIN D2 IOSTANDARD LVCMOS33 } [get_ports { sd_dat[3] }]; #IO_L14N_T2_SRCC_35 Sch=sd_dat[3]
##Accelerometer
#set_property -dict { PACKAGE_PIN E15 IOSTANDARD LVCMOS33 } [get_ports { acl_miso }]; #IO_L11P_T1_SRCC_15 Sch=acl_miso
#set_property -dict { PACKAGE_PIN F14 IOSTANDARD LVCMOS33 } [get_ports { acl_mosi }]; #IO_L5N_T0_AD9N_15 Sch=acl_mosi
#set_property -dict { PACKAGE_PIN F15 IOSTANDARD LVCMOS33 } [get_ports { acl_sclk }]; #IO_L14P_T2_SRCC_15 Sch=acl_sclk
#set_property -dict { PACKAGE_PIN D15 IOSTANDARD LVCMOS33 } [get_ports { acl_csn }]; #IO_L12P_T1_MRCC_15 Sch=acl_csn
#set_property -dict { PACKAGE_PIN B13 IOSTANDARD LVCMOS33 } [get_ports { acl_int[1] }]; #IO_L2P_T0_AD8P_15 Sch=acl_int[1]
#set_property -dict { PACKAGE_PIN C16 IOSTANDARD LVCMOS33 } [get_ports { acl_int[2] }]; #IO_L20P_T3_A20_15 Sch=acl_int[2]
##Temperature Sensor
#set_property -dict { PACKAGE_PIN C14 IOSTANDARD LVCMOS33 } [get_ports { tmp_scl }]; #IO_L1N_T0_AD0N_15 Sch=tmp_scl
#set_property -dict { PACKAGE_PIN C15 IOSTANDARD LVCMOS33 } [get_ports { tmp_sda }]; #IO_L12N_T1_MRCC_15 Sch=tmp_sda
#set_property -dict { PACKAGE_PIN D13 IOSTANDARD LVCMOS33 } [get_ports { tmp_int }]; #IO_L6N_T0_VREF_15 Sch=tmp_int
#set_property -dict { PACKAGE_PIN B14 IOSTANDARD LVCMOS33 } [get_ports { tmp_ct }]; #IO_L2N_T0_AD8N_15 Sch=tmp_ct
##Omnidirectional Microphone
#set_property -dict { PACKAGE_PIN J5 IOSTANDARD LVCMOS33 } [get_ports { m_clk }]; #IO_25_35 Sch=m_clk
#set_property -dict { PACKAGE_PIN H5 IOSTANDARD LVCMOS33 } [get_ports { m_data }]; #IO_L24N_T3_35 Sch=m_data
#set_property -dict { PACKAGE_PIN F5 IOSTANDARD LVCMOS33 } [get_ports { m_lrsel }]; #IO_0_35 Sch=m_lrsel
##PWM Audio Amplifier
#set_property -dict { PACKAGE_PIN A11 IOSTANDARD LVCMOS33 } [get_ports { aud_pwm }]; #IO_L4N_T0_15 Sch=aud_pwm
#set_property -dict { PACKAGE_PIN D12 IOSTANDARD LVCMOS33 } [get_ports { aud_sd }]; #IO_L6P_T0_15 Sch=aud_sd
##USB-RS232 Interface
set_property -dict { PACKAGE_PIN C4 IOSTANDARD LVCMOS33 } [get_ports { uart_txd_in }]; #IO_L7P_T1_AD6P_35 Sch=uart_txd_in
set_property -dict { PACKAGE_PIN D4 IOSTANDARD LVCMOS33 } [get_ports { uart_rxd_out }]; #IO_L11N_T1_SRCC_35 Sch=uart_rxd_out
#set_property -dict { PACKAGE_PIN D3 IOSTANDARD LVCMOS33 } [get_ports { uart_cts }]; #IO_L12N_T1_MRCC_35 Sch=uart_cts
#set_property -dict { PACKAGE_PIN E5 IOSTANDARD LVCMOS33 } [get_ports { uart_rts }]; #IO_L5N_T0_AD13N_35 Sch=uart_rts
##USB HID (PS/2)
#set_property -dict { PACKAGE_PIN F4 IOSTANDARD LVCMOS33 } [get_ports { ps2_clk }]; #IO_L13P_T2_MRCC_35 Sch=ps2_clk
#set_property -dict { PACKAGE_PIN B2 IOSTANDARD LVCMOS33 } [get_ports { ps2_data }]; #IO_L10N_T1_AD15N_35 Sch=ps2_data
##SMSC Ethernet PHY
#set_property -dict { PACKAGE_PIN C9 IOSTANDARD LVCMOS33 } [get_ports { eth_mdc }]; #IO_L11P_T1_SRCC_16 Sch=eth_mdc
#set_property -dict { PACKAGE_PIN A9 IOSTANDARD LVCMOS33 } [get_ports { eth_mdio }]; #IO_L14N_T2_SRCC_16 Sch=eth_mdio
#set_property -dict { PACKAGE_PIN B3 IOSTANDARD LVCMOS33 } [get_ports { eth_rstn }]; #IO_L10P_T1_AD15P_35 Sch=eth_rstn
#set_property -dict { PACKAGE_PIN D9 IOSTANDARD LVCMOS33 } [get_ports { eth_crsdv }]; #IO_L6N_T0_VREF_16 Sch=eth_crs/udv
#set_property -dict { PACKAGE_PIN C10 IOSTANDARD LVCMOS33 } [get_ports { eth_rxerr }]; #IO_L13N_T2_MRCC_16 Sch=eth_rxerr
#set_property -dict { PACKAGE_PIN C11 IOSTANDARD LVCMOS33 } [get_ports { eth_rxd[0] }]; #IO_L13P_T2_MRCC_16 Sch=eth_rxd[0]
#set_property -dict { PACKAGE_PIN D10 IOSTANDARD LVCMOS33 } [get_ports { eth_rxd[1] }]; #IO_L19N_T3_VREF_16 Sch=eth_rxd[1]
#set_property -dict { PACKAGE_PIN B9 IOSTANDARD LVCMOS33 } [get_ports { eth_txen }]; #IO_L11N_T1_SRCC_16 Sch=eth_txen
#set_property -dict { PACKAGE_PIN A10 IOSTANDARD LVCMOS33 } [get_ports { eth_txd[0] }]; #IO_L14P_T2_SRCC_16 Sch=eth_txd[0]
#set_property -dict { PACKAGE_PIN A8 IOSTANDARD LVCMOS33 } [get_ports { eth_txd[1] }]; #IO_L12N_T1_MRCC_16 Sch=eth_txd[1]
#set_property -dict { PACKAGE_PIN D5 IOSTANDARD LVCMOS33 } [get_ports { eth_refclk }]; #IO_L11P_T1_SRCC_35 Sch=eth_refclk
#set_property -dict { PACKAGE_PIN B8 IOSTANDARD LVCMOS33 } [get_ports { eth_intn }]; #IO_L12P_T1_MRCC_16 Sch=eth_intn
##Quad SPI Flash
#set_property -dict { PACKAGE_PIN K17 IOSTANDARD LVCMOS33 } [get_ports { qspi_dq[0] }]; #IO_L1P_T0_D00_MOSI_14 Sch=qspi_dq[0]
#set_property -dict { PACKAGE_PIN K18 IOSTANDARD LVCMOS33 } [get_ports { qspi_dq[1] }]; #IO_L1N_T0_D01_DIN_14 Sch=qspi_dq[1]
#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

View File

@ -1,20 +0,0 @@
---
cores:
my_logic_analyzer:
type: logic_analyzer
sample_depth: 1024
probes:
spike: 1
jet: 2
valentine: 3
ed: 4
ein: 5
triggers:
- ein EQ 3
uart:
port: "auto"
baudrate: 115200
clock_freq: 100000000

View File

@ -1,58 +0,0 @@
/*
This playback module was generated with Manta v0.0.5 on 23 Aug 2023 at 11:25:46 by fischerm
If this breaks or if you've got dank formal verification memes, contact fischerm [at] mit.edu
Provided under a GNU GPLv3 license. Go wild.
Here's an example instantiation of the Manta module you configured, feel free to copy-paste
this into your source!
my_logic_analyzer_playback #(.MEM_FILE("capture.mem")) my_logic_analyzer_playback_inst (
.clk(clk),
.enable(1'b1),
.spike(spike),
.jet(jet),
.valentine(valentine),
.ed(ed),
.ein(ein));
*/
module my_logic_analyzer_playback (
input wire clk,
input wire enable,
output reg done,
output reg spike,
output reg [1:0] jet,
output reg [2:0] valentine,
output reg [3:0] ed,
output reg [4:0] ein);
parameter MEM_FILE = "";
localparam SAMPLE_DEPTH = 1024;
localparam TOTAL_PROBE_WIDTH = 15;
reg [TOTAL_PROBE_WIDTH-1:0] capture [SAMPLE_DEPTH-1:0];
reg [$clog2(SAMPLE_DEPTH)-1:0] addr;
reg [TOTAL_PROBE_WIDTH-1:0] sample;
assign done = (addr >= SAMPLE_DEPTH);
initial begin
$readmemb(MEM_FILE, capture, 0, SAMPLE_DEPTH-1);
addr = 0;
end
always @(posedge clk) begin
if (enable && !done) begin
addr = addr + 1;
sample = capture[addr];
{ein, ed, valentine, jet, spike} = sample;
end
end
endmodule

View File

@ -1,38 +0,0 @@
`default_nettype none
`timescale 1ns/1ps
module playback_tb();
logic clk;
always begin
#5;
clk = !clk;
end
logic spike;
logic [1:0] jet;
logic [2:0] valentine;
logic [3:0] ed;
logic [4:0] ein;
my_logic_analyzer_playback #(.MEM_FILE("capture.mem")) my_logic_analyzer_playback_inst (
.clk(clk),
.enable(1'b1),
.spike(spike),
.jet(jet),
.valentine(valentine),
.ed(ed),
.ein(ein));
initial begin
clk = 0;
$dumpfile("playback_tb.vcd");
$dumpvars(0, playback_tb);
#(450000*5);
$finish();
end
endmodule
`default_nettype wire

View File

@ -1,28 +0,0 @@
`default_nettype none
`timescale 1ns / 1ps
module top_level (
input wire clk,
input wire uart_txd_in,
output logic uart_rxd_out
);
logic [4:0] counter = 0;
always @(posedge clk) counter <= counter + 1;
manta manta_inst (
.clk(clk),
.rx(uart_txd_in),
.tx(uart_rxd_out),
.spike(counter[0]),
.jet(counter[1:0]),
.valentine(counter[2:0]),
.ed(counter[3:0]),
.ein(counter));
endmodule
`default_nettype wire

View File

@ -1,18 +0,0 @@
---
cores:
my_logic_analyzer:
type: logic_analyzer
sample_depth: 64000
trigger_location: 15000
probes:
ps2_clk: 1
ps2_data: 1
triggers:
- ps2_data FALLING
uart:
port: "auto"
baudrate: 115200
clock_freq: 50000000

View File

@ -1,52 +0,0 @@
/*
This playback module was generated with Manta v0.0.5 on 19 Jul 2023 at 18:52:11 by fischerm
If this breaks or if you've got dank formal verification memes, contact fischerm [at] mit.edu
Provided under a GNU GPLv3 license. Go wild.
Here's an example instantiation of the Manta module you configured, feel free to copy-paste
this into your source!
my_logic_analyzer_playback #(.MEM_FILE("capture.mem")) my_logic_analyzer_playback_inst (
.clk(clk),
.enable(1'b1),
.ps2_clk(ps2_clk),
.ps2_data(ps2_data));
*/
module my_logic_analyzer_playback (
input wire clk,
input wire enable,
output reg done,
output reg ps2_clk,
output reg ps2_data);
parameter MEM_FILE = "";
localparam SAMPLE_DEPTH = 64000;
localparam TOTAL_PROBE_WIDTH = 2;
reg [TOTAL_PROBE_WIDTH-1:0] capture [SAMPLE_DEPTH-1:0];
reg [$clog2(SAMPLE_DEPTH)-1:0] addr;
reg [TOTAL_PROBE_WIDTH-1:0] sample;
assign done = (addr >= SAMPLE_DEPTH);
initial begin
$readmemb(MEM_FILE, capture, 0, SAMPLE_DEPTH-1);
addr = 0;
end
always @(posedge clk) begin
if (enable && !done) begin
addr = addr + 1;
sample = capture[addr];
{ps2_data, ps2_clk} = sample;
end
end
endmodule

View File

@ -1,80 +0,0 @@
`default_nettype none
`timescale 1ns/1ps
module ps2_decoder(
input wire clk,
input wire ps2_clk,
input wire ps2_data,
output logic [7:0] data
);
reg prev_clk;
reg [10:0] buffer = 0;
reg [3:0] counter = 0;
always @(posedge clk) begin
prev_clk <= ps2_clk;
if (!prev_clk && ps2_clk) begin
buffer <= {buffer[9:0], ps2_data};
counter <= counter + 1;
end
if (counter == 11) begin
if (!buffer[10] && buffer[0]) begin
counter <= 0;
data <= {buffer[2], buffer[3], buffer[4], buffer[5], buffer[6], buffer[7], buffer[8], buffer[9]};
end
end
end
endmodule
module playback_tb();
logic clk;
always begin
#5;
clk = !clk;
end
logic ps2_clk;
logic ps2_data;
my_logic_analyzer_playback #(.MEM_FILE("capture.mem")) my_logic_analyzer_playback_inst (
.clk(clk),
.enable(1'b1),
.ps2_clk(ps2_clk),
.ps2_data(ps2_data));
logic [7:0] data;
ps2_decoder decoder(
.clk(clk),
.ps2_clk(ps2_clk),
.ps2_data(ps2_data),
.data(data)
);
initial begin
clk = 0;
$dumpfile("playback_tb.vcd");
$dumpvars(0, playback_tb);
#(450000*5);
$finish();
end
endmodule
`default_nettype wire

View File

@ -1,25 +0,0 @@
`default_nettype none
`timescale 1ns / 1ps
module top_level (
input wire clk,
input wire ps2_clk,
input wire ps2_data,
input wire uart_txd_in,
output logic uart_rxd_out
);
manta manta_inst (
.clk(clk),
.rx(uart_txd_in),
.tx(uart_rxd_out),
.ps2_clk(ps2_clk),
.ps2_data(ps2_data));
endmodule
`default_nettype wire

View File

@ -1,254 +0,0 @@
## This file is a general .xdc for the Nexys4 DDR Rev. C
## To use it in a project:
## - uncomment the lines corresponding to used pins
## - rename the used ports (in each line, after get_ports) according to the top level signal names in the project
## This file has been modified from the default .xdc provided by Digilent for the Nexys A7
## Clock signal - uncomment _both_ of these lines to create clk_100mhz
set_property -dict { PACKAGE_PIN E3 IOSTANDARD LVCMOS33 } [get_ports { clk }]; #IO_L12P_T1_MRCC_35 Sch=clk
create_clock -add -name sys_clk_pin -period 10.00 -waveform {0 5} [get_ports {clk}];
##Switches
#set_property -dict { PACKAGE_PIN J15 IOSTANDARD LVCMOS33 } [get_ports { sw[0] }]; #IO_L24N_T3_RS0_15 Sch=sw[0]
#set_property -dict { PACKAGE_PIN L16 IOSTANDARD LVCMOS33 } [get_ports { sw[1] }]; #IO_L3N_T0_DQS_EMCCLK_14 Sch=sw[1]
#set_property -dict { PACKAGE_PIN M13 IOSTANDARD LVCMOS33 } [get_ports { sw[2] }]; #IO_L6N_T0_D08_VREF_14 Sch=sw[2]
#set_property -dict { PACKAGE_PIN R15 IOSTANDARD LVCMOS33 } [get_ports { sw[3] }]; #IO_L13N_T2_MRCC_14 Sch=sw[3]
#set_property -dict { PACKAGE_PIN R17 IOSTANDARD LVCMOS33 } [get_ports { sw[4] }]; #IO_L12N_T1_MRCC_14 Sch=sw[4]
#set_property -dict { PACKAGE_PIN T18 IOSTANDARD LVCMOS33 } [get_ports { sw[5] }]; #IO_L7N_T1_D10_14 Sch=sw[5]
#set_property -dict { PACKAGE_PIN U18 IOSTANDARD LVCMOS33 } [get_ports { sw[6] }]; #IO_L17N_T2_A13_D29_14 Sch=sw[6]
#set_property -dict { PACKAGE_PIN R13 IOSTANDARD LVCMOS33 } [get_ports { sw[7] }]; #IO_L5N_T0_D07_14 Sch=sw[7]
#set_property -dict { PACKAGE_PIN T8 IOSTANDARD LVCMOS18 } [get_ports { sw[8] }]; #IO_L24N_T3_34 Sch=sw[8]
#set_property -dict { PACKAGE_PIN U8 IOSTANDARD LVCMOS18 } [get_ports { sw[9] }]; #IO_25_34 Sch=sw[9]
#set_property -dict { PACKAGE_PIN R16 IOSTANDARD LVCMOS33 } [get_ports { sw[10] }]; #IO_L15P_T2_DQS_RDWR_B_14 Sch=sw[10]
#set_property -dict { PACKAGE_PIN T13 IOSTANDARD LVCMOS33 } [get_ports { sw[11] }]; #IO_L23P_T3_A03_D19_14 Sch=sw[11]
#set_property -dict { PACKAGE_PIN H6 IOSTANDARD LVCMOS33 } [get_ports { sw[12] }]; #IO_L24P_T3_35 Sch=sw[12]
#set_property -dict { PACKAGE_PIN U12 IOSTANDARD LVCMOS33 } [get_ports { sw[13] }]; #IO_L20P_T3_A08_D24_14 Sch=sw[13]
#set_property -dict { PACKAGE_PIN U11 IOSTANDARD LVCMOS33 } [get_ports { sw[14] }]; #IO_L19N_T3_A09_D25_VREF_14 Sch=sw[14]
#set_property -dict { PACKAGE_PIN V10 IOSTANDARD LVCMOS33 } [get_ports { sw[15] }]; #IO_L21P_T3_DQS_14 Sch=sw[15]
## LEDs
#set_property -dict { PACKAGE_PIN H17 IOSTANDARD LVCMOS33 } [get_ports { led[0] }]; #IO_L18P_T2_A24_15 Sch=led[0]
#set_property -dict { PACKAGE_PIN K15 IOSTANDARD LVCMOS33 } [get_ports { led[1] }]; #IO_L24P_T3_RS1_15 Sch=led[1]
#set_property -dict { PACKAGE_PIN J13 IOSTANDARD LVCMOS33 } [get_ports { led[2] }]; #IO_L17N_T2_A25_15 Sch=led[2]
#set_property -dict { PACKAGE_PIN N14 IOSTANDARD LVCMOS33 } [get_ports { led[3] }]; #IO_L8P_T1_D11_14 Sch=led[3]
#set_property -dict { PACKAGE_PIN R18 IOSTANDARD LVCMOS33 } [get_ports { led[4] }]; #IO_L7P_T1_D09_14 Sch=led[4]
#set_property -dict { PACKAGE_PIN V17 IOSTANDARD LVCMOS33 } [get_ports { led[5] }]; #IO_L18N_T2_A11_D27_14 Sch=led[5]
#set_property -dict { PACKAGE_PIN U17 IOSTANDARD LVCMOS33 } [get_ports { led[6] }]; #IO_L17P_T2_A14_D30_14 Sch=led[6]
#set_property -dict { PACKAGE_PIN U16 IOSTANDARD LVCMOS33 } [get_ports { led[7] }]; #IO_L18P_T2_A12_D28_14 Sch=led[7]
#set_property -dict { PACKAGE_PIN V16 IOSTANDARD LVCMOS33 } [get_ports { led[8] }]; #IO_L16N_T2_A15_D31_14 Sch=led[8]
#set_property -dict { PACKAGE_PIN T15 IOSTANDARD LVCMOS33 } [get_ports { led[9] }]; #IO_L14N_T2_SRCC_14 Sch=led[9]
#set_property -dict { PACKAGE_PIN U14 IOSTANDARD LVCMOS33 } [get_ports { led[10] }]; #IO_L22P_T3_A05_D21_14 Sch=led[10]
#set_property -dict { PACKAGE_PIN T16 IOSTANDARD LVCMOS33 } [get_ports { led[11] }]; #IO_L15N_T2_DQS_DOUT_CSO_B_14 Sch=led[11]
#set_property -dict { PACKAGE_PIN V15 IOSTANDARD LVCMOS33 } [get_ports { led[12] }]; #IO_L16P_T2_CSI_B_14 Sch=led[12]
#set_property -dict { PACKAGE_PIN V14 IOSTANDARD LVCMOS33 } [get_ports { led[13] }]; #IO_L22N_T3_A04_D20_14 Sch=led[13]
#set_property -dict { PACKAGE_PIN V12 IOSTANDARD LVCMOS33 } [get_ports { led[14] }]; #IO_L20N_T3_A07_D23_14 Sch=led[14]
#set_property -dict { PACKAGE_PIN V11 IOSTANDARD LVCMOS33 } [get_ports { led[15] }]; #IO_L21N_T3_DQS_A06_D22_14 Sch=led[15]
#set_property -dict { PACKAGE_PIN R12 IOSTANDARD LVCMOS33 } [get_ports { led16_b }]; #IO_L5P_T0_D06_14 Sch=led16_b
#set_property -dict { PACKAGE_PIN M16 IOSTANDARD LVCMOS33 } [get_ports { led16_g }]; #IO_L10P_T1_D14_14 Sch=led16_g
#set_property -dict { PACKAGE_PIN N15 IOSTANDARD LVCMOS33 } [get_ports { led16_r }]; #IO_L11P_T1_SRCC_14 Sch=led16_r
#set_property -dict { PACKAGE_PIN G14 IOSTANDARD LVCMOS33 } [get_ports { led17_b }]; #IO_L15N_T2_DQS_ADV_B_15 Sch=led17_b
#set_property -dict { PACKAGE_PIN R11 IOSTANDARD LVCMOS33 } [get_ports { led17_g }]; #IO_0_14 Sch=led17_g
#set_property -dict { PACKAGE_PIN N16 IOSTANDARD LVCMOS33 } [get_ports { led17_r }]; #IO_L11N_T1_SRCC_14 Sch=led17_r
##7 segment display
#set_property -dict { PACKAGE_PIN T10 IOSTANDARD LVCMOS33 } [get_ports { ca }]; #IO_L24N_T3_A00_D16_14 Sch=ca
#set_property -dict { PACKAGE_PIN R10 IOSTANDARD LVCMOS33 } [get_ports { cb }]; #IO_25_14 Sch=cb
#set_property -dict { PACKAGE_PIN K16 IOSTANDARD LVCMOS33 } [get_ports { cc }]; #IO_25_15 Sch=cc
#set_property -dict { PACKAGE_PIN K13 IOSTANDARD LVCMOS33 } [get_ports { cd }]; #IO_L17P_T2_A26_15 Sch=cd
#set_property -dict { PACKAGE_PIN P15 IOSTANDARD LVCMOS33 } [get_ports { ce }]; #IO_L13P_T2_MRCC_14 Sch=ce
#set_property -dict { PACKAGE_PIN T11 IOSTANDARD LVCMOS33 } [get_ports { cf }]; #IO_L19P_T3_A10_D26_14 Sch=cf
#set_property -dict { PACKAGE_PIN L18 IOSTANDARD LVCMOS33 } [get_ports { cg }]; #IO_L4P_T0_D04_14 Sch=cg
#set_property -dict { PACKAGE_PIN H15 IOSTANDARD LVCMOS33 } [get_ports { dp }]; #IO_L19N_T3_A21_VREF_15 Sch=dp
#set_property -dict { PACKAGE_PIN J17 IOSTANDARD LVCMOS33 } [get_ports { an[0] }]; #IO_L23P_T3_FOE_B_15 Sch=an[0]
#set_property -dict { PACKAGE_PIN J18 IOSTANDARD LVCMOS33 } [get_ports { an[1] }]; #IO_L23N_T3_FWE_B_15 Sch=an[1]
#set_property -dict { PACKAGE_PIN T9 IOSTANDARD LVCMOS33 } [get_ports { an[2] }]; #IO_L24P_T3_A01_D17_14 Sch=an[2]
#set_property -dict { PACKAGE_PIN J14 IOSTANDARD LVCMOS33 } [get_ports { an[3] }]; #IO_L19P_T3_A22_15 Sch=an[3]
#set_property -dict { PACKAGE_PIN P14 IOSTANDARD LVCMOS33 } [get_ports { an[4] }]; #IO_L8N_T1_D12_14 Sch=an[4]
#set_property -dict { PACKAGE_PIN T14 IOSTANDARD LVCMOS33 } [get_ports { an[5] }]; #IO_L14P_T2_SRCC_14 Sch=an[5]
#set_property -dict { PACKAGE_PIN K2 IOSTANDARD LVCMOS33 } [get_ports { an[6] }]; #IO_L23P_T3_35 Sch=an[6]
#set_property -dict { PACKAGE_PIN U13 IOSTANDARD LVCMOS33 } [get_ports { an[7] }]; #IO_L23N_T3_A02_D18_14 Sch=an[7]
##Buttons
#set_property -dict { PACKAGE_PIN C12 IOSTANDARD LVCMOS33 } [get_ports { cpu_resetn }]; #IO_L3P_T0_DQS_AD1P_15 Sch=cpu_resetn
#set_property -dict { PACKAGE_PIN N17 IOSTANDARD LVCMOS33 } [get_ports { btnc }]; #IO_L9P_T1_DQS_14 Sch=btnc
#set_property -dict { PACKAGE_PIN M18 IOSTANDARD LVCMOS33 } [get_ports { btnu }]; #IO_L4N_T0_D05_14 Sch=btnu
#set_property -dict { PACKAGE_PIN P17 IOSTANDARD LVCMOS33 } [get_ports { btnl }]; #IO_L12P_T1_MRCC_14 Sch=btnl
#set_property -dict { PACKAGE_PIN M17 IOSTANDARD LVCMOS33 } [get_ports { btnr }]; #IO_L10N_T1_D15_14 Sch=btnr
#set_property -dict { PACKAGE_PIN P18 IOSTANDARD LVCMOS33 } [get_ports { btnd }]; #IO_L9N_T1_DQS_D13_14 Sch=btnd
##Pmod Headers
##Pmod Header JA
#set_property -dict { PACKAGE_PIN C17 IOSTANDARD LVCMOS33 } [get_ports { ja[0] }]; #IO_L20N_T3_A19_15 Sch=ja[1]
#set_property -dict { PACKAGE_PIN D18 IOSTANDARD LVCMOS33 } [get_ports { ja[1] }]; #IO_L21N_T3_DQS_A18_15 Sch=ja[2]
#set_property -dict { PACKAGE_PIN E18 IOSTANDARD LVCMOS33 } [get_ports { ja[2] }]; #IO_L21P_T3_DQS_15 Sch=ja[3]
#set_property -dict { PACKAGE_PIN G17 IOSTANDARD LVCMOS33 } [get_ports { ja[3] }]; #IO_L18N_T2_A23_15 Sch=ja[4]
#set_property -dict { PACKAGE_PIN D17 IOSTANDARD LVCMOS33 } [get_ports { ja[4] }]; #IO_L16N_T2_A27_15 Sch=ja[7]
#set_property -dict { PACKAGE_PIN E17 IOSTANDARD LVCMOS33 } [get_ports { ja[5] }]; #IO_L16P_T2_A28_15 Sch=ja[8]
#set_property -dict { PACKAGE_PIN F18 IOSTANDARD LVCMOS33 } [get_ports { ja[6] }]; #IO_L22N_T3_A16_15 Sch=ja[9]
#set_property -dict { PACKAGE_PIN G18 IOSTANDARD LVCMOS33 } [get_ports { ja[7] }]; #IO_L22P_T3_A17_15 Sch=ja[10]
##Pmod Header JB
#set_property -dict { PACKAGE_PIN D14 IOSTANDARD LVCMOS33 } [get_ports { jb[0] }]; #IO_L1P_T0_AD0P_15 Sch=jb[1]
#set_property -dict { PACKAGE_PIN F16 IOSTANDARD LVCMOS33 } [get_ports { jb[1] }]; #IO_L14N_T2_SRCC_15 Sch=jb[2]
#set_property -dict { PACKAGE_PIN G16 IOSTANDARD LVCMOS33 } [get_ports { jb[2] }]; #IO_L13N_T2_MRCC_15 Sch=jb[3]
#set_property -dict { PACKAGE_PIN H14 IOSTANDARD LVCMOS33 } [get_ports { jb[3] }]; #IO_L15P_T2_DQS_15 Sch=jb[4]
#set_property -dict { PACKAGE_PIN E16 IOSTANDARD LVCMOS33 } [get_ports { jb[4] }]; #IO_L11N_T1_SRCC_15 Sch=jb[7]
#set_property -dict { PACKAGE_PIN F13 IOSTANDARD LVCMOS33 } [get_ports { jb[5] }]; #IO_L5P_T0_AD9P_15 Sch=jb[8]
#set_property -dict { PACKAGE_PIN G13 IOSTANDARD LVCMOS33 } [get_ports { jb[6] }]; #IO_0_15 Sch=jb[9]
#set_property -dict { PACKAGE_PIN H16 IOSTANDARD LVCMOS33 } [get_ports { jb[7] }]; #IO_L13P_T2_MRCC_15 Sch=jb[10]
##Pmod Header JC
#set_property -dict { PACKAGE_PIN K1 IOSTANDARD LVCMOS33 } [get_ports { jc[0] }]; #IO_L23N_T3_35 Sch=jc[1]
#set_property -dict { PACKAGE_PIN F6 IOSTANDARD LVCMOS33 } [get_ports { jc[1] }]; #IO_L19N_T3_VREF_35 Sch=jc[2]
#set_property -dict { PACKAGE_PIN J2 IOSTANDARD LVCMOS33 } [get_ports { jc[2] }]; #IO_L22N_T3_35 Sch=jc[3]
#set_property -dict { PACKAGE_PIN G6 IOSTANDARD LVCMOS33 } [get_ports { jc[3] }]; #IO_L19P_T3_35 Sch=jc[4]
#set_property -dict { PACKAGE_PIN E7 IOSTANDARD LVCMOS33 } [get_ports { jc[4] }]; #IO_L6P_T0_35 Sch=jc[7]
#set_property -dict { PACKAGE_PIN J3 IOSTANDARD LVCMOS33 } [get_ports { jc[5] }]; #IO_L22P_T3_35 Sch=jc[8]
#set_property -dict { PACKAGE_PIN J4 IOSTANDARD LVCMOS33 } [get_ports { jc[6] }]; #IO_L21P_T3_DQS_35 Sch=jc[9]
#set_property -dict { PACKAGE_PIN E6 IOSTANDARD LVCMOS33 } [get_ports { jc[7] }]; #IO_L5P_T0_AD13P_35 Sch=jc[10]
##Pmod Header JD
#set_property -dict { PACKAGE_PIN H4 IOSTANDARD LVCMOS33 } [get_ports { jd[0] }]; #IO_L21N_T3_DQS_35 Sch=jd[1]
#set_property -dict { PACKAGE_PIN H1 IOSTANDARD LVCMOS33 } [get_ports { jd[1] }]; #IO_L17P_T2_35 Sch=jd[2]
#set_property -dict { PACKAGE_PIN G1 IOSTANDARD LVCMOS33 } [get_ports { jd[2] }]; #IO_L17N_T2_35 Sch=jd[3]
#set_property -dict { PACKAGE_PIN G3 IOSTANDARD LVCMOS33 } [get_ports { jd[3] }]; #IO_L20N_T3_35 Sch=jd[4]
#set_property -dict { PACKAGE_PIN H2 IOSTANDARD LVCMOS33 } [get_ports { jd[4] }]; #IO_L15P_T2_DQS_35 Sch=jd[7]
#set_property -dict { PACKAGE_PIN G4 IOSTANDARD LVCMOS33 } [get_ports { jd[5] }]; #IO_L20P_T3_35 Sch=jd[8]
#set_property -dict { PACKAGE_PIN G2 IOSTANDARD LVCMOS33 } [get_ports { jd[6] }]; #IO_L15N_T2_DQS_35 Sch=jd[9]
#set_property -dict { PACKAGE_PIN F3 IOSTANDARD LVCMOS33 } [get_ports { jd[7] }]; #IO_L13N_T2_MRCC_35 Sch=jd[10]
##Pmod Header JXADC
#set_property -dict { PACKAGE_PIN A14 IOSTANDARD LVDS } [get_ports { xa_n[0] }]; #IO_L9N_T1_DQS_AD3N_15 Sch=xa_n[1]
#set_property -dict { PACKAGE_PIN A13 IOSTANDARD LVDS } [get_ports { xa_p[0] }]; #IO_L9P_T1_DQS_AD3P_15 Sch=xa_p[1]
#set_property -dict { PACKAGE_PIN A16 IOSTANDARD LVDS } [get_ports { xa_n[1] }]; #IO_L8N_T1_AD10N_15 Sch=xa_n[2]
#set_property -dict { PACKAGE_PIN A15 IOSTANDARD LVDS } [get_ports { xa_p[1] }]; #IO_L8P_T1_AD10P_15 Sch=xa_p[2]
#set_property -dict { PACKAGE_PIN B17 IOSTANDARD LVDS } [get_ports { xa_n[2] }]; #IO_L7N_T1_AD2N_15 Sch=xa_n[3]
#set_property -dict { PACKAGE_PIN B16 IOSTANDARD LVDS } [get_ports { xa_p[2] }]; #IO_L7P_T1_AD2P_15 Sch=xa_p[3]
#set_property -dict { PACKAGE_PIN A18 IOSTANDARD LVDS } [get_ports { xa_n[3] }]; #IO_L10N_T1_AD11N_15 Sch=xa_n[4]
#set_property -dict { PACKAGE_PIN B18 IOSTANDARD LVDS } [get_ports { xa_p[3] }]; #IO_L10P_T1_AD11P_15 Sch=xa_p[4]
##VGA Connector
#set_property -dict { PACKAGE_PIN A3 IOSTANDARD LVCMOS33 } [get_ports { vga_r[0] }]; #IO_L8N_T1_AD14N_35 Sch=vga_r[0]
#set_property -dict { PACKAGE_PIN B4 IOSTANDARD LVCMOS33 } [get_ports { vga_r[1] }]; #IO_L7N_T1_AD6N_35 Sch=vga_r[1]
#set_property -dict { PACKAGE_PIN C5 IOSTANDARD LVCMOS33 } [get_ports { vga_r[2] }]; #IO_L1N_T0_AD4N_35 Sch=vga_r[2]
#set_property -dict { PACKAGE_PIN A4 IOSTANDARD LVCMOS33 } [get_ports { vga_r[3] }]; #IO_L8P_T1_AD14P_35 Sch=vga_r[3]
#
#set_property -dict { PACKAGE_PIN C6 IOSTANDARD LVCMOS33 } [get_ports { vga_g[0] }]; #IO_L1P_T0_AD4P_35 Sch=vga_g[0]
#set_property -dict { PACKAGE_PIN A5 IOSTANDARD LVCMOS33 } [get_ports { vga_g[1] }]; #IO_L3N_T0_DQS_AD5N_35 Sch=vga_g[1]
#set_property -dict { PACKAGE_PIN B6 IOSTANDARD LVCMOS33 } [get_ports { vga_g[2] }]; #IO_L2N_T0_AD12N_35 Sch=vga_g[2]
#set_property -dict { PACKAGE_PIN A6 IOSTANDARD LVCMOS33 } [get_ports { vga_g[3] }]; #IO_L3P_T0_DQS_AD5P_35 Sch=vga_g[3]
#
#set_property -dict { PACKAGE_PIN B7 IOSTANDARD LVCMOS33 } [get_ports { vga_b[0] }]; #IO_L2P_T0_AD12P_35 Sch=vga_b[0]
#set_property -dict { PACKAGE_PIN C7 IOSTANDARD LVCMOS33 } [get_ports { vga_b[1] }]; #IO_L4N_T0_35 Sch=vga_b[1]
#set_property -dict { PACKAGE_PIN D7 IOSTANDARD LVCMOS33 } [get_ports { vga_b[2] }]; #IO_L6N_T0_VREF_35 Sch=vga_b[2]
#set_property -dict { PACKAGE_PIN D8 IOSTANDARD LVCMOS33 } [get_ports { vga_b[3] }]; #IO_L4P_T0_35 Sch=vga_b[3]
#set_property -dict { PACKAGE_PIN B11 IOSTANDARD LVCMOS33 } [get_ports { vga_hs }]; #IO_L4P_T0_15 Sch=vga_hs
#set_property -dict { PACKAGE_PIN B12 IOSTANDARD LVCMOS33 } [get_ports { vga_vs }]; #IO_L3N_T0_DQS_AD1N_15 Sch=vga_vs
##Micro SD Connector
#set_property -dict { PACKAGE_PIN E2 IOSTANDARD LVCMOS33 } [get_ports { sd_reset }]; #IO_L14P_T2_SRCC_35 Sch=sd_reset
#set_property -dict { PACKAGE_PIN A1 IOSTANDARD LVCMOS33 } [get_ports { sd_cd }]; #IO_L9N_T1_DQS_AD7N_35 Sch=sd_cd
#set_property -dict { PACKAGE_PIN B1 IOSTANDARD LVCMOS33 } [get_ports { sd_sck }]; #IO_L9P_T1_DQS_AD7P_35 Sch=sd_sck
#set_property -dict { PACKAGE_PIN C1 IOSTANDARD LVCMOS33 } [get_ports { sd_cmd }]; #IO_L16N_T2_35 Sch=sd_cmd
#set_property -dict { PACKAGE_PIN C2 IOSTANDARD LVCMOS33 } [get_ports { sd_dat[0] }]; #IO_L16P_T2_35 Sch=sd_dat[0]
#set_property -dict { PACKAGE_PIN E1 IOSTANDARD LVCMOS33 } [get_ports { sd_dat[1] }]; #IO_L18N_T2_35 Sch=sd_dat[1]
#set_property -dict { PACKAGE_PIN F1 IOSTANDARD LVCMOS33 } [get_ports { sd_dat[2] }]; #IO_L18P_T2_35 Sch=sd_dat[2]
#set_property -dict { PACKAGE_PIN D2 IOSTANDARD LVCMOS33 } [get_ports { sd_dat[3] }]; #IO_L14N_T2_SRCC_35 Sch=sd_dat[3]
##Accelerometer
#set_property -dict { PACKAGE_PIN E15 IOSTANDARD LVCMOS33 } [get_ports { acl_miso }]; #IO_L11P_T1_SRCC_15 Sch=acl_miso
#set_property -dict { PACKAGE_PIN F14 IOSTANDARD LVCMOS33 } [get_ports { acl_mosi }]; #IO_L5N_T0_AD9N_15 Sch=acl_mosi
#set_property -dict { PACKAGE_PIN F15 IOSTANDARD LVCMOS33 } [get_ports { acl_sclk }]; #IO_L14P_T2_SRCC_15 Sch=acl_sclk
#set_property -dict { PACKAGE_PIN D15 IOSTANDARD LVCMOS33 } [get_ports { acl_csn }]; #IO_L12P_T1_MRCC_15 Sch=acl_csn
#set_property -dict { PACKAGE_PIN B13 IOSTANDARD LVCMOS33 } [get_ports { acl_int[1] }]; #IO_L2P_T0_AD8P_15 Sch=acl_int[1]
#set_property -dict { PACKAGE_PIN C16 IOSTANDARD LVCMOS33 } [get_ports { acl_int[2] }]; #IO_L20P_T3_A20_15 Sch=acl_int[2]
##Temperature Sensor
#set_property -dict { PACKAGE_PIN C14 IOSTANDARD LVCMOS33 } [get_ports { tmp_scl }]; #IO_L1N_T0_AD0N_15 Sch=tmp_scl
#set_property -dict { PACKAGE_PIN C15 IOSTANDARD LVCMOS33 } [get_ports { tmp_sda }]; #IO_L12N_T1_MRCC_15 Sch=tmp_sda
#set_property -dict { PACKAGE_PIN D13 IOSTANDARD LVCMOS33 } [get_ports { tmp_int }]; #IO_L6N_T0_VREF_15 Sch=tmp_int
#set_property -dict { PACKAGE_PIN B14 IOSTANDARD LVCMOS33 } [get_ports { tmp_ct }]; #IO_L2N_T0_AD8N_15 Sch=tmp_ct
##Omnidirectional Microphone
#set_property -dict { PACKAGE_PIN J5 IOSTANDARD LVCMOS33 } [get_ports { m_clk }]; #IO_25_35 Sch=m_clk
#set_property -dict { PACKAGE_PIN H5 IOSTANDARD LVCMOS33 } [get_ports { m_data }]; #IO_L24N_T3_35 Sch=m_data
#set_property -dict { PACKAGE_PIN F5 IOSTANDARD LVCMOS33 } [get_ports { m_lrsel }]; #IO_0_35 Sch=m_lrsel
##PWM Audio Amplifier
#set_property -dict { PACKAGE_PIN A11 IOSTANDARD LVCMOS33 } [get_ports { aud_pwm }]; #IO_L4N_T0_15 Sch=aud_pwm
#set_property -dict { PACKAGE_PIN D12 IOSTANDARD LVCMOS33 } [get_ports { aud_sd }]; #IO_L6P_T0_15 Sch=aud_sd
##USB-RS232 Interface
set_property -dict { PACKAGE_PIN C4 IOSTANDARD LVCMOS33 } [get_ports { uart_txd_in }]; #IO_L7P_T1_AD6P_35 Sch=uart_txd_in
set_property -dict { PACKAGE_PIN D4 IOSTANDARD LVCMOS33 } [get_ports { uart_rxd_out }]; #IO_L11N_T1_SRCC_35 Sch=uart_rxd_out
#set_property -dict { PACKAGE_PIN D3 IOSTANDARD LVCMOS33 } [get_ports { uart_cts }]; #IO_L12N_T1_MRCC_35 Sch=uart_cts
#set_property -dict { PACKAGE_PIN E5 IOSTANDARD LVCMOS33 } [get_ports { uart_rts }]; #IO_L5N_T0_AD13N_35 Sch=uart_rts
##USB HID (PS/2)
set_property -dict { PACKAGE_PIN F4 IOSTANDARD LVCMOS33 } [get_ports { ps2_clk }]; #IO_L13P_T2_MRCC_35 Sch=ps2_clk
set_property -dict { PACKAGE_PIN B2 IOSTANDARD LVCMOS33 } [get_ports { ps2_data }]; #IO_L10N_T1_AD15N_35 Sch=ps2_data
##SMSC Ethernet PHY
#set_property -dict { PACKAGE_PIN C9 IOSTANDARD LVCMOS33 } [get_ports { eth_mdc }]; #IO_L11P_T1_SRCC_16 Sch=eth_mdc
#set_property -dict { PACKAGE_PIN A9 IOSTANDARD LVCMOS33 } [get_ports { eth_mdio }]; #IO_L14N_T2_SRCC_16 Sch=eth_mdio
#set_property -dict { PACKAGE_PIN B3 IOSTANDARD LVCMOS33 } [get_ports { eth_rstn }]; #IO_L10P_T1_AD15P_35 Sch=eth_rstn
#set_property -dict { PACKAGE_PIN D9 IOSTANDARD LVCMOS33 } [get_ports { eth_crsdv }]; #IO_L6N_T0_VREF_16 Sch=eth_crs/udv
#set_property -dict { PACKAGE_PIN C10 IOSTANDARD LVCMOS33 } [get_ports { eth_rxerr }]; #IO_L13N_T2_MRCC_16 Sch=eth_rxerr
#set_property -dict { PACKAGE_PIN C11 IOSTANDARD LVCMOS33 } [get_ports { eth_rxd[0] }]; #IO_L13P_T2_MRCC_16 Sch=eth_rxd[0]
#set_property -dict { PACKAGE_PIN D10 IOSTANDARD LVCMOS33 } [get_ports { eth_rxd[1] }]; #IO_L19N_T3_VREF_16 Sch=eth_rxd[1]
#set_property -dict { PACKAGE_PIN B9 IOSTANDARD LVCMOS33 } [get_ports { eth_txen }]; #IO_L11N_T1_SRCC_16 Sch=eth_txen
#set_property -dict { PACKAGE_PIN A10 IOSTANDARD LVCMOS33 } [get_ports { eth_txd[0] }]; #IO_L14P_T2_SRCC_16 Sch=eth_txd[0]
#set_property -dict { PACKAGE_PIN A8 IOSTANDARD LVCMOS33 } [get_ports { eth_txd[1] }]; #IO_L12N_T1_MRCC_16 Sch=eth_txd[1]
#set_property -dict { PACKAGE_PIN D5 IOSTANDARD LVCMOS33 } [get_ports { eth_refclk }]; #IO_L11P_T1_SRCC_35 Sch=eth_refclk
#set_property -dict { PACKAGE_PIN B8 IOSTANDARD LVCMOS33 } [get_ports { eth_intn }]; #IO_L12P_T1_MRCC_16 Sch=eth_intn
##Quad SPI Flash
#set_property -dict { PACKAGE_PIN K17 IOSTANDARD LVCMOS33 } [get_ports { qspi_dq[0] }]; #IO_L1P_T0_D00_MOSI_14 Sch=qspi_dq[0]
#set_property -dict { PACKAGE_PIN K18 IOSTANDARD LVCMOS33 } [get_ports { qspi_dq[1] }]; #IO_L1N_T0_D01_DIN_14 Sch=qspi_dq[1]
#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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 93 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 58 KiB

View File

@ -1,10 +0,0 @@
---
cores:
image_mem:
type: block_memory
width: 12
depth: 16384
ethernet:
interface: "en8"
host_mac: "12:34:56:78:90:ab"

View File

@ -1,37 +0,0 @@
import sys
from PIL import Image, ImageOps
if __name__ == "__main__":
if len(sys.argv) < 2:
print("Usage: {0} <image to convert>".format(sys.argv[0]))
else:
input_fname = sys.argv[1]
image_in = Image.open(input_fname)
image_in = image_in.convert('RGB')
# Resize the image
image_in = image_in.resize((128, 128))
image_out = image_in.copy()
w, h = image_in.size
# Take input image and divide each color channel's value by 16
for y in range(h):
for x in range(w):
r, g, b = image_in.getpixel((x, y))
image_out.putpixel((x,y), (r//16, g//16, b//16))
# Save the image itself
pixels = []
for y in range(h):
for x in range(w):
(r, g, b) = image_out.getpixel((x,y))
color = (r*16*16) + (g*16) + (b)
pixels.append(color)
from manta import Manta
m = Manta('manta.yaml')
addrs = list(range(len(pixels)))
m.image_mem.write(addrs, pixels)

View File

@ -1,207 +0,0 @@
// file: clk_gen.v
//
// (c) Copyright 2008 - 2013 Xilinx, Inc. All rights reserved.
//
// This file contains confidential and proprietary information
// of Xilinx, Inc. and is protected under U.S. and
// international copyright and other intellectual property
// laws.
//
// DISCLAIMER
// This disclaimer is not a license and does not grant any
// rights to the materials distributed herewith. Except as
// otherwise provided in a valid license issued to you by
// Xilinx, and to the maximum extent permitted by applicable
// law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND
// WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES
// AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING
// BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-
// INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and
// (2) Xilinx shall not be liable (whether in contract or tort,
// including negligence, or under any other theory of
// liability) for any loss or damage of any kind or nature
// related to, arising under or in connection with these
// materials, including for any direct, or any indirect,
// special, incidental, or consequential loss or damage
// (including loss of data, profits, goodwill, or any type of
// loss or damage suffered as a result of any action brought
// by a third party) even if such damage or loss was
// reasonably foreseeable or Xilinx had been advised of the
// possibility of the same.
//
// CRITICAL APPLICATIONS
// Xilinx products are not designed or intended to be fail-
// safe, or for use in any application requiring fail-safe
// performance, such as life-support or safety devices or
// systems, Class III medical devices, nuclear facilities,
// applications related to the deployment of airbags, or any
// other applications that could lead to death, personal
// injury, or severe property or environmental damage
// (individually and collectively, "Critical
// Applications"). Customer assumes the sole risk and
// liability of any use of Xilinx products in Critical
// Applications, subject only to applicable laws and
// regulations governing limitations on product liability.
//
// THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS
// PART OF THIS FILE AT ALL TIMES.
//
//----------------------------------------------------------------------------
// User entered comments
//----------------------------------------------------------------------------
// None
//
//----------------------------------------------------------------------------
// Output Output Phase Duty Cycle Pk-to-Pk Phase
// Clock Freq (MHz) (degrees) (%) Jitter (ps) Error (ps)
//----------------------------------------------------------------------------
// clk_50mhz__50.00000______0.000______50.0______150.541_____99.281
// clk_65mhz__65.00000______0.000______50.0______142.278_____99.281
//
//----------------------------------------------------------------------------
// Input Clock Freq (MHz) Input Jitter (UI)
//----------------------------------------------------------------------------
// __primary_________100.000____________0.010
`timescale 1ps/1ps
module clk_gen
(// Clock in ports
// Clock out ports
output clk_50mhz,
output clk_65mhz,
input clk_100mhz
);
// Input buffering
//------------------------------------
wire clk_100mhz_clk_gen;
wire clk_in2_clk_gen;
IBUF clkin1_ibufg
(.O (clk_100mhz_clk_gen),
.I (clk_100mhz));
// Clocking PRIMITIVE
//------------------------------------
// Instantiation of the MMCM PRIMITIVE
// * Unused inputs are tied off
// * Unused outputs are labeled unused
wire clk_50mhz_clk_gen;
wire clk_65mhz_clk_gen;
wire clk_out3_clk_gen;
wire clk_out4_clk_gen;
wire clk_out5_clk_gen;
wire clk_out6_clk_gen;
wire clk_out7_clk_gen;
wire [15:0] do_unused;
wire drdy_unused;
wire psdone_unused;
wire locked_int;
wire clkfbout_clk_gen;
wire clkfbout_buf_clk_gen;
wire clkfboutb_unused;
wire clkout0b_unused;
wire clkout1b_unused;
wire clkout2_unused;
wire clkout2b_unused;
wire clkout3_unused;
wire clkout3b_unused;
wire clkout4_unused;
wire clkout5_unused;
wire clkout6_unused;
wire clkfbstopped_unused;
wire clkinstopped_unused;
MMCME2_ADV
#(.BANDWIDTH ("OPTIMIZED"),
.CLKOUT4_CASCADE ("FALSE"),
.COMPENSATION ("ZHOLD"),
.STARTUP_WAIT ("FALSE"),
.DIVCLK_DIVIDE (1),
.CLKFBOUT_MULT_F (9.750),
.CLKFBOUT_PHASE (0.000),
.CLKFBOUT_USE_FINE_PS ("FALSE"),
.CLKOUT0_DIVIDE_F (19.500),
.CLKOUT0_PHASE (0.000),
.CLKOUT0_DUTY_CYCLE (0.500),
.CLKOUT0_USE_FINE_PS ("FALSE"),
.CLKOUT1_DIVIDE (15),
.CLKOUT1_PHASE (0.000),
.CLKOUT1_DUTY_CYCLE (0.500),
.CLKOUT1_USE_FINE_PS ("FALSE"),
.CLKIN1_PERIOD (10.000))
mmcm_adv_inst
// Output clocks
(
.CLKFBOUT (clkfbout_clk_gen),
.CLKFBOUTB (clkfboutb_unused),
.CLKOUT0 (clk_50mhz_clk_gen),
.CLKOUT0B (clkout0b_unused),
.CLKOUT1 (clk_65mhz_clk_gen),
.CLKOUT1B (clkout1b_unused),
.CLKOUT2 (clkout2_unused),
.CLKOUT2B (clkout2b_unused),
.CLKOUT3 (clkout3_unused),
.CLKOUT3B (clkout3b_unused),
.CLKOUT4 (clkout4_unused),
.CLKOUT5 (clkout5_unused),
.CLKOUT6 (clkout6_unused),
// Input clock control
.CLKFBIN (clkfbout_buf_clk_gen),
.CLKIN1 (clk_100mhz_clk_gen),
.CLKIN2 (1'b0),
// Tied to always select the primary input clock
.CLKINSEL (1'b1),
// Ports for dynamic reconfiguration
.DADDR (7'h0),
.DCLK (1'b0),
.DEN (1'b0),
.DI (16'h0),
.DO (do_unused),
.DRDY (drdy_unused),
.DWE (1'b0),
// Ports for dynamic phase shift
.PSCLK (1'b0),
.PSEN (1'b0),
.PSINCDEC (1'b0),
.PSDONE (psdone_unused),
// Other control and status signals
.LOCKED (locked_int),
.CLKINSTOPPED (clkinstopped_unused),
.CLKFBSTOPPED (clkfbstopped_unused),
.PWRDWN (1'b0),
.RST (1'b0));
// Clock Monitor clock assigning
//--------------------------------------
// Output buffering
//-----------------------------------
BUFG clkf_buf
(.O (clkfbout_buf_clk_gen),
.I (clkfbout_clk_gen));
BUFG clkout1_buf
(.O (clk_50mhz),
.I (clk_50mhz_clk_gen));
BUFG clkout2_buf
(.O (clk_65mhz),
.I (clk_65mhz_clk_gen));
endmodule

View File

@ -1,108 +0,0 @@
`timescale 1ns / 1ps
`default_nettype none
module top_level (
input wire clk_100mhz,
output reg eth_refclk,
output reg eth_rstn,
input wire eth_crsdv,
input wire [1:0] eth_rxd,
output reg eth_txen,
output reg [1:0] eth_txd,
output logic [3:0] vga_r, vga_g, vga_b,
output logic vga_hs, vga_vs);
assign eth_rstn = 1;
// Clock generation
logic clk_50mhz;
logic clk_65mhz;
assign eth_refclk = clk_50mhz;
clk_gen gen(
.clk_100mhz(clk_100mhz),
.clk_50mhz(clk_50mhz),
.clk_65mhz(clk_65mhz));
// VGA signals
logic [10:0] hcount;
logic [9:0] vcount;
logic hsync, vsync, blank;
vga vga_gen(
.pixel_clk_in(clk_65mhz),
.hcount_out(hcount),
.vcount_out(vcount),
.hsync_out(hsync),
.vsync_out(vsync),
.blank_out(blank));
// VGA Pipelining
reg[1:0][10:0] hcount_pipe;
reg[1:0][10:0] vcount_pipe;
reg[1:0] hsync_pipe;
reg[1:0] vsync_pipe;
reg[1:0] blank_pipe;
always_ff @(posedge clk_65mhz)begin
hcount_pipe[0] <= hcount;
vcount_pipe[0] <= vcount;
hsync_pipe[0] <= hsync;
vsync_pipe[0] <= vsync;
blank_pipe[0] <= blank;
for (int i=1; i<2; i = i+1)begin
hcount_pipe[i] <= hcount_pipe[i-1];
vcount_pipe[i] <= vcount_pipe[i-1];
hsync_pipe[i] <= hsync_pipe[i-1];
vsync_pipe[i] <= vsync_pipe[i-1];
blank_pipe[i] <= blank_pipe[i-1];
end
end
localparam WIDTH = 128;
localparam HEIGHT = 128;
localparam X = 0;
localparam Y = 0;
// calculate rom address
logic [$clog2(WIDTH*HEIGHT)-1:0] image_addr;
assign image_addr = (hcount - X) + ((vcount - Y) * WIDTH);
logic in_sprite;
assign in_sprite = ((hcount_pipe[1] >= X && hcount_pipe[1] < (X + WIDTH)) &&
(vcount_pipe[1] >= Y && vcount_pipe[1] < (Y + HEIGHT)));
manta manta_inst (
.clk(clk_50mhz),
.crsdv(eth_crsdv),
.rxd(eth_rxd),
.txen(eth_txen),
.txd(eth_txd),
.image_mem_clk(clk_65mhz),
.image_mem_addr(image_addr),
.image_mem_din(),
.image_mem_dout(sprite_color),
.image_mem_we(1'b0));
logic [11:0] sprite_color;
logic [11:0] color;
assign color = in_sprite ? sprite_color : 12'h0;
// the following lines are required for the Nexys4 VGA circuit - do not change
assign vga_r = ~blank_pipe[1] ? color[11:8]: 0;
assign vga_g = ~blank_pipe[1] ? color[7:4] : 0;
assign vga_b = ~blank_pipe[1] ? color[3:0] : 0;
assign vga_hs = ~hsync_pipe[1];
assign vga_vs = ~vsync_pipe[1];
endmodule
`default_nettype wire

View File

@ -1,68 +0,0 @@
/* vga: Generate VGA display signals (1024 x 768 @ 60Hz)
*
* ---- HORIZONTAL ----- ------VERTICAL -----
* Active Active
* Freq Video FP Sync BP Video FP Sync BP
* 640x480, 60Hz 25.175 640 16 96 48 480 11 2 31
* 800x600, 60Hz 40.000 800 40 128 88 600 1 4 23
* 1024x768, 60Hz 65.000 1024 24 136 160 768 3 6 29
* 1280x1024, 60Hz 108.00 1280 48 112 248 768 1 3 38
* 1280x720p 60Hz 75.25 1280 72 80 216 720 3 5 30
* 1920x1080 60Hz 148.5 1920 88 44 148 1080 4 5 36
*
* change the clock frequency, front porches, sync's, and back porches to create
* other screen resolutions
*/
module vga(
input wire pixel_clk_in,
output logic [10:0] hcount_out, // pixel number on current line
output logic [9:0] vcount_out, // line number
output logic vsync_out, hsync_out,
output logic blank_out);
parameter DISPLAY_WIDTH = 1024; // display width
parameter DISPLAY_HEIGHT = 768; // number of lines
parameter H_FP = 24; // horizontal front porch
parameter H_SYNC_PULSE = 136; // horizontal sync
parameter H_BP = 160; // horizontal back porch
parameter V_FP = 3; // vertical front porch
parameter V_SYNC_PULSE = 6; // vertical sync
parameter V_BP = 29; // vertical back porch
// horizontal: 1344 pixels total
// display 1024 pixels per line
logic hblank,vblank;
logic hsyncon,hsyncoff,hreset,hblankon;
assign hblankon = (hcount_out == (DISPLAY_WIDTH -1));
assign hsyncon = (hcount_out == (DISPLAY_WIDTH + H_FP - 1)); //1047
assign hsyncoff = (hcount_out == (DISPLAY_WIDTH + H_FP + H_SYNC_PULSE - 1)); // 1183
assign hreset = (hcount_out == (DISPLAY_WIDTH + H_FP + H_SYNC_PULSE + H_BP - 1)); //1343
// vertical: 806 lines total
// display 768 lines
logic vsyncon,vsyncoff,vreset,vblankon;
assign vblankon = hreset & (vcount_out == (DISPLAY_HEIGHT - 1)); // 767
assign vsyncon = hreset & (vcount_out == (DISPLAY_HEIGHT + V_FP - 1)); // 771
assign vsyncoff = hreset & (vcount_out == (DISPLAY_HEIGHT + V_FP + V_SYNC_PULSE - 1)); // 777
assign vreset = hreset & (vcount_out == (DISPLAY_HEIGHT + V_FP + V_SYNC_PULSE + V_BP - 1)); // 805
// sync and blanking
logic next_hblank,next_vblank;
assign next_hblank = hreset ? 0 : hblankon ? 1 : hblank;
assign next_vblank = vreset ? 0 : vblankon ? 1 : vblank;
always_ff @(posedge pixel_clk_in) begin
hcount_out <= hreset ? 0 : hcount_out + 1;
hblank <= next_hblank;
hsync_out <= hsyncon ? 0 : hsyncoff ? 1 : hsync_out; // active low
vcount_out <= hreset ? (vreset ? 0 : vcount_out + 1) : vcount_out;
vblank <= next_vblank;
vsync_out <= vsyncon ? 0 : vsyncoff ? 1 : vsync_out; // active low
blank_out <= next_vblank | (next_hblank & ~hreset);
end
endmodule

View File

@ -1,253 +0,0 @@
## This file is a general .xdc for the Nexys4 DDR Rev. C
## To use it in a project:
## - uncomment the lines corresponding to used pins
## - rename the used ports (in each line, after get_ports) according to the top level signal names in the project
## This file has been modified from the default .xdc provided by Digilent for the Nexys A7
## Clock signal
set_property -dict { PACKAGE_PIN E3 IOSTANDARD LVCMOS33 } [get_ports { clk_100mhz }]; #IO_L12P_T1_MRCC_35 Sch=clk_100mhz
create_clock -add -name sys_clk_pin -period 10.00 -waveform {0 5} [get_ports {clk_100mhz}];
##Switches
#set_property -dict { PACKAGE_PIN J15 IOSTANDARD LVCMOS33 } [get_ports { sw[0] }]; #IO_L24N_T3_RS0_15 Sch=sw[0]
#set_property -dict { PACKAGE_PIN L16 IOSTANDARD LVCMOS33 } [get_ports { sw[1] }]; #IO_L3N_T0_DQS_EMCCLK_14 Sch=sw[1]
#set_property -dict { PACKAGE_PIN M13 IOSTANDARD LVCMOS33 } [get_ports { sw[2] }]; #IO_L6N_T0_D08_VREF_14 Sch=sw[2]
#set_property -dict { PACKAGE_PIN R15 IOSTANDARD LVCMOS33 } [get_ports { sw[3] }]; #IO_L13N_T2_MRCC_14 Sch=sw[3]
#set_property -dict { PACKAGE_PIN R17 IOSTANDARD LVCMOS33 } [get_ports { sw[4] }]; #IO_L12N_T1_MRCC_14 Sch=sw[4]
#set_property -dict { PACKAGE_PIN T18 IOSTANDARD LVCMOS33 } [get_ports { sw[5] }]; #IO_L7N_T1_D10_14 Sch=sw[5]
#set_property -dict { PACKAGE_PIN U18 IOSTANDARD LVCMOS33 } [get_ports { sw[6] }]; #IO_L17N_T2_A13_D29_14 Sch=sw[6]
#set_property -dict { PACKAGE_PIN R13 IOSTANDARD LVCMOS33 } [get_ports { sw[7] }]; #IO_L5N_T0_D07_14 Sch=sw[7]
#set_property -dict { PACKAGE_PIN T8 IOSTANDARD LVCMOS18 } [get_ports { sw[8] }]; #IO_L24N_T3_34 Sch=sw[8]
#set_property -dict { PACKAGE_PIN U8 IOSTANDARD LVCMOS18 } [get_ports { sw[9] }]; #IO_25_34 Sch=sw[9]
#set_property -dict { PACKAGE_PIN R16 IOSTANDARD LVCMOS33 } [get_ports { sw[10] }]; #IO_L15P_T2_DQS_RDWR_B_14 Sch=sw[10]
#set_property -dict { PACKAGE_PIN T13 IOSTANDARD LVCMOS33 } [get_ports { sw[11] }]; #IO_L23P_T3_A03_D19_14 Sch=sw[11]
#set_property -dict { PACKAGE_PIN H6 IOSTANDARD LVCMOS33 } [get_ports { sw[12] }]; #IO_L24P_T3_35 Sch=sw[12]
#set_property -dict { PACKAGE_PIN U12 IOSTANDARD LVCMOS33 } [get_ports { sw[13] }]; #IO_L20P_T3_A08_D24_14 Sch=sw[13]
#set_property -dict { PACKAGE_PIN U11 IOSTANDARD LVCMOS33 } [get_ports { sw[14] }]; #IO_L19N_T3_A09_D25_VREF_14 Sch=sw[14]
#set_property -dict { PACKAGE_PIN V10 IOSTANDARD LVCMOS33 } [get_ports { sw[15] }]; #IO_L21P_T3_DQS_14 Sch=sw[15]
## LEDs
#set_property -dict { PACKAGE_PIN H17 IOSTANDARD LVCMOS33 } [get_ports { led[0] }]; #IO_L18P_T2_A24_15 Sch=led[0]
#set_property -dict { PACKAGE_PIN K15 IOSTANDARD LVCMOS33 } [get_ports { led[1] }]; #IO_L24P_T3_RS1_15 Sch=led[1]
#set_property -dict { PACKAGE_PIN J13 IOSTANDARD LVCMOS33 } [get_ports { led[2] }]; #IO_L17N_T2_A25_15 Sch=led[2]
#set_property -dict { PACKAGE_PIN N14 IOSTANDARD LVCMOS33 } [get_ports { led[3] }]; #IO_L8P_T1_D11_14 Sch=led[3]
#set_property -dict { PACKAGE_PIN R18 IOSTANDARD LVCMOS33 } [get_ports { led[4] }]; #IO_L7P_T1_D09_14 Sch=led[4]
#set_property -dict { PACKAGE_PIN V17 IOSTANDARD LVCMOS33 } [get_ports { led[5] }]; #IO_L18N_T2_A11_D27_14 Sch=led[5]
#set_property -dict { PACKAGE_PIN U17 IOSTANDARD LVCMOS33 } [get_ports { led[6] }]; #IO_L17P_T2_A14_D30_14 Sch=led[6]
#set_property -dict { PACKAGE_PIN U16 IOSTANDARD LVCMOS33 } [get_ports { led[7] }]; #IO_L18P_T2_A12_D28_14 Sch=led[7]
#set_property -dict { PACKAGE_PIN V16 IOSTANDARD LVCMOS33 } [get_ports { led[8] }]; #IO_L16N_T2_A15_D31_14 Sch=led[8]
#set_property -dict { PACKAGE_PIN T15 IOSTANDARD LVCMOS33 } [get_ports { led[9] }]; #IO_L14N_T2_SRCC_14 Sch=led[9]
#set_property -dict { PACKAGE_PIN U14 IOSTANDARD LVCMOS33 } [get_ports { led[10] }]; #IO_L22P_T3_A05_D21_14 Sch=led[10]
#set_property -dict { PACKAGE_PIN T16 IOSTANDARD LVCMOS33 } [get_ports { led[11] }]; #IO_L15N_T2_DQS_DOUT_CSO_B_14 Sch=led[11]
#set_property -dict { PACKAGE_PIN V15 IOSTANDARD LVCMOS33 } [get_ports { led[12] }]; #IO_L16P_T2_CSI_B_14 Sch=led[12]
#set_property -dict { PACKAGE_PIN V14 IOSTANDARD LVCMOS33 } [get_ports { led[13] }]; #IO_L22N_T3_A04_D20_14 Sch=led[13]
#set_property -dict { PACKAGE_PIN V12 IOSTANDARD LVCMOS33 } [get_ports { led[14] }]; #IO_L20N_T3_A07_D23_14 Sch=led[14]
#set_property -dict { PACKAGE_PIN V11 IOSTANDARD LVCMOS33 } [get_ports { led[15] }]; #IO_L21N_T3_DQS_A06_D22_14 Sch=led[15]
#set_property -dict { PACKAGE_PIN R12 IOSTANDARD LVCMOS33 } [get_ports { led16_b }]; #IO_L5P_T0_D06_14 Sch=led16_b
#set_property -dict { PACKAGE_PIN M16 IOSTANDARD LVCMOS33 } [get_ports { led16_g }]; #IO_L10P_T1_D14_14 Sch=led16_g
#set_property -dict { PACKAGE_PIN N15 IOSTANDARD LVCMOS33 } [get_ports { led16_r }]; #IO_L11P_T1_SRCC_14 Sch=led16_r
#set_property -dict { PACKAGE_PIN G14 IOSTANDARD LVCMOS33 } [get_ports { led17_b }]; #IO_L15N_T2_DQS_ADV_B_15 Sch=led17_b
#set_property -dict { PACKAGE_PIN R11 IOSTANDARD LVCMOS33 } [get_ports { led17_g }]; #IO_0_14 Sch=led17_g
#set_property -dict { PACKAGE_PIN N16 IOSTANDARD LVCMOS33 } [get_ports { led17_r }]; #IO_L11N_T1_SRCC_14 Sch=led17_r
##7 segment display
#set_property -dict { PACKAGE_PIN T10 IOSTANDARD LVCMOS33 } [get_ports { ca }]; #IO_L24N_T3_A00_D16_14 Sch=ca
#set_property -dict { PACKAGE_PIN R10 IOSTANDARD LVCMOS33 } [get_ports { cb }]; #IO_25_14 Sch=cb
#set_property -dict { PACKAGE_PIN K16 IOSTANDARD LVCMOS33 } [get_ports { cc }]; #IO_25_15 Sch=cc
#set_property -dict { PACKAGE_PIN K13 IOSTANDARD LVCMOS33 } [get_ports { cd }]; #IO_L17P_T2_A26_15 Sch=cd
#set_property -dict { PACKAGE_PIN P15 IOSTANDARD LVCMOS33 } [get_ports { ce }]; #IO_L13P_T2_MRCC_14 Sch=ce
#set_property -dict { PACKAGE_PIN T11 IOSTANDARD LVCMOS33 } [get_ports { cf }]; #IO_L19P_T3_A10_D26_14 Sch=cf
#set_property -dict { PACKAGE_PIN L18 IOSTANDARD LVCMOS33 } [get_ports { cg }]; #IO_L4P_T0_D04_14 Sch=cg
#set_property -dict { PACKAGE_PIN H15 IOSTANDARD LVCMOS33 } [get_ports { dp }]; #IO_L19N_T3_A21_VREF_15 Sch=dp
#set_property -dict { PACKAGE_PIN J17 IOSTANDARD LVCMOS33 } [get_ports { an[0] }]; #IO_L23P_T3_FOE_B_15 Sch=an[0]
#set_property -dict { PACKAGE_PIN J18 IOSTANDARD LVCMOS33 } [get_ports { an[1] }]; #IO_L23N_T3_FWE_B_15 Sch=an[1]
#set_property -dict { PACKAGE_PIN T9 IOSTANDARD LVCMOS33 } [get_ports { an[2] }]; #IO_L24P_T3_A01_D17_14 Sch=an[2]
#set_property -dict { PACKAGE_PIN J14 IOSTANDARD LVCMOS33 } [get_ports { an[3] }]; #IO_L19P_T3_A22_15 Sch=an[3]
#set_property -dict { PACKAGE_PIN P14 IOSTANDARD LVCMOS33 } [get_ports { an[4] }]; #IO_L8N_T1_D12_14 Sch=an[4]
#set_property -dict { PACKAGE_PIN T14 IOSTANDARD LVCMOS33 } [get_ports { an[5] }]; #IO_L14P_T2_SRCC_14 Sch=an[5]
#set_property -dict { PACKAGE_PIN K2 IOSTANDARD LVCMOS33 } [get_ports { an[6] }]; #IO_L23P_T3_35 Sch=an[6]
#set_property -dict { PACKAGE_PIN U13 IOSTANDARD LVCMOS33 } [get_ports { an[7] }]; #IO_L23N_T3_A02_D18_14 Sch=an[7]
##Buttons
#set_property -dict { PACKAGE_PIN C12 IOSTANDARD LVCMOS33 } [get_ports { cpu_resetn }]; #IO_L3P_T0_DQS_AD1P_15 Sch=cpu_resetn
#set_property -dict { PACKAGE_PIN N17 IOSTANDARD LVCMOS33 } [get_ports { btnc }]; #IO_L9P_T1_DQS_14 Sch=btnc
#set_property -dict { PACKAGE_PIN M18 IOSTANDARD LVCMOS33 } [get_ports { btnu }]; #IO_L4N_T0_D05_14 Sch=btnu
#set_property -dict { PACKAGE_PIN P17 IOSTANDARD LVCMOS33 } [get_ports { btnl }]; #IO_L12P_T1_MRCC_14 Sch=btnl
#set_property -dict { PACKAGE_PIN M17 IOSTANDARD LVCMOS33 } [get_ports { btnr }]; #IO_L10N_T1_D15_14 Sch=btnr
#set_property -dict { PACKAGE_PIN P18 IOSTANDARD LVCMOS33 } [get_ports { btnd }]; #IO_L9N_T1_DQS_D13_14 Sch=btnd
##Pmod Headers
##Pmod Header JA
#set_property -dict { PACKAGE_PIN C17 IOSTANDARD LVCMOS33 } [get_ports { ja[0] }]; #IO_L20N_T3_A19_15 Sch=ja[1]
#set_property -dict { PACKAGE_PIN D18 IOSTANDARD LVCMOS33 } [get_ports { ja[1] }]; #IO_L21N_T3_DQS_A18_15 Sch=ja[2]
#set_property -dict { PACKAGE_PIN E18 IOSTANDARD LVCMOS33 } [get_ports { ja[2] }]; #IO_L21P_T3_DQS_15 Sch=ja[3]
#set_property -dict { PACKAGE_PIN G17 IOSTANDARD LVCMOS33 } [get_ports { ja[3] }]; #IO_L18N_T2_A23_15 Sch=ja[4]
#set_property -dict { PACKAGE_PIN D17 IOSTANDARD LVCMOS33 } [get_ports { ja[4] }]; #IO_L16N_T2_A27_15 Sch=ja[7]
#set_property -dict { PACKAGE_PIN E17 IOSTANDARD LVCMOS33 } [get_ports { ja[5] }]; #IO_L16P_T2_A28_15 Sch=ja[8]
#set_property -dict { PACKAGE_PIN F18 IOSTANDARD LVCMOS33 } [get_ports { ja[6] }]; #IO_L22N_T3_A16_15 Sch=ja[9]
#set_property -dict { PACKAGE_PIN G18 IOSTANDARD LVCMOS33 } [get_ports { ja[7] }]; #IO_L22P_T3_A17_15 Sch=ja[10]
##Pmod Header JB
#set_property -dict { PACKAGE_PIN D14 IOSTANDARD LVCMOS33 } [get_ports { jb[0] }]; #IO_L1P_T0_AD0P_15 Sch=jb[1]
#set_property -dict { PACKAGE_PIN F16 IOSTANDARD LVCMOS33 } [get_ports { jb[1] }]; #IO_L14N_T2_SRCC_15 Sch=jb[2]
#set_property -dict { PACKAGE_PIN G16 IOSTANDARD LVCMOS33 } [get_ports { jb[2] }]; #IO_L13N_T2_MRCC_15 Sch=jb[3]
#set_property -dict { PACKAGE_PIN H14 IOSTANDARD LVCMOS33 } [get_ports { jb[3] }]; #IO_L15P_T2_DQS_15 Sch=jb[4]
#set_property -dict { PACKAGE_PIN E16 IOSTANDARD LVCMOS33 } [get_ports { jb[4] }]; #IO_L11N_T1_SRCC_15 Sch=jb[7]
#set_property -dict { PACKAGE_PIN F13 IOSTANDARD LVCMOS33 } [get_ports { jb[5] }]; #IO_L5P_T0_AD9P_15 Sch=jb[8]
#set_property -dict { PACKAGE_PIN G13 IOSTANDARD LVCMOS33 } [get_ports { jb[6] }]; #IO_0_15 Sch=jb[9]
#set_property -dict { PACKAGE_PIN H16 IOSTANDARD LVCMOS33 } [get_ports { jb[7] }]; #IO_L13P_T2_MRCC_15 Sch=jb[10]
##Pmod Header JC
#set_property -dict { PACKAGE_PIN K1 IOSTANDARD LVCMOS33 } [get_ports { jc[0] }]; #IO_L23N_T3_35 Sch=jc[1]
#set_property -dict { PACKAGE_PIN F6 IOSTANDARD LVCMOS33 } [get_ports { jc[1] }]; #IO_L19N_T3_VREF_35 Sch=jc[2]
#set_property -dict { PACKAGE_PIN J2 IOSTANDARD LVCMOS33 } [get_ports { jc[2] }]; #IO_L22N_T3_35 Sch=jc[3]
#set_property -dict { PACKAGE_PIN G6 IOSTANDARD LVCMOS33 } [get_ports { jc[3] }]; #IO_L19P_T3_35 Sch=jc[4]
#set_property -dict { PACKAGE_PIN E7 IOSTANDARD LVCMOS33 } [get_ports { jc[4] }]; #IO_L6P_T0_35 Sch=jc[7]
#set_property -dict { PACKAGE_PIN J3 IOSTANDARD LVCMOS33 } [get_ports { jc[5] }]; #IO_L22P_T3_35 Sch=jc[8]
#set_property -dict { PACKAGE_PIN J4 IOSTANDARD LVCMOS33 } [get_ports { jc[6] }]; #IO_L21P_T3_DQS_35 Sch=jc[9]
#set_property -dict { PACKAGE_PIN E6 IOSTANDARD LVCMOS33 } [get_ports { jc[7] }]; #IO_L5P_T0_AD13P_35 Sch=jc[10]
##Pmod Header JD
#set_property -dict { PACKAGE_PIN H4 IOSTANDARD LVCMOS33 } [get_ports { jd[0] }]; #IO_L21N_T3_DQS_35 Sch=jd[1]
#set_property -dict { PACKAGE_PIN H1 IOSTANDARD LVCMOS33 } [get_ports { jd[1] }]; #IO_L17P_T2_35 Sch=jd[2]
#set_property -dict { PACKAGE_PIN G1 IOSTANDARD LVCMOS33 } [get_ports { jd[2] }]; #IO_L17N_T2_35 Sch=jd[3]
#set_property -dict { PACKAGE_PIN G3 IOSTANDARD LVCMOS33 } [get_ports { jd[3] }]; #IO_L20N_T3_35 Sch=jd[4]
#set_property -dict { PACKAGE_PIN H2 IOSTANDARD LVCMOS33 } [get_ports { jd[4] }]; #IO_L15P_T2_DQS_35 Sch=jd[7]
#set_property -dict { PACKAGE_PIN G4 IOSTANDARD LVCMOS33 } [get_ports { jd[5] }]; #IO_L20P_T3_35 Sch=jd[8]
#set_property -dict { PACKAGE_PIN G2 IOSTANDARD LVCMOS33 } [get_ports { jd[6] }]; #IO_L15N_T2_DQS_35 Sch=jd[9]
#set_property -dict { PACKAGE_PIN F3 IOSTANDARD LVCMOS33 } [get_ports { jd[7] }]; #IO_L13N_T2_MRCC_35 Sch=jd[10]
##Pmod Header JXADC
#set_property -dict { PACKAGE_PIN A14 IOSTANDARD LVDS } [get_ports { xa_n[0] }]; #IO_L9N_T1_DQS_AD3N_15 Sch=xa_n[1]
#set_property -dict { PACKAGE_PIN A13 IOSTANDARD LVDS } [get_ports { xa_p[0] }]; #IO_L9P_T1_DQS_AD3P_15 Sch=xa_p[1]
#set_property -dict { PACKAGE_PIN A16 IOSTANDARD LVDS } [get_ports { xa_n[1] }]; #IO_L8N_T1_AD10N_15 Sch=xa_n[2]
#set_property -dict { PACKAGE_PIN A15 IOSTANDARD LVDS } [get_ports { xa_p[1] }]; #IO_L8P_T1_AD10P_15 Sch=xa_p[2]
#set_property -dict { PACKAGE_PIN B17 IOSTANDARD LVDS } [get_ports { xa_n[2] }]; #IO_L7N_T1_AD2N_15 Sch=xa_n[3]
#set_property -dict { PACKAGE_PIN B16 IOSTANDARD LVDS } [get_ports { xa_p[2] }]; #IO_L7P_T1_AD2P_15 Sch=xa_p[3]
#set_property -dict { PACKAGE_PIN A18 IOSTANDARD LVDS } [get_ports { xa_n[3] }]; #IO_L10N_T1_AD11N_15 Sch=xa_n[4]
#set_property -dict { PACKAGE_PIN B18 IOSTANDARD LVDS } [get_ports { xa_p[3] }]; #IO_L10P_T1_AD11P_15 Sch=xa_p[4]
##VGA Connector
set_property -dict { PACKAGE_PIN A3 IOSTANDARD LVCMOS33 } [get_ports { vga_r[0] }]; #IO_L8N_T1_AD14N_35 Sch=vga_r[0]
set_property -dict { PACKAGE_PIN B4 IOSTANDARD LVCMOS33 } [get_ports { vga_r[1] }]; #IO_L7N_T1_AD6N_35 Sch=vga_r[1]
set_property -dict { PACKAGE_PIN C5 IOSTANDARD LVCMOS33 } [get_ports { vga_r[2] }]; #IO_L1N_T0_AD4N_35 Sch=vga_r[2]
set_property -dict { PACKAGE_PIN A4 IOSTANDARD LVCMOS33 } [get_ports { vga_r[3] }]; #IO_L8P_T1_AD14P_35 Sch=vga_r[3]
set_property -dict { PACKAGE_PIN C6 IOSTANDARD LVCMOS33 } [get_ports { vga_g[0] }]; #IO_L1P_T0_AD4P_35 Sch=vga_g[0]
set_property -dict { PACKAGE_PIN A5 IOSTANDARD LVCMOS33 } [get_ports { vga_g[1] }]; #IO_L3N_T0_DQS_AD5N_35 Sch=vga_g[1]
set_property -dict { PACKAGE_PIN B6 IOSTANDARD LVCMOS33 } [get_ports { vga_g[2] }]; #IO_L2N_T0_AD12N_35 Sch=vga_g[2]
set_property -dict { PACKAGE_PIN A6 IOSTANDARD LVCMOS33 } [get_ports { vga_g[3] }]; #IO_L3P_T0_DQS_AD5P_35 Sch=vga_g[3]
set_property -dict { PACKAGE_PIN B7 IOSTANDARD LVCMOS33 } [get_ports { vga_b[0] }]; #IO_L2P_T0_AD12P_35 Sch=vga_b[0]
set_property -dict { PACKAGE_PIN C7 IOSTANDARD LVCMOS33 } [get_ports { vga_b[1] }]; #IO_L4N_T0_35 Sch=vga_b[1]
set_property -dict { PACKAGE_PIN D7 IOSTANDARD LVCMOS33 } [get_ports { vga_b[2] }]; #IO_L6N_T0_VREF_35 Sch=vga_b[2]
set_property -dict { PACKAGE_PIN D8 IOSTANDARD LVCMOS33 } [get_ports { vga_b[3] }]; #IO_L4P_T0_35 Sch=vga_b[3]
set_property -dict { PACKAGE_PIN B11 IOSTANDARD LVCMOS33 } [get_ports { vga_hs }]; #IO_L4P_T0_15 Sch=vga_hs
set_property -dict { PACKAGE_PIN B12 IOSTANDARD LVCMOS33 } [get_ports { vga_vs }]; #IO_L3N_T0_DQS_AD1N_15 Sch=vga_vs
##Micro SD Connector
#set_property -dict { PACKAGE_PIN E2 IOSTANDARD LVCMOS33 } [get_ports { sd_reset }]; #IO_L14P_T2_SRCC_35 Sch=sd_reset
#set_property -dict { PACKAGE_PIN A1 IOSTANDARD LVCMOS33 } [get_ports { sd_cd }]; #IO_L9N_T1_DQS_AD7N_35 Sch=sd_cd
#set_property -dict { PACKAGE_PIN B1 IOSTANDARD LVCMOS33 } [get_ports { sd_sck }]; #IO_L9P_T1_DQS_AD7P_35 Sch=sd_sck
#set_property -dict { PACKAGE_PIN C1 IOSTANDARD LVCMOS33 } [get_ports { sd_cmd }]; #IO_L16N_T2_35 Sch=sd_cmd
#set_property -dict { PACKAGE_PIN C2 IOSTANDARD LVCMOS33 } [get_ports { sd_dat[0] }]; #IO_L16P_T2_35 Sch=sd_dat[0]
#set_property -dict { PACKAGE_PIN E1 IOSTANDARD LVCMOS33 } [get_ports { sd_dat[1] }]; #IO_L18N_T2_35 Sch=sd_dat[1]
#set_property -dict { PACKAGE_PIN F1 IOSTANDARD LVCMOS33 } [get_ports { sd_dat[2] }]; #IO_L18P_T2_35 Sch=sd_dat[2]
#set_property -dict { PACKAGE_PIN D2 IOSTANDARD LVCMOS33 } [get_ports { sd_dat[3] }]; #IO_L14N_T2_SRCC_35 Sch=sd_dat[3]
##Accelerometer
#set_property -dict { PACKAGE_PIN E15 IOSTANDARD LVCMOS33 } [get_ports { acl_miso }]; #IO_L11P_T1_SRCC_15 Sch=acl_miso
#set_property -dict { PACKAGE_PIN F14 IOSTANDARD LVCMOS33 } [get_ports { acl_mosi }]; #IO_L5N_T0_AD9N_15 Sch=acl_mosi
#set_property -dict { PACKAGE_PIN F15 IOSTANDARD LVCMOS33 } [get_ports { acl_sclk }]; #IO_L14P_T2_SRCC_15 Sch=acl_sclk
#set_property -dict { PACKAGE_PIN D15 IOSTANDARD LVCMOS33 } [get_ports { acl_csn }]; #IO_L12P_T1_MRCC_15 Sch=acl_csn
#set_property -dict { PACKAGE_PIN B13 IOSTANDARD LVCMOS33 } [get_ports { acl_int[1] }]; #IO_L2P_T0_AD8P_15 Sch=acl_int[1]
#set_property -dict { PACKAGE_PIN C16 IOSTANDARD LVCMOS33 } [get_ports { acl_int[2] }]; #IO_L20P_T3_A20_15 Sch=acl_int[2]
##Temperature Sensor
#set_property -dict { PACKAGE_PIN C14 IOSTANDARD LVCMOS33 } [get_ports { tmp_scl }]; #IO_L1N_T0_AD0N_15 Sch=tmp_scl
#set_property -dict { PACKAGE_PIN C15 IOSTANDARD LVCMOS33 } [get_ports { tmp_sda }]; #IO_L12N_T1_MRCC_15 Sch=tmp_sda
#set_property -dict { PACKAGE_PIN D13 IOSTANDARD LVCMOS33 } [get_ports { tmp_int }]; #IO_L6N_T0_VREF_15 Sch=tmp_int
#set_property -dict { PACKAGE_PIN B14 IOSTANDARD LVCMOS33 } [get_ports { tmp_ct }]; #IO_L2N_T0_AD8N_15 Sch=tmp_ct
##Omnidirectional Microphone
#set_property -dict { PACKAGE_PIN J5 IOSTANDARD LVCMOS33 } [get_ports { m_clk }]; #IO_25_35 Sch=m_clk
#set_property -dict { PACKAGE_PIN H5 IOSTANDARD LVCMOS33 } [get_ports { m_data }]; #IO_L24N_T3_35 Sch=m_data
#set_property -dict { PACKAGE_PIN F5 IOSTANDARD LVCMOS33 } [get_ports { m_lrsel }]; #IO_0_35 Sch=m_lrsel
##PWM Audio Amplifier
#set_property -dict { PACKAGE_PIN A11 IOSTANDARD LVCMOS33 } [get_ports { aud_pwm }]; #IO_L4N_T0_15 Sch=aud_pwm
#set_property -dict { PACKAGE_PIN D12 IOSTANDARD LVCMOS33 } [get_ports { aud_sd }]; #IO_L6P_T0_15 Sch=aud_sd
##USB-RS232 Interface
#set_property -dict { PACKAGE_PIN C4 IOSTANDARD LVCMOS33 } [get_ports { uart_txd_in }]; #IO_L7P_T1_AD6P_35 Sch=uart_txd_in
#set_property -dict { PACKAGE_PIN D4 IOSTANDARD LVCMOS33 } [get_ports { uart_rxd_out }]; #IO_L11N_T1_SRCC_35 Sch=uart_rxd_out
#set_property -dict { PACKAGE_PIN D3 IOSTANDARD LVCMOS33 } [get_ports { uart_cts }]; #IO_L12N_T1_MRCC_35 Sch=uart_cts
#set_property -dict { PACKAGE_PIN E5 IOSTANDARD LVCMOS33 } [get_ports { uart_rts }]; #IO_L5N_T0_AD13N_35 Sch=uart_rts
##USB HID (PS/2)
#set_property -dict { PACKAGE_PIN F4 IOSTANDARD LVCMOS33 } [get_ports { ps2_clk }]; #IO_L13P_T2_MRCC_35 Sch=ps2_clk
#set_property -dict { PACKAGE_PIN B2 IOSTANDARD LVCMOS33 } [get_ports { ps2_data }]; #IO_L10N_T1_AD15N_35 Sch=ps2_data
##SMSC Ethernet PHY
#set_property -dict { PACKAGE_PIN C9 IOSTANDARD LVCMOS33 } [get_ports { eth_mdc }]; #IO_L11P_T1_SRCC_16 Sch=eth_mdc
#set_property -dict { PACKAGE_PIN A9 IOSTANDARD LVCMOS33 } [get_ports { eth_mdio }]; #IO_L14N_T2_SRCC_16 Sch=eth_mdio
set_property -dict { PACKAGE_PIN B3 IOSTANDARD LVCMOS33 } [get_ports { eth_rstn }]; #IO_L10P_T1_AD15P_35 Sch=eth_rstn
set_property -dict { PACKAGE_PIN D9 IOSTANDARD LVCMOS33 } [get_ports { eth_crsdv }]; #IO_L6N_T0_VREF_16 Sch=eth_crsdv
#set_property -dict { PACKAGE_PIN C10 IOSTANDARD LVCMOS33 } [get_ports { eth_rxerr }]; #IO_L13N_T2_MRCC_16 Sch=eth_rxerr
set_property -dict { PACKAGE_PIN C11 IOSTANDARD LVCMOS33 } [get_ports { eth_rxd[0] }]; #IO_L13P_T2_MRCC_16 Sch=eth_rxd[0]
set_property -dict { PACKAGE_PIN D10 IOSTANDARD LVCMOS33 } [get_ports { eth_rxd[1] }]; #IO_L19N_T3_VREF_16 Sch=eth_rxd[1]
set_property -dict { PACKAGE_PIN B9 IOSTANDARD LVCMOS33 } [get_ports { eth_txen }]; #IO_L11N_T1_SRCC_16 Sch=eth_txen
set_property -dict { PACKAGE_PIN A10 IOSTANDARD LVCMOS33 } [get_ports { eth_txd[0] }]; #IO_L14P_T2_SRCC_16 Sch=eth_txd[0]
set_property -dict { PACKAGE_PIN A8 IOSTANDARD LVCMOS33 } [get_ports { eth_txd[1] }]; #IO_L12N_T1_MRCC_16 Sch=eth_txd[1]
set_property -dict { PACKAGE_PIN D5 IOSTANDARD LVCMOS33 } [get_ports { eth_refclk }]; #IO_L11P_T1_SRCC_35 Sch=eth_refclk
#set_property -dict { PACKAGE_PIN B8 IOSTANDARD LVCMOS33 } [get_ports { eth_intn }]; #IO_L12P_T1_MRCC_16 Sch=eth_intn
##Quad SPI Flash
#set_property -dict { PACKAGE_PIN K17 IOSTANDARD LVCMOS33 } [get_ports { qspi_dq[0] }]; #IO_L1P_T0_D00_MOSI_14 Sch=qspi_dq[0]
#set_property -dict { PACKAGE_PIN K18 IOSTANDARD LVCMOS33 } [get_ports { qspi_dq[1] }]; #IO_L1N_T0_D01_DIN_14 Sch=qspi_dq[1]
#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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 93 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 58 KiB

View File

@ -1,11 +0,0 @@
---
cores:
image_mem:
type: block_memory
width: 12
depth: 16384
uart:
port: "auto"
baudrate: 115200
clock_freq: 65000000

View File

@ -1,37 +0,0 @@
import sys
from PIL import Image, ImageOps
if __name__ == "__main__":
if len(sys.argv) < 2:
print("Usage: {0} <image to convert>".format(sys.argv[0]))
else:
input_fname = sys.argv[1]
image_in = Image.open(input_fname)
image_in = image_in.convert('RGB')
# Resize the image
image_in = image_in.resize((128, 128))
image_out = image_in.copy()
w, h = image_in.size
# Take input image and divide each color channel's value by 16
for y in range(h):
for x in range(w):
r, g, b = image_in.getpixel((x, y))
image_out.putpixel((x,y), (r//16, g//16, b//16))
# Save the image itself
pixels = []
for y in range(h):
for x in range(w):
(r, g, b) = image_out.getpixel((x,y))
color = (r*16*16) + (g*16) + (b)
pixels.append(color)
from manta import Manta
m = Manta('manta.yaml')
addrs = list(range(len(pixels)))
m.image_mem.write(addrs, pixels)

View File

@ -1,207 +0,0 @@
// file: clk_gen.v
//
// (c) Copyright 2008 - 2013 Xilinx, Inc. All rights reserved.
//
// This file contains confidential and proprietary information
// of Xilinx, Inc. and is protected under U.S. and
// international copyright and other intellectual property
// laws.
//
// DISCLAIMER
// This disclaimer is not a license and does not grant any
// rights to the materials distributed herewith. Except as
// otherwise provided in a valid license issued to you by
// Xilinx, and to the maximum extent permitted by applicable
// law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND
// WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES
// AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING
// BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-
// INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and
// (2) Xilinx shall not be liable (whether in contract or tort,
// including negligence, or under any other theory of
// liability) for any loss or damage of any kind or nature
// related to, arising under or in connection with these
// materials, including for any direct, or any indirect,
// special, incidental, or consequential loss or damage
// (including loss of data, profits, goodwill, or any type of
// loss or damage suffered as a result of any action brought
// by a third party) even if such damage or loss was
// reasonably foreseeable or Xilinx had been advised of the
// possibility of the same.
//
// CRITICAL APPLICATIONS
// Xilinx products are not designed or intended to be fail-
// safe, or for use in any application requiring fail-safe
// performance, such as life-support or safety devices or
// systems, Class III medical devices, nuclear facilities,
// applications related to the deployment of airbags, or any
// other applications that could lead to death, personal
// injury, or severe property or environmental damage
// (individually and collectively, "Critical
// Applications"). Customer assumes the sole risk and
// liability of any use of Xilinx products in Critical
// Applications, subject only to applicable laws and
// regulations governing limitations on product liability.
//
// THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS
// PART OF THIS FILE AT ALL TIMES.
//
//----------------------------------------------------------------------------
// User entered comments
//----------------------------------------------------------------------------
// None
//
//----------------------------------------------------------------------------
// Output Output Phase Duty Cycle Pk-to-Pk Phase
// Clock Freq (MHz) (degrees) (%) Jitter (ps) Error (ps)
//----------------------------------------------------------------------------
// clk_50mhz__50.00000______0.000______50.0______150.541_____99.281
// clk_65mhz__65.00000______0.000______50.0______142.278_____99.281
//
//----------------------------------------------------------------------------
// Input Clock Freq (MHz) Input Jitter (UI)
//----------------------------------------------------------------------------
// __primary_________100.000____________0.010
`timescale 1ps/1ps
module clk_gen
(// Clock in ports
// Clock out ports
output clk_50mhz,
output clk_65mhz,
input clk_100mhz
);
// Input buffering
//------------------------------------
wire clk_100mhz_clk_gen;
wire clk_in2_clk_gen;
IBUF clkin1_ibufg
(.O (clk_100mhz_clk_gen),
.I (clk_100mhz));
// Clocking PRIMITIVE
//------------------------------------
// Instantiation of the MMCM PRIMITIVE
// * Unused inputs are tied off
// * Unused outputs are labeled unused
wire clk_50mhz_clk_gen;
wire clk_65mhz_clk_gen;
wire clk_out3_clk_gen;
wire clk_out4_clk_gen;
wire clk_out5_clk_gen;
wire clk_out6_clk_gen;
wire clk_out7_clk_gen;
wire [15:0] do_unused;
wire drdy_unused;
wire psdone_unused;
wire locked_int;
wire clkfbout_clk_gen;
wire clkfbout_buf_clk_gen;
wire clkfboutb_unused;
wire clkout0b_unused;
wire clkout1b_unused;
wire clkout2_unused;
wire clkout2b_unused;
wire clkout3_unused;
wire clkout3b_unused;
wire clkout4_unused;
wire clkout5_unused;
wire clkout6_unused;
wire clkfbstopped_unused;
wire clkinstopped_unused;
MMCME2_ADV
#(.BANDWIDTH ("OPTIMIZED"),
.CLKOUT4_CASCADE ("FALSE"),
.COMPENSATION ("ZHOLD"),
.STARTUP_WAIT ("FALSE"),
.DIVCLK_DIVIDE (1),
.CLKFBOUT_MULT_F (9.750),
.CLKFBOUT_PHASE (0.000),
.CLKFBOUT_USE_FINE_PS ("FALSE"),
.CLKOUT0_DIVIDE_F (19.500),
.CLKOUT0_PHASE (0.000),
.CLKOUT0_DUTY_CYCLE (0.500),
.CLKOUT0_USE_FINE_PS ("FALSE"),
.CLKOUT1_DIVIDE (15),
.CLKOUT1_PHASE (0.000),
.CLKOUT1_DUTY_CYCLE (0.500),
.CLKOUT1_USE_FINE_PS ("FALSE"),
.CLKIN1_PERIOD (10.000))
mmcm_adv_inst
// Output clocks
(
.CLKFBOUT (clkfbout_clk_gen),
.CLKFBOUTB (clkfboutb_unused),
.CLKOUT0 (clk_50mhz_clk_gen),
.CLKOUT0B (clkout0b_unused),
.CLKOUT1 (clk_65mhz_clk_gen),
.CLKOUT1B (clkout1b_unused),
.CLKOUT2 (clkout2_unused),
.CLKOUT2B (clkout2b_unused),
.CLKOUT3 (clkout3_unused),
.CLKOUT3B (clkout3b_unused),
.CLKOUT4 (clkout4_unused),
.CLKOUT5 (clkout5_unused),
.CLKOUT6 (clkout6_unused),
// Input clock control
.CLKFBIN (clkfbout_buf_clk_gen),
.CLKIN1 (clk_100mhz_clk_gen),
.CLKIN2 (1'b0),
// Tied to always select the primary input clock
.CLKINSEL (1'b1),
// Ports for dynamic reconfiguration
.DADDR (7'h0),
.DCLK (1'b0),
.DEN (1'b0),
.DI (16'h0),
.DO (do_unused),
.DRDY (drdy_unused),
.DWE (1'b0),
// Ports for dynamic phase shift
.PSCLK (1'b0),
.PSEN (1'b0),
.PSINCDEC (1'b0),
.PSDONE (psdone_unused),
// Other control and status signals
.LOCKED (locked_int),
.CLKINSTOPPED (clkinstopped_unused),
.CLKFBSTOPPED (clkfbstopped_unused),
.PWRDWN (1'b0),
.RST (1'b0));
// Clock Monitor clock assigning
//--------------------------------------
// Output buffering
//-----------------------------------
BUFG clkf_buf
(.O (clkfbout_buf_clk_gen),
.I (clkfbout_clk_gen));
BUFG clkout1_buf
(.O (clk_50mhz),
.I (clk_50mhz_clk_gen));
BUFG clkout2_buf
(.O (clk_65mhz),
.I (clk_65mhz_clk_gen));
endmodule

View File

@ -1,96 +0,0 @@
`timescale 1ns / 1ps
`default_nettype none
module top_level (
input wire clk_100mhz,
input wire uart_txd_in,
output logic uart_rxd_out,
output logic [3:0] vga_r, vga_g, vga_b,
output logic vga_hs, vga_vs);
// Clock generation
logic clk_65mhz;
clk_gen gen(
.clk_100mhz(clk_100mhz),
.clk_50mhz(),
.clk_65mhz(clk_65mhz));
// VGA signals
logic [10:0] hcount;
logic [9:0] vcount;
logic hsync, vsync, blank;
vga vga_gen(
.pixel_clk_in(clk_65mhz),
.hcount_out(hcount),
.vcount_out(vcount),
.hsync_out(hsync),
.vsync_out(vsync),
.blank_out(blank));
// VGA Pipelining
reg[1:0][10:0] hcount_pipe;
reg[1:0][10:0] vcount_pipe;
reg[1:0] hsync_pipe;
reg[1:0] vsync_pipe;
reg[1:0] blank_pipe;
always_ff @(posedge clk_65mhz)begin
hcount_pipe[0] <= hcount;
vcount_pipe[0] <= vcount;
hsync_pipe[0] <= hsync;
vsync_pipe[0] <= vsync;
blank_pipe[0] <= blank;
for (int i=1; i<2; i = i+1)begin
hcount_pipe[i] <= hcount_pipe[i-1];
vcount_pipe[i] <= vcount_pipe[i-1];
hsync_pipe[i] <= hsync_pipe[i-1];
vsync_pipe[i] <= vsync_pipe[i-1];
blank_pipe[i] <= blank_pipe[i-1];
end
end
localparam WIDTH = 128;
localparam HEIGHT = 128;
localparam X = 0;
localparam Y = 0;
// calculate rom address
logic [$clog2(WIDTH*HEIGHT)-1:0] image_addr;
assign image_addr = (hcount - X) + ((vcount - Y) * WIDTH);
logic in_sprite;
assign in_sprite = ((hcount_pipe[1] >= X && hcount_pipe[1] < (X + WIDTH)) &&
(vcount_pipe[1] >= Y && vcount_pipe[1] < (Y + HEIGHT)));
manta manta_inst (
.clk(clk_65mhz),
.rx(uart_txd_in),
.tx(uart_rxd_out),
.image_mem_clk(clk_65mhz),
.image_mem_addr(image_addr),
.image_mem_din(),
.image_mem_dout(sprite_color),
.image_mem_we(1'b0));
logic [11:0] sprite_color;
logic [11:0] color;
assign color = in_sprite ? sprite_color : 12'h0;
// the following lines are required for the Nexys4 VGA circuit - do not change
assign vga_r = ~blank_pipe[1] ? color[11:8]: 0;
assign vga_g = ~blank_pipe[1] ? color[7:4] : 0;
assign vga_b = ~blank_pipe[1] ? color[3:0] : 0;
assign vga_hs = ~hsync_pipe[1];
assign vga_vs = ~vsync_pipe[1];
endmodule
`default_nettype wire

View File

@ -1,68 +0,0 @@
/* vga: Generate VGA display signals (1024 x 768 @ 60Hz)
*
* ---- HORIZONTAL ----- ------VERTICAL -----
* Active Active
* Freq Video FP Sync BP Video FP Sync BP
* 640x480, 60Hz 25.175 640 16 96 48 480 11 2 31
* 800x600, 60Hz 40.000 800 40 128 88 600 1 4 23
* 1024x768, 60Hz 65.000 1024 24 136 160 768 3 6 29
* 1280x1024, 60Hz 108.00 1280 48 112 248 768 1 3 38
* 1280x720p 60Hz 75.25 1280 72 80 216 720 3 5 30
* 1920x1080 60Hz 148.5 1920 88 44 148 1080 4 5 36
*
* change the clock frequency, front porches, sync's, and back porches to create
* other screen resolutions
*/
module vga(
input wire pixel_clk_in,
output logic [10:0] hcount_out, // pixel number on current line
output logic [9:0] vcount_out, // line number
output logic vsync_out, hsync_out,
output logic blank_out);
parameter DISPLAY_WIDTH = 1024; // display width
parameter DISPLAY_HEIGHT = 768; // number of lines
parameter H_FP = 24; // horizontal front porch
parameter H_SYNC_PULSE = 136; // horizontal sync
parameter H_BP = 160; // horizontal back porch
parameter V_FP = 3; // vertical front porch
parameter V_SYNC_PULSE = 6; // vertical sync
parameter V_BP = 29; // vertical back porch
// horizontal: 1344 pixels total
// display 1024 pixels per line
logic hblank,vblank;
logic hsyncon,hsyncoff,hreset,hblankon;
assign hblankon = (hcount_out == (DISPLAY_WIDTH -1));
assign hsyncon = (hcount_out == (DISPLAY_WIDTH + H_FP - 1)); //1047
assign hsyncoff = (hcount_out == (DISPLAY_WIDTH + H_FP + H_SYNC_PULSE - 1)); // 1183
assign hreset = (hcount_out == (DISPLAY_WIDTH + H_FP + H_SYNC_PULSE + H_BP - 1)); //1343
// vertical: 806 lines total
// display 768 lines
logic vsyncon,vsyncoff,vreset,vblankon;
assign vblankon = hreset & (vcount_out == (DISPLAY_HEIGHT - 1)); // 767
assign vsyncon = hreset & (vcount_out == (DISPLAY_HEIGHT + V_FP - 1)); // 771
assign vsyncoff = hreset & (vcount_out == (DISPLAY_HEIGHT + V_FP + V_SYNC_PULSE - 1)); // 777
assign vreset = hreset & (vcount_out == (DISPLAY_HEIGHT + V_FP + V_SYNC_PULSE + V_BP - 1)); // 805
// sync and blanking
logic next_hblank,next_vblank;
assign next_hblank = hreset ? 0 : hblankon ? 1 : hblank;
assign next_vblank = vreset ? 0 : vblankon ? 1 : vblank;
always_ff @(posedge pixel_clk_in) begin
hcount_out <= hreset ? 0 : hcount_out + 1;
hblank <= next_hblank;
hsync_out <= hsyncon ? 0 : hsyncoff ? 1 : hsync_out; // active low
vcount_out <= hreset ? (vreset ? 0 : vcount_out + 1) : vcount_out;
vblank <= next_vblank;
vsync_out <= vsyncon ? 0 : vsyncoff ? 1 : vsync_out; // active low
blank_out <= next_vblank | (next_hblank & ~hreset);
end
endmodule

View File

@ -1,253 +0,0 @@
## This file is a general .xdc for the Nexys4 DDR Rev. C
## To use it in a project:
## - uncomment the lines corresponding to used pins
## - rename the used ports (in each line, after get_ports) according to the top level signal names in the project
## This file has been modified from the default .xdc provided by Digilent for the Nexys A7
## Clock signal
set_property -dict { PACKAGE_PIN E3 IOSTANDARD LVCMOS33 } [get_ports { clk_100mhz }]; #IO_L12P_T1_MRCC_35 Sch=clk_100mhz
create_clock -add -name sys_clk_pin -period 10.00 -waveform {0 5} [get_ports {clk_100mhz}];
##Switches
#set_property -dict { PACKAGE_PIN J15 IOSTANDARD LVCMOS33 } [get_ports { sw[0] }]; #IO_L24N_T3_RS0_15 Sch=sw[0]
#set_property -dict { PACKAGE_PIN L16 IOSTANDARD LVCMOS33 } [get_ports { sw[1] }]; #IO_L3N_T0_DQS_EMCCLK_14 Sch=sw[1]
#set_property -dict { PACKAGE_PIN M13 IOSTANDARD LVCMOS33 } [get_ports { sw[2] }]; #IO_L6N_T0_D08_VREF_14 Sch=sw[2]
#set_property -dict { PACKAGE_PIN R15 IOSTANDARD LVCMOS33 } [get_ports { sw[3] }]; #IO_L13N_T2_MRCC_14 Sch=sw[3]
#set_property -dict { PACKAGE_PIN R17 IOSTANDARD LVCMOS33 } [get_ports { sw[4] }]; #IO_L12N_T1_MRCC_14 Sch=sw[4]
#set_property -dict { PACKAGE_PIN T18 IOSTANDARD LVCMOS33 } [get_ports { sw[5] }]; #IO_L7N_T1_D10_14 Sch=sw[5]
#set_property -dict { PACKAGE_PIN U18 IOSTANDARD LVCMOS33 } [get_ports { sw[6] }]; #IO_L17N_T2_A13_D29_14 Sch=sw[6]
#set_property -dict { PACKAGE_PIN R13 IOSTANDARD LVCMOS33 } [get_ports { sw[7] }]; #IO_L5N_T0_D07_14 Sch=sw[7]
#set_property -dict { PACKAGE_PIN T8 IOSTANDARD LVCMOS18 } [get_ports { sw[8] }]; #IO_L24N_T3_34 Sch=sw[8]
#set_property -dict { PACKAGE_PIN U8 IOSTANDARD LVCMOS18 } [get_ports { sw[9] }]; #IO_25_34 Sch=sw[9]
#set_property -dict { PACKAGE_PIN R16 IOSTANDARD LVCMOS33 } [get_ports { sw[10] }]; #IO_L15P_T2_DQS_RDWR_B_14 Sch=sw[10]
#set_property -dict { PACKAGE_PIN T13 IOSTANDARD LVCMOS33 } [get_ports { sw[11] }]; #IO_L23P_T3_A03_D19_14 Sch=sw[11]
#set_property -dict { PACKAGE_PIN H6 IOSTANDARD LVCMOS33 } [get_ports { sw[12] }]; #IO_L24P_T3_35 Sch=sw[12]
#set_property -dict { PACKAGE_PIN U12 IOSTANDARD LVCMOS33 } [get_ports { sw[13] }]; #IO_L20P_T3_A08_D24_14 Sch=sw[13]
#set_property -dict { PACKAGE_PIN U11 IOSTANDARD LVCMOS33 } [get_ports { sw[14] }]; #IO_L19N_T3_A09_D25_VREF_14 Sch=sw[14]
#set_property -dict { PACKAGE_PIN V10 IOSTANDARD LVCMOS33 } [get_ports { sw[15] }]; #IO_L21P_T3_DQS_14 Sch=sw[15]
## LEDs
#set_property -dict { PACKAGE_PIN H17 IOSTANDARD LVCMOS33 } [get_ports { led[0] }]; #IO_L18P_T2_A24_15 Sch=led[0]
#set_property -dict { PACKAGE_PIN K15 IOSTANDARD LVCMOS33 } [get_ports { led[1] }]; #IO_L24P_T3_RS1_15 Sch=led[1]
#set_property -dict { PACKAGE_PIN J13 IOSTANDARD LVCMOS33 } [get_ports { led[2] }]; #IO_L17N_T2_A25_15 Sch=led[2]
#set_property -dict { PACKAGE_PIN N14 IOSTANDARD LVCMOS33 } [get_ports { led[3] }]; #IO_L8P_T1_D11_14 Sch=led[3]
#set_property -dict { PACKAGE_PIN R18 IOSTANDARD LVCMOS33 } [get_ports { led[4] }]; #IO_L7P_T1_D09_14 Sch=led[4]
#set_property -dict { PACKAGE_PIN V17 IOSTANDARD LVCMOS33 } [get_ports { led[5] }]; #IO_L18N_T2_A11_D27_14 Sch=led[5]
#set_property -dict { PACKAGE_PIN U17 IOSTANDARD LVCMOS33 } [get_ports { led[6] }]; #IO_L17P_T2_A14_D30_14 Sch=led[6]
#set_property -dict { PACKAGE_PIN U16 IOSTANDARD LVCMOS33 } [get_ports { led[7] }]; #IO_L18P_T2_A12_D28_14 Sch=led[7]
#set_property -dict { PACKAGE_PIN V16 IOSTANDARD LVCMOS33 } [get_ports { led[8] }]; #IO_L16N_T2_A15_D31_14 Sch=led[8]
#set_property -dict { PACKAGE_PIN T15 IOSTANDARD LVCMOS33 } [get_ports { led[9] }]; #IO_L14N_T2_SRCC_14 Sch=led[9]
#set_property -dict { PACKAGE_PIN U14 IOSTANDARD LVCMOS33 } [get_ports { led[10] }]; #IO_L22P_T3_A05_D21_14 Sch=led[10]
#set_property -dict { PACKAGE_PIN T16 IOSTANDARD LVCMOS33 } [get_ports { led[11] }]; #IO_L15N_T2_DQS_DOUT_CSO_B_14 Sch=led[11]
#set_property -dict { PACKAGE_PIN V15 IOSTANDARD LVCMOS33 } [get_ports { led[12] }]; #IO_L16P_T2_CSI_B_14 Sch=led[12]
#set_property -dict { PACKAGE_PIN V14 IOSTANDARD LVCMOS33 } [get_ports { led[13] }]; #IO_L22N_T3_A04_D20_14 Sch=led[13]
#set_property -dict { PACKAGE_PIN V12 IOSTANDARD LVCMOS33 } [get_ports { led[14] }]; #IO_L20N_T3_A07_D23_14 Sch=led[14]
#set_property -dict { PACKAGE_PIN V11 IOSTANDARD LVCMOS33 } [get_ports { led[15] }]; #IO_L21N_T3_DQS_A06_D22_14 Sch=led[15]
#set_property -dict { PACKAGE_PIN R12 IOSTANDARD LVCMOS33 } [get_ports { led16_b }]; #IO_L5P_T0_D06_14 Sch=led16_b
#set_property -dict { PACKAGE_PIN M16 IOSTANDARD LVCMOS33 } [get_ports { led16_g }]; #IO_L10P_T1_D14_14 Sch=led16_g
#set_property -dict { PACKAGE_PIN N15 IOSTANDARD LVCMOS33 } [get_ports { led16_r }]; #IO_L11P_T1_SRCC_14 Sch=led16_r
#set_property -dict { PACKAGE_PIN G14 IOSTANDARD LVCMOS33 } [get_ports { led17_b }]; #IO_L15N_T2_DQS_ADV_B_15 Sch=led17_b
#set_property -dict { PACKAGE_PIN R11 IOSTANDARD LVCMOS33 } [get_ports { led17_g }]; #IO_0_14 Sch=led17_g
#set_property -dict { PACKAGE_PIN N16 IOSTANDARD LVCMOS33 } [get_ports { led17_r }]; #IO_L11N_T1_SRCC_14 Sch=led17_r
##7 segment display
#set_property -dict { PACKAGE_PIN T10 IOSTANDARD LVCMOS33 } [get_ports { ca }]; #IO_L24N_T3_A00_D16_14 Sch=ca
#set_property -dict { PACKAGE_PIN R10 IOSTANDARD LVCMOS33 } [get_ports { cb }]; #IO_25_14 Sch=cb
#set_property -dict { PACKAGE_PIN K16 IOSTANDARD LVCMOS33 } [get_ports { cc }]; #IO_25_15 Sch=cc
#set_property -dict { PACKAGE_PIN K13 IOSTANDARD LVCMOS33 } [get_ports { cd }]; #IO_L17P_T2_A26_15 Sch=cd
#set_property -dict { PACKAGE_PIN P15 IOSTANDARD LVCMOS33 } [get_ports { ce }]; #IO_L13P_T2_MRCC_14 Sch=ce
#set_property -dict { PACKAGE_PIN T11 IOSTANDARD LVCMOS33 } [get_ports { cf }]; #IO_L19P_T3_A10_D26_14 Sch=cf
#set_property -dict { PACKAGE_PIN L18 IOSTANDARD LVCMOS33 } [get_ports { cg }]; #IO_L4P_T0_D04_14 Sch=cg
#set_property -dict { PACKAGE_PIN H15 IOSTANDARD LVCMOS33 } [get_ports { dp }]; #IO_L19N_T3_A21_VREF_15 Sch=dp
#set_property -dict { PACKAGE_PIN J17 IOSTANDARD LVCMOS33 } [get_ports { an[0] }]; #IO_L23P_T3_FOE_B_15 Sch=an[0]
#set_property -dict { PACKAGE_PIN J18 IOSTANDARD LVCMOS33 } [get_ports { an[1] }]; #IO_L23N_T3_FWE_B_15 Sch=an[1]
#set_property -dict { PACKAGE_PIN T9 IOSTANDARD LVCMOS33 } [get_ports { an[2] }]; #IO_L24P_T3_A01_D17_14 Sch=an[2]
#set_property -dict { PACKAGE_PIN J14 IOSTANDARD LVCMOS33 } [get_ports { an[3] }]; #IO_L19P_T3_A22_15 Sch=an[3]
#set_property -dict { PACKAGE_PIN P14 IOSTANDARD LVCMOS33 } [get_ports { an[4] }]; #IO_L8N_T1_D12_14 Sch=an[4]
#set_property -dict { PACKAGE_PIN T14 IOSTANDARD LVCMOS33 } [get_ports { an[5] }]; #IO_L14P_T2_SRCC_14 Sch=an[5]
#set_property -dict { PACKAGE_PIN K2 IOSTANDARD LVCMOS33 } [get_ports { an[6] }]; #IO_L23P_T3_35 Sch=an[6]
#set_property -dict { PACKAGE_PIN U13 IOSTANDARD LVCMOS33 } [get_ports { an[7] }]; #IO_L23N_T3_A02_D18_14 Sch=an[7]
##Buttons
#set_property -dict { PACKAGE_PIN C12 IOSTANDARD LVCMOS33 } [get_ports { cpu_resetn }]; #IO_L3P_T0_DQS_AD1P_15 Sch=cpu_resetn
#set_property -dict { PACKAGE_PIN N17 IOSTANDARD LVCMOS33 } [get_ports { btnc }]; #IO_L9P_T1_DQS_14 Sch=btnc
#set_property -dict { PACKAGE_PIN M18 IOSTANDARD LVCMOS33 } [get_ports { btnu }]; #IO_L4N_T0_D05_14 Sch=btnu
#set_property -dict { PACKAGE_PIN P17 IOSTANDARD LVCMOS33 } [get_ports { btnl }]; #IO_L12P_T1_MRCC_14 Sch=btnl
#set_property -dict { PACKAGE_PIN M17 IOSTANDARD LVCMOS33 } [get_ports { btnr }]; #IO_L10N_T1_D15_14 Sch=btnr
#set_property -dict { PACKAGE_PIN P18 IOSTANDARD LVCMOS33 } [get_ports { btnd }]; #IO_L9N_T1_DQS_D13_14 Sch=btnd
##Pmod Headers
##Pmod Header JA
#set_property -dict { PACKAGE_PIN C17 IOSTANDARD LVCMOS33 } [get_ports { ja[0] }]; #IO_L20N_T3_A19_15 Sch=ja[1]
#set_property -dict { PACKAGE_PIN D18 IOSTANDARD LVCMOS33 } [get_ports { ja[1] }]; #IO_L21N_T3_DQS_A18_15 Sch=ja[2]
#set_property -dict { PACKAGE_PIN E18 IOSTANDARD LVCMOS33 } [get_ports { ja[2] }]; #IO_L21P_T3_DQS_15 Sch=ja[3]
#set_property -dict { PACKAGE_PIN G17 IOSTANDARD LVCMOS33 } [get_ports { ja[3] }]; #IO_L18N_T2_A23_15 Sch=ja[4]
#set_property -dict { PACKAGE_PIN D17 IOSTANDARD LVCMOS33 } [get_ports { ja[4] }]; #IO_L16N_T2_A27_15 Sch=ja[7]
#set_property -dict { PACKAGE_PIN E17 IOSTANDARD LVCMOS33 } [get_ports { ja[5] }]; #IO_L16P_T2_A28_15 Sch=ja[8]
#set_property -dict { PACKAGE_PIN F18 IOSTANDARD LVCMOS33 } [get_ports { ja[6] }]; #IO_L22N_T3_A16_15 Sch=ja[9]
#set_property -dict { PACKAGE_PIN G18 IOSTANDARD LVCMOS33 } [get_ports { ja[7] }]; #IO_L22P_T3_A17_15 Sch=ja[10]
##Pmod Header JB
#set_property -dict { PACKAGE_PIN D14 IOSTANDARD LVCMOS33 } [get_ports { jb[0] }]; #IO_L1P_T0_AD0P_15 Sch=jb[1]
#set_property -dict { PACKAGE_PIN F16 IOSTANDARD LVCMOS33 } [get_ports { jb[1] }]; #IO_L14N_T2_SRCC_15 Sch=jb[2]
#set_property -dict { PACKAGE_PIN G16 IOSTANDARD LVCMOS33 } [get_ports { jb[2] }]; #IO_L13N_T2_MRCC_15 Sch=jb[3]
#set_property -dict { PACKAGE_PIN H14 IOSTANDARD LVCMOS33 } [get_ports { jb[3] }]; #IO_L15P_T2_DQS_15 Sch=jb[4]
#set_property -dict { PACKAGE_PIN E16 IOSTANDARD LVCMOS33 } [get_ports { jb[4] }]; #IO_L11N_T1_SRCC_15 Sch=jb[7]
#set_property -dict { PACKAGE_PIN F13 IOSTANDARD LVCMOS33 } [get_ports { jb[5] }]; #IO_L5P_T0_AD9P_15 Sch=jb[8]
#set_property -dict { PACKAGE_PIN G13 IOSTANDARD LVCMOS33 } [get_ports { jb[6] }]; #IO_0_15 Sch=jb[9]
#set_property -dict { PACKAGE_PIN H16 IOSTANDARD LVCMOS33 } [get_ports { jb[7] }]; #IO_L13P_T2_MRCC_15 Sch=jb[10]
##Pmod Header JC
#set_property -dict { PACKAGE_PIN K1 IOSTANDARD LVCMOS33 } [get_ports { jc[0] }]; #IO_L23N_T3_35 Sch=jc[1]
#set_property -dict { PACKAGE_PIN F6 IOSTANDARD LVCMOS33 } [get_ports { jc[1] }]; #IO_L19N_T3_VREF_35 Sch=jc[2]
#set_property -dict { PACKAGE_PIN J2 IOSTANDARD LVCMOS33 } [get_ports { jc[2] }]; #IO_L22N_T3_35 Sch=jc[3]
#set_property -dict { PACKAGE_PIN G6 IOSTANDARD LVCMOS33 } [get_ports { jc[3] }]; #IO_L19P_T3_35 Sch=jc[4]
#set_property -dict { PACKAGE_PIN E7 IOSTANDARD LVCMOS33 } [get_ports { jc[4] }]; #IO_L6P_T0_35 Sch=jc[7]
#set_property -dict { PACKAGE_PIN J3 IOSTANDARD LVCMOS33 } [get_ports { jc[5] }]; #IO_L22P_T3_35 Sch=jc[8]
#set_property -dict { PACKAGE_PIN J4 IOSTANDARD LVCMOS33 } [get_ports { jc[6] }]; #IO_L21P_T3_DQS_35 Sch=jc[9]
#set_property -dict { PACKAGE_PIN E6 IOSTANDARD LVCMOS33 } [get_ports { jc[7] }]; #IO_L5P_T0_AD13P_35 Sch=jc[10]
##Pmod Header JD
#set_property -dict { PACKAGE_PIN H4 IOSTANDARD LVCMOS33 } [get_ports { jd[0] }]; #IO_L21N_T3_DQS_35 Sch=jd[1]
#set_property -dict { PACKAGE_PIN H1 IOSTANDARD LVCMOS33 } [get_ports { jd[1] }]; #IO_L17P_T2_35 Sch=jd[2]
#set_property -dict { PACKAGE_PIN G1 IOSTANDARD LVCMOS33 } [get_ports { jd[2] }]; #IO_L17N_T2_35 Sch=jd[3]
#set_property -dict { PACKAGE_PIN G3 IOSTANDARD LVCMOS33 } [get_ports { jd[3] }]; #IO_L20N_T3_35 Sch=jd[4]
#set_property -dict { PACKAGE_PIN H2 IOSTANDARD LVCMOS33 } [get_ports { jd[4] }]; #IO_L15P_T2_DQS_35 Sch=jd[7]
#set_property -dict { PACKAGE_PIN G4 IOSTANDARD LVCMOS33 } [get_ports { jd[5] }]; #IO_L20P_T3_35 Sch=jd[8]
#set_property -dict { PACKAGE_PIN G2 IOSTANDARD LVCMOS33 } [get_ports { jd[6] }]; #IO_L15N_T2_DQS_35 Sch=jd[9]
#set_property -dict { PACKAGE_PIN F3 IOSTANDARD LVCMOS33 } [get_ports { jd[7] }]; #IO_L13N_T2_MRCC_35 Sch=jd[10]
##Pmod Header JXADC
#set_property -dict { PACKAGE_PIN A14 IOSTANDARD LVDS } [get_ports { xa_n[0] }]; #IO_L9N_T1_DQS_AD3N_15 Sch=xa_n[1]
#set_property -dict { PACKAGE_PIN A13 IOSTANDARD LVDS } [get_ports { xa_p[0] }]; #IO_L9P_T1_DQS_AD3P_15 Sch=xa_p[1]
#set_property -dict { PACKAGE_PIN A16 IOSTANDARD LVDS } [get_ports { xa_n[1] }]; #IO_L8N_T1_AD10N_15 Sch=xa_n[2]
#set_property -dict { PACKAGE_PIN A15 IOSTANDARD LVDS } [get_ports { xa_p[1] }]; #IO_L8P_T1_AD10P_15 Sch=xa_p[2]
#set_property -dict { PACKAGE_PIN B17 IOSTANDARD LVDS } [get_ports { xa_n[2] }]; #IO_L7N_T1_AD2N_15 Sch=xa_n[3]
#set_property -dict { PACKAGE_PIN B16 IOSTANDARD LVDS } [get_ports { xa_p[2] }]; #IO_L7P_T1_AD2P_15 Sch=xa_p[3]
#set_property -dict { PACKAGE_PIN A18 IOSTANDARD LVDS } [get_ports { xa_n[3] }]; #IO_L10N_T1_AD11N_15 Sch=xa_n[4]
#set_property -dict { PACKAGE_PIN B18 IOSTANDARD LVDS } [get_ports { xa_p[3] }]; #IO_L10P_T1_AD11P_15 Sch=xa_p[4]
##VGA Connector
set_property -dict { PACKAGE_PIN A3 IOSTANDARD LVCMOS33 } [get_ports { vga_r[0] }]; #IO_L8N_T1_AD14N_35 Sch=vga_r[0]
set_property -dict { PACKAGE_PIN B4 IOSTANDARD LVCMOS33 } [get_ports { vga_r[1] }]; #IO_L7N_T1_AD6N_35 Sch=vga_r[1]
set_property -dict { PACKAGE_PIN C5 IOSTANDARD LVCMOS33 } [get_ports { vga_r[2] }]; #IO_L1N_T0_AD4N_35 Sch=vga_r[2]
set_property -dict { PACKAGE_PIN A4 IOSTANDARD LVCMOS33 } [get_ports { vga_r[3] }]; #IO_L8P_T1_AD14P_35 Sch=vga_r[3]
set_property -dict { PACKAGE_PIN C6 IOSTANDARD LVCMOS33 } [get_ports { vga_g[0] }]; #IO_L1P_T0_AD4P_35 Sch=vga_g[0]
set_property -dict { PACKAGE_PIN A5 IOSTANDARD LVCMOS33 } [get_ports { vga_g[1] }]; #IO_L3N_T0_DQS_AD5N_35 Sch=vga_g[1]
set_property -dict { PACKAGE_PIN B6 IOSTANDARD LVCMOS33 } [get_ports { vga_g[2] }]; #IO_L2N_T0_AD12N_35 Sch=vga_g[2]
set_property -dict { PACKAGE_PIN A6 IOSTANDARD LVCMOS33 } [get_ports { vga_g[3] }]; #IO_L3P_T0_DQS_AD5P_35 Sch=vga_g[3]
set_property -dict { PACKAGE_PIN B7 IOSTANDARD LVCMOS33 } [get_ports { vga_b[0] }]; #IO_L2P_T0_AD12P_35 Sch=vga_b[0]
set_property -dict { PACKAGE_PIN C7 IOSTANDARD LVCMOS33 } [get_ports { vga_b[1] }]; #IO_L4N_T0_35 Sch=vga_b[1]
set_property -dict { PACKAGE_PIN D7 IOSTANDARD LVCMOS33 } [get_ports { vga_b[2] }]; #IO_L6N_T0_VREF_35 Sch=vga_b[2]
set_property -dict { PACKAGE_PIN D8 IOSTANDARD LVCMOS33 } [get_ports { vga_b[3] }]; #IO_L4P_T0_35 Sch=vga_b[3]
set_property -dict { PACKAGE_PIN B11 IOSTANDARD LVCMOS33 } [get_ports { vga_hs }]; #IO_L4P_T0_15 Sch=vga_hs
set_property -dict { PACKAGE_PIN B12 IOSTANDARD LVCMOS33 } [get_ports { vga_vs }]; #IO_L3N_T0_DQS_AD1N_15 Sch=vga_vs
##Micro SD Connector
#set_property -dict { PACKAGE_PIN E2 IOSTANDARD LVCMOS33 } [get_ports { sd_reset }]; #IO_L14P_T2_SRCC_35 Sch=sd_reset
#set_property -dict { PACKAGE_PIN A1 IOSTANDARD LVCMOS33 } [get_ports { sd_cd }]; #IO_L9N_T1_DQS_AD7N_35 Sch=sd_cd
#set_property -dict { PACKAGE_PIN B1 IOSTANDARD LVCMOS33 } [get_ports { sd_sck }]; #IO_L9P_T1_DQS_AD7P_35 Sch=sd_sck
#set_property -dict { PACKAGE_PIN C1 IOSTANDARD LVCMOS33 } [get_ports { sd_cmd }]; #IO_L16N_T2_35 Sch=sd_cmd
#set_property -dict { PACKAGE_PIN C2 IOSTANDARD LVCMOS33 } [get_ports { sd_dat[0] }]; #IO_L16P_T2_35 Sch=sd_dat[0]
#set_property -dict { PACKAGE_PIN E1 IOSTANDARD LVCMOS33 } [get_ports { sd_dat[1] }]; #IO_L18N_T2_35 Sch=sd_dat[1]
#set_property -dict { PACKAGE_PIN F1 IOSTANDARD LVCMOS33 } [get_ports { sd_dat[2] }]; #IO_L18P_T2_35 Sch=sd_dat[2]
#set_property -dict { PACKAGE_PIN D2 IOSTANDARD LVCMOS33 } [get_ports { sd_dat[3] }]; #IO_L14N_T2_SRCC_35 Sch=sd_dat[3]
##Accelerometer
#set_property -dict { PACKAGE_PIN E15 IOSTANDARD LVCMOS33 } [get_ports { acl_miso }]; #IO_L11P_T1_SRCC_15 Sch=acl_miso
#set_property -dict { PACKAGE_PIN F14 IOSTANDARD LVCMOS33 } [get_ports { acl_mosi }]; #IO_L5N_T0_AD9N_15 Sch=acl_mosi
#set_property -dict { PACKAGE_PIN F15 IOSTANDARD LVCMOS33 } [get_ports { acl_sclk }]; #IO_L14P_T2_SRCC_15 Sch=acl_sclk
#set_property -dict { PACKAGE_PIN D15 IOSTANDARD LVCMOS33 } [get_ports { acl_csn }]; #IO_L12P_T1_MRCC_15 Sch=acl_csn
#set_property -dict { PACKAGE_PIN B13 IOSTANDARD LVCMOS33 } [get_ports { acl_int[1] }]; #IO_L2P_T0_AD8P_15 Sch=acl_int[1]
#set_property -dict { PACKAGE_PIN C16 IOSTANDARD LVCMOS33 } [get_ports { acl_int[2] }]; #IO_L20P_T3_A20_15 Sch=acl_int[2]
##Temperature Sensor
#set_property -dict { PACKAGE_PIN C14 IOSTANDARD LVCMOS33 } [get_ports { tmp_scl }]; #IO_L1N_T0_AD0N_15 Sch=tmp_scl
#set_property -dict { PACKAGE_PIN C15 IOSTANDARD LVCMOS33 } [get_ports { tmp_sda }]; #IO_L12N_T1_MRCC_15 Sch=tmp_sda
#set_property -dict { PACKAGE_PIN D13 IOSTANDARD LVCMOS33 } [get_ports { tmp_int }]; #IO_L6N_T0_VREF_15 Sch=tmp_int
#set_property -dict { PACKAGE_PIN B14 IOSTANDARD LVCMOS33 } [get_ports { tmp_ct }]; #IO_L2N_T0_AD8N_15 Sch=tmp_ct
##Omnidirectional Microphone
#set_property -dict { PACKAGE_PIN J5 IOSTANDARD LVCMOS33 } [get_ports { m_clk }]; #IO_25_35 Sch=m_clk
#set_property -dict { PACKAGE_PIN H5 IOSTANDARD LVCMOS33 } [get_ports { m_data }]; #IO_L24N_T3_35 Sch=m_data
#set_property -dict { PACKAGE_PIN F5 IOSTANDARD LVCMOS33 } [get_ports { m_lrsel }]; #IO_0_35 Sch=m_lrsel
##PWM Audio Amplifier
#set_property -dict { PACKAGE_PIN A11 IOSTANDARD LVCMOS33 } [get_ports { aud_pwm }]; #IO_L4N_T0_15 Sch=aud_pwm
#set_property -dict { PACKAGE_PIN D12 IOSTANDARD LVCMOS33 } [get_ports { aud_sd }]; #IO_L6P_T0_15 Sch=aud_sd
##USB-RS232 Interface
set_property -dict { PACKAGE_PIN C4 IOSTANDARD LVCMOS33 } [get_ports { uart_txd_in }]; #IO_L7P_T1_AD6P_35 Sch=uart_txd_in
set_property -dict { PACKAGE_PIN D4 IOSTANDARD LVCMOS33 } [get_ports { uart_rxd_out }]; #IO_L11N_T1_SRCC_35 Sch=uart_rxd_out
#set_property -dict { PACKAGE_PIN D3 IOSTANDARD LVCMOS33 } [get_ports { uart_cts }]; #IO_L12N_T1_MRCC_35 Sch=uart_cts
#set_property -dict { PACKAGE_PIN E5 IOSTANDARD LVCMOS33 } [get_ports { uart_rts }]; #IO_L5N_T0_AD13N_35 Sch=uart_rts
##USB HID (PS/2)
#set_property -dict { PACKAGE_PIN F4 IOSTANDARD LVCMOS33 } [get_ports { ps2_clk }]; #IO_L13P_T2_MRCC_35 Sch=ps2_clk
#set_property -dict { PACKAGE_PIN B2 IOSTANDARD LVCMOS33 } [get_ports { ps2_data }]; #IO_L10N_T1_AD15N_35 Sch=ps2_data
##SMSC Ethernet PHY
#set_property -dict { PACKAGE_PIN C9 IOSTANDARD LVCMOS33 } [get_ports { eth_mdc }]; #IO_L11P_T1_SRCC_16 Sch=eth_mdc
#set_property -dict { PACKAGE_PIN A9 IOSTANDARD LVCMOS33 } [get_ports { eth_mdio }]; #IO_L14N_T2_SRCC_16 Sch=eth_mdio
#set_property -dict { PACKAGE_PIN B3 IOSTANDARD LVCMOS33 } [get_ports { eth_rstn }]; #IO_L10P_T1_AD15P_35 Sch=eth_rstn
#set_property -dict { PACKAGE_PIN D9 IOSTANDARD LVCMOS33 } [get_ports { eth_crsdv }]; #IO_L6N_T0_VREF_16 Sch=eth_crsdv
#set_property -dict { PACKAGE_PIN C10 IOSTANDARD LVCMOS33 } [get_ports { eth_rxerr }]; #IO_L13N_T2_MRCC_16 Sch=eth_rxerr
#set_property -dict { PACKAGE_PIN C11 IOSTANDARD LVCMOS33 } [get_ports { eth_rxd[0] }]; #IO_L13P_T2_MRCC_16 Sch=eth_rxd[0]
#set_property -dict { PACKAGE_PIN D10 IOSTANDARD LVCMOS33 } [get_ports { eth_rxd[1] }]; #IO_L19N_T3_VREF_16 Sch=eth_rxd[1]
#set_property -dict { PACKAGE_PIN B9 IOSTANDARD LVCMOS33 } [get_ports { eth_txen }]; #IO_L11N_T1_SRCC_16 Sch=eth_txen
#set_property -dict { PACKAGE_PIN A10 IOSTANDARD LVCMOS33 } [get_ports { eth_txd[0] }]; #IO_L14P_T2_SRCC_16 Sch=eth_txd[0]
#set_property -dict { PACKAGE_PIN A8 IOSTANDARD LVCMOS33 } [get_ports { eth_txd[1] }]; #IO_L12N_T1_MRCC_16 Sch=eth_txd[1]
#set_property -dict { PACKAGE_PIN D5 IOSTANDARD LVCMOS33 } [get_ports { eth_refclk }]; #IO_L11P_T1_SRCC_35 Sch=eth_refclk
#set_property -dict { PACKAGE_PIN B8 IOSTANDARD LVCMOS33 } [get_ports { eth_intn }]; #IO_L12P_T1_MRCC_16 Sch=eth_intn
##Quad SPI Flash
#set_property -dict { PACKAGE_PIN K17 IOSTANDARD LVCMOS33 } [get_ports { qspi_dq[0] }]; #IO_L1P_T0_D00_MOSI_14 Sch=qspi_dq[0]
#set_property -dict { PACKAGE_PIN K18 IOSTANDARD LVCMOS33 } [get_ports { qspi_dq[1] }]; #IO_L1N_T0_D01_DIN_14 Sch=qspi_dq[1]
#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

View File

@ -0,0 +1 @@
!top_level.sv

View File

@ -0,0 +1,16 @@
from manta import Manta
from time import sleep
manta = Manta("manta.yaml")
i = 0
while True:
# Turn each LED off
for j in range(5):
manta.my_io_core.set_probe(f"LED{j}", 0)
# Turn one LED back on
manta.my_io_core.set_probe(f"LED{i}", 1)
i = (i + 1) % 5
sleep(0.1)

View File

@ -0,0 +1,4 @@
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

View File

@ -11,6 +11,6 @@ cores:
LED4: 1
uart:
port: "auto"
port: "/dev/ttyUSB3"
baudrate: 115200
clock_freq: 12000000

View File

@ -18,6 +18,7 @@ module top_level (
manta manta_inst (
.clk(clk),
.rst(0),
.rx(rs232_rx_ttl),
.tx(rs232_tx_ttl),

View File

@ -0,0 +1 @@
!top_level.sv

View File

@ -0,0 +1,4 @@
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

View File

@ -0,0 +1,19 @@
---
cores:
my_logic_analyzer:
type: logic_analyzer
sample_depth: 256
probes:
probe0: 1
probe1: 4
probe2: 8
probe3: 16
triggers:
- probe2 EQ 3
uart:
port: "/dev/ttyUSB3"
baudrate: 115200
clock_freq: 12000000

View File

@ -0,0 +1,67 @@
# Generic iCEstick placement constraints file
# Red LEDs
set_io LED0 99
set_io LED1 98
set_io LED2 97
set_io LED3 96
# Green LED
set_io LED4 95
# IrDA port
#set_io RXD 106
#set_io TXD 105
#set_io SD 107
# Pmod connector
#set_io PIO1_02 78 # Pin 1
#set_io PIO1_03 79 # Pin 2
#set_io PIO1_04 80 # Pin 3
#set_io PIO1_05 81 # Pin 4
#set_io PIO1_06 87 # Pin 7
#set_io PIO1_07 88 # Pin 8
#set_io PIO1_08 90 # Pin 9
#set_io PIO1_09 91 # Pin 10
# Connector J1
#set_io PIO0_02 112 # Pin 3
#set_io PIO0_03 113 # Pin 4
#set_io PIO0_04 114 # Pin 5
#set_io PIO0_05 115 # Pin 6
#set_io PIO0_06 116 # Pin 7
#set_io PIO0_07 117 # Pin 8
#set_io PIO0_08 118 # Pin 9
#set_io PIO0_09 119 # Pin 10
# Connector J3
#set_io PIO2_17 62 # Pin 3
#set_io PIO2_16 61 # Pin 4
#set_io PIO2_15 60 # Pin 5
#set_io PIO2_14 56 # Pin 6
#set_io PIO2_13 48 # Pin 7
#set_io PIO2_12 47 # Pin 8
#set_io PIO2_11 45 # Pin 9
#set_io PIO2_10 44 # Pin 10
# FTDI Port B UART
#set_io DCDn 1
#set_io DSRn 2
#set_io DTRn 3
#set_io CTSn 4
#set_io RTSn 7
set_io rs232_tx_ttl 8
set_io rs232_rx_ttl 9
# SPI
#set_io SPI_SCK 70
#set_io SPI_SI 68
#set_io SPI_SO 67
#set_io SPI_SS_B 71
# Configuration pins
#set_io CDONE 65
#set_io CRESET_B 66
# 12 MHz clock
set_io clk 21

View File

@ -0,0 +1,38 @@
`default_nettype none
`timescale 1ns / 1ps
`include "manta.v"
module top_level (
input wire clk,
input wire rs232_rx_ttl,
output logic rs232_tx_ttl
);
logic probe0;
logic [3:0] probe1;
logic [7:0] probe2;
logic [15:0] probe3;
always @(posedge clk) begin
probe0 <= probe0 + 1;
probe1 <= probe1 + 1;
probe2 <= probe2 + 1;
probe3 <= probe3 + 1;
end
manta manta_inst (
.clk(clk),
.rst(0),
.rx(rs232_rx_ttl),
.tx(rs232_tx_ttl),
.probe0(probe0),
.probe1(probe1),
.probe2(probe2),
.probe3(probe3));
endmodule
`default_nettype wire

View File

@ -0,0 +1 @@
!top_level.sv

View File

@ -0,0 +1,3 @@
python3 -m manta gen manta.yaml manta.v
mkdir -p build/
$VIVADO -mode batch -source build.tcl

View File

@ -1,10 +1,10 @@
#!/usr/bin/tclsh
set partNum xc7a100tcsg324-1
set outputDir obj
set outputDir build
read_verilog -sv [ glob ./src/*.{sv,v,svh,vh} ]
read_xdc ./xdc/top_level.xdc
read_verilog -sv [ glob *.{sv,v,svh,vh} ]
read_xdc top_level.xdc
set_part $partNum
@ -25,7 +25,6 @@ report_timing_summary -file $outputDir/post_place_timing_summary.rpt
report_timing -file $outputDir/post_place_timing.rpt
# route design and generate bitstream
route_design -directive Explore
write_bitstream -force $outputDir/out.bit

View File

@ -0,0 +1,12 @@
---
cores:
my_memory:
type: memory
mode: host_to_fpga
width: 16
depth: 1024
uart:
port: "/dev/ttyUSB1"
baudrate: 115200
clock_freq: 100000000

View File

@ -3,6 +3,8 @@
module top_level (
input wire clk,
input wire [15:0] sw,
output logic [15:0] led,
input wire uart_txd_in,
output logic uart_rxd_out);
@ -13,11 +15,8 @@ module top_level (
.rx(uart_txd_in),
.tx(uart_rxd_out),
.my_block_memory_clk(clk),
.my_block_memory_addr(0),
.my_block_memory_din(0),
.my_block_memory_dout(),
.my_block_memory_we(0));
.user_addr(sw),
.user_data_out(led));
endmodule

View File

@ -11,42 +11,42 @@ create_clock -add -name sys_clk_pin -period 10.00 -waveform {0 5} [get_ports {cl
##Switches
#set_property -dict { PACKAGE_PIN J15 IOSTANDARD LVCMOS33 } [get_ports { sw[0] }]; #IO_L24N_T3_RS0_15 Sch=sw[0]
#set_property -dict { PACKAGE_PIN L16 IOSTANDARD LVCMOS33 } [get_ports { sw[1] }]; #IO_L3N_T0_DQS_EMCCLK_14 Sch=sw[1]
#set_property -dict { PACKAGE_PIN M13 IOSTANDARD LVCMOS33 } [get_ports { sw[2] }]; #IO_L6N_T0_D08_VREF_14 Sch=sw[2]
#set_property -dict { PACKAGE_PIN R15 IOSTANDARD LVCMOS33 } [get_ports { sw[3] }]; #IO_L13N_T2_MRCC_14 Sch=sw[3]
#set_property -dict { PACKAGE_PIN R17 IOSTANDARD LVCMOS33 } [get_ports { sw[4] }]; #IO_L12N_T1_MRCC_14 Sch=sw[4]
#set_property -dict { PACKAGE_PIN T18 IOSTANDARD LVCMOS33 } [get_ports { sw[5] }]; #IO_L7N_T1_D10_14 Sch=sw[5]
#set_property -dict { PACKAGE_PIN U18 IOSTANDARD LVCMOS33 } [get_ports { sw[6] }]; #IO_L17N_T2_A13_D29_14 Sch=sw[6]
#set_property -dict { PACKAGE_PIN R13 IOSTANDARD LVCMOS33 } [get_ports { sw[7] }]; #IO_L5N_T0_D07_14 Sch=sw[7]
#set_property -dict { PACKAGE_PIN T8 IOSTANDARD LVCMOS18 } [get_ports { sw[8] }]; #IO_L24N_T3_34 Sch=sw[8]
#set_property -dict { PACKAGE_PIN U8 IOSTANDARD LVCMOS18 } [get_ports { sw[9] }]; #IO_25_34 Sch=sw[9]
#set_property -dict { PACKAGE_PIN R16 IOSTANDARD LVCMOS33 } [get_ports { sw[10] }]; #IO_L15P_T2_DQS_RDWR_B_14 Sch=sw[10]
#set_property -dict { PACKAGE_PIN T13 IOSTANDARD LVCMOS33 } [get_ports { sw[11] }]; #IO_L23P_T3_A03_D19_14 Sch=sw[11]
#set_property -dict { PACKAGE_PIN H6 IOSTANDARD LVCMOS33 } [get_ports { sw[12] }]; #IO_L24P_T3_35 Sch=sw[12]
#set_property -dict { PACKAGE_PIN U12 IOSTANDARD LVCMOS33 } [get_ports { sw[13] }]; #IO_L20P_T3_A08_D24_14 Sch=sw[13]
#set_property -dict { PACKAGE_PIN U11 IOSTANDARD LVCMOS33 } [get_ports { sw[14] }]; #IO_L19N_T3_A09_D25_VREF_14 Sch=sw[14]
#set_property -dict { PACKAGE_PIN V10 IOSTANDARD LVCMOS33 } [get_ports { sw[15] }]; #IO_L21P_T3_DQS_14 Sch=sw[15]
set_property -dict { PACKAGE_PIN J15 IOSTANDARD LVCMOS33 } [get_ports { sw[0] }]; #IO_L24N_T3_RS0_15 Sch=sw[0]
set_property -dict { PACKAGE_PIN L16 IOSTANDARD LVCMOS33 } [get_ports { sw[1] }]; #IO_L3N_T0_DQS_EMCCLK_14 Sch=sw[1]
set_property -dict { PACKAGE_PIN M13 IOSTANDARD LVCMOS33 } [get_ports { sw[2] }]; #IO_L6N_T0_D08_VREF_14 Sch=sw[2]
set_property -dict { PACKAGE_PIN R15 IOSTANDARD LVCMOS33 } [get_ports { sw[3] }]; #IO_L13N_T2_MRCC_14 Sch=sw[3]
set_property -dict { PACKAGE_PIN R17 IOSTANDARD LVCMOS33 } [get_ports { sw[4] }]; #IO_L12N_T1_MRCC_14 Sch=sw[4]
set_property -dict { PACKAGE_PIN T18 IOSTANDARD LVCMOS33 } [get_ports { sw[5] }]; #IO_L7N_T1_D10_14 Sch=sw[5]
set_property -dict { PACKAGE_PIN U18 IOSTANDARD LVCMOS33 } [get_ports { sw[6] }]; #IO_L17N_T2_A13_D29_14 Sch=sw[6]
set_property -dict { PACKAGE_PIN R13 IOSTANDARD LVCMOS33 } [get_ports { sw[7] }]; #IO_L5N_T0_D07_14 Sch=sw[7]
set_property -dict { PACKAGE_PIN T8 IOSTANDARD LVCMOS18 } [get_ports { sw[8] }]; #IO_L24N_T3_34 Sch=sw[8]
set_property -dict { PACKAGE_PIN U8 IOSTANDARD LVCMOS18 } [get_ports { sw[9] }]; #IO_25_34 Sch=sw[9]
set_property -dict { PACKAGE_PIN R16 IOSTANDARD LVCMOS33 } [get_ports { sw[10] }]; #IO_L15P_T2_DQS_RDWR_B_14 Sch=sw[10]
set_property -dict { PACKAGE_PIN T13 IOSTANDARD LVCMOS33 } [get_ports { sw[11] }]; #IO_L23P_T3_A03_D19_14 Sch=sw[11]
set_property -dict { PACKAGE_PIN H6 IOSTANDARD LVCMOS33 } [get_ports { sw[12] }]; #IO_L24P_T3_35 Sch=sw[12]
set_property -dict { PACKAGE_PIN U12 IOSTANDARD LVCMOS33 } [get_ports { sw[13] }]; #IO_L20P_T3_A08_D24_14 Sch=sw[13]
set_property -dict { PACKAGE_PIN U11 IOSTANDARD LVCMOS33 } [get_ports { sw[14] }]; #IO_L19N_T3_A09_D25_VREF_14 Sch=sw[14]
set_property -dict { PACKAGE_PIN V10 IOSTANDARD LVCMOS33 } [get_ports { sw[15] }]; #IO_L21P_T3_DQS_14 Sch=sw[15]
## LEDs
#set_property -dict { PACKAGE_PIN H17 IOSTANDARD LVCMOS33 } [get_ports { led[0] }]; #IO_L18P_T2_A24_15 Sch=led[0]
#set_property -dict { PACKAGE_PIN K15 IOSTANDARD LVCMOS33 } [get_ports { led[1] }]; #IO_L24P_T3_RS1_15 Sch=led[1]
#set_property -dict { PACKAGE_PIN J13 IOSTANDARD LVCMOS33 } [get_ports { led[2] }]; #IO_L17N_T2_A25_15 Sch=led[2]
#set_property -dict { PACKAGE_PIN N14 IOSTANDARD LVCMOS33 } [get_ports { led[3] }]; #IO_L8P_T1_D11_14 Sch=led[3]
#set_property -dict { PACKAGE_PIN R18 IOSTANDARD LVCMOS33 } [get_ports { led[4] }]; #IO_L7P_T1_D09_14 Sch=led[4]
#set_property -dict { PACKAGE_PIN V17 IOSTANDARD LVCMOS33 } [get_ports { led[5] }]; #IO_L18N_T2_A11_D27_14 Sch=led[5]
#set_property -dict { PACKAGE_PIN U17 IOSTANDARD LVCMOS33 } [get_ports { led[6] }]; #IO_L17P_T2_A14_D30_14 Sch=led[6]
#set_property -dict { PACKAGE_PIN U16 IOSTANDARD LVCMOS33 } [get_ports { led[7] }]; #IO_L18P_T2_A12_D28_14 Sch=led[7]
#set_property -dict { PACKAGE_PIN V16 IOSTANDARD LVCMOS33 } [get_ports { led[8] }]; #IO_L16N_T2_A15_D31_14 Sch=led[8]
#set_property -dict { PACKAGE_PIN T15 IOSTANDARD LVCMOS33 } [get_ports { led[9] }]; #IO_L14N_T2_SRCC_14 Sch=led[9]
#set_property -dict { PACKAGE_PIN U14 IOSTANDARD LVCMOS33 } [get_ports { led[10] }]; #IO_L22P_T3_A05_D21_14 Sch=led[10]
#set_property -dict { PACKAGE_PIN T16 IOSTANDARD LVCMOS33 } [get_ports { led[11] }]; #IO_L15N_T2_DQS_DOUT_CSO_B_14 Sch=led[11]
#set_property -dict { PACKAGE_PIN V15 IOSTANDARD LVCMOS33 } [get_ports { led[12] }]; #IO_L16P_T2_CSI_B_14 Sch=led[12]
#set_property -dict { PACKAGE_PIN V14 IOSTANDARD LVCMOS33 } [get_ports { led[13] }]; #IO_L22N_T3_A04_D20_14 Sch=led[13]
#set_property -dict { PACKAGE_PIN V12 IOSTANDARD LVCMOS33 } [get_ports { led[14] }]; #IO_L20N_T3_A07_D23_14 Sch=led[14]
#set_property -dict { PACKAGE_PIN V11 IOSTANDARD LVCMOS33 } [get_ports { led[15] }]; #IO_L21N_T3_DQS_A06_D22_14 Sch=led[15]
set_property -dict { PACKAGE_PIN H17 IOSTANDARD LVCMOS33 } [get_ports { led[0] }]; #IO_L18P_T2_A24_15 Sch=led[0]
set_property -dict { PACKAGE_PIN K15 IOSTANDARD LVCMOS33 } [get_ports { led[1] }]; #IO_L24P_T3_RS1_15 Sch=led[1]
set_property -dict { PACKAGE_PIN J13 IOSTANDARD LVCMOS33 } [get_ports { led[2] }]; #IO_L17N_T2_A25_15 Sch=led[2]
set_property -dict { PACKAGE_PIN N14 IOSTANDARD LVCMOS33 } [get_ports { led[3] }]; #IO_L8P_T1_D11_14 Sch=led[3]
set_property -dict { PACKAGE_PIN R18 IOSTANDARD LVCMOS33 } [get_ports { led[4] }]; #IO_L7P_T1_D09_14 Sch=led[4]
set_property -dict { PACKAGE_PIN V17 IOSTANDARD LVCMOS33 } [get_ports { led[5] }]; #IO_L18N_T2_A11_D27_14 Sch=led[5]
set_property -dict { PACKAGE_PIN U17 IOSTANDARD LVCMOS33 } [get_ports { led[6] }]; #IO_L17P_T2_A14_D30_14 Sch=led[6]
set_property -dict { PACKAGE_PIN U16 IOSTANDARD LVCMOS33 } [get_ports { led[7] }]; #IO_L18P_T2_A12_D28_14 Sch=led[7]
set_property -dict { PACKAGE_PIN V16 IOSTANDARD LVCMOS33 } [get_ports { led[8] }]; #IO_L16N_T2_A15_D31_14 Sch=led[8]
set_property -dict { PACKAGE_PIN T15 IOSTANDARD LVCMOS33 } [get_ports { led[9] }]; #IO_L14N_T2_SRCC_14 Sch=led[9]
set_property -dict { PACKAGE_PIN U14 IOSTANDARD LVCMOS33 } [get_ports { led[10] }]; #IO_L22P_T3_A05_D21_14 Sch=led[10]
set_property -dict { PACKAGE_PIN T16 IOSTANDARD LVCMOS33 } [get_ports { led[11] }]; #IO_L15N_T2_DQS_DOUT_CSO_B_14 Sch=led[11]
set_property -dict { PACKAGE_PIN V15 IOSTANDARD LVCMOS33 } [get_ports { led[12] }]; #IO_L16P_T2_CSI_B_14 Sch=led[12]
set_property -dict { PACKAGE_PIN V14 IOSTANDARD LVCMOS33 } [get_ports { led[13] }]; #IO_L22N_T3_A04_D20_14 Sch=led[13]
set_property -dict { PACKAGE_PIN V12 IOSTANDARD LVCMOS33 } [get_ports { led[14] }]; #IO_L20N_T3_A07_D23_14 Sch=led[14]
set_property -dict { PACKAGE_PIN V11 IOSTANDARD LVCMOS33 } [get_ports { led[15] }]; #IO_L21N_T3_DQS_A06_D22_14 Sch=led[15]
#set_property -dict { PACKAGE_PIN R12 IOSTANDARD LVCMOS33 } [get_ports { led16_b }]; #IO_L5P_T0_D06_14 Sch=led16_b
#set_property -dict { PACKAGE_PIN M16 IOSTANDARD LVCMOS33 } [get_ports { led16_g }]; #IO_L10P_T1_D14_14 Sch=led16_g

View File

@ -0,0 +1,8 @@
from manta import Manta
m = Manta("manta.yaml")
# Memory addresses can be written to in Python, and then be read out by
# flipping the switches on the FPGA, and watching the LEDs update!
m.my_memory.write(0, 1)

View File

@ -0,0 +1 @@
!top_level.sv

View File

@ -0,0 +1,25 @@
from manta import Manta
from time import sleep
from random import randint
m = Manta("manta.yaml")
i = 0
while True:
i = (i + 1) % 16
m.my_io_core.set_probe("led", 2**i)
m.my_io_core.set_probe("led16_r", randint(0, 1))
m.my_io_core.set_probe("led16_g", randint(0, 1))
m.my_io_core.set_probe("led16_b", randint(0, 1))
print(f'Switches: {m.my_io_core.get_probe("sw")}')
print(f"Buttons:")
print(f'btnu: {m.my_io_core.get_probe("btnu")}')
print(f'btnd: {m.my_io_core.get_probe("btnd")}')
print(f'btnr: {m.my_io_core.get_probe("btnr")}')
print(f'btnl: {m.my_io_core.get_probe("btnl")}')
print(f'btnc: {m.my_io_core.get_probe("btnc")}')
print("")
sleep(0.1)

View File

@ -0,0 +1,3 @@
python3 -m manta gen manta.yaml manta.v
mkdir -p build/
$VIVADO -mode batch -source build.tcl

View File

@ -0,0 +1,36 @@
#!/usr/bin/tclsh
set partNum xc7a100tcsg324-1
set outputDir build
read_verilog -sv [ glob *.{sv,v,svh,vh} ]
read_xdc top_level.xdc
set_part $partNum
# synth
synth_design -top top_level -part $partNum -verbose
report_utilization -file $outputDir/post_synth_util.rpt
report_timing_summary -file $outputDir/post_synth_timing_summary.rpt
report_timing -file $outputDir/post_synth_timing.rpt
# place
opt_design
place_design
phys_opt_design
report_utilization -file $outputDir/post_place_util.rpt
report_clock_utilization -file $outputDir/clock_util.rpt
report_timing_summary -file $outputDir/post_place_timing_summary.rpt
report_timing -file $outputDir/post_place_timing.rpt
# route design and generate bitstream
route_design -directive Explore
write_bitstream -force $outputDir/out.bit
report_route_status -file $outputDir/post_route_status.rpt
report_timing_summary -file $outputDir/post_route_timing_summary.rpt
report_timing -file $outputDir/post_route_timing.rpt
report_power -file $outputDir/post_route_power.rpt
report_drc -file $outputDir/post_imp_drc.rpt
write_verilog -force $outputDir/cpu_impl_netlist.v -mode timesim -sdf_anno true

View File

@ -21,6 +21,6 @@ cores:
led17_r: 1
uart:
port: "auto"
port: "/dev/ttyUSB1"
baudrate: 115200
clock_freq: 100000000

View File

@ -25,6 +25,7 @@ module top_level (
manta manta_inst (
.clk(clk),
.rst(0),
.rx(uart_txd_in),
.tx(uart_rxd_out),

View File

@ -0,0 +1,2 @@
!top_level.sv
!divider.sv

View File

@ -0,0 +1,3 @@
python3 -m manta gen manta.yaml manta.v
mkdir -p build/
$VIVADO -mode batch -source build.tcl

View File

@ -0,0 +1,36 @@
#!/usr/bin/tclsh
set partNum xc7a100tcsg324-1
set outputDir build
read_verilog -sv [ glob *.{sv,v,svh,vh} ]
read_xdc top_level.xdc
set_part $partNum
# synth
synth_design -top top_level -part $partNum -verbose
report_utilization -file $outputDir/post_synth_util.rpt
report_timing_summary -file $outputDir/post_synth_timing_summary.rpt
report_timing -file $outputDir/post_synth_timing.rpt
# place
opt_design
place_design
phys_opt_design
report_utilization -file $outputDir/post_place_util.rpt
report_clock_utilization -file $outputDir/clock_util.rpt
report_timing_summary -file $outputDir/post_place_timing_summary.rpt
report_timing -file $outputDir/post_place_timing.rpt
# route design and generate bitstream
route_design -directive Explore
write_bitstream -force $outputDir/out.bit
report_route_status -file $outputDir/post_route_status.rpt
report_timing_summary -file $outputDir/post_route_timing_summary.rpt
report_timing -file $outputDir/post_route_timing.rpt
report_power -file $outputDir/post_route_power.rpt
report_drc -file $outputDir/post_imp_drc.rpt
write_verilog -force $outputDir/cpu_impl_netlist.v -mode timesim -sdf_anno true

Some files were not shown because too many files have changed in this diff Show More