------------------------------------------------------------------------- -- Project: JCPU, a portable 8-bit RISC CPU written in VHDL -- This file: testbench for system test using Xilinx ML-402 -- Copyright (C) 2007 J. Ahrensfeld -- This library is free software; you can redistribute it and/or -- modify it under the terms of the GNU Lesser General Public -- License as published by the Free Software Foundation; either -- version 2.1 of the License, or (at your option) any later version. -- This library is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -- Lesser General Public License for more details. -- You should have received a copy of the GNU Lesser General Public -- License along with this library; if not, write to the Free Software -- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -- For questions and ideas, please contact the author at jens@jayfield.org ----------------------------------------------------------------------- LIBRARY ieee; use IEEE.STD_LOGIC_1164.ALL; USE ieee.numeric_std.ALL; use work.vga_types.all; ENTITY tb_vga_frontend64 IS END tb_vga_frontend64; ARCHITECTURE behavior OF tb_vga_frontend64 IS constant tsvga : vga_timespec_t := ts_vga_testbench; constant CLK_PERIOD : time := 10 ns; constant VGA_CLK_PERIOD : time := (integer(1E9) / tsvga.f_pxl_clk) * 1 ns; signal CLK_O : std_logic := '1'; signal RST_O : std_logic := '1'; -- Master signal INT_O : std_logic; signal CYC_O : std_logic; signal STB_O : std_logic; signal WE_O : std_logic; signal SEL_O : unsigned(3 downto 0) := (others => '1'); signal ACK_I : std_logic := '0'; signal MRDY_O : std_logic := '1'; signal SRDY_I : std_logic := '0'; signal ADDR_O : unsigned(31 downto 0) := (others => '-'); signal MDAT_I : unsigned(63 downto 0) := (others => '-'); signal MDAT_O : unsigned(63 downto 0) := (others => '-'); -- Slave signal CYC_I : std_logic := '0'; signal STB_I : std_logic := '0'; signal WE_I : std_logic := '0'; signal SEL_I : unsigned(7 downto 0); signal ACK_O : std_logic; signal MRDY_I : std_logic; signal SRDY_O : std_logic; signal ADDR_I : unsigned(31 downto 0) := (others => '-'); signal SDAT_I : unsigned(31 downto 0) := (others => '-'); signal SDAT_O : unsigned(31 downto 0) := (others => '-'); signal rdy : std_logic := '0'; signal read_reg : unsigned(31 downto 0) := (others => '-'); -- VGA signals signal vga_clk : std_logic := '1'; signal vga_red : unsigned(7 downto 0); signal vga_green : unsigned(7 downto 0); signal vga_blue : unsigned(7 downto 0); signal vga_blank_n : std_logic; signal vga_sync_n : std_logic; signal vga_hsync : std_logic; signal vga_vsync : std_logic; signal vga_en : std_logic; BEGIN inst_vga_frontend64 : entity work.vga_frontend64 GENERIC MAP ( fifo_depth => 2048, fifo_almost_full_thresh => 2048-128, fifo_almost_empty_thresh => 512, tsvga => tsvga ) PORT MAP ( -- System signals RST_I => RST_O, CLK_I => CLK_O, -- JBUS Master signals CYC_O => CYC_I, STB_O => STB_I, WE_O => WE_I, SEL_O => SEL_I, ACK_I => ACK_O, SRDY_I => SRDY_O, MRDY_O => MRDY_I, ADDR_O => ADDR_I, MDAT_I => MDAT_O, MDAT_O => MDAT_I, -- JBUS Slave signals INT_O => INT_O, CYC_I => CYC_O, STB_I => STB_O, WE_I => WE_O, SEL_I => SEL_O, ACK_O => ACK_I, SRDY_O => SRDY_I, MRDY_I => MRDY_O, ADDR_I => ADDR_O, SDAT_I => SDAT_O, SDAT_O => SDAT_I, -- VGA signals vga_clk_in => vga_clk, vga_clk_ce => vga_en, vga_red => vga_red, vga_green => vga_green, vga_blue => vga_blue, vga_blank_n => vga_blank_n, vga_sync_n => vga_sync_n, vga_hsync => vga_hsync, vga_vsync => vga_vsync ); vga_en <= not RST_O; rdy_GEN: process begin wait for 3*CLK_PERIOD/2; wait until rising_edge(CLK_O); rdy <= not rdy; end process; CLK_GEN: process begin wait for CLK_PERIOD/2; CLK_O <= not CLK_O; end process; VGA_CLK_GEN: process begin wait for VGA_CLK_PERIOD/2; vga_clk <= not vga_clk after 3 ns; end process; -- Slave SRDY_O <= CYC_I and rdy; process(CLK_O) variable ack_v : unsigned(11 downto 0); type arr64_t is array (11 downto 0) of unsigned(63 downto 0); variable dat_v : arr64_t; variable res: unsigned(63 downto 0); variable scan_count: unsigned(31 downto 0); variable blit_count: unsigned(31 downto 0); begin if rising_edge(CLK_O) then if RST_O = '1' then scan_count := X"00000000"; blit_count := X"00000000"; for i in 0 to 11 loop dat_v(i) := X"FFFFFFFF_FFFFFFFF"; ack_v(i) := '0'; end loop; else if (CYC_I and STB_I) = '1' and rdy = '1' and WE_I = '0' then if ADDR_I(24) = '0' then res := ADDR_I & scan_count; scan_count := scan_count + 8; else res := ADDR_I & blit_count; blit_count := blit_count + 8; end if; dat_v := dat_v(10 downto 0) & res; ack_v := ack_v(10 downto 0) & '1'; else dat_v := dat_v(10 downto 0) & X"FFFFFFFF_FFFFFFFF"; ack_v := ack_v(10 downto 0) & '0'; end if; MDAT_O <= dat_v(dat_v'left); ACK_O <= ack_v(ack_v'left); end if; end if; end process; process(CLK_O) begin if rising_edge(CLK_O) then if RST_O = '1' then read_reg <= X"00000000"; elsif ACK_I = '1' then read_reg <= SDAT_I; end if; end if; end process; -- Master STIMULUS: process begin wait for 6*CLK_PERIOD; RST_O <= '0'; wait for 60*CLK_PERIOD; -- Enable master CYC_O <= '1'; wait until rising_edge(CLK_O) and SRDY_I = '1'; STB_O <= '1'; WE_O <= '1'; SDAT_O <= X"0000_0002"; ADDR_O <= X"0000_0000"; wait until rising_edge(CLK_O) and SRDY_I = '1'; STB_O <= '0'; -- Read status CYC_O <= '1'; wait until rising_edge(CLK_O) and SRDY_I = '1'; STB_O <= '1'; WE_O <= '0'; ADDR_O <= X"0000_0000"; wait until rising_edge(CLK_O) and SRDY_I = '1'; STB_O <= '0'; -- Read resolution CYC_O <= '1'; wait until rising_edge(CLK_O) and SRDY_I = '1'; STB_O <= '1'; WE_O <= '0'; ADDR_O <= X"0000_0014"; wait until rising_edge(CLK_O) and SRDY_I = '1'; STB_O <= '0'; -- Read Cursor X CYC_O <= '1'; wait until rising_edge(CLK_O) and SRDY_I = '1'; STB_O <= '1'; WE_O <= '0'; ADDR_O <= X"0000_0008"; wait until rising_edge(CLK_O) and SRDY_I = '1'; STB_O <= '0'; -- Read Cursor Y CYC_O <= '1'; wait until rising_edge(CLK_O) and SRDY_I = '1'; STB_O <= '1'; WE_O <= '0'; ADDR_O <= X"0000_000C"; wait until rising_edge(CLK_O) and SRDY_I = '1'; STB_O <= '0'; -- Write char 1 wait until rising_edge(CLK_O) and SRDY_I = '1'; STB_O <= '1'; WE_O <= '1'; SDAT_O <= X"0000_0035"; ADDR_O <= X"0000_0004"; wait until rising_edge(CLK_O) and SRDY_I = '1'; STB_O <= '0'; -- Read char 1 wait until rising_edge(CLK_O) and SRDY_I = '1'; STB_O <= '1'; WE_O <= '0'; ADDR_O <= X"0000_0004"; wait until rising_edge(CLK_O) and SRDY_I = '1'; STB_O <= '0'; -- Write char 2 wait until rising_edge(CLK_O) and SRDY_I = '1'; STB_O <= '1'; WE_O <= '1'; SDAT_O <= X"0000_0045"; ADDR_O <= X"0000_0004"; wait until rising_edge(CLK_O) and SRDY_I = '1'; STB_O <= '0'; -- Read char 2 wait until rising_edge(CLK_O) and SRDY_I = '1'; STB_O <= '1'; WE_O <= '0'; ADDR_O <= X"0000_0004"; wait until rising_edge(CLK_O) and SRDY_I = '1'; STB_O <= '0'; -- Read Cursor X CYC_O <= '1'; wait until rising_edge(CLK_O) and SRDY_I = '1'; STB_O <= '1'; WE_O <= '0'; ADDR_O <= X"0000_0008"; wait until rising_edge(CLK_O) and SRDY_I = '1'; STB_O <= '0'; -- Read Cursor Y CYC_O <= '1'; wait until rising_edge(CLK_O) and SRDY_I = '1'; STB_O <= '1'; WE_O <= '0'; ADDR_O <= X"0000_000C"; wait until rising_edge(CLK_O) and SRDY_I = '1'; STB_O <= '0'; -- Set Cursor X wait until rising_edge(CLK_O) and SRDY_I = '1'; STB_O <= '1'; WE_O <= '1'; SDAT_O <= X"0000_0012"; ADDR_O <= X"0000_0008"; wait until rising_edge(CLK_O) and SRDY_I = '1'; STB_O <= '0'; -- Set Cursor Y wait until rising_edge(CLK_O) and SRDY_I = '1'; STB_O <= '1'; WE_O <= '1'; SDAT_O <= X"0000_0014"; ADDR_O <= X"0000_000C"; wait until rising_edge(CLK_O) and SRDY_I = '1'; STB_O <= '0'; -- Read Cursor X CYC_O <= '1'; wait until rising_edge(CLK_O) and SRDY_I = '1'; STB_O <= '1'; WE_O <= '0'; ADDR_O <= X"0000_0008"; wait until rising_edge(CLK_O) and SRDY_I = '1'; STB_O <= '0'; -- Read Cursor Y CYC_O <= '1'; wait until rising_edge(CLK_O) and SRDY_I = '1'; STB_O <= '1'; WE_O <= '0'; ADDR_O <= X"0000_000C"; wait until rising_edge(CLK_O) and SRDY_I = '1'; STB_O <= '0'; wait until rising_edge(CLK_O); CYC_O <= '0'; wait for 60000*CLK_PERIOD; for i in 0 to 99 loop -- BLIT test -- Read status CYC_O <= '1'; wait until rising_edge(CLK_O) and SRDY_I = '1'; STB_O <= '1'; WE_O <= '0'; ADDR_O <= X"0000_0000"; wait until rising_edge(CLK_O) and SRDY_I = '1'; STB_O <= '0'; wait until rising_edge(CLK_O) and ACK_I = '1'; -- set src addr first CYC_O <= '1'; wait until rising_edge(CLK_O) and SRDY_I = '1'; STB_O <= '1'; WE_O <= '1'; SDAT_O <= X"4100_0000"; ADDR_O <= X"0000_0020"; wait until rising_edge(CLK_O) and SRDY_I = '1'; STB_O <= '0'; -- set src addr last CYC_O <= '1'; wait until rising_edge(CLK_O) and SRDY_I = '1'; STB_O <= '1'; WE_O <= '1'; SDAT_O <= X"4100_0000" + to_unsigned(4*(80*4-1), 32); ADDR_O <= X"0000_0024"; wait until rising_edge(CLK_O) and SRDY_I = '1'; STB_O <= '0'; -- set src dim-x CYC_O <= '1'; wait until rising_edge(CLK_O) and SRDY_I = '1'; STB_O <= '1'; WE_O <= '1'; SDAT_O <= to_unsigned(4*80, 32); ADDR_O <= X"0000_0028"; wait until rising_edge(CLK_O) and SRDY_I = '1'; STB_O <= '0'; -- set dst addr first CYC_O <= '1'; wait until rising_edge(CLK_O) and SRDY_I = '1'; STB_O <= '1'; WE_O <= '1'; SDAT_O <= X"4200_0000"; ADDR_O <= X"0000_0050"; wait until rising_edge(CLK_O) and SRDY_I = '1'; STB_O <= '0'; -- set dst addr last CYC_O <= '1'; wait until rising_edge(CLK_O) and SRDY_I = '1'; STB_O <= '1'; WE_O <= '1'; SDAT_O <= X"4200_0000" + to_unsigned(4*(80*4-1), 32); ADDR_O <= X"0000_0054"; wait until rising_edge(CLK_O) and SRDY_I = '1'; STB_O <= '0'; -- set dst dim-x CYC_O <= '1'; wait until rising_edge(CLK_O) and SRDY_I = '1'; STB_O <= '1'; WE_O <= '1'; SDAT_O <= to_unsigned(4*80, 32); ADDR_O <= X"0000_0058"; wait until rising_edge(CLK_O) and SRDY_I = '1'; STB_O <= '0'; -- set nx CYC_O <= '1'; wait until rising_edge(CLK_O) and SRDY_I = '1'; STB_O <= '1'; WE_O <= '1'; SDAT_O <= to_unsigned(80-1, 32); ADDR_O <= X"0000_0060"; wait until rising_edge(CLK_O) and SRDY_I = '1'; STB_O <= '0'; -- set ny CYC_O <= '1'; wait until rising_edge(CLK_O) and SRDY_I = '1'; STB_O <= '1'; WE_O <= '1'; SDAT_O <= X"0000_0003"; ADDR_O <= X"0000_0064"; wait until rising_edge(CLK_O) and SRDY_I = '1'; STB_O <= '0'; -- set blit request CYC_O <= '1'; wait until rising_edge(CLK_O) and SRDY_I = '1'; STB_O <= '1'; WE_O <= '1'; SDAT_O <= read_reg or X"0000_0100"; ADDR_O <= X"0000_0000"; wait until rising_edge(CLK_O) and SRDY_I = '1'; STB_O <= '0'; CYC_O <= '0'; WE_O <= '0'; wait for 100000*CLK_PERIOD; end loop; wait; end process; END;