----------------------------------------------------------------------- -- $Header: D:\usr\cvsroot/VHDL/lib/JBUS/src/tb_busmaster_async.vhd,v 1.1 2013/07/21 09:21:30 jens Exp $ ----------------------------------------------------------------------- LIBRARY ieee; use IEEE.STD_LOGIC_1164.ALL; USE ieee.numeric_std.ALL; use work.busmaster_types.all; ENTITY tb_busmaster_async IS END tb_busmaster_async; ARCHITECTURE behavior OF tb_busmaster_async IS constant DATA_WIDTH : integer := 32; constant CLK_PERIOD : time := 10 ns; constant JBUS_CLK_PERIOD : time := 20 ns; signal clk : std_logic := '1'; signal rst : std_logic := '1'; 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_64 : unsigned(63 downto 0) := (others => '-'); signal MDAT_O_64 : unsigned(63 downto 0) := (others => '-'); signal MDAT_I : unsigned(31 downto 0) := (others => '-'); signal MDAT_O : unsigned(31 downto 0) := (others => '-'); signal cmd_cycle_finished : std_logic; signal cmd_cycle_en : std_logic := '0'; signal cmd_rdy : std_logic; signal cmd_we : std_logic := '0'; signal cmd_in : bm_cmd_t; signal din : unsigned(31 downto 0) := (others => '-'); signal din_rdy : std_logic; signal din_we : std_logic := '0'; signal dout : unsigned(31 downto 0); signal dout_vld : std_logic; signal dout_re : std_logic := '0'; signal read_reg : unsigned(31 downto 0) := (others => '-'); type state_t is (IDLE, LA_SA, LA_SU, LU_SA, LU_SU, CC_SA, CC_SU); signal state : state_t := IDLE; type ram_t is array (0 to 127) of unsigned(63 downto 0); signal ram64 : ram_t := ( X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000", X"0000_0000_0000_0000" ); BEGIN MDAT_I <= MDAT_I_64(31 downto 0); MDAT_O_64 <= MDAT_O & MDAT_O; inst_uut : entity work.busmaster_async GENERIC MAP ( DATA_WIDTH => 32, FIFO_DEPTH => 2 ) PORT MAP ( -- System signals rst => rst, clk => clk, cmd_cycle_finished => cmd_cycle_finished, cmd_cycle_en => cmd_cycle_en, cmd_rdy => cmd_rdy, cmd_we => cmd_we, cmd_in => cmd_in, din => din, din_rdy => din_rdy, din_we => din_we, dout => dout, dout_vld => dout_vld, dout_re => dout_re, -- JBUS Master signals RST_I => RST_O, CLK_I => CLK_O, CYC_O => CYC_O, STB_O => STB_O, WE_O => WE_O, SEL_O => SEL_O, ACK_I => ACK_I, SRDY_I => SRDY_I, MRDY_O => MRDY_O, ADDR_O => ADDR_O, MDAT_I => MDAT_I, MDAT_O => MDAT_O ); CLK_GEN: process begin wait for CLK_PERIOD/2; clk <= not clk; end process; JBUS_CLK_GEN: process begin wait for JBUS_CLK_PERIOD/2; CLK_O <= not CLK_O; end process; -- Slave SRDY_I <= CYC_O; process(CLK_O) variable res: unsigned(63 downto 0); variable ram_data : unsigned(63 downto 0); begin if rising_edge(CLK_O) then if RST_O = '1' then else ACK_I <= '0'; if (CYC_O and STB_O) = '1' then if WE_O = '0' then ACK_I <= '1'; ram_data := ram64(to_integer(ADDR_O(31 downto 3))); if ADDR_O(2) = '0' then res := ram_data; else res := ram_data(31 downto 0) & ram_data(63 downto 32); end if; elsif MRDY_O = '1' then -- WE=1 ram_data := ram64(to_integer(ADDR_O(31 downto 3))); ram_data := (others => '-'); if ADDR_O(2) = '0' then if SEL_O = "11111111" then ram64(to_integer(ADDR_O(31 downto 3))) <= MDAT_O_64; elsif SEL_O = "00001111" then ram64(to_integer(ADDR_O(31 downto 3))) <= ram_data(63 downto 32) & MDAT_O_64(31 downto 0); elsif SEL_O = "11110000" then ram64(to_integer(ADDR_O(31 downto 3))) <= MDAT_O_64(63 downto 32) & ram_data(31 downto 0); end if; else if SEL_O = "11111111" then ram64(to_integer(ADDR_O(31 downto 3))) <= MDAT_O_64(31 downto 0) & MDAT_O_64(63 downto 32); elsif SEL_O = "00001111" then ram64(to_integer(ADDR_O(31 downto 3))) <= MDAT_O_64(31 downto 0) & ram_data(31 downto 0); elsif SEL_O = "11110000" then ram64(to_integer(ADDR_O(31 downto 3))) <= ram_data(63 downto 32) & MDAT_O_64(63 downto 32); end if; end if; end if; end if; if (CYC_O and MRDY_O) = '1' then MDAT_I_64 <= res; end if; end if; end if; end process; process(clk) begin if rising_edge(clk) then if rst = '1' then read_reg <= X"00000000"; elsif dout_vld = '1' then read_reg <= dout; end if; end if; end process; dout_re <= dout_vld; -- Master STIMULUS: process variable result : unsigned(31 downto 0); procedure cmd_write_single(addr, sel, data : unsigned) is begin din <= data; din_we <= '1'; wait until rising_edge(clk) and din_rdy = '1'; din_we <= '0'; cmd_in.rw <= '1'; cmd_in.sel <= sel; cmd_in.addr <= addr; cmd_we <= '1'; wait until rising_edge(clk) and cmd_rdy = '1'; cmd_we <= '0'; end procedure cmd_write_single; procedure cmd_read_single(addr : unsigned) is begin cmd_in.rw <= '0'; cmd_in.sel <= (others => '0'); cmd_in.addr <= addr; cmd_we <= '1'; wait until rising_edge(clk) and cmd_rdy = '1'; cmd_we <= '0'; end procedure cmd_read_single; begin wait for 6*CLK_PERIOD; rst <= '0'; RST_O <= '0'; wait for 60*CLK_PERIOD; wait until rising_edge(clk); state <= IDLE; for i in 0 to 9 loop cmd_cycle_en <= '1'; cmd_write_single(X"0000_0000", "1111", X"1000_ABCD"); cmd_write_single(X"0000_0008", "1111", X"2000_ABCD"); cmd_write_single(X"0000_0010", "1111", X"3000_ABCD"); cmd_write_single(X"0000_0018", "1111", X"4000_ABCD"); cmd_write_single(X"0000_0020", "1111", X"5000_ABCD"); cmd_write_single(X"0000_0028", "1111", X"6000_ABCD"); cmd_write_single(X"0000_0030", "1111", X"7000_ABCD"); cmd_write_single(X"0000_0038", "1111", X"8000_ABCD"); cmd_read_single(X"0000_0000"); cmd_read_single(X"0000_0008"); cmd_read_single(X"0000_0010"); cmd_read_single(X"0000_0018"); cmd_read_single(X"0000_0020"); cmd_read_single(X"0000_0028"); cmd_read_single(X"0000_0030"); cmd_read_single(X"0000_0038"); cmd_write_single(X"0000_0000", "1111", X"1000_BEEF"); cmd_read_single(X"0000_0000"); cmd_write_single(X"0000_0008", "1111", X"2000_BEEF"); cmd_read_single(X"0000_0008"); cmd_write_single(X"0000_0010", "1111", X"3000_BEEF"); cmd_read_single(X"0000_0010"); cmd_write_single(X"0000_0018", "1111", X"4000_BEEF"); cmd_read_single(X"0000_0018"); cmd_write_single(X"0000_0020", "1111", X"5000_BEEF"); cmd_read_single(X"0000_0020"); cmd_write_single(X"0000_0028", "1111", X"6000_BEEF"); cmd_read_single(X"0000_0028"); cmd_write_single(X"0000_0030", "1111", X"7000_BEEF"); cmd_read_single(X"0000_0030"); cmd_write_single(X"0000_0038", "1111", X"8000_BEEF"); cmd_read_single(X"0000_0038"); cmd_cycle_en <= '0'; wait until rising_edge(clk); wait until rising_edge(clk); cmd_cycle_en <= '1'; cmd_write_single(X"0000_0100", "1111", X"1100_ABCD"); cmd_write_single(X"0000_0108", "1111", X"2200_ABCD"); cmd_write_single(X"0000_0110", "1111", X"3300_ABCD"); cmd_write_single(X"0000_0118", "1111", X"4400_ABCD"); cmd_write_single(X"0000_0120", "1111", X"5500_ABCD"); cmd_write_single(X"0000_0128", "1111", X"6600_ABCD"); cmd_write_single(X"0000_0130", "1111", X"7700_ABCD"); cmd_write_single(X"0000_0138", "1111", X"8800_ABCD"); cmd_read_single(X"0000_0100"); cmd_read_single(X"0000_0108"); cmd_read_single(X"0000_0110"); cmd_read_single(X"0000_0118"); cmd_read_single(X"0000_0120"); cmd_read_single(X"0000_0128"); cmd_read_single(X"0000_0130"); cmd_read_single(X"0000_0138"); cmd_write_single(X"0000_0100", "1111", X"1100_BEEF"); cmd_read_single(X"0000_0100"); cmd_write_single(X"0000_0108", "1111", X"2200_BEEF"); cmd_read_single(X"0000_0108"); cmd_write_single(X"0000_0110", "1111", X"3300_BEEF"); cmd_read_single(X"0000_0110"); cmd_write_single(X"0000_0118", "1111", X"4400_BEEF"); cmd_read_single(X"0000_0118"); cmd_write_single(X"0000_0120", "1111", X"5500_BEEF"); cmd_read_single(X"0000_0120"); cmd_write_single(X"0000_0128", "1111", X"6600_BEEF"); cmd_read_single(X"0000_0128"); cmd_write_single(X"0000_0130", "1111", X"7700_BEEF"); cmd_read_single(X"0000_0130"); cmd_write_single(X"0000_0138", "1111", X"8800_BEEF"); cmd_read_single(X"0000_0138"); cmd_cycle_en <= '0'; wait until rising_edge(clk) and cmd_cycle_finished = '1'; wait for 60*CLK_PERIOD; wait until rising_edge(clk); end loop; state <= IDLE; wait; end process; END;