Forum: FPGA, VHDL & Co. Kein Bild bei eigenem VGA


von Kampi (Gast)


Lesenswert?

Hallo,

ich bin zur Zeit dabei eine VGA-Schnittstelle für meinen Zynq zu bauen. 
Die Schnittstelle soll für einen 640 x 480 Monitor sein.
Zur Zeit verwende ich diesen Code:
1
entity VGA_Top is
2
    Port ( Red : out STD_LOGIC;
3
           Green : out STD_LOGIC;
4
           Blue : out STD_LOGIC;
5
           HSync : out STD_LOGIC;
6
           VSync : out STD_LOGIC;
7
           Lock : out STD_LOGIC;
8
           Clock : in STD_LOGIC
9
           
10
           -- Controlsignals
11
           H_Sync_Check : out STD_LOGIC := '1';
12
           V_Sync_Check : out STD_LOGIC := '1';
13
           );
14
end VGA_Top;
15
16
architecture VGA_Top_Arch of VGA_Top is
17
18
    signal Clock_VGA : std_logic;
19
    signal Pixel_Counter : integer;
20
    signal Line_Counter : integer;
21
    
22
    component System is
23
        Port (
24
          Clock_In : in STD_LOGIC;
25
          Clock_Reset : in STD_LOGIC;
26
          Clock_Locked : out STD_LOGIC;
27
          Clock_Out : out STD_LOGIC);
28
    end component System;
29
30
begin
31
    
32
    Clock_25MHz : System port map (Clock, '1', Lock, Clock_VGA);
33
    
34
    process(Clock_VGA)
35
    
36
    begin
37
        if rising_edge(Clock_VGA) then
38
               
39
            Pixel_Counter <= Pixel_Counter + 1;
40
          
41
            -- Line End
42
            if(Pixel_Counter > 800) then
43
 
44
                Pixel_Counter <= 0;
45
                Line_Counter <= Line_Counter + 1;
46
                
47
                -- VSync
48
                if(Line_Counter < 2) then
49
                    VSync <= '0';
50
                    V_Sync_Check <= '0';
51
                 else
52
                    VSync <= '1';
53
                    V_Sync_Check <= '1';
54
                end if; 
55
                
56
                if(Line_Counter > 525) then
57
                    Line_Counter <= 0;
58
                end if;
59
60
            else
61
                --HSYNC
62
                if(Pixel_Counter < 96) then
63
                    HSync <= '0';
64
                    H_Sync_Check <= '0';
65
                else
66
                    HSync <= '1';
67
                    H_Sync_Check <= '1';
68
                end if; 
69
                
70
                -- Right Black
71
                if(Pixel_Counter < 112) then
72
                    Red <= '0';
73
                    Green <= '0';
74
                    Blue <= '0';
75
                end if; 
76
                
77
                -- Color
78
                if(Pixel_Counter < 752) then
79
                    Red <= '1';
80
                end if; 
81
                
82
                -- Left Black
83
                if(Pixel_Counter < 800) then
84
                    Red <= '0';
85
                    Green <= '0';
86
                    Blue <= '0';
87
                end if; 
88
                     
89
            end if; 
90
        end if;  
91
    end process;
92
end VGA_Top_Arch;

Theoretisch sollte ich doch jetzt am Bildschirm Rot sehen oder?
Die Länge der Signale VSync und HSync habe ich überprüft und die sind 
soweit richtig:

V-Sync
Länge: 16,79ms
Pulsweite: 64µs

H-Sync
Länge: 31,84µs
Pulsweite: 3,81µs

Allerdings bleibt mein Bildschirm schwarz.
Wo ist der Fehler?

Danke und Gruß
Daniel

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


Lesenswert?

Vorneweg: nimm statt den [ code ] Tags besser die [ vhdl ] Tags...

Kampi schrieb:
> Allerdings bleibt mein Bildschirm schwarz.
> Wo ist der Fehler?
Dein Verständnis vom Verhalten von Signalen im Prozess:
die letzte Zuweisung an Rot "gewinnt". Und das ist bei dir
1
                if(Pixel_Counter < 800) then
2
                    Red <= '0';
Probiers mal so:
1
                -- Left Black
2
                if(Pixel_Counter < 800) then
3
                    Red <= '0';
4
                    Green <= '0';
5
                    Blue <= '0';
6
                end if; 
7
8
                -- Color
9
                if(Pixel_Counter < 752) then
10
                    Red <= '1';
11
                end if; 
12
                
13
                -- Right Black
14
                if(Pixel_Counter < 112) then
15
                    Red <= '0';
16
                    Green <= '0';
17
                    Blue <= '0';
18
                end if;
Und wenns funktioniert, dann überleg mal, warum... ;-)

Ich würde es Übrigens nicht mit den "kleiner"-Abfragen machen, sondern 
einfach mit "gleich"-Abfragen. Vorteil: dann ist die Reihenfolge egal...

: Bearbeitet durch Moderator
von Kampi (Gast)


Lesenswert?

Hallo Lothar,

