📄 usb1_idma.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 + -