题目要求
设计一个module,实现任意偶数分频,要求占空比为50%,如4分频、6分频,要求分频参数可配置。
以4分频为例,表示分频后的时钟周期是原时钟周期的4倍,即高电平和低电平时间各占2个周期,波形如下:
解题思路
为了实现目标波形,需要用到一个计数器cnt
来计数基本时钟周期,如4分频,则数两个时钟周期,然后进行输出翻转,如下图所示:
图中:绿色表示输入信号,橙色表示中间变量,红色表示输出信号。
代码实现
module divider_even_n
#(
parameter N = 3'd4
)(
input wire clk ,
input wire rst_n ,
output reg out_clk
);
reg [$clog2(N)-2 : 0] cnt;
wire [$clog2(N)-2 : 0] CNT_MAX;
assign CNT_MAX = (N >> 1'b1) - 1'b1;
always@(posedge clk or negedge rst_n) begin
if(!rst_n)
cnt <= 'd0;
else if(cnt == CNT_MAX)
cnt <= 'd0;
else
cnt <= cnt + 1'b1;
end
always@(posedge clk or negedge rst_n) begin
if(!rst_n)
out_clk <= 1'b0;
else if(cnt == CNT_MAX)
out_clk <= ~out_clk;
else
out_clk <= out_clk;
end
endmodule
代码中需要注意的细节:
①$clog2是系统内置函数,是求出该数转换为二进制需要占的位数;
②翻转的条件为cnt == CNT_MAX
,CNT_MAX = (N >> 1'b1) - 1'b1
,也就是说,若N=4时,需要数2个数,从0开始数,所以数到1就要开始翻转;同理,6分频,N=6,则在2的时候翻转。
Testbench
此题的testbench很简单啦,只需要给好时钟信号和复位信号就可以啦,具体如下:
`timescale 1ns/1ns
module divider_even_n_tb();
reg clk ;
reg rst_n ;
wire out_clk ;
always #10 clk = ~clk;
initial
begin
rst_n = 1'b0;
clk = 1'b1;
#10
rst_n = 1'b1;
end
divider_even_n
#(
.N(3'd6) //6分频,仅仅支持偶数
)
divider_even_n_inst
(
.clk (clk ),
.rst_n (rst_n ),
.out_clk(out_clk)
);
endmodule
此testbench和前一节的奇数分频几乎一模一样。
仿真波形
四分频的波形图:
六分频的波形图: