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 6

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 6 rehnmaak
--    it under the terms of the GNU Lesser General Public License as published by
12 2 rehnmaak
--    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 6 rehnmaak
--    GNU Lesser General Public License for more details.
19 2 rehnmaak
--
20 6 rehnmaak
--    You should have received a copy of the GNU Lesser General Public License
21 2 rehnmaak
--    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 5 rehnmaak
  --  ADDRESS MAP
191
  --  ===========
192
  --  RX FIFO      base + $0
193
  --  TX FIFO      base + $4
194
  --  CONTROL REG  base + $8
195
  --  STATUS REG   base + $C
196
 
197
 
198 2 rehnmaak
  -- Read Only
199
  signal status_Reg : std_logic_vector(7 downto 0);
200
  -- bit 0 rx_Data_Present
201
  -- bit 1 rx_Buffer_Full
202
  -- bit 2 tx_Buffer_Empty
203
  -- bit 3 tx_Buffer_Full
204
  -- bit 4 interrupt flag
205 5 rehnmaak
  -- bit 5 not used
206
  -- bit 6 online flag
207
  -- bit 7 suspend flag  
208 2 rehnmaak
 
209
  -- Write Only
210 5 rehnmaak
  -- bit 0   Reset_TX_FIFO -- not used
211
  -- bit 1   Reset_RX_FIFO -- not used
212 2 rehnmaak
  -- bit 2-3 Dont'Care
213
  -- bit 4   enable_rxinterrupts
214
  -- bit 5   Dont'Care
215
  -- bit 6   enable_txinterrupts
216 5 rehnmaak
  -- bit 7   tx_enable -- not used
217 2 rehnmaak
 
218
  signal enable_txinterrupts : std_logic;
219
  signal enable_rxinterrupts : std_logic;
220
 
221
  signal read_RX_FIFO      : std_logic;
222
  signal reset_RX_FIFO     : std_logic;
223
  signal TX_EN : std_logic;
224
  signal write_TX_FIFO   : std_logic;
225
  signal reset_TX_FIFO   : std_logic;
226
  signal tx_BUFFER_FULL  : std_logic;
227
  signal tx_Buffer_Empty : std_logic;
228
  signal rx_Data_Present  : std_logic;
229
  signal rx_BUFFER_FULL : std_logic;
230
 
231
  signal xfer_Ack     : std_logic;
232
  signal xfer_Ack1 : std_logic;
233
  signal xfer_Ack2 : std_logic;
234
  signal Interrupt_r : std_logic;
235
 
236
  signal read_rx_fifo_r : std_logic;
237
  signal read_rx_fifo_rr : std_logic;
238
  signal read_rx_fifo_rrr : std_logic;
239
  signal write_tx_fifo_r : std_logic;
240
  signal write_tx_fifo_rr : std_logic;
241
  signal write_tx_fifo_rrr : std_logic;
242
 
243
  signal usbrst : std_logic;
244
  signal rxval : std_logic;
245
 
246
  signal rxdat : std_logic_vector (7 downto 0);
247
  signal rxrdy : std_logic;
248
  signal txval : std_logic;
249
  signal txempty : std_logic;
250
  signal txfull : std_logic;
251
  signal rxfull : std_logic;
252
  signal txdat : std_logic_vector (7 downto 0);
253
  signal txrdy : std_logic;
254
 
255
  signal phy_datain : std_logic_vector (7 downto 0);
256
        signal phy_dataout : std_logic_vector (7 downto 0);
257
        signal phy_txvalid : std_logic;
258
        signal phy_txready : std_logic;
259
        signal phy_rxactive : std_logic;
260
        signal phy_rxvalid : std_logic;
261
        signal phy_rxerror : std_logic;
262
        signal phy_linestate : std_logic_vector (1 downto 0);
263
        signal phy_reset : std_logic;
264
        signal phy_resetn : std_logic;
265
        signal phy_usb_rst : std_logic;
266
 
267
  signal highspeed : std_logic;
268
  signal suspend : std_logic;
269
  signal online : std_logic;
270
  signal rxlen : std_logic_vector((C_RXBUFSIZE_BITS-1) downto 0);
271
  signal txroom : std_logic_vector((C_TXBUFSIZE_BITS-1) downto 0);
272
 
273
        attribute TIG : string;
274
        attribute TIG of Reset : signal is "yes";
275
        attribute TIG of write_TX_FIFO : signal is "yes";
276
        attribute TIG of read_RX_FIFO  : signal is "yes";
277
        attribute TIG of rxdat : signal is "yes";
278
        attribute TIG of txdat : signal is "yes";
279
        attribute TIG of rxval : signal is "yes";
280
        attribute TIG of txrdy : signal is "yes";
281
        attribute TIG of txempty : signal is "yes";
282
        attribute TIG of txfull : signal is "yes";
283
        attribute TIG of rxfull : signal is "yes";
284
 
285
        attribute TIG of online : signal is "yes";
286
        attribute TIG of suspend : signal is "yes";
287
 
288
  constant C_TXFULL : std_logic_vector((C_TXBUFSIZE_BITS-1) downto 0) := (others=>'0');
289
  constant C_TXEMPTY : std_logic_vector((C_TXBUFSIZE_BITS-1) downto 0) := (others=>'1');
290
  constant C_RXFULL : std_logic_vector((C_RXBUFSIZE_BITS-1) downto 0) := (others=>'1');
291
  constant C_RXEMPTY : std_logic_vector((C_RXBUFSIZE_BITS-1) downto 0) := (others=>'0');
292
 
293
begin  -- architecture akre
294
 
295
  -----------------------------------------------------------------------------
296
  -- Instanciating Components
297
  -----------------------------------------------------------------------------
298
 
299
  usb_serial_inst : usb_serial
300
    generic map (
301
        VENDORID => C_VENDORID,
302
        PRODUCTID => C_PRODUCTID,
303
        VERSIONBCD => C_VERSIONBCD,
304
        HSSUPPORT => false,
305
        SELFPOWERED => C_SELFPOWERED,
306
        RXBUFSIZE_BITS => C_RXBUFSIZE_BITS,
307
        TXBUFSIZE_BITS => C_TXBUFSIZE_BITS
308
    )
309
    port map (
310
        CLK => usb_clk, --in
311
        RESET => reset, --in
312
        USBRST => usbrst, --out
313
        HIGHSPEED => highspeed, --out
314
        SUSPEND => suspend, --out
315
        ONLINE => online, --out
316
        RXVAL => rxval, --out
317
        RXDAT => rxdat, --out
318
        RXRDY => rxrdy, --in
319
        RXLEN => rxlen, --out
320
        TXVAL => txval, --in
321
        TXDAT => txdat, --in
322
        TXRDY => txrdy, --out
323
        TXROOM => txroom, --out
324
        TXCORK => '0', --in
325
        PHY_DATAIN => phy_datain, --in
326
              PHY_DATAOUT => phy_dataout, --out
327
              PHY_TXVALID => phy_txvalid, --out
328
              PHY_TXREADY => phy_txready, --in
329
              PHY_RXACTIVE => phy_rxactive, --in
330
              PHY_RXVALID => phy_rxvalid, --in
331
              PHY_RXERROR => phy_rxerror, --in
332
              PHY_LINESTATE => phy_linestate, --in
333
              PHY_OPMODE  => open, --out
334
        PHY_XCVRSELECT => open, --out
335
        PHY_TERMSELECT => open, --out
336
              PHY_RESET => phy_reset --out
337
            );
338
 
339
  phy_resetn <= not(phy_reset);
340
 
341
  usb_phy_inst : usb_phy
342
    port map(
343
      clk => Usb_Clk, --in 48MHz
344
      rst => phy_resetn, --in
345
      phy_tx_mode => C_PHYMODE, --in
346
      usb_rst => phy_usb_rst, --out
347
                  txdp => txdp, --out
348
                  txdn => txdn, --out
349
                  txoe => txoe, --out
350
                  rxd => rxd, --in
351
                  rxdp => rxdp, --in
352
                  rxdn => rxdn, --in
353
                  DataOut_i => phy_dataout, --in
354
                  TxValid_i => phy_txvalid, --in
355
                  TxReady_o => phy_txready, --out
356
                  RxValid_o => phy_rxvalid, --out
357
                  RxActive_o => phy_rxactive, --out
358
                  RxError_o => phy_rxerror, --out
359
                  DataIn_o => phy_datain, --out
360
                  LineState_o => phy_linestate --out
361
    );
362
 
363
  -----------------------------------------------------------------------------
364
  -- Status register / Control register
365
  -----------------------------------------------------------------------------
366
  status_Reg(0) <= rx_Data_Present;
367
  status_Reg(1) <= rx_BUFFER_FULL;
368
  status_Reg(2) <= tx_Buffer_Empty;
369
  status_Reg(3) <= tx_BUFFER_FULL;
370
  status_Reg(4) <= Interrupt_r;
371
  status_Reg(5) <= '0';
372
  status_Reg(6) <= online;
373
  status_Reg(7) <= suspend;
374
 
375
 
376
  -----------------------------------------------------------------------------
377
  -- Control / Status Register Handling 
378
  -----------------------------------------------------------------------------
379
 
380
  process (clk, reset) is
381
  begin
382
    if (reset = '1') then                 -- asynchronous reset (active high)
383
      reset_TX_FIFO     <= '1';
384
      reset_RX_FIFO     <= '1';
385
      enable_rxinterrupts <= '0';
386
      enable_txinterrupts <= '0';
387
      TX_EN <= '0';
388
      xfer_Ack2 <= '0';
