I think I don't have to setup the IIC bus, the default values of the AD9980 look fine to me.
However about the timing diagrams of the AD9980, in 4:4:4 timing mode (see page 19 of the datasheet of the AD9980 :
https://www.xilinx.com/products/boards/ml505/datasheets/464471350AD9980_0.pdf) there is some kind of delay between the HS_in and HS_out, and between the DATA_in and DATA_out. I don't really know how to take this into account. Does this delay occur every new pixel-line, or only at the first line of a frame --> the 6 clock cycles delay between HS_out and DATA_out remains constant for the whole frame?
Does this delay occur for the vertical synchronisation aswell?
Thanks in advance,
Simon
- - - Updated - - -
Here is the VHDL code of the design I made, it's very basic, but still won't work. The resolution I use is 800 x 600 @ 75 Hz.
It should take a pixel somewhere in the middle of a frame, in the middle of a pixelline, and store the value of blue [7 downto 0] in the 8 LED's.
When I program this in the FPGA, I expect the same LED's on '1' the whole time when I use the same screen as input. However the LED's change the whole time. This is probably because the VGA input signal of an image on the screen is not in 1 color. But still, it should take the same pixel every time so the LED's should not change.
There should be something wrong with the timing, but according to the testbench, it should work...
Here is a screenshot of the waveform result I get from the testbench. http://i.imgur.com/QVGAq.jpg
This is the VHDL code for the design, the testbench code is below.
Could someone help me with this?
Thanks in advance,
Simon
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- Virtex 5 ml507
-- Using the AD9980 8 bit display interface
entity circuit1 is
port(
reset : in std_logic; -- active high
data_clk : in std_logic; -- data clock aligned with hs and green, red, blue
hs : in std_logic; -- has delay of 2 clock cycles
vs : in std_logic;
--green : in std_logic_vector(0 to 7); not used
--red : in std_logic_vector(0 to 7); not used
blue : in std_logic_vector(0 to 7);
led : out std_logic_vector(0 to 7)
);
end circuit1;
architecture Behavioral of circuit1 is
signal starter : std_logic := '0';
signal pixelcount : integer range 0 to 1055 := 0;
signal linecount : integer range 0 to 624 := 0;
constant maxpixelcount : integer := 1055;
constant maxlinecount : integer := 624;
signal verticalsynchcounter : integer := 0;
begin
-- startup process, only start when you reach a full vertical synchronisation signal, this is protection against starting in middle of line or frame
process(vs, reset, data_clk) -- because we need to find the start of the frame first.
begin
if reset = '0' then
starter <= '0';
else
if rising_edge(data_clk) and vs = '1' then
if verticalsynchcounter < 3167 then
verticalsynchcounter <= verticalsynchcounter + 1;
elsif verticalsynchcounter = 3167 then
verticalsynchcounter <= 0;
starter <= '1';
end if;
end if;
end if;
end process;
process(data_clk, starter, reset)
begin
if reset = '0' then
pixelcount <= 0;
linecount <= 0;
else
if starter = '0' then
pixelcount <= 0;
linecount <= 0;
else
if rising_edge(data_clk) and starter = '1' then
if pixelcount < maxpixelcount then
pixelcount <= pixelcount + 1;
else -- when row is complete
pixelcount <= 0;
if linecount < maxlinecount then
linecount <= linecount + 1;
else -- when frame is complete
linecount <= 0;
end if;
end if;
end if;
end if;
end if;
end process;
process(pixelcount, blue, reset, linecount)
begin
if reset = '0' then
led <= "00000000";
else
if linecount = 300 and pixelcount = 500 then -- take a pixel somewhere in the middle of a line, in the middle of a frame
led <= blue ; -- ask the data in blue in that pixel
end if;
end if;
end process;
end Behavioral;
This is the testbench code I made,
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL; -- nodig om alle getallen arith te maken,
use IEEE.STD_LOGIC_UNSIGNED.ALL; -- alles unsigned, geen negatieve getallen dus
ENTITY tester IS
END tester;
ARCHITECTURE behavior OF tester IS
COMPONENT circuit1
PORT(
reset : IN std_logic;
data_clk : IN std_logic;
vs : IN std_logic;
hs : IN std_logic;
blue : IN std_logic_vector(0 to 7);
led : OUT std_logic_vector(0 to 7)
);
END COMPONENT;
signal reset : std_logic := '0';
signal data_clk : std_logic := '0';
signal vs : std_logic := '0';
signal hs : std_logic := '0';
signal blue : std_logic_vector(0 to 7) := (others => '0');
signal led : std_logic_vector(0 to 7);
signal consta : std_logic_vector(0 to 7) := "00000000";
constant data_clk_period : time := 20.202020 ns;
BEGIN
uut: circuit1 PORT MAP (
reset => reset,
data_clk => data_clk,
vs => vs,
hs => hs,
blue => blue,
led => led
);
-- Clock process definitions
data_clk_process rocess
begin
data_clk <= '0';
wait for data_clk_period/2;
data_clk <= '1';
wait for data_clk_period/2;
end process;
-- Stimulus process
stim_proc: process
begin
reset <= '1'; -- zonder verticale synchronisatie
vs <= '0';
for i in 1 to 625 loop
hs <= '1';
wait for 1.6161616161 us; --
hs <= '0';
wait for 3.35353535 us; -- because of delay of the AD9980, was 3.232323 us
consta <= consta +1;
blue <= consta;
wait for 16.1616161616 us;
blue <= "00000000";
wait for 0.20202020 us; -- because of delay of the AD9980, was 0.32323232 us
end loop;
wait for 0.02133333333 ms;
for j in 1 to 1000 loop -- 1000 frames
consta <= "00000000";
vs <= '1';
wait for 0.064 ms;
vs <= '0';
wait for 0.448 ms;
hs <= '1';
wait for 1.6161616161 us;
hs <= '0';
wait for 3.35353535 us;
consta <= "00000001";
blue <= consta;
wait for 16.161616166 us;
wait for 0.20202020 us;
for i in 2 to 600 loop
hs <= '1';
wait for 1.616161616161 us;
hs <= '0';
wait for 3.35353535 us;
consta <= consta +1;
blue <= consta;
wait for 16.161616161616 us;
wait for 0.20202020 us;
end loop;
consta <= "00000000";
wait for 0.02133333333 ms;
end loop;
end process;
END;