library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

library UNISIM;
use UNISIM.vcomponents.all;

entity clock_divider is
generic (
	G_DIVISOR : positive := 2
);
port (
	
	i_clk : in std_logic;
	i_rst : in std_logic;
	
	o_clk : out std_logic
	
);
end entity clock_divider;

architecture behavioral of clock_divider is

subtype t_counter is natural range 0 to ( G_DIVISOR - 1 );
signal s_counter : t_counter := 0;

constant C_COUNTER : t_counter := G_DIVISOR / 2 - 1;

signal s_clk_divided : std_logic;
attribute clock_signal : string;
attribute clock_signal of s_clk_divided : signal is "yes";

begin

	assert ( G_DIVISOR > 1 ) report "The divisor should be greater than 1" severity failure;
	
	counting : process( i_clk )
	begin
		if( rising_edge(i_clk) ) then
			if( i_rst = '1' ) then
				s_counter <= 0;
				s_clk_divided <= '0';
			else
				if( s_counter = t_counter'high ) then
					s_counter <= 0;
					s_clk_divided <= '0';
				else
					s_counter <= s_counter + 1;
					if( s_counter = C_COUNTER ) then
						s_clk_divided <= '1';
					end if;
				end if;
			end if;
		end if;
	end process counting;
	
	BUFR_inst : BUFR
	generic map (
		BUFR_DIVIDE => "BYPASS", -- "BYPASS", "1", "2", "3", "4", "5", "6", "7", "8"
		SIM_DEVICE => "VIRTEX6") -- Specify target device, "VIRTEX4", "VIRTEX5", "VIRTEX6"
	port map (
		O => o_clk, -- Clock buffer output
		CE => '1', -- Clock enable input
		CLR => '0', -- Clock buffer reset input
		I => s_clk_divided -- Clock buffer input
	);
					
end architecture;
