FPGA与VHDL 小结

本文详细介绍了FPGA的基本概念,解释了它如何通过VHDL编程实现硬件逻辑,并探讨了VHDL的数据类型、运算操作符、属性以及并发和顺序代码的使用。此外,还提到了状态机设计和时序性能优化在FPGA开发中的重要性。
摘要由CSDN通过智能技术生成

祈祷不会问到FPGA 和 VHDL

这门课讲了什么?

课时较少的缘故,仅仅浅显的讲解了FPGA与VHDL。

(FPGA  简介)fpga是什么?fpga现状?

fpga简单的说,就是现场可编程逻辑阵列。它的内部是逻辑单元,它们之间可以用线连接,至于以怎样的形式相连,则可以根据应用者写入的逻辑决定。每次布线都会重新组合逻辑单元,从而可以任意的编写不同的逻辑。当然,前提是定义的逻辑块不超出它可读写的最大值。

应用范围遍及航空航天、医疗、通讯、网络通讯、安防、广播、汽车电子、工业、消费类市场、测量测试等多个热门领域。并随着工艺的进步和技术的发展,向更多、更广泛的应用领域扩展

区别于C语言等是软件语言,芯片执行的时候是一条条执行,而VHDL是硬件语言,执行的时候是并行的,就是所有的语句块同时执行。VHDL是一种语言,是一种硬件语言,可以编出我们要的电路图。FPGA是一种芯片,里面全是门电路,触发器,通过VHDL程序的要求完成门电路的连接。


使计算机的能力越来越强,方法一:通过提高工艺来提高工作频率;方法二:通过优化系统体系,并行!

时序性能的调整提高是

fpga

开发能力的标志

时序性能的调整提高是fpga开发能力的标志


VHDL是什么:
 VHDL是一种语言,是一种硬件语言,可以编出我们要的电路图。与软件语言相比,VHDL 最重要的特点就在于它的并行运行特性,当设计好的电路上电后,器件内部所有信号将同时并发工作,而不会以软件方式按照程序顺序执行,即使在进程内部也是趋向并行工作的。
VHDL 是由美国国防部为描述电子电路所开发的一种语言,其全称为(Very High Speed Integrated Circuit) Hardware Description Language。 与另外一门硬件描述语言 Verilog HDL 相比,VHDL 更善于描述高层的一些设计,包括系统级(算法、数据通路、控制)和行为级(寄存器传输级),而且 VHDL 具有设计重用、大型设计能力、可读性强、易于编译等优点逐渐受到硬件设计者的青睐。但是,VHDL 是一门语法相当严格的语言,易学性差,特别是对于刚开始接触 VHDL 的设计者而言,经常会因某些小细节处理不当导致综合无法通过。

VHDL 讲了什么?
端口:
定义了 5 种类型的端口,分别是 In, Out,Inout, Buffer及 Linkage

号和变量 :
  常数、信号和变量是 VHDL 中最主要的对象,分别代表一定的物理意义。常数对应于数字电路中的电源或地;信号对应某条硬件连线;变量通常指临时数据的局部存储。信号和变量功能相近,用法上却有很大不同。


位(矢量)与逻辑(矢量) :
  bit 或其矢量形式 bit_vector只有’0’和’1’两种状态,数字电路中也只有’0’和’1’两种逻辑,因此会容易有误区,认为采用位(矢量)则足够设计之用,而不必像std_logic那样出现’X’,’U’,’W’各种状态,增加编程难度。但实际情况却并非如此,以一个最简单 D型触发器设计为例 
… … 
① process(clk) 
② begin 
③ if clk’event and clk=’1’ then 
④ Q<=D; 
⑤ end if; 
⑥ end process; 
… … 
实际中 clk 对数据端 D的输入有一定的时间限制,即在 clk 上升沿附近(建立时间和保持时间之内),D必须保持稳定,否则 Q输出会出现亚稳态,如下图所示。 
         当 clk 和 D时序关系不满足时,由于 bit 只有’0’或’1’,系统只能随机的从’0’和’1’中给 Q 输出,这样的结果显然是不可信的;而采用 std_logic 类型,则时序仿真时会输出为一个’X’,提醒用户建立保持时间存在问题,应重新安排 D和 clk 之间时序关系。 
        此外,对于双向总线设计(前面已提及)、 FPGA/CPLD上电配置等问题,如果没有’Z’,’X’等状态,根本无法进行设计和有效验证。 

