D触发器的VHDL实现
156E2的意思是156 × \times × 1 0 2 10^2 102;
下划线可以连接数字。
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
所以区别就是显示方向不同而已。
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) 记录类型
库和程序包(libary, package)
实体(entity)
结构体(architecture)
配置(configuration)
通俗来讲:
库和包 -> 材料,工具箱
实体 -> 硬件外部的接口
结构体 -> 硬件内部的具体实现
实体:实体(Entity)提供了被设计系统或器件的公共信息,指明了输入与输出引脚。实体由实体名、类型说明、端口说明、实体说明部分和实体语句部分组成。
entity 实体名 is
generic(常数名:数据类型:初值)
port(端口信号名:数据类型)
end 实体名
结构体:通过vhdl语句描述实体的具体行为和逻辑功能,
(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内部。
--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