summaryrefslogtreecommitdiff
path: root/uarch/memory.cpp
blob: 5cf9920118a01b243c2b10ff628c56cdc733204b (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include <algorithm>
#include <cstdint>
#include <initializer_list>
#include <iostream>
#include <set>
#include <utility>
#include <vector>

#include "aisa/aisa.h"
#include "uarch/memory.h"
#include "util/assert.h"

namespace uarch {

    MemStage::MemStage(sim::Scheduler &scheduler, sim::Queue<FillReq> &fillreqq, const std::initializer_list<sim::Queue<Fill> *> &fillqs, sim::Queue<Store> &storeq)
        : sim::Schedulable(scheduler)
        , fillreqq(fillreqq)
        , storeq(storeq)
    {
        fillreqq.add_reader(this);
        for (const auto &q : fillqs)
            q->add_writer(this);
        storeq.add_reader(this);
    }

    void MemStage::clock()
    {
        if (storeq.available()) {
            auto s = storeq.read();
            std::uint64_t x = 0;
            for (unsigned int i = 0; i < s.bytes.size(); ++i)
                x |= static_cast<std::uint64_t>(s.bytes[i]) << 8 * i;
            std::cout << "mem stores " << s.bytes.size() << " bytes to " << s.physical_addr << " <- " << x << "\n";
            ASSERT(store_mem(s.physical_addr, s.bytes.data(), s.bytes.size()), "Could not complete store");
        } else if (fillreqq.available()) {
            auto r = fillreqq.read();
            std::cout << "mem fills " << r.size << " bytes from " << r.physical_addr << "\n";
            Fill f;
            f.physical_addr = r.physical_addr;
            f.bytes.resize(r.size);
            ASSERT(fetch_mem(f.bytes.data(), r.physical_addr, r.size), "Could not complete fill");
            r.fillq->write(std::move(f));
        }
    }

}