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 3

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 3 M_artin
--                                                                                      --
44
-- Change history                                                                       --
45
-- +-------+-----------+-------+------------------------------------------------------+ --
46
-- | Vers. | Date      | Autor | Comment                                              | --
47
-- +-------+-----------+-------+------------------------------------------------------+ --
48
-- |  1.0  |04 Feb 2011|  MN   | Initial version                                      | --
49
-- |  1.1  |23 Apr 2011|  MN   | Added 'rst' to most latched signals.                 | --
50
-- |       |           |       | Added ELSE construct in fs_next_state process to     | --
51
-- |       |           |       |   prevent an undesired latch implementation.         | --
52
--======================================================================================--
53 2 M_artin
 
54
library ieee;
55
use ieee.std_logic_1164.all;
56
use ieee.std_logic_arith.all;
57
use ieee.std_logic_unsigned.all;
58
 
59
entity usb_rx_phy is
60
  port (
61
    clk             : in  std_logic;
62
    rst             : in  std_logic;
63
    -- Transciever Interface
64
    fs_ce_o         : out std_logic;
65
    rxd, rxdp, rxdn : in  std_logic;
66
    -- UTMI Interface
67
    DataIn_o        : out std_logic_vector(7 downto 0);
68
    RxValid_o       : out std_logic;
69
    RxActive_o      : out std_logic;
70
    RxError_o       : out std_logic;
71
    RxEn_i          : in  std_logic;
72
    LineState       : out std_logic_vector(1 downto 0)
73
  );
74
end usb_rx_phy;
75
 
76
architecture RTL of usb_rx_phy is
77
 
78
  signal fs_ce                              : std_logic;
79
  signal rxd_s0, rxd_s1, rxd_s              : std_logic;
80
  signal rxdp_s0, rxdp_s1, rxdp_s, rxdp_s_r : std_logic;
81
  signal rxdn_s0, rxdn_s1, rxdn_s, rxdn_s_r : std_logic;
82
  signal synced_d                           : std_logic;
83
  signal k, j, se0                          : std_logic;
84
  signal rxd_r                              : std_logic;
85
  signal rx_en                              : std_logic;
86
  signal rx_active                          : std_logic;
87
  signal bit_cnt                            : std_logic_vector(2 downto 0);
88
  signal rx_valid1, rx_valid                : std_logic;
89
  signal shift_en                           : std_logic;
90
  signal sd_r                               : std_logic;
91
  signal sd_nrzi                            : std_logic;
92
  signal hold_reg                           : std_logic_vector(7 downto 0);
93
  signal drop_bit                           : std_logic;    -- Indicates a stuffed bit
94
  signal one_cnt                            : std_logic_vector(2 downto 0);
95
  signal dpll_state, dpll_next_state        : std_logic_vector(1 downto 0);
96
  signal fs_ce_d                            : std_logic;
97
  signal change                             : std_logic;
98
  signal lock_en                            : std_logic;
99
  signal fs_state, fs_next_state            : std_logic_vector(2 downto 0);
100
  signal rx_valid_r                         : std_logic;
101
  signal sync_err_d, sync_err               : std_logic;
102
  signal bit_stuff_err                      : std_logic;
103
  signal se0_r, byte_err                    : std_logic;
104
  signal se0_s                              : std_logic;
105
  signal fs_ce_r1, fs_ce_r2                 : std_logic;
106
 
107
  constant FS_IDLE  : std_logic_vector(2 downto 0) := "000";
108
  constant K1       : std_logic_vector(2 downto 0) := "001";
109
  constant J1       : std_logic_vector(2 downto 0) := "010";
110
  constant K2       : std_logic_vector(2 downto 0) := "011";
111
  constant J2       : std_logic_vector(2 downto 0) := "100";
112
  constant K3       : std_logic_vector(2 downto 0) := "101";
113
  constant J3       : std_logic_vector(2 downto 0) := "110";
114
  constant K4       : std_logic_vector(2 downto 0) := "111";
115
 
116
begin
117
 
118
  --====================================================================================--
119
  -- Misc Logic                                                                         --
120
  --====================================================================================--
121
 
122
  fs_ce_o    <= fs_ce;
123
  RxActive_o <= rx_active;
124
  RxValid_o  <= rx_valid;
125
  RxError_o  <= sync_err or bit_stuff_err or byte_err;
126
  DataIn_o   <= hold_reg;
127
  LineState  <= rxdn_s1 & rxdp_s1;
128
 
129
  p_rx_en: process (clk)
130
  begin
131
    if rising_edge(clk) then
132
      rx_en <= RxEn_i;
133
    end if;
134
  end process;
135
 
136 3 M_artin
  p_sync_err: process (clk, rst)
137 2 M_artin
  begin
138 3 M_artin
    if rst ='0' then
139
      sync_err <= '0';
140
    elsif rising_edge(clk) then
141 2 M_artin
      sync_err <= not rx_active and sync_err_d;
142
    end if;
143
  end process;
144
 
145
  --====================================================================================--
146
  -- Synchronize Inputs                                                                 --
147
  --====================================================================================--
148
 
149
  -- First synchronize to the local system clock to
150
  -- avoid metastability outside the sync block (*_s0).
151
  -- Then make sure we see the signal for at least two
152
  -- clock cycles stable to avoid glitches and noise
153
 
154
  p_rxd_s: process (clk) -- Avoid detecting Line Glitches and noise
155
  begin
156
    if rising_edge(clk) then
157
        rxd_s0 <= rxd;
158
        rxd_s1 <= rxd_s0;
159
        if rxd_s0 ='1' and rxd_s1 ='1' then
160
          rxd_s <= '1';
161
        elsif not rxd_s0 ='1' and not rxd_s1 ='1' then
162
          rxd_s <= '0';
163
        end if;
164
    end if;
165
  end process;
166
 
167
  p_rxdp_s: process (clk)
168
  begin
169
    if rising_edge(clk) then
170
      rxdp_s0  <= rxdp;
171
      rxdp_s1  <= rxdp_s0;
172
      rxdp_s_r <= rxdp_s0 and rxdp_s1;
173
      rxdp_s   <= (rxdp_s0 and rxdp_s1) or rxdp_s_r;
174
    end if;
175
  end process;
176
 
177
  p_rxdn_s: process (clk)
178
  begin
179
    if rising_edge(clk) then
180
      rxdn_s0  <= rxdn;
181
      rxdn_s1  <= rxdn_s0;
182
      rxdn_s_r <= rxdn_s0 and rxdn_s1;
183
      rxdn_s   <= (rxdn_s0 and rxdn_s1) or rxdn_s_r;
184
    end if;
185
  end process;
186
 
187
  j   <=     rxdp_s and not rxdn_s;
188
  k   <= not rxdp_s and     rxdn_s;
189
  se0 <= not rxdp_s and not rxdn_s;
190
 
191 3 M_artin
  p_se0_s: process (clk, rst)
192 2 M_artin
  begin
193 3 M_artin
    if rst ='0' then
194
      se0_s <= '0';
195
    elsif rising_edge(clk) then
196 2 M_artin
      if fs_ce ='1' then
197
        se0_s   <= se0;
198
      end if;
199
    end if;
200
  end process;
201
 
202
  --====================================================================================--
203
  -- DPLL                                                                               --
204
  --====================================================================================--
205
 
206
  -- This design uses a clock enable to do 12Mhz timing and not a
207
  -- real 12Mhz clock. Everything always runs at 48Mhz. We want to
208
  -- make sure however, that the clock enable is always exactly in
209
  -- the middle between two virtual 12Mhz rising edges.
210
  -- We monitor rxdp and rxdn for any changes and do the appropiate
211
  -- adjustments.
212
  -- In addition to the locking done in the dpll FSM, we adjust the
213
  -- final latch enable to compensate for various sync registers ...
214
 
215
  lock_en <= rx_en; -- Allow clock adjustments only when we are receiving
216
 
217
  p_rxd_r: process (clk)
218
  begin
219
    if rising_edge(clk) then
220
      rxd_r   <= rxd_s;
221
    end if;
222
  end process;
223
 
224
  change  <= rxd_r xor rxd_s; -- Edge detector
225
 
226
  -- DPLL FSM
227
  p_dpll_state: process (clk, rst)
228
  begin
229
    if rst ='0' then
230
      dpll_state <= "01";
231
    elsif rising_edge(clk) then
232
      dpll_state <= dpll_next_state;
233
    end if;
234
  end process;
235
 
236
  p_dpll_next_state: process (dpll_state, lock_en, change)
237
  begin
238
    case (dpll_state) is
239
      when "00" =>
240
        if ((lock_en = '1') and (change = '1')) then
241
          dpll_next_state <= "00";
242
        else
243
          dpll_next_state <= "01";
244
        end if;
245
      when "01" =>
246
        if ((lock_en = '1') and (change = '1')) then
247
          dpll_next_state <= "11";
248
        else
249
          dpll_next_state <= "10";
250
        end if;
251
      when "10" =>
252
        if ((lock_en = '1') and (change = '1')) then
253
          dpll_next_state <= "00";
254
        else
255
          dpll_next_state <= "11";
256
        end if;
257
      when OTHERS =>
258
          dpll_next_state <= "00";
259
    end case;
260
  end process;
261
 
262
  fs_ce_d <= '1' when dpll_state = "01" else '0';
263
 
264
  -- Compensate for sync registers at the input - allign full speed ...
265
  -- ... clock enable to be in the middle between two bit changes :
266
 
267
  p_fs_ce: process (clk)
268
  begin
269
    if rising_edge(clk) then
270
      fs_ce_r1  <= fs_ce_d;
271
      fs_ce_r2  <= fs_ce_r1;
272
      fs_ce <= fs_ce_r2;
273
    end if;
274
  end process;
275
 
276
  --====================================================================================--
277
  -- Find Sync Pattern FSM                                                              --
278
  --====================================================================================--
279
 
280
  p_fs_state: process (clk, rst)
281
  begin
282
    if rst ='0' then
283
      fs_state  <= FS_IDLE;
284
    elsif rising_edge(clk) then
285
      fs_state  <= fs_next_state;
286
    end if;
287
  end process;
288
 
289
  p_fs_next_state: process (fs_state, fs_ce, k, j, rx_en, rx_active, se0, se0_s)
290
  begin
291
    if fs_ce='1' and  rx_active='0' and se0='0' and se0_s='0' then
292
      case fs_state is
293
        when FS_IDLE => if k ='1' and rx_en ='1' then -- 0
294
                          fs_next_state <= K1;
295
                          sync_err_d    <= '0';
296 3 M_artin
                        else
297
                          fs_next_state <= FS_IDLE;
298
                          sync_err_d    <= '0';
299 2 M_artin
                        end if;
300
        when K1      => if j ='1' and rx_en ='1' then -- 1
301
                          fs_next_state <= J1;
302
                          sync_err_d    <= '0';
303
                        else
304
                          fs_next_state <= FS_IDLE;
305
                          sync_err_d    <= '1';
306
                        end if;
307
        when J1      => if k ='1' and rx_en ='1' then -- 2
308
                          fs_next_state <= K2;
309
                          sync_err_d    <= '0';
310
                        else
311
                          fs_next_state <= FS_IDLE;
312
                          sync_err_d    <= '1';
313
                        end if;
314
        when K2      => if j ='1' and rx_en ='1' then -- 3
315
                          fs_next_state <= J2;
316
                          sync_err_d    <= '0';
317
                        else
318
                          fs_next_state <= FS_IDLE;
319
                          sync_err_d    <= '1';
320
                        end if;
321
        when J2      => if k ='1' and rx_en ='1' then -- 4
322
                          fs_next_state <= K3;
323
                          sync_err_d    <= '0';
324
                        else
325
                          fs_next_state <= FS_IDLE;
326
                          sync_err_d    <= '1';
327
                        end if;
328
        when K3      => if j ='1' and rx_en ='1' then -- 5
329
                          fs_next_state <= J3;
330
                          sync_err_d    <= '0';
331
                        elsif k ='1' and rx_en ='1' then  -- Allow missing first K-J
332
                          fs_next_state <= FS_IDLE;
333
                          sync_err_d    <= '0';
334
                        else
335
                          fs_next_state <= FS_IDLE;
336
                          sync_err_d    <= '1';
337
                        end if;
338
        when J3      => if k ='1' and rx_en ='1' then -- 6
339
                          fs_next_state <= K4;
340
                          sync_err_d    <= '0';
341
                        else
342
                          fs_next_state <= FS_IDLE;
343
                          sync_err_d    <= '1';
344
                        end if;
345
        when K4      => if k ='1' and rx_en ='1' then -- 7
346
                          sync_err_d    <= '0';
347
                        else
348
                          sync_err_d    <= '1';
349
                        end if;
350
                        fs_next_state <= FS_IDLE;
351
        when others  => fs_next_state <= FS_IDLE;
352
                        sync_err_d    <= '1';
353
      end case;
354
    else
355
      fs_next_state <= fs_state;
356
      sync_err_d    <= '0';
357
    end if;
358
  end process;
359
 
360
  synced_d   <= fs_ce and rx_en when (fs_state =K3 and k ='1') or  -- Allow missing first K-J
361
                                     (fs_state =K4 and k ='1') else '0';
362
 
363
  --====================================================================================--
364
  -- Generate RxActive                                                                  --
365
  --====================================================================================--
366
 
367
  p_rx_active: process (clk, rst)
368
  begin
369
    if rst ='0' then
370
      rx_active   <= '0';
371
    elsif rising_edge(clk) then
372
      if synced_d ='1' and rx_en ='1' then
373
        rx_active <= '1';
374
      elsif se0 ='1' and rx_valid_r ='1' then
375
        rx_active <= '0';
376
      end if;
377
    end if;
378
  end process;
379
 
380 3 M_artin
  p_rx_valid_r: process (clk, rst)
381 2 M_artin
  begin
382 3 M_artin
    if rst ='0' then
383
      rx_valid_r <= '0';
384
    elsif rising_edge(clk) then
385 2 M_artin
      if rx_valid ='1' then
386
        rx_valid_r      <= '1';
387
      elsif fs_ce ='1' then
388
        rx_valid_r      <= '0';
389
      end if;
390
    end if;
391
  end process;
392
 
393
  --====================================================================================--
394
  -- NRZI Decoder                                                                       --
395
  --====================================================================================--
396
 
397 3 M_artin
  p_sd_r: process (clk, rst)
398 2 M_artin
  begin
399 3 M_artin
    if rst ='0' then
400
      sd_r <= '0';
401
    elsif rising_edge(clk) then
402 2 M_artin
      if fs_ce ='1' then
403
        sd_r <= rxd_s;
404
      end if;
405
    end if;
406
  end process;
407
 
408
  p_sd_nrzi: process (clk, rst)
409
  begin
410
    if rst ='0' then
411
      sd_nrzi <= '0';
412
    elsif rising_edge(clk) then
413
      if rx_active ='0' then
414
        sd_nrzi <= '1';
415
      elsif rx_active ='1' and fs_ce ='1' then
416
        sd_nrzi <= not (rxd_s xor sd_r);
417
      end if;
418
    end if;
419
  end process;
420
 
421
  --====================================================================================--
422
  -- Bit Stuff Detect                                                                   --
423
  --====================================================================================--
424
 
425
  p_one_cnt: process (clk, rst)
426
  begin
