Обратная последовательность бит на VHDL - программирование
Подтвердить что ты не робот

Обратная последовательность бит на VHDL

У меня возникли проблемы с чем-то вроде

b(0 to 7) <= a(7 downto 0)

когда я компилирую его с помощью ghdl, у меня есть ошибка порядка. Единственный способ, с помощью которого я нашел свою схему, - это следующее:

library ieee;
use ieee.std_logic_1164.all;
entity reverser is
    port(
        a: in std_logic_vector(7 downto 0);
        y: out std_logic_vector(7 downto 0);
        rev: in std_logic
        );
end reverser;

architecture rtl of reverser is
    signal b: std_logic_vector (7 downto 0);

begin

    b(7) <= a(0);
    b(6) <= a(1);
    b(5) <= a(2);
    b(4) <= a(3);
    b(3) <= a(4);
    b(2) <= a(5);
    b(1) <= a(6);
    b(0) <= a(7);

    y <= b when rev = '1' else a;

end rtl;

Предложения? Спасибо заранее

4b9b3361

Ответ 1

Это не разрешено - VHDL настолько строго типизирован, что если вы хотите отменить порядок бит, вы должны сделать это явно.

Стандартное решение - использовать функцию (я этого не писал - Джонатан Бромли сделал):

function reverse_any_vector (a: in std_logic_vector)
return std_logic_vector is
  variable result: std_logic_vector(a'RANGE);
  alias aa: std_logic_vector(a'REVERSE_RANGE) is a;
begin
  for i in aa'RANGE loop
    result(i) := aa(i);
  end loop;
  return result;
end; -- function reverse_any_vector

Ответ 2

В вопросе задается вопрос, как конкретно обращаться с b (от 0 до 7) <= a (7 down 0). Я не знаю причин, но иногда это назначение работает для меня (присваивает вещи слева направо, независимо от разрезания), и иногда это присваивание выдает ошибки компилятора (несоответствующий разрез или что-то еще).

К счастью, вам не нужно использовать функцию для обработки несогласованных разрезов. Если вы получаете ошибки компилятора для этой конкретной проблемы, вы можете использовать цикл генерации, чтобы назначить a для b.

for i in a'range generate
   b(i) <= a(i)  
   --when i is 0, you assign a right-most bit to b left-most bit
end generate;

Он выполняет в основном такое же развернутое назначение, как и в вашем примере, просто ограниченное и масштабируемое.

Я также использовал этот шаблон, когда у меня есть несогласованная нарезка в правой части задания. Например:

signal a : std_logic_vector(0 to 7);
signal b : std_logic_vector(7 downto 0);
signal c : std_logic_vector(0 to 7);

...

for i in a'range generate
   c(i) <= a(i) xor b(i);
end generate;

Что эквивалентно:

c(0) <= a(0) xor b(0);
c(1) <= a(1) xor b(1);
c(2) <= a(2) xor b(2);
c(3) <= a(3) xor b(3);
c(4) <= a(4) xor b(4);
c(5) <= a(5) xor b(5);
c(6) <= a(6) xor b(6);
c(7) <= a(7) xor b(7);

Ответ 3

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

gen: for i in 0 to 7 generate
  y(i) <= a(i) when rev='0' else a(7-i);
end generate;

Ответ 4

Действительно инвертирует:

for i in 0 to intermediate_data'left loop

  inverted_vector(i) <= intermediate_data(intermediate_data'left - i);

end loop;

Ответ 5

Предложения?

Поскольку ваш пример указывает фиксированную длину:

architecture rtl of reverser is 
    -- signal b: std_logic_vector (7 downto 0);

begin

    -- b(7) <= a(0);
    -- b(6) <= a(1);
    -- b(5) <= a(2);
    -- b(4) <= a(3);
    -- b(3) <= a(4);
    -- b(2) <= a(5);
    -- b(1) <= a(6);
    -- b(0) <= a(7);

    -- y <= b when rev = '1' else a;

    y <= a(0)&a(1)&a(2)&a(3)&a(4)&a(5)&a(6)&a(7) when rev = '1' else a;

end rtl;

Теория состоит в том, что это должно быть меньше накладных расходов, чем вызов функции или оператор цикла.

Ответ 6

OUT_PUT (7 DOWNTO 0) <= IN_PUT (0 DOWNTO 7)