The "ahb_multilayer" module
a VHDL implementation of a multiple master bus system based on the AHB protocol

The VHDL 2008 module "ahb_multilayer" (see symbol) connects several (or only 1) AHB masters to several AHB slaves.

The ahb_multilayer complies with the AMBA® AHB Protocol Specification (ARM IHI 0033C).
The ahb_multilayer implements the AHB-Lite protocol, named "Issue A" in the specification.

The ahb_multilayer module is configured by generics, which determine the number of masters and slaves
and of course the parameters of the AHB protocol specification, extended by generics for address width
and slave addresses.

Each master can work independently from the other masters as long as it not accesses
a slave which is accessed by another master at the same time. If such a conflict happens,
the master with the lower priority has to wait until the other master has finished its access.
The priority of the masters is determined by a Round-Robin arbitration scheme.
Without any conflict the ahb_multilayer does not introduce a delay to the accesses from master to slave.

The "ahb_multilayer" module was developed with HDL-SCHEM-Editor.

Ports:

Port name Direction Description
hresetn_i input asynchronous reset input, 0-active
hclk_i input clock input
hcontrol_i(g_number_of_masters-1 downto 0) input This input is an array with an entry for each master. Each entry is a record containing the following AHB signals:
htrans, haddr, hwrite, hsize, hburst, hprot, hmastlock.
hwdata_i(g_number_of_masters-1 downto 0)(g_data_width-1:0) input AHB write data bus for each master.
hready_o(g_number_of_masters-1 downto 0) output AHB ready signal for each master.
hrdata_o(g_number_of_masters-1 downto 0)(g_data_width-1:0) output AHB read data bus for each master.
hresp_o(g_number_of_masters-1 downto 0) output AHB error response for each master.
hreadyin_o(g_number_of_slaves-1 downto 0) output AHB ready signal for each slave.
hsel_o(g_number_of_slaves-1 downto 0) output AHB select signal for each slave.
hcontrol_o(g_number_of_slaves-1 downto 0) output This output is an array with an entry for each slave. Each entry is a record containing the following AHB signals:
htrans, haddr, hwrite, hsize, hburst, hprot, hmastlock.
hwdata_o(g_number_of_slaves-1 downto 0)(g_data_width-1:0) output AHB write data bus for each slave.
hreadyout_i(g_number_of_slaves-1 downto 0) input AHB slave ready input for each slave.
hrdata_i(g_number_of_slaves-1 downto 0)(g_data_width-1:0) input AHB read data bus for each slave.
hresp_i(g_number_of_slaves-1 downto 0) input AHB error response for each slave.

Generics:

Generic name Minimum Value Maximum Value Description
g_number_of_masters 1 none Number of masters
g_number_of_slaves 1 none Number of slaves
g_addr_width n/a n/a Width of the address bus haddr (contained in hcontrol_i). The AHB Protocol Specification recommends values between 10 and 64. The selected value must be big enough to include the address spaces of all slaves.
g_data_width n/a n/a Width of the data busses hwdata_i and hrdata_o. The AHB Protocol Specification allows the values 8, 16, 32, 64, 128, 256, 512, 1024.
g_hburst_width 0 3 Width of hburst (contained in hcontrol_i). Allowed values from AHB Protocol Specification are 0 or 3.
g_hprot_width 0 7 Width of hprot (contained in hcontrol_i). Allowed values from AHB Protocol Specification are 0, 4 or 7.
g_start_addresses n/a n/a This is an array of std_logic_vector values, each entry representing the start address of the corresponding slave.
g_slave_address_width n/a n/a This is an array of integers, each entry representing the number of address bits the corresponding slave evaluates.

The module "ahb_multilayer" is a hierarchical module, which is built by 16 submodules.

Submodule name Functionality
ahb_multilayer_package

The package ahb_multilayer_package contains several type definitions. Some of them use VHDL 2008 unconstrained array types. This is the only used VHDL 2008 feature in the "ahb_multilayer" module. There is also a "or" function included for combining hcontrol signals and a debug procedure, which can be used to look inside the signals of type record, if your waveform viewer does not support records.

ahb_multilayer_master_interface

