Арифметика универсального сдвига вправо в VHDL - PullRequest
0 голосов
/ 13 ноября 2010

Я занимаюсь разработкой универсального арифметического оператора сдвига. Есть ли лучший способ добиться этого, кроме использования 32-битного мультиплексора (декодера), как показано ниже?

ENTITY isra IS 
PORT (
  clk:    in std_logic;
  rst:    in std_logic;
  di:     in std_logic_vector (31 downto 0);
  sel:    in std_logic_vector (31  downto 0);
  res:    out std_logic_vector (31 downto 0) := (others => '0')
);
END isra;


PROCESS
  BEGIN
    WAIT UNTIL clk'EVENT AND clk = '1';
    IF rst = '1' THEN
      res <= (others => '0');
    ELSE
    CASE sel IS
        when X"00000001"  => res <= to_stdlogicvector(to_bitvector(a) sra 1);
        when X"00000002"  => res <= to_stdlogicvector(to_bitvector(a) sra 2);
        ...
        when X"0000001F"  => res <= to_stdlogicvector(to_bitvector(a) sra 31);
        when others => res <= (others => '0');
    END CASE;
END IF;
END PROCESS;

Ответы [ 3 ]

4 голосов
/ 15 ноября 2010

Вы можете использовать функцию SRA без каких-либо циклов или операторов case:

res <= to_stdlogicvector(to_bitvector(di) sra to_integer(sel));

Обратите внимание, что вам нужно сделать sel без знака, а не std_logic_vector:

sel: in unsigned (31  downto 0);

В случаеВы не хотите этого, вы все равно можете бросить себя в неподписанного.Вы также должны нам numeric_bit:

use ieee.numeric_bit.all;
1 голос
/ 14 ноября 2010

Использовать индексирование?

PROCESS
  VARIABLE shift_count : INTEGER RANGE 0 TO 31;
BEGIN
  IF rst = '1' THEN
    res <= (others => '0');
  ELSIF RISING_EDGE(clk) THEN
    shift_count := to_integer(sel);
    FOR I IN 0 TO 31 LOOP
      IF I + shift_count < 32 THEN
        res(I) <= din(I + shift_count);
      ELSE
        res(I) <= din(31); -- for logical shift right, use '0' instead
      END IF;
    END LOOP;
  END IF;
END PROCESS;

Эта версия намного проще параметризовать в общий.

Помните, что VHDl - это поведенческое описание, оно не определяет мультиплексирование. Компилятор может генерировать различные проекты в зависимости от того, оптимизируете ли вы размер, скорость, разрешите конвейерную обработку и т. Д.

Обратите внимание, что 5 2: 1 мультиплексоры могут реализовать это в гораздо меньшей области, чем один 32: 1 мультиплексор. Если это не тот блок, который ограничивает вашу тактовую частоту, это может быть предпочтительнее.

Также обратите внимание, что ваш sel ввод слишком широкий, он должен быть только 5 бит.

1 голос
/ 13 ноября 2010

Ну, с аппаратной точки зрения, чтобы сдвинуть вправо за один такт переменное число позиций, каждый бит представляет собой один триггер с одним из 32 возможных значений, основанных на выборе. Итак, с этой точки зрения, вот как вы это делаете.

Я бы сделал sel == 0 делом и сделал бы его проходным. Логично, что это имеет больше смысла, чем устанавливать все в нули.

...