【FPGA零基础学习之旅#6】ip核基础知识之计数器

news2024/11/25 14:56:45

🎉欢迎来到FPGA专栏~ip核基础知识之计数器


  • ☆* o(≧▽≦)o *☆~我是小夏与酒🍹
  • 博客主页:小夏与酒的博客
  • 🎈该系列文章专栏:FPGA学习之旅
  • 文章作者技术和水平有限,如果文中出现错误,希望大家能指正🙏
  • 📜 欢迎大家关注! ❤️
    FPGQ2

CSDN

🎉 目录-ip核基础知识之计数器

  • 一、效果演示
  • 二、ip核创建流程
  • 三、四位计数器仿真与分析
  • 四、计数器级联与仿真

遇见未来

一、效果演示

LPM_COUNTER IP核的RTL视图:
效果1
IP核计数器级联的RTL视图:
效果2

二、ip核创建流程

需要注意:本篇博客所使用的Quartus Ⅱ版本为13.0

创建LPM_COUNTER IP核的过程如下所示:

1、点击“Tools”,选择魔术棒“MegaWizard Plug-In Manager”。
创建1
2、选择“Create a new custom megafunction variation”, 创建一个新的自定义兆函数变体(先这么翻译吧)。
该对话框中的三个选项分别是新建一个定制IP核编辑一个现有的IP核复制一个现有的定制IP核
创建2
3、本次项目使用LPM_COUNTER,选择好输出目录
创建3
4、先使用4位的计数器,选择递增计数方式
创建4
5、配置为计数值计数且为10d,有进位输入以及输出
创建5
6、对于该IP核的基础使用,其余选项默认即可,直到Finish。这时我们能在Files中看到counter.qip文件,双击之后显示如下,这仅仅只是IP核的说明文件而已,我们还需要手动添加counter.v文件。
在这里插入图片描述
7、添加counter.v文件。
创建7
8、进入添加文件的界面。
创建8
9、选择当时输出目录下的counter.v文件。
创建9
10、选择文件完成之后,点击Add,并点击Apply
创建10
11、此时就可以在Files中看到我们所添加的counter.v文件了。
创建11
12、将counter.v设置为顶层,并分析与综合
创建12
分析与综合之后的RTL:
RTL
📜可见通过IP核生成的RTL视图与通过自己编写计数器的RTL是存在差异的。通过IP核生成的电路 更接近于真实的电路结构,IP核做了很多结构上的优化,能够使性能大幅度提高

生成的IP核内容如下:

// megafunction wizard: %LPM_COUNTER%
// GENERATION: STANDARD
// VERSION: WM1.0
// MODULE: LPM_COUNTER 

// ============================================================
// File Name: counter.v
// Megafunction Name(s):
// 			LPM_COUNTER
//
// Simulation Library Files(s):
// 			lpm
// ============================================================
// ************************************************************
// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
//
// 13.0.0 Build 156 04/24/2013 SJ Full Version
// ************************************************************


//Copyright (C) 1991-2013 Altera Corporation
//Your use of Altera Corporation's design tools, logic functions 
//and other software and tools, and its AMPP partner logic 
//functions, and any output files from any of the foregoing 
//(including device programming or simulation files), and any 
//associated documentation or information are expressly subject 
//to the terms and conditions of the Altera Program License 
//Subscription Agreement, Altera MegaCore Function License 
//Agreement, or other applicable license agreement, including, 
//without limitation, that your use is for the sole purpose of 
//programming logic devices manufactured by Altera and sold by 
//Altera or its authorized distributors.  Please refer to the 
//applicable agreement for further details.


