VHDL - И переменное число битов

У меня есть w*y-битная ширина std_logic_vector с именем matrix, где w и y — целые числа. Я хочу, чтобы y-битная ширина std_logic_vector называлась output, чтобы ее биты одновременно присваивались И из w битов matrix элементов.

Например, w=5 y=3:

output(2) <= matrix(14) and matrix(13) and matrix(12) and matrix(11) and matrix(10);
output(1) <= matrix(9) and matrix(8) and matrix(7) and matrix(6) and matrix(5);
output(0) <= matrix(4) and matrix(3) and matrix(2) and matrix(1) and matrix(0);

В примере вы можете видеть, что output имеет длину y-бит, что равно 3, и каждый бит output присваивается И w-битов matrix, что равно 5.

Теперь я хочу написать это с помощью дженериков. Я пытался написать это в два цикла for..generate, но я не могу с этим справиться. Что должно быть справа от output(i)? Это также может быть реализовано по-другому, и я очень приветствую другие идеи. Это не должно быть так, как я думал.

library ieee;
use ieee.std_logic_1164.all;

entity module is

    generic (
        w : integer := 5;   -- input width
        y : integer := 3    -- output width
    );

    port (
        matrix     : in  std_logic_vector(w * y - 1 downto 0);  -- matrix
        output     : out std_logic_vector(y - 1 downto 0)       -- output
    );
end entity module;

architecture rtl of module is

begin  -- architecture rtl


    AND_FOR: for i in y - 1 downto 0 generate
        AND_FOR2: for j in w - 1 downto 0 generate
            output(i) <= ????;
        end generate AND_FOR2;
    end generate AND_FOR;

end architecture rtl;

Если у вас есть доступ к VHDL 2008, я полагаю, что у него есть сокращение и оператор; если нет, то не так уж сложно закодировать его в функции самостоятельно. При этом вам понадобится только один уровень для генерации. В качестве альтернативы вы можете заменить второй for generate на процесс и цикл for и сохранить продукт во временной переменной. После цикла for сохраните переменную в желаемом выходном бите. См. stackoverflow.com/questions/20296276/….

Travis 01.04.2022 22:59
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
1
80
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Цель здесь — найти способ описать срезы с диапазоном элементов в ваших назначениях в качестве входных данных для сокращения И использовать тщательно разработанные границы в как можно меньшем количестве операторов генерации.

Операторы Generate привлекательны тем, что предоставляют статические индексированные имена или имена слайсов, сохраняя возможность синтеза. У нас нет способа разработать выражения различной сложности (здесь длины) в VHDL, что делает привлекательной сведение по И. В зависимости от инструментов синтеза вам может быть «рекомендовано» использовать ранее существовавшую функцию, такую ​​как AND_REDUCE из пакета Synopsys std_logic_misc.

В -2008 мы можем использовать унитарное И (зарезервированное слово, за которым следует операнд. В инструментах, совместимых с более ранними версиями стандарта VHDL, мы можем использовать вызов функции:

architecture rtl of module is
    -- -2008 use unitary AND without parameter instead of call:
    function reduce_and (inp: std_logic_vector) return std_logic is
        variable retval:    std_logic := '1';
    begin
        for i in inp'range loop
            retval := retval and inp(i);
        end loop;
        return retval;
    end function;
begin
AND_FOR: 
    for i in y - 1 downto 0 generate
        output(i) <= reduce_and(matrix((i + 1) * w - 1 downto i * w));
    end generate;

describe_outputs:
    process
    begin
        report "matrix'range is (" & integer'image(matrix'left) & 
               " downto " & integer'image(matrix'right) & ")";
        for i in y - 1 downto 0 loop
            report "output(" & integer'image(i) & ") <= reduce_and(matrix(" &
                integer'image((i + 1) * w - 1 ) & " downto " &
                integer'image (i * w) & ")";
        end loop;
        wait;
    end process;
end architecture;

Оператор for generate создаст блок для каждого значения его параметра for generate (здесь i). Он объявлен как константа в области описания блока. И w, и y являются глобально статическими универсальными константами, и в результате диапазон матрицы также является глобально статическим. В основном это означает, что использование оператора генерации, подобного этому, приводит к операторам присваивания, пригодным для синтеза.

Оператор процесса, помеченный describe_outputs, добавлен, чтобы продемонстрировать эквивалентность (способность алгоритмически описывать элементы, объединяемые по И) с вашими предыдущими операторами присваивания, потому что вы не продемонстрировали значение для матрицы и ожидаемый результат вместе с испытательным стендом. Процесс можно устранить.

Пока вы используете значения для w и x, которые не приводят к нулевому диапазону или нулевому срезу, этот метод должен работать с жестко закодированным направлением (downto).

Операторы отчета зависят от реализации (с необходимой информацией «заголовок»). Здесь показано для ghdl:

