Duplicate an Existing Register Map

It’s now possible to duplicate an existing register map in airhdl.

For that, just click on the “Duplicate register map” link at the bottom of the register maps list:


This will bring up the “Duplicate register map” dialog, where you can select which register map you’d like to clone:


The freshly created register map has the same name as the original one, but with a “- COPY” suffix:


Of course, as register map names are not allowed to contains spaces and dashes, that’s not a valid identifier. So you will need to to rename it by selecting the “edit register map” function in the register map overview:


And then changing its name to a valid identifier:


If you like watching videos, here’s a short demonstration of the “duplicate register map” feature:

Amazon F1 Register File Creation with airhdl

Here’s a short video showing how you can use airhdl to quickly generate a SystemVerilog AXI4-Lite register file for use in your Amazon F1 Custom Logic (CL).

There’s nothing to install or license. Just register for free to airhdl, create your register map in the browser, and download the generated SystemVerilog module. Does it get any simpler than that?

Understanding Register Map Revisions

The latest airhdl update adds register map revisions, an important feature for checking the consistency of generated files like C headers and VHDL/SystemVerilog components.

Each register map now has a revision number, which airhdl manages internally. When you create a new register map, its revision number is initialized to zero. Then, every time you change anything in that register map (e.g. a register or a field), the revision number is automatically incremented.

You can see a register map’s current revision number in the register map view:


The revision number also appears in the header of every generated file. Thus, you now have an easy way to check that your generated files all correspond to the same register map revision. Just compare the numbers in the headers.

Here’s what it looks like in the VHDL header:


Even better, it’s possible to automate that consistency check, i.e. have the C driver check that it uses the same register map revision as the VHDL/SystemVerilog register component it is talking to.

For that, C headers now have a new symbol called


We’ve also added that constant to the VHDL and SystemVerilog packages, which makes it really easy to create a read-only “Revision” register that returns the value of the revision number.

All you have to do is create a “value” field in that register and drive the corresponding input port using the constant mentioned above. That way, the C driver can read the register, and compare its value with the revision number it sees in the C header. In case they don’t match, you have an inconsistency between the register definitions in the C header and the actual implementation in the RTL code.

Here’s how you would map the revision number constant to a field called “value” in a register called “reg_revision”:



Shiny and New: Self-Clearing Fields

For driving things like “clear” or “latch-enable” signals in the user logic, it often comes in  handy to have register fields that automatically reset themselves to zero after one clock cycle. That way, writing a one to a single-bit field has the effect of generating a single-cycle pulse on the corresponding user logic port.

The good news is, airhdl now supports self-clearing fields.

To create a new field, and make it self-clearing, just check the corresponding checkbox at the bottom of the “New Field” dialog:


Of course, it’s also possible to turn existing fields into self-clearing ones. For that, click on the “edit field” icon of the field in question:


This will bring-up the “Edit Field” dialog where you’ll also find the “Self-clearing” checkbox mentioned above.

In the fields list, self-clearing fields are clearly identified by their “Self-clearing” badge:


You can use self-clearing fields in registers of type READ_WRITE and WRITE_ONLY. Enjoy!


FPGA Lint Tools

Every now and then in my FPGA consulting and coaching work I get asked about available FPGA lint tools. Here’s my current list, which I have compiled with the help of my twitter followers.

Please note that not all tools listed below are pure linters: some are HDL editors/IDEs, others are simulators with linting capabilities. The tools are listed in alphabetical order:


AMIQ DVT Eclipse IDE, an Eclipse-based HDL editor with linting capabilities. The same company provides a SystemVerilog Testbench Linter called Verissimo

BluePearl Analyze RTL

GHDL, a free VHDL simulator (using the -s switch)

HDL Works HDL Companion

Invionics Invio, a framework for building custom EDA tools

Real Intent Ascent

Sigasi Studio, an Eclipse-based HDL editor, has built-in linting checks such as sensitivity lists and dead code

Synopsys SpyGlass

Verilator, a free Verilog simulator has built-in linting checks

Xilinx Vivado Design Suite has a lot of built-in DRCs including clock-domain crossings

Using a tool that’s not in this list? Please leave a comment or drop me a note.

Update #1 (08-FEB-2017): added AMIQ tools, as suggested by Tomasz Hemperek

How To Integrate an AirHDL Register File in Xilinx Vivado 2015.3

AirHDL is a free, web-based EDA tool for managing Xilinx ZYNQ and MicroBlaze register files. In this post, I will show you how to integrate an AirHDL-generated register file in a Xilinx ZYNQ design using Vivado 2015.3.

For the purpose of this article, I will use the “Base Zynq” example project that comes with Vivado. It’s a block diagram design of a simple Zynq processsing system with two peripherals: a GPIO and a block memory.


What we’re going to do is add a custom bus peripheral component with an AirHDL-generated register file to this design.

In Vivado, open the “Address Editor” view and look for a free address range for the register map that you’ll create in AirHDL.


I will use 0x4200_0000.

In AirHDL, create a new register map called “myMap” and make sure to use the base address you selected before (in my case: 0x4200_0000) as the regitster map’s base address:


Add a few registers to the newly created register map. I will add a read-write “control” register with a 1-bit “value” field and a read-only “status” register with also a 1-bit “value” field. In AirHDL, each register field will map to a separate port in the generated RTL component.2015-12-26_17-48-38For every register map that you create, AirHDL generates a number of different output products that you can download:

  • C Header
  • VHDL Package
  • VHDL Component
  • VHDL Instantiation Template
  • VHDL Testbench
  • HTML Documentation
  • IP-XACT Specification
  • JSON Specification

For the purpose of the integration into a Xilinx Vivado hardware design, the only files that you need are the VHDL Package and the VHDL Component. Download these and save them into an empty folder on your hard drive (e.g. e:\temp\mymap).


Back in Vivado, select Tools > Create and Package IP…

Select “Package a specified directory” and select the directory containing the downloaded AirHDL files (in my case: e:\temp\mymap).


In the automatically created IP project, check that the ports and interfaces are correct. In particular you’ll expect that the slave AXI interface and the the clock and reset signals have been detected correctly, and that the user I/Os corresponding to each register field appear in the list:


Also note that for processor-writable registers, AirHDL generates a “strobe” port that signals when the register value has been updated by the CPU.

Click “Package IP”

Back in your Vivado “Base Zynq” project, click “Add IP” and select the “myMap_regs” component:


In the block diagram editor, click “Run Connection Automation”. This will connect our component’s AXI-interface to the AXI interconnect:


Open the “Address Editor” view and update the “Offset Address” and “Range” properties of the “myMap_regs” component using the value found in the AirHDL register map view (for the range, use the next higher choice available):


In the block diagram, select the “control_value” and “status_value” ports of the “myMap_regs” component, right-click and select “Make External”. This will create top-level input and output ports and connect them to the register fields.


You’re done! You can now run the synthesis and implementation to generate the bitstream.