-- Copyright (c) 2004 Jez smith (john@jsmith75.wanadoo.co.uk) -- All rights reservedj -- All offers of vast amounts of cash to produce your designs should be sent to -- the above -- -- -- Redistribution and use in source and synthezised forms, with or without -- modification, are permitted provided that the following conditions are met: -- -- Redistributions of source code must retain the above copyright notice, -- this list of conditions and the following disclaimer. -- -- Redistributions in synthesized form must reproduce the above copyright -- notice, this list of conditions and the following disclaimer in the -- documentation and/or other materials provided with the distribution. -- -- Neither the name of the author nor the names of other contributors may -- be used to endorse or promote products derived from this software without -- specific prior written permission. -- -- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTOR "AS IS" -- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, -- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE -- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -- POSSIBILITY OF SUCH DAMAGE. library IEEE; Use IEEE.std_logic_1164.all; entity dfft is port (d :in std_logic; clk : in std_logic; clrn :in std_logic; prn : in std_logic; q: out std_logic); end dfft; architecture rtl of dfft is begin process(clk,clrn,prn) begin if (clrn='0') then q<='0'; elsif (prn='0') then q<='1'; elsif rising_edge(clk) then q<=d; end if; end process; end rtl; library ALTERA; use ALTERA.maxplus2.all; library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_arith.all; use IEEE.std_logic_unsigned.all; library LPM; use LPM.lpm_components.ALL; entity vgacon is generic ( ramfile : string := "UNUSED" ); port( clock : in std_logic; -- 25.175 MHz board clock resetn : in std_logic; -- Active low reset line row : in std_logic_vector(5 downto 0); col : in std_logic_vector( 5 downto 0 ); colour : in std_logic_vector(2 downto 0); do_write : in std_logic; -- Write the colour to (row,col) coords hsync :out std_logic; vsync : out std_logic; -- Horz, Vert vga sync lines data_r : out std_logic; -- Red data line data_g : out std_logic; -- Green data line data_b : out std_logic; -- Blue data line done_screen : out std_logic -- Drawn One Screen ); end vgacon; architecture ComponentLevel of vgacon is component dfft port (d :in std_logic; clk : in std_logic; clrn :in std_logic; prn : in std_logic; q: out std_logic); end component; signal Reset : std_logic; signal EnableVert_din, EnableVert : std_logic; signal ResetVert_din, ResetVert : std_logic; signal CounterHoriz, CounterVert : std_logic_vector( 9 downto 0 ); signal CounterTen : std_logic_vector( 3 downto 0 ); signal EnableCol_din, EnableCol : std_logic; signal CounterCol, CounterRow : std_logic_vector( 5 downto 0 ); signal RAMreadAddress , RAMwriteAddress_din, RAMwriteAddress, RAMaddress_din, RAMaddress : std_logic_vector(11 downto 0 ); signal WriteStart : std_logic; signal WriteControl : std_logic_vector( 1 downto 0 ); signal Reading_din, Reading : std_logic; signal HorizValid_pipe1, VertValid_pipe1, ViewValid_pipe2, ViewValid_pipe3 : std_logic; signal PixelDataOut_pipe3,pixeldatain : std_logic_vector(2 downto 0); signal DataR_din,datar_din,datab_din, hsync_din, vsync_din,n_clk : std_logic; signal High : std_logic; signal Low2 : std_logic_vector( 1 downto 0 ); signal Low4 : std_logic_vector( 3 downto 0 ); --- constant C_VERT_NUM_PIXELS : integer := 480; constant C_VERT_SYNC_START : integer := 493; constant C_VERT_SYNC_END : integer := 494; constant C_VERT_TOTAL_COUNT : integer := 525; constant C_HORZ_NUM_PIXELS : integer := 640; constant C_HORZ_SYNC_START : integer := 659; constant C_HORZ_SYNC_END : integer := 755; constant C_HORZ_TOTAL_COUNT : integer := 800; begin n_clk<=not(clock); High <= '1'; Low4 <= "0000"; Low2 <= "00"; Reset <= NOT Resetn; EnableVert_din <= '1' when CounterHoriz = (C_HORZ_TOTAL_COUNT-2) else '0'; dff1: dfft PORT MAP ( d => EnableVert_din, q => EnableVert, clk => Clock, clrn => Resetn, prn => High ); ResetVert_din <= '1' when ( EnableVert_din = '1' and CounterVert= (C_VERT_TOTAL_COUNT-1) ) else '0'; dff2: dfft PORT MAP ( d => ResetVert_din , q => ResetVert , clk => Clock, clrn => Resetn, prn => High ); Horizontal: lpm_counter GENERIC MAP ( lpm_width => 10 ) PORT MAP ( clock => Clock, aclr => Reset, sclr => EnableVert, -- Reset Horiz on next line q => CounterHoriz ); Vertical: lpm_counter GENERIC MAP ( lpm_width => 10 ) PORT MAP ( clock => Clock, aclr => Reset, sclr => ResetVert, q => CounterVert, cnt_en => EnableVert ); Count10: lpm_counter GENERIC MAP ( lpm_width => 4 ) PORT MAP ( clock => Clock, aclr => Reset, sclr => EnableCol, -- Move to new column, so reset q => CounterTen ); -- ten pixel counter. EnableCol_din <= '1' when CounterTen="1000" else '0'; dff3: DFFt PORT MAP ( d => EnableCol_din, q => EnableCol, clk => Clock, clrn => Resetn, prn => High ); CountCol: lpm_counter GENERIC MAP ( lpm_width => 6 ) PORT MAP ( clock => Clock, aclr => Reset, sclr => EnableVert, -- Next line, reset col counter q => CounterCol, cnt_en => EnableCol ); CounterRow <= CounterVert(8 downto 3); -- process (Clock, Reset) begin if Reset = '1' then HorizValid_pipe1 <= '0'; VertValid_pipe1 <= '0'; ViewValid_pipe2 <= '0'; ViewValid_pipe3 <= '0'; elsif Clock'Event and Clock='1' then if CounterHoriz >= 0 and CounterHoriz < C_HORZ_NUM_PIXELS then HorizValid_pipe1 <= '1'; else HorizValid_pipe1 <= '0'; end if; if CounterVert >= 0 and CounterVert < C_VERT_NUM_PIXELS then VertValid_pipe1 <= '1'; else VertValid_pipe1 <= '0'; end if; ViewValid_pipe2 <= HorizValid_pipe1 and VertValid_pipe1; ViewValid_pipe3 <= ViewValid_pipe2; end if; end process; RAMreadAddress( 11 downto 6 ) <= CounterRow; -- upper six bits contain the row RAMreadAddress( 5 downto 0 ) <= CounterCol; -- lower six bits contain the column RAMwriteAddress_din(11 downto 6 ) <= row; RAMwriteAddress_din( 5 downto 0 ) <= col; reg1: lpm_ff GENERIC MAP ( lpm_width => 12 ) PORT MAP ( data => RAMwriteAddress_din, q => RAMwriteAddress, clock => Clock, aclr => Reset ); srg1: lpm_shiftreg GENERIC MAP ( lpm_width => 2 ) PORT MAP ( clock => Clock, data => Low2, aclr => Reset, shiftin => Do_write, q => WriteControl ); srg2: lpm_shiftreg GENERIC MAP ( lpm_width => 2 ) PORT MAP ( clock => Clock, data => Low2, aclr => Reset, shiftin => colour(0), shiftout => PixelDataIn(0)); srg3: lpm_shiftreg GENERIC MAP ( lpm_width => 2 ) PORT MAP ( clock => Clock, data => Low2, aclr => Reset, shiftin => colour(1), shiftout => PixelDataIn(1)); srg4: lpm_shiftreg GENERIC MAP ( lpm_width => 2 ) PORT MAP ( clock => Clock, data => Low2, aclr => Reset, shiftin => colour(2), shiftout => PixelDataIn(2)); VideoRam: lpm_ram_dp GENERIC MAP ( lpm_widthad => 12, -- 64x64 SuperPixel grid lpm_outdata => "REGISTERED", -- register the output lpm_indata => "REGISTERED", -- and input as well lpm_rdaddress_control => "REGISTERED", -- as add/cont lines. lpm_wraddress_control => "REGISTERED", lpm_file => "UNUSED", lpm_width => 3 ) PORT MAP ( rdaddress=>ramreadaddress, wraddress=>ramwriteaddress,rdclock=>clock,wrclock=>n_clk,rden=>high, rdclken=>high, wrclken=> high,wren=>writecontrol(1),data=>pixeldatain,q=>pixeldataout_pipe3); Datag_din <= ViewValid_pipe3 AND PixelDataOut_pipe3(0); Datar_din <= ViewValid_pipe3 AND PixelDataOut_pipe3(1); Datab_din <= ViewValid_pipe3 AND PixelDataOut_pipe3(2); dff8: dfft port map ( d => Datag_din, q => data_g, clk => Clock, clrn => Resetn, prn => High ); dff9: dfft port map ( d =>datar_din, q => data_r, clk => Clock, clrn => Resetn, prn => High ); dff10: dfft port map ( d => datab_din,q => data_b, clk => Clock, clrn => Resetn, prn => High ); hsync_din <= '0' when ( CounterHoriz >= C_HORZ_SYNC_START and CounterHoriz <= C_HORZ_SYNC_END ) else '1'; srg5: lpm_shiftreg GENERIC MAP ( lpm_width => 4 ) PORT MAP ( clock => Clock, data => Low4, aset => Reset, shiftin => hsync_din, shiftout => hsync ); vsync_din <= '0' when ( CounterVert >= C_VERT_SYNC_START and CounterVert <= C_VERT_SYNC_END ) else '1'; sr4: lpm_shiftreg GENERIC MAP ( lpm_width => 4 ) PORT MAP ( clock => Clock, data => Low4, aset => Reset, shiftin => vsync_din, shiftout => vsync ); done_screen <= ResetVert; end ComponentLevel; library IEEE; use IEEE.std_logic_1164.all; use IEEE.numeric_std.all; entity vga is port( clk : in std_logic; ---25.175 Mhz clk reset : in std_logic; addr_data : in unsigned (7 downto 0); addr_high : in unsigned (7 downto 0); write : in std_logic; ale : in std_logic; psen_n : in std_logic; rd_n : in std_logic; wr_n : in std_logic; hsync : out std_logic; vsync : out std_logic; red : out std_logic; green : out std_logic; blue : out std_logic; int_n : out std_logic ); end vga; architecture rtl of vga is type UC_STATE_TYPE is (IDLE, ADDR_DECODE,ADDR_MATCH, DATA_TRS, END_CYCLE); signal prs_state, next_state : UC_STATE_TYPE; signal colour,row,column,reg_addr : unsigned (7 downto 0); signal ale_i,psen_i,wr_i,rd_i,done_screen_i,write_i :std_logic; constant upper_addr :unsigned:=X"FF"; ---register addresses constant colour_reg :unsigned:=X"00"; constant row_reg :unsigned:=X"01"; constant col_reg :unsigned:=X"02"; component vgacon port( clock : in std_logic; resetn : in std_logic; row : in std_logic_vector(5 downto 0); col : in std_logic_vector( 5 downto 0 ); colour : in std_logic_vector(2 downto 0); do_write : in std_logic; hsync :out std_logic; vsync : out std_logic; data_r : out std_logic; data_g : out std_logic; data_b : out std_logic; done_screen : out std_logic ); end component; begin vgacon1:vgacon port map( clock=>clk, resetn=>reset, row=>std_logic_vector(row(5 downto 0)), col=> std_logic_vector(column(5 downto 0 )), colour=>std_logic_vector(colour(2 downto 0)), do_write=>write_i, hsync=>hsync, vsync=>vsync, data_r=>red, data_g=>green, data_b=>blue, done_screen=>done_screen_i); int_n<= not(done_screen_i); ---make this open drain to allow wired_or sync:process(clk) begin if rising_edge(clk) then ale_i<=ale; psen_i<=psen_n; rd_i<=rd_n; wr_i<=wr_n; write_i<=write; end if; end process; UC_REGS: process (clk) begin if rising_edge(clk) then if reset = '0' then prs_state <= IDLE; else prs_state <= next_state; end if; end if; end process; Uc_decode: process (prs_state,addr_high,addr_data) begin case prs_state is when IDLE => if ale_i='1' and psen_i = '1' then next_state <= ADDR_DECODE; end if; when ADDR_DECODE => if ale_i='0' then if (addr_high=upper_addr and (addr_data=colour_reg or addr_data=col_reg or addr_data=row_reg)) then reg_addr<=addr_data; next_state<=addr_match; else next_state <=idle; end if; end if; when ADDR_MATCH => if wr_i='0' then case reg_addr is when colour_reg=>colour<=addr_data; when col_reg=>column<=addr_data; when row_reg=>row<=addr_data; when others =>null; end case; end if; next_state<=data_trs; when DATA_TRS => if rd_i = '1' and wr_i = '1' then next_state <= END_CYCLE; end if; when END_CYCLE => if ale_i = '0' then next_state <= IDLE; end if; end case; end process; end rtl;