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# 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#
19import math
20
21import numpy as np
22
23
24def 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
128def 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
139data_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]
153ack_rates_20MHz = [6e6, 12e6, 12e6, 24e6, 24e6, 24e6, 24e6, 24e6, 24e6, 24e6, 24e6, 24e6]
154data_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]
168ack_rates_40MHz = [6e6, 12e6, 12e6, 24e6, 24e6, 24e6, 24e6, 24e6, 24e6, 24e6, 24e6, 24e6]
169data_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]
183ack_rates_80MHz = [6e6, 12e6, 12e6, 24e6, 24e6, 24e6, 24e6, 24e6, 24e6, 24e6, 24e6, 24e6]
184data_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]
198ack_rates_160MHz = [6e6, 12e6, 12e6, 24e6, 24e6, 24e6, 24e6, 24e6, 24e6, 24e6, 24e6, 24e6]
199
200# Generate results with frame aggregation disabled
201k = 1
202
203difs = 1
204with 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
222difs = 0
223with 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