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

📄 pl4_lite_stimulus.v

📁 spi接口的vhdl实现
💻 V
📖 第 1 页 / 共 4 页
字号:

            DataInterrupt <= #`TFF 16'h0;
            tasks.send_control({2'b00, DataInterrupt});
          end

          // Control-----------------------------------------------------------
          // If the current word is control and not SOP then send control
          else if (TCCtlFF[TCDatFFBottom] == 1'b1)
          begin
            if (SopCnt < 3'd7)
              SopCnt <= #`TFF (SopCnt + 1) % 8;
            else
              SopCnt <= #`TFF SopCnt;

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

            if (TCDatFF[TCDatFFBottom][14:13] != 2'b00)
            begin
              CreditCnt       <= #`TFF 3'd7;
              CreditBoundary  <= #`TFF 1'b1;
            end
            else
            begin
              CreditCnt       <= #`TFF CreditCnt;
              CreditBoundary  <= #`TFF CreditBoundary;
            end

            if (TCDatFF[TCDatFFBottom] == {2'b00, 16'h000F})
              SentUserIdle  = 1'b1;

            tasks.send_control(TCDatFF[TCDatFFBottom][17:0]);
          end

          // Data -------------------------------------------------------------
          // If the current word is data then send data
          else if (TCCtlFF[TCDatFFBottom] == 1'b0)
          begin
            if (SopCnt < 'd7)
              SopCnt          <= #`TFF (SopCnt + 1) % 8;
            else
              SopCnt          <= #`TFF SopCnt;

            FFReadEn          <= #`TFF 1'b1;
            TCDatFFBottom     <= (TCDatFFBottom + 1) % 1024;
            if (CreditCnt == 6)
            begin
              CreditCnt       <= #`TFF CreditCnt + 1;
              CreditBoundary  <= #`TFF 1'b1;
            end
            else
            begin
              CreditCnt       <= #`TFF (CreditCnt + 1) % 8;
              CreditBoundary  <= #`TFF 1'b0;
            end
            tasks.send_data(TCDatFF[TCDatFFBottom][17:0]);
          end

          // Nothing-----------------------------------------------------------
          // In the default case send an idle
          else
          begin
            FFReadEn <= #`TFF 1'b0;
            if (SopCnt < 'd7)
              SopCnt <= #`TFF (SopCnt + 1) % 8;
            else
              SopCnt <= #`TFF SopCnt;

            SentUserIdle  = 1'b1;
	    tasks.send_idles(1);
	    
          end
        end
    end // else: !if((TrainingCnt >= SnkDataMaxT) &&...
  end // else: !if(!Reset_n)
end // block: send_data_block
  
//******************************************************************************
// Count RDat Training
//******************************************************************************
// The following counts the cycles between traing on RDat
//******************************************************************************

always @(posedge RDClk2x or negedge Reset_n)
begin: count_rdat_train
  if (Reset_n == 1'b0)
  begin
    SendTraining <=  #`TFF 1'b0;
    TrainingCnt  <= #`TFF 'b0;
  end
  else
  begin
    if (((RCtl) &&
         (RDat_P == {2'b0, `TRAINING_CTL})) ||
        ((!RCtl) &&
         (RDat_P == {2'b0, ~`TRAINING_CTL}) &&
         (SendTraining)))
    begin
      SendTraining <= #`TFF 1'b1;
      TrainingCnt  <= #`TFF 'b0;
    end
    else
    begin
      SendTraining <= #`TFF 1'b0;
      TrainingCnt  <= #`TFF TrainingCnt + 1'b1;
    end
  end
end

//******************************************************************************
// The following processes are used to generate dip4 and insert them in
// the data stream
//******************************************************************************

//******************************************************************************
// pipeline
//******************************************************************************
// This process defines the pipeline delay registers.
//******************************************************************************
always @(posedge RDClk2x or negedge Reset_n)  //pipeline
begin
  if (Reset_n == 1'b0)
  begin
    Data_d1 <= 'b0;
    Ctl_d1  <= 1'b1;
    ControlEnableDIP4 <= 1'b1;
  end
  else 
  begin
    Data_d1 <= RDat;
    Ctl_d1  <= RCtl;
    ControlEnableDIP4 <= Ctl_d1;
  end
end //pipeline


//******************************************************************************
// train_detect
//******************************************************************************
// This process detects when Training words are being sent.
//******************************************************************************
always @(posedge RDClk2x or negedge Reset_n) //train_detect
begin 
  if(Reset_n == 1'b0)
    Training <= #`TFF 1'b0;
  else 
    if((RCtl == 1'b1) && (RDat[15:0] == `TRAINING_CTL))
      Training <= #`TFF 1'b1;
    else if (RCtl == 1'b1)
      Training <= #`TFF 1'b0;
end //train_detect


//******************************************************************************
// dip16_calc
/***************************************************************************/
// This process detects the type of word, data or control, and calculates the
// DIP16 word.
/***************************************************************************/
always @(posedge RDClk2x or negedge Reset_n) //dip16_calc
begin
  if(Reset_n == 1'b0)
    DIP16 <= ~0; //(OTHERS => 1'b1);
  else 
    // If this is the first data word, load it into DIP16
    if((RCtl == 1'b0) && (Ctl_d1 == 1'b1))
      DIP16 <= RDat[15:0];
    // else if this is a subsequent data word, ^ it with DIP16
    else if((RCtl == 1'b0) && (Ctl_d1 == 1'b0))
      DIP16 <= RDat[15:0] ^ {DIP16[0], DIP16[15:1]} ;
    // else if this is terminating control word, ^ it with DIP16
    else if((RCtl == 1'b1) && (Ctl_d1 == 1'b0))
      DIP16 <= {RDat[15:4],4'b1111} ^ {DIP16[0],DIP16[15:1]};
    // else if this is a subsequent control word, load it into DIP16
    else if((RCtl == 1'b1) && (Ctl_d1 == 1'b1))
      DIP16 <= {RDat[15:4],4'b1111};
end //dip16_calc

//******************************************************************************
// DIP4 calculations (combinitorial).  It gets registered in data_out_mux.
//******************************************************************************

assign DIP4[3] = DIP16[15] ^ DIP16[11] ^ DIP16[7] ^ DIP16[3];
assign DIP4[2] = DIP16[14] ^ DIP16[10] ^ DIP16[6] ^ DIP16[2];
assign DIP4[1] = DIP16[13] ^ DIP16[9]  ^ DIP16[5] ^ DIP16[1];
assign DIP4[0] = DIP16[12] ^ DIP16[8]  ^ DIP16[4] ^ DIP16[0];

//******************************************************************************
// data_out_mux
//******************************************************************************
// This process determines what information is sent out on the data_control_dip4
// bus.  It also calculates DIP4 from DIP16 and inserts it.
//******************************************************************************
always @(posedge RDClk2x or negedge Reset_n) //data_out_mux
begin
  if(Reset_n == 1'b0)
    DataControlDIP4 <= 0;
  else
    if((Training == 1'b1) || (Ctl_d1 == 1'b0))
      DataControlDIP4 <= Data_d1[15:0];
    else if (Data_d1[16] == 1)
      DataControlDIP4 <= {Data_d1[15:4],~DIP4};
    else
      DataControlDIP4 <= {Data_d1[15:4],DIP4};
end //data_out_mux

assign RDat_P = DataControlDIP4;
assign RDat_N = ~DataControlDIP4;
assign RCtl_P = ControlEnableDIP4;
assign RCtl_N = ~ControlEnableDIP4;

/*****************************************************************************
* Stores TCStat
* Captures the status signal from the control block into TCStatArray using
* TCChannel as an index
*****************************************************************************/
always @(posedge TSClkIn or negedge Reset_n)
begin: store_status
  //If in reset then set all channels to hungry
  if (!Reset_n)
  begin
    for (TCIndex = 0; TCIndex < NumLinks; TCIndex = TCIndex + 1)
      TCStatArray[TCIndex] <=#`TFF 2'b00;
  end
  //Otherwise set the channel specified on TCChannel to the value specified
  //on TCStat
  else
    TCStatArray[TCChannel] <= #`TFF TCStat;
end
  
/*****************************************************************************
* Get Status
* Returns the status on channel GetStatusChan to the testcase via the
* signal GetStatus
*****************************************************************************/
always @(posedge TSClkIn or negedge Reset_n)
begin: get_status_ctl
  if (!Reset_n)
    GetStatus <= #`TFF 2'b00;
  else
    GetStatus <= #`TFF TCStatArray[GetStatusChan];
end
  
/*****************************************************************************
* Send Status, DIP-2, and Framing Patterns
* If the Source core is out of frame (SrcInFrame is low) or the core is
* in reset then send framing data over TStat.  If it is the first word of
* a sequence then send framing.  If it is the last word then send the
* DIP-2 value.  Otherwise send the status from TCStat.
*****************************************************************************/
always @(posedge TSClkIn or negedge Reset_n)
begin: send_status
  if (!Reset_n)
    begin
      TStat  <= #`TFF 2'b11;
      LenCnt <= #`TFF 9'b1;
      MCnt   <= #`TFF 'b1;
      Dip2   <= #`TFF 2'b0;
      First  <= #`TFF 0;
    end
  //Wait until the source is enabled (calender writing is complete) before
  //sending status
  else if (!CalWrEn_n)
    begin
      TStat  <= #`TFF 2'b11;
      Dip2   <= #`TFF 2'b0;
      LenCnt <= #`TFF 1'b1;
      MCnt   <= #`TFF 1'b1;
    end
  //Wait until the SrcInFrame signal is asserted to send status
  else if (SrcInFrame == 0)
    begin
      TStat  <= #`TFF 2'b11;
      Dip2   <= #`TFF 2'b0;
      LenCnt <= #`TFF 1'b1;
      MCnt   <= #`TFF 1'b1;
    end
  else if (First == 0)
    First <= #`TFF 1;
  else
  begin
    //If it is the first word of the sequence then send framing
    if ((LenCnt == 1'b0) && (MCnt == 1'b0))
    begin
      TStat  <= #`TFF 2'b11;
      Dip2   <= #`TFF 2'b00;
      LenCnt <= #`TFF 1'b1;
      MCnt   <= #`TFF 1'b1;
    end
    //If it is the last status word then send the DIP2 value
    else if ((LenCnt == SrcCalendar_Len + 2) && (MCnt == SrcCalendar_M + 1))
    begin
      //If TCDip2Request is set then invert the DIP2 value (user requested
      //DIP2 Error)
      if (TCDIP2Request == 1)
      begin
        TStat[0] <= #`TFF ~(Dip2[1] ^ 1'b1);
        TStat[1] <= #`TFF ~(Dip2[0] ^ 1'b1);
      end
      else
      begin
        TStat[0] <= #`TFF Dip2[1] ^ 1'b1;
        TStat[1] <= #`TFF Dip2[0] ^ 1'b1;
      end
      LenCnt   <= #`TFF 1'b0;
      MCnt     <= #`TFF 1'b0;
      Dip2     <= #`TFF Dip2;
    end
    //Else it is a status word so just send it and calculate the new 
    //DIP2
    else 
    begin
      TStat <= #`TFF TCStatArray[CalSeq[LenCnt - 1]];
      Dip2  <= #`TFF TCStatArray[CalSeq[LenCnt - 1]] ^ {Dip2[0], Dip2[1]};
      //Increment the MCnt (repetitions of the calendar) and reset the
      //LenCnt (length of the calendar) if you are at the end of the
      //calendar
      if ((LenCnt == SrcCalendar_Len + 1) && (MCnt < SrcCalendar_M + 1))
      begin
        MCnt   <= #`TFF (MCnt + 1);
        LenCnt <= #`TFF 1'b1;
      end
      //Otherwise just increment the LenCnt
      else
      begin
        LenCnt <= #`TFF LenCnt + 1;
      end
    end
  end
end

endmodule

⌨️ 快捷键说明

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