⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pl4_lite_data_monitor.v

📁 spi接口的vhdl实现
💻 V
📖 第 1 页 / 共 5 页
字号:
        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 + -