[FPGA 学习记录] 简单组合逻辑——半加器

简单组合逻辑——半加器

在前面两小节当中,我们设计并实现了简单组合逻辑中的多路选择器和3-8译码器。

那么本小节我们将使用 Verilog 语言描绘一个具有半加器功能的电路,同样使用的是简单组合逻辑,为什么要实现半加器功能呢?我们是想通过半加器引入我们的全加器,进而引入层次化设计的方法。

本小节的主要内容分为两个部分:第一部分是理论学习,第二部分是实战演练。
在理论学习部分,我们会讲解一下半加器的相关内容;在实战演练部分,我们会设计并实现一个半加器。
首先开始理论学习

1 理论学习

半加器

加法器是我们数字电路中经常用到的一种基本器件,它主要用于两个数或多个数的相加。加法器又分为半加器和全加器:半加器电路是指对两个输入数据位相加,输出一个结果位和一个进位,它没有进位的输入,它是实现一位二进制数的加法运算电路;全加器是半加器的升级版,除了加数和被加数之外,还要加上上一级传进来的进位信号。

以上就是理论知识的讲解,下面进入实战演练。

2 实战演练

2.1 实验目标

首先搞清楚我们的实验目标:我们希望使用简单组合逻辑,实现一个半加器,功能怎么实现呢?

2.2 硬件资源

同样的,我们使用按键和 LED 灯。我们可以使用我们开发板上的 KEY1 和 KEY2 两个按键,作为两个加数,然后使用 LED 灯 D6,表示相加和的输出,然后使用 D7 表示进位的输出。

image-20231023192703406

那么功能的实现方法已经明确了,接下来就正式开始我们的实战。

2.3 程序设计

首先要新建工程存放位置,新建一个文件夹,文件体系的建立我们已经设置了很多次,这儿应该是轻车熟路。

20231023162320_FDHZ8cEDAA

2.3.1 模块框图

文件体系建立完成之后,打开 doc 文件夹,然后新建 Visio 文件,打开 Visio 文件,开始我们的模块框图的绘制以及波形图的绘制。然后 取消 放大,添加我们的波形工具箱

tPEVeJqWuA

首先是模块框图的绘制,那么输入信号有两个,就是两个被加数

20231023162911_ydn00BphJZ

输出信号也是有两个:一个是结果位,一个是进位。结果位用 sum 表示,进位用 cout 表示

20231023163401_zfSq4ZJZP9

2.3.2 波形绘制
2.3.2.1 真值表

模块框图已经绘制完成,下面开始设计我们的真值表

20231023163559_Sd9iVMiEc1

当两个按键都被按下时,输入的都是 0,两个 0 相加,结果位也是 0,进位也是 0;那么如果只按下 KEY1 松开 KEY2,就是 KEY1 输入的是 0, KEY2 输入的是 1,那么 0 和 1 相加,得到的结果位是 1,进位也是 0;如果只按下 KEY2,松开 KEY1,结果位也是 1,进位还是 0;如果两个按键都不按下时,输入的都是高电平 1,那么结果位就是 0,进位就是 1

20231023164024_bB15syAw2R

下面就可以参照真值表进行波形图的绘制。

2.3.2.2 波形图

首先是两路输入信号,我们填充为绿色;然后是两路输出信号,我们填充为红色

20231023164312_fp5X8na6GO

下面就是参照着真值表进行波形图的绘制。用这个符号表示数据变化,为了方便绘制我们添加一个参考线,对它进行一个颜色的区分,然后变成虚线,将它拉长

20231023164615_eAh8rcIGEw

两路输入信号初始值都是未知,用 X 表示。输入信号未知,得到的进位和结果位也是未知的

20231023165007_IunkUpIJhx

那么参照真值表的第一行:输入信号是 0,得到的结果位和进位也是 0。然后参照着真值表,继续进行波形的绘制

20231023165440_bRTzQzBVKI

那么这样就完成了波形图的绘制。

2.4 代码编写

下面就开始参照着波形图进行代码的编写,首先来新建我们的 .v 文件

20231023165825_q6esMLtiXb

我们前面部分的章节它的内容是比较简单的,所以说波形图也比较简单,那么参照着波形图就可以很快的进行代码的编写。
首先是模块的开始,然后是模块名,然后是 端口列表

7owapPbody

输入信号,然后是 输出信号,那么输入信号和输出信号之间,我们习惯隔开一行,这样在实例化的时候,方便输入信号和输出信号的区分。上面是输入信号,下面是输出信号输出信号的类型我们也使用 wire 型,因为后面我们使用 assign 语句对它们进行赋值

TyaQ16so5s

那么端口列表编写完成,接下来就开始对它们进行赋值。
我们使用 assign 语句,然后使用位拼接的方式,将进位放在高位,结果位放在低位,这样就完成了输出信号的赋值

f6bliMRtz6

将输入信号相加,相加之和的低位赋值给结果位,高位赋值给进位。
我们这里编写的代码比较简单,大家也可以使用其他的组合逻辑对他们进行赋值。

2.5 编译代码

我们对文件进行保存,然后回到桌面,建立我们的实验工程。下一步 文件命名 下一步 下一步,选择我们的芯片,这儿都已经是轻车熟路了

d3IQ6zsaFq

然后添加我们的 .v 文件,然后编译,查找语法错误,点击 OK

20231023171312_MgBhpKR9vp

接下来可以查看一下 RTL 视图,点击这个位置,按住 Ctrl 并滚动鼠标滚轮可以对它进行缩放

20231023171431_n2htbNPNFC

我们可以看到,我们的代码应该是出现了错误,回到代码文件,更正后保存并且重新编译

20231023171714_qkBeONj4HF

我们的代码已经被综合成了一个加法器:ADDER
下面就是仿真验证。

2.6 逻辑仿真

找到我们的文件夹,找到 sim 文件夹,建立一个仿真文件,双击打开

20231023171928_VvngUj540p

现在就可以开始仿真文件的编写。
首先是时间参数,然后是时间单位、时间尺度,然后是模块、模块名、端口列表

20231023172138_O5WL4LtDHr

然后定义两个模拟输入信号,然后定义两个 wire 型的输出信号

20231023172303_bdJewqmJk6

下面就是我们的输入信号的初始化,使用 initial 语句

20231023172415_sLnGYjtEcE

然后是模 2 取余法

20231023172603_OU1OY5X3fL

然后是模块的实例化

20231023172725_1310iXiSvd

然后将信号相连接

20231023172834_QdqDJiZ41E

同样为了便于观察,使用一些系统函数。
仍然使用 initial 语句,首先是时间格式的设置,这个我们也已经编写了很多次了,大家应该很熟悉了,然后是纳秒、小数位数,然后单位,然后是打印字节数

20231023173200_ExNV2s2K4j

这样时间格式就编写完成,开始监测函数

20231023173358_y5aRQ3Twmg

那么这样,监测函数也已经编写完成,对文件进行保存
然后回到我们的实验工程,添加我们的测试文件

20231023173610_ilE4Ez7Fjd

然后进行仿真设置

20231023173741_wlHwjpQySd

然后开始仿真

20231023173934_U6lQRLuF6i
那么编译通过了,现在可以开始仿真。
我们可以找到我们的 sim 选项卡,把我们的被仿真模块添加到波形当中,选中它,可以使用快捷键 Ctrl+W,然后将它的波形添加到波形窗口,然后使用 Ctrl+A 进行波形的全选,然后使用 Ctrl+G 可以进行分组,然后点击左下角这个位置,可以进行路径的屏蔽

20231023174326_itESbd42O1

