A Discrete-Event Network Simulator
API
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 numpy as np
20 import math
21 
22 
23 def bianchi_ax(data_rate, ack_rate, k, difs):
24  # Parameters for 11ax
25  nA = np.linspace(5, 50, 10)
26  CWmin = 15
27  CWmax = 1023
28  L_DATA = 1500 * 8 # data size in bits
29  L_ACK = 14 * 8 # ACK size in bits
30  #B = 1/(CWmin+1)
31  B=0
32  EP = L_DATA/(1-B)
33  T_GI = 800e-9 # guard interval in seconds
34  T_SYMBOL_ACK = 4e-6 # symbol duration in seconds (for ACK)
35  T_SYMBOL_DATA = 12.8e-6 + T_GI # symbol duration in seconds (for DATA)
36  T_PHY_ACK = 20e-6 # PHY preamble & header duration in seconds (for ACK)
37  T_PHY_DATA = 44e-6 # PHY preamble & header duration in seconds (for DATA)
38  L_SERVICE = 16 # service field length in bits
39  L_TAIL = 6 # tail lengthh in bits
40  L_MAC = (30) * 8 # MAC header size in bits
41  L_APP_HDR = 8 * 8 # bits added by the upper layer(s)
42  T_SIFS = 16e-6
43  T_DIFS = 34e-6
44  T_SLOT = 9e-6
45  delta = 1e-7
46 
47  Aggregation_Type = 'A_MPDU' #A_MPDU or A_MSDU (HYBRID not fully supported)
48  K_MSDU = 1
49  K_MPDU = k
50  L_MPDU_HEADER = 4
51  L_MSDU_HEADER = 14 * 8
52  if (k <= 1):
53  Aggregation_Type = 'NONE'
54 
55  N_DBPS = data_rate * T_SYMBOL_DATA # number of data bits per OFDM symbol
56 
57  if (Aggregation_Type == 'NONE'):
58  N_SYMBOLS = math.ceil((L_SERVICE + (L_MAC + L_DATA + L_APP_HDR) + L_TAIL)/N_DBPS)
59  T_DATA = T_PHY_DATA + (T_SYMBOL_DATA * N_SYMBOLS)
60  K_MPDU = 1
61  K_MSDU = 1
62 
63  if (Aggregation_Type == 'A_MSDU'):
64  N_SYMBOLS = math.ceil((L_SERVICE + K_MPDU*(L_MAC + L_MPDU_HEADER + K_MSDU*(L_MSDU_HEADER + L_DATA + L_APP_HDR)) + L_TAIL)/N_DBPS)
65  T_DATA = T_PHY_DATA + (T_SYMBOL_DATA * N_SYMBOLS)
66 
67  if (Aggregation_Type == 'A_MPDU'):
68  N_SYMBOLS = math.ceil((L_SERVICE + K_MPDU*(L_MAC + L_MPDU_HEADER + L_DATA + L_APP_HDR) + L_TAIL)/N_DBPS)
69  T_DATA = T_PHY_DATA + (T_SYMBOL_DATA * N_SYMBOLS)
70 
71  #Calculate ACK Duration
72  N_DBPS = ack_rate * T_SYMBOL_ACK # number of data bits per OFDM symbol
73  N_SYMBOLS = math.ceil((L_SERVICE + L_ACK + L_TAIL)/N_DBPS)
74  T_ACK = T_PHY_ACK + (T_SYMBOL_ACK * N_SYMBOLS)
75 
76  T_s = T_DATA + T_SIFS + T_ACK + T_DIFS
77  if difs == 1: #DIFS
78  T_C = T_DATA + T_DIFS
79  else:
80  T_s = T_DATA + T_SIFS + T_ACK + T_DIFS + delta
81  T_C = T_DATA + T_DIFS + T_SIFS + T_ACK + delta
82 
83  T_S = T_s/(1-B) + T_SLOT
84 
85  S_bianchi = np.zeros(len(nA))
86  for j in range(len(nA)):
87  n = nA[j]*1
88  W = CWmin + 1
89  m = math.log2((CWmax + 1)/(CWmin + 1))
90  tau1 = np.linspace(0, 0.1, 100000)
91  p = 1 - np.power((1 - tau1),(n - 1))
92  ps = p*0
93 
94  for i in range(int(m)):
95  ps = ps + np.power(2*p, i)
96 
97  taup = 2./(1 + W + p*W*ps)
98  b = np.argmin(np.abs(tau1 - taup))
99  tau = taup[b]
100 
101  Ptr = 1 - math.pow((1 - tau), int(n))
102  Ps = n*tau*math.pow((1 - tau), int(n-1))/Ptr
103 
104  S_bianchi[j] = K_MSDU*K_MPDU*Ps*Ptr*EP/((1-Ptr)*T_SLOT+Ptr*Ps*T_S+Ptr*(1-Ps)*T_C)/1e6
105 
106  bianchi_result = S_bianchi
107  return bianchi_result
108 
109 def str_result(bianchi_result, mcs, bw):
110  str_bianchi = ' {' + '\"HeMcs{:d}'.format(mcs) + '_{:d}MHz\"'.format(bw) + ', {\n'
111  for i in range (len(bianchi_result)):
112  str_tmp = ' {' + '{:d}, {:.4f}'.format(5*(i+1), bianchi_result[i]) +'},\n'
113  str_bianchi = str_bianchi + str_tmp
114  str_bianchi = str_bianchi + " }},\n"
115  print(str_bianchi)
116  return str_bianchi
117 
118 # Settings for different MCS and mode
119 data_rates_20MHz = [8.603e6, 17.206e6, 25.8e6, 34.4e6, 51.5e6, 68.8e6, 77.4e6, 86e6, 103.2e6, 114.7e6, 129e6, 143.4e6]
120 ack_rates_20MHz = [6e6, 12e6, 12e6, 24e6, 24e6, 24e6, 24e6, 24e6, 24e6, 24e6, 24e6, 24e6]
121 data_rates_40MHz = [17.2e6, 34.4e6, 51.5e6, 68.8e6, 103.2e6, 137.6e6, 154.9e6, 172.1e6, 206.5e6, 229.4e6, 258.1e6, 286.8e6]
122 ack_rates_40MHz = [6e6, 12e6, 12e6, 24e6, 24e6, 24e6, 24e6, 24e6, 24e6, 24e6, 24e6, 24e6]
123 data_rates_80MHz = [36e6, 72.1e6, 108.1e6, 144.1e6, 216.2e6, 288.2e6, 324.3e6, 360.3e6, 432.4e6, 480.4e6, 540.4e6, 600.5e6]
124 ack_rates_80MHz = [6e6, 12e6, 12e6, 24e6, 24e6, 24e6, 24e6, 24e6, 24e6, 24e6, 24e6, 24e6]
125 data_rates_160MHz = [72.1e6, 144.1e6, 216.2e6, 288.2e6, 432.4e6, 576.5e6, 648.5e6, 720.6e6, 864.7e6, 960.8e6, 1080.9e6, 1201e6]
126 ack_rates_160MHz = [6e6, 12e6, 12e6, 24e6, 24e6, 24e6, 24e6, 24e6, 24e6, 24e6, 24e6, 24e6]
127 
128 # Generate results with frame aggregation disabled
129 k = 1
130 
131 difs = 1
132 fo = open("bianchi_11ax_difs.txt", "w")
133 for i in range(len(data_rates_20MHz)):
134  bianchi_result = bianchi_ax(data_rates_20MHz[i], ack_rates_20MHz[i], k, difs)
135  str_s = str_result(bianchi_result, i, 20)
136  fo.write(str_s)
137 for i in range(len(data_rates_40MHz)):
138  bianchi_result = bianchi_ax(data_rates_40MHz[i], ack_rates_40MHz[i], k, difs)
139  str_s = str_result(bianchi_result, i, 40)
140  fo.write(str_s)
141 for i in range(len(data_rates_80MHz)):
142  bianchi_result = bianchi_ax(data_rates_80MHz[i], ack_rates_80MHz[i], k, difs)
143  str_s = str_result(bianchi_result, i, 80)
144  fo.write(str_s)
145 for i in range(len(data_rates_160MHz)):
146  bianchi_result = bianchi_ax(data_rates_160MHz[i], ack_rates_160MHz[i], k, difs)
147  str_s = str_result(bianchi_result, i, 160)
148  fo.write(str_s)
149 fo.close()
150 
151 difs = 0
152 fo = open("bianchi_11ax_eifs.txt", "w")
153 for i in range(len(data_rates_20MHz)):
154  bianchi_result = bianchi_ax(data_rates_20MHz[i], ack_rates_20MHz[i], k, difs)
155  str_s = str_result(bianchi_result, i, 20)
156  fo.write(str_s)
157 for i in range(len(data_rates_40MHz)):
158  bianchi_result = bianchi_ax(data_rates_40MHz[i], ack_rates_40MHz[i], k, difs)
159  str_s = str_result(bianchi_result, i, 40)
160  fo.write(str_s)
161 for i in range(len(data_rates_80MHz)):
162  bianchi_result = bianchi_ax(data_rates_80MHz[i], ack_rates_80MHz[i], k, difs)
163  str_s = str_result(bianchi_result, i, 80)
164  fo.write(str_s)
165 for i in range(len(data_rates_160MHz)):
166  bianchi_result = bianchi_ax(data_rates_160MHz[i], ack_rates_160MHz[i], k, difs)
167  str_s = str_result(bianchi_result, i, 160)
168  fo.write(str_s)
169 fo.close()
def str_result(bianchi_result, mcs, bw)
Definition: bianchi11ax.py:109
def bianchi_ax(data_rate, ack_rate, k, difs)
Definition: bianchi11ax.py:23