理解VHDL基本概念

1 篇文章 0 订阅

An Introduction To VHDL

Abstract

FPGA(现场可编程逻辑阵列),是一种领先的硬件设计方式,简单地说,用户可以根据需要为开发板设计功能,并且可以随着需求的改变随时改变功能,而对开发板功能的编程,就是由VHDL(高速集成电路硬件描述语言)完成。

由于方便易用的特性,FPGA和VHDL语言在现代嵌入式系统中占据着统治地位,并且在机器学习设计中扮演着越来越重要的作用,FPGA设计师的需求也水涨船高,然而,由于VHDL语言和传统程序设计语言的诸多差异,许多人在接触伊始感到困难。

< XillinxFPGA 设计基础(VHDL版)>是西安电子科技大学出版的一套教材。语言简洁易懂,内容充实,设计合理,注重实验,在实际教学中长期使用。然而,这本书的讲述依然存在着问题,有一些有可能造成困惑的地方,人非圣贤,孰能无过,本文的目的是结合这本经典教材,从一个读者的角度进行梳理,补充和注解,帮助苦于入门的朋友释疑解惑为盼。

顶级抽象:实体和结构体

抽象是计算机科学的基础方法,任何高级语言都将抽象概念作为安身立命之本,例如,C语言中的变量,结构体,Java中的类与实例。VHDL语言作为一种直接定义硬件的高级语言,自然拥有更为庞大的抽象层次1

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RL92651x-1583140120360)(F:\Users\iSIka\AppData\Roaming\Typora\typora-user-images\image-20200301224431542.png)]

实体(entity)就是一个函数,一个明确输入和输出的单元,定义实体时,只需要考虑输入和输出各是什么,不需要考虑输入到输出是如何得到的,这就是计算机科学中著名的黑盒抽象。

构造体(architecture),称之为结构或许更好理解,因为它的功能就是定义黑盒内部的结构,也就是,输入到底是如何变成输出的。

那么,在VHDL中如何定义实体呢?

entity name is 
    port (A : 数据类型;
          B : 数据类型
         );
end entity;

可以看到,定义实体就是定义port,也就是输入和输出,在已知输入输出之后,实体还需要一个名字,将其和其他实体区分。

在VHDL中又是如何定义构造体呢?

architecture arc_name of entity_name is
    do something to get B from A
end architecture;

构造体具体的编写方式,将在下文学习,目前只需要知道,你需要为构造体赋予一个名字,将其与实体绑定即可。实体和构造体之间可以看作一对多的关系,同一个实体可以拥有不同的构造,因此需要名字将其区分。

次级抽象:组件,实例

在构造体中使用已经编写好的实体时,你需要将初始化为实例,具体有两种方式,一是在库中找到你想使用的实体,直接将其初始化,二是先将实体声明为组件(component),再从组件初始化。

A: entity work.entity_name(arc_name) port map(...);
component entity_name
    port(...)
end component
A: entity entity_name(arc_name) port map(...)

其中,port map的作用就是指定实体输入的来源,输出的去向,既可以使用位置对应,也可以使用命名对应。

在这里插入图片描述

我们可以看到,第一种方式要比第二种方便得多,因为component这一层抽象本身不是必要的,我们将会在后面考虑这个问题。

次级抽象:信号

我们讨论了在构造体中使用实体,是通过实例化,那么,想象这样一种情况:

在这里插入图片描述

这是一个AND_OR器件,AND_OR的四个输入分别成为两个2位AND器的输入,而AND_OR的输出就是二位OR的输出,但是AND的输出呢?在定义U0的时候,是不知道U2的存在的,因此我们没办法直接说:U0的输出是U2的输入。

我们可以发现,原件互相独立的初始化方式,为结构描述带来了困难,因此我们需要一些中间变量,这就是信号(signal)。

signal SIG1:std_logic;
U0:entity MY_AND2 map port(INP(0),INP(1),SIG1)

Plug into PCB:配置和组件

我们在第二部分留下了疑问:为什么需要PCB这样一个看似多此一举的抽象?

为了解决这个疑问,请想象一个PCB电路板:

