- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
I'm trying to make a state-machine wich remains in one of the states until one of the variables goes from zero to one three times. I assume it should be quite simple, but after some days I can't succeed. I have tried to save the number of changes both in variables and signals, but no result. To make a simple test, I just made one simple state-machine with two states. It remains on the first one till the signal_to_monitor =1. Then it goes to second state and the idea is to get out of that state after three transitions 0-1 of the signal we are monitoring. The code used is: architecture ctrl_machine of machine is type possible_states is (first_st,second_st); signal next_state,state: possibles_states; signal accumulate : integer range 0 to 5; begin RefreshState : process (clk,reset) begin if (reset='1') then estat <= idle; elsif (clk'event and clk='1') then estat <= seguent_estat; end if; end process RefreshState; NextState : process (state,signal_to_monitor) begin next_state <= state; case state is when first_st => if (signal_to_monitor ='1') then next_state <= second_st; else accumulate <=0; next_state <= first_st; end if; when second_st => next_state <= buidant_calaix; if (signal_to_monitor = '1') then accumulate <=accumulate +1; end if; if (accumulate = 3) then next_state<=first_state; end if; end case; end process; output_proc : process (state) begin case (state) is when first_st => output <='0'; when second_st => output <='1'; end case; end process ; (...) I assume it should be a conceptual error but can't find it! The signal (accumulate) gets mad and begins to flip-flop without control (suppose due to accumulate=accumulate+1 but don't know how to accomplish this simple goal!). Any ideas? Thanks!!! CarlosLink Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Your code is unreadable, because you're mixing original spanish and translated signal and state names. Please post either your original or another consistent code.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Sorry! I tried to translate the code for a better understanding. I resend it with the necessary corrections (and in fact the full code I'm working with). I attach also the simulation result (why does the accumulate signal - and so the output - go from 0 to 1 without control????):
library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; entity Counter is -- counts three ticks of the signal signal_to_monitor -or thats what I wish -- the output signal is integer just to show the evolution in the waveform simulator port( clk: in std_logic; reset,signal_to_monitor: in std_logic; output: out integer ); end Counter; architecture Behavioral of Counter is constant NUM_TICKS : integer := 3; type possible_states is (first_st,second_st); signal next_state,state: possible_states; signal accumulate: integer range 0 to 2; begin RefreshState : process (clk,reset) begin if (reset='1') then state <= first_st; elsif (clk'event and clk='1') then state <= next_state; end if; end process RefreshState; process (state,signal_to_monitor) begin next_state <= state; case state is when first_st => -- no ticks yet if (signal_to_monitor ='1') then -- count one tick and go to the 'counting' state accumulate<=accumulate+1; next_state <= second_st; else accumulate <=0; next_state <= first_st; end if; when second_st => -- if the signal goes to one again, count one more till you arrive to NUM_TICKS -- then fall back to first_state if (signal_to_monitor = '1') then accumulate <=accumulate +1; end if; if (accumulate = NUM_TICKS) then -- next_state<=first_st; end if; end case; -- just to have a look at the waveform I generate the output here output <= accumulate; end process; process (state) begin --do nothing as the output has been generated just for debugging purposes end process ; end Behavioral;- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You can't place a counter in the combinational process. The output gets simply unpredictable this way. The accumulator must be assigned under control of an edge sensitive condition, similar to the state variable.
accumulate<=accumulate+1;
Also I don't see how the state machine can work with just two states. I have difficulties to guess the exact intended behaviour. I suggest to sketch a waveform and use a different state for each step. Care must be taken, if signal_to_monitor is unrelated to the system clock domain, e.g. an external signal. In this case, it's necessary to synchronize it by a clocked register and make the register output control the state machine.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks. I did not know I could not use it inside the combinational process. But - as far as I have seen - I can not do it either making a control like:
if (signal_to_monitor'event and signal_to_monitor='1') then accumulate<=accumulate+1 ;end if; (I include a sample code at the end) The intended behaviour I tried was just to 'stay in one state till the signal makes a number of changes (three in the example)'. It has no other application. So, I wanted to stay in the first state till the signal goes from 0 to 1. Then stay in second_st till 3 changes have been made in the signal (from 0 to 1). Once that happens (accumulate=3), return to first state and reset accumulate. How can I do this? (the only solution is creating additional states like one_change, two_changes and three_changes? ) (if so, what if I needed 50 changes??? :( ) Thanks! -- process (state,signal_to_monitor) begin next_state <= state; if (signal_to_monitor'event and signal_to_monitor='1') then accumulate<=accumulate+1 ;end if; case state is when first_st => -- no ticks yet if ( signal_to_monitor ='1') then -- count one tick and go to the 'counting' state next_state <= second_st; else accumulate <=0; next_state <= first_st; end if; when second_st => -- if the signal goes to one again, count one more till you arrive to NUM_TICKS -- then fall back to first_state if (accumulate = NUM_TICKS) then -- next_state<=first_st; end if; end case;- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Apart from the "how to count" problem, you'll need at least two "counting" states that reflects a high respectively low input state. Then the transition to the counting_high state can also advance the counter. The counter would be incremented under rising_edge(clk).
Personally I prefer a more compact form of a state machine, that has only one, edge sensitive process. You can easily add things like the said counting action to it.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
OK! Thanks. I'll try to do it this way.

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page