用VHDL语言创建一个8位算术逻辑单元(ALU)

描述

来源:内容由半导体行业观察(ID:icbank)编译自allaboutcircuit,谢谢。

在这个项目中,我们用 VHDL 语言创建一个 8 位算术逻辑单元 (ALU),并在连接到带有输入开关和 LED 显示屏的定制 PCB 的 Altera CPLD 开发板上运行。

使用基于硬件的方法开发电子系统并不总是需要将各种晶体管和逻辑门物理连接到面包板或 PCB 上。可以使用离散逻辑构建算术逻辑单元(ALU),但随着逻辑复杂性的增加,有更好的选择。通过可编程逻辑器件和硬件描述语言(HDL),从简单电路到高度专业化的处理单元的任何东西都可以在单个芯片内实现。

ALU项目概述

在这个项目中,我将逐步创建带有输入 DIP 开关和输出 LED 的 8 位 ALU 电路,如图 1 所示。我使用 VHDL 语言对 ALU 进行编码,并在复杂可编程逻辑器件上运行它( CPLD)开发板。我的目标是介绍可编程逻辑,并为使用真实硬件而不仅仅是图表和计算机模拟打开大门。

晶体管

对于此项目,我构建了带有 All About Circuits 品牌的定制印刷电路板 (PCB),如图 2 所示。与更知名的现场可编程门阵列(FPGA ) 相比,CPLD 是一种更实惠但功能稍弱的可编程逻辑器件)。这两种器件均可用于创建具有专用输入和输出的定制电子设计。

晶体管

在内部,这些 CPLD 和 FPGA 组件包含可重新配置逻辑块阵列,并封装为独立 IC,以便嵌入到您自己的设计中。制造商提供开发板,用于使用其技术和软件环境进行学习、测试和实验。我的 CPLD 使用了开发板。

什么是 ALU?

每个处理器的核心都有一个组合逻辑电路,它对整数二进制数执行算术和按位运算,称为算术逻辑单元。我们将在这个项目中构建的电路是一个 8 位 ALU,它包含两个 8 位操作数(输入)、一个 8 位结果(输出)和一个 4 位操作码(输入),该操作码定义将执行什么操作(图3)

晶体管

ALU 通常包含状态位(既作为输入又作为输出),为处理器提供有关上次执行操作的重要信息。该状态信息可以包括结果是否为零或者结果是否溢出到最高有效位(MSB)之外。然而,我们的电路不需要它们,因此不会包含任何它们。

ALU 为学习 VHDL 编码和 CPLD 编程操作提供了一个极好的起点。完成此项目后,您可以轻松扩展到更困难的应用程序。

项目详情和参考资料

在这个项目中,我们将用VHDL语言创建一个8位算术逻辑单元(ALU),并使用Intel的Quartus Prime Lite Edition软件(Altera现已成为Intel的一部分)在Altera Max II EPM240 CPLD开发板上运行它。该电路的代码基于加州大学河滨分校发布的实验室练习设计。

对于这个项目,您需要对编程和离散逻辑有基本的理解。查看AAC 对 VHDL和4 位离散逻辑 ALU 项目的介绍也会有所帮助。

注意:虽然我创建了一个用于该项目的“屏蔽”型板,但这里介绍的所有内容都完全适合面包板和穿孔板。

使用 Quartus Prime 为 Altera MAX II 开发板设置新项目

要开始处理我们的项目,我们需要下载并安装 Quartus Prime Lite Edition 并创建一个文件夹来存储所有项目。我从Intel的网站下载了该软件,并在“Windows Documents”目录中创建了一个名为“quartus”的文件夹。

当我们运行 Quartus 时,我们需要做的第一件事是通过“New Project Wizard”建立一个新项目,该向导可以在“File -> New Project Wizard”下找到。然后,我们需要在名为“简介”的第一个屏幕上单击“下一步”。

如图 4 所示,在名为“目录、名称、顶级实体”的第二个屏幕上,我们需要选择之前创建的文件夹作为工作目录,并为当前项目指定适当的名称。我将这个项目命名为“ALU”。

晶体管

对于“项目类型”屏幕,我们需要选择“空项目”并将下一个名为“添加文件”的屏幕保留为空(图 5)。

晶体管

在“Family, Device & Board Settings”屏幕上,我们需要从“Device family”部分的下拉菜单中选择“MAX II”(图 6)。然后,从“Available devices”部分中选择“EPM240T100C5”,因为这是 Altera MAX II EPM240 上的芯片。

晶体管

接下来,我们需要在“EDA Tool Settings”屏幕上将“Verilog HDL”更改为“VHDL”,单击“下一步”,并检查“Summary”中的一切是否正确(图7)。之后,我们可以单击“完成”按钮,我们的新项目将被创建。

晶体管

该项目打开后,我们需要在“项目导航器:层次结构”窗口中单击实体的名称,然后按“CTRL+N”并选择“VHDL 文件”来创建一个新的 VHDL 文件。

该文件打开后,我们必须通过进入“文件 -> 另存为”将其另存为实体的 VHDL 文件。当所有这些完成后,我们就可以开始为 ALU 编写代码了。

声明 VHDL 库

与所有编程语言一样,我们需要在 VHDL 代码顶部做的第一件事是声明将在项目中使用的库。

