SystemVerilog interface arrays

Guest
Hi,

I have an issue with how to model a module connected to a number of
similar interfaces. Can somebody tell me what I have misunderstood
about systemverilog. The problem apparently is the looping through the
10 interfaces, where the index has tro be constant according to VCS.
Any help in how to solve this is highly appreciated.

interface my_if;
bit req;
bit gnt;
endinterface // my_if

module arbiter(clients);
my_if clients[0:9];

always begin
int winner=0;

for (int p=0; p<10; p++) begin
if (clients[p].req) winner=p;
end
for (int p=0; p<10; p++) clients[p].gnt=(winner==p);
end
endmodule // arbiter

module top;
my_if all_ifs[0:9]();

always begin
for (int p=0; p<10; p++) all_ifs[p].req=(p==4);
end

arbiter my_arb(all_ifs);
endmodule // top
 
mte@oticon.dk wrote:
Hi,

I have an issue with how to model a module connected to a number of
similar interfaces. Can somebody tell me what I have misunderstood
about systemverilog. The problem apparently is the looping through the
10 interfaces, where the index has tro be constant according to VCS.
Any help in how to solve this is highly appreciated.
Due to the possibility of parameterization, there is
no guarantee that the different interfaces in the
"array" are similar to each other (unlike in a normal
array of variables), with the same sizes and internal
structure. So a compiler cannot reasonably generate
generic code that can deal with all the possible
variations of the interface when you finally know at
runtime which one the index is selecting.

So you have two choices. You can use a generate-loop
to generate code to operate on the interfaces (i.e. to
generate 10 different always blocks, each of which is
operating on a single interface with a constant index set
by the genvar).

Alternately, you can use an array of virtual interfaces.
Since all of the interfaces in an array of virtual interfaces
are required to have identical parameterization and thus
identical internal structure, you are allowed to use a
non-constant index with an array of virtual interfaces.
Of course you will need to set the array of virtual
interfaces to point to the elements of your array of
interfaces, and you still can't use a nonconstant
index into the array of interfaces to do it. You can
either write the 10 assignments in series (which is
not parameterizable), or you can use a generate-loop
to do it.
 
Thanks alot. It helped.
I however have a related problem. How do I assign to an array of
interfaces, like in the below example. I need to be able to cross
connections between two modules, so that the interfaces are (at compile
time) permuted.
Regards.

interface my_if;
bit req;
bit gnt;
endinterface // my_if

module ifuser(my_if i[0:2]);
endmodule // ifuser


module top;
my_if i[0:2]();

ifuser ifu1(i); //OKAY
ifuser ifu2({i[0],i[2],i[1]}); // CANNOT DO THIS
endmodule // top



sharp@cadence.com skrev:
mte@oticon.dk wrote:
Hi,

I have an issue with how to model a module connected to a number of
similar interfaces. Can somebody tell me what I have misunderstood
about systemverilog. The problem apparently is the looping through the
10 interfaces, where the index has tro be constant according to VCS.
Any help in how to solve this is highly appreciated.

Due to the possibility of parameterization, there is
no guarantee that the different interfaces in the
"array" are similar to each other (unlike in a normal
array of variables), with the same sizes and internal
structure. So a compiler cannot reasonably generate
generic code that can deal with all the possible
variations of the interface when you finally know at
runtime which one the index is selecting.

So you have two choices. You can use a generate-loop
to generate code to operate on the interfaces (i.e. to
generate 10 different always blocks, each of which is
operating on a single interface with a constant index set
by the genvar).

Alternately, you can use an array of virtual interfaces.
Since all of the interfaces in an array of virtual interfaces
are required to have identical parameterization and thus
identical internal structure, you are allowed to use a
non-constant index with an array of virtual interfaces.
Of course you will need to set the array of virtual
interfaces to point to the elements of your array of
interfaces, and you still can't use a nonconstant
index into the array of interfaces to do it. You can
either write the 10 assignments in series (which is
not parameterizable), or you can use a generate-loop
to do it.
 
