Forum: FPGA, VHDL & Co. Bitlänge ungleich Null bestimmen "length?"


von Student FH Köln (Gast)


Lesenswert?

Hallo zusammen,

ich arbeite momentan an meiner Diplomarbeit und habe folgendes Problem 
in VHDL.
Ich möchte die Länge eines Vektors überprüfen (Std_Logic_Vector oder 
Bit_Vector). Mit dem Befehl "length" kann man meines Wissens die gesamte 
Länge eines Vektors auslesen. Mich interessieren allerdings nicht die 
vorstehenden Nullen, sondern nur die Länge ab der ersten 1.

Beispiel:

 Vector X1 = ...00 0000 0111 --> als Ergebnis hätte ich gerne die Zahl 3
 Vector X2 = ...00 0011 0101 --> als Ergebnis hätte ich gerne die Zahl 6

Eine Lösung wäre, von links alle Bits abzufragen und sobald das Erste 
ungleich 0 ist könnte man über eine Zählschleife die Position ermitten. 
Da mein Programm aber sehr schnell arbeiten muss, habe ich maximal 4 
Takte für die Aufgabe zur verfügung und somit wäre eine Schleife zu 
langsam.

Kann mir vielleicht jemand einen Tipp geben, wie ich dieses Problem 
schneller lösen könnte?

MfG

Christoph

von spartanne (Gast)


Lesenswert?

Wie lang sind die Vektoren?

von Daniel -. (root)


Lesenswert?

vielleicht eine binäre Suche nach der Art

links[n:1],rechts[n:1] <= vec[2n:1]);

when ODER(links) = '1' =>
links[n/2:1],rechts[n/2:1] <= links[n:1]

when ODER(rechts) = '1' =>
links[n/2:1],rechts[n/2:1] <= rechts[n:1]

irgendwie in die Zustände einer State Machine abbilden.

16 bit vector = 2**4 => 4 Takte

von Daniel -. (root)


Lesenswert?

du willst doch das synthetisieren oder?
für die simulation oder was am rechner läuft, braucht man
sicher nicht diese verrenkungen.

von Christoph (Gast)


Lesenswert?

Die Vektoren sind 32 Bit lang und sie müssen synthetisieren werden. 
Deinen Vorschlag durchschaue ich zwar heute abend nicht mehr auf anhieb, 
werde das morgen aber ausprobieren!

von Martin (Gast)


Lesenswert?

Wenns schnell gehen muss dann Bau halt soetwas wie einen Priority 
Encoder.

so in der Art
1
if (vector(0) = '1') then
2
  out <= "0001";
3
end if
4
5
if (vector(1) = '1') then
6
  out <= "0010";
7
end if

Das kostet zwar ein bisschen Logik geht aber auf jeden Fall in einem 
Takt.

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


Lesenswert?

Kürzer geschrieben ginge es etwa so:
1
entity MSB is
2
    Port ( data : in  STD_LOGIC_VECTOR (31 downto 0);
3
           msb1 : out  STD_LOGIC_VECTOR (4 downto 0));
4
end MSB;
5
6
architecture Behavioral of MSB is
7
signal msbint1 : integer range 0 to 31;
8
begin
9
  msbint1 <= 31 when data(31)='1' else
10
             30 when data(30)='1' else
11
             29 when data(29)='1' else
12
             28 when data(28)='1' else
13
                 :
14
              4 when data( 4)='1' else
15
              3 when data( 3)='1' else
16
              2 when data( 2)='1' else
17
              1 when data( 1)='1' else
18
              0;
19
20
   msb1 <= std_logic_vector(to_unsigned(msbint1,msb1'length));
21
end Behavioral;
Das ergibt dann eine recht aufwendige Kombinatorik:
1
Selected Device : 3s50pq208-5 
2
 Number of Slices:                      23  out of    768     2%  
3
 Number of 4 input LUTs:                40  out of   1536     2%  
4
:
5
 Maximum combinational path delay: 19.263ns



Kompakter liest sich eine For-Schleife:
1
   process (data) 
2
   variable foundbit : std_logic;
3
   begin
4
      foundbit := '0';
5
      msbint2 <= 0;
6
      for i in 31 downto 0 loop
7
         if (data(i)='1' and foundbit='0') then 
8
            msbint2  <= i;
9
            foundbit := '1';
10
         end if;
11
      end loop;
12
   end process;
13
  
14
   msb2 <= std_logic_vector(to_unsigned(msbint2,msb2'length));
Aber das Ergebnis ist suboptimal, weil die for-Schleife weiter 
durchlaufen wird, auch wenn eine '1' gefunden wurde:
1
Selected Device : 3s50pq208-5 
2
 Number of Slices:                      51  out of    768     6%  
3
 Number of 4 input LUTs:                87  out of   1536     5%  
4
  :
5
 Maximum combinational path delay: 24.339ns



Dritter Versuch: eine While-Schleife.
1
   process (data) 
2
   variable i : integer range 0 to 31;
3
   begin
4
      i := 31;
5
      while (data(i)='0') loop 
6
         i := i-1;
7
      end loop;
8
      msbint2 <= i;
9
   end process;
10
  
11
   msb2 <= std_logic_vector(to_unsigned(msbint2,msb2'length));
Damit lässt sich auch in der Laufzeit (auf Kosten einiger Slices) noch 
was holen:
1
Selected Device : 3s50pq208-5 
2
 Number of Slices:                      28  out of    768     3%  
3
 Number of 4 input LUTs:                47  out of   1536     3%  
4
  :
5
 Maximum combinational path delay: 18.821ns



Eine For-Schleife mit EXIT sieht so aus:
1
   process (data) 
2
   begin
3
      msbint2 <= 0;
4
      for i in 31 downto 0 loop
5
         if (data(i)='1') then 
6
            msbint2 <= i;
7
            exit;
8
         end if;
9
      end loop;
10
   end process;
11
12
   msb2 <= std_logic_vector(to_unsigned(msbint2,msb2'length));
Hier wird exakt die selbe Logik wie mit dem auscodierten Encoder 
erzeugt:
1
Selected Device : 3s50pq208-5 
2
 Number of Slices:                      23  out of    768     2%  
3
 Number of 4 input LUTs:                40  out of   1536     2%  
4
  :
5
 Maximum combinational path delay: 19.263ns

von christian (Gast)


Lesenswert?

Bei den ganzen For- und While-Schleifen wird nur die Bedingung, das 
Ganze in vier Takten zu lösen, nicht eingehalten.
Ich würde das ganze parallel mit If aufbauen:
1
if data(31) = '1' then
2
msb1 = b"11111";
3
elsif data(30) = '1' then
4
msb1 = b"11110";
5
...

oder nach dem ersten Beispiel von Lothar Miller, was ich fast noch 
schöner finde.

Bei wem schreibst du denn die Diplomarbeit. Hab letztes Jahr an der 
FH-Köln meinen Abschluß gemacht.
Viel Erfolg!

von Duke Scarring (Gast)


Lesenswert?

@christian:
> Bei den ganzen For- und While-Schleifen wird nur die Bedingung, das
> Ganze in vier Takten zu lösen, nicht eingehalten.
Du hast das Konzept der Schleifen in VHDL und paralleler Hardware noch 
nicht verstanden.

Die Beispiele von Lothar dauern genau einen Takt, wenn der im besten 
Fall nicht schneller als 18.821ns ist.

Duke

von christian (Gast)


Lesenswert?

@Duke:
> Du hast das Konzept der Schleifen in VHDL und paralleler Hardware noch
> nicht verstanden.
Sieht so aus :-). Ich komm eigentlich aus der Programmierung. Ich dachte 
schleifen laufen auch in VHDL sequentiel ab, oder liegt das daran, daß 
der Prozess nicht geclockt ist?

von Martin K. (mkohler)


Lesenswert?

christian wrote:
> Ich komm eigentlich aus der Programmierung.
Echt? Hätten wir nie gedacht ;-)

> Ich dachte schleifen laufen auch in VHDL sequentiel ab,
Ja, das ist ein typischer Anfängerfehler

> oder liegt das daran, daß > der Prozess nicht geclockt ist?
Nein, das liegt daran, dass mit VHDL Hardware (Gatter, Register, usw.) 
beschrieben wird und nicht ein Stück Ablaufsoftware.

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


Lesenswert?

> Bei den ganzen For- und While-Schleifen wird nur die Bedingung, das
> Ganze in vier Takten zu lösen, nicht eingehalten.
Wie Duke es schon gesagt hat, ist das Ganze absolut taktlos.
Entweder läuft das Design mit 50MHz, dann ist es nach 1 Takt fertig.
Oder das Design läuft mit 200MHz, dann braucht dieser "MSB-Sucher" 
meherer Zyklen (Multi-Cycle) und ist in 4 Takten fertig.

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.