O-RAN E Maintenance Release contribution for ODULOW
[o-du/phy.git] / fhi_lib / app / gen_test.m
1 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2 %
3 % Copyright (c) 2021 Intel.
4
5 % Licensed under the Apache License, Version 2.0 (the "License");
6 % you may not use this file except in compliance with the License.
7 % You may obtain a copy of the License at
8
9 % http://www.apache.org/licenses/LICENSE-2.0
10
11 % Unless required by applicable law or agreed to in writing, software
12 % distributed under the License is distributed on an "AS IS" BASIS,
13 % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 % See the License for the specific language governing permissions and
15 % limitations under the License.
16
17 %
18 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
19
20 %This script was tested with GNU Octave, version 3.8.2 or Matlab 9.2.0.538062 (R2017a) 
21
22 close all;
23 clear all;
24
25      %  5MHz    10MHz   15MHz   20 MHz  
26 nLteNumRbsPerSymF1 = ...
27 [
28      %  5MHz    10MHz   15MHz   20 MHz  
29         [25,    50,     75,     100]         % Numerology 0 (15KHz)
30 ];
31
32      %  5MHz    10MHz   15MHz   20 MHz  25 MHz  30 MHz  40 MHz  50MHz   60 MHz  70 MHz  80 MHz   90 MHz  100 MHz
33 nNumRbsPerSymF1 = ...
34 [
35      %  5MHz    10MHz   15MHz   20 MHz  25 MHz  30 MHz  40 MHz  50MHz   60 MHz  70 MHz  80 MHz   90 MHz  100 MHz
36         [25,    52,     79,     106,    133,    160,    216,    270,    0,         0,      0,      0,      0]         % Numerology 0 (15KHz)
37         [11,    24,     38,     51,     65,     78,     106,    133,    162,       0,    217,    245,    273]         % Numerology 1 (30KHz)
38         [0,     11,     18,     24,     31,     38,     51,     65,     79,        0,    107,    121,    135]         % Numerology 2 (60KHz)
39 ];
40
41 nNumRbsPerSymF2 = ...
42 [
43     %  50Mhz  100MHz  200MHz   400MHz
44         [66,    132,    264,     0]        % Numerology 2 (60KHz)
45         [32,    66,     132,     264]      % Numerology 3 (120KHz)
46 ];
47
48 % total number of tests
49 tests_total = 12
50 tech_all = ... % 0 - NR 1- LTE
51     [ 
52       0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1  
53     ]
54
55 sub6_all = ...
56     [ 
57       true, true, true, true, false, true, true, true, true, true, true, true
58     ]
59
60 mu_all = ...
61     [
62       0, 0, 0, 1, 3, 1, 0, 0, 0, 0, 0, 0
63     ]
64
65 bw_all = ...
66     [
67       5, 10, 20, 100, 100, 100, 20, 10, 5, 20, 10, 5
68     ]
69
70 ant_num_all = ...
71     [
72       4, 4, 4, 4, 4, 8, 4, 4, 4, 8, 8, 8
73     ]
74
75 bfw_gen_all = ...
76     [
77       false, false, false, false, false, true, false, false, false, true, true, true,
78     ]
79
80 trx_all = ...
81     [ 
82       32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32
83     ]
84 path_to_usecase_all = ... 
85     [
86       "./usecase/cat_a/mu0_5mhz/";
87       "./usecase/cat_a/mu0_10mhz/";
88       "./usecase/cat_a/mu0_20mhz/";
89       "./usecase/cat_a/mu1_100mhz/";
90       "./usecase/cat_a/mu3_100mhz/";
91       "./usecase/cat_b/mu1_100mhz/";
92       "./usecase/lte_a/mu0_20mhz/";
93       "./usecase/lte_a/mu0_10mhz/";
94       "./usecase/lte_a/mu0_5mhz/";
95       "./usecase/lte_b/mu0_20mhz/";
96       "./usecase/lte_b/mu0_10mhz/";
97       "./usecase/lte_b/mu0_5mhz/";      
98     ]
99
100 path_to_usecase_all = cellstr(path_to_usecase_all) 
101
102 nSlots_all = ...
103     [
104        20,20,20,20,20,20,20,20,20,10,10,10
105     ]
106
107 %select mu and bw to generate test files
108 for test_num =(1:1:tests_total)
109     test_num
110     isLte=tech_all(test_num)  %false 
111     sub6=sub6_all(test_num)  %false
112     mu=mu_all(test_num) % 0,1, or 3
113     bw=bw_all(test_num) %5,10,20,100 MHz
114     ant_num = ant_num_all(test_num)
115     bfw_gen=bfw_gen_all(test_num)
116     trx = trx_all(test_num)
117     size(path_to_usecase_all)
118     path_to_usecase = path_to_usecase_all(test_num)
119
120     nSlots=nSlots_all(test_num) % any 40 and 160
121
122     if isLte
123         disp('LTE')
124         if mu < 3
125             nNumerology = mu+1;
126             switch (bw)
127                 case {5}
128                     numRBs = nLteNumRbsPerSymF1(nNumerology,0+1);
129                 case {10}
130                     numRBs = nLteNumRbsPerSymF1(nNumerology,1+1);
131                 case {15}
132                     numRBs = nLteNumRbsPerSymF1(nNumerology,2+1);
133                 case {20}
134                     numRBs = nLteNumRbsPerSymF1(nNumerology,3+1);
135             end
136         end
137     else
138         if sub6
139             disp('Sub6')
140             if mu < 3
141                 nNumerology = mu+1;
142                 switch (bw)
143                     case {5}
144                         numRBs = nNumRbsPerSymF1(nNumerology,0+1);
145                     case {10}
146                         numRBs = nNumRbsPerSymF1(nNumerology,1+1);
147                     case {15}
148                         numRBs = nNumRbsPerSymF1(nNumerology,2+1);
149                     case {20}
150                         numRBs = nNumRbsPerSymF1(nNumerology,3+1);
151                     case {25}
152                         numRBs = nNumRbsPerSymF1(nNumerology,4+1);
153                     case {30}
154                         numRBs = nNumRbsPerSymF1(nNumerology,5+1);
155                     case {40}
156                         numRBs = nNumRbsPerSymF1(nNumerology,6+1);
157                     case {50}
158                         numRBs = nNumRbsPerSymF1(nNumerology,7+1);
159                     case {60}
160                         numRBs = nNumRbsPerSymF1(nNumerology,8+1);
161                     case {70}
162                         numRBs = nNumRbsPerSymF1(nNumerology,9+1);
163                     case {80}
164                         numRBs = nNumRbsPerSymF1(nNumerology,10+1);
165                     case {90}
166                         numRBs = nNumRbsPerSymF1(nNumerology,11+1);
167                     case {100}
168                         numRBs = nNumRbsPerSymF1(nNumerology,12+1);
169                     otherwise
170                         disp('Unknown BW && mu')
171                 end
172             end
173         else
174             disp('mmWave')
175             if  (mu >=2) && (mu <= 3)
176                 nNumerology = mu;
177                 switch (bw)
178                     case {50}
179                         numRBs = nNumRbsPerSymF2(nNumerology-1,0+1);
180                     case {100}
181                         numRBs = nNumRbsPerSymF2(nNumerology-1,1+1);
182                     case {200}
183                         numRBs = nNumRbsPerSymF2(nNumerology-1,2+1);
184                     case {400}
185                         numRBs = nNumRbsPerSymF2(nNumerology-1,3+1);
186                     otherwise
187                         disp('Unknown BW && mu')
188                 end
189             end
190         end
191     end
192     if numRBs ==0
193         disp('Incorrect Numerology and BW combination.')
194         return
195     end
196
197     bw
198     numRBs
199     nSlots
200
201     %use file as input
202     %ifft_in = load('ifft_in.txt')
203
204     %gen IQs
205     ifft_in = [[1:1:(numRBs*12)]', [1:1:(numRBs*12)]'];
206
207     ant_c = ifft_in;
208     for (i=1:1:nSlots*14-1)
209         ifft_in_1 = ifft_in + i;
210         ant_c = [ant_c; ifft_in_1];
211     end
212
213     %write files for IQ samples 
214     for ant = 1:1:ant_num
215         antX=ant_c*(ant*10);
216         antX_16=int16(antX.');
217         file_name = strcat(path_to_usecase,"ant_", num2str(ant-1),".bin");
218         disp(file_name)
219         fileID = fopen(file_name,'w');
220         fwrite(fileID, antX_16, 'int16');
221         fclose(fileID);    
222     end
223
224     if bfw_gen
225         disp('Generate BF Weights per RB')
226
227         %seed to make it repeatable 
228         rand('seed',47)
229
230         %random channel matrix for single sym on syngle RB 
231         H = (rand(trx,ant_num) + 1j*rand(trx,ant_num));
232
233         %calculate weights 
234         % W_dl = H^*(H^TH^*)^-1
235         % W_ul =  ((H^H*H)^-1)H^H
236         % where H^* - conjugate 
237         %       H^T - transpose
238         %       H^H - conjugate transpose 
239         W_dl = conj(H)*(transpose(H)*conj(H))^-1; %weights for DL
240         W_ul = ((ctranspose(H)*H)^-1)*ctranspose(H); %weights for UL
241
242         W_ul = W_ul.';
243
244         for ant = 1:1:ant_num
245             %DL 
246
247             bfw_per_sym = [];
248             % adjust channel per each RB 
249             for iPrb = 1:1:numRBs
250                bfw_per_sym = [ bfw_per_sym, [real((W_dl(:, ant).'))*iPrb; imag((W_dl(:, ant).'))*iPrb]];
251             end
252
253             bfw_all_slots = [];
254             %reuse channel for all symbols  
255             for (slot_idx=1:1:nSlots*14)
256                 bfw_all_slots = [bfw_all_slots, bfw_per_sym];
257             end
258
259             bfw_all_slots_int = int16(bfw_all_slots./max(max(abs((bfw_all_slots.')))).*2^15);
260
261             %write files for IQ samples 
262             antX_16=bfw_all_slots_int.';
263             file_name = strcat(path_to_usecase,"dl_bfw_ue_", num2str(ant-1),".bin");
264             disp(file_name)
265             fileID = fopen(file_name,'w');
266             fwrite(fileID,antX_16, 'int16');
267             fclose(fileID);    
268
269             %UL 
270             bfw_per_sym = [];
271             % adjust channel per each RB 
272             for iPrb = 1:1:numRBs
273                bfw_per_sym = [ bfw_per_sym, [real((W_ul(:, ant).'))*iPrb; imag((W_ul(:, ant).'))*iPrb]];
274             end
275
276             bfw_all_slots = [];
277             %reuse channel for all symbols  
278             for (slot_idx=1:1:nSlots*14)
279                 bfw_all_slots = [bfw_all_slots, bfw_per_sym];
280             end
281
282             bfw_all_slots_int = int16(bfw_all_slots./max(max(abs((bfw_all_slots.')))).*2^15);
283
284             %write files for IQ samples 
285             antX_16=bfw_all_slots_int.';
286             file_name = strcat(path_to_usecase,"ul_bfw_ue_", num2str(ant-1),".bin");
287             disp(file_name)
288             fileID = fopen(file_name,'w');
289             fwrite(fileID,antX_16, 'int16');
290             fclose(fileID);    
291         end  
292     end
293 end
294
295 %% generate IQ file with valid constellation, for DL modulation compression
296 % only in mu1_100mhz
297 %constellation = [4096, -4096];
298 %constellation = [2590, 7770, -7770, -2590];
299 %constellation = [633, 1897, 3161, 4425, -4424, -3160, -1897, -633];
300 constellation_all = [628, 1885, 3141, 4398, 5654, 6911, 8167, 9424, -9424, -8167, -6911, -5654, -4398, -3141, -1885, -628;
301     633, 1897, 3161, 4425, -4424, -3160, -1897, -633, 633, 1897, 3161, 4425, -4424, -3160, -1897, -633;
302     2590, 7770, -7770, -2590, 2590, 7770, -7770, -2590, 2590, 7770, -7770, -2590, 2590, 7770, -7770, -2590;
303     4096, -4096, 4096, -4096, 4096, -4096, 4096, -4096, 4096, -4096, 4096, -4096, 4096, -4096, 4096, -4096;
304     ];
305
306 numRBs = 273
307 nSlots = 20
308 path_all = ...
309     [
310       "./usecase/cat_a/mu1_100mhz/";
311       "./usecase/cat_b/mu1_100mhz/";
312       "./usecase/cat_b/mu1_100mhz/";
313       "./usecase/cat_b/mu1_100mhz/";
314     ]
315 path_all = cellstr(path_all)
316 modtype_all = ...
317     [
318       "256qam_ant_";
319       "64qam_ant_";
320       "16qam_ant_";
321       "qpsk_ant_";
322     ]
323 modtype_all = cellstr(modtype_all)
324
325 for test_num = 1:4
326     path = path_all(test_num);
327     constellation=constellation_all(test_num,:);
328     modtype = modtype_all(test_num);
329     for ant = 1:4
330         ant_in = rand(2*12*numRBs*14*nSlots,1); % random constellation
331         ant_in = 1+round(15 * ant_in);
332         ant_out = constellation(ant_in);
333         file_name = strcat(path,modtype, num2str(ant-1),".bin");
334         disp(file_name)
335         fileID = fopen(file_name,'w');
336         fwrite(fileID, ant_out, 'int16');
337         fclose(fileID);
338     end
339 end
340
341