一、VHDL语言的基本语法
D触发器的VHDL实现
1、VHDL语言的表示符
2、VHDL的数字
2.1 数字型文字
156E2的意思是156 × \times × 1 0 2 10^2 102;
下划线可以连接数字。
2.2 数字基数表示的文字
2.3 字符串型文字
2.4 下标名及下标段名
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、常数
2、变量
3、信号(SIGNAL)
三、VHDL中的数据类型
1、VHDL的预定义数据类型
1.1 布尔(BOOLEAN)
1.2 位(BIT)
1.3 位矢量(BIT_VECTOR)
1.4 字符(CHARACHTER)
1.5 整数(INTEGER)
1.6 实数(REAL)
1.7 字符串(STRING)
1.8 时间(TIME)数据类型
1.9 错误等级(SEVERITY_LEVEL)
2、IEEE预定义标准逻辑位与矢量
2.1 标准逻辑位STD_LOGIN数据类型
2.2 标准逻辑矢量(STD_LOGIC_VECTOR)
2.3 其他预定义标准数据类型
(1) 无符号数据类型(UNSIGNED TYPE)
(2) 有符号数据类型(SIGNED TYPE)
2.4 用户自定义数据类型方式
(1) TYPE语句用法
(2) SUBTYPE语句的用法
(3) 枚举类型
(4) 数组类型
(5) 记录类型
(6) 数据类型转换
在
VHDL
程序设计中,不同类型的对象不能相互赋值。对于变量、信号、常量、文件进行操作时,数据类型一定要一致,否则
EDA
工具进行综合、仿真等过程时将不能通过。
为了进行不同类型的数据变换,可以有
3
种方法:类型标记法、函数转换法和常数转换法。
VHDL程序设计实例
(1)vhdl设计组成:
库和程序包(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入门基础_什么是VHDL分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/70140.html