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

Subversion Repositories opb_usblite

[/] [opb_usblite/] [trunk/] [pcores/] [opb_usblite_v1_00_a/] [hdl/] [vhdl/] [opb_usblite_core.vhd] - Blame information for rev 2

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 rehnmaak
--
2
--    opb_usblite - opb_uartlite replacement
3
--
4
--    opb_usblite is using components from Rudolf Usselmann see
5
--    http://www.opencores.org/cores/usb_phy/
6
--    and Joris van Rantwijk see http://www.xs4all.nl/~rjoris/fpga/usb.html
7
--
8
--    Copyright (C) 2010 Ake Rehnman
9
--
10
--    This program is free software: you can redistribute it and/or modify
11
--    it under the terms of the GNU General Public License as published by
12
--    the Free Software Foundation, either version 3 of the License, or
13
--    (at your option) any later version.
14
--
15
--    This program is distributed in the hope that it will be useful,
16
--    but WITHOUT ANY WARRANTY; without even the implied warranty of
17
--    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
--    GNU General Public License for more details.
19
--
20
--    You should have received a copy of the GNU General Public License
21
--    along with this program.  If not, see <http://www.gnu.org/licenses/>.
22
--
23
library IEEE;
24
use IEEE.std_logic_1164.all;
25
use IEEE.numeric_std.all;
26
 
27
entity OPB_USBLITE_Core is
28
  generic (
29
    C_PHYMODE :       std_logic := '1';
30
    C_VENDORID :      std_logic_vector(15 downto 0) := X"1234";
31
    C_PRODUCTID :     std_logic_vector(15 downto 0) := X"5678";
32
    C_VERSIONBCD :    std_logic_vector(15 downto 0) := X"0200";
33
    C_SELFPOWERED :   boolean := false;
34
    C_RXBUFSIZE_BITS: integer range 7 to 12 := 10;
35
    C_TXBUFSIZE_BITS: integer range 7 to 12 := 10
36
    );
37
  port (
38
    Clk   : in std_logic;
39
    Reset : in std_logic;
40
    Usb_Clk : in std_logic;
41
    -- OPB signals
42
    OPB_CS : in std_logic;
43
    OPB_ABus : in std_logic_vector(0 to 1);
44
    OPB_RNW  : in std_logic;
45
    OPB_DBus : in std_logic_vector(7 downto 0);
46
    SIn_xferAck : out std_logic;
47
    SIn_DBus    : out std_logic_vector(7 downto 0);
48
    Interrupt : out std_logic;
49
    -- USB signals
50
                txdp : out std_logic;
51
                txdn : out std_logic;
52
                txoe : out std_logic;
53
                rxd : in std_logic;
54
                rxdp : in std_logic;
55
                rxdn : in std_logic
56
  );
57
end entity OPB_USBLITE_Core;
58
 
59
library unisim;
60
use unisim.all;
61
 
62
architecture akre of OPB_USBLITE_Core is
63
 
64
component usb_serial is
65
 
66
    generic (
67
 
68
        -- Vendor ID to report in device descriptor.
69
        VENDORID :      std_logic_vector(15 downto 0);
70
 
71
        -- Product ID to report in device descriptor.
72
        PRODUCTID :     std_logic_vector(15 downto 0);
73
 
74
        -- Product version to report in device descriptor.
75
        VERSIONBCD :    std_logic_vector(15 downto 0);
76
 
77
        -- Support high speed mode.
78
        HSSUPPORT :     boolean := false;
79
 
80
        -- Set to true if the device never draws power from the USB bus.
81
        SELFPOWERED :   boolean := false;
82
 
83
        -- Size of receive buffer as 2-logarithm of the number of bytes.
84
        -- Must be at least 10 (1024 bytes) for high speed support.
85
        RXBUFSIZE_BITS: integer range 7 to 12 := 11;
86
 
87
        -- Size of transmit buffer as 2-logarithm of the number of bytes.
88
        TXBUFSIZE_BITS: integer range 7 to 12 := 10
89
    );
90
 
91
    port (
92
 
93
        -- 60 MHz UTMI clock.
94
        CLK :           in  std_logic;
95
 
96
        -- Synchronous reset; clear buffers and re-attach to the bus.
97
        RESET :         in  std_logic;
98
 
99
        -- High for one clock when a reset signal is detected on the USB bus.
100
        -- Note: do NOT wire this signal to RESET externally.
101
        USBRST :        out std_logic;
102
 
103
        -- High when the device is operating (or suspended) in high speed mode.
104
        HIGHSPEED :     out std_logic;
105
 
106
        -- High while the device is suspended.
107
        -- Note: This signal is not synchronized to CLK.
108
        -- It may be used to asynchronously drive the UTMI SuspendM pin.
109
        SUSPEND :       out std_logic;
110
 
111
        -- High when the device is in the Configured state.
112
        ONLINE :        out std_logic;
113
 
114
        -- High if a received byte is available on RXDAT.
115
        RXVAL :         out std_logic;
116
 
117
        -- Received data byte, valid if RXVAL is high.
118
        RXDAT :         out std_logic_vector(7 downto 0);
119
 
120
        -- High if the application is ready to receive the next byte.
121
        RXRDY :         in  std_logic;
122
 
123
        -- Number of bytes currently available in receive buffer.
124
        RXLEN :         out std_logic_vector((RXBUFSIZE_BITS-1) downto 0);
125
 
126
        -- High if the application has data to send.
127
        TXVAL :         in  std_logic;
128
 
129
        -- Data byte to send, must be valid if TXVAL is high.
130
        TXDAT :         in  std_logic_vector(7 downto 0);
131
 
132
        -- High if the entity is ready to accept the next byte.
133
        TXRDY :         out std_logic;
134
 
135
        -- Number of free byte positions currently available in transmit buffer.
136
        TXROOM :        out std_logic_vector((TXBUFSIZE_BITS-1) downto 0);
137
 
138
        -- Temporarily suppress transmissions at the outgoing endpoint.
139
        -- This gives the application an oppertunity to fill the transmit
140
        -- buffer in order to blast data efficiently in big chunks.
141
        TXCORK :        in  std_logic;
142
 
143
        PHY_DATAIN :    in  std_logic_vector(7 downto 0);
144
              PHY_DATAOUT :   out std_logic_vector(7 downto 0);
145
              PHY_TXVALID :   out std_logic;
146
              PHY_TXREADY :   in  std_logic;
147
              PHY_RXACTIVE :  in  std_logic;
148
              PHY_RXVALID :   in  std_logic;
149
              PHY_RXERROR :   in  std_logic;
150
              PHY_LINESTATE : in  std_logic_vector(1 downto 0);
151
              PHY_OPMODE :    out std_logic_vector(1 downto 0);
152
        PHY_XCVRSELECT: out std_logic;
153
        PHY_TERMSELECT: out std_logic;
154
              PHY_RESET :     out std_logic
155
            );
156
  end component usb_serial;
157
 
158
  component usb_phy is
159
    port (
160
      clk : in std_logic;
161
      rst : in std_logic;
162
      phy_tx_mode : in std_logic;
163
      usb_rst : out std_logic;
164
 
165
                -- Transciever Interface
166
                  txdp : out std_logic;
167
                  txdn : out std_logic;
168
                  txoe : out std_logic;
169
                  rxd : in std_logic;
170
                  rxdp : in std_logic;
171
                  rxdn : in std_logic;
172
 
173
                -- UTMI Interface
174
                  DataOut_i : in std_logic_vector (7 downto 0);
175
                  TxValid_i : in std_logic;
176
                  TxReady_o : out std_logic;
177
                  RxValid_o : out std_logic;
178
                  RxActive_o : out std_logic;
179
                  RxError_o : out std_logic;
180
                  DataIn_o : out std_logic_vector (7 downto 0);
181
                  LineState_o : out std_logic_vector (1 downto 0)
182
    );
183
  end component usb_phy;
184
 
185
  constant RX_FIFO_ADR    : std_logic_vector(0 to 1) := "00";
186
  constant TX_FIFO_ADR    : std_logic_vector(0 to 1) := "01";
187
  constant STATUS_REG_ADR : std_logic_vector(0 to 1) := "10";
188
  constant CTRL_REG_ADR   : std_logic_vector(0 to 1) := "11";
189
 
190
  -- Read Only
191
  signal status_Reg : std_logic_vector(7 downto 0);
192
  -- bit 0 rx_Data_Present
193
  -- bit 1 rx_Buffer_Full
194
  -- bit 2 tx_Buffer_Empty
195
  -- bit 3 tx_Buffer_Full
196
  -- bit 4 interrupt flag
197
 
198
  -- Write Only
199
  -- bit 0   Reset_TX_FIFO
200
  -- bit 1   Reset_RX_FIFO
201
  -- bit 2-3 Dont'Care
202
  -- bit 4   enable_rxinterrupts
203
  -- bit 5   Dont'Care
204
  -- bit 6   enable_txinterrupts
205
  -- bit 7   tx_enable
206
 
207
  signal enable_txinterrupts : std_logic;
208
  signal enable_rxinterrupts : std_logic;
209
 
210
  signal read_RX_FIFO      : std_logic;
211
  signal reset_RX_FIFO     : std_logic;
212
  signal TX_EN : std_logic;
213
  signal write_TX_FIFO   : std_logic;
214
  signal reset_TX_FIFO   : std_logic;
215
  signal tx_BUFFER_FULL  : std_logic;
216
  signal tx_Buffer_Empty : std_logic;
217
  signal rx_Data_Present  : std_logic;
218
  signal rx_BUFFER_FULL : std_logic;
219
 
220
  signal xfer_Ack     : std_logic;
221
  signal xfer_Ack1 : std_logic;
222
  signal xfer_Ack2 : std_logic;
223
  signal Interrupt_r : std_logic;
224
 
225
  signal read_rx_fifo_r : std_logic;
226
  signal read_rx_fifo_rr : std_logic;
227
  signal read_rx_fifo_rrr : std_logic;
228
  signal write_tx_fifo_r : std_logic;
229
  signal write_tx_fifo_rr : std_logic;
230
  signal write_tx_fifo_rrr : std_logic;
231
 
232
  signal usbrst : std_logic;
233
  signal rxval : std_logic;
234
 
235
  signal rxdat : std_logic_vector (7 downto 0);
236
  signal rxrdy : std_logic;
237
  signal txval : std_logic;
238
  signal txempty : std_logic;
239
  signal txfull : std_logic;
240
  signal rxfull : std_logic;
241
  signal txdat : std_logic_vector (7 downto 0);
242
  signal txrdy : std_logic;
243
 
244
  signal phy_datain : std_logic_vector (7 downto 0);
245
        signal phy_dataout : std_logic_vector (7 downto 0);
246
        signal phy_txvalid : std_logic;
247
        signal phy_txready : std_logic;
248
        signal phy_rxactive : std_logic;
249
        signal phy_rxvalid : std_logic;
250
        signal phy_rxerror : std_logic;
251
        signal phy_linestate : std_logic_vector (1 downto 0);
252
        signal phy_reset : std_logic;
253
        signal phy_resetn : std_logic;
254
        signal phy_usb_rst : std_logic;
255
 
256
  signal highspeed : std_logic;
257
  signal suspend : std_logic;
258
  signal online : std_logic;
259
  signal rxlen : std_logic_vector((C_RXBUFSIZE_BITS-1) downto 0);
260
  signal txroom : std_logic_vector((C_TXBUFSIZE_BITS-1) downto 0);
261
 
262
        attribute TIG : string;
263
        attribute TIG of Reset : signal is "yes";
264
        attribute TIG of write_TX_FIFO : signal is "yes";
265
        attribute TIG of read_RX_FIFO  : signal is "yes";
266
        attribute TIG of rxdat : signal is "yes";
267
        attribute TIG of txdat : signal is "yes";
268
        attribute TIG of rxval : signal is "yes";
269
        attribute TIG of txrdy : signal is "yes";
270
        attribute TIG of txempty : signal is "yes";
271
        attribute TIG of txfull : signal is "yes";
272
        attribute TIG of rxfull : signal is "yes";
273
 
274
        attribute TIG of online : signal is "yes";
275
        attribute TIG of suspend : signal is "yes";
276
 
277
  constant C_TXFULL : std_logic_vector((C_TXBUFSIZE_BITS-1) downto 0) := (others=>'0');
278
  constant C_TXEMPTY : std_logic_vector((C_TXBUFSIZE_BITS-1) downto 0) := (others=>'1');
279
  constant C_RXFULL : std_logic_vector((C_RXBUFSIZE_BITS-1) downto 0) := (others=>'1');
280
  constant C_RXEMPTY : std_logic_vector((C_RXBUFSIZE_BITS-1) downto 0) := (others=>'0');
281
 
282
begin  -- architecture akre
283
 
284
  -----------------------------------------------------------------------------
285
  -- Instanciating Components
286
  -----------------------------------------------------------------------------
287
 
288
  usb_serial_inst : usb_serial
289
    generic map (
290
        VENDORID => C_VENDORID,
291
        PRODUCTID => C_PRODUCTID,
292
        VERSIONBCD => C_VERSIONBCD,
293
        HSSUPPORT => false,
294
        SELFPOWERED => C_SELFPOWERED,
295
        RXBUFSIZE_BITS => C_RXBUFSIZE_BITS,
296
        TXBUFSIZE_BITS => C_TXBUFSIZE_BITS
297
    )
