3
\$\begingroup\$

everyone. I design a Finite State Machine and try to implement it using VHDL, but the result confuses me. I take too much time on this but I still cannot solve this. Could you give me some advice ?

The logic of State Machine as below: enter image description here

if flag = '0', then cnt <= cnt + '1' ; if cnt equals 12, the process will be reset. I write the VHDL code for this, as below:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.all ;

-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;

-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity getCANID is
    generic ( IDNUM : natural := 11) ;
    port ( clk_sample, rst  : in std_logic ;    
             start          : in std_logic ;
             flag   : in std_logic ;
             cnt_dis                : out std_logic_vector(3 downto 0) );

end getCANID;

architecture Behavioral of getCANID is
    type State is (s0, s1, s2, s3) ;
    signal present_state, next_state : State ;
    signal cnt : std_logic_vector(3 downto 0) ; 
begin
    state_clocked : process(clk_sample, rst)
    begin
        if rst = '1' then
            present_state <= s0 ;
        elsif clk_sample'event and clk_sample = '1' then
            present_state <= next_state ;
        end if ;
    end process ;

    state_comb : process(present_state, start, flag)
    begin
        case present_state is 
            when s0 => cnt <= (others=>'0') ;
                if start = '1' then
                    next_state <= s1 ;
                end if ;
            when s1 => cnt <= (others=>'0') ;
                if flag = '0' then
                    cnt <= cnt + '1';
                    next_state <= s2 ;
                else
                    next_state <= s3 ;
                end if ;
            when s2 =>  
                    if cnt = (IDNUM + 1) then 
                        next_state <= s0 ;
                    else
                        if flag = '0' then 
                            cnt <= cnt + '1';
                            next_state <= s2 ;
                        else
                            next_state <= s3 ;
                        end if ;
                    end if ;
          when s3 =>
                if cnt = (IDNUM + 1) then
                    next_state <= s0 ;
                else
                    if flag = '0' then
                        cnt <= cnt + '1';
                        next_state <= s2 ;
                    else
                        next_state <= s3 ;
                    end if ;
                end if ;
        end case ;
    end process ;

    cnt_dis <= cnt ;
end Behavioral;

I write a testbench to simulate this simple proj. but the result is what I want. enter image description here

I think the cnt should keep increasing when flag equals '0' at every rising edge of the clock. The result seems confusing. Could you help me?

The development tool is: Xilinx ISE 14.7

\$\endgroup\$
9
  • \$\begingroup\$ state diagram .. S3 .. why is the if flag = '1' loop there? \$\endgroup\$
    – jsotola
    Commented Feb 21, 2018 at 17:05
  • 1
    \$\begingroup\$ Simplest approach is to junk the 2-process state machine for the shorter, cleaner, more reliable single process style. Longer approach is to learn why the 2-process approach is junk in the first place : two of the reasons are : (1) much more vulnerable to sensitivity list errors, (2) encourages silly mistakes like putting counters in unclocked processes. \$\endgroup\$
    – user16324
    Commented Feb 21, 2018 at 17:10
  • \$\begingroup\$ @jsotola because I just want when flag equals '1', the state is S3. So everytime I get flag equals '1', state will transit to S3. \$\endgroup\$
    – Joe
    Commented Feb 21, 2018 at 17:14
  • \$\begingroup\$ @BrianDrummond I'm sorry, I'm a beginner to FPGA developing. Do you mean that there could be the situation that when my state_comb process is not finished, and the state_clocked process begins, so there will be some conflict? \$\endgroup\$
    – Joe
    Commented Feb 21, 2018 at 17:21
  • \$\begingroup\$ While two process method in mealy machines keeps modularity in the code, it is a headache while debugging too.... \$\endgroup\$
    – Mitu Raj
    Commented Feb 21, 2018 at 17:24

1 Answer 1

2
\$\begingroup\$

The problem is in s2. After reaching state s2, the "next state" is again assigned to s2 as per your flag logic. It is then assigned to "present state" in the next cycle by first process. The consequence is that your second process is never executed in the next clock cycle. Because nothing in its sensitivity list is changing. Flag, present state, start, all remain the same values before. Changing the design to one single process with only clock in the sensitivity list is the better choice.

\$\endgroup\$
6
  • \$\begingroup\$ Yeah! I agree with you! your answer makes me understood more about this program and the transition mechanism of FSM. I have one more question, why the counter jump from 2 to 4, where is the 3? \$\endgroup\$
    – Joe
    Commented Feb 21, 2018 at 17:49
  • \$\begingroup\$ Seems weird to me. Because i am getting the counter = 3 in between 2 and 4 while simulation. \$\endgroup\$
    – Mitu Raj
    Commented Feb 21, 2018 at 19:00
  • \$\begingroup\$ It has something to do with the way you simulated. When I simulated by forcing the clock 0 and 1 (instead of clocking the clock signal) , the second process gets executed twice for a change in flag from 1 --> 0 at the rising edge of that clock, and count jumps to 4 from 2. \$\endgroup\$
    – Mitu Raj
    Commented Feb 21, 2018 at 19:15
  • \$\begingroup\$ This signifies the race between present state and flag signals, which change together in the second process block, which represents a combinational logic. In real world, these things appear as glitches. \$\endgroup\$
    – Mitu Raj
    Commented Feb 21, 2018 at 19:30
  • \$\begingroup\$ Thx! I guess I understand more about the running way of process in VHDL program. The present state and flag change together, the process is being recalled twice simultaneous, so the counter's value looks confusing. Thx again! \$\endgroup\$
    – Joe
    Commented Feb 21, 2018 at 19:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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