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


von AxelMeineke (Gast)


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.

von Stefan M. (Gast)


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.

von Patric (Gast)


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.

von Stefan M. (Gast)


Lesenswert?

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

von FPGA-User (Gast)


Angehängte Dateien:

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

von AxelMeineke (Gast)


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?

von FPGA-User (Gast)


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 ;-)))

von AxelMeineke (Gast)


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 :-)

von Hagen (Gast)


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

von FPGA-User (Gast)


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.

von FPGA-User (Gast)


Lesenswert?

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

von Hagen (Gast)


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

von André Kronfeldt (Gast)


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é

von Hagen (Gast)


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

von FPGA-User (Gast)


Lesenswert?

Wow, so viele Downloads, vielleicht sollte ich sowas verkaufen ;-))))))

von ups (Gast)


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.

von ups (Gast)


Lesenswert?

natürlich seriell aufaddieren....

von André Kronfeldt (Gast)


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é

von AxelMEineke (Gast)


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

von AxelMEineke (Gast)


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.

von FPGA-User (Gast)


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 !

von AxelMEineke (Gast)


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?

von FPGA-User (Gast)


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.

von FPGA-User (Gast)


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)

von AxelMEineke (Gast)


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 :-)

von Hagen (Gast)


Angehängte Dateien:

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

von Hagen (Gast)


Angehängte Dateien:

Lesenswert?

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

Gruß Hagen

von FPGA-User (Gast)


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.

von Hagen (Gast)


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

von FPGA-User (Gast)


Lesenswert?

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

von Hagen (Gast)


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

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.