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

时间:2019-05-02 13:09:33

标签: vhdl ghdl

Verilog允许将case语句的分支定义为其他文件中的常量。示例:

<div class="col-xs col-sm">
  <div class="flex-grid-component">

    <div class="flex-grid">
      <div class="property-item-container">
        <div class="property-details">
          <div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin a malesuada lorem, ut gravida metus. Cras elementum vitae mi a ornare. Curabitur eget congue diam, at dictum ante.
          </div>
        </div>
      </div>
    </div>
    <div class="flex-grid">
      <div class="property-item-container">
        <div class="property-details">
          <div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin a malesuada lorem, ut gravida metus. Cras elementum vitae mi a ornare. Curabitur eget congue diam, at dictum ante.
          </div>
        </div>
      </div>
    </div>
    <div class="flex-grid">
      <div class="property-item-container">
        <div class="property-details">
          <div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin a malesuada lorem, ut gravida metus. Cras elementum vitae mi a ornare. Curabitur eget congue diam, at dictum ante.
          </div>
        </div>
      </div>
    </div>

  </div>
</div>

如何在VHDL中执行相同的操作?我想在程序包中定义我的case常量,并将这些常量拉入当前体系结构,并使用这些常量为case语句定义分支。工作示例:

`define COND1 3'b001
`define COND2 3'b010
`define COND3 3'b100

module xyz(input wire [2:0] select, output reg value);
    always @* 
    case(select)
    `COND1: value = 1'b0;
    `COND2: value = 1'b1;
    `COND3: value = 1'b0;
    default: value = 1'b0;
endmodule

哪个工作还可以...

但是,当我在VHDL代码中尝试时,出现一个奇怪的错误:

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;

以下是给出此错误的代码:

..\simtools\ghdl\bin\ghdl.exe -a stuff2.vhdl
stuff2.vhdl:40:18: choice must be locally static expression   
stuff2.vhdl:41:18: choice must be locally static expression
stuff2.vhdl:42:18: choice must be locally static expression

2 个答案:

答案 0 :(得分:2)

Kevin Kruse的答案取决于-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尚未实现。否则,凯文(Kevin)的答案似乎对完全符合-2008要求的本地静态基数有效。

在较早的修订版中,由于函数n或to_unsigned的返回值,常量值表达式不是局部静态的。

请参见-2002或更早的版本7.4.2全局静态主变量(9.4.3-2008)“ i)一个函数调用,其函数名称表示纯函数,而其实际参数均为全局静态表达式”,其中每个局部静态表达式为也是全局静态的。

-2008的更改在IEEE软件包中添加了称为函数的函数,不允许对其函数的声明或功能进行更改,允许将它们视为本地静态文件,并受软件包源的版权许可条款的控制。

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

architecture rtl of stuff is
    constant CMD1:  natural range 0 to 7 := 0;  -- "000"
    constant CMD2:  natural range 0 to 7 := 1;  -- "001"
    constant CMD3:  natural range 0 to 7 := 2;  -- "010"
    constant CMD4:  natural range 0 to 7 := 3;  -- "011"
    constant CMD5:  natural range 0 to 7 := 4;  -- "100"
    signal sel2:    natural range 0 to 7;  -- locally static subtype
begin
    sel2 <= to_integer(unsigned(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;

但是问题的第一个VHDL示例最紧密地实现了Verilog代码段。

要启用使用固定切片进行解码的sel1全局静态范围的使用,需要sel2的声明为case表达式提供局部静态子类型:

architecture equiv_w_generic_sel1 of stuff is
    constant COND1:  std_logic_vector (2 downto 0) := "000";
    constant COND2:  std_logic_vector (2 downto 0) := "001";
    constant COND3:  std_logic_vector (2 downto 0) := "010";
    signal sel2:     std_logic_vector (2 downto 0);
begin

    sel2 <= sel1(sel2'range);  -- locally static subtype

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

在这里您不会通过使用非本地静态函数调用来使问题更难定义,并且也不需要use子句来提供程序包numeric_std声明的可见性。请注意,COND1,COND2和COND3常量与Verilog代码段一样具有局部静态值表达式。

以上两种架构都可以分析是否指定了ghdl的--std = 08。


请注意,问题中为ghdl显示的命令行未指定VHDL修订版,并且ghdl的默认值为--std = 93c的等效名称,这提供了与Modelsim对标准-1993修订版的实现相匹配的宽松合规性。

答案 1 :(得分:0)

使用函数n会使常量的值不是局部静态的。

如果将n(0, 3)替换为std_logic_vector(to_unsigned(0, 3)),它将起作用。或者,如您已经显示的,将其替换为"000"