GVSOC
GVSOC Core Engine Architecture

Top-level Flowchart
flowchart TB
subgraph l1 ["Layer 1: Python Configuration"]
direction TB
A1["Target Definition <br/> (Target class)"] --> A2
A2["Component Tree"] --> A3
A3["Simulation runner"]
end
subgraph l2 ["Layer 2: JSON"]
direction TB
B1["gvsoc_config.json"]
end
subgraph l3 ["Layer 3: Simulation"]
C1["Launcher<br>(gv::Controller)"]
C2["Top Level Interface<br>(vp::Top)"]
C3["Trace Engine<br>(vp::TraceEngine)"]
C4["Component Tree<br>(vp::Component)"]
C5["Time Engine<br>(vp::TimeEngine)"]
C1-->C2
C2-->C3
C2-->C4
C2-->C5
end
subgraph l4["Layer 4: HAL"]
D1["RISC-V ISS"]
D2["Device-specific model<br>(Testbench, I2C, etc.)"]
end
A3-->B1
B1-->C1
C4--->|"Functional"|D1
C4--->|"Functional"|D2
C5-->|"Time"|D1
C5-->|"Time"|D2
Gvsoc
class Gvsoc: public Io, public Vcd, public Wire, public Power
{
public:
virtual void open() {}
virtual void bind(Gvsoc_user *user) {}
virtual void close() {}
virtual void start() {}
virtual void run() {}
virtual int64_t stop() { return 0; }
virtual void terminate() {}
virtual void quit(int status) {}
virtual void update(int64_t timestamp) {}
virtual void step(int64_t duration, bool wait=false, void *data=NULL) {}
virtual void step_until(int64_t duration, bool wait=false, void *data=NULL) {}
virtual int join() { return 0; }
virtual void flush() {}
virtual void *get_component(std::string path) { return NULL; }
virtual void lock() {}
virtual void unlock() {}
virtual void wait_runnable() {}
virtual int64_t get_time() { return -1; }
virtual int64_t get_next_event_time() { return -1 ;}
};
Block component
class Component: public Block
{
friend class vp::BlockClock;
friend class vp::BlockPower;
friend class vp::PowerSource;
friend class vp::MasterPort;
friend class vp::Top;
friend class vp::TimeEngine;
friend class gv::Controller;
public:
void new_master_port(std::string name, vp::MasterPort *port, vp::Block *comp=NULL);
void new_slave_port(std::string name, SlavePort *port, void *comp=NULL);
js::Config *get_js_config() { return js_config; }
gv::Controller *get_launcher();
private:
int build_all();
void unbuild_all();
static vp::Component *load_component(
js::Config *config,
js::Config *gv_config,
vp::Component *parent,
std::string name,
vp::TimeEngine *time_engine,
vp::TraceEngine *trace_engine,
vp::PowerEngine *power_engine,
vp::MemCheck *memcheck
);
void set_launcher(gv::Controller *launcher);
std::map<std::string, Component *> childs_dict;
bool is_component() { return true; }
void create_comps();
void create_ports();
void create_bindings();
void bind_comps();
void final_bind();
vp::Port *get_port(std::string name);
void add_port(std::string name, vp::Port *port);
std::map<std::string, vp::Component *> get_childs_dict() { return childs_dict; }
static std::string get_module_path(js::Config *gv_config, std::string relpath);
void add_child(std::string name, vp::Component *child);
vp::Component *new_component(std::string name, js::Config *config, std::string module="");
static void clk_reg(vp::Component *_this, vp::Component *clock);
static void clk_set_frequency(vp::Component *_this, int64_t frequency);
static void power_supply_sync(vp::Block *_this, int state);
static void voltage_sync(vp::Block *_this, int voltage);
static void reset_sync(vp::Block *_this, bool active);
std::string name;
vp::Component *parent;
js::Config *js_config;
js::Config *gv_config;
std::unordered_map<std::string, vp::Port *> ports;
gv::Controller *launcher;
vp::WireSlave<bool> reset_port;
vp::WireSlave<int> power_port;
vp::WireSlave<int> voltage_port;
vp::ClkSlave clock_port;
std::vector<vp::Component *> child_components;
};
Register
template<class T>
class Register
{
private:
T value;
protected:
T reset_val;
T write_mask = -1;
public:
Register(Block &parent, std::string name, int width, bool do_reset=false, T reset_val=0) {}
T get() const { return this->value; }
void set(T value);
}