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

Subversion Repositories ulpi_wrapper

[/] [ulpi_wrapper/] [trunk/] [rtl/] [ulpi_wrapper.v] - Diff between revs 2 and 3

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 2 Rev 3
Line 46... Line 46...
    output [7:0]      ulpi_data_o,
    output [7:0]      ulpi_data_o,
    input             ulpi_dir_i,
    input             ulpi_dir_i,
    input             ulpi_nxt_i,
    input             ulpi_nxt_i,
    output            ulpi_stp_o,
    output            ulpi_stp_o,
 
 
 
    // Register access (Wishbone pipelined access type)
 
    // NOTE: Tie inputs to 0 if unused
 
    input [7:0]       reg_addr_i,
 
    input             reg_stb_i,
 
    input             reg_we_i,
 
    input [7:0]       reg_data_i,
 
    output [7:0]      reg_data_o,
 
    output            reg_ack_o,
 
 
    // UTMI Interface (SIE)
    // UTMI Interface (SIE)
    input             utmi_txvalid_i,
    input             utmi_txvalid_i,
    output            utmi_txready_o,
    output            utmi_txready_o,
    output            utmi_rxvalid_o,
    output            utmi_rxvalid_o,
    output            utmi_rxactive_o,
    output            utmi_rxactive_o,
Line 69... Line 78...
//-----------------------------------------------------------------
//-----------------------------------------------------------------
localparam STATE_W          = 2;
localparam STATE_W          = 2;
localparam STATE_IDLE       = 2'd0;
localparam STATE_IDLE       = 2'd0;
localparam STATE_CMD        = 2'd1;
localparam STATE_CMD        = 2'd1;
localparam STATE_DATA       = 2'd2;
localparam STATE_DATA       = 2'd2;
localparam STATE_WAIT       = 2'd3;
localparam STATE_REG        = 2'd3;
 
 
reg [STATE_W-1:0]   state_q;
reg [STATE_W-1:0]   state_q;
 
 
//-----------------------------------------------------------------
//-----------------------------------------------------------------
 
// Local Params
 
//-----------------------------------------------------------------
 
localparam REG_FUNC_CTRL = 8'h84;
 
localparam REG_OTG_CTRL  = 8'h8a;
 
localparam REG_TRANSMIT  = 8'h40;
 
localparam REG_WRITE     = 8'h80;
 
localparam REG_READ      = 8'hC0;
 
 
 
//-----------------------------------------------------------------
// UTMI Mode Select
// UTMI Mode Select
//-----------------------------------------------------------------
//-----------------------------------------------------------------
reg         mode_update_q;
reg         mode_update_q;
reg [1:0]   xcvrselect_q;
reg [1:0]   xcvrselect_q;
reg         termselect_q;
reg         termselect_q;
reg [1:0]   opmode_q;
reg [1:0]   opmode_q;
reg         phy_reset_q;
reg         phy_reset_q;
 
reg         auto_wr_q;
 
reg         reg_wr_q;
 
 
always @ (posedge ulpi_clk60_i or posedge ulpi_rst_i)
always @ (posedge ulpi_clk60_i or posedge ulpi_rst_i)
if (ulpi_rst_i)
if (ulpi_rst_i)
begin
begin
    mode_update_q   <= 1'b0;
    mode_update_q   <= 1'b0;
