Close

a merge... and so many branches in this fractal.

A project log for sdramThing4.5 "Logic Analyzer"

An AVR, 128MB SDRAM DIMM, old laptop LCD, and a handful of TTL chips -- 30+MS/s 32-channel logic-analyzer interface for an analog 'scope

eric-hertzEric Hertz 03/11/2015 at 10:390 Comments

So, the "bit grumpy" "reversion" method in the last log seems plausible, except for a couple commands which I'm almost certain the SDRAM would be unhappy with receiving repeated back-to-back.

Instead of reverting to sdramThing3.0 (by removing the one-shots), I did some experiments using the ideas behind the "reversion," merged into sdramThing3.5.

A brief reexplanation of the problem:

It appears that the one-shots are somehow allowing each individual byte/column write to occur in two consecutive columns. The whole point of the one-shot circuitry is to take a signal that's active for multiple clock cycles (a Strobe from the AVR), and cause it to only be active for one clock. But, as far as the SDRAM's concerned, it appears that it's still coming through as active during two. (gate propagation delays, differences in Vih/Vil on different chips' clock inputs...?).

So, I sh/could probably track down the bug, but there're so many possibilities, and 'scoping these tiny timing differences that occur seldomly is difficult... thus my having gotten "a bit grumpy" and thinking of ditching the one-shots entirely.

BUT: I *can* write to any specific column and the one thereafter... AND I only need 1022 of the 1024 columns in each page... So, as long as I write everything sequentially, it doesn't matter if column 1022 contains the same data as 1021, since it's never used, anyhow.

Thus, I'm using the one-shots, and ignoring the bug, using the same reasoning that might've resulted in attempted-removal of the one-shots altogether (as crazy and unlikely-to-work as that would've been).

So, I tried the merge... and it almost-sorta worked, briefly. No errors when reading-back the written-data, so possibly the reason it didn't free-run reliably has to do with not being certain which column "0" corresponds to, when writing, vs. which *actual* column is being written. Though I tested the probable offsets pretty thoroughly. So, another possibility is that somewhere I *don't* write the data consecutively. Specifically, for sure, the last column used to draw an LCD frame is initially linked to the next (unused) page, but then rewritten later to link back to the first page. There may be some other non-consecutive writes elsewhere...

IN FACT, I'm glad I wrote this, to get me thinking... Of Course, the Cursors (and status-bar) are written/drawn non-consecutively!

How could that be a problem....?

The pages are laid out (simplified)...

                    SDRAM PAGE
                    ----------
LCD Data/Timing:   |      X   | (X represents newly-written pixel-data)
                    ----------
Fed-Back Commands: |      PAR | ( P = Precharge, A = Activate Row, R = Read Column )
                    ----------
Yeah... Each page contains BOTH LCD data AND Fed-Back Commands, in different bits within the page...

So each time a pixel is changed, the fed-back command at that same memory location must be calculated and rewritten...

So, if two columns are written each time, where only one should be, then, instead of having PAR, we have PPR.

Bad news.

The next page is not activated, So it tries to grab data from an unactivated page. There is no data, Free-Running dies.

----

So many branches... just keep piling up. For this bit alone.

(It's a wonder I'd ever gotten this thing running, it's like a friggin' fractal!).

First, (and regardless of whether I fix the one-shots or stick with this double-write bug):

I need some way to determine *which* column is *actually* written. This is important because e.g. each Fed-Back "READ" command points to column 0 in the next page. But, if the AVR's WRITE command to column 0 actually ends up in column 2, then the Free-Running Fed-Back "Read" will go to an unwritten column, which may randomly contain something that looks like a Fed-Back command. (It's more than just a matter of whether the column is unwritten, it has to start at the right location in order to keep the LCD's *serial* pixel-bitstream in order...).

...How...? I can be sure that Read and Write occur at the *same* column by simply writing the data then reading it back. But, the only way (I can think) of to determine whether *that* column-data was stored in the proper column (or, more importantly, *which* column it is actually being written to) is by actually initiating free-running and checking where it crashes.

I'm imagining a bunch of pages, the "Data" portion would contain some value that's consistent in every column in the page, but differs from page-to-page (maybe the page number itself). This can be read-back by the AVR periodically. Each page will have the "PAR" commands closer and closer to the beginning of the page (does the first have them start somewhere in the middle, in case the offset is negative?).

At some point, Free-Running *will* crash, because, at some point, the previous page's "Read Column 0 in the next page" command will start a read somewhere *within* the *next* page's "Read Column 0 in the next page" command. However many pages it cycled-through before crashing would indicate the column-offset.

(Bank:     0            1            2            3            0            1          )
Page:      0            1            2            3            4            5
SDRAM Col: 0123456789   0123456789   0123456789   0123456789   0123456789   0123456789
          |----------| |----------| |----------| |----------| |----------| |----------|
Data:     |0000000000| |1111111111| |2222222222| |3333333333| |4444444444| |5555555555|
          |----------| |----------| |----------| |----------| |----------| |----------|
Fed-Back: |   PAR----->|  PAR------>| PAR------->|PAR-------->|AR------(P)>|R-------(PA)>
Commands  |----------| |----------| |----------| |----------| |----------| |----------|

Read/Write:2345678901   2345678901   2345678901   2345678901   2345678901   2345678901
"Column"  
(offset by 2, so PAR was written, in Page 0, to Cols567, but in the actual SDRAM, 
 were stored in columns 345) 

Will this crash at page 4, because the Precharge does not get called before Activation
at the next row...? 
(I'm pretty certain Activate -> Activate causes unhappy SDRAMs. Or, it might result in
 a read at the already-opened page...?)

So, ignoring, for now, the AVR's inability to sample *every* column (too slow), 
it would read, from the data... (Also ignoring the CAS Latency)
00000011111222233344
... and after that we'd get... either 
  floating data-lines (which would probably still show "4" for several samples...
                       even with pull-resistors)
  or 000000011111..... if an activate on an already-activated bank results in no change 
                       to that bank

It's not *difficult*, but it's a lot of work, and there are still a lot of unknowns as to the potential implementation. OTOH, this "auto-calibration" method could be thrown in the main project, and be used again if a new circuit is ever built, which may have different gates with different delays, or different sensitivities to clock-edge-levels, or even when I just change the clock to another that might have shallower/steeper edges...?

Second, I need to either work-around this one-shot dual-write bug, or fix it. Now that I remembered the cursors and status-bar, a workaround seems like nearly as much work as a fix. Again, one option *might* be to use a second register... maybe even a third. But if the issue's due to clock-edge-detection-times, then that might not help... And, then, maybe it's necessary to insert a fast-switching clock-buffer (think I'll have to dig around old motherboards for something like that)... And, even then, there may be an issue with the actual lengths/positions of the clock wires... Maybe I need to change from the star-topology used now to a daisy-chained topology...? Or insert gates in the clock path purely for the sake of a predictable delay... It's getting ugly. At this point, I shouldn't call this sdramThing3.5, I should call it sdramThing4000!

Third, nah... I'm already overwhelmed.

Gotta say, though... the ability to do reliable sampling from an AVR's input on data that's coming in at a 2x faster clock-rate is pretty sweet. Tempted to test out how reliable it is, in sdramThing10k.

Discussions