Использовать строку как член множества в метапрограммировании VHDL - PullRequest
0 голосов
/ 13 февраля 2020

Я пишу обобщенный c множитель в VHDL, который должен быть способен создавать экземпляры для обработки любой комбинации факторов со знаком и без знака.

Насколько я понимаю, для того, чтобы сделать все 4 комбинаций умножения со знаком и без знака из единой сущности generi c, и поскольку нет типа / порта данных, который мог бы принимать значения как со знаком, так и без знака (без полиморфизма), мне нужно будет передать оба фактора как std_logic_vectors и преобразовать их как подписанный или неподписанный в зависимости от их подписи.

Чтобы скормить моему generic_multiplier подпись моих факторов, поскольку подпись является stati c, я решил передать в строках "подписанный" или "неподписанный" как обобщенные c аргументы. В зависимости от этих операторов, операторы Generate позаботятся о необходимом преобразовании типов и подпишут расширение от std_logi c до множителей.

Я бы хотел, чтобы мой модуль выдавал ошибку, если пользователь передает любую строку, другую чем "подписано" или "неподписано" в моем аргументе подписи во время создания шаблона шаблона generic c. Я могу придумать ad-ho c способ сделать это с помощью if-операторов, но есть ли какой-то способ для меня определить набор строк, универсальный для всех модулей умножения (а именно, {"Signed", "unsigned"} ), и выдает ошибку компилятора, если моя входная строка не достигает l ie в этом наборе?

Я знаю, что это возможно с контейнерами SystemVerilog или библиотеками метапрограммирования, но я не думаю, что смогу убедить моя команда использовала эти виды инструментов, и мне было интересно, существуют ли какие-либо подобные конструкции, помогающие метапрограммированию в базовом VHDL.

1 Ответ

0 голосов
/ 14 февраля 2020

Может быть проще объявить функцию со знаком * без знака, так как в numeric_std уже есть подпись * со знаком и без знака * без знака. Затем передайте типы и функцию как универсальные объекты (с VHDL 2008)? Таким образом, он заставляет пользователя определять функцию умножения. Если у вас уже есть 4 варианта, все ваши базы покрыты. Если пользователь хочет использовать какой-то другой дурацкий тип, он также должен определить для него функцию «*».

function "*" (l :   signed; r : unsigned) return signed;
function "*" (l : unsigned; r :   signed) return signed;

entity mult_generic is
  generic (
    type op1_t;
    type op2_t;
    type mult_t;
    function "*" (l : op1_t; r: op2_t) return mult_t is <>;
  );

  port (
    clk : in std_logic;

    op1  : op1_t;
    op2  : op2_t;
    mult : mult_t;
  );
end entity mult_generic;

architecture rtl of mult_generic is
begin

  process(clk)
  begin
    if rising_edge(clk) then
      mult <= op1 * op2;
    end if;
  end process;

end architecture;

....

--example
mult_inst : entity work.mult_generic
generic map (
  op1_t => unsigned;
  op2_t => signed;
  mult_t => signed;
)
port map (
  --etc
);
...