Created
July 7, 2022 05:12
-
-
Save jevinskie/42292f2f8eac0cd3680f4319172dbf32 to your computer and use it in GitHub Desktop.
vpi shim code autogened for litex
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
struct vpi_values_t { | |
PLI_INT32 sim_trace; | |
PLI_INT32 sys_clk; | |
PLI_INT32 serial_source_valid; | |
PLI_INT32 serial_source_ready; | |
PLI_INT32 serial_source_data; | |
PLI_INT32 serial_sink_valid; | |
PLI_INT32 serial_sink_ready; | |
PLI_INT32 serial_sink_data; | |
}; | |
static_assert(sizeof(vpi_values_t) == 8 * sizeof(int32_t), "Struct padding detected"); | |
static vpi_values_t sig_vals; | |
struct vpi_handles_t { | |
vpiHandle sim_trace; | |
vpiHandle sys_clk; | |
vpiHandle serial_source_valid; | |
vpiHandle serial_source_ready; | |
vpiHandle serial_source_data; | |
vpiHandle serial_sink_valid; | |
vpiHandle serial_sink_ready; | |
vpiHandle serial_sink_data; | |
}; | |
static vpi_handles_t vpi_handles; | |
extern "C" void litex_vpi_signals_register_callbacks() { | |
static s_vpi_time t{.type = vpiSuppressTime}; | |
static s_vpi_value v{.format = vpiIntVal}; | |
vpi_handles.sim_trace = vpi_handle_by_name("serial2tcp_bare_litex_iverilog.sim_trace", nullptr); | |
assert(vpi_handles.sim_trace); | |
s_cb_data sim_trace_cbd{ | |
.reason = cbValueChange, | |
.cb_rtn = signal_uint8_t_change_cb, | |
.obj = vpi_handles.sim_trace, | |
.time = &t, | |
.value = &v, | |
.user_data = (char *)&sig_vals.sim_trace | |
}; | |
const auto sim_trace_cb = vpi_register_cb(&sim_trace_cbd); | |
assert(sim_trace_cb && vpi_free_object(sim_trace_cb)); | |
sim_trace[0].signal = &sig_vals.sim_trace; | |
assert(!litex_sim_register_pads(sim_trace, "sim_trace", 0)); | |
vpi_handles.sys_clk = vpi_handle_by_name("serial2tcp_bare_litex_iverilog.sys_clk", nullptr); | |
assert(vpi_handles.sys_clk); | |
s_cb_data sys_clk_cbd{ | |
.reason = cbValueChange, | |
.cb_rtn = signal_uint8_t_change_cb, | |
.obj = vpi_handles.sys_clk, | |
.time = &t, | |
.value = &v, | |
.user_data = (char *)&sig_vals.sys_clk | |
}; | |
const auto sys_clk_cb = vpi_register_cb(&sys_clk_cbd); | |
assert(sys_clk_cb && vpi_free_object(sys_clk_cb)); | |
sys_clk[0].signal = &sig_vals.sys_clk; | |
assert(!litex_sim_register_pads(sys_clk, "sys_clk", 0)); | |
vpi_handles.serial_source_valid = vpi_handle_by_name("serial2tcp_bare_litex_iverilog.serial_source_valid", nullptr); | |
assert(vpi_handles.serial_source_valid); | |
s_cb_data serial_source_valid_cbd{ | |
.reason = cbValueChange, | |
.cb_rtn = signal_uint8_t_change_cb, | |
.obj = vpi_handles.serial_source_valid, | |
.time = &t, | |
.value = &v, | |
.user_data = (char *)&sig_vals.serial_source_valid | |
}; | |
const auto serial_source_valid_cb = vpi_register_cb(&serial_source_valid_cbd); | |
assert(serial_source_valid_cb && vpi_free_object(serial_source_valid_cb)); | |
serial[0].signal = &sig_vals.serial_source_valid; | |
vpi_handles.serial_source_ready = vpi_handle_by_name("serial2tcp_bare_litex_iverilog.serial_source_ready", nullptr); | |
assert(vpi_handles.serial_source_ready); | |
s_cb_data serial_source_ready_cbd{ | |
.reason = cbValueChange, | |
.cb_rtn = signal_uint8_t_change_cb, | |
.obj = vpi_handles.serial_source_ready, | |
.time = &t, | |
.value = &v, | |
.user_data = (char *)&sig_vals.serial_source_ready | |
}; | |
const auto serial_source_ready_cb = vpi_register_cb(&serial_source_ready_cbd); | |
assert(serial_source_ready_cb && vpi_free_object(serial_source_ready_cb)); | |
serial[1].signal = &sig_vals.serial_source_ready; | |
vpi_handles.serial_source_data = vpi_handle_by_name("serial2tcp_bare_litex_iverilog.serial_source_data", nullptr); | |
assert(vpi_handles.serial_source_data); | |
s_cb_data serial_source_data_cbd{ | |
.reason = cbValueChange, | |
.cb_rtn = signal_uint8_t_change_cb, | |
.obj = vpi_handles.serial_source_data, | |
.time = &t, | |
.value = &v, | |
.user_data = (char *)&sig_vals.serial_source_data | |
}; | |
const auto serial_source_data_cb = vpi_register_cb(&serial_source_data_cbd); | |
assert(serial_source_data_cb && vpi_free_object(serial_source_data_cb)); | |
serial[2].signal = &sig_vals.serial_source_data; | |
vpi_handles.serial_sink_valid = vpi_handle_by_name("serial2tcp_bare_litex_iverilog.serial_sink_valid", nullptr); | |
assert(vpi_handles.serial_sink_valid); | |
s_cb_data serial_sink_valid_cbd{ | |
.reason = cbValueChange, | |
.cb_rtn = signal_uint8_t_change_cb, | |
.obj = vpi_handles.serial_sink_valid, | |
.time = &t, | |
.value = &v, | |
.user_data = (char *)&sig_vals.serial_sink_valid | |
}; | |
const auto serial_sink_valid_cb = vpi_register_cb(&serial_sink_valid_cbd); | |
assert(serial_sink_valid_cb && vpi_free_object(serial_sink_valid_cb)); | |
serial[3].signal = &sig_vals.serial_sink_valid; | |
vpi_handles.serial_sink_ready = vpi_handle_by_name("serial2tcp_bare_litex_iverilog.serial_sink_ready", nullptr); | |
assert(vpi_handles.serial_sink_ready); | |
s_cb_data serial_sink_ready_cbd{ | |
.reason = cbValueChange, | |
.cb_rtn = signal_uint8_t_change_cb, | |
.obj = vpi_handles.serial_sink_ready, | |
.time = &t, | |
.value = &v, | |
.user_data = (char *)&sig_vals.serial_sink_ready | |
}; | |
const auto serial_sink_ready_cb = vpi_register_cb(&serial_sink_ready_cbd); | |
assert(serial_sink_ready_cb && vpi_free_object(serial_sink_ready_cb)); | |
serial[4].signal = &sig_vals.serial_sink_ready; | |
vpi_handles.serial_sink_data = vpi_handle_by_name("serial2tcp_bare_litex_iverilog.serial_sink_data", nullptr); | |
assert(vpi_handles.serial_sink_data); | |
s_cb_data serial_sink_data_cbd{ | |
.reason = cbValueChange, | |
.cb_rtn = signal_uint8_t_change_cb, | |
.obj = vpi_handles.serial_sink_data, | |
.time = &t, | |
.value = &v, | |
.user_data = (char *)&sig_vals.serial_sink_data | |
}; | |
const auto serial_sink_data_cb = vpi_register_cb(&serial_sink_data_cbd); | |
assert(serial_sink_data_cb && vpi_free_object(serial_sink_data_cb)); | |
serial[5].signal = &sig_vals.serial_sink_data; | |
assert(!litex_sim_register_pads(serial, "serial", 0)); | |
} | |
extern "C" void litex_vpi_signals_writeback() { | |
static vpi_values_t last_sig_vals{}; | |
if (!memcmp(&sig_vals, &last_sig_vals, sizeof(sig_vals))) { | |
return; | |
} | |
s_vpi_value v{.format = vpiIntVal}; | |
if (sig_vals.sim_trace != last_sig_vals.sim_trace) { | |
fprintf(stderr, "sim_trace old: 0x%08x new: 0x%08x\n", last_sig_vals.sim_trace, sig_vals.sim_trace); | |
v.value.integer = sig_vals.sim_trace; | |
assert(!vpi_put_value(vpi_handles.sim_trace, &v, nullptr, vpiNoDelay)); | |
} | |
if (sig_vals.sys_clk != last_sig_vals.sys_clk) { | |
v.value.integer = sig_vals.sys_clk; | |
assert(!vpi_put_value(vpi_handles.sys_clk, &v, nullptr, vpiNoDelay)); | |
} | |
if (sig_vals.serial_source_valid != last_sig_vals.serial_source_valid) { | |
fprintf(stderr, "serial_source_valid old: 0x%08x new: 0x%08x\n", last_sig_vals.serial_source_valid, sig_vals.serial_source_valid); | |
v.value.integer = sig_vals.serial_source_valid; | |
assert(!vpi_put_value(vpi_handles.serial_source_valid, &v, nullptr, vpiNoDelay)); | |
} | |
if (sig_vals.serial_source_ready != last_sig_vals.serial_source_ready) { | |
fprintf(stderr, "serial_source_ready old: 0x%08x new: 0x%08x\n", last_sig_vals.serial_source_ready, sig_vals.serial_source_ready); | |
v.value.integer = sig_vals.serial_source_ready; | |
assert(!vpi_put_value(vpi_handles.serial_source_ready, &v, nullptr, vpiNoDelay)); | |
} | |
if (sig_vals.serial_source_data != last_sig_vals.serial_source_data) { | |
fprintf(stderr, "serial_source_data old: 0x%08x new: 0x%08x\n", last_sig_vals.serial_source_data, sig_vals.serial_source_data); | |
v.value.integer = sig_vals.serial_source_data; | |
assert(!vpi_put_value(vpi_handles.serial_source_data, &v, nullptr, vpiNoDelay)); | |
} | |
if (sig_vals.serial_sink_valid != last_sig_vals.serial_sink_valid) { | |
fprintf(stderr, "serial_sink_valid old: 0x%08x new: 0x%08x\n", last_sig_vals.serial_sink_valid, sig_vals.serial_sink_valid); | |
v.value.integer = sig_vals.serial_sink_valid; | |
assert(!vpi_put_value(vpi_handles.serial_sink_valid, &v, nullptr, vpiNoDelay)); | |
} | |
if (sig_vals.serial_sink_ready != last_sig_vals.serial_sink_ready) { | |
fprintf(stderr, "serial_sink_ready old: 0x%08x new: 0x%08x\n", last_sig_vals.serial_sink_ready, sig_vals.serial_sink_ready); | |
v.value.integer = sig_vals.serial_sink_ready; | |
assert(!vpi_put_value(vpi_handles.serial_sink_ready, &v, nullptr, vpiNoDelay)); | |
} | |
if (sig_vals.serial_sink_data != last_sig_vals.serial_sink_data) { | |
fprintf(stderr, "serial_sink_data old: 0x%08x new: 0x%08x\n", last_sig_vals.serial_sink_data, sig_vals.serial_sink_data); | |
v.value.integer = sig_vals.serial_sink_data; | |
assert(!vpi_put_value(vpi_handles.serial_sink_data, &v, nullptr, vpiNoDelay)); | |
} | |
memcpy(&last_sig_vals, &sig_vals, sizeof(last_sig_vals)); | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment