accessing ports in an array of interfaces

F

fpgabuilder

Guest
I am trying to access individual ports in an array of interface as
below. Ofcourse, this does not work... anybody have any suggestions?

module my_module ();

logic [9:0] my_signal;
my_if.rx my_if_inst [0:9];

assign my_signal[9:0] = my_if_inst[0:9].signal;

endmodule

interface my_if();

logic signal;

modport rx (
input signal;
);

endinterface


TIA.
 
On Aug 2, 11:11 pm, fpgabuilder <parekh...@gmail.com> wrote:
I am trying to access individual ports in an array of interface as
below.  Ofcourse, this does not work... anybody have any suggestions?

module my_module ();

logic [9:0] my_signal;
my_if.rx my_if_inst [0:9];

assign my_signal[9:0] = my_if_inst[0:9].signal;
heh. You can't do that. The select prefix
(the thing that appears before ".signal") must
resolve to a specific instance, but what you've
written describes the whole array of instances.

How about
generate
for (genvar i = 0; i <=9; i++) begin : connect
assign my_signal = my_if_inst.signal;
end
endgenerate

???

--
Jonathan Bromley
 
On Aug 3, 12:20 am, Jonathan Bromley <s...@oxfordbromley.plus.com>
wrote:
On Aug 2, 11:11 pm, fpgabuilder <parekh...@gmail.com> wrote:

I am trying to access individual ports in an array of interface as
below.  Ofcourse, this does not work... anybody have any suggestions?

module my_module ();

logic [9:0] my_signal;
my_if.rx my_if_inst [0:9];

assign my_signal[9:0] = my_if_inst[0:9].signal;

heh.  You can't do that.  The select prefix
(the thing that appears before ".signal") must
resolve to a specific instance, but what you've
written describes the whole array of instances.

How about
  generate
    for (genvar i = 0; i <=9; i++) begin : connect
      assign my_signal = my_if_inst.signal;
    end
  endgenerate

???

--
Jonathan Bromley

Yeah! That works. Thx. Okay so the point is noted about the
resolving a specific instance... but why can't a range be used to
resolve a range of instances?
 
On Tue, 3 Aug 2010 10:22:04 -0700 (PDT), fpgabuilder wrote:

but why can't a range be used to
resolve a range of instances?
Because it would open the door to all manner of
bizarre possibilities, and the language errs on
the side of clear-headed conservatism.

In a similar way, and for similar reasons, you
are not permitted to use a variable to select
from an instance array - even though that would
sometimes make perfect sense. For example:

module Thing;
reg R;
endmodule

module ManyThings;

reg [1:0] Selector;
Thing [3:0] FourThings();
initial begin
Selector = 2;
FourThings[Selector].R = 1; // ILLEGAL

The use of a variable to select into an instance
array is forbidden, because it would make possible
various completely unreasonable things. So we
lose the ability to express certain things in
what appears to be a simple way. Hard luck!
--
Jonathan Bromley
 
On Aug 3, 1:22 pm, Jonathan Bromley <s...@oxfordbromley.plus.com>
wrote:
On Tue, 3 Aug 2010 10:22:04 -0700 (PDT), fpgabuilder wrote:
but why can't a range be used to
resolve a range of instances?

Because it would open the door to all manner of
bizarre possibilities, and the language errs on
the side of clear-headed conservatism.

In a similar way, and for similar reasons, you
are not permitted to use a variable to select
from an instance array - even though that would
sometimes make perfect sense.  For example:

  module Thing;
    reg R;
  endmodule

  module ManyThings;

    reg [1:0] Selector;
    Thing [3:0] FourThings();
    initial begin
      Selector = 2;
      FourThings[Selector].R = 1;  // ILLEGAL

The use of a variable to select into an instance
array is forbidden, because it would make possible
various completely unreasonable things.  So we
lose the ability to express certain things in
what appears to be a simple way.  Hard luck!
--
Jonathan Bromley
Okay, I guess I can see how use of variable can make things difficult
but I still do not see why using a fixed range to access the same
copies of nodes in a range of instances can be so difficult. How is
this different from bit-slicing a bus?
 
On Tue, 3 Aug 2010 17:06:25 -0700 (PDT), fpgabuilder wrote:

I still do not see why using a fixed range to access the same
copies of nodes in a range of instances can be so difficult. How is
this different from bit-slicing a bus?
Because when you bit-slice a vector, the slice range
is sure to be the LAST selector:

// An array of ten 8-bit vectors:
reg [7:0] someArray[0:9];

someArray[5][3:1] // this is OK, 3 bits from element [5]
someArray[2:4] // OK in SystemVerilog:
// a sub-array of 3 whole elements
someArray[2:4][3] // clearly this is crazy

Generally, any use of slice syntax [Start:End] MUST be
the last selector in any selected (dotted) reference
or subscripted reference.

