Skip to content

Commit

Permalink
Update to new VPI interface layer
Browse files Browse the repository at this point in the history
  • Loading branch information
ultraembedded committed Mar 27, 2016
1 parent af78870 commit b354382
Show file tree
Hide file tree
Showing 10 changed files with 466 additions and 465 deletions.
6 changes: 2 additions & 4 deletions ulpi_wrapper/testbench/makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,12 @@ SYSTEMC_HOME ?= /opt/systemc-2.3.1

TRACE ?= 1

DUT_NAME = ulpi_wrapper
RTL_DUT = ../rtl/ulpi_wrapper.v

#########################################################
# Source
#########################################################
SRC = $(filter-out $(DUT_NAME).cpp,$(wildcard *.cpp))
SRC += $(DUT_NAME).cpp
SRC = $(wildcard *.cpp)

SRC_V = tb_top.v
SRC_V += $(RTL_DUT)
Expand Down Expand Up @@ -55,4 +53,4 @@ run: $(EXE) $(VPI_OBJ).vpi
vvp -M. -m$(VPI_OBJ) $(EXE) -vcd

clean:
rm -rf $(OBJ) dut.vpi *.vcd *.out
rm -rf $(OBJ) dut.vpi *.vcd *.out
88 changes: 88 additions & 0 deletions ulpi_wrapper/testbench/sc_vpi_clock.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
#ifndef __SC_VPI_CLOCK_H__
#define __SC_VPI_CLOCK_H__

#include <systemc.h>
#include <vpi_user.h>


static int sc_vpi_clock_after_delay(p_cb_data cb_data);

class sc_vpi_clock
{
public:

sc_signal <bool> m_clk;
int m_low_ns;
int m_high_ns;
uint64_t m_last_time;

sc_module_name m_name;

vpiHandle m_vpi_handle;

sc_vpi_clock(sc_module_name name) : m_clk(name), m_name(name)
{
m_low_ns = 5;
m_high_ns = 5;
m_last_time = 0;

m_vpi_handle = vpi_handle_by_name((const char*)name, NULL);
sc_assert(m_vpi_handle != NULL);
}

void start(void) { after_delay(); }

int after_delay(void)
{
bool clk_next = !m_clk.read();
s_vpi_time vpi_time_s;
s_cb_data cb_data_s;

vpi_time_s.type = vpiSimTime;
vpi_time_s.high = 0;
vpi_time_s.low = 0;

s_vpi_value value_s;
value_s.format = vpiIntVal;
value_s.value.integer = clk_next;
vpi_put_value(m_vpi_handle, &value_s, &vpi_time_s, vpiInertialDelay);

// Setup wait time
vpi_time_s.high = 0;
vpi_time_s.low = clk_next ? m_high_ns : m_low_ns;
vpi_time_s.type = vpiSimTime;

m_clk.write(clk_next);

// Get current time
uint64_t time_value = 0;
s_vpi_time time_now;
time_now.type = vpiSimTime;
vpi_get_time (0, &time_now);

time_value = time_now.high;
time_value <<= 32;
time_value |= time_now.low;

// Update systemC TB
if(sc_pending_activity())
sc_start((int)(time_value-m_last_time),SC_NS);

// Attach value change callbacks for outputs
cb_data_s.user_data = (PLI_BYTE8*)this;
cb_data_s.reason = cbAfterDelay;
cb_data_s.cb_rtn = sc_vpi_clock_after_delay;
cb_data_s.time = &vpi_time_s;
cb_data_s.value = NULL;
vpi_register_cb(&cb_data_s);
}
};

static int sc_vpi_clock_after_delay(p_cb_data cb_data)
{
sc_vpi_clock *p = (sc_vpi_clock*)cb_data->user_data;
return p->after_delay();
}


#endif
145 changes: 145 additions & 0 deletions ulpi_wrapper/testbench/sc_vpi_module.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
#ifndef __SC_VPI_MODULE_H__
#define __SC_VPI_MODULE_H__

#include <systemc.h>
#include <assert.h>
#include <vpi_user.h>

static int sc_vpi_module_value_change(p_cb_data cb_data);

#define sc_vpi_module_read_output_int(obj, name) \
{ \
s_vpi_value value_s; \
s_vpi_time vpi_time_s; \
\
value_s.format = vpiIntVal; \
\
vpi_time_s.type = vpiSimTime; \
vpi_time_s.high = 0; \
vpi_time_s.low = 0; \
\
std::string path = m_hdl_name; \
path = path + "." + name; \
vpiHandle handle = vpi_handle_by_name(path.c_str(), NULL); \
assert(handle != NULL); \
\
vpi_get_value(handle, &value_s); \
obj.write(value_s.value.integer); \
}

#define sc_vpi_module_write_input_int(obj, name) \
{ \
s_vpi_value value_s; \
s_vpi_time vpi_time_s; \
\
value_s.format = vpiIntVal; \
\
vpi_time_s.type = vpiSimTime; \
vpi_time_s.high = 0; \
vpi_time_s.low = 0; \
\
std::string path = m_hdl_name; \
path = path + "." + name; \
vpiHandle handle = vpi_handle_by_name(path.c_str(), NULL); \
assert(handle != NULL); \
\
value_s.value.integer = obj.read(); \
vpi_put_value(handle, &value_s, &vpi_time_s, vpiInertialDelay); \
}

class sc_vpi_module
{
public:
std::string m_hdl_name;
uint64_t m_last_time;
sc_signal<bool> m_stop;

sc_vpi_module(sc_module_name name) : m_hdl_name((std::string)name)
{
m_last_time = 0;
m_stop.write(false);
}

// Simulation control
void stopSimulation() { m_stop.write(true); }
bool isStopped() { return m_stop.read(); }

virtual void read_outputs(void) { }
virtual void write_inputs(void) { }

bool register_signal(const char *name)
{
static s_vpi_value value_s;
static s_vpi_time vpi_time;
s_cb_data cb_data_s;

vpi_time.high = 0;
vpi_time.low = 0;
vpi_time.type = vpiSimTime;

// For each I/O
std::string path = m_hdl_name;
path = path + "." + name;
vpiHandle handle = vpi_handle_by_name(path.c_str(), NULL);
if (!handle)
return false;

// Attach value change callbacks for outputs
cb_data_s.user_data = (PLI_BYTE8*)this;
cb_data_s.reason = cbValueChange;
cb_data_s.cb_rtn = sc_vpi_module_value_change;
cb_data_s.time = &vpi_time;
cb_data_s.value = &value_s;

value_s.format = vpiIntVal;

cb_data_s.obj = handle;
vpi_register_cb(&cb_data_s);

return true;
}

int value_change(void)
{
s_vpi_time vpi_time_s;

vpi_time_s.type = vpiSimTime;
vpi_time_s.high = 0;
vpi_time_s.low = 0;

// Outputs
read_outputs();

// Get current time
uint64_t time_value = 0;
s_vpi_time time_now;
time_now.type = vpiSimTime;
vpi_get_time (0, &time_now);

time_value = time_now.high;
time_value <<= 32;
time_value |= time_now.low;

// Update systemC TB
if(sc_pending_activity())
sc_start((int)(time_value-m_last_time),SC_NS);

m_last_time = time_value;

// Inputs
write_inputs();

if (isStopped())
vpi_sim_control(vpiFinish, 0);

return 0;
}
};

static int sc_vpi_module_value_change(p_cb_data cb_data)
{
sc_vpi_module *p = (sc_vpi_module*)cb_data->user_data;
return p->value_change();
}

#endif
18 changes: 1 addition & 17 deletions ulpi_wrapper/testbench/tb_top.v
Original file line number Diff line number Diff line change
Expand Up @@ -66,31 +66,15 @@ ulpi_wrapper dut
);

//-----------------------------------------------------------------
// Reset
// Trace
//-----------------------------------------------------------------
initial
begin
ulpi_clk60_i = 1;
ulpi_rst_i = 1;

// Hookup System C
$attach_system_c();

if (`TRACE)
begin
$dumpfile("waveform.vcd");
$dumpvars(0,tb_top);
end

#51 ulpi_rst_i = 0;
end

//-----------------------------------------------------------------
// Clock
//-----------------------------------------------------------------
always
begin
#5 ulpi_clk60_i = !ulpi_clk60_i;
end

endmodule
Loading

0 comments on commit b354382

Please sign in to comment.