SystemVerilog: how to attach an SV interface within a VHDL D

A

Andrew FPGA

Guest
We use SystemVerilog top level sims to verify a VHDL device under test
(its a 90kLUT FPGA). We attach the SV class based testbench hierarchy
to the DUT in the traditional manner, using virtual SV interfaces. The
DUT is VHDL, so I use an "SV wrapper module" to instance the DUT and
hookup the SV interfaces to the DUT pins. All rather conventional I
would think.

For simulation performance reasons, we have a need to remove a
specific module within the DUT. Easily done, but how I can attach the
top level testbench to this removed modules ports, so that I can drive
data into, and monitor data out of this removed module? I would love
to instance SV interfaces and then attach these to the removed modules
ports, but I have not figured out how to do this.

The removed module is a high speed serdes and SGMII module which takes
the FPGA pins and converts to the standard 802.3 GMII interface. I
would like to drive and monitor the GMII interface directly, removing
the need to execute the serdes/SGMII models.

After googling and thinking, here are the options/ideas I've come up
with:
1) SV bind. Bind a GMII SV interface into an empty shell of the SGMII/
Serdes model. My understanding is bind is "like" instantiating, so
I'll end up with an SV GMII interface inside the serdes model shell.
How do I get the top level testbench to reference this interface, so I
can pass it in as a virtual interface to the class based testbench
hierarchy? Its VHDL so can't use hierarchical notation?

2) Questasim "signal_spy". This gets me into the VHDL hierarchy, but
simulator specific so yucky.

3) Use a VHDL package with some global signals, which get included by
the serdes model shell. Then, how to drive these global signals from
an SV interface? Doesn't feel right.

4) Breakout the GMII signals to the VHDL top level. Use translate on/
off pragmas so these extra GMII signals on the DUT top level don't
exist at synthesis time. Then can attach these DUT top level signals
to an SV interface in the conventional way.

Any ideas on a cleaner way to do this? Would like to stay within SV/
VHDL rather than use simulator specific features like signal spy, etc.

Cheers
Andrew

Questasim 6.5b.
Lattice Synplify Pro 9.6
 
On Mon, 15 Feb 2010 15:20:09 -0800 (PST), Andrew FPGA wrote:

hi Andrew,

We use SystemVerilog top level sims to verify a VHDL device under test
(its a 90kLUT FPGA). We attach the SV class based testbench hierarchy
to the DUT in the traditional manner, using virtual SV interfaces.
OVM? Home-grown?

DUT is VHDL, so I use an "SV wrapper module" to instance the DUT and
hookup the SV interfaces to the DUT pins. All rather conventional I
would think.
Sounds good to me. Of course it relies on your simulator's
ability to instantiate VHDL inside SV, but all the major
simulators do that just fine.

For simulation performance reasons, we have a need to remove a
specific module within the DUT. Easily done, but how I can attach the
top level testbench to this removed modules ports, so that I can drive
data into, and monitor data out of this removed module? I would love
to instance SV interfaces and then attach these to the removed modules
ports, but I have not figured out how to do this.
I'm sure it's possible, but you have the laudable aim of
avoiding simulator-specific constructs; that makes it a
tad harder.

1) SV bind. Bind a GMII SV interface into an empty shell of the SGMII/
Serdes model. My understanding is bind is "like" instantiating, so
I'll end up with an SV GMII interface inside the serdes model shell.
How do I get the top level testbench to reference this interface, so I
can pass it in as a virtual interface to the class based testbench
hierarchy?
Exactly so. Problem is, it's a SV instance inside VHDL. All the
tools do this OK, but reaching the SV instance by hierarchical
name is quite another matter and is sure to be simulator-specific.
The vendors seized on "bind" as a great way to glom-in modules
containing SV assertions; for an assertions module, of course,
you don't worry about the module's location in the instance
hierarchy.

2) Questasim "signal_spy". This gets me into the VHDL hierarchy, but
simulator specific so yucky.
Agreed, although it's a nice enough mechanism.

3) Use a VHDL package with some global signals, which get included by
the serdes model shell. Then, how to drive these global signals from
an SV interface? Doesn't feel right.
Just as yucky as SignalSpy, I suggest.

4) Breakout the GMII signals to the VHDL top level. Use translate on/
off pragmas so these extra GMII signals on the DUT top level don't
exist at synthesis time. Then can attach these DUT top level signals
to an SV interface in the conventional way.
Tool-independent, but brain-meltingly tedious and messy.

On a more positive note... Here are a few sketch ideas -
not worked through fully, but maybe interesting.

(1)
Wrap the GMII hook interface in a SV module, and bind that
wrapper module into the VHDL design. An "initial" block in
the wrapper module could then make a virtual interface
pointer to its wrapped SV interface instance, and expose
that VI pointer by copying it into the top level testbench
by upwards hierarchical reference - maybe, just maybe,
this is an excuse for using the dreaded $root pseudo-
instance that is the top of your SV instance hierarchy.

(2)
Like (1), but instead of pushing the VI value into the
top level testbench, push it into a variable in a SV
package. This works just like global signals in VHDL,
but it's sooooo much nicer to have to share only one
global. If you have multiple instances of the bound
module, you could make an array of VIs in the package
and use a parameter of the bound module as index into
the array. This parameter can then be set on the
bound module by the simulator (-g or -G option to vsim,
similar options exist for other tools).

(3)
Same idea, but more OOP-friendly: create a registry class
and have the bound module's initial block call some
static registration function in that class. I'm not
exactly sure what value you would get from the %m
instance name formatter in a SV module bound into
your VHDL hierarchy, but I can imagine code like this:

interface GMII_interface (...GMII ports...);
...
endinterface

package connection_package;
typedef virtual GMII_interface p_GMII;
class GMII_registry;
p_GMII registered_hooks[string];
static function register_me(string ID, p_GMII hook);
assert (!registered_hooks.exists(ID)) else
$error($psprintf("Register p_GMII hook %s twice!", ID);
registered_hooks[ID] = hook;
endfunction
endclass
endpackage

module wrapper_to_be_bound(...GMII ports...);
import connection_package::*;
GMII_interface the_hook(...GMII ports...);
initial begin
string identity;
$sformat(identity, "%m");
$display("Registering GMII interface %s", identity);
GMII_registry::register_me(identity, the_hook);
end
endmodule

Now your class-based testbench can ask GMII_registry
to serve up the VI reference (that code is Left As An
Exercise For The Reader). Similarly (maybe better)
you could construct object instances within the bound
module, and give away references to those instances.

My brain is a bit fried at the moment with debugging,
but on a clearer day I could probably suggest some ideas
about using the OVM factory to create parameterized
object instances and get your hooks that way instead.

Hope this helps somewhat.
--
Jonathan Bromley
 
On Mon, 15 Feb 2010 15:20:09 -0800 (PST), Andrew FPGA wrote:

I would love
to instance SV interfaces and then attach these to the removed modules
ports, but I have not figured out how to do this.
As an afterthought to my other post: my former colleague
Doug Smith at Doulos wrote a nice paper for SNUG San Jose
last year, "Using bind for Class-based Testbench Reuse
with Mixed-Language Designs". It probably has much better
answers than the ones I gave you. Download from
www.doulos.com/knowhow (registration needed) or
www.synopsys.com/community/snug/pages/proceedingLp.aspx?loc=San%20Jose&locy=2009
(only available if you have a Synopsys login).
--
Jonathan Bromley
 
On Tue, 16 Feb 2010 22:53:28 +0000, Jonathan Bromley wrote:

class GMII_registry;
p_GMII registered_hooks[string];
static function register_me(string ID, p_GMII hook);
assert (!registered_hooks.exists(ID)) else
$error($psprintf("Register p_GMII hook %s twice!", ID);
registered_hooks[ID] = hook;
endfunction
endclass
Oh poo. My brain really IS fried today. The associative
array must, of course, be static:

class GMII_registry;
static p_GMII registered_hooks[string];
static function register_me(string ID, p_GMII hook);
...

Sorry.
--
Jonathan Bromley
 
Thank you Jonathan. The "OOP" option(3) is certainly the most
appealing. I'm part way through my tedious option, and indeed brain is
melting away.

Yes, I've already read the Doulos bind paper a couple of times - thats
where I figured out the standard model for hooking up dut to testbench
(intefaces/virtual interfaces). Maybe I need to read it again!

No we don't use OVM today, although I've tried to use a monitor/driver
style, to facilitate porting to OVM in the future. We spent some time
evaluating OVM, trying to get a basic example going. We did get stuff
going, but still have some fairly fundamental OVM questions to get to
grips with. e.g.

1) What is the standard OVM way of configuring DUT registers? Today
with no-OVM, I have a layered approach, with the lowest layer
implementing BFMS of a parallel and serial interface that reads/writes
registers. Then layers above that abstract away the configuration as
appropriate. E.g. we have configuration RAMs that have a sequence of
register accesses required, etc. This is nice, tests can be written
that go in at whatever layer is appropriate. Can't see how to
duplicate this in OVM easily. OVM Cookbook talks about creating a
layered api using sequences. Sequences generate stimulus, but for a
register read, need to return the data read..i.e. can use sequences to
go down the stack, but how do we go back up the stack after the
monitor..?

2) Can a monitor change the DUT state? e.g. we read ethernet packets
out of a cpu interface. So we think we need an OVM monitor that will
generate ethernet packet transactions, but reading packets out of the
cpu changes a status bit in the DUT. But, we need to send CPU
interface read/write transactions first...Gets confusing quick.

Fancy a trip to New Zealand ;) What are you doing these days, I had
the impression you were no longer with Doulos?

Cheers
Andrew
 
hi Andrew,

1) What is the standard OVM way of configuring DUT registers?
Depressingly, there isn't one yet. On ovmworld.org you'll find a
prototype register-abstraction package, but I confess I've not
yet tried to make use of it.

with no-OVM, I have a layered approach, with the lowest layer
implementing BFMS of a parallel and serial interface that reads/writes
registers. Then layers above that abstract away the configuration as
appropriate. E.g. we have configuration RAMs that have a sequence of
register accesses required, etc. This is nice, tests can be written
that go in at whatever layer is appropriate. Can't see how to
duplicate this in OVM easily. OVM Cookbook talks about creating a
layered api using sequences. Sequences generate stimulus, but for a
register read, need to return the data read..i.e. can use sequences to
go down the stack, but how do we go back up the stack after the
monitor..?
That's actually fairly easy. If you're being an OVM purist, you
would write/read a register using sequences (of course, there
would be a highly directed sequence at some point to do all the
register config) and the monitor observes the transactions,
including the value you get when you read a register. An
observer attached to the monitor could use this information to
maintain an up-to-date shadow model of the registers. There is
no objection to the stimulus generator making use of such
monitored or modelled information in creating its stimulus.

Hooking all this together in a hygienic way takes a little
thought, but it certainly can be done. The project I'm working
on right now, a biggish OVM environment, does lots of that kind
of stuff. Lots of components in the environment need to be
aware of modelled DUT state that is held in some common place.
OVM's TLM-style interconnect machinery helps a lot here.

Alternatively (but probably less usefully, for the registers
problem) your sequences can get responses back from their BFM.
In a really clean OVM architecture you would not want to use
that response data for anything other than creation of further
sequence activity, however. The monitor approach scales better.

2) Can a monitor change the DUT state?
No, no, and twenty times NO. The big deal about a monitor is
that it is strictly read-only on DUT signals. In that way,
it can remain attached when the DUT is getting its input
signals from other parts of a bigger design.

e.g. we read ethernet packets
out of a cpu interface. So we think we need an OVM monitor that will
generate ethernet packet transactions, but reading packets out of the
cpu changes a status bit in the DUT.
Right; "monitor" in the OVM sense is certainly not the same
as "receiver" or "responder". Your read-packets machine is
not a monitor at all; it's a stimulus generator. Likely, its
default behaviour is simply to respond to packets as they
arrive; but it should be architected so that a sequencer
can change its behaviour - in particular, by introducing
latency in its response. A monitor, sitting beside it.
can observe both the packets and the activity of your
responder, and broadcast its observations to the rest
of the environment. If, in the future, the responder
is replaced by some other RTL module in a bigger system,
the monitor can continue to do its work but the responder
must be disconnected by setting the active/passive flag
in its agent to "passive". BTW, the name "responder" isn't
standard OVM jargon, but I often find it's a useful idea.

