RE: [sv-ec] How do I make a "Virtual Port"

From: Rich, Dave <Dave_Rich_at_.....>
Date: Tue Oct 07 2008 - 10:15:53 PDT
'<=' is an overloaded operator. We have to know the type and, in this
case, the fact that the identifier is a clocking block output to
determine what the syntax represents.

 

Ignoring the clocking block issue for the moment, you could create a
parameterized interface for each signal

 

interface reference #(type T)(ref T signal);

endinterface

 

typedef virtual reference #(bit) ref_bit;

typedef virtual reference #(logic [31:0])   ref_bit32;

 

class RegisterAccess ; 

    ref_bit myPwrUp;

    ref_bit32 myRegWr;

 

    function new(ref_bit_ myPwrUp, ref_bit32 myRegWr);

       this.myPwrUp = myPwrUp;

       this.myRegWr = myRegWr;

    endfunction

    task Write (input logic        ThreadM000H, 

                input logic [10:0] AddrM000H,

                input logic [31:0] DataM000H);

          myPwrUp.signal <= 1'b1;

      #1 myRegWr.signal <= {2'b00, 1'b1, 1'b0, ThreadM000H, AddrM000H};

      #2 myRegWr.signal <= DataM000H[15:0];

      #2 myRegWr.signal <= DataM000H[31:16];

          myPwrUp.signal <= 1'b0;

   endtask

 

 

 

________________________________

From: Alsop, Thomas R [mailto:thomas.r.alsop@intel.com] 
Sent: Tuesday, October 07, 2008 9:25 AM
To: Rich, Dave; sv-ec@server.eda.org; Stuart Sutherland
Subject: RE: [sv-ec] How do I make a "Virtual Port"

 

So it sounds like the proposal is going to have code that looks
something like this.  Does this look right?  

 

 class RegisterAccess ; 

    ref static logic          myPwrUp;

    ref static logic [31:0]   myRegWr;

 

    function new(ref static logic myPwrUp, [31:0] myRegWr);

       this.myPwrUp = myPwrUp;

       this.myRegWr = myRegWr;

    endfunction

 

On the clocking block issue, is this something that can be inferred?  I
assumed that clocking block outputs would be know by the implementation
so if I am driving via '<=' you would know from the LHS variable whether
or not it's a clocking block output.  If it isn't then it's a NBA.  

 

On the code snippet, thanks, I simulated it.  I'm not sure this works
for me.  I want to use ref in classes and access them through object
construction.  And if I could derive the ref in the class from the
interface, it still implies that I would have to port out all the
signals I wanted to reference in my interface port list as ref's, yet
another undesirable list I have to maintain.  

 

Thanks, -Tom

 

________________________________

From: Rich, Dave [mailto:Dave_Rich@mentor.com] 
Sent: Tuesday, October 07, 2008 8:19 AM
To: Alsop, Thomas R; sv-ec@server.eda.org; Stuart Sutherland
Subject: RE: [sv-ec] How do I make a "Virtual Port"

 

Tom,

 

A key point missed with what you are proposing is that we will need
concrete types associated with the reference. You should not be allowed
to dynamically change the type of your reference. We would need also to
know the MyPwrup is a one bit clocking block output and MyRegWr is a 36
bit clocking block output in order to recognize that '<=' is clocking
block drive, and not an NBA.

 

I think you should be able to use ref ports in an interface in today's
SV to get handles to static objects.

 

interface itf(ref int A,input bit clk);

   clocking cb @(posedge clk);

      output A;

   endclocking // cb 

endinterface // itf

 

module top;

   bit clk;

   

bot b1();

 

int external=3;

 

itf i1(b1.internal,clk);

itf i2(external,clk);

  

virtual itf vitf;

 

initial begin

   vitf = i1; // now have a handle to bot.internal

   $display(vitf.A);

   vitf.A <= 2; // NBA

   $display(vitf.A);

   vitf = i2; // now have a handle to external

   $display(vitf.A);

   vitf.cb.A <= 4; // clocking drive

   clk = 1;

   #1;

   $display(vitf.A);

   

end

endmodule

module bot;

   int internal;

endmodule

________________________________

