SRAM timing


Recommended Posts

I have a 2MB Papilio Duo (Kickstarter edition), with the Classic Computing shield, that I'm using for my first serious FPGA project.  I'm using it as a simple FPGA board, so not using the Arduino side, and doing everything myself in VHDL.

I've run into a problem writing data to the SRAM.  My design uses 4 cycles of a global clock for each memory access.  Writes go like this:

  1. /OE <= 0, /WE <= 1, set address, tristate data
  2. /OE <= 0, /WE <= 0, assert data to write
  3. wait
  4. /WE <= 1

My test configuration follows this with a read:

  1. /OE <= 1, set address, tristate data
  2. wait
  3. read data
  4. wait

Unless I've made a mistake (spoiler: I have almost certainly made a mistake), with a 160MHz global clock this should fit comfortably in the SRAM's timing requirements.  At 80MHz it works fine.  At 128MHz it's OK most of the time, with occasional errors.  At 160MHz it's failing very frequently.

I'm fairly sure that it's the writes that are failing: when it's connected to a larger design that copies a ROM into RAM and then displays the contents of RAM on VGA, I get a stable image with missing pixels here and there.  But I can't see what I'm doing wrong.  Can anyone help?

I'll attach my stripped-down SRAM testbed.  I'm very new to VHDL, so comments on style are welcome too.  I'm probably doing everything wrong.  LED1 blinks briefly when the data read back from SRAM doesn't match the data that was written.



Link to comment
Share on other sites

Answering my own question.  Don't put stuff outside the process unless you want it to be horrible and glitchy.  The simulation shows nice in-spec signals, but in reality it was getting occasional glitches that my logic analyser was having trouble seeing.

It's still not working, in ways that I don't really understand, but at least I've got something to go on now.

Link to comment
Share on other sites

  • 1 month later...

I found out what my problem was.

The fact that it worked when I lowered the clock frequency was a big clue that it was something to do with timing.  I since discovered the trce timing report (I said I was new to all this), and that told me what I was doing wrong.

After the falling edge of mclk, clockPhase must make its way to the output of its latches, go through some logic, then make its way to the clock enable of addressPins and dataPins before the next rising edge of mclk.  It has 3.125ns to do all this, and that's not quite enough.

I had clockPhase being latched on the falling edge because I wanted it to be stable before and after the rising edge where all the action happens.  It seems this wasn't such a good idea.  What I should be doing instead I'm not sure, but I will certainly be asking trce for its opinion in the future.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.