C
Chris F Clark
Guest
I'm looking at some verilog code (see the module below) that I am
certain represents a race. However, when we run the code with
Modelsym, it consistently resolves the race the "correct" way (that is
the way the designer intended it). This makes me wonder if there
isn't some clause in the standard I have overlooked that specifies the
order of the two assignments (or their containing always blocks) that
I have overlooked. If anyone can point out a clause (in the standard)
that would require that the posedge block (and its non-blocking
assign) must be executed before the "level sensitive" block (and its
blocking assign), I would appreciate it. I would also appreciate
knowing if others see the same race I do. Results from other
simulators would be interesting too.
BTW, by consistently, I mean Modelysm not only runs the code as
written the way the designer wants, but it runs nuemrous variations on
the code in the desired order (i.e. reordering the blocks, changing
the first block to also be posedge on clk1, inserting assigns in
between the signals, and so forth). As close as I can get to a model
of Modelsyms ordering is that it appears to run the first half (the
value-capture/scheduling part) of non-blocking assignments first, then
blocking assigns. However, I find no support for ordering that in the
standard.
The issue, of course, is that our own home grown simulator runs the
blocking assign first, then the non-blocking assign (and that makes
the d_input value race through the circuit and get to d_out in one
cycle rather than being delayed a cycle). If it is an ambiguous race,
I don't care; the designer has to fix it. If it is supposed to be
deterministic, I have to figure out what's wrong with our simulator.
module rtv_latch_timing_test ( clk1, d_input, d_out );
input clk1 ;
input d_input ;
output d_out ;
reg d_out ;
reg latchout ;
wire clk1 ;
wire d_input ;
always @ ( d_input or clk1 ) // Hi level sens Latch
begin
if ( clk1 )
latchout = ( d_input );
end
always @ ( posedge clk1 ) // Rising edge trig FF
begin
d_out <= ( latchout );
end
endmodule
----------------------------------------------------------------
Modelsym runs the code almost as if it were written this way:
always @ ( d_input or clk1 ) // Hi level sens Latch
begin
if ( clk1 )
#0 latchout = ( d_input );
end
always @ ( posedge clk1 ) // Rising edge trig FF
begin
d_out <= ( latchout );
end
----------------------------------------------------------------
I would like it to interpret the code closer to this way (and argue
that because it is a race either interpretation is valid):
always @ ( d_input or clk1 ) // Hi level sens Latch
begin
if ( clk1 )
latchout = ( d_input );
end
always @ ( posedge clk1 ) // Rising edge trig FF
begin
#0 d_out <= ( latchout );
end
Thanks for any insights,
-Chris
*****************************************************************************
Chris Clark Internet : compres@world.std.com
Compiler Resources, Inc. Web Site : http://world.std.com/~compres
23 Bailey Rd voice : (508) 435-5016
Berlin, MA 01503 USA fax : (978) 838-0263 (24 hours)
------------------------------------------------------------------------------
certain represents a race. However, when we run the code with
Modelsym, it consistently resolves the race the "correct" way (that is
the way the designer intended it). This makes me wonder if there
isn't some clause in the standard I have overlooked that specifies the
order of the two assignments (or their containing always blocks) that
I have overlooked. If anyone can point out a clause (in the standard)
that would require that the posedge block (and its non-blocking
assign) must be executed before the "level sensitive" block (and its
blocking assign), I would appreciate it. I would also appreciate
knowing if others see the same race I do. Results from other
simulators would be interesting too.
BTW, by consistently, I mean Modelysm not only runs the code as
written the way the designer wants, but it runs nuemrous variations on
the code in the desired order (i.e. reordering the blocks, changing
the first block to also be posedge on clk1, inserting assigns in
between the signals, and so forth). As close as I can get to a model
of Modelsyms ordering is that it appears to run the first half (the
value-capture/scheduling part) of non-blocking assignments first, then
blocking assigns. However, I find no support for ordering that in the
standard.
The issue, of course, is that our own home grown simulator runs the
blocking assign first, then the non-blocking assign (and that makes
the d_input value race through the circuit and get to d_out in one
cycle rather than being delayed a cycle). If it is an ambiguous race,
I don't care; the designer has to fix it. If it is supposed to be
deterministic, I have to figure out what's wrong with our simulator.
module rtv_latch_timing_test ( clk1, d_input, d_out );
input clk1 ;
input d_input ;
output d_out ;
reg d_out ;
reg latchout ;
wire clk1 ;
wire d_input ;
always @ ( d_input or clk1 ) // Hi level sens Latch
begin
if ( clk1 )
latchout = ( d_input );
end
always @ ( posedge clk1 ) // Rising edge trig FF
begin
d_out <= ( latchout );
end
endmodule
----------------------------------------------------------------
Modelsym runs the code almost as if it were written this way:
always @ ( d_input or clk1 ) // Hi level sens Latch
begin
if ( clk1 )
#0 latchout = ( d_input );
end
always @ ( posedge clk1 ) // Rising edge trig FF
begin
d_out <= ( latchout );
end
----------------------------------------------------------------
I would like it to interpret the code closer to this way (and argue
that because it is a race either interpretation is valid):
always @ ( d_input or clk1 ) // Hi level sens Latch
begin
if ( clk1 )
latchout = ( d_input );
end
always @ ( posedge clk1 ) // Rising edge trig FF
begin
#0 d_out <= ( latchout );
end
Thanks for any insights,
-Chris
*****************************************************************************
Chris Clark Internet : compres@world.std.com
Compiler Resources, Inc. Web Site : http://world.std.com/~compres
23 Bailey Rd voice : (508) 435-5016
Berlin, MA 01503 USA fax : (978) 838-0263 (24 hours)
------------------------------------------------------------------------------