.. role:: raw-html-m2r(raw)
:format: html
.. _bus_slave_factory:
Bus Slave Factory
=================
Introduction
------------
In many situation it's needed to implement a bus register bank. The ``BusSlaveFactory`` is a tool that provide an abstract and smooth way to define them.
To see capabilities of the tool, an simple example use the Apb3SlaveFactory variation to implement an :ref:`memory mapped UART `. There is also another example with an :ref:`Timer ` which contain a memory mapping function.
You can find more documentation about the internal implementation of the ``BusSlaveFactory`` tool :ref:`there `
Functionality
-------------
| Currently there is three implementation of the ``BusSlaveFactory`` tool : APB3, AXI-lite 3 and Avalon.
| Each implementation of that tool take as argument one instance of the corresponding bus and then offer following functions to map your hardware into the memory mapping :
.. list-table::
:header-rows: 1
:widths: 2 1 10
* - Name
- Return
- Description
* - busDataWidth
- Int
- Return the data width of the bus
* - read(that,address,bitOffset)
-
- When the bus read the ``address``\ , fill the response with ``that`` at ``bitOffset``
* - write(that,address,bitOffset)
-
- When the bus write the ``address``\ , assign ``that`` with bus's data from ``bitOffset``
* - onWrite(address)(doThat)
-
- Call ``doThat`` when a write transaction occur on ``address``
* - onRead(address)(doThat)
-
- Call ``doThat`` when a read transaction occur on ``address``
* - nonStopWrite(that,bitOffset)
-
- Permanently assign ``that`` by the bus write data from ``bitOffset``
* - readAndWrite(that,address,bitOffset)
-
- Make ``that`` readable and writable at ``address`` and placed at ``bitOffset`` in the word
* - readMultiWord(that,address)
-
- | Create the memory mapping to read ``that`` from 'address'.
| If ``that`` is bigger than one word it extends the register on followings addresses
* - writeMultiWord(that,address)
-
- | Create the memory mapping to write ``that`` at 'address'.
| If ``that`` is bigger than one word it extends the register on followings addresses
* - createWriteOnly(dataType,address,bitOffset)
- T
- Create a write only register of type ``dataType`` at ``address`` and placed at ``bitOffset`` in the word
* - createReadWrite(dataType,address,bitOffset)
- T
- Create a read write register of type ``dataType`` at ``address`` and placed at ``bitOffset`` in the word
* - createAndDriveFlow(dataType,address,bitOffset)
- Flow[T]
- Create a writable Flow register of type ``dataType`` at ``address`` and placed at ``bitOffset`` in the word
* - drive(that,address,bitOffset)
-
- Drive ``that`` with a register writable at ``address`` placed at ``bitOffset`` in the word
* - driveAndRead(that,address,bitOffset)
-
- Drive ``that`` with a register writable and readable at ``address`` placed at ``bitOffset`` in the word
* - driveFlow(that,address,bitOffset)
-
- Emit on ``that`` a transaction when a write happen at ``address`` by using data placed at ``bitOffset`` in the word
* - | readStreamNonBlocking(that,
| address,
| validBitOffset,
| payloadBitOffset)
-
- | Read ``that`` and consume the transaction when a read happen at ``address``.
| valid <= validBitOffset bit
| payload <= payloadBitOffset+widthOf(payload) downto ``payloadBitOffset``
* - | doBitsAccumulationAndClearOnRead(that,
| address,
| bitOffset)
-
- | Instanciate an internal register which at each cycle do :
| reg := reg | that
| Then when a read occur, the register is cleared. This register is readable at ``address`` and placed at ``bitOffset`` in the word