⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usb1_idma.v

📁 usb1.1 ip核
💻 V
字号:
/////////////////////////////////////////////////////////////////////////                                                             ////////  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.2 2002/09/25 06:06:49 rudi Exp $////  $Date: 2002/09/25 06:06:49 $//  $Revision: 1.2 $//  $Author: rudi $//  $Locker:  $//  $State: Exp $//// Change History://               $Log: usb1_idma.v,v $//               Revision 1.2  2002/09/25 06:06:49  rudi//               - Added New Top Level//               - Remove old top level and associated files//               - Moved FIFOs to "Generic FIFOs" project////               Revision 1.1.1.1  2002/09/19 12:07:38  rudi//               Initial Checkin////////////`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,//留心这个来自于pa的信号在这里发挥的作用		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,		tx_busy,		// Block Frames至今仍然没有搞清这个地方是什么		ep_bf_en, ep_bf_size,		dropped_frame, misaligned_frame,		// Memory Arb interface		mwe, mre, ep_empty, ep_empty_int, ep_full		);// Packet Disassembler/Assembler interfaceinput		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 Engineinput		tx_dma_en;input		rx_dma_en;output		idma_done;	// DMA is doneinput	[3:0]	ep_sel;//要这个做甚?// Register File Manager Interfaceinput	[8:0]	size;		// MAX PL Size in bytes,拿的是csr的低九位output	[7:0]	rx_cnt;output		rx_done;output		tx_busy;input		ep_bf_en;input	[6:0]	ep_bf_size;output		dropped_frame;output		misaligned_frame;// Memory Arb interfaceoutput		mwe;output		mre;input		ep_empty;output		ep_empty_int;input		ep_full;/////////////////////////////////////////////////////////////////////// Local Wires and Registers//reg		tx_dma_en_r;reg	[8:0]	sizd_c;			// Internal size counterwire		adr_incw;       //这是什么地址?wire		adr_incb;       //什么地址?wire		siz_dec;wire		mwe;			// Memory Write enablewire		mre;			// Memory Read enablereg		mwe_r;//注意这个reg		sizd_is_zero;		// Indicates when all bytes have been					// transferredwire		sizd_is_zero_d;//这根电线干什么?reg		idma_done;		// DMA transfer is donewire		send_data;		// Enable UTMI Transmitter,胡说,明明是给pa的reg		rx_data_done_r;reg		rx_data_valid_r;wire		ff_re, ff_full, ff_empty;//ff是什么?fiforeg		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		ep_empty_int;reg	[6:0]	ec;//这是什么?wire		ec_clr;reg		dropped_frame;reg	[6:0]	rc_cnt;//什么计数器wire		rc_clr;reg		ep_full_latched;//跟上面对称了wire		ep_full_int;//跟上面对称了reg		misaligned_frame;reg		tx_valid_r;wire		tx_valid_e;//???/////////////////////////////////////////////////////////////////////// For IN Block Frames transmit frames in [ep_bf_size] byte quantities//是设备向主机输入吧`ifdef USB1_BF_ENABLE  //这个地方的功能是什么?它想实现什么?always @(posedge clk)	if(!rst)		ec <= #1 7'h0;	else	if(!ep_bf_en | ec_clr)	ec <= #1 7'h0;//如果ep_bf_en为低或ec_clr为高,则	else	if(mre)			ec <= #1 ec + 7'h1;//如果在从存储器读取,就加一计数,要知道这里的mre是读什么,读到哪里的标志                                       //mre输出到idma_re引脚,可初步肯定是读端点fifo用的assign ec_clr = (ec == ep_bf_size) | tx_dma_en;//如果计数满,或是在??ep_bf_size是端点fifo给的大小信息always @(posedge clk)//ep_empty_latched是用来干什么的??	if(!rst)	ep_empty_latched <= #1 1'b0;	else	if(ec_clr)	ep_empty_latched <= #1 ep_empty;//ep_empty_r要了做甚?assign ep_empty_int = ep_bf_en ? ep_empty_latched : ep_empty;//从端点fifo读东西,当然要看看它是否为空了`elseassign ep_empty_int = ep_empty;//看清楚这里的格式,else`endif/////////////////////////////////////////////////////////////////////// For OUT Block Frames always store in [ep_bf_size] byte chunks// if fifo can't accept [ep_bf_size] bytes junk the entire [ep_bf_size]// byte frame//这里是主机向设备输出数据`ifdef USB1_BF_ENABLEalways @(posedge clk)	if(!rst)		rc_cnt <= #1 7'h0;//rc是什么缩写?,rc与接收有关	else	if(!ep_bf_en | rc_clr)	rc_cnt <= #1 7'h0;	else	if(mwe_r)		rc_cnt <= #1 rc_cnt + 7'h1;//如果在从主机接收数据,就加一计数assign rc_clr = ((rc_cnt == ep_bf_size) & mwe_r) | rx_dma_en; //如果计数满,也就是ep的bf满,或是??,就清零always @(posedge clk)	if(!rst)	ep_full_latched <= #1 1'b0;	else	if(rc_clr)	ep_full_latched <= #1 ep_full;assign ep_full_int = ep_bf_en ? ep_full_latched : ep_full;//ep_full_int没有引到外部,去了解它被怎么用了always @(posedge clk)	dropped_frame <= #1 rc_clr & ep_full & ep_bf_en;//不明白,要加深认识才能明白                                                    //收完来自主机的数据后rc_clr,同时fifo肯定full了,那这个dropped_fame是什么含义啊?always @(posedge clk)	misaligned_frame <= #1 rx_data_done_r & ep_bf_en & (rc_cnt!=7'd00);//不太明白,接收到的数据不能正好装满bf??`else                                                                  //数据接收完了,却没有rc_clr信号,导致rc_cnt未清零assign ep_full_int = ep_full;//注意前面的elsealways @(posedge clk)	dropped_frame <= #1 1'b0;always @(posedge clk)	misaligned_frame <= #1 1'b0;`endif// synopsys translate_off`ifdef USBF_VERBOSE_DEBUGalways @(posedge dropped_frame)	$display("WARNING: BF: Droped one OUT frame (no space in FIFO) (%t)",$time);always @(posedge misaligned_frame)	$display("WARNING: BF: 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;//对外的输出,除了mwe_r,还要求端点寄存器有空间存储来自主机的数据/////////////////////////////////////////////////////////////////////// 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 enablealways @(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 Indicatoralways @(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)//对rx_cnt_r赋值	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)//对rx_cnt赋值	if(!rst)		rx_cnt <= #1 8'h00;//复位清零	else	if(rx_data_done_r)	rx_cnt <= #1 rx_cnt_r;//数据传完时把计数结果给rx_cntassign rx_done = rx_data_done_r;//rx_done可是要输出的,表明接收完毕/////////////////////////////////////////////////////////////////////// Transmit Size Counter (counting backward from input size)// For MAX packet size  发送数据的计数//always @(posedge clk or negedge rst)//对sizd_c赋值	if(!rst)			sizd_c <= #1 9'h1ff;	else	if(tx_dma_en)			sizd_c <= #1 size;//如果允许向主机传输数据,则加载sizd_c,size是max packet 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,本地发送数据到主机//assign tx_busy = send_data | tx_dma_en_r | tx_dma_en;//注意或的关系always @(posedge clk)	tx_valid_r <= #1 tx_valid;assign tx_valid_e = tx_valid_r & !tx_valid;//tx_valid_e是不是tx_valid_end的意思?极有可能// 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_ralways @(posedge clk or negedge rst)//对ep_empty_r赋值	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;//ep_empty_r有什么用?always @(posedge clk or negedge rst)//对send_data_r赋值	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;                     //但是fifo中已经没有货了。前提都是rd_next为高!                                                                    //但是rd_next究竟是什么呢????assign send_data = (send_data_r & !ep_empty_r & 		!(sizd_is_zero & size==9'h01)) | tx_dma_en_r1;//已达到最大包限制,且最大包就是1,不能是这种情况,而且                                                     //send_data_r为高,fifo不空,或...,这些条件有必要搞清吗?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;//允许读端点的fifo,同时就开启了idma内部fifo的大门,把读得的数据往里面写always @(posedge clk)	ff_we <= ff_we1;//一级缓冲assign ff_re = rd_next;//如果pa模块要求读取数据,则读取idma内部的fifoassign ff_clr = !tx_valid;//ff_clr的作用,tx_valid为低后,立刻清零idma内部的fifo,去看看tx_valid的产生原理/////////////////////////////////////////////////////////////////////// IDMA fast prefetch fifo//// tx fifo 先入先出模块,大小仅为2个字节!!usb1_fifo2 ff(	.clk(		clk		),	.rst(		rst		),	.clr(		ff_clr		),	.din(		tx_data_st_i	),//注意这里的tx_data_st_i仅说明为input而已	.we(		ff_we		),	.dout(		tx_data_st_o	),//注意这里的tx_data_st_o没有定义为reg型,尽管它是output	.re(		ff_re		)	);endmodule

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -