---------------------------------------------------------------------------- -- cnt8.vhd -- Limited 8bit Counter (Small) -- Version 1.0 -- -- Copyright (C) 2017 H.Poetzl -- -- This program is free software: you can redistribute it and/or -- modify it under the terms of the GNU General Public License -- as published by the Free Software Foundation, either version -- 2 of the License, or (at your option) any later version. -- ---------------------------------------------------------------------------- library IEEE; use IEEE.std_logic_1164.ALL; use IEEE.numeric_std.ALL; library unisim; use unisim.VCOMPONENTS.ALL; library unimacro; use unimacro.VCOMPONENTS.ALL; entity cnt8 is generic ( LIMIT : integer := 250 ); port ( C : in std_logic; R : in std_logic; Q : out std_logic_vector(7 downto 0) ); end entity; architecture RTL of cnt8 is type LUT_t is array (natural range <>) of bit_vector(63 downto 0); type L6I_t is array (natural range <>) of std_logic_vector(5 downto 0); type L2Q_t is array (natural range <>) of std_logic_vector(1 downto 0); constant SLUT : LUT_t (0 to 3) := ( x"6CCCCCCC_5AAAAAAA", x"6CCCCCCC_5AAAAAAA", x"6CCCCCCC_5AAAAAAA", x"6CCCCCCC_5AAAAAAA"); signal SLI : L6I_t (0 to 3); signal SLQ : L2Q_t (0 to 3); constant CL : bit_vector(15 downto 0) := ((LIMIT mod 16) => '1', others => '0'); constant CH : bit_vector(15 downto 0) := ((LIMIT / 16) => '1', others => '0'); constant CLUT : LUT_t (0 to 2) := ( x"80008000_88888888", CH & x"0000_88888888", x"FFFFFFFF" & CL & x"0000"); signal CLI : L6I_t (0 to 2); signal CLQ : L2Q_t (0 to 2); signal RQ : std_logic_vector(7 downto 0) := (others => '0'); attribute RLOC : string; attribute RLOC of RQ : signal is "X0Y0"; signal SR : std_logic; begin GEN_SLUT : for I in 0 to 3 generate attribute RLOC of SLUT_inst : label is "X0Y0"; begin SLUT_inst : LUT6_2 generic map (INIT => SLUT(I)) port map ( I0 => SLI(I)(0), I1 => SLI(I)(1), I2 => SLI(I)(2), I3 => SLI(I)(3), I4 => SLI(I)(4), I5 => SLI(I)(5), O5 => SLQ(I)(0), O6 => SLQ(I)(1)); SLI(I)(0) <= RQ(I*2 + 0); -- direct feedback SLI(I)(1) <= RQ(I*2 + 1); -- direct feedback CLI(0)(I) <= RQ(I); -- carry in CLI(1)(I) <= RQ(I + 4); -- c&c in CLI(2)(I) <= RQ(I); -- check in end generate; reg_proc : process(C) begin if rising_edge(C) then if SR = '1' then RQ <= (others => '0'); else for I in 0 to 3 loop RQ(I*2 + 0) <= SLQ(I)(0); RQ(I*2 + 1) <= SLQ(I)(1); end loop; end if; end if; end process; GEN_CLUT : for I in 0 to 2 generate attribute RLOC of CLUT_inst : label is "X1Y0"; begin CLUT_inst : LUT6_2 generic map (INIT => CLUT(I)) port map ( I0 => CLI(I)(0), I1 => CLI(I)(1), I2 => CLI(I)(2), I3 => CLI(I)(3), I4 => CLI(I)(4), I5 => CLI(I)(5), O5 => CLQ(I)(0), O6 => CLQ(I)(1)); end generate; CLI(0)(5 downto 4) <= "11"; CLI(1)(5 downto 4) <= "11"; CLI(2)(4) <= CLQ(1)(1); -- check in CLI(2)(5) <= R; -- reset SLI(0)(5 downto 2) <= "1111"; SLI(1)(5 downto 3) <= "111"; SLI(1)(2) <= CLQ(0)(0); -- carry SLI(2)(5 downto 3) <= "111"; SLI(2)(2) <= CLQ(0)(1); -- carry SLI(3)(5 downto 4) <= "11"; SLI(3)(3) <= CLQ(1)(0); -- carry SLI(3)(2) <= CLQ(0)(1); -- carry SR <= CLQ(2)(1); -- reset Q <= RQ; end RTL;