# 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 &lt; nrRWregs; nn = nn + 1)
begin :nnRW
assign rwRegs1D[32*nn+31:32*nn] = registers[nn];  // flatten
end
for ( nn = 0; nn &lt; 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 &lt; nrRWregs; nn = nn + 1 )
begin :nnRW
assign registers[nn] = rwRegs1D[32*nn+31:32*nn];
end
for ( nn = 0; nn &lt; 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.

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

### 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.

### Sources

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

• SPI Slave, main module, spi_msg.sv on Altera (or spi_msg.v on Xilinx)
• SPI Slave, message interface, spi_msg_if.sv on Altera (or spi_msg_if.v on Xilinx)

### 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. ASHOKE CHAKRABORTY says:

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 says:

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

3. Yes, that is what this project does. It uses SPI with Arduino being the master.

4. Thanks. This project uses SPI. Both I2C and SPI are well established and documented.

5. Hus says:

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) ??

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