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

Subversion Repositories usb11_sim_model

[/] [usb11_sim_model/] [trunk/] [USB_FS_master.vhd] - Blame information for rev 3

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 M_artin
--==========================================================================================================--
2
--                                                                                                          --
3
--  Copyright (C) 2011  by  Martin Neumann martin@neumanns-mail.de                                          --
4
--                                                                                                          --
5
--  This source file may be used and distributed without restriction provided that this copyright statement --
6
--  is not removed from the file and that any derivative work contains the original copyright notice and    --
7
--  the associated disclaimer.                                                                              --
8
--                                                                                                          --
9
--  This software is provided ''as is'' and without any express or implied warranties, including, but not   --
10 3 M_artin
--  limited to, the implied warranties of merchantability and fitness for a particular purpose. In no event --
11 2 M_artin
--  shall the author or contributors be liable for any direct, indirect, incidental, special, exemplary, or --
12
--  consequential damages (including, but not limited to, procurement of substitute goods or services; loss --
13
--  of use, data, or profits; or business interruption) however caused and on any theory of liability,      --
14
--  whether in  contract, strict liability, or tort (including negligence or otherwise) arising in any way  --
15
--  out of the use of this software, even if advised of the possibility of such damage.                     --
16
--                                                                                                          --
17
--==========================================================================================================--
18
--                                                                                                          --
19
--  File name   : usb_fs_master.vhd                                                                         --
20
--  Author      : Martin Neumann  martin@neumanns-mail.de                                                   --
21
--  Description : USB FS Master, used with usb_Stimuli.vhd data source and usb_fs_monitor.vhd.              --
22
--                                                                                                          --
23
--==========================================================================================================--
24
--                                                                                                          --
25
-- Change history                                                                                           --
26
--                                                                                                          --
27
-- Version / date        Description                                                                        --
28
--                                                                                                          --
29
-- 01  05 Mar 2011 MN    Initial version                                                                    --
30 3 M_artin
-- 02  01 Nov 2011 MN    Removed application specific interface, gererate 12 MHz clk internally             --
31 2 M_artin
--                                                                                                          --
32
-- End change history                                                                                       --
33
--==========================================================================================================--
34
--                                                                                                          --
35
-- http://en.wikipedia.org/wiki/Universal_Serial_Bus                                                        --
36
-- USB  data is transmitted by  toggling the data lines between the J state and the opposite K state. USB   --
37
-- encodes data using the  NRZI convention; a 0 bit is transmitted by toggling the data lines from J to K   --
38
-- or vice-versa, while a 1 bit is transmitted by leaving the data lines as-is.                             --
39
-- To ensure a minimum density of signal transitions, USB  uses bit stuffing - an extra 0 bit is inserted   --
40
-- into the data stream after any appearance of six consecutive 1 bits. Seven consecutive '1's are always   --
41
-- an error.                                                                                                --
42
-- A USB packet begins with an 8-bit synchronization sequence '00000001'. That is, after the initial idle   --
43
-- state J, the data lines  toggle KJKJKJKK. The final 1 bit (repeated K state) marks the end of the sync   --
44
-- pattern  and the beginning of the USB frame. For high bandwidth  USB, the packet  begins with a 32-bit   --
45
-- synchronization sequence.                                                                                --
46
-- A USB packet's end, called EOP (end-of-packet), is indicated by the transmitter driving 2 bit times of   --
47
-- SE0 (D+ and D- both below max) and 1 bit time of J state.  After this, the transmitter ceases to drive   --
48
-- the D+/D- lines and the aforementioned pull up resistors hold it in the J (idle) state. Sometimes skew   --
49
-- due to hubs can add as much as one bit time before the SE0 of the end of packet.                         --
50
-- This  extra bit  can result in a "bit stuff violation" if  the six bits before it  in the CRC are '1's.  --
51
-- This bit should be ignored by receiver.                                                                  --
52
-- A USB bus is reset using a prolonged (10 to 20 milliseconds) SE0 signal.                                 --
53
--                                                                                                          --
54
--==========================================================================================================--
55
 
56
LIBRARY IEEE;
57
  USE IEEE.std_logic_1164.all;
58
  USE IEEE.std_logic_textio.all;
59
  USE std.textio.all;
60
 
61
LIBRARY work;
62
  USE work.usb_commands.all;
63
 
64
ENTITY usb_fs_master IS PORT(
65
  rst_neg_ext     : OUT   STD_LOGIC;
66
  usb_Dp          : INOUT STD_LOGIC;
67 3 M_artin
  usb_Dn          : INOUT STD_LOGIC
68
);
69 2 M_artin
END usb_fs_master;
70
 
71
ARCHITECTURE SIM OF usb_fs_master IS
72
 
