Goto page 1, 2 Next
Jonathan Bromley
Guest
Sun Jan 17, 2010 8:12 pm
hi folks,
as you know, I've been messing with Verilog for quite a
while now, but there's still some stuff I don't know,
so perhaps someone here can help.
I want to model an uncertain signal transition. My
source signal (let's say S) makes a clean transition
from 0 to 1, or the other way, at some time T. I
want an output (let's say Y) to follow this signal,
but with both a delay and an uncertainty - so it
should go to X at time T+Tmin, and then to 1 at
time T+Tmax. Rise and fall behaviour should be
symmetrical.
In VHDL I can trivially do this by using inertial
delay:
Y <= 'X' after Tmin, S after Tmax;
In Verilog I can get nearly there...
always @S begin
Y <= #Tmin 1'bx;
Y <= #Tmax S;
end
but that isn't quite right; suppose, for example,
that S goes from 0 to 1 at time T, and then goes
back to 0 again just before T+Tmax - I'll get Y
going to 1 at T+Tmax, and then back to X again...
it's wrong because Verilog <= delays are transport
rather than inertial.
I can think of various ways to do this, but all of
them cost a few lines of code. I strongly suspect
that there is some super-neat way to do it using
specify blocks or somesuch; can anyone save me a
lot of LRM-rummaging by telling me the trick?
thanks in advance
--
Jonathan Bromley
John McCaskill
Guest
Sun Jan 17, 2010 11:29 pm
On Jan 17, 12:12 pm, Jonathan Bromley <s...@oxfordbromley.plus.com>
wrote:
Quote:
hi folks,
as you know, I've been messing with Verilog for quite a
while now, but there's still some stuff I don't know,
so perhaps someone here can help.
I want to model an uncertain signal transition. My
source signal (let's say S) makes a clean transition
from 0 to 1, or the other way, at some time T. I
want an output (let's say Y) to follow this signal,
but with both a delay and an uncertainty - so it
should go to X at time T+Tmin, and then to 1 at
time T+Tmax. Rise and fall behaviour should be
symmetrical.
In VHDL I can trivially do this by using inertial
delay:
Y <= 'X' after Tmin, S after Tmax;
In Verilog I can get nearly there...
always @S begin
Y <= #Tmin 1'bx;
Y <= #Tmax S;
end
but that isn't quite right; suppose, for example,
that S goes from 0 to 1 at time T, and then goes
back to 0 again just before T+Tmax - I'll get Y
going to 1 at T+Tmax, and then back to X again...
it's wrong because Verilog <= delays are transport
rather than inertial.
I can think of various ways to do this, but all of
them cost a few lines of code. I strongly suspect
that there is some super-neat way to do it using
specify blocks or somesuch; can anyone save me a
lot of LRM-rummaging by telling me the trick?
thanks in advance
--
Jonathan Bromley
Hello Jonathan,
Verilog has both inertial and transport delays. Delays put on the RHS
of the assignment are transport delays. Put the delay on the LHS, and
it will be an inertial delay.
Here is a random paper that has a bit more detail on modeling delays:
http://www.sunburst-design.com/papers/CummingsHDLCON1999_BehavioralDelays_Rev1_1.pdf
Regards,
John McCaskill
www.FasterTechnology.com
Jonathan Bromley
Guest
Sun Jan 17, 2010 11:45 pm
On Sun, 17 Jan 2010 13:29:55 -0800 (PST), John McCaskill wrote:
Quote:
Verilog has both inertial and transport delays. Delays put on the RHS
of the assignment are transport delays. Put the delay on the LHS, and
it will be an inertial delay.
Sorry John, that's only half the story!
First, whilst you're completely right that inertial delay
is available, it doesn't solve my problem because I can't use it
to model more than one different delay for a given assignment.
Second, someone reading your post without the necessary
background might easily get the wrong idea, I fear.
Intra-assignment procedural delays are indeed transport delays;
this...
initial begin
...
a <= #5 b;
is very, very similar to VHDL's
a <= transport b after 5 ns;
Contrariwise, the blocking form is fairly useless:
initial begin
...
a = #5 b;
is simply equivalent to (Verilog)
some_temporary = b;
#5 a = some_temporary;
In procedural code, delays used as a prefix are neither inertial
nor transport; they're simple procedural stall that makes your
code hang for some simulation time while the rest of your model
gets on with other stuff:
...
do_some_stuff;
#10 // twiddle thumbs for 10 time units
do_other_stuff;
And in any kind of continuous assignment, the delay is inertial:
assign #4 target_wire = expression; // inertial delay
Quote:
Here is a random paper that has a bit more detail on modeling delays:
Cliff's a great guy and that paper is fine, but he's an RTL
guy to the core of his being and my question was about
behavioural modelling for simulation only.
I *think* there's some stuff I can do with the pulse rejection
machinery, but that's the part I don't know.... trying to map
the VHDL on to Verilog, my problem is that you can't do inertial
delay in Verilog procedural code at all.
I have a different solution, but it's too clumsy for comfort.
--
Jonathan Bromley
Marcus Harnisch
Guest
Mon Jan 18, 2010 3:41 am
Hi Jonathan
Is this close enough? If the input changes before T_min, you'll still
see a change to 1'bx at the output, though. Not sure how VHDL behaves
in this case.
module buffer;
reg S;
wire Y;
time T_min = 7.5;
time T_max = 10;
always @S
begin
#T_min;
force Y = 1'bx;
#(T_max - T_min);
release Y;
end
assign #(T_max) Y = S;
initial
begin
#13;
// uncritical
S = 1;
#30;
S = 0;
#30;
// input change during uncertainty
S = 1;
#8;
S = 0;
#8;
// input change before uncertainty
S = 1;
#5;
S = 0;
#30;
end
endmodule
Take care
--
Marcus Harnisch
Consultant
DOULOS - Developing Design Know-how
VHDL * SystemC * Verilog * SystemVerilog * e * PSL * Perl * Tcl/Tk
ARM Approved Training Centre (ATC)
Doulos Ltd., Central European Office, Garbsener Landstr. 10, 30419 Hannover
Tel: +49 (0)511 2771340 mailto: marcus.harnisch_at_doulos.com
Fax: +49 (0)511 2771349 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.
Jonathan Bromley
Guest
Mon Jan 18, 2010 9:46 am
On Mon, 18 Jan 2010 03:41:41 +0100, Marcus Harnisch
<marcus.harnisch_at_doulos.com> wrote:
Quote:
Hi Jonathan
Is this close enough? If the input changes before T_min, you'll still
see a change to 1'bx at the output, though. Not sure how VHDL behaves
in this case.
VHDL will wipe out existing scheduled actions, and re-schedule
according to the inertial assignment, for each execution of the
signal assignment. So the end of 'X' gets pushed out to Tmax
after the last transition on S.
Quote:
module buffer;
[snip]
I fear it has the same problem as some of my earlier efforts:
procedural delays in the "always @S" block mean that certain
transitions on S can be missed. I *think* this is more robust,
but I had to do a lot of futzing around to be confident that
I wouldn't get races or lockups. Not so much longer than
yours, if you take out the error checks :-)
module bufX
#(parameter Tmax = 1, Tmin = 0)
(input in, output reg out);
reg transition;
initial begin
if ((Tmax < Tmin) || (Tmax < 0) || (Tmin < 0)) begin
$display("FATAL: bufX %m: Tmax = %0d, Tmin = %0d",
Tmax, Tmin);
$stop;
$finish(1);
end
transition = 1;
fork
forever @(in) begin
if (transition) begin
disable delay;
wait(!transition);
end
out <= #Tmin 1'bx;
transition = 1;
end
forever begin
wait(transition);
begin : delay
#Tmax out <= in;
end
transition = 0;
end
join
end
endmodule
Jonathan Bromley
Guest
Mon Jan 18, 2010 9:47 am
On Mon, 18 Jan 2010 09:46:09 +0100, Jonathan Bromley wrote:
<stuff>
ps - forgot to sign off, and to ask how life is
treating you!
--
Jonathan Bromley
gabor
Guest
Mon Jan 18, 2010 4:08 pm
On Jan 17, 1:12 pm, Jonathan Bromley <s...@oxfordbromley.plus.com>
wrote:
Quote:
hi folks,
as you know, I've been messing with Verilog for quite a
while now, but there's still some stuff I don't know,
so perhaps someone here can help.
I want to model an uncertain signal transition. My
source signal (let's say S) makes a clean transition
from 0 to 1, or the other way, at some time T. I
want an output (let's say Y) to follow this signal,
but with both a delay and an uncertainty - so it
should go to X at time T+Tmin, and then to 1 at
time T+Tmax. Rise and fall behaviour should be
symmetrical.
In VHDL I can trivially do this by using inertial
delay:
Y <= 'X' after Tmin, S after Tmax;
In Verilog I can get nearly there...
always @S begin
Y <= #Tmin 1'bx;
Y <= #Tmax S;
end
but that isn't quite right; suppose, for example,
that S goes from 0 to 1 at time T, and then goes
back to 0 again just before T+Tmax - I'll get Y
going to 1 at T+Tmax, and then back to X again...
it's wrong because Verilog <= delays are transport
rather than inertial.
I can think of various ways to do this, but all of
them cost a few lines of code. I strongly suspect
that there is some super-neat way to do it using
specify blocks or somesuch; can anyone save me a
lot of LRM-rummaging by telling me the trick?
thanks in advance
--
Jonathan Bromley
Maybe not as pretty, but you could use a number
of assignments to get your transport delays:
wire Y_min, Y_max;
assign Y_min = #Tmin S;
assign Y_max = #Tmax S;
always @ (Y_min or Y_max)
if (Y_min != Y_max) Y = Y_min;
else Y = 1'bX;
Just a thought,
Gabor
Jonathan Bromley
Guest
Mon Jan 18, 2010 6:16 pm
On Mon, 18 Jan 2010 08:50:07 -0800 (PST), gabor wrote:
Quote:
wire Y_min, Y_max;
assign Y_min = #Tmin S;
assign Y_max = #Tmax S;
always @ (Y_min or Y_max)
if (Y_min != Y_max) Y = Y_min;
else Y = 1'bX;
Got that backwards! should be if (Y_min == Y_max) . . .
If this works, it's very neat indeed because you can
use wire resolution to get the "X if different":
assign Y = #Tmin S;
assign Y = #Tmax S;
Unfortunately it's not quite right. If S thrashes around
with pulse widths shorter than Tmin, you can yet Y appearing
to settle at any of 0, 1 or X depending on the exact timing
of the pulses; this isn't quite what I wanted.
However, it's a very useful approximation for some of the
simpler cases, and I think it will do the trick in the
component model I'm trying to create just now. Thanks!
--
Jonathan Bromley
gabor
Guest
Mon Jan 18, 2010 6:50 pm
On Jan 18, 9:08 am, gabor <ga...@alacron.com> wrote:
Quote:
On Jan 17, 1:12 pm, Jonathan Bromley <s...@oxfordbromley.plus.com
wrote:
hi folks,
as you know, I've been messing with Verilog for quite a
while now, but there's still some stuff I don't know,
so perhaps someone here can help.
I want to model an uncertain signal transition. My
source signal (let's say S) makes a clean transition
from 0 to 1, or the other way, at some time T. I
want an output (let's say Y) to follow this signal,
but with both a delay and an uncertainty - so it
should go to X at time T+Tmin, and then to 1 at
time T+Tmax. Rise and fall behaviour should be
symmetrical.
In VHDL I can trivially do this by using inertial
delay:
Y <= 'X' after Tmin, S after Tmax;
In Verilog I can get nearly there...
always @S begin
Y <= #Tmin 1'bx;
Y <= #Tmax S;
end
but that isn't quite right; suppose, for example,
that S goes from 0 to 1 at time T, and then goes
back to 0 again just before T+Tmax - I'll get Y
going to 1 at T+Tmax, and then back to X again...
it's wrong because Verilog <= delays are transport
rather than inertial.
I can think of various ways to do this, but all of
them cost a few lines of code. I strongly suspect
that there is some super-neat way to do it using
specify blocks or somesuch; can anyone save me a
lot of LRM-rummaging by telling me the trick?
thanks in advance
--
Jonathan Bromley
Maybe not as pretty, but you could use a number
of assignments to get your transport delays:
wire Y_min, Y_max;
assign Y_min = #Tmin S;
assign Y_max = #Tmax S;
always @ (Y_min or Y_max)
if (Y_min != Y_max) Y = Y_min;
else Y = 1'bX;
Just a thought,
Gabor
Got that backwards! should be if (Y_min == Y_max) . . .
Andy Botterill
Guest
Mon Jan 18, 2010 8:56 pm
Jonathan Bromley wrote:
If this works, it's very neat indeed because you can
Quote:
use wire resolution to get the "X if different":
assign Y = #Tmin S;
assign Y = #Tmax S;
Unfortunately it's not quite right. If S thrashes around
with pulse widths shorter than Tmin, you can yet Y appearing
to settle at any of 0, 1 or X depending on the exact timing
of the pulses; this isn't quite what I wanted.
However, it's a very useful approximation for some of the
simpler cases, and I think it will do the trick in the
component model I'm trying to create just now. Thanks!
This document seems to go through most of the things that you referred to.
http://ce.sharif.edu/courses/84-85/1/ce223/resources/root/Slides/10-Verilog%20Timing%20and%20Delays.ppt
Can you simplify your needs to 0->1, 1->0, 0->z, z->1, 1->z and z->0
with a specific delay time for each transition type? If so look at page
33 of the document.
This a section on state dependent timings.
I hope this is useful. Andy
Marcus Harnisch
Guest
Tue Jan 19, 2010 7:31 am
Jonathan Bromley <jonathan.bromley_at_MYCOMPANY.com> writes:
Quote:
ps - forgot to sign off, and to ask how life is
treating you!
Better than you -- keeping me awake with riddles when I should really
catch some sleep ;-)
Did you mention SystemVerilog in this thread? This solution looks
pretty close to the VHDL version, at least in my not-that-exhaustive
testbench:
module buffer_sv(input S, output Y);
parameter
T_min = 8,
T_max = 10;
always begin
@S;
forever
begin
// schedule x unless another change to S occurs
fork
begin
#T_min;
force Y = 1'bx;
#(T_max - T_min);
release Y;
@S;
end
@S;
join_any
disable fork;
end // forever begin
end
assign #(T_max) Y = S;
endmodule
Regards
--
Marcus Harnisch
Consultant
DOULOS - Developing Design Know-how
VHDL * SystemC * Verilog * SystemVerilog * e * PSL * Perl * Tcl/Tk
ARM Approved Training Centre (ATC)
Doulos Ltd., Central European Office, Garbsener Landstr. 10, 30419 Hannover
Tel: +49 (0)511 2771340 mailto: marcus.harnisch_at_doulos.com
Fax: +49 (0)511 2771349 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.
Cary R.
Guest
Wed Jan 20, 2010 2:16 am
Do you mean something like this
module uncertain(output wire out, input wire in)
parameter t_udef = 0, // The change to 'bx delay
t_def = 0; // The cahnge to defined delay
wire udef_window; // The uncertian window of operation
wire def_window; // The defined window of operation
initial if (t_udef > t_def) begi
$display("Configuration failure t_udef (%d) is greater than t_def (%d)."
t_udef, t_def)
$finish
en
buf #(t_udef, t_def) (udef_window, in)
buf #(t_def, t_udef) (def_window, in)
assign out = (uc_window & 1'bx) | def_window
endmodule
---
frmsrcurl:
http://compgroups.net/comp.lang.verilog/Help-with-timing-modeling-please
Guest
Wed Jan 20, 2010 3:30 am
On Jan 17, 1:12 pm, Jonathan Bromley <s...@oxfordbromley.plus.com>
wrote:
Nonblocking assignment delays are pure transport, i.e. none of the
assignments get descheduled by later assignments. Continuous
assignment and gate delays are pure inertial, i.e. only one event can
be scheduled at a time, and scheduling a new value will deschedule the
previous value.
What I assume you want is what I would call "normal" transport
scheduling. Multiple events can be scheduled as long as the ones
scheduled later are for a time after the ones scheduled earlier. When
an event is scheduled, any old events that would occur after it are
descheduled. So if a pulse width goes negative, the pulse disappears,
rather than having its edges occur in reverse order.
I believe that you can get this with path delays in specify blocks. I
don't know how much of this is part of the Verilog standard and how
much was specific to Verilog-XL (and replicated in NC-Verilog and
presumably some other simulators). I believe that these give you what
I would call transport delays, but with extra control over pulse
filtering. Instead of just filtering pulses that go negative, they
can filter pulses narrower than a given percentage of the delay. By
default I think that percentage is 100%, so it still looks like
inertial delay. If it is set to 0%, it would be transport delay.
This may be controlled by tool options, which is why I suspect it
might not be covered by the standard.
I think there are other controls that will allow narrow pulses to turn
to X for the runt pulse duration, instead of going away (though I
think it has to be implemented by some different mechanism of turning
to a special error state that is then treated as X, to get around some
absurd patent on the basic idea).
Cary R.
Guest
Wed Jan 20, 2010 5:31 am
For the assign version isn't i
assign #T_min out = in
assign #T_max out = in
I don't recognize the other syntax as being valid.
---
frmsrcurl:
http://compgroups.net/comp.lang.verilog/Help-with-timing-modeling-please
Cary R.
Guest
Wed Jan 20, 2010 6:16 am
I thought about this a bit more on the drive home. Let the simulator do the resolution just like was suggested for the assign statements
buf #t_min (out, in)
buf #t_max (out, in)
Should give you exactly what you want.
---
frmsrcurl:
http://compgroups.net/comp.lang.verilog/Help-with-timing-modeling-please
Goto page 1, 2 Next