Multiple VVCs question (1 testbench, 1 test harness, 1 test sequencer process?)

Hi Marius,

The FPGA has different modules which require to be verified in Simulation.

Currently using UVVM & building the BFMs / VVCs to verify different individual FPGA modules. Using at the moment 1 testbench (TB instantiates 1 test harness, a clock generator and a Test Sequencer process) & 1 test harness (Test harness instantiates uvvm_engine, 1 DUT and 1 VVC related to the DUT)

Is it better to instantiate the clock generator within the testbench or test harness? I currently have it instantiated within the testbench. If in the testbench, can use potentially the same clock generator clocking to different harnesses (if more than 1 harness is the preferable choice). But each time clocking the clock generator it will delay the other DUT module unit and it will be tested eg one clock cycle later (via the one Test Sequencer process that resides in the single TB). Any comments here will be appreciated.

So far I used 1 VVC instantiated within the test harness and 1 DUT. VVC was developed to verify the specific DUT.

Within the test harness can we instantiate all the VVCs + different DUTs or do we need a different test harness per related VVCs/DUT ?
What about the testbench? Different one per related test harness/VVCs/DUT too?

Reason for asking is because I currently have 2 small VHDL modules (ie 2 different DUTs within the FPGA) which I developed BFMs & VVCs for them. Verified in simulation one of them using UVVM VVC platform scripts. Currently developing the platform for the other one.

Can I use 1 common testbench for both of them and 1 separate test harness (ie 2 instances within the testbench) for each related DUT/VVCs and use the same ie 1 test sequencer process of the TB to execute the various commands?

Your prompt reply to this matter will be appreciated.

Kind regards,
Kevin

Hi Marius,

I did not receive a reply to the above yet. It could be due to the weekend involved.

Can we use a common testbench (ie 1 testbench) for both DUTs? Do we require to use 2 different test harnesses (ie 2 different test harness instantiations within the testbench) for verifying the 2 different DUTs together with 1 testbench? Is this the right flow?

or do we just need to create 1 testbench / 1 test harness / 1 Test Sequencer per DUT or place all the DUTs, VVCs instances in 1 test harness (that uses 1 testbench)?

→ So far seen that can simulate standalone both DUTs with 1 testbench and 1 test harness each independently.

What is the flow/method of simulating 2 different FPGA internal modules together in UVVM VVC?

Can you please explain / clarify this?


I tried to use 1 common testbench, 2 test harnesses wrt 2 different related DUTs/VVCs. Don’t know if this method is the right one to follow…

The 2 different DUTs are eg ‘clockcyclecounter’ & ‘checkstable’.

The python script generated the same .vhd names for the following:
vvc_cmd_pkg.vhd
vvc_context.vhd
vvc_methods_pkg.vhd

The other 2 names were unique: (xx represents either ‘clockcyclecounter’ or ‘checkstable’ names)
xx_bfm_pkg.vhd
xx_vvc.vhd

I updated then the template files for both DUTs. Simulated standalone the 1st one the Counter one (clockcyclecounter) and works ok. Simulated the 2nd one (checkstable) with just checkstable_reset procedure added. That was ok standalone. So standalone I had 1 testbench and 1 testharness for each DUT/VVCs.

Main aim with this combined 1 testbench method is to see if 1 testbench can call individually the VVC commands for each DUT.

However, experienced complilation issues and decided to the compile then for each DUT all relevant following files in a different -work xxx library:

xx_bfm_pkg.vhd
xx_vvc_cmd_pkg.vhd
td_target_support_pkg.vhd
vvc_methods_pkg.vhd
td_queue_pkg.vhd
td_vvc_framework_common_methods_pkg.vhd
td_vvc_entity_support_pkg.vhd
xx_vvc.vhd
vvc_context.vhd
xx_vvc_th.vhd (test harness)

For the combined 1 testbench tried to compile this to the work library (ie -work work)
combined_tb.vhd (combined testbench)

