How to get SV to scale

T

Thomas Jones

Guest
Hello,

I have a wrapper task that calls a task within an instance array of a
subblock.

task wrapper (
input int instanceNumber);

instanceArrayElement[instanceNumber].instanceTask();

endtask//wrapper

However, instanceNumber must be constant by the LRM. Modelsim
complains

Nonconstant index into instance array 'InstanceNumber'.

I spoke with an FAE and they showed me the line in the LRM where it
says it must be 'constant'.

But what if, say, I set the range of the instance array by a parameter
to the sim such that it may scale? Is there any way within SV itself
to get my task to scale with it? In the past I have used a Perl
preprocessor - just wondering if there is a way to do it within the
language itself.
 
On Thu, 18 Nov 2010 07:36:07 -0800 (PST), Thomas Jones wrote:

I have a wrapper task that calls a task within an instance array of a
subblock.

task wrapper (
input int instanceNumber);
instanceArrayElement[instanceNumber].instanceTask();
endtask//wrapper

However, instanceNumber must be constant by the LRM.
Yes. This is tedious. This is testbench code, right?

Using classes can fix it, because you can easily make an array of
objects of class type and then index into that array to call
a task in a selected object. However, it's not trivial to
link your dynamically created object array to the statically
elaborated instance array in a way that's automatic and scalable.

Virtual interfaces can do this, too.

Here's a sketch of an idea - not fully worked through yet,
although it's probably something I should do...

- Create a little interface with a task in it, BUT NOTE THAT
THIS INTERFACE WILL BE INSTANCED INSIDE YOUR TARGET MODULE:

interface Parasite();
task doInstanceTask();
targetModuleName.instanceTask();
endtask
endinterface

The nifty trick here is that by using the target module's
MODULE NAME rather than its instance name, the path
to the task will work correctly wherever the target module
may be in the instance hierarchy. But it does require that
an instance of Parasite be added to the target module.
Fortunately that's rather easy, using the bind statement.

In your testbench....

- Arrange that every instance of your target module gets a
bound instance of Parasite:
bind targetModuleName Parasite parasite_instance();

- Create an array of virtual interface variables.
Populate the virtual interface array with references
to the bound instances. You'll need to do this in a
generate loop so that the indices are treated as
elaboration constants:

virtual Parasite instanceLinks[N];
// N matches size of your instance array
generate for (genvar i = 0; i<N; i++) begin: hookup
initial instanceLinks =
path.To.My.Instance.parasite_instance;
end endgenerate

- Now you can easily call the task using a variable index:

initial #10 for (int i=0; i<N; i++)
instanceLinks.doInstanceTask();

It takes a bit of setting up, but goes smoothly once that's
done. It's even nicer using classes, but that needs more
code than I can sensibly show here.

HTH
--
Jonathan Bromley
 
Thanks Jonathon. I figured there might be ways to do this with
classes, but we're using non-Questa Modelsim, so I guess I am stuck
with Perl. ~Tom
 
In article <76d501e7-5c3a-49f7-9d34-d2063f277eea@n30g2000vbb.googlegroups.com>,
Thomas Jones <mr.thomas.c.jones@gmail.com> wrote:
Thanks Jonathon. I figured there might be ways to do this with
classes, but we're using non-Questa Modelsim, so I guess I am stuck
with Perl. ~Tom
Modelsim will handle what Jonathan showed just fine. You only
need Questa for assertions/sequences/constraint solver. The features
Jonathon's shown are fine in modelsim with the -sv switch.

--Mark
 

Welcome to EDABoard.com

Sponsor

Back
Top