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 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
--          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
 
45
library ieee;
46
use ieee.std_logic_1164.all;
47
use ieee.std_logic_arith.all;
48
use ieee.std_logic_unsigned.all;
49
 
50
entity usb_rx_phy is
51
  port (
52
    clk             : in  std_logic;
53
    rst             : in  std_logic;
54
    -- Transciever Interface
55
    fs_ce_o         : out std_logic;
56
    rxd, rxdp, rxdn : in  std_logic;
57
    -- UTMI Interface
58
    DataIn_o        : out std_logic_vector(7 downto 0);
59
    RxValid_o       : out std_logic;
60
    RxActive_o      : out std_logic;
61
    RxError_o       : out std_logic;
62
    RxEn_i          : in  std_logic;
63
    LineState       : out std_logic_vector(1 downto 0)
64
  );
65
end usb_rx_phy;
66
 
67
architecture RTL of usb_rx_phy is
68
 
69
  signal fs_ce                              : std_logic;
70
  signal rxd_s0, rxd_s1, rxd_s              : std_logic;
71
  signal rxdp_s0, rxdp_s1, rxdp_s, rxdp_s_r : std_logic;
72
  signal rxdn_s0, rxdn_s1, rxdn_s, rxdn_s_r : std_logic;
73
  signal synced_d                           : std_logic;
74
  signal k, j, se0                          : std_logic;
75
  signal rxd_r                              : std_logic;
76
  signal rx_en                              : std_logic;
77
  signal rx_active                          : std_logic;
78
  signal bit_cnt                            : std_logic_vector(2 downto 0);
79
  signal rx_valid1, rx_valid                : std_logic;
80
  signal shift_en                           : std_logic;
81
  signal sd_r                               : std_logic;
82
  signal sd_nrzi                            : std_logic;
83
  signal hold_reg                           : std_logic_vector(7 downto 0);
84
  signal drop_bit                           : std_logic;    -- Indicates a stuffed bit
85
  signal one_cnt                            : std_logic_vector(2 downto 0);
86
  signal dpll_cntr                          : std_logic_vector(3 downto 0);
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, byte_err            : std_logic;
93
  signal se0_r, se0_s                       : std_logic;
94
 
95
  constant FS_IDLE  : std_logic_vector(2 downto 0) := "000";
96
  constant K1       : std_logic_vector(2 downto 0) := "001";
97
  constant J1       : std_logic_vector(2 downto 0) := "010";
98
  constant K2       : std_logic_vector(2 downto 0) := "011";
99
  constant J2       : std_logic_vector(2 downto 0) := "100";
100
  constant K3       : std_logic_vector(2 downto 0) := "101";
101
  constant J3       : std_logic_vector(2 downto 0) := "110";
102
  constant K4       : std_logic_vector(2 downto 0) := "111";
103
 
104
begin
105
 
106
  --====================================================================================--
107
  -- Misc Logic                                                                         --
108
  --====================================================================================--
109
 
110
  fs_ce_o    <= fs_ce;
111
  RxActive_o <= rx_active;
112
  RxValid_o  <= rx_valid;
113
  RxError_o  <= sync_err or bit_stuff_err or byte_err;
114
  DataIn_o   <= hold_reg;
115
  LineState  <= rxdn_s1 & rxdp_s1;
116
 
117
  p_rx_en: process (clk)
118
  begin
119
    if rising_edge(clk) then
120
      rx_en <= RxEn_i;
121
    end if;
122
  end process;
123
 
124
  p_sync_err: process (clk)
125
  begin
126
    if rst ='0' then
127
      sync_err <= '0';
128
    elsif 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 rst ='0' then
182
      se0_s <= '0';
183
    elsif rising_edge(clk) then
184
      if fs_ce ='1' then
185
        se0_s   <= se0;
186
      end if;
187
    end if;
188
  end process;
189
 
190
  --====================================================================================--
191
  -- DPLL, this section is modified and adopted for a 60 MHz clock (Martin Neumann)     --
192
  --====================================================================================--
193
 
194
  -- This design uses a clock enable to do 12Mhz timing and not a
195
  -- real 12Mhz clock. Everything always runs at 60 Mhz. We want to
196
  -- make sure however, that the clock enable is always exactly in
197
  -- the middle between two virtual 12Mhz rising edges.
198
  -- We monitor rxdp and rxdn for any changes and do the appropiate
199
  -- adjustments.
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
  p_dpll_cntr: process (clk, rst)
213
  begin
214
    if rst ='0' then
215
      dpll_cntr <= "0011";
216
    elsif rising_edge(clk) then
217
      if lock_en = '1' and change = '1' then
218
        if dpll_cntr(3)='1' then
219
          dpll_cntr <= "0010";       -- fe_ce detected, now centered in following cycle
220
        else
221
          dpll_cntr <= "0111";       -- adjust fe_ce to center cycle
222
        end if;
223
      elsif dpll_cntr(3) = '1' then  -- normal count sequence is 8->4->5->6->7->8->4...
224
        dpll_cntr <= "0100";
225
      else
226
        dpll_cntr <= dpll_cntr +1;
227
      end if;
228
    end if;
229
  end process;
230
 
231
  fs_ce <= dpll_cntr(3);
232
 
233
  --====================================================================================--
234
  -- Find Sync Pattern FSM                                                              --
235
  --====================================================================================--
236
 
237
  p_fs_state: process (clk, rst)
238
  begin
239
    if rst ='0' then
240
      fs_state  <= FS_IDLE;
241
    elsif rising_edge(clk) then
242
      fs_state  <= fs_next_state;
243
    end if;
244
  end process;
245
 
246
  p_fs_next_state: process (fs_state, fs_ce, k, j, rx_en, rx_active, se0, se0_s)
247
  begin
248
    if fs_ce='1' and  rx_active='0' and se0='0' and se0_s='0' then
249
      case fs_state is
250
        when FS_IDLE => if k ='1' and rx_en ='1' then -- 0
251
                          fs_next_state <= K1;
252
                          sync_err_d    <= '0';
253
                        end if;
254
        when K1      => if j ='1' and rx_en ='1' then -- 1
255
                          fs_next_state <= J1;
256
                          sync_err_d    <= '0';
257
                        else
258
                          fs_next_state <= FS_IDLE;
259
                          sync_err_d    <= '1';
260
                        end if;
261
        when J1      => if k ='1' and rx_en ='1' then -- 2
262
                          fs_next_state <= K2;
263
                          sync_err_d    <= '0';
264
                        else
265
                          fs_next_state <= FS_IDLE;
266
                          sync_err_d    <= '1';
267
                        end if;
268
        when K2      => if j ='1' and rx_en ='1' then -- 3
269
                          fs_next_state <= J2;
270
                          sync_err_d    <= '0';
271
                        else
272
                          fs_next_state <= FS_IDLE;
273
                          sync_err_d    <= '1';
274
                        end if;
275
        when J2      => if k ='1' and rx_en ='1' then -- 4
276
                          fs_next_state <= K3;
277
                          sync_err_d    <= '0';
278
                        else
279
                          fs_next_state <= FS_IDLE;
280
                          sync_err_d    <= '1';
281
                        end if;
282
        when K3      => if j ='1' and rx_en ='1' then -- 5
283
                          fs_next_state <= J3;
284
                          sync_err_d    <= '0';
285
                        elsif k ='1' and rx_en ='1' then  -- Allow missing first K-J
286
                          fs_next_state <= FS_IDLE;
287
                          sync_err_d    <= '0';
288
                        else
289
                          fs_next_state <= FS_IDLE;
290
                          sync_err_d    <= '1';
291
                        end if;
292
        when J3      => if k ='1' and rx_en ='1' then -- 6
293
                          fs_next_state <= K4;
294
                          sync_err_d    <= '0';
295
                        else
296
                          fs_next_state <= FS_IDLE;
297
                          sync_err_d    <= '1';
298
                        end if;
299
        when K4      => if k ='1' and rx_en ='1' then -- 7
300
                          sync_err_d    <= '0';
301
                        else
302
                          sync_err_d    <= '1';
303
                        end if;
304
                        fs_next_state <= FS_IDLE;
305
        when others  => fs_next_state <= FS_IDLE;
306
                        sync_err_d    <= '1';
307
      end case;
308
    else
309
      fs_next_state <= fs_state;
310
      sync_err_d    <= '0';
311
    end if;
312
  end process;
313
 
314
  synced_d   <= fs_ce and rx_en when (fs_state =K3 and k ='1') or  -- Allow missing first K-J
315
                                     (fs_state =K4 and k ='1') else '0';
316
 
317
  --====================================================================================--
318
  -- Generate RxActive                                                                  --
319
  --====================================================================================--
320
 
321
  p_rx_active: process (clk, rst)
322
  begin
323
    if rst ='0' then
324
      rx_active   <= '0';
325
    elsif rising_edge(clk) then
326
      if synced_d ='1' and rx_en ='1' then
327
        rx_active <= '1';
328
      elsif se0 ='1' and rx_valid_r ='1' then
329
        rx_active <= '0';
330
      end if;
331
    end if;
332
  end process;
333
 
334
  p_rx_valid_r: process (clk)
335
  begin
336
    if rst ='0' then
337
      rx_valid_r <= '0';
338
    elsif rising_edge(clk) then
339
      if rx_valid ='1' then
340
        rx_valid_r      <= '1';
341
      elsif fs_ce ='1' then
