You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			251 lines
		
	
	
		
			5.9 KiB
		
	
	
	
		
			VHDL
		
	
			
		
		
	
	
			251 lines
		
	
	
		
			5.9 KiB
		
	
	
	
		
			VHDL
		
	
| library ieee;
 | |
| use ieee.std_logic_1164.all;
 | |
| use ieee.numeric_std.all;
 | |
| 
 | |
| library work;
 | |
| use work.common.all;
 | |
| use work.wishbone_types.all;
 | |
| 
 | |
| library unisim;
 | |
| use unisim.vcomponents.all;
 | |
| 
 | |
| entity dmi_dtm_tb is
 | |
| end dmi_dtm_tb;
 | |
| 
 | |
| architecture behave of dmi_dtm_tb is
 | |
|     signal clk           : std_ulogic;
 | |
|     signal rst           : std_ulogic;
 | |
|     constant clk_period  : time := 10 ns;
 | |
|     constant jclk_period : time := 30 ns;
 | |
| 
 | |
|     -- DMI debug bus signals
 | |
|     signal dmi_addr	: std_ulogic_vector(7 downto 0);
 | |
|     signal dmi_din	: std_ulogic_vector(63 downto 0);
 | |
|     signal dmi_dout	: std_ulogic_vector(63 downto 0);
 | |
|     signal dmi_req	: std_ulogic;
 | |
|     signal dmi_wr	: std_ulogic;
 | |
|     signal dmi_ack	: std_ulogic;
 | |
| 
 | |
|     -- Global JTAG signals (used by BSCANE2 inside dmi_dtm
 | |
|     alias j : glob_jtag_t is glob_jtag;
 | |
| 
 | |
|     -- Wishbone interfaces
 | |
|     signal wishbone_ram_in : wishbone_slave_out;
 | |
|     signal wishbone_ram_out : wishbone_master_out;
 | |
| 
 | |
| begin
 | |
|     dtm: entity work.dmi_dtm
 | |
| 	generic map(
 | |
| 	    ABITS => 8,
 | |
| 	    DBITS => 64
 | |
| 	    )
 | |
| 	port map(
 | |
| 	    sys_clk	=> clk,
 | |
| 	    sys_reset	=> rst,
 | |
| 	    dmi_addr	=> dmi_addr,
 | |
| 	    dmi_din	=> dmi_din,
 | |
| 	    dmi_dout	=> dmi_dout,
 | |
| 	    dmi_req	=> dmi_req,
 | |
| 	    dmi_wr	=> dmi_wr,
 | |
| 	    dmi_ack	=> dmi_ack
 | |
| 	    );
 | |
| 
 | |
|     simple_ram_0: entity work.mw_soc_memory
 | |
| 	generic map(RAM_INIT_FILE => "simple_ram_behavioural.bin",
 | |
| 		    MEMORY_SIZE => 524288)
 | |
| 	port map(clk => clk, rst => rst,
 | |
| 		 wishbone_in => wishbone_ram_out,
 | |
| 		 wishbone_out => wishbone_ram_in);
 | |
| 
 | |
|     wishbone_debug_0: entity work.wishbone_debug_master
 | |
| 	port map(clk => clk, rst => rst,
 | |
| 		 dmi_addr => dmi_addr(1 downto 0),
 | |
| 		 dmi_dout => dmi_din,
 | |
| 		 dmi_din => dmi_dout,
 | |
| 		 dmi_wr => dmi_wr,
 | |
| 		 dmi_ack => dmi_ack,
 | |
| 		 dmi_req => dmi_req,
 | |
| 		 wb_in => wishbone_ram_in,
 | |
| 		 wb_out => wishbone_ram_out);
 | |
| 
 | |
|     -- system clock
 | |
|     sys_clk: process
 | |
|     begin
 | |
| 	clk <= '1';
 | |
| 	wait for clk_period / 2;
 | |
| 	clk <= '0';
 | |
| 	wait for clk_period / 2;
 | |
|     end process sys_clk;
 | |
| 
 | |
|     -- system sim: just reset and wait
 | |
|     sys_sim: process
 | |
|     begin
 | |
| 	rst <= '1';
 | |
| 	wait for clk_period;
 | |
| 	rst <= '0';
 | |
| 	wait;
 | |
|     end process;
 | |
| 
 | |
|     -- jtag sim process
 | |
|     sim_jtag: process
 | |
| 	procedure clock(count: in INTEGER) is
 | |
| 	begin
 | |
| 	    for i in 1 to count loop
 | |
| 		j.tck <= '0';
 | |
| 		wait for jclk_period/2;
 | |
| 		j.tck <= '1';
 | |
| 		wait for jclk_period/2;
 | |
| 	    end loop;
 | |
| 	end procedure clock;
 | |
| 
 | |
| 	procedure shift_out(val: in std_ulogic_vector) is
 | |
| 	begin
 | |
| 	    for i in 0 to val'length-1 loop
 | |
| 		j.tdi <= val(i);
 | |
| 		clock(1);
 | |
| 	    end loop;
 | |
| 	end procedure shift_out;
 | |
| 
 | |
| 	procedure shift_in(val: out std_ulogic_vector) is
 | |
| 	begin
 | |
| 	    for i in val'length-1 downto 0 loop
 | |
| 		val := j.tdo & val(val'length-1 downto 1);
 | |
| 		clock(1);
 | |
| 	    end loop;
 | |
| 	end procedure shift_in;
 | |
| 
 | |
| 	procedure send_command(
 | |
| 	    addr : in std_ulogic_vector(7 downto 0);
 | |
| 	    data : in std_ulogic_vector(63 downto 0);
 | |
| 	    op   : in std_ulogic_vector(1 downto 0)) is
 | |
| 	begin
 | |
| 	    j.capture <= '1';
 | |
| 	    clock(1);
 | |
| 	    j.capture <= '0';	
 | |
| 	    clock(1);
 | |
| 	    j.shift <= '1';
 | |
| 	    shift_out(op);
 | |
| 	    shift_out(data);
 | |
| 	    shift_out(addr);
 | |
| 	    j.shift <= '0';
 | |
| 	    j.update <= '1';
 | |
| 	    clock(1);
 | |
| 	    j.update <= '0';
 | |
| 	    clock(1);
 | |
| 	end procedure send_command;	
 | |
| 
 | |
| 	procedure read_resp(
 | |
| 	    op   : out std_ulogic_vector(1 downto 0);
 | |
| 	    data : out std_ulogic_vector(63 downto 0)) is
 | |
| 
 | |
| 	    variable addr : std_ulogic_vector(7 downto 0);
 | |
| 	begin
 | |
| 	    j.capture <= '1';
 | |
| 	    clock(1);
 | |
| 	    j.capture <= '0';	
 | |
| 	    clock(1);
 | |
| 	    j.shift <= '1';
 | |
| 	    shift_in(op);
 | |
| 	    shift_in(data);
 | |
| 	    shift_in(addr);
 | |
| 	    j.shift <= '0';
 | |
| 	    j.update <= '1';
 | |
| 	    clock(1);
 | |
| 	    j.update <= '0';
 | |
| 	    clock(1);
 | |
| 	end procedure read_resp;	
 | |
| 
 | |
| 	procedure dmi_write(addr : in std_ulogic_vector(7 downto 0);
 | |
| 			    data : in std_ulogic_vector(63 downto 0)) is
 | |
| 	    variable resp_op   : std_ulogic_vector(1 downto 0);
 | |
| 	    variable resp_data : std_ulogic_vector(63 downto 0);
 | |
| 	    variable timeout   : integer;
 | |
| 	begin
 | |
| 	    send_command(addr, data, "10");
 | |
| 	    loop
 | |
| 		read_resp(resp_op, resp_data);
 | |
| 		case resp_op is
 | |
| 		when "00" =>
 | |
| 		    return;
 | |
| 		when "11" =>
 | |
| 		    timeout := timeout + 1;
 | |
| 		    assert timeout < 0
 | |
| 			report "dmi_write timed out !" severity error;
 | |
| 		when others =>
 | |
| 		    assert 0 > 1 report "dmi_write got odd status: " &
 | |
| 			to_hstring(resp_op) severity error;
 | |
| 		end case;
 | |
| 	    end loop;
 | |
| 	end procedure dmi_write;
 | |
| 	
 | |
| 
 | |
| 	procedure dmi_read(addr : in std_ulogic_vector(7 downto 0);
 | |
| 			   data : out std_ulogic_vector(63 downto 0)) is
 | |
| 	    variable resp_op   : std_ulogic_vector(1 downto 0);
 | |
| 	    variable timeout   : integer;
 | |
| 	begin
 | |
| 	    send_command(addr, (others => '0'), "01");
 | |
| 	    loop
 | |
| 		read_resp(resp_op, data);
 | |
| 		case resp_op is
 | |
| 		when "00" =>
 | |
| 		    return;
 | |
| 		when "11" =>
 | |
| 		    timeout := timeout + 1;
 | |
| 		    assert timeout < 0
 | |
| 			report "dmi_read timed out !" severity error;
 | |
| 		when others =>
 | |
| 		    assert 0 > 1 report "dmi_read got odd status: " &
 | |
| 			to_hstring(resp_op) severity error;
 | |
| 		end case;
 | |
| 	    end loop;
 | |
| 	end procedure dmi_read;
 | |
| 
 | |
| 	variable data : std_ulogic_vector(63 downto 0);
 | |
|     begin
 | |
| 	-- init & reset
 | |
| 	j.reset <= '1';
 | |
| 	j.sel <= "0000";
 | |
| 	j.capture <= '0';
 | |
| 	j.update <= '0';
 | |
| 	j.shift <= '0';
 | |
| 	j.tdi <= '0';
 | |
| 	j.tms <= '0';
 | |
| 	j.runtest <= '0';
 | |
| 	clock(5);
 | |
| 	j.reset <= '0';
 | |
| 	clock(5);
 | |
| 
 | |
| 	-- select chain 2
 | |
| 	j.sel <= "0010";
 | |
| 	clock(1);
 | |
| 
 | |
| 	-- send command
 | |
| 	dmi_read(x"00", data);
 | |
| 	report "Read addr reg:" & to_hstring(data);
 | |
| 	report "Writing addr reg to all 1's";
 | |
| 	dmi_write(x"00", (others => '1'));
 | |
| 	dmi_read(x"00", data);
 | |
| 	report "Read addr reg:" & to_hstring(data);
 | |
| 
 | |
| 	report "Writing ctrl reg to all 1's";
 | |
| 	dmi_write(x"02", (others => '1'));
 | |
| 	dmi_read(x"02", data);
 | |
| 	report "Read ctrl reg:" & to_hstring(data);
 | |
| 
 | |
| 	report "Read memory at 0...\n";
 | |
| 	dmi_write(x"00", x"0000000000000000");
 | |
| 	dmi_write(x"02", x"00000000000007ff");
 | |
| 	dmi_read(x"01", data);
 | |
| 	report "00:" & to_hstring(data);
 | |
| 	dmi_read(x"01", data);
 | |
| 	report "08:" & to_hstring(data);
 | |
| 	dmi_read(x"01", data);
 | |
| 	report "10:" & to_hstring(data);
 | |
| 	dmi_read(x"01", data);
 | |
| 	report "18:" & to_hstring(data);
 | |
| 	clock(10);
 | |
| 	std.env.finish;
 | |
|     end process;
 | |
| end behave;
 |