-- Example of a binary synchronous counter using FSM style LIBRARY ieee; USE IEEE.STD_LOGIC_1164.all; USE IEEE.STD_LOGIC_ARITH.all; USE IEEE.STD_LOGIC_UNSIGNED.all; ENTITY counter_mod10 IS Port ( CLK : IN STD_LOGIC; CD : IN STD_LOGIC; CE : IN STD_LOGIC; Q : OUT STD_LOGIC_VECTOR(3 DOWNTO 0); TC10 : OUT STD_LOGIC ); END counter_mod10; -- Internal desciption in FSM style ARCHITECTURE FSM_like OF counter_mod10 IS -- Internal wires -- State signals declaration -- A BCD counter will consist of 10 diferent states TYPE State_type IS (Num0, Num1, Num2, Num3, Num4, Num5, Num6, Num7, Num8, Num9) ; --------> This is important: specifying to the synthesiser the code for the states ATTRIBUTE syn_encoding : STRING; ATTRIBUTE syn_encoding OF State_type : TYPE IS "sequential"; -- (It may be:"sequential" (binary); "gray"; "one-hot", etc. SIGNAL present_state, future_state : State_type ; -- These two lines work OK, but the state machine is not recognised. -- and regular logic is synthesised (so it's not so good as the syn_encoding). -- ATTRIBUTE enum_encoding : string; -- ATTRIBUTE enum_encoding of State_type : TYPE IS "sequential"; -- Constants for special states (the first and the last state) CONSTANT Reset : State_type := Num0; -- The fisrt state. This is another name for the state Num0 CONSTANT Max_count : State_type := Num9; -- The last state. This is anather way to name the state Num9 BEGIN ---------------------- State Register: the only clocked block. ---------------------- The "memory" of the system (future events will depend on past events state_register: PROCESS (CD,CLK, future_state) BEGIN IF CD = '1' THEN -- reset counter present_state <= Reset; ELSIF (CLK'EVENT and CLK = '1') THEN -- Synchronous register (D-type flip-flop) present_state <= future_state; END IF; END PROCESS state_register; ------------------------- CC1: Combinational system for calculating next state CC_1: PROCESS (present_state, CE) BEGIN IF CE = '0' THEN future_state <= present_state; -- count disable ELSE -- just a simple state up count CASE present_state IS WHEN Num0 => future_state <= Num1 ; WHEN Num1 => future_state <= Num2 ; WHEN Num2 => future_state <= Num3 ; WHEN Num3 => future_state <= Num4 ; WHEN Num4 => future_state <= Num5 ; WHEN Num5 => future_state <= Num6 ; WHEN Num6 => future_state <= Num7 ; WHEN Num7 => future_state <= Num8 ; WHEN Num8 => future_state <= Num9 ; WHEN Num9 => future_state <= Num0 ; END CASE ; END IF; END PROCESS CC_1; ------------------------- CS_2: combinational system for calculating extra outputs -------------------------- and outputing the present state (the actual count) CC_2: PROCESS (present_state, CE) BEGIN -- The terminal count output IF ((present_state = Max_count) AND (CE = '1') ) THEN TC10 <= '1'; ELSE TC10 <= '0'; END IF; -- And now just copying the present state to the output: CASE present_state IS WHEN Num0 => Q <= "0000"; WHEN Num1 => Q <= "0001"; WHEN Num2 => Q <= "0010"; WHEN Num3 => Q <= "0011"; WHEN Num4 => Q <= "0100"; WHEN Num5 => Q <= "0101"; WHEN Num6 => Q <= "0110"; WHEN Num7 => Q <= "0111"; WHEN Num8 => Q <= "1000"; WHEN Num9 => Q <= "1001"; END CASE ; END PROCESS CC_2; -- Place other logic if necessary END FSM_like;