2016-04-13 4 views
0
library IEEE; 
use IEEE.std_logic_1164.all;  
use IEEE.numeric_std.all; 

entity shift_reg is 
    port(
    d : in std_logic; 
    clk : in std_logic; 
    rst_bar : in std_logic; 
    q : out std_logic_vector(7 downto 0) 
    ); 
end shift_reg; 

architecture post_vhdl_08 of shift_reg is 
begin 

    process(clk, rst_bar) 

    variable q_int : std_logic_vector(7 downto 0); 

    begin 
     if rst_bar = '0' then 
      q_int := (others => '0'); 
     elsif rising_edge(clk) then 
      q_int := q_int(6 downto 0) & d; 
     end if; 

     q <= q_int; 

    end process; 

end post_vhdl_08; 

Я реализовал сдвиговый левый регистр с последовательным входом и параллельным выходом, используя «срез» для реализации сдвига; но я не могу понять, как реализовать ту же логику с помощью перегруженного оператора сдвига: оператор 'sll' (shift left logical). Спасибо всем за любую помощь, которую вы можете предложить.Сдвиг влево с помощью оператора сдвига VHDL: проблема sll

+0

Возможный дубликат [shift a std \ _logic \ _vector из n бит вправо или влево] (http://stackoverflow.com/questions/9018087/shift-a-std-logic-vector-of-n-bit -to-right-or-left) –

+0

Я специально спрашиваю, как реализовать этот код с помощью оператора сдвига sll. Я не знаю, как использовать оператора, поэтому мне нужен пример ... другой пост не очень помогает мне понять, как его использовать –

ответ

1

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

process(clk, rst_bar) 

variable q_int : unsigned(7 downto 0); 
subtype st is unsigned(7 downto 0); 

begin 
    if rst_bar = '0' then 
     q_int := (others => '0'); 
    elsif rising_edge(clk) then 
     q_int := q_int sll 1; 
     q_int := q_int or st'(0=>d,others=>'0'); 
     q <= std_logic_vector(q_int); 
    end if; 
end process; 

http://www.edaplayground.com/x/3YGu

Итак, для начала, sll сдвигов в '0', который вы не хотите. Поэтому вам понадобится операция or, чтобы включить вход d. Но sll не перегружен для std_logic_vector, поэтому вы должны использовать либо unsigned, либо signed (unsigned имеет смысл здесь). Мало того, эти типы операторов делают strange things в VHDL. Поэтому, если бы я был вами, я бы придерживался конкатенации.

Кроме того, ваше задание q находится не в том месте. Когда вы выполняете последовательный процесс, вы не должны назначать сигнал за пределами if rising_edge, потому что иначе (в этом случае) q будет назначаться на обоих краях тактового генератора - поведение, которое не является синтезируемым.

Наконец, в зависимости от возможностей вашего синтезатора вы можете получить 16 триггеров вместо 8. Это потому, что ваша переменная будет синтезироваться до 8 триггеров, и ваш сигнал будет синтезироваться еще до 8 («каждый назначенный сигнал в синхронизированном процессе имеет триггер "). Затем вы отвечаете на синтезаторе, чтобы оптимизировать 8 из этих триггеров.

+0

ror, rol, sll и srl не так странны, они не были поскольку sla и sra странны в определении языка VHDL-93. VHDL-2008 реализовала их для std_logic_vector, без знака и подписала. Поскольку sra и sla являются «арифметическими», они реализуются только тогда, когда пакет поддерживает арифметику - следовательно, для std_logic_vector вам понадобится numeric_std_unsigned. Для bit_vector sra и sla неявно определены, поэтому, если вы хотите иметь значение numeric_std (MSB слева) sla и sra, обязательно используйте numeric_bit_unsigned, который перегружает их. –

+0

OTOH, как рекомендует Мэтью, просто используйте конкатенацию - особенно для этой проблемы. –

0

Я могу предложить вам этот метод, чтобы сместить влево/вправо или с помощью поворота (VHDL '87!) ..

library ieee; 
use ieee.std_logic_1164.all; 
use ieee.numeric_std.all; 

entity Barrelshifter is 

    generic (gSize : natural := 3); 
    port (
    iPortA : in std_ulogic_vector(2**gSize-1 downto 0); 
    oPortQ : out std_ulogic_vector(2**gSize-1 downto 0); 
    iShiftDigits : in std_ulogic_vector(gSize-1 downto 0); 
    iModeSelect : in std_ulogic_vector(1 downto 0) 
    ); 

end Barrelshifter; 

architecture Rtl of Barrelshifter is 

begin -- architecture Rtl 

    Comb: process (iPortA, iShiftDigits, iModeSelect) 

    -- component variables 
    variable Count : integer; 

    begin -- process Comb 


    Count := to_integer(unsigned(iShiftDigits)); 

    if iModeSelect = "00" then 
     oPortQ <= std_ulogic_vector(shift_left(unsigned(iPortA), Count)); 

    elsif iModeSelect = "01" then 
     oPortQ <= std_ulogic_vector(shift_right(unsigned(iPortA), Count)); 

    elsif iModeSelect = "10" then 
     oPortQ <= std_ulogic_vector(rotate_left(unsigned(iPortA), Count)); 

    else 
     oPortQ <= std_ulogic_vector(rotate_right(unsigned(iPortA), Count)); 

    end if; 

    end process Comb; 

end Rtl ; 
Смежные вопросы