关于进程 
   进程(Process)是 VHDL 中最为重要的部分,大部分设计都会用到 Process 结构

进程举例:

多余时钟的引入 
       在设计时往往会遇到这种情况,需要对外部某个输入信号进行判断,当其出现上跳或下跳沿时,执行相应的操作,而该信号不像正常时钟那样具有固定占空比和周期,而是很随机,需要程序设计判断其上跳沿出现与否。这时,很容易写出如下程序: 
①  process(Ctl_a) -- Ctl_a即为该输入信号 
② begin 
③ if Ctl_a’event and Ctl_a=’1’ then 
④  …  … ; --执行相应操作 
⑤ end if ; 
⑥ end process; 
        由于出现第③行这类语句,综合工具自动默认 Ctl_a 为时钟,某些 FPGA 更会强行将该输入约束到时钟引脚上。而设计者的初衷只是想将其作为下位机的状态输入以进行判断。上面的程序容易造成多时钟现象,增加设计的难度。解决的办法可以如下,将 Ctl_a 增加一级状态
Ctl_areg 寄存,通过对 Ctl_a 和Ctl_areg 状态判断上跳与否,改正程序如下: 
① process(clk) 
② begin 
③ if clk’event and clk=’1’ then 
④ Ctl_areg<=Ctl_a;--产生相邻状态 
⑤ if Ctl_areg=’0’ and Ctl_a=’1’ then--上跳判断 
⑥  …  … ; --执行相应操作 
⑦ end if; 
⑧ end if; 
⑨ end process; 
程序中第④行用以产生两个相邻状态,第⑤行对前后状态进行判断是否有上跳现象发生。其中,需注意的是 clk 的时钟频率应明显快于 Ctl_a信号的变化频率,以保证正确采样。 


下可省略:

参考:http://blog.sina.com.cn/s/blog_72cd3a5c01014wl1.html

参考:http://blog.csdn.net/shanekong/article/details/42686135


一个VHDL程序代码包含实体(entity)、结构体(architecture)、配置(configuration)、程序包(package)、库(library)等。

一、数据类型

1.用户自定义数据类型

使用关键字TYPE,例如:

TYPEmy_integer IS RANGE -32 TO 32;

–用户自定义的整数类型的子集

TYPEstudent_grade IS RANGE 0 TO 100;

–用户自定义的自然数类型的子集

TYPEstate IS (idle, forward, backward, stop);

–枚举数据类型,常用于有限状态机的状态定义

一般来说,枚举类型的数据自动按顺序依次编码。

2.子类型

在原有已定义数据类型上加一些约束条件,可以定义该数据类型的子类型。VHDL不允许不同类型的数据直接进行操作运算,而某个数据类型的子类型则可以和原有类型数据直接进行操作运算。

子类型定义使用SUBTYPE关键字。

3.数组(ARRAY)

ARRAY是将相同数据类型的数据集合在一起形成的一种新的数据类型。

TYPEtype_name IS ARRAY (specification) OF data_type;

–定义新的数组类型语法结构

SIGNALsignal_name: type_name [:= initial_value];

–使用新的数组类型对SIGNAL,CONSTANT, VARIABLE进行声明

例如:

TYPEdelay_lines IS ARRAY (L-2 DOWNTO 0) OF SIGNED (W_IN-1 DOWNTO 0);

–滤波器输入延迟链类型定义

TYPEcoeffs IS ARRAY (L-1 DOWNTO 0) OF SIGNED (W_COEF-1 DOWNTO 0);

–滤波器系数类型定义

SIGNALdelay_regs: delay_lines;  – 信号延迟寄存器声明

CONSTANTcoef: coeffs := (    ); –常量系数声明并赋初值