From: owner-sv-ec@server.eda.org [mailto:owner-sv-ec@server.eda.org] On
Behalf Of Alsop, Thomas R
Sent: Monday, October 06, 2008 11:56 AM
To: Rich, Dave; sv-ec@server.eda.org; Stuart Sutherland
Subject: RE: [sv-ec] How do I make a "Virtual Port"

 

Thanks Dave.  I did attempt to implement Jonathan's technique but with
the simulator I am using I get illegal port reference errors.  I
mentioned to him and I'll state my opinion here on the reflector as
well, that I appreciate the attempts to make this work, but both
approaches, yours and his, while very elegant are also very indirect.  

 

Also, just a follow up on the fork-join issue below.  Am I correct in my
understanding that references to formal arguments (like XMR's) cannot be
used in anything but fork/join (i.e. not join_none and join_any)?  The
2005 LRM example simple gave this example where 'm' could be undermined,
but who would code this?  If someone coded this, then bad coder, they
deserve to see their value stomped on.  Why limit what we can do this
references to protect ourselves against bad coders.  Most designs have
linting rules anyway that could be written to protect against this. What
am I missing?

 

Variables declared in the block_item_declaration of a fork...join,
join_any, or join_none block shall

be initialized to their initialization value expression whenever
execution enters their scope and before any

processes are spawned. Within a fork...join_any or fork...join_none
block, it shall be illegal to refer

to formal arguments passed by reference other than in the initialization
value expressions of variables

declared in a block_item_declaration of the fork. These variables are
useful in processes spawned by looping

constructs to store unique, per-iteration data. For example:

 

initial

   for( int j = 1; j <= 3; ++j )

      fork

         automatic int k = j; // local copy, k, for each value of j

         #k $write( "%0d", k );

         begin

            automatic int m = j; // the value of m is undetermined

            ...

         end

      join_none

 

The example above generates the output 123.

 

My request to the sv-ec team will be to allow references in classes
without any stipulations (or reasonable ones).  I want to be able to do
something like this:

 

 class RegisterAccess ; 

    ref        myPwrUp;

    ref        myRegWr;

 

    function new(ref myPwrUp, myRegWr);

       this.myPwrUp = myPwrUp;

       this.myRegWr = myRegWr;

    endfunction

 

   task automatic Write (input logic        ThreadM000H, 

                         input logic [10:0] AddrM000H, 

                         input logic [31:0] DataM000H);

          myPwrUp <= 1'b1;

      ##1 myRegWr <= {2'b00, 1'b1, 1'b0, ThreadM000H, AddrM000H};

      ##2 myRegWr <= DataM000H[15:0];

      ##2 myRegWr <= DataM000H[31:16];

          myPwrUp <= 1'b0;

   endtask

 

 Construction code:

 

    RegisterAccess RA;

    initial begin

       RA = new(cb.mu2mlcrwrpwrup, cb.mu2mlcrwr, cb.ml2mucrrd);

       ...

       RA.Write(1'b1, 11'h3FF, 32'hFFFF_0000);

 

This is very clean, very direct, gives simple access to interface and/or
internal DUT signals, and makes it all very generic so I can reuse this
code with any set of signals anywhere in my design; I simply construct
the object with the correct signals (local or XMR) and then call the
method to act on them. 

 

Thanks, 

-Tom

 

________________________________

From: owner-sv-ec@server.eda.org [mailto:owner-sv-ec@server.eda.org] On
Behalf Of Rich, Dave
Sent: Saturday, October 04, 2008 11:12 PM
To: sv-ec@server.eda.org; Stuart Sutherland
Subject: RE: [sv-ec] How do I make a "Virtual Port"

 

Stu and Jonathon,

 

There seems to be an improper editorial change going from draft4 to
draft5. There was a change to consolidate explicitly stating all the
various fork blocks into a generic fork block

 

"Within a fork-join_any or fork-join_none fork-join block-block,

it shall be illegal to refer to formal arguments passed by reference
other than in the initialization value expressions of variables declared
in a block_item_declaration of the fork."

 

However in this case, the simple fork/join was originally excluded
because only the other two types of forks were explicitly mentioned. The
original text from IEEE Std 1800-2005 thru draft 4 says

 

"Within a fork-join_any or fork-join_none block, it shall be illegal to
refer to formal arguments passed by reference other than in the
initialization value expressions of variables declared in a
block_item_declaration of the fork."

 

Jonathan,

 

So I do believe it is legal to call the start() task within a
fork/join_none with a hierarchical reference as its actual argument.

 

I believe the LRM does not specify the effect on an actual argument
passed by reference, but I agree that it should be counted as a
potential procedural assignment. However, if you change the formal to a
const ref, then there can be no assignment to that argument. That should
allow you to set up a monitor to a variable that has a continuous
assignment.

 

Dave

 

 

> -----Original Message-----

> From: owner-sv-ec@server.eda.org [mailto:owner-sv-ec@server.eda.org]
On

> Behalf Of Brad Pierce

> Sent: Saturday, October 04, 2008 10:02 AM

> To: sv-ec@server.eda.org

> Subject: RE: [sv-ec] How do I make a "Virtual Port"

> 

> Jonathan,

> 

> > illegal to access a ref argument in a fork...join_none

> 

> I don't know if it's relevant to your test case, but according to the

> LRM via ballot issue 232 (Mantis 652)

> 

>    "Within a fork-join block, it shall be illegal to refer to formal

> arguments passed by reference other than in the initialization value

> expressions of variables declared in a block_item_declaration of the

> fork."

> 

> -- Brad

> 

> -----Original Message-----

> From: owner-sv-ec@eda.org [mailto:owner-sv-ec@eda.org] On Behalf Of

> jonathan.bromley@doulos.com

> Sent: Saturday, October 04, 2008 1:01 AM

> To: Rich, Dave

> Cc: sv-ec@eda.org; Alsop, Thomas R

> Subject: RE: [sv-ec] How do I make a "Virtual Port"

> 

> [Dave Rich]

> > Having said all that, I do have a register probe class (attached)

> > that may do what you are looking for. You can pass a hierarchical

> > signal to the constructor, and it forks off two threads that keep

> > the signal in sync with the class property.

> 

> I suggested something very similar to Tom Alsop in a

> separate email:  spawn, as an independent thread,

> a long-running task that has the signal of interest

> as a ref argument.  It's potentially a very useful

> idea, I believe.

> 

> Unfortunately, one of the three mainstream simulators

> I can try reports this as an error, asserting that it

> is illegal to access a ref argument in a fork...join_none.

> This seems odd to me, but I can't really find LRM

> evidence to back up the legality of such usage.

> 

> Yet another simulator allows it, but infers a

> procedural driver on the signal from the fact

> that it is passed to a task as a ref argument;

> this prevents you from using the technique

> to monitor the state of any signal that has

> a continuous driver on it.

> 

> I'm sure someone else has a clearer idea than I do

> about whether all this is truly legal and reasonable...

> --

> Jonathan Bromley

> Consultant

> 

> DOULOS - Developing Design Know-how

> VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

> 

> Doulos Ltd. Church Hatch, 22 Market Place, Ringwood, Hampshire, BH24

> 1AW,

> UK

> Tel: +44 (0)1425 471223                   Email:

> jonathan.bromley@doulos.com

> Fax: +44 (0)1425 471573                           Web:

> http://www.doulos.com

> 

> This message may contain personal views which

> are not the views of Doulos Ltd., unless specifically stated.

> 

> 

> --

> This message has been scanned for viruses and

> dangerous content by MailScanner, and is

> believed to be clean.

> 

> 

> --

> This message has been scanned for viruses and

> dangerous content by MailScanner, and is

> believed to be clean.

> 

 


-- 
This message has been scanned for viruses and 
dangerous content by MailScanner <http://www.mailscanner.info/> , and is

believed to be clean. 
-- 
This message has been scanned for viruses and 
dangerous content by MailScanner <http://www.mailscanner.info/> , and is

believed to be clean. 

-- 
This message has been scanned for viruses and
dangerous content by MailScanner, and is
believed to be clean.
Received on Tue Oct 7 12:23:08 2008

This archive was generated by hypermail 2.1.8 : Tue Oct 07 2008 - 12:23:56 PDT