Quartus II的IP核调用及仿真测试

发布于:2025-04-17 ⋅ 阅读:(56) ⋅ 点赞:(0)

第一章 什么是IP核?

IP核就是知识产权核或知识产权模块的意思,在EDA技术开发中具有十分重要的地位。美国著名的Dataquest咨询公司将半导体产业的IP定义为“用于ASIC或FPGA中的预先设计好的电路功能模块”。IP主要分为软IP、固IP和硬IP。软IP是用Verilog/VHDL等硬件描述语言描述的功能块,但是并不涉及用什么具体电路元件实现这些功能。固IP是完成了综合的功能块。硬IP提供设计的最终阶段产品——掩膜。[1]

第二章 什么是LPM?

LPM即参数化模块库(Library of Parameterized Modules),是Altera 公司FPGA/CPLD设计软件Quartus II自带的一些宏功能模块,如:锁相环(PLLs), LVDS,数字信号处理(DSP) 模块等。这些功能是对Altera器件的优化,设计者在用这些模块时,不耗用器件的逻辑资源(Logic Cell)。[2]

第一节 设置LPM_COUNTER模块参数

  1. 新建项目,点击IP Catalog,在搜索框内输入counter,点击LPM_COUNTER,然后将其保存为myLPM_counter.v,点击Ok开始配置
    在这里插入图片描述
    在这里插入图片描述

  2. 基础设置在这里插入图片描述

  3. 设置输入并点击NEXT。
    在这里插入图片描述

  4. 多次点击NEXT,出现如下界面后选择需要文件,点击Finish完成配置,在弹出界面点击Yes
    在这里插入图片描述
    在这里插入图片描述

第二节 仿真

  1. 新建Verilog HDL File,然后写入代码,生成需要的模型,将其保存为Updown_counter10.v
    在这里插入图片描述
module Updown_counter10 (aclr,cp_en,cp,updown,co,q);
    input aclr;
	 input cp_en;
	 input cp;
	 input updown;
	 output co;
	 output [3:0] q;
	 
myLPM_counter  myLPM_counter_inst(
    .aclr(aclr),
    .clk_en(cp_en),
    .clock(cp),
    .updown(updown),
    .cout(co),
    .q (q)
    );
endmodule	 

文件目录如下
在这里插入图片描述

  1. 设置LPM_COUNTER,修改myLPM_counter.qip文件下的myLPM_counter.v,使其符合期望
`timescale 1 ps / 1 ps
module myLPM_counter (aclr,clk_en,clock,sclr,updown,cout,q);
   input   aclr;
	input	  clk_en;
	input	  clock;
	input	  sclr;
	input	  updown;
	
	output	  cout;
	output	[3:0]  q;
	wire  sub_wire0;
	wire [3:0] sub_wire1;
	wire  cout = sub_wire0;
	
	wire [3:0] q = sub_wire1[3:0];

	lpm_counter	LPM_COUNTER_component (
				.clk_en (clk_en),
				.clock (clock),
//				.sclr (sclr),
				.updown (updown),
				.cout (sub_wire0),
				.q (sub_wire1),
				.aclr (1'b0),
				.aload (1'b0),
				
				.aset (1'b0),
				.cin (1'b1),
				.cnt_en (1'b1),
				.data ({4{1'b0}}),
				.eq (),
				
				.sclr(1'b0),
				.sload (1'b0),
				.sset (1'b0));
	defparam
		LPM_COUNTER_component.lpm_direction = "UNUSED",
		LPM_COUNTER_component.lpm_modulus = 10,
		LPM_COUNTER_component.lpm_port_updown = "PORT_USED",
		LPM_COUNTER_component.lpm_type = "LPM_COUNTER",
		LPM_COUNTER_component.lpm_width = 4;
endmodule
  1. 开始完整编译,编译通过后,新建University Program VWF进行仿真
    在这里插入图片描述

在这里插入图片描述

  1. 仿真
    在这里插入图片描述
    观察仿真结果发现,结果与预期相同

第三章 什么是PLL?

PLL即锁相环 (phase locked loop)是一种利用相位同步产生的电压,去调谐压控振荡器以产生目标频率的负反馈控制系统。根据自动控制原理,这是一种典型的反馈控制电路,利用外部输入的参考信号控制环路内部振荡信号的频率和相位,实现输出信号频率对输入信号频率的自动跟踪,一般用于闭环跟踪电路。是无线电发射中使频率较为稳定的一种方法,主要有VCO(压控振荡器)和PLL IC (锁相环集成电路),压控振荡器给出一个信号,一部分作为输出,另一部分通过分频与PLL IC所产生的本振信号作相位比较,为了保持频率不变,就要求相位差不发生改变,如果有相位差的变化,则PLL IC的电压输出端的电压发生变化,去控制VCO,直到相位差恢复,达到锁相的目的。能使受控振荡器的频率和相位均与输入信号保持确定关系的闭环电子电路。[3]

第一节 设置ALTPLL(嵌入式锁相环)模块参数

  1. 选择ALTPLL,与第二章第一节相同的处理方法,在IP Catalog中搜索PLL,选择ALTPLL在点击左下角的Add按钮将其保存为mypll.v文件并开始配置

    在这里插入图片描述

  2. 根据选择的芯片设置合适的晶振,ep4ce115f29c7的晶振为50MHZ,使用时钟频率选择50MHZ,模式为正常
    在这里插入图片描述

  3. 以下配置默认即可
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

  4. 设置时钟
    c0:设置100MHZ,将时钟倍频,占空比设置50%
    在这里插入图片描述
    c1:25MHZ,选择分频,且相位偏移90°,占空比50%
    在这里插入图片描述
    c2:5MHZ,占空比为25%
    在这里插入图片描述
    c3:先分频再倍频,75MHZ,占空比50%
    在这里插入图片描述
    目前只选择4个时钟,第5个时钟不启用

  5. 多次点击next,直到出现此界面,勾选mypll_inst.v文件和mypll_bb.v文件
    在这里插入图片描述

第二节 仿真

  1. 新建Verilog HDL File,写入下面的模型代码,保存为test_IP.v
module test_IP(
    input           clk     , // 时钟信号
    input           rst_n   , // 上电复位低有效
    output          c0      ,
    output          c1      ,
    output          c2      ,
    output          c3      ,
    output          locked  
);

// PLL
mypll mypll_inst (
    .areset ( ~rst_n ), // IP复位高有效
    .inclk0 ( clk    ), // 输入时钟
    .c0     ( c0     ), // 输出时钟
    .c1     ( c1     ), // 输出时钟
    .c2     ( c2     ), // 输出时钟
    .c3     ( c3     ), // 输出时钟
    .locked ( locked )  // 时钟输出锁--锁定不稳定时钟输出
);

endmodule

以及测试代码test_tb.v

`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. 仿真
    在这里插入图片描述

观察仿真结果发现与预期相同

第四章 什么是RAM?

RAM即随机存取存储器(英语:Random Access Memory,缩写:RAM),也叫主存,是与CPU直接交换数据的内部存储器。它可以随时读写(刷新时除外),而且速度很快,通常作为操作系统或其他正在运行中的程序的临时数据存储介质。RAM工作时可以随时从任何一个指定的地址写入(存入)或读出(取出)信息。它与ROM的最大区别是数据的易失性,即一旦断电所存储的数据将随之丢失。RAM在计算机和数字系统中用来暂时存储程序、数据和中间结果。[4]

第一节 RAM_1PORT的调用

  1. 搜索RAM 选择RAM_1PORT并添加保存为RAM_1PORT.v
    在这里插入图片描述

  2. 设置位宽和数据深度
    在这里插入图片描述

  3. 多次点击NEXT直到出现此界面,并勾选RAM_1PORT_inst.vRAM_1PORT_bb.v
    在这里插入图片描述

第二节 配置RAM_1PORT

  1. 新建Verilog HDL File,写入模型的代码
module RAM_1port_test(
    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

以及测试的代码

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

    reg             clk         ;
    reg             rst_n       ;
    reg             rden        ;
    reg             wren        ;
    reg    [7:0]    address     ;
    reg    [7:0]    data        ;
    wire   [7:0]    q           ;
    
//例化要仿真的文件
RAM_1port_test u_RAM_1port_test(
    .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. 完全编译
    在这里插入图片描述

第三节 RAM_2PORT的调用

  1. 同样,找到RAM_2PORT并添加,保存为RAM_2port.v
    在这里插入图片描述
  2. 配置读写模块在这里插入图片描述
  3. 配置数据深度为1024
    在这里插入图片描述
  4. 选择读写时钟分开
    在这里插入图片描述
  5. 读出数据设置为q,同样选择复位清零

在这里插入图片描述

  1. 多次点击next直到出现此界面,选择RAM_2port_inst.vRAM_2port_bb.v
    在这里插入图片描述

第四节 配置RAM_2PORT

  1. 同样编译模型代码和测试代码
    test_IP.v
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

测试代码test_tb.v

`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. 完整编译通过
    在这里插入图片描述

第五章 什么是FIFO?

FIFO( First Input First Output)简单说就是指先进先出。由于微电子技术的飞速发展,新一代FIFO芯片容量越来越大,体积越来越小,价格越来越便宜。作为一种新型大规模集成电路,FIFO芯片以其灵活、方便、高效的特性,逐渐在高速数据采集、高速数据处理、高速数据传输以及多机处理系统中得到越来越广泛的应用。[5]

第一节 FIFO模块参数配置

1.在IP Catelog搜索FIFO,选择FIFO并添加,保存为fifo.v
在这里插入图片描述

  1. 选择读写使用同一个时钟
    在这里插入图片描述
  2. 配置SCFIFO
    在这里插入图片描述
  3. 默认即可,点击next
    在这里插入图片描述
  4. 默认即可
    在这里插入图片描述
  5. 勾选fifo_inst.vfifo_bb.v
    在这里插入图片描述

第二节 配置FIFO

  1. 与前面相同,新建Verilog HDL File,写入如下代码并保存
    模型代码:
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

测试代码:

`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. 全部编译通过
    在这里插入图片描述

参考文献

[1] 潘松·EDA技术与Verilog HDL·北京:清华大学出版社,2010
[2] LPM(FPGA参数化模块库) -百度百科
[3] 锁相环(无线电术语)-百度百科
[4] 杨颂华,冯毛官,孙万蓉,初秀琴,胡力山编著·数字电子技术基础:西安电子科技大学出版社,2016.07
[5] FIFO存储器 -百度百科
[6] Quartus基本IP核调用及仿真
[7] 罗杰.Verilog HDL 与FPGA数字系统设计 第二版[M].机械工业出版社:北京,2022:198-210.


网站公告

今日签到

点亮在社区的每一天
去签到