diff --git a/clock_divider.vhdl b/clock_divider.vhdl new file mode 100644 index 0000000..7d19588 --- /dev/null +++ b/clock_divider.vhdl @@ -0,0 +1,40 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +entity clock_divider is + generic ( + N : integer := 8 + ); + port ( + i_clk : in std_logic; + i_reset_n : in std_logic; + i_divisor_vec : in std_logic_vector(N-1 downto 0); + o_clk : out std_logic + ); +end; + +architecture clock_divider_rtl of clock_divider is +begin + clock_divider_main_proc: process(i_clk) + variable v_cnt : integer range 0 to 2**(N-1) := 0; + variable v_cnt_max : integer range 0 to (2**(N-1))/2 := 0; + variable v_clk : std_logic := '0'; + begin + if rising_edge(i_clk) then + if (i_reset_n = '0') then + v_cnt := 1; + v_cnt_max := to_integer(unsigned(i_divisor_vec))/2; + v_clk := '1'; + else + if (v_cnt >= v_cnt_max) then + v_cnt := 1; + v_clk := not v_clk; + else + v_cnt := v_cnt + 1; + end if; + end if; + end if; + o_clk <= v_clk; + end process clock_divider_main_proc; +end; diff --git a/clock_divider_tb.vhdl b/clock_divider_tb.vhdl new file mode 100644 index 0000000..43d51f7 --- /dev/null +++ b/clock_divider_tb.vhdl @@ -0,0 +1,52 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +entity clock_divider_tb is +end clock_divider_tb; + +architecture clock_divider_tb_rtl of clock_divider_tb is + -- 10 MHz clock + constant c_CLK_PERIOD : time := 100 ns; + constant c_N : integer := 8; + --for clock_divider_0: clock_divider use entity work.clock_divider; + signal tb_i_clk : std_logic := '0'; + signal tb_i_reset_n : std_logic := '1'; + signal tb_i_divisor_vec : std_logic_vector(c_N-1 downto 0) := x"00"; + signal tb_o_clk : std_logic := '0'; + signal tb_done : std_logic := '0'; +begin + --clock_divider_0: clock_divider + clock_divider_0: entity work.clock_divider(clock_divider_rtl) + generic map (N => c_N) + port map ( + i_clk => tb_i_clk, + i_reset_n => tb_i_reset_n, + i_divisor_vec => tb_i_divisor_vec, + o_clk => tb_o_clk + ); + -- Generate clock. + p_clock : process is + begin + if (tb_done = '0') then + tb_i_clk <= '0'; + wait for c_CLK_PERIOD/2; + tb_i_clk <= '1'; + wait for c_CLK_PERIOD/2; + elsif tb_done = '1' then + wait; + end if; + end process p_clock; + -- Process for stimuli. + p_stimuli : process is + begin + tb_i_divisor_vec <= x"02"; + tb_i_reset_n <= '0'; + wait for c_CLK_PERIOD; + tb_i_reset_n <= '1'; + wait for 1 ms; + tb_done <= '1'; + assert false report "end of test" severity note; + wait; + end process p_stimuli; +end clock_divider_tb_rtl;