看了網上的很多例子,有很多的成長。記錄下來。
1.二分頻
module sp6(
input ext_clk_25m,
input ext_rst_n,
output reg clk_12m5
);
always @(posedge ext_clk_25m or negedge ext_rst_n)
if(!ext_rst_n)
clk_12m5 <= 1'b0;
else
clk_12m5 <= ~clk_12m5;
endmodule
2.偶數分頻
module spfen(
input sclk,
input rst_n,
output reg clk_div
);
reg [3:0] cnt;
parameter Num_Div = 6;
always @(posedge sclk or negedge rst_n)
if(!rst_n)
cnt<=1'b0;
else if(cnt<Num_Div/2-1)
cnt<=cnt+1'b1;
else
cnt<=1'b0;
always @(posedge sclk or negedge rst_n)
if(!rst_n)
clk_div<=1'b0;
else if(cnt<Num_Div/2-1)
clk_div<=clk_div;
else
clk_div<=~clk_div;
endmodule
3.奇數分頻
module single_div(
input sclk,
input rst_n,
output clk_div
);
reg [2:0] cnt_p;
reg [2:0] cnt_n;
reg clk_p,clk_n;
parameter Clk_Div = 5;
always @(posedge sclk or negedge rst_n)
if(!rst_n)
cnt_p <= 1'b0;
else if(cnt_p == (Clk_Div-1))
cnt_p <= 1'b0;
else
cnt_p <= cnt_p+1'b1;
always @(negedge sclk or negedge rst_n)
if(!rst_n)
cnt_n <= 1'b0;
else if(cnt_n == (Clk_Div-1))
cnt_n<=1'b0;
else
cnt_n <= cnt_n+1'b1;
always @(posedge sclk or negedge rst_n)
if(!rst_n)
clk_p <= 1'b1;
else if(cnt_p == (Clk_Div-1)/2-1)
clk_p <= ~clk_p;
else if(cnt_p == (Clk_Div-1))
clk_p <= ~clk_p;
always @(negedge sclk or negedge rst_n)
if(!rst_n)
clk_n <= 1'b1;
else if(cnt_n == (Clk_Div-1)/2-1)
clk_n <= ~clk_n;
else if(cnt_n == (Clk_Div-1))
clk_n <= ~clk_n;
//always @(posedge sclk or negedge rst_n)
// if(!rst_n)
// clk_div <= 1'b0;
// else
// clk_div <= clk_p | clk_n;
assign clk_div = clk_p | clk_n;
endmodule
但是值得注意的是:當把output的類型改成reg 類型的時候,用always塊指派,得到的時鐘并不理想,剛入門還沒搞明白,希望高手能在評論區指點。
4.半整數分頻
module half_divider(
input sclk,
input rst_n,
output reg clk_div
);
reg [4:0] cnt;
wire clk1;
reg flag;
parameter N = 3;//N-0.5分頻
always @(posedge clk1 or negedge rst_n)
if(!rst_n)
flag <= 1'b0;
else if(cnt==(N-1)/2)
flag <= ~flag;
assign clk1 = flag?(~sclk):sclk;
always @(posedge clk1 or negedge rst_n)
if(!rst_n)
cnt <= 1'b0;
else if(cnt == N-1)
cnt <= 1'b0;
else
cnt <= cnt+1'b1;
always @(posedge clk1 or negedge rst_n)
if(!rst_n)
clk_div <= 1'b0;
else if(cnt == 5'd0)
clk_div <= 1'b0;
else if(cnt == (N+1)/2)
clk_div <= ~clk_div;
else
clk_div <= clk_div;
endmodule
5.任意整數分頻
module random_divider(
input sclk,
input rst_n,
output clk_p,
output clk_n,
output clk_div
);
reg clk1,clk2;
reg [3:0] cnt_n,cnt_p;
parameter N = 5;
always @(posedge sclk or negedge rst_n)
if(!rst_n)
cnt_p <= 1'b0;
else if(cnt_p == (N/2-1))
cnt_p <= 1'b0;
else
cnt_p <= cnt_p + 1'b1;
always @(negedge sclk or negedge rst_n)
if(!rst_n)
cnt_n <= 1'b0;
else if(cnt_n == (N/2-1))
cnt_n <= 1'b0;
else
cnt_n <= cnt_n + 1'b1;
always @(posedge sclk or negedge rst_n)
if(!rst_n)
clk1 <= 1'b0;
else if(cnt_p < (N/2-1))
clk1 <= clk1;
else
clk1 <= ~clk1;
always @(negedge sclk or negedge rst_n)
if(!rst_n)
clk2 <= 1'b0;
else if(cnt_n < (N/2-1))
clk2 <= clk2;
else
clk2 <= ~clk2;
//always @(posedge sclk or negedge rst_n)
// if(!rst_n)
// clk_div <= 1'b0;
// else
// clk_div<=(N%2)?(clk1|clk2):clk1;
assign clk_div = (N==1)?sclk:(N[0])?(clk1 | clk2):clk1;
assign clk_p = clk1;
assign clk_n = clk2;
endmodule
不過這塊的代碼還有待改善, 我想和奇數分頻一樣實作占空比為50%的時鐘,可是并沒有得到。會繼續解決的,還是希望有路過的大牛能提點一二。這塊的實作思路由https://blog.csdn.net/u014183456/article/details/76695465提供。