UPGRADE YOUR BROWSER

We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!

cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
Visitor mrburen121
Visitor
1,884 Views
Registered: ‎12-03-2017

BASYS3 VGA

Jump to solution

Hello,

 

I'm trying to get the CGA output working on the BASYS3 board but everytime on the VGA scren I get the message "VIDEO MODE NOT SUPPORTED". I have a screen that supports 640x480, that is the resolution what I would like to use.

 

I created my own prescalers to generate a 25Mhz and 20Hz clock. As debug I put the clocks on the Pmod ports for testing with a scope. On the scope I see that the clocks are correct. 25Mhz = 40ns and 20Hz = 50ms.

25Mhz

25Mhz

20Hz

20Hz

 

I created the following code.

-- VGA output with a static background color.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_STD.all;

entity VGA is
port( 
        clock 			: in STD_Logic;	       -- 100Mhz
		Schakelaar		: in STD_Logic;		   -- Switch
        red_uit		: out STD_Logic;       -- Red_out
		green_uit		: out STD_Logic;       -- Green out
		blue_uit		: out STD_Logic;       -- Blue out
		h_sync			: out STD_Logic;       -- Horizontal sync
		V_sync 			: out STD_Logic;       -- Vertical sync
	    clock25_OUT		: out STD_Logic;	   -- 25MHz clock output for testing scope
	    clock20_OUT		: OUT STD_Logic);      -- 20Hz clock output for testing scope
end VGA;

architecture Behavioral of VGA is

-- Signals
signal 	clock_25Mhz		: STD_Logic := '0';
signal	clock_20hz		: std_logic := '0';
signal 	v_on			: STD_Logic := '0';

signal 	lijn_counter 	: integer range -43 to 980;
signal 	h_counter		: integer range   0 to 1023;
signal 	v_counter		: integer range   0 to 1023;
signal	prescaler		: unsigned ( 23 downto 0):= X"000000";
signal	prescaler2		: unsigned ( 3 downto 0):= X"0";

-- constands
constant startvalue	: integer := 0;    -- Start value
constant h_end		: integer := 799;
constant v_end		: integer := 524;

constant hpuls_lb	: integer := 656; -- H puls laag
constant hpuls_le	: integer := 752; -- H puls laag
constant vpuls_lb	: integer := 490; -- V puls laag
constant vpuls_le	: integer := 491; -- V puls laag
constant h_max		: integer := 640;	-- H max px
constant v_max		: integer := 480; -- V max px

begin

-- Prescaler clock 25MHz
prescaler_25Mhz : process(clock)
begin
if rising_edge(clock) then 
	if prescaler2 = X"1" then          -- T=1/25Mhz = 40ns 50.000.000/25.000.000hz = 2 = 2 HEX
		prescaler2 <= (others => '0');
		clock_25Mhz <= not clock_25Mhz;
	else
		prescaler2 <= prescaler2 + "1";
	end if;
end if;
end process prescaler_25Mhz;

-- Prescaler clock 20Hz
prescaler_20hz : process(clock)
begin
if rising_edge(clock) then 
	if prescaler = X"2625A0" then          -- T=1/20hz = 50ms 50.000.000/20hz = 2.500.00 = 2625A0 HEX
		prescaler <= (others => '0');
		clock_20hz <= not clock_20hz;
	else
		prescaler <= prescaler + "1";
	end if;
end if;
end process prescaler_20hz;


-- Create pulse horizontal and vertical counter
-- Sync horizontal and vertical
Sync : process(clock, clock_25Mhz, h_counter, v_counter)
begin
	
	-- Pulsen
	if (h_counter >= hpuls_lb AND h_counter <=  hpuls_le) then
		h_sync <= '0'; else h_sync <= '1';
	end if;
	
	if (v_counter >= vpuls_lb AND v_counter <=  vpuls_le) then
		v_sync <= '0'; else v_sync <= '1';
	end if;
	
	if (h_counter < h_max AND v_counter < v_max) then
		v_on <= '1'; else v_on <= '0';
	end if;

	-- Synchroniseren
	if (clock_25Mhz = '1') then							-- Horizontal sync
		if (rising_edge(clock)) then  
			if (h_counter = h_end) then 
				h_counter <= startvalue; 
				if (v_counter = v_end) then 			-- Vertical sync
					v_counter <= startvalue; else
					v_counter <= v_counter + 1; 
				end if; 
			else
				h_counter <= h_counter + 1; 
			end if;
		end if;
	end if;
end process Sync;


-- Background a static red color
-- move a line over the screen based on a switch
color: process(V_on, clock, clock_25Mhz, clock_20hz, schakelaar, lijn_counter)
begin

-- Line direction up or down based on switch
if rising_edge(clock_20hz) Then

	-- switch = schakelaar
	if schakelaar = '1' Then       -- switch
		if lijn_counter > 640 Then lijn_counter <= 1; -- line counter
		else lijn_counter <= lijn_counter + 1;
		end if;
	end if;
	
	-- switch = schakelaar
	if schakelaar = '0' Then
		if lijn_counter < 0 Then lijn_counter <= 640;
		else lijn_counter <= lijn_counter - 1;
		end if;
	end if;
end if;

-- Kleuren bepalen
if clock_25Mhz = '1' AND rising_edge(clock_25Mhz) Then
	if (v_counter < lijn_counter - 4) or (v_counter > lijn_counter +4) Then
		-- Zwart lijn
		red_uit  <= '1';     -- Red
		green_uit <= '0';     -- Green
		blue_uit <= '0';     -- Blue
	else
		-- Wit achtergrond
		red_uit  <= '0';     -- Red
		green_uit <= '0';     -- Green
		blue_uit <= '1';     -- Blue
	end if;
end if;
end process color;

-- output as debug
clock25_OUT <= clock_25Mhz;     -- On pinout J1 debug
clock20_OUT <= clock_20hz;	    -- On pinout L2 debug

end Behavioral;

This is the testbanch code.

LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
 
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--USE ieee.numeric_std.ALL;
 
ENTITY VGA_TB IS
END VGA_TB;
 
ARCHITECTURE behavior OF VGA_TB IS 
 
    -- Component Declaration for the Unit Under Test (UUT)
    COMPONENT VGA
    PORT(clock				: in STD_Logic;		    -- 100MHz
			Schakelaar		: in STD_Logic;
			red_uit		: out STD_Logic;
			green_uit		: out STD_Logic;
			blue_uit		: out STD_Logic;
			h_sync			: out STD_Logic;
			v_sync 			: out STD_Logic;
			clock25_OUT		: out STD_Logic;		-- 25MHz
			clock20_OUT 	: out STD_Logic);		-- 20Hz
        
    END COMPONENT;
    
   --Inputs
   signal clock 		: std_logic := '0';
   signal Schakelaar    : std_logic := '0';

 	--Outputs
   signal red_uit 	: std_logic;
   signal green_uit 	: std_logic;
   signal blue_uit 	: std_logic;
   signal h_sync 		: std_logic;
   signal v_sync 		: std_logic;
   signal clock25_OUT : std_logic;
	signal clock20_OUT : std_logic;

BEGIN
 
	-- Instantiate the Unit Under Test (UUT)
   uut: VGA PORT MAP (
          clock 		=> clock,
          Schakelaar => Schakelaar,
          red_uit 	=> red_uit,
          green_uit 	=> green_uit,
          blue_uit 	=> blue_uit,
          h_sync 		=> h_sync,
          v_sync 		=> v_sync,
          clock25_OUT => clock25_OUT,
			 clock20_OUT => clock20_OUT
        );
		  
	-- Clock process definitions
   clock_process :process
   begin
	while now <= 100000000 NS loop
		clock <= '0';
		wait for 5 ns;
		clock <= '1';
		wait for 5 ns;
		end loop;
	wait;
   end process;

   -- Stimulus process
   stim_proc: process
   begin		
      -- hold reset state for 100 ns.
      wait for 100 ns;	
		schakelaar <= '1';
		wait for 100 ns;
		schakelaar <= '0';
      -- insert stimulus here 

      wait;
   end process;

END;

This are my constraints:

set_property IOSTANDARD LVTTL [get_ports blauw_uit]
set_property IOSTANDARD LVTTL [get_ports clock]
set_property IOSTANDARD LVTTL [get_ports clock20_OUT]
set_property IOSTANDARD LVTTL [get_ports clock25_OUT]
set_property IOSTANDARD LVTTL [get_ports groen_uit]
set_property IOSTANDARD LVTTL [get_ports h_sync]
set_property IOSTANDARD LVTTL [get_ports rood_uit]
set_property IOSTANDARD LVTTL [get_ports Schakelaar]
set_property IOSTANDARD LVTTL [get_ports V_sync]

set_property PACKAGE_PIN J18 [get_ports blauw_uit]
set_property PACKAGE_PIN W5 [get_ports clock]
set_property PACKAGE_PIN J1 [get_ports clock20_OUT]
set_property PACKAGE_PIN L2 [get_ports clock25_OUT]
set_property PACKAGE_PIN D17 [get_ports groen_uit]
set_property PACKAGE_PIN P19 [get_ports h_sync]
set_property PACKAGE_PIN N19 [get_ports rood_uit]
set_property PACKAGE_PIN R2 [get_ports Schakelaar]
set_property PACKAGE_PIN R19 [get_ports V_sync]

I added a schreenshot in the attachments.

 

What am I doing wrong? 

 

Kind regards,

 

Chris

Tags (1)
Simulation1.PNG
0 Kudos
1 Solution

