VHDL, параллельное назначение сигналов неправильно на FPGA, но правильно в Modelsim

Я изменяю множитель, и у меня возникают проблемы с его запуском на FPGA. В Modelsim все симуляции корректны. У меня есть следующее, что дает неправильный результат на FPGA: вне оператора процесса у меня есть следующий параллельный оператор

(Я опустил объявления сигналов)

architecture behavioral of multiplier is
 ...
 ...
begin
       a_argument <=       a1_neg when booth = "110"
                     else  a2_plus when booth = "011"; 

Значение a1_neg и a2_plus предварительно вычисляются в операторе процесса при входе в состояние умножения:

when MULT_SIGNED_MULT =>
               a1_plus(33 downto 0) <= a(31) & a(31) & a;
               a1_neg(33 downto 0) <= not a(31) &  not a(31) &bv_negate(a);
               a2_plus(33 downto 0) <=   a(31) & a & "0";
               a2_neg(33 downto 0)<= not a(31) &bv_negate(a) & "0";

Затем он переходит к этапу, на котором множитель вычисляет новые значения booth, которые влияют на сигнал a_argument.

С другой стороны, когда я не вычисляю значения заранее и напрямую ввожу все в параллельный оператор следующим образом:

a_argument <=      not a(31) &  not a(31) &bv_negate(a)   when booth = "110" 
              else not a(31) &bv_negate(a) & "0"          when booth = "011";

FPGA выдаст правильный результат. Кроме того, Modelsim даст правильный результат независимо от разницы между этими двумя параметрами.

Мне было интересно, почему один вариант дает правильный результат на FPGA, а другой нет.


person holyprinter    schedule 09.06.2015    source источник
comment
Все возможные причины. Возможно гонка. Как ModelSim дает правильный результат? Как работает этот процесс? Комбинаторный? Часы? Что находится в списке чувствительности?   -  person EML    schedule 09.06.2015
comment
a_argument — это защелка, потому что вы не указали условие when others. Вы должны исследовать, как это синтезируется в вашем целевом устройстве. Здесь вам нужен только мультиплексор 2-к-1, поэтому вы можете просто заменить when booth="011" на when others.   -  person Kevin Thibedeau    schedule 09.06.2015
comment
Обратитесь к списку чувствительности вашего процесса, особенно если вы считаете, что синтезированная реализация верна, а ваша симуляция неверна. Ваши фрагменты кода не являются минимальным, полным и проверяемым примером.   -  person    schedule 09.06.2015
comment
Второе присваивание a_argument отличается от первого в случае booth="011" — это a2_neg, а не a2_plus. Действительно ли опубликованный вами код отражает то, что вы тестируете?   -  person user_1818839    schedule 09.06.2015


Ответы (1)


Я думаю, что ваше параллельное утверждение неверно:

a_argument <=       a1_neg when booth = "110"
                     else  a2_plus when booth = "011";

У вас должен быть еще один оператор else, когда boot отличается от «110» и «011». Пример хорошего параллельного оператора:

a_argument <= a1_neg when booth = "110"
              else a2_plus when booth = "011"
              else (others => '0');

Но значение по умолчанию (другие => '0'), возможно, не то, что вам нужно. Возможно, вам действительно нужна защелка, поэтому вам следует поместить назначение a_argument в синхронизируемый процесс, где защелка a_argument выполняется, когда booth отличается от «110» и «011»:

process(clk)
begin
  if rising_edge(clk) then
    if (booth = "110") then
      a_argument <= a1_neg;
    elsif (booth = "011") then
      a_argument <= a2_plus;
    end if;
end
person Samuel    schedule 20.06.2015