ZYNQ 入门笔记(二):动态时钟

文章目录

  • 1 概述
    • 1.1 DRP
    • 1.2 AXI4-Lite
  • 2 示例
    • 2.1 单时钟输出
    • 2.2 多时钟输出
  • 3 参考文档

1 概述

Clocking Wizard 可通过配置内部寄存器动态调整输出频率,配置接口可选 DRPAXI4-Lite,其中 AXI4-Lite 实际上是对 DRP 接口的封装

image-20240910111652989

1.1 DRP

通过 DRP 接口配置相较 AXI4-Lite 接口要繁琐很多,需要的读者可前往 XAPP888 查看

image-20240912163942182

1.2 AXI4-Lite

通过 AXI4-Lite 配置 Clocking Wizard 的流程如下

  1. 配置全局分频/倍频系数 DIVCLK_DIVDECLKFBOUT

    地址偏移寄存器名默认值读/写描述
    0x200Clock Configuration Register 00x0101_0A00RWBit[7:0] = DIVCLK_DIVDE
    Bit[15:8] = CLKFBOUT_MULT
    Bit[25:16] = CLKFBOUT_FRAC

    DIVCLK_DIVDE 和 CLKFBOUT 的取值范围如下,MMCM 具有更大范围的分频系数且支持小数倍频

    DIVCLK_DIVDECLKFBOUT
    PLL1-562-64
    MMCM1-1062.000-64.000

    CLKFBOUT 分为整数部分 (CLKFBOUT_MULT) 和小数部分 (CLKFBOUT_FRAC),其中小数部分 (CLKFBOUT_FRAC) 仅对 MMCM (E2/E4) 原语有效,即 MMCME3/PLL 原语 不支持小数倍频

    image-20240911121221116

    CLKFBOUT 的小数部分 (CLKFBOUT_FRAC) 取值范围 0-875(对应实际倍频值 0-0.875),步进为 125(对应实际倍频值 0.125)。假设倍频系数为 8.125,则整数部分 Bit[15:8] 位应设置为 8 = 0x8,小数部分 Bit[25:16] 设置为 125 = 0x7D

  2. 配置各个通道的分频系数 CLKOUTx_DIVDE,x 取值范围 0-6

    地址偏移寄存器名读/写描述
    0x208 + x * 12Clock Configuration Register
    (x * 3 + 2)
    RWBit[7:0] = CLKOUTx_DIVDE
    Bit[17:8] = CLKOUT0_FRAC_Divde

    例如 clkout3 的分频寄存器如下

    地址偏移寄存器名读/写描述
    0x208 + 3 * 12 = 0x22CClock Configuration Register 11RWBit[7:0] = DIVCLK_DIVDE

    各个通道的分频系数取值范围如下,其中 clkout0 支持小数分频,clkout1 - clkout6 仅支持整数分频

    clkout0clkout1 - clkout6
    PLL1-1281-128
    MMCM1.000-128.0001-128

    仅 MMCM (E2/E4) 原语支持小数分频,MMCME3/PLL 不支持

  3. 置位寄存器 23 中的 LOAD/SENSADDR 比特,将上述配置加载到内部寄存器

    • LOAD/SEN:加载时钟配置寄存器数据至内部寄存器,当动态配置完成且时钟锁定时该比特被置为 0
    • SADDR:若为 0 则加载 Clocking Wizard GUI 中的默认配置(上述配置无效),若为 1 则加载上述寄存器配置
    地址偏移寄存器名默认值读/写描述
    0x25CClock Configuration Register 230x0000_0000RWBit[0] = LOAD / SEN
    Bit[1] = SADDR

    若想恢复默认配置,可向寄存器 0x25C 写入 0x0000_0001

  4. 等待时钟锁定,对于非 VERSAL 系列可通过 SR 寄存器监测时钟状态

    地址偏移寄存器名默认值读/写描述
    0x4Status Register (SR)0x0000_0000RBit[0] = Locked

Xilinx 提供了一些库函数用来完成上述配置,其本质上是对上述寄存器读写的封装,下面介绍几个常用的函数

