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

📄 pl4_lite_stimulus.v

📁 spi接口的vhdl实现
💻 V
📖 第 1 页 / 共 4 页
字号:
	begin
	  tasks.send_idles(1);
          SendingAutoTraining = 1'b1;
	end
        tasks.send_training(1);

        SentUserIdle        = 1'b0;
      end

      // If a control word is being sent with SOP set and it has been
      // longer than SnkDataMaxT cycles since the last training pattern,
      // then training should be sent after the control word.
      // The control word should be stripped of the payload
      // control bit, the SOP bit, and the address and these should be 
      // inserted into DataInterrupt.  This ensures that the burst before
      // training terminates properly (it either ends with an EOP or an idle)
      // and the next burst (after training) starts properly (with a Payload
      // control word). However, if Rctl != 0
      // (the previous output was a control word) then do not take this
      // branch, as either an EOP or IDLE was just sent or this is a forced
      // SOP-spacing violation
      else if ((TCCtlFF[TCDatFFBottom] == 1'b1) &&
               (TCDatFF[TCDatFFBottom][12] == 1'b1) &&
               (CtlEmpty == 1'b0) && 
               (RCtl == 1'b0) &&
               (TrainingCnt >= SnkDataMaxT && SnkDataMaxT > 0) &&
               (SnkAlphaData != 0 && DataInterrupt == 0) )
      begin
        DataInterrupt   <= #`TFF {4'h9, TCDatFF[TCDatFFBottom][11:4], 4'hF};
        TCDatFFBottom   <= #`TFF (TCDatFFBottom + 1) % 1024;
        FFReadEn        <= #`TFF 1'b1;
        SopCnt          <= #`TFF (SopCnt + 1'b1) % 8;
        CreditCnt       <= #`TFF 3'd7;
        CreditBoundary  <= #`TFF 1'b1;
        tasks.send_control({TCDatFF[TCDatFFBottom][17:16], 1'b0,
                      TCDatFF[TCDatFFBottom][14:13], 9'b0,
                      TCDatFF[TCDatFFBottom][3:0]});

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

      // If SnkDataMaxT cycles have passed since the last training
      // patterns were sent and the data transfer is on a credit
      // boundary then send training
      else if ((TrainingCnt >= SnkDataMaxT) &&
               (SnkDataMaxT > 0) &&
               (CreditBoundary == 1'b1) &&
               (SnkAlphaData != 0) )
        //---------------------------------------------------------------
        // If data was being sent then a payload resume control word
        // will need to be sent once training is complete.  The following
        // if structure creates the control word DataInterrupt
        //---------------------------------------------------------------

        // If the last thing sent was an IDLE, EOP, or abort, then the
        // data stream is already in a state where it's ready for
        // a training sequence, so launch right into that. Note:
        // even though this doesn't check for it, the last word
        // couldn't have indicated an SOP or a continue because
        // CreditBoundary is set
      begin
        if ((RCtl == 1'b1) &&
            ((RDat[15:12] == 4'h0) || (RDat[14:13] != 2'b00)) )
          DataInterrupt   <= #`TFF DataInterrupt;

        else
        begin
          // If DataInterrupt is already set, don't change it. This branch
          // should never get hit, but it's here for clarity
          if (DataInterrupt != 0)
            DataInterrupt <= #`TFF DataInterrupt;

          // If there's an EOP or an abort in the FIFO and the FIFO's not
          // empty then send out the EOP and store the rest of the control
          // word into DataInterrupt
          else if ((TCDatFF[TCDatFFBottom][14:13] != 2'b00) &&
                   (TCCtlFF[TCDatFFBottom] == 1'b1) &&
                   (CtlEmpty == 1'b0) )
          begin
            FFReadEn          <= #`TFF 1'b1;
            TCDatFFBottom     <= #`TFF (TCDatFFBottom + 1) % 1024;

            // If there's an SOP or Payload Control, save that part of the
            // control word into DataInterrupt
            if ((TCDatFF[TCDatFFBottom][15] == 1'b1) ||
                (TCDatFF[TCDatFFBottom][12] == 1'b1) )
              DataInterrupt  <= #`TFF {TCDatFF[TCDatFFBottom][15], 2'b00,
                                       TCDatFF[TCDatFFBottom][12:0]};

            tasks.send_control({TCDatFF[TCDatFFBottom][17:16], 1'b0,
                          TCDatFF[TCDatFFBottom][14:13], 1'b0,
                          12'h00F});
          end

          // Either the FIFO is empty or the next thing in it is either
          // an SOP/continue or data
          else
          begin
            // If the FIFO is non-empty and the next item is data, then
            // store a resume into DataInterrupt and send out an idle
            // before going into training
            if ((TCCtlFF[TCDatFFBottom] == 1'b0) &&
                (CtlEmpty == 1'b0) )
            begin
              DataInterrupt  <= #`TFF {4'h8, CurrentAddress, 4'hF};
              FFReadEn       <= #`TFF 1'b0;
              tasks.send_idles(1);
            end

            // If the FIFO is empty or the next item is non-data,
            // do nothing before going into training
            else
              DataInterrupt  <= #`TFF DataInterrupt;
          end
        end

        // Send the actual training pattern
        SopCnt     <= #`TFF 3'd7;
        FFReadEn   <= #`TFF 1'b0;
        tasks.send_training(SnkAlphaData);
        SentUserIdle        = 1'b0;
        SendingAutoTraining = 1'b1;
      end
      
      // No need to send training
      else
      begin
        HasCredit           = 1'b0;
        HasEOP              = 1'b0;
        SendingUserTraining = 1'b0;
        SendingAutoTraining = 1'b0;
        SentUserIdle        = 1'b0;

        // If the next word out of the FIFO is a payload control word and
        // the FIFO read pointer is less than 8 behind the write pointer then
        // set the HasCredit variable to false (there is less than a credit of
        // data in the FIFO) and check to see if the FIFO contains and EOP
        // control word. If so, set HasEOP to true. This check implicitly
        // fails if the FIFO is empty.
        if ((((TCDatFF[TCDatFFBottom][15] == 1'b1) &&
              (TCCtlFF[TCDatFFBottom] == 1'b1)) ||
              (DataInterrupt[15] == 1'b1)) &&
            (((TCDatFFBottom < TCDatFFTop) &&
             ((TCDatFFBottom + 'd9) % 1024 > TCDatFFTop))
                                ||
            (((TCDatFFBottom + 'd9) % 1024 < 'd9) &&
             ((TCDatFFBottom + 'd9) % 1024 > TCDatFFTop))))
        begin
          // If the FIFO write pointer has wrapped around
          if (TCDatFFBottom + 'b1 > TCDatFFTop)

            // Check every FIFO location between the read and write pointers
            // for an EOP
            for (x = TCDatFFBottom + 1; x < (TCDatFFTop + 1024); x = x + 1)
              if ((TCDatFF[x % 1024][14:13] != 2'b00) &&
                  (TCCtlFF[x % 1024] == 1'b1) )
                HasEOP  = 1'b1;

          // If the FIFO write pointer has not wrapped around
          else
            // Check every FIFO location between the read and write pointers
            // for an EOP
            for (x = TCDatFFBottom + 1; x < TCDatFFTop; x = x + 1)
              if (TCDatFF[x][14:13] != 2'b00 && TCCtlFF[x] == 1'b1)
                HasEOP  = 1'b1;
        end

        // Else FIFO is empty or there is is at least a credit in the FIFO
        else
          HasCredit  = 1'b1;

        // If there is a payload control word at the head of the FIFO and less
        // than a credit of data available with no EOP, then don't start
        // sending the packet out since it is not certain that the entire
        // packet will be written to the FIFO in time to be sent out.
        // Instead, send whatever EOP information is in the payload control
        // word (since it would go with the packet already sent out. The
        // remainder of the payload control word is stored in DataInterrupt
        // to be sent out once a full credit (or EOP) is available in the
        // FIFO.
        if ((HasCredit == 1'b0) && (HasEOP == 1'b0))
        begin
          if ((TCDatFF[TCDatFFBottom][14:13] != 2'b00) &&
              (TCCtlFF[TCDatFFBottom] == 1'b1) &&
              DataInterrupt == 0)

          begin  
            DataInterrupt     <= #`TFF {TCDatFF[TCDatFFBottom][15], 2'b00,
                                        TCDatFF[TCDatFFBottom][12:0]};
            FFReadEn          <= #`TFF 1'b1;
            TCDatFFBottom     <= #`TFF (TCDatFFBottom + 1) % 1024;
            CreditCnt         <= #`TFF 3'd7;
            CreditBoundary    <= #`TFF 1'b1;
            if (SopCnt < 7)
              SopCnt <= #`TFF (SopCnt + 1) % 8;
            else
              SopCnt <= #`TFF 3'd7;

            tasks.send_control({TCDatFF[TCDatFFBottom][17:16], 1'b0,
                          TCDatFF[TCDatFFBottom][14:13], 1'b0, 12'h00f});
          end

          // The next item in the FIFO is a non-EOP, or DataInterrupt is
          // already set
          else
          begin
            FFReadEn  <= #`TFF 1'b0;
            if (SopCnt < 7)
              SopCnt  <= #`TFF (SopCnt + 1) % 8;
            else
              SopCnt  <= #`TFF 'd7;

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

        // Either:
        //  a) A credit is currently in progress (bottom of FIFO isn't
        //     a control word)
        //  b) A full credit is available
        //  c) Less than a credit is available, but there is an EOP in
        //     the FIFO, or
        //  d) The FIFO is empty
        else
        begin

          // Empty ------------------------------------------------------------
          // If the FIFO is empty then just send idles
          if (CtlEmpty == 1'b1)
          begin
            FFReadEn <= #`TFF 1'b0;
            
            if (SopCnt < 'd7)
              SopCnt <= #`TFF (SopCnt + 1) % 8;
            else
              SopCnt <= #`TFF 3'd7;

            tasks.send_idles(1);
            SentUserIdle  = 1'b1;
          end
  
          // SOP --------------------------------------------------------------
          // If the current control word is an SOP or the control word in
          // DataInterrupt is a SOP then make sure that there
          // has been at least one credit sent since the last SOP.  If there
          // hasn't then send idles until this requirement is met.
          else if (((TCDatFF[TCDatFFBottom][12] == 1'b1) &&
                    (TCDatFF[TCDatFFBottom][15] == 1'b1) &&
                    (TCCtlFF[TCDatFFBottom] == 1'b1)) ||
                   ((DataInterrupt[15] == 1'b1) &&
                    (DataInterrupt[12] == 1'b1)))
          begin
            // Check to see if less than one credit has been sent since the
            // last SOP and SOPErr is not set
            if ((SopCnt < 'd7) &&
                (TCDatFF[TCDatFFBottom][18] != 1'b1))
            begin
              SopCnt <= #`TFF (SopCnt + 1) % 8;

              // If there is an EOP then strip off the payload control and
              // store it in DataInterrupt to send after the idles complete
              if ((TCDatFF[TCDatFFBottom][14:13] != 2'b00) &&
                  (DataInterrupt[15] == 1'b0))
              begin
                DataInterrupt  <= #`TFF {4'h9, TCDatFF[TCDatFFBottom][11:4],
                                         4'hF};

                TCDatFFBottom  <= #`TFF (TCDatFFBottom + 1) % 1024;
                FFReadEn       <= #`TFF 1'b1;

                CreditCnt      <= #`TFF 3'd7;
                CreditBoundary <= #`TFF 1'b1;

                tasks.send_control({TCDatFF[TCDatFFBottom][17:16], 1'b0,
                              TCDatFF[TCDatFFBottom][14:13], 1'b0,
                              12'h00F});
                if (SopCnt < 6)
                begin
                  FFReadEn     <= #`TFF 1'b0;
                  SopCnt       <= #`TFF (SopCnt + 1) % 8;
                  tasks.send_idles(1);
                  SentUserIdle  = 1'b1;
                end
              end
              else
              begin
                FFReadEn <= #`TFF 1'b0;
                tasks.send_idles(1);
                SentUserIdle  = 1'b1;
              end
            end

            // If the minimum SOP spacing is met then check to see if
            // DataInterrupt is set.  If it is, send out the control word
            // on it before sending the next data word.  Otherwise send
            // the next word.
            else
            begin
              SopCnt              <= #`TFF 1'b0;
              CreditCnt           <= #`TFF 3'd7;
              CreditBoundary      <= #`TFF 1'b0;

              if (DataInterrupt[15] != 1'b0)
              begin
                DataInterrupt     <= #`TFF 16'h0;
                FFReadEn          <= #`TFF 1'b0;
                tasks.send_control({2'b00, DataInterrupt});
              end
              else
              begin
                TCDatFFBottom     <= #`TFF (TCDatFFBottom + 1) % 1024;
                FFReadEn          <= #`TFF 1'b1;
                tasks.send_control(TCDatFF[TCDatFFBottom][17:0]);
              end
            end
          end

          // DataInterrupt Flag -----------------------------------------------
          // If the DataInterrupt register is set then send it on RDat and
          // reset the register to zero.
          else if (DataInterrupt != 0)
          begin
            FFReadEn      <= #`TFF 1'b0;

            if (DataInterrupt[12] == 1'b1)
              SopCnt      <= #`TFF 3'd0;
            else
              if (SopCnt < 3'd7)
                SopCnt    <= #`TFF (SopCnt + 1) % 8;
              else
                SopCnt    <= #`TFF SopCnt;

⌨️ 快捷键说明

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