首页 > 代码库 > VHDL基础1

VHDL基础1

Description Structure



 

  •  一个可综合的VHDL描述中一般由3部分组成:LIBRARY declarations、ENTITY、ARCHITECTURE
  • Library(库)用来设计重用和代码共享,使代码结构更清晰
1 LIBRARY library_name;
2 USE library_name.package_name.package_parts;
    • 常用的三个Libray:ieee、std、work
    • 其中std、work是默认可见的,不需声明,ieee需要明确的声明
  • Entity(实体)描述电路的输入/输出引脚
    技术分享
    ENTITY entity_name IS
           GENERIC(参数名:数据类型:=设定值
                       ...);        
            PORT (port_name1: port_mode data_type;
                      port_name2: port_mode data_type;
                       ...);
    END entity_name;
    技术分享
    • GENERIC类属性为可选,用来指定诸如数据总线宽度、延时时间等参数
    • singal_mode 可以是 4 种类型:in  out  inout  buffer 
    • OUT 模式无法回读到电路内部,Buffer 模式可以,但是 buffer 不能连接到其他类型的端口,即不能把该模块作为子模块例化,一般使用中间缓冲信号,解决回读问题。
  • Architecture(结构体)描述电路的行为和实现的功能
    • Architecture 包含两个部分:声明部分和代码部分
    • 声明部分(可选)用来声明数据类型、常量、信号、子程序、元件等
    • 代码部分 (begin...end)描述电路行为
      1 ARCHITECTURE 结构体名 OF 实体名 IS
      2      说明语句
      3 BEGIN
      4      功能描述语句
      5           ......
      6 END 结构体名;

       

  •  注释用 -- 开始 
  • VHDL不区分大小写

 

Data Types


 

三种数据对象,声明信号 signal 

1 signal name : type [range] [:= initial_vaule];

还有 常量 constant 声明:

1 constant name : type := value;

还有 变量 variable 声明

1 variable name : type [range] [:= initial_vaule];

 Pre-defined Data Types

bit & bit_vector

  • 用‘0‘、‘1‘赋值
1 signal x : bit;
2 signal y : bit_vector (3 DOWNTO 0);
3 
4 x<=‘1‘;
5 y<="0011"

std_logic & std_logic_vector

  •  不同于bit类型,可取9种逻辑数据类型,但只有0、1、X、Z 可综合
  • std_logic 是 std_ulogic的子集

Boolean

  • 两种取值:true、false

TIME

1 CONSTANT t_delay:TIME:=30 ns

 

  • 数值部分和单位之间有个空格 
  • fs、ps、ns、us、ms、sec、min、hr   103关系

integer

  • 32位表示的整数 范围-(231-1)~(231-1)
  • 其他进制整数先写进制数,再用#括起来16#1F#

real

  • 小数表示、科学计数表示

character & string

  • 使用字符串的可以是常量 和 变量

User-defined Data Types

 

技术分享
1 --integer range
2 TYPE student IS RANGE 0 TO 100;
3 
4 --enumerated(枚举)
5 TYPE state IS (state0,state1,state2,state3);
6 
7 --Array
8 TYPE matrix IS ARRAY (0 TO 3) OF std_loogic_vector;
技术分享

Port Array

有时在定义端口时,需要把端口定义为矢量阵列。但是在 Entity 中不允许使用 type 定义,所以我们必须自己定义包集 (package),然后使用 use 声明使用该用户自定义的包集,最后才能在 Entity 中使用这种新定义的类型。

Data Conversion

  • 在 VHDL 中,不同类型的数据是不能直接进行算术/逻辑运算的,所以必要时必须进行类型转换操作。

             函数名称                        函数功能            
TO_STDLOGICVECTOR()         由BIT_VECTOR转为STD_LOGIC_VECTOR型  
TO_BITVECTOR() 与上相反
TO_STDLOGIC() 由BIT型转为STD_LOGIC型
TO_BIT 与上相反
CONV_STD_LOGIC_VECTOR(a,位长) 由整型转为STD_LOGIC_VECTOR型
CONV_INTEGER() 与上相反

 

 

 

 

 

 

 

Operators 


 

 VHDL 语法虽然枯燥无味,但是只有对数据类型、运算操作符及其属性有了深刻认识,才能写出高质量和高效率的代码。

 Opreators

  • VHDL提供了6种预定义的预算符:
    • 赋值 assignment
    • 逻辑 logical
    • 算术 arithmetic
    • 关系 relational
    • 并置 concatenation

