Sequence of events

U

Uwe Bonnes

Guest
Following code
`timescale 1ns/1ns

module test();
reg clka = 0, clkx2=0;
reg clkb = 0;

reg xa = 0, xb = 0;

always # 5 {clka, clkx2} = {clka, clkx2} + 3'h3;

always @(posedge clkx2)
clkb <= !clkb;

always @(posedge clkx2)
begin
xa <= clka;
xb <= clkb;
#1 $display("xa %x xb %x", xa, xb);
end

initial
begin
$dumpfile("timing.dmp");
$dumpvars;
# 30 $finish;
end

endmodule // test

gives a for me unexpected result in that xa and xb are out of phase
when run with iverilog and cver. Both print

xa 1 xb 0
xa 0 xb 1
xa 1 xb 0

Are these simulators right? And if they are right,
what verilog language feature causes this behaviour.

Thanks

--
Uwe Bonnes bon@elektron.ikp.physik.tu-darmstadt.de

Institut fuer Kernphysik Schlossgartenstrasse 9 64289 Darmstadt
--------- Tel. 06151 162516 -------- Fax. 06151 164321 ----------
 
Uwe Bonnes wrote:
Following code
`timescale 1ns/1ns

module test();
reg clka = 0, clkx2=0;
reg clkb = 0;

reg xa = 0, xb = 0;

always # 5 {clka, clkx2} = {clka, clkx2} + 3'h3;

always @(posedge clkx2)
clkb <= !clkb;

always @(posedge clkx2)
begin
xa <= clka;
xb <= clkb;
#1 $display("xa %x xb %x", xa, xb);
end

initial
begin
$dumpfile("timing.dmp");
$dumpvars;
# 30 $finish;
end

endmodule // test

gives a for me unexpected result in that xa and xb are out of phase
when run with iverilog and cver. Both print

xa 1 xb 0
xa 0 xb 1
xa 1 xb 0

Are these simulators right? And if they are right,
what verilog language feature causes this behaviour.

Thanks
You're latching at the rising or falling edge of clkA. Look at what
happens when you add x2 to the mix with x2<=clkx2 to see which side of
the edge gets latched.

With the Verilog sensitivity list using a posedge rst and executing the
reset with if(rst), it's apparent the later edge of the rise/fall is
what's appropriate for the always block. Both clka and clkx2 have the
same rising edge. The changes to clkb are *caused* by the clkx2 edge so
the *previous* value for clkb applies at the clkx2 posedge as it would
for other RHS values.

The simulator schedules the clka and clkx2 transitions. The clkx2
posedge latches the new value of clka into xa but the previous value
into xb.

This illustrates why generated clocks can be a real bear!
 
On Oct 23, 4:03 pm, Uwe Bonnes <b...@elektron.ikp.physik.tu-
darmstadt.de> wrote:
Following code
`timescale 1ns/1ns

module test();
   reg clka = 0, clkx2=0;
   reg clkb = 0;

   reg xa = 0, xb = 0;

   always # 5 {clka, clkx2} = {clka, clkx2} + 3'h3;

   always @(posedge clkx2)
     clkb <= !clkb;

   always @(posedge clkx2)
     begin
        xa <= clka;
        xb <= clkb;
        #1 $display("xa %x xb %x", xa, xb);
     end

   initial
     begin
        $dumpfile("timing.dmp");
        $dumpvars;
        # 30 $finish;
     end

endmodule // test

gives a for me unexpected result in that xa and xb are out of phase
when run with iverilog and cver. Both print

xa 1 xb 0
xa 0 xb 1
xa 1 xb 0

Are these simulators right? And if they are right,
what verilog language feature causes this behaviour.

Thanks

--
Uwe Bonnes                b...@elektron.ikp.physik.tu-darmstadt.de

Institut fuer Kernphysik  Schlossgartenstrasse 9  64289 Darmstadt
--------- Tel. 06151 162516 -------- Fax. 06151 164321 ----------
clka is changing at the same time as clkx2. clkb changes just after
clkx2 as required by the non-blocking assignment. In real time they
change together, but the order of operation for sampling clka vs. clkb
actually causes what you see:

1: clkx2 and clka change due to always block (at the same time
because they are in the same assignment.

2: clkx2 triggers the always @ posedge block.

3: clka and clkb are sampled. clka has already changed.

4: zero ps later, clkb changes along with xa and xb
due to the scheduled non-blocking assignments.

HTH,
Gabor
 

Welcome to EDABoard.com

Sponsor

Back
Top