【FPGA】【入门基础】三、调用IP内核——PLL

内核创建

首先根据自己的板子型号创建好一个工程,然后点击 IP Catalog 再点击图片高亮处:
在这里插入图片描述
在最上面给创建的内核起个名字,然后最下面根据自己板子上的晶振填写,其余默认即可。比如以下图片:命名:ip_pll 晶振:50MHz
在这里插入图片描述
点击 Output Clocks 进行输出时钟的配置,在此我配置了两个时钟信号,二倍频(100MHz)和二分频(25MHz):
在这里插入图片描述
右边还有相位,占空比的配置,在此不做配置,直接点击ok即可。
随后IP就已经创建完毕了,位置在此处:
在这里插入图片描述
点击如下文件:
在这里插入图片描述
此处就是我们需要在自己的.v文件里调用的:在这里插入图片描述
注意:蓝色字体处也是需要改动的,详细请看下面介绍的.v文件

代码

.v文件:

`timescale 1ns / 1ps

module pll(
    input  wire sys_clk ,  // 系统时钟输入
    input  wire rst_n   ,  // 复位信号

    output reg  [1:0]  led // led输出信号
);

// 计数器计数最大值
parameter  CNT_MAX = 50_000_000 - 1;

// 定义两个28位的计数器   可用计数器算出计数最大值对应的二进制位数 
reg [27:0] timer1;
reg [27:0] timer2;

// 二倍频(100M) 二分频(25M) 输出时钟信号 
wire clk_mul_2 ;
wire clk_div_2 ;
wire locked ;

// 二倍频计数器
always @( posedge clk_mul_2 or negedge rst_n )begin
    if( rst_n == 1'b0 )begin
         timer1 <= 1'd0;
    end
    else if( locked == 1'b1 )begin
        if( timer1 == CNT_MAX )
             timer1 <= 1'd0;
        else
            timer1 <= timer1 + 1'b1;
    end
    else begin
         timer1 <= 1'd0;
    end
end

// 二分频计数器
always @( posedge clk_div_2 or negedge rst_n )begin
    if( rst_n == 1'b0 )begin
        timer2 <= 1'd0;
    end
    else if( locked == 1'b1 )begin
        if( timer2 == CNT_MAX )
             timer2 <= 1'd0;
        else
            timer2 <= timer2  + 1'b1;
    end
    else begin
         timer2 <= 1'd0;
    end
end

// led0状态设置
always @( posedge clk_mul_2 or negedge rst_n )begin
        if( rst_n == 1'b0 )begin
             led[0] <= 1'b1;
        end
        else if( timer1 == CNT_MAX )begin
             led[0] <= ~led[0];
        end
        else begin
             led[0] <= led[0];
        end
 end

// led1状态设置
always @( posedge clk_div_2 or negedge rst_n )begin
        if( rst_n == 1'b0 )begin
             led[1] <= 1'b1;
        end
        else if( timer2 == CNT_MAX )begin
             led[1] <= ~led[1];
        end
        else begin
             led[1] <= led[1];
        end
 end

// 调用创建的ip_pll
ip_pll ip_pll_inst(
        .clk_in1(sys_clk),
        .clk_out1(clk_mul_2),
        .clk_out2(clk_div_2),
        .locked(locked),
        .reset(~rst_n)
);

endmodule

约束文件:

############## clock define##################
create_clock -period 20.000 [get_ports sys_clk]
set_property PACKAGE_PIN N18 [get_ports sys_clk]
set_property IOSTANDARD LVCMOS33 [get_ports sys_clk]

############## key define##################
set_property PACKAGE_PIN P16 [get_ports rst_n]
set_property IOSTANDARD LVCMOS33 [get_ports rst_n]

##############LED define##################
set_property PACKAGE_PIN P15 [get_ports {led[0]}]
set_property PACKAGE_PIN U12 [get_ports {led[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {led[*]}]

有这两个文件就可以生成bit文件了,实验结果为两个led灯以不同的频率进行闪烁。

仿真验证

以下进行仿真验证,仿真文件如下:

`timescale 1ns / 1ps

module tb_pll();

reg sys_clk ;
reg rst_n   ;

wire [1:0] led ;

initial begin
     rst_n = 1'b0;
     #10
     rst_n = 1'b1;
end

initial sys_clk = 1'b1;

always #10 sys_clk = ~sys_clk;

pll #( .CNT_MAX(10) ) t_pll(
    .sys_clk (sys_clk ),
    .rst_n   (rst_n ),
    .led     (led )
);

endmodule

仿真结果:
在这里插入图片描述
两个led闪烁周期差了四倍,验证成功。

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值