Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / verif / model / pcie / dll / pl_consumer.cpp
CommitLineData
86530b38
AT
1// ========== Copyright Header Begin ==========================================
2//
3// OpenSPARC T2 Processor File: pl_consumer.cpp
4// Copyright (C) 1995-2007 Sun Microsystems, Inc. All Rights Reserved
5// 4150 Network Circle, Santa Clara, California 95054, U.S.A.
6//
7// * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
8//
9// This program is free software; you can redistribute it and/or modify
10// it under the terms of the GNU General Public License as published by
11// the Free Software Foundation; version 2 of the License.
12//
13// This program is distributed in the hope that it will be useful,
14// but WITHOUT ANY WARRANTY; without even the implied warranty of
15// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16// GNU General Public License for more details.
17//
18// You should have received a copy of the GNU General Public License
19// along with this program; if not, write to the Free Software
20// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21//
22// For the avoidance of doubt, and except that if any non-GPL license
23// choice is available it will apply instead, Sun elects to use only
24// the General Public License version 2 (GPLv2) at this time for any
25// software where a choice of GPL license versions is made
26// available with the language indicating that GPLv2 or any later version
27// may be used, or where a choice of which version of the GPL is applied is
28// otherwise unspecified.
29//
30// Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
31// CA 95054 USA or visit www.sun.com if you need additional information or
32// have any questions.
33//
34// ========== Copyright Header End ============================================
35#include "dll_top.hpp"
36
37namespace pcie {
38
39 /** This function gets packets from PL and processes them **/
40 void dll_top::pl_consumer()
41 {
42 LOG_DEBUG<<"DLL: pl_consumer begins...";
43 try {
44 RefPciePacket rx_pkt;
45 RefPciePacket tx_ack_nack_pkt;
46 int i,rx_pkt_size;
47 sc_uint<16> rx_pkt_dllp_crc,tx_pkt_dllp_crc;
48 sc_uint<12> rx_pkt_seq_num;
49 sc_uint<8> byte_seq_num;
50 sc_uint<12> tx_pkt_seq_num;
51 sc_uint<12> check_seq_num;
52 sc_uint<32> rx_pkt_calc_lcrc;
53 sc_uint<8> HdrFC;
54 sc_uint<12> DataFC;
55 sc_uint<16> dllp_crc_unmapped;
56 sc_uint<8> SDP_byte1;
57 sc_uint<8> SDP_byte2;
58 sc_uint<8> SDP_byte3;
59 sc_uint<8> SDP_byte4;
60 sc_uint<8> SDP_byte5;
61 sc_uint<8> SDP_byte6;
62 sc_uint<64> tlu_ecl_hw_reg,tlu_ecc_hw_reg ;
63
64 time_last_ack_nak_received=0;
65
66 while (true) {
67 //Receive packet from PL
68 pl_dll_in.get_packet(rx_pkt);
69 //rx_pkt->display_packet();
70
71 if(rx_pkt->get_byte(0) == STP && rx_pkt->get_control() != DLLP_NAK && rx_pkt->get_control() != DLLP_NAK_FRAMING){
72 //cout << sc_time_stamp() << " DLL: Received TLP " << rx_pkt->getPacketId() << " from PL." << endl;
73 rx_pkt_size = rx_pkt->get_size();
74 byte_seq_num = rx_pkt->get_byte(1);
75 rx_pkt_seq_num.range(11,8)=byte_seq_num.range(3,0);
76 byte_seq_num = rx_pkt->get_byte(2);
77 rx_pkt_seq_num.range(7,0)=byte_seq_num.range(7,0);
78 //rx_pkt->pl2dll_display_stp_packet();
79
80 rx_pkt_calc_lcrc=calculate_lcrc(rx_pkt,1,rx_pkt_size-5);
81
82 if((rx_pkt->get_byte(rx_pkt_size - 2) == rx_pkt_calc_lcrc.range(7,0)) &&
83 (rx_pkt->get_byte(rx_pkt_size - 3) == rx_pkt_calc_lcrc.range(15,8)) &&
84 (rx_pkt->get_byte(rx_pkt_size - 4) == rx_pkt_calc_lcrc.range(23,16)) &&
85 (rx_pkt->get_byte(rx_pkt_size - 5) == rx_pkt_calc_lcrc.range(31,24)))
86 {
87 LCRC_MATCHED = 1;
88 }
89 else {
90 LCRC_MATCHED = 0;
91 LOG_DEBUG << "_DLL_ : LCRC MIS-MATCH => Calculated: " << rx_pkt_calc_lcrc << " Received: " << rx_pkt->get_byte(rx_pkt_size-5) << rx_pkt->get_byte(rx_pkt_size-4) << rx_pkt->get_byte(rx_pkt_size-3) << rx_pkt->get_byte(rx_pkt_size-2);
92
93 sc_uint<64> peu_lnk_bit_err_cnt1 = csr_port.read_csr(PEU_CSR_A_LNK_BIT_ERR_CNT_1_HW_ADDR);
94 sc_uint<8> btc = peu_lnk_bit_err_cnt1.range(23,16);
95 if(btc!=ALLONES)
96 {
97 btc++;
98 peu_lnk_bit_err_cnt1.range(23,16) = btc;
99 csr_port.write_csr_mask(PEU_CSR_A_LNK_BIT_ERR_CNT_1_HW_ADDR,peu_lnk_bit_err_cnt1,PEU_CSR_LNK_BIT_ERR_CNT_1_READ_MASK);
100 }
101 }
102
103 if((rx_pkt->get_byte(rx_pkt_size-1)==EDB)){
104 LOG_DEBUG <<" _DLL_ : LCRC matches, but EDB is present. Discarding and sending NAK...";
105 EDB_DETECTED = 1;
106 }
107 else
108 EDB_DETECTED = 0;
109
110 LOG_DEBUG << "_DLL_ : rx_pkt_seq_num: " << rx_pkt_seq_num << " NEXT_RECEIVE_SEQ: " << NEXT_RECEIVE_SEQ ;
111
112 DO_NAK_SCHEDULED_CHECK = 0;
113 check_seq_num = (NEXT_RECEIVE_SEQ - rx_pkt_seq_num ); //% (sc_uint<12>)(4096) ;
114
115 tx_ack_nack_pkt = new pciePacket(6);
116 if(EDB_DETECTED){
117 if((rx_pkt->get_byte( rx_pkt_size - 2) == ~rx_pkt_calc_lcrc.range(7,0)) &&
118 (rx_pkt->get_byte( rx_pkt_size - 3) == ~rx_pkt_calc_lcrc.range(15,8)) &&
119 (rx_pkt->get_byte( rx_pkt_size - 4) == ~rx_pkt_calc_lcrc.range(23,16)) &&
120 (rx_pkt->get_byte( rx_pkt_size - 5) == ~rx_pkt_calc_lcrc.range(31,24)))
121 {
122 // Discard tlp
123 LOG_DEBUG << "EDB_DETECTED, LCRC LOGICAL NOT, seqnum: " << rx_pkt_seq_num ;
124 continue;
125 }
126 else {
127 DO_NAK_SCHEDULED_CHECK = 1;
128 LOG_DEBUG << "EDB_DETECTED, LCRC UNINVERTED, seqnum: " << rx_pkt_seq_num ;
129 }
130 }
131 else if(!LCRC_MATCHED){
132 DO_NAK_SCHEDULED_CHECK = 1;
133 LOG_DEBUG << "LCRC DID NOT MATCH. seqnum: " << rx_pkt_seq_num ;
134 }
135 else if(LCRC_MATCHED && !EDB_DETECTED && rx_pkt->get_control() != DLLP_NAK) {
136 LOG_DEBUG << "LCRC OK and NO EDB FOUND. seqnum: " << rx_pkt_seq_num ;
137
138 if(rx_pkt_seq_num == NEXT_RECEIVE_SEQ ){
139 LOG_DEBUG << "rx_pkt_seq_num == NEXT_RECEIVE_SEQ seqnum " << rx_pkt_seq_num ;
140
141 NEXT_RECEIVE_SEQ++;
142 queueTL.push(rx_pkt);
143 eventTlPktRdy.notify();
144
145 tx_pkt_seq_num=NEXT_RECEIVE_SEQ-1;
146 tx_ack_nack_pkt->set_control(SDP_CONTROL);
147 tx_ack_nack_pkt->modify_byte(0,DLLP_ACK);
148 tx_ack_nack_pkt->modify_byte(1,DATA0);
149 tx_ack_nack_pkt->modify_byte(2,tx_pkt_seq_num.range(11,8));
150 tx_ack_nack_pkt->modify_byte(3,tx_pkt_seq_num.range(7,0));
151 tx_pkt_dllp_crc=calculate_dllp_crc(tx_ack_nack_pkt,0,4);
152 tx_ack_nack_pkt->modify_byte(4,tx_pkt_dllp_crc.range(15,8));
153 tx_ack_nack_pkt->modify_byte(5,tx_pkt_dllp_crc.range(7,0));
154 //tx_ack_nack_pkt->pl2dll_display_sdp_packet(1);
155
156 queue_DLLP.push(tx_ack_nack_pkt);
157 eventPlPktRdy.notify();
158
159 NAK_SCHEDULED=0;
160 LOG_DEBUG << "CLEAR NAK SCHEDULED. seqnum: " << rx_pkt_seq_num ;
161 DO_NAK_SCHEDULED_CHECK = 0;
162 LOG_DEBUG << "Send ACK - rx_pkt_seq_num == NEXT_RECEIVE_SEQ " << rx_pkt_seq_num ;
163 }
164 //else if ( rx_pkt_seq_num < NEXT_RECEIVE_SEQ )
165 else {
166 if( ((NEXT_RECEIVE_SEQ-rx_pkt_seq_num)%4096) <= 2048 ) {
167 LOG_DEBUG << "(NEXT_RECEIVE_SEQ - rx_pkt_seq_num) mod 4096 smaller then 2048 seqnum " << rx_pkt_seq_num ;
168 NAK_SCHEDULED=0; //Why was this not there?
169 DO_NAK_SCHEDULED_CHECK = 0;
170
171 tx_pkt_seq_num=NEXT_RECEIVE_SEQ-1;
172 tx_ack_nack_pkt->set_control(SDP_CONTROL);
173 tx_ack_nack_pkt->modify_byte(0,DLLP_ACK);
174 tx_ack_nack_pkt->modify_byte(1,DATA0);
175 tx_ack_nack_pkt->modify_byte(2,tx_pkt_seq_num.range(11,8));
176 tx_ack_nack_pkt->modify_byte(3,tx_pkt_seq_num.range(7,0));
177 tx_pkt_dllp_crc=calculate_dllp_crc(tx_ack_nack_pkt,0,4);
178 tx_ack_nack_pkt->modify_byte(4,tx_pkt_dllp_crc.range(15,8));
179 tx_ack_nack_pkt->modify_byte(5,tx_pkt_dllp_crc.range(7,0));
180 //tx_ack_nack_pkt->pl2dll_display_sdp_packet(1);
181 queue_DLLP.push(tx_ack_nack_pkt);
182 eventPlPktRdy.notify();
183 LOG_DEBUG<<"Send ACK - rx_pkt_seq_num < NEXT_RECEIVE_SEQ " << rx_pkt_seq_num ;
184 }
185 else {
186 LOG_DEBUG<<"TLP Out of Sequence: Recvd: "<<rx_pkt_seq_num<<" NEXT_RECEIVE_SEQ: "<<NEXT_RECEIVE_SEQ<<" value: "<<check_seq_num ;
187 DO_NAK_SCHEDULED_CHECK = 1;
188 }
189 }
190 }
191 }
192 if(DO_NAK_SCHEDULED_CHECK)
193 {
194 LOG_DEBUG << "RAS: DO_NAK_SCHEDULED_CHECK seqnum " << rx_pkt_seq_num ;
195 if ( !NAK_SCHEDULED/* || rx_pkt->get_control() == DLLP_NAK*/)
196 {
197 LOG_DEBUG << "RAS: NAK SCHEDULED is CLEAR seqnum " << rx_pkt_seq_num ;
198
199 write_error_csr(CE,6,38,"btp");
200 ///////////////////////////////////////////
201 tx_ack_nack_pkt->set_control(SDP_CONTROL);
202 tx_pkt_seq_num=NEXT_RECEIVE_SEQ-1;
203 tx_ack_nack_pkt->modify_byte(0,DLLP_NAK);
204 tx_ack_nack_pkt->modify_byte(1,DATA0);
205 tx_ack_nack_pkt->modify_byte(2,tx_pkt_seq_num.range(11,8));
206 tx_ack_nack_pkt->modify_byte(3,tx_pkt_seq_num.range(7,0));
207
208 tx_pkt_dllp_crc=calculate_dllp_crc(tx_ack_nack_pkt,0,4);
209 tx_ack_nack_pkt->modify_byte(4,tx_pkt_dllp_crc.range(15,8));
210 tx_ack_nack_pkt->modify_byte(5,tx_pkt_dllp_crc.range(7,0));
211 //tx_ack_nack_pkt->pl2dll_display_sdp_packet(1);
212 queue_DLLP.push(tx_ack_nack_pkt);
213 eventPlPktRdy.notify();
214 LOG_DEBUG << " Send NAK - LCRC Mis-match and/or EDB caused by seqnum " << rx_pkt_seq_num ;
215
216 NAK_SCHEDULED = 1;
217 DO_NAK_SCHEDULED_CHECK = 0; //WHY was this not there?
218 }
219 }
220 else{
221 if(!NAK_SCHEDULED && rx_pkt->get_byte(0) == STP && rx_pkt->get_control() == DLLP_NAK){
222
223 write_error_csr(CE,0,32,"re");
224 byte_seq_num = rx_pkt->get_byte(1);
225 rx_pkt_seq_num.range(11,8)=byte_seq_num.range(3,0);
226 byte_seq_num = rx_pkt->get_byte(2);
227 rx_pkt_seq_num.range(7,0)=byte_seq_num.range(7,0);
228
229 LOG_WARNING << "DLL: Receive Error, seqnum: " << rx_pkt_seq_num << ", scheduling NAK... NEXT_RECEIVE_SEQ: "<<NEXT_RECEIVE_SEQ;
230
231 tx_ack_nack_pkt->set_control(SDP_CONTROL);
232 tx_pkt_seq_num=NEXT_RECEIVE_SEQ-1;
233 tx_ack_nack_pkt->modify_byte(0,DLLP_NAK);
234 tx_ack_nack_pkt->modify_byte(1,DATA0);
235 tx_ack_nack_pkt->modify_byte(2,tx_pkt_seq_num.range(11,8));
236 tx_ack_nack_pkt->modify_byte(3,tx_pkt_seq_num.range(7,0));
237
238 tx_pkt_dllp_crc=calculate_dllp_crc(tx_ack_nack_pkt,0,4);
239 tx_ack_nack_pkt->modify_byte(4,tx_pkt_dllp_crc.range(15,8));
240 tx_ack_nack_pkt->modify_byte(5,tx_pkt_dllp_crc.range(7,0));
241 //tx_ack_nack_pkt->pl2dll_display_sdp_packet(1);
242 queue_DLLP.push(tx_ack_nack_pkt);
243 eventPlPktRdy.notify();
244 NAK_SCHEDULED = 1;
245 }
246 else if(!NAK_SCHEDULED && rx_pkt->get_byte(0) == STP && rx_pkt->get_control() == DLLP_NAK_FRAMING){
247//rx_pkt_size = rx_pkt->get_size();
248//rx_pkt_calc_lcrc=calculate_lcrc(rx_pkt,1,rx_pkt_size-5);
249 write_error_csr(OE,11,11,"lin");
250 byte_seq_num = rx_pkt->get_byte(1);
251 rx_pkt_seq_num.range(11,8)=byte_seq_num.range(3,0);
252 byte_seq_num = rx_pkt->get_byte(2);
253 rx_pkt_seq_num.range(7,0)=byte_seq_num.range(7,0);
254
255 LOG_WARNING << "DLL: Framing Receive Error, seqnum: " << rx_pkt_seq_num << ", scheduling NAK... NEXT_RECEIVE_SEQ: "<<NEXT_RECEIVE_SEQ;
256
257 tx_ack_nack_pkt->set_control(SDP_CONTROL);
258 tx_pkt_seq_num=NEXT_RECEIVE_SEQ-1;
259 tx_ack_nack_pkt->modify_byte(0,DLLP_NAK);
260 tx_ack_nack_pkt->modify_byte(1,DATA0);
261 tx_ack_nack_pkt->modify_byte(2,tx_pkt_seq_num.range(11,8));
262 tx_ack_nack_pkt->modify_byte(3,tx_pkt_seq_num.range(7,0));
263
264 tx_pkt_dllp_crc=calculate_dllp_crc(tx_ack_nack_pkt,0,4);
265 tx_ack_nack_pkt->modify_byte(4,tx_pkt_dllp_crc.range(15,8));
266 tx_ack_nack_pkt->modify_byte(5,tx_pkt_dllp_crc.range(7,0));
267 //tx_ack_nack_pkt->pl2dll_display_sdp_packet(1);
268 queue_DLLP.push(tx_ack_nack_pkt);
269 eventPlPktRdy.notify();
270 NAK_SCHEDULED = 1;
271 }
272 }
273
274
275 // DLLP Processing
276 if ( rx_pkt->get_byte(0) == SDP )
277 {
278 if((rx_pkt->get_byte(1) == DLLP_ACK )||(rx_pkt->get_byte(1) == DLLP_NAK))
279 time_last_ack_nak_received = dll_timer;
280
281 //cout << sc_time_stamp() << " DLL: Received DLLP " << rx_pkt->getPacketId() << " from PL." << endl;
282 //rx_pkt->pl2dll_display_sdp_packet(0);
283
284 if ( (rx_pkt->get_byte(1) != DLLP_ACK ) &&
285 (rx_pkt->get_byte(1) != DLLP_NAK ) &&
286 (rx_pkt->get_byte(1) != DLLP_PM_ENTER_L1 ) &&
287 (rx_pkt->get_byte(1) != DLLP_PM_ENTER_L23 ) &&
288 (rx_pkt->get_byte(1) != DLLP_PM_ACT_SR_L1 ) &&
289 (rx_pkt->get_byte(1) != DLLP_PM_REQ_ACK ) &&
290 (rx_pkt->get_byte(1) != DLLP_VENDOR ) &&
291 (rx_pkt->get_byte(1).range(7,3) != DLLP_INITFC1_P_NOVC ) &&
292 (rx_pkt->get_byte(1).range(7,3) != DLLP_INITFC1_NP_NOVC ) &&
293 (rx_pkt->get_byte(1).range(7,3) != DLLP_INITFC1_CPL_NOVC ) &&
294 (rx_pkt->get_byte(1).range(7,3) != DLLP_INITFC2_P_NOVC ) &&
295 (rx_pkt->get_byte(1).range(7,3) != DLLP_INITFC2_NP_NOVC ) &&
296 (rx_pkt->get_byte(1).range(7,3) != DLLP_INITFC2_CPL_NOVC ) &&
297 (rx_pkt->get_byte(1).range(7,3) != DLLP_UPDATEFC_P_NOVC ) &&
298 (rx_pkt->get_byte(1).range(7,3) != DLLP_UPDATEFC_NP_NOVC ) &&
299 (rx_pkt->get_byte(1).range(7,3) != DLLP_UPDATEFC_CPL_NOVC )
300 )
301 {
302 write_error_csr2(OE,2,2,"xxx");
303 }
304 else if(rx_pkt->get_byte(rx_pkt->get_size() - 1) == EDB){
305 LOG_DEBUG << "SDP PKT with EDB";
306 }
307 else {
308 SDP_byte1=rx_pkt->get_byte(1);
309 SDP_byte2=rx_pkt->get_byte(2);
310 SDP_byte3=rx_pkt->get_byte(3);
311 SDP_byte4=rx_pkt->get_byte(4);
312 SDP_byte5=rx_pkt->get_byte(5);
313 SDP_byte6=rx_pkt->get_byte(6);
314
315 if ( SDP_byte1.range(7,4) == 0 )
316 {
317 rx_pkt_seq_num.range(11,8) = SDP_byte3.range(3,0);
318 rx_pkt_seq_num.range(7,0) = SDP_byte4.range(7,0);
319 }
320
321 if ( SDP_byte1 == DLLP_NAK ) {
322 rx_pkt_seq_num.range(11,8) = SDP_byte3.range(3,0);
323 rx_pkt_seq_num.range(7,0) = SDP_byte4.range(7,0);
324 LOG_DEBUG << "REPLAY_BUFFER: Received NAK with seqid = " << rx_pkt_seq_num ;
325 //buffer_replay_single(rx_pkt_seq_num);
326 buffer_replay(rx_pkt_seq_num);
327 ACKD_SEQ=rx_pkt_seq_num;
328 }
329
330 // if ACK, then remove the corresponding TLP entry in the retry buffer
331 if ( SDP_byte1 == DATA0 ) {
332 rx_pkt_seq_num.range(11,8)=SDP_byte3.range(3,0);
333 rx_pkt_seq_num.range(7,0)=SDP_byte4.range(7,0);
334 LOG_DEBUG << "REPLAY_BUFFER: Received ACK with seqid = " << rx_pkt_seq_num ;
335 buffer_remove(rx_pkt_seq_num);
336 REPLAY_NUM=0;
337 REPLAY_TIMER=0;
338 ACKD_SEQ=rx_pkt_seq_num;
339 }
340
341 rx_pkt_dllp_crc.range(15,8)=SDP_byte5.range(7,0);
342 rx_pkt_dllp_crc.range(7,0)=SDP_byte6.range(7,0);
343
344 if ( rx_pkt_dllp_crc != calculate_dllp_crc(rx_pkt,1,5) ) {
345 LOG_DEBUG << " _DLL_: DLLP CRC MIS-MATCH : Calculated DLLP CRC " << calculate_dllp_crc(rx_pkt,1,5) << " Received DLLP CRC" << rx_pkt_dllp_crc ;
346 write_error_csr(CE,7,39,"bdp");
347 sc_uint<64> peu_lnk_bit_err_cnt1 = csr_port.read_csr(PEU_CSR_A_LNK_BIT_ERR_CNT_1_HW_ADDR);
348 sc_uint<8> bdc = peu_lnk_bit_err_cnt1.range(31,24);
349 if(bdc!=ALLONES) {
350 bdc++;
351 peu_lnk_bit_err_cnt1.range(31,24) = bdc;
352 csr_port.write_csr_mask(PEU_CSR_A_LNK_BIT_ERR_CNT_1_HW_ADDR,peu_lnk_bit_err_cnt1,PEU_CSR_LNK_BIT_ERR_CNT_1_READ_MASK);
353 }
354 continue;
355 }
356 else {
357 HdrFC.range(7,2)=SDP_byte2.range(5,0);
358 HdrFC.range(1,0)=SDP_byte3.range(7,6);
359
360 DataFC.range(11,8)=SDP_byte3.range(3,0);
361 DataFC.range(7,0)=SDP_byte4;
362
363 sc_uint<64> peu_diag_csr = csr_port.read_csr(PEU_CSR_A_TLU_DIAG_HW_ADDR);
364
365 tlu_ecc_hw_reg = csr_port.read_csr(PEU_CSR_A_TLU_ECC_HW_ADDR);
366 tlu_ecl_hw_reg = csr_port.read_csr(PEU_CSR_A_TLU_ECL_HW_ADDR);
367 LOG_DEBUG << "ECL: " << tlu_ecl_hw_reg << " ECC: " << tlu_ecc_hw_reg ;
368
369 sc_uint<64> old_ecc = tlu_ecc_hw_reg;
370
371 switch(SDP_byte1.range(7,4)){
372 case 4: // init fc1 p
373 if ( (HdrFC== 0 ) )
374 tlu_ecc_hw_reg.range(60,60) = 1;
375 else
376 tlu_ecc_hw_reg.range(60,60) = 0;
377
378 if ( (DataFC== 0 ) )
379 tlu_ecl_hw_reg.range(60,60) = 1;
380 else
381 tlu_ecl_hw_reg.range(60,60) = 0;
382
383 tlu_ecl_hw_reg.range(19,12) = HdrFC;
384 tlu_ecl_hw_reg.range(11,0) = DataFC;
385
386 LOG_DEBUG << " initfc1P ABOUT TO UPDATE ECL with HDR " << HdrFC << " DataFC " << DataFC << " tlu_ecl_hw_reg " << tlu_ecl_hw_reg;
387 LOG_DEBUG << " initfc1P ABOUT TO UPDATE ECC with HDR " << HdrFC << " DataFC " << DataFC << " tlu_ecc_hw_reg " << tlu_ecc_hw_reg;
388 csr_port.write_csr(PEU_CSR_A_TLU_ECL_HW_ADDR,tlu_ecl_hw_reg);
389 if(old_ecc!=tlu_ecc_hw_reg) csr_port.write_csr(PEU_CSR_A_TLU_ECC_HW_ADDR,tlu_ecc_hw_reg);
390 break;
391
392 case 5: // init fc1 np
393 if ( (HdrFC== 0 ) )
394 tlu_ecc_hw_reg.range(61,61) = 1;
395 else
396 tlu_ecc_hw_reg.range(61,61) = 0;
397
398 if ( (DataFC== 0 ) )
399 tlu_ecl_hw_reg.range(61,61) = 1;
400 else
401 tlu_ecl_hw_reg.range(61,61) = 0;
402
403 tlu_ecl_hw_reg.range(39,32) = HdrFC;
404 tlu_ecl_hw_reg.range(31,20) = DataFC;
405
406 LOG_DEBUG << " initfc1NP ABOUT TO UPDATE ECL with HDR " << HdrFC << " DataFC " << DataFC << " tlu_ecl_hw_reg " << tlu_ecl_hw_reg;
407 LOG_DEBUG << " initfc1NP ABOUT TO UPDATE ECC with HDR " << HdrFC << " DataFC " << DataFC << " tlu_ecc_hw_reg " << tlu_ecc_hw_reg;
408 csr_port.write_csr(PEU_CSR_A_TLU_ECL_HW_ADDR,tlu_ecl_hw_reg);
409 if(old_ecc!=tlu_ecc_hw_reg) csr_port.write_csr(PEU_CSR_A_TLU_ECC_HW_ADDR,tlu_ecc_hw_reg);
410 break;
411
412 case 6: // init fc1 cpl
413 if ( (HdrFC== 0 ) )
414 tlu_ecc_hw_reg.range(62,62) = 1;
415 else
416 tlu_ecc_hw_reg.range(62,62) = 0;
417
418 if ( (DataFC== 0 ) )
419 tlu_ecl_hw_reg.range(62,62) = 1;
420 else
421 tlu_ecl_hw_reg.range(62,62) = 0;
422
423 tlu_ecl_hw_reg.range(59,52) = HdrFC;
424 tlu_ecl_hw_reg.range(51,40) = DataFC;
425
426 LOG_DEBUG << " initfc1CMPL ABOUT TO UPDATE ECL with HDR " << HdrFC << " DataFC " << DataFC << " tlu_ecl_hw_reg " << tlu_ecl_hw_reg;
427 LOG_DEBUG << " initfc1CMPL ABOUT TO UPDATE ECC with HDR " << HdrFC << " DataFC " << DataFC << " tlu_ecc_hw_reg " << tlu_ecc_hw_reg;
428 csr_port.write_csr(PEU_CSR_A_TLU_ECL_HW_ADDR,tlu_ecl_hw_reg);
429 if(old_ecc!=tlu_ecc_hw_reg) csr_port.write_csr(PEU_CSR_A_TLU_ECC_HW_ADDR,tlu_ecc_hw_reg);
430 break;
431
432 case 12: // init fc2 p
433 if ( (HdrFC== 0 ) )
434 tlu_ecc_hw_reg.range(60,60) = 1;
435 else
436 tlu_ecc_hw_reg.range(60,60) = 0;
437
438 if ( (DataFC== 0 ) )
439 tlu_ecl_hw_reg.range(60,60) = 1;
440 else
441 tlu_ecl_hw_reg.range(60,60) = 0;
442
443 tlu_ecl_hw_reg.range(19,12) = HdrFC;
444 tlu_ecl_hw_reg.range(11,0) = DataFC;
445
446 LOG_DEBUG << " initfc2P ABOUT TO UPDATE ECL with HDR " << HdrFC << " DataFC " << DataFC << " tlu_ecl_hw_reg " << tlu_ecl_hw_reg;
447 LOG_DEBUG << " initfc2P ABOUT TO UPDATE ECC with HDR " << HdrFC << " DataFC " << DataFC << " tlu_ecc_hw_reg " << tlu_ecc_hw_reg;
448 csr_port.write_csr(PEU_CSR_A_TLU_ECL_HW_ADDR,tlu_ecl_hw_reg);
449 if(old_ecc!=tlu_ecc_hw_reg) csr_port.write_csr(PEU_CSR_A_TLU_ECC_HW_ADDR,tlu_ecc_hw_reg);
450 break;
451
452 case 13: // init fc2 np
453 if ( (HdrFC== 0 ) )
454 tlu_ecc_hw_reg.range(61,61) = 1;
455 else
456 tlu_ecc_hw_reg.range(61,61) = 0;
457
458 if ( (DataFC== 0 ) )
459 tlu_ecl_hw_reg.range(61,61) = 1;
460 else
461 tlu_ecl_hw_reg.range(61,61) = 0;
462
463 tlu_ecl_hw_reg.range(39,32) = HdrFC;
464 tlu_ecl_hw_reg.range(31,20) = DataFC;
465
466 LOG_DEBUG << " initfc2NP ABOUT TO UPDATE ECL with HDR " << HdrFC << " DataFC " << DataFC << " tlu_ecl_hw_reg " << tlu_ecl_hw_reg;
467 LOG_DEBUG << " initfc2NP ABOUT TO UPDATE ECC with HDR " << HdrFC << " DataFC " << DataFC << " tlu_ecc_hw_reg " << tlu_ecc_hw_reg;
468 csr_port.write_csr(PEU_CSR_A_TLU_ECL_HW_ADDR,tlu_ecl_hw_reg);
469 if(old_ecc!=tlu_ecc_hw_reg) csr_port.write_csr(PEU_CSR_A_TLU_ECC_HW_ADDR,tlu_ecc_hw_reg);
470 break;
471
472 case 14: // init fc2 cpl
473 if ( (HdrFC== 0 ) )
474 tlu_ecc_hw_reg.range(62,62) = 1;
475 else
476 tlu_ecc_hw_reg.range(62,62) = 0;
477
478 if ( (DataFC== 0 ) )
479 tlu_ecl_hw_reg.range(62,62) = 1;
480 else
481 tlu_ecl_hw_reg.range(62,62) = 0;
482
483 tlu_ecl_hw_reg.range(59,52) = HdrFC;
484 tlu_ecl_hw_reg.range(51,40) = DataFC;
485
486 LOG_DEBUG << " initfc2CMPL ABOUT TO UPDATE ECL with HDR " << HdrFC << " DataFC " << DataFC << " tlu_ecl_hw_reg " << tlu_ecl_hw_reg;
487 LOG_DEBUG << " initfc2CMPL ABOUT TO UPDATE ECC with HDR " << HdrFC << " DataFC " << DataFC << " tlu_ecc_hw_reg " << tlu_ecc_hw_reg;
488
489 csr_port.write_csr(PEU_CSR_A_TLU_ECL_HW_ADDR,tlu_ecl_hw_reg);
490 if(old_ecc!=tlu_ecc_hw_reg) csr_port.write_csr(PEU_CSR_A_TLU_ECC_HW_ADDR,tlu_ecc_hw_reg);
491 break;
492
493 case 8: // update p
494 if( (HdrFC!=0 && tlu_ecc_hw_reg.range(60,60)==1) ||
495 (DataFC!=0 && tlu_ecl_hw_reg.range(60,60)==1)) {
496 //Infinite credit update has arrived
497 LOG_DEBUG << "Warning: P Infinite credit update error...";
498 LOG_DEBUG << "HdrFC= " << HdrFC << " DataFC= " << DataFC << " PHI= " << tlu_ecc_hw_reg.range(60,60) << " PDI= " << tlu_ecl_hw_reg.range(60,60);
499
500 write_error_csr(UE,13,45,"fcp");
501 // } else if(((HdrFC-tlu_ecl_hw_reg(19,12))%256)>128 || ((DataFC-tlu_ecl_hw_reg(11,0))%4096)>2048){
502 // LOG_DEBUG << "Warning: UpdateFC_P has HdrFC>128 or DataFC>2048. HdrFC: " << HdrFC << " DataFC: " << DataFC ;
503 // write_error_csr(UE,13,45,"fcp");
504 } else {
505 tlu_ecl_hw_reg.range(19,12) = HdrFC;
506 tlu_ecl_hw_reg.range(11,0) = DataFC;
507 LOG_DEBUG << " P UpdateFC ABOUT TO UPDATE ECL with HDR " << HdrFC << " DataFC " << DataFC << " tlu_ecl_hw_reg " << tlu_ecl_hw_reg;
508 csr_port.write_csr(PEU_CSR_A_TLU_ECL_HW_ADDR,tlu_ecl_hw_reg);
509 }
510 break;
511 case 9: // update np
512 if( (HdrFC!=0 && tlu_ecc_hw_reg.range(61,61)==1) ||
513 (DataFC!=0 && tlu_ecl_hw_reg.range(61,61)==1)) {
514 //Infinite credit update has arrived
515 LOG_DEBUG << "Warning: NP Infinite credit update error...";
516 LOG_DEBUG << "HdrFC= " << HdrFC << " DataFC= " << DataFC << " NHI= " << tlu_ecc_hw_reg.range(61,61) << " NDI= " << tlu_ecl_hw_reg.range(61,61);
517 write_error_csr(UE,13,45,"fcp");
518 // } else if(((HdrFC-tlu_ecl_hw_reg(39,32))%256)>128 || ((DataFC-tlu_ecl_hw_reg(31,20))%4096)>2048){
519 // LOG_DEBUG << "Warning: UpdateFC_NP has HdrFC>128 or DataFC>2048. HdrFC: " << HdrFC << " DataFC: " << DataFC ;
520 // write_error_csr(UE,13,45,"fcp");
521 } else {
522 tlu_ecl_hw_reg.range(39,32) = HdrFC;
523 tlu_ecl_hw_reg.range(31,20) = DataFC;
524 LOG_DEBUG << " NP UpdateFC ABOUT TO UPDATE ECL with HDR " << HdrFC << " DataFC " << DataFC << " tlu_ecl_hw_reg " << tlu_ecl_hw_reg;
525 csr_port.write_csr(PEU_CSR_A_TLU_ECL_HW_ADDR,tlu_ecl_hw_reg);
526 }
527 break;
528 case 10: // update cpl
529 if( (HdrFC!=0 && tlu_ecc_hw_reg.range(62,62)==1) ||
530 (DataFC!=0 && tlu_ecl_hw_reg.range(62,62)==1)) {
531 //Infinite credit update has arrived
532 LOG_DEBUG << "Warning: CMPL Infinite credit update error...";
533 LOG_DEBUG << "HdrFC= " << HdrFC << " DataFC= " << DataFC << " CHI= " << tlu_ecc_hw_reg.range(62,62) << " CDI= " << tlu_ecl_hw_reg.range(62,62);
534 write_error_csr(UE,13,45,"fcp");
535
536 // } else if((((sc_uint<8>)HdrFC-tlu_ecl_hw_reg(59,52))%256)>128 || (((sc_uint<12>)DataFC-tlu_ecl_hw_reg(51,40))%4096)>2048){
537 // LOG_DEBUG << "Warning: UpdateFC_CMPL has HdrFC>128 or DataFC>2048. HdrFC: " << HdrFC << " DataFC: " << DataFC ;
538 // write_error_csr(UE,13,45,"fcp");
539 } else {
540 tlu_ecl_hw_reg.range(59,52) = HdrFC;
541 tlu_ecl_hw_reg.range(51,40) = DataFC;
542 LOG_DEBUG << " CMPL UpdateFC ABOUT TO UPDATE ECL with HDR " << HdrFC << " DataFC " << DataFC << " tlu_ecl_hw_reg " << tlu_ecl_hw_reg;
543 csr_port.write_csr(PEU_CSR_A_TLU_ECL_HW_ADDR,tlu_ecl_hw_reg);
544 }
545 break;
546 default: //Added to capture the unsupport DLLPs
547 LOG_DEBUG << " _DLLP_ : Unsupported DLLP recvd. Drop and ignore.";
548 break;
549 }
550 } // if(CRC matches)
551 } // if DLLP_INVALID
552 }// if(SDP)
553
554 // Check FCINIT1 packets for vc0
555 if ( rx_pkt->get_byte(1) == DLLP_INITFC1_P )
556 {
557 LOG_DEBUG << "_DLL_ : ------------ Received initfc1_p from PL";
558 Flag_FC1_P = 1;
559 fc_init1_complete_ev.notify();
560 }
561 if ( rx_pkt->get_byte(1) == DLLP_INITFC1_NP )
562 {
563 LOG_DEBUG << "_DLL_: ------------ Received initfc1_np from PL" ;
564 Flag_FC1_NP = 1;
565 }
566 if ( rx_pkt->get_byte(1) == DLLP_INITFC1_CPL )
567 {
568 LOG_DEBUG << "_DLL_ : ------------ Received initfc1_cpl from PL";
569 Flag_FC1_CPL = 1;
570 }
571
572 if ( (Flag_FC1_P & Flag_FC1_NP & Flag_FC1_CPL) && !Flag_FC1 ){
573 Flag_FC1 = 1;
574 }
575
576 if ( Flag_FC1 && // we are in fcinit2
577 ( ( rx_pkt->get_byte(1) == DLLP_INITFC2_P ) || // any dllp packet sets fI2
578 ( rx_pkt->get_byte(1) == DLLP_INITFC2_NP ) ||
579 ( rx_pkt->get_byte(1) == DLLP_INITFC2_CPL ) ||
580 ( rx_pkt->get_byte(1) == DLLP_UPDATEFC_CPL ) || // any updatefc sets fI2
581 ( rx_pkt->get_byte(1) == DLLP_UPDATEFC_NP ) ||
582 ( rx_pkt->get_byte(1) == DLLP_UPDATEFC_P ) ) )
583 {
584 Flag_FC2 = 1;
585 fc_init2_complete_ev.notify();
586 }
587 }//end while
588 }//end try
589 catch(sc_exception &e){
590 LOG_DEBUG<<"DLL: Out of pl_consumer";
591 }
592 }
593
594
595 void dll_top::write_error_csr(uint8 err_type, uint8 primary, uint8 secondary, char field_name[3]){
596 sc_uint<64> orig_csr_val;
597 sc_uint<64> new_csr_val=0;
598
599 LOG_DEBUG << "Setting err bit: " << field_name;
600
601 switch(err_type){
602 case OE: orig_csr_val = csr_port.read_csr(PEU_CSR_A_OE_ERR_RW1C_ALIAS_HW_ADDR);
603 LOG_DEBUG << "Updating OE CSR (orig val: " << orig_csr_val << ")";
604 break;
605 case UE: orig_csr_val = csr_port.read_csr(PEU_CSR_A_UE_ERR_RW1C_ALIAS_HW_ADDR);
606 LOG_DEBUG << "Updating UE CSR (orig val: " << orig_csr_val << ")";
607 break;
608 case CE: orig_csr_val = csr_port.read_csr(PEU_CSR_A_CE_ERR_RW1C_ALIAS_HW_ADDR);
609 LOG_DEBUG << "Updating CE CSR (orig val: " << orig_csr_val << ")";
610 break;
611 default: LOG_ERROR << "Warning: undefined error type!";
612 return;
613 }
614
615 if(orig_csr_val.range(primary,primary)!=1)
616 new_csr_val.range(primary,primary)=1;
617 else if(orig_csr_val.range(secondary,secondary)!=1)
618 new_csr_val.range(secondary,secondary)=1;
619 else
620 LOG_DEBUG << "Warning: Both PRIMARY and SECONDARY of " << field_name << "are set.";
621
622 switch(err_type){
623 case OE: csr_port.write_csr(PEU_CSR_A_OE_ERR_RW1S_ALIAS_HW_ADDR,new_csr_val);
624 LOG_DEBUG << "Updating OE CSR (new val : " << new_csr_val << ")";
625 break;
626 case UE: csr_port.write_csr(PEU_CSR_A_UE_ERR_RW1S_ALIAS_HW_ADDR,new_csr_val);
627 LOG_DEBUG << "Updating UE CSR (new val : " << new_csr_val << ")";
628 break;
629 case CE: csr_port.write_csr(PEU_CSR_A_CE_ERR_RW1S_ALIAS_HW_ADDR,new_csr_val);
630 LOG_DEBUG << "Updating CE CSR (new val : " << new_csr_val << ")";
631 break;
632 }
633 return;
634 }//end write_csr_error
635
636 void dll_top::write_error_csr2(uint8 err_type, uint8 primary, uint8 secondary, char field_name[3]){
637 sc_uint<64> orig_csr_val;
638 sc_uint<64> new_csr_val=0;
639
640 LOG_DEBUG << "Setting err bit: " << field_name;
641
642 switch(err_type){
643 case OE: orig_csr_val = csr_port.read_csr( PEU_CSR_A_EVENT_ERR_STS_CLR_RW1C_ALIAS_HW_ADDR );
644 LOG_DEBUG << "Updating OE CSR (orig val: " << orig_csr_val << ")";
645 break;
646 case UE: orig_csr_val = csr_port.read_csr(PEU_CSR_A_EVENT_ERR_STS_CLR_RW1C_ALIAS_HW_ADDR);
647 LOG_DEBUG << "Updating UE CSR (orig val: " << orig_csr_val << ")";
648 break;
649 case CE: orig_csr_val = csr_port.read_csr(PEU_CSR_A_EVENT_ERR_STS_CLR_RW1C_ALIAS_HW_ADDR);
650 LOG_DEBUG << "Updating CE CSR (orig val: " << orig_csr_val << ")";
651 break;
652 default: LOG_ERROR << "Warning: undefined error type!";
653 return;
654 }
655
656 if(orig_csr_val.range(primary,primary)!=1)
657 new_csr_val.range(primary,primary)=1;
658 else if(orig_csr_val.range(secondary,secondary)!=1)
659 new_csr_val.range(secondary,secondary)=1;
660 else
661 LOG_DEBUG << "Warning: Both PRIMARY and SECONDARY of " << field_name << "are set.";
662
663 switch(err_type){
664 case OE: csr_port.write_csr(PEU_CSR_A_EVENT_ERR_STS_CLR_RW1C_ALIAS_HW_ADDR,new_csr_val);
665 LOG_DEBUG << "Updating OE CSR (new val : " << new_csr_val << ")";
666 break;
667 case UE: csr_port.write_csr(PEU_CSR_A_EVENT_ERR_STS_CLR_RW1C_ALIAS_HW_ADDR,new_csr_val);
668 LOG_DEBUG << "Updating UE CSR (new val : " << new_csr_val << ")";
669 break;
670 case CE: csr_port.write_csr(PEU_CSR_A_EVENT_ERR_STS_CLR_RW1C_ALIAS_HW_ADDR,new_csr_val);
671 LOG_DEBUG << "Updating CE CSR (new val : " << new_csr_val << ")";
672 break;
673 }
674 return;
675 }//end write_csr_error
676}