I still get lots of compilation errors at the moment:

eg ** Error: …/…/tb/Combined_tb.vhd(104): (vcom-1078) Identifier “C_CLK_PERIOD” is not directly visible.

Potentially visible declarations are:

user_checkstable.checkstable_bfm_pkg.C_CLK_PERIOD at …/…/checkStable/src/checkstable_bfm_pkg.vhd(23) (constant)

user_clockcyclecounter.clockcyclecounter_bfm_pkg.C_CLK_PERIOD at …/…/ClockCycleCounter/src/clockcyclecounter_bfm_pkg.vhd(29) (constant)

Line 104:
i_clock_generator_vvc : entity bitvis_vip_clock_generator.clock_generator_vvc
generic map(
GC_INSTANCE_IDX => C_CLOCK_GEN,
GC_CLOCK_NAME => “Clock”,
GC_CLOCK_PERIOD => C_CLK_PERIOD, ← line 103
GC_CLOCK_HIGH_TIME => C_CLK_PERIOD / 2 ← line 104
)
port map(
clk => in_clock
);

Line 103 reported same error.

:::

** Error: …/…/tb/Combined_tb.vhd(138): (vcom-1600) No feasible entries for subprogram “set_clock_high_time”

line 138:
set_clock_high_time(CLOCK_GENERATOR_VVCT, 1, C_CLK_PERIOD/2, “Changing the duty cycle to 50%”, C_SCOPE);

Visible subprograms are:

(explicit) vvc_methods_pkg.set_clock_high_time[bitvis_vip_clock_generator.td_target_support_pkg.t_vvc_target_record, INTEGER, std.STANDARD.TIME, std.STANDARD.STRING, std.STANDARD.STRING] at …/…/bitvis_vip_clock_generator/

Awaiting for your reply to this matter.

Kind regards,
Kevin

Hi Kevin,

I would use the Clock Generator VVC to run the clock and put this in the test harness, while controlling it from the test sequencer. You should have all you test components inside the test harness, so for different test cases you only switch which testbench, i.e. test sequencer, to run. So, for 10 test cases you will typically have 10 testbenches/sequencers, and only 1 test harness that will have all the VVCs and the DUT.
When you have more than one DUT you can:

  1. Have a single test harness with both DUTs, but with different Clock Generator VVC instences to run their clocks or individual resets to prevent both DUTs from running at the same time, or
  2. Have multiple test harnesses, one for each DUT.

It depends on the complexity of your design, how related the two DUTs are etc, but I would probably have gone for number 1.

For the error you are receiving for the C_CLOCK_PERIOD is because there are two constants with the C_CLOCK_PERIOD name that are visible from combined_tb.vhd. One is in there checkstable_bfm_pkg and one is in the clockcyclecounter_bfm_pkg. You should only have one, and it should be defined in the testbench or test harness. You can set the BFM config record with the clock period using the
shared_<VVC_NAME>_vvc_config(<VVC_INSTANCE_NUMBER).bfm_config.<BFM_CONFIG_PARAMETER> := <CONFIG_PARAMETER_VALUE>;
in the beginning of your test sequencer, after

await_uvvm_initialization(VOID);

Passing the C_CLOCK_PERIOD constant value from the testbench to test harness can be done by port mapping in the test harness entity.

Br,
Marius

Hi Marius,

Thanks for your reply.

So planning to move then the clock generator in the test harness and control it from the test sequencer process of the specific testbench. Each DUT will have its own VVC (eg clockcyclecounter_vvc) generating the reset to that specific DUT (ie clockcyclecounter).

So you recommend to have different Testbenches / process Sequencers. For each test case have it’s own testbench that instantiates the same test harness (that contains all VVC’s and all DUT’s instances + 1 UVVM engine instance). Please re-confirm.

So if this is the case then the test harness will get updated each time by adding new DUT & VVC instances within it & the new DUT’s / VVC’s get verified by a separate testbench (that instantiates the same updated version of the test harness for all DUT’s/VVC’s within it). Is this the case?

