2012-11-27 8 views
14

Ich habe Probleme etwas zu tun, wieReverse-Bit-Reihenfolge auf VHDL

b(0 to 7) <= a(7 downto 0) 

, wenn ich es mit ghdl kompilieren, habe ich einen Auftrag Fehler. Der einzige Weg, den ich gefunden habe, um meine Schaltung arbeiten zu lassen, ist die folgende:

library ieee; 
use ieee.std_logic_1164.all; 
entity reverser is 
    port(
     a: in std_logic_vector(7 downto 0); 
     y: out std_logic_vector(7 downto 0); 
     rev: in std_logic 
     ); 
end reverser; 

architecture rtl of reverser is 
    signal b: std_logic_vector (7 downto 0); 

begin 

    b(7) <= a(0); 
    b(6) <= a(1); 
    b(5) <= a(2); 
    b(4) <= a(3); 
    b(3) <= a(4); 
    b(2) <= a(5); 
    b(1) <= a(6); 
    b(0) <= a(7); 

    y <= b when rev = '1' else a; 

end rtl; 

Vorschläge? Vielen Dank im Voraus

+0

Obwohl es nicht für den Bit-Rückwärtsbetrieb helfen, das absteigenden Bereich Schlüsselwort 'downto' (dh nicht' unten to'). – wap26

+0

Entschuldigung für den Fehler, was ich meine, war das. b (0 bis 7) <= a (7 abwärts bis 0) – titockmente

Antwort

22

Das ist nicht erlaubt - VHDL ist so stark typisiert, dass, wenn Sie Bit-Aufträge umkehren möchten, müssen Sie es explizit tun.

Die Standardlösung ist eine Funktion zu verwenden (Ich habe das nicht schreiben - Jonathan Bromley did):

function reverse_any_vector (a: in std_logic_vector) 
return std_logic_vector is 
    variable result: std_logic_vector(a'RANGE); 
    alias aa: std_logic_vector(a'REVERSE_RANGE) is a; 
begin 
    for i in aa'RANGE loop 
    result(i) := aa(i); 
    end loop; 
    return result; 
end; -- function reverse_any_vector 
4

Die Frage fragt, wie speziell mit b behandeln (0 bis 7) < = a (7 nach unten 0). Ich kenne die Gründe nicht, aber manchmal funktioniert diese Zuweisung für mich (weist Dinge von links nach rechts zu, unabhängig vom Slicing) und manchmal wirft diese Zuweisung Compilerfehler (nicht übereinstimmendes Slicing oder so).

Glücklicherweise müssen Sie keine Funktion verwenden, um nicht übereinstimmende Schnitte zu verarbeiten. Wenn Sie Compiler-Fehler für dieses spezielle Problem bekommen, können Sie eine generate-Schleife verwenden, um a zu b zuzuweisen.

for i in a'range generate 
    b(i) <= a(i) 
    --when i is 0, you assign a's right-most bit to b's left-most bit 
end generate; 

Es ist im Grunde die gleiche entrollte Zuweisung wie in Ihrem Beispiel, nur knapp und skalierbar.

Ich habe dieses Muster auch verwendet, wenn ich auf der rechten Seite der Zuordnung nicht übereinstimmen. Zum Beispiel:

signal a : std_logic_vector(0 to 7); 
signal b : std_logic_vector(7 downto 0); 
signal c : std_logic_vector(0 to 7); 

... 

for i in a'range generate 
    c(i) <= a(i) xor b(i); 
end generate; 

Welche entspricht:

c(0) <= a(0) xor b(0); 
c(1) <= a(1) xor b(1); 
c(2) <= a(2) xor b(2); 
c(3) <= a(3) xor b(3); 
c(4) <= a(4) xor b(4); 
c(5) <= a(5) xor b(5); 
c(6) <= a(6) xor b(6); 
c(7) <= a(7) xor b(7); 
+1

Standardmäßig wird für die oben definierten a/b-Vektoren und die Anweisung "b <= a" (oder das Äquivalent in einer PORT MAP) VHDL angegeben wird die Vektorbits in der Reihenfolge von links nach rechts zuweisen, unabhängig von der Nummerierung.Dadurch wird MSB == MSB beibehalten, wenn eine Mischung aus Big-Endian- und Little-Endian-Bit-Reihenfolge verwendet wird. (dh. b (7) <= a (0) usw.) Sie erhalten den Fehler, wenn Sie versuchen, "a (x downto y)" oder b (x bis y) "zu verwenden - dh wenn Sie versuchen, umzukehren die deklarierte Reihenfolge eines bestimmten Signals.Wenn Sie absichtlich die Bits außerhalb der Reihenfolge abbilden wollen, dann müssen Sie ein Generat oder eine Funktion verwenden, wie in diesen Antworten gezeigt.Auch – Miral

4

Es gibt mehrere Lösungen für dieses Problem sind. Eine Möglichkeit ist die folgende:

gen: for i in 0 to 7 generate 
    y(i) <= a(i) when rev='0' else a(7-i); 
end generate; 
-6

OUT_PUT (7 DOWNTO 0) < = IN_PUT (0 DOWNTO 7)

0

Verbesserungsvorschläge?

Da Ihr Beispiel wird angegeben, feste Länge:

architecture rtl of reverser is 
    -- signal b: std_logic_vector (7 downto 0); 

begin 

    -- b(7) <= a(0); 
    -- b(6) <= a(1); 
    -- b(5) <= a(2); 
    -- b(4) <= a(3); 
    -- b(3) <= a(4); 
    -- b(2) <= a(5); 
    -- b(1) <= a(6); 
    -- b(0) <= a(7); 

    -- y <= b when rev = '1' else a; 

    y <= a(0)&a(1)&a(2)&a(3)&a(4)&a(5)&a(6)&a(7) when rev = '1' else a; 

end rtl; 

Die Theorie ist, dass diese weniger Overhead als einen Funktionsaufruf oder -Schleifenanweisungen sein sollte.

+1

Wenn das aus dem Synthesizer kommt, anders als eine Schleife oder eine Funktion Rufen Sie an, ich würde einen Fehler protokollieren! –

+0

Versuchen Sie Simulation – user1155120

+0

Ahh, OK, ich sehe, was Sie meinen! –

2

Wirklich Umkehren:

for i in 0 to intermediate_data'left loop 

    inverted_vector(i) <= intermediate_data(intermediate_data'left - i); 

end loop;