Fix uvm_hdl_release_and_read not reading release value or checking for success (#7425)
This commit is contained in:
parent
29a93fe5bc
commit
f7a349c5a7
|
|
@ -3402,7 +3402,7 @@ vpiHandle vpi_put_value(vpiHandle object, p_vpi_value valuep, p_vpi_time /*time_
|
|||
vpi_put_value(object, const_cast<p_vpi_value>(&forcedValue), nullptr, vpiNoDelay);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
return object;
|
||||
}
|
||||
|
||||
if (valuep->format == vpiVectorVal) {
|
||||
|
|
|
|||
|
|
@ -40,9 +40,14 @@ module t;
|
|||
chandle h;
|
||||
|
||||
// To cover testing cases, this has non-zero LSB/LO
|
||||
logic [31+8:8] exposed /*verilator public*/;
|
||||
logic [31+8:8] exposed /*verilator public*/ /*verilator forceable*/;
|
||||
logic not_exposed;
|
||||
logic exposed_not_forceable;
|
||||
logic exposed_not_forceable /*verilator public*/;
|
||||
logic [31+8:8] exposedContinuously /*verilator public*/ /*verilator forceable*/;
|
||||
assign exposedContinuously = 32'h0;
|
||||
|
||||
real realSignal /*verilator public*/ /*verilator forceable*/;
|
||||
string stringSignal /*verilator public*/;
|
||||
|
||||
logic [83:4] wide_dec /* verilator public*/;
|
||||
// verilator lint_off ASCRANGE
|
||||
|
|
@ -52,8 +57,15 @@ module t;
|
|||
logic [31:0] mem1d[1:2] /* verilator public*/;
|
||||
logic [31:0] mem2d[1:2][3:4] /* verilator public*/;
|
||||
|
||||
logic [2047:0] tooWide /* verilator public*/ /* verilator forceable*/ = 2048'h0;
|
||||
|
||||
uvm_hdl_data_t lval;
|
||||
|
||||
task releaseExposedContinuously(input logic [31:0] din, output int i);
|
||||
// verilator no_inline_task
|
||||
i = uvm_hdl_release("t.exposedContinuously");
|
||||
endtask
|
||||
|
||||
initial begin
|
||||
// TODO TEST:
|
||||
// extern const char* uvm_dpi_get_next_arg_c(int init);
|
||||
|
|
@ -221,6 +233,56 @@ module t;
|
|||
`checkh(mem2d[2][3], 32'h2300);
|
||||
end
|
||||
|
||||
begin : t_read_bad
|
||||
$display("= uvm_hdl_read bad ranges");
|
||||
$display("===\nUVM Report expected on next line:");
|
||||
i = uvm_hdl_read("t.exposed[10:3]", lval);
|
||||
`checkh(i, 0);
|
||||
$display("===\nUVM Report expected on next line:");
|
||||
i = uvm_hdl_read("t.exposed[99:15]", lval);
|
||||
`checkh(i, 0);
|
||||
|
||||
$display("= uvm_hdl_read empty name (bad)");
|
||||
$display("===\nUVM Report expected on next line:");
|
||||
i = uvm_hdl_read("", lval);
|
||||
`checkh(i, 0);
|
||||
|
||||
$display("= uvm_hdl_read not found (bad)");
|
||||
$display("===\nUVM Report expected on next line:");
|
||||
i = uvm_hdl_read("t.__READ_NOT_FOUND", lval);
|
||||
`checkh(i, 0);
|
||||
|
||||
$display("= uvm_hdl_read with indexed part-select (bad)");
|
||||
$display("===\nUVM Report expected on next line:");
|
||||
i = uvm_hdl_read("t.exposed[15+8:8]", lval);
|
||||
`checkh(i, 0);
|
||||
|
||||
$display("= uvm_hdl_read from real (bad)");
|
||||
$display("===\nUVM Report expected on next line:");
|
||||
i = uvm_hdl_read("t.realSignal", lval);
|
||||
`checkh(i, 0);
|
||||
|
||||
$display("= uvm_hdl_read from string (bad)");
|
||||
$display("===\nUVM Report expected on next line:");
|
||||
i = uvm_hdl_read("t.stringSignal", lval);
|
||||
`checkh(i, 0);
|
||||
|
||||
$display("= uvm_hdl_read producing error message larger than print buffer (bad)");
|
||||
$display("===\nUVM Report expected on next line:");
|
||||
i = uvm_hdl_read(
|
||||
"t.lorem_ipsum_dolor_sit_amet_consetetur_sadipscing_elitr_sed_diam_nonumy_eirmod_tempor_invidunt_ut_labore_et_dolore_magna_aliquyam_erat_sed_diam_voluptua_at_vero_eos_et_accusam_et_justo_duo_dolores_et_ea_rebum_stet_clita_kasd_gubergren_no_sea_takimata_sanctus_est_lorem_ipsum_dolor_sit_amet_lorem_ipsum_dolor_sit_amet_consetetur_sadipscing_elitr_sed_diam_nonumy_eirmod_tempor_invidunt_ut_labore_et_dolore_magna_aliquyam_erat_sed_diam_voluptua_at_vero_eos_et_accusam_et_justo_duo_dolores_et_ea_rebum_stet_clita_kasd_gubergren_no_sea_takimata_sanctus_est_lorem_ipsum_dolor_sit_amet_lorem_ipsum_dolor_sit_amet_consetetur_sadipscing_elitr_sed_diam_nonumy_eirmod_tempor_invidunt_ut_labore_et_dolore_magna_aliquyam_erat_sed_diam_voluptua_at_vero_eos_et_accusam_et_justo_duo_dolores_et_ea_rebum_stet_clita_kasd_gubergren_no_sea_takimata_sanctus_est_lorem_ipsum_dolor_sit_amet_duis_autem_vel_eum_iriure_dolor_in_hendrerit_in_vulputate_velit_esse_molestie_consequat_vel_illum_dolore_eu_feugiat_nulla_facilisis_at_vero",
|
||||
lval
|
||||
);
|
||||
`checkh(i, 0);
|
||||
|
||||
`ifdef VERILATOR
|
||||
$display("= uvm_hdl_read from not exposed (bad)");
|
||||
$display("===\nUVM Report expected on next line:");
|
||||
i = uvm_hdl_read("t.not_exposed", lval);
|
||||
`checkh(i, 0);
|
||||
`endif
|
||||
end
|
||||
|
||||
begin : t_deposit_bad
|
||||
$display("= uvm_hdl_deposit bad ranges");
|
||||
$display("===\nUVM Report expected on next line:");
|
||||
|
|
@ -230,11 +292,40 @@ module t;
|
|||
i = uvm_hdl_deposit("t.exposed[99:15]", lval);
|
||||
`checkh(i, 0);
|
||||
|
||||
$display("= uvm_hdl_deposit empty name (bad)");
|
||||
$display("===\nUVM Report expected on next line:");
|
||||
i = uvm_hdl_deposit("", lval);
|
||||
`checkh(i, 0);
|
||||
|
||||
$display("= uvm_hdl_deposit not found (bad)");
|
||||
$display("===\nUVM Report expected on next line:");
|
||||
i = uvm_hdl_deposit("t.__DEPOSIT_NOT_FOUND", 12);
|
||||
`checkh(i, 0);
|
||||
|
||||
$display("= uvm_hdl_deposit with indexed part-select (bad)");
|
||||
$display("===\nUVM Report expected on next line:");
|
||||
i = uvm_hdl_deposit("t.exposed[15+8:8]", 0);
|
||||
`checkh(i, 0);
|
||||
|
||||
$display("= uvm_hdl_deposit to real (bad)");
|
||||
$display("===\nUVM Report expected on next line:");
|
||||
i = uvm_hdl_deposit("t.realSignal", 0);
|
||||
`checkh(i, 0);
|
||||
|
||||
$display("= uvm_hdl_deposit to string (bad)");
|
||||
$display("===\nUVM Report expected on next line:");
|
||||
i = uvm_hdl_deposit("t.stringSignal", 0);
|
||||
`checkh(i, 0);
|
||||
|
||||
// lval is only 1024 bits, so if vpi_put_value is called on a 2048-bit
|
||||
// signal, it would read out of bounds of lval if unchecked
|
||||
$display("= Test uvm_hdl_deposit to signal wider than UVM_HDL_MAX_WIDTH (bad)");
|
||||
$display("===\nUVM Report expected on next line:");
|
||||
lval = 1024'hAAAA;
|
||||
i = uvm_hdl_deposit("t.tooWide", lval);
|
||||
`checkh(i, 0);
|
||||
`checkh(tooWide, 2048'h0);
|
||||
|
||||
`ifdef VERILATOR
|
||||
$display("= uvm_hdl_deposit to not exposed (bad)");
|
||||
$display("===\nUVM Report expected on next line:");
|
||||
|
|
@ -248,31 +339,192 @@ module t;
|
|||
i = uvm_hdl_read("t.exposed", lval);
|
||||
`checkh(i, 1);
|
||||
`checkh(lval[31:0], exposed);
|
||||
// UNSUPPORTED: force/release via VPI
|
||||
// If support, validate or throw unsupported on force/release part-selects
|
||||
|
||||
$display("= uvm_hdl_force");
|
||||
i = uvm_hdl_force("t.exposed", 62);
|
||||
`checkh(i, 1);
|
||||
exposed = 32'h0; // should have no effect, since signal is being forced
|
||||
`checkh(exposed, 32'd62);
|
||||
|
||||
$display("= uvm_hdl_release");
|
||||
i = uvm_hdl_release("t.exposed");
|
||||
`checkh(i, 1);
|
||||
// exposed is not assigned continuously, so return value is force value
|
||||
`checkh(exposed, 32'd62);
|
||||
exposed = 32'hFFFF_FFFF;
|
||||
`checkh(exposed, 32'hFFFF_FFFF);
|
||||
|
||||
$display("= uvm_hdl_release_and_read");
|
||||
exposed = 32'hFFFF_FFFF;
|
||||
force exposed[31+8:8] = 32'h0;
|
||||
lval = 1024'hFFFF_FFFF;
|
||||
i = uvm_hdl_release_and_read("t.exposed", lval);
|
||||
`checkh(i, 1);
|
||||
// exposed is not assigned continuously, so return value is force value
|
||||
`checkh(lval[31:0], 32'h0);
|
||||
`checkh(exposed, 32'h0);
|
||||
|
||||
end
|
||||
|
||||
begin : t_force_expose_bad
|
||||
begin : t_force_release_continuous
|
||||
$display("= uvm_hdl_force continuously assigned signal");
|
||||
i = uvm_hdl_force("t.exposedContinuously", 62);
|
||||
`checkh(i, 1);
|
||||
`checkh(exposedContinuously, 32'd62);
|
||||
|
||||
force exposedContinuously = 32'hFFFF_FFFF;
|
||||
$display("= uvm_hdl_release continuously assigned signal");
|
||||
releaseExposedContinuously(
|
||||
exposedContinuously,
|
||||
i); // Need to wrap VPI call in task for Verilation to actually check the release value
|
||||
`checkh(i, 1);
|
||||
`checkh(exposedContinuously, 32'h0);
|
||||
|
||||
$display("= uvm_hdl_release_and_read continuously assigned signal");
|
||||
force exposedContinuously[31+8:8] = 32'hFFFF_FFFF;
|
||||
lval = 1024'hFFFF_FFFF;
|
||||
i = uvm_hdl_release_and_read("t.exposedContinuously", lval);
|
||||
`checkh(i, 1);
|
||||
`checkh(lval[31:0], 32'h0);
|
||||
`checkh(t.exposedContinuously, 32'h0);
|
||||
|
||||
end
|
||||
|
||||
begin : t_force_partial
|
||||
// Partial force from SystemVerilog
|
||||
$display("= uvm_hdl_read partially forced signal");
|
||||
force exposed[15+8:8] = 16'h0;
|
||||
exposed = 32'hFFFF_FFFF; // Expect 16 LSBs to stay at 0
|
||||
`checkh(exposed, 32'hFFFF_0000);
|
||||
lval = 1024'hAAAA_AAAA;
|
||||
i = uvm_hdl_read("t.exposed", lval);
|
||||
`checkh(i, 1);
|
||||
`checkh(lval[31:0], exposed);
|
||||
|
||||
$display("= uvm_hdl_release partially forced signal");
|
||||
i = uvm_hdl_release("t.exposed");
|
||||
`checkh(i, 1);
|
||||
`checkh(exposed, 32'hFFFF_0000);
|
||||
exposed = 32'hFFFF_FFFF;
|
||||
`checkh(exposed, 32'hFFFF_FFFF);
|
||||
|
||||
// Partial force through UVM
|
||||
$display("= uvm_hdl_force multi-bit");
|
||||
i = uvm_hdl_force("t.exposed[23:8]", 0); // [15+8:8] is not valid syntax in Verilator
|
||||
`checkh(i, 1);
|
||||
exposed = 32'hFFFF_FFFF; // Expect 16 LSBs to stay at 0
|
||||
`checkh(exposed, 32'hFFFF_0000);
|
||||
|
||||
$display("= uvm_hdl_release_and_read partially forced signal");
|
||||
lval = 1024'h0;
|
||||
i = uvm_hdl_release_and_read("t.exposed", lval);
|
||||
`checkh(i, 1);
|
||||
// exposed is not assigned continuously, so return value is force value
|
||||
`checkh(lval[31:0], 32'hFFFF_0000);
|
||||
`checkh(exposed, 32'hFFFF_0000);
|
||||
exposed = 32'hFFFF_FFFF;
|
||||
`checkh(exposed, 32'hFFFF_FFFF);
|
||||
end
|
||||
|
||||
begin : t_force_partial_continuous
|
||||
$display("= uvm_hdl_force multi-bit continuously assigned signal");
|
||||
i = uvm_hdl_force("t.exposedContinuously[23:8]", 'hFFFF);
|
||||
`checkh(i, 1);
|
||||
`checkh(exposedContinuously, 32'h0000_FFFF);
|
||||
|
||||
$display("= uvm_hdl_release partially forced continuously assigned signal");
|
||||
i = uvm_hdl_release("t.exposedContinuously");
|
||||
`checkh(i, 1);
|
||||
`checkh(exposedContinuously, 32'h0000_0000);
|
||||
|
||||
$display("= uvm_hdl_release_and_read partially forced continuously assigned signal");
|
||||
force exposedContinuously[23:8] = 16'hFFFF;
|
||||
lval = 1024'h0;
|
||||
i = uvm_hdl_release_and_read("t.exposedContinuously", lval);
|
||||
`checkh(i, 1);
|
||||
`checkh(lval[31:0], 32'h0000_0000);
|
||||
`checkh(exposedContinuously, 32'h0000_0000);
|
||||
end
|
||||
|
||||
begin : t_force_single_bit
|
||||
$display("= uvm_hdl_force single bit");
|
||||
exposed = 32'hAAAA_AAAA;
|
||||
i = uvm_hdl_force("t.exposed[16]", 1);
|
||||
`checkh(i, 1);
|
||||
exposed = 32'h0; // should have no effect on bit 16
|
||||
`checkh(exposed, 32'h0000_0100);
|
||||
|
||||
$display("= uvm_hdl_release_and_read single bit");
|
||||
lval = 1024'h0;
|
||||
i = uvm_hdl_release_and_read("t.exposed[16]", lval);
|
||||
`checkh(i, 1);
|
||||
`checkh(lval[31:0], 32'h0000_0001);
|
||||
exposed = 32'hFFFF_FFFF;
|
||||
`checkh(exposed, 32'hFFFF_FFFF);
|
||||
|
||||
$display("= uvm_hdl_force single bit on continuously assigned signal");
|
||||
i = uvm_hdl_force("t.exposedContinuously[16]", 1);
|
||||
`checkh(i, 1);
|
||||
`checkh(exposedContinuously, 32'h0000_0100);
|
||||
|
||||
$display("= uvm_hdl_release_and_read single bit on continuously assigned signal");
|
||||
lval = 1024'h0;
|
||||
i = uvm_hdl_release_and_read("t.exposedContinuously[16]", lval);
|
||||
`checkh(i, 1);
|
||||
`checkh(lval[31:0], 32'h0000_0000);
|
||||
`checkh(exposedContinuously, 32'h0);
|
||||
end
|
||||
|
||||
begin : t_partial_release
|
||||
$display("= uvm_hdl_release_and_read lower 16 bits only");
|
||||
force exposed = 32'h5555_5555;
|
||||
lval = 1024'h0;
|
||||
i = uvm_hdl_release_and_read("t.exposed[23:8]", lval);
|
||||
`checkh(i, 1);
|
||||
`checkh(lval[31:0], 32'h0000_5555);
|
||||
exposed = 32'hFFFF_FFFF;
|
||||
`checkh(exposed, 32'h5555_FFFF);
|
||||
release exposed;
|
||||
|
||||
$display("= uvm_hdl_release upper 16 bits only of continuously assigned signal");
|
||||
force exposedContinuously = 32'h5555_5555;
|
||||
lval = 1024'h0;
|
||||
i = uvm_hdl_release_and_read("t.exposedContinuously[39:24]", lval);
|
||||
`checkh(i, 1);
|
||||
`checkh(lval[31:0], 32'h0000_0000);
|
||||
`checkh(exposedContinuously, 32'h0000_5555);
|
||||
release exposedContinuously;
|
||||
end
|
||||
|
||||
begin : t_force_bad
|
||||
$display("= uvm_hdl_force to not exposed (bad)");
|
||||
$display("===\nUVM Report expected on next line:");
|
||||
i = uvm_hdl_force("t.not_exposed", 12);
|
||||
`checkh(i, 0);
|
||||
|
||||
exposed = 32'hFFFF_FFFF;
|
||||
$display("= uvm_hdl_force with indexed part-select (bad)");
|
||||
$display("===\nUVM Report expected on next line:");
|
||||
i = uvm_hdl_force("t.exposed[15+8:8]", 0);
|
||||
`checkh(i, 0);
|
||||
`checkh(exposed, 32'hFFFF_FFFF);
|
||||
|
||||
$display("= uvm_hdl_force to not forcable (bad)");
|
||||
$display("===\nUVM Report expected on next line:");
|
||||
i = uvm_hdl_force("t.exposed_not_forceable", 12);
|
||||
`checkh(i, 0);
|
||||
|
||||
$display("= uvm_hdl_force to real (bad)");
|
||||
$display("===\nUVM Report expected on next line:");
|
||||
i = uvm_hdl_force("t.realSignal", 0);
|
||||
`checkh(i, 0);
|
||||
|
||||
$display("= uvm_hdl_force to signal wider than UVM_HDL_MAX_WIDTH (bad)");
|
||||
$display("===\nUVM Report expected on next line:");
|
||||
lval = 1024'hAAAA;
|
||||
i = uvm_hdl_force("t.tooWide", lval);
|
||||
`checkh(i, 0);
|
||||
`checkh(tooWide, 2048'h0);
|
||||
end
|
||||
|
||||
$write("*-* All Finished *-*\n");
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
UVM Report t/t_uvm_dpi.v:62: id message
|
||||
UVM Report t/t_uvm_dpi.v:74: id message
|
||||
uvm_dpi_get_tool_name_c() = Verilator
|
||||
= uvm_re
|
||||
= uvm_hdl_check_path
|
||||
|
|
@ -12,36 +12,126 @@ uvm_dpi_get_tool_name_c() = Verilator
|
|||
= uvm_hdl_read/deposit wide ascending
|
||||
= uvm_hdl_read/deposit 1D memory
|
||||
= uvm_hdl_read/deposit 2D memory
|
||||
= uvm_hdl_read bad ranges
|
||||
===
|
||||
UVM Report expected on next line:
|
||||
UVM Report ../../t/uvm/v2017_1_0/dpi/uvm_hdl_verilator.c:85: UVM/DPI/VLOG_GET unable to locate hdl path (t.exposed[10:3])
|
||||
Either the name is incorrect, or you may not have PLI/ACC visibility to that name
|
||||
===
|
||||
UVM Report expected on next line:
|
||||
UVM Report ../../t/uvm/v2017_1_0/dpi/uvm_hdl_verilator.c:85: UVM/DPI/VLOG_GET unable to locate hdl path (t.exposed[99:15])
|
||||
Either the name is incorrect, or you may not have PLI/ACC visibility to that name
|
||||
= uvm_hdl_read empty name (bad)
|
||||
===
|
||||
UVM Report expected on next line:
|
||||
UVM Report ../../t/uvm/v2017_1_0/dpi/uvm_hdl_verilator.c:85: UVM/DPI/VLOG_GET NULL or empty HDL path passed to uvm_hdl_get_vlog
|
||||
= uvm_hdl_read not found (bad)
|
||||
===
|
||||
UVM Report expected on next line:
|
||||
UVM Report ../../t/uvm/v2017_1_0/dpi/uvm_hdl_verilator.c:85: UVM/DPI/VLOG_GET unable to locate hdl path (t.__READ_NOT_FOUND)
|
||||
Either the name is incorrect, or you may not have PLI/ACC visibility to that name
|
||||
= uvm_hdl_read with indexed part-select (bad)
|
||||
===
|
||||
UVM Report expected on next line:
|
||||
UVM Report ../../t/uvm/v2017_1_0/dpi/uvm_hdl_verilator.c:85: UVM/DPI/VLOG_GET unable to locate hdl path (t.exposed[15+8:8])
|
||||
Either the name is incorrect, or you may not have PLI/ACC visibility to that name
|
||||
= uvm_hdl_read from real (bad)
|
||||
===
|
||||
UVM Report expected on next line:
|
||||
UVM Report ../../t/uvm/v2017_1_0/dpi/uvm_hdl_verilator.c:85: UVM/DPI/VLOG_GET failed to get value for hdl path 't.realSignal'. Common reasons include a signal having an unsupported type, such as a real or a string
|
||||
= uvm_hdl_read from string (bad)
|
||||
===
|
||||
UVM Report expected on next line:
|
||||
UVM Report ../../t/uvm/v2017_1_0/dpi/uvm_hdl_verilator.c:85: UVM/DPI/VLOG_GET failed to get value for hdl path 't.stringSignal'. Common reasons include a signal having an unsupported type, such as a real or a string
|
||||
= uvm_hdl_read producing error message larger than print buffer (bad)
|
||||
===
|
||||
UVM Report expected on next line:
|
||||
UVM Report ../../t/uvm/v2017_1_0/dpi/uvm_hdl_verilator.c:85: UVM/DPI/VLOG_GET unable to locate hdl path (t.lorem_ipsum_dolor_sit_amet_consetetur_sadipscing_elitr_sed_diam_nonumy_eirmod_tempor_invidunt_ut_labore_et_dolore_magna_aliquyam_erat_sed_diam_voluptua_at_vero_eos_et_accusam_et_justo_duo_dolores_et_ea_rebum_stet_clita_kasd_gubergren_no_sea_takimata_sanctus_est_lorem_ipsum_dolor_sit_amet_lorem_ipsum_dolor_sit_amet_consetetur_sadipscing_elitr_sed_diam_nonumy_eirmod_tempor_invidunt_ut_labore_et_dolore_magna_aliquyam_erat_sed_diam_voluptua_at_vero_eos_et_accusam_et_justo_duo_dolores_et_ea_rebum_stet_clita_kasd_gubergren_no_sea_takimata_sanctus_est_lorem_ipsum_dolor_sit_amet_lorem_ipsum_dolor_sit_amet_consetetur_sadipscing_elitr_sed_diam_nonumy_eirmod_tempor_invidunt_ut_labore_et_dolore_magna_aliquyam_erat_sed_diam_voluptua_at_vero_eos_et_accusam_et_justo_duo_dolores_et_ea_rebum_stet_clita_kasd_gubergren_no_sea_takimata_sanctus_est_lorem_ipsum_dolor_sit_amet_duis_autem_vel_eum_iriure_dolor_in_hendrerit_in_vulputate_velit_esse_molestie_consequat_vel_illum_dolore_eu_feugiat_nulla_facilisis_at_vero)
|
||||
Either the name is incorrect, or you may not have PLI/ACC visibility to that name
|
||||
= uvm_hdl_read from not exposed (bad)
|
||||
===
|
||||
UVM Report expected on next line:
|
||||
UVM Report ../../t/uvm/v2017_1_0/dpi/uvm_hdl_verilator.c:85: UVM/DPI/VLOG_GET unable to locate hdl path (t.not_exposed)
|
||||
Either the name is incorrect, or you may not have PLI/ACC visibility to that name
|
||||
= uvm_hdl_deposit bad ranges
|
||||
===
|
||||
UVM Report expected on next line:
|
||||
UVM Report ../../t/uvm/v2017_1_0/dpi/uvm_hdl_verilator.c:54: UVM/DPI/HDL_SET set: unable to locate hdl path (t.exposed[10:3])
|
||||
UVM Report ../../t/uvm/v2017_1_0/dpi/uvm_hdl_verilator.c:85: UVM/DPI/VLOG_PUT set: unable to locate hdl path (t.exposed[10:3])
|
||||
Either the name is incorrect, or you may not have PLI/ACC visibility to that name
|
||||
===
|
||||
UVM Report expected on next line:
|
||||
UVM Report ../../t/uvm/v2017_1_0/dpi/uvm_hdl_verilator.c:54: UVM/DPI/HDL_SET set: unable to locate hdl path (t.exposed[99:15])
|
||||
UVM Report ../../t/uvm/v2017_1_0/dpi/uvm_hdl_verilator.c:85: UVM/DPI/VLOG_PUT set: unable to locate hdl path (t.exposed[99:15])
|
||||
Either the name is incorrect, or you may not have PLI/ACC visibility to that name
|
||||
= uvm_hdl_deposit empty name (bad)
|
||||
===
|
||||
UVM Report expected on next line:
|
||||
UVM Report ../../t/uvm/v2017_1_0/dpi/uvm_hdl_verilator.c:85: UVM/DPI/VLOG_PUT NULL or empty HDL path passed to uvm_hdl_set_vlog
|
||||
= uvm_hdl_deposit not found (bad)
|
||||
===
|
||||
UVM Report expected on next line:
|
||||
UVM Report ../../t/uvm/v2017_1_0/dpi/uvm_hdl_verilator.c:54: UVM/DPI/HDL_SET set: unable to locate hdl path (t.__DEPOSIT_NOT_FOUND)
|
||||
UVM Report ../../t/uvm/v2017_1_0/dpi/uvm_hdl_verilator.c:85: UVM/DPI/VLOG_PUT set: unable to locate hdl path (t.__DEPOSIT_NOT_FOUND)
|
||||
Either the name is incorrect, or you may not have PLI/ACC visibility to that name
|
||||
= uvm_hdl_deposit with indexed part-select (bad)
|
||||
===
|
||||
UVM Report expected on next line:
|
||||
UVM Report ../../t/uvm/v2017_1_0/dpi/uvm_hdl_verilator.c:85: UVM/DPI/VLOG_PUT set: unable to locate hdl path (t.exposed[15+8:8])
|
||||
Either the name is incorrect, or you may not have PLI/ACC visibility to that name
|
||||
= uvm_hdl_deposit to real (bad)
|
||||
===
|
||||
UVM Report expected on next line:
|
||||
UVM Report ../../t/uvm/v2017_1_0/dpi/uvm_hdl_verilator.c:85: UVM/DPI/VLOG_PUT failed to set hdl path 't.realSignal'. Common reasons include a signal having an unsupported type, such as a real or a string, or attempting to force a signal that is not marked as /*verilator forceable*/
|
||||
= uvm_hdl_deposit to string (bad)
|
||||
===
|
||||
UVM Report expected on next line:
|
||||
UVM Report ../../t/uvm/v2017_1_0/dpi/uvm_hdl_verilator.c:85: UVM/DPI/VLOG_PUT failed to set hdl path 't.stringSignal'. Common reasons include a signal having an unsupported type, such as a real or a string, or attempting to force a signal that is not marked as /*verilator forceable*/
|
||||
= Test uvm_hdl_deposit to signal wider than UVM_HDL_MAX_WIDTH (bad)
|
||||
===
|
||||
UVM Report expected on next line:
|
||||
UVM Report ../../t/uvm/v2017_1_0/dpi/uvm_hdl_verilator.c:85: UVM/DPI/VLOG_PUT hdl path 't.tooWide' is 2048 bits, but the maximum size is 1024. You can increase the maximum via a compile-time flag: +define+UVM_HDL_MAX_WIDTH=<value>
|
||||
= uvm_hdl_deposit to not exposed (bad)
|
||||
===
|
||||
UVM Report expected on next line:
|
||||
UVM Report ../../t/uvm/v2017_1_0/dpi/uvm_hdl_verilator.c:54: UVM/DPI/HDL_SET set: unable to locate hdl path (t.not_exposed)
|
||||
UVM Report ../../t/uvm/v2017_1_0/dpi/uvm_hdl_verilator.c:85: UVM/DPI/VLOG_PUT set: unable to locate hdl path (t.not_exposed)
|
||||
Either the name is incorrect, or you may not have PLI/ACC visibility to that name
|
||||
= uvm_hdl_force
|
||||
= uvm_hdl_release
|
||||
= uvm_hdl_release_and_read
|
||||
= uvm_hdl_force continuously assigned signal
|
||||
= uvm_hdl_release continuously assigned signal
|
||||
= uvm_hdl_release_and_read continuously assigned signal
|
||||
= uvm_hdl_read partially forced signal
|
||||
= uvm_hdl_release partially forced signal
|
||||
= uvm_hdl_force multi-bit
|
||||
= uvm_hdl_release_and_read partially forced signal
|
||||
= uvm_hdl_force multi-bit continuously assigned signal
|
||||
= uvm_hdl_release partially forced continuously assigned signal
|
||||
= uvm_hdl_release_and_read partially forced continuously assigned signal
|
||||
= uvm_hdl_force single bit
|
||||
= uvm_hdl_release_and_read single bit
|
||||
= uvm_hdl_force single bit on continuously assigned signal
|
||||
= uvm_hdl_release_and_read single bit on continuously assigned signal
|
||||
= uvm_hdl_release_and_read lower 16 bits only
|
||||
= uvm_hdl_release upper 16 bits only of continuously assigned signal
|
||||
= uvm_hdl_force to not exposed (bad)
|
||||
===
|
||||
UVM Report expected on next line:
|
||||
UVM Report ../../t/uvm/v2017_1_0/dpi/uvm_hdl_verilator.c:54: UVM/DPI/HDL_SET set: unable to locate hdl path (t.not_exposed)
|
||||
UVM Report ../../t/uvm/v2017_1_0/dpi/uvm_hdl_verilator.c:85: UVM/DPI/VLOG_PUT set: unable to locate hdl path (t.not_exposed)
|
||||
Either the name is incorrect, or you may not have PLI/ACC visibility to that name
|
||||
= uvm_hdl_force with indexed part-select (bad)
|
||||
===
|
||||
UVM Report expected on next line:
|
||||
UVM Report ../../t/uvm/v2017_1_0/dpi/uvm_hdl_verilator.c:85: UVM/DPI/VLOG_PUT set: unable to locate hdl path (t.exposed[15+8:8])
|
||||
Either the name is incorrect, or you may not have PLI/ACC visibility to that name
|
||||
= uvm_hdl_force to not forcable (bad)
|
||||
===
|
||||
UVM Report expected on next line:
|
||||
UVM Report ../../t/uvm/v2017_1_0/dpi/uvm_hdl_verilator.c:54: UVM/DPI/HDL_SET set: unable to locate hdl path (t.exposed_not_forceable)
|
||||
Either the name is incorrect, or you may not have PLI/ACC visibility to that name
|
||||
UVM Report ../../t/uvm/v2017_1_0/dpi/uvm_hdl_verilator.c:85: UVM/DPI/VLOG_PUT failed to set hdl path 't.exposed_not_forceable'. Common reasons include a signal having an unsupported type, such as a real or a string, or attempting to force a signal that is not marked as /*verilator forceable*/
|
||||
= uvm_hdl_force to real (bad)
|
||||
===
|
||||
UVM Report expected on next line:
|
||||
UVM Report ../../t/uvm/v2017_1_0/dpi/uvm_hdl_verilator.c:85: UVM/DPI/VLOG_PUT failed to set hdl path 't.realSignal'. Common reasons include a signal having an unsupported type, such as a real or a string, or attempting to force a signal that is not marked as /*verilator forceable*/
|
||||
= uvm_hdl_force to signal wider than UVM_HDL_MAX_WIDTH (bad)
|
||||
===
|
||||
UVM Report expected on next line:
|
||||
UVM Report ../../t/uvm/v2017_1_0/dpi/uvm_hdl_verilator.c:85: UVM/DPI/VLOG_PUT hdl path 't.tooWide' is 2048 bits, but the maximum size is 1024. You can increase the maximum via a compile-time flag: +define+UVM_HDL_MAX_WIDTH=<value>
|
||||
*-* All Finished *-*
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
UVM Report t/t_uvm_dpi.v:62: id message
|
||||
UVM Report t/t_uvm_dpi.v:74: id message
|
||||
uvm_dpi_get_tool_name_c() = Verilator
|
||||
= uvm_re
|
||||
= uvm_hdl_check_path
|
||||
|
|
@ -12,36 +12,126 @@ uvm_dpi_get_tool_name_c() = Verilator
|
|||
= uvm_hdl_read/deposit wide ascending
|
||||
= uvm_hdl_read/deposit 1D memory
|
||||
= uvm_hdl_read/deposit 2D memory
|
||||
= uvm_hdl_read bad ranges
|
||||
===
|
||||
UVM Report expected on next line:
|
||||
UVM Report ../../t/uvm/v2020_3_1/dpi/uvm_hdl_verilator.c:85: UVM/DPI/VLOG_GET unable to locate hdl path (t.exposed[10:3])
|
||||
Either the name is incorrect, or you may not have PLI/ACC visibility to that name
|
||||
===
|
||||
UVM Report expected on next line:
|
||||
UVM Report ../../t/uvm/v2020_3_1/dpi/uvm_hdl_verilator.c:85: UVM/DPI/VLOG_GET unable to locate hdl path (t.exposed[99:15])
|
||||
Either the name is incorrect, or you may not have PLI/ACC visibility to that name
|
||||
= uvm_hdl_read empty name (bad)
|
||||
===
|
||||
UVM Report expected on next line:
|
||||
UVM Report ../../t/uvm/v2020_3_1/dpi/uvm_hdl_verilator.c:85: UVM/DPI/VLOG_GET NULL or empty HDL path passed to uvm_hdl_get_vlog
|
||||
= uvm_hdl_read not found (bad)
|
||||
===
|
||||
UVM Report expected on next line:
|
||||
UVM Report ../../t/uvm/v2020_3_1/dpi/uvm_hdl_verilator.c:85: UVM/DPI/VLOG_GET unable to locate hdl path (t.__READ_NOT_FOUND)
|
||||
Either the name is incorrect, or you may not have PLI/ACC visibility to that name
|
||||
= uvm_hdl_read with indexed part-select (bad)
|
||||
===
|
||||
UVM Report expected on next line:
|
||||
UVM Report ../../t/uvm/v2020_3_1/dpi/uvm_hdl_verilator.c:85: UVM/DPI/VLOG_GET unable to locate hdl path (t.exposed[15+8:8])
|
||||
Either the name is incorrect, or you may not have PLI/ACC visibility to that name
|
||||
= uvm_hdl_read from real (bad)
|
||||
===
|
||||
UVM Report expected on next line:
|
||||
UVM Report ../../t/uvm/v2020_3_1/dpi/uvm_hdl_verilator.c:85: UVM/DPI/VLOG_GET failed to get value for hdl path 't.realSignal'. Common reasons include a signal having an unsupported type, such as a real or a string
|
||||
= uvm_hdl_read from string (bad)
|
||||
===
|
||||
UVM Report expected on next line:
|
||||
UVM Report ../../t/uvm/v2020_3_1/dpi/uvm_hdl_verilator.c:85: UVM/DPI/VLOG_GET failed to get value for hdl path 't.stringSignal'. Common reasons include a signal having an unsupported type, such as a real or a string
|
||||
= uvm_hdl_read producing error message larger than print buffer (bad)
|
||||
===
|
||||
UVM Report expected on next line:
|
||||
UVM Report ../../t/uvm/v2020_3_1/dpi/uvm_hdl_verilator.c:85: UVM/DPI/VLOG_GET unable to locate hdl path (t.lorem_ipsum_dolor_sit_amet_consetetur_sadipscing_elitr_sed_diam_nonumy_eirmod_tempor_invidunt_ut_labore_et_dolore_magna_aliquyam_erat_sed_diam_voluptua_at_vero_eos_et_accusam_et_justo_duo_dolores_et_ea_rebum_stet_clita_kasd_gubergren_no_sea_takimata_sanctus_est_lorem_ipsum_dolor_sit_amet_lorem_ipsum_dolor_sit_amet_consetetur_sadipscing_elitr_sed_diam_nonumy_eirmod_tempor_invidunt_ut_labore_et_dolore_magna_aliquyam_erat_sed_diam_voluptua_at_vero_eos_et_accusam_et_justo_duo_dolores_et_ea_rebum_stet_clita_kasd_gubergren_no_sea_takimata_sanctus_est_lorem_ipsum_dolor_sit_amet_lorem_ipsum_dolor_sit_amet_consetetur_sadipscing_elitr_sed_diam_nonumy_eirmod_tempor_invidunt_ut_labore_et_dolore_magna_aliquyam_erat_sed_diam_voluptua_at_vero_eos_et_accusam_et_justo_duo_dolores_et_ea_rebum_stet_clita_kasd_gubergren_no_sea_takimata_sanctus_est_lorem_ipsum_dolor_sit_amet_duis_autem_vel_eum_iriure_dolor_in_hendrerit_in_vulputate_velit_esse_molestie_consequat_vel_illum_dolore_eu_feugiat_nulla_facilisis_at_vero)
|
||||
Either the name is incorrect, or you may not have PLI/ACC visibility to that name
|
||||
= uvm_hdl_read from not exposed (bad)
|
||||
===
|
||||
UVM Report expected on next line:
|
||||
UVM Report ../../t/uvm/v2020_3_1/dpi/uvm_hdl_verilator.c:85: UVM/DPI/VLOG_GET unable to locate hdl path (t.not_exposed)
|
||||
Either the name is incorrect, or you may not have PLI/ACC visibility to that name
|
||||
= uvm_hdl_deposit bad ranges
|
||||
===
|
||||
UVM Report expected on next line:
|
||||
UVM Report ../../t/uvm/v2020_3_1/dpi/uvm_hdl_verilator.c:54: UVM/DPI/HDL_SET set: unable to locate hdl path (t.exposed[10:3])
|
||||
UVM Report ../../t/uvm/v2020_3_1/dpi/uvm_hdl_verilator.c:85: UVM/DPI/VLOG_PUT set: unable to locate hdl path (t.exposed[10:3])
|
||||
Either the name is incorrect, or you may not have PLI/ACC visibility to that name
|
||||
===
|
||||
UVM Report expected on next line:
|
||||
UVM Report ../../t/uvm/v2020_3_1/dpi/uvm_hdl_verilator.c:54: UVM/DPI/HDL_SET set: unable to locate hdl path (t.exposed[99:15])
|
||||
UVM Report ../../t/uvm/v2020_3_1/dpi/uvm_hdl_verilator.c:85: UVM/DPI/VLOG_PUT set: unable to locate hdl path (t.exposed[99:15])
|
||||
Either the name is incorrect, or you may not have PLI/ACC visibility to that name
|
||||
= uvm_hdl_deposit empty name (bad)
|
||||
===
|
||||
UVM Report expected on next line:
|
||||
UVM Report ../../t/uvm/v2020_3_1/dpi/uvm_hdl_verilator.c:85: UVM/DPI/VLOG_PUT NULL or empty HDL path passed to uvm_hdl_set_vlog
|
||||
= uvm_hdl_deposit not found (bad)
|
||||
===
|
||||
UVM Report expected on next line:
|
||||
UVM Report ../../t/uvm/v2020_3_1/dpi/uvm_hdl_verilator.c:54: UVM/DPI/HDL_SET set: unable to locate hdl path (t.__DEPOSIT_NOT_FOUND)
|
||||
UVM Report ../../t/uvm/v2020_3_1/dpi/uvm_hdl_verilator.c:85: UVM/DPI/VLOG_PUT set: unable to locate hdl path (t.__DEPOSIT_NOT_FOUND)
|
||||
Either the name is incorrect, or you may not have PLI/ACC visibility to that name
|
||||
= uvm_hdl_deposit with indexed part-select (bad)
|
||||
===
|
||||
UVM Report expected on next line:
|
||||
UVM Report ../../t/uvm/v2020_3_1/dpi/uvm_hdl_verilator.c:85: UVM/DPI/VLOG_PUT set: unable to locate hdl path (t.exposed[15+8:8])
|
||||
Either the name is incorrect, or you may not have PLI/ACC visibility to that name
|
||||
= uvm_hdl_deposit to real (bad)
|
||||
===
|
||||
UVM Report expected on next line:
|
||||
UVM Report ../../t/uvm/v2020_3_1/dpi/uvm_hdl_verilator.c:85: UVM/DPI/VLOG_PUT failed to set hdl path 't.realSignal'. Common reasons include a signal having an unsupported type, such as a real or a string, or attempting to force a signal that is not marked as /*verilator forceable*/
|
||||
= uvm_hdl_deposit to string (bad)
|
||||
===
|
||||
UVM Report expected on next line:
|
||||
UVM Report ../../t/uvm/v2020_3_1/dpi/uvm_hdl_verilator.c:85: UVM/DPI/VLOG_PUT failed to set hdl path 't.stringSignal'. Common reasons include a signal having an unsupported type, such as a real or a string, or attempting to force a signal that is not marked as /*verilator forceable*/
|
||||
= Test uvm_hdl_deposit to signal wider than UVM_HDL_MAX_WIDTH (bad)
|
||||
===
|
||||
UVM Report expected on next line:
|
||||
UVM Report ../../t/uvm/v2020_3_1/dpi/uvm_hdl_verilator.c:85: UVM/DPI/VLOG_PUT hdl path 't.tooWide' is 2048 bits, but the maximum size is 1024. You can increase the maximum via a compile-time flag: +define+UVM_HDL_MAX_WIDTH=<value>
|
||||
= uvm_hdl_deposit to not exposed (bad)
|
||||
===
|
||||
UVM Report expected on next line:
|
||||
UVM Report ../../t/uvm/v2020_3_1/dpi/uvm_hdl_verilator.c:54: UVM/DPI/HDL_SET set: unable to locate hdl path (t.not_exposed)
|
||||
UVM Report ../../t/uvm/v2020_3_1/dpi/uvm_hdl_verilator.c:85: UVM/DPI/VLOG_PUT set: unable to locate hdl path (t.not_exposed)
|
||||
Either the name is incorrect, or you may not have PLI/ACC visibility to that name
|
||||
= uvm_hdl_force
|
||||
= uvm_hdl_release
|
||||
= uvm_hdl_release_and_read
|
||||
= uvm_hdl_force continuously assigned signal
|
||||
= uvm_hdl_release continuously assigned signal
|
||||
= uvm_hdl_release_and_read continuously assigned signal
|
||||
= uvm_hdl_read partially forced signal
|
||||
= uvm_hdl_release partially forced signal
|
||||
= uvm_hdl_force multi-bit
|
||||
= uvm_hdl_release_and_read partially forced signal
|
||||
= uvm_hdl_force multi-bit continuously assigned signal
|
||||
= uvm_hdl_release partially forced continuously assigned signal
|
||||
= uvm_hdl_release_and_read partially forced continuously assigned signal
|
||||
= uvm_hdl_force single bit
|
||||
= uvm_hdl_release_and_read single bit
|
||||
= uvm_hdl_force single bit on continuously assigned signal
|
||||
= uvm_hdl_release_and_read single bit on continuously assigned signal
|
||||
= uvm_hdl_release_and_read lower 16 bits only
|
||||
= uvm_hdl_release upper 16 bits only of continuously assigned signal
|
||||
= uvm_hdl_force to not exposed (bad)
|
||||
===
|
||||
UVM Report expected on next line:
|
||||
UVM Report ../../t/uvm/v2020_3_1/dpi/uvm_hdl_verilator.c:54: UVM/DPI/HDL_SET set: unable to locate hdl path (t.not_exposed)
|
||||
UVM Report ../../t/uvm/v2020_3_1/dpi/uvm_hdl_verilator.c:85: UVM/DPI/VLOG_PUT set: unable to locate hdl path (t.not_exposed)
|
||||
Either the name is incorrect, or you may not have PLI/ACC visibility to that name
|
||||
= uvm_hdl_force with indexed part-select (bad)
|
||||
===
|
||||
UVM Report expected on next line:
|
||||
UVM Report ../../t/uvm/v2020_3_1/dpi/uvm_hdl_verilator.c:85: UVM/DPI/VLOG_PUT set: unable to locate hdl path (t.exposed[15+8:8])
|
||||
Either the name is incorrect, or you may not have PLI/ACC visibility to that name
|
||||
= uvm_hdl_force to not forcable (bad)
|
||||
===
|
||||
UVM Report expected on next line:
|
||||
UVM Report ../../t/uvm/v2020_3_1/dpi/uvm_hdl_verilator.c:54: UVM/DPI/HDL_SET set: unable to locate hdl path (t.exposed_not_forceable)
|
||||
Either the name is incorrect, or you may not have PLI/ACC visibility to that name
|
||||
UVM Report ../../t/uvm/v2020_3_1/dpi/uvm_hdl_verilator.c:85: UVM/DPI/VLOG_PUT failed to set hdl path 't.exposed_not_forceable'. Common reasons include a signal having an unsupported type, such as a real or a string, or attempting to force a signal that is not marked as /*verilator forceable*/
|
||||
= uvm_hdl_force to real (bad)
|
||||
===
|
||||
UVM Report expected on next line:
|
||||
UVM Report ../../t/uvm/v2020_3_1/dpi/uvm_hdl_verilator.c:85: UVM/DPI/VLOG_PUT failed to set hdl path 't.realSignal'. Common reasons include a signal having an unsupported type, such as a real or a string, or attempting to force a signal that is not marked as /*verilator forceable*/
|
||||
= uvm_hdl_force to signal wider than UVM_HDL_MAX_WIDTH (bad)
|
||||
===
|
||||
UVM Report expected on next line:
|
||||
UVM Report ../../t/uvm/v2020_3_1/dpi/uvm_hdl_verilator.c:85: UVM/DPI/VLOG_PUT hdl path 't.tooWide' is 2048 bits, but the maximum size is 1024. You can increase the maximum via a compile-time flag: +define+UVM_HDL_MAX_WIDTH=<value>
|
||||
*-* All Finished *-*
|
||||
|
|
|
|||
|
|
@ -32,25 +32,56 @@
|
|||
#include "svdpi.h"
|
||||
#include "vpi_user.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
static void m_uvm_error(const char *ID, const char *msg, ...);
|
||||
static int uvm_hdl_set_vlog(char *path, p_vpi_vecval value, PLI_INT32 flag);
|
||||
static int uvm_hdl_get_vlog(char *path, p_vpi_vecval value, PLI_INT32 flag, int partsel);
|
||||
static int uvm_hdl_get_vlog(char *path, p_vpi_vecval value);
|
||||
static int uvm_hdl_max_width();
|
||||
|
||||
// static print buffer
|
||||
static char m_uvm_temp_print_buffer[1024];
|
||||
static char *m_uvm_temp_print_buffer = NULL;
|
||||
static size_t m_uvm_temp_print_buffer_size = 0;
|
||||
|
||||
// static print error
|
||||
static void m_uvm_error(const char *id, const char *msg, ...) {
|
||||
va_list argptr;
|
||||
va_list size_argptr;
|
||||
int msg_size;
|
||||
size_t formatted_msg_size;
|
||||
|
||||
va_start(argptr, msg);
|
||||
vsprintf(m_uvm_temp_print_buffer, msg, argptr);
|
||||
|
||||
va_copy(size_argptr, argptr);
|
||||
msg_size = vsnprintf(NULL, 0, msg, size_argptr);
|
||||
va_end(size_argptr);
|
||||
if (msg_size < 0) {
|
||||
va_end(argptr);
|
||||
m_uvm_report_dpi(M_UVM_ERROR, (char *)id,
|
||||
(char *)"Failed to format UVM DPI error message", M_UVM_NONE,
|
||||
(char *)__FILE__, __LINE__);
|
||||
return;
|
||||
}
|
||||
|
||||
formatted_msg_size = (size_t)msg_size + 1;
|
||||
if (formatted_msg_size > m_uvm_temp_print_buffer_size) {
|
||||
char *const new_buffer = (char *)realloc(m_uvm_temp_print_buffer, formatted_msg_size);
|
||||
if (new_buffer == NULL) {
|
||||
va_end(argptr);
|
||||
m_uvm_report_dpi(M_UVM_ERROR, (char *)id,
|
||||
(char *)"Failed to allocate memory for UVM DPI error message",
|
||||
M_UVM_NONE, (char *)__FILE__, __LINE__);
|
||||
return;
|
||||
}
|
||||
m_uvm_temp_print_buffer = new_buffer;
|
||||
m_uvm_temp_print_buffer_size = formatted_msg_size;
|
||||
}
|
||||
|
||||
vsnprintf(m_uvm_temp_print_buffer, m_uvm_temp_print_buffer_size, msg, argptr);
|
||||
va_end(argptr);
|
||||
m_uvm_report_dpi(M_UVM_ERROR, (char *)id, &m_uvm_temp_print_buffer[0], M_UVM_NONE,
|
||||
|
||||
m_uvm_report_dpi(M_UVM_ERROR, (char *)id, m_uvm_temp_print_buffer, M_UVM_NONE,
|
||||
(char *)__FILE__, __LINE__);
|
||||
}
|
||||
|
||||
|
|
@ -66,9 +97,6 @@ static void m_uvm_error(const char *id, const char *msg, ...) {
|
|||
* If no such variable is found, then the default
|
||||
* width of 1024 is used.
|
||||
*
|
||||
* This function should only get called once or twice,
|
||||
* its return value is cached in the caller.
|
||||
*
|
||||
*/
|
||||
static int UVM_HDL_MAX_WIDTH = 0;
|
||||
static int uvm_hdl_max_width() {
|
||||
|
|
@ -81,99 +109,12 @@ static int uvm_hdl_max_width() {
|
|||
} else {
|
||||
vpi_get_value(ms, &value_s);
|
||||
UVM_HDL_MAX_WIDTH = value_s.value.integer;
|
||||
vpi_release_handle(ms);
|
||||
}
|
||||
}
|
||||
return UVM_HDL_MAX_WIDTH;
|
||||
}
|
||||
|
||||
/*
|
||||
* Internals: Given a path, look at the path name and determine
|
||||
* the handle and any partsel's needed to access it.
|
||||
*/
|
||||
static vpiHandle uvm_hdl_handle_by_name_partsel(char *path, int *is_partsel_ptr, int *hi_ptr,
|
||||
int *lo_ptr) {
|
||||
vpiHandle r;
|
||||
char *path_ptr;
|
||||
char *path_base_ptr;
|
||||
int temp;
|
||||
*is_partsel_ptr = 0;
|
||||
|
||||
if (!path || !path[0]) return 0;
|
||||
|
||||
// If direct lookup works, go with that
|
||||
r = vpi_handle_by_name(path, 0);
|
||||
if (r) return r;
|
||||
|
||||
// Find array subscript
|
||||
path_ptr = (char *)(path + strlen(path) - 1);
|
||||
if (*path_ptr != ']') return 0;
|
||||
|
||||
while (path_ptr != path && *path_ptr != ':' && *path_ptr != '[') --path_ptr;
|
||||
if (path_ptr == path) return 0;
|
||||
*lo_ptr = *hi_ptr = atoi(path_ptr + 1);
|
||||
*is_partsel_ptr = 1;
|
||||
|
||||
if (*path_ptr == ':') {
|
||||
--path_ptr; // back over :
|
||||
|
||||
while (path_ptr != path && *path_ptr != '[') --path_ptr;
|
||||
*hi_ptr = atoi(path_ptr + 1);
|
||||
if (path_ptr == path) return 0;
|
||||
}
|
||||
|
||||
if (*lo_ptr > *hi_ptr) {
|
||||
temp = *lo_ptr;
|
||||
*lo_ptr = *hi_ptr;
|
||||
*hi_ptr = temp;
|
||||
}
|
||||
|
||||
path_base_ptr = strndup(path, (path_ptr - path));
|
||||
|
||||
r = vpi_handle_by_name(path_base_ptr, 0);
|
||||
if (!r) return 0;
|
||||
|
||||
{
|
||||
vpiHandle rh;
|
||||
s_vpi_value value;
|
||||
int req_width_m1;
|
||||
int decl_ranged = 0;
|
||||
int decl_lo;
|
||||
int decl_hi;
|
||||
int decl_left = -1;
|
||||
int decl_right = -1;
|
||||
rh = vpi_handle(vpiLeftRange, r);
|
||||
if (rh) {
|
||||
value.format = vpiIntVal;
|
||||
vpi_get_value(rh, &value);
|
||||
decl_left = value.value.integer;
|
||||
vpi_release_handle(rh);
|
||||
}
|
||||
rh = vpi_handle(vpiRightRange, r);
|
||||
if (rh) {
|
||||
value.format = vpiIntVal;
|
||||
vpi_get_value(rh, &value);
|
||||
decl_ranged = 1;
|
||||
decl_right = value.value.integer;
|
||||
vpi_release_handle(rh);
|
||||
}
|
||||
if (!decl_ranged) {
|
||||
// vpi_printf((PLI_BYTE8 *)"Outside declaration '%s' range %d:%d\n",
|
||||
// path, decl_left, decl_right);
|
||||
return 0;
|
||||
}
|
||||
// vpi_printf((PLI_BYTE8 *)"%s:%d: req %d:%d decl %d:%d for '%s'\n",
|
||||
// __FILE__, __LINE__, *hi_ptr, *lo_ptr, decl_left, decl_right, path);
|
||||
decl_lo = (decl_left > decl_right) ? decl_right : decl_left;
|
||||
decl_hi = (decl_left > decl_right) ? decl_left : decl_right;
|
||||
if (*lo_ptr < decl_lo) return 0;
|
||||
if (*hi_ptr > decl_hi) return 0;
|
||||
req_width_m1 = *hi_ptr - *lo_ptr;
|
||||
*lo_ptr = (decl_left > decl_right) ? (*lo_ptr - decl_lo) : (decl_right - *hi_ptr);
|
||||
*hi_ptr = *lo_ptr + req_width_m1;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
/*
|
||||
* Given a path, look the path name up using the PLI,
|
||||
* and set it to 'value'.
|
||||
|
|
@ -182,24 +123,31 @@ static int uvm_hdl_set_vlog(char *path, p_vpi_vecval value, PLI_INT32 flag) {
|
|||
vpiHandle r;
|
||||
s_vpi_value value_s = {vpiIntVal, {0}};
|
||||
s_vpi_time time_s = {vpiSimTime, 0, 0, 0.0};
|
||||
int is_partsel, hi, lo;
|
||||
int size;
|
||||
int i, size, chunks;
|
||||
static int s_maxsize = -1;
|
||||
|
||||
r = uvm_hdl_handle_by_name_partsel(path, &is_partsel, &hi, &lo);
|
||||
if (path == NULL || path[0] == '\0') {
|
||||
m_uvm_error("UVM/DPI/VLOG_PUT", "NULL or empty HDL path passed to uvm_hdl_set_vlog");
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = vpi_handle_by_name(path, 0);
|
||||
if (r == 0) {
|
||||
m_uvm_error("UVM/DPI/HDL_SET",
|
||||
m_uvm_error("UVM/DPI/VLOG_PUT",
|
||||
"set: unable to locate hdl path (%s)\n Either the name is incorrect, "
|
||||
"or you may not have PLI/ACC visibility to that name",
|
||||
path);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!is_partsel) {
|
||||
value_s.format = vpiVectorVal;
|
||||
value_s.value.vector = value;
|
||||
vpi_put_value(r, &value_s, &time_s, flag);
|
||||
} else {
|
||||
if (value == NULL && flag != vpiReleaseFlag) {
|
||||
m_uvm_error("UVM/DPI/VLOG_PUT",
|
||||
"NULL value pointer passed for hdl path '%s' in non-release operation", path);
|
||||
vpi_release_handle(r);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (value) {
|
||||
if (s_maxsize == -1) s_maxsize = uvm_hdl_max_width();
|
||||
size = vpi_get(vpiSize, r);
|
||||
if (size > s_maxsize) {
|
||||
|
|
@ -211,16 +159,24 @@ static int uvm_hdl_set_vlog(char *path, p_vpi_vecval value, PLI_INT32 flag) {
|
|||
vpi_release_handle(r);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
value_s.format = vpiVectorVal;
|
||||
vpi_get_value(r, &value_s);
|
||||
value_s.format = value ? vpiVectorVal : vpiSuppressVal;
|
||||
value_s.value.vector = value;
|
||||
vpiHandle returnHandle = vpi_put_value(r, &value_s, &time_s, flag);
|
||||
if (returnHandle == 0) {
|
||||
vpi_release_handle(r);
|
||||
m_uvm_error("UVM/DPI/VLOG_PUT",
|
||||
"failed to set hdl path '%s'. Common reasons include a signal having an "
|
||||
"unsupported type, such as a real or a string, or attempting to force a signal "
|
||||
"that is not marked as /*verilator forceable*/",
|
||||
path);
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (int i = 0; i < (((hi - lo + 1) / 32) + 1); ++i) {
|
||||
int subsize = hi - (lo + (i << 5)) + 1;
|
||||
if (subsize > 32) subsize = 32;
|
||||
svPutPartselLogic(&value_s.value.vector[i], value[i], lo + (i << 5), subsize);
|
||||
}
|
||||
vpi_put_value(r, &value_s, &time_s, flag);
|
||||
if (flag == vpiReleaseFlag && value) {
|
||||
chunks = (size - 1) / 32 + 1;
|
||||
for (i = 0; i < chunks; ++i) value[i] = value_s.value.vector[i];
|
||||
}
|
||||
|
||||
vpi_release_handle(r);
|
||||
|
|
@ -232,14 +188,18 @@ static int uvm_hdl_set_vlog(char *path, p_vpi_vecval value, PLI_INT32 flag) {
|
|||
* Given a path, look the path name up using the PLI
|
||||
* and return its 'value'.
|
||||
*/
|
||||
static int uvm_hdl_get_vlog(char *path, p_vpi_vecval value, PLI_INT32 flag, int partsel) {
|
||||
static int uvm_hdl_get_vlog(char *path, p_vpi_vecval value) {
|
||||
static int s_maxsize = -1;
|
||||
int i, size, chunks;
|
||||
vpiHandle r;
|
||||
s_vpi_value value_s;
|
||||
int is_partsel, hi, lo;
|
||||
s_vpi_value value_s = {vpiVectorVal, {0}};
|
||||
|
||||
r = uvm_hdl_handle_by_name_partsel(path, &is_partsel, &hi, &lo);
|
||||
if (path == NULL || path[0] == '\0') {
|
||||
m_uvm_error("UVM/DPI/VLOG_GET", "NULL or empty HDL path passed to uvm_hdl_get_vlog");
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = vpi_handle_by_name(path, 0);
|
||||
if (r == 0) {
|
||||
m_uvm_error("UVM/DPI/VLOG_GET",
|
||||
"unable to locate hdl path (%s)\n Either the name is incorrect, or you "
|
||||
|
|
@ -248,6 +208,12 @@ static int uvm_hdl_get_vlog(char *path, p_vpi_vecval value, PLI_INT32 flag, int
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (value == NULL) {
|
||||
m_uvm_error("UVM/DPI/VLOG_GET", "NULL value pointer passed for hdl path '%s'", path);
|
||||
vpi_release_handle(r);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (s_maxsize == -1) s_maxsize = uvm_hdl_max_width();
|
||||
size = vpi_get(vpiSize, r);
|
||||
if (size > s_maxsize) {
|
||||
|
|
@ -262,18 +228,21 @@ static int uvm_hdl_get_vlog(char *path, p_vpi_vecval value, PLI_INT32 flag, int
|
|||
|
||||
chunks = (size - 1) / 32 + 1;
|
||||
|
||||
value_s.format = vpiVectorVal;
|
||||
value_s.value.vector = NULL;
|
||||
vpi_get_value(r, &value_s);
|
||||
if (value_s.format != vpiVectorVal || value_s.value.vector == 0) {
|
||||
m_uvm_error("UVM/DPI/VLOG_GET",
|
||||
"failed to get value for hdl path '%s'. Common reasons include a signal having an "
|
||||
"unsupported type, such as a real or a string",
|
||||
path);
|
||||
vpi_release_handle(r);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Note upper bits are not cleared, other simulators do likewise
|
||||
if (!is_partsel) {
|
||||
// Keep as separate branch as subroutine can potentially inline and highly optimize
|
||||
for (i = 0; i < chunks; ++i) {
|
||||
value[i].aval = value_s.value.vector[i].aval;
|
||||
value[i].bval = value_s.value.vector[i].bval;
|
||||
}
|
||||
} else {
|
||||
// Verilator supports > 32 bit widths, which is an extension to IEEE DPI
|
||||
svGetPartselLogic(value, value_s.value.vector, lo, hi - lo + 1);
|
||||
for (i = 0; i < chunks; ++i) {
|
||||
value[i].aval = value_s.value.vector[i].aval;
|
||||
value[i].bval = value_s.value.vector[i].bval;
|
||||
}
|
||||
// vpi_printf((PLI_BYTE8 *)"uvm_hdl_get_vlog(%s,%0x)\n", path, value[0].aval);
|
||||
vpi_release_handle(r);
|
||||
|
|
@ -291,7 +260,13 @@ static int uvm_hdl_get_vlog(char *path, p_vpi_vecval value, PLI_INT32 flag, int
|
|||
int uvm_hdl_check_path(char *path) {
|
||||
vpiHandle handle;
|
||||
|
||||
if (path == NULL || path[0] == '\0') {
|
||||
m_uvm_error("UVM/DPI/VLOG_CHECK", "NULL or empty HDL path passed to uvm_hdl_check_path");
|
||||
return 0;
|
||||
}
|
||||
|
||||
handle = vpi_handle_by_name(path, 0);
|
||||
if (handle) vpi_release_handle(handle);
|
||||
return (handle != 0);
|
||||
}
|
||||
|
||||
|
|
@ -299,9 +274,7 @@ int uvm_hdl_check_path(char *path) {
|
|||
* Given a path, look the path name up using the PLI
|
||||
* or the FLI, and return its 'value'.
|
||||
*/
|
||||
int uvm_hdl_read(char *path, p_vpi_vecval value) {
|
||||
return uvm_hdl_get_vlog(path, value, vpiNoDelay, 0);
|
||||
}
|
||||
int uvm_hdl_read(char *path, p_vpi_vecval value) { return uvm_hdl_get_vlog(path, value); }
|
||||
|
||||
/*
|
||||
* Given a path, look the path name up using the PLI
|
||||
|
|
@ -331,7 +304,4 @@ int uvm_hdl_release_and_read(char *path, p_vpi_vecval value) {
|
|||
* Given a path, look the path name up using the PLI
|
||||
* or the FLI, and release it.
|
||||
*/
|
||||
int uvm_hdl_release(char *path) {
|
||||
s_vpi_vecval value;
|
||||
return uvm_hdl_set_vlog(path, &value, vpiReleaseFlag);
|
||||
}
|
||||
int uvm_hdl_release(char *path) { return uvm_hdl_set_vlog(path, NULL, vpiReleaseFlag); }
|
||||
|
|
|
|||
|
|
@ -32,25 +32,56 @@
|
|||
#include "svdpi.h"
|
||||
#include "vpi_user.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
static void m_uvm_error(const char *ID, const char *msg, ...);
|
||||
static int uvm_hdl_set_vlog(char *path, p_vpi_vecval value, PLI_INT32 flag);
|
||||
static int uvm_hdl_get_vlog(char *path, p_vpi_vecval value, PLI_INT32 flag, int partsel);
|
||||
static int uvm_hdl_get_vlog(char *path, p_vpi_vecval value);
|
||||
static int uvm_hdl_max_width();
|
||||
|
||||
// static print buffer
|
||||
static char m_uvm_temp_print_buffer[1024];
|
||||
static char *m_uvm_temp_print_buffer = NULL;
|
||||
static size_t m_uvm_temp_print_buffer_size = 0;
|
||||
|
||||
// static print error
|
||||
static void m_uvm_error(const char *id, const char *msg, ...) {
|
||||
va_list argptr;
|
||||
va_list size_argptr;
|
||||
int msg_size;
|
||||
size_t formatted_msg_size;
|
||||
|
||||
va_start(argptr, msg);
|
||||
vsprintf(m_uvm_temp_print_buffer, msg, argptr);
|
||||
|
||||
va_copy(size_argptr, argptr);
|
||||
msg_size = vsnprintf(NULL, 0, msg, size_argptr);
|
||||
va_end(size_argptr);
|
||||
if (msg_size < 0) {
|
||||
va_end(argptr);
|
||||
m_uvm_report_dpi(M_UVM_ERROR, (char *)id,
|
||||
(char *)"Failed to format UVM DPI error message", M_UVM_NONE,
|
||||
(char *)__FILE__, __LINE__);
|
||||
return;
|
||||
}
|
||||
|
||||
formatted_msg_size = (size_t)msg_size + 1;
|
||||
if (formatted_msg_size > m_uvm_temp_print_buffer_size) {
|
||||
char *const new_buffer = (char *)realloc(m_uvm_temp_print_buffer, formatted_msg_size);
|
||||
if (new_buffer == NULL) {
|
||||
va_end(argptr);
|
||||
m_uvm_report_dpi(M_UVM_ERROR, (char *)id,
|
||||
(char *)"Failed to allocate memory for UVM DPI error message",
|
||||
M_UVM_NONE, (char *)__FILE__, __LINE__);
|
||||
return;
|
||||
}
|
||||
m_uvm_temp_print_buffer = new_buffer;
|
||||
m_uvm_temp_print_buffer_size = formatted_msg_size;
|
||||
}
|
||||
|
||||
vsnprintf(m_uvm_temp_print_buffer, m_uvm_temp_print_buffer_size, msg, argptr);
|
||||
va_end(argptr);
|
||||
m_uvm_report_dpi(M_UVM_ERROR, (char *)id, &m_uvm_temp_print_buffer[0], M_UVM_NONE,
|
||||
|
||||
m_uvm_report_dpi(M_UVM_ERROR, (char *)id, m_uvm_temp_print_buffer, M_UVM_NONE,
|
||||
(char *)__FILE__, __LINE__);
|
||||
}
|
||||
|
||||
|
|
@ -66,9 +97,6 @@ static void m_uvm_error(const char *id, const char *msg, ...) {
|
|||
* If no such variable is found, then the default
|
||||
* width of 1024 is used.
|
||||
*
|
||||
* This function should only get called once or twice,
|
||||
* its return value is cached in the caller.
|
||||
*
|
||||
*/
|
||||
static int UVM_HDL_MAX_WIDTH = 0;
|
||||
static int uvm_hdl_max_width() {
|
||||
|
|
@ -81,99 +109,12 @@ static int uvm_hdl_max_width() {
|
|||
} else {
|
||||
vpi_get_value(ms, &value_s);
|
||||
UVM_HDL_MAX_WIDTH = value_s.value.integer;
|
||||
vpi_release_handle(ms);
|
||||
}
|
||||
}
|
||||
return UVM_HDL_MAX_WIDTH;
|
||||
}
|
||||
|
||||
/*
|
||||
* Internals: Given a path, look at the path name and determine
|
||||
* the handle and any partsel's needed to access it.
|
||||
*/
|
||||
static vpiHandle uvm_hdl_handle_by_name_partsel(char *path, int *is_partsel_ptr, int *hi_ptr,
|
||||
int *lo_ptr) {
|
||||
vpiHandle r;
|
||||
char *path_ptr;
|
||||
char *path_base_ptr;
|
||||
int temp;
|
||||
*is_partsel_ptr = 0;
|
||||
|
||||
if (!path || !path[0]) return 0;
|
||||
|
||||
// If direct lookup works, go with that
|
||||
r = vpi_handle_by_name(path, 0);
|
||||
if (r) return r;
|
||||
|
||||
// Find array subscript
|
||||
path_ptr = (char *)(path + strlen(path) - 1);
|
||||
if (*path_ptr != ']') return 0;
|
||||
|
||||
while (path_ptr != path && *path_ptr != ':' && *path_ptr != '[') --path_ptr;
|
||||
if (path_ptr == path) return 0;
|
||||
*lo_ptr = *hi_ptr = atoi(path_ptr + 1);
|
||||
*is_partsel_ptr = 1;
|
||||
|
||||
if (*path_ptr == ':') {
|
||||
--path_ptr; // back over :
|
||||
|
||||
while (path_ptr != path && *path_ptr != '[') --path_ptr;
|
||||
*hi_ptr = atoi(path_ptr + 1);
|
||||
if (path_ptr == path) return 0;
|
||||
}
|
||||
|
||||
if (*lo_ptr > *hi_ptr) {
|
||||
temp = *lo_ptr;
|
||||
*lo_ptr = *hi_ptr;
|
||||
*hi_ptr = temp;
|
||||
}
|
||||
|
||||
path_base_ptr = strndup(path, (path_ptr - path));
|
||||
|
||||
r = vpi_handle_by_name(path_base_ptr, 0);
|
||||
if (!r) return 0;
|
||||
|
||||
{
|
||||
vpiHandle rh;
|
||||
s_vpi_value value;
|
||||
int req_width_m1;
|
||||
int decl_ranged = 0;
|
||||
int decl_lo;
|
||||
int decl_hi;
|
||||
int decl_left = -1;
|
||||
int decl_right = -1;
|
||||
rh = vpi_handle(vpiLeftRange, r);
|
||||
if (rh) {
|
||||
value.format = vpiIntVal;
|
||||
vpi_get_value(rh, &value);
|
||||
decl_left = value.value.integer;
|
||||
vpi_release_handle(rh);
|
||||
}
|
||||
rh = vpi_handle(vpiRightRange, r);
|
||||
if (rh) {
|
||||
value.format = vpiIntVal;
|
||||
vpi_get_value(rh, &value);
|
||||
decl_ranged = 1;
|
||||
decl_right = value.value.integer;
|
||||
vpi_release_handle(rh);
|
||||
}
|
||||
if (!decl_ranged) {
|
||||
// vpi_printf((PLI_BYTE8 *)"Outside declaration '%s' range %d:%d\n",
|
||||
// path, decl_left, decl_right);
|
||||
return 0;
|
||||
}
|
||||
// vpi_printf((PLI_BYTE8 *)"%s:%d: req %d:%d decl %d:%d for '%s'\n",
|
||||
// __FILE__, __LINE__, *hi_ptr, *lo_ptr, decl_left, decl_right, path);
|
||||
decl_lo = (decl_left > decl_right) ? decl_right : decl_left;
|
||||
decl_hi = (decl_left > decl_right) ? decl_left : decl_right;
|
||||
if (*lo_ptr < decl_lo) return 0;
|
||||
if (*hi_ptr > decl_hi) return 0;
|
||||
req_width_m1 = *hi_ptr - *lo_ptr;
|
||||
*lo_ptr = (decl_left > decl_right) ? (*lo_ptr - decl_lo) : (decl_right - *hi_ptr);
|
||||
*hi_ptr = *lo_ptr + req_width_m1;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
/*
|
||||
* Given a path, look the path name up using the PLI,
|
||||
* and set it to 'value'.
|
||||
|
|
@ -182,24 +123,31 @@ static int uvm_hdl_set_vlog(char *path, p_vpi_vecval value, PLI_INT32 flag) {
|
|||
vpiHandle r;
|
||||
s_vpi_value value_s = {vpiIntVal, {0}};
|
||||
s_vpi_time time_s = {vpiSimTime, 0, 0, 0.0};
|
||||
int is_partsel, hi, lo;
|
||||
int size;
|
||||
int i, size, chunks;
|
||||
static int s_maxsize = -1;
|
||||
|
||||
r = uvm_hdl_handle_by_name_partsel(path, &is_partsel, &hi, &lo);
|
||||
if (path == NULL || path[0] == '\0') {
|
||||
m_uvm_error("UVM/DPI/VLOG_PUT", "NULL or empty HDL path passed to uvm_hdl_set_vlog");
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = vpi_handle_by_name(path, 0);
|
||||
if (r == 0) {
|
||||
m_uvm_error("UVM/DPI/HDL_SET",
|
||||
m_uvm_error("UVM/DPI/VLOG_PUT",
|
||||
"set: unable to locate hdl path (%s)\n Either the name is incorrect, "
|
||||
"or you may not have PLI/ACC visibility to that name",
|
||||
path);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!is_partsel) {
|
||||
value_s.format = vpiVectorVal;
|
||||
value_s.value.vector = value;
|
||||
vpi_put_value(r, &value_s, &time_s, flag);
|
||||
} else {
|
||||
if (value == NULL && flag != vpiReleaseFlag) {
|
||||
m_uvm_error("UVM/DPI/VLOG_PUT",
|
||||
"NULL value pointer passed for hdl path '%s' in non-release operation", path);
|
||||
vpi_release_handle(r);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (value) {
|
||||
if (s_maxsize == -1) s_maxsize = uvm_hdl_max_width();
|
||||
size = vpi_get(vpiSize, r);
|
||||
if (size > s_maxsize) {
|
||||
|
|
@ -211,16 +159,24 @@ static int uvm_hdl_set_vlog(char *path, p_vpi_vecval value, PLI_INT32 flag) {
|
|||
vpi_release_handle(r);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
value_s.format = vpiVectorVal;
|
||||
vpi_get_value(r, &value_s);
|
||||
value_s.format = value ? vpiVectorVal : vpiSuppressVal;
|
||||
value_s.value.vector = value;
|
||||
vpiHandle returnHandle = vpi_put_value(r, &value_s, &time_s, flag);
|
||||
if (returnHandle == 0) {
|
||||
vpi_release_handle(r);
|
||||
m_uvm_error("UVM/DPI/VLOG_PUT",
|
||||
"failed to set hdl path '%s'. Common reasons include a signal having an "
|
||||
"unsupported type, such as a real or a string, or attempting to force a signal "
|
||||
"that is not marked as /*verilator forceable*/",
|
||||
path);
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (int i = 0; i < (((hi - lo + 1) / 32) + 1); ++i) {
|
||||
int subsize = hi - (lo + (i << 5)) + 1;
|
||||
if (subsize > 32) subsize = 32;
|
||||
svPutPartselLogic(&value_s.value.vector[i], value[i], lo + (i << 5), subsize);
|
||||
}
|
||||
vpi_put_value(r, &value_s, &time_s, flag);
|
||||
if (flag == vpiReleaseFlag && value) {
|
||||
chunks = (size - 1) / 32 + 1;
|
||||
for (i = 0; i < chunks; ++i) value[i] = value_s.value.vector[i];
|
||||
}
|
||||
|
||||
vpi_release_handle(r);
|
||||
|
|
@ -232,14 +188,18 @@ static int uvm_hdl_set_vlog(char *path, p_vpi_vecval value, PLI_INT32 flag) {
|
|||
* Given a path, look the path name up using the PLI
|
||||
* and return its 'value'.
|
||||
*/
|
||||
static int uvm_hdl_get_vlog(char *path, p_vpi_vecval value, PLI_INT32 flag, int partsel) {
|
||||
static int uvm_hdl_get_vlog(char *path, p_vpi_vecval value) {
|
||||
static int s_maxsize = -1;
|
||||
int i, size, chunks;
|
||||
vpiHandle r;
|
||||
s_vpi_value value_s;
|
||||
int is_partsel, hi, lo;
|
||||
s_vpi_value value_s = {vpiVectorVal, {0}};
|
||||
|
||||
r = uvm_hdl_handle_by_name_partsel(path, &is_partsel, &hi, &lo);
|
||||
if (path == NULL || path[0] == '\0') {
|
||||
m_uvm_error("UVM/DPI/VLOG_GET", "NULL or empty HDL path passed to uvm_hdl_get_vlog");
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = vpi_handle_by_name(path, 0);
|
||||
if (r == 0) {
|
||||
m_uvm_error("UVM/DPI/VLOG_GET",
|
||||
"unable to locate hdl path (%s)\n Either the name is incorrect, or you "
|
||||
|
|
@ -248,6 +208,12 @@ static int uvm_hdl_get_vlog(char *path, p_vpi_vecval value, PLI_INT32 flag, int
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (value == NULL) {
|
||||
m_uvm_error("UVM/DPI/VLOG_GET", "NULL value pointer passed for hdl path '%s'", path);
|
||||
vpi_release_handle(r);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (s_maxsize == -1) s_maxsize = uvm_hdl_max_width();
|
||||
size = vpi_get(vpiSize, r);
|
||||
if (size > s_maxsize) {
|
||||
|
|
@ -262,18 +228,21 @@ static int uvm_hdl_get_vlog(char *path, p_vpi_vecval value, PLI_INT32 flag, int
|
|||
|
||||
chunks = (size - 1) / 32 + 1;
|
||||
|
||||
value_s.format = vpiVectorVal;
|
||||
value_s.value.vector = NULL;
|
||||
vpi_get_value(r, &value_s);
|
||||
if (value_s.format != vpiVectorVal || value_s.value.vector == 0) {
|
||||
m_uvm_error("UVM/DPI/VLOG_GET",
|
||||
"failed to get value for hdl path '%s'. Common reasons include a signal having an "
|
||||
"unsupported type, such as a real or a string",
|
||||
path);
|
||||
vpi_release_handle(r);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Note upper bits are not cleared, other simulators do likewise
|
||||
if (!is_partsel) {
|
||||
// Keep as separate branch as subroutine can potentially inline and highly optimize
|
||||
for (i = 0; i < chunks; ++i) {
|
||||
value[i].aval = value_s.value.vector[i].aval;
|
||||
value[i].bval = value_s.value.vector[i].bval;
|
||||
}
|
||||
} else {
|
||||
// Verilator supports > 32 bit widths, which is an extension to IEEE DPI
|
||||
svGetPartselLogic(value, value_s.value.vector, lo, hi - lo + 1);
|
||||
for (i = 0; i < chunks; ++i) {
|
||||
value[i].aval = value_s.value.vector[i].aval;
|
||||
value[i].bval = value_s.value.vector[i].bval;
|
||||
}
|
||||
// vpi_printf((PLI_BYTE8 *)"uvm_hdl_get_vlog(%s,%0x)\n", path, value[0].aval);
|
||||
vpi_release_handle(r);
|
||||
|
|
@ -291,7 +260,13 @@ static int uvm_hdl_get_vlog(char *path, p_vpi_vecval value, PLI_INT32 flag, int
|
|||
int uvm_hdl_check_path(char *path) {
|
||||
vpiHandle handle;
|
||||
|
||||
if (path == NULL || path[0] == '\0') {
|
||||
m_uvm_error("UVM/DPI/VLOG_CHECK", "NULL or empty HDL path passed to uvm_hdl_check_path");
|
||||
return 0;
|
||||
}
|
||||
|
||||
handle = vpi_handle_by_name(path, 0);
|
||||
if (handle) vpi_release_handle(handle);
|
||||
return (handle != 0);
|
||||
}
|
||||
|
||||
|
|
@ -299,9 +274,7 @@ int uvm_hdl_check_path(char *path) {
|
|||
* Given a path, look the path name up using the PLI
|
||||
* or the FLI, and return its 'value'.
|
||||
*/
|
||||
int uvm_hdl_read(char *path, p_vpi_vecval value) {
|
||||
return uvm_hdl_get_vlog(path, value, vpiNoDelay, 0);
|
||||
}
|
||||
int uvm_hdl_read(char *path, p_vpi_vecval value) { return uvm_hdl_get_vlog(path, value); }
|
||||
|
||||
/*
|
||||
* Given a path, look the path name up using the PLI
|
||||
|
|
@ -331,7 +304,4 @@ int uvm_hdl_release_and_read(char *path, p_vpi_vecval value) {
|
|||
* Given a path, look the path name up using the PLI
|
||||
* or the FLI, and release it.
|
||||
*/
|
||||
int uvm_hdl_release(char *path) {
|
||||
s_vpi_vecval value;
|
||||
return uvm_hdl_set_vlog(path, &value, vpiReleaseFlag);
|
||||
}
|
||||
int uvm_hdl_release(char *path) { return uvm_hdl_set_vlog(path, NULL, vpiReleaseFlag); }
|
||||
|
|
|
|||
Loading…
Reference in New Issue