/*** @brief 查询时钟树配置* @param DeviceId 时钟树 ID * @return 时钟树配置,若不存在则返回 NULL*/
XClk_Wiz_Config *XClk_Wiz_LookupConfig(u32 DeviceId);/*** @brief 初始化时钟树* @param InstancePtr 时钟树句柄 * @param Config 时钟树配置* @param EffectiveAddr 时钟树基地址* @return 时钟树初始化成功返回 XST_SUCCESS,否则返回 XST_FAILURE*/
u32 XClk_Wiz_CfgInitialize(XClk_Wiz *InstancePtr, XClk_Wiz_Config *Config, UINTPTR EffectiveAddr);/*** @brief 设置时钟树输出频率,仅当时钟树只有 1 个时钟输出时有效,时钟树有多个输出时返回 XST_FAILURE。*        该函数底层通过遍历 DIVCLK_DIVDE、CLKFBOUT 和 CLKOUT0_DIVDE 获取时钟树配置,需要注意*        1. 仅遍历整数倍频系数*        2. 不保证输出时钟与设置完全一致,两者的误差保存在 InstancePtr->MinErr 中* @param InstancePtr 时钟树句柄* @param SetRate 输出时钟频率(MHz) * @return 设置成功返回 XST_SUCCESS,否则返回 XST_FAILURE*/
u32 XClk_Wiz_SetRate(XClk_Wiz *InstancePtr, u64 SetRate);/** * @brief 等待时钟锁定* @param InstancePtr 设备句柄* @return 时钟锁定返回 XST_SUCCESS,否则返回 XST_FAILURE*/
u32 XClk_Wiz_WaitForLock(XClk_Wiz *InstancePtr);

仅有单个时钟输出不需要小数倍频 时,使用上述库函数操作比较方便;如果需要 多个时钟输出输出频率较为复杂,建议首先在 Clocking Wizard 配置页面设置所需频率并记录相关参数,然后配置相关寄存器

image-20240912114144819

2 示例

下面演示两种常见的时钟动态配置示例

  1. 单个时钟输出且不需要小数分频
  2. 多个时钟输出

2.1 单时钟输出

输入为 300 MHz 差分时钟,输出单端时钟由 100 MHz 动态调整为 10 MHz

首先配置 Clocking Wizard 的原语为 MMCM,勾选 Dynamic Reconfig,设置 Dynamic Reconfig Interface 为 AXI4Lite

image-20240912161333705

为了直观感受时钟变化,将输出时钟分频 10_000_000 倍后连接至 LED,系统整体框图如下

image-20240912160128366

分频器代码如下

module div_clk #(parameter  DIVDE       = 32,parameter  RST_TIME    = 32,localparam CLK_CNT_TH  = (DIVDE >> 1),localparam CLK_RST_CNT = DIVDE * RST_TIME
) (input      clk,input      rst_n,output reg div_clk,output reg div_resetn
);reg [31:0] cnt;reg [31:0] clk_rst_cnt;always @(posedge clk or negedge rst_n) beginif (!rst_n) begincnt <= 'b0;end else if (cnt == CLK_CNT_TH - 1'b1) begincnt <= 'b0;end else begincnt <= cnt + 1'b1;endendalways @(posedge clk or negedge rst_n) beginif (!rst_n) begindiv_clk <= 1'b0;end else if (cnt == CLK_CNT_TH - 1'b1) begindiv_clk <= ~div_clk;endendalways @(posedge clk or negedge rst_n) beginif (!rst_n) beginclk_rst_cnt <= 'b0;end else if (clk_rst_cnt < CLK_RST_CNT) beginclk_rst_cnt <= clk_rst_cnt + 1'b1;end else beginclk_rst_cnt <= clk_rst_cnt;endendalways @(posedge clk or negedge rst_n) beginif (!rst_n) begindiv_resetn <= 1'b0;end else if (clk_rst_cnt == CLK_RST_CNT - 1'b1) begindiv_resetn <= 1'b1;end else begindiv_resetn <= div_resetn;endendendmodule

PS 端代码如下

#include "stdio.h"
#include "xclk_wiz.h"
#include "xil_printf.h"#define CLOCK_WIZARD_DEVICE_ID	XPAR_CLK_WIZ_0_DEVICE_IDint main()
{u32 Status;u32 XClk_Rate;XClk_Wiz XClk_Wiz;XClk_Wiz_Config *XClk_Wiz_Config;// 1.初始化时钟树XClk_Wiz_Config = XClk_Wiz_LookupConfig(CLOCK_WIZARD_DEVICE_ID);if (!XClk_Wiz_Config){xil_printf("[ERROR] Clocking wizard init failed, cannot find config\n");return XST_FAILURE;}Status = XClk_Wiz_CfgInitialize(&XClk_Wiz, XClk_Wiz_Config, XClk_Wiz_Config->BaseAddr);if (Status != XST_SUCCESS){xil_printf("[ERROR] Clocking wizard config failed\n");return Status;}// 2.设置输出时钟频率Status = XClk_Wiz_SetRate(&XClk_Wiz, 10);if (Status != XST_SUCCESS){xil_printf("[ERROR] Clocking wizard set rate failed\n");return Status;}// 3.加载配置到内部寄存器XClk_Wiz_WriteReg(XClk_Wiz_Config->BaseAddr, 0x0000025C, XCLK_WIZ_RECONFIG_LOAD | XCLK_WIZ_RECONFIG_SADDR);// 4.等待时钟锁定Status = XClk_Wiz_WaitForLock(&XClk_Wiz);if (Status != XST_SUCCESS){xil_printf("[ERROR] Clock wizard lock failed\n");return Status;}while (1){}return 0;
}

通过观察 LED 闪烁频率即可验证配置是否生效,通过示波器测量输出时钟频率

2.2 多时钟输出

输入为 300 MHz 差分时钟,通道 0 输出频率由 100 MHz 动态调整为 78 MHz,通道 1 输出频率由 100 MHz 动态调整为 169 MHz

首先配置 Clocking Wizard 的原语为 MMCM,勾选 Dynamic Reconfig,设置 Dynamic Reconfig Interface 为 AXI4Lite

image-20240912161338253

设置 clk_out1 为 78 MHz,clk_out2 为 169 MHz,在 MMCM Settings 页面查看相关配置

  • VCO 输出频率为 300 × 84.5 / 25 = 1014 MHz
  • 通道 0 输出频率为 VCO / 13 = 78 MHz,通道 1 输出频率为 VCO / 6 = 169 MHz

image-20240912161258361

为了直观感受时钟变化,将输出时钟分频 100_000_000 倍后连接至 LED,系统整体框图如下

image-20240912161733628

PS 端整体代码如下,频率调整部分在 XClk_Wizard_Config 函数中完成,其实就是按照 1.2 中的流程配置寄存器