389
    elsif (clk'event and clk = '1') then  -- rising clock edge
390
      reset_TX_FIFO <= '0';
391
      reset_RX_FIFO <= '0';
392
      xfer_Ack2 <= '0';
393
      if (OPB_CS = '1') and (OPB_RNW = '0') and (OPB_ABus = CTRL_REG_ADR) then
394
        reset_TX_FIFO       <= OPB_DBus(0);
395
        reset_RX_FIFO       <= OPB_DBus(1);
396
        enable_rxinterrupts <= OPB_DBus(4);
397
        enable_txinterrupts <= OPB_DBus(6);
398
        TX_EN               <= OPB_DBus(7);
399
        xfer_Ack2 <= '1';
400
      end if;
401
      if (OPB_CS = '1') and (OPB_RNW = '1') and (OPB_ABus = STATUS_REG_ADR) then
402
        xfer_Ack2 <= '1';
403
      end if;
404
    end if;
405
  end process;
406
 
407
  -----------------------------------------------------------------------------
408
  -- Interrupt handling
409
  -----------------------------------------------------------------------------
410
 
411
  process (clk, reset)
412
  begin
413
    if reset = '1' then                 -- asynchronous reset (active high)
414
      Interrupt_r <= '0';
415
    elsif clk'event and clk = '1' then  -- rising clock edge
416
      Interrupt_r <= (enable_rxinterrupts and rx_Data_Present) or
417
                     (enable_txinterrupts and tx_Buffer_Empty);
418
    end if;
419
  end process;
420
 
421
  Interrupt <= Interrupt_r;
422
 
423
  -----------------------------------------------------------------------------
424
  -- Handling the OPB bus interface
425
  -----------------------------------------------------------------------------
426
 
427
  process (clk, OPB_CS) is
428
  begin
429
    if (OPB_CS='0') then
430
      xfer_Ack <= '0';
431
      SIn_DBus <= (others => '0');
432
    elsif (clk'event and clk='1') then
433
      xfer_Ack <= xfer_Ack1 or xfer_Ack2;
434
      SIn_DBus <= (others => '0');
435
      if (OPB_RNW='1') then
436
        if (OPB_ABus = STATUS_REG_ADR) then
437
          SIn_DBus(7 downto 0) <= status_reg;
438
        else
439
          SIn_DBus(7 downto 0) <= rxdat;
440
        end if;
441
      end if;
442
    end if;
443
  end process;
444
 
445
  SIn_xferAck <= xfer_Ack;
446
 
447
  -----------------------------------------------------------------------------
448
  -- Generating read and write pulses to the FIFOs
449
  -----------------------------------------------------------------------------
450
 
451
  process(clk,reset)
452
  begin
453
    if (reset='1') then
454
      read_RX_FIFO <= '0';
455
      write_TX_FIFO <= '0';
456
      xfer_Ack1 <= '0';
457
    elsif (clk'event and clk='1') then
458
      tx_BUFFER_EMPTY <= txempty;
459
      tx_BUFFER_FULL <= txfull;
460
      rx_Data_Present <= rxval;
461
      rx_Buffer_Full <= rxfull;
462
      write_TX_FIFO <= '0';
463
      read_RX_FIFO <= '0';
464
      xfer_Ack1 <= '0';
465
      if (OPB_CS='1' and OPB_RNW='0' and OPB_ABus=TX_FIFO_ADR) then
466
        txdat <= OPB_DBus(7 downto 0);
467
        write_TX_FIFO <= '1';
468
        xfer_Ack1 <= '1';
469
      end if;
470
      if (OPB_CS='1' and OPB_RNW='1' and OPB_ABus=RX_FIFO_ADR) then
471
        read_RX_FIFO <= '1';
472
        xfer_Ack1 <= '1';
473
      end if;
474
    end if;
475
  end process;
476
 
477
  -----------------------------------------------------------------------------
478
  -- Synchronization logic across clock domains 
479
  -----------------------------------------------------------------------------
480
 
481
  process(usb_clk, reset)
482
  begin
483
    if (reset='1') then
484
                read_RX_FIFO_r <= '0';
485
                read_RX_FIFO_rr <= '0';
486
                read_RX_FIFO_rrr <= '0';
487
                write_TX_FIFO_r <= '0';
488
                write_TX_FIFO_rr <= '0';
489
                write_TX_FIFO_rrr <= '0';
490
    elsif (usb_clk'event and usb_clk='1') then
491
      rxrdy <= '0';
492
      txval <= '0';
493
      txfull <= '0';
494
      rxfull <= '0';
495
      txfull <= '0';
496
      txempty <= '0';
497
      if (rxlen = C_RXFULL) then
498
        rxfull <= '1';
499
      end if;
500
      if (txroom = C_TXFULL) then
501
--        txfull <= '1';
502
        txfull <= online and not(suspend);
503
      end if;
504
      if (txroom = C_TXEMPTY) then
505
        txempty <= '1';
506
      end if;
507
      write_TX_FIFO_r <= write_TX_FIFO;
508
      write_TX_FIFO_rr <= write_TX_FIFO_r;
509
      write_TX_FIFO_rrr <= write_TX_FIFO_rr;
510
      read_RX_FIFO_r <= read_RX_FIFO;
511
      read_RX_FIFO_rr <= read_RX_FIFO_r;
512
      read_RX_FIFO_rrr <= read_RX_FIFO_rr;
513
      if (read_RX_FIFO_rrr='1' and read_RX_FIFO_rr='0') then
514
        rxrdy <= '1';
515
      end if;
516
      if (write_TX_FIFO_rrr='1' and write_TX_FIFO_rr='0') then
517
        txval <= '1';
518
      end if;
519
    end if;
520
  end process;
521
 
522
end architecture akre;
523
 
524
 
525
 

powered by: WebSVN 2.1.0

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