示例#1
0
文件: Cache.cpp 项目: 6366295/mgsim
// Called from the processor on a memory write (can be any size with write-through/around)
// Just queues the request.
bool CDMA::Cache::Write(MCID id, MemAddr address, const MemData& data, WClientID wid)
{
    assert(address % m_lineSize == 0);

    // We need to arbitrate between the different processes on the cache,
    // and then between the different clients. There are 2 arbitrators for this.
    if (!p_bus.Invoke())
    {
        // Arbitration failed
        DeadlockWrite("Unable to acquire bus for write");
        return false;
    }

    Request req;
    req.address = address;
    req.write   = true;
    req.client  = id;
    req.wid     = wid;
    COMMIT{
    std::copy(data.data, data.data + m_lineSize, req.mdata.data);
    std::copy(data.mask, data.mask + m_lineSize, req.mdata.mask);
    }

    // Client should have been registered
    assert(m_clients[req.client] != NULL);

    if (!m_requests.Push(req))
    {
        // Buffer was full
        DeadlockWrite("Unable to push write request into buffer");
        return false;
    }

    // Snoop the write back to the other clients
    for (size_t i = 0; i < m_clients.size(); ++i)
    {
        IMemoryCallback* client = m_clients[i];
        if (client != NULL && i != req.client)
        {
            if (!client->OnMemorySnooped(req.address, req.mdata.data, req.mdata.mask))
            {
                DeadlockWrite("Unable to snoop data to cache clients");
                return false;
            }
        }
    }

    return true;
}
示例#2
0
// Called from the processor on a memory write (can be any size with write-through/around)
// Just queues the request.
bool ZLCDMA::Cache::Write(MCID id, MemAddr address, const MemData& data, WClientID wid)
{

    // This method can get called by several 'listeners', so we need
    // to arbitrate and store the request in a buffer to handle it.
    if (!p_bus.Invoke())
    {
        // Arbitration failed
        DeadlockWrite("Unable to acquire bus for write");
        return false;
    }

    Request req;
    req.address = address;
    req.write   = true;
    req.client  = id;
    req.wid     = wid;
    COMMIT{
    std::copy(data.data, data.data + m_lineSize, req.mdata.data);
    std::copy(data.mask, data.mask + m_lineSize, req.mdata.mask);
    }

    // Client should have been registered
    assert(m_clients[req.client] != NULL);

    if (!m_requests.Push(req))
    {
        // Buffer was full
        DeadlockWrite("Unable to push write request into buffer");
        return false;
    }

    // Snoop the write back to the other clients
    for (size_t i = 0; i < m_clients.size(); ++i)
    {
        IMemoryCallback* client = m_clients[i];
        if (client != NULL && i != req.client)
        {
            if (!client->OnMemorySnooped(req.address, req.mdata.data, req.mdata.mask))
            {
                DeadlockWrite("Unable to snoop data to cache clients");
                return false;
            }
        }
    }

    return true;
}
示例#3
0
文件: COMA.cpp 项目: fuzzie/mgsim
MCID TwoLevelCOMA::RegisterClient(IMemoryCallback& callback, Process& process, StorageTraceSet& traces, Storage& storage, bool grouped)
{
    MCID id = m_clientMap.size();
    m_clientMap.resize(id + 1);

    size_t abstract_id;
    if (grouped)
    {
        abstract_id = m_numClients - 1;
    }
    else
    {
        abstract_id = m_numClients++;
    }

    size_t cache_id = abstract_id / m_numClientsPerCache;

    if (cache_id == m_caches.size())
    {
        // Add a cache
        if (m_caches.size() % m_numCachesPerLowRing == 0)
        {
            // First cache in a ring; add a directory
            CacheID firstCache = m_caches.size();

            stringstream name;
            name << "dir" << m_directories.size();
            Directory* dir = new Directory(name.str(), *this, GetClock(), firstCache, m_config);           
            m_directories.push_back(dir);
        }
        
        stringstream name;
        name << "cache" << m_caches.size();
        Cache* cache = new Cache(name.str(), *this, GetClock(), m_caches.size(), m_config);
        m_caches.push_back(cache);
    }
    
    // Forward the registration to the cache associated with the processor

    Cache *cache = m_caches[cache_id];

    MCID id_in_cache = cache->RegisterClient(callback, process, traces, storage);

    m_clientMap[id] = make_pair(cache, id_in_cache);

    if (!grouped)
        m_registry.registerBidiRelation(callback.GetMemoryPeer(), *cache, "mem");

    return id;
}