Close

Trigger-Handler 2.0!

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 11/10/2016 at 22:352 Comments

DUH!

Brief recap (better explained in past logs):

A portion of the sample-memory will be used for a circular pre-buffer. Then, when a trigger is detected, it will jump out of the circular-buffer and begin sampling in the remaining memory.

So the idea is to load the "Free-runner" (memory-controller) with two sequential "Activate [row]" commands... The first would activate the next row within the circular pre-buffer, the second would activate the first row *outside* the pre-buffer. But: Only *one* of these "Activate [row]" commands would be executed, depending on whether the trigger's been detected.

This, previously, was handled by only outputting One "Chip-Select" signal for the two "Activate" commands, alongside only the *first* Activate command. The second would then be "Inhibited."

The trigger, then, would control a MUX, which can selectively delay that "Chip-Select" by one clock-cycle. So, when the Trigger has occurred, that chip-select which was originally alongside the first "Activate" command, will now be delayed to execute the *second* "Activate" command, causing the system to exit from the circular pre-buffer, and enter into the sequential sample-memory.

Here's a *simplified* example from a while-back. (Note that /CSLoop and /CSTriggered should be wired-together for a single /CS input to the circuit):

(Note, this has issues with the case where the trigger occurs *exactly* between the two "Activate" commands, but that has been handled in previous logs. The concept is still the same; selectively delay the input /CS signal).

This concept should work.

BUT:

After the trigger occurs, this system will delay *all* the chip-selects for *all* the commands... Including Read/Write commands. That's OK-ish... So, just repeat each command twice, only one would be executed... no biggie.

I could get into the nitty-gritty details of how the "Free-Runner" (memory-controller) works, again, but I've gone over that in numerous previous logs. But, because of how it works, there remains one slight hurdle... Most commands can be shifted, slightly, without causing trouble. But there are two commands which actually (ideally?) have to occur back-to-back. The "Read" command tells the Free-Runner to begin executing commands from the next memory-page, and the "Write" command tells the sample-memory to sample data at its next memory-page.

(This works because the Read command has an inherent "Latency"... it doesn't start until a couple clock-cycles later, whereas the Write command has no latency, it begins immediately. Thus the two commands can be executed at different times, but will actually *start* at the same time, keeping the Free-Runner and Side-Kick synchronized).

All that to say, if I delay the chip-select after the trigger occurs, then I'd have to have two read-commands, followed by two write-commands, but since the read-command and write-command actually (ideally?) have to occur at specific times, the trigger-handler would affect that. They couldn't be back-to-back. It could be worked-around, but not ideal.

Then BIG DUH:

I really only need to delay the "Activate" command... Or, rather, I really only need to *select* one of two activate-commands... The other commands would, ideally, be left-alone...

So, BIG DUH:

The command-inputs are /RAS ("Row-Address Strobe"), /CAS ("Column-Address Strobe"), and /WE ("Write Enable"). of course, those can be "inhibited" when /CS ("Chip Select") is inactive...

Those, basically, cover the major functions of the memory: Activating a Row and Reading/Writing a column.

And, then, there's NOP... Which is functionally-identical to an "Inhibited" command, except occurs when /CS is *active*... Hmmmmmm

NOP just *happens* to be what happens when all the active-low command-inputs are *inactive*, but again with /CS active.

And /RAS just *happens* to be used for... Strobing a Row-Address... Hmm, like, maybe... "Activating a row"?

Is it possible the *only* command-signal that needs to be activated to switch from NOP to "Activate [row]" is the /RAS signal...?

Yeahp.

So, BIG DUH:

Instead of inserting the trigger-handler between /CS, instead insert it on /RAS! DUH.

The only thing, then, is will it affect our other commands...?

Well, intuitively, /CAS would make sense for Read/Write commands, as those commands begin a read/write at a specific *column*, thus "Column-Address Strobe." Also intuitively, /RAS would make no sense to be active during these commands... That's great, because those, really, are the only two commands that *need* to occur at *exact* times. But, again, this is just intuition, here, and there are a *lot* of commands which don't necessarily work on that intuitive level...

So, what about the others....?

Alright... /RAS only affects "Activate [row]", "Precharge [bank]", "Auto/Self-Refresh", and "Load Mode-Register"...

When sampling data, of these commands only Precharge and Activate are used. Precharge can occur almost whenever, so a delay of one clock doesn't matter. And, Activate, of course, we *want* to be selectively-delayed. Great!

Ah... But... Discussion in a recent-log was about also using the Free-Runner to *initialize* the side-kick (rather than merely telling it when/where to sample data)... And that makes use of both the Auto-Refresh and Load-Mode-Register commands...

And... Now that the Free-Runner's responsible for that, we can't just get away with ... nah, we can. The simple solution is to just *disable* the trigger-handler's "delay" when *not* sampling.

(TODO: Does my current trigger-handler circuit, prior to the MUX, include the possibility to *block* incoming "trigger" signals?) E.G. what happens when *both* Set and Reset are active on a 7474?)

One additional consideration... The Trigger-Handler's delay, now, affects /RAS, rather than /CS... That means it affects commands sent to *both* the Free-Runner *and* the Side-Kick. (There are two separate /CS inputs, one for the Free-Runner, and one for the Side-Kick... But there's only *one* /RAS input, shared between both systems).

... I'm losing steam, but I *think* it's all-good.

AND, I think, the fact that it affects *both* the Free-Runner and Side-Kick actually *also* solves another problem (rather "annoyance") introduced a while back by the circular-prebuffer system...

Guess the question becomes, why didn't I see it before...? Seems friggin' obvious, now.

Discussions

Ted Yapo wrote 11/10/2016 at 23:31 point

I may have missed something along the way ... why doesn't the system continually store into a big circular buffer (the whole memory), and only stop over-writing after some post-trigger delay?  Somewhere I missed the significance of the separate pre-buffer.

  Are you sure? yes | no

Eric Hertz wrote 11/11/2016 at 00:53 point

Awesome question, one I hadn't even considered a possibility, and leads to another thought-point I'd been mulling over.

I guess my logic was that: Since the SDRAM is running much faster than the "Host-interface" it's somewhat difficult for the "host" to keep an eye on which memory address is being accessed/sampled. So, the only way it'd know when to stop sampling would have to be based on something like "dead-reconning" based on *time*, for instance. Another option might be one discussed in a previous log, where I constantly output the row-address at every column within that row... then the host can read that back (slowly) while it's "Free-Running". That's getting a little bit more difficult now that ... (heh, this wouldn't be necessary) I was going to say: now that there's a necessity for *different* addresses to be output. But, that's not necessary if using a single continuous loop. Hmmm...

So, it seems, there's a couple methods for knowing when to stop sampling... time, of course, and watching the address... The only hesitation I have about watching the address is whether at 133MHz, with a small device (like one that has 256 columns per page), would it be that much easier for the host to miss an address-change (while it's also doing other things). But, then, I'm still prototyping with a *really* slow host, compared to e.g. a single-board-computer, that may not be much of a concern. And, several other options, e.g. have just a pin that toggles much less-often, maybe once per every 64 pages, just count a certain number of interrupts. That'd do well-enough, for sure... might lose a few thousand samples at the end of the "loop" but with Millions, that's no big deal.

Hmmm. Really hadn't thought of that as an option with this project... strange, as that's almost exactly how the old sdramThing worked... (one continuous loop). Though triggering was still a ways off, it definitely was planned to be handled under "host"-control.

Whelp, now that you've asked, got some thinking to do...  What *is* the significance of this system...? Spose it's a little less "wasteful" in terms of how many pre-trigger samples are "valid." And *all* the post-trigger samples would be "valid," but again that's not really a concern with all this memory. It does relieve some burden off the "host", so it needn't be watching for the trigger... And, say, the trigger is only a single sample-width, much skinnier than the host's bus-interface could handle, there'd still have to be a latch involved. But the Mux/Selective-Delay wouldn't be necessary at all... four gates and a D-latch saved, right there.

----------------

Ahhh... There was some discussion a while-back about complex-triggering... That's still a bit beyond me, but has been a running-thought ever since. AN idea is to see whether it's possible to do that via the Free-Runner/Side-Kick scenario, where e.g. input-signals might be routed to the address-lines of the memory. (This is something I see as much-more-likely with "older" style memories where they have non-multiplexed address-busses and single-location (rather than burst) access, but is something I've been mulling over, as those two features could be "simulated" to some-extent with a small-enough "look-up-table" fitting in a single row... but also a bit more difficult, here, because the "free-runner" also has to have control over the address-lines when doing the sampling)...

That first implementation might be as simple as merely looking for a parallel data-pattern... but there was also some thought as to whether it could handle, e.g. serial-data-patterns.

Man, that's a *ways* off, but as I see it, something that would require some sort of "jump" system, not unlike that used, here, to "jump" from the circular-buffer to the sequential one. Now that I'm thinking about it, it might not be possible to have *both* a pre-buffer *and* complex-triggering of the sort described, above...

-----

And I still haven't come back to the "other point" this question brought-up... What was that...?

  Are you sure? yes | no