it-swarm.com.de

verschiebe einen std_logic_vector von n Bit nach rechts oder links

Ich habe einen Vektor signal tmp : std_logic_vector(15 downto 0)

Ich muss es nach links oder rechts von n Bit verschieben. Wie kann ich diesen Vorgang realisieren? Ich dachte an die Verkettung, wusste aber nicht, wie sie es nutzen sollte.

18
Mazzy

Verwenden Sie die ieee.numeric_std-Bibliothek und den entsprechenden Vektortyp für die Zahlen, an denen Sie gerade arbeiten (unsigned oder signed).

Dann sind die Operatoren sla/sra für arithmetische Verschiebungen (dh füllen Sie das Vorzeichenbit bei Rechtsverschiebungen und lsb bei linken Verschiebungen) und sll/srl für logische Verschiebungen (dh füllen Sie mit '0').

Sie übergeben dem Operator einen Parameter, um die Anzahl der zu verschiebenden Bits festzulegen:

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

</ s>

Aktualisieren:

Ich habe keine Ahnung, was ich oben geschrieben habe (danke Val, dass ich darauf hingewiesen habe!)

Natürlich ist der richtige Weg, um signed- und unsigned-Typen zu verschieben, die in shift_left definierten shift_right- und ieee.numeric_std-Funktionen.

Die Verschiebungs- und Rotationsoperatoren sll, ror etc sind für die Vektoren boolean, bit oder std_ulogic und können interessanterweise unerwartetes Verhalten haben, indem die Arithmetikverschiebungen das Ende-Bit selbst bei Linksverschiebung duplizieren.

Und noch viel mehr Geschichte finden Sie hier:

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

Die Antwort auf die ursprüngliche Frage ist jedoch noch immer

sig <= tmp sll number_of_bits;
23
Martin Thompson

Es gibt zwei Möglichkeiten, dies zu erreichen. Verkettungs- und Shift/Rot-Funktionen.

  • Verkettung ist die "manuelle" Art, Dinge zu tun. Sie geben an, welcher Teil des Originalsignals Sie "behalten" und dann Daten an das eine oder das andere Ende ketten möchten. Zum Beispiel: tmp <= tmp (14 Abwärts bis 0) & '0';

  • Verschiebungsfunktionen (logisch, arithmetisch): Hierbei handelt es sich um generische Funktionen, mit denen Sie einen Vektor auf viele Arten verschieben oder drehen können. Die Funktionen sind: sll (logisch nach links verschieben), srl (logisch nach rechts verschieben). Eine logische Verschiebung fügt Nullen ein. Arithmetische Verschiebungen (sra/sla) fügen das Bit ganz links oder ganz rechts ein, funktionieren jedoch genauso wie die logische Verschiebung. Beachten Sie, dass Sie für alle diese Operationen angeben, was Sie verschieben möchten (tmp) und wie oft Sie die Verschiebung durchführen möchten (n bits)

  • Drehfunktionen: rol (nach links drehen), ror (nach rechts drehen). Rotieren macht genau das, das MSB landet im LSB und alles verschiebt sich nach links (rol) oder umgekehrt.

Hier ist eine praktische Referenz ich habe gefunden (siehe die erste Seite).

13
Josh

Ich persönlich denke, dass die Verkettung die bessere Lösung ist. Die generische Implementierung wäre

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;

Beide werden als Schieberegister implementiert. Wenn Sie mehr Schieberegister benötigen, für die Sie Ressourcen ausgeben möchten (z. B. 1000 Zahlen durch 4 dividieren), sollten Sie die Verwendung eines BRAM zum Speichern der Werte und eines einzelnen Schieberegisters mit "Indizes" für die Indexierung in Betracht ziehen korrekte Verschiebung aller Zahlen. 

6
Paul Seeb

Ich würde nicht vorschlagen, sll oder srl mit std_logic_vector zu verwenden. 

Während der Simulation gab sll einen U-Wert für die Bits an, bei denen ich 0 erwartete. 

Verwenden Sie die Funktionen shift_left(), shift_right().

Zum Beispiel:

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))));

3

Dies erfolgt normalerweise manuell, indem Sie die entsprechenden Bits aus dem Vektor auswählen und dann 0s anhängen.

Zum Beispiel, um einen Vektor um 8 Bits zu verschieben

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

Hoffentlich ist diese einfache Antwort für jemanden nützlich

2
iyop45
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

Zuerst müssen Sie den std_logic_vector mit der Funktion to_bitvector() Konvertieren, da die sll-Anweisung mit den Bits 1 und 0 arbeitet.

0
Pablito