I have been trying to design a task for my testbench to make my life easier. The task seems to be doing fine when I check the internal signals using $display
. However, when I hook the task up in my initial
block, the simulation output shown on the waveform is NOT the same as the display result. Thank you in advance
===========Code===========
`timescale 1ns/1ps
/*----------Macros----------*/
`define FullCycle 20
`define HalfCycle 10
`define CLK_Cycle(CycleNum) (`FullCycle*CycleNum)
module syncronization_tb();
/*----------DUT I/O----------*/
logic reset_n, clk4m, ppm_data, output_valid_flag;
logic [7: 0] data_out_DUT;
logic flag;
/*----------TX I/O----------*/
logic bit_stream, clk50m;
logic [1: 0] ppm_out;
/*----------RX I/O----------*/
logic clk50mREC;
logic data_out;
assign ppm_data = data_out;
Syncronization DUT
(
reset_n,
clk4m_out,
ppm_data,
data_out_DUT,
output_valid_flag
);
PPM_top TX
(
reset_n,
clk50m,
bit_stream,
ppm_out
);
CLK_Recovery RX
(
clk50mREC,
reset_n,
ppm_out[1],
data_out,
clk4m_out
);
logic [7:0] data;
logic Taskflag;
integer index;
initial forever #`HalfCycle clk50m = ~ clk50m;
initial #17 forever #`HalfCycle clk50mREC = ~clk50mREC;
initial begin
{reset_n, clk50m, bit_stream, clk50mREC} = 0;
#`CLK_Cycle(5);
{reset_n} = 1;
data = 8'haa;
generateBITstream(.data(data), .bit_stream_out(bit_stream),.index(index));
// data = 8'he3;
// generateBITstream(data, bit_stream);
//data = 8'h5b;
//generateBITstream(data, bit_stream);
#`CLK_Cycle(800);
$stop;
end
task automatic generateBITstream;
parameter integer width = 8;
input [width - 1: 0] data;
output logic bit_stream_out;
output integer index;
begin
for(index = 0; index < width; index = index + 1 ) begin
@(posedge TX.clk1m) bit_stream_out = data[index];
$display("%d and time is %t with %b",index, $time, bit_stream_out);
#`CLK_Cycle(10);
end
end
endtask
endmodule
===========Console Display [Correct Result]===========
run -all
# 0 and time is 1870000ps with 0
# 1 and time is 2870000ps with 1
# 2 and time is 3870000ps with 0
# 3 and time is 4870000ps with 1
# 4 and time is 5870000ps with 0
# 5 and time is 6870000ps with 1
# 6 and time is 7870000ps with 0
# 7 and time is 8870000ps with 1
# Break in Module syncronization_tb at G:/Work/PPM/src/Syncronization RTL Simulation/src/syncronization_tb.sv line 74
===========Waveform [Wrong Result]===========
[]
===========A minimal reproducible example===========
`timescale 1ns/1ps
/*----------Macros----------*/
`define FullCycle 20
`define HalfCycle 10
`define CLK_Cycle(CycleNum) (`FullCycle*CycleNum)
module syncronization_tb();
logic [7:0] data;
logic bit_stream, clk50m;
integer index;
initial forever #`HalfCycle clk50m =~ clk50m;
initial begin
clk50m = 0; #`CLK_Cycle(10);
data = 8'haa;
generateBITstream(.data(data), .bit_stream_out(bit_stream),.index(index));
#`CLK_Cycle(800);
$stop;
end
task automatic generateBITstream;
parameter integer width = 8;
input [width - 1: 0] data;
output logic bit_stream_out;
output integer index;
begin
for(index = 0; index < width; index = index + 1 ) begin
@(posedge clk50m) bit_stream_out = data[index];
$display("%d and time is %t with %b",index, $time, bit_stream_out);
#`CLK_Cycle(10);
end
end
endtask
endmodule
===========Console Display [Correct Result]===========
# 0 and time is 210000 with 0
# 1 and time is 410000 with 1
# 2 and time is 610000 with 0
# 3 and time is 810000 with 1
# 4 and time is 1010000 with 0
# 5 and time is 1210000 with 1
# 6 and time is 1410000 with 0
# 7 and time is 1610000 with 1
# Break in Module syncronization_tb at G:/Work/PPM/src/Syncronization RTL Simulation/src/syncronization_tb.sv line 22
The problem is that the signal connected to the task output port (bit_stream
) only gets updated in the testbench once the task completes (after the for
loop). It does not get updated every time the $display
is called in the for
loop.
One way to fix this is to get rid of the task output port, and directly update the bit_stream
signal inside the task:
task automatic generateBITstream;
parameter integer width = 8;
input [width - 1: 0] data;
output integer index;
begin
for(index = 0; index < width; index = index + 1 ) begin
@(posedge TX.clk1m) bit_stream = data[index];
$display("%d and time is %t with %b",index, $time, bit_stream);
#`CLK_Cycle(10);
end
end
endtask
Then call the task as:
generateBITstream(.data(data), .index(index));