| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345 | //-----------------------------------------------------------------//                       USB Serial Port//                            V0.1//                     Ultra-Embedded.com//                       Copyright 2020////                 Email: admin@ultra-embedded.com////                         License: LGPL//-----------------------------------------------------------------//// 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 source file is free software; you can redistribute it   // and/or modify it under the terms of the GNU Lesser General   // Public License as published by the Free Software Foundation; // either version 2.1 of the License, or (at your option) any   // later version.//// This source is distributed in the hope that it will be       // useful, but WITHOUT ANY WARRANTY; without even the implied   // warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      // PURPOSE.  See the GNU Lesser General Public License for more // details.//// You should have received a copy of the GNU Lesser General    // Public License along with this source; if not, write to the // Free Software Foundation, Inc., 59 Temple Place, Suite 330, // Boston, MA  02111-1307  USA//-----------------------------------------------------------------//-----------------------------------------------------------------//                          Generated File//-----------------------------------------------------------------module usbf_sie_tx(    // Inputs     input           clk_i    ,input           rst_i    ,input           enable_i    ,input           chirp_i    ,input           utmi_txready_i    ,input           tx_valid_i    ,input  [  7:0]  tx_pid_i    ,input           data_valid_i    ,input           data_strb_i    ,input  [  7:0]  data_i    ,input           data_last_i    // Outputs    ,output [  7:0]  utmi_data_o    ,output          utmi_txvalid_o    ,output          tx_accept_o    ,output          data_accept_o);//-----------------------------------------------------------------// Defines://-----------------------------------------------------------------`include "usbf_defs.v"localparam STATE_W                       = 3;localparam STATE_TX_IDLE                 = 3'd0;localparam STATE_TX_PID                  = 3'd1;localparam STATE_TX_DATA                 = 3'd2;localparam STATE_TX_CRC1                 = 3'd3;localparam STATE_TX_CRC2                 = 3'd4;localparam STATE_TX_DONE                 = 3'd5;localparam STATE_TX_CHIRP                = 3'd6;reg [STATE_W-1:0] state_q;reg [STATE_W-1:0] next_state_r;//-----------------------------------------------------------------// Request Type//-----------------------------------------------------------------reg data_pid_q;reg data_zlp_q;always @ (posedge clk_i or posedge rst_i)if (rst_i)begin    data_pid_q <= 1'b0;    data_zlp_q <= 1'b0;endelse if (!enable_i)begin    data_pid_q <= 1'b0;    data_zlp_q <= 1'b0;endelse if (tx_valid_i && tx_accept_o)begin    case (tx_pid_i)    `PID_MDATA, `PID_DATA2, `PID_DATA0, `PID_DATA1:    begin        data_pid_q <= 1'b1;        data_zlp_q <= data_valid_i && (data_strb_i == 1'b0) && data_last_i;    end    default :    begin        data_pid_q <= 1'b0;        data_zlp_q <= 1'b0;    end    endcaseendelse if (next_state_r == STATE_TX_CRC1)begin    data_pid_q <= 1'b0;    data_zlp_q <= 1'b0;endassign tx_accept_o = (state_q == STATE_TX_IDLE);//-----------------------------------------------------------------// Next state//-----------------------------------------------------------------always @ *begin    next_state_r = state_q;    //-----------------------------------------    // State Machine    //-----------------------------------------    case (state_q)    //-----------------------------------------    // IDLE    //-----------------------------------------    STATE_TX_IDLE :    begin        if (chirp_i)            next_state_r  = STATE_TX_CHIRP;        else if (tx_valid_i)            next_state_r  = STATE_TX_PID;    end    //-----------------------------------------    // TX_PID    //-----------------------------------------    STATE_TX_PID :    begin        // Data accepted        if (utmi_txready_i)        begin            if (data_zlp_q)                next_state_r = STATE_TX_CRC1;            else if (data_pid_q)                next_state_r = STATE_TX_DATA;            else                next_state_r = STATE_TX_DONE;        end    end    //-----------------------------------------    // TX_DATA    //-----------------------------------------    STATE_TX_DATA :    begin        // Data accepted        if (utmi_txready_i)        begin            // Generate CRC16 at end of packet            if (data_last_i)                next_state_r  = STATE_TX_CRC1;        end    end    //-----------------------------------------    // TX_CRC1 (first byte)    //-----------------------------------------    STATE_TX_CRC1 :    begin        // Data sent?        if (utmi_txready_i)            next_state_r  = STATE_TX_CRC2;    end    //-----------------------------------------    // TX_CRC (second byte)    //-----------------------------------------    STATE_TX_CRC2 :    begin        // Data sent?        if (utmi_txready_i)            next_state_r  = STATE_TX_DONE;    end    //-----------------------------------------    // TX_DONE    //-----------------------------------------    STATE_TX_DONE :    begin        // Data sent?        if (!utmi_txvalid_o || utmi_txready_i)            next_state_r  = STATE_TX_IDLE;    end    //-----------------------------------------    // TX_CHIRP    //-----------------------------------------    STATE_TX_CHIRP :    begin        if (!chirp_i)            next_state_r  = STATE_TX_IDLE;    end    default :       ;    endcase    // USB reset but not chirping...    if (!enable_i && !chirp_i)        next_state_r  = STATE_TX_IDLE;end// Update statealways @ (posedge clk_i or posedge rst_i)if (rst_i)    state_q   <= STATE_TX_IDLE;else    state_q   <= next_state_r;//-----------------------------------------------------------------// Data Input//-----------------------------------------------------------------reg       input_valid_r;reg [7:0] input_byte_r;reg       input_last_r;always @ *begin    input_valid_r = data_strb_i & data_pid_q;    input_byte_r  = data_i;    input_last_r  = data_last_i;endreg data_accept_r;always @ *begin    if (state_q == STATE_TX_DATA)        data_accept_r = utmi_txready_i;    else if (state_q == STATE_TX_PID && data_zlp_q)        data_accept_r = utmi_txready_i;    else        data_accept_r = 1'b0;endassign data_accept_o = data_accept_r;//-----------------------------------------------------------------// CRC16: Generate CRC16 on outgoing data//-----------------------------------------------------------------reg [15:0]  crc_sum_q;wire [15:0] crc_out_w;reg         crc_err_q;usbf_crc16u_crc16(    .crc_in_i(crc_sum_q),    .din_i(utmi_data_o),    .crc_out_o(crc_out_w));always @ (posedge clk_i or posedge rst_i)if (rst_i)    crc_sum_q   <= 16'hFFFF;else if (state_q == STATE_TX_IDLE)    crc_sum_q   <= 16'hFFFF;else if (state_q == STATE_TX_DATA && utmi_txvalid_o && utmi_txready_i)    crc_sum_q   <= crc_out_w;//-----------------------------------------------------------------// Output//-----------------------------------------------------------------reg       valid_q;reg [7:0] data_q;always @ (posedge clk_i or posedge rst_i)if (rst_i)begin    valid_q <= 1'b0;    data_q  <= 8'b0;endelse if (!enable_i)begin    valid_q <= 1'b0;    data_q  <= 8'b0;endelse if (tx_valid_i && tx_accept_o)begin    valid_q <= 1'b1;    data_q  <= tx_pid_i;endelse if (utmi_txready_i)begin    valid_q <= 1'b0;    data_q  <= 8'b0;endreg       utmi_txvalid_r;reg [7:0] utmi_data_r;always @ *begin    if (state_q == STATE_TX_CHIRP)    begin        utmi_txvalid_r = 1'b1;        utmi_data_r    = 8'b0;    end    else if (state_q == STATE_TX_CRC1)    begin        utmi_txvalid_r = 1'b1;        utmi_data_r    = crc_sum_q[7:0] ^ 8'hFF;    end    else if (state_q == STATE_TX_CRC2)    begin        utmi_txvalid_r = 1'b1;        utmi_data_r    = crc_sum_q[15:8] ^ 8'hFF;    end    else if (state_q == STATE_TX_DATA)    begin        utmi_txvalid_r = data_valid_i;        utmi_data_r    = data_i;    end    else    begin        utmi_txvalid_r = valid_q;        utmi_data_r    = data_q;    endendassign utmi_txvalid_o = utmi_txvalid_r;assign utmi_data_o    = utmi_data_r;endmodule
 |