VHDL-2008, Easier to use

文章翻译自 VHDL-2008: Easier to use。如有错误,请指出

引言:VHDL-2008中的增强是为了让VHDL用起来更简单。这些(增强)都是对语言的少量添加或对语法的细微更改,但它们将对VHDL的设计产生实质上的影响。

1. 新的条件运算符

在VHDL-2008之前,VHDL的if语句要求的是布尔表达式,如果A和B的类型是std_logic,那我们必须写成:

if A = '1' and B = '1' then
    ...

VHDL-2008引入了一个新的运算符:??,称为条件运算符,可以将一个std_logic类型转为布尔表达式(boolean),‘1’和‘H’表示为TRUE,其余为FALSE(它同样可以将bit转化为boolean)。所以,现在代码可以写成这样:

if ?? A and B then
    ...

或者更简洁,在某些情况下,?? 是可以省略的。if语句就是其中一种情况,所以代码也可以写成这样:

if A and B then
    ...

2. 增强的位字符串(Enhanced bit string literals)

你可能使用string literals作为std_logic_vector或者其他类似的类型的值,例如:

signal count : unsigned(7 downto 0);
...
count <= "00000000"

在VHDL-1987中,string literals实际上提供了一种将向量表示转为二进制的方法。VHDL-1993则引入了二进制、八进制和十六进制位字符串(bit string literals)

count <= B"0000_0000"; -- "_" 仅为了提高可读性
count <= X"00"; -- X是十六进制,O是八进制

VHDL-1993中的一个限制是十六进制的位字符串始终是4 bits的倍数,而八进制位字符串始终是3 bits的倍数。例如,它不能有10位十六进制位字符串,也不能包含0、1或_以外的值。

在VHDL-2008中,位字符串得到了加强:

  • 可以有明确的位宽
  • 可以声明为signed和unsigned类型
  • 可以包含meta-values(‘U’,'X’等)
    例子如下:
variable S : std_logic_vector(5 downto 0);
begin
S := 6x"0f";  -- specify width 6
S := 6x"XF";  -- means "XX1111"
S := 6SX"F";  -- "111111" (sign extension)
S := 6Ux"f";  -- "001111" (zero extension)
S := 6sb"11"; -- "111111" (binary format)
S := 6uO"7";  -- "000111" (octal format)

注意,在位字符串中,允许使用大写或小写字幕,如F和f

3. 层级名称(Hierarchical names)

VHDL-2008中的部分新功能仅用于验证,而不是设计。验证工程师总是希望编写self-checking测试环境,这在VHDL中很难办到,因为没有一个简单的办法从验证环境的顶层直接访问设计层级中的signal和variable。

VHDL-2008通过引入外部名称(external names)来解决此问题。外部名称可能指位于设计层级结构另一部分的(共享)variable、signal或常量。外部名称嵌于双尖括号中<< >>

特殊字符可用于向上移动层级(比如 ^ )或是去到package的根路径(比如@),举个例子:

<< signal .tb.uut.o_n : std_logic >>  -- hierarchical signal name
<< signal ^.^.a : std_logic >>        -- signal a two levels above
<< variable @lib.pack.v : bit >>      -- variable in a package pack

外部名称的其他用途包括在测试环境中注入错误(injecting error)以及forcing or release value(见后文)。

4. 集合中的向量(Vectors in aggregates)

VHDL集合允许将一组单独的数组(array)或元素构成一个值,对于数组,VHDL1076-2002的版本允许语法像下面这样:

variable V : std_logic_vector(7 downto 0);
begin
V := (others => '0');                    -- "00000000"
V := ('1', '0', others => '0');          -- "10000000"
V := (4 => '1', others => '0');          -- "00010000"
V := (3 downto 0 => '0', others => '1'); -- "11110000"
-- V := ("0000", others => '1');         -- illegal!

VHDL-2008允许数组集合中使用切片(slice),即上个例子可以写成这样:(注意第二和第五个赋值的变化)

V := (others => '0');                    -- "00000000"
V := ("10", others => '0');              -- "10000000"
V := (4 => '1', others => '0');          -- "00010000"
V := (3 downto 0 => '0', others => '1'); -- "11110000"
V := ("0000", others => '1');            -- "00001111"

当然,你也可以使用集合作为赋值的目标,比如:

( S(3 downto 0), S(7 downto 4)) <= S;      -- swap nibbles
( 3 downto 0 => S, 7 downto  4 => S) <= S; -- using named association

5. 条件语句和顺序选择语句(Conditional and selected sequential statements)

VHDL语法有两种执行风格:并发执行和顺序执行。你无法对signal使用条件赋值语句如:

z <= x when x > y else y;

VHDL-2008放宽了这个限制,并允许在process中像下面这样生成一个触发器:

process(clock)
begin
  if rising_edge(clock) then
    q <= '0' when reset else d;  -- not allowed in VHDL 2002
  end if;
end process;

它还允许在process中使用selected信号赋值:

process(clock)
begin
  if rising_edge(clock) then
    with s select              -- equivalent to a case statement
      q <= a when "00",
            b when "01",
            c when "10",
            d when "11";
  end if;
end process;

6. generate 的拓展(Extensions to generate)

VHDL-2008使‘generate’语句更加灵活,他现在允许使用‘else’和‘elseif’。此外还有使用case的‘generate’

这使得‘generate’更便于使用。你不必再写成这样:

g1: if mode = 0 generate
    c1 : entity work.comp(rtl1)
        port map (a => a, b => b);
    end generate;
g2: if mode = 1 generate
    c1 : entity work.comp(rtl2)
        port map (a => a, b => b);
    end generate;
g3: if mode = 2 generate
    c1 : entity work.comp(rtl3)
        port map (a => a, b => b);
    end generate;

而是可以写成case…generate

g1: case mode generate
    when 0 =>
        c1 : entity work.comp(rtl1)
            port map (a => a, b => b);
    when 1 =>
        c1 : entity work.comp(rtl2)
            port map (a => a, b => b);
    when 2 =>
        c1 : entity work.comp(rtl3)
            port map (a => a, b => b);
    when others =>

end generate;

或者if…elsif…else generate

g1: if mode = 0 generate
        c1 : entity work.comp(rtl1)
            port map (a => a, b => b);   
    elsif mode = 1 generate
        c1 : entity work.comp(rtl2)
            port map (a => a, b => b);  
    elsif mode = 2 generate
        c1 : entity work.comp(rtl3)
            port map (a => a, b => b);
    else generate

end generate;

注意,在每个分支中,你可以声明不与其他分支名称冲突本地名称(比如上面的c1),且仍可以用 begin-end 在分支中声明本地对象。when others和else generate分支可以是空的(不做任何事)或是像其他分支一样包含语句。

7. 简化的敏感信号列(Simplified sensitivity lists.)

当关键词‘all’被用于灵敏度的上下文中,便意味着process中的所有signals都被添加到了sensitivity list中,如:

process(all)
begin
    case state is
        when idle =>
            if in1 then
                nextState <= Go1;
            end if;
        when Go1 =>
            nextState <= Go2;
        when Go2 =>
            nextState <= Idle;
    end case;
end process;

这避免了作者在修改组合逻辑的process后忘记更新sensitivity list,从而导致模拟/合成不匹配的常见问题

8. 在std_logic_vector上做算术运算(Arithmetic on std_logic_vector)

VHDL有一个写的很好的package:IEEE.Numeric_std,里面创建了两种新的数据类型:unsigned和signed。然而,有时直接对 std_logic_vector 进行算术运算会更方便——将其视为二进制补码或无符号数。

在之前这主要通过两个非标准的包(std_logic_unsigned和std_logic_signed)来实现。而VHDL-2008通过添加两个新的标准算数包IEEEN.Numeric_std_Unsigned和IEEE.Numeric_std_signed来实现。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值