------------------------------------------------------------------------- -- 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.package_utility.all; Library UNISIM; use UNISIM.vcomponents.all; ENTITY tb_ssram_frontend_wb IS END tb_ssram_frontend_wb; ARCHITECTURE behavior OF tb_ssram_frontend_wb IS constant CLK_PERIOD : time := 10 ns; signal CLK_O : std_logic := '1'; signal RST_O : std_logic := '1'; signal CYC_O : std_logic := '0'; signal STB_O : std_logic := '0'; signal WE_O : std_logic := '0'; signal SEL_O : unsigned(3 downto 0) := (others => '1'); signal ACK_I : std_logic; signal MRDY_O : std_logic := '1'; signal SRDY_I : std_logic; signal ADDR_O : unsigned(31 downto 0) := (others => '-'); signal DAT_I : unsigned(31 downto 0); signal DAT_O : unsigned(31 downto 0) := (others => '-'); SIGNAL ssram_d : unsigned (32 - 1 DOWNTO 0) := (OTHERS => 'Z'); SIGNAL ssram_dp : unsigned (4 - 1 DOWNTO 0) := (OTHERS => 'Z'); SIGNAL ssram_a : unsigned (20 - 1 DOWNTO 0) := (OTHERS => '0'); SIGNAL ssram_clk : STD_LOGIC := '0'; SIGNAL ssram_cke_n : STD_LOGIC; SIGNAL ssram_adv : STD_LOGIC; SIGNAL ssram_mode : STD_LOGIC; SIGNAL ssram_bw_n : unsigned(3 downto 0); SIGNAL ssram_we_n : STD_LOGIC; SIGNAL ssram_oe_n : STD_LOGIC; SIGNAL ssram_ce_n : STD_LOGIC; SIGNAL ssram_zz : STD_LOGIC; SIGNAL ssram_clk_fb : STD_LOGIC; signal dout_rst : std_logic := '0'; signal dout_reg : unsigned(31 downto 0); signal dout_cnt : natural range 0 to 255; BEGIN ssram_clk_fb <= ssram_clk after 0.5 ns; inst_ssram_frontend_wb : entity work.ssram_frontend_wb GENERIC MAP ( addr_width => 20, data_width => 32, parity_width => 4 ) PORT MAP ( -- J-Bus domain RST_I => RST_O, CLK_I => CLK_O, CYC_I => CYC_O, STB_I => STB_O, SEL_I => SEL_O, WE_I => WE_O, ACK_O => ACK_I, SRDY_O => SRDY_I, MRDY_I => MRDY_O, ADDR_I => ADDR_O, DAT_I => DAT_O, DAT_O => DAT_I, -- Sync SRAM domain ssram_clk_o => ssram_clk, ssram_clk_fb => ssram_clk_fb, ssram_cke_n => ssram_cke_n, ssram_ce_n => ssram_ce_n, ssram_oe_n => ssram_oe_n, ssram_we_n => ssram_we_n, ssram_adv => ssram_adv, ssram_mode => ssram_mode, ssram_zz => ssram_zz, ssram_a => ssram_a, ssram_d => ssram_d, ssram_dp => ssram_dp, ssram_bw_n => ssram_bw_n ); inst_ssram : entity work.cy7c1354 -- PORT MAP Declarations PORT MAP ( Dq => STD_LOGIC_VECTOR(ssram_d), -- Data I/O Dpq => STD_LOGIC_VECTOR(ssram_dp), -- Data I/O Addr => STD_LOGIC_VECTOR(ssram_a(19 downto 2)), -- Address Mode => ssram_mode, -- Burst Mode Clk => ssram_clk, -- Clk CEN_n => ssram_cke_n, -- CEN# AdvLd_n => ssram_adv, -- Adv/Ld# Bwa_n => ssram_bw_n(0), -- Bwa# Bwb_n => ssram_bw_n(1), -- BWb# Bwc_n => ssram_bw_n(2), -- Bwc# Bwd_n => ssram_bw_n(3), -- BWd# Rw_n => ssram_we_n, -- RW# Oe_n => ssram_oe_n, -- OE# Ce1_n => ssram_ce_n, -- CE1# Ce2 => '1', -- CE2 Ce3_n => '0', -- CE3# Zz => ssram_zz ); read_register: process(CLK_O) begin if rising_edge(CLK_O) then if dout_rst = '1' then dout_cnt <= 0; elsif ACK_I = '1' and WE_O = '0' then dout_reg <= DAT_I; dout_cnt <= dout_cnt + 1; end if; end if; end process; CLK_GEN: process begin wait for CLK_PERIOD/2; CLK_O <= not CLK_O; end process; STIMULUS: process begin wait for 5*CLK_PERIOD; RST_O <= '0'; wait until rising_edge(CLK_O); -- 8 single cycles CYC_O <= '1'; STB_O <= '1'; WE_O <= '1'; DAT_O <= X"1234_0000"; ADDR_O <= X"0000_0000"; for i in 0 to 31 loop wait until rising_edge(CLK_O) and SRDY_I = '1'; DAT_O <= DAT_O + 1; ADDR_O <= ADDR_O + 4; end loop; STB_O <= '0'; wait until rising_edge(CLK_O); CYC_O <= '0'; ------------------------------------------------------------ wait for 3*CLK_PERIOD; ------------------------------------------------------------ -- 8-word burst cycle dout_rst <= '1'; wait until rising_edge(CLK_O); dout_rst <= '0'; CYC_O <= '1'; STB_O <= '1'; WE_O <= '0'; ADDR_O <= X"0000_0000"; for i in 0 to 31 loop wait until rising_edge(CLK_O) and SRDY_I = '1'; ADDR_O <= ADDR_O + 4; end loop; STB_O <= '0'; wait until rising_edge(CLK_O) and dout_cnt = 31; CYC_O <= '0'; ------------------------------------------------------------ wait for 3*CLK_PERIOD; ------------------------------------------------------------ wait until rising_edge(CLK_O); -- 1-word burst cycle CYC_O <= '1'; STB_O <= '1'; WE_O <= '1'; SEL_O <= "0011"; ADDR_O <= X"0000_0010"; DAT_O <= X"DEADBEEF"; wait until rising_edge(CLK_O) and SRDY_I = '1'; STB_O <= '0'; wait until rising_edge(CLK_O); CYC_O <= '0'; ------------------------------------------------------------ wait for 3*CLK_PERIOD; ------------------------------------------------------------ wait until rising_edge(CLK_O); -- 1-word burst cycle CYC_O <= '1'; STB_O <= '1'; WE_O <= '0'; ADDR_O <= X"0000_0010"; wait until rising_edge(CLK_O) and SRDY_I = '1'; STB_O <= '0'; wait until rising_edge(CLK_O) and ACK_I = '1'; CYC_O <= '0'; ------------------------------------------------------------ wait for 3*CLK_PERIOD; ------------------------------------------------------------ -- 8-word burst cycle dout_rst <= '1'; wait until rising_edge(CLK_O); dout_rst <= '0'; CYC_O <= '1'; STB_O <= '1'; WE_O <= '0'; ADDR_O <= X"0000_0000"; for i in 0 to 31 loop wait until rising_edge(CLK_O) and SRDY_I = '1'; ADDR_O <= ADDR_O + 4; end loop; STB_O <= '0'; wait until rising_edge(CLK_O) and dout_cnt = 31; CYC_O <= '0'; ------------------------------------------------------------ wait for 10*CLK_PERIOD; ------------------------------------------------------------ -- 8-word burst cycle dout_rst <= '1'; wait until rising_edge(CLK_O); dout_rst <= '0'; CYC_O <= '1'; STB_O <= '1'; WE_O <= '0'; ADDR_O <= X"0000_0000"; for i in 0 to 7 loop wait until rising_edge(CLK_O) and SRDY_I = '1'; ADDR_O <= ADDR_O + 4; end loop; STB_O <= '0'; wait until rising_edge(CLK_O) and dout_cnt = 7; CYC_O <= '0'; ------------------------------------------------------------ wait for 10*CLK_PERIOD; ------------------------------------------------------------ -- 8-word burst cycle dout_rst <= '1'; wait until rising_edge(CLK_O); dout_rst <= '0'; CYC_O <= '1'; STB_O <= '1'; WE_O <= '1'; SEL_O <= "1111"; DAT_O <= X"1111_0000"; ADDR_O <= X"0000_0000"; for i in 0 to 7 loop wait until rising_edge(CLK_O) and SRDY_I = '1'; DAT_O <= DAT_O + 1; ADDR_O <= ADDR_O + 4; end loop; WE_O <= '0'; ADDR_O <= X"0000_0000"; for i in 0 to 7 loop wait until rising_edge(CLK_O) and SRDY_I = '1'; ADDR_O <= ADDR_O + 4; end loop; STB_O <= '0'; wait until rising_edge(CLK_O) and dout_cnt = 7; CYC_O <= '0'; -- 8-word burst cycle dout_rst <= '1'; wait until rising_edge(CLK_O); dout_rst <= '0'; CYC_O <= '1'; STB_O <= '1'; WE_O <= '1'; SEL_O <= "1111"; DAT_O <= X"2222_0000"; ADDR_O <= X"0000_0400"; for i in 0 to 7 loop wait until rising_edge(CLK_O) and SRDY_I = '1'; DAT_O <= DAT_O + 1; ADDR_O <= ADDR_O + 4; end loop; WE_O <= '0'; ADDR_O <= X"0000_0400"; for i in 0 to 7 loop wait until rising_edge(CLK_O) and SRDY_I = '1'; ADDR_O <= ADDR_O + 4; end loop; STB_O <= '0'; wait until rising_edge(CLK_O) and dout_cnt = 7; CYC_O <= '0'; -- 8-word burst cycle dout_rst <= '1'; wait until rising_edge(CLK_O); dout_rst <= '0'; CYC_O <= '1'; STB_O <= '1'; WE_O <= '1'; SEL_O <= "1111"; DAT_O <= X"3333_0000"; ADDR_O <= X"0000_0800"; for i in 0 to 7 loop wait until rising_edge(CLK_O) and SRDY_I = '1'; DAT_O <= DAT_O + 1; ADDR_O <= ADDR_O + 4; end loop; WE_O <= '0'; ADDR_O <= X"0000_0800"; for i in 0 to 7 loop wait until rising_edge(CLK_O) and SRDY_I = '1'; ADDR_O <= ADDR_O + 4; end loop; STB_O <= '0'; wait until rising_edge(CLK_O) and dout_cnt = 7; CYC_O <= '0'; -- 8-word burst cycle dout_rst <= '1'; wait until rising_edge(CLK_O); dout_rst <= '0'; CYC_O <= '1'; STB_O <= '1'; WE_O <= '1'; SEL_O <= "1111"; DAT_O <= X"4444_0000"; ADDR_O <= X"0000_0C00"; for i in 0 to 7 loop wait until rising_edge(CLK_O) and SRDY_I = '1'; DAT_O <= DAT_O + 1; ADDR_O <= ADDR_O + 4; end loop; WE_O <= '0'; ADDR_O <= X"0000_0C00"; for i in 0 to 7 loop wait until rising_edge(CLK_O) and SRDY_I = '1'; ADDR_O <= ADDR_O + 4; end loop; STB_O <= '0'; wait until rising_edge(CLK_O) and dout_cnt = 7; CYC_O <= '0'; ------------------------------------------------------------ wait for 10*CLK_PERIOD; ------------------------------------------------------------ -- 8-word burst cycle dout_rst <= '1'; wait until rising_edge(CLK_O); dout_rst <= '0'; CYC_O <= '1'; STB_O <= '1'; WE_O <= '0'; ADDR_O <= X"0000_0000"; for i in 0 to 7 loop wait until rising_edge(CLK_O) and SRDY_I = '1'; ADDR_O <= ADDR_O + 4; end loop; ADDR_O <= X"0000_0400"; for i in 0 to 7 loop wait until rising_edge(CLK_O) and SRDY_I = '1'; ADDR_O <= ADDR_O + 4; end loop; ADDR_O <= X"0000_0800"; for i in 0 to 7 loop wait until rising_edge(CLK_O) and SRDY_I = '1'; ADDR_O <= ADDR_O + 4; end loop; ADDR_O <= X"0000_0C00"; for i in 0 to 7 loop wait until rising_edge(CLK_O) and SRDY_I = '1'; ADDR_O <= ADDR_O + 4; end loop; STB_O <= '0'; wait until rising_edge(CLK_O) and dout_cnt = 31; CYC_O <= '0'; wait; end process; END;