URL
https://opencores.org/ocsvn/usb1_funct/usb1_funct/trunk
Subversion Repositories usb1_funct
[/] [usb1_funct/] [trunk/] [rtl/] [verilog/] [usb1_idma.v] - Rev 2
Go to most recent revision | Compare with Previous | Blame | View Log
///////////////////////////////////////////////////////////////////// //// //// //// Internal DMA Engine //// //// //// //// //// //// Author: Rudolf Usselmann //// //// rudi@asics.ws //// //// //// //// //// //// Downloaded from: http://www.opencores.org/cores/usb1_funct///// //// //// ///////////////////////////////////////////////////////////////////// //// //// //// 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: usb1_idma.v,v 1.1.1.1 2002-09-19 12:07:38 rudi Exp $ // // $Date: 2002-09-19 12:07:38 $ // $Revision: 1.1.1.1 $ // $Author: rudi $ // $Locker: $ // $State: Exp $ // // Change History: // $Log: not supported by cvs2svn $ // // // // // `include "usb1_defines.v" module usb1_idma( clk, rst, // Packet Disassembler/Assembler interface rx_data_valid, rx_data_done, send_data, rd_next, tx_valid, tx_data_st_i, tx_data_st_o, // Protocol Engine tx_dma_en, rx_dma_en, idma_done, ep_sel, // Register File Manager Interface size, rx_cnt, rx_done, dropped_frame, misaligned_frame, // Memory Arb interface mwe, mre, ep_empty, ep_empty_latched, ep_full ); // Packet Disassembler/Assembler interface input clk, rst; input rx_data_valid; input rx_data_done; output send_data; input rd_next; input tx_valid; input [7:0] tx_data_st_i; output [7:0] tx_data_st_o; // Protocol Engine input tx_dma_en; input rx_dma_en; output idma_done; // DMA is done input [3:0] ep_sel; // Register File Manager Interface input [8:0] size; // MAX PL Size in bytes output [7:0] rx_cnt; output rx_done; output dropped_frame; output misaligned_frame; // Memory Arb interface output mwe; output mre; input ep_empty; output ep_empty_latched; input ep_full; /////////////////////////////////////////////////////////////////// // // Local Wires and Registers // reg tx_dma_en_r; reg [8:0] sizd_c; // Internal size counter wire adr_incw; wire adr_incb; wire siz_dec; wire mwe; // Memory Write enable wire mre; // Memory Read enable reg mwe_r; reg sizd_is_zero; // Indicates when all bytes have been // transferred wire sizd_is_zero_d; reg idma_done; // DMA transfer is done wire send_data; // Enable UTMI Transmitter reg rx_data_done_r; reg rx_data_valid_r; wire ff_re, ff_full, ff_empty; reg ff_we, ff_we1; reg tx_dma_en_r1; reg tx_dma_en_r2; reg tx_dma_en_r3; reg send_data_r; wire ff_clr; reg [7:0] rx_cnt; reg [7:0] rx_cnt_r; reg ep_empty_r; reg ep_empty_latched; wire sp_ep_sel; wire ep_empty_int; reg [5:0] ec; wire ec_clr; reg dropped_frame; reg [5:0] rc_cnt; wire sp_ep2_sel; wire rc_clr; reg ep_full_latched; wire ep_full_int; reg misaligned_frame; /////////////////////////////////////////////////////////////////// // // For ISO interface transmit frames in 32 byte quantities // assign sp_ep_sel = (ep_sel==4'h1); // Special endpoint `ifdef USB1_ISO_CHUNKS assign ep_empty_int = sp_ep_sel ? ep_empty_latched : ep_empty; `else assign ep_empty_int = ep_empty; `endif always @(posedge clk) if(!rst) ec <= #1 6'h0; else if(!sp_ep_sel | ec_clr) ec <= #1 6'h0; else if(mre) ec <= #1 ec + 6'h1; assign ec_clr = (ec == 6'd032) | tx_dma_en; always @(posedge clk) if(!rst) ep_empty_latched <= #1 1'b0; else if(ec_clr) ep_empty_latched <= #1 ep_empty; /////////////////////////////////////////////////////////////////// // // For ISO interface OUT always store in 32 byte chunks // if fifo can't accept 32 bytes junk the entire 32 byte frame // assign sp_ep2_sel = (ep_sel==4'h2); // Special endpoint always @(posedge clk) if(!rst) rc_cnt <= #1 6'h0; else if(!sp_ep2_sel | rc_clr) rc_cnt <= #1 6'h0; else if(mwe_r) rc_cnt <= #1 rc_cnt + 6'h1; assign rc_clr = ((rc_cnt == 6'd031) & mwe_r) | rx_dma_en; always @(posedge clk) if(!rst) ep_full_latched <= #1 1'b0; else if(rc_clr) ep_full_latched <= #1 ep_full; `ifdef USB1_ISO_CHUNKS assign ep_full_int = sp_ep2_sel ? ep_full_latched : ep_full; `else assign ep_full_int = ep_full; `endif always @(posedge clk) dropped_frame <= #1 rc_clr & ep_full & sp_ep2_sel; always @(posedge clk) misaligned_frame <= #1 rx_data_done_r & sp_ep2_sel & (rc_cnt!=6'd00); // synopsys translate_off `ifdef USBF_VERBOSE_DEBUG always @(posedge dropped_frame) $display("WARNING: Droped one OUT frame (no space in FIFO) (%t)",$time); always @(posedge misaligned_frame) $display("WARNING: Received misaligned frame (%t)",$time); `endif // synopsys translate_on /////////////////////////////////////////////////////////////////// // // FIFO interface // always @(posedge clk) mwe_r <= #1 rx_data_valid; assign mwe = mwe_r & !ep_full_int; /////////////////////////////////////////////////////////////////// // // Misc Logic // always @(posedge clk) rx_data_valid_r <= #1 rx_data_valid; always @(posedge clk) rx_data_done_r <= #1 rx_data_done; // Generate one cycle pulses for tx and rx dma enable always @(posedge clk) tx_dma_en_r <= #1 tx_dma_en; always @(posedge clk) tx_dma_en_r1 <= tx_dma_en_r; always @(posedge clk) tx_dma_en_r2 <= tx_dma_en_r1; always @(posedge clk) tx_dma_en_r3 <= tx_dma_en_r2; // DMA Done Indicator always @(posedge clk) idma_done <= #1 (rx_data_done_r | sizd_is_zero_d | ep_empty_int); /////////////////////////////////////////////////////////////////// // // RX Size Counter // always @(posedge clk or negedge rst) if(!rst) rx_cnt_r <= #1 8'h00; else if(rx_data_done_r) rx_cnt_r <= #1 8'h00; else if(rx_data_valid) rx_cnt_r <= #1 rx_cnt_r + 8'h01; always @(posedge clk or negedge rst) if(!rst) rx_cnt <= #1 8'h00; else if(rx_data_done_r) rx_cnt <= #1 rx_cnt_r; assign rx_done = rx_data_done_r; /////////////////////////////////////////////////////////////////// // // Transmit Size Counter (counting backward from input size) // For MAX packet size // always @(posedge clk or negedge rst) if(!rst) sizd_c <= #1 9'h1ff; else if(tx_dma_en) sizd_c <= #1 size; else if(siz_dec) sizd_c <= #1 sizd_c - 9'h1; assign siz_dec = (tx_dma_en_r | tx_dma_en_r1 | rd_next) & !sizd_is_zero_d; assign sizd_is_zero_d = sizd_c == 9'h0; always @(posedge clk) sizd_is_zero <= #1 sizd_is_zero_d; /////////////////////////////////////////////////////////////////// // // TX Logic // reg tx_valid_r; wire tx_valid_e; always @(posedge clk) tx_valid_r <= #1 tx_valid; assign tx_valid_e = tx_valid_r & !tx_valid; // Since we are prefetching two entries in to our fast fifo, we // need to know when exactly ep_empty was asserted, as we might // only need 1 or 2 bytes. This is for ep_empty_r always @(posedge clk or negedge rst) if(!rst) ep_empty_r <= #1 1'b0; else if(!tx_valid) ep_empty_r <= #1 1'b0; else if(tx_dma_en_r2) ep_empty_r <= #1 ep_empty_int; always @(posedge clk or negedge rst) if(!rst) send_data_r <= #1 1'b0; else if((tx_dma_en_r & !ep_empty_int)) send_data_r <= #1 1'b1; else if(rd_next & (sizd_is_zero_d | (ep_empty_int & !sizd_is_zero_d)) ) send_data_r <= #1 1'b0; assign send_data = (send_data_r & !ep_empty_r & !(sizd_is_zero & size==9'h01)) | tx_dma_en_r1; assign mre = (tx_dma_en_r1 | tx_dma_en_r | rd_next) & !sizd_is_zero_d & !ep_empty_int & (send_data | tx_dma_en_r1 | tx_dma_en_r); always @(posedge clk) ff_we1 <= mre; always @(posedge clk) ff_we <= ff_we1; assign ff_re = rd_next; assign ff_clr = !tx_valid; /////////////////////////////////////////////////////////////////// // // IDMA fast prefetch fifo // // tx fifo usb1_fifo2 ff( .clk( clk ), .rst( rst ), .clr( ff_clr ), .din( tx_data_st_i ), .we( ff_we ), .dout( tx_data_st_o ), .re( ff_re ) ); endmodule
Go to most recent revision | Compare with Previous | Blame | View Log