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
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
du willst doch das synthetisieren oder? für die simulation oder was am rechner läuft, braucht man sicher nicht diese verrenkungen.
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!
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.
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 |
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!
@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
@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?
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.
> 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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.