summaryrefslogtreecommitdiff
path: root/tb
diff options
context:
space:
mode:
authorAlejandro Soto <alejandro@34project.org>2023-09-29 04:53:21 -0600
committerAlejandro Soto <alejandro@34project.org>2023-09-29 04:53:21 -0600
commit231f61c7a07c41ff5b66aff400e7022310e6ec8b (patch)
treea808d4c36a83e56f0cd19b93ff06a4f97017ca4e /tb
parent24daea338920944133a394bcb85b2c459ccd1352 (diff)
tb: read line-sized reads of word-sized I/O slaves
Diffstat (limited to 'tb')
-rw-r--r--tb/avalon.hpp20
-rw-r--r--tb/avalon.impl.hpp2
-rw-r--r--tb/mem.cpp2
-rw-r--r--tb/mem.hpp5
4 files changed, 20 insertions, 9 deletions
diff --git a/tb/avalon.hpp b/tb/avalon.hpp
index e286786..6c720bc 100644
--- a/tb/avalon.hpp
+++ b/tb/avalon.hpp
@@ -104,19 +104,26 @@ namespace taller::avalon
virtual bool read(std::uint32_t addr, std::uint32_t &data)
{
line line_data;
- if (!this->read_line(addr >> 2, line_data))
+ if (!this->read_line(addr >> 2, line_data, 0b1111 << ((addr & 0b11) * 4)))
return false;
data = line_data.words[addr & 0b11];
return true;
}
- virtual bool read_line(std::uint32_t addr, line &data)
+ virtual bool read_line(std::uint32_t addr, line &data, unsigned byte_enable)
{
- data.hi = 0;
- data.lo = 0;
+ //XXX: Realmente es esto lo que genera qsys? Avalon spec no es clara
+ if (byte_enable & 0x000f)
+ return this->read(addr << 2, data.words[0]);
+ else if (byte_enable & 0x00f0)
+ return this->read((addr << 2) + 1, data.words[1]);
+ else if (byte_enable & 0x0f00)
+ return this->read((addr << 2) + 2, data.words[2]);
+ else if (byte_enable & 0xf000)
+ return this->read((addr << 2) + 3, data.words[3]);
- return this->read(addr << 2, data.words[0]);
+ return true;
}
virtual bool write
@@ -129,7 +136,8 @@ namespace taller::avalon
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) {
+ virtual bool write_line(std::uint32_t addr, const line &data, unsigned byte_enable)
+ {
unsigned offset = 0;
if (byte_enable & 0x00f0)
offset = 1;
diff --git a/tb/avalon.impl.hpp b/tb/avalon.impl.hpp
index d6dac11..efae0b9 100644
--- a/tb/avalon.impl.hpp
+++ b/tb/avalon.impl.hpp
@@ -111,7 +111,7 @@ namespace taller::avalon
if (avl_read) {
line readdata;
- plat.avl_waitrequest = !active->read_line(pos, readdata);
+ plat.avl_waitrequest = !active->read_line(pos, readdata, avl_byteenable);
plat.avl_readdata = readdata;
} else if (avl_write)
plat.avl_waitrequest = !active->write_line(pos, avl_writedata, avl_byteenable);
diff --git a/tb/mem.cpp b/tb/mem.cpp
index 47073ab..a58eaa9 100644
--- a/tb/mem.cpp
+++ b/tb/mem.cpp
@@ -12,7 +12,7 @@ namespace taller::avalon
block(std::make_unique<line[]>(size >> 4))
{}
- bool mem::read_line(std::uint32_t addr, line &data)
+ bool mem::read_line(std::uint32_t addr, line &data, unsigned byte_enable [[maybe_unused]])
{
data = block[addr];
return true;/*ready();*/
diff --git a/tb/mem.hpp b/tb/mem.hpp
index 4c37b0e..abcf386 100644
--- a/tb/mem.hpp
+++ b/tb/mem.hpp
@@ -13,7 +13,10 @@ namespace taller::avalon
public:
mem(std::uint32_t base, std::uint32_t size);
- virtual bool read_line(std::uint32_t addr, line &data) final override;
+ virtual bool read_line
+ (
+ std::uint32_t addr, line &data, unsigned byte_enable
+ ) final override;
virtual bool write_line
(