diff --git a/byte_display.vhd b/byte_display.vhd new file mode 100644 index 0000000..32b77bf --- /dev/null +++ b/byte_display.vhd @@ -0,0 +1,91 @@ +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; + +entity byte_display is + port( + clk: in std_logic; + reset: in std_logic; + + write: in std_logic; + enable: in std_logic; + + data: in std_logic_vector(7 downto 0); + + segments: out std_logic_vector(1 downto 0); + leds: out std_logic_vector(6 downto 0) + ); +end byte_display; + +architecture bhv of byte_display is + procedure display_digit( + signal digit: in std_logic_vector (3 downto 0); + signal leds: out std_logic_vector(6 downto 0) + ) is + begin + case digit is -- GFEDCBA + when "0000" => leds <= "0111111"; -- 0 ABCDEF + when "0001" => leds <= "0000110"; -- 1 BC + when "0010" => leds <= "1011011"; -- 2 ABDEG + when "0011" => leds <= "1001111"; -- 3 ABCDG + when "0100" => leds <= "1100110"; -- 4 BCFG + when "0101" => leds <= "1101101"; -- 5 ACDFG + when "0110" => leds <= "1111101"; -- 6 ACDEFG + when "0111" => leds <= "0000111"; -- 7 ABC + when "1000" => leds <= "1111111"; -- 8 ABCDEFG + when "1001" => leds <= "1101111"; -- 9 ABCDFG + when "1010" => leds <= "1110111"; -- A ABCEFG + when "1011" => leds <= "1111100"; -- B CDEFG + when "1100" => leds <= "1011000"; -- C DEG + when "1101" => leds <= "1011110"; -- D BCDEG + when "1110" => leds <= "1111001"; -- E ADEFG + when "1111" => leds <= "1110001"; -- F AEFG + when others => leds <= (others => '0'); + end case; + end display_digit; + + type digits_type is array (1 downto 0) of std_logic_vector (3 downto 0); + signal digits: digits_type; + +begin + -- update internal byte + process(clk, reset) + begin + if reset = '1' then + digits(0) <= (others => '0'); + digits(1) <= (others => '0'); + elsif reset = '0' and rising_edge(clk) then + if enable = '1' and write = '1' then + for i in 0 to 1 loop + -- digits sind ein internes Signal + digits(i) <= data(((4*i)+3) downto (4*i)); + end loop; + end if; + end if; + end process; + + process(clk, digits) + variable digit_cntr : integer := 0; + variable digit : integer := 0; + begin + -- select proper digit + if rising_edge(clk) then + digit_cntr := digit_cntr + 1; + if (digit_cntr > 50000) then + digit_cntr := 0; + digit := digit + 1; + if (digit > 1) then + digit := 0; + end if; + end if; + end if; + + -- display the nibble + if (digit = 0) then + segments <= "01"; + display_digit(digits(0),leds); + else + segments <= "10"; + display_digit(digits(1),leds); + end if; + end process; +end bhv; diff --git a/byte_input.vhd b/byte_input.vhd new file mode 100644 index 0000000..4f0367d --- /dev/null +++ b/byte_input.vhd @@ -0,0 +1,29 @@ +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; + +entity byte_input is + PORT( + clk: in std_logic; + data: out std_logic_vector(7 downto 0); + switches: in std_logic_vector(7 downto 0); + button: in std_logic + ); +end byte_input; + +architecture sim of byte_input is + signal s_button: std_logic; +begin + debouncer: entity work.debounce + port map ( + clk => clk, + button => not button, + result => s_button + ); + + process(clk) + begin + if rising_edge(clk) and s_button = '1' then + data <= switches; + end if; + end process; +end sim; \ No newline at end of file diff --git a/clock_divider_module.vhd b/clock_divider_module.vhd new file mode 100644 index 0000000..02bc7cc --- /dev/null +++ b/clock_divider_module.vhd @@ -0,0 +1,43 @@ +LIBRARY ieee; +USE ieee.std_logic_1164.all; + +ENTITY clock_divider_module IS + GENERIC ( + scale_1: INTEGER; + scale_2: INTEGER + ); + PORT ( + clk: IN std_logic; + clock_out_1: OUT std_logic; + clock_out_2: OUT std_logic + ); +END clock_divider_module; + +ARCHITECTURE behavior_clock_divider_module OF clock_divider_module IS + signal counter_1: integer range 0 to (scale_1 - 1) := 0; + signal slow_1: std_logic := '0'; + signal counter_2: integer range 0 to (scale_2 - 1) := 0; + signal slow_2: std_logic := '0'; +begin + clock_out_1 <= slow_1; + clock_out_2 <= slow_2; + process(clk) + begin + if rising_edge(clk) then + if (counter_1 = (scale_1 - 1)) then + slow_1 <= '1'; + counter_1 <= 0; + else + slow_1 <= '0'; + counter_1 <= counter_1 + 1; + end if; + if (counter_2 = (scale_2 - 1)) then + slow_2 <= '1'; + counter_2 <= 0; + else + slow_2 <= '0'; + counter_2 <= counter_2 + 1; + end if; + end if; + end process; +end behavior_clock_divider_module; diff --git a/debounce.vhd b/debounce.vhd new file mode 100644 index 0000000..08a968f --- /dev/null +++ b/debounce.vhd @@ -0,0 +1,59 @@ +-------------------------------------------------------------------------------- +-- +-- FileName: debounce.vhd +-- Dependencies: none +-- Design Software: Quartus II 32-bit Version 11.1 Build 173 SJ Full Version +-- +-- HDL CODE IS PROVIDED "AS IS." DIGI-KEY EXPRESSLY DISCLAIMS ANY +-- WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED, INCLUDING BUT NOT +-- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +-- PARTICULAR PURPOSE, OR NON-INFRINGEMENT. IN NO EVENT SHALL DIGI-KEY +-- BE LIABLE FOR ANY INCIDENTAL, SPECIAL, INDIRECT OR CONSEQUENTIAL +-- DAMAGES, LOST PROFITS OR LOST DATA, HARM TO YOUR EQUIPMENT, COST OF +-- PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR SERVICES, ANY CLAIMS +-- BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), +-- ANY CLAIMS FOR INDEMNITY OR CONTRIBUTION, OR OTHER SIMILAR COSTS. +-- +-- Version History +-- Version 1.0 3/26/2012 Scott Larson +-- Initial Public Release +-- +-- Taken from https://eewiki.net/pages/viewpage.action?pageId=4980758 +-------------------------------------------------------------------------------- + +LIBRARY ieee; +USE ieee.std_logic_1164.all; +USE ieee.numeric_std.all; + +ENTITY debounce IS + GENERIC( + counter_size : INTEGER := 19); --counter size (19 bits gives 10.5ms with 50MHz clock) + PORT( + clk : IN STD_LOGIC; --input clock + button : IN STD_LOGIC; --input signal to be debounced + result : OUT STD_LOGIC); --debounced signal +END debounce; + +ARCHITECTURE logic OF debounce IS + SIGNAL flipflops : STD_LOGIC_VECTOR(1 DOWNTO 0); --input flip flops + SIGNAL counter_set : STD_LOGIC; --sync reset to zero + SIGNAL counter_out : STD_LOGIC_VECTOR(counter_size DOWNTO 0) := (OTHERS => '0'); --counter output +BEGIN + + counter_set <= flipflops(0) xor flipflops(1); --determine when to start/reset counter + + PROCESS(clk) + BEGIN + IF(clk'EVENT and clk = '1') THEN + flipflops(0) <= button; + flipflops(1) <= flipflops(0); + If(counter_set = '1') THEN --reset counter because input is changing + counter_out <= (OTHERS => '0'); + ELSIF(counter_out(counter_size) = '0') THEN --stable input time is not yet met + counter_out <= std_logic_vector(unsigned(counter_out) + 1); + ELSE --stable input time is met + result <= flipflops(1); + END IF; + END IF; + END PROCESS; +END logic; diff --git a/demo.vhd b/demo.vhd new file mode 100644 index 0000000..ca9c05e --- /dev/null +++ b/demo.vhd @@ -0,0 +1,51 @@ +LIBRARY ieee; +USE ieee.std_logic_1164.ALL; +USE ieee.numeric_std.all; + +library work; + +entity demo is + PORT( + -- the system's clock + clk: IN STD_LOGIC; + -- outputs from byte display + segments: out std_logic_vector(1 downto 0); + leds: out std_logic_vector(6 downto 0); + -- inputs from byte input + switches: in std_logic_vector(7 downto 0); + button: in std_LOGIC + ); +end demo; + +architecture sim of demo is + SIGNAL slow_clk: STD_LOGIC := '0'; + SIGNAL ram_clk: STD_LOGIC := '0'; + + SIGNAL s_address:STD_LOGIC_VECTOR (3 DOWNTO 0) := "0000"; + SIGNAL s_data_in: STD_LOGIC_VECTOR (7 DOWNTO 0); + SIGNAL s_data_out: STD_LOGIC_VECTOR (7 DOWNTO 0) := x"FF"; + SIGNAL s_wren: STD_LOGIC := '0'; +begin + clock_divider: entity work.clock_divider_module generic map ( + scale_1 => 25000000, + scale_2 => 25000000/4 + ) port map (clk, slow_clk, ram_clk); + + input: entity work.byte_input port map ( + clk, + s_data_out, + switches, + button + ); + + display: entity work.byte_display port map ( + clk => clk, + reset => '0', + write => slow_clk, + enable => slow_clk, + --data => "0000" & s_address, + data => s_data_out, + segments => segments, + leds => leds + ); +END sim;