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

📄 pl4_lite_stimulus.v

📁 spi接口的vhdl实现
💻 V
📖 第 1 页 / 共 4 页
字号:
reg         SendTraining;        //Indicates control is sending training
reg         SendingAutoTraining; //Indicates periodic training
reg         SendingUserTraining; //Indicates user-initiated training
reg         SendingUserIdle;     //Indicates user-initiated idle
reg         SentUserIdle;        //Post-indicates user-initiated idle
  
//Signals for DIP-4 calculation
reg  [15:0] DataControlDIP4;     //Data to be outputted with DIP-4 inserted
reg         ControlEnableDIP4;   //Control to be outputted
reg  [17:0] Data_d1;             //Data without the DIP4 inserted
reg         Ctl_d1;              //Control signal used by DIP4 calculation
reg  [15:0] DIP16;               //Dip16 calculation
wire  [3:0] DIP4;                //Dip4 Calculation
reg         Training;            //Indicates in training during DIP4 calc
//Signals for Testcase Status Capture
reg  [1:0]  TCStatArray [NumLinks - 1:0];
reg  [8:0]  TCIndex;
//Signals for DIP-2 calculation
reg  [9:0]  LenCnt;              //Index for position in calendar sequence
reg  [15:0] MCnt;                //Counter for number of repititions of cal.
reg  [1:0]  Dip2;                //Dip2 calculation
reg         FFReadEn;            //Indicates data has been read from the FF
reg         First;

