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!
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...
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
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.
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.
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.
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.
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.
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.
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.
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...
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.
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
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.
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
Gucke genau: Grau == 50% der Pixel schwarz die anderen 50% weiss
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
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
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
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.
Es gibt das DE0-nano, ist aber von Altera. Kostet ca 80$. http://www.terasic.com.tw/cgi-bin/page/archive.pl?No=593
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?
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
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?
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.
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)
-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
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.
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
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...
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.
Sieht auch gut aus. Allerdings braucht an bei den Modulen den passenden Programmer. Duke
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.