Hallo, ich möchte ein Bild (28x28 in BMP-Format) in den SDRAM schreiben und vom SDRAM zum VGA-Monitor ausgeben. Dazu habe ich das Bild in HEX-Daten konvertiert und in eine Textdatei kopiert. Als Test möchte ich zuerst 512 Bytes lesen und in SDRAM schreiben. Ich möchte also die Daten von der Textdatei lesen und in den SDRAM schreiben aber das funktioniert nicht (die Daten werden in den SDRAM nicht gechrieben). Ich habe es mit dem ILA von Quartus geprüft. 1. Frage: Wo machte ich denn der Fehler? 2. Frage: Wie kann ich mein Bild in RGB Werten so konvertieren, dass diese zur VGA-Ausgabe bereits sind? Ich nutze das DE2-115 Board von Intel und Quartus. Im Anhang ist der entsprechende Code-Ausschnitt zu sehen. Ich freue mich auf eure Hilfe.
:
Verschoben durch Moderator
Yann B. schrieb: > Ich möchte also die Daten von der Textdatei lesen und in den SDRAM > schreiben aber das funktioniert nicht (die Daten werden in den SDRAM > nicht gechrieben). Hast du mal die wichtigsten Signale am SDRAM mit einem Logicanalyzer gemessen (Steuersignale, sowie jeweils eine Adress- und eine Datenleitung, die sich ändern)? Wenn nein: tu das. Wenn ja: entsprechen die Timings dem, was das RAM laut Datenblatt erwartet? Und wo ich mir jetzt mal den Code so ansehe: > file_open(fin, filename, read_mode); Ich meine fast sicher behaupten zu können, dass das zur Laufzeit auf dem FPGA nicht funktioniert UND dir dein Synthesizer diesen Code einfach wegoptimiert UND dir auch entsprechende Meldungen ausgibt. > 1. Frage: Wo machte ich denn der Fehler? Denk einfach mal nach: wo liegt diese Datei und wie soll denn dein FPGA Zugriff auf diese Datei haben? > 2. Frage: Wie kann ich mein Bild in RGB Werten so konvertieren, dass > diese zur VGA-Ausgabe bereits sind? Das kommt darauf an, wie das Bild in dieser Datei liegt. Und dann musst du das Bild noch dauerhaft in einen Speicher auf dem FPGA-System bekommen. Ein RAM ist da ungeeignet. Welche dauerhaften Speicher hast du da ausser dem Config Flash?
:
Bearbeitet durch Moderator
Das Board hat SRAM und SDRAM. Für SDRAM solltest du noch CAS und RAS beachten. Der Code sieht DEUTLICH zu einfach aus.
Der Code taugt für das gewünschte gar nichts, tut mir leid. Wenns einfach gehen soll: Lade die Daten als Init-Werte in ein Blockram. Läuft deine VGA Ausgabe überhaupt schon mit statischen Farben/Farbverlauf?
Lothar M. schrieb: > Ich meine fast sicher behaupten zu können, ich bin da sogar ganz sicher (um nicht zu sagen: felsenfest überzeugt). Alleine der Typ LINE
1 | TYPE LINE IS ACCESS STRING; |
geht (als Pointer) nicht durch die Synthese (wie auch). Yann B. schrieb: > 2. Frage: Wie kann ich mein Bild in RGB Werten so konvertieren, dass > diese zur VGA-Ausgabe bereits sind? Du kannst dir (z.B. mit Hilfe eines .tcl-Scriptes) VHDL (Quell-) Code erzeugen, der das Bild als ROM synthetisiert.
Ich habe vor Jahren auch mal SDRam an dem gleichen Board gemacht. Falls ich micht richtig erinnere: Ich habe eine ganze Woche gebraucht, um den Implementation für den reinen Zugriff zu schreiben. Im Prinzip muss man sich das Datenblatt für die Chips besorgen, und 1 zu 1 die gesamte State-Machine nachprogrammieren. Man kann natürlich ein von Altera bereitgestelltes Beispiel-Design (IP-Core) nehmen. Nur da lernt man nichts. Als Beispiel für eine Statemachine: https://www.anandtech.com/show/3851/everything-you-always-wanted-to-know-about-sdram-memory-but-were-afraid-to-ask/3 Das Datenblatt zu dem SDRam habe ich nicht mehr zur Hand
Lothar M. schrieb: > Yann B. schrieb: >> Ich möchte also die Daten von der Textdatei lesen und in den SDRAM >> schreiben aber das funktioniert nicht (die Daten werden in den SDRAM >> nicht gechrieben). > Hast du mal die wichtigsten Signale am SDRAM mit einem Logicanalyzer > gemessen (Steuersignale, sowie jeweils eine Adress- und eine > Datenleitung, die sich ändern)? Gemessen habe ich bisher nicht aber paar davon habe ich mir schon mit dem ELA (Embedded Logikanalyser) angeschaut. > Wenn nein: tu das. Ich weiss nicht wie ich diese Timing-Signale mit dem ELA messen kann aber ich versuche. > Wenn ja: entsprechen die Timings dem, was das RAM laut Datenblatt > erwartet? > > Und wo ich mir jetzt mal den Code so ansehe: >> file_open(fin, filename, read_mode); > Ich meine fast sicher behaupten zu können, dass das zur Laufzeit auf dem > FPGA nicht funktioniert UND dir dein Synthesizer diesen Code einfach > wegoptimiert UND dir auch entsprechende Meldungen ausgibt. Warum? >> 1. Frage: Wo machte ich denn der Fehler? > Denk einfach mal nach: wo liegt diese Datei und wie soll denn dein FPGA > Zugriff auf diese Datei haben? Die Datei lag im meinem Projektordner. Ich habe sogar nachher noch den ganzen Pfad angegeben aber passierte nichts. >> 2. Frage: Wie kann ich mein Bild in RGB Werten so konvertieren, dass >> diese zur VGA-Ausgabe bereits sind? > Das kommt darauf an, wie das Bild in dieser Datei liegt. Und dann musst > du das Bild noch dauerhaft in einen Speicher auf dem FPGA-System > bekommen. Ein RAM ist da ungeeignet. Ich möchte die Bilder auf dem Board nicht dauerhaft speichern. Diese würde ich in den SDRAM laden und vom SDRAM nutzten. Der ist aber der einzige auf dem Board, der genug Speicher hat glaube ich. Welche dauerhaften Speicher hast > du da ausser dem Config Flash? Glaube keine mehr! https://www.terasic.com.tw/cgi-bin/page/archive.pl?Language=English&CategoryNo=163&No=502&PartNo=2#section
Gustl B. schrieb: > Das Board hat SRAM und SDRAM. Für SDRAM solltest du noch CAS und RAS > beachten. Der Code sieht DEUTLICH zu einfach aus. Ich möchte gern den SDRAM. Was die Einfachheit des Codes angeht, ist mir klar, weil ich mich noch nie mit dem SDRAM befasst hatte.Deswegen fange ich einfach an.
FPGA zum Spass schrieb im Beitrag #5872195: > Der Code taugt für das gewünschte gar nichts, tut mir leid. Warum? > Wenns einfach gehen soll: > > Lade die Daten als Init-Werte in ein Blockram. Das habe ich schon gemacht(aber nicht mit VGA) und das hast geklappt. Aber jetzt wollte ich mit dem SDRAM und VGA versuchen. > Läuft deine VGA Ausgabe überhaupt schon mit statischen > Farben/Farbverlauf? Ja
Markus F. schrieb: > Lothar M. schrieb: >> Ich meine fast sicher behaupten zu können, > > ich bin da sogar ganz sicher (um nicht zu sagen: felsenfest überzeugt). > > Alleine der Typ LINE > >
1 | > TYPE LINE IS ACCESS STRING; |
2 | >
|
> > geht (als Pointer) nicht durch die Synthese (wie auch). Okay. > Yann B. schrieb: >> 2. Frage: Wie kann ich mein Bild in RGB Werten so konvertieren, dass >> diese zur VGA-Ausgabe bereits sind? > > Du kannst dir (z.B. mit Hilfe eines .tcl-Scriptes) VHDL (Quell-) Code > erzeugen, der das Bild als ROM synthetisiert. Und wie geht es? Oder kannst du bitte noch konkreter sein?
:
Bearbeitet durch User
PittyJ schrieb: > Ich habe vor Jahren auch mal SDRam an dem gleichen Board gemacht. > > Falls ich micht richtig erinnere: > Ich habe eine ganze Woche gebraucht, um den Implementation für den > reinen Zugriff zu schreiben. Im Prinzip muss man sich das Datenblatt für > die Chips besorgen, und 1 zu 1 die gesamte State-Machine > nachprogrammieren. > > Man kann natürlich ein von Altera bereitgestelltes Beispiel-Design > (IP-Core) nehmen. Nur da lernt man nichts. Und wie findest du diesen IP Core ? > Als Beispiel für eine Statemachine: > https://www.anandtech.com/show/3851/everything-you-always-wanted-to-know-about-sdram-memory-but-were-afraid-to-ask/3 > > Das Datenblatt zu dem SDRam habe ich nicht mehr zur Hand Hier ist der Link dazu: http://www.issi.com/WW/pdf/42S16320B-86400B.pdf
Yann B. schrieb: >> Man kann natürlich ein von Altera bereitgestelltes Beispiel-Design >> (IP-Core) nehmen. Nur da lernt man nichts. > Und wie findest du diesen IP Core ? Es ist schon ein paar Jahre her. Damals war Altera noch selbständig. Core konnte man dort aus einem Store herunterladen und/oder kaufen. Für z.B: einen Ethernet IP-Core habe wir ca 900 Euro bezahlt. Wie das aktuell aussieht, weiss ich nicht. >> Als Beispiel für eine Statemachine: >> > https://www.anandtech.com/show/3851/everything-you-always-wanted-to-know-about-sdram-memory-but-were-afraid-to-ask/3 >> >> Das Datenblatt zu dem SDRam habe ich nicht mehr zur Hand > Hier ist der Link dazu: http://www.issi.com/WW/pdf/42S16320B-86400B.pdf Das ist ja super. Auf Seite 14 ist die State-Machine des Rams. Und die musst du 1:1 im FPGA abbilden. Dazu dann die einzelnen States auch weiter aufspalten, wie z.B. auf Seite 22 für den Auto-Refresh. Insgesamt war ich bei SDRam mit ca 1000 Zeilen dabei. SRam ging übrigens in nur 100 Zeilen.
Die ganze Diskussion über den SDRAM-Controller wird dir nicht viel helfen. Du hast da ein Henne-Ei Problem. Der SDRAM-Controller kann ja erst funktionieren, wenn die Config im FPGA geladen und aktiviert ist. Erst danach kannst Du mit Hilfe des Controllers ins SDRAM schreiben. Wenn Dein Bild nicht mit der Config mitgekommen ist, wirst Du nichts zu schreiben haben. Das Bild muß also bereits mit der Config mitkommen oder irgendwie nachgeladen werden. Paßt das Bild nicht als ROM in die Config, nutzt dir der SDRAM-Controller nichts. Dein verbliebenes RAM wirst Du (auch wenn Du's schaffst, das Bild ins SDRAM "auszulagern") wahrscheinlich als FIFO für deinen VGA-Controller brauchen. SDRAM hat eine relativ hohe Latenz und dein VGA-Controller kann nicht darauf warten, bis Du deine Bilddaten dort "rausgelutscht" hast, Du mußt sie also (bzw. zumindest einen Teil davon) in einem FIFO vorhalten. Yann B. schrieb: >> Yann B. schrieb: >>> 2. Frage: Wie kann ich mein Bild in RGB Werten so konvertieren, dass >>> diese zur VGA-Ausgabe bereits sind? >> >> Du kannst dir (z.B. mit Hilfe eines .tcl-Scriptes) VHDL (Quell-) Code >> erzeugen, der das Bild als ROM synthetisiert. > > Und wie geht es? Oder kannst du bitte noch konkreter sein? So z.B.:
1 | package require cmdline |
2 | |
3 | post_message "embed_bmp.tcl" |
4 | |
5 | set binfile picture.bmp |
6 | set fp [open $binfile r] |
7 | fconfigure $fp -translation binary |
8 | set bindata [read $fp] |
9 | close $fp |
10 | |
11 | set filename bmp_binary.vhd |
12 | |
13 | set date [clock format [clock seconds] -format { %a, %Y-%m-%d, %H:%M }] |
14 | set file [open $filename w] |
15 | set script [info script] |
16 | |
17 | puts $file "library ieee;" |
18 | puts $file "use ieee.std_logic_1164.all;" |
19 | puts $file "" |
20 | puts $file " -- VHDL representation of $binfile" |
21 | puts $file " -- generated by $script on $date" |
22 | puts $file " -- bmp picture as preloaded RAM contents" |
23 | puts $file "" |
24 | puts $file "package bmp_binary is" |
25 | puts $file " subtype ubyte is std_logic_vector(7 downto 0);" |
26 | puts $file " type ubyte_array is array (natural range <>) of ubyte;" |
27 | puts $file "" |
28 | puts $file " constant bmp_binary : ubyte_array :=" |
29 | puts $file " (" |
30 | puts -nonewline $file " " |
31 | set len [string length $bindata] |
32 | for {set i 0} {$i < $len} {incr i} { |
33 | set char [string index $bindata $i] |
34 | binary scan $char H2 byte |
35 | puts -nonewline $file "x\"" |
36 | puts -nonewline $file $byte |
37 | puts -nonewline $file "\"" |
38 | if { ! ([expr $i + 1] == $len) } { |
39 | puts -nonewline $file ", " |
40 | } |
41 | if { [expr ($i + 1) % 8] == 0 } { |
42 | puts $file "" |
43 | puts -nonewline $file " " |
44 | } |
45 | } |
46 | puts $file "" |
47 | puts $file " );" |
48 | puts $file "end package bmp_binary;" |
49 | close $file |
Das .tcl-Script kannst Du entweder einmal "von Hand" ausführen oder in Quartus über die "PRE_FLOW_SCRIPT_FILE"-Variable in deinen Workflow einbauen: project.qsf:
1 | set_global_assignment -name PRE_FLOW_SCRIPT_FILE "quartus_sh:embed_bmp.tcl" |
Es wird dann bei jedem Syntheselauf ausgeführt und baut dir aus deinem .bmp Bild ein VHDL-File (das Du in deinem Projekt einbauen musst) mit einem konstanten Array aus Binärwerten, die Du als ROM ansprechen kannst.
Markus F. schrieb: > Der SDRAM-Controller kann ja erst funktionieren, wenn die Config im FPGA > geladen und aktiviert ist. Erst danach kannst Du mit Hilfe des > Controllers ins SDRAM schreiben. Wenn Dein Bild nicht mit der Config > mitgekommen ist, wirst Du nichts zu schreiben haben. Was meinst du genau mit der Config? Meinst du das Laden des Bildes in den ROM? Der SDRAM IP Core hatte ich schon in Platform Designer konfiguriert und genau nach dem folgenden UG: ftp://ftp.intel.com/Pub/fpgaup/pub/Intel_Material/14.0/Tutorials/VHDL/DE 2-115/Using_the_SDRAM.pdf. > Dein verbliebenes RAM wirst Du (auch wenn Du's schaffst, das Bild ins > SDRAM "auszulagern") wahrscheinlich als FIFO für deinen VGA-Controller > brauchen. SDRAM hat eine relativ hohe Latenz und dein VGA-Controller > kann nicht darauf warten, bis Du deine Bilddaten dort "rausgelutscht" > hast, Du mußt sie also (bzw. zumindest einen Teil davon) in einem FIFO > vorhalten. Ja, ich habe einen FIFO dafür gebaut. > Das .tcl-Script kannst Du entweder einmal "von Hand" ausführen oder in > Quartus über die "PRE_FLOW_SCRIPT_FILE"-Variable in deinen Workflow > einbauen: > > project.qsf: >
1 | > set_global_assignment -name PRE_FLOW_SCRIPT_FILE |
2 | > "quartus_sh:embed_bmp.tcl" |
3 | > |
> > Es wird dann bei jedem Syntheselauf ausgeführt und baut dir aus deinem > .bmp Bild ein VHDL-File (das Du in deinem Projekt einbauen musst) mit > einem konstanten Array aus Binärwerten, die Du als ROM ansprechen > kannst. Vielen Dank für diesen Code-Auschnitt. Aber das Synthetisieren des Bildes als ROM, ist es nicht genau das gleiche, wenn man das Bild als .mif Datei initialisiert? (Siehe s_rom.vhd). Musst ich eine neue Datei im Projekt erstellen und diese als .tcl speichern? Soll diese dann zum Projekt für das Kompilieren hinzugefügt werden?
Also, ich habe den SDRAM temporär auf Seite gelassen und ich möchte jetzt das Bild vom ROM lesen und auf dem VGA-Monitor zeigen. Der beigefügte s_rom.vhd Datei lässt sich synthetisieren und simulieren aber bei Programmieren kriege nichts. Meine Vermutung ist die Größe des ROMs: 784x24 Ich habe mit ELA festgestellt, dass R, G und B immer den Wert Null haben, also es werden keine Daten vom ROM gelesen, obwohl dieser mit der Datei am Anfang initialisiert wird. Kann einer vielleicht weiter helfen?
Ich sehe da nirgends die Bilddaten. Readline kannst du auf Hardware vergessen. Wo soll das FPGA denn das Bild lesen? Das Bild sollte man schon vorher fest ins ROM legen. Oder du schiebst das Bild danach über eine Schnittstelle ins FPGA aber dann musst du auch dafür die nötige Hardware beschreiben. Ist nicht schwer mit UART, wird dann aber kein ROM sondern ein RAM.
-gb- schrieb: > Ich sehe da nirgends die Bilddaten. Die Daten liegen in diese Datei "28_28_lena_bmp.mif" >Readline kannst du auf Hardware vergessen. Ok aber warum läuft die Synthese troztdem? > Wo soll das FPGA denn das Bild lesen? Soviel ich weiß, gibt es 2 Arten, den ROM oder RAM zu itialisieren. Entweder manuell über eine Funktion z.B zum Lesen der Datei, die als .mif (für VHDL) sein musst. Oder in Platform Designer über das Megawizard
Dann guck mal in der Simulation ins RAM oder ROM ob da was drinnen steht. Oder guck mal was für Bauteile die Synthese verwendet.
Anhang die simulation des Gesamtsystems mit modelsim. Die Daten liegen im ROM und werden mit 25MHz gelesen.
Wunderbar! Schick, dass die Synthese sowas kann. Ja, also wieso RGB auf 0 bleiben weiß ich auch nicht. Wo ist denn der Code dazu?
Dann stell doch bitte Code und Testbench nochmal hier ein. Wenn Deine Simulation tatsächlich geht, und keine wilden Konstrukte drin sind, die nicht durch die Synthese gehen, sollte es funktionieren. Mit Signaltap könntest Du auch im FPGA prüfen, ob dein Adresszähler wackelt und was aus Deinem ROM rauskommt. Duke
Yann B. schrieb: > Vielen Dank für diesen Code-Auschnitt. Aber das Synthetisieren des > Bildes als ROM, ist es nicht genau das gleiche, wenn man das Bild als > .mif Datei initialisiert? (Siehe s_rom.vhd). Fast. Die .mif-Initialisierung funktioniert (zumindest) beim MAX10 nicht. Meine schon. > Musst ich eine neue Datei im Projekt erstellen und diese als .tcl > speichern? Soll diese dann zum Projekt für das Kompilieren hinzugefügt > werden? Steht doch alles da? Die .tcl gehört nicht zum Projekt, kann aber per PRE_FLOW_SCRIPT_FILE in den Ablauf integriert werden. Du kannst die Datei auch zum Projekt hinzufügen (schadet nichts), ausgeführt wird sie aber nur, wenn Du das .qsf händisch änderst. Meines Wissens gibt es keine Möglichkeit PRE_FLOW_SCRIPT_FILE von Quartus aus zu setzen.
Yann B. schrieb: > Kann jmd bitte hier weiter helfen? Schau dir doch erst einmal an, wie man mit VGA arbeitet. https://www.mikrocontroller.net/articles/Projekt_VGA_Core_in_VHDL Dann suche dir ein Format aus! Dann überlege dir eine Schaltung, die die Takte erzeugt. Dann formuliere ihre Struktur und Funktion in VHDL. Und dann frage ich, ob es dazu nötig ist, ein *.BMP-Format in ein RAM zu übertragen.
Hallo, ich war kurz krank. Also, ich habe den ROM (vom On-Chip-Memory IP) im Platform-Designer direkt mit meiner .mif-Datei initialisiert und lese dann vom ROM die Daten aus und sende zum VGA. Allerdings wird das Bild immer noch nicht richtig angezeigt. Es geht um ein 28x28 Graustufenbild,das im bmp war und und durch einen Skript in .mif konvertiert wurde. Also im ROM habe ich dann 784 Pixels. Weißt jmd vielleicht, warum das Bild nicht richtig angezeit wird? Anbei findet ihr meine Top-Level-Datei(top_level.vhd),die vom MegaWizard erstellte vhd-Daten des ROMs (rom_ip.vhd), das Graustufenbild(28_28_gray_lena.bmp) und die .mif-Datei(lena.mif), als Anhang. Vielen Dank im Voraus.
:
Bearbeitet durch User
Ja also ... da fehlt natürlich die Adresse des Pixels im Bild. Ein bestimmtes Pixel soll ja genau in einer Zeile des VGA Signals an nur einer Position auftauchen. Ich sehe keine Stelle an der die Rom Adresse einen Zusammenhang zum VGA HS und VS hat.
Anbei das Ausgangsbild. Ich hatte vergessen, es hochzuladen.
Ja wunderhybsch. Ist aber egal. Du solltest die Pixel genau dann an die Farbkanäle ausgeben wenn der Elektronenstrahl an der Position ist an der das Pixel sitzen soll. Dafür braucht man üblicherweise zwei Zahlen. Diese bilden zusammen die Koordinate des Strahls. In Abhängigkeit dieser Koordinate liest man dann aus dem Speicher.
-gb- schrieb: > Ja also ... da fehlt natürlich die Adresse des Pixels im Bild. Ein > bestimmtes Pixel soll ja genau in einer Zeile des VGA Signals an nur > einer Position auftauchen. Ich sehe keine Stelle an der die Rom Adresse > einen Zusammenhang zum VGA HS und VS hat. Ich habe mich auch gewundert, warum bei der Instanziierung des ROMs die Datenausgabe von der Adresse nicht abhängig ist (so q <=rom(address) meine ich).
:
Bearbeitet durch User
Doch, das ist sie oder sollte es sein. Aber die Adresse sollte nicht einfach nur stumpf hochzählen sondern von der horizontalen und vertikalen Position abhängen. Das fehlt noch komplett. Hier https://gus.tl/fpga habe ich auch ein VGA ein Minimalbeispiel. Nicht für deinen FPGA, aber das malt zumindest ein weißes Viereck auf den Schirm. Hier https://gus.tl/fpga/FPGA_Talk.pdf sind auch die beiden wichtigsten Bildchen zu VGA drinnen.
Gustl B. schrieb: > Doch, das ist sie oder sollte es sein. Aber die Adresse sollte nicht > einfach nur stumpf hochzählen sondern von der horizontalen und > vertikalen Position abhängen. Das fehlt noch komplett. Den VGA Controller habe ich doch in meinem Projekt. Habe aber nicht hochgeladen. Hier unten kann man sehen wie ich VideoActive steuere: if((h_cnt > Xpos and h_cnt < (Xpos + 28)) and (v_cnt > Ypos and v_cnt < (Ypos + 28))) then video_on <= '1'; else video_on <= '0'; end if;
Ja, das ist ganz fein, aber die Helligkeitswerte der Pixel soll passend zum VGA Timing ausgegeben werden. Wenn also Xpos und Ypos genau einen bestimmten Wert haben, dann muss das Pixel ausgegeben werden, das an diese Stelle gemalt werden soll. Du musst also Xpos und Ypos irgendwie verwenden um daraus die Adresse für dein ROM zu erzeugen.
Gustl B. schrieb: > Wenn also Xpos und Ypos genau einen bestimmten Wert haben, dann muss das > Pixel ausgegeben werden, das an diese Stelle gemalt werden soll. Du > musst also Xpos und Ypos irgendwie verwenden um daraus die Adresse für > dein ROM zu erzeugen. Hi Gustl, und vielen Dank für deinen Beitrag. Anbei habe ich den neuen VGA-Modul und die neue Top-Level Datei hochgeladen. Die Adresse des ROMs rechne ich abhängig vom Xpos und Ypos aber ich bekomme trotzdem das gleiche Ergebnisbild (siehe VGA-Bild). Nach der Simulation stelle ich aber fest, dass der zweite Pixel erst nach 4 Taktzyklen nach dem ersten kommt. Woran liegt das? Außerdem, wenn videoActive auf Null geht, sollte ich den alten Pixel beibehalten statt Null zu rgb zu geben? Vielen Dank im Voraus.
Duke Scarring schrieb: > Ohne Testbench läßt sich das nur schwer nachvollziehen... Anbei die Simulation im ModelSim.
Yann B. schrieb: > Kann Jemand mir bitte helfen? Nun, - ohne deinen Code genau angeschaut zu haben - Du scheinst ein Latency-Problem zu haben. Die ALTSYNCRAM-Komponente hat verschiedene Register an Ein-und Ausgängen, die sich nicht beliebig ausschalten lassen (zumindest nicht bei allen FPGA-Typen). Heisst: sie ist nicht in der Lage, nach dem Anlegen der Adresse gleich im nächsten Takt das Ergebnis auszuspucken, das dauert (je nachdem, welche input/outputs Du als "registered" angegeben hast) ein bis drei Takte. Der Rest deines Designs muss das entsprechend berücksichtigen.
Hier ist die Testbench dazu. Mir fehlt gerade die Quartus-Installation und damit der 'altsyncram'. Duke
Die Latenz würde nur bewirken, dass die Zeilen im Bild etwas verschoben sind.
In top_level.vhd wird die ROM-Adresse nicht verändert. So kommt nur ein konstanter Wert aus dem Speicher... Duke
Hi Duke, das wundert mich aber dein Ergebnisbild bekomme ich nicht. Ist es meine Dateien, die du synthetisiert hast oder hast du die noch angepasst?
Markus F. schrieb: > Heisst: sie ist nicht in der Lage, nach dem Anlegen der Adresse gleich > im nächsten Takt das Ergebnis auszuspucken, das dauert (je nachdem, > welche input/outputs Du als "registered" angegeben hast) ein bis drei > Takte. Das dachte ich mir auch aber ich finde nicht das passende User Guide darüber. Ich habe mir die Datei das User Guide (ug_ram_rom) hier:https://www.intel.com/content/dam/www/programmable/us/en/pdfs/literature/ug/ug_ram_rom.pdf angeguckt aber keine Infos über die Lesen-Latenz wird explizit erwähnt. Weiß du vielleicht wo ich die Infos drüber kriegen kann?
Duke Scarring schrieb: > In top_level.vhd wird die ROM-Adresse nicht verändert. So kommt nur ein > konstanter Wert aus dem Speicher... Ich habe festgestellt, dass die romAddr in VGA-Component in der hochgeladen Top-Level Datei nicht dabei ist. Vielleicht ist es der Grund, warum du dieses Bild bekommst.
Yann B. schrieb: > Das dachte ich mir auch aber ich finde nicht das passende User Guide > darüber. Ich habe mir die Datei das User Guide (ug_ram_rom) > hier:https://www.intel.com/content/dam/www/programmable/us/en/pdfs/literature/ug/ug_ram_rom.pdf > angeguckt aber keine Infos über die Lesen-Latenz wird explizit erwähnt. > Weiß du vielleicht wo ich die Infos drüber kriegen kann? In Kapitel 3 des von Dir genannten Dokuments befinden sich doch Unmengen an Timingdiagrammen, anhand derer man ablesen kann, wann welches Datum geschrieben oder gelesen wird.
Yann B. schrieb: > Ist es meine > Dateien, die du synthetisiert hast oder hast du die noch angepasst? Das sind alles deine Dateien, bis auf die Testbench. Wobei die Testbench ja nur 50 MHz Takt erzeugt und das Resultat als Bitmap wegschreibt. top_level.vhd und vga.vhd sind aus diesem Beitrag: Beitrag "Re: Bilder in den SDRAM in VHDL schreiben" rom_ip.vhd und lena.mif von hier: Beitrag "Re: Bilder in den SDRAM in VHDL schreiben" Achja, die Testbench kommt von hier: Beitrag "Re: Bilder in den SDRAM in VHDL schreiben" Vielleicht stellst Du Deinen Arbeitstand noch einmal komplett hier ein, damit wir von gleichen Voraussetzungen ausgehen können. Duke
Hi, anbei die aktuellsten Dateien. Das Problem mit der Verzögerung des zweiten Byte ist noch aktuell. Dies kommt immer 4 Taktzyklen spater und das Bild wird nicht ganz gelesen. Bitte helft mir, dies zu lösen. Ich möchte das Bild auf dem VGA-Monitor richtig anzeigen.
Das in ROM geladene Bild ist das gleiche (lena.mif) und und ist 28x28 also 784 Pixels. Vielleicht hat jmd schon Erfahrung damit, und kann mir sagen, was ich falsch mache.
Dein addr im top_level.vhd zählt immernoch nur stumpf nach oben und hat keinen erkennbaren Zusammenhang mit der Pixelposition auf dem Bildschirm.
Yann B. schrieb: > anbei die aktuellsten Dateien Mal probiert die zu compilieren?
1 | -- Compiling entity vga |
2 | -- Compiling architecture main of vga |
3 | ###### vga.vhd(40): vga_clk:process(clk, reset_n) |
4 | ** Error: vga.vhd(40): (vcom-1136) Unknown identifier "reset_n". |
5 | ** Error: vga.vhd(40): Expression is not a signal. |
6 | ###### vga.vhd(42): if reset_n = '0' then |
7 | ** Error: vga.vhd(42): (vcom-1136) Unknown identifier "reset_n". |
8 | ** Error: vga.vhd(42): Type error resolving infix expression "=" as type std.STANDARD.BOOLEAN. |
9 | ###### vga.vhd(49): counter_proc: process(vga_clk_25, reset_n) |
10 | ** Error: vga.vhd(49): (vcom-1136) Unknown identifier "reset_n". |
11 | ** Error: vga.vhd(49): Expression is not a signal. |
12 | ###### vga.vhd(51): if (reset_n = '0') then |
13 | ** Error: vga.vhd(51): (vcom-1136) Unknown identifier "reset_n". |
14 | ** Error: vga.vhd(51): Type error resolving infix expression "=" as type std.STANDARD.BOOLEAN. |
15 | ###### vga.vhd(68): main_proc: process(vga_clk_25, reset_n) |
16 | ** Error: vga.vhd(68): (vcom-1136) Unknown identifier "reset_n". |
17 | ** Error: vga.vhd(68): Expression is not a signal. |
18 | ###### vga.vhd(70): if(reset_n = '0') then |
19 | ** Error: vga.vhd(70): (vcom-1136) Unknown identifier "reset_n". |
20 | ** Error: vga.vhd(70): Type error resolving infix expression "=" as type std.STANDARD.BOOLEAN. |
21 | ###### vga.vhd(108): end main; |
22 | ** Error: vga.vhd(108): VHDL Compiler exiting |
Yann B. schrieb: > ist 28x28 > also 784 Pixels Dein Adresszähler läuft nur bis 728 (27*27-1). Außerdem solltest Du den mit jedem Frame zurücksetzen, sonst wird es ein Video ;-) Duke
Gustl B. schrieb: > Dein addr im top_level.vhd zählt immernoch nur stumpf nach oben und hat > keinen erkennbaren Zusammenhang mit der Pixelposition auf dem > Bildschirm. Das hilft mir leider nicht weiter. Sag mir bitte, wie ich das richtig machen sollte. Du hast es schon hingewiesen (oben) und ich habe hier https://www.mikrocontroller.net/attachment/highlight/421570 den Code korrigiert mit paar Fragen aber keine hilfsreiche Antworten bekommen. Deswegen ist es noch aktuell.
> ** Error: vga.vhd(108): VHDL Compiler exiting
Sorry, mein Fehler. Habe unbewusst reset_n von port gelöscht. Musst in
der Entity als Input sein.
Duke Scarring schrieb: > Dein Adresszähler läuft nur bis 728 (27*27-1). Hmmm, dke. Muss nicht so sein. Ich korrigiere es. Duke Scarring schrieb: > Außerdem solltest Du den mit jedem Frame zurücksetzen, sonst wird es ein > Video ;-) Kannst du bitte noch konkreter sein?
Duke Scarring schrieb: > Außerdem sind in Deiner lena.mif nur Streifen drin... Streifen!!! Das sind die Pixeldaten. Öffne mal die Datei in Quartus, dann wirst du sehen wie das aussieht.
Yann B. schrieb: > Duke Scarring schrieb: >> Außerdem solltest Du den mit jedem Frame zurücksetzen, sonst wird es ein >> Video ;-) > > Kannst du bitte noch konkreter sein? Statt bei einem Zähler auf einen impliziten oder expliten Überlauf zu hoffen, ist es meist äußerst ratsam, den oder die Zähler bei bestimmten Ereignissen explizit auf den Anfangswert zurückzusetzen. Das vereinfacht auch spätere Anpassungen/Erweiterungen/Korrekturen. Man verlässt sich also nicht darauf, dass ein Pixelzähler beim Systemstart bei Null loszählt und bis zum Sanktnimmerleinstag synchron zur H- und V-Synchronisation bleibt, sondern spätestens bei der V-Synchronisation setzt man ihn auf seinen Startwert zurück. Das Verhalten überlaufender Zähler kann in der Simulation und auf der Zielhardware auch komplett unterschiedlich aussehen! Ein Zähler des Typs "integer range 13 to 42" wird auf einem FPGA nicht munter bei 13 starten, bis 42 weiterzählen und dann wieder auf 13 springen, sondern er wird durch einen normalen sechs Bit breiten Binärzähler von 0..63 dargestellt werden. In der Simulation wird einem meist auf die Finger gehauen, wenn der Wertebereich überschritten werden sollte.
Yann B. schrieb: > Streifen!!! Das sind die Pixeldaten. Öffne mal die Datei in Quartus, > dann wirst du sehen wie das aussieht. Hab Quartus auf einem anderen Rechner. Meine Erweiterung zur VGA-Testbench schreibt für jedes Frame eine Bitmap raus. Hier aus Platzgründen zu PNG konvertiert. Siehe Anhang... Duke
Anbei die neuen Dateien mit den Simulationsergebnissen. romAddr zählt jetzt richtig (von 0 bis 783) aber wegen dieser schon erwähnten Verzögerung (4 Taktzyklen) entsprechend die Pixel nach dem ersten den richtigen Adressen nicht.
Ey man, guck dir an wie ein alter Röhrenmonitor das Bild ausgibt. Wie du die Adresse für dein ROM gestalten musst kann ich nicht sagen. Das hängt davon ab wie dein Bild aufgebaut ist. Aber gut ich mache ien paar Annahmen und erkläre es für diesen einen Fall: Dein Bild hat 27 Zeilen mit je 27 Bildpunkten? Wenn das Bild im ROM liegt, dann ist ROM(0) der Bildpunkt links oben im Bild? ROM(27) ist dann der linkeste Bildpunkt der zweiten Zeile von oben? ROM(26) ist der rechteste Bildpunkt in der obersten Bildzeile? Dann guckst du dieses Bild an: http://www.cs.ucr.edu/~jtarango/cs122a/lab4/lab4_vga_timing.png Es wird zuerst der VSync abgewartet. Auch noch der Front Porch vom VSync. Dann kommen die einzelnen Zeilen. In jeder Zeile wartest du bis der HSync und der dazugehörige Frontporch vergangen sind. Erst dann gibst du in der jeweiligen Zeile die Zeile des Bildes aus. Du hast also einen Zähler für Zeile und Spalte im Bild. Die Spalte wird nach HSync und Frontporch mit jedem Pixeltakt um 1 erhöht und bei Beginn des Backporch wieder auf 0 gesetzt. Die Zeile wird nach VSync und Frontporch mit jedem HSync um 1 erhöht und zu Beginn des Backporches auf 0 gesetzt. So, jetzt hast du horizontale und vertikale Adresse. Jetzt musst du aus dem Rom passend lesen. Da bietet es sich an das Bild gleich als 2D Array zu speichern. Dann könntest du die Pixel ausgeben mit Pixel <= Bild(Zeile)(Spalte) Wenn du das nicht machen willst sondern das Bild so gespeichert hast wie ich hier oben als Annahme geschrieben habe, dann kannst du das so ausgeben: Pixel <= Bild(Zeile*27+Spalte)
Yann B. schrieb: > Das in ROM geladene Bild ist das gleiche (lena.mif) und und ist 28x28 > also 784 Pixels. Vielleicht hat jmd schon Erfahrung damit, und kann mir > sagen, was ich falsch mache. Tut mir Leid, wenn ich viele von euch mit dem oberen Text verwirrt habe. - Also, das urspüngliche ist Bild ein 28x28 Graustufenbild BMP-Format (siehe Beitrag "Re: Bilder in den SDRAM in VHDL schreiben"). - Dieses habe ich dann mit einem Matlab-Skript in .mif-Datei konvertiert, um den ROM mit lena.mif zu initialisieren. Die lena.mif (siehe Beitrag "Re: Bilder in den SDRAM in VHDL schreiben") ist aber kein 28x28 Array sondern hat 784 Pixel und jedes Pixel ist 1 Byte groß. - Der ROM jetzt ist 1kx8 Bit konfiguriert worden und wie man der Simulation (Beitrag "Re: Bilder in den SDRAM in VHDL schreiben") entnehmen kann, ROM(0) hat genau das erste Pixel x"9d" und ROM(783) sollte normalerweise x"5f" haben. Gustl B. schrieb: > Dein Bild hat 27 Zeilen mit je 27 Bildpunkten? > Wenn das Bild im ROM liegt, dann ist ROM(0) der Bildpunkt links oben im > Bild? ROM(27) ist dann der linkeste Bildpunkt der zweiten Zeile von > oben? ROM(26) ist der rechteste Bildpunkt in der obersten Bildzeile? Ist also schon geklärkt. Gustl B. schrieb: > Da bietet es sich an das Bild gleich als 2D Array > zu speichern. Dann könntest du die Pixel ausgeben mit > Pixel <= Bild(Zeile)(Spalte) das hatte ich am Anfang vor, aber wegen der großen Menge der Pixel habe ich nicht gemacht. In diesem Fall, müsste ich für jedes der 784 Pixel die Quote z.b: "100011101" vor und nach dem Byte schreiben. Wenn ich aber ein größeres Bild hätte, dann würde es kein Spaß mehr machen oder? Gustl B. schrieb: > Wenn du das nicht machen willst sondern das Bild so gespeichert hast wie > ich hier oben als Annahme geschrieben habe, dann kannst du das so > ausgeben: > Pixel <= Bild(Zeile*27+Spalte) Das würde auch nicht gehen, weil mein Bild nicht so gespeichert ist. Anbei habe ich noch die rom_ip.vhd Datei hochgeladen.
:
Bearbeitet durch User
Yann B. schrieb: > Das würde auch nicht gehen, weil mein Bild nicht so gespeichert ist. Na dann solltest du entweder ändern wie das Bild im Speicher liegt oder du musst dir eine andere Art der Adressierung überlegen. Also eine Funktion die dir in Abhängigkeit von X und Y das richtige Pixel liefert. Pixel(X,Y)=Speicher(???) Das Speicherformat ändern ist sehr einfach.
Dein neuer Code zählt immer noch schief. Ich würde bei der Pixelabfrage aus dem 'pix_x > Xpos' ein 'pix_x >= Xpo' machen. Außerdem wird die Adresse zum falschen Zeitpunkt zurückgesetzt. Ich würde den Zähler nullen, wenn vga_vs = '0' ist. Duke
Hi, ich habe gestern festgestellt, dass in der .mif Datei (lena.mif) nur die erste Spalte des 28x28 Bildes beinhaltet, die sich 28 Mal wiederholt. Also, die Konvertierung nach .mif war falsch. Ich habe den Skript nachgearbeitet und anbei findet ihr die neue .mif (lena) Datei. Ich melde mich heute Abend mit dem Testergebnis, wenn ich zu Hause bin. Ich freue mich schon darauf.
:
Bearbeitet durch User
Solange die Leseadresse nix mit der Position des Pixels zu tun hat hilft auch kein neues Bild. Zeichne doch mal ein weißes Rechteck auf den Bildschirm. Ganz ohne ROM.
Yann B. schrieb: > ich habe gestern festgestellt, dass in der .mif Datei (lena.mif) nur die > erste Spalte des 28x28 Bildes beinhaltet, die sich 28 Mal wiederholt. Das meinte ich mit "Dein Bild enthält nur Streifen". -gb- schrieb: > Solange die Leseadresse nix mit der Position des Pixels zu tun hat hilft > auch kein neues Bild. Gustl, das hat er doch schon lange eingebaut... Und jetzt geht's ja auch, theoretisch. Der praktische Test, ob ein Monitor mit den Frequenzen klar kommt, steht noch aus. Duke
Das Bild wird angezeigt! Anbei findet ihr auch ein Foto des Ergebnisbildes (vga_lena_neu). Vielen Dank an Alle für eure Hilfe. Duke Scarring schrieb: > Yann B. schrieb: >> ich habe gestern festgestellt, dass in der .mif Datei (lena.mif) nur die >> erste Spalte des 28x28 Bildes beinhaltet, die sich 28 Mal wiederholt. > Das meinte ich mit "Dein Bild enthält nur Streifen". Achso, dann sorry Duke. Du hattest Recht. Schön das du auch mit der neuen .mif Datei das richtige Bild bekommst. Aber warum sieht deins breiter als meins aus? Duke Scarring schrieb: > Der praktische Test, ob ein Monitor mit den Frequenzen klar kommt, steht > noch aus. Was meinst du konkret?
:
Bearbeitet durch User
Sorry, hatte vorhin zu schnell geantwortet. Lob und Anerkennung an Yann.
Yann B. schrieb: > Aber warum sieht deins > breiter als meins aus? Mein Bild kommt aus der Simulation und nicht von einem echten Monitor. > Was meinst du konkret? Das ich Deinen Code nicht auf echter Hardware getestet habe, sondern nur im Simulator. Das Code im Simulator funktioniert, ist - in meinen Augen - eine notwendige Bedingung dafür, das er auch auf echter Hardware funktioniert. Aber es ist keine hinreichende Bedingung, da in der Simulation oft nur Teilaspekte der echten Hardware berücksichtigt werden. Schön, das jetzt bei Dir funktioniert. Möglicherweise hast Du auch das eine oder andere dabei gelernt. ;-) Duke
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.