Skip to content

File atomic.h

File List > arbitrator > atomic.h

Go to the documentation of this file

#pragma once

#include <simtix/param.h>

#include <cstdint>
#include <vector>

#include "sm/arbitrator/base.h"

namespace simtix {

// Class: AtomicArbitrator
class AtomicArbitrator : public BaseArbitrator {
 public:
  explicit AtomicArbitrator(const ArchParam &p);
  ~AtomicArbitrator() = default;

  void PushRegfileReadReq(const std::vector<Thread *> &active_threads,
                          uint32_t reg_id, int64_t *data,
                          OnReady on_ready) override;

  void PushRegfileWriteReq(const std::vector<Thread *> &active_threads,
                           uint32_t reg_id, int64_t *data,
                           OnReady on_ready) override;

  void PushRegfileWriteReq(const std::vector<Thread *> &active_threads,
                           uint32_t reg_id, int64_t data,
                           OnReady on_ready) override;

  int64_t ReadRegfile(uint32_t wid, uint32_t tid, uint32_t reg_id) override {
    return regfile_[ToRegfileIndex(wid, tid, reg_id)] * (reg_id != 0);
  }

  void WriteRegfile(uint32_t wid, uint32_t tid, uint32_t reg_id,
                    int64_t data) override {
    regfile_[ToRegfileIndex(wid, tid, reg_id)] = data * (reg_id != 0);
  }

 private:
  const uint32_t kThreadsPerWarp;
  const uint32_t kWarpsPerCore;

  uint32_t ToRegfileIndex(uint32_t wid, uint32_t tid, uint32_t reg_id) {
    //   | W0:R0 | W0:R1 | ... | W1:R0 | W1:R1 | ...
    //         ->|~~~~~~~|<- kThreadsPerWarp(int64_t)
    // ->|~~~~~~~~~~~~~~~~~~~~~|<- (kThreadsPerWarp * 32)(int64_t)
    return wid * (kThreadsPerWarp * 32) + (reg_id * kThreadsPerWarp) + tid;
  }

  // W0:R0 | W0:R1 | ... | W1:R0 | W1:R1 | ...
  std::vector<int64_t> regfile_;
};

}  // namespace simtix