Skip to content
Snippets Groups Projects
Commit 78c67718 authored by Eric Kooistra's avatar Eric Kooistra
Browse files

Updated text.

parent a89b407e
No related branches found
No related tags found
No related merge requests found
Purpose:
Prestudy to investigate how we can define MM slaves using a peripheral.cfg
config file and then use that peripheral.cfg file to generate:
Prestudy to investigate how we can define MM slaves using a peripheral
config file and then use that peripheral config file to generate:
* Documentation
The mmm.cfg provides the address map and all the MM slaves. The MM slaves
are defined by the peripheral.cfg files
are defined by the peripheral config files
* Python periperal
Basic MM access functionality of the peripheral in Python. Comparable to
......@@ -21,17 +21,24 @@ config file and then use that peripheral.cfg file to generate:
MM block RAM the fields are available to the application in series.
* Perhaps there is more useful targets that we can generate based on the
peripheral.cfg. For example:
peripheral config file. For example:
. *.h include file for C code
* A system config file can define a list of peripherals to define the MM
bus for a design. In addition a system config file can define more aspects
of the design like clock speed and board support package.
Contents:
1) Current MM slave definition in VHDL:
2) Background information for peripheral.cfg
2) Background information for peripheral config files
3) Peripheral config file draft format
4) Appendix: Current common peripheral class in Python
5) Appendix: Example of mmm.cfg:
4) System config file draft format
*) Appendix: Current common peripheral class in Python
*) Appendix: Example of mmm.cfg
......@@ -126,43 +133,65 @@ b) Block RAM definition
- undefined ("UNUSED")
2) Background information for peripheral.cfg
2) Background information for peripheral config files
a) Config file format
a) Config file format --> Choose YAML
Use the ini-file format that we are also using for hdllib.cfg and mmm.cfg.
This ini-file format basicly defines a Python 'dict'.
So far we do not need a more sophisticated configuration file format, eg.
like xml or yaml.
like xml or yaml? Using YAML is better suited to represent the hierarchy
of a MM bus with peripherals, MM slaves, registers/RAMs/Fifos and fields.
Therefore we choose to use YAML.
b) Location
The pi_<peripheral_name>.cfg can be stored at the library next to the
hdllib.cfg
The peripheral config file can be stored in a directory that has the
peripheral name.
c) Periperal definition
- A peripheral can consist of one or more MM slaves (or should we define
a peripharal as always only one MM slave? No, I don't think so(HJ)).
- A peripheral can consist of one or more MM slaves.
- Each MM slave is addressed via a mosi/miso port in the VHDL.
- All slaves have 32 bit data per address. If the slave uses less than 32
- Define data word width per address 32 bit. If the slave uses less than 32
bit data, then still each data occupies one address. The unused data bits
are not implemented in firmware and when the data is read then those
unused bits will be 0 or sign extended dependent on the data definition.
- Define the span of a slave as the number of addresses * 4, so in number
of bytes.
The MM slave can be a:
* register
- with various field definitions
- Each field has a unique name
- Typically there is one field per address, so then the maximum field size
is 32 bit. However it is also allowed to have muliple smaller fields per
address or larger fields that span multiple addresses:
> a field can consist of more than one data word:
. field width > 32 bit, e.g. 64 bit bsn, accumulator
. when low 32 bit word is read, then the remaining bits of the field
must be captured by the VHDL as well to ensure that whole field
can be read as an atomic unit (see e.g. dp_bsn_source_reg.vhd).
> there can be multiple fields at the same address:
. hi-lo bit range or specify field widths in order starting from bit 0
. same access mode for all fields at the same address
. support for multiple fields per word can be added at a later stage
- a field can have a default value
- implemented in logic
- all fields are available to the firmware in parallel
- fields can have different modes/types:
- Fields can have different modes, but only if they are at different
addresses. Per address there can only be one mode. The mode defines two
things (should these be separated into e.g. access and side_effect?):
. the MM access (e.g. R, W, R/W, ...)
. a side effect (e.g. none, clear after read, output read pulse, output write pulse, ...)
For example:
. Read only
. Write only
. Read and write
. Clear after read
. Pulse on write
- Each field has a unique name
* memories or RAM
- range of data words/fields
- one field per address
- implemented in (block) RAM
- at each clock cycle only one data word is available to the firmware
- defined in two steps:
......@@ -170,16 +199,23 @@ c) Periperal definition
2) Number of fields availabe in the RAM
* fifo
- one data word forms the single addres window to a write FIFO or a read
FIFO
- one data word forms the single addres window to a write FIFO or a read FIFO
- The fifo needs some register fields for monitoring:
. fifo full bit
. fifo empty bit
. fifo depth/size
. fifo used number of words
- could a FIFO also be defined as a register whereby multiple read or write to
the FIFO field do not increment the address, so as an RO or WO access mode
without address increment?
d) Peripheral construction
* The peripheral can consist of an array of MM slaves, where each MM slaves
* The peripheral can consist of an array of MM slaves, where each MM slave
has the same definition. The length of the array is specified by the
number_of_instances parameter. Arrays are supported via
number of instances parameter. Arrays are supported via
common_mem_mux per array of MM slaves. Each MM slave in the array has start
address at the next power of two address that is free.
For instance:
For example:
BSN Monitor for 4 channels:
-Reg 0
-Reg 1
......@@ -190,7 +226,7 @@ d) Peripheral construction
register and a RAM. The record can also be an array of registers and an
array of RAMs. This is probably easier than supporting an array of records
and this is also how we do it currently manually.
For instance:
For example:
-Reg 0
-Reg 1
-Reg 2
......@@ -200,7 +236,7 @@ d) Peripheral construction
* When multiple peripherals exist in a design, each unique instantiation
of the peripheral will be pointed using a post fix in the name.
For instance:
For example:
reg_bsn_monitor_input (4 channels => nof_instances = 4)
reg_bsn_monitor_mesh (3 channels => nof_instances = 3)
......@@ -220,7 +256,9 @@ d) Peripheral construction
- Peripheral
Attributes: array of Register, array of RAM, array of FIFO, Nof_instances, Instance_name
e) Peripheral instantiation on MM bus
* When instantiating a peripheral from a mmm.cfg file there are two
variables that should be dominated by the mmm.cfg. These variables are:
- Nof_instances
......@@ -228,11 +266,67 @@ d) Peripheral construction
The periheral definition should have default values for these.
* The rom_system_info defines the peripherals on the MM bus based on the MM slave ports:
. base address (can be fixed or free)
. slave name (can have an instance postfix)
. span of the slave (is number of addresses * 4 for 1 instance, for >1 instances the span
is nof instances time the next power of 2 that fits the span of 1 instance)
. number of instances of the slave (>= 1)
* A peripheral consists of one or a group of slaves. If a peripheral supports number of
instances > 1 then the multiple instances are made per slave, so not per group. This
is due to that internally common_mem_mux.vhd is used to create an array of slave ports.
The advantage of this that this scheme typically uses less address range, because the
muliptle instances have to start at power of 2 of their address range. For example:
. a register with 5 addresses has to start at a multiple of 2**3 = 8 > 5.
. a RAM with 768 addresses has to start at a multiple of 2**10 = 1024 > 768
. a periperal of with 5 instances of this register and RAM will first have 5 register
slaves each taking 8 addresses and then 5 RAM slaves each taking 1024 addresses.
Between the last register slave and the first RAM slave there will be a gap in the
address map of 1024 -5*8. The 5 register slave fit in 1024, so in total the periperal
will take (1 + 5) * 1024 address. If number of instances in the peripheral was done
per group of slaves then the peripheral would take (1+1)* 5 * 1024 addresses.
If the peripheral supports multiple instances then this internally taken care of by
common_mem_mux.vhd. However for the register slave the multiple instances may also
be taken care of by having multiple control fields. For example mms_diag_block_gen.
3) Peripheral config file draft format
* The peripheral config file format should support all existing peripherals.
* We will use yaml for the peripheral config file and system config file.
* All peripheral config files have the same name (e.g. peripheral.yaml). A library can
have multiple peripherals (e.g. dp, diag). Therefore each peripheral config file
needs to be in a separate directory. This scheme looks like the hdllib.cfg. Alternative
is to use a specific name with a common prefix (e.g. peripheral_<name>.yaml). The
advantage of a fixed peripheral (prefix) name is that a script can find all peripheral
config files in a rootdir.
* The python script that handles a peripheral config file should preferrably use the
same approach as the hdllib_config.py script:
- find all peripheral config files in one (or more) rootdir
- support similar command line options
4) Appendix: Current common peripheral class in Python
4) System config file draft format
The system config file describes:
- lists all peripherals that are on the MM bus
- clocks
- board support packages
* Typically there is only system.yaml per FPGA design. Therefore the system.yaml can be
kept in the same directory as the hdllib.cfg.
* For the memory map the list of peripherals is sufficient. Per peripheral the system config
file can overrule the default parameter values.
The current peripheral.py script can already read a system.yaml and a set of periperal.yaml:
> python $RADIOHDL/tools/oneclick/prestudy/YAML/python peripheral.py
*) Appendix: Current common peripheral class in Python
class PiCommon():
def __init__(self, tc, io, pi_name, pid, regmap, addr_w=None, inst_name=None, nof_inst=None, derived_reg_methods=None):
......@@ -275,7 +369,7 @@ class PiCommon():
return self.io.writeRegister(node_nrs, self.name, reg_offset, data)
5) Appendix: Example of mmm.cfg:
*) Appendix: Example of mmm.cfg
mmm_name = apertif_unb1_correlator
......@@ -323,6 +417,3 @@ input_clks = mm_clk
synth_master = qsys
vhdl_output_path = src/vhdl/
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment