--- Quote Start ---
Thanks for your comments, Cris72, Socrates and K_J
Would this really be impossible? I was thinking we could possibly multiplex the signals between the 2 SDRAM controllers, since the read and write operations are separate. That is, we use a signal/flag that tells us whether we are writing or reading from SDRAM, and using that signal to choose the addr, data, write_select, etc. signals from the controller in SOPC while in write mode, and then choose signals from the other controller when in "read" mode.
I haven't done it before though, so I'm not quite sure what complications might arise.
--- Quote End ---
KJ: Two controllers imply that you're accessing two independent SDRAMs therefore anything you write to one SDRAM from your one source is not accessible to be read by your other source...therefore yes, it is impossible because it does meet your functional requirements.
What you're describing though is arbitrating access to a
single SDRAM and its controller. The muxing you described is the final part of that arbitration. In particular, the muxing would occur after the arbiter has decided who gets access to the SDRAM.
SOPC Builder allows you to be somewhat oblivious to this by allowing you to connect up multiple masters to a single slave but that is simply because it generates the arbitration logic for you. Slave interfaces on SOPC components describe nuances that will affect how that arbitration logic gets generated. For example, some devices can be switched between bus masters on every clock cycle without penalty; others, such as SDRAM and other memories, usually cannot.
For SDRAM, when you switch between bus masters, you likely switch between SDRAM pages which will cause the controller to have to open a new memory page which takes some overhead. In that case, if you quickly switch back and forth between who has access to the memory, you can be thrashing the memory and get very poor performance. On the other hand, the thing that is requesting access to the memory generally can't wait forever for the request to be granted so there is a tradeoff between how long it can wait and the overall performance. Arbitration logic needs to take these things into account. All of this is simply meant as a background on arbitration logic which may or may not be important to you, the main point is that what you're describing as reading and writing memory is really that there are two different memory requestors so those requestors must be arbitrated...either via SOPC Builder or your own arbiter.
Likely the simplest thing is for you to create a DMA Controller and make it into an SOPC Builder component that you can then connect right up in SOPC Builder. Then the arbitration logic can be taken care of for you and you can remain somewhat unconcerned about exactly how this arbitration actually happens. Within that basic construct you'll have to make an Avalon master which generates the address and read signal to the SDRAM. This component gets added in SOPC Builder, you tell SOPC Builder to connect it to the SDRAM Controller component and you're mostly done.
For the streaming output interface of the DMA Controller that provides the data to your custom modules you have a decision to make about whether you want that to be an Avalon interface or not. My guess is that the most expedient method for you would be to not make this Avalon compliant, simply a custom interface. You do that when you create the component by telling the tool that those signals are to be exported. You then manually connect up the exported signals to your modules.
Now your task is simply to create the logic for the DMA Controller. As I mentioned you'll need to have something to create the memory address and the size of the block of data that needs to be moved. How does that happen? Do you need to have the processor set this up by a processor? If so, your DMA Controller will need a third interface, likely an Avalon slave that is read/writable by whatever it is that will set these things up. It's also conceivable that in your application you might have hard coded numbers to use here, no external setup required.
Now that you have some method for reading data from memory from your DMA Controller logic, you'll need to format that to be compatible with what your existing modules are expecting for input from a camera. Some likely issues you may run into are:
- Maybe the camera provided a large burst of data, then a gap but your access to SDRAM in the new system might not. How will you provide that block?
- If providing a block of data from SDRAM is not really feasible, how do you want to modify your existing modules to work with 'bursty' data from the SDRAM?
The task you're solving with the DMA Controller is the logic required to source data from a memory interface rather than a camera interface.
--- Quote Start ---
Yes you are correct. This is exactly my situation. This seems to be the way to go, at least for now. I'm afraid I'm not very familiar with DMA, though. Do you think it's straightforward enough to quickly write one myself, or do you suggest I use the megacore?
--- Quote End ---
KJ: A DMA Controller is very simple, it consists of two loadable counters; one that generates the memory address the other which counts down how many things need to be moved (i.e. the block size) and of course some minimal logic for controlling when the thing is running and when it is idle. DMA Controllers have a minimum of two interfaces, one for the memory, one for the data stream. Generally there is a third one for setting up the parameters needed to run the memory interface.
Kevin Jennings