%: ghdl -a module.vhdl
%: ghdl -e module
%: ghdl -r module
module.vhdl:35:9:@0ms:(report note): matrix'range is (14 downto 0)
module.vhdl:38:13:@0ms:(report note): output(2) <= reduce_and(matrix(14 downto 10)
module.vhdl:38:13:@0ms:(report note): output(1) <= reduce_and(matrix(9 downto 5)
module.vhdl:38:13:@0ms:(report note): output(0) <= reduce_and(matrix(4 downto 0)
%:

Мне действительно нужно было reduce_xor, поэтому я изменил variable retval: std_logic := '1'; на variable retval: std_logic := '0';, а также, очевидно, and на xor, и использовал это решение. Это работает очень хорошо! Спасибо.

efe373 05.04.2022 19:51

Вы действительно можете смоделировать это с помощью двумерного генератора, но вам нужен промежуточный сигнал, соответствующий выходам двухвходовых логических элементов И.

Давайте рассмотрим ваш ввод как матрицу y строк, умноженных на w столбцов. Для простоты объяснения мы будем обозначать m(i,j) элемент в строке i, столбце j матрицы m. Так что ваш matrix(i*w+j) обозначается matrix(i,j).

Вы хотите, чтобы output(i), где 0 <= i <= y-1, было побитовым и строкой i из matrix. Вы можете использовать матрицу y строк, умноженных на w-1 столбцы tmp, чтобы получить результаты 2-входных И. tmp(i,0) будет AND matrix(i,0) и matrix(i,1). Тогда tmp(i,1) будет И между tmp(i,0) и matrix(i,2)... Наконец, tmp(i,w-2) будет И между tmp(i,w-3) и matrix(i,w-1), и это также будет output(i), которое вы хотите.

Кодирование VHDL:

library ieee;
use ieee.std_logic_1164.all;

entity module is
  generic(
    w: integer := 5;
    y: integer := 3
  );
  port(
    matrix: in  std_logic_vector(w * y - 1 downto 0);
    output: out std_logic_vector(y - 1 downto 0)
  );
end entity module;

architecture rtl of module is
  type matrix_t is array(natural range <>, natural range <>) of std_logic;
  signal tmp: matrix_t(0 to y - 1, 0 to w - 2);
begin
  and_for: for i in 0 to y - 1 generate
    tmp(i, 0) <= matrix(i * w) and matrix(i * w + 1);
    and_for2: for j in 1 to w - 2 generate
      tmp(i, j) <= tmp(i, j - 1) and matrix(i * w + j + 1);
    end generate and_for2;
    output(i) <= tmp(i, w - 2);
  end generate and_for;
end architecture rtl;

Демо:

library ieee;
use ieee.std_logic_1164.all;

entity module_sim is
end entity module_sim;

architecture sim of module_sim is
  constant w: natural := 5;
  constant y: natural := 3;
  signal matrix: std_logic_vector(w * y - 1 downto 0);
  signal output: std_logic_vector(y - 1 downto 0);
begin
  u0: entity work.module(rtl)
  port map(
    matrix => matrix,
    output => output
  );

  process
  begin
    matrix <= (others => '1');
    wait for 1 ns;
    report to_string(output);
    for i in 0 to y - 1 loop
      matrix(i * w) <= '0';
    end loop;
    wait for 1 ns;
    report to_string(output);
    matrix <= (others => '1');
    wait for 1 ns;
    report to_string(output);
    wait;
  end process;
end architecture sim;
$ ghdl -a --std=08 module_sim.vhd
$ ghdl -r --std=08 module_sim
module_sim.vhd:50:5:@1ns:(report note): 111
module_sim.vhd:55:5:@2ns:(report note): 000
module_sim.vhd:58:5:@3ns:(report note): 111

Но, как предлагается в другом ответе, использование функции сокращения И вместо самого внутреннего оператора генерации проще и менее подвержено ошибкам.

В прошлые дни мы беспокоились о том, сколько процессов (здесь w * y) и сколько раз они будут вызваны до того, как продвинется время моделирования. Теперь не так много, ограничивающим фактором производительности моделирования является объем памяти в модели, особенно для сигналов. Существует также единая модель процесса (выражение вызова функции, требующее регистрации вывода только для достаточно больших значений w, чтобы иметь значение глубины затвора, а также зависит от архитектуры логической ячейки FPGA для синтеза). Инструмент синтеза с надлежащими ограничениями может дать один и тот же ответ из любого из этих описаний.

user16145658 04.04.2022 10:45

Спасибо, Рено, я ценю. Это похоже на правильное решение, однако, как вы также упомянули, другой ответ работал довольно хорошо и проще, я думаю, что пока буду придерживаться его.

efe373 05.04.2022 19:49

Другие вопросы по теме