AXI-Lite register bank

This (relatively large) code snippet is about implementing a register bank with an AXI-Lite interface.

Some time ago I published a previous version of this module, based on an AXI-Lite code from Xilinx. From the feedback I received on Reddit, I understood that the Xilinx code for AXI-Lite slave, regretfully, is broken. So I wrote down my own version of the code and tested it thoroughly.

Continue reading “AXI-Lite register bank”

Parallel to serial converter

This VHDL module receives parallel data as input at it outputs the data in serial format.

This VHDL module receives parallel data from the data_in bus when load is asserted. One clock after load is de-asserted, the data is serially transmitted out on the data_out line, MSB first, and valid is also asserted. The frame signal is asserted together with the end of the transmission (i.e. when the LSB is transmitted).

Continue reading “Parallel to serial converter”

VHDL Modulo counter, how to code and test it

A modulo counter is a counter that wraps around when it reaches a certain value. For example, a counter modulo 5 will count 0, 1, 2, 3, 4, 0, 1, …; namely, after 4 it will wrap around to 0. The reason the counter wraps after 4 is that to count five clock pulses starting from zero, the maximum value of the counter must be (modulo-1), in this case, 5-1=4.

Every VHDL counter is a modulo counter. If you define a two-bit counter, it will wrap around automatically from 3 to 0 without the need of writing special logic for that.

Continue reading “VHDL Modulo counter, how to code and test it”

Coding and testing a Generic VHDL Downcounter

For synchronous logic, a timer and a counter are almost the same. After all, a timer counts clock units. That is why in many digital applications we see them called timers/counters.

The code below models a generic timer/counter, using unconstrained ports:

Continue reading “Coding and testing a Generic VHDL Downcounter”

Generic demultiplexer and decoder

The demultiplexer receives one data bit din as input and routes it to one of ‘n’ possible outputs. The output is selected according to the value of the sel input.

The demultiplexer size is configurable via a generic parameter SEL_W.

The decoder is a simpler version of a demultiplexer, it will be shown after the code for the demultiplexer and the Vivado simulation results below:

Continue reading “Generic demultiplexer and decoder”

Generic register with load

The VHDL code presented below models a synchronous parallel register with a load signal.

The register width is unconstrained (data_in and data_out don’t have a declared size). In previous versions of this code, I used generics to create a module with a configurable size. Using unconstrained ports instead of generics greatly improves the cleanliness and modularity of the code. The size of these signals will be known when the module is instantiated, in this case, by the test bench.

Continue reading “Generic register with load”