File atomic.h
File List > fu > lsu > atomic.h
Go to the documentation of this file
#pragma once
#include <cassert>
#include <string>
#include <utility>
#include <vector>
#include "sm/fu/lsu/base.h"
namespace simtix {
// Class: TimingLoadStoreUnit
// A load/store unit that takes memory delay into consideration, which
// separates requests from instructions and outstanding requests in 2
// separated queues. <TimingLoadStoreUnit> will always accept <InstrPtr> for
// Read/Write, putting them into sized <pending_requests_> queue. The
// number of outstanding requests is determined by the parameter during
// construction of <TimingLoadStoreUnit>. The requests will be processed
// in the order of arrival, and the responses will be put into
// <response_requests_> queue.
class AtomicLoadStoreUnit : public BaseLoadStoreUnit, sim::Clocked {
public:
struct Request {
Request() = default;
Request(const Payload &payload, bool is_write, OnResp on_resp)
: payload(payload),
valid(true),
accepted(false),
is_write(is_write),
on_resp(std::move(on_resp)) {}
Request(Request &&other)
: payload(other.payload),
valid(other.valid),
accepted(other.accepted),
is_write(other.is_write),
on_resp(std::move(other.on_resp)) {}
Request &operator=(Request &&other) {
payload = other.payload;
valid = other.valid;
accepted = other.accepted;
is_write = other.is_write;
on_resp = std::move(other.on_resp);
return *this;
}
Payload payload;
bool valid;
bool accepted;
bool is_write;
OnResp on_resp;
};
explicit AtomicLoadStoreUnit(const std::string &name,
uint32_t num_outstanding_requests,
const ArchParam &p = kDefaultArchParam)
: BaseLoadStoreUnit(name, p),
sim::Clocked(name),
outstanding_requests_(p.kThreadsPerWarp()) {}
~AtomicLoadStoreUnit() {}
bool Busy() override;
bool Put(InstrPtr instr) override;
std::optional<InstrPtr> Get() override;
void PushWriteRequest(uint32_t tid, Payload payload, OnResp on_resp) override;
void PushReadRequest(uint32_t tid, Payload payload, OnResp on_resp) override;
protected:
void Tick() override;
bool HasPendingTasks() override;
std::vector<Request> outstanding_requests_;
bool requesting_ = false;
};
} // namespace simtix