Sample projects

These projects demonstrate how to use Topwrap on a practical level, with examples based on a variety of useful designs.

Embedded GUI

This section extensively uses an embedded version of Topwrap’s GUI to visualize the design of all the examples.

You can use it to explore designs, while adding new blocks, connections, nodes and hierarchies.

The features that require direct connection with Topwrap’s backend are not implemented in this demo version, including:

  • saving and loading data in .yaml files

  • building designs

  • verifying designs

Tip

Don’t forget to use the “Enable fullscreen” button if the viewport is too small.

_images/kpm_button_fullscreen.png

Constant

Link to source

This example shows how to assign a constant value to a port in an IP core. You can see it in the GUI by using the interactive preview functionality. It is also visible in the description file (project.yaml).

Tip

You can find the constant node blueprint in the nodes browser within the Metanode section.

Usage

Switch to the subdirectory with the example:

cd examples/constant

Generate the HDL source:

make generate

Inout

Link to source

This example showcases the usage of an inout port and its representation in the GUI.

Tip

An inout port is marked in the GUI by a green circle without a directional arrow inside.

The design consists of 3 modules: input buffer ibuf, output buffer obuf, and bidirectional buffer iobuf. Their operation can be described as:

  • the input buffer is a synchronous D-type flip flop with an asynchronous reset

  • the output buffer is a synchronous D-type flip flop with an asynchronous reset and an output enable, which sets the output to a high impedance state (Hi-Z)

  • the inout buffer instantiates 1 input and 1 output buffer. The input of the ibuf and output of the obuf are connected with an inout wire (port).

Usage

Switch to the subdirectory with the example:

cd examples/inout

Install the required dependencies:

pip install -r requirements.txt

To generate the bitstream for Zynq, use:

make

To generate only the HDL sources use:

make generate

User repository

Link to source

This example presents the structure of a user repository containing prepackaged IP cores with sources and custom interface definitions.

Elements of the repo directory can be easily reused in different designs by linking to them from the config file or in the CLI.

See also

For more information about user repositories see this chapter.

Tip

As other components of the design are automatically imported from the repository, it’s possible to load the entire example by specifying the design file:

topwrap gui -d project.yml

Usage

Navigate to the /examples/user_repository/ directory and run:

topwrap gui -d project.yml

Expected result

Topwrap will load two cores from the cores directory, using the interface from the interfaces directory.

In the Nodes browser under IPcore, two loaded cores: core1 and core2, should be visible.

Hierarchy

Link to source

This example shows how to create a hierarchical design in Topwrap, including a hierarchy that contains IP cores as well as other nested hierarchies.

Check out project.yaml to learn how the above design translates to a design description file

See also

For more information, see the section on Hierarchies.

Tip

Hierarchies are represented in the GUI by nodes with a green header. To display inner designs, click the Edit subgraph option from the context menu.

To exit from the hierarchy subgraph, use the back arrow button on the top left. To add a new hierarchy node, use the New Graph Node option in the node browser.

Usage

This example contains the user repository (repo directory) and a configuration file for Topwrap (topwrap.yaml). It can be loaded by entering the examples directory, and running:

topwrap gui -d project.yaml

PWM

Link to source

Tip

The IP core in the center of the design (axi_axil_adapter) showcases how IP cores with overridable parameters are represented in the GUI.

This is an example of an AXI-mapped PWM IP core that can be generated with LiteX, connected to the ZYNQ Processing System. The core uses the AXILite interface, so a AXI -> AXILite converter is needed. You can access its registers starting from address 0x4000000 (the base address of AXI_GP0 on ZYNQ). The generated signal can be used in a FPGA or connected to a physical port on a board.

Note

To connect I/O signals to specific FPGA pins, you must use mappings in a constraints file. See zynq.xdc used in the setup and modify it accordingly.

Usage

Switch to the subdirectory with the example:

cd examples/pwm

Install the required dependencies:

pip install -r requirements.txt

Note

In order to generate a bitstream, install Vivado and add it to the PATH.

To generate bitstream for Zynq, use:

make

To generate HDL sources without running Vivado, use:

make generate

HDMI

Link to source

This is an example of how to use Topwrap to build a complex and synthesizable design.

Usage

Switch to the subdirectory with the example:

cd examples/hdmi

Install the required dependencies:

pip install -r requirements.txt

Note

In order to generate a bitstream, install Vivado and add it to the PATH.

Generate bitstream for desired target

Snickerdoodle Black:

make snickerdoodle

Zynq Video Board:

make zvb

To generate HDL sources without running Vivado, use:

make generate

SoC

Link to source

This is an example of how to use Topwrap to build a synthesizable SoC design. The SoC contains a VexRiscv core, data and instruction memory, UART and an interconnect that ties all the components together.

Usage

Switch to the subdirectory with the example:

cd examples/soc

Install the required dependencies:

sudo apt install git make g++ ninja-build gcc-riscv64-unknown-elf bsdextrautils

Note

To run the simulation, you need:

  • verilator

To create and load the bitstream, use:

  • Vivado (preferably version 2020.2).

  • openFPGALoader (branch)

Generate HDL sources:

make generate

Build and run the simulation:

make sim

The expected waveform generated by the simulation is shown in expected-waveform.svg.

Generate the bitstream:

make bitstream

Last update: 2024-12-10