Как установить ветку в выписке из константы?ОШИБКА: выбор должен быть локально статическим выражением - PullRequest
2 голосов
/ 02 мая 2019

Verilog позволяет определять ветви оператора 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?Я хочу, чтобы мои константы для прецедента были определены в пакете и перетянуть эти константы в текущую архитектуру и использовать константы для определения ветвей для оператора 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;

Что работает нормально ...

Однако, когда я пробую это в своем коде VHDL, я получаю странную ошибку:

..\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

Воткод, который дает эту ошибку:

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;

Ответы [ 2 ]

2 голосов
/ 02 мая 2019

Ответ Кевина Крузе зависит от -2008:

9.4.2 Локально-статические основные цвета

Выражение называется локально-статическим тогда и только тогда, когда каждый оператор в выражении обозначаетнеявно определенный оператор или оператор, определенный в одном из пакетов STD_LOGIC_1164, NUMERIC_BIT, NUMERIC_STD, NUMERIC_BIT_UNSIGNED или NUMERIC_STD_UNSIGNED в библиотеке IEEE, и если каждый первичный элемент в выражении является локально статическим первичным первичным, где локально статический первичный элемент определен дляиз следующих:

...
e) Вызов функции, имя функции которой обозначает неявно определенную операцию или операцию, определенную в одном из пакетов STD_LOGIC_1164, NUMERIC_BIT, NUMERIC_STD, NUMERIC_BIT_UNSIGNED илиNUMERIC_STD_UNSIGNED в библиотеке IEEE, фактическими параметрами которой являются каждое локально статическое выражение

, которое еще не реализовано в ghdl-0.36.В противном случае ответ Кевина представляется действительным для полностью -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 тo предоставить локально статический подтип для выражения 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 версии стандарта.
0 голосов
/ 02 мая 2019

Использование вами функции n делает значение констант не локально статическим.

Если вы замените n(0, 3) на std_logic_vector(to_unsigned(0, 3)), это сработает.Или, как вы уже показали, замените его на "000".

...