.. _module_reg_file: Module reg_file =============== This document contains technical documentation for the ``reg_file`` module. To browse the source code, please visit the `repository on GitHub `__. The hdl-modules project contains many components that together form everything you need to set up a register bus. Below is a diagram of the typical layout for a register bus. .. digraph:: my_graph graph [ dpi = 300 splines=ortho ]; rankdir="LR"; cpu [ label="AXI master\n(CPU)" shape=box ]; cpu -> axi_to_axi_lite [label="AXI"]; axi_to_axi_lite [ label="axi_to_axi_lite" shape=box ]; axi_to_axi_lite -> axi_lite_mux [label="AXI-Lite" ]; axi_lite_mux [ label="axi_lite_mux" shape=box height=3.5 ]; axi_lite_mux -> axi_lite_reg_file0; axi_lite_reg_file0 [ label="axi_lite_reg_file" shape=box ]; axi_lite_mux -> axi_lite_reg_file1; axi_lite_reg_file1 [ label="axi_lite_reg_file" shape=box ]; axi_lite_mux -> axi_lite_cdc2; axi_lite_cdc2 [ label="axi_lite_cdc" shape=box ]; axi_lite_cdc2 -> axi_lite_reg_file2; axi_lite_reg_file2 [ label="axi_lite_reg_file" shape=box ]; axi_lite_mux -> axi_lite_cdc3; axi_lite_cdc3 [ label="axi_lite_cdc" shape=box ]; axi_lite_cdc3 -> axi_lite_reg_file3; axi_lite_reg_file3 [ label="axi_lite_reg_file" shape=box ]; dots [ shape=none label="..."]; axi_lite_mux -> dots; In hdl-modules, the register bus used is is AXI-Lite. In cases where a module uses a different clock than the AXI master (CPU), the bus must be resynchronized. This makes sure that each module's register values are always in the clock domain where they are used. This means that the module design does not have to worry about metastability, vector coherency, pulse resynchronization, etc. * :ref:`axi_lite.axi_to_axi_lite` is a simple protocol converter between AXI and AXI-Lite. It does not perform any burst splitting or handling of write strobes, but instead assumes the master to be well behaved. If this is not the case, AXI slave error (``SLVERR``) will be sent on the response channel (``R``/``B``). * :ref:`axi_lite.axi_lite_mux` is a 1-to-N AXI-Lite multiplexer that operates based on base addresses specified via a generic. If the address requested by the master does not match any slave, AXI decode error (``DECERR``) will be sent on the response channel (``R``/``B``). There will still be proper AXI handshaking done, so the master will not be stalled. * :ref:`axi_lite.axi_lite_cdc` is an asynchronous FIFO-based clock domain crossing (CDC) for AXI-Lite buses. It must be used in the cases where the ``axi_lite_reg_file`` (i.e. your module) is in a different clock domain than the CPU AXI master. * :ref:`reg_file.axi_lite_reg_file` is a generic, parameterizable, register file for AXI-Lite register buses. It is parameterizable via a generic that sets the list of registers, with their modes and their default values. If the address requested by the master does not match any register, or there is a mode mismatch (e.g. write to a read-only register), AXI slave error (``SLVERR``) will be sent on the response channel (``R``/``B``). Note that there is also a convenience wrapper :ref:`axi_lite.axi_to_axi_lite_vec` that instantiates :ref:`axi_lite.axi_to_axi_lite`, :ref:`axi_lite.axi_lite_mux` and any necessary :ref:`axi_lite.axi_lite_cdc` based on the appropriate generics. .. _reg_file.axi_lite_reg_file: axi_lite_reg_file.vhd --------------------- `View source code on GitHub `__. .. symbolator:: component axi_lite_reg_file is generic ( regs : reg_definition_vec_t; default_values : reg_vec_t ); port ( clk : in std_ulogic; --# {{}} axi_lite_m2s : in axi_lite_m2s_t; axi_lite_s2m : out axi_lite_s2m_t; --# {{}} regs_up : in reg_vec_t; regs_down : out reg_vec_t; --# {{}} reg_was_read : out std_ulogic_vector; reg_was_written : out std_ulogic_vector ); end component; Generic, parameterizable, register file for AXI-Lite register buses. Is parameterizable via a generic that sets the list of registers, with their modes and their default values. Will respond with ``SLVERR`` on the ``R`` channel when attempting to read a register that 1. Does not exists (``ARADDR`` out of range), or 2. Is not of a register type that can be read by the bus (e.g. write only). Similarly, it will respond with ``SLVERR`` on the ``B`` channel when attempting to write a register that 1. Does not exists (``AWADDR`` out of range), or 2. Is not of a register type that can be written by the bus (e.g. read only). Both cases are handled cleanly without stalling or hanging the AXI-Lite bus. The ``regs`` and ``default_values`` generics are designed to get their values from a package generated by the ``hdl-registers`` VHDL generator: :py:class:`VhdlRegisterPackageGenerator `. The values can be constructed by hand as well, of course. .. _reg_file.axi_lite_reg_file.resource_utilization: Resource utilization ____________________ This entity has `netlist builds `__ set up with `automatic size checkers `__ in `module_reg_file.py `__. The following table lists the resource utilization for the entity, depending on generic configuration. .. list-table:: Resource utilization for **axi_lite_reg_file** netlist builds. :header-rows: 1 * - Generics - Total LUTs - FFs - RAMB36 - RAMB18 - Maximum logic level * - (Using wrapper axi_lite_reg_file_netlist_wrapper.vhd) - 202 - 447 - 0 - 0 - 4 .. _reg_file.interrupt_register: interrupt_register.vhd ---------------------- `View source code on GitHub `__. .. symbolator:: component interrupt_register is port ( clk : in std_ulogic; --# {{}} sources : in reg_t; mask : in reg_t; clear : in reg_t; --# {{}} status : out reg_t; trigger : out std_ulogic ); end component; Generic interrupt register for producing a sticky interrupt bit. Each bit in ``status`` is raised, and kept high, if the corresponding bit in ``sources`` is ever ``'1'``. A ``status`` bit is cleared to zero if the corresponding ``clear`` bit is ever asserted. The ``trigger`` pin is asserted if any bit is ``'1'`` in both ``status`` and ``mask``. I.e. ``status`` always shows the sticky interrupt value, but the ``trigger`` pin is only asserted if the bit is also ``mask`` ed. Clearing all asserted ``status`` bits, or ``mask`` ing out all bits, will also clear ``trigger``. .. _reg_file.interrupt_register.resource_utilization: Resource utilization ____________________ This entity has `netlist builds `__ set up with `automatic size checkers `__ in `module_reg_file.py `__. The following table lists the resource utilization for the entity, depending on generic configuration. .. list-table:: Resource utilization for **interrupt_register** netlist builds. :header-rows: 1 * - Generics - Total LUTs - FFs - Maximum logic level * - - 39 - 33 - 5 .. _reg_file.reg_file_pkg: reg_file_pkg.vhd ---------------- `View source code on GitHub `__. Package with constants/types/functions for generic register file ecosystem. .. _reg_file.reg_operations_pkg: reg_operations_pkg.vhd ---------------------- `View source code on GitHub `__. Various helper functions for reading/writing/checking registers. .. note:: This file is largely unused, and replaced by simulation support packages produced by the ``hdl-registers`` register interface code generator: https://hdl-registers.com The file is kept for legacy reasons in case someone out there is still using it. There is an intentional asymmetry in the default value for ``other_bits_value`` between ``check_reg_equal_bit(s)`` and ``wait_until_reg_equals_bit(s)``. For the former it is ``'0'`` while it is ``'-'`` for the latter. This is based on the philosophy that a false positive is better than a hidden error. False positives, when discovered, can be worked around by e.g. changing the default value. Consider the example of ``check`` ing an error status register. When we want to check that the expected error bit has been set, we would like to be informed if any further errors have also occurred. This would not happen unless ``other_bits_value`` value to ``check_reg_equal_bit(s)`` is ``'0'``. Consider furthermore the situation where we are ``wait`` ing for a certain error bit to be asserted in a test, but ten other errors occur. In this scenario we would like the wait to end, and for the errors to have consequences. This would not occur unless ``other_bits_value`` value to ``wait_until_reg_equals_bit(s)`` is ``'-'``.