基於VHDL語言分頻器電路程序設計

基於VHDL語言分頻器電路程序設計(彙總)

分頻器簡介:

分頻器是數字電路中最常用的電路之一,在 FPGA 的設計中也是使用效率非常高的基本設計。基於 FPGA 實現的分頻電路一般有兩種方法:一是使用FPGA 芯片內部提供的鎖相環電路,如 ALTERA 提供的 PLL(Phase Locked

Loop),Xilinx 提供的 DLL(Delay Locked Loop);二是使用硬件描述語言,如VHDL、Verilog HDL 等。使用鎖相環電路有許多優點,如可以實現倍頻;相位偏移;佔空比可調等。但 FPGA 提供的鎖相環個數極爲有限,不能滿足使用要求。因此使用硬件描述語言實現分頻電路經常使用在數字電路設計中,消耗不多的邏輯單元就可以實現對時鐘的操作,具有成本低、可編程等優點。

計數器

計數器是實現分頻電路的基礎,計數器有普通計數器和約翰遜計數器兩種。這兩種計數器均可應用在分頻電路中。

  • 普通計數器: 最普通的計數器是加法(或減法)計數器。
  • 約翰遜計數器: 約翰遜計數器是一種移位計數器,採用的是把輸出的最高位取非,然後反饋送到最低位觸發器的輸入端。約翰遜計數器在每個時鐘下只有一個輸出發生變化。

分頻器

如前所述,分頻器的基礎是計數器,設計分頻器的關鍵在於輸出電平翻轉的時機。下面使用加法計數器分別描述各種分頻器的實現。

  • 偶數分頻器:偶數分頻最易於實現,欲實現佔空比爲 50%的偶數 N 分頻,一般來說有兩種方案:一是當計數器計數到N/2-1 時,將輸出電平進行一次翻轉,同時給計數器一個復位信號,如此循環下去;二是當計數器輸出爲 0 到 N/2-1 時,時鐘輸出爲 0 或 1,計數器輸出爲 N/2 到 N-1 時,時鐘輸出爲 1 或 0,當計數器計數到N-1 時,復位計數器,如此循環下去。需要說明的是,第一種方案僅僅能實現佔空比爲 50%的分頻器,第二種方案可以有限度的調整佔空比,參考非 50%佔空比的奇數分頻實現。
  • 奇數分頻器:實現非50%佔空比的奇數分頻,如實現佔空比爲 20%(1/5)、40%(2/5)、60%(3/5)、80%(4/5)的 5 分頻器,可以採用似偶數分頻的第二種方案;但如果實現佔空比爲 50%的奇數分頻,就不能使用偶數分頻中所採用的方案了。
  • 半整數分頻器:僅僅採用數字分頻,不可能獲得佔空比爲 50%的 N+0.5 分頻,我們只可以設計出佔空比爲(M+0.5)/(N+0.5)或者 M/(N+0.5)的分頻器,M 小於 N。這種半整數分頻方法是對輸入時鐘進行操作,讓計數器計數到某一個數值時,將輸入時鐘電平進行一次反轉,這樣,該計數值只保持了半個時鐘週期,因此實現半整數分頻。
  • 小數分頻器:小數分頻是通過可變分頻和多次平均的方法實現的。例如要實現 4.7 分頻,只要在 10 次分頻中,做 7 次 5 分頻,3 次 4 分頻就可以得到。再如要實現 5.67 分頻,只要在 100 次分頻中,做 67 次6 分頻,33 次 5 分頻即可。考慮到小數分頻器要進行多次兩種頻率的分頻,必須設法將兩種分頻均勻。
  • 分數分頻器:將小數分頻的方法進行擴展,可以得到形如M (L/N )的分數分頻的方法,例如, 2(7/13)等於分母的,進行分頻,只要在 13 次分頻中,進行 7 次 3 分頻,6 次 2 分頻就可以得到。同樣,爲了將兩種分頻均勻,將分子部分累加,小於分母的,進行M分頻,大於(M+1)分頻。
  • 積分分頻器:積分分頻器用於實現形如 2m1/N2^{m-1}/N的分頻,例如 8/3 分頻。我們當然可以使用上面提到的分數分頻的方法,但對於這種形式的分頻,使用積分分頻的方法綜合往往佔用更少的 FPGA 資源。積分分頻法基於下述原理:一個 m 位的二進制數字每次累加 N,假定累加x 次累加值最低m 位回到 0,同時越過 2my2^my 次,那麼,當前累加的數字應該是Nx= 2my2^my;每越過 2m2^m一次,最高位變化 2 次,所以,累加 x 次,最高位變化 2y次,得到x/2y=2m1/Nx/2y=2^{m-1}/N分頻的分頻器例如,取 m 爲 4,N 爲 3,當累加 16 次時,累加值爲 48,最低 m 位變回到 0,同時越過 16 三次,最高位變化 6 次,由此得到 16/6=8/3 分頻的分頻器。

注意: 以上分頻器程序設計的案例將會在下邊進行一一分析。

軟件說明: ModelSimSetup-13.1.0.162,QuartusSetup-13.1.0.162。

建立工程:

第一步:打開Quartus軟件。

第二步:點擊New Project Wizard -> next.

第三步:選擇工程文件的存放位置,輸入工程名 -> next -> next。

第四步:在family欄選擇芯片型號-Cyclone IV E,在Name欄選擇EP4CE115F29C7,選擇完之後點擊next。(如果不進行硬件調試時,此處默認即可)

第五步:檢查工程有沒有建錯,點擊完成。如下圖:

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-JAvIBjAI-1592033868964)(G:\研究生\FPGA課程\筆記文檔\rec\20161122122950778.png)]

程序設計:

普通計數器:
--文件名:ADDER8B.vhd 應與工程名保持一致:
--Description: 帶復位功能的加法計數器
library ieee;
use ieee.std_logic_1164.all; 
use ieee.std_logic_arith.all; 
use ieee.std_logic_unsigned.all; 
entity ripple is
 generic (width: integer := 4); 
 port(clk, rst: in std_logic; 
 cnt: out std_logic_vector(width - 1 downto 0)); 
end ripple; 
architecture a of ripple is
 signal cntQ: std_logic_vector(width - 1 downto 0); 
begin 
	 process(clk, rst) 
	 begin 
	 if (rst = '1') then
		 cntQ <= (others => '0'); 
	 elsif (clk'event and clk = '1') then
		 cntQ <= cntQ + 1;
	 end if; 
	 end process; 
 cnt <= cntQ; 
end a;

在同一時刻,加法計數器的輸出可能有多位發生變化,因此,當使用組合邏輯對輸出進行譯碼時,會導致尖峯脈衝信號。使用約翰遜計數器可以避免這個問題。

文件仿真(這裏採用modelsim仿真波形):
  1. 選擇File-> New -> Verification/Debugging Files ->University Program VWF。

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-hIScEXtC-1592033868968)(G:\研究生\FPGA課程\筆記文檔\rec\QQ截圖20200423165155.png)]

2.打開測試文件。(右鍵點擊添加端口,對輸入信號初始化,賦值。)

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-D7l1kkjK-1592033868970)(G:\研究生\FPGA課程\筆記文檔\rec\截圖20200612183621.png)]

3.仿真結果:

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-xsubDOQn-1592033868976)(G:\研究生\FPGA課程\筆記文檔\rec\截圖20200612183335.png)]

邏輯電路圖:

顯示編譯成功後,選擇菜單欄 Tools –>Netlist Viewers  –>RTL Viewer 顯示邏輯電路圖[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-9wdym7zZ-1592033868980)(G:\研究生\FPGA課程\筆記文檔\rec\截圖20200612181245.png)]

約翰遜計數器:
--file Name: johnson.vhd 
--Description: 帶復位功能的約翰遜計數器
library ieee; 
use ieee.std_logic_1164.all; 
use ieee.std_logic_arith.all; 
use ieee.std_logic_unsigned.all; 
entity johnson is
 generic (width: integer := 4); 
 port (clk, rst: in std_logic; 
 cnt: out std_logic_vector(width - 1 downto 0)); 
end johnson; 
architecture a of johnson is
 signal cntQ: std_logic_vector(width - 1 downto 0); 
begin 
 process(clk, rst) 
 begin 
 if(rst = '1') then
 cntQ <= (others => '0'); 
 elsif (rising_edge(clk)) then
 cntQ(width - 1 downto 1) <= cntQ(width - 2 downto 0); 
 cntQ(0) <= not cntQ(width - 1); 
 end if; 
 end process;
   cnt <= cntQ; 
end a;

邏輯電路圖:

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-kV4PDTgw-1592033868982)(G:\研究生\FPGA課程\筆記文檔\rec\截圖20200612184615.png)]

仿真結果:

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-riiRRVV3-1592033868983)(G:\研究生\FPGA課程\筆記文檔\rec\截圖20200612185535.png)]

顯然,約翰遜計數器沒有有效利用寄存器的所有狀態,假設最初值或復位狀態爲0000,則依次爲 0000、0001、0011、0111、1111、1110、1100、1000、0000 如 循環。再者,如果由於干擾噪聲引入一個無效狀態,如 0010,則無法恢復到有效到循環中去,需要我們加入錯誤恢復處理.

偶數分頻器:(6 分頻)

architecture a 使用的是第一種方案,architecture b 使用的是第二種方案。更改 configuration 可查看不同方案的綜合結果。

--filename clk_div6.vhd
--description: 佔空比爲 50%的 6 分頻 
library ieee; 
use ieee.std_logic_1164.all; 
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all; 
entity clk_div6 is
 port(clk_in: in std_logic; clk_out: out std_logic);
end clk_div6; 
--使用第一種方案
architecture a of clk_div6 is
	 signal clk_outQ: std_logic := '0';--賦初始值僅供仿真使用
	 signal countQ: std_logic_vector(2 downto 0) := "000"; 
	 begin 
		 process(clk_in) 
		 begin 
		 if(clk_in'event and clk_in = '1') then
			 if(countQ /= 2) then 
				 CountQ <= CountQ + 1; 
			 else 
				 clk_outQ <= not clk_outQ; 
				 CountQ <= (others =>'0'); 
			 end if; 
		 end if; 
		 end process; 
	 clk_out <= clk_outQ;
end a; 
--使用第二種方案
architecture b of clk_div6 is
	 signal countQ: std_logic_vector(2 downto 0);
	 begin 
		 process(clk_in) 
		 begin 
			 if(clk_in'event and clk_in = '1') then
				 if(countQ < 5) then
					 countQ <= countQ + 1; 
				 else 
					 CountQ <= (others =>'0'); 
				 end if; 
			 end if; 
		 end process; 
		 process(countQ) 
		 begin 
				 if(countQ < 3) then
					 clk_out <= '0'; 
				 else 
					 clk_out <= '1';
				end if; 
		 end process; 
 end b;
     
configuration cfg of clk_div6 is
 for a 
 end for; 
end cfg;

邏輯電路圖:

architecture a:

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-ESVyd5Ae-1592033868985)(G:\研究生\FPGA課程\筆記文檔\rec\截圖20200612192249.png)]

architecture b:

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-oDh4ZwB0-1592033868986)(G:\研究生\FPGA課程\筆記文檔\rec\截圖20200612193435.png)]

仿真結果:

architecture a、b:

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-aweAL1EG-1592033868987)(G:\研究生\FPGA課程\筆記文檔\rec\截圖20200612192655.png)]

奇數分頻器:

非 50%佔空比:

下面就以實現佔空比爲40%的 5 分頻分頻器爲例,說明非 50%佔空比的奇數分頻器的實現。該分頻器的實現對於我們實現 50%佔空比的分頻器有一定的借鑑意義。

--filename clk_div5.vhd
--description: 佔空比爲 40%的 5 分頻
library ieee; 
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all; 
use ieee.std_logic_unsigned.all;
entity clk_div5 is
 port(clk_in: in std_logic; clk_out: out std_logic);
end clk_div5;
architecture a of clk_div5 is
   signal countQ: std_logic_vector(2 downto 0);
	begin 
	 process(clk_in) 
	 begin
		if(clk_in'event and clk_in = '1') then
			if(countQ < 4) then
				 countQ <= countQ + 1; 
			 else 
				 CountQ <= (others =>'0'); 
			 end if; 
		end if; 
	 end process; 
		process(countQ) 
		 begin 
			 if(countQ < 3) then
				 clk_out <= '0'; 
			 else 
				 clk_out <= '1'; 
			 end if; 
	 end process; 
end a;

邏輯電路圖:

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-gTQmg5gH-1592033868989)(G:\研究生\FPGA課程\筆記文檔\rec\截圖20200612221125.png)]

仿真結果:

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-PGse4UHD-1592033868990)(G:\研究生\FPGA課程\筆記文檔\rec\截圖20200612221101.png)]

50%佔空比的奇數分頻:

通過待分頻時鐘下降沿觸發計數,產生一個佔空比爲40%(2/5)的 5 分頻器。將產生的時鐘與上升沿觸發產生的時鐘相或,即可得到一個佔空比 50%的 5 分頻器。

推廣爲一般方法:欲實現佔空比爲 50%的 2N+1 分頻器,則需要對待分頻時鐘上升沿和下降沿分別進行N/(2N+1)分頻,然後將兩個分頻所得的時鐘信號相或得到佔空比爲 50%的 2N+1 分頻器。

下面的代碼就是利用上述思想獲得佔空比爲 50%的 7 分頻器。需要我們分別對上升沿和下降沿進行 3/7 分頻,再將分頻獲得的信號相或。

--filename clk_div7.vhd 
--description: 佔空比爲 50%的 7 分頻
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity clk_div7 is
	port(clk_in: in std_logic; clk_out: out std_logic);
end clk_div7;

architecture a of clk_div7 is 
	 signal cnt1, cnt2: integer range 0 to 6; 
	 signal clk1,clk2: std_logic;
	 begin 
		 process(clk_in)--上升沿
			begin 
			 if(rising_edge(clk_in)) then
				 if(cnt1 < 6)then
					cnt1 <= cnt1 + 1;
				 else 
				   cnt1 <= 0; 
				 end if;
				 if(cnt1 < 3) then
					 clk1 <= '1';
				 else
					clk1 <= '0';
				 end if; 
			 end if;
		 end process;
		 process(clk_in)--下降沿
			begin 
				 if(falling_edge(clk_in)) then
					if(cnt2 < 6) then
						 cnt2 <= cnt2 + 1;
					 else 
						 cnt2 <= 0; 
					 end if;
					 if(cnt2 < 3) then
						 clk2 <= '1';
					 else 
						 clk2 <= '0'; 
					 end if; 
				  end if; 
		 end process;
	clk_out <= clk1 or clk2;
end a;

邏輯電路圖:

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-8sXSHOT6-1592033868991)(G:\研究生\FPGA課程\筆記文檔\rec\截圖20200612223407.png)]

仿真結果:

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-HTT4cUUW-1592033868993)(G:\研究生\FPGA課程\筆記文檔\rec\截圖20200612223628.png)]

半整數分頻器:

如上所述,佔空比爲 50%的奇數分頻可以幫助我們實現半整數分頻,將佔空比爲50%的奇數分頻與待分頻時鐘異或得到計數脈衝,下面的代碼就是依靠佔空比爲 50%的 5 分頻實現 2.5 分頻器的。

--filename clk_div2_5.vhd 
--description: 佔空比爲 1/1.5,即 60%。的 2.5分頻
library ieee; 
use ieee.std_logic_1164.all; 
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;

entity clk_div2_5 is
	  port(clk_in: in std_logic; clk_out: out std_logic);
end clk_div2_5; 

architecture a of clk_div2_5 is
  signal cnt1, cnt2: integer range 0 to 4;
  signal clk1, clk2: std_logic;
  signal Pclk, Lclk: std_logic;
  signal cnt3:integer range 0 to 2;
begin 
	 process(clk_in) 
		 begin 
			 if(rising_edge(clk_in)) then
				 if(cnt1 < 4) then
					 cnt1 <= cnt1 + 1; 
				 else 
					 cnt1 <= 0; 
				 end if; 
			 end if; 
	 end process;
	 process(clk_in) 
		 begin 
			 if(falling_edge(clk_in)) then 
					if(cnt2 <4)  then
						 cnt2 <= cnt2 + 1;
					else 
						 cnt2 <= 0; 
					end if; 
			 end if; 
	 end process;
	 process(cnt1) 
		 begin 
			 if (cnt1 <3) then
				clk1 <= '0';
			 else 
				 clk1 <= '1';
			 end if; 
	 end process;
	 process(cnt2) 
		 begin 
			 if (cnt2 < 3) then
				 clk2 <= '0';
			 else 
				 clk2 <= '1';
			 end if; 
	 end process;
   
	 process(Lclk) 
	 begin
		if(rising_edge(Lclk)) then
			 if(cnt3 < 2) then
				cnt3 <= cnt3 + 1;
		    else
			   cnt3 <= 0;
		    end if;
		end if;
	 end process;    
	 process(cnt3) 
		 begin 
		 if(cnt3 < 2) then
			 clk_out <= '0';
		 else 
			 clk_out <='1';
		 end if; 
	 end process;    
	 Pclk <= clk1 or clk2;
	 Lclk <= clk_in xor Pclk;--對輸入時鐘進行處理
end a;        

仿真結果:

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-hsxxu81n-1592033868994)(G:\研究生\FPGA課程\筆記文檔\rec\截圖20200612231446.png)]

小數分頻器:

表 1以 2.7 分頻爲例,小數部分進行累加,如果大於等於10,則進行 3 分頻,如果小於 10,進行

2 分頻。

表一:小數分頻係數序列

序號 0 1 2 3 4 5 6 7 8 9
累加值 7 14 11 8 15 12 9 16 13 10
分頻 係數 2 3 3 2 3 3 2 3 3 3

下加器面的代碼就是基於上述原理實現 2.7 分頻。architecture b 是使用累加器計算分頻係數選則時機, chitectur a 是直接使用已計算好的結果。

--file name: clk_div2_7.vhd
--description: 2.7 分頻 ,佔空比應爲 10/27。
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity clk_div2_7 is
	  port(clk_in: in std_logic; clk_out: out std_logic);
end clk_div2_7;
architecture b of clk_div2_7 is
 signal clkoutQ: std_logic; 
 signal ctrl: std_logic; 
 signal cnt1: integer range 0  to 1;
 signal cnt2: integer range 0  to 2;
begin 
	 clk_out <= clkoutQ; 
	 process(clkoutQ) 
		variable tmp: integer range 0 to 20;
		begin 
			 if(rising_edge(clkoutQ)) then
					tmp := tmp + 7; 
				 if(tmp < 10) then
						ctrl <= '1'; 
				 else 
						ctrl <= '0';
						tmp := tmp - 10;
				 end if; 
			 end if; 
	 end process;
		 
	 process(clk_in) 
		 begin 
			 if(clk_in'event and clk_in = '1') then
				 if(ctrl = '1') then
					 if(cnt1 < 1) then
						  cnt1 <= cnt1 + 1;
					 else
						  cnt1 <= 0; 
					 end if; 
					 if(cnt1 < 1) then
					     clkoutQ <= '1'; 
					 else 
						  clkoutQ <= '0'; 
					 end if; 
				 else 
					 if(cnt2 < 2) then
							cnt2 <= cnt2 + 1;
					 else 
							cnt2 <= 0; 
					 end if; 
				 if(cnt2 < 1) then
					 clkoutQ <= '1';
				 else 
					 clkoutQ <= '0'; 
				 end if; 
				 end if;
			  end if; 
	 end process;
 end b;
 architecture a of clk_div2_7 is
	 signal cnt: integer range 0 to 9;
	 signal clkoutQ: std_logic;
	 signal cnt1: integer range 0 to 1;
	 signal cnt2: integer range 0 to 2;
	begin 
		clk_out <= clkoutQ;
		process(clkOutQ)
		  begin 
			 if(clkoutQ'event and clkoutQ = '1') then
					if (cnt < 9) then
					    cnt <= cnt + 1; 
					else 
					    cnt <= 0; 
					end if; 
			 end if; 
		end process;
		process(clk_in) 
		  begin 
			 if(clk_in'event and clk_in = '1') then
				 case cnt is
					  when 0|3|6 =>
						  if(cnt1 < 1) then
							   cnt1 <= cnt1 + 1;
						  else
							   cnt1 <= 0;
						  end if; 
						  if(cnt1 < 1) then
								clkoutQ <= '1';
						  else 
								clkoutQ <='0';
						  end if; 
					  when others =>
						  if(cnt2 < 2) then
							  cnt2 <= cnt2 + 1;
						  else 
						     cnt2 <= 0; 
						 end if; 
						 if(cnt2 < 1) then
						     clkoutQ <= '1'; 
						 else 
						     clkoutQ <= '0';
						 end if; 
				 end case; 
			 end if; 
		 end process; 
 end a; 
   
configuration cfg of clk_div2_7 is
	 for a 
	 end for; 
end cfg;

仿真結果:

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-dVTcxP47-1592033868995)(G:\研究生\FPGA課程\筆記文檔\rec\截圖20200613144632.png)]

分數分頻器:

表 2顯示了 2(7/13)的分頻次序。仿照小數分頻器代碼,給出 2(7/13) 分頻的代碼如下:

表 2 分數分頻係數序列

序號 0 1 2 3 4 5 6 7 8 9 10 11 12
累加值 7 14 8 15 9 16 10 17 11 18 12 19 13
分頻 係數 2 3 2 3 2 3 2 3 2 3 2 3 3
--file name: clk_div2_7_13.vhd
--description: 33/13分頻
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity clk_div2_7 is
	  port(clk_in: in std_logic; clk_out: out std_logic);
end clk_div2_7;
architecture b of clk_div2_7 is
 signal clkoutQ: std_logic; 
 signal ctrl: std_logic; 
 signal cnt1: integer range 0  to 1;
 signal cnt2: integer range 0  to 2;
begin 
	 clk_out <= clkoutQ; 
	 process(clkoutQ) 
		variable tmp: integer range 0 to 26;
		begin 
			 if(rising_edge(clkoutQ)) then
					tmp := tmp + 7; 
				 if(tmp < 10) then
						ctrl <= '1'; 
				 else 
						ctrl <= '0';
						tmp := tmp - 13;
				 end if; 
			 end if; 
	 end process;
		 
	 process(clk_in) 
		 begin 
			 if(clk_in'event and clk_in = '1') then
				 if(ctrl = '1') then
					 if(cnt1 < 1) then
						  cnt1 <= cnt1 + 1;
					 else
						  cnt1 <= 0; 
					 end if; 
					 if(cnt1 < 1) then
					     clkoutQ <= '1'; 
					 else 
						  clkoutQ <= '0'; 
					 end if; 
				 else 
					 if(cnt2 < 2) then
							cnt2 <= cnt2 + 1;
					 else 
							cnt2 <= 0; 
					 end if; 
				 if(cnt2 < 1) then
					 clkoutQ <= '1';
				 else 
					 clkoutQ <= '0'; 
				 end if; 
				 end if;
			  end if; 
	 end process;
 end b;
 architecture a of clk_div2_7 is
	 signal cnt: integer range 0 to 12;
	 signal clkoutQ: std_logic;
	 signal cnt1: integer range 0 to 1;
	 signal cnt2: integer range 0 to 2;
	begin 
		clk_out <= clkoutQ;
		process(clkOutQ)
		  begin 
			 if(clkoutQ'event and clkoutQ = '1') then
					if (cnt < 9) then
					    cnt <= cnt + 1; 
					else 
					    cnt <= 0; 
					end if; 
			 end if; 
		end process;
		process(clk_in) 
		  begin 
			 if(clk_in'event and clk_in = '1') then
				 case cnt is
					  when 0|2|4|6|8|10 =>
						  if(cnt1 < 1) then
							   cnt1 <= cnt1 + 1;
						  else
							   cnt1 <= 0;
						  end if; 
						  if(cnt1 < 1) then
								clkoutQ <= '1';
						  else 
								clkoutQ <='0';
						  end if; 
					  when others =>
						  if(cnt2 < 2) then
							  cnt2 <= cnt2 + 1;
						  else 
						     cnt2 <= 0; 
						 end if; 
						 if(cnt2 < 1) then
						     clkoutQ <= '1'; 
						 else 
						     clkoutQ <= '0';
						 end if; 
				 end case; 
			 end if; 
		 end process; 
 end a; 
   
configuration cfg of clk_div2_7 is
	 for b
	 end for; 
end cfg;

仿真結果:

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-KfWgmGn7-1592033868997)(G:\研究生\FPGA課程\筆記文檔\rec\截圖20200613151638.png)]

積分分頻器:

例如,取 m 爲 4,N 爲 3,當累加 16 次時,累加值爲 48,最低 m 位變回到 0,同時越過 16 三次,最高位變化 6 次,由此得到 16/6=8/3 分頻的分頻器。

--file name: clk_div8.vhd 
--description: 使用積分分頻實現 8/3 分頻
library ieee; 
use ieee.std_logic_1164.all; 
use ieee.std_logic_unsigned.all;
entity clk_div_8f3 is
  port(clk_in: in std_logic; clk_out: out std_logic);
end clk_div_8f3;
architecture a of clk_div_8f3 is
	  signal cnt: std_logic_vector(3 downto 0) := (others => '0');
	  signal dly: std_logic;
	  begin 
		 process(clk_in)
		  begin 
		 if(clk_in'event and clk_in = '1') then
				 dly <= cnt(3);
				 cnt <= cnt + 3;
		  end if; 
		 end process;
	  clk_out <= dly xor cnt(3);
 end a;

仿真結果:

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-ukv4ZkHL-1592033868998)(G:\研究生\FPGA課程\筆記文檔\rec\截圖20200613153422.png)]

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章