refactor: redesign the type system | embrace the new bit_type concept
This commit is contained in:
39
demo/bit.cpp
39
demo/bit.cpp
@ -1,39 +0,0 @@
|
|||||||
#include "../include/tools"
|
|
||||||
|
|
||||||
signed main() {
|
|
||||||
[[maybe_unused]]
|
|
||||||
Bit <1> a; // Create a 1-bit object, default to 0
|
|
||||||
|
|
||||||
Bit <10> b(10); // Create a 10-bit object
|
|
||||||
|
|
||||||
auto ref = b.slice <4, 2> (); // A copy of [2, 3, 4] bit
|
|
||||||
|
|
||||||
std::cout << b << std::endl; // 10
|
|
||||||
|
|
||||||
b.set <3, 1> (ref); // Set [1, 2, 3] bit to [2, 3, 4] bit
|
|
||||||
|
|
||||||
std::cout << b << std::endl; // 4
|
|
||||||
|
|
||||||
b.set <0> (~a); // Set the 0-th bit to ~a (= 1 in this case)
|
|
||||||
|
|
||||||
std::cout << b << std::endl; // 5
|
|
||||||
|
|
||||||
auto sec = b.slice <2> (); // A copy of the 2-th bit (= 1 in this case)
|
|
||||||
|
|
||||||
auto d = sec.zero_extend(); // Zero extend (default to 32-bit)
|
|
||||||
|
|
||||||
std::cout << d << std::endl; // 1
|
|
||||||
|
|
||||||
auto c = sec.sign_extend <3> (); // Sign extend (default to 32-bit)
|
|
||||||
|
|
||||||
std::cout << c << std::endl; // 7
|
|
||||||
|
|
||||||
// c + d; // Error: different size
|
|
||||||
// a += 1; // Error: no assignment-operation operator
|
|
||||||
|
|
||||||
auto e = b - 1; // normal integer can be assumed as any size
|
|
||||||
|
|
||||||
std::cout << e << std::endl; // 4
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,38 +0,0 @@
|
|||||||
#include "../include/tools"
|
|
||||||
|
|
||||||
struct Input {
|
|
||||||
Wire a;
|
|
||||||
Wire b;
|
|
||||||
std::array <Wire, 2> c;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Output {
|
|
||||||
Register d;
|
|
||||||
Register e;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Content {
|
|
||||||
Register r;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct MyModule : Input, Output, private Content {
|
|
||||||
using Tags = SyncTags <Input, Output, Content>;
|
|
||||||
friend class Visitor;
|
|
||||||
|
|
||||||
void demo() { this->d <= this->a + this->b; }
|
|
||||||
};
|
|
||||||
|
|
||||||
signed main() {
|
|
||||||
MyModule m;
|
|
||||||
|
|
||||||
m.a = []() { return 1; };
|
|
||||||
m.b.assign([&]() { return (target_size_t)m.d; });
|
|
||||||
|
|
||||||
for (int i = 0 ; i < 10 ; ++i) {
|
|
||||||
std::cout << m.d << std::endl;
|
|
||||||
m.demo();
|
|
||||||
std::cout << m.d << std::endl;
|
|
||||||
sync_member(m);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
130
include/bit.h
130
include/bit.h
@ -1,20 +1,13 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "target.h"
|
#include "concept.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include <version>
|
#include <version>
|
||||||
|
#include <climits>
|
||||||
#include <concepts>
|
#include <concepts>
|
||||||
|
|
||||||
namespace dark::bits {
|
namespace dark {
|
||||||
|
|
||||||
static constexpr std::size_t kMaxLength = 8 * sizeof(target_size_t);
|
static constexpr std::size_t kMaxLength = std::numeric_limits<max_size_t>::digits;
|
||||||
|
|
||||||
template <int _First>
|
|
||||||
constexpr auto int_concat(target_size_t arg) { return arg; }
|
|
||||||
|
|
||||||
template <int _First, int ..._Lens>
|
|
||||||
constexpr auto int_concat(target_size_t arg, auto ...args) {
|
|
||||||
return (arg << (_Lens + ...)) | int_concat<_Lens...>(args...);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <std::size_t _Nm>
|
template <std::size_t _Nm>
|
||||||
struct Bit {
|
struct Bit {
|
||||||
@ -22,117 +15,38 @@ struct Bit {
|
|||||||
static_assert(0 < _Nm && _Nm <= kMaxLength,
|
static_assert(0 < _Nm && _Nm <= kMaxLength,
|
||||||
"Bit: _Nm out of range. Should be in [1, kMaxLength]");
|
"Bit: _Nm out of range. Should be in [1, kMaxLength]");
|
||||||
|
|
||||||
target_size_t _M_data : _Nm; // Real storage
|
max_size_t _M_data : _Nm; // Real storage
|
||||||
|
|
||||||
|
template <std::size_t _Hi, std::size_t _Lo>
|
||||||
|
static constexpr void _M_range_check();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static constexpr std::size_t _Bit_Len = _Nm;
|
static constexpr std::size_t _Bit_Len = _Nm;
|
||||||
|
|
||||||
constexpr Bit(target_size_t data = {}) : _M_data(data) {}
|
constexpr Bit(max_size_t data = 0) : _M_data(data) {}
|
||||||
|
|
||||||
template <std::size_t ..._Lens>
|
constexpr explicit operator max_size_t() const { return this->_M_data; }
|
||||||
constexpr Bit(Bit<_Lens> ...args) requires ((_Lens + ...) == _Nm) :
|
|
||||||
_M_data(int_concat<_Lens...>(args...)) {}
|
|
||||||
|
|
||||||
constexpr Bit(const Bit &val) = default;
|
template <concepts::bit_type ..._Tp>
|
||||||
|
requires ((_Tp::_Bit_Len + ...) == _Nm)
|
||||||
|
constexpr Bit(const _Tp &...args);
|
||||||
|
|
||||||
template <std::size_t _Len>
|
template <concepts::bit_match <Bit> _Tp>
|
||||||
constexpr Bit(const Bit <_Len> &val) requires (_Len != _Nm) {
|
constexpr Bit &operator=(const _Tp &val);
|
||||||
static_assert(_Len == _Nm, "Bit: bit length mismatch");
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr Bit &operator=(const Bit &val) = default;
|
template <std::size_t _Hi, std::size_t _Lo = _Hi, concepts::bit_match <Bit> _Tp>
|
||||||
|
constexpr void set(const _Tp &val);
|
||||||
template <std::size_t _Len> requires (_Len != _Nm)
|
|
||||||
constexpr Bit &operator=(const Bit <_Len> &val) {
|
|
||||||
static_assert(_Len == _Nm, "Bit: bit length mismatch");
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr Bit &operator=(target_size_t val) {
|
|
||||||
this->_M_data = val;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr operator target_size_t() const { return this->_M_data; }
|
|
||||||
|
|
||||||
template <std::size_t _Hi, std::size_t _Lo = _Hi>
|
template <std::size_t _Hi, std::size_t _Lo = _Hi>
|
||||||
constexpr auto set(Bit <_Hi - _Lo + 1> val) {
|
constexpr auto range() const -> Bit <_Hi - _Lo + 1>;
|
||||||
static_cast <void> (this->slice<_Hi, _Lo>());
|
|
||||||
const auto mask = // Mask those bit in the middle
|
|
||||||
(target_size_t(1) << (_Hi + 1)) - (target_size_t(1) << _Lo);
|
|
||||||
const auto data = // Set those bit in the middle
|
|
||||||
static_cast <target_size_t> (val) << _Lo;
|
|
||||||
this->_M_data = (this->_M_data & ~mask) | data;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <std::size_t _Hi, std::size_t _Lo = _Hi>
|
|
||||||
constexpr auto slice() const -> Bit <_Hi - _Lo + 1> {
|
|
||||||
static_assert(_Lo <= _Hi, "Bit::slice: _Lo should be no greater than _Hi");
|
|
||||||
static_assert(_Hi < _Nm, "Bit::slice: _Hi should be less than _Nm");
|
|
||||||
return Bit<_Hi - _Lo + 1>(this->_M_data >> _Lo);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <std::size_t _Len = 1>
|
template <std::size_t _Len = 1>
|
||||||
constexpr auto at(target_size_t pos) const -> Bit <_Len> {
|
constexpr auto slice(std::size_t pos) const -> Bit <_Len>;
|
||||||
static_assert(_Len != 0, "Bit::at: _Len should be greater than 0");
|
|
||||||
debug::assert(pos + _Len <= _Nm, "Bit::at: pos out of range");
|
|
||||||
return Bit <_Len> (this->_M_data >> pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr auto operator [](target_size_t pos) const -> Bit <1> { return this->at(pos); }
|
constexpr Bit <1> operator [](std::size_t pos) const { return this->slice(pos); }
|
||||||
|
|
||||||
template <std::size_t _New = kMaxLength>
|
|
||||||
constexpr auto zero_extend() const -> Bit<_New>;
|
|
||||||
|
|
||||||
template <std::size_t _New = kMaxLength>
|
|
||||||
constexpr auto sign_extend() const -> Bit<_New>;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename _Tp>
|
template <concepts::bit_type ..._Tp>
|
||||||
static constexpr bool is_bit_v = false;
|
|
||||||
template <std::size_t _Nm>
|
|
||||||
static constexpr bool is_bit_v<Bit<_Nm>> = true;
|
|
||||||
|
|
||||||
template <typename _Tp>
|
|
||||||
concept BitType = is_bit_v<_Tp>;
|
|
||||||
|
|
||||||
template <BitType ..._Tp>
|
|
||||||
Bit(_Tp...) -> Bit<(_Tp::_Bit_Len + ...)>;
|
Bit(_Tp...) -> Bit<(_Tp::_Bit_Len + ...)>;
|
||||||
|
|
||||||
template <std::size_t _Old, std::size_t _New = kMaxLength>
|
} // namespace dark
|
||||||
constexpr auto sign_extend(target_size_t val) {
|
|
||||||
static_assert(_Old < _New, "sign_extend: _Old should be less than _New");
|
|
||||||
struct { target_ssize_t _M_data : _Old; } tmp;
|
|
||||||
return Bit<_New>(tmp._M_data = val);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <std::size_t _New = kMaxLength, BitType _Tp>
|
|
||||||
constexpr auto sign_extend(_Tp val) {
|
|
||||||
return sign_extend<_Tp::_Bit_Len, _New>(static_cast<target_size_t>(val));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <std::size_t _Old, std::size_t _New = kMaxLength>
|
|
||||||
constexpr auto zero_extend(target_size_t val) {
|
|
||||||
static_assert(_Old < _New, "zero_extend: _Old should be less than _New");
|
|
||||||
struct { target_size_t _M_data : _Old; } tmp;
|
|
||||||
return Bit<_New>(tmp._M_data = val);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <std::size_t _New = kMaxLength, BitType _Tp>
|
|
||||||
constexpr auto zero_extend(_Tp val) {
|
|
||||||
return zero_extend<_Tp::_Bit_Len, _New>(static_cast<target_size_t>(val));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <std::size_t _Nm>
|
|
||||||
template <std::size_t _New>
|
|
||||||
constexpr auto Bit<_Nm>::sign_extend() const -> Bit<_New> {
|
|
||||||
return ::dark::bits::sign_extend<_New> (*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <std::size_t _Nm>
|
|
||||||
template <std::size_t _New>
|
|
||||||
constexpr auto Bit<_Nm>::zero_extend() const -> Bit<_New> {
|
|
||||||
return ::dark::bits::zero_extend<_New> (*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace dark::bits
|
|
||||||
|
94
include/bit_impl.h
Normal file
94
include/bit_impl.h
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "bit.h"
|
||||||
|
|
||||||
|
namespace dark {
|
||||||
|
|
||||||
|
template <int _First>
|
||||||
|
constexpr auto int_concat(max_size_t arg) { return arg; }
|
||||||
|
|
||||||
|
template <int _First, int ..._Lens>
|
||||||
|
constexpr auto int_concat(max_size_t arg, auto ...args) {
|
||||||
|
return (arg << (_Lens + ...)) | int_concat<_Lens...>(args...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <std::size_t _Old, std::size_t _New = kMaxLength>
|
||||||
|
constexpr auto sign_extend(max_size_t val) {
|
||||||
|
static_assert(_Old < _New, "sign_extend: _Old should be less than _New");
|
||||||
|
struct { max_ssize_t _M_data : _Old; } tmp;
|
||||||
|
return Bit<_New>(tmp._M_data = val);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <std::size_t _New = kMaxLength, concepts::bit_type _Tp>
|
||||||
|
constexpr auto sign_extend(const _Tp & val) {
|
||||||
|
return sign_extend<_Tp::_Bit_Len, _New>(static_cast<max_size_t>(val));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <std::size_t _Old, std::size_t _New = kMaxLength>
|
||||||
|
constexpr auto zero_extend(max_size_t val) {
|
||||||
|
static_assert(_Old < _New, "zero_extend: _Old should be less than _New");
|
||||||
|
struct { max_size_t _M_data : _Old; } tmp;
|
||||||
|
return Bit<_New>(tmp._M_data = val);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <std::size_t _New = kMaxLength, concepts::bit_type _Tp>
|
||||||
|
constexpr auto zero_extend(const _Tp &val) {
|
||||||
|
return zero_extend<_Tp::_Bit_Len, _New>(static_cast<max_size_t>(val));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <std::size_t _Nm>
|
||||||
|
template <concepts::bit_type ..._Tp>
|
||||||
|
requires ((_Tp::_Bit_Len + ...) == _Nm)
|
||||||
|
constexpr Bit<_Nm>::Bit(const _Tp &...args)
|
||||||
|
: _M_data(int_concat<_Tp::_Bit_Len...>(static_cast<max_size_t>(args)...)) {}
|
||||||
|
|
||||||
|
template <std::size_t _Nm>
|
||||||
|
template <concepts::bit_match <Bit <_Nm>> _Tp>
|
||||||
|
constexpr Bit<_Nm> &Bit<_Nm>::operator=(const _Tp &val) {
|
||||||
|
this->_M_data = static_cast<max_size_t>(val);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <std::size_t _Nm>
|
||||||
|
template <std::size_t _Hi, std::size_t _Lo>
|
||||||
|
constexpr void Bit<_Nm>::_M_range_check() {
|
||||||
|
static_assert(_Lo <= _Hi, "Bit::range_check: _Lo should be no greater than _Hi");
|
||||||
|
static_assert(_Hi < _Nm, "Bit::range_check: _Hi should be less than _Nm");
|
||||||
|
}
|
||||||
|
|
||||||
|
template <std::size_t _Nm>
|
||||||
|
template <std::size_t _Hi, std::size_t _Lo, concepts::bit_match <Bit<_Nm>> _Tp>
|
||||||
|
constexpr void Bit<_Nm>::set(const _Tp &val) {
|
||||||
|
this->_M_range_check<_Hi, _Lo>();
|
||||||
|
auto data = static_cast<max_size_t>(val);
|
||||||
|
constexpr auto _Length = _Hi - _Lo + 1;
|
||||||
|
if constexpr (_Length == kMaxLength) {
|
||||||
|
this->_M_data = data;
|
||||||
|
} else {
|
||||||
|
auto mask = ((1 << _Length) - 1) << _Lo;
|
||||||
|
this->_M_data = (this->_M_data & ~mask) | ((data << _Lo) & mask);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <std::size_t _Nm>
|
||||||
|
template <std::size_t _Hi, std::size_t _Lo>
|
||||||
|
constexpr auto Bit<_Nm>::range() const -> Bit <_Hi - _Lo + 1> {
|
||||||
|
this->_M_range_check<_Hi, _Lo>();
|
||||||
|
constexpr auto _Length = _Hi - _Lo + 1;
|
||||||
|
return Bit<_Length>(this->_M_data >> _Lo);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <std::size_t _Nm>
|
||||||
|
template <std::size_t _Len>
|
||||||
|
constexpr auto Bit<_Nm>::slice(std::size_t pos) const -> Bit <_Len> {
|
||||||
|
static_assert(_Len <= _Nm, "Bit::slice: _Len should be no greater than _Nm");
|
||||||
|
debug::assert(pos <= _Nm - _Len, "Bit::slice: pos should be less than _Nm - _Len");
|
||||||
|
if constexpr (_Len == kMaxLength) {
|
||||||
|
return *this;
|
||||||
|
} else {
|
||||||
|
return Bit<_Len>(this->_M_data >> pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace dark
|
1
include/bit_op.h
Normal file
1
include/bit_op.h
Normal file
@ -0,0 +1 @@
|
|||||||
|
#pragma once
|
@ -1,32 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include "bit.h"
|
|
||||||
|
|
||||||
namespace dark::bits {
|
|
||||||
|
|
||||||
template <typename _Tp>
|
|
||||||
concept NonBit = !BitType<_Tp>;
|
|
||||||
|
|
||||||
template <typename _Tp>
|
|
||||||
auto cast(_Tp &&val) -> target_size_t {
|
|
||||||
return static_cast<target_size_t>(val);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <BitType _Lhs, BitType _Rhs>
|
|
||||||
constexpr auto operator + (_Lhs lhs, _Rhs rhs) {
|
|
||||||
static_assert(_Lhs::_Bit_Len == _Rhs::_Bit_Len,
|
|
||||||
"operator +: lhs and rhs should have the same length");
|
|
||||||
return _Lhs { cast(lhs) + cast(rhs) };
|
|
||||||
}
|
|
||||||
|
|
||||||
template <BitType _Lhs, NonBit _Rhs>
|
|
||||||
constexpr auto operator + (_Lhs lhs, _Rhs &&rhs) {
|
|
||||||
return _Lhs { cast(lhs) + cast(rhs) };
|
|
||||||
}
|
|
||||||
|
|
||||||
template <NonBit _Lhs, BitType _Rhs>
|
|
||||||
constexpr auto operator + (_Lhs &&lhs, _Rhs rhs) {
|
|
||||||
return _Rhs { cast(lhs) + cast(rhs) };
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace dark::bits
|
|
41
include/concept.h
Normal file
41
include/concept.h
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <cstdint>
|
||||||
|
#include <concepts>
|
||||||
|
|
||||||
|
namespace dark {
|
||||||
|
|
||||||
|
using max_size_t = std::uint32_t;
|
||||||
|
using max_ssize_t = std::int32_t;
|
||||||
|
|
||||||
|
} // namespace dark
|
||||||
|
|
||||||
|
namespace dark::concepts {
|
||||||
|
|
||||||
|
template <typename _Tp>
|
||||||
|
using func_t = void(*)(_Tp);
|
||||||
|
|
||||||
|
template <typename _From, typename _To>
|
||||||
|
concept implicit_convertible_to = requires(_From &a, func_t <_To> b) {
|
||||||
|
b(a); // Can implicitly convert
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename _From, typename _To>
|
||||||
|
concept explicit_convertible_to =
|
||||||
|
!implicit_convertible_to <_From, _To>
|
||||||
|
&& std::constructible_from <_To, _From>;
|
||||||
|
|
||||||
|
template <typename _Tp>
|
||||||
|
concept has_length = requires { _Tp::_Bit_Len; };
|
||||||
|
|
||||||
|
template <typename _Tp>
|
||||||
|
concept bit_type = has_length <_Tp> && explicit_convertible_to <_Tp, max_size_t>;
|
||||||
|
|
||||||
|
template <typename _Tp>
|
||||||
|
concept int_type = !has_length <_Tp> && implicit_convertible_to <_Tp, max_size_t>;
|
||||||
|
|
||||||
|
template <typename _Lhs, typename _Rhs>
|
||||||
|
concept bit_match =
|
||||||
|
(bit_type <_Lhs> && bit_type <_Rhs> && _Lhs::_Bit_Len == _Rhs::_Bit_Len)
|
||||||
|
|| (int_type <_Lhs> || int_type <_Rhs>);
|
||||||
|
|
||||||
|
} // namespace dark::concepts
|
@ -1,7 +1,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "target.h"
|
#include "concept.h"
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <cstdint>
|
||||||
#include <concepts>
|
#include <concepts>
|
||||||
|
|
||||||
namespace dark::hardware {
|
namespace dark::hardware {
|
||||||
@ -13,7 +14,7 @@ struct Register;
|
|||||||
template <typename _Fn>
|
template <typename _Fn>
|
||||||
concept WireFunction =
|
concept WireFunction =
|
||||||
!std::same_as <Wire, std::decay_t <_Fn>> &&
|
!std::same_as <Wire, std::decay_t <_Fn>> &&
|
||||||
requires(_Fn &&__f) { { __f() } -> std::convertible_to <target_size_t>; };
|
requires(_Fn &&__f) { { __f() } -> std::convertible_to <max_size_t>; };
|
||||||
|
|
||||||
struct WireBase {
|
struct WireBase {
|
||||||
using _Ret_t = int;
|
using _Ret_t = int;
|
||||||
@ -46,7 +47,7 @@ struct Wire {
|
|||||||
using _Manage_t = WireBase;
|
using _Manage_t = WireBase;
|
||||||
|
|
||||||
std::unique_ptr <_Manage_t> _M_impl;
|
std::unique_ptr <_Manage_t> _M_impl;
|
||||||
mutable target_size_t _M_cache;
|
mutable max_size_t _M_cache;
|
||||||
mutable bool _M_holds;
|
mutable bool _M_holds;
|
||||||
|
|
||||||
[[no_unique_address]]
|
[[no_unique_address]]
|
||||||
@ -65,7 +66,6 @@ struct Wire {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Wire() : _M_impl(new EmptyWire), _M_cache(), _M_holds(), _M_dirty() {}
|
Wire() : _M_impl(new EmptyWire), _M_cache(), _M_holds(), _M_dirty() {}
|
||||||
|
|
||||||
Wire(Wire &&) = delete;
|
Wire(Wire &&) = delete;
|
||||||
@ -90,7 +90,7 @@ struct Wire {
|
|||||||
this->_M_holds = false;
|
this->_M_holds = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
operator target_size_t() const {
|
operator max_size_t() const {
|
||||||
if (this->_M_holds == false) {
|
if (this->_M_holds == false) {
|
||||||
this->_M_cache = this->_M_impl->call();
|
this->_M_cache = this->_M_impl->call();
|
||||||
this->_M_holds = true;
|
this->_M_holds = true;
|
||||||
@ -103,8 +103,8 @@ struct Register {
|
|||||||
private:
|
private:
|
||||||
friend struct Visitor;
|
friend struct Visitor;
|
||||||
|
|
||||||
target_size_t _M_new;
|
max_size_t _M_new;
|
||||||
target_size_t _M_old;
|
max_size_t _M_old;
|
||||||
|
|
||||||
[[no_unique_address]]
|
[[no_unique_address]]
|
||||||
debug::DebugValue <bool, false> _M_dirty;
|
debug::DebugValue <bool, false> _M_dirty;
|
||||||
@ -116,15 +116,16 @@ struct Register {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_value(target_size_t value) {
|
void set_value(max_size_t value) {
|
||||||
this->_M_new = value;
|
this->_M_new = value;
|
||||||
debug::assert(!this->_M_dirty, "Register is already assigned in this cycle.");
|
debug::assert(!this->_M_dirty, "Register is already assigned in this cycle.");
|
||||||
this->_M_dirty = true;
|
this->_M_dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto get_value() const -> target_size_t { return this->_M_old; }
|
auto get_value() const -> max_size_t { return this->_M_old; }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Register() : _M_new(), _M_old(), _M_dirty() {}
|
Register() : _M_new(), _M_old(), _M_dirty() {}
|
||||||
|
|
||||||
Register(Register &&) = delete;
|
Register(Register &&) = delete;
|
||||||
@ -132,12 +133,12 @@ struct Register {
|
|||||||
Register &operator=(Register &&) = delete;
|
Register &operator=(Register &&) = delete;
|
||||||
Register &operator=(const Register &rhs) = delete;
|
Register &operator=(const Register &rhs) = delete;
|
||||||
|
|
||||||
template <std::convertible_to <target_size_t> _Int>
|
template <std::convertible_to <max_size_t> _Int>
|
||||||
void operator <= (_Int &&value) {
|
void operator <= (_Int &&value) {
|
||||||
this->set_value(static_cast <target_size_t>(value));
|
this->set_value(static_cast <max_size_t>(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
operator target_size_t() const { return this->get_value(); }
|
operator max_size_t() const { return this->get_value(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace dark::hardware
|
} // namespace dark::hardware
|
||||||
|
@ -1,9 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include <cstdint>
|
|
||||||
|
|
||||||
namespace dark {
|
|
||||||
|
|
||||||
using target_size_t = std::uint32_t;
|
|
||||||
using target_ssize_t = std::int32_t;
|
|
||||||
|
|
||||||
} // namespace dark
|
|
@ -1,17 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include "target.h"
|
|
||||||
#include "hardware.h"
|
|
||||||
#include "synchronize.h"
|
|
||||||
#include "bit.h"
|
|
||||||
#include "bitop.h"
|
|
||||||
|
|
||||||
using ::dark::target_size_t;
|
|
||||||
using ::dark::target_ssize_t;
|
|
||||||
|
|
||||||
using ::dark::hardware::Register;
|
|
||||||
using ::dark::hardware::Wire;
|
|
||||||
using ::dark::hardware::Visitor;
|
|
||||||
using ::dark::hardware::SyncTags;
|
|
||||||
using ::dark::hardware::sync_member;
|
|
||||||
|
|
||||||
using ::dark::bits::Bit;
|
|
Reference in New Issue
Block a user