Accepted Solutions
Moderator
Moderator
2,279 Views
Registered: ‎11-09-2015

Re: BASYS3 VGA

Jump to solution

Hi @mrburen121,

 

I guess this is not the same board clock between the two boards.

 

How do I create a prescaler that converts the 100Mhz clock to a 25Mhz clock? In the code below is the prescaler from 50Mhz to 25Mhz

> Why aren't you using a MMCM/PLL? You might want to look at the clocking wizard IP.

 

Hope that helps,

 

Regards,

 

Florent


Florent
Product Application Engineer - Xilinx Technical Support EMEA
**~ Don't forget to reply, give kudos, and accept as solution.~**

View solution in original post

0 Kudos
6 Replies
Moderator
Moderator
1,847 Views
Registered: ‎11-09-2015

Re: BASYS3 VGA

Jump to solution

Hi @mrburen121,

 

It is maybe written in your code but I do not want to do code review:

  • What is the refresh rate of your resolution (is it 60Hz)? So 25 MHz is your pixel clock?
  • What is you 20Hz clock? Why do you need it?
  • Assuming that you are doing 640*480@60Hz, hsynq and Vsync are negative pulses. Is it what you have?
  • Make sure you are not sending data while you are not in the active data period. From your code I am not sure it is the case

Regards,

 

Florent


Florent
Product Application Engineer - Xilinx Technical Support EMEA
**~ Don't forget to reply, give kudos, and accept as solution.~**
0 Kudos
Visitor mrburen121
Visitor
1,834 Views
Registered: ‎12-03-2017

Re: BASYS3 VGA

Jump to solution
Hallo Floreert,

Thee refresh rate is 60Hz that is indeed the 25MHz pixel clock. The 20Hz clock is for moving a line over the screen. This isn't necessary for now, I was was testing the switch on the basys3. 640*480@60Hz hsynq and Vsync are negative pulse. I'm not sure about your last point, I will look into that.

Kind regards,

Chris
0 Kudos
Mentor watari
Mentor
1,798 Views
Registered: ‎06-16-2013

Re: BASYS3 VGA

Jump to solution

Hi @mrburen121

 

I guess it is monitor issue or polarity of syn issue.

 

Please confirm the following.

 

- What kind of monitor do you use ? Does this monitor support CGA video timing ?

- Could you confirm polarity of hsync and vsync at CGA video timing ?

 

Thank you.

Best regards,

 

Visitor mrburen121
Visitor
1,744 Views
Registered: ‎12-03-2017

Re: BASYS3 VGA

Jump to solution

Hello,

 

Thank you for your replay.

1. My monitor support CGA video timing.

2. HSYNC and VSYNC are correct.

 

I changed my code and removed the 20Hz clock. instead of moving the line based on the clock and state of the switch. Now I changed it to show a number of line based on the state of three switches. Meaning 001 = 1 and 011 = 3 etc. The lines are cyan with a dark blue blackgrond  See the code below.

This code is working on a basys2 board with output to VGA screen. But when I uploaded the code (with the 25Mhz prescaler in my furst post) to a basys3 board it isn't working. So there is something wrong with my prescaler. How do I create a prescaler that converts the 100Mhz clock to a 25Mhz clock? In the code below is the prescaler from 50Mhz to 25Mhz.

 

----------------------------------------------------------------------------------
-- blue background
-- cyan lines
-- lines are 4 px
-- max 7 lines
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_STD.all;

entity VGA is
port(           clock 			: in STD_Logic;				-- 50Mhz clock
		sw			: std_logic_vector( 2 downto 0);        -- Input sw
                red_out			: out STD_Logic;			-- VGA red out
		green_out		: out STD_Logic;			-- VGA green out
		blue_out		: out STD_Logic;			-- VGA blue out
		h_sync			: out STD_Logic;			-- HSYNC
		V_sync 			: out STD_Logic);			-- VSYNC
end VGA;

architecture Behavioral of VGA is

-- Signals
signal 	clock_25Mhz		: STD_Logic := '0';			-- 25Mhz clock for 640x480 op 60Hz refresh rate
signal 	v_on			: STD_Logic := '0';			-- Video output 640x480 at 60Hz refresh rate

signal 	h_counter		: integer range   0 to 1023;
signal 	v_counter		: integer range   0 to 1023;

Signal 	choice			: integer := 0;				-- sw selection for binary input, default "000" = 0

-- constands
constant beginValue	        : integer := 0;				-- Begin value horizontal counter
constant h_end			: integer := 799;			-- Horizontal end px
constant v_end			: integer := 524;			-- Vertical 

constant hpuls_lb			: integer := 656; 		-- H pulse low
constant hpuls_le			: integer := 752; 		-- H pulse low
constant vpuls_lb			: integer := 490; 		-- V pulse low
constant vpuls_le			: integer := 491; 		-- V pulse low
constant h_max				: integer := 640;		-- H max px
constant v_max				: integer := 480; 		-- V max px