You mention that it depends on the complexity of the design, how related the 2 DUTs are etc. But your suggestion was to go for the 1st option (ie 1 test harness instantiating all DUTs & VVCs). The issue I see here if 1 test harness is used it’s portmap list will increase with time propagating signals to the corresponding top-level testbench. If specific test harness signals of a specific DUT are not related then could have an issue with the separate testbenches having to initialize within them any unwanted top level test harness input signals. Isn’t this the case? I don’t mind doing this if it be easier to do.

Before I attempt to try this option1, like your further comments please on this matter.

Kind regards,
Kevin

Hi,
Yes, I think I would go for option 1, but option 2 is also a fair choice.
Which signals do you want to access from the sequencer? Normally the signals from the DUT are connected to the BFMs, and then also to the VVCs, and any timing checkers etc would be in the test harness. Should you need access to test harness signals from the sequencer you could always do

alias signal_name is  <<signal path_name : signal_type>>;

Br,
Marius

Hi Marius,

After talking to one of my team members yesterday he suggested using 1 main testbench with 1 test sequencer process (within it) executing all commands for the entire FPGA UVVM VVC verification platform so no multiple testbenches/sequencers.

Each main sub-block of the FPGA will have its own Test harness and within each test harness we will have all the related main sub-block DUT / VVC instances, clock & reset generation, ti_uvvm_engine.

Is this flow ok? What is your opinion on this matter?

Kind regards,

Kevin

Hi Marius,

Another important query I have wrt UVVM architecture with multiple FPGA VCC’s / DUT’s.

When I created from Python the vvc templates for one DUT created the following files:
• <dut_name>_bfm_pkg.vhd
• <dut_name>_vvc.vhd

• transaction_pkg.vhd (extra file generated when extended UVVM features is enabled)
• vvc_cmd_pkg.vhd
• vvc_context.vhd
• vvc_methods_pkg.vhd

First 2 look unique FPGA submodule DUT ones.

If multiple DUTs are used related to the same FPGA sub_module, the last 4 files listed above will they be regarded as common ones for all FPGA sub-modules because they don’t start with <dut_name>_ extension?

If yes, do you advise placing these in a top-level common_src directory to be updated accordingly by all FPGA submodules or each FPGA submodule should have these last 4 files included?

I believe that the last 4 files listed above should be in a top-level common_src directory for access to all FPGA submodules and updated with the relevant info for all the DUT VCCs. Isn’t this the case?

Your prompt reply to this matter will be appreciated.

Kind regards,
Kevin

Hi,
All files generated by the vvc_generator script are for that VVC only. If you have more than one DUT, but with the same interface, you will use that VVC to interface with the DUTs from the tests.
The following files belong to one single VVC and should be compiled to a unique library for that VVC:

  • <interface_name>_bfm_pkg.vhd
  • <interface_name>_vvc.vhd
  • vvc_cmd_pkg.vhd
  • vvc_context.vhd
  • vvc_methods_pkg.vhd

When you use a VVC in a testbench/environment you will import that library (e.g. <interface_name>_vvc_lib) and the required files:

  • library <interface_name>_vvc_lib;
  • use <interface_name>_vvc_lib.vvc_methods_pkg.all;
  • use <interface_name>_vvc_lib.td_vvc_framework_common_methods_pkg.all;

or use the context file:

  • library <interface_name>_vvc_lib;
  • context <interface_name>_vvc_lib.vvc_context;

Br,
Marius

Hi Marius,

When I generated the VVC templates for the eg clockcyclecounter the vvc_content.vhd listed eg

library bitvis_vip_clockcyclecounter;
use bitvis_vip_clockcyclecounter.transaction_pkg.all;
use bitvis_vip_clockcyclecounter.vvc_methods_pkg.all;
::

So the library I must use will be bitvis_vip_clockcyclecounter and not clockcyclecounter_vvc_lib

