当前位置:   article > 正文

EDA学习笔记_vhdl count

vhdl count

EDA学习笔记

VHDL程序结构

一般的 VHDL 程序可以由实体(Entity)、结构体(Architecture)、结构体的四种描述方式:

结构化描述、数据流描述、行为描述、混合。、程序包和程序包体(Package)以及库(Library)5 个部分组成,它们是 VHDL 程序的设计单元。

其中实体、配置和程序包属于初级设计单元,主要的功能是进行端口、行为、函数等的定义。结构体和程序包体是次级设计单元,包含了所有行为以及函数的实现代码。其中,程序包和程序包体又属于公用设计单元,即它们是被其他程序模块调用的。库则是一批程序包的集合。

1. 实体(Entity)

实体描述了设计单元的输入输出接口信号或引脚,是设计实体经封装后对外的一个通信界面。

实体描述的格式如下:

ENTITY 实体名 IS
    [GENERIC(参数表);]
    [PORT(端口表);]
  [BEGIN
    实体语句部分;]
  END [ENTITY] [实体名];
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
ENTITY 实体名 IS -- 引导语句
[GENERIC (常数名: 数据类型: 设定值)] -- 类属表
PORT -- 端口表
(
    端口名1: 端口方向 端口类型;
    端口名2: 端口方向 端口类型;
    端口名3: 端口方向 端口类型;
    ......
    端口名n: 端口方向 端口类型 -- 最后一个一定不能加";",不然会报next process的")" expect ";" or ","
);
END [实体名]; -- 结束语句
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
1.1 类属

类属说明的书写格式是:

GENERIC(常数名:数据类型:设定值
        常数名:数据类型:设定值);
  • 1
  • 2

类属 GENERIC 参量是一种端口界面常数,常以一种说明的形式放在实体或块结构体前的说明部分。比较常见的情况是利用类属来动态规定一个实体的端口的大小,或设计实体的物理特性,或结构体中的总线宽度,或设计实体中底层中同种元件的例化数量等等。

1.2 端口

端口语句的格式:

PORT(端口名:端口模式 数据类型;
	 端口名:端口模式 数据类型);
  • 1
  • 2

端口模式有:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FMzwOlM3-1651836407529)(C:\Users\22899\Desktop\EDA\img\aHR0cHM6Ly9tbWJpei5xcGljLmNuL21tYml6X3BuZy9hVTA0WFBxOHBkaEpSZ0ZFUjBzV0VTS3RLaWJhcXZpYlFHaWMyNUY0NDZKVXpQc3NGbnRodmliR3Y0dGNFeHdmbFBZdDlaczRxaWJ3RldnU0pUaWJaYWR6bzJFQS82NDA.png)]

2. 结构体(Architecture)

结构体的任务是:定义结构体中的各项内部使用元素,如数据类型(TYPE),常数(CONSTAND),信号(SIGNAL),元件(COMPONENT),过程(POCEDURE),变量(VARIABLE)和进程(PROCESS)等。通过VHDL语句描述实体所要求的具体行为和逻辑功能。描述各元件之间的连接。

特点:

  1. 用于描述模型的功能
  2. 必须和一个 Entity相关联
  3. 一个Entity可有多个 Architectures
  4. Architecture 语句并发执行.

结构体的格式:

ARCHITECTURE 结构体名 OF 实体名 IS
	[说明语句]
BEGIN
	[功能描述语句]
END ARCHITECTURE 结构体名;
  • 1
  • 2
  • 3
  • 4
  • 5

结构体的四种描述方式:

结构化描述、数据流描述、行为描述、混合。

3. 配置(Configuration)

配置的作用:
用于实现模型的关联,可将一个 Entity 和一个Architecture关联起来,也可将一个 component 和一个 entity-architecture关联起来。
目的是为了在一个实体中灵活的使用不同的Architecture。可以在仿真环境中大量使用,但是在综合环境中限制使用。
配置的格式:

--默认配置
Configuration 配置名 of 实体名 IS
    for 结构体名
    end for;
end;配置名

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

4. 库

库是专门用于存放预先编译好的程序包的地方,对应一个文件目录,程序包的文件就放在此目录中,其功能相当于共享资源的仓库,所有已完成的设计资源只有存入某个“库”内才可以被其他实体共享。库的说明总是放在设计单元的最前面,表示该库资源对以下的设计单元开放。库语句格式如下:

LIBRARY 库名;
  • 1

常用的库有IEEE库、STD库和WORK库:

IEEE库:是VHDL设计中最常用的资源库,包含IEEE标准的STD_LOGIC_1164、NUMERIC_BIT、NUMERIC_STD以及其他一些支持工业标准的程序包。其中最重要和最常用的是STD_LOGIC_1164程序包,大部分程序都是以此程序包中设定的标准为设计基础。
STD库:是VHDL的标准库,VHDL在编译过程中会自动调用这个库,所以使用时不需要用语句另外说明。
WORK库:是用户在进行VHDL设计时的现行工作库,用户的设计成果将自动保存在这个库中,是用户自己的仓库,同STD库一样,使用该库不需要任何说明。
库的作用范围:

库说明语句的作用范围从一个实体说明开始到它所属的构造体、配置为止。当一个源程序中出现两个以上的实体时,两条作为使用库的说明语句应在每个实体说明语句前重复书写。

5. 程序包

程序包是用VHDL语言编写的一段程序,可以供其他设计单元调用和共享,相当于公用的“工具箱”,各种数据类型、子程序等一旦放入了程序包,就成为共享的“工具”,类似于C语言的头文件,使用它可以减少代码的输入量,使程序结构清晰。在一个设计中,实体部分所定义的数据类型、常量和子程序可以在相应的结构体中使用,但在一个实体的声明部分和结构体部分中定义的数据类型、常量及子程序却不能被其他设计单元使用。因此,程序包的作用是可以使一组数据类型、常量和子程序能够被多个设计单元使用。
程序包分为包头和包体两部分。包头(也称程序包说明)是对包中使用的数据类型、元件、函数和子程序进行定义,其形式与实体定义类似。包体规定了程序包的实际功能,存放函数和过程的程序体,而且还允许建立内部的子程序、内部变量和数据类型。包头、包体均以关键字PACKAGE开头。

程序包格式如下:

--包头格式:
PACKAGE 程序包名 IS
[包头说明语句]
END 程序包名;
 
--包体格式:
PACKAGE BODY 程序包名 IS
[包体说明语句及包体内容]
END 程序包名;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
5.1 库和程序包的调用方法
LIBRARY 库名;
USE 库名.程序包名.ALL ;

USE 库名.程序包名.项目名 ;
USE 库名.程序包名.ALL;
--例子
LIBRARY IEEE ;
USE IEEE.STD_LOGIC_1164.ALL ;

LIBRARY IEEE ;
USE IEEE.STD_LOGIC_1164.STD_ULOGIC ;
USE IEEE.STD_LOGIC_1164.RISING_EDGE ;

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

常用预定义程序包有以下四个:

1.STD_LOGIC_1164程序包
STD_LOGIC_1164程序包定义了一些数据类型、子类型和函数。数据类型包括:STD_ULOGIC、STD_ULOGIC _VECTOR、STD_LOGIC和STD_LOGIC _VECTOR,用的最多最广的是STD_LOGIC和STD_LOGIC_VECTOR数据类型。调用STD_LOGIC_1164程序包中的项目需要使用以下语句:
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
该程序包预先在IEEE库中编译,是IEEE库中最常用的标准程序包,其数据类型能够满足工业标准,非常适合CPLD(或FPGA)器件的多值逻辑设计结构。
2.STD_LOGIC_ARITH程序包
该程序包是美国Synopsys公司的程序包,预先编译在IEEE库中。主要是在STD_LOGIC_1164程序包的基础上扩展了UNSIGNED(无符号)、SIGNED(符号)和SMALL_INT(短整型)三个数据类型,并定义了相关的算术运算符和转换函数。
3.STD_LOGIC_SIGNED程序包
该程序包预先编译在IEEE库中,也是Synopsys公司的程序包。主要定义有符号数的运算,重载后可用于INTEGER(整数)、STD_LOGIC(标准逻辑位)和STD_LOGIC _VECTOR(标准逻辑位向量)之间的混合运算,并且定义了STD_LOGIC _VECTOR到INTEGER的转换函数。还定义了STD_LOGIC _VECTOR类型的符号数算数运算子程序。
4.STD_LOGIC_UNSIGNED程序包
该程序包用来定义无符号数的运算,其他功能与STD_LOGIC_SIGNED相似。

VHDL描述语句

顺序语句和并行语句是VHDL程序设计中两大基本描述语句系列。顺序语句(Sequential Statements)用来实现模型的算法描述;并行语句(Concurrent Statements)用来表示各模型算法描述之间的连接关系,这些语句从多侧面完整地描述数字系统的硬件结构和基本逻辑功能,其中包括通信的方式、信号的赋值、多层次的元件例化以及系统行为等。

1. 顺序描述语句

执行顺序与书写顺序一致,与传统软件设计语言的特点相似。
顺序语句只能用在进程与子程序中。
可描述组合逻辑、时序逻辑。

1. 赋值语句

VHDL中常用的 5 种赋值对象
1)简单名称,如 my_var;
2)索引名称,如 my_array_var(3);
3)片断名称,如 my_array_var(3 to 6);
4)记录域名,如 my_record.a_field;
5)集合,如(my_var1, my_var2)。

变量与信号的差异:
1)赋值方式的不同:
变量:= 表达式;
信号 < = 表达式;
2)硬件实现的功能不同:
信号代表电路单元、功能模块间的互联,代表实际的硬件连线;
变量代表电路单元内部的操作,代表暂存的临时数据。

3)有效范围不同:
信号:程序包、实体、结构体----全局量。
变量:进程、子程序----局部量。

4)赋值行为的不同:
信号赋值延迟更新数值、时序电路;
变量赋值立即更新数值、组合电路。

5)信号的多次赋值
a. 一个进程:最后一次赋值有效
b. 多个进程:多源驱动
线与、线或、三态

--1.变量赋值语句
目标变量:=表达式
--2.信号赋值语句
目的信号量<= 信号表达式
  • 1
  • 2
  • 3
  • 4
2. WAIT 语句

WAIT语句属于敏感信号激励信号,一个进程语句含有敏感信号时,进程中不能出现WAIT等待语句;当进程语句不含有敏感信号时,进程语句必须含有其他形态的敏感信号激励。
WAIT语句有五种形式:

WAIT; 
--无限等待;
WAIT ON (敏感信号1,敏感信号2,敏感信号N); 
--敏感信号变化,表中的信号产生变化时才往下运行;
WAIT UNTIL 布尔表达式; --为TRUE时,进程启动,为FARLSE是等待
WAIT FOR 时间表达式; --到时进程才会启动
WAIT UNTIL 布尔表达式 ON(敏感信号1,敏感信号2,敏感信号N)FOR 时间表达式 --多条件等待语句,注意在多条件等待语句的表达式中,至少应有一个信号量,因为处于等待进程中的变量是不可改变的。
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
3. IF语句
IF <条件1> THEN
<顺序处理语句1>;
[ELSIF <条件> THEN
<顺序处理语句>;]
…….
[ELSE
<顺序处理语句>;]
END IF ;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
4. CASE语句

Case 语句使用注意:
1)分支条件的值必须在表达式的取值范围内。
2)两个分支条件不能重叠。
3)CASE语句执行时必须选中,且只能选中一个分支条件。
4)如果没有others分支条件存在,则分支条件必须覆盖表达式所有可能的值。 对std_logic, std_logic_vector数据类型要特别注意使用others分支条件。

CASE 〈条件表达式〉 IS
WHEN 〈条件取值1〉 =>顺序处理语句1;
WHEN 〈条件取值2〉 =>顺序处理语句2;
WHEN 〈条件取值3〉 =>顺序处理语句3;
WHEN   OTHERS    =>顺序处理语句n;
END CASE;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
5. LOOP 语句
FOR模式的LOOP语句格式:
[LOOP标号:] FOR 循环变量 IN 离散范围 LOOP
〈顺序处理语句〉;
END LOOP [LOOP标号];

WHILE模式的LOOP语句格式:
[LOOP标号:] WHILE〈条件〉LOOP
〈顺序处理语句〉;
END LOOP[LOOP标号];
--循环变量 i 需事先定义、赋初值,并指定 其变化方式。一般综合工具不支持 while … loop 语句。
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

特点:
① 循环变量是 loop 内部自动声明的局部量,
仅在 loop 内可见;不需要指定其变化方式。
② 离散范围必须是可计算的整数范围:
整数表达式 to 整数表达式
整数表达式 downto 整数表达式

6. NEXT和EXIT语句

这两种语句都是用于跳出LOOP循环的,NEXT语句是用来跳出本次循环的,而EXIT语句是用于跳出全部循环的。格式:

NEXT或EXIT [LOOP标号] [WHEN条件]
  • 1
7. NULL空操作语句

书写格式:NULL;
作用:使程序流程运行到下一个语句,常用于CASE语句当中

8. RETURN语句

用在一段子程序结束后,用来返回到主程序的控制语句,一般情况之下,有两种书写格式,分别是:

VHDL RETURN; —只能用于进程返回 RETURN 表达式;--只能用于函数返回
  • 1

在实际的应用中,一般的VHDL综合工具要求函数中只能包含一个RETURN,并规定这条RETURN语句只能写在函数末尾,但一些VHDL综合工具允许函数中出现多个RETURN语句。

9. ASSERT断言语句

主要用于程序仿真、调试中的人机对话,它可以给出一个文字串作为警告和错误信息,基本书写格式如下:

错误级别为四级:

Note: 用在仿真时传递信息。
Warning: 出现非平常情形仿真仍继续,结果不可预知。
Error: 仿真不能继续。
Failure: 致命错误,必须立即停止。

