VHDL: используйте инструкцию WHEN-ELSE с переменными

Проблема
Я пишу функцию в пакете, которая преобразует некоторые значения для тестового стенда. Я хочу проверить, превышает ли выход максимальное значение, если это так, я хочу установить его на это максимальное значение. Что меня утомило, так это следующее:

  -- vec_in: 0...1023, returns -14...23.5 dB
  function conv_dac602_scale (
    vec_in : std_logic_vector)
    return real is
    variable val_in, dB : real := 0.0;
    constant lower : real := -14.0;
    constant upper : real := 23.5;
  begin  -- function conv_dac602_scale
    val_in := real(to_integer(unsigned(vec_in)));
    dB := (lower+(val_in*((upper-lower)/1024.0)));
    return dB when dB <= upper else upper;  -- this is the important line! (129)
  end function conv_dac602_scale;

Когда я пытаюсь скомпилировать это, я получаю следующие ошибки:

** Error: myfile.vhd(129): near "when": expecting ';'
** Error: myfile.vhd(260): VHDL Compiler exiting

Затем я попытался сначала присвоить его переменной r:

  ...
    r := dB when dB <= upper else upper;  -- this is the important line! (129)
    return r;
  end function conv_dac602_scale;

Что не изменило исход. Я знаю, что вместо этого я могу использовать простое предложение if/else, но мой вопрос в том, почему я не могу использовать предложение when.

Система
Modelsim SE 10.0b, VHDL 2008


person youR.Fate    schedule 13.03.2014    source источник


Ответы (2)


target <= signal when x — это так называемый параллельный оператор, который предназначен для простого создания назначений сигналов вне процесса. Вы можете использовать его внутри архитектуры, но не внутри процесса. If и else предназначены для последовательных операторов внутри процесса. В вашем случае вам придется использовать if/else.

Изменить: похоже, это верно только для Vhdl до 2008 года. Как указывает fru1tbat, это действительный код vhdl 2008, и проблема заключается в том, что компилятор Modelsim не поддерживает функцию.

person MatthiasB    schedule 13.03.2014
comment
В VHDL-2008 одновременные назначения разрешены в последовательных процессах. Проблема может заключаться в том, что ModelSim 10.0b не поддерживает эту конструкцию (у меня нет под рукой 10.0b, но 10.1 прекрасно ее компилирует). - person fru1tbat; 13.03.2014
comment
Не знал этого. Я должен посмотреть это, звучит аккуратно, чтобы использовать для некоторых случаев :) - person MatthiasB; 13.03.2014
comment
@ fru1tbat Надо будет попробовать с aldec. - person youR.Fate; 14.03.2014
comment
Я должен уточнить, что он компилируется с корректировкой, которую вы сделали, когда сначала присвоили переменной. Вы все равно не можете вернуть... когда... иначе. - person fru1tbat; 14.03.2014

Я бы еще раз подумал об изменении того, как вы вызываете свой возврат, так как похоже, что ваш синтаксис с использованием WHEN неверен.

Уточните, что вы пытаетесь сделать:

return dB when dB <= upper else upper;

По сути, это «возврат dB, когда dB меньше или равен upper, иначе выше», где upper не будет возвращено из-за того, как вы делаете оператор возврата. Вы можете сказать: ... else return upper

В этом случае я бы предпочел оператор if:

if ( dB <= upper) then
     return dB;
else
     return upper;
end if;
person Signus    schedule 13.03.2014
comment
Как это ничего не делает? По сути, это предел возврата, если значение больше предела, что кажется мне совершенно разумным (помимо проблемы с использованием его с возвратом в первую очередь). - person fru1tbat; 14.03.2014
comment
Он не вернет upper из-за того, как он делает оператор return. - person Signus; 14.03.2014
comment
Извините, я истолковал ваше утверждение как сомнение в идее, а не в синтаксисе. Концептуально это совершенно правильно. - person fru1tbat; 14.03.2014
comment
Не волнуйтесь. Я уточню это в своем ответе. Спасибо! - person Signus; 14.03.2014