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

powered by: WebSVN 2.1.0

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