www.mikrocontroller.net

Forum: FPGA, VHDL & Co. einsen im Vektor zählen


Autor: AxelMeineke (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo.
Ich habe momentan eine Problemstellung mit deren eigenen Lösung ich
nicht so ganz zufreiden bin. Evtl hat eibner von euch ja eine
elegantere Lösung für mich.
Ich habe einen Vektor der 256 Bit groß ist. Der Vektor ist
Charakterischtisch immer so aufgebaut das zu beginn ein oder mehrere
Nullen stelen. Gefolg werden sie von mehreren einsen und am ende stehen
wieder nullen. Die Verhältnisse variieren aber immer. Es ist quasi ein
Impuls mit variabler länge. Ich muss nun die Anzahl der einsen
bestimmen. MEine Idee war nun, die Daten über ein Schiebegister in
einen Seriellen Datenstrom umzuwandeln, und dann die anzahl der
aufeinanderfolgenden einsen zu zählen. Das ist abllerdings eine sehr
zeitaufwendige angelegenheit 256 bits zu schieben.
Gibt es keine lösung, um die einsen im Vektor aufzuaddieren? Oder hat
jemand eine ganz andere Idee??
Danke für eure Hilfe.

Autor: Stefan May (smay4finger)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du könntest alle Bits mit einem XOR zusammenschalten. Bei 256 bit kommt
da aber eine Menge Logik zusammen. Die Laufzeiten dürften auch nicht
unerheblich sein.

ciao, Stefan.

Autor: Patric (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Alle Bits XOR-verknüpft ergibt aber doch die Parität. Wie willst du
damit auf die genaue Anzahl kommen?

IMHO sollte das mit einem SR dessen Ausgang auf den EN-Eingang eines
Zählers geht am einfachsten zu realisieren sein.

Autor: Stefan May (smay4finger)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ach sorry. Da habe ich nicht genau genug gelesen. :-)

Autor: FPGA-User (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
das ist doch endlich mal eine richtig schöne Frage mit
unendlich vielen Realisierungsmöglichkeiten in VHDL,
das ist ernst gemeint.
Da kann man mal sehen, was in VHDL so geht, mit Schematics
wäre das ziemlich umständlich.

Die Funktion lässt sich komplett kombinatorisch realisieren,
mit weniger als 40 Zeilen VHDL, ohne jedes Flip-Flop.
Nachteil : extrem groß, also in diesem Punkt keine Konkurrenz
zur SRG-Variante, dafür aber in knapp 200 ns fertig mit
zählen !
Das Ding braucht 1285 (!) Logikelemente in einem Cyclone II,
EP2C20F484, immerhin 6% von diesem Baustein,
Details + Screenshot von der Simulation s. Anhang,
m.E. ein gutes Bsp. für die Verwendung von Funktionen in VHDL

PS:
hier lässt sich sicher noch was optimieren, wenn man der Synthese
etwas auf die Sprünge hilft, ich denke Reduktion auf 1/4 ist drin

Autor: AxelMeineke (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Puh... super.
Das ist eine gute Idee. Ich werde das gleich mal imlementieren. Ich
hoffe ich oute mich jetzt nicht als absolutet noob, aber wie
funktioniert die Übergabe von "din" in der entity zu "imp"?
Verknüpft VHDL den ersten eintrag im funktionsaufrum mit dem ersten
eintrag in dr entity? Oder schaut er welcher Vektor bei der größe in
frage kommt?

Autor: FPGA-User (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
din wird in Zeile 35 als Argument an die Funktion f1
übergeben (zugegeben ein blöder Name, man sollte da was
sinnvolles nehmen), in f1 werden die 1sen gezählt
und das Ergebnis als integer zurückgegeben.
in Zeile 35 erfolgt dann gleichzeitig die Konvertierung
zurück auf std_logic_vector.

Bei der Wärme macht das aber schon 'ne Kiste Eis ;-)))

Autor: AxelMeineke (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das ist der Hammer. Ich denke ich muss noch ein bisschen üben, das ich
das mal eben so aus dem ärmel schütteln kann. Respekt und Anerkennung.
Na mal schauen wie ich das wieder gutmachen kann. Aber jetzt bin ich
mir auch im klaren darüber, warum ich VHDL so interessant finde. Da
kann man immer wiedr feststellen das 1001 wege nach Rom führen, und
meine nie die beste ist :-)

Autor: Hagen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@FPGA-user:

wie würde sich der Resourcenverbrauch ändern wenn man deine Funktion
splittet. Also man hat eine Funktion die nur 128 Bit zählen, dies ruft
aber intern für zwei Teile a 64 Bit eine Funktion auf die nur 64Bit
große Vektoren zählen, diese wiederum zweimal eine Funktion für 32Bit
usw. usw. D.h. ein sogenanntes Binary Splitting. Ziel wäre es das der
Fitter bei der Synthese nun die Möglichkeit bekommt gleiche
Funktionsblöcke zu rationalisieren.

Wäre sowas von Erfolg gekrönnt ?

Gruß Hagen

Autor: FPGA-User (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Hagen
das wäre eine Variante der Optimierung. Gleiche Funktionsblöcke
allein werden evt. nicht viel bringen. Meine Idee wäre,
eine Funktion zu schreiben, die mit einer Look-Up Table
4 Input-Bits in eine 3 bit Binärzahl wandelt, das wären
bei 256 bit = 64 Look-Up-Tables. Die 64 Ergebnisse müsste
man dann mit einem Adder-Tree schrittweise auf das Endergebnis
mit 9 bit aufaddieren. Das wären dann 32 + 16 + 8 + 4 + 2 + 1 = 63
Addierer mit jeweils 2 Eingängen, wobei sich die Bitbreite in
jeder Addierer-Stufe um 1 erhöht.
Nur so ne Idee, keine Ahnung wieviel LEs das am Ende bringt,
die Synthese ist manchmal unergründlich.

Autor: FPGA-User (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sorry, sind natürlich 3 * 64  = 192 Look-Up-Tables in der 1.Stufe
- die Wärme ..........

Autor: Hagen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hm, ich habe nochmal drüber nachgedacht. Mein Vorschlag wird nichts
bringen wenn man davon ausgeht das in parallel die kompletten 256 Bits
mit einmal ausgerechnet werden müssen. Denn dann muß die Synthese immer
ein Resultat bringen das die 256 Bits eben parallel berechnen.

Wenn ich das richtig verstanden habe so arbeiten die Fitter immer mit
den gleichen Regeln für die Optimierung von Boolschen Operationen. Ihre
Matrix Optimierung findet immer die kompakteste Boolsche Verknüpfung für
eine vorgegebene Formel. Ergo: sollte das Design komplett kombinatorisch
gelösst werden müssen so meine ich das egal welcher VHDL Source benutzt
wird immer fast identisch viele LE's drauf gehen werden. Erst eine
synchron getaktete Lösung könnte den Resourcenverbrauch reduzieren, da
dann immer Stückchenweise zb. 32Bits ausgewertet werden, dann aber eben
in 8 Takte nacheinander.

Gruß Hagen

Autor: André Kronfeldt (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

ich bin zwar auch ein Anfänger, möchte aber meinen Senf auch noch
dazugeben ;-)

Wie wäre es 2 Zähler durchlaufen zu lassen?
Einer von Vorne und einer von Hinten.
Sobald beide eine '1' gefunden haben, kann
man Hinten-Vorne berechnen und hat die Anzahl.
Geht das? Wäre maximal 1/2 Laufzeit.

2. Optimierung (Laufzeit). Wenn ZHinten<ZVorne, dann Anzahl = 0

Grüße,
André

Autor: Hagen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sobald du Zähler benutzt hast du ein synchrones Design und kein
kombinatorisches. Die Laufzeit des kombinatorischen Design ist im
Vergleich zu einem Synchronen -> sofort. Mal abgesehen von den Gatter
Laufzeiten. Die obigen Vorschläge zielten immer auf ein kombinatorische
Design ab, sprich man legt vorne 256 Bits an und hinten kommt über die
verschiedenen Gatter sofort die Anzahl der gesetzten Bits raus.

Meiner Meinung nach lässt sich das wirklich nur über ein synchrones
Design, das somit mehrere takte benötigt, mit weniger Resourcen
bewerkstelligen.

Gruß Hagen

Autor: FPGA-User (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wow, so viele Downloads, vielleicht sollte ich sowas verkaufen ;-))))))

Autor: ups (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ja wenn es was umsonst gibt :-)

also ich denke wenn man das in hardware realisieren will müsste man
wirklich erstmal wissen wie viel zeit man für die auswertung
verbrauchen darf. je nachdem wieviele takte zur verfügung stehen würde
ich das signal entsprechend zerlegen und die einsen jeweils
aufaddieren.

Autor: ups (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
natürlich seriell aufaddieren....

Autor: André Kronfeldt (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

so. Nachdem ich wieder nüchtern bin und ausgeschlafen habe, möchte ich
kurz anmerken daß meine Idee für die Tonne ist. Die verbraucht mehr
Resourcen und ist im Worst-Case auch nicht schneller als ein
Schieberegister.

Vielleicht kann man was optimieren, wenn man weiß woher der Vektor
kommt und mit welcher Länge der Impuls mindestens/höchstens vorliegt.

Grüße,
André

Autor: AxelMEineke (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi ich bin es noch mal ... die anderen Zuweisungen habe ich wohl
verstanden, aber was mir nicht klar ist, ist die Zuweisung von "din"
zu "inp". Woher weiss die Funktion das "inp" die werte von "Din"
repräsentiert? Ich sehe nirgendwo so etwas wie inp <= din oder so. Wenn
mir das noch ein mal einer verklickern könnte... Danke

Autor: AxelMEineke (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich frage auch so genau, da der Vektor mit den 256 Bit in meinem fall
ein Signal ist und nicht in de entity enthalten ist. Daher habe ich
bedenken ob das dann auch funktioniert. Deswegen wollt ich so genau
wissen wie die Werteübergabe stattfindet.

Autor: FPGA-User (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
das funktioniert schon, keine Angst, nimm einfach bitcount
als Component in Deinen Code rein, leg das Signal an din
an und das Ergebnis bekommst Du an sum_1 geliefert.

wenn du schonmal z.B. in C programmiert hast, dann sollte das
mit der Funktion nichts besonderes sein. Es wird eine Funktion
deklariert, die einen Parameter übergeben bekommt. In der Funktion
heisst dieser eben <inp>. Wie nun das Signal heisst, das Du beim
Aufruf von f1 übergibst, ist völlig wurscht, Hauptsache es ist
vom TYP den die Funktion erwartet !

Wo ich damals als Einsteiger viel länger fürs Verständnis gebraucht
habe ist der Punkt, dass in der Funktion eine Loop mit einer
Zählvariablen steht, in Hardware wird aber kein einziger Zähler,
nichtmal ein Flip-Flop generiert ! Ich finde es extrem stark, dass
man in VHDL Kombinatorik so abstrahieren kann !

Autor: AxelMEineke (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das geht ja leider nicht. Ich kann keinen 256 Bit großen Vektor in einem
Stück an eine komponente übergeben. Dann meckert das webpack. In dem
Design Summary steht bei boundet IOB maximum von 173. Deswegen habe ich
diesen langen Vektor in einzelnen 32er blöcken die hinereinander
getaktet werden übertragen. in diese Komponente werden die dann mit
hilfe von addressen wieder aneinander . Somit steht mir der lange
Vektor nicht in der entity zur verfügung, sondern nur als Signal,
nachdem ich dn Vektor wieder zusammengebaut habe. Was kann ich denn da
machen?

Autor: FPGA-User (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
also steht der Vektor im FPGA komplett mit 256 bit zur Verfügung
oder nicht ?

JA)
wo ist das Problem?

NEIN)
umso besser, dann schreib die Funktion einfach für 32 bit oder so
um und addiere die Ergebnisse auf, dann brauchst halt 8 Takte
bis das Ergebnis da ist

aus Deinem letzten Satz hätte ich gefolgert, dass das Signal
komplett vorhanden ist. Dann sind doch keine IOBs erforderlich
oder was meinst Du mit IOB Maximum 173 ???
Dass der Vektor bei mir über IOBs rausgeht ist doch nur ein
Besipiel, um mal schnell eine Synthese zu machen.

Autor: FPGA-User (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
noch ne Idee, wenn da eine Beschränkung des WebPack vorliegt,
dann kopier die Funktion doch in Deine Sourcen rein, an den
Anfang der Architecture, und ruf sie dann einfach auf, warum
geht das nicht ?(habe hier nur die ALTERA Software, kein WebPack)

Autor: AxelMEineke (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Argh... jetzt hab ich es glaub ich verstanden... sorry das ich so
generft hab. Ich schiebs einfach mal auf das Wetter :-)


Danke ich denke es klappt nun :-)

Autor: Hagen (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Anbei mal mein Versuch eine teilsynchrone Lösung zu bauen. Du kannst im
VHDL in den Generics alles konfigurieren. Über InputWidth die Größe des
Input Vektors und über SliceWidth die Anzahl der Bits die aus dem Input
Vektor pro Takt als kombinatorische Berechnung berechnet werden
sollen.

Interessant ist nun das du über SliceWidth die Synthese derart
beeinflussen kannst das entweder wenige LE's verbraucht werden dafür
aber mehr Takte benötigt werden, oder sehr viele LE's benötigt werden
dafür aber die maximal möglich Taktgeschwindigkeit sich wieder
reduziert.

Man muß also tatsächlich eine Kompromiss finden zwischen LE Verbrauch
und benötigter Zeit pro kombinatorische Berechnung. Je größer
SliceWidth gewählt wird um so mehr LE's werden verbraucht und um so
geringer muß die Taktfrequenz von Clock sein. Je kleiner SliceWidth
gesetzt wird um so mehr Takte benötigt man, verbracht weniger LE's und
die Taktfrequenz kann höher gewählt werden.

Gruß Hagen

Autor: Hagen (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
anbei mal ein Screenshot aus der Simulation von Quartus II mit
SliceWidth := 16;

Gruß Hagen

Autor: FPGA-User (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Hagen
nicht schlecht, da hast Du Dir einige Arbeit gemacht.
Kleine Kritik sei erlaubt : Im Extremfall bei 1 bit SliceWidth
dürfte bei Deiner Version ein 256 zu 1 Multiplexer rauskommen,
für den Fall wäre ein Schieberegister vermutlich effektiver.

Autor: Hagen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja, das dachte ich mir auch schon. Allerdings lässt sich so einigermaßen
der Effekt von SliceWidth auf den Verbracuh von LE's und der nötigen
Gatterlaufzeit der kombinatorischen Logik vergleichen. Ich werde sogar
das Ding mal unter Xilinx WebPack und Quartus II für verschiedene
FPGA's austesten, nur so zum Vergleich.

Ansonsten noch Verbesserungen oder Kritiken ? ich bin auch nur
Anfänger.

Gruß Hagen

Autor: FPGA-User (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ansonsten top, ordentlicher Stil, alles schön eingerückt,
einheitliche Notation, mit das beste VHDL, was ich so im
Forum gesehen hab

Autor: Hagen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke fürs Kompliment, die Sauberkeit entwickelt man nach 20 Jahren als
Profiprogrammierer. Nur, leider hilft das bei der "Programmierung"
von FPGA/CPLD nicht so viel weiter. Ich habe einige Programmiersprachen
für normale PC's erlernt und dies ging eigentlich immer schneller. Der
Einstieg auf FPGAs/CPLDs ist wohl in letzter Zeit das härteste Brot
beim Erlernen einer neuen Programmiersprache für mich.

Zb. mit obigem VHDL: alles fertig, alles schein logisch korrekt zu sein
nur bei der Simlation zeigte sich das der Code die untersten 8 Bits des
256 Bit Inputs immer doppelt gezählt hat. Ich habe mindestens 4 Stunden
benötigt um zu erkennen das meine Clockfrequenz schneller als die
internen Gatterlaufzeiten waren ! Nach Reduktion der Taktfrequenz gings
auf einmal. Ich hasse das wenn man in einer Programmmiersprache noch
nicht routiniert ist und jedesmal bei Problemen wie der Ochse vorm
Scheunentor rumgrübelt.

Also nichts für ungut, guter Stil hin&her, aber das nützt nichts wenn
man es immer noch nicht voll begriffen hat ;)

Gruß Hagen

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.