mortbopet / VSRTL

Visual Simulation of Register Transfer Logic
MIT License
88 stars 18 forks source link

Add "Memory" core component #30

Closed mortbopet closed 4 years ago

mortbopet commented 5 years ago

The vsrtl::Memory object should be seen as a base class for all components implementing some form of memory (whether this is to model ram, rom, ...).

The memory component should provide different policies for handling invalid memory accesses (RAZ/WI or other policies). Subclasses of memory shall during construction specify the regions available within the component.

interface to the memory could be:

template<int width>
class Memory : public Component {
public:
    Port* address = nullptr;
    Port* readEnable = nullptr;
    Port* writeEnable = nullptr;
    Port* dataRead = nullptr;
    Port* dataValid = nullptr;

    // Externally modify value at addr, size in bytes
    void externalWrite(VSRTL_VT_U addr, VSRTL_VT_U data, int size){
    static_assert(sizeof(data) <= size);
    }

    // This function would verify that the memory blob which is written to is
    // appropriately sized. Also, add handling for writing to contiguous but separate
    // blobs
    void externalWrite(VSRTL_VT_U addr, VSRTL_VT_U dataPtr, int size);

    // Externally modify value at addr, size in bytes
    VSRTL_VT_U externalRead(VSRTL_VT_U addr, data, int size){
    static_assert(sizeof(data) <= size);
    }

private:
    enum class readErrorPolicy{ RAZ,  RDEADBEEF, ... };
    enum class writeErrorPolicy{ WI } ;
}

template<int width>
class ROM : public Memory {
public:
    Rom(Component* parent) : Memory<width>(parent){
        readEnable = createPort(this, width);
        dataRead = createPort(this, width);
        dataValid = createPort(this, width);
        // writeEnable is not instantiated, Read-only memory
    }

}
mortbopet commented 5 years ago

Note in the implementation that the memory - RAM, ROM, ..., will always be synchronous read/write.