OpenCores
URL https://opencores.org/ocsvn/opb_usblite/opb_usblite/trunk

Subversion Repositories opb_usblite

[/] [opb_usblite/] [trunk/] [pcores/] [opb_usblite_v1_00_a/] [hdl/] [vhdl/] [tb_USBLITE_Core.vhd] - Rev 2

Go to most recent revision | Compare with Previous | Blame | View Log

--
--    opb_usblite - opb_uartlite replacement
--
--    opb_usblite is using components from Rudolf Usselmann see
--    http://www.opencores.org/cores/usb_phy/
--    and Joris van Rantwijk see http://www.xs4all.nl/~rjoris/fpga/usb.html
--
--    Copyright (C) 2010 Ake Rehnman
--
--    This program is free software: you can redistribute it and/or modify
--    it under the terms of the GNU General Public License as published by
--    the Free Software Foundation, either version 3 of the License, or
--    (at your option) any later version.
--
--    This program 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 General Public License for more details.
--
--    You should have received a copy of the GNU General Public License
--    along with this program.  If not, see <http://www.gnu.org/licenses/>.
--
 
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
use STD.TEXTIO.all;
use IEEE.STD_LOGIC_TEXTIO.all;
 
 
entity tb_USBLITE_Core is
end entity tb_USBLITE_Core;
 
library unisim;
use unisim.all;
 
architecture akre of tb_USBLITE_Core is
 
  component usb_phy is
    port (
      clk : in std_logic;
      rst : in std_logic;
      phy_tx_mode : in std_logic;
      usb_rst : out std_logic;
 
		-- Transciever Interface
		  txdp : out std_logic;
		  txdn : out std_logic;
		  txoe : out std_logic;
		  rxd : in std_logic;
		  rxdp : in std_logic;
		  rxdn : in std_logic;
 
		-- UTMI Interface
		  DataOut_i : in std_logic_vector (7 downto 0);
		  TxValid_i : in std_logic;
		  TxReady_o : out std_logic;
		  RxValid_o : out std_logic;
		  RxActive_o : out std_logic;
		  RxError_o : out std_logic;
		  DataIn_o : out std_logic_vector (7 downto 0);
		  LineState_o : out std_logic_vector (1 downto 0)
    );
  end component usb_phy;
 
  component OPB_USBLITE_Core is
  generic (
    C_PHYMODE :       std_logic := '1';
    C_VENDORID :      std_logic_vector(15 downto 0) := X"1234";
    C_PRODUCTID :     std_logic_vector(15 downto 0) := X"5678";
    C_VERSIONBCD :    std_logic_vector(15 downto 0) := X"0200";
    C_SELFPOWERED :   boolean := false;
    C_RXBUFSIZE_BITS: integer range 7 to 12 := 10;
    C_TXBUFSIZE_BITS: integer range 7 to 12 := 10 
    );
  port (
    Clk   : in std_logic;
    Reset : in std_logic;
    Usb_Clk : in std_logic;
    -- OPB signals
    OPB_CS : in std_logic;
    OPB_ABus : in std_logic_vector(0 to 1);
    OPB_RNW  : in std_logic;
    OPB_DBus : in std_logic_vector(7 downto 0);
    SIn_xferAck : out std_logic;
    SIn_DBus    : out std_logic_vector(7 downto 0);
    Interrupt : out std_logic;
    -- USB signals
		txdp : out std_logic;
		txdn : out std_logic;
		txoe : out std_logic;
		rxd : in std_logic;
		rxdp : in std_logic;
		rxdn : in std_logic
  );
  end component OPB_USBLITE_Core;
 
  signal clk : std_logic;
  signal usbclk : std_logic;
  signal reset : std_logic;
  signal rxdp : std_logic;
  signal rxdn : std_logic;
  signal rxd : std_logic;
  signal txdp : std_logic;
  signal txdn : std_logic;
  signal txoe : std_logic;
 
  signal usbtxdata : std_logic_vector (7 downto 0);
  signal usbtxvalid : std_logic;
  signal usbtxready : std_logic;
  signal usbrxvalid : std_logic;
  signal usbrxactive : std_logic;
  signal usbrxerror : std_logic;
  signal usbrxdata : std_logic_vector (7 downto 0);
  signal usblinestate : std_logic_vector (1 downto 0);
 
  signal Bus2IP_CS : std_logic := '0';
  signal Bus2IP_CE : std_logic := '0';
  signal Bus2IP_Addr : std_logic_vector(0 to 31) := X"00000000";
  signal Bus2IP_RNW : std_logic := '0';
  signal Bus2IP_Data : std_logic_vector(0 to 31);
  signal Bus2IP_BE : std_logic_vector(3 downto 0) := "0000";
  signal IP2Bus_Ack : std_logic := '0';
  signal IP2Bus_Data : std_logic_vector(0 to 31) := X"00000000";
  signal Interrupt : std_logic := '0';
 
  signal resetn : std_logic;
  signal usbrxdata_r : std_logic_vector(7 downto 0);
 
