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

Subversion Repositories usb11_phy_translation

[/] [usb11_phy_translation/] [trunk/] [usb_rx_phy.vhdl] - Blame information for rev 2

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

Line No. Rev Author Line
1 2 M_artin
--======================================================================================--
2
--          Verilog to VHDL conversion by Martin Neumann martin@neumnns-mail.de         --
3
--                                                                                      --
4
--          ///////////////////////////////////////////////////////////////////         --
5
--          //                                                               //         --
6
--          //  USB 1.1 PHY                                                  //         --
7
--          //  RX & DPLL                                                    //         --
8
--          //                                                               //         --
9
--          //                                                               //         --
10
--          //  Author: Rudolf Usselmann                                     //         --
11
--          //          rudi@asics.ws                                        //         --
12
--          //                                                               //         --
13
--          //                                                               //         --
14
--          //  Downloaded from: http://www.opencores.org/cores/usb_phy/     //         --
15
--          //                                                               //         --
16
--          ///////////////////////////////////////////////////////////////////         --
17
--          //                                                               //         --
18
--          //  Copyright (C) 2000-2002 Rudolf Usselmann                     //         --
19
--          //                          www.asics.ws                         //         --
20
--          //                          rudi@asics.ws                        //         --
21
--          //                                                               //         --
22
--          //  This source file may be used and distributed without         //         --
23
--          //  restriction provided that this copyright statement is not    //         --
24
--          //  removed from the file and that any derivative work contains  //         --
25
--          //  the original copyright notice and the associated disclaimer. //         --
26
--          //                                                               //         --
27
--          //      THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY      //         --
28
--          //  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED    //         --
29
--          //  TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS    //         --
30
--          //  FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR       //         --
31
--          //  OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,          //         --
32
--          //  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES     //         --
33
--          //  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE    //         --
34
--          //  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR         //         --
35
--          //  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF   //         --
36
--          //  LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT   //         --
37
--          //  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT   //         --
38
--          //  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE          //         --
39
--          //  POSSIBILITY OF SUCH DAMAGE.                                  //         --
40
--          //                                                               //         --
41
--          ///////////////////////////////////////////////////////////////////         --
42
--======================================================================================--
43
 
44
library ieee;
45
use ieee.std_logic_1164.all;
46
use ieee.std_logic_arith.all;
47
use ieee.std_logic_unsigned.all;
48
 
49
entity usb_rx_phy is
50
  port (
51
    clk             : in  std_logic;
52
    rst             : in  std_logic;
53
    -- Transciever Interface
54
    fs_ce_o         : out std_logic;
55
    rxd, rxdp, rxdn : in  std_logic;
56
    -- UTMI Interface
57
    DataIn_o        : out std_logic_vector(7 downto 0);
58
    RxValid_o       : out std_logic;
59
    RxActive_o      : out std_logic;
60
    RxError_o       : out std_logic;
61
    RxEn_i          : in  std_logic;
62
    LineState       : out std_logic_vector(1 downto 0)
63
  );
64
end usb_rx_phy;
65
 
66
architecture RTL of usb_rx_phy is
67
 
68
  signal fs_ce                              : std_logic;
69
  signal rxd_s0, rxd_s1, rxd_s              : std_logic;
70
  signal rxdp_s0, rxdp_s1, rxdp_s, rxdp_s_r : std_logic;
71
  signal rxdn_s0, rxdn_s1, rxdn_s, rxdn_s_r : std_logic;
72
  signal synced_d                           : std_logic;
73
  signal k, j, se0                          : std_logic;
74
  signal rxd_r                              : std_logic;
75
  signal rx_en                              : std_logic;
76
  signal rx_active                          : std_logic;
77
  signal bit_cnt                            : std_logic_vector(2 downto 0);
78
  signal rx_valid1, rx_valid                : std_logic;
79
  signal shift_en                           : std_logic;
80
  signal sd_r                               : std_logic;
81
  signal sd_nrzi                            : std_logic;
82
  signal hold_reg                           : std_logic_vector(7 downto 0);
83
  signal drop_bit                           : std_logic;    -- Indicates a stuffed bit
84
  signal one_cnt                            : std_logic_vector(2 downto 0);
85
  signal dpll_state, dpll_next_state        : std_logic_vector(1 downto 0);
86
  signal fs_ce_d                            : std_logic;
87
  signal change                             : std_logic;
88
  signal lock_en                            : std_logic;
89
  signal fs_state, fs_next_state            : std_logic_vector(2 downto 0);
90
  signal rx_valid_r                         : std_logic;
91
  signal sync_err_d, sync_err               : std_logic;
92
  signal bit_stuff_err                      : std_logic;
93
  signal se0_r, byte_err                    : std_logic;
94
  signal se0_s                              : std_logic;
95
  signal fs_ce_r1, fs_ce_r2                 : std_logic;
96
 
97
  constant FS_IDLE  : std_logic_vector(2 downto 0) := "000";
98
  constant K1       : std_logic_vector(2 downto 0) := "001";
99
  constant J1       : std_logic_vector(2 downto 0) := "010";
100
  constant K2       : std_logic_vector(2 downto 0) := "011";
101
  constant J2       : std_logic_vector(2 downto 0) := "100";
102
  constant K3       : std_logic_vector(2 downto 0) := "101";
103
  constant J3       : std_logic_vector(2 downto 0) := "110";
104
  constant K4       : std_logic_vector(2 downto 0) := "111";
105
 
106
begin
107
 
108
  --====================================================================================--
109
  -- Misc Logic                                                                         --
110
  --====================================================================================--
111
 
112
  fs_ce_o    <= fs_ce;
113
  RxActive_o <= rx_active;
114
  RxValid_o  <= rx_valid;
115
  RxError_o  <= sync_err or bit_stuff_err or byte_err;
116
  DataIn_o   <= hold_reg;
117
  LineState  <= rxdn_s1 & rxdp_s1;
118
 
119
  p_rx_en: process (clk)
120
  begin
121
    if rising_edge(clk) then
122
      rx_en <= RxEn_i;
123
    end if;
124
  end process;
125
 
126
  p_sync_err: process (clk)
127
  begin
128
    if rising_edge(clk) then
129
      sync_err <= not rx_active and sync_err_d;
130
    end if;
131
  end process;
132
 
133
  --====================================================================================--
134
  -- Synchronize Inputs                                                                 --
135
  --====================================================================================--
136
 
137
  -- First synchronize to the local system clock to
138
  -- avoid metastability outside the sync block (*_s0).
139
  -- Then make sure we see the signal for at least two
140
  -- clock cycles stable to avoid glitches and noise
141
 
142
  p_rxd_s: process (clk) -- Avoid detecting Line Glitches and noise
143
  begin
144
    if rising_edge(clk) then
145
        rxd_s0 <= rxd;
146
        rxd_s1 <= rxd_s0;
147
        if rxd_s0 ='1' and rxd_s1 ='1' then
148
          rxd_s <= '1';
149
        elsif not rxd_s0 ='1' and not rxd_s1 ='1' then
150
          rxd_s <= '0';
151
        end if;
152
    end if;
153
  end process;
154
 
155
  p_rxdp_s: process (clk)
156
  begin
157
    if rising_edge(clk) then
158
      rxdp_s0  <= rxdp;
159
      rxdp_s1  <= rxdp_s0;
160
      rxdp_s_r <= rxdp_s0 and rxdp_s1;
161
      rxdp_s   <= (rxdp_s0 and rxdp_s1) or rxdp_s_r;
162
    end if;
163
  end process;
164
 
165
  p_rxdn_s: process (clk)
166
  begin
167
    if rising_edge(clk) then
168
      rxdn_s0  <= rxdn;
169
      rxdn_s1  <= rxdn_s0;
170
      rxdn_s_r <= rxdn_s0 and rxdn_s1;
171
      rxdn_s   <= (rxdn_s0 and rxdn_s1) or rxdn_s_r;
172
    end if;
173
  end process;
174
 
175
  j   <=     rxdp_s and not rxdn_s;
176
  k   <= not rxdp_s and     rxdn_s;
177
  se0 <= not rxdp_s and not rxdn_s;
178
 
179
  p_se0_s: process (clk)
180
  begin
181
    if rising_edge(clk) then
182
      if fs_ce ='1' then
183
        se0_s   <= se0;
184
      end if;
185
    end if;
186
  end process;
187
 
188
  --====================================================================================--
189
  -- DPLL                                                                               --
190
  --====================================================================================--
191
 
192
  -- This design uses a clock enable to do 12Mhz timing and not a
193
  -- real 12Mhz clock. Everything always runs at 48Mhz. We want to
194
  -- make sure however, that the clock enable is always exactly in
195
  -- the middle between two virtual 12Mhz rising edges.
196
  -- We monitor rxdp and rxdn for any changes and do the appropiate
197
  -- adjustments.
198
  -- In addition to the locking done in the dpll FSM, we adjust the
199
  -- final latch enable to compensate for various sync registers ...
200
 
201
  lock_en <= rx_en; -- Allow clock adjustments only when we are receiving
202
 
203
  p_rxd_r: process (clk)
204
  begin
205
    if rising_edge(clk) then
206
      rxd_r   <= rxd_s;
207
    end if;
208
  end process;
209
 
210
  change  <= rxd_r xor rxd_s; -- Edge detector
211
 
212
  -- DPLL FSM
213
  p_dpll_state: process (clk, rst)
214
  begin
215
    if rst ='0' then
216
      dpll_state <= "01";
217
    elsif rising_edge(clk) then
218
      dpll_state <= dpll_next_state;
219
    end if;
220
  end process;
221
 
222
  p_dpll_next_state: process (dpll_state, lock_en, change)
223
  begin
224
    case (dpll_state) is
225
      when "00" =>
226
        if ((lock_en = '1') and (change = '1')) then
227
          dpll_next_state <= "00";
228
        else
229
          dpll_next_state <= "01";
230
        end if;
231
      when "01" =>
232
        if ((lock_en = '1') and (change = '1')) then
233
          dpll_next_state <= "11";
234
        else
235
          dpll_next_state <= "10";
236
        end if;
237
      when "10" =>
238
        if ((lock_en = '1') and (change = '1')) then
239
          dpll_next_state <= "00";
240
        else
241
          dpll_next_state <= "11";
242
        end if;
243
      when OTHERS =>
244
          dpll_next_state <= "00";
245
    end case;
246
  end process;
247
 
248
  fs_ce_d <= '1' when dpll_state = "01" else '0';
249
 
250
  -- Compensate for sync registers at the input - allign full speed ...
251
  -- ... clock enable to be in the middle between two bit changes :
252
 
253
  p_fs_ce: process (clk)
254
  begin
255
    if rising_edge(clk) then
256
      fs_ce_r1  <= fs_ce_d;
257
      fs_ce_r2  <= fs_ce_r1;
258
      fs_ce <= fs_ce_r2;
259
    end if;
260
  end process;
261
 
262
  --====================================================================================--
263
  -- Find Sync Pattern FSM                                                              --
264
  --====================================================================================--
265
 
266
  p_fs_state: process (clk, rst)
267
  begin
268
    if rst ='0' then
269
      fs_state  <= FS_IDLE;
270
    elsif rising_edge(clk) then
271
      fs_state  <= fs_next_state;
272
    end if;
273
  end process;
274
 
275
  p_fs_next_state: process (fs_state, fs_ce, k, j, rx_en, rx_active, se0, se0_s)
276
  begin
277
    if fs_ce='1' and  rx_active='0' and se0='0' and se0_s='0' then
278
      case fs_state is
279
        when FS_IDLE => if k ='1' and rx_en ='1' then -- 0
280
                          fs_next_state <= K1;
281
                          sync_err_d    <= '0';
282
                        end if;
283
        when K1      => if j ='1' and rx_en ='1' then -- 1
284
                          fs_next_state <= J1;
285
                          sync_err_d    <= '0';
286
                        else
287
                          fs_next_state <= FS_IDLE;
288
                          sync_err_d    <= '1';
289
                        end if;
290
        when J1      => if k ='1' and rx_en ='1' then -- 2
291
                          fs_next_state <= K2;
292
                          sync_err_d    <= '0';
293
                        else
294
                          fs_next_state <= FS_IDLE;
295
                          sync_err_d    <= '1';
296
                        end if;
297
        when K2      => if j ='1' and rx_en ='1' then -- 3
298
                          fs_next_state <= J2;
299
                          sync_err_d    <= '0';
300
                        else
301
                          fs_next_state <= FS_IDLE;
302
                          sync_err_d    <= '1';
303
                        end if;
304
        when J2      => if k ='1' and rx_en ='1' then -- 4
305
                          fs_next_state <= K3;
306
                          sync_err_d    <= '0';
307
                        else
308
                          fs_next_state <= FS_IDLE;
309
                          sync_err_d    <= '1';
310
                        end if;
311
        when K3      => if j ='1' and rx_en ='1' then -- 5
312
                          fs_next_state <= J3;
313
                          sync_err_d    <= '0';
314
                        elsif k ='1' and rx_en ='1' then  -- Allow missing first K-J
315
                          fs_next_state <= FS_IDLE;
316
                          sync_err_d    <= '0';
317
                        else
318
                          fs_next_state <= FS_IDLE;
319
                          sync_err_d    <= '1';
320
                        end if;
321
        when J3      => if k ='1' and rx_en ='1' then -- 6
322
                          fs_next_state <= K4;
323
                          sync_err_d    <= '0';
324
                        else
325
                          fs_next_state <= FS_IDLE;
326
                          sync_err_d    <= '1';
327
                        end if;
328
        when K4      => if k ='1' and rx_en ='1' then -- 7
329
                          sync_err_d    <= '0';
330
                        else
331
                          sync_err_d    <= '1';
332
                        end if;
333
                        fs_next_state <= FS_IDLE;
334
        when others  => fs_next_state <= FS_IDLE;
335
                        sync_err_d    <= '1';
336
      end case;
337
    else
338
      fs_next_state <= fs_state;
339
      sync_err_d    <= '0';
340
    end if;
341
  end process;
342
 
343
  synced_d   <= fs_ce and rx_en when (fs_state =K3 and k ='1') or  -- Allow missing first K-J
344
                                     (fs_state =K4 and k ='1') else '0';
345
 
346
  --====================================================================================--
347
  -- Generate RxActive                                                                  --
348
  --====================================================================================--
349
 
350
  p_rx_active: process (clk, rst)
351
  begin
352
    if rst ='0' then
353
      rx_active   <= '0';
354
    elsif rising_edge(clk) then
355
      if synced_d ='1' and rx_en ='1' then
356
        rx_active <= '1';
357
      elsif se0 ='1' and rx_valid_r ='1' then
358
        rx_active <= '0';
359
      end if;
360
    end if;
361
  end process;
362
 
363
  p_rx_valid_r: process (clk)
364
  begin
365
    if rising_edge(clk) then
366
      if rx_valid ='1' then
367
        rx_valid_r      <= '1';
368
      elsif fs_ce ='1' then
369
        rx_valid_r      <= '0';
370
      end if;
371
    end if;
372
  end process;
373
 
374
  --====================================================================================--
375
  -- NRZI Decoder                                                                       --
376
  --====================================================================================--
377
 
378
  p_sd_r: process (clk)
379
  begin
380
    if rising_edge(clk) then
381
      if fs_ce ='1' then
382
        sd_r <= rxd_s;
383
      end if;
384
    end if;
385
  end process;
386
 
