summaryrefslogtreecommitdiff
path: root/tb/mem.hpp
diff options
context:
space:
mode:
authorAlejandro Soto <alejandro@34project.org>2023-09-24 23:39:17 -0600
committerAlejandro Soto <alejandro@34project.org>2023-09-24 23:39:17 -0600
commitd4d9f5296b193f80ee7fc2e42e52d974249d09e0 (patch)
treebaa99636a2b40882af4cdd253162c9ac2f5f14d3 /tb/mem.hpp
parent15230c6cd2190a1efd61c2758bf56de37f3fe8da (diff)
tb: implement support for cache line-sized slaves
Diffstat (limited to 'tb/mem.hpp')
-rw-r--r--tb/mem.hpp29
1 files changed, 22 insertions, 7 deletions
diff --git a/tb/mem.hpp b/tb/mem.hpp
index 0943530..4c37b0e 100644
--- a/tb/mem.hpp
+++ b/tb/mem.hpp
@@ -8,30 +8,45 @@
namespace taller::avalon
{
- template<typename Cell>
class mem : public slave
{
public:
mem(std::uint32_t base, std::uint32_t size);
- virtual bool read(std::uint32_t addr, std::uint32_t &data) final override;
+ virtual bool read_line(std::uint32_t addr, line &data) final override;
- virtual bool write
+ virtual bool write_line
(
- std::uint32_t addr, std::uint32_t data, unsigned byte_enable = 0b1111
+ std::uint32_t addr, const line &data, unsigned byte_enable
) final override;
template<typename F>
void load(F loader, std::size_t offset = 0);
private:
- std::unique_ptr<Cell[]> block;
+ std::unique_ptr<line[]> block;
unsigned count = 0;
bool ready() noexcept;
};
-}
-#include "mem.impl.hpp"
+ template<typename F>
+ void mem::load(F loader, std::size_t offset)
+ {
+ const auto base = base_address();
+ const auto bits = 4;
+
+ std::size_t size = address_span();
+ std::size_t addr = base_address() + offset;
+
+ while (addr >= base && addr < base + size) {
+ std::size_t read = loader(&block[(addr - base) >> bits], (base + size - addr) >> bits);
+ if (!read)
+ break;
+
+ addr += read << bits;
+ }
+ }
+}
#endif