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

📄 pl4_lite_procedures.v

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

/*****************************************************************************
* test
* Use this task to test specific sequences of control words and data words
*****************************************************************************/
task test;
  begin
    send_control(18'b00_1111_0000_0010_0000);
    send_data(18'd1);
    send_data(18'd2);
    send_data(18'd3);
    send_data(18'd4);
    send_data(18'd5);
    send_data(18'd6);
    send_data(18'd7);
    send_data(18'd8);
    send_data(18'd9);
    send_control(18'b00_0110_0000_0000_0000);
  @(posedge RDClk2x);
    //FIFO write enable is deasserted after all data has been written
    FFWriteEn <= 1'b0;
  end
endtask

/*****************************************************************************
* Sop Spacing error
* This task sends two SOP control words in an amount of time specified by
* the user.  It disables the Control Modules checking for minimum SOP
* spacing
******************************************************************************
* Inputs
* NumBytes1: The number of bytes to send after the first SOP
* Err1: The Error flag for the control word after data is sent
* Address1: The address for the first control word
* Eop2: Whether or not to set the EOP bit for the second control word
* Err2: Whether to set bits [14:13] to EOP abort or not for the second
*       control word
* Address2: The channel for the second control word
* NumBytes2: The number of bytes to send after the second control word
* NumIdles: The number of idle cycles between the first EOP control word
*           and the second SOP control word
*****************************************************************************/
task sop_spacing;
input [7:0] NumBytes1;
input       Err1;
input [7:0] Address1;
input       Eop2;
input       Err2;
input [7:0] Address2;
input [7:0] NumBytes2;
input [2:0] NumCycles;
reg   [7:0] BytesDiv2;
reg   [2:0] NumIdles;
reg   [7:0] Cnt;
reg   [1:0] Eops;
reg   [1:0] Eops2;

begin
  //Send the first SOP control word
  send_control({1'b0,TCDIP4Request,3'b100, 1'b1, Address1, 4'b1111});

  //Calculate the number of cycles to send data and idles
  //If the number of bytes is odd
  if ((NumBytes1 % 2) == 1)
  begin

    //If the number of data cycles would be greater then 6, then set the number
    //of data cycles to 5 and the number of idles to 0
    if (((NumBytes1 / 2) + 1) > 6)
      begin
      BytesDiv2 = 5;
      NumIdles  = 0;
      end
    //Otherwise the number of data cycles is calculated normally
    else
      begin
      BytesDiv2 = (NumBytes1 / 2) + 1;
      //If the number of idle cycles plus the number of data cycles is
      //greater than 6 then set the number of idle cycles to 5 minus data
      //cycles
      if ((NumCycles + BytesDiv2) > 6)
        NumIdles = 5 - BytesDiv2;
      //Otherwise the number of idle cycles is simply the inputted number
      //of idle cycles
      else
        NumIdles = NumCycles;
      end

  end

  //If the number of bytes is even 
  else
  begin
    //If the number of data cycles would be greater then 6, then set the number
    //of data cycles to 5 and the number of idles to 0
    if ((NumBytes1 / 2) > 6)
      begin
      BytesDiv2 = 5;
      NumIdles  = 0;
      end

    //Otherwise the number of data cycles is calculated normally
    else
      begin
      BytesDiv2 = (NumBytes1 / 2);
      //If the number of idle cycles plus the number of data cycles is
      //greater than 6 then set the number of idle cycles to 5 minus data
      //cycles
      if ((NumCycles + BytesDiv2) > 6)
        NumIdles = 5 - BytesDiv2;
      //Otherwise the number of idle cycles is simply the inputted number
      //of idle cycles
      else
        NumIdles = NumCycles;
      end

  end

  //Send data corresponding to the first control word
  send_words(BytesDiv2, Address1);

  //Set the flag to tell the Control module to ignore SOP spacing errors
  SopErr = 1'b1;

  //If the Err flag is set for the first EOP control word
  if (Err1 == 1'b1)
    Eops = 2'b01;
  //Otherwise calculate the mod
  else if ((NumBytes1 % 2) == 0)
    Eops = 2'b10;
  else if ((NumBytes1 % 2) == 1)
    Eops = 2'b11;
  else
    $display("Error in sop_spacing on EOP1 at time", $time);

  //Send the first EOP control word
  send_control({1'b0,TCDIP4Request,1'b0, Eops, 1'b0, 12'h00f});

  //Send Idles
  send_idles(NumIdles);

  //Send the second SOP control word
  send_control({1'b0,TCDIP4Request,4'b1001, Address2, 4'b1111});

  //Calculate the number of cycles needed to send all the data 
  if ((NumBytes2 % 2) == 1)
    BytesDiv2 = (NumBytes2 / 2) + 1;
  else
    BytesDiv2 = (NumBytes2 / 2);

  //Send data corresponding to the second SOP control word
  send_words(BytesDiv2, Address2);

  //Calculate bits [14:13] for last control word
  if (Err2 == 1'b1)
    Eops2 = 2'b01;
  else if (Eop2 == 1'b1)
  begin
    if ((NumBytes2 % 2) == 0)
      Eops2 = 2'b10;
    else if ((NumBytes2 % 2) == 1)
      Eops2 = 2'b11;
  end
  else
    Eops2 = 2'b00;
  SopErr = 1'b0;

  //Send last control word
  send_control({1'b0,TCDIP4Request,1'b0, Eops2, 1'b0, 12'h00f});

  //Deassert the Sop spacing error signal and the FIFO write enable signal
  //SopErr = 1'b0;
  FFWriteEn <= 1'b0;
end
endtask

/*****************************************************************************
* Non credit boundary without an EOP
* This task sends a payload control word followed by data.  It then sends
* another control word without an EOP on a non credit boundary
******************************************************************************
* Inputs
* Sop: Specifies whether first payload control word is an SOP
* Address: Channel to send data to
* NumBytes: The number of bytes to send
*****************************************************************************/
task non_credit_wo_eop;
input       Sop;
input [7:0] Address;
input [7:0] NumBytes;
reg   [7:0] BytesDiv2;
reg   [7:0] Cycles;
reg   [7:0] Cnt;

begin
  //Send the payload control word
  send_control({1'b0,TCDIP4Request,3'b100, Sop, Address, 4'b1111});

  //Calculate the number of cycles to send data for
  if ((NumBytes % 2) == 1)
    BytesDiv2 = (NumBytes / 2) + 1;
  else
    BytesDiv2 = (NumBytes / 2);

  //If the number of cycles constitutes a credit boundary then add one to
  //the cumber of cycles to force sending a non EOP control word on a non
  //credit boundary
  if ((BytesDiv2 % 8) == 0)
    Cycles = BytesDiv2 + 1;
  else
    Cycles = BytesDiv2;

  //Send the data
  send_words(Cycles, Address);

  //Deassert the FIFO write enable
  FFWriteEn <= 1'b0;
end
endtask

/*****************************************************************************
* Reserved Control Word
* This task sends one of four reserved control words
******************************************************************************
* Inputs
* Eops: Represents bits [14:13] of the control word
*****************************************************************************/
task reserved_control_word;
input [1:0] Eops;

begin
  //Send the reserved control word
  send_control({1'b0,TCDIP4Request,1'b0, Eops, 1'b1, 12'h00f});

  //Deassert the FIFO write enable
  FFWriteEn <= 1'b0;
end
endtask

/*****************************************************************************
* Send Words
* This procedure sends NumWords number of words from the data source
* specified by DATA_TYPE. It does not send any control words, just the
* actual data words.
******************************************************************************
* Inputs
* NumWords: The number of words (cycles of data) to send
* Address:  The channel data is to be sent on (only used for incremental)
*****************************************************************************/
task send_words;
input [7:0] NumWords;
input [7:0] Address;
reg   [7:0] Cnt;
integer     IntSeed;

begin
  
  IntSeed = RandomSeed + $time;  

  // Loop for all the data words
  for (Cnt = 0; Cnt < NumWords; Cnt = Cnt + 1)
  begin
    case (`DATA_TYPE)
      //Case 1: Incremental Data
      2'b00 : begin
        DataOut[Address] <= #`TFF DataOut[Address] + 1;
        send_data({1'b0,TCDIP4Request,DataOut[Address]});
      end
      //Case 2: Random Data
      2'b01 : begin
        send_data({1'b0,TCDIP4Request,{$random(IntSeed)}%65535});
      end
      //Case 3: Data from a file
      2'b10 : begin
        send_data({1'b0,TCDIP4Request,DataOut[DataCnt]});
        if (DataCnt < FileLength)
          DataCnt = DataCnt + 1;
        else
        begin
          $display("WARNING: %0d End of data file reached.  Starting Over",$time);
          DataCnt = 'b0;
        end
      end
      //Default: Incorrect `Data_TYPE value
      default: $display ("%s: %0d DATA_TYPE not set to a valid value", "ERROR", $time);
    endcase
  end
end
endtask

  
/*****************************************************************************
* Send Idles
* This task sends the specified number of idle cycles
******************************************************************************
* Inputs
* Cnt: The number of cycles to send idles for
*****************************************************************************/
task send_idles;
input   [8:0]  Cnt;
reg     [17:0] Data;

  begin
    //Repeat for Cnt number of time
    repeat (Cnt)
      begin
      Data = 18'b00_0000_0000_0000_1111;
      //Send Cnt number of idles
      send_control(Data);

      //Deassert the FIFO write enable
      FFWriteEn = 1'b0;
      end
  end
endtask

/*****************************************************************************
* Send Training
* This task sends the specified number of training patterns
******************************************************************************
* Inputs 
* Cnt: The number of training patterns to send
*****************************************************************************/
task send_training;
input  [7:0]  Cnt;
reg    [17:0] Data;
reg    [4:0]  i;
reg    [4:0]  j;

  begin
    //Repeat for Cnt number of patterns
    repeat (Cnt) 
    begin
      Data = 18'b00_0000_1111_1111_1111; 
      //Repeat sending the training control pattern 10 times
      for (i = 0; i < 10; i = i + 1)
        begin
        send_control(Data);
        end
      Data = 18'b00_1111_0000_0000_0000; 
      //Repeat sending the training data pattern 10 times
      for (j = 0; j < 10; j = j + 1)
        begin
        send_data(Data);
        end
    end
  //Deassert the FIFO write enable
  FFWriteEn = 1'b0;
  end
endtask

/*****************************************************************************
* Send Status
* This task sends the status for a given channel to the Control Module
******************************************************************************
* Inputs
* Channel: The channel to send the status for
* Status: The status to send (satisfied, hungry, starving)
*****************************************************************************/
task send_status;
input [15:0] Channel;
input [1:0] Status;
begin
  @(posedge TSClk);
  Stat <= Status;
  Chan <= Channel;
end
endtask

/*****************************************************************************
* Get Status
* This task gets the status for a given channel and returns it to the
* testcase module
******************************************************************************
* Inputs
* Chan: The channel to get the status for
*****************************************************************************/
task get_status;
input [7:0] Chan;

begin
  @(posedge TSClk);
  GetStatusChan <= Chan;
end
endtask

/*****************************************************************************
* Send Control
* This task sends a control word
******************************************************************************
* Inputs
* Data_t: The control word that needs to be sent out
*****************************************************************************/
task send_control;
input  [17:0] Data_t;

  begin

  // Don't write to a full FIFO
  while (FFFull == 'b1)
  begin
    FFWriteEn  <= 'b0;
    @ (posedge RDClk2x);
  end

  FFWriteEn <= 1'b1;
  RDat <= Data_t;
  RCtl <= 1'b1;
  @ (posedge RDClk2x);
  FFWriteEn <= 'b0;
  end
endtask

/*****************************************************************************
* Send Data
* This task sends a data word
******************************************************************************
* Inputs
* Data: The data word that needs to be sent out
*****************************************************************************/
task send_data;
input  [17:0] Data;

  begin

  // Don't write to a full FIFO
  while (FFFull == 'b1)
  begin
    FFWriteEn  <= 'b0;
    @ (posedge RDClk2x);
  end

  FFWriteEn <= 1'b1;
  RDat <= Data;
  RCtl <= 1'b0;
  @ (posedge RDClk2x);
  FFWriteEn <= 'b0;
  end
endtask
endmodule

⌨️ 快捷键说明

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