http://www.edn.com/contents/images/6372832.pdf
1 library ieee; 2 use ieee.std_logic_1164.all; 3 4 entity example_dual_mod is 5 port( 6 reset : in std_logic; -- Active-High Synchronous Reset 7 clock : in std_logic; -- Input Clock 8 output : out std_logic -- Output Baud Clock 9 ); 10 end example_dual_mod; 11 12 architecture implementation of example_dual_mod is 13 14 -- These parameters calculated according to the text. 15 -- This set generates 115200 Hz rate output from 10 MHz 16 constant C : integer := 72; -- Sequence Length 17 constant B : integer := 43; -- # of times to divide by P 18 constant N : integer := 44; -- N should always be P+1 19 constant P : integer := 43; -- P should always be N-1 20 21 signal seq_ctr : integer range 0 to C-1; -- Sequence Counter 22 signal dual_mod_load : integer range 0 to N-1; -- Selected load value 23 signal dual_mod_ctr : integer range 0 to N-1; -- Dual Modulus Counter 24 signal mux_select : std_logic; -- Selects between N and P 25 signal term_count : std_logic; -- Dual Modulus Terminal Count 26 signal divider : std_logic; -- Output Divider 27 28 begin 29 30 -- This is the sequence counter. Count from C-1 downto 0. Enabled only 31 -- when term_count is active. If count is 0, then reload to C-1 32 pSeqCount : process(clock) 33 begin 34 if (rising_edge(clock)) then 35 if (reset = '1') then 36 seq_ctr <= 0; 37 else 38 if (term_count = '1') then 39 if (seq_ctr = 0) then 40 seq_ctr <= C-1; 41 else 42 seq_ctr <= seq_ctr - 1; 43 end if; 44 end if; 45 end if; 46 end if; 47 end process; 48 49 -- This is the comparison of the current sequence count to the value B 50 mux_select <= '1' when (seq_ctr < B) else '0'; 51 52 -- This statement implements the modulus selection multiplexer 53 dual_mod_load <= (P-1) when (mux_select = '1') else (N-1); 54 55 -- This is the dual-modulus counter. Count from dual_mod_load downto 0. 56 -- Counter auto reloads when terminal count is reached. 57 pDualModCount : process(clock) 58 begin 59 if (rising_edge(clock)) then 60 if (reset = '1') then 61 dual_mod_ctr <= 0; 62 else 63 if (term_count = '1') then 64 dual_mod_ctr <= dual_mod_load; 65 else 66 dual_mod_ctr <= dual_mod_ctr - 1; 67 end if; 68 end if; 69 end if; 70 end process; 71 72 -- Detect the terminal count condition 73 term_count <= '1' when (dual_mod_ctr = 0) else '0'; 74 75 -- The output divide-by-two counter 76 pDivider : process(clock) 77 begin 78 if (rising_edge(clock)) then 79 if (reset = '1') then 80 divider <= '0'; 81 elsif (term_count = '1') then 82 divider <= not(divider); 83 end if; 84 end if; 85 end process; 86 87 -- Module Output 88 output <= divider; 89 90 end implementation;
1 library ieee; 2 use ieee.std_logic_1164.all; 3 4 entity dual_mod_tb is 5 end dual_mod_tb; 6 7 architecture testbench of dual_mod_tb is 8 9 signal clock : std_logic; 10 signal reset : std_logic; 11 signal output : std_logic; 12 13 begin 14 15 UUT : entity work.example_dual_mod 16 port map( 17 reset => reset, -- Active-High Synchronous Reset 18 clock => clock, -- Input Clock 19 output => output -- Output Baud Clock 20 ); 21 22 pClock : process 23 begin 24 clock <= '0'; 25 wait for 10 ns; 26 clock <= '1'; 27 wait for 10 ns; 28 end process; 29 30 pReset : process 31 begin 32 reset <= '1'; 33 wait until rising_edge(clock); 34 wait until rising_edge(clock); 35 wait until rising_edge(clock); 36 reset <= '0'; 37 wait; -- Forever 38 end process; 39 40 end testbench;
http://electronix.ru/forum/lofiversion/index.php/t22525.html