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
相关推荐
长春的KAKA35 分钟前
Proxmark3 RDV4.01:Windows 11 下 Iceman 固件升级与完整使用指南
fpga开发
奋斗的阿狸_198616 小时前
ESP32-S3 + ES7210 四通道麦克风录音上传方案
c语言·开发语言·fpga开发
hahaha601616 小时前
FPGA+ARM实现AWB的全流程
人工智能·嵌入式硬件·算法·计算机视觉·fpga开发
unicrom_深圳市由你创科技20 小时前
板上调试,先抓哪些信号?排查顺序是什么?
fpga开发
北城笑笑1 天前
FPGA 55 ,FPGA 行业 2026 发展分析与报告
fpga开发·fpga
Jason_zhao_MR1 天前
新一代电能数据采集终端方案
linux·人工智能·嵌入式硬件·fpga开发·嵌入式
ERROR:992 天前
AMD Ross没有介入Vivado的私生活
fpga开发
Riwuarua2 天前
从近似 0 基础开始 FPGA 开发——Part.18:FPGA 复位系统与可靠启动设计
fpga开发
智感子3 天前
测控链路:从传感器到上位机
人工智能·嵌入式硬件·fpga开发
szxinmai主板定制专家4 天前
基于Zynq的高精度多通道数据采集卡完整解决方案(工业振动/高速采集/边缘传输)
fpga开发·zynq·数据采集卡