LIBRARY ieee; USE ieee.std_logic_1164.ALL; USE ieee.numeric_std.all; LIBRARY std; USE std.textio.all; USE work.mbl_pkg.all; USE work.lx_rocon_pkg.all; ENTITY lx_tumbl_tb IS END lx_tumbl_tb; ARCHITECTURE behavior OF lx_tumbl_tb IS --Clock signals signal clk_cpu : std_logic := '0'; signal clk_50m : std_logic := '0'; -- Clock period definitions --constant clk_period_cpu : time := 13.8 ns; constant clk_period_50m : time := 20 ns; constant cycle_cnt_limit : natural := 2**20 - 1; signal cycle_cnt : integer range 0 to cycle_cnt_limit; signal tumbl_reset_s : std_logic := '1'; -- Internal memory signals signal imem_en_s : std_logic := '0'; signal dmem_en_s : std_logic := '0'; signal imem_we_s : std_logic_vector(3 downto 0) := "0000"; signal dmem_we_s : std_logic_vector(3 downto 0) := "0000"; signal imem_data_o_s : std_logic_vector(31 downto 0); signal dmem_data_o_s : std_logic_vector(31 downto 0); signal imem_data_i_s : std_logic_vector(31 downto 0); signal dmem_data_i_s : std_logic_vector(31 downto 0); signal imem_address_s : std_logic_vector(8 downto 0); signal dmem_address_s : std_logic_vector(9 downto 0); signal xmemb_sel_s : std_logic; signal xmemb_i_s : DMEMB2CORE_Type; signal xmemb_o_s : CORE2DMEMB_Type; signal imem_ready_s : std_logic := '0'; signal imem_fill_addr_s : natural range 0 to 2**8-1 := 0; -- Simulate special events and interactions signal delay_access_s : std_logic := '0'; signal delay_access_r : std_logic := '0'; signal delay_access_r2 : std_logic := '0'; BEGIN -- Instantiate the Unit Under Test (UUT) uut: lx_rocon_tumbl generic map ( IMEM_ABITS_g => 9, DMEM_ABITS_g => 10, -- USE_HW_MUL_g => true, USE_BARREL_g => true, COMPATIBILITY_MODE_g => false ) port map ( clk_i => clk_cpu, rst_i => tumbl_reset_s, halt_i => '0', int_i => '0', trace_i => '0', trace_kick_i => '0', pc_o => open, halted_o => open, halt_code_o => open, -- Internal memory (instruction) imem_clk_i => clk_cpu, imem_en_i => imem_en_s, imem_we_i => imem_we_s, imem_addr_i => imem_address_s, imem_data_i => imem_data_i_s, imem_data_o => imem_data_o_s, -- Internal memory (data) dmem_clk_i => clk_cpu, dmem_en_i => dmem_en_s, dmem_we_i => dmem_we_s, dmem_addr_i => dmem_address_s, dmem_data_i => dmem_data_i_s, dmem_data_o => dmem_data_o_s, -- External memory bus xmemb_sel_o => xmemb_sel_s, xmemb_i => xmemb_i_s, xmemb_o => xmemb_o_s ); clk_cpu <= clk_50m; xmemb_i_s.int <= '0'; -- No interrupt setup_process :process begin wait until clk_cpu'event and clk_cpu = '1'; if cycle_cnt < cycle_cnt_limit and imem_ready_s = '1' then cycle_cnt <= cycle_cnt + 1; end if; if cycle_cnt < 8 then tumbl_reset_s <= '1'; else tumbl_reset_s <= '0'; end if; end process; setup_imem_process : process file imem_file : text open READ_MODE is "imem.bits"; variable my_line : LINE; variable bits_line : LINE; variable mem_location : bit_vector(31 downto 0); begin wait until clk_50m'event and clk_50m = '1'; if endfile(imem_file) then if imem_ready_s = '0' then write(my_line, string'("reading imem complete")); writeline(output, my_line); end if; imem_ready_s <= '1'; imem_we_s <= "0000"; imem_en_s <= '0'; else imem_address_s <= std_logic_vector(to_unsigned(imem_fill_addr_s, 9)); readline(imem_file, bits_line); read(bits_line, mem_location); imem_data_i_s <= to_stdLogicVector(mem_location); imem_we_s <= "1111"; imem_en_s <= '1'; imem_fill_addr_s <= imem_fill_addr_s + 1; end if; end process; events_process: process(cycle_cnt, xmemb_sel_s, delay_access_r, delay_access_r2) begin -- Simulate externall access to xmem bus shared with Tumbl if cycle_cnt >= 47 and cycle_cnt <= 48 then -- if xmemb_sel_s = '1' and (delay_access_r = '0' or delay_access_r2 = '0') then delay_access_s <= '1'; else delay_access_s <= '0'; end if; end process; -- Enable xmem clken only when bus available for Tumbl xmemb_i_s.clken <= not delay_access_s; xmemb_process :process variable xmemb_addr_v : std_logic_vector(14 downto 0); variable my_line : LINE; begin wait until clk_cpu'event and clk_cpu = '1'; xmemb_i_s.data <= (others => 'X'); xmemb_addr_v := xmemb_o_s.addr; if xmemb_o_s.rd = '1' then if delay_access_s = '1' then xmemb_i_s.data(31 downto 16) <= x"F0F0"; else xmemb_i_s.data(31 downto 16) <= x"ACCE"; xmemb_i_s.data(15 downto 2) <= xmemb_addr_v(13 downto 0); xmemb_i_s.data(1 downto 0) <= "00"; end if; write(my_line, string'("@")); write(my_line, cycle_cnt); write(my_line, string'(" tumbl read @(")); write(my_line, to_bitvector(xmemb_o_s.addr)); write(my_line, string'(")")); writeline(output, my_line); end if; if xmemb_o_s.bls /= "0000" then write(my_line, string'("@")); write(my_line, cycle_cnt); write(my_line, string'(" tumbl write ")); write(my_line, to_bitvector(xmemb_i_s.data)); write(my_line, string'(" -> @(")); write(my_line, to_bitvector(xmemb_o_s.addr)); write(my_line, string'(")")); writeline(output, my_line); end if; delay_access_r <= delay_access_s; delay_access_r2 <= delay_access_r; end process; clk_50m_process :process begin clk_50m <= '1'; wait for clk_period_50m/2; clk_50m <= '0'; wait for clk_period_50m/2; end process; -- Stimulus process stim_proc: process begin -- External ModelSim script wait; end process; END;