DMA Transfers between a slow peripheral and a SDRAM
I'm trying to implement a SoC for image processing on a Virtex 4 FX12 device. My system is composed of a PPC, a PLB bus, a Central PLB DMA controller, and I developped an interface to a CMOS sensor using IPIF wizard. The aim is to dispose of a line buffer with a FIFO and to use the DMA to transfer the full image to an external SDRAM without PPC intervention. In order to save FPGA ressources, and after many tests, I chose not to use the DMA/SG and RDFifo services in my IP, and prefered to implement my own FIFO using Coregen.
Ideally, I'd like to ask the DMA to manage a full image transfer by initializing it once (at each new image) and let it do the rest. The fact is that PLB burst reads are done approximatively 32 times faster than writing in the FIFO. As a consequence, the FIFO becomes empty quite often, and an error occurs on PLB each time the DMA tries to read the FIFO while it's empty, which stops the transfer.
My question is simple : how can I set a DMA transfer in a wait state while the FIFO in my IP is empty? Which PLB signals should I use?
Perhaps it would be easier to only start a burst transfer when the FIFO
has sufficient data for the whole burst? You can add "count"
outputs to your CoreGen FIFO or a programmable almost empty flag to
determine if the FIFO has the appropriate number of words. If you
need to empty the FIFO, e.g. at the end of a video frame, you can set a
flag that says the end of frame has been written to the FIFO and in
that case only allow the DMA burst to start whenever the FIFO isn't
I already tried this solution, by initiating (using interrupts) a DMA transfer at the end of each line, with the size of a complete line : this seems to work for the first 10 lines or so but it fails when trying to capture a whole image this way (fails when trying to capture about 30 lines). In this version, I was using two interrupts : one at each end of line (horizontal sync) and another at each end of image (vertical sync).
Moreover, I tried to use programmable empty flags (or almost empty flags) and this does not seem to be sufficient to block and postpone the PLB read request.