#include "stdio.h"
#include "xclk_wiz.h"
#include "xil_printf.h"#define XCLK_WIZARD_BASEADDR XPAR_CLK_WIZ_0_BASEADDRu32 XClk_Wizard_Reset(u32 DeviceBaseAddr);
u32 XClk_Wizard_Config(u32 DeviceBaseAddr);int main()
{u32 Status;while (1){// 使用默认配置,输出时钟均为 100MHzStatus = XClk_Wizard_Reset(XCLK_WIZARD_BASEADDR);if (Status != XST_SUCCESS){return Status;}xil_printf("[INFO] 100MHz\n");usleep(3 * 1000 * 1000);// 配置时钟 1 为 78MHz,时钟 2 为 169MHzStatus = XClk_Wizard_Config(XCLK_WIZARD_BASEADDR);if (Status != XST_SUCCESS){return Status;}xil_printf("[INFO] 78MHz\n");usleep(3 * 1000 * 1000);}}u32 XClk_Wizard_Reset(u32 DeviceBaseAddr)
{if (!DeviceBaseAddr){return XST_FAILURE;}// 置位 LOAD/SENXil_Out32(DeviceBaseAddr + 0x25C, XCLK_WIZ_RECONFIG_LOAD);return XST_SUCCESS;
}u32 XClk_Wizard_Config(u32 DeviceBaseAddr)
{u32 Count;if (!DeviceBaseAddr){return XST_FAILURE;}// 设置全局分频系数 DIVCLK_DIVDE 为 25,全局倍频系数 CLKFBOUT_MULT 为 84.5Xil_Out32(DeviceBaseAddr + 0x200, (500 << 16) | (84 << 8) | 25);// 配置通道 0 的分频系数为 13(300 / 25 * 84.5 / 13 = 78MHz)// 配置通道 1 的分频系数为 6 (300 / 25 * 84.5 / 6  = 169MHz)Xil_Out32(DeviceBaseAddr + 0x208 + 0 * 12, 13);Xil_Out32(DeviceBaseAddr + 0x208 + 1 * 12,  6);// 将配置加载至内部寄存器Xil_Out32(DeviceBaseAddr + 0x25C, XCLK_WIZ_RECONFIG_LOAD | XCLK_WIZ_RECONFIG_SADDR);// 等待时钟锁定Count = 0;while (Count < 1000){if (Xil_In32(DeviceBaseAddr + 0x4) & XCLK_WIZ_LOCK){return XST_SUCCESS;}Count++;}return XST_FAILURE;
}

3 参考文档

[1] PG065. Clocking Wizard v6.0 LogiCORE IP Product Guide

[2] XAPP888. MMCM and PLL Dynamic Reconfiguration Application Note

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/422201.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

用RNN(循环神经网络)预测股票价格

RNN&#xff08;循环神经网络&#xff09;是一种特殊类型的神经网络&#xff0c;它能够处理序列数据&#xff0c;并且具有记忆先前信息的能力。这种网络结构特别适合于处理时间序列数据、文本、语音等具有时间依赖性的问题。RNN的核心特点是它可以捕捉时间序列中的长期依赖关系…

C2免杀--手工shellcode编译,shellcode免杀思路

前言 欢迎来到我的博客 个人主页:北岭敲键盘的荒漠猫-CSDN博客 本文主要整理C2免杀中 shellcode代码免杀的相关部分 shellcode概念 我们也不啰嗦&#xff0c;我直接直观的描述一下他。 他就是一串机器能运行的代码&#xff0c;但是他不是正统的python&#xff0c;c&#xff…

中伟视界:煤矿皮带运输机异物监测AI算法能检测哪几种异物,通过什么方式来判断异物?

在矿山运输系统中&#xff0c;运输皮带上可能出现各种异物&#xff0c;如大煤块、锚杆、钻杆、煤矸石、木板、铁棍等。这些异物会对运输系统造成损害&#xff0c;影响生产效率&#xff0c;甚至引发安全事故。为了实时监测并识别这些异物&#xff0c;现代技术采用AI算法进行分析…

QT串口读取Serial->readAll()踩过的坑

QT串口读取Serial->readAll接收不完全踩过的坑 Chapter1 QT串口读取Serial->readAll()踩过的坑坑一&#xff1a;坑二 Chapter2 [QT串口上位机BUG解决]json解析数据bug以及接收数据问题问题描述原因分析&#xff1a;解决方案&#xff1a;一、是数据采集端&#xff08;单片…

Go语言?IDEA能支持吗?增删查走起?

序&#xff1a; 最近突然身边突然开始冒出关于go语言的只言片语&#xff0c;很好奇这个go语言是怎么样的&#xff1f;这几天有空就会去网上浏览一遍各位大咖的简介。这边主要是已学习为目的&#xff0c;关键人家都说它好这边记录一下学习过程的进坑和爬坑过程供大家娱乐一下。…

OpenCV结构分析与形状描述符(8)点集凸包计算函数convexHull()的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 查找一个点集的凸包。 函数 cv::convexHull 使用斯克拉斯基算法&#xff08;Sklansky’s algorithm&#xff09;来查找一个二维点集的凸包&#…

视频回放 | DolphinDB 2024 年度峰会主会场演讲精彩回顾

9 月 6 日&#xff0c;“以实时&#xff0c;见未来” DolphinDB 2024 年度峰会在杭州成功举办。上午&#xff0c;DolphinDB 创始团队与技术团队分别从不同方面介绍了 DolphinDB 这一年来的创新和突破。没来到现场没关系&#xff0c;现在就为您送上全场完整视频回放~&#xff08…

Pyspark下操作dataframe方法(1)

文章目录 Pyspark dataframe创建DataFrame使用Row对象使用元组与scheam使用字典与scheam注意 agg 聚合操作alias 设置别名字段设置别名设置dataframe别名 cache 缓存checkpoint RDD持久化到外部存储coalesce 设置dataframe分区数量collect 拉取数据columns 获取dataframe列 Pys…

CnCrypt(磁盘加密工具绿色版是一款功能强大磁盘加密工具,供大家学习研究参考

CnCrypt(磁盘加密工具)特点 加密单个分区或整个硬盘,所有加密都是以分区为基础的 提供两级方案,以应对被强迫说出密码的情况(如抢劫。隐藏分区(覆盖式密码术,steganography)无法探测到CnCrypt 加密分区(加密数据会被认为是随机数据)。 CnCrypt(磁盘加密工具)特色 1、加密U…

ucx 编译安装检验方式备忘

1&#xff0c; 下载配置编译 预备依赖&#xff1a; sudo apt-get install valgrind sudo apt-get install libibverbs-dev librdmacm-dev 1.1 下载源码 git clone --recursive https://github.com/openucx/ucx.git cd ucx/ git checkout v1.16.0 git 下来的代码&#xff0c;…

《Diffusion Models Without Attention》CVPR2024

摘要 这篇论文探讨了在高保真图像生成领域&#xff0c;去噪扩散概率模型&#xff08;Denoising Diffusion Probabilistic Models, DDPMs&#xff09;的重要性。尽管DDPMs在捕捉复杂视觉分布方面表现出色&#xff0c;但在高分辨率图像生成上面临显著的计算挑战。现有的方法&…

Vue邮件发送:如何有效集成邮件发送功能?

vue邮件发送功能实现方法&#xff1f;Vue邮件发送性能怎么优化&#xff1f; 无论是用户注册验证、密码重置&#xff0c;还是通知提醒&#xff0c;邮件发送功能都能提供重要的支持。本文将详细探讨如何在Vue项目中有效集成邮件发送功能&#xff0c;确保邮件能够准确、及时地送达…

macos 系统文件操作时提示 Operation not permitted 异常解决方法 , 通过恢复模式 开启 /关闭 SIP方法

在macos系统中操作系统文件时提示 Operation not permitted 这个异常, 原因是因为在macos 10.11以上版本中默认启用了 SIP( System Integrity Protection )机制对系统文件进行保护, 要解决这个问题我们需要关机, 然后进入mac的恢复模式 : 在按电源键开机的同时, 一直按住 co…

【机器学习】马尔可夫随机场的基本概念、和贝叶斯网络的联系与对比以及在python中的实例

引言 马尔可夫随机场&#xff08;Markov Random Field&#xff0c;简称MRF&#xff09;是一种用于描述变量之间依赖关系的概率模型&#xff0c;它在机器学习和图像处理等领域有着广泛的应用 文章目录 引言一、马尔科夫随机场1.1 定义1.2 特点1.3 应用1.4 学习算法1.5 总结 二、…

UG/NX加载插件失败的原因汇总

在自己的电脑上运行得好好的插件&#xff0c;部署到客户的电脑上出现未注册的命令错误或者“未能加载图像”的错误 1.首先检查插件的所有依赖是否齐全&#xff0c;确保齐全 2.这个问题在网络上搜索一番&#xff0c;大多数都是不知所云&#xff0c;后来看到这一篇文章【UG二次…

C++的流提取(>>)(输入) 流插入(<<)(输出)

什么是输入和输出流 流提取&#xff08;<<&#xff09;(输入) 理解&#xff1a;我们可以理解为&#xff0c;输入到io流里面&#xff0c;比如是cin&#xff0c;然后从输入流中读取数据 流插入&#xff08;<<&#xff09;&#xff08;输出&#xff09; 理解&#xff…

直播相关02-录制麦克风声音,QT 信号与槽,自定义信号和槽

一 信号与槽函数 #include "mainwindow.h" #include <QPushButton> #include <iostream> using namespace std;//我们的目的是在 window中加入一个button&#xff0c;当点击这个button后&#xff0c;关闭 MainWindow 。 MainWindow::MainWindow(QWidget …

828华为云征文 | 华为云Flexus X实例上实现Docker容器的实时监控与可视化分析

前言 华为云Flexus X&#xff0c;以顶尖算力与智能调度&#xff0c;引领Docker容器管理新风尚。828企业上云节之际&#xff0c;Flexus X携手前沿技术&#xff0c;实现容器运行的实时监控与数据可视化&#xff0c;让管理变得直观高效。无论是性能瓶颈的精准定位&#xff0c;还是…

TS 常用类型

我们经常说TypeScript是JavaScript的一个超级 TypeScript 常用类型 TypeScript 是 JS 的超集&#xff0c;TS 提供了 JS 的所有功能&#xff0c;并且额外的增加了&#xff1a;类型系统 所有的 JS 代码都是 TS 代码 JS 有类型&#xff08;比如&#xff0c;number/string 等&…

客厅无主灯设计:灯位布局与灯光灯具的和谐搭配

在现代家居设计中&#xff0c;客厅作为家庭活动的中心区域&#xff0c;其照明设计的重要性不言而喻。无主灯设计以其灵活多变、氛围营造独特的优势&#xff0c;逐渐成为客厅照明的热门选择。然而&#xff0c;如何合理规划灯位布局&#xff0c;并科学搭配灯光与灯具&#xff0c;…