A similar problem exists when the DUT performs read cycles
on something like a memory device. Although the initiation
of the read cycles is done autonomously by the DUT, there
are features of the response (read data, ready/ack signals)
that must be driven by the memory model. OVM sequencers
cope with this pretty well - a responder BFM sees the read
cycle, asks its sequencer for response data (and timing
information), and then implements that response back to
the DUT.

Fancy a trip to New Zealand ;) What are you doing these days, I had
the impression you were no longer with Doulos?
A nasty little demon in my head kept telling me that,
after ten years of being a technical trainer, there was
a serious risk of bullshit and it was about time to
start doing real work instead. So I'm now with a
verification consulting outfit (Verilab) whose
undoubtedly international reach sadly doesn't extend
to NZ at present. Though I'm sure we would be happy to
negotiate :)

Regards
--
Jonathan Bromley
 
Hi Jonathan, (and anyone else who needs to do this in the future)
I have your option 3 working. :) SV bind a module wrapping the SV
interface. Then push a virtual interface to a static member of a
class. Top level testbench then pulls the virtual interface from this
class.

But, I do have this issue I don't understand. I get the error below
during elaboration. A work around is to create a dummy gmii_if
interface instance in the testbench top level module. Its not
connected to anything, but at least it allows questa to elaborate
without this Fatal. Googling shows folk mentioning a -
permit_umatched_virtual_intf option as another work around - but I
can't find this in the manual and nor does it seem to work.

# ** Fatal: (vsim-8451) d:/work/DAC_GEv3_repo_test/FPGA_DACGEV3/
Simulation/Questasim_top/../../Sources/Simulation/system_verilog_top/
DACGEv3_testbench_top.sv(52): Virtual interface resolution cannot find
a matching instance of interface 'gmii_if.phy'.
# Time: 0 ps Iteration: 0 Instance: /
DACGEv3_testbench_top_sv_unit File: d:/work/DAC_GEv3_repo_test/
FPGA_DACGEV3/Simulation/Questasim_top/../../Sources/Simulation/
system_verilog_top/DACGEv3_testbench_top.sv

Trap with bind and VHDL - make sure the case of the target and target
instance are correct. Even if VHDL source has upper case, these turn
into lower case. VHDL is case insensitive so assume everything gets
turned into lower case. SV is case sensitive so must use lower case
even though source has upper case.

PS - thanks for your explanaation on those OVM q's. Apparently this is
very useful to my colleague who is working on our use of OVM. Bit
scary though - I do wonder if OVM is too much tool for us. I'm
convinced SV is for us, but OVM I'm less convinced.

Cheers
Andrew
 
Andrew FPGA <andrew.newsgroup@gmail.com> writes:

Hi Jonathan, (and anyone else who needs to do this in the future)
I have your option 3 working. :) SV bind a module wrapping the SV
Thank you for sharing this with us. I've used SV (VCS) and VHDL
(Modelsim) separately, but never toghether, even though I would like
to do so in the near future.

Does anybody have any experience with SV/VHDL co-simulation using
VCS/MX from Synopsys?

Petter
--
A: Because it messes up the order in which people normally read text.
Q: Why is top-posting such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
 
On Thu, 18 Feb 2010 20:07:16 -0800 (PST), Andrew FPGA wrote:

Hi Jonathan, (and anyone else who needs to do this in the future)
I have your option 3 working. :) SV bind a module wrapping the SV
interface. Then push a virtual interface to a static member of a
class. Top level testbench then pulls the virtual interface from this
class.

But, I do have this issue I don't understand. I get the error below
during elaboration. A work around is to create a dummy gmii_if
interface instance in the testbench top level module. Its not
connected to anything, but at least it allows questa to elaborate
without this Fatal. Googling shows folk mentioning a -
permit_umatched_virtual_intf option as another work around - but I
can't find this in the manual and nor does it seem to work.

