实验:时钟分频器(整数分频)
一、实验目的
设计一个可配置的时钟分频器模块,能够将输入时钟信号按照50%的占空比进行分频,并输出分频后的时钟信号。
二、实验原理
分频器:使用计数器在时钟信号上升沿或者下降沿进行计数,当计数器的值等于分频系数的一半或者等于分频系数,信号反转。
占空比:高电平占一个周期的比例
三、系统构架设计
共使用工程模块和仿真模块两部分。工程模块中需要包括计时器模块、偶数分频模块、奇数分频模块、奇偶数判断模块。仿真模块包括设置时间单位、定义分频模块、定义分频系数、设置初始值及测试时间周期、模块实例化。
四、模块声明
输入端:时钟信号:clk;复位信号:ret_n;
输出端:分频后信号:outclk。
系统通过计时器cnt实现分频,并产生三个时钟信号(clk1、clk2、clk3)。当给定分频系数divider_in为奇数时,系统会输出outclk为clk1和clk2相或之后的结果,当给定分频系数divider_in为偶数时,系统会输出outclk为clk3。
五、工程代码
module clk1#(parameter divider_in = ?)(
// ports
input clk ,
input rst_n ,
output wire outclk
);
reg [3:0] cnt;
reg clk1;
reg clk2;
reg clk3;
//计时器
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
cnt <= 3'b0;
end
else if(cnt < divider_in - 1) begin
cnt <= cnt + 2'b1;
end
else if(cnt == divider_in - 1) begin
cnt <= 3'b0;
end
end
//奇数分频clk1
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
clk1 <= 0;
end
else if (cnt < ((divider_in - 1) / 2)) begin
clk1 <= 1;
end
else begin
clk1 <= 0;
end
end
//奇数分频clk2
always @(negedge clk or negedge rst_n) begin
if (!rst_n) begin
clk2 <= 0;
end
else if (cnt < ((divider_in - 1) / 2)) begin
clk2 <= 1;
end
else begin
clk2 <= 0;
end
end
//偶数部分clk3
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
clk3 <= 0;
end
else if (cnt < (divider_in / 2)) begin
clk3 <= 1;
end
else begin
clk3 <= 0;
end
end
//outclk
assign outclk =(divider_in % 2 == 0) ? (clk3) : (clk1 | clk2);
endmodule
功能仿真
仿真文件分为四个部分:测试模块声明、设定时钟周期、设定输入信号、实例化。
`timescale 1ns/1ps
module tb_clk1 ();
reg tb_clk;
reg tb_rst_n;
wire tb_outclk;
parameter tb_divider_in = ?;
//设置20ns时钟周期
always #10 tb_clk = ~tb_clk;
//输入信号设定
initial begin
tb_clk = 0;
tb_rst_n = 0;
#20
tb_rst_n = 1;
#300
$stop;
end
//实例化
clk1 #(.divider_in(tb_divider_in))tb_clk1(
/*tb_clk; */ .clk (tb_clk ),
/*tb_rst_n; */ .rst_n (tb_rst_n ),
/*tb_outclk;*/ .outclk (tb_outclk)
);
endmodule
仿真波形图
当分频为6时:输出信号outclk为clk3信号,如下图。
当分频为7时:输出信号outclk为clk1和clk2相或的信号,如下图。