我们在这儿再教大家一些 ModelSim 使用的一些技巧,比如说我们意外的关闭了这个波形窗口,怎样把它调出来呢?我们可以使用 View,然后在我们这个位置 勾选,我们的波形窗口又重新回到了界面

20231023174504_zMDAP4jLM3

我们再添加我们的模块,选中它使用快捷键,然后对它们进行分组

20231023174626_vDk0QXzE4K

我们还可以点击右上角这个位置,将它单独拉出来,然后再次点击这个位置又可以把它锁定回去

20231023174807_3dAGkjzQis

如果说你的 ModelSim 界面,因为你的误操作发生了混乱,我们可以把它们初始化,点击这个位置,然后选择 Reset,它就会回到最初的模样,我们可以选择任意窗口的界面,点击它们右上角的 +,就可以把所有的选项卡放在下面,这样方便操作,而且更加清晰

20231023174959_C3M3ZBfD2y

接下来开始波形的查看,我们使用 Restart 清除所有的波形,然后输入参数 100us,然后运行一次

20231023175128_VcvDCJRYgg

进行全局视图,添加我们的参考线,然后以参考线为中心进行放大,下面将我们的仿真波形与我们绘制的波形图进行比较

20231023175427_lXWV57EIcW

我们任选一个位置,比如说这个位置,输入信号 1 是高电平,输入信号 2 是低电平,结果位就是 1,进位是 0,这种情况与我们波形图中这种情况是对应的

w3FntHIljv

然后我们再选取一个位置,比如说这个位置,两个输入信号都是高电平,结果位是低电平,进位是高电平,与这个位置对应了

20231023175813_PJtmYqKLQC

然后查看打印列表,将打印列表与我们的真值表进行比对。我们随便选择一组数据,选择这一组。输入信号 1 为高电平,输入信号 2 为低电平,那么结果位是 1,进位是 0 与真值表之中的这个是对应的

YWJphpJADP

再随便选取一组数据,比如说这个位置,那么输入信号 1 和输入信号 2 都是高电平,结果位是 0,进位是 1,那么与最后一行是对应的

VCqvvRPuD0

仿真波形与我们绘制波形图是一致的,而且打印列表与真值表也是一致的,所以说仿真验证通过。
那么下面就可以进行上板验证

2.7 管脚绑定

上板验证之前是管脚的绑定。我们在我们的实验工程中,点击这个位置,绑定我们的管脚,那么进位是与 D7——LED 灯相连,它与 FPGA 的物理连接是 M6,点击回车;那么按键 1 是 M2 回车,按键 2 是 M1 回车;然后结果位是 L7 回车,这样管脚绑定完成

20231023180541_Izync6R6Jm

进行一次全编译,编译完成之后有 7 个警告,我们点击 OK

20231023180710_jh1V95O8LA

2.8 上板验证

按照下图所示,连接我们的板卡与下载器还有电源,下载器的另一端连接电脑,我们为它上电

上板验证前的硬件连线

点击工具栏上的 Programmer 图标,选择 Add File…(添加文件),找到 output_files 文件夹,选择我们的 led.sof 文件,点击 Open,点击 Start(开始),文件下载完成

20231023190745_3wNuZGPV0K

程序下载完成,我们打开摄像头
当按键 KEY1、KEY2 都没有被按下时,它们输入的都是高电平,那么结果位就是 0,进位就是 1,表示结果位的 LED 灯被点亮;如果说按下按键 KEY1 或者按下按键 KEY2,它们两者之中有一个是高电平,有一个是低电平,那么结果位就是高电平,进位就是 0,所以说表示进位的 LED 灯被点亮;如果 KEY1、KEY2 两个按键同时被按下,这就表示输入信号都为 0,那么进位也为 0,结果位也为 0,所以说两个 LED 灯都被点亮

半加器 上板验证

那么上板验证通过


参考资料:

6. 简单组合逻辑 — 半加器

09-第八讲-简单组合逻辑——半加器

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值