verilog练习四:计数器IP核调用与验证

Quartus提供的LPM_counter IP 核的使用

一、FPGA主要设计方式

1、原理图(不推荐):

原理图设计早期应该用比较广泛,但当系统比较大时,修改比较困难,因此,目前已逐渐被HDL设计方式所取代,仅在有些设计的顶层描述会有使用。Quartus内嵌的原理图编辑器时Schematic Editor。

2、Verilog HDL 设计方式

应用最广泛,目前常用的语言有Verilog和VHDL语言。Quartus内嵌的文本编辑器为Text Editor,其可以根据语法来用不同的颜色显示关键字。除此之外,常用的文本编辑器还有Ultra Edit。

3、IP核输入方式

IP核输入方式是FPGA设计中的一个重要设计输入方式。所谓的IP核是指Mega-functions/Mega Wizard,它能生成IP核功能较多,无论是简单的基本设计模块还是复杂的处理器都可以,适当地使用IP核,可以很大程度上减轻工程师地设计工作量,并且也可提高设计质量,缩短开发周期。

4、其他辅助性设计输入

其他辅助性设计输入方法还有状态机输入、真值表输入和波形图输入等。

二、IP核介绍

1、定义

将在数字电路中常用但较复杂的功能块,如FFT、FIR滤波器、PCI接口等设计成可修改参数的模块,让其他用户可以直接调用这些模块,从而减轻了工程师负担,避免重复劳动。

2、分类

核是一种预定义的并经过验证的复杂功能模块,其可以集成到系统设计中。

在FPGA设计中的核分为三种:硬核、固核和软核。

  • 硬核:针对特定的实现技术优化的,具有不可修改的结构和布局布线,可作为库元件使用,时序性能稳定,但是无法按照设计进行修改和调整时序。
  • 固核:由HDL源码和实现技术有关的网表组成,使用者可按照规定增减部分功能。固核的关键路径时序是固定的,但其实现技术无法更改,即不同厂家的FPGA固核无法互换使用。
  • 软核:可综合的硬件描述语言源码,其与实现技术无关,可按照使用者进行修改,具有很大的灵活性,但软核的关键路径时序性能无保证,最终性能主要决定于使用者采用的综合、布局布线和实现技术。

3、核基FPGA设计流程

  1. 设计输入:一般采用HDL语言,输入完设计和仿真模型后就可进行第二步;
  2. 功能仿真
  3. 逻辑电路综合:这一步应该加上合适的时序约束,从而满足设计的要求,约束条件可以由综合文件给出,完成设计输入后进入第四步;
  4. 设计实现阶段:在此阶段,用户综合出的网表和设计约束文件一起输入给FPGA布局布线工具,完成FPGA的最后实现,并产生时序文件用于时序仿真和功能验证;
  5. 设计验证阶段:这一阶段用静态时序分析判定设计是否达到性能要求,对比仿真结果和时序仿真结果,验证设计的时序和功能是否正确。若性能无法达到要求,则需要找出影响性能的关键路径,并返回延时信息,修改约束文件,对设计进行重新综合和布局布线,如此重复多次指导满足设计要求为止。若仍不满足设计要求,则需要修改设计或采用其他实现技术。

三、实操

1、调用Quartus自带的计数器IP核

Tools--->MegaWizard Plug-In Manger--->Creat --->Next--->LPM_COUNTER--->Next--->打开了参数配置页面,设置计数器输出多少位(这里设置4位),创建端口有只增、只减和增减(这里选择只增)--->Next--->计数器类型(选择计数器计数到10时自动清零),设计其他端口(进位输入,进位输出)--->Next--->设置其他输入信号(这里暂不添加)--->Next--->Next--->Finish

点击Files,单击右键,点击Adds/Remove Files in Project,点击三个点,点击counter,点击Add,点击ok。

点击counter.v文件,选择将其设计为顶层文件后,分析和综合后,双击RTL Files查看结构。

2、仿真验证

`timescale 1ns/1ns
`define clock_period 20  //设置时钟周期20ns,即频率为50MHz

module counter_tb;
   reg cin; //进位输入
   reg clk; //计数基准时钟
   wire cout; //进位输出
   wire [3:0] q;
    
  counter counter0(
    .cin(cin),
    .clock(cout),
    .cout(cout),
    .q(q)
  );
  initial clk = 1;
  always #(`clock_period/2 ) clk = ~clk; //每次到达时钟周期一半时,信号翻转
  
  initial begin
     repeat(5) begin //重复5次,产生脉冲信号
      cin = 0;
      #{`clock_period*5} cin = 1; //延时5个时钟周期后,cin为1
      #(`clock_period) cin = 0;   //延时1个时钟周期后,cin为0
     end
      #{`clock_period*200} ;
      $stop;
  end


endmodule

3、结果分析

 由于在程序中设置的重复5次,因此cin有五次信号,且5个时钟周期后变为高电平,1个时钟周期后,变为低电平,当cin为高电平时,进位输出q加1,从000变为101

四、将四位计数器修改为八位计数器

方法一:直接在IP核中修改

方法二:将两个四位计数器级联为八位计数器,具体如下图所示:

将两个四位计数器级联,当counter0计满后,cout输入信号给counter1的cin。

程序如下所示:

module counter_top(cin,clk,cout,q);

  input cin;
  input clk;
  output cout;
  output [7:0] q;
  wire cout0;
  
  counter counter0(
	.cin(cin),
	.clock(clk),
	.cout(cout0),
	.q(q[3:0])
	);
	counter counter1(
	.cin(cout0),
	.clock(clk),
	.cout(cout),
	.q(q[7:4])
	);

endmodule

对其进行测试程序输入:

`timescale 1ns/1ns
`define clock_period 20

module  counter_top_tb;
   reg cin;//进位输入
	reg clk;//计数基准时钟
	wire cout;//进位输出
	wire [7:0] q;
	
 counter_top counter0(
	.cin(cin),
	.clk(clk),
	.cout(cout),
	.q(q)
	);
  initial clk = 1;
  always #(`clock_period/2) clk = ~clk;
  
  initial begin
     repeat(300)begin
	    cin = 0;
		 #(`clock_period*5) cin = 1;
		 #(`clock_period)   cin = 0;
	  end
     #(`clock_period*200);
	  $stop;
  
  end
endmodule 

对其进行RTL仿真,得到如下结果:

从图中可以看出,当低四位到9后,counter0的cout向counter1的cin输入信号,当高四位和低四位到99后,cout输出一个信号。 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值