// synopsys translate_off
`timescale 1 ps / 1 ps
// synopsys translate_on
module counter (
	cin,
	clock,
	cout,
	q);

	input	  cin;
	input	  clock;
	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 (
				.cin (cin),
				.clock (clock),
				.cout (sub_wire0),
				.q (sub_wire1),
				.aclr (1'b0),
				.aload (1'b0),
				.aset (1'b0),
				.clk_en (1'b1),
				.cnt_en (1'b1),
				.data ({4{1'b0}}),
				.eq (),
				.sclr (1'b0),
				.sload (1'b0),
				.sset (1'b0),
				.updown (1'b1));
	defparam
		LPM_COUNTER_component.lpm_direction = "UP",
		LPM_COUNTER_component.lpm_modulus = 10,
		LPM_COUNTER_component.lpm_port_updown = "PORT_UNUSED",
		LPM_COUNTER_component.lpm_type = "LPM_COUNTER",
		LPM_COUNTER_component.lpm_width = 4;


endmodule

// ============================================================
// CNX file retrieval info
// ============================================================
// Retrieval info: PRIVATE: ACLR NUMERIC "0"
// Retrieval info: PRIVATE: ALOAD NUMERIC "0"
// Retrieval info: PRIVATE: ASET NUMERIC "0"
// Retrieval info: PRIVATE: ASET_ALL1 NUMERIC "1"
// Retrieval info: PRIVATE: CLK_EN NUMERIC "0"
// Retrieval info: PRIVATE: CNT_EN NUMERIC "0"
// Retrieval info: PRIVATE: CarryIn NUMERIC "1"
// Retrieval info: PRIVATE: CarryOut NUMERIC "1"
// Retrieval info: PRIVATE: Direction NUMERIC "0"
// Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone IV E"
// Retrieval info: PRIVATE: ModulusCounter NUMERIC "1"
// Retrieval info: PRIVATE: ModulusValue NUMERIC "10"
// Retrieval info: PRIVATE: SCLR NUMERIC "0"
// Retrieval info: PRIVATE: SLOAD NUMERIC "0"
// Retrieval info: PRIVATE: SSET NUMERIC "0"
// Retrieval info: PRIVATE: SSET_ALL1 NUMERIC "1"
// Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0"
// Retrieval info: PRIVATE: nBit NUMERIC "4"
// Retrieval info: PRIVATE: new_diagram STRING "1"
// Retrieval info: LIBRARY: lpm lpm.lpm_components.all
// Retrieval info: CONSTANT: LPM_DIRECTION STRING "UP"
// Retrieval info: CONSTANT: LPM_MODULUS NUMERIC "10"
// Retrieval info: CONSTANT: LPM_PORT_UPDOWN STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: LPM_TYPE STRING "LPM_COUNTER"
// Retrieval info: CONSTANT: LPM_WIDTH NUMERIC "4"
// Retrieval info: USED_PORT: cin 0 0 0 0 INPUT NODEFVAL "cin"
// Retrieval info: USED_PORT: clock 0 0 0 0 INPUT NODEFVAL "clock"
// Retrieval info: USED_PORT: cout 0 0 0 0 OUTPUT NODEFVAL "cout"
// Retrieval info: USED_PORT: q 0 0 4 0 OUTPUT NODEFVAL "q[3..0]"
// Retrieval info: CONNECT: @cin 0 0 0 0 cin 0 0 0 0
// Retrieval info: CONNECT: @clock 0 0 0 0 clock 0 0 0 0
// Retrieval info: CONNECT: cout 0 0 0 0 @cout 0 0 0 0
// Retrieval info: CONNECT: q 0 0 4 0 @q 0 0 4 0
// Retrieval info: GEN_FILE: TYPE_NORMAL counter.v TRUE
// Retrieval info: GEN_FILE: TYPE_NORMAL counter.inc FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL counter.cmp FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL counter.bsf FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL counter_inst.v FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL counter_bb.v TRUE
// Retrieval info: LIB_FILE: lpm

三、四位计数器仿真与分析

编写测试激励文件:

`timescale 1ns/1ns
`define clock_period 20

module counter_tb;

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

仿真结果:
结果1
可以观察到在仿真结果中出现了毛刺,在这里可以先理解为:由于IP核生成的计数器的电路更接近于真实的电路结构,且已经经过了布局布线的优化,所以会出现毛刺。对于更具体的原因,不需要深究。

当进位输入一个高电平之后,q计数1次;当进位输入10次高电平之后,q计数10次,同时产生一个进位输出高电平

四、计数器级联与仿真

先上RTL视图:
RTL2
通过创建顶层文件的方式,调用两次IP核生成的计数器,并实现级联。

其中,Ucounter0实现的是低四位的计数,Ucounter1实现高四位的计数。当低四位计算10次之后,Ucounter0的cout产生一个进位输出,传入给Ucounter1作为进位输入。

在顶层文件中实现级联:

module counter_top(
	input 	cin,
	input 	clk,
	output 	[7:0]q,
	output 	cout
);
	
	wire cout0;
		
	counter Ucounter0(
		.cin(cin),
		.clock(clk),
		.cout(cout0),
		.q(q[3:0])
	);
	
	counter Ucounter1(
		.cin(cout0),
		.clock(clk),
		.cout(cout),
		.q(q[7:4])
	);

endmodule

在分析与综合之前,先把counter_top.v设置为顶层。

测试激励文件:

`timescale 1ns/1ns
`define clock_period 20

module counter_top_tb;

	reg clk;//计数基准时钟
	reg cin;//进位输入
	
	wire cout;//进位输出
	wire [7:0]q;
	
	counter_top counter_top_0(
		.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

为了便于观察计数效果,可以将计数值改为hex格式
计数值

hex格式
十六进制(简写为hex或下标16)在数学中是一种逢16进1的进位制。一般用数字0到9和字母A到F表示,其中A ~ F相当于十进制的10~15,这些称作十六进制数字。例如十进制数57,在二进制写作111001,在16进制写作39。
现在的16进制则普遍应用在计算机领域,这是因为将4个位元(Bit)化成单独的16进制数字不太困难。1个字节(Byte)可以表示成2个连续的16进制数字

观察仿真结果,当计数值到达99,即计数了100次时,cout产生一个高电平脉冲:
计数

csdn

🧸结尾


  • ❤️ 感谢您的支持和鼓励! 😊🙏
  • 📜您可能感兴趣的内容:
  • 【stm32开发】stm32+oled最小系统板资料(原理图、PCB、示例代码)【六一】
  • 【FPGA零基础学习之旅#5】产生非等占空比信号
  • 【Arduino TinyGo】【最新】使用Go语言编写Arduino-环境搭建和点亮LED灯
  • 【全网首发开源教程】【Labview机器人仿真与控制】Labview与Solidworks多路支配关系-四足爬行机器人仿真与控制
    遇见未来

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/608708.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[网络工程]小型局域网组建的常用命令(ENSP)

⭐作者介绍:大二本科网络工程专业在读,持续学习Java,努力输出优质文章 ⭐作者主页:逐梦苍穹 目录 1、引言2、常用命令(ENSP)常规VTYConsole端口安全单臂路由DHCPNATACL基础ACL高级ACL GVRPSTP 1、引言 局域网(Local A…

C++学习——第一节课-初识C++

大家好,我是涵子。今天我们来开始学习C。 目录 一、课前准备 二、C的第一个程序 2.1.C是个啥 2.2.C的第一个程序编写 2.2.1.头文件 2.2.2.命名空间 2.2.3.主程序函数 2.2.4.输出流 2.2.5.代码结束 三、其它的应用 3.1.输出三角形,矩形和勾 …

单例模式C++实现和观察者模式C++实现

目录 1、单例模式介绍 2、单例代码实现 2.1 static介绍 2.2 C中static的三种用法: (1)静态局部变量 (2)静态成员变量 (3)静态成员函数 3、观察者模式介绍 4、观察者代码实现 1、单例模…

.ini配置文件介绍与解析库使用

【前言】 ini 文件是英文"Initialization"的缩写,即初始化文件。它用来配置特定应用软件以实现对程序初始化或进行参数设置。.ini文件由节(section)、键(key)、值(value)三种模块构成。在windows系统/嵌入式软件中有很多XXX.ini文件,例如Syste…

IDC机房相电压与线电压的关系

380V电动机(三相空调压缩机)的电流计算公式为:Ⅰ=额定功率(1.732额定电压功率因数效率)。 功率因数是电力系统的一个重要的技术数据。功率因数是衡量电气设备效率高低的一个系数。功率因数低,说…

通过源码编译安装搭建 LNMP平台

搭建LNMP平台 一. 安装Nginx服务1.1 安装依赖包1.2 创建运行用户1.3 编译安装1.4 优化路径1.5 添加 Nginx 系统服务 二. 安装mysql服务2.1 安装Mysql环境依赖包2.2 创建运行用户2.3 编译安装2.4 修改mysql 配置文件2.5 更改mysql安装目录和配置文件的属主属组2.6 设置路径环境变…

VMware安装Windows11

VMware安装Windows11 嘚吧嘚准备工作VMware下载Windows11下载 VMware安装Windows11VMware配置安装Windows11 嘚吧嘚 最近在搞一些自己感兴趣的东西,需要(临时)安装一些软件来验证,考虑到用完还要卸载,不想把自己的电脑搞得乱七八糟&#x1f…

字节序及IP地址转换

一、主机字节序和网络字节序 1.什么是字节序? 字节序是指多字节数据在计算机内存中存储或者网络传输时各字节的存储顺序,分为:大端字节序(Big endian)、小端字节序(Little endian)。 示例&am…

前端技术双周刊 2023-06-04:React 发布 10 周年整

项目地址:olivewind/weekly 微信公众号:依赖注入 发布时间:2023.06.04 本周内容:资讯x3、开源x4、文章x5 动态 React 圆桌会议 - Server Components, Suspense 和 Actions 为庆祝 React 成立 10 周年,Delba de Oliveir…

MySQL 约束控制

文章目录 约束控制非空约束主键约束默认值约束唯一约束外键约束 约束控制 数据的完整性约束(简称“约束”)是在表和字段上强制执行的数据检测规则,是为了防止不规范的数据进入数据库。当我们对数据进行 DML 操作时,数据库管理系统…

被面试官上过一课后,我学到的不止是如何答题

写在前面双向奔赴切勿急于否定自己做足功课关于简历关于简历投递常见面试题汇总● 按照一般的面试流程,先来一个自我介绍吧● 你的优点和缺点是什么● 你理解的项目经理是干什么的● 能完整的说一下软件项目的整个流程么● 项目经理和产品经理的区别在哪里● 项目管…

UniAD:实现多类别异常检测的统一模型

来源:投稿 作者:Mr.Eraser 编辑:学姐 论文标题:用于多类异常检测的统一模型 论文链接:https://arxiv.org/abs/2206.03687 论文贡献: 提出UniAD,它以一个统一框架完成了多个类别的异常检测。 …

Jetson 硬件 安装SSD固态作为启动盘以及安装CUDA等

Jetson硬件的自带闪存一般较小,只能安装jetpack等基本的环境,所以需要额外增加SSD固态或SD卡作为存储空间,很明显SSD的读取速度远远大于SD卡,所以为更好发挥出Jetson 的计算性能,我们选择使用SSD固态作为存储 1. 安装…

随机森林原理和性能分析

文章目录 随机森林入门构造随机森林随机森林性能随机森林特点 随机森林入门 决策树入门、sklearn实现、原理解读和算法分析中针对决策树进行了详细的描述,但是其只考虑了一颗决策树的情况。俗话说,三个臭皮匠,顶个诸葛亮。本文将研究如何通过…

C++:深入理解多态,多态实现原理及拓展

文章目录 1. 理解虚表1.1 虚表1.2 验证1.3 子类虚表1.4 相同类不同对象的虚表 2. 静态绑定和动态绑定2.1 静态绑定2.2 动态绑定 3. 多态的实现原理3.1 向上转型3.2 多继承3.3 原理 4. 拓展4.1 构造函数能不能是虚函数4.2 父类和子类的析构函数在底层的命名问题4.3 对象之间无法…

[论文阅读] (30)李沐老师视频学习——3.研究的艺术·讲好故事和论点

《娜璋带你读论文》系列主要是督促自己阅读优秀论文及听取学术讲座,并分享给大家,希望您喜欢。由于作者的英文水平和学术能力不高,需要不断提升,所以还请大家批评指正,非常欢迎大家给我留言评论,学术路上期…

SpringMVC第十一阶段:SpringMVC 拦截器执行源码解析

SpringMVC 拦截器执行源码解析: 1、执行doDispatcher做请求分发处理 1.1、调用getHandler()获取请求处理器,处理器中包含请求的方法和拦截器信息 getHandlerInternal() 根据请求地址获取对应的目标方法getHandlerExecutionChain() 获取请求地址对…

(转载)基于鱼群算法的函数寻优算法(matlab实现)

1 理论基础 1.1 人工鱼群算法概述 人工鱼群算法是李晓磊等人于2002年提出的一类基于动物行为的群体智能优化算法。该算法是通过模拟鱼类的觅食、聚群、追尾、随机等行为在搜索域中进行寻优,是集群体智能思想的一个具体应用。生物的视觉是极其复杂的,它…

Java006——对第一个Java程序HelloWorld的简单介绍

一、HelloWorld.java程序整体认识 public class HelloWorld { //创建一个名字叫HelloWorld的类(Java中的类叫class)public static void main(String[] args) {//主程序入口,类似C语言main函数System.out.println("He…

python之scipy.signal重采样

前言 在复现LiftingNet过程中,了解到作者对于不同转速设备的机械信号进行重采样来矫正转速,也就是固定长度的样本包含了相同旋转周期的设备信息,而非相同时间长度。po一下原文: 这里其实用到了阶次分析的原理,该样本…