73
  SIGNAL T_No           : NATURAL;
74 3 M_artin
  SIGNAL usb_clk        : STD_LOGIC;
75 2 M_artin
  SIGNAL crc_16         : STD_LOGIC_VECTOR(15 DOWNTO 0);
76
  SIGNAL crc_5          : STD_LOGIC_VECTOR( 4 DOWNTO 0);
77
  SIGNAL master_oe      : STD_LOGIC;
78
  SIGNAL stimuli_bit    : STD_LOGIC := 'Z';
79
  SIGNAL stuffing_requ  : BOOLEAN;
80
  SIGNAL usb_request    : usb_action;
81
 
82
  function next_CRC_5 (Data: std_logic; crc:  std_logic_vector(4 downto 0)) return std_logic_vector is
83
    -- Copyright (C) 1999-2008 Easics NV. http://www.easics.com/webtools/crctool
84 3 M_artin
    variable d:       std_logic;
85
    variable c:       std_logic_vector(4 downto 0);
86 2 M_artin
    variable new_crc: std_logic_vector(4 downto 0);
87
  begin
88
    d          := Data;
89
    c          := crc;
90
    new_crc(0) := d xor c(4);
91
    new_crc(1) := c(0);
92
    new_crc(2) := d xor c(1) xor c(4);
93
    new_crc(3) := c(2);
94
    new_crc(4) := c(3);
95
    return new_crc;
96
  end next_CRC_5;
97
 
98
  function next_CRC_16 (Data: std_logic; crc:  std_logic_vector(15 downto 0)) return std_logic_vector is
99
    -- Copyright (C) 1999-2008 Easics NV. http://www.easics.com/webtools/crctool
100
    variable d:      std_logic;
101
    variable c:      std_logic_vector(15 downto 0);
102
    variable new_crc: std_logic_vector(15 downto 0);
103
  begin
104
    d                     := Data;
105
    c                     := crc;
106
    new_crc(0)            := d xor c(15);
107
    new_crc(1)            := c(0);
108
    new_crc(2)            := d xor c(1) xor c(15);
109
    new_crc(14 DOWNTO 3)  := c(13 DOWNTO 2);
110
    new_crc(15)           := d xor c(14) xor c(15);
111
    return new_crc;
112
  end next_CRC_16;
113
 
114
  FUNCTION nrzi(data_bit, last_level : std_logic) RETURN STD_LOGIC IS
115
  BEGIN
116
    IF data_bit = '0' THEN
117
      RETURN not last_level;
118
    ELSE
119
      RETURN last_level;
120
    END IF;
121
  END nrzi;
122
 
123
--==========================================================================================================--
124
 
125
begin
126
 
127 3 M_artin
  p_usb_clk : PROCESS
128
  BEGIN
129
    usb_clk <= '0';
130
    WAIT FOR 20866 ps;
131
    usb_clk <= '1';
132
    WAIT FOR 41600 ps;
133
    usb_clk <= '0';
134
    WAIT FOR 20867 ps;
135
  END PROCESS;
136
 
137 2 M_artin
  test_case : ENTITY work.usb_stimuli
138
  PORT MAP(
139
    usb         => usb_request,
140
    rst_neg_ext => rst_neg_ext,
141 3 M_artin
    T_No        => T_No
142 2 M_artin
  );
143
 
144
  usb_fs_monitor : ENTITY work.usb_fs_monitor
145
  port map (
146
    master_oe   => master_oe,
147
    usb_Dp      => usb_dp,
148
    usb_Dn      => usb_dn
149
  );
150
 
151
  master_oe <= '0' WHEN usb_request = idle OR usb_request = recv_eop ELSE '1';
152
 
153
  p_usb_data : PROCESS
154
    VARIABLE d_new    : STD_LOGIC;
155
    VARIABLE ones_cnt : NATURAL;
156
  BEGIN
157
    WAIT UNTIL rising_edge(usb_clk);
158
    stuffing_requ <= FALSE;
159
    IF stimuli_bit = 'L' THEN
160
      usb_Dp <= '0';
161
      usb_Dn <= '0';
162
    ELSIF stimuli_bit = 'Z' THEN
163
      usb_Dp <= 'Z';
164
      usb_Dn <= 'L';
165
    ELSIF stimuli_bit = '1' THEN
166
      ones_cnt := ones_cnt +1;
167
      d_new  := nrzi('1', usb_Dp);
168
      usb_Dp <= d_new;
169
      usb_Dn <= not d_new;
170
      IF ones_cnt = 6 THEN   -- add stuffing bit
171
        stuffing_requ <= TRUE;
172
        ones_cnt := 0;
173
        WAIT UNTIL rising_edge(usb_clk);
174
        stuffing_requ <= FALSE;
175
        d_new  := nrzi('0', usb_Dp);
176
        usb_Dp <= d_new;
177
        usb_Dn <= not d_new;
178
      END IF;
179
    ELSE
180
      ones_cnt := 0;
181
      d_new  := nrzi('0', usb_Dp);
182
      usb_Dp <= d_new;
183
      usb_Dn <= not d_new;
184
    END IF;
185
  END PROCESS;
186
 
187
  p_stimuli_bit : PROCESS                                        --always transfer LSB first (exception crc)
188
    CONSTANT sync_data : std_logic_vector(7 DOWNTO 0) := X"80";  --USB FS : sync patter is KJKJKJKK
189
    CONSTANT eop_data  : std_logic_vector(3 DOWNTO 0) := "Z0LL"; --'L' forces both usb_up, usb_dn low !!
190
  BEGIN
191
    WAIT ON usb_request;
192
    IF usb_request = reset THEN
193
      usb_status <= usb_request;
194
      stimuli_bit <= 'L';
195
      WAIT FOR 5 us;
196
      WAIT UNTIL rising_edge(usb_clk);
197
      stimuli_bit <= 'Z';
198
      usb_status <= idle;
199
    ELSIF usb_request = sync THEN
200
      usb_status <= usb_request;
201
      FOR i IN 0 TO 7  LOOP -- Sync pattern
202
        WAIT UNTIL rising_edge(usb_clk);
203
        stimuli_bit <= sync_data(i);
204
      END LOOP;
205
      usb_status <= idle;
206
    ELSIF usb_request = pid THEN
207
      usb_status <= usb_request;
208
      FOR i IN 0 TO 7  LOOP
209
        WAIT UNTIL rising_edge(usb_clk) AND NOT stuffing_requ;
210
        stimuli_bit <= sv_usb_byte(i);
211
      END LOOP;
212
      crc_5   <= (others =>'1');
213
      crc_16  <= (others =>'1');
214
      usb_status <= idle;
215
    ELSIF usb_request = addr THEN
216
      usb_status <= usb_request;
217
      FOR i IN 0 TO 10 LOOP
218
        WAIT UNTIL rising_edge(usb_clk) AND NOT stuffing_requ;
219
        stimuli_bit <= sv_usb_addr(i);
220
        crc_5  <= next_crc_5(sv_usb_addr(i),crc_5);
221
      END LOOP;
222
      usb_status <= idle;
223
    ELSIF usb_request = wr_odd OR usb_request = wr_even THEN
224
      usb_status <= usb_request;
225
      FOR i IN 0 TO 7 LOOP
226
        WAIT UNTIL rising_edge(usb_clk) AND NOT stuffing_requ;
227
        stimuli_bit <= sv_usb_byte(i);
228
        crc_16  <= next_crc_16(sv_usb_byte(i),crc_16);
229
      END LOOP;
230
      usb_status <= idle;
231
   --   WAIT for 1 ns;
232
    ELSIF usb_request = wr_crc5 THEN
233
      usb_status <= usb_request;
234
      FOR i IN 4 DOWNTO 0 LOOP   -- Token crc5, LSB last
235
        WAIT UNTIL rising_edge(usb_clk) AND NOT stuffing_requ;
236
        stimuli_bit <= NOT crc_5(i);
237
      END LOOP;
238
      usb_status <= idle;
239
    ELSIF usb_request = wr_crc16 THEN
240
      usb_status <= usb_request;
241
      FOR i IN 15 DOWNTO 0 LOOP  -- Data crc16, LSB last
242
        WAIT UNTIL rising_edge(usb_clk) AND NOT stuffing_requ;
243
        stimuli_bit <= NOT crc_16(i);
244
      END LOOP;
245
      usb_status <= idle;
246
    ELSIF usb_request = send_eop THEN
247
      usb_status <= usb_request;
248
      FOR i IN 0 TO 3 LOOP
249
        WAIT UNTIL rising_edge(usb_clk) AND NOT stuffing_requ;
250
        stimuli_bit <= eop_data(i);
251
      END LOOP;
252
      usb_status <= idle;
253
    ELSIF usb_request = Recv_eop THEN
254
      usb_status <= usb_request;
255
      WAIT UNTIL rising_edge(usb_clk) AND usb_Dp ='0' AND usb_Dn ='0';
256
      WAIT FOR 400 ns;
257
      usb_status <= idle;
258
    ELSE
259
      stimuli_bit <= 'Z';
260
      usb_status <= idle;
261
    END IF;
262
  END PROCESS;
263
 
264
END SIM;
265
 
266
--======================================== END OF usb_fs_master.vhd ========================================--

powered by: WebSVN 2.1.0

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