http://www.cnblogs.com/oomusou/archive/2008/07/16/verilog_clock_divider.html
WIDTH代表計數器的寬度,N代表要要除的任意正整數,
若要產生各種除頻器,只要改這兩個參數即可。
parameter WIDTH = 26;
若要產生各種除頻器,只要改這兩個參數即可。
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。
//產生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
沒有留言:
張貼留言