FPGA分频器

1、 整数倍分频为 2、 4、 8, 这种 2^n 次方倍数关系的分频最容易实现, 所以我们可以把这 3 种分频方式归为一类。

2、 3 分频是奇数倍分频, 这种分频比较麻烦, 对于初学者肯定得思考一番。

3、 2HZ 和前文中流水灯的延迟控制方法一样, 只要实现每过 500ms 对寄存器取反操作

复制代码
// -----------------------------------------------------------------------------
// Copyright (c) 2014-2026 All rights reserved
// -----------------------------------------------------------------------------
// Author : lvjitao lvjitao_o@163.com
// File   : Clk_Divider.v
// Create : 2026-03-14 14:36:38
// Revise : 2026-03-14 15:58:50
// Editor : sublime text3, tab size (4)
// -----------------------------------------------------------------------------
`timescale  1ns/1ps


module Clk_Divider#(
	parameter	Debug_Enble	=	1'b1,
	parameter	Ref_clk		=	32'd100000000
	)

(
	input	wire	clk_i,
	input	wire	rst_n_i,
	output	reg		div2_o,
	output	reg		div3_o,
	output	reg		div4_o,
	output	reg		div8_o,
	output	reg		div2hz_o

    );


//2分频

reg	div2_cnt;
always @(posedge clk_i or negedge rst_n_i) begin
	if(~rst_n_i) begin
		div2_cnt <= 0;
	end 
	else begin
		div2_cnt <= ~div2_cnt;
	end
end

//4\8分频计数器

reg[1:0]	div4_8_cnt;

always @(posedge clk_i or negedge rst_n_i) begin 
	if(~rst_n_i) begin
		div4_8_cnt <= 0;
	end else begin
		div4_8_cnt <= div4_8_cnt + 1'b1;
	end
end

//4,8fanzhuang
reg	div4_cnt;
reg div8_cnt;

always @(posedge clk_i or negedge rst_n_i) begin : proc_
	if(~rst_n_i) begin
		div4_cnt <= 0;
		div8_cnt <= 0;
	end else if (div4_8_cnt == 2'b00 || div4_8_cnt == 2'b10) begin
		div4_o <= ~div4_o;
	end
	else if (div4_8_cnt == 2'b00) begin
		/* code */
		div8_o <= ~div8_o;
	end
	else begin
		div8_o <= div8_o;
		div4_o <= div4_o;
	end
end


//3 分频的本质是我们需要在每次 1.5 倍的时钟周期的时候实现 3 分频寄存器的翻转, 但是我们无法直接实现 1.5 倍的分频。
//因此采取分别采取 2 个计数器 pos_cnt 和 neg_cnt, 分别对上升沿和下降沿计数。 计数周期是 0-1-2, 共计 3 个时钟周期。
//我们取 pos_cnt == 2'd1 的时候 div3_o_r0 输出高电平, neg_cnt == 2'd1 的时候 div3_o_r1 输出高电平。
//由于 div3_o_r0 和 div3_o_r1 输出 1 个时钟的高电平, 但是相位相差 180°, 
//因此只要执行 div3_o = div3_o_r0 | div3_o_r1运算,就能实现 1.5 倍周期的输出高电平, 那么剩余的 1.5 倍源时钟周期就是输出低电平了。

reg [1:0]	pos_cnt;
reg [1:0]	neg_cnt;

always @(posedge clk_i or negedge rst_n_i) begin 
	if(~rst_n_i) begin
		pos_cnt <= 'd0;
	end else if(pos_cnt == 2'd2) begin
		pos_cnt <= 2'b00;
	end
	else begin
		pos_cnt <= pos_cnt + 1'b1;
	end
end

always @(posedge clk_i or negedge rst_n_i) begin
	if(~rst_n_i) begin
		neg_cnt <= 'd0;
	end else if(neg_cnt == 2'd2) begin
		neg_cnt <= 2'b00;
	end
	else begin
		neg_cnt <= neg_cnt + 1'b1;
	end
end


reg div3_o_r0;
reg div3_o_r1;

always @(posedge clk_i or negedge rst_n_i) begin 
	if(~rst_n_i) begin
		div3_o_r0 <= 0;
	end else if(pos_cnt <2'd1) begin
		div3_o_r0 <= 1'b1;
	end
	else
		div3_o_r0 <= 1'b0;
end

always @(posedge clk_i or negedge rst_n_i) begin 
	if(~rst_n_i) begin
		div3_o_r1 <= 0;
	end else if(neg_cnt < 2'd1) begin
		div3_o_r1 <= 1'b1;
	end
	else 
		div3_o_r1 <= 1'b0;
end

reg 		div2hz_o_r;
reg [25:0]	div2hz_cnt;

wire ms250_en = (div2hz_cnt == Ref_clk/4 - 1'b1);

always @(posedge clk_i or negedge rst_n_i) begin 
	if(~rst_n_i) begin
		div2hz_cnt <= 0;
	end else if(div2hz_cnt < Ref_clk/4 - 1'b1) begin
		div2hz_cnt <= div2hz_cnt + 1'b1;
	end
	else
		div2hz_cnt <= 0;
end

always @(posedge clk_i or negedge rst_n_i) begin
	if(~rst_n_i) begin
		div2hz_o_r <= 0;
	end else if(ms250_en) begin
		div2hz_o_r <= ~div2hz_o_r;
	end
	else
		div2hz_o_r <= div2hz_o_r; 
end

assign div2_o = div2hz_o_r;
assign div3_o = div3_o_r0 | div3_o_r1;
assign div4_o = div4_cnt;
assign div8_o = div8_cnt;
assign div2hz_o = div2hz_o_r;

endmodule
相关推荐
上班最快乐1 天前
基于FPGA的APS6404L-3SQR QSPI PSRAM驱动设计(2)
fpga开发
FPGA-ADDA1 天前
第一篇:软件无线电(SDR)基础与FPGA的角色
fpga开发·fpga·数字电路·dsp·软件无线电
Fpga_User1 天前
基于Zynq UltraScale+的FLASH固化问题记录
嵌入式硬件·fpga开发
FPGA-ADDA1 天前
高速数据记录仪19EG_4NVME_EXT_V1.2存储板
fpga开发·fpga·高速存储·mpsoc·大容量存储
Saniffer_SH1 天前
【每日一题】PCIe链路协商的时候进入Polling compliance如何排错?
服务器·人工智能·驱动开发·嵌入式硬件·测试工具·fpga开发·自动化
亮锅锅来啦1 天前
Synplify_2023综合时报错clk_out is not input pin
fpga开发
浩子智控1 天前
航天高可靠性设备开发—抗辐射
嵌入式硬件·fpga开发·硬件工程
XPii1 天前
FPGA工程师面试资料【1】
fpga开发·面试·职场和发展
沐欣工作室_lvyiyi2 天前
基于FPGA的电容测试仪设计与实现(论文+源码)
fpga开发·毕业设计·电容测试仪·电阻电容电感测试