2012年12月8日 星期六

將Clock 除以N倍 (除頻器) 適用於DE2-70

源自於
http://www.cnblogs.com/oomusou/archive/2008/07/16/verilog_clock_divider.html


WIDTH代表計數器的寬度,N代表要要除的任意正整數,
若要產生各種除頻器,只要改這兩個參數即可。
parameter WIDTH = 26;
parameter N     = 50_000_000;




//Input  : Clock . Reset 
//Output : Clock Divided by N Clock pluse   

module Div_N  (CLOCK_50,KEY,LEDG);

input   CLOCK_50;
input [0:0]  KEY;
output [0:0] LEDG;

Divide_N UUT0 (.clk(CLOCK_50),
.rst_n(KEY[0]),
.o_clk(LEDG[0])
);


endmodule



//Input  : Clock . Reset 
//Output : Clock Divided by N Clock pluse   

module Divide_N  (
input  clk,
input  rst_n,
output o_clk
);
parameter WIDTH = 26;
parameter N     = 50_000_000;
reg [WIDTH-1:0] cnt_p;
reg [WIDTH-1:0] cnt_n;
reg             clk_p;
reg             clk_n;

//setting output clock 
assign o_clk = (N == 1) ? clk :    
(N[0])   ? (clk_p | clk_n) : (clk_p);
//if N=1 then output clock = clock_in , Teset N= Odd or Even ??
//若為奇數,則clk_p | clk_n,若為偶數,則clk_p即可
   //**********************(clk_p)***********************   
always@(posedge clk or negedge rst_n) begin
if (!rst_n)
cnt_p <= 0;
else if (cnt_p == (N-1))
cnt_p <= 0;         //clock is Counted to N-1 ???
else
cnt_p <= cnt_p + 1;
end
always@(posedge clk or negedge rst_n) begin
if (!rst_n) 
clk_p <= 1;
else if (cnt_p < (N>>1))
clk_p = 1;       //if N/2 > cnt_p then clk_p = 1-->0-->1
else //generate clock/2 pluse
clk_p = 0;    
end
//**********************(clk_n)***********************   
//產生duty cycle為50%的clock,所以一半要1,一半要0,但0、1、2該怎麼平分呢?由於前半部的波形1做or
// 會 變大,所以就少分一點,也就是當計數器為0產生1,1、2時產生0。

always@(negedge clk or negedge rst_n) begin
if (!rst_n)
cnt_n <= 0;
else if (cnt_n == (N-1))
cnt_n <= 0;
else
cnt_n <= cnt_n + 1;
end

always@(negedge clk or negedge rst_n) begin
if (!rst_n)
clk_n <= 1;
else if (cnt_n < (N>>1))
clk_n = 1;
else
clk_n = 0;
end
endmodule

沒有留言:

張貼留言

Messaging API作為替代方案

  LINE超好用功能要沒了!LINE Notify明年3月底終止服務,有什麼替代方案? LINE Notify將於2025年3月31日結束服務,官方建議改用Messaging API作為替代方案。 //CHANNEL_ACCESS_TOKEN = 'Messaging ...