# ** Fatal: (vsim-8451) d:/work/DAC_GEv3_repo_test/FPGA_DACGEV3/
Simulation/Questasim_top/../../Sources/Simulation/system_verilog_top/
DACGEv3_testbench_top.sv(52): Virtual interface resolution cannot find
a matching instance of interface 'gmii_if.phy'.
Can you share the relevant bits of code with us? I can't
really see what the problem is from this diagnostic.

Oh, horror - I suppose it's because the interface instance
is inside a module that is instanced only by 'bind'. It
still seems wrong, though. I guess you could try
using -permit_unmatched_virtual_intf on the vsim command
line, but I was under the impression that was more to do
with relaxing Mentor's fairly aggressive interpretation
of SV's extremely foggy rules concerning the data type
of a parameterized interface. Does your interface
have parameters? If so, it may be important even if
you leave the parameters at their default value. That
is a major area of confusion in the SV standard; I've
collaborated with Mentor in the past on a couple of
papers complaining/ranting about it.

Are you aware of the -cuname commandline fandango that
you can use to force elaboration of a package that is
imported only by bound modules? That might help too.
Just trawl the Questa docs for the -cuname option -
don't ask me to explain, it busts my head every time.

One last possible act of desperation: can you postpone
creation of the virtual interface reference for a very
short time after elaboration, so that you can be 100%
sure the entire hierarchy (including all bound instances)
is elaborated first? A simple #0 (#1 if you're paranoid)
delay before the assignment might do the trick. But
such a delay might have nasty consequences for the time-0
construction of your class-based testbench :-(

Trap with bind and VHDL - make sure the case of the target and target
instance are correct. Even if VHDL source has upper case, these turn
into lower case. VHDL is case insensitive so assume everything gets
turned into lower case. SV is case sensitive so must use lower case
even though source has upper case.
Yup, that's the way Modelsim/Questa does it - all VHDL
names are internally flattened to lowercase. I'm not
sure about other tools. If you really need mixed-case
names you can always use VHDL escaped identifiers
(Please Nurse, the kidney-bowl!).

PS - thanks for your explanaation on those OVM q's. Apparently this is
very useful to my colleague who is working on our use of OVM. Bit
scary though - I do wonder if OVM is too much tool for us. I'm
convinced SV is for us, but OVM I'm less convinced.
I sympathise (or maybe empathise?), but you're in for
a fair amount of wheel re-invention if you don't adopt
one of the major methodologies.
--
Jonathan Bromley
 
Hi Andrew and Jonathan,

I sympathise (or maybe empathise?), but you're in for
a fair amount of wheel re-invention if you don't adopt
one of the major methodologies.
--
While I respect Jonathan and count him among my friends, I disagree
with his statement. Your experience, your team, and your company are
all factors that go into a methodology. The heaver the methodology,
the less likely it is to fit your situation. And OVM (now UVM) and VMM
and quite heavy. Besides there is not that much well though out code
in there ;-)

I have developed a free, open-source, true multi-vendor lightweight
methodology that may be useful to you. It's available (at www.trusster.com)
in SV and C++ (and systemc as well). It's only a handful of source
files, so you can pick and choose what fits your team.

Take Care,
Mike Mintz
mike <> trusster <> com
 
On Fri, 19 Feb 2010 06:00:37 -0800 (PST), "mmintz@gmail.com" wrote:

Hi Andrew and Jonathan,

I sympathise (or maybe empathise?), but you're in for
a fair amount of wheel re-invention if you don't adopt
one of the major methodologies.
--

While I respect Jonathan and count him among my friends, I disagree
with his statement.
And who was it, Mike, who excluded Teal/Truss from "major
methodologies"? Not I; I was rather careful in my
choice of words :)

Your experience, your team, and your company are
all factors that go into a methodology. The heaver the methodology,
the less likely it is to fit your situation. And OVM (now UVM) and VMM
and quite heavy.
All true.