387
  p_sd_nrzi: process (clk, rst)
388
  begin
389
    if rst ='0' then
390
      sd_nrzi <= '0';
391
    elsif rising_edge(clk) then
392
      if rx_active ='0' then
393
        sd_nrzi <= '1';
394
      elsif rx_active ='1' and fs_ce ='1' then
395
        sd_nrzi <= not (rxd_s xor sd_r);
396
      end if;
397
    end if;
398
  end process;
399
 
400
  --====================================================================================--
401
  -- Bit Stuff Detect                                                                   --
402
  --====================================================================================--
403
 
404
  p_one_cnt: process (clk, rst)
405
  begin
406
    if rst ='0' then
407
      one_cnt <= "000";
408
    elsif rising_edge(clk) then
409
      if shift_en ='0' then
410
        one_cnt <= "000";
411
      elsif fs_ce ='1' then
412
        if sd_nrzi ='0' or drop_bit ='1' then
413
          one_cnt <= "000";
414
        else
415
          one_cnt <= one_cnt + 1;
416
        end if;
417
      end if;
418
    end if;
419
  end process;
420
 
421
  drop_bit <= '1' when one_cnt ="110" else '0';
422
 
423
  p_bit_stuff_err: process (clk) -- Bit Stuff Error
424
  begin
425
    if rising_edge(clk) then
426
      bit_stuff_err <= drop_bit and sd_nrzi and fs_ce and not se0 and rx_active;
427
    end if;
428
  end process;
429
 
430
  --====================================================================================--
431
  -- Serial => Parallel converter                                                       --
432
  --====================================================================================--
433
 
434
  p_shift_en: process (clk)
435
  begin
436
    if rising_edge(clk) then
437
      if fs_ce ='1' then
438
        shift_en <= synced_d or rx_active;
439
      end if;
440
    end if;
441
  end process;
442
 
443
  p_hold_reg: process (clk)
444
  begin
445
    if rising_edge(clk) then
446
      if fs_ce ='1' and shift_en ='1' and drop_bit ='0' then
447
        hold_reg <= sd_nrzi & hold_reg(7 downto 1);
448
      end if;
449
    end if;
450
  end process;
451
 
452
  --====================================================================================--
453
  -- Generate RxValid                                                                  --
454
  --====================================================================================--
455
 
456
  p_bit_cnt: process (clk, rst)
457
  begin
458
    if rst ='0' then
459
      bit_cnt <= "000";
460
    elsif rising_edge(clk) then
461
      if shift_en ='0' then
462
        bit_cnt <=  "000";
463
      elsif fs_ce ='1' and drop_bit ='0' then
464
        bit_cnt <= unsigned(bit_cnt) + 1;
465
      end if;
466
    end if;
467
  end process;
468
 
469
  p_rx_valid1: process (clk, rst)
470
  begin
471
    if rst ='0' then
472
      rx_valid1 <= '0';
473
    elsif rising_edge(clk) then
474
      if fs_ce ='1' and drop_bit ='0' and bit_cnt ="111" then
475
        rx_valid1 <= '1';
476
      elsif rx_valid1 ='1' and fs_ce ='1' and drop_bit ='0' then
477
        rx_valid1 <= '0';
478
      end if;
479
    end if;
480
  end process;
481
 
482
  p_rx_valid: process (clk)
483
  begin
484
    if rising_edge(clk) then
485
      rx_valid <= not drop_bit and rx_valid1 and fs_ce;
486
    end if;
487
  end process;
488
 
489
  p_se0_r: process (clk)
490
  begin
491
    if rising_edge(clk) then
492
      se0_r <= se0;
493
    end if;
494
  end process;
495
 
496
  p_byte_err: process (clk)
497
  begin
498
    if rising_edge(clk) then
499
      byte_err <= se0 and not se0_r and (bit_cnt(1) or bit_cnt(2)) and rx_active;
500
    end if;
501
  end process;
502
 
503
end RTL;

powered by: WebSVN 2.1.0

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