当前位置:   article > 正文

Quartus基本IP核调用及仿真_quartus ip

quartus ip

一.PLL

PLL介绍

PLL全称Phase Locked Loop,也就是锁相环,是一种反馈控制电路。PLL对时钟网络进行系统级的时钟管理和偏移控制,具有时钟倍频、分频、相位偏移和可编程占空比的功能。PLL一般由模拟电路所实现。
在这里插入图片描述
PLL是FPGA重要的资源,不同FPGA的PLL 是不一样。以我们开发板的Cyclone IV为例,它有两个PLL,每个PLL可以提供5路输出。
PLL 的时钟输入可以是PLL 所在的 Bank 的时钟输入管脚或者其他 PLL 的输出,FPGA 内部产生的信号不能驱动PLL。Cyclone IV PLL 产生的时钟可以为单端时钟信号或差分时钟信号, 可以通过GCLK 网络直接驱动 FPGA 外部的 IO 口。

PLL的IP核调用

打开Quartus软件,新建一个项目后(命名为test_IP),在界面的最右侧,可以看见一个IP Catalog的栏目,在这里有很多的IP核可以供我们选择使用在这里插入图片描述
我们在这里需要选择PLL
在这里插入图片描述
资源比较多,可以在搜索栏搜索,双击选择ALTPLL后出现如下弹窗
在这里插入图片描述
点击…选择文件保存路径,这里使用我们创建工程文件夹里面的ip文件夹,将文件命名为pll.v,点击OK
在这里插入图片描述
我使用的是Cyclone IV系列的EP4CE6F17C8,只有一个50MHZ的晶振,时钟频率选择50MHZ就可以了,选择正常模式就可以了
在这里插入图片描述
选择创建一个’areset’输入异步重置锁相环
在这里插入图片描述
这一步默认就好了
在这里插入图片描述
Next
在这里插入图片描述
Next
在这里插入图片描述
原时钟频率为50MHZ,这里选择100MHZ,相当于把时钟倍频,占空比50%

在这里插入图片描述
第二个时钟,25MHZ,选择分频,且相位偏移90°,占空比50%
在这里插入图片描述
第三个时钟,5MHZ,占空比为25%
在这里插入图片描述
第四个时钟,先分频再倍频,75MHZ,占空比50%
这里只使用了4个时钟,第五个时钟不勾选
在这里插入图片描述
Next
在这里插入图片描述
选择生成pll_inst.v和pll_bb.v文件,点击Finish
现在PLL的相关资源已经添加到项目中了,在Quartus软件左侧选择IP Components就可以看见我们添加的pll了(其他IP核在后面介绍)
在这里插入图片描述

PLL仿真

我们可以自己编写例化
例如我们编写test_IP.v文件例化PLL模块

module test_IP(
    input           clk     ,//时钟信号
    input           rst_n   ,//上电复位低有效
    output          c0      ,
    output          c1      ,
    output          c2      ,
    output          c3      ,
    output          locked  ,
);
// //PLL
    pll	pll_inst (
    	.areset ( ~rst_n ),//IP复位高有效
    	.inclk0 ( clk    ),//输入时钟
    	.c0     ( c0     ),//输出时钟
    	.c1     ( c1     ),//输出时钟
    	.c2     ( c2     ),//输出时钟
    	.c3     ( c3     ),//输出时钟
    	.locked ( locked ) //时钟输出锁--锁定不稳定时钟输出
    	);
endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

再编写一个测试文件

