- Timestamp:
- Sep 9, 2014, 6:40:02 PM (10 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 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 348 const bool 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( 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( 510 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( 514 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( 529 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() 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 623 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) 997 tmpl(void)::transition() 995 998 ////////////////////////////////// 996 999 { … … 998 1001 999 1002 // RESET 1000 if (! 1003 if (!p_resetn.read()) 1001 1004 { 1002 1005 … … 1054 1057 m_cmd_cas_eop_fifo.init() ; 1055 1058 1056 r_config_cmd 1057 r_config_lock 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) 1292 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 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 // Y : SUBTYPE ( LOCAL, REMOTE, OTHER )//1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 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 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 2101 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 2100 r_config_to_tgt_rsp_trdid 2101 r_config_to_tgt_rsp_pktid 2102 r_config_to_tgt_rsp_error 2103 r_config_to_tgt_rsp_req 2104 r_config_fsm 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( 2162 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 2150 (r_config_cmd.read() == MEMC_CMD_INVAL)) 2151 { 2152 r_config_fsm 2153 } 2154 else if (entry.valid and 2176 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 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( 2215 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 2201 size_t 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( 2264 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( 2267 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 2241 size_t 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( 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 2285 r_config_address = r_config_address.read() + (m_words<<2);2286 r_config_fsm 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( 2336 // 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 2310 2311 if (r_config_dir_count.read() == 0 2312 { 2313 m_cache_directory.inval( way, set);2314 r_config_cmd_lines 2315 r_config_address = r_config_address.read() + (m_words<<2);2316 r_config_fsm 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 2327 size_t 2328 bool 2329 size_t 2330 size_t 2331 size_t 2332 addr_t nline = m_nline[(addr_t)(r_config_address.read())];2333 size_t 2334 2335 wok = m_ivt.set( 2336 broadcast,2337 2338 2339 2340 2341 2342 2343 2344 index);2345 2346 if (wok 2363 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 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 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 2390 r_config_address 2391 r_config_fsm 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 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 2468 if (r_config_dir_count.read() == 1) // one copy 2420 2469 { 2421 2470 // prepare next iteration 2422 r_config_cmd_lines 2423 r_config_address 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 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: 2460 { 2461 HeapEntry entry = m_heap.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 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: 2540 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( 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 2508 r_config_address = r_config_address.read() + (m_words<<2);2509 r_config_fsm 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 3063 3064 3065 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 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 assert(not m_cmd_write_eop_fifo.read() &&3080 3081 3082 3083 3084 3085 3086 3087 for(size_t word=0 ; word<m_words; word++)3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 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 3115 3116 3117 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 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 4056 4057 4058 4059 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 4066 4067 4068 4069 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 4076 4077 4078 4079 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 4086 4087 4088 4089 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 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 4110 4111 4112 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 4226 4227 4228 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 4389 4390 4391 4392 4393 4557 { 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)) 4595 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: 4443 { 4444 if ((r_alloc_trt_fsm.read() == ALLOC_TRT_IXR_RSP) and 4445 { 4446 size_t index 4447 size_t word 4448 bool eop 4449 wide_data_t data 4450 bool rerror 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 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 5701 5702 5703 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 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 5731 5732 assert((r_alloc_dir_fsm.read() == ALLOC_DIR_CAS) and5733 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 5739 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 5751 5752 5753 5754 5755 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 5768 5769 5770 5771 5772 5773 5774 5775 5776 5777 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 6728 6729 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 6735 6736 6737 6738 6739 6740 6741 6742 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 6880 6881 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 6910 6911 6912 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 7052 7053 7054 7055 7056 7057 7058 7059 7060 7061 7062 7063 7064 7065 7066 7067 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 7073 7074 7075 7076 7077 7078 7079 7080 7081 7082 7083 7084 7085 7086 7087 7088 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 7094 7095 7096 7097 7098 7099 7100 7101 7102 7103 7104 7105 7106 7107 7108 7109 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 7115 7116 7117 7118 7119 7120 7121 7122 7123 7124 7125 7126 7127 7128 7129 7130 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 7136 7137 7138 7139 7140 7141 7142 7143 7144 7145 7146 7147 7148 7149 7150 7151 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 7158 7159 7160 7161 7162 7163 7164 7165 7166 7167 7168 7169 7170 7171 7172 7173 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 7179 7180 7181 7182 7183 7184 7185 7186 7187 7188 7189 7190 7191 7192 7193 7194 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 7200 7201 7202 7203 7204 7205 7206 7207 7208 7209 7210 7211 7212 7213 7214 7215 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 7223 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 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 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 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 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 7854 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() 7622 (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 7651 ((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 7683 ((r_write_fsm.read() == WRITE_UPT_HEAP_LOCK)and7684 7685 7686 ((r_write_fsm.read() == WRITE_MISS_TRT_LOCK)and7687 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 7719 ((r_cas_fsm.read() == CAS_UPT_HEAP_LOCK)and7720 7721 7722 ((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 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( 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( 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( 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( 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( 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( 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( 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( 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( 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( 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( 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( 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( 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( 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( 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 8397 p_vci_ixr.wdata 8398 p_vci_ixr.eop 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 8403 p_vci_ixr.cmd 8404 p_vci_ixr.wdata 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 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 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 8544 8545 8546 8547 8548 8549 8550 8551 8552 8553 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 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 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 8880 p_vci_tgt.rdata = 1; 8568 8881 else 8569 p_vci_tgt.rdata 8570 p_vci_tgt.rsrcid 8571 p_vci_tgt.rtrdid 8572 p_vci_tgt.rpktid 8573 p_vci_tgt.rerror 8574 p_vci_tgt.reop 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 8579 p_vci_tgt.rdata 8580 p_vci_tgt.rsrcid 8581 p_vci_tgt.rtrdid 8582 p_vci_tgt.rpktid 8583 p_vci_tgt.rerror 8584 p_vci_tgt.reop 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 8589 p_vci_tgt.rdata 8590 p_vci_tgt.rsrcid 8591 p_vci_tgt.rtrdid 8592 p_vci_tgt.rpktid 8593 p_vci_tgt.rerror 8594 p_vci_tgt.reop 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 8616 p_vci_tgt.rtrdid 8617 p_vci_tgt.rpktid 8618 p_vci_tgt.rerror 8619 p_vci_tgt.reop 8929 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 8626 p_vci_tgt.rdata 8627 p_vci_tgt.rsrcid 8628 p_vci_tgt.rtrdid 8629 p_vci_tgt.rpktid 8630 p_vci_tgt.rerror 8631 p_vci_tgt.reop 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 8662 8663 8974 { 8975 break; 8976 } 8977 //////////////////////////////// 8664 8978 case CC_SEND_CONFIG_INVAL_HEADER: 8665 8666 8667 8668 8669 8670 8671 8672 8673 8674 8675 8676 8677 8678 8679 8680 DspinDhccpParam::dspin_set(flit,8681 8682 8683 8684 DspinDhccpParam::dspin_set(flit,8685 8686 8687 8688 DspinDhccpParam::dspin_set(flit,8689 8690 8691 8692 8693 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 8699 DspinDhccpParam::dspin_set(flit,8700 8701 8702 8703 8704 8705 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 8711 8712 8713 8714 8715 8716 8717 8718 8719 8720 8721 8722 8723 8724 8725 8726 DspinDhccpParam::dspin_set(flit,8727 8728 8729 8730 DspinDhccpParam::dspin_set(flit,8731 8732 8733 8734 DspinDhccpParam::dspin_set(flit,8735 8736 8737 8738 8739 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 8746 8747 DspinDhccpParam::dspin_set(flit,8748 8749 8750 8751 8752 8753 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 8763 8764 DspinDhccpParam::dspin_set(flit,8765 8766 8767 8768 DspinDhccpParam::dspin_set(flit,8769 8770 8771 8772 8773 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 8779 DspinDhccpParam::dspin_set(flit,8780 8781 8782 8783 8784 8785 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 8791 DspinDhccpParam::dspin_set(flit,8792 8793 8794 8795 8796 8797 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 8803 DspinDhccpParam::dspin_set(flit,8804 8805 8806 8807 8808 8809 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 8815 DspinDhccpParam::dspin_set(flit,8816 8817 8818 8819 8820 8821 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 8827 8828 8829 8830 8831 8832 8833 8834 8835 8836 8837 8838 8839 8840 8841 8842 8843 8844 8845 8846 8847 8848 8849 8850 8851 8852 8853 8854 8855 8856 8857 8858 8859 8860 8861 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 8867 8868 8869 8870 8871 8872 8873 8874 8875 8876 8877 8878 8879 8880 8881 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 8915 8916 8917 8918 8919 8920 8921 8922 8923 8924 8925 8926 8927 8928 8929 8930 8931 8932 8933 8934 8935 8936 8937 8938 8939 8940 8941 8942 8943 8944 8945 8946 8947 8948 8949 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 8955 8956 8957 8958 8959 8960 8961 8962 8963 8964 8965 8966 8967 8968 8969 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 8975 8976 8977 8978 8979 8980 8981 8982 8983 8984 8985 8986 8987 8988 8989 8990 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 8996 8997 8998 8999 9000 9001 9002 9003 9004 9005 9006 9007 9008 9009 9010 9011 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 9075 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 9081 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 9086 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.