Jump to content

How can I have a virtual interface in systemC analogous to systemverilog


KEVIN CHACKO

Recommended Posts

SystemC has no special concept similar to SystemVerilog interfaces.  Instead you can use regular SystemC modules to work as SystemVerilog interfaces.

 

SystemC has it's own notion of interface that is similar to interface notion in object-oriented programming: interface is basically a set of pure virtual functions.

So for example you can define a simple memory interface as a set of mem_read and mem_write functions. SystemC requires that interfaces inherit virtually from sc_interface:

struct memory_if : virtual sc_interface {
    virtual uint32_t mem_read( uint32_t address) = 0; // reads data from memory at given address
    virtual void     mem_write( uint32_t address, uint32_t data) = 0; // writes data to memory at given address
};

Next you can define a module that implements and exports this interface.  For example:

struct memory_module : sc_module, memory_if {
    sc_export<memory_if>  mem_export{"mem_export"};

    SC_CTOR(memory_module) {
        mem_export.bind(*this);
    }

private:

    std::array<uint32_t , 1024> mem;

    uint32_t mem_read(uint32_t address) override {
        return mem.at(address >> 2);
    }

    void mem_write(uint32_t address, uint32_t data) override {
        mem.at(address >> 2) = data;
    }
};

You can have other modules implementing memory_if.  For example you can write a module that translates mem_read and mem_write function calls into a cycle-accurate signal-level memory protocol.  And this is what SystemVerilog interfaces often do.  

Now the closest analog to SystemVerilog virtual interface is SystemC sc_port. For example you can define a test_module that has a sc_port<memory_if> and sends memory reads and writes using this port:

struct test_module : sc_module {
  
    sc_port<memory_if> mem_port{"mem_port"};

    SC_CTOR(test_module) {
        SC_THREAD(test_thread);
    }
  
private:
    void test_thread() {
        cout << " test_thread \n";
        const int TEST_SIZE = 10;
        for (int i = 0; i < TEST_SIZE; ++i) {
            cout << hex << "Write mem[" << i * 4 << "] = " << i << "\n";
            mem_port->mem_write(i*4, i);
        }
        for (int i = 0; i < TEST_SIZE; ++i) {
            cout << hex << "Read mem[" << i * 4 << "] == " << mem_port->mem_read( i * 4 ) << "\n";
        }
    }
};

 

To create a simulation you instantiate both memory_module and test_module and bind port to export:

int sc_main (int argc, char **argv) {
    test_module tmod{"tmod"};
    memory_module mmod{"mmod"};
    tmod.mem_port.bind(mmod.mem_export);
    sc_start();
    return 0;
}

 

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...