summaryrefslogtreecommitdiff
path: root/tb/avalon.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'tb/avalon.hpp')
-rw-r--r--tb/avalon.hpp56
1 files changed, 52 insertions, 4 deletions
diff --git a/tb/avalon.hpp b/tb/avalon.hpp
index a00ced0..8134677 100644
--- a/tb/avalon.hpp
+++ b/tb/avalon.hpp
@@ -1,7 +1,9 @@
-#ifndef AVALON_HPP
-#define AVALON_HPP
+#ifndef TALLER_AVALON_HPP
+#define TALLER_AVALON_HPP
+#include <cassert>
#include <cstdint>
+#include <cstdio>
#include <vector>
namespace taller::avalon
@@ -9,11 +11,57 @@ namespace taller::avalon
class slave
{
public:
- virtual std::uint32_t base_address() noexcept = 0;
- virtual std::uint32_t address_mask() noexcept = 0;
+ inline slave(std::uint32_t base, std::uint32_t size, std::size_t word_size)
+ : base(base),
+ mask(~(size - 1)),
+ word(log2i(word_size))
+ {
+ assert(!((word_size - 1) & word_size));
+ assert(!(base & word_mask()) && !(size & word_mask()) && !((size - 1) & size));
+ }
+
+ inline std::uint32_t base_address() noexcept
+ {
+ return base;
+ }
+
+ inline std::uint32_t address_mask() noexcept
+ {
+ return mask;
+ }
+
+ inline std::uint32_t word_mask() noexcept
+ {
+ return (1 << word) - 1;
+ }
+
+ inline std::size_t word_size() noexcept
+ {
+ return 1 << word;
+ }
+
+ inline unsigned word_bits() noexcept
+ {
+ return word;
+ }
+
+ inline std::uint32_t address_span() noexcept
+ {
+ return ~mask + 1;
+ }
virtual bool read(std::uint32_t addr, std::uint32_t &data) = 0;
virtual bool write(std::uint32_t addr, std::uint32_t data, unsigned byte_enable) = 0;
+
+ private:
+ std::uint32_t base;
+ std::uint32_t mask;
+ unsigned word;
+
+ static inline int log2i(int i)
+ {
+ return sizeof(int) * 8 - __builtin_clz(i) - 1;
+ }
};
template<class Platform>