Hi
below is possible the most dense divide by 2^n ever implemented on any FPGA: divide by 2^37 takes only 3 Virtex Slices! (4 slices on spartan-3)
Antti
--
--
--
-- Divide by 2^n, n=21..37, code=0000 n=37, code=1111 n=21
-- Theory of operation:
-- bit serial NCO with 32 bit phase accumulator (2 LUT's as SRL16),
-- phase increment is fixed constant "..0001" (2LUT's as SRL16)
-- 1 LUT for 1 bit adder, 1 LUT for carry logic,
-- 1 flip-flop for carry, 1 flip-flop for 1 bit serial to parallel conversion
-- total: 3 Slices (4 for Spartan3)
-- the bit serial auto divides the incoming clock by 2^5 that is the frequency
-- for the NCO to operate, the phase accumulator gets overflow in 2^32 so the
-- maximum divide constant is 2^37
-- :)
-- snipped-for-privacy@openchip.org
library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; library UNISIM; use UNISIM.VComponents.all;
entity div_2n_21_37 is Port ( clk : in std_logic; code : in std_logic_vector(3 downto 0); fout : out std_logic); end div_2n_21_37;
architecture Behavioral of div_2n_21_37 is signal one_L: std_logic; signal one_H: std_logic; signal one_X: std_logic; signal accu_L: std_logic; signal accu_in: std_logic; signal accu_out: std_logic; signal cy_out: std_logic; signal cy_in: std_logic;
begin
-- rotating 1, 32 bit long Instance_SRL16_1L: SRLC16E generic map (INIT => X"0001") port map (CLK => clk, CE => '1', A0 => code(0), A1 => code(1), A2 =>
code(2), A3 => code(3), Q => one_X, D => one_H, Q15 => one_L); Instance_SRL16_1H: SRLC16E generic map (INIT => X"0000") port map (CLK => clk, CE => '1', A0 => '1', A1 => '1', A2 => '1', A3 => '1', Q => one_H, D => one_L, Q15 => open);
-- rotating ACCU, 32 bit long Instance_SRL16_AL: SRLC16E generic map (INIT => X"0000") port map (CLK => clk, CE => '1', A0 => '0', A1 => '0', A2 => '0', A3 => '0', Q => open, D => accu_in, Q15 => accu_L); Instance_SRL16_AH: SRLC16E generic map (INIT => X"0000") port map (CLK => clk, CE => '1', A0 => '0', A1 => '0', A2 => '0', A3 => '0', Q => open, D => accu_L, Q15 => accu_out);
-- ALU add 1 with Carry, only when not 1 accu_in clk, D => cy_in, R => '0');
-- 1 bit serial to parallel converter Instance_fout: FDRE port map(Q => fout, C => clk, CE=> one_X, D => accu_out, R => '0'); end Behavioral;