Fix vpi_register_cb using bad s_cb_data, bug370.

This commit is contained in:
Wilson Snyder 2011-07-27 13:03:49 -04:00
parent 55906486d8
commit 6d2f09b579
4 changed files with 69 additions and 4 deletions

View File

@ -13,6 +13,8 @@ indicates the contributor was also the author of the fix; Thanks!
*** Support $fopen and I/O with integer instead of `verilator_file_descriptor.
**** Fix vpi_register_cb using bad s_cb_data, bug370. [by Thomas Watts]
**** Fix $display missing leading zeros in %0d, bug367. [Alex Solomatnikov]
**** Use 'vluint64_t' for SystemC instead of (same sized) 'uint64' for MSVC++.

View File

@ -95,9 +95,12 @@ typedef PLI_INT32 (*VerilatedPliCb)(struct t_cb_data *);
class VerilatedVpioCb : public VerilatedVpio {
t_cb_data m_cbData;
s_vpi_value m_value;
QData m_time;
public:
VerilatedVpioCb(const t_cb_data* cbDatap, QData time) : m_cbData(*cbDatap), m_time(time) {}
VerilatedVpioCb(const t_cb_data* cbDatap, QData time) : m_cbData(*cbDatap), m_time(time) {
m_cbData.value = &m_value;
}
virtual ~VerilatedVpioCb() {}
static inline VerilatedVpioCb* castp(vpiHandle h) { return dynamic_cast<VerilatedVpioCb*>((VerilatedVpio*)h); }
vluint32_t reason() const { return m_cbData.reason; }
@ -326,6 +329,7 @@ public:
VL_DEBUG_IF_PLI(VL_PRINTF("-vltVpi: value_callback %p %s v[0]=%d\n",
vop,varop->fullname(), *((CData*)newDatap)););
memcpy(prevDatap, newDatap, varop->entSize());
vpi_get_value(vop->cb_datap()->obj, vop->cb_datap()->value);
(vop->cb_rtnp()) (vop->cb_datap());
}
}

View File

@ -28,6 +28,10 @@
// __FILE__ is too long
#define FILENM "t_vpi_var.cpp"
unsigned int main_time = false;
unsigned int callback_count = false;
unsigned int callback_count_half = false;
//======================================================================
@ -87,6 +91,46 @@ int _mon_check_callbacks() {
return 0;
}
int _value_callback(p_cb_data cb_data) {
CHECK_RESULT(cb_data->value->value.integer+10, main_time);
callback_count++;
return 0;
}
int _value_callback_half(p_cb_data cb_data) {
CHECK_RESULT(cb_data->value->value.integer*2+10, main_time);
callback_count_half++;
return 0;
}
int _mon_check_value_callbacks() {
vpiHandle vh1 = vpi_handle_by_name((PLI_BYTE8*)"t.count", NULL);
CHECK_RESULT_NZ(vh1);
s_vpi_value v;
v.format = vpiIntVal;
vpi_get_value(vh1, &v);
t_cb_data cb_data;
cb_data.reason = cbValueChange;
cb_data.cb_rtn = _value_callback;
cb_data.obj = vh1;
cb_data.value = &v;
vpiHandle vh = vpi_register_cb(&cb_data);
CHECK_RESULT_NZ(vh);
vh1 = vpi_handle_by_name((PLI_BYTE8*)"t.half_count", NULL);
CHECK_RESULT_NZ(vh1);
cb_data.obj = vh1;
cb_data.cb_rtn = _value_callback_half;
vh = vpi_register_cb(&cb_data);
CHECK_RESULT_NZ(vh);
return 0;
}
int _mon_check_var() {
VlVpiHandle vh1 = vpi_handle_by_name((PLI_BYTE8*)"t.onebit", NULL);
CHECK_RESULT_NZ(vh1);
@ -246,6 +290,7 @@ int _mon_check_quad() {
int mon_check() {
// Callback from initial block in monitor
if (int status = _mon_check_callbacks()) return status;
if (int status = _mon_check_value_callbacks()) return status;
if (int status = _mon_check_var()) return status;
if (int status = _mon_check_varlist()) return status;
if (int status = _mon_check_getput()) return status;
@ -255,7 +300,6 @@ int mon_check() {
//======================================================================
unsigned int main_time = false;
double sc_time_stamp () {
return main_time;
@ -288,12 +332,15 @@ int main(int argc, char **argv, char **env) {
while (sc_time_stamp() < sim_time && !Verilated::gotFinish()) {
main_time += 1;
topp->eval();
VerilatedVpi::callValueCbs();
topp->clk = !topp->clk;
//mon_do();
#if VM_TRACE
if (tfp) tfp->dump (main_time);
#endif
}
CHECK_RESULT(callback_count, 501);
CHECK_RESULT(callback_count_half, 250);
if (!Verilated::gotFinish()) {
vl_fatal(FILENM,__LINE__,"main", "%Error: Timeout; never got a $finish");
}

View File

@ -19,6 +19,9 @@ module t (/*AUTOARG*/
reg [3:2][61:0] quads /*verilator public_flat_rw @(posedge clk) */;
reg [31:0] count /*verilator public_flat_rd */;
reg [31:0] half_count /*verilator public_flat_rd */;
integer status;
sub sub();
@ -34,8 +37,17 @@ module t (/*AUTOARG*/
if (onebit != 1'b1) $stop;
if (quads[2] != 62'h12819213_abd31a1c) $stop;
if (quads[3] != 62'h1c77bb9b_3784ea09) $stop;
$write("*-* All Finished *-*\n");
$finish;
end
always @(posedge clk) begin
count <= count + 2;
if (count[1])
half_count <= half_count + 2;
if (count == 1000) begin
$write("*-* All Finished *-*\n");
$finish;
end
end
endmodule