Confused with "task" keyword.

C

Confused Frank

Guest
I wrote a task to feed test vectors to my design, however, I realized some
differences between
"task" and the normal state machines I used to do. One sample code below, I
am expecting the
the signal "trd_sample" to be delayed by one cycle of "trc", i.e. 2nd
posedge of trc. However,
why does the simulation shows on the first posedge of trc?

I have put the modelsim waveform here.
http://img234.imageshack.us/img234/5034/confusedtask7bg.jpg

Thank you in advance.


module sim;
reg clk;
reg rst_n;

reg trw;
reg [3:0] trd;
reg trc;

reg [3:0] trd_sample;

always #5 clk <= ~ clk;

initial begin
clk <= 1'b0;
rst_n <= 1'b1;
#1 rst_n <= 1'b0;
#2 rst_n <= 1'b1;
tx_in;
$stop();
end



task tx_in;
integer i, j;
begin
@ (posedge clk);
@ (posedge clk);
trc <= 1'b0;
trw <= 1'b0;
trd <= 4'h0;
@ (posedge clk);
trc <= 1'b1;
trw <= 1'b1;
trd <= 4'hA;
@ (posedge clk);
trc <= 1'b0;
@ (posedge clk);
trc <= 1'b1;
trd <= 4'h9;
@ (posedge clk);
trc <= 1'b0;
@ (posedge clk);
trc <= 1'b1;
trd <= 4'h8;
@ (posedge clk);
trc <= 1'b0;
@ (posedge clk);
trc <= 1'b1;
trd <= 4'h7;
@ (posedge clk);
@ (posedge clk);
@ (posedge clk);
@ (posedge clk);
end
endtask

always @ (posedge trc or negedge rst_n) begin
if (~rst_n)
trd_sample <= 4'h0;
else begin
if (trw)
trd_sample <= trd;
end
end

endmodule
 
there is no discrepancy between your task and the waveform from
Modelsim,
see below :
@ (posedge clk);
trc <= 1'b1;
trw <= 1'b1;
trd <= 4'hA;

you are using non blocking assignments, so right hand side are
evaluated first,
Then the Left hand side is updated AFTER all events ...

As a rising edge is detected on trc ...
the always @(posedge trc ) block is activated,
BUT one delta delay later thus
trw and trd are already updated and the sampled value is 4'hA at time
25 on the
simulation.

To avoid this kind of simulation issue you should delay your data
signals
in your bench BUT not your clock (avoiding hold time issue )
@ (posedge clk);
trc <= 1'b1; // clock
trw <= #(1) 1'b1; // data
trd <= #(1) 4'hA; // data
@ (posedge clk);
trc <= 1'b0; // clock
@ (posedge clk);
trc <= 1'b1; //clock
trd <= #(1) 4'h9; // data
 
Thank you renald.


"Renaud" <rc064c@free.fr> wrote in message
news:1122407940.724367.109740@o13g2000cwo.googlegroups.com...
there is no discrepancy between your task and the waveform from
Modelsim,
see below :
@ (posedge clk);
trc <= 1'b1;
trw <= 1'b1;
trd <= 4'hA;

you are using non blocking assignments, so right hand side are
evaluated first,
Then the Left hand side is updated AFTER all events ...

As a rising edge is detected on trc ...
the always @(posedge trc ) block is activated,
BUT one delta delay later thus
trw and trd are already updated and the sampled value is 4'hA at time
25 on the
simulation.

To avoid this kind of simulation issue you should delay your data
signals
in your bench BUT not your clock (avoiding hold time issue )
@ (posedge clk);
trc <= 1'b1; // clock
trw <= #(1) 1'b1; // data
trd <= #(1) 4'hA; // data
@ (posedge clk);
trc <= 1'b0; // clock
@ (posedge clk);
trc <= 1'b1; //clock
trd <= #(1) 4'h9; // data
 
Hi,
It has nothing to do with your task, rather you've scheduled events on
trc and trd such that they both get updated towards the same delta
cycle. As other reply also pointed out, you are changing data & clk at
the same time and hence is the result you are seeing. Remember, NBA
(Non-Blocking Assign) in Verilog is "scheduled" and in your case, you
have:

trc <= 1'b1;
trd <= 8'haa; // or some thing
@(posedge clk)

This means that you schedule 2 events on trc & trd and both get updated
at the end of a time step BEFORE proceeding to the next @(posedge clk)
(as there is an event delay there).

Now you have another always blk sampling on posedge trc - posedge trc
happens when the previous scheduling is complete, by then trd got its
new value too.

Actually, if you use VCS + DVE (their new debug tool), you can record
"delta delays" and debug this very clearly (You can expand one clk edge
and it clearly shows how the event scheduling happens), not sure if
Modelsim has that feature.

An easy fix would be to move your trc assignment outside the block and
do some thing like:

assign trc <= clk;

HTH
Aji
http://www.noveldv.com
 
"Ajeetha" <ajeetha@gmail.com> wrote in message
news:1122490318.778145.128470@f14g2000cwb.googlegroups.com...
Hi,
It has nothing to do with your task, rather you've scheduled events on
trc and trd such that they both get updated towards the same delta
cycle. As other reply also pointed out, you are changing data & clk at
the same time and hence is the result you are seeing. Remember, NBA
(Non-Blocking Assign) in Verilog is "scheduled" and in your case, you
have:

trc <= 1'b1;
trd <= 8'haa; // or some thing
@(posedge clk)

This means that you schedule 2 events on trc & trd and both get updated
at the end of a time step BEFORE proceeding to the next @(posedge clk)
(as there is an event delay there).

Now you have another always blk sampling on posedge trc - posedge trc
happens when the previous scheduling is complete, by then trd got its
new value too.

Actually, if you use VCS + DVE (their new debug tool), you can record
"delta delays" and debug this very clearly (You can expand one clk edge
and it clearly shows how the event scheduling happens), not sure if
Modelsim has that feature.

An easy fix would be to move your trc assignment outside the block and
do some thing like:

assign trc <= clk;

HTH
Aji
http://www.noveldv.com
Thank you Chuck.
I am done by putting a unit delay at txd & trw, and I have better
understanding
over non/blocking assignment now.
 

Welcome to EDABoard.com

Sponsor

Back
Top