ASSERT〈条件〉
REPORT〈输出信号〉   --字符串
SEVERITY〈错误级别〉;--有四种NOTE、WARNING、ERROR和FAILURE
    
  • 1
  • 2
  • 3
  • 4

如果程序在仿真或调试过程中出现问题,断方语句就会给出一个文字串作为提示信息,当程序执行到断言语句时,就会对ASSERT条件表达式进行判断,如果返回值为TRUE则断言语句不做任何操作,程序向下执行,如果返回值为FALSE,则输出指定的提示信息和出错级别。
断言语句可以分为顺序断言语句和并行断言语句。

10. REPORT语句

报告语句是93版VHDL标准提供的一种新的顺序语句,该语句没有增加任何功能,只是提供了某些形式的顺序断言语句的短格式,也算是ASSERT语句的一个精简,格式如下:

 REPORT 〈输出信息〉[SEVERITY〈出错级别〉]
  • 1

2. 并行描述语句

1.并行信号赋值语句
--1.简单信号赋值语句
赋值目标 <= 表达式;
--2.条件信号赋值语句
赋值目标 <= 表达式1 WHEN 赋值条件1 ELSE
    	   表达式2 WHEN 赋值条件2 ELSE
           ...
           表达式n ;
--3.选择信号赋值语句
WITH 选择表达式 SELECT
     赋值目标 <= 表达式1 WHEN 选择条件1,
               表达式2 WHEN 选择条件2,
               ...
               表达式n WHEN 选择条件n;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
2.进程语句

进程语句是一种并发处理语句,在一个结构体中多个 PROCESS 语句可以同时并行运行(相当于多个 CPU 同时运作)。PROCESS 语句是 VHDL 语言中描述硬件系统并发行为的最基本语句。

PROCESS 语句归纳起来有如下几个特点:

它可以与其他进程并发运行,并可存取结构体或实体号中所定义的信号;• 进程结构中的所有语句都是按顺序执行的;

为启动进程,在进行结构中必须包含一个显式的敏感信号量表或包含一个 WAIT 语句;

进程之间的通信是通过信号量传递来实现的。

PROCESS 语句的格式如下:

[进程名]:PROCESS[(敏感信号表)][IS]
	[进程说明语句];--定义该进程所需局部数据环境
BEGIN
	顺序描述语句;--描述该进程的行为
END PROCESS[进程名];
  • 1
  • 2
  • 3
  • 4
  • 5

举例

LIBRARY ieee;
USE ieee.std_logic_1164.all;
ENTITY mux IS 
   PORT ( a, b, c, d : IN Std_Logic;
	                       sel : IN Std_Logic_Vector(1 downto 0);
	                      y, z : OUT Std_Logic);
END mux;
ARCHITECTURE rtl OF mux IS
BEGIN
    PROCESS ( a, b, c, d, sel )
    BEGIN
        IF sel="00" THEN  y <= a;
        ELSIF sel="01" THEN  y <= b;
        ELSIF sel="10" THEN  y <= c;
        ELSE  y <= d;
       END IF;
  END PROCESS;
ENDrtl;

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
3.块语句

BLOCK 语句的格式如下:

[块名:]BLOCK[(保护条件)]
    [参数 GENERIC 说明; [参数映射;] ]
    [端口说明; [端口映射;] ]
    [块说明语句]--说明语句
BEGIN
    并发语句组;
END BLOCK 块名;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

BLOCK 放在结构体的并行语句组中,每一个 BLOCK 相当于一个子电路原理图。和 PROCESS语句不同,BLOCK 内的语句是并发执行的。只要 BLOCK 右边的条件满足,BLOCK 内的语句就被执行。如果省略条件,表示本 BLOCK 被无条件执行。

4.元件例化语句
--元件定义语句:
COMPONENT 元件名 IS
    PORT(端口说明)
END COMPONENT [元件名];
--元件例化语句:
标号名:元件名 PORT MAP([端口名=>] 连接实体端口名,...);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
5. 生成语句

生成语句的作用:

生成语句具有复制作用,可以生成与某个元件或设计单元电路完全相同的一组并行元件或设计单元电路结构。
分为两类:
for ┅ generate:采用一个离散的范围决定备份的数目。

标号:for  循环变量   in   范围    generate
                        { 并行语句 }
            end   generate  [标号];

  • 1
  • 2
  • 3
  • 4

If ┅ generate:有条件地生成 0 个或 1 个备份。

标号:if   条件表达式   generate
                      { 并行语句 } 
            end   generate  [标号];
  • 1
  • 2
  • 3

if 语句与 If ┅ generate 的区别:
1、If ┅ generate 没有类似于 if 语句的
else 或 elsif 分支语句。
2、if 语句是顺序语句,If ┅ generate为并
行语句。

6. 子程序语句

子程序由一组顺序语句组成,是为了在程序中重复使用而设立的。
子程序不是一个独立的编译单位,只能置于结构体或程序包中,
在结构体中定义的子程序对于该结构体来说是局部的,即不能被其它设计层次的结构体调用。如果要在其它结构体中调用同一个子程序,就需要把子程序定义到程序包中。

子程序的分类:
过程:过程通过调用返回0个或多个值。
函数:函数直接返回单个值。
子程序组成两部分:
子程序声明和主体部分。
在程序包中声明子程序时,子程序声明必须要在程序包声明中,子程序主体必须要在程序包体中。

1.过程语句

过程的作用是传递信息,即通过参数进行内外的信息传递。其中参数需说明(信号、变量及常量)类别、类型及传递方向。

1.1过程定义语句

过程定义的格式为:

PROCEDURE  过程名 (参数表)--过程首
    
PROCEDURE  过程名 [参数声明] IS --过程体
			[子程序声明项];
	BEGIN
		顺序语句;
END [PROCEDURE] [过程名] ; 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

1.2过程调用语句

过程名 [([参数名=>] 表达式 {,[参数名=>] 表达式})]

  • 1
  • 2

2.函数语句

函数语句的作用是输入若干参数,通过函数运算求值,最后返回一个值。
函数语句的格式为:

FUNCTION  函数名 [参数表]
RETURN  类型;     --函数首

FUNCTION  函数名 [参数表]   --函数体
RETURN  类型  IS
    [子程序声明项;]
    BEGIN
    顺序语句;
END 函数名;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

1.1函数定义语句

1.2函数调用语句

3.属性描述与定义语句

基本逻辑电路设计

基本逻辑电路:
组合逻辑电路、时序逻辑电路

组合逻辑电路设计

简单门电路、编码器、译码器、加法器、多路选择器、三态门等。

时序逻辑电路设计

触发器、寄存器、计数器、分频器、信号发生器等。

一、时序电路特殊信号的描述

​ 时钟信号和复位信号

1、时钟信号描述
常用的描述方式:
1)进程的敏感信号是时钟信号,在进程内部
用if 语句描述时钟的边沿条件。

如:
process (clock)
begin
if (clock_edge_condition) then
signal_out <= signal_in ;

其它时序语句

end if ;
end process ;