427
    if rst ='0' then
428
      one_cnt <= "000";
429
    elsif rising_edge(clk) then
430
      if shift_en ='0' then
431
        one_cnt <= "000";
432
      elsif fs_ce ='1' then
433
        if sd_nrzi ='0' or drop_bit ='1' then
434
          one_cnt <= "000";
435
        else
436
          one_cnt <= one_cnt + 1;
437
        end if;
438
      end if;
439
    end if;
440
  end process;
441
 
442
  drop_bit <= '1' when one_cnt ="110" else '0';
443
 
444 3 M_artin
  p_bit_stuff_err: process (clk, rst) -- Bit Stuff Error
445 2 M_artin
  begin
446 3 M_artin
    if rst ='0' then
447
      bit_stuff_err <= '0';
448
    elsif rising_edge(clk) then
449 2 M_artin
      bit_stuff_err <= drop_bit and sd_nrzi and fs_ce and not se0 and rx_active;
450
    end if;
451
  end process;
452
 
453
  --====================================================================================--
454
  -- Serial => Parallel converter                                                       --
455
  --====================================================================================--
456
 
457 3 M_artin
  p_shift_en: process (clk, rst)
458 2 M_artin
  begin
459 3 M_artin
    if rst ='0' then
460
      shift_en <= '0';
461
    elsif rising_edge(clk) then
462 2 M_artin
      if fs_ce ='1' then
463
        shift_en <= synced_d or rx_active;
464
      end if;
465
    end if;
466
  end process;
467
 
468
  p_hold_reg: process (clk)
469
  begin
470
    if rising_edge(clk) then
471
      if fs_ce ='1' and shift_en ='1' and drop_bit ='0' then
472
        hold_reg <= sd_nrzi & hold_reg(7 downto 1);
473
      end if;
474
    end if;
475
  end process;
476
 
477
  --====================================================================================--
478
  -- Generate RxValid                                                                  --
479
  --====================================================================================--
480
 
481
  p_bit_cnt: process (clk, rst)
482
  begin
483
    if rst ='0' then
484
      bit_cnt <= "000";
485
    elsif rising_edge(clk) then
486
      if shift_en ='0' then
487
        bit_cnt <=  "000";
488
      elsif fs_ce ='1' and drop_bit ='0' then
489
        bit_cnt <= unsigned(bit_cnt) + 1;
490
      end if;
491
    end if;
492
  end process;
493
 
494
  p_rx_valid1: process (clk, rst)
495
  begin
496
    if rst ='0' then
497
      rx_valid1 <= '0';
498
    elsif rising_edge(clk) then
499
      if fs_ce ='1' and drop_bit ='0' and bit_cnt ="111" then
500
        rx_valid1 <= '1';
501
      elsif rx_valid1 ='1' and fs_ce ='1' and drop_bit ='0' then
502
        rx_valid1 <= '0';
503
      end if;
504
    end if;
505
  end process;
506
 
507 3 M_artin
  p_rx_valid: process (clk, rst)
508 2 M_artin
  begin
509 3 M_artin
    if rst ='0' then
510
      rx_valid <= '0';
511
    elsif rising_edge(clk) then
512 2 M_artin
      rx_valid <= not drop_bit and rx_valid1 and fs_ce;
513
    end if;
514
  end process;
515
 
516
  p_se0_r: process (clk)
517
  begin
518
    if rising_edge(clk) then
519
      se0_r <= se0;
520
    end if;
521
  end process;
522
 
523 3 M_artin
  p_byte_err: process (clk, rst)
524 2 M_artin
  begin
525 3 M_artin
    if rst ='0' then
526
      byte_err <= '0';
527
    elsif rising_edge(clk) then
528 2 M_artin
      byte_err <= se0 and not se0_r and (bit_cnt(1) or bit_cnt(2)) and rx_active;
529
    end if;
530
  end process;
531
 
532
end RTL;

powered by: WebSVN 2.1.0

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