0
votes

I am using a clocking block in my interface for signal aliasing. I want to concatenate some of the bits together to form a bus, and then drive this bus from my driver. So, for example:

interface bus_intf (clk);
    input logic      clk;
          logic[1:0] x_lsb;
          logic[1:0] x_msb;

   clocking driver_bus @(posedge clk)
      default input #1step output #0;
      output x_bus = {x_msb, x_lsb};
   endclocking
endinterface

Now the problem with this is, in one of my assertions, I need to read bus_intf.driver_bus.x_bus. As stated in the SV manual, an output variable from a clocking block should not be read by the testbench, and if it is, then simulator spits out an error (or warning in my case).

So I modified the interface:

interface bus_intf (clk);
    input logic      clk;
          logic[1:0] x_lsb;
          logic[1:0] x_msb;

   clocking driver_bus @(posedge clk)
      default input #1step output #0;
      inout x_bus = {x_msb, x_lsb};
   endclocking
endinterface

The problem now is, in my waveform I see two signals being created - x_bus and x_bus__o. I understand why Questasim did this - it is to separate the inout declaration so I can view both versions. However, the problem now is all my clocking drive is delayed by one clock cycle! so x_bus__o which is connected to the DUT is one clock cycle later than x_bus. This is inspite of me explicitly stating that output skew is #0.

Any idea why this happens? Am I doing something wrong or have I misunderstood?

2

2 Answers

2
votes

I've put your code on EDAPlayground and tried it out. It seems to be working as expected. Here's my test harness:

module top;
  bit clk;
  always #1 clk = ~clk;

  bus_intf busif(clk);

  initial begin
    @busif.driver_bus;
    $display("time = ", $time);
    busif.driver_bus.x_bus <= 'hf;

    repeat (2)
      @(negedge clk);
    $display("time = ", $time);
    busif.driver_bus.x_bus <= 'ha;

    #100;
    $finish();
  end

  always @(busif.x_lsb)
    $display("time = ", $time, " x_lsb = ", busif.x_lsb);

  always @(busif.x_msb)
    $display("time = ", $time, " x_msb = ", busif.x_msb);
endmodule

The link is here if you want to try it online: http://www.edaplayground.com/x/Utf

If I drive x_bus at a posedge, then the value will be written immediately, as would be expected due to the #0 output delay. If I drive x_bus at a negedge (or at any other time aside from a posedge), then it will wait until the next posedge to drive the value. I see this behavior regardless of whether x_bus is declared as output or inout.

Check to see when you are scheduling your writes; this might be the reason you see some delays on your waves.

0
votes

When you have bidirectional flow through a clocking block, the signal from the verification to the hardware and back has to go through two virtual D-FFs. So the original observation is correct. The input of 1-step is one D-FF to the design; then the return is one more D-FF back appearing 0ns (i.e., just after the clock). Clocking blocks are not useful in the situation of a signal that requires a single-cycle turn-around, and for that reason, you avoid them if that is a requirement. For most designs, it is simply not necessary. Monitors will observe the signals with a pipeline delay of one cycle, which is generally not a problem.