1、偶分频:N/2-1,状态翻转,计数器清零
2、奇分频:
clk1:上升沿计数(N-1)/2状态反转,(N-1)状态反转
clk2:下降沿计数(N-1)/2状态反转,(N-1)状态反转
clk:clk1|clk2
3、N+0.5分频 非50%占空比
条件:仿真时,复位之后时钟的上升沿先到来
第一种方法丢掉了第一个时钟,跳转之后计数值为0
①两个计数器cnt_p、cnt_n计数到2*N置零
②pos:初始clk=0,cnt_p==2*N时候置1,cnt_p==N置0
neg:初始clk=1,cnt_p==2*N时候置0,cnt_p==N-1置1
③pos&neg
第二种方法较为严谨,跳转之前计数值为0
①两个计数器cnt_p、cnt_n计数到2*N置零
②pos:初始clk=0,cnt_p==0||cnt_p==N+1反转
neg:初始clk=1,cnt_p==0||cnt_p==N反转
③pos&neg
5分频、4分频、2.5分频仿真
`timescale 1ns / 1ps
module div(
input clk, //50MHz时钟
input rst_n, //复位信号,低电平有效
output reg clk1,
output reg clk2,
output clk_10, //5分频
output clk_12_5, //4分频
output reg [2:0]cnt_p,
output reg [2:0]cnt_n,
output reg clk4,
output reg clk5,
output clk_20 //2.5分频
);
//reg clk1;
reg [2:0]cnt1;
//reg clk2;
reg [2:0]cnt2;
parameter N=5;
always@(posedge clk or negedge rst_n)begin
if(!rst_n)begin
clk1<=0;
cnt1<=0;
end
else if(cnt1==(N-1)/2)begin
clk1<=~clk1;
cnt1<=cnt1+1;
end
else if(cnt1==(N-1))begin
clk1<=~clk1;
cnt1<=0;
end
else
cnt1<=cnt1+1'b1;
end
always@(negedge clk or negedge rst_n)begin
if(!rst_n)begin
clk2<=0;
cnt2<=0;
end
else if(cnt2==(N-1)/2)begin
clk2<=~clk2;
cnt2<=cnt2+1;
end
else if(cnt2==(N-1))begin
clk2<=~clk2;
cnt2<=0;
end
else
cnt2<=cnt2+1'b1;
end
assign clk_10=clk1|clk2;
//4分频
reg clk3;
reg cnt3;
parameter nn=4;
always@(posedge clk or negedge rst_n)begin
if(!rst_n)begin
clk3<=0;
cnt3<=0;
end
else if(cnt3==nn/2-1)begin
clk3<=~clk3;
cnt3<=0;
end
else
cnt3<=cnt3+1;
end
assign clk_12_5=clk3;
//2.5分频,非50%占空比
parameter mm=2;
//reg clk4,clk5;
//reg [2:0]cnt_p,cnt_n;
always@(posedge clk or negedge rst_n)begin
if(!rst_n)begin
clk4<=0;
cnt_p<=0;
end
else if(cnt_p==mm)begin
clk4<=0;
cnt_p<=cnt_p+1'b1;
end
else if(cnt_p==2*mm)begin
clk4<=1;
cnt_p<=0;
end
else
cnt_p<=cnt_p+1;
end
always@(negedge clk or negedge rst_n)begin
if(!rst_n)begin
clk5<=1;
cnt_n<=0;
end
else if(cnt_n==mm-1)begin
clk5<=1;
cnt_n<=cnt_n+1'b1;
end
else if(cnt_n==2*mm)begin
clk5<=0;
cnt_n<=0;
end
else
cnt_n<=cnt_n+1;
end
always@(posedge clk or negedge rst_n)begin
// if(!rst_n)
// cnt_p<=0;
// else if(cnt_p==3'd4)
// cnt_p<=0;
// else
// cnt_p<=cnt_p+1'b1;
//end
//
//always@(posedge clk or negedge rst_n)begin
// if(!rst_n)
// clk4<=0;
// else if(cnt_p==3'd0||cnt_p==mm+1)
// clk4<=~clk4;
// else
// clk4<=clk4;
//end
//
//
//always@(negedge clk or negedge rst_n)begin
// if(!rst_n)
// cnt_n<=0;
// else if(cnt_p==3'd4)
// cnt_n<=0;
// else
// cnt_n<=cnt_n+1'b1;
//end
//always@(negedge clk or negedge rst_n)begin
// if(!rst_n)
// clk5<=1;
// else if(cnt_n==3'd0||cnt_n==mm)
// clk5<=~clk5;
// else
// clk5<=clk5;
//end
assign clk_20=clk4&clk5;
endmodule
testbench
`timescale 1ns / 1ps
module eee;
// Inputs
reg clk;
reg rst_n;
// Outputs
wire clk1;
wire clk2;
wire clk_10;
wire clk_12_5;
wire clk4;
wire clk5;
wire clk_20;
wire [2:0] cnt_p;
wire [2:0] cnt_n;
// Instantiate the Unit Under Test (UUT)
div uut (
.clk(clk),
.rst_n(rst_n),
.clk1(clk1),
.clk2(clk2),
.clk_10(clk_10),
.clk_12_5(clk_12_5),
.cnt_p(cnt_p),
.cnt_n(cnt_n),
.clk4(clk4),
.clk5(clk5),
.clk_20(clk_20)
);
initial begin
// Initialize Inputs
clk = 0;
rst_n = 0;
// Wait 100 ns for global reset to finish
#101;
rst_n = 1;
// Add stimulus here
end
initial clk=0;
always #10 clk=~clk;
endmodule