`timescale 1ns/1ps
module test_tb();

    reg             clk         ;
    reg             rst_n       ;
    wire            c0          ;
    wire            c1          ;
    wire            c2          ;
    wire            c3          ;
    
//例化要仿真的文件
test_IP u_test_IP(
    .clk        (clk        ),//时钟信号
    .rst_n      (rst_n      ),//上电复位低有效
    .c0         (c0         ),
    .c1         (c1         ),
    .c2         (c2         ),
    .c3         (c3         ),
    .locked     (locked     )
);

always  #10     clk = ~clk;//产生50M仿真时钟

integer i = 0,j = 0;//用于产生地址,写入数据

initial begin
    clk = 1'b1;
    rst_n = 1'b1;
    #200.1;
    rst_n = 1'b0;//主动产生上电复位
    #200;
    rst_n = 1'b1;

    #20000;
    $stop;
end

endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38

编译仿真:

二.RAM

RAM介绍

RAM的英文全称是Random Access Memory,即随机存取存储器,它可以随时把数据写入任一指定地址的存储单元,也可以随时从任一指定地址中读出数据。其读写速度是由时钟频率决定的。RAM主要用来存放程序及程序执行过程中产生的中间数据、运算结果等。其特点适合双向交换数据。

其他类型的寄存器:

  • ROM(Read-Only Memory):只读存储器,系统上电后数据就被写入ROM,运行过程中智能从ROM中读取数据,而不能改变ROM中的数值。
  • FIFO(不寻址,操作简单)适合数据缓冲或跨时钟域数据同步处理;

总结:RAM、ROM、FIFO都是FPGA提供的存储单元

RAM的IP核调用(单时钟)

同样在IP Catalog中搜索RAM
在这里插入图片描述
双击选择RAM:1-PORT,同样保存在ip文件夹下,命名为RAM_1port.v
在这里插入图片描述
选择数据位大小,以及数据深度
在这里插入图片描述
在这里插入图片描述
Next
在这里插入图片描述
Next
在这里插入图片描述
同样勾选RAM_1port_inst.v和RAM_1port_bb.v文件

RAM仿真(单时钟)

同样,先例化
test_IP.v

module test_IP(
    input           clk     ,//时钟信号
    input           rst_n   ,//上电复位低有效
    input           rden    ,
    input           wren    ,
    input   [7:0]   address ,
    input   [7:0]   data    ,

    output  [7:0]   q
);

//RAM_1port
    RAM_1port	RAM_1port_inst (
        .aclr       ( ~rst_n    ),
     	.address    ( address   ),
     	.clock      ( clk       ),
     	.data       ( data      ),
     	.rden       ( rden      ),
     	.wren       ( wren      ),
     	.q          ( q         )
     	);
endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

编写测试文件test_tb.v

`timescale 1ns/1ps
module test_tb();

    reg             clk         ;
    reg             rst_n       ;
    reg             rden        ;
    reg             wren        ;
    reg    [7:0]    address     ;
    reg    [7:0]    data        ;
    wire   [7:0]    q           ;
    
//例化要仿真的文件
test_IP u_test_IP(
    .clk        (clk        ),//时钟信号
    .rst_n      (rst_n      ),//上电复位低有效
    .rden       (rden       ),
    .wren       (wren       ),
    .address    (address    ),
    .data       (data       ),

    .q          (q          )
);

always  #10     clk = ~clk;//产生50M仿真时钟

integer i = 0,j = 0;//用于产生地址,写入数据

initial begin
    clk = 1'b1;
    rst_n = 1'b1;
    #200.1;
    rst_n = 1'b0;//主动产生上电复位
//RAM_1PORT
    wren = 1'b0;//复位有效,赋初值
    rden = 1'b0;
    data = 0;
    address = 0;
    #200;
    rst_n = 1'b1;
    #200;
    //wren  50M
    for(i=0;i<256;i=i+1)begin
        wren = 1'b1;//高电平有效
        address = i;
        data = i+1;
        #20;
    end
    wren = 1'b0;//写完拉低
    #100;
    //rden  100M
    for(j=0;j<256;j=j+1)begin
        rden = 1'b1;
        address = j;
        #20;
    end
    rden = 1'b0;//读完拉低
    #200;
    $stop;
end

endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61

编译仿真:

RAM的IP核调用(双时钟)

选择RAM:2-PORT
在这里插入图片描述
在这里插入图片描述
选择一个读模块一个写模块
在这里插入图片描述
默认就好了
在这里插入图片描述
选择读写时钟分开,也就是读写是两个单独的时钟
在这里插入图片描述
读出数据设置为q,同样选择复位清零
在这里插入图片描述
Next
在这里插入图片描述

RAM仿真(双时钟)

例化

module test_IP(
    input           clk     ,//时钟信号
    input           rst_n   ,//上电复位低有效
    input   [7:0]   data        ,
    input   [7:0]   rdaddress   ,
    input           rden        ,
    input   [7:0]   wraddress   ,
    input           wrclock     ,
    input           wren        ,
    output  [7:0]   q

);

// //RAM_2port
    RAM_2port	RAM_2port_inst (
    .data       ( data      ),
    .rd_aclr    ( ~rst_n    ),
    .rdaddress  ( rdaddress ),
    .rdclock    ( clk       ),
    .rden       ( rden      ),
    .wraddress  ( wraddress ),
    .wrclock    ( wrclock   ),
    .wren       ( wren      ),
    .q          ( q         )
    );

endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

测试文件:

