FPGA教程:通过Mojo开发板介绍FPGA – 第1部分

这篇文章来源于DevicePlus.com英语网站的翻译稿。

fpga tutorial

引言

迄今为止,我们的嵌入式系统教程和项目已经使用了多块微控制器开发板,比如不同型号的Arduino微控制器板。使用微控制器时,用户将微控制器上的数字和模拟接口引脚连至受控外围电子设备,然后,用户上传包含一系列指令的软件,微控制器会循环执行这些指令。运行时,微控制器的核心处理器按照微控制器模块的时钟速率读取并执行这些指令。因此,我们可以看到,在某一时刻,微控制器通常只运行一条指令。

 

对于许多嵌入式系统项目来说,尤其是那些在入门微控制器模块(比如Arduino开发板)上实现的项目,这种单独的指令执行并不影响性能。这是因为时钟速度足够快,以至于人类感官无法区分后续运行。然而,许多大型应用可能需要不同的操作并行运行,这就使得微控制器实现变得非常复杂或完全不可能。现场可编程门阵列(简称FPGA)是一种不同的计算平台,由于其固有的不同功能方式,能够实现微控制器无法实现的功能。

 

fpga tutorial

图1:一块Arduino微控制器开发板(左)和一块Altera FPGA开发板(右)/ ©RobotShop & ©Waveshare

FPGA和微控制器的主要区别在于配置方法。用户不需要像处理微控制器那样上载一系列指令让板载芯片解释执行,而是直接配置FPGA的硬件。这意味着用户为FPGA编写的程序不是重复执行的一系列指令,而是如何配置内部硬件以执行不同任务的规划。硬件以内部逻辑门和存储单元的形式出现,最基本的级别就是多晶体管电路组合。

由于FPGA的项目实现实际上只是硬件连接,所以FPGA可以并行运行多个操作!想象一下,如果系统任务如下:读取光敏电阻上的压降;读取霍尔效应传感器的输入;并通过UART连接与另一个设备进行通信。微控制器方案的程序流程图可能如下所示:

fpga tutorial

请注意不同任务是串行完成的。而FPGA则可以使用不同电路分别执行三个任务,因此允许系统并行执行所有三个操作。因此,FPGA方案的项目实现原理将如下所示:

fpga tutorial

上述例子只是很简单地解释了微控制器方案与运行和FPGA方案与运行之间的区别,这一点很重要。实际上,FPGA的内部项目实现取决于项目本身,微控制器可能通过并行化执行指令来提高性能。关键的一点是这两种架构实现相同任务的方式不同:微控制器串行执行指令,而FPGA则通过路由内部硬件实现功能行为。

许多FPGA开发板都可以当作入门模块使用,比如Digilent和Xilinx出售的ArtyBasys开发板。在本教程中,我们将使用Embedded Micro的Mojo V3。这是一款低成本板卡,也可用作入门模块。我个人比较喜欢Mojo开发板,比如Basys 3,因为它带有大量可与外部电路连接的插头引脚!此外,Embedded Micro还提供许多很棒的教程,帮助开发人员使用FPGA(请参考附录中的链接)!

fpga tutorial

图2:Mojo V3开发板/ ©Embedded Micro

在本教程中,我们从一个基本的输入/输出示例开始,向您介绍Mojo开发板的编程过程。在第2部分中,我们会为您准备一个更复杂的项目:硬件PWM实现!

本教程演示了如何使用Verilog硬件描述语言(稍后我们将详细讨论该语言)来配置Mojo!Verilog及其变体已经成为行业常用软件,所以您通过 Mojo项目学到的知识也能应用到其他更高级的开发板上!

所需软硬件如下:

硬件:

  • Mojo V3开发板
  • Micro USB电缆
  • Windows或Linux电脑(不幸的是,目前不支持Mac操作系统)
  • 红色LED
  • 1 x 150Ω或类似电阻(用于LED限流)
  • 2 x 10kΩ电阻(用于按钮下拉)
  • 面包板和跳线

软件:

  • Mojo Loader(将设计实现上传至FPGA)
  • ISE Design Suite(编写和综合Verilog代码的IDE)
    • 在下载页面上向下滚动,直到看到标有“ISE Design Suite”的部分
  • Mojo 基本项目所有项目都将以Mojo提供的该项目骨架为基础)

比如说,我们想只有当两个外部按钮都按下时,才能点亮一个外部LED。首先,我们注意到这是一个数字系统,因为按钮输入电压和LED输出电压只能取两个值中的一个:0伏或3.3伏。我们可以用逻辑0表示0伏,用逻辑1表示3.3伏,从而对输入端和输出端的所有可能电压值进行二进制编码。实际上,1和0是“高”和“低”数字电压信号的另一种表达方式。

下表总结了按钮输入的所有值和对应的LED输出值:

 

