Math Talk

This continues the third part of the inquiry Math Talk. This page shows a master implementation of the message protocol described earlier.

Messages Exchange with FPGA as Slave

The implementation builds onto the Byte Module code shown earlier. We will start by explaining how to pass multidimensional arrays through ports.

Registers

On Altera, we can the multidimentional arrays available in system verilog HDL

wire [nrRWregs+nrROregs-1:0] [31:0] registers;

The implementation is slightly more complicated on Xilinx, because Verilog 2001 doesn’t allow multidimensional arrays to be used as inputs or outputs. Instead, we work around this by flatten the 2D registers array into two vectors. One for input, and one for the output ports as shown in the code fragments below.

Flatten the 2-dimensional array, registers, into vectors rwRegs1D and roRegs1D

genvar nn;
wire [31:0] roRegs2D[0:nrROregs-1];
for ( nn = 0; nn < nrRWregs; nn = nn + 1)
   begin :nnRW
      assign rwRegs1D[32*nn+31:32*nn] = registers[nn];  // flatten
   end
for ( nn = 0; nn < nrROregs; nn = nn + 1)
   begin :nnRO
      assign roRegs2D[nn] = roRegs1D[32*nn+31:32*nn];  // inflate
   end

Inflate the vectors, rwRegs1D and roRegs1D, into a 2-dimensional array registers.

wire [0:31] registers[0:nrRWregs+nrROregs-1];
genvar nn;
for ( nn = 0; nn < nrRWregs; nn = nn + 1 )
   begin :nnRW
      assign registers[nn] = rwRegs1D[32*nn+31:32*nn];
   end
for ( nn = 0; nn < nrROregs; nn = nn + 1 )	
   begin :nnRO
      assign roRegs1D[32*nn+31:32*nn] = registers[nn+nrRWregs];
   end

Timing

The timing diagram below shows the relation between the different signals at the message level on Xilinx.

own work
Timing for XIlinx implementation

The Altera implementation is more optimized, as it needs to run at 200 MHz. The gate level simulation is shown below;

own work
Timing for Altera implementation

Finite State Machine

This message module converts the bytes into messages and visa versa. The protocol is implemented using a state machine with 4 states:

  • Idle (0)
  • Transmit status (1), transmits 8-bit status to master
  • Transmit register value (2) , transmits a 32-bit register value to the master
  • Receive register value (3), receives a 32-bit register value from the master

An additional state-like variable, byteId, is used to keeps track of what byte to transmit or receive.

own work; requires browser svg support
SPI Finate State Machine

Sources

The complete project including constraints and test bench is available through Github. The two main files are listed below.

Verification

To verify the implementation, run the test bench (spi_msg_tb.v) using gate level simulation. This test bench will monitor the communication and report errors when found. In the real world, we connect the Arduino SPI Master that acts just like the test bench.

The next part explains how to proceed using this SPI message protocol.

Embedded software developer
Passionately curious and stubbornly persistent. Enjoys to inspire and consult with others to exchange the poetry of logical ideas.

5 Replies to “Math Talk”

  1. Very well explained. I am looking some details with respect to interfacing Arduino with FPGA (Altera) using I2C where FPGA is a master and arduino is slave.

  2. Can we use this project to establish a communication between Arduino and FPGA?

  3. The Two-stage shift register here is used to synchronize only the serial clock coming from Master. Right? Or do we need to sync the rest signals (i.e MOSI, SS, MISO) ??

Leave a Reply

Your email address will not be published. Required fields are marked *

 

This site uses Akismet to reduce spam. Learn how your comment data is processed.