FPGA实现任意分频系数和占空比的时钟频率输出

分频在 fpga 的设计中一直都担任着很重要的角色,而说到分频,我相信很多人都已经想到了利用计算器来计算达到想要的时钟频率,但问题是仅仅利用计数器来分频,只可以实现偶数分频,而如果我需要三分频,五分频,七分频等等奇数类分频,那究竟怎么办呢?在这里,让我介绍一个可以实现任意整数分频的方法,这个办法也是同样利用了计数器来计算,当是跟偶数分频不一样的地方是任意整数分频利用了两个计数器来实现。

一、设计原理

本次设计主要是设计一个可调的分频器,我可以设置其参数,可以调节其输出的占空比,占空比的意思就是高电平所占周期的多少。我们通知计算高电平的时间和低电平的时间来实现,其实就是我们用两个计数器来控制的。

FPGA实现任意分频系数和占空比的时钟频率输出
图 1 FPGA 实现任意分频器模块设计

通过对两个计数器的计数,一个计算到了跳转下一个状态,等下一计数器计数到了又调回第一个状态,从而完成任意分频器的设计。

FPGA实现任意分频系数和占空比的时钟频率输出
图 2 FPGA 实现任意分频器状态分析

二、设计代码

设计模块:

//-------------------------Timescale----------------------------//
`timescale 1 ns / 1 ps 
//-----------------------Module freq_divider------------------------//
module freq_divider(
	clk,
	rst_n,
	clk_out
);

input clk;
input rst_n;
output reg clk_out;

parameter HW = 7 ;     //分一个高位 7
parameter LW = 3 ;  //低电平为 3  也就是 5M 的时钟
localparam s0 = 1'b0;    //定义两个状态
localparam s1 = 1'b1;

reg state;
reg [2:0] count;

always @(posedge clk or negedge rst_n)
	if(!rst_n)
	begin
		state <= 1'b0;
		count <= 3'b0;
		clk_out <= 1'b0;
	end
	else case (state)
	s0:
	begin
		if(HW + 1 > 1)  //判断是否 HW 为 0
			if(count < HW - 1)  //计数器计数高电平
			begin
				clk_out <= 1'b1;  //产生高电平
				count <= count + 1'b1;
			end
			else
			begin
				count <= 1'b0;
				state <= 1;clk_out <= 1'b0;
			end
	end
	s1:
	begin
		if(LW + 1 > 1)  //判断是否 LW 为 0
			if(count < LW - 1)  //计数器计数低电平
			begin
				clk_out <= 1'b0;    //产生低电平
				count <= count + 1'b1;
			end
			else
			begin
				count <= 1'b0;
				state <= 0;clk_out <= 1'b1;
			end
	end
	default:state <= 0;
	endcase

endmodule

测试模块:

`timescale 1ns/1ps

module freq_divider_tb();

reg clk;
reg rst_n;
wire clk_out;       //定义输出为 wire 型

parameter HW = 5;
parameter LW = 5;

initial begin
	clk = 1'b1;
	rst_n = 1'b0;
	#200 rst_n = 1'b1;
	#2000 $stop;
end

always #10 clk = ~clk;    //产生 50M 时钟

freq_divider #(.HW(HW),.LW(LW))   //例化,我们可以在这里改变占空比, 和频率

freq_divider_dut(

.clk(clk),
.rst_n(rst_n),
.clk_out(clk_out)
);

endmodule

do 文件:

vlib work
vmap work work
vlog -novopt -incr -work work "../freq_divider.v"
vlog -novopt -incr -work work "../freq_divider_tb.v"
vsim -novopt work.freq_divider_tb -L altera_mf  -t 1ns 
add wave -noupdate /freq_divider_tb/clk
add wave -noupdate /freq_divider_tb/rst_n
add wave -noupdate /freq_divider_tb/clk_out


run 2000

仿真图:

FPGA实现任意分频系数和占空比的时钟频率输出
图 3 FPGA 实现任意分频器仿真波形

图中通过数上升沿的个数可以看到输出 clk0 的输出为高 5,低 5,符合 FPGA 实现任意分频器设计预期。

扫码关注尚为网微信公众号

尚为网微信公众号
每天学习电路设计嵌入式系统的专业知识,关注一波,没准就用上了。

原创文章,作者:sunev,如若转载,请注明出处:https://www.sunev.cn/embedded/928.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2021年3月6日 17:10
下一篇 2021年3月10日 15:30

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注