5

I'd like to know if it's possible to somehow figure out if, by mistake, inside a UVM driver the developer writes to a DUT output signal, instead of an input signal. I've tried this out and there is no compile/runtime error message. The example is here (try outs were done in Incisive on my machine and the code later uploaded):

http://www.edaplayground.com/x/386

The assign on 'some_signal' models a DUT output (a continuous driver). I would have expected a runtime error whenever I try to drive 'some_signal' from the class saying that the signal is multiply driven, but the class driver "wins" and updates the signal.

Some time ago, when I had just started doing SV I played around with modports. I would declare some signals as inputs in the modport, but I noticed that it was still legal to drive them. I quit using them afterwards. Apparently this is something well known, as this post says: https://verificationacademy.com/forums/systemverilog/modports-sv

I recently inherited some code from a colleague that makes use of modports in classes. I made the following example to illustrate what that code is doing:

http://www.edaplayground.com/x/2W_

I try to use modports in the two classes, but ModelSim complains that one should not use modports in hierarchical paths. Incisive had no problem with the code and issued no warnings. The ModelSim errors, together with this quote from the 2012 standard "To restrict interface access within a module, there are modport lists with directions declared within the interface." kind of suggest that modports aren't really intended to be used in classes.

Can someone confirm that modports aren't the way to go here? Also, does anyone know if such errors (driving DUT outputs from classes) could be caught in any way?

Tudor Timi
  • 7,453
  • 1
  • 24
  • 53
  • I am confused by modports as well, but I think what what you want to use here are clocking blocks. Do they give you the same issues? – nguthrie Feb 26 '14 at 00:19
  • Good idea, I'll try it out and post the results. – Tudor Timi Feb 26 '14 at 10:07
  • I've made another playground using clocking blocks http://www.edaplayground.com/x/2yV It does issue an error if I try to write to an input, but only in Incisive and not in the ModelSim version on EDA Playground. – Tudor Timi Feb 26 '14 at 16:50
  • The example in 1800-2012 just before section 25.9.1 shows assigning virtual interfaces with modports. This may be helpful. – nguthrie Feb 26 '14 at 19:59

1 Answers1

1

Tried the following code in vcs and got the below error.

Error-[MPCBD] Modport port cannot be driven modp.sv, 32 some_package, "vif.some_signal" Port 'some_signal' of modport 'slave' has been restricted as an input port. Input ports cannot be driven.

interface some_interface();
  bit clk;
  logic some_signal;
  logic some_signal2;

  modport master(input clk, output some_signal);
  modport slave(input clk, input some_signal);
  modport temp (output some_signal, output some_signal2);
endinterface


package some_package;

  class some_master_class;
    virtual some_interface.master vif;

    task do_something();
      @(posedge vif.clk);
      vif.some_signal <= 1;

      @(posedge vif.clk);
      vif.some_signal <= 0;
    endtask
  endclass


  class some_slave_class;
    virtual some_interface.slave vif;

    task do_something();
      forever @(posedge vif.clk);
        vif.some_signal = 0;
      //$display("some_signal = ", vif.some_signal);
    endtask
  endclass  

endpackage

module temp_1 (some_interface.temp iif);
  assign iif.some_signal = 1;
  assign iif.some_signal2 = 0;
endmodule

module top();

  import some_package::*;

  some_interface my_if();

  bit clk;
  always #1 clk = ~clk;

  assign my_if.clk = clk;

  temp_1 temp (my_if.temp);

  initial begin
    some_master_class master = new();
    some_slave_class slave = new();

    master.vif = my_if.master;
    slave.vif = my_if.slave;

    fork
      master.do_something();
      slave.do_something();
    join_any

    $finish();
  end

endmodule

As I understand when we mention a signal as an output in the modport we just say that the signal's direction is like a output from this block. It doesn't care whether any other block is driving the same.(I guess the standard doesn't mention any restriction about this). I guess that's why we get error for an input being driven and not for an output.

From 25.5 if IEEE Std 1800-2009:

To restrict interface access within a module, there are modport lists with directions declared within the interface. The keyword modport indicates that the directions are declared as if inside the module.

Vineeth VS
  • 404
  • 8
  • 18
  • I tried it in a newer version of Questa and it doesn't issue any warnings, but writing to modport inputs is still allowed, which defeats the purpose. – Tudor Timi Feb 27 '14 at 16:30
  • @Tudor: Don't you get at least a warning for writing to the input of a `modport`? When you write are you using `intf.modport.signal` ? – Vineeth VS Feb 27 '14 at 16:38
  • Nope, no warning, no error, no nothing. Like I linked in the question, apparently this is because the standard didn't explicitly state that it's illegal to drive inputs. For clocking blocks it does say that and there an error is explicitly triggered. – Tudor Timi Feb 28 '14 at 09:09
  • With regard to your latest edit: I've tried it in both Questa and in Incisive and it doesn't issue any error. VCS I don't have, but it's cool to see that at least there is an error there. Also, driving the same net/logic/etc. from multiple processes (initial, always, etc.) is in general not checked, regardless. The last scheduled update wins. – Tudor Timi Feb 28 '14 at 15:30
  • @Tudor If you don't get warning/errors I think you should ask the tool vendors... As I understand driving a modport input is illegal. – Vineeth VS Mar 02 '14 at 07:36