1、题目描述:
–设计一个分频器,输入时钟clk的频率为100MHz,输出一个N分频时钟(N为整数)。
–要求:
输入信号:clk(上升沿采样), rstn(异步低电平复位)
输出信号: clk_out,
输出时钟的占空比为50%
对分频原理进行描述
注意:
(1)不可采用电平触发
(2)同一敏感列表中不可同时出现同一个信号的上升沿和下降沿
违反上述两条,代码为0分。
端口描述如下:
module clk_div #( parameter N = 2) ( input clk, input rstn, output clk_out);
50%占空比 2分频波形图
50%占空比 5分频波形图
2、Verilog代码
module clk_div
#(
parameter N = 2) //根据参数N判断进行奇分频or偶分频
(
input clk,
input rstn,
output reg clk_out);
reg [7:0] cnt; //计数,计算时钟上升沿
reg clk_1; //even分频时即为clk_1
reg clk_2; //clk_1延迟半个时钟周期得到clk_2
reg clk_odd; //奇分频得到的时钟
always@(posedge clk,negedge rstn)begin //时钟上升沿计数
if(!rstn)
cnt<=0;
else if(cnt==N-1)
cnt<=0;
else
cnt<=cnt+1;
end
always@(posedge clk,negedge rstn)begin
if(!rstn)
clk_1<=0;
else if(cnt==0)
clk_1<=1; //时钟上升沿开始
else if(cnt==(N>>1)) //达到N的一半时,下降为低电平。e.g.N=3,0高,12为低。N=4,01高,23低
clk_1<=0;
end
always@(negedge clk,negedge rstn)begin
if(!rstn)
clk_2<=0;
else
clk_2<=clk_1; //clk_2在时钟的下降沿等于clk_1
end
always@(*)begin
clk_odd=clk_1|clk_2; //odd分频时的电路。
clk_out=N[0]?clk_odd:clk_1;
end
endmodule
- odd分频时,e.g.N=3,即在三个系统时钟周期中,分别有3个上升、下降沿-------共6个边沿,因此前3个为3分频的高,后三个为3分频的低。
- 四个always块为并行结构,e.g.N=3,因此第一个posedge clk,cnt=0。第二个posedge clk,cnt=1,clk_1变为0;只存在了一个时钟周期,不过与clk_2或之后,就有了一个半的时钟周期。
3、 testbench:
module tb_clk_div();
reg clk;
reg rstn;
wire clk_out;
clk_div #(.N(3)) U(clk,rstn,clk_out);
initial begin
clk=0;rstn=0;
#10 clk=1;rstn=0;
#10 clk=0;rstn=1;
#10 clk=1;rstn=1;
#10 clk=0;
#10 clk=1;
#10 clk=0;
#10 clk=1;
#10 clk=0;
#10 clk=1;
#10 clk=0;
#10 clk=1;
#10 clk=0;
#10 clk=1;
#10 clk=0;
#10 clk=1;
#10 clk=0;
#10 clk=1;
#10 clk=0;
#10 clk=1;
#10 clk=0;
#10 clk=1;
end
initial begin
$dumpfile("test.vcd");
$dumpvars(0);
end
endmodule
波形图:
4、总结
此代码仅能实现50%的占空比 ,能够根据参数N实现奇分频或者偶分频。
更为详细的讲解,参考:Verilog 分频器设计_verilog分频-CSDN博客