Forum: FPGA, VHDL & Co. 320x240 Display nach 640x480 VGA


von Gustl B. (-gb-)


Lesenswert?

Hallo, ich habe hier ein kleines altes Display das 320x240 Pixel hat. Es 
wird digital angesteuert mit sowas ähnlichem wie HSync, VSync, einem 
4-Bit Datenbus und einem Takt. Je Takt werden 4 Pixel einer Zeile 
übertragen, also 320/4 = 80 Takte je Zeile.
Eine Zeile dauert 57,x us.

Jetzt will ich das Bild aber über VGA ausgeben. Weil ich keine 
VGA-Auflösung gefunden habe die mit der Zeilenfrequenz oder der 
doppelten Zeilenfrequenz zusammenpasst, muss ich wohl ein Vollbild 
speichern im FPGA.

Also habe ich mir da ein fettes Array definiert, also 240 Zeilen mal 80 
Elemente und 4 Bits je Element. Und weil ich schöne Zweierpotenzen haben 
wollte habe ich 256x128x4 genommen. Das sind 16KBits.

Auf einem Spartan 3 1500 schafft es das Xilinx Tool aber nicht das in 
das BlockRAM zu packen, sondern will immer DistributedRAM machen.

Wie sollte man da vorgehen wenn man ein Array machen will das größer ist 
wie ein BlockRAM? Sollte das XST das können oder ist es geschickter das 
aufzuteilen? Hier auf 8 einzelne 2K BRAMs, also 128x128 je BRAM, oder 
128x32x4.

Vielen Dank!

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


Lesenswert?

Gustl Buheitel schrieb:
> Sollte das XST das können oder ist es geschickter das aufzuteilen?
Wenn du eine Beschreibung hast, die ein Block-RAM ermöglicht, dann 
macht die ISE die Parallelschaltung der RAMs von sich aus.

Vermutlich ist es eher so, dass der Synthesizer nicht erkennt, dass du 
ein BRAM willst. Oder dass du das Array so beschrieben hast, dass es 
nicht mit einem BRAM umgesetzt werden kann. Lies mal den XST Users Guide 
dazu...

von Duke Scarring (Gast)


Lesenswert?

Gustl Buheitel schrieb:
> Auf einem Spartan 3 1500 schafft es das Xilinx Tool aber nicht das in
> das BlockRAM zu packen, sondern will immer DistributedRAM machen.
>
> Wie sollte man da vorgehen wenn man ein Array machen will das größer ist
> wie ein BlockRAM?
Das geht. mache ich hier ständig. Offenbar ist an Deiner 
RAM-Beschreibung noch was faul (zu viele Ports, Reset dran oder 
Verwendung von byte-enable [geht erst bei Spartan 6]).

Den Abschnitt ROM/RAM im XST User Guide kennst Du schon, oder?

Wenn es gar nicht klappen will, dann stell doch Deine RAM-Beschreibung 
mal hier ein.

Duke

von -gb- (Gast)


Lesenswert?

Hallo, habe den Code gerade nicht zur Hand, aber sinngemäß:

[vhdl]
DATA: in std_logic_vector(3 downto 0);

...

type ZEILE is array(0 to 127) of std_logic_vector(3 downto 0);
type FRAME is array(0 to 255) of ZEILE;
signal BILD: FRAME;

begin

process
begin
wait until rising_edge(EXT_CLK);

   BILD(zeilenzähler)(spaltenzähler) <= DATA

-- zeilenzähler von 0...239
-- spaltenzähler von 0...79

end process;

process
begin
wait until rising_edge(VGA_CLK);

   PIXEL <= BILD(zeilenzähler_VGA/2)(spaltenzähler_VGA(9 downto 
3))(spaltenzähler_VGA(2 downto 1));

-- zeilenzähler_VGA von 0...479
-- spaltenzähler_VGA von 0...639

end process;

Also so das grobe Konzept was das RAM betrifft.

von Gustl B. (-gb-)


Lesenswert?

