Skip to content

Registers Infrastrcture

Greg Watson edited this page Jan 23, 2024 · 5 revisions

Section I: Introduction

For NetFPGA SUME, the registers infrastructure was enhanced, so addition of registers to modules is mostly automatic.

The register generator helps users to generate a register module for their desired IPcore. It offers an infrastructure (using a spreadsheet, scripts etc.) where user can easily define their own registers. Two files are currently included in the registers generation scheme:

  • module_generation.xlsm - An example spreadsheet used to define the per module registers
  • regs_template.txt - A text file used as the base for the code generation.

The registers generation is conducted by using these 2 files. To use the generator, a user needs to define his registers in the module_generation.xlsm file. After that, he/she presses a button that executes a VBA script (macro). The script creates a python file regs_gen.py: it takes the registers parameters from the spreadsheet and writes them into a file in a python format, and following concatenates regs_template.txt to this file. regs_template contains most of the python coding. The result is a python script that can generate the required verilog modules and output files. Then, users can generate his/her desired register interface by running the python script regs_gen.py

Updates Log:

  • Version 1.00 - Inital Release. This version is kept before release_1.2.0

  • Version 1.10 - Fix bugs, add indirect access. This version is update since release_1.3.0.

Section II: Register Generation Flow

Step 1: Working with the spreadsheet

  • open the spreadsheet in LibreOffice/Excel and make sure that macros are enabled and security settings do not block running VBA code (See Section III for details).

  • Select your operating system in cell F2 dropdown menu

  • For each register, fill in the following fields:

    • Block name (Col A) - the name of the module/core (where the registers are instantiated)

    • Register name (Col B) - must be a single word. For multiple words, concatenate them and use a capital letter at the beginning of every word. In verilog, each word will be separated by an underline, e.g. register name MyCounter will appear in verilog as my_counter.

    • Address offset (Col C) - offset within the block. Use the formula in the example to set the address (Hex, in steps of 0x4 or multiplications of it). Global registers have no offset.

    • Description (Col D) - Registers description. Needs to be informative (for documentation purposes).

    • Type (Col E) - Type of the entry : Global (register), Reg (Register) or Field (a certain range within a register)

    • Bits (Col F) - which bits are used by the register (by default can set to 31:0). If you would like to change the register width, please make sure it is smaller than the bus width (AXI_LITE, 32-bit by default). And the bits are suggested to be multiple of bytes, i.e (7:0, 15:0 etc.), non-regular width is not supported. If you intend to use non-regular width, please check fields option in (Col E).

    • Endian type (Col G) - choose the endianness type for your register, i.e Little or Big (the field is not case sensitive). Note that in current version, if you intended to use big-endian assignment, it is suggested to assign the bits to be identical to the bus width (AXI_LITE,by default 32-bit).

    • Access mode (Col H) - Indicates the register type, currently supported options are:

      • RO - Read Only
      • ROC - Read Only Clear
      • WO - Write Only
      • WOE - Write Only Event (a single clock event)
      • RWS - Read/Write by SW only
      • RWA - Read/Write by HW and SW
      • RWCR - Read/Write clear on read
      • RWCW - Read/Write clear on write
      • ROI - Read Only, Indirect (Version 1.10)
      • RWSI - Read/Write by SW only, Indirect (Version 1.10)
      • RWI - Read/Write by HW and SW, Indirect (Version 1.10)
    • Valid for sub-modules (Col I) - To be used when multiple sub-modules are included within the same top module (e.g. Rx queue, Tx queue under 10G Interface module). Reserved for Future Use (RFU).

    • Default (Col J) - Default value, the value to be set to the register upon reset. Note that the default value must be assigned in hexadecimal format (e.g. 32'h0)

    • Constraints and remarks (Col K) - Open text for general purpose (currently documentation only)

    • Each register may have multiple fields, i.e. each bit or a range of bit may serve a different function. An example is a counter register, where bits [30:0] indicate the counter value and bit 31 is an overflow bit. Registers are marked in blue and fields in white. Fields are not generated as separate buses to the user's logic, rather they are part of their register's bus, thus (currently) the use is in the spreadsheet is for documentation only.

  • Last: Press "Generate Registers" (B2)

Indirect Access (Version 1.10)

Indirect access to memories is defined by two parts of the spreadsheet: indirect registers and indirect memories.

Indirect registers should not be altered (though their address may be changed). They should be used as follows:

  • IndirectAddress - Address of an indirect access. Bits [31:28] are the base address of the selected memory.

  • IndirectWrData - Data to be written in an indirect write access.

  • IndirectReply - Data returned from an indirect read access.

  • IndirectConfig - Configures the indirect command, including:

    • IndirectAddressIncrement - If multiple write commands are required, this is the address increment between each access

    • IndirectWriteType - Type of write access: wait states (wait a certain number of cycles before the next action) or transfer acknowledge (wait to an acknowledgement signal, indicated by <mem_name>_reply_valid)

    • IndirectTimeout - For a read transaction or a write transaction using transfer acknowledge, this is the command timeout. For a write transaction using wait states, this is the number of wait states.

    • IndirectRepeatCount - Number of time a write command is executed. A read command is always executed only once.

  • IndirectCommand - Sets the indirect command, including:

    • IndirectTrigger - Starts (triggers) the indirect command. The field is set back to 0 when the command is completed.

    • IndirectType - Read or Write command type.

    • IndirectCommandStatus - Indicates whether the last command succeeded (0) or failed on timeout (1). Valid only when IndirectTrigger is 0.

The list of memories that require indirect access from within the module is defined at the bottom of the spreadsheet. The list of memories must always come after the last register. It is possible to omit the list of memories, if no indirect access is required.

The fields used for memories definition are as follows:

  • Block name (Col A) - the name of the module/core (where the registers are instantiated)

  • Memory name (Col B) - must be a single word. These will be used to generate memory-specific signals.

  • Address offset (Col C) - Not required, leave blank.

  • Description (Col D) - Memory description. Needs to be informative (for documentation purposes).

  • Type (Col E) - Type of the entry : Must be "Mem"

  • Bits (Col F) - which data bits are used by the memory (by default can set to 31:0).

  • Endian type (Col G) - choose the endianness type for your register, i.e Little or Big.

  • Address Bits (Col H) - which address bits are used by the memory (by default can set to 31:0).

  • Valid for sub-modules (Col I) - To be used when multiple sub-modules are included within the same top module. Reserved for Future Use (RFU).

  • Base Address (Col J) - Memory base address. Bits [31:28] are used to distinguish between different memories.

Step 2: generate python script

After you Press "Generate Registers" (B2), you should see regs_gen.py created under the current folder, and the following files will be generated: (If running on windows, or if you don't see these file, please manually run regs_gen.py, see Section III)

  • cpu_regs.v - an instantiation of the registers code, without dedicated logic. Should be placed under <core_name>/hdl folder.

  • cpu_regs_defines.v - a registers definitions file including parameters such as address, number of bits, etc. Used both by the user's logic and cpu_regs.v. Should be placed under <core_name>/hdl folder.

  • module_cpu_template.v - This file contains the lines that need to be copied into the user's module, including instantiation of cpu_regs and a template for using the registers. The functional use of the registers (e.g. a counting action) still needs to be coded by the user.

  • module_name.tcl - A generated tcl script that is used for for the generation of the software include (h) file. It includes the names and addresses (offset only) of all registers. Should be placed under <core_name>/data folder.(Might be removed in the future)

  • module_name.h - A generated header file that is used for python script import names and addresses (offset only) of all registers. Should be placed under <core_name>/data folder. (Might be removed in the future)

  • module_name.txt - A generated table file that is used to export name and address for tcl script in export_register.tcl. Should be placed under <core_name>/data folder.

Please refer to the example reference cores to see how these files are placed and used.

Section III: Troubleshooting and Limitations

  • It is important to enable macros in LibreOffice/Excel. If you are working under MS Excel, when you open the spreadsheet, an automatically generated warning will help you enable macros. However, you can always manually enable macros by (an example configuration for MS Office 2010)

    • clicking File in Menu bar, find Options and click it
    • find Trust Center, and then click Trust Center Settings
    • In the new window find Macro Settings, and select Enable all macros (not recommended; potentially dangerous code can run), and then press OK.
  • If you are working with LibraOffice under Ubuntu. You can enable macro by:

    • click Tools in the menu bar
    • goto LibreOffice > Security, and then Macro Security
    • choose Low(not recommended) and then press OK.
  • This spreadsheet is tested with the guarantee of using MS Office (2010 or above) or LibreOffice (4.3 or above). It is suggested to use this script with LibreOffice under Ubuntu 14.04 environment. OpenOffice is not supported (different macro format). Furthermore, altering the macro code under LibreOffice may cause it to stop working.

  • On some OS, the generated python script is not executed by the spreadsheet macro and needs to be executed manually by execute "python regs_gen.py" in the terminal. The python environment tested is: Python 2.7.6.

  • Not all fields in the spreadsheet are currently used, some as RFU

  • Not all the header files (such as .tcl .h) are used. For instance, in the reference project only table txt file is used. These files offers user more feasibility, but might be removed.

  • Synchronization stage is not implemented under current infrastructure. User need to eliminate asynchronous clock within the register interface if there is any. This decision offers the user the feasibility of been avoid using unnecessary synchronization stage if required.

  • Indirect access was tested under a limited number of scenarios, and is not fully verified.

  • Indirect access currently supports up to 32-bit address access. To access over 32 bit, it is currently recommended to manually change the _cpu_regs.v file. This is as most memories currently require less than 32-bit address, thus saving logic (extra registers etc.)

  • Unsupported Features:

    • Generation of RTF/documentation file is currently unsupported
    • Generation of a simulation testbench for the registers is currently not supported.
    • Configurable file names and folders are not supported
    • Fields are currently not written to the (.v) definition file.
    • etc.
Clone this wiki locally