FPGA_学习_10_IP核_PLL

 

片上资源的使用,或者说IP核的使用,是FPGA编程要学习的分量很重的一部分内容。 其中最常见的就要属PLL了,时钟是一切程序的基础。 PLL的时钟倍频功能是用户自己手撕代码无法实现的,但使用PLL IP核,几步简单的图像界面的操作就能个实现。本文的内容就是配置一个PLL IP核,并在我们的FPGA代码中调用。

 

目录

1 PLL IP核配置步骤

2 测试代码

3 约束文件

4 运行结果


1 PLL IP核配置步骤

(Vivado 赛灵思)

 

 

我看的教程里面,那个兄弟是选的下面这个。 看来还是比较注重开发效率。

下面按照截图路径打开这个veo文件,学习如何在FPGA程序中例化IP核(有点像C++你创建了一个类,然后你实例化一个)。

2 测试代码

现在咱们有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信号,这一点请不要忽略。

3 约束文件

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		]  

4 运行结果

PLL_RUN1

左边的灯闪1次,右边的灯闪2次。  左边灯用的是50MHz时钟,右边灯用的100MHz时钟

PLL_RUN2

左边的灯闪2次,右边的灯闪1次。  左边灯用的是50MHz时钟,右边灯用的25MHz时钟

相似内容,参考:IP核简介及PLL_IP核的调用-CSDN博客

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

江湖上都叫我秋博

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值