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