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
相关推荐
LabVIEW开发12 小时前
LabVIEW振动信号采集分析
fpga开发·labview·labview知识·labview功能·labview程序
发光的沙子12 小时前
FPGA----vitis生成静态链接库
fpga开发
FPGA小迷弟12 小时前
FPGA工程师面试题汇总(二十四)
网络协议·tcp/ip·fpga开发·verilog·fpga
cici158741 天前
基于FPGA的任意四位除法器设计与实现
fpga开发
guygg882 天前
基于STM8S的FreeModbus协议移植指南
fpga开发
kanhao1002 天前
从 Vectorless 到 SAIF 再到板级实测:HLS Kernel 功耗估计全流程实战
嵌入式硬件·fpga开发
yongui478342 天前
基于FPGA的频率计与串口通信系统设计与实现
fpga开发
FPGA_ADDA2 天前
国产复旦微FPGA+DSP 6U VPX处理板
fpga开发·全国产·复旦微690t·ft6678dsp·6u vpx板卡·jfm7vx690t36
fengfuyao9852 天前
基于FPGA的简易电子密码锁设计(Verilog实现)
fpga开发
hoiii1872 天前
104键PS2接口标准键盘C语言驱动程序
c语言·fpga开发·计算机外设