The "ahb_multilayer_master_interface" module connects each master to the AHB multi-layer bus. It has the two submodules ahb_multilayer_instage and ahb_multilayer_decoder.

ahb_multilayer_interconnect_hsel

The ahb_multilayer_interconnect_hsel submodule rearranges the hsel signals created by the ahb_multilayer_decoder submodules so that they can be connected to the ahb_multilayer_slave_interfaces. It has no logic.

ahb_multilayer_slave_interface

The "ahb_multilayer_slave_interface_inst" submodule connects each slave to the AHB multi-layer bus.

It has two submodules named ahb_multilayer_detect_request and ahb_multilayer_arbiter for the arbitration.

It has three submodules named ahb_multilayer_mux_hcontrol, ahb_multilayer_mux_hready and ahb_multilayer_mux_hwdata to bring the master access to the slave.

It has three submodules named ahb_multilayer_demux_hreadyout, ahb_multilayer_demux_hrdata and ahb_multilayer_demux_hresp to bring the slave answer to the master.

ahb_multilayer_default_slave

The "ahb_multilayer_default_slave" submodule is a simple AHB slave which generates an AHB error response in case a master accesses an address gap.

ahb_multilayer_instage

The ahb_multilayer_instage submodule stores an access, if the master does not get the addressed slave in a valid address phase. Afterwards the submodule connects the stored access to the multi-layer AHB until the slave gets free again.

ahb_multilayer_decoder

The ahb_multilayer_decoder submodule compares hcontrol.haddr to the slave start addresses defined by the generics. If a slave is addressed, it activates the hsel signal for the slave. If no slave is selected, but hcontrol.htrans is different from idle, then the submodule signals that an error response must be created by the submodule ahb_multilayer_default_slave.

ahb_multilayer_detect_request

The ahb_multilayer_detect_request submodule combines the hsel and hcontrol.htrans signals of all masters to request signals for a slave. It also checks if any request is a locked request or a burst which shall not be interrupted by another access. Bursts or locks over slave borders are not supported (and are not required by the AHB specification).

ahb_multilayer_arbiter

The ahb_multilayer_arbiter submodule is a round robin arbiter. It checks the request signals created by the submodule ahb_multilayer_detect_request. The arbitration is disabled, if a request gets a grant in an invalid address phase. The ahb_multilayer_arbiter submodule creates a grant for the address phase and a second one for the data phase. The ahb_multilayer_arbiter submodule does not introduce a delay into a sequence of accesses if the accessed slaves are available without any waiting.

ahb_multilayer_mux_hcontrol

The ahb_multilayer_mux_hcontrol submodule is a multiplexer passing the hcontrol information from the chosen master to the slave.

ahb_multilayer_mux_hready

The ahb_multilayer_mux_hready submodule is a multiplexer passing the hready from the chosen master to the slave.

ahb_multilayer_mux_hwdata

The ahb_multilayer_mux_hwdata submodule is a multiplexer passing the hwdata from the chosen master to the slave.

ahb_multilayer_demux_hreadyout

The ahb_multilayer_demux_hreadyout submodule passes the hreadyout from the slave to the master, which has the grant.
It also creates a hreadyout=0 for a master, which must wait for the slave and additionally informs ahb_multilayer_instage that this access must be stored.
To all other masters, which do not access the slave, it creates a hreadyout=1.

ahb_multilayer_demux_hrdata

The ahb_multilayer_demux_hrdata submodule passes the hreadyout from the slave to the master, which has the grant.

ahb_multilayer_demux_hresp

The ahb_multilayer_demux_hresp submodule passes the hresp from the slave to the master, which has the grant.

ahb_multilayer_interconnect_slave_response

The ahb_multilayer_interconnect_slave_response submodule distributes the answers of all ahb_multilayer_slave_interfaces to the ahb_multilayer_master_interfaces.

Address decoding:

The ahb_multilayer module must create select signals hsel for the slaves depending on the hcontrol.haddr signals,
which is done in this way:
The start address of each slave is defined by the generic g_start_addresses.
The number of address bits each slave observes is defined by the generic g_slave_address_width.
This number of least significant bits is cut off from each slave start address and also from hcontrol.haddr.
The remaining address parts are compared for equality and the hsel signals are generated.
In this way no address arithmetic is needed, which would make hsel generation slow.