298
    port map (
299
        CLK => usb_clk, --in
300
        RESET => reset, --in
301
        USBRST => usbrst, --out
302
        HIGHSPEED => highspeed, --out
303
        SUSPEND => suspend, --out
304
        ONLINE => online, --out
305
        RXVAL => rxval, --out
306
        RXDAT => rxdat, --out
307
        RXRDY => rxrdy, --in
308
        RXLEN => rxlen, --out
309
        TXVAL => txval, --in
310
        TXDAT => txdat, --in
311
        TXRDY => txrdy, --out
312
        TXROOM => txroom, --out
313
        TXCORK => '0', --in
314
        PHY_DATAIN => phy_datain, --in
315
              PHY_DATAOUT => phy_dataout, --out
316
              PHY_TXVALID => phy_txvalid, --out
317
              PHY_TXREADY => phy_txready, --in
318
              PHY_RXACTIVE => phy_rxactive, --in
319
              PHY_RXVALID => phy_rxvalid, --in
320
              PHY_RXERROR => phy_rxerror, --in
321
              PHY_LINESTATE => phy_linestate, --in
322
              PHY_OPMODE  => open, --out
323
        PHY_XCVRSELECT => open, --out
324
        PHY_TERMSELECT => open, --out
325
              PHY_RESET => phy_reset --out
326
            );
327
 
328
  phy_resetn <= not(phy_reset);
329
 
330
  usb_phy_inst : usb_phy
331
    port map(
332
      clk => Usb_Clk, --in 48MHz
333
      rst => phy_resetn, --in
334
      phy_tx_mode => C_PHYMODE, --in
335
      usb_rst => phy_usb_rst, --out
336
                  txdp => txdp, --out
337
                  txdn => txdn, --out
338
                  txoe => txoe, --out
339
                  rxd => rxd, --in
340
                  rxdp => rxdp, --in
341
                  rxdn => rxdn, --in
342
                  DataOut_i => phy_dataout, --in
343
                  TxValid_i => phy_txvalid, --in
344
                  TxReady_o => phy_txready, --out
345
                  RxValid_o => phy_rxvalid, --out
346
                  RxActive_o => phy_rxactive, --out
347
                  RxError_o => phy_rxerror, --out
348
                  DataIn_o => phy_datain, --out
349
                  LineState_o => phy_linestate --out
350
    );
351
 
352
  -----------------------------------------------------------------------------
353
  -- Status register / Control register
354
  -----------------------------------------------------------------------------
355
  status_Reg(0) <= rx_Data_Present;
356
  status_Reg(1) <= rx_BUFFER_FULL;
357
  status_Reg(2) <= tx_Buffer_Empty;
358
  status_Reg(3) <= tx_BUFFER_FULL;
359
  status_Reg(4) <= Interrupt_r;
360
  status_Reg(5) <= '0';
361
  status_Reg(6) <= online;
362
  status_Reg(7) <= suspend;
363
--  status_Reg(6) <= '0';
364
--  status_Reg(7) <= '0';
365
 
366
 
367
  -----------------------------------------------------------------------------
368
  -- Control / Status Register Handling 
369
  -----------------------------------------------------------------------------
370
 
371
  process (clk, reset) is
372
  begin
373
    if (reset = '1') then                 -- asynchronous reset (active high)
374
      reset_TX_FIFO     <= '1';
375
      reset_RX_FIFO     <= '1';
376
      enable_rxinterrupts <= '0';
377
      enable_txinterrupts <= '0';
378
      TX_EN <= '0';
379
      xfer_Ack2 <= '0';
380
    elsif (clk'event and clk = '1') then  -- rising clock edge
381
      reset_TX_FIFO <= '0';
382
      reset_RX_FIFO <= '0';
383
      xfer_Ack2 <= '0';
384
      if (OPB_CS = '1') and (OPB_RNW = '0') and (OPB_ABus = CTRL_REG_ADR) then
385
        reset_TX_FIFO       <= OPB_DBus(0);
386
        reset_RX_FIFO       <= OPB_DBus(1);
387
        enable_rxinterrupts <= OPB_DBus(4);
388
        enable_txinterrupts <= OPB_DBus(6);
389
        TX_EN               <= OPB_DBus(7);
390
        xfer_Ack2 <= '1';
391
      end if;
392
      if (OPB_CS = '1') and (OPB_RNW = '1') and (OPB_ABus = STATUS_REG_ADR) then
393
        xfer_Ack2 <= '1';
394
      end if;
395
    end if;
396
  end process;
397
 
398
  -----------------------------------------------------------------------------
399
  -- Interrupt handling
400
  -----------------------------------------------------------------------------
401
 
402
  process (clk, reset)
403
  begin
404
    if reset = '1' then                 -- asynchronous reset (active high)
405
      Interrupt_r <= '0';
406
    elsif clk'event and clk = '1' then  -- rising clock edge
407
      Interrupt_r <= (enable_rxinterrupts and rx_Data_Present) or
408
                     (enable_txinterrupts and tx_Buffer_Empty);
409
    end if;
410
  end process;
411
 
412
  Interrupt <= Interrupt_r;
413
 
414
  -----------------------------------------------------------------------------
415
  -- Handling the OPB bus interface
416
  -----------------------------------------------------------------------------
417
 
418
  process (clk, OPB_CS) is
419
  begin
420
    if (OPB_CS='0') then
421
      xfer_Ack <= '0';
422
      SIn_DBus <= (others => '0');
423
    elsif (clk'event and clk='1') then
424
      xfer_Ack <= xfer_Ack1 or xfer_Ack2;
425
      SIn_DBus <= (others => '0');
426
      if (OPB_RNW='1') then
427
        if (OPB_ABus = STATUS_REG_ADR) then
428
          SIn_DBus(7 downto 0) <= status_reg;
429
        else
430
          SIn_DBus(7 downto 0) <= rxdat;
431
        end if;
432
      end if;
433
    end if;
434
  end process;
435
 
436
  SIn_xferAck <= xfer_Ack;
437
 
438
  -----------------------------------------------------------------------------
439
  -- Generating read and write pulses to the FIFOs
440
  -----------------------------------------------------------------------------
441
 
442
  process(clk,reset)
443
  begin
444
    if (reset='1') then
445
      read_RX_FIFO <= '0';
446
      write_TX_FIFO <= '0';
447
      xfer_Ack1 <= '0';
448
    elsif (clk'event and clk='1') then
449
      tx_BUFFER_EMPTY <= txempty;
450
      tx_BUFFER_FULL <= txfull;
451
      rx_Data_Present <= rxval;
452
      rx_Buffer_Full <= rxfull;
453
      write_TX_FIFO <= '0';
454
      read_RX_FIFO <= '0';
455
      xfer_Ack1 <= '0';
456
      if (OPB_CS='1' and OPB_RNW='0' and OPB_ABus=TX_FIFO_ADR) then
457
        txdat <= OPB_DBus(7 downto 0);
458
        write_TX_FIFO <= '1';
459
        xfer_Ack1 <= '1';
460
      end if;
461
      if (OPB_CS='1' and OPB_RNW='1' and OPB_ABus=RX_FIFO_ADR) then
462
        read_RX_FIFO <= '1';
463
        xfer_Ack1 <= '1';
464
      end if;
465
    end if;
466
  end process;
467
 
468
  -----------------------------------------------------------------------------
469
  -- Synchronization logic across clock domains 
470
  -----------------------------------------------------------------------------
471
 
472
  process(usb_clk, reset)
473
  begin
474
    if (reset='1') then
475
                read_RX_FIFO_r <= '0';
476
                read_RX_FIFO_rr <= '0';
477
                read_RX_FIFO_rrr <= '0';
478
                write_TX_FIFO_r <= '0';
479
                write_TX_FIFO_rr <= '0';
480
                write_TX_FIFO_rrr <= '0';
481
    elsif (usb_clk'event and usb_clk='1') then
482
      rxrdy <= '0';
483
      txval <= '0';
484
      txfull <= '0';
485
      rxfull <= '0';
486
      txfull <= '0';
487
      txempty <= '0';
488
      if (rxlen = C_RXFULL) then
489
        rxfull <= '1';
490
      end if;
491
      if (txroom = C_TXFULL) then
492
--        txfull <= '1';
493
        txfull <= online and not(suspend);
494
      end if;
495
      if (txroom = C_TXEMPTY) then
496
        txempty <= '1';
497
      end if;
498
      write_TX_FIFO_r <= write_TX_FIFO;
499
      write_TX_FIFO_rr <= write_TX_FIFO_r;
500
      write_TX_FIFO_rrr <= write_TX_FIFO_rr;
501
      read_RX_FIFO_r <= read_RX_FIFO;
502
      read_RX_FIFO_rr <= read_RX_FIFO_r;
503
      read_RX_FIFO_rrr <= read_RX_FIFO_rr;
504
      if (read_RX_FIFO_rrr='1' and read_RX_FIFO_rr='0') then
505
        rxrdy <= '1';
506
      end if;
507
      if (write_TX_FIFO_rrr='1' and write_TX_FIFO_rr='0') then
508
        txval <= '1';
509
      end if;
510
    end if;
511
  end process;
512
 
513
end architecture akre;
514
 
515
 
516
 

powered by: WebSVN 2.1.0

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