赞
踩
片上资源的使用,或者说IP核的使用,是FPGA编程要学习的分量很重的一部分内容。 其中最常见的就要属PLL了,时钟是一切程序的基础。 PLL的时钟倍频功能是用户自己手撕代码无法实现的,但使用PLL IP核,几步简单的图像界面的操作就能个实现。本文的内容就是配置一个PLL IP核,并在我们的FPGA代码中调用。
目录
(Vivado 赛灵思)
我看的教程里面,那个兄弟是选的下面这个。 看来还是比较注重开发效率。
下面按照截图路径打开这个veo文件,学习如何在FPGA程序中例化IP核(有点像C++你创建了一个类,然后你实例化一个)。
现在咱们有3个不同频率的时钟了,我们用这三个时钟计数到同样的值,然后点灯。 就能看出时钟频率的区别。由于灯只有两个,所以实验分成了两次,一次是50MHz时钟和100MHz时钟的对比,一次是50MHz时钟和25MHz时钟的对比。
- `timescale 1ns / 1ps
-
- module pll(
- input wire clk ,
- input wire rst_n ,
- output wire [1:0] led
- );
-
- //==================================================================
- // Parameter define
- //==================================================================
-
- localparam CNT_MAX = 50_000_000 - 1;
-
-
- //==================================================================
- // Internal Signals
- //==================================================================
-
- // IP_PLL 输出信号引出
- wire clk_out1 ; // 注意,这里用的wire类型
- wire clk_out2 ;
- wire clk_out3 ;
- wire locked ;
-
- reg [31:0] timer1cnt ;
- reg [31:0] timer2cnt ;
- reg [31:0] timer3cnt ;
- reg [1:0] led_r ;
-
- assign led = ~led_r;
-
- IP_PLL inst_pll
- (
- .clk_out1(clk_out1), // output clk_out1 50MHz 0
- .clk_out2(clk_out2), // output clk_out2 100MHz 90
- .clk_out3(clk_out3), // output clk_out3 25MHz 0
- .reset(~rst_n), // input reset 默认高有效,我们的复位信号是低有效,遂取反
- .locked(locked), // output locked
- .clk_in1(clk) // input clk_in1 我们的输入时钟信号是clk
- );
-
- //----------------------------- clk_out1 and timer1cnt and locked -----------------------------
- always @(posedge clk_out1 or negedge rst_n) begin
- if (rst_n == 1'b0) begin
- timer1cnt <= 'd0;
- end
- else if (locked == 1'b1) begin
- if (timer1cnt == CNT_MAX) begin
- timer1cnt <= 'd0;
- end
- else begin
- timer1cnt <= timer1cnt + 1'b1;
- end
- end
- else begin
- timer1cnt <= 'd0;
- end
- end
- //----------------------------- clk_out2 and timer2cnt and locked -----------------------------
- always @(posedge clk_out2 or negedge rst_n) begin
- if (rst_n == 1'b0) begin
- timer2cnt <= 'd0;
- end
- else if (locked == 1'b1) begin
- if (timer2cnt == CNT_MAX) begin
- timer2cnt <= 'd0;
- end
- else begin
- timer2cnt <= timer2cnt + 1'b1;
- end
- end
- else begin
- timer2cnt <= 'd0;
- end
- end
- //----------------------------- clk_out3 and timer3cnt and locked -----------------------------
- always @(posedge clk_out3 or negedge rst_n) begin
- if (rst_n == 1'b0) begin
- timer3cnt <= 'd0;
- end
- else if (locked == 1'b1) begin
- if (timer3cnt == CNT_MAX) begin
- timer3cnt <= 'd0;
- end
- else begin
- timer3cnt <= timer3cnt + 1'b1;
- end
- end
- else begin
- timer3cnt <= 'd0;
- end
- end
- //----------------------------- clk_out1 led -----------------------------
- always @(posedge clk_out1 or negedge rst_n) begin
- if (rst_n == 1'b0) begin
- led_r[0] <= 1'b0;
- end
- else if (timer1cnt == CNT_MAX) begin
- led_r[0] <= ~led_r[0];
- end
- else begin
- led_r[0] <= led_r[0];
- end
- end
-
-
- // //----------------------------- clk_out2 led -----------------------------
- // always @(posedge clk_out2 or negedge rst_n) begin
- // if (rst_n == 1'b0) begin
- // led_r[1] <= 1'b0;
- // end
- // else if (timer2cnt == CNT_MAX) begin
- // led_r[1] <= ~led_r[1];
- // end
- // else begin
- // led_r[1] <= led_r[1];
- // end
- // end
-
- //----------------------------- clk_out3 led -----------------------------
- always @(posedge clk_out3 or negedge rst_n) begin
- if (rst_n == 1'b0) begin
- led_r[1] <= 1'b0;
- end
- else if (timer3cnt == CNT_MAX) begin
- led_r[1] <= ~led_r[1];
- end
- else begin
- led_r[1] <= led_r[1];
- end
- end
-
- endmodule
在代码中,应该重点关注IP核是如何被调用(例化)的,同时注意例化时,填写的输入输出。 另外,在使用IP核输出的时钟信号计数时,我们同时使用了locked信号,这一点请不要忽略。
- create_clock -period 20.000 [ get_ports clk ]
-
- set_property PACKAGE_PIN N18 [ get_ports clk ]
- set_property PACKAGE_PIN P15 [ get_ports {led[0]} ]
- set_property PACKAGE_PIN U12 [ get_ports {led[1]} ]
- set_property PACKAGE_PIN T12 [ get_ports rst_n ]
-
- set_property IOSTANDARD LVCMOS33 [ get_ports clk ]
- set_property IOSTANDARD LVCMOS33 [ get_ports {led[*]} ]
- set_property IOSTANDARD LVCMOS33 [ get_ports rst_n ]
PLL_RUN1
左边的灯闪1次,右边的灯闪2次。 左边灯用的是50MHz时钟,右边灯用的100MHz时钟
PLL_RUN2
左边的灯闪2次,右边的灯闪1次。 左边灯用的是50MHz时钟,右边灯用的25MHz时钟
相似内容,参考:IP核简介及PLL_IP核的调用-CSDN博客
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。