So, jetzt:
1
library ieee;
2
use ieee.std_logic_1164.all;
3
use IEEE.numeric_std.all;
4
use ieee.math_real.all;
5
6
entity vga is
7
port (CLK, VS_EXT, CLK_EXT, HS_EXT: in std_logic;
8
    DATA: in std_logic_vector(3 downto 0);
9
    HS, VS: out std_logic;
10
    VGAr: out std_logic_vector(6 downto 0);
11
    VGAg: out std_logic_vector(6 downto 0);
12
    VGAb: out std_logic_vector(6 downto 0));
13
end vga;
14
15
architecture behav of vga is
16
17
signal row_counter: integer range 0 to 79:=0;
18
signal line_counter: unsigned(7 downto 0):="00000000";
19
20
signal CLK25,bool: std_logic:= '0';
21
22
signal screen_h, screen_v: unsigned(9 downto 0);
23
24
type ZEILE is array (0 to 127) of std_logic_vector(3 downto 0);
25
type FELD is array (0 to 255) of ZEILE;
26
signal FRAME: FELD;
27
28
begin
29
30
process begin
31
   wait until rising_edge(CLK_EXT);
32
  
33
  FRAME(to_integer(line_counter))(row_counter) <= DATA;
34
  
35
end process;
36
37
process
38
  begin
39
   wait until rising_edge(CLK25);
40
  
41
  bool <= FRAME(to_integer(screen_v(9 downto 1)))(to_integer(screen_h(9 downto 3)))(to_integer(screen_h(2 downto 1)));
42
  
43
end process;
44
45
end behav;

Also nur das Skelett was das BRAM betrifft, den Rest hab ich zwar auch, 
aber will ich gerne selber machen, also es geht hier nur um das BRAM ob 
ich das richtig mache. Ich bin der Meinung, dass XST da ein DP-RAM draus 
machen könnte.

von Sigi (Gast)


Lesenswert?

Rechne doch mal das komplette Timing des 320x240er und des
640x480er Displays durch:
57.x us bei 240+x Zeilen ergibt doch ca. 60 Hz, d.h. der
640x480er hat eine ca. 4x höhere PixelClock. Also kanst du eine
Zeile LCD in 2 Zeilen VGA wandeln, dafür ist nur ein "1/2"er
BRAM erforderlich. Das ganze nennt sich ScanDoubler, findet
sich z.B. bei FPGA-Implementierungen von Computer-Klassiker
wie C64, VC20, ...
Ein komplettes Bild dagegen abspeichern ist Verschwendung
an Resourcen.

von Gustl B. (-gb-)


Lesenswert?

Und genau das circa ist mein Problem. Wenn ich für die zwei Zeilen am 
VGA länger brauche wie das 320x240 Display für eine, dann kommen ja da 
schon neue Pixeldaten während ich die letzte Zeile noch nicht ausgegeben 
habe. Es muss also genau passen und nicht nur ungefähr. Liege ich da 
richtig? Laut http://tinyvga.com/vga-timing/640x480@60Hz dauert eine 
Zeile bei 640x480 nämlich 31,x us, das ist zu lange weil ich dann bei 
62,x us lande für zwei Zeilen und das 320x240 Display schon neue Daten 
bekommt.

von Sigi (Gast)


Lesenswert?

Ja aber das ist doch das Tolle an VGA, du must dich nicht an
die exakten Timings halten. Selbst neuere TFTs akzeptieren per
analog-VGA-Eingang 55-65 Hz etc. (DVI ist hier problematischer).
Ich habe hier einen TFT, des sogar bis 48Hz runtergeht.

Unter Umständen kannst du nicht eine Clock-Domain inkl.
ClockEnable verwenden, sondern musst 2 Clocks verwenden und
damit die BlockRAMs asyncron ansteuern. Aber das ist bei den
Spartan3er kein Problem.

Ist bei deinem 320x240er LCD das Timing fest vorgegeben oder
kannst du das Timing noch leicht ändern? Falls ja, dann kann
man evtl. nur eine Clock verwenden. (bei meinem LCD: erlaubt
ist 51us .. 59us)

Für die Ansteuerung meines 320x240er Displays habe ich jedenfalls
ein 640x480er-kompatibles Timing verwendet.

von Gustl B. (-gb-)


Lesenswert?

