- Timestamp:
- Jul 29, 2013, 11:31:38 AM (11 years ago)
- Location:
- branches/ODCCP/modules/vci_cc_vcache_wrapper
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/ODCCP/modules/vci_cc_vcache_wrapper
-
Property
svn:mergeinfo
set to
(toggle deleted branches)
/trunk/modules/vci_cc_vcache_wrapper merged eligible /branches/v5/modules/vci_cc_vcache_wrapper 444-467
-
Property
svn:mergeinfo
set to
(toggle deleted branches)
-
branches/ODCCP/modules/vci_cc_vcache_wrapper/caba/source/src/vci_cc_vcache_wrapper.cpp
r460 r479 65 65 66 66 "ICACHE_CC_CHECK", 67 "ICACHE_CC_UPDT", 67 68 "ICACHE_CC_INVAL", 68 "ICACHE_CC_UPDT",69 "ICACHE_CC_BROADCAST",70 "ICACHE_CC_SEND_WAIT",71 69 }; 72 70 … … 116 114 117 115 "DCACHE_CC_CHECK", 116 "DCACHE_CC_UPDT", 117 "DCACHE_CC_INVAL", 118 118 "DCACHE_CC_INVAL_DATA", 119 "DCACHE_CC_INVAL",120 "DCACHE_CC_UPDT",121 "DCACHE_CC_BROADCAST",122 "DCACHE_CC_SEND_WAIT",123 119 124 120 "DCACHE_INVAL_TLB_SCAN", … … 167 163 const char *cc_receive_fsm_state_str[] = { 168 164 "CC_RECEIVE_IDLE", 169 "CC_RECEIVE_CLACK",170 165 "CC_RECEIVE_BRDCAST_HEADER", 171 166 "CC_RECEIVE_BRDCAST_NLINE", 172 "CC_RECEIVE_INVAL_HEADER", 173 "CC_RECEIVE_INVAL_NLINE", 174 "CC_RECEIVE_UPDT_HEADER", 175 "CC_RECEIVE_UPDT_NLINE", 176 "CC_RECEIVE_UPDT_DATA", 167 "CC_RECEIVE_INS_INVAL_HEADER", 168 "CC_RECEIVE_INS_INVAL_NLINE", 169 "CC_RECEIVE_INS_UPDT_HEADER", 170 "CC_RECEIVE_INS_UPDT_NLINE", 171 "CC_RECEIVE_INS_UPDT_DATA", 172 "CC_RECEIVE_DATA_INVAL_HEADER", 173 "CC_RECEIVE_DATA_INVAL_NLINE", 174 "CC_RECEIVE_DATA_UPDT_HEADER", 175 "CC_RECEIVE_DATA_UPDT_NLINE", 176 "CC_RECEIVE_DATA_UPDT_DATA", 177 177 }; 178 178 … … 224 224 p_resetn("p_resetn"), 225 225 p_vci("p_vci"), 226 p_dspin_in("p_dspin_in"), 227 p_dspin_out("p_dspin_out"), 226 p_dspin_m2p("p_dspin_m2p"), 227 p_dspin_p2m("p_dspin_p2m"), 228 p_dspin_clack("p_dspin_clack"), 228 229 229 230 m_cacheability_table( mtd.getCacheabilityTable() ), … … 792 793 r_icache_cc_send_req = false; 793 794 795 r_icache_clack_req = false; 796 794 797 // No pending write in pipeline 795 798 r_dcache_wbuf_req = false; … … 812 815 r_dcache_cc_send_req = false; 813 816 817 r_dcache_clack_req = false; 818 814 819 // No request from CC_RECEIVE FSM to ICACHE/DCACHE FSMs 815 820 r_cc_receive_icache_req = false; … … 826 831 r_icache_miss_inval = false; 827 832 r_dcache_miss_inval = false; 833 834 r_dspin_clack_req = false; 828 835 829 836 // No signalisation of errors … … 1077 1084 // 5/ uncacheable read miss => ICACHE_UNC_REQ 1078 1085 { 1086 // coherence clack interrupt 1087 if ( r_icache_clack_req.read() ) 1088 { 1089 r_icache_fsm = ICACHE_CC_CHECK; 1090 r_icache_fsm_save = r_icache_fsm.read(); 1091 break; 1092 } 1093 1079 1094 // coherence interrupt 1080 1095 if ( r_cc_receive_icache_req.read()) … … 1306 1321 // external coherence request are accepted in this state. 1307 1322 { 1323 // coherence clack interrupt 1324 if ( r_icache_clack_req.read() ) 1325 { 1326 r_icache_fsm = ICACHE_CC_CHECK; 1327 r_icache_fsm_save = r_icache_fsm.read(); 1328 break; 1329 } 1330 1308 1331 // coherence interrupt 1309 1332 if ( r_cc_receive_icache_req.read() ) … … 1350 1373 // A cleanup request is generated for each valid line 1351 1374 { 1375 // coherence clack interrupt 1376 if ( r_icache_clack_req.read() ) 1377 { 1378 r_icache_fsm = ICACHE_CC_CHECK; 1379 r_icache_fsm_save = r_icache_fsm.read(); 1380 break; 1381 } 1382 1352 1383 // coherence request (from CC_RECEIVE FSM) 1353 1384 if ( r_cc_receive_icache_req.read() ) … … 1548 1579 { 1549 1580 if (m_ireq.valid) m_cost_ins_miss_frz++; 1581 1582 // coherence clack interrupt 1583 if ( r_icache_clack_req.read() ) 1584 { 1585 r_icache_fsm = ICACHE_CC_CHECK; 1586 r_icache_fsm_save = r_icache_fsm.read(); 1587 break; 1588 } 1550 1589 1551 1590 // coherence interrupt … … 1638 1677 if (m_ireq.valid) m_cost_ins_miss_frz++; 1639 1678 1679 // coherence clack interrupt 1680 if ( r_icache_clack_req.read() ) 1681 { 1682 r_icache_fsm = ICACHE_CC_CHECK; 1683 r_icache_fsm_save = r_icache_fsm.read(); 1684 break; 1685 } 1686 1640 1687 // coherence interrupt 1641 1688 if ( r_cc_receive_icache_req.read() ) … … 1709 1756 if ( m_ireq.valid ) m_cost_ins_miss_frz++; 1710 1757 1758 // coherence clack interrupt 1759 if ( r_icache_clack_req.read() ) 1760 { 1761 r_icache_fsm = ICACHE_CC_CHECK; 1762 r_icache_fsm_save = r_icache_fsm.read(); 1763 break; 1764 } 1765 1711 1766 // coherence interrupt 1712 1767 if ( r_cc_receive_icache_req.read() ) … … 1780 1835 case ICACHE_UNC_WAIT: // waiting a response to an uncacheable read from VCI_RSP FSM 1781 1836 { 1837 // coherence clack interrupt 1838 if ( r_icache_clack_req.read() ) 1839 { 1840 r_icache_fsm = ICACHE_CC_CHECK; 1841 r_icache_fsm_save = r_icache_fsm.read(); 1842 break; 1843 } 1844 1782 1845 // coherence interrupt 1783 1846 if ( r_cc_receive_icache_req.read() ) … … 1820 1883 paddr_t mask = ~((m_icache_words<<2)-1); 1821 1884 1822 if (r_cc_receive_icache_type.read() == CC_TYPE_CLACK) 1823 // We switch the directory slot to EMPTY state 1824 // and reset r_icache_miss_clack if the cleanup ack 1825 // is matching a pending miss 1826 { 1827 1828 if ( m_ireq.valid ) m_cost_ins_miss_frz++; 1829 1830 #ifdef INSTRUMENTATION 1831 m_cpt_icache_dir_write++; 1832 #endif 1833 r_icache.write_dir( 0, 1834 r_cc_receive_icache_way.read(), 1835 r_cc_receive_icache_set.read(), 1836 CACHE_SLOT_STATE_EMPTY); 1837 1838 if ( (r_icache_miss_set.read() == r_cc_receive_icache_set.read()) and 1839 (r_icache_miss_way.read() == r_cc_receive_icache_way.read()) ) 1840 r_icache_miss_clack = false; 1841 1842 r_icache_fsm = r_icache_fsm_save.read() ; 1843 r_cc_receive_icache_req = false; 1844 1845 #if DEBUG_ICACHE 1846 if ( m_debug_activated ) 1847 { 1848 std::cout << " <PROC " << name() 1849 << " ICACHE_CC_CHECK> CC_TYPE_CLACK slot returns to empty state" 1850 << " set = " << r_cc_receive_icache_set.read() 1851 << " / way = " << r_cc_receive_icache_way.read() << std::endl; 1852 } 1853 #endif 1854 } 1855 else if( ((r_icache_fsm_save.read() == ICACHE_MISS_SELECT) or 1856 (r_icache_fsm_save.read() == ICACHE_MISS_WAIT) or 1857 (r_icache_fsm_save.read() == ICACHE_MISS_DIR_UPDT)) and 1858 ((r_icache_vci_paddr.read() & mask) == (paddr & mask)) ) // matching 1885 1886 // Match between MISS address and CC address 1887 // note: In the same cycle we can handle a CLACK and a MISS match 1888 // because the CLACK access the directory but the MISS match dont. 1889 if (r_cc_receive_icache_req.read() and 1890 ((r_icache_fsm_save.read() == ICACHE_MISS_SELECT ) or 1891 (r_icache_fsm_save.read() == ICACHE_MISS_WAIT ) or 1892 (r_icache_fsm_save.read() == ICACHE_MISS_DIR_UPDT)) and 1893 ((r_icache_vci_paddr.read() & mask) == (paddr & mask)) ) // matching 1859 1894 { 1860 1895 // signaling the matching … … 1867 1902 r_icache_fsm = ICACHE_CC_UPDT; 1868 1903 r_icache_cc_word = r_cc_receive_word_idx.read(); 1904 1869 1905 // just pop the fifo , don't write in icache 1870 1906 r_icache_cc_need_write = false; … … 1885 1921 #endif 1886 1922 } 1887 else // no match 1888 { 1889 int state = 0; 1890 size_t way = 0; 1891 size_t set = 0; 1892 size_t word = 0; 1923 1924 // CLACK handler 1925 // We switch the directory slot to EMPTY state 1926 // and reset r_icache_miss_clack if the cleanup ack 1927 // is matching a pending miss. 1928 if ( r_icache_clack_req.read() ) 1929 { 1930 1931 if ( m_ireq.valid ) m_cost_ins_miss_frz++; 1893 1932 1894 1933 #ifdef INSTRUMENTATION 1895 m_cpt_icache_dir_read++; 1896 #endif 1897 r_icache.read_dir(paddr, 1898 &state, 1899 &way, 1900 &set, 1901 &word); 1902 1903 r_icache_cc_way = way; 1904 r_icache_cc_set = set; 1905 1906 if ( state == CACHE_SLOT_STATE_VALID_CC) // hit 1907 { 1908 // need to update the cache state 1909 r_icache_cc_need_write = true; 1910 if (r_cc_receive_icache_type.read() == CC_TYPE_UPDT) // hit update 1911 { 1912 r_icache_fsm = ICACHE_CC_UPDT; 1913 r_icache_cc_word = r_cc_receive_word_idx.read(); 1914 } 1915 else if (r_cc_receive_icache_type.read() == CC_TYPE_INVAL) // hit inval 1916 { 1917 r_icache_fsm = ICACHE_CC_INVAL; 1918 } 1919 else if (r_cc_receive_icache_type.read() == CC_TYPE_BRDCAST) // hit broadcast 1920 { 1921 r_icache_fsm = ICACHE_CC_BROADCAST; 1922 } 1923 } 1924 else // miss 1925 { 1926 // multicast acknowledgement required in case of update 1927 if(r_cc_receive_icache_type.read() == CC_TYPE_UPDT) 1928 { 1929 r_icache_fsm = ICACHE_CC_UPDT; 1930 r_icache_cc_word = r_cc_receive_word_idx.read(); 1931 // just pop the fifo , don't write in icache 1932 r_icache_cc_need_write = false; 1933 } 1934 else // No response needed 1935 { 1936 r_cc_receive_icache_req = false; 1937 r_icache_fsm = r_icache_fsm_save.read(); 1938 } 1939 } 1940 } 1941 break; 1942 } 1943 ///////////////////// 1944 case ICACHE_CC_INVAL: // hit inval : switch slot to EMPTY state 1945 { 1934 m_cpt_icache_dir_write++; 1935 #endif 1936 r_icache.write_dir( 0, 1937 r_icache_clack_way.read(), 1938 r_icache_clack_set.read(), 1939 CACHE_SLOT_STATE_EMPTY); 1940 1941 if ( (r_icache_miss_set.read() == r_icache_clack_set.read()) and 1942 (r_icache_miss_way.read() == r_icache_clack_way.read()) ) 1943 { 1944 r_icache_miss_clack = false; 1945 } 1946 1947 r_icache_clack_req = false; 1948 1949 // return to cc_save state if no pending CC request 1950 if ( not r_cc_receive_icache_req.read() ) 1951 r_icache_fsm = r_icache_fsm_save.read(); 1946 1952 1947 1953 #if DEBUG_ICACHE … … 1949 1955 { 1950 1956 std::cout << " <PROC " << name() 1951 << " ICACHE_//CC_INVAL>slot returns to empty state"1952 << " set = " << r_icache_cc_set.read()1953 << " / way = " << r_icache_cc_way.read() << std::endl;1957 << " ICACHE_CC_CHECK> CC_TYPE_CLACK slot returns to empty state" 1958 << " set = " << r_icache_clack_set.read() 1959 << " / way = " << r_icache_clack_way.read() << std::endl; 1954 1960 } 1955 1961 #endif 1962 1963 break; 1964 } 1965 1966 // wait if pending request to CC_SEND. This way if there are pending 1967 // CLACK they can be treated in this state and then a deadlock 1968 // situation is avoided 1969 if ( r_icache_cc_send_req.read() ) break; 1970 1971 // CC request handler 1972 1973 int state = 0; 1974 size_t way = 0; 1975 size_t set = 0; 1976 size_t word = 0; 1956 1977 1957 1978 #ifdef INSTRUMENTATION 1958 1979 m_cpt_icache_dir_read++; 1959 1980 #endif 1960 1961 if (r_icache_cc_need_write.read()) 1962 { 1963 r_icache.write_dir( 0, 1964 r_icache_cc_way.read(), 1965 r_icache_cc_set.read(), 1966 CACHE_SLOT_STATE_EMPTY ); 1967 // no need to write in the cache anymore 1981 r_icache.read_dir(paddr, 1982 &state, 1983 &way, 1984 &set, 1985 &word); 1986 1987 r_icache_cc_way = way; 1988 r_icache_cc_set = set; 1989 1990 if ( state == CACHE_SLOT_STATE_VALID_CC) // hit 1991 { 1992 // need to update the cache state 1993 if (r_cc_receive_icache_type.read() == CC_TYPE_UPDT) // hit update 1994 { 1995 r_icache_cc_need_write = true; 1996 r_icache_fsm = ICACHE_CC_UPDT; 1997 r_icache_cc_word = r_cc_receive_word_idx.read(); 1998 } 1999 else if ( r_cc_receive_icache_type.read() == CC_TYPE_INVAL ) // hit inval 2000 { 2001 r_icache_fsm = ICACHE_CC_INVAL; 2002 } 2003 } 2004 else // miss 2005 { 2006 // multicast acknowledgement required in case of update 2007 if(r_cc_receive_icache_type.read() == CC_TYPE_UPDT) 2008 { 2009 r_icache_fsm = ICACHE_CC_UPDT; 2010 r_icache_cc_word = r_cc_receive_word_idx.read(); 2011 2012 // just pop the fifo , don't write in icache 1968 2013 r_icache_cc_need_write = false; 1969 2014 } 1970 // multicast acknowledgement 1971 // send a request to cc_send_fsm 1972 if(not r_icache_cc_send_req.read()) // cc_send is available 1973 { 1974 // coherence request completed 1975 r_cc_receive_icache_req = false; 1976 // request multicast acknowledgement 1977 r_icache_cc_send_req = true; 1978 r_icache_cc_send_nline = r_cc_receive_icache_nline.read(); 1979 r_icache_cc_send_updt_tab_idx = r_cc_receive_icache_updt_tab_idx.read(); 1980 r_icache_cc_send_type = CC_TYPE_MULTI_ACK; 1981 1982 r_icache_fsm = r_icache_fsm_save.read(); 1983 } 1984 //else wait for previous cc_send request to be sent 2015 else // No response needed 2016 { 2017 r_cc_receive_icache_req = false; 2018 r_icache_fsm = r_icache_fsm_save.read(); 2019 } 2020 } 2021 break; 2022 } 2023 ///////////////////// 2024 case ICACHE_CC_INVAL: // hit inval : switch slot to ZOMBI state 2025 { 2026 assert (not r_icache_cc_send_req.read() && 2027 "ERROR in ICACHE_CC_INVAL: the r_icache_cc_send_req " 2028 "must not be set"); 2029 2030 #ifdef INSTRUMENTATION 2031 m_cpt_icache_dir_read++; 2032 #endif 2033 2034 // Switch slot state to ZOMBI and send CLEANUP command 2035 r_icache.write_dir( 0, 2036 r_icache_cc_way.read(), 2037 r_icache_cc_set.read(), 2038 CACHE_SLOT_STATE_ZOMBI ); 2039 2040 // coherence request completed 2041 r_icache_cc_send_req = true; 2042 r_icache_cc_send_nline = r_cc_receive_icache_nline.read(); 2043 r_icache_cc_send_way = r_icache_cc_way.read(); 2044 r_icache_cc_send_type = CC_TYPE_CLEANUP; 2045 2046 r_icache_fsm = r_icache_fsm_save.read(); 2047 2048 #if DEBUG_ICACHE 2049 if ( m_debug_activated ) 2050 { 2051 std::cout << " <PROC " << name() 2052 << " ICACHE_CC_INVAL> slot returns to ZOMBI state" 2053 << " set = " << r_icache_cc_set.read() 2054 << " / way = " << r_icache_cc_way.read() << std::endl; 2055 } 2056 #endif 2057 1985 2058 break; 1986 2059 } … … 1988 2061 case ICACHE_CC_UPDT: // hit update : write one word per cycle 1989 2062 { 2063 assert (not r_icache_cc_send_req.read() && 2064 "ERROR in ICACHE_CC_UPDT: the r_icache_cc_send_req " 2065 "must not be set"); 2066 2067 if ( not r_cc_receive_updt_fifo_be.rok() ) break; 2068 2069 2070 size_t word = r_icache_cc_word.read(); 2071 size_t way = r_icache_cc_way.read(); 2072 size_t set = r_icache_cc_set.read(); 2073 2074 if (r_icache_cc_need_write.read()) 2075 { 2076 r_icache.write( way, 2077 set, 2078 word, 2079 r_cc_receive_updt_fifo_data.read(), 2080 r_cc_receive_updt_fifo_be.read() ); 2081 2082 r_icache_cc_word = word+1; 2083 2084 #ifdef INSTRUMENTATION 2085 m_cpt_icache_data_write++; 2086 #endif 1990 2087 1991 2088 #if DEBUG_ICACHE … … 1999 2096 } 2000 2097 #endif 2001 2002 #ifdef INSTRUMENTATION 2003 m_cpt_icache_data_write++; 2004 #endif 2005 size_t word = r_icache_cc_word.read(); 2006 size_t way = r_icache_cc_way.read(); 2007 size_t set = r_icache_cc_set.read(); 2008 2009 if (r_cc_receive_updt_fifo_be.rok()) 2010 { 2011 if (r_icache_cc_need_write.read()) 2012 { 2013 r_icache.write( way, 2014 set, 2015 word, 2016 r_cc_receive_updt_fifo_data.read(), 2017 r_cc_receive_updt_fifo_be.read() ); 2018 2019 r_icache_cc_word = word+1; 2020 } 2021 if ( r_cc_receive_updt_fifo_eop.read() ) // last word 2022 { 2098 } 2099 2100 if ( r_cc_receive_updt_fifo_eop.read() ) // last word 2101 { 2023 2102 // no need to write in the cache anymore 2024 r_icache_cc_need_write = false; 2025 // wait to send a request to cc_send_fsm 2026 if(not r_icache_cc_send_req.read()) // cc_send is available 2027 { 2028 //consume last flit 2029 cc_receive_updt_fifo_get = true; 2030 // coherence request completed 2031 r_cc_receive_icache_req = false; 2032 // request multicast acknowledgement 2033 r_icache_cc_send_req = true; 2034 r_icache_cc_send_nline = r_cc_receive_icache_nline.read(); 2035 r_icache_cc_send_updt_tab_idx = r_cc_receive_icache_updt_tab_idx.read(); 2036 r_icache_cc_send_type = CC_TYPE_MULTI_ACK; 2037 2038 r_icache_fsm = r_icache_fsm_save.read(); 2039 } 2040 } 2041 else 2042 { 2043 //consume fifo if not eop 2044 cc_receive_updt_fifo_get = true; 2045 } 2046 } 2103 r_icache_cc_need_write = false; 2104 2105 // coherence request completed 2106 r_cc_receive_icache_req = false; 2107 2108 // request multicast acknowledgement 2109 r_icache_cc_send_req = true; 2110 r_icache_cc_send_nline = r_cc_receive_icache_nline.read(); 2111 r_icache_cc_send_updt_tab_idx = r_cc_receive_icache_updt_tab_idx.read(); 2112 r_icache_cc_send_type = CC_TYPE_MULTI_ACK; 2113 2114 r_icache_fsm = r_icache_fsm_save.read(); 2115 } 2116 //consume fifo if not eop 2117 cc_receive_updt_fifo_get = true; 2118 2047 2119 break; 2048 2120 } 2049 ///////////////////////// 2050 case ICACHE_CC_BROADCAST: // hit broadcast : switch slot to ZOMBI state 2051 // and request a cleanup 2052 { 2053 2054 #if DEBUG_ICACHE 2055 if ( m_debug_activated ) 2056 { 2057 std::cout << " <PROC " << name() 2058 << " ICACHE_CC_BROADCAST > Slot goes to zombi state " 2059 << " set = " << r_icache_cc_set.read() 2060 << " / way = " << r_icache_cc_way.read() << std::endl; 2061 } 2062 #endif 2063 2064 #ifdef INSTRUMENTATION 2065 m_cpt_icache_dir_write++; 2066 #endif 2067 if (r_icache_cc_need_write.read()) 2068 { 2069 r_icache.write_dir( r_icache_cc_way.read(), 2070 r_icache_cc_set.read(), 2071 CACHE_SLOT_STATE_ZOMBI ); 2072 // no need to write in the cache anymore 2073 r_icache_cc_need_write = false; 2074 } 2075 2076 // cleanup 2077 // send a request to cc_send_fsm 2078 if(not r_icache_cc_send_req.read()) // cc_send is available 2079 { 2080 // coherence request completed 2081 r_cc_receive_icache_req = false; 2082 // request cleanup 2083 r_icache_cc_send_req = true; 2084 r_icache_cc_send_nline = r_cc_receive_icache_nline.read(); 2085 r_icache_cc_send_way = r_icache_cc_way.read(); 2086 r_icache_cc_send_type = CC_TYPE_CLEANUP; 2087 2088 r_icache_fsm = r_icache_fsm_save.read(); 2089 } 2090 //else wait for previous cc_send request to be sent 2091 break; 2092 } 2121 2093 2122 } // end switch r_icache_fsm 2094 2123 … … 2371 2400 } 2372 2401 2402 // coherence clack request (from DSPIN CLACK) 2403 else if ( r_dcache_clack_req.read() ) 2404 { 2405 r_dcache_fsm = DCACHE_CC_CHECK; 2406 r_dcache_fsm_cc_save = r_dcache_fsm.read(); 2407 } 2373 2408 // coherence request (from CC_RECEIVE FSM) 2374 2409 else if ( r_cc_receive_dcache_req.read() ) … … 3067 3102 case DCACHE_TLB_PTE1_GET: // try to read a PT1 entry in dcache 3068 3103 { 3104 // coherence clack request (from DSPIN CLACK) 3105 if ( r_dcache_clack_req.read() ) 3106 { 3107 r_dcache_fsm = DCACHE_CC_CHECK; 3108 r_dcache_fsm_cc_save = r_dcache_fsm.read(); 3109 break; 3110 } 3111 3069 3112 // coherence request (from CC_RECEIVE FSM) 3070 3113 if ( r_cc_receive_dcache_req.read() ) … … 3366 3409 case DCACHE_TLB_PTE2_GET: // Try to get a PTE2 (64 bits) in the dcache 3367 3410 { 3411 // coherence clack request (from DSPIN CLACK) 3412 if ( r_dcache_clack_req.read() ) 3413 { 3414 r_dcache_fsm = DCACHE_CC_CHECK; 3415 r_dcache_fsm_cc_save = r_dcache_fsm.read(); 3416 break; 3417 } 3418 3368 3419 // coherence request (from CC_RECEIVE FSM) 3369 3420 if ( r_cc_receive_dcache_req.read() ) … … 3665 3716 3666 3717 { 3718 // coherence clack request (from DSPIN CLACK) 3719 if ( r_dcache_clack_req.read() ) 3720 { 3721 r_dcache_fsm = DCACHE_CC_CHECK; 3722 r_dcache_fsm_cc_save = r_dcache_fsm.read(); 3723 break; 3724 } 3725 3667 3726 // coherence request (from CC_RECEIVE FSM) 3668 3727 if ( r_cc_receive_dcache_req.read() ) … … 3736 3795 // as there is a risk of dead-lock 3737 3796 { 3797 // coherence clack request (from DSPIN CLACK) 3798 if ( r_dcache_clack_req.read() ) 3799 { 3800 r_dcache_fsm = DCACHE_CC_CHECK; 3801 r_dcache_fsm_cc_save = r_dcache_fsm.read(); 3802 break; 3803 } 3804 3738 3805 // coherence request (from CC_RECEIVE FSM) 3739 3806 if ( r_cc_receive_dcache_req.read() ) … … 3741 3808 r_dcache_fsm = DCACHE_CC_CHECK; 3742 3809 r_dcache_fsm_cc_save = r_dcache_fsm.read(); 3810 break; 3743 3811 } 3744 3812 … … 3757 3825 // and because it can exist a simultaneous ITLB miss 3758 3826 { 3827 // coherence clack request (from DSPIN CLACK) 3828 if ( r_dcache_clack_req.read() ) 3829 { 3830 r_dcache_fsm = DCACHE_CC_CHECK; 3831 r_dcache_fsm_cc_save = r_dcache_fsm.read(); 3832 break; 3833 } 3834 3759 3835 // coherence request (from CC_RECEIVE FSM) 3760 3836 if ( r_cc_receive_dcache_req.read() ) … … 3792 3868 // returns to IDLE and flush TLBs when last slot 3793 3869 { 3870 // coherence clack request (from DSPIN CLACK) 3871 if ( r_dcache_clack_req.read() ) 3872 { 3873 r_dcache_fsm = DCACHE_CC_CHECK; 3874 r_dcache_fsm_cc_save = r_dcache_fsm.read(); 3875 break; 3876 } 3877 3794 3878 // coherence request (from CC_RECEIVE FSM) 3795 3879 if ( r_cc_receive_dcache_req.read() ) … … 3895 3979 r_dcache_xtn_flush_addr_data = r_dcache_xtn_flush_addr_data.read() + 4; 3896 3980 3897 cleanup_data_updt_fifo_dcache_get = false;3898 3981 cleanup_data_updt_fifo_dcache_put = true; 3899 3982 cleanup_data_updt_fifo_dcache_data = rdata; … … 4158 4241 r_dcache_xtn_data_addr = r_dcache_xtn_data_addr.read() + 4; 4159 4242 4160 cleanup_data_updt_fifo_dcache_get = false;4161 4243 cleanup_data_updt_fifo_dcache_put = true; 4162 4244 cleanup_data_updt_fifo_dcache_data = rdata; … … 4193 4275 { 4194 4276 if ( m_dreq.valid) m_cost_data_miss_frz++; 4277 4278 // coherence clack request (from DSPIN CLACK) 4279 if ( r_dcache_clack_req.read() ) 4280 { 4281 r_dcache_fsm = DCACHE_CC_CHECK; 4282 r_dcache_fsm_cc_save = r_dcache_fsm.read(); 4283 break; 4284 } 4195 4285 4196 4286 // coherence request (from CC_RECEIVE FSM) … … 4247 4337 r_dcache_fsm = DCACHE_MISS_DATA; 4248 4338 m_cpt_data_cleanup_dirty ++; 4249 4339 4250 4340 /*STATS DIRTY*/ 4251 4341 for (size_t w = 0; w < m_dcache_words; w++) … … 4294 4384 size_t set; 4295 4385 size_t word; 4296 4297 4386 r_dcache.read_neutral(r_dcache_miss_data_addr, 4298 4387 &rdata, … … 4300 4389 &set, 4301 4390 &word); 4391 4302 4392 if(r_cc_send_data_fifo.wok()) 4303 4393 { 4304 4394 r_dcache_miss_data_addr = r_dcache_miss_data_addr.read() + 4; 4305 4395 4306 cleanup_data_updt_fifo_dcache_get = false;4307 4396 cleanup_data_updt_fifo_dcache_put = true; 4308 4397 cleanup_data_updt_fifo_dcache_data = rdata; … … 4314 4403 r_dcache_fsm = DCACHE_MISS_CLEAN; 4315 4404 } 4405 #if DEBUG_DCACHE 4406 if ( m_debug_activated ) 4407 { 4408 std::cout << " <PROC " << name() 4409 << " DCACHE_MISS_DATA>:" << std::hex 4410 << " / DATA = " << rdata 4411 << " / WORD = " << word 4412 << " / PADDR = " << std::hex << r_dcache_miss_data_addr.read() << std::endl; 4413 } 4414 #endif 4316 4415 } 4317 4416 break; … … 4370 4469 { 4371 4470 if ( m_dreq.valid) m_cost_data_miss_frz++; 4471 4472 // coherence clack request (from DSPIN CLACK) 4473 if ( r_dcache_clack_req.read() ) 4474 { 4475 r_dcache_fsm = DCACHE_CC_CHECK; 4476 r_dcache_fsm_cc_save = r_dcache_fsm.read(); 4477 break; 4478 } 4372 4479 4373 4480 // coherence request (from CC_RECEIVE FSM) … … 4486 4593 if ( m_dreq.valid) m_cost_data_miss_frz++; 4487 4594 4595 // coherence clack request (from DSPIN CLACK) 4596 if ( r_dcache_clack_req.read() ) 4597 { 4598 r_dcache_fsm = DCACHE_CC_CHECK; 4599 r_dcache_fsm_cc_save = r_dcache_fsm.read(); 4600 break; 4601 } 4602 4488 4603 // coherence request (from CC_RECEIVE FSM) 4489 4604 if ( r_cc_receive_dcache_req.read() ) … … 4592 4707 case DCACHE_UNC_WAIT: // waiting a response to an uncacheable read 4593 4708 { 4709 // coherence clack request (from DSPIN CLACK) 4710 if ( r_dcache_clack_req.read() ) 4711 { 4712 r_dcache_fsm = DCACHE_CC_CHECK; 4713 r_dcache_fsm_cc_save = r_dcache_fsm.read(); 4714 break; 4715 } 4716 4594 4717 // coherence request (from CC_RECEIVE FSM) 4595 4718 if ( r_cc_receive_dcache_req.read() ) … … 4629 4752 case DCACHE_LL_WAIT: // waiting VCI response to a LL transaction 4630 4753 { 4754 // coherence clack request (from DSPIN CLACK) 4755 if ( r_dcache_clack_req.read() ) 4756 { 4757 r_dcache_fsm = DCACHE_CC_CHECK; 4758 r_dcache_fsm_cc_save = r_dcache_fsm.read(); 4759 break; 4760 } 4761 4631 4762 // coherence request (from CC_RECEIVE FSM) 4632 4763 if ( r_cc_receive_dcache_req.read() ) … … 4675 4806 case DCACHE_SC_WAIT: // waiting VCI response to a SC transaction 4676 4807 { 4808 // coherence clack request (from DSPIN CLACK) 4809 if ( r_dcache_clack_req.read() ) 4810 { 4811 r_dcache_fsm = DCACHE_CC_CHECK; 4812 r_dcache_fsm_cc_save = r_dcache_fsm.read(); 4813 break; 4814 } 4815 4677 4816 // coherence request (from CC_RECEIVE FSM) 4678 4817 if ( r_cc_receive_dcache_req.read() ) … … 4714 4853 size_t way; 4715 4854 size_t set; 4716 size_t word; 4855 size_t word; // unused 4717 4856 int state; 4718 4857 … … 4767 4906 // - if the CAS is a failure, we just retry the write. 4768 4907 { 4908 // coherence clack request (from DSPIN CLACK) 4909 if ( r_dcache_clack_req.read() ) 4910 { 4911 r_dcache_fsm = DCACHE_CC_CHECK; 4912 r_dcache_fsm_cc_save = r_dcache_fsm.read(); 4913 break; 4914 } 4915 4769 4916 // coherence request (from CC_RECEIVE FSM) 4770 4917 if ( r_cc_receive_dcache_req.read() ) … … 4775 4922 } 4776 4923 4777 if ( r_vci_rsp_data_error.read() ) 4924 if ( r_vci_rsp_data_error.read() ) // bus error 4778 4925 { 4779 4926 std::cout << "BUS ERROR in DCACHE_DIRTY_WAIT state" << std::endl; … … 4781 4928 exit(0); 4782 4929 } 4783 else if ( r_vci_rsp_fifo_dcache.rok() ) 4930 else if ( r_vci_rsp_fifo_dcache.rok() ) // response available 4784 4931 { 4785 4932 vci_rsp_fifo_dcache_get = true; … … 4825 4972 #endif 4826 4973 4827 if (r_cc_receive_dcache_type.read() == CC_TYPE_CLACK) 4828 // We switch the directory slot to EMPTY state 4829 // and reset r_icache_miss_clack if the cleanup ack 4830 // is matching a pending miss. 4831 { 4832 4833 if ( m_dreq.valid ) m_cost_data_miss_frz++; 4834 4835 #ifdef INSTRUMENTATION 4836 m_cpt_dcache_dir_write++; 4837 #endif 4838 r_dcache.write_dir( 0, 4839 r_cc_receive_dcache_way.read(), 4840 r_cc_receive_dcache_set.read(), 4841 CACHE_SLOT_STATE_EMPTY); 4842 4843 /*STATS DIRTY*/ 4844 for (size_t word = 0; word < m_dcache_words; word++) 4845 { 4846 dirty_stats[(r_cc_receive_dcache_way * m_dcache_sets + r_cc_receive_dcache_set) * m_dcache_words + word] = false; 4847 } 4848 4849 4850 if ( (r_dcache_miss_set.read() == r_cc_receive_dcache_set.read()) and 4851 (r_dcache_miss_way.read() == r_cc_receive_dcache_way.read()) ) 4852 r_dcache_miss_clack = false; 4853 4854 r_dcache_fsm = r_dcache_fsm_cc_save.read() ; 4855 r_cc_receive_dcache_req = false; 4856 #if DEBUG_DCACHE 4857 if ( m_debug_activated ) 4858 { 4859 std::cout << " <PROC " << name() 4860 << " DCACHE_CC_CHECK> CC_TYPE_CLACK Switch slot to EMPTY state" 4861 << " set = " << r_cc_receive_dcache_set.read() 4862 << " / way = " << r_cc_receive_dcache_way.read() << std::endl; 4863 } 4864 #endif 4865 } 4866 else if( ((r_dcache_fsm_cc_save == DCACHE_MISS_SELECT) or 4867 (r_dcache_fsm_cc_save == DCACHE_MISS_WAIT) or 4868 (r_dcache_fsm_cc_save == DCACHE_MISS_DIR_UPDT)) and 4869 ((r_dcache_vci_paddr.read() & mask) == (paddr & mask)) ) // matching 4974 4975 // Match between MISS address and CC address 4976 // note: In the same cycle we can handle a CLACK and a MISS match 4977 // because the CLACK access the directory but the MISS match dont. 4978 if (r_cc_receive_dcache_req.read() and 4979 ((r_dcache_fsm_cc_save == DCACHE_MISS_SELECT ) or 4980 (r_dcache_fsm_cc_save == DCACHE_MISS_WAIT ) or 4981 (r_dcache_fsm_cc_save == DCACHE_MISS_DIR_UPDT)) and 4982 ((r_dcache_vci_paddr.read() & mask) == (paddr & mask))) // matching 4870 4983 { 4871 4984 // signaling matching … … 4878 4991 r_dcache_fsm = DCACHE_CC_UPDT; 4879 4992 r_dcache_cc_word = r_cc_receive_word_idx.read(); 4993 4880 4994 // just pop the fifo , don't write in icache 4881 4995 r_dcache_cc_need_write = false; … … 4885 4999 { 4886 5000 r_cc_receive_dcache_req = false; 4887 r_dcache_fsm = r_dcache_fsm_cc_save.read();5001 r_dcache_fsm = r_dcache_fsm_cc_save.read(); 4888 5002 } 4889 5003 … … 4896 5010 } 4897 5011 #endif 4898 4899 } 4900 else // no match 4901 { 4902 int state = 0; 4903 size_t way = 0; 4904 size_t set = 0; 4905 size_t word = 0; 5012 } 5013 5014 // CLACK handler 5015 // We switch the directory slot to EMPTY state and reset 5016 // r_dcache_miss_clack if the cleanup ack is matching a pending miss. 5017 if ( r_dcache_clack_req.read() ) 5018 { 5019 if ( m_dreq.valid ) m_cost_data_miss_frz++; 5020 5021 #ifdef INSTRUMENTATION 5022 m_cpt_dcache_dir_write++; 5023 #endif 5024 r_dcache.write_dir( 0, 5025 r_dcache_clack_way.read(), 5026 r_dcache_clack_set.read(), 5027 CACHE_SLOT_STATE_EMPTY); 5028 /*STATS DIRTY*/ 5029 for (size_t word = 0; word < m_dcache_words; word++) 5030 { 5031 dirty_stats[(r_cc_receive_dcache_way * m_dcache_sets + r_cc_receive_dcache_set) * m_dcache_words + word] = false; 5032 } 5033 5034 if ( (r_dcache_miss_set.read() == r_dcache_clack_set.read()) and 5035 (r_dcache_miss_way.read() == r_dcache_clack_way.read()) ) 5036 { 5037 r_dcache_miss_clack = false; 5038 } 5039 5040 r_dcache_clack_req = false; 5041 5042 // return to cc_save state if no pending CC request 5043 if ( not r_cc_receive_dcache_req.read() ) 5044 { 5045 r_dcache_fsm = r_dcache_fsm_cc_save.read() ; 5046 } 5047 5048 #if DEBUG_DCACHE 5049 if ( m_debug_activated ) 5050 { 5051 std::cout << " <PROC " << name() 5052 << " DCACHE_CC_CHECK> CC_TYPE_CLACK Switch slot to EMPTY state" 5053 << " set = " << r_dcache_clack_set.read() 5054 << " / way = " << r_dcache_clack_way.read() << std::endl; 5055 } 5056 #endif 5057 break; 5058 } 5059 5060 // wait if pending request to CC_SEND. This way if there are pending 5061 // CLACK they can be treated in this state and then a deadlock 5062 // situation is avoided 5063 if ( r_dcache_cc_send_req.read() ) break; 5064 5065 // CC request handler 5066 5067 int state = 0; 5068 size_t way = 0; 5069 size_t set = 0; 5070 size_t word = 0; 4906 5071 4907 5072 #ifdef INSTRUMENTATION 4908 5073 m_cpt_dcache_dir_read++; 4909 5074 #endif 4910 r_dcache.read_dir( paddr, 4911 &state, 4912 &way, 4913 &set, 4914 &word ); // unused 4915 4916 r_dcache_cc_way = way; 4917 r_dcache_cc_set = set; 4918 /*ODCCP*/ 4919 if ((state == CACHE_SLOT_STATE_VALID_CC) or (state == CACHE_SLOT_STATE_VALID_NCC)) // hit 4920 { 4921 // need to update the cache state 4922 r_dcache_cleanup_ncc = false; 4923 r_dcache_cc_need_write = true; 4924 if (r_cc_receive_dcache_type.read() == CC_TYPE_UPDT) // hit update 5075 r_dcache.read_dir( paddr, 5076 &state, 5077 &way, 5078 &set, 5079 &word ); // unused 5080 5081 r_dcache_cc_way = way; 5082 r_dcache_cc_set = set; 5083 /*ODCCP*/ 5084 if ((state == CACHE_SLOT_STATE_VALID_CC) or (state == CACHE_SLOT_STATE_VALID_NCC)) // hit 5085 { 5086 r_dcache_cleanup_ncc = false; 5087 r_dcache_cc_need_write = true; 5088 if (r_cc_receive_dcache_type.read() == CC_TYPE_UPDT) // hit update 5089 { 5090 /*ODCCP*/ // we can't receive a CC_UPDT on a NCC line 5091 if (state == CACHE_SLOT_STATE_VALID_NCC) 5092 std::cout << "DCACHE_CC_CHECK : IMPOSSIBLE NCC STATE FOR CC_UPDT at cycle " << m_cpt_total_cycles << std::endl; 5093 assert((state != CACHE_SLOT_STATE_VALID_NCC) and "DCACHE_CC_CHECK : IMPOSSIBLE NCC STATE FOR CC_UPDT"); 5094 5095 r_dcache_fsm = DCACHE_CC_UPDT; 5096 r_dcache_cc_word = r_cc_receive_word_idx.read(); 5097 } 5098 else if (r_cc_receive_dcache_type.read() == CC_TYPE_INVAL) // hit inval 5099 { 5100 if ( (state == CACHE_SLOT_STATE_VALID_NCC) ) 4925 5101 { 4926 /*ODCCP*/ // we can't receive a CC_UPDT on a NCC line 4927 if (state == CACHE_SLOT_STATE_VALID_NCC) 4928 std::cout << "DCACHE_CC_CHECK : IMPOSSIBLE NCC STATE FOR CC_UPDT at cycle " << m_cpt_total_cycles << std::endl; 4929 assert((state != CACHE_SLOT_STATE_VALID_NCC) and "DCACHE_CC_CHECK : IMPOSSIBLE NCC STATE FOR CC_UPDT"); 4930 4931 r_dcache_fsm = DCACHE_CC_UPDT; 4932 r_dcache_cc_word = r_cc_receive_word_idx.read(); 5102 if (r_dcache_content_state[way*m_dcache_sets+set] == LINE_CACHE_DATA_DIRTY) 5103 m_cpt_data_cleanup_dirty ++; 5104 r_dcache_cc_state = state; 5105 r_dcache_cc_inval_addr = (paddr &~0x3F); 5106 r_dcache_cc_inval_data_cpt = 0; 4933 5107 } 4934 else if (r_cc_receive_dcache_type.read() == CC_TYPE_INVAL) // hit inval5108 else 4935 5109 { 4936 if ( (state == CACHE_SLOT_STATE_VALID_NCC) ) 4937 { 4938 if (r_dcache_content_state[way*m_dcache_sets+set] == LINE_CACHE_DATA_DIRTY) 4939 m_cpt_data_cleanup_dirty ++; 4940 r_dcache_cc_state = state; 4941 r_dcache_cc_inval_addr = (paddr &~0x3F); 4942 r_dcache_cc_inval_data_cpt = 0; 4943 } 4944 else 4945 { 4946 r_dcache_cc_state = state; 4947 r_dcache_cc_inval_addr = (paddr &~0x3F); 4948 } 4949 r_dcache_fsm = DCACHE_CC_INVAL; 5110 r_dcache_cc_state = state; 5111 r_dcache_cc_inval_addr = (paddr &~0x3F); 4950 5112 } 4951 else if ( r_cc_receive_dcache_type.read() == CC_TYPE_BRDCAST) // hit broadcast 4952 { 4953 assert((state != CACHE_SLOT_STATE_VALID_NCC) and "DCACHE_CC_CHECK : IMPOSSIBLE NCC STATE FOR CC_BROADCAST"); 4954 r_dcache_fsm = DCACHE_CC_BROADCAST; 4955 } 4956 } 4957 else // miss 4958 { 4959 // multicast acknowledgement required in case of update 4960 if(r_cc_receive_dcache_type.read() == CC_TYPE_UPDT) 4961 { 4962 r_dcache_fsm = DCACHE_CC_UPDT; 4963 r_dcache_cc_word = r_cc_receive_word_idx.read(); 4964 // just pop the fifo , don't write in icache 4965 r_dcache_cc_need_write = false; 4966 } 4967 else // No response needed 4968 { 4969 r_cc_receive_dcache_req = false; 4970 r_dcache_fsm = r_dcache_fsm_cc_save.read(); 4971 } 4972 } 5113 r_dcache_fsm = DCACHE_CC_INVAL; 5114 } 5115 } 5116 else // miss 5117 { 5118 // multicast acknowledgement required in case of update 5119 if(r_cc_receive_dcache_type.read() == CC_TYPE_UPDT) 5120 { 5121 r_dcache_fsm = DCACHE_CC_UPDT; 5122 r_dcache_cc_word = r_cc_receive_word_idx.read(); 5123 5124 // just pop the fifo , don't write in icache 5125 r_dcache_cc_need_write = false; 5126 } 5127 else // No response needed 5128 { 5129 r_cc_receive_dcache_req = false; 5130 r_dcache_fsm = r_dcache_fsm_cc_save.read(); 5131 } 5132 } 4973 5133 4974 5134 #if DEBUG_DCACHE … … 4982 5142 } 4983 5143 #endif 5144 5145 break; 5146 } 5147 ///////////////////// 5148 case DCACHE_CC_INVAL: // hit inval: switch slot to ZOMBI state and send a 5149 // CLEANUP after possible invalidation of copies in 5150 // TLBs 5151 { 5152 size_t way = r_dcache_cc_way.read(); 5153 size_t set = r_dcache_cc_set.read(); 5154 int state = r_dcache_cc_state.read(); 5155 if ( r_dcache_content_state[way*m_dcache_sets+set] == LINE_CACHE_IN_TLB ) 5156 { 5157 r_dcache_content_state[way*m_dcache_sets+set] = LINE_CACHE_DATA_NOT_DIRTY; 5158 r_dcache_tlb_inval_line = r_cc_receive_dcache_nline.read(); 5159 r_dcache_tlb_inval_set = 0; 5160 r_dcache_fsm_scan_save = r_dcache_fsm.read(); 5161 r_dcache_fsm = DCACHE_INVAL_TLB_SCAN; 5162 break; 5163 } 5164 if ( r_dcache_content_state[way*m_dcache_sets+set] == LINE_CACHE_CONTAINS_PTD ) 5165 { 5166 r_itlb.reset(); 5167 r_dtlb.reset(); 5168 r_dcache_content_state[way*m_dcache_sets+set] = LINE_CACHE_DATA_NOT_DIRTY; 5169 5170 #if DEBUG_DCACHE 5171 if ( m_debug_activated ) 5172 { 5173 std::cout << " <PROC " << name() 5174 << " DCACHE_CC_INVAL> Flush DTLB & ITLB" << std::endl; 5175 } 5176 #endif 5177 } 5178 5179 5180 if ( state == CACHE_SLOT_STATE_VALID_CC ) 5181 { 5182 // Switch slot state to ZOMBI and send CLEANUP command 5183 r_dcache.write_dir( way, 5184 set, 5185 CACHE_SLOT_STATE_ZOMBI ); 5186 #if DEBUG_DCACHE 5187 if ( m_debug_activated ) 5188 { 5189 std::cout << " <PROC " << name() 5190 << " DCACHE_CC_INVAL> Switch slot valid CC to ZOMBI state:" << std::dec 5191 << " / WAY = " << way 5192 << " / SET = " << set << std::endl; 5193 } 5194 #endif 5195 } 5196 5197 assert (not r_dcache_cc_send_req.read() && 5198 "ERROR in DCACHE_CC_INVAL: the r_dcache_cc_send_req " 5199 "must not be set"); 5200 5201 // coherence request completed 5202 r_cc_receive_dcache_req = false; 5203 r_dcache_cc_send_req = true; 5204 r_dcache_cc_send_nline = r_cc_receive_dcache_nline.read(); 5205 r_dcache_cc_send_way = way; 5206 r_dcache_cc_send_type = CC_TYPE_CLEANUP; 5207 r_dcache_fsm = r_dcache_fsm_cc_save.read(); 5208 5209 if ( (state == CACHE_SLOT_STATE_VALID_NCC) ) 5210 { 5211 r_dcache_cleanup_ncc = true; 5212 5213 if (r_dcache_content_state[way*m_dcache_sets+set] == LINE_CACHE_DATA_DIRTY) 5214 { 5215 r_dcache_cc_cleanup_updt_data = true; 5216 r_dcache_fsm = DCACHE_CC_INVAL_DATA; 5217 5218 /*STATS DIRTY*/ 5219 for (size_t w = 0; w < m_dcache_words; w++) 5220 { 5221 if(dirty_stats[(way * m_dcache_sets + set) * m_dcache_words + w] == true) 5222 m_cpt_words_dirty++; 5223 } 5224 } 5225 else 5226 { 5227 r_dcache_cc_cleanup_updt_data = false; 5228 r_dcache.write_dir( way, 5229 set, 5230 CACHE_SLOT_STATE_ZOMBI ); 5231 r_dcache_fsm = r_dcache_fsm_cc_save.read(); 5232 } 4984 5233 } 4985 5234 break; … … 5001 5250 r_dcache_cc_inval_addr = r_dcache_cc_inval_addr.read() + 4; 5002 5251 5003 cleanup_data_updt_fifo_dcache_get = false;5004 5252 cleanup_data_updt_fifo_dcache_put = true; 5005 5253 cleanup_data_updt_fifo_dcache_data = rdata; … … 5026 5274 break; 5027 5275 } 5028 /////////////////// //5029 case DCACHE_CC_ INVAL: // hit inval: switch slot to EMPTY state,5276 /////////////////// 5277 case DCACHE_CC_UPDT: // hit update: write one word per cycle, 5030 5278 // after possible invalidation of copies in TLBs 5031 5279 { 5032 size_t way = r_dcache_cc_way.read(); 5033 size_t set = r_dcache_cc_set.read(); 5034 int state = r_dcache_cc_state.read(); 5035 if (r_dcache_cc_need_write.read()) 5036 { 5037 if ( r_dcache_content_state[way*m_dcache_sets+set] == LINE_CACHE_IN_TLB ) 5038 { 5039 r_dcache_content_state[way*m_dcache_sets+set] = LINE_CACHE_DATA_NOT_DIRTY; 5040 r_dcache_tlb_inval_line = r_cc_receive_dcache_nline.read(); 5041 r_dcache_tlb_inval_set = 0; 5042 r_dcache_fsm_scan_save = r_dcache_fsm.read(); 5043 r_dcache_fsm = DCACHE_INVAL_TLB_SCAN; 5044 break; 5045 } 5046 else 5047 { 5048 if ( r_dcache_content_state[way*m_dcache_sets+set] == LINE_CACHE_CONTAINS_PTD ) 5049 { 5050 r_itlb.reset(); 5051 r_dtlb.reset(); 5052 r_dcache_content_state[way*m_dcache_sets+set] = LINE_CACHE_DATA_NOT_DIRTY; 5053 5054 #if DEBUG_DCACHE 5055 if ( m_debug_activated ) 5056 { 5057 std::cout << " <PROC " << name() 5058 << " DCACHE_CC_INVAL> Flush DTLB & ITLB" << std::endl; 5059 } 5060 #endif 5061 } 5062 5063 if ( state == CACHE_SLOT_STATE_VALID_CC ) 5064 { 5065 r_dcache.write_dir( 0, 5066 way, 5067 set, 5068 CACHE_SLOT_STATE_EMPTY ); 5069 #if DEBUG_DCACHE 5070 if ( m_debug_activated ) 5071 { 5072 std::cout << " <PROC " << name() 5073 5074 << " DCACHE_CC_INVAL> Switch slot to EMPTY state:" << std::dec 5075 << " / WAY = " << way 5076 << " / SET = " << set << std::endl; 5077 } 5078 #endif 5079 } 5080 r_dcache_cc_need_write = false; 5081 5082 } 5083 } 5084 5085 // multicast acknowledgement 5086 // send a request to cc_send_fsm 5087 if(not r_dcache_cc_send_req.read()) // cc_send is available 5088 { 5089 5090 // coherence request completed 5091 r_cc_receive_dcache_req = false; 5092 r_dcache_cc_send_req = true; 5093 r_dcache_cc_send_nline = r_cc_receive_dcache_nline.read(); 5094 5095 5096 if ( (state == CACHE_SLOT_STATE_VALID_NCC) ) 5097 { 5098 r_dcache_cleanup_ncc = true; 5099 r_dcache_cc_send_type = CC_TYPE_CLEANUP; 5100 r_dcache_cc_send_way = way; 5101 5102 if (r_dcache_content_state[way*m_dcache_sets+set] == LINE_CACHE_DATA_DIRTY) 5103 { 5104 r_dcache_cc_cleanup_updt_data = true; 5105 r_dcache_fsm = DCACHE_CC_INVAL_DATA; 5106 5107 /*STATS DIRTY*/ 5108 for (size_t w = 0; w < m_dcache_words; w++) 5109 { 5110 if(dirty_stats[(way * m_dcache_sets + set) * m_dcache_words + w] == true) 5111 m_cpt_words_dirty++; 5112 } 5113 } 5114 else 5115 { 5116 r_dcache_cc_cleanup_updt_data = false; 5117 r_dcache.write_dir( way, 5118 set, 5119 CACHE_SLOT_STATE_ZOMBI ); 5120 r_dcache_fsm = r_dcache_fsm_cc_save.read(); 5121 } 5122 } 5123 else 5124 { 5125 // request multicast acknowledgement 5126 r_dcache_cc_send_updt_tab_idx = r_cc_receive_dcache_updt_tab_idx.read(); 5127 r_dcache_cc_send_type = CC_TYPE_MULTI_ACK; 5128 r_dcache_fsm = r_dcache_fsm_cc_save.read(); 5129 } 5130 } 5131 //else wait for previous cc_send request to be sent 5132 break; 5133 } 5134 /////////////////// 5135 case DCACHE_CC_UPDT: // hit update: write one word per cycle, 5136 // after possible invalidation of copies in TLBs 5137 { 5138 size_t word = r_dcache_cc_word.read(); 5139 size_t way = r_dcache_cc_way.read(); 5140 size_t set = r_dcache_cc_set.read(); 5141 5142 if (r_cc_receive_updt_fifo_be.rok()) 5143 { 5144 if (r_dcache_cc_need_write.read()) 5145 { 5146 // selective TLB inval 5147 if ( r_dcache_content_state[way*m_dcache_sets+set] == LINE_CACHE_IN_TLB ) 5148 { 5149 r_dcache_content_state[way*m_dcache_sets+set] = LINE_CACHE_DATA_NOT_DIRTY; 5150 r_dcache_tlb_inval_line = r_cc_receive_dcache_nline.read(); 5151 r_dcache_tlb_inval_set = 0; 5152 r_dcache_fsm_scan_save = r_dcache_fsm.read(); 5153 r_dcache_fsm = DCACHE_INVAL_TLB_SCAN; 5154 break; 5155 } 5156 // TLB flush 5157 if ( r_dcache_content_state[way*m_dcache_sets+set] == LINE_CACHE_CONTAINS_PTD ) 5158 { 5159 r_itlb.reset(); 5160 r_dtlb.reset(); 5161 r_dcache_content_state[way*m_dcache_sets+set] = LINE_CACHE_DATA_NOT_DIRTY; 5280 size_t word = r_dcache_cc_word.read(); 5281 size_t way = r_dcache_cc_way.read(); 5282 size_t set = r_dcache_cc_set.read(); 5283 5284 // selective TLB inval 5285 if ( r_dcache_content_state[way*m_dcache_sets+set] == LINE_CACHE_IN_TLB ) 5286 { 5287 r_dcache_content_state[way*m_dcache_sets+set] = LINE_CACHE_DATA_NOT_DIRTY; 5288 r_dcache_tlb_inval_line = r_cc_receive_dcache_nline.read(); 5289 r_dcache_tlb_inval_set = 0; 5290 r_dcache_fsm_scan_save = r_dcache_fsm.read(); 5291 r_dcache_fsm = DCACHE_INVAL_TLB_SCAN; 5292 break; 5293 } 5294 // TLB flush 5295 if ( r_dcache_content_state[way*m_dcache_sets+set] == LINE_CACHE_CONTAINS_PTD ) 5296 { 5297 r_itlb.reset(); 5298 r_dtlb.reset(); 5299 r_dcache_content_state[way*m_dcache_sets+set] = LINE_CACHE_DATA_NOT_DIRTY; 5162 5300 5163 5301 #if DEBUG_DCACHE … … 5165 5303 { 5166 5304 std::cout << " <PROC " << name() 5167 5305 << " DCACHE_CC_UPDT> Flush DTLB & ITLB" << std::endl; 5168 5306 } 5169 5307 #endif 5170 } 5171 5308 } 5309 5310 assert (not r_dcache_cc_send_req.read() && 5311 "ERROR in DCACHE_CC_INVAL: the r_dcache_cc_send_req " 5312 "must not be set"); 5313 5314 if ( not r_cc_receive_updt_fifo_be.rok() ) break; 5315 5316 if (r_dcache_cc_need_write.read()) 5317 { 5318 5172 5319 #ifdef INSTRUMENTATION 5173 5320 m_cpt_dcache_data_write++; 5174 5321 #endif 5175 5176 5177 5178 5179 5180 5181 5322 r_dcache.write( way, 5323 set, 5324 word, 5325 r_cc_receive_updt_fifo_data.read(), 5326 r_cc_receive_updt_fifo_be.read() ); 5327 5328 r_dcache_cc_word = word + 1; 5182 5329 5183 5330 #if DEBUG_DCACHE … … 5192 5339 } 5193 5340 #endif 5194 } 5195 5196 if ( r_cc_receive_updt_fifo_eop.read() ) // last word 5197 { 5198 // no need to write in the cache anymore 5199 r_dcache_cc_need_write = false; 5200 5201 // wait to send a request to cc_send_fsm 5202 if(not r_dcache_cc_send_req.read()) 5203 // cc_send is available 5204 { 5205 //consume last fifo flit if eop and request to cc_send possible 5206 cc_receive_updt_fifo_get = true; 5207 5208 // coherence request completed 5209 r_cc_receive_dcache_req = false; 5210 5211 // request multicast acknowledgement 5212 r_dcache_cc_send_req = true; 5213 r_dcache_cc_send_nline = r_cc_receive_dcache_nline.read(); 5214 r_dcache_cc_send_updt_tab_idx = r_cc_receive_dcache_updt_tab_idx.read(); 5215 r_dcache_cc_send_type = CC_TYPE_MULTI_ACK; 5216 5217 r_dcache_fsm = r_dcache_fsm_cc_save.read(); 5218 } 5219 } 5220 else 5221 { 5222 //consume fifo if not eop 5223 cc_receive_updt_fifo_get = true; 5224 } 5225 } 5226 break; 5227 } 5228 ///////////////////////// 5229 case DCACHE_CC_BROADCAST: // hit broadcast : switch state to ZOMBI state 5230 // and request a cleanup, after possible 5231 // invalidation of copies in TLBs 5232 { 5233 size_t way = r_dcache_cc_way.read(); 5234 size_t set = r_dcache_cc_set.read(); 5235 paddr_t nline = r_cc_receive_dcache_nline.read(); 5236 5237 if (r_dcache_cc_need_write.read()) 5238 { 5239 // selective TLB inval 5240 if ( r_dcache_content_state[way*m_dcache_sets+set] == LINE_CACHE_IN_TLB ) 5241 { 5242 r_dcache_content_state[way*m_dcache_sets+set] = LINE_CACHE_DATA_NOT_DIRTY; 5243 r_dcache_tlb_inval_line = nline; 5244 r_dcache_tlb_inval_set = 0; 5245 r_dcache_fsm_scan_save = r_dcache_fsm.read(); 5246 r_dcache_fsm = DCACHE_INVAL_TLB_SCAN; 5247 break; 5248 } 5249 else 5250 { 5251 // TLB flush 5252 if ( r_dcache_content_state[way*m_dcache_sets+set] == LINE_CACHE_CONTAINS_PTD ) 5253 { 5254 r_itlb.reset(); 5255 r_dtlb.reset(); 5256 r_dcache_content_state[way*m_dcache_sets+set] = LINE_CACHE_DATA_NOT_DIRTY; 5257 5258 #if DEBUG_DCACHE 5259 if ( m_debug_activated ) 5260 { 5261 std::cout << " <PROC " << name() 5262 << " DCACHE_CC_BROADCAST> Flush DTLB & ITLB" << std::endl; 5263 } 5264 #endif 5265 } 5266 5267 #ifdef INSTRUMENTATION 5268 m_cpt_dcache_dir_write++; 5269 #endif 5270 r_dcache.write_dir( way, 5271 set, 5272 CACHE_SLOT_STATE_ZOMBI ); 5273 5274 r_dcache_cc_need_write = false; 5275 #if DEBUG_DCACHE 5276 if ( m_debug_activated ) 5277 { 5278 std::cout << " <PROC " << name() 5279 << " DCACHE_CC_BROADCAST > Slot goes to ZOMBI state " 5280 << " SET = " << set 5281 << " / WAY = " << way << std::endl; 5282 } 5283 #endif 5284 } 5285 } 5286 // cleanup 5287 // send a request to cc_send_fsm 5288 if(not r_dcache_cc_send_req.read()) // cc_send is available 5289 { 5341 } 5342 5343 if ( r_cc_receive_updt_fifo_eop.read() ) // last word 5344 { 5345 // no need to write in the cache anymore 5346 r_dcache_cc_need_write = false; 5347 5290 5348 // coherence request completed 5291 5349 r_cc_receive_dcache_req = false; 5292 // request cleanup 5293 r_dcache_cc_send_req = true; 5294 r_dcache_cc_send_nline = r_cc_receive_dcache_nline.read(); 5295 r_dcache_cc_send_way = r_dcache_cc_way.read(); 5296 r_dcache_cc_send_type = CC_TYPE_CLEANUP; 5297 5298 r_dcache_fsm = r_dcache_fsm_cc_save.read(); 5299 } 5300 //else wait for previous cc_send request to be sent 5350 5351 // request multicast acknowledgement 5352 r_dcache_cc_send_req = true; 5353 r_dcache_cc_send_nline = r_cc_receive_dcache_nline.read(); 5354 r_dcache_cc_send_updt_tab_idx = r_cc_receive_dcache_updt_tab_idx.read(); 5355 r_dcache_cc_send_type = CC_TYPE_MULTI_ACK; 5356 5357 r_dcache_fsm = r_dcache_fsm_cc_save.read(); 5358 } 5359 5360 //consume fifo if not eop 5361 cc_receive_updt_fifo_get = true; 5362 5301 5363 break; 5302 5364 } … … 5689 5751 if ( r_vci_rsp_fifo_icache.wok() ) 5690 5752 { 5691 assert( (r_vci_rsp_cpt.read() < m_icache_words) and 5692 "The VCI response packet for instruction miss is too long" ); 5693 5753 if ( r_vci_rsp_cpt.read() >= m_icache_words ) 5754 { 5755 std::cout << "ERROR in VCI_CC_VCACHE " << name() 5756 << " VCI response packet too long " 5757 << " for instruction miss" << std::endl; 5758 exit(0); 5759 } 5694 5760 r_vci_rsp_cpt = r_vci_rsp_cpt.read() + 1; 5695 5761 vci_rsp_fifo_icache_put = true, … … 5697 5763 if ( p_vci.reop.read() ) 5698 5764 { 5699 assert( (r_vci_rsp_cpt.read() == m_icache_words - 1) and 5700 "The VCI response packet for instruction miss is too short"); 5701 5765 if ( r_vci_rsp_cpt.read() != (m_icache_words - 1) ) 5766 { 5767 std::cout << "ERROR in VCI_CC_VCACHE " << name() 5768 << " VCI response packet too short" 5769 << " for instruction miss" << std::endl; 5770 exit(0); 5771 } 5702 5772 r_vci_rsp_fsm = RSP_IDLE; 5703 5773 } … … 5902 5972 { 5903 5973 // wait for the first flit to be consumed 5904 if (p_dspin_ out.read.read())5974 if (p_dspin_p2m.read.read()) 5905 5975 r_cc_send_fsm = CC_SEND_CLEANUP_2; 5906 5976 … … 5911 5981 { 5912 5982 // wait for the second flit to be consumed 5913 if (p_dspin_ out.read.read())5983 if (p_dspin_p2m.read.read()) 5914 5984 { 5915 5985 /*ODCCP*/ // If there is a cleanup with data and dcache active request we send other flits contained data … … 5933 6003 case CC_SEND_CLEANUP_DATA_UPDT: /*ODCCP*/ // we send the data values of line cache into [m_dcache_words] flits 5934 6004 { 5935 if (p_dspin_ out.read.read())6005 if (p_dspin_p2m.read.read()) 5936 6006 { 5937 6007 if(r_cc_send_data_fifo.rok()) … … 5956 6026 { 5957 6027 // wait for the flit to be consumed 5958 if(p_dspin_ out.read.read())6028 if(p_dspin_p2m.read.read()) 5959 6029 { 5960 6030 if(r_cc_send_last_client.read() == 0) // dcache active request … … 5970 6040 5971 6041 /////////////////////////////////////////////////////////////////////////////// 5972 // 6042 // CC_RECEIVE FSM 5973 6043 // This FSM receive all coherence packets on a DSPIN40 port. 5974 // There is 7packet types:6044 // There is 5 packet types: 5975 6045 // - CC_DATA_INVAL : DCACHE invalidate request 5976 6046 // - CC_DATA_UPDT : DCACHE update request (multi-words) … … 5978 6048 // - CC_INST_UPDT : ICACHE update request (multi-words) 5979 6049 // - CC_BROADCAST : Broadcast invalidate request (both DCACHE & ICACHE) 5980 // - CC_DATA_CLACK : DCACHE cleanup acknowledge5981 // - CC_INST_CLACK : ICACHE cleanup acknowledge5982 6050 ////////////////////////////////////////////////////////////////////////////// 5983 6051 switch( r_cc_receive_fsm.read() ) … … 5987 6055 { 5988 6056 // a coherence request has arrived 5989 if (p_dspin_ in.write.read())6057 if (p_dspin_m2p.write.read()) 5990 6058 { 5991 6059 // initialize dspin received data 5992 uint64_t receive_data = p_dspin_ in.data.read();6060 uint64_t receive_data = p_dspin_m2p.data.read(); 5993 6061 // initialize coherence packet type 5994 6062 uint64_t receive_type = DspinDhccpParam::dspin_get(receive_data, 5995 DspinDhccpParam::FROM_MC_TYPE); 5996 // initialize data/ins flip_flop (0 data / 1 ins) 5997 r_cc_receive_data_ins = (bool)(receive_type & 0x1); 6063 DspinDhccpParam::M2P_TYPE); 5998 6064 // test for a broadcast 5999 if (DspinDhccpParam::dspin_get(receive_data,DspinDhccpParam:: FROM_MC_BC))6065 if (DspinDhccpParam::dspin_get(receive_data,DspinDhccpParam::M2P_BC)) 6000 6066 { 6001 6067 r_cc_receive_fsm = CC_RECEIVE_BRDCAST_HEADER; 6002 6068 } 6003 // test for a CLACK 6004 else if ((receive_type == DspinDhccpParam::TYPE_CLEANUP_ACK_DATA) or 6005 (receive_type == DspinDhccpParam::TYPE_CLEANUP_ACK_INST)) 6069 // test for a multi updt 6070 else if (receive_type == DspinDhccpParam::TYPE_MULTI_UPDT_DATA) 6006 6071 { 6007 r_cc_receive_fsm = CC_RECEIVE_ CLACK;6072 r_cc_receive_fsm = CC_RECEIVE_DATA_UPDT_HEADER; 6008 6073 } 6009 // test for a multi updt 6010 else if ((receive_type == DspinDhccpParam::TYPE_MULTI_UPDT_DATA) or 6011 (receive_type == DspinDhccpParam::TYPE_MULTI_UPDT_INST)) 6074 else if (receive_type == DspinDhccpParam::TYPE_MULTI_UPDT_INST) 6012 6075 { 6013 r_cc_receive_fsm = CC_RECEIVE_ UPDT_HEADER;6076 r_cc_receive_fsm = CC_RECEIVE_INS_UPDT_HEADER; 6014 6077 } 6015 6078 // test for a multi inval 6079 else if (receive_type == DspinDhccpParam::TYPE_MULTI_INVAL_DATA) 6080 { 6081 r_cc_receive_fsm = CC_RECEIVE_DATA_INVAL_HEADER; 6082 } 6016 6083 else 6017 6084 { 6018 r_cc_receive_fsm = CC_RECEIVE_IN VAL_HEADER;6085 r_cc_receive_fsm = CC_RECEIVE_INS_INVAL_HEADER; 6019 6086 } 6020 6087 } 6021 break;6022 }6023 //////////////////////6024 case CC_RECEIVE_CLACK:6025 {6026 // initialize dspin received data6027 uint64_t receive_data = p_dspin_in.data.read();6028 6029 // for data CLACK, wait for dcache to take the request6030 if ((r_cc_receive_data_ins.read() == 0) and6031 not r_cc_receive_dcache_req.read())6032 {6033 // request dcache to handle the CLACK6034 r_cc_receive_dcache_req = true;6035 r_cc_receive_dcache_set = DspinDhccpParam::dspin_get(receive_data,6036 DspinDhccpParam::CLEANUP_ACK_SET) &6037 ((1ULL<<(uint32_log2(m_dcache_sets)))-1);6038 r_cc_receive_dcache_way = DspinDhccpParam::dspin_get(receive_data,6039 DspinDhccpParam::CLEANUP_ACK_WAY) &6040 ((1ULL<<(uint32_log2(m_dcache_ways)))-1);6041 r_cc_receive_dcache_type = CC_TYPE_CLACK;6042 // get back to idle state6043 r_cc_receive_fsm = CC_RECEIVE_IDLE;6044 break;6045 }6046 // for ins CLACK, wait for icache to take the request6047 if ((r_cc_receive_data_ins.read() == 1) and6048 not (r_cc_receive_icache_req.read()))6049 {6050 // request icache to handle the CLACK6051 r_cc_receive_icache_req = true;6052 r_cc_receive_icache_set = DspinDhccpParam::dspin_get(receive_data,6053 DspinDhccpParam::CLEANUP_ACK_SET) &6054 ((1ULL<<(uint32_log2(m_icache_sets)))-1);6055 r_cc_receive_icache_way = DspinDhccpParam::dspin_get(receive_data,6056 DspinDhccpParam::CLEANUP_ACK_WAY) &6057 ((1ULL<<(uint32_log2(m_icache_ways)))-1);6058 r_cc_receive_icache_type = CC_TYPE_CLACK;6059 // get back to idle state6060 r_cc_receive_fsm = CC_RECEIVE_IDLE;6061 break;6062 }6063 // keep waiting for the correct cache to accept the request6064 6088 break; 6065 6089 } … … 6075 6099 { 6076 6100 // initialize dspin received data 6077 uint64_t receive_data = p_dspin_ in.data.read();6101 uint64_t receive_data = p_dspin_m2p.data.read(); 6078 6102 // wait for both dcache and icache to take the request 6079 6103 // TODO maybe we need to wait for both only to leave the state, but … … 6082 6106 if (not (r_cc_receive_icache_req.read()) and 6083 6107 not (r_cc_receive_dcache_req.read()) and 6084 (p_dspin_ in.write.read()))6108 (p_dspin_m2p.write.read())) 6085 6109 { 6086 6110 // request dcache to handle the BROADCAST 6087 r_cc_receive_dcache_req 6111 r_cc_receive_dcache_req = true; 6088 6112 r_cc_receive_dcache_nline = DspinDhccpParam::dspin_get(receive_data, 6089 6113 DspinDhccpParam::BROADCAST_NLINE); 6090 r_cc_receive_dcache_type = CC_TYPE_ BRDCAST;6114 r_cc_receive_dcache_type = CC_TYPE_INVAL; 6091 6115 // request icache to handle the BROADCAST 6092 r_cc_receive_icache_req 6116 r_cc_receive_icache_req = true; 6093 6117 r_cc_receive_icache_nline = DspinDhccpParam::dspin_get(receive_data, 6094 6118 DspinDhccpParam::BROADCAST_NLINE); 6095 r_cc_receive_icache_type = CC_TYPE_ BRDCAST;6119 r_cc_receive_icache_type = CC_TYPE_INVAL; 6096 6120 // get back to idle state 6097 6121 r_cc_receive_fsm = CC_RECEIVE_IDLE; … … 6102 6126 } 6103 6127 ///////////////////////////// 6104 case CC_RECEIVE_ INVAL_HEADER:6128 case CC_RECEIVE_DATA_INVAL_HEADER: 6105 6129 { 6106 6130 // sample updt tab index in the HEADER, then skip to second flit 6107 uint64_t receive_data = p_dspin_in.data.read(); 6131 r_cc_receive_fsm = CC_RECEIVE_DATA_INVAL_NLINE; 6132 break; 6133 } 6134 ///////////////////////////// 6135 case CC_RECEIVE_INS_INVAL_HEADER: 6136 { 6137 // sample updt tab index in the HEADER, then skip to second flit 6138 r_cc_receive_fsm = CC_RECEIVE_INS_INVAL_NLINE; 6139 break; 6140 } 6141 //////////////////////////// 6142 case CC_RECEIVE_DATA_INVAL_NLINE: 6143 { 6144 // sample nline in the second flit 6145 uint64_t receive_data = p_dspin_m2p.data.read(); 6108 6146 // for data INVAL, wait for dcache to take the request 6109 if ((r_cc_receive_data_ins.read() == 0) and 6110 not (r_cc_receive_dcache_req.read())) 6111 { 6112 r_cc_receive_dcache_updt_tab_idx = DspinDhccpParam::dspin_get(receive_data, 6113 DspinDhccpParam::MULTI_INVAL_UPDT_INDEX); 6114 r_cc_receive_fsm = CC_RECEIVE_INVAL_NLINE; 6115 break; 6116 } 6117 // for ins INVAL, wait for icache to take the request 6118 if ((r_cc_receive_data_ins.read() == 1) and 6119 not (r_cc_receive_icache_req.read())) 6120 { 6121 r_cc_receive_icache_updt_tab_idx = DspinDhccpParam::dspin_get(receive_data, 6122 DspinDhccpParam::MULTI_INVAL_UPDT_INDEX); 6123 r_cc_receive_fsm = CC_RECEIVE_INVAL_NLINE; 6124 break; 6125 } 6126 // keep waiting for the correct cache to accept the request 6127 break; 6128 } 6129 //////////////////////////// 6130 case CC_RECEIVE_INVAL_NLINE: 6131 { 6132 // sample nline in the second flit 6133 uint64_t receive_data = p_dspin_in.data.read(); 6134 // for data INVAL, wait for dcache to take the request 6135 if ( (r_cc_receive_data_ins.read() == 0) and 6136 not (r_cc_receive_dcache_req.read()) and 6137 (p_dspin_in.write.read()) ) 6147 if (p_dspin_m2p.write.read() and not r_cc_receive_dcache_req.read()) 6138 6148 { 6139 6149 // request dcache to handle the INVAL 6140 r_cc_receive_dcache_req 6141 r_cc_receive_dcache_nline 6150 r_cc_receive_dcache_req = true; 6151 r_cc_receive_dcache_nline = DspinDhccpParam::dspin_get(receive_data,DspinDhccpParam::MULTI_INVAL_NLINE); 6142 6152 r_cc_receive_dcache_type = CC_TYPE_INVAL; 6143 6153 // get back to idle state … … 6145 6155 break; 6146 6156 } 6157 break; 6158 } 6159 ////////////////////////////// 6160 case CC_RECEIVE_INS_INVAL_NLINE: 6161 { 6162 // sample nline in the second flit 6163 uint64_t receive_data = p_dspin_m2p.data.read(); 6147 6164 // for ins INVAL, wait for icache to take the request 6148 if ( (r_cc_receive_data_ins.read() == 1) and not (r_cc_receive_icache_req.read()) and (p_dspin_in.write.read()))6165 if (p_dspin_m2p.write.read() and not r_cc_receive_icache_req.read()) 6149 6166 { 6150 6167 // request icache to handle the INVAL 6151 r_cc_receive_icache_req 6152 r_cc_receive_icache_nline 6168 r_cc_receive_icache_req = true; 6169 r_cc_receive_icache_nline = DspinDhccpParam::dspin_get(receive_data,DspinDhccpParam::MULTI_INVAL_NLINE); 6153 6170 r_cc_receive_icache_type = CC_TYPE_INVAL; 6154 6171 // get back to idle state … … 6156 6173 break; 6157 6174 } 6158 // we should never get there 6159 assert ( false && "ERROR in CC_VCACHE : CC_RECEIVE_INVAL_NLINE\n"); 6175 break; 6160 6176 } 6161 6177 //////////////////////////// 6162 case CC_RECEIVE_ UPDT_HEADER:6178 case CC_RECEIVE_DATA_UPDT_HEADER: 6163 6179 { 6164 6180 // sample updt tab index in the HEADER, than skip to second flit 6165 uint64_t receive_data = p_dspin_ in.data.read();6181 uint64_t receive_data = p_dspin_m2p.data.read(); 6166 6182 // for data INVAL, wait for dcache to take the request and fifo to 6167 6183 // be empty 6168 if ( (r_cc_receive_data_ins.read() == 0) and not r_cc_receive_dcache_req.read() and r_cc_receive_updt_fifo_be.empty())6184 if (not r_cc_receive_dcache_req.read()) 6169 6185 { 6170 6186 r_cc_receive_dcache_updt_tab_idx = DspinDhccpParam::dspin_get(receive_data,DspinDhccpParam::MULTI_UPDT_UPDT_INDEX); 6171 r_cc_receive_fsm = CC_RECEIVE_ UPDT_NLINE;6187 r_cc_receive_fsm = CC_RECEIVE_DATA_UPDT_NLINE; 6172 6188 break; 6173 6189 } 6190 break; 6191 } 6192 //////////////////////////// 6193 case CC_RECEIVE_INS_UPDT_HEADER: 6194 { 6195 // sample updt tab index in the HEADER, than skip to second flit 6196 uint64_t receive_data = p_dspin_m2p.data.read(); 6174 6197 // for ins INVAL, wait for icache to take the request and fifo to be 6175 6198 // empty 6176 if ( (r_cc_receive_data_ins.read() == 1) and not r_cc_receive_icache_req.read() and r_cc_receive_updt_fifo_be.empty())6199 if (not r_cc_receive_icache_req.read()) 6177 6200 { 6178 6201 r_cc_receive_icache_updt_tab_idx = DspinDhccpParam::dspin_get(receive_data,DspinDhccpParam::MULTI_UPDT_UPDT_INDEX); 6179 r_cc_receive_fsm = CC_RECEIVE_ UPDT_NLINE;6202 r_cc_receive_fsm = CC_RECEIVE_INS_UPDT_NLINE; 6180 6203 break; 6181 6204 } … … 6184 6207 } 6185 6208 /////////////////////////// 6186 case CC_RECEIVE_ UPDT_NLINE:6209 case CC_RECEIVE_DATA_UPDT_NLINE: 6187 6210 { 6188 6211 // sample nline and word index in the second flit 6189 uint64_t receive_data = p_dspin_ in.data.read();6212 uint64_t receive_data = p_dspin_m2p.data.read(); 6190 6213 // for data INVAL, wait for dcache to take the request and fifo to 6191 6214 // be empty 6192 if ( (r_cc_receive_data_ins.read() == 0) and 6193 not (r_cc_receive_dcache_req.read()) and 6194 r_cc_receive_updt_fifo_be.empty() and 6195 (p_dspin_in.write.read()) ) 6196 { 6215 if ( r_cc_receive_updt_fifo_be.empty() and 6216 p_dspin_m2p.write.read() ) 6217 { 6218 r_cc_receive_dcache_req = true; 6197 6219 r_cc_receive_dcache_nline = DspinDhccpParam::dspin_get(receive_data,DspinDhccpParam::MULTI_UPDT_NLINE); 6198 6220 r_cc_receive_word_idx = DspinDhccpParam::dspin_get(receive_data,DspinDhccpParam::MULTI_UPDT_WORD_INDEX); 6199 6221 r_cc_receive_dcache_type = CC_TYPE_UPDT; 6200 6222 // get back to idle state 6201 r_cc_receive_fsm = CC_RECEIVE_ UPDT_DATA;6223 r_cc_receive_fsm = CC_RECEIVE_DATA_UPDT_DATA; 6202 6224 break; 6203 6225 } 6226 break; 6227 } 6228 //////////////////////////// 6229 case CC_RECEIVE_INS_UPDT_NLINE: 6230 { 6231 // sample nline and word index in the second flit 6232 uint64_t receive_data = p_dspin_m2p.data.read(); 6204 6233 // for ins INVAL, wait for icache to take the request and fifo to be 6205 6234 // empty 6206 if ( (r_cc_receive_data_ins.read() == 1) and 6207 not (r_cc_receive_icache_req.read()) and 6208 r_cc_receive_updt_fifo_be.empty() and 6209 (p_dspin_in.write.read())) 6210 { 6235 if ( r_cc_receive_updt_fifo_be.empty() and 6236 p_dspin_m2p.write.read() ) 6237 { 6238 r_cc_receive_icache_req = true; 6211 6239 r_cc_receive_icache_nline = DspinDhccpParam::dspin_get(receive_data,DspinDhccpParam::MULTI_UPDT_NLINE); 6212 6240 r_cc_receive_word_idx = DspinDhccpParam::dspin_get(receive_data,DspinDhccpParam::MULTI_UPDT_WORD_INDEX); 6213 6241 r_cc_receive_icache_type = CC_TYPE_UPDT; 6214 6242 // get back to idle state 6215 r_cc_receive_fsm = CC_RECEIVE_ UPDT_DATA;6243 r_cc_receive_fsm = CC_RECEIVE_INS_UPDT_DATA; 6216 6244 break; 6217 6245 } 6218 // we should never get there6219 assert ( false && "ERROR in CC_VCACHE : CC_RECEIVE_UPDT_NLINE \n");6220 6246 break; 6221 6247 } 6222 6248 ////////////////////////// 6223 case CC_RECEIVE_UPDT_DATA: 6224 { 6225 if ((r_cc_receive_data_ins.read() == 0) and not (r_cc_receive_dcache_req.read()) and (p_dspin_in.write.read())) 6226 r_cc_receive_dcache_req = true; 6227 if ((r_cc_receive_data_ins.read() == 1) and not (r_cc_receive_icache_req.read()) and (p_dspin_in.write.read())) 6228 r_cc_receive_icache_req = true; 6229 6249 case CC_RECEIVE_DATA_UPDT_DATA: 6250 { 6230 6251 // wait for the fifo 6231 if (r_cc_receive_updt_fifo_be.wok() and (p_dspin_ in.write.read()))6232 { 6233 uint64_t receive_data = p_dspin_ in.data.read();6234 bool receive_eop = p_dspin_ in.eop.read();6252 if (r_cc_receive_updt_fifo_be.wok() and (p_dspin_m2p.write.read())) 6253 { 6254 uint64_t receive_data = p_dspin_m2p.data.read(); 6255 bool receive_eop = p_dspin_m2p.eop.read(); 6235 6256 cc_receive_updt_fifo_be = DspinDhccpParam::dspin_get(receive_data,DspinDhccpParam::MULTI_UPDT_BE); 6236 6257 cc_receive_updt_fifo_data = DspinDhccpParam::dspin_get(receive_data,DspinDhccpParam::MULTI_UPDT_DATA); … … 6241 6262 break; 6242 6263 } 6264 ////////////////////////// 6265 case CC_RECEIVE_INS_UPDT_DATA: 6266 { 6267 // wait for the fifo 6268 if (r_cc_receive_updt_fifo_be.wok() and (p_dspin_m2p.write.read())) 6269 { 6270 uint64_t receive_data = p_dspin_m2p.data.read(); 6271 bool receive_eop = p_dspin_m2p.eop.read(); 6272 cc_receive_updt_fifo_be = DspinDhccpParam::dspin_get(receive_data,DspinDhccpParam::MULTI_UPDT_BE); 6273 cc_receive_updt_fifo_data = DspinDhccpParam::dspin_get(receive_data,DspinDhccpParam::MULTI_UPDT_DATA); 6274 cc_receive_updt_fifo_eop = receive_eop; 6275 cc_receive_updt_fifo_put = true; 6276 if ( receive_eop ) r_cc_receive_fsm = CC_RECEIVE_IDLE; 6277 } 6278 break; 6279 } 6280 6243 6281 } // end switch CC_RECEIVE FSM 6282 6283 ///////////////// DSPIN CLACK interface /////////////// 6284 6285 uint64_t clack_type = DspinDhccpParam::dspin_get(r_dspin_clack_flit.read(), 6286 DspinDhccpParam::CLACK_TYPE); 6287 6288 size_t clack_way = DspinDhccpParam::dspin_get(r_dspin_clack_flit.read(), 6289 DspinDhccpParam::CLACK_WAY); 6290 6291 size_t clack_set = DspinDhccpParam::dspin_get(r_dspin_clack_flit.read(), 6292 DspinDhccpParam::CLACK_SET); 6293 6294 bool dspin_clack_get = false; 6295 bool dcache_clack_request = (clack_type == DspinDhccpParam::TYPE_CLACK_DATA); 6296 bool icache_clack_request = (clack_type == DspinDhccpParam::TYPE_CLACK_INST); 6297 6298 if (r_dspin_clack_req.read()) 6299 { 6300 // CLACK DATA: Send request to DCACHE FSM 6301 if (dcache_clack_request and not r_dcache_clack_req.read()){ 6302 r_dcache_clack_req = true; 6303 r_dcache_clack_way = clack_way & ((1ULL<<(uint32_log2(m_dcache_ways)))-1); 6304 r_dcache_clack_set = clack_set & ((1ULL<<(uint32_log2(m_dcache_sets)))-1); 6305 dspin_clack_get = true; 6306 } 6307 6308 // CLACK INST: Send request to ICACHE FSM 6309 else if (icache_clack_request and not r_icache_clack_req.read()){ 6310 r_icache_clack_req = true; 6311 r_icache_clack_way = clack_way & ((1ULL<<(uint32_log2(m_dcache_ways)))-1); 6312 r_icache_clack_set = clack_set & ((1ULL<<(uint32_log2(m_icache_sets)))-1); 6313 dspin_clack_get = true; 6314 } 6315 } 6316 else 6317 { 6318 dspin_clack_get = true; 6319 } 6320 6321 if (dspin_clack_get) 6322 { 6323 r_dspin_clack_req = p_dspin_clack.write.read(); 6324 r_dspin_clack_flit = p_dspin_clack.data.read(); 6325 } 6244 6326 6245 6327 ///////////////// Response FIFOs update ////////////////////// … … 6447 6529 case CC_SEND_IDLE: 6448 6530 { 6449 p_dspin_ out.write = false;6531 p_dspin_p2m.write = false; 6450 6532 break; 6451 6533 } … … 6454 6536 { 6455 6537 // initialize dspin send data 6538 // DspinDhccpParam::dspin_set(dspin_send_data, 6539 // 0, 6540 // DspinDhccpParam::P2M_EOP); 6456 6541 DspinDhccpParam::dspin_set(dspin_send_data, 6457 6542 m_cc_global_id, … … 6459 6544 DspinDhccpParam::dspin_set(dspin_send_data, 6460 6545 0, 6461 DspinDhccpParam:: FROM_L1_BC);6546 DspinDhccpParam::P2M_BC); 6462 6547 6463 6548 if(r_cc_send_last_client.read() == 0) // dcache active request … … 6480 6565 DspinDhccpParam::dspin_set(dspin_send_data, 6481 6566 DspinDhccpParam::TYPE_CLEANUP_DATA, 6482 DspinDhccpParam:: FROM_L1_TYPE);6567 DspinDhccpParam::P2M_TYPE); 6483 6568 /*ODCCP*/ // If cleanup on NCC line we set the CLEANUP_NCC bit in cleanup flit 6484 6569 if (r_dcache_cleanup_ncc.read()) … … 6516 6601 DspinDhccpParam::dspin_set(dspin_send_data, 6517 6602 DspinDhccpParam::TYPE_CLEANUP_INST, 6518 DspinDhccpParam:: FROM_L1_TYPE);6603 DspinDhccpParam::P2M_TYPE); 6519 6604 6520 6605 DspinDhccpParam::dspin_set(dspin_send_data, … … 6523 6608 } 6524 6609 // send flit 6525 p_dspin_ out.data = dspin_send_data;6526 p_dspin_ out.write = true;6527 p_dspin_ out.eop = false;6610 p_dspin_p2m.data = dspin_send_data; 6611 p_dspin_p2m.write = true; 6612 p_dspin_p2m.eop = false; 6528 6613 break; 6529 6614 } … … 6535 6620 if (r_dcache_cc_cleanup_updt_data.read() and not r_cc_send_last_client.read()) 6536 6621 { 6537 p_dspin_ out.eop = false;6622 p_dspin_p2m.eop = false; 6538 6623 } 6539 6624 else 6540 6625 { 6541 p_dspin_ out.eop = true;6626 p_dspin_p2m.eop = true; 6542 6627 } 6543 6628 … … 6555 6640 } 6556 6641 // send flit 6557 p_dspin_ out.data = dspin_send_data;6558 p_dspin_ out.write = true;6642 p_dspin_p2m.data = dspin_send_data; 6643 p_dspin_p2m.write = true; 6559 6644 break; 6560 6645 } … … 6564 6649 if (r_cc_send_cpt_word.read() == m_dcache_words-1) /*ODCCP*/ // Last flit sent 6565 6650 { 6566 p_dspin_ out.eop = true;6651 p_dspin_p2m.eop = true; 6567 6652 } 6568 6653 else 6569 6654 { 6570 p_dspin_ out.eop = false;6655 p_dspin_p2m.eop = false; 6571 6656 } 6572 6657 … … 6575 6660 DspinDhccpParam::CLEANUP_DATA_UPDT); 6576 6661 6577 p_dspin_out.data = dspin_send_data; 6578 p_dspin_out.write = true; 6662 p_dspin_p2m.data = dspin_send_data; 6663 //p_dspin_p2m.write = true; 6664 if(r_cc_send_data_fifo.rok()) 6665 p_dspin_p2m.write = true; 6666 else 6667 p_dspin_p2m.write = false; 6579 6668 break; 6580 6669 } … … 6585 6674 // DspinDhccpParam::dspin_set(dspin_send_data, 6586 6675 // 1, 6587 // DspinDhccpParam:: FROM_L1_EOP);6676 // DspinDhccpParam::P2M_EOP); 6588 6677 DspinDhccpParam::dspin_set(dspin_send_data, 6589 6678 0, 6590 DspinDhccpParam:: FROM_L1_BC);6679 DspinDhccpParam::P2M_BC); 6591 6680 DspinDhccpParam::dspin_set(dspin_send_data, 6592 6681 DspinDhccpParam::TYPE_MULTI_ACK, 6593 DspinDhccpParam:: FROM_L1_TYPE);6682 DspinDhccpParam::P2M_TYPE); 6594 6683 6595 6684 if(r_cc_send_last_client.read() == 0) // dcache active request … … 6623 6712 } 6624 6713 // send flit 6625 p_dspin_ out.data = dspin_send_data;6626 p_dspin_ out.write = true;6627 p_dspin_ out.eop = true;6714 p_dspin_p2m.data = dspin_send_data; 6715 p_dspin_p2m.write = true; 6716 p_dspin_p2m.eop = true; 6628 6717 6629 6718 break; … … 6633 6722 // Receive coherence packets 6634 6723 // It depends on the CC_RECEIVE FSM 6635 6636 6724 switch( r_cc_receive_fsm.read() ) 6637 6725 { … … 6639 6727 case CC_RECEIVE_IDLE: 6640 6728 { 6641 p_dspin_in.read = false; 6642 break; 6643 } 6644 ////////////////////// 6645 case CC_RECEIVE_CLACK: 6646 { 6647 if (((r_cc_receive_data_ins.read() == 0) and not (r_cc_receive_dcache_req.read())) or 6648 ((r_cc_receive_data_ins.read() == 1) and not (r_cc_receive_icache_req.read()))) 6649 p_dspin_in.read = true; 6650 else 6651 p_dspin_in.read = false; 6729 p_dspin_m2p.read = false; 6652 6730 break; 6653 6731 } … … 6655 6733 case CC_RECEIVE_BRDCAST_HEADER: 6656 6734 { 6657 p_dspin_ in.read = true;6735 p_dspin_m2p.read = true; 6658 6736 break; 6659 6737 } … … 6665 6743 // flip_flop to check that ? 6666 6744 if (not (r_cc_receive_icache_req.read()) and not (r_cc_receive_dcache_req.read())) 6667 p_dspin_ in.read = true;6745 p_dspin_m2p.read = true; 6668 6746 else 6669 p_dspin_ in.read = false;6747 p_dspin_m2p.read = false; 6670 6748 break; 6671 6749 } 6672 6750 ///////////////////////////// 6673 case CC_RECEIVE_INVAL_HEADER: 6674 { 6675 if (((r_cc_receive_data_ins.read() == 0) and not (r_cc_receive_dcache_req.read())) or 6676 ((r_cc_receive_data_ins.read() == 1) and not (r_cc_receive_icache_req.read()))) 6677 p_dspin_in.read = true; 6751 case CC_RECEIVE_DATA_INVAL_HEADER: 6752 case CC_RECEIVE_INS_INVAL_HEADER: 6753 { 6754 p_dspin_m2p.read = true; 6755 break; 6756 } 6757 //////////////////////////// 6758 case CC_RECEIVE_DATA_INVAL_NLINE: 6759 { 6760 p_dspin_m2p.read = not r_cc_receive_dcache_req.read(); 6761 break; 6762 } 6763 case CC_RECEIVE_INS_INVAL_NLINE: 6764 { 6765 p_dspin_m2p.read = not r_cc_receive_icache_req.read(); 6766 break; 6767 } 6768 /////////////////////////// 6769 case CC_RECEIVE_DATA_UPDT_HEADER: 6770 { 6771 if (not r_cc_receive_dcache_req.read()) 6772 p_dspin_m2p.read = true; 6678 6773 else 6679 p_dspin_ in.read = false;6774 p_dspin_m2p.read = false; 6680 6775 break; 6681 6776 } 6682 6777 //////////////////////////// 6683 case CC_RECEIVE_INVAL_NLINE: 6684 { 6685 p_dspin_in.read = true; 6686 break; 6687 } 6688 //////////////////////////// 6689 case CC_RECEIVE_UPDT_HEADER: 6690 { 6691 if (((r_cc_receive_data_ins.read() == 0) and 6692 not r_cc_receive_dcache_req.read() and 6693 r_cc_receive_updt_fifo_be.empty()) 6694 or 6695 (((r_cc_receive_data_ins.read() == 1) and 6696 not r_cc_receive_icache_req.read()) and 6697 r_cc_receive_updt_fifo_be.empty())) 6698 p_dspin_in.read = true; 6778 case CC_RECEIVE_INS_UPDT_HEADER: 6779 { 6780 if ( not r_cc_receive_icache_req.read()) 6781 p_dspin_m2p.read = true; 6699 6782 else 6700 p_dspin_ in.read = false;6783 p_dspin_m2p.read = false; 6701 6784 break; 6702 6785 } 6703 6786 /////////////////////////// 6704 case CC_RECEIVE_UPDT_NLINE: 6705 { 6706 if (((r_cc_receive_data_ins.read() == 0) and 6707 not (r_cc_receive_dcache_req.read()) and 6708 r_cc_receive_updt_fifo_be.empty()) 6709 or 6710 ((r_cc_receive_data_ins.read() == 1) and 6711 not (r_cc_receive_icache_req.read()) and 6712 r_cc_receive_updt_fifo_be.empty())) 6713 p_dspin_in.read = true; 6787 case CC_RECEIVE_DATA_UPDT_NLINE: 6788 case CC_RECEIVE_INS_UPDT_NLINE: 6789 { 6790 if(r_cc_receive_updt_fifo_be.empty()) 6791 p_dspin_m2p.read = true; 6714 6792 else 6715 p_dspin_in.read = false; 6716 break; 6717 } 6718 ////////////////////////// 6719 case CC_RECEIVE_UPDT_DATA: 6793 p_dspin_m2p.read = false; 6794 break; 6795 } 6796 /////////////////////////// 6797 case CC_RECEIVE_DATA_UPDT_DATA: 6798 case CC_RECEIVE_INS_UPDT_DATA: 6720 6799 { 6721 6800 if (r_cc_receive_updt_fifo_be.wok()) 6722 p_dspin_ in.read = true;6801 p_dspin_m2p.read = true; 6723 6802 else 6724 p_dspin_ in.read = false;6803 p_dspin_m2p.read = false; 6725 6804 break; 6726 6805 } 6727 6806 } // end switch CC_RECEIVE FSM 6728 6807 6808 6809 int clack_type = DspinDhccpParam::dspin_get(r_dspin_clack_flit.read(), 6810 DspinDhccpParam::CLACK_TYPE); 6811 6812 bool dspin_clack_get = false; 6813 bool dcache_clack_request = (clack_type == DspinDhccpParam::TYPE_CLACK_DATA); 6814 bool icache_clack_request = (clack_type == DspinDhccpParam::TYPE_CLACK_INST); 6815 6816 if (r_dspin_clack_req.read()) 6817 { 6818 // CLACK DATA: wait if pending request to DCACHE FSM 6819 if (dcache_clack_request and not r_dcache_clack_req.read()) 6820 { 6821 dspin_clack_get = true; 6822 } 6823 6824 // CLACK INST: wait if pending request to ICACHE FSM 6825 else if (icache_clack_request and not r_icache_clack_req.read()) 6826 { 6827 dspin_clack_get = true; 6828 } 6829 } 6830 else 6831 { 6832 dspin_clack_get = true; 6833 } 6834 6835 p_dspin_clack.read = dspin_clack_get; 6729 6836 } // end genMoore 6730 6837
Note: See TracChangeset
for help on using the changeset viewer.