📄 pl4_lite_procedures.v
字号:
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 + -