原创 以半加器 解释vhdl case 元件例化等语法

2012-2-1 21:13 3933 5 5 分类: FPGA/CPLD

【例4-20】
LIBRARY  IEEE;   --半加器描述(2)
USE IEEE.STD_LOGIC_1164.ALL; 
ENTITY h_adder IS 
PORT (a, b : IN STD_LOGIC;  
    co, so : OUT STD_LOGIC);  
END ENTITY h_adder;     
ARCHITECTURE fh1 OF h_adder  is  
 SIGNAL abc : STD_LOGIC_VECTOR(1 DOWNTO 0);
BEGIN
  abc <= a & b ; 
 PROCESS(abc)
  BEGIN
   CASE abc IS
    WHEN "00" => so<='0'; co<='0' ;
    WHEN "01" => so<='1'; co<='0' ;
    WHEN "10" => so<='1'; co<='0' ;
    WHEN "11" => so<='0'; co<='1' ;
    WHEN OTHERS => NULL ;
   END CASE;
 END PROCESS;
 
END ARCHITECTURE fh1 ;


1. CASE语句
CASE 语句属于顺序语句,因此必须放在进程语句中使用,CASE 语句的一般表达
式是:
CASE <表达式> IS
When <选择值或标识符> => <顺序语句>; ... ; <顺序语句> ;
When <选择值或标识符> => <顺序语句>; ... ; <顺序语句> ;
...
END CASE ;
当执行到CASE语句时,首先计算<表达式> 的值,然后根据WHEN条件句中与之
相同的<选择值或标识符>,执行对应的<顺序语句>,最后结束CASE语句。条件句中的
=“>”不是操作符,它的含义相当于THEN(或“于是” ) 。使用CASE语句应该注意以
下几点:
● WHEN条件句中的选择值或标识符所代表的值必须在表达式的取值范围内。
● 除非所有条件句中的选择值能完整覆盖CASE语句中表达式的取值,否则最末一
个条件句中的选择必须用关键词 OTHERS 表示以上已列的所有条
件句中未能列出的其他可能的取值。OTHERS只能出现一次,且只能作为最后一
种条件取值。 使用OTHERS的目的是为了使条件句中的所有选择值能涵盖表达式
的所有取值,以免综合器会插入不必要的锁存器。关键词NULL表示不做任何操
作。
● CASE语句中的选择值只能出现一次,不允许有相同选择值的条件语句出现。
● CASE语句执行中必须选中,且只能选中所列条件语句中的一条。

 

2.
SIGNAL abc : STD_LOGIC_VECTOR(1 DOWNTO 0);

标准逻辑矢量数据类型STD_LOGIC_VECTOR
STD_LOGIC_VECTOR 类型与 STD_LOGIC 一样,都定义在 STD_LOGIC_1164 程序包中,
但STD_LOGIC属于标准位类型,而STD_LOGIC_VECTOR被定义为标准一维
数组,数组中的每一个元素的数据类型都是标准逻辑位 STD_LOGIC。

使用STD_LOGIC_VECTOR可以表达电路中并列的多通道端口或节点,或者总线BUS。
在使用STD_LOGIC_VECTOR中,必须注明其数组宽度,即位宽,如:
B : OUT  STD_LOGIC_VECTOR(7 DOWNTO 0);  
或       SIGNAL A :STD_LOGIC_VECTOR(1 TO 4)
上句表明标识符B的数据类型被定义为一个具有8位位宽的矢量或总线端口信号,
它的最左位,即最高位是B(7) ,通过数组元素排列指示关键词“DOWNTO”向右依次
递减为B(6)、B(5)…B(0) 。根据以上两式的定义,A和B的赋值方式如下:
B <= "01100010" ;            -- B(7)为 '0'
B(4 DOWNTO 1)<= "1101" ;   -- B(4)为 '1'
B(7 DOWNTO 4)<= A ;         -- B(6)等于 A(2)
其中的"01100010"表示二进制数(矢量位) ,必须加双引号,如"01";而单一二进制数则
用单引号,如 '1'
语句SIGNAL A:STD_LOGIC_VECTOR(1 TO 4)中的A的数据类型被定义为4
位位宽总线,数据对象是信号SIGNAL,其最左位是A(1) ,通过关键词“TO”向右依
次递增为A(2)、A(3)和A(4)。
与STD_LOGIC_VECTOR对应的是BIT_VECTOR位矢量数据类型,其每一个元素
的数据类型都是逻辑位BIT,使用方法与STD_LOGIC_VECTOR相同,如:
     SIGNAL C :BIT_VECTOR(3 DOWNTO 0);
例 4-20 中的内部信号被定义为二元素的 STD_LOGIC_VECTOR 数据类型,高位是
abc(1) ,低位是abc(0)。

 

3.
并置操作符  &

操作符  & 表示将操作数(如逻辑位 '1' 或 '0'  )或是数组合并起来
形成新的数组。例如“VH”&“DL”的结果为“VHDL”;'0'&'1'&'1'的结果为''11''。
显然语句abc <= a & b的作用是令:abc(1)<= a;abc(0)<= b 。

因此,利用并置符可以有多种方式来建立新的数组,如可以将一个单元素并置于一
个数的左端或右端形成更长的数组,或将两个数组并置成一个新数组等,在实际运算过
程中,要注意并置操作前后的数组长度应一致。以下是一些并置操作示例:
SIGNAL a : STD_LOGIC_VECTOR (3 DOWNTO 0);
SIGNAL d : STD_LOGIC_VECTOR (1 DOWNTO 0);
...
a  <= '1'&'0'&d(1)&'1'  ;    -- 元素与元素并置,并置后的数组长度为4
...
IF a & d = "101011"  THEN ... –- 在IF条件句中可以使用并置符

 


【例4-22】
LIBRARY  IEEE;   --1位二进制全加器顶层设计描述
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY f_adder IS
PORT (ain,bin,cin  : IN STD_LOGIC;
         cout,sum   : OUT STD_LOGIC );
END ENTITY f_adder;
ARCHITECTURE fd1 OF f_adder IS
  COMPONENT h_adder
   PORT (  a,b :  IN STD_LOGIC;
      co,so :  OUT STD_LOGIC);
  END COMPONENT ;
  COMPONENT or2a
 PORT (a,b : IN STD_LOGIC; 
            c : OUT STD_LOGIC);
  END COMPONENT;
SIGNAL d,e,f  :  STD_LOGIC; 
  BEGIN
   u1 : h_adder PORT MAP(a=>ain,b=>bin,co=>d,so=>e);    
   u2 : h_adder PORT MAP(a=>e,  b=>cin, co=>f,so=>sum);
   u3 :   or2a   PORT MAP(a=>d,  b=>f,   c=>cout);
 END ARCHITECTURE fd1;

1
在 ARCHITECTURE 和 BEGIN 之间利
用COMPONENT语句对准备调用的元件(或门和半加器)作了声明,并定义了d、e、f
三个信号作为器件内部的连接线(见图4-10) 。最后利用端口映射语句PORT MAP( )
将两个半加器和一个或门连接起来构成一个完整的全加器。

元件例化语句由两部分组成,第一部分是将一个现成的设计实体定义为
语句的功能是对待调用的元件作出调用声明,它的最简表达式如下:
COMPONENT 元件名 IS 
PORT  (端口名表) ;
END COMPONENT 文件名 ;
这一部分可以称为是元件定义语句,相当于对一个现成的设计实体进行封装,使其
只留出对外的接口界面。 就像一个集成芯片只留几个引脚在外一样, “端口名表” 需要列
出该元件对外通信的各端口名。命名方式与实体中的PORT()语句一致。元件定义语句必
须放在结构体的ARCHITECTURE 和BEGIN之间。另外应注意,尽管例4-22中对或门
和半加器的调用声明的端口说明中使用了与原来元件(VHDL描述)相同的端口符号,
但这并非是唯一的表达方式,如可以作如下表达(数据类型的定义必须与原文件一致) : 
COMPONENT h_adder
     PORT (  c,d :  IN STD_LOGIC;
       e,f :  OUT STD_LOGIC);


2
元件例化语句的第二部分则是此元件与当前设计实体(顶层文件)中元件间及端口
的连接说明。语句的表达式如下:
例化名 : 元件名 PORT MAP( [端口名 =>] 连接端口名,...);
其中的“例化名”是必须存在的,它类似于标在当前系统(电路板)中的一个插座名,
而“元件名”则是准备在此插座上插入的、已定义好的元件名,即为待调用的VHDL设
计实体的实体名。对应于例 4-22 中的元件名 h_adder 和 or2a ,其例化名分别为 u1、u2
和u3。PORT MAP是端口映射的意思,或者说端口连接的意思。其中的“端口名”是在
元件定义语句中的端口名表中已定义好的元件端口的名字,或者说是顶层文件中待连接
的各个元件本身的端口名; “连接端口名” 则是顶层系统中, 准备与接入的元件的端口相
连的通信线名,或者是顶层系统的端口名。

以例 4-22 中的例化名为 u1 的端口映射语句为例:a=>ain 表示元件 h_adder 的内部
端口信号a(端口名)与系统的外部端口名ain 相连;co=>d 表示元件h_adder 的内部端
口信号co(端口名)与元件外部的连线d(定义在内部的信号线)相连,如此等等。
注意:这里的符号“=>”是连接符号,其左面放置内部元件的端口名,右面放置内
部元件以外需要连接的端口名或信号名,这种位置排列方式是固定的,但连
接表达式(如co=>d)在PORT MAP语句中的位置是任意的。
在例4-18中将一个简单的或门用一个完整的文件描述出来, 主要是借此说明多层次
设计和元件例化的设计流程和方法。在实际设计中完全没有必要如此繁琐。


 

文章评论0条评论)

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