从VHDL代码到真实硬件:设计有限状态机

从VHDL代码到真实硬件:设计有限状态机
2024年09月03日 09:06 电子产品世界

学习如何通过创建一个4位二进制计数器,在VHDL中实现有限状态机。编译后,它将在连接到带有输入开关和LED显示器的自定义PCB的Altera CPLD开发板上运行。

本文引用地址:

本项目是我“从VHDL代码到真实硬件”系列的第二部分,在该系列中,我们使用基于硬件的方法和可编程逻辑IC设计简单的电子系统。这些系统为重要设计概念提供了极好的介绍,这些概念也可以应用于更复杂的项目。

有限状态机项目概述

在这个项目中,我将介绍有限状态机(FSM)的开发。具体来说,我将构建一个4位二进制计数器,带有四个输出LED和一个四位DIP开关模式输入

逻辑将使用VHDL(一种硬件描述编程语言)编写,并上传到复杂可编程逻辑(CPLD)芯片。CPLD是一种可重复编程的现成逻辑门IC,类似于FPGA。

本项目将使用与我之前设计的8位算术逻辑单元(ALU)相同的硬件和软件设置:

Altera Max II EPM240 CPLD开发板,

英特尔的Quartus Prime Lite版IDE。

如果您想复习可编程逻辑集成电路和Quartus Prime套件的基础知识,您需要查看之前的项目。

什么是有限状态机?

在深入设计之前,我们先快速回顾一下有限状态机。有限状态机是顺序逻辑电路的抽象数学模型,在任何给定时刻,它只能在有限数量的状态中运行。

FSM可以在每个时钟周期在其状态之间转换一次。下一个状态基于外部输入和当前状态(这意味着它使用了记忆逻辑)。

有限状态机可用于检测或生成序列,是电梯、交通灯、自动售货机和电子锁等系统的基础。

二进制计数器

有限状态机(FSM)的一种特殊实现是二进制计数器。这些电路的设计目标是迭代并显示所需的二进制数序列,通常使用一系列相互连接的触发器构建。二进制计数器的每个新状态都必须由输入脉冲触发,该脉冲可以来自外部源或电路自己的时钟信号。

有了这些背景知识,让我们深入了解一下4位二进制计数器的代码。

FSM二进制计数器的VHDL代码

我们将在VHDL文件的顶部声明几个库,开始为二进制计数器编写代码:

港口定义

接下来,我们将为我们的电路创建一个名为fsm的实体,并定义其输入和输出端口:

在此代码片段中,我们定义了:

流程和数据类型定义

既然我们已经定义了FSM实体,我们就可以为我们的电路创建一个架构。这个架构将有三个过程:

状态记忆。

下一个状态逻辑。

输出逻辑。

在创建这些进程之前,我们需要为我们的状态定义一个新的数据类型,并为该数据类型定义两个信号变量,用于记忆当前状态和下一个状态(将它们视为寄存器)。

状态记忆过程

现在我们可以创建第一个名为STATE_MEMORY的进程。使用IF语句,它会在CLK信号的每个上升沿将下一个状态的值写入当前状态变量。

下一个状态逻辑过程

我们将使用SEL输入端口和CURRENT_STATE信号创建一个名为NEXT_STATE_LOGIC的进程。在这个进程中,我们为当前状态调用一个CASE-WHEN语句。我们在第一个CASE-WHEN语句的每个WHEN子句中嵌套其他CASE-WHEN语句以用于模式。

这样,我们就有了一个架构,它首先检查FSM的当前状态,然后从SEL端口读取值。当这个过程完成时,最后一个嵌套的WHEN子句将根据我们的代码(对正在计数的序列)将正确的下一个状态值写入NEXT_STATE信号

下面的代码块显示了一个简单的向上计数器,当SEL端口值等于“0000”时,该计数器处于活动状态。为了简洁起见,这里只显示了一些重复的case语句,但完整的代码将在下面提供。

跳过案例,C3到C13是相似的,我们到达NEXT_STATE_LOGIC过程的末尾,我们有:

