-1
\$\begingroup\$

I have a clock divider and state machine like this:

signal clk_200Hz : std_logic := '0';
signal counter : unsigned(19 downto 0) := x"00000";
begin

clkdiv : process (clk_100Mhz)
begin
    if rising_edge(clk_100Mhz) then
        if counter = x"00000" then
            counter <= X"3D090"
            clk_200Hz <= not clk_200Hz;
        else
            counter <= counter - 1;
        end if;
    end if;
end process clkdiv;

States:

 type SM_STATES is (state_column_1, scan_col_1, state_column_2, scan_col_2,
                          state_column_3, scan_col_3);
 signal my_state     : SM_STATES                   := state_column_1;
 -- By next state I mean something like this :
 -- signal my_state, my_next_state     : SM_STATES                   := state_column_1;

Below is the state machine:

scanner_sm : process (clk)
begin  -- process key_scanner
  if clk'event and clk = '1' then

  if clk_200Hz = '1' then -- clock divider finished counting down 

    -- reset scan_complete
    scan_complete <= '0';

case my_state is

  when state_column_1 =>
    scanned_val  <= (others => '0');
    original_col   <= "110";
    my_state <= scan_col_1;

  when scan_col_1 =>
    case bcd_val is
      when "1110" => 
      out_flag <= '1';
      scanned_val <= "1100100";  -- 1 wrong
      when "1101" => 
      out_flag <= '1';
      scanned_val <= "1100010";  -- 2 wrong
      when others => 
      out_flag <= '0';
      scanned_val <= "0010000";
    end case;
    my_state <= state_column_2;

  when state_column_2 =>
    original_col   <= "011";
    my_state <= scan_col_2;

  when scan_col_2 =>
    case bcd_val is
      when "1110" => 
    out_flag <= '1';
    scanned_val <= "1011011";  -- 5 wrong
      when "1101" => 
    out_flag <= '1';
    scanned_val <= "1011111";  -- 6 wrong
      when others =>
      out_flag <= '0';
      scanned_val <= "0000000";
    end case;
    my_state <= state_column_3;

  when state_column_3 =>
    original_col   <= "101";
    my_state <= scan_col_3;

  when scan_col_3 => -- Reading S1 // The only working state
    case bcd_val is
      when "1110" =>
    out_flag <= '1'; 
    scanned_val <= "1100000";  -- 9/ 1
      when "1101" => 
    out_flag <= '1';
    scanned_val <= "0111110";  -- X/ 2
      when others =>
     out_flag <= '0';
     scanned_val <= "0000000";
    end case;
    my_state <= state_column_1; -- 
    scan_complete <= '1'; -- 

  when others => scanned_val <= "0000000";
end case;

      end if;
  end if;
end process scanner_sm;

Question 1: I don't have next state and everything works fine, do I need it? What is it good for? If everything is working without it, why would people need it? By next state I mean a second states type which contains the same states, starts with my_state, end of each state, state is switched to my_next_state and after each rising clock my_state <= my_next_state. Is this mealy or moore? According to me mealy. How many processes are involved in this and what are they?

Question 2: State machine is activated only if clk_200Hz is "1" I have 6 states, a full scan takes for me 1200 Hz or 200 Hz? My question is am I going to each state every 200 Hz or in 200Hz the whole 6 states are being scanned? If someone can elaborate this Clock events for the state machine, I would be glad!

Question 3: How can I control the duration of out_flag I would like to make it lets say 70 ms, I would like increase its duration or maybe decrease, how can I do this? Default value of out_flag is zero.

Thanks a lot for reading!

\$\endgroup\$
  • \$\begingroup\$ Your code is not complete. What does this code do? What do you mean by saying that you don't have a next state?!! In each state of your state diagram, you are assigning value to your my_state, which is your next state. Or you meant to say that you don't have a state named next_state? \$\endgroup\$ – nidhin May 17 '14 at 19:25
  • \$\begingroup\$ Need more explanation on 'duration of out_flag' because its don't see its value changing. \$\endgroup\$ – nidhin May 17 '14 at 19:28
  • \$\begingroup\$ @nidhin I want to send this out_flag to the processor, and the duration of out_flag and the interrupt job done should be the same. That is why I need to set to a fixed time. Default value is "0" and on others also set to "0". My code was incomplete, added more, sorry! \$\endgroup\$ – Anarkie May 17 '14 at 19:38
  • \$\begingroup\$ @nidhin Updated my question for Next state part as well. \$\endgroup\$ – Anarkie May 17 '14 at 19:43
  • \$\begingroup\$ What I understood is that you have to send out_flag to a processor every 70ms. For that, write a separate process which assigns the value every 70ms. \$\endgroup\$ – nidhin May 17 '14 at 19:47
1
\$\begingroup\$
  1. You already define a next state in your clocked process. If you had a non-clocked (combinational) next state process then you would explicitly define a next_state signal and route it to a clocked process defined somewhere else.

  2. If your enable clk_200hz pulses every 200Hz and your state machine has 6 states it will take 6 enable pulses to cycle through your entire state machine. So 1200Hz I guess, but that's kind of an unusual way to think about it.

  3. The simplest thing to do would be to create a separate wait state after every state that sets out_flag and have the new wait state wait for 70ms before going to the next state.

Edited:

For 3 - Add something like this after each of your states

when example_wait1 =>
    if (count = 70) then -- adjust count to 70ms based off your clock speed
        count    <= (others => '0');
        my_state <= next_state;
    else
        count    <= count + 1;
        my_state <= example_wait1;
    end if;
...
when example_wait2 =>
    if (count = 70) then -- adjust count to 70ms based off your clock speed
        count    <= (others => '0');
        my_state <= next_state;
    else
        count    <= count + 1;
        my_state <= example_wait2;
    end if;
...
\$\endgroup\$
  • \$\begingroup\$ How do I implement this wait state? \$\endgroup\$ – Anarkie May 17 '14 at 19:45
0
\$\begingroup\$

1.There is no keyword in VHDL named next_state. If you change from one state to other on any signal, then you have a present and next state. The machine you considered here is Mealy since its output (out_flag) depends on input (scanned_val) and present state.

2.This depends on the frequency of clk. The process scanner_sm is called every time when clk is changed. And it goes to your case statement if clk_200Hz is high (level triggered). I assume that your clk_200Hz has a frequency of 200Hz.

  • If frequency of clk >> frequency of clk_200Hz, then it takes less than 0.5ms(time period of 200Hz signal) to scan your 6 states.
  • If If frequency of clk << frequency of clk_200Hz, then it depends on the time period of clk which would be greater than 0.5ms.

3.I think you wanted to assign the value of out_flag to some processor pin. For that write a process like the one shown below and add it after your clkdiv process.

proc1:process(processor_pin)
begin
wait for 70 ms;
processor_pin <= out_flag;
end process proc1
\$\endgroup\$
  • \$\begingroup\$ is this going to wait for 70ms and then assign the flag or assign it for the duration of 70ms? \$\endgroup\$ – Anarkie May 17 '14 at 20:25
  • \$\begingroup\$ This assigns it for a duration of 70ms. This process copies the value of out_flag to processor_pin every 70ms. The value of processor_pin can change only at multiples of 70ms where as out_flag can changed from other process during this period. \$\endgroup\$ – nidhin May 17 '14 at 20:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.