Skip to main content
Topic: Advanced Trigger Questions (Read 10152 times) previous topic - next topic

Advanced Trigger Questions

@dogsbody,
Thank you for your huge contribution! I am excited about the new trigger capabilities.

@all
I have not looked at Verilog until now, and have some questions about the advanced trigger that I hope someone else can answer until I learn the language enough to figure it out.

To understand the trigger system, and with an eye toward a trigger configuration user-interface (and application perhaps), I attempted to flesh-out the trigger resource and sequence illustrations shown in the OLS FPGA specification (which is a beautiful creation in its own right!). The attachment (Visio native and SVG format available on request here) is the result.

Edit: I replaced this with an updated "version 2" from the post below.
[attachment=0]
Notes: I simplified the range mask operation (implied bit packing for arbitrary bits).

0. Is the topology correct?
1. Did I include all the parameters that a user would need to set (manually or via a macro)?
2. Are the parameter options (uppercase) appropriate?
3. Do the term operators 'op2' and 'op3' allow a single input (i.e. A/B/C/D and A/B, respectively) to be selected? The spec leaves me thinking no.
4. Does the Hit term duration count specify contiguous hits ('duration'-width pulse detector) or just totalize hits (allows signal to change between count increments)?

Hopefully the answers to these questions will be useful to others as well.

Thanks.

Re: Advanced Trigger Questions

Reply #1
flubberlab, nice job!  To answer your questions...

0) The topology looks fine.

1/2) Parameters look good.  Might want to add an enable/disable flag to the term inputs though.  See below.

3) Yes, the "op1/op2/op3" operators allow a single input.  They are LUT tables themselves & can be configured to implement -any- function.  Figure 23 in the spec contains the example "A" & "B" columns accordingly.  In the HP16550, the various inputs (ie: a/b/c/range1/d/edge1/etc...) had an Enable/Disable control.  The op stages only offered "and/or/xor/nand/nor/nxor".  In the case of the OLS, the client needs to configure the op1/op2/op3 stages to match the input enable/disable state.

4)  Currently, the hit-term counter tracks total hits.  To handle contiguous hits, you'd need to use the "else" state.  So if you miss on the hit-state, configure an else-term to jump to another state -- or even just back to the same state.  Taking the else-path zeros the hit-count.

Cheers!
-- IED
-- debugging hardware at 2am is a bad idea...

Re: Advanced Trigger Questions

Reply #2
So the Enable/Disable and Pass/Invert are implemented in the 'op' LUTs, but would typically be exposed separately for the user's ease-of-use benefit?

From the user's point of view, the 11 op blocks could be rolled into one block? But, of course, the interesting part is how the user would specify the operation (another topic).

I had lumped the resource terms (a/b/c/range1/d/edge1/etc...) into pairs, because I thought that they would be restricted that way given the op block topology. I am still trying to get my feet wet and arms around what it means to do any operation and its capabilities, so maybe I was wrong.

Are all the resource terms treated equally, i.e. can they "cross-reference" each other arbitrarily in the op?

I can see how useful a canned macro library, like the 16550 has, would be!

Pretty soon this should probably be moved to the Client Software section.

Here is the updated "menu map."

Re: Advanced Trigger Questions

Reply #3
Yes, enable/disable on terms is simply for ease of use.

The op blocks connectivity is not infinitely flexible.  The drawing accurate shows the connections -- which mirrors the 16550 pretty closely.  However, by using "a-only" or "b-only" op-blocks (ie: disabling unused inputs), you can combine any term with another to some degree. 

If the user needs a really complex function, then they must assign terms to permit it. 
-- IED
-- debugging hardware at 2am is a bad idea...

Re: Advanced Trigger Questions

Reply #4
@ian,
I just noticed your addition of the drawing at http://dangerousprototypes.com/2011/04/ ... r-support/. Wow, it's like being in the phone book! Thanks.

Just FYI, I updated the first post with a more recent version. I probably should have added it, and not deleted the first version, which is gone for good.