& in the testbench if I use the VCC I could then declare at the top as:

library bitvis_vip_clockcyclecounter;
context bitvis_vip_clockcyclecounter.vvc_context;

My script here works fine when I do this change …

Please comment here.

Regards,
Kevin

Hi Marius,

Another matter. the clockcountercycle VVC related file showed ‘work’ library within it eg vvc_cmd_pkg.vhd included within it:

– Removed
–use work.transaction_pkg.all;

– Replaced
library bitvis_vip_clockcyclecounter;
context bitvis_vip_clockcyclecounter.vvc_context;

& within the package:

– Removed
–alias t_operation is work.transaction_pkg.t_operation;

– Replaced
alias t_operation is bitvis_vip_clockcyclecounter.transaction_pkg.t_operation;

Is this correct to what I removed & replaced ?
Thought I do not have to touch these template files wrt declaration of libraries

Can I leave all those with ‘work’ as they were before?

When I tried above changes, observed compilation issues so put them back to ‘work.xx’ as it was before:

vvc_cmd_pkg.vhd was left as:

use work.transaction_pkg.all;

& within the package:

alias t_operation is work.transaction_pkg.t_operation;
:::

Script with ‘work.xx’ declared as shown in the above example works ok…

Regards,
Kevin

Hi,
That is correct - your VVCs will expect to be compiled to a library in the form "bitvis_vip_<interface_name>, and in your design it will be “bitvis_vip_clockcyclecounter”. And in your TB you will use this library name.

For your 2nd question - no, do not make any changes to the use statements nor the use clauses in the VVC files. Library work will be a reference to working library in the VVC files, and in your case this will be bitvis_vip_clockcyclecounter. Your changes will work, but the VVCs works as is when generated from the vvc_generator script, and making other changes than required will increase the chances of creating a bug/error.

Br,
Marius

Hi Marius,

So if we have different VVCs for different interfaces you listed above the 5 unique files per VVC that should be compiled to their unique library. That includes the transaction_pkg.vhd (if Extended UVVM Features’ option is enabled).

So the following 4 files are not common to all FPGA VVCs if they come with different DUT interfaces:

  • vvc_cmd_pkg.vhd
  • vvc_context.vhd
  • vvc_methods_pkg.vhd
  • transaction_pkg.vhd

And if the VVCs come with the same interface all the above 4 files including the 2 following VVCs

  • <interface_name>_bfm_pkg.vhd
  • <interface_name>_vvc.vhd

should be placed in a separate related VVC directory.

Please re-confirm all above. It is important because my colleagues were informing me that these (ie above first 4 .vhd files listed) should be common files for the entire FPGA.

They will be only common files for related VVCs if they belong to the same interface of the DUTs (as you state in your above msg) & thus we can use these 4 common extra files for the related DUTs. Please re-confirm.

The names of the 4 files are common ie same names to all VVCs. The thing that makes them unique wrt the DUTs with same interface is where that VVC gets compiled into and they are placed in different directories (if this is right wrt one of my above queries). Is this the case? Please confirm

Kind regards,
Kevin

Thank you for confirming my previous msg :slight_smile:

Will appreciate a reply to my last today’s message too. Thanks…

Hi Marius,

Can you please comment here too wrt the above email posted 2 days ago?
Thanks.

Regards,
Kevin

Will appreciate a reply to my latest today’s message too. Thanks…

Hi Marius,

Just edited in bold my previous message for clarity to the queries raised.
Will appreciate your response to this matter because will have to inform my team about it, if it is as I describe below.

Thanks.
Kevin

Hi Kevin,
The files generated from vvc_generator.py belongs to 1 VVC and its instances only. If you for some reason create several VVCs, and after editing the generated files the vvc_cmd_pkg/vvc_context/vvc_methods_pkg/transaction_pkg contains the same information, it is a big chance you only needed 1 VVC in the first place. So, generate the VVCs (interfaces) you will need to verify your DUT(s) and keep all the files generated for each VVC separate from other VVCs - and compile them to their own libraries. Have a look at the VVCs that we have shipped with UVVM - the files are kept separate.

