# Debugging FPGA VGA connection

I want to display images on the screen and to do this I used this git and this article as references. The specs of my screen are 1280x1024, including porch pixels the dimensions are 1688x1066. From this I derived the needed pixel frequency.

107.96MHz = 1688 x 1066 x 60

To generate 108MHz clock I used Altera PLL with reference clock of 50MHz.

My calculated timings for v_sync and h_sync are 16.7ms and 15.66us respectively.

Values for VGA_SYNC_N and VGA_BLANK_N I used constants that were used in that eewiki article, although there wasn't much info I could find on these parameters. I have read ADV7123 datasheet, but that didn't help me much.

VGA_R   [7..0]  <= 4-bit red pixel value
VGA_G   [7..0]  <= 4-bit green pixel value
VGA_B   [7..0]  <= 4-bit blue pixel value
VGA_CLK         <= 108MHz
VGA_SYNC_N      <= '0'
VGA_BLANK_N     <= '1'


This is the diagram I used as a reference

and this is my RTL diagram

Factory flash of the De1 Soc FPGA displays a wallpaper via the VGA. I measured those VGA outputs with an oscilloscope and get timings and amplitudes for various signals and use them as a comparison for my own values.

vsync = 16.6ms, 3.3V
hsync = 33us, 3.3V
RGB outputs = between 1.2V and 1.6V


I flashed FPGA with my attempt at displaying stuff and used the scope again. Measured timings match my design but don't match the timings chosen by the stock flash to display stuff. are correct while color values I really can't tell. In my code if set all the RGB values to 0, resultant is a noise with 100mV pk-pk.

vsync = 16.6ms, 3.3V
hsync = 15.7us , 3.3V
RGB outputs = around 180mV


I do not know why my AD7123 output is ~180mV when a given colour is set to '1', but same colour output will be ~1.5V when using the factory flash. My vsync and hsync timings match the calculated theoretical settings, but are different to the values measured from the factory flash. VGA DAC has only 3 non-colour inputs and I do not know how can I force it to output a single analog value that is bigger than 180mV. Tutorial which I was following on YouTube, that guy seemed to able to display stuff on the screen without having to involve the VGA_CLK, VGA_SYNC_N and VGA_BLANK_N and had the same screen resolution and development board as me.

I have verified couple of times that my assignments in pin planner are correct.

I am unable to get on the right track to debug this further. If anyone could point flows in my reasoning or hint me at what things I might have done wrong or overlooked as I am really stuck and do not know how to progress.

My question is: What am I lacking in my design that might be preventing me from interfacing a cyclone to a VGA output?

Here is my code in case someone can spot an obvious error that I can not.

VGA Controller

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

ENTITY VGA IS
PORT(
CLOCK_50MHz:        IN STD_LOGIC_VECTOR(1 downto 0);
VGA_HS,VGA_VS:      OUT STD_LOGIC;
VGA_CLK:            OUT STD_LOGIC;
SW: STD_LOGIC_VECTOR(1 downto 0);
KEY: STD_LOGIC_VECTOR(3 DOWNTO 0);
VGA_R,VGA_B,VGA_G: OUT STD_LOGIC_VECTOR(3 downto 0);

n_b:        OUT STD_LOGIC; -- VGA_BLANK_N
n_s:        OUT STD_LOGIC; -- VGA_SYNC_N
);
END VGA;

ARCHITECTURE MAIN OF VGA IS
SIGNAL VGACLK,RESET,HSYNC:STD_LOGIC;

component pll_50_to_108 is
port (
clk_in_clk    : in  std_logic := 'X'; -- clk
clk_out_clk   : out std_logic;        -- clk
reset_1_reset : in  std_logic := 'X'  -- reset
);
end component pll_50_to_108;

COMPONENT SYNC IS
PORT(
CLK: IN STD_LOGIC;
HSYNC: OUT STD_LOGIC;
VSYNC: OUT STD_LOGIC;
R: OUT STD_LOGIC_VECTOR(3 downto 0);
G: OUT STD_LOGIC_VECTOR(3 downto 0);
B: OUT STD_LOGIC_VECTOR(3 downto 0);
KEYS: IN STD_LOGIC_VECTOR(3 DOWNTO 0);
S: IN STD_LOGIC_VECTOR(1 downto 0)
);
END COMPONENT SYNC;

BEGIN

VGA_CLK <= VGACLK;

n_b        <='1';
n_s        <='0';

C1: pll_50_to_108 PORT MAP (CLOCK_50MHz(0), VGACLK,RESET);
C2: SYNC PORT MAP(VGACLK,VGA_HS,VGA_VS,VGA_R,VGA_G,VGA_B,"0000","00");

END MAIN;


SYNC

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.my.all;

ENTITY SYNC IS
PORT(
CLK: IN STD_LOGIC;
HSYNC: OUT STD_LOGIC:='1';
VSYNC: OUT STD_LOGIC:='1';
R: OUT STD_LOGIC_VECTOR(3 downto 0);
G: OUT STD_LOGIC_VECTOR(3 downto 0);
B: OUT STD_LOGIC_VECTOR(3 downto 0);
KEYS: IN STD_LOGIC_VECTOR(3 DOWNTO 0);
S: IN STD_LOGIC_VECTOR(1 downto 0)
);
END SYNC;

ARCHITECTURE MAIN OF SYNC IS
-----1280x1024 @ 60 Hz pixel clock 108 MHz
SIGNAL RGB: STD_LOGIC_VECTOR(3 downto 0);
SIGNAL SQ_X1,SQ_Y1: INTEGER RANGE 0 TO 1688:=500;
SIGNAL SQ_X2,SQ_Y2: INTEGER RANGE 0 TO 1688:=600;
SIGNAL DRAW1,DRAW2:STD_LOGIC:='0';
SIGNAL HPOS: INTEGER RANGE 0 TO 1688:=0;
SIGNAL VPOS: INTEGER RANGE 0 TO 1066:=0;
BEGIN

PROCESS(CLK)
BEGIN
IF(CLK'EVENT AND CLK='1')THEN

-- turn all the pixels
if((HPOS>408 and HPOS <1100) or (VPOS>42 and VPOS<600)) then
R<=(others=>'1');
G<=(others=>'1');
B<=(others=>'1');
else
R<=(others=>'0');
G<=(others=>'0');
B<=(others=>'0');
end if;

IF(HPOS<1688)THEN
HPOS<=HPOS+1;
ELSE
HPOS<=0;
IF(VPOS<1066)THEN
VPOS<=VPOS+1;
ELSE
VPOS<=0;
END IF;
END IF;

-- turn off pixels at the porches
IF((HPOS>0 AND HPOS<408) OR (VPOS>0 AND VPOS<42))THEN
R<=(others=>'0');
G<=(others=>'0');
B<=(others=>'0');
END IF;

IF(HPOS>48 AND HPOS<160)THEN    --  HSYNC
HSYNC<='0';
ELSE
HSYNC<='1';
END IF;
IF(VPOS>0 AND VPOS<4)THEN   --  VSYNC
VSYNC<='0';
ELSE
VSYNC<='1';
END IF;
END IF;
END PROCESS;
END MAIN;

• Why are you using 4-bit buses to drive a device that has 8-bit inputs? What are you doing with the leftover bits? – Dave Tweed Mar 20 '17 at 20:51
• Have you specified timing constraints with an SDC file and verified with timequest that the design is meeting those timing requirements? – Tom Carpenter Mar 20 '17 at 21:16
• Are you driving the 4 most significant bits of R, G and B to the DAC ? – TEMLIB Mar 20 '17 at 21:43
• I have tried with both driving 4 most significant ones and having 8-bits of colour. Each time output is the same. – mega_creamery Mar 21 '17 at 9:00
• Thanks, a lot for help guys. Helped me a lot. Turns out the there was something wrong with the development board. The code worked fine on a different unit. – mega_creamery Mar 24 '17 at 12:14