零基础学FPGA(五):时序逻辑电路设计之计数器(附有呼吸灯实验、简单组合逻辑设计介绍)
目录
- 日常·唠嗑
- 前言
- 一、认清逻辑设计
- 二、时序逻辑电路设计
- 三、扩展:呼吸灯实验
日常·唠嗑
第一次建立《零基础学FPGA》专栏,是在2021年2月2日,已经过去了一年了,目前只更新了4篇。总说要更新,却总是拖更,直到这两天有关注的朋友提起,才想起来,在这里跟各位关注我的朋友说声抱歉。
新的一年,我的时间会比较充裕,会花更多时间在这个专栏上,初心不变,还是跟大家一起共进步,嘿嘿。
最近会接触一些国产FPGA开发,如京微齐力的伏羲软件等,有兴趣的也可以一起交流哇~~
前言
在零基础学FPGA系列中,我没有写组合逻辑电路设计,而是直接进入时序逻辑电路设计。因为组合逻辑比较简单,在这里我简单提一下就好。
顺带提一下,有关非阻塞赋值、阻塞赋值、assign和always这些Verilog之类的语法,我放到下一篇再讲。
一、认清逻辑设计
在数字电路中可以根据电路功能的不同分为,组合逻辑电路与时序逻辑电路。组合逻辑电路在逻辑功能上的特点是:任意时刻的输出仅仅取决于该时刻的输入,与电路原来的状态无关。而时序逻辑从电路特征上看来,其特点为任意时刻的输出不仅取决于该时刻的输入,而且还和电路原来的状态有关。通常是以assign语句为主。 组合逻辑电路在电路结构上,不涉及对信号跳变沿的处理,无存储电路,也没有反馈电路,通常可以通过真值表的形式表达出来。时序逻辑电路在电路结构上,不管输入如何变化,仅当时钟的沿(上升沿或下降沿)到达时,才有可能使输出发生变化。通常是以always语句为主。
对于组合逻辑,这里用一个3-8 译码器电路来介绍一下:
译码器是一种多输入多输出的组合逻辑电路,负责将二进制代码翻译为特定的对象(如逻辑电平等),功能与编码器相反。译码器一般分为通用译码器和数字显示译码器两大类。
比如:三八译码器,将 3 种输入状态翻译成 8 种输出状态,其真值表如下所示。其中 A,B,C 为数据输入,Out 为数据输出。在 MCU 应用中,如果需要保证一定的速度情况下实现此功能,一般选取外挂一片74HC38 或者 74LS38 等独立芯片,但 FPGA 提供了一个完整的想象以及实现空间,仅靠其自身即可实现设计要求。
译码器真值表
module decoder( a,b,c,out);input a;//输入端口Ainput b;//输入端口Binput c;//输入端口Coutput [7:0]out;//输出端口reg [7:0]out;always@(a,b,c)//always@()括号内为敏感信号列表//always语句可以带时钟,也可以不带时钟。在always不带时钟时,逻辑功能和assign完全一致,都是只产生组合逻辑。begincase({a,b,c})//判断a,b,c状态值,可以用拨键开关做测试3'b000:out = 8'b0000_0001;3'b001:out = 8'b0000_0010;3'b010:out = 8'b0000_0100;3'b011:out = 8'b0000_1000;3'b100:out = 8'b0001_0000;3'b101:out = 8'b0010_0000;3'b110:out = 8'b0100_0000;3'b111:out = 8'b1000_0000;endcase endendmodule
二、时序逻辑电路设计
时序逻辑电路是指电路任何时刻的稳态输出不仅取决于当前的输入,还与前一时刻输入形成的状态有关。这跟组合逻辑电路相反,组合逻辑的输出只会跟目前的输入成一种函数关系。换句话说,时序逻辑拥有储存元件来存储信息,而组合逻辑则没有。
重点:
时序逻辑电路分为很多种,在这里我讲一下最常用的计数器,并比较与组合逻辑电路的区别。此处设计一个计数器,使开发板上的 LED 状态每 500ms 翻转一次。市面上开发板的晶振大多为 50MHz,也就是说时钟周期为 20ns(1÷500_000),这样可以计算得出 500ms = 500_000_000ns/20ns = 25_000_000,即需要计数器计数 25_000_000 次,也就是需要一个至少25 位的计数器(225>25_000_000>224)。且每当计数次数达到需要清零并重新计数。
Verilog HDL 之所以被称为硬件电路描述语言,就是因为我们不是在类似 C 一样进行普通的编程,而是在编写一个实际的硬件电路。下面将设计一个计数器,通过计数器控制一个LED 闪。
module counter
(
input clk, //时钟信号50Mhz
input reset_n,//复位信号
output led
); reg led;parameter MCNT = 24_999_999;reg [24:0]period_cnt ; //定义计数器寄存器//计数器计数进程
always@(posedge clk or posedge reset_n)
if(reset_n)period_cnt <= 25'd0;
else if(period_cnt == MCNT)period_cnt <= 25'd0;
elseperiod_cnt <= period_cnt + 1'b1;//led输出控制进程
always@(posedge clk or posedge reset_n)
if(reset_n)led <= 1'b1;
else if(period_cnt == MCNT)led <= ~led;
elseled <= led;endmodule
因为计数器是从 0 开始计数而不是 1,所以在计数值计数到 25’d24_999_999 时清零,而不是计数到25’d25_000_000 时清零,这里计数器最大值使用 parameter 进行参数化定义表示,使用参数化定义的好处是通过修改顶层parameter参数,从而完成整体变量参数修改。
当计数器计数到预设的值后就让 led 取反一次,来达到亮灭翻转的目的。
在这个实验基础上,可以通过PWM做呼吸灯实验。
三、扩展:呼吸灯实验
呼吸灯采用 PWM 的方式,在固定的频率下,通过调整占空比的方式来控制 LED 灯亮度的变化。PWM,即脉冲宽度调制,在由计数器产生的固定周期的 PWM 信号下,如果其占空比为 0,则 LED 灯不亮;如果其占空比为 100%,则 LED 灯最亮。所以将占空比从 0 到 100%,再从 100%到 0 不断变化,就可以实现 LED 灯的“呼吸”效果。PWM 占空比调节示意图如下图所示:
由上图可知,LED 高电平的时间由长渐渐变短,再由短渐渐变长,如果 LED 灯是高电平点亮,则 LED灯会呈现出亮度由亮到暗,再由暗到亮的过程。
周期信号计数器用于产生驱动 LED 的脉冲信号,本次实验的周期信号频率为 1Khz,其占空比由后级逻辑在每个周期之后进行递增或递减,最后再对当前计数值和占空比计数值进行比较,以输出占空比可调的脉冲信号。
module breath_led(input clk , //时钟信号50Mhzinput reset_n , //复位信号output led //LED
);//reg define
reg [15:0] period_cnt ; //周期计数器频率:1khz 周期:1ms 计数值:1ms/20ns=50000
reg [15:0] duty_cycle ; //占空比数值
reg inc_dec_flag ; //0 递增 1 递减//根据占空比和计数值之间的大小关系来输出LED
assign led = (period_cnt >= duty_cycle) ? 1'b1 : 1'b0;//周期计数器
always @(posedge clk or negedge reset_n) beginif(!reset_n)period_cnt <= 16'd0;else if(period_cnt == 16'd50000)period_cnt <= 16'd0;elseperiod_cnt <= period_cnt + 1'b1;
end//在周期计数器的节拍下递增或递减占空比
always @(posedge clk or negedge reset_n) beginif(!reset_n) beginduty_cycle <= 16'd0;inc_dec_flag <= 1'b0;endelse beginif(period_cnt == 16'd50000) begin //计满1msif(inc_dec_flag == 1'b0) begin //占空比递增状态if(duty_cycle == 16'd50000) //如果占空比已递增至最大inc_dec_flag <= 1'b1; //则占空比开始递减else //否则占空比以25为单位递增duty_cycle <= duty_cycle + 16'd25;endelse begin //占空比递减状态if(duty_cycle == 16'd0) //如果占空比已递减至0inc_dec_flag <= 1'b0; //则占空比开始递增else //否则占空比以25为单位递减duty_cycle <= duty_cycle - 16'd25;endendend
endendmodule
第 21-28 行是 1KHz 周期信号的计数器,用于产生 1KHz 的 LED 驱动信号。第 31-52 行的 always 块为占空比设定模块,每次计数完了一个周期,就根据递增/递减标志来对占空比计数值(duty_cycle)进行递增/递减 25 个计数值,这个递增或者递减的数值大小可以用来控制呼吸灯的呼吸频率。
如果占空比计数值(duty_cycle)已经递增到了最大,则呼吸灯已经处于最亮的状态,接下来开始递减;反之,如果占空比计数至已经递减到了最小,即 0,则呼吸灯处于熄灭的状态,接下来开始递增;如此循环往复,最终实现了流水灯的效果。在代码的第 18 行通过组合逻辑把当前的周期计数值和占空比计数值进行比较,来判断 LED 的输出电平。在一个周期内,如果当前的周期计数值小于等于占空比计数值,则 LED 输出高电平,即点亮;如果当前的周期计数值大于占空比计数值,则 LED 输出低电平,即熄灭。
零基础学FPGA(五):时序逻辑电路设计之计数器(附有呼吸灯实验、简单组合逻辑设计介绍)相关推荐
- 零基础学FPGA(八):可编程逻辑单元(基本结构,Xilinx+Altera)
目录 日常·唠嗑 一.概述 二.基于多路选择器的逻辑单元 1.基于多路选择器的逻辑单元(早期) 2.基于PLD结构的逻辑单元(类CPLD) 3.基于查询表的逻辑单元(目前主流) 三.Xilinx基本结 ...
- 零基础学FPGA(一):与FPGA的爱恨情仇
我笑夏蝉唱不完少年梦 ,他说街灯亮不过明日光. --胡歌 最近挺迷茫的,要做的事真的很多,要学的东西也很多,看见什么都觉得很有趣,很实用,想学一手.记得财哥曾经说过:事情少的时候,你会认真的,抓紧时间 ...
- 零基础学FPGA(三):国产芯片短板—FPGA(为什么选择FPGA)
文章目录 前言 一.FPGA简介 二.FPGA的用途 三.FPGA比较 1.FPGA与单片机比较 2.FPGA与CPU比较 四.为什么选择FPGA 总结 前言 在正点原子的技术文档里面看到一个小故事, ...
- sdram 时钟相位_零基础学FPGA (二十五)必会! 从静态时序分析到SDRAM时序收敛(下篇)...
七.SDRAM工作时钟相位偏移计算本文引用地址:http://www.eepw.com.cn/article/279083.htm 从上篇文章中我们知道,我们的数据是要经过一定的延时才会到达目标器件的 ...
- java开发技术有什么意义,零基础学Java开发技术有哪些优势和好处?
零基础学Java开发技术有哪些优势和好处?Java开发技术有下列优势:Java编程语言简单.面向对象集中于对象及其接口.分布式处理TCP/IP协议.鲁棒性.安全性.体系结构中立性.可移植性.解释执行. ...
- 【零基础学Java】—哈希值(四十一)
[零基础学Java]-哈希值(四十一) 一. HashSet集合的介绍 java.util.Set接口 extends Collection接口 Set接口的特点: 不允许重复的元素 没有索引,没有带 ...
- 【零基础学Java】—TCP通信(五十四)
[零基础学Java]-TCP通信(五十四) TCP通信:面向连接的通信,客户端和服务器端必须经过三次握手,建立逻辑连接,才能通信(安全). 通信的步骤: 服务器端先启动 服务器端不会主动的请求客户端, ...
- 【零基础学Java】—网络编程(五十三)
[零基础学Java]-网络编程(五十三) 一.软件结构 C/S结构:全称为Client/Server结构,是指客户端和服务器结构,常见的程序有QQ.迅雷等软件 B/S:全称为Browser/Serve ...
- 【零基础学Java】—Socket类(五十五)
[零基础学Java]-Socket类(五十五) Socket类:该类实现客户端套接字,套接字是指两台设备之间通讯的端点. 在Java中,提供了两个类用于实现TCP通信程序 客户端:java.net.S ...
最新文章
- php多表头表格,HTML多表头表格代码示例
- 推进大数据中心新能源应用 广东省六部门联合印发培育新能源战略性新兴产业集群行动计划(2021—2025年)...
- Linux 系统内存分析
- android中控制ListView宽度和高度
- Extended Euclidean algorithm(扩展欧几里得算法Matlab实现)
- TensorFlow Lite 正式发布,谷歌移动端深度学习框架
- Material Design风格登录注册
- 自定义标签之使用struts的valueStack取值
- 利用JS实现QQ空间自动点赞
- Vs2010中文版MSDN 安装方法
- wps右键失效_鼠标点击右键没有反应怎么办
- zuma解析:SEO网站跳出率
- word2019使一级标题为第一章,二级标题为1.1的格式
- notepad打开java乱码_notepad打开中文乱码
- 中国咖啡机市场运行现状调研及投资战略分析报告2022-2027年
- 16999元!华为Mate X终于发布了!附上手视频
- 华为Mate 20 Pro拆解、iPhone XR 拆解、iPhone XS/XS Max拆解
- Java温习——表达式expression
- 什么是MapReduce
- linux多重引导工具,不同操作环境下,如何制作多重引导USB?