// Copyright 2023 Google LLC

#ifndef TESTS_VERILATOR_SIM_SYSC_TB_H_
#define TESTS_VERILATOR_SIM_SYSC_TB_H_

// A SystemC baseclass for constrained random testing of Verilated RTL.
#include <systemc.h>

#include <iostream>
#include <string>

#include "tests/verilator_sim/fifo.h"
// sc_core needs to be included before verilator header
using namespace sc_core;      // NOLINT(build/namespaces)
#include "verilated_vcd_c.h"  // NOLINT(build/include_subdir): From verilator.

using sc_dt::sc_bv;

const char *vcd_path_ = "/tmp/kelvin/vcd";

#define BIND(a, b) a.b(b)
#define BIND2(a, b, c) \
  BIND(a, c);          \
  BIND(b, c)

template <typename T>
struct sc_signal_vrb {
  sc_signal<bool> valid;
  sc_signal<bool> ready;
  sc_signal<T> bits;
};

template <typename T>
struct sc_in_vrb {
  sc_in<bool> valid;
  sc_out<bool> ready;
  sc_in<T> bits;

  void bind(sc_signal<bool> &v, sc_signal<bool> &r, sc_signal<T> &b) {
    valid.bind(v);
    ready.bind(r);
    bits.bind(b);
  }

  void bind(sc_signal_vrb<T> &vrb) {
    valid.bind(vrb.valid);
    ready.bind(vrb.ready);
    bits.bind(vrb.bits);
  }

  void operator()(sc_signal<bool> &v, sc_signal<bool> &r, sc_signal<T> &b) {
    bind(v, r, b);
  }

  void operator()(sc_signal_vrb<T> &vrb) { bind(vrb); }
};

template <typename T>
struct sc_out_vrb {
  sc_out<bool> valid;
  sc_in<bool> ready;
  sc_out<T> bits;

  void bind(sc_signal<bool> &v, sc_signal<bool> &r, sc_signal<T> &b) {
    valid.bind(v);
    ready.bind(r);
    bits.bind(b);
  }

  void bind(sc_signal_vrb<T> &vrb) {
    valid.bind(vrb.valid);
    ready.bind(vrb.ready);
    bits.bind(vrb.bits);
  }

  void operator()(sc_signal<bool> &v, sc_signal<bool> &r, sc_signal<T> &b) {
    bind(v, r, b);
  }

  void operator()(sc_signal_vrb<T> &vrb) { bind(vrb); }
};

// eg. struct message : base {...};
struct base {
  inline bool operator==(const base &rhs) const { return false; }

  inline friend std::ostream &operator<<(std::ostream &os, base const &v) {
    return os;
  }
};

// Base class for testbench {posedge & negedge}.
struct Sysc_tb : public sc_module {
  sc_clock clock;
  sc_signal<bool> reset;
  sc_signal<bool> resetn;

  SC_HAS_PROCESS(Sysc_tb);

  Sysc_tb(sc_module_name n, int loops, bool random = true)
      : sc_module(n),
        clock("clock", 1, SC_NS),
        reset("reset"),
        resetn("resetn"),
        random_(random),
        loops_(loops) {
    loop_ = 0;
    error_ = false;

    SC_METHOD(tb_posedge);
    sensitive << clock_.pos();

    SC_METHOD(tb_negedge);
    sensitive << clock_.neg();

    SC_METHOD(tb_stop);
    sensitive << clock_.neg();

    clock_(clock);

    // Verilated::commandArgs(argc, argv);
    tf_ = new VerilatedVcdC;
  }

  ~Sysc_tb() {
    if (error_) {
      exit(23);
    }
  }

  void start() {
    init();

    reset = 1;
    resetn = 0;
    sc_start(4.75, SC_NS);  // falling edge of clock
    reset = 0;
    resetn = 1;

    sc_start();

    if (tf_) {
      tf_->dump(sim_time_++);  // last falling edge
      tf_->close();
      delete tf_;
      tf_ = nullptr;
    }
  }

  template <typename T>
  void trace(T &design, const char *name = "") {
    if (!strlen(name)) {
      name = design.name();
    }
    std::string path = std::string(vcd_path_) + "/" + name;
    design.trace(tf_, 99);
    path += ".vcd";
    Verilated::traceEverOn(true);
    tf_->open(path.c_str());
    printf("\nInfo: default timescale unit used for tracing: 1 ps (%s)\n",
           path.c_str());
  }

  static char *get_name(char *s) {
    const int len = strlen(s);
    char *p = s;
    for (int i = 0; i < len; ++i) {
      if (s[i] == '/') {
        p = s + i + 1;
      }
    }
    return p;
  }

 protected:
  virtual void init() {}
  virtual void posedge() {}
  virtual void negedge() {}

  bool check(bool v, const char *s = "") {
    const char *KRED = "\x1B[31m";
    const char *KRST = "\033[0m";
    if (!v) {
      sc_stop();
      printf("%s", KRED);
      if (strlen(s)) {
        printf("***ERROR[%s]::VERIFY \"%s\"\n", this->name(), s);
      } else {
        printf("***ERROR[%s]::VERIFY\n", this->name());
      }
      printf("%s", KRST);
      error_ = true;
    }
    return v;
  }

  bool rand_bool() {
    // Do not allow any 'io_in_valid' controls to be set during reset.
    return !reset &&
           (!random_ || (rand() & 1));  // NOLINT(runtime/threadsafe_fn)
  }

  int rand_int(int min = 0, int max = (1 << 31)) {
    return (rand() % (max - min + 1)) + min;  // NOLINT(runtime/threadsafe_fn)
  }

  uint32_t rand_uint32(uint32_t min = 0, uint32_t max = 0xffffffffu) {
    uint32_t r = (rand() & 0xffff) |  // NOLINT(runtime/threadsafe_fn)
                 (rand() << 16);      // NOLINT(runtime/threadsafe_fn)
    if (min == 0 && max == 0xffffffff) return r;
    return (r % (max - min + 1)) + min;
  }

  uint64_t rand_uint64(uint64_t min = 0, uint64_t max = 0xffffffffffffffffull) {
    uint64_t r = rand_uint32() | (uint64_t(rand_uint32()) << 32);
    if (min == 0 && max == 0xffffffffffffffffull) return r;
    return (r % (max - min + 1)) + min;
  }

  uint32_t cycle() {
    return sim_time_ / 2;  // posedge + negedge
  }

 private:
  const bool random_;
  const int loops_;
  int loop_;
  bool error_;

  sc_in<bool> clock_;

  uint32_t sim_time_ = 0;
  VerilatedVcdC *tf_ = nullptr;

  void tb_posedge() {
    if (tf_) tf_->dump(sim_time_++);
    if (reset) return;
    posedge();
  }

  void tb_negedge() {
    if (tf_) tf_->dump(sim_time_++);
    if (reset) return;
    negedge();
  }

  void tb_stop() {
    // LessThanEqual for one more edge (end - start + 1).
    if (loop_ <= loops_) {
      loop_++;
    } else {
      printf("\nInfo: loop limit \"%d\" reached\n", loops_);
      sc_stop();
    }
  }
};

#endif  // TESTS_VERILATOR_SIM_SYSC_TB_H_
