Changeset 468 for trunk/modules/vci_cc_vcache_wrapper
- Timestamp:
- Jul 24, 2013, 8:47:40 AM (11 years ago)
- Location:
- trunk/modules/vci_cc_vcache_wrapper
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/modules/vci_cc_vcache_wrapper
-
Property
svn:mergeinfo
set to
/branches/v5/modules/vci_cc_vcache_wrapper merged eligible
-
Property
svn:mergeinfo
set to
-
trunk/modules/vci_cc_vcache_wrapper/caba/metadata/vci_cc_vcache_wrapper.sd
r421 r468 37 37 ports = [ 38 38 Port('caba:vci_initiator', 'p_vci'), 39 Port('caba:dspin_input', 'p_dspin_ in',39 Port('caba:dspin_input', 'p_dspin_m2p', 40 40 dspin_data_size = parameter.Reference('dspin_in_width')), 41 Port('caba:dspin_output', 'p_dspin_ out',41 Port('caba:dspin_output', 'p_dspin_p2m', 42 42 dspin_data_size = parameter.Reference('dspin_out_width')), 43 Port('caba:dspin_input', 'p_dspin_clack', 44 dspin_data_size = parameter.Reference('dspin_in_width')), 43 45 Port('caba:bit_in','p_irq', parameter.Constant('n_irq')), 44 46 Port('caba:bit_in', 'p_resetn', auto = 'resetn'), -
trunk/modules/vci_cc_vcache_wrapper/caba/source/include/vci_cc_vcache_wrapper.h
r432 r468 89 89 // handling coherence requests 90 90 ICACHE_CC_CHECK, 91 ICACHE_CC_UPDT, 91 92 ICACHE_CC_INVAL, 92 ICACHE_CC_UPDT,93 ICACHE_CC_BROADCAST,94 ICACHE_CC_SEND_WAIT,95 93 }; 96 94 … … 138 136 // handling coherence requests 139 137 DCACHE_CC_CHECK, 138 DCACHE_CC_UPDT, 140 139 DCACHE_CC_INVAL, 141 DCACHE_CC_UPDT,142 DCACHE_CC_BROADCAST,143 DCACHE_CC_SEND_WAIT,144 140 // handling TLB inval (after a coherence or XTN request) 145 141 DCACHE_INVAL_TLB_SCAN, … … 173 169 { 174 170 CC_RECEIVE_IDLE, 175 CC_RECEIVE_CLACK,176 171 CC_RECEIVE_BRDCAST_HEADER, 177 172 CC_RECEIVE_BRDCAST_NLINE, 178 CC_RECEIVE_INVAL_HEADER, 179 CC_RECEIVE_INVAL_NLINE, 180 CC_RECEIVE_UPDT_HEADER, 181 CC_RECEIVE_UPDT_NLINE, 182 CC_RECEIVE_UPDT_DATA, 173 CC_RECEIVE_INS_INVAL_HEADER, 174 CC_RECEIVE_INS_INVAL_NLINE, 175 CC_RECEIVE_INS_UPDT_HEADER, 176 CC_RECEIVE_INS_UPDT_NLINE, 177 CC_RECEIVE_INS_UPDT_DATA, 178 CC_RECEIVE_DATA_INVAL_HEADER, 179 CC_RECEIVE_DATA_INVAL_NLINE, 180 CC_RECEIVE_DATA_UPDT_HEADER, 181 CC_RECEIVE_DATA_UPDT_NLINE, 182 CC_RECEIVE_DATA_UPDT_DATA, 183 183 }; 184 184 … … 285 285 286 286 public: 287 sc_in<bool> p_clk; 288 sc_in<bool> p_resetn; 289 sc_in<bool> p_irq[iss_t::n_irq]; 290 soclib::caba::VciInitiator<vci_param> p_vci; 291 soclib::caba::DspinInput <dspin_in_width> p_dspin_in; 292 soclib::caba::DspinOutput<dspin_out_width> p_dspin_out; 287 sc_in<bool> p_clk; 288 sc_in<bool> p_resetn; 289 sc_in<bool> p_irq[iss_t::n_irq]; 290 soclib::caba::VciInitiator<vci_param> p_vci; 291 soclib::caba::DspinInput<dspin_in_width> p_dspin_m2p; 292 soclib::caba::DspinOutput<dspin_out_width> p_dspin_p2m; 293 soclib::caba::DspinInput<dspin_in_width> p_dspin_clack; 293 294 294 295 private: … … 371 372 sc_signal<bool> r_icache_cc_need_write; // activate the cache for writing 372 373 374 // coherence clack handling 375 sc_signal<bool> r_icache_clack_req; // clack request 376 sc_signal<size_t> r_icache_clack_way; // clack way 377 sc_signal<size_t> r_icache_clack_set; // clack set 378 373 379 // icache flush handling 374 380 sc_signal<size_t> r_icache_flush_count; // slot counter used for cache flush … … 444 450 sc_signal<bool> r_dcache_cc_need_write; // activate the cache for writing 445 451 452 // coherence clack handling 453 sc_signal<bool> r_dcache_clack_req; // clack request 454 sc_signal<size_t> r_dcache_clack_way; // clack way 455 sc_signal<size_t> r_dcache_clack_set; // clack set 456 446 457 // dcache flush handling 447 458 sc_signal<size_t> r_dcache_flush_count; // slot counter used for cache flush … … 537 548 sc_signal<paddr_t> r_cc_receive_dcache_nline; // cache line physical address 538 549 550 /////////////////////////////////// 551 // DSPIN CLACK INTERFACE REGISTER 552 /////////////////////////////////// 553 sc_signal<bool> r_dspin_clack_req; 554 sc_signal<uint64_t> r_dspin_clack_flit; 555 539 556 ////////////////////////////////////////////////////////////////// 540 557 // processor, write buffer, caches , TLBs -
trunk/modules/vci_cc_vcache_wrapper/caba/source/src/vci_cc_vcache_wrapper.cpp
r434 r468 62 62 63 63 "ICACHE_CC_CHECK", 64 "ICACHE_CC_UPDT", 64 65 "ICACHE_CC_INVAL", 65 "ICACHE_CC_UPDT",66 "ICACHE_CC_BROADCAST",67 "ICACHE_CC_SEND_WAIT",68 66 }; 69 67 … … 110 108 111 109 "DCACHE_CC_CHECK", 110 "DCACHE_CC_UPDT", 112 111 "DCACHE_CC_INVAL", 113 "DCACHE_CC_UPDT",114 "DCACHE_CC_BROADCAST",115 "DCACHE_CC_SEND_WAIT",116 112 117 113 "DCACHE_INVAL_TLB_SCAN", … … 160 156 const char *cc_receive_fsm_state_str[] = { 161 157 "CC_RECEIVE_IDLE", 162 "CC_RECEIVE_CLACK",163 158 "CC_RECEIVE_BRDCAST_HEADER", 164 159 "CC_RECEIVE_BRDCAST_NLINE", 165 "CC_RECEIVE_INVAL_HEADER", 166 "CC_RECEIVE_INVAL_NLINE", 167 "CC_RECEIVE_UPDT_HEADER", 168 "CC_RECEIVE_UPDT_NLINE", 169 "CC_RECEIVE_UPDT_DATA", 160 "CC_RECEIVE_INS_INVAL_HEADER", 161 "CC_RECEIVE_INS_INVAL_NLINE", 162 "CC_RECEIVE_INS_UPDT_HEADER", 163 "CC_RECEIVE_INS_UPDT_NLINE", 164 "CC_RECEIVE_INS_UPDT_DATA", 165 "CC_RECEIVE_DATA_INVAL_HEADER", 166 "CC_RECEIVE_DATA_INVAL_NLINE", 167 "CC_RECEIVE_DATA_UPDT_HEADER", 168 "CC_RECEIVE_DATA_UPDT_NLINE", 169 "CC_RECEIVE_DATA_UPDT_DATA", 170 170 }; 171 171 … … 216 216 p_resetn("p_resetn"), 217 217 p_vci("p_vci"), 218 p_dspin_in("p_dspin_in"), 219 p_dspin_out("p_dspin_out"), 218 p_dspin_m2p("p_dspin_m2p"), 219 p_dspin_p2m("p_dspin_p2m"), 220 p_dspin_clack("p_dspin_clack"), 220 221 221 222 m_cacheability_table( mtd.getCacheabilityTable() ), … … 755 756 r_icache_cc_send_req = false; 756 757 758 r_icache_clack_req = false; 759 757 760 // No pending write in pipeline 758 761 r_dcache_wbuf_req = false; … … 775 778 r_dcache_cc_send_req = false; 776 779 780 r_dcache_clack_req = false; 781 777 782 // No request from CC_RECEIVE FSM to ICACHE/DCACHE FSMs 778 783 r_cc_receive_icache_req = false; … … 789 794 r_icache_miss_inval = false; 790 795 r_dcache_miss_inval = false; 796 797 r_dspin_clack_req = false; 791 798 792 799 // No signalisation of errors … … 1014 1021 // 5/ uncacheable read miss => ICACHE_UNC_REQ 1015 1022 { 1023 // coherence clack interrupt 1024 if ( r_icache_clack_req.read() ) 1025 { 1026 r_icache_fsm = ICACHE_CC_CHECK; 1027 r_icache_fsm_save = r_icache_fsm.read(); 1028 break; 1029 } 1030 1016 1031 // coherence interrupt 1017 1032 if ( r_cc_receive_icache_req.read() ) … … 1242 1257 // external coherence request are accepted in this state. 1243 1258 { 1259 // coherence clack interrupt 1260 if ( r_icache_clack_req.read() ) 1261 { 1262 r_icache_fsm = ICACHE_CC_CHECK; 1263 r_icache_fsm_save = r_icache_fsm.read(); 1264 break; 1265 } 1266 1244 1267 // coherence interrupt 1245 1268 if ( r_cc_receive_icache_req.read() ) … … 1286 1309 // A cleanup request is generated for each valid line 1287 1310 { 1311 // coherence clack interrupt 1312 if ( r_icache_clack_req.read() ) 1313 { 1314 r_icache_fsm = ICACHE_CC_CHECK; 1315 r_icache_fsm_save = r_icache_fsm.read(); 1316 break; 1317 } 1318 1288 1319 // coherence request (from CC_RECEIVE FSM) 1289 1320 if ( r_cc_receive_icache_req.read() ) … … 1484 1515 { 1485 1516 if (m_ireq.valid) m_cost_ins_miss_frz++; 1517 1518 // coherence clack interrupt 1519 if ( r_icache_clack_req.read() ) 1520 { 1521 r_icache_fsm = ICACHE_CC_CHECK; 1522 r_icache_fsm_save = r_icache_fsm.read(); 1523 break; 1524 } 1486 1525 1487 1526 // coherence interrupt … … 1574 1613 if (m_ireq.valid) m_cost_ins_miss_frz++; 1575 1614 1615 // coherence clack interrupt 1616 if ( r_icache_clack_req.read() ) 1617 { 1618 r_icache_fsm = ICACHE_CC_CHECK; 1619 r_icache_fsm_save = r_icache_fsm.read(); 1620 break; 1621 } 1622 1576 1623 // coherence interrupt 1577 1624 if ( r_cc_receive_icache_req.read() ) … … 1645 1692 if ( m_ireq.valid ) m_cost_ins_miss_frz++; 1646 1693 1694 // coherence clack interrupt 1695 if ( r_icache_clack_req.read() ) 1696 { 1697 r_icache_fsm = ICACHE_CC_CHECK; 1698 r_icache_fsm_save = r_icache_fsm.read(); 1699 break; 1700 } 1701 1647 1702 // coherence interrupt 1648 1703 if ( r_cc_receive_icache_req.read() ) … … 1716 1771 case ICACHE_UNC_WAIT: // waiting a response to an uncacheable read from VCI_RSP FSM 1717 1772 { 1773 // coherence clack interrupt 1774 if ( r_icache_clack_req.read() ) 1775 { 1776 r_icache_fsm = ICACHE_CC_CHECK; 1777 r_icache_fsm_save = r_icache_fsm.read(); 1778 break; 1779 } 1780 1718 1781 // coherence interrupt 1719 1782 if ( r_cc_receive_icache_req.read() ) … … 1756 1819 paddr_t mask = ~((m_icache_words<<2)-1); 1757 1820 1758 if (r_cc_receive_icache_type.read() == CC_TYPE_CLACK) 1759 // We switch the directory slot to EMPTY state 1760 // and reset r_icache_miss_clack if the cleanup ack 1761 // is matching a pending miss 1762 { 1763 1764 if ( m_ireq.valid ) m_cost_ins_miss_frz++; 1765 1766 #ifdef INSTRUMENTATION 1767 m_cpt_icache_dir_write++; 1768 #endif 1769 r_icache.write_dir( 0, 1770 r_cc_receive_icache_way.read(), 1771 r_cc_receive_icache_set.read(), 1772 CACHE_SLOT_STATE_EMPTY); 1773 1774 if ( (r_icache_miss_set.read() == r_cc_receive_icache_set.read()) and 1775 (r_icache_miss_way.read() == r_cc_receive_icache_way.read()) ) 1776 r_icache_miss_clack = false; 1777 1778 r_icache_fsm = r_icache_fsm_save.read() ; 1779 r_cc_receive_icache_req = false; 1780 1781 #if DEBUG_ICACHE 1782 if ( m_debug_activated ) 1783 { 1784 std::cout << " <PROC " << name() 1785 << " ICACHE_CC_CHECK> CC_TYPE_CLACK slot returns to empty state" 1786 << " set = " << r_cc_receive_icache_set.read() 1787 << " / way = " << r_cc_receive_icache_way.read() << std::endl; 1788 } 1789 #endif 1790 } 1791 else if( ((r_icache_fsm_save.read() == ICACHE_MISS_SELECT) or 1792 (r_icache_fsm_save.read() == ICACHE_MISS_WAIT) or 1793 (r_icache_fsm_save.read() == ICACHE_MISS_DIR_UPDT)) and 1794 ((r_icache_vci_paddr.read() & mask) == (paddr & mask)) ) // matching 1821 1822 // Match between MISS address and CC address 1823 // note: In the same cycle we can handle a CLACK and a MISS match 1824 // because the CLACK access the directory but the MISS match dont. 1825 if (r_cc_receive_icache_req.read() and 1826 ((r_icache_fsm_save.read() == ICACHE_MISS_SELECT ) or 1827 (r_icache_fsm_save.read() == ICACHE_MISS_WAIT ) or 1828 (r_icache_fsm_save.read() == ICACHE_MISS_DIR_UPDT)) and 1829 ((r_icache_vci_paddr.read() & mask) == (paddr & mask)) ) // matching 1795 1830 { 1796 1831 // signaling the matching … … 1803 1838 r_icache_fsm = ICACHE_CC_UPDT; 1804 1839 r_icache_cc_word = r_cc_receive_word_idx.read(); 1840 1805 1841 // just pop the fifo , don't write in icache 1806 1842 r_icache_cc_need_write = false; … … 1821 1857 #endif 1822 1858 } 1823 else // no match 1824 { 1825 int state = 0; 1826 size_t way = 0; 1827 size_t set = 0; 1828 size_t word = 0; 1859 1860 // CLACK handler 1861 // We switch the directory slot to EMPTY state 1862 // and reset r_icache_miss_clack if the cleanup ack 1863 // is matching a pending miss. 1864 if ( r_icache_clack_req.read() ) 1865 { 1866 1867 if ( m_ireq.valid ) m_cost_ins_miss_frz++; 1829 1868 1830 1869 #ifdef INSTRUMENTATION 1831 m_cpt_icache_dir_read++; 1832 #endif 1833 r_icache.read_dir(paddr, 1834 &state, 1835 &way, 1836 &set, 1837 &word); 1838 1839 r_icache_cc_way = way; 1840 r_icache_cc_set = set; 1841 1842 if ( state == CACHE_SLOT_STATE_VALID) // hit 1843 { 1844 // need to update the cache state 1845 r_icache_cc_need_write = true; 1846 if (r_cc_receive_icache_type.read() == CC_TYPE_UPDT) // hit update 1847 { 1848 r_icache_fsm = ICACHE_CC_UPDT; 1849 r_icache_cc_word = r_cc_receive_word_idx.read(); 1850 } 1851 else if (r_cc_receive_icache_type.read() == CC_TYPE_INVAL) // hit inval 1852 { 1853 r_icache_fsm = ICACHE_CC_INVAL; 1854 } 1855 else if (r_cc_receive_icache_type.read() == CC_TYPE_BRDCAST) // hit broadcast 1856 { 1857 r_icache_fsm = ICACHE_CC_BROADCAST; 1858 } 1859 } 1860 else // miss 1861 { 1862 // multicast acknowledgement required in case of update 1863 if(r_cc_receive_icache_type.read() == CC_TYPE_UPDT) 1864 { 1865 r_icache_fsm = ICACHE_CC_UPDT; 1866 r_icache_cc_word = r_cc_receive_word_idx.read(); 1867 // just pop the fifo , don't write in icache 1868 r_icache_cc_need_write = false; 1869 } 1870 else // No response needed 1871 { 1872 r_cc_receive_icache_req = false; 1873 r_icache_fsm = r_icache_fsm_save.read(); 1874 } 1875 } 1876 } 1877 break; 1878 } 1879 ///////////////////// 1880 case ICACHE_CC_INVAL: // hit inval : switch slot to EMPTY state 1881 { 1870 m_cpt_icache_dir_write++; 1871 #endif 1872 r_icache.write_dir( 0, 1873 r_icache_clack_way.read(), 1874 r_icache_clack_set.read(), 1875 CACHE_SLOT_STATE_EMPTY); 1876 1877 if ( (r_icache_miss_set.read() == r_icache_clack_set.read()) and 1878 (r_icache_miss_way.read() == r_icache_clack_way.read()) ) 1879 { 1880 r_icache_miss_clack = false; 1881 } 1882 1883 r_icache_clack_req = false; 1884 1885 // return to cc_save state if no pending CC request 1886 if ( not r_cc_receive_icache_req.read() ) 1887 r_icache_fsm = r_icache_fsm_save.read(); 1882 1888 1883 1889 #if DEBUG_ICACHE … … 1885 1891 { 1886 1892 std::cout << " <PROC " << name() 1887 << " ICACHE_CC_INVAL>slot returns to empty state"1888 << " set = " << r_icache_cc_set.read()1889 << " / way = " << r_icache_cc_way.read() << std::endl;1893 << " ICACHE_CC_CHECK> CC_TYPE_CLACK slot returns to empty state" 1894 << " set = " << r_icache_clack_set.read() 1895 << " / way = " << r_icache_clack_way.read() << std::endl; 1890 1896 } 1891 1897 #endif 1898 1899 break; 1900 } 1901 1902 // wait if pending request to CC_SEND. This way if there are pending 1903 // CLACK they can be treated in this state and then a deadlock 1904 // situation is avoided 1905 if ( r_icache_cc_send_req.read() ) break; 1906 1907 // CC request handler 1908 1909 int state = 0; 1910 size_t way = 0; 1911 size_t set = 0; 1912 size_t word = 0; 1892 1913 1893 1914 #ifdef INSTRUMENTATION 1894 1915 m_cpt_icache_dir_read++; 1895 1916 #endif 1896 if (r_icache_cc_need_write.read()) 1897 { 1898 r_icache.write_dir( 0, 1899 r_icache_cc_way.read(), 1900 r_icache_cc_set.read(), 1901 CACHE_SLOT_STATE_EMPTY ); 1902 // no need to write in the cache anymore 1903 r_icache_cc_need_write = false; 1904 } 1905 1906 // multicast acknowledgement 1907 // send a request to cc_send_fsm 1908 if(not r_icache_cc_send_req.read()) // cc_send is available 1909 { 1910 // coherence request completed 1911 r_cc_receive_icache_req = false; 1912 // request multicast acknowledgement 1913 r_icache_cc_send_req = true; 1914 r_icache_cc_send_nline = r_cc_receive_icache_nline.read(); 1915 r_icache_cc_send_updt_tab_idx = r_cc_receive_icache_updt_tab_idx.read(); 1916 r_icache_cc_send_type = CC_TYPE_MULTI_ACK; 1917 1918 r_icache_fsm = r_icache_fsm_save.read(); 1919 } 1920 //else wait for previous cc_send request to be sent 1917 r_icache.read_dir(paddr, 1918 &state, 1919 &way, 1920 &set, 1921 &word); 1922 1923 r_icache_cc_way = way; 1924 r_icache_cc_set = set; 1925 1926 if ( state == CACHE_SLOT_STATE_VALID) // hit 1927 { 1928 // need to update the cache state 1929 if (r_cc_receive_icache_type.read() == CC_TYPE_UPDT) // hit update 1930 { 1931 r_icache_cc_need_write = true; 1932 r_icache_fsm = ICACHE_CC_UPDT; 1933 r_icache_cc_word = r_cc_receive_word_idx.read(); 1934 } 1935 else if ( r_cc_receive_icache_type.read() == CC_TYPE_INVAL ) // hit inval 1936 { 1937 r_icache_fsm = ICACHE_CC_INVAL; 1938 } 1939 } 1940 else // miss 1941 { 1942 // multicast acknowledgement required in case of update 1943 if(r_cc_receive_icache_type.read() == CC_TYPE_UPDT) 1944 { 1945 r_icache_fsm = ICACHE_CC_UPDT; 1946 r_icache_cc_word = r_cc_receive_word_idx.read(); 1947 1948 // just pop the fifo , don't write in icache 1949 r_icache_cc_need_write = false; 1950 } 1951 else // No response needed 1952 { 1953 r_cc_receive_icache_req = false; 1954 r_icache_fsm = r_icache_fsm_save.read(); 1955 } 1956 } 1957 break; 1958 } 1959 ///////////////////// 1960 case ICACHE_CC_INVAL: // hit inval : switch slot to ZOMBI state 1961 { 1962 assert (not r_icache_cc_send_req.read() && 1963 "ERROR in ICACHE_CC_INVAL: the r_icache_cc_send_req " 1964 "must not be set"); 1965 1966 #ifdef INSTRUMENTATION 1967 m_cpt_icache_dir_read++; 1968 #endif 1969 1970 // Switch slot state to ZOMBI and send CLEANUP command 1971 r_icache.write_dir( 0, 1972 r_icache_cc_way.read(), 1973 r_icache_cc_set.read(), 1974 CACHE_SLOT_STATE_ZOMBI ); 1975 1976 // coherence request completed 1977 r_icache_cc_send_req = true; 1978 r_icache_cc_send_nline = r_cc_receive_icache_nline.read(); 1979 r_icache_cc_send_way = r_icache_cc_way.read(); 1980 r_icache_cc_send_type = CC_TYPE_CLEANUP; 1981 1982 r_icache_fsm = r_icache_fsm_save.read(); 1983 1984 #if DEBUG_ICACHE 1985 if ( m_debug_activated ) 1986 { 1987 std::cout << " <PROC " << name() 1988 << " ICACHE_CC_INVAL> slot returns to ZOMBI state" 1989 << " set = " << r_icache_cc_set.read() 1990 << " / way = " << r_icache_cc_way.read() << std::endl; 1991 } 1992 #endif 1993 1921 1994 break; 1922 1995 } … … 1924 1997 case ICACHE_CC_UPDT: // hit update : write one word per cycle 1925 1998 { 1999 assert (not r_icache_cc_send_req.read() && 2000 "ERROR in ICACHE_CC_UPDT: the r_icache_cc_send_req " 2001 "must not be set"); 2002 2003 if ( not r_cc_receive_updt_fifo_be.rok() ) break; 2004 2005 2006 size_t word = r_icache_cc_word.read(); 2007 size_t way = r_icache_cc_way.read(); 2008 size_t set = r_icache_cc_set.read(); 2009 2010 if (r_icache_cc_need_write.read()) 2011 { 2012 r_icache.write( way, 2013 set, 2014 word, 2015 r_cc_receive_updt_fifo_data.read(), 2016 r_cc_receive_updt_fifo_be.read() ); 2017 2018 r_icache_cc_word = word+1; 2019 2020 #ifdef INSTRUMENTATION 2021 m_cpt_icache_data_write++; 2022 #endif 1926 2023 1927 2024 #if DEBUG_ICACHE … … 1935 2032 } 1936 2033 #endif 1937 1938 #ifdef INSTRUMENTATION 1939 m_cpt_icache_data_write++; 1940 #endif 1941 size_t word = r_icache_cc_word.read(); 1942 size_t way = r_icache_cc_way.read(); 1943 size_t set = r_icache_cc_set.read(); 1944 1945 if (r_cc_receive_updt_fifo_be.rok()) 1946 { 1947 if (r_icache_cc_need_write.read()) 1948 { 1949 r_icache.write( way, 1950 set, 1951 word, 1952 r_cc_receive_updt_fifo_data.read(), 1953 r_cc_receive_updt_fifo_be.read() ); 1954 1955 r_icache_cc_word = word+1; 1956 } 1957 if ( r_cc_receive_updt_fifo_eop.read() ) // last word 1958 { 1959 // no need to write in the cache anymore 1960 r_icache_cc_need_write = false; 1961 // wait to send a request to cc_send_fsm 1962 if(not r_icache_cc_send_req.read()) // cc_send is available 1963 { 1964 //consume last flit 1965 cc_receive_updt_fifo_get = true; 1966 // coherence request completed 1967 r_cc_receive_icache_req = false; 1968 // request multicast acknowledgement 1969 r_icache_cc_send_req = true; 1970 r_icache_cc_send_nline = r_cc_receive_icache_nline.read(); 1971 r_icache_cc_send_updt_tab_idx = r_cc_receive_icache_updt_tab_idx.read(); 1972 r_icache_cc_send_type = CC_TYPE_MULTI_ACK; 1973 1974 r_icache_fsm = r_icache_fsm_save.read(); 1975 } 1976 } 1977 else 1978 { 1979 //consume fifo if not eop 1980 cc_receive_updt_fifo_get = true; 1981 } 1982 } 2034 } 2035 2036 if ( r_cc_receive_updt_fifo_eop.read() ) // last word 2037 { 2038 // no need to write in the cache anymore 2039 r_icache_cc_need_write = false; 2040 2041 // coherence request completed 2042 r_cc_receive_icache_req = false; 2043 2044 // request multicast acknowledgement 2045 r_icache_cc_send_req = true; 2046 r_icache_cc_send_nline = r_cc_receive_icache_nline.read(); 2047 r_icache_cc_send_updt_tab_idx = r_cc_receive_icache_updt_tab_idx.read(); 2048 r_icache_cc_send_type = CC_TYPE_MULTI_ACK; 2049 2050 r_icache_fsm = r_icache_fsm_save.read(); 2051 } 2052 //consume fifo if not eop 2053 cc_receive_updt_fifo_get = true; 2054 1983 2055 break; 1984 2056 } 1985 ///////////////////////// 1986 case ICACHE_CC_BROADCAST: // hit broadcast : switch slot to ZOMBI state 1987 // and request a cleanup 1988 { 1989 1990 #if DEBUG_ICACHE 1991 if ( m_debug_activated ) 1992 { 1993 std::cout << " <PROC " << name() 1994 << " ICACHE_CC_BROADCAST > Slot goes to zombi state " 1995 << " set = " << r_icache_cc_set.read() 1996 << " / way = " << r_icache_cc_way.read() << std::endl; 1997 } 1998 #endif 1999 2000 #ifdef INSTRUMENTATION 2001 m_cpt_icache_dir_write++; 2002 #endif 2003 if (r_icache_cc_need_write.read()) 2004 { 2005 r_icache.write_dir( r_icache_cc_way.read(), 2006 r_icache_cc_set.read(), 2007 CACHE_SLOT_STATE_ZOMBI ); 2008 // no need to write in the cache anymore 2009 r_icache_cc_need_write = false; 2010 } 2011 2012 // cleanup 2013 // send a request to cc_send_fsm 2014 if(not r_icache_cc_send_req.read()) // cc_send is available 2015 { 2016 // coherence request completed 2017 r_cc_receive_icache_req = false; 2018 // request cleanup 2019 r_icache_cc_send_req = true; 2020 r_icache_cc_send_nline = r_cc_receive_icache_nline.read(); 2021 r_icache_cc_send_way = r_icache_cc_way.read(); 2022 r_icache_cc_send_type = CC_TYPE_CLEANUP; 2023 2024 r_icache_fsm = r_icache_fsm_save.read(); 2025 } 2026 //else wait for previous cc_send request to be sent 2027 break; 2028 } 2057 2029 2058 } // end switch r_icache_fsm 2030 2059 … … 2308 2337 } 2309 2338 2339 // coherence clack request (from DSPIN CLACK) 2340 else if ( r_dcache_clack_req.read() ) 2341 { 2342 r_dcache_fsm = DCACHE_CC_CHECK; 2343 r_dcache_fsm_cc_save = r_dcache_fsm.read(); 2344 } 2310 2345 // coherence request (from CC_RECEIVE FSM) 2311 2346 else if ( r_cc_receive_dcache_req.read() ) … … 2912 2947 case DCACHE_TLB_PTE1_GET: // try to read a PT1 entry in dcache 2913 2948 { 2949 // coherence clack request (from DSPIN CLACK) 2950 if ( r_dcache_clack_req.read() ) 2951 { 2952 r_dcache_fsm = DCACHE_CC_CHECK; 2953 r_dcache_fsm_cc_save = r_dcache_fsm.read(); 2954 break; 2955 } 2956 2914 2957 // coherence request (from CC_RECEIVE FSM) 2915 2958 if ( r_cc_receive_dcache_req.read() ) … … 3209 3252 case DCACHE_TLB_PTE2_GET: // Try to get a PTE2 (64 bits) in the dcache 3210 3253 { 3254 // coherence clack request (from DSPIN CLACK) 3255 if ( r_dcache_clack_req.read() ) 3256 { 3257 r_dcache_fsm = DCACHE_CC_CHECK; 3258 r_dcache_fsm_cc_save = r_dcache_fsm.read(); 3259 break; 3260 } 3261 3211 3262 // coherence request (from CC_RECEIVE FSM) 3212 3263 if ( r_cc_receive_dcache_req.read() ) … … 3506 3557 3507 3558 { 3559 // coherence clack request (from DSPIN CLACK) 3560 if ( r_dcache_clack_req.read() ) 3561 { 3562 r_dcache_fsm = DCACHE_CC_CHECK; 3563 r_dcache_fsm_cc_save = r_dcache_fsm.read(); 3564 break; 3565 } 3566 3508 3567 // coherence request (from CC_RECEIVE FSM) 3509 3568 if ( r_cc_receive_dcache_req.read() ) … … 3577 3636 // as there is a risk of dead-lock 3578 3637 { 3638 // coherence clack request (from DSPIN CLACK) 3639 if ( r_dcache_clack_req.read() ) 3640 { 3641 r_dcache_fsm = DCACHE_CC_CHECK; 3642 r_dcache_fsm_cc_save = r_dcache_fsm.read(); 3643 break; 3644 } 3645 3579 3646 // coherence request (from CC_RECEIVE FSM) 3580 3647 if ( r_cc_receive_dcache_req.read() ) … … 3582 3649 r_dcache_fsm = DCACHE_CC_CHECK; 3583 3650 r_dcache_fsm_cc_save = r_dcache_fsm.read(); 3651 break; 3584 3652 } 3585 3653 … … 3598 3666 // and because it can exist a simultaneous ITLB miss 3599 3667 { 3668 // coherence clack request (from DSPIN CLACK) 3669 if ( r_dcache_clack_req.read() ) 3670 { 3671 r_dcache_fsm = DCACHE_CC_CHECK; 3672 r_dcache_fsm_cc_save = r_dcache_fsm.read(); 3673 break; 3674 } 3675 3600 3676 // coherence request (from CC_RECEIVE FSM) 3601 3677 if ( r_cc_receive_dcache_req.read() ) … … 3633 3709 // returns to IDLE and flush TLBs when last slot 3634 3710 { 3711 // coherence clack request (from DSPIN CLACK) 3712 if ( r_dcache_clack_req.read() ) 3713 { 3714 r_dcache_fsm = DCACHE_CC_CHECK; 3715 r_dcache_fsm_cc_save = r_dcache_fsm.read(); 3716 break; 3717 } 3718 3635 3719 // coherence request (from CC_RECEIVE FSM) 3636 3720 if ( r_cc_receive_dcache_req.read() ) … … 3893 3977 { 3894 3978 if ( m_dreq.valid) m_cost_data_miss_frz++; 3979 3980 // coherence clack request (from DSPIN CLACK) 3981 if ( r_dcache_clack_req.read() ) 3982 { 3983 r_dcache_fsm = DCACHE_CC_CHECK; 3984 r_dcache_fsm_cc_save = r_dcache_fsm.read(); 3985 break; 3986 } 3895 3987 3896 3988 // coherence request (from CC_RECEIVE FSM) … … 4009 4101 { 4010 4102 if ( m_dreq.valid) m_cost_data_miss_frz++; 4103 4104 // coherence clack request (from DSPIN CLACK) 4105 if ( r_dcache_clack_req.read() ) 4106 { 4107 r_dcache_fsm = DCACHE_CC_CHECK; 4108 r_dcache_fsm_cc_save = r_dcache_fsm.read(); 4109 break; 4110 } 4011 4111 4012 4112 // coherence request (from CC_RECEIVE FSM) … … 4125 4225 if ( m_dreq.valid) m_cost_data_miss_frz++; 4126 4226 4227 // coherence clack request (from DSPIN CLACK) 4228 if ( r_dcache_clack_req.read() ) 4229 { 4230 r_dcache_fsm = DCACHE_CC_CHECK; 4231 r_dcache_fsm_cc_save = r_dcache_fsm.read(); 4232 break; 4233 } 4234 4127 4235 // coherence request (from CC_RECEIVE FSM) 4128 4236 if ( r_cc_receive_dcache_req.read() ) … … 4199 4307 case DCACHE_UNC_WAIT: // waiting a response to an uncacheable read 4200 4308 { 4309 // coherence clack request (from DSPIN CLACK) 4310 if ( r_dcache_clack_req.read() ) 4311 { 4312 r_dcache_fsm = DCACHE_CC_CHECK; 4313 r_dcache_fsm_cc_save = r_dcache_fsm.read(); 4314 break; 4315 } 4316 4201 4317 // coherence request (from CC_RECEIVE FSM) 4202 4318 if ( r_cc_receive_dcache_req.read() ) … … 4236 4352 case DCACHE_LL_WAIT: // waiting VCI response to a LL transaction 4237 4353 { 4354 // coherence clack request (from DSPIN CLACK) 4355 if ( r_dcache_clack_req.read() ) 4356 { 4357 r_dcache_fsm = DCACHE_CC_CHECK; 4358 r_dcache_fsm_cc_save = r_dcache_fsm.read(); 4359 break; 4360 } 4361 4238 4362 // coherence request (from CC_RECEIVE FSM) 4239 4363 if ( r_cc_receive_dcache_req.read() ) … … 4282 4406 case DCACHE_SC_WAIT: // waiting VCI response to a SC transaction 4283 4407 { 4408 // coherence clack request (from DSPIN CLACK) 4409 if ( r_dcache_clack_req.read() ) 4410 { 4411 r_dcache_fsm = DCACHE_CC_CHECK; 4412 r_dcache_fsm_cc_save = r_dcache_fsm.read(); 4413 break; 4414 } 4415 4284 4416 // coherence request (from CC_RECEIVE FSM) 4285 4417 if ( r_cc_receive_dcache_req.read() ) … … 4321 4453 size_t way; 4322 4454 size_t set; 4323 size_t word; 4455 size_t word; // unused 4324 4456 int state; 4325 4457 … … 4374 4506 // - if the CAS is a failure, we just retry the write. 4375 4507 { 4508 // coherence clack request (from DSPIN CLACK) 4509 if ( r_dcache_clack_req.read() ) 4510 { 4511 r_dcache_fsm = DCACHE_CC_CHECK; 4512 r_dcache_fsm_cc_save = r_dcache_fsm.read(); 4513 break; 4514 } 4515 4376 4516 // coherence request (from CC_RECEIVE FSM) 4377 4517 if ( r_cc_receive_dcache_req.read() ) … … 4382 4522 } 4383 4523 4384 if ( r_vci_rsp_data_error.read() ) 4524 if ( r_vci_rsp_data_error.read() ) // bus error 4385 4525 { 4386 4526 std::cout << "BUS ERROR in DCACHE_DIRTY_WAIT state" << std::endl; … … 4388 4528 exit(0); 4389 4529 } 4390 else if ( r_vci_rsp_fifo_dcache.rok() ) 4530 else if ( r_vci_rsp_fifo_dcache.rok() ) // response available 4391 4531 { 4392 4532 vci_rsp_fifo_dcache_get = true; … … 4432 4572 #endif 4433 4573 4434 if (r_cc_receive_dcache_type.read() == CC_TYPE_CLACK) 4435 // We switch the directory slot to EMPTY state 4436 // and reset r_icache_miss_clack if the cleanup ack 4437 // is matching a pending miss. 4438 { 4439 4440 if ( m_dreq.valid ) m_cost_data_miss_frz++; 4441 4442 #ifdef INSTRUMENTATION 4443 m_cpt_dcache_dir_write++; 4444 #endif 4445 r_dcache.write_dir( 0, 4446 r_cc_receive_dcache_way.read(), 4447 r_cc_receive_dcache_set.read(), 4448 CACHE_SLOT_STATE_EMPTY); 4449 4450 if ( (r_dcache_miss_set.read() == r_cc_receive_dcache_set.read()) and 4451 (r_dcache_miss_way.read() == r_cc_receive_dcache_way.read()) ) 4452 r_dcache_miss_clack = false; 4453 4454 r_dcache_fsm = r_dcache_fsm_cc_save.read() ; 4455 r_cc_receive_dcache_req = false; 4456 #if DEBUG_DCACHE 4457 if ( m_debug_activated ) 4458 { 4459 std::cout << " <PROC " << name() 4460 << " DCACHE_CC_CHECK> CC_TYPE_CLACK Switch slot to EMPTY state" 4461 << " set = " << r_cc_receive_dcache_set.read() 4462 << " / way = " << r_cc_receive_dcache_way.read() << std::endl; 4463 } 4464 #endif 4465 } 4466 else if( ((r_dcache_fsm_cc_save == DCACHE_MISS_SELECT) or 4467 (r_dcache_fsm_cc_save == DCACHE_MISS_WAIT) or 4468 (r_dcache_fsm_cc_save == DCACHE_MISS_DIR_UPDT)) and 4469 ((r_dcache_vci_paddr.read() & mask) == (paddr & mask)) ) // matching 4574 4575 // Match between MISS address and CC address 4576 // note: In the same cycle we can handle a CLACK and a MISS match 4577 // because the CLACK access the directory but the MISS match dont. 4578 if (r_cc_receive_dcache_req.read() and 4579 ((r_dcache_fsm_cc_save == DCACHE_MISS_SELECT ) or 4580 (r_dcache_fsm_cc_save == DCACHE_MISS_WAIT ) or 4581 (r_dcache_fsm_cc_save == DCACHE_MISS_DIR_UPDT)) and 4582 ((r_dcache_vci_paddr.read() & mask) == (paddr & mask))) // matching 4470 4583 { 4471 4584 // signaling matching … … 4478 4591 r_dcache_fsm = DCACHE_CC_UPDT; 4479 4592 r_dcache_cc_word = r_cc_receive_word_idx.read(); 4593 4480 4594 // just pop the fifo , don't write in icache 4481 4595 r_dcache_cc_need_write = false; … … 4485 4599 { 4486 4600 r_cc_receive_dcache_req = false; 4487 r_dcache_fsm = r_dcache_fsm_cc_save.read();4601 r_dcache_fsm = r_dcache_fsm_cc_save.read(); 4488 4602 } 4489 4603 … … 4496 4610 } 4497 4611 #endif 4498 4499 } 4500 else // no match 4501 { 4502 int state = 0; 4503 size_t way = 0; 4504 size_t set = 0; 4505 size_t word = 0; 4612 } 4613 4614 // CLACK handler 4615 // We switch the directory slot to EMPTY state and reset 4616 // r_dcache_miss_clack if the cleanup ack is matching a pending miss. 4617 if ( r_dcache_clack_req.read() ) 4618 { 4619 if ( m_dreq.valid ) m_cost_data_miss_frz++; 4620 4621 #ifdef INSTRUMENTATION 4622 m_cpt_dcache_dir_write++; 4623 #endif 4624 r_dcache.write_dir( 0, 4625 r_dcache_clack_way.read(), 4626 r_dcache_clack_set.read(), 4627 CACHE_SLOT_STATE_EMPTY); 4628 4629 if ( (r_dcache_miss_set.read() == r_dcache_clack_set.read()) and 4630 (r_dcache_miss_way.read() == r_dcache_clack_way.read()) ) 4631 { 4632 r_dcache_miss_clack = false; 4633 } 4634 4635 r_dcache_clack_req = false; 4636 4637 // return to cc_save state if no pending CC request 4638 if ( not r_cc_receive_dcache_req.read() ) 4639 { 4640 r_dcache_fsm = r_dcache_fsm_cc_save.read() ; 4641 } 4642 4643 #if DEBUG_DCACHE 4644 if ( m_debug_activated ) 4645 { 4646 std::cout << " <PROC " << name() 4647 << " DCACHE_CC_CHECK> CC_TYPE_CLACK Switch slot to EMPTY state" 4648 << " set = " << r_dcache_clack_set.read() 4649 << " / way = " << r_dcache_clack_way.read() << std::endl; 4650 } 4651 #endif 4652 break; 4653 } 4654 4655 // wait if pending request to CC_SEND. This way if there are pending 4656 // CLACK they can be treated in this state and then a deadlock 4657 // situation is avoided 4658 if ( r_dcache_cc_send_req.read() ) break; 4659 4660 // CC request handler 4661 4662 int state = 0; 4663 size_t way = 0; 4664 size_t set = 0; 4665 size_t word = 0; 4506 4666 4507 4667 #ifdef INSTRUMENTATION 4508 4668 m_cpt_dcache_dir_read++; 4509 4669 #endif 4510 r_dcache.read_dir( paddr, 4511 &state, 4512 &way, 4513 &set, 4514 &word ); // unused 4515 4516 r_dcache_cc_way = way; 4517 r_dcache_cc_set = set; 4518 4519 if ( state == CACHE_SLOT_STATE_VALID) // hit 4520 { 4521 // need to update the cache state 4670 r_dcache.read_dir( paddr, 4671 &state, 4672 &way, 4673 &set, 4674 &word ); // unused 4675 4676 r_dcache_cc_way = way; 4677 r_dcache_cc_set = set; 4678 4679 if ( state == CACHE_SLOT_STATE_VALID) // hit 4680 { 4681 // need to update the cache state 4682 if (r_cc_receive_dcache_type.read() == CC_TYPE_UPDT) // hit update 4683 { 4522 4684 r_dcache_cc_need_write = true; 4523 if (r_cc_receive_dcache_type.read() == CC_TYPE_UPDT) // hit update 4524 { 4525 r_dcache_fsm = DCACHE_CC_UPDT; 4526 r_dcache_cc_word = r_cc_receive_word_idx.read(); 4527 } 4528 else if (r_cc_receive_dcache_type.read() == CC_TYPE_INVAL) // hit inval 4529 { 4530 r_dcache_fsm = DCACHE_CC_INVAL; 4531 } 4532 else if ( r_cc_receive_dcache_type.read() == CC_TYPE_BRDCAST) // hit broadcast 4533 { 4534 r_dcache_fsm = DCACHE_CC_BROADCAST; 4535 } 4536 } 4537 else // miss 4538 { 4539 // multicast acknowledgement required in case of update 4540 if(r_cc_receive_dcache_type.read() == CC_TYPE_UPDT) 4541 { 4542 r_dcache_fsm = DCACHE_CC_UPDT; 4543 r_dcache_cc_word = r_cc_receive_word_idx.read(); 4544 // just pop the fifo , don't write in icache 4545 r_dcache_cc_need_write = false; 4546 } 4547 else // No response needed 4548 { 4549 r_cc_receive_dcache_req = false; 4550 r_dcache_fsm = r_dcache_fsm_cc_save.read(); 4551 } 4552 } 4685 r_dcache_fsm = DCACHE_CC_UPDT; 4686 r_dcache_cc_word = r_cc_receive_word_idx.read(); 4687 } 4688 else if ( r_cc_receive_dcache_type.read() == CC_TYPE_INVAL ) // hit inval 4689 { 4690 r_dcache_fsm = DCACHE_CC_INVAL; 4691 } 4692 } 4693 else // miss 4694 { 4695 // multicast acknowledgement required in case of update 4696 if(r_cc_receive_dcache_type.read() == CC_TYPE_UPDT) 4697 { 4698 r_dcache_fsm = DCACHE_CC_UPDT; 4699 r_dcache_cc_word = r_cc_receive_word_idx.read(); 4700 4701 // just pop the fifo , don't write in icache 4702 r_dcache_cc_need_write = false; 4703 } 4704 else // No response needed 4705 { 4706 r_cc_receive_dcache_req = false; 4707 r_dcache_fsm = r_dcache_fsm_cc_save.read(); 4708 } 4709 } 4553 4710 4554 4711 #if DEBUG_DCACHE … … 4562 4719 } 4563 4720 #endif 4564 } 4721 4565 4722 break; 4566 4723 } 4567 4724 ///////////////////// 4568 case DCACHE_CC_INVAL: // hit inval: switch slot to EMPTY state, 4569 // after possible invalidation of copies in TLBs 4570 { 4571 size_t way = r_dcache_cc_way.read(); 4572 size_t set = r_dcache_cc_set.read(); 4573 4574 if (r_dcache_cc_need_write.read()) 4575 { 4576 if ( r_dcache_in_tlb[way*m_dcache_sets+set] ) // selective TLB inval 4577 { 4578 r_dcache_in_tlb[way*m_dcache_sets+set] = false; 4579 r_dcache_tlb_inval_line = r_cc_receive_dcache_nline.read(); 4580 r_dcache_tlb_inval_set = 0; 4581 r_dcache_fsm_scan_save = r_dcache_fsm.read(); 4582 r_dcache_fsm = DCACHE_INVAL_TLB_SCAN; 4583 break; 4584 } 4585 else 4586 { 4587 if ( r_dcache_contains_ptd[way*m_dcache_sets+set] ) // TLB flush 4588 { 4589 r_itlb.reset(); 4590 r_dtlb.reset(); 4591 r_dcache_contains_ptd[way*m_dcache_sets+set] = false; 4725 case DCACHE_CC_INVAL: // hit inval: switch slot to ZOMBI state and send a 4726 // CLEANUP after possible invalidation of copies in 4727 // TLBs 4728 { 4729 size_t way = r_dcache_cc_way.read(); 4730 size_t set = r_dcache_cc_set.read(); 4731 4732 if ( r_dcache_in_tlb[way*m_dcache_sets+set] ) // selective TLB inval 4733 { 4734 r_dcache_in_tlb[way*m_dcache_sets+set] = false; 4735 r_dcache_tlb_inval_line = r_cc_receive_dcache_nline.read(); 4736 r_dcache_tlb_inval_set = 0; 4737 r_dcache_fsm_scan_save = r_dcache_fsm.read(); 4738 r_dcache_fsm = DCACHE_INVAL_TLB_SCAN; 4739 break; 4740 } 4741 4742 if ( r_dcache_contains_ptd[way*m_dcache_sets+set] ) // TLB flush 4743 { 4744 r_itlb.reset(); 4745 r_dtlb.reset(); 4746 r_dcache_contains_ptd[way*m_dcache_sets+set] = false; 4592 4747 4593 4748 #if DEBUG_DCACHE … … 4598 4753 } 4599 4754 #endif 4600 } 4601 4602 r_dcache.write_dir( 0, 4603 way, 4604 set, 4605 CACHE_SLOT_STATE_EMPTY ); 4606 4607 r_dcache_cc_need_write = false; 4755 } 4756 4757 assert (not r_dcache_cc_send_req.read() && 4758 "ERROR in DCACHE_CC_INVAL: the r_dcache_cc_send_req " 4759 "must not be set"); 4760 4761 // Switch slot state to ZOMBI and send CLEANUP command 4762 r_dcache.write_dir( 0, 4763 way, 4764 set, 4765 CACHE_SLOT_STATE_ZOMBI ); 4766 4767 // coherence request completed 4768 r_cc_receive_dcache_req = false; 4769 r_dcache_cc_send_req = true; 4770 r_dcache_cc_send_nline = r_cc_receive_dcache_nline.read(); 4771 r_dcache_cc_send_way = r_dcache_cc_way.read(); 4772 r_dcache_cc_send_type = CC_TYPE_CLEANUP; 4773 r_dcache_fsm = r_dcache_fsm_cc_save.read(); 4608 4774 4609 4775 #if DEBUG_DCACHE … … 4611 4777 { 4612 4778 std::cout << " <PROC " << name() 4613 4614 4615 4779 << " DCACHE_CC_INVAL> Switch slot to EMPTY state:" << std::dec 4780 << " / WAY = " << way 4781 << " / SET = " << set << std::endl; 4616 4782 } 4617 4783 #endif 4618 }4619 }4620 // multicast acknowledgement4621 // send a request to cc_send_fsm4622 if(not r_dcache_cc_send_req.read()) // cc_send is available4623 {4624 // coherence request completed4625 r_cc_receive_dcache_req = false;4626 // request multicast acknowledgement4627 r_dcache_cc_send_req = true;4628 r_dcache_cc_send_nline = r_cc_receive_dcache_nline.read();4629 r_dcache_cc_send_updt_tab_idx = r_cc_receive_dcache_updt_tab_idx.read();4630 r_dcache_cc_send_type = CC_TYPE_MULTI_ACK;4631 4632 r_dcache_fsm = r_dcache_fsm_cc_save.read();4633 }4634 //else wait for previous cc_send request to be sent4635 4784 break; 4636 4785 } 4637 4786 /////////////////// 4638 case DCACHE_CC_UPDT: 4787 case DCACHE_CC_UPDT: // hit update: write one word per cycle, 4639 4788 // after possible invalidation of copies in TLBs 4640 4789 { 4641 size_t word = r_dcache_cc_word.read(); 4642 size_t way = r_dcache_cc_way.read(); 4643 size_t set = r_dcache_cc_set.read(); 4644 4645 if (r_cc_receive_updt_fifo_be.rok()) 4646 { 4647 if (r_dcache_cc_need_write.read()) 4648 { 4649 if ( r_dcache_in_tlb[way*m_dcache_sets+set] ) // selective TLB inval 4650 { 4651 r_dcache_in_tlb[way*m_dcache_sets+set] = false; 4652 r_dcache_tlb_inval_line = r_cc_receive_dcache_nline.read(); 4653 r_dcache_tlb_inval_set = 0; 4654 r_dcache_fsm_scan_save = r_dcache_fsm.read(); 4655 r_dcache_fsm = DCACHE_INVAL_TLB_SCAN; 4656 break; 4657 } 4658 4659 if ( r_dcache_contains_ptd[way*m_dcache_sets+set] ) // TLB flush 4660 { 4661 r_itlb.reset(); 4662 r_dtlb.reset(); 4663 r_dcache_contains_ptd[way*m_dcache_sets+set] = false; 4790 size_t word = r_dcache_cc_word.read(); 4791 size_t way = r_dcache_cc_way.read(); 4792 size_t set = r_dcache_cc_set.read(); 4793 4794 if ( r_dcache_in_tlb[way*m_dcache_sets+set] ) // selective TLB inval 4795 { 4796 r_dcache_in_tlb[way*m_dcache_sets+set] = false; 4797 r_dcache_tlb_inval_line = r_cc_receive_dcache_nline.read(); 4798 r_dcache_tlb_inval_set = 0; 4799 r_dcache_fsm_scan_save = r_dcache_fsm.read(); 4800 r_dcache_fsm = DCACHE_INVAL_TLB_SCAN; 4801 4802 break; 4803 } 4804 4805 if ( r_dcache_contains_ptd[way*m_dcache_sets+set] ) // TLB flush 4806 { 4807 r_itlb.reset(); 4808 r_dtlb.reset(); 4809 r_dcache_contains_ptd[way*m_dcache_sets+set] = false; 4664 4810 4665 4811 #if DEBUG_DCACHE … … 4670 4816 } 4671 4817 #endif 4672 } 4673 4818 } 4819 4820 assert (not r_dcache_cc_send_req.read() && 4821 "ERROR in DCACHE_CC_INVAL: the r_dcache_cc_send_req " 4822 "must not be set"); 4823 4824 if ( not r_cc_receive_updt_fifo_be.rok() ) break; 4825 4826 if (r_dcache_cc_need_write.read()) 4827 { 4828 4674 4829 #ifdef INSTRUMENTATION 4675 4830 m_cpt_dcache_data_write++; 4676 4831 #endif 4677 4678 4679 4680 4681 4682 4683 4832 r_dcache.write( way, 4833 set, 4834 word, 4835 r_cc_receive_updt_fifo_data.read(), 4836 r_cc_receive_updt_fifo_be.read() ); 4837 4838 r_dcache_cc_word = word + 1; 4684 4839 4685 4840 #if DEBUG_DCACHE … … 4694 4849 } 4695 4850 #endif 4696 } 4697 4698 if ( r_cc_receive_updt_fifo_eop.read() ) // last word 4699 { 4700 // no need to write in the cache anymore 4701 r_dcache_cc_need_write = false; 4702 4703 // wait to send a request to cc_send_fsm 4704 if(not r_dcache_cc_send_req.read()) 4705 // cc_send is available 4706 { 4707 //consume last fifo flit if eop and request to cc_send possible 4708 cc_receive_updt_fifo_get = true; 4709 4710 // coherence request completed 4711 r_cc_receive_dcache_req = false; 4712 4713 // request multicast acknowledgement 4714 r_dcache_cc_send_req = true; 4715 r_dcache_cc_send_nline = r_cc_receive_dcache_nline.read(); 4716 r_dcache_cc_send_updt_tab_idx = r_cc_receive_dcache_updt_tab_idx.read(); 4717 r_dcache_cc_send_type = CC_TYPE_MULTI_ACK; 4718 4719 r_dcache_fsm = r_dcache_fsm_cc_save.read(); 4720 } 4721 } 4722 else 4723 { 4724 //consume fifo if not eop 4725 cc_receive_updt_fifo_get = true; 4726 } 4727 } 4728 break; 4729 } 4730 ///////////////////////// 4731 case DCACHE_CC_BROADCAST: // hit broadcast : switch state to ZOMBI state 4732 // and request a cleanup, after possible 4733 // invalidation of copies in TLBs 4734 { 4735 size_t way = r_dcache_cc_way.read(); 4736 size_t set = r_dcache_cc_set.read(); 4737 paddr_t nline = r_cc_receive_dcache_nline.read(); 4738 4739 if (r_dcache_cc_need_write.read()) 4740 { 4741 if ( r_dcache_in_tlb[way*m_dcache_sets+set] ) // selective TLB inval 4742 { 4743 r_dcache_in_tlb[way*m_dcache_sets+set] = false; 4744 r_dcache_tlb_inval_line = nline; 4745 r_dcache_tlb_inval_set = 0; 4746 r_dcache_fsm_scan_save = r_dcache_fsm.read(); 4747 r_dcache_fsm = DCACHE_INVAL_TLB_SCAN; 4748 break; 4749 } 4750 else 4751 { 4752 if ( r_dcache_contains_ptd[way*m_dcache_sets+set] ) // TLB flush 4753 { 4754 r_itlb.reset(); 4755 r_dtlb.reset(); 4756 r_dcache_contains_ptd[way*m_dcache_sets+set] = false; 4757 4758 #if DEBUG_DCACHE 4759 if ( m_debug_activated ) 4760 { 4761 std::cout << " <PROC " << name() 4762 << " DCACHE_CC_BROADCAST> Flush DTLB & ITLB" << std::endl; 4763 } 4764 #endif 4765 } 4766 4767 #ifdef INSTRUMENTATION 4768 m_cpt_dcache_dir_write++; 4769 #endif 4770 r_dcache.write_dir( way, 4771 set, 4772 CACHE_SLOT_STATE_ZOMBI ); 4773 4774 r_dcache_cc_need_write = false; 4775 #if DEBUG_DCACHE 4776 if ( m_debug_activated ) 4777 { 4778 std::cout << " <PROC " << name() 4779 << " DCACHE_CC_BROADCAST > Slot goes to ZOMBI state " 4780 << " SET = " << set 4781 << " / WAY = " << way << std::endl; 4782 } 4783 #endif 4784 } 4785 } 4786 // cleanup 4787 // send a request to cc_send_fsm 4788 if(not r_dcache_cc_send_req.read()) // cc_send is available 4789 { 4851 } 4852 4853 if ( r_cc_receive_updt_fifo_eop.read() ) // last word 4854 { 4855 // no need to write in the cache anymore 4856 r_dcache_cc_need_write = false; 4857 4790 4858 // coherence request completed 4791 4859 r_cc_receive_dcache_req = false; 4792 // request cleanup 4793 r_dcache_cc_send_req = true; 4794 r_dcache_cc_send_nline = r_cc_receive_dcache_nline.read(); 4795 r_dcache_cc_send_way = r_dcache_cc_way.read(); 4796 r_dcache_cc_send_type = CC_TYPE_CLEANUP; 4797 4798 r_dcache_fsm = r_dcache_fsm_cc_save.read(); 4799 } 4800 //else wait for previous cc_send request to be sent 4860 4861 // request multicast acknowledgement 4862 r_dcache_cc_send_req = true; 4863 r_dcache_cc_send_nline = r_cc_receive_dcache_nline.read(); 4864 r_dcache_cc_send_updt_tab_idx = r_cc_receive_dcache_updt_tab_idx.read(); 4865 r_dcache_cc_send_type = CC_TYPE_MULTI_ACK; 4866 4867 r_dcache_fsm = r_dcache_fsm_cc_save.read(); 4868 } 4869 4870 //consume fifo if not eop 4871 cc_receive_updt_fifo_get = true; 4872 4801 4873 break; 4802 4874 } … … 5389 5461 { 5390 5462 // wait for the first flit to be consumed 5391 if (p_dspin_ out.read.read())5463 if (p_dspin_p2m.read.read()) 5392 5464 r_cc_send_fsm = CC_SEND_CLEANUP_2; 5393 5465 … … 5398 5470 { 5399 5471 // wait for the second flit to be consumed 5400 if (p_dspin_ out.read.read())5472 if (p_dspin_p2m.read.read()) 5401 5473 { 5402 5474 if (r_cc_send_last_client.read() == 0) // dcache active request … … 5414 5486 { 5415 5487 // wait for the flit to be consumed 5416 if(p_dspin_ out.read.read())5488 if(p_dspin_p2m.read.read()) 5417 5489 { 5418 5490 if(r_cc_send_last_client.read() == 0) // dcache active request … … 5428 5500 5429 5501 /////////////////////////////////////////////////////////////////////////////// 5430 // 5502 // CC_RECEIVE FSM 5431 5503 // This FSM receive all coherence packets on a DSPIN40 port. 5432 // There is 7packet types:5504 // There is 5 packet types: 5433 5505 // - CC_DATA_INVAL : DCACHE invalidate request 5434 5506 // - CC_DATA_UPDT : DCACHE update request (multi-words) … … 5436 5508 // - CC_INST_UPDT : ICACHE update request (multi-words) 5437 5509 // - CC_BROADCAST : Broadcast invalidate request (both DCACHE & ICACHE) 5438 // - CC_DATA_CLACK : DCACHE cleanup acknowledge5439 // - CC_INST_CLACK : ICACHE cleanup acknowledge5440 5510 ////////////////////////////////////////////////////////////////////////////// 5441 5511 switch( r_cc_receive_fsm.read() ) … … 5445 5515 { 5446 5516 // a coherence request has arrived 5447 if (p_dspin_ in.write.read())5517 if (p_dspin_m2p.write.read()) 5448 5518 { 5449 5519 // initialize dspin received data 5450 uint64_t receive_data = p_dspin_ in.data.read();5520 uint64_t receive_data = p_dspin_m2p.data.read(); 5451 5521 // initialize coherence packet type 5452 5522 uint64_t receive_type = DspinDhccpParam::dspin_get(receive_data, 5453 DspinDhccpParam::FROM_MC_TYPE); 5454 // initialize data/ins flip_flop (0 data / 1 ins) 5455 r_cc_receive_data_ins = (bool)(receive_type & 0x1); 5523 DspinDhccpParam::M2P_TYPE); 5456 5524 // test for a broadcast 5457 if (DspinDhccpParam::dspin_get(receive_data,DspinDhccpParam:: FROM_MC_BC))5525 if (DspinDhccpParam::dspin_get(receive_data,DspinDhccpParam::M2P_BC)) 5458 5526 { 5459 5527 r_cc_receive_fsm = CC_RECEIVE_BRDCAST_HEADER; 5460 5528 } 5461 // test for a CLACK 5462 else if ((receive_type == DspinDhccpParam::TYPE_CLEANUP_ACK_DATA) or 5463 (receive_type == DspinDhccpParam::TYPE_CLEANUP_ACK_INST)) 5529 // test for a multi updt 5530 else if (receive_type == DspinDhccpParam::TYPE_MULTI_UPDT_DATA) 5464 5531 { 5465 r_cc_receive_fsm = CC_RECEIVE_ CLACK;5532 r_cc_receive_fsm = CC_RECEIVE_DATA_UPDT_HEADER; 5466 5533 } 5467 // test for a multi updt 5468 else if ((receive_type == DspinDhccpParam::TYPE_MULTI_UPDT_DATA) or 5469 (receive_type == DspinDhccpParam::TYPE_MULTI_UPDT_INST)) 5534 else if (receive_type == DspinDhccpParam::TYPE_MULTI_UPDT_INST) 5470 5535 { 5471 r_cc_receive_fsm = CC_RECEIVE_ UPDT_HEADER;5536 r_cc_receive_fsm = CC_RECEIVE_INS_UPDT_HEADER; 5472 5537 } 5473 5538 // test for a multi inval 5539 else if (receive_type == DspinDhccpParam::TYPE_MULTI_INVAL_DATA) 5540 { 5541 r_cc_receive_fsm = CC_RECEIVE_DATA_INVAL_HEADER; 5542 } 5474 5543 else 5475 5544 { 5476 r_cc_receive_fsm = CC_RECEIVE_IN VAL_HEADER;5545 r_cc_receive_fsm = CC_RECEIVE_INS_INVAL_HEADER; 5477 5546 } 5478 5547 } 5479 break;5480 }5481 //////////////////////5482 case CC_RECEIVE_CLACK:5483 {5484 // initialize dspin received data5485 uint64_t receive_data = p_dspin_in.data.read();5486 5487 // for data CLACK, wait for dcache to take the request5488 if ((r_cc_receive_data_ins.read() == 0) and5489 not (r_cc_receive_dcache_req.read()))5490 {5491 // request dcache to handle the CLACK5492 r_cc_receive_dcache_req = true;5493 r_cc_receive_dcache_set = DspinDhccpParam::dspin_get(receive_data,5494 DspinDhccpParam::CLEANUP_ACK_SET) &5495 ((1ULL<<(uint32_log2(m_dcache_sets)))-1);5496 r_cc_receive_dcache_way = DspinDhccpParam::dspin_get(receive_data,5497 DspinDhccpParam::CLEANUP_ACK_WAY) &5498 ((1ULL<<(uint32_log2(m_dcache_ways)))-1);5499 r_cc_receive_dcache_type = CC_TYPE_CLACK;5500 // get back to idle state5501 r_cc_receive_fsm = CC_RECEIVE_IDLE;5502 break;5503 }5504 // for ins CLACK, wait for icache to take the request5505 if ((r_cc_receive_data_ins.read() == 1) and5506 not (r_cc_receive_icache_req.read()))5507 {5508 // request icache to handle the CLACK5509 r_cc_receive_icache_req = true;5510 r_cc_receive_icache_set = DspinDhccpParam::dspin_get(receive_data,5511 DspinDhccpParam::CLEANUP_ACK_SET) &5512 ((1ULL<<(uint32_log2(m_icache_sets)))-1);5513 r_cc_receive_icache_way = DspinDhccpParam::dspin_get(receive_data,5514 DspinDhccpParam::CLEANUP_ACK_WAY) &5515 ((1ULL<<(uint32_log2(m_icache_ways)))-1);5516 r_cc_receive_icache_type = CC_TYPE_CLACK;5517 // get back to idle state5518 r_cc_receive_fsm = CC_RECEIVE_IDLE;5519 break;5520 }5521 // keep waiting for the correct cache to accept the request5522 5548 break; 5523 5549 } … … 5533 5559 { 5534 5560 // initialize dspin received data 5535 uint64_t receive_data = p_dspin_ in.data.read();5561 uint64_t receive_data = p_dspin_m2p.data.read(); 5536 5562 // wait for both dcache and icache to take the request 5537 5563 // TODO maybe we need to wait for both only to leave the state, but … … 5540 5566 if (not (r_cc_receive_icache_req.read()) and 5541 5567 not (r_cc_receive_dcache_req.read()) and 5542 (p_dspin_ in.write.read()))5568 (p_dspin_m2p.write.read())) 5543 5569 { 5544 5570 // request dcache to handle the BROADCAST 5545 r_cc_receive_dcache_req 5571 r_cc_receive_dcache_req = true; 5546 5572 r_cc_receive_dcache_nline = DspinDhccpParam::dspin_get(receive_data, 5547 5573 DspinDhccpParam::BROADCAST_NLINE); 5548 r_cc_receive_dcache_type = CC_TYPE_ BRDCAST;5574 r_cc_receive_dcache_type = CC_TYPE_INVAL; 5549 5575 // request icache to handle the BROADCAST 5550 r_cc_receive_icache_req 5576 r_cc_receive_icache_req = true; 5551 5577 r_cc_receive_icache_nline = DspinDhccpParam::dspin_get(receive_data, 5552 5578 DspinDhccpParam::BROADCAST_NLINE); 5553 r_cc_receive_icache_type = CC_TYPE_ BRDCAST;5579 r_cc_receive_icache_type = CC_TYPE_INVAL; 5554 5580 // get back to idle state 5555 5581 r_cc_receive_fsm = CC_RECEIVE_IDLE; … … 5560 5586 } 5561 5587 ///////////////////////////// 5562 case CC_RECEIVE_ INVAL_HEADER:5588 case CC_RECEIVE_DATA_INVAL_HEADER: 5563 5589 { 5564 5590 // sample updt tab index in the HEADER, then skip to second flit 5565 uint64_t receive_data = p_dspin_in.data.read(); 5591 r_cc_receive_fsm = CC_RECEIVE_DATA_INVAL_NLINE; 5592 break; 5593 } 5594 ///////////////////////////// 5595 case CC_RECEIVE_INS_INVAL_HEADER: 5596 { 5597 // sample updt tab index in the HEADER, then skip to second flit 5598 r_cc_receive_fsm = CC_RECEIVE_INS_INVAL_NLINE; 5599 break; 5600 } 5601 //////////////////////////// 5602 case CC_RECEIVE_DATA_INVAL_NLINE: 5603 { 5604 // sample nline in the second flit 5605 uint64_t receive_data = p_dspin_m2p.data.read(); 5566 5606 // for data INVAL, wait for dcache to take the request 5567 if ((r_cc_receive_data_ins.read() == 0) and 5568 not (r_cc_receive_dcache_req.read())) 5569 { 5570 r_cc_receive_dcache_updt_tab_idx = DspinDhccpParam::dspin_get(receive_data, 5571 DspinDhccpParam::MULTI_INVAL_UPDT_INDEX); 5572 r_cc_receive_fsm = CC_RECEIVE_INVAL_NLINE; 5573 break; 5574 } 5575 // for ins INVAL, wait for icache to take the request 5576 if ((r_cc_receive_data_ins.read() == 1) and 5577 not (r_cc_receive_icache_req.read())) 5578 { 5579 r_cc_receive_icache_updt_tab_idx = DspinDhccpParam::dspin_get(receive_data, 5580 DspinDhccpParam::MULTI_INVAL_UPDT_INDEX); 5581 r_cc_receive_fsm = CC_RECEIVE_INVAL_NLINE; 5582 break; 5583 } 5584 // keep waiting for the correct cache to accept the request 5585 break; 5586 } 5587 //////////////////////////// 5588 case CC_RECEIVE_INVAL_NLINE: 5589 { 5590 // sample nline in the second flit 5591 uint64_t receive_data = p_dspin_in.data.read(); 5592 // for data INVAL, wait for dcache to take the request 5593 if ( (r_cc_receive_data_ins.read() == 0) and 5594 not (r_cc_receive_dcache_req.read()) and 5595 (p_dspin_in.write.read()) ) 5607 if (p_dspin_m2p.write.read() and not r_cc_receive_dcache_req.read()) 5596 5608 { 5597 5609 // request dcache to handle the INVAL 5598 r_cc_receive_dcache_req 5599 r_cc_receive_dcache_nline 5610 r_cc_receive_dcache_req = true; 5611 r_cc_receive_dcache_nline = DspinDhccpParam::dspin_get(receive_data,DspinDhccpParam::MULTI_INVAL_NLINE); 5600 5612 r_cc_receive_dcache_type = CC_TYPE_INVAL; 5601 5613 // get back to idle state … … 5603 5615 break; 5604 5616 } 5617 break; 5618 } 5619 ////////////////////////////// 5620 case CC_RECEIVE_INS_INVAL_NLINE: 5621 { 5622 // sample nline in the second flit 5623 uint64_t receive_data = p_dspin_m2p.data.read(); 5605 5624 // for ins INVAL, wait for icache to take the request 5606 if ( (r_cc_receive_data_ins.read() == 1) and not (r_cc_receive_icache_req.read()) and (p_dspin_in.write.read()))5625 if (p_dspin_m2p.write.read() and not r_cc_receive_icache_req.read()) 5607 5626 { 5608 5627 // request icache to handle the INVAL 5609 r_cc_receive_icache_req 5610 r_cc_receive_icache_nline 5628 r_cc_receive_icache_req = true; 5629 r_cc_receive_icache_nline = DspinDhccpParam::dspin_get(receive_data,DspinDhccpParam::MULTI_INVAL_NLINE); 5611 5630 r_cc_receive_icache_type = CC_TYPE_INVAL; 5612 5631 // get back to idle state … … 5614 5633 break; 5615 5634 } 5616 // we should never get there 5617 assert ( false && "ERROR in CC_VCACHE : CC_RECEIVE_INVAL_NLINE\n"); 5635 break; 5618 5636 } 5619 5637 //////////////////////////// 5620 case CC_RECEIVE_ UPDT_HEADER:5638 case CC_RECEIVE_DATA_UPDT_HEADER: 5621 5639 { 5622 5640 // sample updt tab index in the HEADER, than skip to second flit 5623 uint64_t receive_data = p_dspin_ in.data.read();5641 uint64_t receive_data = p_dspin_m2p.data.read(); 5624 5642 // for data INVAL, wait for dcache to take the request and fifo to 5625 5643 // be empty 5626 if ( (r_cc_receive_data_ins.read() == 0) and not r_cc_receive_dcache_req.read() and r_cc_receive_updt_fifo_be.empty())5644 if (not r_cc_receive_dcache_req.read()) 5627 5645 { 5628 5646 r_cc_receive_dcache_updt_tab_idx = DspinDhccpParam::dspin_get(receive_data,DspinDhccpParam::MULTI_UPDT_UPDT_INDEX); 5629 r_cc_receive_fsm = CC_RECEIVE_ UPDT_NLINE;5647 r_cc_receive_fsm = CC_RECEIVE_DATA_UPDT_NLINE; 5630 5648 break; 5631 5649 } 5650 break; 5651 } 5652 //////////////////////////// 5653 case CC_RECEIVE_INS_UPDT_HEADER: 5654 { 5655 // sample updt tab index in the HEADER, than skip to second flit 5656 uint64_t receive_data = p_dspin_m2p.data.read(); 5632 5657 // for ins INVAL, wait for icache to take the request and fifo to be 5633 5658 // empty 5634 if ( (r_cc_receive_data_ins.read() == 1) and not r_cc_receive_icache_req.read() and r_cc_receive_updt_fifo_be.empty())5659 if (not r_cc_receive_icache_req.read()) 5635 5660 { 5636 5661 r_cc_receive_icache_updt_tab_idx = DspinDhccpParam::dspin_get(receive_data,DspinDhccpParam::MULTI_UPDT_UPDT_INDEX); 5637 r_cc_receive_fsm = CC_RECEIVE_ UPDT_NLINE;5662 r_cc_receive_fsm = CC_RECEIVE_INS_UPDT_NLINE; 5638 5663 break; 5639 5664 } … … 5642 5667 } 5643 5668 /////////////////////////// 5644 case CC_RECEIVE_ UPDT_NLINE:5669 case CC_RECEIVE_DATA_UPDT_NLINE: 5645 5670 { 5646 5671 // sample nline and word index in the second flit 5647 uint64_t receive_data = p_dspin_ in.data.read();5672 uint64_t receive_data = p_dspin_m2p.data.read(); 5648 5673 // for data INVAL, wait for dcache to take the request and fifo to 5649 5674 // be empty 5650 if ( (r_cc_receive_data_ins.read() == 0) and 5651 not (r_cc_receive_dcache_req.read()) and 5652 r_cc_receive_updt_fifo_be.empty() and 5653 (p_dspin_in.write.read()) ) 5654 { 5675 if ( r_cc_receive_updt_fifo_be.empty() and 5676 p_dspin_m2p.write.read() ) 5677 { 5678 r_cc_receive_dcache_req = true; 5655 5679 r_cc_receive_dcache_nline = DspinDhccpParam::dspin_get(receive_data,DspinDhccpParam::MULTI_UPDT_NLINE); 5656 5680 r_cc_receive_word_idx = DspinDhccpParam::dspin_get(receive_data,DspinDhccpParam::MULTI_UPDT_WORD_INDEX); 5657 5681 r_cc_receive_dcache_type = CC_TYPE_UPDT; 5658 5682 // get back to idle state 5659 r_cc_receive_fsm = CC_RECEIVE_ UPDT_DATA;5683 r_cc_receive_fsm = CC_RECEIVE_DATA_UPDT_DATA; 5660 5684 break; 5661 5685 } 5686 break; 5687 } 5688 //////////////////////////// 5689 case CC_RECEIVE_INS_UPDT_NLINE: 5690 { 5691 // sample nline and word index in the second flit 5692 uint64_t receive_data = p_dspin_m2p.data.read(); 5662 5693 // for ins INVAL, wait for icache to take the request and fifo to be 5663 5694 // empty 5664 if ( (r_cc_receive_data_ins.read() == 1) and 5665 not (r_cc_receive_icache_req.read()) and 5666 r_cc_receive_updt_fifo_be.empty() and 5667 (p_dspin_in.write.read())) 5668 { 5695 if ( r_cc_receive_updt_fifo_be.empty() and 5696 p_dspin_m2p.write.read() ) 5697 { 5698 r_cc_receive_icache_req = true; 5669 5699 r_cc_receive_icache_nline = DspinDhccpParam::dspin_get(receive_data,DspinDhccpParam::MULTI_UPDT_NLINE); 5670 5700 r_cc_receive_word_idx = DspinDhccpParam::dspin_get(receive_data,DspinDhccpParam::MULTI_UPDT_WORD_INDEX); 5671 5701 r_cc_receive_icache_type = CC_TYPE_UPDT; 5672 5702 // get back to idle state 5673 r_cc_receive_fsm = CC_RECEIVE_ UPDT_DATA;5703 r_cc_receive_fsm = CC_RECEIVE_INS_UPDT_DATA; 5674 5704 break; 5675 5705 } 5676 // we should never get there5677 assert ( false && "ERROR in CC_VCACHE : CC_RECEIVE_UPDT_NLINE \n");5678 5706 break; 5679 5707 } 5680 5708 ////////////////////////// 5681 case CC_RECEIVE_UPDT_DATA: 5682 { 5683 if ((r_cc_receive_data_ins.read() == 0) and not (r_cc_receive_dcache_req.read()) and (p_dspin_in.write.read())) 5684 r_cc_receive_dcache_req = true; 5685 if ((r_cc_receive_data_ins.read() == 1) and not (r_cc_receive_icache_req.read()) and (p_dspin_in.write.read())) 5686 r_cc_receive_icache_req = true; 5687 5709 case CC_RECEIVE_DATA_UPDT_DATA: 5710 { 5688 5711 // wait for the fifo 5689 if (r_cc_receive_updt_fifo_be.wok() and (p_dspin_ in.write.read()))5690 { 5691 uint64_t receive_data = p_dspin_ in.data.read();5692 bool receive_eop = p_dspin_ in.eop.read();5712 if (r_cc_receive_updt_fifo_be.wok() and (p_dspin_m2p.write.read())) 5713 { 5714 uint64_t receive_data = p_dspin_m2p.data.read(); 5715 bool receive_eop = p_dspin_m2p.eop.read(); 5693 5716 cc_receive_updt_fifo_be = DspinDhccpParam::dspin_get(receive_data,DspinDhccpParam::MULTI_UPDT_BE); 5694 5717 cc_receive_updt_fifo_data = DspinDhccpParam::dspin_get(receive_data,DspinDhccpParam::MULTI_UPDT_DATA); … … 5699 5722 break; 5700 5723 } 5724 ////////////////////////// 5725 case CC_RECEIVE_INS_UPDT_DATA: 5726 { 5727 // wait for the fifo 5728 if (r_cc_receive_updt_fifo_be.wok() and (p_dspin_m2p.write.read())) 5729 { 5730 uint64_t receive_data = p_dspin_m2p.data.read(); 5731 bool receive_eop = p_dspin_m2p.eop.read(); 5732 cc_receive_updt_fifo_be = DspinDhccpParam::dspin_get(receive_data,DspinDhccpParam::MULTI_UPDT_BE); 5733 cc_receive_updt_fifo_data = DspinDhccpParam::dspin_get(receive_data,DspinDhccpParam::MULTI_UPDT_DATA); 5734 cc_receive_updt_fifo_eop = receive_eop; 5735 cc_receive_updt_fifo_put = true; 5736 if ( receive_eop ) r_cc_receive_fsm = CC_RECEIVE_IDLE; 5737 } 5738 break; 5739 } 5740 5701 5741 } // end switch CC_RECEIVE FSM 5742 5743 ///////////////// DSPIN CLACK interface /////////////// 5744 5745 uint64_t clack_type = DspinDhccpParam::dspin_get(r_dspin_clack_flit.read(), 5746 DspinDhccpParam::CLACK_TYPE); 5747 5748 size_t clack_way = DspinDhccpParam::dspin_get(r_dspin_clack_flit.read(), 5749 DspinDhccpParam::CLACK_WAY); 5750 5751 size_t clack_set = DspinDhccpParam::dspin_get(r_dspin_clack_flit.read(), 5752 DspinDhccpParam::CLACK_SET); 5753 5754 bool dspin_clack_get = false; 5755 bool dcache_clack_request = (clack_type == DspinDhccpParam::TYPE_CLACK_DATA); 5756 bool icache_clack_request = (clack_type == DspinDhccpParam::TYPE_CLACK_INST); 5757 5758 if (r_dspin_clack_req.read()) 5759 { 5760 // CLACK DATA: Send request to DCACHE FSM 5761 if (dcache_clack_request and not r_dcache_clack_req.read()){ 5762 r_dcache_clack_req = true; 5763 r_dcache_clack_way = clack_way & ((1ULL<<(uint32_log2(m_dcache_ways)))-1); 5764 r_dcache_clack_set = clack_set & ((1ULL<<(uint32_log2(m_dcache_sets)))-1); 5765 dspin_clack_get = true; 5766 } 5767 5768 // CLACK INST: Send request to ICACHE FSM 5769 else if (icache_clack_request and not r_icache_clack_req.read()){ 5770 r_icache_clack_req = true; 5771 r_icache_clack_way = clack_way & ((1ULL<<(uint32_log2(m_dcache_ways)))-1); 5772 r_icache_clack_set = clack_set & ((1ULL<<(uint32_log2(m_icache_sets)))-1); 5773 dspin_clack_get = true; 5774 } 5775 } 5776 else 5777 { 5778 dspin_clack_get = true; 5779 } 5780 5781 if (dspin_clack_get) 5782 { 5783 r_dspin_clack_req = p_dspin_clack.write.read(); 5784 r_dspin_clack_flit = p_dspin_clack.data.read(); 5785 } 5702 5786 5703 5787 ///////////////// Response FIFOs update ////////////////////// … … 5897 5981 case CC_SEND_IDLE: 5898 5982 { 5899 p_dspin_ out.write = false;5983 p_dspin_p2m.write = false; 5900 5984 break; 5901 5985 } … … 5906 5990 // DspinDhccpParam::dspin_set(dspin_send_data, 5907 5991 // 0, 5908 // DspinDhccpParam:: FROM_L1_EOP);5992 // DspinDhccpParam::P2M_EOP); 5909 5993 DspinDhccpParam::dspin_set(dspin_send_data, 5910 5994 m_cc_global_id, … … 5912 5996 DspinDhccpParam::dspin_set(dspin_send_data, 5913 5997 0, 5914 DspinDhccpParam:: FROM_L1_BC);5998 DspinDhccpParam::P2M_BC); 5915 5999 5916 6000 if(r_cc_send_last_client.read() == 0) // dcache active request … … 5934 6018 DspinDhccpParam::dspin_set(dspin_send_data, 5935 6019 DspinDhccpParam::TYPE_CLEANUP_DATA, 5936 DspinDhccpParam:: FROM_L1_TYPE);6020 DspinDhccpParam::P2M_TYPE); 5937 6021 } 5938 6022 else // icache active request … … 5956 6040 DspinDhccpParam::dspin_set(dspin_send_data, 5957 6041 DspinDhccpParam::TYPE_CLEANUP_INST, 5958 DspinDhccpParam:: FROM_L1_TYPE);6042 DspinDhccpParam::P2M_TYPE); 5959 6043 } 5960 6044 // send flit 5961 p_dspin_ out.data = dspin_send_data;5962 p_dspin_ out.write = true;5963 p_dspin_ out.eop = false;6045 p_dspin_p2m.data = dspin_send_data; 6046 p_dspin_p2m.write = true; 6047 p_dspin_p2m.eop = false; 5964 6048 break; 5965 6049 } … … 5970 6054 // DspinDhccpParam::dspin_set(dspin_send_data, 5971 6055 // 1, 5972 // DspinDhccpParam:: FROM_L1_EOP);6056 // DspinDhccpParam::P2M_EOP); 5973 6057 5974 6058 if(r_cc_send_last_client.read() == 0) // dcache active request … … 5985 6069 } 5986 6070 // send flit 5987 p_dspin_ out.data = dspin_send_data;5988 p_dspin_ out.write = true;5989 p_dspin_ out.eop = true;6071 p_dspin_p2m.data = dspin_send_data; 6072 p_dspin_p2m.write = true; 6073 p_dspin_p2m.eop = true; 5990 6074 break; 5991 6075 } … … 5996 6080 // DspinDhccpParam::dspin_set(dspin_send_data, 5997 6081 // 1, 5998 // DspinDhccpParam:: FROM_L1_EOP);6082 // DspinDhccpParam::P2M_EOP); 5999 6083 DspinDhccpParam::dspin_set(dspin_send_data, 6000 6084 0, 6001 DspinDhccpParam:: FROM_L1_BC);6085 DspinDhccpParam::P2M_BC); 6002 6086 DspinDhccpParam::dspin_set(dspin_send_data, 6003 6087 DspinDhccpParam::TYPE_MULTI_ACK, 6004 DspinDhccpParam:: FROM_L1_TYPE);6088 DspinDhccpParam::P2M_TYPE); 6005 6089 6006 6090 if(r_cc_send_last_client.read() == 0) // dcache active request … … 6034 6118 } 6035 6119 // send flit 6036 p_dspin_ out.data = dspin_send_data;6037 p_dspin_ out.write = true;6038 p_dspin_ out.eop = true;6120 p_dspin_p2m.data = dspin_send_data; 6121 p_dspin_p2m.write = true; 6122 p_dspin_p2m.eop = true; 6039 6123 6040 6124 break; … … 6044 6128 // Receive coherence packets 6045 6129 // It depends on the CC_RECEIVE FSM 6046 6047 6130 switch( r_cc_receive_fsm.read() ) 6048 6131 { … … 6050 6133 case CC_RECEIVE_IDLE: 6051 6134 { 6052 p_dspin_in.read = false; 6053 break; 6054 } 6055 ////////////////////// 6056 case CC_RECEIVE_CLACK: 6057 { 6058 if (((r_cc_receive_data_ins.read() == 0) and not (r_cc_receive_dcache_req.read())) or 6059 ((r_cc_receive_data_ins.read() == 1) and not (r_cc_receive_icache_req.read()))) 6060 p_dspin_in.read = true; 6061 else 6062 p_dspin_in.read = false; 6135 p_dspin_m2p.read = false; 6063 6136 break; 6064 6137 } … … 6066 6139 case CC_RECEIVE_BRDCAST_HEADER: 6067 6140 { 6068 p_dspin_ in.read = true;6141 p_dspin_m2p.read = true; 6069 6142 break; 6070 6143 } … … 6076 6149 // flip_flop to check that ? 6077 6150 if (not (r_cc_receive_icache_req.read()) and not (r_cc_receive_dcache_req.read())) 6078 p_dspin_ in.read = true;6151 p_dspin_m2p.read = true; 6079 6152 else 6080 p_dspin_ in.read = false;6153 p_dspin_m2p.read = false; 6081 6154 break; 6082 6155 } 6083 6156 ///////////////////////////// 6084 case CC_RECEIVE_INVAL_HEADER: 6085 { 6086 if (((r_cc_receive_data_ins.read() == 0) and not (r_cc_receive_dcache_req.read())) or 6087 ((r_cc_receive_data_ins.read() == 1) and not (r_cc_receive_icache_req.read()))) 6088 p_dspin_in.read = true; 6157 case CC_RECEIVE_DATA_INVAL_HEADER: 6158 case CC_RECEIVE_INS_INVAL_HEADER: 6159 { 6160 p_dspin_m2p.read = true; 6161 break; 6162 } 6163 //////////////////////////// 6164 case CC_RECEIVE_DATA_INVAL_NLINE: 6165 { 6166 p_dspin_m2p.read = not r_cc_receive_dcache_req.read(); 6167 break; 6168 } 6169 case CC_RECEIVE_INS_INVAL_NLINE: 6170 { 6171 p_dspin_m2p.read = not r_cc_receive_icache_req.read(); 6172 break; 6173 } 6174 /////////////////////////// 6175 case CC_RECEIVE_DATA_UPDT_HEADER: 6176 { 6177 if (not r_cc_receive_dcache_req.read()) 6178 p_dspin_m2p.read = true; 6089 6179 else 6090 p_dspin_ in.read = false;6180 p_dspin_m2p.read = false; 6091 6181 break; 6092 6182 } 6093 6183 //////////////////////////// 6094 case CC_RECEIVE_INVAL_NLINE: 6095 { 6096 p_dspin_in.read = true; 6097 break; 6098 } 6099 //////////////////////////// 6100 case CC_RECEIVE_UPDT_HEADER: 6101 { 6102 if (((r_cc_receive_data_ins.read() == 0) and 6103 not r_cc_receive_dcache_req.read() and 6104 r_cc_receive_updt_fifo_be.empty()) 6105 or 6106 (((r_cc_receive_data_ins.read() == 1) and 6107 not r_cc_receive_icache_req.read()) and 6108 r_cc_receive_updt_fifo_be.empty())) 6109 p_dspin_in.read = true; 6184 case CC_RECEIVE_INS_UPDT_HEADER: 6185 { 6186 if ( not r_cc_receive_icache_req.read()) 6187 p_dspin_m2p.read = true; 6110 6188 else 6111 p_dspin_ in.read = false;6189 p_dspin_m2p.read = false; 6112 6190 break; 6113 6191 } 6114 6192 /////////////////////////// 6115 case CC_RECEIVE_UPDT_NLINE: 6116 { 6117 if (((r_cc_receive_data_ins.read() == 0) and 6118 not (r_cc_receive_dcache_req.read()) and 6119 r_cc_receive_updt_fifo_be.empty()) 6120 or 6121 ((r_cc_receive_data_ins.read() == 1) and 6122 not (r_cc_receive_icache_req.read()) and 6123 r_cc_receive_updt_fifo_be.empty())) 6124 p_dspin_in.read = true; 6193 case CC_RECEIVE_DATA_UPDT_NLINE: 6194 case CC_RECEIVE_INS_UPDT_NLINE: 6195 { 6196 if(r_cc_receive_updt_fifo_be.empty()) 6197 p_dspin_m2p.read = true; 6125 6198 else 6126 p_dspin_in.read = false; 6127 break; 6128 } 6129 ////////////////////////// 6130 case CC_RECEIVE_UPDT_DATA: 6199 p_dspin_m2p.read = false; 6200 break; 6201 } 6202 /////////////////////////// 6203 case CC_RECEIVE_DATA_UPDT_DATA: 6204 case CC_RECEIVE_INS_UPDT_DATA: 6131 6205 { 6132 6206 if (r_cc_receive_updt_fifo_be.wok()) 6133 p_dspin_ in.read = true;6207 p_dspin_m2p.read = true; 6134 6208 else 6135 p_dspin_ in.read = false;6209 p_dspin_m2p.read = false; 6136 6210 break; 6137 6211 } 6138 6212 } // end switch CC_RECEIVE FSM 6139 6213 6214 6215 int clack_type = DspinDhccpParam::dspin_get(r_dspin_clack_flit.read(), 6216 DspinDhccpParam::CLACK_TYPE); 6217 6218 bool dspin_clack_get = false; 6219 bool dcache_clack_request = (clack_type == DspinDhccpParam::TYPE_CLACK_DATA); 6220 bool icache_clack_request = (clack_type == DspinDhccpParam::TYPE_CLACK_INST); 6221 6222 if (r_dspin_clack_req.read()) 6223 { 6224 // CLACK DATA: wait if pending request to DCACHE FSM 6225 if (dcache_clack_request and not r_dcache_clack_req.read()) 6226 { 6227 dspin_clack_get = true; 6228 } 6229 6230 // CLACK INST: wait if pending request to ICACHE FSM 6231 else if (icache_clack_request and not r_icache_clack_req.read()) 6232 { 6233 dspin_clack_get = true; 6234 } 6235 } 6236 else 6237 { 6238 dspin_clack_get = true; 6239 } 6240 6241 p_dspin_clack.read = dspin_clack_get; 6140 6242 } // end genMoore 6141 6243
Note: See TracChangeset
for help on using the changeset viewer.