Line 97... Line 117...
begin
begin
    xcvrselect_q    <= utmi_xcvrselect_i;
    xcvrselect_q    <= utmi_xcvrselect_i;
    termselect_q    <= utmi_termselect_i;
    termselect_q    <= utmi_termselect_i;
    opmode_q        <= utmi_opmode_i;
    opmode_q        <= utmi_opmode_i;
 
 
    if (mode_update_q && (state_q == STATE_IDLE) && !ulpi_dir_i)
    if (mode_update_q && (state_q == STATE_CMD) && (ulpi_data_o == REG_FUNC_CTRL))
    begin
    begin
        mode_update_q <= 1'b0;
        mode_update_q <= 1'b0;
        phy_reset_q   <= 1'b0;
        phy_reset_q   <= 1'b0;
    end
    end
    else if (opmode_q     != utmi_opmode_i     ||
    else if (opmode_q     != utmi_opmode_i     ||
Line 127... Line 147...
else
else
begin
begin
    dppulldown_q    <= utmi_dppulldown_i;
    dppulldown_q    <= utmi_dppulldown_i;
    dmpulldown_q    <= utmi_dmpulldown_i;
    dmpulldown_q    <= utmi_dmpulldown_i;
 
 
    if (otg_update_q && !mode_update_q && (state_q == STATE_IDLE) && !ulpi_dir_i)
    if (otg_update_q && (state_q == STATE_CMD) && (ulpi_data_o == REG_OTG_CTRL))
        otg_update_q <= 1'b0;
        otg_update_q <= 1'b0;
    else if (dppulldown_q != utmi_dppulldown_i ||
    else if (dppulldown_q != utmi_dppulldown_i ||
             dmpulldown_q != utmi_dmpulldown_i)
             dmpulldown_q != utmi_dmpulldown_i)
        otg_update_q <= 1'b1;
        otg_update_q <= 1'b1;
end
end
Line 147... Line 167...
else
else
    ulpi_dir_q <= ulpi_dir_i;
    ulpi_dir_q <= ulpi_dir_i;
 
 
wire turnaround_w = ulpi_dir_q ^ ulpi_dir_i;
wire turnaround_w = ulpi_dir_q ^ ulpi_dir_i;
 
 
 
reg ulpi_rxcmd_q;
 
always @ (posedge ulpi_clk60_i or posedge ulpi_rst_i)
 
if (ulpi_rst_i)
 
    ulpi_rxcmd_q <= 1'b0;
 
// Switch to input with NXT asserted in turnaround cycle
 
else if (!ulpi_dir_q && ulpi_dir_i && ulpi_nxt_i)
 
    ulpi_rxcmd_q <= 1'b1;
 
// Switch to output (turnaround cycle)
 
else if (ulpi_dir_q && !ulpi_dir_i)
 
    ulpi_rxcmd_q <= 1'b0;
 
 
 
//-----------------------------------------------------------------
 
// Register Access
 
//-----------------------------------------------------------------
 
reg       reg_wr_pending_q;
 
reg       reg_rd_pending_q;
 
reg [7:0] reg_addr_q;
 
reg [7:0] reg_data_q;
 
reg       reg_ack_q;
 
 
 
wire reg_ready_w = (reg_wr_pending_q && state_q == STATE_REG && ulpi_nxt_i && reg_wr_q) ||
 
                   (reg_rd_pending_q && !turnaround_w && ulpi_dir_i && !ulpi_rxcmd_q);
 
 
 
always @ (posedge ulpi_clk60_i or posedge ulpi_rst_i)
 
if (ulpi_rst_i)
 
begin
 
    reg_wr_pending_q    <= 1'b0;
 
    reg_rd_pending_q    <= 1'b0;
 
    reg_addr_q          <= 8'b0;
 
end
 
else if (reg_stb_i)
 
begin
 
    reg_addr_q          <= reg_addr_i;
 
    reg_wr_pending_q    <= reg_we_i;
 
    reg_rd_pending_q    <= ~reg_we_i;
 
end
 
else if (reg_ready_w)
 
begin
 
    reg_wr_pending_q    <= 1'b0;
 
    reg_rd_pending_q    <= 1'b0;
 
end
 
 
 
always @ (posedge ulpi_clk60_i or posedge ulpi_rst_i)
 
if (ulpi_rst_i)
 
    reg_data_q  <= 8'b0;
 
else if (reg_stb_i && reg_we_i)
 
    reg_data_q  <= reg_data_i;
 
 
 
assign reg_data_o = utmi_data_o;
 
 
 
always @ (posedge ulpi_clk60_i or posedge ulpi_rst_i)
 
if (ulpi_rst_i)
 
    reg_ack_q  <= 1'b0;
 
else
 
    reg_ack_q  <= reg_ready_w;
 
 
 
assign reg_ack_o = reg_ack_q;
 
 
//-----------------------------------------------------------------
//-----------------------------------------------------------------
// Rx - Tx delay
// Rx - Tx delay
//-----------------------------------------------------------------
//-----------------------------------------------------------------
localparam TX_DELAY_W       = 3;
localparam TX_DELAY_W       = 3;
localparam TX_START_DELAY   = 3'd7;
localparam TX_START_DELAY   = 3'd7;
Line 230... Line 308...
reg                 utmi_rxerror_q;
reg                 utmi_rxerror_q;
reg                 utmi_rxactive_q;
reg                 utmi_rxactive_q;
reg [1:0]           utmi_linestate_q;
reg [1:0]           utmi_linestate_q;
reg [7:0]           utmi_data_q;
reg [7:0]           utmi_data_q;
 
 
reg                 cmd_wr_q;
 
 
 
localparam REG_FUNC_CTRL = 8'h84;
 
localparam REG_OTG_CTRL  = 8'h8a;
 
localparam REG_TRANSMIT  = 8'h40;
 
localparam REG_WRITE     = 8'h80;
 
localparam REG_READ      = 8'hC0;
 
 
 
always @ (posedge ulpi_clk60_i or posedge ulpi_rst_i)
always @ (posedge ulpi_clk60_i or posedge ulpi_rst_i)
begin
begin
    if (ulpi_rst_i)
    if (ulpi_rst_i)
    begin
    begin
        state_q             <= STATE_IDLE;
        state_q             <= STATE_IDLE;
Line 252... Line 322...
        utmi_rxvalid_q      <= 1'b0;
        utmi_rxvalid_q      <= 1'b0;
        utmi_rxerror_q      <= 1'b0;
        utmi_rxerror_q      <= 1'b0;
        utmi_rxactive_q     <= 1'b0;
        utmi_rxactive_q     <= 1'b0;
        utmi_linestate_q    <= 2'b0;
        utmi_linestate_q    <= 2'b0;
        utmi_data_q         <= 8'b0;
        utmi_data_q         <= 8'b0;
        cmd_wr_q            <= 1'b0;
        auto_wr_q           <= 1'b0;
 
        reg_wr_q            <= 1'b0;
    end
    end
    else
    else
    begin
    begin
        ulpi_stp_q          <= 1'b0;
        ulpi_stp_q          <= 1'b0;
        utmi_rxvalid_q      <= 1'b0;
        utmi_rxvalid_q      <= 1'b0;
 
 
        if (!turnaround_w)
        if (!turnaround_w)
        begin
        begin
            //-----------------------------------------------------------------
            //-----------------------------------------------------------------
            // Input
            // Input: RX_DATA
            //-----------------------------------------------------------------
            //-----------------------------------------------------------------
            if (ulpi_dir_i)
            if (ulpi_dir_i && ulpi_rxcmd_q)
            begin
            begin
                utmi_rxvalid_q  <= ulpi_nxt_i;
                utmi_rxvalid_q  <= ulpi_nxt_i;
                utmi_data_q     <= ulpi_data_i;
                utmi_data_q     <= ulpi_data_i;
 
 
                // No valid data, extract phy status 
                // No valid data, extract phy status 
Line 299... Line 370...
                // RxValid (so force RxActive)
                // RxValid (so force RxActive)
                else
                else
                    utmi_rxactive_q <= 1'b1;
                    utmi_rxactive_q <= 1'b1;
            end
            end
            //-----------------------------------------------------------------
            //-----------------------------------------------------------------
 
            // Input: REG_DATA
 
            //-----------------------------------------------------------------
 
            else if (ulpi_dir_i)
 
            begin
 
                utmi_rxvalid_q  <= 1'b0;
 
                utmi_data_q     <= ulpi_data_i;
 
            end
 
            //-----------------------------------------------------------------
            // Output
            // Output
            //-----------------------------------------------------------------
            //-----------------------------------------------------------------
            else
            else
            begin
            begin
                // IDLE: Pending mode update
                // IDLE: Pending mode update
Line 310... Line 389...
                begin
                begin
                    data_q      <= {1'b0, 1'b1, phy_reset_q, opmode_q, termselect_q, xcvrselect_q};
                    data_q      <= {1'b0, 1'b1, phy_reset_q, opmode_q, termselect_q, xcvrselect_q};
                    ulpi_data_q <= REG_FUNC_CTRL;
                    ulpi_data_q <= REG_FUNC_CTRL;
 
 
                    state_q     <= STATE_CMD;
                    state_q     <= STATE_CMD;
                    cmd_wr_q    <= 1'b1;
                    auto_wr_q   <= 1'b1;
 
                    reg_wr_q    <= 1'b0;
                end
                end
                // IDLE: Pending OTG control update
                // IDLE: Pending OTG control update
                else if ((state_q == STATE_IDLE) && otg_update_q)
                else if ((state_q == STATE_IDLE) && otg_update_q)
                begin
                begin
                    data_q      <= {5'b0, dmpulldown_q, dppulldown_q, 1'b0};
                    data_q      <= {5'b0, dmpulldown_q, dppulldown_q, 1'b0};
                    ulpi_data_q <= REG_OTG_CTRL;
                    ulpi_data_q <= REG_OTG_CTRL;
 
 
                    state_q     <= STATE_CMD;
                    state_q     <= STATE_CMD;
                    cmd_wr_q    <= 1'b1;
                    auto_wr_q   <= 1'b1;
 
                    reg_wr_q    <= 1'b0;
 
                end
 
                // IDLE: Pending register access
 
                else if ((state_q == STATE_IDLE) && (reg_wr_pending_q || reg_rd_pending_q))
 
                begin
 
                    data_q      <= reg_data_q;
 
 
 
                    if (reg_wr_pending_q)
 
                        ulpi_data_q <= REG_WRITE | {2'b0, reg_addr_q[5:0]};
 
                    else
 
                        ulpi_data_q <= REG_READ  | {2'b0, reg_addr_q[5:0]};
 
 
 
                    state_q     <= STATE_CMD;
 
                    auto_wr_q   <= 1'b0;
 
                    reg_wr_q    <= reg_wr_pending_q;
                end
                end
                // IDLE: Pending transmit
                // IDLE: Pending transmit
                else if ((state_q == STATE_IDLE) && utmi_tx_ready_w)
                else if ((state_q == STATE_IDLE) && utmi_tx_ready_w)
                begin
                begin
                    ulpi_data_q <= REG_TRANSMIT | {4'b0, utmi_tx_data_w[3:0]};
                    ulpi_data_q <= REG_TRANSMIT | {4'b0, utmi_tx_data_w[3:0]};
                    state_q     <= STATE_DATA;
                    state_q     <= STATE_DATA;
                    cmd_wr_q    <= 1'b0;
                    auto_wr_q   <= 1'b0;
 
                    reg_wr_q    <= 1'b0;
                end
                end
                // Command
                // Command
                else if ((state_q == STATE_CMD) && ulpi_nxt_i)
                else if ((state_q == STATE_CMD) && ulpi_nxt_i)
                begin
                begin
                    state_q     <= STATE_DATA;
                    // Read Register
 
                    if (!reg_wr_q && !auto_wr_q)
 
                    begin
 
                        state_q     <= STATE_IDLE;
 
                        ulpi_data_q <= 8'b0;
 
                    end
 
                    // Write Register
 
                    else
 
                    begin
 
                        state_q     <= STATE_REG;
                    ulpi_data_q <= data_q;
                    ulpi_data_q <= data_q;
                end
                end
 
                end
 
                // Data (register write)
 
                else if (state_q == STATE_REG && ulpi_nxt_i)
 
                begin
 
                    state_q       <= STATE_IDLE;
 
                    ulpi_data_q   <= 8'b0;  // IDLE
 
                    ulpi_stp_q    <= 1'b1;
 
                    auto_wr_q     <= 1'b0;
 
                    reg_wr_q      <= 1'b0;
 
                end
                // Data
                // Data
                else if (state_q == STATE_DATA && ulpi_nxt_i)
                else if (state_q == STATE_DATA && ulpi_nxt_i)
                begin
                begin
                    // End of packet
                    // End of packet
                    if (!utmi_tx_ready_w || cmd_wr_q)
                    if (!utmi_tx_ready_w)
                    begin
                    begin
                        state_q       <= STATE_IDLE;
                        state_q       <= STATE_IDLE;
                        ulpi_data_q   <= 8'b0;  // IDLE
                        ulpi_data_q   <= 8'b0;  // IDLE
                        ulpi_stp_q    <= 1'b1;
                        ulpi_stp_q    <= 1'b1;
                        cmd_wr_q      <= 1'b0;
 
                    end
                    end
                    else
                    else
                    begin
                    begin
                        state_q        <= STATE_DATA;
                        state_q        <= STATE_DATA;
                        ulpi_data_q    <= utmi_tx_data_w;
                        ulpi_data_q    <= utmi_tx_data_w;
Line 357... Line 471...
        end
        end
    end
    end
end
end
 
 
// Accept from buffer
// Accept from buffer
assign utmi_tx_accept_w = ((state_q == STATE_IDLE) && !(mode_update_q || otg_update_q || turnaround_w) && !ulpi_dir_i) ||
assign utmi_tx_accept_w = ((state_q == STATE_IDLE) && !(mode_update_q || otg_update_q || turnaround_w || reg_wr_pending_q || reg_rd_pending_q) && !ulpi_dir_i) ||
                          (state_q == STATE_DATA && ulpi_nxt_i && !ulpi_dir_i && !cmd_wr_q);
                          (state_q == STATE_DATA && ulpi_nxt_i && !ulpi_dir_i);
 
 
//-----------------------------------------------------------------
//-----------------------------------------------------------------
// Assignments
// Assignments
//-----------------------------------------------------------------
//-----------------------------------------------------------------
// ULPI Interface
// ULPI Interface

powered by: WebSVN 2.1.0

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