首先绘制两个输入信号的波形 sys_clk 时钟信号和 sys_rst_n 复位信号,既然需要分频那肯定需要一个计数器,所以我们定义一个名为 cnt_clk 的计数器,对于计数器我们要精确的控制它何时计数、何时清零,这里计数的开始我们没有特殊要求,即只要时钟正常工作且复位被释放我们就可以立刻进行计数。那计数器计数到多少清零呢?这里我们的要求是进行3分频所以我们最大计数值为3所以cnt_clk位宽为2,低电平是一个时钟周期,高电平时 2 个时钟周期
,three_clk1 波形的变化都是在系统时钟 sys_clk 上升沿时进行,three_clk2 波形的变化都是在系统时钟 sys_clk 下降沿时进行,three_out 输出信号是我们想要的 3 分频的,我们仔细观察画下波形,可以发现 three_clk1 和 three_clk2 相或的结果就是 three_out的波形,
module divider_three
(
input wire sys_clk,//系统时钟
input wire sys_rst_n,
output wire three_clk//分频后输出的时钟
);
reg [1:0] cnt_clk;//上升沿分频计数器
reg three_clk1;
reg three_clk2;
always@(posedge sys_clk or negedge sys_rst_n)begin
if(sys_rst_n==0)begin
cnt_clk<=0;
end
else if(cnt_clk==2'd2)
cnt_clk<=0;
else
cnt_clk<=cnt_clk+2'd1;
end
//系统时钟上升沿cnt_clk计数到1翻转一次,计数到2再翻转一次
always@(posedge sys_clk or negedge sys_rst_n)begin
if(sys_rst_n==0)begin
cnt_clk<=0;
three_clk1<=0;
end
else if(cnt_clk==1)
three_clk1<=~three_clk1;
else if(cnt_clk==2)
three_clk1<=~three_clk1;
end
//系统时钟下降沿cnt_clk计数到1翻转一次,计数到2再翻转一次
always@(negedge sys_clk or negedge sys_rst_n)begin
if(sys_rst_n==0)begin
cnt_clk<=0;
three_clk2<=0;
end
else if(cnt_clk==1)
three_clk2<=~three_clk2;
else if(cnt_clk==2)
three_clk2<=~three_clk2;
end
//相或得到结果
assign three_clk=three_clk1|three_clk2;//分频后输出的时钟
endmodule
//仿真文件
`timescale 1ns/1ns
module tb_divider_three();
reg sys_clk ;//系统时钟
reg sys_rst_n ;
wire three_clk ; //分频后输出的时钟
initial begin
sys_clk<=0;
sys_rst_n<=0;
#20
sys_rst_n<=1'b1;
end
always #20 sys_clk<=~sys_clk;
divider_three divider_three_inst(
.sys_clk (sys_clk ),
.sys_rst_n (sys_rst_n),
.three_clk (three_clk)
);
endmodule
最终仿真结果