A Discrete-Event Network Simulator
QKDNetSim v2.0 (NS-3 v3.41) @ (+)
API
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
bianchi11ax.py
Go to the documentation of this file.
1 #
2 # Copyright 2020 University of Washington
3 #
4 # This program is free software; you can redistribute it and/or modify
5 # it under the terms of the GNU General Public License version 2 as
6 # published by the Free Software Foundation;
7 #
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details.
12 #
13 # You should have received a copy of the GNU General Public License
14 # along with this program; if not, write to the Free Software
15 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 #
17 # Authors: Hao Yin and Sebastien Deronne
18 #
19 import math
20 
21 import numpy as np
22 
23 
24 def bianchi_ax(data_rate, ack_rate, k, difs):
25  # Parameters for 11ax
26  nA = np.linspace(5, 50, 10)
27  CWmin = 15
28  CWmax = 1023
29  L_DATA = 1500 * 8 # data size in bits
30  L_ACK = 14 * 8 # ACK size in bits
31  # B = 1/(CWmin+1)
32  B = 0
33  EP = L_DATA / (1 - B)
34  T_GI = 800e-9 # guard interval in seconds
35  T_SYMBOL_ACK = 4e-6 # symbol duration in seconds (for ACK)
36  T_SYMBOL_DATA = 12.8e-6 + T_GI # symbol duration in seconds (for DATA)
37  T_PHY_ACK = 20e-6 # PHY preamble & header duration in seconds (for ACK)
38  T_PHY_DATA = 44e-6 # PHY preamble & header duration in seconds (for DATA)
39  L_SERVICE = 16 # service field length in bits
40  L_TAIL = 6 # tail length in bits
41  L_MAC = (30) * 8 # MAC header size in bits
42  L_APP_HDR = 8 * 8 # bits added by the upper layer(s)
43  T_SIFS = 16e-6
44  T_DIFS = 34e-6
45  T_SLOT = 9e-6
46  delta = 1e-7
47 
48  Aggregation_Type = "A_MPDU" # A_MPDU or A_MSDU (HYBRID not fully supported)
49  K_MSDU = 1
50  K_MPDU = k
51  L_MPDU_HEADER = 4
52  L_MSDU_HEADER = 14 * 8
53  if k <= 1:
54  Aggregation_Type = "NONE"
55 
56  N_DBPS = data_rate * T_SYMBOL_DATA # number of data bits per OFDM symbol
57 
58  if Aggregation_Type == "NONE":
59  N_SYMBOLS = math.ceil((L_SERVICE + (L_MAC + L_DATA + L_APP_HDR) + L_TAIL) / N_DBPS)
60  T_DATA = T_PHY_DATA + (T_SYMBOL_DATA * N_SYMBOLS)
61  K_MPDU = 1
62  K_MSDU = 1
63 
64  if Aggregation_Type == "A_MSDU":
65  N_SYMBOLS = math.ceil(
66  (
67  L_SERVICE
68  + K_MPDU * (L_MAC + L_MPDU_HEADER + K_MSDU * (L_MSDU_HEADER + L_DATA + L_APP_HDR))
69  + L_TAIL
70  )
71  / N_DBPS
72  )
73  T_DATA = T_PHY_DATA + (T_SYMBOL_DATA * N_SYMBOLS)
74 
75  if Aggregation_Type == "A_MPDU":
76  N_SYMBOLS = math.ceil(
77  (L_SERVICE + K_MPDU * (L_MAC + L_MPDU_HEADER + L_DATA + L_APP_HDR) + L_TAIL) / N_DBPS
78  )
79  T_DATA = T_PHY_DATA + (T_SYMBOL_DATA * N_SYMBOLS)
80 
81  # Calculate ACK Duration
82  N_DBPS = ack_rate * T_SYMBOL_ACK # number of data bits per OFDM symbol
83  N_SYMBOLS = math.ceil((L_SERVICE + L_ACK + L_TAIL) / N_DBPS)
84  T_ACK = T_PHY_ACK + (T_SYMBOL_ACK * N_SYMBOLS)
85 
86  T_s = T_DATA + T_SIFS + T_ACK + T_DIFS
87  if difs == 1: # DIFS
88  T_C = T_DATA + T_DIFS
89  else:
90  T_s = T_DATA + T_SIFS + T_ACK + T_DIFS + delta
91  T_C = T_DATA + T_DIFS + T_SIFS + T_ACK + delta
92 
93  T_S = T_s / (1 - B) + T_SLOT
94 
95  S_bianchi = np.zeros(len(nA))
96  for j in range(len(nA)):
97  n = nA[j] * 1
98  W = CWmin + 1
99  m = math.log2((CWmax + 1) / (CWmin + 1))
100  tau1 = np.linspace(0, 0.1, 100000)
101  p = 1 - np.power((1 - tau1), (n - 1))
102  ps = p * 0
103 
104  for i in range(int(m)):
105  ps = ps + np.power(2 * p, i)
106 
107  taup = 2.0 / (1 + W + p * W * ps)
108  b = np.argmin(np.abs(tau1 - taup))
109  tau = taup[b]
110 
111  Ptr = 1 - math.pow((1 - tau), int(n))
112  Ps = n * tau * math.pow((1 - tau), int(n - 1)) / Ptr
113 
114  S_bianchi[j] = (
115  K_MSDU
116  * K_MPDU
117  * Ps
118  * Ptr
119  * EP
120  / ((1 - Ptr) * T_SLOT + Ptr * Ps * T_S + Ptr * (1 - Ps) * T_C)
121  / 1e6
122  )
123 
124  bianchi_result = S_bianchi
125  return bianchi_result
126 
127 
128 def str_result(bianchi_result, mcs, bw):
129  str_bianchi = " {" + '"HeMcs{:d}'.format(mcs) + '_{:d}MHz"'.format(bw) + ", {\n"
130  for i in range(len(bianchi_result)):
131  str_tmp = " {" + "{:d}, {:.4f}".format(5 * (i + 1), bianchi_result[i]) + "},\n"
132  str_bianchi = str_bianchi + str_tmp
133  str_bianchi = str_bianchi + " }},\n"
134  print(str_bianchi)
135  return str_bianchi
136 
137 
138 # Settings for different MCS and mode
139 data_rates_20MHz = [
140  8.603e6,
141  17.206e6,
142  25.8e6,
143  34.4e6,
144  51.5e6,
145  68.8e6,
146  77.4e6,
147  86e6,
148  103.2e6,
149  114.7e6,
150  129e6,
151  143.4e6,
152 ]
153 ack_rates_20MHz = [6e6, 12e6, 12e6, 24e6, 24e6, 24e6, 24e6, 24e6, 24e6, 24e6, 24e6, 24e6]
154 data_rates_40MHz = [
155  17.2e6,
156  34.4e6,
157  51.5e6,
158  68.8e6,
159  103.2e6,
160  137.6e6,
161  154.9e6,
162  172.1e6,
163  206.5e6,
164  229.4e6,
165  258.1e6,
166  286.8e6,
167 ]
168 ack_rates_40MHz = [6e6, 12e6, 12e6, 24e6, 24e6, 24e6, 24e6, 24e6, 24e6, 24e6, 24e6, 24e6]
169 data_rates_80MHz = [
170  36e6,
171  72.1e6,
172  108.1e6,
173  144.1e6,
174  216.2e6,
175  288.2e6,
176  324.3e6,
177  360.3e6,
178  432.4e6,
179  480.4e6,
180  540.4e6,
181  600.5e6,
182 ]
183 ack_rates_80MHz = [6e6, 12e6, 12e6, 24e6, 24e6, 24e6, 24e6, 24e6, 24e6, 24e6, 24e6, 24e6]
184 data_rates_160MHz = [
185  72.1e6,
186  144.1e6,
187  216.2e6,
188  288.2e6,
189  432.4e6,
190  576.5e6,
191  648.5e6,
192  720.6e6,
193  864.7e6,
194  960.8e6,
195  1080.9e6,
196  1201e6,
197 ]
198 ack_rates_160MHz = [6e6, 12e6, 12e6, 24e6, 24e6, 24e6, 24e6, 24e6, 24e6, 24e6, 24e6, 24e6]
199 
200 # Generate results with frame aggregation disabled
201 k = 1
202 
203 difs = 1
204 with open("bianchi_11ax_difs.txt", "w", encoding="utf-8") as f:
205  for i in range(len(data_rates_20MHz)):
206  bianchi_result = bianchi_ax(data_rates_20MHz[i], ack_rates_20MHz[i], k, difs)
207  str_s = str_result(bianchi_result, i, 20)
208  f.write(str_s)
209  for i in range(len(data_rates_40MHz)):
210  bianchi_result = bianchi_ax(data_rates_40MHz[i], ack_rates_40MHz[i], k, difs)
211  str_s = str_result(bianchi_result, i, 40)
212  f.write(str_s)
213  for i in range(len(data_rates_80MHz)):
214  bianchi_result = bianchi_ax(data_rates_80MHz[i], ack_rates_80MHz[i], k, difs)
215  str_s = str_result(bianchi_result, i, 80)
216  f.write(str_s)
217  for i in range(len(data_rates_160MHz)):
218  bianchi_result = bianchi_ax(data_rates_160MHz[i], ack_rates_160MHz[i], k, difs)
219  str_s = str_result(bianchi_result, i, 160)
220  f.write(str_s)
221 
222 difs = 0
223 with open("bianchi_11ax_eifs.txt", "w", encoding="utf-8") as f:
224  for i in range(len(data_rates_20MHz)):
225  bianchi_result = bianchi_ax(data_rates_20MHz[i], ack_rates_20MHz[i], k, difs)
226  str_s = str_result(bianchi_result, i, 20)
227  f.write(str_s)
228  for i in range(len(data_rates_40MHz)):
229  bianchi_result = bianchi_ax(data_rates_40MHz[i], ack_rates_40MHz[i], k, difs)
230  str_s = str_result(bianchi_result, i, 40)
231  f.write(str_s)
232  for i in range(len(data_rates_80MHz)):
233  bianchi_result = bianchi_ax(data_rates_80MHz[i], ack_rates_80MHz[i], k, difs)
234  str_s = str_result(bianchi_result, i, 80)
235  f.write(str_s)
236  for i in range(len(data_rates_160MHz)):
237  bianchi_result = bianchi_ax(data_rates_160MHz[i], ack_rates_160MHz[i], k, difs)
238  str_s = str_result(bianchi_result, i, 160)
239  f.write(str_s)
def bianchi_ax(data_rate, ack_rate, k, difs)
Definition: bianchi11ax.py:24
def str_result(bianchi_result, mcs, bw)
Definition: bianchi11ax.py:128