vhdl 语法总结 4

四、        顺序代码

在PROCESS, , PROCEDURE内部的代码都是顺序执行的,这样的语句包括IF,WAIT,CASE和LOOP。变量只能在顺序代码中使用,相对于信号而言,变量是局部的,所以它的值不能传递到PROCESS,和PROCEDURE的外部。

1.      进程(PROCESS)

进程内部经常使用IF,WAIT,CASE或LOOP语句。PROCESS具有敏感信号列表(sensitivity list),或者使用WAIT语句进行执行条件的判断。PROCESS必须包含在主代码段中,当敏感信号列表中的某个信号发生变化时(或者当WAIT语句的条件得到满足时),PROCESS内部的代码就顺序执行一次。语法结构如下:

[label: ] PROCESS (sensitivity list)

       [VARIABLE name type [range] [ := initial_value; ]]

BEGIN

       (顺序执行的代码)

END PROCESS [label];

如果要在PROCESS内部使用变量,则必须在关键字BEGIN之前的变量声明部分对其进行定义。变量的初始值是不可综合的,只用于仿真。在设计同步电路时,要对某些信号边沿的跳变进行监视(时钟的上升沿或下降沿)。通常使用EVENT属性来监视一个信号是否发生了变化。

2.      信号和变量

信号可在PACKAGE,ENTITY和ARCHITECTURE中声明,而变量只能在一段顺序描述代码的内部声明。因此,信号通常是全局的,变量通常是局部的。赋予变量的值是立刻生效的,在后续的代码中,此变量将使用新的变量值,而信号的值通常只有在整个PROCESS执行完毕后才开始生效。

3.      IF语句

IF/ELSE语句在综合时可能会产生不必要的优先级解码电路。IF语句语法结构如下:

IF conditions THEN assignments;

ELSIF conditions THEN assignments;

ELSE assignments;

END IF;

————————————————————————————————

例:

IF (x < y) temp := “1111_1111”;

ELSIF (x = y AND w = ‘0’) THEN temp := “1111_0000”;

ELSE temp := (OTHERS => ‘0’);

4.      WAIT语句

如果在process中使用了WAIT语句,就不能使用敏感信号列表了。WAIT语句使用以下3种形式的语法结构:

WAIT UNTIL signal_condition;

WAIT ON signal1 [, signal2, ...];

WAIT FOR time;

WAIT UNTIL 后面只有一个信号条件表达式,更适合于实现同步电路(将时钟的上升沿或下降沿作为条件),由于没有敏感信号列表,所以它必须是process的第一条语句。当WAIT UNTIL语句的条件满足是,process内部的代码就执行一遍。

–带有同步复位的8bit寄存器

process –没有敏感信号列表

begin

       wait until (clk’event and clk = ‘1′);

       if (rst = ‘1′) then

              output <= (others => ‘0′);

       elsif (clk’event and clk = ‘1′) then

              output <= input;

       end if;

end process;

WAIT ON 语句中可以出现多个信号,只要信号列表中的任何一个发生变化,process内的代码就开始执行。

–带异步复位的8bit寄存器

process

begin

       wait on clk, rst;

       if (rst = ‘1′) then

              output <= (others => ‘0′);

       elsif (clk’event and clk = ‘1′) then

              output <= input;

       end if;

end process;

WAIT FOR 语句只能用于仿真。

 

5.      CASE 语句

CASE语句的语法结构如下:

CASE 表达式 IS

       WHEN 条件表达式 => 顺序执行语句;

       WHEN 条件表达式 => 顺序执行语句;

       ……

END CASE

例:

case control is

       when “00″      =>   x <= a; y <= b;

       when “01″      =>   x <= b; y <= c;

       when others =>     x <= “0000″; y <= “zzzz”;

end case;

关键词OTHERS代表了所有未列出的可能情况,与Verilog中default相当。关键词NULL表示没有操作发生,如WHEN OTHERS => NULL.

CASE语句允许在每个测试条件下执行多个赋值操作,WHEN语句只允许执行一个赋值操作。

6.      LOOP语句

LOOP语句用在需要多次重复执行时。语法结构有以下几种:

FOR/LOOP: 循环固定次数

