Forum: FPGA, VHDL & Co. Bits vertauschen


von Dirk (Gast)


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:
1
entity ledmatrix is
2
    Port ( ledstate : in  STD_LOGIC_VECTOR (15 downto 0);
3
           clk : in  STD_LOGIC;
4
           row : out  STD_LOGIC_VECTOR (3 downto 0);
5
           col : out  STD_LOGIC_VECTOR (3 downto 0));
6
end ledmatrix;
7
8
9
col(0) <= ledstate(3);
10
col(1) <= ledstate(2);
11
col(2) <= ledstate(1);
12
col(3) <= ledstate(0);

von Der Besucher (Gast)


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

von nixda (Gast)


Lesenswert?


von Hagen R. (hagen)


Lesenswert?

1
process(ledstate)
2
begin
3
  for i in 0 to ledstate'high loop
4
    col(i) <= ledstate(ledstate'high - i);
5
  end loop;
6
end process;

Gruß Hagen

von Hagen R. (hagen)


Lesenswert?

1
-- nicht getestet !!
2
3
function reverse(input: std_logic_vector) return std_logic_vector is
4
  variable output: std_logic_vector;
5
begin
6
  for i in 0 to input'high loop
7
    output(i) := input(input'high -i);
8
  end loop;
9
  return output;
10
end reverse;
11
12
-- test
13
  col <= reverse(ledstate);

Gruß Hagen

von Boris M. (borism)


Lesenswert?

Die Frage lautete doch:

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

von SuperWilly (Gast)


Lesenswert?

Es gibt eine nette reverse-Funktion in VHDL:
1
function reverse(p: std_logic_vector) return std_logic_vector is
2
variable temp: std_logic_vector(p'reverse_range);
3
variable result: std_logic_vector(p'range);
4
begin
5
   for i in p'range loop
6
      temp(i) := p(i);
7
   end loop;
8
   
9
   result := temp;
10
11
return result;
12
end;

SuperWilly

von nixda (Gast)


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

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


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.
1
ledstate : in STD_LOGIC_VECTOR (15 downto 0);
2
col : out  STD_LOGIC_VECTOR (3 downto 0));
3
4
col(0) <= ledstate(3);
5
col(1) <= ledstate(2);
6
col(2) <= ledstate(1);
7
col(3) <= ledstate(0);

von nixda (Gast)


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

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Angehängte Dateien:

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:
1
  ledstate : in STD_LOGIC_VECTOR (15 downto 0);
2
  col : out  STD_LOGIC_VECTOR (3 downto 0));
3
:
4
alias b: std_logic_vector(0 to 3) is ledstate(3 downto 0);
5
:
6
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:
1
  ledstate : in STD_LOGIC_VECTOR (15 downto 0);
2
  col : out  STD_LOGIC_VECTOR (3 downto 0));
3
:
4
alias b: std_logic_vector(0 to 3) is ledstate(3 downto 0);
5
:
6
col(0) <= b(0);
7
col(1) <= b(1);
8
col(2) <= b(2);
9
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...

von nixda (Gast)


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

von Der Besucher (Gast)


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

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

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

von Patrick Lehmann (Gast)


Lesenswert?

verbessere reverse Funktion

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

von Patrick Lehmann (Gast)


Lesenswert?

da ich mich leider nicht angemeldet habe muss ich wohl die Korrektur so 
posten :(
1
  FUNCTION reverse(a: STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR IS
2
    VARIABLE Temp    : STD_LOGIC_VECTOR(a'range);
3
    VARIABLE Result  : STD_LOGIC_VECTOR(a'reverse_range);
4
  BEGIN
5
    FOR i IN 0 To (a'high - a'low) LOOP
6
      Temp(a'low + i) := a(a'high - i);
7
    END LOOP;
8
  
9
    Result := Temp;
10
  
11
    RETURN Result;
12
  END;

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.