原创 vhdl 从d触发器程序理解vhdl语法

2012-2-4 12:13 3230 5 5 分类: FPGA/CPLD

 

以下内容是 根据《eda技术使用手册》第三版中的一个实例的介绍
下面是一个d触发器的代码
LIBRARY IEEE ;
USE IEEE.STD_LOGIC_1164.ALL ; 
ENTITY DFF1 IS
  PORT (CLK : IN STD_LOGIC ;
            D : IN STD_LOGIC ;
            Q : OUT STD_LOGIC );
 END ;
 ARCHITECTURE bhv OF DFF1 IS
  SIGNAL Q1 : STD_LOGIC ;   --类似于在芯片内部定义一个数据的暂存节点
  BEGIN
   PROCESS (CLK)
    BEGIN
     IF  CLK'EVENT AND CLK = '1'    
         THEN  Q1 <= D ;    
     END IF; 
         Q <= Q1 ;              --将内部的暂存数据向端口输出  
   END PROCESS ;
 END bhv;
一些知识点:
1.
PROCESS (CLK)
按照书本上所说的:通常要求将进程中所有的输入信号都放在敏感信号表中 ,可以看到上面process中还有一个输入信号是‘D’,但是并没有放到里面
感觉有点问题
 
2.BIT数据类型定义:        
TYPE BIT IS('0','1');
STD_LOGIC数据类型定义: 
TYPE STD_LOGIC IS ('U','X','0','1','Z','W','L','H','-');
:'U'表示未初始化的;'X'表示强未知的;
'0'表示强逻辑0;'1'表示强逻辑1;'Z'表示高阻态;'W' 表示弱未知的;'L'表示弱逻辑0;
'H'表示弱逻辑1;'-'表示忽略。
3.
LIBRARY  STD ;
USE STD.STANDARD.ALL ;  
第二句中的LIBRARY是关键词,LIBRARY STD表示打开STD库;第三句的USE
和ALL是关键词,USE STD.STANDARD.ALL表示允许使用STD库中STANDARD程
序包中的所有内容(.ALL) ,如类型定义、函数、过程、常量等。
LIBRARY  <设计库名>;
USE  <设计库名>.<程序包名>.ALL ;  
STD_LOGIC 数据类型定义在被称为 STD_LOGIC_1164 的程序包中
此包由 IEEE定义,而且此程序包所在的程序库的库名被取名为IEEE
LIBRARY  IEEE ;
USE  IEEE.STD_LOGIC_1164.ALL ;
4
标识符Q1的数据对象为信号SIGNAL,其数据类型为STD_LOGIC。由于Q1被定义为
器件的内部节点信号,数据的进出不像端口信号那样受限制,所以不必定义其端口模式
(如 IN、OUT 等) 。定义 Q1 的目的是为了在设计更大的电路时使用由此引入的时序电路的信号,这是一种常用的时序电路设计的方式。
Q1,对它规定的数据对象是信号,而数据类型是STD_LOGIC,前者
规定了Q1的行为方式和功能特点,后者限定了Q1的取值范围。根据VHDL规定,Q1
作为信号,它可以如同一根连线那样在整个结构体中传递信息,也可以根据程序的功能
描述构成一个时序元件;但 Q1 传递或存储的数据的类型只能包含在 STD_LOGIC 的定
义中。
 
5
数据对象有三类,即信号(SIGNAL) 、变量(VARIABLE)和常量(CONSTANT)
注意的是VARIABLE 一定要在begin前面赋值。
 
6
看vhdl和verilog的区别
vhdl中的“=”是比较相等的意思,而verilog中是 立即赋值的意思。
7.
这个地方的难点理解:
IF  CLK'EVENT AND CLK = '1'
条件语句的判断表达式“CLK'EVENT AND CLK='1'”是用于检测时钟信
号CLK的上升沿的,即如果检测到CLK的上升沿,此表达式将输出“true”。
关键词EVENT是信号属性,VHDL通过以下表达式来测定某信号的跳变边沿:
<信号名>'EVENT
短语“clock'EVENT”就是对 clock 标识符的信号在当前的一个极小的时间段δ内发
生事件的情况进行检测。所谓发生事件,就是 clock 的电平发生变化,从一种电平方式
转变到另一种电平方式。如果 clock 的数据类型定义为 STD_LOGIC,则在δ时间段内,
clock 从其数据类型允许的9 种值中的任何一个值向另一值跳变,如由'0'变成'1'、由'1'变
成'0'或由'Z'变成'0',都认为发生了事件,于是此表达式将输出一个布尔值“true” ,否则
为“false”。
如果将以上短语“clock'EVENT”改成:clock'EVENT AND clock='1',则表示一旦
“clock'EVENT”在δ 时间内测得 clock 有一个跳变,而此小时间段δ之后又测得 clock
为高电平'1',即满足此语句右侧的clock ='1'的条件,于是两者相与(AND)后返回值为
true,由此便可以从当前的 clock ='1'推断在此前的δ时间段内,clock 必为'0' (设 clock
的数据类型是BIT) 。因此,以上的表达式就可以用来对信号clock的上升沿进行检测,
于是语句clock'EVENT AND clock ='1'就成了边沿测试语句。
严格地说,如果信号CLK的数据类型是STD_LOGIC,则它可能的取值有9种,而CLK'EVENT为真的条件是CLK在9种数据中的任何两种间的跳变,因而当
CLK'EVENT AND CLK='1' 为真时,并不能推定 CLK 在  δ 时刻前是'0' (例如,它可以从'Z'变到'1') ,从而不能肯定 CLK 发生了一次由'0'到'1'的上升沿的跳变。为了确保此 CLK 发生的是一次
上升沿的跳变,例4-11采用了如下条件判断语句:
CLK'EVENT AND (CLK='1')AND (CLK'LAST_VALUE='0')
与 EVENT 一样,'LAST_VALUE 也属于预定义信号属性,它表示最近一次事件(EVENT)发生前的值。CLK'LAST_VALUE='0'为true,表示CLK在δ时刻前为'0'。 若CLK'EVENT AND CLK='1'和
CLK'LAST_VALUE='0'相与为真, 则保证了CLK在δ时刻内的跳变是从'0'变到'1'的。
上面的语句和
IF  rising_edge(CLK)
或者:
IF  CLK='1' AND CLK'LAST_VALUE='0'
效果一样。

文章评论0条评论)

登录后参与讨论
我要评论
0
5
关闭 站长推荐上一条 /2 下一条