Подтвердить что ты не робот

Сдвиг std_logic_vector из n бит вправо или влево

У меня есть вектор signal tmp : std_logic_vector(15 downto 0)

Мне нужно сдвинуть его влево или вправо от n бит. как я могу реализовать эту операцию. Я думал о операции конкатенации, но я не знал, как это использовать.

4b9b3361

Ответ 1

Используйте библиотеку ieee.numeric_std и соответствующий векторный тип для чисел, над которыми вы работаете (unsigned или signed).

Тогда операторы sla/sra для арифметических сдвигов (т.е. заполняют знаковым битом в сдвигах справа и lsb в левых сдвигах) и sll/srl для логических сдвигов (т.е. заполняют с помощью 0).

Вы передаете параметр оператору для определения количества сдвигатых битов:

A <= B srl 2; -- logical shift right 2 bits

Обновление:

Я понятия не имею, что я пишу выше (спасибо Валу за то, что указали это!)

Конечно, правильный способ смены типов signed и unsigned - с функциями shift_left и shift_right, определенными в ieee.numeric_std.

Операторы сдвига и поворота sll, ror и т.д. предназначены для векторов boolean, bit или std_ulogic, и может иметь интересное неожиданное поведение в том, что арифметические сдвиги дублируют конечный бит даже при сдвиге влево.

И многое другое можно найти здесь:

http://jdebp.eu./FGA/bit-shifts-in-vhdl.html

Однако ответ на исходный вопрос по-прежнему

sig <= tmp sll number_of_bits;

Ответ 2

Есть два способа добиться этого. Конкатенация и функции сдвига/поворота.

  • Конкатенация - это "ручной" способ делать вещи. Вы указываете, какую часть исходного сигнала вы хотите "сохранить", а затем конкатенацию данных на одном конце или другом. Например: tmp <= tmp (14 до 0) и '0';

  • Функции сдвига (логические, арифметические): это общие функции, которые позволяют вам перемещать или поворачивать вектор разными способами. Функции: sll (сдвиг влево логический), srl (сдвиг вправо логический). Логический сдвиг вставляет нули. Арифметические сдвиги (sra/sla) вставляют левый самый или самый правый бит, но работают так же, как логический сдвиг. Обратите внимание, что для всех этих операций вы указываете, что вы хотите сдвинуть (tmp), и сколько раз вы хотите выполнить сдвиг (n бит)

  • Поворот функций: rol (вращение влево), ror (поворот вправо). Вращение делает именно это, MSB попадает в LSB, и все сдвигается влево (ролл) или наоборот для ror.

Вот полезная ссылка, которую я нашел (см. первую страницу).

Ответ 3

Лично я считаю, что конкатенация - лучшее решение. Общая реализация была бы

entity shifter is
    generic (
        REGSIZE  : integer := 8);
    port(
        clk      : in  str_logic;
        Data_in  : in  std_logic;
        Data_out : out std_logic(REGSIZE-1 downto 0);
end shifter ;

architecture bhv of shifter is
    signal shift_reg : std_logic_vector(REGSIZE-1 downto 0) := (others<='0');
begin
    process (clk) begin
        if rising_edge(clk) then
            shift_reg <= shift_reg(REGSIZE-2 downto 0) & Data_in;
        end if;
    end process;
end bhv;
Data_out <= shift_reg;

Оба будут реализованы как сдвиговые регистры. Если вам нужно больше регистров сдвига, чем вы готовы тратить ресурсы (EG делит 1000 номеров на 4), вы можете использовать BRAM для хранения значений и одного регистра сдвига, чтобы содержать "индексы", которые приводят к правильный сдвиг всех чисел.

Ответ 4

Я бы не предлагал использовать sll или srl с помощью std_logic_vector.

Во время моделирования sll дал мне значение "U" для этих битов, где я ожидал 0.

Используйте функции shift_left(), shift_right().

Например:

OP1 : in std_logic_vector(7 downto 0); signal accum: std_logic_vector(7 downto 0);

accum <= std_logic_vector(shift_left(unsigned(accum), to_integer(unsigned(OP1)))); accum <= std_logic_vector(shift_right(unsigned(accum), to_integer(unsigned(OP1))));

Ответ 5

Обычно это делается вручную, выбирая соответствующие биты из вектора, а затем добавляя 0s.

Например, чтобы сдвинуть вектор 8 бит

variable tmp : std_logic_vector(15 downto 0)
...
tmp := x"00" & tmp(15 downto 8);

Надеюсь, этот простой ответ полезен кому-то.

Ответ 6

add_Pbl <= to_stdlogicvector(to_bitvector(dato_cu(25 downto 2)) sll 1);
add_Pbl is a std_logic_vector of 24 bit
dato_cu is a std_logic_vector of 32 bit

Сначала вам нужно преобразовать функцию std_logic_vector с помощью функции to_bitvector() потому что инструкция sll работает с логическими 1 и 0 битами.