VHDL 2008 и оператор CASE

У меня есть вопрос об операторе case и VHDL 2008. У меня есть объект, определенный следующим образом:

entity multiplier_v2 is
generic(    WIDTH_WORD  : integer := 32;
            WIDTH_RSA   : integer := 2048;
            LENGTH_ADDRESS : integer := 6 );
port (
    reset                   :   in std_logic;
    clk                     :   in std_logic;
    start                   :   in std_logic;
    input_1                 :   in std_logic_vector(WIDTH_WORD - 1 downto 0);
    input_2                 :   in std_logic_vector(WIDTH_WORD - 1 downto 0);
    module                  :   in std_logic_vector(WIDTH_WORD - 1 downto 0);
    output                  :   out std_logic_vector(WIDTH_WORD - 1 downto 0);
    ack_data                :   out std_logic;
    data_valid              :   out std_logic;
    new_module              :   in std_logic;

Внутри модуля я объявил сигнал следующим образом:

signal counter_ack                  : std_logic_vector(LENGTH_ADDRESS - 1 downto 0);

Я использую этот сигнал в операторе case:

case counter_ack is
when (others => '1') =>
    ack_data <= '0';
when others => 
    counter_ack <= counter_ack + 1;
end case;

Теперь я почти уверен, что опция VHDL-2008 включена в моем инструменте синтеза, но у меня есть следующая ошибка в отношении этой части моего кода:

2049990 ОШИБКА - E:/My_Designs/Custom Module/Montgomery_Multiplier/Diamond/src/multiplier_v2.vhd(456,6-461,15) (VHDL-1544) тип массива case выражение должно иметь локально статический подтип

Я читал, что эта ошибка должна быть исправлена ​​в VHDL-2008. Любые идеи ?


person haster8558    schedule 18.03.2015    source источник
comment
Я не уверен, что это законно в VHDL-2008 (хотя некоторые инструменты могут это принять), поскольку диапазон не ограничен. IMO, вам было бы лучше, если counter_ack = 2**counter_ack'length-1, затем ack_data ‹= '0'; иначе counter_ack ‹= counter_ack + 1; закончить, если;   -  person Jonathan Drolet    schedule 18.03.2015
comment
@JonathanDrolet Спасибо за помощь. На самом деле я не знаю, законно это или нет. Я видел, что на многих форумах это предлагаемое решение. Я могу использовать оператор if, но он отличается с точки зрения синтеза от случая (у меня есть несколько таких случаев в моем исходном коде). Тогда я действительно не понимаю, в чем проблема. Когда я помещаю компонент в исходный код VHDL, синтезатор знает размер сигналов. Это не без ограничений. Тогда почему с If должно быть все в порядке, а с случаем — нет? Может быть, моя вина в том, что я думаю как программист на C.   -  person haster8558    schedule 18.03.2015
comment
VHDL является строго типизированным (в отличие от C) и предназначен для обнаружения как можно большего количества ошибок во время компиляции. Несмотря на то, что совершенно ясно, как следует интерпретировать код, VHDL просит вас написать его явно, на всякий случай. Такие вещи, как неявное приведение типов, существуют в C, но не в VHDL. VHDL-2008 смягчил педантизм, но никогда его не уберет. Моя строка кода if сравнивает std_logic_vector (я предположил, что вы использовали ieee.numeric_std_unsigned) с целым числом, что допустимо, поскольку существует перегруженный оператор сравнения.   -  person Jonathan Drolet    schedule 18.03.2015
comment
@ haster8558 haster8558, если вы используете подобный оператор case, он даст результаты, идентичные оператору if. Вы можете рассмотреть возможность публикации большего количества кода. Как сбросить счетчик? Вы можете считать в обратном порядке до 0.   -  person Jim Lewis    schedule 18.03.2015
comment
Вы можете подумать об ограничении размера выбора. (LENGTH_ADDRESS -1 до 0 => '0')   -  person Jim Lewis    schedule 18.03.2015


Ответы (1)


Я скомпилировал приведенный ниже код в Quartus II с опцией компилятора VHDL 2008. У меня нет ошибки. Ваше заявление по делу находится в процессе?

LIBRARY ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.std_logic_signed.all;

ENTITY casestate IS
generic(    WIDTH_WORD  : integer := 32;
            WIDTH_RSA   : integer := 2048;
            LENGTH_ADDRESS : integer := 6 );
port (
    reset                   :   in std_logic;
    clk                     :   in std_logic;
    ack_data                :   out std_logic
     );
END casestate;

ARCHITECTURE fpga OF casestate IS
    signal counter_ack                  : std_logic_vector(LENGTH_ADDRESS - 1 downto 0);

BEGIN

process(clk,reset)
begin
if(reset = '0')then
    ack_data <= '0';
elsif(rising_edge(clk))then
    case counter_ack is
        when (others => '1') =>
            ack_data <= '0';
        when others => 
            counter_ack <= counter_ack + 1;
            ack_data <= '1';
        end case;
end if;
end process;
end fpga;
person Nicolas Roudel    schedule 18.03.2015
comment
Да, это в процессе. На мой взгляд, Diamond (Lattice Semiconductor IDE) — отстой. У меня тоже нет ошибки с synplify. VHDL-2008 работает плохо. Я могу выбрать инструмент синтеза в Diamond (инструмент синтеза Synplify или Lattice). Первый работает, второй нет. Теперь я предполагаю, что если я хочу использовать логический анализатор Lattice, я не должен использовать VHDL-2008. - person haster8558; 18.03.2015
comment
@Nicolas, пожалуйста, не используйте пакет std_logic_signed. Что вы предлагаете сделать с counter_ack для его сброса? Согласно запрограммированному коду, ваша конструкция должна поддерживать текущее значение counter_ack во время сброса. Это свяжет ваш сигнал сброса с функциональной логикой, что может создать проблемы с глобальной линией сброса. - person Jim Lewis; 18.03.2015
comment
@ Джим, я написал этот код только для проверки, если компилятор выдаст мне ошибку. Мне все равно, имеет ли этот код смысл, но вы правы. - person Nicolas Roudel; 18.03.2015