📄 pl4_lite_data_monitor.v
字号:
RCtlData[RDatDataIndex] <= #`TFF RCtl;
RDatDataIndex <= #`TFF RDatDataIndexPlus1;
end
end // RCtl == 1
end // Reset_n == 1
end // interprete_rdat
//******************************************************************************
// check_rdat_sop
//******************************************************************************
// Check RDat SOP spacing to ensure it meets minimum requirements
//******************************************************************************
always @(RDClk or negedge Reset_n)
begin: check_rdat_sop
if (!Reset_n)
SopCnt <= #`TFF 'b0;
else
begin
// If the current input is a data word, increment the inter-SOP count
if (RCtl == 1'b0)
begin
if (SopCnt < 7)
SopCnt <= #`TFF SopCnt + 1;
else
SopCnt <= #`TFF 'd7;
end
// Otherwise it's a control word
else // RCtl == 1
begin
// If the control word is an SOP, check for SOP spacing violation
if (RDat[12] == 1)
begin
if (SopCnt < 7)
$display("RDat Warning: Protocol Violation #9. Minumum SOP Spacing not met. %0d ps", $time);
SopCnt <= #`TFF 'b0;
end
// Otherwise it's not an SOP, so increment the inter-SOP count
else
if (SopCnt < 7)
SopCnt <= #`TFF SopCnt + 1;
else
SopCnt <= #`TFF 'd7;
end
end
end // Check RDat SOP
//******************************************************************************
// check_rdat_credit
//******************************************************************************
// Check RDat for credit boundaries
//******************************************************************************
always @(RDClk or negedge Reset_n)
begin: check_rdat_credit
if (!Reset_n)
begin
CreditBoundaryLast <= #`TFF 1'b1;
CreditBoundary <= #`TFF 1'b1;
CreditCnt <= #`TFF 'b0;
BurstCnt <= #`TFF 'b0;
end
else
begin
// If Training or idle data do not update CreditBoundaryLast
if (((InTraining == 1) && (RCtl == 1'b0)) ||
((RCtl == 1'b1) && (RDat == `TRAINING_CTL)) ||
((RCtl == 1'b1) && (RDat[15:4] == 12'h000)));
// do nothing for training or idle
// Otherwise update CreditBoundaryLast
else
CreditBoundaryLast <= #`TFF CreditBoundary;
// If it is payload control reset the burst count. Also if there is a data
// word preceded by a non-payload control word then reset BurstCnt. If there
// is a credit boundary then increment burst count. Otherwise it is the same
if (((RCtl == 1) && (RDat[15] == 1)) ||
((RCtl == 0) && ((RCtlData[RDatDataIndexMinus1] == 1) &&
(RDatData[RDatDataIndexMinus1][15] == 0))))
BurstCnt <= #`TFF 'b0;
else
if (CreditCnt == 7)
BurstCnt <= #`TFF (BurstCnt + 1) % 64;
else if (BurstCnt >= SrcBurstLen)
BurstCnt <= #`TFF 'b0;
else
BurstCnt <= #`TFF BurstCnt;
// If an EOP control word
if ((RCtl == 1) && (RDat[14:13] != 2'b00))
begin
CreditCnt <= #`TFF 'b0;
CreditBoundary <= #`TFF 1'b1;
end
// If it is a non-EOP control word set CreditCnt to zero and do not
// increment
else if (RCtl == 1)
begin
CreditCnt <= #`TFF 'b0;
CreditBoundary <= #`TFF 1'b0;
end
// If it is a data word check to see if it is on a credit boundary
else if (CreditCnt == 6)
begin
CreditCnt <= #`TFF CreditCnt + 1'b1;
CreditBoundary <= #`TFF 1'b1;
end
// Increment (and roll over) CreditCnt and clear CreditBoundary
else
begin
CreditBoundary <= #`TFF 1'b0;
CreditCnt <= #`TFF (CreditCnt + 1'b1) % 8;
end
end
end // Check RDat Credit
//******************************************************************************
// check_rdat_training
//******************************************************************************
// Check RDat for training. If training is being sent, set InTraining
//******************************************************************************
always @(RDClk or negedge Reset_n)
begin: check_rdat_training
if (!Reset_n)
begin
TrainingCnt <= #`TFF 'b0;
InTraining <= #`TFF 1'b0;
end
else
begin
// if it is a training control word
if ((RCtl == 1'b1) && (RDat == `TRAINING_CTL))
begin
InTraining <= #`TFF 1'b1;
RDatTrainPatterns <= #`TFF RDatTrainPatterns;
end
// if it is a non training control word
else if ((RCtl == 1'b1) && (RDat != `TRAINING_CTL))
begin
InTraining <= #`TFF 1'b0;
RDatTrainPatterns <= #`TFF 'b0;
end
// if it is a training data word
else if ((RDat == ~`TRAINING_CTL) && (InTraining == 1'b1))
begin
InTraining <= #`TFF 1'b1;
// If there has been 10 training words reset word counter and
// increment pattern counter
if (TrainingCnt == 4'd9)
begin
TrainingCnt <= #`TFF 'b0;
RDatTrainPatterns <= #`TFF (RDatTrainPatterns + 1) % 256;
end
// Otherwise just increment the word counter
else
begin
TrainingCnt <= #`TFF (TrainingCnt + 1) % 16;
RDatTrainPatterns <= #`TFF RDatTrainPatterns;
end
end
// IF it is non-training data word then reset counters
else
begin
InTraining <= #`TFF 1'b0;
RDatTrainPatterns <= #`TFF 'b0;
end
end
end // Check RDat Training
//******************************************************************************
// create_srcinframe
//******************************************************************************
// Create the SrcInFrame signal. This signal is used by the Control Module
// to know when to stop sending framing and begin sending valid status.
// This occurs after DATA_NUM_TRAIN_SEQ number of training patterns have
// been received
//******************************************************************************
always @(TDClk_align or negedge Reset_n)
begin: create_srcinframe
if (!Reset_n)
SrcInFrame <= #`TFF 1'b0;
// If the source went out of frame then set SrcInFrame to zero
else if (SrcOofPulse == 1)
SrcInFrame <= #`TFF 1'b0;
else
begin
// If there have been more then NumTrainSequences number of training
// patterns then set SrcInFrame to one
if (TDatTrainPatterns >= NumTrainSequences)
SrcInFrame <= #`TFF 1'b1;
else
SrcInFrame <= #`TFF SrcInFrame;
end
end
//******************************************************************************
// check_srcoof
//******************************************************************************
// Check the SrcOof signal for a rising edge. If there is one then pulse
// SrcOofPulse
//******************************************************************************
always @(RDClk or negedge Reset_n)
begin: check_srcoof
if (!Reset_n)
begin
SrcOofPulse <= #`TFF 1'b0;
SrcOofLast <= #`TFF 1'b1;
end
else
begin
SrcOofLast <= #`TFF SrcOof;
if ((SrcOof == 1) && (SrcOofLast == 0))
SrcOofPulse <= #`TFF 1'b1;
else
SrcOofPulse <= #`TFF 1'b0;
end
end
//******************************************************************************
// interperete_tdat
//******************************************************************************
// This process reads incoming data from TDat and compares it with what was
// read in from RDat. It splits any merged control words into an EOP and
// SOP part.
//******************************************************************************
always @(TDClk_align or negedge Reset_n or negedge TDatResetComplete)
begin: interperete_tdat
if (!Reset_n || !TDatResetComplete)
begin
TDatDataIndex <= #`TFF 'b0;
TDatFirst <= #`TFF 1'b0;
end
else
begin
// If TDat is training or idle or OSERDES reset is not complete,
// ignore it.
if ( ((TDatTraining == 1) && (TCtl == 1'b0)) ||
((TCtl == 1'b1) && (TDat == `TRAINING_CTL)) ||
((TDat[15:4] == 12'h000) && (TCtl == 1)) ||
(TDatResetComplete == 'b0) );
// do nothing
// Non-training & non-idle
else
begin
TDatFirst <= #`TFF 1'b1;
// If the Control words are not equal then print and Error flag
if (RCtlData[TDatDataIndex] != TCtl)
begin
// If there is a payload control on source and not on sink, and
// SrcBurstMode = 0 then print a warning to say that the source is
// segmenting bursts. If SrcBurstMode = 1 then print error.
if ((SrcBurstMode == 0) && (TCtl == 1) && (TDat[15:12] == 4'b1000))
$display("TDat Warning: Source is segmenting packets. %0d ps", $time);
else
begin
$display("TCtl Error: Control Mismatch: Expected: %h, Received %h. %0d ps", RCtlData[TDatDataIndex], TCtl, $time);
TDatDataIndex <= #`TFF (TDatDataIndex + 1'b1) % `STORAGE_SIZE;
end
end
// If it is a control word check to see if it needs to be split into
// two
else if (TCtl == 1)
begin
// If the control word contains EOP and PC data then split it into
// two words and compare them seperately with RDat
if ((TDat[14:13] != 0) && ((TDat[15] != 0) || (TDat[12:4] != 0)))
begin
TDatDataIndex <= #`TFF (TDatDataIndex + 2'd2) % `STORAGE_SIZE;
// Compare first half (EOP)
if (RDatData[TDatDataIndex][15:4] == {1'b0, TDat[14:13], 9'b0});
// If it matches, do nothing
// If it doesn't match, flag an error
else
$display("TDat Error: Data Mismatch #1. Expected %h, Received %h. %0d ps", RDatData[TDatDataIndex][15:4], {1'b0, TDat[14:13], 9'b0}, $time);
// Compare second half (payload control/SOP)
if (RDatData[(TDatDataIndex + 1'b1) % `STORAGE_SIZE][15:4] ==
{TDat[15], 2'b00, TDat[12:4]});
// If it matches, do nothing
// If it doesn't match, flag an error
else
$display("TDat Error: Data Mismatch #2. Expected %h, Received %h. %0d ps", RDatData[(TDatDataIndex + 1'b1) % `STORAGE_SIZE][15:4], {TDat[15], 2'b00, TDat[12:4]}, $time);
end
// If the control word only contains EOP or PC then compare it with
// RDat
else
begin
TDatDataIndex <= #`TFF (TDatDataIndex + 1'b1) % `STORAGE_SIZE;
// If the control word matches
if (RDatData[TDatDataIndex][15:4] == TDat[15:4]);
// do nothing
// Control word does not match
else
$display("TDat Error: Data Mismatch #3. Expected %h, Received %h. %0d ps", RDatData[TDatDataIndex][15:4], TDat[15:4], $time);
end
end // TCtl == 1
// If it was a data word then comapre it with RDat
else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -