VHDL 2008 и 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 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, би било по-добре с if counter_ack = 2**counter_ack'length-1 then ack_data ‹= '0'; иначе counter_ack ‹= counter_ack + 1; край ако;   -  person Jonathan Drolet    schedule 18.03.2015
comment
@JonathanDrolet Благодаря за помощта. Всъщност не знам дали е законно или не. Виждал съм, че в много форуми това е предложено решение. Мога да използвам оператор if, но той е различен по отношение на синтез от case (имам няколко случая като този в моя изходен код). Тогава наистина не разбирам къде е проблема. Когато поставя компонента в моя VHDL източник cose, синтезаторът знае размера на сигналите. Не е неограничено. Тогава защо с If трябва да е добре, а с case не? Може би грешката ми е, че мисля като 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, ако използвате оператор 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 synthesis tool ). Първото работи, второто не. Сега предполагам, че ако искам да използвам логическия анализатор Lattice, не трябва да използвам VHDL-2008. - person haster8558; 18.03.2015
comment
@Nicolas, моля, не използвайте пакета std_logic_signed. Какво предлагате да направите с counter_ack, за да го нулирате? Както е кодирано, вашият дизайн трябва да поддържа counter_ack на текущата му стойност по време на нулиране. Това ще свърже вашия сигнал за нулиране с функционална логика, което може да създаде проблеми WRT линия за глобално нулиране. - person Jim Lewis; 18.03.2015
comment
@Jim Написах този код само за тестване дали компилаторът ми дава грешка. Не ме интересува дали този код има смисъл, но си прав. - person Nicolas Roudel; 18.03.2015