mirror of
https://github.com/verilator/verilator.git
synced 2025-01-11 00:57:44 +00:00
Merge branch 'master' of ssh://git-verilator-wsnyder/git/verilator
This commit is contained in:
commit
301c878c0f
2
Changes
2
Changes
@ -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++.
|
||||
|
@ -714,17 +714,21 @@ IData VL_FGETS_IXI(int obits, void* destp, IData fpi) {
|
||||
return got;
|
||||
}
|
||||
|
||||
QData VL_FOPEN_QI(QData filename, IData mode) {
|
||||
IData VL_FOPEN_QI(QData filename, IData mode) {
|
||||
IData fnw[2]; VL_SET_WQ(fnw, filename);
|
||||
return VL_FOPEN_WI(2, fnw, mode);
|
||||
}
|
||||
QData VL_FOPEN_WI(int fnwords, WDataInP filenamep, IData mode) {
|
||||
IData VL_FOPEN_WI(int fnwords, WDataInP filenamep, IData mode) {
|
||||
char filenamez[VL_TO_STRING_MAX_WORDS*VL_WORDSIZE+1];
|
||||
_VL_VINT_TO_STRING(fnwords*VL_WORDSIZE, filenamez, filenamep);
|
||||
char modez[5];
|
||||
_VL_VINT_TO_STRING(VL_WORDSIZE, modez, &mode);
|
||||
return VerilatedImp::fdNew(fopen(filenamez,modez));
|
||||
return VL_FOPEN_S(filenamez,modez);
|
||||
}
|
||||
IData VL_FOPEN_S(const char* filenamep, const char* modep) {
|
||||
return VerilatedImp::fdNew(fopen(filenamep,modep));
|
||||
}
|
||||
|
||||
void VL_FCLOSE_I(IData fdi) {
|
||||
FILE* fp = VL_CVT_I_FP(fdi);
|
||||
if (VL_UNLIKELY(!fp)) return;
|
||||
|
@ -324,9 +324,10 @@ extern WDataOutP _vl_moddiv_w(int lbits, WDataOutP owp, WDataInP lwp, WDataInP r
|
||||
/// File I/O
|
||||
extern IData VL_FGETS_IXI(int obits, void* destp, IData fpi);
|
||||
|
||||
extern QData VL_FOPEN_WI(int fnwords, WDataInP ofilename, IData mode);
|
||||
extern QData VL_FOPEN_QI(QData ofilename, IData mode);
|
||||
inline QData VL_FOPEN_II(IData ofilename, IData mode) { return VL_FOPEN_QI(ofilename,mode); }
|
||||
extern IData VL_FOPEN_S(const char* filenamep, const char* mode);
|
||||
extern IData VL_FOPEN_WI(int fnwords, WDataInP ofilename, IData mode);
|
||||
extern IData VL_FOPEN_QI(QData ofilename, IData mode);
|
||||
inline IData VL_FOPEN_II(IData ofilename, IData mode) { return VL_FOPEN_QI(ofilename,mode); }
|
||||
|
||||
extern void VL_FCLOSE_I(IData fdi);
|
||||
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
@ -735,19 +739,26 @@ vpiHandle vpi_put_value(vpiHandle object, p_vpi_value value_p,
|
||||
|
||||
// I/O routines
|
||||
|
||||
//-PLI_UINT32 vpi_mcd_open(PLI_BYTE8 *fileName) {
|
||||
//- _VL_VPI_UNIMP(); return 0;
|
||||
//-}
|
||||
//-PLI_UINT32 vpi_mcd_close(PLI_UINT32 mcd) {
|
||||
//- _VL_VPI_UNIMP(); return 0;
|
||||
//-}
|
||||
//-PLI_BYTE8 *vpi_mcd_name(PLI_UINT32 cd) {
|
||||
//- _VL_VPI_UNIMP(); return 0;
|
||||
//-}
|
||||
//-PLI_INT32 vpi_mcd_printf(PLI_UINT32 mcd, PLI_BYTE8 *format, ...) {
|
||||
PLI_UINT32 vpi_mcd_open(PLI_BYTE8 *filenamep) {
|
||||
return VL_FOPEN_S(filenamep,"wb");
|
||||
}
|
||||
|
||||
PLI_UINT32 vpi_mcd_close(PLI_UINT32 mcd) {
|
||||
VL_FCLOSE_I(mcd); return 0;
|
||||
}
|
||||
|
||||
//-PLI_BYTE8 *vpi_mcd_name(PLI_UINT32 mcd) {
|
||||
//- _VL_VPI_UNIMP(); return 0;
|
||||
//-}
|
||||
|
||||
PLI_INT32 vpi_mcd_printf(PLI_UINT32 mcd, PLI_BYTE8 *formatp, ...) {
|
||||
va_list ap;
|
||||
va_start(ap,formatp);
|
||||
int chars = vpi_mcd_vprintf(mcd, formatp, ap);
|
||||
va_end(ap);
|
||||
return chars;
|
||||
}
|
||||
|
||||
PLI_INT32 vpi_printf(PLI_BYTE8 *formatp, ...) {
|
||||
va_list ap;
|
||||
va_start(ap,formatp);
|
||||
@ -760,15 +771,24 @@ PLI_INT32 vpi_vprintf(PLI_BYTE8* formatp, va_list ap) {
|
||||
return VL_VPRINTF(formatp, ap);
|
||||
}
|
||||
|
||||
//-PLI_INT32 vpi_mcd_vprintf(PLI_UINT32 mcd, PLI_BYTE8 *format, va_list ap) {
|
||||
//- _VL_VPI_UNIMP(); return 0;
|
||||
//-}
|
||||
//-PLI_INT32 vpi_flush(void) {
|
||||
//- _VL_VPI_UNIMP(); return 0;
|
||||
//-}
|
||||
//-PLI_INT32 vpi_mcd_flush(PLI_UINT32 mcd) {
|
||||
//- _VL_VPI_UNIMP(); return 0;
|
||||
//-}
|
||||
PLI_INT32 vpi_mcd_vprintf(PLI_UINT32 mcd, PLI_BYTE8 *format, va_list ap) {
|
||||
FILE* fp = VL_CVT_I_FP(mcd);
|
||||
if (VL_UNLIKELY(!fp)) return 0;
|
||||
int chars = vfprintf(fp, format, ap);
|
||||
return chars;
|
||||
}
|
||||
|
||||
PLI_INT32 vpi_flush(void) {
|
||||
Verilated::flushCall();
|
||||
return 0;
|
||||
}
|
||||
|
||||
PLI_INT32 vpi_mcd_flush(PLI_UINT32 mcd) {
|
||||
FILE* fp = VL_CVT_I_FP(mcd);
|
||||
if (VL_UNLIKELY(!fp)) return 1;
|
||||
fflush(fp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// utility routines
|
||||
|
||||
|
@ -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;
|
||||
|
||||
//======================================================================
|
||||
|
||||
|
||||
@ -72,6 +76,35 @@ public:
|
||||
return __LINE__; \
|
||||
}
|
||||
|
||||
int _mon_check_mcd() {
|
||||
PLI_INT32 status;
|
||||
|
||||
PLI_UINT32 mcd;
|
||||
PLI_BYTE8* filename = (PLI_BYTE8*)"mcd_open.tmp";
|
||||
mcd = vpi_mcd_open(filename);
|
||||
CHECK_RESULT_NZ(mcd);
|
||||
|
||||
{ // Check it got written
|
||||
FILE* fp = fopen(filename,"r");
|
||||
CHECK_RESULT_NZ(fp);
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
status = vpi_mcd_printf(mcd, (PLI_BYTE8*)"hello %s", "vpi_mcd_printf");
|
||||
CHECK_RESULT(status, strlen("hello vpi_mcd_printf"));
|
||||
|
||||
status = vpi_mcd_flush(mcd);
|
||||
CHECK_RESULT(status, 0);
|
||||
|
||||
status = vpi_mcd_close(mcd);
|
||||
CHECK_RESULT(status, 0);
|
||||
|
||||
status = vpi_flush();
|
||||
CHECK_RESULT(status, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _mon_check_callbacks() {
|
||||
t_cb_data cb_data;
|
||||
cb_data.reason = cbEndOfSimulation;
|
||||
@ -87,6 +120,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);
|
||||
@ -245,7 +318,9 @@ int _mon_check_quad() {
|
||||
|
||||
int mon_check() {
|
||||
// Callback from initial block in monitor
|
||||
if (int status = _mon_check_mcd()) return status;
|
||||
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 +330,6 @@ int mon_check() {
|
||||
|
||||
//======================================================================
|
||||
|
||||
unsigned int main_time = false;
|
||||
|
||||
double sc_time_stamp () {
|
||||
return main_time;
|
||||
@ -288,12 +362,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");
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user