/*****************************************************************************
* Instantiate procedures module
*****************************************************************************/
pl4_lite_procedures tasks (
  .RDat          (RDat),
  .RCtl          (RCtl),
  .RDClk2x       (RDClk2x),
  .SopErr        (),
  .TCDIP4Request (),
  .Stat          (),
  .Chan          (),
  .TSClk         (TSClkIn),
  .FFWriteEn     (),
  .GetStatusChan (),
  .FullVec       (),
  .FFFull        (1'b0),
  .SnkAlmostFull_n  (SnkAlmostFull_n) ,
  .CheckRStat    (CheckRStat),
  .RandomSeed    (RandomSeed)
);

/*****************************************************************************
* Initial Conditions
*****************************************************************************/
initial
  begin
    RDClk_P         = 1'b0;
    RDClk_N         = 1'b1;
    TrainingCnt     = 16'b0;
    SopCnt          = 3'd7;
    CurrentAddress  = 8'h00;
    DataInterrupt   = 16'h0000;
    CreditBoundary  = 1'b1;
    SendTraining    = 1'b0;
    Training        = 1'b0;
    MCnt            = 8'h01;
    Dip2            = 2'b00;
    GetStatus       = 2'b00;
  end

/*****************************************************************************
* Create RDClk
* Divides the RDClk2x clock by 2 to create RDClk
*****************************************************************************/
always @(posedge RDClk2x)
  begin: RDClk_gen
    RDClk_P = !RDClk_P;
    RDClk_N = !RDClk_N;
  end

/*****************************************************************************
* Assign TSClk
*****************************************************************************/
assign TSClk = TSClkIn;

assign SnkDip2ErrRequest = TCSnkDip2ErrRequest;
assign TrainingRequest   = TCTrainingRequest;
assign IdleRequest       = TCIdleRequest;

/*****************************************************************************
* Capture Calendar
* Captures the calendar sequence that is loaded from the file so that the
* control module knows the sequence of the channels.  
*****************************************************************************/
always @(posedge UserClk)
  begin:capture_calendar
    if (!CalWrEn_n)
      CalSeq [CalAddr] <= #`TFF CalData;
    else
      CalSeq [CalAddr] <= #`TFF CalSeq [CalAddr];
  end

/*****************************************************************************
* Generate FIFO flags asynchronously
*****************************************************************************/
always @(Reset_n or TCDatFFTop or TCDatFFBottom)
  begin: fifo_flags
  if (!Reset_n)
    begin
      CtlEmpty      <= 1'b1;
      CtlFull_i     <= 1'b0;
      AlmostEmpty   <= 1'b0;
      AlmostFull    <= 1'b0;
    end
  else
  begin

    // If the write index is one greater than the read index, the FIFO is
    // almost empty
    if (TCDatFFTop == ((TCDatFFBottom + 1) % 1024))
    begin
      CtlEmpty          <= 1'b0;
      CtlFull_i         <= 1'b0;
      AlmostEmpty       <= 1'b1;
      AlmostFull        <= 1'b0;
    end

    // If the read index is one greater than the write index, the FIFO is
    // almost full
    else if (TCDatFFBottom == ((TCDatFFTop + 1) % 1024))
    begin
      CtlEmpty          <= 1'b0;
      CtlFull_i         <= 1'b0;
      AlmostEmpty       <= 1'b0;
      AlmostFull        <= 1'b1;
    end

    // If the write index and read index are equal, the FIFO is either full
    // or empty - determine which one
    else if (TCDatFFBottom == TCDatFFTop)
    begin

      // If AlmostEmpty or CtlEmpty was previously asserted, FIFO is now
      // (still) empty
      if (AlmostEmpty || CtlEmpty)
        begin
          CtlEmpty        <= 1'b1;
          CtlFull_i       <= 1'b0;
          AlmostEmpty     <= 1'b0;
          AlmostFull      <= 1'b0;
        end

      // Otherwise FIFO is now full
      else
        begin
          CtlEmpty        <= 1'b0;
          CtlFull_i       <= 1'b1;
          AlmostEmpty     <= 1'b0;
          AlmostFull      <= 1'b0;
        end
    end

    // If read and write are more than one index apart, deassert all flags
    else
    begin
      CtlEmpty          <= 1'b0;
      CtlFull_i         <= 1'b0;
      AlmostEmpty       <= 1'b0;
      AlmostFull        <= 1'b0;
    end
  end
end

// Assert external CtlFull one clock early to prevent overflow
assign CtlFull = CtlFull_i | AlmostFull;

/*****************************************************************************
* Capture data on TCDat
* Captures the data coming from the testcase module and stores it in 
* TCDatFF.  SOPErr is stored in TCDatFF[x][18], DIP4 Error Request is stored
* in TCDatFF[x][16] and TCDatFF[x][17] is reserved for future use.
*****************************************************************************/
always @(posedge RDClk2x or negedge Reset_n)
begin
  if (!Reset_n)
    begin
      TCDatFFTop        <= #`TFF 1'b0;
      for (i=0; i <= 1023; i = i+1)
      begin
       TCDatFF[i]           <= #`TFF {19{1'b0}};
       TCCtlFF[i]           <= #`TFF {1{1'b0}};
      end
    end
  else 
    begin

      // If the Merge Payload constant is set to 1 then merge the current
      // word with the last one written to the FIFO if:
      // * The last word in written was an EOP w/o Payload Control
      // * The word being written is a Payload Control word w/o any EOP
      //   bits set
      // * The last word written hasn't been read out yet
      // * Neither control word has the DIP4Request bit set
      // If all these conditions are met, merge the two control words into
      // one control word and don't increment the top index.
      if  ((MergePayload) &&
           (FFWriteEn == 1'b1) &&
           (TCCtlFF[TCDatFFTop - 1'b1] == 1'b1) &&
           (TCDatFF[TCDatFFTop - 1'b1][12] == 1'b0) &&
           (TCDatFF[TCDatFFTop - 1'b1][14:13] != 2'b00) &&
           (TCDatFF[TCDatFFTop - 1'b1][15] == 1'b0) &&
           (TCDatFF[TCDatFFTop - 1'b1][16] == 1'b0) &&
           (TCCtl == 1'b1) && 
           (TCDat[14:13] == 2'b00) &&
           (TCDat[15] == 1'b1) &&
           (TCDat[16] == 1'b0) &&
           !((CtlEmpty == 1'b1) ||
	     (AlmostEmpty == 1'b1)))
        begin
          // Replace the top word with the merged control word
          TCDatFF[TCDatFFTop - 1'b1] =
            {SopErr, TCDatFF[TCDatFFTop - 1'b1][17:16], TCDat[15],
            TCDatFF[TCDatFFTop - 1'b1][14:13], TCDat[12:0]};
          TCDatFFTop = TCDatFFTop;
        end

      // If write is asserted and the FIFO isn't full, store the input and
      // increment the write pointer
      else if (FFWriteEn == 1'b1 && CtlFull_i == 1'b0)
        begin
          TCDatFF[TCDatFFTop] <= #`TFF {SopErr, TCDat};
          TCCtlFF[TCDatFFTop] <= #`TFF TCCtl;
          TCDatFFTop          <= #`TFF TCDatFFTop + 1;
        end
    end
end

/*****************************************************************************
* Create RDat signal
* Creates the signal that will be passed to the core on the RDat bus.
* If the core is in reset it sends all zeros.  If the core is out of frame
* or SnkDataMaxT cycles have passed since the last training patterns
* were sent it sends training.  If the minimum number of cycles have not
* passed since the last SOP control word then it sends idles. In all other 
* cases it sends the data from the testcase FIFO.  In the case where it sends 
* idles or training, if it interrupted a data burst a payload resume burst 
* should be send after the idles or training completes.  Note: All clocking
* for this process is done in the procedures module.  All outgoing data is
* synchronous with RDClk2x.
*****************************************************************************/
always 
  begin: send_data_block
    if (!Reset_n)
    begin
      tasks.reset;

      TCDatFFBottom       <= #`TFF 'b0;
      SopCnt              <= #`TFF 3'b111;
      CreditCnt           <= #`TFF 3'b111;
      CreditBoundary      <= #`TFF 1'b1;
      DataInterrupt       <= #`TFF 16'b0;
      CurrentAddress      <= #`TFF 8'b0;
      FFReadEn            <= #`TFF 1'b0;
      HasEOP              <= #`TFF 1'b0;
      HasCredit           <= #`TFF 1'b0;
      SendingAutoTraining <= #`TFF 1'b0;
      SendingUserTraining <= #`TFF 1'b0;
      SendingUserIdle     <= #`TFF 1'b0;
    end
    else
    begin
      //If the current word is a control word then capture the current address
      if ((TCCtlFF[TCDatFFBottom] == 1'b1) && 
          (TCDatFF[TCDatFFBottom][15] == 1'b1))
        CurrentAddress <= #`TFF TCDatFF[TCDatFFBottom][11:4];
      else
        CurrentAddress <= #`TFF CurrentAddress;

      // If the user is trying to send a training pattern, allow it through
      // even if the core is out of sync, as long as an IDLE has just been
      // sent (a prerequisite for sending training) and the process isn't
      // already in the middle of sending automatic (periodic) training
      if ((!SendingAutoTraining) &&
          (SentUserIdle) &&
          (((TCCtlFF[TCDatFFBottom] == 1'b1) &&
            (TCDatFF[TCDatFFBottom] == {2'b0, `TRAINING_CTL})) ||
           ((SendingUserTraining) &&
            (TCCtlFF[TCDatFFBottom] == 1'b0) &&
            (TCDatFF[TCDatFFBottom] == {2'b0,  !(`TRAINING_CTL)}))) &&
          (CtlEmpty == 1'b0))
      begin
        SopCnt         <= #`TFF 3'd7;
        CreditCnt      <= #`TFF 3'd7;
        CreditBoundary <= #`TFF 1'b1;

        TCDatFFBottom   <= #`TFF (TCDatFFBottom + 1) % 1024;
        FFReadEn        <= #`TFF 1'b1;
        if (TCCtlFF[TCDatFFBottom] == 1'b1)
          tasks.send_control(TCDatFF[TCDatFFBottom][17:0]);
        else
          tasks.send_data(TCDatFF[TCDatFFBottom][17:0]);

        SendingUserTraining  = 1'b1;
        SendingAutoTraining  = 1'b0;
      end

      // If the user is trying to send a training pattern and hasn't preceded
      // it with an IDLE, insert an idle
      else if ((SendingAutoTraining == 1'b0) &&
               (SendingUserTraining == 1'b0) &&
               (SentUserIdle == 1'b0) &&
               (((TCCtlFF[TCDatFFBottom] == 1'b1) &&
                 (TCDatFF[TCDatFFBottom] == {2'b00, `TRAINING_CTL}))) &&
               (CtlEmpty == 1'b0))
      begin
        FFReadEn <= #`TFF 1'b0;
        if (SopCnt < 7)
          SopCnt <= #`TFF (SopCnt + 1) % 8;
        else
          SopCnt <= #`TFF SopCnt;

        tasks.send_idles(1);
        SendingUserTraining = 1'b0;
        SendingAutoTraining = 1'b0;
        SentUserIdle        = 1'b1;
      end

      // If the sink core is out of frame then send training patterns until
      // it comes into frame
      else if (SnkInFrame == 1'b0)
      begin
        SopCnt         <= #`TFF 3'd7;
        FFReadEn       <= #`TFF 1'b0;
        CreditCnt      <= #`TFF 3'd7;
        CreditBoundary <= #`TFF 1'b1;

        // If an idle hasn't been sent yet (currently not sending training)
        // then send one before sending training
	if (SendingAutoTraining == 1'b0)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -