----------------------------------------------------------------------------------
-- Company: 
-- Engineer: 
-- 
-- Create Date:    00:19:15 09/13/2012 
-- Design Name: 
-- Module Name:    seven_seg - Behavioral 
-- Project Name: 
-- Target Devices: 
-- Tool versions: 
-- Description: 
--
-- Dependencies: 
--
-- Revision: 
-- Revision 0.01 - File Created
-- Additional Comments: 
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.NUMERIC_STD.all;

-- N is the size of the register that holds the counter in bits.
-- M represents the modulo value, i.e., if 10, counter counts to 9 and wraps
entity SlowClockGen is
   generic(
      N: integer := 4;
      M: integer := 10
   );
   port(
      clk_in, reset: in std_logic;
      clk_out_tick: out std_logic
   );
end SlowClockGen;

architecture beh of SlowClockGen is
   signal r_reg: unsigned(N-1 downto 0);
   signal r_next: unsigned(N-1 downto 0);
   begin

-- sequential logic that creates the FF
   process(clk_in, reset)
      begin
         if (reset = '1') then
            r_reg <= (others => '0');
         elsif (clk_in'event and clk_in='1') then
            r_reg <= r_next;
         end if;
   end process;

-- next state logic for the FF, count from 0 to M-1 and wrap
   r_next <= (others => '0') when r_reg=(M-1) else r_reg + 1;

-- generate a 1 clock cycle wide 'tick' when counter reaches max value
   clk_out_tick <= '1' when r_reg=(M-1) else '0';

end beh;


----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

entity bin2bcd is
   Port (
      clk: in  STD_LOGIC;
      reset: in  STD_LOGIC;
      blank: in  STD_LOGIC;
      switches: in  STD_LOGIC_VECTOR (4 downto 0);
      cathodes: out  STD_LOGIC_VECTOR (7 downto 0);
      anodes: out  STD_LOGIC_VECTOR (3 downto 0));
end bin2bcd;

architecture Behavioral of bin2bcd is
   type state_type is (idle, digit0, digit1, check_conditions);
   type led_ptns_type is array (0 to 15) of std_logic_vector(7 downto 0);

   signal state_reg, state_next : state_type; 
   signal led_clk_tick : std_logic;
   signal cathode_reg, cathode_next : std_logic_vector(7 downto 0);
   signal anode_reg, anode_next: std_logic_vector(3 downto 0);
   signal led_ptns : led_ptns_type := (
        "00111111", -- "0"
        "00000110", -- "1"
        "01011011", -- "2"
        "01001111", -- "3"
        "01100110", -- "4"
        "01101101", -- "5"
        "01111101", -- "6"
        "00000111", -- "7"
        "01111111", -- "8"
        "01100111", -- "9"
        "00000000", -- <blank>
        "00000000", -- <blank>
        "00000000", -- <blank>
        "00000000", -- <blank>
        "00000000", -- <blank>
        "00000000"  -- <blank>
        );
   signal digits : STD_LOGIC_VECTOR (7 downto 0);

   begin

-- Connect output signals
    cathodes <= not cathode_reg;
    anodes <= not anode_reg;

   LED_Clk_inst: entity work.SlowClockGen(beh)
      generic map ( N=>17, M=>25000) 
      port map (clk_in=>clk, reset=>reset, clk_out_tick=>led_clk_tick);

   Reg_proc: process (clk, reset) is 
      begin 
         if (reset = '1') then 
            state_reg <= idle;
            cathode_reg <= (others => '1'); -- '1' is off
            anode_reg <= (others => '1');   -- '1' is off
        elsif (clk'event and clk = '1') then 
            state_reg <= state_next;
            cathode_reg <= cathode_next;
            anode_reg <= anode_next;
        end if;
    end process;

-----------------------------------------------------------------------------------------------
--
--
-- ADD CODE TO CONVERT 5-bit binary SWITCH SIGNALS (switches) TO 2 BCD 4-bit values (digits).
--
--
--
--
--
-----------------------------------------------------------------------------------------------    
    
   FSM_proc: process (state_reg, cathode_reg, anode_reg, blank, led_ptns, digits, led_clk_tick) is 
      begin 

-- Default assignment statements
      state_next <= state_reg;
      cathode_next <= cathode_reg;
      anode_next <= anode_reg;
        
-- FSM state processing 
      case state_reg is 
         when idle => 
-- This state blanks the display and waits for blank to go low. 
            cathode_next <= X"00";
            anode_next <= X"0";
            if (blank = '0' and led_clk_tick = '1') then 
               state_next <= digit0;
            end if;

         when digit0 => 
-- Assert pattern for 'ones' digit on the cathode signals and turn on digit 0
            cathode_next <= led_ptns(to_integer(unsigned(digits(3 downto 0))));
            anode_next <= "0001";
            if (led_clk_tick = '1') then 
               state_next <= digit1;
            end if;

         when digit1 => 
-- Assert pattern for 'tens' digit on the cathode signals and turn on digit 1
            cathode_next <= led_ptns(to_integer(unsigned(digits(7 downto 4))));
            anode_next <= "0010";
            if (led_clk_tick = '1') then 
               state_next <= check_conditions;
            end if;

         when check_conditions => 
-- Check the 'blank' switch and stop displaying when high
            if (led_clk_tick = '1') then 
               if (blank = '1') then 
                  state_next <= idle;
               else 
                  state_next <= digit0;
               end if;
            end if;
                    
         when others => 
            state_next <= idle;
        end case;
    end process;
end Behavioral;

