📄 eth_wishbonedma.v
字号:
//assign BDDataIn = TxStatusWrite ? {TxLength[15:0], StatusIzTxEthMACModula} : {RxLength, NewRxStatus};
assign BDDataIn = TxStatusWrite ? {TxStatus[31:9], 9'h0}
: {RxLength, NewRxStatus};
assign BDStatusWrite = TxStatusWrite | RxStatusWrite;
// Generating delayed signals
always @ (posedge WB_CLK_I or posedge WB_RST_I)
begin
if(WB_RST_I)
begin
TxRestart_wb_q <=#Tp 1'b0;
TxDone_wb_q <=#Tp 1'b0;
TxAbort_wb_q <=#Tp 1'b0;
BDRead_q <=#Tp 1'b0;
DMACycleFinishedTx_q <=#Tp 1'b0;
end
else
begin
TxRestart_wb_q <=#Tp TxRetry_wb;
TxDone_wb_q <=#Tp TxDone_wb;
TxAbort_wb_q <=#Tp TxAbort_wb;
BDRead_q <=#Tp BDRead;
DMACycleFinishedTx_q <=#Tp DMACycleFinishedTx;
end
end
// Signals used for various purposes
assign TxRestartPulse = TxRetry_wb & ~TxRestart_wb_q;
assign TxDonePulse = TxDone_wb & ~TxDone_wb_q;
assign TxAbortPulse = TxAbort_wb & ~TxAbort_wb_q;
// Next descriptor for Tx DMA channel
always @ (posedge WB_CLK_I or posedge WB_RST_I)
begin
if(WB_RST_I)
WB_ND_O_TX <=#Tp 1'b0;
else
if(TxDonePulse | TxAbortPulse)
WB_ND_O_TX <=#Tp 1'b1;
else
if(WB_ND_O_TX)
WB_ND_O_TX <=#Tp 1'b0;
end
// Force next descriptor on DMA channel 0 (Tx)
assign WB_ND_O[0] = WB_ND_O_TX;
// Restart descriptor for DMA channel 0 (Tx)
always @ (posedge WB_CLK_I or posedge WB_RST_I)
begin
if(WB_RST_I)
WB_RD_O <=#Tp 1'b0;
else
if(TxRestartPulse)
WB_RD_O <=#Tp 1'b1;
else
if(WB_RD_O)
WB_RD_O <=#Tp 1'b0;
end
assign SetClearTxBDReady = ~TxUsedData & TxUsedData_q;
assign ResetClearTxBDReady = ClearTxBDReady | WB_RST_I;
always @ (posedge SetClearTxBDReady or posedge ResetClearTxBDReady)
begin
if(ResetClearTxBDReady)
ClearTxBDReadySync1 <=#Tp 1'b0;
else
ClearTxBDReadySync1 <=#Tp 1'b1;
end
always @ (posedge WB_CLK_I or posedge WB_RST_I)
begin
if(WB_RST_I)
ClearTxBDReadySync2 <=#Tp 1'b0;
else
if(ClearTxBDReadySync1 & ~ClearTxBDReady)
ClearTxBDReadySync2 <=#Tp 1'b1;
else
ClearTxBDReadySync2 <=#Tp 1'b0;
end
always @ (posedge WB_CLK_I or posedge WB_RST_I)
begin
if(WB_RST_I)
ClearTxBDReady <=#Tp 1'b0;
else
if(ClearTxBDReadySync2 & ~ClearTxBDReady)
ClearTxBDReady <=#Tp 1'b1;
else
ClearTxBDReady <=#Tp 1'b0;
end
// Latching and synchronizing the Tx pause request signal
eth_sync_clk1_clk2 syn1 (.clk1(MTxClk), .clk2(WB_CLK_I), .reset1(WB_RST_I), .reset2(WB_RST_I),
.set2(TxPauseRq), .sync_out(TPauseRqSync2)
);
always @ (posedge MTxClk or posedge WB_RST_I)
begin
if(WB_RST_I)
TPauseRq <=#Tp 1'b0;
else
if(TPauseRq )
TPauseRq <=#Tp 1'b0;
else
if(TPauseRqSync2)
TPauseRq <=#Tp 1'b1;
end
// Generating delayed signals
always @ (posedge MTxClk or posedge WB_RST_I)
begin
if(WB_RST_I)
begin
TxAbort_q <=#Tp 1'b0;
TxDone_q <=#Tp 1'b0;
TxRetry_q <=#Tp 1'b0;
TxUsedData_q <=#Tp 1'b0;
end
else
begin
TxAbort_q <=#Tp TxAbort;
TxDone_q <=#Tp TxDone;
TxRetry_q <=#Tp TxRetry;
TxUsedData_q <=#Tp TxUsedData;
end
end
// Sinchronizing and evaluating tx data
assign SetGotData = (TxStartFrm_wb | NewTxDataAvaliable_wb & ~TxAbort_wb & ~TxRetry_wb) & ~WB_CLK_I;
eth_sync_clk1_clk2 syn2 (.clk1(MTxClk), .clk2(WB_CLK_I), .reset1(WB_RST_I), .reset2(WB_RST_I),
.set2(SetGotData), .sync_out(GotDataSync3));
// Evaluating data. If abort or retry occured meanwhile than data is ignored.
assign GotDataEvaluate = GotDataSync3 & ~GotData & (~TxRetry & ~TxAbort | (TxRetry | TxAbort) & (TxStartFrmRequest | TxStartFrm));
// Indication of good data
always @ (posedge MTxClk or posedge WB_RST_I)
begin
if(WB_RST_I)
GotData <=#Tp 1'b0;
else
if(GotDataEvaluate)
GotData <=#Tp 1'b1;
else
GotData <=#Tp 1'b0;
end
// Tx start frame generation
always @ (posedge MTxClk or posedge WB_RST_I)
begin
if(WB_RST_I)
TxStartFrm <=#Tp 1'b0;
else
if(TxUsedData_q | TxAbort & ~TxAbort_q | TxRetry & ~TxRetry_q)
TxStartFrm <=#Tp 1'b0;
else
if(TxBDReady & GotData & TxStartFrmRequest)
TxStartFrm <=#Tp 1'b1;
end
// Indication of the last word
always @ (posedge MTxClk or posedge WB_RST_I)
begin
if(WB_RST_I)
LastWord <=#Tp 1'b0;
else
if((TxEndFrm | TxAbort | TxRetry) & Flop)
LastWord <=#Tp 1'b0;
else
if(TxUsedData & Flop & TxByteCnt == 2'h3)
LastWord <=#Tp TxEndFrm_wbLatched;
end
// Tx end frame generation
always @ (posedge MTxClk or posedge WB_RST_I)
begin
if(WB_RST_I)
TxEndFrm <=#Tp 1'b0;
else
if(Flop & TxEndFrm | TxAbort | TxRetry_q)
TxEndFrm <=#Tp 1'b0;
else
if(Flop & LastWord)
begin
case (TxValidBytesLatched)
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 WB_RST_I)
begin
if(WB_RST_I)
TxData <=#Tp 8'h0;
else
if(GotData & ~TxStartFrm & ~TxUsedData)
TxData <=#Tp TxDataLatched_wb[7:0];
else
if(TxUsedData & Flop)
begin
case(TxByteCnt)
0 : TxData <=#Tp TxDataLatched[7:0];
1 : TxData <=#Tp TxDataLatched[15:8];
2 : TxData <=#Tp TxDataLatched[23:16];
3 : TxData <=#Tp TxDataLatched[31:24];
endcase
end
end
// Latching tx data
always @ (posedge MTxClk or posedge WB_RST_I)
begin
if(WB_RST_I)
TxDataLatched[31:0] <=#Tp 32'h0;
else
if(GotData & ~TxUsedData & ~TxStartFrm)
TxDataLatched[31:0] <=#Tp TxDataLatched_wb[31:0];
else
if(TxUsedData & Flop & TxByteCnt == 2'h3)
TxDataLatched[31:0] <=#Tp TxDataLatched_wb[31:0];
end
// Generation of the DataNotAvaliable signal which is used for the generation of the TxUnderRun signal
assign ResetDataNotAvaliable = DMACycleFinishedTx_q | WB_RST_I;
assign SetDataNotAvaliable = GotData & ~TxUsedData & ~TxStartFrm | TxUsedData & Flop & TxByteCnt == 2'h3;
always @ (posedge MTxClk or posedge ResetDataNotAvaliable)
begin
if(ResetDataNotAvaliable)
DataNotAvaliable <=#Tp 1'b0;
else
if(SetDataNotAvaliable) // data is latched here
DataNotAvaliable <=#Tp 1'b1;
end
// Tx under run
always @ (posedge MTxClk or posedge WB_RST_I)
begin
if(WB_RST_I)
TxUnderRun <=#Tp 1'b0;
else
if(TxAbort & ~TxAbort_q)
TxUnderRun <=#Tp 1'b0;
else
if(TxUsedData & Flop & TxByteCnt == 2'h3 & ~LastWord & DataNotAvaliable)
TxUnderRun <=#Tp 1'b1;
end
// Tx Byte counter
always @ (posedge MTxClk or posedge WB_RST_I)
begin
if(WB_RST_I)
TxByteCnt <=#Tp 2'h0;
else
if(TxAbort_q | TxRetry_q)
TxByteCnt <=#Tp 2'h0;
else
if(TxStartFrm & ~TxUsedData)
TxByteCnt <=#Tp 2'h1;
else
if(TxUsedData & Flop)
TxByteCnt <=#Tp TxByteCnt + 1;
end
// Generation of the GetNewTxData signal
always @ (posedge MTxClk or posedge WB_RST_I)
begin
if(WB_RST_I)
GetNewTxData <=#Tp 1'b0;
else
if(GetNewTxData)
GetNewTxData <=#Tp 1'b0;
else
if(TxBDReady & GotData & ~(TxStartFrm | TxUsedData))
GetNewTxData <=#Tp 1'b1;
else
if(TxUsedData & ~TxEndFrm_wbLatched & TxByteCnt == 2'h3)
GetNewTxData <=#Tp ~LastWord;
end
// TxRetryLatched
always @ (posedge MTxClk or posedge WB_RST_I)
begin
if(WB_RST_I)
TxRetryLatched <=#Tp 1'b0;
else
if(TxStartFrm)
TxRetryLatched <=#Tp 1'b0;
else
if(TxRetry)
TxRetryLatched <=#Tp 1'b1;
end
// Synchronizing request for a new tx data
//ne eth_sync_clk1_clk2 syn3 (.clk1(MTxClk), .clk2(WB_CLK_I), .reset1(WB_RST_I), .reset2(WB_RST_I),
// .set2(SetGotData), .sync_out(GotDataSync3));
// This section still needs to be changed due to ASIC demands
assign ResetSyncGetNewTxData_wb = SyncGetNewTxData_wb3 | TxAbort_wb | TxRetry_wb | WB_RST_I;
assign SetSyncGetNewTxData_wb = GetNewTxData;
// Sync. stage 1
always @ (posedge SetSyncGetNewTxData_wb or posedge ResetSyncGetNewTxData_wb)
begin
if(ResetSyncGetNewTxData_wb)
SyncGetNewTxData_wb1 <=#Tp 1'b0;
else
SyncGetNewTxData_wb1 <=#Tp 1'b1;
end
// Sync. stage 2
always @ (posedge WB_CLK_I or posedge WB_RST_I)
begin
if(WB_RST_I)
SyncGetNewTxData_wb2 <=#Tp 1'b0;
else
if(SyncGetNewTxData_wb1 & ~GetNewTxData_wb & ~TxAbort_wb & ~TxRetry_wb)
SyncGetNewTxData_wb2 <=#Tp 1'b1;
else
SyncGetNewTxData_wb2 <=#Tp 1'b0;
end
// Sync. stage 3
always @ (posedge WB_CLK_I or posedge WB_RST_I)
begin
if(WB_RST_I)
SyncGetNewTxData_wb3 <=#Tp 1'b0;
else
if(SyncGetNewTxData_wb2 & ~GetNewTxData_wb & ~TxAbort_wb & ~TxRetry_wb)
SyncGetNewTxData_wb3 <=#Tp 1'b1;
else
SyncGetNewTxData_wb3 <=#Tp 1'b0;
end
// Synchronized request for a new tx data
always @ (posedge WB_CLK_I or posedge WB_RST_I)
begin
if(WB_RST_I)
GetNewTxData_wb <=#Tp 1'b0;
else
if(GetNewTxData_wb)
GetNewTxData_wb <=#Tp 1'b0;
else
if(SyncGetNewTxData_wb3 & ~GetNewTxData_wb & ~TxAbort_wb & ~TxRetry_wb)
GetNewTxData_wb <=#Tp 1'b1;
end
// Synchronizine transmit done signal
// Sinchronizing and evaluating tx data
eth_sync_clk1_clk2 syn4 (.clk1(WB_CLK_I), .clk2(MTxClk), .reset1(WB_RST_I), .reset2(WB_RST_I),
.set2(TxDone), .sync_out(TxDoneSync3)
);
// Syncronized signal TxDone_wb (sync. to WISHBONE clock)
always @ (posedge WB_CLK_I or posedge WB_RST_I)
begin
if(WB_RST_I)
TxDone_wb <=#Tp 1'b0;
else
if(TxStartFrm_wb | WillSendControlFrame)
TxDone_wb <=#Tp 1'b0;
else
if(TxDoneSync3 & ~TxStartFrmRequest)
TxDone_wb <=#Tp 1'b1;
end
assign ResetTxCtrlEndFrm_wb = TxCtrlEndFrm_wb | WB_RST_I;
assign SetTxCtrlEndFrm_wb = TxCtrlEndFrm;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -