Interface FPGA and microcontroller - Page 1
Forum section: electronics / general

author: gauravmp
author_rank: Regular Contributor
timestamp: May 23, 2016, 03:48:14 pm
content: Hi,I'm pretty new to FPGAs but I'm fairly competent in microcontrollers and have used a wide variety of those. I'm wondering if anyone has a suggested reading list for interfacing an FPGA with a microcontroller. Any list of books would be appreciated.Thanks.

author: asgard20032
author_rank: Regular Contributor
timestamp: May 23, 2016, 03:50:17 pm
content: You don't need a book for that. MCU mostly use slow speed bus, such as SPI, I2C and UART. You won't plug an mcu to an FPGA trough PCI express or usb. The easiest way to implement your interface would be to use SPI. Since its a synchronous protocol, that can be reprenseted with simple shift register. It is also the one that offer the greatest speed for a micro controller.

author: nctnico
author_rank: Super Contributor
timestamp: May 23, 2016, 04:00:28 pm
content: If the interface is purely digital then SPI is a good way but it will need clock domain crossing inside the FPGA.

author: Daving
author_rank: Contributor
timestamp: May 23, 2016, 04:04:00 pm
content: Agreed. SPI would be easiest. Make the MCU the master and the FPGA the slave for the easiest configuration since you're more comfortable with MCUs.

author: rstofer
author_rank: Super Contributor
timestamp: May 23, 2016, 04:54:23 pm
content: Quote from: Daving on May 23, 2016, 04:04:00 pmWhich might be the hard way around when it comes to creating a slave device on the FPGA.I have only done this once and the FPGA was the source of data so I set it up as a master. The slave was an MBED and I was clocking the SPI at 6.25 MHz. To do this, I had to use an interrupt driven bit of code on the uC. It all works well. In my view, it was better to do the code intensive work on the uC.Now, if the uC is running Linux (Raspberry PI) then all bets are off. I'm pretty sure the PI can only be a master. This is true for other packaged uCs as well.

author: langwadt
author_rank: Super Contributor
timestamp: May 23, 2016, 05:09:07 pm
content: Quote from: nctnico on May 23, 2016, 04:00:28 pmsorta, if you can avoid it don't use the spi as clock, sample the signals and detect changes instead

author: John_ITIC
author_rank: Frequent Contributor
timestamp: May 23, 2016, 05:49:50 pm
content: The way I do it is to simply use an 8-bit I/O port on the uC with a couple of extra 'address latch, 'write' and 'read' strobe signals. The uC first outputs the address and strobes 'address latch'; the FPGA sees the strobe and clocks in the address. Synchronization of the strobe signals is needed but not the data since will be stable by the time the strobe comes around. Once the uC is writing, it puts the data on the bus and strobes 'write'. The FPGA sees the 'write' strobe and puts the data into its register file (mem <= data). Same for read but 'data = mem'. Regular bidirectional port Verilog rules apply. The uC sets up the I/O port direction depending on if it is reading or writing.

author: gauravmp
author_rank: Regular Contributor
timestamp: May 23, 2016, 06:04:39 pm
content: Thanks a lot for the help guys!!! Really appreciate it! Would you guys have any book recommendations for learning more advanced FPGA programming? I can implement basic digital sequential and combinational circuits. But I'm unsure how to implement something like SPI or UART....Thanks again.

author: rstofer
author_rank: Super Contributor
timestamp: May 23, 2016, 06:21:53 pm
content: Quote from: gauravmp on May 23, 2016, 06:04:39 pmI have several HDL books and they all take the same approach of discussing gates, implementing a few trivial circuits and then showing an equally trivial state machine. Not one useful circuit in the bunch. Maybe I have the wrong books...SPI is just what you think it is: As a master, you drop the CS' signal, wait as long as the receiving device requires before clocking (read the datasheet) and then start clocking bits at an acceptable rate. Finally, raise the CS' signal after a delay as required by the datasheet. And abide by whatever is required for the idle state of the clock.A slave device could be a great deal more difficult because you first need to come across the clock domain (clock every signal into the FPGA) and somehow have the data bit ready with enough setup time for the uC. This is where you will spend a LOT of time with the uC datasheet.The bits per transaction are determined by the uC. The FPGA doesn't care how long it is.Sign up with OpenCores.org, they have a bunch of SPI implementations under Projects -> Communication Core.

author: gauravmp
author_rank: Regular Contributor
timestamp: May 23, 2016, 06:35:35 pm
content: Quote from: rstofer on May 23, 2016, 06:21:53 pmThanks a lot man! haha yes, there are a lot of timing requirements that i'll have to consider. I'll try it out. thanks

author: nctnico
author_rank: Super Contributor
timestamp: May 23, 2016, 07:20:29 pm
content: I would take anything from Opencores with a large number of grains of salt. What I have seen so far is very poorly coded and resulting in very bulky logic. If it works and you have enough space and don't need speed then using something from Opencores could be a solution.

author: Scrts
author_rank: Frequent Contributor
timestamp: May 23, 2016, 08:10:03 pm
content: I also vote for SPI. We've used in a couple of designs. Don't ever use SPI clock as clock input, since it's not continuous. Synchronize on CS signal and oversample the clock signal with internal clock.

author: rstofer
author_rank: Super Contributor
timestamp: May 23, 2016, 08:27:27 pm
content: Quote from: nctnico on May 23, 2016, 07:20:29 pmAnd for a person just starting out, what is the option? They need to look at something and it certainly won't be in a text book. Or at least not in the books I have bought. If there is a book that covers useful circuits, I would certainly be interested in buying it.Once the overall flow is understood, the logic can be reduced.I just sat down and coded the FSM but I didn't have to worry about oversampling because I coded a master.

author: nctnico
author_rank: Super Contributor
timestamp: May 23, 2016, 09:23:56 pm
content: First hit when Googling for 'VHDL recipes':http://store.elsevier.com/Design-Recipes-for-FPGAs-Using-Verilog-and-VHDL/Peter-Wilson/isbn-9780080548425/

author: Kjelt
author_rank: Super Contributor
timestamp: May 23, 2016, 09:30:33 pm
content: Oh just a beginners tip you might already know, if you are used to microcontrollers, you are probably used in thinking in the serial software design domain, that is everything happens after eachother.In vhdl and logic everything you describe in code happens at the same clock tick, all parallel (exceptions there of course).This is one of the big challenges I think, it is as big a going from C to a full OO design

author: gauravmp
author_rank: Regular Contributor
timestamp: May 23, 2016, 09:35:52 pm
content: Thanks guys!!!

author: asgard20032
author_rank: Regular Contributor
timestamp: May 24, 2016, 12:08:44 am
content: Quote from: Scrts on May 23, 2016, 08:10:03 pmNot sure exactly I understand how to implement it using oversampling.

author: rstofer
author_rank: Super Contributor
timestamp: May 24, 2016, 12:52:49 am
content: Quote from: asgard20032 on May 24, 2016, 12:08:44 amI'm not sure I know how to implement it at all! I'd have to think about it. Oversampling might not be a good answer and maybe just finding the edge of the clock signal will work. That might turn out to be pretty easy.I haven't thought about SPI slave - it can't be too hard, people do it all the time.

author: Someone
author_rank: Super Contributor
timestamp: May 24, 2016, 03:47:39 am
content: Quote from: rstofer on May 24, 2016, 12:52:49 amOversampling for majority voting and edge finding is relatively easy to include on these relatively slow serial interfaces, and makes it easy to have the FPGA slave running in its own fast clock domain. For interfaces less than 10Mb/s its tempting to just use UARTs.

author: AndyC_772
author_rank: Super Contributor
timestamp: May 24, 2016, 06:56:35 am
content: One of the hardest things to get right in a 'my first FPGA' design is the configuration interface, and it's the clocking that's at the root of the problem.Chances are your FPGA has a clock input which is reasonably fast and which runs continuously. This master clock is used to drive the various counters, timers, state machines and other logic in your design, and unless you end up simply trying to do too much per clock cycle, it's unlikely to cause you too many problems. The timing relationships between all the various elements are known, and your synthesis tool contains a simulation model of the device which allows it to fit your logic in a way which is guaranteed to work.The problem comes when trying to receive information from another source, such as your MCU, which runs off a different clock. If the relationship between the two clocks is unknown or is not fixed, then it's impossible to know when it's "OK" to sample any input from that source, because there's always the chance that it'll be changing state at just the wrong moment.When this happens, at best you'll get the wrong data. At worst, it'll break your design in a way which, literally, seems to defy logic. (Search for "metastability" and have a good read).So, at some point in your design, you need a mechanism to 'import' data from outside into the master clock domain, ie. that region of your logic which is all driven from the nice predictable, continuous clock.For an SPI interface, and especially for one that doesn't need to run too quickly, the easiest way (IMHO) is to treat SCLK as an asynchronous logic signal, rather than actually using it as a true clock. Whenever you sample a signal which is not synchronous to a known clock, you can ensure it's read reliably by double-sampling. In VHDL:Code:IF mclk'event AND mclk = '1' THENsclk_meta <= sclk_pin; -- this is the one and only time that sclk_pin is referenced<other code involving sclk_meta>END IF;The SPI interface updates when SCLK is recognised as having changed state. For example, if the interface is designed such that both master and slave set up on falling edges and sample on rising, your code might be:Code:IF mclk'event AND mclk = '1' THENsclk_meta <= sclk_pin;sclk_prev <= sclk_meta;IF sclk_prev = '0' AND sclk_meta = '1' THEN -- rising edgemosi_m <= mosi_pin; -- no need to double sample this because we know it's stable at this pointEND IF;IF sclk_prev = '1' AND sclk_meta = '0' THEN -- falling edgemiso_pin <= miso_m;END IF;END IF;This technique works well for fairly slow SPI clocks. The fastest SPI clock it can possibly work with reliably is about 1/4 the speed of the master clock; this is because there needs to be a master clock edge on which the following conditions are true:- 2 clocks ago SCLK was low- 1 clock again SCLK was high- on this edge, MOSI is OK to sample, ie. is not changing

author: rstofer
author_rank: Super Contributor
timestamp: May 24, 2016, 01:54:08 pm
content: When setting up the output, the data must first be fetched from <somewhere> and placed into a register to be shifted out on MISO. This, in my view, is where it gets difficult. Suppose MOSI comes in as a command to select a value stored in BlockRAM. Before the master is allowed to shift the value out (presumably with the next group of clocks) we have to fetch and register the data.I looked briefly at this datasheet and it shows data shifted out on the very next clock after receiving a command. CS' is not toggled between the sending of the command and shifting of the result.http://www.atmel.com/Images/Atmel-8707-SEEPROM-AT25010B-020B-040B-Datasheet.pdfThis is an interesting problem. Much more exciting than creating a master!

author: AndyC_772
author_rank: Super Contributor
timestamp: May 24, 2016, 02:03:22 pm
content: That's why clocks have two edges :-)

author: Scrts
author_rank: Frequent Contributor
timestamp: May 24, 2016, 05:00:12 pm
content: Quote from: rstofer on May 24, 2016, 12:52:49 amWell, you elaborate that further correctly. You oversample the incoming signals looking for edges, then sample the value.Good thing is that your sampling frequency is relatively high, it doesn't matter what the SPI bus speed is and you can modify the master code to increase the bandwidth.

author: gauravmp
author_rank: Regular Contributor
timestamp: May 24, 2016, 05:36:51 pm
content: Quote from: AndyC_772 on May 24, 2016, 06:56:35 amThanks a lot for your advice!

author: josuah
author_rank: Regular Contributor
timestamp: May 10, 2022, 05:50:56 pm
content: Quote from: langwadt on May 23, 2016, 05:09:07 pmQuote from: Someone on May 24, 2016, 03:47:39 amAnd this was tried and seems to work fine for him:https://zipcpu.com/blog/2017/06/08/simple-wb-master.htmlhttps://zipcpu.com/blog/2017/06/05/wb-bridge-overview.htmlP.S.: I know, sorry, this is an old thread. It might still be helpful for travelers coming from search engines.

author: DiTBho
author_rank: Super Contributor
timestamp: May 10, 2022, 06:52:24 pm
content: Implement a simple uart device, and use it. Up to 2Mbps can be achieved and it's enough for basic use.

author: josuah
author_rank: Regular Contributor
timestamp: May 11, 2022, 03:52:22 am
content: I was wondering how I would handle Wishbone ACKs with SPI: there may be any (hopefully short) number of STALL cycles before the Wishbone peripheral answers. It is not enough to insert dummy cycles like done for SPI: the delay is not guaranteed constant-time.Let's try with UART with sampling for now! It UART will let the answer happen asynchronously (A in UART after all) "when it's ready": whenever the slave happen to answer.

author: SiliconWizard
author_rank: Super Contributor
timestamp: May 11, 2022, 05:22:39 pm
content: Quote from: Daving on May 23, 2016, 04:04:00 pmIf the MCU supports SPI slave (which most do these days) and the OP is not comfortable with FPGAs, I would actually suggest the opposite.As others have pointed out, implementing SPI slave in the FPGA will require clock domain crossing and I wouldn't suggest that for a first project even to my worst enemy.

author: SpacedCowboy
author_rank: Frequent Contributor
timestamp: May 11, 2022, 05:56:09 pm
content: There's a fairly simple treatment of SPI <-> ARM (ARM master and FPGA slave) atfpga4fun.com. Clock-crossing it may be, but it's not so terrible to understand what's going on when the code is explained as it's written...

author: khach
author_rank: Contributor
timestamp: May 12, 2022, 10:45:41 am
content: SPI to slow for my application. But QSPI probably get enough speed of communication. Any example of realization such QSPI slave in FPGA side?

author: Bassman59
author_rank: Super Contributor
timestamp: May 12, 2022, 08:28:20 pm
content: Quote from: khach on May 12, 2022, 10:45:41 amIt's pretty trivial to implement QSPI in an FPGA.What gets interesting is if the QSPI in the FPGA has to interpret instructions sent on only one of the four lanes, or whatever other weirdness might be involved.

author: Scrts
author_rank: Frequent Contributor
timestamp: May 12, 2022, 08:41:20 pm
content: Quote from: khach on May 12, 2022, 10:45:41 amSPI works well at 20Mbps. Do you really need more? If so, I'd opt for some parallel bus, like STM32 FSMC. If it's one way, you can also utilize camera interface.