Hallo, das höre/lese ich das erste Mal. Gibt es denn irgendwo eine 
Richtlinie was ich dann überhaupt einhalten muss? Also wielange muss das 
HSync und das VSync sein, wieviel Prozent vom Bild/Zeile und welchen 
Takt und alles darf ich machen?

Gefunden habe ich bisher nur http://tinyvga.com/vga-timing und auch 
Wikipedia hat nur eine Liste der unterstützten Modi aber nichts 
generelles.

von Gustl B. (-gb-)


Lesenswert?

Danke Lothar und Dukem, es ist zwar nicht der XST Userguide den ich 
lese, aber die xapp463. Und da ist das Stichwort Memory Organizations:

16Kx1
8Kx2
4Kx4
2Kx8 (no parity)
2Kx9 (x8 + parity)
1Kx16 (no parity)
1Kx18 (x16 + 2 parity)
512x32 (no parity)
512x36 (x32 + 4 parity)
256x72 (single-port only)

Wenn ich also
1
type ZEILE is array (0 to 127) of std_logic_vector(3 downto 0);

schreibe, dann wird das doch 4Kx4 und davon werden nur 128 verwendet?!
1
type FELD is array (0 to 255) of ZEILE;
2
signal FRAME: FELD;

geht dann nicht, weil ich nur 32 BRAMs im XC3S1500L habe und nicht 256.

Also kann ich auch nicht jedes BRAM als 128x128 machen ... hm, wie macht 
man das elegant wenn man je Takt 4Bits schreiben will? Also ich könnte 
dann wohl 32 BRAMs mit 4Kx4 nehmen und dann die ersten Zeilen in das 
Erste rein, die nächsten 32 Zeilen in das Zweite, ... hm, ist nicht so 
hybsch hinzuschreiben.

von Mike (Gast)


Lesenswert?

Gustl Buheitel schrieb:
> Also kann ich auch nicht jedes BRAM als 128x128 machen ... hm, wie macht
> man das elegant wenn man je Takt 4Bits schreiben will? Also ich könnte
> dann wohl 32 BRAMs mit 4Kx4 nehmen und dann die ersten Zeilen in das
> Erste rein, die nächsten 32 Zeilen in das Zweite, ... hm, ist nicht so
> hybsch hinzuschreiben.

Vielleicht doch einmal dem Synthesizer das Leben nicht unnötig schwer 
machen und sich vom Ansatz mit dem mehrdimensionalen Array lösen? Das 
ist kein C-Compiler...

Besser wäre es vermutlich wenn du nur ein eindimensionales (x4) Array 
benutzt. Beim Einlesen brauchst du nur einen einzelnen Zähler der pro 
Takt hochzählt. Auslesen sollte ähnlich gehen...

von Gustl B. (-gb-)


Lesenswert?

Du meinst ich kann da ein einzelnes
1
array (0 to 19199) of std_logic_vector(3 downto 0);

19200 = 80*240

oder mit Zweierpotenzen dann 128*256=32768 anlegen? Wäre hybsch ... mit 
8 einzelnen 4Kx4 baut es zumindest fertig ohne zu meckern.

von Duke Scarring (Gast)


Lesenswert?

Gustl Buheitel schrieb:
> type ZEILE is array (0 to 127) of std_logic_vector(3 downto 0);
> type FELD is array (0 to 255) of ZEILE;
> signal FRAME: FELD;
>
> begin
>
> process begin
>    wait until rising_edge(CLK_EXT);
>
>   FRAME(to_integer(line_counter))(row_counter) <= DATA;

Ne, so wird das nix. Du hast ja hier ein 3D-Array. BRAM ist aber nur 2D.
FELD und ZEILE mußt Du zu einer Adresse zusammenfassen.
Außerdem empfehle ich Dual-Port-Memory, da kannst Du auf einem Port 
schreiben und gleichzeitig auf dem anderen Port lesen.

Aber schau wirklich mal in den UG627.

Duke

von Gustl B. (-gb-)


Lesenswert?

Ja ne, ich hab das ziemlich 1:1 hierher:

http://www.lothar-miller.de/s9y/archives/39-Mehrdimensionale-Arrays.html

