VHDL 整数 小数 分数 分频

 1 --Description: 带复位功能的加法计数器
 2 library IEEE;
 3 use IEEE.STD_LOGIC_1164.ALL;
 4 use IEEE.STD_LOGIC_ARITH.ALL;
 5 use IEEE.STD_LOGIC_UNSIGNED.ALL;
 6 
 7 entity ripple is
 8   generic (width: integer := 4);
 9   port( clk, rst: in std_logic;
10         cnt: out std_logic_vector(width - 1 downto 0));
11 end ripple;
12 
13 architecture a of ripple is
14 
15 signal cntQ: std_logic_vector(width - 1 downto 0);
16 begin
17   process(clk, rst)
18   begin
19     if (rst = '1') then
20       cntQ <= (others => '0');
21     elsif (clk'event and clk = '1') then
22       cntQ <= cntQ + 1;
23     end if;
24   end process;
25   cnt <= cntQ;
26 end a;
 1 --Description: 带复位功能的约翰逊计数器
 2 library IEEE;
 3 use IEEE.STD_LOGIC_1164.ALL;
 4 use IEEE.STD_LOGIC_ARITH.ALL;
 5 use IEEE.STD_LOGIC_UNSIGNED.ALL;
 6 
 7 entity johnson is
 8   generic (width: integer := 4);
 9   port (clk, rst: in std_logic;
10         cnt: out std_logic_vector(width - 1 downto 0));
11 end johnson;
12 
13 architecture a of johnson is signal cntQ: std_logic_vector(width - 1 downto 0);
14 begin
15   process(clk, rst)
16   begin
17     if(rst = '1') then
18       cntQ <= (others => '0');
19     elsif (rising_edge(clk)) then
20       cntQ(width - 1 downto 1) <= cntQ(width - 2 downto 0);
21       cntQ(0) <= not cntQ(width - 1);
22     end if;
23   end process;
24   cnt <= cntQ;
25 end a;
 1 --Description: 占空比 50% 的 6 分频
 2 library IEEE;
 3 use IEEE.STD_LOGIC_1164.ALL;
 4 use IEEE.STD_LOGIC_ARITH.ALL;
 5 use IEEE.STD_LOGIC_UNSIGNED.ALL;
 6 
 7 entity clk_div1 is
 8   port ( clk_in : in std_logic;
 9     clk_out : out std_logic);
10 end clk_div1;
11 
12 -- 偶数分频 占空比一直是 50%
13 architecture a of clk_div1 is
14   signal clk_outQ : std_logic := '0';
15   signal countQ : std_logic_vector ( 2 downto 0 ) := "000";
16 begin
17   process(clk_in)
18   begin
19     if (rising_edge(clk_in)) then
20       if ( countQ /= ( 6/2 - 1) ) then  -- countQ != N/2 - 1
21         countQ <= CountQ + 1;           -- INC
22       else                              -- countQ == N/2 - 1
23         clk_outQ <= not clk_outQ;       -- NOT clk_out
24         countQ <= ( others => '0' );    -- RESET
25       end if;
26     end if;
27   end process;
28 
29   clk_out <= clk_outQ;
30 end a;
31 
32 -- 偶数分频 有限度的调整占空比 40%, 50%, 60% etc.
33 -- 奇数分频 占空比 40%, 60% etc. 不可能是 50%
34 --
35 architecture b of clk_div1 is
36   signal countQ : std_logic_vector ( 2 downto 0 ) := "000";
37 begin
38   process(clk_in)
39   begin
40     if (rising_edge(clk_in)) then
41       if ( countQ < 5 ) then            -- 0..N-2
42         countQ <= CountQ + 1;           -- 1..N-1
43       else
44         countQ <= ( others => '0' );    -- Reset when countQ == N-1
45       end if;
46     end if;
47   end process;
48 
49   process(countQ)
50   begin
51     if ( countQ < 3 ) then
52       clk_out <= '0';                   -- '0' when 0..N/2-1
53     else
54       clk_out <= '1';                   -- '1' when N/2 .. N-1
55     end if;
56   end process;
57 
58 end b;
59 
60 configuration cfg of clk_div1 is
61   for a
62   end for;
63 end cfg;
 1 -- 奇数分频 占空比 40%, 60% etc. 不可能是 50%
 2 --
 3 --Description: 占空比 40% 的 5 分频
 4 library IEEE;
 5 use IEEE.STD_LOGIC_1164.ALL;
 6 use IEEE.STD_LOGIC_ARITH.ALL;
 7 use IEEE.STD_LOGIC_UNSIGNED.ALL;
 8 
 9 entity clk_div2 is
10   port ( clk_in : in std_logic;
11     clk_out : out std_logic);
12 end clk_div2;
13 
14 architecture a of clk_div2 is
15   signal countQ : std_logic_vector ( 2 downto 0 ) := "000";
16 begin
17   process(clk_in)
18   begin
19     if (rising_edge(clk_in)) then
20       if ( countQ < 4 ) then            -- 0..N-2
21         countQ <= CountQ + 1;           -- 1..N-1
22       else
23         countQ <= ( others => '0' );    -- Reset when countQ == N-1
24       end if;
25     end if;
26   end process;
27 
28   process(countQ)
29   begin
30     if ( countQ < 3 ) then
31       clk_out <= '0';                   -- '0' when 0..N/2-1
32     else
33       clk_out <= '1';                   -- '1' when N/2 .. N-1
34     end if;
35   end process;
36 
37 end a;
 1 -- 50% 占空比的奇数分频 7 : 2N+1 (N=3)
 2 -- 对输入时钟的上升沿和下降沿分别进行 (3/7) : N / (2N+1) 分频
 3 -- 然后对分频后的两个时钟 相或 OR 得到 50% 占空比的奇数分频 2N+1
 4 library IEEE;
 5 use IEEE.STD_LOGIC_1164.ALL;
 6 use IEEE.STD_LOGIC_ARITH.ALL;
 7 use IEEE.STD_LOGIC_UNSIGNED.ALL;
 8 
 9 entity clk_div3 is
10   port ( clk_in : in std_logic;
11     clk_out : out std_logic);
12 end clk_div3;
13 
14 architecture a of clk_div3 is
15   signal cnt1, cnt2 : integer range 0 to 6;
16   signal clk1, clk2 : std_logic;
17 begin
18   process(clk_in)
19   begin
20     if (rising_edge(clk_in)) then
21       if ( cnt1 < 6 ) then            -- 0..N-2
22         cnt1 <= cnt1 + 1;             -- 1..N-1
23       else
24         cnt1 <= 0;                    -- Reset when cnt1 == N-1
25       end if;
26 
27       if ( cnt1 < 3 ) then
28         clk1 <= '0';                    -- '0' when 0..N/2-1
29       else
30         clk1 <= '1';                    -- '1' when N/2 .. N-1
31       end if;
32 
33     end if;
34   end process;
35 
36   process(clk_in)
37   begin
38     if (falling_edge(clk_in)) then
39       if ( cnt2 < 6 ) then            -- 0..N-2
40         cnt2 <= cnt2 + 1;             -- 1..N-1
41       else
42         cnt2 <= 0;                    -- Reset when cnt1 == N-1
43       end if;
44 
45       if ( cnt2 < 3 ) then
46         clk2 <= '0';                    -- '0' when 0..N/2-1
47       else
48         clk2 <= '1';                    -- '1' when N/2 .. N-1
49       end if;
50 
51     end if;
52   end process;
53 
54   clk_out <= clk1 or clk2;
55 end a;
 1 -- 半整数分频 2.5 : N = 2 : ( N+0.5) 非 50% 占空比
 2 -- 占空比 : (M+0.5) / (N+0.5)
 3 -- 占空比 : (    M) / (N+0.5)
 4 -- 条件   : M < N
 5 -- 对输入时钟操作, 让计数器达到某一个数值时, 将输入始终翻转一次
 6 -- 这样这个计数值只保存了半个时钟周期, 实现了半整数分频
 7 -- 将 50% 占空比的奇数分频与输入时钟 异或 XOR 得到计数脉冲
 8 
 9 library IEEE;
10 use IEEE.STD_LOGIC_1164.ALL;
11 use IEEE.STD_LOGIC_ARITH.ALL;
12 use IEEE.STD_LOGIC_UNSIGNED.ALL;
13 
14 entity clk_div4 is
15   port ( clk_in : in std_logic;
16     clk_out : out std_logic);
17 end clk_div4;
18 
19 architecture a of clk_div4 is
20   signal cnt1 : integer range 0 to 4;
21   signal cnt2 : integer range 0 to 4;
22   signal cnt3 : integer range 0 to 2;
23 
24   signal clk1, clk2 : std_logic;
25   signal pclk, lclk : std_logic;
26 begin
27   process(clk_in)
28   begin
29     if (rising_edge(clk_in)) then
30       if ( cnt1 < 4 ) then            -- 0..N-2
31         cnt1 <= cnt1 + 1;             -- 1..N-1
32       else
33         cnt1 <= 0;                    -- Reset when cnt1 == N-1
34       end if;
35     end if;
36   end process;
37 
38   process(cnt1)
39   begin
40     if ( cnt1 < 3 ) then
41       clk1 <= '0';                    -- '0' when 0..N/2-1
42     else
43       clk1 <= '1';                    -- '1' when N/2 .. N-1
44     end if;
45   end process;
46 
47   process(clk_in)
48   begin
49     if (falling_edge(clk_in)) then
50       if ( cnt2 < 4 ) then            -- 0..N-2
51         cnt2 <= cnt2 + 1;             -- 1..N-1
52       else
53         cnt2 <= 0;                    -- Reset when cnt1 == N-1
54       end if;
55     end if;
56   end process;
57 
58   process(cnt2)
59   begin
60     if ( cnt2 < 3 ) then
61       clk2 <= '0';                    -- '0' when 0..N/2-1
62     else
63       clk2 <= '1';                    -- '1' when N/2 .. N-1
64     end if;
65   end process;
66 
67   pclk <= clk1 or clk2;
68   lclk <= pclk xor clk_in;
69 
70   process(lclk)
71   begin
72     if (rising_edge(lclk)) then
73       if ( cnt3 < 2 ) then            -- 0..N-2
74         cnt3 <= cnt3 + 1;             -- 1..N-1
75       else
76         cnt3 <= 0;                    -- Reset when cnt1 == N-1
77       end if;
78     end if;
79   end process;
80 
81   process(cnt3)
82   begin
83     if ( cnt3 < 1 ) then
84       clk_out <= '0';                   -- '0' when 0..N/2-1
85     else
86       clk_out <= '1';                   -- '1' when N/2 .. N-1
87     end if;
88   end process;
89 end a;
  1 -- 任意小数分频器
  2 -- 通过平均分布可变分频实现
  3 -- Div 4.7  : 共计  10次分频 =  7次     5分频 +        3次 4分频
  4 -- Div M.N  : 共计  10次分频 =  N次 (M+1)分频 +   (10-N)次 M分频
  5 
  6 -- Div 5.67 : 共计 100次分频 = 67次     6分频 +       33次 5分频
  7 -- Div M.NN : 共计 100次分频 = NN次 (M+1)分频 + (100-NN)次 M分频
  8 
  9 -- 平均分布方法 Div 2.7 M=2, N=7
 10 --
 11 -- Index  0       1     2     3     4     5     6     7     8     9
 12 -- Count  7      14    21    28    35    42    49    56    63    70
 13 --
 14 -- Count  7      14    11     8    15    12     9    16    13    10
 15 --
 16 -- Div    2       3     3     2     3     3     2     3     3     3
 17 --
 18 --  process(clkoutQ)
 19 --    var tmp : integer range 0 to 20;
 20 --  begin
 21 --    if (rising_edge(clkoutQ)) then
 22 --      tmp := tmp + 7;
 23 --
 24 --      if ( tmp < 10 ) then
 25 --        ctrl <= '1';
 26 --      else
 27 --        ctrl <= '0';
 28 --        tmp := tmp - 10;
 29 --      end if;
 30 --    end if;
 31 --  end process;
 32 
 33 -- 平均分布方法 Div 2.7 M=2, N=7
 34 --
 35 library IEEE;
 36 use IEEE.STD_LOGIC_1164.ALL;
 37 use IEEE.STD_LOGIC_ARITH.ALL;
 38 use IEEE.STD_LOGIC_UNSIGNED.ALL;
 39 
 40 entity clk_div6 is
 41   port ( clk_in : in std_logic;
 42     clk_out : out std_logic);
 43 end clk_div6;
 44 
 45 -- 实时计算结果
 46 architecture a of clk_div6 is
 47   signal ctrl    : std_logic;
 48 
 49   signal clkoutQ : std_logic;
 50   signal cnt1 : integer range 0 to 1;
 51   signal cnt2 : integer range 0 to 2;
 52 
 53 begin
 54   clk_out <= clkoutQ;
 55 
 56   process(clkoutQ)
 57     variable tmp : integer range 0 to 20;
 58   begin
 59     if (rising_edge(clkoutQ)) then
 60       tmp := tmp + 7;
 61       if ( tmp < 10 ) then
 62         ctrl <= '1';
 63       else
 64         ctrl <= '0';
 65         tmp := tmp - 10;
 66       end if;
 67     end if;
 68   end process;
 69 
 70   process(clk_in)
 71   begin
 72     if (rising_edge(clk_in)) then
 73       if ( ctrl = '1' ) then
 74 
 75         if ( cnt1 < 1 ) then
 76           cnt1 <= cnt1 + 1;
 77         else
 78           cnt1 <= 0;
 79         end if;
 80 
 81         if ( cnt1 < 1 ) then
 82           clkoutQ <= '1';
 83         else
 84           clkoutQ <= '0';
 85         end if;
 86 
 87       else
 88         if ( cnt2 < 2 ) then
 89           cnt2 <= cnt2 + 1;
 90         else
 91           cnt2 <= 0;
 92         end if;
 93 
 94         if ( cnt2 < 1 ) then
 95           clkoutQ <= '1';
 96         else
 97           clkoutQ <= '0';
 98         end if;
 99 
100       end if;
101     end if;
102   end process;
103 
104 end a;
105 
106 -- 实现计算结果
107 architecture b of clk_div6 is
108   signal cnt : integer range 0 to 9;
109 
110   signal clkoutQ : std_logic;
111   signal cnt1 : integer range 0 to 1;
112   signal cnt2 : integer range 0 to 2;
113 
114 begin
115   clk_out <= clkoutQ;
116 
117   process(clkoutQ)
118   begin
119     if (rising_edge(clkoutQ)) then
120       if ( cnt < 9 ) then
121         cnt <= cnt + 1;
122       else
123         cnt <= 0;
124       end if;
125     end if;
126   end process;
127 
128   process(clk_in)
129   begin
130     if (rising_edge(clk_in)) then
131       case cnt is
132       when 0|3|6 =>
133         if cnt1 < 1 then
134           cnt1 <= cnt1 + 1;
135         else
136           cnt1 <= 0;
137         end if;
138 
139         if ( cnt1 < 1 ) then
140           clkoutQ <= '1';
141         else
142           clkoutQ <= '0';
143         end if;
144 
145       when others =>
146         if ( cnt2 < 2 ) then
147           cnt2 <= cnt2 + 1;
148         else
149           cnt2 <= 0;
150         end if;
151 
152         if ( cnt2 < 1 ) then
153           clkoutQ <= '1';
154         else
155           clkoutQ <= '0';
156         end if;
157 
158       end case;
159     end if;
160 
161   end process;
162 
163 end b;
164 
165 configuration cfg of clk_div6 is
166   for a
167   end for;
168 end cfg;
  1 -- 分数分频器 M + L/N : 2 + 7/13 : 33/6
  2 --
  3 -- 共计 13次分频 : 7次     3分频 +    6 次 2分频
  4 -- 共计 N 次分频 : L次 (M+1)分频 + (N-L)次 M分频
  5 
  6 -- 平均分布 : 分子累加, 小于分母的, 进行M分频, 大于等于 分母的, 进行 M+1 分频
  7 --
  8 -- Index  0       1     2     3     4     5     6     7     8     9    10   11    12
  9 -- Count  7      14    21    28    35    42    49    56    63    70    83   96    103
 10 --
 11 -- Count  7      14    8     15     9    16    10    17    11    18    12   19    13
 12 --
 13 -- Div    2       3     3     2     3     3     2     3     3     3
 14 --
 15 
 16 library IEEE;
 17 use IEEE.STD_LOGIC_1164.ALL;
 18 use IEEE.STD_LOGIC_ARITH.ALL;
 19 use IEEE.STD_LOGIC_UNSIGNED.ALL;
 20 
 21 entity clk_div7 is
 22   port ( clk_in : in std_logic;
 23     clk_out : out std_logic);
 24 end clk_div7;
 25 
 26 -- 实时计算结果
 27 architecture a of clk_div7 is
 28   signal ctrl    : std_logic;
 29 
 30   signal clkoutQ : std_logic;
 31 
 32   signal cnt1 : integer range 0 to 1;   -- 分频 整数部分  : 整数-1
 33   signal cnt2 : integer range 0 to 2;   -- 分频 整数部分+1 : 整数
 34 
 35 begin
 36   clk_out <= clkoutQ;
 37 
 38   process(clkoutQ)
 39     variable tmp : integer range 0 to 26;    -- 分母*2
 40   begin
 41     if (rising_edge(clkoutQ)) then
 42       tmp := tmp + 7;                   -- 分子
 43       if ( tmp < 13 ) then              -- 分母
 44         ctrl <= '1';
 45       else
 46         ctrl <= '0';
 47         tmp := tmp - 13;                -- 分母
 48       end if;
 49     end if;
 50   end process;
 51 
 52   process(clk_in)
 53   begin
 54     if (rising_edge(clk_in)) then
 55       if ( ctrl = '1' ) then
 56 
 57         if ( cnt1 < 1 ) then
 58           cnt1 <= cnt1 + 1;
 59         else
 60           cnt1 <= 0;
 61         end if;
 62 
 63         if ( cnt1 < 1 ) then
 64           clkoutQ <= '1';
 65         else
 66           clkoutQ <= '0';
 67         end if;
 68 
 69       else
 70         if ( cnt2 < 2 ) then
 71           cnt2 <= cnt2 + 1;
 72         else
 73           cnt2 <= 0;
 74         end if;
 75 
 76         if ( cnt2 < 1 ) then
 77           clkoutQ <= '1';
 78         else
 79           clkoutQ <= '0';
 80         end if;
 81 
 82       end if;
 83     end if;
 84   end process;
 85 
 86 end a;
 87 
 88 -- 实现计算结果
 89 architecture b of clk_div6 is
 90   signal cnt : integer range 0 to 12;   -- 分母-1
 91 
 92   signal clkoutQ : std_logic;
 93 
 94   signal cnt1 : integer range 0 to 1;   -- 分频 整数部分  : 整数-1
 95   signal cnt2 : integer range 0 to 2;   -- 分频 整数部分+1 : 整数
 96 
 97 begin
 98   clk_out <= clkoutQ;
 99 
100   process(clkoutQ)
101   begin
102     if (rising_edge(clkoutQ)) then
103       if ( cnt < 12 ) then              -- 分母-1
104         cnt <= cnt + 1;
105       else
106         cnt <= 0;
107       end if;
108     end if;
109   end process;
110 
111   process(clk_in)
112   begin
113     if (rising_edge(clk_in)) then
114       case cnt is
115       when 0|2|4|6|8|10 =>
116         if cnt1 < 1 then
117           cnt1 <= cnt1 + 1;
118         else
119           cnt1 <= 0;
120         end if;
121 
122         if ( cnt1 < 1 ) then
123           clkoutQ <= '1';
124         else
125           clkoutQ <= '0';
126         end if;
127 
128       when others =>
129         if ( cnt2 < 2 ) then
130           cnt2 <= cnt2 + 1;
131         else
132           cnt2 <= 0;
133         end if;
134 
135         if ( cnt2 < 1 ) then
136           clkoutQ <= '1';
137         else
138           clkoutQ <= '0';
139         end if;
140 
141             end case;
142         end if;
143   end process;
144 
145 end b;
146 
147 configuration cfg of clk_div7 is
148   for a
149   end for;
150 end cfg;
 1 -- 积分法分频 8/3
 2 library IEEE;
 3 use IEEE.STD_LOGIC_1164.ALL;
 4 use IEEE.STD_LOGIC_ARITH.ALL;
 5 use IEEE.STD_LOGIC_UNSIGNED.ALL;
 6 
 7 entity clk_div8 is
 8   port ( clk_in : in std_logic;
 9     clk_out : out std_logic);
10 end clk_div8;
11 
12 architecture a of clk_div8 is
13   signal cnt : std_logic_vector ( 3 downto 0 ) := ( others => '0');
14   signal dly : std_logic;
15 begin
16   process(clk_in)
17   begin
18     if (rising_edge(clk_in)) then
19       dly <= cnt(3);
20       cnt <= cnt + 3;
21     end if;
22   end process;
23 
24   clk_out <= dly xor cnt(3);
25 
26 end a;
 1 -- 积分法分频 fpga4fun.com
 2 --
 3 -- 1024/59
 4 --
 5 library IEEE;
 6 use IEEE.STD_LOGIC_1164.ALL;
 7 use IEEE.STD_LOGIC_ARITH.ALL;
 8 use IEEE.STD_LOGIC_UNSIGNED.ALL;
 9 
10 entity clk_div8a is
11   port ( clk_in : in std_logic;
12     clk_out : out std_logic);
13 end clk_div8a;
14 
15 architecture a of clk_div8a is
16   signal cnt : std_logic_vector ( 10 downto 0 ) := ( others => '0' );   -- 2 ** MSB = 1024 : MSB=10
17   signal dly : std_logic;
18 begin
19   process(clk_in)
20   begin
21     if (rising_edge(clk_in)) then
22       dly <= cnt(10);                                                   -- MSB
23       cnt <= cnt + 59;                                                  -- 1024 / N : N=59
24     end if;
25   end process;
26 
27   clk_out <= dly xor cnt(10);
28 
29 end a;
 1 -- fpga4fun.com baud generator 分频
 2 --
 3 -- 1024/59
 4 --
 5 
 6 library IEEE;
 7 use IEEE.STD_LOGIC_1164.ALL;
 8 use IEEE.STD_LOGIC_ARITH.ALL;
 9 use IEEE.STD_LOGIC_UNSIGNED.ALL;
10 
11 entity clk_div9 is
12   port ( clk_in : in std_logic;
13     clk_out : out std_logic);
14 end clk_div9;
15 
16 architecture a of clk_div9 is
17   -- 10 bits for the accumulator ([9:0]),
18   -- and one extra bit for the accumulator carry-out ([10])
19   -- 11 bits total !
20   signal cnt : std_logic_vector ( 10 downto 0 ) := ( others => '0' );   -- 2 ** MSB = 1024 : MSB=10
21 begin
22   process(clk_in)
23   begin
24     if (rising_edge(clk_in)) then
25       -- use only 10 bits from the previous result, but save the full 11 bits
26       cnt <= ( '0' & cnt(9 downto 0) )  + 59;
27     end if;
28   end process;
29 
30   -- so that the 11th bit is the carry-out
31   clk_out <= cnt(10);
32 
33 end a;
posted @ 2012-05-10 20:01  IAmAProgrammer  阅读(1642)  评论(0编辑  收藏  举报