diff options
| author | Alejandro Soto <alejandro@34project.org> | 2022-09-18 17:14:54 -0600 |
|---|---|---|
| committer | Alejandro Soto <alejandro@34project.org> | 2022-09-18 17:14:54 -0600 |
| commit | 54544911601351465a6a887a045f3baddcb90dc6 (patch) | |
| tree | a18c6a015a8c924db47c15ee8c49329200cf5276 /tb | |
| parent | 1f27d200401eb0497c23054ebbe04c488c6974b9 (diff) | |
Implement Avalon memory module for simulation
Diffstat (limited to 'tb')
| -rw-r--r-- | tb/mem.cpp | 49 | ||||
| -rw-r--r-- | tb/mem.hpp | 36 |
2 files changed, 85 insertions, 0 deletions
diff --git a/tb/mem.cpp b/tb/mem.cpp new file mode 100644 index 0000000..bfbc3ea --- /dev/null +++ b/tb/mem.cpp @@ -0,0 +1,49 @@ +#include <cassert> +#include <cstdint> +#include <memory> + +#include "mem.hpp" + +namespace taller::avalon +{ + mem::mem(std::uint32_t base, std::uint32_t size) + : base(base), mask(~(size - 1)), + block(std::make_unique<std::uint32_t[]>(size >> 2)) + { + assert(!(size & 0b11) && !((size - 1) & size)); + } + + bool mem::read(std::uint32_t addr, std::uint32_t &data) + { + data = block[addr]; + return true; + } + + bool mem::write(std::uint32_t addr, std::uint32_t data, unsigned byte_enable) + { + std::uint32_t bytes = 0; + + if(byte_enable & 0b1000) + { + bytes |= 0xff << 24; + } + + if(byte_enable & 0b0100) + { + bytes |= 0xff << 16; + } + + if(byte_enable & 0b0010) + { + bytes |= 0xff << 8; + } + + if(byte_enable & 0b0001) + { + bytes |= 0xff; + } + + block[addr] = (data & bytes) | (block[addr] & ~bytes); + return true; + } +} diff --git a/tb/mem.hpp b/tb/mem.hpp new file mode 100644 index 0000000..0d9bbb0 --- /dev/null +++ b/tb/mem.hpp @@ -0,0 +1,36 @@ +#ifndef MEM_HPP +#define MEM_HPP + +#include <cstdint> +#include <memory> + +#include "avalon.hpp" + +namespace taller::avalon +{ + class mem : public slave + { + public: + mem(std::uint32_t base, std::uint32_t size); + + virtual inline std::uint32_t base_address() noexcept final override + { + return base; + } + + virtual inline std::uint32_t address_mask() noexcept final override + { + return mask; + } + + virtual bool read(std::uint32_t addr, std::uint32_t &data); + virtual bool write(std::uint32_t addr, std::uint32_t data, unsigned byte_enable); + + private: + std::unique_ptr<std::uint32_t[]> block; + std::uint32_t base; + std::uint32_t mask; + }; +} + +#endif |
