Skip to content

Commit d62404d

Browse files
committed
testbenches/ip/util_axis_fifo: include test with random tkeep
- Add support for user-defined tkeep on m_axis_sequencer, - Add test_tkeep to util_axis_fifo, with random tkeep - Add cfg_tkeep to util_axis_fifo, which forces TKEEP_EN=1 Signed-off-by: Laez Barbosa <laez.barbosa@analog.com>
1 parent c661b2c commit d62404d

File tree

4 files changed

+293
-26
lines changed

4 files changed

+293
-26
lines changed

library/vip/amd/axis/m_axis_sequencer.sv

Lines changed: 98 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,11 @@ package m_axis_sequencer_pkg;
4343
import logger_pkg::*;
4444

4545
typedef enum {
46-
DATA_GEN_MODE_TEST_DATA, // get data from test
47-
DATA_GEN_MODE_AUTO_INCR, // autogenerate incrementing data until aborted
48-
DATA_GEN_MODE_AUTO_RAND // autogenerate randomized data until aborted
46+
DATA_GEN_MODE_TEST_DATA, // get data from test
47+
DATA_GEN_MODE_TEST_DATA_TKEEP, // get data from test, with user-defined tkeep
48+
DATA_GEN_MODE_AUTO_INCR, // autogenerate incrementing data until aborted
49+
DATA_GEN_MODE_AUTO_INCR_TKEEP, // autogenerate incrementing data until aborted, with user-defined tkeep
50+
DATA_GEN_MODE_AUTO_RAND // autogenerate randomized data until aborted
4951
} data_gen_mode_t;
5052

5153
typedef enum bit [1:0] {
@@ -81,10 +83,12 @@ package m_axis_sequencer_pkg;
8183
protected event packet_done;
8284
protected event queue_empty;
8385
protected event byte_stream_ev;
86+
protected event tkeep_stream_ev;
8487
protected event queue_ev;
8588

8689
protected axi4stream_transaction trans;
8790
protected xil_axi4stream_data_byte byte_stream [$];
91+
protected xil_axi4stream_strb tkeep_stream [$];
8892

8993
typedef struct{
9094
int num_bytes;
@@ -268,8 +272,9 @@ package m_axis_sequencer_pkg;
268272
if (enabled || (!enabled && stop_policy == STOP_POLICY_DESCRIPTOR_QUEUE)) begin
269273
packetize();
270274
descriptor_delay_subroutine();
271-
end else
275+
end else begin
272276
@enable_ev;
277+
end
273278
end else begin
274279
this.queue_empty_sig = 1;
275280
->> queue_empty;
@@ -288,6 +293,12 @@ package m_axis_sequencer_pkg;
288293
->>byte_stream_ev;
289294
endfunction: push_byte_for_stream
290295

296+
function void push_tkeep_for_stream(xil_axi4stream_strb tkeep_stream);
297+
this.tkeep_stream.push_back(tkeep_stream);
298+
->>tkeep_stream_ev;
299+
endfunction: push_tkeep_for_stream
300+
301+
291302
// descriptor delay subroutine
292303
// - can be overridden in inherited classes for more specific delay generation
293304
protected task data_beat_delay_subroutine();
@@ -403,41 +414,102 @@ package m_axis_sequencer_pkg;
403414

404415
for (int tc=0; tc<packet_length; tc++) begin : packet_loop
405416
data = new[byte_per_beat];
406-
for (int i=0; i<byte_per_beat; i++)
407-
data[i] = 'd0;
408417
keep = new[byte_per_beat];
418+
for (int i=0; i<byte_per_beat; i++) begin
419+
data[i] = 'd0;
420+
keep[i] = 1'b0;
421+
end
409422

410423
for (int i=0; i<byte_per_beat && (keep_all || tc*byte_per_beat+i<descriptor.num_bytes); i++) begin
411424
case (data_gen_mode)
412425
DATA_GEN_MODE_TEST_DATA:
413426
// block transfer until we get data from byte stream queue
414-
forever begin
415-
if (byte_stream.size() > 0) begin
416-
data[i] = byte_stream.pop_front();
417-
keep[i] = 1'b1;
418-
break;
419-
end else
420-
fork begin
421-
fork
422-
@byte_stream_ev;
423-
begin
424-
@disable_ev;
425-
if (tc==0 && i==0) begin
426-
case (stop_policy)
427-
STOP_POLICY_PACKET: ->> packet_done;
428-
STOP_POLICY_DATA_BEAT: ->> beat_done;
429-
default: ;
430-
endcase
427+
if (byte_stream.size() > 0) begin
428+
data[i] = byte_stream.pop_front();
429+
keep[i] = 1'b1;
430+
end else begin
431+
fork begin
432+
fork
433+
@byte_stream_ev;
434+
begin
435+
@disable_ev;
436+
if (tc==0 && i==0) begin
437+
case (stop_policy)
438+
STOP_POLICY_PACKET: ->> packet_done;
439+
STOP_POLICY_DATA_BEAT: ->> beat_done;
440+
default: ;
441+
endcase
442+
end
443+
end
444+
join_any
445+
disable fork;
446+
end join
447+
end
448+
DATA_GEN_MODE_TEST_DATA_TKEEP:
449+
// block transfer until we get data from byte stream queue
450+
if (byte_stream.size() > 0 && tkeep_stream.size() > 0) begin
451+
data[i] = byte_stream.pop_front();
452+
keep[i] = tkeep_stream.pop_front();
453+
end else begin
454+
fork begin
455+
fork
456+
begin
457+
fork
458+
begin
459+
if (byte_stream.size() == 0) begin
460+
@byte_stream_ev;
461+
end
431462
end
463+
begin
464+
if (tkeep_stream.size() == 0) begin
465+
@tkeep_stream_ev;
466+
end
467+
end
468+
join
469+
end
470+
begin
471+
@disable_ev;
472+
if (tc==0 && i==0) begin
473+
case (stop_policy)
474+
STOP_POLICY_PACKET: ->> packet_done;
475+
STOP_POLICY_DATA_BEAT: ->> beat_done;
476+
default: ;
477+
endcase
432478
end
433-
join_any
434-
disable fork;
435-
end join
479+
end
480+
join_any
481+
disable fork;
482+
end join
436483
end
437484
DATA_GEN_MODE_AUTO_INCR: begin
438485
data[i] = byte_count++;
439486
keep[i] = 1'b1;
440487
end
488+
DATA_GEN_MODE_AUTO_INCR_TKEEP: begin
489+
// block transfer until we get data from tkeep stream queue
490+
if (tkeep_stream.size() > 0) begin
491+
data[i] = byte_count++;;
492+
keep[i] = tkeep_stream.pop_front();
493+
break;
494+
end else begin
495+
fork begin
496+
fork
497+
@tkeep_stream_ev;
498+
begin
499+
@disable_ev;
500+
if (tc==0 && i==0) begin
501+
case (stop_policy)
502+
STOP_POLICY_PACKET: ->> packet_done;
503+
STOP_POLICY_DATA_BEAT: ->> beat_done;
504+
default: ;
505+
endcase
506+
end
507+
end
508+
join_any
509+
disable fork;
510+
end join
511+
end
512+
end
441513
DATA_GEN_MODE_AUTO_RAND: begin
442514
data[i] = $random;
443515
keep[i] = 1'b1;
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
global ad_project_params
2+
3+
set async_clk [expr int(rand()*2)]
4+
set ad_project_params(ASYNC_CLK) $async_clk
5+
6+
set tkeep_en 1
7+
set ad_project_params(TKEEP_EN) $tkeep_en
8+
9+
set tlast_en [expr int(rand()*2)]
10+
set ad_project_params(TLAST_EN) $tlast_en
11+
12+
set random_width [expr int(8*pow(2, int(7.0*rand()+1)))]
13+
set INPUT_WIDTH random_width
14+
set ad_project_params(INPUT_WIDTH) $INPUT_WIDTH
15+
16+
set random_width [expr int(8*pow(2, int(7.0*rand()+1)))]
17+
set OUTPUT_WIDTH random_width
18+
set ad_project_params(OUTPUT_WIDTH) $OUTPUT_WIDTH
19+
20+
set fifo_limited [expr int(rand()*2)]
21+
set ad_project_params(FIFO_LIMITED) $fifo_limited
22+
23+
if {$fifo_limited} {
24+
if {$INPUT_WIDTH > $OUTPUT_WIDTH} {
25+
set RATIO $INPUT_WIDTH/$OUTPUT_WIDTH
26+
} else {
27+
set RATIO $OUTPUT_WIDTH/$INPUT_WIDTH
28+
}
29+
} else {
30+
set RATIO 1
31+
}
32+
33+
set random_width [expr int(int(log($RATIO)/log(2))+4.0*rand()+1)]
34+
set ad_project_params(ADDRESS_WIDTH) $random_width
35+
36+
set input_clk [expr int(rand()*9)+1]
37+
set ad_project_params(INPUT_CLK) $input_clk
38+
39+
if {$async_clk} {
40+
set output_clk [expr int(rand()*9)+1]
41+
set ad_project_params(OUTPUT_CLK) $output_clk
42+
} else {
43+
set ad_project_params(OUTPUT_CLK) $input_clk
44+
}

testbenches/ip/util_axis_fifo_asym/system_project.tcl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ source $ad_tb_dir/library/includes/sp_include_scoreboard.tcl
2323
adi_sim_project_files [list \
2424
"environment.sv" \
2525
"tests/test_program.sv" \
26+
"tests/test_tkeep.sv" \
2627
]
2728

2829
#set a default test program
Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
// ***************************************************************************
2+
// ***************************************************************************
3+
// Copyright (C) 2024-2025 Analog Devices, Inc. All rights reserved.
4+
//
5+
// In this HDL repository, there are many different and unique modules, consisting
6+
// of various HDL (Verilog or VHDL) components. The individual modules are
7+
// developed independently, and may be accompanied by separate and unique license
8+
// terms.
9+
//
10+
// The user should read each of these license terms, and understand the
11+
// freedoms and responsibilities that he or she has by using this source/core.
12+
//
13+
// This core is distributed in the hope that it will be useful, but WITHOUT ANY
14+
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
15+
// A PARTICULAR PURPOSE.
16+
//
17+
// Redistribution and use of source or resulting binaries, with or without modification
18+
// of this file, are permitted under one of the following two license terms:
19+
//
20+
// 1. The GNU General Public License version 2 as published by the
21+
// Free Software Foundation, which can be found in the top level directory
22+
// of this repository (LICENSE_GPL2), and also online at:
23+
// <https://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
24+
//
25+
// OR
26+
//
27+
// 2. An ADI specific BSD license, which can be found in the top level directory
28+
// of this repository (LICENSE_ADIBSD), and also on-line at:
29+
// https://github.com/analogdevicesinc/hdl/blob/main/LICENSE_ADIBSD
30+
// This will allow to generate bit files and not release the source code,
31+
// as long as it attaches to an ADI device.
32+
//
33+
// ***************************************************************************
34+
// ***************************************************************************
35+
36+
`include "utils.svh"
37+
`include "axis_definitions.svh"
38+
39+
import logger_pkg::*;
40+
import test_harness_env_pkg::*;
41+
import environment_pkg::*;
42+
import watchdog_pkg::*;
43+
import m_axis_sequencer_pkg::*;
44+
45+
import `PKGIFY(test_harness, mng_axi_vip)::*;
46+
import `PKGIFY(test_harness, ddr_axi_vip)::*;
47+
48+
import `PKGIFY(test_harness, input_axis)::*;
49+
import `PKGIFY(test_harness, output_axis)::*;
50+
51+
program test_tkeep ();
52+
53+
timeunit 1ns;
54+
timeprecision 1ps;
55+
56+
// declare the class instances
57+
test_harness_env #(`AXI_VIP_PARAMS(test_harness, mng_axi_vip), `AXI_VIP_PARAMS(test_harness, ddr_axi_vip)) base_env;
58+
util_axis_fifo_environment #(`AXIS_VIP_PARAMS(test_harness, input_axis), `AXIS_VIP_PARAMS(test_harness, output_axis), `INPUT_CLK, `OUTPUT_CLK) uaf_env;
59+
60+
watchdog send_data_wd;
61+
62+
int byte_count, sample_count;
63+
64+
initial begin
65+
66+
// create environment
67+
base_env = new("Base Environment",
68+
`TH.`SYS_CLK.inst.IF,
69+
`TH.`DMA_CLK.inst.IF,
70+
`TH.`DDR_CLK.inst.IF,
71+
`TH.`SYS_RST.inst.IF,
72+
`TH.`MNG_AXI.inst.IF,
73+
`TH.`DDR_AXI.inst.IF);
74+
75+
uaf_env = new("Util AXIS FIFO Environment",
76+
`TH.`INPUT_CLK_VIP.inst.IF,
77+
`TH.`OUTPUT_CLK_VIP.inst.IF,
78+
`TH.`INPUT_AXIS.inst.IF,
79+
`TH.`OUTPUT_AXIS.inst.IF);
80+
81+
setLoggerVerbosity(ADI_VERBOSITY_NONE);
82+
83+
base_env.start();
84+
uaf_env.start();
85+
86+
base_env.sys_reset();
87+
88+
uaf_env.configure();
89+
uaf_env.input_axis_agent.sequencer.set_keep_some();
90+
uaf_env.input_axis_agent.sequencer.set_data_gen_mode(DATA_GEN_MODE_TEST_DATA_TKEEP);
91+
uaf_env.input_axis_agent.sequencer.set_descriptor_gen_mode(0);
92+
93+
uaf_env.run();
94+
95+
send_data_wd = new("Util AXIS FIFO Watchdog", 50000, "Send data");
96+
97+
send_data_wd.start();
98+
99+
uaf_env.input_axis_agent.sequencer.start();
100+
101+
// stimulus
102+
//repeat($urandom_range(5,10)) begin
103+
repeat(1) begin
104+
send_data_wd.reset();
105+
106+
if ((!`TKEEP_EN || !`TLAST_EN) && `INPUT_WIDTH < `OUTPUT_WIDTH) begin
107+
`FATAL(("bad parameter case"));
108+
repeat($urandom_range(1,5)) begin
109+
sample_count = $urandom_range(1,128);
110+
repeat(sample_count) begin
111+
uaf_env.input_axis_agent.sequencer.push_byte_for_stream($urandom_range(0,255));
112+
uaf_env.input_axis_agent.sequencer.push_tkeep_for_stream($urandom_range(0,1));
113+
end
114+
uaf_env.input_axis_agent.sequencer.add_xfer_descriptor_sample_count(sample_count*`OUTPUT_WIDTH/`INPUT_WIDTH, `TLAST_EN, 0);
115+
end
116+
end else begin
117+
//repeat($urandom_range(1,5)) begin
118+
repeat(1) begin
119+
byte_count = 16;//$urandom_range(1,1024);
120+
repeat(byte_count) begin
121+
uaf_env.input_axis_agent.sequencer.push_byte_for_stream($urandom_range(0,255));
122+
uaf_env.input_axis_agent.sequencer.push_tkeep_for_stream($urandom_range(0,1));
123+
end
124+
uaf_env.input_axis_agent.sequencer.add_xfer_descriptor_byte_count(byte_count, `TLAST_EN, 0);
125+
end
126+
end
127+
128+
129+
#($urandom_range(1,10)*1us);
130+
131+
uaf_env.input_axis_agent.sequencer.clear_descriptor_queue();
132+
uaf_env.input_axis_agent.sequencer.wait_empty_descriptor_queue();
133+
134+
uaf_env.scoreboard_inst.wait_until_complete();
135+
136+
end
137+
138+
send_data_wd.stop();
139+
140+
#100ns;
141+
142+
uaf_env.stop();
143+
base_env.stop();
144+
145+
`INFO(("Test bench done!"), ADI_VERBOSITY_NONE);
146+
$finish();
147+
148+
end
149+
150+
endprogram

0 commit comments

Comments
 (0)