首页 > 其他分享 >08 FPGA多路分频器实验

08 FPGA多路分频器实验

时间:2023-12-29 11:12:02浏览次数:31  
标签:分频 分频器 FPGA clk 08 cnt else div2hz div3

软件版本:VIVADO2021.1

操作系统:WIN10 64bit

硬件平台:适用XILINX A7/K7/Z7/ZU/KU系列FPGA

登录米联客(MILIANKE)FPGA社区-www.uisrc.com观看免费视频课程、在线答疑解惑!

1 概述

在FPGA中,时钟分频是经常用到的。本节课讲解2分频、3分频、4分频和8分频的Verilog实现并且学习generate语法功能的应用,本文的重点是培养读者对于verilog基础编程的基本功掌握。

2 硬件电路分析

硬件接口和子卡模块请阅读"附录 1"

配套工程的 FPGA PIN 脚定义路径为 fpga_prj/uisrc/04_pin/ fpga_pin.xdc。

3 程序设计思路

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

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

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

对于这类基础简单的方案,笔者认为,大家学习主要缺少的是思路,所以我们直接拿程序来分析。

Clk_Divider.v文件

`timescale 1ns / 1ps

module Clk_Divider#

(

parameter DEBUG_ENABLE = 1'b1,

parameter REF_CLK      = 32'd50_000_000

)

(

input I_clk,

input  I_rst_n,

output O_div2,

output O_div3,

output O_div4,

output O_div8,

output O_div2hz

    );

 

//2分频代码:只要基于源时钟每个时钟的上升沿对O_div2_r寄存器取反    

reg O_div2_r;

always@(posedge I_clk)begin

    if(!I_rst_n)

        O_div2_r <= 1'b0;

    else

        O_div2_r <= ~O_div2_r;

end

 

//4分频和8分频代码:共同使用了div_cnt1计数器

//4分频就是对计数器在div_cnt1==2'b00或者div_cnt1==2'b10的时候对O_div4_r寄存器取反;

//而8分频是对div_cnt1==2'b00的时候对O_div8_r取反

reg [1:0] div_cnt1;

always@(posedge I_clk)begin

    if(!I_rst_n)

        div_cnt1 <= 2'b00;

    else

        div_cnt1 <= div_cnt1+1'b1;

end

 

reg O_div4_r;

reg O_div8_r;

always@(posedge I_clk)begin

    if(!I_rst_n)

        O_div4_r <= 1'b0;

    else if(div_cnt1==2'b00 || div_cnt1==2'b10)

        O_div4_r <= ~O_div4_r;

    else

        O_div4_r <= O_div4_r;

end

 

always@(posedge I_clk)begin

    if(!I_rst_n)

        O_div8_r <= 1'b0;

    else if(div_cnt1==2'b00)

        O_div8_r <= ~O_div8_r;

    else

        O_div8_r <= O_div8_r;

end

/*

3分频的本质是我们需要在每次1.5倍的时钟周期的时候实现3分频寄存器的翻转,但是我们无法直接实现1.5倍的分频。

因此采取分别采取2个计数器pos_cnt和neg_cnt,分别对上升沿和下降沿计数。计数周期是0-1-2,共计3个时钟周期。

我们取pos_cnt == 2'd1的时候O_div3_r0输出高电平,neg_cnt == 2'd1的时候O_div3_r1输出高电平。

由于O_div3_r0和O_div3_r1输出1个时钟的高电平,但是相位相差180°,因此只要执行O_div3 = O_div3_r0 | O_div3_r1运算,

就能实现1.5倍周期的输出高电平,那么剩余的1.5倍源时钟周期就是输出低电平了。

*/

reg [1:0] pos_cnt;

reg [1:0] neg_cnt;

always@(posedge I_clk)begin

    if(!I_rst_n)

        pos_cnt <= 2'b00;

    else if(pos_cnt == 2'd2)

        pos_cnt <= 2'b00;

    else

        pos_cnt <= pos_cnt + 1'b1;

end

 

always@(negedge I_clk)begin

    if(!I_rst_n)    

        neg_cnt <= 2'b00;

    else if(neg_cnt == 2'd2)

        neg_cnt <= 2'b00;

    else

        neg_cnt <= neg_cnt + 1'b1;

end

 

reg O_div3_r0;

reg O_div3_r1;

always@(posedge I_clk)begin

    if(!I_rst_n)

        O_div3_r0 <= 1'b0;

    else if(pos_cnt < 2'd1)

        O_div3_r0 <= 1'b1;

    else

        O_div3_r0 <= 1'b0;

end

 

always@(negedge I_clk)begin

    if(!I_rst_n)

        O_div3_r1 <= 1'b0;

    else if(neg_cnt < 2'd1)

        O_div3_r1 <= 1'b1;

    else

        O_div3_r1 <= 1'b0;

end

 

reg O_div2hz_r;

reg [25:0] div2hz_cnt;

 

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

always@(posedge I_clk)

begin

    if(!I_rst_n)

        div2hz_cnt <= 0;

    else if(div2hz_cnt < REF_CLK/4 - 1'b1)

        div2hz_cnt <= div2hz_cnt + 1'b1;

    else

        div2hz_cnt <= 0;

end

 

always@(posedge I_clk)

begin

    if(!I_rst_n)

        O_div2hz_r <= 0;

    else if(ms250_en)

        O_div2hz_r <= ~O_div2hz_r;

    else

        O_div2hz_r <= O_div2hz_r;

end

 

assign O_div2 = O_div2_r;

assign O_div3 = O_div3_r0 | O_div3_r1;

assign O_div4 = O_div4_r;

assign O_div8 = O_div8_r;

assign O_div2hz = O_div2hz_r;

 

generate  if(DEBUG_ENABLE == 1'b1) begin : debugcore

//添加ila IP ,Chipscope观察信号

ila_0 ila_0 (

    .clk(I_clk), // input wire clk

    .probe0(O_div2hz), // input wire [0:0]  probe0  

    .probe1({O_div2,O_div3,O_div4,O_div8}) // input wire [3:0]  probe1

);

end

Endgenerate

 

endmodule

  

代码解释:

2分频代码:

只要基于源时钟每个时钟的上升沿对o_div2_r寄存器取反

4分频和8分频代码

共同使用了div_cnt1计数器,4分频就是对计数器在div_cnt1==2'b00或者div_cnt1==2'b10的时候对div4_o_r寄存器取反;而8分频是对div_cnt1==2'b00的时候对o_div8_r取反

3分频代码:

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的时候o_div3_r1输出高电平。由于o_div3_r0和o_div3_r1输出1个时钟的高电平,但是相位相差180°,因此只要执行o_div3 =o_ div3_r0 | o_div3_r1运算,就能实现1.5倍周期的输出高电平,那么剩余的1.5倍源时钟周期就是输出低电平了。

2HZ分频代码:

和前面文章中的流水灯延迟控制的分频方法一样。

4 RTL仿真

4.1 添加仿真测试源码

仿真测试文件存放在工程目录uisrc\02_sim中,源码如下:

`timescale 1ns / 1ps

 