4.端口数组

在定义电路的输入/输出端口时,有时需把端口定义为矢量阵列,而在ENTITY中不允许使用TYPE进行类型定义,所以必须在包集(PACKAGE)中根据端口的具体信号特征建立用户自定义的数据类型,该数据类型可以供包括ENTITY在内的整个设计使用。

—————————————PACKAGE———————————-

libraryieee;

useieee.std_logic_1164.all;

——————————————

PACKAGEmy_data_types IS

     TYPE vector_array IS ARRAY (natural range<>) OF STD_LOGIC_VECTOR(7 DOWNTO 0); –声明8位的数组

ENDmy_data_types;

———————————–MainCode—————————————

libraryieee;

useieee.std_logic_1164.all;

usework.my_data_types.all; –用户自定义包集

——————————————————————

ENTITYmux IS

PORT(inp: IN vector_array(0 to 3);

ENDmux;

——————————————————————————-

5.有符号数和无符号数

要使用SIGNED和UNSIGNED类型数据,必须在代码开始部分声明ieee库中的包集std_logic_arith。它们支持算术运算但不支持逻辑运算。

libraryieee;

useieee.std_logic_1164.all;

useieee.std_logic_arith.all;

……

SIGNALa: IN SIGNED (7 DOWNTO 0);

SIGNALb: IN SIGNED (7 DOWNTO 0);

SIGNALx: IN SIGNED (7 DOWNTO 0);

……

v<= a + b;

w<= a AND b;  –非法(不支持逻辑运算)

——————————————————————————-

STD_LOGIC_VECTOR类型的数据不能直接进行算术运算,只有声明了std_logic_signed和std_logic_unsigned两个包集后才可以像SIGNED和UNSIGNED类型的数据一样进行算术运算。

6.数据类型转换

在ieee库的std_logic_arith包集中提供了许多数据类型转换函数:

1.conv_integer(p): 将数据类型为INTEGER,UNSIGNED,SIGNED,STD_ULOGIC或STD_LOGIC的操作数p转换成INTEGER类型。不包含STD_LOGIC_VECTOR。

2. conv_unsigned(p,b):将数据类型为INTEGER,UNSIGNED,SIGNED或STD_ULOGIC的操作数p转换成位宽为b的UNSIGNED类型数据。

3. conv_signed(p,b):将数据类型为INTEGER, UNSIGNED,SIGNED或STD_ULOGIC的操作数p转换成位宽为b的SIGNED类型的数据。

4.conv_std_logic_vector(p, b):将数据类型为INTEGER,UNSIGNED, SIGNED或STD_LOGIC的操作数p转换成位宽为b的STD_LOGIC_VECTOR类型的数据。

二、运算操作符和属性

.运算操作符

赋值运算符

赋值运算符用来给信号、变量和常数赋值。

<=    用于对SIGNAL类型赋值;

:=     用于对VARIABLE,CONSTANT和GENERIC赋值,也可用于赋初始值;

=>    用于对矢量中的某些位赋值,或对某些位之外的其他位赋值(常用OTHERS表示)。

例:

SIGNALx: STD_LOGIC;

VARIABLEy: STD_LOGIC_VECTOR(3 DOWNTO 0);  –最左边的位是MSB

SIGNALw: STD_LOGIC_VECTOR(0 TO 7);  –最右边的位是MSB

x<= ‘1’;

y:= “0000”;

w<= “1000_0000”;  – LSB位为1,其余位为0

w<= (0 => ‘1’, OTHERS => ‘0’);  –LSB位是1, 其他位是0

逻辑运算符

操作数必须是BIT, STD_LOGIC或STD_ULOGIC类型的数据或者是这些数据类型的扩展,即BIT_VECTOR,STD_LOGIC_VECTOR,STD_ULOGIC_VECTOR。

VHDL的逻辑运算符有以下几种:(优先级递减)

Ÿ   NOT —— 取反

Ÿ   AND —— 与

Ÿ   OR —— 或

Ÿ   NAND —— 与非

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值