《VHDL 数字电路设计教程》电工版/第6章:顺序代码

6.1    进程(PROCESS)

    进程(PROCESS)内部的语句是顺序描述语句,其内部经常使用IFWAITCASELOOP语句。PROCESS具有敏感信息列表(sensitivity list),或者使用WAIT语句进行执行条件的判断。当敏感信息列表中的某个信号发生变化时(或者当WAIT语句的条件得到满足时),PROCESS内部的代码就顺序执行一次

    但如果一个信号出现在敏感信号列表中,但没有在PROCESS内部的任何语句中出现,通常编译器会把它忽略掉。

[label:]PROCESS (sensitivity list)
  [VARIABLE name: type [range][ := initial_value;]]
BEGIN
  (顺序执行的代码)
END PROCESS [label];

    其中,变量的声明部分是可选的,且变量的初始值是不可综合的,只是在仿真过程中使用。

    PS:变量只能在顺序代码中使用,相对于信号而言,变量是局部的,所以它的值不能传递到PROCESS、FUNCTION和PROCEDURE的外部。

6.2    信号与变量

信号(SIGNAL) 变量(VARIABLE)
信号可以在PACKAGEENTITYARCHITECTURE中声明,即信号通常是全局的。 变量只能在一段顺序描述代码的内部声明(比如在PROCESS内部进行声明),即变量通常是局部的。
在PROCESS中使用的信号,新的信号值通常只有在整个PROCESS运行完毕以后才开始生效

变量的值无法直接传递到PROCESS外部。如果需要进行变量值的传递,

则必须把值赋给一个信号,然后由该信号将变量的值传递到PROCESS外部。

另一方面,赋予变量的值是立刻生效的,在此后的代码中,此变量将使用新的变量值。

赋值操作符“<= 赋值操作符“:=

6.3    IF语句

    IF/ELSE语句在综合时可能会产生不必要的优先级解码电路,综合工具在处理这类语句时会对其结构进行优化,以避免占用过多的硬件资源。语法结构如下:

扫描二维码关注公众号,回复: 1848500 查看本文章
IF conditions THEN assignments;
ELSIF conditions THEN assignments;
...
ELSE assignments;
END IF;

6.4    WAIT语句

    如果在PROCESS中使用了WAIT语句,就不能再使用敏感信息列表了。

    语法结构有3种:

WAIT UNTIL signal_condition;

    含义:直到信号条件(signal_condition)满足时才进行后面的操作。

    注意:①WAIT UNTIL语句后面只有一个信号条件表达式,更适合于实现同步电路

           ②WAIT UNTIL语句必须是PROCESS中“BEGIN“开始后的第一条语句。当WAIT UNTIL语句的条件满足时,PROCESS内部的代码就执行一遍。

        (同步是指与系统时钟同步。同步复位是指当复位信号有效时,并不立刻生效,而是要等到复位信号有效且系统时钟的有效边沿到达时才会生效。

           异步复位则是立即生效,只要复位信号有效,无论系统时钟是怎样的,系统都会立即被复位。)

          同步时序电路中的时钟问题:第一,在代码中如果在参考时钟的两个边沿(上升沿和下降沿)都可以触发对同一个信号的的赋值操作,那么这样的代码通常是不可综合的;第二,语句“IF(clk'EVENT)”存在二义性,即EVENT属性必须和某个测试条件关联起来,例如“clk'EVENT AND clk = '1' ”等。

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

    含义:当后面列出的信号中有一个发生变化时,开始进行后面的操作(相当于PROCESS的敏感信号列表)。

WAIT FOR time;

    含义:等待time所确定的时间后开始后面的操作,该语句且只能用于仿真是不可综合的

------------带有同步复位端的8位寄存器--------
PROCESS       --没有敏感信号列表
BEGIN
   WAIT UNTIL (clk'EVENT AND clk = '1');
   IF (rst = '1') THEN
      output <= "00000000";
   ELSIF (clk'EVENT AND clk = '1') THEN
      output <= input;
   END IF;
END PROCESS;
------------带有异步复位端的8位寄存器---------
PROCESS
BEGIN
   WAIT ON clk,rst;    --相当于敏感信号列表
   IF (rst = '1') THEN
      output <= "00000000";
   ELSIF (clk'EVENT AND clk = '1') THEN
      output <= input;
   END IF;
END PROCESS;

6.5    CASE语句

    CASE语句也是一种专用于顺序代码中的语句。语法结构如下:

CASE 表达式 IS
   WHEN 条件表达式 => 顺序执行语句;
   WHEN 条件表达式 => 顺序执行语句;
   ...
END CASE;
CASE control IS
   WHEN"00" => x <= a;y <= b;     --when后的多值判断见第5章
   WHEN"01" => x <= b;y <= c;
   WHEN OTHERS => NULL;
END CASE;

    注意:“WHEN OTHERS => NULL”表示在所有未列出的可能情况下没有操作发生。

    另外,CASE语句和WHEN语句(第五章)有些类似,但CASE语句允许在每个测试条件下执行多个赋值操作,而WHEN语句只允许执行一个赋值操作。

6.6    LOOP语句

    LOOP语句也是顺序描述语句,所以只能用于PROCESSFUNCTIONPROCEDURE中,且适用于当一段代码需要多次重复执行的情况。

    1.    FOR/LOOP:循环固定次数

[label:] FOR 循环变量 IN 范围 LOOP   --上下界必须是静态值
   (顺序描述语句)
END LOOP [label];
    2.    WHILE/ LOOP:循环执行直到某个条件不再满足
[label:] WHILE 条件表达式 LOOP
   (顺序描述语句)
END LOOP [label];

    3.    EXIT结束整个循环操作

[label:] EXIT [label] [WHEN条件表达式] ;
    4.    NEXT跳出本次循环

[label:] NEXT [loop_label] [WHEN条件表达式];
    例1
FOR i IN 0 TO data'RANGE LOOP
   CASE data(i) IS
      WHEN '0' => count := count+1;
      WHEN OTHERS => EXIT;          --结束整个LOOP循环
   END CASE;
END LOOP;
    例2
FOR i IN 0 TO 15 LOOP
   NEXT WHEN i=skip;    --跳到下一次循环
      (...)
END LOOP;

    6.7    CASEIF比较

    尽管在原则上IF/ELSE语句中的ELSE的出现可能会造成综合后的电路中出现优先级解码器(CASE语句不会出现这种情况),但实际上由于综合工具的优化功能,IF语句会综合成一个一个多路复用器而不是优先级解码器。因此,用IF语句和CASE语句编写的代码在综合、优化后最终生成的电路结构通常是一样的。

    6.8    CASE与WHEN比较

    比较如下

            

    例    从实现的功能上看 下面的两段代码是等效的

------------------with WHEN-----------------
WITH sel SELECT               --用于并发描述
  x <= a WHEN "000";
       b WHEN "001";
       c WHEN "010";
       UNAFFECTED WHEN OTHERS;
------------------with CASE-----------------
CASE sel IS                   --用于顺序描述
   WHEN "000" =>  x<=a; y<=b;
   WHEN "001" =>  x<=b; y<=a;
   WHEN "010" =>  x<=c; y<=c;
   WHEN OTHERS =>  NULL;
END CASE;

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

    用顺序代码可以实现时序电路和组合逻辑电路。

    如果希望所编写的代码综合出一个组合逻辑电路,那么必须遵守下面的原则:

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

    原则2:确保考虑了输入/输出信号的所有可能组合,即电路的真值表必须在代码中完整地反映出来(实际上对顺序代码和并发代码都有这一要求)。

    





    

猜你喜欢

转载自blog.csdn.net/jackiezhang1993/article/details/79847861
今日推荐