Line 82... |
Line 82... |
TxAbortIn, TxStartFrmOut, ReceivedLengthOK, ReceivedPacketGood,
|
TxAbortIn, TxStartFrmOut, ReceivedLengthOK, ReceivedPacketGood,
|
TxUsedDataOutDetected, Pause, ReceivedPauseFrm, AddressOK,
|
TxUsedDataOutDetected, Pause, ReceivedPauseFrm, AddressOK,
|
RxStatusWriteLatched_sync2, r_PassAll, SetPauseTimer
|
RxStatusWriteLatched_sync2, r_PassAll, SetPauseTimer
|
);
|
);
|
|
|
parameter Tp = 1;
|
|
|
|
|
|
input MTxClk;
|
input MTxClk;
|
input MRxClk;
|
input MRxClk;
|
input TxReset;
|
input TxReset;
|
input RxReset;
|
input RxReset;
|
Line 163... |
Line 161... |
|
|
// Address Detection (Multicast or unicast)
|
// Address Detection (Multicast or unicast)
|
always @ (posedge MRxClk or posedge RxReset)
|
always @ (posedge MRxClk or posedge RxReset)
|
begin
|
begin
|
if(RxReset)
|
if(RxReset)
|
AddressOK <= #Tp 1'b0;
|
AddressOK <= 1'b0;
|
else
|
else
|
if(DetectionWindow & ByteCntEq0)
|
if(DetectionWindow & ByteCntEq0)
|
AddressOK <= #Tp RxData[7:0] == ReservedMulticast[47:40] | RxData[7:0] == MAC[47:40];
|
AddressOK <= RxData[7:0] == ReservedMulticast[47:40] | RxData[7:0] == MAC[47:40];
|
else
|
else
|
if(DetectionWindow & ByteCntEq1)
|
if(DetectionWindow & ByteCntEq1)
|
AddressOK <= #Tp (RxData[7:0] == ReservedMulticast[39:32] | RxData[7:0] == MAC[39:32]) & AddressOK;
|
AddressOK <= (RxData[7:0] == ReservedMulticast[39:32] | RxData[7:0] == MAC[39:32]) & AddressOK;
|
else
|
else
|
if(DetectionWindow & ByteCntEq2)
|
if(DetectionWindow & ByteCntEq2)
|
AddressOK <= #Tp (RxData[7:0] == ReservedMulticast[31:24] | RxData[7:0] == MAC[31:24]) & AddressOK;
|
AddressOK <= (RxData[7:0] == ReservedMulticast[31:24] | RxData[7:0] == MAC[31:24]) & AddressOK;
|
else
|
else
|
if(DetectionWindow & ByteCntEq3)
|
if(DetectionWindow & ByteCntEq3)
|
AddressOK <= #Tp (RxData[7:0] == ReservedMulticast[23:16] | RxData[7:0] == MAC[23:16]) & AddressOK;
|
AddressOK <= (RxData[7:0] == ReservedMulticast[23:16] | RxData[7:0] == MAC[23:16]) & AddressOK;
|
else
|
else
|
if(DetectionWindow & ByteCntEq4)
|
if(DetectionWindow & ByteCntEq4)
|
AddressOK <= #Tp (RxData[7:0] == ReservedMulticast[15:8] | RxData[7:0] == MAC[15:8]) & AddressOK;
|
AddressOK <= (RxData[7:0] == ReservedMulticast[15:8] | RxData[7:0] == MAC[15:8]) & AddressOK;
|
else
|
else
|
if(DetectionWindow & ByteCntEq5)
|
if(DetectionWindow & ByteCntEq5)
|
AddressOK <= #Tp (RxData[7:0] == ReservedMulticast[7:0] | RxData[7:0] == MAC[7:0]) & AddressOK;
|
AddressOK <= (RxData[7:0] == ReservedMulticast[7:0] | RxData[7:0] == MAC[7:0]) & AddressOK;
|
else
|
else
|
if(ReceiveEnd)
|
if(ReceiveEnd)
|
AddressOK <= #Tp 1'b0;
|
AddressOK <= 1'b0;
|
end
|
end
|
|
|
|
|
|
|
// TypeLengthOK (Type/Length Control frame detected)
|
// TypeLengthOK (Type/Length Control frame detected)
|
always @ (posedge MRxClk or posedge RxReset )
|
always @ (posedge MRxClk or posedge RxReset )
|
begin
|
begin
|
if(RxReset)
|
if(RxReset)
|
TypeLengthOK <= #Tp 1'b0;
|
TypeLengthOK <= 1'b0;
|
else
|
else
|
if(DetectionWindow & ByteCntEq12)
|
if(DetectionWindow & ByteCntEq12)
|
TypeLengthOK <= #Tp ByteCntEq12 & (RxData[7:0] == TypeLength[15:8]);
|
TypeLengthOK <= ByteCntEq12 & (RxData[7:0] == TypeLength[15:8]);
|
else
|
else
|
if(DetectionWindow & ByteCntEq13)
|
if(DetectionWindow & ByteCntEq13)
|
TypeLengthOK <= #Tp ByteCntEq13 & (RxData[7:0] == TypeLength[7:0]) & TypeLengthOK;
|
TypeLengthOK <= ByteCntEq13 & (RxData[7:0] == TypeLength[7:0]) & TypeLengthOK;
|
else
|
else
|
if(ReceiveEnd)
|
if(ReceiveEnd)
|
TypeLengthOK <= #Tp 1'b0;
|
TypeLengthOK <= 1'b0;
|
end
|
end
|
|
|
|
|
|
|
// Latch Control Frame Opcode
|
// Latch Control Frame Opcode
|
always @ (posedge MRxClk or posedge RxReset )
|
always @ (posedge MRxClk or posedge RxReset )
|
begin
|
begin
|
if(RxReset)
|
if(RxReset)
|
OpCodeOK <= #Tp 1'b0;
|
OpCodeOK <= 1'b0;
|
else
|
else
|
if(ByteCntEq16)
|
if(ByteCntEq16)
|
OpCodeOK <= #Tp 1'b0;
|
OpCodeOK <= 1'b0;
|
else
|
else
|
begin
|
begin
|
if(DetectionWindow & ByteCntEq14)
|
if(DetectionWindow & ByteCntEq14)
|
OpCodeOK <= #Tp ByteCntEq14 & RxData[7:0] == 8'h00;
|
OpCodeOK <= ByteCntEq14 & RxData[7:0] == 8'h00;
|
|
|
if(DetectionWindow & ByteCntEq15)
|
if(DetectionWindow & ByteCntEq15)
|
OpCodeOK <= #Tp ByteCntEq15 & RxData[7:0] == 8'h01 & OpCodeOK;
|
OpCodeOK <= ByteCntEq15 & RxData[7:0] == 8'h01 & OpCodeOK;
|
end
|
end
|
end
|
end
|
|
|
|
|
// ReceivedPauseFrmWAddr (+Address Check)
|
// ReceivedPauseFrmWAddr (+Address Check)
|
always @ (posedge MRxClk or posedge RxReset )
|
always @ (posedge MRxClk or posedge RxReset )
|
begin
|
begin
|
if(RxReset)
|
if(RxReset)
|
ReceivedPauseFrmWAddr <= #Tp 1'b0;
|
ReceivedPauseFrmWAddr <= 1'b0;
|
else
|
else
|
if(ReceiveEnd)
|
if(ReceiveEnd)
|
ReceivedPauseFrmWAddr <= #Tp 1'b0;
|
ReceivedPauseFrmWAddr <= 1'b0;
|
else
|
else
|
if(ByteCntEq16 & TypeLengthOK & OpCodeOK & AddressOK)
|
if(ByteCntEq16 & TypeLengthOK & OpCodeOK & AddressOK)
|
ReceivedPauseFrmWAddr <= #Tp 1'b1;
|
ReceivedPauseFrmWAddr <= 1'b1;
|
end
|
end
|
|
|
|
|
|
|
// Assembling 16-bit timer value from two 8-bit data
|
// Assembling 16-bit timer value from two 8-bit data
|
always @ (posedge MRxClk or posedge RxReset )
|
always @ (posedge MRxClk or posedge RxReset )
|
begin
|
begin
|
if(RxReset)
|
if(RxReset)
|
AssembledTimerValue[15:0] <= #Tp 16'h0;
|
AssembledTimerValue[15:0] <= 16'h0;
|
else
|
else
|
if(RxStartFrm)
|
if(RxStartFrm)
|
AssembledTimerValue[15:0] <= #Tp 16'h0;
|
AssembledTimerValue[15:0] <= 16'h0;
|
else
|
else
|
begin
|
begin
|
if(DetectionWindow & ByteCntEq16)
|
if(DetectionWindow & ByteCntEq16)
|
AssembledTimerValue[15:8] <= #Tp RxData[7:0];
|
AssembledTimerValue[15:8] <= RxData[7:0];
|
if(DetectionWindow & ByteCntEq17)
|
if(DetectionWindow & ByteCntEq17)
|
AssembledTimerValue[7:0] <= #Tp RxData[7:0];
|
AssembledTimerValue[7:0] <= RxData[7:0];
|
end
|
end
|
end
|
end
|
|
|
|
|
// Detection window (while PAUSE detection is possible)
|
// Detection window (while PAUSE detection is possible)
|
always @ (posedge MRxClk or posedge RxReset )
|
always @ (posedge MRxClk or posedge RxReset )
|
begin
|
begin
|
if(RxReset)
|
if(RxReset)
|
DetectionWindow <= #Tp 1'b1;
|
DetectionWindow <= 1'b1;
|
else
|
else
|
if(ByteCntEq18)
|
if(ByteCntEq18)
|
DetectionWindow <= #Tp 1'b0;
|
DetectionWindow <= 1'b0;
|
else
|
else
|
if(ReceiveEnd)
|
if(ReceiveEnd)
|
DetectionWindow <= #Tp 1'b1;
|
DetectionWindow <= 1'b1;
|
end
|
end
|
|
|
|
|
|
|
// Latching Timer Value
|
// Latching Timer Value
|
always @ (posedge MRxClk or posedge RxReset )
|
always @ (posedge MRxClk or posedge RxReset )
|
begin
|
begin
|
if(RxReset)
|
if(RxReset)
|
LatchedTimerValue[15:0] <= #Tp 16'h0;
|
LatchedTimerValue[15:0] <= 16'h0;
|
else
|
else
|
if(DetectionWindow & ReceivedPauseFrmWAddr & ByteCntEq18)
|
if(DetectionWindow & ReceivedPauseFrmWAddr & ByteCntEq18)
|
LatchedTimerValue[15:0] <= #Tp AssembledTimerValue[15:0];
|
LatchedTimerValue[15:0] <= AssembledTimerValue[15:0];
|
else
|
else
|
if(ReceiveEnd)
|
if(ReceiveEnd)
|
LatchedTimerValue[15:0] <= #Tp 16'h0;
|
LatchedTimerValue[15:0] <= 16'h0;
|
end
|
end
|
|
|
|
|
|
|
// Delayed CEC counter
|
// Delayed CEC counter
|
always @ (posedge MRxClk or posedge RxReset)
|
always @ (posedge MRxClk or posedge RxReset)
|
begin
|
begin
|
if(RxReset)
|
if(RxReset)
|
DlyCrcCnt <= #Tp 3'h0;
|
DlyCrcCnt <= 3'h0;
|
else
|
else
|
if(RxValid & RxEndFrm)
|
if(RxValid & RxEndFrm)
|
DlyCrcCnt <= #Tp 3'h0;
|
DlyCrcCnt <= 3'h0;
|
else
|
else
|
if(RxValid & ~RxEndFrm & ~DlyCrcCnt[2])
|
if(RxValid & ~RxEndFrm & ~DlyCrcCnt[2])
|
DlyCrcCnt <= #Tp DlyCrcCnt + 1'b1;
|
DlyCrcCnt <= DlyCrcCnt + 1'b1;
|
end
|
end
|
|
|
|
|
assign ResetByteCnt = RxEndFrm;
|
assign ResetByteCnt = RxEndFrm;
|
assign IncrementByteCnt = RxValid & DetectionWindow & ~ByteCntEq18 & (~DlyCrcEn | DlyCrcEn & DlyCrcCnt[2]);
|
assign IncrementByteCnt = RxValid & DetectionWindow & ~ByteCntEq18 & (~DlyCrcEn | DlyCrcEn & DlyCrcCnt[2]);
|
Line 311... |
Line 309... |
|
|
// Byte counter
|
// Byte counter
|
always @ (posedge MRxClk or posedge RxReset)
|
always @ (posedge MRxClk or posedge RxReset)
|
begin
|
begin
|
if(RxReset)
|
if(RxReset)
|
ByteCnt[4:0] <= #Tp 5'h0;
|
ByteCnt[4:0] <= 5'h0;
|
else
|
else
|
if(ResetByteCnt)
|
if(ResetByteCnt)
|
ByteCnt[4:0] <= #Tp 5'h0;
|
ByteCnt[4:0] <= 5'h0;
|
else
|
else
|
if(IncrementByteCnt)
|
if(IncrementByteCnt)
|
ByteCnt[4:0] <= #Tp ByteCnt[4:0] + 1'b1;
|
ByteCnt[4:0] <= ByteCnt[4:0] + 1'b1;
|
end
|
end
|
|
|
|
|
assign ByteCntEq0 = RxValid & ByteCnt[4:0] == 5'h0;
|
assign ByteCntEq0 = RxValid & ByteCnt[4:0] == 5'h0;
|
assign ByteCntEq1 = RxValid & ByteCnt[4:0] == 5'h1;
|
assign ByteCntEq1 = RxValid & ByteCnt[4:0] == 5'h1;
|
Line 344... |
Line 342... |
|
|
// PauseTimer[15:0]
|
// PauseTimer[15:0]
|
always @ (posedge MRxClk or posedge RxReset)
|
always @ (posedge MRxClk or posedge RxReset)
|
begin
|
begin
|
if(RxReset)
|
if(RxReset)
|
PauseTimer[15:0] <= #Tp 16'h0;
|
PauseTimer[15:0] <= 16'h0;
|
else
|
else
|
if(SetPauseTimer)
|
if(SetPauseTimer)
|
PauseTimer[15:0] <= #Tp LatchedTimerValue[15:0];
|
PauseTimer[15:0] <= LatchedTimerValue[15:0];
|
else
|
else
|
if(DecrementPauseTimer)
|
if(DecrementPauseTimer)
|
PauseTimer[15:0] <= #Tp PauseTimer[15:0] - 1'b1;
|
PauseTimer[15:0] <= PauseTimer[15:0] - 1'b1;
|
end
|
end
|
|
|
assign PauseTimerEq0 = ~(|PauseTimer[15:0]);
|
assign PauseTimerEq0 = ~(|PauseTimer[15:0]);
|
|
|
|
|
Line 362... |
Line 360... |
// Synchronization of the pause timer
|
// Synchronization of the pause timer
|
always @ (posedge MTxClk or posedge TxReset)
|
always @ (posedge MTxClk or posedge TxReset)
|
begin
|
begin
|
if(TxReset)
|
if(TxReset)
|
begin
|
begin
|
PauseTimerEq0_sync1 <= #Tp 1'b1;
|
PauseTimerEq0_sync1 <= 1'b1;
|
PauseTimerEq0_sync2 <= #Tp 1'b1;
|
PauseTimerEq0_sync2 <= 1'b1;
|
end
|
end
|
else
|
else
|
begin
|
begin
|
PauseTimerEq0_sync1 <= #Tp PauseTimerEq0;
|
PauseTimerEq0_sync1 <= PauseTimerEq0;
|
PauseTimerEq0_sync2 <= #Tp PauseTimerEq0_sync1;
|
PauseTimerEq0_sync2 <= PauseTimerEq0_sync1;
|
end
|
end
|
end
|
end
|
|
|
|
|
// Pause signal generation
|
// Pause signal generation
|
always @ (posedge MTxClk or posedge TxReset)
|
always @ (posedge MTxClk or posedge TxReset)
|
begin
|
begin
|
if(TxReset)
|
if(TxReset)
|
Pause <= #Tp 1'b0;
|
Pause <= 1'b0;
|
else
|
else
|
if((TxDoneIn | TxAbortIn | ~TxUsedDataOutDetected) & ~TxStartFrmOut)
|
if((TxDoneIn | TxAbortIn | ~TxUsedDataOutDetected) & ~TxStartFrmOut)
|
Pause <= #Tp RxFlow & ~PauseTimerEq0_sync2;
|
Pause <= RxFlow & ~PauseTimerEq0_sync2;
|
end
|
end
|
|
|
|
|
// Divider2 is used for incrementing the Slot timer every other clock
|
// Divider2 is used for incrementing the Slot timer every other clock
|
always @ (posedge MRxClk or posedge RxReset)
|
always @ (posedge MRxClk or posedge RxReset)
|
begin
|
begin
|
if(RxReset)
|
if(RxReset)
|
Divider2 <= #Tp 1'b0;
|
Divider2 <= 1'b0;
|
else
|
else
|
if(|PauseTimer[15:0] & RxFlow)
|
if(|PauseTimer[15:0] & RxFlow)
|
Divider2 <= #Tp ~Divider2;
|
Divider2 <= ~Divider2;
|
else
|
else
|
Divider2 <= #Tp 1'b0;
|
Divider2 <= 1'b0;
|
end
|
end
|
|
|
|
|
assign ResetSlotTimer = RxReset;
|
assign ResetSlotTimer = RxReset;
|
assign IncrementSlotTimer = Pause & RxFlow & Divider2;
|
assign IncrementSlotTimer = Pause & RxFlow & Divider2;
|
Line 405... |
Line 403... |
|
|
// SlotTimer
|
// SlotTimer
|
always @ (posedge MRxClk or posedge RxReset)
|
always @ (posedge MRxClk or posedge RxReset)
|
begin
|
begin
|
if(RxReset)
|
if(RxReset)
|
SlotTimer[5:0] <= #Tp 6'h0;
|
SlotTimer[5:0] <= 6'h0;
|
else
|
else
|
if(ResetSlotTimer)
|
if(ResetSlotTimer)
|
SlotTimer[5:0] <= #Tp 6'h0;
|
SlotTimer[5:0] <= 6'h0;
|
else
|
else
|
if(IncrementSlotTimer)
|
if(IncrementSlotTimer)
|
SlotTimer[5:0] <= #Tp SlotTimer[5:0] + 1'b1;
|
SlotTimer[5:0] <= SlotTimer[5:0] + 1'b1;
|
end
|
end
|
|
|
|
|
assign SlotFinished = &SlotTimer[5:0] & IncrementSlotTimer; // Slot is 512 bits (64 bytes)
|
assign SlotFinished = &SlotTimer[5:0] & IncrementSlotTimer; // Slot is 512 bits (64 bytes)
|
|
|
Line 423... |
Line 421... |
|
|
// Pause Frame received
|
// Pause Frame received
|
always @ (posedge MRxClk or posedge RxReset)
|
always @ (posedge MRxClk or posedge RxReset)
|
begin
|
begin
|
if(RxReset)
|
if(RxReset)
|
ReceivedPauseFrm <=#Tp 1'b0;
|
ReceivedPauseFrm <= 1'b0;
|
else
|
else
|
if(RxStatusWriteLatched_sync2 & r_PassAll | ReceivedPauseFrm & (~r_PassAll))
|
if(RxStatusWriteLatched_sync2 & r_PassAll | ReceivedPauseFrm & (~r_PassAll))
|
ReceivedPauseFrm <=#Tp 1'b0;
|
ReceivedPauseFrm <= 1'b0;
|
else
|
else
|
if(ByteCntEq16 & TypeLengthOK & OpCodeOK)
|
if(ByteCntEq16 & TypeLengthOK & OpCodeOK)
|
ReceivedPauseFrm <=#Tp 1'b1;
|
ReceivedPauseFrm <= 1'b1;
|
end
|
end
|
|
|
|
|
endmodule
|
endmodule
|
|
|
No newline at end of file
|
No newline at end of file
|