module Clk_Divider_Tb();

// Inputs

reg I_clk;

reg I_rst_n;

// Outputs

wire O_div2;

//wire div3_o;

wire O_div4;

wire O_div8;

wire O_div2hz;

 

// Instantiate the Unit Under Test (UUT)

Clk_Divider#(

.DEBUG_ENABLE(1'b0),

.REF_CLK(50000000)

)

Clk_Divider_inst

(

.I_clk(I_clk),

.I_rst_n(I_rst_n),

.O_div2(O_div2),

.O_div4(O_div4),

.O_div8(O_div8),

.O_div2hz(O_div2hz)

);

 

 

initial begin

// Initialize Inputs4

    I_clk= 0;

    I_rst_n = 0;

// Wait 100 ns for global reset to finish

    #100;

    I_rst_n=1;

end

always #10 I_clk =~I_clk;

 

endmodule

4.2 仿真结果

2分频、3分频、4分频、8分频

2HZ分频

5测试结果

5.1 在线逻辑分析仪

通过ila在线逻辑分析仪我们也能看出我们的2分频、4分频、8分频信号都分频成功

5.2 开发板现象

(该教程为通用型教程,教程中仅展示一款示例开发板的连接方式,具体连接方式以所购买的开发板型号以及结合配套代码管脚约束为准。)

请确保下载器和开发板已经正确连接,并且开发板已经上电。(注意JTAG端子不支持热插拔,而USB接口支持,所以在不通电的情况下接通好JTAG后,再插入USB到电脑,之后再上电,以免造成JTAG IO损坏)

 

如下图所示LED闪烁,闪烁频率2Hz

 