danke für die fixe Antwort.
Es hat leider keine Besserung gebracht. :(
Hin und wieder flackert an dem Monitor die "No Signal" Meldung auf, aber 
ansonsten bleibt er schwarz.
Das mit den Gleichheitszeichen meinst du nur bei den Abfragen für die 
Farbe bzw. die Schwarzschultern oder? Hab das mal für die drei Abgleiche 
gemacht.
1
begin
2
    
3
    Clock_25MHz : System port map (Clock, '1', Lock, Clock_VGA);
4
    
5
    process(Clock_VGA)
6
    
7
    begin
8
        if rising_edge(Clock_VGA) then
9
               
10
            Pixel_Counter <= Pixel_Counter + 1;
11
          
12
            -- Line End
13
            if(Pixel_Counter > 800) then
14
 
15
                Pixel_Counter <= 0;
16
                Line_Counter <= Line_Counter + 1;
17
                
18
                -- VSync
19
                if(Line_Counter < 2) then
20
                    VSync <= '0';
21
                    V_Sync_Check <= '0';
22
                 else
23
                    VSync <= '1';
24
                    V_Sync_Check <= '1';
25
                end if; 
26
                
27
                if(Line_Counter > 525) then
28
                    Line_Counter <= 0;
29
                end if;
30
31
            else
32
                --HSYNC
33
                if(Pixel_Counter < 96) then
34
                    HSync <= '0';
35
                    H_Sync_Check <= '0';
36
                else
37
                    HSync <= '1';
38
                    H_Sync_Check <= '1';
39
                end if; 
40
                
41
                -- Left Black
42
                if(Pixel_Counter = 800) then
43
                    Red <= '0';
44
                    Green <= '0';
45
                    Blue <= '0';
46
                end if; 
47
                
48
                -- Color
49
                if(Pixel_Counter = 752) then
50
                    Red <= '1';
51
                end if; 
52
                
53
                -- Right Black
54
                if(Pixel_Counter = 112) then
55
                    Red <= '0';
56
                    Green <= '0';
57
                    Blue <= '0';
58
                end if; 
59
                     
60
            end if; 
61
        end if;  
62
    end process;
63
end VGA_Top_Arch;

: Bearbeitet durch Moderator
von Kampi (Gast)


Lesenswert?

Edit: Falsche Klammer -.-
Wenn es geht bitte korrigieren :(

von Holger (Gast)


Lesenswert?

Kampi schrieb:
> Die Länge der Signale VSync und HSync habe ich überprüft und die sind
> soweit richtig:
Wie hast Du das festgestellt?
Hast Du die Frequenz von Clock_VGA geprüft?

von Kampi (Gast)


Angehängte Dateien:

Lesenswert?

Hey,

die Impulse habe ich mir mittels LA ausgeben lassen (siehe Anhang).
Die Frequenz lasse ich über den Clock Wizard erzeugen und die liegt bei 
25,6MHz.

von Fpgakuechle K. (Gast)


Lesenswert?

Kampi schrieb:
> Hey,
>
> die Impulse habe ich mir mittels LA ausgeben lassen (siehe Anhang).
> Die Frequenz lasse ich über den Clock Wizard erzeugen und die liegt bei
> 25,6MHz.

Will der Monitor  die Syncs low- oder high-active?

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


Lesenswert?

Kampi schrieb:
> Die Länge der Signale VSync und HSync habe ich überprüft
Erkennt der Monitor das Timing?
Mich wundert ein wenig, dass du in 800x600 auch die Sync-Signale 
untetbringst. Sind die normalerweise nicht "ausserhalb"?

von Kampi (Gast)


Angehängte Dateien:

Lesenswert?

Lothar Miller schrieb:
> Kampi schrieb:
>> Die Länge der Signale VSync und HSync habe ich überprüft
> Erkennt der Monitor das Timing?
> Mich wundert ein wenig, dass du in 800x600 auch die Sync-Signale
> untetbringst. Sind die normalerweise nicht "ausserhalb"?

Hey,

ich habe mal ein PDF angehängt, wo ich mir die Infos zum VGA raus geholt 
habe. Hab noch nie wirklich mit VGA gearbeitet, von daher kann es gut 
sein, dass ich da was falsch verstanden habe :(

Mit positiven Impulsen habe ich es gerade getestet. Es brachte leider 
keine Änderung.

von Fpgakuechle K. (Gast)


Lesenswert?

Lothar Miller schrieb:
> Kampi schrieb:
>> Die Länge der Signale VSync und HSync habe ich überprüft
> Erkennt der Monitor das Timing?
> Mich wundert ein wenig, dass du in 800x600 auch die Sync-Signale
> untetbringst. Sind die normalerweise nicht "ausserhalb"?

Er will wohl 640x480, nicht 800x600.

MfG

von Kampi (Gast)


Lesenswert?

Der Monitor erkennt auf jeden Fall ein Signal. Nach jedem Programmieren 
verschwindet die "No Signal" Meldung.

von Fpgakuechle K. (Gast)


Lesenswert?

Kampi schrieb:


> Mit positiven Impulsen habe ich es gerade getestet. Es brachte leider
> keine Änderung.

Hier steht was von low-active vsync by 640x480:
http://en.wikipedia.org/wiki/Video_Graphics_Array

Wenn der Monitor den Modus nicht erkennt (im OSD Status oder info 
auswählen, dann stimmen die syncs nicht. Erkennt er den Mosus richtig, 
aber die Farben, Helligkeit stimmen nicht, dann ist meist das Farbsignal 
außerhalb des sichtbaren Bereichs nicht schwarz.
Wenn der Moni den Modus nicht unterstützt, dann sagt das OSD meist not 
supported mode oder so.

MfG

von Fpgakuechle K. (Gast)


Lesenswert?

Kampi schrieb:
> Lothar Miller schrieb:
>> Kampi schrieb:
>>> Die Länge der Signale VSync und HSync habe ich überprüft
>> Erkennt der Monitor das Timing?
>> Mich wundert ein wenig, dass du in 800x600 auch die Sync-Signale
>> untetbringst. Sind die normalerweise nicht "ausserhalb"?
>
> Hey,
>
> ich habe mal ein PDF angehängt, wo ich mir die Infos zum VGA raus geholt
> habe. Hab noch nie wirklich mit VGA gearbeitet, von daher kann es gut
> sein, dass ich da was falsch verstanden habe :(
>
> Mit positiven Impulsen habe ich es gerade getestet. Es brachte leider
> keine Änderung.

Dort:
http://ece.wpi.edu/~rjduck/vga_controller_640_60.vhd
ist ein vga-controller den digilent für die xilinx starterkits 
verwendet.

Du kannst ihn ja mal parallel zu deinem simulieren und nach 
Unterschieden schauen. Der von digilent richtet sich nach VESA-Norm die 
auch von TFT-Monis unterstützt wird. Zumindest die 800x600 Variante habe 
ich selbst getestet und die tut es.

MfG,

von Kampi (Gast)


Lesenswert?

Hallo,

so von der Logik her sieht das in etwa so aus wie bei mir, nur wie Werte 
für die Sync-Signale sind anders.
Da verstehe ich nicht so ganz wie die drauf gekommen sind.
Hab die Werte jetzt mal übernommen (und meinen Code etwas umgeordnet, 
sodass ich nicht mehr diesen einen großen Prozess habe).

Wo ich gerade schon dabei bin...
Wie ist das am besten wenn ich mehrere Sachen habe die bei einem 
Clockimpuls gemacht werden sollen. Alles in einen Prozess oder lieber 
aufteilen (quasi wie bei meinem VGA Code und dem Beispielcode - ein 
schönes Beispiel)?

von Kampi (Gast)


Lesenswert?

Edit:

Der neue Code brachte im Bezug auf Timings keinen Unterschied. Sieht am 
LA immer noch gleich aus.

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


Lesenswert?

Kampi schrieb:
> Sieht am LA immer noch gleich aus.
Und wie? Zeig doch mal ein paar Screenshots...

von Kampi (Gast)


Angehängte Dateien:

Lesenswert?

So hier :)

von Gustl B. (-gb-)


Lesenswert?

So hier eine schöne Liste aller VGA Signalzeiten.
http://tinyvga.com/vga-timing

Morgen oder Übermorgen paste ich hier gerne mein funktionierendes 
1024x768 mit 75mHz Pixeltakt.

von Kampi (Gast)


Lesenswert?

Hey,

genau die Seite habe ich auch bereits gefunden :)
Wäre toll wenn du deins mal zeigen könntest. Von den Sync Signalen sieht 
meins (nach LA) richtig aus....ich muss nur noch schauen wie ich jetzt 
die Farben da rein bekomme :)

Gruß

von Gustl B. (-gb-)


Lesenswert?

Für das Bild musst du die einzelnen Bits des DA-Wandlers entsprechend 
setzen, aber nur innerhalb des sichtbaren Bereichs. Man sieht auch was 
wenn man die außerhalb gesetzt lässt aber einige Monitore skalieren dann 
das Bild nicht richtig. Also RGB Ausgänge sollten auf 0 sein wenn es 
außerhalb des sichtbaren Bereichs ist.

von Kampi (Gast)


Lesenswert?

Hey,

das war auch meine Vermutung. Ich habe deswegen mal die Farbe Rot auf 
"1" gesetzt, aber nichts ist passiert.
Selbst wenn dann was falsch skaliert wird, müsste da ja was angezeigt 
werden :)

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


Lesenswert?

Gustl Buheitel schrieb:
> Für das Bild musst du die einzelnen Bits des DA-Wandlers entsprechend
> setzen,
Ich gehe jetzt mal davon aus, dass der jeweilige "Farbpin" des FPGA 
direkt an die VGA Buchse geführt ist...

von Gustl B. (-gb-)


Lesenswert?

Ja gut wenn das ein Widerstandsnetz DA-Wandler ist dann sind das mehrere 
Bits, wenn man da irgendeines auf 1 setzt kann das noch ziemlich dunkel 
sein. Wie muss eigentlich die Spannung bei den Farben sein? Ist da 3,3V 
das Maximum oder wäre das bei mehr noch heller? Oder passt das der 
Monitor dynamisch an?

von Kampi (Gast)


Lesenswert?

Hey,

schau mal hier ins Datenblatt vom Zybo:

https://www.digilentinc.com/Data/Products/ZYBO/ZYBO_sch.pdf

Ich habe da einfach mal das LSB der Farben genommen (also R0).
Ob das hell genug ist weiß ich leider nicht.

von Gustl B. (-gb-)


Lesenswert?

Nimm mal das höchste Bit, das LSB ist das dunkelste. Noch besser du 
setzt alle auf 1 oder 0 wenn du es am hellsten willst.

von -gb- (Gast)


Lesenswert?

1
library IEEE;
2
use IEEE.STD_LOGIC_1164.ALL;
3
use IEEE.numeric_std.all;
4
5
entity vga is
6
  port(clk75_in: in std_logic;
7
     bin  : in std_logic; -- eingang, wenn bin '1' ist dann wird das aktuelle Pixel weiß
8
     horizontal_counter : out std_logic_vector (10 downto 0); --  müsste man nicht herausreichen
9
     vertical_counter   : out std_logic_vector (9 downto 0); -- das auch nicht
10
       red_out   : out std_logic_vector(6 downto 0); -- 7 Bits je Farbe
11
       green_out : out std_logic_vector(6 downto 0);
12
       blue_out  : out std_logic_vector(6 downto 0);
13
       hs_out    : out std_logic;
14
       vs_out    : out std_logic);
15
end vga;
16
17
architecture Behavioral of vga is
18
19
signal hc: integer range 0 to 1328;
20
signal vc: integer range 0 to 806;
21
22
begin
23
horizontal_counter <= std_logic_vector(to_unsigned(hc,11));
24
vertical_counter <= std_logic_vector(to_unsigned(vc,10));
25
26
--BILD begint bei Sync-pulse
27
process
28
begin
29
  wait until rising_edge(clk75_in);
30
  if (hc >= 280 ) -- 280 = Sync-pulse + Back-porch
31
  and (hc < 1304 ) -- 1304 = Sync-pulse + Back-porch + Visible-area
32
  and (vc >= 35 ) -- 35 = Sync-pulse + Back-porch
33
  and (vc < 803 ) -- 803 = Sync-pulse + Back-porch + Visible-area
34
  and bin = '1' then
35
    red_out    <= "1111111";
36
    green_out <= "1111111";
37
    blue_out  <= "1111111";
38
  else
39
    red_out    <= "0000000";
40
    green_out <= "0000000";
41
    blue_out  <= "0000000";
42
  end if;
43
  
44
  if (hc > 0) and (hc < 136) then hs_out <= '0'; else hs_out <= '1'; end if; -- 136 = Sync-pulse
45
  if (vc > 0) and (vc <   6) then vs_out <= '0'; else vs_out <= '1'; end if; -- 6 = Sync-pulse
46
   
47
  hc <= hc + 1;
48
  if (hc = 1328) then -- 1328 = Whole-line
49
    vc <= vc + 1;
50
    hc <= 0;
51
  end if;
52
  if (vc = 806) then  -- 806  = Whole-frame    
53
    vc <= 0;
54
  end if;
55
end process;
56
57
end Behavioral;

von -gb- (Gast)


Lesenswert?

Minimal sieht das dann so aus:
1
library IEEE;
2
use IEEE.STD_LOGIC_1164.ALL;
3
use IEEE.numeric_std.all;
4
5
entity vga is
6
  port(clk75_in: in std_logic;
7
       red_out   : out std_logic_vector(6 downto 0); -- 7 Bits je Farbe
8
       green_out : out std_logic_vector(6 downto 0):="0000000";
9
       blue_out  : out std_logic_vector(6 downto 0):="0000000";
10
       hs_out    : out std_logic;
11
       vs_out    : out std_logic);
12
end vga;
13
14
architecture Behavioral of vga is
15
16
signal hc: integer range 0 to 1328; - horizontal zähler
17
signal vc: integer range 0 to 806; --vertikal zähler
18
19
begin
20
-- Bild begint bei Sync-pulse
21
process
22
begin
23
  wait until rising_edge(clk75_in);
24
  if (hc >= 280 ) -- 280 = Sync-pulse + Back-porch = beginn sichtbarer Bereich (horizontal)
25
  and (hc < 1304 ) -- 1304 = Sync-pulse + Back-porch + Visible-area 
26
  and (vc >= 35 ) -- 35 = Sync-pulse + Back-porch = beginn sichtbarer Bereich (vertikal)
27
  and (vc < 803 ) -- 803 = Sync-pulse + Back-porch + Visible-area
28
  and (hc < 792) then -- linke Hälfte 792 = 280 + 1024/2
29
    red_out    <= "1111111";
30
  else
31
    red_out    <= "0000000";
32
  end if;
33
  
34
  if (hc > 0) and (hc < 136) then hs_out <= '0'; else hs_out <= '1'; end if; -- 136 = Sync-pulse
35
  if (vc > 0) and (vc <   6) then vs_out <= '0'; else vs_out <= '1'; end if; -- 6 = Sync-pulse
36
   
37
  hc <= hc + 1;
38
  if (hc = 1328) then -- 1328 = Whole-line
39
    vc <= vc + 1;
40
    hc <= 0;
41
  end if;
42
  if (vc = 806) then  -- 806  = Whole-frame    
43
    vc <= 0;
44
  end if;
45
end process;
46
47
end Behavioral;

Jetzt sollte die linke Hälfte des Bildes rot sein

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


Lesenswert?

Kampi schrieb:
> Ich habe da einfach mal das LSB der Farben genommen (also R0).
> Ob das hell genug ist weiß ich leider nicht.
LSB bedeutet "das am wenigsten signifikante Bit". Und jetzt denk mal 
drüber nach, ob "das am wenigsten signifikante Bit" etwas gut 
erkennbares ausmacht.

Kampi schrieb:
> Wo ist der Fehler?
Wie so oft: nicht im geposteten Code, sondern ganz woanders.
Wenn das Ausgangssignal wenigstens ein Vektor oder die Hardware bekannt 
gewesen wäre...

Kampi schrieb:
> Die Frequenz lasse ich über den Clock Wizard erzeugen und die liegt bei
> 25,6MHz.
Du könntest hier auch einfach mit einem Clock-Enable arbeiten, dann 
hättest du ganz einfach ganz genau 25MHz:
1
   signal en_25M : std_logic := '0';
2
3
    process (PS_CLK) begin
4
        if rising_edge(PS_CLK) then
5
            en_25M <= not en_25M;
6
            if (en_25M='1') then
7
                -- dein Code
8
            end if;
9
        end if;
10
   end process;
Das erleichtert dann den Übergang von anderen Komponenten, die mit den 
50MHz arbeiten...

: Bearbeitet durch Moderator
von Kampi (Gast)


Lesenswert?

Hallo Lothar,

danke für den Hinweis. Im Nachhinein wäre es wahrscheinlich echt 
leichter gewesen die 25MHz zu nehmen, anstatt die 25,175 (vor allem wenn 
man dran denkt, dass der Clock Wizard leicht buggy ist....).
Ich hab den Test gestern Abend noch mal mit dem MSB gemacht und da kam 
ebenfalls nichts :(
Ich probier heute Abend noch mal den gezeigten Code aus und wenn es dann 
funktioniert, gleiche ich das mal mit meinem ab und schaue wo der Hund 
begraben ist.

Danke & Gruß

von Gustl B. (-gb-)


Lesenswert?

Du kannst auch 800x600 mit 50mHz Pixeltakt machen. Werde ich auch in 
Zukunft verwenden. Die Dogilent Boards haben einen 50mHz Quarz.
http://tinyvga.com/vga-timing/800x600@72Hz

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


Lesenswert?

Kampi schrieb:
> Ich hab den Test gestern Abend noch mal mit dem MSB gemacht und da kam
> ebenfalls nichts :(
Nimm wie schon vorgeschlagen den ganzen Vektor VGA_R0..4 und beschalte 
auch die VGA_Bx und VGA_Gx Pins mit "gültigen" Pegeln...

Denn theoretisch hätte es ausgereicht, an irgendeinem der VGA-Pins 
herumzuzappeln, wenn die anderen alle hochohmige Eingänge sind.

von Kampi (Gast)


Lesenswert?

Gut :)
Ich teste mal heute nach der Arbeit etwas rum.
Ich halte euch auf dem laufenden!

von Dirk (Gast)


Lesenswert?

Stimmen die Pin Zuweisungen ?

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


Lesenswert?

Dirk schrieb:
> Stimmen die Pin Zuweisungen ?
Kampi wird hoffentlich schon mal am Pin gemessen haben. Das ist 
eigentlich naheliegend. Und man kann einfach auch "binäres" VGA fahren, 
dann sind eben nur 8 Farben möglich: nix, R, G, B, RG, RB GB, RGB...

von -gb- (Gast)


Lesenswert?

Jetzt hab ich mal nach den Spannungen geguckt und lese gleich mehrfach, 
dass die Farben bei VGA von 0 bis 0.7V gehen. Das erstaunt mich jetzt 
schon, weil der FPGA ja 3,3V anlegt.

Die Frage ist jetzt: Kann ich da mit 3,3V was kaputt machen? Soll ich 
einen Spannungsteiler verwenden?

Danke!

von Falk B. (falk)


Lesenswert?

@ -gb- (Gast)

>Jetzt hab ich mal nach den Spannungen geguckt und lese gleich mehrfach,
>dass die Farben bei VGA von 0 bis 0.7V gehen.

Das ist auch so.

>Das erstaunt mich jetzt
>schon, weil der FPGA ja 3,3V anlegt.

Sicher?

>Die Frage ist jetzt: Kann ich da mit 3,3V was kaputt machen?

Keine Ahnung.

> Soll ich einen Spannungsteiler verwenden?

So ziemlich ALLE FPGA-Boards haben dort passende Spannungsteiler, eben 
um mit einfachsten Mitteln eine VGA-Ansteuerung zu erreichen.

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


Lesenswert?

-gb- schrieb:
> Die Frage ist jetzt: Kann ich da mit 3,3V was kaputt machen?
Nein. Du musst dann nur die Helligkeit ein wenig runterdrehen...

Bei dem Board ist es auch so gemacht:
Beitrag "Re: was haltet ihr von diesem Board?"

von Kampi (Gast)


Lesenswert?

Hey,

also mittlerweile weiß ich nicht wo der Fehler sein soll...
Ich habe diesen Code:
1
entity VGA_Top is
2
    Port ( Red : out STD_LOGIC_VECTOR(4 downto 0);
3
           Green : out STD_LOGIC_VECTOR(5 downto 0);
4
           Blue : out STD_LOGIC_VECTOR(4 downto 0);
5
           HSync : out STD_LOGIC;
6
           VSync : out STD_LOGIC;
7
           Lock : out STD_LOGIC;
8
           Clock : in STD_LOGIC;
9
           
10
           -- Controlsignals
11
           H_Sync_Check : out STD_LOGIC := '1';
12
           V_Sync_Check : out STD_LOGIC := '1'
13
           );
14
end VGA_Top;
15
16
architecture VGA_Top_Arch of VGA_Top is
17
18
    signal Clock_VGA : std_logic;
19
    signal Pixel_Counter : integer;
20
    signal Line_Counter : integer;
21
    
22
    component System is
23
        Port (
24
          Clock_In : in STD_LOGIC;
25
          Clock_Reset : in STD_LOGIC;
26
          Clock_Locked : out STD_LOGIC;
27
          Clock_Out : out STD_LOGIC);
28
    end component System;
29
30
begin
31
    
32
    Clock_25MHz : System port map (Clock, '1', Lock, Clock_VGA);
33
    
34
    process(Clock_VGA)
35
    begin
36
        if rising_edge(Clock_VGA) then
37
          if (Line_Counter >= 148 ) -- 280 = Sync-pulse + Back-porch = beginn sichtbarer Bereich (horizontal)
38
          and (Line_Counter < 784 ) -- 1304 = Sync-pulse + Back-porch + Visible-area 
39
          and (Pixel_Counter >= 35 ) -- 35 = Sync-pulse + Back-porch = beginn sichtbarer Bereich (vertikal)
40
          and (Pixel_Counter < 515 ) -- 803 = Sync-pulse + Back-porch + Visible-area
41
          and (Line_Counter < 468) then -- linke Hälfte 792 = 280 + 1024/2
42
            Red    <= "11111";
43
          else
44
            Red    <= "00000";
45
          end if;
46
        end if;        
47
    end process;
48
    
49
    -- Pixelcounter
50
    process(Clock_VGA)
51
    begin
52
        if rising_edge(Clock_VGA) then
53
            if(Pixel_Counter = 800) then
54
                Pixel_Counter <= 0;
55
                if(Line_Counter = 525) then
56
                    Line_Counter <= 0;
57
                else
58
                    Line_Counter <= Line_Counter + 1;
59
                end if; 
60
            else
61
                Pixel_Counter <= Pixel_Counter + 1;
62
            end if;
63
        end if;
64
    end process;
65
66
    -- HSync
67
    process(Clock_VGA)
68
    begin
69
        if rising_edge(Clock_VGA) then
70
            if((Pixel_Counter > 0) and (Pixel_Counter < 96)) then
71
                VSync <= '0';
72
                V_Sync_Check <= '0';
73
            else
74
                VSync <= '1';
75
                V_Sync_Check <= '1';
76
            end if;
77
        end if;
78
    end process; 
79
    
80
    -- VSync
81
    process(Clock_VGA)
82
    begin
83
        if rising_edge(Clock_VGA) then
84
            if((Line_Counter > 0) and (Line_Counter < 3)) then
85
                HSync <= '0';
86
                H_Sync_Check <= '0';
87
            else
88
                HSync <= '1';
89
                H_Sync_Check <= '1';
90
            end if;
91
        end if;
92
    end process; 
93
end VGA_Top_Arch;

Und meine Constraints sehen so aus
1
# Clock
2
set_property PACKAGE_PIN L16 [get_ports Clock]
3
set_property IOSTANDARD LVCMOS33 [get_ports Clock]
4
create_clock -period 8.000 -name sys_clk_pin -waveform {0.000 4.000} -add [get_ports Clock]
5
6
set_property IOSTANDARD LVCMOS33 [get_ports Lock]
7
set_property PACKAGE_PIN M14 [get_ports Lock]
8
9
# Farben
10
set_property PACKAGE_PIN F19 [get_ports {Red[4]}]
11
set_property PACKAGE_PIN G20 [get_ports {Red[3]}]
12
set_property PACKAGE_PIN J20 [get_ports {Red[2]}]
13
set_property PACKAGE_PIN L20 [get_ports {Red[1]}]
14
set_property PACKAGE_PIN M19 [get_ports {Red[0]}]
15
16
set_property IOSTANDARD LVCMOS33 [get_ports {Red[4]}]
17
set_property IOSTANDARD LVCMOS33 [get_ports {Red[3]}]
18
set_property IOSTANDARD LVCMOS33 [get_ports {Red[2]}]
19
set_property IOSTANDARD LVCMOS33 [get_ports {Red[1]}]
20
set_property IOSTANDARD LVCMOS33 [get_ports {Red[0]}]
21
22
set_property PACKAGE_PIN F20 [get_ports {Green[5]}]
23
set_property PACKAGE_PIN H20 [get_ports {Green[4]}]
24
set_property PACKAGE_PIN J19 [get_ports {Green[3]}]
25
set_property PACKAGE_PIN L19 [get_ports {Green[2]}]
26
set_property PACKAGE_PIN N20 [get_ports {Green[1]}]
27
set_property PACKAGE_PIN H18 [get_ports {Green[0]}]
28
29
set_property IOSTANDARD LVCMOS33 [get_ports {Green[5]}]
30
set_property IOSTANDARD LVCMOS33 [get_ports {Green[4]}]
31
set_property IOSTANDARD LVCMOS33 [get_ports {Green[3]}]
32
set_property IOSTANDARD LVCMOS33 [get_ports {Green[2]}]
33
set_property IOSTANDARD LVCMOS33 [get_ports {Green[1]}]
34
set_property IOSTANDARD LVCMOS33 [get_ports {Green[0]}]
35
36
set_property PACKAGE_PIN G19 [get_ports {Blue[4]}]
37
set_property PACKAGE_PIN J18 [get_ports {Blue[3]}]
38
set_property PACKAGE_PIN K19 [get_ports {Blue[2]}]
39
set_property PACKAGE_PIN M20 [get_ports {Blue[1]}]
40
set_property PACKAGE_PIN P20 [get_ports {Blue[0]}]
41
set_property IOSTANDARD LVCMOS33 [get_ports {Blue[4]}]
42
set_property IOSTANDARD LVCMOS33 [get_ports {Blue[3]}]
43
set_property IOSTANDARD LVCMOS33 [get_ports {Blue[2]}]
44
set_property IOSTANDARD LVCMOS33 [get_ports {Blue[1]}]
45
set_property IOSTANDARD LVCMOS33 [get_ports {Blue[0]}]
46
47
# Sync
48
set_property PACKAGE_PIN R19 [get_ports VSync]
49
set_property IOSTANDARD LVCMOS33 [get_ports VSync]
50
set_property PACKAGE_PIN P19 [get_ports HSync]
51
set_property IOSTANDARD LVCMOS33 [get_ports HSync]
52
53
# Kontrollsignale
54
set_property PACKAGE_PIN T20 [get_ports H_Sync_Check]
55
set_property IOSTANDARD LVCMOS33 [get_ports H_Sync_Check]
56
57
set_property PACKAGE_PIN U20 [get_ports V_Sync_Check]
58
set_property IOSTANDARD LVCMOS33 [get_ports V_Sync_Check]

Hab sie mit dem Schaltplan vom Zybo abgeglichen...die stimmen soweit.
Aber ich habe auf dem Monitor immer noch kein Bild :(
Der Monitor funktioniert, das habe ich mit einem Linuximage auf dem Zynq 
getestet.
Auch die Timings für den Sync stimmen (seit der Änderung schwanken die 
ab und an mal um 1-1,5µs aber das sollte hoffentlich nichts ausmachen).
Also wo zum Geier ist der kack Fehler -.-?

von Kampi (Gast)


Lesenswert?

Hey,

so....
Ich habe mal was getestet. Ich habe mir den Originalcode von -gb- 
genommen, den in mein Zynq gekloppt (mit einem Clock Wizard für die 
75MHz), die Constraints von mir genommen und es getestet.
Und siehe da....es kommt eine "Out of Range" Meldung (wahrscheinlich 
weil das Bild zu groß ist -> passe es jetzt mal an).
D.h. was ich sagen kann ist, dass die Constraints richtig sind (oh 
wunder ^.^) und mein Code irgendwo eine Macke hat :)

von Cornelius (Gast)


Lesenswert?

Kampi schrieb:
> es kommt eine "Out of Range" Meldung (wahrscheinlich
> weil das Bild zu groß ist
Nein, die Meldung kommt, weil die Frequenzen nicht stimmen.

Hast Du mal einen Link zum Schaltplan des Boards?

von Kampi (Gast)


Lesenswert?

Hey,

so habe die Frequenz nun auf 25,175MHz gestellt und siehe da....es läuft 
:)
Das Board findet ihr hier:

http://www.digilentinc.com/Data/Products/ZYBO/ZYBO_sch.pdf

Jetzt muss ich mal schauen woran es bei mir liegt...

von Kampi (Gast)


Lesenswert?

Meine Fresse Vivado ist so buggy -.-
1 Stunde nach einem Bug von meinem Clock gesucht der auf einmal da war 
und nach einem Neustart des Programms war er weg -.-
Der VGA läuft nun....der Fehler war richtig, richtig, richtig 
dämlich...es lief nämlich quasi schon gestern.
Ich hatte statt

if (Pixel_Counter >= 144 ) and (Pixel_Counter < 784 )
and (Line_Counter >= 35 ) and (Line_Counter < 515 ) and (Pixel_Counter < 
304) then

nämlich

if (Line_Counter >= 144 ) and (Line_Counter < 784 )
and (Pixel_Counter >= 35 ) and (Pixel_Counter < 515 ) and (Line_Counter 
< 304) then

stehen, sprich die Counter waren vertauscht und die Bedingungen sind nie 
eingetroffen...
Der Vollständigkeithalber noch mal der funktionierende Code (hab den 
jetzt mal geordnet und jedem Funktionsblock einen einzelnen Prozess 
gegeben):
1
----------------------------------------------------------------------------------
2
-- Company:         www.kampis-elektroecke.de
3
-- Engineer:        Daniel Kampert
4
-- 
5
-- Create Date:     02.08.2014 13:17:51
6
-- Design Name: 
7
-- Module Name:     VGA_Top - VGA_Top_Arch
8
-- Project Name: 
9
-- Target Devices:  XC7Z010CLG400-1
10
-- Tool Versions:   Vivado 2014.2
11
-- Description:     VGA Interface for a 640 x 480 Pixel Screen
12
-- 
13
-- Dependencies: 
14
-- 
15
-- Revision:
16
-- Revision         0.01 - File Created
17
-- Additional Comments:
18
-- 
19
----------------------------------------------------------------------------------
20
21
library IEEE;
22
use IEEE.STD_LOGIC_1164.ALL;
23
24
-- Uncomment the following library declaration if using
25
-- arithmetic functions with Signed or Unsigned values
26
--use IEEE.NUMERIC_STD.ALL;
27
28
-- Uncomment the following library declaration if instantiating
29
-- any Xilinx leaf cells in this code.
30
--library UNISIM;
31
--use UNISIM.VComponents.all;
32
33
entity VGA_Top is
34
    Port ( Red : out STD_LOGIC_VECTOR(4 downto 0);
35
           Green : out STD_LOGIC_VECTOR(5 downto 0);
36
           Blue : out STD_LOGIC_VECTOR(4 downto 0);
37
           HSync : out STD_LOGIC;
38
           VSync : out STD_LOGIC;
39
           Lock : out STD_LOGIC;
40
           Clock : in STD_LOGIC;
41
           );
42
end VGA_Top;
43
44
architecture VGA_Top_Arch of VGA_Top is
45
46
    signal Clock_VGA : std_logic;
47
    signal Pixel_Counter : integer  range 0 to 1328;
48
    signal Line_Counter : integer  range 0 to 806;
49
    
50
    component System is
51
        Port (
52
          Clock_In : in STD_LOGIC;
53
          Clock_Reset : in STD_LOGIC;
54
          Clock_Locked : out STD_LOGIC;
55
          Clock_Out : out STD_LOGIC);
56
    end component System;
57
58
begin
59
    
60
    Clock_25MHz : System port map (Clock, '1', Lock, Clock_VGA);
61
    
62
    -- Picture
63
    process(Clock_VGA)
64
    begin
65
        if rising_edge(Clock_VGA) then
66
          if (Pixel_Counter >= 144 )
67
          and (Pixel_Counter < 784 )
68
          and (Line_Counter >= 35 )
69
          and (Line_Counter < 515 )
70
          and (Pixel_Counter < 304) then 
71
            Red    <= "11111";
72
          else
73
            Red    <= "00000";
74
          end if;
75
        end if;        
76
    end process;
77
78
    -- HSync
79
    process(Clock_VGA)
80
    begin
81
        if rising_edge(Clock_VGA) then
82
            if((Pixel_Counter > 0) and (Pixel_Counter < 96)) then
83
                HSync <= '0';
84
            else
85
                HSync <= '1';
86
            end if;
87
        end if;
88
    end process; 
89
    
90
    -- VSync
91
    process(Clock_VGA)
92
    begin
93
        if rising_edge(Clock_VGA) then
94
            if((Line_Counter > 0) and (Line_Counter < 3)) then
95
                VSync <= '0';
96
            else
97
                VSync <= '1';
98
            end if;
99
        end if;
100
    end process; 
101
    
102
    -- Pixelcounter
103
    process(Clock_VGA)
104
    begin
105
        if rising_edge(Clock_VGA) then
106
            Pixel_Counter <= Pixel_Counter + 1;
107
            if(Pixel_Counter = 800) then
108
                Pixel_Counter <= 0;
109
                Line_Counter <= Line_Counter + 1;
110
            end if; 
111
            
112
            if(Line_Counter = 525) then
113
                Line_Counter <= 0;
114
            end if;
115
        end if;
116
    end process;  
117
end VGA_Top_Arch;

Hab dann direkt noch eine weitere Verständnisfrage.
Mal angenommen ich habe jetzt in meinem RAM ein Bild liegen, welches ich 
auf dem Monitor ausgeben will.
Dann würde ich diesen Prozess
1
    process(Clock_VGA)
2
    begin
3
        if rising_edge(Clock_VGA) then
4
          if (Pixel_Counter >= 144 )
5
          and (Pixel_Counter < 784 )
6
          and (Line_Counter >= 35 )
7
          and (Line_Counter < 515 )
8
          and (Pixel_Counter < 304) then 
9
            Red    <= "11111";
10
          else
11
            Red    <= "00000";
12
          end if;
13
        end if;        
14
    end process;
einfach dahingehend ändern, dass bei jedem Clock (wenn die Bedingungen 
erfüllt sind) ein bestimmtes Pixel ausgegeben wird.
Also sowas wie (Pseudocode):

if(Clock) then
   Counter + 1
   Farbe = Pixelarray(Counter)

Sehe ich das richtig?

Danke noch mal für die Hilfe :)
Freue mich, dass es nun funktioniert! Und vor allem, dass meine erste 
Idee quasi korrekt war (bis auf den ein oder anderen kleinen 
Schönheitsfehler). :)