For your other question - I would have used multiple testbenches/sequencers, but I guess you have a good reason for putting all in one. Tests that can and/or need be tested separately should be tested in individual testcases. How you structure your testcases can be a matter of taste, but I like to have one test sequencer for each testcase. The test sequencer will issue VVC commands towards the DUT, but if you have changed the test harness to have a DUT with a different interface and VVC in another testcase, this will result in VVC commands that have no VVC and no DUT - i.e. creating an error.
The only solution I can think of is if you structuring your tests like this inside a single test sequencer is by using a generic on the TB entity that selects which test to run, and putting each testcase inside procedures which will be selected by an if-statement inside the test sequencer, based on the TB entity generic value.
E.g.
GC_TESTCASE : integer := 0;

… p_sequencer: process()

procedure testcase1(…testcase 1 code…)
prosedure testcase2(…testcase 2 code…) and so on

begin
if GC_TESTCASE = ‘1’ then
testcase1();
elsif GC_TESTCASE = ‘2’ then
testcase2();
… and so on

Br,
Marius

Hi Marius,

Thanks for your replies so far. I have another query.

I am looking now into incorporating 2 VVCs into the my UVVM VVC testbench environment and using 1 Testbench (1 Test Sequencer). Each VVC in this instance has its own test harness because they are 2 separate DUTs and their interfaces are different.

I created a separate directory to where I include all 6 below related VVC .vhd files:

vvc_cmd_pkg.vhd
vvc_context.vhd
vvc_methods_pkg.vhd
transaction_pkg.vhd
<interface_name>_bfm_pkg.vhd
<interface_name>_vvc.vhd

In my current flow, I noticed that there were also 4 other following uvvm_vvc_framework .vhd target dependent package files that had to be compliled too:

td_target_support_pkg.vhd
td_vvc_framework_common_methods_pkg.vhd
td_queue_pkg.vhd
td_vvc_entity_support_pkg.vhd

Currently the above 4 bolted files I was compiling them into work library. I will need to change the work library here to the specific VVC one to where the other 1st 6 above .vhd files were compiled.

So, the 4 above bolted td_* files are intended also to be compiled into each VVC, providing supporting datatypes and methods for the UVVM VVC Framework. Please confirm.

Seen also the following statement within the VC_Framework_Manual.pdf (pg.20):

"3. ‘VVC FRAMEWORK target dependent packages’
Functionality that is common for all (or most) VVCs, but is dependent on VVC dedicated definitions/declarations.

  • Such packages are located under the UVVM_VVC_Framework directory as their contents are common, but they are compiled into VVC libraries as they depend on other compiled packages in their respective VVC library.
  • Shown in Figure 9 as orange – to indicate that the packages are located under UVVM_VVC_Framework, but compiled into a dedicated VV "

Kind regards,
Kevin

Hi Marius,

My UVVM Framework environment will have multiple test harnesses and 1 testbench as stated in one of my previous emails. My choice was to use multiple testbenches but the team asked me to stick to 1 testbench / multiple test harnesses which I am currently doing.

My other query now is related to the different test harnesses and the single Testbench.

Where do you suggest compiling each test harness .vhd file? To a new library eg adc_work, i2c_work etc? And the test harness name for the related VVCs should have a unique name that relates to those VVCs eg adc_vvc_th.vhd, i2c_vvc_th.vhd etc. Is this the case?

Also, the testbench that instantiates all test harnesses and includes 1 test sequencer. What library will be best to use to compile the testbench to? work library?

Your reply to this matter too will be appreciated.

Kind regards,
Kevin

Hi Kevin,
The 4 td_ files will have to be compiled into the same libraries as the VVCs. You can see the compile order in e.g. bitvis_vip_sbi/doc/sbi_vvc_qr.pdf - final page.

Br,
Marius