Changeset 582 for trunk


Ignore:
Timestamp:
Dec 3, 2013, 10:28:34 PM (11 years ago)
Author:
alain
Message:

Bug fix in config FSM : concurrent access to r_config_rsplines counter...

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/modules/vci_mem_cache/caba/source/src/vci_mem_cache.cpp

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