VHDL:项目数组只能是'0'或'1',而不能用于case语句中的'X','L','H'或'U'?

时间:2019-08-15 14:49:23

标签: vhdl

VHDL中是否有一种数据类型,该数据类型类似于“ std_logic_vector”这样的数组,但并非全部具有9种可能的状态:

'U': uninitialized. This signal hasn't been set yet. 
'X': unknown. Impossible to determine this value/result. 
'0': logic 0 
'1': logic 1 
'Z': High Impedance 
'W': Weak signal, can't tell if it should be 0 or 1. 
'L': Weak signal that should probably go to 0 
'H': Weak signal that should probably go to 1 
'-': Don't care. 

只有两种可能的状态:

'0': logic 0 
'1': logic 1 

之所以这样问,是因为我正在寻找相当于verilog case语句的VHDL。 Verilog示例:

module m1(input a, input b, output reg[7:0] q);
wire [1:0] sel = {a, b};
always @* begin
    case(sel)
    2'b00: q = 8'd1;
    2'b01: q = 8'd2;
    2'b10: q = 8'd3;
    2'b11: q = 8'd4;
    endcase
end 
endmodule

在VHDL中,我可以毫无问题地做到这一点:

entity m1 is
    port(
        a :in std_logic;
        b :in std_logic;
        q :out std_logic_vector(7 downto 0)
    );
end entity;
architecture rtl of m1 is
    signal sel :std_logic_vector(1 downto 0);
begin
    sel <= a & b;

    process(sel)
    begin
        case sel is
        when "00" => q <= 1;
        when "01" => q <= 2;
        when "10" => q <= 3;
        when "11" => q <= 4;
        end case;
   end process;

end architecture;

此问题是Xilinx ISE和Modelsim都拒绝编译此代码,因为我没有涵盖“ X”,“ U”,“ L”,“ H”等状态。 所以我需要添加一个“当其他人=> q <='X';时”向我的VHDL声明。...

然后,当我用Vivado编译代码时,它说:“警告:即使涵盖了全部情况,您还是有默认情况。”所以我删除了案件的“ when others =>”子句...

好吧,这很烦人……有没有办法让它在每种工具中都能工作,而又不产生错误消息或虚假警告消息?

我的想法是只使用像整数一样只能为“ 0”或“ 1”的数组类型……但更像是std_logic_vector,而不支持所有其他弄乱case select并要求“当其他人=>”子句。...

可能吗?是否有这样的VHDL数据类型已经内置?仅包含“ 0”或“ 1”的数组,没有其他内容专门用于共同催化并用作案例选择吗?整数类型没有'U'或'X',但是完全可以在VHDL情况下使用...我想知道对于('0','1')数组类型是否同样适用?

3 个答案:

答案 0 :(得分:1)

您应该坚持使用SELECT CASE WHEN '1' = '1 ' THEN 'yes' ELSE 'no' END -- results in yes std_logic,另一则帖子提出了不同之处:When to use STD_LOGIC over BIT in VHDL

我认为您的问题也来自将std_logic_vector放入integer的事实。您应该使用转换功能:

  • std_logic_vector
  • to_unsigned(arg: natural, size: natural) return unsigned

哪个会引导您:

std_logic_vector(arg: signed or unsigned) return std_logic_vector

答案 1 :(得分:0)

尝试使用包装标准中的VHDL预定义类型:

type bit is ('0', '1');
type bit_vector is array (natural range <>) of bit;

funciton to_stdlogicvector (b :bit_vector)  return std_logic_vector;
function to_bitvector      (s :std_ulogic_vector) return bit_vector;
architecture rtl of m1 is
    signal sel :std_logic_vector(1 downto 0);
    signal bv  :bit_vector(1 downto 0);
begin
    sel <= a & b;
    bv  <= to_bitvector(sel);

    process(bv)
    begin
        case bv is
        when "00" => q <= 1;
        when "01" => q <= 2;
        when "10" => q <= 3;
        when "11" => q <= 4;
        end case;
   end process;

end architecture;

答案 2 :(得分:0)

