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

📄 switchasyncfifo.v

📁 ethmac10g_latest.tar.gz源代码
💻 V
字号:
//// Module SwitchAsyncFIFO//// the differences between this FIFO and the general one are listed below//    1. because there is no any write and read acknowledgements, the user should take advantage of the status flags to generate the write and read requests.//    2. after the qWFull flag has been asserted, the word can not be written into the FIFO.//    3. after the qREmpty flag has been asserted, the data can not be read out from the FIFO.//    4. 2 flip-flops are used to re-synchronize the addresses of the different clock domains.//    5. to decrease 1 clock, the negedge of the clock is utilized by the 1st flip-flop.//    6. to provide guaranteed free space information, the qRNumberLeft has been subtracted 4.//// Created://          by - Xinchun Liu//          at - 2006-09-27//// revised://          by - Xinchun Liu//          at - 2007-05-15//    1. to decrease the clock to output time, a output register has been added.//    2. 1 cycle latency has been added to the output data and empty flag.//`resetall`timescale 1ns/10psmodule SwitchAsyncFIFO(   inReset,   iWClk,   iWEn,   ivDataIn,   qWFull,   qvWCount,   iRClk,   iREn,   ovDataOut,   qREmpty,   qvRNumberLeft);// Default address and data widthparameter   pDepthWidth = 5 ;parameter   pWordWidth = 16 ;input   inReset ;input   iWClk ;input iWEn ;input [pWordWidth-1:0]   ivDataIn ;output   qWFull ;output   [pDepthWidth:0]   qvWCount ;input   iRClk ;input   iREn ;output   [pWordWidth-1:0]   ovDataOut ;output   qREmpty ;output   [pDepthWidth:0]   qvRNumberLeft ;wire   inReset ;wire   iWClk ;wire   iWEn ;wire  [pWordWidth-1:0]   ivDataIn ;wire   qWFull ;wire  [pDepthWidth:0]   qvWCount ;wire   iRClk ;wire   iREn ;wire  [pWordWidth-1:0]   ovDataOut ;wire   qREmpty ;wire  [pDepthWidth:0]   qvRNumberLeft ;wire  MemWEn;wire  [pDepthWidth-1:0] vWriteAddr ;wire  [pDepthWidth-1:0] vReadAddr ;wire   [pWordWidth-1:0] MemDataOut ;DualPortRAM_ASYN #( pDepthWidth, pWordWidth ) Fifo_Storage   (      // Generic synchronous two-port RAM interface      .WriteClock    ( iWClk ),      .MemWEn        ( MemWEn ),      .MemWAddr      ( vWriteAddr ),      .MemDataIn     ( ivDataIn ),      .ReadClock     ( iRClk ),      .MemRAddr      ( vReadAddr ),      .MemDataOut    ( MemDataOut )    );FifoControl_ASYN #( pDepthWidth, pWordWidth ) Fifo_Controller   (      .inReset       ( inReset ) ,      .WriteClock    ( iWClk ) ,      .iWEn          ( iWEn ) ,      .MemWEn        ( MemWEn ) ,      .vWAddr        ( vWriteAddr ) ,      .qWFull        ( qWFull ) ,       .qvWCount      ( qvWCount ) ,      .ReadClock     ( iRClk ) ,      .iREn          ( iREn ) ,      .vRAddr        ( vReadAddr ) ,      .qREmpty       ( qREmpty ) ,       .MemDataOut    ( MemDataOut ),      .qvDataOut     ( ovDataOut ),      .qvRNumberLeft ( qvRNumberLeft )   ) ;endmodulemodule FifoControl_ASYN(   inReset ,   WriteClock ,   iWEn ,   MemWEn ,   vWAddr ,   qWFull ,    qvWCount ,   ReadClock ,   iREn ,   vRAddr ,   qREmpty ,    MemDataOut ,    qvDataOut ,    qvRNumberLeft);// Default address and data widthparameter   pDepthWidth = 5 ;parameter   pWordWidth = 16 ;input  inReset ;input  WriteClock ;input  iWEn ;output  MemWEn ;output  [pDepthWidth-1:0] vWAddr ;output  qWFull ;output  [pDepthWidth:0] qvWCount ;input   ReadClock ;input   iREn ;output  [pDepthWidth-1:0] vRAddr ;output  qREmpty ; input   [pWordWidth-1:0]  MemDataOut ;output  [pWordWidth-1:0]  qvDataOut ;output  [pDepthWidth:0]   qvRNumberLeft ;wire  inReset ;wire  WriteClock ;wire  iWEn ;wire  MemWEn ;wire  [pDepthWidth-1:0] vWAddr ;reg   qWFull ;reg   [pDepthWidth:0]   qvWCount ;wire  ReadClock ;wire  iREn ;wire  [pDepthWidth-1:0] vRAddr ;reg   qREmpty ; wire  [pWordWidth-1:0]  MemDataOut ;reg   [pWordWidth-1:0]  qvDataOut ;reg   [pDepthWidth:0]   qvRNumberLeft ;// internal variables   // write clock domainreg  [pDepthWidth:0] qvWAddr ;reg  [pDepthWidth:0] qvNextWAddr ;reg  [pDepthWidth:0] qvPreWGrayAddr ;reg  [pDepthWidth:0] qvWGrayAddr ;reg  [pDepthWidth:0] qvRGrayAddr_WSync1 ;reg  [pDepthWidth:0] qvRGrayAddr_WSync2 ;reg  [pDepthWidth:0] qvRAddr_WSync2 ;   // read clock domainreg  [pDepthWidth:0] qvRAddr ;reg  [pDepthWidth:0] qvNextRAddr ;reg  [pDepthWidth:0] qvRGrayAddr ;reg  [pDepthWidth:0] qvPreWGrayAddr_RSync1 ;reg  [pDepthWidth:0] qvPreWGrayAddr_RSync2 ;reg  [pDepthWidth:0] qvPreWAddr_RSync2 ;reg  [pDepthWidth:0] qvWGrayAddr_RSync1 ;reg  [pDepthWidth:0] qvWGrayAddr_RSync2 ;reg  [pDepthWidth:0] qvPointerForNumLeft ;reg  [pDepthWidth:0] qvNextPointerForNumLeft ;reg   qREmpty_int ;wire  MemREn ;assign MemREn = !qREmpty_int && ( qREmpty || iREn ) ;assign MemWEn = iWEn && ( !qWFull ) ;assign vWAddr = qvWAddr[pDepthWidth-1:0] ;assign vRAddr = MemREn ? qvNextRAddr[pDepthWidth-1:0] : qvRAddr[pDepthWidth-1:0] ;// logicinteger i;// write clock domain   // write addressalways @ ( negedge inReset or posedge WriteClock )begin   if( !inReset ) begin      qvWAddr <= 1 ;      qvNextWAddr <= 2 ;      qvPreWGrayAddr <= 0 ;      qvWGrayAddr <= 1 ;   end   else  if( MemWEn )   begin      qvWAddr <= qvNextWAddr ;      qvNextWAddr <= qvNextWAddr + 1'b1 ;      qvPreWGrayAddr <= qvWGrayAddr ;      qvWGrayAddr <= ( qvNextWAddr >> 1 ) ^ qvNextWAddr ;//      qvPreWGrayAddr <= ( qvWAddr >> 1 ) ^ qvWAddr ;   endend   // re-synchronize the read addresses within write clock domain      // the 1st synchronizing cyclealways @ ( negedge inReset or posedge WriteClock )  begin   if( !inReset ) begin      qvRGrayAddr_WSync1 <= 1 ;   end   else  begin      qvRGrayAddr_WSync1 <= qvRGrayAddr ;   endend      // the 2nd synchronizing cyclealways @ ( negedge inReset or posedge WriteClock )  begin   if( !inReset ) begin         qvRGrayAddr_WSync2 <= 1 ;   end   else  begin      qvRGrayAddr_WSync2 <= qvRGrayAddr_WSync1 ;   endend   //   to calculate the read address in write clock domainalways @ ( negedge inReset or posedge WriteClock )  begin   // 1 cycle delay will be added   if( !inReset ) begin         qvRAddr_WSync2 <= 1 ;   end   else  begin      for( i=0; i<=pDepthWidth; i=i+1 )         qvRAddr_WSync2[i] <= ^( qvRGrayAddr_WSync2 >>i ) ;   // Gray To Binary Conversion   endend//always @ ( qvRGrayAddr_WSync2 )   // Gray To Binary Conversion//   for( i=0; i<=pDepthWidth; i=i+1 )//      qvRAddr_WSync2[i] = ^( qvRGrayAddr_WSync2 >>i ) ;   // calculates qvWCount always @ ( negedge inReset or posedge WriteClock )  begin   if( !inReset ) begin         qvWCount <= 0 ;   end   else  begin      if( MemWEn )         qvWCount <= qvNextWAddr - qvRAddr_WSync2 ;      else         qvWCount <= qvWAddr - qvRAddr_WSync2 ;    end            end   // generates qWFullalways @ ( qvWCount[pDepthWidth] )   qWFull <= qvWCount[pDepthWidth] ;// read clock domain   // read addressalways @ ( negedge inReset or posedge ReadClock )begin   if( !inReset ) begin      qvRAddr <= 1 ;      qvNextRAddr <= 2 ;      qvRGrayAddr <= 1 ;      qvPointerForNumLeft <= { 1'b1, {pDepthWidth{1'b0}} } ;      qvNextPointerForNumLeft <= { 1'b1, {(pDepthWidth-1){1'b0}}, 1'b1 } ;   end   else  if( MemREn )   begin      qvRAddr <= qvNextRAddr ;      qvNextRAddr <= qvNextRAddr + 1'b1 ;      qvRGrayAddr <= ( qvNextRAddr >> 1 ) ^ qvNextRAddr ;      qvNextPointerForNumLeft <= qvNextPointerForNumLeft + 1'b1 ;      qvPointerForNumLeft <= qvNextPointerForNumLeft ;//      qvPointerForNumLeft <= qvPointerForNumLeft + 1'b1 ;    endend   // re-synchronize the write addresses within read clock domain      // the 1st synchronizing cyclealways @ ( negedge inReset or posedge ReadClock )  begin   if( !inReset ) begin         qvPreWGrayAddr_RSync1 <= 0 ;      qvWGrayAddr_RSync1 <= 1 ;   end   else  begin      qvPreWGrayAddr_RSync1 <= qvPreWGrayAddr ;      qvWGrayAddr_RSync1 <= qvWGrayAddr ;   endend      // the 2nd synchronizing cyclealways @ ( negedge inReset or posedge ReadClock )  begin   if( !inReset ) begin         qvPreWGrayAddr_RSync2 <= 0 ;      qvWGrayAddr_RSync2 <= 1 ;   end   else  begin      qvPreWGrayAddr_RSync2 <= qvPreWGrayAddr_RSync1 ;      qvWGrayAddr_RSync2 <= qvWGrayAddr_RSync1 ;   endend   //   to calculate the write address in read clock domainalways @ ( negedge inReset or posedge ReadClock )  begin   // 1 cycle delay will be added   if( !inReset ) begin         qvPreWAddr_RSync2 <= 0 ;   end   else  begin      for( i=0; i<=pDepthWidth; i=i+1 )         qvPreWAddr_RSync2[i] <= ^( qvPreWGrayAddr_RSync2 >>i ) ;   // Gray To Binary Conversion   endend//always @ ( qvPreWGrayAddr_RSync2 )   // Gray To Binary Conversion//   for( i=0; i<=pDepthWidth; i=i+1 )//      qvWAddr_RSync2[i] <= ^( qvPreWGrayAddr_RSync2 >>i ) ;   // Gray To Binary Conversion   // calculates qvRNumberLeftreg  [pDepthWidth:0] qvRNumberLeft_int ;always @ ( negedge inReset or posedge ReadClock )  begin   if( !inReset ) begin         qvRNumberLeft_int <= { 1'b1, {pDepthWidth{1'b0}} } ;   end   else  begin      if( MemREn )         qvRNumberLeft_int <= qvNextPointerForNumLeft - qvPreWAddr_RSync2 ;      else         qvRNumberLeft_int <= qvPointerForNumLeft - qvPreWAddr_RSync2 ;    end            endalways @ ( negedge inReset or posedge ReadClock )  begin   if( !inReset ) begin         qvRNumberLeft <= { 1'b1, {pDepthWidth{1'b0}} } ;   end   else  begin      if( qvRNumberLeft_int >= 4 )  qvRNumberLeft <= qvRNumberLeft_int - 4 ;       else  qvRNumberLeft <= 0 ;    end            end   // generates qREmpty_intalways @ ( negedge inReset or posedge ReadClock )  begin   if( !inReset ) begin         qREmpty_int <= 1 ;   end   else  begin      if( ~qREmpty_int ) begin         if( MemREn && ( qvRGrayAddr == qvPreWGrayAddr_RSync2 ) )            qREmpty_int <= 1 ;      end       else  begin          if( qvRGrayAddr != qvWGrayAddr_RSync2 )             qREmpty_int <= 0 ;       end   end            end//always @ ( qvRNumberLeft_int[pDepthWidth] )//   qREmpty_int <= qvRNumberLeft_int[pDepthWidth] ;always @ ( negedge inReset or posedge ReadClock )  begin   if( !inReset ) begin         qREmpty <= 1'b1 ;   end   else  begin      if( qREmpty )  begin         if( !qREmpty_int )   qREmpty <= 1'b0 ;       end       else         if( qREmpty_int && iREn )   qREmpty <= 1'b1 ;    end            endalways @ ( negedge inReset or posedge ReadClock )  begin   if( !inReset ) begin         qvDataOut <= {pWordWidth{1'b0}} ;   end   else  begin      if( MemREn )  begin         qvDataOut <= MemDataOut ;      end    end            endendmodule module DualPortRAM_ASYN   (      // Generic synchronous two-port RAM interface   WriteClock ,   MemWEn ,   MemWAddr ,   MemDataIn ,   ReadClock ,   MemRAddr ,   MemDataOut     );// Default address and data widthparameter   pDepthWidth = 5 ;                      parameter   pWordWidth = 16 ;                      // Generic synchronous two-port RAM interfaceinput WriteClock ;input MemWEn ;input MemWAddr ;input MemDataIn ;input ReadClock ;input  [pDepthWidth-1:0] MemRAddr ;output  [pWordWidth-1:0] MemDataOut ;wire  WriteClock ;wire  MemWEn ;wire  [pDepthWidth-1:0] MemWAddr ;wire  [pWordWidth-1:0] MemDataIn ;wire  ReadClock ;wire  [pDepthWidth-1:0] MemRAddr ;wire  [pWordWidth-1:0] MemDataOut ;reg   [pWordWidth-1:0]  mem [(1<<pDepthWidth)-1:0] /*synthesis syn_ramstyle="no_rw_check"*/; // RAM read and write// a port for writealways @ ( posedge WriteClock )   if( MemWEn )      mem[MemWAddr] <= MemDataIn ;// RAM read and write//b for read/* registered address */reg   [pDepthWidth-1:0] qvRAddr ;always @ ( posedge ReadClock )   qvRAddr <= MemRAddr ;   assign MemDataOut = mem[qvRAddr] ;endmodule 

⌨️ 快捷键说明

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