[label: ] FOR 循环变量 IN 范围 LOOP

       (顺序描述语句)

END LOOP [label];

WHILE/LOOP: 循环执行直到某个条件不再满足

[label: ] WHILE condition LOOP

       (顺序描述语句)

END LOOP [label];

EXIT: 结束整个循环操作

[label: ] EXIT  [label] [WHEN condition];

NEXT: 跳出本次循环

[label: ] NEXT [loop_label] [WHEN condition];

 

Example: FOR/LOOP

for i in 0 to 5 loop

       x(i) <= enable and w(i+2);

       y(0, i) <= w(i);

end loop

Example: WHILE/LOOP

while (i < 10) loop — 0~9

       wait until clk’event and clk = ‘1′;

       (其他语句)

end loop;

 

for i in 0 to data’range loop

       case data(i) is

              when ‘0′ =>  count := count + 1;

              when others => null;

       end case;

end loop;

7.      CASE语句和IF语句的比较

IF语句和CASE语句编写的代码在综合、优化后最终生成的电路结构是一样的。

例:下面两段代码综合后可以得到结构相同的多路复用器

————with IF————–

if    (sel = “00″)  then x <= a;

elsif (sel = “01″)  then x <= b;

elsif (sel = “10″)  then x <= c;

else x <= d;

end if;

————-with case———–

case sel is

       when “00″ =>     x <= a;

       when “01″ =>     x <= b;

       when “10″ =>     x <= c;

       when others =>  x <= d;

end case;

8.      CASE语句和WHEN语句的比较

case语句和when语句的不同之处在于,when语句是并发执行的,case语句是顺序实行的。

–下面两段代码的功能等效

——-with when——————

with sel select

       x <= a when “000″,

               b when “001″,

               c when “101″,

               unaffected when others;

——-with case——————

case sel is

       when “000″ => x <= a;

       when “001″ => x <= b;

       when “101″ => x <= c;

       when others => null;

end case;

9.      使用顺序代码设计组合逻辑电路

原则1:确保在process中用到的所有输入信号都出现在敏感信号列表中;

原则2:电路的真值表必须在代码中完整的反映出来。(否则会生成锁存器)

 

五、        信号和变量

常量和信号是全局的,既可以用在顺序执行的代码中,也可用在并发执行的代码中。变量是局部的,只能用在顺序代码中,并且它们的值是不能直接向外传递的。

1.       常量

CONSTANT name: type := value;

2.       信号-signal

VHDL中的signal代表的是逻辑电路中的“硬”连线,既可用于电路的输入/输出端口,也可用于电路内部各单元之间的连接。Entity的所有端口默认为signal。格式如下:

SIGNAL name: type [range] [:= initial value];

当信号用在顺序描述语句中时,其值不是立刻更新的,信号值是在相应的进程、函数或过程完成之后才进行更新的。对信号赋初值的操作时不可综合的。

3.      变量

变量仅用于局部电路的描述,只能在顺序执行的代码中使用,而且对它的赋值是立即生效的,所以新的值可在下一行代码中立即使用。格式:

VARIABLE name: type [range] [:= initial value];

对变量的赋初值操作也是不可综合的。

4.      寄存器的数量

当一个信号的赋值是以另一个信号的跳变为条件时,或者说当发生同步赋值时,该信号经过编译后就会生成寄存器。如果一个变量是在一个信号跳变时被赋值的,并且该值最终又被赋给了另外的信号,则综合后就会生成寄存器。如果一个信号在还没有进行赋值操作时已被使用,那么也会在综合时生成寄存器。

process (clk)

begin

       if (clk’event and clk = ‘1′) then

              output1 <= temp;       – output1被寄存

              output2 <= a;            – output2被寄存

       end if;

end process;

 

process (clk)

begin

       if (clk’event and clk = ‘1′) then

              output1 <= temp;       – output1被寄存

       end if;

       output2 <= a;     – output2未被寄存

end process;

 

process (clk)

       variable temp:     bit;

begin

       if (clk’event and clk = ‘1′) then

              temp <= a;

       end if;

       x <= temp;   – temp促使x被寄存

end process;

 

posted @ 2013-03-15 16:19  feitian629  阅读(1445)  评论(0编辑  收藏  举报