Changeset 799
- Timestamp:
- Sep 9, 2014, 6:40:02 PM (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/modules/vci_mem_cache/caba/source/src/vci_mem_cache.cpp
r789 r799 330 330 331 331 tmpl(/**/)::VciMemCache( 332 sc_module_name name,333 const MappingTable &mtp,// mapping table for direct network334 const MappingTable &mtx,// mapping table for external network335 const IntTab &srcid_x,// global index on external network336 const IntTab &tgtid_d,// global index on direct network337 const size_t x_width,// number of x bits in platform338 const size_t y_width,// number of x bits in platform339 const size_t nways,// number of ways per set340 const size_t nsets,// number of associative sets341 const size_t nwords,// number of words in cache line342 const size_t max_copies,// max number of copies in heap343 const size_t heap_size,// number of heap entries344 const size_t trt_lines,// number of TRT entries345 const size_t upt_lines,// number of UPT entries346 const size_t ivt_lines,// number of IVT entries347 const size_t debug_start_cycle,348 const bool debug_ok)332 sc_module_name name, 333 const MappingTable &mtp, // mapping table for direct network 334 const MappingTable &mtx, // mapping table for external network 335 const IntTab &srcid_x, // global index on external network 336 const IntTab &tgtid_d, // global index on direct network 337 const size_t x_width, // number of x bits in platform 338 const size_t y_width, // number of x bits in platform 339 const size_t nways, // number of ways per set 340 const size_t nsets, // number of associative sets 341 const size_t nwords, // number of words in cache line 342 const size_t max_copies, // max number of copies in heap 343 const size_t heap_size, // number of heap entries 344 const size_t trt_lines, // number of TRT entries 345 const size_t upt_lines, // number of UPT entries 346 const size_t ivt_lines, // number of IVT entries 347 const size_t debug_start_cycle, 348 const bool debug_ok) 349 349 350 350 : soclib::caba::BaseModule(name), 351 351 352 p_clk( "p_clk"),353 p_resetn( "p_resetn"),354 p_irq ( "p_irq"),355 p_vci_tgt( "p_vci_tgt"),356 p_vci_ixr( "p_vci_ixr"),357 p_dspin_p2m( "p_dspin_p2m"),358 p_dspin_m2p( "p_dspin_m2p"),359 p_dspin_clack( "p_dspin_clack"),352 p_clk("p_clk"), 353 p_resetn("p_resetn"), 354 p_irq ("p_irq"), 355 p_vci_tgt("p_vci_tgt"), 356 p_vci_ixr("p_vci_ixr"), 357 p_dspin_p2m("p_dspin_p2m"), 358 p_dspin_m2p("p_dspin_m2p"), 359 p_dspin_clack("p_dspin_clack"), 360 360 361 361 m_seglist(mtp.getSegmentList(tgtid_d)), 362 362 m_nseg(0), 363 m_srcid_x( mtx.indexForId(srcid_x)),363 m_srcid_x(mtx.indexForId(srcid_x)), 364 364 m_initiators(1 << vci_param_int::S), 365 365 m_heap_size(heap_size), … … 394 394 395 395 // CONFIG interface 396 m_config_addr_mask((1 <<12)-1),396 m_config_addr_mask((1 << 12) - 1), 397 397 398 398 m_config_regr_width(7), 399 399 m_config_func_width(3), 400 m_config_regr_idx_mask((1 <<m_config_regr_width)-1),401 m_config_func_idx_mask((1 <<m_config_func_width)-1),400 m_config_regr_idx_mask((1 << m_config_regr_width) - 1), 401 m_config_func_idx_mask((1 << m_config_func_width) - 1), 402 402 403 403 // FIFOs … … 428 428 r_tgt_cmd_fsm("r_tgt_cmd_fsm"), 429 429 430 r_config_fsm( "r_config_fsm"),431 432 m_config_to_cc_send_inst_fifo( "m_config_to_cc_send_inst_fifo", 8),433 m_config_to_cc_send_srcid_fifo( "m_config_to_cc_send_srcid_fifo", 8),434 435 r_read_fsm( "r_read_fsm"),436 437 r_write_fsm( "r_write_fsm"),430 r_config_fsm("r_config_fsm"), 431 432 m_config_to_cc_send_inst_fifo("m_config_to_cc_send_inst_fifo", 8), 433 m_config_to_cc_send_srcid_fifo("m_config_to_cc_send_srcid_fifo", 8), 434 435 r_read_fsm("r_read_fsm"), 436 437 r_write_fsm("r_write_fsm"), 438 438 439 439 m_write_to_cc_send_inst_fifo("m_write_to_cc_send_inst_fifo",8), … … 471 471 #if MONITOR_MEMCACHE_FSM == 1 472 472 , 473 p_read_fsm("p_read_fsm"), 474 p_write_fsm("p_write_fsm"), 475 p_xram_rsp_fsm("p_xram_rsp_fsm"), 476 p_cas_fsm("p_cas_fsm"), 477 p_cleanup_fsm("p_cleanup_fsm"), 478 p_config_fsm("p_config_fsm"), 479 p_alloc_heap_fsm("p_alloc_heap_fsm"), 480 p_alloc_dir_fsm("p_alloc_dir_fsm"), 481 p_alloc_trt_fsm("p_alloc_trt_fsm"), 482 p_alloc_upt_fsm("p_alloc_upt_fsm"), 483 p_alloc_ivt_fsm("p_alloc_ivt_fsm"), 484 p_tgt_cmd_fsm("p_tgt_cmd_fsm"), 485 p_tgt_rsp_fsm("p_tgt_rsp_fsm"), 486 p_ixr_cmd_fsm("p_ixr_cmd_fsm"), 487 p_ixr_rsp_fsm("p_ixr_rsp_fsm"), 488 p_cc_send_fsm("p_cc_send_fsm"), 473 p_read_fsm("p_read_fsm"), 474 p_write_fsm("p_write_fsm"), 475 p_xram_rsp_fsm("p_xram_rsp_fsm"), 476 p_cas_fsm("p_cas_fsm"), 477 p_cleanup_fsm("p_cleanup_fsm"), 478 p_config_fsm("p_config_fsm"), 479 p_alloc_heap_fsm("p_alloc_heap_fsm"), 480 p_alloc_dir_fsm("p_alloc_dir_fsm"), 481 p_alloc_trt_fsm("p_alloc_trt_fsm"), 482 p_alloc_upt_fsm("p_alloc_upt_fsm"), 483 p_alloc_ivt_fsm("p_alloc_ivt_fsm"), 484 p_tgt_cmd_fsm("p_tgt_cmd_fsm"), 485 p_tgt_rsp_fsm("p_tgt_rsp_fsm"), 486 p_ixr_cmd_fsm("p_ixr_cmd_fsm"), 487 p_ixr_rsp_fsm("p_ixr_rsp_fsm"), 488 p_cc_send_fsm("p_cc_send_fsm"), 489 489 p_cc_receive_fsm("p_cc_receive_fsm"), 490 490 p_multi_ack_fsm("p_multi_ack_fsm") … … 505 505 506 506 // check internal and external data width 507 assert( (vci_param_int::B == 4) and507 assert((vci_param_int::B == 4) and 508 508 "MEMC ERROR : VCI internal data width must be 32 bits"); 509 509 510 assert( (vci_param_ext::B == 8) and510 assert((vci_param_ext::B == 8) and 511 511 "MEMC ERROR : VCI external data width must be 64 bits"); 512 512 513 513 // Check coherence between internal & external addresses 514 assert( (vci_param_int::N == vci_param_ext::N) and514 assert((vci_param_int::N == vci_param_ext::N) and 515 515 "MEMC ERROR : VCI internal & external addresses must have the same width"); 516 516 … … 527 527 } 528 528 529 assert( (m_nseg > 0) and529 assert((m_nseg > 0) and 530 530 "MEMC ERROR : At least one segment must be mapped to this component"); 531 531 … … 534 534 for (seg = m_seglist.begin(); seg != m_seglist.end(); seg++) 535 535 { 536 if (seg->special() ) m_seg_config = i;536 if (seg->special()) m_seg_config = i; 537 537 m_seg[i] = & (*seg); 538 538 i++; … … 587 587 size_t way = 0; 588 588 size_t set = 0; 589 size_t word = ((size_t) addr & 0x3F) >> 2;590 589 size_t word = ((size_t) addr & 0x3F) >> 2; 590 591 591 DirectoryEntry entry = m_cache_directory.read_neutral(addr, &way, &set); 592 592 … … 595 595 if (entry.valid) 596 596 { 597 if (single_word )597 if (single_word) 598 598 { 599 599 m_debug_data[word] = m_cache_data.read(way, set, word); 600 if ( m_debug_previous_valid and601 (m_debug_data[word] != m_debug_previous_data[word]) )600 if (m_debug_previous_valid and 601 (m_debug_data[word] != m_debug_previous_data[word])) 602 602 { 603 603 data_change = true; … … 609 609 { 610 610 m_debug_data[wcur] = m_cache_data.read(way, set, wcur); 611 if ( m_debug_previous_valid and612 (m_debug_data[wcur] != m_debug_previous_data[wcur]) )611 if (m_debug_previous_valid and 612 (m_debug_data[wcur] != m_debug_previous_data[wcur])) 613 613 { 614 614 data_change = true; … … 620 620 // print values if any change 621 621 if ((entry.valid != m_debug_previous_valid) or 622 (entry.valid and (entry.count != m_debug_previous_count)) or623 (entry.valid and (entry.dirty != m_debug_previous_dirty)) or data_change)622 (entry.valid and (entry.count != m_debug_previous_count)) or 623 (entry.valid and (entry.dirty != m_debug_previous_dirty)) or data_change) 624 624 { 625 625 std::cout << "Monitor MEMC " << name() … … 628 628 << " / VAL = " << std::dec << entry.valid 629 629 << " / WAY = " << way 630 << " / COUNT = " << entry.count 630 << " / COUNT = " << entry.count 631 631 << " / DIRTY = " << entry.dirty 632 << " / DATA_CHANGE = " << data_change; 633 if ( single_word)632 << " / DATA_CHANGE = " << data_change; 633 if (single_word) 634 634 { 635 635 std::cout << std::hex << " / value = " << m_debug_data[word] << std::endl; … … 662 662 m_debug_previous_valid = entry.valid; 663 663 m_debug_previous_dirty = entry.dirty; 664 for (size_t wcur = 0; wcur < m_words; wcur++) 664 for (size_t wcur = 0; wcur < m_words; wcur++) 665 { 665 666 m_debug_previous_data[wcur] = m_debug_data[wcur]; 667 } 666 668 } 667 669 668 670 669 671 ///////////////////////////////////////////////////// 670 672 tmpl(uint32_t)::req_distance(uint32_t req_srcid) … … 795 797 796 798 ////////////////////////////////////////////////// 797 tmpl(void)::print_trace( size_t detailed)799 tmpl(void)::print_trace(size_t detailed) 798 800 ////////////////////////////////////////////////// 799 801 { … … 818 820 << " | " << alloc_heap_fsm_str[r_alloc_heap_fsm.read()] << std::endl; 819 821 820 if ( detailed) m_trt.print(0);822 if (detailed) m_trt.print(0); 821 823 } 822 824 823 825 824 826 ///////////////////////////////////////// 825 827 tmpl(void)::reset_counters() … … 866 868 m_cpt_cleanup_remote = 0; 867 869 m_cpt_cleanup_cost = 0; 868 870 869 871 m_cpt_read_miss = 0; 870 872 m_cpt_write_miss = 0; … … 884 886 std::cout << "*** MEM_CACHE " << name() << std::endl; 885 887 std::cout << "**********************************" << std::dec << std::endl; 886 if (activity_counters) { 888 if (activity_counters) 889 { 887 890 std::cout << "----------------------------------" << std::dec << std::endl; 888 891 std::cout << "--- Activity Counters ---" << std::dec << std::endl; … … 992 995 993 996 ////////////////////////////////// 994 tmpl(void) ::transition()997 tmpl(void)::transition() 995 998 ////////////////////////////////// 996 999 { … … 998 1001 999 1002 // RESET 1000 if (! p_resetn.read())1003 if (!p_resetn.read()) 1001 1004 { 1002 1005 … … 1054 1057 m_cmd_cas_eop_fifo.init() ; 1055 1058 1056 r_config_cmd = MEMC_CMD_NOP;1057 r_config_lock = false;1059 r_config_cmd = MEMC_CMD_NOP; 1060 r_config_lock = false; 1058 1061 1059 1062 m_config_to_cc_send_inst_fifo.init(); … … 1159 1162 m_cpt_write_miss = 0; 1160 1163 m_cpt_write_dirty = 0; 1161 1164 1162 1165 m_cpt_trt_rb = 0; 1163 1166 m_cpt_trt_full = 0; … … 1196 1199 bool config_rsp_lines_cleanup_decr = false; 1197 1200 bool config_rsp_lines_ixr_rsp_decr = false; 1198 1201 1199 1202 bool config_to_cc_send_fifo_put = false; 1200 1203 bool config_to_cc_send_fifo_get = false; … … 1253 1256 // The READ/WRITE commands accepted in the configuration segment are targeting 1254 1257 // configuration or status registers. They must contain one single flit. 1255 // - For almost all addressable registers, the response is returned immediately. 1258 // - For almost all addressable registers, the response is returned immediately. 1256 1259 // - For MEMC_CMD_TYPE, the response is delayed until the operation is completed. 1257 1260 //////////////////////////////////////////////////////////////////////////////////// … … 1266 1269 #if DEBUG_MEMC_TGT_CMD 1267 1270 if (m_debug) 1271 { 1268 1272 std::cout << " <MEMC " << name() 1269 1273 << " TGT_CMD_IDLE> Receive command from srcid " 1270 1274 << std::hex << p_vci_tgt.srcid.read() 1271 1275 << " / address " << std::hex << p_vci_tgt.address.read() << std::endl; 1276 } 1272 1277 #endif 1273 1278 // checking segmentation violation … … 1285 1290 } 1286 1291 1287 if (config) /////////// configuration command1292 if (config) /////////// configuration command 1288 1293 { 1289 1294 if (!p_vci_tgt.eop.read()) r_tgt_cmd_fsm = TGT_CMD_ERROR; 1290 1295 else r_tgt_cmd_fsm = TGT_CMD_CONFIG; 1291 1296 } 1292 else //////////// memory access1297 else //////////// memory access 1293 1298 { 1294 1299 if (p_vci_tgt.cmd.read() == vci_param_int::CMD_READ) … … 1334 1339 "The type specified in the pktid field is incompatible with the NOP CMD"); 1335 1340 1336 if ((p_vci_tgt.pktid.read() & 0x7) == TYPE_CAS) r_tgt_cmd_fsm = TGT_CMD_CAS; 1337 else r_tgt_cmd_fsm = TGT_CMD_WRITE; 1341 if ((p_vci_tgt.pktid.read() & 0x7) == TYPE_CAS) 1342 { 1343 r_tgt_cmd_fsm = TGT_CMD_CAS; 1344 } 1345 else 1346 { 1347 r_tgt_cmd_fsm = TGT_CMD_WRITE; 1348 } 1338 1349 } 1339 1350 else … … 1363 1374 #if DEBUG_MEMC_TGT_CMD 1364 1375 if (m_debug) 1376 { 1365 1377 std::cout << " <MEMC " << name() 1366 1378 << " TGT_CMD_ERROR> Segmentation violation:" … … 1370 1382 << " / pktid = " << p_vci_tgt.pktid.read() 1371 1383 << " / plen = " << std::dec << p_vci_tgt.plen.read() << std::endl; 1372 #endif 1373 1384 } 1385 #endif 1374 1386 } 1375 1387 break; … … 1377 1389 //////////////////// 1378 1390 case TGT_CMD_CONFIG: // execute config request and return response 1379 {1380 ///////////////////////////////////////////////////////////1381 // Decoding CONFIG interface commands //1382 // //1383 // VCI ADDRESS //1384 // ================================================ //1385 // GLOBAL | LOCAL | ... | FUNC_IDX | REGS_IDX | 00 //1386 // IDX | IDX | | (3 bits) | (7 bits) | //1387 // ================================================ //1388 // //1389 // For instrumentation : FUNC_IDX = 0b001 //1390 // //1391 // REGS_IDX //1392 // ============================================ //1393 // Z | Y | X | W //1394 // (1 bit) | (2 bits) | (3 bits) | (1 bit) //1395 // ============================================ //1396 // //1397 // Z : DIRECT / COHERENCE //1398 // Y : SUBTYPE ( LOCAL, REMOTE, OTHER )//1399 // X : REGISTER INDEX //1400 // W : HI / LO //1401 // //1402 // For configuration: FUNC_IDX = 0b000 //1403 // //1404 // REGS_IDX //1405 // ============================================ //1406 // RESERVED | X | //1407 // (4 bits) | (3 bits) | //1408 // ============================================ //1409 // //1410 // X : REGISTER INDEX //1411 // //1412 // For WRITE MISS error signaling: FUNC = 0x010 //1413 // //1414 // REGS_IDX //1415 // ============================================ //1416 // RESERVED | X | //1417 // (4 bits) | (3 bits) | //1418 // ============================================ //1419 // //1420 // X : REGISTER INDEX //1421 // //1422 ///////////////////////////////////////////////////////////1423 1424 addr_t addr_lsb = p_vci_tgt.address.read() &1425 m_config_addr_mask; 1426 1427 addr_t cell = (addr_lsb / vci_param_int::B); 1428 1429 size_t regr = cell & 1430 m_config_regr_idx_mask;1431 1432 size_t func = (cell >> m_config_regr_width) &1433 m_config_func_idx_mask;1434 1435 bool need_rsp;1436 int error; 1437 uint32_t rdata = 0; // default value1438 uint32_t wdata = p_vci_tgt.wdata.read();1439 1440 switch(func)1441 { 1442 // memory operation1443 case MEMC_CONFIG:1391 { 1392 /////////////////////////////////////////////////////////// 1393 // Decoding CONFIG interface commands // 1394 // // 1395 // VCI ADDRESS // 1396 // ================================================ // 1397 // GLOBAL | LOCAL | ... | FUNC_IDX | REGS_IDX | 00 // 1398 // IDX | IDX | | (3 bits) | (7 bits) | // 1399 // ================================================ // 1400 // // 1401 // For instrumentation : FUNC_IDX = 0b001 // 1402 // // 1403 // REGS_IDX // 1404 // ============================================ // 1405 // Z | Y | X | W // 1406 // (1 bit) | (2 bits) | (3 bits) | (1 bit) // 1407 // ============================================ // 1408 // // 1409 // Z : DIRECT / COHERENCE // 1410 // Y : SUBTYPE (LOCAL, REMOTE, OTHER) // 1411 // X : REGISTER INDEX // 1412 // W : HI / LO // 1413 // // 1414 // For configuration: FUNC_IDX = 0b000 // 1415 // // 1416 // REGS_IDX // 1417 // ============================================ // 1418 // RESERVED | X | // 1419 // (4 bits) | (3 bits) | // 1420 // ============================================ // 1421 // // 1422 // X : REGISTER INDEX // 1423 // // 1424 // For WRITE MISS error signaling: FUNC = 0x010 // 1425 // // 1426 // REGS_IDX // 1427 // ============================================ // 1428 // RESERVED | X | // 1429 // (4 bits) | (3 bits) | // 1430 // ============================================ // 1431 // // 1432 // X : REGISTER INDEX // 1433 // // 1434 /////////////////////////////////////////////////////////// 1435 1436 addr_t addr_lsb = p_vci_tgt.address.read() & m_config_addr_mask; 1437 1438 addr_t cell = (addr_lsb / vci_param_int::B); 1439 1440 size_t regr = cell & m_config_regr_idx_mask; 1441 1442 size_t func = (cell >> m_config_regr_width) & m_config_func_idx_mask; 1443 1444 bool need_rsp; 1445 int error; 1446 uint32_t rdata = 0; // default value 1447 uint32_t wdata = p_vci_tgt.wdata.read(); 1448 1449 switch (func) 1450 { 1451 // memory operation 1452 case MEMC_CONFIG: 1453 { 1454 if ((p_vci_tgt.cmd.read() == vci_param_int::CMD_READ) // get lock 1455 and (regr == MEMC_LOCK)) 1444 1456 { 1445 if ((p_vci_tgt.cmd.read() == vci_param_int::CMD_READ) // get lock 1446 and (regr == MEMC_LOCK)) 1447 { 1448 rdata = (uint32_t) r_config_lock.read(); 1449 need_rsp = true; 1450 error = 0; 1451 r_config_lock = true; 1452 } 1453 else if ((p_vci_tgt.cmd.read() == vci_param_int::CMD_WRITE) // release lock 1454 and (regr == MEMC_LOCK)) 1455 { 1456 need_rsp = true; 1457 error = 0; 1458 r_config_lock = false; 1459 } 1460 else if ((p_vci_tgt.cmd.read() == vci_param_int::CMD_WRITE) // set addr_lo 1461 and (regr == MEMC_ADDR_LO)) 1462 { 1463 assert( ((wdata % (m_words * vci_param_int::B)) == 0) and 1464 "VCI_MEM_CACHE CONFIG ERROR: The buffer must be aligned on a cache line"); 1465 1466 need_rsp = true; 1467 error = 0; 1468 r_config_address = (r_config_address.read() & 0xFFFFFFFF00000000LL) | 1469 ((addr_t)wdata); 1470 } 1471 else if ((p_vci_tgt.cmd.read() == vci_param_int::CMD_WRITE) // set addr_hi 1472 and (regr == MEMC_ADDR_HI)) 1473 1474 { 1475 need_rsp = true; 1476 error = 0; 1477 r_config_address = (r_config_address.read() & 0x00000000FFFFFFFFLL) | 1478 (((addr_t) wdata) << 32); 1479 } 1480 else if ((p_vci_tgt.cmd.read() == vci_param_int::CMD_WRITE) // set buf_lines 1481 and (regr == MEMC_BUF_LENGTH)) 1482 { 1483 need_rsp = true; 1484 error = 0; 1485 size_t lines = wdata / (m_words << 2); 1486 if (wdata % (m_words << 2)) lines++; 1487 r_config_cmd_lines = lines; 1488 r_config_rsp_lines = 0; 1489 } 1490 else if ((p_vci_tgt.cmd.read() == vci_param_int::CMD_WRITE) // set cmd type 1491 and (regr == MEMC_CMD_TYPE)) 1492 { 1493 need_rsp = false; 1494 error = 0; 1495 r_config_cmd = wdata; 1496 1497 // prepare delayed response from CONFIG FSM 1498 r_config_srcid = p_vci_tgt.srcid.read(); 1499 r_config_trdid = p_vci_tgt.trdid.read(); 1500 r_config_pktid = p_vci_tgt.pktid.read(); 1501 } 1502 else 1503 { 1504 need_rsp = true; 1505 error = 1; 1506 } 1507 1508 break; 1457 rdata = (uint32_t) r_config_lock.read(); 1458 need_rsp = true; 1459 error = 0; 1460 r_config_lock = true; 1509 1461 } 1510 1511 // instrumentation registers 1512 case MEMC_INSTRM: 1513 { 1514 need_rsp = true; 1515 1516 if (p_vci_tgt.cmd.read() == vci_param_int::CMD_READ) 1517 { 1518 error = read_instrumentation(regr, rdata); 1519 } 1520 else 1521 { 1522 error = 1; 1523 } 1524 1525 break; 1526 } 1527 1528 // xram GET bus error registers 1529 case MEMC_RERROR: 1462 else if ((p_vci_tgt.cmd.read() == vci_param_int::CMD_WRITE) // release lock 1463 and (regr == MEMC_LOCK)) 1530 1464 { 1531 1465 need_rsp = true; 1532 1466 error = 0; 1533 1534 if (p_vci_tgt.cmd.read() == vci_param_int::CMD_WRITE) 1535 { 1536 switch (regr) 1537 { 1538 case MEMC_RERROR_IRQ_ENABLE: 1539 r_xram_rsp_rerror_irq_enable = 1540 (p_vci_tgt.wdata.read() != 0); 1541 1542 break; 1543 1544 default: 1545 error = 1; 1546 break; 1547 } 1548 } 1549 else if (p_vci_tgt.cmd.read() == vci_param_int::CMD_READ) 1550 { 1551 switch (regr) 1552 { 1553 case MEMC_RERROR_SRCID: 1554 rdata = (uint32_t) 1555 r_xram_rsp_rerror_rsrcid.read(); 1556 1557 break; 1558 1559 case MEMC_RERROR_ADDR_LO: 1560 rdata = (uint32_t) 1561 (r_xram_rsp_rerror_address.read()) & 1562 ((1ULL<<32)-1); 1563 1564 break; 1565 1566 case MEMC_RERROR_ADDR_HI: 1567 rdata = (uint32_t) 1568 (r_xram_rsp_rerror_address.read() >> 32) & 1569 ((1ULL<<32)-1); 1570 1571 break; 1572 1573 case MEMC_RERROR_IRQ_RESET: 1574 if (not r_xram_rsp_rerror_irq.read()) break; 1575 1576 r_xram_rsp_rerror_irq = false; 1577 1578 break; 1579 1580 case MEMC_RERROR_IRQ_ENABLE: 1581 rdata = (uint32_t) 1582 (r_xram_rsp_rerror_irq_enable.read()) ? 1 : 0; 1583 1584 break; 1585 1586 default: 1587 error = 1; 1588 break; 1589 } 1590 } 1591 else 1592 { 1593 error = 1; 1594 } 1595 1596 break; 1467 r_config_lock = false; 1597 1468 } 1598 1599 //unknown function 1600 default: 1469 else if ((p_vci_tgt.cmd.read() == vci_param_int::CMD_WRITE) // set addr_lo 1470 and (regr == MEMC_ADDR_LO)) 1471 { 1472 assert(((wdata % (m_words * vci_param_int::B)) == 0) and 1473 "VCI_MEM_CACHE CONFIG ERROR: The buffer must be aligned on a cache line"); 1474 1475 need_rsp = true; 1476 error = 0; 1477 r_config_address = (r_config_address.read() & 0xFFFFFFFF00000000LL) | 1478 ((addr_t)wdata); 1479 } 1480 else if ((p_vci_tgt.cmd.read() == vci_param_int::CMD_WRITE) // set addr_hi 1481 and (regr == MEMC_ADDR_HI)) 1482 1483 { 1484 need_rsp = true; 1485 error = 0; 1486 r_config_address = (r_config_address.read() & 0x00000000FFFFFFFFLL) | 1487 (((addr_t) wdata) << 32); 1488 } 1489 else if ((p_vci_tgt.cmd.read() == vci_param_int::CMD_WRITE) // set buf_lines 1490 and (regr == MEMC_BUF_LENGTH)) 1491 { 1492 need_rsp = true; 1493 error = 0; 1494 size_t lines = wdata / (m_words << 2); 1495 if (wdata % (m_words << 2)) lines++; 1496 r_config_cmd_lines = lines; 1497 r_config_rsp_lines = 0; 1498 } 1499 else if ((p_vci_tgt.cmd.read() == vci_param_int::CMD_WRITE) // set cmd type 1500 and (regr == MEMC_CMD_TYPE)) 1501 { 1502 need_rsp = false; 1503 error = 0; 1504 r_config_cmd = wdata; 1505 1506 // prepare delayed response from CONFIG FSM 1507 r_config_srcid = p_vci_tgt.srcid.read(); 1508 r_config_trdid = p_vci_tgt.trdid.read(); 1509 r_config_pktid = p_vci_tgt.pktid.read(); 1510 } 1511 else 1601 1512 { 1602 1513 need_rsp = true; 1603 1514 error = 1; 1604 1605 break;1606 1515 } 1607 } 1608 1609 if (need_rsp) 1610 { 1611 // blocked if previous pending request to TGT_RSP FSM 1612 if (r_tgt_cmd_to_tgt_rsp_req.read()) break; 1613 1614 r_tgt_cmd_to_tgt_rsp_srcid = p_vci_tgt.srcid.read(); 1615 r_tgt_cmd_to_tgt_rsp_trdid = p_vci_tgt.trdid.read(); 1616 r_tgt_cmd_to_tgt_rsp_pktid = p_vci_tgt.pktid.read(); 1617 r_tgt_cmd_to_tgt_rsp_req = true; 1618 r_tgt_cmd_to_tgt_rsp_error = error; 1619 r_tgt_cmd_to_tgt_rsp_rdata = rdata; 1620 } 1621 1622 r_tgt_cmd_fsm = TGT_CMD_IDLE; 1516 1517 break; 1518 } 1519 1520 // instrumentation registers 1521 case MEMC_INSTRM: 1522 { 1523 need_rsp = true; 1524 1525 if (p_vci_tgt.cmd.read() == vci_param_int::CMD_READ) 1526 { 1527 error = read_instrumentation(regr, rdata); 1528 } 1529 else 1530 { 1531 error = 1; 1532 } 1533 1534 break; 1535 } 1536 1537 // xram GET bus error registers 1538 case MEMC_RERROR: 1539 { 1540 need_rsp = true; 1541 error = 0; 1542 1543 if (p_vci_tgt.cmd.read() == vci_param_int::CMD_WRITE) 1544 { 1545 switch (regr) 1546 { 1547 case MEMC_RERROR_IRQ_ENABLE: 1548 r_xram_rsp_rerror_irq_enable = 1549 (p_vci_tgt.wdata.read() != 0); 1550 1551 break; 1552 1553 default: 1554 error = 1; 1555 break; 1556 } 1557 } 1558 else if (p_vci_tgt.cmd.read() == vci_param_int::CMD_READ) 1559 { 1560 switch (regr) 1561 { 1562 case MEMC_RERROR_SRCID: 1563 rdata = (uint32_t) 1564 r_xram_rsp_rerror_rsrcid.read(); 1565 break; 1566 1567 case MEMC_RERROR_ADDR_LO: 1568 rdata = (uint32_t) 1569 (r_xram_rsp_rerror_address.read()) & ((1ULL << 32) - 1); 1570 1571 break; 1572 1573 case MEMC_RERROR_ADDR_HI: 1574 rdata = (uint32_t) 1575 (r_xram_rsp_rerror_address.read() >> 32) & ((1ULL << 32) - 1); 1576 break; 1577 1578 case MEMC_RERROR_IRQ_RESET: 1579 if (not r_xram_rsp_rerror_irq.read()) break; 1580 r_xram_rsp_rerror_irq = false; 1581 break; 1582 1583 case MEMC_RERROR_IRQ_ENABLE: 1584 rdata = (uint32_t) (r_xram_rsp_rerror_irq_enable.read()) ? 1 : 0; 1585 break; 1586 1587 default: 1588 error = 1; 1589 break; 1590 } 1591 } 1592 else 1593 { 1594 error = 1; 1595 } 1596 1597 break; 1598 } 1599 1600 //unknown function 1601 default: 1602 { 1603 need_rsp = true; 1604 error = 1; 1605 break; 1606 } 1607 } 1608 1609 if (need_rsp) 1610 { 1611 // blocked if previous pending request to TGT_RSP FSM 1612 if (r_tgt_cmd_to_tgt_rsp_req.read()) break; 1613 1614 r_tgt_cmd_to_tgt_rsp_srcid = p_vci_tgt.srcid.read(); 1615 r_tgt_cmd_to_tgt_rsp_trdid = p_vci_tgt.trdid.read(); 1616 r_tgt_cmd_to_tgt_rsp_pktid = p_vci_tgt.pktid.read(); 1617 r_tgt_cmd_to_tgt_rsp_req = true; 1618 r_tgt_cmd_to_tgt_rsp_error = error; 1619 r_tgt_cmd_to_tgt_rsp_rdata = rdata; 1620 } 1621 1622 r_tgt_cmd_fsm = TGT_CMD_IDLE; 1623 1623 1624 1624 #if DEBUG_MEMC_TGT_CMD 1625 if (m_debug) 1626 std::cout << " <MEMC " << name() << " TGT_CMD_CONFIG> Configuration request:" 1627 << " address = " << std::hex << p_vci_tgt.address.read() 1628 << " / func = " << func 1629 << " / regr = " << regr 1630 << " / rdata = " << rdata 1631 << " / wdata = " << p_vci_tgt.wdata.read() 1632 << " / need_rsp = " << need_rsp 1633 << " / error = " << error << std::endl; 1634 #endif 1635 break; 1636 } 1637 ////////////////// 1625 if (m_debug) 1626 { 1627 std::cout << " <MEMC " << name() << " TGT_CMD_CONFIG> Configuration request:" 1628 << " address = " << std::hex << p_vci_tgt.address.read() 1629 << " / func = " << func 1630 << " / regr = " << regr 1631 << " / rdata = " << rdata 1632 << " / wdata = " << p_vci_tgt.wdata.read() 1633 << " / need_rsp = " << need_rsp 1634 << " / error = " << error << std::endl; 1635 } 1636 #endif 1637 break; 1638 } 1639 ////////////////// 1638 1640 case TGT_CMD_READ: // Push a read request into read fifo 1639 1641 … … 1652 1654 << " read command packet must contain one single flit" << std::endl; 1653 1655 exit(0); 1654 } 1656 } 1655 1657 // check plen for LL 1656 if ((p_vci_tgt.cmd.read() == vci_param_int::CMD_LOCKED_READ) and 1658 if ((p_vci_tgt.cmd.read() == vci_param_int::CMD_LOCKED_READ) and 1657 1659 (p_vci_tgt.plen.read() != 8)) 1658 1660 { … … 1667 1669 #if DEBUG_MEMC_TGT_CMD 1668 1670 if (m_debug) 1671 { 1669 1672 std::cout << " <MEMC " << name() << " TGT_CMD_READ> Push into read_fifo:" 1670 1673 << " address = " << std::hex << p_vci_tgt.address.read() … … 1673 1676 << " / pktid = " << p_vci_tgt.pktid.read() 1674 1677 << " / plen = " << std::dec << p_vci_tgt.plen.read() << std::endl; 1678 } 1675 1679 #endif 1676 1680 cmd_read_fifo_put = true; 1677 1681 // <Activity counters> 1678 if (p_vci_tgt.cmd.read() == vci_param_int::CMD_LOCKED_READ) { 1682 if (p_vci_tgt.cmd.read() == vci_param_int::CMD_LOCKED_READ) 1683 { 1679 1684 if (is_local_req(p_vci_tgt.srcid.read())) 1680 1685 { … … 1689 1694 } 1690 1695 else { 1691 if (is_local_req(p_vci_tgt.srcid.read())) 1696 if (is_local_req(p_vci_tgt.srcid.read())) 1692 1697 { 1693 1698 m_cpt_read_local++; 1694 1699 } 1695 else 1700 else 1696 1701 { 1697 1702 m_cpt_read_remote++; … … 1712 1717 #if DEBUG_MEMC_TGT_CMD 1713 1718 if (m_debug) 1719 { 1714 1720 std::cout << " <MEMC " << name() << " TGT_CMD_WRITE> Push into write_fifo:" 1715 1721 << " address = " << std::hex << p_vci_tgt.address.read() … … 1720 1726 << " / be = " << p_vci_tgt.be.read() 1721 1727 << " / plen = " << std::dec << p_vci_tgt.plen.read() << std::endl; 1728 } 1722 1729 #endif 1723 1730 cmd_write_fifo_put = true; 1724 1731 // <Activity counters> 1725 if (p_vci_tgt.cmd.read() == vci_param_int::CMD_NOP) { 1732 if (p_vci_tgt.cmd.read() == vci_param_int::CMD_NOP) 1733 { 1726 1734 // (2 (CMD) + 1 (RSP)) flits VCI => 4 + (1 (success) || 2 (failure)) flits dspin 1727 1735 m_cpt_sc_cost += 5 * req_distance(p_vci_tgt.srcid.read()); 1728 1736 } 1729 1737 else { 1730 if (is_local_req(p_vci_tgt.srcid.read())) 1738 if (is_local_req(p_vci_tgt.srcid.read())) 1731 1739 { 1732 1740 m_cpt_write_flits_local++; … … 1741 1749 // </Activity counters> 1742 1750 1743 if (p_vci_tgt.eop) { 1751 if (p_vci_tgt.eop) 1752 { 1744 1753 // <Activity counters> 1745 if (p_vci_tgt.cmd.read() == vci_param_int::CMD_NOP) { 1754 if (p_vci_tgt.cmd.read() == vci_param_int::CMD_NOP) 1755 { 1746 1756 if (is_local_req(p_vci_tgt.srcid.read())) 1747 1757 { … … 1783 1793 #if DEBUG_MEMC_TGT_CMD 1784 1794 if (m_debug) 1795 { 1785 1796 std::cout << " <MEMC " << name() << " TGT_CMD_CAS> Pushing command into cmd_cas_fifo:" 1786 1797 << " address = " << std::hex << p_vci_tgt.address.read() … … 1791 1802 << " be = " << p_vci_tgt.be.read() 1792 1803 << " plen = " << std::dec << p_vci_tgt.plen.read() << std::endl; 1804 } 1793 1805 #endif 1794 1806 cmd_cas_fifo_put = true; 1795 if (p_vci_tgt.eop) { 1807 if (p_vci_tgt.eop) 1808 { 1796 1809 // <Activity counters> 1797 1810 if (is_local_req(p_vci_tgt.srcid.read())) … … 1799 1812 m_cpt_cas_local++; 1800 1813 } 1801 else 1814 else 1802 1815 { 1803 1816 m_cpt_cas_remote++; … … 1815 1828 // MULTI_ACK FSM 1816 1829 ///////////////////////////////////////////////////////////////////////// 1817 // This FSM controls the response to the multicast update requests sent 1830 // This FSM controls the response to the multicast update requests sent 1818 1831 // by the memory cache to the L1 caches and update the UPT. 1819 1832 // … … 1827 1840 //////////////////////////////////////////////////////////////////////// 1828 1841 1829 //std::cout << std::endl << "multi_ack_fsm" << std::endl; 1830 1831 switch(r_multi_ack_fsm.read()) 1842 switch (r_multi_ack_fsm.read()) 1832 1843 { 1833 1844 //////////////////// 1834 1845 case MULTI_ACK_IDLE: 1835 { 1836 bool multi_ack_fifo_rok = m_cc_receive_to_multi_ack_fifo.rok(); 1837 1838 // No CC_RECEIVE FSM request and no WRITE FSM request 1839 if (not multi_ack_fifo_rok and not r_write_to_multi_ack_req.read()) 1840 break; 1841 1842 uint8_t updt_index; 1843 1844 // handling WRITE FSM request to decrement update table response 1845 // counter if no CC_RECEIVE FSM request 1846 if (not multi_ack_fifo_rok) 1847 { 1848 updt_index = r_write_to_multi_ack_upt_index.read(); 1849 r_write_to_multi_ack_req = false; 1850 } 1851 // Handling CC_RECEIVE FSM request 1846 { 1847 bool multi_ack_fifo_rok = m_cc_receive_to_multi_ack_fifo.rok(); 1848 1849 // No CC_RECEIVE FSM request and no WRITE FSM request 1850 if (not multi_ack_fifo_rok and not r_write_to_multi_ack_req.read()) 1851 break; 1852 1853 uint8_t updt_index; 1854 1855 // handling WRITE FSM request to decrement update table response 1856 // counter if no CC_RECEIVE FSM request 1857 if (not multi_ack_fifo_rok) 1858 { 1859 updt_index = r_write_to_multi_ack_upt_index.read(); 1860 r_write_to_multi_ack_req = false; 1861 } 1862 // Handling CC_RECEIVE FSM request 1863 else 1864 { 1865 uint64_t flit = m_cc_receive_to_multi_ack_fifo.read(); 1866 updt_index = DspinDhccpParam::dspin_get(flit, 1867 DspinDhccpParam::MULTI_ACK_UPDT_INDEX); 1868 1869 cc_receive_to_multi_ack_fifo_get = true; 1870 } 1871 1872 assert((updt_index < m_upt.size()) and 1873 "VCI_MEM_CACHE ERROR in MULTI_ACK_IDLE : " 1874 "index too large for UPT"); 1875 1876 r_multi_ack_upt_index = updt_index; 1877 r_multi_ack_fsm = MULTI_ACK_UPT_LOCK; 1878 1879 #if DEBUG_MEMC_MULTI_ACK 1880 if (m_debug) 1881 { 1882 if (multi_ack_fifo_rok) 1883 { 1884 std::cout << " <MEMC " << name() 1885 << " MULTI_ACK_IDLE> Response for UPT entry " 1886 << (size_t) updt_index << std::endl; 1887 } 1852 1888 else 1853 1889 { 1854 uint64_t flit = m_cc_receive_to_multi_ack_fifo.read(); 1855 updt_index = DspinDhccpParam::dspin_get(flit, 1856 DspinDhccpParam::MULTI_ACK_UPDT_INDEX); 1857 1858 cc_receive_to_multi_ack_fifo_get = true; 1859 } 1860 1861 assert((updt_index < m_upt.size()) and 1862 "VCI_MEM_CACHE ERROR in MULTI_ACK_IDLE : " 1863 "index too large for UPT"); 1864 1865 r_multi_ack_upt_index = updt_index; 1866 r_multi_ack_fsm = MULTI_ACK_UPT_LOCK; 1890 std::cout << " <MEMC " << name() 1891 << " MULTI_ACK_IDLE> Write FSM request to decrement UPT entry " 1892 << updt_index << std::endl; 1893 } 1894 } 1895 #endif 1896 break; 1897 } 1898 1899 //////////////////////// 1900 case MULTI_ACK_UPT_LOCK: 1901 { 1902 // get lock to the UPDATE table 1903 if (r_alloc_upt_fsm.read() != ALLOC_UPT_MULTI_ACK) break; 1904 1905 // decrement the number of expected responses 1906 size_t count = 0; 1907 bool valid = m_upt.decrement(r_multi_ack_upt_index.read(), count); 1908 1909 if (not valid) 1910 { 1911 std::cout << "VCI_MEM_CACHE ERROR " << name() 1912 << " MULTI_ACK_UPT_LOCK state" << std::endl 1913 << "unsuccessful access to decrement the UPT" << std::endl; 1914 exit(0); 1915 } 1916 1917 if (count == 0) 1918 { 1919 r_multi_ack_fsm = MULTI_ACK_UPT_CLEAR; 1920 } 1921 else 1922 { 1923 r_multi_ack_fsm = MULTI_ACK_IDLE; 1924 } 1867 1925 1868 1926 #if DEBUG_MEMC_MULTI_ACK 1869 if (m_debug) 1870 { 1871 if (multi_ack_fifo_rok) 1872 { 1873 std::cout << " <MEMC " << name() 1874 << " MULTI_ACK_IDLE> Response for UPT entry " 1875 << (size_t)updt_index << std::endl; 1876 } 1877 else 1878 { 1879 std::cout << " <MEMC " << name() 1880 << " MULTI_ACK_IDLE> Write FSM request to decrement UPT entry " 1881 << updt_index << std::endl; 1882 } 1883 } 1884 #endif 1885 break; 1886 } 1887 1888 //////////////////////// 1889 case MULTI_ACK_UPT_LOCK: 1890 { 1891 // get lock to the UPDATE table 1892 if (r_alloc_upt_fsm.read() != ALLOC_UPT_MULTI_ACK) break; 1893 1894 // decrement the number of expected responses 1895 size_t count = 0; 1896 bool valid = m_upt.decrement(r_multi_ack_upt_index.read(), count); 1897 1898 if (not valid) 1899 { 1900 std::cout << "VCI_MEM_CACHE ERROR " << name() 1901 << " MULTI_ACK_UPT_LOCK state" << std::endl 1902 << "unsuccessful access to decrement the UPT" << std::endl; 1903 exit(0); 1904 } 1905 1906 if (count == 0) 1907 { 1908 r_multi_ack_fsm = MULTI_ACK_UPT_CLEAR; 1909 } 1910 else 1911 { 1912 r_multi_ack_fsm = MULTI_ACK_IDLE; 1913 } 1927 if (m_debug) 1928 { 1929 std::cout << " <MEMC " << name() 1930 << " MULTI_ACK_UPT_LOCK> Decrement the responses counter for UPT:" 1931 << " entry = " << r_multi_ack_upt_index.read() 1932 << " / rsp_count = " << std::dec << count << std::endl; 1933 } 1934 #endif 1935 break; 1936 } 1937 1938 ///////////////////////// 1939 case MULTI_ACK_UPT_CLEAR: // Clear UPT entry / Test if rsp or ack required 1940 { 1941 if (r_alloc_upt_fsm.read() != ALLOC_UPT_MULTI_ACK) 1942 { 1943 std::cout << "VCI_MEM_CACHE ERROR " << name() 1944 << " MULTI_ACK_UPT_CLEAR state" 1945 << " bad UPT allocation" << std::endl; 1946 exit(0); 1947 } 1948 1949 r_multi_ack_srcid = m_upt.srcid(r_multi_ack_upt_index.read()); 1950 r_multi_ack_trdid = m_upt.trdid(r_multi_ack_upt_index.read()); 1951 r_multi_ack_pktid = m_upt.pktid(r_multi_ack_upt_index.read()); 1952 r_multi_ack_nline = m_upt.nline(r_multi_ack_upt_index.read()); 1953 bool need_rsp = m_upt.need_rsp(r_multi_ack_upt_index.read()); 1954 1955 // clear the UPT entry 1956 m_upt.clear(r_multi_ack_upt_index.read()); 1957 1958 if (need_rsp) r_multi_ack_fsm = MULTI_ACK_WRITE_RSP; 1959 else r_multi_ack_fsm = MULTI_ACK_IDLE; 1914 1960 1915 1961 #if DEBUG_MEMC_MULTI_ACK 1916 if (m_debug) 1917 std::cout << " <MEMC " << name() 1918 << " MULTI_ACK_UPT_LOCK> Decrement the responses counter for UPT:" 1919 << " entry = " << r_multi_ack_upt_index.read() 1920 << " / rsp_count = " << std::dec << count << std::endl; 1921 #endif 1922 break; 1923 } 1924 1925 ///////////////////////// 1926 case MULTI_ACK_UPT_CLEAR: // Clear UPT entry / Test if rsp or ack required 1927 { 1928 if (r_alloc_upt_fsm.read() != ALLOC_UPT_MULTI_ACK) 1929 { 1930 std::cout << "VCI_MEM_CACHE ERROR " << name() 1931 << " MULTI_ACK_UPT_CLEAR state" 1932 << " bad UPT allocation" << std::endl; 1933 exit(0); 1934 } 1935 1936 r_multi_ack_srcid = m_upt.srcid(r_multi_ack_upt_index.read()); 1937 r_multi_ack_trdid = m_upt.trdid(r_multi_ack_upt_index.read()); 1938 r_multi_ack_pktid = m_upt.pktid(r_multi_ack_upt_index.read()); 1939 r_multi_ack_nline = m_upt.nline(r_multi_ack_upt_index.read()); 1940 bool need_rsp = m_upt.need_rsp(r_multi_ack_upt_index.read()); 1941 1942 // clear the UPT entry 1943 m_upt.clear(r_multi_ack_upt_index.read()); 1944 1945 if ( need_rsp ) r_multi_ack_fsm = MULTI_ACK_WRITE_RSP; 1946 else r_multi_ack_fsm = MULTI_ACK_IDLE; 1962 if (m_debug) 1963 { 1964 std::cout << " <MEMC " << name() 1965 << " MULTI_ACK_UPT_CLEAR> Clear UPT entry " 1966 << std::dec << r_multi_ack_upt_index.read() << std::endl; 1967 } 1968 #endif 1969 break; 1970 } 1971 ///////////////////////// 1972 case MULTI_ACK_WRITE_RSP: // Post a response request to TGT_RSP FSM 1973 // Wait if pending request 1974 { 1975 if (r_multi_ack_to_tgt_rsp_req.read()) break; 1976 1977 r_multi_ack_to_tgt_rsp_req = true; 1978 r_multi_ack_to_tgt_rsp_srcid = r_multi_ack_srcid.read(); 1979 r_multi_ack_to_tgt_rsp_trdid = r_multi_ack_trdid.read(); 1980 r_multi_ack_to_tgt_rsp_pktid = r_multi_ack_pktid.read(); 1981 r_multi_ack_fsm = MULTI_ACK_IDLE; 1947 1982 1948 1983 #if DEBUG_MEMC_MULTI_ACK 1949 if (m_debug) 1950 std::cout << " <MEMC " << name() 1951 << " MULTI_ACK_UPT_CLEAR> Clear UPT entry " 1952 << std::dec << r_multi_ack_upt_index.read() << std::endl; 1953 #endif 1954 break; 1955 } 1956 ///////////////////////// 1957 case MULTI_ACK_WRITE_RSP: // Post a response request to TGT_RSP FSM 1958 // Wait if pending request 1959 { 1960 if (r_multi_ack_to_tgt_rsp_req.read()) break; 1961 1962 r_multi_ack_to_tgt_rsp_req = true; 1963 r_multi_ack_to_tgt_rsp_srcid = r_multi_ack_srcid.read(); 1964 r_multi_ack_to_tgt_rsp_trdid = r_multi_ack_trdid.read(); 1965 r_multi_ack_to_tgt_rsp_pktid = r_multi_ack_pktid.read(); 1966 r_multi_ack_fsm = MULTI_ACK_IDLE; 1967 1968 #if DEBUG_MEMC_MULTI_ACK 1969 if (m_debug) 1970 std::cout << " <MEMC " << name() << " MULTI_ACK_WRITE_RSP>" 1971 << " Request TGT_RSP FSM to send a response to srcid " 1972 << std::hex << r_multi_ack_srcid.read() << std::endl; 1973 #endif 1974 break; 1975 } 1984 if (m_debug) 1985 { 1986 std::cout << " <MEMC " << name() << " MULTI_ACK_WRITE_RSP>" 1987 << " Request TGT_RSP FSM to send a response to srcid " 1988 << std::hex << r_multi_ack_srcid.read() << std::endl; 1989 } 1990 #endif 1991 break; 1992 } 1976 1993 } // end switch r_multi_ack_fsm 1977 1994 … … 1989 2006 // - uint32_t r_config_rsp_lines : number of lines not completed 1990 2007 // 1991 // For both INVAL and SYNC commands, the CONFIG FSM contains the loop handling 2008 // For both INVAL and SYNC commands, the CONFIG FSM contains the loop handling 1992 2009 // all cache lines covered by the buffer. The various lines of a given buffer 1993 2010 // can be pipelined: the CONFIG FSM does not wait the response for line (n) to send 1994 // the command for line (n+1). It decrements the r_config_cmd_lines counter until 2011 // the command for line (n+1). It decrements the r_config_cmd_lines counter until 1995 2012 // the last request has been registered in TRT (for a SYNC), or in IVT (for an INVAL). 1996 2013 // The r_config_rsp_lines counter contains the number of expected responses from … … 2002 2019 // 2003 2020 // - INVAL request: 2004 // For each line, it access to the DIR. 2005 // In case of miss, it does nothing, and a response is requested to TGT_RSP FSM. 2021 // For each line, it access to the DIR. 2022 // In case of miss, it does nothing, and a response is requested to TGT_RSP FSM. 2006 2023 // In case of hit, with no copies in L1 caches, the line is invalidated and 2007 2024 // a response is requested to TGT_RSP FSM. … … 2014 2031 // This constraint can be released, but it requires to make 2 PUT transactions 2015 2032 // for the first and the last line... 2016 // 2033 // 2017 2034 // - SYNC request: 2018 // For each line, it access to the DIR. 2019 // In case of miss, it does nothing, and a response is requested to TGT_RSP FSM. 2035 // For each line, it access to the DIR. 2036 // In case of miss, it does nothing, and a response is requested to TGT_RSP FSM. 2020 2037 // In case of hit, a PUT transaction is registered in TRT and a request is sent 2021 2038 // to IXR_CMD FSM. The IXR_RSP FSM decrements the r_config_rsp_lines counter … … 2024 2041 // 2025 2042 // From the software point of view, a configuration request is a sequence 2026 // of 6 atomic accesses in an uncached segment. A dedicated lock is used 2043 // of 6 atomic accesses in an uncached segment. A dedicated lock is used 2027 2044 // to handle only one configuration command at a given time: 2028 2045 // - Read MEMC_LOCK : Get the lock … … 2036 2053 //std::cout << std::endl << "config_fsm" << std::endl; 2037 2054 2038 switch (r_config_fsm.read())2055 switch (r_config_fsm.read()) 2039 2056 { 2040 2057 ///////////////// 2041 case CONFIG_IDLE: // waiting a config request 2042 { 2043 if (r_config_cmd.read() != MEMC_CMD_NOP )2044 { 2045 r_config_fsm = CONFIG_LOOP;2058 case CONFIG_IDLE: // waiting a config request 2059 { 2060 if (r_config_cmd.read() != MEMC_CMD_NOP) 2061 { 2062 r_config_fsm = CONFIG_LOOP; 2046 2063 2047 2064 #if DEBUG_MEMC_CONFIG 2048 if (m_debug) 2049 std::cout << " <MEMC " << name() << " CONFIG_IDLE> Config Request received" 2050 << " / address = " << std::hex << r_config_address.read() 2051 << " / lines = " << std::dec << r_config_cmd_lines.read() 2052 << " / type = " << r_config_cmd.read() << std::endl; 2065 if (m_debug) 2066 { 2067 std::cout << " <MEMC " << name() << " CONFIG_IDLE> Config Request received" 2068 << " / address = " << std::hex << r_config_address.read() 2069 << " / lines = " << std::dec << r_config_cmd_lines.read() 2070 << " / type = " << r_config_cmd.read() << std::endl; 2071 } 2053 2072 #endif 2054 2073 } … … 2058 2077 case CONFIG_LOOP: // test if last line to be handled 2059 2078 { 2060 if (r_config_cmd_lines.read() == 0 )2079 if (r_config_cmd_lines.read() == 0) 2061 2080 { 2062 2081 r_config_cmd = MEMC_CMD_NOP; … … 2069 2088 2070 2089 #if DEBUG_MEMC_CONFIG 2071 if (m_debug) 2072 std::cout << " <MEMC " << name() << " CONFIG_LOOP>" 2073 << " / address = " << std::hex << r_config_address.read() 2074 << " / lines not handled = " << std::dec << r_config_cmd_lines.read() 2075 << " / command = " << r_config_cmd.read() << std::endl; 2090 if (m_debug) 2091 { 2092 std::cout << " <MEMC " << name() << " CONFIG_LOOP>" 2093 << " / address = " << std::hex << r_config_address.read() 2094 << " / lines not handled = " << std::dec << r_config_cmd_lines.read() 2095 << " / command = " << r_config_cmd.read() << std::endl; 2096 } 2076 2097 #endif 2077 2098 break; 2078 2099 } 2079 2100 ///////////////// 2080 case CONFIG_WAIT: // wait completion (last response) 2081 { 2082 if (r_config_rsp_lines.read() == 0 ) // last response received2101 case CONFIG_WAIT: // wait completion (last response) 2102 { 2103 if (r_config_rsp_lines.read() == 0) // last response received 2083 2104 { 2084 2105 r_config_fsm = CONFIG_RSP; … … 2086 2107 2087 2108 #if DEBUG_MEMC_CONFIG 2088 if (m_debug) 2089 std::cout << " <MEMC " << name() << " CONFIG_WAIT>" 2090 << " / lines to do = " << std::dec << r_config_rsp_lines.read() << std::endl; 2109 if (m_debug) 2110 { 2111 std::cout << " <MEMC " << name() << " CONFIG_WAIT>" 2112 << " / lines to do = " << std::dec << r_config_rsp_lines.read() << std::endl; 2113 } 2091 2114 #endif 2092 2115 break; 2093 2116 } 2094 2117 //////////////// 2095 case CONFIG_RSP: // request TGT_RSP FSM to return response 2118 case CONFIG_RSP: // request TGT_RSP FSM to return response 2096 2119 { 2097 2120 if (not r_config_to_tgt_rsp_req.read()) 2098 2121 { 2099 r_config_to_tgt_rsp_srcid = r_config_srcid.read();2100 r_config_to_tgt_rsp_trdid = r_config_trdid.read();2101 r_config_to_tgt_rsp_pktid = r_config_pktid.read();2102 r_config_to_tgt_rsp_error = false;2103 r_config_to_tgt_rsp_req = true;2104 r_config_fsm = CONFIG_IDLE;2122 r_config_to_tgt_rsp_srcid = r_config_srcid.read(); 2123 r_config_to_tgt_rsp_trdid = r_config_trdid.read(); 2124 r_config_to_tgt_rsp_pktid = r_config_pktid.read(); 2125 r_config_to_tgt_rsp_error = false; 2126 r_config_to_tgt_rsp_req = true; 2127 r_config_fsm = CONFIG_IDLE; 2105 2128 2106 2129 #if DEBUG_MEMC_CONFIG 2107 if (m_debug) 2108 std::cout << " <MEMC " << name() << " CONFIG_RSP> Request TGT_RSP FSM to send response:" 2109 << " error = " << r_config_to_tgt_rsp_error.read() 2110 << " / rsrcid = " << std::hex << r_config_srcid.read() 2111 << " / rtrdid = " << std::hex << r_config_trdid.read() 2112 << " / rpktid = " << std::hex << r_config_pktid.read() << std::endl; 2130 if (m_debug) 2131 { 2132 std::cout << " <MEMC " << name() << " CONFIG_RSP> Request TGT_RSP FSM to send response:" 2133 << " error = " << r_config_to_tgt_rsp_error.read() 2134 << " / rsrcid = " << std::hex << r_config_srcid.read() 2135 << " / rtrdid = " << std::hex << r_config_trdid.read() 2136 << " / rpktid = " << std::hex << r_config_pktid.read() << std::endl; 2137 } 2113 2138 #endif 2114 2139 } … … 2118 2143 case CONFIG_DIR_REQ: // Request directory lock 2119 2144 { 2120 if (r_alloc_dir_fsm.read() == ALLOC_DIR_CONFIG )2145 if (r_alloc_dir_fsm.read() == ALLOC_DIR_CONFIG) 2121 2146 { 2122 2147 r_config_fsm = CONFIG_DIR_ACCESS; … … 2124 2149 2125 2150 #if DEBUG_MEMC_CONFIG 2126 if (m_debug) 2127 std::cout << " <MEMC " << name() << " CONFIG_DIR_REQ>" 2128 << " Request DIR access" << std::endl; 2151 if (m_debug) 2152 { 2153 std::cout << " <MEMC " << name() << " CONFIG_DIR_REQ>" 2154 << " Request DIR access" << std::endl; 2155 } 2129 2156 #endif 2130 2157 break; … … 2133 2160 case CONFIG_DIR_ACCESS: // Access directory and decode config command 2134 2161 { 2135 assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_CONFIG) and2162 assert((r_alloc_dir_fsm.read() == ALLOC_DIR_CONFIG) and 2136 2163 "MEMC ERROR in CONFIG_DIR_ACCESS state: bad DIR allocation"); 2137 2164 … … 2147 2174 r_config_dir_ptr = entry.ptr; 2148 2175 2149 if (entry.valid and // hit & inval command2150 (r_config_cmd.read() == MEMC_CMD_INVAL)) 2151 { 2152 r_config_fsm = CONFIG_IVT_LOCK;2153 } 2154 else if (entry.valid and // hit & sync command2176 if (entry.valid and // hit & inval command 2177 (r_config_cmd.read() == MEMC_CMD_INVAL)) 2178 { 2179 r_config_fsm = CONFIG_IVT_LOCK; 2180 } 2181 else if (entry.valid and // hit & sync command 2155 2182 entry.dirty and 2156 2183 (r_config_cmd.read() == MEMC_CMD_SYNC)) 2157 { 2158 r_config_fsm = CONFIG_TRT_LOCK;2159 } 2160 else // miss : return to LOOP2184 { 2185 r_config_fsm = CONFIG_TRT_LOCK; 2186 } 2187 else // miss : return to LOOP 2161 2188 { 2162 2189 r_config_cmd_lines = r_config_cmd_lines.read() - 1; 2163 r_config_address = r_config_address.read() + (m_words <<2);2190 r_config_address = r_config_address.read() + (m_words << 2); 2164 2191 r_config_fsm = CONFIG_LOOP; 2165 2192 } 2166 2193 2167 2194 #if DEBUG_MEMC_CONFIG 2168 if (m_debug) 2169 std::cout << " <MEMC " << name() << " CONFIG_DIR_ACCESS> Accessing directory: " 2170 << " address = " << std::hex << r_config_address.read() 2171 << " / hit = " << std::dec << entry.valid 2172 << " / dirty = " << entry.dirty 2173 << " / count = " << entry.count 2174 << " / is_cnt = " << entry.is_cnt << std::endl; 2195 if (m_debug) 2196 { 2197 std::cout << " <MEMC " << name() << " CONFIG_DIR_ACCESS> Accessing directory: " 2198 << " address = " << std::hex << r_config_address.read() 2199 << " / hit = " << std::dec << entry.valid 2200 << " / dirty = " << entry.dirty 2201 << " / count = " << entry.count 2202 << " / is_cnt = " << entry.is_cnt << std::endl; 2203 } 2175 2204 #endif 2176 2205 break; … … 2178 2207 ///////////////////// 2179 2208 case CONFIG_TRT_LOCK: // enter this state in case of SYNC command 2180 // to a dirty cache line 2209 // to a dirty cache line 2181 2210 // keep DIR lock, and try to get TRT lock 2182 2211 // return to LOOP state if TRT full … … 2184 2213 // transaction in TRT if not full. 2185 2214 { 2186 assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_CONFIG) and2215 assert((r_alloc_dir_fsm.read() == ALLOC_DIR_CONFIG) and 2187 2216 "MEMC ERROR in CONFIG_TRT_LOCK state: bad DIR allocation"); 2188 2217 2189 if (r_alloc_trt_fsm.read() == ALLOC_TRT_CONFIG )2218 if (r_alloc_trt_fsm.read() == ALLOC_TRT_CONFIG) 2190 2219 { 2191 2220 size_t index = 0; 2192 bool wok= not m_trt.full(index);2193 2194 if (not wok )2221 bool wok = not m_trt.full(index); 2222 2223 if (not wok) 2195 2224 { 2196 2225 r_config_fsm = CONFIG_LOOP; … … 2198 2227 else 2199 2228 { 2200 size_t way = r_config_dir_way.read();2201 size_t set = m_y[r_config_address.read()];2229 size_t way = r_config_dir_way.read(); 2230 size_t set = m_y[r_config_address.read()]; 2202 2231 2203 2232 // reset dirty bit in DIR … … 2212 2241 entry.owner.inst = r_config_dir_copy_inst.read(); 2213 2242 entry.owner.srcid = r_config_dir_copy_srcid.read(); 2214 m_cache_directory.write( set, way, entry);2243 m_cache_directory.write(set, way, entry); 2215 2244 2216 2245 r_config_trt_index = index; … … 2219 2248 2220 2249 #if DEBUG_MEMC_CONFIG 2221 if (m_debug) 2222 std::cout << " <MEMC " << name() << " CONFIG_TRT_LOCK> Access TRT: " 2223 << " wok = " << std::dec << wok 2224 << " index = " << index << std::endl; 2250 if (m_debug) 2251 { 2252 std::cout << " <MEMC " << name() << " CONFIG_TRT_LOCK> Access TRT: " 2253 << " wok = " << std::dec << wok 2254 << " index = " << index << std::endl; 2255 } 2225 2256 #endif 2226 2257 } … … 2231 2262 // and post a PUT request in TRT 2232 2263 { 2233 assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_CONFIG) and2264 assert((r_alloc_dir_fsm.read() == ALLOC_DIR_CONFIG) and 2234 2265 "MEMC ERROR in CONFIG_TRT_SET state: bad DIR allocation"); 2235 2266 2236 assert( (r_alloc_trt_fsm.read() == ALLOC_TRT_CONFIG) and2267 assert((r_alloc_trt_fsm.read() == ALLOC_TRT_CONFIG) and 2237 2268 "MEMC ERROR in CONFIG_TRT_SET state: bad TRT allocation"); 2238 2269 2239 2270 // read data into cache 2240 size_t way = r_config_dir_way.read();2241 size_t set = m_y[r_config_address.read()];2271 size_t way = r_config_dir_way.read(); 2272 size_t set = m_y[r_config_address.read()]; 2242 2273 std::vector<data_t> data_vector; 2243 2274 data_vector.clear(); 2244 for (size_t word=0; word<m_words; word++)2245 { 2246 uint32_t data = m_cache_data.read( way, set, word);2247 data_vector.push_back( data);2275 for (size_t word = 0; word < m_words; word++) 2276 { 2277 uint32_t data = m_cache_data.read(way, set, word); 2278 data_vector.push_back(data); 2248 2279 } 2249 2280 2250 2281 // post the PUT request in TRT 2251 m_trt.set( r_config_trt_index.read(),2252 false,// PUT transaction2253 m_nline[r_config_address.read()],// line index2254 0,// srcid: unused2255 0,// trdid: unused2256 0,// pktid: unused2257 false,// not proc_read2258 0,// read_length: unused2259 0,// word_index: unused2260 std::vector<be_t>(m_words,0xF), // byte-enable: unused2261 data_vector,// data to be written2262 0,// ll_key: unused2263 true );// requested by config FSM2282 m_trt.set(r_config_trt_index.read(), 2283 false, // PUT transaction 2284 m_nline[r_config_address.read()], // line index 2285 0, // srcid: unused 2286 0, // trdid: unused 2287 0, // pktid: unused 2288 false, // not proc_read 2289 0, // read_length: unused 2290 0, // word_index: unused 2291 std::vector<be_t>(m_words, 0xF), // byte-enable: unused 2292 data_vector, // data to be written 2293 0, // ll_key: unused 2294 true); // requested by config FSM 2264 2295 config_rsp_lines_incr = true; 2265 2296 r_config_fsm = CONFIG_PUT_REQ; 2266 2297 2267 2298 #if DEBUG_MEMC_CONFIG 2268 if (m_debug) 2269 std::cout << " <MEMC " << name() << " CONFIG_TRT_SET> PUT request in TRT:" 2270 << " address = " << std::hex << r_config_address.read() 2271 << " index = " << std::dec << r_config_trt_index.read() << std::endl; 2299 if (m_debug) 2300 { 2301 std::cout << " <MEMC " << name() << " CONFIG_TRT_SET> PUT request in TRT:" 2302 << " address = " << std::hex << r_config_address.read() 2303 << " index = " << std::dec << r_config_trt_index.read() << std::endl; 2304 } 2272 2305 #endif 2273 2306 break; … … 2282 2315 2283 2316 // prepare next iteration 2284 r_config_cmd_lines = r_config_cmd_lines.read() - 1;2285 r_config_address = r_config_address.read() + (m_words<<2);2286 r_config_fsm = CONFIG_LOOP;2317 r_config_cmd_lines = r_config_cmd_lines.read() - 1; 2318 r_config_address = r_config_address.read() + (m_words << 2); 2319 r_config_fsm = CONFIG_LOOP; 2287 2320 2288 2321 #if DEBUG_MEMC_CONFIG 2289 if (m_debug) 2290 std::cout << " <MEMC " << name() << " CONFIG_PUT_REQ> post PUT request to IXR_CMD_FSM" 2291 << " / address = " << std::hex << r_config_address.read() << std::endl; 2322 if (m_debug) 2323 { 2324 std::cout << " <MEMC " << name() << " CONFIG_PUT_REQ> post PUT request to IXR_CMD_FSM" 2325 << " / address = " << std::hex << r_config_address.read() << std::endl; 2326 } 2292 2327 #endif 2293 2328 } … … 2299 2334 // Return to LOOP state if IVT full. 2300 2335 // Register inval in IVT, and invalidate the 2301 // directory if IVT not full. 2302 { 2303 assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_CONFIG) and2336 // directory if IVT not full. 2337 { 2338 assert((r_alloc_dir_fsm.read() == ALLOC_DIR_CONFIG) and 2304 2339 "MEMC ERROR in CONFIG_IVT_LOCK state: bad DIR allocation"); 2305 2340 2306 if (r_alloc_ivt_fsm.read() == ALLOC_IVT_CONFIG )2307 { 2308 size_t set = m_y[(addr_t)(r_config_address.read())];2309 size_t way = r_config_dir_way.read();2310 2311 if (r_config_dir_count.read() == 0 ) // inval DIR and return to LOOP2312 { 2313 m_cache_directory.inval( way, set);2314 r_config_cmd_lines = r_config_cmd_lines.read() - 1;2315 r_config_address = r_config_address.read() + (m_words<<2);2316 r_config_fsm = CONFIG_LOOP;2341 if (r_alloc_ivt_fsm.read() == ALLOC_IVT_CONFIG) 2342 { 2343 size_t set = m_y[(addr_t) (r_config_address.read())]; 2344 size_t way = r_config_dir_way.read(); 2345 2346 if (r_config_dir_count.read() == 0) // inval DIR and return to LOOP 2347 { 2348 m_cache_directory.inval(way, set); 2349 r_config_cmd_lines = r_config_cmd_lines.read() - 1; 2350 r_config_address = r_config_address.read() + (m_words << 2); 2351 r_config_fsm = CONFIG_LOOP; 2317 2352 2318 2353 #if DEBUG_MEMC_CONFIG 2319 if (m_debug) 2320 std::cout << " <MEMC " << name() << " CONFIG_IVT_LOCK>" 2321 << " No copies in L1 : inval DIR entry" << std::endl; 2354 if (m_debug) 2355 { 2356 std::cout << " <MEMC " << name() << " CONFIG_IVT_LOCK>" 2357 << " No copies in L1 : inval DIR entry" << std::endl; 2358 } 2322 2359 #endif 2323 2360 } 2324 2361 else // try to register inval in IVT 2325 2362 { 2326 bool wok = false;2327 size_t index = 0;2328 bool broadcast = r_config_dir_is_cnt.read();2329 size_t srcid = r_config_srcid.read();2330 size_t trdid = r_config_trdid.read();2331 size_t pktid = r_config_pktid.read();2332 addr_t nline = m_nline[(addr_t)(r_config_address.read())];2333 size_t nb_copies = r_config_dir_count.read();2334 2335 wok = m_ivt.set( false, // it's an inval transaction2336 broadcast,2337 false, // no response required2338 true, // acknowledge required2339 srcid,2340 trdid,2341 pktid,2342 nline,2343 nb_copies,2344 index);2345 2346 if (wok ) // IVT success => inval DIR slot2363 bool wok = false; 2364 size_t index = 0; 2365 bool broadcast = r_config_dir_is_cnt.read(); 2366 size_t srcid = r_config_srcid.read(); 2367 size_t trdid = r_config_trdid.read(); 2368 size_t pktid = r_config_pktid.read(); 2369 addr_t nline = m_nline[(addr_t) (r_config_address.read())]; 2370 size_t nb_copies = r_config_dir_count.read(); 2371 2372 wok = m_ivt.set(false, // it's an inval transaction 2373 broadcast, 2374 false, // no response required 2375 true, // acknowledge required 2376 srcid, 2377 trdid, 2378 pktid, 2379 nline, 2380 nb_copies, 2381 index); 2382 2383 if (wok) // IVT success => inval DIR slot 2347 2384 { 2348 m_cache_directory.inval( way, set);2349 r_config_ivt_index = index;2385 m_cache_directory.inval(way, set); 2386 r_config_ivt_index = index; 2350 2387 config_rsp_lines_incr = true; 2351 if (broadcast ) r_config_fsm = CONFIG_BC_SEND; 2352 else r_config_fsm = CONFIG_INVAL_SEND; 2388 if (broadcast) 2389 { 2390 r_config_fsm = CONFIG_BC_SEND; 2391 } 2392 else 2393 { 2394 r_config_fsm = CONFIG_INVAL_SEND; 2395 } 2353 2396 2354 2397 #if DEBUG_MEMC_CONFIG 2355 if (m_debug) 2356 std::cout << " <MEMC " << name() << " CONFIG_IVT_LOCK>" 2357 << " Inval DIR entry and register inval in IVT" 2358 << " / index = " << std::dec << index 2359 << " / broadcast = " << broadcast << std::endl; 2398 if (m_debug) 2399 { 2400 std::cout << " <MEMC " << name() << " CONFIG_IVT_LOCK>" 2401 << " Inval DIR entry and register inval in IVT" 2402 << " / index = " << std::dec << index 2403 << " / broadcast = " << broadcast << std::endl; 2404 } 2360 2405 #endif 2361 2406 } … … 2365 2410 2366 2411 #if DEBUG_MEMC_CONFIG 2367 if (m_debug) 2368 std::cout << " <MEMC " << name() << " CONFIG_IVT_LOCK>" 2369 << " IVT full : release DIR & IVT locks and retry" << std::endl; 2412 if (m_debug) 2413 { 2414 std::cout << " <MEMC " << name() << " CONFIG_IVT_LOCK>" 2415 << " IVT full : release DIR & IVT locks and retry" << std::endl; 2416 } 2370 2417 #endif 2371 2418 } … … 2377 2424 case CONFIG_BC_SEND: // Post a broadcast inval request to CC_SEND FSM 2378 2425 { 2379 if (not r_config_to_cc_send_multi_req.read() and 2426 if (not r_config_to_cc_send_multi_req.read() and 2380 2427 not r_config_to_cc_send_brdcast_req.read()) 2381 2428 { 2382 2429 // post bc inval request 2383 r_config_to_cc_send_multi_req = false;2430 r_config_to_cc_send_multi_req = false; 2384 2431 r_config_to_cc_send_brdcast_req = true; 2385 2432 r_config_to_cc_send_trdid = r_config_ivt_index.read(); … … 2387 2434 2388 2435 // prepare next iteration 2389 r_config_cmd_lines = r_config_cmd_lines.read() - 1;2390 r_config_address = r_config_address.read() + (m_words << 2);2391 r_config_fsm = CONFIG_LOOP;2436 r_config_cmd_lines = r_config_cmd_lines.read() - 1; 2437 r_config_address = r_config_address.read() + (m_words << 2); 2438 r_config_fsm = CONFIG_LOOP; 2392 2439 2393 2440 #if DEBUG_MEMC_CONFIG 2394 if (m_debug) 2395 std::cout << " <MEMC " << name() << " CONFIG_BC_SEND>" 2396 << " Post a broadcast inval request to CC_SEND FSM" 2397 << " / address = " << r_config_address.read() <<std::endl; 2441 if (m_debug) 2442 { 2443 std::cout << " <MEMC " << name() << " CONFIG_BC_SEND>" 2444 << " Post a broadcast inval request to CC_SEND FSM" 2445 << " / address = " << r_config_address.read() <<std::endl; 2446 } 2398 2447 #endif 2399 2448 } … … 2403 2452 case CONFIG_INVAL_SEND: // Post a multi inval request to CC_SEND FSM 2404 2453 { 2405 if (not r_config_to_cc_send_multi_req.read() and 2454 if (not r_config_to_cc_send_multi_req.read() and 2406 2455 not r_config_to_cc_send_brdcast_req.read()) 2407 2456 { 2408 2457 // post multi inval request 2409 r_config_to_cc_send_multi_req = true;2458 r_config_to_cc_send_multi_req = true; 2410 2459 r_config_to_cc_send_brdcast_req = false; 2411 2460 r_config_to_cc_send_trdid = r_config_ivt_index.read(); … … 2417 2466 config_to_cc_send_fifo_put = true; 2418 2467 2419 if (r_config_dir_count.read() == 1 ) // one copy2468 if (r_config_dir_count.read() == 1) // one copy 2420 2469 { 2421 2470 // prepare next iteration 2422 r_config_cmd_lines = r_config_cmd_lines.read() - 1;2423 r_config_address = r_config_address.read() + (m_words << 2);2424 r_config_fsm= CONFIG_LOOP;2471 r_config_cmd_lines = r_config_cmd_lines.read() - 1; 2472 r_config_address = r_config_address.read() + (m_words << 2); 2473 r_config_fsm = CONFIG_LOOP; 2425 2474 } 2426 2475 else // several copies … … 2430 2479 2431 2480 #if DEBUG_MEMC_CONFIG 2432 if (m_debug) 2433 std::cout << " <MEMC " << name() << " CONFIG_INVAL_SEND>" 2434 << " Post multi inval request to CC_SEND FSM" 2435 << " / address = " << std::hex << r_config_address.read() 2436 << " / copy = " << r_config_dir_copy_srcid.read() 2437 << " / inst = " << std::dec << r_config_dir_copy_inst.read() << std::endl; 2481 if (m_debug) 2482 { 2483 std::cout << " <MEMC " << name() << " CONFIG_INVAL_SEND>" 2484 << " Post multi inval request to CC_SEND FSM" 2485 << " / address = " << std::hex << r_config_address.read() 2486 << " / copy = " << r_config_dir_copy_srcid.read() 2487 << " / inst = " << std::dec << r_config_dir_copy_inst.read() << std::endl; 2488 } 2438 2489 #endif 2439 2490 } … … 2443 2494 case CONFIG_HEAP_REQ: // Try to get access to Heap 2444 2495 { 2445 if (r_alloc_heap_fsm.read() == ALLOC_HEAP_CONFIG )2446 { 2447 r_config_fsm = CONFIG_HEAP_SCAN;2496 if (r_alloc_heap_fsm.read() == ALLOC_HEAP_CONFIG) 2497 { 2498 r_config_fsm = CONFIG_HEAP_SCAN; 2448 2499 r_config_heap_next = r_config_dir_ptr.read(); 2449 2500 } 2450 2501 2451 2502 #if DEBUG_MEMC_CONFIG 2452 if (m_debug) 2453 std::cout << " <MEMC " << name() << " CONFIG_HEAP_REQ>" 2454 << " Requesting HEAP lock" << std::endl; 2503 if (m_debug) 2504 { 2505 std::cout << " <MEMC " << name() << " CONFIG_HEAP_REQ>" 2506 << " Requesting HEAP lock" << std::endl; 2507 } 2455 2508 #endif 2456 2509 break; 2457 2510 } 2458 2511 ////////////////////// 2459 case CONFIG_HEAP_SCAN: // scan HEAP and send inval to CC_SEND FSM2460 { 2461 HeapEntry entry = m_heap.read( r_config_heap_next.read());2462 bool last_copy = (entry.next == r_config_heap_next.read());2512 case CONFIG_HEAP_SCAN: // scan HEAP and send inval to CC_SEND FSM 2513 { 2514 HeapEntry entry = m_heap.read(r_config_heap_next.read()); 2515 bool last_copy = (entry.next == r_config_heap_next.read()); 2463 2516 2464 2517 config_to_cc_send_fifo_srcid = entry.owner.srcid; 2465 config_to_cc_send_fifo_inst = entry.owner.inst; 2466 // config_to_cc_send_fifo_last = last_copy; 2467 config_to_cc_send_fifo_put = true; 2518 config_to_cc_send_fifo_inst = entry.owner.inst; 2519 config_to_cc_send_fifo_put = true; 2468 2520 2469 2521 if (m_config_to_cc_send_inst_fifo.wok()) // inval request accepted 2470 2522 { 2471 2523 r_config_heap_next = entry.next; 2472 if (last_copy ) r_config_fsm = CONFIG_HEAP_LAST;2524 if (last_copy) r_config_fsm = CONFIG_HEAP_LAST; 2473 2525 } 2474 2526 2475 2527 #if DEBUG_MEMC_CONFIG 2476 if (m_debug) 2477 std::cout << " <MEMC " << name() << " CONFIG_HEAP_SCAN>" 2478 << " Post multi inval request to CC_SEND FSM" 2479 << " / address = " << std::hex << r_config_address.read() 2480 << " / copy = " << entry.owner.srcid 2481 << " / inst = " << std::dec << entry.owner.inst << std::endl; 2528 if (m_debug) 2529 { 2530 std::cout << " <MEMC " << name() << " CONFIG_HEAP_SCAN>" 2531 << " Post multi inval request to CC_SEND FSM" 2532 << " / address = " << std::hex << r_config_address.read() 2533 << " / copy = " << entry.owner.srcid 2534 << " / inst = " << std::dec << entry.owner.inst << std::endl; 2535 } 2482 2536 #endif 2483 2537 break; 2484 2538 } 2485 2539 ////////////////////// 2486 case CONFIG_HEAP_LAST: // HEAP housekeeping2540 case CONFIG_HEAP_LAST: // HEAP housekeeping 2487 2541 { 2488 2542 size_t free_pointer = m_heap.next_free_ptr(); … … 2497 2551 } 2498 2552 else 2499 { 2553 { 2500 2554 last_entry.next = free_pointer; 2501 2555 } 2502 2556 2503 m_heap.write_free_ptr( r_config_dir_ptr.read());2504 m_heap.write( r_config_heap_next.read(), last_entry);2557 m_heap.write_free_ptr(r_config_dir_ptr.read()); 2558 m_heap.write(r_config_heap_next.read(), last_entry); 2505 2559 2506 2560 // prepare next iteration 2507 r_config_cmd_lines = r_config_cmd_lines.read() - 1;2508 r_config_address = r_config_address.read() + (m_words<<2);2509 r_config_fsm = CONFIG_LOOP;2561 r_config_cmd_lines = r_config_cmd_lines.read() - 1; 2562 r_config_address = r_config_address.read() + (m_words << 2); 2563 r_config_fsm = CONFIG_LOOP; 2510 2564 2511 2565 #if DEBUG_MEMC_CONFIG 2512 if (m_debug) 2513 std::cout << " <MEMC " << name() << " CONFIG_HEAP_LAST>" 2514 << " Heap housekeeping" << std::endl; 2566 if (m_debug) 2567 { 2568 std::cout << " <MEMC " << name() << " CONFIG_HEAP_LAST>" 2569 << " Heap housekeeping" << std::endl; 2570 } 2515 2571 #endif 2516 2572 break; … … 2518 2574 } // end switch r_config_fsm 2519 2575 2520 2576 2521 2577 2522 2578 //////////////////////////////////////////////////////////////////////////////////// … … 2549 2605 /////////////// 2550 2606 case READ_IDLE: // waiting a read request 2551 { 2552 if (m_cmd_read_addr_fifo.rok()) 2553 { 2554 2555 #if DEBUG_MEMC_READ 2556 if (m_debug) 2557 std::cout << " <MEMC " << name() << " READ_IDLE> Read request" 2558 << " : address = " << std::hex << m_cmd_read_addr_fifo.read() 2559 << " / srcid = " << m_cmd_read_srcid_fifo.read() 2560 << " / trdid = " << m_cmd_read_trdid_fifo.read() 2561 << " / pktid = " << m_cmd_read_pktid_fifo.read() 2562 << " / nwords = " << std::dec << m_cmd_read_length_fifo.read() << std::endl; 2563 #endif 2564 r_read_fsm = READ_DIR_REQ; 2565 } 2566 break; 2567 } 2568 ////////////////// 2569 case READ_DIR_REQ: // Get the lock to the directory 2570 { 2571 if (r_alloc_dir_fsm.read() == ALLOC_DIR_READ) 2572 { 2573 r_read_fsm = READ_DIR_LOCK; 2574 } 2607 { 2608 if (m_cmd_read_addr_fifo.rok()) 2609 { 2575 2610 2576 2611 #if DEBUG_MEMC_READ 2577 2612 if (m_debug) 2578 std::cout << " <MEMC " << name() << " READ_DIR_REQ> Requesting DIR lock " << std::endl; 2579 #endif 2580 break; 2581 } 2582 2583 /////////////////// 2613 { 2614 std::cout << " <MEMC " << name() << " READ_IDLE> Read request" 2615 << " : address = " << std::hex << m_cmd_read_addr_fifo.read() 2616 << " / srcid = " << m_cmd_read_srcid_fifo.read() 2617 << " / trdid = " << m_cmd_read_trdid_fifo.read() 2618 << " / pktid = " << m_cmd_read_pktid_fifo.read() 2619 << " / nwords = " << std::dec << m_cmd_read_length_fifo.read() << std::endl; 2620 } 2621 #endif 2622 r_read_fsm = READ_DIR_REQ; 2623 } 2624 break; 2625 } 2626 ////////////////// 2627 case READ_DIR_REQ: // Get the lock to the directory 2628 { 2629 if (r_alloc_dir_fsm.read() == ALLOC_DIR_READ) 2630 { 2631 r_read_fsm = READ_DIR_LOCK; 2632 } 2633 2634 #if DEBUG_MEMC_READ 2635 if (m_debug) 2636 { 2637 std::cout << " <MEMC " << name() << " READ_DIR_REQ> Requesting DIR lock " << std::endl; 2638 } 2639 #endif 2640 break; 2641 } 2642 2643 /////////////////// 2584 2644 case READ_DIR_LOCK: // check directory for hit / miss 2585 { 2586 assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_READ) and 2587 "MEMC ERROR in READ_DIR_LOCK state: Bad DIR allocation"); 2588 2589 size_t way = 0; 2590 DirectoryEntry entry = m_cache_directory.read(m_cmd_read_addr_fifo.read(), way); 2591 2592 // access the global table ONLY when we have an LL cmd 2593 if ((m_cmd_read_pktid_fifo.read() & 0x7) == TYPE_LL) 2594 { 2595 r_read_ll_key = m_llsc_table.ll(m_cmd_read_addr_fifo.read()); 2596 } 2597 r_read_is_cnt = entry.is_cnt; 2598 r_read_dirty = entry.dirty; 2599 r_read_lock = entry.lock; 2600 r_read_tag = entry.tag; 2601 r_read_way = way; 2602 r_read_count = entry.count; 2603 r_read_copy = entry.owner.srcid; 2604 r_read_copy_inst = entry.owner.inst; 2605 r_read_ptr = entry.ptr; // pointer to the heap 2606 2607 // check if this is a cached read, this means pktid is either 2608 // TYPE_READ_DATA_MISS 0bX001 with TSAR encoding 2609 // TYPE_READ_INS_MISS 0bX011 with TSAR encoding 2610 bool cached_read = (m_cmd_read_pktid_fifo.read() & 0x1); 2611 if (entry.valid) // hit 2612 { 2613 // test if we need to register a new copy in the heap 2614 if (entry.is_cnt or (entry.count == 0) or !cached_read) 2645 { 2646 assert((r_alloc_dir_fsm.read() == ALLOC_DIR_READ) and 2647 "MEMC ERROR in READ_DIR_LOCK state: Bad DIR allocation"); 2648 2649 size_t way = 0; 2650 DirectoryEntry entry = m_cache_directory.read(m_cmd_read_addr_fifo.read(), way); 2651 2652 // access the global table ONLY when we have an LL cmd 2653 if ((m_cmd_read_pktid_fifo.read() & 0x7) == TYPE_LL) 2654 { 2655 r_read_ll_key = m_llsc_table.ll(m_cmd_read_addr_fifo.read()); 2656 } 2657 r_read_is_cnt = entry.is_cnt; 2658 r_read_dirty = entry.dirty; 2659 r_read_lock = entry.lock; 2660 r_read_tag = entry.tag; 2661 r_read_way = way; 2662 r_read_count = entry.count; 2663 r_read_copy = entry.owner.srcid; 2664 r_read_copy_inst = entry.owner.inst; 2665 r_read_ptr = entry.ptr; // pointer to the heap 2666 2667 // check if this is a cached read, this means pktid is either 2668 // TYPE_READ_DATA_MISS 0bX001 with TSAR encoding 2669 // TYPE_READ_INS_MISS 0bX011 with TSAR encoding 2670 bool cached_read = (m_cmd_read_pktid_fifo.read() & 0x1); 2671 if (entry.valid) // hit 2672 { 2673 // test if we need to register a new copy in the heap 2674 if (entry.is_cnt or (entry.count == 0) or !cached_read) 2675 { 2676 r_read_fsm = READ_DIR_HIT; 2677 } 2678 else 2679 { 2680 r_read_fsm = READ_HEAP_REQ; 2681 } 2682 } 2683 else // miss 2684 { 2685 r_read_fsm = READ_TRT_LOCK; 2686 } 2687 2688 #if DEBUG_MEMC_READ 2689 if (m_debug) 2690 { 2691 std::cout << " <MEMC " << name() << " READ_DIR_LOCK> Accessing directory: " 2692 << " address = " << std::hex << m_cmd_read_addr_fifo.read() 2693 << " / hit = " << std::dec << entry.valid 2694 << " / count = " <<std::dec << entry.count 2695 << " / is_cnt = " << entry.is_cnt; 2696 if ((m_cmd_read_pktid_fifo.read() & 0x7) == TYPE_LL) 2697 { 2698 std::cout << " / LL access" << std::endl; 2699 } 2700 else 2701 { 2702 std::cout << std::endl; 2703 } 2704 } 2705 #endif 2706 break; 2707 } 2708 ////////////////// 2709 case READ_DIR_HIT: // read data in cache & update the directory 2710 // we enter this state in 3 cases: 2711 // - the read request is uncachable 2712 // - the cache line is in counter mode 2713 // - the cache line is valid but not replicated 2714 { 2715 assert((r_alloc_dir_fsm.read() == ALLOC_DIR_READ) and 2716 "MEMC ERROR in READ_DIR_HIT state: Bad DIR allocation"); 2717 2718 // check if this is an instruction read, this means pktid is either 2719 // TYPE_READ_INS_UNC 0bX010 with TSAR encoding 2720 // TYPE_READ_INS_MISS 0bX011 with TSAR encoding 2721 bool inst_read = ((m_cmd_read_pktid_fifo.read() & 0x2) != 0); 2722 // check if this is a cached read, this means pktid is either 2723 // TYPE_READ_DATA_MISS 0bX001 with TSAR encoding 2724 // TYPE_READ_INS_MISS 0bX011 with TSAR encoding 2725 bool cached_read = (m_cmd_read_pktid_fifo.read() & 0x1); 2726 bool is_cnt = r_read_is_cnt.read(); 2727 2728 // read data in the cache 2729 size_t set = m_y[(addr_t)(m_cmd_read_addr_fifo.read())]; 2730 size_t way = r_read_way.read(); 2731 2732 m_cache_data.read_line(way, set, r_read_data); 2733 2734 // update the cache directory 2735 DirectoryEntry entry; 2736 entry.valid = true; 2737 entry.is_cnt = is_cnt; 2738 entry.dirty = r_read_dirty.read(); 2739 entry.tag = r_read_tag.read(); 2740 entry.lock = r_read_lock.read(); 2741 entry.ptr = r_read_ptr.read(); 2742 2743 if (cached_read) // Cached read => we must update the copies 2744 { 2745 if (!is_cnt) // Not counter mode 2746 { 2747 entry.owner.srcid = m_cmd_read_srcid_fifo.read(); 2748 entry.owner.inst = inst_read; 2749 entry.count = r_read_count.read() + 1; 2750 } 2751 else // Counter mode 2752 { 2753 entry.owner.srcid = 0; 2754 entry.owner.inst = false; 2755 entry.count = r_read_count.read() + 1; 2756 } 2757 } 2758 else // Uncached read 2759 { 2760 entry.owner.srcid = r_read_copy.read(); 2761 entry.owner.inst = r_read_copy_inst.read(); 2762 entry.count = r_read_count.read(); 2763 } 2764 2765 #if DEBUG_MEMC_READ 2766 if (m_debug) 2767 { 2768 std::cout << " <MEMC " << name() << " READ_DIR_HIT> Update directory entry:" 2769 << " addr = " << std::hex << m_cmd_read_addr_fifo.read() 2770 << " / set = " << std::dec << set 2771 << " / way = " << way 2772 << " / owner_id = " << std::hex << entry.owner.srcid 2773 << " / owner_ins = " << std::dec << entry.owner.inst 2774 << " / count = " << entry.count 2775 << " / is_cnt = " << entry.is_cnt << std::endl; 2776 } 2777 #endif 2778 m_cache_directory.write(set, way, entry); 2779 r_read_fsm = READ_RSP; 2780 break; 2781 } 2782 /////////////////// 2783 case READ_HEAP_REQ: // Get the lock to the HEAP directory 2784 { 2785 if (r_alloc_heap_fsm.read() == ALLOC_HEAP_READ) 2786 { 2787 r_read_fsm = READ_HEAP_LOCK; 2788 } 2789 2790 #if DEBUG_MEMC_READ 2791 if (m_debug) 2792 { 2793 std::cout << " <MEMC " << name() << " READ_HEAP_REQ>" 2794 << " Requesting HEAP lock " << std::endl; 2795 } 2796 #endif 2797 break; 2798 } 2799 2800 //////////////////// 2801 case READ_HEAP_LOCK: // read data in cache, update the directory 2802 // and prepare the HEAP update 2803 { 2804 if (r_alloc_heap_fsm.read() == ALLOC_HEAP_READ) 2805 { 2806 // enter counter mode when we reach the limit of copies or the heap is full 2807 bool go_cnt = (r_read_count.read() >= m_max_copies) or m_heap.is_full(); 2808 2809 // read data in the cache 2810 size_t set = m_y[(addr_t) (m_cmd_read_addr_fifo.read())]; 2811 size_t way = r_read_way.read(); 2812 2813 m_cache_data.read_line(way, set, r_read_data); 2814 2815 // update the cache directory 2816 DirectoryEntry entry; 2817 entry.valid = true; 2818 entry.is_cnt = go_cnt; 2819 entry.dirty = r_read_dirty.read(); 2820 entry.tag = r_read_tag.read(); 2821 entry.lock = r_read_lock.read(); 2822 entry.count = r_read_count.read() + 1; 2823 2824 if (not go_cnt) // Not entering counter mode 2825 { 2826 entry.owner.srcid = r_read_copy.read(); 2827 entry.owner.inst = r_read_copy_inst.read(); 2828 entry.ptr = m_heap.next_free_ptr(); // set pointer on the heap 2829 } 2830 else // Entering Counter mode 2831 { 2832 entry.owner.srcid = 0; 2833 entry.owner.inst = false; 2834 entry.ptr = 0; 2835 } 2836 2837 m_cache_directory.write(set, way, entry); 2838 2839 // prepare the heap update (add an entry, or clear the linked list) 2840 if (not go_cnt) // not switching to counter mode 2841 { 2842 // We test if the next free entry in the heap is the last 2843 HeapEntry heap_entry = m_heap.next_free_entry(); 2844 r_read_next_ptr = heap_entry.next; 2845 r_read_last_free = (heap_entry.next == m_heap.next_free_ptr()); 2846 2847 r_read_fsm = READ_HEAP_WRITE; // add an entry in the HEAP 2848 } 2849 else // switching to counter mode 2850 { 2851 if (r_read_count.read() > 1) // heap must be cleared 2615 2852 { 2616 r_read_fsm = READ_DIR_HIT; 2853 HeapEntry next_entry = m_heap.read(r_read_ptr.read()); 2854 r_read_next_ptr = m_heap.next_free_ptr(); 2855 m_heap.write_free_ptr(r_read_ptr.read()); 2856 2857 if (next_entry.next == r_read_ptr.read()) // last entry 2858 { 2859 r_read_fsm = READ_HEAP_LAST; // erase the entry 2860 } 2861 else // not the last entry 2862 { 2863 r_read_ptr = next_entry.next; 2864 r_read_fsm = READ_HEAP_ERASE; // erase the list 2865 } 2617 2866 } 2618 else 2867 else // the heap is not used / nothing to do 2619 2868 { 2620 r_read_fsm = READ_ HEAP_REQ;2869 r_read_fsm = READ_RSP; 2621 2870 } 2622 }2623 else // miss2624 {2625 r_read_fsm = READ_TRT_LOCK;2626 2871 } 2627 2872 … … 2629 2874 if (m_debug) 2630 2875 { 2631 std::cout << " <MEMC " << name() << " READ_DIR_LOCK> Accessing directory: " 2632 << " address = " << std::hex << m_cmd_read_addr_fifo.read() 2633 << " / hit = " << std::dec << entry.valid 2634 << " / count = " <<std::dec << entry.count 2635 << " / is_cnt = " << entry.is_cnt; 2636 if ((m_cmd_read_pktid_fifo.read() & 0x7) == TYPE_LL) std::cout << " / LL access" << std::endl; 2637 else std::cout << std::endl; 2638 } 2639 #endif 2640 break; 2641 } 2642 ////////////////// 2643 case READ_DIR_HIT: // read data in cache & update the directory 2644 // we enter this state in 3 cases: 2645 // - the read request is uncachable 2646 // - the cache line is in counter mode 2647 // - the cache line is valid but not replicated 2648 2649 { 2650 assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_READ) and 2651 "MEMC ERROR in READ_DIR_HIT state: Bad DIR allocation"); 2652 2653 // check if this is an instruction read, this means pktid is either 2654 // TYPE_READ_INS_UNC 0bX010 with TSAR encoding 2655 // TYPE_READ_INS_MISS 0bX011 with TSAR encoding 2656 bool inst_read = ((m_cmd_read_pktid_fifo.read() & 0x2) != 0); 2657 // check if this is a cached read, this means pktid is either 2658 // TYPE_READ_DATA_MISS 0bX001 with TSAR encoding 2659 // TYPE_READ_INS_MISS 0bX011 with TSAR encoding 2660 bool cached_read = (m_cmd_read_pktid_fifo.read() & 0x1); 2661 bool is_cnt = r_read_is_cnt.read(); 2662 2663 // read data in the cache 2664 size_t set = m_y[(addr_t)(m_cmd_read_addr_fifo.read())]; 2665 size_t way = r_read_way.read(); 2666 2667 m_cache_data.read_line(way, set, r_read_data); 2668 2669 // update the cache directory 2670 DirectoryEntry entry; 2671 entry.valid = true; 2672 entry.is_cnt = is_cnt; 2673 entry.dirty = r_read_dirty.read(); 2674 entry.tag = r_read_tag.read(); 2675 entry.lock = r_read_lock.read(); 2676 entry.ptr = r_read_ptr.read(); 2677 2678 if (cached_read) // Cached read => we must update the copies 2679 { 2680 if (!is_cnt) // Not counter mode 2681 { 2682 entry.owner.srcid = m_cmd_read_srcid_fifo.read(); 2683 entry.owner.inst = inst_read; 2684 entry.count = r_read_count.read() + 1; 2685 } 2686 else // Counter mode 2687 { 2688 entry.owner.srcid = 0; 2689 entry.owner.inst = false; 2690 entry.count = r_read_count.read() + 1; 2691 } 2692 } 2693 else // Uncached read 2694 { 2695 entry.owner.srcid = r_read_copy.read(); 2696 entry.owner.inst = r_read_copy_inst.read(); 2697 entry.count = r_read_count.read(); 2698 } 2876 std::cout << " <MEMC " << name() << " READ_HEAP_LOCK> Update directory:" 2877 << " tag = " << std::hex << entry.tag 2878 << " set = " << std::dec << set 2879 << " way = " << way 2880 << " count = " << entry.count 2881 << " is_cnt = " << entry.is_cnt << std::endl; 2882 } 2883 #endif 2884 } 2885 else 2886 { 2887 std::cout << "VCI_MEM_CACHE ERROR " << name() << " READ_HEAP_LOCK" 2888 << "Bad HEAP allocation" << std::endl; 2889 exit(0); 2890 } 2891 break; 2892 } 2893 ///////////////////// 2894 case READ_HEAP_WRITE: // add an entry in the heap 2895 { 2896 if (r_alloc_heap_fsm.read() == ALLOC_HEAP_READ) 2897 { 2898 HeapEntry heap_entry; 2899 heap_entry.owner.srcid = m_cmd_read_srcid_fifo.read(); 2900 heap_entry.owner.inst = ((m_cmd_read_pktid_fifo.read() & 0x2) != 0); 2901 2902 if (r_read_count.read() == 1) // creation of a new linked list 2903 { 2904 heap_entry.next = m_heap.next_free_ptr(); 2905 } 2906 else // head insertion in existing list 2907 { 2908 heap_entry.next = r_read_ptr.read(); 2909 } 2910 m_heap.write_free_entry(heap_entry); 2911 m_heap.write_free_ptr(r_read_next_ptr.read()); 2912 if (r_read_last_free.read()) { 2913 m_heap.set_full(); 2914 } 2915 2916 r_read_fsm = READ_RSP; 2699 2917 2700 2918 #if DEBUG_MEMC_READ 2701 2919 if (m_debug) 2702 std::cout << " <MEMC " << name() << " READ_DIR_HIT> Update directory entry:" 2703 << " addr = " << std::hex << m_cmd_read_addr_fifo.read() 2704 << " / set = " << std::dec << set 2705 << " / way = " << way 2706 << " / owner_id = " << std::hex << entry.owner.srcid 2707 << " / owner_ins = " << std::dec << entry.owner.inst 2708 << " / count = " << entry.count 2709 << " / is_cnt = " << entry.is_cnt << std::endl; 2710 #endif 2711 m_cache_directory.write(set, way, entry); 2712 r_read_fsm = READ_RSP; 2713 break; 2714 } 2715 /////////////////// 2716 case READ_HEAP_REQ: // Get the lock to the HEAP directory 2717 { 2718 if (r_alloc_heap_fsm.read() == ALLOC_HEAP_READ) 2719 { 2720 r_read_fsm = READ_HEAP_LOCK; 2721 } 2920 { 2921 std::cout << " <MEMC " << name() << " READ_HEAP_WRITE> Add an entry in the heap:" 2922 << " owner_id = " << std::hex << heap_entry.owner.srcid 2923 << " owner_ins = " << std::dec << heap_entry.owner.inst << std::endl; 2924 } 2925 #endif 2926 } 2927 else 2928 { 2929 std::cout << "VCI_MEM_CACHE ERROR " << name() << " READ_HEAP_WRITE" 2930 << "Bad HEAP allocation" << std::endl; 2931 exit(0); 2932 } 2933 break; 2934 } 2935 ///////////////////// 2936 case READ_HEAP_ERASE: 2937 { 2938 if (r_alloc_heap_fsm.read() == ALLOC_HEAP_READ) 2939 { 2940 HeapEntry next_entry = m_heap.read(r_read_ptr.read()); 2941 if (next_entry.next == r_read_ptr.read()) 2942 { 2943 r_read_fsm = READ_HEAP_LAST; 2944 } 2945 else 2946 { 2947 r_read_ptr = next_entry.next; 2948 r_read_fsm = READ_HEAP_ERASE; 2949 } 2950 } 2951 else 2952 { 2953 std::cout << "VCI_MEM_CACHE ERROR " << name() << " READ_HEAP_ERASE" 2954 << "Bad HEAP allocation" << std::endl; 2955 exit(0); 2956 } 2957 break; 2958 } 2959 2960 //////////////////// 2961 case READ_HEAP_LAST: 2962 { 2963 if (r_alloc_heap_fsm.read() == ALLOC_HEAP_READ) 2964 { 2965 HeapEntry last_entry; 2966 last_entry.owner.srcid = 0; 2967 last_entry.owner.inst = false; 2968 2969 if (m_heap.is_full()) 2970 { 2971 last_entry.next = r_read_ptr.read(); 2972 m_heap.unset_full(); 2973 } 2974 else 2975 { 2976 last_entry.next = r_read_next_ptr.read(); 2977 } 2978 m_heap.write(r_read_ptr.read(),last_entry); 2979 r_read_fsm = READ_RSP; 2980 } 2981 else 2982 { 2983 std::cout << "VCI_MEM_CACHE ERROR " << name() << " READ_HEAP_LAST" 2984 << "Bad HEAP allocation" << std::endl; 2985 exit(0); 2986 } 2987 break; 2988 } 2989 ////////////// 2990 case READ_RSP: // request the TGT_RSP FSM to return data 2991 { 2992 if (!r_read_to_tgt_rsp_req) 2993 { 2994 for (size_t i = 0; i < m_words; i++) 2995 { 2996 r_read_to_tgt_rsp_data[i] = r_read_data[i]; 2997 } 2998 r_read_to_tgt_rsp_word = m_x[(addr_t) m_cmd_read_addr_fifo.read()]; 2999 r_read_to_tgt_rsp_length = m_cmd_read_length_fifo.read(); 3000 r_read_to_tgt_rsp_srcid = m_cmd_read_srcid_fifo.read(); 3001 r_read_to_tgt_rsp_trdid = m_cmd_read_trdid_fifo.read(); 3002 r_read_to_tgt_rsp_pktid = m_cmd_read_pktid_fifo.read(); 3003 r_read_to_tgt_rsp_ll_key = r_read_ll_key.read(); 3004 cmd_read_fifo_get = true; 3005 r_read_to_tgt_rsp_req = true; 3006 r_read_fsm = READ_IDLE; 2722 3007 2723 3008 #if DEBUG_MEMC_READ 2724 3009 if (m_debug) 2725 std::cout << " <MEMC " << name() << " READ_HEAP_REQ>" 2726 << " Requesting HEAP lock " << std::endl; 2727 #endif 2728 break; 2729 } 2730 2731 //////////////////// 2732 case READ_HEAP_LOCK: // read data in cache, update the directory 2733 // and prepare the HEAP update 2734 { 2735 if (r_alloc_heap_fsm.read() == ALLOC_HEAP_READ) 2736 { 2737 // enter counter mode when we reach the limit of copies or the heap is full 2738 bool go_cnt = (r_read_count.read() >= m_max_copies) or m_heap.is_full(); 2739 2740 // read data in the cache 2741 size_t set = m_y[(addr_t)(m_cmd_read_addr_fifo.read())]; 2742 size_t way = r_read_way.read(); 2743 2744 m_cache_data.read_line(way, set, r_read_data); 2745 2746 // update the cache directory 2747 DirectoryEntry entry; 2748 entry.valid = true; 2749 entry.is_cnt = go_cnt; 2750 entry.dirty = r_read_dirty.read(); 2751 entry.tag = r_read_tag.read(); 2752 entry.lock = r_read_lock.read(); 2753 entry.count = r_read_count.read() + 1; 2754 2755 if (not go_cnt) // Not entering counter mode 2756 { 2757 entry.owner.srcid = r_read_copy.read(); 2758 entry.owner.inst = r_read_copy_inst.read(); 2759 entry.ptr = m_heap.next_free_ptr(); // set pointer on the heap 2760 } 2761 else // Entering Counter mode 2762 { 2763 entry.owner.srcid = 0; 2764 entry.owner.inst = false; 2765 entry.ptr = 0; 2766 } 2767 2768 m_cache_directory.write(set, way, entry); 2769 2770 // prepare the heap update (add an entry, or clear the linked list) 2771 if (not go_cnt) // not switching to counter mode 2772 { 2773 // We test if the next free entry in the heap is the last 2774 HeapEntry heap_entry = m_heap.next_free_entry(); 2775 r_read_next_ptr = heap_entry.next; 2776 r_read_last_free = (heap_entry.next == m_heap.next_free_ptr()); 2777 2778 r_read_fsm = READ_HEAP_WRITE; // add an entry in the HEAP 2779 } 2780 else // switching to counter mode 2781 { 2782 if (r_read_count.read() >1) // heap must be cleared 2783 { 2784 HeapEntry next_entry = m_heap.read(r_read_ptr.read()); 2785 r_read_next_ptr = m_heap.next_free_ptr(); 2786 m_heap.write_free_ptr(r_read_ptr.read()); 2787 2788 if (next_entry.next == r_read_ptr.read()) // last entry 2789 { 2790 r_read_fsm = READ_HEAP_LAST; // erase the entry 2791 } 2792 else // not the last entry 2793 { 2794 r_read_ptr = next_entry.next; 2795 r_read_fsm = READ_HEAP_ERASE; // erase the list 2796 } 2797 } 2798 else // the heap is not used / nothing to do 2799 { 2800 r_read_fsm = READ_RSP; 2801 } 2802 } 3010 { 3011 std::cout << " <MEMC " << name() << " READ_RSP> Request TGT_RSP FSM to return data:" 3012 << " rsrcid = " << std::hex << m_cmd_read_srcid_fifo.read() 3013 << " / address = " << std::hex << m_cmd_read_addr_fifo.read() 3014 << " / nwords = " << std::dec << m_cmd_read_length_fifo.read() << std::endl; 3015 } 3016 #endif 3017 } 3018 break; 3019 } 3020 /////////////////// 3021 case READ_TRT_LOCK: // read miss : check the Transaction Table 3022 { 3023 if (r_alloc_trt_fsm.read() == ALLOC_TRT_READ) 3024 { 3025 size_t index = 0; 3026 addr_t addr = (addr_t) m_cmd_read_addr_fifo.read(); 3027 bool hit_read = m_trt.hit_read(m_nline[addr], index); 3028 bool hit_write = m_trt.hit_write(m_nline[addr]); 3029 bool wok = not m_trt.full(index); 3030 3031 if (hit_read or !wok or hit_write) // line already requested or no space 3032 { 3033 if (!wok) m_cpt_trt_full++; 3034 if (hit_read or hit_write) m_cpt_trt_rb++; 3035 r_read_fsm = READ_IDLE; 3036 } 3037 else // missing line is requested to the XRAM 3038 { 3039 m_cpt_read_miss++; 3040 r_read_trt_index = index; 3041 r_read_fsm = READ_TRT_SET; 3042 } 2803 3043 2804 3044 #if DEBUG_MEMC_READ 2805 if (m_debug) 2806 std::cout << " <MEMC " << name() << " READ_HEAP_LOCK> Update directory:" 2807 << " tag = " << std::hex << entry.tag 2808 << " set = " << std::dec << set 2809 << " way = " << way 2810 << " count = " << entry.count 2811 << " is_cnt = " << entry.is_cnt << std::endl; 2812 #endif 2813 } 2814 else 2815 { 2816 std::cout << "VCI_MEM_CACHE ERROR " << name() << " READ_HEAP_LOCK" 2817 << "Bad HEAP allocation" << std::endl; 2818 exit(0); 2819 } 2820 break; 2821 } 2822 ///////////////////// 2823 case READ_HEAP_WRITE: // add an entry in the heap 2824 { 2825 if (r_alloc_heap_fsm.read() == ALLOC_HEAP_READ) 2826 { 2827 HeapEntry heap_entry; 2828 heap_entry.owner.srcid = m_cmd_read_srcid_fifo.read(); 2829 heap_entry.owner.inst = ((m_cmd_read_pktid_fifo.read() & 0x2) != 0); 2830 2831 if (r_read_count.read() == 1) // creation of a new linked list 2832 { 2833 heap_entry.next = m_heap.next_free_ptr(); 2834 } 2835 else // head insertion in existing list 2836 { 2837 heap_entry.next = r_read_ptr.read(); 2838 } 2839 m_heap.write_free_entry(heap_entry); 2840 m_heap.write_free_ptr(r_read_next_ptr.read()); 2841 if (r_read_last_free.read()) m_heap.set_full(); 2842 2843 r_read_fsm = READ_RSP; 2844 3045 if (m_debug) 3046 { 3047 std::cout << " <MEMC " << name() << " READ_TRT_LOCK> Check TRT:" 3048 << " hit_read = " << hit_read 3049 << " / hit_write = " << hit_write 3050 << " / full = " << !wok << std::endl; 3051 } 3052 #endif 3053 } 3054 break; 3055 } 3056 ////////////////// 3057 case READ_TRT_SET: // register get transaction in TRT 3058 { 3059 if (r_alloc_trt_fsm.read() == ALLOC_TRT_READ) 3060 { 3061 m_trt.set(r_read_trt_index.read(), 3062 true, // GET 3063 m_nline[(addr_t) (m_cmd_read_addr_fifo.read())], 3064 m_cmd_read_srcid_fifo.read(), 3065 m_cmd_read_trdid_fifo.read(), 3066 m_cmd_read_pktid_fifo.read(), 3067 true, // proc read 3068 m_cmd_read_length_fifo.read(), 3069 m_x[(addr_t) (m_cmd_read_addr_fifo.read())], 3070 std::vector<be_t> (m_words, 0), 3071 std::vector<data_t> (m_words, 0), 3072 r_read_ll_key.read()); 2845 3073 #if DEBUG_MEMC_READ 2846 if (m_debug) 2847 std::cout << " <MEMC " << name() << " READ_HEAP_WRITE> Add an entry in the heap:" 2848 << " owner_id = " << std::hex << heap_entry.owner.srcid 2849 << " owner_ins = " << std::dec << heap_entry.owner.inst << std::endl; 2850 #endif 2851 } 2852 else 2853 { 2854 std::cout << "VCI_MEM_CACHE ERROR " << name() << " READ_HEAP_WRITE" 2855 << "Bad HEAP allocation" << std::endl; 2856 exit(0); 2857 } 2858 break; 2859 } 2860 ///////////////////// 2861 case READ_HEAP_ERASE: 2862 { 2863 if (r_alloc_heap_fsm.read() == ALLOC_HEAP_READ) 2864 { 2865 HeapEntry next_entry = m_heap.read(r_read_ptr.read()); 2866 if (next_entry.next == r_read_ptr.read()) 2867 { 2868 r_read_fsm = READ_HEAP_LAST; 2869 } 2870 else 2871 { 2872 r_read_ptr = next_entry.next; 2873 r_read_fsm = READ_HEAP_ERASE; 2874 } 2875 } 2876 else 2877 { 2878 std::cout << "VCI_MEM_CACHE ERROR " << name() << " READ_HEAP_ERASE" 2879 << "Bad HEAP allocation" << std::endl; 2880 exit(0); 2881 } 2882 break; 2883 } 2884 2885 //////////////////// 2886 case READ_HEAP_LAST: 2887 { 2888 if (r_alloc_heap_fsm.read() == ALLOC_HEAP_READ) 2889 { 2890 HeapEntry last_entry; 2891 last_entry.owner.srcid = 0; 2892 last_entry.owner.inst = false; 2893 2894 if (m_heap.is_full()) 2895 { 2896 last_entry.next = r_read_ptr.read(); 2897 m_heap.unset_full(); 2898 } 2899 else 2900 { 2901 last_entry.next = r_read_next_ptr.read(); 2902 } 2903 m_heap.write(r_read_ptr.read(),last_entry); 2904 r_read_fsm = READ_RSP; 2905 } 2906 else 2907 { 2908 std::cout << "VCI_MEM_CACHE ERROR " << name() << " READ_HEAP_LAST" 2909 << "Bad HEAP allocation" << std::endl; 2910 exit(0); 2911 } 2912 break; 2913 } 2914 ////////////// 2915 case READ_RSP: // request the TGT_RSP FSM to return data 2916 { 2917 if (!r_read_to_tgt_rsp_req) 2918 { 2919 for(size_t i=0 ; i<m_words ; i++) r_read_to_tgt_rsp_data[i] = r_read_data[i]; 2920 r_read_to_tgt_rsp_word = m_x[(addr_t) m_cmd_read_addr_fifo.read()]; 2921 r_read_to_tgt_rsp_length = m_cmd_read_length_fifo.read(); 2922 r_read_to_tgt_rsp_srcid = m_cmd_read_srcid_fifo.read(); 2923 r_read_to_tgt_rsp_trdid = m_cmd_read_trdid_fifo.read(); 2924 r_read_to_tgt_rsp_pktid = m_cmd_read_pktid_fifo.read(); 2925 r_read_to_tgt_rsp_ll_key = r_read_ll_key.read(); 2926 cmd_read_fifo_get = true; 2927 r_read_to_tgt_rsp_req = true; 2928 r_read_fsm = READ_IDLE; 3074 if (m_debug) 3075 { 3076 std::cout << " <MEMC " << name() << " READ_TRT_SET> Set a GET in TRT:" 3077 << " address = " << std::hex << m_cmd_read_addr_fifo.read() 3078 << " / srcid = " << std::hex << m_cmd_read_srcid_fifo.read() << std::endl; 3079 } 3080 #endif 3081 r_read_fsm = READ_TRT_REQ; 3082 } 3083 break; 3084 } 3085 3086 ////////////////// 3087 case READ_TRT_REQ: // consume the read request in FIFO and send it to IXR_CMD_FSM 3088 { 3089 if (not r_read_to_ixr_cmd_req) 3090 { 3091 cmd_read_fifo_get = true; 3092 r_read_to_ixr_cmd_req = true; 3093 r_read_to_ixr_cmd_index = r_read_trt_index.read(); 3094 r_read_fsm = READ_IDLE; 2929 3095 2930 3096 #if DEBUG_MEMC_READ 2931 if (m_debug) 2932 std::cout << " <MEMC " << name() << " READ_RSP> Request TGT_RSP FSM to return data:" 2933 << " rsrcid = " << std::hex << m_cmd_read_srcid_fifo.read() 2934 << " / address = " << std::hex << m_cmd_read_addr_fifo.read() 2935 << " / nwords = " << std::dec << m_cmd_read_length_fifo.read() << std::endl; 2936 #endif 2937 } 2938 break; 2939 } 2940 /////////////////// 2941 case READ_TRT_LOCK: // read miss : check the Transaction Table 2942 { 2943 if (r_alloc_trt_fsm.read() == ALLOC_TRT_READ) 2944 { 2945 size_t index = 0; 2946 addr_t addr = (addr_t) m_cmd_read_addr_fifo.read(); 2947 bool hit_read = m_trt.hit_read(m_nline[addr], index); 2948 bool hit_write = m_trt.hit_write(m_nline[addr]); 2949 bool wok = not m_trt.full(index); 2950 2951 if (hit_read or !wok or hit_write) // line already requested or no space 2952 { 2953 if (!wok) m_cpt_trt_full++; 2954 if (hit_read or hit_write) m_cpt_trt_rb++; 2955 r_read_fsm = READ_IDLE; 2956 } 2957 else // missing line is requested to the XRAM 2958 { 2959 m_cpt_read_miss++; 2960 r_read_trt_index = index; 2961 r_read_fsm = READ_TRT_SET; 2962 } 2963 2964 #if DEBUG_MEMC_READ 2965 if (m_debug) 2966 std::cout << " <MEMC " << name() << " READ_TRT_LOCK> Check TRT:" 2967 << " hit_read = " << hit_read 2968 << " / hit_write = " << hit_write 2969 << " / full = " << !wok << std::endl; 2970 #endif 2971 } 2972 break; 2973 } 2974 ////////////////// 2975 case READ_TRT_SET: // register get transaction in TRT 2976 { 2977 if (r_alloc_trt_fsm.read() == ALLOC_TRT_READ) 2978 { 2979 m_trt.set( r_read_trt_index.read(), 2980 true, // GET 2981 m_nline[(addr_t)(m_cmd_read_addr_fifo.read())], 2982 m_cmd_read_srcid_fifo.read(), 2983 m_cmd_read_trdid_fifo.read(), 2984 m_cmd_read_pktid_fifo.read(), 2985 true, // proc read 2986 m_cmd_read_length_fifo.read(), 2987 m_x[(addr_t)(m_cmd_read_addr_fifo.read())], 2988 std::vector<be_t> (m_words,0), 2989 std::vector<data_t> (m_words,0), 2990 r_read_ll_key.read()); 2991 #if DEBUG_MEMC_READ 2992 if (m_debug) 2993 std::cout << " <MEMC " << name() << " READ_TRT_SET> Set a GET in TRT:" 2994 << " address = " << std::hex << m_cmd_read_addr_fifo.read() 2995 << " / srcid = " << std::hex << m_cmd_read_srcid_fifo.read() << std::endl; 2996 #endif 2997 r_read_fsm = READ_TRT_REQ; 2998 } 2999 break; 3000 } 3001 3002 ////////////////// 3003 case READ_TRT_REQ: // consume the read request in FIFO and send it to IXR_CMD_FSM 3004 { 3005 if (not r_read_to_ixr_cmd_req) 3006 { 3007 cmd_read_fifo_get = true; 3008 r_read_to_ixr_cmd_req = true; 3009 r_read_to_ixr_cmd_index = r_read_trt_index.read(); 3010 r_read_fsm = READ_IDLE; 3011 3012 #if DEBUG_MEMC_READ 3013 if (m_debug) 3014 std::cout << " <MEMC " << name() << " READ_TRT_REQ> Request GET transaction for address " 3015 << std::hex << m_cmd_read_addr_fifo.read() << std::endl; 3016 #endif 3017 } 3018 break; 3019 } 3097 if (m_debug) 3098 { 3099 std::cout << " <MEMC " << name() << " READ_TRT_REQ> Request GET transaction for address " 3100 << std::hex << m_cmd_read_addr_fifo.read() << std::endl; 3101 } 3102 #endif 3103 } 3104 break; 3105 } 3020 3106 } // end switch read_fsm 3021 3107 … … 3053 3139 ///////////////////////////////////////////////////////////////////////////////////// 3054 3140 3055 //std::cout << std::endl << "write_fsm" << std::endl; 3056 3057 switch(r_write_fsm.read()) 3141 switch (r_write_fsm.read()) 3058 3142 { 3059 3143 //////////////// 3060 3144 case WRITE_IDLE: // copy first word of a write burst in local buffer 3061 {3062 if (not m_cmd_write_addr_fifo.rok()) break;3063 3064 // consume a word in the FIFO & write it in the local buffer3065 cmd_write_fifo_get = true;3066 size_t index = m_x[(addr_t)(m_cmd_write_addr_fifo.read())];3067 3068 r_write_address = (addr_t)(m_cmd_write_addr_fifo.read());3069 r_write_word_index = index;3070 r_write_word_count = 0;3071 r_write_data[index] = m_cmd_write_data_fifo.read();3072 r_write_srcid = m_cmd_write_srcid_fifo.read();3073 r_write_trdid = m_cmd_write_trdid_fifo.read();3074 r_write_pktid = m_cmd_write_pktid_fifo.read();3075 3076 // if SC command, get the SC key3077 if ((m_cmd_write_pktid_fifo.read() & 0x7) == TYPE_SC)3078 {3079 assert(not m_cmd_write_eop_fifo.read() &&3080 "MEMC ERROR in WRITE_IDLE state: "3081 "invalid packet format for SC command");3082 3083 r_write_sc_key = m_cmd_write_data_fifo.read();3084 }3085 3086 // initialize the be field for all words3087 for(size_t word=0 ; word<m_words; word++)3088 {3089 if (word == index) r_write_be[word] = m_cmd_write_be_fifo.read();3090 else r_write_be[word] = 0x0;3091 }3092 3093 if (m_cmd_write_eop_fifo.read())3094 {3095 r_write_fsm = WRITE_DIR_REQ;3096 }3097 else3098 {3099 r_write_fsm = WRITE_NEXT;3100 }3145 { 3146 if (not m_cmd_write_addr_fifo.rok()) break; 3147 3148 // consume a word in the FIFO & write it in the local buffer 3149 cmd_write_fifo_get = true; 3150 size_t index = m_x[(addr_t) (m_cmd_write_addr_fifo.read())]; 3151 3152 r_write_address = (addr_t) (m_cmd_write_addr_fifo.read()); 3153 r_write_word_index = index; 3154 r_write_word_count = 0; 3155 r_write_data[index] = m_cmd_write_data_fifo.read(); 3156 r_write_srcid = m_cmd_write_srcid_fifo.read(); 3157 r_write_trdid = m_cmd_write_trdid_fifo.read(); 3158 r_write_pktid = m_cmd_write_pktid_fifo.read(); 3159 3160 // if SC command, get the SC key 3161 if ((m_cmd_write_pktid_fifo.read() & 0x7) == TYPE_SC) 3162 { 3163 assert(not m_cmd_write_eop_fifo.read() && 3164 "MEMC ERROR in WRITE_IDLE state: " 3165 "invalid packet format for SC command"); 3166 3167 r_write_sc_key = m_cmd_write_data_fifo.read(); 3168 } 3169 3170 // initialize the be field for all words 3171 for (size_t word = 0; word < m_words; word++) 3172 { 3173 if (word == index) r_write_be[word] = m_cmd_write_be_fifo.read(); 3174 else r_write_be[word] = 0x0; 3175 } 3176 3177 if (m_cmd_write_eop_fifo.read()) 3178 { 3179 r_write_fsm = WRITE_DIR_REQ; 3180 } 3181 else 3182 { 3183 r_write_fsm = WRITE_NEXT; 3184 } 3101 3185 3102 3186 #if DEBUG_MEMC_WRITE 3103 if (m_debug) 3104 std::cout << " <MEMC " << name() << " WRITE_IDLE> Write request " 3105 << " srcid = " << std::hex << m_cmd_write_srcid_fifo.read() 3106 << " / address = " << std::hex << m_cmd_write_addr_fifo.read() 3107 << " / data = " << m_cmd_write_data_fifo.read() << std::endl; 3108 #endif 3109 break; 3110 } 3111 //////////////// 3187 if (m_debug) 3188 { 3189 std::cout << " <MEMC " << name() << " WRITE_IDLE> Write request " 3190 << " srcid = " << std::hex << m_cmd_write_srcid_fifo.read() 3191 << " / address = " << std::hex << m_cmd_write_addr_fifo.read() 3192 << " / data = " << m_cmd_write_data_fifo.read() << std::endl; 3193 } 3194 #endif 3195 break; 3196 } 3197 //////////////// 3112 3198 case WRITE_NEXT: // copy next word of a write burst in local buffer 3113 {3114 if (not m_cmd_write_addr_fifo.rok()) break;3115 3116 // check that the next word is in the same cache line3117 assert((m_nline[(addr_t)(r_write_address.read())] ==3199 { 3200 if (not m_cmd_write_addr_fifo.rok()) break; 3201 3202 // check that the next word is in the same cache line 3203 assert((m_nline[(addr_t)(r_write_address.read())] == 3118 3204 m_nline[(addr_t)(m_cmd_write_addr_fifo.read())]) && 3119 "MEMC ERROR in WRITE_NEXT state: Illegal write burst"); 3120 3121 size_t index = m_x[(addr_t)(m_cmd_write_addr_fifo.read())]; 3122 bool is_sc = ((m_cmd_write_pktid_fifo.read() & 0x7) == TYPE_SC); 3123 3124 // check that SC command has constant address 3125 assert((not is_sc or (index == r_write_word_index)) && 3126 "MEMC ERROR in WRITE_NEXT state: " 3127 "the address must be constant on a SC command"); 3128 3129 // check that SC command has two flits 3130 assert((not is_sc or m_cmd_write_eop_fifo.read()) && 3131 "MEMC ERROR in WRITE_NEXT state: " 3132 "invalid packet format for SC command"); 3133 3134 // consume a word in the FIFO & write it in the local buffer 3135 cmd_write_fifo_get = true; 3136 3137 r_write_be[index] = m_cmd_write_be_fifo.read(); 3138 r_write_data[index] = m_cmd_write_data_fifo.read(); 3139 3140 // the first flit of a SC command is the reservation key and 3141 // therefore it must not be counted as a data to write 3142 if (not is_sc) 3143 { 3144 r_write_word_count = r_write_word_count.read() + 1; 3145 } 3146 3147 if (m_cmd_write_eop_fifo.read()) r_write_fsm = WRITE_DIR_REQ; 3205 "MEMC ERROR in WRITE_NEXT state: Illegal write burst"); 3206 3207 size_t index = m_x[(addr_t)(m_cmd_write_addr_fifo.read())]; 3208 bool is_sc = ((m_cmd_write_pktid_fifo.read() & 0x7) == TYPE_SC); 3209 3210 // check that SC command has constant address 3211 assert((not is_sc or (index == r_write_word_index)) && 3212 "MEMC ERROR in WRITE_NEXT state: " 3213 "the address must be constant on a SC command"); 3214 3215 // check that SC command has two flits 3216 assert((not is_sc or m_cmd_write_eop_fifo.read()) && 3217 "MEMC ERROR in WRITE_NEXT state: " 3218 "invalid packet format for SC command"); 3219 3220 // consume a word in the FIFO & write it in the local buffer 3221 cmd_write_fifo_get = true; 3222 3223 r_write_be[index] = m_cmd_write_be_fifo.read(); 3224 r_write_data[index] = m_cmd_write_data_fifo.read(); 3225 3226 // the first flit of a SC command is the reservation key and 3227 // therefore it must not be counted as a data to write 3228 if (not is_sc) 3229 { 3230 r_write_word_count = r_write_word_count.read() + 1; 3231 } 3232 3233 if (m_cmd_write_eop_fifo.read()) 3234 { 3235 r_write_fsm = WRITE_DIR_REQ; 3236 } 3148 3237 3149 3238 #if DEBUG_MEMC_WRITE 3150 if (m_debug) 3151 std::cout << " <MEMC " << name() 3152 << " WRITE_NEXT> Write another word in local buffer" 3153 << std::endl; 3154 #endif 3155 break; 3156 } 3157 /////////////////// 3239 if (m_debug) 3240 { 3241 std::cout << " <MEMC " << name() 3242 << " WRITE_NEXT> Write another word in local buffer" 3243 << std::endl; 3244 } 3245 #endif 3246 break; 3247 } 3248 /////////////////// 3158 3249 case WRITE_DIR_REQ: // Get the lock to the directory 3159 3250 // and access the llsc_global_table 3160 { 3161 if (r_alloc_dir_fsm.read() != ALLOC_DIR_WRITE ) break; 3162 3251 { 3252 if (r_alloc_dir_fsm.read() != ALLOC_DIR_WRITE) break; 3253 3254 if ((r_write_pktid.read() & 0x7) == TYPE_SC) 3255 { 3256 // test address and key match of the SC command on the 3257 // LL/SC table without removing reservation. The reservation 3258 // will be erased after in this FSM. 3259 bool sc_success = m_llsc_table.check(r_write_address.read(), 3260 r_write_sc_key.read()); 3261 3262 r_write_sc_fail = not sc_success; 3263 3264 if (not sc_success) r_write_fsm = WRITE_RSP; 3265 else r_write_fsm = WRITE_DIR_LOCK; 3266 } 3267 else 3268 { 3269 // write burst 3270 #define L2 soclib::common::uint32_log2 3271 addr_t min = r_write_address.read(); 3272 addr_t max = r_write_address.read() + 3273 (r_write_word_count.read() << L2(vci_param_int::B)); 3274 #undef L2 3275 3276 m_llsc_table.sw(min, max); 3277 3278 r_write_fsm = WRITE_DIR_LOCK; 3279 } 3280 3281 #if DEBUG_MEMC_WRITE 3282 if (m_debug) 3283 { 3284 std::cout << " <MEMC " << name() << " WRITE_DIR_REQ> Requesting DIR lock " 3285 << std::endl; 3286 } 3287 #endif 3288 break; 3289 } 3290 //////////////////// 3291 case WRITE_DIR_LOCK: // access directory to check hit/miss 3292 { 3293 assert((r_alloc_dir_fsm.read() == ALLOC_DIR_WRITE) and 3294 "MEMC ERROR in ALLOC_DIR_LOCK state: Bad DIR allocation"); 3295 3296 size_t way = 0; 3297 DirectoryEntry entry(m_cache_directory.read(r_write_address.read(), way)); 3298 3299 if (entry.valid) // hit 3300 { 3301 // copy directory entry in local buffer in case of hit 3302 r_write_is_cnt = entry.is_cnt; 3303 r_write_lock = entry.lock; 3304 r_write_tag = entry.tag; 3305 r_write_copy = entry.owner.srcid; 3306 r_write_copy_inst = entry.owner.inst; 3307 r_write_count = entry.count; 3308 r_write_ptr = entry.ptr; 3309 r_write_way = way; 3310 3311 if (entry.is_cnt and entry.count) r_write_fsm = WRITE_BC_DIR_READ; 3312 else r_write_fsm = WRITE_DIR_HIT; 3313 } 3314 else // miss 3315 { 3316 r_write_fsm = WRITE_MISS_TRT_LOCK; 3317 } 3318 3319 #if DEBUG_MEMC_WRITE 3320 if (m_debug) 3321 { 3322 std::cout << " <MEMC " << name() << " WRITE_DIR_LOCK> Check the directory: " 3323 << " address = " << std::hex << r_write_address.read() 3324 << " / hit = " << std::dec << entry.valid 3325 << " / count = " << entry.count 3326 << " / is_cnt = " << entry.is_cnt ; 3163 3327 if ((r_write_pktid.read() & 0x7) == TYPE_SC) 3164 3328 { 3165 // test address and key match of the SC command on the 3166 // LL/SC table without removing reservation. The reservation 3167 // will be erased after in this FSM. 3168 bool sc_success = m_llsc_table.check(r_write_address.read(), 3169 r_write_sc_key.read()); 3170 3171 r_write_sc_fail = not sc_success; 3172 3173 if (not sc_success) r_write_fsm = WRITE_RSP; 3174 else r_write_fsm = WRITE_DIR_LOCK; 3329 std::cout << " / SC access" << std::endl; 3175 3330 } 3176 3331 else 3177 3332 { 3178 // write burst 3179 #define L2 soclib::common::uint32_log2 3180 addr_t min = r_write_address.read(); 3181 addr_t max = r_write_address.read() + 3182 (r_write_word_count.read() << L2(vci_param_int::B)); 3183 #undef L2 3184 3185 m_llsc_table.sw(min, max); 3186 3187 r_write_fsm = WRITE_DIR_LOCK; 3188 } 3333 std::cout << " / SW access" << std::endl; 3334 } 3335 } 3336 #endif 3337 break; 3338 } 3339 /////////////////// 3340 case WRITE_DIR_HIT: // update the cache directory with Dirty bit 3341 // and update data cache 3342 { 3343 assert((r_alloc_dir_fsm.read() == ALLOC_DIR_WRITE) and 3344 "MEMC ERROR in ALLOC_DIR_HIT state: Bad DIR allocation"); 3345 3346 DirectoryEntry entry; 3347 entry.valid = true; 3348 entry.dirty = true; 3349 entry.tag = r_write_tag.read(); 3350 entry.is_cnt = r_write_is_cnt.read(); 3351 entry.lock = r_write_lock.read(); 3352 entry.owner.srcid = r_write_copy.read(); 3353 entry.owner.inst = r_write_copy_inst.read(); 3354 entry.count = r_write_count.read(); 3355 entry.ptr = r_write_ptr.read(); 3356 3357 size_t set = m_y[(addr_t) (r_write_address.read())]; 3358 size_t way = r_write_way.read(); 3359 3360 // update directory 3361 m_cache_directory.write(set, way, entry); 3362 3363 // owner is true when the the first registered copy is the writer itself 3364 bool owner = ((r_write_copy.read() == r_write_srcid.read()) 3365 and not r_write_copy_inst.read()); 3366 3367 // no_update is true when there is no need for coherence transaction 3368 bool no_update = ((r_write_count.read() == 0) or 3369 (owner and (r_write_count.read() == 1) and 3370 ((r_write_pktid.read() & 0x7) != TYPE_SC))); 3371 3372 // write data in the cache if no coherence transaction 3373 if (no_update) 3374 { 3375 // SC command but zero copies 3376 if ((r_write_pktid.read() & 0x7) == TYPE_SC) 3377 { 3378 m_llsc_table.sc(r_write_address.read(), 3379 r_write_sc_key.read()); 3380 } 3381 3382 for (size_t word = 0; word < m_words; word++) 3383 { 3384 m_cache_data.write(way, 3385 set, 3386 word, 3387 r_write_data[word].read(), 3388 r_write_be[word].read()); 3389 } 3390 } 3391 3392 if (owner and not no_update and ((r_write_pktid.read() & 0x7) != TYPE_SC)) 3393 { 3394 r_write_count = r_write_count.read() - 1; 3395 } 3396 3397 if (no_update) // Write transaction completed 3398 { 3399 r_write_fsm = WRITE_RSP; 3400 } 3401 else // coherence update required 3402 { 3403 if (!r_write_to_cc_send_multi_req.read() and 3404 !r_write_to_cc_send_brdcast_req.read()) 3405 { 3406 r_write_fsm = WRITE_UPT_LOCK; 3407 } 3408 else 3409 { 3410 r_write_fsm = WRITE_WAIT; 3411 } 3412 } 3189 3413 3190 3414 #if DEBUG_MEMC_WRITE 3191 if (m_debug) 3192 std::cout << " <MEMC " << name() << " WRITE_DIR_REQ> Requesting DIR lock " 3193 << std::endl; 3194 #endif 3195 break; 3196 } 3197 //////////////////// 3198 case WRITE_DIR_LOCK: // access directory to check hit/miss 3199 { 3200 assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_WRITE) and 3201 "MEMC ERROR in ALLOC_DIR_LOCK state: Bad DIR allocation"); 3202 3203 size_t way = 0; 3204 DirectoryEntry entry(m_cache_directory.read(r_write_address.read(), way)); 3205 3206 if (entry.valid) // hit 3207 { 3208 // copy directory entry in local buffer in case of hit 3209 r_write_is_cnt = entry.is_cnt; 3210 r_write_lock = entry.lock; 3211 r_write_tag = entry.tag; 3212 r_write_copy = entry.owner.srcid; 3213 r_write_copy_inst = entry.owner.inst; 3214 r_write_count = entry.count; 3215 r_write_ptr = entry.ptr; 3216 r_write_way = way; 3217 3218 if (entry.is_cnt and entry.count) r_write_fsm = WRITE_BC_DIR_READ; 3219 else r_write_fsm = WRITE_DIR_HIT; 3220 } 3221 else // miss 3222 { 3223 r_write_fsm = WRITE_MISS_TRT_LOCK; 3224 } 3225 3226 #if DEBUG_MEMC_WRITE 3227 if (m_debug) 3228 { 3229 std::cout << " <MEMC " << name() << " WRITE_DIR_LOCK> Check the directory: " 3230 << " address = " << std::hex << r_write_address.read() 3231 << " / hit = " << std::dec << entry.valid 3232 << " / count = " << entry.count 3233 << " / is_cnt = " << entry.is_cnt ; 3234 if ((r_write_pktid.read() & 0x7) == TYPE_SC) 3235 std::cout << " / SC access" << std::endl; 3236 else 3237 std::cout << " / SW access" << std::endl; 3238 } 3239 #endif 3240 break; 3241 } 3242 /////////////////// 3243 case WRITE_DIR_HIT: // update the cache directory with Dirty bit 3244 // and update data cache 3245 { 3246 assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_WRITE) and 3247 "MEMC ERROR in ALLOC_DIR_HIT state: Bad DIR allocation"); 3248 3249 DirectoryEntry entry; 3250 entry.valid = true; 3251 entry.dirty = true; 3252 entry.tag = r_write_tag.read(); 3253 entry.is_cnt = r_write_is_cnt.read(); 3254 entry.lock = r_write_lock.read(); 3255 entry.owner.srcid = r_write_copy.read(); 3256 entry.owner.inst = r_write_copy_inst.read(); 3257 entry.count = r_write_count.read(); 3258 entry.ptr = r_write_ptr.read(); 3259 3260 size_t set = m_y[(addr_t)(r_write_address.read())]; 3261 size_t way = r_write_way.read(); 3262 3263 // update directory 3264 m_cache_directory.write(set, way, entry); 3265 3266 // owner is true when the the first registered copy is the writer itself 3267 bool owner = ( (r_write_copy.read() == r_write_srcid.read()) 3268 and not r_write_copy_inst.read()); 3269 3270 // no_update is true when there is no need for coherence transaction 3271 bool no_update = ( (r_write_count.read() == 0) or 3272 (owner and (r_write_count.read() == 1) and 3273 ((r_write_pktid.read() & 0x7) != TYPE_SC))); 3274 3275 // write data in the cache if no coherence transaction 3415 if (m_debug) 3416 { 3276 3417 if (no_update) 3277 3418 { 3278 // SC command but zero copies 3419 std::cout << " <MEMC " << name() 3420 << " WRITE_DIR_HIT> Write into cache / No coherence transaction" << std::endl; 3421 } 3422 else 3423 { 3424 std::cout << " <MEMC " << name() << " WRITE_DIR_HIT> Coherence update required:" 3425 << " is_cnt = " << r_write_is_cnt.read() 3426 << " nb_copies = " << std::dec << r_write_count.read() << std::endl; 3427 if (owner) 3428 { 3429 std::cout << " ... but the first copy is the writer" << std::endl; 3430 } 3431 } 3432 } 3433 #endif 3434 break; 3435 } 3436 //////////////////// 3437 case WRITE_UPT_LOCK: // Try to register the update request in UPT 3438 { 3439 if (r_alloc_upt_fsm.read() == ALLOC_UPT_WRITE) 3440 { 3441 bool wok = false; 3442 size_t index = 0; 3443 size_t srcid = r_write_srcid.read(); 3444 size_t trdid = r_write_trdid.read(); 3445 size_t pktid = r_write_pktid.read(); 3446 addr_t nline = m_nline[(addr_t) (r_write_address.read())]; 3447 size_t nb_copies = r_write_count.read(); 3448 size_t set = m_y[(addr_t) (r_write_address.read())]; 3449 size_t way = r_write_way.read(); 3450 3451 wok = m_upt.set(true, // it's an update transaction 3452 false, // it's not a broadcast 3453 true, // response required 3454 false, // no acknowledge required 3455 srcid, 3456 trdid, 3457 pktid, 3458 nline, 3459 nb_copies, 3460 index); 3461 3462 if (wok) // write data in cache 3463 { 3279 3464 if ((r_write_pktid.read() & 0x7) == TYPE_SC) 3280 3465 { 3281 3466 m_llsc_table.sc(r_write_address.read(), 3282 r_write_sc_key.read());3467 r_write_sc_key.read()); 3283 3468 } 3284 3469 3285 for (size_t word=0 ; word<m_words; word++)3470 for (size_t word = 0; word < m_words; word++) 3286 3471 { 3287 m_cache_data.write( way,3288 set, 3289 word, 3290 r_write_data[word].read(), 3472 m_cache_data.write(way, 3473 set, 3474 word, 3475 r_write_data[word].read(), 3291 3476 r_write_be[word].read()); 3292 3477 } 3293 3478 } 3294 3479 3295 if (owner and not no_update and ((r_write_pktid.read() & 0x7) != TYPE_SC)) 3296 { 3297 r_write_count = r_write_count.read() - 1; 3298 } 3299 3300 if (no_update) // Write transaction completed 3301 { 3302 r_write_fsm = WRITE_RSP; 3303 } 3304 else // coherence update required 3305 { 3306 if (!r_write_to_cc_send_multi_req.read() and 3307 !r_write_to_cc_send_brdcast_req.read()) 3480 #if DEBUG_MEMC_WRITE 3481 if (m_debug and wok) 3482 { 3483 std::cout << " <MEMC " << name() 3484 << " WRITE_UPT_LOCK> Register the multicast update in UPT / " 3485 << " nb_copies = " << r_write_count.read() << std::endl; 3486 } 3487 #endif 3488 r_write_upt_index = index; 3489 // releases the lock protecting UPT and the DIR if no entry... 3490 if (wok) r_write_fsm = WRITE_UPT_HEAP_LOCK; 3491 else r_write_fsm = WRITE_WAIT; 3492 } 3493 break; 3494 } 3495 3496 ///////////////////////// 3497 case WRITE_UPT_HEAP_LOCK: // get access to heap 3498 { 3499 if (r_alloc_heap_fsm.read() == ALLOC_HEAP_WRITE) 3500 { 3501 3502 #if DEBUG_MEMC_WRITE 3503 if (m_debug) 3504 { 3505 std::cout << " <MEMC " << name() 3506 << " WRITE_UPT_HEAP_LOCK> Get acces to the HEAP" << std::endl; 3507 } 3508 #endif 3509 r_write_fsm = WRITE_UPT_REQ; 3510 } 3511 break; 3512 } 3513 3514 ////////////////// 3515 case WRITE_UPT_REQ: // prepare the coherence transaction for the CC_SEND FSM 3516 // and write the first copy in the FIFO 3517 // send the request if only one copy 3518 { 3519 assert(not r_write_to_cc_send_multi_req.read() and 3520 not r_write_to_cc_send_brdcast_req.read() and 3521 "Error in VCI_MEM_CACHE : pending multicast or broadcast\n" 3522 "transaction in WRITE_UPT_REQ state"); 3523 3524 r_write_to_cc_send_brdcast_req = false; 3525 r_write_to_cc_send_trdid = r_write_upt_index.read(); 3526 r_write_to_cc_send_nline = m_nline[(addr_t)(r_write_address.read())]; 3527 r_write_to_cc_send_index = r_write_word_index.read(); 3528 r_write_to_cc_send_count = r_write_word_count.read(); 3529 3530 for (size_t i = 0; i < m_words; i++) 3531 { 3532 r_write_to_cc_send_be[i] = r_write_be[i].read(); 3533 } 3534 3535 size_t min = r_write_word_index.read(); 3536 size_t max = r_write_word_index.read() + r_write_word_count.read(); 3537 for (size_t i = min; i <= max; i++) 3538 { 3539 r_write_to_cc_send_data[i] = r_write_data[i]; 3540 } 3541 3542 if ((r_write_copy.read() != r_write_srcid.read()) or 3543 ((r_write_pktid.read() & 0x7) == TYPE_SC) or 3544 r_write_copy_inst.read()) 3545 { 3546 // put the first srcid in the fifo 3547 write_to_cc_send_fifo_put = true; 3548 write_to_cc_send_fifo_inst = r_write_copy_inst.read(); 3549 write_to_cc_send_fifo_srcid = r_write_copy.read(); 3550 if (r_write_count.read() == 1) 3551 { 3552 r_write_fsm = WRITE_IDLE; 3553 r_write_to_cc_send_multi_req = true; 3554 } 3555 else 3556 { 3557 r_write_fsm = WRITE_UPT_NEXT; 3558 r_write_to_dec = false; 3559 3560 } 3561 } 3562 else 3563 { 3564 r_write_fsm = WRITE_UPT_NEXT; 3565 r_write_to_dec = false; 3566 } 3567 3568 #if DEBUG_MEMC_WRITE 3569 if (m_debug) 3570 { 3571 std::cout 3572 << " <MEMC " << name() 3573 << " WRITE_UPT_REQ> Post first request to CC_SEND FSM" 3574 << " / srcid = " << std::dec << r_write_copy.read() 3575 << " / inst = " << std::dec << r_write_copy_inst.read() << std::endl; 3576 3577 if (r_write_count.read() == 1) 3578 { 3579 std::cout << " ... and this is the last" << std::endl; 3580 } 3581 } 3582 #endif 3583 break; 3584 } 3585 3586 /////////////////// 3587 case WRITE_UPT_NEXT: 3588 { 3589 // continue the multi-update request to CC_SEND fsm 3590 // when there is copies in the heap. 3591 // if one copy in the heap is the writer itself 3592 // the corresponding SRCID should not be written in the fifo, 3593 // but the UPT counter must be decremented. 3594 // As this decrement is done in the WRITE_UPT_DEC state, 3595 // after the last copy has been found, the decrement request 3596 // must be registered in the r_write_to_dec flip-flop. 3597 3598 HeapEntry entry = m_heap.read(r_write_ptr.read()); 3599 3600 bool dec_upt_counter; 3601 3602 // put the next srcid in the fifo 3603 if ((entry.owner.srcid != r_write_srcid.read()) or 3604 ((r_write_pktid.read() & 0x7) == TYPE_SC) or 3605 entry.owner.inst) 3606 { 3607 dec_upt_counter = false; 3608 write_to_cc_send_fifo_put = true; 3609 write_to_cc_send_fifo_inst = entry.owner.inst; 3610 write_to_cc_send_fifo_srcid = entry.owner.srcid; 3611 3612 #if DEBUG_MEMC_WRITE 3613 if (m_debug) 3614 { 3615 std::cout << " <MEMC " << name() << " WRITE_UPT_NEXT> Post another request to CC_SEND FSM" 3616 << " / heap_index = " << std::dec << r_write_ptr.read() 3617 << " / srcid = " << std::dec << r_write_copy.read() 3618 << " / inst = " << std::dec << r_write_copy_inst.read() << std::endl; 3619 if (entry.next == r_write_ptr.read()) 3308 3620 { 3309 r_write_fsm = WRITE_UPT_LOCK; 3621 std::cout << " ... and this is the last" << std::endl; 3622 } 3623 } 3624 #endif 3625 } 3626 else // the UPT counter must be decremented 3627 { 3628 dec_upt_counter = true; 3629 #if DEBUG_MEMC_WRITE 3630 if (m_debug) 3631 { 3632 std::cout << " <MEMC " << name() << " WRITE_UPT_NEXT> Skip one entry in heap matching the writer" 3633 << " / heap_index = " << std::dec << r_write_ptr.read() 3634 << " / srcid = " << std::dec << r_write_copy.read() 3635 << " / inst = " << std::dec << r_write_copy_inst.read() << std::endl; 3636 if (entry.next == r_write_ptr.read()) 3637 { 3638 std::cout << " ... and this is the last" << std::endl; 3639 } 3640 } 3641 #endif 3642 } 3643 3644 // register the possible UPT decrement request 3645 r_write_to_dec = dec_upt_counter or r_write_to_dec.read(); 3646 3647 if (not m_write_to_cc_send_inst_fifo.wok()) 3648 { 3649 std::cout << "*** VCI_MEM_CACHE ERROR " << name() << " WRITE_UPT_NEXT state" << std::endl 3650 << "The write_to_cc_send_fifo should not be full" << std::endl 3651 << "as the depth should be larger than the max number of copies" << std::endl; 3652 exit(0); 3653 } 3654 3655 r_write_ptr = entry.next; 3656 3657 if (entry.next == r_write_ptr.read()) // last copy 3658 { 3659 r_write_to_cc_send_multi_req = true; 3660 if (r_write_to_dec.read() or dec_upt_counter) r_write_fsm = WRITE_UPT_DEC; 3661 else r_write_fsm = WRITE_IDLE; 3662 } 3663 break; 3664 } 3665 3666 ////////////////// 3667 case WRITE_UPT_DEC: 3668 { 3669 // If the initial writer has a copy, it should not 3670 // receive an update request, but the counter in the 3671 // update table must be decremented by the MULTI_ACK FSM. 3672 3673 if (!r_write_to_multi_ack_req.read()) 3674 { 3675 r_write_to_multi_ack_req = true; 3676 r_write_to_multi_ack_upt_index = r_write_upt_index.read(); 3677 r_write_fsm = WRITE_IDLE; 3678 } 3679 break; 3680 } 3681 3682 /////////////// 3683 case WRITE_RSP: // Post a request to TGT_RSP FSM to acknowledge the write 3684 // In order to increase the Write requests throughput, 3685 // we don't wait to return in the IDLE state to consume 3686 // a new request in the write FIFO 3687 { 3688 if (not r_write_to_tgt_rsp_req.read()) 3689 { 3690 // post the request to TGT_RSP_FSM 3691 r_write_to_tgt_rsp_req = true; 3692 r_write_to_tgt_rsp_srcid = r_write_srcid.read(); 3693 r_write_to_tgt_rsp_trdid = r_write_trdid.read(); 3694 r_write_to_tgt_rsp_pktid = r_write_pktid.read(); 3695 r_write_to_tgt_rsp_sc_fail = r_write_sc_fail.read(); 3696 3697 // try to get a new write request from the FIFO 3698 if (not m_cmd_write_addr_fifo.rok()) 3699 { 3700 r_write_fsm = WRITE_IDLE; 3701 } 3702 else 3703 { 3704 // consume a word in the FIFO & write it in the local buffer 3705 cmd_write_fifo_get = true; 3706 size_t index = m_x[(addr_t) (m_cmd_write_addr_fifo.read())]; 3707 3708 r_write_address = (addr_t) (m_cmd_write_addr_fifo.read()); 3709 r_write_word_index = index; 3710 r_write_word_count = 0; 3711 r_write_data[index] = m_cmd_write_data_fifo.read(); 3712 r_write_srcid = m_cmd_write_srcid_fifo.read(); 3713 r_write_trdid = m_cmd_write_trdid_fifo.read(); 3714 r_write_pktid = m_cmd_write_pktid_fifo.read(); 3715 3716 // if SC command, get the SC key 3717 if ((m_cmd_write_pktid_fifo.read() & 0x7) == TYPE_SC) 3718 { 3719 assert(not m_cmd_write_eop_fifo.read() && 3720 "MEMC ERROR in WRITE_RSP state: " 3721 "invalid packet format for SC command"); 3722 3723 r_write_sc_key = m_cmd_write_data_fifo.read(); 3724 } 3725 3726 // initialize the be field for all words 3727 for (size_t word = 0; word < m_words; word++) 3728 { 3729 if (word == index) r_write_be[word] = m_cmd_write_be_fifo.read(); 3730 else r_write_be[word] = 0x0; 3731 } 3732 3733 if (m_cmd_write_eop_fifo.read()) 3734 { 3735 r_write_fsm = WRITE_DIR_REQ; 3310 3736 } 3311 3737 else 3312 3738 { 3313 r_write_fsm = WRITE_ WAIT;3739 r_write_fsm = WRITE_NEXT; 3314 3740 } 3315 3741 } … … 3318 3744 if (m_debug) 3319 3745 { 3320 if (no_update) 3746 std::cout << " <MEMC " << name() << " WRITE_RSP> Post a request to TGT_RSP FSM" 3747 << " : rsrcid = " << std::hex << r_write_srcid.read() << std::endl; 3748 if (m_cmd_write_addr_fifo.rok()) 3321 3749 { 3322 std::cout << " <MEMC " << name() 3323 << " WRITE_DIR_HIT> Write into cache / No coherence transaction" << std::endl; 3750 std::cout << " New Write request: " 3751 << " srcid = " << std::hex << m_cmd_write_srcid_fifo.read() 3752 << " / address = " << m_cmd_write_addr_fifo.read() 3753 << " / data = " << m_cmd_write_data_fifo.read() << std::endl; 3324 3754 } 3325 else 3326 { 3327 std::cout << " <MEMC " << name() << " WRITE_DIR_HIT> Coherence update required:" 3328 << " is_cnt = " << r_write_is_cnt.read() 3329 << " nb_copies = " << std::dec << r_write_count.read() << std::endl; 3330 if (owner) std::cout << " ... but the first copy is the writer" << std::endl; 3331 } 3332 } 3333 #endif 3334 break; 3335 } 3336 //////////////////// 3337 case WRITE_UPT_LOCK: // Try to register the update request in UPT 3338 { 3339 if (r_alloc_upt_fsm.read() == ALLOC_UPT_WRITE) 3340 { 3341 bool wok = false; 3342 size_t index = 0; 3343 size_t srcid = r_write_srcid.read(); 3344 size_t trdid = r_write_trdid.read(); 3345 size_t pktid = r_write_pktid.read(); 3346 addr_t nline = m_nline[(addr_t)(r_write_address.read())]; 3347 size_t nb_copies = r_write_count.read(); 3348 size_t set = m_y[(addr_t)(r_write_address.read())]; 3349 size_t way = r_write_way.read(); 3350 3351 wok = m_upt.set( true, // it's an update transaction 3352 false, // it's not a broadcast 3353 true, // response required 3354 false, // no acknowledge required 3355 srcid, 3356 trdid, 3357 pktid, 3358 nline, 3359 nb_copies, 3360 index); 3361 3362 if (wok ) // write data in cache 3363 { 3364 3365 if ((r_write_pktid.read() & 0x7) == TYPE_SC) 3366 { 3367 m_llsc_table.sc(r_write_address.read(), 3368 r_write_sc_key.read()); 3369 } 3370 3371 for(size_t word=0 ; word<m_words ; word++) 3372 { 3373 m_cache_data.write( way, 3374 set, 3375 word, 3376 r_write_data[word].read(), 3377 r_write_be[word].read()); 3378 } 3379 } 3380 3381 #if DEBUG_MEMC_WRITE 3382 if (m_debug and wok) 3383 { 3384 std::cout << " <MEMC " << name() 3385 << " WRITE_UPT_LOCK> Register the multicast update in UPT / " 3386 << " nb_copies = " << r_write_count.read() << std::endl; 3387 } 3388 #endif 3389 r_write_upt_index = index; 3390 // releases the lock protecting UPT and the DIR if no entry... 3391 if (wok) r_write_fsm = WRITE_UPT_HEAP_LOCK; 3392 else r_write_fsm = WRITE_WAIT; 3393 } 3394 break; 3395 } 3396 3397 ///////////////////////// 3398 case WRITE_UPT_HEAP_LOCK: // get access to heap 3399 { 3400 if (r_alloc_heap_fsm.read() == ALLOC_HEAP_WRITE) 3401 { 3402 3403 #if DEBUG_MEMC_WRITE 3404 if (m_debug) 3405 std::cout << " <MEMC " << name() 3406 << " WRITE_UPT_HEAP_LOCK> Get acces to the HEAP" << std::endl; 3407 #endif 3408 r_write_fsm = WRITE_UPT_REQ; 3409 } 3410 break; 3411 } 3412 3413 ////////////////// 3414 case WRITE_UPT_REQ: // prepare the coherence transaction for the CC_SEND FSM 3415 // and write the first copy in the FIFO 3416 // send the request if only one copy 3417 { 3418 assert(not r_write_to_cc_send_multi_req.read() and 3419 not r_write_to_cc_send_brdcast_req.read() and 3420 "Error in VCI_MEM_CACHE : pending multicast or broadcast\n" 3421 "transaction in WRITE_UPT_REQ state" 3422 ); 3423 3424 r_write_to_cc_send_brdcast_req = false; 3425 r_write_to_cc_send_trdid = r_write_upt_index.read(); 3426 r_write_to_cc_send_nline = m_nline[(addr_t)(r_write_address.read())]; 3427 r_write_to_cc_send_index = r_write_word_index.read(); 3428 r_write_to_cc_send_count = r_write_word_count.read(); 3429 3430 for(size_t i=0; i<m_words ; i++) r_write_to_cc_send_be[i]=r_write_be[i].read(); 3431 3432 size_t min = r_write_word_index.read(); 3433 size_t max = r_write_word_index.read() + r_write_word_count.read(); 3434 for(size_t i=min ; i<=max ; i++) r_write_to_cc_send_data[i] = r_write_data[i]; 3435 3436 if ((r_write_copy.read() != r_write_srcid.read()) or 3437 ((r_write_pktid.read() & 0x7) == TYPE_SC) or 3438 r_write_copy_inst.read()) 3439 { 3440 // put the first srcid in the fifo 3441 write_to_cc_send_fifo_put = true; 3442 write_to_cc_send_fifo_inst = r_write_copy_inst.read(); 3443 write_to_cc_send_fifo_srcid = r_write_copy.read(); 3444 if (r_write_count.read() == 1) 3445 { 3446 r_write_fsm = WRITE_IDLE; 3447 r_write_to_cc_send_multi_req = true; 3448 } 3449 else 3450 { 3451 r_write_fsm = WRITE_UPT_NEXT; 3452 r_write_to_dec = false; 3453 3454 } 3455 } 3456 else 3457 { 3458 r_write_fsm = WRITE_UPT_NEXT; 3459 r_write_to_dec = false; 3460 } 3755 } 3756 #endif 3757 } 3758 break; 3759 } 3760 3761 ///////////////////////// 3762 case WRITE_MISS_TRT_LOCK: // Miss : check Transaction Table 3763 { 3764 if (r_alloc_trt_fsm.read() == ALLOC_TRT_WRITE) 3765 { 3461 3766 3462 3767 #if DEBUG_MEMC_WRITE 3463 3768 if (m_debug) 3464 3769 { 3465 std::cout 3466 << " <MEMC " << name() 3467 << " WRITE_UPT_REQ> Post first request to CC_SEND FSM" 3468 << " / srcid = " << std::dec << r_write_copy.read() 3469 << " / inst = " << std::dec << r_write_copy_inst.read() << std::endl; 3470 3471 if (r_write_count.read() == 1) 3472 std::cout << " ... and this is the last" << std::endl; 3473 } 3474 #endif 3475 break; 3476 } 3477 3478 /////////////////// 3479 case WRITE_UPT_NEXT: 3480 { 3481 // continue the multi-update request to CC_SEND fsm 3482 // when there is copies in the heap. 3483 // if one copy in the heap is the writer itself 3484 // the corresponding SRCID should not be written in the fifo, 3485 // but the UPT counter must be decremented. 3486 // As this decrement is done in the WRITE_UPT_DEC state, 3487 // after the last copy has been found, the decrement request 3488 // must be registered in the r_write_to_dec flip-flop. 3489 3490 HeapEntry entry = m_heap.read(r_write_ptr.read()); 3491 3492 bool dec_upt_counter; 3493 3494 // put the next srcid in the fifo 3495 if ((entry.owner.srcid != r_write_srcid.read()) or 3496 ((r_write_pktid.read() & 0x7) == TYPE_SC) or 3497 entry.owner.inst) 3498 { 3499 dec_upt_counter = false; 3500 write_to_cc_send_fifo_put = true; 3501 write_to_cc_send_fifo_inst = entry.owner.inst; 3502 write_to_cc_send_fifo_srcid = entry.owner.srcid; 3770 std::cout << " <MEMC " << name() << " WRITE_MISS_TRT_LOCK> Check the TRT" << std::endl; 3771 } 3772 #endif 3773 size_t hit_index = 0; 3774 size_t wok_index = 0; 3775 addr_t addr = (addr_t) r_write_address.read(); 3776 bool hit_read = m_trt.hit_read(m_nline[addr], hit_index); 3777 bool hit_write = m_trt.hit_write(m_nline[addr]); 3778 bool wok = not m_trt.full(wok_index); 3779 3780 // wait an empty entry in TRT 3781 if (not hit_read and (not wok or hit_write)) 3782 { 3783 r_write_fsm = WRITE_WAIT; 3784 m_cpt_trt_full++; 3785 3786 break; 3787 } 3788 3789 if ((r_write_pktid.read() & 0x7) == TYPE_SC) 3790 { 3791 m_llsc_table.sc(r_write_address.read(), 3792 r_write_sc_key.read()); 3793 } 3794 3795 // register the modified data in TRT 3796 if (hit_read) 3797 { 3798 r_write_trt_index = hit_index; 3799 r_write_fsm = WRITE_MISS_TRT_DATA; 3800 m_cpt_write_miss++; 3801 break; 3802 } 3803 3804 // set a new entry in TRT 3805 if (wok and not hit_write) 3806 { 3807 r_write_trt_index = wok_index; 3808 r_write_fsm = WRITE_MISS_TRT_SET; 3809 m_cpt_write_miss++; 3810 break; 3811 } 3812 3813 assert(false && "VCI_MEM_CACHE ERROR: this part must not be reached"); 3814 } 3815 break; 3816 } 3817 3818 //////////////// 3819 case WRITE_WAIT: // release the locks protecting the shared ressources 3820 { 3503 3821 3504 3822 #if DEBUG_MEMC_WRITE 3505 if (m_debug) 3506 { 3507 std::cout << " <MEMC " << name() << " WRITE_UPT_NEXT> Post another request to CC_SEND FSM" 3508 << " / heap_index = " << std::dec << r_write_ptr.read() 3509 << " / srcid = " << std::dec << r_write_copy.read() 3510 << " / inst = " << std::dec << r_write_copy_inst.read() << std::endl; 3511 if (entry.next == r_write_ptr.read()) 3512 std::cout << " ... and this is the last" << std::endl; 3513 } 3514 #endif 3515 } 3516 else // the UPT counter must be decremented 3517 { 3518 dec_upt_counter = true; 3519 3520 #if DEBUG_MEMC_WRITE 3521 if (m_debug) 3522 { 3523 std::cout << " <MEMC " << name() << " WRITE_UPT_NEXT> Skip one entry in heap matching the writer" 3524 << " / heap_index = " << std::dec << r_write_ptr.read() 3525 << " / srcid = " << std::dec << r_write_copy.read() 3526 << " / inst = " << std::dec << r_write_copy_inst.read() << std::endl; 3527 if (entry.next == r_write_ptr.read()) 3528 std::cout << " ... and this is the last" << std::endl; 3529 } 3530 #endif 3531 } 3532 3533 // register the possible UPT decrement request 3534 r_write_to_dec = dec_upt_counter or r_write_to_dec.read(); 3535 3536 if (not m_write_to_cc_send_inst_fifo.wok()) 3537 { 3538 std::cout << "VCI_MEM_CACHE ERROR " << name() << " WRITE_UPT_NEXT state" << std::endl 3539 << "The write_to_cc_send_fifo should not be full" << std::endl 3540 << "as the depth should be larger than the max number of copies" << std::endl; 3541 exit(0); 3542 } 3543 3544 r_write_ptr = entry.next; 3545 3546 if (entry.next == r_write_ptr.read()) // last copy 3547 { 3548 r_write_to_cc_send_multi_req = true; 3549 if (r_write_to_dec.read() or dec_upt_counter) r_write_fsm = WRITE_UPT_DEC; 3550 else r_write_fsm = WRITE_IDLE; 3551 } 3552 break; 3553 } 3554 3555 ////////////////// 3556 case WRITE_UPT_DEC: 3557 { 3558 // If the initial writer has a copy, it should not 3559 // receive an update request, but the counter in the 3560 // update table must be decremented by the MULTI_ACK FSM. 3561 3562 if (!r_write_to_multi_ack_req.read()) 3563 { 3564 r_write_to_multi_ack_req = true; 3565 r_write_to_multi_ack_upt_index = r_write_upt_index.read(); 3566 r_write_fsm = WRITE_IDLE; 3567 } 3568 break; 3569 } 3570 3571 /////////////// 3572 case WRITE_RSP: // Post a request to TGT_RSP FSM to acknowledge the write 3573 // In order to increase the Write requests throughput, 3574 // we don't wait to return in the IDLE state to consume 3575 // a new request in the write FIFO 3576 { 3577 if (not r_write_to_tgt_rsp_req.read()) 3578 { 3579 // post the request to TGT_RSP_FSM 3580 r_write_to_tgt_rsp_req = true; 3581 r_write_to_tgt_rsp_srcid = r_write_srcid.read(); 3582 r_write_to_tgt_rsp_trdid = r_write_trdid.read(); 3583 r_write_to_tgt_rsp_pktid = r_write_pktid.read(); 3584 r_write_to_tgt_rsp_sc_fail = r_write_sc_fail.read(); 3585 3586 // try to get a new write request from the FIFO 3587 if (not m_cmd_write_addr_fifo.rok()) 3588 { 3589 r_write_fsm = WRITE_IDLE; 3590 } 3591 else 3592 { 3593 // consume a word in the FIFO & write it in the local buffer 3594 cmd_write_fifo_get = true; 3595 size_t index = m_x[(addr_t) (m_cmd_write_addr_fifo.read())]; 3596 3597 r_write_address = (addr_t) (m_cmd_write_addr_fifo.read()); 3598 r_write_word_index = index; 3599 r_write_word_count = 0; 3600 r_write_data[index] = m_cmd_write_data_fifo.read(); 3601 r_write_srcid = m_cmd_write_srcid_fifo.read(); 3602 r_write_trdid = m_cmd_write_trdid_fifo.read(); 3603 r_write_pktid = m_cmd_write_pktid_fifo.read(); 3604 3605 // if SC command, get the SC key 3606 if ((m_cmd_write_pktid_fifo.read() & 0x7) == TYPE_SC) 3607 { 3608 assert( not m_cmd_write_eop_fifo.read() && 3609 "MEMC ERROR in WRITE_RSP state: " 3610 "invalid packet format for SC command"); 3611 3612 r_write_sc_key = m_cmd_write_data_fifo.read(); 3613 } 3614 3615 // initialize the be field for all words 3616 for(size_t word=0 ; word<m_words ; word++) 3617 { 3618 if (word == index) r_write_be[word] = m_cmd_write_be_fifo.read(); 3619 else r_write_be[word] = 0x0; 3620 } 3621 3622 if (m_cmd_write_eop_fifo.read()) 3623 { 3624 r_write_fsm = WRITE_DIR_REQ; 3625 } 3626 else 3627 { 3628 r_write_fsm = WRITE_NEXT; 3629 } 3630 } 3631 3632 #if DEBUG_MEMC_WRITE 3633 if (m_debug) 3634 { 3635 std::cout << " <MEMC " << name() << " WRITE_RSP> Post a request to TGT_RSP FSM" 3636 << " : rsrcid = " << std::hex << r_write_srcid.read() << std::endl; 3637 if (m_cmd_write_addr_fifo.rok()) 3638 { 3639 std::cout << " New Write request: " 3640 << " srcid = " << std::hex << m_cmd_write_srcid_fifo.read() 3641 << " / address = " << m_cmd_write_addr_fifo.read() 3642 << " / data = " << m_cmd_write_data_fifo.read() << std::endl; 3643 } 3644 } 3645 #endif 3646 } 3647 break; 3648 } 3649 3650 ///////////////////////// 3651 case WRITE_MISS_TRT_LOCK: // Miss : check Transaction Table 3652 { 3653 if (r_alloc_trt_fsm.read() == ALLOC_TRT_WRITE) 3654 { 3655 3656 #if DEBUG_MEMC_WRITE 3657 if (m_debug) 3658 std::cout << " <MEMC " << name() << " WRITE_MISS_TRT_LOCK> Check the TRT" << std::endl; 3659 #endif 3660 size_t hit_index = 0; 3661 size_t wok_index = 0; 3662 addr_t addr = (addr_t) r_write_address.read(); 3663 bool hit_read = m_trt.hit_read(m_nline[addr], hit_index); 3664 bool hit_write = m_trt.hit_write(m_nline[addr]); 3665 bool wok = not m_trt.full(wok_index); 3666 3667 // wait an empty entry in TRT 3668 if(not hit_read and (not wok or hit_write)) 3669 { 3670 r_write_fsm = WRITE_WAIT; 3671 m_cpt_trt_full++; 3672 3673 break; 3674 } 3675 3676 if ((r_write_pktid.read() & 0x7) == TYPE_SC) 3677 { 3678 m_llsc_table.sc(r_write_address.read(), 3679 r_write_sc_key.read()); 3680 } 3681 3682 // register the modified data in TRT 3683 if (hit_read) 3684 { 3685 r_write_trt_index = hit_index; 3686 r_write_fsm = WRITE_MISS_TRT_DATA; 3687 m_cpt_write_miss++; 3688 break; 3689 } 3690 3691 // set a new entry in TRT 3692 if (wok and not hit_write) 3693 { 3694 r_write_trt_index = wok_index; 3695 r_write_fsm = WRITE_MISS_TRT_SET; 3696 m_cpt_write_miss++; 3697 break; 3698 } 3699 3700 assert(false && "VCI_MEM_CACHE ERROR: this part must not be reached"); 3701 } 3702 break; 3703 } 3704 3705 //////////////// 3706 case WRITE_WAIT: // release the locks protecting the shared ressources 3707 { 3823 if (m_debug) 3824 { 3825 std::cout << " <MEMC " << name() << " WRITE_WAIT> Releases the locks before retry" << std::endl; 3826 } 3827 #endif 3828 r_write_fsm = WRITE_DIR_REQ; 3829 break; 3830 } 3831 3832 //////////////////////// 3833 case WRITE_MISS_TRT_SET: // register a new transaction in TRT (Write Buffer) 3834 { 3835 if (r_alloc_trt_fsm.read() == ALLOC_TRT_WRITE) 3836 { 3837 std::vector<be_t> be_vector; 3838 std::vector<data_t> data_vector; 3839 be_vector.clear(); 3840 data_vector.clear(); 3841 for (size_t i = 0; i < m_words; i++) 3842 { 3843 be_vector.push_back(r_write_be[i]); 3844 data_vector.push_back(r_write_data[i]); 3845 } 3846 m_trt.set(r_write_trt_index.read(), 3847 true, // read request to XRAM 3848 m_nline[(addr_t)(r_write_address.read())], 3849 r_write_srcid.read(), 3850 r_write_trdid.read(), 3851 r_write_pktid.read(), 3852 false, // not a processor read 3853 0, // not a single word 3854 0, // word index 3855 be_vector, 3856 data_vector); 3857 r_write_fsm = WRITE_MISS_XRAM_REQ; 3708 3858 3709 3859 #if DEBUG_MEMC_WRITE 3710 3860 if (m_debug) 3711 std::cout << " <MEMC " << name() << " WRITE_WAIT> Releases the locks before retry" << std::endl; 3712 #endif 3713 r_write_fsm = WRITE_DIR_REQ; 3714 break; 3715 } 3716 3717 //////////////////////// 3718 case WRITE_MISS_TRT_SET: // register a new transaction in TRT (Write Buffer) 3719 { 3720 if (r_alloc_trt_fsm.read() == ALLOC_TRT_WRITE) 3721 { 3722 std::vector<be_t> be_vector; 3723 std::vector<data_t> data_vector; 3724 be_vector.clear(); 3725 data_vector.clear(); 3726 for(size_t i=0; i<m_words; i++) 3727 { 3728 be_vector.push_back(r_write_be[i]); 3729 data_vector.push_back(r_write_data[i]); 3730 } 3731 m_trt.set(r_write_trt_index.read(), 3732 true, // read request to XRAM 3733 m_nline[(addr_t)(r_write_address.read())], 3734 r_write_srcid.read(), 3735 r_write_trdid.read(), 3736 r_write_pktid.read(), 3737 false, // not a processor read 3738 0, // not a single word 3739 0, // word index 3740 be_vector, 3741 data_vector); 3742 r_write_fsm = WRITE_MISS_XRAM_REQ; 3861 { 3862 std::cout << " <MEMC " << name() << " WRITE_MISS_TRT_SET> Set a new entry in TRT" << std::endl; 3863 } 3864 #endif 3865 } 3866 break; 3867 } 3868 3869 ///////////////////////// 3870 case WRITE_MISS_TRT_DATA: // update an entry in TRT (used as a Write Buffer) 3871 { 3872 if (r_alloc_trt_fsm.read() == ALLOC_TRT_WRITE) 3873 { 3874 std::vector<be_t> be_vector; 3875 std::vector<data_t> data_vector; 3876 be_vector.clear(); 3877 data_vector.clear(); 3878 for (size_t i = 0; i < m_words; i++) 3879 { 3880 be_vector.push_back(r_write_be[i]); 3881 data_vector.push_back(r_write_data[i]); 3882 } 3883 m_trt.write_data_mask(r_write_trt_index.read(), 3884 be_vector, 3885 data_vector); 3886 r_write_fsm = WRITE_RSP; 3743 3887 3744 3888 #if DEBUG_MEMC_WRITE 3745 if (m_debug) 3746 std::cout << " <MEMC " << name() << " WRITE_MISS_TRT_SET> Set a new entry in TRT" << std::endl; 3747 #endif 3748 } 3749 break; 3750 } 3751 3752 ///////////////////////// 3753 case WRITE_MISS_TRT_DATA: // update an entry in TRT (used as a Write Buffer) 3754 { 3755 if (r_alloc_trt_fsm.read() == ALLOC_TRT_WRITE) 3756 { 3757 std::vector<be_t> be_vector; 3758 std::vector<data_t> data_vector; 3759 be_vector.clear(); 3760 data_vector.clear(); 3761 for(size_t i=0; i<m_words; i++) 3762 { 3763 be_vector.push_back(r_write_be[i]); 3764 data_vector.push_back(r_write_data[i]); 3765 } 3766 m_trt.write_data_mask( r_write_trt_index.read(), 3767 be_vector, 3768 data_vector ); 3769 r_write_fsm = WRITE_RSP; 3889 if (m_debug) 3890 { 3891 std::cout << " <MEMC " << name() << " WRITE_MISS_TRT_DATA> Modify an existing entry in TRT" << std::endl; 3892 } 3893 #endif 3894 } 3895 break; 3896 } 3897 ///////////////////////// 3898 case WRITE_MISS_XRAM_REQ: // send a GET request to IXR_CMD FSM 3899 { 3900 if (not r_write_to_ixr_cmd_req.read()) 3901 { 3902 r_write_to_ixr_cmd_req = true; 3903 r_write_to_ixr_cmd_index = r_write_trt_index.read(); 3904 r_write_fsm = WRITE_RSP; 3770 3905 3771 3906 #if DEBUG_MEMC_WRITE 3772 if (m_debug) 3773 std::cout << " <MEMC " << name() << " WRITE_MISS_TRT_DATA> Modify an existing entry in TRT" << std::endl; 3774 #endif 3775 } 3776 break; 3777 } 3778 ///////////////////////// 3779 case WRITE_MISS_XRAM_REQ: // send a GET request to IXR_CMD FSM 3780 { 3781 if (not r_write_to_ixr_cmd_req.read()) 3782 { 3783 r_write_to_ixr_cmd_req = true; 3784 r_write_to_ixr_cmd_index = r_write_trt_index.read(); 3785 r_write_fsm = WRITE_RSP; 3786 3787 #if DEBUG_MEMC_WRITE 3788 if (m_debug) 3789 std::cout << " <MEMC " << name() 3790 << " WRITE_MISS_XRAM_REQ> Post a GET request to the" 3791 << " IXR_CMD FSM" << std::endl; 3792 #endif 3793 } 3794 break; 3795 } 3796 /////////////////////// 3907 if (m_debug) 3908 { 3909 std::cout << " <MEMC " << name() 3910 << " WRITE_MISS_XRAM_REQ> Post a GET request to the" 3911 << " IXR_CMD FSM" << std::endl; 3912 } 3913 #endif 3914 } 3915 break; 3916 } 3917 /////////////////////// 3797 3918 case WRITE_BC_DIR_READ: // enter this state if a broadcast-inval is required 3798 3919 // the cache line must be erased in mem-cache, and written 3799 3920 // into XRAM. 3800 { 3801 assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_WRITE) and 3802 "MEMC ERROR in WRITE_BC_DIR_READ state: Bad DIR allocation"); 3803 3804 // write enable signal for data buffer. 3805 r_write_bc_data_we = true; 3806 3807 r_write_fsm = WRITE_BC_TRT_LOCK; 3808 3921 { 3922 assert((r_alloc_dir_fsm.read() == ALLOC_DIR_WRITE) and 3923 "MEMC ERROR in WRITE_BC_DIR_READ state: Bad DIR allocation"); 3924 3925 // write enable signal for data buffer. 3926 r_write_bc_data_we = true; 3927 3928 r_write_fsm = WRITE_BC_TRT_LOCK; 3929 3930 #if DEBUG_MEMC_WRITE 3931 if (m_debug) 3932 { 3933 std::cout << " <MEMC " << name() << " WRITE_BC_DIR_READ>" 3934 << " Read the cache to complete local buffer" << std::endl; 3935 } 3936 #endif 3937 break; 3938 } 3939 /////////////////////// 3940 case WRITE_BC_TRT_LOCK: // get TRT lock to check TRT not full 3941 { 3942 assert((r_alloc_dir_fsm.read() == ALLOC_DIR_WRITE) and 3943 "MEMC ERROR in WRITE_BC_TRT_LOCK state: Bad DIR allocation"); 3944 3945 // We read the cache and complete the buffer. As the DATA cache uses a 3946 // synchronous RAM, the read DATA request has been performed in the 3947 // WRITE_BC_DIR_READ state but the data is available in this state. 3948 if (r_write_bc_data_we.read()) 3949 { 3950 size_t set = m_y[(addr_t) (r_write_address.read())]; 3951 size_t way = r_write_way.read(); 3952 for (size_t word = 0; word < m_words ; word++) 3953 { 3954 data_t mask = 0; 3955 if (r_write_be[word].read() & 0x1) mask = mask | 0x000000FF; 3956 if (r_write_be[word].read() & 0x2) mask = mask | 0x0000FF00; 3957 if (r_write_be[word].read() & 0x4) mask = mask | 0x00FF0000; 3958 if (r_write_be[word].read() & 0x8) mask = mask | 0xFF000000; 3959 3960 // complete only if mask is not null (for energy consumption) 3961 r_write_data[word] = 3962 (r_write_data[word].read() & mask) | 3963 (m_cache_data.read(way, set, word) & ~mask); 3964 } 3809 3965 #if DEBUG_MEMC_WRITE 3810 3966 if (m_debug) 3811 std::cout << " <MEMC " << name() << " WRITE_BC_DIR_READ>" 3812 << " Read the cache to complete local buffer" << std::endl; 3813 #endif 3967 { 3968 std::cout << " <MEMC " << name() 3969 << " WRITE_BC_TRT_LOCK> Complete data buffer" << std::endl; 3970 } 3971 #endif 3972 } 3973 3974 if (r_alloc_trt_fsm.read() != ALLOC_TRT_WRITE) 3975 { 3976 // if we loop in this state, the data does not need to be 3977 // rewritten (for energy consuption) 3978 r_write_bc_data_we = false; 3814 3979 break; 3815 3980 } 3816 /////////////////////// 3817 case WRITE_BC_TRT_LOCK: // get TRT lock to check TRT not full 3818 { 3819 assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_WRITE) and 3820 "MEMC ERROR in WRITE_BC_TRT_LOCK state: Bad DIR allocation"); 3821 3822 // We read the cache and complete the buffer. As the DATA cache uses a 3823 // synchronous RAM, the read DATA request has been performed in the 3824 // WRITE_BC_DIR_READ state but the data is available in this state. 3825 if (r_write_bc_data_we.read()) 3826 { 3827 size_t set = m_y[(addr_t)(r_write_address.read())]; 3828 size_t way = r_write_way.read(); 3829 for(size_t word=0 ; word<m_words ; word++) 3830 { 3831 data_t mask = 0; 3832 if (r_write_be[word].read() & 0x1) mask = mask | 0x000000FF; 3833 if (r_write_be[word].read() & 0x2) mask = mask | 0x0000FF00; 3834 if (r_write_be[word].read() & 0x4) mask = mask | 0x00FF0000; 3835 if (r_write_be[word].read() & 0x8) mask = mask | 0xFF000000; 3836 3837 // complete only if mask is not null (for energy consumption) 3838 r_write_data[word] = 3839 (r_write_data[word].read() & mask) | 3840 (m_cache_data.read(way, set, word) & ~mask); 3841 } 3981 3982 size_t wok_index = 0; 3983 bool wok = not m_trt.full(wok_index); 3984 if (wok) 3985 { 3986 r_write_trt_index = wok_index; 3987 r_write_fsm = WRITE_BC_IVT_LOCK; 3988 } 3989 else // wait an empty slot in TRT 3990 { 3991 r_write_fsm = WRITE_WAIT; 3992 } 3993 3842 3994 #if DEBUG_MEMC_WRITE 3843 if (m_debug) 3844 std::cout 3845 << " <MEMC " << name() 3846 << " WRITE_BC_TRT_LOCK> Complete data buffer" << std::endl; 3847 #endif 3848 } 3849 3850 if (r_alloc_trt_fsm.read() != ALLOC_TRT_WRITE) 3851 { 3852 // if we loop in this state, the data does not need to be 3853 // rewritten (for energy consuption) 3854 r_write_bc_data_we = false; 3855 break; 3856 } 3857 3858 size_t wok_index = 0; 3859 bool wok = not m_trt.full(wok_index); 3860 if (wok ) 3861 { 3862 r_write_trt_index = wok_index; 3863 r_write_fsm = WRITE_BC_IVT_LOCK; 3864 } 3865 else // wait an empty slot in TRT 3866 { 3867 r_write_fsm = WRITE_WAIT; 3868 } 3995 if (m_debug) 3996 { 3997 std::cout << " <MEMC " << name() 3998 << " WRITE_BC_TRT_LOCK> Check TRT : wok = " << wok 3999 << " / index = " << wok_index << std::endl; 4000 } 4001 #endif 4002 break; 4003 } 4004 ////////////////////// 4005 case WRITE_BC_IVT_LOCK: // get IVT lock and register BC transaction in IVT 4006 { 4007 assert((r_alloc_dir_fsm.read() == ALLOC_DIR_WRITE) and 4008 "MEMC ERROR in WRITE_BC_IVT_LOCK state: Bad DIR allocation"); 4009 4010 assert((r_alloc_trt_fsm.read() == ALLOC_TRT_WRITE) and 4011 "MEMC ERROR in WRITE_BC_IVT_LOCK state: Bad TRT allocation"); 4012 4013 if (r_alloc_ivt_fsm.read() == ALLOC_IVT_WRITE) 4014 { 4015 bool wok = false; 4016 size_t index = 0; 4017 size_t srcid = r_write_srcid.read(); 4018 size_t trdid = r_write_trdid.read(); 4019 size_t pktid = r_write_pktid.read(); 4020 addr_t nline = m_nline[(addr_t) (r_write_address.read())]; 4021 size_t nb_copies = r_write_count.read(); 4022 4023 wok = m_ivt.set(false, // it's an inval transaction 4024 true, // it's a broadcast 4025 true, // response required 4026 false, // no acknowledge required 4027 srcid, 4028 trdid, 4029 pktid, 4030 nline, 4031 nb_copies, 4032 index); 4033 #if DEBUG_MEMC_WRITE 4034 if (m_debug and wok) 4035 { 4036 std::cout << " <MEMC " << name() << " WRITE_BC_IVT_LOCK> Register broadcast inval in IVT" 4037 << " / nb_copies = " << r_write_count.read() << std::endl; 4038 } 4039 #endif 4040 r_write_upt_index = index; 4041 4042 if (wok) r_write_fsm = WRITE_BC_DIR_INVAL; 4043 else r_write_fsm = WRITE_WAIT; 4044 } 4045 break; 4046 } 4047 //////////////////////// 4048 case WRITE_BC_DIR_INVAL: // Register a put transaction in TRT 4049 // and invalidate the line in directory 4050 { 4051 assert((r_alloc_dir_fsm.read() == ALLOC_DIR_WRITE) and 4052 "MEMC ERROR in WRITE_BC_DIR_INVAL state: Bad DIR allocation"); 4053 4054 assert((r_alloc_trt_fsm.read() == ALLOC_TRT_WRITE) and 4055 "MEMC ERROR in WRITE_BC_DIR_INVAL state: Bad TRT allocation"); 4056 4057 assert((r_alloc_ivt_fsm.read() == ALLOC_IVT_WRITE) and 4058 "MEMC ERROR in WRITE_BC_DIR_INVAL state: Bad IVT allocation"); 4059 4060 // register PUT request in TRT 4061 std::vector<data_t> data_vector; 4062 data_vector.clear(); 4063 for (size_t i = 0; i < m_words; i++) 4064 { 4065 data_vector.push_back(r_write_data[i].read()); 4066 } 4067 m_trt.set(r_write_trt_index.read(), 4068 false, // PUT request 4069 m_nline[(addr_t) (r_write_address.read())], 4070 0, // unused 4071 0, // unused 4072 0, // unused 4073 false, // not a processor read 4074 0, // unused 4075 0, // unused 4076 std::vector<be_t> (m_words, 0), 4077 data_vector); 4078 4079 // invalidate directory entry 4080 DirectoryEntry entry; 4081 entry.valid = false; 4082 entry.dirty = false; 4083 entry.tag = 0; 4084 entry.is_cnt = false; 4085 entry.lock = false; 4086 entry.owner.srcid = 0; 4087 entry.owner.inst = false; 4088 entry.ptr = 0; 4089 entry.count = 0; 4090 size_t set = m_y[(addr_t) (r_write_address.read())]; 4091 size_t way = r_write_way.read(); 4092 4093 m_cache_directory.write(set, way, entry); 4094 4095 if ((r_write_pktid.read() & 0x7) == TYPE_SC) 4096 { 4097 m_llsc_table.sc(r_write_address.read(), r_write_sc_key.read()); 4098 } 4099 4100 #if DEBUG_MEMC_WRITE 4101 if (m_debug) 4102 { 4103 std::cout << " <MEMC " << name() << " WRITE_BC_DIR_INVAL> Inval DIR and register in TRT:" 4104 << " address = " << std::hex << r_write_address.read() << std::endl; 4105 } 4106 #endif 4107 r_write_fsm = WRITE_BC_CC_SEND; 4108 break; 4109 } 4110 4111 ////////////////////// 4112 case WRITE_BC_CC_SEND: // Post a coherence broadcast request to CC_SEND FSM 4113 { 4114 if (!r_write_to_cc_send_multi_req.read() and !r_write_to_cc_send_brdcast_req.read()) 4115 { 4116 r_write_to_cc_send_multi_req = false; 4117 r_write_to_cc_send_brdcast_req = true; 4118 r_write_to_cc_send_trdid = r_write_upt_index.read(); 4119 r_write_to_cc_send_nline = m_nline[(addr_t) (r_write_address.read())]; 4120 r_write_to_cc_send_index = 0; 4121 r_write_to_cc_send_count = 0; 4122 4123 for (size_t i = 0; i < m_words; i++) // Ã quoi sert ce for? (AG) 4124 { 4125 r_write_to_cc_send_be[i] = 0; 4126 r_write_to_cc_send_data[i] = 0; 4127 } 4128 r_write_fsm = WRITE_BC_XRAM_REQ; 3869 4129 3870 4130 #if DEBUG_MEMC_WRITE 3871 4131 if (m_debug) 3872 std::cout << " <MEMC " << name() 3873 << " WRITE_BC_TRT_LOCK> Check TRT : wok = " << wok 3874 << " / index = " << wok_index << std::endl; 3875 #endif 3876 break; 3877 } 3878 ////////////////////// 3879 case WRITE_BC_IVT_LOCK: // get IVT lock and register BC transaction in IVT 3880 { 3881 assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_WRITE) and 3882 "MEMC ERROR in WRITE_BC_IVT_LOCK state: Bad DIR allocation"); 3883 3884 assert( (r_alloc_trt_fsm.read() == ALLOC_TRT_WRITE) and 3885 "MEMC ERROR in WRITE_BC_IVT_LOCK state: Bad TRT allocation"); 3886 3887 if (r_alloc_ivt_fsm.read() == ALLOC_IVT_WRITE) 3888 { 3889 bool wok = false; 3890 size_t index = 0; 3891 size_t srcid = r_write_srcid.read(); 3892 size_t trdid = r_write_trdid.read(); 3893 size_t pktid = r_write_pktid.read(); 3894 addr_t nline = m_nline[(addr_t)(r_write_address.read())]; 3895 size_t nb_copies = r_write_count.read(); 3896 3897 wok = m_ivt.set(false, // it's an inval transaction 3898 true, // it's a broadcast 3899 true, // response required 3900 false, // no acknowledge required 3901 srcid, 3902 trdid, 3903 pktid, 3904 nline, 3905 nb_copies, 3906 index); 3907 #if DEBUG_MEMC_WRITE 3908 if (m_debug and wok ) 3909 std::cout << " <MEMC " << name() << " WRITE_BC_IVT_LOCK> Register broadcast inval in IVT" 3910 << " / nb_copies = " << r_write_count.read() << std::endl; 3911 #endif 3912 r_write_upt_index = index; 3913 3914 if (wok ) r_write_fsm = WRITE_BC_DIR_INVAL; 3915 else r_write_fsm = WRITE_WAIT; 3916 } 3917 break; 3918 } 3919 //////////////////////// 3920 case WRITE_BC_DIR_INVAL: // Register a put transaction in TRT 3921 // and invalidate the line in directory 3922 { 3923 assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_WRITE) and 3924 "MEMC ERROR in WRITE_BC_DIR_INVAL state: Bad DIR allocation"); 3925 3926 assert( (r_alloc_trt_fsm.read() == ALLOC_TRT_WRITE) and 3927 "MEMC ERROR in WRITE_BC_DIR_INVAL state: Bad TRT allocation"); 3928 3929 assert( (r_alloc_ivt_fsm.read() == ALLOC_IVT_WRITE) and 3930 "MEMC ERROR in WRITE_BC_DIR_INVAL state: Bad IVT allocation"); 3931 3932 // register PUT request in TRT 3933 std::vector<data_t> data_vector; 3934 data_vector.clear(); 3935 for(size_t i=0; i<m_words; i++) data_vector.push_back(r_write_data[i].read()); 3936 m_trt.set( r_write_trt_index.read(), 3937 false, // PUT request 3938 m_nline[(addr_t)(r_write_address.read())], 3939 0, // unused 3940 0, // unused 3941 0, // unused 3942 false, // not a processor read 3943 0, // unused 3944 0, // unused 3945 std::vector<be_t> (m_words,0), 3946 data_vector ); 3947 3948 // invalidate directory entry 3949 DirectoryEntry entry; 3950 entry.valid = false; 3951 entry.dirty = false; 3952 entry.tag = 0; 3953 entry.is_cnt = false; 3954 entry.lock = false; 3955 entry.owner.srcid = 0; 3956 entry.owner.inst = false; 3957 entry.ptr = 0; 3958 entry.count = 0; 3959 size_t set = m_y[(addr_t)(r_write_address.read())]; 3960 size_t way = r_write_way.read(); 3961 3962 m_cache_directory.write(set, way, entry); 3963 3964 if ((r_write_pktid.read() & 0x7) == TYPE_SC) 3965 { 3966 m_llsc_table.sc(r_write_address.read(), 3967 r_write_sc_key.read()); 3968 } 4132 { 4133 std::cout << " <MEMC " << name() 4134 << " WRITE_BC_CC_SEND> Post a broadcast request to CC_SEND FSM" << std::endl; 4135 } 4136 #endif 4137 } 4138 break; 4139 } 4140 4141 /////////////////////// 4142 case WRITE_BC_XRAM_REQ: // Post a PUT request to IXR_CMD FSM 4143 { 4144 if (not r_write_to_ixr_cmd_req.read()) 4145 { 4146 r_write_to_ixr_cmd_req = true; 4147 r_write_to_ixr_cmd_index = r_write_trt_index.read(); 4148 r_write_fsm = WRITE_IDLE; 3969 4149 3970 4150 #if DEBUG_MEMC_WRITE 3971 4151 if (m_debug) 3972 std::cout << " <MEMC " << name() << " WRITE_BC_DIR_INVAL> Inval DIR and register in TRT:" 3973 << " address = " << std::hex << r_write_address.read() << std::endl; 3974 #endif 3975 r_write_fsm = WRITE_BC_CC_SEND; 3976 break; 3977 } 3978 3979 ////////////////////// 3980 case WRITE_BC_CC_SEND: // Post a coherence broadcast request to CC_SEND FSM 3981 { 3982 if (!r_write_to_cc_send_multi_req.read() and !r_write_to_cc_send_brdcast_req.read()) 3983 { 3984 r_write_to_cc_send_multi_req = false; 3985 r_write_to_cc_send_brdcast_req = true; 3986 r_write_to_cc_send_trdid = r_write_upt_index.read(); 3987 r_write_to_cc_send_nline = m_nline[(addr_t)(r_write_address.read())]; 3988 r_write_to_cc_send_index = 0; 3989 r_write_to_cc_send_count = 0; 3990 3991 for(size_t i=0; i<m_words ; i++) // Ã quoi sert ce for? (AG) 3992 { 3993 r_write_to_cc_send_be[i]=0; 3994 r_write_to_cc_send_data[i] = 0; 3995 } 3996 r_write_fsm = WRITE_BC_XRAM_REQ; 3997 3998 #if DEBUG_MEMC_WRITE 3999 if (m_debug) 4000 std::cout << " <MEMC " << name() 4001 << " WRITE_BC_CC_SEND> Post a broadcast request to CC_SEND FSM" << std::endl; 4002 #endif 4003 } 4004 break; 4005 } 4006 4007 /////////////////////// 4008 case WRITE_BC_XRAM_REQ: // Post a PUT request to IXR_CMD FSM 4009 { 4010 if (not r_write_to_ixr_cmd_req.read()) 4011 { 4012 r_write_to_ixr_cmd_req = true; 4013 r_write_to_ixr_cmd_index = r_write_trt_index.read(); 4014 r_write_fsm = WRITE_IDLE; 4015 4016 #if DEBUG_MEMC_WRITE 4017 if (m_debug) 4018 std::cout << " <MEMC " << name() 4019 << " WRITE_BC_XRAM_REQ> Post a put request to IXR_CMD FSM" << std::endl; 4020 #endif 4021 } 4022 break; 4023 } 4152 { 4153 std::cout << " <MEMC " << name() 4154 << " WRITE_BC_XRAM_REQ> Post a put request to IXR_CMD FSM" << std::endl; 4155 } 4156 #endif 4157 } 4158 break; 4159 } 4024 4160 } // end switch r_write_fsm 4025 4161 … … 4032 4168 // 4033 4169 // - It sends a single flit VCI read to the XRAM in case of 4034 // GET request posted by the READ, WRITE or CAS FSMs. 4170 // GET request posted by the READ, WRITE or CAS FSMs. 4035 4171 // - It sends a multi-flit VCI write in case of PUT request posted by 4036 4172 // the XRAM_RSP, WRITE, CAS, or CONFIG FSMs. … … 4045 4181 //////////////////////////////////////////////////////////////////////// 4046 4182 4047 //std::cout << std::endl << "ixr_cmd_fsm" << std::endl; 4048 4049 switch(r_ixr_cmd_fsm.read()) 4183 switch (r_ixr_cmd_fsm.read()) 4050 4184 { 4051 4185 /////////////////////// 4052 4186 case IXR_CMD_READ_IDLE: 4053 {4054 if(r_write_to_ixr_cmd_req.read()) r_ixr_cmd_fsm = IXR_CMD_WRITE_TRT;4055 else if (r_cas_to_ixr_cmd_req.read()) r_ixr_cmd_fsm = IXR_CMD_CAS_TRT;4056 else if (r_xram_rsp_to_ixr_cmd_req.read()) r_ixr_cmd_fsm = IXR_CMD_XRAM_TRT;4057 else if (r_config_to_ixr_cmd_req.read()) r_ixr_cmd_fsm = IXR_CMD_CONFIG_TRT;4058 else if (r_read_to_ixr_cmd_req.read()) r_ixr_cmd_fsm = IXR_CMD_READ_TRT;4059 break;4060 }4061 ////////////////////////4187 { 4188 if (r_write_to_ixr_cmd_req.read()) r_ixr_cmd_fsm = IXR_CMD_WRITE_TRT; 4189 else if (r_cas_to_ixr_cmd_req.read()) r_ixr_cmd_fsm = IXR_CMD_CAS_TRT; 4190 else if (r_xram_rsp_to_ixr_cmd_req.read()) r_ixr_cmd_fsm = IXR_CMD_XRAM_TRT; 4191 else if (r_config_to_ixr_cmd_req.read()) r_ixr_cmd_fsm = IXR_CMD_CONFIG_TRT; 4192 else if (r_read_to_ixr_cmd_req.read()) r_ixr_cmd_fsm = IXR_CMD_READ_TRT; 4193 break; 4194 } 4195 //////////////////////// 4062 4196 case IXR_CMD_WRITE_IDLE: 4063 {4064 if(r_cas_to_ixr_cmd_req.read()) r_ixr_cmd_fsm = IXR_CMD_CAS_TRT;4065 else if (r_xram_rsp_to_ixr_cmd_req.read()) r_ixr_cmd_fsm = IXR_CMD_XRAM_TRT;4066 else if (r_config_to_ixr_cmd_req.read()) r_ixr_cmd_fsm = IXR_CMD_CONFIG_TRT;4067 else if (r_read_to_ixr_cmd_req.read()) r_ixr_cmd_fsm = IXR_CMD_READ_TRT;4068 else if (r_write_to_ixr_cmd_req.read()) r_ixr_cmd_fsm = IXR_CMD_WRITE_TRT;4069 break;4070 }4071 //////////////////////4197 { 4198 if (r_cas_to_ixr_cmd_req.read()) r_ixr_cmd_fsm = IXR_CMD_CAS_TRT; 4199 else if (r_xram_rsp_to_ixr_cmd_req.read()) r_ixr_cmd_fsm = IXR_CMD_XRAM_TRT; 4200 else if (r_config_to_ixr_cmd_req.read()) r_ixr_cmd_fsm = IXR_CMD_CONFIG_TRT; 4201 else if (r_read_to_ixr_cmd_req.read()) r_ixr_cmd_fsm = IXR_CMD_READ_TRT; 4202 else if (r_write_to_ixr_cmd_req.read()) r_ixr_cmd_fsm = IXR_CMD_WRITE_TRT; 4203 break; 4204 } 4205 ////////////////////// 4072 4206 case IXR_CMD_CAS_IDLE: 4073 {4074 if(r_xram_rsp_to_ixr_cmd_req.read()) r_ixr_cmd_fsm = IXR_CMD_XRAM_TRT;4075 else if (r_config_to_ixr_cmd_req.read()) r_ixr_cmd_fsm = IXR_CMD_CONFIG_TRT;4076 else if (r_read_to_ixr_cmd_req.read()) r_ixr_cmd_fsm = IXR_CMD_READ_TRT;4077 else if (r_write_to_ixr_cmd_req.read()) r_ixr_cmd_fsm = IXR_CMD_WRITE_TRT;4078 else if (r_cas_to_ixr_cmd_req.read()) r_ixr_cmd_fsm = IXR_CMD_CAS_TRT;4079 break;4080 }4081 ///////////////////////4207 { 4208 if (r_xram_rsp_to_ixr_cmd_req.read()) r_ixr_cmd_fsm = IXR_CMD_XRAM_TRT; 4209 else if (r_config_to_ixr_cmd_req.read()) r_ixr_cmd_fsm = IXR_CMD_CONFIG_TRT; 4210 else if (r_read_to_ixr_cmd_req.read()) r_ixr_cmd_fsm = IXR_CMD_READ_TRT; 4211 else if (r_write_to_ixr_cmd_req.read()) r_ixr_cmd_fsm = IXR_CMD_WRITE_TRT; 4212 else if (r_cas_to_ixr_cmd_req.read()) r_ixr_cmd_fsm = IXR_CMD_CAS_TRT; 4213 break; 4214 } 4215 /////////////////////// 4082 4216 case IXR_CMD_XRAM_IDLE: 4083 {4084 if(r_config_to_ixr_cmd_req.read()) r_ixr_cmd_fsm = IXR_CMD_CONFIG_TRT;4085 else if (r_read_to_ixr_cmd_req.read()) r_ixr_cmd_fsm = IXR_CMD_READ_TRT;4086 else if (r_write_to_ixr_cmd_req.read()) r_ixr_cmd_fsm = IXR_CMD_WRITE_TRT;4087 else if (r_cas_to_ixr_cmd_req.read()) r_ixr_cmd_fsm = IXR_CMD_CAS_TRT;4088 else if (r_xram_rsp_to_ixr_cmd_req.read()) r_ixr_cmd_fsm = IXR_CMD_XRAM_TRT;4089 break;4090 }4091 /////////////////////////4217 { 4218 if (r_config_to_ixr_cmd_req.read()) r_ixr_cmd_fsm = IXR_CMD_CONFIG_TRT; 4219 else if (r_read_to_ixr_cmd_req.read()) r_ixr_cmd_fsm = IXR_CMD_READ_TRT; 4220 else if (r_write_to_ixr_cmd_req.read()) r_ixr_cmd_fsm = IXR_CMD_WRITE_TRT; 4221 else if (r_cas_to_ixr_cmd_req.read()) r_ixr_cmd_fsm = IXR_CMD_CAS_TRT; 4222 else if (r_xram_rsp_to_ixr_cmd_req.read()) r_ixr_cmd_fsm = IXR_CMD_XRAM_TRT; 4223 break; 4224 } 4225 ///////////////////////// 4092 4226 case IXR_CMD_CONFIG_IDLE: 4093 {4094 if (r_read_to_ixr_cmd_req.read())r_ixr_cmd_fsm = IXR_CMD_READ_TRT;4095 else if (r_write_to_ixr_cmd_req.read())r_ixr_cmd_fsm = IXR_CMD_WRITE_TRT;4096 else if (r_cas_to_ixr_cmd_req.read())r_ixr_cmd_fsm = IXR_CMD_CAS_TRT;4097 else if (r_xram_rsp_to_ixr_cmd_req.read())r_ixr_cmd_fsm = IXR_CMD_XRAM_TRT;4098 else if (r_config_to_ixr_cmd_req.read())r_ixr_cmd_fsm = IXR_CMD_CONFIG_TRT;4099 break;4100 }4101 4102 //////////////////////4227 { 4228 if (r_read_to_ixr_cmd_req.read()) r_ixr_cmd_fsm = IXR_CMD_READ_TRT; 4229 else if (r_write_to_ixr_cmd_req.read()) r_ixr_cmd_fsm = IXR_CMD_WRITE_TRT; 4230 else if (r_cas_to_ixr_cmd_req.read()) r_ixr_cmd_fsm = IXR_CMD_CAS_TRT; 4231 else if (r_xram_rsp_to_ixr_cmd_req.read()) r_ixr_cmd_fsm = IXR_CMD_XRAM_TRT; 4232 else if (r_config_to_ixr_cmd_req.read()) r_ixr_cmd_fsm = IXR_CMD_CONFIG_TRT; 4233 break; 4234 } 4235 4236 ////////////////////// 4103 4237 case IXR_CMD_READ_TRT: // access TRT for a GET 4104 {4105 if (r_alloc_trt_fsm.read() == ALLOC_TRT_IXR_CMD)4106 {4107 TransactionTabEntry entry = m_trt.read(r_read_to_ixr_cmd_index.read());4108 r_ixr_cmd_address = entry.nline * (m_words<<2);4109 r_ixr_cmd_trdid = r_read_to_ixr_cmd_index.read();4110 r_ixr_cmd_get = true;4111 r_ixr_cmd_word = 0;4112 r_ixr_cmd_fsm = IXR_CMD_READ_SEND;4238 { 4239 if (r_alloc_trt_fsm.read() == ALLOC_TRT_IXR_CMD) 4240 { 4241 TransactionTabEntry entry = m_trt.read(r_read_to_ixr_cmd_index.read()); 4242 r_ixr_cmd_address = entry.nline * (m_words << 2); 4243 r_ixr_cmd_trdid = r_read_to_ixr_cmd_index.read(); 4244 r_ixr_cmd_get = true; 4245 r_ixr_cmd_word = 0; 4246 r_ixr_cmd_fsm = IXR_CMD_READ_SEND; 4113 4247 4114 4248 #if DEBUG_MEMC_IXR_CMD 4115 if (m_debug) 4116 std::cout << " <MEMC " << name() << " IXR_CMD_READ_TRT> TRT access" 4117 << " index = " << std::dec << r_read_to_ixr_cmd_index.read() 4118 << " / address = " << std::hex << (entry.nline*(m_words<<2)) << std::endl; 4119 #endif 4120 } 4121 break; 4122 } 4123 /////////////////////// 4124 case IXR_CMD_WRITE_TRT: // access TRT for a PUT or a GET 4125 { 4126 if (r_alloc_trt_fsm.read() == ALLOC_TRT_IXR_CMD ) 4127 { 4128 TransactionTabEntry entry = m_trt.read( r_write_to_ixr_cmd_index.read()); 4129 r_ixr_cmd_address = entry.nline * (m_words<<2); 4130 r_ixr_cmd_trdid = r_write_to_ixr_cmd_index.read(); 4131 r_ixr_cmd_get = entry.xram_read; 4132 r_ixr_cmd_word = 0; 4133 r_ixr_cmd_fsm = IXR_CMD_WRITE_SEND; 4134 4135 // Read data from TRT if PUT transaction 4136 if (not entry.xram_read) 4249 if (m_debug) 4250 { 4251 std::cout << " <MEMC " << name() << " IXR_CMD_READ_TRT> TRT access" 4252 << " index = " << std::dec << r_read_to_ixr_cmd_index.read() 4253 << " / address = " << std::hex << (entry.nline * (m_words << 2)) << std::endl; 4254 } 4255 #endif 4256 } 4257 break; 4258 } 4259 /////////////////////// 4260 case IXR_CMD_WRITE_TRT: // access TRT for a PUT or a GET 4261 { 4262 if (r_alloc_trt_fsm.read() == ALLOC_TRT_IXR_CMD) 4263 { 4264 TransactionTabEntry entry = m_trt.read(r_write_to_ixr_cmd_index.read()); 4265 r_ixr_cmd_address = entry.nline * (m_words << 2); 4266 r_ixr_cmd_trdid = r_write_to_ixr_cmd_index.read(); 4267 r_ixr_cmd_get = entry.xram_read; 4268 r_ixr_cmd_word = 0; 4269 r_ixr_cmd_fsm = IXR_CMD_WRITE_SEND; 4270 4271 // Read data from TRT if PUT transaction 4272 if (not entry.xram_read) 4273 { 4274 for (size_t i = 0; i < m_words; i++) 4137 4275 { 4138 for( size_t i=0 ; i<m_words ; i++ )r_ixr_cmd_wdata[i] = entry.wdata[i];4276 r_ixr_cmd_wdata[i] = entry.wdata[i]; 4139 4277 } 4278 } 4140 4279 4141 4280 #if DEBUG_MEMC_IXR_CMD 4142 if (m_debug) 4143 std::cout << " <MEMC " << name() << " IXR_CMD_WRITE_TRT> TRT access" 4144 << " index = " << std::dec << r_write_to_ixr_cmd_index.read() 4145 << " / address = " << std::hex << (entry.nline*(m_words<<2)) << std::endl; 4146 #endif 4147 } 4148 break; 4149 } 4150 ///////////////////// 4151 case IXR_CMD_CAS_TRT: // access TRT for a PUT or a GET 4152 { 4153 if (r_alloc_trt_fsm.read() == ALLOC_TRT_IXR_CMD ) 4154 { 4155 TransactionTabEntry entry = m_trt.read( r_cas_to_ixr_cmd_index.read()); 4156 r_ixr_cmd_address = entry.nline * (m_words<<2); 4157 r_ixr_cmd_trdid = r_cas_to_ixr_cmd_index.read(); 4158 r_ixr_cmd_get = entry.xram_read; 4159 r_ixr_cmd_word = 0; 4160 r_ixr_cmd_fsm = IXR_CMD_CAS_SEND; 4161 4162 // Read data from TRT if PUT transaction 4163 if (not entry.xram_read) 4281 if (m_debug) 4282 { 4283 std::cout << " <MEMC " << name() << " IXR_CMD_WRITE_TRT> TRT access" 4284 << " index = " << std::dec << r_write_to_ixr_cmd_index.read() 4285 << " / address = " << std::hex << (entry.nline * (m_words << 2)) << std::endl; 4286 } 4287 #endif 4288 } 4289 break; 4290 } 4291 ///////////////////// 4292 case IXR_CMD_CAS_TRT: // access TRT for a PUT or a GET 4293 { 4294 if (r_alloc_trt_fsm.read() == ALLOC_TRT_IXR_CMD) 4295 { 4296 TransactionTabEntry entry = m_trt.read(r_cas_to_ixr_cmd_index.read()); 4297 r_ixr_cmd_address = entry.nline * (m_words << 2); 4298 r_ixr_cmd_trdid = r_cas_to_ixr_cmd_index.read(); 4299 r_ixr_cmd_get = entry.xram_read; 4300 r_ixr_cmd_word = 0; 4301 r_ixr_cmd_fsm = IXR_CMD_CAS_SEND; 4302 4303 // Read data from TRT if PUT transaction 4304 if (not entry.xram_read) 4305 { 4306 for (size_t i = 0; i < m_words; i++) 4164 4307 { 4165 for( size_t i=0 ; i<m_words ; i++ )r_ixr_cmd_wdata[i] = entry.wdata[i];4308 r_ixr_cmd_wdata[i] = entry.wdata[i]; 4166 4309 } 4310 } 4167 4311 4168 4312 #if DEBUG_MEMC_IXR_CMD 4169 if (m_debug) 4170 std::cout << " <MEMC " << name() << " IXR_CMD_CAS_TRT> TRT access" 4171 << " index = " << std::dec << r_cas_to_ixr_cmd_index.read() 4172 << " / address = " << std::hex << (entry.nline*(m_words<<2)) << std::endl; 4173 #endif 4174 } 4175 break; 4176 } 4177 ////////////////////// 4178 case IXR_CMD_XRAM_TRT: // access TRT for a PUT 4179 { 4180 if (r_alloc_trt_fsm.read() == ALLOC_TRT_IXR_CMD ) 4181 { 4182 TransactionTabEntry entry = m_trt.read( r_xram_rsp_to_ixr_cmd_index.read()); 4183 r_ixr_cmd_address = entry.nline * (m_words<<2); 4184 r_ixr_cmd_trdid = r_xram_rsp_to_ixr_cmd_index.read(); 4185 r_ixr_cmd_get = false; 4186 r_ixr_cmd_word = 0; 4187 r_ixr_cmd_fsm = IXR_CMD_XRAM_SEND; 4188 for( size_t i=0 ; i<m_words ; i++ ) r_ixr_cmd_wdata[i] = entry.wdata[i]; 4313 if (m_debug) 4314 { 4315 std::cout << " <MEMC " << name() << " IXR_CMD_CAS_TRT> TRT access" 4316 << " index = " << std::dec << r_cas_to_ixr_cmd_index.read() 4317 << " / address = " << std::hex << (entry.nline * (m_words << 2)) << std::endl; 4318 } 4319 #endif 4320 } 4321 break; 4322 } 4323 ////////////////////// 4324 case IXR_CMD_XRAM_TRT: // access TRT for a PUT 4325 { 4326 if (r_alloc_trt_fsm.read() == ALLOC_TRT_IXR_CMD) 4327 { 4328 TransactionTabEntry entry = m_trt.read(r_xram_rsp_to_ixr_cmd_index.read()); 4329 r_ixr_cmd_address = entry.nline * (m_words << 2); 4330 r_ixr_cmd_trdid = r_xram_rsp_to_ixr_cmd_index.read(); 4331 r_ixr_cmd_get = false; 4332 r_ixr_cmd_word = 0; 4333 r_ixr_cmd_fsm = IXR_CMD_XRAM_SEND; 4334 for (size_t i = 0; i < m_words; i++) 4335 { 4336 r_ixr_cmd_wdata[i] = entry.wdata[i]; 4337 } 4189 4338 4190 4339 #if DEBUG_MEMC_IXR_CMD 4191 if (m_debug) 4192 std::cout << " <MEMC " << name() << " IXR_CMD_XRAM_TRT> TRT access" 4193 << " index = " << std::dec << r_xram_rsp_to_ixr_cmd_index.read() 4194 << " / address = " << std::hex << (entry.nline*(m_words<<2)) << std::endl; 4195 #endif 4196 } 4197 break; 4198 } 4199 //////////////////////// 4340 if (m_debug) 4341 { 4342 std::cout << " <MEMC " << name() << " IXR_CMD_XRAM_TRT> TRT access" 4343 << " index = " << std::dec << r_xram_rsp_to_ixr_cmd_index.read() 4344 << " / address = " << std::hex << (entry.nline*(m_words<<2)) << std::endl; 4345 } 4346 #endif 4347 } 4348 break; 4349 } 4350 //////////////////////// 4200 4351 case IXR_CMD_CONFIG_TRT: // access TRT for a PUT 4201 { 4202 if (r_alloc_trt_fsm.read() == ALLOC_TRT_IXR_CMD ) 4203 { 4204 TransactionTabEntry entry = m_trt.read( r_config_to_ixr_cmd_index.read()); 4205 r_ixr_cmd_address = entry.nline * (m_words<<2); 4206 r_ixr_cmd_trdid = r_config_to_ixr_cmd_index.read(); 4207 r_ixr_cmd_get = false; 4208 r_ixr_cmd_word = 0; 4209 r_ixr_cmd_fsm = IXR_CMD_CONFIG_SEND; 4210 for( size_t i=0 ; i<m_words ; i++ ) r_ixr_cmd_wdata[i] = entry.wdata[i]; 4352 { 4353 if (r_alloc_trt_fsm.read() == ALLOC_TRT_IXR_CMD) 4354 { 4355 TransactionTabEntry entry = m_trt.read(r_config_to_ixr_cmd_index.read()); 4356 r_ixr_cmd_address = entry.nline * (m_words << 2); 4357 r_ixr_cmd_trdid = r_config_to_ixr_cmd_index.read(); 4358 r_ixr_cmd_get = false; 4359 r_ixr_cmd_word = 0; 4360 r_ixr_cmd_fsm = IXR_CMD_CONFIG_SEND; 4361 for (size_t i = 0; i < m_words; i++) 4362 { 4363 r_ixr_cmd_wdata[i] = entry.wdata[i]; 4364 } 4211 4365 4212 4366 #if DEBUG_MEMC_IXR_CMD 4213 if (m_debug) 4214 std::cout << " <MEMC " << name() << " IXR_CMD_CONFIG_TRT> TRT access" 4215 << " index = " << std::dec << r_config_to_ixr_cmd_index.read() 4216 << " / address = " << std::hex << (entry.nline*(m_words<<2)) << std::endl; 4217 #endif 4218 } 4219 break; 4220 } 4221 4222 /////////////////////// 4367 if (m_debug) 4368 { 4369 std::cout << " <MEMC " << name() << " IXR_CMD_CONFIG_TRT> TRT access" 4370 << " index = " << std::dec << r_config_to_ixr_cmd_index.read() 4371 << " / address = " << std::hex << (entry.nline*(m_words<<2)) << std::endl; 4372 } 4373 #endif 4374 } 4375 break; 4376 } 4377 4378 /////////////////////// 4223 4379 case IXR_CMD_READ_SEND: // send a get from READ FSM 4224 {4225 if (p_vci_ixr.cmdack)4226 {4227 r_ixr_cmd_fsm = IXR_CMD_READ_IDLE;4228 r_read_to_ixr_cmd_req = false;4380 { 4381 if (p_vci_ixr.cmdack) 4382 { 4383 r_ixr_cmd_fsm = IXR_CMD_READ_IDLE; 4384 r_read_to_ixr_cmd_req = false; 4229 4385 4230 4386 #if DEBUG_MEMC_IXR_CMD 4231 if (m_debug) 4232 std::cout << " <MEMC " << name() << " IXR_CMD_READ_SEND> GET request:" << std::hex 4233 << " address = " << r_ixr_cmd_address.read() + (r_ixr_cmd_word.read()<<2) << std::endl; 4234 #endif 4235 } 4236 break; 4237 } 4238 //////////////////////// 4387 if (m_debug) 4388 { 4389 std::cout << " <MEMC " << name() << " IXR_CMD_READ_SEND> GET request:" << std::hex 4390 << " address = " << r_ixr_cmd_address.read() + (r_ixr_cmd_word.read()<<2) << std::endl; 4391 } 4392 #endif 4393 } 4394 break; 4395 } 4396 //////////////////////// 4239 4397 case IXR_CMD_WRITE_SEND: // send a put or get from WRITE FSM 4240 { 4241 if (p_vci_ixr.cmdack) 4242 { 4243 if (not r_ixr_cmd_get.read()) // PUT 4244 { 4245 if (r_ixr_cmd_word.read() == (m_words - 2)) 4246 { 4247 r_ixr_cmd_fsm = IXR_CMD_WRITE_IDLE; 4248 r_write_to_ixr_cmd_req = false; 4249 } 4250 else 4251 { 4252 r_ixr_cmd_word = r_ixr_cmd_word.read() + 2; 4253 } 4254 4255 #if DEBUG_MEMC_IXR_CMD 4256 if (m_debug) 4257 std::cout << " <MEMC " << name() << " IXR_CMD_WRITE_SEND> PUT request:" << std::hex 4258 << " address = " << r_ixr_cmd_address.read() + (r_ixr_cmd_word.read()<<2) << std::endl; 4259 #endif 4260 } 4261 else // GET 4398 { 4399 if (p_vci_ixr.cmdack) 4400 { 4401 if (not r_ixr_cmd_get.read()) // PUT 4402 { 4403 if (r_ixr_cmd_word.read() == (m_words - 2)) 4262 4404 { 4263 4405 r_ixr_cmd_fsm = IXR_CMD_WRITE_IDLE; 4264 4406 r_write_to_ixr_cmd_req = false; 4265 4266 #if DEBUG_MEMC_IXR_CMD4267 if (m_debug)4268 std::cout << " <MEMC " << name() << " IXR_CMD_WRITE_SEND> GET request:" << std::hex4269 << " address = " << r_ixr_cmd_address.read() + (r_ixr_cmd_word.read()<<2) << std::endl;4270 #endif4271 }4272 }4273 break;4274 }4275 //////////////////////4276 case IXR_CMD_CAS_SEND: // send a put or get command from CAS FSM4277 {4278 if (p_vci_ixr.cmdack)4279 {4280 if (not r_ixr_cmd_get.read()) // PUT4281 {4282 if (r_ixr_cmd_word.read() == (m_words - 2))4283 {4284 r_ixr_cmd_fsm = IXR_CMD_CAS_IDLE;4285 r_cas_to_ixr_cmd_req = false;4286 }4287 else4288 {4289 r_ixr_cmd_word = r_ixr_cmd_word.read() + 2;4290 }4291 4292 #if DEBUG_MEMC_IXR_CMD4293 if (m_debug)4294 std::cout << " <MEMC " << name() << " IXR_CMD_CAS_SEND> PUT request:" << std::hex4295 << " address = " << r_ixr_cmd_address.read() + (r_ixr_cmd_word.read()<<2) << std::endl;4296 #endif4297 }4298 else // GET4299 {4300 r_ixr_cmd_fsm = IXR_CMD_CAS_IDLE;4301 r_cas_to_ixr_cmd_req = false;4302 4303 #if DEBUG_MEMC_IXR_CMD4304 if (m_debug)4305 std::cout << " <MEMC " << name() << " IXR_CMD_CAS_SEND> GET request:" << std::hex4306 << " address = " << r_ixr_cmd_address.read() + (r_ixr_cmd_word.read()<<2) << std::endl;4307 #endif4308 }4309 }4310 break;4311 }4312 ///////////////////////4313 case IXR_CMD_XRAM_SEND: // send a put from XRAM_RSP FSM4314 {4315 if (p_vci_ixr.cmdack.read())4316 {4317 if (r_ixr_cmd_word.read() == (m_words - 2))4318 {4319 r_ixr_cmd_fsm = IXR_CMD_XRAM_IDLE;4320 r_xram_rsp_to_ixr_cmd_req = false;4321 4407 } 4322 4408 else … … 4327 4413 #if DEBUG_MEMC_IXR_CMD 4328 4414 if (m_debug) 4329 std::cout << " <MEMC " << name() << " IXR_CMD_XRAM_SEND> PUT request:" << std::hex 4415 { 4416 std::cout << " <MEMC " << name() << " IXR_CMD_WRITE_SEND> PUT request:" << std::hex 4330 4417 << " address = " << r_ixr_cmd_address.read() + (r_ixr_cmd_word.read()<<2) << std::endl; 4331 #endif 4332 } 4333 break; 4334 } 4335 ///////////////////////// 4336 case IXR_CMD_CONFIG_SEND: // send a put from CONFIG FSM 4337 { 4338 if (p_vci_ixr.cmdack.read()) 4418 } 4419 #endif 4420 } 4421 else // GET 4422 { 4423 r_ixr_cmd_fsm = IXR_CMD_WRITE_IDLE; 4424 r_write_to_ixr_cmd_req = false; 4425 4426 #if DEBUG_MEMC_IXR_CMD 4427 if (m_debug) 4428 { 4429 std::cout << " <MEMC " << name() << " IXR_CMD_WRITE_SEND> GET request:" << std::hex 4430 << " address = " << r_ixr_cmd_address.read() + (r_ixr_cmd_word.read()<<2) << std::endl; 4431 } 4432 #endif 4433 } 4434 } 4435 break; 4436 } 4437 ////////////////////// 4438 case IXR_CMD_CAS_SEND: // send a put or get command from CAS FSM 4439 { 4440 if (p_vci_ixr.cmdack) 4441 { 4442 if (not r_ixr_cmd_get.read()) // PUT 4339 4443 { 4340 4444 if (r_ixr_cmd_word.read() == (m_words - 2)) 4341 4445 { 4342 r_ixr_cmd_fsm = IXR_CMD_CONFIG_IDLE;4343 r_c onfig_to_ixr_cmd_req = false;4446 r_ixr_cmd_fsm = IXR_CMD_CAS_IDLE; 4447 r_cas_to_ixr_cmd_req = false; 4344 4448 } 4345 4449 else … … 4350 4454 #if DEBUG_MEMC_IXR_CMD 4351 4455 if (m_debug) 4352 std::cout << " <MEMC " << name() << " IXR_CMD_CONFIG_SEND> PUT request:" << std::hex 4353 << " address = " << r_ixr_cmd_address.read() + (r_ixr_cmd_word.read()<<2) << std::endl; 4354 #endif 4355 } 4356 break; 4357 } 4456 { 4457 std::cout << " <MEMC " << name() << " IXR_CMD_CAS_SEND> PUT request:" << std::hex 4458 << " address = " << r_ixr_cmd_address.read() + (r_ixr_cmd_word.read() << 2) << std::endl; 4459 } 4460 #endif 4461 } 4462 else // GET 4463 { 4464 r_ixr_cmd_fsm = IXR_CMD_CAS_IDLE; 4465 r_cas_to_ixr_cmd_req = false; 4466 4467 #if DEBUG_MEMC_IXR_CMD 4468 if (m_debug) 4469 { 4470 std::cout << " <MEMC " << name() << " IXR_CMD_CAS_SEND> GET request:" << std::hex 4471 << " address = " << r_ixr_cmd_address.read() + (r_ixr_cmd_word.read() << 2) << std::endl; 4472 } 4473 #endif 4474 } 4475 } 4476 break; 4477 } 4478 /////////////////////// 4479 case IXR_CMD_XRAM_SEND: // send a put from XRAM_RSP FSM 4480 { 4481 if (p_vci_ixr.cmdack.read()) 4482 { 4483 if (r_ixr_cmd_word.read() == (m_words - 2)) 4484 { 4485 r_ixr_cmd_fsm = IXR_CMD_XRAM_IDLE; 4486 r_xram_rsp_to_ixr_cmd_req = false; 4487 } 4488 else 4489 { 4490 r_ixr_cmd_word = r_ixr_cmd_word.read() + 2; 4491 } 4492 4493 #if DEBUG_MEMC_IXR_CMD 4494 if (m_debug) 4495 { 4496 std::cout << " <MEMC " << name() << " IXR_CMD_XRAM_SEND> PUT request:" << std::hex 4497 << " address = " << r_ixr_cmd_address.read() + (r_ixr_cmd_word.read() << 2) << std::endl; 4498 } 4499 #endif 4500 } 4501 break; 4502 } 4503 ///////////////////////// 4504 case IXR_CMD_CONFIG_SEND: // send a put from CONFIG FSM 4505 { 4506 if (p_vci_ixr.cmdack.read()) 4507 { 4508 if (r_ixr_cmd_word.read() == (m_words - 2)) 4509 { 4510 r_ixr_cmd_fsm = IXR_CMD_CONFIG_IDLE; 4511 r_config_to_ixr_cmd_req = false; 4512 } 4513 else 4514 { 4515 r_ixr_cmd_word = r_ixr_cmd_word.read() + 2; 4516 } 4517 4518 #if DEBUG_MEMC_IXR_CMD 4519 if (m_debug) 4520 { 4521 std::cout << " <MEMC " << name() << " IXR_CMD_CONFIG_SEND> PUT request:" << std::hex 4522 << " address = " << r_ixr_cmd_address.read() + (r_ixr_cmd_word.read()<<2) << std::endl; 4523 } 4524 #endif 4525 } 4526 break; 4527 } 4358 4528 } // end switch r_ixr_cmd_fsm 4359 4529 … … 4368 4538 // The FSM takes the lock protecting the TRT, and the corresponding 4369 4539 // entry is erased. If an acknowledge was required (in case of software SYNC) 4370 // the r_config_rsp_lines counter is decremented. 4540 // the r_config_rsp_lines counter is decremented. 4371 4541 // 4372 4542 // - A response to a GET request is a multi-cell VCI packet. … … 4375 4545 // The FSM takes the lock protecting the TRT to store the line in the TRT 4376 4546 // (taking into account the write requests already stored in the TRT). 4377 // When the line is completely written, the r_ixr_rsp_to_xram_rsp_rok[index] 4547 // When the line is completely written, the r_ixr_rsp_to_xram_rsp_rok[index] 4378 4548 // signal is set to inform the XRAM_RSP FSM. 4379 4549 /////////////////////////////////////////////////////////////////////////////// … … 4385 4555 ////////////////// 4386 4556 case IXR_RSP_IDLE: // test transaction type: PUT/GET 4387 {4388 if (p_vci_ixr.rspval.read())4389 {4390 r_ixr_rsp_cpt = 0;4391 r_ixr_rsp_trt_index = p_vci_ixr.rtrdid.read();4392 4393 if (p_vci_ixr.reop.read() and not4557 { 4558 if (p_vci_ixr.rspval.read()) 4559 { 4560 r_ixr_rsp_cpt = 0; 4561 r_ixr_rsp_trt_index = p_vci_ixr.rtrdid.read(); 4562 4563 if (p_vci_ixr.reop.read() and not 4394 4564 p_vci_ixr.rerror.read()) // PUT 4565 { 4566 r_ixr_rsp_fsm = IXR_RSP_TRT_ERASE; 4567 4568 #if DEBUG_MEMC_IXR_RSP 4569 if (m_debug) 4570 std::cout << " <MEMC " << name() 4571 << " IXR_RSP_IDLE> Response from XRAM to a put transaction" << std::endl; 4572 #endif 4573 } 4574 else // GET 4575 { 4576 r_ixr_rsp_fsm = IXR_RSP_TRT_READ; 4577 4578 #if DEBUG_MEMC_IXR_RSP 4579 if (m_debug) 4395 4580 { 4396 r_ixr_rsp_fsm = IXR_RSP_TRT_ERASE; 4397 4398 #if DEBUG_MEMC_IXR_RSP 4399 if (m_debug) 4400 std::cout << " <MEMC " << name() 4401 << " IXR_RSP_IDLE> Response from XRAM to a put transaction" << std::endl; 4402 #endif 4581 std::cout << " <MEMC " << name() 4582 << " IXR_RSP_IDLE> Response from XRAM to a get transaction" << std::endl; 4403 4583 } 4404 else // GET 4405 { 4406 r_ixr_rsp_fsm = IXR_RSP_TRT_READ; 4407 4408 #if DEBUG_MEMC_IXR_RSP 4409 if (m_debug) 4410 std::cout << " <MEMC " << name() 4411 << " IXR_RSP_IDLE> Response from XRAM to a get transaction" << std::endl; 4412 #endif 4413 } 4414 } 4415 break; 4416 } 4584 #endif 4585 } 4586 } 4587 break; 4588 } 4417 4589 //////////////////////// 4418 4590 case IXR_RSP_TRT_ERASE: // erase the entry in the TRT … … 4421 4593 if (r_alloc_trt_fsm.read() == ALLOC_TRT_IXR_RSP) 4422 4594 { 4423 size_t index = r_ixr_rsp_trt_index.read(); 4424 4425 if (m_trt.is_config(index)) // it's a config transaction4595 size_t index = r_ixr_rsp_trt_index.read(); 4596 4597 if (m_trt.is_config(index)) // it's a config transaction 4426 4598 { 4427 4599 config_rsp_lines_ixr_rsp_decr = true; … … 4432 4604 4433 4605 #if DEBUG_MEMC_IXR_RSP 4434 if (m_debug) 4435 std::cout << " <MEMC " << name() << " IXR_RSP_TRT_ERASE> Erase TRT entry " 4436 << r_ixr_rsp_trt_index.read() << std::endl; 4606 if (m_debug) 4607 { 4608 std::cout << " <MEMC " << name() << " IXR_RSP_TRT_ERASE> Erase TRT entry " 4609 << r_ixr_rsp_trt_index.read() << std::endl; 4610 } 4437 4611 #endif 4438 4612 } … … 4440 4614 } 4441 4615 ////////////////////// 4442 case IXR_RSP_TRT_READ: // write a 64 bits data word in TRT4443 { 4444 if ((r_alloc_trt_fsm.read() == ALLOC_TRT_IXR_RSP) and p_vci_ixr.rspval)4445 { 4446 size_t index = r_ixr_rsp_trt_index.read();4447 size_t word = r_ixr_rsp_cpt.read();4448 bool eop = p_vci_ixr.reop.read();4449 wide_data_t data = p_vci_ixr.rdata.read();4450 bool rerror = ((p_vci_ixr.rerror.read() & 0x1) == 1);4451 4452 assert(((eop == (word == (m_words -2))) or rerror) and4616 case IXR_RSP_TRT_READ: // write a 64 bits data word in TRT 4617 { 4618 if ((r_alloc_trt_fsm.read() == ALLOC_TRT_IXR_RSP) and p_vci_ixr.rspval) 4619 { 4620 size_t index = r_ixr_rsp_trt_index.read(); 4621 size_t word = r_ixr_rsp_cpt.read(); 4622 bool eop = p_vci_ixr.reop.read(); 4623 wide_data_t data = p_vci_ixr.rdata.read(); 4624 bool rerror = ((p_vci_ixr.rerror.read() & 0x1) == 1); 4625 4626 assert(((eop == (word == (m_words - 2))) or rerror) and 4453 4627 "MEMC ERROR in IXR_RSP_TRT_READ state : invalid response from XRAM"); 4454 4628 4455 m_trt.write_rsp( index, word, data, rerror);4629 m_trt.write_rsp(index, word, data, rerror); 4456 4630 4457 4631 r_ixr_rsp_cpt = word + 2; 4458 4632 4459 if (eop )4633 if (eop) 4460 4634 { 4461 4635 r_ixr_rsp_to_xram_rsp_rok[r_ixr_rsp_trt_index.read()] = true; … … 4464 4638 4465 4639 #if DEBUG_MEMC_IXR_RSP 4466 if (m_debug) 4467 std::cout << " <MEMC " << name() << " IXR_RSP_TRT_READ> Writing 2 words in TRT : " 4468 << " index = " << std::dec << index 4469 << " / word = " << word 4470 << " / data = " << std::hex << data << std::endl; 4640 if (m_debug) 4641 { 4642 std::cout << " <MEMC " << name() << " IXR_RSP_TRT_READ> Writing 2 words in TRT : " 4643 << " index = " << std::dec << index 4644 << " / word = " << word 4645 << " / data = " << std::hex << data << std::endl; 4646 } 4471 4647 #endif 4472 4648 } … … 4481 4657 // The cache line has been written in the TRT by the IXR_CMD_FSM. 4482 4658 // As the IXR_RSP FSM and the XRAM_RSP FSM are running in parallel, 4483 // there is as many flip-flops r_ixr_rsp_to_xram_rsp_rok[i] as the number 4659 // there is as many flip-flops r_ixr_rsp_to_xram_rsp_rok[i] as the number 4484 4660 // of entries in the TRT, that are handled with a round-robin priority... 4485 4661 // … … 4498 4674 /////////////////////////////////////////////////////////////////////////////// 4499 4675 4500 //std::cout << std::endl << "xram_rsp_fsm" << std::endl;4501 4502 4676 switch(r_xram_rsp_fsm.read()) 4503 4677 { 4504 4678 /////////////////// 4505 4679 case XRAM_RSP_IDLE: // scan the XRAM responses / select a TRT index (round robin) 4506 { 4507 size_t old = r_xram_rsp_trt_index.read(); 4508 size_t lines = m_trt_lines; 4509 for(size_t i=0 ; i<lines ; i++) 4510 { 4511 size_t index = (i+old+1) %lines; 4512 if (r_ixr_rsp_to_xram_rsp_rok[index]) 4513 { 4514 r_xram_rsp_trt_index = index; 4515 r_ixr_rsp_to_xram_rsp_rok[index] = false; 4516 r_xram_rsp_fsm = XRAM_RSP_DIR_LOCK; 4517 4518 #if DEBUG_MEMC_XRAM_RSP 4519 if (m_debug) 4520 std::cout << " <MEMC " << name() << " XRAM_RSP_IDLE>" 4521 << " Available cache line in TRT:" 4522 << " index = " << std::dec << index << std::endl; 4523 #endif 4524 break; 4525 } 4526 } 4527 break; 4528 } 4529 /////////////////////// 4530 case XRAM_RSP_DIR_LOCK: // Takes the DIR lock and the TRT lock 4531 // Copy the TRT entry in a local buffer 4532 { 4533 if ((r_alloc_dir_fsm.read() == ALLOC_DIR_XRAM_RSP) and 4534 (r_alloc_trt_fsm.read() == ALLOC_TRT_XRAM_RSP)) 4535 { 4536 // copy the TRT entry in the r_xram_rsp_trt_buf local buffer 4537 size_t index = r_xram_rsp_trt_index.read(); 4538 r_xram_rsp_trt_buf.copy( m_trt.read(index)); 4539 r_xram_rsp_fsm = XRAM_RSP_TRT_COPY; 4680 { 4681 size_t old = r_xram_rsp_trt_index.read(); 4682 size_t lines = m_trt_lines; 4683 for (size_t i = 0; i < lines; i++) 4684 { 4685 size_t index = (i + old + 1) % lines; 4686 if (r_ixr_rsp_to_xram_rsp_rok[index]) 4687 { 4688 r_xram_rsp_trt_index = index; 4689 r_ixr_rsp_to_xram_rsp_rok[index] = false; 4690 r_xram_rsp_fsm = XRAM_RSP_DIR_LOCK; 4540 4691 4541 4692 #if DEBUG_MEMC_XRAM_RSP 4542 4693 if (m_debug) 4543 std::cout << " <MEMC " << name() << " XRAM_RSP_DIR_LOCK>" 4544 << " Get access to DIR and TRT" << std::endl; 4545 #endif 4546 } 4547 break; 4548 } 4549 /////////////////////// 4550 case XRAM_RSP_TRT_COPY: // Select a victim cache line 4551 // and copy it in a local buffer 4552 { 4553 assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_XRAM_RSP) and 4554 "MEMC ERROR in XRAM_RSP_TRT_COPY state: Bad DIR allocation"); 4555 4556 assert( (r_alloc_trt_fsm.read() == ALLOC_TRT_XRAM_RSP) and 4557 "MEMC ERROR in XRAM_RSP_TRT_COPY state: Bad TRT allocation"); 4558 4559 // selects & extracts a victim line from cache 4560 size_t way = 0; 4561 size_t set = m_y[(addr_t)(r_xram_rsp_trt_buf.nline * m_words * 4)]; 4562 4563 DirectoryEntry victim(m_cache_directory.select(set, way)); 4564 4565 bool inval = (victim.count and victim.valid) ; 4566 4567 // copy the victim line in a local buffer (both data dir) 4568 m_cache_data.read_line(way, set, r_xram_rsp_victim_data); 4569 4570 r_xram_rsp_victim_copy = victim.owner.srcid; 4571 r_xram_rsp_victim_copy_inst = victim.owner.inst; 4572 r_xram_rsp_victim_count = victim.count; 4573 r_xram_rsp_victim_ptr = victim.ptr; 4574 r_xram_rsp_victim_way = way; 4575 r_xram_rsp_victim_set = set; 4576 r_xram_rsp_victim_nline = (addr_t)victim.tag*m_sets + set; 4577 r_xram_rsp_victim_is_cnt = victim.is_cnt; 4578 r_xram_rsp_victim_inval = inval ; 4579 r_xram_rsp_victim_dirty = victim.dirty; 4580 4581 if (not r_xram_rsp_trt_buf.rerror ) r_xram_rsp_fsm = XRAM_RSP_IVT_LOCK; 4582 else r_xram_rsp_fsm = XRAM_RSP_ERROR_ERASE; 4694 { 4695 std::cout << " <MEMC " << name() << " XRAM_RSP_IDLE>" 4696 << " Available cache line in TRT:" 4697 << " index = " << std::dec << index << std::endl; 4698 } 4699 #endif 4700 break; 4701 } 4702 } 4703 break; 4704 } 4705 /////////////////////// 4706 case XRAM_RSP_DIR_LOCK: // Takes the DIR lock and the TRT lock 4707 // Copy the TRT entry in a local buffer 4708 { 4709 if ((r_alloc_dir_fsm.read() == ALLOC_DIR_XRAM_RSP) and 4710 (r_alloc_trt_fsm.read() == ALLOC_TRT_XRAM_RSP)) 4711 { 4712 // copy the TRT entry in the r_xram_rsp_trt_buf local buffer 4713 size_t index = r_xram_rsp_trt_index.read(); 4714 r_xram_rsp_trt_buf.copy(m_trt.read(index)); 4715 r_xram_rsp_fsm = XRAM_RSP_TRT_COPY; 4583 4716 4584 4717 #if DEBUG_MEMC_XRAM_RSP 4585 4718 if (m_debug) 4586 std::cout << " <MEMC " << name() << " XRAM_RSP_TRT_COPY>" 4587 << " Select a victim slot: " 4588 << " way = " << std::dec << way 4589 << " / set = " << set 4590 << " / inval_required = " << inval << std::endl; 4591 #endif 4592 break; 4593 } 4594 /////////////////////// 4595 case XRAM_RSP_IVT_LOCK: // Keep DIR and TRT locks and take the IVT lock 4596 // to check a possible pending inval 4597 { 4598 assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_XRAM_RSP) and 4599 "MEMC ERROR in XRAM_RSP_IVT_LOCK state: Bad DIR allocation"); 4600 4601 assert( (r_alloc_trt_fsm.read() == ALLOC_TRT_XRAM_RSP) and 4602 "MEMC ERROR in XRAM_RSP_IVT_LOCK state: Bad TRT allocation"); 4603 4604 if (r_alloc_ivt_fsm == ALLOC_IVT_XRAM_RSP) 4605 { 4606 size_t index = 0; 4607 if (m_ivt.search_inval(r_xram_rsp_trt_buf.nline, index)) // pending inval 4719 { 4720 std::cout << " <MEMC " << name() << " XRAM_RSP_DIR_LOCK>" 4721 << " Get access to DIR and TRT" << std::endl; 4722 } 4723 #endif 4724 } 4725 break; 4726 } 4727 /////////////////////// 4728 case XRAM_RSP_TRT_COPY: // Select a victim cache line 4729 // and copy it in a local buffer 4730 { 4731 assert((r_alloc_dir_fsm.read() == ALLOC_DIR_XRAM_RSP) and 4732 "MEMC ERROR in XRAM_RSP_TRT_COPY state: Bad DIR allocation"); 4733 4734 assert((r_alloc_trt_fsm.read() == ALLOC_TRT_XRAM_RSP) and 4735 "MEMC ERROR in XRAM_RSP_TRT_COPY state: Bad TRT allocation"); 4736 4737 // selects & extracts a victim line from cache 4738 size_t way = 0; 4739 size_t set = m_y[(addr_t) (r_xram_rsp_trt_buf.nline * m_words * 4)]; 4740 4741 DirectoryEntry victim(m_cache_directory.select(set, way)); 4742 4743 bool inval = (victim.count and victim.valid) ; 4744 4745 // copy the victim line in a local buffer (both data dir) 4746 m_cache_data.read_line(way, set, r_xram_rsp_victim_data); 4747 4748 r_xram_rsp_victim_copy = victim.owner.srcid; 4749 r_xram_rsp_victim_copy_inst = victim.owner.inst; 4750 r_xram_rsp_victim_count = victim.count; 4751 r_xram_rsp_victim_ptr = victim.ptr; 4752 r_xram_rsp_victim_way = way; 4753 r_xram_rsp_victim_set = set; 4754 r_xram_rsp_victim_nline = (addr_t)victim.tag*m_sets + set; 4755 r_xram_rsp_victim_is_cnt = victim.is_cnt; 4756 r_xram_rsp_victim_inval = inval ; 4757 r_xram_rsp_victim_dirty = victim.dirty; 4758 4759 if (not r_xram_rsp_trt_buf.rerror) r_xram_rsp_fsm = XRAM_RSP_IVT_LOCK; 4760 else r_xram_rsp_fsm = XRAM_RSP_ERROR_ERASE; 4761 4762 #if DEBUG_MEMC_XRAM_RSP 4763 if (m_debug) 4764 { 4765 std::cout << " <MEMC " << name() << " XRAM_RSP_TRT_COPY>" 4766 << " Select a victim slot: " 4767 << " way = " << std::dec << way 4768 << " / set = " << set 4769 << " / inval_required = " << inval << std::endl; 4770 } 4771 #endif 4772 break; 4773 } 4774 /////////////////////// 4775 case XRAM_RSP_IVT_LOCK: // Keep DIR and TRT locks and take the IVT lock 4776 // to check a possible pending inval 4777 { 4778 assert((r_alloc_dir_fsm.read() == ALLOC_DIR_XRAM_RSP) and 4779 "MEMC ERROR in XRAM_RSP_IVT_LOCK state: Bad DIR allocation"); 4780 4781 assert((r_alloc_trt_fsm.read() == ALLOC_TRT_XRAM_RSP) and 4782 "MEMC ERROR in XRAM_RSP_IVT_LOCK state: Bad TRT allocation"); 4783 4784 if (r_alloc_ivt_fsm == ALLOC_IVT_XRAM_RSP) 4785 { 4786 size_t index = 0; 4787 if (m_ivt.search_inval(r_xram_rsp_trt_buf.nline, index)) // pending inval 4788 { 4789 r_xram_rsp_fsm = XRAM_RSP_INVAL_WAIT; 4790 4791 #if DEBUG_MEMC_XRAM_RSP 4792 if (m_debug) 4608 4793 { 4609 r_xram_rsp_fsm = XRAM_RSP_INVAL_WAIT; 4794 std::cout << " <MEMC " << name() << " XRAM_RSP_IVT_LOCK>" 4795 << " Get acces to IVT, but line invalidation registered" 4796 << " / address = " << std::hex << r_xram_rsp_trt_buf.nline * m_words * 4 4797 << " / index = " << std::dec << index << std::endl; 4798 } 4799 #endif 4800 4801 } 4802 else if (m_ivt.is_full() and r_xram_rsp_victim_inval.read()) // IVT full 4803 { 4804 r_xram_rsp_fsm = XRAM_RSP_INVAL_WAIT; 4610 4805 4611 4806 #if DEBUG_MEMC_XRAM_RSP 4612 if (m_debug) 4613 std::cout << " <MEMC " << name() << " XRAM_RSP_IVT_LOCK>" 4614 << " Get acces to IVT, but line invalidation registered" 4615 << " / address = " << std::hex << r_xram_rsp_trt_buf.nline*m_words*4 4616 << " / index = " << std::dec << index << std::endl; 4617 #endif 4618 4807 if (m_debug) 4808 { 4809 std::cout << " <MEMC " << name() << " XRAM_RSP_IVT_LOCK>" 4810 << " Get acces to IVT, but inval required and IVT full" << std::endl; 4619 4811 } 4620 else if (m_ivt.is_full() and r_xram_rsp_victim_inval.read()) // IVT full 4812 #endif 4813 } 4814 else 4815 { 4816 r_xram_rsp_fsm = XRAM_RSP_DIR_UPDT; 4817 4818 #if DEBUG_MEMC_XRAM_RSP 4819 if (m_debug) 4621 4820 { 4622 r_xram_rsp_fsm = XRAM_RSP_INVAL_WAIT; 4821 std::cout << " <MEMC " << name() << " XRAM_RSP_IVT_LOCK>" 4822 << " Get acces to IVT / no pending inval request" << std::endl; 4823 } 4824 #endif 4825 } 4826 } 4827 break; 4828 } 4829 ///////////////////////// 4830 case XRAM_RSP_INVAL_WAIT: // release all locks and returns to DIR_LOCK to retry 4831 { 4623 4832 4624 4833 #if DEBUG_MEMC_XRAM_RSP 4625 if (m_debug) 4626 std::cout << " <MEMC " << name() << " XRAM_RSP_IVT_LOCK>" 4627 << " Get acces to IVT, but inval required and IVT full" << std::endl; 4628 #endif 4629 } 4630 else 4631 { 4632 r_xram_rsp_fsm = XRAM_RSP_DIR_UPDT; 4834 if (m_debug) 4835 { 4836 std::cout << " <MEMC " << name() << " XRAM_RSP_INVAL_WAIT>" 4837 << " Release all locks and retry" << std::endl; 4838 } 4839 #endif 4840 r_xram_rsp_fsm = XRAM_RSP_DIR_LOCK; 4841 break; 4842 } 4843 /////////////////////// 4844 case XRAM_RSP_DIR_UPDT: // updates the cache (both data & directory), 4845 // erases the TRT entry if victim not dirty, 4846 // and set inval request in IVT if required 4847 { 4848 assert((r_alloc_dir_fsm.read() == ALLOC_DIR_XRAM_RSP) and 4849 "MEMC ERROR in XRAM_RSP_DIR_UPDT state: Bad DIR allocation"); 4850 4851 assert((r_alloc_trt_fsm.read() == ALLOC_TRT_XRAM_RSP) and 4852 "MEMC ERROR in XRAM_RSP_DIR_UPDT state: Bad TRT allocation"); 4853 4854 assert((r_alloc_ivt_fsm.read() == ALLOC_IVT_XRAM_RSP) and 4855 "MEMC ERROR in XRAM_RSP_DIR_UPDT state: Bad IVT allocation"); 4856 4857 // check if this is an instruction read, this means pktid is either 4858 // TYPE_READ_INS_UNC 0bX010 with TSAR encoding 4859 // TYPE_READ_INS_MISS 0bX011 with TSAR encoding 4860 bool inst_read = (r_xram_rsp_trt_buf.pktid & 0x2) and r_xram_rsp_trt_buf.proc_read; 4861 4862 // check if this is a cached read, this means pktid is either 4863 // TYPE_READ_DATA_MISS 0bX001 with TSAR encoding 4864 // TYPE_READ_INS_MISS 0bX011 with TSAR encoding 4865 bool cached_read = (r_xram_rsp_trt_buf.pktid & 0x1) and r_xram_rsp_trt_buf.proc_read; 4866 4867 bool dirty = false; 4868 4869 // update cache data 4870 size_t set = r_xram_rsp_victim_set.read(); 4871 size_t way = r_xram_rsp_victim_way.read(); 4872 4873 for (size_t word = 0; word < m_words; word++) 4874 { 4875 m_cache_data.write(way, set, word, r_xram_rsp_trt_buf.wdata[word]); 4876 dirty = dirty or (r_xram_rsp_trt_buf.wdata_be[word] != 0); 4877 } 4878 4879 // update cache directory 4880 DirectoryEntry entry; 4881 entry.valid = true; 4882 entry.is_cnt = false; 4883 entry.lock = false; 4884 entry.dirty = dirty; 4885 entry.tag = r_xram_rsp_trt_buf.nline / m_sets; 4886 entry.ptr = 0; 4887 if (cached_read) 4888 { 4889 entry.owner.srcid = r_xram_rsp_trt_buf.srcid; 4890 entry.owner.inst = inst_read; 4891 entry.count = 1; 4892 } 4893 else 4894 { 4895 entry.owner.srcid = 0; 4896 entry.owner.inst = 0; 4897 entry.count = 0; 4898 } 4899 m_cache_directory.write(set, way, entry); 4900 4901 // register invalid request in IVT for victim line if required 4902 if (r_xram_rsp_victim_inval.read()) 4903 { 4904 bool broadcast = r_xram_rsp_victim_is_cnt.read(); 4905 size_t index = 0; 4906 size_t count_copies = r_xram_rsp_victim_count.read(); 4907 4908 bool wok = m_ivt.set(false, // it's an inval transaction 4909 broadcast, // set broadcast bit 4910 false, // no response required 4911 false, // no acknowledge required 4912 0, // srcid 4913 0, // trdid 4914 0, // pktid 4915 r_xram_rsp_victim_nline.read(), 4916 count_copies, 4917 index); 4918 4919 r_xram_rsp_ivt_index = index; 4920 4921 assert(wok and "MEMC ERROR in XRAM_RSP_DIR_UPDT state: IVT should not be full"); 4922 } 4633 4923 4634 4924 #if DEBUG_MEMC_XRAM_RSP 4635 if (m_debug) 4636 std::cout << " <MEMC " << name() << " XRAM_RSP_IVT_LOCK>" 4637 << " Get acces to IVT / no pending inval request" << std::endl; 4638 #endif 4639 } 4640 } 4641 break; 4642 } 4643 ///////////////////////// 4644 case XRAM_RSP_INVAL_WAIT: // release all locks and returns to DIR_LOCK to retry 4645 { 4925 if (m_debug) 4926 { 4927 std::cout << " <MEMC " << name() << " XRAM_RSP_DIR_UPDT>" 4928 << " Cache update: " 4929 << " way = " << std::dec << way 4930 << " / set = " << set 4931 << " / owner_id = " << std::hex << entry.owner.srcid 4932 << " / owner_ins = " << std::dec << entry.owner.inst 4933 << " / count = " << entry.count 4934 << " / is_cnt = " << entry.is_cnt << std::endl; 4935 if (r_xram_rsp_victim_inval.read()) 4936 { 4937 std::cout << " Invalidation request for address " 4938 << std::hex << r_xram_rsp_victim_nline.read() * m_words * 4 4939 << " / broadcast = " << r_xram_rsp_victim_is_cnt.read() << std::endl; 4940 } 4941 } 4942 #endif 4943 4944 // If the victim is not dirty, we don't need to reuse the TRT entry for 4945 // another PUT transaction, and we can erase the TRT entry 4946 if (not r_xram_rsp_victim_dirty.read()) 4947 { 4948 m_trt.erase(r_xram_rsp_trt_index.read()); 4949 } 4950 4951 // Next state 4952 if (r_xram_rsp_victim_dirty.read()) r_xram_rsp_fsm = XRAM_RSP_TRT_DIRTY; 4953 else if (r_xram_rsp_trt_buf.proc_read) r_xram_rsp_fsm = XRAM_RSP_DIR_RSP; 4954 else if (r_xram_rsp_victim_inval.read()) r_xram_rsp_fsm = XRAM_RSP_INVAL; 4955 else r_xram_rsp_fsm = XRAM_RSP_IDLE; 4956 break; 4957 } 4958 //////////////////////// 4959 case XRAM_RSP_TRT_DIRTY: // set the TRT entry (PUT to XRAM) if the victim is dirty 4960 { 4961 if (r_alloc_trt_fsm.read() == ALLOC_TRT_XRAM_RSP) 4962 { 4963 std::vector<data_t> data_vector; 4964 data_vector.clear(); 4965 for (size_t i = 0; i < m_words; i++) 4966 { 4967 data_vector.push_back(r_xram_rsp_victim_data[i].read()); 4968 } 4969 m_trt.set(r_xram_rsp_trt_index.read(), 4970 false, // PUT 4971 r_xram_rsp_victim_nline.read(), // line index 4972 0, // unused 4973 0, // unused 4974 0, // unused 4975 false, // not proc_read 4976 0, // unused 4977 0, // unused 4978 std::vector<be_t>(m_words,0xF), 4979 data_vector); 4646 4980 4647 4981 #if DEBUG_MEMC_XRAM_RSP 4648 4982 if (m_debug) 4649 std::cout << " <MEMC " << name() << " XRAM_RSP_INVAL_WAIT>" 4650 << " Release all locks and retry" << std::endl; 4651 #endif 4652 r_xram_rsp_fsm = XRAM_RSP_DIR_LOCK; 4653 break; 4654 } 4655 /////////////////////// 4656 case XRAM_RSP_DIR_UPDT: // updates the cache (both data & directory), 4657 // erases the TRT entry if victim not dirty, 4658 // and set inval request in IVT if required 4659 { 4660 assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_XRAM_RSP) and 4661 "MEMC ERROR in XRAM_RSP_DIR_UPDT state: Bad DIR allocation"); 4662 4663 assert( (r_alloc_trt_fsm.read() == ALLOC_TRT_XRAM_RSP) and 4664 "MEMC ERROR in XRAM_RSP_DIR_UPDT state: Bad TRT allocation"); 4665 4666 assert( (r_alloc_ivt_fsm.read() == ALLOC_IVT_XRAM_RSP) and 4667 "MEMC ERROR in XRAM_RSP_DIR_UPDT state: Bad IVT allocation"); 4668 4669 // check if this is an instruction read, this means pktid is either 4670 // TYPE_READ_INS_UNC 0bX010 with TSAR encoding 4671 // TYPE_READ_INS_MISS 0bX011 with TSAR encoding 4672 bool inst_read = (r_xram_rsp_trt_buf.pktid & 0x2) and r_xram_rsp_trt_buf.proc_read; 4673 4674 // check if this is a cached read, this means pktid is either 4675 // TYPE_READ_DATA_MISS 0bX001 with TSAR encoding 4676 // TYPE_READ_INS_MISS 0bX011 with TSAR encoding 4677 bool cached_read = (r_xram_rsp_trt_buf.pktid & 0x1) and r_xram_rsp_trt_buf.proc_read; 4678 4679 bool dirty = false; 4680 4681 // update cache data 4682 size_t set = r_xram_rsp_victim_set.read(); 4683 size_t way = r_xram_rsp_victim_way.read(); 4684 4685 for(size_t word=0; word<m_words ; word++) 4686 { 4687 m_cache_data.write(way, set, word, r_xram_rsp_trt_buf.wdata[word]); 4688 dirty = dirty or (r_xram_rsp_trt_buf.wdata_be[word] != 0); 4689 } 4690 4691 // update cache directory 4692 DirectoryEntry entry; 4693 entry.valid = true; 4694 entry.is_cnt = false; 4695 entry.lock = false; 4696 entry.dirty = dirty; 4697 entry.tag = r_xram_rsp_trt_buf.nline / m_sets; 4698 entry.ptr = 0; 4699 if (cached_read) 4700 { 4701 entry.owner.srcid = r_xram_rsp_trt_buf.srcid; 4702 entry.owner.inst = inst_read; 4703 entry.count = 1; 4704 } 4705 else 4706 { 4707 entry.owner.srcid = 0; 4708 entry.owner.inst = 0; 4709 entry.count = 0; 4710 } 4711 m_cache_directory.write(set, way, entry); 4712 4713 // register invalid request in IVT for victim line if required 4714 if (r_xram_rsp_victim_inval.read()) 4715 { 4716 bool broadcast = r_xram_rsp_victim_is_cnt.read(); 4717 size_t index = 0; 4718 size_t count_copies = r_xram_rsp_victim_count.read(); 4719 4720 bool wok = m_ivt.set(false, // it's an inval transaction 4721 broadcast, // set broadcast bit 4722 false, // no response required 4723 false, // no acknowledge required 4724 0, // srcid 4725 0, // trdid 4726 0, // pktid 4727 r_xram_rsp_victim_nline.read(), 4728 count_copies, 4729 index); 4730 4731 r_xram_rsp_ivt_index = index; 4732 4733 assert( wok and 4734 "MEMC ERROR in XRAM_RSP_DIR_UPDT state: IVT should not be full"); 4735 } 4983 { 4984 std::cout << " <MEMC " << name() << " XRAM_RSP_TRT_DIRTY>" 4985 << " Set TRT entry for the put transaction" 4986 << " / address = " << (r_xram_rsp_victim_nline.read() * m_words * 4) << std::endl; 4987 } 4988 #endif 4989 if (r_xram_rsp_trt_buf.proc_read) r_xram_rsp_fsm = XRAM_RSP_DIR_RSP; 4990 else if (r_xram_rsp_victim_inval.read()) r_xram_rsp_fsm = XRAM_RSP_INVAL; 4991 else r_xram_rsp_fsm = XRAM_RSP_WRITE_DIRTY; 4992 } 4993 break; 4994 } 4995 ////////////////////// 4996 case XRAM_RSP_DIR_RSP: // Request a response to TGT_RSP FSM 4997 { 4998 if (not r_xram_rsp_to_tgt_rsp_req.read()) 4999 { 5000 r_xram_rsp_to_tgt_rsp_srcid = r_xram_rsp_trt_buf.srcid; 5001 r_xram_rsp_to_tgt_rsp_trdid = r_xram_rsp_trt_buf.trdid; 5002 r_xram_rsp_to_tgt_rsp_pktid = r_xram_rsp_trt_buf.pktid; 5003 for (size_t i = 0; i < m_words; i++) 5004 { 5005 r_xram_rsp_to_tgt_rsp_data[i] = r_xram_rsp_trt_buf.wdata[i]; 5006 } 5007 r_xram_rsp_to_tgt_rsp_word = r_xram_rsp_trt_buf.word_index; 5008 r_xram_rsp_to_tgt_rsp_length = r_xram_rsp_trt_buf.read_length; 5009 r_xram_rsp_to_tgt_rsp_ll_key = r_xram_rsp_trt_buf.ll_key; 5010 r_xram_rsp_to_tgt_rsp_rerror = false; 5011 r_xram_rsp_to_tgt_rsp_req = true; 5012 5013 if (r_xram_rsp_victim_inval.read()) r_xram_rsp_fsm = XRAM_RSP_INVAL; 5014 else if (r_xram_rsp_victim_dirty.read()) r_xram_rsp_fsm = XRAM_RSP_WRITE_DIRTY; 5015 else r_xram_rsp_fsm = XRAM_RSP_IDLE; 4736 5016 4737 5017 #if DEBUG_MEMC_XRAM_RSP 4738 5018 if (m_debug) 4739 5019 { 4740 std::cout << " <MEMC " << name() << " XRAM_RSP_DIR_UPDT>" 4741 << " Cache update: " 4742 << " way = " << std::dec << way 4743 << " / set = " << set 4744 << " / owner_id = " << std::hex << entry.owner.srcid 4745 << " / owner_ins = " << std::dec << entry.owner.inst 4746 << " / count = " << entry.count 4747 << " / is_cnt = " << entry.is_cnt << std::endl; 4748 if (r_xram_rsp_victim_inval.read()) 4749 std::cout << " Invalidation request for address " 4750 << std::hex << r_xram_rsp_victim_nline.read()*m_words*4 4751 << " / broadcast = " << r_xram_rsp_victim_is_cnt.read() << std::endl; 4752 } 4753 #endif 4754 4755 // If the victim is not dirty, we don't need to reuse the TRT entry for 4756 // another PUT transaction, and we can erase the TRT entry 4757 if (not r_xram_rsp_victim_dirty.read()) 4758 { 4759 m_trt.erase(r_xram_rsp_trt_index.read()); 4760 } 4761 4762 // Next state 4763 if (r_xram_rsp_victim_dirty.read()) r_xram_rsp_fsm = XRAM_RSP_TRT_DIRTY; 4764 else if (r_xram_rsp_trt_buf.proc_read) r_xram_rsp_fsm = XRAM_RSP_DIR_RSP; 4765 else if (r_xram_rsp_victim_inval.read()) r_xram_rsp_fsm = XRAM_RSP_INVAL; 4766 else r_xram_rsp_fsm = XRAM_RSP_IDLE; 4767 break; 4768 } 4769 //////////////////////// 4770 case XRAM_RSP_TRT_DIRTY: // set the TRT entry (PUT to XRAM) if the victim is dirty 4771 { 4772 if (r_alloc_trt_fsm.read() == ALLOC_TRT_XRAM_RSP) 4773 { 4774 std::vector<data_t> data_vector; 4775 data_vector.clear(); 4776 for(size_t i=0; i<m_words; i++) 4777 { 4778 data_vector.push_back(r_xram_rsp_victim_data[i].read()); 4779 } 4780 m_trt.set( r_xram_rsp_trt_index.read(), 4781 false, // PUT 4782 r_xram_rsp_victim_nline.read(), // line index 4783 0, // unused 4784 0, // unused 4785 0, // unused 4786 false, // not proc_read 4787 0, // unused 4788 0, // unused 4789 std::vector<be_t>(m_words,0xF), 4790 data_vector); 4791 4792 #if DEBUG_MEMC_XRAM_RSP 4793 if (m_debug) 4794 std::cout << " <MEMC " << name() << " XRAM_RSP_TRT_DIRTY>" 4795 << " Set TRT entry for the put transaction" 4796 << " / address = " << (r_xram_rsp_victim_nline.read()*m_words*4) << std::endl; 4797 #endif 4798 if (r_xram_rsp_trt_buf.proc_read) r_xram_rsp_fsm = XRAM_RSP_DIR_RSP; 4799 else if (r_xram_rsp_victim_inval.read()) r_xram_rsp_fsm = XRAM_RSP_INVAL; 4800 else r_xram_rsp_fsm = XRAM_RSP_WRITE_DIRTY; 4801 } 4802 break; 4803 } 4804 ////////////////////// 4805 case XRAM_RSP_DIR_RSP: // Request a response to TGT_RSP FSM 4806 { 4807 if (not r_xram_rsp_to_tgt_rsp_req.read()) 4808 { 4809 r_xram_rsp_to_tgt_rsp_srcid = r_xram_rsp_trt_buf.srcid; 4810 r_xram_rsp_to_tgt_rsp_trdid = r_xram_rsp_trt_buf.trdid; 4811 r_xram_rsp_to_tgt_rsp_pktid = r_xram_rsp_trt_buf.pktid; 4812 for(size_t i=0; i < m_words; i++) 4813 { 4814 r_xram_rsp_to_tgt_rsp_data[i] = r_xram_rsp_trt_buf.wdata[i]; 4815 } 4816 r_xram_rsp_to_tgt_rsp_word = r_xram_rsp_trt_buf.word_index; 4817 r_xram_rsp_to_tgt_rsp_length = r_xram_rsp_trt_buf.read_length; 4818 r_xram_rsp_to_tgt_rsp_ll_key = r_xram_rsp_trt_buf.ll_key; 4819 r_xram_rsp_to_tgt_rsp_rerror = false; 4820 r_xram_rsp_to_tgt_rsp_req = true; 4821 4822 if (r_xram_rsp_victim_inval.read()) r_xram_rsp_fsm = XRAM_RSP_INVAL; 4823 else if (r_xram_rsp_victim_dirty.read()) r_xram_rsp_fsm = XRAM_RSP_WRITE_DIRTY; 4824 else r_xram_rsp_fsm = XRAM_RSP_IDLE; 4825 4826 #if DEBUG_MEMC_XRAM_RSP 4827 if (m_debug) 4828 std::cout << " <MEMC " << name() << " XRAM_RSP_DIR_RSP>" 4829 << " Request the TGT_RSP FSM to return data:" 4830 << " rsrcid = " << std::hex << r_xram_rsp_trt_buf.srcid 4831 << " / address = " << std::hex << r_xram_rsp_trt_buf.nline*m_words*4 4832 << " / nwords = " << std::dec << r_xram_rsp_trt_buf.read_length << std::endl; 4833 #endif 4834 } 4835 break; 4836 } 4837 //////////////////// 5020 std::cout << " <MEMC " << name() << " XRAM_RSP_DIR_RSP>" 5021 << " Request the TGT_RSP FSM to return data:" 5022 << " rsrcid = " << std::hex << r_xram_rsp_trt_buf.srcid 5023 << " / address = " << std::hex << r_xram_rsp_trt_buf.nline * m_words * 4 5024 << " / nwords = " << std::dec << r_xram_rsp_trt_buf.read_length << std::endl; 5025 } 5026 #endif 5027 } 5028 break; 5029 } 5030 //////////////////// 4838 5031 case XRAM_RSP_INVAL: // send invalidate request to CC_SEND FSM 4839 { 4840 if (!r_xram_rsp_to_cc_send_multi_req.read() and 4841 !r_xram_rsp_to_cc_send_brdcast_req.read()) 4842 { 4843 bool multi_req = !r_xram_rsp_victim_is_cnt.read(); 4844 bool last_multi_req = multi_req and (r_xram_rsp_victim_count.read() == 1); 4845 bool not_last_multi_req = multi_req and (r_xram_rsp_victim_count.read() != 1); 4846 4847 r_xram_rsp_to_cc_send_multi_req = last_multi_req; 4848 r_xram_rsp_to_cc_send_brdcast_req = r_xram_rsp_victim_is_cnt.read(); 4849 r_xram_rsp_to_cc_send_nline = r_xram_rsp_victim_nline.read(); 4850 r_xram_rsp_to_cc_send_trdid = r_xram_rsp_ivt_index; 4851 xram_rsp_to_cc_send_fifo_srcid = r_xram_rsp_victim_copy.read(); 4852 xram_rsp_to_cc_send_fifo_inst = r_xram_rsp_victim_copy_inst.read(); 4853 xram_rsp_to_cc_send_fifo_put = multi_req; 4854 r_xram_rsp_next_ptr = r_xram_rsp_victim_ptr.read(); 4855 4856 if (r_xram_rsp_victim_dirty) r_xram_rsp_fsm = XRAM_RSP_WRITE_DIRTY; 4857 else if (not_last_multi_req) r_xram_rsp_fsm = XRAM_RSP_HEAP_REQ; 4858 else r_xram_rsp_fsm = XRAM_RSP_IDLE; 4859 4860 #if DEBUG_MEMC_XRAM_RSP 4861 if (m_debug) 4862 std::cout << " <MEMC " << name() << " XRAM_RSP_INVAL>" 4863 << " Send an inval request to CC_SEND FSM" 4864 << " / address = " << r_xram_rsp_victim_nline.read()*m_words*4 << std::endl; 4865 #endif 4866 } 4867 break; 4868 } 4869 ////////////////////////// 4870 case XRAM_RSP_WRITE_DIRTY: // send a write request to IXR_CMD FSM 4871 { 4872 if (not r_xram_rsp_to_ixr_cmd_req.read()) 4873 { 4874 r_xram_rsp_to_ixr_cmd_req = true; 4875 r_xram_rsp_to_ixr_cmd_index = r_xram_rsp_trt_index.read(); 4876 4877 m_cpt_write_dirty++; 4878 4879 bool multi_req = not r_xram_rsp_victim_is_cnt.read() and 4880 r_xram_rsp_victim_inval.read(); 4881 bool not_last_multi_req = multi_req and (r_xram_rsp_victim_count.read() != 1); 4882 4883 if (not_last_multi_req) r_xram_rsp_fsm = XRAM_RSP_HEAP_REQ; 4884 else r_xram_rsp_fsm = XRAM_RSP_IDLE; 4885 4886 #if DEBUG_MEMC_XRAM_RSP 4887 if (m_debug) 4888 std::cout << " <MEMC " << name() << " XRAM_RSP_WRITE_DIRTY>" 4889 << " Send the put request to IXR_CMD FSM" 4890 << " / address = " << r_xram_rsp_victim_nline.read()*m_words*4 << std::endl; 4891 #endif 4892 } 4893 break; 4894 } 4895 ///////////////////////// 4896 case XRAM_RSP_HEAP_REQ: // Get the lock to the HEAP 4897 { 4898 if (r_alloc_heap_fsm.read() == ALLOC_HEAP_XRAM_RSP) 4899 { 4900 r_xram_rsp_fsm = XRAM_RSP_HEAP_ERASE; 4901 } 5032 { 5033 if (!r_xram_rsp_to_cc_send_multi_req.read() and 5034 !r_xram_rsp_to_cc_send_brdcast_req.read()) 5035 { 5036 bool multi_req = !r_xram_rsp_victim_is_cnt.read(); 5037 bool last_multi_req = multi_req and (r_xram_rsp_victim_count.read() == 1); 5038 bool not_last_multi_req = multi_req and (r_xram_rsp_victim_count.read() != 1); 5039 5040 r_xram_rsp_to_cc_send_multi_req = last_multi_req; 5041 r_xram_rsp_to_cc_send_brdcast_req = r_xram_rsp_victim_is_cnt.read(); 5042 r_xram_rsp_to_cc_send_nline = r_xram_rsp_victim_nline.read(); 5043 r_xram_rsp_to_cc_send_trdid = r_xram_rsp_ivt_index; 5044 xram_rsp_to_cc_send_fifo_srcid = r_xram_rsp_victim_copy.read(); 5045 xram_rsp_to_cc_send_fifo_inst = r_xram_rsp_victim_copy_inst.read(); 5046 xram_rsp_to_cc_send_fifo_put = multi_req; 5047 r_xram_rsp_next_ptr = r_xram_rsp_victim_ptr.read(); 5048 5049 if (r_xram_rsp_victim_dirty) r_xram_rsp_fsm = XRAM_RSP_WRITE_DIRTY; 5050 else if (not_last_multi_req) r_xram_rsp_fsm = XRAM_RSP_HEAP_REQ; 5051 else r_xram_rsp_fsm = XRAM_RSP_IDLE; 4902 5052 4903 5053 #if DEBUG_MEMC_XRAM_RSP 4904 5054 if (m_debug) 4905 std::cout << " <MEMC " << name() << " XRAM_RSP_HEAP_REQ>" 4906 << " Requesting HEAP lock" << std::endl; 4907 #endif 4908 break; 4909 } 4910 ///////////////////////// 5055 { 5056 std::cout << " <MEMC " << name() << " XRAM_RSP_INVAL>" 5057 << " Send an inval request to CC_SEND FSM" 5058 << " / address = " << r_xram_rsp_victim_nline.read()*m_words*4 << std::endl; 5059 } 5060 #endif 5061 } 5062 break; 5063 } 5064 ////////////////////////// 5065 case XRAM_RSP_WRITE_DIRTY: // send a write request to IXR_CMD FSM 5066 { 5067 if (not r_xram_rsp_to_ixr_cmd_req.read()) 5068 { 5069 r_xram_rsp_to_ixr_cmd_req = true; 5070 r_xram_rsp_to_ixr_cmd_index = r_xram_rsp_trt_index.read(); 5071 5072 m_cpt_write_dirty++; 5073 5074 bool multi_req = not r_xram_rsp_victim_is_cnt.read() and 5075 r_xram_rsp_victim_inval.read(); 5076 bool not_last_multi_req = multi_req and (r_xram_rsp_victim_count.read() != 1); 5077 5078 if (not_last_multi_req) r_xram_rsp_fsm = XRAM_RSP_HEAP_REQ; 5079 else r_xram_rsp_fsm = XRAM_RSP_IDLE; 5080 5081 #if DEBUG_MEMC_XRAM_RSP 5082 if (m_debug) 5083 { 5084 std::cout << " <MEMC " << name() << " XRAM_RSP_WRITE_DIRTY>" 5085 << " Send the put request to IXR_CMD FSM" 5086 << " / address = " << r_xram_rsp_victim_nline.read() * m_words * 4 << std::endl; 5087 } 5088 #endif 5089 } 5090 break; 5091 } 5092 ///////////////////////// 5093 case XRAM_RSP_HEAP_REQ: // Get the lock to the HEAP 5094 { 5095 if (r_alloc_heap_fsm.read() == ALLOC_HEAP_XRAM_RSP) 5096 { 5097 r_xram_rsp_fsm = XRAM_RSP_HEAP_ERASE; 5098 } 5099 5100 #if DEBUG_MEMC_XRAM_RSP 5101 if (m_debug) 5102 { 5103 std::cout << " <MEMC " << name() << " XRAM_RSP_HEAP_REQ>" 5104 << " Requesting HEAP lock" << std::endl; 5105 } 5106 #endif 5107 break; 5108 } 5109 ///////////////////////// 4911 5110 case XRAM_RSP_HEAP_ERASE: // erase the copies and send invalidations 4912 { 4913 if (r_alloc_heap_fsm.read() == ALLOC_HEAP_XRAM_RSP) 4914 { 4915 HeapEntry entry = m_heap.read(r_xram_rsp_next_ptr.read()); 4916 4917 xram_rsp_to_cc_send_fifo_srcid = entry.owner.srcid; 4918 xram_rsp_to_cc_send_fifo_inst = entry.owner.inst; 4919 xram_rsp_to_cc_send_fifo_put = true; 4920 if (m_xram_rsp_to_cc_send_inst_fifo.wok()) 5111 { 5112 if (r_alloc_heap_fsm.read() == ALLOC_HEAP_XRAM_RSP) 5113 { 5114 HeapEntry entry = m_heap.read(r_xram_rsp_next_ptr.read()); 5115 5116 xram_rsp_to_cc_send_fifo_srcid = entry.owner.srcid; 5117 xram_rsp_to_cc_send_fifo_inst = entry.owner.inst; 5118 xram_rsp_to_cc_send_fifo_put = true; 5119 if (m_xram_rsp_to_cc_send_inst_fifo.wok()) 5120 { 5121 r_xram_rsp_next_ptr = entry.next; 5122 if (entry.next == r_xram_rsp_next_ptr.read()) // last copy 4921 5123 { 4922 r_xram_rsp_next_ptr = entry.next; 4923 if (entry.next == r_xram_rsp_next_ptr.read()) // last copy 4924 { 4925 r_xram_rsp_to_cc_send_multi_req = true; 4926 r_xram_rsp_fsm = XRAM_RSP_HEAP_LAST; 4927 } 4928 else 4929 { 4930 r_xram_rsp_fsm = XRAM_RSP_HEAP_ERASE; 4931 } 5124 r_xram_rsp_to_cc_send_multi_req = true; 5125 r_xram_rsp_fsm = XRAM_RSP_HEAP_LAST; 4932 5126 } 4933 5127 else … … 4935 5129 r_xram_rsp_fsm = XRAM_RSP_HEAP_ERASE; 4936 5130 } 5131 } 5132 else 5133 { 5134 r_xram_rsp_fsm = XRAM_RSP_HEAP_ERASE; 5135 } 5136 5137 #if DEBUG_MEMC_XRAM_RSP 5138 if (m_debug) 5139 { 5140 std::cout << " <MEMC " << name() << " XRAM_RSP_HEAP_ERASE>" 5141 << " Erase copy:" 5142 << " srcid = " << std::hex << entry.owner.srcid 5143 << " / inst = " << std::dec << entry.owner.inst << std::endl; 5144 } 5145 #endif 5146 } 5147 break; 5148 } 5149 ///////////////////////// 5150 case XRAM_RSP_HEAP_LAST: // last copy 5151 { 5152 if (r_alloc_heap_fsm.read() != ALLOC_HEAP_XRAM_RSP) 5153 { 5154 std::cout << "VCI_MEM_CACHE ERROR " << name() << " XRAM_RSP_HEAP_LAST" 5155 << " bad HEAP allocation" << std::endl; 5156 exit(0); 5157 } 5158 size_t free_pointer = m_heap.next_free_ptr(); 5159 5160 HeapEntry last_entry; 5161 last_entry.owner.srcid = 0; 5162 last_entry.owner.inst = false; 5163 if (m_heap.is_full()) 5164 { 5165 last_entry.next = r_xram_rsp_next_ptr.read(); 5166 m_heap.unset_full(); 5167 } 5168 else 5169 { 5170 last_entry.next = free_pointer; 5171 } 5172 5173 m_heap.write_free_ptr(r_xram_rsp_victim_ptr.read()); 5174 m_heap.write(r_xram_rsp_next_ptr.read(),last_entry); 5175 5176 r_xram_rsp_fsm = XRAM_RSP_IDLE; 5177 5178 #if DEBUG_MEMC_XRAM_RSP 5179 if (m_debug) 5180 { 5181 std::cout << " <MEMC " << name() << " XRAM_RSP_HEAP_LAST>" 5182 << " Heap housekeeping" << std::endl; 5183 } 5184 #endif 5185 break; 5186 } 5187 ////////////////////////// 5188 case XRAM_RSP_ERROR_ERASE: // erase TRT entry in case of error 5189 { 5190 m_trt.erase(r_xram_rsp_trt_index.read()); 5191 5192 // Next state 5193 if (r_xram_rsp_trt_buf.proc_read) 5194 { 5195 r_xram_rsp_fsm = XRAM_RSP_ERROR_RSP; 5196 } 5197 else 5198 { 5199 // Trigger an interruption to signal a bus error from 5200 // the XRAM because a processor WRITE MISS (XRAM GET 5201 // transaction and not processor read). 5202 // 5203 // To avoid deadlocks we do not wait an error to be 5204 // acknowledged before signaling another one. 5205 // Therefore, when there is an active error, and other 5206 // errors arrive, these are not considered 5207 5208 if (!r_xram_rsp_rerror_irq.read() && r_xram_rsp_rerror_irq_enable.read() 5209 && r_xram_rsp_trt_buf.xram_read) 5210 { 5211 r_xram_rsp_rerror_irq = true; 5212 r_xram_rsp_rerror_address = r_xram_rsp_trt_buf.nline * m_words * 4; 5213 r_xram_rsp_rerror_rsrcid = r_xram_rsp_trt_buf.srcid; 4937 5214 4938 5215 #if DEBUG_MEMC_XRAM_RSP 4939 5216 if (m_debug) 4940 std::cout << " <MEMC " << name() << " XRAM_RSP_HEAP_ERASE>" 4941 << " Erase copy:" 4942 << " srcid = " << std::hex << entry.owner.srcid 4943 << " / inst = " << std::dec << entry.owner.inst << std::endl; 4944 #endif 4945 } 4946 break; 4947 } 4948 ///////////////////////// 4949 case XRAM_RSP_HEAP_LAST: // last copy 4950 { 4951 if (r_alloc_heap_fsm.read() != ALLOC_HEAP_XRAM_RSP) 4952 { 4953 std::cout << "VCI_MEM_CACHE ERROR " << name() << " XRAM_RSP_HEAP_LAST" 4954 << " bad HEAP allocation" << std::endl; 4955 exit(0); 4956 } 4957 size_t free_pointer = m_heap.next_free_ptr(); 4958 4959 HeapEntry last_entry; 4960 last_entry.owner.srcid = 0; 4961 last_entry.owner.inst = false; 4962 if (m_heap.is_full()) 4963 { 4964 last_entry.next = r_xram_rsp_next_ptr.read(); 4965 m_heap.unset_full(); 4966 } 4967 else 4968 { 4969 last_entry.next = free_pointer; 4970 } 4971 4972 m_heap.write_free_ptr(r_xram_rsp_victim_ptr.read()); 4973 m_heap.write(r_xram_rsp_next_ptr.read(),last_entry); 5217 { 5218 std::cout 5219 << " <MEMC " << name() << " XRAM_RSP_ERROR_ERASE>" 5220 << " Triggering interrupt to signal WRITE MISS bus error" 5221 << " / irq_enable = " << r_xram_rsp_rerror_irq_enable.read() 5222 << " / nline = " << r_xram_rsp_trt_buf.nline 5223 << " / rsrcid = " << r_xram_rsp_trt_buf.srcid 5224 << std::endl; 5225 } 5226 #endif 5227 } 5228 5229 r_xram_rsp_fsm = XRAM_RSP_IDLE; 5230 } 5231 5232 #if DEBUG_MEMC_XRAM_RSP 5233 if (m_debug) 5234 { 5235 std::cout << " <MEMC " << name() << " XRAM_RSP_ERROR_ERASE>" 5236 << " Error reported by XRAM / erase the TRT entry" << std::endl; 5237 } 5238 #endif 5239 break; 5240 } 5241 //////////////////////// 5242 case XRAM_RSP_ERROR_RSP: // Request an error response to TGT_RSP FSM 5243 { 5244 if (!r_xram_rsp_to_tgt_rsp_req.read()) 5245 { 5246 r_xram_rsp_to_tgt_rsp_srcid = r_xram_rsp_trt_buf.srcid; 5247 r_xram_rsp_to_tgt_rsp_trdid = r_xram_rsp_trt_buf.trdid; 5248 r_xram_rsp_to_tgt_rsp_pktid = r_xram_rsp_trt_buf.pktid; 5249 for (size_t i = 0; i < m_words; i++) 5250 { 5251 r_xram_rsp_to_tgt_rsp_data[i] = r_xram_rsp_trt_buf.wdata[i]; 5252 } 5253 r_xram_rsp_to_tgt_rsp_word = r_xram_rsp_trt_buf.word_index; 5254 r_xram_rsp_to_tgt_rsp_length = r_xram_rsp_trt_buf.read_length; 5255 r_xram_rsp_to_tgt_rsp_rerror = true; 5256 r_xram_rsp_to_tgt_rsp_req = true; 4974 5257 4975 5258 r_xram_rsp_fsm = XRAM_RSP_IDLE; … … 4977 5260 #if DEBUG_MEMC_XRAM_RSP 4978 5261 if (m_debug) 4979 std::cout << " <MEMC " << name() << " XRAM_RSP_HEAP_LAST>" 4980 << " Heap housekeeping" << std::endl; 4981 #endif 4982 break; 4983 } 4984 ////////////////////////// 4985 case XRAM_RSP_ERROR_ERASE: // erase TRT entry in case of error 4986 { 4987 m_trt.erase(r_xram_rsp_trt_index.read()); 4988 4989 // Next state 4990 if (r_xram_rsp_trt_buf.proc_read) 4991 { 4992 r_xram_rsp_fsm = XRAM_RSP_ERROR_RSP; 4993 } 4994 else 4995 { 4996 // Trigger an interruption to signal a bus error from 4997 // the XRAM because a processor WRITE MISS (XRAM GET 4998 // transaction and not processor read). 4999 // 5000 // To avoid deadlocks we do not wait an error to be 5001 // acknowledged before signaling another one. 5002 // Therefore, when there is an active error, and other 5003 // errors arrive, these are not considered 5004 5005 if (!r_xram_rsp_rerror_irq.read() && r_xram_rsp_rerror_irq_enable.read() 5006 && r_xram_rsp_trt_buf.xram_read ) 5007 { 5008 r_xram_rsp_rerror_irq = true; 5009 r_xram_rsp_rerror_address = r_xram_rsp_trt_buf.nline * m_words * 4; 5010 r_xram_rsp_rerror_rsrcid = r_xram_rsp_trt_buf.srcid; 5011 5012 #if DEBUG_MEMC_XRAM_RSP 5013 if (m_debug) 5014 std::cout 5015 << " <MEMC " << name() << " XRAM_RSP_ERROR_ERASE>" 5016 << " Triggering interrupt to signal WRITE MISS bus error" 5017 << " / irq_enable = " << r_xram_rsp_rerror_irq_enable.read() 5018 << " / nline = " << r_xram_rsp_trt_buf.nline 5019 << " / rsrcid = " << r_xram_rsp_trt_buf.srcid 5020 << std::endl; 5021 #endif 5022 } 5023 5024 r_xram_rsp_fsm = XRAM_RSP_IDLE; 5025 } 5026 5027 #if DEBUG_MEMC_XRAM_RSP 5028 if (m_debug) 5029 std::cout << " <MEMC " << name() << " XRAM_RSP_ERROR_ERASE>" 5030 << " Error reported by XRAM / erase the TRT entry" << std::endl; 5031 #endif 5032 break; 5033 } 5034 //////////////////////// 5035 case XRAM_RSP_ERROR_RSP: // Request an error response to TGT_RSP FSM 5036 { 5037 if (!r_xram_rsp_to_tgt_rsp_req.read()) 5038 { 5039 r_xram_rsp_to_tgt_rsp_srcid = r_xram_rsp_trt_buf.srcid; 5040 r_xram_rsp_to_tgt_rsp_trdid = r_xram_rsp_trt_buf.trdid; 5041 r_xram_rsp_to_tgt_rsp_pktid = r_xram_rsp_trt_buf.pktid; 5042 for(size_t i=0; i < m_words; i++) 5043 { 5044 r_xram_rsp_to_tgt_rsp_data[i] = r_xram_rsp_trt_buf.wdata[i]; 5045 } 5046 r_xram_rsp_to_tgt_rsp_word = r_xram_rsp_trt_buf.word_index; 5047 r_xram_rsp_to_tgt_rsp_length = r_xram_rsp_trt_buf.read_length; 5048 r_xram_rsp_to_tgt_rsp_rerror = true; 5049 r_xram_rsp_to_tgt_rsp_req = true; 5050 5051 r_xram_rsp_fsm = XRAM_RSP_IDLE; 5052 5053 #if DEBUG_MEMC_XRAM_RSP 5054 if (m_debug) 5055 std::cout << " <MEMC " << name() 5056 << " XRAM_RSP_ERROR_RSP> Request a response error to TGT_RSP FSM:" 5057 << " srcid = " << std::dec << r_xram_rsp_trt_buf.srcid << std::endl; 5058 #endif 5059 } 5060 break; 5061 } 5262 { 5263 std::cout << " <MEMC " << name() 5264 << " XRAM_RSP_ERROR_RSP> Request a response error to TGT_RSP FSM:" 5265 << " srcid = " << std::dec << r_xram_rsp_trt_buf.srcid << std::endl; 5266 } 5267 #endif 5268 } 5269 break; 5270 } 5062 5271 } // end swich r_xram_rsp_fsm 5063 5272 … … 5073 5282 ////////////////// 5074 5283 case CLEANUP_IDLE: // Get first DSPIN flit of the CLEANUP command 5075 { 5076 if (not m_cc_receive_to_cleanup_fifo.rok()) break; 5077 5078 uint64_t flit = m_cc_receive_to_cleanup_fifo.read(); 5079 5080 uint32_t srcid = DspinDhccpParam::dspin_get(flit, 5081 DspinDhccpParam::CLEANUP_SRCID); 5082 5083 uint8_t type = DspinDhccpParam::dspin_get(flit, 5084 DspinDhccpParam::P2M_TYPE); 5085 5086 r_cleanup_way_index = DspinDhccpParam::dspin_get(flit, 5087 DspinDhccpParam::CLEANUP_WAY_INDEX); 5088 5089 r_cleanup_nline = DspinDhccpParam::dspin_get(flit, 5090 DspinDhccpParam::CLEANUP_NLINE_MSB) << 32; 5091 5092 r_cleanup_inst = (type == DspinDhccpParam::TYPE_CLEANUP_INST); 5093 r_cleanup_srcid = srcid; 5094 5095 assert((srcid < m_initiators) and 5096 "MEMC ERROR in CLEANUP_IDLE state : illegal SRCID value"); 5097 5098 cc_receive_to_cleanup_fifo_get = true; 5099 r_cleanup_fsm = CLEANUP_GET_NLINE; 5284 { 5285 if (not m_cc_receive_to_cleanup_fifo.rok()) break; 5286 5287 uint64_t flit = m_cc_receive_to_cleanup_fifo.read(); 5288 5289 uint32_t srcid = DspinDhccpParam::dspin_get(flit, 5290 DspinDhccpParam::CLEANUP_SRCID); 5291 5292 uint8_t type = DspinDhccpParam::dspin_get(flit, 5293 DspinDhccpParam::P2M_TYPE); 5294 5295 r_cleanup_way_index = DspinDhccpParam::dspin_get(flit, 5296 DspinDhccpParam::CLEANUP_WAY_INDEX); 5297 5298 r_cleanup_nline = DspinDhccpParam::dspin_get(flit, 5299 DspinDhccpParam::CLEANUP_NLINE_MSB) << 32; 5300 5301 r_cleanup_inst = (type == DspinDhccpParam::TYPE_CLEANUP_INST); 5302 r_cleanup_srcid = srcid; 5303 5304 assert((srcid < m_initiators) and 5305 "MEMC ERROR in CLEANUP_IDLE state : illegal SRCID value"); 5306 5307 cc_receive_to_cleanup_fifo_get = true; 5308 r_cleanup_fsm = CLEANUP_GET_NLINE; 5309 5310 #if DEBUG_MEMC_CLEANUP 5311 if (m_debug) 5312 { 5313 std::cout << " <MEMC " << name() 5314 << " CLEANUP_IDLE> Cleanup request:" << std::hex 5315 << " owner_id = " << srcid 5316 << " / owner_ins = " << (type == DspinDhccpParam::TYPE_CLEANUP_INST) << std::endl; 5317 } 5318 #endif 5319 break; 5320 } 5321 /////////////////////// 5322 case CLEANUP_GET_NLINE: // GET second DSPIN flit of the cleanup command 5323 { 5324 if (not m_cc_receive_to_cleanup_fifo.rok()) break; 5325 5326 uint64_t flit = m_cc_receive_to_cleanup_fifo.read(); 5327 5328 addr_t nline = r_cleanup_nline.read() | 5329 DspinDhccpParam::dspin_get(flit, DspinDhccpParam::CLEANUP_NLINE_LSB); 5330 5331 cc_receive_to_cleanup_fifo_get = true; 5332 r_cleanup_nline = nline; 5333 r_cleanup_fsm = CLEANUP_DIR_REQ; 5334 5335 #if DEBUG_MEMC_CLEANUP 5336 if (m_debug) 5337 { 5338 std::cout << " <MEMC " << name() 5339 << " CLEANUP_GET_NLINE> Cleanup request:" 5340 << " address = " << std::hex << nline * m_words * 4 << std::endl; 5341 } 5342 #endif 5343 break; 5344 } 5345 ///////////////////// 5346 case CLEANUP_DIR_REQ: // Get the lock to the directory 5347 { 5348 if (r_alloc_dir_fsm.read() != ALLOC_DIR_CLEANUP) break; 5349 5350 r_cleanup_fsm = CLEANUP_DIR_LOCK; 5351 5352 #if DEBUG_MEMC_CLEANUP 5353 if (m_debug) 5354 { 5355 std::cout << " <MEMC " << name() << " CLEANUP_DIR_REQ> Requesting DIR lock" << std::endl; 5356 } 5357 #endif 5358 break; 5359 } 5360 ////////////////////// 5361 case CLEANUP_DIR_LOCK: // test directory status 5362 { 5363 assert((r_alloc_dir_fsm.read() == ALLOC_DIR_CLEANUP) and 5364 "MEMC ERROR in CLEANUP_DIR_LOCK: bad DIR allocation"); 5365 5366 // Read the directory 5367 size_t way = 0; 5368 addr_t cleanup_address = r_cleanup_nline.read() * m_words * 4; 5369 DirectoryEntry entry = m_cache_directory.read(cleanup_address , way); 5370 r_cleanup_is_cnt = entry.is_cnt; 5371 r_cleanup_dirty = entry.dirty; 5372 r_cleanup_tag = entry.tag; 5373 r_cleanup_lock = entry.lock; 5374 r_cleanup_way = way; 5375 r_cleanup_count = entry.count; 5376 r_cleanup_ptr = entry.ptr; 5377 r_cleanup_copy = entry.owner.srcid; 5378 r_cleanup_copy_inst = entry.owner.inst; 5379 5380 if (entry.valid) // hit : the copy must be cleared 5381 { 5382 assert((entry.count > 0) and 5383 "MEMC ERROR in CLEANUP_DIR_LOCK state, CLEANUP on valid entry with no copies"); 5384 5385 if ((entry.count == 1) or (entry.is_cnt)) // no access to the heap 5386 { 5387 r_cleanup_fsm = CLEANUP_DIR_WRITE; 5388 } 5389 else // access to the heap 5390 { 5391 r_cleanup_fsm = CLEANUP_HEAP_REQ; 5392 } 5393 } 5394 else // miss : check IVT for a pending inval 5395 { 5396 r_cleanup_fsm = CLEANUP_IVT_LOCK; 5397 } 5398 5399 #if DEBUG_MEMC_CLEANUP 5400 if (m_debug) 5401 { 5402 std::cout << " <MEMC " << name() 5403 << " CLEANUP_DIR_LOCK> Test directory status: " 5404 << std::hex << " address = " << cleanup_address 5405 << " / hit = " << entry.valid 5406 << " / dir_id = " << entry.owner.srcid 5407 << " / dir_ins = " << entry.owner.inst 5408 << " / search_id = " << r_cleanup_srcid.read() 5409 << " / search_ins = " << r_cleanup_inst.read() 5410 << " / count = " << entry.count 5411 << " / is_cnt = " << entry.is_cnt << std::endl; 5412 } 5413 #endif 5414 break; 5415 } 5416 /////////////////////// 5417 case CLEANUP_DIR_WRITE: // Update the directory entry without heap access 5418 { 5419 assert((r_alloc_dir_fsm.read() == ALLOC_DIR_CLEANUP) and 5420 "MEMC ERROR in CLEANUP_DIR_LOCK: bad DIR allocation"); 5421 5422 size_t way = r_cleanup_way.read(); 5423 size_t set = m_y[(addr_t) (r_cleanup_nline.read() * m_words * 4)]; 5424 bool match_srcid = (r_cleanup_copy.read() == r_cleanup_srcid.read()); 5425 bool match_inst = (r_cleanup_copy_inst.read() == r_cleanup_inst.read()); 5426 bool match = match_srcid and match_inst; 5427 5428 assert((r_cleanup_is_cnt.read() or match) and 5429 "MEMC ERROR in CLEANUP_DIR_LOCK: illegal CLEANUP on valid entry"); 5430 5431 // update the cache directory (for the copies) 5432 DirectoryEntry entry; 5433 entry.valid = true; 5434 entry.is_cnt = r_cleanup_is_cnt.read(); 5435 entry.dirty = r_cleanup_dirty.read(); 5436 entry.tag = r_cleanup_tag.read(); 5437 entry.lock = r_cleanup_lock.read(); 5438 entry.ptr = r_cleanup_ptr.read(); 5439 entry.count = r_cleanup_count.read() - 1; 5440 entry.owner.srcid = 0; 5441 entry.owner.inst = 0; 5442 5443 m_cache_directory.write(set, way, entry); 5444 5445 r_cleanup_fsm = CLEANUP_SEND_CLACK; 5446 5447 #if DEBUG_MEMC_CLEANUP 5448 if (m_debug) 5449 { 5450 std::cout << " <MEMC " << name() 5451 << " CLEANUP_DIR_WRITE> Update directory:" 5452 << std::hex << " address = " << r_cleanup_nline.read() * m_words * 4 5453 << " / dir_id = " << entry.owner.srcid 5454 << " / dir_ins = " << entry.owner.inst 5455 << " / count = " << entry.count 5456 << " / is_cnt = " << entry.is_cnt << std::endl; 5457 } 5458 #endif 5459 5460 break; 5461 } 5462 ////////////////////// 5463 case CLEANUP_HEAP_REQ: // get the lock to the HEAP directory 5464 { 5465 if (r_alloc_heap_fsm.read() != ALLOC_HEAP_CLEANUP) break; 5466 5467 r_cleanup_fsm = CLEANUP_HEAP_LOCK; 5468 5469 #if DEBUG_MEMC_CLEANUP 5470 if (m_debug) 5471 { 5472 std::cout << " <MEMC " << name() 5473 << " CLEANUP_HEAP_REQ> HEAP lock acquired " << std::endl; 5474 } 5475 #endif 5476 break; 5477 } 5478 ////////////////////// 5479 case CLEANUP_HEAP_LOCK: // two cases are handled in this state : 5480 // 1. the matching copy is directly in the directory 5481 // 2. the matching copy is the first copy in the heap 5482 { 5483 assert((r_alloc_heap_fsm.read() == ALLOC_HEAP_CLEANUP) and 5484 "MEMC ERROR in CLEANUP_HEAP_LOCK state: bad HEAP allocation"); 5485 5486 size_t way = r_cleanup_way.read(); 5487 size_t set = m_y[(addr_t)(r_cleanup_nline.read() * m_words * 4)]; 5488 5489 HeapEntry heap_entry = m_heap.read(r_cleanup_ptr.read()); 5490 bool last = (heap_entry.next == r_cleanup_ptr.read()); 5491 5492 // match_dir computation 5493 bool match_dir_srcid = (r_cleanup_copy.read() == r_cleanup_srcid.read()); 5494 bool match_dir_inst = (r_cleanup_copy_inst.read() == r_cleanup_inst.read()); 5495 bool match_dir = match_dir_srcid and match_dir_inst; 5496 5497 // match_heap computation 5498 bool match_heap_srcid = (heap_entry.owner.srcid == r_cleanup_srcid.read()); 5499 bool match_heap_inst = (heap_entry.owner.inst == r_cleanup_inst.read()); 5500 bool match_heap = match_heap_srcid and match_heap_inst; 5501 5502 r_cleanup_prev_ptr = r_cleanup_ptr.read(); 5503 r_cleanup_prev_srcid = heap_entry.owner.srcid; 5504 r_cleanup_prev_inst = heap_entry.owner.inst; 5505 5506 assert((not last or match_dir or match_heap) and 5507 "MEMC ERROR in CLEANUP_HEAP_LOCK state: hit but no copy found"); 5508 5509 assert((not match_dir or not match_heap) and 5510 "MEMC ERROR in CLEANUP_HEAP_LOCK state: two matching copies found"); 5511 5512 DirectoryEntry dir_entry; 5513 dir_entry.valid = true; 5514 dir_entry.is_cnt = r_cleanup_is_cnt.read(); 5515 dir_entry.dirty = r_cleanup_dirty.read(); 5516 dir_entry.tag = r_cleanup_tag.read(); 5517 dir_entry.lock = r_cleanup_lock.read(); 5518 dir_entry.count = r_cleanup_count.read() - 1; 5519 5520 // the matching copy is registered in the directory and 5521 // it must be replaced by the first copy registered in 5522 // the heap. The corresponding entry must be freed 5523 if (match_dir) 5524 { 5525 dir_entry.ptr = heap_entry.next; 5526 dir_entry.owner.srcid = heap_entry.owner.srcid; 5527 dir_entry.owner.inst = heap_entry.owner.inst; 5528 r_cleanup_next_ptr = r_cleanup_ptr.read(); 5529 r_cleanup_fsm = CLEANUP_HEAP_FREE; 5530 } 5531 5532 // the matching copy is the first copy in the heap 5533 // It must be freed and the copy registered in directory 5534 // must point to the next copy in heap 5535 else if (match_heap) 5536 { 5537 dir_entry.ptr = heap_entry.next; 5538 dir_entry.owner.srcid = r_cleanup_copy.read(); 5539 dir_entry.owner.inst = r_cleanup_copy_inst.read(); 5540 r_cleanup_next_ptr = r_cleanup_ptr.read(); 5541 r_cleanup_fsm = CLEANUP_HEAP_FREE; 5542 } 5543 5544 // The matching copy is in the heap, but is not the first copy 5545 // The directory entry must be modified to decrement count 5546 else 5547 { 5548 dir_entry.ptr = r_cleanup_ptr.read(); 5549 dir_entry.owner.srcid = r_cleanup_copy.read(); 5550 dir_entry.owner.inst = r_cleanup_copy_inst.read(); 5551 r_cleanup_next_ptr = heap_entry.next; 5552 r_cleanup_fsm = CLEANUP_HEAP_SEARCH; 5553 } 5554 5555 m_cache_directory.write(set,way,dir_entry); 5556 5557 #if DEBUG_MEMC_CLEANUP 5558 if (m_debug) 5559 { 5560 std::cout << " <MEMC " << name() 5561 << " CLEANUP_HEAP_LOCK> Checks matching:" 5562 << " address = " << r_cleanup_nline.read() * m_words * 4 5563 << " / dir_id = " << r_cleanup_copy.read() 5564 << " / dir_ins = " << r_cleanup_copy_inst.read() 5565 << " / heap_id = " << heap_entry.owner.srcid 5566 << " / heap_ins = " << heap_entry.owner.inst 5567 << " / search_id = " << r_cleanup_srcid.read() 5568 << " / search_ins = " << r_cleanup_inst.read() << std::endl; 5569 } 5570 #endif 5571 break; 5572 } 5573 //////////////////////// 5574 case CLEANUP_HEAP_SEARCH: // This state is handling the case where the copy 5575 // is in the heap, but not the first in linked list 5576 { 5577 assert((r_alloc_heap_fsm.read() == ALLOC_HEAP_CLEANUP) and 5578 "MEMC ERROR in CLEANUP_HEAP_LOCK state: bad HEAP allocation"); 5579 5580 HeapEntry heap_entry = m_heap.read(r_cleanup_next_ptr.read()); 5581 5582 bool last = (heap_entry.next == r_cleanup_next_ptr.read()); 5583 bool match_heap_srcid = (heap_entry.owner.srcid == r_cleanup_srcid.read()); 5584 bool match_heap_inst = (heap_entry.owner.inst == r_cleanup_inst.read()); 5585 bool match_heap = match_heap_srcid and match_heap_inst; 5586 5587 assert((not last or match_heap) and 5588 "MEMC ERROR in CLEANUP_HEAP_SEARCH state: no copy found"); 5589 5590 // the matching copy must be removed 5591 if (match_heap) 5592 { 5593 // re-use ressources 5594 r_cleanup_ptr = heap_entry.next; 5595 r_cleanup_fsm = CLEANUP_HEAP_CLEAN; 5596 } 5597 // test the next in the linked list 5598 else 5599 { 5600 r_cleanup_prev_ptr = r_cleanup_next_ptr.read(); 5601 r_cleanup_prev_srcid = heap_entry.owner.srcid; 5602 r_cleanup_prev_inst = heap_entry.owner.inst; 5603 r_cleanup_next_ptr = heap_entry.next; 5604 r_cleanup_fsm = CLEANUP_HEAP_SEARCH; 5605 } 5606 5607 #if DEBUG_MEMC_CLEANUP 5608 if (m_debug) 5609 { 5610 if (not match_heap) 5611 { 5612 std::cout 5613 << " <MEMC " << name() 5614 << " CLEANUP_HEAP_SEARCH> Matching copy not found, search next:" 5615 << std::endl; 5616 } 5617 else 5618 { 5619 std::cout 5620 << " <MEMC " << name() 5621 << " CLEANUP_HEAP_SEARCH> Matching copy found:" 5622 << std::endl; 5623 } 5624 std::cout 5625 << " address = " << r_cleanup_nline.read() * m_words * 4 5626 << " / heap_id = " << heap_entry.owner.srcid 5627 << " / heap_ins = " << heap_entry.owner.inst 5628 << " / search_id = " << r_cleanup_srcid.read() 5629 << " / search_ins = " << r_cleanup_inst.read() 5630 << " / last = " << last 5631 << std::endl; 5632 } 5633 #endif 5634 break; 5635 } 5636 //////////////////////// 5637 case CLEANUP_HEAP_CLEAN: // remove a copy in the linked list 5638 { 5639 assert((r_alloc_heap_fsm.read() == ALLOC_HEAP_CLEANUP) and 5640 "MEMC ERROR in CLEANUP_HEAP_LOCK state: bad HEAP allocation"); 5641 5642 HeapEntry heap_entry; 5643 heap_entry.owner.srcid = r_cleanup_prev_srcid.read(); 5644 heap_entry.owner.inst = r_cleanup_prev_inst.read(); 5645 bool last = (r_cleanup_next_ptr.read() == r_cleanup_ptr.read()); 5646 5647 if (last) // this is the last entry of the list of copies 5648 { 5649 heap_entry.next = r_cleanup_prev_ptr.read(); 5650 } 5651 else // this is not the last entry 5652 { 5653 heap_entry.next = r_cleanup_ptr.read(); 5654 } 5655 5656 m_heap.write(r_cleanup_prev_ptr.read(), heap_entry); 5657 5658 r_cleanup_fsm = CLEANUP_HEAP_FREE; 5659 5660 #if DEBUG_MEMC_CLEANUP 5661 if (m_debug) 5662 { 5663 std::cout << " <MEMC " << name() << " CLEANUP_HEAP_SEARCH>" 5664 << " Remove the copy in the linked list" << std::endl; 5665 } 5666 #endif 5667 break; 5668 } 5669 /////////////////////// 5670 case CLEANUP_HEAP_FREE: // The heap entry pointed by r_cleanup_next_ptr is freed 5671 // and becomes the head of the list of free entries 5672 { 5673 assert((r_alloc_heap_fsm.read() == ALLOC_HEAP_CLEANUP) and 5674 "MEMC ERROR in CLEANUP_HEAP_LOCK state: bad HEAP allocation"); 5675 5676 HeapEntry heap_entry; 5677 heap_entry.owner.srcid = 0; 5678 heap_entry.owner.inst = false; 5679 5680 if (m_heap.is_full()) 5681 { 5682 heap_entry.next = r_cleanup_next_ptr.read(); 5683 } 5684 else 5685 { 5686 heap_entry.next = m_heap.next_free_ptr(); 5687 } 5688 5689 m_heap.write(r_cleanup_next_ptr.read(),heap_entry); 5690 m_heap.write_free_ptr(r_cleanup_next_ptr.read()); 5691 m_heap.unset_full(); 5692 5693 r_cleanup_fsm = CLEANUP_SEND_CLACK; 5694 5695 #if DEBUG_MEMC_CLEANUP 5696 if (m_debug) 5697 { 5698 std::cout << " <MEMC " << name() << " CLEANUP_HEAP_FREE>" 5699 << " Update the list of free entries" << std::endl; 5700 } 5701 #endif 5702 break; 5703 } 5704 ////////////////////// 5705 case CLEANUP_IVT_LOCK: // get the lock protecting the IVT to search a pending 5706 // invalidate transaction matching the cleanup 5707 { 5708 if (r_alloc_ivt_fsm.read() != ALLOC_IVT_CLEANUP) break; 5709 5710 size_t index = 0; 5711 bool match_inval; 5712 5713 match_inval = m_ivt.search_inval(r_cleanup_nline.read(), index); 5714 5715 if (not match_inval) // no pending inval in IVT 5716 { 5717 r_cleanup_fsm = CLEANUP_SEND_CLACK; 5100 5718 5101 5719 #if DEBUG_MEMC_CLEANUP 5102 5720 if (m_debug) 5103 std::cout << " <MEMC " << name() 5104 << " CLEANUP_IDLE> Cleanup request:" << std::hex 5105 << " owner_id = " << srcid 5106 << " / owner_ins = " << (type == DspinDhccpParam::TYPE_CLEANUP_INST) << std::endl; 5107 #endif 5108 break; 5109 } 5110 /////////////////////// 5111 case CLEANUP_GET_NLINE: // GET second DSPIN flit of the cleanup command 5112 { 5113 if (not m_cc_receive_to_cleanup_fifo.rok()) break; 5114 5115 uint64_t flit = m_cc_receive_to_cleanup_fifo.read(); 5116 5117 addr_t nline = r_cleanup_nline.read() | 5118 DspinDhccpParam::dspin_get(flit, DspinDhccpParam::CLEANUP_NLINE_LSB); 5119 5120 cc_receive_to_cleanup_fifo_get = true; 5121 r_cleanup_nline = nline; 5122 r_cleanup_fsm = CLEANUP_DIR_REQ; 5721 { 5722 std::cout << " <MEMC " << name() << " CLEANUP_IVT_LOCK>" 5723 << " Unexpected cleanup with no corresponding IVT entry:" 5724 << " address = " << std::hex << (r_cleanup_nline.read() * 4 * m_words) << std::endl; 5725 } 5726 #endif 5727 } 5728 else // pending inval in IVT 5729 { 5730 r_cleanup_write_srcid = m_ivt.srcid(index); 5731 r_cleanup_write_trdid = m_ivt.trdid(index); 5732 r_cleanup_write_pktid = m_ivt.pktid(index); 5733 r_cleanup_need_rsp = m_ivt.need_rsp(index); 5734 r_cleanup_need_ack = m_ivt.need_ack(index); 5735 r_cleanup_index = index; 5736 r_cleanup_fsm = CLEANUP_IVT_DECREMENT; 5123 5737 5124 5738 #if DEBUG_MEMC_CLEANUP 5125 5739 if (m_debug) 5126 std::cout << " <MEMC " << name() 5127 << " CLEANUP_GET_NLINE> Cleanup request:" 5128 << " address = " << std::hex << nline * m_words * 4 << std::endl; 5129 #endif 5130 break; 5131 } 5132 ///////////////////// 5133 case CLEANUP_DIR_REQ: // Get the lock to the directory 5134 { 5135 if (r_alloc_dir_fsm.read() != ALLOC_DIR_CLEANUP) break; 5136 5137 r_cleanup_fsm = CLEANUP_DIR_LOCK; 5740 { 5741 std::cout << " <MEMC " << name() << " CLEANUP_IVT_LOCK>" 5742 << " Cleanup matching pending invalidate transaction on IVT:" 5743 << " address = " << std::hex << (r_cleanup_nline.read() * m_words * 4) 5744 << " / ivt_entry = " << index << std::endl; 5745 } 5746 #endif 5747 } 5748 break; 5749 } 5750 /////////////////////////// 5751 case CLEANUP_IVT_DECREMENT: // decrement response counter in IVT matching entry 5752 // and test if last 5753 { 5754 assert((r_alloc_ivt_fsm.read() == ALLOC_IVT_CLEANUP) and 5755 "MEMC ERROR in CLEANUP_IVT_DECREMENT state: Bad IVT allocation"); 5756 5757 size_t count = 0; 5758 m_ivt.decrement(r_cleanup_index.read(), count); 5759 5760 if (count == 0) r_cleanup_fsm = CLEANUP_IVT_CLEAR; 5761 else r_cleanup_fsm = CLEANUP_SEND_CLACK ; 5138 5762 5139 5763 #if DEBUG_MEMC_CLEANUP 5140 if (m_debug) 5141 std::cout << " <MEMC " << name() << " CLEANUP_DIR_REQ> Requesting DIR lock" << std::endl; 5142 #endif 5143 break; 5144 } 5145 ////////////////////// 5146 case CLEANUP_DIR_LOCK: // test directory status 5147 { 5148 assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_CLEANUP) and 5149 "MEMC ERROR in CLEANUP_DIR_LOCK: bad DIR allocation"); 5150 5151 // Read the directory 5152 size_t way = 0; 5153 addr_t cleanup_address = r_cleanup_nline.read() * m_words * 4; 5154 DirectoryEntry entry = m_cache_directory.read(cleanup_address , way); 5155 r_cleanup_is_cnt = entry.is_cnt; 5156 r_cleanup_dirty = entry.dirty; 5157 r_cleanup_tag = entry.tag; 5158 r_cleanup_lock = entry.lock; 5159 r_cleanup_way = way; 5160 r_cleanup_count = entry.count; 5161 r_cleanup_ptr = entry.ptr; 5162 r_cleanup_copy = entry.owner.srcid; 5163 r_cleanup_copy_inst = entry.owner.inst; 5164 5165 if (entry.valid) // hit : the copy must be cleared 5166 { 5167 assert( (entry.count > 0) and 5168 "MEMC ERROR in CLEANUP_DIR_LOCK state, CLEANUP on valid entry with no copies"); 5169 5170 if ((entry.count == 1) or (entry.is_cnt)) // no access to the heap 5171 { 5172 r_cleanup_fsm = CLEANUP_DIR_WRITE; 5173 } 5174 else // access to the heap 5175 { 5176 r_cleanup_fsm = CLEANUP_HEAP_REQ; 5177 } 5178 } 5179 else // miss : check IVT for a pending inval 5180 { 5181 r_cleanup_fsm = CLEANUP_IVT_LOCK; 5182 } 5764 if (m_debug) 5765 { 5766 std::cout << " <MEMC " << name() << " CLEANUP_IVT_DECREMENT>" 5767 << " Decrement response counter in IVT:" 5768 << " IVT_index = " << r_cleanup_index.read() 5769 << " / rsp_count = " << count << std::endl; 5770 } 5771 #endif 5772 break; 5773 } 5774 /////////////////////// 5775 case CLEANUP_IVT_CLEAR: // Clear IVT entry 5776 // Acknowledge CONFIG FSM if required 5777 { 5778 assert((r_alloc_ivt_fsm.read() == ALLOC_IVT_CLEANUP) and 5779 "MEMC ERROR in CLEANUP_IVT_CLEAR state : bad IVT allocation"); 5780 5781 m_ivt.clear(r_cleanup_index.read()); 5782 5783 if (r_cleanup_need_ack.read()) 5784 { 5785 assert((r_config_rsp_lines.read() > 0) and 5786 "MEMC ERROR in CLEANUP_IVT_CLEAR state"); 5787 5788 config_rsp_lines_cleanup_decr = true; 5789 } 5790 5791 if (r_cleanup_need_rsp.read()) r_cleanup_fsm = CLEANUP_WRITE_RSP; 5792 else r_cleanup_fsm = CLEANUP_SEND_CLACK; 5183 5793 5184 5794 #if DEBUG_MEMC_CLEANUP 5185 if (m_debug) 5186 std::cout << " <MEMC " << name() 5187 << " CLEANUP_DIR_LOCK> Test directory status: " 5188 << std::hex << " address = " << cleanup_address 5189 << " / hit = " << entry.valid 5190 << " / dir_id = " << entry.owner.srcid 5191 << " / dir_ins = " << entry.owner.inst 5192 << " / search_id = " << r_cleanup_srcid.read() 5193 << " / search_ins = " << r_cleanup_inst.read() 5194 << " / count = " << entry.count 5195 << " / is_cnt = " << entry.is_cnt << std::endl; 5196 #endif 5197 break; 5198 } 5199 /////////////////////// 5200 case CLEANUP_DIR_WRITE: // Update the directory entry without heap access 5201 { 5202 assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_CLEANUP) and 5203 "MEMC ERROR in CLEANUP_DIR_LOCK: bad DIR allocation"); 5204 5205 size_t way = r_cleanup_way.read(); 5206 size_t set = m_y[(addr_t)(r_cleanup_nline.read()*m_words*4)]; 5207 bool match_srcid = (r_cleanup_copy.read() == r_cleanup_srcid.read()); 5208 bool match_inst = (r_cleanup_copy_inst.read() == r_cleanup_inst.read()); 5209 bool match = match_srcid and match_inst; 5210 5211 assert( (r_cleanup_is_cnt.read() or match) and 5212 "MEMC ERROR in CLEANUP_DIR_LOCK: illegal CLEANUP on valid entry"); 5213 5214 // update the cache directory (for the copies) 5215 DirectoryEntry entry; 5216 entry.valid = true; 5217 entry.is_cnt = r_cleanup_is_cnt.read(); 5218 entry.dirty = r_cleanup_dirty.read(); 5219 entry.tag = r_cleanup_tag.read(); 5220 entry.lock = r_cleanup_lock.read(); 5221 entry.ptr = r_cleanup_ptr.read(); 5222 entry.count = r_cleanup_count.read() - 1; 5223 entry.owner.srcid = 0; 5224 entry.owner.inst = 0; 5225 5226 m_cache_directory.write(set, way, entry); 5227 5228 r_cleanup_fsm = CLEANUP_SEND_CLACK; 5795 if (m_debug) 5796 { 5797 std::cout << " <MEMC " << name() 5798 << " CLEANUP_IVT_CLEAR> Clear entry in IVT:" 5799 << " IVT_index = " << r_cleanup_index.read() << std::endl; 5800 } 5801 #endif 5802 break; 5803 } 5804 /////////////////////// 5805 case CLEANUP_WRITE_RSP: // response to a previous write on the direct network 5806 // wait if pending request to the TGT_RSP FSM 5807 { 5808 if (r_cleanup_to_tgt_rsp_req.read()) break; 5809 5810 // no pending request 5811 r_cleanup_to_tgt_rsp_req = true; 5812 r_cleanup_to_tgt_rsp_srcid = r_cleanup_write_srcid.read(); 5813 r_cleanup_to_tgt_rsp_trdid = r_cleanup_write_trdid.read(); 5814 r_cleanup_to_tgt_rsp_pktid = r_cleanup_write_pktid.read(); 5815 r_cleanup_fsm = CLEANUP_SEND_CLACK; 5229 5816 5230 5817 #if DEBUG_MEMC_CLEANUP 5231 if (m_debug)5232 std::cout << " <MEMC " << name()5233 << " CLEANUP_DIR_WRITE> Update directory:"5234 << std::hex << " address = " << r_cleanup_nline.read() * m_words * 45235 << " / dir_id = " << entry.owner.srcid5236 << " / dir_ins = " << entry.owner.inst5237 << " / count = " << entry.count5238 << " / is_cnt = " << entry.is_cnt << std::endl;5239 #endif 5240 5241 break;5242 }5243 //////////////////////5244 case CLEANUP_HEAP_REQ: // get the lock to the HEAP directory5245 {5246 if (r_alloc_heap_fsm.read() != ALLOC_HEAP_CLEANUP) break;5247 5248 r_cleanup_fsm = CLEANUP_HEAP_LOCK;5818 if (m_debug) 5819 { 5820 std::cout << " <MEMC " << name() << " CLEANUP_WRITE_RSP>" 5821 << " Send a response to a previous write request: " 5822 << " rsrcid = " << std::hex << r_cleanup_write_srcid.read() 5823 << " / rtrdid = " << r_cleanup_write_trdid.read() 5824 << " / rpktid = " << r_cleanup_write_pktid.read() << std::endl; 5825 } 5826 #endif 5827 break; 5828 } 5829 //////////////////////// 5830 case CLEANUP_SEND_CLACK: // acknowledgement to a cleanup command 5831 // on the coherence CLACK network. 5832 { 5833 if (not p_dspin_clack.read) break; 5834 5835 r_cleanup_fsm = CLEANUP_IDLE; 5249 5836 5250 5837 #if DEBUG_MEMC_CLEANUP 5251 if (m_debug) 5252 std::cout << " <MEMC " << name() 5253 << " CLEANUP_HEAP_REQ> HEAP lock acquired " << std::endl; 5254 #endif 5255 break; 5256 } 5257 ////////////////////// 5258 case CLEANUP_HEAP_LOCK: // two cases are handled in this state : 5259 // 1. the matching copy is directly in the directory 5260 // 2. the matching copy is the first copy in the heap 5261 { 5262 assert( (r_alloc_heap_fsm.read() == ALLOC_HEAP_CLEANUP) and 5263 "MEMC ERROR in CLEANUP_HEAP_LOCK state: bad HEAP allocation"); 5264 5265 size_t way = r_cleanup_way.read(); 5266 size_t set = m_y[(addr_t)(r_cleanup_nline.read() *m_words*4)]; 5267 5268 HeapEntry heap_entry = m_heap.read(r_cleanup_ptr.read()); 5269 bool last = (heap_entry.next == r_cleanup_ptr.read()); 5270 5271 // match_dir computation 5272 bool match_dir_srcid = (r_cleanup_copy.read() == r_cleanup_srcid.read()); 5273 bool match_dir_inst = (r_cleanup_copy_inst.read() == r_cleanup_inst.read()); 5274 bool match_dir = match_dir_srcid and match_dir_inst; 5275 5276 // match_heap computation 5277 bool match_heap_srcid = (heap_entry.owner.srcid == r_cleanup_srcid.read()); 5278 bool match_heap_inst = (heap_entry.owner.inst == r_cleanup_inst.read()); 5279 bool match_heap = match_heap_srcid and match_heap_inst; 5280 5281 r_cleanup_prev_ptr = r_cleanup_ptr.read(); 5282 r_cleanup_prev_srcid = heap_entry.owner.srcid; 5283 r_cleanup_prev_inst = heap_entry.owner.inst; 5284 5285 assert( (not last or match_dir or match_heap) and 5286 "MEMC ERROR in CLEANUP_HEAP_LOCK state: hit but no copy found"); 5287 5288 assert( (not match_dir or not match_heap) and 5289 "MEMC ERROR in CLEANUP_HEAP_LOCK state: two matching copies found"); 5290 5291 DirectoryEntry dir_entry; 5292 dir_entry.valid = true; 5293 dir_entry.is_cnt = r_cleanup_is_cnt.read(); 5294 dir_entry.dirty = r_cleanup_dirty.read(); 5295 dir_entry.tag = r_cleanup_tag.read(); 5296 dir_entry.lock = r_cleanup_lock.read(); 5297 dir_entry.count = r_cleanup_count.read()-1; 5298 5299 // the matching copy is registered in the directory and 5300 // it must be replaced by the first copy registered in 5301 // the heap. The corresponding entry must be freed 5302 if (match_dir) 5303 { 5304 dir_entry.ptr = heap_entry.next; 5305 dir_entry.owner.srcid = heap_entry.owner.srcid; 5306 dir_entry.owner.inst = heap_entry.owner.inst; 5307 r_cleanup_next_ptr = r_cleanup_ptr.read(); 5308 r_cleanup_fsm = CLEANUP_HEAP_FREE; 5309 } 5310 5311 // the matching copy is the first copy in the heap 5312 // It must be freed and the copy registered in directory 5313 // must point to the next copy in heap 5314 else if (match_heap) 5315 { 5316 dir_entry.ptr = heap_entry.next; 5317 dir_entry.owner.srcid = r_cleanup_copy.read(); 5318 dir_entry.owner.inst = r_cleanup_copy_inst.read(); 5319 r_cleanup_next_ptr = r_cleanup_ptr.read(); 5320 r_cleanup_fsm = CLEANUP_HEAP_FREE; 5321 } 5322 5323 // The matching copy is in the heap, but is not the first copy 5324 // The directory entry must be modified to decrement count 5325 else 5326 { 5327 dir_entry.ptr = r_cleanup_ptr.read(); 5328 dir_entry.owner.srcid = r_cleanup_copy.read(); 5329 dir_entry.owner.inst = r_cleanup_copy_inst.read(); 5330 r_cleanup_next_ptr = heap_entry.next; 5331 r_cleanup_fsm = CLEANUP_HEAP_SEARCH; 5332 } 5333 5334 m_cache_directory.write(set,way,dir_entry); 5335 5336 #if DEBUG_MEMC_CLEANUP 5337 if (m_debug) 5338 std::cout << " <MEMC " << name() 5339 << " CLEANUP_HEAP_LOCK> Checks matching:" 5340 << " address = " << r_cleanup_nline.read() * m_words * 4 5341 << " / dir_id = " << r_cleanup_copy.read() 5342 << " / dir_ins = " << r_cleanup_copy_inst.read() 5343 << " / heap_id = " << heap_entry.owner.srcid 5344 << " / heap_ins = " << heap_entry.owner.inst 5345 << " / search_id = " << r_cleanup_srcid.read() 5346 << " / search_ins = " << r_cleanup_inst.read() << std::endl; 5347 #endif 5348 break; 5349 } 5350 //////////////////////// 5351 case CLEANUP_HEAP_SEARCH: // This state is handling the case where the copy 5352 // is in the heap, but not the first in linked list 5353 { 5354 assert( (r_alloc_heap_fsm.read() == ALLOC_HEAP_CLEANUP) and 5355 "MEMC ERROR in CLEANUP_HEAP_LOCK state: bad HEAP allocation"); 5356 5357 HeapEntry heap_entry = m_heap.read(r_cleanup_next_ptr.read()); 5358 5359 bool last = (heap_entry.next == r_cleanup_next_ptr.read()); 5360 bool match_heap_srcid = (heap_entry.owner.srcid == r_cleanup_srcid.read()); 5361 bool match_heap_inst = (heap_entry.owner.inst == r_cleanup_inst.read()); 5362 bool match_heap = match_heap_srcid and match_heap_inst; 5363 5364 assert( (not last or match_heap) and 5365 "MEMC ERROR in CLEANUP_HEAP_SEARCH state: no copy found"); 5366 5367 // the matching copy must be removed 5368 if (match_heap) 5369 { 5370 // re-use ressources 5371 r_cleanup_ptr = heap_entry.next; 5372 r_cleanup_fsm = CLEANUP_HEAP_CLEAN; 5373 } 5374 // test the next in the linked list 5375 else 5376 { 5377 r_cleanup_prev_ptr = r_cleanup_next_ptr.read(); 5378 r_cleanup_prev_srcid = heap_entry.owner.srcid; 5379 r_cleanup_prev_inst = heap_entry.owner.inst; 5380 r_cleanup_next_ptr = heap_entry.next; 5381 r_cleanup_fsm = CLEANUP_HEAP_SEARCH; 5382 } 5383 5384 #if DEBUG_MEMC_CLEANUP 5385 if (m_debug) 5386 { 5387 if (not match_heap) 5388 { 5389 std::cout 5390 << " <MEMC " << name() 5391 << " CLEANUP_HEAP_SEARCH> Matching copy not found, search next:" 5392 << std::endl; 5393 } 5394 else 5395 { 5396 std::cout 5397 << " <MEMC " << name() 5398 << " CLEANUP_HEAP_SEARCH> Matching copy found:" 5399 << std::endl; 5400 } 5401 std::cout 5402 << " address = " << r_cleanup_nline.read() * m_words * 4 5403 << " / heap_id = " << heap_entry.owner.srcid 5404 << " / heap_ins = " << heap_entry.owner.inst 5405 << " / search_id = " << r_cleanup_srcid.read() 5406 << " / search_ins = " << r_cleanup_inst.read() 5407 << " / last = " << last 5408 << std::endl; 5409 } 5410 #endif 5411 break; 5412 } 5413 //////////////////////// 5414 case CLEANUP_HEAP_CLEAN: // remove a copy in the linked list 5415 { 5416 assert( (r_alloc_heap_fsm.read() == ALLOC_HEAP_CLEANUP) and 5417 "MEMC ERROR in CLEANUP_HEAP_LOCK state: bad HEAP allocation"); 5418 5419 HeapEntry heap_entry; 5420 heap_entry.owner.srcid = r_cleanup_prev_srcid.read(); 5421 heap_entry.owner.inst = r_cleanup_prev_inst.read(); 5422 bool last = (r_cleanup_next_ptr.read() == r_cleanup_ptr.read()); 5423 5424 if (last) // this is the last entry of the list of copies 5425 { 5426 heap_entry.next = r_cleanup_prev_ptr.read(); 5427 } 5428 else // this is not the last entry 5429 { 5430 heap_entry.next = r_cleanup_ptr.read(); 5431 } 5432 5433 m_heap.write(r_cleanup_prev_ptr.read(), heap_entry); 5434 5435 r_cleanup_fsm = CLEANUP_HEAP_FREE; 5436 5437 #if DEBUG_MEMC_CLEANUP 5438 if (m_debug) 5439 std::cout << " <MEMC " << name() << " CLEANUP_HEAP_SEARCH>" 5440 << " Remove the copy in the linked list" << std::endl; 5441 #endif 5442 break; 5443 } 5444 /////////////////////// 5445 case CLEANUP_HEAP_FREE: // The heap entry pointed by r_cleanup_next_ptr is freed 5446 // and becomes the head of the list of free entries 5447 { 5448 assert( (r_alloc_heap_fsm.read() == ALLOC_HEAP_CLEANUP) and 5449 "MEMC ERROR in CLEANUP_HEAP_LOCK state: bad HEAP allocation"); 5450 5451 HeapEntry heap_entry; 5452 heap_entry.owner.srcid = 0; 5453 heap_entry.owner.inst = false; 5454 5455 if (m_heap.is_full()) 5456 { 5457 heap_entry.next = r_cleanup_next_ptr.read(); 5458 } 5459 else 5460 { 5461 heap_entry.next = m_heap.next_free_ptr(); 5462 } 5463 5464 m_heap.write(r_cleanup_next_ptr.read(),heap_entry); 5465 m_heap.write_free_ptr(r_cleanup_next_ptr.read()); 5466 m_heap.unset_full(); 5467 5468 r_cleanup_fsm = CLEANUP_SEND_CLACK; 5469 5470 #if DEBUG_MEMC_CLEANUP 5471 if (m_debug) 5472 std::cout << " <MEMC " << name() << " CLEANUP_HEAP_FREE>" 5473 << " Update the list of free entries" << std::endl; 5474 #endif 5475 break; 5476 } 5477 ////////////////////// 5478 case CLEANUP_IVT_LOCK: // get the lock protecting the IVT to search a pending 5479 // invalidate transaction matching the cleanup 5480 { 5481 if (r_alloc_ivt_fsm.read() != ALLOC_IVT_CLEANUP) break; 5482 5483 size_t index = 0; 5484 bool match_inval; 5485 5486 match_inval = m_ivt.search_inval(r_cleanup_nline.read(), index); 5487 5488 if (not match_inval ) // no pending inval in IVT 5489 { 5490 r_cleanup_fsm = CLEANUP_SEND_CLACK; 5491 5492 #if DEBUG_MEMC_CLEANUP 5493 if (m_debug) 5494 std::cout << " <MEMC " << name() << " CLEANUP_IVT_LOCK>" 5495 << " Unexpected cleanup with no corresponding IVT entry:" 5496 << " address = " << std::hex << (r_cleanup_nline.read()*4*m_words) << std::endl; 5497 #endif 5498 } 5499 else // pending inval in IVT 5500 { 5501 r_cleanup_write_srcid = m_ivt.srcid(index); 5502 r_cleanup_write_trdid = m_ivt.trdid(index); 5503 r_cleanup_write_pktid = m_ivt.pktid(index); 5504 r_cleanup_need_rsp = m_ivt.need_rsp(index); 5505 r_cleanup_need_ack = m_ivt.need_ack(index); 5506 r_cleanup_index = index; 5507 r_cleanup_fsm = CLEANUP_IVT_DECREMENT; 5508 5509 #if DEBUG_MEMC_CLEANUP 5510 if (m_debug) 5511 std::cout << " <MEMC " << name() << " CLEANUP_IVT_LOCK>" 5512 << " Cleanup matching pending invalidate transaction on IVT:" 5513 << " address = " << std::hex << (r_cleanup_nline.read()*m_words*4) 5514 << " / ivt_entry = " << index << std::endl; 5515 #endif 5516 } 5517 break; 5518 } 5519 /////////////////////////// 5520 case CLEANUP_IVT_DECREMENT: // decrement response counter in IVT matching entry 5521 // and test if last 5522 { 5523 assert( (r_alloc_ivt_fsm.read() == ALLOC_IVT_CLEANUP) and 5524 "MEMC ERROR in CLEANUP_IVT_DECREMENT state: Bad IVT allocation"); 5525 5526 size_t count = 0; 5527 m_ivt.decrement(r_cleanup_index.read(), count); 5528 5529 if (count == 0) r_cleanup_fsm = CLEANUP_IVT_CLEAR; 5530 else r_cleanup_fsm = CLEANUP_SEND_CLACK ; 5531 5532 #if DEBUG_MEMC_CLEANUP 5533 if (m_debug) 5534 std::cout << " <MEMC " << name() << " CLEANUP_IVT_DECREMENT>" 5535 << " Decrement response counter in IVT:" 5536 << " IVT_index = " << r_cleanup_index.read() 5537 << " / rsp_count = " << count << std::endl; 5538 #endif 5539 break; 5540 } 5541 /////////////////////// 5542 case CLEANUP_IVT_CLEAR: // Clear IVT entry 5543 // Acknowledge CONFIG FSM if required 5544 { 5545 assert( (r_alloc_ivt_fsm.read() == ALLOC_IVT_CLEANUP) and 5546 "MEMC ERROR in CLEANUP_IVT_CLEAR state : bad IVT allocation"); 5547 5548 m_ivt.clear(r_cleanup_index.read()); 5549 5550 if (r_cleanup_need_ack.read()) 5551 { 5552 assert( (r_config_rsp_lines.read() > 0) and 5553 "MEMC ERROR in CLEANUP_IVT_CLEAR state"); 5554 5555 config_rsp_lines_cleanup_decr = true; 5556 } 5557 5558 if (r_cleanup_need_rsp.read()) r_cleanup_fsm = CLEANUP_WRITE_RSP; 5559 else r_cleanup_fsm = CLEANUP_SEND_CLACK; 5560 5561 #if DEBUG_MEMC_CLEANUP 5562 if (m_debug) 5563 std::cout << " <MEMC " << name() 5564 << " CLEANUP_IVT_CLEAR> Clear entry in IVT:" 5565 << " IVT_index = " << r_cleanup_index.read() << std::endl; 5566 #endif 5567 break; 5568 } 5569 /////////////////////// 5570 case CLEANUP_WRITE_RSP: // response to a previous write on the direct network 5571 // wait if pending request to the TGT_RSP FSM 5572 { 5573 if (r_cleanup_to_tgt_rsp_req.read()) break; 5574 5575 // no pending request 5576 r_cleanup_to_tgt_rsp_req = true; 5577 r_cleanup_to_tgt_rsp_srcid = r_cleanup_write_srcid.read(); 5578 r_cleanup_to_tgt_rsp_trdid = r_cleanup_write_trdid.read(); 5579 r_cleanup_to_tgt_rsp_pktid = r_cleanup_write_pktid.read(); 5580 r_cleanup_fsm = CLEANUP_SEND_CLACK; 5581 5582 #if DEBUG_MEMC_CLEANUP 5583 if (m_debug) 5584 std::cout << " <MEMC " << name() << " CLEANUP_WRITE_RSP>" 5585 << " Send a response to a previous write request: " 5586 << " rsrcid = " << std::hex << r_cleanup_write_srcid.read() 5587 << " / rtrdid = " << r_cleanup_write_trdid.read() 5588 << " / rpktid = " << r_cleanup_write_pktid.read() << std::endl; 5589 #endif 5590 break; 5591 } 5592 //////////////////////// 5593 case CLEANUP_SEND_CLACK: // acknowledgement to a cleanup command 5594 // on the coherence CLACK network. 5595 { 5596 if (not p_dspin_clack.read) break; 5597 5598 r_cleanup_fsm = CLEANUP_IDLE; 5599 5600 #if DEBUG_MEMC_CLEANUP 5601 if (m_debug) 5602 std::cout << " <MEMC " << name() 5603 << " CLEANUP_SEND_CLACK> Send the response to a cleanup request:" 5604 << " address = " << std::hex << r_cleanup_nline.read()*m_words*4 5605 << " / way = " << std::dec << r_cleanup_way.read() 5606 << " / srcid = " << std::hex << r_cleanup_srcid.read() 5607 << std::endl; 5608 #endif 5609 break; 5610 } 5838 if (m_debug) 5839 { 5840 std::cout << " <MEMC " << name() 5841 << " CLEANUP_SEND_CLACK> Send the response to a cleanup request:" 5842 << " address = " << std::hex << r_cleanup_nline.read() * m_words * 4 5843 << " / way = " << std::dec << r_cleanup_way.read() 5844 << " / srcid = " << std::hex << r_cleanup_srcid.read() 5845 << std::endl; 5846 } 5847 #endif 5848 break; 5849 } 5611 5850 } // end switch cleanup fsm 5612 5851 … … 5637 5876 //std::cout << std::endl << "cas_fsm" << std::endl; 5638 5877 5639 switch (r_cas_fsm.read())5878 switch (r_cas_fsm.read()) 5640 5879 { 5641 5880 //////////// 5642 5881 case CAS_IDLE: // fill the local rdata buffers 5643 { 5644 if (m_cmd_cas_addr_fifo.rok()) 5645 { 5646 5647 #if DEBUG_MEMC_CAS 5648 if (m_debug) 5649 std::cout << " <MEMC " << name() << " CAS_IDLE> CAS command: " << std::hex 5650 << " srcid = " << std::dec << m_cmd_cas_srcid_fifo.read() 5651 << " addr = " << std::hex << m_cmd_cas_addr_fifo.read() 5652 << " wdata = " << m_cmd_cas_wdata_fifo.read() 5653 << " eop = " << std::dec << m_cmd_cas_eop_fifo.read() 5654 << " cpt = " << std::dec << r_cas_cpt.read() << std::endl; 5655 #endif 5656 if (m_cmd_cas_eop_fifo.read()) 5657 { 5658 r_cas_fsm = CAS_DIR_REQ; 5659 } 5660 else // we keep the last word in the FIFO 5661 { 5662 cmd_cas_fifo_get = true; 5663 } 5664 5665 // We fill the two buffers 5666 if (r_cas_cpt.read() < 2) // 32 bits access 5667 r_cas_rdata[r_cas_cpt.read()] = m_cmd_cas_wdata_fifo.read(); 5668 5669 if ((r_cas_cpt.read() == 1) and m_cmd_cas_eop_fifo.read()) 5670 r_cas_wdata = m_cmd_cas_wdata_fifo.read(); 5671 5672 assert( (r_cas_cpt.read() <= 3) and // no more than 4 flits... 5673 "MEMC ERROR in CAS_IDLE state: illegal CAS command"); 5674 5675 if (r_cas_cpt.read() ==2) 5676 r_cas_wdata = m_cmd_cas_wdata_fifo.read(); 5677 5678 r_cas_cpt = r_cas_cpt.read() +1; 5679 } 5680 break; 5681 } 5682 ///////////////// 5683 case CAS_DIR_REQ: 5684 { 5685 if (r_alloc_dir_fsm.read() == ALLOC_DIR_CAS) 5686 { 5687 r_cas_fsm = CAS_DIR_LOCK; 5688 } 5882 { 5883 if (m_cmd_cas_addr_fifo.rok()) 5884 { 5689 5885 5690 5886 #if DEBUG_MEMC_CAS 5691 5887 if (m_debug) 5692 std::cout << " <MEMC " << name() << " CAS_DIR_REQ> Requesting DIR lock " << std::endl; 5693 #endif 5694 break; 5695 } 5696 ///////////////// 5888 { 5889 std::cout << " <MEMC " << name() << " CAS_IDLE> CAS command: " << std::hex 5890 << " srcid = " << std::dec << m_cmd_cas_srcid_fifo.read() 5891 << " addr = " << std::hex << m_cmd_cas_addr_fifo.read() 5892 << " wdata = " << m_cmd_cas_wdata_fifo.read() 5893 << " eop = " << std::dec << m_cmd_cas_eop_fifo.read() 5894 << " cpt = " << std::dec << r_cas_cpt.read() << std::endl; 5895 } 5896 #endif 5897 if (m_cmd_cas_eop_fifo.read()) 5898 { 5899 r_cas_fsm = CAS_DIR_REQ; 5900 } 5901 else // we keep the last word in the FIFO 5902 { 5903 cmd_cas_fifo_get = true; 5904 } 5905 5906 // We fill the two buffers 5907 if (r_cas_cpt.read() < 2) // 32 bits access 5908 { 5909 r_cas_rdata[r_cas_cpt.read()] = m_cmd_cas_wdata_fifo.read(); 5910 } 5911 5912 if ((r_cas_cpt.read() == 1) and m_cmd_cas_eop_fifo.read()) 5913 { 5914 r_cas_wdata = m_cmd_cas_wdata_fifo.read(); 5915 } 5916 5917 assert((r_cas_cpt.read() <= 3) and // no more than 4 flits... 5918 "MEMC ERROR in CAS_IDLE state: illegal CAS command"); 5919 5920 if (r_cas_cpt.read() == 2) 5921 { 5922 r_cas_wdata = m_cmd_cas_wdata_fifo.read(); 5923 } 5924 5925 r_cas_cpt = r_cas_cpt.read() + 1; 5926 } 5927 break; 5928 } 5929 ///////////////// 5930 case CAS_DIR_REQ: 5931 { 5932 if (r_alloc_dir_fsm.read() == ALLOC_DIR_CAS) 5933 { 5934 r_cas_fsm = CAS_DIR_LOCK; 5935 } 5936 5937 #if DEBUG_MEMC_CAS 5938 if (m_debug) 5939 { 5940 std::cout << " <MEMC " << name() << " CAS_DIR_REQ> Requesting DIR lock " << std::endl; 5941 } 5942 #endif 5943 break; 5944 } 5945 ///////////////// 5697 5946 case CAS_DIR_LOCK: // Read the directory 5698 {5699 assert((r_alloc_dir_fsm.read() == ALLOC_DIR_CAS) and5700 "MEMC ERROR in CAS_DIR_LOCK: Bad DIR allocation");5701 5702 size_t way = 0;5703 DirectoryEntry entry(m_cache_directory.read(m_cmd_cas_addr_fifo.read(), way));5704 5705 r_cas_is_cnt= entry.is_cnt;5706 r_cas_dirty= entry.dirty;5707 r_cas_tag= entry.tag;5708 r_cas_way= way;5709 r_cas_copy= entry.owner.srcid;5710 r_cas_copy_inst= entry.owner.inst;5711 r_cas_ptr= entry.ptr;5712 r_cas_count= entry.count;5713 5714 if (entry.valid) r_cas_fsm = CAS_DIR_HIT_READ;5715 elser_cas_fsm = CAS_MISS_TRT_LOCK;5947 { 5948 assert((r_alloc_dir_fsm.read() == ALLOC_DIR_CAS) and 5949 "MEMC ERROR in CAS_DIR_LOCK: Bad DIR allocation"); 5950 5951 size_t way = 0; 5952 DirectoryEntry entry(m_cache_directory.read(m_cmd_cas_addr_fifo.read(), way)); 5953 5954 r_cas_is_cnt = entry.is_cnt; 5955 r_cas_dirty = entry.dirty; 5956 r_cas_tag = entry.tag; 5957 r_cas_way = way; 5958 r_cas_copy = entry.owner.srcid; 5959 r_cas_copy_inst = entry.owner.inst; 5960 r_cas_ptr = entry.ptr; 5961 r_cas_count = entry.count; 5962 5963 if (entry.valid) r_cas_fsm = CAS_DIR_HIT_READ; 5964 else r_cas_fsm = CAS_MISS_TRT_LOCK; 5716 5965 5717 5966 #if DEBUG_MEMC_CAS 5718 if (m_debug) 5719 std::cout << " <MEMC " << name() << " CAS_DIR_LOCK> Directory acces" 5720 << " / address = " << std::hex << m_cmd_cas_addr_fifo.read() 5721 << " / hit = " << std::dec << entry.valid 5722 << " / count = " << entry.count 5723 << " / is_cnt = " << entry.is_cnt << std::endl; 5724 #endif 5725 5726 break; 5727 } 5728 ///////////////////// 5967 if (m_debug) 5968 { 5969 std::cout << " <MEMC " << name() << " CAS_DIR_LOCK> Directory acces" 5970 << " / address = " << std::hex << m_cmd_cas_addr_fifo.read() 5971 << " / hit = " << std::dec << entry.valid 5972 << " / count = " << entry.count 5973 << " / is_cnt = " << entry.is_cnt << std::endl; 5974 } 5975 #endif 5976 5977 break; 5978 } 5979 ///////////////////// 5729 5980 case CAS_DIR_HIT_READ: // update directory for lock and dirty bit 5730 // and check data change in cache5731 {5732 assert((r_alloc_dir_fsm.read() == ALLOC_DIR_CAS) and5733 "MEMC ERROR in CAS_DIR_HIT_READ: Bad DIR allocation");5734 5735 size_t way= r_cas_way.read();5736 size_t set= m_y[(addr_t)(m_cmd_cas_addr_fifo.read())];5737 5738 // update directory (lock & dirty bits)5739 DirectoryEntry entry;5740 entry.valid= true;5741 entry.is_cnt= r_cas_is_cnt.read();5742 entry.dirty= true;5743 entry.lock= true;5744 entry.tag= r_cas_tag.read();5745 entry.owner.srcid= r_cas_copy.read();5746 entry.owner.inst= r_cas_copy_inst.read();5747 entry.count= r_cas_count.read();5748 entry.ptr= r_cas_ptr.read();5749 5750 m_cache_directory.write(set, way, entry);5751 5752 // Store data from cache in buffer to do the comparison in next state5753 m_cache_data.read_line(way, set, r_cas_data);5754 5755 r_cas_fsm = CAS_DIR_HIT_COMPARE;5981 // and check data change in cache 5982 { 5983 assert((r_alloc_dir_fsm.read() == ALLOC_DIR_CAS) and 5984 "MEMC ERROR in CAS_DIR_HIT_READ: Bad DIR allocation"); 5985 5986 size_t way = r_cas_way.read(); 5987 size_t set = m_y[(addr_t)(m_cmd_cas_addr_fifo.read())]; 5988 5989 // update directory (lock & dirty bits) 5990 DirectoryEntry entry; 5991 entry.valid = true; 5992 entry.is_cnt = r_cas_is_cnt.read(); 5993 entry.dirty = true; 5994 entry.lock = true; 5995 entry.tag = r_cas_tag.read(); 5996 entry.owner.srcid = r_cas_copy.read(); 5997 entry.owner.inst = r_cas_copy_inst.read(); 5998 entry.count = r_cas_count.read(); 5999 entry.ptr = r_cas_ptr.read(); 6000 6001 m_cache_directory.write(set, way, entry); 6002 6003 // Store data from cache in buffer to do the comparison in next state 6004 m_cache_data.read_line(way, set, r_cas_data); 6005 6006 r_cas_fsm = CAS_DIR_HIT_COMPARE; 5756 6007 5757 6008 #if DEBUG_MEMC_CAS 5758 if (m_debug) 5759 std::cout << " <MEMC " << name() << " CAS_DIR_HIT_READ> Read data from " 5760 << " cache and store it in buffer" << std::endl; 5761 #endif 5762 break; 5763 } 5764 //////////////////////// 6009 if (m_debug) 6010 { 6011 std::cout << " <MEMC " << name() << " CAS_DIR_HIT_READ> Read data from " 6012 << " cache and store it in buffer" << std::endl; 6013 } 6014 #endif 6015 break; 6016 } 6017 //////////////////////// 5765 6018 case CAS_DIR_HIT_COMPARE: 5766 {5767 size_t word = m_x[(addr_t)(m_cmd_cas_addr_fifo.read())];5768 5769 // check data change5770 bool ok = (r_cas_rdata[0].read() == r_cas_data[word].read());5771 5772 if (r_cas_cpt.read() == 4) // 64 bits CAS5773 ok &= (r_cas_rdata[1] == r_cas_data[word+1]);5774 5775 // to avoid livelock, force the atomic access to fail pseudo-randomly5776 bool forced_fail = ((r_cas_lfsr % (64) == 0) and RANDOMIZE_CAS);5777 r_cas_lfsr = (r_cas_lfsr >> 1) ^ ((- (r_cas_lfsr & 1)) & 0xd0000001);5778 5779 if (ok and not forced_fail) r_cas_fsm = CAS_DIR_HIT_WRITE;5780 else r_cas_fsm = CAS_RSP_FAIL;6019 { 6020 size_t word = m_x[(addr_t)(m_cmd_cas_addr_fifo.read())]; 6021 6022 // check data change 6023 bool ok = (r_cas_rdata[0].read() == r_cas_data[word].read()); 6024 6025 if (r_cas_cpt.read() == 4) // 64 bits CAS 6026 ok &= (r_cas_rdata[1] == r_cas_data[word+1]); 6027 6028 // to avoid livelock, force the atomic access to fail pseudo-randomly 6029 bool forced_fail = ((r_cas_lfsr % (64) == 0) and RANDOMIZE_CAS); 6030 r_cas_lfsr = (r_cas_lfsr >> 1) ^ ((- (r_cas_lfsr & 1)) & 0xd0000001); 6031 6032 if (ok and not forced_fail) r_cas_fsm = CAS_DIR_HIT_WRITE; 6033 else r_cas_fsm = CAS_RSP_FAIL; 5781 6034 5782 6035 #if DEBUG_MEMC_CAS 5783 if (m_debug) 5784 std::cout << " <MEMC " << name() << " CAS_DIR_HIT_COMPARE> Compare old and new data" 5785 << " / expected value = " << std::hex << r_cas_rdata[0].read() 5786 << " / actual value = " << std::hex << r_cas_data[word].read() 5787 << " / forced_fail = " << std::dec << forced_fail << std::endl; 5788 #endif 5789 break; 5790 } 5791 ////////////////////// 6036 if (m_debug) 6037 { 6038 std::cout << " <MEMC " << name() << " CAS_DIR_HIT_COMPARE> Compare old and new data" 6039 << " / expected value = " << std::hex << r_cas_rdata[0].read() 6040 << " / actual value = " << std::hex << r_cas_data[word].read() 6041 << " / forced_fail = " << std::dec << forced_fail << std::endl; 6042 } 6043 #endif 6044 break; 6045 } 6046 ////////////////////// 5792 6047 case CAS_DIR_HIT_WRITE: // test if a CC transaction is required 5793 // write data in cache if no CC request 5794 { 5795 assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_CAS) and 5796 "MEMC ERROR in CAS_DIR_HIT_WRITE: Bad DIR allocation"); 5797 5798 // The CAS is a success => sw access to the llsc_global_table 5799 m_llsc_table.sw(m_cmd_cas_addr_fifo.read(), m_cmd_cas_addr_fifo.read()); 5800 5801 // test coherence request 5802 if (r_cas_count.read()) // replicated line 5803 { 5804 if (r_cas_is_cnt.read()) 5805 { 5806 r_cas_fsm = CAS_BC_TRT_LOCK; // broadcast invalidate required 5807 5808 #if DEBUG_MEMC_CAS 5809 if (m_debug) 5810 std::cout << " <MEMC " << name() << " CAS_DIR_HIT_WRITE>" 5811 << " Broacast Inval required" 5812 << " / copies = " << r_cas_count.read() << std::endl; 5813 #endif 5814 } 5815 else if (not r_cas_to_cc_send_multi_req.read() and 5816 not r_cas_to_cc_send_brdcast_req.read()) 5817 { 5818 r_cas_fsm = CAS_UPT_LOCK; // multi update required 5819 5820 #if DEBUG_MEMC_CAS 5821 if (m_debug) 5822 std::cout << " <MEMC " << name() << " CAS_DIR_HIT_WRITE>" 5823 << " Multi Inval required" 5824 << " / copies = " << r_cas_count.read() << std::endl; 5825 #endif 5826 } 5827 else 5828 { 5829 r_cas_fsm = CAS_WAIT; 5830 5831 #if DEBUG_MEMC_CAS 5832 if (m_debug) 5833 std::cout << " <MEMC " << name() << " CAS_DIR_HIT_WRITE>" 5834 << " CC_SEND FSM busy: release all locks and retry" << std::endl; 5835 #endif 5836 } 5837 } 5838 else // no copies 5839 { 5840 size_t way = r_cas_way.read(); 5841 size_t set = m_y[(addr_t)(m_cmd_cas_addr_fifo.read())]; 5842 size_t word = m_x[(addr_t)(m_cmd_cas_addr_fifo.read())]; 5843 5844 // cache update 5845 m_cache_data.write(way, set, word, r_cas_wdata.read()); 5846 if (r_cas_cpt.read() == 4) 5847 m_cache_data.write(way, set, word+1, m_cmd_cas_wdata_fifo.read()); 5848 5849 r_cas_fsm = CAS_RSP_SUCCESS; 5850 5851 #if DEBUG_MEMC_CAS 5852 if (m_debug) 5853 std::cout << " <MEMC " << name() << " CAS_DIR_HIT_WRITE> Update cache:" 5854 << " way = " << std::dec << way 5855 << " / set = " << set 5856 << " / word = " << word 5857 << " / value = " << r_cas_wdata.read() 5858 << " / count = " << r_cas_count.read() 5859 << " / global_llsc_table access" << std::endl; 5860 #endif 5861 } 5862 break; 5863 } 5864 ///////////////// 5865 case CAS_UPT_LOCK: // try to register the transaction in UPT 5866 // and write data in cache if successful registration 5867 // releases locks to retry later if UPT full 5868 { 5869 if (r_alloc_upt_fsm.read() == ALLOC_UPT_CAS) 5870 { 5871 bool wok = false; 5872 size_t index = 0; 5873 size_t srcid = m_cmd_cas_srcid_fifo.read(); 5874 size_t trdid = m_cmd_cas_trdid_fifo.read(); 5875 size_t pktid = m_cmd_cas_pktid_fifo.read(); 5876 addr_t nline = m_nline[(addr_t)(m_cmd_cas_addr_fifo.read())]; 5877 size_t nb_copies = r_cas_count.read(); 5878 5879 wok = m_upt.set( true, // it's an update transaction 5880 false, // it's not a broadcast 5881 true, // response required 5882 false, // no acknowledge required 5883 srcid, 5884 trdid, 5885 pktid, 5886 nline, 5887 nb_copies, 5888 index); 5889 if (wok) // coherence transaction registered in UPT 5890 { 5891 // cache update 5892 size_t way = r_cas_way.read(); 5893 size_t set = m_y[(addr_t)(m_cmd_cas_addr_fifo.read())]; 5894 size_t word = m_x[(addr_t)(m_cmd_cas_addr_fifo.read())]; 5895 5896 m_cache_data.write(way, set, word, r_cas_wdata.read()); 5897 if (r_cas_cpt.read() ==4) 5898 m_cache_data.write(way, set, word+1, m_cmd_cas_wdata_fifo.read()); 5899 5900 r_cas_upt_index = index; 5901 r_cas_fsm = CAS_UPT_HEAP_LOCK; 5902 } 5903 else // releases the locks protecting UPT and DIR UPT full 5904 { 5905 r_cas_fsm = CAS_WAIT; 5906 } 5907 5908 #if DEBUG_MEMC_CAS 5909 if (m_debug) 5910 std::cout << " <MEMC " << name() 5911 << " CAS_UPT_LOCK> Register multi-update transaction in UPT" 5912 << " / wok = " << wok 5913 << " / address = " << std::hex << nline*m_words*4 5914 << " / count = " << nb_copies << std::endl; 5915 #endif 5916 } 5917 break; 5918 } 5919 ///////////// 5920 case CAS_WAIT: // release all locks and retry from beginning 5921 { 5922 5923 #if DEBUG_MEMC_CAS 5924 if (m_debug) 5925 std::cout << " <MEMC " << name() << " CAS_WAIT> Release all locks" << std::endl; 5926 #endif 5927 r_cas_fsm = CAS_DIR_REQ; 5928 break; 5929 } 5930 ////////////////////// 5931 case CAS_UPT_HEAP_LOCK: // lock the heap 5932 { 5933 if (r_alloc_heap_fsm.read() == ALLOC_HEAP_CAS) 5934 { 6048 // write data in cache if no CC request 6049 { 6050 assert((r_alloc_dir_fsm.read() == ALLOC_DIR_CAS) and 6051 "MEMC ERROR in CAS_DIR_HIT_WRITE: Bad DIR allocation"); 6052 6053 // The CAS is a success => sw access to the llsc_global_table 6054 m_llsc_table.sw(m_cmd_cas_addr_fifo.read(), m_cmd_cas_addr_fifo.read()); 6055 6056 // test coherence request 6057 if (r_cas_count.read()) // replicated line 6058 { 6059 if (r_cas_is_cnt.read()) 6060 { 6061 r_cas_fsm = CAS_BC_TRT_LOCK; // broadcast invalidate required 5935 6062 5936 6063 #if DEBUG_MEMC_CAS 5937 6064 if (m_debug) 5938 6065 { 5939 std::cout << " <MEMC " << name() 5940 << " CAS_UPT_HEAP_LOCK> Get access to the heap" << std::endl; 6066 std::cout << " <MEMC " << name() << " CAS_DIR_HIT_WRITE>" 6067 << " Broacast Inval required" 6068 << " / copies = " << r_cas_count.read() << std::endl; 5941 6069 } 5942 6070 #endif 5943 r_cas_fsm = CAS_UPT_REQ; 5944 } 5945 break; 5946 } 5947 //////////////// 5948 case CAS_UPT_REQ: // send a first update request to CC_SEND FSM 5949 { 5950 assert((r_alloc_heap_fsm.read() == ALLOC_HEAP_CAS) and 5951 "VCI_MEM_CACHE ERROR : bad HEAP allocation"); 5952 5953 if (!r_cas_to_cc_send_multi_req.read() and !r_cas_to_cc_send_brdcast_req.read()) 5954 { 5955 r_cas_to_cc_send_brdcast_req = false; 5956 r_cas_to_cc_send_trdid = r_cas_upt_index.read(); 5957 r_cas_to_cc_send_nline = m_nline[(addr_t)(m_cmd_cas_addr_fifo.read())]; 5958 r_cas_to_cc_send_index = m_x[(addr_t)(m_cmd_cas_addr_fifo.read())]; 5959 r_cas_to_cc_send_wdata = r_cas_wdata.read(); 5960 5961 if (r_cas_cpt.read() == 4) 5962 { 5963 r_cas_to_cc_send_is_long = true; 5964 r_cas_to_cc_send_wdata_high = m_cmd_cas_wdata_fifo.read(); 5965 } 5966 else 5967 { 5968 r_cas_to_cc_send_is_long = false; 5969 r_cas_to_cc_send_wdata_high = 0; 5970 } 5971 5972 // We put the first copy in the fifo 5973 cas_to_cc_send_fifo_put = true; 5974 cas_to_cc_send_fifo_inst = r_cas_copy_inst.read(); 5975 cas_to_cc_send_fifo_srcid = r_cas_copy.read(); 5976 if (r_cas_count.read() == 1) // one single copy 5977 { 5978 r_cas_fsm = CAS_IDLE; // Response will be sent after receiving 5979 // update responses 5980 cmd_cas_fifo_get = true; 5981 r_cas_to_cc_send_multi_req = true; 5982 r_cas_cpt = 0; 5983 } 5984 else // several copies 5985 { 5986 r_cas_fsm = CAS_UPT_NEXT; 5987 } 6071 } 6072 else if (not r_cas_to_cc_send_multi_req.read() and 6073 not r_cas_to_cc_send_brdcast_req.read()) 6074 { 6075 r_cas_fsm = CAS_UPT_LOCK; // multi update required 5988 6076 5989 6077 #if DEBUG_MEMC_CAS 5990 6078 if (m_debug) 5991 6079 { 5992 std::cout << " <MEMC " << name() << " CAS_UPT_REQ> Send the first update request to CC_SEND FSM " 5993 << " / address = " << std::hex << m_cmd_cas_addr_fifo.read() 5994 << " / wdata = " << std::hex << r_cas_wdata.read() 5995 << " / srcid = " << std::dec << r_cas_copy.read() 5996 << " / inst = " << std::dec << r_cas_copy_inst.read() << std::endl; 6080 std::cout << " <MEMC " << name() << " CAS_DIR_HIT_WRITE>" 6081 << " Multi Inval required" 6082 << " / copies = " << r_cas_count.read() << std::endl; 5997 6083 } 5998 6084 #endif 5999 6085 } 6000 break; 6001 } 6002 ///////////////// 6003 case CAS_UPT_NEXT: // send a multi-update request to CC_SEND FSM 6004 { 6005 assert((r_alloc_heap_fsm.read() == ALLOC_HEAP_CAS) 6006 and "VCI_MEM_CACHE ERROR : bad HEAP allocation"); 6007 6008 HeapEntry entry = m_heap.read(r_cas_ptr.read()); 6009 cas_to_cc_send_fifo_srcid = entry.owner.srcid; 6010 cas_to_cc_send_fifo_inst = entry.owner.inst; 6011 cas_to_cc_send_fifo_put = true; 6012 6013 if (m_cas_to_cc_send_inst_fifo.wok()) // request accepted by CC_SEND FSM 6014 { 6015 r_cas_ptr = entry.next; 6016 if (entry.next == r_cas_ptr.read()) // last copy 6086 else 6087 { 6088 r_cas_fsm = CAS_WAIT; 6089 6090 #if DEBUG_MEMC_CAS 6091 if (m_debug) 6017 6092 { 6018 r_cas_to_cc_send_multi_req = true; 6019 r_cas_fsm = CAS_IDLE; // Response will be sent after receiving 6020 // all update responses 6021 cmd_cas_fifo_get = true; 6022 r_cas_cpt = 0; 6093 std::cout << " <MEMC " << name() << " CAS_DIR_HIT_WRITE>" 6094 << " CC_SEND FSM busy: release all locks and retry" << std::endl; 6023 6095 } 6024 } 6096 #endif 6097 } 6098 } 6099 else // no copies 6100 { 6101 size_t way = r_cas_way.read(); 6102 size_t set = m_y[(addr_t) (m_cmd_cas_addr_fifo.read())]; 6103 size_t word = m_x[(addr_t) (m_cmd_cas_addr_fifo.read())]; 6104 6105 // cache update 6106 m_cache_data.write(way, set, word, r_cas_wdata.read()); 6107 if (r_cas_cpt.read() == 4) 6108 { 6109 m_cache_data.write(way, set, word + 1, m_cmd_cas_wdata_fifo.read()); 6110 } 6111 6112 r_cas_fsm = CAS_RSP_SUCCESS; 6025 6113 6026 6114 #if DEBUG_MEMC_CAS 6027 6115 if (m_debug) 6028 6116 { 6029 std::cout << " <MEMC " << name() << " CAS_UPT_NEXT> Send the next update request to CC_SEND FSM " 6117 std::cout << " <MEMC " << name() << " CAS_DIR_HIT_WRITE> Update cache:" 6118 << " way = " << std::dec << way 6119 << " / set = " << set 6120 << " / word = " << word 6121 << " / value = " << r_cas_wdata.read() 6122 << " / count = " << r_cas_count.read() 6123 << " / global_llsc_table access" << std::endl; 6124 } 6125 #endif 6126 } 6127 break; 6128 } 6129 ///////////////// 6130 case CAS_UPT_LOCK: // try to register the transaction in UPT 6131 // and write data in cache if successful registration 6132 // releases locks to retry later if UPT full 6133 { 6134 if (r_alloc_upt_fsm.read() == ALLOC_UPT_CAS) 6135 { 6136 bool wok = false; 6137 size_t index = 0; 6138 size_t srcid = m_cmd_cas_srcid_fifo.read(); 6139 size_t trdid = m_cmd_cas_trdid_fifo.read(); 6140 size_t pktid = m_cmd_cas_pktid_fifo.read(); 6141 addr_t nline = m_nline[(addr_t)(m_cmd_cas_addr_fifo.read())]; 6142 size_t nb_copies = r_cas_count.read(); 6143 6144 wok = m_upt.set(true, // it's an update transaction 6145 false, // it's not a broadcast 6146 true, // response required 6147 false, // no acknowledge required 6148 srcid, 6149 trdid, 6150 pktid, 6151 nline, 6152 nb_copies, 6153 index); 6154 if (wok) // coherence transaction registered in UPT 6155 { 6156 // cache update 6157 size_t way = r_cas_way.read(); 6158 size_t set = m_y[(addr_t) (m_cmd_cas_addr_fifo.read())]; 6159 size_t word = m_x[(addr_t) (m_cmd_cas_addr_fifo.read())]; 6160 6161 m_cache_data.write(way, set, word, r_cas_wdata.read()); 6162 if (r_cas_cpt.read() == 4) 6163 { 6164 m_cache_data.write(way, set, word + 1, m_cmd_cas_wdata_fifo.read()); 6165 } 6166 6167 r_cas_upt_index = index; 6168 r_cas_fsm = CAS_UPT_HEAP_LOCK; 6169 } 6170 else // releases the locks protecting UPT and DIR UPT full 6171 { 6172 r_cas_fsm = CAS_WAIT; 6173 } 6174 6175 #if DEBUG_MEMC_CAS 6176 if (m_debug) 6177 { 6178 std::cout << " <MEMC " << name() 6179 << " CAS_UPT_LOCK> Register multi-update transaction in UPT" 6180 << " / wok = " << wok 6181 << " / address = " << std::hex << nline * m_words * 4 6182 << " / count = " << nb_copies << std::endl; 6183 } 6184 #endif 6185 } 6186 break; 6187 } 6188 ///////////// 6189 case CAS_WAIT: // release all locks and retry from beginning 6190 { 6191 6192 #if DEBUG_MEMC_CAS 6193 if (m_debug) 6194 { 6195 std::cout << " <MEMC " << name() << " CAS_WAIT> Release all locks" << std::endl; 6196 } 6197 #endif 6198 r_cas_fsm = CAS_DIR_REQ; 6199 break; 6200 } 6201 ////////////////////// 6202 case CAS_UPT_HEAP_LOCK: // lock the heap 6203 { 6204 if (r_alloc_heap_fsm.read() == ALLOC_HEAP_CAS) 6205 { 6206 6207 #if DEBUG_MEMC_CAS 6208 if (m_debug) 6209 { 6210 std::cout << " <MEMC " << name() 6211 << " CAS_UPT_HEAP_LOCK> Get access to the heap" << std::endl; 6212 } 6213 #endif 6214 r_cas_fsm = CAS_UPT_REQ; 6215 } 6216 break; 6217 } 6218 //////////////// 6219 case CAS_UPT_REQ: // send a first update request to CC_SEND FSM 6220 { 6221 assert((r_alloc_heap_fsm.read() == ALLOC_HEAP_CAS) and 6222 "VCI_MEM_CACHE ERROR : bad HEAP allocation"); 6223 6224 if (!r_cas_to_cc_send_multi_req.read() and !r_cas_to_cc_send_brdcast_req.read()) 6225 { 6226 r_cas_to_cc_send_brdcast_req = false; 6227 r_cas_to_cc_send_trdid = r_cas_upt_index.read(); 6228 r_cas_to_cc_send_nline = m_nline[(addr_t) (m_cmd_cas_addr_fifo.read())]; 6229 r_cas_to_cc_send_index = m_x[(addr_t) (m_cmd_cas_addr_fifo.read())]; 6230 r_cas_to_cc_send_wdata = r_cas_wdata.read(); 6231 6232 if (r_cas_cpt.read() == 4) 6233 { 6234 r_cas_to_cc_send_is_long = true; 6235 r_cas_to_cc_send_wdata_high = m_cmd_cas_wdata_fifo.read(); 6236 } 6237 else 6238 { 6239 r_cas_to_cc_send_is_long = false; 6240 r_cas_to_cc_send_wdata_high = 0; 6241 } 6242 6243 // We put the first copy in the fifo 6244 cas_to_cc_send_fifo_put = true; 6245 cas_to_cc_send_fifo_inst = r_cas_copy_inst.read(); 6246 cas_to_cc_send_fifo_srcid = r_cas_copy.read(); 6247 if (r_cas_count.read() == 1) // one single copy 6248 { 6249 r_cas_fsm = CAS_IDLE; // Response will be sent after receiving 6250 // update responses 6251 cmd_cas_fifo_get = true; 6252 r_cas_to_cc_send_multi_req = true; 6253 r_cas_cpt = 0; 6254 } 6255 else // several copies 6256 { 6257 r_cas_fsm = CAS_UPT_NEXT; 6258 } 6259 6260 #if DEBUG_MEMC_CAS 6261 if (m_debug) 6262 { 6263 std::cout << " <MEMC " << name() << " CAS_UPT_REQ> Send the first update request to CC_SEND FSM " 6030 6264 << " / address = " << std::hex << m_cmd_cas_addr_fifo.read() 6031 6265 << " / wdata = " << std::hex << r_cas_wdata.read() 6032 << " / srcid = " << std::dec << entry.owner.srcid 6033 << " / inst = " << std::dec << entry.owner.inst << std::endl; 6034 } 6035 #endif 6036 break; 6037 } 6038 ///////////////////// 6039 case CAS_BC_TRT_LOCK: // get TRT lock to check TRT not full 6040 { 6041 assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_CAS) and 6042 "MEMC ERROR in CAS_BC_TRT_LOCK state: Bas DIR allocation"); 6043 6044 if (r_alloc_trt_fsm.read() == ALLOC_TRT_CAS) 6045 { 6046 size_t wok_index = 0; 6047 bool wok = !m_trt.full(wok_index); 6048 if (wok ) 6049 { 6050 r_cas_trt_index = wok_index; 6051 r_cas_fsm = CAS_BC_IVT_LOCK; 6052 } 6053 else 6054 { 6055 r_cas_fsm = CAS_WAIT; 6056 } 6266 << " / srcid = " << std::dec << r_cas_copy.read() 6267 << " / inst = " << std::dec << r_cas_copy_inst.read() << std::endl; 6268 } 6269 #endif 6270 } 6271 break; 6272 } 6273 ///////////////// 6274 case CAS_UPT_NEXT: // send a multi-update request to CC_SEND FSM 6275 { 6276 assert((r_alloc_heap_fsm.read() == ALLOC_HEAP_CAS) 6277 and "VCI_MEM_CACHE ERROR : bad HEAP allocation"); 6278 6279 HeapEntry entry = m_heap.read(r_cas_ptr.read()); 6280 cas_to_cc_send_fifo_srcid = entry.owner.srcid; 6281 cas_to_cc_send_fifo_inst = entry.owner.inst; 6282 cas_to_cc_send_fifo_put = true; 6283 6284 if (m_cas_to_cc_send_inst_fifo.wok()) // request accepted by CC_SEND FSM 6285 { 6286 r_cas_ptr = entry.next; 6287 if (entry.next == r_cas_ptr.read()) // last copy 6288 { 6289 r_cas_to_cc_send_multi_req = true; 6290 r_cas_fsm = CAS_IDLE; // Response will be sent after receiving 6291 // all update responses 6292 cmd_cas_fifo_get = true; 6293 r_cas_cpt = 0; 6294 } 6295 } 6057 6296 6058 6297 #if DEBUG_MEMC_CAS 6059 if (m_debug) 6060 std::cout << " <MEMC " << name() << " CAS_BC_TRT_LOCK> Check TRT" 6061 << " : wok = " << wok << " / index = " << wok_index << std::endl; 6062 #endif 6063 } 6064 break; 6065 } 6066 ///////////////////// 6067 case CAS_BC_IVT_LOCK: // get IVT lock and register BC transaction in IVT 6068 { 6069 assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_CAS) and 6070 "MEMC ERROR in CAS_BC_IVT_LOCK state: Bas DIR allocation"); 6071 6072 assert( (r_alloc_trt_fsm.read() == ALLOC_TRT_CAS) and 6073 "MEMC ERROR in CAS_BC_IVT_LOCK state: Bas TRT allocation"); 6074 6075 if (r_alloc_ivt_fsm.read() == ALLOC_IVT_CAS ) 6076 { 6077 // register broadcast inval transaction in IVT 6078 bool wok = false; 6079 size_t index = 0; 6080 size_t srcid = m_cmd_cas_srcid_fifo.read(); 6081 size_t trdid = m_cmd_cas_trdid_fifo.read(); 6082 size_t pktid = m_cmd_cas_pktid_fifo.read(); 6083 addr_t nline = m_nline[(addr_t)(m_cmd_cas_addr_fifo.read())]; 6084 size_t nb_copies = r_cas_count.read(); 6085 6086 wok = m_ivt.set( false, // it's an inval transaction 6087 true, // it's a broadcast 6088 true, // response required 6089 false, // no acknowledge required 6090 srcid, 6091 trdid, 6092 pktid, 6093 nline, 6094 nb_copies, 6095 index); 6096 #if DEBUG_MEMC_CAS 6097 if (m_debug and wok ) 6098 std::cout << " <MEMC " << name() << " CAS_BC_IVT_LOCK> Register broadcast inval in IVT" 6099 << " / copies = " << r_cas_count.read() << std::endl; 6100 #endif 6101 r_cas_upt_index = index; 6102 if (wok ) r_cas_fsm = CAS_BC_DIR_INVAL; 6103 else r_cas_fsm = CAS_WAIT; 6104 } 6105 break; 6106 } 6107 ////////////////////// 6108 case CAS_BC_DIR_INVAL: // Register PUT transaction in TRT, 6109 // and inval the DIR entry 6110 { 6111 assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_CAS) and 6112 "MEMC ERROR in CAS_BC_DIR_INVAL state: Bad DIR allocation"); 6113 6114 assert( (r_alloc_trt_fsm.read() == ALLOC_TRT_CAS) and 6115 "MEMC ERROR in CAS_BC_DIR_INVAL state: Bad TRT allocation"); 6116 6117 assert( (r_alloc_ivt_fsm.read() == ALLOC_IVT_CAS) and 6118 "MEMC ERROR in CAS_BC_DIR_INVAL state: Bad IVT allocation"); 6119 6120 // set TRT 6121 std::vector<data_t> data_vector; 6122 data_vector.clear(); 6123 size_t word = m_x[(addr_t)(m_cmd_cas_addr_fifo.read())]; 6124 for(size_t i=0; i<m_words; i++) 6125 { 6126 if (i == word) // first modified word 6127 data_vector.push_back( r_cas_wdata.read()); 6128 else if ((i == word+1) and (r_cas_cpt.read() == 4)) // second modified word 6129 data_vector.push_back( m_cmd_cas_wdata_fifo.read()); 6130 else // unmodified words 6131 data_vector.push_back( r_cas_data[i].read()); 6132 } 6133 m_trt.set( r_cas_trt_index.read(), 6134 false, // PUT request 6135 m_nline[(addr_t)(m_cmd_cas_addr_fifo.read())], 6136 0, 6137 0, 6138 0, 6139 false, // not a processor read 6140 0, 6141 0, 6142 std::vector<be_t> (m_words,0), 6143 data_vector ); 6144 6145 // invalidate directory entry 6146 DirectoryEntry entry; 6147 entry.valid = false; 6148 entry.dirty = false; 6149 entry.tag = 0; 6150 entry.is_cnt = false; 6151 entry.lock = false; 6152 entry.count = 0; 6153 entry.owner.srcid = 0; 6154 entry.owner.inst = false; 6155 entry.ptr = 0; 6156 size_t set = m_y[(addr_t)(m_cmd_cas_addr_fifo.read())]; 6157 size_t way = r_cas_way.read(); 6158 6159 m_cache_directory.write(set, way, entry); 6160 6161 r_cas_fsm = CAS_BC_CC_SEND; 6298 if (m_debug) 6299 { 6300 std::cout << " <MEMC " << name() << " CAS_UPT_NEXT> Send the next update request to CC_SEND FSM " 6301 << " / address = " << std::hex << m_cmd_cas_addr_fifo.read() 6302 << " / wdata = " << std::hex << r_cas_wdata.read() 6303 << " / srcid = " << std::dec << entry.owner.srcid 6304 << " / inst = " << std::dec << entry.owner.inst << std::endl; 6305 } 6306 #endif 6307 break; 6308 } 6309 ///////////////////// 6310 case CAS_BC_TRT_LOCK: // get TRT lock to check TRT not full 6311 { 6312 assert((r_alloc_dir_fsm.read() == ALLOC_DIR_CAS) and 6313 "MEMC ERROR in CAS_BC_TRT_LOCK state: Bas DIR allocation"); 6314 6315 if (r_alloc_trt_fsm.read() == ALLOC_TRT_CAS) 6316 { 6317 size_t wok_index = 0; 6318 bool wok = !m_trt.full(wok_index); 6319 if (wok) 6320 { 6321 r_cas_trt_index = wok_index; 6322 r_cas_fsm = CAS_BC_IVT_LOCK; 6323 } 6324 else 6325 { 6326 r_cas_fsm = CAS_WAIT; 6327 } 6162 6328 6163 6329 #if DEBUG_MEMC_CAS 6164 6330 if (m_debug) 6165 std::cout << " <MEMC " << name() << " CAS_BC_DIR_INVAL> Inval DIR & register in TRT:" 6166 << " address = " << m_cmd_cas_addr_fifo.read() << std::endl; 6167 #endif 6168 break; 6169 } 6170 /////////////////// 6331 { 6332 std::cout << " <MEMC " << name() << " CAS_BC_TRT_LOCK> Check TRT" 6333 << " : wok = " << wok << " / index = " << wok_index << std::endl; 6334 } 6335 #endif 6336 } 6337 break; 6338 } 6339 ///////////////////// 6340 case CAS_BC_IVT_LOCK: // get IVT lock and register BC transaction in IVT 6341 { 6342 assert((r_alloc_dir_fsm.read() == ALLOC_DIR_CAS) and 6343 "MEMC ERROR in CAS_BC_IVT_LOCK state: Bas DIR allocation"); 6344 6345 assert((r_alloc_trt_fsm.read() == ALLOC_TRT_CAS) and 6346 "MEMC ERROR in CAS_BC_IVT_LOCK state: Bas TRT allocation"); 6347 6348 if (r_alloc_ivt_fsm.read() == ALLOC_IVT_CAS) 6349 { 6350 // register broadcast inval transaction in IVT 6351 bool wok = false; 6352 size_t index = 0; 6353 size_t srcid = m_cmd_cas_srcid_fifo.read(); 6354 size_t trdid = m_cmd_cas_trdid_fifo.read(); 6355 size_t pktid = m_cmd_cas_pktid_fifo.read(); 6356 addr_t nline = m_nline[(addr_t)(m_cmd_cas_addr_fifo.read())]; 6357 size_t nb_copies = r_cas_count.read(); 6358 6359 wok = m_ivt.set(false, // it's an inval transaction 6360 true, // it's a broadcast 6361 true, // response required 6362 false, // no acknowledge required 6363 srcid, 6364 trdid, 6365 pktid, 6366 nline, 6367 nb_copies, 6368 index); 6369 #if DEBUG_MEMC_CAS 6370 if (m_debug and wok) 6371 { 6372 std::cout << " <MEMC " << name() << " CAS_BC_IVT_LOCK> Register broadcast inval in IVT" 6373 << " / copies = " << r_cas_count.read() << std::endl; 6374 } 6375 #endif 6376 r_cas_upt_index = index; 6377 if (wok) r_cas_fsm = CAS_BC_DIR_INVAL; 6378 else r_cas_fsm = CAS_WAIT; 6379 } 6380 break; 6381 } 6382 ////////////////////// 6383 case CAS_BC_DIR_INVAL: // Register PUT transaction in TRT, 6384 // and inval the DIR entry 6385 { 6386 assert((r_alloc_dir_fsm.read() == ALLOC_DIR_CAS) and 6387 "MEMC ERROR in CAS_BC_DIR_INVAL state: Bad DIR allocation"); 6388 6389 assert((r_alloc_trt_fsm.read() == ALLOC_TRT_CAS) and 6390 "MEMC ERROR in CAS_BC_DIR_INVAL state: Bad TRT allocation"); 6391 6392 assert((r_alloc_ivt_fsm.read() == ALLOC_IVT_CAS) and 6393 "MEMC ERROR in CAS_BC_DIR_INVAL state: Bad IVT allocation"); 6394 6395 // set TRT 6396 std::vector<data_t> data_vector; 6397 data_vector.clear(); 6398 size_t word = m_x[(addr_t)(m_cmd_cas_addr_fifo.read())]; 6399 for (size_t i = 0; i < m_words; i++) 6400 { 6401 if (i == word) 6402 { 6403 // first modified word 6404 data_vector.push_back(r_cas_wdata.read()); 6405 } 6406 else if ((i == word + 1) and (r_cas_cpt.read() == 4)) 6407 { 6408 // second modified word 6409 data_vector.push_back(m_cmd_cas_wdata_fifo.read()); 6410 } 6411 else { 6412 // unmodified words 6413 data_vector.push_back(r_cas_data[i].read()); 6414 } 6415 } 6416 m_trt.set(r_cas_trt_index.read(), 6417 false, // PUT request 6418 m_nline[(addr_t)(m_cmd_cas_addr_fifo.read())], 6419 0, 6420 0, 6421 0, 6422 false, // not a processor read 6423 0, 6424 0, 6425 std::vector<be_t> (m_words,0), 6426 data_vector); 6427 6428 // invalidate directory entry 6429 DirectoryEntry entry; 6430 entry.valid = false; 6431 entry.dirty = false; 6432 entry.tag = 0; 6433 entry.is_cnt = false; 6434 entry.lock = false; 6435 entry.count = 0; 6436 entry.owner.srcid = 0; 6437 entry.owner.inst = false; 6438 entry.ptr = 0; 6439 size_t set = m_y[(addr_t) (m_cmd_cas_addr_fifo.read())]; 6440 size_t way = r_cas_way.read(); 6441 6442 m_cache_directory.write(set, way, entry); 6443 6444 r_cas_fsm = CAS_BC_CC_SEND; 6445 6446 #if DEBUG_MEMC_CAS 6447 if (m_debug) 6448 { 6449 std::cout << " <MEMC " << name() << " CAS_BC_DIR_INVAL> Inval DIR & register in TRT:" 6450 << " address = " << m_cmd_cas_addr_fifo.read() << std::endl; 6451 } 6452 #endif 6453 break; 6454 } 6455 /////////////////// 6171 6456 case CAS_BC_CC_SEND: // Request the broadcast inval to CC_SEND FSM 6172 { 6173 if (not r_cas_to_cc_send_multi_req.read() and 6174 not r_cas_to_cc_send_brdcast_req.read()) 6175 { 6176 r_cas_to_cc_send_multi_req = false; 6177 r_cas_to_cc_send_brdcast_req = true; 6178 r_cas_to_cc_send_trdid = r_cas_upt_index.read(); 6179 r_cas_to_cc_send_nline = m_nline[(addr_t)(m_cmd_cas_addr_fifo.read())]; 6180 r_cas_to_cc_send_index = 0; 6181 r_cas_to_cc_send_wdata = 0; 6182 6183 r_cas_fsm = CAS_BC_XRAM_REQ; 6184 6185 #if DEBUG_MEMC_CAS 6186 if (m_debug) 6187 std::cout << " <MEMC " << name() 6188 << " CAS_BC_CC_SEND> Post a broadcast request to CC_SEND FSM" << std::endl; 6189 #endif 6190 } 6191 break; 6192 } 6193 //////////////////// 6194 case CAS_BC_XRAM_REQ: // request the IXR FSM to start a PUT transaction 6195 { 6196 if (not r_cas_to_ixr_cmd_req.read()) 6197 { 6198 r_cas_to_ixr_cmd_req = true; 6199 r_cas_to_ixr_cmd_index = r_cas_trt_index.read(); 6200 r_cas_fsm = CAS_IDLE; 6201 cmd_cas_fifo_get = true; 6202 r_cas_cpt = 0; 6203 6204 #if DEBUG_MEMC_CAS 6205 if (m_debug) 6206 std::cout << " <MEMC " << name() 6207 << " CAS_BC_XRAM_REQ> Request a PUT transaction to IXR_CMD FSM" << std::hex 6208 << " / address = " << (addr_t) m_cmd_cas_addr_fifo.read() 6209 << " / trt_index = " << r_cas_trt_index.read() << std::endl; 6210 #endif 6211 } 6212 break; 6213 } 6214 ///////////////// 6215 case CAS_RSP_FAIL: // request TGT_RSP FSM to send a failure response 6216 { 6217 if (not r_cas_to_tgt_rsp_req.read()) 6218 { 6219 cmd_cas_fifo_get = true; 6220 r_cas_cpt = 0; 6221 r_cas_to_tgt_rsp_req = true; 6222 r_cas_to_tgt_rsp_data = 1; 6223 r_cas_to_tgt_rsp_srcid = m_cmd_cas_srcid_fifo.read(); 6224 r_cas_to_tgt_rsp_trdid = m_cmd_cas_trdid_fifo.read(); 6225 r_cas_to_tgt_rsp_pktid = m_cmd_cas_pktid_fifo.read(); 6226 r_cas_fsm = CAS_IDLE; 6227 6228 #if DEBUG_MEMC_CAS 6229 if (m_debug) 6230 std::cout << " <MEMC " << name() 6231 << " CAS_RSP_FAIL> Request TGT_RSP to send a failure response" << std::endl; 6232 #endif 6233 } 6234 break; 6235 } 6236 //////////////////// 6237 case CAS_RSP_SUCCESS: // request TGT_RSP FSM to send a success response 6238 { 6239 if (not r_cas_to_tgt_rsp_req.read()) 6240 { 6241 cmd_cas_fifo_get = true; 6242 r_cas_cpt = 0; 6243 r_cas_to_tgt_rsp_req = true; 6244 r_cas_to_tgt_rsp_data = 0; 6245 r_cas_to_tgt_rsp_srcid = m_cmd_cas_srcid_fifo.read(); 6246 r_cas_to_tgt_rsp_trdid = m_cmd_cas_trdid_fifo.read(); 6247 r_cas_to_tgt_rsp_pktid = m_cmd_cas_pktid_fifo.read(); 6248 r_cas_fsm = CAS_IDLE; 6249 6250 #if DEBUG_MEMC_CAS 6251 if (m_debug) 6252 std::cout << " <MEMC " << name() 6253 << " CAS_RSP_SUCCESS> Request TGT_RSP to send a success response" << std::endl; 6254 #endif 6255 } 6256 break; 6257 } 6258 /////////////////////// 6259 case CAS_MISS_TRT_LOCK: // cache miss : request access to transaction Table 6260 { 6261 if (r_alloc_trt_fsm.read() == ALLOC_TRT_CAS) 6262 { 6263 size_t index = 0; 6264 bool hit_read = m_trt.hit_read( 6265 m_nline[(addr_t) m_cmd_cas_addr_fifo.read()],index); 6266 bool hit_write = m_trt.hit_write( 6267 m_nline[(addr_t) m_cmd_cas_addr_fifo.read()]); 6268 bool wok = not m_trt.full(index); 6269 6270 #if DEBUG_MEMC_CAS 6271 if (m_debug) 6272 std::cout << " <MEMC " << name() << " CAS_MISS_TRT_LOCK> Check TRT state" 6273 << " / hit_read = " << hit_read 6274 << " / hit_write = " << hit_write 6275 << " / wok = " << wok 6276 << " / index = " << index << std::endl; 6277 #endif 6278 6279 if (hit_read or !wok or hit_write) // missing line already requested or TRT full 6280 { 6281 r_cas_fsm = CAS_WAIT; 6282 } 6283 else 6284 { 6285 r_cas_trt_index = index; 6286 r_cas_fsm = CAS_MISS_TRT_SET; 6287 } 6288 } 6289 break; 6290 } 6291 ////////////////////// 6292 case CAS_MISS_TRT_SET: // register the GET transaction in TRT 6293 { 6294 assert( (r_alloc_trt_fsm.read() == ALLOC_TRT_CAS) and 6295 "MEMC ERROR in CAS_MISS_TRT_SET state: Bad TRT allocation"); 6296 6297 std::vector<be_t> be_vector; 6298 std::vector<data_t> data_vector; 6299 be_vector.clear(); 6300 data_vector.clear(); 6301 for(size_t i=0; i<m_words; i++) 6302 { 6303 be_vector.push_back(0); 6304 data_vector.push_back(0); 6305 } 6306 6307 m_trt.set( r_cas_trt_index.read(), 6308 true, // GET 6309 m_nline[(addr_t) m_cmd_cas_addr_fifo.read()], 6310 m_cmd_cas_srcid_fifo.read(), 6311 m_cmd_cas_trdid_fifo.read(), 6312 m_cmd_cas_pktid_fifo.read(), 6313 false, // write request from processor 6314 0, 6315 0, 6316 std::vector<be_t>(m_words,0), 6317 std::vector<data_t>(m_words,0)); 6318 6319 r_cas_fsm = CAS_MISS_XRAM_REQ; 6457 { 6458 if (not r_cas_to_cc_send_multi_req.read() and 6459 not r_cas_to_cc_send_brdcast_req.read()) 6460 { 6461 r_cas_to_cc_send_multi_req = false; 6462 r_cas_to_cc_send_brdcast_req = true; 6463 r_cas_to_cc_send_trdid = r_cas_upt_index.read(); 6464 r_cas_to_cc_send_nline = m_nline[(addr_t)(m_cmd_cas_addr_fifo.read())]; 6465 r_cas_to_cc_send_index = 0; 6466 r_cas_to_cc_send_wdata = 0; 6467 6468 r_cas_fsm = CAS_BC_XRAM_REQ; 6320 6469 6321 6470 #if DEBUG_MEMC_CAS 6322 6471 if (m_debug) 6323 std::cout << " <MEMC " << name() << " CAS_MISS_TRT_SET> Register GET transaction in TRT" 6324 << " / address = " << std::hex << (addr_t)m_cmd_cas_addr_fifo.read() 6472 { 6473 std::cout << " <MEMC " << name() 6474 << " CAS_BC_CC_SEND> Post a broadcast request to CC_SEND FSM" << std::endl; 6475 } 6476 #endif 6477 } 6478 break; 6479 } 6480 //////////////////// 6481 case CAS_BC_XRAM_REQ: // request the IXR FSM to start a PUT transaction 6482 { 6483 if (not r_cas_to_ixr_cmd_req.read()) 6484 { 6485 r_cas_to_ixr_cmd_req = true; 6486 r_cas_to_ixr_cmd_index = r_cas_trt_index.read(); 6487 r_cas_fsm = CAS_IDLE; 6488 cmd_cas_fifo_get = true; 6489 r_cas_cpt = 0; 6490 6491 #if DEBUG_MEMC_CAS 6492 if (m_debug) 6493 { 6494 std::cout << " <MEMC " << name() 6495 << " CAS_BC_XRAM_REQ> Request a PUT transaction to IXR_CMD FSM" << std::hex 6496 << " / address = " << (addr_t) m_cmd_cas_addr_fifo.read() 6497 << " / trt_index = " << r_cas_trt_index.read() << std::endl; 6498 } 6499 #endif 6500 } 6501 break; 6502 } 6503 ///////////////// 6504 case CAS_RSP_FAIL: // request TGT_RSP FSM to send a failure response 6505 { 6506 if (not r_cas_to_tgt_rsp_req.read()) 6507 { 6508 cmd_cas_fifo_get = true; 6509 r_cas_cpt = 0; 6510 r_cas_to_tgt_rsp_req = true; 6511 r_cas_to_tgt_rsp_data = 1; 6512 r_cas_to_tgt_rsp_srcid = m_cmd_cas_srcid_fifo.read(); 6513 r_cas_to_tgt_rsp_trdid = m_cmd_cas_trdid_fifo.read(); 6514 r_cas_to_tgt_rsp_pktid = m_cmd_cas_pktid_fifo.read(); 6515 r_cas_fsm = CAS_IDLE; 6516 6517 #if DEBUG_MEMC_CAS 6518 if (m_debug) 6519 std::cout << " <MEMC " << name() 6520 << " CAS_RSP_FAIL> Request TGT_RSP to send a failure response" << std::endl; 6521 #endif 6522 } 6523 break; 6524 } 6525 //////////////////// 6526 case CAS_RSP_SUCCESS: // request TGT_RSP FSM to send a success response 6527 { 6528 if (not r_cas_to_tgt_rsp_req.read()) 6529 { 6530 cmd_cas_fifo_get = true; 6531 r_cas_cpt = 0; 6532 r_cas_to_tgt_rsp_req = true; 6533 r_cas_to_tgt_rsp_data = 0; 6534 r_cas_to_tgt_rsp_srcid = m_cmd_cas_srcid_fifo.read(); 6535 r_cas_to_tgt_rsp_trdid = m_cmd_cas_trdid_fifo.read(); 6536 r_cas_to_tgt_rsp_pktid = m_cmd_cas_pktid_fifo.read(); 6537 r_cas_fsm = CAS_IDLE; 6538 6539 #if DEBUG_MEMC_CAS 6540 if (m_debug) 6541 { 6542 std::cout << " <MEMC " << name() 6543 << " CAS_RSP_SUCCESS> Request TGT_RSP to send a success response" << std::endl; 6544 } 6545 #endif 6546 } 6547 break; 6548 } 6549 /////////////////////// 6550 case CAS_MISS_TRT_LOCK: // cache miss : request access to transaction Table 6551 { 6552 if (r_alloc_trt_fsm.read() == ALLOC_TRT_CAS) 6553 { 6554 size_t index = 0; 6555 bool hit_read = m_trt.hit_read( 6556 m_nline[(addr_t) m_cmd_cas_addr_fifo.read()],index); 6557 bool hit_write = m_trt.hit_write( 6558 m_nline[(addr_t) m_cmd_cas_addr_fifo.read()]); 6559 bool wok = not m_trt.full(index); 6560 6561 #if DEBUG_MEMC_CAS 6562 if (m_debug) 6563 { 6564 std::cout << " <MEMC " << name() << " CAS_MISS_TRT_LOCK> Check TRT state" 6565 << " / hit_read = " << hit_read 6566 << " / hit_write = " << hit_write 6567 << " / wok = " << wok 6568 << " / index = " << index << std::endl; 6569 } 6570 #endif 6571 6572 if (hit_read or !wok or hit_write) // missing line already requested or TRT full 6573 { 6574 r_cas_fsm = CAS_WAIT; 6575 } 6576 else 6577 { 6578 r_cas_trt_index = index; 6579 r_cas_fsm = CAS_MISS_TRT_SET; 6580 } 6581 } 6582 break; 6583 } 6584 ////////////////////// 6585 case CAS_MISS_TRT_SET: // register the GET transaction in TRT 6586 { 6587 assert((r_alloc_trt_fsm.read() == ALLOC_TRT_CAS) and 6588 "MEMC ERROR in CAS_MISS_TRT_SET state: Bad TRT allocation"); 6589 6590 std::vector<be_t> be_vector; 6591 std::vector<data_t> data_vector; 6592 be_vector.clear(); 6593 data_vector.clear(); 6594 for (size_t i = 0; i < m_words; i++) 6595 { 6596 be_vector.push_back(0); 6597 data_vector.push_back(0); 6598 } 6599 6600 m_trt.set(r_cas_trt_index.read(), 6601 true, // GET 6602 m_nline[(addr_t) m_cmd_cas_addr_fifo.read()], 6603 m_cmd_cas_srcid_fifo.read(), 6604 m_cmd_cas_trdid_fifo.read(), 6605 m_cmd_cas_pktid_fifo.read(), 6606 false, // write request from processor 6607 0, 6608 0, 6609 std::vector<be_t>(m_words, 0), 6610 std::vector<data_t>(m_words, 0)); 6611 6612 r_cas_fsm = CAS_MISS_XRAM_REQ; 6613 6614 #if DEBUG_MEMC_CAS 6615 if (m_debug) 6616 { 6617 std::cout << " <MEMC " << name() << " CAS_MISS_TRT_SET> Register GET transaction in TRT" 6618 << " / address = " << std::hex << (addr_t)m_cmd_cas_addr_fifo.read() 6619 << " / trt_index = " << std::dec << r_cas_trt_index.read() << std::endl; 6620 } 6621 #endif 6622 break; 6623 } 6624 ////////////////////// 6625 case CAS_MISS_XRAM_REQ: // request the IXR_CMD FSM a GET request 6626 { 6627 if (not r_cas_to_ixr_cmd_req.read()) 6628 { 6629 r_cas_to_ixr_cmd_req = true; 6630 r_cas_to_ixr_cmd_index = r_cas_trt_index.read(); 6631 r_cas_fsm = CAS_WAIT; 6632 6633 #if DEBUG_MEMC_CAS 6634 if (m_debug) 6635 { 6636 std::cout << " <MEMC " << name() << " CAS_MISS_XRAM_REQ> Request a GET transaction" 6637 << " / address = " << std::hex << (addr_t) m_cmd_cas_addr_fifo.read() 6325 6638 << " / trt_index = " << std::dec << r_cas_trt_index.read() << std::endl; 6326 #endif 6327 break; 6328 } 6329 ////////////////////// 6330 case CAS_MISS_XRAM_REQ: // request the IXR_CMD FSM a GET request 6331 { 6332 if (not r_cas_to_ixr_cmd_req.read()) 6333 { 6334 r_cas_to_ixr_cmd_req = true; 6335 r_cas_to_ixr_cmd_index = r_cas_trt_index.read(); 6336 r_cas_fsm = CAS_WAIT; 6337 6338 #if DEBUG_MEMC_CAS 6339 if (m_debug) 6340 std::cout << " <MEMC " << name() << " CAS_MISS_XRAM_REQ> Request a GET transaction" 6341 << " / address = " << std::hex << (addr_t) m_cmd_cas_addr_fifo.read() 6342 << " / trt_index = " << std::dec << r_cas_trt_index.read() << std::endl; 6343 #endif 6344 } 6345 break; 6346 } 6639 } 6640 #endif 6641 } 6642 break; 6643 } 6347 6644 } // end switch r_cas_fsm 6348 6645 … … 6355 6652 // 6356 6653 // It implements a round-robin priority between the four possible client FSMs 6357 // XRAM_RSP > CAS > WRITE > CONFIG 6654 // XRAM_RSP > CAS > WRITE > CONFIG 6358 6655 // 6359 6656 // Each FSM can request the next services: … … 6366 6663 // - r_config_to_cc_send_multi_req : multi-inval 6367 6664 // r_config_to_cc_send_brdcast_req : broadcast-inval 6368 // 6665 // 6369 6666 // An inval request is a double DSPIN flit command containing: 6370 6667 // 1. the index of the line to be invalidated. … … 6376 6673 /////////////////////////////////////////////////////////////////////////////// 6377 6674 6378 //std::cout << std::endl << "cc_send_fsm" << std::endl; 6379 6380 switch(r_cc_send_fsm.read()) 6675 switch (r_cc_send_fsm.read()) 6381 6676 { 6382 6677 ///////////////////////// 6383 6678 case CC_SEND_CONFIG_IDLE: // XRAM_RSP FSM has highest priority 6384 { 6385 // XRAM_RSP 6386 if (m_xram_rsp_to_cc_send_inst_fifo.rok() or 6387 r_xram_rsp_to_cc_send_multi_req.read()) 6388 { 6389 r_cc_send_fsm = CC_SEND_XRAM_RSP_INVAL_HEADER; 6390 break; 6391 } 6392 if (r_xram_rsp_to_cc_send_brdcast_req.read()) 6393 { 6394 r_cc_send_fsm = CC_SEND_XRAM_RSP_BRDCAST_HEADER; 6395 break; 6396 } 6397 // CAS 6398 if (m_cas_to_cc_send_inst_fifo.rok() or 6399 r_cas_to_cc_send_multi_req.read()) 6400 { 6401 r_cc_send_fsm = CC_SEND_CAS_UPDT_HEADER; 6402 break; 6403 } 6404 if (r_cas_to_cc_send_brdcast_req.read()) 6405 { 6406 r_cc_send_fsm = CC_SEND_CAS_BRDCAST_HEADER; 6407 break; 6408 } 6409 // WRITE 6410 if (m_write_to_cc_send_inst_fifo.rok() or 6411 r_write_to_cc_send_multi_req.read()) 6412 { 6413 r_cc_send_fsm = CC_SEND_WRITE_UPDT_HEADER; 6414 break; 6415 } 6416 if (r_write_to_cc_send_brdcast_req.read()) 6417 { 6418 r_cc_send_fsm = CC_SEND_WRITE_BRDCAST_HEADER; 6419 break; 6420 } 6421 // CONFIG 6422 if (r_config_to_cc_send_multi_req.read()) 6423 { 6424 r_cc_send_fsm = CC_SEND_CONFIG_INVAL_HEADER; 6425 break; 6426 } 6427 if (r_config_to_cc_send_brdcast_req.read()) 6428 { 6429 r_cc_send_fsm = CC_SEND_CONFIG_BRDCAST_HEADER; 6430 break; 6431 } 6679 { 6680 // XRAM_RSP 6681 if (m_xram_rsp_to_cc_send_inst_fifo.rok() or 6682 r_xram_rsp_to_cc_send_multi_req.read()) 6683 { 6684 r_cc_send_fsm = CC_SEND_XRAM_RSP_INVAL_HEADER; 6432 6685 break; 6433 6686 } 6434 //////////////////////// 6687 if (r_xram_rsp_to_cc_send_brdcast_req.read()) 6688 { 6689 r_cc_send_fsm = CC_SEND_XRAM_RSP_BRDCAST_HEADER; 6690 break; 6691 } 6692 // CAS 6693 if (m_cas_to_cc_send_inst_fifo.rok() or 6694 r_cas_to_cc_send_multi_req.read()) 6695 { 6696 r_cc_send_fsm = CC_SEND_CAS_UPDT_HEADER; 6697 break; 6698 } 6699 if (r_cas_to_cc_send_brdcast_req.read()) 6700 { 6701 r_cc_send_fsm = CC_SEND_CAS_BRDCAST_HEADER; 6702 break; 6703 } 6704 // WRITE 6705 if (m_write_to_cc_send_inst_fifo.rok() or 6706 r_write_to_cc_send_multi_req.read()) 6707 { 6708 r_cc_send_fsm = CC_SEND_WRITE_UPDT_HEADER; 6709 break; 6710 } 6711 if (r_write_to_cc_send_brdcast_req.read()) 6712 { 6713 r_cc_send_fsm = CC_SEND_WRITE_BRDCAST_HEADER; 6714 break; 6715 } 6716 // CONFIG 6717 if (r_config_to_cc_send_multi_req.read()) 6718 { 6719 r_cc_send_fsm = CC_SEND_CONFIG_INVAL_HEADER; 6720 break; 6721 } 6722 if (r_config_to_cc_send_brdcast_req.read()) 6723 { 6724 r_cc_send_fsm = CC_SEND_CONFIG_BRDCAST_HEADER; 6725 break; 6726 } 6727 break; 6728 } 6729 //////////////////////// 6435 6730 case CC_SEND_WRITE_IDLE: // CONFIG FSM has highest priority 6436 { 6437 // CONFIG 6438 if (r_config_to_cc_send_multi_req.read()) 6439 { 6440 r_cc_send_fsm = CC_SEND_CONFIG_INVAL_HEADER; 6441 break; 6442 } 6443 if (r_config_to_cc_send_brdcast_req.read()) 6444 { 6445 r_cc_send_fsm = CC_SEND_CONFIG_BRDCAST_HEADER; 6446 break; 6447 } 6448 // XRAM_RSP 6449 if (m_xram_rsp_to_cc_send_inst_fifo.rok() or 6450 r_xram_rsp_to_cc_send_multi_req.read()) 6451 { 6452 r_cc_send_fsm = CC_SEND_XRAM_RSP_INVAL_HEADER; 6453 break; 6454 } 6455 if (r_xram_rsp_to_cc_send_brdcast_req.read()) 6456 { 6457 r_cc_send_fsm = CC_SEND_XRAM_RSP_BRDCAST_HEADER; 6458 break; 6459 } 6460 // CAS 6461 if (m_cas_to_cc_send_inst_fifo.rok() or 6462 r_cas_to_cc_send_multi_req.read()) 6463 { 6464 r_cc_send_fsm = CC_SEND_CAS_UPDT_HEADER; 6465 break; 6466 } 6467 if (r_cas_to_cc_send_brdcast_req.read()) 6468 { 6469 r_cc_send_fsm = CC_SEND_CAS_BRDCAST_HEADER; 6470 break; 6471 } 6472 // WRITE 6473 if (m_write_to_cc_send_inst_fifo.rok() or 6474 r_write_to_cc_send_multi_req.read()) 6475 { 6476 r_cc_send_fsm = CC_SEND_WRITE_UPDT_HEADER; 6477 break; 6478 } 6479 if (r_write_to_cc_send_brdcast_req.read()) 6480 { 6481 r_cc_send_fsm = CC_SEND_WRITE_BRDCAST_HEADER; 6482 break; 6483 } 6731 { 6732 // CONFIG 6733 if (r_config_to_cc_send_multi_req.read()) 6734 { 6735 r_cc_send_fsm = CC_SEND_CONFIG_INVAL_HEADER; 6484 6736 break; 6485 6737 } 6486 /////////////////////////// 6738 if (r_config_to_cc_send_brdcast_req.read()) 6739 { 6740 r_cc_send_fsm = CC_SEND_CONFIG_BRDCAST_HEADER; 6741 break; 6742 } 6743 // XRAM_RSP 6744 if (m_xram_rsp_to_cc_send_inst_fifo.rok() or 6745 r_xram_rsp_to_cc_send_multi_req.read()) 6746 { 6747 r_cc_send_fsm = CC_SEND_XRAM_RSP_INVAL_HEADER; 6748 break; 6749 } 6750 if (r_xram_rsp_to_cc_send_brdcast_req.read()) 6751 { 6752 r_cc_send_fsm = CC_SEND_XRAM_RSP_BRDCAST_HEADER; 6753 break; 6754 } 6755 // CAS 6756 if (m_cas_to_cc_send_inst_fifo.rok() or 6757 r_cas_to_cc_send_multi_req.read()) 6758 { 6759 r_cc_send_fsm = CC_SEND_CAS_UPDT_HEADER; 6760 break; 6761 } 6762 if (r_cas_to_cc_send_brdcast_req.read()) 6763 { 6764 r_cc_send_fsm = CC_SEND_CAS_BRDCAST_HEADER; 6765 break; 6766 } 6767 // WRITE 6768 if (m_write_to_cc_send_inst_fifo.rok() or 6769 r_write_to_cc_send_multi_req.read()) 6770 { 6771 r_cc_send_fsm = CC_SEND_WRITE_UPDT_HEADER; 6772 break; 6773 } 6774 if (r_write_to_cc_send_brdcast_req.read()) 6775 { 6776 r_cc_send_fsm = CC_SEND_WRITE_BRDCAST_HEADER; 6777 break; 6778 } 6779 break; 6780 } 6781 /////////////////////////// 6487 6782 case CC_SEND_XRAM_RSP_IDLE: // CAS FSM has highest priority 6488 { 6489 // CAS 6490 if (m_cas_to_cc_send_inst_fifo.rok() or 6491 r_cas_to_cc_send_multi_req.read()) 6492 { 6493 r_cc_send_fsm = CC_SEND_CAS_UPDT_HEADER; 6494 break; 6495 } 6496 if (r_cas_to_cc_send_brdcast_req.read()) 6497 { 6498 r_cc_send_fsm = CC_SEND_CAS_BRDCAST_HEADER; 6499 break; 6500 } 6501 // WRITE 6502 if (m_write_to_cc_send_inst_fifo.rok() or 6503 r_write_to_cc_send_multi_req.read()) 6504 { 6505 r_cc_send_fsm = CC_SEND_WRITE_UPDT_HEADER; 6506 break; 6507 } 6508 6509 if (r_write_to_cc_send_brdcast_req.read()) 6510 { 6511 r_cc_send_fsm = CC_SEND_WRITE_BRDCAST_HEADER; 6512 break; 6513 } 6514 // CONFIG 6515 if (r_config_to_cc_send_multi_req.read()) 6516 { 6517 r_cc_send_fsm = CC_SEND_CONFIG_INVAL_HEADER; 6518 break; 6519 } 6520 if (r_config_to_cc_send_brdcast_req.read()) 6521 { 6522 r_cc_send_fsm = CC_SEND_CONFIG_BRDCAST_HEADER; 6523 break; 6524 } 6525 // XRAM_RSP 6526 if (m_xram_rsp_to_cc_send_inst_fifo.rok() or 6527 r_xram_rsp_to_cc_send_multi_req.read()) 6528 { 6529 r_cc_send_fsm = CC_SEND_XRAM_RSP_INVAL_HEADER; 6530 break; 6531 } 6532 if (r_xram_rsp_to_cc_send_brdcast_req.read()) 6533 { 6534 r_cc_send_fsm = CC_SEND_XRAM_RSP_BRDCAST_HEADER; 6535 break; 6536 } 6783 { 6784 // CAS 6785 if (m_cas_to_cc_send_inst_fifo.rok() or 6786 r_cas_to_cc_send_multi_req.read()) 6787 { 6788 r_cc_send_fsm = CC_SEND_CAS_UPDT_HEADER; 6537 6789 break; 6538 6790 } 6539 ////////////////////// 6791 if (r_cas_to_cc_send_brdcast_req.read()) 6792 { 6793 r_cc_send_fsm = CC_SEND_CAS_BRDCAST_HEADER; 6794 break; 6795 } 6796 // WRITE 6797 if (m_write_to_cc_send_inst_fifo.rok() or 6798 r_write_to_cc_send_multi_req.read()) 6799 { 6800 r_cc_send_fsm = CC_SEND_WRITE_UPDT_HEADER; 6801 break; 6802 } 6803 6804 if (r_write_to_cc_send_brdcast_req.read()) 6805 { 6806 r_cc_send_fsm = CC_SEND_WRITE_BRDCAST_HEADER; 6807 break; 6808 } 6809 // CONFIG 6810 if (r_config_to_cc_send_multi_req.read()) 6811 { 6812 r_cc_send_fsm = CC_SEND_CONFIG_INVAL_HEADER; 6813 break; 6814 } 6815 if (r_config_to_cc_send_brdcast_req.read()) 6816 { 6817 r_cc_send_fsm = CC_SEND_CONFIG_BRDCAST_HEADER; 6818 break; 6819 } 6820 // XRAM_RSP 6821 if (m_xram_rsp_to_cc_send_inst_fifo.rok() or 6822 r_xram_rsp_to_cc_send_multi_req.read()) 6823 { 6824 r_cc_send_fsm = CC_SEND_XRAM_RSP_INVAL_HEADER; 6825 break; 6826 } 6827 if (r_xram_rsp_to_cc_send_brdcast_req.read()) 6828 { 6829 r_cc_send_fsm = CC_SEND_XRAM_RSP_BRDCAST_HEADER; 6830 break; 6831 } 6832 break; 6833 } 6834 ////////////////////// 6540 6835 case CC_SEND_CAS_IDLE: // CLEANUP FSM has highest priority 6541 { 6542 if (m_write_to_cc_send_inst_fifo.rok() or 6543 r_write_to_cc_send_multi_req.read()) 6544 { 6545 r_cc_send_fsm = CC_SEND_WRITE_UPDT_HEADER; 6546 break; 6547 } 6548 if (r_write_to_cc_send_brdcast_req.read()) 6549 { 6550 r_cc_send_fsm = CC_SEND_WRITE_BRDCAST_HEADER; 6551 break; 6552 } 6553 // CONFIG 6554 if (r_config_to_cc_send_multi_req.read()) 6555 { 6556 r_cc_send_fsm = CC_SEND_CONFIG_INVAL_HEADER; 6557 break; 6558 } 6559 if (r_config_to_cc_send_brdcast_req.read()) 6560 { 6561 r_cc_send_fsm = CC_SEND_CONFIG_BRDCAST_HEADER; 6562 break; 6563 } 6564 if (m_xram_rsp_to_cc_send_inst_fifo.rok() or 6565 r_xram_rsp_to_cc_send_multi_req.read()) 6566 { 6567 r_cc_send_fsm = CC_SEND_XRAM_RSP_INVAL_HEADER; 6568 break; 6569 } 6570 if (r_xram_rsp_to_cc_send_brdcast_req.read()) 6571 { 6572 r_cc_send_fsm = CC_SEND_XRAM_RSP_BRDCAST_HEADER; 6573 break; 6574 } 6575 if (m_cas_to_cc_send_inst_fifo.rok() or 6576 r_cas_to_cc_send_multi_req.read()) 6577 { 6578 r_cc_send_fsm = CC_SEND_CAS_UPDT_HEADER; 6579 break; 6580 } 6581 if (r_cas_to_cc_send_brdcast_req.read()) 6582 { 6583 r_cc_send_fsm = CC_SEND_CAS_BRDCAST_HEADER; 6584 break; 6585 } 6836 { 6837 if (m_write_to_cc_send_inst_fifo.rok() or 6838 r_write_to_cc_send_multi_req.read()) 6839 { 6840 r_cc_send_fsm = CC_SEND_WRITE_UPDT_HEADER; 6586 6841 break; 6587 6842 } 6588 ///////////////////////////////// 6843 if (r_write_to_cc_send_brdcast_req.read()) 6844 { 6845 r_cc_send_fsm = CC_SEND_WRITE_BRDCAST_HEADER; 6846 break; 6847 } 6848 // CONFIG 6849 if (r_config_to_cc_send_multi_req.read()) 6850 { 6851 r_cc_send_fsm = CC_SEND_CONFIG_INVAL_HEADER; 6852 break; 6853 } 6854 if (r_config_to_cc_send_brdcast_req.read()) 6855 { 6856 r_cc_send_fsm = CC_SEND_CONFIG_BRDCAST_HEADER; 6857 break; 6858 } 6859 if (m_xram_rsp_to_cc_send_inst_fifo.rok() or 6860 r_xram_rsp_to_cc_send_multi_req.read()) 6861 { 6862 r_cc_send_fsm = CC_SEND_XRAM_RSP_INVAL_HEADER; 6863 break; 6864 } 6865 if (r_xram_rsp_to_cc_send_brdcast_req.read()) 6866 { 6867 r_cc_send_fsm = CC_SEND_XRAM_RSP_BRDCAST_HEADER; 6868 break; 6869 } 6870 if (m_cas_to_cc_send_inst_fifo.rok() or 6871 r_cas_to_cc_send_multi_req.read()) 6872 { 6873 r_cc_send_fsm = CC_SEND_CAS_UPDT_HEADER; 6874 break; 6875 } 6876 if (r_cas_to_cc_send_brdcast_req.read()) 6877 { 6878 r_cc_send_fsm = CC_SEND_CAS_BRDCAST_HEADER; 6879 break; 6880 } 6881 break; 6882 } 6883 ///////////////////////////////// 6589 6884 case CC_SEND_CONFIG_INVAL_HEADER: // send first flit multi-inval (from CONFIG FSM) 6590 { 6591 if (m_config_to_cc_send_inst_fifo.rok()) 6592 { 6593 if (not p_dspin_m2p.read) break; 6594 // <Activity Counters> 6595 if (is_local_req(m_config_to_cc_send_srcid_fifo.read())) 6596 { 6597 m_cpt_minval_local++; 6598 } 6599 else 6600 { 6601 m_cpt_minval_remote++; 6602 } 6603 // 2 flits for multi inval 6604 m_cpt_minval_cost += 2 * req_distance(m_config_to_cc_send_srcid_fifo.read()); 6605 // </Activity Counters> 6606 r_cc_send_fsm = CC_SEND_CONFIG_INVAL_NLINE; 6607 break; 6608 } 6609 if (r_config_to_cc_send_multi_req.read()) r_config_to_cc_send_multi_req = false; 6610 // <Activity Counters> 6611 m_cpt_minval++; 6612 // </Activity Counters> 6613 r_cc_send_fsm = CC_SEND_CONFIG_IDLE; 6614 break; 6615 } 6616 //////////////////////////////// 6617 case CC_SEND_CONFIG_INVAL_NLINE: // send second flit multi-inval (from CONFIG FSM) 6618 { 6619 if (not p_dspin_m2p.read) break; 6620 config_to_cc_send_fifo_get = true; 6621 r_cc_send_fsm = CC_SEND_CONFIG_INVAL_HEADER; 6622 6623 #if DEBUG_MEMC_CC_SEND 6624 if (m_debug) 6625 std::cout << " <MEMC " << name() 6626 << " CC_SEND_CONFIG_INVAL_NLINE> multi-inval for line " 6627 << std::hex << r_config_to_cc_send_nline.read() << std::endl; 6628 #endif 6629 break; 6630 } 6631 /////////////////////////////////// 6632 case CC_SEND_CONFIG_BRDCAST_HEADER: // send first flit BC-inval (from CONFIG FSM) 6633 { 6634 if (not p_dspin_m2p.read) break; 6635 r_cc_send_fsm = CC_SEND_CONFIG_BRDCAST_NLINE; 6636 break; 6637 } 6638 ////////////////////////////////// 6639 case CC_SEND_CONFIG_BRDCAST_NLINE: // send second flit BC-inval (from CONFIG FSM) 6885 { 6886 if (m_config_to_cc_send_inst_fifo.rok()) 6640 6887 { 6641 6888 if (not p_dspin_m2p.read) break; 6642 6889 // <Activity Counters> 6643 m_cpt_binval++; 6890 if (is_local_req(m_config_to_cc_send_srcid_fifo.read())) 6891 { 6892 m_cpt_minval_local++; 6893 } 6894 else 6895 { 6896 m_cpt_minval_remote++; 6897 } 6898 // 2 flits for multi inval 6899 m_cpt_minval_cost += 2 * req_distance(m_config_to_cc_send_srcid_fifo.read()); 6644 6900 // </Activity Counters> 6645 r_config_to_cc_send_brdcast_req = false; 6646 r_cc_send_fsm = CC_SEND_CONFIG_IDLE; 6901 r_cc_send_fsm = CC_SEND_CONFIG_INVAL_NLINE; 6902 break; 6903 } 6904 if (r_config_to_cc_send_multi_req.read()) r_config_to_cc_send_multi_req = false; 6905 // <Activity Counters> 6906 m_cpt_minval++; 6907 // </Activity Counters> 6908 r_cc_send_fsm = CC_SEND_CONFIG_IDLE; 6909 break; 6910 } 6911 //////////////////////////////// 6912 case CC_SEND_CONFIG_INVAL_NLINE: // send second flit multi-inval (from CONFIG FSM) 6913 { 6914 if (not p_dspin_m2p.read) break; 6915 config_to_cc_send_fifo_get = true; 6916 r_cc_send_fsm = CC_SEND_CONFIG_INVAL_HEADER; 6647 6917 6648 6918 #if DEBUG_MEMC_CC_SEND 6649 if (m_debug) 6650 std::cout << " <MEMC " << name() 6651 << " CC_SEND_CONFIG_BRDCAST_NLINE> BC-Inval for line " 6652 << std::hex << r_config_to_cc_send_nline.read() << std::endl; 6653 #endif 6654 break; 6655 } 6656 /////////////////////////////////// 6919 if (m_debug) 6920 { 6921 std::cout << " <MEMC " << name() 6922 << " CC_SEND_CONFIG_INVAL_NLINE> multi-inval for line " 6923 << std::hex << r_config_to_cc_send_nline.read() << std::endl; 6924 } 6925 #endif 6926 break; 6927 } 6928 /////////////////////////////////// 6929 case CC_SEND_CONFIG_BRDCAST_HEADER: // send first flit BC-inval (from CONFIG FSM) 6930 { 6931 if (not p_dspin_m2p.read) break; 6932 r_cc_send_fsm = CC_SEND_CONFIG_BRDCAST_NLINE; 6933 break; 6934 } 6935 ////////////////////////////////// 6936 case CC_SEND_CONFIG_BRDCAST_NLINE: // send second flit BC-inval (from CONFIG FSM) 6937 { 6938 if (not p_dspin_m2p.read) break; 6939 // <Activity Counters> 6940 m_cpt_binval++; 6941 // </Activity Counters> 6942 r_config_to_cc_send_brdcast_req = false; 6943 r_cc_send_fsm = CC_SEND_CONFIG_IDLE; 6944 6945 #if DEBUG_MEMC_CC_SEND 6946 if (m_debug) 6947 std::cout << " <MEMC " << name() 6948 << " CC_SEND_CONFIG_BRDCAST_NLINE> BC-Inval for line " 6949 << std::hex << r_config_to_cc_send_nline.read() << std::endl; 6950 #endif 6951 break; 6952 } 6953 /////////////////////////////////// 6657 6954 case CC_SEND_XRAM_RSP_INVAL_HEADER: // send first flit multi-inval (from XRAM_RSP FSM) 6658 { 6659 if (m_xram_rsp_to_cc_send_inst_fifo.rok()) 6660 { 6661 if (not p_dspin_m2p.read) break; 6662 // <Activity Counters> 6663 if (is_local_req(m_xram_rsp_to_cc_send_srcid_fifo.read())) 6664 { 6665 m_cpt_minval_local++; 6666 } 6667 else 6668 { 6669 m_cpt_minval_remote++; 6670 } 6671 // 2 flits for multi inval 6672 m_cpt_minval_cost += 2 * req_distance(m_xram_rsp_to_cc_send_srcid_fifo.read()); 6673 // </Activity Counters> 6674 r_cc_send_fsm = CC_SEND_XRAM_RSP_INVAL_NLINE; 6675 break; 6676 } 6677 if (r_xram_rsp_to_cc_send_multi_req.read()) r_xram_rsp_to_cc_send_multi_req = false; 6678 // <Activity Counters> 6679 m_cpt_minval++; 6680 // </Activity Counters> 6681 r_cc_send_fsm = CC_SEND_XRAM_RSP_IDLE; 6682 break; 6683 } 6684 ////////////////////////////////// 6685 case CC_SEND_XRAM_RSP_INVAL_NLINE: // send second flit multi-inval (from XRAM_RSP FSM) 6686 { 6687 if (not p_dspin_m2p.read) break; 6688 xram_rsp_to_cc_send_fifo_get = true; 6689 r_cc_send_fsm = CC_SEND_XRAM_RSP_INVAL_HEADER; 6690 6691 #if DEBUG_MEMC_CC_SEND 6692 if (m_debug) 6693 std::cout << " <MEMC " << name() 6694 << " CC_SEND_XRAM_RSP_INVAL_NLINE> Multicast-Inval for line " 6695 << std::hex << r_xram_rsp_to_cc_send_nline.read() << std::endl; 6696 #endif 6697 break; 6698 } 6699 ///////////////////////////////////// 6700 case CC_SEND_XRAM_RSP_BRDCAST_HEADER: // send first flit broadcast-inval (from XRAM_RSP FSM) 6701 { 6702 if (not p_dspin_m2p.read) break; 6703 r_cc_send_fsm = CC_SEND_XRAM_RSP_BRDCAST_NLINE; 6704 break; 6705 } 6706 //////////////////////////////////// 6707 case CC_SEND_XRAM_RSP_BRDCAST_NLINE: // send second flit broadcast-inval (from XRAM_RSP FSM) 6955 { 6956 if (m_xram_rsp_to_cc_send_inst_fifo.rok()) 6708 6957 { 6709 6958 if (not p_dspin_m2p.read) break; 6710 6959 // <Activity Counters> 6711 m_cpt_binval++; 6960 if (is_local_req(m_xram_rsp_to_cc_send_srcid_fifo.read())) 6961 { 6962 m_cpt_minval_local++; 6963 } 6964 else 6965 { 6966 m_cpt_minval_remote++; 6967 } 6968 // 2 flits for multi inval 6969 m_cpt_minval_cost += 2 * req_distance(m_xram_rsp_to_cc_send_srcid_fifo.read()); 6712 6970 // </Activity Counters> 6713 r_xram_rsp_to_cc_send_brdcast_req = false; 6714 r_cc_send_fsm = CC_SEND_XRAM_RSP_IDLE; 6971 r_cc_send_fsm = CC_SEND_XRAM_RSP_INVAL_NLINE; 6972 break; 6973 } 6974 if (r_xram_rsp_to_cc_send_multi_req.read()) r_xram_rsp_to_cc_send_multi_req = false; 6975 // <Activity Counters> 6976 m_cpt_minval++; 6977 // </Activity Counters> 6978 r_cc_send_fsm = CC_SEND_XRAM_RSP_IDLE; 6979 break; 6980 } 6981 ////////////////////////////////// 6982 case CC_SEND_XRAM_RSP_INVAL_NLINE: // send second flit multi-inval (from XRAM_RSP FSM) 6983 { 6984 if (not p_dspin_m2p.read) break; 6985 xram_rsp_to_cc_send_fifo_get = true; 6986 r_cc_send_fsm = CC_SEND_XRAM_RSP_INVAL_HEADER; 6715 6987 6716 6988 #if DEBUG_MEMC_CC_SEND 6717 if (m_debug) 6718 std::cout << " <MEMC " << name() 6719 << " CC_SEND_XRAM_RSP_BRDCAST_NLINE> BC-Inval for line " 6720 << std::hex << r_xram_rsp_to_cc_send_nline.read() << std::endl; 6721 #endif 6722 break; 6723 } 6724 ////////////////////////////////// 6989 if (m_debug) 6990 { 6991 std::cout << " <MEMC " << name() 6992 << " CC_SEND_XRAM_RSP_INVAL_NLINE> Multicast-Inval for line " 6993 << std::hex << r_xram_rsp_to_cc_send_nline.read() << std::endl; 6994 } 6995 #endif 6996 break; 6997 } 6998 ///////////////////////////////////// 6999 case CC_SEND_XRAM_RSP_BRDCAST_HEADER: // send first flit broadcast-inval (from XRAM_RSP FSM) 7000 { 7001 if (not p_dspin_m2p.read) break; 7002 r_cc_send_fsm = CC_SEND_XRAM_RSP_BRDCAST_NLINE; 7003 break; 7004 } 7005 //////////////////////////////////// 7006 case CC_SEND_XRAM_RSP_BRDCAST_NLINE: // send second flit broadcast-inval (from XRAM_RSP FSM) 7007 { 7008 if (not p_dspin_m2p.read) break; 7009 // <Activity Counters> 7010 m_cpt_binval++; 7011 // </Activity Counters> 7012 r_xram_rsp_to_cc_send_brdcast_req = false; 7013 r_cc_send_fsm = CC_SEND_XRAM_RSP_IDLE; 7014 7015 #if DEBUG_MEMC_CC_SEND 7016 if (m_debug) 7017 { 7018 std::cout << " <MEMC " << name() 7019 << " CC_SEND_XRAM_RSP_BRDCAST_NLINE> BC-Inval for line " 7020 << std::hex << r_xram_rsp_to_cc_send_nline.read() << std::endl; 7021 } 7022 #endif 7023 break; 7024 } 7025 ////////////////////////////////// 6725 7026 case CC_SEND_WRITE_BRDCAST_HEADER: // send first flit broadcast-inval (from WRITE FSM) 6726 {6727 if (not p_dspin_m2p.read) break;6728 r_cc_send_fsm = CC_SEND_WRITE_BRDCAST_NLINE;6729 break;6730 }6731 /////////////////////////////////7027 { 7028 if (not p_dspin_m2p.read) break; 7029 r_cc_send_fsm = CC_SEND_WRITE_BRDCAST_NLINE; 7030 break; 7031 } 7032 ///////////////////////////////// 6732 7033 case CC_SEND_WRITE_BRDCAST_NLINE: // send second flit broadcast-inval (from WRITE FSM) 6733 {6734 if (not p_dspin_m2p.read) break;6735 6736 // <Activity Counters>6737 m_cpt_binval++;6738 m_cpt_write_broadcast++;6739 // </Activity Counters>6740 6741 r_write_to_cc_send_brdcast_req = false;6742 r_cc_send_fsm = CC_SEND_WRITE_IDLE;7034 { 7035 if (not p_dspin_m2p.read) break; 7036 7037 // <Activity Counters> 7038 m_cpt_binval++; 7039 m_cpt_write_broadcast++; 7040 // </Activity Counters> 7041 7042 r_write_to_cc_send_brdcast_req = false; 7043 r_cc_send_fsm = CC_SEND_WRITE_IDLE; 6743 7044 6744 7045 #if DEBUG_MEMC_CC_SEND 6745 if (m_debug) 6746 std::cout << " <MEMC " << name() 6747 << " CC_SEND_WRITE_BRDCAST_NLINE> BC-Inval for line " 6748 << std::hex << r_write_to_cc_send_nline.read() << std::endl; 6749 #endif 6750 break; 6751 } 6752 /////////////////////////////// 7046 if (m_debug) 7047 { 7048 std::cout << " <MEMC " << name() 7049 << " CC_SEND_WRITE_BRDCAST_NLINE> BC-Inval for line " 7050 << std::hex << r_write_to_cc_send_nline.read() << std::endl; 7051 } 7052 #endif 7053 break; 7054 } 7055 /////////////////////////////// 6753 7056 case CC_SEND_WRITE_UPDT_HEADER: // send first flit for a multi-update (from WRITE FSM) 6754 { 6755 if (m_write_to_cc_send_inst_fifo.rok()) 6756 { 6757 if (not p_dspin_m2p.read) break; 6758 // <Activity Counters> 6759 if (is_local_req(m_write_to_cc_send_srcid_fifo.read())) 6760 { 6761 m_cpt_update_local++; 6762 } 6763 else 6764 { 6765 m_cpt_update_remote++; 6766 } 6767 // 2 flits for multi update 6768 m_cpt_update_cost += 2 * req_distance(m_write_to_cc_send_srcid_fifo.read()); 6769 // </Activity Counters> 6770 6771 r_cc_send_fsm = CC_SEND_WRITE_UPDT_NLINE; 6772 break; 6773 } 6774 6775 if (r_write_to_cc_send_multi_req.read()) 6776 { 6777 r_write_to_cc_send_multi_req = false; 6778 } 6779 6780 // <Activity Counters> 6781 m_cpt_update++; 6782 // </Activity Counters> 6783 r_cc_send_fsm = CC_SEND_WRITE_IDLE; 6784 break; 6785 } 6786 ////////////////////////////// 6787 case CC_SEND_WRITE_UPDT_NLINE: // send second flit for a multi-update (from WRITE FSM) 6788 { 6789 if (not p_dspin_m2p.read) break; 6790 6791 r_cc_send_cpt = 0; 6792 r_cc_send_fsm = CC_SEND_WRITE_UPDT_DATA; 6793 6794 #if DEBUG_MEMC_CC_SEND 6795 if (m_debug) 6796 std::cout << " <MEMC " << name() 6797 << " CC_SEND_WRITE_UPDT_NLINE> Multicast-Update for address " 6798 << r_write_to_cc_send_nline.read()*m_words*4 << std::endl; 6799 #endif 6800 break; 6801 } 6802 ///////////////////////////// 6803 case CC_SEND_WRITE_UPDT_DATA: // send data flits for multi-update (from WRITE FSM) 6804 { 6805 if (not p_dspin_m2p.read) break; 6806 if (r_cc_send_cpt.read() == r_write_to_cc_send_count.read()) 6807 { 6808 write_to_cc_send_fifo_get = true; 6809 r_cc_send_fsm = CC_SEND_WRITE_UPDT_HEADER; 6810 break; 6811 } 6812 6813 r_cc_send_cpt = r_cc_send_cpt.read() + 1; 6814 break; 6815 } 6816 //////////////////////////////// 6817 case CC_SEND_CAS_BRDCAST_HEADER: // send first flit broadcast-inval (from CAS FSM) 6818 { 6819 if (not p_dspin_m2p.read) break; 6820 r_cc_send_fsm = CC_SEND_CAS_BRDCAST_NLINE; 6821 break; 6822 } 6823 /////////////////////////////// 6824 case CC_SEND_CAS_BRDCAST_NLINE: // send second flit broadcast-inval (from CAS FSM) 7057 { 7058 if (m_write_to_cc_send_inst_fifo.rok()) 6825 7059 { 6826 7060 if (not p_dspin_m2p.read) break; 6827 7061 // <Activity Counters> 6828 m_cpt_binval++; 7062 if (is_local_req(m_write_to_cc_send_srcid_fifo.read())) 7063 { 7064 m_cpt_update_local++; 7065 } 7066 else 7067 { 7068 m_cpt_update_remote++; 7069 } 7070 // 2 flits for multi update 7071 m_cpt_update_cost += 2 * req_distance(m_write_to_cc_send_srcid_fifo.read()); 6829 7072 // </Activity Counters> 6830 7073 6831 r_cas_to_cc_send_brdcast_req = false; 6832 r_cc_send_fsm = CC_SEND_CAS_IDLE; 7074 r_cc_send_fsm = CC_SEND_WRITE_UPDT_NLINE; 7075 break; 7076 } 7077 7078 if (r_write_to_cc_send_multi_req.read()) 7079 { 7080 r_write_to_cc_send_multi_req = false; 7081 } 7082 7083 // <Activity Counters> 7084 m_cpt_update++; 7085 // </Activity Counters> 7086 r_cc_send_fsm = CC_SEND_WRITE_IDLE; 7087 break; 7088 } 7089 ////////////////////////////// 7090 case CC_SEND_WRITE_UPDT_NLINE: // send second flit for a multi-update (from WRITE FSM) 7091 { 7092 if (not p_dspin_m2p.read) break; 7093 7094 r_cc_send_cpt = 0; 7095 r_cc_send_fsm = CC_SEND_WRITE_UPDT_DATA; 6833 7096 6834 7097 #if DEBUG_MEMC_CC_SEND 6835 if (m_debug) 6836 std::cout << " <MEMC " << name() 6837 << " CC_SEND_CAS_BRDCAST_NLINE> Broadcast-Inval for address: " 6838 << r_cas_to_cc_send_nline.read()*m_words*4 << std::endl; 6839 #endif 7098 if (m_debug) 7099 { 7100 std::cout << " <MEMC " << name() 7101 << " CC_SEND_WRITE_UPDT_NLINE> Multicast-Update for address " 7102 << r_write_to_cc_send_nline.read() * m_words * 4 << std::endl; 7103 } 7104 #endif 7105 break; 7106 } 7107 ///////////////////////////// 7108 case CC_SEND_WRITE_UPDT_DATA: // send data flits for multi-update (from WRITE FSM) 7109 { 7110 if (not p_dspin_m2p.read) break; 7111 if (r_cc_send_cpt.read() == r_write_to_cc_send_count.read()) 7112 { 7113 write_to_cc_send_fifo_get = true; 7114 r_cc_send_fsm = CC_SEND_WRITE_UPDT_HEADER; 6840 7115 break; 6841 7116 } 6842 ///////////////////////////// 7117 7118 r_cc_send_cpt = r_cc_send_cpt.read() + 1; 7119 break; 7120 } 7121 //////////////////////////////// 7122 case CC_SEND_CAS_BRDCAST_HEADER: // send first flit broadcast-inval (from CAS FSM) 7123 { 7124 if (not p_dspin_m2p.read) break; 7125 r_cc_send_fsm = CC_SEND_CAS_BRDCAST_NLINE; 7126 break; 7127 } 7128 /////////////////////////////// 7129 case CC_SEND_CAS_BRDCAST_NLINE: // send second flit broadcast-inval (from CAS FSM) 7130 { 7131 if (not p_dspin_m2p.read) break; 7132 // <Activity Counters> 7133 m_cpt_binval++; 7134 // </Activity Counters> 7135 7136 r_cas_to_cc_send_brdcast_req = false; 7137 r_cc_send_fsm = CC_SEND_CAS_IDLE; 7138 7139 #if DEBUG_MEMC_CC_SEND 7140 if (m_debug) 7141 { 7142 std::cout << " <MEMC " << name() 7143 << " CC_SEND_CAS_BRDCAST_NLINE> Broadcast-Inval for address: " 7144 << r_cas_to_cc_send_nline.read() * m_words * 4 << std::endl; 7145 } 7146 #endif 7147 break; 7148 } 7149 ///////////////////////////// 6843 7150 case CC_SEND_CAS_UPDT_HEADER: // send first flit for a multi-update (from CAS FSM) 6844 { 6845 if (m_cas_to_cc_send_inst_fifo.rok()) 6846 { 6847 if (not p_dspin_m2p.read) break; 6848 // <Activity Counters> 6849 if (is_local_req(m_cas_to_cc_send_srcid_fifo.read())) 6850 { 6851 m_cpt_update_local++; 6852 } 6853 else 6854 { 6855 m_cpt_update_remote++; 6856 } 6857 // 2 flits for multi update 6858 m_cpt_update_cost += 2 * req_distance(m_cas_to_cc_send_srcid_fifo.read()); 6859 // </Activity Counters> 6860 r_cc_send_fsm = CC_SEND_CAS_UPDT_NLINE; 6861 break; 6862 } 6863 6864 // no more packets to send for the multi-update 6865 if (r_cas_to_cc_send_multi_req.read()) 6866 { 6867 r_cas_to_cc_send_multi_req = false; 6868 } 6869 7151 { 7152 if (m_cas_to_cc_send_inst_fifo.rok()) 7153 { 7154 if (not p_dspin_m2p.read) break; 6870 7155 // <Activity Counters> 6871 m_cpt_update++; 7156 if (is_local_req(m_cas_to_cc_send_srcid_fifo.read())) 7157 { 7158 m_cpt_update_local++; 7159 } 7160 else 7161 { 7162 m_cpt_update_remote++; 7163 } 7164 // 2 flits for multi update 7165 m_cpt_update_cost += 2 * req_distance(m_cas_to_cc_send_srcid_fifo.read()); 6872 7166 // </Activity Counters> 6873 r_cc_send_fsm = CC_SEND_CAS_ IDLE;7167 r_cc_send_fsm = CC_SEND_CAS_UPDT_NLINE; 6874 7168 break; 6875 7169 } 6876 //////////////////////////// 7170 7171 // no more packets to send for the multi-update 7172 if (r_cas_to_cc_send_multi_req.read()) 7173 { 7174 r_cas_to_cc_send_multi_req = false; 7175 } 7176 7177 // <Activity Counters> 7178 m_cpt_update++; 7179 // </Activity Counters> 7180 r_cc_send_fsm = CC_SEND_CAS_IDLE; 7181 break; 7182 } 7183 //////////////////////////// 6877 7184 case CC_SEND_CAS_UPDT_NLINE: // send second flit for a multi-update (from CAS FSM) 6878 {6879 if (not p_dspin_m2p.read) break;6880 r_cc_send_cpt = 0;6881 r_cc_send_fsm = CC_SEND_CAS_UPDT_DATA;7185 { 7186 if (not p_dspin_m2p.read) break; 7187 r_cc_send_cpt = 0; 7188 r_cc_send_fsm = CC_SEND_CAS_UPDT_DATA; 6882 7189 6883 7190 #if DEBUG_MEMC_CC_SEND 6884 if (m_debug) 6885 std::cout << " <MEMC " << name() 6886 << " CC_SEND_CAS_UPDT_NLINE> Multicast-Update for address " 6887 << r_cas_to_cc_send_nline.read()*m_words*4 << std::endl; 6888 #endif 7191 if (m_debug) 7192 { 7193 std::cout << " <MEMC " << name() 7194 << " CC_SEND_CAS_UPDT_NLINE> Multicast-Update for address " 7195 << r_cas_to_cc_send_nline.read() * m_words * 4 << std::endl; 7196 } 7197 #endif 7198 break; 7199 } 7200 /////////////////////////// 7201 case CC_SEND_CAS_UPDT_DATA: // send first data for a multi-update (from CAS FSM) 7202 { 7203 if (not p_dspin_m2p.read) break; 7204 7205 if (r_cas_to_cc_send_is_long.read()) 7206 { 7207 r_cc_send_fsm = CC_SEND_CAS_UPDT_DATA_HIGH; 6889 7208 break; 6890 7209 } 6891 /////////////////////////// 6892 case CC_SEND_CAS_UPDT_DATA: // send first data for a multi-update (from CAS FSM) 6893 { 6894 if (not p_dspin_m2p.read) break; 6895 6896 if (r_cas_to_cc_send_is_long.read()) 6897 { 6898 r_cc_send_fsm = CC_SEND_CAS_UPDT_DATA_HIGH; 6899 break; 6900 } 6901 6902 cas_to_cc_send_fifo_get = true; 6903 r_cc_send_fsm = CC_SEND_CAS_UPDT_HEADER; 6904 break; 6905 } 6906 //////////////////////////////// 7210 7211 cas_to_cc_send_fifo_get = true; 7212 r_cc_send_fsm = CC_SEND_CAS_UPDT_HEADER; 7213 break; 7214 } 7215 //////////////////////////////// 6907 7216 case CC_SEND_CAS_UPDT_DATA_HIGH: // send second data for multi-update (from CAS FSM) 6908 {6909 if (not p_dspin_m2p.read) break;6910 cas_to_cc_send_fifo_get = true;6911 r_cc_send_fsm = CC_SEND_CAS_UPDT_HEADER;6912 break;6913 }7217 { 7218 if (not p_dspin_m2p.read) break; 7219 cas_to_cc_send_fifo_get = true; 7220 r_cc_send_fsm = CC_SEND_CAS_UPDT_HEADER; 7221 break; 7222 } 6914 7223 } 6915 7224 // end switch r_cc_send_fsm … … 6922 7231 ////////////////////////////////////////////////////////////////////////////// 6923 7232 6924 //std::cout << std::endl << "cc_receive_fsm" << std::endl; 6925 6926 switch(r_cc_receive_fsm.read()) 7233 switch (r_cc_receive_fsm.read()) 6927 7234 { 6928 7235 ///////////////////// 6929 7236 case CC_RECEIVE_IDLE: 6930 { 6931 if (not p_dspin_p2m.write) break; 6932 6933 uint8_t type = 6934 DspinDhccpParam::dspin_get( 6935 p_dspin_p2m.data.read(), 6936 DspinDhccpParam::P2M_TYPE); 6937 6938 if ((type == DspinDhccpParam::TYPE_CLEANUP_DATA) or 6939 (type == DspinDhccpParam::TYPE_CLEANUP_INST)) 6940 { 6941 r_cc_receive_fsm = CC_RECEIVE_CLEANUP; 6942 break; 6943 } 6944 6945 if (type == DspinDhccpParam::TYPE_MULTI_ACK) 6946 { 6947 r_cc_receive_fsm = CC_RECEIVE_MULTI_ACK; 6948 break; 6949 } 6950 6951 assert(false and 6952 "VCI_MEM_CACHE ERROR in CC_RECEIVE : " 6953 "Illegal type in coherence request"); 6954 7237 { 7238 if (not p_dspin_p2m.write) break; 7239 7240 uint8_t type = 7241 DspinDhccpParam::dspin_get( 7242 p_dspin_p2m.data.read(), 7243 DspinDhccpParam::P2M_TYPE); 7244 7245 if ((type == DspinDhccpParam::TYPE_CLEANUP_DATA) or 7246 (type == DspinDhccpParam::TYPE_CLEANUP_INST)) 7247 { 7248 r_cc_receive_fsm = CC_RECEIVE_CLEANUP; 6955 7249 break; 6956 7250 } 6957 //////////////////////// 7251 7252 if (type == DspinDhccpParam::TYPE_MULTI_ACK) 7253 { 7254 r_cc_receive_fsm = CC_RECEIVE_MULTI_ACK; 7255 break; 7256 } 7257 7258 assert(false and 7259 "VCI_MEM_CACHE ERROR in CC_RECEIVE : " 7260 "Illegal type in coherence request"); 7261 7262 break; 7263 } 7264 //////////////////////// 6958 7265 case CC_RECEIVE_CLEANUP: 6959 { 6960 // write first CLEANUP flit in CC_RECEIVE to CLEANUP fifo 6961 6962 if (not p_dspin_p2m.write or not m_cc_receive_to_cleanup_fifo.wok()) 6963 break; 6964 6965 assert(not p_dspin_p2m.eop.read() and 6966 "VCI_MEM_CACHE ERROR in CC_RECEIVE : " 6967 "CLEANUP command must have two flits"); 6968 6969 cc_receive_to_cleanup_fifo_put = true; 6970 r_cc_receive_fsm = CC_RECEIVE_CLEANUP_EOP; 6971 6972 // <Activity Counters> 6973 uint32_t srcid = DspinDhccpParam::dspin_get( 6974 p_dspin_p2m.data.read(), 6975 DspinDhccpParam::CLEANUP_SRCID); 6976 6977 if (is_local_req(srcid)) { 6978 m_cpt_cleanup_local++; 6979 } 6980 else { 6981 m_cpt_cleanup_remote++; 6982 } 6983 // 2 flits for cleanup without data 6984 m_cpt_cleanup_cost += 2 * req_distance(srcid); 6985 // </Activity Counters> 6986 7266 { 7267 // write first CLEANUP flit in CC_RECEIVE to CLEANUP fifo 7268 7269 if (not p_dspin_p2m.write or not m_cc_receive_to_cleanup_fifo.wok()) 6987 7270 break; 6988 } 6989 //////////////////////////// 7271 7272 assert(not p_dspin_p2m.eop.read() and 7273 "VCI_MEM_CACHE ERROR in CC_RECEIVE : " 7274 "CLEANUP command must have two flits"); 7275 7276 cc_receive_to_cleanup_fifo_put = true; 7277 r_cc_receive_fsm = CC_RECEIVE_CLEANUP_EOP; 7278 7279 // <Activity Counters> 7280 uint32_t srcid = DspinDhccpParam::dspin_get( 7281 p_dspin_p2m.data.read(), 7282 DspinDhccpParam::CLEANUP_SRCID); 7283 7284 if (is_local_req(srcid)) 7285 { 7286 m_cpt_cleanup_local++; 7287 } 7288 else { 7289 m_cpt_cleanup_remote++; 7290 } 7291 // 2 flits for cleanup without data 7292 m_cpt_cleanup_cost += 2 * req_distance(srcid); 7293 // </Activity Counters> 7294 7295 break; 7296 } 7297 //////////////////////////// 6990 7298 case CC_RECEIVE_CLEANUP_EOP: 6991 { 6992 // write second CLEANUP flit in CC_RECEIVE to CLEANUP fifo 6993 6994 if (not p_dspin_p2m.write or not m_cc_receive_to_cleanup_fifo.wok()) 6995 break; 6996 6997 assert(p_dspin_p2m.eop.read() and 6998 "VCI_MEM_CACHE ERROR in CC_RECEIVE : " 6999 "CLEANUP command must have two flits"); 7000 7001 cc_receive_to_cleanup_fifo_put = true; 7002 r_cc_receive_fsm = CC_RECEIVE_IDLE; 7003 7299 { 7300 // write second CLEANUP flit in CC_RECEIVE to CLEANUP fifo 7301 7302 if (not p_dspin_p2m.write or not m_cc_receive_to_cleanup_fifo.wok()) 7004 7303 break; 7005 } 7006 7007 ////////////////////////// 7304 7305 assert(p_dspin_p2m.eop.read() and 7306 "VCI_MEM_CACHE ERROR in CC_RECEIVE : " 7307 "CLEANUP command must have two flits"); 7308 7309 cc_receive_to_cleanup_fifo_put = true; 7310 r_cc_receive_fsm = CC_RECEIVE_IDLE; 7311 7312 break; 7313 } 7314 7315 ////////////////////////// 7008 7316 case CC_RECEIVE_MULTI_ACK: 7009 { 7010 // write MULTI_ACK flit in CC_RECEIVE to MULTI_ACK fifo 7011 7012 // wait for a WOK in the CC_RECEIVE to MULTI_ACK fifo 7013 if (not p_dspin_p2m.write or not m_cc_receive_to_multi_ack_fifo.wok()) 7014 break; 7015 7016 assert(p_dspin_p2m.eop.read() and 7017 "VCI_MEM_CACHE ERROR in CC_RECEIVE : " 7018 "MULTI_ACK command must have one flit"); 7019 7020 cc_receive_to_multi_ack_fifo_put = true; 7021 r_cc_receive_fsm = CC_RECEIVE_IDLE; 7317 { 7318 // write MULTI_ACK flit in CC_RECEIVE to MULTI_ACK fifo 7319 7320 // wait for a WOK in the CC_RECEIVE to MULTI_ACK fifo 7321 if (not p_dspin_p2m.write or not m_cc_receive_to_multi_ack_fifo.wok()) 7022 7322 break; 7023 } 7323 7324 assert(p_dspin_p2m.eop.read() and 7325 "VCI_MEM_CACHE ERROR in CC_RECEIVE : " 7326 "MULTI_ACK command must have one flit"); 7327 7328 cc_receive_to_multi_ack_fifo_put = true; 7329 r_cc_receive_fsm = CC_RECEIVE_IDLE; 7330 break; 7331 } 7024 7332 } 7025 7333 … … 7042 7350 ////////////////////////////////////////////////////////////////////////// 7043 7351 7044 //std::cout << std::endl << "tgt_rsp_fsm" << std::endl; 7045 7046 switch(r_tgt_rsp_fsm.read()) 7352 switch (r_tgt_rsp_fsm.read()) 7047 7353 { 7048 7354 ///////////////////////// 7049 7355 case TGT_RSP_CONFIG_IDLE: // tgt_cmd requests have the highest priority 7050 {7051 if (r_tgt_cmd_to_tgt_rsp_req) r_tgt_rsp_fsm = TGT_RSP_TGT_CMD;7052 else if (r_read_to_tgt_rsp_req)7053 {7054 r_tgt_rsp_fsm = TGT_RSP_READ;7055 r_tgt_rsp_cpt = r_read_to_tgt_rsp_word.read();7056 }7057 else if (r_write_to_tgt_rsp_req) r_tgt_rsp_fsm = TGT_RSP_WRITE;7058 else if (r_cas_to_tgt_rsp_req) r_tgt_rsp_fsm = TGT_RSP_CAS;7059 else if (r_xram_rsp_to_tgt_rsp_req)7060 {7061 r_tgt_rsp_fsm = TGT_RSP_XRAM;7062 r_tgt_rsp_cpt = r_xram_rsp_to_tgt_rsp_word.read();7063 }7064 else if (r_multi_ack_to_tgt_rsp_req) r_tgt_rsp_fsm = TGT_RSP_MULTI_ACK;7065 else if (r_cleanup_to_tgt_rsp_req) r_tgt_rsp_fsm = TGT_RSP_CLEANUP;7066 else if (r_config_to_tgt_rsp_req) r_tgt_rsp_fsm = TGT_RSP_CONFIG;7067 break;7068 }7069 //////////////////////////7356 { 7357 if (r_tgt_cmd_to_tgt_rsp_req) r_tgt_rsp_fsm = TGT_RSP_TGT_CMD; 7358 else if (r_read_to_tgt_rsp_req) 7359 { 7360 r_tgt_rsp_fsm = TGT_RSP_READ; 7361 r_tgt_rsp_cpt = r_read_to_tgt_rsp_word.read(); 7362 } 7363 else if (r_write_to_tgt_rsp_req) r_tgt_rsp_fsm = TGT_RSP_WRITE; 7364 else if (r_cas_to_tgt_rsp_req) r_tgt_rsp_fsm = TGT_RSP_CAS; 7365 else if (r_xram_rsp_to_tgt_rsp_req) 7366 { 7367 r_tgt_rsp_fsm = TGT_RSP_XRAM; 7368 r_tgt_rsp_cpt = r_xram_rsp_to_tgt_rsp_word.read(); 7369 } 7370 else if (r_multi_ack_to_tgt_rsp_req) r_tgt_rsp_fsm = TGT_RSP_MULTI_ACK; 7371 else if (r_cleanup_to_tgt_rsp_req) r_tgt_rsp_fsm = TGT_RSP_CLEANUP; 7372 else if (r_config_to_tgt_rsp_req) r_tgt_rsp_fsm = TGT_RSP_CONFIG; 7373 break; 7374 } 7375 ////////////////////////// 7070 7376 case TGT_RSP_TGT_CMD_IDLE: // read requests have the highest priority 7071 {7072 if (r_read_to_tgt_rsp_req)7073 {7074 r_tgt_rsp_fsm = TGT_RSP_READ;7075 r_tgt_rsp_cpt = r_read_to_tgt_rsp_word.read();7076 }7077 else if (r_write_to_tgt_rsp_req) r_tgt_rsp_fsm = TGT_RSP_WRITE;7078 else if (r_cas_to_tgt_rsp_req) r_tgt_rsp_fsm = TGT_RSP_CAS;7079 else if (r_xram_rsp_to_tgt_rsp_req)7080 {7081 r_tgt_rsp_fsm = TGT_RSP_XRAM;7082 r_tgt_rsp_cpt = r_xram_rsp_to_tgt_rsp_word.read();7083 }7084 else if (r_multi_ack_to_tgt_rsp_req) r_tgt_rsp_fsm = TGT_RSP_MULTI_ACK;7085 else if (r_cleanup_to_tgt_rsp_req) r_tgt_rsp_fsm = TGT_RSP_CLEANUP;7086 else if (r_config_to_tgt_rsp_req) r_tgt_rsp_fsm = TGT_RSP_CONFIG;7087 else if (r_tgt_cmd_to_tgt_rsp_req) r_tgt_rsp_fsm = TGT_RSP_TGT_CMD;7088 break;7089 }7090 ///////////////////////7377 { 7378 if (r_read_to_tgt_rsp_req) 7379 { 7380 r_tgt_rsp_fsm = TGT_RSP_READ; 7381 r_tgt_rsp_cpt = r_read_to_tgt_rsp_word.read(); 7382 } 7383 else if (r_write_to_tgt_rsp_req) r_tgt_rsp_fsm = TGT_RSP_WRITE; 7384 else if (r_cas_to_tgt_rsp_req) r_tgt_rsp_fsm = TGT_RSP_CAS; 7385 else if (r_xram_rsp_to_tgt_rsp_req) 7386 { 7387 r_tgt_rsp_fsm = TGT_RSP_XRAM; 7388 r_tgt_rsp_cpt = r_xram_rsp_to_tgt_rsp_word.read(); 7389 } 7390 else if (r_multi_ack_to_tgt_rsp_req) r_tgt_rsp_fsm = TGT_RSP_MULTI_ACK; 7391 else if (r_cleanup_to_tgt_rsp_req) r_tgt_rsp_fsm = TGT_RSP_CLEANUP; 7392 else if (r_config_to_tgt_rsp_req) r_tgt_rsp_fsm = TGT_RSP_CONFIG; 7393 else if (r_tgt_cmd_to_tgt_rsp_req) r_tgt_rsp_fsm = TGT_RSP_TGT_CMD; 7394 break; 7395 } 7396 /////////////////////// 7091 7397 case TGT_RSP_READ_IDLE: // write requests have the highest priority 7092 {7093 if (r_write_to_tgt_rsp_req) r_tgt_rsp_fsm = TGT_RSP_WRITE;7094 else if (r_cas_to_tgt_rsp_req) r_tgt_rsp_fsm = TGT_RSP_CAS;7095 else if (r_xram_rsp_to_tgt_rsp_req)7096 {7097 r_tgt_rsp_fsm = TGT_RSP_XRAM;7098 r_tgt_rsp_cpt = r_xram_rsp_to_tgt_rsp_word.read();7099 }7100 else if (r_multi_ack_to_tgt_rsp_req) r_tgt_rsp_fsm = TGT_RSP_MULTI_ACK;7101 else if (r_cleanup_to_tgt_rsp_req) r_tgt_rsp_fsm = TGT_RSP_CLEANUP;7102 else if (r_config_to_tgt_rsp_req) r_tgt_rsp_fsm = TGT_RSP_CONFIG;7103 else if (r_tgt_cmd_to_tgt_rsp_req) r_tgt_rsp_fsm = TGT_RSP_TGT_CMD;7104 else if (r_read_to_tgt_rsp_req)7105 {7106 r_tgt_rsp_fsm = TGT_RSP_READ;7107 r_tgt_rsp_cpt = r_read_to_tgt_rsp_word.read();7108 }7109 break;7110 }7111 ////////////////////////7398 { 7399 if (r_write_to_tgt_rsp_req) r_tgt_rsp_fsm = TGT_RSP_WRITE; 7400 else if (r_cas_to_tgt_rsp_req) r_tgt_rsp_fsm = TGT_RSP_CAS; 7401 else if (r_xram_rsp_to_tgt_rsp_req) 7402 { 7403 r_tgt_rsp_fsm = TGT_RSP_XRAM; 7404 r_tgt_rsp_cpt = r_xram_rsp_to_tgt_rsp_word.read(); 7405 } 7406 else if (r_multi_ack_to_tgt_rsp_req) r_tgt_rsp_fsm = TGT_RSP_MULTI_ACK; 7407 else if (r_cleanup_to_tgt_rsp_req) r_tgt_rsp_fsm = TGT_RSP_CLEANUP; 7408 else if (r_config_to_tgt_rsp_req) r_tgt_rsp_fsm = TGT_RSP_CONFIG; 7409 else if (r_tgt_cmd_to_tgt_rsp_req) r_tgt_rsp_fsm = TGT_RSP_TGT_CMD; 7410 else if (r_read_to_tgt_rsp_req) 7411 { 7412 r_tgt_rsp_fsm = TGT_RSP_READ; 7413 r_tgt_rsp_cpt = r_read_to_tgt_rsp_word.read(); 7414 } 7415 break; 7416 } 7417 //////////////////////// 7112 7418 case TGT_RSP_WRITE_IDLE: // cas requests have the highest priority 7113 {7114 if (r_cas_to_tgt_rsp_req) r_tgt_rsp_fsm = TGT_RSP_CAS;7115 else if (r_xram_rsp_to_tgt_rsp_req)7116 {7117 r_tgt_rsp_fsm = TGT_RSP_XRAM;7118 r_tgt_rsp_cpt = r_xram_rsp_to_tgt_rsp_word.read();7119 }7120 else if (r_multi_ack_to_tgt_rsp_req) r_tgt_rsp_fsm = TGT_RSP_MULTI_ACK;7121 else if (r_cleanup_to_tgt_rsp_req) r_tgt_rsp_fsm = TGT_RSP_CLEANUP;7122 else if (r_config_to_tgt_rsp_req) r_tgt_rsp_fsm = TGT_RSP_CONFIG;7123 else if (r_tgt_cmd_to_tgt_rsp_req) r_tgt_rsp_fsm = TGT_RSP_TGT_CMD;7124 else if (r_read_to_tgt_rsp_req)7125 {7126 r_tgt_rsp_fsm = TGT_RSP_READ;7127 r_tgt_rsp_cpt = r_read_to_tgt_rsp_word.read();7128 }7129 else if (r_write_to_tgt_rsp_req) r_tgt_rsp_fsm = TGT_RSP_WRITE;7130 break;7131 }7132 ///////////////////////7419 { 7420 if (r_cas_to_tgt_rsp_req) r_tgt_rsp_fsm = TGT_RSP_CAS; 7421 else if (r_xram_rsp_to_tgt_rsp_req) 7422 { 7423 r_tgt_rsp_fsm = TGT_RSP_XRAM; 7424 r_tgt_rsp_cpt = r_xram_rsp_to_tgt_rsp_word.read(); 7425 } 7426 else if (r_multi_ack_to_tgt_rsp_req) r_tgt_rsp_fsm = TGT_RSP_MULTI_ACK; 7427 else if (r_cleanup_to_tgt_rsp_req) r_tgt_rsp_fsm = TGT_RSP_CLEANUP; 7428 else if (r_config_to_tgt_rsp_req) r_tgt_rsp_fsm = TGT_RSP_CONFIG; 7429 else if (r_tgt_cmd_to_tgt_rsp_req) r_tgt_rsp_fsm = TGT_RSP_TGT_CMD; 7430 else if (r_read_to_tgt_rsp_req) 7431 { 7432 r_tgt_rsp_fsm = TGT_RSP_READ; 7433 r_tgt_rsp_cpt = r_read_to_tgt_rsp_word.read(); 7434 } 7435 else if (r_write_to_tgt_rsp_req) r_tgt_rsp_fsm = TGT_RSP_WRITE; 7436 break; 7437 } 7438 /////////////////////// 7133 7439 case TGT_RSP_CAS_IDLE: // xram_rsp requests have the highest priority 7134 {7135 if (r_xram_rsp_to_tgt_rsp_req)7136 {7137 r_tgt_rsp_fsm = TGT_RSP_XRAM;7138 r_tgt_rsp_cpt = r_xram_rsp_to_tgt_rsp_word.read();7139 }7140 else if (r_multi_ack_to_tgt_rsp_req) r_tgt_rsp_fsm = TGT_RSP_MULTI_ACK ;7141 else if (r_cleanup_to_tgt_rsp_req) r_tgt_rsp_fsm = TGT_RSP_CLEANUP;7142 else if (r_config_to_tgt_rsp_req) r_tgt_rsp_fsm = TGT_RSP_CONFIG;7143 else if (r_tgt_cmd_to_tgt_rsp_req) r_tgt_rsp_fsm = TGT_RSP_TGT_CMD;7144 else if (r_read_to_tgt_rsp_req)7145 {7146 r_tgt_rsp_fsm = TGT_RSP_READ;7147 r_tgt_rsp_cpt = r_read_to_tgt_rsp_word.read();7148 }7149 else if (r_write_to_tgt_rsp_req) r_tgt_rsp_fsm = TGT_RSP_WRITE;7150 else if (r_cas_to_tgt_rsp_req) r_tgt_rsp_fsm = TGT_RSP_CAS ;7151 break;7152 }7153 ///////////////////////7440 { 7441 if (r_xram_rsp_to_tgt_rsp_req) 7442 { 7443 r_tgt_rsp_fsm = TGT_RSP_XRAM; 7444 r_tgt_rsp_cpt = r_xram_rsp_to_tgt_rsp_word.read(); 7445 } 7446 else if (r_multi_ack_to_tgt_rsp_req) r_tgt_rsp_fsm = TGT_RSP_MULTI_ACK ; 7447 else if (r_cleanup_to_tgt_rsp_req) r_tgt_rsp_fsm = TGT_RSP_CLEANUP; 7448 else if (r_config_to_tgt_rsp_req) r_tgt_rsp_fsm = TGT_RSP_CONFIG; 7449 else if (r_tgt_cmd_to_tgt_rsp_req) r_tgt_rsp_fsm = TGT_RSP_TGT_CMD; 7450 else if (r_read_to_tgt_rsp_req) 7451 { 7452 r_tgt_rsp_fsm = TGT_RSP_READ; 7453 r_tgt_rsp_cpt = r_read_to_tgt_rsp_word.read(); 7454 } 7455 else if (r_write_to_tgt_rsp_req) r_tgt_rsp_fsm = TGT_RSP_WRITE; 7456 else if (r_cas_to_tgt_rsp_req) r_tgt_rsp_fsm = TGT_RSP_CAS ; 7457 break; 7458 } 7459 /////////////////////// 7154 7460 case TGT_RSP_XRAM_IDLE: // multi ack requests have the highest priority 7155 {7156 7157 if (r_multi_ack_to_tgt_rsp_req) r_tgt_rsp_fsm = TGT_RSP_MULTI_ACK ;7158 else if (r_cleanup_to_tgt_rsp_req) r_tgt_rsp_fsm = TGT_RSP_CLEANUP;7159 else if (r_config_to_tgt_rsp_req) r_tgt_rsp_fsm = TGT_RSP_CONFIG;7160 else if (r_tgt_cmd_to_tgt_rsp_req) r_tgt_rsp_fsm = TGT_RSP_TGT_CMD;7161 else if (r_read_to_tgt_rsp_req)7162 {7163 r_tgt_rsp_fsm = TGT_RSP_READ;7164 r_tgt_rsp_cpt = r_read_to_tgt_rsp_word.read();7165 }7166 else if (r_write_to_tgt_rsp_req) r_tgt_rsp_fsm = TGT_RSP_WRITE;7167 else if (r_cas_to_tgt_rsp_req) r_tgt_rsp_fsm = TGT_RSP_CAS ;7168 else if (r_xram_rsp_to_tgt_rsp_req)7169 {7170 r_tgt_rsp_fsm = TGT_RSP_XRAM;7171 r_tgt_rsp_cpt = r_xram_rsp_to_tgt_rsp_word.read();7172 }7173 break;7174 }7175 ////////////////////////////7461 { 7462 7463 if (r_multi_ack_to_tgt_rsp_req) r_tgt_rsp_fsm = TGT_RSP_MULTI_ACK ; 7464 else if (r_cleanup_to_tgt_rsp_req) r_tgt_rsp_fsm = TGT_RSP_CLEANUP; 7465 else if (r_config_to_tgt_rsp_req) r_tgt_rsp_fsm = TGT_RSP_CONFIG; 7466 else if (r_tgt_cmd_to_tgt_rsp_req) r_tgt_rsp_fsm = TGT_RSP_TGT_CMD; 7467 else if (r_read_to_tgt_rsp_req) 7468 { 7469 r_tgt_rsp_fsm = TGT_RSP_READ; 7470 r_tgt_rsp_cpt = r_read_to_tgt_rsp_word.read(); 7471 } 7472 else if (r_write_to_tgt_rsp_req) r_tgt_rsp_fsm = TGT_RSP_WRITE; 7473 else if (r_cas_to_tgt_rsp_req) r_tgt_rsp_fsm = TGT_RSP_CAS ; 7474 else if (r_xram_rsp_to_tgt_rsp_req) 7475 { 7476 r_tgt_rsp_fsm = TGT_RSP_XRAM; 7477 r_tgt_rsp_cpt = r_xram_rsp_to_tgt_rsp_word.read(); 7478 } 7479 break; 7480 } 7481 //////////////////////////// 7176 7482 case TGT_RSP_MULTI_ACK_IDLE: // cleanup requests have the highest priority 7177 {7178 if (r_cleanup_to_tgt_rsp_req) r_tgt_rsp_fsm = TGT_RSP_CLEANUP;7179 else if (r_config_to_tgt_rsp_req) r_tgt_rsp_fsm = TGT_RSP_CONFIG;7180 else if (r_tgt_cmd_to_tgt_rsp_req) r_tgt_rsp_fsm = TGT_RSP_TGT_CMD;7181 else if (r_read_to_tgt_rsp_req)7182 {7183 r_tgt_rsp_fsm = TGT_RSP_READ;7184 r_tgt_rsp_cpt = r_read_to_tgt_rsp_word.read();7185 }7186 else if (r_write_to_tgt_rsp_req) r_tgt_rsp_fsm = TGT_RSP_WRITE;7187 else if (r_cas_to_tgt_rsp_req) r_tgt_rsp_fsm = TGT_RSP_CAS ;7188 else if (r_xram_rsp_to_tgt_rsp_req)7189 {7190 r_tgt_rsp_fsm = TGT_RSP_XRAM;7191 r_tgt_rsp_cpt = r_xram_rsp_to_tgt_rsp_word.read();7192 }7193 else if (r_multi_ack_to_tgt_rsp_req) r_tgt_rsp_fsm = TGT_RSP_MULTI_ACK;7194 break;7195 }7196 //////////////////////////7483 { 7484 if (r_cleanup_to_tgt_rsp_req) r_tgt_rsp_fsm = TGT_RSP_CLEANUP; 7485 else if (r_config_to_tgt_rsp_req) r_tgt_rsp_fsm = TGT_RSP_CONFIG; 7486 else if (r_tgt_cmd_to_tgt_rsp_req) r_tgt_rsp_fsm = TGT_RSP_TGT_CMD; 7487 else if (r_read_to_tgt_rsp_req) 7488 { 7489 r_tgt_rsp_fsm = TGT_RSP_READ; 7490 r_tgt_rsp_cpt = r_read_to_tgt_rsp_word.read(); 7491 } 7492 else if (r_write_to_tgt_rsp_req) r_tgt_rsp_fsm = TGT_RSP_WRITE; 7493 else if (r_cas_to_tgt_rsp_req) r_tgt_rsp_fsm = TGT_RSP_CAS ; 7494 else if (r_xram_rsp_to_tgt_rsp_req) 7495 { 7496 r_tgt_rsp_fsm = TGT_RSP_XRAM; 7497 r_tgt_rsp_cpt = r_xram_rsp_to_tgt_rsp_word.read(); 7498 } 7499 else if (r_multi_ack_to_tgt_rsp_req) r_tgt_rsp_fsm = TGT_RSP_MULTI_ACK; 7500 break; 7501 } 7502 ////////////////////////// 7197 7503 case TGT_RSP_CLEANUP_IDLE: // tgt cmd requests have the highest priority 7198 {7199 if (r_config_to_tgt_rsp_req) r_tgt_rsp_fsm = TGT_RSP_CONFIG;7200 else if (r_tgt_cmd_to_tgt_rsp_req) r_tgt_rsp_fsm = TGT_RSP_TGT_CMD;7201 else if (r_read_to_tgt_rsp_req)7202 {7203 r_tgt_rsp_fsm = TGT_RSP_READ;7204 r_tgt_rsp_cpt = r_read_to_tgt_rsp_word.read();7205 }7206 else if (r_write_to_tgt_rsp_req) r_tgt_rsp_fsm = TGT_RSP_WRITE;7207 else if (r_cas_to_tgt_rsp_req) r_tgt_rsp_fsm = TGT_RSP_CAS ;7208 else if (r_xram_rsp_to_tgt_rsp_req)7209 {7210 r_tgt_rsp_fsm = TGT_RSP_XRAM;7211 r_tgt_rsp_cpt = r_xram_rsp_to_tgt_rsp_word.read();7212 }7213 else if (r_multi_ack_to_tgt_rsp_req) r_tgt_rsp_fsm = TGT_RSP_MULTI_ACK ;7214 else if (r_cleanup_to_tgt_rsp_req) r_tgt_rsp_fsm = TGT_RSP_CLEANUP;7215 break;7216 }7217 ////////////////////7504 { 7505 if (r_config_to_tgt_rsp_req) r_tgt_rsp_fsm = TGT_RSP_CONFIG; 7506 else if (r_tgt_cmd_to_tgt_rsp_req) r_tgt_rsp_fsm = TGT_RSP_TGT_CMD; 7507 else if (r_read_to_tgt_rsp_req) 7508 { 7509 r_tgt_rsp_fsm = TGT_RSP_READ; 7510 r_tgt_rsp_cpt = r_read_to_tgt_rsp_word.read(); 7511 } 7512 else if (r_write_to_tgt_rsp_req) r_tgt_rsp_fsm = TGT_RSP_WRITE; 7513 else if (r_cas_to_tgt_rsp_req) r_tgt_rsp_fsm = TGT_RSP_CAS ; 7514 else if (r_xram_rsp_to_tgt_rsp_req) 7515 { 7516 r_tgt_rsp_fsm = TGT_RSP_XRAM; 7517 r_tgt_rsp_cpt = r_xram_rsp_to_tgt_rsp_word.read(); 7518 } 7519 else if (r_multi_ack_to_tgt_rsp_req) r_tgt_rsp_fsm = TGT_RSP_MULTI_ACK ; 7520 else if (r_cleanup_to_tgt_rsp_req) r_tgt_rsp_fsm = TGT_RSP_CLEANUP; 7521 break; 7522 } 7523 //////////////////// 7218 7524 case TGT_RSP_CONFIG: // send the response for a config transaction 7219 {7220 if (p_vci_tgt.rspack)7221 {7222 r_config_to_tgt_rsp_req = false;7223 r_tgt_rsp_fsm = TGT_RSP_CONFIG_IDLE;7525 { 7526 if (p_vci_tgt.rspack) 7527 { 7528 r_config_to_tgt_rsp_req = false; 7529 r_tgt_rsp_fsm = TGT_RSP_CONFIG_IDLE; 7224 7530 7225 7531 #if DEBUG_MEMC_TGT_RSP 7226 if (m_debug ) 7532 if (m_debug) 7533 { 7534 std::cout 7535 << " <MEMC " << name() 7536 << " TGT_RSP_CONFIG> Config transaction completed response" 7537 << " / rsrcid = " << std::hex << r_config_to_tgt_rsp_srcid.read() 7538 << " / rtrdid = " << r_config_to_tgt_rsp_trdid.read() 7539 << " / rpktid = " << r_config_to_tgt_rsp_pktid.read() 7540 << std::endl; 7541 } 7542 #endif 7543 } 7544 break; 7545 } 7546 ///////////////////// 7547 case TGT_RSP_TGT_CMD: // send the response for a configuration access 7548 { 7549 if (p_vci_tgt.rspack) 7550 { 7551 r_tgt_cmd_to_tgt_rsp_req = false; 7552 r_tgt_rsp_fsm = TGT_RSP_TGT_CMD_IDLE; 7553 7554 #if DEBUG_MEMC_TGT_RSP 7555 if (m_debug) 7556 { 7557 std::cout 7558 << " <MEMC " << name() 7559 << " TGT_RSP_TGT_CMD> Send response for a configuration access" 7560 << " / rsrcid = " << std::hex << r_tgt_cmd_to_tgt_rsp_srcid.read() 7561 << " / rtrdid = " << r_tgt_cmd_to_tgt_rsp_trdid.read() 7562 << " / rpktid = " << r_tgt_cmd_to_tgt_rsp_pktid.read() 7563 << " / error = " << r_tgt_cmd_to_tgt_rsp_error.read() 7564 << std::endl; 7565 } 7566 #endif 7567 } 7568 break; 7569 } 7570 ////////////////// 7571 case TGT_RSP_READ: // send the response to a read 7572 { 7573 if (p_vci_tgt.rspack) 7574 { 7575 7576 #if DEBUG_MEMC_TGT_RSP 7577 if (m_debug) 7578 { 7579 std::cout 7580 << " <MEMC " << name() << " TGT_RSP_READ> Read response" 7581 << " / rsrcid = " << std::hex << r_read_to_tgt_rsp_srcid.read() 7582 << " / rtrdid = " << r_read_to_tgt_rsp_trdid.read() 7583 << " / rpktid = " << r_read_to_tgt_rsp_pktid.read() 7584 << " / rdata = " << r_read_to_tgt_rsp_data[r_tgt_rsp_cpt.read()].read() 7585 << " / cpt = " << std::dec << r_tgt_rsp_cpt.read() << std::endl; 7586 } 7587 #endif 7588 7589 uint32_t last_word_idx = r_read_to_tgt_rsp_word.read() + 7590 r_read_to_tgt_rsp_length.read() - 1; 7591 bool is_last_word = (r_tgt_rsp_cpt.read() == last_word_idx); 7592 bool is_ll = ((r_read_to_tgt_rsp_pktid.read() & 0x7) == TYPE_LL); 7593 7594 if ((is_last_word and not is_ll) or 7595 (r_tgt_rsp_key_sent.read() and is_ll)) 7596 { 7597 // Last word in case of READ or second flit in case if LL 7598 r_tgt_rsp_key_sent = false; 7599 r_read_to_tgt_rsp_req = false; 7600 r_tgt_rsp_fsm = TGT_RSP_READ_IDLE; 7601 } 7602 else 7603 { 7604 if (is_ll) 7227 7605 { 7228 std::cout 7229 << " <MEMC " << name() 7230 << " TGT_RSP_CONFIG> Config transaction completed response" 7231 << " / rsrcid = " << std::hex << r_config_to_tgt_rsp_srcid.read() 7232 << " / rtrdid = " << r_config_to_tgt_rsp_trdid.read() 7233 << " / rpktid = " << r_config_to_tgt_rsp_pktid.read() 7234 << std::endl; 7235 } 7236 #endif 7237 } 7238 break; 7239 } 7240 ///////////////////// 7241 case TGT_RSP_TGT_CMD: // send the response for a configuration access 7242 { 7243 if (p_vci_tgt.rspack ) 7244 { 7245 r_tgt_cmd_to_tgt_rsp_req = false; 7246 r_tgt_rsp_fsm = TGT_RSP_TGT_CMD_IDLE; 7247 7248 #if DEBUG_MEMC_TGT_RSP 7249 if (m_debug ) 7250 { 7251 std::cout 7252 << " <MEMC " << name() 7253 << " TGT_RSP_TGT_CMD> Send response for a configuration access" 7254 << " / rsrcid = " << std::hex << r_tgt_cmd_to_tgt_rsp_srcid.read() 7255 << " / rtrdid = " << r_tgt_cmd_to_tgt_rsp_trdid.read() 7256 << " / rpktid = " << r_tgt_cmd_to_tgt_rsp_pktid.read() 7257 << " / error = " << r_tgt_cmd_to_tgt_rsp_error.read() 7258 << std::endl; 7259 } 7260 #endif 7261 } 7262 break; 7263 } 7264 ////////////////// 7265 case TGT_RSP_READ: // send the response to a read 7266 { 7267 if (p_vci_tgt.rspack ) 7268 { 7269 7270 #if DEBUG_MEMC_TGT_RSP 7271 if (m_debug ) 7272 { 7273 std::cout 7274 << " <MEMC " << name() << " TGT_RSP_READ> Read response" 7275 << " / rsrcid = " << std::hex << r_read_to_tgt_rsp_srcid.read() 7276 << " / rtrdid = " << r_read_to_tgt_rsp_trdid.read() 7277 << " / rpktid = " << r_read_to_tgt_rsp_pktid.read() 7278 << " / rdata = " << r_read_to_tgt_rsp_data[r_tgt_rsp_cpt.read()].read() 7279 << " / cpt = " << std::dec << r_tgt_rsp_cpt.read() << std::endl; 7280 } 7281 #endif 7282 7283 uint32_t last_word_idx = r_read_to_tgt_rsp_word.read() + 7284 r_read_to_tgt_rsp_length.read() - 1; 7285 bool is_last_word = (r_tgt_rsp_cpt.read() == last_word_idx); 7286 bool is_ll = ((r_read_to_tgt_rsp_pktid.read() & 0x7) == TYPE_LL); 7287 7288 if ((is_last_word and not is_ll) or 7289 (r_tgt_rsp_key_sent.read() and is_ll)) 7290 { 7291 // Last word in case of READ or second flit in case if LL 7292 r_tgt_rsp_key_sent = false; 7293 r_read_to_tgt_rsp_req = false; 7294 r_tgt_rsp_fsm = TGT_RSP_READ_IDLE; 7606 r_tgt_rsp_key_sent = true; // Send second flit of ll 7295 7607 } 7296 7608 else 7297 7609 { 7298 if (is_ll) 7299 { 7300 r_tgt_rsp_key_sent = true; // Send second flit of ll 7301 } 7302 else 7303 { 7304 r_tgt_rsp_cpt = r_tgt_rsp_cpt.read() + 1; // Send next word of read 7305 } 7610 r_tgt_rsp_cpt = r_tgt_rsp_cpt.read() + 1; // Send next word of read 7306 7611 } 7307 7612 } 7308 break; 7309 } 7310 ////////////////// 7613 } 7614 break; 7615 } 7616 ////////////////// 7311 7617 case TGT_RSP_WRITE: // send the write acknowledge 7312 {7313 if (p_vci_tgt.rspack)7314 {7618 { 7619 if (p_vci_tgt.rspack) 7620 { 7315 7621 7316 7622 #if DEBUG_MEMC_TGT_RSP 7317 if (m_debug) 7318 std::cout << " <MEMC " << name() << " TGT_RSP_WRITE> Write response" 7319 << " / rsrcid = " << std::hex << r_write_to_tgt_rsp_srcid.read() 7320 << " / rtrdid = " << r_write_to_tgt_rsp_trdid.read() 7321 << " / rpktid = " << r_write_to_tgt_rsp_pktid.read() << std::endl; 7322 #endif 7323 r_tgt_rsp_fsm = TGT_RSP_WRITE_IDLE; 7324 r_write_to_tgt_rsp_req = false; 7325 } 7326 break; 7327 } 7328 ///////////////////// 7623 if (m_debug) 7624 { 7625 std::cout << " <MEMC " << name() << " TGT_RSP_WRITE> Write response" 7626 << " / rsrcid = " << std::hex << r_write_to_tgt_rsp_srcid.read() 7627 << " / rtrdid = " << r_write_to_tgt_rsp_trdid.read() 7628 << " / rpktid = " << r_write_to_tgt_rsp_pktid.read() << std::endl; 7629 } 7630 #endif 7631 r_tgt_rsp_fsm = TGT_RSP_WRITE_IDLE; 7632 r_write_to_tgt_rsp_req = false; 7633 } 7634 break; 7635 } 7636 ///////////////////// 7329 7637 case TGT_RSP_CLEANUP: // pas clair pour moi (AG) 7330 {7331 if (p_vci_tgt.rspack)7332 {7638 { 7639 if (p_vci_tgt.rspack) 7640 { 7333 7641 7334 7642 #if DEBUG_MEMC_TGT_RSP 7335 if (m_debug) 7336 std::cout << " <MEMC " << name() << " TGT_RSP_CLEANUP> Cleanup response" 7337 << " / rsrcid = " << std::hex << r_cleanup_to_tgt_rsp_srcid.read() 7338 << " / rtrdid = " << r_cleanup_to_tgt_rsp_trdid.read() 7339 << " / rpktid = " << r_cleanup_to_tgt_rsp_pktid.read() << std::endl; 7340 #endif 7341 r_tgt_rsp_fsm = TGT_RSP_CLEANUP_IDLE; 7342 r_cleanup_to_tgt_rsp_req = false; 7343 } 7344 break; 7345 } 7346 ///////////////// 7643 if (m_debug) 7644 { 7645 std::cout << " <MEMC " << name() << " TGT_RSP_CLEANUP> Cleanup response" 7646 << " / rsrcid = " << std::hex << r_cleanup_to_tgt_rsp_srcid.read() 7647 << " / rtrdid = " << r_cleanup_to_tgt_rsp_trdid.read() 7648 << " / rpktid = " << r_cleanup_to_tgt_rsp_pktid.read() << std::endl; 7649 } 7650 #endif 7651 r_tgt_rsp_fsm = TGT_RSP_CLEANUP_IDLE; 7652 r_cleanup_to_tgt_rsp_req = false; 7653 } 7654 break; 7655 } 7656 ///////////////// 7347 7657 case TGT_RSP_CAS: // send one atomic word response 7348 {7349 if (p_vci_tgt.rspack)7350 {7658 { 7659 if (p_vci_tgt.rspack) 7660 { 7351 7661 7352 7662 #if DEBUG_MEMC_TGT_RSP 7353 if (m_debug) 7354 std::cout << " <MEMC " << name() << " TGT_RSP_CAS> CAS response" 7355 << " / rsrcid = " << std::hex << r_cas_to_tgt_rsp_srcid.read() 7356 << " / rtrdid = " << r_cas_to_tgt_rsp_trdid.read() 7357 << " / rpktid = " << r_cas_to_tgt_rsp_pktid.read() << std::endl; 7358 #endif 7359 r_tgt_rsp_fsm = TGT_RSP_CAS_IDLE; 7360 r_cas_to_tgt_rsp_req = false; 7361 } 7362 break; 7363 } 7364 ////////////////// 7663 if (m_debug) 7664 { 7665 std::cout << " <MEMC " << name() << " TGT_RSP_CAS> CAS response" 7666 << " / rsrcid = " << std::hex << r_cas_to_tgt_rsp_srcid.read() 7667 << " / rtrdid = " << r_cas_to_tgt_rsp_trdid.read() 7668 << " / rpktid = " << r_cas_to_tgt_rsp_pktid.read() << std::endl; 7669 } 7670 #endif 7671 r_tgt_rsp_fsm = TGT_RSP_CAS_IDLE; 7672 r_cas_to_tgt_rsp_req = false; 7673 } 7674 break; 7675 } 7676 ////////////////// 7365 7677 case TGT_RSP_XRAM: // send the response after XRAM access 7366 {7367 if (p_vci_tgt.rspack)7368 {7678 { 7679 if (p_vci_tgt.rspack) 7680 { 7369 7681 7370 7682 #if DEBUG_MEMC_TGT_RSP 7371 if (m_debug ) 7372 std::cout << " <MEMC " << name() << " TGT_RSP_XRAM> Response following XRAM access" 7373 << " / rsrcid = " << std::hex << r_xram_rsp_to_tgt_rsp_srcid.read() 7374 << " / rtrdid = " << r_xram_rsp_to_tgt_rsp_trdid.read() 7375 << " / rpktid = " << r_xram_rsp_to_tgt_rsp_pktid.read() 7376 << " / rdata = " << r_xram_rsp_to_tgt_rsp_data[r_tgt_rsp_cpt.read()].read() 7377 << " / cpt = " << std::dec << r_tgt_rsp_cpt.read() << std::endl; 7378 #endif 7379 uint32_t last_word_idx = r_xram_rsp_to_tgt_rsp_word.read() + 7380 r_xram_rsp_to_tgt_rsp_length.read() - 1; 7381 bool is_last_word = (r_tgt_rsp_cpt.read() == last_word_idx); 7382 bool is_ll = ((r_xram_rsp_to_tgt_rsp_pktid.read() & 0x7) == TYPE_LL); 7383 bool is_error = r_xram_rsp_to_tgt_rsp_rerror.read(); 7384 7385 if (((is_last_word or is_error) and not is_ll) or 7386 (r_tgt_rsp_key_sent.read() and is_ll)) 7683 if (m_debug) 7684 { 7685 std::cout << " <MEMC " << name() << " TGT_RSP_XRAM> Response following XRAM access" 7686 << " / rsrcid = " << std::hex << r_xram_rsp_to_tgt_rsp_srcid.read() 7687 << " / rtrdid = " << r_xram_rsp_to_tgt_rsp_trdid.read() 7688 << " / rpktid = " << r_xram_rsp_to_tgt_rsp_pktid.read() 7689 << " / rdata = " << r_xram_rsp_to_tgt_rsp_data[r_tgt_rsp_cpt.read()].read() 7690 << " / cpt = " << std::dec << r_tgt_rsp_cpt.read() << std::endl; 7691 } 7692 #endif 7693 uint32_t last_word_idx = r_xram_rsp_to_tgt_rsp_word.read() + 7694 r_xram_rsp_to_tgt_rsp_length.read() - 1; 7695 bool is_last_word = (r_tgt_rsp_cpt.read() == last_word_idx); 7696 bool is_ll = ((r_xram_rsp_to_tgt_rsp_pktid.read() & 0x7) == TYPE_LL); 7697 bool is_error = r_xram_rsp_to_tgt_rsp_rerror.read(); 7698 7699 if (((is_last_word or is_error) and not is_ll) or 7700 (r_tgt_rsp_key_sent.read() and is_ll)) 7701 { 7702 // Last word sent in case of READ or second flit sent in case if LL 7703 r_tgt_rsp_key_sent = false; 7704 r_xram_rsp_to_tgt_rsp_req = false; 7705 r_tgt_rsp_fsm = TGT_RSP_XRAM_IDLE; 7706 } 7707 else 7708 { 7709 if (is_ll) 7387 7710 { 7388 // Last word sent in case of READ or second flit sent in case if LL 7389 r_tgt_rsp_key_sent = false; 7390 r_xram_rsp_to_tgt_rsp_req = false; 7391 r_tgt_rsp_fsm = TGT_RSP_XRAM_IDLE; 7711 r_tgt_rsp_key_sent = true; // Send second flit of ll 7392 7712 } 7393 7713 else 7394 7714 { 7395 if (is_ll) 7396 { 7397 r_tgt_rsp_key_sent = true; // Send second flit of ll 7398 } 7399 else 7400 { 7401 r_tgt_rsp_cpt = r_tgt_rsp_cpt.read() + 1; // Send next word of read 7402 } 7715 r_tgt_rsp_cpt = r_tgt_rsp_cpt.read() + 1; // Send next word of read 7403 7716 } 7404 7717 } 7405 break; 7406 } 7407 /////////////////////// 7718 } 7719 break; 7720 } 7721 /////////////////////// 7408 7722 case TGT_RSP_MULTI_ACK: // send the write response after coherence transaction 7409 {7410 if (p_vci_tgt.rspack)7411 {7723 { 7724 if (p_vci_tgt.rspack) 7725 { 7412 7726 7413 7727 #if DEBUG_MEMC_TGT_RSP 7414 if (m_debug) 7415 std::cout << " <MEMC " << name() << " TGT_RSP_MULTI_ACK> Write response after coherence transaction" 7416 << " / rsrcid = " << std::hex << r_multi_ack_to_tgt_rsp_srcid.read() 7417 << " / rtrdid = " << r_multi_ack_to_tgt_rsp_trdid.read() 7418 << " / rpktid = " << r_multi_ack_to_tgt_rsp_pktid.read() << std::endl; 7419 #endif 7420 r_tgt_rsp_fsm = TGT_RSP_MULTI_ACK_IDLE; 7421 r_multi_ack_to_tgt_rsp_req = false; 7422 } 7423 break; 7424 } 7728 if (m_debug) 7729 { 7730 std::cout << " <MEMC " << name() << " TGT_RSP_MULTI_ACK> Write response after coherence transaction" 7731 << " / rsrcid = " << std::hex << r_multi_ack_to_tgt_rsp_srcid.read() 7732 << " / rtrdid = " << r_multi_ack_to_tgt_rsp_trdid.read() 7733 << " / rpktid = " << r_multi_ack_to_tgt_rsp_pktid.read() << std::endl; 7734 } 7735 #endif 7736 r_tgt_rsp_fsm = TGT_RSP_MULTI_ACK_IDLE; 7737 r_multi_ack_to_tgt_rsp_req = false; 7738 } 7739 break; 7740 } 7425 7741 } // end switch tgt_rsp_fsm 7426 7742 … … 7489 7805 // - The XRAM_RSP FSM initiates broadcast/multicast invalidate transaction and sets 7490 7806 // a new entry in the IVT 7491 // - The CONFIG FSM does the same thing as the XRAM_RSP FSM 7807 // - The CONFIG FSM does the same thing as the XRAM_RSP FSM 7492 7808 // - The CLEANUP FSM complete those trasactions and erase the IVT entry. 7493 7809 // The resource is always allocated. … … 7536 7852 /////////////////////// 7537 7853 case ALLOC_IVT_CLEANUP: // allocated to CLEANUP FSM 7538 if ((r_cleanup_fsm.read() != CLEANUP_IVT_LOCK ) and7854 if ((r_cleanup_fsm.read() != CLEANUP_IVT_LOCK) and 7539 7855 (r_cleanup_fsm.read() != CLEANUP_IVT_DECREMENT)) 7540 7856 { … … 7619 7935 ////////////////////// 7620 7936 case ALLOC_DIR_CONFIG: // allocated to CONFIG FSM 7621 if ((r_config_fsm.read() != CONFIG_DIR_REQ) and7622 (r_config_fsm.read()!= CONFIG_DIR_ACCESS) and7623 (r_config_fsm.read()!= CONFIG_TRT_LOCK) and7624 (r_config_fsm.read()!= CONFIG_TRT_SET) and7625 (r_config_fsm.read()!= CONFIG_IVT_LOCK))7937 if ((r_config_fsm.read() != CONFIG_DIR_REQ) and 7938 (r_config_fsm.read() != CONFIG_DIR_ACCESS) and 7939 (r_config_fsm.read() != CONFIG_TRT_LOCK) and 7940 (r_config_fsm.read() != CONFIG_TRT_SET) and 7941 (r_config_fsm.read() != CONFIG_IVT_LOCK)) 7626 7942 { 7627 7943 if (r_read_fsm.read() == READ_DIR_REQ) … … 7644 7960 //////////////////// 7645 7961 case ALLOC_DIR_READ: // allocated to READ FSM 7646 if (((r_read_fsm.read() != READ_DIR_REQ)and7647 (r_read_fsm.read() != READ_DIR_LOCK)and7648 (r_read_fsm.read() != READ_TRT_LOCK)and7649 (r_read_fsm.read()!= READ_HEAP_REQ))7650 or7651 ((r_read_fsm.read() == READ_TRT_LOCK)and7652 (r_alloc_trt_fsm.read()== ALLOC_TRT_READ)))7962 if (((r_read_fsm.read() != READ_DIR_REQ) and 7963 (r_read_fsm.read() != READ_DIR_LOCK) and 7964 (r_read_fsm.read() != READ_TRT_LOCK) and 7965 (r_read_fsm.read() != READ_HEAP_REQ)) 7966 or 7967 ((r_read_fsm.read() == READ_TRT_LOCK) and 7968 (r_alloc_trt_fsm.read() == ALLOC_TRT_READ))) 7653 7969 { 7654 7970 if (r_write_fsm.read() == WRITE_DIR_REQ) … … 7671 7987 ///////////////////// 7672 7988 case ALLOC_DIR_WRITE: // allocated to WRITE FSM 7673 if (((r_write_fsm.read() != WRITE_DIR_REQ)and7674 (r_write_fsm.read() != WRITE_DIR_LOCK)and7675 (r_write_fsm.read() != WRITE_BC_DIR_READ)and7676 (r_write_fsm.read() != WRITE_DIR_HIT)and7677 (r_write_fsm.read() != WRITE_BC_TRT_LOCK)and7678 (r_write_fsm.read() != WRITE_BC_IVT_LOCK)and7679 (r_write_fsm.read() != WRITE_MISS_TRT_LOCK)and7680 (r_write_fsm.read() != WRITE_UPT_LOCK)and7681 (r_write_fsm.read()!= WRITE_UPT_HEAP_LOCK))7682 or7683 ((r_write_fsm.read() == WRITE_UPT_HEAP_LOCK)and7684 (r_alloc_heap_fsm.read() == ALLOC_HEAP_WRITE))7685 or7686 ((r_write_fsm.read() == WRITE_MISS_TRT_LOCK)and7687 (r_alloc_trt_fsm.read() == ALLOC_TRT_WRITE)))7989 if (((r_write_fsm.read() != WRITE_DIR_REQ) and 7990 (r_write_fsm.read() != WRITE_DIR_LOCK) and 7991 (r_write_fsm.read() != WRITE_BC_DIR_READ) and 7992 (r_write_fsm.read() != WRITE_DIR_HIT) and 7993 (r_write_fsm.read() != WRITE_BC_TRT_LOCK) and 7994 (r_write_fsm.read() != WRITE_BC_IVT_LOCK) and 7995 (r_write_fsm.read() != WRITE_MISS_TRT_LOCK) and 7996 (r_write_fsm.read() != WRITE_UPT_LOCK) and 7997 (r_write_fsm.read() != WRITE_UPT_HEAP_LOCK)) 7998 or 7999 ((r_write_fsm.read() == WRITE_UPT_HEAP_LOCK) and 8000 (r_alloc_heap_fsm.read() == ALLOC_HEAP_WRITE)) 8001 or 8002 ((r_write_fsm.read() == WRITE_MISS_TRT_LOCK) and 8003 (r_alloc_trt_fsm.read() == ALLOC_TRT_WRITE))) 7688 8004 { 7689 8005 if (r_cas_fsm.read() == CAS_DIR_REQ) … … 7706 8022 /////////////////// 7707 8023 case ALLOC_DIR_CAS: // allocated to CAS FSM 7708 if (((r_cas_fsm.read() != CAS_DIR_REQ)and7709 (r_cas_fsm.read() != CAS_DIR_LOCK)and7710 (r_cas_fsm.read() != CAS_DIR_HIT_READ)and7711 (r_cas_fsm.read() != CAS_DIR_HIT_COMPARE)and7712 (r_cas_fsm.read() != CAS_DIR_HIT_WRITE)and7713 (r_cas_fsm.read() != CAS_BC_TRT_LOCK)and7714 (r_cas_fsm.read() != CAS_BC_IVT_LOCK)and7715 (r_cas_fsm.read() != CAS_MISS_TRT_LOCK)and7716 (r_cas_fsm.read() != CAS_UPT_LOCK)and7717 (r_cas_fsm.read()!= CAS_UPT_HEAP_LOCK))7718 or7719 ((r_cas_fsm.read() == CAS_UPT_HEAP_LOCK)and7720 (r_alloc_heap_fsm.read() == ALLOC_HEAP_CAS))7721 or7722 ((r_cas_fsm.read() == CAS_MISS_TRT_LOCK)and7723 (r_alloc_trt_fsm.read()== ALLOC_TRT_CAS)))8024 if (((r_cas_fsm.read() != CAS_DIR_REQ) and 8025 (r_cas_fsm.read() != CAS_DIR_LOCK) and 8026 (r_cas_fsm.read() != CAS_DIR_HIT_READ) and 8027 (r_cas_fsm.read() != CAS_DIR_HIT_COMPARE) and 8028 (r_cas_fsm.read() != CAS_DIR_HIT_WRITE) and 8029 (r_cas_fsm.read() != CAS_BC_TRT_LOCK) and 8030 (r_cas_fsm.read() != CAS_BC_IVT_LOCK) and 8031 (r_cas_fsm.read() != CAS_MISS_TRT_LOCK) and 8032 (r_cas_fsm.read() != CAS_UPT_LOCK) and 8033 (r_cas_fsm.read() != CAS_UPT_HEAP_LOCK)) 8034 or 8035 ((r_cas_fsm.read() == CAS_UPT_HEAP_LOCK) and 8036 (r_alloc_heap_fsm.read() == ALLOC_HEAP_CAS)) 8037 or 8038 ((r_cas_fsm.read() == CAS_MISS_TRT_LOCK) and 8039 (r_alloc_trt_fsm.read() == ALLOC_TRT_CAS))) 7724 8040 { 7725 8041 if (r_cleanup_fsm.read() == CLEANUP_DIR_REQ) 7726 r_alloc_dir_fsm = ALLOC_DIR_CLEANUP;8042 r_alloc_dir_fsm = ALLOC_DIR_CLEANUP; 7727 8043 7728 8044 else if (r_xram_rsp_fsm.read() == XRAM_RSP_DIR_LOCK) … … 7829 8145 r_alloc_trt_fsm = ALLOC_TRT_IXR_RSP; 7830 8146 7831 else if (r_config_fsm.read() == CONFIG_TRT_LOCK )8147 else if (r_config_fsm.read() == CONFIG_TRT_LOCK) 7832 8148 r_alloc_trt_fsm = ALLOC_TRT_CONFIG; 7833 8149 } … … 7859 8175 r_alloc_trt_fsm = ALLOC_TRT_IXR_RSP; 7860 8176 7861 else if (r_config_fsm.read() == CONFIG_TRT_LOCK )8177 else if (r_config_fsm.read() == CONFIG_TRT_LOCK) 7862 8178 r_alloc_trt_fsm = ALLOC_TRT_CONFIG; 7863 8179 … … 7888 8204 r_alloc_trt_fsm = ALLOC_TRT_IXR_RSP; 7889 8205 7890 else if (r_config_fsm.read() == CONFIG_TRT_LOCK )8206 else if (r_config_fsm.read() == CONFIG_TRT_LOCK) 7891 8207 r_alloc_trt_fsm = ALLOC_TRT_CONFIG; 7892 8208 … … 7916 8232 r_alloc_trt_fsm = ALLOC_TRT_IXR_RSP; 7917 8233 7918 else if (r_config_fsm.read() == CONFIG_TRT_LOCK )8234 else if (r_config_fsm.read() == CONFIG_TRT_LOCK) 7919 8235 r_alloc_trt_fsm = ALLOC_TRT_CONFIG; 7920 8236 … … 7944 8260 r_alloc_trt_fsm = ALLOC_TRT_IXR_RSP; 7945 8261 7946 else if (r_config_fsm.read() == CONFIG_TRT_LOCK )8262 else if (r_config_fsm.read() == CONFIG_TRT_LOCK) 7947 8263 r_alloc_trt_fsm = ALLOC_TRT_CONFIG; 7948 8264 … … 8208 8524 ///////////////////////////////////////////////////////////////////// 8209 8525 8210 m_cmd_read_addr_fifo.update( cmd_read_fifo_get, cmd_read_fifo_put,8526 m_cmd_read_addr_fifo.update(cmd_read_fifo_get, cmd_read_fifo_put, 8211 8527 p_vci_tgt.address.read()); 8212 m_cmd_read_length_fifo.update( cmd_read_fifo_get, cmd_read_fifo_put,8213 p_vci_tgt.plen.read() >> 2 );8214 m_cmd_read_srcid_fifo.update( cmd_read_fifo_get, cmd_read_fifo_put,8528 m_cmd_read_length_fifo.update(cmd_read_fifo_get, cmd_read_fifo_put, 8529 p_vci_tgt.plen.read() >> 2); 8530 m_cmd_read_srcid_fifo.update(cmd_read_fifo_get, cmd_read_fifo_put, 8215 8531 p_vci_tgt.srcid.read()); 8216 m_cmd_read_trdid_fifo.update( cmd_read_fifo_get, cmd_read_fifo_put,8532 m_cmd_read_trdid_fifo.update(cmd_read_fifo_get, cmd_read_fifo_put, 8217 8533 p_vci_tgt.trdid.read()); 8218 m_cmd_read_pktid_fifo.update( cmd_read_fifo_get, cmd_read_fifo_put,8534 m_cmd_read_pktid_fifo.update(cmd_read_fifo_get, cmd_read_fifo_put, 8219 8535 p_vci_tgt.pktid.read()); 8220 8536 … … 8223 8539 ///////////////////////////////////////////////////////////////////// 8224 8540 8225 m_cmd_write_addr_fifo.update( cmd_write_fifo_get, cmd_write_fifo_put,8541 m_cmd_write_addr_fifo.update(cmd_write_fifo_get, cmd_write_fifo_put, 8226 8542 (addr_t)p_vci_tgt.address.read()); 8227 m_cmd_write_eop_fifo.update( cmd_write_fifo_get, cmd_write_fifo_put,8543 m_cmd_write_eop_fifo.update(cmd_write_fifo_get, cmd_write_fifo_put, 8228 8544 p_vci_tgt.eop.read()); 8229 m_cmd_write_srcid_fifo.update( cmd_write_fifo_get, cmd_write_fifo_put,8545 m_cmd_write_srcid_fifo.update(cmd_write_fifo_get, cmd_write_fifo_put, 8230 8546 p_vci_tgt.srcid.read()); 8231 m_cmd_write_trdid_fifo.update( cmd_write_fifo_get, cmd_write_fifo_put,8547 m_cmd_write_trdid_fifo.update(cmd_write_fifo_get, cmd_write_fifo_put, 8232 8548 p_vci_tgt.trdid.read()); 8233 m_cmd_write_pktid_fifo.update( cmd_write_fifo_get, cmd_write_fifo_put,8549 m_cmd_write_pktid_fifo.update(cmd_write_fifo_get, cmd_write_fifo_put, 8234 8550 p_vci_tgt.pktid.read()); 8235 m_cmd_write_data_fifo.update( cmd_write_fifo_get, cmd_write_fifo_put,8551 m_cmd_write_data_fifo.update(cmd_write_fifo_get, cmd_write_fifo_put, 8236 8552 p_vci_tgt.wdata.read()); 8237 m_cmd_write_be_fifo.update( cmd_write_fifo_get, cmd_write_fifo_put,8553 m_cmd_write_be_fifo.update(cmd_write_fifo_get, cmd_write_fifo_put, 8238 8554 p_vci_tgt.be.read()); 8239 8555 … … 8242 8558 //////////////////////////////////////////////////////////////////////////////////// 8243 8559 8244 m_cmd_cas_addr_fifo.update( cmd_cas_fifo_get, cmd_cas_fifo_put,8560 m_cmd_cas_addr_fifo.update(cmd_cas_fifo_get, cmd_cas_fifo_put, 8245 8561 (addr_t)p_vci_tgt.address.read()); 8246 m_cmd_cas_eop_fifo.update( cmd_cas_fifo_get, cmd_cas_fifo_put,8562 m_cmd_cas_eop_fifo.update(cmd_cas_fifo_get, cmd_cas_fifo_put, 8247 8563 p_vci_tgt.eop.read()); 8248 m_cmd_cas_srcid_fifo.update( cmd_cas_fifo_get, cmd_cas_fifo_put,8564 m_cmd_cas_srcid_fifo.update(cmd_cas_fifo_get, cmd_cas_fifo_put, 8249 8565 p_vci_tgt.srcid.read()); 8250 m_cmd_cas_trdid_fifo.update( cmd_cas_fifo_get, cmd_cas_fifo_put,8566 m_cmd_cas_trdid_fifo.update(cmd_cas_fifo_get, cmd_cas_fifo_put, 8251 8567 p_vci_tgt.trdid.read()); 8252 m_cmd_cas_pktid_fifo.update( cmd_cas_fifo_get, cmd_cas_fifo_put,8568 m_cmd_cas_pktid_fifo.update(cmd_cas_fifo_get, cmd_cas_fifo_put, 8253 8569 p_vci_tgt.pktid.read()); 8254 m_cmd_cas_wdata_fifo.update( cmd_cas_fifo_get, cmd_cas_fifo_put,8570 m_cmd_cas_wdata_fifo.update(cmd_cas_fifo_get, cmd_cas_fifo_put, 8255 8571 p_vci_tgt.wdata.read()); 8256 8572 … … 8259 8575 //////////////////////////////////////////////////////////////////////////////////// 8260 8576 8261 m_cc_receive_to_cleanup_fifo.update( cc_receive_to_cleanup_fifo_get,8262 cc_receive_to_cleanup_fifo_put, 8577 m_cc_receive_to_cleanup_fifo.update(cc_receive_to_cleanup_fifo_get, 8578 cc_receive_to_cleanup_fifo_put, 8263 8579 p_dspin_p2m.data.read()); 8264 8580 … … 8267 8583 //////////////////////////////////////////////////////////////////////////////////// 8268 8584 8269 m_cc_receive_to_multi_ack_fifo.update( cc_receive_to_multi_ack_fifo_get,8270 cc_receive_to_multi_ack_fifo_put, 8585 m_cc_receive_to_multi_ack_fifo.update(cc_receive_to_multi_ack_fifo_get, 8586 cc_receive_to_multi_ack_fifo_put, 8271 8587 p_dspin_p2m.data.read()); 8272 8588 … … 8275 8591 //////////////////////////////////////////////////////////////////////////////////// 8276 8592 8277 m_write_to_cc_send_inst_fifo.update( write_to_cc_send_fifo_get,8593 m_write_to_cc_send_inst_fifo.update(write_to_cc_send_fifo_get, 8278 8594 write_to_cc_send_fifo_put, 8279 write_to_cc_send_fifo_inst );8280 m_write_to_cc_send_srcid_fifo.update( write_to_cc_send_fifo_get,8595 write_to_cc_send_fifo_inst); 8596 m_write_to_cc_send_srcid_fifo.update(write_to_cc_send_fifo_get, 8281 8597 write_to_cc_send_fifo_put, 8282 write_to_cc_send_fifo_srcid );8598 write_to_cc_send_fifo_srcid); 8283 8599 8284 8600 //////////////////////////////////////////////////////////////////////////////////// … … 8286 8602 //////////////////////////////////////////////////////////////////////////////////// 8287 8603 8288 m_config_to_cc_send_inst_fifo.update( config_to_cc_send_fifo_get,8604 m_config_to_cc_send_inst_fifo.update(config_to_cc_send_fifo_get, 8289 8605 config_to_cc_send_fifo_put, 8290 config_to_cc_send_fifo_inst );8291 m_config_to_cc_send_srcid_fifo.update( config_to_cc_send_fifo_get,8606 config_to_cc_send_fifo_inst); 8607 m_config_to_cc_send_srcid_fifo.update(config_to_cc_send_fifo_get, 8292 8608 config_to_cc_send_fifo_put, 8293 config_to_cc_send_fifo_srcid );8609 config_to_cc_send_fifo_srcid); 8294 8610 8295 8611 //////////////////////////////////////////////////////////////////////////////////// … … 8297 8613 //////////////////////////////////////////////////////////////////////////////////// 8298 8614 8299 m_xram_rsp_to_cc_send_inst_fifo.update( xram_rsp_to_cc_send_fifo_get,8615 m_xram_rsp_to_cc_send_inst_fifo.update(xram_rsp_to_cc_send_fifo_get, 8300 8616 xram_rsp_to_cc_send_fifo_put, 8301 xram_rsp_to_cc_send_fifo_inst );8302 m_xram_rsp_to_cc_send_srcid_fifo.update( xram_rsp_to_cc_send_fifo_get,8617 xram_rsp_to_cc_send_fifo_inst); 8618 m_xram_rsp_to_cc_send_srcid_fifo.update(xram_rsp_to_cc_send_fifo_get, 8303 8619 xram_rsp_to_cc_send_fifo_put, 8304 xram_rsp_to_cc_send_fifo_srcid );8620 xram_rsp_to_cc_send_fifo_srcid); 8305 8621 8306 8622 //////////////////////////////////////////////////////////////////////////////////// … … 8308 8624 //////////////////////////////////////////////////////////////////////////////////// 8309 8625 8310 m_cas_to_cc_send_inst_fifo.update( cas_to_cc_send_fifo_get,8626 m_cas_to_cc_send_inst_fifo.update(cas_to_cc_send_fifo_get, 8311 8627 cas_to_cc_send_fifo_put, 8312 cas_to_cc_send_fifo_inst );8313 m_cas_to_cc_send_srcid_fifo.update( cas_to_cc_send_fifo_get,8628 cas_to_cc_send_fifo_inst); 8629 m_cas_to_cc_send_srcid_fifo.update(cas_to_cc_send_fifo_get, 8314 8630 cas_to_cc_send_fifo_put, 8315 cas_to_cc_send_fifo_srcid );8631 cas_to_cc_send_fifo_srcid); 8316 8632 m_cpt_cycles++; 8317 8633 … … 8320 8636 // The three sources of (increment / decrement) are CONFIG / CLEANUP / IXR_RSP FSMs 8321 8637 //////////////////////////////////////////////////////////////////////////////////// 8322 if ( config_rsp_lines_incr and not8323 (config_rsp_lines_cleanup_decr or config_rsp_lines_ixr_rsp_decr) )8638 if (config_rsp_lines_incr and not 8639 (config_rsp_lines_cleanup_decr or config_rsp_lines_ixr_rsp_decr)) 8324 8640 { 8325 8641 r_config_rsp_lines = r_config_rsp_lines.read() + 1; 8326 8642 } 8327 if ( not config_rsp_lines_incr and8328 (config_rsp_lines_cleanup_decr or config_rsp_lines_ixr_rsp_decr) )8643 if (not config_rsp_lines_incr and 8644 (config_rsp_lines_cleanup_decr or config_rsp_lines_ixr_rsp_decr)) 8329 8645 { 8330 8646 r_config_rsp_lines = r_config_rsp_lines.read() - 1; … … 8338 8654 { 8339 8655 #if MONITOR_MEMCACHE_FSM == 1 8340 p_read_fsm.write (r_read_fsm.read());8341 p_write_fsm.write (r_write_fsm.read());8342 p_xram_rsp_fsm.write (r_xram_rsp_fsm.read());8343 p_cas_fsm.write (r_cas_fsm.read());8344 p_cleanup_fsm.write (r_cleanup_fsm.read());8345 p_config_fsm.write (r_config_fsm.read());8346 p_alloc_heap_fsm.write (r_alloc_heap_fsm.read());8347 p_alloc_dir_fsm.write (r_alloc_dir_fsm.read());8348 p_alloc_trt_fsm.write (r_alloc_trt_fsm.read());8349 p_alloc_upt_fsm.write (r_alloc_upt_fsm.read());8350 p_alloc_ivt_fsm.write (r_alloc_ivt_fsm.read());8351 p_tgt_cmd_fsm.write (r_tgt_cmd_fsm.read());8352 p_tgt_rsp_fsm.write (r_tgt_rsp_fsm.read());8353 p_ixr_cmd_fsm.write (r_ixr_cmd_fsm.read());8354 p_ixr_rsp_fsm.write (r_ixr_rsp_fsm.read());8355 p_cc_send_fsm.write (r_cc_send_fsm.read());8356 p_cc_receive_fsm.write (r_cc_receive_fsm.read());8357 p_multi_ack_fsm.write (r_multi_ack_fsm.read());8656 p_read_fsm.write (r_read_fsm.read()); 8657 p_write_fsm.write (r_write_fsm.read()); 8658 p_xram_rsp_fsm.write (r_xram_rsp_fsm.read()); 8659 p_cas_fsm.write (r_cas_fsm.read()); 8660 p_cleanup_fsm.write (r_cleanup_fsm.read()); 8661 p_config_fsm.write (r_config_fsm.read()); 8662 p_alloc_heap_fsm.write(r_alloc_heap_fsm.read()); 8663 p_alloc_dir_fsm.write (r_alloc_dir_fsm.read()); 8664 p_alloc_trt_fsm.write (r_alloc_trt_fsm.read()); 8665 p_alloc_upt_fsm.write (r_alloc_upt_fsm.read()); 8666 p_alloc_ivt_fsm.write (r_alloc_ivt_fsm.read()); 8667 p_tgt_cmd_fsm.write (r_tgt_cmd_fsm.read()); 8668 p_tgt_rsp_fsm.write (r_tgt_rsp_fsm.read()); 8669 p_ixr_cmd_fsm.write (r_ixr_cmd_fsm.read()); 8670 p_ixr_rsp_fsm.write (r_ixr_rsp_fsm.read()); 8671 p_cc_send_fsm.write (r_cc_send_fsm.read()); 8672 p_cc_receive_fsm.write(r_cc_receive_fsm.read()); 8673 p_multi_ack_fsm.write (r_multi_ack_fsm.read()); 8358 8674 #endif 8359 8675 … … 8364 8680 // DATA width is 8 bytes 8365 8681 // The following values are not transmitted to XRAM 8366 // p_vci_ixr.be 8367 // p_vci_ixr.pktid 8368 // p_vci_ixr.cons 8369 // p_vci_ixr.wrap 8370 // p_vci_ixr.contig 8371 // p_vci_ixr.clen 8372 // p_vci_ixr.cfixed 8682 // p_vci_ixr.be 8683 // p_vci_ixr.pktid 8684 // p_vci_ixr.cons 8685 // p_vci_ixr.wrap 8686 // p_vci_ixr.contig 8687 // p_vci_ixr.clen 8688 // p_vci_ixr.cfixed 8373 8689 8374 8690 p_vci_ixr.plen = 64; 8375 8691 p_vci_ixr.srcid = m_srcid_x; 8376 8692 p_vci_ixr.trdid = r_ixr_cmd_trdid.read(); 8377 p_vci_ixr.address = (addr_t)r_ixr_cmd_address.read() + (r_ixr_cmd_word.read() <<2);8378 p_vci_ixr.be = 0xFF; 8693 p_vci_ixr.address = (addr_t)r_ixr_cmd_address.read() + (r_ixr_cmd_word.read() << 2); 8694 p_vci_ixr.be = 0xFF; 8379 8695 p_vci_ixr.pktid = 0; 8380 8696 p_vci_ixr.cons = false; … … 8394 8710 if (r_ixr_cmd_get.read()) // GET 8395 8711 { 8396 p_vci_ixr.cmd = vci_param_ext::CMD_READ;8397 p_vci_ixr.wdata = 0;8398 p_vci_ixr.eop = true;8712 p_vci_ixr.cmd = vci_param_ext::CMD_READ; 8713 p_vci_ixr.wdata = 0; 8714 p_vci_ixr.eop = true; 8399 8715 } 8400 8716 else // PUT 8401 8717 { 8402 size_t word = r_ixr_cmd_word.read();8403 p_vci_ixr.cmd = vci_param_ext::CMD_WRITE;8404 p_vci_ixr.wdata = ((wide_data_t)(r_ixr_cmd_wdata[word].read())) |8405 ((wide_data_t) (r_ixr_cmd_wdata[word+1].read()) << 32);8406 p_vci_ixr.eop = (word == (m_words-2));8718 size_t word = r_ixr_cmd_word.read(); 8719 p_vci_ixr.cmd = vci_param_ext::CMD_WRITE; 8720 p_vci_ixr.wdata = ((wide_data_t)(r_ixr_cmd_wdata[word].read())) | 8721 ((wide_data_t) (r_ixr_cmd_wdata[word + 1].read()) << 32); 8722 p_vci_ixr.eop = (word == (m_words - 2)); 8407 8723 } 8408 8724 } … … 8418 8734 if ((r_ixr_rsp_fsm.read() == IXR_RSP_TRT_READ) or 8419 8735 (r_ixr_rsp_fsm.read() == IXR_RSP_TRT_ERASE)) 8420 { 8736 { 8421 8737 p_vci_ixr.rspack = (r_alloc_trt_fsm.read() == ALLOC_TRT_IXR_RSP); 8422 8738 } … … 8430 8746 //////////////////////////////////////////////////// 8431 8747 8432 switch ((tgt_cmd_fsm_state_e) r_tgt_cmd_fsm.read())8748 switch ((tgt_cmd_fsm_state_e) r_tgt_cmd_fsm.read()) 8433 8749 { 8434 8750 case TGT_CMD_IDLE: … … 8443 8759 addr_t cell = (addr_lsb / vci_param_int::B); 8444 8760 8445 size_t regr = cell & 8446 m_config_regr_idx_mask; 8761 size_t regr = cell & m_config_regr_idx_mask; 8447 8762 8448 8763 size_t func = (cell >> m_config_regr_width) & 8449 8764 m_config_func_idx_mask; 8450 8765 8451 switch (func)8766 switch (func) 8452 8767 { 8453 8768 case MEMC_CONFIG: … … 8491 8806 //////////////////////////////////////////////////// 8492 8807 8493 switch (r_tgt_rsp_fsm.read())8808 switch (r_tgt_rsp_fsm.read()) 8494 8809 { 8495 8810 case TGT_RSP_CONFIG_IDLE: … … 8501 8816 case TGT_RSP_MULTI_ACK_IDLE: 8502 8817 case TGT_RSP_CLEANUP_IDLE: 8503 {8504 p_vci_tgt.rspval= false;8505 p_vci_tgt.rsrcid= 0;8506 p_vci_tgt.rdata= 0;8507 p_vci_tgt.rpktid= 0;8508 p_vci_tgt.rtrdid= 0;8509 p_vci_tgt.rerror= 0;8510 p_vci_tgt.reop= false;8511 break;8512 }8818 { 8819 p_vci_tgt.rspval = false; 8820 p_vci_tgt.rsrcid = 0; 8821 p_vci_tgt.rdata = 0; 8822 p_vci_tgt.rpktid = 0; 8823 p_vci_tgt.rtrdid = 0; 8824 p_vci_tgt.rerror = 0; 8825 p_vci_tgt.reop = false; 8826 break; 8827 } 8513 8828 case TGT_RSP_CONFIG: 8514 { 8515 p_vci_tgt.rspval = true; 8516 p_vci_tgt.rdata = 0; 8517 p_vci_tgt.rsrcid = r_config_to_tgt_rsp_srcid.read(); 8518 p_vci_tgt.rtrdid = r_config_to_tgt_rsp_trdid.read(); 8519 p_vci_tgt.rpktid = r_config_to_tgt_rsp_pktid.read(); 8520 p_vci_tgt.rerror = r_config_to_tgt_rsp_error.read(); 8521 p_vci_tgt.reop = true; 8522 8523 break; 8524 } 8829 { 8830 p_vci_tgt.rspval = true; 8831 p_vci_tgt.rdata = 0; 8832 p_vci_tgt.rsrcid = r_config_to_tgt_rsp_srcid.read(); 8833 p_vci_tgt.rtrdid = r_config_to_tgt_rsp_trdid.read(); 8834 p_vci_tgt.rpktid = r_config_to_tgt_rsp_pktid.read(); 8835 p_vci_tgt.rerror = r_config_to_tgt_rsp_error.read(); 8836 p_vci_tgt.reop = true; 8837 break; 8838 } 8525 8839 case TGT_RSP_TGT_CMD: 8526 { 8527 p_vci_tgt.rspval = true; 8528 p_vci_tgt.rdata = r_tgt_cmd_to_tgt_rsp_rdata.read(); 8529 p_vci_tgt.rsrcid = r_tgt_cmd_to_tgt_rsp_srcid.read(); 8530 p_vci_tgt.rtrdid = r_tgt_cmd_to_tgt_rsp_trdid.read(); 8531 p_vci_tgt.rpktid = r_tgt_cmd_to_tgt_rsp_pktid.read(); 8532 p_vci_tgt.rerror = r_tgt_cmd_to_tgt_rsp_error.read(); 8533 p_vci_tgt.reop = true; 8534 8535 break; 8536 } 8840 { 8841 p_vci_tgt.rspval = true; 8842 p_vci_tgt.rdata = r_tgt_cmd_to_tgt_rsp_rdata.read(); 8843 p_vci_tgt.rsrcid = r_tgt_cmd_to_tgt_rsp_srcid.read(); 8844 p_vci_tgt.rtrdid = r_tgt_cmd_to_tgt_rsp_trdid.read(); 8845 p_vci_tgt.rpktid = r_tgt_cmd_to_tgt_rsp_pktid.read(); 8846 p_vci_tgt.rerror = r_tgt_cmd_to_tgt_rsp_error.read(); 8847 p_vci_tgt.reop = true; 8848 break; 8849 } 8537 8850 case TGT_RSP_READ: 8538 {8539 uint32_t last_word_idx = r_read_to_tgt_rsp_word.read() + r_read_to_tgt_rsp_length - 1;8540 bool is_last_word= (r_tgt_rsp_cpt.read() == last_word_idx);8541 bool is_ll= ((r_read_to_tgt_rsp_pktid.read() & 0x7) == TYPE_LL);8542 8543 p_vci_tgt.rspval = true;8544 8545 if (is_ll and not r_tgt_rsp_key_sent.read())8546 {8547 // LL response first flit8548 p_vci_tgt.rdata = r_read_to_tgt_rsp_ll_key.read();8549 }8550 else8551 {8552 // LL response second flit or READ response8553 p_vci_tgt.rdata = r_read_to_tgt_rsp_data[r_tgt_rsp_cpt.read()].read();8554 }8555 8556 p_vci_tgt.rsrcid= r_read_to_tgt_rsp_srcid.read();8557 p_vci_tgt.rtrdid= r_read_to_tgt_rsp_trdid.read();8558 p_vci_tgt.rpktid= r_read_to_tgt_rsp_pktid.read();8559 p_vci_tgt.rerror= 0;8560 p_vci_tgt.reop= (is_last_word and not is_ll) or (r_tgt_rsp_key_sent.read() and is_ll);8561 break;8562 }8851 { 8852 uint32_t last_word_idx = r_read_to_tgt_rsp_word.read() + r_read_to_tgt_rsp_length - 1; 8853 bool is_last_word = (r_tgt_rsp_cpt.read() == last_word_idx); 8854 bool is_ll = ((r_read_to_tgt_rsp_pktid.read() & 0x7) == TYPE_LL); 8855 8856 p_vci_tgt.rspval = true; 8857 8858 if (is_ll and not r_tgt_rsp_key_sent.read()) 8859 { 8860 // LL response first flit 8861 p_vci_tgt.rdata = r_read_to_tgt_rsp_ll_key.read(); 8862 } 8863 else 8864 { 8865 // LL response second flit or READ response 8866 p_vci_tgt.rdata = r_read_to_tgt_rsp_data[r_tgt_rsp_cpt.read()].read(); 8867 } 8868 8869 p_vci_tgt.rsrcid = r_read_to_tgt_rsp_srcid.read(); 8870 p_vci_tgt.rtrdid = r_read_to_tgt_rsp_trdid.read(); 8871 p_vci_tgt.rpktid = r_read_to_tgt_rsp_pktid.read(); 8872 p_vci_tgt.rerror = 0; 8873 p_vci_tgt.reop = (is_last_word and not is_ll) or (r_tgt_rsp_key_sent.read() and is_ll); 8874 break; 8875 } 8563 8876 8564 8877 case TGT_RSP_WRITE: 8565 p_vci_tgt.rspval = true;8878 p_vci_tgt.rspval = true; 8566 8879 if (((r_write_to_tgt_rsp_pktid.read() & 0x7) == TYPE_SC) and r_write_to_tgt_rsp_sc_fail.read()) 8567 p_vci_tgt.rdata = 1;8880 p_vci_tgt.rdata = 1; 8568 8881 else 8569 p_vci_tgt.rdata = 0;8570 p_vci_tgt.rsrcid = r_write_to_tgt_rsp_srcid.read();8571 p_vci_tgt.rtrdid = r_write_to_tgt_rsp_trdid.read();8572 p_vci_tgt.rpktid = r_write_to_tgt_rsp_pktid.read();8573 p_vci_tgt.rerror = 0;8574 p_vci_tgt.reop = true;8882 p_vci_tgt.rdata = 0; 8883 p_vci_tgt.rsrcid = r_write_to_tgt_rsp_srcid.read(); 8884 p_vci_tgt.rtrdid = r_write_to_tgt_rsp_trdid.read(); 8885 p_vci_tgt.rpktid = r_write_to_tgt_rsp_pktid.read(); 8886 p_vci_tgt.rerror = 0; 8887 p_vci_tgt.reop = true; 8575 8888 break; 8576 8889 8577 8890 case TGT_RSP_CLEANUP: 8578 p_vci_tgt.rspval = true;8579 p_vci_tgt.rdata = 0;8580 p_vci_tgt.rsrcid = r_cleanup_to_tgt_rsp_srcid.read();8581 p_vci_tgt.rtrdid = r_cleanup_to_tgt_rsp_trdid.read();8582 p_vci_tgt.rpktid = r_cleanup_to_tgt_rsp_pktid.read();8583 p_vci_tgt.rerror = 0; // Can be a CAS rsp8584 p_vci_tgt.reop = true;8891 p_vci_tgt.rspval = true; 8892 p_vci_tgt.rdata = 0; 8893 p_vci_tgt.rsrcid = r_cleanup_to_tgt_rsp_srcid.read(); 8894 p_vci_tgt.rtrdid = r_cleanup_to_tgt_rsp_trdid.read(); 8895 p_vci_tgt.rpktid = r_cleanup_to_tgt_rsp_pktid.read(); 8896 p_vci_tgt.rerror = 0; // Can be a CAS rsp 8897 p_vci_tgt.reop = true; 8585 8898 break; 8586 8899 8587 8900 case TGT_RSP_CAS: 8588 p_vci_tgt.rspval = true;8589 p_vci_tgt.rdata = r_cas_to_tgt_rsp_data.read();8590 p_vci_tgt.rsrcid = r_cas_to_tgt_rsp_srcid.read();8591 p_vci_tgt.rtrdid = r_cas_to_tgt_rsp_trdid.read();8592 p_vci_tgt.rpktid = r_cas_to_tgt_rsp_pktid.read();8593 p_vci_tgt.rerror = 0;8594 p_vci_tgt.reop = true;8901 p_vci_tgt.rspval = true; 8902 p_vci_tgt.rdata = r_cas_to_tgt_rsp_data.read(); 8903 p_vci_tgt.rsrcid = r_cas_to_tgt_rsp_srcid.read(); 8904 p_vci_tgt.rtrdid = r_cas_to_tgt_rsp_trdid.read(); 8905 p_vci_tgt.rpktid = r_cas_to_tgt_rsp_pktid.read(); 8906 p_vci_tgt.rerror = 0; 8907 p_vci_tgt.reop = true; 8595 8908 break; 8596 8909 … … 8602 8915 bool is_error = r_xram_rsp_to_tgt_rsp_rerror.read(); 8603 8916 8604 p_vci_tgt.rspval = true; 8605 8606 if (is_ll and not r_tgt_rsp_key_sent.read()) { 8917 p_vci_tgt.rspval = true; 8918 8919 if (is_ll and not r_tgt_rsp_key_sent.read()) 8920 { 8607 8921 // LL response first flit 8608 8922 p_vci_tgt.rdata = r_xram_rsp_to_tgt_rsp_ll_key.read(); … … 8613 8927 } 8614 8928 8615 p_vci_tgt.rsrcid = r_xram_rsp_to_tgt_rsp_srcid.read();8616 p_vci_tgt.rtrdid = r_xram_rsp_to_tgt_rsp_trdid.read();8617 p_vci_tgt.rpktid = r_xram_rsp_to_tgt_rsp_pktid.read();8618 p_vci_tgt.rerror = is_error;8619 p_vci_tgt.reop = (((is_last_word or is_error) and not is_ll) or8929 p_vci_tgt.rsrcid = r_xram_rsp_to_tgt_rsp_srcid.read(); 8930 p_vci_tgt.rtrdid = r_xram_rsp_to_tgt_rsp_trdid.read(); 8931 p_vci_tgt.rpktid = r_xram_rsp_to_tgt_rsp_pktid.read(); 8932 p_vci_tgt.rerror = is_error; 8933 p_vci_tgt.reop = (((is_last_word or is_error) and not is_ll) or 8620 8934 (r_tgt_rsp_key_sent.read() and is_ll)); 8621 8935 break; … … 8623 8937 8624 8938 case TGT_RSP_MULTI_ACK: 8625 p_vci_tgt.rspval = true;8626 p_vci_tgt.rdata = 0; // Can be a CAS or SC rsp8627 p_vci_tgt.rsrcid = r_multi_ack_to_tgt_rsp_srcid.read();8628 p_vci_tgt.rtrdid = r_multi_ack_to_tgt_rsp_trdid.read();8629 p_vci_tgt.rpktid = r_multi_ack_to_tgt_rsp_pktid.read();8630 p_vci_tgt.rerror = 0;8631 p_vci_tgt.reop = true;8939 p_vci_tgt.rspval = true; 8940 p_vci_tgt.rdata = 0; // Can be a CAS or SC rsp 8941 p_vci_tgt.rsrcid = r_multi_ack_to_tgt_rsp_srcid.read(); 8942 p_vci_tgt.rtrdid = r_multi_ack_to_tgt_rsp_trdid.read(); 8943 p_vci_tgt.rpktid = r_multi_ack_to_tgt_rsp_pktid.read(); 8944 p_vci_tgt.rerror = 0; 8945 p_vci_tgt.reop = true; 8632 8946 break; 8633 8947 } // end switch r_tgt_rsp_fsm … … 8651 8965 p_dspin_m2p.data = 0; 8652 8966 8653 switch (r_cc_send_fsm.read())8967 switch (r_cc_send_fsm.read()) 8654 8968 { 8655 8969 /////////////////////////// … … 8658 8972 case CC_SEND_WRITE_IDLE: 8659 8973 case CC_SEND_CAS_IDLE: 8660 {8661 break;8662 }8663 ////////////////////////////////8974 { 8975 break; 8976 } 8977 //////////////////////////////// 8664 8978 case CC_SEND_CONFIG_INVAL_HEADER: 8665 {8666 uint8_t multi_inval_type;8667 if (m_config_to_cc_send_inst_fifo.read())8668 {8669 multi_inval_type = DspinDhccpParam::TYPE_MULTI_INVAL_INST;8670 }8671 else8672 {8673 multi_inval_type = DspinDhccpParam::TYPE_MULTI_INVAL_DATA;8674 }8675 8676 uint64_t flit = 0;8677 uint64_t dest = m_config_to_cc_send_srcid_fifo.read() <<8678 (DspinDhccpParam::SRCID_WIDTH - vci_param_int::S);8679 8680 DspinDhccpParam::dspin_set(flit,8681 dest,8682 DspinDhccpParam::MULTI_INVAL_DEST);8683 8684 DspinDhccpParam::dspin_set(flit,8685 r_config_to_cc_send_trdid.read(),8686 DspinDhccpParam::MULTI_INVAL_UPDT_INDEX);8687 8688 DspinDhccpParam::dspin_set(flit,8689 multi_inval_type,8690 DspinDhccpParam::M2P_TYPE);8691 p_dspin_m2p.write = true;8692 p_dspin_m2p.data = flit;8693 break;8694 }8695 ////////////////////////////////8979 { 8980 uint8_t multi_inval_type; 8981 if (m_config_to_cc_send_inst_fifo.read()) 8982 { 8983 multi_inval_type = DspinDhccpParam::TYPE_MULTI_INVAL_INST; 8984 } 8985 else 8986 { 8987 multi_inval_type = DspinDhccpParam::TYPE_MULTI_INVAL_DATA; 8988 } 8989 8990 uint64_t flit = 0; 8991 uint64_t dest = m_config_to_cc_send_srcid_fifo.read() << 8992 (DspinDhccpParam::SRCID_WIDTH - vci_param_int::S); 8993 8994 DspinDhccpParam::dspin_set(flit, 8995 dest, 8996 DspinDhccpParam::MULTI_INVAL_DEST); 8997 8998 DspinDhccpParam::dspin_set(flit, 8999 r_config_to_cc_send_trdid.read(), 9000 DspinDhccpParam::MULTI_INVAL_UPDT_INDEX); 9001 9002 DspinDhccpParam::dspin_set(flit, 9003 multi_inval_type, 9004 DspinDhccpParam::M2P_TYPE); 9005 p_dspin_m2p.write = true; 9006 p_dspin_m2p.data = flit; 9007 break; 9008 } 9009 //////////////////////////////// 8696 9010 case CC_SEND_CONFIG_INVAL_NLINE: 8697 {8698 uint64_t flit = 0;8699 DspinDhccpParam::dspin_set(flit,8700 r_config_to_cc_send_nline.read(),8701 DspinDhccpParam::MULTI_INVAL_NLINE);8702 p_dspin_m2p.eop = true;8703 p_dspin_m2p.write = true;8704 p_dspin_m2p.data = flit;8705 break;8706 }8707 ///////////////////////////////////9011 { 9012 uint64_t flit = 0; 9013 DspinDhccpParam::dspin_set(flit, 9014 r_config_to_cc_send_nline.read(), 9015 DspinDhccpParam::MULTI_INVAL_NLINE); 9016 p_dspin_m2p.eop = true; 9017 p_dspin_m2p.write = true; 9018 p_dspin_m2p.data = flit; 9019 break; 9020 } 9021 /////////////////////////////////// 8708 9022 case CC_SEND_XRAM_RSP_INVAL_HEADER: 8709 {8710 if (not m_xram_rsp_to_cc_send_inst_fifo.rok()) break;8711 8712 uint8_t multi_inval_type;8713 if (m_xram_rsp_to_cc_send_inst_fifo.read())8714 {8715 multi_inval_type = DspinDhccpParam::TYPE_MULTI_INVAL_INST;8716 }8717 else8718 {8719 multi_inval_type = DspinDhccpParam::TYPE_MULTI_INVAL_DATA;8720 }8721 8722 uint64_t flit = 0;8723 uint64_t dest = m_xram_rsp_to_cc_send_srcid_fifo.read() <<8724 (DspinDhccpParam::SRCID_WIDTH - vci_param_int::S);8725 8726 DspinDhccpParam::dspin_set(flit,8727 dest,8728 DspinDhccpParam::MULTI_INVAL_DEST);8729 8730 DspinDhccpParam::dspin_set(flit,8731 r_xram_rsp_to_cc_send_trdid.read(),8732 DspinDhccpParam::MULTI_INVAL_UPDT_INDEX);8733 8734 DspinDhccpParam::dspin_set(flit,8735 multi_inval_type,8736 DspinDhccpParam::M2P_TYPE);8737 p_dspin_m2p.write = true;8738 p_dspin_m2p.data = flit;8739 break;8740 }8741 8742 //////////////////////////////////9023 { 9024 if (not m_xram_rsp_to_cc_send_inst_fifo.rok()) break; 9025 9026 uint8_t multi_inval_type; 9027 if (m_xram_rsp_to_cc_send_inst_fifo.read()) 9028 { 9029 multi_inval_type = DspinDhccpParam::TYPE_MULTI_INVAL_INST; 9030 } 9031 else 9032 { 9033 multi_inval_type = DspinDhccpParam::TYPE_MULTI_INVAL_DATA; 9034 } 9035 9036 uint64_t flit = 0; 9037 uint64_t dest = m_xram_rsp_to_cc_send_srcid_fifo.read() << 9038 (DspinDhccpParam::SRCID_WIDTH - vci_param_int::S); 9039 9040 DspinDhccpParam::dspin_set(flit, 9041 dest, 9042 DspinDhccpParam::MULTI_INVAL_DEST); 9043 9044 DspinDhccpParam::dspin_set(flit, 9045 r_xram_rsp_to_cc_send_trdid.read(), 9046 DspinDhccpParam::MULTI_INVAL_UPDT_INDEX); 9047 9048 DspinDhccpParam::dspin_set(flit, 9049 multi_inval_type, 9050 DspinDhccpParam::M2P_TYPE); 9051 p_dspin_m2p.write = true; 9052 p_dspin_m2p.data = flit; 9053 break; 9054 } 9055 9056 ////////////////////////////////// 8743 9057 case CC_SEND_XRAM_RSP_INVAL_NLINE: 8744 {8745 uint64_t flit = 0;8746 8747 DspinDhccpParam::dspin_set(flit,8748 r_xram_rsp_to_cc_send_nline.read(),8749 DspinDhccpParam::MULTI_INVAL_NLINE);8750 p_dspin_m2p.eop = true;8751 p_dspin_m2p.write = true;8752 p_dspin_m2p.data = flit;8753 break;8754 }8755 8756 /////////////////////////////////////9058 { 9059 uint64_t flit = 0; 9060 9061 DspinDhccpParam::dspin_set(flit, 9062 r_xram_rsp_to_cc_send_nline.read(), 9063 DspinDhccpParam::MULTI_INVAL_NLINE); 9064 p_dspin_m2p.eop = true; 9065 p_dspin_m2p.write = true; 9066 p_dspin_m2p.data = flit; 9067 break; 9068 } 9069 9070 ///////////////////////////////////// 8757 9071 case CC_SEND_CONFIG_BRDCAST_HEADER: 8758 9072 case CC_SEND_XRAM_RSP_BRDCAST_HEADER: 8759 9073 case CC_SEND_WRITE_BRDCAST_HEADER: 8760 9074 case CC_SEND_CAS_BRDCAST_HEADER: 8761 {8762 uint64_t flit = 0;8763 8764 DspinDhccpParam::dspin_set(flit,8765 m_broadcast_boundaries,8766 DspinDhccpParam::BROADCAST_BOX);8767 8768 DspinDhccpParam::dspin_set(flit,8769 1ULL,8770 DspinDhccpParam::M2P_BC);8771 p_dspin_m2p.write = true;8772 p_dspin_m2p.data = flit;8773 break;8774 }8775 ////////////////////////////////////9075 { 9076 uint64_t flit = 0; 9077 9078 DspinDhccpParam::dspin_set(flit, 9079 m_broadcast_boundaries, 9080 DspinDhccpParam::BROADCAST_BOX); 9081 9082 DspinDhccpParam::dspin_set(flit, 9083 1ULL, 9084 DspinDhccpParam::M2P_BC); 9085 p_dspin_m2p.write = true; 9086 p_dspin_m2p.data = flit; 9087 break; 9088 } 9089 //////////////////////////////////// 8776 9090 case CC_SEND_XRAM_RSP_BRDCAST_NLINE: 8777 {8778 uint64_t flit = 0;8779 DspinDhccpParam::dspin_set(flit,8780 r_xram_rsp_to_cc_send_nline.read(),8781 DspinDhccpParam::BROADCAST_NLINE);8782 p_dspin_m2p.write = true;8783 p_dspin_m2p.eop = true;8784 p_dspin_m2p.data = flit;8785 break;8786 }8787 //////////////////////////////////9091 { 9092 uint64_t flit = 0; 9093 DspinDhccpParam::dspin_set(flit, 9094 r_xram_rsp_to_cc_send_nline.read(), 9095 DspinDhccpParam::BROADCAST_NLINE); 9096 p_dspin_m2p.write = true; 9097 p_dspin_m2p.eop = true; 9098 p_dspin_m2p.data = flit; 9099 break; 9100 } 9101 ////////////////////////////////// 8788 9102 case CC_SEND_CONFIG_BRDCAST_NLINE: 8789 {8790 uint64_t flit = 0;8791 DspinDhccpParam::dspin_set(flit,8792 r_config_to_cc_send_nline.read(),8793 DspinDhccpParam::BROADCAST_NLINE);8794 p_dspin_m2p.write = true;8795 p_dspin_m2p.eop = true;8796 p_dspin_m2p.data = flit;8797 break;8798 }8799 /////////////////////////////////9103 { 9104 uint64_t flit = 0; 9105 DspinDhccpParam::dspin_set(flit, 9106 r_config_to_cc_send_nline.read(), 9107 DspinDhccpParam::BROADCAST_NLINE); 9108 p_dspin_m2p.write = true; 9109 p_dspin_m2p.eop = true; 9110 p_dspin_m2p.data = flit; 9111 break; 9112 } 9113 ///////////////////////////////// 8800 9114 case CC_SEND_WRITE_BRDCAST_NLINE: 8801 {8802 uint64_t flit = 0;8803 DspinDhccpParam::dspin_set(flit,8804 r_write_to_cc_send_nline.read(),8805 DspinDhccpParam::BROADCAST_NLINE);8806 p_dspin_m2p.write = true;8807 p_dspin_m2p.eop = true;8808 p_dspin_m2p.data = flit;8809 break;8810 }8811 ///////////////////////////////9115 { 9116 uint64_t flit = 0; 9117 DspinDhccpParam::dspin_set(flit, 9118 r_write_to_cc_send_nline.read(), 9119 DspinDhccpParam::BROADCAST_NLINE); 9120 p_dspin_m2p.write = true; 9121 p_dspin_m2p.eop = true; 9122 p_dspin_m2p.data = flit; 9123 break; 9124 } 9125 /////////////////////////////// 8812 9126 case CC_SEND_CAS_BRDCAST_NLINE: 8813 {8814 uint64_t flit = 0;8815 DspinDhccpParam::dspin_set(flit,8816 r_cas_to_cc_send_nline.read(),8817 DspinDhccpParam::BROADCAST_NLINE);8818 p_dspin_m2p.write = true;8819 p_dspin_m2p.eop = true;8820 p_dspin_m2p.data = flit;8821 break;8822 }8823 ///////////////////////////////9127 { 9128 uint64_t flit = 0; 9129 DspinDhccpParam::dspin_set(flit, 9130 r_cas_to_cc_send_nline.read(), 9131 DspinDhccpParam::BROADCAST_NLINE); 9132 p_dspin_m2p.write = true; 9133 p_dspin_m2p.eop = true; 9134 p_dspin_m2p.data = flit; 9135 break; 9136 } 9137 /////////////////////////////// 8824 9138 case CC_SEND_WRITE_UPDT_HEADER: 8825 {8826 if (not m_write_to_cc_send_inst_fifo.rok()) break;8827 8828 uint8_t multi_updt_type;8829 if (m_write_to_cc_send_inst_fifo.read())8830 {8831 multi_updt_type = DspinDhccpParam::TYPE_MULTI_UPDT_INST;8832 }8833 else8834 {8835 multi_updt_type = DspinDhccpParam::TYPE_MULTI_UPDT_DATA;8836 }8837 8838 uint64_t flit = 0;8839 uint64_t dest =8840 m_write_to_cc_send_srcid_fifo.read() <<8841 (DspinDhccpParam::SRCID_WIDTH - vci_param_int::S);8842 8843 DspinDhccpParam::dspin_set(8844 flit,8845 dest,8846 DspinDhccpParam::MULTI_UPDT_DEST);8847 8848 DspinDhccpParam::dspin_set(8849 flit,8850 r_write_to_cc_send_trdid.read(),8851 DspinDhccpParam::MULTI_UPDT_UPDT_INDEX);8852 8853 DspinDhccpParam::dspin_set(8854 flit,8855 multi_updt_type,8856 DspinDhccpParam::M2P_TYPE);8857 8858 p_dspin_m2p.write = true;8859 p_dspin_m2p.data = flit;8860 8861 break;8862 }8863 //////////////////////////////9139 { 9140 if (not m_write_to_cc_send_inst_fifo.rok()) break; 9141 9142 uint8_t multi_updt_type; 9143 if (m_write_to_cc_send_inst_fifo.read()) 9144 { 9145 multi_updt_type = DspinDhccpParam::TYPE_MULTI_UPDT_INST; 9146 } 9147 else 9148 { 9149 multi_updt_type = DspinDhccpParam::TYPE_MULTI_UPDT_DATA; 9150 } 9151 9152 uint64_t flit = 0; 9153 uint64_t dest = 9154 m_write_to_cc_send_srcid_fifo.read() << 9155 (DspinDhccpParam::SRCID_WIDTH - vci_param_int::S); 9156 9157 DspinDhccpParam::dspin_set( 9158 flit, 9159 dest, 9160 DspinDhccpParam::MULTI_UPDT_DEST); 9161 9162 DspinDhccpParam::dspin_set( 9163 flit, 9164 r_write_to_cc_send_trdid.read(), 9165 DspinDhccpParam::MULTI_UPDT_UPDT_INDEX); 9166 9167 DspinDhccpParam::dspin_set( 9168 flit, 9169 multi_updt_type, 9170 DspinDhccpParam::M2P_TYPE); 9171 9172 p_dspin_m2p.write = true; 9173 p_dspin_m2p.data = flit; 9174 9175 break; 9176 } 9177 ////////////////////////////// 8864 9178 case CC_SEND_WRITE_UPDT_NLINE: 8865 {8866 uint64_t flit = 0;8867 8868 DspinDhccpParam::dspin_set(8869 flit,8870 r_write_to_cc_send_index.read(),8871 DspinDhccpParam::MULTI_UPDT_WORD_INDEX);8872 8873 DspinDhccpParam::dspin_set(8874 flit,8875 r_write_to_cc_send_nline.read(),8876 DspinDhccpParam::MULTI_UPDT_NLINE);8877 8878 p_dspin_m2p.write = true;8879 p_dspin_m2p.data = flit;8880 8881 break;8882 }8883 /////////////////////////////9179 { 9180 uint64_t flit = 0; 9181 9182 DspinDhccpParam::dspin_set( 9183 flit, 9184 r_write_to_cc_send_index.read(), 9185 DspinDhccpParam::MULTI_UPDT_WORD_INDEX); 9186 9187 DspinDhccpParam::dspin_set( 9188 flit, 9189 r_write_to_cc_send_nline.read(), 9190 DspinDhccpParam::MULTI_UPDT_NLINE); 9191 9192 p_dspin_m2p.write = true; 9193 p_dspin_m2p.data = flit; 9194 9195 break; 9196 } 9197 ///////////////////////////// 8884 9198 case CC_SEND_WRITE_UPDT_DATA: 8885 { 8886 8887 uint8_t multi_updt_cpt = 8888 r_cc_send_cpt.read() + r_write_to_cc_send_index.read(); 8889 8890 uint8_t multi_updt_be = r_write_to_cc_send_be[multi_updt_cpt].read(); 8891 uint32_t multi_updt_data = r_write_to_cc_send_data[multi_updt_cpt].read(); 8892 8893 uint64_t flit = 0; 8894 8895 DspinDhccpParam::dspin_set( 8896 flit, 8897 multi_updt_be, 8898 DspinDhccpParam::MULTI_UPDT_BE); 8899 8900 DspinDhccpParam::dspin_set( 8901 flit, 8902 multi_updt_data, 8903 DspinDhccpParam::MULTI_UPDT_DATA); 8904 8905 p_dspin_m2p.write = true; 8906 p_dspin_m2p.eop = (r_cc_send_cpt.read() == r_write_to_cc_send_count.read()); 8907 p_dspin_m2p.data = flit; 8908 8909 break; 8910 } 8911 //////////////////////////// 9199 { 9200 9201 uint8_t multi_updt_cpt = r_cc_send_cpt.read() + r_write_to_cc_send_index.read(); 9202 uint8_t multi_updt_be = r_write_to_cc_send_be[multi_updt_cpt].read(); 9203 uint32_t multi_updt_data = r_write_to_cc_send_data[multi_updt_cpt].read(); 9204 9205 uint64_t flit = 0; 9206 9207 DspinDhccpParam::dspin_set( 9208 flit, 9209 multi_updt_be, 9210 DspinDhccpParam::MULTI_UPDT_BE); 9211 9212 DspinDhccpParam::dspin_set( 9213 flit, 9214 multi_updt_data, 9215 DspinDhccpParam::MULTI_UPDT_DATA); 9216 9217 p_dspin_m2p.write = true; 9218 p_dspin_m2p.eop = (r_cc_send_cpt.read() == r_write_to_cc_send_count.read()); 9219 p_dspin_m2p.data = flit; 9220 9221 break; 9222 } 9223 //////////////////////////// 8912 9224 case CC_SEND_CAS_UPDT_HEADER: 8913 {8914 if (not m_cas_to_cc_send_inst_fifo.rok()) break;8915 8916 uint8_t multi_updt_type;8917 if (m_cas_to_cc_send_inst_fifo.read())8918 {8919 multi_updt_type = DspinDhccpParam::TYPE_MULTI_UPDT_INST;8920 }8921 else8922 {8923 multi_updt_type = DspinDhccpParam::TYPE_MULTI_UPDT_DATA;8924 }8925 8926 uint64_t flit = 0;8927 uint64_t dest =8928 m_cas_to_cc_send_srcid_fifo.read() <<8929 (DspinDhccpParam::SRCID_WIDTH - vci_param_int::S);8930 8931 DspinDhccpParam::dspin_set(8932 flit,8933 dest,8934 DspinDhccpParam::MULTI_UPDT_DEST);8935 8936 DspinDhccpParam::dspin_set(8937 flit,8938 r_cas_to_cc_send_trdid.read(),8939 DspinDhccpParam::MULTI_UPDT_UPDT_INDEX);8940 8941 DspinDhccpParam::dspin_set(8942 flit,8943 multi_updt_type,8944 DspinDhccpParam::M2P_TYPE);8945 8946 p_dspin_m2p.write = true;8947 p_dspin_m2p.data = flit;8948 8949 break;8950 }8951 ////////////////////////////9225 { 9226 if (not m_cas_to_cc_send_inst_fifo.rok()) break; 9227 9228 uint8_t multi_updt_type; 9229 if (m_cas_to_cc_send_inst_fifo.read()) 9230 { 9231 multi_updt_type = DspinDhccpParam::TYPE_MULTI_UPDT_INST; 9232 } 9233 else 9234 { 9235 multi_updt_type = DspinDhccpParam::TYPE_MULTI_UPDT_DATA; 9236 } 9237 9238 uint64_t flit = 0; 9239 uint64_t dest = 9240 m_cas_to_cc_send_srcid_fifo.read() << 9241 (DspinDhccpParam::SRCID_WIDTH - vci_param_int::S); 9242 9243 DspinDhccpParam::dspin_set( 9244 flit, 9245 dest, 9246 DspinDhccpParam::MULTI_UPDT_DEST); 9247 9248 DspinDhccpParam::dspin_set( 9249 flit, 9250 r_cas_to_cc_send_trdid.read(), 9251 DspinDhccpParam::MULTI_UPDT_UPDT_INDEX); 9252 9253 DspinDhccpParam::dspin_set( 9254 flit, 9255 multi_updt_type, 9256 DspinDhccpParam::M2P_TYPE); 9257 9258 p_dspin_m2p.write = true; 9259 p_dspin_m2p.data = flit; 9260 9261 break; 9262 } 9263 //////////////////////////// 8952 9264 case CC_SEND_CAS_UPDT_NLINE: 8953 {8954 uint64_t flit = 0;8955 8956 DspinDhccpParam::dspin_set(8957 flit,8958 r_cas_to_cc_send_index.read(),8959 DspinDhccpParam::MULTI_UPDT_WORD_INDEX);8960 8961 DspinDhccpParam::dspin_set(8962 flit,8963 r_cas_to_cc_send_nline.read(),8964 DspinDhccpParam::MULTI_UPDT_NLINE);8965 8966 p_dspin_m2p.write = true;8967 p_dspin_m2p.data = flit;8968 8969 break;8970 }8971 ///////////////////////////9265 { 9266 uint64_t flit = 0; 9267 9268 DspinDhccpParam::dspin_set( 9269 flit, 9270 r_cas_to_cc_send_index.read(), 9271 DspinDhccpParam::MULTI_UPDT_WORD_INDEX); 9272 9273 DspinDhccpParam::dspin_set( 9274 flit, 9275 r_cas_to_cc_send_nline.read(), 9276 DspinDhccpParam::MULTI_UPDT_NLINE); 9277 9278 p_dspin_m2p.write = true; 9279 p_dspin_m2p.data = flit; 9280 9281 break; 9282 } 9283 /////////////////////////// 8972 9284 case CC_SEND_CAS_UPDT_DATA: 8973 {8974 uint64_t flit = 0;8975 8976 DspinDhccpParam::dspin_set(8977 flit,8978 0xF,8979 DspinDhccpParam::MULTI_UPDT_BE);8980 8981 DspinDhccpParam::dspin_set(8982 flit,8983 r_cas_to_cc_send_wdata.read(),8984 DspinDhccpParam::MULTI_UPDT_DATA);8985 8986 p_dspin_m2p.write = true;8987 p_dspin_m2p.eop = not r_cas_to_cc_send_is_long.read();8988 p_dspin_m2p.data = flit;8989 8990 break;8991 }8992 ////////////////////////////////9285 { 9286 uint64_t flit = 0; 9287 9288 DspinDhccpParam::dspin_set( 9289 flit, 9290 0xF, 9291 DspinDhccpParam::MULTI_UPDT_BE); 9292 9293 DspinDhccpParam::dspin_set( 9294 flit, 9295 r_cas_to_cc_send_wdata.read(), 9296 DspinDhccpParam::MULTI_UPDT_DATA); 9297 9298 p_dspin_m2p.write = true; 9299 p_dspin_m2p.eop = not r_cas_to_cc_send_is_long.read(); 9300 p_dspin_m2p.data = flit; 9301 9302 break; 9303 } 9304 //////////////////////////////// 8993 9305 case CC_SEND_CAS_UPDT_DATA_HIGH: 8994 {8995 uint64_t flit = 0;8996 8997 DspinDhccpParam::dspin_set(8998 flit,8999 0xF,9000 DspinDhccpParam::MULTI_UPDT_BE);9001 9002 DspinDhccpParam::dspin_set(9003 flit,9004 r_cas_to_cc_send_wdata_high.read(),9005 DspinDhccpParam::MULTI_UPDT_DATA);9006 9007 p_dspin_m2p.write = true;9008 p_dspin_m2p.eop = true;9009 p_dspin_m2p.data = flit;9010 9011 break;9012 }9306 { 9307 uint64_t flit = 0; 9308 9309 DspinDhccpParam::dspin_set( 9310 flit, 9311 0xF, 9312 DspinDhccpParam::MULTI_UPDT_BE); 9313 9314 DspinDhccpParam::dspin_set( 9315 flit, 9316 r_cas_to_cc_send_wdata_high.read(), 9317 DspinDhccpParam::MULTI_UPDT_DATA); 9318 9319 p_dspin_m2p.write = true; 9320 p_dspin_m2p.eop = true; 9321 p_dspin_m2p.data = flit; 9322 9323 break; 9324 } 9013 9325 } 9014 9326 … … 9068 9380 /////////////////////////////////////////////////////////////////// 9069 9381 // 9070 switch (r_cc_receive_fsm.read())9382 switch (r_cc_receive_fsm.read()) 9071 9383 { 9072 9384 case CC_RECEIVE_IDLE: 9073 {9074 p_dspin_p2m.read = false;9075 break;9076 }9385 { 9386 p_dspin_p2m.read = false; 9387 break; 9388 } 9077 9389 case CC_RECEIVE_CLEANUP: 9078 9390 case CC_RECEIVE_CLEANUP_EOP: 9079 {9080 p_dspin_p2m.read = m_cc_receive_to_cleanup_fifo.wok();9081 break;9082 }9391 { 9392 p_dspin_p2m.read = m_cc_receive_to_cleanup_fifo.wok(); 9393 break; 9394 } 9083 9395 case CC_RECEIVE_MULTI_ACK: 9084 {9085 p_dspin_p2m.read = m_cc_receive_to_multi_ack_fifo.wok();9086 break;9087 }9396 { 9397 p_dspin_p2m.read = m_cc_receive_to_multi_ack_fifo.wok(); 9398 break; 9399 } 9088 9400 } 9089 9401 // end switch r_cc_send_fsm
Note: See TracChangeset
for help on using the changeset viewer.
