kevinc

主攻ZYNQ及RTOS开发,关注Flash存储

vivado中通过AXI配置可调时钟输出

1
阅读(9817)

项目需要:实现一个可调的时钟,来探测实验对象的速率边界。范围1mhz-50mhz。

现在时钟的产生一般都是PLL(Phase Locked Loop)实现的。锁相环通常由鉴相器(PD)、环路滤波器(LF)和压控振荡器(VCO)三部分组成。模拟电路实现的APLL,频率可以做到很高,但是控制jitter等参数比较困难;现在的DPLL数字锁相环,可以很容易用fpga来实现。


在xilinx的IP catalog中找到Clocking Wizard,能实现高达800mhz的输出。勾选其中的Dynamic Reconfig后,还可以实现通过AXI-Lite接口控制参数来调整clock输出频率。

https://www.xilinx.com/support/documentation/ip_documentation/clk_wiz/v5_3/pg065-clk-wiz.pdf

https://www.xilinx.com/support/documentation/application_notes/xapp888_7Series_DynamicRecon.pdf




第一部分:实现原理

输入时钟经过一个分频D(一般都是1),再经过PLL后输出VCO主频时钟,在各个输出口进行分频。

比如主频是1000mhz,分频30,得到33.33mhz。

blob.png


第二部分:内部结构分析

blob.png

核心在于primitive原语:可以选择用MMCM或者PLL结构实现clock,内部参数都可以config。

MMCM(Mixed-Mode Clock Manager),PLL(Phase-Locked Loop)

blob.png

到底选择MMCM还是PLL取决于你的项目需求,其实就是对这些可配置参数的需求。

比如,我需要Dynamic Config功能,同时要出2路clk,那么选择PLL模式明显会减少资源占用。

如果资源足够,选择MMCM可以出更多路的clock。


第三部分:控制方式

blob.png

我们可以通过AXI控制外侧的regs来间接修改clk参数,也可以用AXI控制DRP接口然后直接控制primitive内部的regs。配置界面的Write DRP registers就是通过DRP接口直写primitive registers,这种选择会避免使用DSP资源,比默认方式更节省资源。

Config Regs分为三类:系统regs,外侧DRR,以及内部primitive Regs。

0x00

blob.png

0x200

blob.png

0x300

blob.png


第四部分:具体实现

在IP GUI里面选择:PLL,Dynamic Reconfig,AXI4Lite,Write DRP registers;

blob.png

输出两路时钟20mhz, 40mhz

blob.png

输入时钟是50mhz,倍频20,那么VCO出来的平台时钟是1000mhz

blob.png

在DRP Registers页,能看到各DRP feature数值

blob.png

任意分频的方式就是去count这个1000m的VCO时钟。HIGH time高占空个数 + LOW time低占空个数 = 周期(即频率)。比如我要出个33.33mhz的频率,那个1000mhz/33.33mhz=30,我们设置HIGH=15,LOW=15

000-1-001111-001111即数值0x13CF。

blob.pngxapp888

根据pg065手册p55,我们只需要写两个数值:

BASE_ADDR+0x304 = 0x000013CF; //

BASE_ADDR+0x35C = 0x00000003; //set the LOAD and SEN bits

delay(1); // 等稳定

设置完成!

结束!


--------------------------------------------分割线------------------------------------------------

补充:配置AXI4Lite控制0x200寄存器的方式

假设我的input clock是50mhz,想要输出clkout1=33.33mhz。方式是先2倍频到100mhz,然后3分频。

(Page54)

1. Configure the Clock Configuration register 0 (Address: C_BASEADDR + 0x200) with 0x00000201.

Writing this value sets DIVCLK_DIVIDE value to 1 and CLKFBOUT_MULT to 10.

分析:register0是用来设置core的平台时钟VCO,也是core里面最高的时钟,所有的clkout都是从这分出来的

公式:VCO Frequency = (Input Clock Frequency) * (CLKFBOUT_MULT) / DIVCLK_DIVIDE (Page53)

其中input clock是50Mhz,那么根据下面的寄存器说明,倍频2倍,没分频,即100mhz

2. Configure the Clock Configuration Register 2 (Address: C_BASEADDR + 0x208) with 0x00000003.

Writing this value sets CLKOUT0_DIVIDE to 3. The VCO frequency being 100 MHz, dividing it by CLKOUT0_DIVIDE will give the 33.33 MHz frequency on the clkout1 in the IP.

分析:后面的各子clkout只会从VCO分频出来,可以带小数,理论上能分出各种频率。这里是3分频出33.33mhz

3. Check for the Status register(Address: C_BASEADDR + 0x04) , if the status register value is 0x1, locked, then go to step 3.

分析:正常工作时是1,正在cfg时是0.

4. Configure the Clock Configuration Register 23 (Address: C_BASEADDR + 0x25C) with 0x00000003 to set the LOAD and SEN bits.

分析:这一步其实是一个统一update的操作。(肯定不能写一个更新一个 会出大bug)

5. Check for the Status register, wait for the locked signal, value is 0x1. The new frequency can be checked at clkout1 output port.

分析:这个locked能不能作为后端逻辑的reset信号?毕竟cfg clk的时候程序有可能会跑飞了。有可能吗?

Note: You can reset to the default settings by configuring the Clock Configuration Register 23

(Address: C_BASEADDR + 0x25C) with the value 0x00000001.

分析:VCO是有范围的,超出了就没法实现了。出错了建议退回default cfg。

(Page16) - Register Space

blob.png

blob.png

blob.png

blob.png

1、clock切换时,logic状态会不会跑偏?

个人认为,逻辑电路分为时序和组合,组合跟时钟没关系,时序都是在clk控制下,从一个clk切换到另一个clk,理论上各block仍然是在clk的边沿变化的,不会导致错乱。

如果担心这个问题,建议将PLL模块的locked信号引入logic作为一种reset条件。locked正常为1,时钟切换时为0.

2、逻辑资源占用问题

从pg065手册上列举的数据来看,AXI4Lite实现的PLL会占用较多的DSP资源,可以通过DRP方式不用DSP。待仔细研究......

blob.png

Write DRP Feature

The main advantage of this feature is to avoid the usage of DSP’s in the core. This option can be selected in the Dynamic Reconfiguration mode and valid only for AXI4 Lite interface.This feature allows you to write directly to the primitive registers through AXI


Baidu
map