VHDL入门基础

一、VHDL语言的基本语法

D触发器的VHDL实现

VHDL入门基础_第1张图片

 

1、VHDL语言的表示符

 

VHDL入门基础_第2张图片 

2、VHDL的数字
2.1 数字型文字

156E2的意思是156 × \times × 1 0 2 10^2 102;
下划线可以连接数字。
VHDL入门基础_第3张图片

 2.2 数字基数表示的文字

VHDL入门基础_第4张图片 

2.3 字符串型文字 

VHDL入门基础_第5张图片 

VHDL入门基础_第6张图片 

VHDL入门基础_第7张图片 

2.4 下标名及下标段名 

VHDL入门基础_第8张图片 

VHDL入门基础_第9张图片 

downto 和 to 有什么区别
举个例子,比如要生命一个长度位8的vector的信号
Signal s1: std_logic_vector(7 downto 0); 这个形成的数组下标值从右到左依次是7,6,5,4,3,2,1,0
Signal s2: std_logic_vector(0 to 7);这个形成的数组的下标值从右到做依次是0,1,2,3,4,5,6,7
所以区别就是显示方向不同而已。

 二、VHDL语言的数据对象

1、常数 

VHDL入门基础_第10张图片

VHDL入门基础_第11张图片 

2、变量 

VHDL入门基础_第12张图片 

VHDL入门基础_第13张图片 

VHDL入门基础_第14张图片 

3、信号(SIGNAL) 

VHDL入门基础_第15张图片 

VHDL入门基础_第16张图片 

 

VHDL入门基础_第17张图片 

VHDL入门基础_第18张图片 

三、VHDL中的数据类型 

VHDL入门基础_第19张图片 

VHDL入门基础_第20张图片 

1、VHDL的预定义数据类型 

VHDL入门基础_第21张图片 

1.1 布尔(BOOLEAN) 

VHDL入门基础_第22张图片 

1.2 位(BIT) 

VHDL入门基础_第23张图片 

1.3 位矢量(BIT_VECTOR) 

VHDL入门基础_第24张图片 

1.4 字符(CHARACHTER) 

VHDL入门基础_第25张图片 

1.5 整数(INTEGER) 

VHDL入门基础_第26张图片 

VHDL入门基础_第27张图片 

1.6 实数(REAL) 

VHDL入门基础_第28张图片 

1.7 字符串(STRING) 

VHDL入门基础_第29张图片 

1.8 时间(TIME)数据类型 

VHDL入门基础_第30张图片 

1.9 错误等级(SEVERITY_LEVEL) 

VHDL入门基础_第31张图片 

2、IEEE预定义标准逻辑位与矢量 

VHDL入门基础_第32张图片

2.1 标准逻辑位STD_LOGIN数据类型 

VHDL入门基础_第33张图片 

VHDL入门基础_第34张图片 

2.2 标准逻辑矢量(STD_LOGIC_VECTOR)

VHDL入门基础_第35张图片 

2.3 其他预定义标准数据类型

VHDL入门基础_第36张图片 

VHDL入门基础_第37张图片 

(1) 无符号数据类型(UNSIGNED TYPE)

VHDL入门基础_第38张图片 

(2) 有符号数据类型(SIGNED TYPE) 

VHDL入门基础_第39张图片 

2.4 用户自定义数据类型方式 

(1) TYPE语句用法 

 (2) SUBTYPE语句的用法

VHDL入门基础_第40张图片 

(3) 枚举类型 

VHDL入门基础_第41张图片 

(4) 数组类型 

 

VHDL入门基础_第42张图片 

 VHDL入门基础_第43张图片

VHDL入门基础_第44张图片 

(5) 记录类型 

VHDL入门基础_第45张图片 

VHDL入门基础_第46张图片 (6) 数据类型转换 

² VHDL 程序设计中,不同类型的对象不能相互赋值。对于变量、信号、常量、文件进行操作时,数据类型一定要一致,否则 EDA 工具进行综合、仿真等过程时将不能通过。
² 为了进行不同类型的数据变换,可以有 3 种方法:类型标记法、函数转换法和常数转换法。

VHDL入门基础_第47张图片 

VHDL入门基础_第48张图片 

VHDL入门基础_第49张图片 

VHDL入门基础_第50张图片 

VHDL入门基础_第51张图片 

 

VHDL程序设计实例

(1)vhdl设计组成:

VHDL入门基础_第52张图片 

 库和程序包(libary, package)
实体(entity)
结构体(architecture)
配置(configuration)

通俗来讲:
库和包 -> 材料,工具箱
实体 -> 硬件外部的接口
结构体 -> 硬件内部的具体实现

(2)语法

实体实体(Entity)提供了被设计系统或器件的公共信息,指明了输入与输出引脚。实体由实体名、类型说明、端口说明、实体说明部分和实体语句部分组成。

entity 实体名 is  
    generic(常数名:数据类型:初值)  
    port(端口信号名:数据类型)  
