Wednesday, March 4, 2015

Reworking the DDR memory controller

In between other things, I have been reimplementing the DDR memory controller wrapper, as I attempt to get DDR memory working.

The Digilent supplied wrapper, while good, had a lot of the signal control logic spread around, rather than my preferred (but probably horrible to other people) style of keeping related logic together.  This made it hard to me to actually follow what was going on.

This also gave me the opportunity to switch it to using an 8-bit wide data bus instead of 16-bit, simplifying logic in the CPU a little.

It also allowed me to make the DDR wrapper cache the 16-bit memory line once read, so that subsequent reads could be serviced from the cached copy.  The cache gets updated by writes, to ensure consistency.

I also modified the wrapper so that it accurately reports to the CPU when it has finished servicing a request, so that there is no longer any need to tune the number of waitstate applied to slow ram.  Together with the little cache, this means that the DDR-based slowram will hopefully be faster on average than the old slowram was -- at least once I get it working.

In the process of debugging the caching code (which still has a bug in it), I also made the realisation that much of my trouble with the DDR memory controller is that it was not registered to the CPU clock, and so it was possible for glitching to occur.  Indeed, I noticed this because I finally realised that the funny memory behaviour I was seeing looked very much like cross-clock glitching, where the CPU would sometimes read the previous byte value from the memory, because the memory data hadn't been updated quickly enough, as can be seen below.

 :8000000 92 92 21 01 01 9B 4C 19 19 03 16 16 08 62 55 55
 :8000010 92 2C 21 21 31 9B 9B 19 39 03 03 00 08 08 55 01
 :8000020 92 92 21 01 31 31 4C 19 19 03 16 00 00 62 55 55
 :8000030 01 2C 21 21 31 9B 4C 4C 39 03 03 00 08 62 62 01
 :8000040 92 2C 2C 01 31 31 4C 19 39 39 16 00 00 62 55 01
 :8000050 01 2C 21 01 01 9B 4C 4C 39 03 16 16 08 62 62 01
 :8000060 92 2C 2C 01 31 9B 9B 19 39 39 16 00 08 08 55 01
 :8000070 92 92 21 01 01 9B 4C 19 19 03 16 16 08 62 55 55
 :8000080 92 2C 21 21 31 9B 9B 19 39 03 03 00 08 08 55 01
 :8000090 92 92 21 01 31 31 4C 19 19 03 16 00 00 62 55 55
 :80000A0 01 2C 21 21 31 9B 4C 4C 39 03 03 00 08 62 62 01
 :80000B0 92 92 2C 01 31 31 4C 19 39 39 16 00 00 62 55 01
 :80000C0 01 2C 21 21 01 9B 4C 4C 39 03 16 16 08 62 62 01
 :80000D0 92 2C 2C 01 31 9B 9B 19 39 39 16 00 08 08 55 01

 :80000E0 01 92 21 01 01 9B 4C 19 19 03 16 16 08 62 55 55

Taking a look at this memory dump it can be seen that the various byte values sometimes turn up one memory access late.  It is also possible that in some instances one or more of the data lines turns up late, while others are okay, although there isn't really clear evidence of this. Indeed, if you look at each column, there are only two values in each column, and no hybrid ones. Presumably one is the "on time" value, and the other is the "late" value, i.e., the value from the previous read.  Based on this, we can conclude that the correct values would be:

92 2C 21 01 31 9B 4C 19 39 03 16 00 08 62 55 01

However, that is really just speculation until I resynthesize with the ram_done signal delayed by a cycle to make sure that the data turns up first.

Also, there is the question of why the same 16 bytes of data are being presented every time, instead of the correct 16 bytes being read.  Writing to the DDR memory is also not working with my wrapper yet, so I need to debug that as well.  But at last I feel like I am making progress, and will be able to get the DDR RAM working properly soon.

3 comments:

  1. Nice update - the C65 seems to be getting closer, one cycle at a time! :) Speaking of which - are you aware of Dallas Moore's "Original Commodore 64C Computer Housing in New Cool Colors" Kickstarter project? Even though he uses original C64 molds, I can't help but think what he could potentially add to your table (look at that super bright and Amiga-esque C64 case, for instance!).

    https://www.kickstarter.com/projects/1670214687/original-commodore-64c-computer-housing-in-new-coo?ref=users

    ReplyDelete
    Replies
    1. Hello,

      Thanks for the heads up on this! I have just made a little post to spread the word on this, as well as ordering a bright white case for myself. I totally agree that having a C65GS board inside a real brand-new C64C case is an appealing combination.

      Delete
    2. The pleasure is all mine - although I'm about to setup an Ethernet-connected C128 for my 8-bit gaming and development needs, I would _love_ to devote one additional router port to a brand new C65-clone in a bright white Commodore-styled case (built in 3,5"-floppy drive or not!).

      Hopefully, your new post will stirr up some additional interest in the mold project, too!

      Delete