diff options
| author | Alejandro Soto <alejandro@34project.org> | 2023-09-25 05:14:25 -0600 |
|---|---|---|
| committer | Alejandro Soto <alejandro@34project.org> | 2023-09-25 05:14:25 -0600 |
| commit | d18a37a740db37707e5266e5ca6a8fd956737197 (patch) | |
| tree | 3e2d6ea6d354d8cac722f864f5b8c51fd881e2a9 /tb/avalon.impl.hpp | |
| parent | 27978501a87c5bb7a9fd78e376e8f6772cad009e (diff) | |
tb: implement cache ring
Diffstat (limited to 'tb/avalon.impl.hpp')
| -rw-r--r-- | tb/avalon.impl.hpp | 95 |
1 files changed, 28 insertions, 67 deletions
diff --git a/tb/avalon.impl.hpp b/tb/avalon.impl.hpp index 992f949..5dd9822 100644 --- a/tb/avalon.impl.hpp +++ b/tb/avalon.impl.hpp @@ -33,22 +33,19 @@ namespace taller::avalon template<class Platform> bool interconnect<Platform>::tick(bool clk) noexcept { - if(!plat.reset_reset_n) - { + if (!plat.reset_reset_n) { active = nullptr; plat.avl_irq = 0; avl_read = false; avl_write = false; avl_address = 0; - avl_writedata = 0; avl_byteenable = 0; return true; } - if(active) - { + if (active) { assert(avl_address == plat.avl_address); assert(avl_read == plat.avl_read); assert(avl_write == plat.avl_write); @@ -56,21 +53,16 @@ namespace taller::avalon assert(avl_byteenable == plat.avl_byteenable); } - if(!clk) - { + if (!clk) { tick_falling(); return true; - } else if(!active) - { + } else if (!active) assert(!avl_read || !avl_write); - } - try - { + try { tick_rising(); return true; - } catch(const avl_bus_error&) - { + } catch(const avl_bus_error&) { return false; } } @@ -78,48 +70,36 @@ namespace taller::avalon template<class Platform> void interconnect<Platform>::tick_rising() { - for(auto &binding : devices) - { + for (auto &binding : devices) binding.dev.tick(); - } - if(root_intc) - { + if (root_intc) plat.avl_irq = root_intc->irq(); - } - if(!active) - { + if (!active) { 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; - if(!avl_read && !avl_write) - { + if (!avl_read && !avl_write) return; - } - for(auto &binding : devices) - { - if((avl_address & binding.mask) == binding.base) - { + for (auto &binding : devices) + if ((avl_address & binding.mask) == binding.base) { active = &binding.dev; break; } - } - if(!active) [[unlikely]] - { + if (!active) [[unlikely]] { bail(); const char *op = avl_read ? "read" : "write"; fprintf(stderr, "[avl] attempt to %s memory hole at 0x%08x\n", op, avl_address); throw avl_bus_error{"memory hole addressed"}; - } else if(avl_address & active->word_mask()) [[unlikely]] - { + } else if(avl_address & 0b1111) [[unlikely]] { bail(); fprintf(stderr, "[avl] unaligned address: 0x%08x\n", avl_address); @@ -127,35 +107,28 @@ namespace taller::avalon } } - auto pos = (avl_address & ~active->address_mask()) >> active->word_bits(); + auto pos = (avl_address & ~active->address_mask()) >> 4; - if(avl_read) - { - std::uint32_t readdata; - plat.avl_waitrequest = !active->read(pos, readdata); + if (avl_read) { + line readdata; + plat.avl_waitrequest = !active->read_line(pos, readdata); plat.avl_readdata = readdata; - } else if(avl_write) - { - plat.avl_waitrequest = !active->write(pos, avl_writedata, avl_byteenable); - } + } else if (avl_write) + plat.avl_waitrequest = !active->write_line(pos, avl_writedata, avl_byteenable); } template<class Platform> void interconnect<Platform>::tick_falling() noexcept { - if(!plat.avl_waitrequest) - { + if (!plat.avl_waitrequest) active = nullptr; - } } template<class Platform> void interconnect<Platform>::bail() noexcept { - for(auto &binding : devices) - { + for (auto &binding : devices) binding.dev.bail(); - } } template<class Platform> @@ -164,17 +137,13 @@ namespace taller::avalon std::uint32_t avl_address = addr << 2; auto *dev = resolve_external(avl_address); - if(!dev) - { + if (!dev) return false; - } auto pos = (avl_address & ~dev->address_mask()) >> dev->word_bits(); - while(!dev->read(pos, word)) - { + while (!dev->read(pos, word)) continue; - } return true; } @@ -185,17 +154,13 @@ namespace taller::avalon std::uint32_t avl_address = addr << 2; auto *dev = resolve_external(avl_address); - if(!dev) - { + if (!dev) return false; - } auto pos = (avl_address & ~dev->address_mask()) >> dev->word_bits(); - while(!dev->write(pos, writedata, 0b1111)) - { + while (!dev->write(pos, writedata, 0b1111)) continue; - } return true; } @@ -203,13 +168,9 @@ namespace taller::avalon template<class Platform> slave* interconnect<Platform>::resolve_external(std::uint32_t avl_address) { - for(auto &binding : devices) - { - if((avl_address & binding.mask) == binding.base) - { + for (auto &binding : devices) + if ((avl_address & binding.mask) == binding.base) return &binding.dev; - } - } fprintf(stderr, "[avl] attempt to access hole at 0x%08x\n", avl_address); return nullptr; |
