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

Subversion Repositories usb11_phy_translation

[/] [usb11_phy_translation/] [trunk/] [usb_tx_phy.vhdl] - Blame information for rev 3

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
--          //  TX                                                           //         --
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 missing 'rst' in process sensitivity lists     | --
50
-- |       |           |       | Added ELSE constructs in 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_tx_phy is
60
  port (
61
    clk              : in  std_logic;
62
    rst              : in  std_logic;
63
    fs_ce            : in  std_logic;
64
    phy_mode         : in  std_logic;
65
    -- Transciever Interface
66
    txdp, txdn, txoe : out std_logic;
67
    -- UTMI Interface
68
    DataOut_i        : in  std_logic_vector(7 downto 0);
69
    TxValid_i        : in  std_logic;
70
    TxReady_o        : out std_logic
71
  );
72
end usb_tx_phy;
73
 
74
architecture RTL of usb_tx_phy is
75
 
76
  signal hold_reg           : std_logic_vector(7 downto 0);
77
  signal ld_data            : std_logic;
78 3 M_artin
  signal ld_data_d          : std_logic;
79 2 M_artin
  signal ld_eop_d           : std_logic;
80
  signal ld_sop_d           : std_logic;
81
  signal bit_cnt            : std_logic_vector(2 downto 0);
82
  signal sft_done_e         : std_logic;
83
  signal append_eop         : std_logic;
84
  signal append_eop_sync1   : std_logic;
85
  signal append_eop_sync2   : std_logic;
86
  signal append_eop_sync3   : std_logic;
87
  signal append_eop_sync4   : std_logic;
88
  signal data_done          : std_logic;
89
  signal eop_done           : std_logic;
90
  signal hold_reg_d         : std_logic_vector(7 downto 0);
91
  signal one_cnt            : std_logic_vector(2 downto 0);
92
  signal sd_bs_o            : std_logic;
93
  signal sd_nrzi_o          : std_logic;
94
  signal sd_raw_o           : std_logic;
95
  signal sft_done           : std_logic;
96
  signal sft_done_r         : std_logic;
97
  signal state, next_state  : std_logic_vector(2 downto 0);
98
  signal stuff              : std_logic;
99
  signal tx_ip              : std_logic;
100
  signal tx_ip_sync         : std_logic;
101
  signal txoe_r1, txoe_r2   : std_logic;
102
 
103
  constant IDLE_STATE       : std_logic_vector := "000";
104
  constant SOP_STATE        : std_logic_vector := "001";
105
  constant DATA_STATE       : std_logic_vector := "010";
106
  constant EOP1_STATE       : std_logic_vector := "011";
107
  constant EOP2_STATE       : std_logic_vector := "100";
108
  constant WAIT_STATE       : std_logic_vector := "101";
109
 
110
begin
111
 
112
--======================================================================================--
113
  -- Misc Logic                                                                         --
114
--======================================================================================--
115
 
116
  p_TxReady_o: process (clk, rst)
117
  begin
118
    if rst ='0' then
119
      TxReady_o <= '0';
120
    elsif rising_edge(clk) then
121
      TxReady_o <= ld_data_d and TxValid_i;
122
    end if;
123
  end process;
124
 
125
  p_ld_data: process (clk)
126
  begin
127
    if rising_edge(clk) then
128
      ld_data <= ld_data_d;
129
    end if;
130
  end process;
131
 
132
--======================================================================================--
133
  -- Transmit in progress indicator                                                     --
134
--======================================================================================--
135
 
136
  p_tx_ip: process (clk, rst)
137
  begin
138
    if rst ='0' then
139
      tx_ip <= '0';
140
    elsif rising_edge(clk) then
141
      if ld_sop_d  ='1' then
142
        tx_ip <= '1';
143
      elsif eop_done ='1' then
144
        tx_ip <= '0';
145
      end if;
146
    end if;
147
  end process;
148
 
149
  p_tx_ip_sync: process (clk, rst)
150
  begin
151
    if rst ='0' then
152
      tx_ip_sync <= '0';
153
    elsif rising_edge(clk) then
154
      if fs_ce ='1' then
155
        tx_ip_sync <= tx_ip;
156
      end if;
157
    end if;
158
  end process;
159
 
160
  -- data_done helps us to catch cases where TxValid drops due to
161
  -- packet end and then gets re-asserted as a new packet starts.
162
  -- We might not see this because we are still transmitting.
163
  -- data_done should solve those cases ...
164
  p_data_done: process (clk, rst)
165
  begin
166
    if rst ='0' then
167
      data_done <= '0';
168
    elsif rising_edge(clk) then
169
      if TxValid_i ='1' and tx_ip ='0' then
170
        data_done <= '1';
171
      elsif TxValid_i = '0' then
