It can be difficult to get logic and block rams in a Spartan to go at 200MHz (the speed I want to run the DDR memories), but we can work on this concept.
Although there are more complex approaches (with minimal return for the extra logic), we can generally treat a RAM chip as able to do one thing at a time. There are four independent banks. For each bank, you have to open a row before you can access a column (memory cell). Before accessing a column in a different row, you have to close (precharge) the one that's open. Also, there are refreshes. Based on which row is open for your bank and what command was performed most recently, a read or write may require precharge, active, and no-op cycles. (CAS latency is a separate issue.) There are two main ways I've seen memory controllers done. One works well for FPGAs: You have a single counter, and your timing parameters are hard-coded constants compared against that counter. This works well and is fast since it's fast to compare a register against a constant. The other approach is programmable (so it can go into an ASIC). You have registers that are loaded with your timing numbers, and perhaps multiple counters. Only when a counter is zero can you execute its associated command. What I'd like to try to do is once again turn hardware into a program file. Instead of counters, the current machine state is used to generate an address into an on-chip block RAM, and that's used to handle delays. Here are some random thoughts I have on this: Let's say the delay between an activate and a read is 5 cycles, and the delay between a read and a precharge is 5. BUT the delay between an activate and a precharge is 12 cycles. This is simple enough. Somehow, the read command and the current state generated a starting program counter address for the block ram (maybe via a config register). The data outputs from the RAM indicate two major things to the controller: Which memory commands to assert on the memory control bus (like the precharge and activate commands), and which controller commands are acceptable at a given time. So, rather than having a 3-bit counter to count those 5 cycles, there are 5 "instructions" in our program file. Here are some things that would be involved in major state transitions (implicit branches): - Is the row for this bank open? - If it's open, is it a hit or a miss? - The command being issued to the controller. Some things that the instruction would indicate: - Is this a read command (CAS latency handled separately)? - Is this a write command? - Memory command - What to select to put on bank pins - What to select (row, col, etc.) to put on address pins - Which controller commands are allowed on the next cycle Commands to the controller: - Read - Write - Precharge all - Load mode register - Refresh This is a high-level design topic. You don't need to know hardware (much) to help with this. Just think about how the controller needs to behave and see if you can find a way to turn current state and requested controller command into realtime code. _______________________________________________ Open-graphics mailing list [email protected] http://lists.duskglow.com/mailman/listinfo/open-graphics List service provided by Duskglow Consulting, LLC (www.duskglow.com)
