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

news2024/9/20 17:53:31

文章目录

  • 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) begin
        if (!rst_n) begin
            cnt <= 'b0;
        end else if (cnt == CLK_CNT_TH - 1'b1) begin
            cnt <= 'b0;
        end else begin
            cnt <= cnt + 1'b1;
        end
    end

    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            div_clk <= 1'b0;
        end else if (cnt == CLK_CNT_TH - 1'b1) begin
            div_clk <= ~div_clk;
        end
    end

    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            clk_rst_cnt <= 'b0;
        end else if (clk_rst_cnt < CLK_RST_CNT) begin
            clk_rst_cnt <= clk_rst_cnt + 1'b1;
        end else begin
            clk_rst_cnt <= clk_rst_cnt;
        end
    end

    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            div_resetn <= 1'b0;
        end else if (clk_rst_cnt == CLK_RST_CNT - 1'b1) begin
            div_resetn <= 1'b1;
        end else begin
            div_resetn <= div_resetn;
        end
    end

endmodule

PS 端代码如下

#include "stdio.h"
#include "xclk_wiz.h"
#include "xil_printf.h"

#define CLOCK_WIZARD_DEVICE_ID	XPAR_CLK_WIZ_0_DEVICE_ID

int 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_BASEADDR

u32 XClk_Wizard_Reset(u32 DeviceBaseAddr);
u32 XClk_Wizard_Config(u32 DeviceBaseAddr);

int main()
{
    u32 Status;

    while (1)
    {
        // 使用默认配置,输出时钟均为 100MHz
        Status = XClk_Wizard_Reset(XCLK_WIZARD_BASEADDR);
        if (Status != XST_SUCCESS)
        {
            return Status;
        }
        xil_printf("[INFO] 100MHz\n");
        usleep(3 * 1000 * 1000);

        // 配置时钟 1 为 78MHz,时钟 2 为 169MHz
        Status = 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/SEN
    Xil_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.5
    Xil_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.coloradmin.cn/o/2130801.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python文件操作:上下文管理器(with语句)②

文章目录 1. 上下文管理器概述1.1 什么是上下文管理器&#xff1f;1.2 为什么使用上下文管理器&#xff1f;1.3 with语句的基本语法 2. 文件操作中的上下文管理器2.1 使用with语句打开文件2.2 读取文件2.2.1 读取整个文件内容2.2.2 逐行读取文件 2.3 写入文件2.3.1 覆盖写入2.3…

JavaWeb使用web.xml配置Servlet路径映射的相关操作以及易错问题分析与解决

前言 我们在使用Servlet创建JavaWeb项目时&#xff0c;想要绑定url路径和Servlet的映射关系&#xff0c;需要在web.xml中配置映射关系。Servlet从2.5版本开始支持注解。具体来说&#xff0c;Servlet 2.5引入了注解配置方式&#xff0c;使得Servlet应用程序的配置更加简单、灵活…

文档智能:OCR+Rocketqa+layoutxlm

此次先记录LayoutLMv2&#xff0c;梳理相关论文&#xff0c;记录如下&#xff1a; 首先认识一下 visually-rich document understanding tasks → \to → VrDU 其次&#xff0c;the text fields of interest&#xff0c;与图像识别的感兴趣区域 region of Interest 类似&…

MySQL数据的增删改查(一)

目录 新增&#xff08;create&#xff09; 插入单条记录 插入多条记录 查询&#xff08;retrieve&#xff09; 查询所有列 查询特定列 查询字段为表达式 别名 去重 排序 按单列排序 按多列排序 使用表达式或别名排序 排序NULL值 条件查询 比较运算符 逻辑运算…

双向dfs,多次dfs

前言&#xff1a;这个答案给我们提供了一种多次dfs的思路&#xff0c;记录queue的size&#xff0c;每次只取size个&#xff0c;就刚刚好只处理了上一次的‘ 题目地址 #include<bits/stdc.h> using namespace std;//定义队列节点 struct node {int x,y; }rear,front; //Q[…

Leetcode面试经典150题-350.两个数组的交集II

题目比较简单&#xff0c;散散心吧 这个题竟然是349更简单的版本&#xff0c;可以先看看349题的解法&#xff1a; Leetcode面试经典150题-349.两个数组的交集-CSDN博客 349会了&#xff0c;这个也就会了 解法都在代码里&#xff0c;不懂就留言或者私信 class Solution {/…

C51单片机矩阵键盘输入数码管静态显示

【实验目的】 学会矩阵键盘的检测&#xff0c;掌握数码管静态显示原理。 【实验现象】 依次按下4*4矩阵键盘上从第1到第20个键&#xff0c;同时在六位数码管上依次显示0、1、2、3、4、5、6、7、8、9、A、B、C、D、E、F。 【实验说明】 本开发板上数码管为共阴极。静态数码管显示…

R与机器学习系列|15.可解释的机器学习算法(Interpretable Machine Learning)(下)

今天我们介绍可解释机器学习算法的最后一部分&#xff0c;基于XGBoost算法的SHAP值可视化。关于SHAP值其实我们之前的很多个推文中都介绍到&#xff0c;不论是R版本的还是Python版本的&#xff0c;亦不论是普通的分类问题还是生存数据模型的。在此推文中我们将基于XGBoost模型理…

付费进群付费入群流量掘金入群系统九牧云版源码系统搭建

适用于各类资源类付费进群领取&#xff0c;私域类项目经营等 简洁大气直观。流量掘金类必备。 前端展示视频&#xff1a; https://pan.baidu.com/s/1lqyGCOrfmE4LDXb1cm-eDQ?pwdvnk6 https://yun.ktbf.xyz/s/by6jIzghpb 大致功能&#xff1a; 支持域名防红模式 支持对接…

QT+OSG+OSG-earth如何在窗口显示一个地球

1、环境配置 系统&#xff1a;windows10系统 QT:版本5.15.2 编译器&#xff1a;MSVC2019_64bit 编辑器&#xff1a;QT Creator OSG版本&#xff1a;3.7.0 64位 为MSVC环境下编译 osgQt:为第三方编译的库&#xff0c;OSG因为版本不同已经不提供osgQt的…

【一文就懂】计算机视觉期刊和会议缩写

下面IEEE相关的期刊及其缩写&#xff0c;并重新整理为期刊和会议两个部分。 期刊缩写 期刊全称缩写IEEE Transactions on Pattern Analysis and Machine IntelligenceIEEE Trans. Pattern Anal. Mach. Intell.IEEE Transactions on Image ProcessingIEEE Trans. Image Proce…

用于大数据分析的数据存储格式:Parquet、Avro 和 ORC 的性能和成本影响

高效的数据处理对于依赖大数据分析做出明智决策的企业和组织至关重要。显著影响数据处理性能的一个关键因素是数据的存储格式。本文探讨了不同存储格式&#xff08;特别是 Parquet、Avro 和 ORC&#xff09;对 Google Cloud Platform &#xff08;GCP&#xff09; 上大数据环境…

机器学习--支持向量机(SVM)

支持向量机(线性) S V M SVM SVM 引入 S V M SVM SVM 用于解决的问题也是 c l a s s i f i c a t i o n classification classification&#xff0c;这里 y ∈ { − 1 , 1 } y \in \{-1, 1\} y∈{−1,1} 比如说这样一个需要分类的训练数据&#xff1a; 我们可以有很多直线来…

Vue3 的 shallowRef 和 shallowReactive:优化性能

大家对 Vue3 的 ref 和 reactive 都很熟悉&#xff0c;那么对 shallowRef 和 shallowReactive 是否了解呢&#xff1f; 在编程和数据结构中&#xff0c;“shallow”&#xff08;浅层&#xff09;通常指对数据结构的最外层进行操作&#xff0c;而不递归地处理其内部或嵌套的数据…

Brave编译指南2024 Windows篇:安装Git(四)

1.引言 在编译Brave浏览器的过程中&#xff0c;Git是必不可少的工具之一。作为最流行的分布式版本控制系统&#xff0c;Git允许开发者高效地管理和协作开发源码。通过Git&#xff0c;您可以轻松获取、更新和提交Brave的源码版本&#xff0c;并跟踪所有更改记录。无论是独立开发…

大模型入门 ch 03:注意力机制

本文是github上的大模型教程LLMs-from-scratch的学习笔记&#xff0c;教程地址&#xff1a;教程链接 Chapter 3&#xff1a; Attention Mechanism 本文首先从固定参数的注意力机制说起&#xff0c;然后拓展到可以训练的注意力机制&#xff0c;然后加入掩码mask&#xff0c;最后…

基于 onsemi NCV78343 NCV78964的汽车矩阵式大灯方案

一、方案描述 大联大世平集团针对汽车矩阵大灯&#xff0c;推出 基于 onsemi NCV78343 & NCV78964的汽车矩阵式大灯方案。 开发板搭载的主要器件有 onsemi 的 Matrix Controller NCV78343、LED Driver NCV78964、Motor Driver NCV70517、以及 NXP 的 MCU S32K344。 二、开…

抖音微信超火国庆节国旗头像生成源码

源码介绍&#xff1a; 抖音微信超火国庆节国旗头像生成源码&#xff0c;静态页前端生成速度超快&#xff01;源码直接上传到服务器即可使用。 1、打开地址后点击上传->选一张你喜欢的头像->然后点右边箭头符合选款式->最后点保存头像->按照提示 2、保存到手机即…

开源多场景问答社区论坛Apache Answer本地部署并发布至公网使用

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

CCDO|数据跃动未来:首席数据官如何引领构建活数据引擎

在数字化浪潮汹涌澎湃的今天&#xff0c;数据已成为企业最宝贵的资产之一&#xff0c;它不仅记录着过去&#xff0c;更预示着未来的方向。随着大数据、人工智能、云计算等技术的飞速发展&#xff0c;数据的潜力被前所未有地激发&#xff0c;而首席数据官&#xff08;CDO&#x…