2016-04-13 13 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; 

Vardiyayı uygulamak için bir "dilim" kullanarak seri giriş ve paralel çıkışlı bir kaydırma sol kaydı gerçekleştirdim; ama aynı mantığı aşırı yüklenen bir vardiya operatörü kullanarak nasıl uygulayacağımı anlayamıyorum: 'sll' (shift left logical) operatörü. Sunduğunuz her türlü yardım için hepinize teşekkür ederim.VHDL kaydırma operatörü kullanarak sola kayma: sll trouble

+0

Olası çoğalt [shift a std \ _logic \ _vector n bit sağa veya sola] (http://stackoverflow.com/questions/9018087/shift-a-std-logic-vector-of-n-bit -to-right-or-left) –

+0

Özellikle sll shift operatörünü kullanarak yukarıdaki kodu nasıl uygulayacağımı soruyorum. Operatörü nasıl kullanacağımı gerçekten bilmiyorum bu yüzden bir örneğe ihtiyacım var ... diğer mesajın nasıl kullanıldığını anlamamda bana yardımcı olmuyor –

cevap

1

örneğin sll operatörün nasıl kullanılacağını olduğunu. Gördüğünüz gibi, bu bir ağrı o ne istersen yap ve yapılacak mucking diğer var olmadığından, var:

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

Yani, başlayanlar, bir '0' içinde sll kaymalar için hangi İstemek istemiyor. Böylece d girişini dahil etmek için or işlemine ihtiyacınız vardır. Ancak, sll, std_logic_vector için için aşırı yüklü değil, bu nedenle unsigned veya signed (unsigned burada anlamlıdır) kullanmanız gerekir. Sadece bu değil, bu tür operatörler VHDL'de strange things yapıyor. Öyleyse, eğer ben olsaydım, birleşme ile yapışırdım.

Ayrıca, atamanız q yanlış yerde. Sıralı bir işlem yaptığınızda, if rising_edge dışında bir sinyale atamamalısınız, aksi halde (bu durumda) q her iki saat kenarına da atanabilir - sentezlenemeyen davranış. Son olarak, sentezleyicinizin yeteneklerine bağlı olarak, 8 yerine 16 flip-flop alabilirsiniz. Bunun nedeni, değişkeninizin 8 flip-flop'a sentezlemesi ve sinyalinizin 8 daha fazla sentezlemesidir ("her bir sinyal atanmış" demektir.). bir saat işleminde bir flip-flop ") açar. Daha sonra bu parmak arası terliklerden 8 tanesini optimize etmek için sentezleyicinizi yanıtlıyorsunuz.

+0

ror, rol, sll ve srl çok garip değil VHDL-93 dil tanımında sla ve sra beri garip vardır. VHDL-2008 bunları std_logic_vector için imzaladı, imzaladı ve imzaladı. Sra ve sla "aritmetik" olduklarından, sadece paket aritmetik desteklediğinde uygulanır - std_logic_vector için, numeric_std_unsigned gerekir. Bit_vector sra ve sla için örtülü olarak tanımlanmıştır, bu nedenle sla ve sra'nın numeric_std sense (soldaki MSB) olmasını istiyorsanız, numeric_bit_unsigned'i kullandığınızdan emin olun. –

+0

OTOH, Matthew'in de önerdiği gibi, özellikle de bu problem için birleştirme kullanımı kullanın. –

0

Sana doğru ya da döndürme kullanarak sol/kaydırmaya bu yöntemi sunabilir (VHDL '87!) .. Burada

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 ; 
İlgili konular