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