#ifndef HLSDEV_AP_INT_STUB_H #define HLSDEV_AP_INT_STUB_H // =========================================================================== // EDITOR-ONLY STAND-IN for Xilinx's // --------------------------------------------------------------------------- // This is NOT the real header. It exists so clangd can resolve ap_uint // (and so a simple C-simulation can be built) on a machine with no Xilinx // tools installed. // // It implements only what the EMBS practicals use: unsigned fixed-width // values, bit indexing, += / -=, and conversion to/from integers. // It supports widths 1..64 only, and has none of the real header's // arbitrary-precision, signed, overflow or simulation semantics. // // Run ./fetch-headers.sh to download the REAL headers from csteach0. // They take precedence over this file when present. // =========================================================================== #include template class ap_uint { static_assert(W > 0 && W <= 64, "hlsdev stub ap_uint supports widths 1..64"); public: unsigned long long v; static constexpr unsigned long long width_mask() { return W >= 64 ? ~0ULL : ((1ULL << W) - 1ULL); } ap_uint() : v(0) {} ap_uint(int x) : v((unsigned long long)x & width_mask()) {} ap_uint(unsigned int x) : v((unsigned long long)x & width_mask()) {} ap_uint(unsigned long long x) : v(x & width_mask()) {} // Cross-width conversion, so e.g. ap_uint<4> += ap_uint<1> works. // The implicit copy constructor is still preferred for the same width. template ap_uint(const ap_uint& o) : v((unsigned long long)o & width_mask()) {} operator unsigned long long() const { return v & width_mask(); } ap_uint& operator=(unsigned long long x) { v = x & width_mask(); return *this; } ap_uint& operator+=(const ap_uint& o) { v = (v + o.v) & width_mask(); return *this; } ap_uint& operator-=(const ap_uint& o) { v = (v - o.v) & width_mask(); return *this; } // Writing a single bit needs a proxy object, just like the real ap_uint. class bit_ref { ap_uint& parent; int bit; public: bit_ref(ap_uint& p, int b) : parent(p), bit(b) {} bit_ref& operator=(bool x) { if (x) parent.v |= (1ULL << bit); else parent.v &= ~(1ULL << bit); return *this; } operator bool() const { return ((parent.v >> bit) & 1ULL) != 0; } // Convert straight to any ap_uint in a single user-defined // conversion, so things like acc += grid[r][c]; resolve cleanly. template operator ap_uint() const { return ap_uint((parent.v >> bit) & 1ULL); } }; bit_ref operator[](int b) { return bit_ref(*this, b); } bool operator[](int b) const { return ((v >> b) & 1ULL) != 0; } }; #endif // HLSDEV_AP_INT_STUB_H