some months back @eyal and I got our hands on a cheap Chinese Spartan 6 board each, QM Tech brand if you’re interested. BTW, I just visited the QMTech Aliexpress store, this board has been discontinued in favour of a DDR3 variant, no wonder we got them cheap. Read on to find out why…
Their XC6LX16_SDRAM product is a very basic FPGA board that breaks out lots of pins on to two convenient 0.1" spaced headers. There are two user buttons, two user LEDs and an SDRAM chip. The designer has obviously done this before because 1) they appear to have made an effort to impedance match the off board signals and 2) one of the I/O banks can have it’s voltage customised, e.g. 1.2, 1.5 etc. The other banks are hardwired for 3.3V operation, no big issue.
The SDRAM chip poses a slight problem. For a start it’s SDRAM, not SRAM. SRAM is EASY to connect to and incorporate into a simple soft processor design, like the 6502 stuff that I like to play with.
What does that extra letter ‘D’ mean? Damn Difficult, if you ask me. For a start the chips they’ve used is an SDR SDRAM, that’s Single Data Rate for the non-gamer types. The Spartan 6 has on chip memory interface logic but will only work with DDR/2/3 (Double Data Rate) chips. If you want SDR then you’ll have to roll you own controller, the Xilinx tools won’t help you.
Never mind. With the whole lockdown thing I have more time than usual to experiment so I spent a good part of Sunday looking in to how to get the SDRAM chip working. Once I stopped trying to do it all myself and ‘stand on the shoulders of giants’ it became surprisingly easy. The first step is to download and read the memory chip datasheet. I’m not going to pretend this stuff is easy, it isn’t, but the datasheet is one of the best I’ve seen, period.
Memory chips in the SDRAM family, i.e. Synchronous DRAM, be they SDR, DDR, DDR2 etc. all have similar characteristics:
- They are clocked and pipelined - this means that memory access is in the form of ‘requests’ and that these requests are queued, taking several clock cycles to generate a result. E.g. a read command is issued, 2-3 clock cycles later the data appears at the outputs.
- For efficiency data is normally requested in ‘bursts’ - E.g. begin read of 4 bytes of data at address 4, 3 cycles later you get data @4, 4 cycles later data @5 etc. Data output continues until either the burst size is reached or an abort is issued.
- They require a complex memory controller - this organises and interleaves the requests with their responses, plus managing the housekeeping tasks like memory refreshes.
Sounds difficult? Yes, it is. However in the space of a few hours I was able to get an open source SDRAM controller working in Xilinx ISE. Some kind soul has posted an excellent implementation to the Opencores website. This example demonstrates a working SDR SDRAM controller and will happily work with the QM Tech board.
To run it up, create a project in ISE using a Spartan 6 LX16 and add the sdram.v file to the project. I’ve added a Verilog test bench to the MHV Github account. Add it to the project and then simulate for 200 microseconds or so. You should be able to see interesting initialisation tasks at the 100us mark.