end 实体名  

 结构体:通过vhdl语句描述实体的具体行为和逻辑功能,

² 结构体( Architecture Body )具体指明了设计实体的行为,定义了设计实体的功能,规定了该设计实体的数据流程,指派了实体中内部元件的连接关系。一个实体必须有一个或可以有多个结构体。用 VHDL 语言描述结构体有 4 种方法:

1)行为描述法:采用进程语句,顺序描述设计实体的行为。

2)数据流描述法:采用进程语句,顺序描述数据流在控制流作用下被加工、处理、存储的全过程。

3)结构描述法:采用并行处理语句描述设计实体内的结构组织和元件互连关系。

4)采用多个进程(Process)、多个模块(Blocks)、多个子程序(Subprograms)的方法。

architecture 结构体名 of 实体名 is  
    说明部分(可选,如数据类型type 常数constand 信号signal 元件component 过程pocedure 变量variable和进程process等)  
begin  
    功能描述部分  
end 结构体名  

 逻辑

if 条件 then  
    --do something;
else if 条件 then 
    --do something;
else 
    --do something;
end if; 

 循环

for x in 0 to n loop
    --do something;
end loop;

 运算符

   

赋值运算:
    <= 信号赋值
    := 变量赋值
    => 数组内部分元素赋值

  逻辑运算:
   

 not 非
    and 与
    or 或
    nand 与非
    nor 或非
    xor 异或
    注意:对数组类型,参与运算的数组位数要相等,运算为对应位进行

   算术运算:
   

+ 加
    - 减
    * 乘
    / 除
    mod 模
    rem 取余
    ** 指数
    abs 绝对值
    注意:尽量只使用加减

    关系运算:
   

 => 大于等于
    <= 小于等于
    大于
    < 小于
    /= 不等于
    = 等于

    连接运算:
   

& 连接运算结果为同类型构成的数组

注意:从本质上讲,VHDL代码是并发执行的。只有PROCESS,FUNCTION或者PROCEDURE内部的代码才是顺序执行的。值得注意的是,尽管这些模块中的代码是顺序执行的,但是当它们作为一个整体是,与其他模块之间又是并发的。IF,WAIT,CASE,LOOP语句都是顺序代码,用在PROCESS,FUNCTION和PROCEDURE内部。

2、代码实例

(1)半加器

--halfadder
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;

entity halfadder is
    port(a, b : in std_logic;
         s, c : out std_logic
         --s -> sum, c -> carry
        );
end halfadder;

architecture f_halfadder of halfadder is 
begin
    s <= a xor b;
    c <= a and b;
end f_halfadder;

(2)一位全加器 

--fulladder
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;

entity fulladder is 
    port(a, b, c0 : in std_logic;
            s, c1 : out std_logic
        );
end fulladder;

architecture f_fulladder of fulladder is 
begin 
    s  <= a xor b xor c0;
    c1 <= (a and b) or (c0 and (a xor b)); 
end f_fulladder;

 (3)四位加法器

--add4
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;

entity add4 is 
    port(a, b : in std_logic_vector(3 downto 0); 
            s : out std_logic_vector(3 downto 0);
           c0 : in std_logic;
           c1 : out std_logic
        );
end add4;

architecture f_add4 of add4 is 
begin 
    --模拟手算加法
    process(a, b, c0)
    variable t : std_logic;
    begin
        t := c0;
        for x in 0 to 3 loop
            s(x) <= a(x) xor b(x) xor t;
               t := (a(x) and b(x)) or (t and (a(x) xor b(x)));
        end loop;
        c1 <= t;
    end process;
end f_add4;

 3、Debug日志

1、同一个项目文件有两个vhd文件时,如果要对不同的vhd文件进行仿真的话需要对先把要仿真的文件置于top entity,然后把这个文件编译一遍,这样才能在node finder里边找到对应的引脚。

2、信号的赋值操作只有在进程结束后才会进行,所以如果信号在进程内被多次赋值的话,只有最后一次赋值操作才会起作用,所以在进程内写算法一般都是用variable,signal和variable的区别具体可以看这篇blog => VHDL中信号与变量的区别及赋值的讨论【博客大赛】VHDL中信号与变量的区别及赋值的讨论_qijitao的博客-CSDN博客_信号与变量的区别
3、当自己制作的组件的某一个接口是一个数组,这时候要用总线连接,具体的连法可以看这篇blogquartus总线怎样连接quartus总线怎样连接(例如,怎么和ROM连接)_deniece1的博客-CSDN博客_quartus总线和单线怎么连
4、在用vhdl写组件的的时候,在定义process的时候,一定要把用到的input的端口写进porcess定义时的括号里边,否则可能导致的后果就是你把你写好的这个组件生成出来之后,结果永远对不上!
VHDL快速入门_yao.x的博客-CSDN博客_vhdl

你可能感兴趣的:(VHDL,fpga开发,开发语言,嵌入式硬件)