1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
|
//
// Copyright 2020 Ettus Research, A National Instruments Company
//
// SPDX-License-Identifier: LGPL-3.0-or-later
//
// Module: PkgChdrData
//
// Description: This package defines the data types used to represent CHDR
// words and data samples in RFNoC as well as utilities for converting between
// them.
//
package PkgChdrData;
// Default value for ITEM_W needs to be 64 due to a bug in Vivado 2019.1.
class ChdrData #(int CHDR_W = 64, int ITEM_W = 64);
// CHDR bus word (CHDR_W bits)
typedef logic [CHDR_W-1:0] chdr_word_t ;
typedef chdr_word_t chdr_word_queue_t[$];
// The item/sample word type (user-defined width, a multiple of 8 bits)
typedef logic [ITEM_W-1:0] item_t ;
typedef item_t item_queue_t[$];
function new();
assert ((ITEM_W % 8 == 0) && (CHDR_W % ITEM_W == 0)) else begin
$fatal(1, "RfnocData::new: Invalid CHDR_W and/or ITEM_W");
end
endfunction
// Convert a queue of items to a queue of CHDR words
static function chdr_word_queue_t item_to_chdr(ref item_queue_t items);
int items_per_word = CHDR_W / ITEM_W;
int num_chdr_words = ((items.size() + items_per_word - 1) / items_per_word);
chdr_word_queue_t chdr_words;
chdr_word_t word;
for (int i = 0; i < num_chdr_words; i++) begin
for (int j = 0; j < items_per_word; j++) begin
word[j*ITEM_W +: ITEM_W] = items[i*items_per_word + j];
end
chdr_words.push_back(word);
end
return chdr_words;
endfunction : item_to_chdr
// Convert a queue of CHDR words to a queue of items. The optional
// num_bytes argument indicates how many bytes are in the item queue that
// you want to convert.
static function item_queue_t chdr_to_item(
ref chdr_word_queue_t chdr_words,
input int num_bytes = -1
);
int items_per_word = CHDR_W / ITEM_W;
int bytes_left;
item_queue_t item_words;
if (num_bytes < 0) bytes_left = chdr_words.size() * (CHDR_W / 8);
else bytes_left = num_bytes;
foreach (chdr_words[i]) begin
for (int j = 0; j < items_per_word; j++) begin
if (bytes_left > 0) begin
item_words.push_back(chdr_words[i][j*ITEM_W +: ITEM_W]);
bytes_left -= (ITEM_W/8);
end
end
end
assert (bytes_left == 0) else begin
$warning("ChdrData::chdr_to_item: num_bytes is not a multiple of items");
end
return item_words;
endfunction : chdr_to_item
// Return a string representation of the contents of the CHDR queue
static function string chdr_string(
ref chdr_word_queue_t chdr_words,
input string format = "%X"
);
string str = $sformatf("%0d-bit CHDR words (%0d words or %0d bytes):\n",
CHDR_W, chdr_words.size(), chdr_words.size() * (CHDR_W/8));
foreach (chdr_words[i]) begin
str = { str, $sformatf({"%5d> ", format, "\n"}, i, chdr_words[i]) };
end
return str;
endfunction : chdr_string
// Return a string representation of the contents of the item queue
static function string item_string(
ref item_queue_t items,
input string format = "%X"
);
string str = $sformatf("%0d-bit items (%0d items or %0d bytes)\n",
ITEM_W, items.size(), items.size() * (ITEM_W/8));
foreach (items[i]) begin
str = { str, $sformatf({"%5d> ", format, "\n"}, i, items[i]) };
end
return str;
endfunction : item_string
// Display a string representation of the contents of a CHDR word queue
static function void print_chdr(
ref chdr_word_queue_t chdr_words,
input string format = "%X"
);
$display(chdr_string(chdr_words, format));
endfunction : print_chdr
// Display a string representation of the contents of an item queue
static function void print_item(
ref item_queue_t items,
input string format = "%X"
);
$display(item_string(items, format));
endfunction : print_item
// Check if the contents of two CHDR queues is equal
static function bit chdr_equal(
ref chdr_word_queue_t left,
ref chdr_word_queue_t right
);
if (left.size() != right.size()) return 0;
for (int i = 0; i < left.size(); i++) begin
if (left[i] != right[i]) return 0;
end
return 1;
endfunction : chdr_equal
// Check if the contents of two item queues is equal
static function bit item_equal(
ref item_queue_t left,
ref item_queue_t right
);
if (left.size() != right.size()) return 0;
for (int i = 0; i < left.size(); i++) begin
if (left[i] != right[i]) return 0;
end
return 1;
endfunction : item_equal
endclass : ChdrData
endpackage : PkgChdrData
|