Операция VHDL arithmati c между нефиксированным номером с фиксированной точкой (с префиксом) и номером без знака - PullRequest
1 голос
/ 06 февраля 2020

Я хотел бы выполнить некоторую арифметическую c операцию между числом без знака и номером без знака с фиксированной точкой в ​​VHDL:

signal A : ufixed(11 downto -8);
signal B : unsigned(11 downto 0);
signal C : ufixed(A'range);

Каков наилучший способ выполнения операции арифметии c в целочисленных частях что-то вроде этого:

C <= A - B;

Я не смог найти никакой информации о преобразовании unsigned в ufixed при сохранении того же "значения". Нужно ли конвертировать B в std_logic_vector, pad 0s и использовать процедуру to_ufixed()?

Есть ли какой-нибудь вменяемый способ выполнения операций такого типа? Спасибо за любые предложения!

Обновление: добавьте минимальный пример

Я пробовал оба предложения, используя GHDL, но все еще получал ошибку, говорящую: ошибка связанной проверки в (операция присваивания) line.

К сожалению, мне все еще не удается заставить модели работать в моей системе Linux.

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.fixed_pkg.all;

entity sub is
  port (
    A : in ufixed (11 downto -8);
    B : in unsigned (11 downto 0);
    C : out ufixed (11 downto -8));
end entity;

architecture RTL of sub is
begin
  -- C <= A - to_ufixed(B, 11, -8);
  C <= A - ufixed(B);
end architecture;

Файл тестового стенда:

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.fixed_pkg.all;

entity sub_tb is
end entity sub_tb;

architecture sim of sub_tb is
  -- component ports
  signal A : ufixed (11 downto -8)  := (others => '0');
  signal B : unsigned (11 downto 0) := (others => '0');
  signal C : ufixed (11 downto -8);

begin  -- architecture sim

  -- component instantiation
  DUT: entity work.sub
    port map (
      A => A,
      B => B,
      C => C);

  -- waveform generation
  WaveGen_Proc: process
  begin
    A <= "00000000111110000000";
    B <= "000000000000";
    wait for 100 ns;
    B <= "000000000001";
    wait for 100 ns;
    B <= "000000001110";

  end process WaveGen_Proc;

end architecture sim;

ghdl -r --std=08 sub_tb
./sub_tb:error: bound check failure at sub_tb.vhdl:16
./sub_tb:error: simulation failed

Ответы [ 2 ]

1 голос
/ 06 февраля 2020

Ответ Мэтью Тейлора верен, однако вам также придется объявить C по-другому.

При добавлении двух чисел с фиксированной точкой одинакового размера результат будет на 1 бит больше в целочисленной части.

Следовательно, C должен быть объявлен как:

signal C : ufixed(12 downto -8);

Если вам случится знать, что величина ваших значений останется ниже 12 бит, или если вы хотите для насыщения вы можете использовать функцию resize с фиксированной точкой, которая описана в руководстве пользователя.

Чтобы узнать больше о том, как работает пакет с фиксированной точкой, вам нужно прочитать руководство пользователя с фиксированным пакетом. Его можно найти здесь . Там есть таблица, в которой показано, как рассчитать размер результатов с арифметикой с фиксированной точкой c на основе размеров операндов (это на второй странице).

1 голос
/ 06 февраля 2020

В пакете fixed_pkg есть функция to_ufixed:

  function to_ufixed (
    arg                     : UNRESOLVED_UNSIGNED;             -- unsigned
    constant left_index     : INTEGER;  -- left index (high index)
    constant right_index    : INTEGER                   := 0;  -- right index
    constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
    constant round_style    : fixed_round_style_type    := fixed_round_style)
    return UNRESOLVED_ufixed;

Итак, как насчет:

C <= A - to_ufixed(B, 11, -8);
...