Multiplexer implementation:

All needed multiplexers are implemented by forcing the not selected 1-active signals to 0 and then "oring" them.
If the not selected signals are 0-active, then all not selected signals are forced to 1 and then "anded".

Write and read data paths:

As separate databusses exist for write and read data, ahb_multilayer never checks the status of the hwrite signal.
As a consequence at every write transfer the slave can deliver read data and at every read transfer the master can deliver write data.
So this is used by the testbench components:
At each access, the hcontrol signals are copied into the write data at the master and
also the hcontrol signals are copied into the read data at the slave.
This allows a lot of automatic checks at both master and slave side.

Instance creation:

For an instance of the ahb_multilayer module the package ahb_multilayer_package must be used to introduce the data types at ahb_multilayer's ports.
If this is not allowed or wished, then a shell around ahb_multilayer can help.
In this shell the conversion from the special ahb_multilayer data types to the standard data types can be realized.
There also the generics of the ahb_multilayer module can be set, so that the entity of the shell does not have special types or generics.

Timing:

The critical combinatorial path through ahb_multilayer starts at hcontrol_i.htrans, hcontrol_i.haddr and hcontrol_i.hmastlock.
These signals are read by the arbitration which generates a grant when the master is allowed to access the slave.
This grant is then used to connect the hreadyout_i of the slave to the hready_o of the master.
This hready for the master is then also send to the slave by hreadyin_o, which is the end of the combinatorial path.
The combinatorial depth for this path was 6 LUT in a Vivado synthesis with a Xilinx device.
All other combinatorial paths through the design are faster.

Gate count:

The number of flipflops for each connected AHB master is identical to the number of bits in the hcontrol_i signal, plus 3.
The number of flipflops for each connected AHB slave is 3 times the number of masters.
Additionally, combinatorial gates are needed for arbitration and multiplexers.

symbol symbol symbol symbol symbol symbol symbol symbol symbol symbol symbol symbol symbol symbol symbol symbol symbol symbol

Source code for HDL-SCHEM-Editor and HDL-FSM-Editor for "ahb_multilayer" module and its testbench (Number of downloads = 2 ).
With these files the schematics and the state-diagram of "ahb_multilayer" module can be loaded into HDL-SCHEM-Editor or HDL-FSM-Editor and can be easily read and modified:

All module VHDL-files of the "ahb_multilayer" module (Number of downloads = 2 ).
These files were generated by HDL-SCHEM-Editor and HDL-FSM-Editor:

All testbench VHDL-files of the "ahb_multilayer" module (Number of downloads = 2 ).
These files were generated by HDL-SCHEM-Editor and HDL-FSM-Editor:

Relocation hints:

You should extract all archives into a folder named "ahb_multilayer".

Then you should load the toplevel (probably the testbench) into HDL-SCHEM-Editor.
When you navigate through the design hierarchy by a double click at each symbol,
HDL-SCHEM-Editor will find the submodules on your disk and ask if it can replace
the original path to the submodule by the new one at your disk.
After storing the changed modules the relocation of the source files is done
(instead you could replace "M:/gesicherte Daten/Programmieren/VHDL/ahb_multilayer" in all
"hdl_editor_designs/*.hse" source files by your path to this directory with your editor).

Now you can navigate through the design by HDL-SCHEM-Editor and generate HDL by HDL-SCHEM-Editor
for all modules except ahb_multilayer_default_slave, ahb_multilayer_instage and ahb_slave,
for which the HDL must be generated by HDL-FSM-Editor.
Of course there is only need for generating HDL, if you change something at the modules,
because you can find the HDL in VHDL_designs.zip and VHDL_testbenches.zip.

If you want to simulate or modify the modules by HDL-SCHEM-Editor you also must adapt the information in the
Control-tab of the toplevel you want to work on. There you must define a "Compile through hierarchy command",
an "Edit command", the path to your HDL-FSM-Editor and a "Working directory".

Change log:

Version 1.0 (16.10.2025):

If you detect any bugs or have any questions,
please send a mail to "matthias.schweikart@gmx.de".