LIBRARY ieee;

USE ieee.std_logic_1164.ALL;

USE ieee.std_logic_unsigned.ALL;

USE ieee.std_logic_arith.ALL;

现在我们需要设计电路的架构或行为。我们将使用三个输入或端口A、B和Sel创建一个流程。

在此过程中,我们可以调用“case-when”语句(类似于其他编程语言中的“switch-case”),在其中检查端口SEL的状态。SEL值是 ALU 的操作码,决定在端口A和B接收的两个 8 位数字之间需要执行哪个操作。

这是在语句的“when XXXX =>”部分完成的,其中XXXX代表SEL的二进制状态(0000 到 1111 之间的位置)。每个状态都分配给使用端口A和B上接收到的值执行的相应 ALU 操作。输出在端口RES上写出。

之后,我们可以结束“case”语句、流程和行为架构,并结束我们项目的代码部分。

ARCHITECTURE behv OF alu IS

BEGIN

PROCESS (A, B, Sel)

BEGIN

CASE Sel IS

WHEN "0000" =>

RES <= "00000000"; -- no operation

WHEN "0001" =>

RES <= A + B; -- addition

WHEN "0010" =>

RES <= A + (NOT B) + 1; -- subtraction

WHEN "0011" =>

RES <= A + 1; -- add one to operand A

WHEN "0100" =>

RES <= A - 1; -- subtract one from operand A

WHEN "0101" =>

RES <= A(6 DOWNTO 0) & '0'; -- shift operand A to the left

WHEN "0110" =>

RES <= '0' & A(7 DOWNTO 1); -- shift operand A to the right

WHEN "0111" =>

RES <= NOT A; -- one's complement of operand A

WHEN "1000" =>

RES <= NOT A + 1; -- two's complement of operand A

WHEN "1001" =>

RES <= A AND B; -- logical and

WHEN "1010" =>

RES <= A OR B; -- logical or

WHEN "1011" =>

RES <= A NAND B; -- logical nand

WHEN "1100" =>

RES <= A NOR B; -- logical nor

WHEN "1101" =>

RES <= A XOR B; -- logical xor

WHEN "1110" =>

RES <= (NOT A) + (NOT B); -- random operation

WHEN "1111" =>

RES <= (A + B) AND (A OR B); -- another random operation

WHEN OTHERS =>

RES <= "00000000";

END CASE;

END PROCESS;

END behv;

在上面的代码中,我包含了一些最常见的算术和逻辑运算以及一些随机运算,并对它们各自的作用进行了评论。在这里您可以替换并包含您想要的任意算术或逻辑运算!

引脚映射

当我们的代码完成后,我们需要做的第一件事就是编译它。这可以通过进入“处理 -> 开始编译”来完成。如果一切都正确编译,我们不应该收到任何错误消息,尽管我们可能会收到一些可以忽略的警告。

接下来,我们需要将之前为实体定义的端口连接到 Altera 开发板上的物理引脚。我们将通过 Quartus 的 Pin Planner 工具来完成此操作,该工具可通过“Assignments -> Pin Planner”访问。

引脚规划器工具包含:

所用芯片(本例中为 EPM240)的直观表示。

描述每种引脚类型的引脚图例。

包含来自我们实体端口的每个单独节点的表。在此表中,我们可以通过将每个节点写到“位置”列的相应行中,将其连接到专用引脚。

表 1 包含我生成的引脚分配表。

晶体管

将代码上传到 Altera 开发板

将每个输入和输出分配给引脚后,我们需要再次编译代码。如果没有弹出错误消息,我们可以继续将其上传到Altera MAX II。

为此,我们首先必须通过板载桶形插孔将板本身连接到 5 V 电源。接下来,我们必须通过JTAG端口将其连接到 USB Blaster,然后使用迷你 USB 插孔将 USB Blaster 连接到我们的计算机(图 8)。

晶体管

之后,我们可以通过进入“工具->编程器”并选中“编程/配置”来运行编程器,如图9所示。然后我们需要打开“硬件设置”并选择“USB Blaster”作为我们的“可用硬件” item”(我们的程序员),然后单击“Start”将我们的代码上传到 Altera MAX II。

晶体管

PCB电路图

图 10 的原理图描绘了我们的电路图。每个 LED 通过限流电阻连接到输出引脚。连接到输入引脚的 DIP 开关的每个触点也通过电阻网络下拉至地面(在定制 PCB 上,这些触点隐藏在 DIP 开关下方)。

晶体管

连接完所有内容并为 Altera 板供电 5 V 后,我们可以通过在操作数端口上输入数字并将操作模式切换到我们喜欢的任何操作来看到 ALU 开始工作。LED 显示结果,如上图 1 所示。

ALU 项目的 BOM

表 2 包含该项目的材料清单。

晶体管

在这个项目中,我们用VHDL语言创建了一个8位ALU电路,并在CPLD开发板上运行它。在这里,我的目标是介绍可编程逻辑,并为使用真实硬件组件而不是图表和计算机模拟来使用 FPGA 组件打开大门。

如果您复制此项目,您可以轻松地将其他操作码添加到 ALU 的 VHDL 操作中。您还可以修改电路设计以输出和显示状态代码。在下面的评论中分享您的想法或项目!

  审核编辑:汤梓红

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分