mirror of
https://github.com/verilator/verilator.git
synced 2025-01-11 09:07:53 +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.
|
*** 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]
|
**** Fix $display missing leading zeros in %0d, bug367. [Alex Solomatnikov]
|
||||||
|
|
||||||
**** Use 'vluint64_t' for SystemC instead of (same sized) 'uint64' for MSVC++.
|
**** 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;
|
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);
|
IData fnw[2]; VL_SET_WQ(fnw, filename);
|
||||||
return VL_FOPEN_WI(2, fnw, mode);
|
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];
|
char filenamez[VL_TO_STRING_MAX_WORDS*VL_WORDSIZE+1];
|
||||||
_VL_VINT_TO_STRING(fnwords*VL_WORDSIZE, filenamez, filenamep);
|
_VL_VINT_TO_STRING(fnwords*VL_WORDSIZE, filenamez, filenamep);
|
||||||
char modez[5];
|
char modez[5];
|
||||||
_VL_VINT_TO_STRING(VL_WORDSIZE, modez, &mode);
|
_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) {
|
void VL_FCLOSE_I(IData fdi) {
|
||||||
FILE* fp = VL_CVT_I_FP(fdi);
|
FILE* fp = VL_CVT_I_FP(fdi);
|
||||||
if (VL_UNLIKELY(!fp)) return;
|
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
|
/// File I/O
|
||||||
extern IData VL_FGETS_IXI(int obits, void* destp, IData fpi);
|
extern IData VL_FGETS_IXI(int obits, void* destp, IData fpi);
|
||||||
|
|
||||||
extern QData VL_FOPEN_WI(int fnwords, WDataInP ofilename, IData mode);
|
extern IData VL_FOPEN_S(const char* filenamep, const char* mode);
|
||||||
extern QData VL_FOPEN_QI(QData ofilename, IData mode);
|
extern IData VL_FOPEN_WI(int fnwords, WDataInP ofilename, IData mode);
|
||||||
inline QData VL_FOPEN_II(IData ofilename, IData mode) { return VL_FOPEN_QI(ofilename,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);
|
extern void VL_FCLOSE_I(IData fdi);
|
||||||
|
|
||||||
|
@ -95,9 +95,12 @@ typedef PLI_INT32 (*VerilatedPliCb)(struct t_cb_data *);
|
|||||||
|
|
||||||
class VerilatedVpioCb : public VerilatedVpio {
|
class VerilatedVpioCb : public VerilatedVpio {
|
||||||
t_cb_data m_cbData;
|
t_cb_data m_cbData;
|
||||||
|
s_vpi_value m_value;
|
||||||
QData m_time;
|
QData m_time;
|
||||||
public:
|
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() {}
|
virtual ~VerilatedVpioCb() {}
|
||||||
static inline VerilatedVpioCb* castp(vpiHandle h) { return dynamic_cast<VerilatedVpioCb*>((VerilatedVpio*)h); }
|
static inline VerilatedVpioCb* castp(vpiHandle h) { return dynamic_cast<VerilatedVpioCb*>((VerilatedVpio*)h); }
|
||||||
vluint32_t reason() const { return m_cbData.reason; }
|
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",
|
VL_DEBUG_IF_PLI(VL_PRINTF("-vltVpi: value_callback %p %s v[0]=%d\n",
|
||||||
vop,varop->fullname(), *((CData*)newDatap)););
|
vop,varop->fullname(), *((CData*)newDatap)););
|
||||||
memcpy(prevDatap, newDatap, varop->entSize());
|
memcpy(prevDatap, newDatap, varop->entSize());
|
||||||
|
vpi_get_value(vop->cb_datap()->obj, vop->cb_datap()->value);
|
||||||
(vop->cb_rtnp()) (vop->cb_datap());
|
(vop->cb_rtnp()) (vop->cb_datap());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -735,19 +739,26 @@ vpiHandle vpi_put_value(vpiHandle object, p_vpi_value value_p,
|
|||||||
|
|
||||||
// I/O routines
|
// I/O routines
|
||||||
|
|
||||||
//-PLI_UINT32 vpi_mcd_open(PLI_BYTE8 *fileName) {
|
PLI_UINT32 vpi_mcd_open(PLI_BYTE8 *filenamep) {
|
||||||
//- _VL_VPI_UNIMP(); return 0;
|
return VL_FOPEN_S(filenamep,"wb");
|
||||||
//-}
|
}
|
||||||
//-PLI_UINT32 vpi_mcd_close(PLI_UINT32 mcd) {
|
|
||||||
//- _VL_VPI_UNIMP(); return 0;
|
PLI_UINT32 vpi_mcd_close(PLI_UINT32 mcd) {
|
||||||
//-}
|
VL_FCLOSE_I(mcd); return 0;
|
||||||
//-PLI_BYTE8 *vpi_mcd_name(PLI_UINT32 cd) {
|
}
|
||||||
//- _VL_VPI_UNIMP(); return 0;
|
|
||||||
//-}
|
//-PLI_BYTE8 *vpi_mcd_name(PLI_UINT32 mcd) {
|
||||||
//-PLI_INT32 vpi_mcd_printf(PLI_UINT32 mcd, PLI_BYTE8 *format, ...) {
|
|
||||||
//- _VL_VPI_UNIMP(); return 0;
|
//- _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, ...) {
|
PLI_INT32 vpi_printf(PLI_BYTE8 *formatp, ...) {
|
||||||
va_list ap;
|
va_list ap;
|
||||||
va_start(ap,formatp);
|
va_start(ap,formatp);
|
||||||
@ -760,15 +771,24 @@ PLI_INT32 vpi_vprintf(PLI_BYTE8* formatp, va_list ap) {
|
|||||||
return VL_VPRINTF(formatp, ap);
|
return VL_VPRINTF(formatp, ap);
|
||||||
}
|
}
|
||||||
|
|
||||||
//-PLI_INT32 vpi_mcd_vprintf(PLI_UINT32 mcd, PLI_BYTE8 *format, va_list ap) {
|
PLI_INT32 vpi_mcd_vprintf(PLI_UINT32 mcd, PLI_BYTE8 *format, va_list ap) {
|
||||||
//- _VL_VPI_UNIMP(); return 0;
|
FILE* fp = VL_CVT_I_FP(mcd);
|
||||||
//-}
|
if (VL_UNLIKELY(!fp)) return 0;
|
||||||
//-PLI_INT32 vpi_flush(void) {
|
int chars = vfprintf(fp, format, ap);
|
||||||
//- _VL_VPI_UNIMP(); return 0;
|
return chars;
|
||||||
//-}
|
}
|
||||||
//-PLI_INT32 vpi_mcd_flush(PLI_UINT32 mcd) {
|
|
||||||
//- _VL_VPI_UNIMP(); return 0;
|
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
|
// utility routines
|
||||||
|
|
||||||
|
@ -28,6 +28,10 @@
|
|||||||
// __FILE__ is too long
|
// __FILE__ is too long
|
||||||
#define FILENM "t_vpi_var.cpp"
|
#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__; \
|
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() {
|
int _mon_check_callbacks() {
|
||||||
t_cb_data cb_data;
|
t_cb_data cb_data;
|
||||||
cb_data.reason = cbEndOfSimulation;
|
cb_data.reason = cbEndOfSimulation;
|
||||||
@ -87,6 +120,46 @@ int _mon_check_callbacks() {
|
|||||||
return 0;
|
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() {
|
int _mon_check_var() {
|
||||||
VlVpiHandle vh1 = vpi_handle_by_name((PLI_BYTE8*)"t.onebit", NULL);
|
VlVpiHandle vh1 = vpi_handle_by_name((PLI_BYTE8*)"t.onebit", NULL);
|
||||||
CHECK_RESULT_NZ(vh1);
|
CHECK_RESULT_NZ(vh1);
|
||||||
@ -245,7 +318,9 @@ int _mon_check_quad() {
|
|||||||
|
|
||||||
int mon_check() {
|
int mon_check() {
|
||||||
// Callback from initial block in monitor
|
// 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_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_var()) return status;
|
||||||
if (int status = _mon_check_varlist()) return status;
|
if (int status = _mon_check_varlist()) return status;
|
||||||
if (int status = _mon_check_getput()) 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 () {
|
double sc_time_stamp () {
|
||||||
return main_time;
|
return main_time;
|
||||||
@ -288,12 +362,15 @@ int main(int argc, char **argv, char **env) {
|
|||||||
while (sc_time_stamp() < sim_time && !Verilated::gotFinish()) {
|
while (sc_time_stamp() < sim_time && !Verilated::gotFinish()) {
|
||||||
main_time += 1;
|
main_time += 1;
|
||||||
topp->eval();
|
topp->eval();
|
||||||
|
VerilatedVpi::callValueCbs();
|
||||||
topp->clk = !topp->clk;
|
topp->clk = !topp->clk;
|
||||||
//mon_do();
|
//mon_do();
|
||||||
#if VM_TRACE
|
#if VM_TRACE
|
||||||
if (tfp) tfp->dump (main_time);
|
if (tfp) tfp->dump (main_time);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
CHECK_RESULT(callback_count, 501);
|
||||||
|
CHECK_RESULT(callback_count_half, 250);
|
||||||
if (!Verilated::gotFinish()) {
|
if (!Verilated::gotFinish()) {
|
||||||
vl_fatal(FILENM,__LINE__,"main", "%Error: Timeout; never got a $finish");
|
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 [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;
|
integer status;
|
||||||
|
|
||||||
sub sub();
|
sub sub();
|
||||||
@ -34,8 +37,17 @@ module t (/*AUTOARG*/
|
|||||||
if (onebit != 1'b1) $stop;
|
if (onebit != 1'b1) $stop;
|
||||||
if (quads[2] != 62'h12819213_abd31a1c) $stop;
|
if (quads[2] != 62'h12819213_abd31a1c) $stop;
|
||||||
if (quads[3] != 62'h1c77bb9b_3784ea09) $stop;
|
if (quads[3] != 62'h1c77bb9b_3784ea09) $stop;
|
||||||
$write("*-* All Finished *-*\n");
|
end
|
||||||
$finish;
|
|
||||||
|
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
|
end
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
Loading…
Reference in New Issue
Block a user