前言
分频器,是将输入信号的频率进行缩小。实际上,在数学IC笔面中常考的分频器设计,就是采用计数器,对输入时钟合理生成中间信号,最后通过逻辑操作输出。本质上,这里考的还是计数器相关的知识点,同时会涉及到时钟相关的基本概念。
实验手册
一、实验目的
设计一个能够自主定义分频参数的时钟分频器模块,能够将输入时钟信号按照给定的任意分频比例进行分频,并输出分频后的时钟信号。
二、实验原理
1.理论原理
我们在实验时有时不需要用到太大的时钟频率,为了方便使用,将原本的时钟频率变成相应倍数低的输出信号,分频方式是使用计数器,由于计数器的输出端口是按一定规律输出脉冲的,所以对不同的端口输出的信号脉冲,就可以看作是对输入信号的分频。
2.硬件原理
无
三、系统架构设计
输入时钟信号和复位信号,在时钟分频模块中进行对输入时钟信号的进行分频,最后输出分频信号。
在时钟分频模块顶层设计一个参数,想要什么分频比例修改参数即可。
四、模块说明
1.模块端口信号列表
端口信号 | 数据类型 | 名称 | 含义 |
---|---|---|---|
input | wire | clk | 时钟信号 |
input | wire | rst_n | 复位信号 |
output | reg | divier_out | 偶数分频信号 |
output | wire | divier_odd_out | 奇数分频信号 |
2.状态转移图
无
3.时序图
无
五、仿真波形图
当分频参数为3时,一个分频上升沿和下降沿共占3个时钟周期,分频成功,在对奇数分频时,将上升沿分频(divider_odd_pout),高电平保持n周期,低电平保持n+1周期,再将下降沿分频(divider_odd_nout),高电平保持n周期,低电平保持n+1周期,最后将两者相或,即可得到输出最终奇数分频信号(divider_odd_out),以上操作是为了满足占空比为50%,若占空比不做要求,则直接使用偶数分频方法即可
当分频参数为4时,一个分频上升沿和下降沿共占4个时钟周期,分频成功,对偶数分频时,只需在分频计数器的一半时(也就是分频参数的一半)将信号反转即可。
六、板级验证效果(拍照或录制视频)
无
代码编写
模块文件
module divider #(parameter variable = 4) (
input clk,
input rst_n,
output reg divider_out, //偶数分频信号输出
output wire divider_odd_out //奇数分频信号输出
);
reg divider_odd_pout; //时钟上升沿分频
reg divider_odd_nout; //时钟下降沿分频
reg [31:0] cnt;
//分频参数计数器
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
cnt <= 32'd0;
end
else if (cnt == (variable-1)) begin
cnt <= 32'd0;
end
else begin
cnt <= cnt + 32'd1;
end
end
//偶数分频模块
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
divider_out <= 1'd0;
end
else if (cnt <= (variable/2 - 1) && variable % 2 == 0) begin//variable % 2 == 0该语句判断是否为偶数
divider_out <= 1'b1;
end
else begin
divider_out <= 1'b0;
end
end
//时钟上升沿分频
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
divider_odd_pout <= 1'd0;
end
else if (cnt == (variable - 1) && variable%2 != 0) begin
divider_odd_pout <= 1'b1;
end
else begin
divider_odd_pout <=1'b0;
end
end
//时钟下降沿分频
always @(negedge clk or negedge rst_n) begin
if (!rst_n) begin
divider_odd_nout <= 1'd0;
end
else if (cnt == (variable - 1) && variable%2 != 0) begin
divider_odd_nout <= 1'b1;
end
else begin
divider_odd_nout <= 1'b0;
end
end
assign divider_odd_out = divider_odd_pout | divider_odd_nout; //获得奇数分频信号
endmodule
测试文件
`timescale 1ns/1ns
//测试文件模块
module divider_tb ();
//激励信号定义(input)
/* input */reg clk ;
/* input */reg rst_n ;
//响应信号定义(output)
/* output */wire divider_out ;
wire divider_odd_out;
//参数
parameter variable = 3;
//产生时钟
always #10 clk <= ~clk;
//产生激励
initial begin
rst_n <= 1'b0;
clk <= 1'b0;
#2
rst_n <= 1'b1;
#10000
$stop;
end
//实例化
divider #(.variable(variable))u_divider(
.clk ( clk) ,
.rst_n ( rst_n) ,
.divider_out( divider_out) ,
.divider_odd_out(divider_odd_out)
);
endmodule