`timescale 1ns/1ps
module test_tb();

    reg             clk         ;
    reg             rst_n       ;
    reg     [7:0]   data        ;
    reg     [7:0]   rdaddress   ;
    reg             rden        ;
    reg     [7:0]   wraddress   ;
    reg             wrclock     ;
    reg             wren        ;
    wire    [7:0]   q           ;

//例化要仿真的文件
test_IP u_test_IP(
    .clk        (clk        ),//时钟信号
    .rst_n      (rst_n      ),//上电复位低有效
    .data        (data      ),
    .rdaddress   (rdaddress ),
    .rden        (rden      ),
    .wraddress   (wraddress ),
    .wrclock     (clk       ),
    .wren        (wren      ),
    .q           (q         )
);

always  #10     clk = ~clk;//产生50M仿真时钟

integer i = 0,j = 0;//用于产生地址,写入数据

initial begin
    clk = 1'b1;
    rst_n = 1'b1;
    #200.1;
    rst_n = 1'b0;//主动产生上电复位
    wren = 1'b0;//复位有效,赋初值
    rden = 1'b0;
    rdaddress = 0;
    wraddress = 0;
    data = 0;
    #200;
    rst_n = 1'b1;
    #200;
    //wren  50M
    for(i=0;i<256;i=i+1)begin
        wren = 1'b1;//高电平有效
        wraddress = i;
        data = i+1;
        #20;
    end
    wren = 1'b0;//写完拉低
    #100;
    //rden  100M
    for(j=0;j<256;j=j+1)begin
        rden = 1'b1;
        rdaddress = j;
        #20;
    end
    rden = 1'b0;//读完拉低
    #200;
    $stop;
end

endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64

编译仿真:

三.FIFO

FIFO介绍

FIFO的英文全称是First In First Out,即先进先出。FPGA使用的FIFO一般指的是对数据的存储具有先进先出特性的一个缓存器,常被用于数据的缓存或者高速异步数据的交互,也即所谓的跨时钟域信号传递。
它与FPGA内部的RAM和ROM的区别是没有外部读写地址线,采取顺序写入数据,顺序读出数据的方式,使用起来简单方便,由此带来的缺点就是不能像RAM和ROM那样可以由地址线决定读取或写入某个指定的地址。

FIFO的IP核调用(读写共用时钟)

在这里插入图片描述
在这里插入图片描述
选择读写使用同一个时钟
在这里插入图片描述
勾选如上信号
在这里插入图片描述
Next
在这里插入图片描述
Next
在这里插入图片描述

FIFO仿真(读写共用时钟)

例化:

module test_IP(
    input           clk     ,//时钟信号
    input           rst_n   ,//上电复位低有效
    input   [7:0]   data    ,
    input           rdreq   ,
    input           wrreq   ,

    output          empty   ,
    output          full    ,
    output  [7:0]   q       ,
    output  [7:0]   usedw   

);

// //FIFO
    fifo	fifo_inst (
    .aclr   ( ~rst_n    ),
    .clock  ( clk       ),
    .data   ( data      ),
    .rdreq  ( rdreq     ),
    .wrreq  ( wrreq     ),
    .empty  ( empty     ),
    .full   ( full      ),
    .q      ( q         ),
    .usedw  ( usedw     )
    );
endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

测试文件:

`timescale 1ns/1ps
module test_tb();

    reg             clk         ;
    reg             rst_n       ;
    reg             wrreq       ;
    reg             rdreq       ;
    reg     [7:0]   data        ;
    wire    [7:0]   q           ;
    wire            empty       ;
    wire            full        ;
    wire            usedw       ;

//例化要仿真的文件
test_IP u_test_IP(
    .clk        (clk        ),//时钟信号
    .rst_n      (rst_n      ),//上电复位低有效
    .data       (data   ),
    .rdreq      (rdreq  ),
    .wrreq      (wrreq  ),
    .empty      (empty  ),    
    .full       (full   ),    
    .q          (q      ),         
    .usedw      (usedw  ) 
);

always  #10     clk = ~clk;//产生50M仿真时钟

integer i = 0,j = 0;//用于产生地址,写入数据

initial begin
    clk = 1'b1;
    rst_n = 1'b1;
    #200.1;
    rst_n = 1'b0;//主动产生上电复位
    rdreq = 1'b0;
    wrreq = 1'b0;
    data = 0;
    #200;
    rst_n = 1'b1;
    #200;

    //wrreq  50M
    for(i=0;i<256;i=i+1)begin
        wrreq = 1'b1;//高电平有效
        data = {$random};
        #20;
    end
    wrreq = 1'b0;//写完拉低
    #100;

    //rdreq  100M
    for(j=0;j<256;j=j+1)begin
        rdreq = 1'b1;
        #20;
    end
    rdreq = 1'b0;
    #200;
    $stop;
