一、如何进行偶分频
通过之前的计数器,我发现,可以通过计数的功能实现对原有板载的时钟进行分频。例如,想实现六分频,那么就需要计六个数,依次从0到2,总共三个数,每次到2的时候对输出变量进行取反操作,这样就可以实现占空比为50%的六分频。但是该设计在低频中没什么差错,但是如果在高频中使用的话,可能会出现一些问题,因为从系统时钟开始进行分频的话,是需要消耗时间的,因此,设计了更好的办法,使用脉冲,及就是降频的方法,这样虽然输出的占空比不是50%,但是可以在使用的过程中在敏感列表使用系统时钟,这样无论高低频,都很稳定。
二、设计步骤
1.画分析图
2.分析得出波形图
1)占空比为50%的波形图
2)使用脉冲的波形图
3.代码实现
divider_six.v:
`timescale 1ns / 1ps
//
// Company: XUPT
// Engineer: ZZP
//
// Create Date: 2021/08/23 13:12:31
// Design Name: divider_six
// Module Name: divider_six
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//
module divider_six(
input wire sys_clk,
input wire sys_rst_n,
// output reg clk_out
output reg clk_flag
);
reg [2:0] cnt;
/* always @(posedge sys_clk or negedge sys_rst_n) begin
if (sys_rst_n == 1'b0)begin
cnt <= 2'd0;
end
else if (cnt == 2'd2) begin
cnt <= 2'd0;
end
else begin
cnt <= cnt + 2'd1;
end
end
always @(posedge sys_clk or negedge sys_rst_n) begin
if (sys_rst_n == 1'b0) begin
clk_out <= 1'b0;
end
else if (cnt == 2'd2) begin
clk_out <= ~clk_out;
end
else begin
clk_out <= clk_out;
end
end */
// 这个是使用脉冲的方法,也就是降频,在高频系统中不容易出现问题
always @(posedge sys_clk or negedge sys_rst_n) begin
if (sys_rst_n == 1'b0)begin
cnt <= 3'd0;
end
else if (cnt == 3'd5) begin
cnt <= 3'd0;
end
else begin
cnt <= cnt + 3'd1;
end
end
always @(posedge sys_clk or negedge sys_rst_n) begin
if (sys_rst_n == 1'b0) begin
clk_flag <= 1'b0;
end
else if (cnt == 3'd4) begin
clk_flag <= 1'b1;
end
else begin
clk_flag <= 1'b0;
end
end
endmodule
tb_divider_six.v:
`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2021/08/23 14:56:40
// Design Name:
// Module Name: tb_divider_six
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//
module tb_divider_six();
reg sys_clk;
reg sys_rst_n;
//wire clk_out;
wire clk_flag;
initial begin
sys_clk = 1'b1;
sys_rst_n <= 1'b0;
#10
sys_rst_n <= 1'b1;
end
always #5 sys_clk =~ sys_clk;
/*divider_six divider_six_inst(
. sys_clk (sys_clk),
. sys_rst_n (sys_rst_n),
. clk_out(clk_out)
);*/
divider_six divider_six_inst(
. sys_clk (sys_clk),
. sys_rst_n (sys_rst_n),
. clk_flag(clk_flag)
);
endmodule