summaryrefslogtreecommitdiff
path: root/tb/avalon.impl.hpp
diff options
context:
space:
mode:
authorAlejandro Soto <alejandro@34project.org>2022-09-18 17:16:46 -0600
committerAlejandro Soto <alejandro@34project.org>2022-09-18 17:16:46 -0600
commit503957e2883e754fc8424c420c3d9838bd639ed3 (patch)
treef4b0bad5928fee6a43b73f246df875e14b3f6728 /tb/avalon.impl.hpp
parent54544911601351465a6a887a045f3baddcb90dc6 (diff)
Fix memory simulation
Diffstat (limited to '')
-rw-r--r--tb/avalon.impl.hpp44
1 files changed, 31 insertions, 13 deletions
diff --git a/tb/avalon.impl.hpp b/tb/avalon.impl.hpp
index 7f589ae..cc371a7 100644
--- a/tb/avalon.impl.hpp
+++ b/tb/avalon.impl.hpp
@@ -7,26 +7,44 @@
namespace taller::avalon
{
template<class Platform>
+ inline interconnect<Platform>::interconnect(Platform &plat) noexcept
+ : plat(plat)
+ {}
+
+ template<class Platform>
void interconnect<Platform>::attach(slave &dev)
{
- devices.push_back(binding { dev.base_address(), dev.address_mask(), dev });
+ auto base = dev.base_address();
+ auto mask = dev.address_mask();
+ assert((base & mask) == base);
+
+ devices.push_back(binding { base, mask, dev });
}
template<class Platform>
- void interconnect<Platform>::tick()
+ void interconnect<Platform>::tick(bool clk)
{
- auto addr = plat.avl_address;
+ if(!clk)
+ {
+ avl_address = plat.avl_address;
+ avl_read = plat.avl_read;
+ avl_write = plat.avl_write;
+ avl_writedata = plat.avl_writedata;
+ avl_byteenable = plat.avl_byteenable;
+ return;
+ }
+
if(!active)
{
- if(addr & 0b11)
+ if(avl_address & 0b11)
{
- fprintf(stderr, "[avl] unaligned address: 0x%08x\n", addr);
+ fprintf(stderr, "[avl] unaligned address: 0x%08x\n", avl_address);
assert(false);
}
for(auto &binding : devices)
{
- if((addr & binding.mask) == binding.base)
+ if((avl_address & binding.mask) == binding.base)
{
active = &binding.dev;
break;
@@ -35,21 +53,21 @@ namespace taller::avalon
if(!active)
{
- const char *op = plat.avl_read ? "read" : "write";
- fprintf(stderr, "[avl] attempt to %s memory hole at 0x%08x\n", op, addr);
+ const char *op = avl_read ? "read" : "write";
+ fprintf(stderr, "[avl] attempt to %s memory hole at 0x%08x\n", op, avl_address);
assert(false);
}
}
- assert(!plat.avl_read || !plat.avl_write);
- auto pos = addr >> 2;
+ assert(!avl_read || !avl_write);
+ auto pos = (avl_address & ~active->address_mask()) >> 2;
- if(plat.avl_read)
+ if(avl_read)
{
plat.avl_waitrequest = !active->read(pos, plat.avl_readdata);
- } else if(plat.avl_write)
+ } else if(avl_write)
{
- plat.avl_waitrequest = !active->write(pos, plat.avl_writedata, plat.avl_byteenable);
+ plat.avl_waitrequest = !active->write(pos, avl_writedata, avl_byteenable);
}
if(!plat.avl_waitrequest)