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;