看了网上的很多例子,有很多的成长。记录下来。
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提供。