输出逻辑流程

最后,为了在4位LED显示屏上输出当前状态,我们需要编写另一个名为OUTPUT_LOGIC的进程。它枚举了我们之前定义的每种状态类型,并配以相应的4位二进制数。

这同样是通过使用CURRENT_STATE信号并调用另一个CASE-WHEN语句来完成的。CNT输出表示当前状态作为其4位二进制对应物:

编译代码

编写代码后,我们首先需要编译它。然后,我们必须使用Quartus的Pin Planner工具,将我们在程序中定义的端口分配到Altera CPLD的物理引脚上,使用表1中显示的映射。

表1. 端口到引脚映射

上传到开发板

接下来,我们需要再次编译代码,然后才能最终将其上传到开发板上。此过程是使用通过JTAG连接到Altera MAX II的USB Blaster进行的,如图1所示。

Altera板和USB Blaster连接

图1. Altera板和USB Blaster连接。图片由Kristijan Nelkovski提供图1. Altera板和USB Blaster连接。图片由Kristijan Nelkovski提供

添加外部触发器

将代码上传到Altera板后,我们需要添加一个时钟信号——某种类型的外部触发器,使我们的计数器能够遍历其状态。在这里,我要稍微作弊一下,使用运行默认Arduino Blink草图的Raspberry Pi Pico,它充当我们电路的粗糙时钟源。

您可以使用任何其他MCU开发板来实现此功能;只需确保向Altera MAX II发送3.3 V逻辑电平信号即可。Raspberry Pi Pico本身输出3.3 V逻辑信号。

在我们的电路中,Blink草图将提供0.5 Hz的时钟信号(您可以在Arduino代码的延迟部分更改频率)。它不会让LED闪烁一秒钟,然后再熄灭一秒钟,而是告诉我们的同步电路何时切换到其下一个状态,如我们的VHDL代码中所定义。

PCB电路图

图2中的示意图显示了项目的完整电路图。在这里,每个LED都通过限流电阻连接到输出引脚,连接到输入引脚的DIP开关的每个触点都通过电阻网络下拉到地。然后,时钟引脚连接到运行Blink的微控制器板上的假定LED引脚。

4位二进制计数器项目的电路原理图

图2:4位二进制计数器项目的电路示意图。图片由Kristijan Nelkovski提供图2:4位二进制计数器项目的电路示意图。图片由Kristijan Nelkovski提供

在将所有东西连接起来并为电路提供足够的电源后,我们的FSM计数器应根据通过DIP开关选择的计数模式,开始在其四个LED上迭代不同的二进制序列。

设计其他计数序列

对于SEL输入的其他值,您可以创建任意4位数字序列。在本文末尾的完整代码下载中,我包含了16种计数模式,可以使用表2中描述的4位SEL输入进行选择。

表2. 计数模式的SEL控制

注意:从技术上讲,斐波那契数列应该重复出现1,但在这个简单的项目中,这些序列中只有一个1。

物料清单

表3包含项目物料清单(BOM)。

表3. 4位计数器物料清单。

轮到你了!

在这个项目中,我们使用VHDL硬件描述语言创建了一个有限状态机电路,并在CPLD开发板上运行。本系列文章的目标是介绍可编程逻辑,并使用真实硬件而不是电路图和计算机模拟来深入了解FPGA组件的实际使用。

如果你复制这个项目,你可以随时修改代码,切换计数模式,或者根据需要添加和删除不同的序列。在下面的评论中分享你的想法和修改!

新浪科技公众号
新浪科技公众号

“掌”握科技鲜闻 (微信搜索techsina或扫描左侧二维码关注)

创事记

科学探索

科学大家

苹果汇

众测

专题

官方微博

新浪科技 新浪数码 新浪手机 科学探索 苹果汇 新浪众测

公众号

新浪科技

新浪科技为你带来最新鲜的科技资讯

苹果汇

苹果汇为你带来最新鲜的苹果产品新闻

新浪众测

新酷产品第一时间免费试玩

新浪探索

提供最新的科学家新闻,精彩的震撼图片