From 54544911601351465a6a887a045f3baddcb90dc6 Mon Sep 17 00:00:00 2001 From: Alejandro Soto Date: Sun, 18 Sep 2022 17:14:54 -0600 Subject: Implement Avalon memory module for simulation --- tb/mem.cpp | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ tb/mem.hpp | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+) create mode 100644 tb/mem.cpp create mode 100644 tb/mem.hpp (limited to 'tb') 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 +#include +#include + +#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(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 +#include + +#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 block; + std::uint32_t base; + std::uint32_t mask; + }; +} + +#endif -- cgit v1.2.3