Обратная последовательность бит на 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;
Предложения?
Спасибо заранее
Ответы
Ответ 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)