Re: Advanced Trigger Questions

Reply #5
No problem. It's great to see movement on the advanced triggers, and I thought we might inspire some other Java programmers to get involved too.

I'm not experienced with Java, so I can't add new features to a big project like Jawi's client. I can help with algos and related code though, and maybe get better at Java along the way.
Got a question? Please ask in the forum for the fastest answers.

Re: Advanced Trigger Questions

Reply #6
That's right; I was glad you were trying to bring in some Java programmers  (to help jawi I assumed).

I have not yet touched Java except to look at jawi's client. Not wanting to jump in yet (intent on helping to robustify the serial interface, I have been poking around with VC++ (and MFC) to get an app going quickly with a serial interface I am familiar with.

Re: Advanced Trigger Questions

Reply #7
Great writeup, flubberlab! It greatly aided me in understanding the advanced trigger support in IEDs firmware.

While I'm currently finishing up the 0.9.4 release, I intend to prepare the client for advanced triggers as of the 0.9.5 release. Aside the new signal display component, this might be the next big feature...
when good software is not an alternative...

Re: Advanced Trigger Questions

Reply #8
BIG KICK!

I've started a small side project to start developing the advanced trigger support provided by the demoncore.

Many thanks to flubberlab, as his diagram greatly aids (still) in understanding the full functionality of the adv. triggers. I've got a couple of questions though while reading the demoncore spec and various manuals of the HP165xx analyzers:

  • does the "while storing"/capture term only apply for the state-mode triggers, or for the timing-mode triggers as well?
  • for the state-mode triggers, one can enable and disable the final capture-trigger signal, while for timing-mode triggers only can enable the final capture-trigger signal only?
  • the ANY/NOP operations, on which terms of the trigger sum do they apply? I understand ANY means always one, and NOP always zero, but how does this translate to a sensible trigger sum?
  • Where is the inversion of pair inputs handled? By means of the pair operation itself?
  • Does the demoncore support the less than/greater than occurrence counts, I couldn't really find it in the specs;
  • Is the occurrence count samples for both timing-mode triggers as well as state-mode triggers?
when good software is not an alternative...

Re: Advanced Trigger Questions

Reply #9
Don't get too confused by the 16550 manuals.  :-)

1) The advanced trigger itself doesn't perceive state mode (ie: external clock) vs timing mode (ie: internal clock).    It only sees samples.  So yes, the "while storing" term applies to both on the demon core.

2)  The demon core trigger is a one time thing.  Once you flip the trigger, the OLS captures everything.  For selective capturing, use the per-sequence state capturing control instead.

3)  The ANY/NOP operations could be used anywhere.  However, only NOP really makes sense.  The pair LUT & mid LUT operations can use them to ignore inputs.  ie: ignoring a specific trigger input or an entire branch of trigger inputs. 

4) Inversion must be handled within the pair LUT's.  Since trigger terms are the LUT inputs, you have total control over how they are parsed.  It is a little confusing...  I'll update my spec with some example code.  I've attached more detail below.

5) The demon core has a per sequence state hit counter.    So for example, a given sequence state could be setup to require 42 occurrences/matches before recognizing a hit.  If the target trigger is a less/greater than, you should be set.  Perhaps there is something in the 16550 spec I'm missing?

6)  Yup.  As in #1, the trigger only sees samples.  So counts can be used for both timing & state modes.

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

Ok, inverting inputs.  It's confusing because of how I implemented the first state "pair" LUT's for maximum packing in the fpga.  Trigger terms (a,b,c,...,h,i,j) output two bits, both of which must be true to signal a hit. 

For example, the OR & NOR operations from the pairvalue table become:

--OR--   --NOR--
0xF888   0x0777   (not-inverted)
0xF777   0x0888   (invert "A" input)
0x8FFF   0x7000   (invert "B" input)
0x7FFF   0x8000   (invert both)