Also es geht 3d, aber ich habe Speicher beschrieben gehabt der nicht in 
den Memory Organizations gelistet ist, bzw. zuviele davon.

von Gustl B. (-gb-)


Angehängte Dateien:

Lesenswert?

So, es funktioniert!

Sehr seltsam finde ich aber, dass es auch graue Pixel gibt. In meinem 
VHDL setze ich ein Pixel immer entweder auf schwarz oder weiß aber nie 
grau und trotzdem sehen die auf dem Monitor grau aus. Klar das finde ich 
gut weil ist ja beim TDS auch so, aber auch da im Displaydatenblatt 
werden nie Graustufen erwähnt und auch nicht übertragen, das Pixel ist 
entweder 0 oder 1.

Egal, noch etwas ist das Bild an sich, das ist außerhalb des Rahmens mit 
der Wellenformanzeige total statisch und schön ruhig, aber innen, da 
habe ich ein leichtes Flackern. Das wirkt unruhig. Also finde ich nicht 
gut, aber könnte natürlich der Grund für die grauen Pixel sein die 
einfach oft ein und ausgeschalten werden.

Im Anhang Fotos vom Board, ja man muss da was wegschneiden wenn man von 
der Unterseite ranwill. Und auch das Datenblatt des Displays. Also für 
alle die es nachbaslteln möchten.

Ich werde noch irgendwann "soonish" ein kleines FPGA Board kaufen und 
direkt in das TDS einbauen samt VGA-Buchse. Dann gibt es auch Schaltplan 
und VHDL.

Ich speichere jetzt ein Vollbild
1
type FELD is array (0 to 32767) of std_logic_vector(3 downto 0);
2
signal frame: FELD;

das braucht 8 BRAMs.

gustl

von Peter S. (psavr)


Lesenswert?

Gucke genau: Grau == 50% der Pixel schwarz die anderen 50% weiss

von Gustl B. (-gb-)


Angehängte Dateien:

Lesenswert?

Nein, das stimmt so nicht, klar, das könnte man meinen weil es so 
aussieht, aber auch der Rahmen und die Gitterlinien sind in Grau.

Aber: Es flackert und das macht, dass es Grau aussieht. Wen man genau 
auf das Display des TDS2xx starrt, dann sieht man, dass es auch dort 
minimal flackert, also alles was in Grau ist.

In dem Foto sieht man das und auch, dass unten im Foto immer 2 Pixel 
übereinander schwarz sind. Am TDS ist das die Mittellinie und das sind 
durchgezogene vertikale kurze Striche in Grau. Hier habe ich es genau so 
getroffen als eben diese zwei Pixel dunkel waren.

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


Lesenswert?

Gustl Buheitel schrieb:
> Wen man genau auf das Display des TDS2xx starrt, dann sieht man, dass es
> auch dort minimal flackert, also alles was in Grau ist.
Aber weil das alte SW-STN-Display langsamer ist, sieht man dort das 
Flackern nur ganz leicht. Mit solcher Modulation konnten die Displays 
locker 16 Graustufen darstellen...

: Bearbeitet durch Moderator
von Gustl B. (-gb-)


Lesenswert?

Ja, voll doof weil hier am TFT flackert das ganz ordentlich und ich 
wollte doch ein hybsches VGA Bild. Ich muss mal gucken ob da immer nur 
zwei oder doch mehrere Bilder abwechseln für das Grau. Sonst könnte man 
zwei Vollbilder speichern und dann echtes Grau ausgeben ...

: Bearbeitet durch User
von Gustl B. (-gb-)


Angehängte Dateien:

Lesenswert?

So ... mit nur zwei gespeicherten Vollbildern flackert es noch manchmal, 
jetzt mache ich drei Vollbilder, also 24 BRAMs und es passt super!

Ja, jetzt bin ich auf der Suche nach einem FPGA Board das folgendes 
erfüllt:

- 5V oder 3,3V Eingang
- 20+ IOs
- >= 64KBytes BRAM
- Klein, < 10cm x 10cm
- JTAG
- Flash für Bitstream
- Kein/wenig sonstiges Zeug wie Schlter, Buttons, ...
- Am liebsten Xilinx FPGA
- < 50€ besser < 30€

