2

I have defined an interface for my DUT as such:

interface video_input_interface(clk, rst);

   input logic       clk;
   input logic       rst;
         logic[1:0]  x_lsb;
         logic[1:0]  x_msb;
         logic[3:0]  x;

   assign x = {x_msb, x_lsb};
endinterface

The reason I did this is because my DUT has separate ports for x_msb and x_lsb and I want to explicitly show which bits of signal x I am connecting to these ports. For example, when instantiating the DUT:

interface video_input_interface vif;
dut udut(
    .msb(vif.x_msb),
    .lsb(vif.x_lsb),
.............
);

Now the issue is I have 2 drivers in my agent:

Driver A: When driving the interface from Driver A, I would like to drive signal x and not x_lsb, x_msb.

Driver B: When driving the interface from Driver B, I would like to drive signal x_lsb and x_msb individually.

I would think that my solution would split up signal x in my interface into x_lsb and x_msb. In DriverA, I can just drive this signal x. Also, for driver B the interface would be ok with me accessing the bits individually and everything would work just fine... not!

The assign causes signal x to be "X - unknown value". I have to drive x_msb and x_lsb individually for DriverA. Or other option is to

assign x_lsb = x[1:0]
assign x_msb = x[3:2]

This means DriverA would work, but would run into same problem from DriverB (when trying to drive x_lsb and x_msb).

Is there a solution to this? Thanks

Ciano
  • 554
  • 5
  • 16
noobuntu
  • 903
  • 1
  • 18
  • 42

2 Answers2

3

You can use clocking blocks, one per driver:

interface video_input_interface(clk, rst);

   input logic       clk;
   input logic       rst;
         logic[1:0]  x_lsb;
         logic[1:0]  x_msb;

  clocking cb_a @(posedge clk);
    output x = { x_lsb, x_msb };
  endclocking

  clocking cb_b @(posedge clk);
    output x_lsb;
    output x_msb;
  endclocking

endinterface

From driver A, you would always reference cb_a:

@(posedge clk);
video_if.cb_a.x <= 'hA;

From driver B, you would always reference cb_b:

@(posedge clk);
video_if.cb_b.x_msb <= 'h1;
video_if.cb_b.x_lsb <= 'h2;

Full example on EDAPlayground: http://www.edaplayground.com/x/3hK

You just have to be careful not to drive from both drivers at the same time. Read more on clocking blocks in Section 14. Clocking blocks of the SV 2012 standard.

Tudor Timi
  • 7,453
  • 1
  • 24
  • 53
  • Thanks @Tudor. I have a couple of questions: 1) Why is it that you haven't declared output x as logic[3:0] x on the top? 2) How exactly does this work? for driverA, I can drive x directly because it is declared as an output? but it is x_msb and x_lsb that are connected to the DUT so wouldn't they be the outputs? Sorry but I am a bit confused – noobuntu Jun 04 '14 at 15:07
  • @noobuntu In 'cb_b', 'x_lsb' and'x_msb' are clocking vars and they reference interface signals directly. In 'cb_a', 'x' is also a clocking variable, but it needn't be a signal inside the interface. Clocking vars can have any expression (hierarchical path, slicing, composition of other signals). Basically the simulator knows that when you drive 'x', he's supposed to drive 'x_lsb' and 'x_msb' instead. If you want to also read 'x' (in a monitor for example), you must declare it as 'inout'. – Tudor Timi Jun 04 '14 at 15:12
  • OK I think I get it. so basically, clocking vars are different completely from interface vars. They can be used to reference interface vars or combine them in any way required. Is my understanding correct? I am only a bit unsure about why it is declared an output? What is is output from? The clocking block? – noobuntu Jun 04 '14 at 15:33
  • Yes, it means that when you reference that clock var from the clocking block, you're allowed to write to it and it will propagate the value to the interface signals. – Tudor Timi Jun 04 '14 at 15:44
  • 1
    @Tudor: Doesn't a clocking block imply that the signals inside it are synchronized to the clock? I don't see this synchronization in OP's question. – Ari Jun 04 '14 at 17:02
  • @Ari It does, I just assumed that since he had a clock defined in the interface that the signals are synchronous to it. – Tudor Timi Jun 05 '14 at 08:06
2

Your question is a bit unclear... So do drivers A and B drive x simultaneously? What should be the value of x when x_msb and x_lsb are driven by B and x is driven by A?

You already assign to x in the interface. Therefore, you cannot drive it in another module (Driver A) because x cannot have multiple drivers.

If the two drivers are not driving simultaneously, how about a multiplexed solution as in the following?

interface video_input_interface(clk, rst);

   input logic       clk;
   input logic       rst;
         logic[1:0]  x_lsb;
         logic[1:0]  x_msb;
         logic[3:0]  x;
         logic       driverIsA;       //Indicates the driver is A
         logic       xValueFromA;     //The x value driven by A

   assign x = driverIsA ? xValueFromA : {x_msb, x_lsb};
endinterface
Ari
  • 7,251
  • 11
  • 40
  • 70
  • Sorry I should have made it clear. Only one driver will drive the interface at one time. I like your solution but would rather use clocking blocks to do this.. – noobuntu Jun 04 '14 at 15:08
  • @noobuntu: Using clocking blocks work, but just notice that they make your signals synchronized to `clk`. This is not the case in your question. – Ari Jun 05 '14 at 16:51