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

powered by: WebSVN 2.1.0

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