VUnit / vunit

VUnit is a unit testing framework for VHDL/SystemVerilog
http://vunit.github.io/
Other
739 stars 263 forks source link

.dat input files not found #589

Closed haggaie closed 4 years ago

haggaie commented 4 years ago

I'm trying to simulate Verilog modules that are generated automatically using Vivado HLS. Some of these modules refer to auxiliary input files that initialize arrays (using $readmemh). Usually, Vivado copies the files to the current directory of the simulator before running the simulator. Is there a standard way of doing this with vunit?

trailbound commented 4 years ago

I concur! Would be nice if VUnit would provide a clean, standard way to copy files into the working directory of the simulation run prior to simulation start. Or at least provide the simulation working directory in the pre_config hook.

I've run into this issue as well using a Vivado+Questasim flow. There are multiple file types to load memories or coefficients that Vivado expects to be copied into the working directory of the simulation run prior to simulation. I worked around the issue by using a pre_config hook and adding a relative reference to the output_path in order to copy files into the simulation working directory, but this is ugly.

The work around goes something like this:

from shutil import copyfile

class Configurator:
    def pre_config(self, output_path):
        # Copy files to the working directory of the simulation run.
        copyfile(join(ip_path, "fir_compiler_0/fir_compiler_0.mif"), join(output_path, '../../modelsim/fir_compiler_0.mif'))
        copyfile(join(ip_path, "fir_compiler_0/filter_coef.coe"), join(output_path, '../../modelsim/filter_coef.coe'))
        return True

c = Configurator()

tb = tb_lib.test_bench('demo_tb')
t = tb.test('demo_test')
t.set_pre_config(c.pre_config)
eine commented 4 years ago

AFAIK, in VUnit there is no concept such as the working directory of the simulation. All the paths that are provided to the simulators are absolute paths, so that it is not relevant where is the simulator called from. For example, you can add print(cmd) in https://github.com/VUnit/vunit/blob/master/vunit/sim_if/ghdl.py#L292. Executing example array_axis_vcs will show:

'/usr/local/bin/ghdl'
'--elab-run'
'--std=08'
'--work=lib'
'--workdir=/src/examples/vhdl/array_axis_vcs/vunit_out/ghdl/libraries/lib'
'-P/src/examples/vhdl/array_axis_vcs/vunit_out/ghdl/libraries/vunit_lib'
'-P/src/examples/vhdl/array_axis_vcs/vunit_out/ghdl/libraries/osvvm'
'-P/src/examples/vhdl/array_axis_vcs/vunit_out/ghdl/libraries/lib'
'-o'
'/src/examples/vhdl/array_axis_vcs/vunit_out/test_output/lib.tb_axis_loop.test_260bb5c8c675e898eca5dc9024a4420ede12c0bc/ghdl/tb_axis_loop-tb'
'tb_axis_loop'
'tb'
'-gtb_path=/src/examples/vhdl/array_axis_vcs/src/test/'
'-grunner_cfg=active python runner : true,enabled_test_cases : test,output path : /src/examples/vhdl/array_axis_vcs/vunit_out/test_output/lib.tb_axis_loop.test_260bb5c8c675e898eca5dc9024a4420ede12c0bc/,tb path : /src/examples/vhdl/array_axis_vcs/src/test/,use_color : true', '--assert-level=error']

I think that the standard way to handle this would be to use tb_path (see http://vunit.github.io/user_guide.html#special-generics-parameters). You would put the files in a location relative to the testbench and fix HDL sources to prepend paths with tb_path.

@trailbound, note that join(output_path, '..', '..') is equal to join(dirname(__file__), 'vunit_out'), i.e., a subdir which is a sibling of run.py. Hence, it seems that you don't need pre_config to copy the *.mif and *.coe files. You can mkdir -p vunit_out/modelsim and cp them before running run.py. Of course, you can do it in Python too; the point is that you don't need output_path because you are using no specific info besides name vunit_out, which you will know if you change the default.

BTW, join(output_path, '../../modelsim/fir_compiler_0.mif') might not work on Windows. It is better to use join(output_path, '..', '..', 'modelsim', 'fir_compiler_0.mif').

kraigher commented 4 years ago

See this discussion for a solution: https://github.com/VUnit/vunit/issues/236

haggaie commented 4 years ago

Thanks everyone.

I prefer not to change the source Verilog files as they are auto-generated from HLS. I used a solution that copies in the pre_config function, even though I agree that passing a tb_path parameter would be cleaner.

curiousengineer commented 3 years ago

Is it true that a "proper" method has not yet been created for this in VUnit even though this problem has been going on for some years now?

With my Qsys design simulation system, there is always a TCL script generated to simulate the design. It contains a function to copy the memory files into a location local to the simulator. Here is the excerpt from rivierapro_setup.tcl:

# Copy ROM/RAM files to simulation directory
alias file_copy {
  echo "\[exec\] file_copy"
  file copy -force $QSYS_SIMDIR/submodules/SPRINT_OSI_S_mem_if_ddr2_emif_0_s0_AC_ROM.hex ./
  file copy -force $QSYS_SIMDIR/submodules/SPRINT_OSI_S_mem_if_ddr2_emif_0_s0_inst_ROM.hex ./
  file copy -force $QSYS_SIMDIR/submodules/SPRINT_OSI_S_NiosII_cpu_bht_ram.dat ./
  file copy -force $QSYS_SIMDIR/submodules/SPRINT_OSI_S_NiosII_cpu_bht_ram.hex ./
  file copy -force $QSYS_SIMDIR/submodules/SPRINT_OSI_S_NiosII_cpu_bht_ram.mif ./
  file copy -force $QSYS_SIMDIR/submodules/SPRINT_OSI_S_NiosII_cpu_dc_tag_ram.dat ./
  file copy -force $QSYS_SIMDIR/submodules/SPRINT_OSI_S_NiosII_cpu_dc_tag_ram.hex ./
  file copy -force $QSYS_SIMDIR/submodules/SPRINT_OSI_S_NiosII_cpu_dc_tag_ram.mif ./
  file copy -force $QSYS_SIMDIR/submodules/SPRINT_OSI_S_NiosII_cpu_ic_tag_ram.dat ./
  file copy -force $QSYS_SIMDIR/submodules/SPRINT_OSI_S_NiosII_cpu_ic_tag_ram.hex ./
  file copy -force $QSYS_SIMDIR/submodules/SPRINT_OSI_S_NiosII_cpu_ic_tag_ram.mif ./
  file copy -force $QSYS_SIMDIR/submodules/SPRINT_OSI_S_NiosII_cpu_ociram_default_contents.dat ./
  file copy -force $QSYS_SIMDIR/submodules/SPRINT_OSI_S_NiosII_cpu_ociram_default_contents.hex ./
  file copy -force $QSYS_SIMDIR/submodules/SPRINT_OSI_S_NiosII_cpu_ociram_default_contents.mif ./
  file copy -force $QSYS_SIMDIR/submodules/SPRINT_OSI_S_NiosII_cpu_rf_ram_a.dat ./
  file copy -force $QSYS_SIMDIR/submodules/SPRINT_OSI_S_NiosII_cpu_rf_ram_a.hex ./
  file copy -force $QSYS_SIMDIR/submodules/SPRINT_OSI_S_NiosII_cpu_rf_ram_a.mif ./
  file copy -force $QSYS_SIMDIR/submodules/SPRINT_OSI_S_NiosII_cpu_rf_ram_b.dat ./
  file copy -force $QSYS_SIMDIR/submodules/SPRINT_OSI_S_NiosII_cpu_rf_ram_b.hex ./
  file copy -force $QSYS_SIMDIR/submodules/SPRINT_OSI_S_NiosII_cpu_rf_ram_b.mif ./
}

Now how do I make VUnit do this?

Does VUnit provide a method to pass a TCL script to the simulator that can be run just before simulation starts or just after simulation ends? Or, is everything bound to Python scripting?

Ahmad-Zaklouta commented 2 years ago

Hence, it seems that you don't need pre_config to copy the *.mif and *.coe files. You can mkdir -p vunit_out/modelsim and cp them before running run.py. Of course, you can do it in Python too; the point is that you don't need output_path because you are using no specific info besides name vunit_out, which you will know if you change the default.

@eine

Aren't these files suppose to be in the directory of the testcase itself? or is it enough to be in vunit_out/modelsim directory?

LarsAsplund commented 2 years ago

@curiousengineer The proper method with VUnit is to use pre_config and copy files to the simulator working directory using the simulator_output_path argument. See https://vunit.github.io/py/ui.html#pre-and-post-simulation-hooks

For sourcing TCL scripts before the simulation have a look at https://vunit.github.io/py/opts.html#simulation-options