SPI/UART/I2C controllers use a
concept of Descriptor to know from where in the memory data is present, how
much to be transmitted or received, direction
Transfer involves 2 things
Processor filling the memory
with data to be transmitted
Processor configuring
descriptors in to SPI controller
These descriptors will tell
from where in the main memory data is read from
This read data will be
transmitted to the SPI interface using SPI protocol
Configuration
register(pkt_drive_reg) is used to program following
Pkt_drive_reg[5: 0] used to
configure number of words to be processed in one iteration
Pkt_drive_reg[6] = 1 used to initiate the transfer
If we want to 5 iteration, do
(a, b ) 5 times
5 times transfer will
a : how many words to transfer
b : start the transfer
Modeling the SPI slave device
SPI Controller is acting like
SPI master
SPI slave device should collect
data at every +edge of the clock, when data is valid
Read SPI protocol
SPI slave should work on this
protocol
It should exactly collect 32
bits of data (32’hxxxx_xxxx) format
Once SPI slave has collected
data, it will re-transmit it on MISO port back to SPI controller
SPI Controller should have
logic to collect the data coming on MISO
Put this data in to memory,
rx_mem
Write a logic to compare data
from tx_mem to rx_mem
SPI controller is essentially
converting the data that is programmed using APB interface (written in to
Memory) in to SPI protocol, viceversa for the received data
Prst used to reset all the
design variables, regs, memory
Always block Is used to check
whenever there is valid transaction on APB interface
If write is the tx, update SPI
controller memory or registers
If read is the tx, read the
data from SPI controller memory or registers
When ‘Pkt_drive_reg’ register
is programmed with right set of values, SPI controller will initiate the
transfer
SPI slave
Ports: miso, mosi, spi_clk
Logic to decide when the data
is valid
Once data is valid, store the
data in to reg array
Once 32 bits are collected,
transfer that back to controller
Now program SPI pkt_drive_reg
to initiate the transfers
By configuring
pkt_drive_reg[5:0], [6] bits correct values, transfer should happen on SPI
interface
How to confirm design is
working fine
View the waveform
Write checkers to read back
data from rx_mem
In the TB, we wrote tx_mem (to
locaitons 0 to 63)
In the TB, write a logic to
read data from rx_mem (66 to 129 locations)
Compare the words we wrote in
to tx_mem with words read from rx_mem, but not all 64 locations, it is the
number of words we have configured to transfer
Use this comparison as a
criteria to say test is passing or failing.
Display status, before calling
$finish
Further improvements in design
Currently design only supports
SPI protocol only
Design can be updated to
support UART, I2C protocol in same design
First implement them as
separate designs
Once all of them are confirmed
to be working(waveforms, comparisons)
Integrate all the 3 protocol
logic in to same controller block
Use another register to program
which protocol to follow
Improve design further to
support multiple I2C ports, multiple SPI ports, multiple UART ports with
transfer happening on required ports(used programs the registers to decide
which SPI, UART, I2C)