--  type txmemarray is array (0 to 2048) of std_logic_vector(7 downto 0);
  type txmemarray is array (0 to 255) of std_logic_vector(7 downto 0);
  shared variable txmem : txmemarray;
 
--  type bufferarray is array (0 to 16384) of std_logic_vector(7 downto 0);
  type bufferarray is array (0 to 255) of std_logic_vector(7 downto 0);
  shared variable buffer1 : bufferarray;
  shared variable buffer0 : bufferarray;
  shared variable buffer1_last : integer;
  shared variable len : integer;
  shared variable setup_pid : std_logic;
  shared variable error_cnt : integer;
 
  constant USBF_T_PID_OUT : std_logic_vector(3 downto 0):="0001";
  constant USBF_T_PID_IN : std_logic_vector(3 downto 0):="1001";
  constant USBF_T_PID_SOF : std_logic_vector(3 downto 0):="0101";
  constant USBF_T_PID_SETUP : std_logic_vector(3 downto 0):="1101";
  constant USBF_T_PID_DATA0 : std_logic_vector(3 downto 0):="0011";
  constant USBF_T_PID_DATA1 : std_logic_vector(3 downto 0):="1011";
  constant USBF_T_PID_DATA2 : std_logic_vector(3 downto 0):="0111";
  constant USBF_T_PID_MDATA : std_logic_vector(3 downto 0):="1111";
  constant USBF_T_PID_ACK : std_logic_vector(3 downto 0):="0010";
  constant USBF_T_PID_NACK : std_logic_vector(3 downto 0):="1010";
  constant USBF_T_PID_STALL : std_logic_vector(3 downto 0):="1110";
  constant USBF_T_PID_NYET : std_logic_vector(3 downto 0):="0110";
  constant USBF_T_PID_PRE : std_logic_vector(3 downto 0):="1100";
  constant USBF_T_PID_ERR : std_logic_vector(3 downto 0):="1100";
  constant USBF_T_PID_SPLIT : std_logic_vector(3 downto 0):="1000";
  constant USBF_T_PID_PING : std_logic_vector(3 downto 0):="0100";
  constant USBF_T_PID_RES : std_logic_vector(3 downto 0):="0000";
 
  constant  GET_STATUS : std_logic_vector(7 downto 0) :=	X"00";
	constant	CLEAR_FEATURE	: std_logic_vector(7 downto 0) :=	X"01";
	constant	SET_FEATURE	: std_logic_vector(7 downto 0) :=	X"03";
	constant	SET_ADDRESS	: std_logic_vector(7 downto 0) :=	X"05";
	constant	GET_DESCRIPTOR	: std_logic_vector(7 downto 0) :=	X"06";
	constant	SET_DESCRIPTOR	: std_logic_vector(7 downto 0) :=	X"07";
	constant	GET_CONFIG	: std_logic_vector(7 downto 0) :=	X"08";
	constant	SET_CONFIG	: std_logic_vector(7 downto 0) :=	X"09";
	constant	GET_INTERFACE	: std_logic_vector(7 downto 0) :=	X"0a";
	constant	SET_INTERFACE	: std_logic_vector(7 downto 0) :=	X"0b";
	constant	SYNCH_FRAME	: std_logic_vector(7 downto 0) :=	X"0c";
 
  procedure utmi_recv_pack (variable size : inout integer) is
  begin
    size := 0;
    while (usbrxactive /= '1') loop
      wait until rising_edge(usbclk);
    end loop;
    while (usbrxactive= '1') loop
    	while (usbrxvalid /= '1' and usbrxactive = '1') loop
	      wait until rising_edge(usbclk);
    	end loop; 
	    if (usbrxvalid = '1' and usbrxactive = '1') then
			  txmem(size) := usbrxdata;
			  size := size + 1;
	    end if;
	    wait until rising_edge(usbclk);
    end loop;
  end procedure utmi_recv_pack;
 
  procedure utmi_send_pack (constant size : integer; signal usbtxdata: out std_logic_vector; signal usbtxvalid: out std_logic) is
    variable n : integer;
  begin
    for n in 0 to size-1 loop
      wait until rising_edge(usbclk);
	    usbtxvalid <= '1';
      usbtxdata <= txmem(n);
      while (usbtxready/='1') loop
        wait until rising_edge(usbclk);
      end loop;
    end loop;
    wait until rising_edge(usbclk);
    usbtxvalid <= '0';
  end procedure utmi_send_pack;
 
  function crc5 (crc_in:std_logic_vector; din:std_logic_vector) return std_logic_vector is
    variable crc5x : std_logic_vector (4 downto 0);
  begin
    crc5x(0) :=	din(10) xor din(9) xor din(6) xor din(5) xor din(3) xor din(0) xor crc_in(0) xor crc_in(3) xor crc_in(4);
    crc5x(1) :=	din(10) xor din(7) xor din(6) xor din(4) xor din(1) xor	crc_in(0) xor crc_in(1) xor crc_in(4);
    crc5x(2) :=	din(10) xor din(9) xor din(8) xor din(7) xor din(6) xor	din(3) xor din(2) xor din(0) xor crc_in(0) xor crc_in(1) xor crc_in(2) xor crc_in(3) xor crc_in(4);
    crc5x(3) :=	din(10) xor din(9) xor din(8) xor din(7) xor din(4) xor din(3) xor din(1) xor crc_in(1) xor crc_in(2) xor crc_in(3) xor crc_in(4);
    crc5x(4) :=	din(10) xor din(9) xor din(8) xor din(5) xor din(4) xor din(2) xor crc_in(2) xor crc_in(3) xor crc_in(4);
    return crc5x;
  end function crc5;
 
  function crc16 (crc_in: std_logic_vector; din:std_logic_vector) return std_logic_vector is
    variable crc_out : std_logic_vector (15 downto 0);
  begin
		crc_out(0) :=	din(7) xor din(6) xor din(5) xor din(4) xor din(3) xor
		din(2) xor din(1) xor din(0) xor crc_in(8) xor crc_in(9) xor
		crc_in(10) xor crc_in(11) xor crc_in(12) xor crc_in(13) xor
		crc_in(14) xor crc_in(15);
		crc_out(1) :=	din(7) xor din(6) xor din(5) xor din(4) xor din(3) xor din(2) xor
		din(1) xor crc_in(9) xor crc_in(10) xor crc_in(11) xor
		crc_in(12) xor crc_in(13) xor crc_in(14) xor crc_in(15);
		crc_out(2) :=	din(1) xor din(0) xor crc_in(8) xor crc_in(9);
		crc_out(3) :=	din(2) xor din(1) xor crc_in(9) xor crc_in(10);
		crc_out(4) :=	din(3) xor din(2) xor crc_in(10) xor crc_in(11);
		crc_out(5) :=	din(4) xor din(3) xor crc_in(11) xor crc_in(12);
		crc_out(6) :=	din(5) xor din(4) xor crc_in(12) xor crc_in(13);
		crc_out(7) :=	din(6) xor din(5) xor crc_in(13) xor crc_in(14);
		crc_out(8) :=	din(7) xor din(6) xor crc_in(0) xor crc_in(14) xor crc_in(15);
		crc_out(9) :=	din(7) xor crc_in(1) xor crc_in(15);
		crc_out(10) :=	crc_in(2);
		crc_out(11) :=	crc_in(3);
		crc_out(12) :=	crc_in(4);
		crc_out(13) :=	crc_in(5);
		crc_out(14) :=	crc_in(6);
		crc_out(15) :=	din(7) xor din(6) xor din(5) xor din(4) xor din(3) xor din(2) xor
		din(1) xor din(0) xor crc_in(7) xor crc_in(8) xor crc_in(9) xor
		crc_in(10) xor crc_in(11) xor crc_in(12) xor crc_in(13) xor
		crc_in(14) xor crc_in(15);
		return crc_out;
	end function crc16;
 
	procedure recv_packet(variable pid: inout std_logic_vector(3 downto 0); variable size: inout integer) is
    variable del,n : integer;
    variable crc16r : std_logic_vector(15 downto 0);
    variable x,y : std_logic_vector(7 downto 0);
    variable s : LINE;
	begin
	  crc16r := X"ffff";
    utmi_recv_pack(size);
    for n in 1 to size-3 loop
    	y := txmem(n);
	    x(7) := y(0);
	    x(6) := y(1);
	    x(5) := y(2);
	    x(4) := y(3);
	    x(3) := y(4);
	    x(2) := y(5);
	    x(1) := y(6);
	    x(0) := y(7);
	    crc16r := crc16(crc16r, x);
    end loop;
    n := size-2;
 
    y := crc16r(15 downto 8); 
    x(7) := y(0);
    x(6) := y(1);
    x(5) := y(2);
    x(4) := y(3);
    x(3) := y(4);
    x(2) := y(5);
    x(1) := y(6);
    x(0) := y(7);
    crc16r(15 downto 8) := not(x);
 
    y := crc16r(7 downto 0);
    x(7) := y(0);
    x(6) := y(1);
    x(5) := y(2);
    x(4) := y(3);
    x(3) := y(4);
    x(2) := y(5);
    x(1) := y(6);
    x(0) := y(7);
    crc16r(7 downto 0) := not(x);
 
    if (crc16r /= txmem(n)&txmem(n+1)) then
      --$display("ERROR: CRC Mismatch: Expected: %h, Got: %h%h (%t)",crc16r, txmem[n], txmem[n+1], $time);
      WRITE(s,string'("ERROR: CRC Mismatch got:"));
      HWRITE(s,crc16r);
      WRITE(s,string'(" expected:"));
      HWRITE(s,txmem(n)&txmem(n+1));
      report s.all;
    end if;
 
    for n in 0 to size-3 loop
	    buffer1(buffer1_last+n) := txmem(n+1);
	  end loop;
    n := size-3;
 
    buffer1_last := buffer1_last+n;
 
    -- Check PID
    x := txmem(0);
 
    if (x(7 downto 4) /= not(x(3 downto 0))) then
      --$display("ERROR: Pid Checksum mismatch: Top: %h Bottom: %h (%t)",x[7:4], x[3:0], $time);
      WRITE(s,string'("ERROR: Pid Checksum mismatch: Top: "));
      HWRITE(s,x(7 downto 4));
      WRITE(s,string'(" Bottom:"));
      HWRITE(s,x(3 downto 0));
      report s.all;
    end if;
 
    pid := x(3 downto 0);
    size:= size-3;
 
  end procedure recv_packet;
 
  procedure send_token (constant fa:std_logic_vector(7 downto 0); constant ep:std_logic_vector(3 downto 0); constant pid:std_logic_vector(3 downto 0)) is
    variable tmp_data:std_logic_vector(15 downto 0);
    variable x,y:std_logic_vector(10 downto 0);
    variable len:integer;
  begin
    tmp_data := fa(6 downto 0)&ep&"00000";
    if (pid=USBF_T_PID_ACK)	then
      len := 1;
    else
    	len := 3;  
    end if;
    y := fa(6 downto 0)&ep;
    x(10) := y(4);
    x(9) := y(5);
    x(8) := y(6);
    x(7) := y(7);
    x(6) := y(8);
    x(5) := y(9);
    x(4) := y(10);
    x(3) := y(0);
    x(2) := y(1);
    x(1) := y(2);
    x(0) := y(3);
    y(4 downto 0)  := crc5("11111", x);
    tmp_data(4 downto 0)  := not(y(4 downto 0));
    tmp_data(15 downto 5) := x;
    txmem(0) := (not(pid)&pid);	-- PID
    txmem(1) := (	tmp_data(8)&tmp_data(9)&tmp_data(10)&tmp_data(11)&tmp_data(12)&tmp_data(13)&tmp_data(14)&tmp_data(15));
    txmem(2) := (	tmp_data(0)&tmp_data(1)&tmp_data(2)&tmp_data(3)&tmp_data(4)&tmp_data(5)&tmp_data(6)&tmp_data(7));
    utmi_send_pack(len,usbtxdata,usbtxvalid);
  end procedure send_token;
 
  procedure send_data (constant pid:std_logic_vector(3 downto 0); constant len:integer; constant mode:integer) is
    variable n : integer;
    variable crc16r : std_logic_vector(15 downto 0);
    variable x,y : std_logic_vector(7 downto 0);
  begin
    txmem(0) := not(pid)&pid;	-- PID
    crc16r := X"ffff";
    for n in 0 to len-1 loop
	    if(mode=1)	then
	      y := buffer1(buffer1_last+n);
	    else
	      y := std_logic_vector(to_unsigned(n,8));
	    end if;
 
--	    x(7 downto 0) := y(0 to 7);
	    x(7) := y(0);
	    x(6) := y(1);
	    x(5) := y(2);
	    x(4) := y(3);
	    x(3) := y(4);
	    x(2) := y(5);
	    x(1) := y(6);
	    x(0) := y(7);
	    txmem(n+1) := y;
	    crc16r := crc16(crc16r, x);
    end loop;
 
    buffer1_last := buffer1_last + len - 1;
    y := crc16r(15 downto 8);
--    x(7 downto 0) := y(0 to 7);
    x(7) := y(0);
    x(6) := y(1);
    x(5) := y(2);
    x(4) := y(3);
    x(3) := y(4);
    x(2) := y(5);
    x(1) := y(6);
    x(0) := y(7);
    txmem(len+1) := not(x);
 
    y := crc16r(7 downto 0);
--    x(7 downto 0) := y(0 to 7);
    x(7) := y(0);
    x(6) := y(1);
    x(5) := y(2);
    x(4) := y(3);
    x(3) := y(4);
    x(2) := y(5);
    x(1) := y(6);
    x(0) := y(7);
    txmem(len+2) := not(x);
 
    utmi_send_pack(len+3,usbtxdata,usbtxvalid);
  end procedure send_data;
 
  procedure data_in (constant fa:std_logic_vector(7 downto 0); constant pl_size:integer) is
    variable rlen : integer;
    variable pid : std_logic_vector(3 downto 0);
    variable expected_pid : std_logic_vector(3 downto 0);
    variable s : LINE;
  begin
	  buffer1_last := 0;
		send_token(	fa,		    -- Function Address
			X"00",		-- Logical Endpoint Number
			USBF_T_PID_IN	-- PID
		);
	  recv_packet(pid,rlen);
	  if (setup_pid='1') then
	    expected_pid := X"b"; -- DATA 1
	  else
	    expected_pid := X"3";  -- DATA 0
    end if;
	  if (pid /= expected_pid) then
  		--$display("ERROR: Data IN PID mismatch. Expected: %h, Got: %h (%t)",		expect_pid, pid, $time);
  		report "ERROR: Data IN PID mismatch.";
   	  error_cnt := error_cnt + 1;
	  end if;
 
	  setup_pid := not(setup_pid);
	  if (rlen /= pl_size) then
	    report "ERROR: Data IN Size mismatch.";
			--$display("ERROR: Data IN Size mismatch. Expected: %d, Got: %d (%t)",		pl_size, rlen, $time);
		  error_cnt := error_cnt + 1;
	  end if;
 
    DEALLOCATE(s);
    WRITE(s,string'("RCV bytes: "));
    WRITE(s,rlen);
    report s.all;
	  for n in 0 to rlen-1 loop
--		  $display("RCV Data[%0d]: %h",n,buffer1[n]);
      DEALLOCATE(s);
      WRITE(s,string'("RCV Data["));
      WRITE(s,n);
      WRITE(s,string'("]="));
      HWRITE(s,buffer1(n));
      report s.all;
		end loop;
 
--	  repeat(5)	@(posedge clk);
    wait for 1 us;
 
	  send_token(	fa,		-- Function Address
			X"00",		      -- Logical Endpoint Number
			USBF_T_PID_ACK	-- PID
		);
 
--	  repeat(5)	@(posedge clk);
    wait for 1 us;
  end procedure data_in;  
 
  procedure data_out(fa:std_logic_vector(7 downto 0); pl_size:integer) is
    variable len : integer;
  begin
	  send_token(	fa,		-- Function Address
			X"00",          -- Logical Endpoint Number
			USBF_T_PID_OUT	-- PID
			);
    wait until rising_edge(usbclk);
 
	  if (setup_pid='0') then
	  	send_data(USBF_T_PID_DATA0, pl_size, 1);
	  else
	    send_data(USBF_T_PID_DATA1, pl_size, 1);
    end if;
 
	  setup_pid := not(setup_pid);
 
	  -- Wait for ACK
 
	  utmi_recv_pack(len);
 
	  if(txmem(0) /= X"d2") then
			--$display("ERROR: ACK mismatch. Expected: %h, Got: %h (%t)",8'hd2, txmem[0], $time);
      report "ERROR: SETUP: ACK mismatch";
		  error_cnt := error_cnt + 1;
	  end if;
 
	  if(len /= 1) then
		  --$display("ERROR: SETUP: Length mismatch. Expected: %h, Got: %h (%t)",8'h1, len, $time);
      report "ERROR: SETUP: Length mismatch";
		  error_cnt := error_cnt + 1;
	  end if;
 
		-- repeat(5)	@(posedge clk);
	  wait for 1 us;
  end procedure data_out;  
 
  procedure send_setup (constant fa:std_logic_vector(7 downto 0);
                        constant req_type:std_logic_vector(7 downto 0);
                        constant request:std_logic_vector(7 downto 0);
                        constant wValue:std_logic_vector(15 downto 0);
                        constant wIndex:std_logic_vector(15 downto 0);
                        constant wLength:std_logic_vector(15 downto 0)) is
  begin
    send_token(fa,X"0",USBF_T_PID_SETUP);
    wait for 1 us;
    buffer1(0) := req_type;
    buffer1(1) := request;
    buffer1(3) := wValue(15 downto 8);
    buffer1(2) := wValue(7 downto 0);
    buffer1(5) := wIndex(15 downto 8);
    buffer1(4) := wIndex(7 downto 0);
    buffer1(7) := wLength(15 downto 8);
    buffer1(6) := wLength(7 downto 0);
    buffer1_last := 0;
    send_data(USBF_T_PID_DATA0, 8, 1);
    utmi_recv_pack(len);
    if (txmem(0) /= x"d2") then
      --$display("ERROR: SETUP: ACK mismatch. Expected: %h, Got: %h (%t)",	8'hd2, txmem[0], $time);
      report "ERROR: SETUP: ACK mismatch";
      error_cnt := error_cnt + 1;      
    end if;
    if (len /= 1) then
	    --$display("ERROR: SETUP: Length mismatch. Expected: %h, Got: %h (%t)", 8'h1, len, $time);    
      report "ERROR: SETUP: Length mismatch. len="&integer'image(len);
      error_cnt := error_cnt + 1;      
    end if;  
 
    wait until rising_edge(usbclk);
    setup_pid := '1';
    wait until rising_edge(usbclk);
 
  end procedure send_setup;
 
  procedure send_sof(constant frmn:integer) is
    variable frmnv : std_logic_vector(10 downto 0);
    variable tmp_data : std_logic_vector(15 downto 0);
    variable x,y : std_logic_vector(10 downto 0);
  begin
    frmnv := std_logic_vector(to_unsigned(frmn,11));
    y := frmnv;
		x(10) := y(0);
		x(9) := y(1);
		x(8) := y(2);
		x(7) := y(3);
		x(6) := y(4);
		x(5) := y(5);
		x(4) := y(6);
		x(3) := y(7);
		x(2) := y(8);
		x(1) := y(9);
		x(0) := y(10);
 
		tmp_data(15 downto 5) := x;
		y(4 downto 0)  := crc5( X"1F", x );
		tmp_data(4 downto 0)  := not(y(4 downto 0));
		txmem(0) := not(USBF_T_PID_SOF)&USBF_T_PID_SOF;	-- PID
    txmem(1) :=  	tmp_data(8)&tmp_data(9)&tmp_data(10)&tmp_data(11)&
                  tmp_data(12)&tmp_data(13)&tmp_data(14)&tmp_data(15);
    txmem(2) :=  	tmp_data(0)&tmp_data(1)&tmp_data(2)&tmp_data(3)&
		              tmp_data(4)&tmp_data(5)&tmp_data(6)&tmp_data(7);
    txmem(1) := 	frmnv(7 downto 0);
    txmem(2) :=  	tmp_data(0)&tmp_data(1)&tmp_data(2)&tmp_data(3)&
		              tmp_data(4)& frmnv(10 downto 8);
    utmi_send_pack(3,usbtxdata,usbtxvalid);
  end procedure send_sof;
 
 
  procedure buswrite(constant adr : in std_logic_vector(31 downto 0);
                     constant data : in std_logic_vector(31 downto 0);
                     signal Bus2IP_Clk : in std_logic;
                     signal Bus2IP_Addr : out std_logic_vector(0 to 31);
                     signal Bus2IP_Data : out std_logic_vector(0 to 31);
                     signal Bus2IP_BE : out std_logic_vector(0 to 3);
                     signal Bus2IP_CS : out std_logic;
                     signal Bus2IP_CE : out std_logic;
                     signal Bus2IP_RNW : out std_logic;
                     signal IP2Bus_Data : in std_logic_vector(0 to 31);                     
                     signal IP2Bus_Ack : in std_logic) is
  begin  	
  	wait until (Bus2IP_Clk='1' and Bus2IP_Clk'event);
  	wait for 1 ns;
  	Bus2IP_Addr <= adr;
  	Bus2IP_Data <= data;
  	Bus2IP_RNW <= '0';
  	Bus2IP_CE <= '1';
  	Bus2IP_CS <= '1';
  	Bus2IP_BE <= "1111";
  	wait until (Bus2IP_Clk'event and Bus2IP_Clk='1' and IP2Bus_Ack='1');
  	wait for 1 ns;
  	Bus2IP_Addr <= (others=>'0');
  	Bus2IP_Data <= (others=>'0');
  	Bus2IP_RNW <= '0';
  	Bus2IP_CE <= '0';  	
  	Bus2IP_CS <= '0';
  	Bus2IP_BE <= "0000";
  end buswrite; 
 
  procedure busread (constant adr : in std_logic_vector(31 downto 0);
                     variable data : out std_logic_vector(31 downto 0);
                     signal Bus2IP_Clk : in std_logic;
                     signal Bus2IP_Addr : out std_logic_vector(0 to 31);
                     signal Bus2IP_Data : out std_logic_vector(0 to 31);
                     signal Bus2IP_BE : out std_logic_vector(0 to 3);
                     signal Bus2IP_CS : out std_logic;
                     signal Bus2IP_CE : out std_logic;
                     signal Bus2IP_RNW : out std_logic;
                     signal IP2Bus_Data : in std_logic_vector(0 to 31);
                     signal IP2Bus_Ack : in std_logic) is
  begin  	
  	wait until (Bus2IP_Clk='1' and Bus2IP_Clk'event);
  	wait for 1 ns;
  	Bus2IP_Addr <= adr;
  	Bus2IP_Data <= (others=>'0');
  	Bus2IP_RNW <= '1';
  	Bus2IP_CS <= '1';
  	Bus2IP_CE <= '1';
  	Bus2IP_BE <= "1111";
  	wait until (Bus2IP_Clk'event and Bus2IP_Clk='1' and IP2Bus_Ack='1');
  	data := IP2Bus_Data;
  	wait for 1 ns;
  	Bus2IP_Addr <= (others=>'0');
  	Bus2IP_Data <= (others=>'0');
  	Bus2IP_RNW <= '0';
  	Bus2IP_CS <= '0';  	
  	Bus2IP_CE <= '0';  	
  	Bus2IP_BE <= "0000";
  end busread; 
 
  procedure uartread (variable d : out std_logic_vector (7 downto 0)) is
    variable tmp : std_logic_vector(31 downto 0);
--    variable ss : LINE;    
  begin
    loop
       busread(X"00000002", tmp, clk, Bus2IP_Addr, Bus2IP_Data, Bus2IP_BE, Bus2IP_CS, Bus2IP_CE, Bus2IP_RNW, IP2Bus_Data, IP2Bus_Ack);
       exit when ((tmp and X"00000001") /= X"00000000");
    end loop;
--      DEALLOCATE(ss);
--      WRITE(ss,string'("uartstatus="));
--      HWRITE(ss,tmp);
--      report ss.all;    
    busread(X"00000000", tmp, clk, Bus2IP_Addr, Bus2IP_Data, Bus2IP_BE, Bus2IP_CS, Bus2IP_CE, Bus2IP_RNW, IP2Bus_Data, IP2Bus_Ack);
    d := tmp(7 downto 0);
  end procedure uartread;
 
  procedure uartwrite (variable d : std_logic_vector (7 downto 0)) is
    variable tmp : std_logic_vector(31 downto 0);
  begin
    loop
       busread(X"00000002", tmp, clk, Bus2IP_Addr, Bus2IP_Data, Bus2IP_BE, Bus2IP_CS, Bus2IP_CE, Bus2IP_RNW, IP2Bus_Data, IP2Bus_Ack);
       exit when ((tmp and X"00000004") /= X"00000000");
    end loop;
    tmp := X"00000000";
    tmp(7 downto 0) := d;    
    buswrite(X"00000001", tmp, clk, Bus2IP_Addr, Bus2IP_Data, Bus2IP_BE, Bus2IP_CS, Bus2IP_CE, Bus2IP_RNW, IP2Bus_Data, IP2Bus_Ack);
 
  end procedure uartwrite;
 
  shared variable nn : integer;
  shared variable pid : std_logic_vector(3 downto 0); 
  shared variable ss : LINE;
  shared variable dd : std_logic_vector(7 downto 0);
  shared variable rlen : integer;
begin
 
 
  resetn <= not(reset);
  rxd <= rxdp;
 
  usb_phy_inst : usb_phy
      port map (
      clk => usbclk,
      rst => resetn,
      phy_tx_mode => '1',
      usb_rst => open,
		  txdp => rxdp,
		  txdn => rxdn,
		  txoe => open,
		  rxd => txdp,
		  rxdp => txdp,
		  rxdn => txdn,
 
		-- UTMI Interface
		  DataOut_i => usbtxdata,
		  TxValid_i => usbtxvalid,
		  TxReady_o => usbtxready,
		  RxValid_o => usbrxvalid,
		  RxActive_o => usbrxactive,
		  RxError_o => usbrxerror,
		  DataIn_o => usbrxdata,
		  LineState_o => usblinestate
    );
 
 
  OPB_USBLITE_Core_inst : OPB_USBLITE_Core
  port map (
    Clk   => clk,
    Reset => reset,
    Usb_Clk => usbclk,
    OPB_CS => Bus2IP_CS,
    OPB_ABus => Bus2IP_Addr(30 to 31),
    OPB_RNW  => Bus2IP_RNW,
    OPB_DBus => Bus2IP_Data(24 to 31),
    SIn_xferAck => IP2Bus_Ack,
    SIn_DBus => IP2Bus_Data(24 to 31),
    Interrupt => Interrupt,
		txdp => txdp,
		txdn => txdn,
		txoe => txoe,
		rxd => rxd,
		rxdp => rxdp,
		rxdn => rxdn
  );
 
 
  process
  begin
    clk <= '0';
    wait for 6.66666ns;
    clk <= '1';
    wait for 6.66666ns;
  end process;
 
  process
  begin
    usbclk <= '0';
    wait for 10.41666ns;
    usbclk <= '1';
    wait for 10.41666ns;
  end process;
 
  process(usbclk)
  begin
    if (usbclk'event and usbclk='1') then
      if (usbrxvalid='1') then
        usbrxdata_r <= usbrxdata;
      end if;
    end if;
  end process;
 
  process
  begin
    wait for 100ns;
    reset <= '1';
    wait for 100ns;
    reset <= '0';
    wait for 100 us;
 
 report "Setting Address ...";
    wait for 1 us;
    send_setup(	X"00", 		-- Function Address
		X"00",		            -- Request Type
		SET_ADDRESS,	        -- Request
		X"0012",	            -- wValue
		X"0000",		          -- wIndex
		X"0000"		            -- wLength
		);
 
-- Status OK		
		data_in(	X"00",		-- Function Address
		0		                -- Expected payload size
	  );
 
 report("Getting DEVICE descriptor ...");
    send_setup(	X"12", 		-- Function Address
		X"80",		            -- Request Type
		GET_DESCRIPTOR,	      -- Request
		X"0100",	            -- wValue
		X"0000",	            -- wIndex
		X"0008"		            -- wLength
		);
 
    data_in(	X"12",		-- Function Address
		8		                -- Expected payload size
		);
 
-- Status OK
    data_out(	X"12",		-- Function Address
		0   		            -- Expected payload size
	  );
 
 report("Getting whole DEVICE descriptor ...");
    send_setup(	X"12", 		-- Function Address
		X"80",		            -- Request Type
		GET_DESCRIPTOR,	      -- Request
		X"0100",	            -- wValue
		X"0000",	            -- wIndex
		X"0012"		            -- wLength
		);
 
    data_in(	X"12",		-- Function Address
		18	                -- Expected payload size
		);
 
-- Status OK
    data_out(	X"12",		-- Function Address
		0   		            -- Expected payload size
	  );
 
report "Getting CONFIGURATION descriptor ...";
    send_setup(	X"12", 		-- Function Address
		X"80",		            -- Request Type
		GET_DESCRIPTOR,	      -- Request
		X"0200",	            -- wValue
		X"0000",	            -- wIndex
		X"0008"	              -- wLength
		);
 
    data_in(	X"12",	    -- Function Address
		8		                  -- Expected payload size
	  );
 
-- Status OK
    data_out(	X"12",		  -- Function Address
		0	    	              -- Expected payload size
	  );
 
report "Getting whole CONFIGURATION descriptor ...";
		send_setup(	X"12", 		-- Function Address
		X"80",		            -- Request Type
		GET_DESCRIPTOR,	      -- Request
		X"0200",	            -- wValue
		X"0000",              -- wIndex
		X"0043"		            -- wLength
		);
 
    data_in(	X"12",		  -- Function Address
		64 	    	            -- Expected payload size
	  );
 
-- Status OK
    data_out(	X"12",		  -- Function Address
		0		                  -- Expected payload size
	  );
 
    data_in(	X"12",		  -- Function Address
		3 	    	            -- Expected payload size
	  );
 
-- Status OK
    data_out(	X"12",		  -- Function Address
		0		                  -- Expected payload size
	  );
 
report "Set configuration 1...";	  
		send_setup(	X"12", 		-- Function Address
		X"00",		            -- Request Type
		SET_CONFIG,           -- Request
		X"0001",	            -- wValue
		X"0000",              -- wIndex
		X"0000"		            -- wLength
		);
 
    data_in(	X"12",		  -- Function Address
		0 	    	            -- Expected payload size
	  );
 
    wait for 1 us;
 
report "EP1 OUT...";	  
	  for nn in 0 to 63 loop
		  buffer1(nn) := std_logic_vector(to_unsigned(nn+32,8));
    end loop;
	  buffer1_last := 0;
	  pid := "0000";
 
	  send_sof(0);	 -- Send SOF
	  wait until rising_edge(usbclk);
 
	  send_token(	X"12",	-- Function Address
			X"1",             -- Logical Endpoint Number
			USBF_T_PID_OUT	  -- PID
			);
 
	  wait until rising_edge(usbclk);
 
	  if (pid="0000")	then
	    send_data(USBF_T_PID_DATA0, 64, 1);
	  else
	    send_data(USBF_T_PID_DATA1, 64, 1);
	  end if;
 
	  pid := not(pid);
 
    -- Wait for ACK
	  utmi_recv_pack(len);		
 
		for nn in 0 to 63 loop
		  uartread(dd);
      DEALLOCATE(ss);
      WRITE(ss,string'("uartread="));
      HWRITE(ss,dd);
      report ss.all;		  
		end loop;
 
    wait for 1 us;
 
report "EP1 IN...";	
 
		for nn in 0 to 63 loop
	    dd := std_logic_vector(to_unsigned(nn,8));
      DEALLOCATE(ss);
      WRITE(ss,string'("uartwrite="));
      HWRITE(ss,dd);
      report ss.all;		  
		  uartwrite(dd);
		end loop;
 
 
	-- Send Data
	  send_sof(1);	        -- Send SOF
	  send_token(	X"12",		-- Function Address
			X"1",		            -- Logical Endpoint Number
			USBF_T_PID_IN	      -- PID
			);
 
	   recv_packet(pid,rlen);
 
	  for nn in 0 to 63 loop
	    dd := txmem(nn+1);
      DEALLOCATE(ss);
      WRITE(ss,string'("usb recv="));
      HWRITE(ss,dd);
      report ss.all;		  
    end loop;	  
 
	  send_token(	X"12",		-- Function Address
			X"1",		            -- Logical Endpoint Number
			USBF_T_PID_ACK	    -- PID
			);    
 
		wait for 10us;
 
		reset <= '1';
		wait for 1us;
		reset <= '0';
 
    wait;
  end process;
 
 
end architecture akre;
 

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.