抽空写一下奇数倍以及偶数倍分频的verilog代码,复习一下
目录
1、偶数倍分频的实现,占空比50%
以四分频为例
//占空比50%
module div_even_f(
input wire clk,
input wire rst_n,
output reg div_clk
);
reg [1:0] div_cnt;
parameter N = 4;
always @(posedge clk or negedge rst_n) begin
if (!rst_n)
div_cnt <= 2'd0;
else if(div_cnt < (N/2-1))
div_cnt <= div_cnt +1'b1;
else
div_cnt <= 2'd0;
end
always @(posedge clk or negedge rst_n) begin
if (!rst_n)
div_clk <= 1'b0;
else if (div_cnt == (N/2-1))
div_clk <= ~div_clk;
else
div_clk <= div_clk;
end
endmodule
2、偶数倍分频tb文件
`timescale 1ns/1ps
module tb_div_even();
reg clk;
reg rst_n;
wire div_clk;
initial begin
clk =0;
rst_n =0;
#100
rst_n =1;
end
always #5 clk =~clk;
div_even_f div_f_even_inst(
.clk(clk),
.rst_n(rst_n),
.div_clk(div_clk)
);
endmodule
3、偶数倍分频仿真结果
输出时钟频率是输入时钟频率的四分之一,仿真正确
4、奇数倍分频的实现,50%占空比
以5分频为例
1、奇数倍分频要比偶数倍分频稍微复杂一点,主要使用两个计数器,一个上升沿触发,一个下降沿触发,通过调节各个计数器产生时钟的占空比,最后异或,可以得到不同占空比的分频信号。
简要的画了个图,如果需要调整占空比,就只需要改变clk0、clk1的占空比,即只需要调整clk0、1翻转的位置即可
verilog实现:
//百分之50%占空比
module div_uneven(
input wire clk,
input wire rst_n,
output wire clk_out
);
reg [2:0]div_cnt0,div_cnt1;
reg clk0,clk1;
parameter N = 5;
always @(posedge clk or negedge rst_n)
if(!rst_n)
div_cnt0 <= 3'd0;
else if(div_cnt0 < N-1)
div_cnt0 <= div_cnt0 +1'b1;
else
div_cnt0 <= 3'd0;
always @(negedge clk or negedge rst_n) begin
if (!rst_n)
div_cnt1 <= 3'd0;
else if (div_cnt1 < N-1)
div_cnt1 <= div_cnt1 +1'b1;
else
div_cnt1 <= 3'd0;
end
always @(posedge clk or negedge rst_n) begin
if (!rst_n)
clk0 =1'b0;
else if (div_cnt0 == (N/2-2) || div_cnt0 == (N-3))
clk0 <= ~clk0;
else
clk0 <= clk0;
end
always @(negedge clk or negedge rst_n) begin
if (!rst_n)
clk1 =1'b0;
else if (div_cnt1 == (N/2-2) || div_cnt1 == (N-3))
clk1 <= ~clk1;
else
clk1 <= clk1;
end
assign clk_out =clk1 |clk0 ;
endmodule
5、奇数倍分频的tb文件
`timescale 1ns/1ps
module tb_div_uneven();
reg clk;
reg rst_n;
wire div_clk;
initial begin
clk =0;
rst_n =0;
#100
rst_n =1;
end
always #5 clk =~clk;
div_uneven div_uneven_inst(
.clk(clk),
.rst_n(rst_n),
.clk_out(div_clk)
);
endmodule