📄 usbf_pe.v
字号:
///////////////////////////////////////////////////////////////////////// //////// Protocol Engine //////// Performs automatic protocol functions //////// //////// Author: Rudolf Usselmann //////// rudi@asics.ws //////// //////// //////// Downloaded from: http://www.opencores.org/cores/usb/ //////// ///////////////////////////////////////////////////////////////////////////// //////// Copyright (C) 2000 Rudolf Usselmann //////// 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: usbf_pe.v,v 1.2 2001/08/10 08:48:33 rudi Exp $//// $Date: 2001/08/10 08:48:33 $// $Revision: 1.2 $// $Author: rudi $// $Locker: $// $State: Exp $//// Change History:// $Log: usbf_pe.v,v $// Revision 1.2 2001/08/10 08:48:33 rudi//// - Changed IO names to be more clear.// - Uniquifyed define names to be core specific.//// Revision 1.1 2001/08/03 05:30:09 rudi////// 1) Reorganized directory structure//// Revision 1.2 2001/03/31 13:00:51 rudi//// - Added Core configuration// - Added handling of OUT packets less than MAX_PL_SZ in DMA mode// - Modified WISHBONE interface and sync logic// - Moved SSRAM outside the core (added interface)// - Many small bug fixes ...//// Revision 1.0 2001/03/07 09:17:12 rudi////// Changed all revisions to revision 1.0. This is because OpenCores CVS// interface could not handle the original '0.1' revision ....//// Revision 0.2 2001/03/07 09:08:13 rudi//// Added USB control signaling (Line Status) block. Fixed some minor// typos, added resume bit and signal.//// Revision 0.1.0.1 2001/02/28 08:11:07 rudi// Initial Release////`include "usbf_defines.v"module usbf_pe( clk, rst, // UTMI Interfaces tx_valid, rx_active, // PID Information pid_OUT, pid_IN, pid_SOF, pid_SETUP, pid_DATA0, pid_DATA1, pid_DATA2, pid_MDATA, pid_ACK, pid_NACK, pid_STALL, pid_NYET, pid_PRE, pid_ERR, pid_SPLIT, pid_PING, // Speed Mode mode_hs, // Token Information token_valid, crc5_err, // Receive Data Output rx_data_valid, rx_data_done, crc16_err, // Packet Assembler Interface send_token, token_pid_sel, data_pid_sel, // IDMA Interface rx_dma_en, tx_dma_en, abort, idma_done, adr, size, buf_size, sizu_c, dma_en, // Register File Interface fsel, idin, dma_in_buf_sz1, dma_out_buf_avail, ep_sel, match, nse_err, buf0_rl, buf0_set, buf1_set, uc_bsel_set, uc_dpd_set, int_buf1_set, int_buf0_set, int_upid_set, int_crc16_set, int_to_set, int_seqerr_set, out_to_small, csr, buf0, buf1 );parameter SSRAM_HADR = 14;input clk, rst;input tx_valid, rx_active;// Packet Disassembler Interface // Decoded PIDs (used when token_valid is asserted)input pid_OUT, pid_IN, pid_SOF, pid_SETUP;input pid_DATA0, pid_DATA1, pid_DATA2, pid_MDATA;input pid_ACK, pid_NACK, pid_STALL, pid_NYET;input pid_PRE, pid_ERR, pid_SPLIT, pid_PING;input mode_hs;input token_valid; // Token is validinput crc5_err; // Token crc5 errorinput rx_data_valid; // Data on rx_data_st is validinput rx_data_done; // Indicates end of a transferinput crc16_err; // Data packet CRC 16 error// Packet Assembler Interfaceoutput send_token;output [1:0] token_pid_sel;output [1:0] data_pid_sel;// IDMA Interfaceoutput rx_dma_en; // Allows the data to be storedoutput tx_dma_en; // Allows for data to be retrievedoutput abort; // Abort Transfer (time_out, crc_err or rx_error)input idma_done; // DMA is done indicatoroutput [SSRAM_HADR + 2:0] adr; // Byte Addressoutput [13:0] size; // Size in bytesoutput [13:0] buf_size; // Actual buffer sizeinput [10:0] sizu_c; // Up and Down counting size registers, used to updateoutput dma_en; // USB external DMA mode enabled// Register File interfaceinput fsel; // This function is selectedoutput [31:0] idin; // Data Outputinput [3:0] ep_sel; // Endpoint Number Inputinput match; // Endpoint Matchedoutput nse_err; // no such endpoint errorinput dma_in_buf_sz1, dma_out_buf_avail;output buf0_rl; // Reload Buf 0 with original valuesoutput buf0_set; // Write to buf 0output buf1_set; // Write to buf 1output uc_bsel_set; // Write to the uc_bsel fieldoutput uc_dpd_set; // Write to the uc_dpd fieldoutput int_buf1_set; // Set buf1 full/empty interruptoutput int_buf0_set; // Set buf0 full/empty interruptoutput int_upid_set; // Set unsupported PID interruptoutput int_crc16_set; // Set CRC16 error interruptoutput int_to_set; // Set time out interruptoutput int_seqerr_set; // Set PID sequence error interruptoutput out_to_small; // OUT packet was to small for DMA operationinput [31:0] csr; // Internal CSR Outputinput [31:0] buf0; // Internal Buf 0 Outputinput [31:0] buf1; // Internal Buf 1 Output/////////////////////////////////////////////////////////////////////// Local Wires and Registers//// tx token decodingparameter ACK = 0, NACK = 1, STALL = 2, NYET = 3;// State decodingparameter [9:0] // synopsys enum state IDLE = 10'b000000_0001, TOKEN = 10'b000000_0010, IN = 10'b000000_0100, IN2 = 10'b000000_1000, OUT = 10'b000001_0000, OUT2A = 10'b000010_0000, OUT2B = 10'b000100_0000, UPDATEW = 10'b001000_0000, UPDATE = 10'b010000_0000, UPDATE2 = 10'b100000_0000;reg [1:0] token_pid_sel;reg [1:0] token_pid_sel_d;reg send_token;reg send_token_d;reg rx_dma_en, tx_dma_en;reg int_seqerr_set_d;reg int_seqerr_set;reg int_upid_set;reg match_r;// Endpoint Decodingwire IN_ep, OUT_ep, CTRL_ep; // Endpoint Typeswire txfr_iso, txfr_int, txfr_bulk; // Transfer Typeswire ep_disabled, ep_stall; // Endpoint forced conditionswire lrg_ok, sml_ok; // Packet size acceptancewire [1:0] tr_fr; // Number of transfers per micro-framewire [10:0] max_pl_sz; // Max payload sizewire [1:0] uc_dpd, uc_bsel;// Buffer checkswire buf_sel;reg buf0_na, buf1_na;wire [SSRAM_HADR + 2:0] buf0_adr, buf1_adr;wire [13:0] buf0_sz, buf1_sz;reg [9:0] /* synopsys enum state */ state, next_state;// synopsys state_vector state// PID next and current decodersreg [1:0] next_dpid;reg [1:0] this_dpid;reg pid_seq_err;wire [1:0] tr_fr_d;wire [13:0] size_next;wire buf_smaller;reg [SSRAM_HADR + 2:0] adr;reg [13:0] new_size;reg [13:0] new_sizeb;reg buffer_full;reg buffer_empty;wire [SSRAM_HADR + 2:0] new_adr;reg buffer_done;reg no_bufs0, no_bufs1;wire no_bufs;// After sending Data in response to an IN token from host, the// host must reply with an ack. The host has XXXnS to reply.// "rx_ack_to" indicates when this time has expired.// rx_ack_to_clr, clears the timerreg rx_ack_to_clr;reg rx_ack_to_clr_d;reg rx_ack_to;reg [5:0] rx_ack_to_cnt;// After sending a OUT token the host must send a data packet.// The host has XX nS to send the packet. "tx_data_to" indicates// when this time has expired.// tx_data_to_clr, clears the timerwire tx_data_to_clr;reg tx_data_to;reg [15:0] tx_data_to_cnt;wire [5:0] rx_ack_to_val, tx_data_to_val;reg int_set_en;wire [1:0] next_bsel;reg buf_set_d;reg uc_stat_set_d;reg [31:0] idin;reg buf0_set, buf1_set;reg uc_bsel_set;reg uc_dpd_set;reg buf0_rl_d;reg buf0_rl;wire no_buf0_dma;reg buf0_st_max;reg buf1_st_max;reg [SSRAM_HADR + 2:0] adr_r;reg [13:0] size_next_r;reg in_token;reg out_token;reg setup_token;wire in_op, out_op; // Indicate a IN or OUT operationreg to_small; // Indicates a "to small packer" errorreg to_large; // Indicates a "to large packer" errorreg buffer_overflow;reg [1:0] allow_pid;reg nse_err;reg out_to_small, out_to_small_r;reg abort;/////////////////////////////////////////////////////////////////////// Misc Logic//// Endpoint/CSR Decodingassign IN_ep = csr[27:26]==2'b01;assign OUT_ep = csr[27:26]==2'b10;assign CTRL_ep = csr[27:26]==2'b00;assign txfr_int = csr[25:24]==2'b00;assign txfr_iso = csr[25:24]==2'b01;assign txfr_bulk = csr[25:24]==2'b10;assign ep_disabled = csr[23:22]==2'b01;assign ep_stall = csr[23:22]==2'b10;assign lrg_ok = csr[17];assign sml_ok = csr[16];assign dma_en = csr[15] & !CTRL_ep;assign tr_fr = csr[12:11];assign max_pl_sz = csr[10:0];assign uc_dpd = csr[29:28];assign uc_bsel = csr[31:30];// Buffer decoding and allocation checksassign buf0_adr = buf0[SSRAM_HADR + 2:0];assign buf1_adr = buf1[SSRAM_HADR + 2:0];assign buf0_sz = buf0[30:17];assign buf1_sz = buf1[30:17];always @(posedge clk) buf0_na <= #1 buf0[31] | ( &buf0_adr );always @(posedge clk) buf1_na <= #1 buf1[31] | ( &buf1_adr );//assign buf0_na = buf0[31] | ( &buf0_adr );//assign buf1_na = buf1[31] | ( &buf1_adr );always @(posedge clk) match_r <= #1 match;// No Such Endpoint Indicatoralways @(posedge clk) nse_err <= #1 token_valid & (pid_OUT | pid_IN | pid_SETUP) & !match;always @(posedge clk) send_token <= #1 send_token_d;always @(posedge clk) token_pid_sel <= #1 token_pid_sel_d;/////////////////////////////////////////////////////////////////////// Data Pid Sequencer//assign tr_fr_d = mode_hs ? tr_fr : 0;always @(posedge clk) // tr/mf:ep/type:tr/type:last dpd casex({tr_fr_d,csr[27:26],csr[25:24],uc_dpd}) // synopsys full_case parallel_case 8'b0?_01_01_??: next_dpid <= #1 2'b00; // ISO txfr. IN, 1 tr/mf 8'b10_01_01_?0: next_dpid <= #1 2'b01; // ISO txfr. IN, 2 tr/mf 8'b10_01_01_?1: next_dpid <= #1 2'b00; // ISO txfr. IN, 2 tr/mf 8'b11_01_01_00: next_dpid <= #1 2'b01; // ISO txfr. IN, 3 tr/mf 8'b11_01_01_01: next_dpid <= #1 2'b10; // ISO txfr. IN, 3 tr/mf 8'b11_01_01_10: next_dpid <= #1 2'b00; // ISO txfr. IN, 3 tr/mf 8'b0?_10_01_??: next_dpid <= #1 2'b00; // ISO txfr. OUT, 1 tr/mf 8'b10_10_01_??: // ISO txfr. OUT, 2 tr/mf begin // Resynchronize in case of PID error case({pid_MDATA, pid_DATA1}) 2'b10: next_dpid <= #1 2'b01; 2'b01: next_dpid <= #1 2'b00; endcase end 8'b11_10_01_00: // ISO txfr. OUT, 3 tr/mf begin // Resynchronize in case of PID error case({pid_MDATA, pid_DATA2}) 2'b10: next_dpid <= #1 2'b01; 2'b01: next_dpid <= #1 2'b00; endcase end 8'b11_10_01_01: // ISO txfr. OUT, 3 tr/mf begin // Resynchronize in case of PID error case({pid_MDATA, pid_DATA2}) 2'b10: next_dpid <= #1 2'b10; 2'b01: next_dpid <= #1 2'b00; endcase end 8'b11_10_01_10: // ISO txfr. OUT, 3 tr/mf begin // Resynchronize in case of PID error case({pid_MDATA, pid_DATA2}) 2'b10: next_dpid <= #1 2'b01; 2'b01: next_dpid <= #1 2'b00; endcase end 8'b??_01_00_?0, // IN/OUT endpoint only 8'b??_10_00_?0: next_dpid <= #1 2'b01; // INT transfers 8'b??_01_00_?1, // IN/OUT endpoint only 8'b??_10_00_?1: next_dpid <= #1 2'b00; // INT transfers 8'b??_01_10_?0, // IN/OUT endpoint only 8'b??_10_10_?0: next_dpid <= #1 2'b01; // BULK transfers 8'b??_01_10_?1, // IN/OUT endpoint only 8'b??_10_10_?1: next_dpid <= #1 2'b00; // BULK transfers 8'b??_00_??_??: // CTRL Endpoint casex({setup_token, in_op, out_op, uc_dpd}) // synopsys full_case parallel_case 5'b1_??_??: next_dpid <= #1 2'b11; // SETUP operation 5'b0_10_0?: next_dpid <= #1 2'b11; // IN operation 5'b0_10_1?: next_dpid <= #1 2'b01; // IN operation 5'b0_01_?0: next_dpid <= #1 2'b11; // OUT operation 5'b0_01_?1: next_dpid <= #1 2'b10; // OUT operation endcase endcase// Current PID decoder// Allow any PID for ISO. transfers when mode full speed or tr_fr is zeroalways @(pid_DATA0 or pid_DATA1 or pid_DATA2 or pid_MDATA) case({pid_DATA0, pid_DATA1, pid_DATA2, pid_MDATA} ) // synopsys full_case parallel_case 4'b1000: allow_pid = 2'b00; 4'b0100: allow_pid = 2'b01; 4'b0010: allow_pid = 2'b10; 4'b0001: allow_pid = 2'b11; endcasealways @(posedge clk) // tf/mf:ep/type:tr/type:last dpd casex({tr_fr_d,csr[27:26],csr[25:24],uc_dpd}) // synopsys full_case parallel_case 8'b0?_01_01_??: this_dpid <= #1 2'b00; // ISO txfr. IN, 1 tr/mf 8'b10_01_01_?0: this_dpid <= #1 2'b01; // ISO txfr. IN, 2 tr/mf 8'b10_01_01_?1: this_dpid <= #1 2'b00; // ISO txfr. IN, 2 tr/mf 8'b11_01_01_00: this_dpid <= #1 2'b10; // ISO txfr. IN, 3 tr/mf 8'b11_01_01_01: this_dpid <= #1 2'b01; // ISO txfr. IN, 3 tr/mf
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -