www.mikrocontroller.net

Forum: FPGA, VHDL & Co. Bits vertauschen


Autor: Dirk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
ich habe hier 2 vektoren die einander zugewiesen werden. Ich möchte aber 
das das bit ganz links von vektor 1 bei vektor 2 das bit ganz rechts 
ist.

Gibts da eine Möglichkeit das ohne for-schleife bzw. händisch zu machen?

Händisch wäre z.B. so:
entity ledmatrix is
    Port ( ledstate : in  STD_LOGIC_VECTOR (15 downto 0);
           clk : in  STD_LOGIC;
           row : out  STD_LOGIC_VECTOR (3 downto 0);
           col : out  STD_LOGIC_VECTOR (3 downto 0));
end ledmatrix;


col(0) <= ledstate(3);
col(1) <= ledstate(2);
col(2) <= ledstate(1);
col(3) <= ledstate(0);


Autor: Der Besucher (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
so vielleicht:

col <= ledstate(0) & ledstate(1) & ledstate(2) & ledstate(3);


Was leider nicht geht ist;

col <= ledstate(0 to 3);

Würde ich mir auch wünschen...

Der Besucher

Autor: nixda (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: Hagen Re (hagen)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
process(ledstate)
begin
  for i in 0 to ledstate'high loop
    col(i) <= ledstate(ledstate'high - i);
  end loop;
end process;

Gruß Hagen

Autor: Hagen Re (hagen)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
-- nicht getestet !!

function reverse(input: std_logic_vector) return std_logic_vector is
  variable output: std_logic_vector;
begin
  for i in 0 to input'high loop
    output(i) := input(input'high -i);
  end loop;
  return output;
end reverse;

-- test
  col <= reverse(ledstate);

Gruß Hagen

Autor: Boris M. (borism)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die Frage lautete doch:

> Gibts da eine Möglichkeit das ohne for-schleife bzw. händisch zu machen?

Autor: SuperWilly (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es gibt eine nette reverse-Funktion in VHDL:
function reverse(p: std_logic_vector) return std_logic_vector is
variable temp: std_logic_vector(p'reverse_range);
variable result: std_logic_vector(p'range);
begin
   for i in p'range loop
      temp(i) := p(i);
   end loop;
   
   result := temp;

return result;
end;

SuperWilly

Autor: nixda (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
servus,

also "alias" geht, einfach und gut :-)

signal a: std_ulogic_vector(3 downto 0) := "1011";
alias b: std_ulogic_vector(0 to 3) is a(3 downto 0);

fuehrt zu

a(2) = 0

und

b(1) = 0;

/mfg

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das bedeutet, dass die Bits einfach an der selben Stelle bleiben.
Also ist a = "1011" und b = "1011"

Damit wird also nicht die gewünschte Umkehr der Bitreihenfolge erreicht 
:-o
Denn es sollte ja genau diese Bitreihenfolge umgekehrt werden, aber 
ledstate und col sind nun mal downto deklariert.
ledstate : in STD_LOGIC_VECTOR (15 downto 0);
col : out  STD_LOGIC_VECTOR (3 downto 0));

col(0) <= ledstate(3);
col(1) <= ledstate(2);
col(2) <= ledstate(1);
col(3) <= ledstate(0);

Autor: nixda (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
servus,


dadurch dass der range die richtung aendert, ist a(0) = b(3) usw.

>Damit wird also nicht die gewünschte Umkehr der Bitreihenfolge erreicht

hmmm,

also um beim beispiel zu bleiben

signal a: std_ulogic_vector(3 downto 0) := "1011";
alias b: std_ulogic_vector(0 to 3) is a(3 downto 0);

ergibt im simulator (getestet!)

a=(2=>0, others=>1)
b=(1=>0, other=>1)

damit ist der vector logisch reversed, oder?

ich glaub du verwechselt hier darstellung und wert.


der printout ist bei beiden gleich (der enthaelt ja nicht in welcher 
richtung in der der vector zu lesen ist)

im vhdl kann man das ganz gut sehen an

type'left,type'right und type'low+type'high

left kann low oder high sein, und dementsprechend auch right='low|'high
das ganze existiert damit man algorithmen unabhaengig von der array 
direction spezifieren kann.

/mfg

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
> dadurch dass der range die richtung aendert, ist a(0) = b(3) usw.
Richtig, aber leider bringt das nichts, wenn Ausgangs- und Zielvektor 
downto sind. Da bringt ein "Pseudovektor" mit to nichts.
Die Bitreihenfolge von links nach rechts bleibt gleich.

> damit ist der vector logisch reversed, oder?
Ja, nur kommen wir mit dieser Logik nicht weiter, denn das war nur die 
halbe Strecke...
Am Ende wartet der Port col auf eine Zuweisung:
  ledstate : in STD_LOGIC_VECTOR (15 downto 0);
  col : out  STD_LOGIC_VECTOR (3 downto 0));
:
alias b: std_logic_vector(0 to 3) is ledstate(3 downto 0);
:
col <= b;
Was kommt denn jetzt an col an?
Laut meiner Simulation nach wie vor ledstate(3 downto 0).
Oder wie sollte das deiner Meinung nach gehen?

Es würde nur etwas bringen, wenn dann tatsächlich auf die einzelnen Bits 
zugegriffen werden würde. So etwa:
  ledstate : in STD_LOGIC_VECTOR (15 downto 0);
  col : out  STD_LOGIC_VECTOR (3 downto 0));
:
alias b: std_logic_vector(0 to 3) is ledstate(3 downto 0);
:
col(0) <= b(0);
col(1) <= b(1);
col(2) <= b(2);
col(3) <= b(3);

Sieh dir mal den angehängten Code und den Screenshot der Simulation 
an...

> ich glaub du verwechselt hier darstellung und wert.
Ich wäre mir da wie gesagt nicht allzu sicher...

Autor: nixda (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
servus,

schon klar das das assignment 'left to 'right zuweist. und da sich das 
nie geaendert hat kommt das original raus. der alias trick hilft wenn 
man die einzelbits braucht (evtl in prozessen und beim rechnen).

braucht man den vector bei gleicher direction (to,downto) aber reversed 
kann man die funktionsloesung nehmen (siehe oben) bzw per alias + 
for_i_in_a'range.

/mfg

Autor: Der Besucher (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich denke, da wird man wohl nicht um eine reverse-Funktion herum kommen, 
oder eben "händisch" die Zuweisungen vornehmen müssen.
Aber die ganze Umordnung kostet ja in der endgültigen Schaltung nix. Nur 
Simulator und Synthesewerkzeug haben etwas mehr zu tun.

Für solche Fälle generiere ich meist ein Hilfssignal, was nur aus einem 
Buchstaben besteht und kann so meist in einer einzigen Zeile die 
Umsortierung "händisch" durchführen. Aber Vorsicht, das ist auch 
fehleranfällig.

signal a: std_logic_vector(3 downto 0);
...
a <= ledstate(3 downto 0);
col <= a(0) & a(1) & a(2) & a(3);

Nunja, nicht gerade elegant, aber es funktioniert.

Der Besucher

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das ginge jetzt auch wieder mit dem Alias:
  ledstate : in STD_LOGIC_VECTOR (15 downto 0);
  col : out  STD_LOGIC_VECTOR (3 downto 0));
:
alias b: std_logic_vector(0 to 3) is ledstate(3 downto 0);
:
col <= b(3) & b(2) & b(1) & b(0);
Damit wirds aber langsam unübersichtlich...  :-o
Denn der Schritt zum falschen
col <= b(3 downto 0);
und in letzter Konsequenz zum
col <= b;
ist nicht weit.

Autor: Patrick Lehmann (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
verbessere reverse Funktion

Vorteile:
"""""""""""
- als Eingabe kann nun auch ein z.B. STD_LOGIC_VECTOR(15 DOWNTO 8) 
benutzt werden
  FUNCTION reverse(a: STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR IS
    VARIABLE Result: STD_LOGIC_VECTOR(a'reverse_range);
  BEGIN
    FOR i IN 0 To (a'high - a'low) LOOP
      Result(a'low + i) := a(a'high - i);
    END LOOP;
  
    RETURN Result;
  END;

Autor: Patrick Lehmann (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
da ich mich leider nicht angemeldet habe muss ich wohl die Korrektur so 
posten :(
  FUNCTION reverse(a: STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR IS
    VARIABLE Temp    : STD_LOGIC_VECTOR(a'range);
    VARIABLE Result  : STD_LOGIC_VECTOR(a'reverse_range);
  BEGIN
    FOR i IN 0 To (a'high - a'low) LOOP
      Temp(a'low + i) := a(a'high - i);
    END LOOP;
  
    Result := Temp;
  
    RETURN Result;
  END;

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [vhdl]VHDL-Code[/vhdl]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.