Close

sdRamblingThing Concepts, revisited

A project log for sdramThingZero - 133MS/s 32-bit Logic Analyzer

Add an old SDRAM DIMM to your SBC for a 133MS/s 32-bit Logic Analyzer, add ADCs for a Scope...

eric-hertzEric Hertz 04/15/2022 at 19:460 Comments

I've been contacted, recently, about someone's interest in trying this out... Specifically, if I understand, trying to create a state-machine with lookup-tables.

I think it important to note HOW this thing [supposedly] works:

Unlike typical Static or Dynamic RAMs, which you just supply an address and it gives the value at that address, SDRAM has a function called Read-Burst (also write-burst).

When you start a read burst at some address, it outputs the data from that address, then automatically outputs the data from the address after that one during the next clock cycle, and so-on for a selectable number of addresses. E.G a typical burst-length setting is 4 or 8 locations.

All the SDRAM chips I've worked with can be configured to burst an entire row of data (usually 256, 512, or 1024 bytes). 

But, of course, a 1MB chip has way more than 1024 bytes... So a single read-burst /cannot/ output the entire chip's contents. 

To do that, you'd have to start a new read-burst in the next row immediately after the first burst completes. (actually, due to CAS-Latency, it has to be started a few clock cycles *before* the previous burst completes, if you want an uninterrupted burst of two rows, or i.e. 2048 bytes).

So, what I've done is add a second identical SDRAM chip in the mix (This is easy when using a DIMM!). This second chip is addressed with the same address bits, uses [most of] the same command-inputs. When a read-burst is initiated on the original chip, that same read burst occurs in this new/second chip. So, now, the two chips together burst 2 bytes simultaneously.

Now, there's no reason to limit this to two chips. A DIMM actually has 8 chips or 8 bytes' worth of chips... So, I group them into two groups, each 4bytes wide...

The memory I want to burst-read (or write) is 4bytes, 32bits. This is the Sample-memory in sdramThingZero (and #sdramThing4.5 "Logic Analyzer") logic-analyzer.

This can also be, say, a framebuffer to drive a LCD... or, basically anything one might want to output/input in a huge continuous burst.

Again, that group of chips, alone, would only be able to burst a maximum of 1024 32bit words, before requiring a precisely-timed NEW read-burst command, telling it to begin a new burst from the next row.

So the other group of chips, 4 bytes' worth/32bits, is loaded-up with that command. This group (I call the "FreeRunner") has its data outputs tied [mostly] directly back to both groups' command/address inputs. (The other group, the "memory" for sampling, or a framebuffer, I poorly named "The SideKick"). 

So, Now, the FreeRunner and the SideKick BOTH burst the same addresses at the same time. The FreeRunner is MOSTLY filled with "NOP" commands, so mostly doesn't interfere with a row-burst. BUT a few addresses shy of the last address in the burst, it requests a new burst in the next row. Which begins a few clock cycles later, immediately after the first completes.

That's a bit simplified, but should do for now.

Fill the FreeRunner with commands such that the SideKick will burst its entire contents in a continuous stream, 32 bits from each address, once per clock cycle.

Great for sampling data in a logic analyzer, great for refreshing an LCD, I dunno what-all.

....

So, the FreeRunner basically does little else than cycle through all the addresses in the DIMM.

Unfortunately, not much at all like an EPROM lookup table, more like a VGA card. Heh. 

...

However, it /is/ a bit like a very limited CPU, The addresses' incrementing after each NOP is a bit like a program-counter.

Now, it is possible to send different commands to the Sidekick and Freerunner. Each group of 4 bytes has a separate Chip-Select. So, e.g. in a logic-analyzer setup, the Freerunner is always burst-reading (outputting the commands stored in it) while the Sample Memory (SideKick) may be burst-writing (sampling data, storing it in memory) OR burst-reading (outputting the stored samples back to the host computer (or LCD/Oscilloscope, in sdramThing4.5).

One is reading the other is either reading OR writing...

So, if you're clever, you *can* decouple the FreeRunner's and SideKick's addresses, and actually have them doing different things. They needn't burst the /entire/ contents, maybe just a few addresses in a short loop, or plausibly repeatedly outputting the same address for read-back to a much slower bus... 

....

BUT there are MANY considerations. 

First-Off, the address lines are the same for both systems, so even though you can tell one to ignore the command (via chip select), only one "command" can be stored in each memory location. So, the two cannot be given differing instructions at the same time; they'd have to be interleaved.

(I was able to get away with the FreeRunner reading and SideKick writing at the same addresses at the same time because read bursts start three clocks later, whereas write-bursts start immediately. The read command was three addresses *before* the write command).

But here's a really big "gotcha"...

The entire memory must be refreshed, regularly, regardless of what small loop you're running...

So, say you're in a loop waiting for external input... E.G. I thought to add a level-sensitive "trigger" to the logic analyzer.

Before the trigger occurs, the RAM must be refreshed... So the idea was to use as many addresses as necessary to refresh all the rows *within* the "wait for trigger" loop... Say it's 1024 rows by 1024 cols, for a 1MB/chip... That means the wait for trigger loop has to be at least 2048 cols, or two rows, Just For Refreshing. (Open Row/Close Row=Refresh Row). 

For the sake of responsiveness, I'd probably put the trigger test between every row refresh, so now we need at least 3 rows, 3000+ addresses/"instructions" just for the loop that detects the trigger.

On the plus-side, I could be repeatedly burst-writing in the SideKick during this time, which would mean it would have 3000+ samples in a circular-buffer *before* the trigger in case that'd be useful.

...

But the point is, as a "state machine," well... it's a lot of work.

...

Now, take my FreeRunner idea and burst-reads out of the picture, and it may be easier to treat the SDRAM like any ol' SRAM/EPROM; a bit of external glue/latching logic to access a memory location in a linear fashion... And since it wouldn't be constantly bursting, one could put it in AutoRefresh whenever it's not being accessed...

...

So, I guess the quick of it is that this concept of using the memory [FreeRunner] to control the memory [SideKick and FreeRunner] is pretty obscure and probably only has a few niche use-cases for which it's probably not even really well-suited. Heh.

It works well for a logic-analyzer whose host-computer/bus is too slow, or too imprecise, to reach the speeds the RAM itself can achieve. It doesn't really make for a very good framebuffer, since writing to it would interrupt the video-feed...

There MAY be other interesting uses, but it's almost certainly not a good idea for a product, unless that product is trying to make use of old tech, keeping it out of ewaste. Heh.

Oh, and BTW, since it's usually the first question: No. It'd be FAR more difficult to implement this in DDR, burst lengths are limited to 8 addresses, or 4 clock cycles, which is *barely* enough to start the next burst. Nevermind weird voltages and timing constraints.

...

It would be quite interesting to see where this technique could go, but it's probably not at all what one might expect going in... That's kinda exactly what made #sdramThing4.5 "Logic Analyzer" so interesting, it seemed to take a path that I would've never predicted, based on weird quirks and limitations... E.G. who woulda thought to put Cursors in the FreeRunner, and thus in a separate yet parallel framebuffer for Blue?

[Heh, this writing didn't come out at all like I expected when I started... I had examples and better explanations that have vanished from my awareness! But, this unexpected-path isn't nearly as interesting, nor maybe as positive/useful, as sT4.5's. Heh.]

Discussions