📄 eth_wishbone.v
字号:
rx_burst_en<=#Tp MasterWbRX ? enough_data_in_rxfifo_for_burst_plus1 : enough_data_in_rxfifo_for_burst; // Counter is not decremented, yet, so plus1 is used.
`ifdef ETH_WISHBONE_B3
m_wb_cti_o <=#Tp 3'b0;
`endif
end
8'b00_00_00_00: // whatever and no master read or write is needed (ack or err comes finishing previous access)
begin
tx_burst_cnt<=#Tp 0;
tx_burst_en<=#Tp txfifo_cnt<(`ETH_TX_FIFO_DEPTH-`ETH_BURST_LENGTH) & (TxLength>(`ETH_BURST_LENGTH*4+4));
end
default: // Don't touch
begin
MasterWbTX <=#Tp MasterWbTX;
MasterWbRX <=#Tp MasterWbRX;
m_wb_cyc_o <=#Tp m_wb_cyc_o;
m_wb_stb_o <=#Tp m_wb_stb_o;
m_wb_sel_o <=#Tp m_wb_sel_o;
IncrTxPointer<=#Tp IncrTxPointer;
end
endcase
end
end
wire TxFifoClear;
assign TxFifoClear = (TxAbortPacket | TxRetryPacket);
eth_fifo #(`ETH_TX_FIFO_DATA_WIDTH, `ETH_TX_FIFO_DEPTH, `ETH_TX_FIFO_CNT_WIDTH)
tx_fifo ( .data_in(m_wb_dat_i), .data_out(TxData_wb),
.clk(WB_CLK_I), .reset(Reset),
.write(MasterWbTX & m_wb_ack_i), .read(ReadTxDataFromFifo_wb & ~TxBufferEmpty),
.clear(TxFifoClear), .full(TxBufferFull),
.almost_full(TxBufferAlmostFull), .almost_empty(TxBufferAlmostEmpty),
.empty(TxBufferEmpty), .cnt(txfifo_cnt)
);
reg StartOccured;
reg TxStartFrm_sync1;
reg TxStartFrm_sync2;
reg TxStartFrm_syncb1;
reg TxStartFrm_syncb2;
// Start: Generation of the TxStartFrm_wb which is then synchronized to the MTxClk
always @ (posedge WB_CLK_I or posedge Reset)
begin
if(Reset)
TxStartFrm_wb <=#Tp 1'b0;
else
if(TxBDReady & ~StartOccured & (TxBufferFull | TxLengthEq0))
TxStartFrm_wb <=#Tp 1'b1;
else
if(TxStartFrm_syncb2)
TxStartFrm_wb <=#Tp 1'b0;
end
// StartOccured: TxStartFrm_wb occurs only ones at the beginning. Then it's blocked.
always @ (posedge WB_CLK_I or posedge Reset)
begin
if(Reset)
StartOccured <=#Tp 1'b0;
else
if(TxStartFrm_wb)
StartOccured <=#Tp 1'b1;
else
if(ResetTxBDReady)
StartOccured <=#Tp 1'b0;
end
// Synchronizing TxStartFrm_wb to MTxClk
always @ (posedge MTxClk or posedge Reset)
begin
if(Reset)
TxStartFrm_sync1 <=#Tp 1'b0;
else
TxStartFrm_sync1 <=#Tp TxStartFrm_wb;
end
always @ (posedge MTxClk or posedge Reset)
begin
if(Reset)
TxStartFrm_sync2 <=#Tp 1'b0;
else
TxStartFrm_sync2 <=#Tp TxStartFrm_sync1;
end
always @ (posedge WB_CLK_I or posedge Reset)
begin
if(Reset)
TxStartFrm_syncb1 <=#Tp 1'b0;
else
TxStartFrm_syncb1 <=#Tp TxStartFrm_sync2;
end
always @ (posedge WB_CLK_I or posedge Reset)
begin
if(Reset)
TxStartFrm_syncb2 <=#Tp 1'b0;
else
TxStartFrm_syncb2 <=#Tp TxStartFrm_syncb1;
end
always @ (posedge MTxClk or posedge Reset)
begin
if(Reset)
TxStartFrm <=#Tp 1'b0;
else
if(TxStartFrm_sync2)
TxStartFrm <=#Tp 1'b1;
else
if(TxUsedData_q | ~TxStartFrm_sync2 & (TxRetry & (~TxRetry_q) | TxAbort & (~TxAbort_q)))
TxStartFrm <=#Tp 1'b0;
end
// End: Generation of the TxStartFrm_wb which is then synchronized to the MTxClk
// TxEndFrm_wb: indicator of the end of frame
always @ (posedge WB_CLK_I or posedge Reset)
begin
if(Reset)
TxEndFrm_wb <=#Tp 1'b0;
else
if(TxLengthEq0 & TxBufferAlmostEmpty & TxUsedData)
TxEndFrm_wb <=#Tp 1'b1;
else
if(TxRetryPulse | TxDonePulse | TxAbortPulse)
TxEndFrm_wb <=#Tp 1'b0;
end
// Marks which bytes are valid within the word.
assign TxValidBytes = TxLengthLt4 ? TxLength[1:0] : 2'b0;
reg LatchValidBytes;
reg LatchValidBytes_q;
always @ (posedge WB_CLK_I or posedge Reset)
begin
if(Reset)
LatchValidBytes <=#Tp 1'b0;
else
if(TxLengthLt4 & TxBDReady)
LatchValidBytes <=#Tp 1'b1;
else
LatchValidBytes <=#Tp 1'b0;
end
always @ (posedge WB_CLK_I or posedge Reset)
begin
if(Reset)
LatchValidBytes_q <=#Tp 1'b0;
else
LatchValidBytes_q <=#Tp LatchValidBytes;
end
// Latching valid bytes
always @ (posedge WB_CLK_I or posedge Reset)
begin
if(Reset)
TxValidBytesLatched <=#Tp 2'h0;
else
if(LatchValidBytes & ~LatchValidBytes_q)
TxValidBytesLatched <=#Tp TxValidBytes;
else
if(TxRetryPulse | TxDonePulse | TxAbortPulse)
TxValidBytesLatched <=#Tp 2'h0;
end
assign TxIRQEn = TxStatus[14];
assign WrapTxStatusBit = TxStatus[13];
assign PerPacketPad = TxStatus[12];
assign PerPacketCrcEn = TxStatus[11];
assign RxIRQEn = RxStatus[14];
assign WrapRxStatusBit = RxStatus[13];
// Temporary Tx and Rx buffer descriptor address
assign TempTxBDAddress[7:0] = {8{ TxStatusWrite & ~WrapTxStatusBit}} & (TxBDAddress + 2'h2) ; // Tx BD increment or wrap (last BD)
assign TempRxBDAddress[7:0] = {8{ WrapRxStatusBit}} & (r_TxBDNum<<1) | // Using first Rx BD
{8{~WrapRxStatusBit}} & (RxBDAddress + 2'h2) ; // Using next Rx BD (incremenrement address)
// Latching Tx buffer descriptor address
always @ (posedge WB_CLK_I or posedge Reset)
begin
if(Reset)
TxBDAddress <=#Tp 8'h0;
else
if(TxStatusWrite)
TxBDAddress <=#Tp TempTxBDAddress;
end
// Latching Rx buffer descriptor address
always @ (posedge WB_CLK_I or posedge Reset)
begin
if(Reset)
RxBDAddress <=#Tp `ETH_TX_BD_NUM_DEF<<1;
else
if(TX_BD_NUM_Wr) // When r_TxBDNum is updated, RxBDAddress is also
RxBDAddress <=#Tp WB_DAT_I[7:0]<<1;
else
if(RxStatusWrite)
RxBDAddress <=#Tp TempRxBDAddress;
end
wire [8:0] TxStatusInLatched = {TxUnderRun, RetryCntLatched[3:0], RetryLimit, LateCollLatched, DeferLatched, CarrierSenseLost};
assign RxBDDataIn = {LatchedRxLength, 1'b0, RxStatus, 4'h0, RxStatusInLatched};
assign TxBDDataIn = {LatchedTxLength, 1'b0, TxStatus, 2'h0, TxStatusInLatched};
// Signals used for various purposes
assign TxRetryPulse = TxRetry_wb & ~TxRetry_wb_q;
assign TxDonePulse = TxDone_wb & ~TxDone_wb_q;
assign TxAbortPulse = TxAbort_wb & ~TxAbort_wb_q;
// Generating delayed signals
always @ (posedge MTxClk or posedge Reset)
begin
if(Reset)
begin
TxAbort_q <=#Tp 1'b0;
TxRetry_q <=#Tp 1'b0;
TxUsedData_q <=#Tp 1'b0;
end
else
begin
TxAbort_q <=#Tp TxAbort;
TxRetry_q <=#Tp TxRetry;
TxUsedData_q <=#Tp TxUsedData;
end
end
// Generating delayed signals
always @ (posedge WB_CLK_I or posedge Reset)
begin
if(Reset)
begin
TxDone_wb_q <=#Tp 1'b0;
TxAbort_wb_q <=#Tp 1'b0;
TxRetry_wb_q <=#Tp 1'b0;
end
else
begin
TxDone_wb_q <=#Tp TxDone_wb;
TxAbort_wb_q <=#Tp TxAbort_wb;
TxRetry_wb_q <=#Tp TxRetry_wb;
end
end
reg TxAbortPacketBlocked;
always @ (posedge WB_CLK_I or posedge Reset)
begin
if(Reset)
TxAbortPacket <=#Tp 1'b0;
else
if(TxAbort_wb & (~tx_burst_en) & MasterWbTX & MasterAccessFinished & (~TxAbortPacketBlocked) |
TxAbort_wb & (~MasterWbTX) & (~TxAbortPacketBlocked))
TxAbortPacket <=#Tp 1'b1;
else
TxAbortPacket <=#Tp 1'b0;
end
always @ (posedge WB_CLK_I or posedge Reset)
begin
if(Reset)
TxAbortPacket_NotCleared <=#Tp 1'b0;
else
if(TxEn & TxEn_q & TxAbortPacket_NotCleared)
TxAbortPacket_NotCleared <=#Tp 1'b0;
else
if(TxAbort_wb & (~tx_burst_en) & MasterWbTX & MasterAccessFinished & (~TxAbortPacketBlocked) |
TxAbort_wb & (~MasterWbTX) & (~TxAbortPacketBlocked))
TxAbortPacket_NotCleared <=#Tp 1'b1;
end
always @ (posedge WB_CLK_I or posedge Reset)
begin
if(Reset)
TxAbortPacketBlocked <=#Tp 1'b0;
else
if(!TxAbort_wb & TxAbort_wb_q)
TxAbortPacketBlocked <=#Tp 1'b0;
else
if(TxAbortPacket)
TxAbortPacketBlocked <=#Tp 1'b1;
end
reg TxRetryPacketBlocked;
always @ (posedge WB_CLK_I or posedge Reset)
begin
if(Reset)
TxRetryPacket <=#Tp 1'b0;
else
if(TxRetry_wb & !tx_burst_en & MasterWbTX & MasterAccessFinished & !TxRetryPacketBlocked |
TxRetry_wb & !MasterWbTX & !TxRetryPacketBlocked)
TxRetryPacket <=#Tp 1'b1;
else
TxRetryPacket <=#Tp 1'b0;
end
always @ (posedge WB_CLK_I or posedge Reset)
begin
if(Reset)
TxRetryPacket_NotCleared <=#Tp 1'b0;
else
if(StartTxBDRead)
TxRetryPacket_NotCleared <=#Tp 1'b0;
else
if(TxRetry_wb & !tx_burst_en & MasterWbTX & MasterAccessFinished & !TxRetryPacketBlocked |
TxRetry_wb & !MasterWbTX & !TxRetryPacketBlocked)
TxRetryPacket_NotCleared <=#Tp 1'b1;
end
always @ (posedge WB_CLK_I or posedge Reset)
begin
if(Reset)
TxRetryPacketBlocked <=#Tp 1'b0;
else
if(!TxRetry_wb & TxRetry_wb_q)
TxRetryPacketBlocked <=#Tp 1'b0;
else
if(TxRetryPacket)
TxRetryPacketBlocked <=#Tp 1'b1;
end
reg TxDonePacketBlocked;
always @ (posedge WB_CLK_I or posedge Reset)
begin
if(Reset)
TxDonePacket <=#Tp 1'b0;
else
if(TxDone_wb & !tx_burst_en & MasterWbTX & MasterAccessFinished & !TxDonePacketBlocked |
TxDone_wb & !MasterWbTX & !TxDonePacketBlocked)
TxDonePacket <=#Tp 1'b1;
else
TxDonePacket <=#Tp 1'b0;
end
always @ (posedge WB_CLK_I or posedge Reset)
begin
if(Reset)
TxDonePacket_NotCleared <=#Tp 1'b0;
else
if(TxEn & TxEn_q & TxDonePacket_NotCleared)
TxDonePacket_NotCleared <=#Tp 1'b0;
else
if(TxDone_wb & !tx_burst_en & MasterWbTX & MasterAccessFinished & (~TxDonePacketBlocked) |
TxDone_wb & !MasterWbTX & (~TxDonePacketBlocked))
TxDonePacket_NotCleared <=#Tp 1'b1;
end
always @ (posedge WB_CLK_I or posedge Reset)
begin
if(Reset)
TxDonePacketBlocked <=#Tp 1'b0;
else
if(!TxDone_wb & TxDone_wb_q)
TxDonePacketBlocked <=#Tp 1'b0;
else
if(TxDonePacket)
TxDonePacketBlocked <=#Tp 1'b1;
end
// Indication of the last word
always @ (posedge MTxClk or posedge Reset)
begin
if(Reset)
LastWord <=#Tp 1'b0;
else
if((TxEndFrm | TxAbort | TxRetry) & Flop)
LastWord <=#Tp 1'b0;
else
if(TxUsedData & Flop & TxByteCnt == 2'h3)
LastWord <=#Tp TxEndFrm_wb;
end
// Tx end frame generation
always @ (posedge MTxClk or posedge Reset)
begin
if(Reset)
TxEndFrm <=#Tp 1'b0;
else
if(Flop & TxEndFrm | TxAbort | TxRetry_q)
TxEndFrm <=#Tp 1'b0;
else
if(Flop & LastWord)
begin
case (TxValidBytesLatched) // synopsys parallel_case
1 : TxEndFrm <=#Tp TxByteCnt == 2'h0;
2 : TxEndFrm <=#Tp TxByteCnt == 2'h1;
3 : TxEndFrm <=#Tp TxByteCnt == 2'h2;
0 : TxEndFrm <=#Tp TxByteCnt == 2'h3;
default : TxEndFrm <=#Tp 1'b0;
endcase
end
end
// Tx data selection (latching)
always @ (posedge MTxClk or posedge Reset)
begin
if(Reset)
TxData <=#Tp 0;
else
if(TxStartFrm_sync2 & ~TxStartFrm)
case(TxPointerLSB) // synopsys parallel_case
2'h0 : TxData <=#Tp TxData_wb[31:24]; // Big Endian Byte Ordering
2'h1 : TxData <=#Tp TxData_wb[23:16]; // Big Endian Byte Ordering
2'h2 : TxData <=#Tp TxData_wb[15:08]; // Big Endian Byte Ordering
2'h3 : TxData <=#Tp TxData_wb[07:00]; // Big Endian Byte Ordering
endcase
else
if(TxStartFrm & TxUsedData & TxPointerLSB==2'h3)
TxData <=#Tp TxData_wb[31:24]; // Big Endian Byte Ordering
else
if(TxUsedData & Flop)
begin
case(TxByteCnt) // synopsys parallel_case
0 : TxData <=#Tp TxDataLatched[31:24]; // Big Endian Byte Ordering
1 : TxData <=#Tp TxDataLatched[23:16];
2 : TxData <=#Tp TxDataLatched[15:8];
3 : TxData <=#Tp TxDataLatched[7:0];
endcase
end
end
// Latching tx data
always @ (posedge MTxClk or posedge Reset)
begin
if(Reset)
TxDataLatched[31:0] <=#Tp 32'h0;
else
if(TxStartFrm_sync2 & ~TxStartFrm | TxUsedData & Flop & TxByteCnt == 2'h3 | TxStartFrm & TxUsedData & Flop & TxByteCnt == 2'h0)
TxDataLatched[31:0] <=#Tp TxData_wb[31:0];
end
// Tx under run
always @ (posedge WB_CLK_I or posedge Reset)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -