Vhdl 如何从常量设置case语句中的分支?错误:选项必须是本地静态表达式

Vhdl 如何从常量设置case语句中的分支?错误:选项必须是本地静态表达式,vhdl,ghdl,Vhdl,Ghdl,Verilog允许将case语句的分支定义为不同文件中的常量。例如: `define COND1 3'b001 `定义条件2 3'b010 `定义COND3 3'b100 模块xyz(输入线[2:0]选择,输出reg值); 始终@* 案例(精选) `条件1:值=1'b0; `条件2:值=1'b1; `条件3:值=1'b0; 默认值:值=1'b0; 端模 如何在VHDL中实现同样的功能?我希望在包中定义case的常量,并将这些常量拉入当前体系结构,并使用这些常量定义case语句的分支。工作示例:

Verilog允许将case语句的分支定义为不同文件中的常量。例如:

`define COND1 3'b001
`定义条件2 3'b010
`定义COND3 3'b100
模块xyz(输入线[2:0]选择,输出reg值);
始终@*
案例(精选)
`条件1:值=1'b0;
`条件2:值=1'b1;
`条件3:值=1'b0;
默认值:值=1'b0;
端模
如何在VHDL中实现同样的功能?我希望在包中定义case的常量,并将这些常量拉入当前体系结构,并使用这些常量定义case语句的分支。工作示例:

library ieee;
use ieee.std_logic_1164.all;

entity stuff is
   port(
       sel1: in std_logic_vector(2 downto 0);
       val1:  out std_logic
   );
end entity;

architecture rtl of stuff is
    constant COND1 : std_logic_vector(2 downto 0) := "001";
    constant COND2 : std_logic_vector(2 downto 0) := "010";
    constant COND3 : std_logic_vector(2 downto 0) := "100";
begin

    process(sel1) 
    begin 
        case sel1 is
        when COND1 => val1 <= '0';
        when COND2 => val1 <= '1';
        when COND3 => val1 <= '0';
        when others => val1 <= '0';
        end case;
    end process;

end architecture;
以下是导致此错误的代码:

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity stuff is

    generic(
        CW : integer := 3
    );
    port(    
        sel1 : in    std_logic_vector(CW-1 downto 0);
        val1 : out   std_logic
    );

end entity;

architecture rtl of stuff is

    function n(n_value:integer; n_width:integer) 
        return std_logic_vector is
    begin
        return std_logic_vector(to_unsigned(n_value, n_width));
    end function;

    constant CMD1 : std_logic_vector(2 downto 0) := n(0, 3);
    constant CMD2 : std_logic_vector(2 downto 0) := n(1, 3);
    constant CMD3 : std_logic_vector(2 downto 0) := n(2, 3);
    constant CMD4 : std_logic_vector(2 downto 0) := n(3, 3);
    constant CMD5 : std_logic_vector(2 downto 0) := n(4, 3);

    signal sel2 : std_logic_vector(2 downto 0);

begin

    sel2 <= sel1(2 downto 0);

    process(sel2)
    begin
        case sel2 is
            when CMD1   => val1 <= '0';     
            when CMD2   => val1 <= '1';     
            when CMD3   => val1 <= '0';     
            when others => val1 <= '0';     
        end case;
    end process;

end architecture;
ieee库;
使用ieee.std_logic_1164.all;
使用ieee.numeric_std.all;
实体的东西是
一般的(
CW:整数:=3
);
港口(
sel1:标准逻辑向量(CW-1向下至0);
val1:输出标准逻辑
);
终端实体;
stuff的体系结构rtl是
函数n(n_值:整数;n_宽度:整数)
返回标准逻辑向量为
开始
返回标准逻辑向量(到无符号(n值,n宽度));
末端功能;
常数CMD1:std_逻辑_向量(2到0):=n(0,3);
常数CMD2:std_逻辑_向量(2到0):=n(1,3);
常数CMD3:std_逻辑_向量(2到0):=n(2,3);
常数CMD4:std_逻辑_向量(2到0):=n(3,3);
常数CMD5:std_逻辑_向量(2到0):=n(4,3);
信号sel2:标准逻辑向量(2到0);
开始

sel2 val1 val1 val1 val1使用函数
n
使常数的值不是局部静态的


如果将
n(0,3)
替换为
std_逻辑_向量(to_unsigned(0,3))
它会工作。或者,如您所示,将其替换为
“000”

凯文·克鲁斯的答案取决于-2008:

9.4.2局部静态基色

当且仅当表达式中的每个运算符表示隐式定义的运算符或库IEEE中STD_LOGIC_1164、NUMERIC_BIT、NUMERIC_STD、NUMERIC_BIT_UNSIGNED或NUMERIC_STD_UNSIGNED包之一中定义的运算符时,表达式称为局部静态表达式,如果表达式中的每个主项都是本地静态主项,则本地静态主项定义为以下内容之一:


e) 一种函数调用,其函数名表示一个隐式定义的操作或在库IEEE中的STD_LOGIC_1164、NUMERIC_BIT、NUMERIC_STD、NUMERIC_BIT_UNSIGNED或NUMERIC_STD_UNSIGNED包之一中定义的操作,其实际参数均为本地静态表达式

自ghdl-0.36起尚未实施。否则,凯文的答案似乎适用于完全符合2008年的地方静态初选

在早期版本中,由于函数n的返回值或函数u的无符号,常量值表达式不是局部静态的

参见-2002或更早版本7.4.2全局静态基本(9.4.3-2008)“i)函数名表示纯函数且实际参数为全局静态表达式的函数调用”,其中每个局部静态表达式也是全局静态的

在IEEE包中添加被调用函数的-2008更改不允许对其函数声明或功能进行更改,允许将其视为本地静态函数,并受包源的版权许可条款控制

对于-2008或更早版本的标准的不兼容实施,可以定义CMD1-4的数值,并将sel(2向下转换为0)转换为本地静态整数子类型值:

东西的架构rtl是
常数CMD1:自然范围0到7:=0;--"000"
常数CMD2:自然范围0到7:=1;--"001"
常数CMD3:自然范围0到7:=2;--"010"
常数CMD4:自然范围0到7:=3;--"011"
常数CMD5:自然范围0到7:=4;--"100"
信号sel2:自然范围0至7;——局部静态子类型
开始
sel2 val1 val1 val1 val1 val1 val1 val1 val1 val1 val1 val1