Vivado在案例陈述中对其他选择的警告仅仅是警告。另一个选择作为最后的唯一选择即使未涵盖任何情况也始终有效-即使其他情况的选择涵盖sel的所有值也是合法的(请参阅IEEE Std 1076-2008 10.9 Case statement,其他选择的规则在该标准的所有修订版中都是相同的。

如果由于Vivado将案例声明映射到Verilog案例声明规则而感到烦恼,则有两个选择。

您可以在BIT / BITVECTOR中完成所有操作:

-- VHDL -2008 supports bit string literals of base d (decimal)
entity m1 is
    port (
        a:  in  bit;
        b:  in  bit;
        q:  out bit_vector(7 downto 0)
    );
end entity;

architecture foo of m1 is
    signal sel: bit_vector (1 downto 0);
begin
    sel <= (a, b);  -- an aggregate, the type taken from context
    process (sel)
    begin
        case sel is
            when 2b"00" => q <= 8d"1";  -- where the decimal bit string literal
            when 2b"01" => q <= 8d"2";  -- length 8 is converted to an
            when 2b"10" => q <= 8d"3";  -- equivalent bit string with the type
            when 2b"11" => q <= 8d"4";  -- taken from context (q)
        end case;
    end process;
end architecture;

在显示与Verilog等价的基2个位字符串字面量的情况下,位字符串字面量告诉使用"00"的类型的规则等效于'2b“ 00”。位字符串长度前缀仅在-2008中可用。

此示例取决于VHDL -2008,该版本包括对基于十进制的位字符串的支持,这些字符串保留为“ 0”。对于不带前缀长度的VHDL标准的较早版本,分配给q的表达式将需要类似于air78所示的内容,此处使用IEEE软件包numeric_bit而不是numeric_std:

library ieee;
use ieee.numeric_bit.all;

entity m1 is
    port (
        a:  in  bit;
        b:  in  bit;
        q:  out bit_vector(7 downto 0)
    );
end entity;

architecture foo of m1 is
    signal sel: bit_vector (1 downto 0);
begin
    sel <= (a, b);  -- an aggregate, the type taken from context
    process (sel)
    begin
        case sel is
            when "00" => q <= bit_vector(to_unsigned(1, q'length)); 
            when "01" => q <= bit_vector(to_unsigned(2, q'length));
            when "10" => q <= bit_vector(to_unsigned(3, q'length));
            when "11" => q <= bit_vector(to_unsigned(4, q'length));
        end case;
    end process;
end architecture;

(您可以看到我们有一些Verilog爱好者正在进入-2008的VHDL标准化过程。)

第二种方法是仅使sel依赖于BIT的元素类型:

library ieee;
use ieee.std_logic_1164.all;

entity m1 is
    port (
        a:  in  std_logic;
        b:  in  std_logic;
        q:  out std_logic_vector(7 downto 0)
    );
end entity;

architecture foo of m1 is
    signal sel: bit_vector (1 downto 0);
begin
    sel <= to_bitvector((a, b));  -- an aggregate, the type taken from context
    process (sel)
    begin 
        case sel is
            when 2b"00" => q <= 8d"1";  -- where the decimal bit string literal
            when 2b"01" => q <= 8d"2";  -- length 8 is converted to an 
            when 2b"10" => q <= 8d"3";  -- equivalent bit string with the type
            when 2b"11" => q <= 8d"4";  -- taken from context (q)
        end case;
    end process;
end architecture;

To_bitvector在IEEE std_logic_1164程序包中定义。可以删除相同的扭曲以消除-2008依赖项。

请注意,自用户指南901 Synthesis,2018.3起,Vivado不声称支持基于十进制的位字符串文字或具有前缀长度的文字-请参阅支持的VHDL-2008功能。从警告中可以看出,Vivado也不适当地支持VHDL案例声明。

您的问题不在于VHDL语言,而是在于Vivado的支持。您可能还会注意到-2008长度定义的位字符串文字可与std_logic_vector一起使用。位字符串文字的类型由上下文决定(请参阅IEEE Std 1076-2008 15.8位字符串文字,5。类型,9.3.2文字和12.5重载解析的上下文)。

支持长度定义的位字符串可能会干扰某些工具供应商的历史性做法,即不需要在相邻的抽象文字和标识符词法元素之间使用分隔符(如10ns中那样,其中物理文字不是词法元素,请参阅5.2.4。物理类型,15.3词法元素,分隔符和定界符“在标识符或抽象文字与相邻的标识符或抽象文字之间至少需要一个分隔符。”在标准的每次修订中都要求;-)。

-2008标准将表达式to_bitvector(a,b)定义为具有局部静态范围

10.9案例说明

  

对于普通case语句或匹配的case语句,如果表达式是BIT类型或元素类型为BIT的数组类型,则该表达式为对象的名称,其子类型为局部静态,标量类型或数组类型,则子类型的每个值在case语句的选择集中将只被表示一次,并且不允许其他值;如果表达式是限定表达式或类型转换,其类型标记表示局部静态子类型,或者该表达式是对函数的调用,而该函数的返回类型标记表示局部静态子类型,或者表达式是该段中描述的并且用括号括起来的表达式。

9.4.2局部静态原语

  

局部静态范围是边界为局部静态表达式的第二种形式的范围(请参阅5.2.1),或者是其前缀表示局部静态子类型或形式为a的对象的第一种形式的范围。局部静态子类型。 ...

其中局部静态范围由聚合((a, b),另请参见9.3.3.3数组聚合)中固有的基本操作(5.1)定义

architecture fum of m2 is
begin
    process (a, b)
    begin 
        case To_bitvector((a,b)) is
            when 2b"00" => q <= 8d"1";  -- where the decimal bit string literal
            when 2b"01" => q <= 8d"2";  -- length 8 is converted to an 
            when 2b"10" => q <= 8d"3";  -- equivalent bit string with the type
            when 2b"11" => q <= 8d"4";  -- taken from context (q)
        end case;
    end process;
    process (q)
    begin
        report "a = " & std_ulogic'image(a) &
               "b = " & std_ulogic'image(a) & 
               ", q = " & to_string(q);
    end process;
end architecture;

-2008 VHDL可以取消“ {wire} sel”。

根据《用户指南901综合》第6章支持的VHDL-2008功能,尚不清楚Vivado是否支持-2008案例表达式(支持匹配的案例语句)。尝试使用指定长度的十进制位文字和聚合提供的本地静态子类型都是很有启发性的。