Gruß
Daniel

von Gustl B. (-gb-)


Lesenswert?

Du hast das Bild dann als Array von Werten, also wenn du ein Bild mit 9 
Zeilen und je Zeile 16 Pixel mit je 8Bit Farbe, also ein 16x9 Bild hast, 
wäre das ein 2D Array aus 144 8Bit Werten.

Adressenen kannst du das so,

Farbe = Array(vertikaler_counter*16 + horizontaler_counter);

Aufpassen musst du aber weil der counter auch den nicht sichtbaren 
bereich enthält. Ausserdem vord das bild von oben nach unten aufgebaut, 
also der vertikale counter fängt oben bei 0 an.

von Kampi (Gast)


Lesenswert?

Hey,

danke für die Antwort.
Gut die Problematik mit dem nicht sichtbaren Bereich kann man ja 
umgehen, indem man den Counter an eine Bedingung knüpft, wie z.B. das er 
nur zählen soll wenn er im sichtbaren Bereich ist oder?
Ansonsten teste ich das morgen mal mit dem Bild :)

Danke & gute Nacht :)

Gruß
Daniel

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


Lesenswert?

Kampi schrieb:
> stehen, sprich die Counter waren vertauscht und die Bedingungen sind nie
> eingetroffen...
In einer Simulation sieht man das sehr schnell...
1
    -- HSync
2
    process(Clock_VGA)
3
    begin
4
        if rising_edge(Clock_VGA) then
5
            if((Pixel_Counter > 0) and (Pixel_Counter < 96)) then
6
                HSync <= '0';
7
            else
8
                HSync <= '1';
9
            end if;
10
        end if;
11
    end process;
Ich würde das so schreiben:
1
    -- HSync
2
    process begin
3
        wait until rising_edge(Clock_VGA);
4
        if (Pixel_Counter = 0 ) then  HSync <= '0'; end if;
5
        if (Pixel_Counter = 96) then  HSync <= '1'; end if;
6
    end process;

Und vor Allem würde ich extra Zähler (x+y oder s+z) für das sichtbare 
Bild einführen. Du rechnest dich ja zu Tode mit dem Offset auf dem 
Pixel- und Line-Counter...
1
    -- x-Position
2
    process begin
3
        wait until rising_edge(Clock_VGA);
4
        if (x < 639)             then  x <= x+1; end if;
5
        if (Pixel_Counter < 144) then  x <= 0;   end if;
6
    end process; 
7
8
    -- y-Position
9
    process begin
10
        wait until rising_edge(Clock_VGA);
11
        if (Pixel_Counter = 748 and y < 479) then  y <= y+1; end if;
12
        if (Line_Counter < 35)               then  y <= 0;   end if;
13
    end process;

Kampi schrieb:
> Mal angenommen ich habe jetzt in meinem RAM ein Bild liegen, welches ich
> auf dem Monitor ausgeben will.
Dann hättest du mit den oben berechneten x und y kein Problem, darauf 
zuzugreifen...

: Bearbeitet durch Moderator
von Kampi (Gast)


Lesenswert?

Hallo Lothar,

danke für den Hinweis.
Eine Simulation hatte ich da nie gemacht (muss ich einfach mal öfters 
bei den Dingern machen...).
Welchen Grund hat das, dass du die If-Abfrage aufteilst?
Den Zähler für den sichtbaren Bereich habe ich gestern schon angefangen 
einzuführen, als ich ein paar Blöcke auf dem Display ausgeben wollte und 
mich die Rechnerei genervt hat :P

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


Lesenswert?

Kampi schrieb:
> Welchen Grund hat das, dass du die If-Abfrage aufteilst?
Es sieht schöner aus... ;-)
Ich verwende hier die implizite Priorisierung von Signalzuweisungen im 
Prozess: die letzte Zuweisung an ein Signal gewinnt. So lassen sich 
leicht im Prozess zuerst die "normalen" Bedingungen bearbeiten (Zähler 
hochzählen und sättigen), und zum Schluss dann die Reset-Bedingung. Und 
genau so habe ich es gemacht...

von Kampi (Gast)


Lesenswert?

Ahh alles klar :)
Gut, ich teste heute Abend mal etwas weiter. Mal schauen ob es mit der 
Bildausgabe klappt...

von Kampi (Gast)


Lesenswert?

Hey,

ich wollte das jetzt mal ausprobieren mit dem Bild.
Dafür habe ich die Idee aufgegriffen ein 16x9 Bild darzustellen (wollte 
es nachher über eine Zeitverzögerung noch länger machen oder so...) aber 
ich bekomme schon mit dem 3D Array Probleme.
Mein Bild ist im Moment ein gestreifter Kasten:
1
    type Bild_Array is array (0 to 15, 0 to 9) of std_logic_vector(4 downto 0); 
2
    signal Bild : Bild_Array := (
3
    (x"1F",x"1F",x"1F",x"1F",x"1F",x"1F",x"1F",x"1F",x"1F",x"1F",x"1F",x"1F",x"1F",x"1F",x"1F"),
4
    (x"0",x"F",x"F",x"F",x"F",x"F",x"F",x"F",x"F",x"F",x"F",x"F",x"F",x"F",x"F"),
5
    (x"1F",x"1F",x"1F",x"1F",x"1F",x"1F",x"1F",x"1F",x"1F",x"1F",x"1F",x"1F",x"1F",x"1F",x"1F"),
6
    (x"0",x"F",x"F",x"F",x"F",x"F",x"F",x"F",x"F",x"F",x"F",x"F",x"F",x"F",x"F"),
7
    (x"1F",x"1F",x"1F",x"1F",x"1F",x"1F",x"1F",x"1F",x"1F",x"1F",x"1F",x"1F",x"1F",x"1F",x"1F"),
8
    (x"0",x"F",x"F",x"F",x"F",x"F",x"F",x"F",x"F",x"F",x"F",x"F",x"F",x"F",x"F"),
9
    (x"1F",x"1F",x"1F",x"1F",x"1F",x"1F",x"1F",x"1F",x"1F",x"1F",x"1F",x"1F",x"1F",x"1F",x"1F"),
10
    (x"0",x"F",x"F",x"F",x"F",x"F",x"F",x"F",x"F",x"F",x"F",x"F",x"F",x"F",x"F"),
11
    (x"1F",x"1F",x"1F",x"1F",x"1F",x"1F",x"1F",x"1F",x"1F",x"1F",x"1F",x"1F",x"1F",x"1F",x"1F")
12
    );

Das ist ja jetzt ein Array mit den "Abmaßen" 16x9 und jede Stelle 
beinhaltet 5 Bits oder sehe ich das falsch?
weil Vivado spuckt mir den Fehler hier aus:

[Synth 8-691] width mismatch in association of array element 0; element 
has 5 bits, expression has 8 bits 
["C:/Users/Daniel/Desktop/VGA/VGA.srcs/sources_1/new/VGA_Top.vhd":63]

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


Lesenswert?

x"1F" sind zwei 4 Bit breite Hexzahlen. In der Summe also 8 Bit...

von Kampi (Gast)


Angehängte Dateien:

Lesenswert?

Ah ok :)
Gut es funktioniert nun....allerdings nicht ganz so wie gedacht.
Hab das Array nun auf 20x16 vergrößert (der Rest ist gleich geblieben)
Auf dem Bild sehe ich nun aber keinen kleinen, gestreiften Kasten, 
sondern sowas...
Skaliert der Displaycontroller das hoch? Oder ist das ein Codefehler?

von Gustl B. (-gb-)


Lesenswert?

Poste doch mal gen ganzen Code, das interessante ist die Adressierung 
und Ausgabe der Werte.

von Kampi (Gast)


Lesenswert?

Ok, hier ist er:
1
library IEEE;
2
use IEEE.STD_LOGIC_1164.ALL;
3
4
-- Uncomment the following library declaration if using
5
-- arithmetic functions with Signed or Unsigned values
6
--use IEEE.NUMERIC_STD.ALL;
7
8
-- Uncomment the following library declaration if instantiating
9
-- any Xilinx leaf cells in this code.
10
--library UNISIM;
11
--use UNISIM.VComponents.all;
12
13
entity VGA_Top is
14
    Port ( Red : out STD_LOGIC_VECTOR(4 downto 0);
15
           Green : out STD_LOGIC_VECTOR(5 downto 0);
16
           Blue : out STD_LOGIC_VECTOR(4 downto 0);
17
           HSync : out STD_LOGIC;
18
           VSync : out STD_LOGIC;
19
           Lock : out STD_LOGIC;
20
           Clock : in STD_LOGIC
21
           );
22
end VGA_Top;
23
24
architecture VGA_Top_Arch of VGA_Top is
25
26
    signal Clock_VGA : std_logic;
27
    signal Pixel_Counter : integer  range 0 to 800;
28
    signal Line_Counter : integer  range 0 to 525;
29
    signal Picture_Enable : std_logic;
30
    signal x : integer range 0 to 16;
31
    signal y : integer range 0 to 20;
32
    
33
    component System is
34
        Port (
35
          Clock_In : in STD_LOGIC;
36
          Clock_Reset : in STD_LOGIC;
37
          Clock_Locked : out STD_LOGIC;
38
          Clock_Out : out STD_LOGIC);
39
    end component System;
40
    
41
    type Bild_Array is array (0 to 19, 0 to 15) of std_logic_vector(4 downto 0); 
42
    signal Bild : Bild_Array := (
43
    ("11111","11111","11111","11111","11111","11111","11111","11111","11111","11111","11111","11111","11111","11111","11111","11111"),
44
    ("00000","00000","00000","00000","00000","00000","00000","00000","00000","00000","00000","00000","00000","00000","00000","00000"),
45
    ("11111","11111","11111","11111","11111","11111","11111","11111","11111","11111","11111","11111","11111","11111","11111","11111"),
46
    ("00000","00000","00000","00000","00000","00000","00000","00000","00000","00000","00000","00000","00000","00000","00000","00000"),
47
    ("11111","11111","11111","11111","11111","11111","11111","11111","11111","11111","11111","11111","11111","11111","11111","11111"),
48
    ("00000","00000","00000","00000","00000","00000","00000","00000","00000","00000","00000","00000","00000","00000","00000","00000"),
49
    ("11111","11111","11111","11111","11111","11111","11111","11111","11111","11111","11111","11111","11111","11111","11111","11111"),
50
    ("00000","00000","00000","00000","00000","00000","00000","00000","00000","00000","00000","00000","00000","00000","00000","00000"),
51
    ("11111","11111","11111","11111","11111","11111","11111","11111","11111","11111","11111","11111","11111","11111","11111","11111"),
52
    ("00000","00000","00000","00000","00000","00000","00000","00000","00000","00000","00000","00000","00000","00000","00000","00000"),
53
    ("11111","11111","11111","11111","11111","11111","11111","11111","11111","11111","11111","11111","11111","11111","11111","11111"),
54
    ("00000","00000","00000","00000","00000","00000","00000","00000","00000","00000","00000","00000","00000","00000","00000","00000"),
55
    ("11111","11111","11111","11111","11111","11111","11111","11111","11111","11111","11111","11111","11111","11111","11111","11111"),
56
    ("00000","00000","00000","00000","00000","00000","00000","00000","00000","00000","00000","00000","00000","00000","00000","00000"),
57
    ("11111","11111","11111","11111","11111","11111","11111","11111","11111","11111","11111","11111","11111","11111","11111","11111"),
58
    ("00000","00000","00000","00000","00000","00000","00000","00000","00000","00000","00000","00000","00000","00000","00000","00000"),
59
    ("11111","11111","11111","11111","11111","11111","11111","11111","11111","11111","11111","11111","11111","11111","11111","11111"),
60
    ("00000","00000","00000","00000","00000","00000","00000","00000","00000","00000","00000","00000","00000","00000","00000","00000"),
61
    ("11111","11111","11111","11111","11111","11111","11111","11111","11111","11111","11111","11111","11111","11111","11111","11111"),
62
    ("00000","00000","00000","00000","00000","00000","00000","00000","00000","00000","00000","00000","00000","00000","00000","00000")
63
    );
64
65
begin
66
    
67
    Clock_25MHz : System port map (Clock, '1', Lock, Clock_VGA);
68
    
69
    -- X-Koordinate hochzählen
70
    process(Clock_VGA)
71
    begin
72
        if rising_edge(Clock_VGA) then
73
            if(Pixel_Counter < 784) then    x <= x + 1; end if;
74
            if(Pixel_Counter < 144) then    x <= 0;     end if;
75
        end if;        
