奇数倍分频有多种实现方法,此处占空比为50%的3分频练习为常用的错位“异或”法。
过程
:
1.首先进行上升沿触发的模3计数,计数到选定值2时进行输出时钟翻转,然后
经过(3-1)/2 再次进行翻转得到一个占空比非 50%奇数3分频时钟。
2.再者同时进行下降沿触发的模3计数,到和上升沿触发输出时钟翻转选定值相同值时,进行输出时钟时钟翻转,同样经过(3-1)/2 时,输出时钟再次翻转生成占空比非 50%的奇数3分频时钟。
3.两个占空比非 50%的3分频时钟相或运算,得到占空比为 50%的奇数3分频时钟。
testbench
:
被测模块的输入端口相连的信号定义为 reg 类型,便于在 initial 语句和 always 语句块中对其进行赋值;
被测模块输出端口相连的信号定义为 wire 类型,便于进行检测。
工程源文件
:
`timescale 1ns / 1ps
//
// Engineer:wjc
// Create Date: 2020/06/29 09:52:40
// Module Name: clk_div_3
//
module clk_div_3(
input clk_in,
input rst_n,
output clk_out
);
reg [1:0] cnt,cnt1;
reg clk_1to3p,clk_1to3n;
always @ (posedge clk_in)begin//上升沿3分频,占空比1:2
if(!rst_n)begin //rst_n=0
cnt<=0;
clk_1to3p<=0;
end
else begin
if(cnt==2'b10)begin //由0开始,计数到2时
cnt<=0; //计数归零
clk_1to3p<=clk_1to3p;//不变
end
else begin //未计数到2
cnt<=cnt+1;//计数
clk_1to3p<=!clk_1to3p;//时钟翻转
end
end
end
always @ (negedge clk_in)begin//下降沿3分频,占空比1:2
if(!rst_n)begin
cnt1<=0;
clk_1to3n<=0;
end
else begin
if(cnt1==2'b10)begin//由0开始,计数到2时
cnt1<=0; //计数归零
clk_1to3n<=clk_1to3n;//不变
end
else begin//未计数到2
cnt1<=cnt+1;//计数
clk_1to3n<=!clk_1to3n;//时钟翻转
end
end
end
assign clk_out=clk_1to3p|clk_1to3n;//时钟相或运算
endmodule
测试文件
:
`timescale 1ns / 1ps
//
// Engineer: wjc
// Create Date: 2020/06/29 18:02:27
// Module Name: clk_div_3_tb
//
module clk_div_3_tb;
reg clk_in,rst_n;
wire clk_out;
clk_div_3 uut(
.clk_in (clk_in),
.rst_n (rst_n),
.clk_out (clk_out));
initial begin
clk_in = 1'b0;
forever #10 clk_in = ~clk_in;
end
initial begin
rst_n = 1'b0;
#100 rst_n = 1'b1;
end
endmodule
仿真结果
:
时序理解
:
按自己理解画的时序图,凑合着看吧,有错误请指正。