assignment

一共三种:

  • <= 用于给 signal 对象赋值
  • :=  用于给 variable, constant, 赋值
  • => 用于给矢量(vector)对象的某些位赋值,常和 others 一起使用

logical

进行逻辑运算,操作数必须是 bit, std_logic, std_ulogic 类型或者他们的扩展,即 bit_vector, std_logic_vector, std_ulogic_vector 类型

  • NOT, AND, OR, NAND, NOR, XOR

arithmetic

  • 操作数是 signed,  integer, real,其中 real 类型是不可综合的
  • +   -   *   /   **   MOD   REM   ABS

comparison

一共有6种:=   /=   >   <   >=   <=

concatenation

用于位的拼接。

  • 操作数:任何支持逻辑运算的数据类型
  • 操作符:&   (, , ,)

 

Concurrent Code


 

HDL对应的是硬件电路,而硬件电路时刻工作,所以它的代码是并发执行的。只有process、function、procedure中的代码是顺序执行的,而这些模块作为共同整体时,它们之间也是并行的。

在并发代码中可以使用下列各项:

  • 运算操作符
  • when 语句(when/else 和 with/select/when)
  • generate 语句
  • block 语句

when

when/else syntax:

1 assignment WHEN condition ELSE
2 assignment WHEN condition ELSE
3 ...;

 

with/select/when syntax:

1 WITH 选择信号表达式 SELECT
2 assignment WHEN value,
3 assignment WHEN value,
4 ...;

generate

常和 for/if 一起使用,因为描述对象是电路,电路是固定的,功能也是静态的,所以一种用途是生成相同元件的多次实例化,第二种用途是生成结构相同的多次赋值、组合逻辑。两种用途目的都是减少代码量,增加可读性和可维护性

block

为了把较长的代码分成几个较小的区域,便于阅读和维护,在每个块内都能对局部信号、数据类型和常量定义

1 块标号:BLOCK[(块保护表达式)]
2       [说明部分]
3 BEGIN
4        并行语句
5 END BLOCK [块标号];

 

Sequential Code


VHDL 本质是并发执行的代码,但是在 processfunctionprocedure 内部的代码是顺序执行的,当它们作为一个整体时,相互之间也是并发执行的。

顺序代码并非只能与时序逻辑 (sequential logic) 对应,同样也可以用它们来实现组合逻辑 (combinational logic)。

这里主要讨论顺序代码,也就是这 3 个块中的代码,包括 ifwaitcaseloop 语句。

process

在一个结构体中允许放置多个进程语句,这些进程也都是并行的,每个进程内部由一系列顺序语句构成

1 [进程标号:] PROCESS [敏感信号参数表] IS
2                  [进程说明部分]
3                       BEGIN
4                            顺序描述语句
5                    END PROCESS [进程标号];
  • 每当敏感信号参数表里的任何参数变化时,进程都被激活重新执行一遍
  • 进程说明部分主要定义一些局部量如常量, 变量,子程序等,但这里不能定义信号
  • 顺序描述语句是最重要的部分,常用顺序语句 if/case/loop

if

1 IF conditions THEN assignment;
2 ELSIF conditions THEN assignments;
3 ......
4 ELSE assignments;
5 END IF;

case

case 和 when 的区别在于,case 允许在每个测试条件下执行多个赋值操作,而 when 只能执行一个赋值操作。

1 CASE 表达式 IS
2         WHEN value =http://www.mamicode.com/> assignment;>

 

loop

常用格式有两种

loop

1 [loop标号:] LOOP
2      顺序语句;
3 END LOOP[loop 标号];

for/loop

1 [LOOP标号:] FOR 循环变量 IN 循环参数范围 LOOP
2         顺序语句;
3 END LOOP[LOOP 标号];
  • 循环变量是一个临时局部变量,由LOOP语句自动定义

LOOP不能自己跳出循环,也不能自己跳到另一个循环,有时候需要加入其它控制语句

1 [标识:] EXIT [LOOP 标识] [WHEN condition];
2 
3 [标识:] NEXT [另一个LOOP 标识] [WHEN condition];

 

/*****注释*****/

*一组在逻辑上互相独立的程序或程序段在执行过程中,其执行时间在客观上互相重叠

 

VHDL基础1