- Timestamp:
- Dec 3, 2013, 10:28:34 PM (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/modules/vci_mem_cache/caba/source/src/vci_mem_cache.cpp
r549 r582 888 888 m_cmd_cas_eop_fifo.init() ; 889 889 890 r_config_cmd = MEMC_CMD_NOP;891 r_config_lock = false;890 r_config_cmd = MEMC_CMD_NOP; 891 r_config_lock = false; 892 892 893 893 m_config_to_cc_send_inst_fifo.init(); … … 1014 1014 size_t xram_rsp_to_cc_send_fifo_srcid = 0; 1015 1015 1016 bool config_rsp_lines_incr = false; 1017 bool config_rsp_lines_cleanup_decr = false; 1018 bool config_rsp_lines_ixr_rsp_decr = false; 1019 1016 1020 bool config_to_cc_send_fifo_put = false; 1017 1021 bool config_to_cc_send_fifo_get = false; … … 1254 1258 if (wdata % (m_words << 2)) lines++; 1255 1259 r_config_cmd_lines = lines; 1256 r_config_rsp_lines = lines;1260 r_config_rsp_lines = 0; 1257 1261 } 1258 1262 else if ((p_vci_tgt.cmd.read() == vci_param_int::CMD_WRITE) // set cmd type … … 1621 1625 // the command for line (n+1). It decrements the r_config_cmd_lines counter until 1622 1626 // the last request has been registered in TRT (for a SYNC), or in IVT (for an INVAL). 1623 // 1627 // The r_config_rsp_lines counter contains the number of expected responses from 1628 // CLEANUP FSM (inval) or from IXR_RSP FSM (sync). This register is incremented by 1629 // the CONFIG FSM (each time a transaction is requested), and decremented by the 1630 // CLEANUP or IXR_RSP FSMs(each time a response is received. As this register can 1631 // be concurently accessed by those three FSMs, it is implemented as an [incr/decr] 1632 // counter. 1633 // 1624 1634 // - INVAL request: 1625 1635 // For each line, it access to the DIR. … … 1660 1670 ///////////////// 1661 1671 case CONFIG_IDLE: // waiting a config request 1662 1663 1664 1665 1672 { 1673 if (r_config_cmd.read() != MEMC_CMD_NOP ) 1674 { 1675 r_config_fsm = CONFIG_LOOP; 1666 1676 1667 1677 #if DEBUG_MEMC_CONFIG 1668 1669 1670 1671 1672 1673 #endif 1674 1675 1676 1677 1678 if (m_debug) 1679 std::cout << " <MEMC " << name() << " CONFIG_IDLE> Config Request received" 1680 << " / address = " << std::hex << r_config_address.read() 1681 << " / lines = " << std::dec << r_config_cmd_lines.read() 1682 << " / type = " << r_config_cmd.read() << std::endl; 1683 #endif 1684 } 1685 break; 1686 } 1687 ///////////////// 1678 1688 case CONFIG_LOOP: // test if last line to be handled 1679 { 1680 if (r_config_cmd_lines.read() == 0 ) 1681 { 1682 r_config_cmd = MEMC_CMD_NOP; 1683 r_config_fsm = CONFIG_WAIT; 1689 { 1690 if (r_config_cmd_lines.read() == 0 ) 1691 { 1692 r_config_cmd = MEMC_CMD_NOP; 1693 r_config_fsm = CONFIG_WAIT; 1694 } 1695 else 1696 { 1697 r_config_fsm = CONFIG_DIR_REQ; 1698 } 1699 1700 #if DEBUG_MEMC_CONFIG 1701 if (m_debug) 1702 std::cout << " <MEMC " << name() << " CONFIG_LOOP>" 1703 << " / address = " << std::hex << r_config_address.read() 1704 << " / lines not handled = " << std::dec << r_config_cmd_lines.read() 1705 << " / command = " << r_config_cmd.read() << std::endl; 1706 #endif 1707 break; 1708 } 1709 ///////////////// 1710 case CONFIG_WAIT: // wait completion (last response) 1711 { 1712 if (r_config_rsp_lines.read() == 0 ) // last response received 1713 { 1714 r_config_fsm = CONFIG_RSP; 1715 } 1716 1717 #if DEBUG_MEMC_CONFIG 1718 if (m_debug) 1719 std::cout << " <MEMC " << name() << " CONFIG_WAIT>" 1720 << " / lines to do = " << std::dec << r_config_rsp_lines.read() << std::endl; 1721 #endif 1722 break; 1723 } 1724 //////////////// 1725 case CONFIG_RSP: // request TGT_RSP FSM to return response 1726 { 1727 if (not r_config_to_tgt_rsp_req.read()) 1728 { 1729 r_config_to_tgt_rsp_srcid = r_config_srcid.read(); 1730 r_config_to_tgt_rsp_trdid = r_config_trdid.read(); 1731 r_config_to_tgt_rsp_pktid = r_config_pktid.read(); 1732 r_config_to_tgt_rsp_error = false; 1733 r_config_to_tgt_rsp_req = true; 1734 r_config_fsm = CONFIG_IDLE; 1735 1736 #if DEBUG_MEMC_CONFIG 1737 if (m_debug) 1738 std::cout << " <MEMC " << name() << " CONFIG_RSP> Request TGT_RSP FSM to send response:" 1739 << " error = " << r_config_to_tgt_rsp_error.read() 1740 << " / rsrcid = " << std::hex << r_config_srcid.read() 1741 << " / rtrdid = " << std::hex << r_config_trdid.read() 1742 << " / rpktid = " << std::hex << r_config_pktid.read() << std::endl; 1743 #endif 1744 } 1745 break; 1746 } 1747 //////////////////// 1748 case CONFIG_DIR_REQ: // Request directory lock 1749 { 1750 if (r_alloc_dir_fsm.read() == ALLOC_DIR_CONFIG ) 1751 { 1752 r_config_fsm = CONFIG_DIR_ACCESS; 1753 } 1754 1755 #if DEBUG_MEMC_CONFIG 1756 if (m_debug) 1757 std::cout << " <MEMC " << name() << " CONFIG_DIR_REQ>" 1758 << " Request DIR access" << std::endl; 1759 #endif 1760 break; 1761 } 1762 /////////////////////// 1763 case CONFIG_DIR_ACCESS: // Access directory and decode config command 1764 { 1765 assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_CONFIG) and 1766 "MEMC ERROR in CONFIG_DIR_ACCESS state: bad DIR allocation"); 1767 1768 size_t way = 0; 1769 DirectoryEntry entry = m_cache_directory.read(r_config_address.read(), way); 1770 1771 r_config_dir_way = way; 1772 r_config_dir_copy_inst = entry.owner.inst; 1773 r_config_dir_copy_srcid = entry.owner.srcid; 1774 r_config_dir_is_cnt = entry.is_cnt; 1775 r_config_dir_lock = entry.lock; 1776 r_config_dir_count = entry.count; 1777 r_config_dir_ptr = entry.ptr; 1778 1779 if (entry.valid and // hit & inval command 1780 (r_config_cmd.read() == MEMC_CMD_INVAL)) 1781 { 1782 r_config_fsm = CONFIG_IVT_LOCK; 1783 } 1784 else if (entry.valid and // hit & sync command 1785 entry.dirty and 1786 (r_config_cmd.read() == MEMC_CMD_SYNC)) 1787 { 1788 r_config_fsm = CONFIG_TRT_LOCK; 1789 } 1790 else // miss : return to LOOP 1791 { 1792 r_config_cmd_lines = r_config_cmd_lines.read() - 1; 1793 r_config_address = r_config_address.read() + (m_words<<2); 1794 r_config_fsm = CONFIG_LOOP; 1795 } 1796 1797 #if DEBUG_MEMC_CONFIG 1798 if (m_debug) 1799 std::cout << " <MEMC " << name() << " CONFIG_DIR_ACCESS> Accessing directory: " 1800 << " address = " << std::hex << r_config_address.read() 1801 << " / hit = " << std::dec << entry.valid 1802 << " / dirty = " << entry.dirty 1803 << " / count = " << entry.count 1804 << " / is_cnt = " << entry.is_cnt << std::endl; 1805 #endif 1806 break; 1807 } 1808 ///////////////////// 1809 case CONFIG_TRT_LOCK: // enter this state in case of SYNC command 1810 // to a dirty cache line 1811 // keep DIR lock, and try to get TRT lock 1812 // return to LOOP state if TRT full 1813 // reset dirty bit in DIR and register a PUT 1814 // transaction in TRT if not full. 1815 { 1816 assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_CONFIG) and 1817 "MEMC ERROR in CONFIG_TRT_LOCK state: bad DIR allocation"); 1818 1819 if (r_alloc_trt_fsm.read() == ALLOC_TRT_CONFIG ) 1820 { 1821 size_t index = 0; 1822 bool wok = not m_trt.full(index); 1823 1824 if (not wok ) 1825 { 1826 r_config_fsm = CONFIG_LOOP; 1684 1827 } 1685 1828 else 1686 1829 { 1687 r_config_fsm = CONFIG_DIR_REQ; 1830 size_t way = r_config_dir_way.read(); 1831 size_t set = m_y[r_config_address.read()]; 1832 1833 // reset dirty bit in DIR 1834 DirectoryEntry entry; 1835 entry.valid = true; 1836 entry.dirty = false; 1837 entry.tag = m_z[r_config_address.read()]; 1838 entry.is_cnt = r_config_dir_is_cnt.read(); 1839 entry.lock = r_config_dir_lock.read(); 1840 entry.ptr = r_config_dir_ptr.read(); 1841 entry.count = r_config_dir_count.read(); 1842 entry.owner.inst = r_config_dir_copy_inst.read(); 1843 entry.owner.srcid = r_config_dir_copy_srcid.read(); 1844 m_cache_directory.write( set, way, entry ); 1845 1846 r_config_trt_index = index; 1847 r_config_fsm = CONFIG_TRT_SET; 1688 1848 } 1689 1849 1690 1850 #if DEBUG_MEMC_CONFIG 1691 if (m_debug) 1692 std::cout << " <MEMC " << name() << " CONFIG_LOOP>" 1693 << " / address = " << std::hex << r_config_address.read() 1694 << " / lines not handled = " << std::dec << r_config_cmd_lines.read() 1695 << " / command = " << r_config_cmd.read() << std::endl; 1696 #endif 1697 break; 1698 } 1699 ///////////////// 1700 case CONFIG_WAIT: // wait completion (last response) 1701 { 1702 if (r_config_rsp_lines.read() == 0 ) // last response received 1703 { 1704 r_config_fsm = CONFIG_RSP; 1705 } 1851 if (m_debug) 1852 std::cout << " <MEMC " << name() << " CONFIG_TRT_LOCK> Access TRT: " 1853 << " wok = " << std::dec << wok 1854 << " index = " << index << std::endl; 1855 #endif 1856 } 1857 break; 1858 } 1859 //////////////////// 1860 case CONFIG_TRT_SET: // read data in cache 1861 // and post a PUT request in TRT 1862 { 1863 assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_CONFIG) and 1864 "MEMC ERROR in CONFIG_TRT_SET state: bad DIR allocation"); 1865 1866 assert( (r_alloc_trt_fsm.read() == ALLOC_TRT_CONFIG) and 1867 "MEMC ERROR in CONFIG_TRT_SET state: bad TRT allocation"); 1868 1869 // read data into cache 1870 size_t way = r_config_dir_way.read(); 1871 size_t set = m_y[r_config_address.read()]; 1872 std::vector<data_t> data_vector; 1873 data_vector.clear(); 1874 for(size_t word=0; word<m_words; word++) 1875 { 1876 uint32_t data = m_cache_data.read( way, set, word ); 1877 data_vector.push_back( data ); 1878 } 1879 1880 // post the PUT request in TRT 1881 m_trt.set( r_config_trt_index.read(), 1882 false, // PUT transaction 1883 m_nline[r_config_address.read()], // line index 1884 0, // srcid: unused 1885 0, // trdid: unused 1886 0, // pktid: unused 1887 false, // not proc_read 1888 0, // read_length: unused 1889 0, // word_index: unused 1890 std::vector<be_t>(m_words,0xF), // byte-enable: unused 1891 data_vector, // data to be written 1892 0, // ll_key: unused 1893 true ); // requested by config FSM 1894 config_rsp_lines_incr = true; 1895 r_config_fsm = CONFIG_PUT_REQ; 1706 1896 1707 1897 #if DEBUG_MEMC_CONFIG 1708 if (m_debug) 1709 std::cout << " <MEMC " << name() << " CONFIG_WAIT>" 1710 << " / lines to do = " << std::dec << r_config_rsp_lines.read() << std::endl; 1711 #endif 1712 break; 1713 } 1714 //////////////// 1715 case CONFIG_RSP: // request TGT_RSP FSM to return response 1716 { 1717 if (not r_config_to_tgt_rsp_req.read()) 1718 { 1719 r_config_to_tgt_rsp_srcid = r_config_srcid.read(); 1720 r_config_to_tgt_rsp_trdid = r_config_trdid.read(); 1721 r_config_to_tgt_rsp_pktid = r_config_pktid.read(); 1722 r_config_to_tgt_rsp_error = false; 1723 r_config_to_tgt_rsp_req = true; 1724 r_config_fsm = CONFIG_IDLE; 1898 if (m_debug) 1899 std::cout << " <MEMC " << name() << " CONFIG_TRT_SET> PUT request in TRT:" 1900 << " address = " << std::hex << r_config_address.read() 1901 << " index = " << std::dec << r_config_trt_index.read() << std::endl; 1902 #endif 1903 break; 1904 } 1905 //////////////////// 1906 case CONFIG_PUT_REQ: // post PUT request to IXR_CMD_FSM 1907 { 1908 if (not r_config_to_ixr_cmd_req.read()) 1909 { 1910 r_config_to_ixr_cmd_req = true; 1911 r_config_to_ixr_cmd_index = r_config_trt_index.read(); 1912 1913 // prepare next iteration 1914 r_config_cmd_lines = r_config_cmd_lines.read() - 1; 1915 r_config_address = r_config_address.read() + (m_words<<2); 1916 r_config_fsm = CONFIG_LOOP; 1725 1917 1726 1918 #if DEBUG_MEMC_CONFIG 1727 if (m_debug) 1728 std::cout << " <MEMC " << name() << " CONFIG_RSP> Request TGT_RSP FSM to return response:" 1729 << " error = " << r_config_to_tgt_rsp_error.read() 1730 << " / rsrcid = " << std::hex << r_config_srcid.read() 1731 << " / rtrdid = " << std::hex << r_config_trdid.read() 1732 << " / rpktid = " << std::hex << r_config_pktid.read() << std::endl; 1733 #endif 1734 } 1735 break; 1736 1737 } 1738 //////////////////// 1739 case CONFIG_DIR_REQ: // Request directory lock 1740 { 1741 if (r_alloc_dir_fsm.read() == ALLOC_DIR_CONFIG ) 1742 { 1743 r_config_fsm = CONFIG_DIR_ACCESS; 1744 } 1919 if (m_debug) 1920 std::cout << " <MEMC " << name() << " CONFIG_PUT_REQ> post PUT request to IXR_CMD_FSM" 1921 << " / address = " << std::hex << r_config_address.read() << std::endl; 1922 #endif 1923 } 1924 break; 1925 } 1926 ///////////////////// 1927 case CONFIG_IVT_LOCK: // enter this state in case of INVAL command 1928 // Keep DIR lock and Try to get IVT lock. 1929 // Return to LOOP state if IVT full. 1930 // Register inval in IVT, and invalidate the 1931 // directory if IVT not full. 1932 { 1933 assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_CONFIG) and 1934 "MEMC ERROR in CONFIG_IVT_LOCK state: bad DIR allocation"); 1935 1936 if (r_alloc_ivt_fsm.read() == ALLOC_IVT_CONFIG ) 1937 { 1938 size_t set = m_y[(addr_t)(r_config_address.read())]; 1939 size_t way = r_config_dir_way.read(); 1940 1941 if (r_config_dir_count.read() == 0 ) // inval DIR and return to LOOP 1942 { 1943 m_cache_directory.inval( way, set ); 1944 r_config_cmd_lines = r_config_cmd_lines.read() - 1; 1945 r_config_address = r_config_address.read() + (m_words<<2); 1946 r_config_fsm = CONFIG_LOOP; 1745 1947 1746 1948 #if DEBUG_MEMC_CONFIG 1747 if (m_debug) 1748 std::cout << " <MEMC " << name() << " CONFIG_DIR_REQ>" 1749 << " Request DIR access" << std::endl; 1750 #endif 1751 break; 1752 } 1753 /////////////////////// 1754 case CONFIG_DIR_ACCESS: // Access directory and decode config command 1755 { 1756 assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_CONFIG) and 1757 "MEMC ERROR in CONFIG_DIR_ACCESS state: bad DIR allocation"); 1758 1759 size_t way = 0; 1760 DirectoryEntry entry = m_cache_directory.read(r_config_address.read(), way); 1761 1762 r_config_dir_way = way; 1763 r_config_dir_copy_inst = entry.owner.inst; 1764 r_config_dir_copy_srcid = entry.owner.srcid; 1765 r_config_dir_is_cnt = entry.is_cnt; 1766 r_config_dir_lock = entry.lock; 1767 r_config_dir_count = entry.count; 1768 r_config_dir_ptr = entry.ptr; 1769 1770 if (entry.valid and // hit & inval command 1771 (r_config_cmd.read() == MEMC_CMD_INVAL)) 1772 { 1773 r_config_fsm = CONFIG_IVT_LOCK; 1774 } 1775 else if (entry.valid and // hit & sync command 1776 entry.dirty and 1777 (r_config_cmd.read() == MEMC_CMD_SYNC)) 1778 { 1779 r_config_fsm = CONFIG_TRT_LOCK; 1780 } 1781 else // miss : return to LOOP 1782 { 1783 r_config_cmd_lines = r_config_cmd_lines.read() - 1; 1784 r_config_rsp_lines = r_config_rsp_lines.read() - 1; 1785 r_config_address = r_config_address.read() + (m_words<<2); 1786 r_config_fsm = CONFIG_LOOP; 1787 } 1949 if (m_debug) 1950 std::cout << " <MEMC " << name() << " CONFIG_IVT_LOCK>" 1951 << " No copies in L1 : inval DIR entry" << std::endl; 1952 #endif 1953 } 1954 else // try to register inval in IVT 1955 { 1956 bool wok = false; 1957 size_t index = 0; 1958 bool broadcast = r_config_dir_is_cnt.read(); 1959 size_t srcid = r_config_srcid.read(); 1960 size_t trdid = r_config_trdid.read(); 1961 size_t pktid = r_config_pktid.read(); 1962 addr_t nline = m_nline[(addr_t)(r_config_address.read())]; 1963 size_t nb_copies = r_config_dir_count.read(); 1964 1965 wok = m_ivt.set( false, // it's an inval transaction 1966 broadcast, 1967 false, // no response required 1968 true, // acknowledge required 1969 srcid, 1970 trdid, 1971 pktid, 1972 nline, 1973 nb_copies, 1974 index ); 1975 1976 if (wok ) // IVT success => inval DIR slot 1977 { 1978 m_cache_directory.inval( way, set ); 1979 r_config_ivt_index = index; 1980 config_rsp_lines_incr = true; 1981 if (broadcast ) r_config_fsm = CONFIG_BC_SEND; 1982 else r_config_fsm = CONFIG_INVAL_SEND; 1788 1983 1789 1984 #if DEBUG_MEMC_CONFIG 1790 if (m_debug) 1791 std::cout << " <MEMC " << name() << " CONFIG_DIR_ACCESS> Accessing directory: " 1792 << " address = " << std::hex << r_config_address.read() 1793 << " / hit = " << std::dec << entry.valid 1794 << " / dirty = " << entry.dirty 1795 << " / count = " << entry.count 1796 << " / is_cnt = " << entry.is_cnt << std::endl; 1797 #endif 1798 break; 1799 } 1800 ///////////////////// 1801 case CONFIG_TRT_LOCK: // enter this state in case of SYNC command 1802 // to a dirty cache line 1803 // keep DIR lock, and try to get TRT lock 1804 // return to LOOP state if TRT full 1805 // reset dirty bit in DIR and register a PUT 1806 // trabsaction in TRT if not full. 1807 { 1808 assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_CONFIG) and 1809 "MEMC ERROR in CONFIG_TRT_LOCK state: bad DIR allocation"); 1810 1811 if (r_alloc_trt_fsm.read() == ALLOC_TRT_CONFIG ) 1812 { 1813 size_t index = 0; 1814 bool wok = not m_trt.full(index); 1815 1816 if (not wok ) 1985 if (m_debug) 1986 std::cout << " <MEMC " << name() << " CONFIG_IVT_LOCK>" 1987 << " Inval DIR entry and register inval in IVT" 1988 << " / index = " << std::dec << index 1989 << " / broadcast = " << broadcast << std::endl; 1990 #endif 1991 } 1992 else // IVT full => release both DIR and IVT locks 1817 1993 { 1818 1994 r_config_fsm = CONFIG_LOOP; 1819 }1820 else1821 {1822 size_t way = r_config_dir_way.read();1823 size_t set = m_y[r_config_address.read()];1824 1825 // reset dirty bit in DIR1826 DirectoryEntry entry;1827 entry.valid = true;1828 entry.dirty = false;1829 entry.tag = m_z[r_config_address.read()];1830 entry.is_cnt = r_config_dir_is_cnt.read();1831 entry.lock = r_config_dir_lock.read();1832 entry.ptr = r_config_dir_ptr.read();1833 entry.count = r_config_dir_count.read();1834 entry.owner.inst = r_config_dir_copy_inst.read();1835 entry.owner.srcid = r_config_dir_copy_srcid.read();1836 m_cache_directory.write( set, way, entry );1837 1838 r_config_trt_index = index;1839 r_config_fsm = CONFIG_TRT_SET;1840 }1841 1995 1842 1996 #if DEBUG_MEMC_CONFIG 1843 if (m_debug) 1844 std::cout << " <MEMC " << name() << " CONFIG_TRT_LOCK> Access TRT: " 1845 << " wok = " << std::dec << wok 1846 << " index = " << index << std::endl; 1847 #endif 1848 } 1849 break; 1850 } 1851 //////////////////// 1852 case CONFIG_TRT_SET: // read data in cache 1853 // and post a PUT request in TRT 1854 { 1855 assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_CONFIG) and 1856 "MEMC ERROR in CONFIG_TRT_SET state: bad DIR allocation"); 1857 1858 assert( (r_alloc_trt_fsm.read() == ALLOC_TRT_CONFIG) and 1859 "MEMC ERROR in CONFIG_TRT_SET state: bad TRT allocation"); 1860 1861 // read data into cache 1862 size_t way = r_config_dir_way.read(); 1863 size_t set = m_y[r_config_address.read()]; 1864 std::vector<data_t> data_vector; 1865 data_vector.clear(); 1866 for(size_t word=0; word<m_words; word++) 1867 { 1868 uint32_t data = m_cache_data.read( way, set, word ); 1869 data_vector.push_back( data ); 1870 } 1871 1872 // post the PUT request in TRT 1873 m_trt.set( r_config_trt_index.read(), 1874 false, // PUT transaction 1875 m_nline[r_config_address.read()], // line index 1876 0, // srcid: unused 1877 0, // trdid: unused 1878 0, // pktid: unused 1879 false, // not proc_read 1880 0, // read_length: unused 1881 0, // word_index: unused 1882 std::vector<be_t>(m_words,0xF), // byte-enable: unused 1883 data_vector, // data to be written 1884 0, // ll_key: unused 1885 true ); // requested by config FSM 1886 r_config_fsm = CONFIG_PUT_REQ; 1997 if (m_debug) 1998 std::cout << " <MEMC " << name() << " CONFIG_IVT_LOCK>" 1999 << " IVT full : release DIR & IVT locks and retry" << std::endl; 2000 #endif 2001 } 2002 } 2003 } 2004 break; 2005 } 2006 //////////////////// 2007 case CONFIG_BC_SEND: // Post a broadcast inval request to CC_SEND FSM 2008 { 2009 if (not r_config_to_cc_send_multi_req.read() and 2010 not r_config_to_cc_send_brdcast_req.read()) 2011 { 2012 // post bc inval request 2013 r_config_to_cc_send_multi_req = false; 2014 r_config_to_cc_send_brdcast_req = true; 2015 r_config_to_cc_send_trdid = r_config_ivt_index.read(); 2016 r_config_to_cc_send_nline = m_nline[(addr_t)(r_config_address.read())]; 2017 2018 // prepare next iteration 2019 r_config_cmd_lines = r_config_cmd_lines.read() - 1; 2020 r_config_address = r_config_address.read() + (m_words << 2); 2021 r_config_fsm = CONFIG_LOOP; 1887 2022 1888 2023 #if DEBUG_MEMC_CONFIG 1889 if (m_debug) 1890 std::cout << " <MEMC " << name() << " CONFIG_TRT_SET> PUT request in TRT:" 1891 << " address = " << std::hex << r_config_address.read() 1892 << " index = " << std::dec << r_config_trt_index.read() << std::endl; 1893 #endif 1894 break; 1895 } 1896 //////////////////// 1897 case CONFIG_PUT_REQ: // post PUT request to IXR_CMD_FSM 1898 { 1899 if (not r_config_to_ixr_cmd_req.read()) 1900 { 1901 r_config_to_ixr_cmd_req = true; 1902 r_config_to_ixr_cmd_index = r_config_trt_index.read(); 1903 2024 if (m_debug) 2025 std::cout << " <MEMC " << name() << " CONFIG_BC_SEND>" 2026 << " Post a broadcast inval request to CC_SEND FSM" 2027 << " / address = " << r_config_address.read() <<std::endl; 2028 #endif 2029 } 2030 break; 2031 } 2032 /////////////////////// 2033 case CONFIG_INVAL_SEND: // Post a multi inval request to CC_SEND FSM 2034 { 2035 if (not r_config_to_cc_send_multi_req.read() and 2036 not r_config_to_cc_send_brdcast_req.read()) 2037 { 2038 // post multi inval request 2039 r_config_to_cc_send_multi_req = true; 2040 r_config_to_cc_send_brdcast_req = false; 2041 r_config_to_cc_send_trdid = r_config_ivt_index.read(); 2042 r_config_to_cc_send_nline = m_nline[(addr_t)(r_config_address.read())]; 2043 2044 // post data into FIFO 2045 config_to_cc_send_fifo_srcid = r_config_dir_copy_srcid.read(); 2046 config_to_cc_send_fifo_inst = r_config_dir_copy_inst.read(); 2047 config_to_cc_send_fifo_put = true; 2048 2049 if (r_config_dir_count.read() == 1 ) // one copy 2050 { 1904 2051 // prepare next iteration 1905 r_config_cmd_lines = r_config_cmd_lines.read() - 1; 1906 r_config_address = r_config_address.read() + (m_words<<2); 1907 r_config_fsm = CONFIG_LOOP; 2052 r_config_cmd_lines = r_config_cmd_lines.read() - 1; 2053 r_config_address = r_config_address.read() + (m_words << 2); 2054 r_config_fsm = CONFIG_LOOP; 2055 } 2056 else // several copies 2057 { 2058 r_config_fsm = CONFIG_HEAP_REQ; 2059 } 1908 2060 1909 2061 #if DEBUG_MEMC_CONFIG 1910 if (m_debug) 1911 std::cout << " <MEMC " << name() << " CONFIG_PUT_REQ> post PUT request to IXR_CMD_FSM" 1912 << " / address = " << std::hex << r_config_address.read() << std::endl; 1913 #endif 1914 } 1915 break; 1916 } 1917 ///////////////////// 1918 case CONFIG_IVT_LOCK: // enter this state in case of INVAL command 1919 // Keep DIR lock and Try to get IVT lock. 1920 // Return to LOOP state if IVT full. 1921 // Register inval in IVT, and invalidate the 1922 // directory if IVT not full. 1923 { 1924 assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_CONFIG) and 1925 "MEMC ERROR in CONFIG_IVT_LOCK state: bad DIR allocation"); 1926 1927 if (r_alloc_ivt_fsm.read() == ALLOC_IVT_CONFIG ) 1928 { 1929 size_t set = m_y[(addr_t)(r_config_address.read())]; 1930 size_t way = r_config_dir_way.read(); 1931 1932 if (r_config_dir_count.read() == 0 ) // inval DIR and return to LOOP 1933 { 1934 m_cache_directory.inval( way, set ); 1935 r_config_cmd_lines = r_config_cmd_lines.read() - 1; 1936 r_config_rsp_lines = r_config_rsp_lines.read() - 1; 1937 r_config_address = r_config_address.read() + (m_words<<2); 1938 r_config_fsm = CONFIG_LOOP; 2062 if (m_debug) 2063 std::cout << " <MEMC " << name() << " CONFIG_INVAL_SEND>" 2064 << " Post multi inval request to CC_SEND FSM" 2065 << " / address = " << std::hex << r_config_address.read() 2066 << " / copy = " << r_config_dir_copy_srcid.read() 2067 << " / inst = " << std::dec << r_config_dir_copy_inst.read() << std::endl; 2068 #endif 2069 } 2070 break; 2071 } 2072 ///////////////////// 2073 case CONFIG_HEAP_REQ: // Try to get access to Heap 2074 { 2075 if (r_alloc_heap_fsm.read() == ALLOC_HEAP_CONFIG ) 2076 { 2077 r_config_fsm = CONFIG_HEAP_SCAN; 2078 r_config_heap_next = r_config_dir_ptr.read(); 2079 } 1939 2080 1940 2081 #if DEBUG_MEMC_CONFIG 1941 if (m_debug) 1942 std::cout << " <MEMC " << name() << " CONFIG_IVT_LOCK>" 1943 << " No copies in L1 : inval DIR entry" << std::endl; 1944 #endif 1945 } 1946 else // try to register inval in IVT 1947 { 1948 bool wok = false; 1949 size_t index = 0; 1950 bool broadcast = r_config_dir_is_cnt.read(); 1951 size_t srcid = r_config_srcid.read(); 1952 size_t trdid = r_config_trdid.read(); 1953 size_t pktid = r_config_pktid.read(); 1954 addr_t nline = m_nline[(addr_t)(r_config_address.read())]; 1955 size_t nb_copies = r_config_dir_count.read(); 1956 1957 wok = m_ivt.set(false, // it's an inval transaction 1958 broadcast, 1959 false, // no response required 1960 true, // acknowledge required 1961 srcid, 1962 trdid, 1963 pktid, 1964 nline, 1965 nb_copies, 1966 index); 1967 1968 if (wok ) // IVT success => inval DIR slot 1969 { 1970 m_cache_directory.inval( way, set ); 1971 r_config_ivt_index = index; 1972 if (broadcast ) r_config_fsm = CONFIG_BC_SEND; 1973 else r_config_fsm = CONFIG_INVAL_SEND; 2082 if (m_debug) 2083 std::cout << " <MEMC " << name() << " CONFIG_HEAP_REQ>" 2084 << " Requesting HEAP lock" << std::endl; 2085 #endif 2086 break; 2087 } 2088 ////////////////////// 2089 case CONFIG_HEAP_SCAN: // scan HEAP and send inval to CC_SEND FSM 2090 { 2091 HeapEntry entry = m_heap.read( r_config_heap_next.read()); 2092 bool last_copy = (entry.next == r_config_heap_next.read()); 2093 2094 config_to_cc_send_fifo_srcid = entry.owner.srcid; 2095 config_to_cc_send_fifo_inst = entry.owner.inst; 2096 // config_to_cc_send_fifo_last = last_copy; 2097 config_to_cc_send_fifo_put = true; 2098 2099 if (m_config_to_cc_send_inst_fifo.wok()) // inval request accepted 2100 { 2101 r_config_heap_next = entry.next; 2102 if (last_copy ) r_config_fsm = CONFIG_HEAP_LAST; 2103 } 1974 2104 1975 2105 #if DEBUG_MEMC_CONFIG 1976 if (m_debug) 1977 std::cout << " <MEMC " << name() << " CONFIG_IVT_LOCK>" 1978 << " Inval DIR entry and register inval in IVT" 1979 << " / index = " << std::dec << index 1980 << " / broadcast = " << broadcast << std::endl; 1981 #endif 1982 } 1983 else // IVT full => release both DIR and IVT locks 1984 { 1985 r_config_fsm = CONFIG_LOOP; 2106 if (m_debug) 2107 std::cout << " <MEMC " << name() << " CONFIG_HEAP_SCAN>" 2108 << " Post multi inval request to CC_SEND FSM" 2109 << " / address = " << std::hex << r_config_address.read() 2110 << " / copy = " << entry.owner.srcid 2111 << " / inst = " << std::dec << entry.owner.inst << std::endl; 2112 #endif 2113 break; 2114 } 2115 ////////////////////// 2116 case CONFIG_HEAP_LAST: // HEAP housekeeping 2117 { 2118 size_t free_pointer = m_heap.next_free_ptr(); 2119 HeapEntry last_entry; 2120 last_entry.owner.srcid = 0; 2121 last_entry.owner.inst = false; 2122 2123 if (m_heap.is_full()) 2124 { 2125 last_entry.next = r_config_dir_ptr.read(); 2126 m_heap.unset_full(); 2127 } 2128 else 2129 { 2130 last_entry.next = free_pointer; 2131 } 2132 2133 m_heap.write_free_ptr( r_config_dir_ptr.read()); 2134 m_heap.write( r_config_heap_next.read(), last_entry ); 2135 2136 // prepare next iteration 2137 r_config_cmd_lines = r_config_cmd_lines.read() - 1; 2138 r_config_address = r_config_address.read() + (m_words<<2); 2139 r_config_fsm = CONFIG_LOOP; 1986 2140 1987 2141 #if DEBUG_MEMC_CONFIG 1988 if (m_debug) 1989 std::cout << " <MEMC " << name() << " CONFIG_IVT_LOCK>" 1990 << " IVT full : release DIR & IVT locks and retry" << std::endl; 1991 #endif 1992 } 1993 } 1994 } 1995 break; 1996 } 1997 //////////////////// 1998 case CONFIG_BC_SEND: // Post a broadcast inval request to CC_SEND FSM 1999 { 2000 if (not r_config_to_cc_send_multi_req.read() and 2001 not r_config_to_cc_send_brdcast_req.read()) 2002 { 2003 // post bc inval request 2004 r_config_to_cc_send_multi_req = false; 2005 r_config_to_cc_send_brdcast_req = true; 2006 r_config_to_cc_send_trdid = r_config_ivt_index.read(); 2007 r_config_to_cc_send_nline = m_nline[(addr_t)(r_config_address.read())]; 2008 2009 // prepare next iteration 2010 r_config_cmd_lines = r_config_cmd_lines.read() - 1; 2011 r_config_address = r_config_address.read() + (m_words << 2); 2012 r_config_fsm = CONFIG_LOOP; 2013 2014 #if DEBUG_MEMC_CONFIG 2015 if (m_debug) 2016 std::cout << " <MEMC " << name() << " CONFIG_BC_SEND>" 2017 << " Post a broadcast inval request to CC_SEND FSM" 2018 << " / address = " << r_config_address.read() <<std::endl; 2019 #endif 2020 } 2021 break; 2022 } 2023 /////////////////////// 2024 case CONFIG_INVAL_SEND: // Post a multi inval request to CC_SEND FSM 2025 { 2026 if (not r_config_to_cc_send_multi_req.read() and 2027 not r_config_to_cc_send_brdcast_req.read()) 2028 { 2029 // post multi inval request 2030 r_config_to_cc_send_multi_req = true; 2031 r_config_to_cc_send_brdcast_req = false; 2032 r_config_to_cc_send_trdid = r_config_ivt_index.read(); 2033 r_config_to_cc_send_nline = m_nline[(addr_t) (r_config_address.read())]; 2034 2035 // post data into FIFO 2036 config_to_cc_send_fifo_srcid = r_config_dir_copy_srcid.read(); 2037 config_to_cc_send_fifo_inst = r_config_dir_copy_inst.read(); 2038 config_to_cc_send_fifo_put = true; 2039 2040 if (r_config_dir_count.read() == 1 ) // one copy 2041 { 2042 // prepare next iteration 2043 r_config_cmd_lines = r_config_cmd_lines.read() - 1; 2044 r_config_address = r_config_address.read() + (m_words << 2); 2045 r_config_fsm = CONFIG_LOOP; 2046 } 2047 else // several copies 2048 { 2049 r_config_fsm = CONFIG_HEAP_REQ; 2050 } 2051 2052 #if DEBUG_MEMC_CONFIG 2053 if (m_debug) 2054 std::cout << " <MEMC " << name() << " CONFIG_INVAL_SEND>" 2055 << " Post multi inval request to CC_SEND FSM" 2056 << " / address = " << std::hex << r_config_address.read() 2057 << " / copy = " << r_config_dir_copy_srcid.read() 2058 << " / inst = " << std::dec << r_config_dir_copy_inst.read() << std::endl; 2059 #endif 2060 } 2061 break; 2062 } 2063 ///////////////////// 2064 case CONFIG_HEAP_REQ: // Try to get access to Heap 2065 { 2066 if (r_alloc_heap_fsm.read() == ALLOC_HEAP_CONFIG ) 2067 { 2068 r_config_fsm = CONFIG_HEAP_SCAN; 2069 r_config_heap_next = r_config_dir_ptr.read(); 2070 } 2071 2072 #if DEBUG_MEMC_CONFIG 2073 if (m_debug) 2074 std::cout << " <MEMC " << name() << " CONFIG_HEAP_REQ>" 2075 << " Requesting HEAP lock" << std::endl; 2076 #endif 2077 break; 2078 } 2079 ////////////////////// 2080 case CONFIG_HEAP_SCAN: // scan HEAP and send inval to CC_SEND FSM 2081 { 2082 HeapEntry entry = m_heap.read( r_config_heap_next.read()); 2083 bool last_copy = (entry.next == r_config_heap_next.read()); 2084 2085 config_to_cc_send_fifo_srcid = entry.owner.srcid; 2086 config_to_cc_send_fifo_inst = entry.owner.inst; 2087 // config_to_cc_send_fifo_last = last_copy; 2088 config_to_cc_send_fifo_put = true; 2089 2090 if (m_config_to_cc_send_inst_fifo.wok()) // inval request accepted 2091 { 2092 r_config_heap_next = entry.next; 2093 if (last_copy ) r_config_fsm = CONFIG_HEAP_LAST; 2094 } 2095 2096 #if DEBUG_MEMC_CONFIG 2097 if (m_debug) 2098 std::cout << " <MEMC " << name() << " CONFIG_HEAP_SCAN>" 2099 << " Post multi inval request to CC_SEND FSM" 2100 << " / address = " << std::hex << r_config_address.read() 2101 << " / copy = " << entry.owner.srcid 2102 << " / inst = " << std::dec << entry.owner.inst << std::endl; 2103 #endif 2104 break; 2105 } 2106 ////////////////////// 2107 case CONFIG_HEAP_LAST: // HEAP housekeeping 2108 { 2109 size_t free_pointer = m_heap.next_free_ptr(); 2110 HeapEntry last_entry; 2111 last_entry.owner.srcid = 0; 2112 last_entry.owner.inst = false; 2113 2114 if (m_heap.is_full()) 2115 { 2116 last_entry.next = r_config_dir_ptr.read(); 2117 m_heap.unset_full(); 2118 } 2119 else 2120 { 2121 last_entry.next = free_pointer; 2122 } 2123 2124 m_heap.write_free_ptr( r_config_dir_ptr.read()); 2125 m_heap.write( r_config_heap_next.read(), last_entry ); 2126 2127 // prepare next iteration 2128 r_config_cmd_lines = r_config_cmd_lines.read() - 1; 2129 r_config_address = r_config_address.read() + (m_words<<2); 2130 r_config_fsm = CONFIG_LOOP; 2131 2132 #if DEBUG_MEMC_CONFIG 2133 if (m_debug) 2134 std::cout << " <MEMC " << name() << " CONFIG_HEAP_LAST>" 2135 << " Heap housekeeping" << std::endl; 2136 #endif 2137 break; 2138 } 2142 if (m_debug) 2143 std::cout << " <MEMC " << name() << " CONFIG_HEAP_LAST>" 2144 << " Heap housekeeping" << std::endl; 2145 #endif 2146 break; 2147 } 2139 2148 } // end switch r_config_fsm 2149 2150 2140 2151 2141 2152 //////////////////////////////////////////////////////////////////////////////////// … … 4045 4056 { 4046 4057 size_t index = r_ixr_rsp_trt_index.read(); 4047 if (m_trt.is_config(index)) 4048 r_config_rsp_lines = r_config_rsp_lines.read() - 1; 4049 m_trt.erase(index); 4050 r_ixr_rsp_fsm = IXR_RSP_IDLE; 4058 if (m_trt.is_config(index)) // it's a config transaction 4059 { 4060 config_rsp_lines_ixr_rsp_decr = true; 4061 m_trt.erase(index); 4062 r_ixr_rsp_fsm = IXR_RSP_IDLE; 4063 } 4064 else // not a config transaction 4065 { 4066 m_trt.erase(index); 4067 r_ixr_rsp_fsm = IXR_RSP_IDLE; 4068 } 4051 4069 4052 4070 #if DEBUG_MEMC_IXR_RSP … … 5147 5165 "MEMC ERROR in CLEANUP_IVT_CLEAR state"); 5148 5166 5149 r_config_rsp_lines = r_config_rsp_lines.read() - 1;5167 config_rsp_lines_cleanup_decr = true; 5150 5168 } 5151 5169 5152 5170 if (r_cleanup_need_rsp.read()) r_cleanup_fsm = CLEANUP_WRITE_RSP; 5153 else 5171 else r_cleanup_fsm = CLEANUP_SEND_CLACK; 5154 5172 5155 5173 #if DEBUG_MEMC_CLEANUP … … 7890 7908 m_cpt_cycles++; 7891 7909 7910 //////////////////////////////////////////////////////////////////////////////////// 7911 // Update r_config_rsp_lines counter. 7912 // The three sources of (increment / decrement) are CONFIG / CLEANUP / IXR_RSP FSMs 7913 //////////////////////////////////////////////////////////////////////////////////// 7914 if ( config_rsp_lines_incr and not 7915 (config_rsp_lines_cleanup_decr or config_rsp_lines_ixr_rsp_decr) ) 7916 { 7917 r_config_rsp_lines = r_config_rsp_lines.read() + 1; 7918 } 7919 if ( not config_rsp_lines_incr and 7920 (config_rsp_lines_cleanup_decr or config_rsp_lines_ixr_rsp_decr) ) 7921 { 7922 r_config_rsp_lines = r_config_rsp_lines.read() - 1; 7923 } 7924 7892 7925 } // end transition() 7893 7926
Note: See TracChangeset
for help on using the changeset viewer.