FPGARelated.com
Forums

Statemachine debugging with Chipscope

Started by Richard G. November 6, 2010
Hi all,

I have a very simple question. I have a statemachine, where the states
are declared as follows:

type  SM_TYPE is (IDLE,WRITE0,WRITE1,READ1,ABORT0, ABORT1,ABORT2,ABORT3,
                   ABORT4, DONE);

signal nstate : SM_TYPE;

I would like to have now an output signal of my state machine which
encodes the state to that I can use this signal to debug the 
statemachine with Chipscope. I am just wondering what kind of signal
the output port that encodes the state has to be. I think one-hot 
encoding is used, and I have 10 states, so I would assume that
I could declare it like that

   port (
     ...
     dbg_state_out : out  std_logic_vector(9 downto 0);
     ...
   );

...

dbg_state_out <= nstate;

Is my approach right, or is the state encoded in something different 
than a std_logic_vector.

Many thanks
Richard G. wrote:
> Hi all, > > I have a very simple question. I have a statemachine, where the states > are declared as follows: > > type SM_TYPE is (IDLE,WRITE0,WRITE1,READ1,ABORT0, > ABORT1,ABORT2,ABORT3, ABORT4, DONE); > > signal nstate : SM_TYPE; > > I would like to have now an output signal of my state machine which > encodes the state to that I can use this signal to debug the > statemachine with Chipscope. I am just wondering what kind of signal > the output port that encodes the state has to be. I think one-hot > encoding is used, and I have 10 states, so I would assume that > I could declare it like that > > port ( > ... > dbg_state_out : out std_logic_vector(9 downto 0); > ... > ); > > ... > > dbg_state_out <= nstate; > > Is my approach right, or is the state encoded in something different > than a std_logic_vector. > > Many thanks
I didn't think you could cast a statemachine signal into a vector. I've used the long hand way of putting statemachine in another process to convert the state into a std_logic_vector nstate_proc : process(nstate) begin case nstate is when IDLE => dbg_state_out <= "000000000" .... .... .... end case; end process;
Just to expound on what Fredxx described, I usually binary encode my
one-hot state machine bits to reduce the bits (e.g. 16 states gets
reduced to 4 bits) before reporting the state to a status reg. Just
remember to pipeline properly to isolate from the one-hot
implementation. For example, register the one-hots into another
register, then do the double-ranking into another set of regs. Also
remember to use a "capture_status" signal if multiple clock domains
are used to synchronize your binary-encoded state bits. For chipscope
purposes, simply add these binary-encoded bits into your signal
monitoring list, but remember to account for coherency between the
binary-encoded bits and other signals you may be monitoring.
On Nov 8, 7:40=A0am, jc <jcappe...@optimal-design.com> wrote:
> Just to expound on what Fredxx described, I usually binary encode my > one-hot state machine bits to reduce the bits (e.g. 16 states gets > reduced to 4 bits) before reporting the state to a status reg. Just > remember to pipeline properly to isolate from the one-hot > implementation. For example, register the one-hots into another > register, then do the double-ranking into another set of regs. Also > remember to use a "capture_status" signal if multiple clock domains > are used to synchronize your binary-encoded state bits. For chipscope > purposes, simply add these binary-encoded bits into your signal > monitoring list, but remember to account for coherency between the > binary-encoded bits and other signals you may be monitoring.
One more point, if you will be using the ChipScope inserter, you may need to add a KEEP attribute on your encoded state vector to prevent it from being removed from the design before the translate phase where the inserter grabs its connections. Also I have used the inserter to attach to state machine state variables without encoding them first. They tend to keep the same name as the original state variable with a numeric suffix. However you would need to figure out the encoding (usually reported in the synthesis report) in order to use these directly. I found that in the case of binary encoding, the post-translate signals have numeric suffixes 1 to N that roughly match N-1 downto 0 of the encoded bits. This means you probably have to reverse the bus order in the ChipScope viewer. regards, Gabor
"Richard G." <Richard@yahoo.com> writes:

> Hi all, > > I have a very simple question. I have a statemachine, where the states > are declared as follows: > > type SM_TYPE is (IDLE,WRITE0,WRITE1,READ1,ABORT0, ABORT1,ABORT2,ABORT3, > ABORT4, DONE); > > signal nstate : SM_TYPE; > > I would like to have now an output signal of my state machine which > encodes the state to that I can use this signal to debug the > statemachine with Chipscope.
If you use the chipscope core inserter, you can just probe the state directly. I usually put an attribute on my state machine to stop it being one-hot encoded in these cases if I can get away with it as it means the signal is much narrower, so less BRAMs are used. Check the synth reports very carefully as the state mapping is unlikely to be anything you expect it to be once the optimiser has finished :) If you are wanting to instantiate the ILA within your HDL the solution already presented of a separate process with explicit decode works fine, if a little verbose (and potentially error-prone if you're changing the content of SM_TYPE a lot). As an alternative, you could try using the "'pos method" (XST seems to accept this, although I haven't taken it through to a bitstream): debug_sig <= std_logic_vector(to_unsigned(nstate'pos, debug_sig'length)); This may have the side-effect of forcing state to be binary-encoded, depending on the logic around it I think.
> I am just wondering what kind of signal the output port that encodes > the state has to be. I think one-hot encoding is used, and I have 10 > states, so I would assume that I could declare it like that > > port ( > ... > dbg_state_out : out std_logic_vector(9 downto 0); > ... > ); > > ... > > dbg_state_out <= nstate; > > Is my approach right, or is the state encoded in something different > than a std_logic_vector. >
VHDL is strongly typed, so you can't do anything like that. Within the VHDL language, there is no concept of "state encodings". They are just elements of an enumerated type, with no other existence - other than the fact you can use the 'pos attribute to get a numerical position for them. HTH, Martin -- martin.j.thompson@trw.com TRW Conekt - Consultancy in Engineering, Knowledge and Technology http://www.conekt.co.uk/capabilities/39-electronic-hardware
On Nov 8, 10:44=A0am, Martin Thompson <martin.j.thomp...@trw.com> wrote:
[snip]
> > debug_sig <=3D std_logic_vector(to_unsigned(nstate'pos, debug_sig'length)=
);
> > This may have the side-effect of forcing state to be binary-encoded, > depending on the logic around it I think. >
My experience has been that no matter how you use state variables in your code, the encoding is based on optimization. So even if your states are listed in a binary fashion AND you use the state variable externally, e.g. in a status register, you may still have one-hot encoding if that makes the synthesizer happy. The state will then be re-encoded for external use. This of course masks problems with one-hot encoding, as the "zero hot" state usually shows up in the re-encoded binary state as state "0" rather than no state. Regards, Gabor
I've had success referencing variables in binary-encode construct:

CASE is pstate
  WHEN idle => pstate_binencode <= X"0";
  WHEN st_s1 => pstate_binencode <= X"1";
  :
  WHEN st_term => pstate_binencode <= X"A";
  WHEN OTHERS => pstate_binencode <= X"F";
END CASE;

In this case, my binencode sequence will follow what I expect from the
way the fsm was coded, regardless of how bits were synthesized or what
new labels are used. The "pstate_binencode" signal should appear in
chipscope as a 4-bit vector that sequences from 0x0, 0x1, etc., for
normal sequence. The "OTHERS" clause even has built-in illegal state
detection in case you'd want to add some fault tolerance.

Gabor <gabor@alacron.com> wrote:
(snip)

> My experience has been that no matter how you use state variables > in your code, the encoding is based on optimization. > So even if your states are listed in a binary fashion AND you > use the state variable externally, e.g. in a status register, > you may still have one-hot encoding if that makes the synthesizer > happy. The state will then be re-encoded for external > use. This of course masks problems with one-hot encoding, as the > "zero hot" state usually shows up in the re-encoded binary state > as state "0" rather than no state.
Just as long as it doesn't do what one did to me some years ago. I had a two bit/four state machine, using the state externally. The software recoded it as one-hot, and gave two of the bits as the output, without re-encoding them. -- glen
jc <jcappello@optimal-design.com> writes:

> I've had success referencing variables in binary-encode construct: > > CASE is pstate > WHEN idle => pstate_binencode <= X"0"; > WHEN st_s1 => pstate_binencode <= X"1"; > : > WHEN st_term => pstate_binencode <= X"A"; > WHEN OTHERS => pstate_binencode <= X"F"; > END CASE; >
Is this not just a longer-winded version of pstate'pos (barring the "others" bit...)
> In this case, my binencode sequence will follow what I expect from the > way the fsm was coded, regardless of how bits were synthesized or what > new labels are used. The "pstate_binencode" signal should appear in > chipscope as a 4-bit vector that sequences from 0x0, 0x1, etc., for > normal sequence. The "OTHERS" clause even has built-in illegal state > detection in case you'd want to add some fault tolerance.
If you're using an enumerated type, and you've covered all the elements in the "real" cases, I'd expect the "others" clause will just be chucked away by the synth - unless you have one with special pragma's for making safe state-machines. Have you seen otherwise? Cheers, Martin -- martin.j.thompson@trw.com TRW Conekt - Consultancy in Engineering, Knowledge and Technology http://www.conekt.co.uk/capabilities/39-electronic-hardware
Gabor <gabor@alacron.com> writes:

> On Nov 8, 10:44&#4294967295;am, Martin Thompson <martin.j.thomp...@trw.com> wrote: > [snip] >> >> debug_sig <= std_logic_vector(to_unsigned(nstate'pos, debug_sig'length)); >> >> This may have the side-effect of forcing state to be binary-encoded, >> depending on the logic around it I think. >> > > My experience has been that no matter how you use state variables in > your code, the encoding is based on optimization.
Indeed - that's what I meant. [Depending on the other logic around the SM] the synth may decide that the best encoding (now that you've said you want a numerical representation of the states) is to keep them binary coded. Or it might not and produce a 1-hot SM with some 1-hot to integer decode logic (as you pointed out later). Cheers, Martin -- martin.j.thompson@trw.com TRW Conekt - Consultancy in Engineering, Knowledge and Technology http://www.conekt.co.uk/capabilities/39-electronic-hardware