在这里插入图片描述

一个电子器件由电路板上许多小部件组成,也就是我们定义的功能单元:实体,然而你会发现,实体在被插到PCB上之前,首先上了一个套,这个套把内部结构完全屏蔽起来,外界只知道针脚的信息。

而这个套就是组件(component),第二部分中,我们说:先将实体声明为组件,其实这是不确切的,因为实体和组件之间并不是绑定的关系,我们之所以必须为二者取相同的名字和输入输出,只是因为这是默认的匹配方式,当你这样定义之后,如果没有显式写配置语句,编译器就会直接找到库下和组件同名的实体2,将其插入套中。

正如更换CPU,在VHDL中,你可以随时更换组件对应的实体,只要它们的针脚(输入输出)对应。

configuration MUX2_specified_CFG of MUX2 is
  for STRUCTURE  --对于mux2的structure构造体
    for G2 : AOI  --对于构造体中G2这一组件
      use entity work.AOI(v1);  --使用库中AOI(v1)实体
    end for;
  end for;
end MUX2_specified_CFG;

迄今为止,我们学习了实体,它是完整的功能单元,学习了构造体,它是实体功能的描述,学习了信号,通过它,我们将功能单元自小而大,自底向上的组织起来,学习了配置,它帮助我们有条理地组织和动态更换实体,那么,目前为止已经可以完成很多设计实验了。

编程方式:结构和表现

有时你会希望以结构的方式描述功能3,但有的时候,你很清楚实体应该做什么,将他分解为小的组件却是困难的,例如,仅仅知道真值表,却不知道真值表对应的逻辑表达式。

在这种情况下,表现结构(behavioral architecture)4是适用的,它允许你用if,case,loop等控制语句描述硬件行为,换句话说,如果你使用控制语句而不是硬件结构来描述功能,这就是表现式的,它说明了硬件在什么情况下应该怎么做,却不关心具体怎么实现4

例如,一个二位数据选择器:

在这里插入图片描述
如果你幸运地化简出它的表达式:

Z=!(!(a&&sel)||(b&&!sel))

你可能会这样编写:

  selb <=  not sel;
  fb <= not((a and sel) or (b and selb));
  f <= not fb;

晦涩难懂,不是吗?

相反地,采用表现结构的VHDL如下所示:

  process (sel, a, b)
  begin
    if sel = '1' then
      f <= a;
    else
      f <= b;
    end if;
  end process;

这很简单,它的功能是什么,就怎么编写代码。

一言以蔽之,我们可以用过程(process)替代掉繁琐的实体分解,直接描述功能。同一个实体可能拥有多个过程,只要功能上相互独立,就应该以不同的过程描述。

Last Issue:并行和顺序

一言以蔽之,结构体中的所有元素(<=赋值,process)都是并行的,因为它们都定义了实体一部分独立的功能,而过程中的语句是顺序执行的,因为它们是一个整体

A <= '0'
B <= A
Process(A)
begin
	C <= A
    D <= C
end process;
Process(A)
begin
	E <= A
    F <= C
end process;

Conclusion

在这篇文章中,我们叙述了VHDL最重要的几个概念,这是理解VHDL的重点和难点。

当然,还有很多基础功能是本文没有涵盖的,例如:操作符,generic,变量,为了实际使用VHDL,你必须学习这些内容。

Reference

  1. < XillinxFPGA 设计基础(VHDL版)> -西安电子科技大学出版社
  2. VHDL Designer Guide -duolos.com
  3. Many Great Questions in Stackoverflow

  1. 本文认为,这是它的优点,但也是难以学习的原因。我们都知道,抽象层次越多,快速原型越困难,在C语言中只需要一个main函数就能完成一次快速原型,在VHDL中却至少需要实体(entity)->构造体(ARCHITECTURE)->测试器(Test Bench),在这三部分完成之前,设计人员宛如虔诚的信徒,唯有祈祷一途。 ↩︎

  2. 的最新结构版本 ↩︎

  3. 大多数时候,这是因为他的结构是明确可分的。 ↩︎

  4. 也称为RTL ↩︎ ↩︎

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值