F/F model with timing, but without specify?

E

Evan Lavelle

Guest
Does anyone know of a F/F model which checks its own timing, but
without using a specify block? It should have parameters for input
setup and hold times, output hold, and clock-to-out.

I need one for testing, but couldn't find one on Google. This is
non-trivial, so I'd rather not rush into it if someone is willing to
share one.

Thanks -

Evan
 
Evan Lavelle wrote:
Does anyone know of a F/F model which checks its own timing, but
without using a specify block? It should have parameters for input
setup and hold times, output hold, and clock-to-out.

I need one for testing, but couldn't find one on Google. This is
non-trivial, so I'd rather not rush into it if someone is willing to
share one.
I have done this before on vhdl testbenches,
but not since I discovered static timing.
I am curious what STA does not cover
in this case.

-- Mike Treseler
 
On Wed, 10 Oct 2007 10:46:13 -0700, Mike Treseler
<mike_treseler@comcast.net> wrote:

Evan Lavelle wrote:
Does anyone know of a F/F model which checks its own timing, but
without using a specify block? It should have parameters for input
setup and hold times, output hold, and clock-to-out.

I need one for testing, but couldn't find one on Google. This is
non-trivial, so I'd rather not rush into it if someone is willing to
share one.

I have done this before on vhdl testbenches,
but not since I discovered static timing.
I am curious what STA does not cover
in this case.

-- Mike Treseler
Yes, VHDL would be good for this, but isn't an option. On STA, see:

http://iverilog.wikia.com/wiki/Graffiti#Why_bother.3F

In short, relying on STA can be dangerous. I was thinking of adding
something about bidi I/Os (though I can't think of anything specific
at the moment) and problems with high-speed synchronous memory I/Fs
(virtual clocks, etc.)

Evan
 
Evan Lavelle wrote:

On STA, see:
http://iverilog.wikia.com/wiki/Graffiti#Why_bother.3F

In short, relying on STA can be dangerous. I was thinking of adding
something about bidi I/Os (though I can't think of anything specific
at the moment) and problems with high-speed synchronous memory I/Fs
(virtual clocks, etc.)
I agree with your points, and I do run gate
sims as a check-off item against synthesis errors.
Yes, STA assumes certain design rules and
separate functional verification.

However, I don't believe that it is possible
for me to beat STA at its job of covering worst case timing
by siming the gate netlist.

Good luck on your project,
and if I see an instrumented verilog flop model
I will let you know.


-- Mike Treseler
 
On Wed, 10 Oct 2007 10:23:08 +0100, Evan Lavelle <nospam@nospam.com>
wrote:

Does anyone know of a F/F model which checks its own timing, but
without using a specify block? It should have parameters for input
setup and hold times, output hold, and clock-to-out.

I need one for testing, but couldn't find one on Google. This is
non-trivial, so I'd rather not rush into it if someone is willing to
share one.
Non-trivial but not too hard, I think. However, I can't help
asking: why do you need a timing model without specify blocks?
You'll end up with something that can have its timing applied
instance by instance, but only by using parameter override -
obviously SDF backannotation won't work. And it will surely
run dog-slow by comparison with the $setup() and similar
checks that are built in to the Verilog sim kernel.
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
jonathan.bromley@MYCOMPANY.com
http://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 
On Thu, 11 Oct 2007 16:02:15 +0100, Jonathan Bromley
<jonathan.bromley@MYCOMPANY.com> wrote:

Non-trivial but not too hard, I think. However, I can't help
asking: why do you need a timing model without specify blocks?
You'll end up with something that can have its timing applied
instance by instance, but only by using parameter override -
obviously SDF backannotation won't work. And it will surely
run dog-slow by comparison with the $setup() and similar
checks that are built in to the Verilog sim kernel.
The only reason is that one of my reference simulators doesn't support
specify blocks (the other 4 do), and it's popular in the
financially-challenged end of the market. I don't think doing this
would be too difficult, but I need to (I think) manually step through
the entire setup and hold windows, at the minimum precision, and
sample on the last delta. It's a bit cumbersome without postponed
processes or a 'stable attribute. sdf's not a problem - the code's
generated by a compiler, and it can write in literals as required.

Evan
 
On Thu, 11 Oct 2007 18:12:05 +0100,
Evan Lavelle <nospam@nospam.com> wrote:

The only reason is that one of my reference simulators doesn't support
specify blocks (the other 4 do), and it's popular in the
financially-challenged end of the market.
OK.

I need to (I think) manually step through
the entire setup and hold windows, at the minimum precision, and
sample on the last delta.
I don't think you need to do that. I'll try to work up something
and post it later.

--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
jonathan.bromley@MYCOMPANY.com
http://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 
On Thu, 11 Oct 2007 20:15:46 +0100,
Jonathan Bromley <jonathan.bromley@MYCOMPANY.com> wrote:

I'll try to work up something and post it later.
Beats watching reality TV, anyhow. Try this for size.

Many details missing - it needs a check for clock period
greater than output hold time, it doesn't yet have reset
or a notifier... but it may provide some ideas. I'm
hesitant to offer it because I suspect you can work this
stuff out at least as well as I can, but I do know for
sure that the tricks I've used avoid some of the pitfalls
of more obvious techniques. And it shouldn't be too
inefficient, since there aren't unreasonably large
numbers of extra events or process evaluations.

Comments/criticisms welcomed. ABSOLUTELY NO WARRANTY
as it's not fully tested for all combinations of the
various parameters.

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Verilog FF model with timing checks and simple delay
// modelling.
// Jonathan Bromley, 11 Oct 2007
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

`timescale 1ns/1ps

module ff_timing_model
#(parameter Tsu=1.0, Th=1.0, Tqh=1.2, Tcq=3.0)
(input wire ck, d, output reg q);

// Sanity checks on parameters.
//
initial begin
// Check Th<Tcq, to ensure that updating of q is causal
// even in the presence of hold violations.
if (Th >= Tcq) begin
$display ("*** FATAL: Th>=Tcq (%t>%t) on ff_timing_model %m",
Th, Tcq);
$finish;
end
// Check Tqh<Tcq for obvious reasons.
if (Tqh >= Tcq) begin
$display ("*** FATAL: Tqh>=Tcq (%t>%t) on ff_timing_model %m",
Tqh, Tcq);
$finish;
end
end

realtime last_d, last_clock;
reg capture_q, qh_window;

initial begin
last_d = 0.0;
last_clock = 0.0;
// avoid spurious X before first clock
qh_window = 1;
// Monitor for changes on d...
forever @d begin
// log change time, needed at clock edge to check setup
last_d = $realtime;
// check time since last clock edge, for hold
if ((last_d - last_clock) < Th) begin
$display(
"*** ERROR: hold violation on %m at %t:", last_clock,
" required Th=%t, actual %t", Th, last_d-last_clock);
// trash projected output value if there's a hold violation
capture_q = 1'bx;
// and ensure that the change will be appropriately scheduled
qh_window = 1;
end
end
end

always @(posedge ck) begin
// log clock time, needed on data change to check hold
// (could also be used to check minimum clock period)
last_clock = $realtime;
// check time since last data transition, for setup
if ((last_clock - last_d) < Tsu) begin
$display(
"*** ERROR: setup violation on %m at %t:", last_clock,
" required Tsu=%t, actual %t", Tsu, last_clock-last_d);
// trash projected output value if there's a setup violation
capture_q = 1'bx;
end else begin
// capture projected output value
capture_q = d;
end
// if there is to be an output change, schedule the transition
if (capture_q !== q) begin
qh_window <= 1;
end
// always do this, because qh_window might have been set
// by the hold violation logic
qh_window <= #Tqh 0;
end

// Make a control signal that goes high after Tqh
// and low again after Tcq, using inertial delay
// so that clock period <Tcq is correctly handled
// (but clock period <Tqh may not be)
wire #(Tqh, Tcq-Tqh) q_control = qh_window;
// Whenever q_control is high, drive q=1'bx.
// On trailing edge of q_control, set q=capture_q.
always @q_control q = q_control ? 1'bx: capture_q;

endmodule

//////////////////////////////////////////////////////////////
// Stupid little randomized test.
//////////////////////////////////////////////////////////////
module ff_tb;

parameter Thalf = 5.0;

reg ck, d;
wire q;
ff_timing_model DUT(ck, d, q);

initial $timeformat (-9, 3, "ns", 0);

initial begin
ck = 0;
repeat(200) // run for 100 clocks
#Thalf ck = ~ck;
end

initial begin : test
integer seed, delay;
seed = 42;
@(posedge ck);
forever @(negedge ck) begin
delay = $dist_uniform(seed, 0, 200*Thalf);
#(delay/100.0) d = $dist_uniform(seed, 0, 1);
end
end

endmodule

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
jonathan.bromley@MYCOMPANY.com
http://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 
On Thu, 11 Oct 2007 21:57:40 +0100,
Jonathan Bromley <jonathan.bromley@MYCOMPANY.com> wrote:

ABSOLUTELY NO WARRANTY
as it's not fully tested for all combinations of the
various parameters.
Hitting "send" is about the best code review tool I know...
Note that all the parameters need to be non-negative
(I think zero is OK for all of them). Checks needed,
of course (rule #1 of programming: trust no-one).
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
jonathan.bromley@MYCOMPANY.com
http://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 
I didn't actually expect you to write it! Thanks; I'll look at
extending it for negative setup/hold cases.

I plugged your code into my TB, for the positive setup/positive hold
case, and it complained on the first test:

*** ERROR: hold violation on top.DUT at 25.0 ns: required Th=0.2 ns,
actual 0.2 ns

which gives me the opportunity to attach a Verilog version of one of
my favourite test programs. One sim produces:

rounding error: (15.000000 - 14.800000) is less than 0.200000
rounding error: (15.000000 - 14.700000) is less than 0.300000

while another 3 produce:

rounding error: (15.000000 - 14.800000) is less than 0.200000
rounding error: (15.000000 - 14.700000) is more than 0.300000

the fix is easy enough, though.

I've done some more playing around with $setuphold, and the support
for it isn't as good as I'd thought. One sim (the expensive one)
worked Ok; another reported lots of spurious errors if either the
setup or the hold limit was negative, and another omitted to report
real errors for a negative hold limit.

Evan

-----------------------------------------------------------
module test;
real fa, fb;

initial begin
fa = 15.0; fb = 14.8; test(0.2);
fa = 15.0; fb = 14.7; test(0.3);
end

task test;
input diff;
real diff;
if((fa - fb) != diff)
$display("rounding error: (%f - %f) is %s than %f",
fa, fb, ((fa - fb) < diff)? "less" : "more", diff);
endtask

endmodule
 
On Fri, 12 Oct 2007 16:10:05 +0100,
Evan Lavelle <nospam@nospam.com> wrote:

I'll look at extending it for negative setup/hold cases
I was hoping you wouldn't say that... I really have no idea
how to do it properly; I think you need to introduce delays in
the clock, or the data, or something, so that the real checks
can use positive time values. Otherwise you need to
remember an awful lot of Stuff whenever there's a clock or
data transition. Or use a quantum simulator that doesn't
need to worry about outmoded bourgeois concerns like causality.

I plugged your code into my TB, for the positive setup/positive hold
case, and it complained on the first test:

*** ERROR: hold violation on top.DUT at 25.0 ns: required Th=0.2 ns,
actual 0.2 ns
May be related to the fact that I had 1ps time resolution, but I'm
only displaying the times to 100ps precision?

Also, there's another bug I didn't notice in my code: if you get a
hold violation, it can artificially increase the output hold time.
I suspect you can easily see how to fix it, and other improvements.

I've done some more playing around with $setuphold, and the support
for it isn't as good as I'd thought. One sim (the expensive one)
worked Ok; another reported lots of spurious errors if either the
setup or the hold limit was negative, and another omitted to report
real errors for a negative hold limit.
As per my earlier caveat, I'm a bit hazy about this stuff. I know
that at least one sim has a compile-time switch to enable negative
Tsu/Th checking - presumably it entails some runtime cost.
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
jonathan.bromley@MYCOMPANY.com
http://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 
On Fri, 12 Oct 2007 16:28:40 +0100, Jonathan Bromley
<jonathan.bromley@MYCOMPANY.com> wrote:


*** ERROR: hold violation on top.DUT at 25.0 ns: required Th=0.2 ns,
actual 0.2 ns

May be related to the fact that I had 1ps time resolution, but I'm
only displaying the times to 100ps precision?
No, just floating-point rounding:

realtime last_d, last_clock;
...
if ((last_d - last_clock) < Th) begin
if last_d is 15.0, and last_clock is 14.8, and Th is 0.2, then the
sims I've tried evaluate the if condition as true, rather than the
expected false, so reporting a hold violation when there isn't one.
The fix is just to use integer times.

Evan
 

Welcome to EDABoard.com

Sponsor

Back
Top