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

Ich habe eine Verschiebung Register links mit seriellen Eingang und parallelen Ausgang mit einem "Slice" implementiert, um die Verschiebung zu implementieren; aber ich kann nicht herausfinden, wie man dieselbe Logik mit einem überladenen Schichtoperator implementiert: 'sll' (shift left logic) -Operator. Vielen Dank für alle Hilfe, die Sie anbieten können.Shift Links Register mit VHDL Shift-Operator: Sll Problem

+0

Mögliches Duplikat von [verschiebe einen std \ _logic \ _vector von n Bit nach rechts oder links] (http://stackoverflow.com/questions/9018087/shift-a-std-logic-vector-of-n-bit (nach rechts oder nach links) –

+0

Ich frage speziell, wie ich den obigen Code mithilfe des SLL-Shift-Operators implementieren würde. Ich weiß nicht wirklich, wie man den Operator benutzt, also brauche ich ein Beispiel ... der andere Beitrag hilft mir nicht wirklich zu verstehen, wie man ihn benutzt –

Antwort

1

Hier ist, wie die Sie zum Beispiel sll Operator zu verwenden. Wie Sie sehen können, ist es ein Schmerz, weil es nicht tut, was Sie wollen, und es andere ist herumschlagen zu tun:

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

So, für Vorspeisen, sll Verschiebungen in einem '0', die Willst du nicht wollen. Sie benötigen also eine or Operation, um den d Eingang einzuschließen. Aber, sll ist nicht überladen für std_logic_vector, so müssen Sie entweder unsigned oder signed verwenden (unsigned macht Sinn hier). Nicht nur das, diese Arten von Operatoren tun strange things in VHDL. Also würde ich bei der Verkettung bleiben, wenn ich du wäre.

Auch Ihre Zuordnung zu q ist an der falschen Stelle. Wenn Sie einen sequentiellen Prozess ausführen, müssen Sie kein Signal außerhalb des if rising_edge zuweisen, da andernfalls (in diesem Fall) q auf beiden Taktflanken zugewiesen wird - Verhalten, das nicht synthetisch ist.

Schließlich könnten Sie, abhängig von den Fähigkeiten Ihres Synthesizers, 16 Flip-Flops anstelle von 8 bekommen. Dies liegt daran, dass Ihre Variable zu 8 Flip-Flops synthetisiert und Ihr Signal zu 8 mehr synthetisiert in einem getakteten Prozess ergibt sich ein Flip-Flop "). Sie antworten dann auf Ihrem Synthesizer, um 8 dieser Flip-Flops zu optimieren.

+0

ror, rol, sll und srl sind nicht so seltsam, sie waren es nicht implementiert, da sla und sra in der Sprachdefinition VHDL-93 seltsam sind. VHDL-2008 implementiert diese für std_logic_vector, unsigned und signed. Da sra und sla "arithmetisch" sind, werden sie nur implementiert, wenn das Paket die Arithmetik unterstützt - daher benötigen Sie für std_logic_vector numeric_std_unsigned. Für bit_vector sind sra und sla implizit definiert. Wenn Sie also den Wert für numeric_std (MSB auf der linken Seite) von sla und sra verwenden möchten, verwenden Sie numeric_bit_unsigned, wodurch diese überladen werden. –

+0

OTOH, wie Matthew auch empfiehlt, verwenden Sie einfach die Verkettung - besonders für dieses Problem. –

0

kann ich Ihnen diese Methode bieten verschieben links/rechts oder unter Verwendung drehen (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 ;