begin


-- Prescaler for clock 25MHz
prescaler_25Mhz: process(clock)
begin
	if rising_edge(clock) then
		if clock_25Mhz = '1' then clock_25Mhz <= '0';
		else clock_25Mhz <= '1';
		end if;
	end if;
end process prescaler_25Mhz;


-- Create pulse horizontal and vertical counter
-- Sync horizontal and vertical
Sync : process(clock, clock_25Mhz, h_counter, v_counter)
begin
	
	-- Pulsen
	if (h_counter >= hpuls_lb AND h_counter <=  hpuls_le) then
		h_sync <= '0'; else h_sync <= '1';
	end if;
	
	if (v_counter >= vpuls_lb AND v_counter <=  vpuls_le) then
		v_sync <= '0'; else v_sync <= '1';
	end if;
	
	if (h_counter < h_max AND v_counter < v_max) then
		v_on <= '1'; else v_on <= '0';
	end if;

	-- Sync
	if (clock_25Mhz = '1') then							-- Horizontal sync
		if (rising_edge(clock)) then  
			if (h_counter = h_end) then 
				h_counter <= beginValue; 
				if (v_counter = v_end) then 			-- Vertical sync
					v_counter <= beginValue; else
					v_counter <= v_counter + 1; 
				end if; 
			else
				h_counter <= h_counter + 1; 
			end if;
		end if;
	end if;
end process Sync;


-- Background blue and line(s) cyan
-- Show based on the binary sw input a number of line from 0 to 7
color: process(V_on, clock, clock_25Mhz, sw)
begin

-- Kleuren bepalen
if clock_25Mhz = '1' AND rising_edge(clock_25Mhz) Then
	-- Read binary the state of the switches and convert to integer
	choice <= to_integer(unsigned(sw));
	
	if (v_counter < 34) AND (v_counter >= 30) AND (choice > 0) then 		-- sw 001 = 1 line
		red_out <=  '0'  ;
		blue_out <= v_on ;
		green_out <= v_on ;
	elsif (v_counter < 103) AND (v_counter >= 99) AND (choice > 1) then		-- sw 010 = 2 lines
		red_out <=  '0'  ;
		blue_out <= v_on ;
		green_out <= v_on ;
	elsif (v_counter < 171) AND (v_counter >= 167) AND (choice > 2) then	-- sw 011 = 3 lines
		red_out <=  '0'  ;
		blue_out <= v_on ;
		green_out <= v_on ;
	elsif (v_counter < 240) AND (v_counter >= 236) AND (choice > 3) then 	-- sw 100 = 4 lines
		red_out <=  '0'  ;
		blue_out <= v_on ;
		green_out <= v_on ;
	elsif (v_counter < 309) AND (v_counter >= 305) AND (choice > 4) then 	-- sw 101 = 5 lines
		red_out <=  '0'  ;
		blue_out <= v_on ;
		green_out <= v_on ;
	elsif (v_counter < 377) AND (v_counter >= 373) AND (choice > 5) then 	-- sw 110 = 6 lines
		red_out <=  '0'  ;
		blue_out <= v_on ;
		green_out <= v_on ;
	elsif (v_counter < 446) AND (v_counter >= 442) AND (choice > 6)then 	-- sw 111 = 7 lines
		red_out <=  '0'  ;
		blue_out <= v_on ;
		green_out <= v_on ;
	else
		-- blue background
		red_out  <= '0'  ;
		green_out <= '0'  ;
		blue_out <= v_on ;
	end if;
end if;
end process color;

end Behavioral;

Best regards,

0 Kudos
Moderator
Moderator
2,280 Views
Registered: ‎11-09-2015

Re: BASYS3 VGA

Jump to solution

Hi @mrburen121,

 

I guess this is not the same board clock between the two boards.

 

How do I create a prescaler that converts the 100Mhz clock to a 25Mhz clock? In the code below is the prescaler from 50Mhz to 25Mhz

> Why aren't you using a MMCM/PLL? You might want to look at the clocking wizard IP.

 

Hope that helps,

 

Regards,

 

Florent


Florent
Product Application Engineer - Xilinx Technical Support EMEA
**~ Don't forget to reply, give kudos, and accept as solution.~**

View solution in original post

0 Kudos
Mentor watari
Mentor
1,729 Views
Registered: ‎06-16-2013

Re: BASYS3 VGA

Jump to solution

Hi @mrburen121

 

According to your design, the polarity of horizontal sync and vertical sync are same as negative.

However, in my experience and the following URL, the polarity of horizontal sync and vertical sync are same as positive.

 

http://nemesis.lonestar.org/reference/video/ega.html

 

Could you modify each polarity ?

 

Thank you.

Best regards,

 

0 Kudos