5分频可以通过计数器来实现,值得注意的是5是奇数,如果通过简单的计数来实现分频占空比不是50%。下面按照两种方法来讲解,第一种占空比为60%(即分频后高电平占3个时钟周期,低电平占2两个时钟周期);第二种,占空比为50%。
一、占空比为60%的5分频
上代码
`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2022/08/10 21:48:57
// Design Name:
// Module Name: div_5clk
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//
module div_5clk(
input clk,
input rst,
output reg clk_out
);
reg [3:0] cnt;
always@(posedge clk or negedge rst)begin
if(!rst)begin
cnt<=1'b0;
end
else if(cnt==3'b100)begin
cnt<='b0;
end
else
cnt<=cnt+1'b1;
end
always@(posedge clk or negedge rst)begin
if(!rst)begin
clk_out<='b0;
end
else if(cnt==1'b1)begin
clk_out<=~clk_out;
end
else if(cnt==3'b100)begin
clk_out<=~clk_out;
end
end
endmodule
测试代码
`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2022/08/10 21:58:29
// Design Name:
// Module Name: tb_div_5clk
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//
module tb_div_5clk();
reg clk;
reg rst;
wire clk_out;
div_5clk div_5clk_u(
. clk(clk),
. rst(rst),
.clk_out(clk_out)
);
initial begin
rst<=0;
clk<=0;
#10 rst<=1'b1;
forever #10 clk<=~clk;
end
endmodule
仿真结果
clk为原来的时钟,经过分频后输出时钟是clk_out。
二、占空比为50%的5分频
相比之下,实现占空比为50%的5分频难度稍微有些高,但其实也不是很难。定义两个寄存器clk_p和clk_n,当cnt计数到2时clk_p实现翻转,clk_n在时钟的下降沿再将clk_p的值给clk_n,然后通过或运算assign clk_out = clk_p | clk_n;
最终得到我们所需要的clk_out。话不多说直接上代码:
代码
`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2022/08/10 22:48:01
// Design Name:
// Module Name: div_5clk_50pes
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//
module div_5clk_50pes(
input clk,
input rst,
output clk_out
);
reg [3:0] cnt;
reg clk_p;
reg clk_n;
always@(posedge clk or negedge rst)begin
if(!rst)begin
cnt<=1'b0;
end
else if(cnt==3'b100)begin
cnt<='b0;
end
else
cnt<=cnt+1'b1;
end
always@(posedge clk or negedge rst)begin
if(!rst)begin
clk_p<='b0;
end
else if(cnt<=1'b1)begin
clk_p<=1'b1;
end
else begin
clk_p<=1'b0;
end
end
always@(negedge clk )begin//注意这里是低电平有效,而不是打一拍(延迟一个时钟周期),所以只延迟半个时钟周期
clk_n<=clk_p;
end
assign clk_out = clk_p | clk_n;
endmodule
测试代码
`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2022/08/10 21:58:29
// Design Name:
// Module Name: tb_div_5clk
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//
module tb_div_5clk();
reg clk;
reg rst;
wire clk_out;
div_5clk_50pes div_5clk_50pes_u(
. clk(clk),
. rst(rst),
.clk_out(clk_out)
);
initial begin
rst<=0;
clk<=0;
#10 rst<=1'b1;
forever #10 clk<=~clk;
end
endmodule
仿真图
可以看到clk_out满足了我们的需求,通过这个小实验可以清楚的了解如何实现奇数分频电路,代码逻辑也相对简单,仔细分析就能理解其中的含义,好了今天就写到这里。
--晓凡 2022年8月10日于南宁书