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

Subversion Repositories usb_phy

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /usb_phy/tags/start/rtl/verilog
    from Rev 3 to Rev 12
    Reverse comparison

Rev 3 → Rev 12

/usb_rx_phy.v
0,0 → 1,411
/////////////////////////////////////////////////////////////////////
//// ////
//// USB 1.1 PHY ////
//// RX & DPLL ////
//// ////
//// ////
//// Author: Rudolf Usselmann ////
//// rudi@asics.ws ////
//// ////
//// ////
//// Downloaded from: http://www.opencores.org/cores/usb_phy/ ////
//// ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000-2002 Rudolf Usselmann ////
//// www.asics.ws ////
//// rudi@asics.ws ////
//// ////
//// This source file may be used and distributed without ////
//// restriction provided that this copyright statement is not ////
//// removed from the file and that any derivative work contains ////
//// the original copyright notice and the associated disclaimer.////
//// ////
//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
//// POSSIBILITY OF SUCH DAMAGE. ////
//// ////
/////////////////////////////////////////////////////////////////////
 
// CVS Log
//
// $Id: usb_rx_phy.v,v 1.1.1.1 2002-09-16 14:27:01 rudi Exp $
//
// $Date: 2002-09-16 14:27:01 $
// $Revision: 1.1.1.1 $
// $Author: rudi $
// $Locker: $
// $State: Exp $
//
// Change History:
// $Log: not supported by cvs2svn $
//
//
//
//
//
//
//
 
`include "timescale.v"
 
module usb_rx_phy( clk, rst, fs_ce,
// Transciever Interface
rxd, rxdp, rxdn,
 
// UTMI Interface
RxValid_o, RxActive_o, RxError_o, DataIn_o,
RxEn_i, LineState);
 
input clk;
input rst;
output fs_ce;
input rxd, rxdp, rxdn;
output [7:0] DataIn_o;
output RxValid_o;
output RxActive_o;
output RxError_o;
input RxEn_i;
output [1:0] LineState;
 
///////////////////////////////////////////////////////////////////
//
// Local Wires and Registers
//
 
reg rxd_t1, rxd_s1, rxd_s;
reg rxdp_t1, rxdp_s1, rxdp_s;
reg rxdn_t1, rxdn_s1, rxdn_s;
reg synced_d;
wire k, j, se0;
reg rx_en;
reg rx_active;
reg [2:0] bit_cnt;
reg rx_valid1, rx_valid;
reg shift_en;
reg sd_r;
reg sd_nrzi;
reg [7:0] hold_reg;
wire drop_bit; // Indicates a stuffed bit
reg [2:0] one_cnt;
 
reg [1:0] dpll_state, dpll_next_state;
reg fs_ce_d, fs_ce;
wire change;
reg rxdp_s1r, rxdn_s1r;
wire lock_en;
reg fs_ce_r1, fs_ce_r2, fs_ce_r3;
reg [2:0] fs_state, fs_next_state;
reg rx_valid_r;
 
///////////////////////////////////////////////////////////////////
//
// Misc Logic
//
 
assign RxActive_o = rx_active;
assign RxValid_o = rx_valid;
assign RxError_o = 0;
assign DataIn_o = hold_reg;
assign LineState = {rxdp_s1, rxdn_s1};
 
always @(posedge clk)
rx_en <= #1 RxEn_i;
 
///////////////////////////////////////////////////////////////////
//
// Synchronize Inputs
//
 
// First synchronize to the local system clock to
// avoid metastability outside the sync block (*_s1)
// Second synchronise to the internal bit clock (*_s)
always @(posedge clk)
rxd_t1 <= #1 rxd;
 
always @(posedge clk)
rxd_s1 <= #1 rxd_t1;
 
always @(posedge clk)
rxd_s <= #1 rxd_s1;
 
always @(posedge clk)
rxdp_t1 <= #1 rxdp;
 
always @(posedge clk)
rxdp_s1 <= #1 rxdp_t1;
 
always @(posedge clk)
rxdp_s <= #1 rxdp_s1;
 
always @(posedge clk)
rxdn_t1 <= #1 rxdn;
 
always @(posedge clk)
rxdn_s1 <= #1 rxdn_t1;
 
always @(posedge clk)
rxdn_s <= #1 rxdn_s1;
 
assign k = !rxdp_s & rxdn_s;
assign j = rxdp_s & !rxdn_s;
assign se0 = !rxdp_s & !rxdn_s;
 
///////////////////////////////////////////////////////////////////
//
// DPLL
//
 
// This design uses a clock enable to do 12Mhz timing and not a
// real 12Mhz clock. Everything always runs at 48Mhz. We want to
// make sure however, that the clock enable is always exactly in
// the middle between two virtual 12Mhz rising edges.
// We monitor rxdp and rxdn for any changes and do the appropiate
// adjustments.
// In addition to the locking done in the dpll FSM, we adjust the
// final latch enable to compensate for various sync registers ...
 
// Allow lockinf only when we are receiving
assign lock_en = rx_en;
 
// Edge detector
always @(posedge clk)
rxdp_s1r <= #1 rxdp_s1;
 
always @(posedge clk)
rxdn_s1r <= #1 rxdn_s1;
 
assign change = (rxdp_s1r != rxdp_s1) | (rxdn_s1r != rxdn_s1);
 
// DPLL FSM
`ifdef USB_ASYNC_REST
always @(posedge clk or negedge rst)
`else
always @(posedge clk)
`endif
if(!rst) dpll_state <= #1 2'h1;
else dpll_state <= #1 dpll_next_state;
 
always @(dpll_state or lock_en or change)
begin
fs_ce_d = 1'b0;
case(dpll_state) // synopsys full_case parallel_case
2'h0:
if(lock_en & change) dpll_next_state = 3'h0;
else dpll_next_state = 3'h1;
2'h1:begin
fs_ce_d = 1'b1;
//if(lock_en & change) dpll_next_state = 3'h0;
if(lock_en & change) dpll_next_state = 3'h3;
else dpll_next_state = 3'h2;
end
2'h2:
if(lock_en & change) dpll_next_state = 3'h0;
else dpll_next_state = 3'h3;
2'h3:
if(lock_en & change) dpll_next_state = 3'h0;
else dpll_next_state = 3'h0;
endcase
end
 
// Compensate for sync registers at the input - allign full speed
// clock enable to be in the middle between two bit changes ...
always @(posedge clk)
fs_ce_r1 <= #1 fs_ce_d;
 
always @(posedge clk)
fs_ce_r2 <= #1 fs_ce_r1;
 
always @(posedge clk)
fs_ce_r3 <= #1 fs_ce_r2;
 
always @(posedge clk)
fs_ce <= #1 fs_ce_r3;
 
///////////////////////////////////////////////////////////////////
//
// Find Sync Pattern FSM
//
 
parameter FS_IDLE = 3'h0,
K1 = 3'h1,
J1 = 3'h2,
K2 = 3'h3,
J2 = 3'h4,
K3 = 3'h5,
J3 = 3'h6,
K4 = 3'h7;
 
`ifdef USB_ASYNC_REST
always @(posedge clk or negedge rst)
`else
always @(posedge clk)
`endif
if(!rst) fs_state <= #1 FS_IDLE;
else fs_state <= #1 fs_next_state;
 
always @(fs_state or fs_ce or k or j or rx_en)
begin
synced_d = 1'b0;
fs_next_state = fs_state;
if(fs_ce)
case(fs_state) // synopsys full_case parallel_case
FS_IDLE:
begin
if(k & rx_en) fs_next_state = K1;
end
K1:
begin
if(j & rx_en) fs_next_state = J1;
else fs_next_state = FS_IDLE;
end
J1:
begin
if(k & rx_en) fs_next_state = K2;
else fs_next_state = FS_IDLE;
end
K2:
begin
if(j & rx_en) fs_next_state = J2;
else fs_next_state = FS_IDLE;
end
J2:
begin
if(k & rx_en) fs_next_state = K3;
else fs_next_state = FS_IDLE;
end
K3:
begin
if(j & rx_en) fs_next_state = J3;
else
if(k & rx_en) fs_next_state = K4; // Allow missing one J
else fs_next_state = FS_IDLE;
end
J3:
begin
if(k & rx_en) fs_next_state = K4;
else fs_next_state = FS_IDLE;
end
K4:
begin
if(k) synced_d = 1'b1;
fs_next_state = FS_IDLE;
end
endcase
end
 
///////////////////////////////////////////////////////////////////
//
// Generate RxActive
//
 
`ifdef USB_ASYNC_REST
always @(posedge clk or negedge rst)
`else
always @(posedge clk)
`endif
if(!rst) rx_active <= #1 1'b0;
else
if(synced_d & rx_en) rx_active <= #1 1'b1;
else
if(se0 & rx_valid_r ) rx_active <= #1 1'b0;
 
always @(posedge clk)
if(rx_valid) rx_valid_r <= #1 1'b1;
else
if(fs_ce) rx_valid_r <= #1 1'b0;
 
///////////////////////////////////////////////////////////////////
//
// NRZI Decoder
//
 
always @(posedge clk)
if(fs_ce) sd_r <= #1 rxd_s;
 
`ifdef USB_ASYNC_REST
always @(posedge clk or negedge rst)
`else
always @(posedge clk)
`endif
if(!rst) sd_nrzi <= #1 1'b0;
else
if(rx_active & fs_ce) sd_nrzi <= #1 !(rxd_s ^ sd_r);
 
///////////////////////////////////////////////////////////////////
//
// Bit Stuff Detect
//
 
`ifdef USB_ASYNC_REST
always @(posedge clk or negedge rst)
`else
always @(posedge clk)
`endif
if(!rst) one_cnt <= #1 3'h0;
else
if(!shift_en) one_cnt <= #1 3'h0;
else
if(fs_ce)
begin
if(!sd_nrzi | drop_bit) one_cnt <= #1 3'h0;
else one_cnt <= #1 one_cnt + 3'h1;
end
 
assign drop_bit = (one_cnt==3'h6);
 
///////////////////////////////////////////////////////////////////
//
// Serial => Parallel converter
//
 
always @(posedge clk)
if(fs_ce) shift_en <= #1 synced_d | rx_active;
 
always @(posedge clk)
if(fs_ce & shift_en & !drop_bit)
hold_reg <= #1 {sd_nrzi, hold_reg[7:1]};
 
///////////////////////////////////////////////////////////////////
//
// Generate RxValid
//
 
`ifdef USB_ASYNC_REST
always @(posedge clk or negedge rst)
`else
always @(posedge clk)
`endif
if(!rst) bit_cnt <= #1 3'b0;
else
if(!shift_en) bit_cnt <= #1 3'h0;
else
if(fs_ce & !drop_bit) bit_cnt <= #1 bit_cnt + 3'h1;
 
`ifdef USB_ASYNC_REST
always @(posedge clk or negedge rst)
`else
always @(posedge clk)
`endif
if(!rst) rx_valid1 <= #1 1'b0;
else
if(fs_ce & !drop_bit & (bit_cnt==3'h7)) rx_valid1 <= #1 1'b1;
else
if(rx_valid1 & fs_ce & !drop_bit) rx_valid1 <= #1 1'b0;
 
always @(posedge clk)
rx_valid <= #1 !drop_bit & rx_valid1 & fs_ce;
 
endmodule
 
/usb_tx_phy.v
0,0 → 1,451
/////////////////////////////////////////////////////////////////////
//// ////
//// USB 1.1 PHY ////
//// TX ////
//// ////
//// ////
//// Author: Rudolf Usselmann ////
//// rudi@asics.ws ////
//// ////
//// ////
//// Downloaded from: http://www.opencores.org/cores/usb_phy/ ////
//// ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000-2002 Rudolf Usselmann ////
//// www.asics.ws ////
//// rudi@asics.ws ////
//// ////
//// This source file may be used and distributed without ////
//// restriction provided that this copyright statement is not ////
//// removed from the file and that any derivative work contains ////
//// the original copyright notice and the associated disclaimer.////
//// ////
//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
//// POSSIBILITY OF SUCH DAMAGE. ////
//// ////
/////////////////////////////////////////////////////////////////////
 
// CVS Log
//
// $Id: usb_tx_phy.v,v 1.1.1.1 2002-09-16 14:27:02 rudi Exp $
//
// $Date: 2002-09-16 14:27:02 $
// $Revision: 1.1.1.1 $
// $Author: rudi $
// $Locker: $
// $State: Exp $
//
// Change History:
// $Log: not supported by cvs2svn $
//
//
//
//
//
//
 
`include "timescale.v"
 
module usb_tx_phy(
clk, rst, fs_ce, phy_mode,
// Transciever Interface
txdp, txdn, txoe,
 
// UTMI Interface
DataOut_i, TxValid_i, TxReady_o
);
 
input clk;
input rst;
input fs_ce;
input phy_mode;
output txdp, txdn, txoe;
input [7:0] DataOut_i;
input TxValid_i;
output TxReady_o;
 
///////////////////////////////////////////////////////////////////
//
// Local Wires and Registers
//
 
parameter IDLE = 3'd0,
SOP = 3'h1,
DATA = 3'h2,
EOP1 = 3'h3,
EOP2 = 3'h4,
WAIT = 3'h5;
 
reg TxReady_o;
reg [2:0] state, next_state;
reg tx_ready;
reg tx_ready_d;
reg ld_sop_d;
reg ld_data_d;
reg ld_eop_d;
reg tx_ip;
reg tx_ip_sync;
reg [2:0] bit_cnt;
reg [7:0] hold_reg;
reg sd_raw_o;
wire hold;
reg data_done;
reg sft_done;
reg sft_done_r;
wire sft_done_e;
reg ld_data;
wire eop_done;
reg [2:0] one_cnt;
wire stuff;
reg sd_bs_o;
reg sd_nrzi_o;
reg append_eop;
reg append_eop_sync1;
reg append_eop_sync2;
reg append_eop_sync3;
reg txdp, txdn;
reg txoe_r1, txoe_r2;
reg txoe;
 
///////////////////////////////////////////////////////////////////
//
// Misc Logic
//
 
always @(posedge clk)
tx_ready <= #1 tx_ready_d;
 
`ifdef USB_ASYNC_REST
always @(posedge clk or negedge rst)
`else
always @(posedge clk)
`endif
if(!rst) TxReady_o <= #1 1'b0;
else TxReady_o <= #1 tx_ready_d & TxValid_i;
 
always @(posedge clk)
ld_data <= #1 ld_data_d;
 
///////////////////////////////////////////////////////////////////
//
// Transmit in progress indicator
//
 
`ifdef USB_ASYNC_REST
always @(posedge clk or negedge rst)
`else
always @(posedge clk)
`endif
if(!rst) tx_ip <= #1 1'b0;
else
if(ld_sop_d) tx_ip <= #1 1'b1;
else
if(eop_done) tx_ip <= #1 1'b0;
 
`ifdef USB_ASYNC_REST
always @(posedge clk or negedge rst)
`else
always @(posedge clk)
`endif
if(!rst) tx_ip_sync <= #1 1'b0;
else
if(fs_ce) tx_ip_sync <= #1 tx_ip;
 
// data_done helps us to catch cases where TxValid drops due to
// packet end and then gets re-asserted as a new packet starts.
// We might not see this because we are still transmitting.
// data_done should solve those cases ...
`ifdef USB_ASYNC_REST
always @(posedge clk or negedge rst)
`else
always @(posedge clk)
`endif
if(!rst) data_done <= #1 1'b0;
else
if(TxValid_i & ! tx_ip) data_done <= #1 1'b1;
else
if(!TxValid_i) data_done <= #1 1'b0;
 
///////////////////////////////////////////////////////////////////
//
// Shift Register
//
 
`ifdef USB_ASYNC_REST
always @(posedge clk or negedge rst)
`else
always @(posedge clk)
`endif
if(!rst) bit_cnt <= #1 3'h0;
else
if(!tx_ip_sync) bit_cnt <= #1 3'h0;
else
if(fs_ce & !hold) bit_cnt <= #1 bit_cnt + 3'h1;
 
assign hold = stuff;
 
always @(posedge clk)
if(!tx_ip_sync) sd_raw_o <= #1 1'b0;
else
case(bit_cnt) // synopsys full_case parallel_case
3'h0: sd_raw_o <= #1 hold_reg[0];
3'h1: sd_raw_o <= #1 hold_reg[1];
3'h2: sd_raw_o <= #1 hold_reg[2];
3'h3: sd_raw_o <= #1 hold_reg[3];
3'h4: sd_raw_o <= #1 hold_reg[4];
3'h5: sd_raw_o <= #1 hold_reg[5];
3'h6: sd_raw_o <= #1 hold_reg[6];
3'h7: sd_raw_o <= #1 hold_reg[7];
endcase
 
always @(posedge clk)
sft_done <= #1 !hold & (bit_cnt == 3'h7);
 
always @(posedge clk)
sft_done_r <= #1 sft_done;
 
assign sft_done_e = sft_done & !sft_done_r;
 
// Out Data Hold Register
always @(posedge clk)
if(ld_sop_d) hold_reg <= #1 8'h80;
else
if(ld_data) hold_reg <= #1 DataOut_i;
 
///////////////////////////////////////////////////////////////////
//
// Bit Stuffer
//
 
`ifdef USB_ASYNC_REST
always @(posedge clk or negedge rst)
`else
always @(posedge clk)
`endif
if(!rst) one_cnt <= #1 3'h0;
else
if(!tx_ip_sync) one_cnt <= #1 3'h0;
else
if(fs_ce)
begin
if(!sd_raw_o | stuff) one_cnt <= #1 3'h0;
else one_cnt <= #1 one_cnt + 3'h1;
end
 
assign stuff = (one_cnt==3'h6);
 
`ifdef USB_ASYNC_REST
always @(posedge clk or negedge rst)
`else
always @(posedge clk)
`endif
if(!rst) sd_bs_o <= #1 1'h0;
else
if(fs_ce) sd_bs_o <= #1 !tx_ip_sync ? 1'b0 :
(stuff ? 1'b0 : sd_raw_o);
 
///////////////////////////////////////////////////////////////////
//
// NRZI Encoder
//
 
`ifdef USB_ASYNC_REST
always @(posedge clk or negedge rst)
`else
always @(posedge clk)
`endif
if(!rst) sd_nrzi_o <= #1 1'b1;
else
if(!tx_ip_sync | !txoe_r1) sd_nrzi_o <= #1 1'b1;
else
if(fs_ce) sd_nrzi_o <= #1 sd_bs_o ? sd_nrzi_o : ~sd_nrzi_o;
 
///////////////////////////////////////////////////////////////////
//
// EOP append logic
//
 
`ifdef USB_ASYNC_REST
always @(posedge clk or negedge rst)
`else
always @(posedge clk)
`endif
if(!rst) append_eop <= #1 1'b0;
else
if(ld_eop_d) append_eop <= #1 1'b1;
else
if(append_eop_sync2) append_eop <= #1 1'b0;
 
`ifdef USB_ASYNC_REST
always @(posedge clk or negedge rst)
`else
always @(posedge clk)
`endif
if(!rst) append_eop_sync1 <= #1 1'b0;
else
if(fs_ce) append_eop_sync1 <= #1 append_eop;
 
`ifdef USB_ASYNC_REST
always @(posedge clk or negedge rst)
`else
always @(posedge clk)
`endif
if(!rst) append_eop_sync2 <= #1 1'b0;
else
if(fs_ce) append_eop_sync2 <= #1 append_eop_sync1;
 
`ifdef USB_ASYNC_REST
always @(posedge clk or negedge rst)
`else
always @(posedge clk)
`endif
if(!rst) append_eop_sync3 <= #1 1'b0;
else
if(fs_ce) append_eop_sync3 <= #1 append_eop_sync2;
 
assign eop_done = append_eop_sync3;
 
///////////////////////////////////////////////////////////////////
//
// Output Enable Logic
//
 
`ifdef USB_ASYNC_REST
always @(posedge clk or negedge rst)
`else
always @(posedge clk)
`endif
if(!rst) txoe_r1 <= #1 1'b0;
else
if(fs_ce) txoe_r1 <= #1 tx_ip_sync;
 
`ifdef USB_ASYNC_REST
always @(posedge clk or negedge rst)
`else
always @(posedge clk)
`endif
if(!rst) txoe_r2 <= #1 1'b0;
else
if(fs_ce) txoe_r2 <= #1 txoe_r1;
 
`ifdef USB_ASYNC_REST
always @(posedge clk or negedge rst)
`else
always @(posedge clk)
`endif
if(!rst) txoe <= #1 1'b1;
else
if(fs_ce) txoe <= #1 !(txoe_r1 | txoe_r2);
 
///////////////////////////////////////////////////////////////////
//
// Output Registers
//
 
`ifdef USB_ASYNC_REST
always @(posedge clk or negedge rst)
`else
always @(posedge clk)
`endif
if(!rst) txdp <= #1 1'b1;
else
if(fs_ce) txdp <= #1 phy_mode ?
(!append_eop_sync3 & sd_nrzi_o) :
sd_nrzi_o;
 
`ifdef USB_ASYNC_REST
always @(posedge clk or negedge rst)
`else
always @(posedge clk)
`endif
if(!rst) txdn <= #1 1'b0;
else
if(fs_ce) txdn <= #1 phy_mode ?
(!append_eop_sync3 & ~sd_nrzi_o) :
append_eop_sync3;
 
///////////////////////////////////////////////////////////////////
//
// Tx Statemashine
//
 
`ifdef USB_ASYNC_REST
always @(posedge clk or negedge rst)
`else
always @(posedge clk)
`endif
if(!rst) state <= #1 IDLE;
else state <= #1 next_state;
 
always @(state or TxValid_i or data_done or sft_done_e or eop_done or fs_ce)
begin
next_state = state;
tx_ready_d = 1'b0;
 
ld_sop_d = 1'b0;
ld_data_d = 1'b0;
ld_eop_d = 1'b0;
 
case(state) // synopsys full_case parallel_case
IDLE:
begin
if(TxValid_i)
begin
ld_sop_d = 1'b1;
next_state = SOP;
end
end
SOP:
begin
if(sft_done_e)
begin
tx_ready_d = 1'b1;
ld_data_d = 1'b1;
next_state = DATA;
end
end
DATA:
begin
if(!data_done & sft_done_e)
begin
ld_eop_d = 1'b1;
next_state = EOP1;
end
if(data_done & sft_done_e)
begin
tx_ready_d = 1'b1;
ld_data_d = 1'b1;
end
end
EOP1:
begin
if(eop_done) next_state = EOP2;
end
EOP2:
begin
if(!eop_done & fs_ce) next_state = WAIT;
end
WAIT:
begin
if(fs_ce) next_state = IDLE;
end
endcase
end
 
endmodule
 
/timescale.v
0,0 → 1,451
`timescale 1ns / 10ps
/usb_phy.v
0,0 → 1,165
/////////////////////////////////////////////////////////////////////
//// ////
//// USB 1.1 PHY ////
//// ////
//// ////
//// Author: Rudolf Usselmann ////
//// rudi@asics.ws ////
//// ////
//// ////
//// Downloaded from: http://www.opencores.org/cores/usb_phy/ ////
//// ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000-2002 Rudolf Usselmann ////
//// www.asics.ws ////
//// rudi@asics.ws ////
//// ////
//// This source file may be used and distributed without ////
//// restriction provided that this copyright statement is not ////
//// removed from the file and that any derivative work contains ////
//// the original copyright notice and the associated disclaimer.////
//// ////
//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
//// POSSIBILITY OF SUCH DAMAGE. ////
//// ////
/////////////////////////////////////////////////////////////////////
 
// CVS Log
//
// $Id: usb_phy.v,v 1.1.1.1 2002-09-16 14:26:59 rudi Exp $
//
// $Date: 2002-09-16 14:26:59 $
// $Revision: 1.1.1.1 $
// $Author: rudi $
// $Locker: $
// $State: Exp $
//
// Change History:
// $Log: not supported by cvs2svn $
//
//
//
//
//
//
//
 
`include "timescale.v"
 
module usbf_phy(clk, rst, phy_tx_mode, usb_rst,
// Transciever Interface
txdp, txdn, txoe,
rxd, rxdp, rxdn,
 
// UTMI Interface
DataOut_i, TxValid_i, TxReady_o, RxValid_o,
RxActive_o, RxError_o, DataIn_o, LineState_o
);
 
input clk;
input rst;
input phy_tx_mode;
output usb_rst;
output txdp, txdn, txoe;
input rxd, rxdp, rxdn;
input [7:0] DataOut_i;
input TxValid_i;
output TxReady_o;
output [7:0] DataIn_o;
output RxValid_o;
output RxActive_o;
output RxError_o;
output [1:0] LineState_o;
 
///////////////////////////////////////////////////////////////////
//
// Local Wires and Registers
//
 
reg [5:0] rst_cnt;
reg usb_rst;
wire reset;
 
///////////////////////////////////////////////////////////////////
//
// Misc Logic
//
 
assign reset = rst & ~usb_rst;
 
///////////////////////////////////////////////////////////////////
//
// TX Phy
//
 
usb_tx_phy i_tx_phy(
.clk( clk ),
.rst( reset ),
.fs_ce( fs_ce ),
.phy_mode( phy_tx_mode ),
 
// Transciever Interface
.txdp( txdp ),
.txdn( txdn ),
.txoe( txoe ),
 
// UTMI Interface
.DataOut_i( DataOut_i ),
.TxValid_i( TxValid_i ),
.TxReady_o( TxReady_o )
);
 
///////////////////////////////////////////////////////////////////
//
// RX Phy and DPLL
//
 
usb_rx_phy i_rx_phy(
.clk( clk ),
.rst( reset ),
.fs_ce( fs_ce ),
 
// Transciever Interface
.rxd( rxd ),
.rxdp( rxdp ),
.rxdn( rxdn ),
 
// UTMI Interface
.DataIn_o( DataIn_o ),
.RxValid_o( RxValid_o ),
.RxActive_o( RxActive_o ),
.RxError_o( RxError_o ),
.RxEn_i( txoe ),
.LineState( LineState_o )
);
 
///////////////////////////////////////////////////////////////////
//
// Generate an USB Reset is we see SE0 for at least 2.5uS
//
 
always @(posedge clk)
if(!rst) rst_cnt <= #1 5'h0;
else
if(LineState_o != 2'h0) rst_cnt <= #1 5'h0;
else
if(!usb_rst & fs_ce) rst_cnt <= #1 rst_cnt + 5'h1;
 
always @(posedge clk)
usb_rst <= #1 (rst_cnt == 5'd31);
 
endmodule
 

powered by: WebSVN 2.1.0

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