342
        rx_valid_r      <= '0';
343
      end if;
344
    end if;
345
  end process;
346
 
347
  --====================================================================================--
348
  -- NRZI Decoder                                                                       --
349
  --====================================================================================--
350
 
351
  p_sd_r: process (clk)
352
  begin
353
    if rst ='0' then
354
      sd_r <= '0';
355
    elsif rising_edge(clk) then
356
      if fs_ce ='1' then
357
        sd_r <= rxd_s;
358
      end if;
359
    end if;
360
  end process;
361
 
362
  p_sd_nrzi: process (clk, rst)
363
  begin
364
    if rst ='0' then
365
      sd_nrzi <= '0';
366
    elsif rising_edge(clk) then
367
      if rx_active ='0' then
368
        sd_nrzi <= '1';
369
      elsif rx_active ='1' and fs_ce ='1' then
370
        sd_nrzi <= not (rxd_s xor sd_r);
371
      end if;
372
    end if;
373
  end process;
374
 
375
  --====================================================================================--
376
  -- Bit Stuff Detect                                                                   --
377
  --====================================================================================--
378
 
379
  p_one_cnt: process (clk, rst)
380
  begin
381
    if rst ='0' then
382
      one_cnt <= "000";
383
    elsif rising_edge(clk) then
384
      if shift_en ='0' then
385
        one_cnt <= "000";
386
      elsif fs_ce ='1' then
387
        if sd_nrzi ='0' or drop_bit ='1' then
388
          one_cnt <= "000";
389
        else
390
          one_cnt <= one_cnt + 1;
391
        end if;
392
      end if;
393
    end if;
394
  end process;
395
 
396
  drop_bit <= '1' when one_cnt ="110" else '0';
397
 
398
  p_bit_stuff_err: process (clk) -- Bit Stuff Error
399
  begin
400
    if rst ='0' then
401
      bit_stuff_err <= '0';
402
    elsif rising_edge(clk) then
403
      bit_stuff_err <= drop_bit and sd_nrzi and fs_ce and not se0 and rx_active;
404
    end if;
405
  end process;
406
 
407
  --====================================================================================--
408
  -- Serial => Parallel converter                                                       --
409
  --====================================================================================--
410
 
411
  p_shift_en: process (clk)
412
  begin
413
    if rst ='0' then
414
      shift_en <= '0';
415
    elsif rising_edge(clk) then
416
      if fs_ce ='1' then
417
        shift_en <= synced_d or rx_active;
418
      end if;
419
    end if;
420
  end process;
421
 
422
  p_hold_reg: process (clk)
423
  begin
424
    if rising_edge(clk) then
425
      if fs_ce ='1' and shift_en ='1' and drop_bit ='0' then
426
        hold_reg <= sd_nrzi & hold_reg(7 downto 1);
427
      end if;
428
    end if;
429
  end process;
430
 
431
  --====================================================================================--
432
  -- Generate RxValid                                                                  --
433
  --====================================================================================--
434
 
435
  p_bit_cnt: process (clk, rst)
436
  begin
437
    if rst ='0' then
438
      bit_cnt <= "000";
439
    elsif rising_edge(clk) then
440
      if shift_en ='0' then
441
        bit_cnt <=  "000";
442
      elsif fs_ce ='1' and drop_bit ='0' then
443
        bit_cnt <= unsigned(bit_cnt) + 1;
444
      end if;
445
    end if;
446
  end process;
447
 
448
  p_rx_valid1: process (clk, rst)
449
  begin
450
    if rst ='0' then
451
      rx_valid1 <= '0';
452
    elsif rising_edge(clk) then
453
      if fs_ce ='1' and drop_bit ='0' and bit_cnt ="111" then
454
        rx_valid1 <= '1';
455
      elsif rx_valid1 ='1' and fs_ce ='1' and drop_bit ='0' then
456
        rx_valid1 <= '0';
457
      end if;
458
    end if;
459
  end process;
460
 
461
  p_rx_valid: process (clk)
462
  begin
463
    if rst ='0' then
464
      rx_valid <= '0';
465
    elsif rising_edge(clk) then
466
      rx_valid <= not drop_bit and rx_valid1 and fs_ce;
467
    end if;
468
  end process;
469
 
470
  p_se0_r: process (clk)
471
  begin
472
    if rising_edge(clk) then
473
      se0_r <= se0;
474
    end if;
475
  end process;
476
 
477
  p_byte_err: process (clk)
478
  begin
479
    if rst ='0' then
480
      byte_err <= '0';
481
    elsif rising_edge(clk) then
482
      byte_err <= se0 and not se0_r and (bit_cnt(1) or bit_cnt(2)) and rx_active;
483
    end if;
484
  end process;
485
 
486
end RTL;

powered by: WebSVN 2.1.0

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