end

endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62

编译仿真:

FIFO的IP核调用(读50MHZ时钟,写时钟100MHZ时钟)

同样选择上面的FIFO
在这里插入图片描述
选择读写时钟分开
在这里插入图片描述
在这里插入图片描述
勾选以上信号

在这里插入图片描述
在这里插入图片描述

FIFO仿真(读50MHZ时钟,写时钟100MHZ时钟)

这里要使用100MHZ时钟,就需要使用上面的PLL模块
例化:

module test_IP(
    input           clk     ,//时钟信号
    input           rst_n   ,//上电复位低有效

PLL
    output          c0      ,
    output          c1      ,
    output          c2      ,
    output          c3      ,
    output          locked  ,
    
//FIFO2
    input   [7:0]     data     ,
    input             rdreq    ,
    input             wrreq    ,
    output  [7:0]     q        ,
    output            rdempty  ,
    output            rdfull   ,
    output  [7:0]     rdusedw  ,
    output            wrempty  ,
    output            wrfull   ,
    output  [7:0]     wrusedw  

);

// //PLL
    pll	pll_inst (
    	.areset ( ~rst_n ),//IP复位高有效
    	.inclk0 ( clk    ),//输入时钟
    	.c0     ( c0     ),//输出时钟
    	.c1     ( c1     ),//输出时钟
    	.c2     ( c2     ),//输出时钟
    	.c3     ( c3     ),//输出时钟
    	.locked ( locked ) //时钟输出锁--锁定不稳定时钟输出
    	);
//FIFO2
    fifo2	fifo2_inst (
    	.aclr       ( ~rst_n    ),
    	.data       ( data      ),
    	.rdclk      ( clk       ),//50M
    	.rdreq      ( rdreq     ),
    	.wrclk      ( c0        ),//100M
    	.wrreq      ( wrreq     ),
    	.q          ( q         ),
    	.rdempty    ( rdempty   ),
    	.rdfull     ( rdfull    ),
    	.rdusedw    ( rdusedw   ),
    	.wrempty    ( wrempty   ),
    	.wrfull     ( wrfull    ),
    	.wrusedw    ( wrusedw   )
    	);
endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52

仿真文件:

`timescale 1ns/1ps
module test_tb();

    reg             clk         ;
    reg             rst_n       ;

// //PLL
    wire            c0          ;
    wire            c1          ;
    wire            c2          ;
    wire            c3          ;

//FIFO2
    reg      [7:0]     data     ;
    reg                rdreq    ;
    reg                wrreq    ;
    wire     [7:0]     q        ;
    wire               rdempty  ;
    wire               rdfull   ;
    wire     [7:0]     rdusedw  ;
    wire               wrempty  ;
    wire               wrfull   ;
    wire     [7:0]     wrusedw  ;

//例化要仿真的文件
test_IP u_test_IP(
    .clk        (clk        ),//时钟信号
    .rst_n      (rst_n      ),//上电复位低有效

PLL   
    .c0         (c0         ),
    .c1         (c1         ),
    .c2         (c2         ),
    .c3         (c3         ),
    .locked     (locked     ),

//FIFO2
    .data       (data   ),
    .rdreq      (rdreq  ),
    .wrreq      (wrreq  ),
    .q          (q      ),
    .rdempty    (rdempty),
    .rdfull     (rdfull ),
    .rdusedw    (rdusedw),
    .wrempty    (wrempty),
    .wrfull     (wrfull ),
    .wrusedw    (wrusedw)

);

always  #10     clk = ~clk;//产生50M仿真时钟

integer i = 0,j = 0;//用于产生地址,写入数据

initial begin
    clk = 1'b1;
    rst_n = 1'b1;
    #200.1;
    rst_n = 1'b0;//主动产生上电复位
    
//FIFO2
    rdreq = 1'b0;
    wrreq = 1'b0;
    data = 0;
    #200;
    rst_n = 1'b1;
    #200;

    //wrreq  50M
    for(i=0;i<256;i=i+1)begin
        wrreq = {$random}%2;//高电平有效
        data = {$random};
        #20;
    end
    wrreq = 1'b0;//写完拉低
    #100;
    //rdreq  100M
    for(j=0;j<256;j=j+1)begin
        rdreq = {$random}%2;
        #20;
    end
    rdreq = 1'b0;
    #200;
    $stop;
end

endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87

编译仿真:

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/550165
推荐阅读
相关标签
  

闽ICP备14008679号