Intel® Quartus® Prime Software
Intel® Quartus® Prime Design Software, Design Entry, Synthesis, Simulation, Verification, Timing Analysis, System Design (Platform Designer, formerly Qsys)
17049 Discussions

Securely start a State-Machine with pulses or edges

Altera_Forum
Honored Contributor II
2,111 Views

Hi there, 

 

this problem occures in my work from time to time: 

I want to start a State-Machine (Transition from Idle-State S000 to State S010) either with a single one-clock-pulse or on the edge (rising or falling) of a signal. 

But just when I think "Hey, this seems secure!", the state-machine misses the pulse or the edge. 

 

Is there some kind of attribute or something to mark an input or a signal of the component as really really really very important to the compiler? 

 

I currently work on a project which uses mainly a 125MHz-Clock.  

 

some tries here: 

(The following codes are inside the idle-state of a state-machine.) 

 

edge detection (with filter) on input start_in: 

sig_Start_IN(0) <= Start_IN; sig_Start_IN(1) <= sig_Start_IN(0); sig_Start_IN(2) <= sig_Start_IN(1); sig_Start_IN(3) <= sig_Start_IN(2); if (sig_Start_IN = "0011") then current_state <= S010; elsif (sig_Start_IN = "1111") then current_state <= current_state; elsif (sig_Start_IN = "1100") then current_state <= S000; else current_state <= current_state; end if;  

 

edge detection (without filter) on input start_in: 

sig_Start_IN <= Start_IN; if ((sig_Start_IN = '0') AND (Start_IN = '1')) then current_state <= S010; else current_state <= S000; end if;  

 

start by a one-clock-pulse on start_in: 

if (Start_IN = '1') then current_state <= S010; else current_state <= S000; end if;  

 

Is there somewhere a better way defined to securely "see" the pulse ore edge? Why does the process sometimes skip a pulse or an edge?
0 Kudos
20 Replies
Altera_Forum
Honored Contributor II
1,426 Views

assuming start_IN is fully synchronous to your 125MHz clock, then your problems are problems with your design, not the fact it is being "missed". Logic never misses anything. 

If startIN is not fully synchronous, then you may be getting some meta-stable values on sig_start_in(0) or bouncing when you shift it into your shift register (so you dont get a clean "0011"). I suggest synchronising the signal first.
0 Kudos
Altera_Forum
Honored Contributor II
1,426 Views

OK, this is an information I dind't give you: 

The Start_IN-Signal is generated by an other core, which uses the exactly same 125MHz clock like this component. 

 

Normally for clock crossing I use a kind of handshaking: 

Core 1: Set Start_IN to '1'. 

-> Core 2: Set Started_OUT to '1' to indicate the Core is started. 

-> Core 1: Checks if Core 2 is started and sets Start_IN-Signal to '0'. 

-> Core 2: Sets Started_OUT to '0' if it's done with its work. 

This works very well, but I can not use this every time. 

 

So you can call me a liar, but you can not call my oszilloscope a liar. I see that there is a synchronous Start_IN-Pulse attached to the correct clock-edge but the next core (on the same clock) doesn't see it. 

I know it's strange, but it happens from time to time.
0 Kudos
Altera_Forum
Honored Contributor II
1,426 Views

if its from another core inside the same FPGA on the same clock, then I suggest there is a problem with the statemachine logic - its not that it is "not seeing it", there is a bug in your code - either this block or the other one.

0 Kudos
Altera_Forum
Honored Contributor II
1,426 Views

I can't agree with you because the core normally starts ery well, except for about 1 out of 100 to 1000 tries. This could be caused by a clock-glitch, but they are on the same clock, so there can be no glitch. 

If my state-machine is kind of messed up, wouldn't this cause much more errors? 

Besides, I've already checked if the state-machine is in an other state than the idle-state when the Start_IN comes. -It isn't. 

My cores process a message from outside the FPGA. The outside "Logic" (Processor) sends one message and the waits for the result (answer-message) before sending the next message. If the processor is done receiving the answer, every core in the FPGA is already in idle-state. So I assume the state-machines are working well. 

 

Except that it can occure, that one of the cores seems to "miss" its start-signal and so the message is lost.
0 Kudos
Altera_Forum
Honored Contributor II
1,426 Views

you assume - how do you know? 

do you have a full verification testbench? have you got one that tries to do bad things in bad states? 

If everything is on the same clock - then the only answer is that its a code bug. Simple as that.
0 Kudos
Altera_Forum
Honored Contributor II
1,426 Views

is your input signal Start_in synchronised to clock?

0 Kudos
Altera_Forum
Honored Contributor II
1,426 Views

I assume it because I made a extra logic which gives me a trigger, when the situation occurs. 

This trigger plus a signal indicating the state of the core is routed out using LAI. 

I see, when the trigger occurs, the state was 0 (for several clocks) and stays 0 (for several clocks). Now tell me is it in a bad state? Does the core start but doesn't tell me it by keeping the state-indication low?
0 Kudos
Altera_Forum
Honored Contributor II
1,426 Views

Hi kaz, 

yes it is. I already mentioned it above.
0 Kudos
Altera_Forum
Honored Contributor II
1,426 Views

 

--- Quote Start ---  

Hi kaz, 

yes it is. I already mentioned it above. 

--- Quote End ---  

 

 

I meant do you use two stage synchroniser on start_in e.g. 

 

on clock edge: 

start_1d <= start_in; 

start_2d <=start_1d; 

 

then use start_2d as input to state machine(not start_1d, nor start_in) 

and make sure start_in is of enough duration to be sampled
0 Kudos
Altera_Forum
Honored Contributor II
1,426 Views

This is something I normally don't use. But I think my filtered edge-detection is somehow similar to that. 

The problem is between two cores inside the FPGA. Both cores are on the same clock and are working on the same edge (falling_edge). 

So I think the signal must already be synchronized.
0 Kudos
Altera_Forum
Honored Contributor II
1,426 Views

 

--- Quote Start ---  

This is something I normally don't use 

--- Quote End ---  

 

For any asynchronous input it is a must. 

 

 

--- Quote Start ---  

 

But I think my filtered edge-detection is somehow similar to that.  

--- Quote End ---  

 

No it is not unless you use the output of second synchroniser and discard others in the synchroniser chain. 

 

 

--- Quote Start ---  

 

The problem is between two cores inside the FPGA. Both cores are on the same clock and are working on the same edge (falling_edge). 

So I think the signal must already be synchronized. 

--- Quote End ---  

 

 

still it does not explain how the start_in comes in.
0 Kudos
Altera_Forum
Honored Contributor II
1,426 Views

I don't know how to explain it more in detail. See attached Picture. 

 

The Start_IN-signal is set and unset on falling_edge by Core1. It is read by Core2 on falling_edge. Do I have to synchronize an already synchronized signal? 

 

Besides to "Logic never misses anything.". Currently I have also a state machine which skips sometimes a state although the path it goes has never been programmed.
0 Kudos
Altera_Forum
Honored Contributor II
1,426 Views

start_in goes into core1 then some logic(I presume) then core2. This is not safe. For core1 it is not synchronised by two stage. For core2 it is not either as the chain of two registers should be clean of any logic. 

 

start_in should go through two registers then be used in any core(core1 or core2)
0 Kudos
Altera_Forum
Honored Contributor II
1,426 Views

No, Start_IN is generated by core1 (called Start_OUT, obviously an OUTput). Then no logic, directly connected to core2 where it is called Start_IN (an INput). 

Where do you see Start_IN giong into core1? Where do you see "some logic"?
0 Kudos
Altera_Forum
Honored Contributor II
1,426 Views

 

--- Quote Start ---  

No, Start_IN is generated by core1 (called Start_OUT, obviously an OUTput). Then no logic, directly connected to core2 where it is called Start_IN (an INput). 

Where do you see Start_IN giong into core1? Where do you see "some logic"? 

--- Quote End ---  

 

 

if you are just generating start_in from same one clock then it is ok and there is no need to consider clock crossing. Moreover this is only a register generating a pulse rather than a core (which gives impression of loads of logic). You haven't explained how do you actually generate the pulse and is it based on async reset. If it all synchronous then this pulse will not be missed in a state machine that runs on same clock unless your state machine logic is not right or timing is not right. The best thing is to show the whole code of state machine.
0 Kudos
Altera_Forum
Honored Contributor II
1,426 Views

Now it seems that we're slowly on the same level. Right, the Start_IN signal is already from a synchronized core with a synchronous reset, is read in synchronous by the second core (which also has an synchronous reset) and the result is on synchronous outputs. No asynchronous logic in between. 

 

Well, now the really generalized question is (see initial post) what are the best (securest) ways to detect edges or one-clock-pulses (everything synchronized) to trigger the start of a state-machine. 

This is a general question and not for debugging a special code. 

 

I will ask, if I can publish my code to you. (Company problem) 

 

PS: I think there are so much "synchronous" in this post, we can call Guinness. :) 

PPS: To be sure: synchronous :D
0 Kudos
Altera_Forum
Honored Contributor II
1,426 Views

 

--- Quote Start ---  

 

 

Well, now the really generalized question is (see initial post) what are the best (securest) ways to detect edges or one-clock-pulses (everything synchronized) to trigger the start of a state-machine. 

This is a general question and not for debugging a special code. 

 

 

--- Quote End ---  

 

 

There is only one way and is surest securest: sample the pulse on the clock edge and use same clock edge as that generated it, though you may take risk and swap edges but there is no need to swap edges unless for some reason you want to overcome timing issues.  

 

The timing makes sure that there is setup window and hold window of pulse transition relative to clock edge and in effect says I see the pulse. 

 

If sampling fails and the clock edge did not see the pulse then either timing is not right or else your logic is not right. We trust the technology otherwise we wouldn't be here.
0 Kudos
Altera_Forum
Honored Contributor II
1,426 Views

 

--- Quote Start ---  

There is only one way and is surest securest: sample the pulse on the clock edge and use same clock edge as that generated it 

--- Quote End ---  

 

 

ie. 

 

signal ip_r : std_logic; process(clk) begin if rising_edge(clk) then ip_r <= ip; if ip_r = '0' and ip = '1' then --action on rising edge elsif ip_r = '1' and ip = '0' then --action on falling edge end if; end if; end process;  

 

Assuming there are no timing failures this will ALWAYS work. 

 

 

--- Quote Start ---  

 

If sampling fails and the clock edge did not see the pulse then either timing is not right or else your logic is not right. We trust the technology otherwise we wouldn't be here. 

--- Quote End ---  

 

 

Timequest will tell you if theres a timing problem 

A good testbench will tell you if theres a logic problem. 

 

Fixing either is usually acheived through modifying the code. Fixing timing problems with extra SDC constraints should be the last resort.
0 Kudos
Altera_Forum
Honored Contributor II
1,426 Views

NOW THAT'S AN ANSWER!!!! NICE. THANK YOU! 

 

Excuse me for being so loud. ;) 

 

OK, I know this method (see unfiltered edge detection in first post). Well, if this is a method even a guru choses then it will be fine for me, too. 

Timing is no problem in my design. Everything seems to be working really nice (for TimeQuest) and I have a worst-case slack of +0.17 on a source synchronous 125MHz interface. 

Logic also is no problem because I always test my cores in ModelSim before implementing them. 

 

Well, seems that there are no other ways than those I already know. Thank you.
0 Kudos
Altera_Forum
Honored Contributor II
1,378 Views

Modelsim does not test things for you. Modelsim is a tool that runs your testbench. If your test cases are not catching this bug then I can only assume that your test cases are not good enough. 

Try and capture as much info as you can in the run up to the problem, then try and re-create the bug in modelsim. I bet there is some combination of events that you are not covering in the testbench that are occuring as some corner case in the real system.
0 Kudos
Reply