diff options
| author | Alejandro Soto <alejandro@34project.org> | 2023-09-24 23:39:17 -0600 |
|---|---|---|
| committer | Alejandro Soto <alejandro@34project.org> | 2023-09-24 23:39:17 -0600 |
| commit | d4d9f5296b193f80ee7fc2e42e52d974249d09e0 (patch) | |
| tree | baa99636a2b40882af4cdd253162c9ac2f5f14d3 /tb/avalon.hpp | |
| parent | 15230c6cd2190a1efd61c2758bf56de37f3fe8da (diff) | |
tb: implement support for cache line-sized slaves
Diffstat (limited to '')
| -rw-r--r-- | tb/avalon.hpp | 61 |
1 files changed, 59 insertions, 2 deletions
diff --git a/tb/avalon.hpp b/tb/avalon.hpp index a2cc348..40bfe9a 100644 --- a/tb/avalon.hpp +++ b/tb/avalon.hpp @@ -9,6 +9,21 @@ namespace taller::avalon { + union line + { + __int128 qword; + + struct + { + std::uint64_t lo, hi; + }; + + struct + { + std::uint32_t words[4]; + }; + }; + class slave { public: @@ -57,8 +72,50 @@ namespace taller::avalon inline virtual void bail() noexcept {} - 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; + virtual bool read(std::uint32_t addr, std::uint32_t &data) + { + line line_data; + if (!this->read_line(addr >> 2, line_data)) + return false; + + data = line_data.words[addr & 0b11]; + return true; + } + + virtual bool read_line(std::uint32_t addr, line &data) + { + data.hi = 0; + data.lo = 0; + + return this->read(addr << 2, data.words[0]); + } + + virtual bool write + ( + std::uint32_t addr, std::uint32_t data, unsigned byte_enable = 0b1111 + ) { + line line_data; + line_data.words[addr & 0b11] = data; + + return this->write_line(addr >> 2, line_data, byte_enable << ((addr & 0b11) * 4)); + } + + virtual bool write_line(std::uint32_t addr, const line &data, unsigned byte_enable) { + unsigned offset = 0; + if (byte_enable & 0x00f0) + offset = 1; + else if (byte_enable & 0x0f00) + offset = 2; + else if (byte_enable & 0xf000) + offset = 3; + + return this->write + ( + (addr << 2) + offset, + data.words[offset], + (byte_enable >> (offset * 4)) & 0b1111 + ); + } inline virtual bool irq() noexcept { |
