Datum:
Hallo Zusammen, dieser Code macht mich verrückt und ich kann den Fehler einfach nicht finden. Folgender Zusammenhang: Habe den Code aus einer Übung heraus kopiert und wollte ihn einmal testen und ein Rechteckt per VGA auf den Monitor übertragen. Leider wir kein Signal übertragen und ich begann Testleds in den Code einzubauen, um rauszufinden wo der Fehler liegen könnte. Das Problem ist: Ich habe in den ersten beiden Prozessen über ein If-Statement, die einen Taster und die Reset-Taste abfragt, eine Ein- und Ausfunktion einer LED eingebaut. Das Ding ist nur, dass die LEDs immer brennen, egal ob ich den Taster drücke oder nicht. PIN-Belegung der Taster ist tausendfach gecheckt worden und richtig. Irgendwo muss ein grundlegender Fehler sein, den ich einfach nicht finden kann... Vielleicht kann jemand mit mehr Erfahrung und Expertise mir weiterhelfen... Vielen Dank für alle Antworten... Hier der komplette Code:
library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; use ieee.numeric_std.all; entity vga_control is port ( reset, taster : in std_logic; clk : in std_logic; VGA_CLK, -- Should be 25.125 MHz VGA_CLK, Dot clock to DAC VGA_HS, -- Active Low Horizontal Sync VGA_VS, -- Active Low Vertical Sync VGA_BLANK, -- Active Low DAC blanking control VGA_SYNC : out std_logic; -- Active Low DAC Sync on Green VGA_R, VGA_G, VGA_B : out std_logic_vector(7 downto 0); ledtest1, ledtest2, ledtest3 : out std_logic := '0' ); end vga_control; architecture rtl of vga_control is -- Video parameters constant HTOTAL : integer := 800; constant HSYNC : integer := 96; constant HBACK_PORCH : integer := 48; constant HACTIVE : integer := 640; constant HFRONT_PORCH : integer := 16; constant VTOTAL : integer := 525; constant VSYNC : integer := 2; constant VBACK_PORCH : integer := 33; constant VACTIVE : integer := 480; constant VFRONT_PORCH : integer := 10; constant RECTANGLE_HSTART : integer := 100; constant RECTANGLE_HEND : integer := 540; constant RECTANGLE_VSTART : integer := 100; constant RECTANGLE_VEND : integer := 380; signal Hcount : std_logic_vector(9 downto 0):= "0000000000"; -- Horizontal position (0 - 800) signal Vcount : std_logic_vector(9 downto 0):= "0000000000"; -- Vertical position (0 - 524) signal EndOfLine, EndOfField : std_logic :='0'; signal vga_hblank, vga_hsync, vga_vblank, vga_vsync : std_logic; -- Sync. signals signal rectangle_h, rectangle_v, rectangle : std_logic; -- rectangle area begin test : process (clk) begin if taster= '1' then ledtest1<='0'; else ledtest1<='1'; end if; end process test; HCounter : process (clk) begin if reset = '0' then Hcount <= (others=> '0'); ledtest2<='1'; elsif (clk'event and clk = '1') then ledtest2<='0'; if EndOfLine = '1' then Hcount <= (others=> '0'); else Hcount <= Hcount + 1; end if; end if; end process; VCounter: process (clk) begin if reset = '0' then Vcount <= (others=> '0'); elsif (clk'event and clk = '1') then if EndOfLine = '1' then if EndOfField = '1' then Vcount <= (others=> '0'); else Vcount <= Vcount + 1; end if; end if; end if; end process VCounter; HSyncGen : process (clk) begin if reset = '1' then vga_hsync <= '1'; elsif clk'event and clk = '1' then if EndOfLine = '1' then vga_hsync <= '1'; elsif Hcount = HSYNC - 1 then vga_hsync <= '0'; end if; end if; end process HSyncGen; HBlankGen : process (clk) begin if reset='1' then vga_hblank <= '1'; elsif clk'event and clk='1' then if Hcount = HSYNC + HBACK_PORCH then vga_hblank <= '0'; elsif Hcount = HSYNC + HBACK_PORCH + HACTIVE then vga_hblank <= '1'; end if; end if; end process HBlankGen; VSyncGen : process (clk) begin if reset='1' then vga_vsync <= '1'; elsif clk'event and clk = '1' then if EndOfLine ='1' then if EndOfField = '1' then vga_vsync <= '1'; elsif Vcount = VSYNC - 1 then vga_vsync <= '0'; end if; end if; end if; end process VSyncGen; VBlankGen : process (clk) begin if reset = '1' then vga_vblank <= '1'; elsif clk'event and clk = '1' then if EndOfLine = '1' then if Vcount = VSYNC + VBACK_PORCH - 1 then vga_vblank <= '0'; elsif Vcount = VSYNC + VBACK_PORCH + VACTIVE - 1 then vga_vblank <= '1'; end if; end if; end if; end process VBlankGen; RectangleHGen : process (clk) begin if reset = '1' then rectangle_h <= '1'; elsif clk'event and clk = '1' then if Hcount = HSYNC + HBACK_PORCH + RECTANGLE_HSTART then rectangle_h <= '1'; elsif Hcount = HSYNC + HBACK_PORCH + RECTANGLE_HEND then rectangle_h <= '0'; end if; end if; end process RectangleHGen; RectangleVGen : process (clk) begin if reset = '1' then rectangle_v <= '0'; elsif clk'event and clk = '1' then if EndOfLine = '1' then if Vcount = VSYNC + VBACK_PORCH - 1 + RECTANGLE_VSTART then rectangle_v <= '1'; elsif Vcount = VSYNC + VBACK_PORCH - 1 + RECTANGLE_VEND then rectangle_v <= '0'; end if; end if; end if; end process RectangleVGen; rectangle <= rectangle_h and rectangle_v; VideoOut: process (clk) begin if reset = '1' then VGA_R <= "00000000"; VGA_G <= "00000000"; VGA_B <= "00000000"; elsif clk'event and clk = '1' then if rectangle = '1' then VGA_R <= "11111111"; VGA_G <= "11111111"; VGA_B <= "11111111"; elsif vga_hblank = '0' and vga_vblank ='0' then VGA_R <= "00000000"; VGA_G <= "00000000"; VGA_B <= "11111111"; else VGA_R <= "00000000"; VGA_G <= "00000000"; VGA_B <= "00000000"; end if; end if; end process VideoOut; vga_clk_gen : PROCESS(clk)--devides 50MHz clock in 2, making it a 25MHz clock VARIABLE count : INTEGER := 0; BEGIN IF rising_edge(clk) THEN IF count = 0 THEN VGA_CLK <= '1'; --1 period of 50MHz high count := 1; ELSIF count = 1 THEN VGA_CLK <= '0'; count := 0; END IF; END IF; END PROCESS vga_clk_gen; VGA_HS <= not vga_hsync; VGA_VS <= not vga_vsync; VGA_SYNC <='0'; VGA_BLANK <= not (vga_hsync or vga_vsync); end rtl; |
Datum:
kurzes Update: LEDs funktionieren nun. Ich weiß zwar nicht warum ;-(, aber es geht nun. Nur funktioniert der Code nicht, war auch ein Rätsel für mich ist... Vielleicht kann mir jemand in dem Punkt weiter helfen...
Datum:
Mike schrieb: > Nur funktioniert der Code nicht, war auch ein Rätsel für mich ist... WAS funktioniert nicht? WIE hast du das festgestellt? WO ist die Testbench? Am Rande: Entweder die use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; oder die use ieee.numeric_std.all; aber NIEMALS beide zusammen! Und dann noch der Beitrag "IEEE.STD_LOGIC_ARITH.ALL obsolete" Flasche Sensitivliste:
test : process (clk) -- clk wird nicht gebraucht begin if taster= '1' then -- taster fehlt in der sensitivliste ledtest1<='0'; else ledtest1<='1'; end if; end process test; |
Unvollständige Sensitivlisten:
HCounter : process (clk) begin if reset = '0' then -- reset fehlt in der Sensitivliste! Hcount <= (others=> '0'); ledtest2<='1'; elsif (clk'event and clk = '1') then ... VCounter: process (clk) begin if reset = '0' then -- reset fehlt in der Sensitivliste! Vcount <= (others=> '0'); elsif (clk'event and clk = '1') then ... |
Warum brauchst du bei sowas wie einem VGA-Interface, wo sich immer wieder alles wiederholt, überhaupt einen Reset?
Datum:
Abgesehen von Lothars Bemerkungen. Dein Timing laeuft intern mit 50 MHz. Du gibt aber einen VGA Clock von 25 MHz aus. Irgendwas passt da nicht zusammen... Ralf
Datum:
@lothar Sorry für meine doch sehr grobe Fehlerbeschreibung. Also der Bildschirm bekommt kein Signal, das ist mein Hauptproblem. Ich hab mich nun durch verschiedene VHDL-Code-Versionen für die Ansteuerung eines VGA-Signals durchgearbeiten und habe dabei bei der Signalübertragung verschiedene Versionen gesehen. In meinem Code wird zu allererst vor der Übertragung der Farbeinformationen das HSync und HBack_Porch "gesetzt" bevor dann die Farbinformation übertragen wird. Beispiel_V1: h_Sync(96)-->h_back_porch(48)-->Farbübertragung(640)... In einer anderen Version aus dem Netz wurde sofort die RGB-Farbinformation übertragen und dann mit dem Counter soweit bis zur Ende des aktiven Pixelbereichs hochgezählt und dann erst die Synchronisation realisiert. In diesem Fall hat wenigstens der LCD ein "Out of Range" rausgegeben. Immerhin kam was an, daher vermute ich, dass diese Version richtig ist... Beispiel_V2: Farbübertragung(640)-->HFront_Porch(16)-->h_Sync(96)-->h_back_porch(48). .. Wenn mir das jemand mitteilen könnte, würde das wohl mein (Verständis-)Problem lösen...
Datum:
Diese Timings sind erstmal ziemlich unwichtig. Schlimmstenfalls ist dein Bild auf dem Schirm leicht verschoben... Mike schrieb: > der Bildschirm bekommt kein Signal, das ist mein Hauptproblem. Und was sagt die Simulation? Gerade ein VGA-Interface lässt sich bildhübsch simulieren... Mein (uralter) Code dafür sieht so aus:
library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.NUMERIC_STD.ALL; entity VGA is Port ( CLK : in std_logic; Line : out integer range 0 to 480; Column : out integer range 0 to 640; RedIn : in std_logic; GreenIn : in std_logic; BlueIn : in std_logic; Hsync : out std_logic; Vsync : out std_logic; RedOut : out std_logic; GreenOut : out std_logic; BlueOut : out std_logic); end VGA; architecture Behavioral of VGA is signal pixelclk : std_logic := '0'; signal inScreen : std_logic := '0'; signal dispHorizontal : std_logic := '0'; signal dispVertical : std_logic := '0'; signal syncH : std_logic := '1'; signal syncV : std_logic := '1'; signal aktHorizontal : integer range 0 to 800; -- horizontal counter: 800 * 40ns = 320us -> 31,25kHz signal aktVertical : integer range 0 to 521; -- vertical counter: 521 * 320us = 320us -> 31,25kHz signal aktLine : integer range 0 to 480; signal aktColumn : integer range 0 to 640; begin process begin wait until (rising_edge(CLK)); -- 50MHz pixelclk <= not pixelclk; -- 25MHz = 40ns if(pixelclk='1') then aktHorizontal <= aktHorizontal+1; if (aktHorizontal = 799) then aktHorizontal <= 0; aktVertical <= aktVertical+1; if (aktVertical = 520) then aktVertical <= 0; end if; end if; end if; if (aktHorizontal=0) then syncH <= '0'; elsif (aktHorizontal=96) then syncH <= '1'; else syncH <= syncH; end if; if (aktVertical=0) then syncV <= '0'; elsif (aktVertical=2) then syncV <= '1'; else syncV <= syncV; end if; if (aktHorizontal=0) then dispHorizontal <= '0'; elsif (aktHorizontal=144)then dispHorizontal <= '1'; elsif (aktHorizontal=784)then dispHorizontal <= '0'; else dispHorizontal <= dispHorizontal; end if; if (aktVertical=0) then dispVertical <= '0'; elsif (aktVertical=31) then dispVertical <= '1'; elsif (aktVertical=511) then dispVertical <= '0'; else dispVertical <= dispVertical; end if; end process; inScreen <= dispVertical and dispHorizontal; aktColumn <= aktHorizontal-144 when dispHorizontal='1' else 0; aktLine <= aktVertical-31 when dispVertical='1' else 0; Line <= aktLine; Column <= aktColumn; RedOut <= RedIn when inScreen='1' else '0'; GreenOut <= GreenIn when inScreen='1' else '0'; BlueOut <= BlueIn when inScreen='1' else '0'; Hsync <= syncH; Vsync <= syncV; end Behavioral; |
Datum:
@lothar Ich danke dir für den Code, werde ihn (wenn alle Stricke reissen) auch einmal ausprobieren. Habe den Code nun soweit umgeschrieben, dass in der Simulation eigentlich alles passen solle. Leider gibt der LCD-M. immer noch kein Signal aus. Daher 2 konkrete Fragen: 1. Ich habe in meinem Code angenommen, dass das blank-Signal low-active ist. Ist das richtig? 2. Ich arbeite mit 25 Mhz. In meiner Simulation dauert die horizontale Synchronisation 3,88 us. Als Standart ist aber 3,813 us definiert, da die clk mit 25.175 Mhz arbeitet. Könnte das ein Problem sein? Liebe Grüße Mike
Datum:
@Mike Wenn in der Simulation alles soweit passt und gut aussieht, und es dann immer noch nicht funzt kannst du nur mit einem Scope gucken ob die Signale auch so ankommen. Wenn VSync und HSync erstmal passen und die RGB Infos nur während der Display-Active-Time "zappeln" dann passts bzw sollte was zu sehen sein. Aber ich kann mich nur Lothar anschließen : Ein VGA-Signal zu simulieren bzw erzeugen ist (bei normalem Std-VGA) kein Problem. zu 2) : 25MHz statt 25.1irgendwas MHz sind kein Problem. Man kann den HSync ja ein/zwei Impulse kürzer machen. Aber i.d.r sollte kein Monitor ein Problem damit haben. Ich hab damals auch mit 25MHz gearbeitet, kein Thema, lief auf anhieb.
Datum:
Mike schrieb: > 2. Ich arbeite mit 25 Mhz. In meiner Simulation dauert die horizontale > Synchronisation 3,88 us. Als Standart ist aber 3,813 us definiert, da > die clk mit 25.175 Mhz arbeitet. Könnte das ein Problem sein? Nein. Aktuelle Monitore können sich auch bei sehr großen Abweichungen noch synchronisieren... > Ich danke dir für den Code, werde ihn (wenn alle Stricke reissen) auch > einmal ausprobieren. Aber du kannst ihn vorher schon einfach mal anschauen, der lief bei mir als VGA Timingenerator für das legendäre Pong... ;-)
Datum:
unglaublich, es läuft nun...;-) Ich danke Lothar, Ralf, Takter und Rene B. für die hilfreichen Kommentare. @lothar: werde ich machen. Nur weil es läuft, heißt es ja nicht, das der Code so in dem Zustand stabil ist. ;-)
Datum:
Durch die Simulation bemerkte ich einige Fehler im Code z.B. dass das RGB-Signal immer noch online war, während ich die Synchronisation durchführte und nicht über das blank-Signal ausgeschaltet wurde...
