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;
六、 包集元件
1. 包集
经常使用的代码通常以component,function或procedure的形式编写。这些代码被添加到package中,并在最后编译到目标library中。Package中还可以包含TYPE和CONSTANT的定义。语法格式如下: package package_name is (declaration) end package_name;
package body package_name is (function and procedure description) end package_name;] Example6.1 简单的程序包 library ieee;