MCU to FPGA communication - Page 1
Forum section: electronics / general

author: fagiano
author_rank: Regular Contributor
timestamp: September 23, 2013, 02:53:27 pm
content: Hi, I'm designing a board with an MCU(STM32 Cortex-M4) and an FPGA to do few projects that require some light DSP capabilities. I require a decently fast interconnect between the 2 chips, something around 20MB/s+ streaming FPGA->MCU(no addressing required). so I connected the external SRAM controller pins of the MCU and I was planning to implement a synchronous SRAM core. However, as I was reviewing the layout of the board I started to question if burning almost half of the IO pins on the FPGA is really necessary. I'm wondering if there are alternatives to the SRAM controller.I was thinking to see how complicated is to use the SDIO(8-bit MMC) interface instead, that would be about 1/4 of the SRAM pins but the logic required is more complicated.Can anybody share some wisdom? What do you use for MCU to FPGA communication?thank you for your timeciaoAlberto

author: Crazy Ape
author_rank: Regular Contributor
timestamp: September 23, 2013, 03:45:05 pm
content: You've got upto 42 Mbits/s on the SPI ports. If you've got one of the STM32F4's with a camera port, that's gives you upto 54 Mbytes/s, though you have to make the FPGA look like a camera to the MCU and I'm not sure what data formats are involved.Generally you do all the heavy lifting on the FPGA and only use the MCU for control signalling info to the FPGA if required. Is there a reason you need to get so much data to the MCU?You could use DMA and an IO port to talk in parallel to the FPGA.

author: free_electron
author_rank: Super Contributor
timestamp: September 23, 2013, 03:58:14 pm
content: keep in mind that for serial comms (if there is no dma engine) you are wasting lots of cpu time for the trnsactions to complete.i always implement a 11 wire bus ( or more )8 bit bidirectional data. 1 bit that selects data/cmd, 1 r/w bit, 1 clockbit.you can do whatever you want in the fpga.data is written if cmd is low and write is high on rising edge of clkdata is read if cmd is low , write is low on rising edge of clockcomand same but then with cmd highi create commands like0x00 : reset0x01 : set address . this is followed by 2 or 4 byte writes as data ( 16 or 32 bit address) addresses auto increment when reading wirting data0x02 : do this0x03 : do that.and so onif i can have more pins i expand the databus to be 16 bit wide or 32 bit wideor i inject a couple of address linesthe command register then can take the data from the databus and the address lines select the commandcmd high :address 0 write = resetaddress 1 write : set address for next operationaddress 2 write : do this with arguments in databusblabla ...in general the EMIF of your cpu can deliver all you need. since you have an arm the emif can even do the 32 bit to 16 or 8 bit translation for you. it will give you a flah for high word low word or 2 bits for the byte selection.you write a 32 bit word form code and the EMIF does the splitting into words or bytes. a simple register in the fpga reconstructs.

author: abyrvalg
author_rank: Frequent Contributor
timestamp: September 23, 2013, 05:07:33 pm
content: fagiano, which pins did you connected for SRAM mode? With little cheating you can reduce the pin count as much as you need:1. drop all (or some) address pins, since you don't need addressing. Just don't connect them and don't implement on FPGA side, MCU will not notice this - you'll just get the data port aliased to many addresses.2. change data bus width freely - even if you connect some really odd number of data pins (like 13), you just need to mask the data on MCU side to drop trash bits from unconnected lines and it should work

author: fagiano
author_rank: Regular Contributor
timestamp: September 23, 2013, 07:10:20 pm
content: mmh that all makes a lot of sense. It didn't occur to me I could just ignore some part of the interface like the address. For some reason I thought "If I use SRAM I gotta have all 26 bits of address". thank you all, now I'm looking at the problem in a different light. I think I'll go back to the drawing board. I suspect a 16bits wide sram data with only a few bits of address would be perfect(maybe even 8 bits is enough).Why do I need all this data? I need to stream it over USB to a PC.thank you againciaoAlberto

author: abyrvalg
author_rank: Frequent Contributor
timestamp: September 24, 2013, 10:55:40 am
content: If you just need to stream data in a fixed order, you can ignore addressing (Ax, AVD) totally - just drive D[] with next data word at right CLK edges according to CE, OE, or assert WAIT when not ready. Look at SRAM read waveforms - MCU doesn't expect any answer to addressing itself, it looks at data stage only.

author: fagiano
author_rank: Regular Contributor
timestamp: September 29, 2013, 03:49:12 pm
content: FYI I just successfully prototyped my MCU->FPGA communication. I ended up only connecting 16 bits of data bus and various signals/clock for a total of 24 pins. I use a PSRAM interface in synchronous burst mode with 16 bits of data and 16 bits of address multiplexed on the same pins. I haven't done any benchmark but considering that the bus clock is 84MHz and the burst can do 16 bits per clock after 4 clocks of address setup, it should be way faster than my requirements.thank you all for the adviceciaoAlberto

author: nctnico
author_rank: Super Contributor
timestamp: September 30, 2013, 10:39:43 am
content: Maybe too late but you could have implemented an ethernet MAC in the FPGA. This is not difficult and there is hefty buffering and DMA available at the MCU side.

author: Harvs
author_rank: Super Contributor
timestamp: October 02, 2013, 10:53:52 am
content: Quote from: nctnico on September 30, 2013, 10:39:43 amThe ethernet interface, like all the others on this device, has a smallish FIFO (2KB in this case) and quite flexible DMA so you setup the main buffer in the main SRAM.You can do the same thing with the external memory interface, which is considerably slower than internal RAM depending on the timing configuration.For the DMA, just set it to do mem to mem transfers with incrementing internal address and your set. This memory interface (FSMC) is really quite flexible, I've been using it to communicate with a high speed parallel ADC recently. It's just their application note only addresses using it as a memory controller, they probably could have added a couple of paragraphs on using it as a generic parallel data interface.

author: abyrvalg
author_rank: Frequent Contributor
timestamp: October 02, 2013, 09:42:59 pm
content: There should be NAND flash interface also, which is efficient in data cycles / address cycles

author: NiHaoMike
author_rank: Super Contributor
timestamp: October 03, 2013, 02:26:06 am
content: Quote from: free_electron on September 23, 2013, 03:58:14 pmI'm doing something a little similar except it's for interconnecting a dsPIC and an OpenWRT platform. There are 6 wires, 4 data, a clock, and a frame sync. The clock is DDR, so on the rising edge, the upper 4 bits are sent or received and on the falling edge, the lower 4 bits are sent or received. (The application doesn't need much bandwidth, but there's about a foot or two of wire between the OpenWRT and the dsPIC, so a parallel bus allows me to use low frequencies. Also, I designed the bus for easy and efficient implementation with GPIO.) On a falling edge of the frame sync, the master (OpenWRT in this case) sends the command and read/write, similar to I2C. When the frame sync is high, the bus logic is reset to a known state.