You're welcome to tell me I'm stupid, but I think we have a definition problem in clocking blocks. Here's a trivial but complete example of a clocking block that references some signals in the design, and a program that interacts with the design through this clocking block: module M; logic d, q; bit clk; always #5 clk = ~clk; clocking C @(posedge clk); input #0 q; output #0 d; endclocking : C program P; initial forever @C begin : Test C.d <= <test_data>; if (C.q !== <expected_result>) ... end : Test endprogram : P //DUT is just a flip-flop: always @(posedge clk) q <= d; endmodule The sampling and driving semantics on the design signals M.d, M.q are clearly defined in the LRM (I'm looking at P1800-D6-p1). What is much less clear to me is the behaviour of the resynchronised signals M.C.d, M.C.q (note that the LRM doesn't even give this kind of object a name, although it seems sensible to call them "resynchronised signals"). It's clear that these are distinct data objects in their own right, so we need to establish exactly how they are updated and sampled. The LRM is almost entirely silent on this matter. We use clocking blocks to impose a cycle-based discipline on our code, so the test program does everything on clock events. It assigns to M.C.d using NBA, as it must. This, I think, is fairly uncontroversial. At clock number N, test data t(N) is driven on to M.C.d by NBA, but meanwhile test data t(N-1) is copied from M.C.d to M.d by NBA through the action of the clocking's "output #0". At clock N+1, the clocking block "output #0" action schedules an NBA that will copy t(N) on to M.d, and consequently the external RTL code will see the new value t(N) at clock N+2, copying it on to M.q by NBA at that time. Now for the hard part - input sampling. We have #0 input sampling in the clocking block, so it samples M.q in the Observed region. Consequently it will see the newly updated value of M.q, carrying test data t(N), in the Observed region of the timeslot corresponding to clock N+2. What is absolutely NOT clear, though, is when this new value gets copied to M.C.q where the program can see it. When the Observed region is executed, the clock event N+2 has already happened; so it seems unreasonable for M.C.q to be updated. Do we wait yet one more clock cycle for M.C.q to be updated? Is M.C.q updated in the NBA region, the Observed region or the Active region? Is the update of M.C.q treated specially in the case of "input #0", as is the sampling of M.q? The LRM is not telling me what I need to know about this. It is entirely possible that this is because I've missed something, but I'm not the only one who's confused about it; the two implementations to which I have access are in total disagreement. This is disappointing, given that the combination of program+clocking was specifically conceived to allow the use of cycle-based test benches without risk of indeterminacy. -- Jonathan Bromley, Consultant DOULOS - Developing Design Know-how VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services Doulos Ltd. Church Hatch, 22 Market Place, Ringwood, Hampshire, BH24 1AW, UK Tel: +44 (0)1425 471223 Email: jonathan.bromley@doulos.com Fax: +44 (0)1425 471573 Web: http://www.doulos.com This e-mail and any attachments are confidential and Doulos Ltd. reserves all rights of privilege in respect thereof. It is intended for the use of the addressee only. If you are not the intended recipient please delete it from your system, any use, disclosure, or copying of this document is unauthorised. The contents of this message may contain personal views which are not the views of Doulos Ltd., unless specifically stated.Received on Wed Jul 27 08:09:45 2005
This archive was generated by hypermail 2.1.8 : Wed Jul 27 2005 - 08:10:03 PDT