New Generator: Linear-Feedback Shift Registers

Building on our vision to offer a comprehensive, web-based code generator for FPGA and ASIC developers, we are thrilled to announce the initial rollout of our Linear-Feedback Shift Register (LFSR) generator.

LFSRs are a class of pseudo-random number generators that can be implemented very efficiently in FPGA or ASIC technologies. As you can see in the figure below, a 7-bit LFSR is just a chain of 7 register stages with two XNOR feedback taps at positions 6 and 7. When initialized to zero, and provided with a clock signal, this marvelous little circuit will almost magically cycle through every possible state (except one) of the 7-bit word in a defined sequence that repeats itself every 127 cycles.

The micro-architecture of a 7-bit linear-feedback shift register

LFSRs have a single invalid state which—like a beetle stuck on its back—they cannot exit on their own. For XNOR feedback types LFSRs, the invalid state is all ones. Fortunately, the invalid word is not part of the LFSR’s natural sequence whose length is thus 2N-1 instead of 2N, N being the LFSR length in bits.

In digital electronics, LFSRs are often used to generate Pseudorandom Binary Sequences (PRBS) for testing serial or parallel communication links. PRBS-7 and PRBS-31 are two common kinds of Pseudorandom Binary Sequences, which can be generated respectively with 7-bit and 31-bit LFSRs. In the case of a serial communication link, the bit sequence is obtained from the MSB of the shift register (e.g. Q7 in the diagram above).

Implementing LFSRs in hardware is no rocket science. Still, since it’s not something that developers do every day, it can easily take an hour or two until the proper feedback taps and feedback type have been figured out and the circuit is finally working in simulation and in synthesis.

Using the new LFSR generator in airhdl, you can now design an LFSR in minutes and immediately download the VHDL or SystemVerilog implementation.

The new LFSR view in

For your convenience, airhdl also provides C and Python models of the LFSR so that you can easily display the sequence of numbers that the LFSR will cycle through. This can be super convenient when it comes to comparing numbers recorded with a logic analyzer with the expected sequence.

By default, the Python model outputs the first 16 words of the LFSR sequence in hexadecimal format:

$ python .\

Using the optional count argument, you can tell the script how many output words to generate:

$ python .\ 4

The -i option allows you to start the sequence on an arbitrary initial value:

$ python .\ -i 0x3F 8

This way you can easily convince yourself that it’s a very bad idea to initialize the LFSR to all ones (that’s the beetle stuck on its back):

$ python .\ -i 0x7F 8

We hope you’ll find the new LFSR generator useful and as always, make sure to let us know what you think!

Update (30-AUG-2023): Philip Abbey has generic VHDL implementation of LFSRs, which is described on his blog: Swapping Synchronous and LFSR Counters

New Feature: Transfer Register Map Ownership

One of the many benefits of the airhdl Professional plans is the ability to share register maps with other airhdl users, either in a read-only way or with full editing priviledges. Technically, the user who first creates a register map becomes the owner of that register map, and that gives him or her special priviledges, such as being able the share the register map with other users, or to delete the register map from the database.

After a few years of working with airhdl (and possibly switching jobs in between), some of our users have expressed the need to transfer the ownership of one or more register maps to other airhdl users. Until now, that wasn’t possible in the user interface but the latest airhdl release now allows you to do that very easily, provided you have an active Professional subscription.

To transfer ownership of a register map to another airhdl user, click on the gear icon in the Register Map view and select Transfer Ownership in the drop down menu:

This brings up the Transfer Ownership dialog, which prompts you for the e-mail address of the user you’d like to transfer that register map to. The e-mail address should correspond to the one of a registered airhdl user:

Once you’ve entered the e-mail address, click the Transfer Ownership button to trigger the transfer.

Note that transferring ownership of a register map cannot be undone. Please make sure to double-check the e-mail address of the destination user before clicking the Transfer Ownership button.

New Feature: Auto-Compute Register Offsets

Following several user requests, airhdl now offers a way to auto-compute the register offsets within a register map. By clicking the Auto-compute register offsets button, airhdl automatically re-computes the address offsets of all the registers in the register map, starting at zero, and ensuring that there are no address gaps between them.

Auto-compute register offsets button

We hope you’ll find this feature useful. If you use airhdl, please make sure check out our Feature Requests board where you can submit new ideas for improvement and/or vote for existing proposals.

New Feature: Markdown Generator

Following a user request, airhdl is introducing a new a Markdown documentation generator. You can now choose to download your register map documentation in either HTML or Markdown formats:

In case you haven’t come across Markdown before, it’s lightweight, text-based markup format that was initially proposed by John Gruber. You can find a description of the Markdown syntax here.

Markdown being such a popular markup language, it is well supported by source code editors such as Visual Studio Code or Eclipse. Besides that, there are many other tools for processing Markdown documents.

