基于FPGA的IP核-PLL-基础篇

📅 2026/7/10 22:45:47
基于FPGA的IP核-PLL-基础篇
目录IP核的介绍(记优缺点)IP-PLL锁存器绘制模块框图建立工程,配置IP核调用my_pll模块编写仿真代码仿真验证小作业绘制模块框图编写模块代码编写仿真代码仿真验证IP核的介绍(记优缺点)随着CPLD/FPGA的规模越来越大设计越来越复杂IC的复杂度以每年55%的速率递增而设计能力每年仅提高21%设计者的主要任务是在规定的时间周期内完成复杂的设计。为了解决这一问题将一些在数字电路中常用但比较复杂的功能块如FIR滤波器、SDRAM控制器、PCI接口等设计成可修改参数的模块。这样可以避免重复劳动大大减轻工程师的负担提高开发效率大大缩短产品上市时间。IPIntellectual Property即知识产权。美国 Dataquest 咨询公司将半导体产业的 IP 定义为“用于ASIC或FPGA中的预先设计好的电路功能模块”。简而言之这里的IP即电路功能模块。IP核在数字电路中常用于比较复杂的功能模块如FIFO、RAM、FIR滤波器、SDRAM控制器、PCIE接口等设计成参数可修改的模块让其他用户可以直接调用这些模块。随着设计规模增大复杂度提高使用IP核可以提高开发效率减少设计和调试时间加速开发进程降低开发成本是业界的发展趋势。利用IP核设计电子系统引用方便修改基本元件的功能容易。具有复杂功能和商业价值的IP核一般具有知识产权尽管IP核的市场活动还不规范但是仍有许多集成电路设计公司从事 IP 核的设计、开发和营销工作。同一事物的利弊总是共存的IP 核在拥有以上众多好处的同时也有他的巨大缺点1、在跨平台时IP核往往不通用需要重新设计。IP核都是不全透明的是每个FPGA开发厂商根据自己芯片适配的定制IP所以如果你之前用的Xilinx的芯片用了一个PLL但是因为某些原因需要将代码移植到Altera平台上那就必须要将PLL给重新替换掉着增加了代码移植的复杂性。2、IP核就是个黑匣子是不透明的我们往往看不到其核心代码。IP核都是各大FPGA厂商专门设计的都会进行加密内核代码都看不到如果你使用的这个IP核万一出现了问题或者需要知道其内部结构针对具体的应用进行定制优化时你是无法进行修改的。以上两个问题就很棘手所以有些公司坚持所有的可综合设计都不使用IP核就是为了是所有的模块都能够掌控在在自己手里。3、有些定制的IP核由于是不通用的往往会有较高的收费这也是一笔巨大的开销。所以IP核在能够加快我们开发周期的情况下也存在以上三种常见的问题这就是需要我们权衡利弊针对具体的需求来做具体的选择。下面我们来使用IP核的PLL锁存器IP-PLL锁存器PLLPhase Locked Loop即锁相环是最常用的 IP 核之一其性能强大可以对输 入到 FPGA 的时钟信号进行任意分频、倍频、相位调整、占空比调整从而输出一个期望 时钟实际上即使不想改变输入到 FPGA 时钟的任何参数也常常会使用 PLL因为经 过 PLL 后的时钟在抖动Jitter方面的性能更好一些。Altera中的PLL是模拟锁相环和 数字锁相环不同的是模拟锁相环的优点是输出的稳定度高、相位连续可调、延时连续可 调缺点是当温度过高或者电磁辐射过强时会失锁普通环境下不考虑该问题。PLL大体的一个结构模型示意图我们可以看出这是一个闭环反馈系 统其工作原理和过程主要如下1、首先需要参考时钟ref_clk通过鉴频FD鉴相器PD鉴频鉴相器的英文为 Phase Frequency Detector缩写为 PFD和需要比较的时钟频 率进行比较我们以频率调整为例如果参考时钟频率等于需要比较的时钟频率则鉴频鉴 相器输出为 0如果参考时钟频率大于需要比较的时钟频率则鉴频鉴相器输出一个变大的 成正比的值如果参考时钟频率小于需要比较的时钟频率则鉴频鉴相器输出一个变小的正 比的值。2、鉴频鉴相器的输出连接到环路滤波器LF上用于控制噪声的带宽滤掉高频 噪声使之稳定在一个值起到将带有噪声的波形变平滑的作用。如果鉴频鉴相器之前的 波形抖动比较大经过环路滤波器后抖动就会变小趋近于信号的平均值。3、经过环路滤波器的输出连接到压控振荡器VCO上环路滤波器输出的电压可 以控制VCO输出频率的大小环路滤波器输出的电压越大VCO输出的频率越高然后将 这个频率信号连接到鉴频鉴相器作为需要比较的频率。如果 ref_clk 参考时钟输入的频率和需要比较的时钟频率不相等该系统最终实现的就 是让它们逐渐相等并稳定下来。如果 ref_clk 参考时钟的频率是 50MHz经过整个闭环反 馈系统后锁相环对外输出的时钟频率pll_out也是50MHz。那倍频是如何实现的呢如图 27-5 所示倍频是在 VCO后直接加一级分频器我们 知道 ref_clk 参考时钟输入的频率和需要比较的时钟频率经过闭环反馈系统后最终会保持频 率相等而在需要比较的时钟之前加入分频器就会使进入分频器之前的信号频率为需要 比较的时钟频率的倍数VCO后输出的 pll_out信号频率就是 ref_clk 参考时钟倍频后的结 果。分频又是如何实现的呢如图 27-6 所示分频是在 ref_clk 参考时钟后加一级分频 器这样需要比较的时钟频率就始终和 ref_clk 参考时钟分频后的频率相等在 VCO后输 出的pll_out信号就是ref_clk参考时钟分频后的结果。绘制模块框图建立工程,配置IP核建立完工程之后我需要做以下步骤最后点击Finish即可。完成my_pll的配置。调用my_pll模块module ip_pll( input wire clk , input wire rst_n , output wire c0 , output wire c1 , output wire c2 , output wire c3 , output wire c4 , output wire locked ); my_pll my_pll_inst ( .areset (~rst_n), .inclk0 (clk ), .c0 (c0 ), .c1 (c1 ), .c2 (c2 ), .c3 (c3 ), .c4 (c4 ), .locked (locked) ); endmodule编写仿真代码timescale 1ns/1ps module ip_pll_tb(); reg clk ; reg rst_n; wire c0 ; wire c1 ; wire c2 ; wire c3 ; wire c4 ; wire locked; initial begin clk 1b0; rst_n 1b0; #123 rst_n 1b1; end always #10 clk ~clk; ip_pll ip_pll_inst( .clk (clk ) , .rst_n (rst_n ) , .c0 (c0 ) , .c1 (c1 ) , .c2 (c2 ) , .c3 (c3 ) , .c4 (c4 ) , .locked (locked) ); endmodule仿真验证根据仿真波形图可知仿真通过。小作业绘制模块框图建立过程配置my_pll。编写模块代码顶层模块signaltap_sgdmodule signaltap_sgd( input wire clk , input wire rst_n , output wire led ); wire clk_100Mhz ; wire rst_n_100Mhz; my_pll my_pll_inst ( .areset ( ~rst_n ), .inclk0 ( clk ), .c0 ( clk_100Mhz ), .locked ( rst_n_100Mhz ) ); SGD #( .CNT_MAX ( 32d49_999_999 ) //0.5s ) SGD_inst ( .clk (clk_100Mhz ),//100Mhz,10ns .rst_n (rst_n_100Mhz), .led (led ) ); endmodule子功能模块SGDmodule SGD #(//parameter定义常量参数(多常量时,定义语句需要用,隔开) parameter CNT_MAX 32d49_999_999 //0.5s ) ( input wire clk ,//100Mhz,10ns input wire rst_n , output reg led ); //parameter CNT_MAX 22d24_999_999 ;//0.5s(全局参数) //localparam 本地参数(只供给本模块使用) reg [31:0] cnt; //cnt:0.5s循环计数器 always (posedge clk or negedge rst_n) begin if(!rst_n) cnt 32d0; else if(cnt CNT_MAX) //计数计满 cnt 32d0; //清零 else //计数未计满 cnt cnt 1b1; //自加计数 end //led:0.5s闪光灯(不能使用组合逻辑,因为不是一一对应的) always (posedge clk or negedge rst_n) begin if(!rst_n) led 1b0; else if(cnt CNT_MAX) led ~led; else led led; end endmodule编写仿真代码timescale 1ns/1ps module signaltap_sgd_tb(); reg clk ; reg rst_n; wire led ; initial begin clk 1b0; rst_n 1b0; #123 rst_n 1b1; end always #10 clk ~clk; signaltap_sgd signaltap_sgd_inst( .clk (clk ) , .rst_n (rst_n) , .led (led ) ); endmodule仿真验证这里使用signaltap抓取波形需要提前绑定引脚以下是采取的波形图。根据波形图验证通过。