altera - VHDL VGA interface -


i've been modelling vga interface on de0 board. have following model 640x480 display refreshes @ 60hz:

main model:

library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all;  entity vga    port (clk                     :   in   std_logic; -- demo had 2 bit vector         vga_hs, vga_vs          :   out std_logic;         vga_r, vga_g, vga_b :   out std_logic_vector(3 downto 0)); end entity vga;  architecture a1 of vga   signal rst, clk25 :   std_logic; -- rst resets pixel clock  begin   sync1  :  entity work.sync(a1)             port map (clk25, vga_hs, vga_vs, vga_r, vga_g, vga_b);   clk_25 :  entity work.pll(rtl)             port map (clk, rst, clk25); end architecture a1; 

sync model:

library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all;  entity sync port(      clk                :   in  std_logic;      h_sync, v_sync     :   out     std_logic;      r, g, b            :   out std_logic_vector(3 downto 0)      ); end entity sync;  architecture a1 of sync   signal h_pos: integer range 0 800:=0;   signal v_pos : integer range 0 520:=0; begin   timing :process(clk) begin     if rising_edge(clk)         if (h_pos = 480 or v_pos = 280)  -- middle of screen pic res/2 + (fp + sync + bp)             r <= (others => '1');             g <= (others => '1');             b <= (others => '1');         else             r <= (others => '0');             g <= (others => '0');             b <= (others => '0');            end if;          if (h_pos < 800)             h_pos <= h_pos + 1;             else                 h_pos <= 1;             if (v_pos < 520)                 v_pos <= v_pos + 1;                 else                 v_pos <= 1;             end if;           end if;       if (h_pos > 16 , h_pos < 112 ) -- h_pos between end of fp , end of h_sync         h_sync <= '0';   -- h_sync needs stay low during display     else         h_sync <= '1';     end if;       if (v_pos > 8 , v_pos < 10 ) --v_pos between end of fp , end of v_sync         v_sync <= '0';  -- v_sync needs stay low during display     else         v_sync <= '1';     end if;      if ((h_pos > 0 , h_pos < 160) or (v_pos > 0 , v_pos < 40 )) then--during of sync i.e fp + sync + bp colour signals stay low         r <= (others => '0');         g <= (others => '0');         b <= (others => '0');     end if;   end if; end process timing;  end architecture a1; ----------amendments made model 09/02 13:42---------- 

the other direct instantiation pll generated quartus ii seems work fine.. thank mr zilmer :). model compiles fine. load de0. connect monitor , nothing on display. should display cross in centre of screen. display using samsung 1920x1080. stop model displaying anything? or have made obvious mistake in model. have changed of standard timing values fit 60hz refresh 25mz clk. d

your vhdl code entity sync doesn't analyze. missing end if , initial values h_sync , v_sync violate subtype constraint:

    signal h_pos: integer range 1 800 := 0;     signal v_pos: integer range 1 520 := 0; 

where 0 outside bounds of 1 800 or 1 520.

this raises question of whether or not have architecture entity sync, or whether sync unbound. either of might give incorrect indication (and error isn't demonstrated in question).

we can use testbench demonstrate sync in simulation 25 mhz clock:

library ieee; use ieee.std_logic_1164.all; --use ieee.numeric_std.all;  entity sync     port (         clk:               in  std_logic;         h_sync, v_sync:    out std_logic;         r, g, b:           out std_logic_vector(3 downto 0)     ); end entity sync;  architecture a1 of sync     signal h_pos: integer range 1 800 := 1; -- := 0;     signal v_pos: integer range 1 520 := 1; -- := 0; begin timing:       process (clk)         begin         if rising_edge(clk)             if h_pos = 480 or v_pos = 280  -- middle of screen                 r <= (others => '1');                 g <= (others => '1');                 b <= (others => '1');             else                 r <= (others => '0');                 g <= (others => '0');                 b <= (others => '0');                end if;              if h_pos < 800                 h_pos <= h_pos + 1;                 else                     h_pos <= 1;                 if v_pos < 520                     v_pos <= v_pos + 1;                     else                     v_pos <= 1;                 end if;                  if h_pos > 16 , h_pos < 112                       h_sync <= '0';   -- h_sync low during display                 else                     h_sync <= '1';                 end if;                   if v_pos > 8 , v_pos < 10                       v_sync <= '0';  -- v_sync low during display                 else                     v_sync <= '1';                 end if;                  if (h_pos > 1 , h_pos < 160) or                     (v_pos > 1 , v_pos < 40 ) -- black during blanking                     r <= (others => '0');                     g <= (others => '0');                     b <= (others => '0');                 end if;             end if;         end if;  -- added misssing end if     end process timing;  end architecture a1;  library ieee; use ieee.std_logic_1164.all;  entity sync_tb end entity;  architecture foo of sync_tb     signal clk:     std_logic := '0';     signal h_sync:  std_logic;     signal v_sync:  std_logic;     signal r, g, b: std_logic_vector (3 downto 0); begin dut:     entity work.sync          port map (             clk => clk,             h_sync => h_sync,             v_sync => v_sync,             r => r,             g => g,             b => b         ); clock:     process     begin         wait 20 ns;  -- clock period 25 mhz = 40 ns;         clk <= not clk;         if > 20 ms  -- 1 frame time plus bit             wait;         end if;     end process; end architecture; 

and troubleshoot:

sync_tb_1.png

the first thing notice h_sync wrong. note v_sync appears around 16.667 ms (1/60th of second).

we can add h_pos , v_pos counters can @ h_sync, know h_pos counter running v_sync can see in right neighborhood of 60 hz.

so picked wrong place add end if. correcting separates operating counters operating on outputs (h_sync, v_sync , r,g,b).

timing:       process (clk)         begin         if rising_edge(clk)             if h_pos = 480 or v_pos = 280  -- middle of screen                 r <= (others => '1');                 g <= (others => '1');                 b <= (others => '1');             else                 r <= (others => '0');                 g <= (others => '0');                 b <= (others => '0');                end if;              if h_pos < 800                 h_pos <= h_pos + 1;             else                 h_pos <= 1;                 if v_pos < 520                     v_pos <= v_pos + 1;                 else                     v_pos <= 1;                  end if;               end if;  -- separate counters produce             -- hsync             if h_pos > 16 , h_pos < 112                   h_sync <= '0';   -- h_sync low during display             else                 h_sync <= '1';             end if;              -- vsync             if v_pos > 8 , v_pos < 10                   v_sync <= '0';  -- v_sync low during display             else                 v_sync <= '1';             end if;             -- blanking             if (h_pos > 1 , h_pos < 160) or                 (v_pos > 1 , v_pos < 40 )                 r <= (others => '0');                 g <= (others => '0');                 b <= (others => '0');             end if;         end if;     end process timing;  

we have h_sync now:

sync_tb_2.png

notice can see vertical blanking interval too.

zooming in can see there horizontal white line @ v_pos 280:

sync_tb_3.png

along vertical line @ h_pos 480 (+1):

sync_tb_4.png

and looks might work.

the design change might tempted make start visible portion of line @ h_pos = 0 , the visible portion of frame @ v_pos = 0. allow else address pixels writing in frame buffer without adding additional pixel counters or having offset arithmetic. (pixel addressing starts @ 0 x , y axis).


Comments

Popular posts from this blog

routing - AngularJS State management ->load multiple states in one page -

python - GRASS parser() error -

Swift game error message -