2
votes

This is a simple SV program (I know an arbiter is much more complex, pardon me for naming this as one), but I don't know how the line repeat(4) @ar.cb; keeps controlling the entire clock. If I comment out that line, the clock stops even though I have put it in an 'always' block inside the top module. I can't understand how this works.

testbench.sv

interface arb_if(input bit clk);
    logic [1:0] request;
    logic [1:0] grant;
    logic reset;
    clocking cb @(posedge clk);
        output request;
        input grant;
    endclocking

    modport DUT(input request,clk,reset,output grant);
    modport TB(clocking cb,output reset); endinterface

program automatic test(arb_if.TB ar);
    initial begin
        ar.reset <= 1;
        ar.cb.request<=$urandom;
        $display("[%0t]Request is sent",$time);
        repeat(4) @ar.cb;
        $display("[%0t]Grant=%0d",$time,ar.cb.grant);
    end endprogram

module top;
    bit clk;
    always #5 clk=~clk;
    arb_if arb(clk);
    test tb(arb);
    arbit a1(arb,clk); endmodule

design.sv

module arbit(arb_if.DUT arbiter,input bit clk);   always @(posedge clk)
      if(arbiter.reset==0)
        arbiter.grant<=2'bxx;
      else
        #1 arbiter.grant<=arbiter.request; 
endmodule

And in the design, the grant does not get assigned till the next cycle even if I use a blocking assignment (unless I give #1, in which case it does, of course after the delay).

I am struggling with understanding the synchronous circuit timings. It'd be a great help if someone can clear this up for me.

Without #1:

Without #1

With #1:

With #1

1
Also, Do you know why that #1 delay causes the program to function properly ? Is it beacuse the read and write cannot happen simultaneously or that design reads input value just before the active clock edge ? (Or delay time in this case) - WhirlWind
My question is since request is already assigned, why not assign it to grant at the end of the time frame ? Why the extra clock cycle delay ? - WhirlWind

1 Answers

2
votes

The program terminates the simulation.

From IEEE Std 1800-2017, section 24.3 The program construct:

When all initial procedures within a program have reached their end, that program shall immediately terminate all descendent threads of initial procedures within that program. If there is at least one initial procedure within at least one program block, the entire simulation shall terminate by means of an implicit call to the $finish system task immediately after all the threads and all their descendent threads originating from all initial procedures within all programs have ended.

With the repeat statement, the simulation ends at time 35. It waits for 4 positive edges of clk, then implicitly calls $finish.

Without the repeat statement, the simulation ends at time 0. It doesn't wait for any clk edges, then implicitly calls $finish.