|
| 1 | +-------------------------------------------------------------------------------- |
| 2 | +-- PROJECT: FPGA MISC |
| 3 | +-------------------------------------------------------------------------------- |
| 4 | +-- NAME: SSEG_DRIVER |
| 5 | +-- AUTHORS: Jakub Cabal <[email protected]> |
| 6 | +-- LICENSE: The MIT License |
| 7 | +-- WEBSITE: https://github.com/jakubcabal/fpga-misc |
| 8 | +-------------------------------------------------------------------------------- |
| 9 | + |
| 10 | +library IEEE; |
| 11 | +use IEEE.STD_LOGIC_1164.ALL; |
| 12 | +use IEEE.NUMERIC_STD.ALL; |
| 13 | + |
| 14 | +entity SSEG_DRIVER is |
| 15 | + Port ( |
| 16 | + CLK : in std_logic; -- system clock |
| 17 | + CLK_EN_1K : in std_logic; -- clock enable 1 KHz |
| 18 | + ASYNC_RST : in std_logic; -- asynchrounous reset |
| 19 | + -- USER INTERFACE |
| 20 | + DATA0 : in std_logic_vector(3 downto 0); -- BCD or HEX(4b) |
| 21 | + DATA1 : in std_logic_vector(3 downto 0); -- BCD or HEX(4b) |
| 22 | + DATA2 : in std_logic_vector(3 downto 0); -- BCD or HEX(4b) |
| 23 | + DATA3 : in std_logic_vector(3 downto 0); -- BCD or HEX(4b) |
| 24 | + DOTS : in std_logic_vector(3 downto 0); -- DP on/off |
| 25 | + -- SSEG INTERFACE |
| 26 | + SSEG : out std_logic_vector(7 downto 0); -- "dot" & "gfedcba" |
| 27 | + SSEG_AN : out std_logic_vector(3 downto 0) -- sseg anodes |
| 28 | + ); |
| 29 | +end SSEG_DRIVER; |
| 30 | + |
| 31 | +architecture RTL of SSEG_DRIVER is |
| 32 | + |
| 33 | + signal sseg_anode_cnt : unsigned(1 downto 0); |
| 34 | + signal sseg_anode : std_logic_vector(3 downto 0); |
| 35 | + signal sseg_anode_reg : std_logic_vector(3 downto 0); |
| 36 | + signal sseg_bin : std_logic_vector(3 downto 0); |
| 37 | + signal sseg_code : std_logic_vector(6 downto 0); |
| 38 | + signal sseg_dp : std_logic; |
| 39 | + signal sseg_REG : std_logic_vector(7 downto 0); |
| 40 | + |
| 41 | +begin |
| 42 | + |
| 43 | + -- ------------------------------------------------------------------------- |
| 44 | + -- SSEG ANODE MUXING |
| 45 | + -- ------------------------------------------------------------------------- |
| 46 | + |
| 47 | + sseg_an_cnt_p : process (CLK, ASYNC_RST) |
| 48 | + begin |
| 49 | + if (ASYNC_RST = '1') then |
| 50 | + sseg_anode_cnt <= (others => '0'); |
| 51 | + elsif (rising_edge(CLK)) then |
| 52 | + if (CLK_EN_1K = '1') then |
| 53 | + sseg_anode_cnt <= sseg_anode_cnt + 1; |
| 54 | + end if; |
| 55 | + end if; |
| 56 | + end process; |
| 57 | + |
| 58 | + process(sseg_anode_cnt, DATA0, DATA1, DATA2, DATA3, DOTS) |
| 59 | + begin |
| 60 | + case sseg_anode_cnt is |
| 61 | + when "00" => |
| 62 | + sseg_bin <= DATA0; |
| 63 | + sseg_dp <= not DOTS(0); |
| 64 | + sseg_anode <= "1110"; |
| 65 | + when "01" => |
| 66 | + sseg_bin <= DATA1; |
| 67 | + sseg_dp <= not DOTS(1); |
| 68 | + sseg_anode <= "1101"; |
| 69 | + when "10" => |
| 70 | + sseg_bin <= DATA2; |
| 71 | + sseg_dp <= not DOTS(2); |
| 72 | + sseg_anode <= "1011"; |
| 73 | + when "11" => |
| 74 | + sseg_bin <= DATA3; |
| 75 | + sseg_dp <= not DOTS(3); |
| 76 | + sseg_anode <= "0111"; |
| 77 | + when others => |
| 78 | + sseg_bin <= DATA0; |
| 79 | + sseg_dp <= not DOTS(0); |
| 80 | + sseg_anode <= "1110"; |
| 81 | + end case; |
| 82 | + end process; |
| 83 | + |
| 84 | + -- ------------------------------------------------------------------------- |
| 85 | + -- SSEG ANODE REGISTER |
| 86 | + -- ------------------------------------------------------------------------- |
| 87 | + |
| 88 | + sseg_anode_reg_p : process (CLK, ASYNC_RST) |
| 89 | + begin |
| 90 | + if (ASYNC_RST = '1') then |
| 91 | + sseg_anode_reg <= (others => '1'); |
| 92 | + elsif (rising_edge(CLK)) then |
| 93 | + sseg_anode_reg <= sseg_anode; |
| 94 | + end if; |
| 95 | + end process; |
| 96 | + |
| 97 | + SSEG_AN <= sseg_anode_reg; |
| 98 | + |
| 99 | + -- ------------------------------------------------------------------------- |
| 100 | + -- SSEG DECODER |
| 101 | + -- ------------------------------------------------------------------------- |
| 102 | + |
| 103 | + with sseg_bin select |
| 104 | + sseg_code <= "1000000" when "0000", -- 0 |
| 105 | + "1111001" when "0001", -- 1 |
| 106 | + "0100100" when "0010", -- 2 |
| 107 | + "0110000" when "0011", -- 3 |
| 108 | + "0011001" when "0100", -- 4 |
| 109 | + "0010010" when "0101", -- 5 |
| 110 | + "0000010" when "0110", -- 6 |
| 111 | + "1111000" when "0111", -- 7 |
| 112 | + "0000000" when "1000", -- 8 |
| 113 | + "0010000" when "1001", -- 9 |
| 114 | + "0001000" when "1010", -- A |
| 115 | + "0000011" when "1011", -- B |
| 116 | + "1000110" when "1100", -- C |
| 117 | + "0100001" when "1101", -- D |
| 118 | + "0000110" when "1110", -- E |
| 119 | + "0001110" when "1111", -- F |
| 120 | + "1111111" when others; -- nic |
| 121 | + -- "gfedcba" |
| 122 | + |
| 123 | + -- ------------------------------------------------------------------------- |
| 124 | + -- SSEG REGISTER |
| 125 | + -- ------------------------------------------------------------------------- |
| 126 | + |
| 127 | + sseg_reg_p : process (CLK, ASYNC_RST) |
| 128 | + begin |
| 129 | + if (ASYNC_RST = '1') then |
| 130 | + sseg_reg <= (others => '1'); |
| 131 | + elsif (rising_edge(CLK)) then |
| 132 | + sseg_reg <= sseg_dp & sseg_code; |
| 133 | + end if; |
| 134 | + end process; |
| 135 | + |
| 136 | + SSEG <= sseg_reg; |
| 137 | + |
| 138 | +end RTL; |
0 commit comments