标签:分频,分频器,FPGA,clk,08,cnt,else,div2hz,div3
From: https://www.cnblogs.com/milianke/p/17934350.html

相关文章

  • 05 FPGA流水灯实验
    软件版本:VIVADO2021.1操作系统:WIN1064bit硬件平台:适用XILINXA7/K7/Z7/ZU/KU系列FPGA登录米联客(MiLianKe)FPGA社区-www.uisrc.com观看免费视频课程、在线答疑解惑!1概述本章课程以大家熟悉的流水灯为例子,详细讲解了VIVADO软件的使用,包括创建FPGA工程,编写Verilog代码,添加管......
  • 《FPGA原理和结构》——读书笔记
    最近做了一个关于FPGA的项目后,读了《FPGA原理和结构》这本书。主要梗概内容和想法如下。第一章:理解FPGA所需要的基础知识理解FPGA我们需要数电的组合逻辑、时序逻辑等内容的知识。FPGA(20世纪70年度发展起来的,因为其具有通过组合使用器件内大量的逻辑块来实现所需的电路,比以往侠......
  • FPGA处理编码信号进行毛刺滤波
    目录一、前言二、滤波算法三、代码设计一、前言在利用处理编码信号时,一般在较为理想的环境下可以很方便进行计算,判断等。但是由于有时候受到电磁干扰等环境因素,会导致编码信号产生毛刺等,这时候如果不对编码信号进行预处理而是直接进行边缘判断等操作则极容易导致错误,所以需要提......
  • DAC转化——FPGA驱动LTC1446
    目录一、前言二、结合LTC1446芯片手册分析三、Verilog代码与仿真四、总结一、前言最近在学习利用FPGA结合DAC芯片实现数模转换,在实验中选择的LTC1446这款芯片。接下来自己将结合芯片手册进行分析,并编写Verilog代码并进行仿真验证。二、结合LTC1446芯片手册分析首先从上述第......
  • FPGA驱动AD9240实现AD转换
    目录一、前言二、时序原理三、代码设计四、结果验证一、前言在做项目中,经常会用到AD转换模块。前段时间做毕业设计的时候需要用到FPGA驱动AD9240模块实现模拟数据的采集和转换,尽管相对来说AD9240算比较简单的驱动模块,但是也想记录下分析和设计过程。二、时序原理首先通过芯片......
  • 2080 Ti就能跑70B大模型,上交大新框架让LLM推理增速11倍
    原本需要一张16万元的80GA100干的活,现在只需要一张不到2万元的24G4090就够了!上海交大IPADS实验室推出的开源推理框架PowerInfer,让大模型推理速度加快了11倍。而且不用量化,就用FP16精度,也能让40B模型在个人电脑上运行;如果加入量化,2080Ti也能流畅运行70B模型。结合大模型的独特特......
  • class084 数位dp-上【算法】
    class084数位dp-上【算法】算法讲解084【必备】数位dp-上code1357.统计各位数字都不同的数字个数//统计各位数字都不同的数字个数//给你一个整数n,代表十进制数字最多有n位//如果某个数字,每一位都不同,那么这个数字叫做有效数字//返回有效数字的个数,不统计负数范围//测试......
  • 【PXIE301-208】基于PXIE总线架构的Serial RapidIO总线通讯协议仿真卡
    板卡概述PXIE301-208是一款基于3UPXIE总线架构的SerialRapidIO总线通讯协议仿真卡。该板卡采用Xilinx的高性能Kintex系列FPGA作为主处理器,实现各个接口之间的数据互联、处理以及实时信号处理。板卡支持4路SFP+光纤接口,支持一个PCIex8主机接口,板载1组独立的64位DDR3SDRAM大容......
  • 基于FPGA的图像差分运算及目标提取实现,包含testbench和MATLAB辅助验证程序
    1.算法运行效果图预览  2.算法运行软件版本matlab2022a 3.算法理论概述      基于FPGA(Field-ProgrammableGateArray)的图像差分运算及目标提取实现主要涉及图像处理、差分运算和目标提取等原理和数学公式。 一、图像处理原理       图像处理是......
  • 08.W3C performance api
    WebPerformanceWorkingGroupThemissionoftheWebPerformanceWorkingGroupistoprovidemethodstomeasureaspectsofapplicationperformanceofuseragentfeaturesandAPIs.Web性能工作组的使命是提供测量用户代理功能和AP!的应用程序性能方面的方法WebPerf......