原本記憶體部分打算在實作 Load/Store 的前一篇寫。
但為了閱讀方便,調整順序讓接下來指令集的實作變成連續的章節。
P.S. 本來標題是 hart 之間的回憶,
但想想還是不要亂來好了,把文章寫好就好 :D
RISC-V 中,每個 hart (Hardware Thread) 都有一塊 byte-addressable 的定址空間。
這塊定址空間可能對應到三個類型的區域:
多個 hart 之間的定址空間可以完全共用、部分共用,
也可以互相獨立不共用。
規格書中區分了兩種記憶體存取來源:
RISC-V 預設的一致性模型為 Weak Memory Ordering (RVWMO),
也可以自行實作規範更強的一致性模型(例如本次實作的為 Strong Ordering)。
RVWMO 明確指出不管是哪一種存取來源,
都要在必要時使用 Fence 或者 Cache Control 指令來確保一致性。
例如 JIT compiler 在 Code Generation 後要 Invalid Cache、
或者 CA 課堂上也常提到相關的範例。
另外,規格書明確寫出可被 explict 存取而且可寫的區域一定可讀。
規格書中定義一個 word 的單位是 32-bit,如下所示:
+--------------------------+
| 32-bit |
+--------------------------+
| word |
+--------------------------+
| halfword | halfword |
+--------------------------+
| byte | byte | |
+--------------------------+
github 頁面 Tag: ITDay8
考量到之後可能在 Address Space 加入其他裝置,
設計的時候並不會直接把 memory 接在 CPU 上,而是另外用了一層 BUS 轉接。
class BUS: public ADDRESS_SPACE_INTERFACE, public sc_module
{
public:
BUS(sc_module_name name);
virtual int32_t read(uint32_t addr, uint32_t size) override;
virtual void write(uint32_t addr, uint32_t data, uint32_t size) override;
private:
MEMORY memory;
tlm_utils::simple_initiator_socket<BUS> memory_socket;
};
和 Register File 一樣,這次加了 ADDRESS_SPACE_INTERFACE
當作 BUS 的介面。
也用 shared_ptr 來管理 Instance。
//cpu
class CPU : public sc_module
{
public:
...
void set_address_space(const std::shared_ptr<ADDRESS_SPACE_INTERFACE> &instance);
...
std::shared_ptr<ADDRESS_SPACE_INTERFACE> address_space;
};
//main
int sc_main(int argc,char** argv)
{
...
cpu.set_address_space(std::make_shared<BUS>("bus"));
...
}