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.wishbone_bram_wrapper generic map(RAM_INIT_FILE => "main_ram.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;