mte@oticon.dk wrote:
How do I assign to an array of
interfaces, like in the below example. I need to be able to cross
connections between two modules, so that the interfaces are (at compile
time) permuted.

module ifuser(my_if i[0:2]);
endmodule // ifuser


module top;
my_if i[0:2]();

ifuser ifu1(i); //OKAY
ifuser ifu2({i[0],i[2],i[1]}); // CANNOT DO THIS
endmodule // top
You definitely cannot use this syntax with just {}. That is a
concatenation, and is not legal for anything but vectors.
Early versions of SystemVerilog used this same syntax for
array literals, but this was changed due to problems with
ambiguity with concatenations. The new syntax in the IEEE
standard uses typename'{} to indicate an aggregate literal
(now called an "assignment pattern expression") of type
typename. Or in an assignment, where the type can be
gotten from what you are assigning it to, you can use
leave out the typename and have an assignment pattern,
with the syntax '{}.

Your tools may not support this newer syntax, and may
still require the older obsolete concatenation syntax.

Even if this syntax is supported, it is really only defined
for data aggregates (data arrays and structs). I don't
think it covers "arrays" of instances, like your array of
interface instances.

So the only solution I c an see is to define your module
with 3 separate interface ports, instead of one port that
is an array of 3 interfaces. Then you can connect with
any permutation you want. If you need an array inside
the module, you can assign the interface ports to an
array of virtual interfaces. But I don't think you can pass
virtual interfaces through a port, so you can only do this
at the final level where you are ready to use the interfaces.
 
Thanks a lot for your help. It helps me to know the limitations, which
in my opinion are not very clear in the LRM. Your suggestion using
three interface ports instead of an array, does not help a lot, as the
number of interfaces in my design is much higher than three. I have 32
identical ones, and its really sad that I cannot use interface arrays
for it. But thanks anyway.


sharp@cadence.com skrev:
mte@oticon.dk wrote:
How do I assign to an array of
interfaces, like in the below example. I need to be able to cross
connections between two modules, so that the interfaces are (at compile
time) permuted.

module ifuser(my_if i[0:2]);
endmodule // ifuser


module top;
my_if i[0:2]();

ifuser ifu1(i); //OKAY
ifuser ifu2({i[0],i[2],i[1]}); // CANNOT DO THIS
endmodule // top

You definitely cannot use this syntax with just {}. That is a
concatenation, and is not legal for anything but vectors.
Early versions of SystemVerilog used this same syntax for
array literals, but this was changed due to problems with
ambiguity with concatenations. The new syntax in the IEEE
standard uses typename'{} to indicate an aggregate literal
(now called an "assignment pattern expression") of type
typename. Or in an assignment, where the type can be
gotten from what you are assigning it to, you can use
leave out the typename and have an assignment pattern,
with the syntax '{}.

Your tools may not support this newer syntax, and may
still require the older obsolete concatenation syntax.

Even if this syntax is supported, it is really only defined
for data aggregates (data arrays and structs). I don't
think it covers "arrays" of instances, like your array of
interface instances.

So the only solution I c an see is to define your module
with 3 separate interface ports, instead of one port that
is an array of 3 interfaces. Then you can connect with
any permutation you want. If you need an array inside
the module, you can assign the interface ports to an
array of virtual interfaces. But I don't think you can pass
virtual interfaces through a port, so you can only do this
at the final level where you are ready to use the interfaces.
 
mte@oticon.dk writes:

Thanks a lot for your help. It helps me to know the limitations, which
in my opinion are not very clear in the LRM. Your suggestion using
three interface ports instead of an array, does not help a lot, as the
number of interfaces in my design is much higher than three. I have 32
identical ones, and its really sad that I cannot use interface arrays
for it. But thanks anyway.
Could you map your array into a (very long) vector, and then pick out
each part for each instanciation?

(Welcome to the dumbed down world of SV after using VHDL ;-)

/PS: say hi to igj from me.

Kai
--
Kai Harrekilde-Petersen <khp(at)harrekilde(dot)dk>
 

Welcome to EDABoard.com

Sponsor

Back
Top