I had generated an integrated logic analyzer (ILA) with 32 signals to watch. After a first run, I assigned a few more of the 32 and regenerated, but whenever I launched the ILA on the hardware, it showed only the original set of signals. This is yet another of the well known misbehaviors of the toolchain. Fortunately there was a way to force the update.
SPOTTED WHY MY MEMORY INTERFACE WAS SHUTTING DOWN
Since the example runs well but my logic does not, but we use the exact same memory interface and clock wizard settings, I began to look very carefully at any tiny difference. All at once, I spotted the reason my memory was stalling, both in simulation and real life.
The user can ask the memory interface to accomplish three special tasks - refresh, ZR calibration and self-refresh requests. The designer can ask the memory interface to do a calibration if they believe that errors are occurring which can be minimized by another round of calibration. The designer can also control the memory refresh timing
Normally the memory interface will generate refresh cycles to the DRAM chips to keep the cells charged, accessing each row and each column regularly enough that the capacitors that form the cell don't discharge. A designer who wants complete control over this can turn off the automatic refresh and instead call the memory interface to do a refresh at specific times. This can position the refresh activity at a time when it won't delay time critical read or write requests.
These are not normally used by designers, thus I thought I had those requests turned off. However, I though these were active low requests, thus a 0 value would request them. As such, I instantiated the memory interface with constants of binary 1 for these three request lines. I was wrong. Arrrgh. They needed to be set to binary 0.
I reran a simulation now that the requests are set to 0, and the problem with the memory interface disappeared. I can now debug my logic that calls the memory interface, since it can be trusted to provide memory access.
WHY UPLOADER NO LONGER RUNS TO COMPLETION
The logic for uploading the disk cartridge contents from RAM writes out the first header, for cylinder 0, head 0, sector 0 then tries to read word 0 of the sector. Nothing is printed and the word address sits at 1 after that point. It was apparently working to completion of the cartridge when it was running at 921,600 baud but after my conversion of the output to 115,200 baud, it stopped.
I moved the ILA from the dram controller module to the uploader module which is where the failure appears to occur. After wiring all the relevant signals, I generated the bitstream and started up the board. The problem was indeed relative timing. My dram controller module will raise the signal dataready but only for one cycle. If my state machine in the uploader is still busy pumping out the header message, by the time it looks for the dataready flag, it has gone back to 0.
The solution was to interlock the request for data from dram controller. The caller, uploader module, will keep echoword high until it sees dataready come back. The dram controller won't drop dataready until it sees the echoword request turn off.
I have a bit of cleanup and optimization to do in the uploader module now that it is basically working. After this, I imagine I will need a working Diablo drive to debug further.
No comments:
Post a Comment