Besides there is not that much well though out code
in there ;-)
I think that's a bit unfair. I don't want to get into a
slanging match about features vs. elegance vs. robustness
and all that sort of crap, but all these toolkits (for
that's what they are; "methodology" is way over-the-top)
have to compromise in the face of many sometimes
conflicting requirements. Not least among these are
"must run on existing SV tools" and "must look at least
slightly like another methodology we used to promote".
Given all those things, OVM and VMM don't do too badly.
However, I have to agree with you that the feature bloat
that makes VMM tricky to approach for new users is also
beginning to afflict OVM; whatever you provide, there
will always be some customer who wants you to provide
more. Personally I'm all in favour of the lightweight
toolkit that allows me to throw together whatever
suits me, but there are always folk who want everything
served up to them in party dress, and software tool
vendors are usually only too keen to oblige (will the
real Windows Vista please stand up?).

I have developed a free, open-source, true multi-vendor lightweight
methodology that may be useful to you. It's available (at www.trusster.com)
in SV and C++ (and systemc as well). It's only a handful of source
files, so you can pick and choose what fits your team.
And I should have mentioned that. Thanks for keeping me honest.
--
Jonathan Bromley
 
Hi Jonathan (and others),
Can you share the relevant bits of code with us?  I can't
really see what the problem is from this diagnostic.
Here is the complete code sample, including my work around to avoid
the elaboration Fatal. Little concerned about the way I put the
virtual interface on the stack, but I think I'm just storing a
reference temporarily on the stack temporarily so ok? As long as a
reference to the real SV inteface makes its way to the class based
testbench driver, then I think all is good....But I'm no virtual
expert.

***Within bound module. This gets bound inside the DUT to expose an
internal DUT interface.
Instantiate SV interface, push it to a static class member.

//Instance SV Interface
gmii_if ch0();

//Hookup the SV interface to this modules ports.
assign sys_clk_125m = ch0.rx_clk;
assign data_out_mii_ch0 = ch0.rxd;
...and so on

//Make the SV interface available to the testbench top level as a
virtual interface.
initial begin
string identity;
$sformat(identity, "%m");
$display("Registering GMII interfaces from %s", identity);
GMII_registry::put("GMII_ch0",ch0);
end

***Class holding virtual interfaces in static members

class GMII_registry;
//Store for registered hooks.
static virtual gmii_if registered_hooks[string];

//Allow hooks to be registered.
static function void put( input string ID,
input virtual gmii_if hook);
assert (!registered_hooks.exists(ID)) else
$error($psprintf("Register GMII hook %s twice!", ID));
registered_hooks[ID] = hook;
endfunction

//Allow read access to register hooks.
static function void get( input string ID,
output virtual gmii_if hook );
$display("Getting GMII interface hook %s", ID);
assert (registered_hooks.exists(ID)) else
$error($psprintf("GMII hook %s has not been registered.", ID));
hook = registered_hooks[ID];
endfunction
endclass

***Testbench top level. Binds into DUT a module containing SV
interfaces. Build the class based testbench hierarchy which attaches
to DUT via virtual interfaces.

bind sgmii_pcs_1g :dut.vhdl_module.serdes_cor.pcsa_quad
SGMII_PCS_1G_SV_interface SGMII_PCS_1G_SV_interface_inst(.*);

//Build the class based testbench hierarchy.
initial
begin
build_test_harness_ethernet();
//run some test cases....
...
end

GMII_driver GMII_driver_port0;

//Build the test harness components for ethernet frame generation/
checking (i.e. via GMII interfaces).
task automatic build_test_harness_ethernet();
virtual gmii_if gmii_vif_ch0;

//Get handle to the bound GMII SV interface
GMII_registry::get( "GMII_ch0", gmii_vif_ch0 ); //dodgy?
gmii_vif_cho doesn't exist once build_test_harness_ethernet returns

//Create GMII driver object, start it up.
GMII_driver_port0 = new( gmii_vif_ch0 );
GMII_driver_port0.run();
endtask

//Dummy to prevent Questa elaboration Fatal.
gmii_if dummy();

***And here is the GMII driver object.

class GMII_driver;
virtual gmii_if.phy gmii_vif;
function new( virtual gmii_if.phy gmii_vif );
this.gmii_vif = gmii_vif;
endfunction

task automatic run();
//Assume we are PHY, and generate rx clock.
$display("Starting GMII rx_clk generation.");
fork
generate_clocks();
join_none
endtask

local task automatic generate_clocks();
this.gmii_vif.rx_clk = 0;
forever #4 this.gmii_vif.rx_clk <= ~this.gmii_vif.rx_clk;
endtask

endclass

***And here is the SV interface definition itself
interface gmii_if ();
//Reconciliation sublayer
logic [7:0] txd;
logic tx_en;
logic tx_er;
logic gtx_clk;

logic [7:0] rxd;
logic rx_dv;
logic rx_er;
logic rx_clk;

logic col, crs; //collision detect, carrier sense

modport mac ( output txd, tx_en, tx_er, gtx_clk,
input rxd, rx_dv, rx_er, rx_clk, col, crs );

modport phy ( output rxd, rx_dv, rx_er, rx_clk, col, crs,
input txd, tx_en, tx_er, gtx_clk );

endinterface : gmii_if

Cheers
Andrew
 
On Sun, 21 Feb 2010 16:33:18 -0800 (PST), Andrew FPGA wrote:

Hi Jonathan (and others),
Can you share the relevant bits of code with us?  I can't
really see what the problem is from this diagnostic.

Here is the complete code sample
Andrew, I'm not ignoring you, but I'm a bit
stretched at the moment and won't have a chance
to look at your code for at least a couple of days.
Apologies - I would like to sort this out for
myself too! Anyways, I'm glad you found a
workaround. And I really will look at it as
soon as I am able.

Little concerned about the way I put the
virtual interface on the stack
A virtual interface is just a variable; make copies
of it where and when you feel like it. I've even seen
people pass them through ports, which strikes me as
disturbingly perverted, but there's no accounting for
taste. Or, as they say in the part of England where I
was brought up, "there's nowt so queer as folk".
--
Jonathan Bromley
 
Andrew, I'm not ignoring you, but I'm a bit
stretched at the moment
No probs. This is usenet after all :) I have a workaround, but there
is always that irksome feeling its going to come back and bite me...

A virtual interface is just a variable; make copies
of it where and when you feel like it.
I guess the thing that is bothering me is that the variable ceases to
exist once the automatic task that declared it returns. I.e. the task
is called, the variable goes on the stack, task ends so the variable
ceases to exist/its memory use deallocated. I'm assuming SV is similar
to say C in that regard. So my concern is, will I still have a valid
reference to my SV interface, after the variable has ceased to exist
on the stack.

Maybe SV garbage collector at play here?... SV knows there is still a
reference to that variable, so even though the variable is out of
scope, it doesn't deallocate its memory yet.

Cheers
Andrew
 
On Feb 23, 5:49 pm, Jonathan Bromley <jonathan.brom...@MYCOMPANY.com>
wrote:
A virtual interface is just a variable; make copies
of it where and when you feel like it.  I've even seen
people pass them through ports, which strikes me as
disturbingly perverted, but there's no accounting for
taste.
I believe that the LRM states that ports of type virtual interface are
illegal.

I don't know why this is the case. Perhaps somebody figured you could
already pass an interface through an interface port, and didn't want
confusion between interface ports and a variable port of type virtual
interface. But an interface port is statically bound to a particular
interface at elaboration time. Passing a virtual interface through a
port would allow changing which interface it referenced at runtime.
Admittedly, most virtual interfaces probably get initialized to a
particular interface near the start of simulation and never changed
afterwards. But there still might be situations where this would be
useful.

As you say, a virtual interface is just a variable. I don't see any
reason why passing it through a port would be different from passing
any other kind of variable.

There would still be some differences between an interface port, and a
virtual interface port that happened to be connected to a specific
instance. You are allowed to reach into interfaces and refer to types
and parameter values there, and have it considered an elaboration-time
constant. I don't think you can do that with a virtual interface
(though the type of the virtual interface, including its
parameterization, should be known at elaboration). An interface port
can be unparameterized, or even completely generic, and it will become
whatever type of interface is connected. A virtual interface port
would have to specify the full datatype of the port, which includes
the specific interface declaration and its parameterization.
 

Welcome to EDABoard.com

Sponsor

Back
Top