Another example of the possible craziness, this one
appealing to SystemVerilog data structures:

typedef struct {
int A;
logic B;
} int_and_logic;

int_and_logic R[0:9]; // array of 10 structs

R[5].A // OK, get the int part of R[5]
R[3:7] // OK, sub-array of five complete structs
R[3:7].A // surely not?

I fully understand that you can find a sensible meaning
for your specific example, but it simply would not scale
to more complicated examples. Keep things simple!

Amusing quiz for those of us who have met many different
programming languages: Can you think of any languages
that DO (or did) support operations like A[4:6][3:0] ???

Jonathan Bromley
 
I can see your notion of keeping things simple. And I am even sure
that the same thing can be realized by writing things in a generate
loop. But there are two things that bug me about that...
1. The fact that when we use generate loops, something as basic as an
assignment gets its own blocks in simulator and synthesizer. Nothing
wrong with that... just that I have dig deeper into hierarchy to trace
something.
2. I still don't get the craziness that you talk about.

And I haven't seen many programming languages in my lifetime. But
when I think of Verilog as describing hardware... I still do not see
the craziness that you point out... But if you are tempted to
respond... I humbly say thanks for indulging me.


On Aug 4, 5:20 pm, Jonathan Bromley <s...@oxfordbromley.plus.com>
wrote:
On Tue, 3 Aug 2010 17:06:25 -0700 (PDT), fpgabuilder wrote:
I still do not see why using a fixed range to access the same
copies of nodes in a range of instances can be so difficult.  How is
this different from bit-slicing a bus?

Because when you bit-slice a vector, the slice range
is sure to be the LAST selector:

   // An array of ten 8-bit vectors:
   reg [7:0] someArray[0:9];

   someArray[5][3:1]  // this is OK, 3 bits from element [5]
   someArray[2:4]     // OK in SystemVerilog:
                      // a sub-array of 3 whole elements
   someArray[2:4][3]  // clearly this is crazy
Why is this crazy? I could say "use bit 3 from elements 2 through
4." Why is this too complicated for the tools? I say USE but I could
very well say UPDATE. Can it not simplify the code if you can update
the registers this way?

Generally, any use of slice syntax [Start:End] MUST be
the last selector in any selected (dotted) reference
or subscripted reference.

Another example of the possible craziness, this one
appealing to SystemVerilog data structures:

   typedef struct {
     int A;
     logic B;
   } int_and_logic;

   int_and_logic R[0:9];  // array of 10 structs

   R[5].A  // OK, get the int part of R[5]
   R[3:7]  // OK, sub-array of five complete structs
   R[3:7].A  // surely not?
Again. Why not? "Use int A from int_and_logic structure instances
R[3 through 7].
I fully understand that you can find a sensible meaning
for your specific example, but it simply would not scale
to more complicated examples.  Keep things simple!

Amusing quiz for those of us who have met many different
programming languages:  Can you think of any languages
that DO (or did) support operations like A[4:6][3:0] ???

Jonathan Bromley
 
On Fri, 6 Aug 2010 11:28:44 -0700 (PDT), fpgabuilder wrote:

 // clearly this is crazy
Why is this crazy? I could say "use bit 3 from elements 2 through
4." Why is this too complicated for the tools?
I'm sure that in principle it's not; tools can do all
manner of complicated and clever things. But, in
practice, the overwhelming majority of programming
languages like each data object to occupy a contiguous
block of memory, uninterrupted by pieces of other data
objects. The "sparse slice" someArray[2:4][3] is a
scattering of pieces from a bigger object, with other
unwanted pieces of the original object mixed in with
them.

Clearly you could imagine reconstructing a new
object from the pieces, and I'm sure that's the
kind of thing you are thinking about. In hardware
(synthesis) it's probably rather easier than it would
be in pure software - pick every third wire from this
ribbon cable, and reconstruct them into a new ribbon
cable that's a third the size of the original!
But that's irrelevant; hardware languages like
Verilog are defined by their simulation execution
model, not by the hardware they create.

People just don't design programming languages
that way, with a few notable exceptions (do you know
about APL, for example? And I think you can do
something of the sort with Matlab.)

So you could probably say that I was being
unfair in describing such "checkerboard objects"
as crazy, but they are certainly unusual.
I don't know for sure, but I suspect that the
task of defining the semantics of such a
language would be challenging.

The effect you desire, in the simple cases you
describe, can easily be achieved by other methods.
Consequently, I'm quite happy that we don't have
this "sparse slicing" making SystemVerilog even
more complicated than it already is. Making your
code five lines shorter, at the expense of making
the language harder to understand and less
efficient for everyone, is a bad tradeoff.
--
Jonathan Bromley
 

Welcome to EDABoard.com

Sponsor

Back
Top