FPGA_学习_10_IP核_PLL

1 PLL IP核配置步骤

(Vivado 赛灵思)

FPGA_学习_10_IP核_PLL_第1张图片

 FPGA_学习_10_IP核_PLL_第2张图片

 FPGA_学习_10_IP核_PLL_第3张图片

FPGA_学习_10_IP核_PLL_第4张图片

FPGA_学习_10_IP核_PLL_第5张图片

FPGA_学习_10_IP核_PLL_第6张图片

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

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

FPGA_学习_10_IP核_PLL_第7张图片

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时钟

你可能感兴趣的:(FPGA,fpga开发,学习)