📄 eth_wishbone.v
字号:
begin
if(Reset)
TxUnderRun_wb <=#Tp 1'b0;
else
if(TxAbortPulse)
TxUnderRun_wb <=#Tp 1'b0;
else
if(TxBufferEmpty & ReadTxDataFromFifo_wb)
TxUnderRun_wb <=#Tp 1'b1;
end
reg TxUnderRun_sync1;
// Tx under run
always @ (posedge MTxClk or posedge Reset)
begin
if(Reset)
TxUnderRun_sync1 <=#Tp 1'b0;
else
if(TxUnderRun_wb)
TxUnderRun_sync1 <=#Tp 1'b1;
else
if(BlockingTxStatusWrite_sync2)
TxUnderRun_sync1 <=#Tp 1'b0;
end
// Tx under run
always @ (posedge MTxClk or posedge Reset)
begin
if(Reset)
TxUnderRun <=#Tp 1'b0;
else
if(BlockingTxStatusWrite_sync2)
TxUnderRun <=#Tp 1'b0;
else
if(TxUnderRun_sync1)
TxUnderRun <=#Tp 1'b1;
end
// Tx Byte counter
always @ (posedge MTxClk or posedge Reset)
begin
if(Reset)
TxByteCnt <=#Tp 2'h0;
else
if(TxAbort_q | TxRetry_q)
TxByteCnt <=#Tp 2'h0;
else
if(TxStartFrm & ~TxUsedData)
case(TxPointerLSB) // synopsys parallel_case
2'h0 : TxByteCnt <=#Tp 2'h1;
2'h1 : TxByteCnt <=#Tp 2'h2;
2'h2 : TxByteCnt <=#Tp 2'h3;
2'h3 : TxByteCnt <=#Tp 2'h0;
endcase
else
if(TxUsedData & Flop)
TxByteCnt <=#Tp TxByteCnt + 1'b1;
end
// Start: Generation of the ReadTxDataFromFifo_tck signal and synchronization to the WB_CLK_I
reg ReadTxDataFromFifo_sync1;
reg ReadTxDataFromFifo_sync2;
reg ReadTxDataFromFifo_sync3;
reg ReadTxDataFromFifo_syncb1;
reg ReadTxDataFromFifo_syncb2;
reg ReadTxDataFromFifo_syncb3;
always @ (posedge MTxClk or posedge Reset)
begin
if(Reset)
ReadTxDataFromFifo_tck <=#Tp 1'b0;
else
if(TxStartFrm_sync2 & ~TxStartFrm | TxUsedData & Flop & TxByteCnt == 2'h3 & ~LastWord | TxStartFrm & TxUsedData & Flop & TxByteCnt == 2'h0)
ReadTxDataFromFifo_tck <=#Tp 1'b1;
else
if(ReadTxDataFromFifo_syncb2 & ~ReadTxDataFromFifo_syncb3)
ReadTxDataFromFifo_tck <=#Tp 1'b0;
end
// Synchronizing TxStartFrm_wb to MTxClk
always @ (posedge WB_CLK_I or posedge Reset)
begin
if(Reset)
ReadTxDataFromFifo_sync1 <=#Tp 1'b0;
else
ReadTxDataFromFifo_sync1 <=#Tp ReadTxDataFromFifo_tck;
end
always @ (posedge WB_CLK_I or posedge Reset)
begin
if(Reset)
ReadTxDataFromFifo_sync2 <=#Tp 1'b0;
else
ReadTxDataFromFifo_sync2 <=#Tp ReadTxDataFromFifo_sync1;
end
always @ (posedge MTxClk or posedge Reset)
begin
if(Reset)
ReadTxDataFromFifo_syncb1 <=#Tp 1'b0;
else
ReadTxDataFromFifo_syncb1 <=#Tp ReadTxDataFromFifo_sync2;
end
always @ (posedge MTxClk or posedge Reset)
begin
if(Reset)
ReadTxDataFromFifo_syncb2 <=#Tp 1'b0;
else
ReadTxDataFromFifo_syncb2 <=#Tp ReadTxDataFromFifo_syncb1;
end
always @ (posedge MTxClk or posedge Reset)
begin
if(Reset)
ReadTxDataFromFifo_syncb3 <=#Tp 1'b0;
else
ReadTxDataFromFifo_syncb3 <=#Tp ReadTxDataFromFifo_syncb2;
end
always @ (posedge WB_CLK_I or posedge Reset)
begin
if(Reset)
ReadTxDataFromFifo_sync3 <=#Tp 1'b0;
else
ReadTxDataFromFifo_sync3 <=#Tp ReadTxDataFromFifo_sync2;
end
assign ReadTxDataFromFifo_wb = ReadTxDataFromFifo_sync2 & ~ReadTxDataFromFifo_sync3;
// End: Generation of the ReadTxDataFromFifo_tck signal and synchronization to the WB_CLK_I
// Synchronizing TxRetry signal (synchronized to WISHBONE clock)
always @ (posedge WB_CLK_I or posedge Reset)
begin
if(Reset)
TxRetrySync1 <=#Tp 1'b0;
else
TxRetrySync1 <=#Tp TxRetry;
end
always @ (posedge WB_CLK_I or posedge Reset)
begin
if(Reset)
TxRetry_wb <=#Tp 1'b0;
else
TxRetry_wb <=#Tp TxRetrySync1;
end
// Synchronized TxDone_wb signal (synchronized to WISHBONE clock)
always @ (posedge WB_CLK_I or posedge Reset)
begin
if(Reset)
TxDoneSync1 <=#Tp 1'b0;
else
TxDoneSync1 <=#Tp TxDone;
end
always @ (posedge WB_CLK_I or posedge Reset)
begin
if(Reset)
TxDone_wb <=#Tp 1'b0;
else
TxDone_wb <=#Tp TxDoneSync1;
end
// Synchronizing TxAbort signal (synchronized to WISHBONE clock)
always @ (posedge WB_CLK_I or posedge Reset)
begin
if(Reset)
TxAbortSync1 <=#Tp 1'b0;
else
TxAbortSync1 <=#Tp TxAbort;
end
always @ (posedge WB_CLK_I or posedge Reset)
begin
if(Reset)
TxAbort_wb <=#Tp 1'b0;
else
TxAbort_wb <=#Tp TxAbortSync1;
end
reg RxAbortSync1;
reg RxAbortSync2;
reg RxAbortSync3;
reg RxAbortSync4;
reg RxAbortSyncb1;
reg RxAbortSyncb2;
assign StartRxBDRead = RxStatusWrite | RxAbortSync3 & ~RxAbortSync4;
// Reading the Rx buffer descriptor
always @ (posedge WB_CLK_I or posedge Reset)
begin
if(Reset)
RxBDRead <=#Tp 1'b1;
else
if(StartRxBDRead & ~RxReady)
RxBDRead <=#Tp 1'b1;
else
if(RxBDReady)
RxBDRead <=#Tp 1'b0;
end
// Reading of the next receive buffer descriptor starts after reception status is
// written to the previous one.
// Latching READY status of the Rx buffer descriptor
always @ (posedge WB_CLK_I or posedge Reset)
begin
if(Reset)
RxBDReady <=#Tp 1'b0;
else
if(RxPointerRead)
RxBDReady <=#Tp 1'b0;
else
if(RxEn & RxEn_q & RxBDRead)
RxBDReady <=#Tp ram_do[15]; // RxBDReady is sampled only once at the beginning
end
// Latching Rx buffer descriptor status
// Data is avaliable one cycle after the access is started (at that time signal RxEn is not active)
always @ (posedge WB_CLK_I or posedge Reset)
begin
if(Reset)
RxStatus <=#Tp 2'h0;
else
if(RxEn & RxEn_q & RxBDRead)
RxStatus <=#Tp ram_do[14:13];
end
// RxReady generation
always @ (posedge WB_CLK_I or posedge Reset)
begin
if(Reset)
RxReady <=#Tp 1'b0;
else
if(ShiftEnded | RxAbortSync2 & ~RxAbortSync3)
RxReady <=#Tp 1'b0;
else
if(RxEn & RxEn_q & RxPointerRead)
RxReady <=#Tp 1'b1;
end
// Reading Rx BD pointer
assign StartRxPointerRead = RxBDRead & RxBDReady;
// Reading Tx BD Pointer
always @ (posedge WB_CLK_I or posedge Reset)
begin
if(Reset)
RxPointerRead <=#Tp 1'b0;
else
if(StartRxPointerRead)
RxPointerRead <=#Tp 1'b1;
else
if(RxEn & RxEn_q)
RxPointerRead <=#Tp 1'b0;
end
//Latching Rx buffer pointer from buffer descriptor;
always @ (posedge WB_CLK_I or posedge Reset)
begin
if(Reset)
RxPointerMSB <=#Tp 30'h0;
else
if(RxEn & RxEn_q & RxPointerRead)
RxPointerMSB <=#Tp ram_do[31:2];
else
if(MasterWbRX & m_wb_ack_i)
RxPointerMSB <=#Tp RxPointerMSB + 1; // Word access (always word access. m_wb_sel_o are used for selecting bytes)
end
//Latching last addresses from buffer descriptor (used as byte-half-word indicator);
always @ (posedge WB_CLK_I or posedge Reset)
begin
if(Reset)
RxPointerLSB_rst[1:0] <=#Tp 0;
else
if(MasterWbRX & m_wb_ack_i) // After first write all RxByteSel are active
RxPointerLSB_rst[1:0] <=#Tp 0;
else
if(RxEn & RxEn_q & RxPointerRead)
RxPointerLSB_rst[1:0] <=#Tp ram_do[1:0];
end
always @ (RxPointerLSB_rst)
begin
case(RxPointerLSB_rst[1:0]) // synopsys parallel_case
2'h0 : RxByteSel[3:0] = 4'hf;
2'h1 : RxByteSel[3:0] = 4'h7;
2'h2 : RxByteSel[3:0] = 4'h3;
2'h3 : RxByteSel[3:0] = 4'h1;
endcase
end
always @ (posedge WB_CLK_I or posedge Reset)
begin
if(Reset)
RxEn_needed <=#Tp 1'b0;
else
if(~RxReady & r_RxEn & WbEn & ~WbEn_q)
RxEn_needed <=#Tp 1'b1;
else
if(RxPointerRead & RxEn & RxEn_q)
RxEn_needed <=#Tp 1'b0;
end
// Reception status is written back to the buffer descriptor after the end of frame is detected.
assign RxStatusWrite = ShiftEnded & RxEn & RxEn_q;
reg RxEnableWindow;
// Indicating that last byte is being reveived
always @ (posedge MRxClk or posedge Reset)
begin
if(Reset)
LastByteIn <=#Tp 1'b0;
else
if(ShiftWillEnd & (&RxByteCnt) | RxAbort)
LastByteIn <=#Tp 1'b0;
else
if(RxValid & RxReady & RxEndFrm & ~(&RxByteCnt) & RxEnableWindow)
LastByteIn <=#Tp 1'b1;
end
reg ShiftEnded_rck;
reg ShiftEndedSync1;
reg ShiftEndedSync2;
reg ShiftEndedSync3;
reg ShiftEndedSync_c1;
reg ShiftEndedSync_c2;
wire StartShiftWillEnd;
assign StartShiftWillEnd = LastByteIn | RxValid & RxEndFrm & (&RxByteCnt) & RxEnableWindow;
// Indicating that data reception will end
always @ (posedge MRxClk or posedge Reset)
begin
if(Reset)
ShiftWillEnd <=#Tp 1'b0;
else
if(ShiftEnded_rck | RxAbort)
ShiftWillEnd <=#Tp 1'b0;
else
if(StartShiftWillEnd)
ShiftWillEnd <=#Tp 1'b1;
end
// Receive byte counter
always @ (posedge MRxClk or posedge Reset)
begin
if(Reset)
RxByteCnt <=#Tp 2'h0;
else
if(ShiftEnded_rck | RxAbort)
RxByteCnt <=#Tp 2'h0;
else
if(RxValid & RxStartFrm & RxReady)
case(RxPointerLSB_rst) // synopsys parallel_case
2'h0 : RxByteCnt <=#Tp 2'h1;
2'h1 : RxByteCnt <=#Tp 2'h2;
2'h2 : RxByteCnt <=#Tp 2'h3;
2'h3 : RxByteCnt <=#Tp 2'h0;
endcase
else
if(RxValid & RxEnableWindow & RxReady | LastByteIn)
RxByteCnt <=#Tp RxByteCnt + 1'b1;
end
// Indicates how many bytes are valid within the last word
always @ (posedge MRxClk or posedge Reset)
begin
if(Reset)
RxValidBytes <=#Tp 2'h1;
else
if(RxValid & RxStartFrm)
case(RxPointerLSB_rst) // synopsys parallel_case
2'h0 : RxValidBytes <=#Tp 2'h1;
2'h1 : RxValidBytes <=#Tp 2'h2;
2'h2 : RxValidBytes <=#Tp 2'h3;
2'h3 : RxValidBytes <=#Tp 2'h0;
endcase
else
if(RxValid & ~LastByteIn & ~RxStartFrm & RxEnableWindow)
RxValidBytes <=#Tp RxValidBytes + 1;
end
always @ (posedge MRxClk or posedge Reset)
begin
if(Reset)
RxDataLatched1 <=#Tp 24'h0;
else
if(RxValid & RxReady & ~LastByteIn)
if(RxStartFrm)
begin
case(RxPointerLSB_rst) // synopsys parallel_case
2'h0: RxDataLatched1[31:24] <=#Tp RxData; // Big Endian Byte Ordering
2'h1: RxDataLatched1[23:16] <=#Tp RxData;
2'h2: RxDataLatched1[15:8] <=#Tp RxData;
2'h3: RxDataLatched1 <=#Tp RxDataLatched1;
endcase
end
else if (RxEnableWindow)
begin
case(RxByteCnt) // synopsys parallel_case
2'h0: RxDataLatched1[31:24] <=#Tp RxData; // Big Endian Byte Ordering
2'h1: RxDataLatched1[23:16] <=#Tp RxData;
2'h2: RxDataLatched1[15:8] <=#Tp RxData;
2'h3: RxDataLatched1 <=#Tp RxDataLatched1;
endcase
end
end
wire SetWriteRxDataToFifo;
// Assembling data that will be written to the rx_fifo
always @ (posedge MRxClk or posedge Reset)
begin
if(Reset)
RxDataLatched2 <=#Tp 32'h0;
else
if(SetWriteRxDataToFifo & ~ShiftWillEnd)
RxDataLatched2 <=#Tp {RxDataLatched1[31:8], RxData}; // Big Endian Byte Ordering
else
if(SetWriteRxDataToFifo & ShiftWillEnd)
case(RxValidBytes) // synopsys parallel_case
0 : RxDataLatched2 <=#Tp {RxDataLatched1[31:8], RxData}; // Big Endian Byte Ordering
1 : RxDataLatched2 <=#Tp {RxDataLatched1[31:24], 24'h0};
2 : RxDataLatched2 <=#Tp {RxDataLatched1[31:16], 16'h0};
3 : RxDataLatched2 <=#Tp {RxDataLatched1[31:8], 8'h0};
endcase
end
reg WriteRxDataToFifoSync1;
reg WriteRxDataToFifoSync2;
reg WriteRxDataToFifoSync3;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -