diff --git a/soc/peripheral/scrolling_controller.vhd b/soc/peripheral/scrolling_controller.vhd new file mode 100644 index 0000000..66535e7 --- /dev/null +++ b/soc/peripheral/scrolling_controller.vhd @@ -0,0 +1,104 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +entity scrolling_controller is + port( + clk : in std_logic; + rst : in std_logic; + on_off : in std_logic; + cnt_start : out std_logic; + cnt_done : in std_logic; + next_char : out std_logic; + hex_char : in std_logic_vector(4 downto 0); + seg_data : out std_logic_vector(3 downto 0); + seg_off : out std_logic; + seg_shift : out std_logic; + seg_write : out std_logic; + seg_clear : out std_logic + ); +end entity scrolling_controller; + +architecture Behavioral of scrolling_controller is + + type state_type is (s_off, s_wait, s_update); + signal state : state_type; + +begin + + process(clk) + begin + if clk'event and clk='1' then + if rst = '1' then + state <= s_off; + seg_clear <= '1'; + cnt_start <= '0'; + next_char <= '0'; + + seg_data <= (others => '0'); + seg_off <= '0'; + seg_shift <= '0'; + seg_write <= '0'; + else + case state is + when s_off => + if on_off = '0' then + state <= s_off; + seg_shift <= '0'; + seg_write <= '0'; + seg_clear <= '0'; + cnt_start <= '0'; + next_char <= '0'; + else + state <= s_update; + seg_data <= hex_char(3 downto 0); + seg_shift <= '1'; + seg_write <= '1'; + seg_clear <= '0'; + seg_off <= hex_char(4); + cnt_start <= '1'; + next_char <= '1'; + end if; + when s_wait => + if on_off = '1' then + state <= s_off; + seg_clear <= '1'; + cnt_start <= '0'; + next_char <= '0'; + elsif cnt_done = '0' then + state <= s_wait; + seg_shift <= '0'; + seg_write <= '0'; + seg_clear <= '0'; + cnt_start <= '0'; + next_char <= '0'; + else -- cnt_cone = '1' + state <= s_update; + seg_shift <= '0'; + seg_write <= '0'; + seg_clear <= '0'; + cnt_start <= '1'; + next_char <= '1'; + end if; + when s_update => + if on_off = '0' then + state <= s_wait; + seg_data <= hex_char(3 downto 0); + seg_shift <= '1'; + seg_write <= '1'; + seg_clear <= '0'; + seg_off <= hex_char(4); + cnt_start <= '0'; + next_char <= '0'; + else + state <= s_off; + seg_clear <= '1'; + cnt_start <= '0'; + next_char <= '0'; + end if; + end case; + end if; + end if; + end process; + +end Behavioral; diff --git a/soc/testbench/scrolling_controller_tb.vhd b/soc/testbench/scrolling_controller_tb.vhd new file mode 100644 index 0000000..cfebc79 --- /dev/null +++ b/soc/testbench/scrolling_controller_tb.vhd @@ -0,0 +1,102 @@ +-- See the file "LICENSE" for the full license governing this code. -- +LIBRARY ieee; +USE ieee.std_logic_1164.ALL; +USE ieee.numeric_std.ALL; + +LIBRARY work; +USE work.lt16soc_peripherals.ALL; + +ENTITY scrolling_controller_tb IS +END ENTITY; + +ARCHITECTURE sim OF scrolling_controller_tb IS + + constant CLK_PERIOD : time := 10 ns; + + signal rst : std_logic; + signal clk : std_logic := '0'; + + signal on_off : std_logic := '0'; + signal cnt_start : std_logic := '0'; + signal cnt_done : std_logic := '0'; + signal next_char : std_logic := '0'; + signal hex_char : std_logic_vector(4 downto 0) := (others => '0'); + signal seg_data : std_logic_vector(3 downto 0) := (others => '0'); + signal seg_off : std_logic := '0'; + signal seg_shift : std_logic := '0'; + signal seg_write : std_logic := '0'; + signal seg_clear : std_logic := '0'; + + component scrolling_controller + port( + clk : in std_logic; + rst : in std_logic; + on_off : in std_logic; + cnt_start : out std_logic; + cnt_done : in std_logic; + next_char : out std_logic; + hex_char : in std_logic_vector(4 downto 0); + seg_data : out std_logic_vector(3 downto 0); + seg_off : out std_logic; + seg_shift : out std_logic; + seg_write : out std_logic; + seg_clear : out std_logic + ); + end component; +BEGIN + + controller: scrolling_controller + port map( + clk => clk, + rst => rst, + on_off => on_off, + cnt_start => cnt_start, + cnt_done => cnt_done, + next_char => next_char, + hex_char => hex_char, + seg_data => seg_data, + seg_off => seg_off, + seg_shift => seg_shift, + seg_write => seg_write, + seg_clear => seg_clear + ); + + clk_gen: process + begin + clk <= not clk; + wait for CLK_PERIOD/2; + end process clk_gen; + + stimuli: process + begin + rst <= '1'; + wait for CLK_PERIOD; + + rst <= '0'; + wait for CLK_PERIOD; + + hex_char <= "01010"; + + wait for CLK_PERIOD * 2; + on_off <= '1'; + + wait for CLK_PERIOD; + on_off <= '0'; + + wait for CLK_PERIOD*3; + hex_char <= "00101"; + cnt_done <= '1'; + + wait for CLK_PERIOD; + cnt_done <= '0'; + + wait for CLK_PERIOD * 3; + on_off <= '1'; + hex_char <= "01111"; + + wait for CLK_PERIOD * 5; + + assert false report "Simulation terminated!" severity failure; + end process stimuli; + +END ARCHITECTURE;