elmar
03-05-2008, 11:41 AM
Hi
We observe a strange behavior of the OVM application below on IUS 06.20-s004.
It implements two independent transaction level comunications using tlm_fifo:
1) pre_source --> driver
2) monitor --> sink
Running the code exactly as it is below everything is o.k.
However, erasing the line marked "********* initial delay offset *************"
the two comunications get mixed up.
Is this my programming error or a OVM error or a IUS error ?
Elmar
module tb;
`include "ovm.svh"
class packet extends ovm_transaction;
rand int i;
constraint i_range {
i > 0;
i < 16;
}
endclass
class pre_source extends ovm_threaded_component;
ovm_put_port #(packet) data_out;
function new(string name, ovm_component parent);
super.new(name,parent);
data_out = new("data_out", this);
endfunction
task run();
packet p;
while(1) begin
p = new();
assert(p.randomize());
$display("source %0t: put %0d", $time, p.i);
data_out.put(p);
end
endtask
endclass
class driver extends ovm_threaded_component;
ovm_get_port #(packet) data_in;
function new(string name, ovm_component parent);
super.new(name,parent);
data_in = new("data_in", this);
endfunction
task run();
packet p;
while(1) begin
#10;
data_in.get(p);
$display("driver %0t: rec %0d", $time, p.i);
p = null;
end
endtask
endclass
class monitor extends ovm_threaded_component;
ovm_put_port #(packet) data_out;
function new(string name, ovm_component parent);
super.new(name,parent);
data_out = new("data_out", this);
endfunction
task run();
packet p;
#1; // ********* initial delay offset *************
while(1) begin
#10;
p = new();
assert(p.randomize());
$display(" monitor %0t: put %0d", $time, p.i);
data_out.put(p);
end
endtask
endclass
class sink extends ovm_threaded_component;
ovm_get_port #(packet) tr_in;
function new(string name, ovm_component parent);
super.new(name,parent);
tr_in = new("tr_in", this);
endfunction
task run();
packet tr;
while(1) begin
tr_in.get(tr);
$display(" sink %0t: rec %0d", $time, tr.i);
tr = null;
end
endtask
endclass
class env extends ovm_env;
pre_source sou;
driver dri;
monitor mon;
sink sin;
tlm_fifo #(packet) source_driver;
tlm_fifo #(packet) monitor_checker;
function new(string name = "env");
sou = new("sou", this);
dri = new("dri", this);
mon = new("mon", this);
sin = new("sin", this);
source_driver = new("source_driver", this, 1);
monitor_checker = new("monitor_checker", this, 1);
endfunction
function void connect();
mon.data_out.connect(monitor_checker.put_export);
sin.tr_in.connect(monitor_checker.get_export);
sou.data_out.connect(source_driver.put_export);
dri.data_in.connect(source_driver.get_export);
endfunction
task run();
#100;
endtask
endclass
env e;
initial begin
e = new();
e.do_test();
$finish;
end
endmodule
Output with initial delay offset of 1 for monitor-sink transactions (everything o.k.)
================================================== =================
source 0: put 5
source 0: put 11
driver 10: rec 5
source 10: put 3
monitor 11: put 11
sink 11: rec 11
driver 20: rec 11
source 20: put 11
monitor 21: put 12
sink 21: rec 12
driver 30: rec 3
source 30: put 10
monitor 31: put 11
sink 31: rec 11
driver 40: rec 11
source 40: put 6
monitor 41: put 2
sink 41: rec 2
driver 50: rec 10
source 50: put 4
monitor 51: put 14
sink 51: rec 14
driver 60: rec 6
source 60: put 1
monitor 61: put 1
sink 61: rec 1
driver 70: rec 4
source 70: put 3
monitor 71: put 15
sink 71: rec 15
driver 80: rec 1
source 80: put 5
monitor 81: put 3
sink 81: rec 3
driver 90: rec 3
source 90: put 1
monitor 91: put 9
sink 91: rec 9
driver 100: rec 5
Output for simultaneous transactions (BAD: sink receives transaction from source instead from monitor)
====================================
source 0: put 5
source 0: put 11
monitor 10: put 11
driver 10: rec 5
sink 10: rec 5
source 10: put 3
monitor 20: put 12
driver 20: rec 11
sink 20: rec 11
source 20: put 11
monitor 30: put 11
driver 30: rec 3
sink 30: rec 3
source 30: put 10
monitor 40: put 2
driver 40: rec 11
sink 40: rec 11
source 40: put 6
monitor 50: put 14
driver 50: rec 10
sink 50: rec 10
source 50: put 4
monitor 60: put 1
driver 60: rec 6
sink 60: rec 6
source 60: put 1
monitor 70: put 15
driver 70: rec 4
sink 70: rec 4
source 70: put 3
monitor 80: put 3
driver 80: rec 1
sink 80: rec 1
source 80: put 5
monitor 90: put 9
driver 90: rec 3
sink 90: rec 3
source 90: put 1
monitor 100: put 14
driver 100: rec 5
We observe a strange behavior of the OVM application below on IUS 06.20-s004.
It implements two independent transaction level comunications using tlm_fifo:
1) pre_source --> driver
2) monitor --> sink
Running the code exactly as it is below everything is o.k.
However, erasing the line marked "********* initial delay offset *************"
the two comunications get mixed up.
Is this my programming error or a OVM error or a IUS error ?
Elmar
module tb;
`include "ovm.svh"
class packet extends ovm_transaction;
rand int i;
constraint i_range {
i > 0;
i < 16;
}
endclass
class pre_source extends ovm_threaded_component;
ovm_put_port #(packet) data_out;
function new(string name, ovm_component parent);
super.new(name,parent);
data_out = new("data_out", this);
endfunction
task run();
packet p;
while(1) begin
p = new();
assert(p.randomize());
$display("source %0t: put %0d", $time, p.i);
data_out.put(p);
end
endtask
endclass
class driver extends ovm_threaded_component;
ovm_get_port #(packet) data_in;
function new(string name, ovm_component parent);
super.new(name,parent);
data_in = new("data_in", this);
endfunction
task run();
packet p;
while(1) begin
#10;
data_in.get(p);
$display("driver %0t: rec %0d", $time, p.i);
p = null;
end
endtask
endclass
class monitor extends ovm_threaded_component;
ovm_put_port #(packet) data_out;
function new(string name, ovm_component parent);
super.new(name,parent);
data_out = new("data_out", this);
endfunction
task run();
packet p;
#1; // ********* initial delay offset *************
while(1) begin
#10;
p = new();
assert(p.randomize());
$display(" monitor %0t: put %0d", $time, p.i);
data_out.put(p);
end
endtask
endclass
class sink extends ovm_threaded_component;
ovm_get_port #(packet) tr_in;
function new(string name, ovm_component parent);
super.new(name,parent);
tr_in = new("tr_in", this);
endfunction
task run();
packet tr;
while(1) begin
tr_in.get(tr);
$display(" sink %0t: rec %0d", $time, tr.i);
tr = null;
end
endtask
endclass
class env extends ovm_env;
pre_source sou;
driver dri;
monitor mon;
sink sin;
tlm_fifo #(packet) source_driver;
tlm_fifo #(packet) monitor_checker;
function new(string name = "env");
sou = new("sou", this);
dri = new("dri", this);
mon = new("mon", this);
sin = new("sin", this);
source_driver = new("source_driver", this, 1);
monitor_checker = new("monitor_checker", this, 1);
endfunction
function void connect();
mon.data_out.connect(monitor_checker.put_export);
sin.tr_in.connect(monitor_checker.get_export);
sou.data_out.connect(source_driver.put_export);
dri.data_in.connect(source_driver.get_export);
endfunction
task run();
#100;
endtask
endclass
env e;
initial begin
e = new();
e.do_test();
$finish;
end
endmodule
Output with initial delay offset of 1 for monitor-sink transactions (everything o.k.)
================================================== =================
source 0: put 5
source 0: put 11
driver 10: rec 5
source 10: put 3
monitor 11: put 11
sink 11: rec 11
driver 20: rec 11
source 20: put 11
monitor 21: put 12
sink 21: rec 12
driver 30: rec 3
source 30: put 10
monitor 31: put 11
sink 31: rec 11
driver 40: rec 11
source 40: put 6
monitor 41: put 2
sink 41: rec 2
driver 50: rec 10
source 50: put 4
monitor 51: put 14
sink 51: rec 14
driver 60: rec 6
source 60: put 1
monitor 61: put 1
sink 61: rec 1
driver 70: rec 4
source 70: put 3
monitor 71: put 15
sink 71: rec 15
driver 80: rec 1
source 80: put 5
monitor 81: put 3
sink 81: rec 3
driver 90: rec 3
source 90: put 1
monitor 91: put 9
sink 91: rec 9
driver 100: rec 5
Output for simultaneous transactions (BAD: sink receives transaction from source instead from monitor)
====================================
source 0: put 5
source 0: put 11
monitor 10: put 11
driver 10: rec 5
sink 10: rec 5
source 10: put 3
monitor 20: put 12
driver 20: rec 11
sink 20: rec 11
source 20: put 11
monitor 30: put 11
driver 30: rec 3
sink 30: rec 3
source 30: put 10
monitor 40: put 2
driver 40: rec 11
sink 40: rec 11
source 40: put 6
monitor 50: put 14
driver 50: rec 10
sink 50: rec 10
source 50: put 4
monitor 60: put 1
driver 60: rec 6
sink 60: rec 6
source 60: put 1
monitor 70: put 15
driver 70: rec 4
sink 70: rec 4
source 70: put 3
monitor 80: put 3
driver 80: rec 1
sink 80: rec 1
source 80: put 5
monitor 90: put 9
driver 90: rec 3
sink 90: rec 3
source 90: put 1
monitor 100: put 14
driver 100: rec 5