architecture archmux of mux4 is begin
y<= a0 when s=\ else a1 when s=\ else a2 when s=\ else a3 ; end archmux;
三、例化语句
即元件调用,可参见以下两节:“元件及元件例化” 及“配置”。
□ 顺序(Sequential)语句
最常用的顺序语句是IF-THEN-ELSE语句和CASE-WHEN语句。顺序语句总是处于进程(PROCESS)的内部,并且从仿真的角度来看是顺序执行的。
.IF-THEN-ELSE
IF-THEN-ELSE语句只在进程中使用,它根据一个或一组条件的布尔运算而选择某一特定的执行通道。例如:
architecture archmux of mux4 is begin
process(s,a0,a1,a2,a3) begin
if s=\ then y<=a0;
elsif s=\ then y<=a1;
elsif s=\ then y<=a2; else y<=a3; end if; end process; end archmux;
ELSIF可允许在一个语句中出现多重条件,每一个“IF” 语句都必须有一个对应的“END IF”语句。“IF” 语句可嵌套使用,即在一个IF语句中可在调用另一个“IF”语句。
.CASE-WHEN
135 — —
CAE-WHEN语句也只能在进程中使用。例如: architecture archmux of mux4 is begin
process(s,a0,a1,a2,a3) begin
case s is
when \=> y<=a0; when \=> y<=a1; when \=> y<=a2; when others => y<=a3; end case; end process; end archmux;
CAE-WHEN语句常用于状态机的描述中,详见第2节的例子。此外还有“for-loop”语句,可见第2节的例子“奇偶校验电路”,以及wait until ,wait on语句等。
4.1.9 元件及元件例化
元件声明是对VHDL模块(即底层设计,也是完整的VHDL设计)的说明,使之可在其他模块中被调用,元件声明可放在程序包中,也可在某个设计的结构体中声明。 元件例化指元件的调用。元件声明及元件例化的语法分别如下:
元件声明:
component<元件实体名>
port (<元件端口信息,同该元件实现时的实体的port部分>); end component;
--元件例化:
< 例化名>:<实体名,即元件名> port map (<端口列表>);
例如,在一个设计中调用一个模为10的计数器cntm10和一个七段译码器decode47构成如下电路,则该调用过程即元件例化的VHDL描述如下: library IEEE;
use IEEE.std_logic_1164.all;
entity cntvh10 IS port
( Rd,ci,clk :in std_logic; co : out std_logic; qout : out std_logic_vector(6 downto 0));
136 — —
end cntvh10;
ARCHITECTURE arch OF cntvh10 IS --元件声明
Component decode47 is port
(adr: in std_logic_vector(3 downto 0);
decodeout:out std_logic_vector(6 downto 0)); end Component;
Component cntm10 is port (ci : IN std_logic; nreset : IN std_logic; clk : IN std_logic; co : out std_logic; qcnt : buffer std_logic_vector(3 downto 0)); end Component;
signal qa : std_logic_vector(3 downto 0); BEGIN
u1: cntm10 port map(ci,Rd,clk,co,qa); --元件例化 u2: decode47 port map(decodeout=>qout, adr=>qa); END arch;
元件例化时的端口列表可按位置关联方法,如u1,这种方法要求的实参(该设计中连接到端口的实际信号,如ci,Rd等)所映射的形参(元件的对外接口信号)的位置同元件声明中一样;元件例化时的端口列表也可按名称关联方法映射实参与形参,如u2。格式为(形参1=>实参1,形参2=>实参2,….)。这种方法与位置无关。 其描述的电路为下图所示:
cntm10(模为10的计数器)及decode47(七段译码器)可参考“上机练习”
参数化元件可增加元件例化的灵活性。所谓参数化元件是指元件的规模(或特性)可以通过引用参数的形式指定的一类元件。例如,下面定义了一个位数可调的计数器: library ieee; use ieee.std_logic_1164.all;
137 — —
use ieee.std_logic_unsigned.all;
ENTITY cntnbits IS
generic(cntwidth:integer:=4); --定义了一个可调参数
PORT
(
ci : IN std_logic;
nreset : IN std_logic; clk : IN std_logic; co : out std_logic; qcnt : buffer std_logic_vector(cntwidth-1 downto 0)
);
END cntnbits;
ARCHITECTURE behave OF cntnbits IS
constant allis1:std_logic_vector(cntwidth-1 downto 0):=(others=>'1'); BEGIN
co<='1' when (qcnt=allis1 and ci='1') else '0'; PROCESS (clk,nreset) BEGIN IF(nreset='0') THEN qcnt<=(others=>'0'); ELSIF (clk'EVENT AND clk = '1') THEN if(ci='1') then qcnt<=qcnt+1; end if; END IF; END PROCESS; END behave;
我们可看到,该计数器同第一节中的四位计数器相比,改动不大,其中在实体处增加了一行:
generic(cntwidth:integer:=4);
该行定义了一个整数cntwidth并赋初值‘4‘,用它代替原来的固定的计数器长度,若想设计的计数器位数位8位,仅需将cntwidth的初值赋为8: generic(cntwidth:integer:=8);
若以此计数器为元件,则元件声明为:
Component cntnbits IS generic(cntwidth:integer:=4); PORT
138 — —
(
ci : IN std_logic;
nreset : IN std_logic; clk : IN std_logic; co : out std_logic; qcnt : buffer std_logic_vector(cntwidth-1 downto 0) );
END Component ;
元件例化时按如下格式:
< 例化名>:<实体名,即元件名>
generic map (<实际参数,如确定的总线宽度等>) port map (<端口列表>); 例如,例化为6位计数器:
u1: cntnbits generic map(6) port map(ci,Rd,clk,co,qa); --元件例化
在上述的可变位数计数器中,定义了一个常数“allis1 ”用于产生进位输出信号时的判断。它的值为各位都为‘1‘。此处,用了(others=>'1')赋值。(others=>'1')表示一个集合,集合中各元素用’,‘格开。表示各元素都为’1‘。others必须出现在集合的最后。 例: signal: sa:std_logic_vector(7 downto 0); sa<=(‘1’,’0’,others=>’1’)
其结果是给信号sa赋值“1011 1111 ”。
4.1.10 配置(Configuration)
前面说过,一个实体可用多个结构体描述,在具体综合时选择哪一个结构体来综合,则由配置来确定。即配置语句来安装连接具体设计(元件)到一个实体--结构体对。配置被看作是设计的零件清单, 它描述对每个实体用哪一种行为,所以它非常象一个描述设计每部分用哪一种零件的清单。 配置语句举例:
--这是一个两位相等比较器的例子,它用四种不同描述来实现,即有四个结构体。 ENTITY equ2 IS PORT (a,b : IN std_logic_vector(1 downto 0); equ : OUT std_logic ); END equ2;
--结构体一:用元件例化来实现,即网表形式: ARCHITECTURE netlist OF equ2 IS
139 — —