前言
奇偶分频又是一个面试常考问题
正文
怎么理解分频呢,日常生活中,要分什么东西,一般是从较多的地方分的,比如分蛋糕,就是把一整个蛋糕分成小份,从大蛋糕分到小蛋糕。同理这里的分频也就是从频率快的时钟分频得到频率慢的时钟
一、偶分频
偶分频中的核心部分是计数器,即在计数器计满的瞬间将分频时钟取反
设计文件
6分频
:6个clk=1个div_6
计数器
:进行6分频时,需要使用计数器计满2就清0
module divider_6 (
input clk,
input rst_n,
output reg div_6
);
reg [1:0] count_3;
// 1.明确好偶分频是通过计数器实现的
always @(posedge clk or negedge rst_n) begin
if(!rst_n)
count_3 <= 3'd0;
else if(count_3 == 2'd2)
count_3 <= 2'd0;
else
count_3 <= count_3 + 2'd1;
end
// 2. 得到计数器后,就可以通过计数器进行偶分频
always @(posedge clk or negedge rst_n) begin
if(!rst_n)
div_6 <= 1'd0;
else if(count_3 == 2'd2)
div_6 <= ~ div_6;
else
div_6 <= div_6;
end
endmodule
测试文件
`timescale 1ps/1ps
module tb_divider_6 (
);
reg clk;
reg rst_n;
wire div_6;
initial begin
clk = 1'd0;
rst_n = 1'd0;
#20
rst_n = 1'd1;
end
always #10 clk = ~ clk;
divider_6 divider_6_inst(
.clk(clk),
.rst_n(rst_n),
.div_6(div_6)
);
endmodule
二、奇分频
目标
:设计一个9分频的时钟
计数器
:计到8清0
重点:分别使用上升沿和下降沿 触发,并且将9分为4+5
设计文件
module divider_9 (
input clk,
input rst_n,
output div_9
);
reg [3:0] count_8;// 用来计需要几个clk
reg pose_9;// 上升沿触发
reg nege_9;
// 1.9分频需要计数器计到8
always @(posedge clk or negedge rst_n) begin
if(!rst_n)
count_8 <= 4'd0;
else if(count_8 == 4'd8)
count_8 <= 4'd0;
else
count_8 <= count_8 + 4'd1;
end
//==========================================================
// 分别使用上升沿和下降沿触发
//=======================上升沿触发==============================
// 3. 由于是9分频,所以要将9个clk分成4+5
// 即当计数器计到3时,拉高信号;当计数器计到8时,拉低信号
always @(posedge clk or negedge rst_n) begin
if(!rst_n)
pose_9 <= 1'd0;
else if(count_8 == 4'd3)
pose_9 <= 4'd1;
else if(count_8 == 4'd8)
pose_9 <= 4'd0;
else
pose_9 <= pose_9;
end
//=======================下降沿触发==============================
always @(negedge clk or negedge rst_n) begin
if(!rst_n)
nege_9 <= 1'd0;
else if(count_8 == 4'd3)
nege_9 <= 4'd1;
else if(count_8 == 4'd8)
nege_9 <= 4'd0;
else
nege_9 <= nege_9;
end
// 当 pose_9 && nege_9 等于1时,对9分频时钟信号取反
assign div_9 = pose_9 && nege_9;
endmodule
测试文件
`timescale 1ps/1ps
module tb_divider_9 (
);
reg clk;
reg rst_n;
wire div_9;
initial begin
clk = 1'd0;
rst_n = 1'd0;
#20
rst_n = 1'd1;
end
always #10 clk = ~ clk;
divider_9 divider_9_inst(
.clk(clk),
.rst_n(rst_n),
.div_9(div_9)
);
endmodule