172
        data_done <= '0';
173
      end if;
174
    end if;
175
  end process;
176
 
177
--======================================================================================--
178
  -- Shift Register                                                                     --
179
--======================================================================================--
180
 
181
  p_bit_cnt: process (clk, rst)
182
  begin
183
    if rst ='0' then
184
      bit_cnt <= "000";
185
    elsif rising_edge(clk) then
186
      if tx_ip_sync ='0' then
187
        bit_cnt <= "000";
188
      elsif fs_ce ='1' and stuff ='0' then
189
        bit_cnt <= bit_cnt + 1;
190
      end if;
191
    end if;
192
  end process;
193
 
194
  p_sd_raw_o: process (clk)
195
  begin
196
    if rising_edge(clk) then
197
      if tx_ip_sync ='0' then
198
        sd_raw_o <= '0';
199
      else
200
        sd_raw_o <= hold_reg_d(CONV_INTEGER(UNSIGNED(bit_cnt)));
201
      end if;
202
    end if;
203
  end process;
204
 
205
  p_sft_done: process (clk)
206
  begin
207
    if rising_edge(clk) then
208
      if bit_cnt = "111" then
209
        sft_done <= not stuff;
210
      else
211
        sft_done <= '0';
212
      end if;
213
    end if;
214
  end process;
215
 
216
  p_sft_done_r: process (clk)
217
  begin
218
    if rising_edge(clk) then
219
      sft_done_r      <= sft_done;
220
    end if;
221
  end process;
222
 
223
  sft_done_e <= sft_done and not sft_done_r;
224
 
225
  -- Out Data Hold Register
226 3 M_artin
  p_hold_reg: process (clk, rst)
227 2 M_artin
  begin
228
    if rst ='0' then
229
        hold_reg   <= X"00";
230
        hold_reg_d <= X"00";
231
    elsif rising_edge(clk) then
232
      if ld_sop_d ='1' then
233
        hold_reg <= X"80";
234
      elsif ld_data ='1' then
235
        hold_reg <= DataOut_i;
236
      end if;
237
      hold_reg_d <= hold_reg;
238
    end if;
239
  end process;
240
 
241
--======================================================================================--
242
  -- Bit Stuffer                                                                        --
243
--======================================================================================--
244
 
245
  p_one_cnt: process (clk, rst)
246
  begin
247
    if rst ='0' then
248
      one_cnt <= "000";
249
    elsif rising_edge(clk) then
250
      if tx_ip_sync ='0' then
251
        one_cnt <= "000";
252
      elsif fs_ce ='1' then
253
        if sd_raw_o ='0' or stuff = '1' then
254
          one_cnt <= "000";
255
        else
256
          one_cnt <= one_cnt + 1;
257
        end if;
258
      end if;
259
    end if;
260
  end process;
261
 
262
  stuff   <= '1' when one_cnt = "110" else '0';
263
 
264
  p_sd_bs_o: process (clk, rst)
265
  begin
266
    if rst ='0' then
267
      sd_bs_o <= '0';
268
    elsif rising_edge(clk) then
269
      if fs_ce ='1' then
270
        if tx_ip_sync ='0' then
271
          sd_bs_o <= '0';
272
        else
273
          if stuff ='1' then
274
            sd_bs_o <= '0';
275
          else
276
            sd_bs_o <= sd_raw_o;
277
          end if;
278
        end if;
279
      end if;
280
    end if;
281
  end process;
282
 
283
--======================================================================================--
284
  -- NRZI Encoder                                                                       --
285
--======================================================================================--
286
 
287
  p_sd_nrzi_o: process (clk, rst)
288
  begin
289
    if rst ='0' then
290
      sd_nrzi_o <= '1';
291
    elsif rising_edge(clk) then
292
      if tx_ip_sync ='0' or txoe_r1 ='0' then
293
        sd_nrzi_o <= '1';
294
      elsif fs_ce ='1' then
295
        if sd_bs_o ='1' then
296
          sd_nrzi_o <= sd_nrzi_o;
297
        else
298
          sd_nrzi_o <= not sd_nrzi_o;
299
        end if;
300
      end if;
301
    end if;
302
  end process;
303
 
304
--======================================================================================--
305
  -- EOP append logic                                                                   --
306
--======================================================================================--
307
 
308
  p_append_eop: process (clk, rst)
309
  begin
310
    if rst ='0' then
311
      append_eop <= '0';
312
    elsif rising_edge(clk) then
313
      if ld_eop_d ='1' then
314
        append_eop <= '1';
315
      elsif append_eop_sync2 ='1' then
316
        append_eop <= '0';
317
      end if;
318
    end if;
319
  end process;
320
 
321
  p_append_eop_sync: process (clk, rst)
322
  begin
323
    if rst ='0' then
324
      append_eop_sync1 <= '0';
325
      append_eop_sync2 <= '0';
326
      append_eop_sync3 <= '0';
327
      append_eop_sync4 <= '0';
328
    elsif rising_edge(clk) then
329
      if fs_ce ='1' then
330
        append_eop_sync1 <= append_eop;
331
        append_eop_sync2 <= append_eop_sync1;
332
        append_eop_sync3 <= append_eop_sync2 or -- Make sure always 2 bit wide
333
                            (append_eop_sync3 and not append_eop_sync4);
334
        append_eop_sync4 <= append_eop_sync3;
335
      end if;
336
    end if;
337
  end process;
338
 
339
  eop_done <= append_eop_sync3;
340
 
341
--======================================================================================--
342
  -- Output Enable Logic                                                                --
343
--======================================================================================--
344
 
345
  p_txoe: process (clk, rst)
346
  begin
347
    if rst ='0' then
348
      txoe_r1 <= '0';
349
      txoe_r2 <= '0';
350
      txoe    <= '1';
351
    elsif rising_edge(clk) then
352
      if fs_ce ='1' then
353
        txoe_r1 <= tx_ip_sync;
354
        txoe_r2 <= txoe_r1;
355
        txoe    <= not (txoe_r1 or txoe_r2);
356
      end if;
357
    end if;
358
  end process;
359
 
360
--======================================================================================--
361
  -- Output Registers                                                                   --
362
--======================================================================================--
363
 
364
  p_txdpn: process (clk, rst)
365
  begin
366
    if rst ='0' then
367
      txdp <= '1';
368
      txdn <= '0';
369
    elsif rising_edge(clk) then
370
      if fs_ce ='1' then
371
        if phy_mode ='1' then
372
          txdp <= not append_eop_sync3 and     sd_nrzi_o;
373
          txdn <= not append_eop_sync3 and not sd_nrzi_o;
374
        else
375
          txdp <= sd_nrzi_o;
376
          txdn <= append_eop_sync3;
377
        end if;
378
      end if;
379
    end if;
380
  end process;
381
 
382
--======================================================================================--
383
  -- Tx Statemashine                                                                    --
384
--======================================================================================--
385
 
386
  p_state: process (clk, rst)
387
  begin
388
    if rst ='0' then
389
      state <= IDLE_STATE;
390
    elsif rising_edge(clk) then
391
      state <= next_state;
392
    end if;
393
  end process;
394
 
395
  p_next_state: process (rst, state, TxValid_i, data_done, sft_done_e, eop_done, fs_ce)
396
  begin
397
    if rst='0' then
398
      next_state <= IDLE_STATE;
399
    else
400
      case (state) is
401
        when IDLE_STATE => if TxValid_i ='1' then
402
                             next_state <= SOP_STATE;
403 3 M_artin
                           ELSE
404
                             next_state <= IDLE_STATE;
405 2 M_artin
                           end if;
406
        when SOP_STATE  => if sft_done_e ='1' then
407
                             next_state <= DATA_STATE;
408 3 M_artin
                           ELSE
409
                             next_state <= SOP_STATE;
410 2 M_artin
                           end if;
411
        when DATA_STATE => if data_done ='0' and sft_done_e ='1' then
412
                             next_state <= EOP1_STATE;
413 3 M_artin
                           ELSE
414
                             next_state <= DATA_STATE;
415 2 M_artin
                           end if;
416
        when EOP1_STATE => if eop_done ='1' then
417
                             next_state <= EOP2_STATE;
418 3 M_artin
                           ELSE
419
                             next_state <= EOP1_STATE;
420 2 M_artin
                           end if;
421
        when EOP2_STATE => if eop_done ='0' and fs_ce ='1' then
422
                             next_state <= WAIT_STATE;
423 3 M_artin
                           ELSE
424
                             next_state <= EOP2_STATE;
425 2 M_artin
                           end if;
426 3 M_artin
        when WAIT_STATE => if fs_ce = '1' then
427 2 M_artin
                             next_state <= IDLE_STATE;
428 3 M_artin
                           ELSE
429
                             next_state <= WAIT_STATE;
430 2 M_artin
                           end if;
431 3 M_artin
        when others     => next_state <= IDLE_STATE;
432 2 M_artin
      end case;
433
    end if;
434
  end process;
435
 
436
  ld_sop_d  <= TxValid_i  when state = IDLE_STATE else '0';
437
  ld_data_d <= sft_done_e when state = SOP_STATE or (state = DATA_STATE and data_done ='1') else '0';
438
  ld_eop_d  <= sft_done_e when state = Data_STATE and data_done ='0' else '0';
439
 
440
end RTL;
441
 

powered by: WebSVN 2.1.0

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