Hallo! Ich bin relativ neu im FPGA und VHDL Bereich und bin mir in vielen Sachen noch recht unsicher: Mein Projekt ist es die Daten eines CMOS Sensors(MT9M001 ...1280x1024 a 10bit) auszuelesen und über USB (EZUSB FX2LP) an den Rechner zu senden. Als FPGA nutze ich auf einem Board (Ztex USB-FPGA 1.15b) den Xilinx Spartan6 XC6SLX75. Auf dem board ist auch ein 128MB RAM drauf. Da der Sensor ohne Unterbrechung seine Pixel schickt sobald er einen Takt bekommt und der USB Fifo zwischendurch mal voll sein könnte, müssen die Pixel zwischengespeichert werden um Datenverlust zu vermeiden. Dafür nutze ich mit dem Xilinx MIG den RAM als RingBuffer. Der BlockRAM hat ja "nur" 3096kBit und somit passen da keine ganzen Bilder rein und wenn ich nur Zeilen zwischenspeicher muss ich den Takt so langsam laufen lassen das ich die Bilder mit nur 3-4FPS auf den Rechner bekomme. Ich habe also einen Prozess, der die Pixel mit dem CMOS Takt in den RAM schreibt. Ein zweiter Prozess liest die Daten aus dem RAM mit dem USB Takt aus. Ein weiterer Prozess synchronisiert den Füllstand des RAMS zwischen dem Lese- und dem Schreibprozess. Jetzt mein Problem: Ich würde gerne noch ein bisschen Bildverarbeitung auf dem FPGA reinbauen. Zum Beispiel ein "ganz einfaches" Histogramm. Ich habe mir gedacht, dass ich im Schreibprozess in den RAM die jeweiligen Grauwerte zählen könnnte. Im Leseprozess aus dem RAM ins USB könnte ich dann Pixel im Bild mit meinem Histogramm überschreiben. Allerdings brauche ich ja, wenn ich nur ein Histogramm einer Zeile machen will schon ein Array von 1280*10bit. Bei einem ganzen Bild bräuchte ich das ganze 1024mal. Jetzt stellt sich mir die Frage ob das ganze überhaupt realisierbar ist. Die einzige Methode die mir erade einfällt wäre es, das Histogramm auch ins RAM zu schreiben. Aber wenn ich wirklich ein Histogramm eines ganzen Bildes haben will, dann müsste ich doch für jeden Grauwert, also 1024 mal, über das Bild gehen und diesen zählen was mir auch nicht sinnvoll erscheint... Ich hoffe der text war nicht zu lang und ich habe nichts wichtiges vergessen. bin euch für jeden Tip sehr dankbar :) Gruß manuel
OK bei der ganzen Aufregung,dass ich kein ganzes Bild im fpgazwischen speichern kann, habe ich vergessen,dass es einen unterschied macht ob man tatsächlich 1280*1024 10bit Werte speichern möchte oder 1024 Werte (10bit) mit denen man 1024*1280 darstellen kann
Gleich zu Beginn ein solches Projekt auszuwählen ist vlt nicht gerade die beste Idee. Aber gut, zur Kamera: MT9-Module gibt's z.B. bei EBay für ca. 20-30 Euro, allerdings mit 8Bit. Ein einfaches I2C-master-Modul reicht, um die Controller-Parameter zu setzen. (hab ich mit einem dieser Boards mal gemacht, ist kein grosser Aufwand). Zu USB: Ich kenne das TZEX-Board nicht, die USB-Ansteuerung auf dem Board scheint aber auch nicht so kompliziert sein. Aber statt USB ist vlt ein VGA als einfache Ausgabe besser/einfacher. Anleitungen für VGA-Ansteuerungen gibt's auch zu Hauf (und die Kameraparameter zu setzen ist mit I2C-master ein Klacks). Falls der FIFO überläuft: Einfach den Pixel-Takt runtersetzen und mit weniger FPS zufrieden geben.
Sigi schrieb: > Falls der FIFO überläuft: Einfach den Pixel-Takt runtersetzen > und mit weniger FPS zufrieden geben. Dann hast Du aber keine ordentlichen FPS mehr, einige Sensoren machen das Timingmässig auch nicht mit.
Hi, mit einer ähnlichen Konfiguration arbeite ich schon ne Weile. Ist recht komplex, einen zuverlässigen Bildstrom hinzukriegen. Wenn noch gar kein Framework existiert, wird das ein ganz schönes Paket. Wenns nur zum Lernen ist, würde ich mal mit einem 3x3-Filterkernel oder einem Debayer-Algo anfangen. Da kommt man schon mal ohne RAM aus. Ansonsten die Checkliste: 1) USB-FIFO-Interface 2) Sensor-Ansteuerung i2c (Soft CPU?) 3) PC-seitiges "Frame-grabbing" per USB. Wichtiges Detail: Ohne RAM-Pufferung der Bilder geht es fast nur im isochronen Transfermodus.
Hallo! Danke schonmal für die Antworten. Bin noch einmal in mich gegangen und habe die letzten Tage etwas dran gearbeitet. Wahrscheinlich ist es falsch rübergekommen aber einige Dinge funktionieren schon: Ich habe auf dem FPGA einen Ringbuffer beschrieben mit einem Adressbereich der genau 2 Bilder umfasst. Es wird also immer ein Bild vom CMOS in den DDR RAM geschrieben während das vorherige aus dem DDR RAM gelesen wird und über USB an den Rechner geschickt wird. Das ganze läuft in 2 verschiedenen Prozessen, einem Lese- und einem Schreibprozess ab. Auf dem PC kriege ich auch schon ein Livebild über ein JAVA GUI. I2C Befehle kann ich ebenfalls an ein I2C Slave Modul auf dem FPGA senden. So kann ich zum Beispiel einen Benutzerdefinierten Threshold ans FPGA schicken und der binarisiert mir dann das Bild im Leseprozess(if-Abfrage ob das gerade gelesene Pixel über oder unter dem Threshold liegt...). Jetzt ist mein Problem, dass ich gerne auf dem FPGA ein Histogramm erstellen würde. Wenn ich allerdings ein Array mit 1024 Einträgen a 21 Bit (weil eine Graustufe maximal 1280*1024 mal vorkommen kann) erstelle dauert das synthetisieren so ewig lange das ich es vorzeitig abbreche weil ich gar nicht weis ob er irgendwann mal fertig wird. Wie geht man mit so großen Datenmengen um? Das Histogramm auch ins RAM zu schreiben erscheint mir sehr kompliziert zu sein, denn wenn ich auf den ersten Eintrag zugreifen bzw. den ersten Grauwert inkrementieren will müsste ich den ja erstmal einlesen, dann inkrementieren und dann wieder ins RAM schreiben was mind. 3 Taktzyklen dauern würde?! Vielleicht hat bezüglich Histogramm und großen Datenmengen ja noch jemand einen Tip :) Besten Gruß Manuel
Manuel Ted schrieb: > Das Histogramm auch ins RAM zu schreiben erscheint mir sehr kompliziert > zu sein Da bist ja schon von selbst auf die richtige Lösung gekommen, und das ist nicht derart kompliziert wie es auf den ersten Blick scheint. Und Du sparst Dir ein riesiges FF-Grab. Richtig gepipelined solltest Du jeden zweiten Wert aus dem Bild in das Histogramm reinkriegen. Vermutlich reicht es aber auch, wenn Du noch weniger Werte berücksichtigst, und z.B. mit einem (separaten...) 1024x16-Ram auskommst. Da solltest Du Dir sowieso Gedanken machen wie genau Du's denn wirklich brauchst. Für eine simple Darstellung im Bild selbst, ohne weitere Verarbeitung, genügt Dir sicher noch weniger.
Peter K. schrieb: > Da bist ja schon von selbst auf die richtige Lösung gekommen, und das > ist nicht derart kompliziert wie es auf den ersten Blick scheint. Und Du > sparst Dir ein riesiges FF-Grab. Hallo! Die Antwort kam ja schnell! Danke! Dazu habe ich ein paar Fragen: > Richtig gepipelined solltest Du jeden zweiten Wert aus dem Bild in das > Histogramm reinkriegen. Vermutlich reicht es aber auch, wenn Du noch > weniger Werte berücksichtigst, und z.B. mit einem (separaten...) > 1024x16-Ram auskommst. Da solltest Du Dir sowieso Gedanken machen wie > genau Du's denn wirklich brauchst. Für eine simple Darstellung im Bild > selbst, ohne weitere Verarbeitung, genügt Dir sicher noch weniger. Was ist mit richtig gepipelined gemeint? Ich verstehe das jetzt so, da ich ja aus dem RAM erstmal lesen muss um einen Wert zu inkrementieren oder sonstiges den erst mal lesen muss und erst auf der zweiten Taktflanke wieder reinschreiben kann. Daher jeder 2te Pixel? Richtig! Für die simple Darstellung im Bild brauche ich eigentlich gar nicht so viele Werte weil ich die eh' nicht alle Darstellen kann. 256 pro Graustufe würden für den Anfang sicher dicke reichen. Wie ist das mit dem RAM gemeint. Extra dafür ins DDR RAM? Oder muss/kann ich mir da etwas aus den Language Templates auf Basis des Block RAMs kopieren? Habe hierzu einmal unter Device Macro Instatiation -> Spartan 6 -> RAM/ROM die BRAM_*_MACRO Sachen gefunden. und unter Synthesis Constructs ->Coding Examples -> RAM -> BlockRAM gibt's auch was. Bin nun etwas verunsichert welches ich nehmen soll aber ich habe mir jetzt auch schon den UG383 Spartan-6 Block RAM User Guide geschnappt und werde mir das mal durchlesen...
Manuel Ted schrieb: > Extra dafür ins DDR RAM? Nein, bloss nicht, bei dieser Art Operation bräuchtest Du im DDR immer mehrere (viele) Zyklen. Deshalb schreibe ich ja separat. Nimm dafür ein Block-RAM, dafür sind sie da. > Was ist mit richtig gepipelined gemeint? Synchron lesen braucht 2 Zyklen, schreiben 1 Zyklus und inkrementieren je nach Clockspeed auch noch einen Zyklus. Trotzdem kannst Du mit ein paar Kniffen erreichen, dass Du alle 2 Zyklen einen Wert bearbeiten kannst. Den Aufwand kannst Du Dir aber sparen, wenn es nicht so genau sein muss.
Wieso ausgerechnet (nur) jeden zweiten? Wenn fummeln, dann richtig. Bei einem echten looped access aufs RAM braucht man in der Regel wenigstens 3 Takte, weil das BRAM einen Takt verzögert ist und die Addition nicht voll kombinatorisch zu machen ist. 1:setadr 2:fetch 3:add 4:store 5:read Ein neues "setadr" kann frühestens beim Takt 4 kommen, weil schon im nächsten Takt dieser Wert geholt werden können muss, um aktuell zu bleiben. Man hätte also (4-1) = 3 Takte Verzögerung, erfasste also nur jeden dritten. Bei einem DP-RAM braucht man u.U. sogar 4 steps, wegen des Transparenzproblems beim write while read, erspart sich aber dafür etwas Verwaltungslogik. Ok, wenn man denn Adder irgendwie noch mit reinnimmt, wäre noch ein Takt zu sparen, aber Du brauchst so oder so immer Schattenrams und /oder parallele Architektur, es sei denn Dein FPGA-Takt ist n mal schneller, als die Daten. Wenn man es aber richtig pipelined, bekommt man natürlich jeden Wert mitgezählt. Ist natürlich ein bissl Gefummel und baucht einen pre write cache und einen post read cache sowie einen intelligenten Adder, der die Doubletten in der cache pipe erfasst. Dann geht es mit einem internen B-BRAM und aufgrund der einfacheren Verwaltung ist dann die DP-RAM Lösung kürzer.
Juergen S. schrieb: > Wieso ausgerechnet (nur) jeden zweiten? Du hast natürlich recht, es geht auch mit komplett allen Werten. Die Lösung "nur jeden zweiten" bietet m.E. aber das beste Aufwand-Ertrags-Verhältnis, wenn man es einigermassen genau will. Für diesen Fall hier aber ist die "billigste" Lösung, sprich nur jeden N-ten Wert überhaupt zu benutzen und gar nichts zu pipelinen, wahrscheinlich sowieso hinreichend.
Was spräche dagegen, jeden zweiten Wert in ein eigenes RAM zu schieben und nachher zu addieren?
Bei einem Histogramm reicht in der Regel ein repräsentativer Querschnitt, weil das, was aus einem Histogramm herauszuholen ist, nämlich z.B. der Median wenig Verwertbarkeit besitzt.
Ah Habe gar nicht gesehen, dsas hier noch mehr Beiträge gekommen sind! Danke! Ist es nicht sogar möglich jeden Wert ins Histogramm reinzunehmen indem der BRAM mit READ_FIRST Mode implementiert wird? Da ich 1024 Grauwerte und höchstens 2 Bilder im RAM habe, habe ich einen 2048 * 10 Bit BRAM mit asynchronen Ports (einer schreibt ins BRAM mit dem Takt mit dem die Pixel kommen, der andere liest vom BRAM mit dem USB Takt) inferiert(so richtig?)
1 | process(CLKA) |
2 | begin
|
3 | if ( rising_edge(clka) ) then |
4 | if ena = '1' then |
5 | doa <= RAM(to_integer(unsigned(addra))); |
6 | if ( wea = '1' ) then |
7 | RAM(to_integer(unsigned(addra))) := dia; |
8 | end if; |
9 | end if; |
10 | end if; |
11 | end process; |
12 | |
13 | process(clkb) |
14 | begin
|
15 | if ( rising_edge(clkb) ) then |
16 | if enb = '1' then |
17 | dob <= RAM(to_integer(unsigned(addrb))); |
18 | if ( web = '1' ) then |
19 | RAM(to_integer(unsigned(addrb))) := dib; |
20 | end if; |
21 | end if; |
22 | end if; |
23 | end process; |
Man fängt beim ersten Pixel an und setzt die Adresse. Beim nächsten Takt wird der Wert erhöht und der WriteEnable Pin gesetzt sowie die Adresse des nächsten Grauwertes gesetzt. Allerdings kommt man an der Stelle wahrscheinlich in einen Konflikt da vemutlich beim schreiben schon die nächste Adresse verwendet wird und nicht wie gewünscht die vom ersten Pixel. Allerdings müsste man so doch zumindest jeden zweiten Wert schreiben können. Ich kann schon Werte in meinem Bild darstellen allerdings bekomme ich komischerweise immer 16 Pixel Breite Lücken in meinem Histogramm. Ich vermute, dass das evtl. mit folgender InfoMeldung(Keine Warnung) im Design Summary zusammenhängt: Xst:1843 - HDL ADVISOR - FlipFlop HIST1_ADDRA_0 connected to a primary input has been replicated Die Meldung bekomme ich für die Adressbits 0 - 3 des BlockRAM, womit sich ja 2^4 = 16 Werte darstellen lassen. Im XST User Guide steht man soll den Max_Fanout Wert für das Projekt höher stellen, allerdings weis ich nicht was ich da einstellen soll. Der steht momentan auf 100000. Ansonsten bekomme ich nur noch eine Warnung, dass die Timings bei Async BRAM mit Read_first_mode einzuhalten sind und nicht auf beiden Ports von auf Adresse gleichzeitig gelesene/geschrieben werden darf.
Ich habe jetzt den BlockRAM mal als ipcore reingemacht und dort habe ich das gleiche Problem, allerdings ohne Infos im Design Summary. Scheint also doch evtl. an meinem vhdl design zu liegen.
Manuel Ted schrieb: > Ist es nicht sogar möglich jeden Wert ins Histogramm reinzunehmen indem > der BRAM mit READ_FIRST Mode implementiert wird? Das read first regelt nur, dass bei gleichzeitigem Lesen zuerst der alte Wert gelesen wird und dann geschrieben. > Ich kann schon Werte in meinem Bild darstellen allerdings bekomme ich > komischerweise immer 16 Pixel Breite Lücken in meinem Histogramm. Weil du immer alte Werte ausliest und sie addierst. > Ich vermute, dass das evtl. mit folgender InfoMeldung(Keine Warnung) im > Design Summary zusammenhängt: > Xst:1843 - HDL ADVISOR - FlipFlop HIST1_ADDRA_0 connected to a > primary input has been replicated Nö, das hat was mit Geschwindigkeit zu tun und dem Umstand, dass das primary FF in den IO Zellen sitzt. Im replizierten steht nichts anderes drin.
Ralf schrieb: >> Ich kann schon Werte in meinem Bild darstellen allerdings bekomme ich >> komischerweise immer 16 Pixel Breite Lücken in meinem Histogramm. > Weil du immer alte Werte ausliest und sie addierst. Und wieso sind die Lücken immer 16 Pixel Breit? Die Adresse für das BlockRAM setze ich immer über den gerade anliegenden Grauwert für das jeweilige Pixel. Müssten die Daten dann nicht "ungeordnet" im BlockRAM liegen und man würde willkürliche bzw von den Grauwerten abhängige Lücken bekommen?
Ok vielleicht mache ich auch irgendwas mit der Adressierung falsch? Wenn ich das BlockRAM einfach mit Werten vollschreibe bekomme ich keine 16 Pixel Breite Lücken. Das mache ich folgendermaßen:
1 | -- WR_IMG = 0 Erstes Bild wird geschrieben
|
2 | if ( WR_IMG = '0' ) then |
3 | -- Fülle die ersten 1024 Adressen mit dem Wert 128
|
4 | if ( HIST1_ADDRA(9 downto 0) <= 1023 ) then |
5 | HIST1_DIA <= "10000000"; |
6 | HIST1_WEA <= ( others => '1' ); |
7 | HIST1_ADDRA(10) <= WR_IMG; |
8 | HIST1_ADDRA <= HIST1_ADDRA + 1; |
9 | -- Sind die Adressen gefüllt mache nichts
|
10 | else
|
11 | HIST1_WEA <= ( others => '0' ); |
12 | end if; |
13 | -- WR_IMG = 1 Zweites Bild wird geschrieben
|
14 | else
|
15 | -- Fülle die Adressen von Bild 2 mit dem Wert 255
|
16 | if ( HIST1_ADDRA(9 downto 0) <= 1023 ) then |
17 | HIST1_DIA <= ( others => '1' ); |
18 | HIST1_WEA <= ( others => '1' ); |
19 | HIST1_ADDRA(10) <= WR_IMG; |
20 | HIST1_ADDRA <= HIST1_ADDRA + 1; |
21 | -- Sind die Adressen gefüllt mache nichts
|
22 | else
|
23 | HIST1_WEA <= ( others => '0' ); |
24 | end if; |
25 | end if; |
Das BlockRAM hat eine Tiefe von 2048 und eine Breite von 8 Bit. Da ich im externen RAM ja einen Speicherbereich "reserviert" habe in den 2 Bilder passen will ich in den ersten 1024 Adressen des BlockRAMs das Histogramm vom ersten Bild speichern und in den Adressen 1025-2048 das Histogramm vom zweiten Bild. WR_IMG = '0' heißt, dass gerade das erste Bild geschrieben wird. Ist das Bit gesetzt, wird das zweite Bild geschrieben. Folglich müsste ich doch wenn ich das oberste Bit der BRam Adresse mit dem WR_IMG Signal setze auch das Histogramm für das erste oder zweite Bild schreiben können. So bekomme ich im ersten Bild ein (den leseprozess lass ich jetzt mal außen vor) Histogramm was mir für jeden Wert eine 128 anzeigt. Für das zweite Bild eine 255... Wenn ich allerdings die Adresse über den pixelwert setze kriege ich wieder die 16 pixel breiten lücken.
1 | -- Setze die Adresse über den Grauwert
|
2 | if ( HIST1_READA = '0' ) then |
3 | HIST1_ADDRA(10) <= WR_IMG; |
4 | HIST1_ADDRA(9 downto 0) <= CAM_DD; |
5 | HIST1_READA <= not HIST1_READA; |
6 | -- schreibe den an der Adresse anliegenden Wert + 1 in die Adresse
|
7 | else
|
8 | HIST1_DIA <= HIST1_DOA + 1; |
9 | HIST1_WEA <= ( others => '1' ); |
10 | HIST1_READA <= not HIST1_READA; |
11 | end if; |
Juergen S. schrieb: > 1:setadr > 2:fetch > 3:add > 4:store > 5:read Hier habe ich ja nur: 1: setadr 2: fetch,add,store Ist das viellecht der Grund? Wenn ja wieso?
:
Bearbeitet durch User
Ok sry... ich sehe gerade, dass wenn ich einfach ein Software Histogramm vom gespeicherten bild mache auch schon die Grauwerte welche die 16 Pixel breiten Lücken verursachen zu fehlen scheinen. Also schein es irgendwo an der Hardware zu liegen. Tut mir leid das ich den Thread wieder hochgeholt habe. Ich mache mich jetzt erstmal auf die Suche nach dem Fehler ;)
Dein Input ist nicht normal verteilt. Was Dein VDHL tut, sollte man simulieren können.
Die äquidistanten Lücken kamen daher, dass Bit 4 vom CMOS Sensor auf meinem Board nicht richtig angelötet war. Nächstes Problem : Ich möchte die Werte des Histogramms auf den Wert 255 normieren damit ich diese venünftig darstellen kann. Allerdings ist das mit dem teilen und multiplizieren auf einem FPGA ja nicht so einfach. Selbst wenn ich nur die Daten verarbeiten will für eine Kantendetektion oder so muss ja vermutlich auch irgendwo mal geteilt werden. Wenn ich einfach bei 255 aufhöre den jeweiligen Grauwert zu zählen, ist bei einem 1280*1024 großem Bild je nachdem was man aufnimmt fast jeder Grauwert bei 255. Vielleicht ist eine "quick&dirty" Lösung einfach das rechtsschieben von Bits was ja einer Division von 2 entspricht... hmhmhm :-)
:
Bearbeitet durch User
> Vielleicht ist eine "quick&dirty" Lösung einfach das rechtsschieben von > Bits was ja einer Division von 2 entspricht... hmhmhm :-) bzw. nur die oberen 8 Bit verdrahten, dann mußt du nicht mal schieben
Ja das wäre auch eine Idee! Gibt es eine Möglichkeit über Attribute wie 'length oder so rauszufinden welches das höchste gesetzte Bit bei einem std_logic_vector ist? Dann könnte ich die Darstellung immer ab diesem Bit + den nächsten 7 Bit für den jeweiligen Grauwert machen.
Während der Synthese kann man das prüfen und optimieren lassen, zur Laufzeit geht das nur durch einen priority decoder.
Hallo! Wie wird das Teilen denn bei den "Profis" gemacht? Fast jeder Filter, etc braucht doch Divisionen. Wird das dann wirklich mit so einem Radix-2 Teiler gemacht? Wenn ich das richtig verstanden habe, dauert bei einer Division die Verzögerung des Ergebnisses so lange wie die Anzahl der Bits des Dividenden. Das würde für eine Bearbeitung eines 1280*1024 Bildes und 8 Bit Pixeln bzw. Dividend bei 200 MHz doch "schon" 50ms Sekunden bedeuten. Das wärde in meinem Fall eine Halbierung der Framerate :( Will man jetzt die Nachbarn von einem Pixel betrachten stelle ich mir das auch ziemlich schwer vor, da man die Pixeldaten ja Stück für Stück aus dem Ram holt. Ist das ganze wirklich so kompliziert? Ich habe keine Ahnung von Pico-/Microblaze oder sogar DSPs aber geht das damit evtl. "einfacher" ?
Manuel Ted schrieb: > Das würde für eine Bearbeitung eines 1280*1024 Bildes und 8 Bit Pixeln > bzw. Dividend bei 200 MHz doch "schon" 50ms Sekunden bedeuten. > Das wärde in meinem Fall eine Halbierung der Framerate :( Du rechnest bei 8-bit Auflösung mal mit 8 Cycles. Wenn Du nun jeden Eintrag deines Histogramms durch den Maximalwert teilst, ergibt das dann 1024 * 8 = 8192 Cycles, bei 200 MHz sind das ~41 us. Wenn Du Double-Buffering betreibst, reduziert sich Deine Framerate überhaupt nicht.
Schon... meine Rechnung bezog mich aber auf einen Algorithmus bei dem jeder Pixel geteilt werden muss. Scheint aber alles schmarrn zu sein: Anscheinend macht man es so, dass man die Divisionen so "pipelined", dass diese für die Pixel Parallel ablaufen. Also man startet bei Pixel 1, macht mit einer weiteren Division bei Pixel 2 weiter und wenn man bei Pixel 8 ist, ist die Division für Pixel 1 (fast) fertig. Am Ende vom Bild hat man dann nur eine Verzögerung von 8 Taktzyklen.
Genau so macht man es. Die schrittweise Division wird nicht sequenziell nach und nach ausgeführt, sondern jede Rechenstufe exisitert real. Ist im Prinzip so wie bei Opel am Band. Jeder Arbeiter macht einen Schritt und zwar immer denselben, am Ende ist die Karre fertig und derletzte gibt das Ergebnis aus. Und dann kommt General Motors und behauptet, die pipeline ist zu lang, braucht zuviel Strom und fordert Beihilfen, die die hessische Landesregierung bereitwillig rausgibt.
Manuel schrieb: > Scheint aber alles schmarrn zu sein: > Anscheinend macht man es so, dass man die Divisionen so "pipelined", > dass diese für die Pixel Parallel ablaufen. Das mit dem "Schmarrn" greift etwas zu kurz. Wenn Dein Ausleseprozess schnell genug ist und Du daneben die Zeit zur Verfügung hast, machst Du es mit nur einer Instanz, wenn es möglichst schnell gehen muss nimmst Du N parallele Instanzen. Ist immer ein Tradeoff: Eines kostet weniger FPGA-Resourcen (& allenfalls Strom), das andere weniger Zeit.
:
Bearbeitet durch User
Manuel Ted schrieb: > Gibt es eine Möglichkeit über Attribute wie 'length oder so rauszufinden > welches das höchste gesetzte Bit bei einem std_logic_vector ist? So einfach ist das zur Laufzeit nicht: http://www.lothar-miller.de/s9y/archives/55-Finde-das-MSB.html
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.