library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; -- Uncomment the following lines to use the declarations that are -- provided for instantiating Xilinx primitive components. library UNISIM; use UNISIM.VComponents.all; entity clktest is Port ( clk50in : in std_logic; clk40in : in std_logic; --40MHZ TFT clock pb_in : in std_logic_vector(3 downto 0); -- 4 pushbutton inputs led_out : out std_logic_vector(7 downto 0); -- 8 LEDs clk40out : buffer std_logic; --TFT clock hsync,vsync,den : out std_logic; --TFT sync signals red5,green5,blue5 : out std_logic; -- TFT colour MSbits grey : out std_logic_vector(4 downto 0); -- TFT R.G and B bits 0..4 sw_in : in std_logic_vector(7 downto 0); -- S3 board switches debugout:out std_logic_vector(9 downto 0); --debug outputs clkout,dllclkout:buffer std_logic); end clktest; architecture arch1 of clktest is constant white: std_logic_vector(7 downto 0) :="11111111"; constant black: std_logic_vector(7 downto 0) :="00000000"; constant green: std_logic_vector(7 downto 0) :="01011111"; constant red: std_logic_vector(7 downto 0) :="10011111"; constant blue: std_logic_vector(7 downto 0) :="00111111"; constant cyan: std_logic_vector(7 downto 0) :="01111111"; constant magenta: std_logic_vector(7 downto 0) :="10111111"; constant yellow: std_logic_vector(7 downto 0) :="11011111"; COMPONENT dcmtest PORT( CLKIN_IN : IN std_logic; PSCLK_IN : IN std_logic; PSEN_IN : IN std_logic; PSINCDEC_IN : IN std_logic; RST_IN : IN std_logic; CLKIN_IBUFG_OUT : OUT std_logic; CLK0_OUT : OUT std_logic; LOCKED_OUT : OUT std_logic; PSDONE_OUT : OUT std_logic ); END COMPONENT; signal xcounter :std_logic_vector(9 downto 0); -- x LCD pixel counter signal ycounter : std_logic_vector(9 downto 0); -- y LCD line counter signal rst : std_logic; --reset (for DCM) signal pb:std_logic_vector(3 downto 0); -- S3 board pushbuttons signal rand:std_logic_vector(31 downto 0); -- random-number register for noise display signal fr,frame,ln,line:std_logic; -- end-of-line and frame flags signal dispadr_x,dispadr_y:std_logic_vector(7 downto 0); --display address within display area, pixels triplicated signal mod3count_x,mod3count_y:std_logic_vector(2 downto 0); --ring counters to triple pixels signal clk40,clk40op:std_logic; signal psclk:std_logic; signal pscnt:std_logic_vector(2 downto 0); -- used for DCM phase adjust via pushbuttons signal colour:std_logic_vector(7 downto 0); --TFT composite colour byte alias gy:std_logic_vector(4 downto 0) is colour(4 downto 0); alias rgb:std_logic_vector(2 downto 0) is colour(7 downto 5); begin rst<=pb_in(0); red5<=colour(7); -- copy TFT data value green5<=colour(6); blue5<=colour(5); grey<=gy; Inst_dcmtest: dcmtest PORT MAP( --DCM using buttons to fine-adjust clock phase CLKIN_IN => clk40in, PSCLK_IN => psclk, PSEN_IN =>pb_in(3) , PSINCDEC_IN => pb_in(1), RST_IN => rst, CLKIN_IBUFG_OUT => clk40op, CLK0_OUT => clk40, LOCKED_OUT => open, PSDONE_OUT => open ); clk40out<=clk40op; process(clk40,frame) -- slow counter for DCM phase fine-adjust begin if rising_edge(clk40) and frame='1' then pscnt<=pscnt+1; if pscnt=0 then psclk<='1'; else psclk<='0'; end if; end if; end process; process(clk40op,clkout) -- debug clocks for phase measurement begin if rising_edge(clk40op) then if rst='1' then clkout<='0'; else clkout<=clkout xor '1'; end if; end if; end process; process(clk40,dllclkout) begin if rising_edge(clk40) then if rst='1' then dllclkout<='0'; else dllclkout<=dllclkout xor '1'; end if; end if; end process; process(xcounter,clk40,ycounter,sw_in,rand) begin --clk40out<=clk40in; if rising_edge(clk40) then if rst='1' then rand<="10101010101010101010101010101010"; else -- random sequence generator for noise display rand<=( (rand(0) xor rand(26) xor rand(27) xor rand(31))& rand(31 downto 1)); end if; xcounter <= xcounter+1; -- x pixel counter if sw_in(7)='1' then debugout<=xcounter; else debugout<=ycounter;end if; if line='1' then -- end of line, reset x mod3 counter, inc y counter mod3count_x<="100"; dispadr_x<="00000000"; mod3count_y<=(mod3count_y(0) & mod3count_y(2) & mod3count_y(1)); -- rotate if mod3count_y(0)='1' then dispadr_y<=dispadr_y+1;end if; end if; if ycounter=1 then mod3count_y<="001";dispadr_y<="11111111"; end if; -- reset y addr at start of disp area -------------------------------------------------------------------- display areas if ycounter>1 and ycounter<578 and xcounter>1 and xcounter<722 then -- main image area case sw_in(2 downto 0) is -- different patterns depending on switches when "000"=> --if rand(2)='1' then colour<="11111111"; else colour<="00000000";end if; if rand(0)='1' then colour<=white; else colour <= black; end if; when "001"=> colour(4 downto 0)<=dispadr_x(6 downto 2); colour(7 downto 5) <=dispadr_y(6 downto 4); when "010"=> colour(4 downto 0)<=dispadr_x(6 downto 2); colour(7)<=dispadr_x(7); colour(6)<=dispadr_x(7); colour(5)<=dispadr_x(7); when "011" => if xcounter(0)='1' then colour<=white; else colour<=black;end if; when others => colour<=black; end case; mod3count_x<=(mod3count_x(0) & mod3count_x(2) & mod3count_x(1)); -- rotate if mod3count_x(0)='1' then dispadr_x<=dispadr_x+1;end if; -- inc x addr every 3 x pixels elsif (ycounter<580 and xcounter<724) then -------------------------- image border colour<=green; elsif ycounter>583 then ----------------------------------------------bottom status line if xcounter(3 downto 1)=7 then colour<=black; else colour<=cyan;end if; elsif xcounter>733 and ycounter<576 ------------------------------------- right text area and ycounter(3 downto 1)/=7 and xcounter(3 downto 1)/=7 then -- 8x8 blocks colour<=yellow; else colour<=black; end if;--display area end if; --clock edge end process; process(xcounter,ycounter,clk40) -- generate TFT sync and DEN signals -- x/y counters phased so 0,0 = top-left displayed pixel begin if rising_edge(clk40) then fr<='0'; ln<='0'; if xcounter= 0 and ycounter <600 then den<='1';end if; if xcounter= 800 then den<='0';end if; if xcounter=900 then line<='1';hsync<='0'; else line<='0';end if; if xcounter =980 then hsync<='1';end if; if xcounter=1023 then ln<='1'; if ycounter=616 then vsync<='1'; fr<='1'; end if; if ycounter=624 then vsync<='0'; end if; if ycounter=632 then ycounter<="0000000000"; else ycounter<=ycounter+1; end if; end if; end if; frame<=fr;line<=ln; end process; end arch1;