输入1(按钮1) 输入2(按钮2) 输出(LED
0 0 0
0 1 0
1 0 0
1 1 1

 

熟悉布尔代数(研究二进制值和二进制值的不同运算)的人会把这个双输入单输出系统看作与(AND )门。与门的工作原理是只有当两个输入都是1时输出才是1,这正是我们想要的按钮和LED配置!许多逻辑门将输出值定义为输入值的函数。要查看所有逻辑门的信息,请点击附件中的链接!

我们首先按下图所示将按钮和LED连至Mojo开发板:

fpga tutorial

图3:Mojo开 发板连接一个LED和两个按钮的接线图(通过Fritzing创建;Mojo Fritzing文件由Michael Earls制作)

我们现在可以对Mojo进行编程。启动ISE并打开您下载的基础项目。屏幕应该如下所示:

fpga tutorial

在窗口左侧,您应该看到一个含有不同文件的层次结构。双击文件mojo_top.v。该文件中的Verilog代码应该在屏幕右侧弹出。

fpga tutorial

现在,我们简单介绍一下Verilog语言及其文件结构。首先需要注意的是,Verilog不是传统意义上的编程语言。如前所述,FPGA的内部硬件是可配置的。而Verilog语言则是设计人员和FPGA实现软件(本文为ISE Design Suite)之间的接口。更具体地说,实现软件读取Verilog代码并通过内部算法将其转换成一系列逻辑门,从而实现代码指定的功能。因此,Verilog被称为硬件描述语言,简称HDL。

Verilog代码分为相互作用的多个不同模块——这些模块类似于其他编程语言的函数。这些模块可以有多个输入和输出,模块内部的代码会指定如何根据不同的输入值驱动输出。您可能会注意到,不同模块可以分布在多个Verilog .v文件中。Mojo基础项目包含几个.v文件:AVR、SPI和串行功能。mojo_top.v文件是中心Verilog模块,该模块指定FPGA的主要行为。ISE足够智能,能识别这是程序的中心(“主”)模块。在屏幕左侧的文件层次结构中,您会看到mojo_top.v文件位于列表顶部。

 

fpga tutorial

除Verilog .v文件外,您还会看到一个扩展名为.ucf的文件,该文件代表用户约束文件(User Constraints File)。在这个文件中,用户在他或她的项目中为输入和输出(I / O)连接指定名称,并确定与这些信号相关的引脚和I/O标准。我们开始编辑这个文件。在左侧浏览器中双击文件名,该文件会在右侧的新选项卡中打开。

fpga tutorial

您会看到这个文件中已经存在几条指令。这些指令指定了板上连接的名称,比如板载LED和不同通信总线的连接。向下滚动至文件末尾,按键盘上的“Enter”键创建一个新行。我们要添加三条指令,分别对应两个按钮输入引脚和一个LED输出引脚。 我们要做的就是按照文件中其他指令的格式编写新指令即可!

您可以复制文件中以“NET”开头的任何一条指令,然后在文件底部粘贴三次,修改行首引号内的字符串以及“P”后面的数字。在本教程中,我们将使用14和21脚作为按钮输入,26脚作为LED输出,因此我们应在文件底部添加以下指令:

NET “button_a” LOC = P14 | IOSTANDARD = LVTTL;

NET “button_b” LOC = P21 | IOSTANDARD = LVTTL;

NET “led_external” LOC = P26 | IOSTANDARD = LVTTL;

请确保您选择的引脚不与UCF文件指定的引脚冲突。

现在您的UCF文件应该是这样的:

fpga tutorial

现在我们已经指定项目的具体信号名称及其关联连接,我们可以编写代码,将LED输出描述为按钮输入信号的函数。您可能已经猜到了,这需要修改mojo_top模块。

模块声明部分的顶部是单词“module”(模块),然后是模块名称(本例中模块名称为mojo_top)以及模块将要使用的输入和输出信号列表。我们需要将两个按钮信号名称和LED信号名称添加到该连接列表中,使得信号能够成为输入和输出。要做到这一点,我们可以在信号列表末尾添加以下程序:

input button_a,

input button_b,

output led_external

现在,模块头应该是这样的:

fpga tutorial

至此,我们已经为按钮和外部LED声明了信号名称,并为这些信号分配了Mojo开发板I/O引脚,并且在Verilog中指定这些信号分别是输入和输出。现在,我们所要做的就是定义LED点亮的条件!更具体地说,我们需要指定发光二极管开启(二进制1)和关闭(二进制0)的情况。

回想之前的讨论,我提到LED的操作行为与布尔与(AND)函数完全相同。在Verilog中,我们用符号&&表示布尔与(AND)运算。我们想要将按钮输入的与函数结果分配给LED。实现此功能的Verilog代码如下:

assign led_external = button_a && button_b;

将这行指令添加到模块末尾就可以实现我们所需的行为。打开基础项目时,我们会看到这行程序上方本来就存在许多程序行,这些程序设置了其他不同信号,比如板上SPI和板载LED信号,在本项目中我们不会使用这些信号。

现在,完整模块应该是这样的:

fpga tutorial

要对FPGA进行编程以实现我们指定的行为,我们必须生成一个编程文件,其格式为.bin文件。发出命令之后,ISE会综合我们的设计(检查错误并运行测试),然后实现设计(定义实现指定行为所需的内部门结构),并生成这个编程文件。要运行此过程,请双击左下窗口中的“Generate Programming File”(生成编程文件)按钮。

fpga tutorial

在编程文件生成的过程中,ISE会发出几条丢失网络和/或未路由网络的警告。这些警告对于此实现并不重要,不会影响我们对FPGA的编程。我们没有使用UCF中指定的所有信号,所以ISE才会发出这些警告。

编程文件生成完成后,ISE会在我们刚才双击的按钮旁边添加一个绿色对号。

fpga tutorial

现在,我们所要做的就是将编程文件上传到Mojo开发板上。首先,请确保按上图所示将按钮和LED连至Mojo的引脚。

其次,打开Mojo Loader软件并选择与Mojo相对应的USB端口。然后,选择ISE生成的.bin文件。您必须导航至项目目录下的/syn/文件夹。在Mojo Loader内打开.bin文件后,请点击窗口右下方的“Load”(加载)按钮。编程文件就开始向Mojo开发板上传。

fpga tutorial

该过程完成后,您就可以测试您的设计了!只有按下两个按钮时,LED灯才会点亮。恭喜,您已经完成了您的第一个FPGA项目!我们还为您准备了一个更复杂的硬件PWM项目,敬请查看本教程的第2部分!

 

附录

Embedded Micro教程:https://embeddedmicro.com/tutorials/mojo

逻辑门:https://en.wikipedia.org/wiki/Logic_gate