From 3d4ae63afb93686dde6c3076db5c499ca4b68fa8 Mon Sep 17 00:00:00 2001 From: Derek Christ Date: Mon, 14 Nov 2022 16:41:54 +0100 Subject: [PATCH] Add scrolling timer --- soc/peripheral/scrolling_timer.vhd | 50 ++++++++++++++++++ soc/testbench/scrolling_timer_tb.vhd | 77 ++++++++++++++++++++++++++++ 2 files changed, 127 insertions(+) create mode 100644 soc/peripheral/scrolling_timer.vhd create mode 100644 soc/testbench/scrolling_timer_tb.vhd diff --git a/soc/peripheral/scrolling_timer.vhd b/soc/peripheral/scrolling_timer.vhd new file mode 100644 index 0000000..7f2d2ec --- /dev/null +++ b/soc/peripheral/scrolling_timer.vhd @@ -0,0 +1,50 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +entity scrolling_timer is + port( + clk : in std_logic; + rst : in std_logic; + cnt_start : in std_logic; + cnt_done : out std_logic; + cnt_value : in std_logic_vector(31 downto 0) + ); +end entity scrolling_timer; + +architecture Behavioral of scrolling_timer is + + signal counter : std_logic_vector(31 downto 0); + signal done : std_logic; + signal counting : std_logic; + signal value : std_logic_vector(31 downto 0); + +begin + + process(clk) + begin + if clk'event and clk='1' then + if rst = '1' then + counter <= x"00000000"; + done <= '0'; + counting <= '0'; + else + value <= cnt_value; + done <= '0'; + + if counter = value and counting = '1' then + counter <= x"00000000"; + done <= '1'; + counting <= '0'; + elsif counting = '1' then + counter <= std_logic_vector(unsigned(counter) + 1); + elsif counting = '0' and cnt_start = '1' then + counting <= '1'; + end if; + end if; + end if; + end process; + + cnt_done <= done; + +end Behavioral; diff --git a/soc/testbench/scrolling_timer_tb.vhd b/soc/testbench/scrolling_timer_tb.vhd new file mode 100644 index 0000000..95f31ff --- /dev/null +++ b/soc/testbench/scrolling_timer_tb.vhd @@ -0,0 +1,77 @@ +-- 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_timer_tb IS +END ENTITY; + +ARCHITECTURE sim OF scrolling_timer_tb IS + + constant CLK_PERIOD : time := 10 ns; + + signal rst : std_logic; + signal clk : std_logic := '0'; + + signal cnt_start : std_logic := '0'; + signal cnt_done : std_logic := '0'; + signal cnt_value : std_logic_vector(31 downto 0) := x"00000000"; + + component scrolling_timer is + port( + clk : in std_logic; + rst : in std_logic; + cnt_start : in std_logic; + cnt_done : out std_logic; + cnt_value : in std_logic_vector(31 downto 0) + ); + end component; + +BEGIN + + timer: scrolling_timer + port map( + clk => clk, + rst => rst, + cnt_start => cnt_start, + cnt_done => cnt_done, + cnt_value => cnt_value + ); + + 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*3; + + cnt_value <= x"00000100"; + cnt_start <= '1'; + + wait for CLK_PERIOD; + cnt_start <= '0'; + + wait for CLK_PERIOD * 300; + + cnt_value <= x"0000000A"; + cnt_start <= '1'; + + wait for CLK_PERIOD; + cnt_start <= '0'; + + wait for CLK_PERIOD * 15; + + assert false report "Simulation terminated!" severity failure; + end process stimuli; + +END ARCHITECTURE;