Forum: FPGA, VHDL & Co. Bilder in den SDRAM in VHDL schreiben


von Yann B. (yann)


Angehängte Dateien:

Lesenswert?

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
von Yann B. (yann)


Lesenswert?

Bitte Hilfe!!!

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

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
von Gustl B. (-gb-)


Lesenswert?

Das Board hat SRAM und SDRAM. Für SDRAM solltest du noch CAS und RAS 
beachten. Der Code sieht DEUTLICH zu einfach aus.

von FPGA zum Spass (Gast)


Lesenswert?

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?

von Markus F. (mfro)


Lesenswert?

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.

von PittyJ (Gast)


Lesenswert?

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

von Yann B. (yann)


Lesenswert?

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

von Yann B. (yann)


Lesenswert?

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.

von Yann B. (yann)


Lesenswert?

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

von Yann B. (yann)


Lesenswert?

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
von Yann B. (yann)


Lesenswert?

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

von PittyJ (Gast)


Lesenswert?

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.

von Markus F. (mfro)


Lesenswert?

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.

von Yann B. (yann)


Angehängte Dateien:

Lesenswert?

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?

von Yann B. (yann)


Lesenswert?

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?

von -gb- (Gast)


Lesenswert?

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.

von Yann B. (yann)


Lesenswert?

-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

von Gustl B. (-gb-)


Lesenswert?

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.

von Yann B. (yann)


Angehängte Dateien:

Lesenswert?

Anhang die simulation des Gesamtsystems mit modelsim. Die Daten liegen 
im ROM und werden mit 25MHz gelesen.

von Gustl B. (-gb-)


Lesenswert?

Wunderbar! Schick, dass die Synthese sowas kann. Ja, also wieso RGB auf 
0 bleiben weiß ich auch nicht. Wo ist denn der Code dazu?

von Yann B. (yann)


Lesenswert?

Kann jmd bitte hier weiter helfen?

von Duke Scarring (Gast)


Lesenswert?

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

von Markus F. (mfro)


Lesenswert?

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.

von J. S. (engineer) Benutzerseite


Lesenswert?

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.

von Yann B. (yann)


Angehängte Dateien:

Lesenswert?

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
von Yann B. (yann)


Lesenswert?

Bei der Top-Levell Datei bitte die zweite betrachten!!!

von Yann B. (yann)


Lesenswert?

Keine Reaktion??

von -gb- (Gast)


Lesenswert?

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.

von Yann B. (yann)


Angehängte Dateien:

Lesenswert?

Anbei das Ausgangsbild. Ich hatte vergessen, es hochzuladen.

von Gustl B. (-gb-)


Lesenswert?

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.

von Yann B. (yann)


Lesenswert?

-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
von Gustl B. (-gb-)


Lesenswert?

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.

von Yann B. (yann)


Lesenswert?

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;

von Gustl B. (-gb-)


Lesenswert?

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.

von Duke Scarring (Gast)


Lesenswert?

Yann B. schrieb:
> Keine Reaktion?
Ohne Testbench läßt sich das nur schwer nachvollziehen...

von Yann B. (yann)


Angehängte Dateien:

Lesenswert?

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.

von Yann B. (yann)


Angehängte Dateien:

Lesenswert?

Duke Scarring schrieb:
> Ohne Testbench läßt sich das nur schwer nachvollziehen...

Anbei die Simulation im ModelSim.

von Yann B. (yann)


Lesenswert?

Kann Jemand mir bitte helfen?

von Markus F. (mfro)


Lesenswert?

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.

von Duke Scarring (Gast)


Angehängte Dateien:

Lesenswert?

Hier ist die Testbench dazu. Mir fehlt gerade die Quartus-Installation 
und damit der 'altsyncram'.

Duke

von Gustl B. (-gb-)


Lesenswert?

Die Latenz würde nur bewirken, dass die Zeilen im Bild etwas verschoben 
sind.

von Duke Scarring (Gast)


Angehängte Dateien:

Lesenswert?

In top_level.vhd wird die ROM-Adresse nicht verändert. So kommt nur ein 
konstanter Wert aus dem Speicher...

Duke

von Yann B. (yann)


Lesenswert?

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?

von Yann B. (yann)


Lesenswert?

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?

von Yann B. (yann)


Lesenswert?

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.

von Andreas S. (Firma: Schweigstill IT) (schweigstill) Benutzerseite


Lesenswert?

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.

von Duke Scarring (Gast)


Lesenswert?

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

von Yann B. (yann)


Angehängte Dateien:

Lesenswert?

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.

von Yann B. (yann)


Lesenswert?

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.

von Gustl B. (-gb-)


Lesenswert?

Dein addr im top_level.vhd zählt immernoch nur stumpf nach oben und hat 
keinen erkennbaren Zusammenhang mit der Pixelposition auf dem 
Bildschirm.

von Duke Scarring (Gast)


Angehängte Dateien:

Lesenswert?

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

von Duke Scarring (Gast)


Angehängte Dateien:

Lesenswert?

Außerdem sind in Deiner lena.mif nur Streifen drin...

von Yann B. (yann)


Lesenswert?

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.

von Yann B. (yann)


Lesenswert?

> ** 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.

von Yann B. (yann)


Lesenswert?

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?

von Yann B. (yann)


Lesenswert?

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.

von Andreas S. (Firma: Schweigstill IT) (schweigstill) Benutzerseite


Lesenswert?

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.

von Duke Scarring (Gast)


Angehängte Dateien:

Lesenswert?

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

von Yann B. (yann)


Angehängte Dateien:

Lesenswert?

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.

von Gustl B. (-gb-)


Lesenswert?

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)

von Yann B. (yann)


Angehängte Dateien:

Lesenswert?

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
von Gustl B. (-gb-)


Lesenswert?

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.

von Duke Scarring (Gast)


Angehängte Dateien:

Lesenswert?

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

von Yann B. (yann)


Angehängte Dateien:

Lesenswert?

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
von -gb- (Gast)


Lesenswert?

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.

von Duke Scarring (Gast)


Angehängte Dateien:

Lesenswert?

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

von Yann B. (yann)


Angehängte Dateien:

Lesenswert?

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
von -gb- (Gast)


Lesenswert?

Sorry, hatte vorhin zu schnell geantwortet. Lob und Anerkennung an Yann.

von Duke Scarring (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.