Skip to content

File pc_gen_stage.h

File List > pipelined > pc_gen_stage.h

Go to the documentation of this file

#pragma once

#include <deque>
#include <vector>

#include "sm/pipelined/pipelined.h"

namespace simtix {

namespace uvm {
class FrontendGoldenImpl;
}

namespace pipelined {

class PCGenStage {
 public:
  explicit PCGenStage(PipelinedSMImpl *sm, const PipelinedSM::Param &p);

  ~PCGenStage() = default;

  void PCGen();

  bool Ready();

  void NotifyIssue(uint32_t wid, std::optional<uint32_t> ssw);

  void NotifyFill(uint64_t pc);

  void Reset();

 protected:
  PipelinedSMImpl *const sm_;

  using SswValidBits = std::array<bool, 3>;

  struct FetchFilterEntry {
    bool valid = false;  // Valid when fetch request is generated.
    uint64_t addr = 0;   // Fetch address.
  };

  void NotifyEmpty(uint32_t wid, std::optional<uint32_t> ssw) {
    uint32_t leader_wid = wid / kWarpsPerWarpGroup;
    starving_leader_warps_[leader_wid][ssw ? 1 + ssw.value() : 0] = true;
  }

  void GenerateFetchRequest(uint32_t wid, std::optional<uint32_t> ssw);

  inline constexpr uint64_t ToFetchAddress(uint64_t addr) const {
    return addr & ~(kFetchWidth * 4 - 1);
  }

  const uint32_t kLeaderWarps;
  const uint32_t kFetchWidth;
  const uint32_t kOutstandingInstrFetches;
  const uint32_t kWarpsPerWarpGroup;

  std::deque<uint32_t> free_entry_ids_;
  std::vector<FetchFilterEntry> fetch_filter_;
  std::vector<std::vector<SswValidBits> *> warp_lists_;

  uint32_t prioritized_leader_wid_;
  std::vector<SswValidBits> issuing_leader_warps_;
  std::vector<SswValidBits> starving_leader_warps_;

  friend class uvm::FrontendGoldenImpl;
};

}  // namespace pipelined

}  // namespace simtix