FW: [sv-bc] 0003605: UVM ubus example should not use controversial code with variable driven by mix of continous assignment and procedural assign

From: Alsop, Thomas R <thomas.r.alsop@intel.com>
Date: Tue Aug 06 2013 - 16:50:27 PDT
Forwarding Steven and Brad's explanation and some suggestions Steven made to fix this.  Thanks Guys! -Tom

From: Steven Sharp [mailto:sharp@cadence.com]
Sent: Tuesday, August 06, 2013 4:26 PM
To: Alsop, Thomas R; Brad Pierce
Cc: Arturo Salz
Subject: RE: [sv-bc] 0003605: UVM ubus example should not use controversial code with variable driven by mix of continous assignment and procedural assign

They might have been trying to create a multiply driven signal, but there is no way to use a variable to do that.  Variables are either updated with procedural writes, or they are treated like a "poor man's" wire that can only be driven by a single continuous assignment.  Mixtures or multiple drivers are forbidden because they would not behave like a real wire.

Your attempt to change this to a wire would allow it to be multiply driven, but then a wire cannot be procedurally assigned through the virtual interface.  Wires have to be continuously driven, and the values of multiple continuous drivers then continuously resolved.

To make this work, I think you would have to do something like the following, which creates two continuous assignments driving the wire, with one of the drivers using the value of a variable that can be updated using the virtual interface.  If you wanted the output port to actually be able to drive a non-z value, you would need to add logic to make sure that sig_read_driver was z any time the output port was driving.

interface iface;
            logic clk;
            wire sig_read;
            logic sig_read_driver = 1'bz;
            assign sig_read = sig_read_driver;
       endinterface

       module dut(input clk,output reg xbus_read);
            initial xbus_read<=1'bz;
            always @(posedge clk)begin
                xbus_read<=1'bz;
                $display("2: xbus_read<=1'bz");
            end
       endmodule

       class C;
            virtual iface vi;
            function new(virtual iface i);
                vi=i;
            endfunction
            function drive;
                vi.sig_read_driver<=1; //write to sig_read_driver which drives sig_read
                $display("1: vi.sig_read<=1");
            endfunction
       endclass

       module top;
            iface iface_i();
            dut uut(iface_i.clk,iface_i.sig_read);* //dut instantation - continous drive of sig_read*
            C c =new(iface_i);
            initial iface_i.clk=0;
            always #5 iface_i.clk = ~ iface_i.clk;
            initial begin
                $display("START");
                 $monitor($time,">>>>", iface_i.sig_read);
                @(posedge iface_i.clk)
                c.drive();
                @(posedge iface_i.clk);
                #1;
                $display("END");
                assert(iface_i.sig_read)else $fatal("fatal error");
                $finish;
                end

       endmodule



From: Alsop, Thomas R [mailto:thomas.r.alsop@intel.com]
Sent: Tuesday, August 06, 2013 6:21 PM
To: Brad Pierce
Cc: Steven Sharp; Arturo Salz
Subject: RE: [sv-bc] 0003605: UVM ubus example should not use controversial code with variable driven by mix of continous assignment and procedural assign

Hold on, I see what I am missing Brad.  I didn't realize this was a multiply driven port.  We do not do this that I know of here at Intel unless we declare these buses to be wire types with the appropriate pull strengths, etc...  Sorry, I completely missed that.  So really the example needs to be updated so that it reflects the proper way to model a high impedance driver.

Would this be the appropriate change:

interface iface;
            logic clk;
            wire sig_read;
       endinterface

       module dut(input clk,output wire xbus_read);
            assign xbus_read =1'bz;
            $display("2: xbus_read =1'bz");
       endmodule

       class C;
            virtual iface vi;
            function new(virtual iface i);
                vi=i;
            endfunction
            function drive;
                vi.sig_read =1;* //procedural drive of sig_read*
                $display("1: vi.sig_read =1");
            endfunction
       endclass

Thanks!! -Tom

From: Brad Pierce [mailto:Brad.Pierce@synopsys.com]
Sent: Tuesday, August 06, 2013 2:59 PM
To: Alsop, Thomas R
Cc: Steven Sharp; Arturo Salz
Subject: RE: [sv-bc] 0003605: UVM ubus example should not use controversial code with variable driven by mix of continous assignment and procedural assign

Hi Tom,

I don't know the reason for the LRM restrictions or if they are sensible. According to 23.3.3.2,

Procedural or continuous assignments to a variable connected to the output port of an instance shall be illegal.

If you're doing that, and it's working fine, then I'd suspect the LRM is overly restrictive, or that there's a loophole for virtual interfaces. In synthesis you would get a multiply-driven error, but you wouldn't be synthesizing your testbench, and there's no problem in simulation with multiply-driving.

-- Brad

From: Alsop, Thomas R [mailto:thomas.r.alsop@intel.com]
Sent: Tuesday, August 06, 2013 2:41 PM
To: Brad Pierce
Cc: Steven Sharp
Subject: RE: [sv-bc] 0003605: UVM ubus example should not use controversial code with variable driven by mix of continous assignment and procedural assign

Hi Brad,

By this definition every connection up through the module hierarchy is a continuous assignment while at the leaf level module we drive these signals with procedural assignments.  So we violate this everywhere in our Intel designs.

Thanks,
-Tom

From: Brad Pierce [mailto:Brad.Pierce@synopsys.com]
Sent: Tuesday, August 06, 2013 2:11 PM
To: Alsop, Thomas R
Cc: Steven Sharp
Subject: RE: [sv-bc] 0003605: UVM ubus example should not use controversial code with variable driven by mix of continous assignment and procedural assign

Hi Tom,

According to 23.3.3

Each port connection shall be a continuous assignment of source to sink, where one connected item shall be a signal source and the other shall be a signal sink.

I think this means that the output port connection in the following is itself a continuous assignment.

     dut uut(iface_i.clk,iface_i.sig_read);
     //dut instantation - continous drive of sig_read*

     module dut(input clk, output reg xbus_read);

-- Brad

From: owner-sv-bc@eda.org<mailto:owner-sv-bc@eda.org> [mailto:owner-sv-bc@eda.org] On Behalf Of Alsop, Thomas R
Sent: Tuesday, August 06, 2013 2:01 PM
To: sv-bc@eda.org<mailto:sv-bc@eda.org>
Cc: Miller Hillel-R53776
Subject: [sv-bc] 0003605: UVM ubus example should not use controversial code with variable driven by mix of continous assignment and procedural assign

Question for the sv-bc team from a UVM bug that I own.

Daniel Mlynek filed this UVM Users Guide bug awhile ago.  Looking more closely at the code, I am not sure I agree with the fact that there is any continuous assignment in here for the signal 'sig_read'.  I have highlighted the relevant code below.  According to the latest LRM clause 10.4, all cases of sig_read appear to be "triggered" assignments.  Specifically the one that he calls continuous is the instantiation of the dut, but in this case xbus_read is driven via an initial block and within and always procedural block.  These are both considered procedural assignments.  Am I missing something?

http://www.eda.org/svdb/view.php?id=3605

Thanks, -Tom


Below code show the problem in UBUS.
Variable sig_read is driven by both continous assignment in instance port and procedural assignment via virtual interface.
Such code is not currently officialy blocked by LRM but it is at least controversial.
Official example should not use such code pattern as good idea.

interface iface;
            logic clk;
            logic sig_read;
       endinterface

       module dut(input clk,output reg xbus_read);
            initial xbus_read<=1'bz;
            always @(posedge clk)begin
                xbus_read<=1'bz;
                $display("2: xbus_read<=1'bz");
            end
       endmodule

       class C;
            virtual iface vi;
            function new(virtual iface i);
                vi=i;
            endfunction
            function drive;
                vi.sig_read<=1;* //procedural drive of sig_read*
                $display("1: vi.sig_read<=1");
            endfunction
       endclass

       module top;
            iface iface_i();
            dut uut(iface_i.clk,iface_i.sig_read);* //dut instantation - continous drive of sig_read*
            C c =new(iface_i);
            initial iface_i.clk=0;
            always #5 iface_i.clk = ~ iface_i.clk;
            initial begin
                $display("START");
                 $monitor($time,">>>>", iface_i.sig_read);
                @(posedge iface_i.clk)
                c.drive();
                @(posedge iface_i.clk);
                #1;
                $display("END");
                assert(iface_i.sig_read)else $fatal("fatal error");
                $finish;
                end

       endmodule

--
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 Aug 6 16:51:34 2013

This archive was generated by hypermail 2.1.8 : Tue Aug 06 2013 - 16:51:42 PDT