Jump to content
  • 0

PSRAM chip baked, or am I just high?


kc5tja

Question

Greetings everyone.  I'm Samuel A. Falvo II, creator of the Kestrel-3 home-brew computer project.  I'm currently using the Nexys-2 board as a development platform, since that's a known-working software/hardware configuration for me.  My plan is to migrate to something different/better after I get a working reference model here.

Related to this project, I'm completely ineffectual at getting the PSRAM chip to function.  I was wondering if someone else has created a 16-bit Wishbone(-compatible/-like) interface to the PSRAM chip that I can re-use in my MPLv2-licensed project.  After a month of trying to hack my own, I've come to the conclusion that my PSRAM chip is utterly dead on arrival:

  • When in asynchronous mode, I could never get the chip to respond to memory writes beyond a certain (and seemingly completely unpredictable) point.  But, it could read OK, as evidenced by a stable image of noise on my monitor (video refresh is configured to use external memory).
  • When in synchronous mode, I'm utterly unable to get the PSRAM chip to drive the DQ pins when trying to read from the chip.  As a result, video shows a stable pattern of pixels corresponding to the last 16-bit word written out to memory (since this precharges the DQ lines, the video circuit sees this state and treats it as valid pixel data).  It is completely unknown if it's actually responding to write transactions.

I just don't know, and honestly, I'm getting rather desperate now.  So far as I'm able to tell, I'm well within the timing parameters of asynchronous and (especially) synchronous mode operation.  If there's an existing design I can re-use to sanity-check my design, that would be especially helpful.  Thanks in advance.

Link to comment
Share on other sites

15 answers to this question

Recommended Posts

It works with the BIST code, but that's the only place it seems to work.  Under any other circumstances I've attempted to use the PSRAM chip, it has either failed outright to commit writes, OR, has failed to drive the DQ pins on read, as per my bullet list above.  The EPP controller is inscrutible to me, I don't know what it's doing or how it does it.  Moreover, it's bottlenecked with an 8-bit bus; I really need a 16-bit bus.

Per your suggestion on IRC about using an on-chip logic analyzer/scope thing, I attempted to write one that would work for my hardware, but it ends up crashing ISim when I attempt to simulate it.

I'm --><-- this close to just throwing in the towel on the project, after having spent years working on it.  I'm about ready to tell people, "You get 48KB of block RAM, and that's that.  Have fun."  No more 16MB, not even 256KB.  I'm just so very, very, very frustrated right now.

 

Link to comment
Share on other sites

@kc5tja,

Looking over your code this morning, I notice nowhere where you register the outputs into flip-flops before actually sending them to I/O ports, not even in your top level file.  As a result, you may find the I/O pins still switching during the between clock intervals when you believe they are constant.  Further, Xilinx recommends using an ODDR module on any clock output path to avoid having logic glitches in the path, such as you might have if you output the result of a combinatorial process as you have chosen to do.  (Having said that, I can't seem to find where I read that recommendation earlier ...)

Dan

Link to comment
Share on other sites

@kc5tja,

One more note regarding the Epp being an 8-bit interface: I built a converter some time ago to convert from the DEPP 8-bit interface to a 32-bit interface.  You can find that converter here.  I'm not using that code anymore, though, since I later moved to a simpler converter that turns the DEPP words into an 8-bit data channel, that can then be used with an 8-bit to 32-bit wishbone bridge that also handles address and data compression.  That's the wbubus.v module you were looking at the other night, though this link has it without the obfuscation.

Dan

Link to comment
Share on other sites

2 hours ago, D@n said:

@kc5tja,

Looking over your code this morning, I notice nowhere where you register the outputs into flip-flops before actually sending them to I/O ports, not even in your top level file.  As a result, you may find the I/O pins still switching during the between clock intervals when you believe they are constant.  Further, Xilinx recommends using an ODDR module on any clock output path to avoid having logic glitches in the path, such as you might have if you output the result of a combinatorial process as you have chosen to do.  (Having said that, I can't seem to find where I read that recommendation earlier ...)

Dan

Adding registers to the address and/or data output buses (the only signals w/out registers) introduces a clock of latency.  This means now I'd need _seven_ clocks per individual hit to RAM, and it would rule support for 16-color 640x480 displays impossible.  Like I said on IRC: accesses to memory must consume no more than six clocks.  That is a hard limit.

Also, does a Spartan 3 series FPGA even have ODDRs?  I don't recall reading about them in the Spartan 3 family documentation.  Maybe I missed them.

Link to comment
Share on other sites

Two definitions of "it works" are, (1) I can use external RAM for a video frame buffer, and (2) the CPU runs no slower than 2 MIPS.

So far, the lack of this chip's ability to adhere to published documentation on its timing parameters forced me to degrade this project's features twice already, and leaves me to believe that the Nexys-2 is simply inappropriate for what I'm trying to do.  I'm not willing to do it a third time.  I'm evaluating now if my time would be better spent just porting the project to use another FPGA board equipped with real static RAM.

Link to comment
Share on other sites

Found an old project written by a colleague that should help out:

https://www.dropbox.com/s/rfth9tixtgp5di1/MemCtlForCellularRAM_orig.zip?dl=0

That project contains a very reusable HDL block for reading a framebuffer out of the PSRAM to VGA using synchronous mode and multiplexes in async writes. A rough draft of documentation for it can be found here:

https://www.dropbox.com/s/2xjpq68z5kqcovr/MemCtlForCellularRam.docx?dl=0

The top module example included in the zip above is a Nexys2 project that uses the sub component to stream in a test pattern (whenever SW0 is high) and constantly read out the PSRAM contents to the VGA. I found this project in an old archive on my computer, but unfortunately I am not in the office so I can't test it. I do recall it working though... 

 

 

Link to comment
Share on other sites

I built and tested that project using the 500 chip, which probably explains your error. Try replacing the equivalent 4 lines in your pins.ucf file with these:

#NET "LED_O<4>"      LOC = "E16";     # Bank = 1, Pin name = N.C., Type = N.C.,                             Sch name = LD4? other than s3e500
#NET "LED_O<5>"      LOC = "P16";     # Bank = 1, Pin name = N.C., Type = N.C.,                             Sch name = LD5? other than s3e500
#NET "LED_O<6>"      LOC = "E4";      # Bank = 3, Pin name = N.C., Type = N.C.,                             Sch name = LD6? other than s3e500
#NET "LED_O<7>"      LOC = "P4";      # Bank = 3, Pin name = N.C., Type = N.C.,                             Sch name = LD7? other than s3e500

You will also need to retarget the project for the s3e1200, but I'm assuming you already did that  because it threw an error.

Another thing to double check is that the FIFO IP cores are included in the project as .xco coregen files and not prebuilt .ngc netlists (because they would have been built for the wrong part). If you see them in the project explorer pane as .ngc files, remove them from the project and then add the .xco files (the .xco files are all included in the project directory).

Link to comment
Share on other sites

Glad to hear it!

I'm not sure what is causing the instability, but off the top of my head, I'd guess that the 640x480 pixel clock may not be exactly correct. The project uses a 25MHz clock, but I think it is actually supposed to be 25.175 MHz. You could try messing with the clock generator to get closer to this. 

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...