The Dual-Modulus Divider in VHDL

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

posted @ 2012-05-10 19:28  IAmAProgrammer  阅读(464)  评论(0编辑  收藏  举报