76
    end process;
77
    
78
    -- Y-Koordinate hochzählen
79
    process(Clock_VGA)
80
    begin
81
        if rising_edge(Clock_VGA) then
82
            if((Line_Counter < 515) and (Pixel_Counter = 800)) then    y <= y + 1; end if;
83
            if(Line_Counter < 35) then    y <= 0;     end if;
84
        end if;        
85
    end process;
86
87
    -- Bild ausgeben
88
    process(Clock_VGA)
89
    begin
90
        Red <= Bild(y,x);     
91
    end process;
92
93
    -- HSync
94
    process(Clock_VGA)
95
    begin
96
        if rising_edge(Clock_VGA) then
97
            if(Pixel_Counter > 0)   then    HSync <= '0';   end if;
98
            if(Pixel_Counter < 96)  then    HSync <= '1';   end if;
99
        end if;
100
    end process; 
101
    
102
    -- VSync
103
    process(Clock_VGA)
104
    begin
105
        if rising_edge(Clock_VGA) then
106
            if(Line_Counter > 0)    then    VSync <= '0';   end if;
107
            if(Line_Counter < 3)    then    VSync <= '1';   end if;
108
        end if;
109
    end process; 
110
    
111
    -- Pixelcounter
112
    process(Clock_VGA)
113
    begin
114
        if rising_edge(Clock_VGA) then
115
            Pixel_Counter <= Pixel_Counter + 1;
116
            if(Pixel_Counter = 800) then
117
                Pixel_Counter <= 0;
118
                Line_Counter <= Line_Counter + 1;
119
            end if; 
120
            
121
            if(Line_Counter = 525)  then    Line_Counter <= 0;  end if;
122
        end if;
123
    end process;  
124
end VGA_Top_Arch;

von Gustl B. (-gb-)


Lesenswert?

Huiuiuiuiu, also da ist einiges drinnen was mir so nicht gefällt, z.B.:
1
if(Line_Counter > 0)    then    VSync <= '0';   end if;
2
if(Line_Counter < 3)    then    VSync <= '1';   end if;

Was soll da sein wenn Line_Counter den Wert 1 hat? Das ist > 0 und < 3.

Sowas ist da mehrmals, also ändere das mal so wie es sein soll und gucke 
ob das was ändert.

von Kampi (Gast)


Lesenswert?

Hey,

danke für die Antwort.
Ich hatte noch ein paar Probleme damit die Vereinfachungen von Lothar 
Miller zu verstehen, bzw. ich habe sie falsch verstanden. Daher waren da 
noch die Größer/Kleiner Zeichen drin.
Mittlerweile hat sich das erledigt und ich schaue noch mal drüber :)

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


Lesenswert?

Gustl Buheitel schrieb:
> Was soll da sein wenn Line_Counter den Wert 1 hat? Das ist > 0 und < 3.
Dann merkt sich das Flipflop den zuletzt gespeicherten Wert...

Aber ich würde da einfach auf "gleich" vergleichen, dann muss man dich 
nicht immer diese plusminus 1 Geschichte bei "kleiner" und "größer" 
antun.

von Kampi (Gast)


Lesenswert?

So hab es mal angepasst
1
begin
2
    
3
    Clock_25MHz : System port map (Clock, '1', Lock, Clock_VGA);
4
    
5
    -- X-Koordinate hochzählen
6
    process(Clock_VGA)
7
    begin
8
        if rising_edge(Clock_VGA) then
9
            if(x < 639) then    x <= x + 1; end if;
10
            if(Pixel_Counter < 144) then    x <= 0;     end if;
11
        end if;        
12
    end process;
13
    
14
    -- Y-Koordinate hochzählen
15
    process(Clock_VGA)
16
    begin
17
        if rising_edge(Clock_VGA) then
18
            if((y < 479) and (Pixel_Counter = 800))  then    y <= y + 1; end if;
19
            if(Line_Counter < 35) then    y <= 0;     end if;
20
        end if;        
21
    end process;
22
23
    -- Bild ausgeben
24
    process(Clock_VGA)
25
    begin
26
        Red <= Bild(y,x);     
27
    end process;
28
29
    -- HSync
30
    process(Clock_VGA)
31
    begin
32
        if rising_edge(Clock_VGA) then
33
            if(Pixel_Counter = 0)   then    HSync <= '0';   end if;
34
            if(Pixel_Counter = 96)  then    HSync <= '1';   end if;
35
        end if;
36
    end process; 
37
    
38
    -- VSync
39
    process(Clock_VGA)
40
    begin
41
        if rising_edge(Clock_VGA) then
42
            if(Line_Counter = 0)    then    VSync <= '0';   end if;  
43
            if(Line_Counter = 2)    then    VSync <= '1';   end if;          
44
        end if;
45
    end process; 
46
    
47
    -- Pixelcounter
48
    process(Clock_VGA)
49
    begin
50
        if rising_edge(Clock_VGA) then
51
            Pixel_Counter <= Pixel_Counter + 1;
52
            if(Pixel_Counter = 800) then
53
                Pixel_Counter <= 0;
54
                Line_Counter <= Line_Counter + 1;
55
            end if; 
56
            
57
            if(Line_Counter = 525)  then    Line_Counter <= 0;  end if;
58
        end if;
59
    end process;  
60
end VGA_Top_Arch;

Hoffe da sind nun alle zweifelhaften Stellen weg :)
Das Bild hat sich leider nicht geändert :(

von Gustl B. (-gb-)


Lesenswert?

Lothar Miller schrieb:
> Dann merkt sich das Flipflop den zuletzt gespeicherten Wert...

Das ist mir auch klar aber ... ich finde das trotzdem nicht sauber, 
schon gar nicht für Anfänger, da sollte alles möglichst einfach und 
verständlich lesbar sein.

Es ist sofar weniger Schreibarbeit:
1
if(Pixel_Counter > 0)   then    HSync <= '0';   end if;
2
if(Pixel_Counter < 96)  then    HSync <= '1';   end if;
1
if(Pixel_Counter < 96)  then
2
   HSync <= '1';
3
else
4
   HSync <= '0';
5
end if;

von Gustl B. (-gb-)


Lesenswert?

Ja genau denn da
1
signal x : integer range 0 to 16;
2
signal y : integer range 0 to 20;

kann x hier nur maximal 16 sein
1
if(x < 639) then    x <= x + 1; end if;

und y nur maximal 20
1
if((y < 479) and (Pixel_Counter = 800))  then    y <= y + 1; end if;

von Kampi (Gast)


Lesenswert?

Hey,

Lothar Miller schrieb:
> Gustl Buheitel schrieb:
>> Was soll da sein wenn Line_Counter den Wert 1 hat? Das ist > 0 und < 3.
> Dann merkt sich das Flipflop den zuletzt gespeicherten Wert...
>
> Aber ich würde da einfach auf "gleich" vergleichen, dann muss man dich
> nicht immer diese plusminus 1 Geschichte bei "kleiner" und "größer"
> antun.

also die Schreibweise hat mir jetzt keine Probleme bereitet. Es war nur 
das Verständnis nicht sofort da, warum der Code vom Lothar genau das 
selbe gemacht hat wie mein "langer" Code (worunter übrigens auch der 
Vergleich mit dem "=" fiel).
Ich habe mir dann aber mal beide Codes genommen und die logisch 
durchgespielt und dann war das eigentlich auch relativ klar (vor allem 
auch mit dem Vergleich durch "=") :)
Vergleiche mit "Größer", "Kleiner" etc. zu machen ist bei mir noch 
irgendwie drin....ka warum. Ist halt erst mal wieder etwas Umgewöhnung.

Hab die Zähler jetzt mal angepasst. Jetzt habe ich am oberen Rand 4 
Linien und am unteren Rand 2. Ich vermute mal, dass es jetzt daran 
liegt, dass ich zu "früh" anfange zu Zeichnen und dann noch im 
Schwarzbereich bin oder?
Aber ich verstehe auch noch nicht, warum ich Linien habe. Eigentlich 
sollte ich doch nur einen einzelnen Kasten haben.
Die Zählschleifen sehen nun so aus (hab den Parameter "range" der 
Zählerstände noch um 1 vermindert, weil ich die Stelle 0 wieder nicht 
mit gezählt hatte):
1
    signal x : integer range 0 to 15;
2
    signal y : integer range 0 to 19;
3
4
    process(Clock_VGA)
5
    begin
6
        if rising_edge(Clock_VGA) then
7
            if(x < 15) then    x <= x + 1; end if;
8
            if(Pixel_Counter < 144) then    x <= 0;     end if;
9
        end if;        
10
    end process;
11
    
12
    -- Y-Koordinate hochzählen
13
    process(Clock_VGA)
14
    begin
15
        if rising_edge(Clock_VGA) then
16
            if((y < 19) and (Pixel_Counter = 800))  then    y <= y + 1; end if;
17
            if(Line_Counter < 35) then    y <= 0;     end if;
18
        end if;        
19
    end process;

von Gustl B. (-gb-)


Lesenswert?

Mir ist noch unklar wie du das "Bild" ausgeben möchtest, möchtest du das 
20x16 Bild in einer Ecke des Bildschirmes sehen oder soll das auf den 
ganzen Anzeigebereich "skaliert werden"?

Bei Letzterem und 16 Zeilen und 20 Spalten müsste bei einer 800x600 
Bildschirmauflösung

Der Zähler für die Spalte alle 800/20 Pixel um eines hochzählen und der 
Zähler für die Array-Zeile alle 600/16 Bildschirm-Zeilen um eines 
hochzählen.

Also ganz grob:

Farbe <= Array(horizontal_zähler/20,vertikal_zähler/16);

Mit angepassten Zählern die nur im sichtbaren Bereich fon 0 ... 799 bzw. 
von 0 ... 599 zählen.

von Kampi (Gast)


Lesenswert?

Hey,

ja, die Grundidee war einen kleinen Würfel von 20x16 Pixeln auszugeben, 
der halt schwarz/rot gestreift ist.
Und ich habe einen 640x480 Monitor :)

von peter (Gast)


Lesenswert?

Au man, ihr zieht hier mit VGA eine Lachnummer ab.

Ich als alter Anfänger(Pensionär) kann jetzt schon Text auf den VGA 
bringen mit eingebundener Tastatur und serieller Schnittstelle.

Man lernt auch im Stillem....hab mich lange nicht mehr gemeldet.

Viel Hilfe die einem etwas nützt kommt hier im Forum nicht bei raus, 
wird viel rum gesabbert ohne eine klare Aussage.

Gruss von der Heimentwicklung mit VHDL.

von Christian R. (supachris)


Lesenswert?

@ Peter Bierbach: Manch einer will halt auch verstehen, was er macht und 
fängt klein an anstatt einfach fertige Code-Schnipsel zusammen zu 
kopieren. Aber wir wissen ja jetzt dass du der Überflieger schlechthin 
bist.

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


Lesenswert?

Sehr geehrter Herr Bierbach, Sie bringen in die vielschichtige 
Diskussion interessante neue Aspekte ein, die die Problematik von einer 
völlig neuen Seite beleuchten. Ihre Ausführungen zeugen von hoher 
Sachkenntnis und überzeugen auch im Detail. Besonders im Mittelteil 
transportieren sie eine Fülle hochwertiger Informationen, die dem Kreis 
der betroffenen Nutzer nicht vorenthalten werden dürfen.

von Kampi (Gast)


Lesenswert?

peter schrieb:
> Au man, ihr zieht hier mit VGA eine Lachnummer ab.
>
> Ich als alter Anfänger(Pensionär) kann jetzt schon Text auf den VGA
> bringen mit eingebundener Tastatur und serieller Schnittstelle.
>
> Man lernt auch im Stillem....hab mich lange nicht mehr gemeldet.
>
> Viel Hilfe die einem etwas nützt kommt hier im Forum nicht bei raus,
> wird viel rum gesabbert ohne eine klare Aussage.
>
> Gruss von der Heimentwicklung mit VHDL.

Vielen Dank. Du bist das perfekte Beispiel für viel drum herumreden ohne 
klare Aussage.
Wenn ich nur VGA laufen lassen will, hätte ich den fertigen IP-Core von 
Xilinx genommen, mit meinem Tastaturencode und nem fertigen UART Core 
vom Xilinx. Hätte die Dinger zusammen ins Zynq geschossen und wäre 
happy.
Aber für mich gehört zu einem Lernprozess halt auch, dass ich mich mal 
mit der Materie beschäftige und wirklich verstehen möchte wie sie 
funktioniert.
Mittlerweile gibt es eh für alles fertigen Code im Netz. Das sind zwei 
paar Schuhe ob man den Code nur kopiert oder ob man ihn auch versteht...

von Kampi (Gast)


Angehängte Dateien:

Lesenswert?

Also das Quadrat habe ich nun hin bekommen.
Der Fehler bestand einfach darin, dass ich in den Zeilen wo ich Rot 
zeichne die Farbe nicht mehr deaktiviert habe, sprich der Ausgang Rot 
wurde aktiviert und bliebt halt aktiviert, bis die nächste Bildzeile 
kommt.
Hab das Problem nun behoben, indem ich am Ende meines "Bildes" eine 
schwarze Spalte eingefügt habe.
Direkt nach dem Einschalten ist das Bild in Ordnung -> ein rotes, 
gestreiftes Quadrat in der Ecke. Aber wenig später sieht es dann so aus:

von Gustl B. (-gb-)


Lesenswert?

Also so ganz ok sieht das irgendwie auch nicht aus. Ist das wirklich wie 
im Array? Oder schreib doch mal ein Zeichen ins Array, also ein 
Buchstaben mit 20*16 Auflösung oder ein Muster an dem man erkennt ob es 
passt.

Und dann in Zukunft kleinere Dateigrößen, das ließe sich super zurecht 
schneiden.

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


Lesenswert?

Kampi schrieb:
> das perfekte Beispiel für viel drum herumreden ohne klare Aussage.
Man muss ein wrnig nach hinten schauen, zeitlich, dann sieht man in 
einem anderen Licht, was peter schrieb:
>>> Man lernt auch im Stillem....
http://www.mikrocontroller.net/search?query=bierbach&forums%5B%5D=9&max_age=-&sort_by_date=1

von Kampi (Gast)


Angehängte Dateien:

Lesenswert?

Lothar Miller schrieb:
> Kampi schrieb:
>> das perfekte Beispiel für viel drum herumreden ohne klare Aussage.
> Man muss ein wrnig nach hinten schauen, zeitlich, dann sieht man in
> einem anderen Licht, was peter schrieb:
>>>> Man lernt auch im Stillem....
> http://www.mikrocontroller.net/search?query=bierba...

Naja gut...ich reagiere halt immer leicht allergisch auf sowas, weil um 
die Sachen zu verstehen muss man halt nachfragen (wobei es natürlich 
auch mit bisschen Eigenarbeit verbunden ist...)
Aber zurück zum Thema :)
Ja, du hast Recht. Richtig sieht das nicht aus. Direkt nach dem 
Einschalten sieht es so aus wie auf dem Foto, bis irgendwann ein 
"Sprung" zu dem eben gezeigten Bild kommt.

von Gustl B. (-gb-)


Lesenswert?

Mach wirklich mal kleinere Dateianhänge, also nur den interessanten 
Bereich ausschneiden. Und dann würde ich ein Muster ins Array schreiben 
an dem man einfacher erkennen kann was falsch ist. Also Z.B. in jeder 
Zeile einen Verlauf von "11111" nach "01001", also am Ende einen 
Helligkeitsverlauf. Das könntest du noch in jeder Zeile variieren um 
diese unterscheiden zu können. Oder mit Farben.

von P. K. (pek)


Lesenswert?

peter schrieb:
> Viel Hilfe die einem etwas nützt kommt hier im Forum nicht bei raus,
> wird viel rum gesabbert ohne eine klare Aussage.

Wie man in den Wald ruft tönt es zurück. Ich für meinen Teil habe schon 
hin und wieder mal einen ganz nützlichen Tipp oder zumindest einen 
weiterführenden Denkanstoss bekommen. "Chapeau" den Unermüdlichen hier.

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


Lesenswert?

peter schrieb:
> Man lernt auch im Stillem....hab mich lange nicht mehr gemeldet.
Es war eigentlich schön ruhig, so...
> Viel Hilfe die einem etwas nützt kommt hier im Forum nicht bei raus,
> wird viel rum gesabbert ohne eine klare Aussage.
Peter, du bist echt arrogant und eingebildet! Ich möchte dich nur mal 
auf dein hoffnungsloses Rumgegurke vor 3 Monaten hinweisen.
> Ich als alter Anfänger(Pensionär) kann jetzt schon Text auf den
> VGA bringen mit eingebundener Tastatur und serieller Schnittstelle.
Ich denke, den Code "deiner" seriellen Schnitte kenne ich in- und 
auswendig. Und vermutlich auch den "deiner" Tastaturschnittstelle...

P. K. schrieb:
> Ich für meinen Teil habe schon hin und wieder mal einen ganz nützlichen
> Tipp oder zumindest einen weiterführenden Denkanstoss bekommen.
Ich auch. Und genau das ist es wert.

Gustl Buheitel schrieb:
> Mach wirklich mal kleinere Dateianhänge, also nur den interessanten
> Bereich ausschneiden.
Ja, und stell den Foto gleich mal um auf Bilder mit 300kB. Sonst muss 
ich die 3MB-Bilder hinterher wieder zurechtschneiden. Und vor allem: 
unterwegs mit dem Tablet dauert das Laden ewig (vom Traffic mal 
abgesehen).

> Und dann würde ich ein Muster ins Array schreiben
> an dem man einfacher erkennen kann was falsch ist.
Z.B. ein Fadenkreuz oder sowas...

: Bearbeitet durch Moderator
von Kampi (Gast)


Angehängte Dateien:

Lesenswert?

Hey,

sorry wegen der Fotogröße. Hab die Bilder mit meiner Digicam gemacht und 
nicht daran gedacht, dass die Bilder so riesig sind...
Ich habe jetzt mal ein Fadenkreuz implementiert:
1
architecture VGA_Top_Arch of VGA_Top is
2
3
    signal Clock_VGA : std_logic;
4
    signal Pixel_Counter : integer  range 0 to 800;
5
    signal Line_Counter : integer  range 0 to 525;
6
    signal Picture_Enable : std_logic;
7
    signal x : integer range 0 to 19;
8
    signal y : integer range 0 to 19;
9
    
10
    component System is
11
        Port (
12
          Clock_In : in STD_LOGIC;
13
          Clock_Reset : in STD_LOGIC;
14
          Clock_Locked : out STD_LOGIC;
15
          Clock_Out : out STD_LOGIC);
16
    end component System;
17
    
18
    type Bild_Array is array (0 to 19, 0 to 19) of std_logic_vector(4 downto 0); 
19
    signal Bild : Bild_Array := (
20
    ("00000","00000","00000","00000","00000","00000","00000","00000","00000","11111","11111","00000","00000","00000","00000","00000","00000","00000","00000","00000"),
21
    ("00000","00000","00000","00000","00000","00000","00000","00000","00000","11111","11111","00000","00000","00000","00000","00000","00000","00000","00000","00000"),
22
    ("00000","00000","00000","00000","00000","00000","00000","00000","00000","11111","11111","00000","00000","00000","00000","00000","00000","00000","00000","00000"),
23
    ("00000","00000","00000","00000","00000","00000","00000","00000","00000","11111","11111","00000","00000","00000","00000","00000","00000","00000","00000","00000"),
24
    ("00000","00000","00000","00000","00000","00000","00000","00000","00000","11111","11111","00000","00000","00000","00000","00000","00000","00000","00000","00000"),
25
    ("00000","00000","00000","00000","00000","00000","00000","00000","00000","11111","11111","00000","00000","00000","00000","00000","00000","00000","00000","00000"),
26
    ("00000","00000","00000","00000","00000","00000","00000","00000","00000","11111","11111","00000","00000","00000","00000","00000","00000","00000","00000","00000"),
27
    ("00000","00000","00000","00000","00000","00000","00000","00000","00000","11111","11111","00000","00000","00000","00000","00000","00000","00000","00000","00000"),
28
    ("00000","00000","00000","00000","00000","00000","00000","00000","00000","11111","11111","00000","00000","00000","00000","00000","00000","00000","00000","00000"),
29
    ("11111","11111","11111","11111","11111","11111","11111","11111","11111","11111","11111","11111","11111","11111","11111","11111","11111","11111","11111","11111"),
30
    ("11111","11111","11111","11111","11111","11111","11111","11111","11111","11111","11111","11111","11111","11111","11111","11111","11111","11111","11111","11111"),
31
    ("00000","00000","00000","00000","00000","00000","00000","00000","00000","11111","11111","00000","00000","00000","00000","00000","00000","00000","00000","00000"),
32
    ("00000","00000","00000","00000","00000","00000","00000","00000","00000","11111","11111","00000","00000","00000","00000","00000","00000","00000","00000","00000"),
33
    ("00000","00000","00000","00000","00000","00000","00000","00000","00000","11111","11111","00000","00000","00000","00000","00000","00000","00000","00000","00000"),
34
    ("00000","00000","00000","00000","00000","00000","00000","00000","00000","11111","11111","00000","00000","00000","00000","00000","00000","00000","00000","00000"),
35
    ("00000","00000","00000","00000","00000","00000","00000","00000","00000","11111","11111","00000","00000","00000","00000","00000","00000","00000","00000","00000"),
36
    ("00000","00000","00000","00000","00000","00000","00000","00000","00000","11111","11111","00000","00000","00000","00000","00000","00000","00000","00000","00000"),
37
    ("00000","00000","00000","00000","00000","00000","00000","00000","00000","11111","11111","00000","00000","00000","00000","00000","00000","00000","00000","00000"),
38
    ("00000","00000","00000","00000","00000","00000","00000","00000","00000","11111","11111","00000","00000","00000","00000","00000","00000","00000","00000","00000"),
39
    ("00000","00000","00000","00000","00000","00000","00000","00000","00000","11111","11111","00000","00000","00000","00000","00000","00000","00000","00000","00000")
40
    );
41
42
begin
43
    
44
    Clock_25MHz : System port map (Clock, '1', Lock, Clock_VGA);
45
    
46
    -- X-Koordinate hochzählen
47
    process(Clock_VGA)
48
    begin
49
        if rising_edge(Clock_VGA) then
50
            if(x < 19) then    
51
                x <= x + 1;  
52
            end if;
53
            if(Pixel_Counter < 144) then    x <= 0;     end if;
54
        end if;        
55
    end process;
56
    
57
    -- Y-Koordinate hochzählen
58
    process(Clock_VGA)
59
    begin
60
        if rising_edge(Clock_VGA) then
61
            if((y < 19) and (Pixel_Counter = 800))  then    y <= y + 1; end if;
62
            if(Line_Counter < 44) then    y <= 0;     end if;
63
        end if;        
64
    end process;
65
66
    -- Bild ausgeben
67
    process(Clock_VGA)
68
    begin
69
        Red <= Bild(y,x);          
70
    end process;
71
72
    -- HSync auslösen
73
    process(Clock_VGA)
74
    begin
75
        if rising_edge(Clock_VGA) then
76
            if(Pixel_Counter = 0)   then    HSync <= '0';   end if;
77
            if(Pixel_Counter = 96)  then    HSync <= '1';   end if;
78
        end if;
79
    end process; 
80
    
81
    -- VSync auslösen
82
    process(Clock_VGA)
83
    begin
84
        if rising_edge(Clock_VGA) then
85
            if(Line_Counter = 0)    then    VSync <= '0';   end if;  
86
            if(Line_Counter = 2)    then    VSync <= '1';   end if;          
87
        end if;
88
    end process; 
89
    
90
    -- Counter
91
    process(Clock_VGA)
92
    begin
93
        if rising_edge(Clock_VGA) then
94
        
95
            -- Pixelzähler erhöhen
96
            Pixel_Counter <= Pixel_Counter + 1;
97
            
98
            -- Pixelcounter zurücksetzen und Zeilencounter erhöhen
99
            if(Pixel_Counter = 800) then
100
                Pixel_Counter <= 0;
101
                Line_Counter <= Line_Counter + 1;
102
            end if; 
103
            
104
            -- Zeilencounter zurücksetzen
105
            if(Line_Counter = 525)  then    Line_Counter <= 0;  end if;
106
107
        end if;
108
    end process;  
109
end VGA_Top_Arch;

Und als Bild kommt das gezeigte raus.

von Peter P. (Gast)


Lesenswert?

Wenn x außerhalb des Kastens oder y außerhalb des Kastens,
was passiert dann mit Red?
Bleibt x auf 19? Und damit wird die letzte Spalte immer wieder
ausgegeben?
Bleibt y auf 19? Und damit wird die letzte Zeile immer wieder
ausgegeben?

Was bewirkt
"if(Pixel_Counter < 144)" bzw. "if(Line_Counter < 44)"?
Soll damit der Kasten einen (x/y)-Offset bekommen?

von Kampi (Gast)


Lesenswert?

Hey,

meinst du mit "Kasten" den sichtbaren Bereich?
Mit der Abfrage if(Pixel_Counter < 144)" bzw. "if(Line_Counter < 44) 
möchte ich, dass der Zähler so lange auf 0 bleibt wie das Display noch 
im Schwarzbereich ist.

Was mit x und y passiert ist eine gute Frage...
Ich setze die nirgends zurück. Ich vermute mal, da die eine range von 
0-19 haben, dass die auf dem Wert 19 bleiben, da die sich nicht bei 19 
reseten sondern erst bei 20.

Stimmt das so?

von Kampi (Gast)


Angehängte Dateien:

Lesenswert?

Cool dein Denkanstoß war genial :)

Habe die Signale nun auf

range 0 to 18 gesetzt. Damit werden die automatisch zurück gesetzt und 
siehe da...

Das müsste dann ja so funktionieren (bitte korrigieren falls falsch!):
Mein Array hat eine Breite von 20. Der Integer eine range von 0-18, d.h. 
19 Werte. Beim nächsten Takt würde der Counter dann auf 19 springen und 
den Integer reseten, sodass der wieder auf 0 steht und damit würde ich 
dann wieder die Adresse 0 des Arrays ansprechen.

Aber wo bleibt dann der 20. Wert vom Array? kopfkratz
Oder habe ich da einen Denkfehler?

von Kampi (Gast)


Lesenswert?

Ok noch mal etwas weiter gespielt...
Anscheinend hatte ich einen Denkfehler. Wenn ich die Signale für x und y 
bis 18 mache, werden die immer resetet, wodurch sich die Kreuze dann 
immer wiederholen.
Lasse ich die Signale aber auf der range von 19, habe ich oben in der 
Ecke ein einzelnes Kreuz, so wie es sein muss.

Bleibt nur die Frage warum ab und an nach dem Einschalten ein lang 
gezogenes Kreuz erscheint...

von peter (Gast)


Lesenswert?

----------------------------
Mittlerweile gibt es eh für alles fertigen Code im Netz. Das sind zwei
paar Schuhe ob man den Code nur kopiert oder ob man ihn auch versteht...
----------------------------

Mittlerweile gibt es fertige Fernseher, Auto, Handy....
Ich brauche nicht alle verstehen wie sie entwickelt worden sind, sondern 
nur wie einzelne Funktionen zu handhaben sind....

von peter (Gast)


Lesenswert?

-------------------------
also die Schreibweise hat mir jetzt keine Probleme bereitet. Es war nur
das Verständnis nicht sofort da, warum der Code vom Lothar genau das
selbe gemacht hat wie mein "langer" Code (worunter übrigens auch der
Vergleich mit dem "=" fiel).
------------------------

Au man er schreibt immer noch "Code"...was sagt Miller dazu?

von Kampi (Gast)


Lesenswert?

peter schrieb:
> -------------------------
> also die Schreibweise hat mir jetzt keine Probleme bereitet. Es war nur
> das Verständnis nicht sofort da, warum der Code vom Lothar genau das
> selbe gemacht hat wie mein "langer" Code (worunter übrigens auch der
> Vergleich mit dem "=" fiel).
> ------------------------
>
> Au man er schreibt immer noch "Code"...was sagt Miller dazu?

Code ist ja auch richtig...
Siehe Wikipedia:

http://de.wikipedia.org/wiki/Very_High_Speed_Integrated_Circuit_Hardware_Description_Language

Nur deine Aussagen das du ein FPGA programmierst sind falsch...
Ein Code kann vieles sein...auch hier wieder Wikipedia:

http://de.wikipedia.org/wiki/Code

In VHDL codierst du eine Schaltung. Du drückst mit Worten die Funktion 
aus und legst nicht, wie bei der Software, mit bestimmten Befehlen ein 
Verhalten einer Schaltung fest.

von Kampi (Gast)


Lesenswert?

peter schrieb:
> ----------------------------
> Mittlerweile gibt es eh für alles fertigen Code im Netz. Das sind zwei
> paar Schuhe ob man den Code nur kopiert oder ob man ihn auch versteht...
> ----------------------------
>
> Mittlerweile gibt es fertige Fernseher, Auto, Handy....
> Ich brauche nicht alle verstehen wie sie entwickelt worden sind, sondern
> nur wie einzelne Funktionen zu handhaben sind....

Dann mal viel Spaß wenn du Programme oder Schaltungen anpassen oder 
ändern musst. Dann kommt es nämlich sehr wohl auf das Verständnis der 
ganzen Schaltung an...

von Kampi (Gast)


Angehängte Dateien:

Lesenswert?

Heyho,

so mal ein kleines Update :)
Habe ein bisschen an dem Code rum gearbeitet und mich dazu entschlossen 
die drei Farben in einen Vektor zu legen. Dadurch kann ich ganz einfach 
die Farben je nach Hexwert schalten:
1
----------------------------------------------------------------------------------
2
-- Company:         www.kampis-elektroecke.de
3
-- Engineer:        Daniel Kampert
4
-- 
5
-- Create Date:     02.08.2014 13:17:51
6
-- Design Name: 
7
-- Module Name:     VGA_Top - VGA_Top_Arch
8
-- Project Name: 
9
-- Target Devices:  XC7Z010CLG400-1
10
-- Tool Versions:   Vivado 2014.2
11
-- Description:     VGA Interface for a 640 x 480 Pixel Screen
12
-- 
13
-- Dependencies: 
14
-- 
15
-- Revision:
16
-- Revision         0.01 - File Created
17
-- Additional Comments:
18
-- 
19
----------------------------------------------------------------------------------
20
21
library IEEE;
22
use IEEE.STD_LOGIC_1164.ALL;
23
24
-- Uncomment the following library declaration if using
25
-- arithmetic functions with Signed or Unsigned values
26
--use IEEE.NUMERIC_STD.ALL;
27
28
-- Uncomment the following library declaration if instantiating
29
-- any Xilinx leaf cells in this code.
30
--library UNISIM;
31
--use UNISIM.VComponents.all;
32
33
entity VGA_Top is
34
    Port ( Color : out STD_LOGIC_VECTOR(15 downto 0);
35
           HSync : out STD_LOGIC;
36
           VSync : out STD_LOGIC;
37
           Lock : out STD_LOGIC;
38
           Clock : in STD_LOGIC
39
           );
40
end VGA_Top;
41
42
architecture VGA_Top_Arch of VGA_Top is
43
44
    -- Bildeinstellungen
45
    constant x_Offset : integer := 200;
46
    constant y_Offset : integer := 200;
47
    constant Bild_Breite : integer := 20;
48
    constant Bild_Hoehe : integer := 20;
49
50
    signal Clock_VGA : std_logic;
51
    signal Pixel_Counter : integer  range 0 to 800;
52
    signal Line_Counter : integer  range 0 to 525;
53
    signal x : integer range 0 to (Bild_Breite - 1) := x_Offset;
54
    signal y : integer range 0 to (Bild_Hoehe - 1) := y_Offset;
55
    
56
    component System is
57
        Port (
58
          Clock_In : in STD_LOGIC;
59
          Clock_Reset : in STD_LOGIC;
60
          Clock_Locked : out STD_LOGIC;
61
          Clock_Out : out STD_LOGIC);
62
    end component System;
63
    
64
    type Bild_Array is array (0 to 19, 0 to 19) of std_logic_vector(15 downto 0); 
65
    signal Bild : Bild_Array := (
66
    (x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000"),
67
    (x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"FC1F", x"FC1F", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000"),
68
    (x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"FC1F", x"FC1F", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000"),
69
    (x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"FC1F", x"FC1F", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000"),
70
    (x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"FC1F", x"FC1F", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000"),
71
    (x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"FC1F", x"FC1F", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000"),
72
    (x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"FC1F", x"FC1F", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000"),
73
    (x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"FC1F", x"FC1F", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000"),
74
    (x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"FC1F", x"FC1F", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000"),
75
    (x"0000", x"001F", x"001F", x"001F", x"001F", x"001F", x"001F", x"001F", x"001F", x"FC1F", x"FC1F", x"001F", x"001F", x"001F", x"001F", x"001F", x"001F", x"001F", x"001F", x"0000"),
76
    (x"0000", x"001F", x"001F", x"001F", x"001F", x"001F", x"001F", x"001F", x"001F", x"FC1F", x"FC1F", x"001F", x"001F", x"001F", x"001F", x"001F", x"001F", x"001F", x"001F", x"0000"),
77
    (x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"FC1F", x"FC1F", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000"),
78
    (x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"FC1F", x"FC1F", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000"),
79
    (x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"FC1F", x"FC1F", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000"),
80
    (x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"FC1F", x"FC1F", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000"),
81
    (x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"FC1F", x"FC1F", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000"),
82
    (x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"FC1F", x"FC1F", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000"),
83
    (x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"FC1F", x"FC1F", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000"),
84
    (x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"FC1F", x"FC1F", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000"),
85
    (x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000")
86
    );
87
88
begin
89
    
90
    Clock_25MHz : System port map (Clock, '1', Lock, Clock_VGA);
91
    
92
    -- X-Koordinate hochzählen
93
    process(Clock_VGA)
94
    begin
95
        if rising_edge(Clock_VGA) then
96
            if(x < (Bild_Breite - )) then    
97
                x <= x + 1;  
98
            end if;
99
            
100
            if(Pixel_Counter < 144) then    x <= 0;     end if;
101
        end if;        
102
    end process;
103
    
104
    -- Y-Koordinate hochzählen
105
    process(Clock_VGA)
106
    begin
107
        if rising_edge(Clock_VGA) then
108
            if((y < (Bild_Hoehe - 1)) and (Pixel_Counter = 800))  then    
109
                y <= y + 1; 
110
            end if;
111
            
112
            if(Line_Counter < 32) then    y <= 0;     end if;
113
        end if;        
114
    end process;
115
116
    -- Bild ausgeben
117
    process(Clock_VGA)
118
    begin
119
        Color <= Bild(y,x);      
120
    end process;
121
122
    -- HSync auslösen
123
    process(Clock_VGA)
124
    begin
125
        if rising_edge(Clock_VGA) then
126
            if(Pixel_Counter = 0)   then    HSync <= '0';   end if;
127
            if(Pixel_Counter = 96)  then    HSync <= '1';   end if;
128
        end if;
129
    end process; 
130
    
131
    -- VSync auslösen
132
    process(Clock_VGA)
133
    begin
134
        if rising_edge(Clock_VGA) then
135
            if(Line_Counter = 0)    then    VSync <= '0';   end if;  
136
            if(Line_Counter = 2)    then    VSync <= '1';   end if;          
137
        end if;
138
    end process; 
139
    
140
    -- Counter
141
    process(Clock_VGA)
142
    begin
143
        if rising_edge(Clock_VGA) then
144
        
145
            -- Pixelzähler erhöhen
146
            Pixel_Counter <= Pixel_Counter + 1;
147
            
148
            -- Pixelcounter zurücksetzen und Zeilencounter erhöhen
149
            if(Pixel_Counter = 800) then
150
                Pixel_Counter <= 0;
151
                Line_Counter <= Line_Counter + 1;
152
            end if; 
153
            
154
            -- Zeilencounter zurücksetzen
155
            if(Line_Counter = 525)  then    Line_Counter <= 0;  end if;
156
157
        end if;
158
    end process;  
159
end VGA_Top_Arch;

Woran ich jetzt noch arbeite ist eine Offsetfunktion, sodass ich das 
Bild irgendwo im Display darstellen kann und vielleicht noch einen 
Counter um das Bild wiederholt darstellen zu können.
Sowas bekomme ich im Moment nur hin, indem ich die Variablen für die x 
und y Koordinaten vom Parameter "range" 1 kleiner mache als die 
Bildgröße...aber das ist irgendwie nicht zielführend.
Im Moment sieht das so aus wie auf dem Foto...da bin ich eigentlich 
schon ganz zufrieden mit :)
Die mehrfarbige Darstellung klappt auch. Jetzt packe ich demnächst noch 
das Array für das Bild an, wo dann das Bild jedes mal abgelegt wird und 
dann werden einfach nur Bildinformationen da rein geschrieben und die 
Schaltung gibt das Bild dann aus (wenn jemand eine bessere Idee hat, ich 
bin immer für Kritik offen :) )

Danke noch mal für die Hilfe zum Umsetzen der Schaltung. Hat zwar etwas 
gedauert, aber dafür weiß ich jetzt auch was die macht und wie sie 
funktioniert.

Ach eine Frage noch...wenn ich auf dem Display jetzt Buchstaben 
wiedergeben möchte....wie mache ich sowas am besten? Da muss ich ja 
jeden Buchstaben in dem Code definieren, also was Länge und Breite und 
dann das Pixelmuster angeht (wobei Länge und Breite ja im Grunde für 
alle Buchstaben fest sind).
Wie kann man sowas geschickt abbilden?

Danke und Gruß
Daniel

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


Lesenswert?

peter schrieb:
> Au man er schreibt immer noch "Code"...was sagt Miller dazu?
Ein "Code" ist noch lange kein (Software-)"Programm". Das hatte ich 
schon mal in einem deiner Threads geschrieben, Peter.

Kampi schrieb:
> Habe ein bisschen an dem Code rum gearbeitet und mich dazu entschlossen
> die drei Farben in einen Vektor zu legen.
Da ist es ganz praktisch, dass es diese "seltsame" Aufteilung der 
Bitbreiten gibt...

Dieser Prozess hat eine fehlerhafte Sensitivliste, dadurch ist die 
Simulation falsch: die Daten werden dort einen "halben" Takt versetzt an 
Color weitergegeben.
1
    -- Bild ausgeben
2
    process(Clock_VGA)
3
    begin
4
        Color <= Bild(y,x);      
5
    end process;
Du kannst das hier problemlos und fehlerfrei abkürzen (so wie der 
Synthesizer das auch macht), und am besten auch den zweifelhaften 
Kommentar streichen:
1
    -- Bild ausgeben  <-- hui, hier wird ein GANZES Bild ausgegeben?
2
    Color <= Bild(y,x);

> Ach eine Frage noch...wenn ich auf dem Display jetzt Buchstaben
> wiedergeben möchte....wie mache ich sowas am besten?
Ähnlich wie diese "Sprites", die du hier ausgibst: du legst eine 
Zeichentabelle ab, wo jeder Buchstabe drin ist, und greifst dann mit 
einem Offset auf das gewünschte zeichen zu.

: Bearbeitet durch Moderator
von P. K. (pek)


Lesenswert?

Kampi schrieb:
> Wie kann man sowas geschickt abbilden?

Momentan hast Du das (signal) Bild und die Ansteuerung in derselben 
Entity. Wenn Du nun daran gehen willst, Text oder sonst was 
darzustellen, solltest Du das trennen:
- Video I/F (liest Framebuffer und generiert die Ausgangssignale)
- Framebuffer (RAM, X*Y Pixel)
- Bespassung des Framebuffers (z.B. *.bmp via anderes I/F reinladen,
  Character Buffer, oder andere Aufbereitung)

Da Du offensichtlich Characters darstellen willst, brauchst Du einen 
Characterbuffer und eine LUT (ROM) wo Deine Characters drinnstehen. Wie 
sowas geht könntest Du einem Character LCD-Treiber abschauen (z.B. 
PCF2119)

von Kampi (Gast)


Lesenswert?

Hey,

danke euch beiden für die Antwort.
Über die "seltsame" Aufteilung der Bitbreite bin ich aus versehen 
gestolpert...wunderte mich dann auch warum Grün 6 Bit lang ist, aber das 
kann evtl. was damit zu tun haben, dass ein Mensch Grün stärker wahr 
nimmt...
Der Kommentar ist wirklich doof gewählt...da suche ich was besseres :)
Stimmt...wenn man genauer drüber nachdenkt fällt einem auch schnell ein, 
dass man für die Zeile

Color <= Bild(y,x);

gar keinen Process braucht. Die Koordinaten x und y werden ja schon 
getaktet erhöht und die Zeile soll ja nur den Eingang entsprechend eines 
aktuellen Pixels im RAM setzen.
Kannst du mir noch erklären wie du auf einen halben Takt kommst? Ich 
würde eher vermuten, dass dann ein ganzer Takt Verzögerung drin ist, 
weil mit Takt 1 werden die neuen Array Koordinaten generiert und Takt 
würde die Koordinaten dann in die entsprechende Zelle umwandeln und 
diese dann ausgeben.
Theoretisch passiert das ja alles gleichzeitig, aber es kann ja nicht 
gleichzeitig der Counter für die Koordinaten erhöht werden und dann die 
aktuellen Zelleninhalte ausgegeben werden.

@ pek:
Ja diese Idee ist mir jetzt auch über Nacht gekommen. Im Grunde ist der 
Teil, an dem ich bisher gearbeitet habe nur für die Darstellung da, 
sprich er greift auf einen Buffer (halt das Array) zu und gibt den 
Inhalt aus.
Für die Bildgenerierung innerhalb des Arrays ist ein anderer Teil 
zuständig.
Daher habe ich den Codeteil für die Bilderstellung jetzt schon mal 
ausgelagert in ein einzelnes Modul und das dann instanziert.
Ich wollte da heute noch ein paar Schönheitsänderungen machen und mich 
dann an einen zweiten Teil setzen, der die Bilderzeugung übernimmt (halt 
den Framebuffer den du meintest).
Die Idee mit dem LCD Controller ist super :)
Den Framebuffer mache ich dann wahrscheinlich direkt so groß, dass dort 
die 640x480 Pixel rein passen oder eher kleiner machen?
Ich hatte mir das so überlegt, dass ich das Array in der Größe des 
sichtbaren Bereiches mache und dann halt die entsprechenden Zellen 
beschreibe (z.B. mit Buchstaben).

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


Lesenswert?

Kampi schrieb:
> Über die "seltsame" Aufteilung der Bitbreite bin ich aus versehen
> gestolpert...wunderte mich dann auch warum Grün 6 Bit lang ist, aber das
> kann evtl. was damit zu tun haben, dass ein Mensch Grün stärker wahr
> nimmt...
Ja, und damit, dass 5+5+6 ganz gut und zudem genau in 2 Byte passen... 
;-)

> Kannst du mir noch erklären wie du auf einen halben Takt kommst?
Das kommt, weil der Simulator den Prozess bei jeder Änderung von 
Clock_VGA neu berechnet, also auch bei der fallenden Flanke.

: Bearbeitet durch Moderator
von peter (Gast)


Lesenswert?

if(x < (Bild_Breite - )) then

So kann das nicht laufen....

von Peter P. (Gast)


Lesenswert?

Wenn du nur Zeichen ausgeben willst,
könnte auch folgender Ablauf helfen:
(nur die Idee, ich kann kein/kaum VHDL)

Zusätzlich zu x und y noch ein Spalte und Zeile verwenden.
(Beispiel: Zeichen sind 8x8 groß)
Wobei

Spalte mehr oder weniger x / 8
Zeile mehr oder weniger y / 8

ist. Kannst auch direkt x und y nehmen (und die unteren
Adressleitungen weglassen).

Dann etwas in der Art:

Zeichen_an_Zeile_Spalte = Zeichenbuffer(y,x);

Color <= Bild(Zeichen_an_Zeile_Spalte,y,x);

"Bild" ist dann die Pixel-Darstellung aller Buchstaben/Zeichen.

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


Lesenswert?

Peter P. schrieb:
> Wobei
> Spalte mehr oder weniger x / 8
> Zeile mehr oder weniger y / 8
> ist. Kannst auch direkt x und y nehmen (und die unteren
> Adressleitungen weglassen).
Das macht der Synthesizer bei /8 sowieso. Wobei das bei einem signed 
Integer eigentlich nicht richtig ist: bei negativen Zahlen wird da 
falsch gerundet...

von Kampi (Gast)


Lesenswert?

peter schrieb:
> if(x < (Bild_Breite - )) then
>
> So kann das nicht laufen....

Sorry, da ist mir die 1 flöten gegangen. Vielleicht kann das ein 
Moderator ja eben korrigieren :)

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


Lesenswert?

Kampi schrieb:
> Vielleicht kann das ein Moderator ja eben korrigieren :)
Ach, lass mal. Das ist der Intelligenztest für Anfänger...  ;-)

: Bearbeitet durch Moderator
von peter (Gast)


Lesenswert?

Darum laufen hier viele VHDL nicht korrekt, weil die kleine Fehler 
beinhalten und nicht berichtigt werden obwohl erkannt.

Miller, deine Ausrede ist irgendwie blöd....gegenüber dem, der das 
Programm geschrieben hat. Der möchte das andere evtl sein Programm mal 
Testen und du lässt ihn nicht den Fehler berichtigen.
Hoffentlich hast du keine gewerbliche Firma angemeldet...

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


Lesenswert?

peter schrieb:
> Der möchte das andere evtl sein Programm mal Testen und du lässt ihn
> nicht den Fehler berichtigen.
Wenn da einer so blöd oder faul ist, nur den Code zu kopieren und nicht 
mal zwei Beiträge davor und danach zu lesen, dann bin ich nicht an 
dessen Scheitern schuld...


> Miller, deine Ausrede ist irgendwie blöd....
Menschen, die mich duzen und meinen Nachnamen dabei benutzen obwohl 
ihnen der Rufname vor der Nase liegt, sind mir extrem unsympathisch. 
Eist billig und hochnäsig.

Und, Peter: VHDL Beschreibungen "laufen" nicht "nicht korrekt", Sie 
werden bestenfalls "nicht korrekt umgesetzt".

von Peter B. (funkheld)


Lesenswert?

-----------------------------------
dann bin ich nicht an dessen Scheitern schuld...
-----------------------------------

Aber eine Mitschuld und Mitverantwortung von Fehlerhaften VHDL , wenn du 
davon Weisst(Vorsatz) und diesen mit Absicht öffentlich verbreitest.

von Christian R. (supachris)


Lesenswert?

Das meckert der Parser/Compiler doch sowieso an, bis zum Start der 
Sythese kommts doch da da gar nicht. Peter, du nervst.

von Kampi (Gast)


Angehängte Dateien:

Lesenswert?

Peter Bierbach schrieb:
> -----------------------------------
> dann bin ich nicht an dessen Scheitern schuld...
> -----------------------------------
>
> Aber eine Mitschuld und Mitverantwortung von Fehlerhaften VHDL , wenn du
> davon Weisst(Vorsatz) und diesen mit Absicht öffentlich verbreitest.

Wer Code ohne nachdenken aus dem Internet kopiert muss sowieso damit 
rechnen das er falsch ist....

Ich habe heute noch mal etwas weiter gebastelt.
Ich habe mir jetzt ein eigenes Design für einen VGA Controller gebaut, 
der die Syncs und die Koordinaten für das Bild erzeugt.
Inspiriert wurde ich durch das Bild hier:

http://eewiki.net/pages/viewpage.action?pageId=15925278

Der VGA-Controller ist an für sich nun abgeschlossen (hab dem ganzen 
auch nen Reset spendiert ;) ).
Jetzt geht es um die Umsetzung eines Bildes, aber davor habe ich noch 
ein (kleines) Problem.
Heute Mittag (bevor ich die Änderungen gemacht hatte) habe ich es 
geschafft, dass sich das Kreuz über den Bildschirm bewegt. Dazu hatte 
ich einen langsameren Clock genommen und die Koordinaten hoch gezählt.
Jetzt habe ich diesen Code
1
entity VGA_Top is
2
    Port (  Color : out STD_LOGIC_VECTOR(15 downto 0);
3
            HSync : out STD_LOGIC;
4
            VSync : out STD_LOGIC;
5
            Output : out STD_LOGIC_VECTOR(1 downto 0);
6
            Reset : in STD_LOGIC;
7
            Clock : in STD_LOGIC            
8
            );
9
end VGA_Top;
10
11
architecture VGA_Top_Arch of VGA_Top is
12
13
    signal Clock_VGA : std_logic;
14
    signal Clock_10k : std_logic;
15
    signal Clock_1 : std_logic;
16
    signal Pos_x : integer;
17
    signal Pos_y : integer;
18
    signal Lock : std_logic;
19
    
20
    -- Erzeugung des 25,175MHz Taktes
21
    component System is
22
        Port (  Clock_In : in STD_LOGIC;
23
                Clock_Reset : in STD_LOGIC;
24
                Clock_Locked : out STD_LOGIC;
25
                Clock_Out : out STD_LOGIC
26
          );
27
    end component System;
28
    
29
    -- Einbinden des VGA-Controllers
30
    component VGA_Controller is
31
        Port (  HSync : out STD_LOGIC;
32
                VSync : out STD_LOGIC;
33
                Clock_VGA : in STD_LOGIC;
34
                Reset : in STD_LOGIC;
35
                Offset_x : in integer;
36
                Offset_y : in integer;
37
                x_out : out integer;
38
                y_out : out integer
39
                );
40
    end component VGA_Controller;  
41
    
42
    component Clock_Div is
43
        Port (  Clock_In : in STD_LOGIC;
44
                Clock_Out : out STD_LOGIC;
45
                Divider : in integer
46
                );
47
    end component Clock_Div;  
48
    
49
    type Bild_Array is array (0 to (20 - 1), 0 to (20 - 1)) of std_logic_vector(15 downto 0); 
50
    signal Bild : Bild_Array := (
51
    (x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000"),
52
    (x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"FC1F", x"FC1F", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000"),
53
    (x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"FC1F", x"FC1F", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000"),
54
    (x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"FC1F", x"FC1F", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000"),
55
    (x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"FC1F", x"FC1F", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000"),
56
    (x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"FC1F", x"FC1F", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000"),
57
    (x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"FC1F", x"FC1F", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000"),
58
    (x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"FC1F", x"FC1F", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000"),
59
    (x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"FC1F", x"FC1F", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000"),
60
    (x"0000", x"001F", x"001F", x"001F", x"001F", x"001F", x"001F", x"001F", x"001F", x"FC1F", x"FC1F", x"001F", x"001F", x"001F", x"001F", x"001F", x"001F", x"001F", x"001F", x"0000"),
61
    (x"0000", x"001F", x"001F", x"001F", x"001F", x"001F", x"001F", x"001F", x"001F", x"FC1F", x"FC1F", x"001F", x"001F", x"001F", x"001F", x"001F", x"001F", x"001F", x"001F", x"0000"),
62
    (x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"FC1F", x"FC1F", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000"),
63
    (x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"FC1F", x"FC1F", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000"),
64
    (x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"FC1F", x"FC1F", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000"),
65
    (x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"FC1F", x"FC1F", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000"),
66
    (x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"FC1F", x"FC1F", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000"),
67
    (x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"FC1F", x"FC1F", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000"),
68
    (x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"FC1F", x"FC1F", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000"),
69
    (x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"FC1F", x"FC1F", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000"),
70
    (x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000", x"0000")
71
    );
72
73
begin
74
    
75
    Clock_25MHz : System port map (Clock, '1', Lock, Clock_VGA);
76
    VGA_Core : VGA_Controller port map (HSync, VSync, Clock_VGA, Reset, 320, 240, Pos_x, Pos_y);
77
    Clock_10000 : Clock_Div port map (Clock_VGA, Clock_10k, 2500);
78
    
79
    -- Pixel ausgeben
80
    process(Clock_VGA)
81
    begin
82
        if(rising_edge(Clock_VGA)) then
83
            Color <= Bild(Pos_y, Pos_x); 
84
        end if;     
85
    end process;
86
87
    -- Betriebsstatus
88
    Output(1) <= Lock;
89
    Output(0) <= Reset;
90
    
91
end VGA_Top_Arch;

Und wenn ich jetzt in der Architektur das hier
1
   process(Clock_10k)
2
    begin
3
        if(rising_edge(Clock_10k)) then
4
            Pos_x <= Pos_x + 1;
5
            
6
            if(Pos_x = 639) then
7
                Pos_y <= Pos_y + 1;
8
            end if;
9
        end if;
10
    end process;

einfüge bekomme ich die im Screenshot sichtbaren Meldungen (sie 
verschwinden auch wieder sobald ich den Block wieder entferne).
Woher kommt die Meldung und was kann man dagegen machen?
Laut Xilinx bedeutet sie das Pins im Constraint nicht geroutet sind, was 
aber hier nicht zutrifft.
Btw: Clock_Div ist ein simpler Clock Divider...einfach nur um einen Takt 
ohne Clock Wizard runter zu teilen.

Danke für die Hilfe

Gruß
Daniel

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


Lesenswert?

Kampi schrieb:
> Und wenn ich jetzt in der Architektur das hier
>             Pos_x <= Pos_x + 1;
> einfüge bekomme ich die im Screenshot sichtbaren Meldungen
> "Multiple Drivers Pos_x ... Pos_y"
Das bedeutet, dass du Pos_x und Pos_y von 2 Stellen aus "treibst". Das 
ist wie wenn du in der Hardware 2 Ausgänge aufeinander schaltest.

Und wenn wir das Ganze mal verfolgen wird blitzschnell klar, was da 
passiert:
1
    component VGA_Controller is
2
        Port (  ...
3
                x_out : out integer;
4
                y_out : out integer );
5
    :
6
    :
7
    VGA_Core : VGA_Controller port map (... Pos_x, Pos_y);
Vom VGA_Controller wird ein Ausgang x_out auf Pos_x gelegt, deshalb 
darfst du da nicht noch zusätzlich einen Zähler draus machen.

> Woher kommt die Meldung und was kann man dagegen machen?
Es sollte eher die Frage sein: was willst du machen? Die Pos_x und 
Pos_y kommen aus dem Controller und zeigen dir an, wo die ausgaben 
bezogen auf die generierten Sync-Impulse gerade ist. Du darfst also 
nicht an diesen beiden Signalen herumschrauben, sondern musst auf sie 
reagieren.

BTW:
Was ist die absicht dabei, dass du diese Ausgabe hier taktest?
1
    -- Pixel ausgeben
2
    process(Clock_VGA)
3
    begin
4
        if(rising_edge(Clock_VGA)) then
5
            Color <= Bild(Pos_y, Pos_x); 
6
        end if;     
7
    end process;
Warum schreibst du nicht einfach so:
1
    -- Pixel ausgeben
2
    Color <= Bild(Pos_y, Pos_x);
Kommt dabei ein Unterschied heraus (mal abgesehen davon, dass der zweite 
Vorschlag einen Takt früher dran ist)?

Peter Bierbach schrieb:
> Aber eine Mitschuld und Mitverantwortung von Fehlerhaften VHDL
Das ist in etwa so wie Parken auf dem Mutter-Kind-Parkplatz nachts um 
3...
> Aber eine Mitschuld und Mitverantwortung von Fehlerhaften VHDL
Ich bin mir diesem Druck bewusst und werde ihm wie ein Mann 
entgegenstehen!

: Bearbeitet durch Moderator
von Kampi (Gast)


Lesenswert?

Hey Lothar,

danke für die ausführliche Antwort :)
Das kann gut sein das dieser Process bei der Pixelausgabe daran schuld 
ist...den hatte ich gestern aus irgendeinem Grund eingefügt und nicht 
mehr daran gedacht. Ich probier das heute Abend mal aus.

von Kampi (Gast)


Lesenswert?

Ach direkt noch eine Frage zu dem abgelegten Zeichensatz für die 
Textausgabe im FPGA...
Ich habe noch ein paar Probleme damit mir zu überlegen wie man das am 
besten machen kann.
Wenn ich das Datenblatt des LCD Controllers

http://www.nxp.com/documents/data_sheet/PCF2119X.pdf

als Grundlage nehme und diesen Zeichensatz samt Adressierung nachbauen 
will, wie kann man das am besten realisieren?
Gibt es die Möglichkeit, ähnlich wie in C, eigene Headerfiles zu 
importieren, wo ich dann z.B. den Zeichensatz drin habe?
Und wie kann man die Zeichen am optimalsten speichern?
Ich brauch ja dafür (denke ich mal) ein 1-D Array, wo jede Stelle 2-D 
ist um das Zeichen zu beschreiben.
Kann man sowas implementieren? Und wenn ja wie? :)

von Duke Scarring (Gast)


Lesenswert?

Kampi schrieb:
> Gibt es die Möglichkeit, ähnlich wie in C, eigene Headerfiles zu
> importieren, wo ich dann z.B. den Zeichensatz drin habe?
So ähnlich. Du kannst z.B. ein package verwenden.

> Und wie kann man die Zeichen am optimalsten speichern?
In einem Array, schau mal hier:
http://sourceforge.net/p/fpgastartset/code/29/tree/%20fpgastartset-code/Durchblicker/src/charrom.vhd

Duke

von Kampi (Gast)


Lesenswert?

Hallo,

danke für die Antwort.
Ich habe mal am Wochenende wieder etwas weiter rumprobiert und bei 
meinen Suchen bin ich auf dieses PDF gestoßen:

-> 
http://ece.gmu.edu/coursewebpages/ECE/ECE448/S13/viewgraphs/ECE448_lecture8_VGA_2.pdf

Die Schaltung für das Font-ROM verstehe ich... aber dadrunter die 
Schaltung für den "Text generation" Circuit" verstehe ich nicht 
wirklich...
Ich verstehe noch nicht so ganz, wie ich aus den x und y Koordinaten die 
mein VGA-Controller ausgibt und dem Zeichensatz, welcher im Font-ROM 
gespeichert ist, ein Bild mit Text generieren kann :(

von Noson Nonameborg (Gast)


Lesenswert?

Kampi schrieb:
> Ich verstehe noch nicht so ganz, wie ich aus den x und y Koordinaten die
> mein VGA-Controller ausgibt und dem Zeichensatz, welcher im Font-ROM
> gespeichert ist, ein Bild mit Text generieren kann :(

In diesem projekt: http://www.mikrocontroller.net/articles/Durchblicker

hat es auch eine Zahlenausgabe, ebenso in diesem FPGA-nachbau eines 
Einplatinencomputers mit ASCII-Ausgabe:

http://www.mikrocontroller.net/articles/Retrocomputing_auf_FPGA#Textausgabe

Letzlich geschieht die Zeichengenerierung über einen ROM, der das 
Bitmuster der zeichen enthält. Die unteren bits der x und y Koordinaten 
werden in Adressbits des ROM umgerechnet. Das ist das ganze Geheimnis.

MfG,

von Kampi (Gast)


Lesenswert?

Hallo,

noch mal eine kurze Frage...
Ich möchte jetzt eine Linie auf dem Display zeigen.
Dafür habe ich diesen Code
1
entity VGA_Top is
2
    Port (  Color : out STD_LOGIC_VECTOR(15 downto 0);
3
            HSync : out STD_LOGIC;
4
            VSync : out STD_LOGIC;
5
            Output : out STD_LOGIC_VECTOR(1 downto 0);
6
            Reset : in STD_LOGIC;
7
            Clock : in STD_LOGIC            
8
            );
9
end VGA_Top;
10
11
architecture VGA_Top_Arch of VGA_Top is
12
13
    signal Clock_VGA : std_logic;
14
    signal Clock_10k : std_logic;
15
    signal Clock_1 : std_logic;
16
    signal Pos_x : integer;
17
    signal Pos_y : integer;
18
    signal Lock : std_logic;
19
    
20
    constant Wall_X_l : integer := 32;
21
    constant Wall_X_r : integer := 35;
22
    
23
    -- Erzeugung des 25,175MHz Taktes
24
    component System is
25
        Port (  Clock_In : in STD_LOGIC;
26
                Clock_Reset : in STD_LOGIC;
27
                Clock_Locked : out STD_LOGIC;
28
                Clock_Out : out STD_LOGIC
29
                );
30
    end component System;
31
    
32
    -- Einbinden des VGA-Controllers
33
    component VGA_Controller is
34
        Port (  HSync : out STD_LOGIC;
35
                VSync : out STD_LOGIC;
36
                Clock_VGA : in STD_LOGIC;
37
                Reset : in STD_LOGIC;
38
                x_out : out integer;
39
                y_out : out integer
40
                );
41
    end component VGA_Controller;  
42
    
43
    component Clock_Div is
44
        Port (  Clock_In : in STD_LOGIC;
45
                Clock_Out : out STD_LOGIC;
46
                Divider : in integer
47
                );
48
    end component Clock_Div;  
49
    
50
    component Font_ROM is
51
        Port (  Clock : in STD_LOGIC;
52
                Adresse : in STD_LOGIC_VECTOR(15 downto 0);
53
                Data : out STD_LOGIC_VECTOR(7 downto 0)    
54
                );
55
    end component Font_ROM;
56
57
begin
58
    
59
    Clock_25MHz : System port map (Clock, '1', Lock, Clock_VGA);
60
    VGA_Core : VGA_Controller port map (HSync, VSync, Clock_VGA, Reset, Pos_x, Pos_y);
61
    Clock_10000 : Clock_Div port map (Clock_VGA, Clock_10k, 2500);
62
    
63
    process(Clock)
64
   
65
    begin
66
        if(rising_edge(Clock)) then
67
            if((Pos_x > 35) and (Pos_x < 40)) then
68
                Color <= x"FC1F";
69
            end if;        
70
        end if;
71
    end process;
72
73
    -- Betriebsstatus
74
    Output(1) <= Lock;
75
    Output(0) <= Reset;
76
    
77
end VGA_Top_Arch;

Aber ich bekomme keine Linie :(
Wo ist das Problem?

von Lattice User (Gast)


Lesenswert?

Kampi schrieb:
>
> Aber ich bekomme keine Linie :(
> Wo ist das Problem?

2 Fehler:

Erstens solltest du Clock_VGA benutzen um die Line zu erzeugen.
Zweitens hast du keine Farbe für ausserhalb der Linie definiert.

Letzteres kann man auf 2 Arten läussen,
a) ein else
b) Hintergrundfarbe am Anfang des Prozesses ausgeben.

von Kampi (Gast)


Lesenswert?

Hey,

danke für die Antwort.
Klappt nun :)
Warum sollte ich Clock_VGA nehmen? Hat das einen bestimmten Grund?

von Kampi (Gast)


Lesenswert?

Hallo,

ich habe eine neue Frage...
Und zwar versuche ich gerade ein paar animierte Objekte auf dem 
Bildschirm darzustellen.
Dazu habe ich versucht einen Code aus einem Buch zu übernehmen:
1
entity VGA_Top is
2
    Port (  Color : out STD_LOGIC_VECTOR(15 downto 0);
3
            HSync : out STD_LOGIC;
4
            VSync : out STD_LOGIC;
5
            Output : out STD_LOGIC_VECTOR(1 downto 0);
6
            Reset : in STD_LOGIC;
7
            Clock : in STD_LOGIC            
8
            );
9
end VGA_Top;
10
11
architecture VGA_Top_Arch of VGA_Top is
12
13
    signal Clock_VGA : std_logic;
14
    signal Clock_10k : std_logic;
15
    signal Clock_1 : std_logic;
16
    signal Pos_x : integer;
17
    signal Pos_y : integer;
18
    signal Lock : std_logic;
19
    
20
    signal Bar_L : integer := 32;
21
    signal Bar_R : integer := 35;
22
    
23
    signal Bar_On : std_logic;
24
25
    -- Erzeugung des 25,175MHz Taktes
26
    component System is
27
        Port (  Clock_In : in STD_LOGIC;
28
                Clock_Reset : in STD_LOGIC;
29
                Clock_Locked : out STD_LOGIC;
30
                Clock_Out : out STD_LOGIC
31
                );
32
    end component System;
33
    
34
    -- Einbinden des VGA-Controllers
35
    component VGA_Controller is
36
        Port (  HSync : out STD_LOGIC;
37
                VSync : out STD_LOGIC;
38
                Clock_VGA : in STD_LOGIC;
39
                Reset : in STD_LOGIC;
40
                x_out : out integer;
41
                y_out : out integer
42
                );
43
    end component VGA_Controller;  
44
    
45
    component Clock_Div is
46
        Port (  Clock_In : in STD_LOGIC;
47
                Clock_Out : out STD_LOGIC;
48
                Divider : in integer
49
                );
50
    end component Clock_Div;  
51
    
52
    component Font_ROM is
53
        Port (  Clock : in STD_LOGIC;
54
                Adresse : in STD_LOGIC_VECTOR(15 downto 0);
55
                Data : out STD_LOGIC_VECTOR(7 downto 0)    
56
                );
57
    end component Font_ROM;
58
    
59
begin
60
    
61
    Clock_25MHz : System port map (Clock, '1', Lock, Clock_VGA);
62
    VGA_Core : VGA_Controller port map (HSync, VSync, Clock_VGA, Reset, Pos_x, Pos_y);
63
    Clock_10000 : Clock_Div port map (Clock_VGA, Clock_10k, 2500);
64
    
65
    Bar_On <= 
66
        '1' when (32 <= Pos_x) and (Pos_x <= 35) else
67
        '0';
68
        
69
    process(Bar_on)
70
    
71
    begin
72
        if(Bar_On = '1') then
73
            Color <= x"FC00";
74
        else
75
            Color <= x"001F";
76
        end if;
77
    end process;
78
79
    -- Betriebsstatus
80
    Output(1) <= Lock;
81
    Output(0) <= Reset;
82
    
83
end VGA_Top_Arch;

Eigentlich sollte da jetzt eine einfarbige Linie auf einem einfarbigen 
Hintergrund erscheinen.
Aber es erscheint nur die Linie und ich verstehe gerade nicht so ganz 
warum :(

Danke für die Hilfe!

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


Lesenswert?

Kampi schrieb:
> Hat das einen bestimmten Grund?
Ja. Du solltest niemals ohne Not eine zweite Taktdomäne aufmachen. 
Blitzschnell hast du da nämlich Taktverhältnisse, die "nicht zueinander 
passen" an der Backe und damit ein asynchrones Design im FPGA. Arbeite 
stattdessen mit Clock-Enables!!

Such mal hier im FPGA-Forum nach "Postulate"...

> Aber es erscheint nur die Linie und ich verstehe gerade nicht so ganz
> warum :(
Wie ist color an die Hardware angeschlossen?

BTW
Dieser sehr ausführliche Bar_on Prozess könnte so viel übersichtlicher 
geschrieben werden:
Color <= x"FC00" when Bar_in='1' else x"001F";

von Kampi (Gast)


Lesenswert?

Hallo,

danke für die Antwort.
Color ist wie folgt angeschlossen:

Bits 0-4 Farbe 1
Bits 5-9 Farbe 2
Bits 10-15 Farbe 3

Wie gesagt, das Beispiel ist erst einmal nur abgeschrieben und an meinen 
Code angepasst. Schöner machen kommt nachher :)

Gruß
Daniel

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


Lesenswert?

Kampi schrieb:
> Lothar Miller schrieb:
>> Dieser sehr ausführliche Bar_on Prozess könnte so viel übersichtlicher
>> geschrieben werden: ...
> das Beispiel ist erst einmal nur abgeschrieben
Da wo du das herhast, würde ich nichts abschreiben...


> Color ist wie folgt angeschlossen:
Was passiert, wenn du das umdrehst:
1
        if(Bar_On = '1') then
2
            Color <= x"001F";
3
        else
4
            Color <= x"FC00";
5
        end if;

Was passiert, wenn du die Farbe in der Mitte nimmst?

Was passiert, wenn du alle Bits setzt?

von Kampi (Gast)


Lesenswert?

Wenn ich es umdrehe habe ich einen roten Balken und der Rest ist 
schwarz.
Bei den Bits in der Mitte ist der Balken dann Lila und wenn ich alle 
Bits setze, ist da ebenfalls ein Violetter Balken.

Was ich mich halt frage ist warum der Hintergrund keine andere Farbe 
hat...

von Lattice User (Gast)


Lesenswert?

Kampi schrieb:
> Wenn ich es umdrehe habe ich einen roten Balken und der Rest ist
> schwarz.
> Bei den Bits in der Mitte ist der Balken dann Lila und wenn ich alle
> Bits setze, ist da ebenfalls ein Violetter Balken.
>
> Was ich mich halt frage ist warum der Hintergrund keine andere Farbe
> hat...

Pins richtig zugeordnet?

von Kampi (Gast)


Lesenswert?

Sorry, meinte ein kaum sichtbarer schwarzer Balken bei allen Pins auf 1.

von Kampi (Gast)


Lesenswert?

Lattice User schrieb:
> Kampi schrieb:
>> Wenn ich es umdrehe habe ich einen roten Balken und der Rest ist
>> schwarz.
>> Bei den Bits in der Mitte ist der Balken dann Lila und wenn ich alle
>> Bits setze, ist da ebenfalls ein Violetter Balken.
>>
>> Was ich mich halt frage ist warum der Hintergrund keine andere Farbe
>> hat...
>
> Pins richtig zugeordnet?

Jap. Habs ausprobiert

von Lattice User (Gast)


Lesenswert?

Kampi schrieb:
> Lattice User schrieb:
>> Kampi schrieb:
>>> Wenn ich es umdrehe habe ich einen roten Balken und der Rest ist
>>> schwarz.
>>> Bei den Bits in der Mitte ist der Balken dann Lila und wenn ich alle
>>> Bits setze, ist da ebenfalls ein Violetter Balken.
>>>
>>> Was ich mich halt frage ist warum der Hintergrund keine andere Farbe
>>> hat...
>>
>> Pins richtig zugeordnet?
>
> Jap. Habs ausprobiert

Dann muss es funktionieren, der Fehler liegt nicht im gepostetem Code. 
(Es sei denn ich bin blind)

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


Lesenswert?

Kampi schrieb:
> Was ich mich halt frage ist warum der Hintergrund keine andere Farbe
> hat...
Hat er doch. Nur die komplett falsche...

Kampi schrieb:
>> Pins richtig zugeordnet?
> Jap. Habs ausprobiert
Wie?
Hast du schonmal ein blaues oder ein grünes Bild erzeugt?

Kampi schrieb:
> Bei den Bits in der Mitte ist der Balken dann Lila
Eher Magenta? Also die Mischung von Baul und Rot?
http://www.bewegtesbild.de/content/index.php?option=com_content&task=view&id=31&Itemid=29

Kampi schrieb:
> Sorry, meinte ein kaum sichtbarer schwarzer Balken bei allen Pins auf 1.
Kurios! Wird da noch was invertiert?
Evtl. verdaut der Monitor die hohen 3V-Pegel doch nicht... :-/
Da wäre jetzt ein Oszilloskop recht hilfreich. Hast du sowas?

Lattice User schrieb:
> der Fehler liegt nicht im gepostetem Code.
Ganz deiner Meinung.

von Kampi (Gast)


Lesenswert?

mmh ein Oszi habe ich.
Aber ich habe gerade ein anderes Problem festgestellt.
Und zwar wollte ich mir die drei Farben mal ausgeben lassen, aber es 
werden immer nur 2 Farben angezeigt.
Hab den Code mal umgeformt:
1
begin
2
    
3
    Clock_25MHz : System port map (Clock, '1', Lock, Clock_VGA);
4
    VGA_Core : VGA_Controller port map (HSync, VSync, Clock_VGA, Reset, Pos_x, Pos_y);
5
    Clock_10000 : Clock_Div port map (Clock_VGA, Clock_10k, 2500);
6
    
7
    Red <= 
8
        '1' when (200 <= Pos_x) and (Pos_x <= 250) else '0';
9
    Blue <= 
10
         '1' when (400 <= Pos_x) and (Pos_x <= 450) else '0';
11
    Green <= 
12
          '1' when (300 <= Pos_x) and (Pos_x <= 350) else '0';       
13
    process(Clock_VGA)
14
    
15
    begin
16
        if(rising_edge(Clock_VGA)) then
17
        if(Red = '1') then
18
            Color <= x"0010";
19
        end if;
20
        if(Blue = '1') then
21
            Color <= x"0200";
22
        end if;
23
        if(Green = '1') then
24
            Color <= x"8000";
25
        end if;
26
        end if;
27
    end process;
28
29
    -- Betriebsstatus
30
    Output(1) <= Lock;
31
    Output(0) <= Reset;
32
    
33
end VGA_Top_Arch;

Im Moment werden Rot und Grün angezeigt. Tausche ich jetzt die 
Koordinaten in der Abfrage von Grün und Blau, wird ein roter und ein 
blauer Balken angezeigt :/

von Lattice User (Gast)


Lesenswert?

Du hast wieder vergessen eine Hintergrundfarbe (z.B. Schwarz) zu 
definieren

z.B. so
1
        if(rising_edge(Clock_VGA)) then
2
          Color <= x"0000";
3
          if(Red = '1') then
4
          .....

von Lattice User (Gast)


Lesenswert?

Kampi schrieb:
>
> Im Moment werden Rot und Grün angezeigt. Tausche ich jetzt die
> Koordinaten in der Abfrage von Grün und Blau, wird ein roter und ein
> blauer Balken angezeigt :/

Könnte natürlich sein, dass x_pos nie 400 oder grösser wird, oder dass
das Timing nicht stimmt un der Monitor nur das halbe Bild anzeigt.

Definiere eine Hintergrundfarbe, und schau wo die 2 sichtbaren Balken 
erscheinen und ob sie eventuell abgeschnitten werden.

von Kampi (Gast)


Lesenswert?

Lattice User schrieb:
> Du hast wieder vergessen eine Hintergrundfarbe (z.B. Schwarz) zu
> definieren
>
> z.B. so        if(rising_edge(Clock_VGA)) then
>           Color <= x"0000";
>           if(Red = '1') then
>           .....

Chaka :)
Das wars!
Kannst du mir erklären warum ihn das stört?
Wobei ich es mir fast denken kann...im Grunde tritt in den 
Zwischenspalten keine der Bedingungen in Kraft, wodurch die Pins so 
gesetzt bleiben (in meinem ersten Beispiel). Aber warum wurde der 
Bildschirm dann am Ende des 2. Balkens doch wieder Schwarz?

von Lattice User (Gast)


Lesenswert?

Kampi schrieb:

> Chaka :)
> Das wars!
> Kannst du mir erklären warum ihn das stört?

Den FPGA sollte es jedenfalls nicht stören.

> Wobei ich es mir fast denken kann...im Grunde tritt in den
> Zwischenspalten keine der Bedingungen in Kraft, wodurch die Pins so
> gesetzt bleiben (in meinem ersten Beispiel). Aber warum wurde der
> Bildschirm dann am Ende des 2. Balkens doch wieder Schwarz?

Hat du mit dem Osci die VGA Signale angeschaut, mit und ohne Änderungen?
So ist das alles im rumgestochere im Nebel.

von Kampi (Gast)


Lesenswert?

Hey,

also ich habe da eigentlich nichts merkwürdiges gemessen.
Kann aber auch sein das Vivado wieder etwas rumgesponnen hat und die 
Synthese nicht geklappt hat >.< (hatte ich die Tage öfters, nach einer 
zweiten Synthese funktioniert die Schaltung dann).
Naja....bin im Moment dabei einen Punkt zur Bewegung zu bringen :)
Hab irgendwie gerade Lust mir mein eigenes Pong Game zu bauen :o

von Kampi (Gast)


Lesenswert?

Hallo,

ich habe die Tage mal etwas weiter rum gespielt und mir nun versucht 
einen Kreis auf dem Bildschirm auszugeben.
1
----------------------------------------------------------------------------------
2
-- Company:         www.kampis-elektroecke.de
3
-- Engineer:        Daniel Kampert
4
-- 
5
-- Create Date:     02.08.2014 13:17:51
6
-- Design Name: 
7
-- Module Name:     VGA_Top - VGA_Top_Arch
8
-- Project Name: 
9
-- Target Devices:  XC7Z010CLG400-1
10
-- Tool Versions:   Vivado 2014.2
11
-- Description:     VGA Interface for a 640 x 480 Pixel Screen
12
-- 
13
-- Dependencies: 
14
-- 
15
-- Revision:
16
-- Revision         0.01 - File Created
17
-- Additional Comments:
18
-- 
19
----------------------------------------------------------------------------------
20
21
library IEEE;
22
use IEEE.STD_LOGIC_1164.ALL;
23
24
-- Uncomment the following library declaration if using
25
-- arithmetic functions with Signed or Unsigned values
26
use IEEE.NUMERIC_STD.ALL;
27
28
-- Uncomment the following library declaration if instantiating
29
-- any Xilinx leaf cells in this code.
30
--library UNISIM;
31
--use UNISIM.VComponents.all;
32
33
entity VGA_Top is
34
    Port (  Color : out STD_LOGIC_VECTOR(15 downto 0);
35
            HSync : out STD_LOGIC;
36
            VSync : out STD_LOGIC;
37
            Output : out STD_LOGIC_VECTOR(2 downto 0);
38
            Reset : in STD_LOGIC;
39
            Clock : in STD_LOGIC;
40
            Button : in STD_LOGIC_VECTOR(3 downto 0)           
41
            );
42
end VGA_Top;
43
44
architecture VGA_Top_Arch of VGA_Top is
45
46
    -- Einstellungen
47
    constant Ballsize : integer := 8;
48
    constant Len_Wall_r : integer := 150;
49
    constant Len_Wall_l : integer := 150;
50
    constant Height : integer := 480;
51
    constant Lenght : integer := 640;
52
53
    -- Clocksignale
54
    signal Clock_VGA : std_logic;
55
    signal Clock_1250 : std_logic;
56
    signal Clock_Refresh : std_logic;
57
58
    -- Koordinaten des Zeigers auf dem Bildschirm
59
    signal Pos_x : std_logic_vector(9 downto 0);                
60
    signal Pos_y : std_logic_vector(9 downto 0); 
61
    
62
    -- Enable Signale für die Formen
63
    signal Wall_l_on : std_logic;
64
    signal Wall_r_on : std_logic;
65
    signal Ball_on : std_logic;
66
    
67
    -- Button 
68
    signal Button_Deb1 : std_logic;
69
    signal Button_Deb2 : std_logic;
70
    signal Button_Deb3 : std_logic;
71
    signal Button_Deb4 : std_logic;
72
73
    -- Balkengrenzen
74
    signal Wall_l_o : integer := 2;
75
    signal Wall_l_u : integer := 150;
76
    signal Wall_r_o : integer := 2;
77
    signal Wall_r_u : integer := 150;
78
    
79
    -- Startposition Ball
80
    signal Ball_x_l : integer := 32;
81
    signal Ball_x_r : integer := 39;
82
    signal Ball_y_t : integer := 32;
83
    signal Ball_y_b : integer := 39;
84
    
85
    -- Register für die aktuelle Position
86
    signal Ball_x_reg : unsigned(9 downto 0);
87
    signal Ball_y_reg : unsigned(9 downto 0);
88
    signal Wall_l_reg : unsigned(9 downto 0);
89
    signal Wall_r_reg : unsigned(9 downto 0);
90
    
91
    -- Ballgeschwindigkeiten
92
    signal x_vel_reg : integer;
93
    signal y_vel_reg : integer;
94
    
95
    -- Balkenschritte
96
    signal Wall_l_step : integer;
97
    signal Wall_r_step : integer;
98
    
99
    -- Balldaten
100
    signal Ball_Data : std_logic_vector(7 downto 0);
101
    signal ROM_Addr : std_logic_vector(2 downto 0);
102
    signal ROM_Col : std_logic_vector(2 downto 0);
103
    signal ROM_Data : std_logic_vector(7 downto 0);
104
    signal ROM_Bit : std_logic;
105
    
106
    -- Systemsignale
107
    signal Lock : std_logic;
108
    signal Test : std_logic;
109
110
    -- Erzeugung des 25,175MHz Taktes
111
    component System is
112
        Port (  Clock_In : in STD_LOGIC;
113
                Clock_Reset : in STD_LOGIC;
114
                Clock_Locked : out STD_LOGIC;
115
                Clock_Out : out STD_LOGIC
116
                );
117
    end component System;
118
    
119
    -- Einbinden des VGA-Controllers
120
    component VGA_Controller is
121
        Port (  HSync : out STD_LOGIC;
122
                VSync : out STD_LOGIC;
123
                Clock_VGA : in STD_LOGIC;
124
                Reset : in STD_LOGIC;
125
                x_out : out STD_LOGIC_VECTOR(9 downto 0);                
126
                y_out : out STD_LOGIC_VECTOR(9 downto 0) 
127
                );
128
    end component VGA_Controller;  
129
    
130
    component Clock_Div is
131
        Port (  Clock_In : in STD_LOGIC;
132
                Clock_Out : out STD_LOGIC;
133
                Divider : in integer
134
                );
135
    end component Clock_Div;  
136
    
137
    component Font_ROM is
138
        Port (  Clock : in STD_LOGIC;
139
                Adresse : in STD_LOGIC_VECTOR(15 downto 0);
140
                Data : out STD_LOGIC_VECTOR(7 downto 0)    
141
                );
142
    end component Font_ROM;
143
    
144
    component Debounce is
145
        Port (  Input : in  STD_LOGIC;
146
                Output : out  STD_LOGIC;
147
                Clock : in  STD_LOGIC;
148
                Debouncetime : in integer
149
                );
150
    end component Debounce;
151
    
152
    type Bild_Array is array (0 to 7) of std_logic_vector(7 downto 0); 
153
    constant Ball : Bild_Array := 
154
    (
155
        "00111100",
156
        "01111110",
157
        "11111111",
158
        "11111111",
159
        "11111111",
160
        "11111111",    
161
        "01111110", 
162
        "00111100"  
163
    );
164
165
begin
166
    
167
    Clock_25MHz     : System port map (Clock, '1', Lock, Clock_VGA);
168
    VGA_Core        : VGA_Controller port map (HSync, VSync, Clock_VGA, Reset, Pos_x, Pos_y);
169
    Clock_1k2Hz     : Clock_Div port map (Clock_VGA, Clock_1250, 10000);    
170
    Clock_100Hz     : Clock_Div port map (Clock_1250, Clock_Refresh, 125); 
171
    
172
    -- Taster entprellen
173
    Taster1         : Debounce port map (Button(0), Button_Deb1, Clock_1250, 25);   
174
    Taster2         : Debounce port map (Button(1), Button_Deb2, Clock_1250, 25);   
175
    Taster3         : Debounce port map (Button(2), Button_Deb3, Clock_1250, 25);   
176
    Taster4         : Debounce port map (Button(3), Button_Deb4, Clock_1250, 25); 
177
    
178
    -- Wenn Position erreicht, Enable-Signal auf High setzen
179
    Ball_on <=
180
        '1' when (Ball_x_l <= to_integer(unsigned(Pos_x))) and (to_integer(unsigned(Pos_x)) <= Ball_x_r) and
181
                 (Ball_y_t <= to_integer(unsigned(Pos_y))) and (to_integer(unsigned(Pos_y)) <= Ball_y_b) else '0';
182
    Wall_l_on <=
183
        '1' when (0 <= to_integer(unsigned(Pos_x))) and (to_integer(unsigned(Pos_x)) <= 10) and
184
                 (0 <= to_integer(unsigned(Pos_y))) and (to_integer(unsigned(Pos_y)) <= 150) else '0';
185
                 
186
    Wall_r_on <=
187
        '1' when (630 <= to_integer(unsigned(Pos_x))) and (to_integer(unsigned(Pos_x)) <= 640) and
188
                 (Wall_r_o <= to_integer(unsigned(Pos_y))) and (to_integer(unsigned(Pos_y)) <= Wall_r_u) else '0';                 
189
190
    -- Daten für den Ball auslesen
191
    ROM_Addr <= Pos_y(2 downto 0);
192
    ROM_Col <= Pos_x(2 downto 0);
193
    ROM_Data <= Ball(to_integer(unsigned(ROM_Addr)));
194
    ROM_Bit <= ROM_Data(to_integer(unsigned(ROM_Col)));
195
    
196
    -- Formen am Bildschirm ausgeben
197
    process(Clock_VGA) 
198
    begin 
199
        if(rising_edge(Clock_VGA)) then
200
            -- Hintergrund 
201
            Color <= x"0000";
202
            if((ROM_Bit = '1') and (Ball_on = '1')) then
203
                Color <= x"FC00";
204
            end if;
205
            
206
            if(Wall_l_on = '1') then
207
                Color <= x"0010";
208
            end if;
209
            
210
            if(Wall_r_on = '1') then
211
                Color <= x"0010";
212
            end if;        
213
        end if;
214
    end process;
215
    
216
     -- Positionen updaten
217
    process(Clock_1250)
218
    
219
    begin
220
        if(rising_edge(Clock_Refresh)) then
221
                                    
222
            if(to_integer(unsigned(Ball_x_reg)) = (Lenght - 1)) then
223
                x_vel_reg <= -1;
224
            elsif(to_integer(unsigned(Ball_x_reg)) = 0) then
225
                x_vel_reg <= 1;
226
            end if;
227
            
228
            if(to_integer(unsigned(Ball_y_reg)) = (Height - 1)) then
229
                y_vel_reg <= -1;
230
            elsif(to_integer(unsigned(Ball_y_reg)) = 0) then
231
                y_vel_reg <= 1;
232
            end if;
233
        
234
            Ball_x_reg <= Ball_x_reg + x_vel_reg;
235
            Ball_y_reg <= Ball_y_reg + y_vel_reg;
236
        end if;
237
    end process;
238
239
240
    -- Objektpositionen updaten
241
    Ball_x_l <= to_integer(unsigned(Ball_x_reg));
242
    Ball_x_r <= Ball_x_l + (Ballsize - 1);
243
    Ball_y_t <= to_integer(unsigned(Ball_y_reg));
244
    Ball_y_b <= Ball_y_t + (Ballsize - 1);
245
    Wall_r_o <= to_integer(unsigned(Wall_r_reg));
246
    Wall_r_u <= Wall_r_o + Len_Wall_r;
247
    Wall_l_o <= to_integer(unsigned(Wall_l_reg));
248
    Wall_l_u <= Wall_l_o + Len_Wall_l;
249
250
    -- Betriebsstatus
251
    Output(2) <= Test;
252
    Output(1) <= Lock;
253
    Output(0) <= Reset;
254
    
255
end VGA_Top_Arch;
Die Ausgabe funktioniert auch super, nur wenn ich den Kreis jetzt über 
den Bildschirm wandern lasse, wird er eckig dargestellt :(
Woran das liegt kann ich mir in etwa denken (wahrscheinlich daran, dass 
ich die letzten drei Bits der Koordinaten auf dem Bildschirm für das 
Array nutze).
Nur wie bekomme ich das jetzt anders hin, sodass der Kreis weiterhin 
rund bleibt :/?
Einen separaten Counter für die Adresse?

Danke für die Hilfe!

von Kampi (Gast)


Lesenswert?

Hab das Problem quasi gelöst. Ich habe einfach gesagt, dass die 
Schrittweite nicht 1 ist, sondern ein vielfaches von 8.
Dann wird der Speicher richtig ausgelesen und der Ball ist rund :)

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.