Gibt es sowas? Irgendwie finde ich das seltsam dass selbst so Boards mit 
echt kleinem und auch alten FPGA gleich um die 100€ kosten, das muss 
doch für deutlich weniger machbar sein.

von user (Gast)


Lesenswert?

Es gibt das DE0-nano, ist aber von Altera. Kostet ca 80$.
http://www.terasic.com.tw/cgi-bin/page/archive.pl?No=593

von Gustl B. (-gb-)


Lesenswert?

Ja, richtig das sieht ganz fein aus habe halt mit Altere bisher nix am 
Hut.

Ich habe mir jetzt das hier geshoppt um es ins TDS einzubauen. Aber der 
Preis? Wieviel davon ist wohl Gewinn? Die Hälfte? Oder ist das wirklich 
so teuer zu fertigen?

von Duke Scarring (Gast)


Lesenswert?

Gustl Buheitel schrieb:
> - 5V oder 3,3V Eingang
> - 20+ IOs
> - >= 64KBytes BRAM
> - Klein, < 10cm x 10cm
> - JTAG
> - Flash für Bitstream
> - Kein/wenig sonstiges Zeug wie Schlter, Buttons, ...
> - Am liebsten Xilinx FPGA
> - < 50€ besser < 30€
Ein Lattice MachXO2-Breakout-Board mit selbst rangestricktem SRAM und 
TXS0108E als Pegelwandler (wo wirklich nötig) dürfte alle Deine 
Anforderungen erfüllen.

Duke

von -gb- (Gast)


Lesenswert?

Danke! Ja diese Lattice Boards sehen in der Tat gut aus, haben vor allem 
viel IO. Wie sieht es da aus mit BRAM und Programmieradapter?

Bei Xilinx verwende ich den Digilent JTAG der recht günstig ist, gibt es 
für Lattice auch was günstiges für JTAG?

Der iCE40HX-8k hat 128KBits BRAM, der LCMXO2-7000HE hat 550KBits BRAM, 
Letzteres wären ja um die 60KBytes, das ist schon ganz ordentlich.

Bisher habe ich Lattice nicht verwendet weil mir vieles unklar ist, eben 
wieviele Zusatzkosten für Programmer und Software auf mich zukommen und 
auch in wieweit ich meine schon geschriebenen VHDL Bausteinchen 
weiterverwenden kann.
Ausserdem ist das natürlich wieder Einarbeitungszeit.

Wie seht ihr das? Hat das Nachteile gegenüber Xilinx?

von Sigi (Gast)


Lesenswert?

Wie bei Xilinx ist bei Lattice der China-JTAG-Klon teuer
(so ca. 30-35 Euro). Billiger ist da Altera (ab 5 Euro).
Einarbeitung ist relativ einfach, wenn man schon mal mit
ISE oder Quartus gearbeitet hat.

von Gustl B. (-gb-)


Lesenswert?

OK Danke und was kostet ein Original JTAG? Das Originalteil von Digilent 
für Xilinx kostet so <50€.

von Sigi (Gast)


Lesenswert?

Orginal heisst eigentlich von Xilinx bzw. Altera bzw. Lattice.
Xilinx: ca. 200+x Euro (Klon: 30+kleines X)
Digilent: billiger, aber nicht kompatibel zum Xilinx JTAG !!
          (ist bei alten ISEs wichtig)
Altera: ca. 300 Euro (Klon: 5+kleines X oder Terasic: ca. 50 Euro)
Lattice: ca. 300 Euro (Klon: 30+kleines X)

von Duke Scarring (Gast)


Lesenswert?

-gb- schrieb:
> Danke! Ja diese Lattice Boards sehen in der Tat gut aus, haben vor allem
> viel IO. Wie sieht es da aus mit BRAM und Programmieradapter?
Bei dem MachXO2 ist ein FT2232H mit drauf, der hat eine JTAG-Engine. 
Also keine Extra-Kosten, sondern direkt USB und fertig. Den zweiten 
Kanal kann man für UART nutzen.

> Der iCE40HX-8k hat 128KBits BRAM, der LCMXO2-7000HE hat 550KBits BRAM,
> Letzteres wären ja um die 60KBytes, das ist schon ganz ordentlich.
Ich würde an Deiner Stelle noch einen externen RAM anschließen. Pins 
sind ja da. Zur Not kann man den SRAM auch auf Lochraster fädeln.

> Bisher habe ich Lattice nicht verwendet weil mir vieles unklar ist, eben
> wieviele Zusatzkosten für Programmer und Software auf mich zukommen und
> auch in wieweit ich meine schon geschriebenen VHDL Bausteinchen
> weiterverwenden kann.
> Ausserdem ist das natürlich wieder Einarbeitungszeit.
Software kostenlos, Programmer onboard. Und wenn man auf 
Xilinx-Primitives verzichtet, funktioniert auch der VHDL-Code 1:1.
Die Einarbeitungszeit hängt natürlich von Deiner Erfahrung ab, aber 
Lattice kocht auch nur mit Wasser. Die Prinzipien sind die selben, wie 
bei Xilinx und Altera.

Duke

von Gustl B. (-gb-)


Lesenswert?

Danke! Spricht etwas gegen das BRAM bei Lattice? Das lässt sich doch 
hoffentlich genauso verwenden wie bei Xilinx ...
Ich verzichte immer gerne auf externes RAM weil das eben langsam ist und 
man noch eine FSM braucht.

Das Digilent JTAG geht auch bei nicht Digilent Boards direkt am JTAG des 
FPGAs und kann auch das Flash beschreiben wenn es kein Xilinx-Flash ist.

Aber gut wenn diese manche Lattice Boards sich direkt über USB 
ansprechen lassen dann ist das sehr fein.

Hat Jemand Interesse an einer Sammelbestellung?

Ich würde das hier 
http://www.latticesemi.com/Products/DevelopmentBoardsAndKits/MachXO2BreakoutBoard.aspx 
bestellen.

von Duke Scarring (Gast)


Lesenswert?

Gustl Buheitel schrieb:
> Spricht etwas gegen das BRAM bei Lattice?
Nein.

> Das lässt sich doch
> hoffentlich genauso verwenden wie bei Xilinx ...
Ja. Zumindest, wenn mal eine allgemein Beschreibung für RAM verwendet, 
wie z.B. hier [1] (Abschnitt BRAM).

Im XO2-7000 [2] hast Du 26 EBR zur Verfügung. Das sind 'nur' 26 kByte.
Deswegen auch der Vorschlag mit dem SRAM.

Duke


[1]http://www.lothar-miller.de/s9y/archives/20-RAM.html
[2]http://www.latticesemi.com/~/media/Documents/DataSheets/MachXO23/MachXO2FamilyDataSheet.pdf

von Duke Scarring (Gast)


Lesenswert?

Gustl Buheitel schrieb:
> Hat Jemand Interesse an einer Sammelbestellung?
Wenn ich nicht genügend von den Dingern hier hätte, würde ich mich 
beteiligen...

von Gustl B. (-gb-)


Lesenswert?

Hallo, ich habe was gefunden:

http://www.ebay.com/itm/XILINX-XC3S200-FPGA-module-FPGA-kit-Development-board-SPARTAN-3-/281386582682?pt=LH_DefaultDomain_0&hash=item4183f2829a

der ist eigentlich mit den günstigen Lattice Boards vergleichbar, hat 
sehr viele IOs und auch 24kBytes BRAM. Ich glaube davon kauf ich mir ein 
paar. Sollte auch zollfrei gehen weil Estland in der EU ist.

von Duke Scarring (Gast)


Lesenswert?

Sieht auch gut aus. Allerdings braucht an bei den Modulen den passenden 
Programmer.

Duke

von Gustl B. (-gb-)


Lesenswert?

Den hat der auch in seinem Shop, kostet 30€ und auch da hat man wohl im 
keine Zollprobleme, also nicht wie mit dem anderen 
Xilinx-Programmer-Nachbar aus Fernost.

http://www.ebay.com/itm/XILINX-USB-JTAG-programming-cable-/281486615591?pt=LH_DefaultDomain_0&hash=item4189e8e427

: Bearbeitet durch User
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.