For example, you can use the Python grip package to render a Markdown document in a web browser:

python grip

Or you can use pandoc to convert a Markdown document to a PDF file:

pandoc -o my_regs.pdf

We hope that you’ll find the new Markdown documentation generator useful!

New Feature: Enumerated Values

Upon popular request, airhdl now supports enumerated values for register fields.

Enumerated values are a convenient was to give names to specific field values. As an example, we’ll take a two-bit mode field that is used to control a processing engine. This field supports the following values:

• 0: disabled
• 1: manual
• 2: automatic

To edit a field’s enumerated values, bring-up the Edit Field dialog and activate the Enumerated Values tab:

For each enumerated value, enter the name and the corresponding value in the input fields and click Add:

When you’re done entering all enumerated values for a field, click Save Field:

Once you have done that, airhdl knows about those values and corresponding symbols appear in the generated files. For example, in the generated C header, you’ll find them as preprocessor defines:


Of course, your enumerated values are available in the generated RTL code (VHDL and SystemVerilog) as constants too.

We hope you’ll find them useful.

New Feature: the Register Calculator

Calculating a register’s value from the values of its fields, or vice-versa, can be a tedious and error-prone task. It’s often a time where we developers have to pull out a sheet of paper and draw some diagrams in order to get it right.

In our quest to make your life as a developer easier, we’re introducing a new tool to airhdl called the Register Calculator. It’s available for every register created in airhdl: to start it just click on the calculator icon in the register overview:


This brings up the Register Calculator in a pop-up window where you’ll see a graphical representation of the register, along with an input field for every register field and an input field for the total register value. Changing the value of a field updates the total register value (at the bottom). And as you would expect, changing the register value updates the field values as well.


In the top right corner of the window, a radix selector lets you choose between the three usual radixes (hexadecimal, decimal and binary). The selected radix applies to all fields in the window.

Next to the register value field, three helper buttons are available for the following actions:

  • Clear the register (set all fields to zero)
  • Reset the register (set all fields to their reset value)
  • Copy the register value to the clipboard

We hope you’ll like it!

New Feature: Register Map Sharing

As a first step towards the goal of enabling true collaborative work between team members, airhdl now supports sharing register maps in a read-only way. This means that any airhdl user with a Professional subscription (which is just $199 per year or $16 per month) can now share his/her register maps with any other airhdl user. The recipient will have the right to view the shared register map, and to generate the corresponding files.

Let’s have a look at how to actually share a register map in airhdl.

At the bottom of the register map overview, you’ll notice a new “Sharing” section. To share the current register map, click on the “+ Share” link at the bottom of the table.


Then, in the “Share Register Map” dialog, enter the e-mail address of the user with whom you’d like to share (please make sure to enter the e-mail address that the user actually uses to log-in to airhdl), and click the Share button.


The newly created permission then appears in the sharing table:


When the recipient user logs in, the register map will appear in his list of register maps, in the “Shared Register Maps” section:



New Feature: Memory Interfaces

Upon popular request, airhdl now supports a new kind of register map element called a “memory interface”. Unlike the “register” and “register array” elements, a memory interface does not generate storage elements in the register bank. Instead, it allows you to connect an external SRAM to the register bank using a simple address and data bus, and to access that SRAM from the bus as if it were an array of registers.

Memory interfaces support the following access modes: read-write, write-only and read-only. While a read-write memory can be read and written from the bus,  a write-only memory can only be written from the bus (which can be useful for elements like look-up tables that must be writable by software and readable from the user logic).

To add a memory interface to an existing register map, click the “+ Memory” icon at the bottom of the registers list:


This brings up the new memory dialog, which, in addition to the usual information, asks you for the memory depth (in elements). Each memory element occupies the same number of bytes as a single register in the memory map (4 bytes). For example, a memory with a depth of 16 will occupy 64 bytes in the memory map. The first element is accessible at the memory’s base address, while the last one resides at offset 15 · 4 = 60 from the memory’s base address.

Now let’s have a look at how to actually connect a memory to the register bank. Assuming a read-write memory interface, airhdl will generate the following user ports for the memory:

• *_addr is the read and write address
• *_wdata is the write data bus
• *_wen is the (byte-wide) write-enable signal
• *_rdata is the read data bus

Memory writes are performed by asserting the *_wen signals while outputting the write address on the *_addr port and the write data on the *_wdata port.


Memory reads assume a sychronous RAM with a read latency of one clock cycle:


• on rising edge #2, the register bank outputs the address
• on rising edge #3, the SRAM is expected to output the corresponding data
• on rising edge #4, the register bank registers the read data on the *_rdata port

Please feel free to give memory interfaces a try, and let us know what you think.

New Feature: Duplicate 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:

New Feature: 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”: