📄 eth_avalon.v
字号:
assign bd_index = rx_txn_sel ? (rx_bd_index + r_TxBDNum) : tx_bd_index;// Determine BD wait signal back to RX interfaceassign rx_bd_wait = ~rx_txn_sel | (rx_txn_sel & rx_bd_read & ~rx_bd_read_r);// Determine BD wait signal back to TX interfaceassign tx_bd_wait = rx_txn_sel | (~rx_txn_sel & tx_bd_read & ~tx_bd_read_r);// Register BD RAM read signals used to control waitalways @(posedge av_clk) begin av_read_r <= av_read; rx_bd_read_r <= rx_bd_read & rx_txn_sel; tx_bd_read_r <= tx_bd_read & ~rx_txn_sel; if((rx_txn_sel & ~rx_bd_wait) | (~rx_txn_sel & ~tx_bd_wait)) rx_txn_sel <= ~rx_txn_sel;end// Pointer BD RAMeth_avalon_bd_ram #(.DEPTH(RDC) ) ptr_ram( .clock (av_clk ), // port A (Avalon interface) .wren_a (av_write&av_bd_ptr_cs ), .address_a (av_address>>1 ), .data_a (av_writedata ), .q_a (av_ptr_readdata ), // port B (DMA interface) .wren_b (1'b0 ), .address_b (bd_index ), .data_b (32'd0 ), .q_b (bd_ptr ) );// Descriptor BD RAMeth_avalon_bd_ram #(.DEPTH(RDC) ) desc_ram( .clock (av_clk ), // port A (Avalon interface) .wren_a (av_write&av_bd_desc_cs ), .address_a (av_address>>1 ), .data_a (av_writedata ), .q_a (av_desc_readdata ), // port B (DMA interface) .wren_b (bd_write ), .address_b (bd_index ), .data_b (bd_writedata ), .q_b (bd_desc ) );//************************ End Descriptor Interface *************************//***************************************************************************//***************************************************************************//****************************** RX Interface *******************************// Determine maximum RX descriptor index assign max_rx_bd = MAX_DESC - r_TxBDNum;// Decode RX Status inputsassign RxStatus = { ReceivedPauseFrm, AddressMiss , 1'b0 , InvalidSymbol , DribbleNibble, ReceivedPacketTooBig, ShortFrame, LatchedCrcError, RxLateCollision};//RX Interface is held in reset when not enabledalways @(posedge av_clk) rx_reset <= av_reset | ~r_RxEn;//RX Interfaceeth_avalon_rxdma #(.FIFO_DEPTH(RX_FIFO_DEPTH) ) eth_rxdma_inst( .clk (av_clk ), // Avalon clock .reset (rx_reset ), // Avalon reset //Descriptor ram interface .max_rx_bd (max_rx_bd ), // Highest index RX Descriptor .bd_desc (bd_desc ), // Descriptor Control data input .bd_ptr (bd_ptr ), // Descriptor pointer input .bd_wait (rx_bd_wait ), // Descriptor RAM is busy .bd_write (rx_bd_write ), // write control data to BD RAM .bd_read (rx_bd_read ), // read control and pointer data from BD RAM .bd_index (rx_bd_index ), // Which descriptor to read .bd_writedata (rx_bd_writedata ), // Control data to be written to descriptor //Memory port interface .av_waitrequest (av_rx_waitrequest ), // Memory port is busy .av_write (av_rx_write ), // Memory port write .av_address (av_rx_address ), // Memory port address .av_writedata (av_rx_writedata ), // Memory port writedata .av_byteenable (av_rx_byteenable ), // Memory port byteenable //Streaming interface .RxEn (r_RxEn ), // Receive enable .rxclk (MRxClk ), // Receive clock .rx_data (RxData ), // input data .rx_dv (RxValid ), // qualifies datain, startofpacket, and endofpacket .rx_err (RxStatus_r ), // error bits .rx_sop (RxStartFrm ), // start of data packet .rx_eop (RxEndFrm | RxAbort ), // end of data packet //Interrupt outputs .RxB_IRQ (RxB_IRQ ), // Receive success IRQ .RxE_IRQ (RxE_IRQ ), // Receive error IRQ .Busy_IRQ (Busy_IRQ ) // Receive busy IRQ);//Register RxStatusalways @(posedge MRxClk) if (LoadRxStatus) RxStatus_r <= RxStatus;//We save the data and cross the clock domains in the RX DMA module so //there is no need for synchronization here. We do it to be compliant//with Igor's implementaionalways @(posedge MRxClk) RxStatusWriteLatched_sync2 <= LoadRxStatus;//***************************************************************************//**************************** TX Interface *********************************// TX interface is held in reset when not enabledalways @(posedge av_clk) tx_reset <= av_reset | ~r_TxEn;//TX Interfaceeth_avalon_txdma #(.FIFO_DEPTH(TX_FIFO_DEPTH)) eth_txdma_inst( //Common signals .clk (av_clk ), // Avalon clock .reset (tx_reset ), // Avalon reset //Descriptor ram interface .max_tx_bd (r_TxBDNum - 7'd1 ), // Highest index RX Descriptor .bd_desc (bd_desc ), // Descriptor Control data input .bd_ptr (bd_ptr ), // Descriptor pointer input .bd_wait (tx_bd_wait ), // Descriptor RAM is busy .bd_write (tx_bd_write ), // write control data to BD RAM .bd_read (tx_bd_read ), // read control and pointer data from BD RAM .bd_index (tx_bd_index ), // Which descriptor to read .bd_writedata (tx_bd_writedata ), // Control data to be written to descriptor //Memory port interface .av_waitrequest (av_tx_waitrequest ), // Memory port is busy .av_readdata (av_tx_readdata ), // Memory port readdata .av_readdatavalid (av_tx_readdatavalid), // Memory port readdata valid signal .av_read (av_tx_read ), // Memory port read .av_address (av_tx_address ), // Memory port address //Streaming interface .TxEn (r_TxEn ), // Enable transmit .txclk (MTxClk ), // Transmit clock .tx_data (TxData ), // output data .tx_dv ( ), // qualifies dataout, startofpacket, and endofpacket .tx_sop (TxStartFrm ), // start of data packet .tx_eop (TxEndFrm ), // end of data packet .tx_ack (TxUsedData & Flop ), // Acknowledge TX data .tx_stat ({TxUnderRun_r, RetryCntLatched, RetryLimit, LateCollLatched, DeferLatched, CarrierSenseLost}), // Status bits .tx_stat_valid (TxRetry|TxAbort|TxDone),// Status is valid .tx_stat_ack (tx_stat_ack ), .tx_retry (tx_retry ), .PerPacketPad (PerPacketPad ), .PerPacketCrc (PerPacketCrcEn ), .TxUnderRun (TxUnderRun ), //Interrupt outputs .TxB_IRQ (TxB_IRQ ), // TX success IRQ .TxE_IRQ (TxE_IRQ ) // TX error IRQ );//Send Reset defered latch back to coreassign RstDeferLatched = (TxRetry|TxAbort|TxDone);//The Flop signal is used to toggle valid TxUsedData//because the core only uses the data on every other//clock (8 bits local interface vs. 4 bits MII interface)always @(posedge MTxClk or posedge tx_reset) if(tx_reset) Flop <= 1'b0; else if(TxDone|TxAbort|TxRetry) Flop <= 1'b0; else if(TxUsedData) Flop <= ~Flop;always @(posedge MTxClk or posedge tx_reset) if(tx_reset) TxUnderRun_r <= 1'b0; else begin if(tx_stat_ack) TxUnderRun_r <= 1'b0; if(TxUnderRun) TxUnderRun_r <= 1'b1; endalways @(posedge MTxClk or posedge tx_reset) if(tx_reset) tx_retry <= 1'b0; else if(TxRetry) tx_retry <= 1'b1; else if(tx_stat_ack) tx_retry <= 1'b0;endmodule
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -