?? div.txt
字號:
分頻器是FPGA設(shè)計中使用頻率非常高的基本單元之一。盡管目前在大部分設(shè)計中還廣泛使用集成鎖相環(huán)(如altera的PLL,Xilinx的DLL)來進行時鐘的分頻、倍頻以及相移設(shè)計,但是,對于時鐘要求不太嚴格的設(shè)計,通過自主設(shè)計進行時鐘分頻的實現(xiàn)方法仍然非常流行。首先這種方法可以節(jié)省鎖相環(huán)資源,再者,這種方式只消耗不多的邏輯單元就可以達到對時鐘操作的目的。
偶數(shù)倍分頻:偶數(shù)倍分頻應(yīng)該是大家都比較熟悉的分頻,通過計數(shù)器計數(shù)是完全可以實現(xiàn)的。如進行N倍偶數(shù)分頻,那么可以通過由待分頻的時鐘觸發(fā)計數(shù)器計數(shù),當計數(shù)器從0計數(shù)到N/2-1時,輸出時鐘進行翻轉(zhuǎn),并給計數(shù)器一個復(fù)位信號,使得下一個時鐘從零開始計數(shù)。以此循環(huán)下去。這種方法可以實現(xiàn)任意的偶數(shù)分頻。
module odd_division(clk,rst,count,clk_odd); /*count沒必要放在端口中,這里只是為了仿真時觀察*/
input clk,rst;
output clk_odd;
output[3:0] count;
reg clk_odd;
reg[3:0] count;
parameter N = 6; /*6分頻* /
always @ (posedge clk)
if(! rst)
begin
count <= 1'b0;
clk_odd <= 1'b0;
end
else
if ( count < N/2-1)
begin
count <= count + 1'b1;
end
else
begin
count <= 1'b0;
clk_odd <= ~clk_odd;
end
endmodule
奇數(shù)倍分頻:歸類為一般的方法為:對于實現(xiàn)占空比為50%的N倍奇數(shù)分頻,首先進行上升沿觸發(fā)進行模N計數(shù),計數(shù)從零開始,到N-1)/2進行輸出時鐘翻轉(zhuǎn),然后經(jīng)過(N-1)/2再次進行翻轉(zhuǎn)得到一個占空比非50%奇數(shù)n分頻時鐘。再者同時進行下降沿觸發(fā)的模N計數(shù),到和上升沿過(N-1)/2時,輸出時鐘再次翻轉(zhuǎn)生成占空比非50%的奇數(shù)n分頻時鐘。兩個占空比非50%的n分頻時鐘相或運算,得到占空比為50%的奇數(shù)n分頻時鐘。
module even_division(clk,rst,count1,count2,clk_even); /*count1,count2沒必要放在端口中,這里只是為了仿真時觀察*/
input clk,rst;
output[3:0] count1,count2;
output clk_even;
reg[3:0] count1,count2;
reg clkA,clkB;
wire clk_even,clk_re;
parameter N = 5; /*5分頻*/
assign clk_re = ~clk;
assign clk_even = clkA | clkB;
always @(posedge clk)
if(! rst)
begin
count1 <= 1'b0;
clkA <= 1'b0;
end
else
if(count1 < (N - 1))
begin
count1 <= count1 + 1'b1; /*這里是阻塞賦值是先執(zhí)行了下面的IF判斷,最后才賦的值。最初看這程序時沒注意,想了好半天*/
if(count1 == (N - 1)/2)
begin
clkA <= ~clkA;
end
end
else
begin
clkA <= ~clkA;
count1 <= 1'b0;
end
always @ (posedge clk_re)
if(! rst)
begin
count2 <= 1'b0;
clkB <= 1'b0;
end
else
if(count2 < (N - 1))
begin
count2 <= count2 + 1'b1;
if(count2 == (N - 1)/2)
begin
clkB <= ~clkB;
end
end
else
begin
clkB <= ~clkB;
count2 <= 1'b0;
end
endmodule
在源代碼中完成對時鐘信號CLK的2分頻,4分頻,8分頻,16分頻。
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY clkdiv IS
PORT(clk : IN STD_LOGIC;
clk_div2 : OUT STD_LOGIC;
clk_div4 : OUT STD_LOGIC;
clk_div8 : OUT STD_LOGIC;
clk_div16 : OUT STD_LOGIC);
END clk_div;
ARCHITECTURE rtl OF clk_div IS
SIGNAL count : STD_LOGIC_VECTOR(3 DOWNTO 0);
BEGIN
PROCESS(clk)
BEGIN
IF (clk’event AND clk=’1’) THEN
IF(count=”1111”) THEN
Count <= (OTHERS =>’0’);
ELSE
Count <= count +1;
END IF ;
END IF ;
END PROCESS;
clk_div2 <= count(0);
clk_div4 <= count(1);
clk_div8 <= count(2);
clk_div16 <= count(3);
END rtl;
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -