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

📄 eth_wishbone.v

📁 此文档为采用FPGA实现的以太网MAC层
💻 V
📖 第 1 页 / 共 5 页
字号:
reg             ReadTxDataFromFifo_tck;reg             BlockingTxStatusWrite;reg             BlockingTxBDRead;reg             Flop;reg     [7:1]   TxBDAddress;reg     [7:1]   RxBDAddress;reg             TxRetrySync1;reg             TxAbortSync1;reg             TxDoneSync1;reg             TxAbort_q;reg             TxRetry_q;reg             TxUsedData_q;reg    [31:0]   RxDataLatched2;reg    [31:8]   RxDataLatched1;     // Big Endian Byte Orderingreg     [1:0]   RxValidBytes;reg     [1:0]   RxByteCnt;reg             LastByteIn;reg             ShiftWillEnd;reg             WriteRxDataToFifo;reg    [15:0]   LatchedRxLength;reg             RxAbortLatched;reg             ShiftEnded;reg             RxOverrun;reg     [3:0]   BDWrite;                    // BD Write Enable for access from WISHBONE sidereg             BDRead;                     // BD Read access from WISHBONE sidewire   [31:0]   RxBDDataIn;                 // Rx BD data inwire   [31:0]   TxBDDataIn;                 // Tx BD data inreg             TxEndFrm_wb;wire            TxRetryPulse;wire            TxDonePulse;wire            TxAbortPulse;wire            StartRxBDRead;wire            StartTxBDRead;wire            TxIRQEn;wire            WrapTxStatusBit;wire            RxIRQEn;wire            WrapRxStatusBit;wire    [1:0]   TxValidBytes;wire    [7:1]   TempTxBDAddress;wire    [7:1]   TempRxBDAddress;wire            RxStatusWrite;wire            RxBufferFull;wire            RxBufferAlmostEmpty;wire            RxBufferEmpty;reg             WB_ACK_O;wire    [8:0]   RxStatusIn;reg     [8:0]   RxStatusInLatched;reg WbEn, WbEn_q;reg RxEn, RxEn_q;reg TxEn, TxEn_q;reg r_TxEn_q;reg r_RxEn_q;wire ram_ce;wire [3:0]  ram_we;wire ram_oe;reg [7:0]   ram_addr;reg [31:0]  ram_di;wire [31:0] ram_do;wire StartTxPointerRead;reg  TxPointerRead;reg TxEn_needed;reg RxEn_needed;wire StartRxPointerRead;reg RxPointerRead; `ifdef ETH_WISHBONE_B3assign m_wb_bte_o = 2'b00;    // Linear burst`endifassign m_wb_stb_o = m_wb_cyc_o;always @ (posedge WB_CLK_I)begin  WB_ACK_O <=#Tp (|BDWrite) & WbEn & WbEn_q | BDRead & WbEn & ~WbEn_q;endassign WB_DAT_O = ram_do;// Generic synchronous single-port RAM interfaceeth_spram_256x32 bd_ram (	.clk(WB_CLK_I), .rst(Reset), .ce(ram_ce), .we(ram_we), .oe(ram_oe), .addr(ram_addr), .di(ram_di), .do(ram_do)`ifdef ETH_BIST  ,  .mbist_si_i       (mbist_si_i),  .mbist_so_o       (mbist_so_o),  .mbist_ctrl_i       (mbist_ctrl_i)`endif);assign ram_ce = 1'b1;assign ram_we = (BDWrite & {4{(WbEn & WbEn_q)}}) | {4{(TxStatusWrite | RxStatusWrite)}};assign ram_oe = BDRead & WbEn & WbEn_q | TxEn & TxEn_q & (TxBDRead | TxPointerRead) | RxEn & RxEn_q & (RxBDRead | RxPointerRead);always @ (posedge WB_CLK_I or posedge Reset)begin  if(Reset)    TxEn_needed <=#Tp 1'b0;  else  if(~TxBDReady & r_TxEn & WbEn & ~WbEn_q)    TxEn_needed <=#Tp 1'b1;  else  if(TxPointerRead & TxEn & TxEn_q)    TxEn_needed <=#Tp 1'b0;end// Enabling access to the RAM for three devices.always @ (posedge WB_CLK_I or posedge Reset)begin  if(Reset)    begin      WbEn <=#Tp 1'b1;      RxEn <=#Tp 1'b0;      TxEn <=#Tp 1'b0;      ram_addr <=#Tp 8'h0;      ram_di <=#Tp 32'h0;      BDRead <=#Tp 1'b0;      BDWrite <=#Tp 1'b0;    end  else    begin      // Switching between three stages depends on enable signals      case ({WbEn_q, RxEn_q, TxEn_q, RxEn_needed, TxEn_needed})  // synopsys parallel_case        5'b100_10, 5'b100_11 :          begin            WbEn <=#Tp 1'b0;            RxEn <=#Tp 1'b1;  // wb access stage and r_RxEn is enabled            TxEn <=#Tp 1'b0;            ram_addr <=#Tp {RxBDAddress, RxPointerRead};            ram_di <=#Tp RxBDDataIn;          end        5'b100_01 :          begin            WbEn <=#Tp 1'b0;            RxEn <=#Tp 1'b0;            TxEn <=#Tp 1'b1;  // wb access stage, r_RxEn is disabled but r_TxEn is enabled            ram_addr <=#Tp {TxBDAddress, TxPointerRead};            ram_di <=#Tp TxBDDataIn;          end        5'b010_00, 5'b010_10 :          begin            WbEn <=#Tp 1'b1;  // RxEn access stage and r_TxEn is disabled            RxEn <=#Tp 1'b0;            TxEn <=#Tp 1'b0;            ram_addr <=#Tp WB_ADR_I[9:2];            ram_di <=#Tp WB_DAT_I;            BDWrite <=#Tp BDCs[3:0] & {4{WB_WE_I}};            BDRead <=#Tp (|BDCs) & ~WB_WE_I;          end        5'b010_01, 5'b010_11 :          begin            WbEn <=#Tp 1'b0;            RxEn <=#Tp 1'b0;            TxEn <=#Tp 1'b1;  // RxEn access stage and r_TxEn is enabled            ram_addr <=#Tp {TxBDAddress, TxPointerRead};            ram_di <=#Tp TxBDDataIn;          end        5'b001_00, 5'b001_01, 5'b001_10, 5'b001_11 :          begin            WbEn <=#Tp 1'b1;  // TxEn access stage (we always go to wb access stage)            RxEn <=#Tp 1'b0;            TxEn <=#Tp 1'b0;            ram_addr <=#Tp WB_ADR_I[9:2];            ram_di <=#Tp WB_DAT_I;            BDWrite <=#Tp BDCs[3:0] & {4{WB_WE_I}};            BDRead <=#Tp (|BDCs) & ~WB_WE_I;          end        5'b100_00 :          begin            WbEn <=#Tp 1'b0;  // WbEn access stage and there is no need for other stages. WbEn needs to be switched off for a bit          end        5'b000_00 :          begin            WbEn <=#Tp 1'b1;  // Idle state. We go to WbEn access stage.            RxEn <=#Tp 1'b0;            TxEn <=#Tp 1'b0;            ram_addr <=#Tp WB_ADR_I[9:2];            ram_di <=#Tp WB_DAT_I;            BDWrite <=#Tp BDCs[3:0] & {4{WB_WE_I}};            BDRead <=#Tp (|BDCs) & ~WB_WE_I;          end      endcase    endend// Delayed stage signalsalways @ (posedge WB_CLK_I or posedge Reset)begin  if(Reset)    begin      WbEn_q <=#Tp 1'b0;      RxEn_q <=#Tp 1'b0;      TxEn_q <=#Tp 1'b0;      r_TxEn_q <=#Tp 1'b0;      r_RxEn_q <=#Tp 1'b0;    end  else    begin      WbEn_q <=#Tp WbEn;      RxEn_q <=#Tp RxEn;      TxEn_q <=#Tp TxEn;      r_TxEn_q <=#Tp r_TxEn;      r_RxEn_q <=#Tp r_RxEn;    endend// Changes for tx occur every second clock. Flop is used for this manner.always @ (posedge MTxClk or posedge Reset)begin  if(Reset)    Flop <=#Tp 1'b0;  else  if(TxDone | TxAbort | TxRetry_q)    Flop <=#Tp 1'b0;  else  if(TxUsedData)    Flop <=#Tp ~Flop;endwire ResetTxBDReady;assign ResetTxBDReady = TxDonePulse | TxAbortPulse | TxRetryPulse;// Latching READY status of the Tx buffer descriptoralways @ (posedge WB_CLK_I or posedge Reset)begin  if(Reset)    TxBDReady <=#Tp 1'b0;  else  if(TxEn & TxEn_q & TxBDRead)    TxBDReady <=#Tp ram_do[15] & (ram_do[31:16] > 4); // TxBDReady is sampled only once at the beginning.  else                                                // Only packets larger then 4 bytes are transmitted.  if(ResetTxBDReady)    TxBDReady <=#Tp 1'b0;end// Reading the Tx buffer descriptorassign StartTxBDRead = (TxRetryPacket_NotCleared | TxStatusWrite) & ~BlockingTxBDRead & ~TxBDReady;always @ (posedge WB_CLK_I or posedge Reset)begin  if(Reset)    TxBDRead <=#Tp 1'b1;  else  if(StartTxBDRead)    TxBDRead <=#Tp 1'b1;  else  if(TxBDReady)    TxBDRead <=#Tp 1'b0;end// Reading Tx BD pointerassign StartTxPointerRead = TxBDRead & TxBDReady;// Reading Tx BD Pointeralways @ (posedge WB_CLK_I or posedge Reset)begin  if(Reset)    TxPointerRead <=#Tp 1'b0;  else  if(StartTxPointerRead)    TxPointerRead <=#Tp 1'b1;  else  if(TxEn_q)    TxPointerRead <=#Tp 1'b0;end// Writing status back to the Tx buffer descriptorassign TxStatusWrite = (TxDonePacket_NotCleared | TxAbortPacket_NotCleared) & TxEn & TxEn_q & ~BlockingTxStatusWrite;// Status writing must occur only once. Meanwhile it is blocked.always @ (posedge WB_CLK_I or posedge Reset)begin  if(Reset)    BlockingTxStatusWrite <=#Tp 1'b0;  else  if(~TxDone_wb & ~TxAbort_wb)    BlockingTxStatusWrite <=#Tp 1'b0;  else  if(TxStatusWrite)    BlockingTxStatusWrite <=#Tp 1'b1;endreg BlockingTxStatusWrite_sync1;reg BlockingTxStatusWrite_sync2;reg BlockingTxStatusWrite_sync3;// Synchronizing BlockingTxStatusWrite to MTxClkalways @ (posedge MTxClk or posedge Reset)begin  if(Reset)    BlockingTxStatusWrite_sync1 <=#Tp 1'b0;  else    BlockingTxStatusWrite_sync1 <=#Tp BlockingTxStatusWrite;end// Synchronizing BlockingTxStatusWrite to MTxClkalways @ (posedge MTxClk or posedge Reset)begin  if(Reset)    BlockingTxStatusWrite_sync2 <=#Tp 1'b0;  else    BlockingTxStatusWrite_sync2 <=#Tp BlockingTxStatusWrite_sync1;end// Synchronizing BlockingTxStatusWrite to MTxClkalways @ (posedge MTxClk or posedge Reset)begin  if(Reset)    BlockingTxStatusWrite_sync3 <=#Tp 1'b0;  else    BlockingTxStatusWrite_sync3 <=#Tp BlockingTxStatusWrite_sync2;endassign RstDeferLatched = BlockingTxStatusWrite_sync2 & ~BlockingTxStatusWrite_sync3;// TxBDRead state is activated only once. always @ (posedge WB_CLK_I or posedge Reset)begin  if(Reset)    BlockingTxBDRead <=#Tp 1'b0;  else  if(StartTxBDRead)    BlockingTxBDRead <=#Tp 1'b1;  else  if(~StartTxBDRead & ~TxBDReady)    BlockingTxBDRead <=#Tp 1'b0;end// Latching status from the tx buffer descriptor// Data is avaliable one cycle after the access is started (at that time signal TxEn is not active)always @ (posedge WB_CLK_I or posedge Reset)begin  if(Reset)    TxStatus <=#Tp 4'h0;  else  if(TxEn & TxEn_q & TxBDRead)    TxStatus <=#Tp ram_do[14:11];endreg ReadTxDataFromMemory;wire WriteRxDataToMemory;reg MasterWbTX;reg MasterWbRX;reg [29:0] m_wb_adr_o;reg        m_wb_cyc_o;reg  [3:0] m_wb_sel_o;reg        m_wb_we_o;wire TxLengthEq0;wire TxLengthLt4;reg BlockingIncrementTxPointer;reg [31:2] TxPointerMSB;reg [1:0]  TxPointerLSB;reg [1:0]  TxPointerLSB_rst;reg [31:2] RxPointerMSB;reg [1:0]  RxPointerLSB_rst;wire RxBurstAcc;wire RxWordAcc;wire RxHalfAcc;wire RxByteAcc;//Latching length from the buffer descriptor;always @ (posedge WB_CLK_I or posedge Reset)begin  if(Reset)    TxLength <=#Tp 16'h0;  else  if(TxEn & TxEn_q & TxBDRead)    TxLength <=#Tp ram_do[31:16];  else  if(MasterWbTX & m_wb_ack_i)    begin      if(TxLengthLt4)        TxLength <=#Tp 16'h0;      else      if(TxPointerLSB_rst==2'h0)        TxLength <=#Tp TxLength - 3'h4;    // Length is subtracted at the data request      else      if(TxPointerLSB_rst==2'h1)        TxLength <=#Tp TxLength - 3'h3;    // Length is subtracted at the data request      else      if(TxPointerLSB_rst==2'h2)        TxLength <=#Tp TxLength - 3'h2;    // Length is subtracted at the data request      else      if(TxPointerLSB_rst==2'h3)        TxLength <=#Tp TxLength - 3'h1;    // Length is subtracted at the data request    endend//Latching length from the buffer descriptor;always @ (posedge WB_CLK_I or posedge Reset)begin  if(Reset)    LatchedTxLength <=#Tp 16'h0;  else  if(TxEn & TxEn_q & TxBDRead)    LatchedTxLength <=#Tp ram_do[31:16];endassign TxLengthEq0 = TxLength == 0;assign TxLengthLt4 = TxLength < 4;reg cyc_cleared;reg IncrTxPointer;// Latching Tx buffer pointer from buffer descriptor. Only 30 MSB bits are latched// because TxPointerMSB is only used for word-aligned accesses.always @ (posedge WB_CLK_I or posedge Reset)begin  if(Reset)    TxPointerMSB <=#Tp 30'h0;  else  if(TxEn & TxEn_q & TxPointerRead)    TxPointerMSB <=#Tp ram_do[31:2];  else  if(IncrTxPointer & ~BlockingIncrementTxPointer)    TxPointerMSB <=#Tp TxPointerMSB + 1'b1;     // TxPointer is word-alignedend// Latching 2 MSB bits of the buffer descriptor. Since word accesses are performed,// valid data does not necesserly start at byte 0 (could be byte 0, 1, 2 or 3). This

⌨️ 快捷键说明

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