在時鐘分頻技術中,對于偶數倍分頻是比較好做的,實作2N倍的分頻,隻需計數到N,然後讓時鐘進行翻轉即可。
但是在奇數倍分頻中,我們總會面0.5的關系。例如實作5倍分頻,也就是計數到2.5,然後時鐘進行翻轉。可是2.5是沒有辦法計數的。是以我們就得另尋它法了。
假如我們有兩個時鐘,clk1和clk2。如果時鐘clk1的高電平持續2個周期,而clk2的低電平持續3個時鐘周期,并且兩者的時間錯開半個周期,将兩者進行或運算就ok了。
如下圖所示:

其實主要的算法就是在不同的時鐘沿進行技術,目的就是為了找到那半個周期。
需要有兩個計數器cnt1和cnt2:如果是5分頻則:cnt1=5/2=2(從0到2共3個clk周期),cnt2=5-1=4(從2到4共2個clk周期);
如果是7分頻則:cnt1=7/2=3(從0到3共4個clk周期),cnt2=7-1=6(從3到6共3個clk周期);
如此就可以進行奇數倍的分頻了!
`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 08:21:02 07/15/2015
// Design Name:
// Module Name: CLK_DCM
// Project Name:
// Target Devices:
// Tool versions:
// Description: 實作時鐘的奇數分頻;此工程實作5分頻,此時5/2=2(0--2);5-1=4(2--4);3-0.5=2+0.5
//
// Author: ganggang
//
//
module CLK_DCM(
//---input pin----
clk,rst_n,
//---output pin---
clk_out
);
//--------------------------------
//parameter declation
//--------------------------------
parameter DLY = 1;
//---------------------------------
//input declation
//---------------------------------
input clk; //100MHZ
input rst_n; //active low
//----------------------------------
//output declation
//----------------------------------
output clk_out;
//----------------------------------
//wire or reg declation
//----------------------------------
reg clk_out;
reg[2:0] cnt1;
reg[2:0] cnt2;
reg clk1;
reg clk2;
///
//
//LOGIC
//
//
// posedge clk
always @(posedge clk or negedge rst_n)
begin
if(rst_n==1'b0)
begin
cnt1 <=#DLY 2'd0;
clk1 <=#DLY 1'b0;
end
else
begin
if(cnt1==3'd4)
begin
cnt1 <=#DLY 3'd0;
clk1 <=#DLY ~clk1;
end
else
begin
if(cnt1==3'd2)
begin
clk1 <=#DLY ~clk1;
cnt1 <= #DLY cnt1 +1'b1;
end
else
begin
clk1 <= #DLY clk1;
cnt1 <=#DLY cnt1 +1'b1;
end
end
end
end
//negedge clk
always @(negedge clk or negedge rst_n)
begin
if(rst_n==1'b0)
begin
cnt2 <=#DLY 3'd0;
clk2 <=#DLY 1'b0;
end
else
begin
if(cnt2==3'd4)
begin
clk2 <=#DLY ~clk2;
cnt2 <=#DLY 3'd0;
end
else
begin
if(cnt2 == 3'd2)
begin
clk2 <=#DLY ~clk2;
cnt2 <=#DLY cnt2 +1'b1;
end
else
begin
clk2 <=#DLY clk2;
cnt2 <=#DLY cnt2 +1'b1;
end
end
end
end
always @(clk1 or clk2 )
begin
clk_out <= clk1 ||clk2;
end
endmodule