To invert the "A" input, exchange 0x7's with 0x8's (& visa versa).    To invert the "B" input, swap the most significant nibble with all lower nibbles.  To invert both, do both.

Here are updated functions that support inverting trigger inputs.  Instead of accessing the pairvalue array directly, I use a new function to handle the inverting:

Code: [Select]
int get_pairvalue(int op, int invert_a, int invert_b)
{
  static int flipa[] = {0,0,0,0,0,0,0,8,7,0,0,0,0,0,0,0xF};
  int value = pairvalue[op];

  if (invert_a)
    value = (flipa[(value>>12)&0xF]<<12) | (flipa[(value>>8)&0xF]<<8) |
            (flipa[(value>>4)&0xF]<<4) | (flipa[value&0xF]);

  if (invert_b)
    value = ((value & 0xF)<<12) | ((value>>4) & 0xF00) |
            ((value>>8) & 0xF0) | ((value>>12) & 0xF);

  return (value);
}

void write_trigger_sum (
  int statenum, int stateterm,
  int invert_a, int invert_b, int invert_c, int invert_d, int invert_e,
  int invert_range1, int invert_edge1, int invert_timer1,
  int invert_f, int invert_g, int invert_h, int invert_i, int invert_j,
  int invert_range2, int invert_edge2, int invert_timer2,
  int op_ab, int op_c_range1, int op_d_edge1, int op_e_timer1,
  int op_fg, int op_h_range2, int op_i_edge2, int op_j_timer2,
  int op_mid1, int op_mid2, int op_final)
{
  int pv_ab = get_pairvalue(op_ab, invert_a, invert_b);
  int pv_c_range1 = get_pairvalue(op_c_range1, invert_c, invert_range1);
  int pv_d_edge1 = get_pairvalue(op_d_edge1, invert_d, invert_edge1);
  int pv_e_timer1 = get_pairvalue(op_e_timer1, invert_e, invert_timer1);
  int pv_fg = get_pairvalue(op_fg, invert_f, invert_g);
  int pv_h_range2 = get_pairvalue(op_h_range2, invert_h, invert_range2);
  int pv_i_edge2 = get_pairvalue(op_i_edge2, invert_i, invert_edge2);
  int pv_j_timer2 = get_pairvalue(op_j_timer2, invert_j, invert_timer2);

  write_select (0x40 + (statenum*4) + stateterm);
  write_chain (finalvalue[op_final]);
  write_chain ((midvalue[op_mid2]<<16) | midvalue[op_mid1]);
  write_chain ((pv_j_timer2<<16) | pv_i_edge2);
  write_chain ((pv_h_range2<<16) | pv_fg);
  write_chain ((pv_e_timer1<<16) | pv_d_edge1);
  write_chain ((pv_c_range1<<16) | pv_ab);
}
I think this is right.  Been a while since I last thought about this.  Cheers!
-- IED
-- debugging hardware at 2am is a bad idea...

Re: Advanced Trigger Questions

Reply #10
[quote author="dogsbody"]Don't get too confused by the 16550 manuals.  :-)[/quote]

*grin* I won't; but I can assure you that reading concise manuals like these don't sooth any headaches... :-)

[quote author="dogsbody"]1) The advanced trigger itself doesn't perceive state mode (ie: external clock) vs timing mode (ie: internal clock).    It only sees samples.  So yes, the "while storing" term applies to both on the demon core.

2)  The demon core trigger is a one time thing.  Once you flip the trigger, the OLS captures everything.  For selective capturing, use the per-sequence state capturing control instead.[/quote]

Ok, clear. So, per sequence state you can define what subset of channels are to be captured?! That would mean that you can capture, for example, channels 1-2 for state 1, then channels 3-5 for state 2, and end with a capture of channels 2-4 for state 3? All other channels are zero'd out then?

[quote author="dogsbody"]3)  The ANY/NOP operations could be used anywhere.  However, only NOP really makes sense.  The pair LUT & mid LUT operations can use them to ignore inputs.  ie: ignoring a specific trigger input or an entire branch of trigger inputs.[/quote]

Does this not imply that the inputs of pair/mid LUTs that are unused are always set to NOPs/ANYs, depending on the chosen operator? A NOP-pair LUT for an AND-mid LUT will cause the operation to be quite predictable, and the same goes for a ANY-pair LUT for an OR-mid LUT. Does the HP165xx have any smart logic behind this, or is this the responsibility of the user?

Also, I see HP165xx manuals often referring to "While capturing <no state>" or "If target <any state>". Does this imply that the final LUT-term is set to NOP/ANY in these situations?

[quote author="dogsbody"]4) Inversion must be handled within the pair LUT's.  Since trigger terms are the LUT inputs, you have total control over how they are parsed.  It is a little confusing...  I'll update my spec with some example code.  I've attached more detail below.[/quote]

Thanks; that clarifies things; the sample code was really helpful!

[quote author="dogsbody"]5) The demon core has a per sequence state hit counter.    So for example, a given sequence state could be setup to require 42 occurrences/matches before recognizing a hit.  If the target trigger is a less/greater than, you should be set.  Perhaps there is something in the 16550 spec I'm missing?[/quote]

I've seen this in the 16550 and 16554 manuals, in the section about the "sequence instruction menu", on page 5-14 (of the 16554 manual) it states that you can define a greater/smaller than operation for timing-mode triggers instead of the occurrence counter. I'm asking this, because it influences the sequence state a bit: you cannot define an else-term in case you select the greater/smaller operation...
when good software is not an alternative...

Re: Advanced Trigger Questions

Reply #11
[quote author="jawi"]Ok, clear. So, per sequence state you can define what subset of channels are to be captured?! That would mean that you can capture, for example, channels 1-2 for state 1, then channels 3-5 for state 2, and end with a capture of channels 2-4 for state 3? All other channels are zero'd out then?[/quote]
All 8, or 16, or 32 bits are captured.  The "which channels are captured" part didn't change.  Only "-when- are the channels captured" changed. 

The adv trigger simply gives you control over -when- to perform a capture.  You can move between trigger states based on any input channel bit, or any random selection of input channel bits.  See this happen, advanced to next state.  See something bad, go somewhere else.  See a specific thing of interest occur, capture that sample.  Otherwise, sit & do nothing.

For example, assume a SPI interface.  You could configure an adv. trigger to sit idle & not capture anything until it sees activity.  Once it sees something, have it capture only on the rising or falling edges of the SPI clock.

Note also the adv trigger (like the basic trigger), can work on channel bits which -arn't- being captured.  All 32 input channels are available always for any trigger.  So you could trigger on bits from byte0, but store byte1.  etc...

[quote author="jawi"]Does this not imply that the inputs of pair/mid LUTs that are unused are always set to NOPs/ANYs, depending on the chosen operator? A NOP-pair LUT for an AND-mid LUT will cause the operation to be quite predictable, and the same goes for a ANY-pair LUT for an OR-mid LUT. Does the HP165xx have any smart logic behind this, or is this the responsibility of the user?[/quote]
You're simply selecting different types of logic gates.  The 16550 doesn't try to be clever.  You either select a specific trigger term (which boils down to using the "A" or "B" only operations), or access the complex trigger mode where everything is user programmable.

[quote author="jawi"]Also, I see HP165xx manuals often referring to "While capturing <no state>" or "If target <any state>". Does this imply that the final LUT-term is set to NOP/ANY in these situations?[/quote]
Exactly.

[quote author="jawi"]I've seen this in the 16550 and 16554 manuals, in the section about the "sequence instruction menu", on page 5-14 (of the 16554 manual) it states that you can define a greater/smaller than operation for timing-mode triggers instead of the occurrence counter. I'm asking this, because it influences the sequence state a bit: you cannot define an else-term in case you select the greater/smaller operation...[/quote]
The 16550 calls the occurrence counter a duration counter in timing mode.  It's the same thing though I think.  In timing mode, the samples come at a fixed rate.  So instead of waiting for 150 samples, the GUI let's you wait for 1.5usec (assuming 100Mhz capture rate).  If the user subsequently changed the sample rate to 50Mhz, the GUI automagically waits for 75 samples instead, maintaining the requested "1.5usec" duration.

The greater-than & "occurrence" counts are basically the same thing (maybe +/- a count).  ie:
State 1:  Wait 150 samples while "term" true then, apply user "capture" & "hit" events, then advance to next state.  If "term" false (else path), goto user "else" state.

The less-than thing is hiding a little complexity on HP's part.  On page 5-14 of the 16554/16555 user manual HP admits using three sequence states.  ie:

State 1:  Wait 150 samples while "term" true then advance to state 2.  If "term" false (else path), goto state 3.
State 2:  On <no state>, do nothing.  Otherwise (else path), apply user "else" state.
State 3:  On <any state>, apply user "capture" & user "hit" events, then advance to next state.

So if the term occurs -less- than the 150 samples, you end up in state 3 where the "hit" occurs.  More than 150 samples, then you're in state 2 where the "else" is handled.

The 16550 has various advanced constructs which are compiled automatically down to multiple sequence states.

The demon core allows for duplicating most of the 16550, but it could take a long time to implement in the client.  I'd suggest keeping it simple.  First, just provide access to all 16 states & the capture/hit/else terms.  Provide access to single terms for capture, hit & else events.  Leave the complex trigger stuff for later. 

btw... just to review, a trigger term is anything from a single channel bit to all 32 channels (just like a basic trigger but ten of them), or one of two range terms, two edge terms or two timer terms.  The 16550 lets a user assign names to the terms.  There are 16 terms total.  Separately there are 16 sequence/state levels for making use of the terms.  Each sequence state can use any combination of the terms for a hit, else or capture events.
-- IED
-- debugging hardware at 2am is a bad idea...

Re: Advanced Trigger Questions

Reply #12
HI, I didn´t like to disturb this post, I´m reading with interest and becomes a question to me. In agilent and tek oscilloscopes after the 16XXX implements a type of trigger more specific and very usefull to me. I think that can be implemented from the client and translate as "normal" advance trigger sequences, but may be it´s easy to implement in demon core directly. I refer to teh triggers for the serial protocols like USART, I2C, SPI, CAN, LIN, etc (in this order of importance) that permit, for example, establish that certain channels are I2C channels and speak to the clients in term of protocol instead of terms of crude bits. That is that we can establish for example the start condition as a simple click, r/W as a check box, then put a condition for the I2C address and perhaps data and this in a simple form and the client or demon decode the sequence of triggers to execute this trigger.

It´s like an inverse decoder, but it´s really usefull and fast. I offer to help with this if you need.

Thank and sorry for disturb this excellent post

Re: Advanced Trigger Questions

Reply #13
Hi Tarloth,

I believe Jawi's client already has decoders for USART, I2C, SPI, etc...  You specify which pins are what & off it goes.  Triggering on specific I2C addresses (for example) should be possible with the adv trigger.  Maybe eventually the client could contain a suite of canned adv triggers for various protocols like you suggest. 

Modifying the fpga is possible also of course, but there would be headaches.  Like ensuring I get all the various protocols right.  Having enough flexibility to handle variations from all the different manufacturers.  Giving enough options so everyone is happy (good luck on -that- one).  Keep it small enough to fit within the fpga -- which is already somewhat full.  Etc...   

Providing basic building blocks & leaving the rest to software is much easier.  :-)

Cheers!
-- IED
-- debugging hardware at 2am is a bad idea...

Re: Advanced Trigger Questions

Reply #14
I agree, I do the trigger translating manually to """basic""" blocks, but it´s helpfull to have some shortcuts as have in modern PRO LA. I agree that it´s much easier to implement at the client side through an assistant or something like it. Thanks for your answer