2)在进程中用 wait until 语句描述时钟信号,此
时进程将没有敏感信号。
如:
process
begin
wait until (clock_edge_condition) ;
signal_out <= signal_in ;

其它时序语句

end process ;

注意:
a. 在对时钟边沿说明时,一定要注明是上升沿
还是下降沿。
b. 一个进程中只能描述一个时钟信号。
c. Wait until 语句只能放在进程的最前面或
最后面。

3)时钟边沿的描述
时钟上升沿:
(clock’event and clock = ‘1’)
时钟下降沿:
(clock’event and clock = ‘0’)

2、触发器的复位信号描述
1)同步复位:在只有以时钟为敏感信号的
进程中定义。
如:process (clock)
begin
if (clock_edge_condition) then
if (reset_condition) then
signal_out <= reset_value ;
else
signal_out <= signal_in ;

end if ;
end if ;
end process ;

2)异步复位:进程的敏感信号表中除时钟信号外,还有复位信号。
如:process (reset_signal, clock)
begin
if (reset_condition) then
signal_out <= reset_value;
elsif (clock_edge_condition) then
signal_out <= signal_in ;

end if ;
end process ;

状态机的VHDL设计

FSM数学定义:
一个有限状态机M=(S,I,O,f,g,s0),包含一个有限的状态集合S,一个有限输入I,一个有限输出O,一个转换函数f,它为每一个状态和输入对,给出一个新的状态,一个输出函数 g,它为每一个状态和输入对,给出一个输出,一个初始状态s0。
设M=(S,I,O,f,g,s0)是一个有限状态机,我们可以用一个状态表来表示所有状态和输入对的转换函数f和输出函数g的值。

FSM是为时序电路设计而创建的特殊模型技术,在针对任务顺序非常明确的电路(如交通灯控制器)是非常实用。
理论上,任何时序电路都可以建立FSM模型,但并不总是一种高效的方法。如果一味地追求使用FSM来设计时序电路,可能会导致代码冗长和容易出错。例如,任务简单的寄存器就不必使用FSM方式实现。又例如,虽然任务与顺序很明确,但任务数目太多或者性能要求较高时,也不宜用FSM方式实现。
状态机的设计包含两个主要过程,一是状态机的建模,二是状态机的编码。

状态机的组成:如图。
状态机的种类:
Mealy型:当前状态、当前输入相关
Moore型:仅当前状态相关

状态机的分类:
摩尔型状态机(Moore)
–输出信号仅和状态有关
米勒型状态机(Mealy)
–输出信号和状态与输入信号有关VHDL代码结构:
时序逻辑部分:process内部
组合逻辑部分:
在使用FSM方式设计VHDL代码时,通常会在结构体的开始部分插入一个用户自定义的枚举数据类型,其中包含所有可能出现的电路状态。

一种结构清晰、易于实现的FSM设计风格:
FSM中的时序逻辑部分和组合逻辑部分分别独立设计;
定义一个枚举数据类型,内部包含所有FSM需要的状态;

FSM中时序逻辑部分的设计特点:
确定的输入/输出端口
典型的模板可供使用

FSM中组合逻辑部分的设计特点:
并发代码、顺序代码皆可;
顺序代码方式的设计模板

有限状态机的容错设计:

​ 状态机的容错设计主要是针对未定位状态(或称为剩余状态)。状态机的每一状态对应着一个用二进制表示的状态编码,因此,若需要的状态数不足2N(N为状态编码的二进制位数),则必然会有一些状态编码未使用,即剩余状态。系统一旦进入此状态,状态机的行为将出错。
​ 例如:定义了S0,S1,S2,S3,S4,S5五个状态,分别用000,001,010,011,100表示,则剩余的编码101,110,111未被使用。

剩余状态处理:

​ 为了使系统进入未定义状态后能够回复正常工作,一般使用以下两种方法:
​ 1、单独设计一个状态(如ERROR),用于处理状态机出错时的情况:
​ WHEN OHTERS => state <= ERROR;
​ 2、直接回到已设定的状态。如果系统对状态机的容错性要求不高,那么可以不对状态机出错进行处理,直接回到某一确定状态(如初始状态 S0)。

例子

全加器

1.用VHDL行为描述设计一个一位全加器,全加器的端口
说明中,inc表述全加器的低位进位,outc表示高位进位

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ib3A910i-1651836407531)(C:\Users\22899\Desktop\EDA\img\图片1.png)]

LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY add_full  IS
  PORT ( ina, inb, inc: IN STD_LOGIC;
                 outc, q: OUT STD_LOGIC
);
END add_full;
ARCHITECTURE behave OF add_full IS
BEGIN
  PROCESS ( ina, inb, inc)
    VARIABLE n: INTEGER RANGE 0 TO 3;
    CONSTANT q_vector: STD_LOGIC_VECTOR (0 TO 3):= "0101" ;
    CONSTANT outc_vector: STD_LOGIC_VECTOR (0 to 3):= "0011";
   BEGIN
n:=0;
    IF (ina= '1') THEN 
      n:=n+1;
    END IF;
    IF (inb='1') THEN
      n:=n+1;
    END IF;
    IF (inc='1') THEN
      n:=n+1;
    END IF;
    q<=q_vector (n);
    outc<=outc_vector (n);
  END PROCESS;
END behave; 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY counter_up IS
    PORT ( reset, clock: IN STD_LOGIC; 
                       counter : OUT STD_LOGIC_VECTOR (7 DOWNTO 0));
END counter_up;
ARCHITECTURE art OF counter_up IS
  SIGANL cnt_ff : STD_LOGIC_VECTOR (7 DOWNTO 0);
BEGIN
  PROCESS (clock, reset, cnt_ff)
  BEGIN
     IF reset=’1’ THEN
        cnt_ff<=X”00”;
      ELSIF clock’ EVENT AND clock=’1’ THEN
         cnt_ff <= cnt_ff +1;
      END IF;
  END PROCESS;
   Counter<= cnt_ff; 
END art;

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

用VHDL寄存器传输方式描述一位全加器

采用卡诺图法得到一位全加器的和q及高位进位outc的逻辑表达式:

​ S=ina ⊕inb ⊕inc
​ outc=(ina ⊕inb)inc + inainb

LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY add_full  IS
  PORT ( ina, inb, inc: IN STD_LOGIC;
                 outc, q: OUT STD_LOGIC
);
END add_full;
ARCHITECTURE rtl OF add_full IS
           SIGNAL tmp: STD_LOGIC; 
BEGIN
           tmp <= ina XOR inb;
                q <= tmp1 XOR inc;                        
             outc <= (tmp AND inc ) OR ( ina AND inb);
END rtl;

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

用VHDL结构描述设计一全加器,全加器可由两个半加器和一个或门组成。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FkGnjbSI-1651836407532)(C:\Users\22899\Desktop\EDA\img\QQ截图20220421114111.png)]

--首先用VHDL的数据流描述方式设计半加器:
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY half_adder IS 
	PORT( ina, inb: IN STD_LOGIC;    
		q, outc: OUT STD_LOGIC);
END half_adder;
ARCHITECTURE rtl OF half_adder IS
BEGIN
	PROCESS ( ina, inb )
	BEGIN  
		q<= ina XOR inb; 
		outc <=  ina  AND  inb;
	END PROCESS;
END rtl;
--首先用VHDL的数据流描述方式设计半加器:
ENTITY or_gate IS 
  PORT( ina, inb: IN STD_LOGIC;   
                          q:OUT STD_LOGIC);
END or_gate;
    ARCHITECTURE orgate_arc OF or_gate IS 
BEGIN
   q<= ina OR inb;
END orgate_arc;
--下面将两个半加器,一个或门的端口,通过定义一些中间信号将其连接起来形成VHDL的结构描述。
--在下面举的全加器例子里定义了中间信号tmp1,tmp2和tmp3          
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY full_adder IS 
  PORT( ina, inb , inc : IN STD_LOGIC;   
                          q, outc: OUT STD_LOGIC);
END full_adder;
ARCHITECTURE structure OF full_adder IS 
    SIGNAL tmp1,tmp2,tmp3: STD_LOGIC;  
COMPONENT half_adder
   PORT( ina, inb: IN STD_LOGIC;        
               q, outc:OUT STD_LOGIC); 
END COMPONENT;
COMPONENT or_gate   
   PORT ( ina, inb : IN STD_LOGIC;      
                            q:OUT STD_LGIC); 
END COMPONENT;
BEGIN
  U0:half_adder  PORT MAP(ina,inb,tmp1,tmp2);
  U1:half_adder  PORT MAP (tmp1,inc,q,tmp3);
  U2:or_gate   PORT MAP(tmp2,tmp3,outc);
END fullsub_arc;
--图中虚线框各元件之间的连线命名。tmp1将第一个半加器的和输出连到第二个半加器的输入端。信号tmp2将第一个半加器的进位输出连至“或”门的一个输入端,信号tmp3将第二个半加器的进位输出连至“或”门的另一个输入端。
--          用三个元件调用语句定义这三个连接关系。
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY mix_add IS 
  PORT ( ina, inb , inc : IN STD_LOGIC;   
                          q, outc: OUT STD_LOGIC);
END full_adder;
ARCHITECTURE mix OF mix_add IS 
    SIGNAL d: STD_LOGIC;  
COMPNENT xor_gate IS
         PORT( ina,  inb   : IN STD_LOGIC; 
                                 ouc: OUT STD_LOGIC);
    END COMPONENT;
BEGIN
      outc <=(ina AND inb) OR  (d AND inc);  
      u1: xor_gate PORT MAP (ina, inb, d);
      u2: xor_gate PORT MAP (d,inc, q);  
END mix;
CONFIGURATION  part_mix OF mix_add  IS
   FOR mix
       FOR aLL:xor_gate USE ENTITY WORK.xor_gate(xor_arc);
       END FOR;
   END FOR;
END part_mix;

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73

选择器

2选1选择器的VHDL描述:

LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY mux21 IS
   PORT (a,b: IN STD_LOGIC;
          s: IN STD_LOGIC;
          y: OUT STD_LOGIC);
END mux21;
ARCHITECTURE mux_arch OF mux21 IS
BEGIN 
   y<=a WHEN s='0' ELSE
      b WHEN s='1';
END mux_arch;

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

用case 语句描述四选一电路

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GZ7fXyoq-1651836407532)(C:\Users\22899\Desktop\EDA\img\图片2.png)]

用条件信号赋值语句描述四选一电路

entity mux4 is
      port(i0, i1, i2, i3, a, b : in std_logic; 
              q : out std_logic);
  end  mux4;
  architecture  rtl  of  mux4  is
      signal  sel : std_logic_vector (1 downto 0);
  begin
      sel<=b & a;
      q<=i0  when  sel = “00”  else
         i1  when  sel = “01”  else
         i2  when  sel = “10”  else
         i3  when  sel = “11”;
  end  rtl; 

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

用选择信号赋值语句描述四选一电路

entity mux4 is
               port(i0, i1, i2, i3, a, b : in std_logic;
                      q : out std_logic);
        end  mux4;
       architecture  rtl  of  mux4  is
             signal  sel : std_logic_vector (1 downto 0);
       begin
             sel<=b & a;
             with  sel  select
                      q<=i0  when  sel = “00” ,
                      i1  when  sel = “01” ,
                      i2  when  sel = “10” ,
                      i3  when  sel = “11” ,
                     ‘X’  when  others;
             end  rtl; 

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

寄存器

4位移位寄存器设计

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BUpYv5LT-1651836407533)(C:\Users\22899\Desktop\EDA\img\图片3.png)]

LIBRARY	ieee;
USE		ieee.std_logic_1164.ALL;
ENTITY shifter IS
PORT(	din,clk:	IN	std_logic;
                         dout:	OUT std_logic);
END shifter;
ARCHITECTURE	a  OF shifter IS
    COMPONENT dff
    PORT	(D,clk:	IN      std_logic;
                            Q:	OUT  std_logic);
    END COMPONENT;
   SIGNAL d: std_logic _vector (4 DOWNTO 0);
BEGIN
	d(0)<=din;
   U0:dff  PORT MAP (d(0),clk,d(1));
   U1:dff  PORT MAP (d(1),clk,d(2));
   U2:dff  PORT MAP (D=>d(2), clk=> clk, Q=>d(3));
   U3:dff  PORT MAP (D=>d(3), clk=> clk, Q=>d(4));
  dout<=d(4);
END a;

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

4位移位寄存器设计(用生成语句)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-G5nA2pJD-1651836407533)(C:\Users\22899\Desktop\EDA\img\图片5.png)]

练习

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-H7ize5MO-1651836407533)(C:\Users\22899\Desktop\EDA\img\QQ截图20220420164721.png)]

LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
ENTITY my_design IS 
PORT (
	d:	       IN 	 std_logic_vector(11 DOWNTO 0);
	oe, clk:  IN 	 std_logic;
	ad:	       INOUT 	 std_logic_vector(11 DOWNTO 0);
	a:	       OUT 	 std_logic_vector(11 DOWNTO 0);
	int:	       OUT 	 std_logic;
	as:	       BUFFER std_logic);
END my_design;

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

1、编写包含全加器的实体代码。
2、编写4选1数据选择器的实体代码。

用元件例化方法设计下面电路

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Rxkypez9-1651836407534)(C:\Users\22899\Desktop\EDA\img\图片4.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8wq2q27j-1651836407534)(C:\Users\22899\Desktop\EDA\img\QQ截图20220421120006.png)]

计数器

一个完整描述(3 bit 计数器)

ENTITY counter3 IS
  PORT (clk,reset: IN BIT;
       count: OUT INTEGER RANGE 0 TO 7);
END counter3;
ARCHITECTURE my_arch OF counter3 IS
  SIGNAL count_tmp: INTEGER RANGE 0 TO 7;
BEGIN
  PROCESS
  BEGIN
    WAIT UNTIL (clk‘ EVENT AND clk='1');
    IF reset='1' OR count_tmp=7 THEN
       count_tmp<=0;
    ELSE
       cout_tmp<=count_tmp + 1;
    END IF;
  END PROCESS;
     count<=count_tmp;
END my_arch;

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

3bit计数器的等效描述(out与buffer的区别):

ENTITY counter3 IS
  PORT (clk,reset: IN BIT;
       count: BUFFER INTEGER RANGE 0 TO 7);
END counter3;
ARCHITECTURE my_arch OF counter3 IS
        - - SIGNAL count_tmp: INTEGER RANGE 0 TO 7;
BEGIN
  PROCESS
  BEGIN
    WAIT UNTIL (clk‘ EVENT AND clk='1');
    IF reset='1' OR count_tmp=7 THEN
       count <=0;
    ELSE
       count <= count + 1;
    END IF;
  END PROCESS;
            - -  count<=count_tmp;
END my_arch;

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

一个与非门不同实现方式的配置如下:

library ieee;
 use ieee.std_logic_1164.all;
 entity nand2 is
      port(a: in std_logic;
              b: in std_logic;
              c: out std_logic);
 end nand2;
 architecture art1 of nand2 is
 begin
       c <= not (a and b);
 end art1;
 
architecture art2 of nand2 is
 begin
      c<=‘1’ when (a=‘0’) and (b=‘0’) else
            ‘1’ when (a=‘0’) and (b=‘1’) else
            ‘1’ when (a=‘1’) and (b=‘0’) else
            ‘0’ when (a=‘1’) and (b=‘1’) else
            ‘0’;
 end art2;
 
configuration first of nand2 is
       for art1;
       end for;
 end first; 
 configuration second of nand2 is
       for art2
       end for;
 end  second;

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

例:一个对计数器实现多种形式的配置如右

ENTITY counter IS                              --8bit counter
  PORT (clear, clk: IN BIT;
               data_out: OUT INTEGER);
END counter;
ARCHITECTURE count_255 OF counter IS
BEGIN
  PROCESS (clk, clear)
    VARIABLE count: integer:=0;
  BEGIN
    IF clear='1' THEN
       count:=0;
 ELSIF clk‘ EVENT AND clk='1' THEN
       IF count=255 THEN
          count=0;
       ELSE
          count=count+1;
       END IF;
    END IF;
       data_out<=count;
  END PROCESS;
END count_255;
           
ARCHITECTURE count_64k OF counter IS --16bit counter
BEGIN
  PROCESS (clk, clear)
      VARIABLE count: integer:=0;
  BEGIN
    IF clear='1' THEN
       count:=0;
    ELSIF clk‘ EVENT AND clk='1' THEN
       IF count=65535 THEN
          count:=0;
ELSE
          count:=count+1;
       END IF;
    END IF;
       data_out<=count;
  END PROCESS;
END count_64K;
CONFIGURATION small_count OF counter IS
    FOR count_255
    END FOR;
END small_count;

CONFIGURATION big_count OF counter IS
    FOR count_64K
    END FOR;
END big_count;

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8Qq3mAL8-1651836407535)(C:\Users\22899\Desktop\EDA\img\QQ截图20220506160102.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zFUhUMYA-1651836407535)(C:\Users\22899\Desktop\EDA\img\QQ截图20220506160124.png)]

编码器

8-3优先级编码器。

library ieee;
 use ieee.std_logic_1164.all;
 entity coder is
    port(input: in std_logic_vector(7 downto 0);
    output: out std_logic_vector(2 downto 0));
 end coder;
  architecture art of coder is
 begin
       process(input)
       begin
             if input(7)=‘0’ then
                 output<=“000”;
             elsif input(6)=‘0’ then
                  output<=“001”;
             elsif input(5)=‘0’ then
                  output<=“010”;
             elsif input(4)=‘0’ then
                  output<=“011”;             
            elsif input(3)=‘0’ then
                  output<=“100”;
             elsif  input(2)=‘0’ then
                  output<=“101”;
             elsif input(1)=‘0’ then
                  output<=“110”’;
             else
                   output<=“111”;
             end if;
       end process;
 end art;               

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fBET6bad-1651836407536)(C:\Users\22899\Desktop\EDA\img\QQ截图20220421115356.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MzjFw2Be-1651836407536)(C:\Users\22899\Desktop\EDA\img\QQ截图20220421115430.png)]

触发器

用wait until语句实现D触发器

architecture rtl of  d is
     begin
        process
        begin
           wait until clk'event and clk='1';
           q <= d;      
        end process;
     end rtl;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

同步复位功能电路

process
    begin
       rst_loop: loop
          wait until clk’event and clk=‘1’;
            if  rst=‘1’  then
                x<=‘0’;
            else
                x<=a;
            end  if;
       end  loop  rst_loop; 
    end process;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

断言语句的使用(RS触发器)

LIBRARY	ieee;
USE		ieee.std_logic_1164.ALL;
USE		ieee.std_logic_arith.ALL;
USE		ieee.std_logic_unsigned.ALL;
ENTITY	rs_1		IS
	PORT	(s,r:		IN std_logic;
                          q,nq :	OUT std_logic);
END	rs_1;
ARCHITECTURE ar_11 OF rs_1 IS
BEGIN
	PROCESS
		VARIABLE blh_1:bit:=′0′;
        BEGIN
		ASSERT NOT(s=′1′AND r=′1′)
		REPORT"BOTH s AND r EQUAL TO′1′!“
             SEVERITY ERROR;
		IF s =′0′AND r=′0′ THEN
		   blh_1:=blh_1;
		ELSIF s=′0′AND r=′1′THEN
		   blh_1:=′0′;
		ELSE			
		  blh_1:=′1′;
		END IF;
		q<=blh_1 after 2 ns;
          nq<=NOT blh_1
		WAIT ON r,s;
	END PROCESS;
END ar_11;

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

使用元件配置来实现RS触发器

LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY nand2 IS 
  PORT (a: IN STD_LOGIC;
       b:IN STD_LOGIC;
       c: OUT STD_LOGIC);
END nand2;
ARCHITECTURE nand_arc OF nand2 IS
BEGIN 
   c<= NOT (a AND b);
END nand_arc;
CONFIGURATION nand_cfg OF nand2 IS
       FOR nand2_arc;
       END FOR;
END nand2_cfg ;

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

利用与非门实现基本RS触发器如下:

LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY rs IS
    PORT (r ,s: IN STD_LOGIC;
                 q, qf : BUFFER STD_LOGIC);
END rs; 
ARCHITECTURE rs_arc OF rs IS 
COMPONENT nand2 
      PORT (a: IN STD_LOGIC;
                   b: IN STD_LOGIC;
                   c: OUT STD_LOGIC);
END COMPONENT;
BEGIN
        u1: nand2 PORT MAP (s, qf, q);
        u2: nand2 PORT MAP (q, r, qf) ;
END rs_arc; 
CONFIGURATION rs_cfg OF rs Is
     FOR rs_arc;
;        FOR u1,u2: nand2 USE CONFIGURATION WORK.nand2_cfg ;
         END FOR;
     END FOR;
END rs_cfg;

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fK5sMIPV-1651836407537)(C:\Users\22899\Desktop\EDA\img\QQ截图20220421113456.png)]

T触发器

2)T触发器
 library ieee;
 use ieee.std_logic_1164.all;
 entity t_ff is
      port(t, clk : in std_logic;
             q : buffer std_logic);
 end t_ff;
 architecture rtl of t_ff is
 begin
      process(clk)
      begin
            if clk’event and clk=‘1’ then
                 q<=not q;
            end if;
      end process;
 end rtl;

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

分频器

二进制分频器的VHDL源程序

Library ieee;
Use ieee.std_logic_1164.all;
Use ieee.std_logic_unsigned.all;
Use ieee.std_logic_arith.all;

Entity fdiv is
  generic(N: integer:=3);      --rate=2N,N为正整数
  port(
        clkin: IN std_logic;
        clkout: OUT std_logic
        );
End fdiv;
Architecture a of fdiv is
  signal cnt: std_logic_vector(N-1 downto 0);
Begin
  process(clkin)
  begin
      if(clkin'event and clkin='1') then
          cnt <= cnt+1;
      end if;
  end process;

  clkout <= cnt(N-1);
End a;


  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

状态机

--例题 6.44 摩尔型程序
entity moore is
port(x,clock:in std_logic;
z:out std_logic);
end moore;
architecture behavior of moore is
type state_type is (s0,s1,s2,s3);
signal current_state:state_type;
signal next_state:state_type;
begin
combin:
process(current_state,x)
begin
case current_state is
when s0=>z<='0';
if x='0' then 
next_state<=s0;
else
next_state<=s1;
end if;
when s1=>z<='1';
if x='0' then 
next_state<=s2;
else
next_state<=s1;
end if;
when s2=>z<='0';
if x='0' then 
next_state<=s3;
else
next_state<=s2;
end if;
when s3=>z<='0';
if x='0' then 
next_state<=s1;
else
next_state<=s0;
end if;
end case;
end process;
synch:
process(clock)
begin
if clock'event and clock='1' then
current_state<=next_state;
end if;
end process;
end behavior;
--例题 6.45 米勒型程序
entity mealy is
port(x,clock:in std_logic;
z:out std_logic);
end mealy;
architecture behavior of mealy is
type state_type is (s0,s1,s2,s3);
signal current_state:state_type;
signal next_state:state_type;
begin
combin:
process(current_state,x)
begin
case current_state is
when s0=> if x='0' then z<='0';
 next_state<=s0;
else
z<='1';
next_state<=s1;
end if;
when s1=> if x='0' then z<='0';
next_state<=s2;
else
z<='1';
next_state<=s1;
end if;
when s2=> if x='0' then z<='1';
next_state<=s3;
else
z<='0';
next_state<=s2;
end if;
when s3=> if x='0' then z<='0';
next_state<=s1;
else
z<='1';
next_state<=s0;
end if;
end case;
end process;
synch:
process(clock)
begin
if clock'event and clock='1' then
current_state<=next_state;
end if;
end process;
end behavior;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96

习题

第4章 习题
1、进程语句的特点是什么?应从哪几个方面来理
解进程语句?
2、块语句的作用是什么?有什么特点?
3、简单并行赋值语句与什么语句等效?为什么?
条件信号赋值语句、选择信号赋值语句又分别
与什么语句等效?有什么异同点?
4、元件例化语句的作用是什么?如何进行元件例
化?元件例化时端口映射有哪两种方式?有什
么注意事项?
5、生成语句与循环语句的异同点是什么?

IF语句和CASE语句最大的差别是什么?

1、信号与变量的区别有哪些?信号可以用来描述哪些硬件特性?
答:1)赋值方式的不同:变量:= 表达式;信号 < = 表达式;
2)硬件实现的功能不同:信号代表电路单元、功能模块间的互联,代表实际的硬件连线;
变量代表电路单元内部的操作,代表暂存的临时数据。
3)有效范围不同:信号:程序包、实体、结构体-全局量。变量:进程、子程序----局部量。
4)赋值行为的不同:信号赋值延迟更新数值、时序电路;变量赋值立即更新数值、组合电路。
2、如何用嵌套式if语句描述具有优先级的电路?
答:if_then_elsif 语句中隐含了优先级别的判断,最先出现的条件优先级最高,可用于设计具有优先级的电路。
3、case语句有什么特点?其分支条件使用时有哪些注意事项?
答:1)分支条件的值必须在表达式的取值范围内。
2)两个分支条件不能重叠。
3)CASE语句执行时必须选中,且只能选中一个分支条件。
4)如果没有others分支条件存在,则分支条件必须覆盖表达式所有可能的值。
4、loop语句的类型有哪些?其循环变量有什么特点?那种类型的loop语句综合器不支持?
答:1)无限loop语句
2) for ··· loop语句
循环变量是loop内部自动声明的局部量,仅在loop内可见;
不需要指定其变化方式。
3) while … loop语句
循环变量i需事先定义、赋初值,并指定其变化方式。
while … loop语句综合器不支持
5、next语句与exit语句的区别是什么?
答:Next语句无条件终止当前的循环,跳回到本次循环LOOP语句开始处,开始下次循环。而exit语句则是跳向loop语句的终点。
6、wait语句有哪些类型?wait语句在进程中的作用是什么?与敏感信号表有什么关系?
答:wait语句有以下类型:
wait——无限等待.
wait on——敏感信号量变化
wait until——条件满足
wait for——时间到
wait语句在进程中的作用是描述仿真时的两个状态:
执行或挂起
进程状态的变化受wait语句或敏感信号量变化的控制。
敏感信号量列表和wait 语句只能选其一,两者不能同时使用。

1、一个完整的 VHDL语言程序通常包含 实体(entity) , 构造(architecture), 配置(configuration), 包集合(package)和 库(library) 5各部分。

2、在一个实体的端口方向说明时,输入使用 in表示,那么构造体内部不能再使用的输出是 用 out 表示;双向端口是用 inout 表示;构造体内部可再次使用的输出是用 buffer 表示;

3、一个构造体可以使用几个子结构,即相对比较独立的几个模块来构成。VHDL语言可以 有以下 3种形式的子结构描述语句: BLOCK 语句结构; PROCESS语句结构和 SUBPROGRAMS结构。

4、VHDL的客体,或称数据对象包括了常数、 变量 variable 和 信号 signal。

5、请列出三个 VHDL语言的数据类型,如实数、位等。 位矢量 , 字符 , 布尔 量。

6、设 D0为’0’,D1为’0’,D2为’1’,D3为’0’,D0&D1&D2&D3的运算结果是“0010”,D3&D2 &D1&D0的运算结果是“0100”。

7、构造体的描述方式包括三种,分别是 寄存器传输(RTL)描述方法或称数据流 ; 构 造体的结构描述方式 和 构造体的行为描述方式 。

1.传统的系统硬件设计方法是采用自下而上(bottom up)的设计方法,利用硬件描述语言 (HDL)的硬件电路设计方法采用自上而下(top down)的设计方法。

2、VHDL可以采用层次化的设计,一个高层的结构体中可以调用低层的实体

3、一个 VHAL程序中可以使用多个进程语句。

逻辑运算符<关系运算符<乘法运算

1.VHDL实体由实体说明语句(ENTITY)、类属说明语句(GENERIC)、端口说明语句(PORT)、 结束语句(END)组成。

2.VHDL结构体由结构体说明语句、功能描述语句组成。

3.VHDL中的对象是指 常量 、 变量 、 信号 、 文件 。

4.VHDL定义的基本数据类型包括整数、实数、位、位矢量、布尔、字符、字符串、自然数、 时间、错误类型十种。

5.VHDL有逻辑运算符、关系运算符、算术运算符、并置运算四类操作符。

6.VHDL的顺序语句只能出现在进程(PROCESS)、过程(PROCEDURE)和函数(FUNCTION) 中,是按照书写顺序自上而下,一条一条执行。

7.VHDL的进程(process)语句是由顺序语句组成的,但其本身却是并行执行的。

8.所谓组合逻辑电路是指:在任何时刻,逻辑电路的输出状态只取决于电路各输入信号的组 合,而与电路的原有状态无关。

9.寄存器按照功能不同可分为两类 只读 寄存器和 随机 寄存器。

10.数字电路按照是否有记忆功能通常可分为两类 组合电路 、 时序电路 。

11.由四位移位寄存器构成的顺序脉冲发生器可产生 16个顺序脉冲。9. 触发器 是组成寄 存器和移位寄存器的基本单元电器,而一个触发器可存放 1 位二进制代码,一个 n位的 数码寄存器和移位寄存器需由 n个触发器组成。

12.常见的触发器有 JK触发器 、 T触发器 、 D触发器 和 RS触发器 。

13.块语句(BLOCK)实现的是从 结构体形式 上的划分,并非 功能 上的划分。

14.VHDL中的断言语句主要用于程序调试、时序仿真的人机对话,属于不可综合语句,综 合中被忽略而不会生成逻辑电路,只用于检测某些电路模型是否正常工作等。

15.过程调用语句属于 VHDL子程序 的一种类型。 子程序 是一个 VHDL程序模块,利用 顺序语句来定义和完成算法,应用它能更有效地完成重复性的设计工作。

16.在进程中,当程序执行到 WAIT语句时,运行程序将被 挂起 ,直到满足此语句设置的 条件后,才重新开始执行进程或过程中的程序。

17.NEXT语句主要用于在 LOOP语句执行中进行有条件的或无条件的 转向 控制。

18.VHDL常用的预定义属性有 数值属性 、 函数属性 、 类型属性 、 范 围属性

和 信号属性 5大类。

19.VHDL的数值属性有 数值类型 、 数值数组 和 数值块 3大类。

20.VHDL的函数属性有 函数数值 、 函数数组 和 函数信号 3种。

21.VHDL语言总共定义了 DELAYED、 STABLE、 QUIET和 TRANSACTION4种信号属 性供设计者使用。

22.数据类型属性(TypeAttributes)主要用于返回指定类型或子类型的基本(BASE)类 型(Type)。

23.VHDL系统的仿真延迟分为 惯性延时 和 传输延时 2种。

体的描述方式包括三种,分别是 寄存器传输(RTL)描述方法或称数据流 ; 构 造体的结构描述方式 和 构造体的行为描述方式 。

1.传统的系统硬件设计方法是采用自下而上(bottom up)的设计方法,利用硬件描述语言 (HDL)的硬件电路设计方法采用自上而下(top down)的设计方法。

2、VHDL可以采用层次化的设计,一个高层的结构体中可以调用低层的实体

3、一个 VHAL程序中可以使用多个进程语句。

逻辑运算符<关系运算符<乘法运算

1.VHDL实体由实体说明语句(ENTITY)、类属说明语句(GENERIC)、端口说明语句(PORT)、 结束语句(END)组成。

2.VHDL结构体由结构体说明语句、功能描述语句组成。

3.VHDL中的对象是指 常量 、 变量 、 信号 、 文件 。

4.VHDL定义的基本数据类型包括整数、实数、位、位矢量、布尔、字符、字符串、自然数、 时间、错误类型十种。

5.VHDL有逻辑运算符、关系运算符、算术运算符、并置运算四类操作符。

6.VHDL的顺序语句只能出现在进程(PROCESS)、过程(PROCEDURE)和函数(FUNCTION) 中,是按照书写顺序自上而下,一条一条执行。

7.VHDL的进程(process)语句是由顺序语句组成的,但其本身却是并行执行的。

8.所谓组合逻辑电路是指:在任何时刻,逻辑电路的输出状态只取决于电路各输入信号的组 合,而与电路的原有状态无关。

9.寄存器按照功能不同可分为两类 只读 寄存器和 随机 寄存器。

10.数字电路按照是否有记忆功能通常可分为两类 组合电路 、 时序电路 。

11.由四位移位寄存器构成的顺序脉冲发生器可产生 16个顺序脉冲。9. 触发器 是组成寄 存器和移位寄存器的基本单元电器,而一个触发器可存放 1 位二进制代码,一个 n位的 数码寄存器和移位寄存器需由 n个触发器组成。

12.常见的触发器有 JK触发器 、 T触发器 、 D触发器 和 RS触发器 。

13.块语句(BLOCK)实现的是从 结构体形式 上的划分,并非 功能 上的划分。

14.VHDL中的断言语句主要用于程序调试、时序仿真的人机对话,属于不可综合语句,综 合中被忽略而不会生成逻辑电路,只用于检测某些电路模型是否正常工作等。

15.过程调用语句属于 VHDL子程序 的一种类型。 子程序 是一个 VHDL程序模块,利用 顺序语句来定义和完成算法,应用它能更有效地完成重复性的设计工作。

16.在进程中,当程序执行到 WAIT语句时,运行程序将被 挂起 ,直到满足此语句设置的 条件后,才重新开始执行进程或过程中的程序。

17.NEXT语句主要用于在 LOOP语句执行中进行有条件的或无条件的 转向 控制。

18.VHDL常用的预定义属性有 数值属性 、 函数属性 、 类型属性 、 范 围属性

和 信号属性 5大类。

19.VHDL的数值属性有 数值类型 、 数值数组 和 数值块 3大类。

20.VHDL的函数属性有 函数数值 、 函数数组 和 函数信号 3种。

21.VHDL语言总共定义了 DELAYED、 STABLE、 QUIET和 TRANSACTION4种信号属 性供设计者使用。

22.数据类型属性(TypeAttributes)主要用于返回指定类型或子类型的基本(BASE)类 型(Type)。

23.VHDL系统的仿真延迟分为 惯性延时 和 传输延时 2种。

24.子程序有两种类型,即 过程 和 函数 。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/寸_铁/article/detail/805207
推荐阅读
相关标签
  

闽ICP备14008679号