├── Cell.py ├── InterSliceSch.py ├── IntraSliceSch.py ├── LICENSE ├── LICENSE.md ├── README.md ├── Results.py ├── Scheds_Inter.py ├── Scheds_Intra.py ├── Slice.py ├── UE.py ├── doc ├── Py5cheSim.Cell.Cell.html ├── Py5cheSim.Cell.html ├── Py5cheSim.InterSliceSch.InterSliceScheduler.html ├── Py5cheSim.InterSliceSch.html ├── Py5cheSim.IntraSliceSch.Format.html ├── Py5cheSim.IntraSliceSch.IntraSliceScheduler.html ├── Py5cheSim.IntraSliceSch.LTE_scheduler.html ├── Py5cheSim.IntraSliceSch.TBqueue.html ├── Py5cheSim.IntraSliceSch.TransportBlock.html ├── Py5cheSim.IntraSliceSch.html ├── Py5cheSim.Results.UEgroup.html ├── Py5cheSim.Results.html ├── Py5cheSim.Scheds_Inter.PF_Scheduler.html ├── Py5cheSim.Scheds_Inter.RRplus_Scheduler.html ├── Py5cheSim.Scheds_Inter.html ├── Py5cheSim.Scheds_Intra.PF_Scheduler.html ├── Py5cheSim.Scheds_Intra.TBqueueTDD.html ├── Py5cheSim.Scheds_Intra.TDD_Scheduler.html ├── Py5cheSim.Scheds_Intra.html ├── Py5cheSim.Slice.Slice.html ├── Py5cheSim.Slice.html ├── Py5cheSim.UE.Bearer.html ├── Py5cheSim.UE.Format.html ├── Py5cheSim.UE.Packet.html ├── Py5cheSim.UE.PacketFlow.html ├── Py5cheSim.UE.PcktQueue.html ├── Py5cheSim.UE.RadioLink.html ├── Py5cheSim.UE.UE.html ├── Py5cheSim.UE.html ├── Py5cheSim.html ├── Py5cheSim.simulation.html ├── apidocs.css ├── bootstrap.min.css ├── classIndex.html ├── index.html ├── moduleIndex.html ├── nameIndex.html ├── objects.inv ├── pydoctor.js └── undoccedSummary.html └── simulation.py /Cell.py: -------------------------------------------------------------------------------- 1 | """ This module contains the Cell class. 2 | """ 3 | import os 4 | import sys 5 | import simpy #from SimPy.Simulation import * (simpy2.2) 6 | from collections import deque 7 | import math 8 | import random 9 | from Slice import * 10 | from Scheds_Inter import * 11 | 12 | # Cell Class: cell description 13 | 14 | class Cell(): 15 | """Cell class has cell relative parameters and collect kpi ststistics. """ 16 | def __init__(self,i,b,fr,dm,mBue,tdd,gr,schInter): 17 | """This method creates a cell instance. 18 | 19 | It initialices cell parameters and interSliceScheduler according to the algorithm specified on the sch attribute.""" 20 | self.id = i 21 | self.bw = b 22 | self.inactTimer = 3000 23 | self.tUdQueue = 0.05 24 | self.maxBuffUE = mBue 25 | """Maximum bearer buffer size by UE, in bytes""" 26 | self.sch = schInter 27 | if schInter[0:3] == 'RRp': 28 | self.interSliceSched = RRplus_Scheduler(self.bw,fr,dm,tdd,gr) 29 | elif schInter[0:2] == 'PF': 30 | self.interSliceSched = PF_Scheduler(self.bw,fr,dm,tdd,gr,schInter) 31 | elif schInter[0:2] == 'DT': 32 | self.interSliceSched = dynTDD_Scheduler(self.bw,fr,dm,tdd,gr) 33 | else: 34 | self.interSliceSched = InterSliceScheduler(self.bw,fr,dm,tdd,gr) 35 | self.sch = 'RR' 36 | self.slicesStsts = {} 37 | 38 | def updateStsts(self,env,interv,tSim): # ---------- PEM ------------- 39 | """This method manages the statistics collection. This is a PEM Method. 40 | 41 | This method creates statistics files and stores counter values to calculate later the main kpi considered. \n 42 | Inter Slice statistics are stored in the dlStsts_InterSlice.txt file for DL and ulStsts_InterSlice.txt file for UL. \n 43 | Intra Slice statistics are stored in the dlStsts_Slice.txt file for DL and ulStsts_Slice.txt file for UL.""" 44 | if not os.path.exists('Statistics'): 45 | os.mkdir('Statistics') 46 | for slice in list(self.interSliceSched.slices.keys()): 47 | self.slicesStsts[slice] = {} 48 | self.slicesStsts[slice]['DL'] = open('Statistics/dlStsts'+'_'+slice+'.txt','w') 49 | self.slicesStsts[slice]['DL'].write('time ue sinr MCS BLER ResourceUse sntPackets lstPackets rcvdBytes sliceLabel'+'\n') 50 | self.slicesStsts[slice]['UL'] = open('Statistics/ulStsts'+'_'+slice+'.txt','w') 51 | self.slicesStsts[slice]['UL'].write('time ue sinr MCS BLER ResourceUse sntPackets lstPackets rcvdBytes sliceLabel'+'\n') 52 | self.slicesStsts['InterSlice'] = {} 53 | self.slicesStsts['InterSlice']['DL'] = open('Statistics/dlStsts_InterSlice.txt','w') 54 | self.slicesStsts['InterSlice']['DL'].write('time Slice Connections ResourceUse sntPackets lstPackets rcvdBytes bufferSize'+'\n') 55 | self.slicesStsts['InterSlice']['UL'] = open('Statistics/ulStsts_InterSlice.txt','w') 56 | self.slicesStsts['InterSlice']['UL'].write('time Slice Connections ResourceUse sntPackets lstPackets rcvdBytes bufferSize'+'\n') 57 | 58 | while env.now<(tSim*0.83): 59 | yield env.timeout(interv) 60 | for slice in list(self.interSliceSched.slices.keys()): 61 | conn_UEs = list(self.interSliceSched.slices[slice].schedulerDL.ues.keys()) 62 | res = self.interSliceSched.slices[slice].schedulerDL.nrbUEmax 63 | lostP = 0 64 | sentP = 0 65 | recByts = 0 66 | sliceRcvdBytes = 0 # interSlice PF scheduler 67 | buf = 0 68 | for ue in conn_UEs: 69 | lP = self.interSliceSched.slices[slice].schedulerDL.ues[ue].packetFlows[0].lostPackets 70 | sP = self.interSliceSched.slices[slice].schedulerDL.ues[ue].packetFlows[0].sentPackets 71 | rB = self.interSliceSched.slices[slice].schedulerDL.ues[ue].packetFlows[0].rcvdBytes 72 | sinr = self.interSliceSched.slices[slice].schedulerDL.ues[ue].radioLinks.linkQuality 73 | mcs = self.interSliceSched.slices[slice].schedulerDL.ues[ue].MCS 74 | bler = self.interSliceSched.slices[slice].schedulerDL.ues[ue].bler 75 | resUse = self.interSliceSched.slices[slice].schedulerDL.ues[ue].resUse 76 | buf = self.interSliceSched.slices[slice].schedulerDL.updSumPcks() 77 | lostP = lostP + lP 78 | sentP = sentP + sP 79 | recByts = recByts + rB 80 | self.slicesStsts[slice]['DL'].write(str(env.now)+' '+ue+' '+str(sinr)+' '+str(mcs)+' '+str(bler)+' '+str(resUse)+' '+str(sP)+' '+str(lP)+' '+str(rB)+' '+slice+'\n') 81 | sliceRcvdBytes = sliceRcvdBytes + recByts # interSlice PF scheduler 82 | pfSliceMetric = self.interSliceSched.slices[slice].metric 83 | self.slicesStsts['InterSlice']['DL'].write(str(env.now)+' '+slice+' '+str(len(conn_UEs))+' '+str(res)+' '+ str(sentP)+' '+str(lostP)+' '+str(recByts)+' '+str(buf)+' '+str(pfSliceMetric)+'\n') 84 | 85 | if slice != 'LTE': 86 | conn_UEs = list(self.interSliceSched.slices[slice].schedulerUL.ues.keys()) 87 | res = self.interSliceSched.slices[slice].schedulerUL.nrbUEmax 88 | lostP = 0 89 | sentP = 0 90 | recByts = 0 91 | buf = 0 92 | for ue in list(self.interSliceSched.slices[slice].schedulerUL.ues.keys()): 93 | lP = self.interSliceSched.slices[slice].schedulerUL.ues[ue].packetFlows[0].lostPackets 94 | sP = self.interSliceSched.slices[slice].schedulerUL.ues[ue].packetFlows[0].sentPackets 95 | rB = self.interSliceSched.slices[slice].schedulerUL.ues[ue].packetFlows[0].rcvdBytes 96 | sinr = self.interSliceSched.slices[slice].schedulerUL.ues[ue].radioLinks.linkQuality 97 | mcs = self.interSliceSched.slices[slice].schedulerUL.ues[ue].MCS 98 | bler = self.interSliceSched.slices[slice].schedulerUL.ues[ue].bler 99 | resUse = self.interSliceSched.slices[slice].schedulerUL.ues[ue].resUse 100 | buf = self.interSliceSched.slices[slice].schedulerUL.updSumPcks() 101 | lostP = lostP + lP 102 | sentP = sentP + sP 103 | recByts = recByts + rB 104 | self.slicesStsts[slice]['UL'].write(str(env.now)+' '+ue+' '+str(sinr)+' '+str(mcs)+' '+str(bler)+' '+str(resUse)+' '+str(sP)+' '+str(lP)+' '+str(rB)+' '+slice+'\n') 105 | sliceRcvdBytes = sliceRcvdBytes + recByts # interSlice PF scheduler 106 | self.slicesStsts['InterSlice']['UL'].write(str(env.now)+' '+slice+' '+str(len(conn_UEs))+' '+str(res)+' '+ str(sentP)+' '+str(lostP)+' '+str(recByts)+' '+str(buf)+' '+str(pfSliceMetric)+'\n') 107 | if self.sch[0:2] == 'PF' and len(self.interSliceSched.slices[slice].rcvdBytes) >= self.interSliceSched.rcvdBytesLen: 108 | self.interSliceSched.slices[slice].rcvdBytes.popleft() 109 | self.interSliceSched.slices[slice].rcvdBytes.append(sliceRcvdBytes) # to consider the received bytes during the meassurement interval 110 | 111 | if env.now % (tSim/10) == 0: 112 | i=int(env.now/(tSim/10)) 113 | print ("\r[%-10s] %d%%" % ('='*i, 10*i)+ ' complete simulation') 114 | -------------------------------------------------------------------------------- /InterSliceSch.py: -------------------------------------------------------------------------------- 1 | """This module contains the basic Inter Slice Scheduler class. 2 | All possible inter slice schedulers should inherit from this.""" 3 | import math 4 | import os 5 | from Slice import * 6 | import random 7 | 8 | class InterSliceScheduler(): 9 | """ Basic inter slice scheduler. It implements Round Robin algorithm.""" 10 | def __init__(self,ba,fr,dm,tdd,gr): 11 | self.bw = ba 12 | self.FR = fr 13 | self.nRBtable = {'FR1':{'15kHz':{'5MHz':25,'10MHz':52,'15MHz':79,'20MHz':106,'25MHz':133,'30MHz':160,'40MHz':216,'50MHz':270}, 14 | '30kHz':{'5MHz':11,'10MHz':24,'15MHz':38,'20MHz':51,'25MHz':65,'30MHz':78,'40MHz':106,'50MHz':133,'60MHz':162,'80MHz':217,'90MHz':245,'100MHz':273}, 15 | '60kHz':{'10MHz':11,'15MHz':18,'20MHz':24,'25MHz':31,'30MHz':38,'40MHz':51,'50MHz':65,'60MHz':79,'80MHz':107,'90MHz':121,'100MHz':135}}, 16 | 'FR2':{'60kHz':{'50MHz':66,'100MHz':132,'200MHz':264}, 17 | '120kHz':{'50MHz':32,'100MHz':66,'200MHz':132,'400MHz':264}}} # TS 38.101 table 5.3.2-1 18 | 19 | self.PRBs = 0 20 | for b in self.bw: 21 | if fr == 'FR1': 22 | self.PRBs = self.PRBs + self.nRBtable[fr]['15kHz'][str(b)+'MHz'] 23 | else: 24 | self.PRBs = self.PRBs + self.nRBtable[fr]['60kHz'][str(b)+'MHz'] 25 | self.slices = {} 26 | self.dm = dm 27 | if not os.path.exists('Logs'): 28 | os.mkdir('Logs') 29 | self.dbFile = open('Logs/AllSlices_dbFile.html','w') 30 | self.tdd = tdd 31 | self.granularity = gr 32 | 33 | def resAlloc(self,env): #PEM ------------------------------------------------ 34 | """This method implements Round Robin PRB allocation between the different configured slices. This is a PEM method""" 35 | while True: 36 | self.dbFile.write('

SUBFRAME NUMBER: '+str(env.now)+'

') 37 | if len(list(self.slices.keys()))>0: 38 | if len(list(self.slices.keys()))>1: 39 | for slice in list(self.slices.keys()): 40 | self.slices[slice].updateConfig(int((self.PRBs/len(list(self.slices.keys())))/self.slices[slice].numRefFactor)) 41 | self.printSliceConfig(slice) 42 | else: 43 | slice = self.slices[list(self.slices.keys())[0]] 44 | prbs = 0 45 | for b in self.bw: 46 | prbs = prbs + self.nRBtable[self.FR][slice.scs][str(b)+'MHz'] 47 | slice.updateConfig(prbs) 48 | #slice.updateConfig(1) # For 1PRB IoT test example! ################################################3 49 | self.dbFile.write('
') 50 | yield env.timeout(self.granularity) 51 | 52 | def createSlice(self,dly,thDL,thUL,avl,cnxDL,cnxUL,ba,dm,mmd,ly,lbl,sch): 53 | """This method creates a slice and stores it in the slices dictionary.""" 54 | self.slices[lbl] = Slice(dly,thDL,thUL,avl,cnxDL,cnxUL,ba,dm,mmd,ly,lbl,self.tdd,sch) 55 | 56 | 57 | def printSliceConfig(self,slice): 58 | """This method stores inter slice scheduling debugging information on the log file.""" 59 | if slice == 'LTE': 60 | sliceCnx = len(list(self.slices[slice].schedulerDL.ues.keys())) 61 | sliceBrBuffSz = self.slices[slice].schedulerDL.updSumPcks() 62 | sliceRessources = self.slices[slice].schedulerDL.nrbUEmax 63 | self.dbFile.write('
Slice '+self.slices[slice].label+' data:
') 64 | else: 65 | sliceCnx = max(len(list(self.slices[slice].schedulerDL.ues.keys())),len(list(self.slices[slice].schedulerUL.ues.keys()))) 66 | sliceBrBuffSz = max(self.slices[slice].schedulerDL.updSumPcks(),self.slices[slice].schedulerUL.updSumPcks()) 67 | sliceRessources = max(self.slices[slice].schedulerDL.nrbUEmax,self.slices[slice].schedulerUL.nrbUEmax) 68 | self.dbFile.write('
Slice '+self.slices[slice].label+' data:
') 69 | self.dbFile.write('DL/UL symbols: '+str(self.slices[slice].schedulerDL.TDDsmb)+'/'+str(self.slices[slice].schedulerUL.TDDsmb)+'
') 70 | 71 | self.dbFile.write('Connections: '+str(sliceCnx)+'
') 72 | self.dbFile.write('Bearer Buffer Size (Packets): '+str(sliceBrBuffSz)+'
') 73 | self.dbFile.write('Resources (PRBs): '+str(sliceRessources)+'
') 74 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright 2021 2 | Instituto de Ingenieria Electrica, Facultad de Ingenieria, 3 | Universidad de la Republica, Uruguay. 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Py5cheSim 2 | Py5cheSim is a flexible and open-source simulator based on Python and 3 | specially oriented to simulate cell capacity in 3GPP 5G networks and beyond. 4 | To the best of our knowledge, Py5cheSim is the first simulator that supports 5 | Network Slicing at the Radio Access Network (RAN), one of the main innovations of 5G. 6 | 7 | Py5cheSim was designed to simplify new schedulers implementation. 8 | The main network model abstractions are contained in the simulator Core, so there is no need to have deep knowledge on that field to run a simulation or to integrate a new scheduler. In this way Py5cheSim provides a framework for 5G new scheduler algorithms implementation in a straightforward and intuitive way. 9 | 10 | The tool used to implement Discrete Event Simulation was SimPy and code documentation was made using pydoctor. 11 | 12 | Py5cheSim is build on the next modules:
13 | • UE.py: UE parameters and traffic generation.
14 | • Cell.py: Cell configuration and statistics management.
15 | • Slice.py: Slice configuration.
16 | • IntraSliceSch.py: Base intra slice scheduler implementation.
17 | • InterSliceSch.py: Base inter slice scheduler implementation.
18 | • Scheds Intra.py: Other intra slice schedulers implementation.
19 | • Scheds Inter.py: Other inter slice schedulers implementation.
20 | • simulation.py: Is the simulation script. It configures and runs a simulation.
21 | • Results.py: Provides auxiliary methods to present simulation results, and configure traffic profiles.
22 | 23 | Py5cheSim 1.0 is the result of the Master Thesis of Gabriela Pereyra (Facultad de Ingeniería, UdelaR). 24 | Thesis: Pereyra, G. (2021.). Scheduling in 5G networks : Developing a 5G cell capacity simulator. Tesis de maestría. Universidad de la República (Uruguay). Facultad de Ingeniería. 25 | Article: https://hdl.handle.net/20.500.12008/30549 26 | 27 | Code Documentation: https://htmlpreview.github.io/?https://github.com/ClaudinaRattaro/Py5cheSim/blob/main/doc/Py5cheSim.html 28 | 29 | 30 | In https://github.com/linglesloggia/py5chesim is the improved version of the simulator (version 2 ) 31 | it is related to article: https://www.colibri.udelar.edu.uy/jspui/bitstream/20.500.12008/31723/1/PIRB22.pdf 32 | 33 | In https://github.com/charluy/PFC we have integrated the framework deepmimo (https://deepmimo.net/) as an input of py5chesim (improving the channel model and mimo feature) 34 | -------------------------------------------------------------------------------- /Scheds_Inter.py: -------------------------------------------------------------------------------- 1 | """This module contains different implemented inter slice schedulers. 2 | New schedulers should be implemented here following the current structure.""" 3 | import math 4 | from InterSliceSch import InterSliceScheduler 5 | from Slice import * 6 | import random 7 | 8 | class RRplus_Scheduler(InterSliceScheduler): 9 | """This class implements Round Robin Plus inter slice scheduling algorithm.""" 10 | def __init__(self,ba,fr,dm,tdd,gr): 11 | InterSliceScheduler.__init__(self,ba,fr,dm,tdd,gr) 12 | 13 | def resAlloc(self,env): #PEM ------------------------------------------------ 14 | """This method implements Round Robin Plus PRB allocation between the different configured slices. 15 | This PEM method overwrites the resAlloc method from InterSliceScheduler class. 16 | 17 | Round Robin Plus scheduler allocates the same amount of resources to each slice with packets in buffer. """ 18 | while True: 19 | self.dbFile.write('

SUBFRAME NUMBER: '+str(env.now)+'

') 20 | if len(list(self.slices.keys()))>0: 21 | if len(list(self.slices.keys()))>1: 22 | slicesWithPacks = 0 23 | for slice in list(self.slices.keys()): 24 | sliceHasPackets = self.slices[slice].schedulerDL.updSumPcks()>0 or self.slices[slice].schedulerUL.updSumPcks()>0 25 | if sliceHasPackets: 26 | slicesWithPacks = slicesWithPacks + 1 27 | if slicesWithPacks == 0: 28 | for slice in list(self.slices.keys()): 29 | self.slices[slice].updateConfig(int((self.PRBs/len(list(self.slices.keys())))/self.slices[slice].numRefFactor)) 30 | self.printSliceConfig(slice) 31 | else: 32 | for slice in list(self.slices.keys()): 33 | sliceHasPackets = self.slices[slice].schedulerDL.updSumPcks()>0 or self.slices[slice].schedulerUL.updSumPcks()>0 34 | if not sliceHasPackets: 35 | self.slices[slice].updateConfig(0) 36 | else: 37 | self.slices[slice].updateConfig(int((self.PRBs/slicesWithPacks)/self.slices[slice].numRefFactor)) 38 | self.printSliceConfig(slice) 39 | else: 40 | slice = self.slices[list(self.slices.keys())[0]] 41 | prbs = 0 42 | for b in self.bw: 43 | prbs = prbs + self.nRBtable[self.FR][slice.scs][str(b)+'MHz'] 44 | slice.updateConfig(prbs) 45 | self.dbFile.write('
') 46 | yield env.timeout(self.granularity) 47 | 48 | 49 | class PF_Scheduler(InterSliceScheduler): 50 | """This class implements Proportional Fair inter slice scheduling algorithm.""" 51 | def __init__(self,ba,fr,dm,tdd,gr,sch): 52 | InterSliceScheduler.__init__(self,ba,fr,dm,tdd,gr) 53 | self.sch = sch 54 | """String formatted as PFXY, with X=numerator exponent for metric formula, and Y=denominator exponent. """ 55 | self.rcvdBytesLen = 10 56 | """rcvdBytes list length in Slice instance. No more that rcvdBytesLen values are stored.""" 57 | 58 | def resAlloc(self,env): #PEM ------------------------------------------------ 59 | """This method implements Proportional Fair resource allocation between the different configured slices. 60 | This PEM method overwrites the resAlloc method from InterSliceScheduler class. 61 | 62 | Proportional Fair scheduler allocates all PRBs in the cell to the slice with the biggest metric. 63 | Metric for each slice is calculated as PossibleAverageUEtbs/ReceivedBytes.""" 64 | while True: 65 | self.dbFile.write('

SUBFRAME NUMBER: '+str(env.now)+'

') 66 | if len(list(self.slices.keys()))>0: 67 | if len(list(self.slices.keys()))>1: 68 | if env.now>0: 69 | self.setMetric(float(self.sch[2]),float(self.sch[3])) 70 | maxMetSlice = self.findMaxMetSlice() 71 | self.assign2aSlice(maxMetSlice) 72 | self.printSliceConfig(maxMetSlice) 73 | else: 74 | initialSlice = random.choice(list(self.slices.keys())) 75 | self.assign2aSlice(initialSlice) 76 | self.printSliceConfig(initialSlice) 77 | else: 78 | slice = self.slices[list(self.slices.keys())[0]] 79 | prbs = 0 80 | for b in self.bw: 81 | prbs = prbs + self.nRBtable[self.FR][slice.scs][str(b)+'MHz'] 82 | slice.updateConfig(prbs) 83 | self.printSliceConfig(slice.label) 84 | self.dbFile.write('
') 85 | yield env.timeout(self.granularity) 86 | 87 | def setMetric(self,exp_n,exp_d): 88 | """This method sets the PF metric for each slice""" 89 | if len(list(self.slices.keys()))>0: 90 | for slice in list(self.slices.keys()): 91 | rcvdBt_end = self.slices[slice].rcvdBytes[len(self.slices[slice].rcvdBytes)-1] 92 | rcvdBt_in = self.slices[slice].rcvdBytes[0] 93 | if rcvdBt_end - rcvdBt_in == 0: 94 | den = 1 95 | else: 96 | den = rcvdBt_end - rcvdBt_in 97 | num = 0 98 | for ue in list(self.slices[slice].schedulerDL.ues.keys()): 99 | [tbs, mod, bi, mcs] = self.slices[slice].schedulerDL.setMod(ue,self.PRBs) 100 | num = num + tbs 101 | for ue in list(self.slices[slice].schedulerUL.ues.keys()): 102 | [tbs, mod, bi, mcs] = self.slices[slice].schedulerUL.setMod(ue,self.PRBs) 103 | num = num + tbs 104 | num = num/(len(list(self.slices[slice].schedulerDL.ues.keys()))+len(list(self.slices[slice].schedulerUL.ues.keys()))) 105 | self.slices[slice].metric = math.pow(float(num), exp_n)/math.pow(den,exp_d) 106 | 107 | def findMaxMetSlice(self): 108 | """This method finds and returns the Slice with the highest metric""" 109 | metric = 0 110 | for slice in list(self.slices.keys()): 111 | if self.slices[slice].metric > metric: 112 | metric = self.slices[slice].metric 113 | maxSliceM = slice 114 | if self.slices[slice].metric == metric: 115 | slicesMlist = [maxSliceM,slice] 116 | maxSliceM = random.choice(slicesMlist) 117 | return maxSliceM 118 | 119 | def assign2aSlice(self,slice): 120 | """This method allocates cell's PRBs to the indicated slice""" 121 | for sl in list(self.slices.keys()): 122 | if sl == slice: 123 | self.slices[sl].updateConfig(int(self.PRBs/self.slices[sl].numRefFactor)) 124 | else: 125 | self.slices[sl].updateConfig(0) 126 | 127 | def printSliceConfig(self,slice): 128 | """This method stores inter slice scheduling debugging information on the log file, adding PF metric values.""" 129 | super().printSliceConfig(slice) 130 | for s in list(self.slices.keys()): 131 | self.dbFile.write('Slice: '+str(s)+' -> PF Metric: '+str(self.slices[s].metric)+'
') 132 | -------------------------------------------------------------------------------- /Scheds_Intra.py: -------------------------------------------------------------------------------- 1 | """This module contains different implemented intra slice schedulers. 2 | New schedulers should be implemented here following the current structure.""" 3 | 4 | import math 5 | from IntraSliceSch import IntraSliceScheduler, Format 6 | from collections import deque 7 | 8 | class PF_Scheduler(IntraSliceScheduler): # PF Sched --------- 9 | """This class implements Proportional Fair intra slice scheduling algorithm.""" 10 | def __init__(self,ba,n,debMd,sLod,ttiByms,mmd_,ly_,dir,Smb,robustMCS,slcLbl,sch): 11 | IntraSliceScheduler.__init__(self,ba,n,debMd,sLod,ttiByms,mmd_,ly_,dir,Smb,robustMCS,slcLbl,sch) 12 | self.promLen = 30 13 | """Past Throughput average length considered in PF metric""" 14 | def resAlloc(self,band): 15 | """This method implements Proportional Fair resource allocation between the different connected UEs. 16 | This method overwrites the resAlloc method from IntraSliceScheduler class. 17 | 18 | Proportional Fair scheduler allocates all PRBs in the slice to the UE with the biggest metric. 19 | Metric for each UE is calculated as PossibleUEtbs/AveragePastTbs.""" 20 | schd = self.schType[0:2] 21 | if schd=='PF' and len(list(self.ues.keys()))>0: 22 | exp_num = float(self.schType[2]) 23 | exp_den = float(self.schType[3]) 24 | self.setUEfactor(exp_num, exp_den) 25 | maxInd = self.findMaxFactor() 26 | for ue in list(self.ues.keys()): 27 | if ue == maxInd: 28 | self.ues[ue].prbs = band 29 | else: 30 | self.ues[ue].prbs = 0 31 | if len(self.ues[ue].pastTbsz)>self.promLen: 32 | self.ues[ue].pastTbsz.popleft() 33 | self.ues[ue].pastTbsz.append(self.ues[ue].tbsz) 34 | self.ues[ue].tbsz = 1 35 | # Print Resource Allocation 36 | self.printResAlloc() 37 | 38 | def setUEfactor(self, exp_n, exp_d): 39 | """This method sets the PF metric for each UE""" 40 | for ue in list(self.ues.keys()): 41 | sumTBS = 0 42 | for t in self.ues[ue].pastTbsz: 43 | sumTBS = sumTBS + t 44 | actual_den = sumTBS/len(self.ues[ue].pastTbsz) 45 | [tbs, mod, bi, mcs] = self.setMod(ue,self.nrbUEmax) 46 | self.ues[ue].pfFactor = math.pow(float(tbs), exp_n)/math.pow(actual_den,exp_d) 47 | self.ues[ue].lastDen = actual_den 48 | self.ues[ue].num = tbs 49 | 50 | def findMaxFactor(self): 51 | """This method finds and returns the UE with the highest metric""" 52 | factorMax = 0 53 | factorMaxInd = '' 54 | for ue in list(self.ues.keys()): 55 | if len(self.ues[ue].bearers[0].buffer.pckts)>0 and self.ues[ue].pfFactor>factorMax: 56 | factorMax = self.ues[ue].pfFactor 57 | factorMaxInd = ue 58 | if factorMaxInd=='': 59 | ue = list(self.ues.keys())[self.ind_u] 60 | q = 0 61 | while len(self.ues[ue].bearers[0].buffer.pckts)==0 and q') 72 | self.printDebData('PRBs: '+str(self.nrbUEmax)+'
') 73 | resAllocMsg = '' 74 | for ue in list(self.ues.keys()): 75 | resAllocMsg = resAllocMsg + ue +' '+ str(self.ues[ue].pfFactor)+' '+str(self.ues[ue].prbs)+ ' '+str(self.ues[ue].num)+' '+ str(self.ues[ue].lastDen)+'
' 76 | self.printDebData(resAllocMsg) 77 | self.printDebData('+++++++++++++++++++++++++++++++++++'+'
') 78 | 79 | class TDD_Scheduler(IntraSliceScheduler): # TDD Sched --------- 80 | """This class implements TDD intra slice scheduling.""" 81 | def __init__(self,ba,n,debMd,sLod,ttiByms,mmd_,ly_,dir,Smb,robustMCS,slcLbl,sch): 82 | IntraSliceScheduler.__init__(self,ba,n,debMd,sLod,ttiByms,mmd_,ly_,dir,Smb,robustMCS,slcLbl,sch) 83 | self.symMax = Smb 84 | self.queue = TBqueueTDD(self.symMax) 85 | """TDD scheduler TB queue. 86 | 87 | IntraSliceScheduler class attribute queue is overwriten here by a new type of queue 88 | which handles symbols. This queue will contain as much TB as a slot can contain. If resource allocation is made 89 | in terms of slots, it will contain 1 element, else, it will contain as much mini-slots as can be supported in 1 slot.""" 90 | 91 | def resAlloc(self,band): 92 | """This method implements resource allocation between the different connected UEs in a TDD slice. 93 | 94 | It overwrites the resAlloc method from IntraSliceScheduler class. 95 | In this Py5cheSim version TDD scheduler allocates all PRBs in the slice to a UE during 1 slot. 96 | Future Py5cheSim versions could support mini-slot allocation by changing the UE symbol allocation in this method. 97 | Note that in that case, althoug there is no need to update the queueUpdate method, 98 | TBS calculation must be adjusted to avoid losing capacity when trunking the Nre__ value.""" 99 | 100 | if len(list(self.ues.keys()))>0: 101 | for ue in list(self.ues.keys()): 102 | self.ues[ue].prbs = band 103 | self.ues[ue].symb = self.TDDsmb 104 | # Print Resource Allocation 105 | self.printResAlloc() 106 | 107 | def queueUpdate(self): 108 | """This method fills scheduler TB queue at each TTI with TBs built with UE data/signalling bytes. 109 | 110 | It overwrites queueUpdate method from IntraSliceScheduler class, making Resource allocation in terms of slot Symbols 111 | and insert generated TBs into Scheduler queue in a TTI. Althoug in this version Resource allocation is made by slot, 112 | it is prepared to support mini-slot resource allocation by handling a scheduler TB queue in terms of symbols.""" 113 | packts = 1 114 | self.ueLst = list(self.ues.keys()) 115 | self.resAlloc(self.nrbUEmax) 116 | sym = 0 117 | if self.nrbUEmax == 0: 118 | self.sm_lim = 0 119 | else: 120 | if self.mimomd == 'MU': 121 | self.sm_lim = self.symMax*self.nlayers 122 | else: 123 | self.sm_lim = self.symMax 124 | 125 | while len(self.ueLst)>0 and packts>0 and sym < self.sm_lim: 126 | ue = self.ueLst[self.ind_u] 127 | self.printDebDataDM('---------------- '+ue+' ------------------
') # print more info in debbug mode 128 | if self.ues[ue].symb>0: 129 | if len(self.ues[ue].bearers)>0 and sym < self.sm_lim: 130 | if len(self.ues[ue].pendingTB)==0: # No TB to reTX 131 | sym = sym + self.rrcUncstSigIn(ue) 132 | if sym < self.sm_lim and len(self.ues[ue].bearers[0].buffer.pckts)>0: 133 | sym = sym + self.dataPtoTB(ue) 134 | else: # There are TB to reTX 135 | self.printPendTB() 136 | sym = sym + self.retransmitTB(ue) 137 | if self.dbMd: 138 | self.printQtb() # Print TB queue in debbug mode 139 | self.updIndUE() 140 | packts = self.updSumPcks() 141 | 142 | def rrcUncstSigIn(self,u): 143 | ueN = int(self.ues[u].id[2:]) 144 | sfSig = int(float(1)/self.sLoad) 145 | rrcUESigCond = (self.sbFrNum-ueN)%sfSig == 0 146 | if rrcUESigCond: 147 | p_l = [] 148 | p_l.append(self.ues[u].packetFlows[0].pId) 149 | self.ues[u].packetFlows[0].pId = self.ues[u].packetFlows[0].pId + 1 150 | ins = self.insertTB(self.ues[u].TBid,'4-QAM',u,'Sig',p_l,self.ues[u].prbs,19) 151 | r = self.symMax 152 | else: 153 | r = 0 154 | return r 155 | 156 | def retransmitTB(self,u): 157 | pendingTbl = self.ues[u].pendingTB[0] 158 | if pendingTbl.reTxNum < 3000: # TB retransmission 159 | intd = self.queue.insertTB(pendingTbl) 160 | self.ues[u].pendingTB.pop(0) 161 | pendingTbl.reTxNum = pendingTbl.reTxNum + 1 162 | r = self.symMax 163 | else: 164 | self.ues[u].pendingTB.pop(0) # Drop!!! 165 | r = 0 166 | return r 167 | 168 | def dataPtoTB(self,u): 169 | """This method takes UE data bytes, builds TB and puts them in the scheduler TB queue. 170 | 171 | It overwrites dataPtoTB method from IntraSliceScheduler class. In this case it returns 172 | the amount of allocated symbols to the UE.""" 173 | n = self.ues[u].prbs 174 | [tbSbits,mod,bits,mcs__] = self.setMod(u,n) 175 | if self.schType[0:2]=='PF': 176 | if len(self.ues[u].pastTbsz)>self.promLen: 177 | self.ues[u].pastTbsz.popleft() 178 | self.ues[u].pastTbsz.append(self.ues[u].tbsz) 179 | 180 | self.ues[u].tbsz = tbSbits 181 | self.ues[u].MCS = mcs__ 182 | self.setBLER(u) 183 | tbSize = int(float(tbSbits)/8) # TB size in bytes 184 | self.printDebDataDM('TBs: '+str(tbSize)+' nrb: '+str(n)+' FreeSp: '+str(self.queue.getFreeSpace())+'
') 185 | pks_s = 0 186 | list_p = [] 187 | while pks_s0: 188 | pacD = self.ues[u].bearers[0].buffer.removePckt() 189 | pks_s = pks_s + pacD.size 190 | list_p.append(pacD.secNum) 191 | 192 | insrt = self.insertTB(self.ues[u].TBid,mod,u,'data',list_p,n,min(int(pks_s),tbSize)) 193 | if (pks_s - tbSize)>0: 194 | pacD.size = pks_s - tbSize 195 | self.ues[u].bearers[0].buffer.insertPcktLeft(pacD) 196 | return self.ues[u].symb 197 | 198 | def setTBS(self,r,qm,uldl,u_,fr,nprb): # TS 38.214 procedure 199 | OHtable = {'DL':{'FR1':0.14,'FR2':0.18},'UL':{'FR1':0.08,'FR2':0.10}} 200 | OH = OHtable[uldl][fr] 201 | Nre__ = min(156,math.floor(12*self.ues[u_].symb*(1-OH))) 202 | if self.mimomd == 'SU': 203 | Ninfo = Nre__*nprb*r*qm*self.nlayers 204 | tbs = Ninfo 205 | else: 206 | Ninfo = Nre__*nprb*r*qm 207 | tbs = Ninfo 208 | return tbs 209 | 210 | def printResAlloc(self): 211 | if self.dbMd: 212 | self.printDebData('+++++++++++ Res Alloc +++++++++++++'+'
') 213 | self.printDebData('PRBs: '+str(self.nrbUEmax)+'
') 214 | resAllocMsg = '' 215 | for ue in list(self.ues.keys()): 216 | resAllocMsg = resAllocMsg + ue +': '+ str(self.ues[ue].symb)+' symbols'+'
' 217 | self.printDebData(resAllocMsg) 218 | self.printDebData('+++++++++++++++++++++++++++++++++++'+'
') 219 | 220 | class TBqueueTDD: # TB queue!!! 221 | """This class is used to model scheduler TB queue in TDD scheduler.""" 222 | def __init__(self,symb): 223 | self.res = deque([]) 224 | self.numRes = symb 225 | 226 | def getFreeSpace(self): 227 | freeSpace = self.numRes 228 | if len(self.res)>0: 229 | for tbl in self.res: 230 | freeSpace = freeSpace - 1 231 | return freeSpace 232 | 233 | def insertTB(self,tb): 234 | succ = False 235 | freeSpace = self.getFreeSpace() 236 | if freeSpace>=1: 237 | self.res.append(tb) # The TB fits the free space 238 | succ = True 239 | else: 240 | succ = False 241 | print (Format.CRED+'Not enough space!!! : '+str(freeSpace)+'/'+str(tb.numRB)+Format.CEND) 242 | return succ 243 | 244 | def removeTB(self): 245 | if len(self.res)>0: 246 | return self.res.popleft() 247 | 248 | def updateSize(self,newSize): 249 | self.numRes = newSize 250 | -------------------------------------------------------------------------------- /Slice.py: -------------------------------------------------------------------------------- 1 | """This module contains the Slice class. 2 | """ 3 | from IntraSliceSch import IntraSliceScheduler, LTE_scheduler 4 | from Scheds_Intra import * 5 | from collections import deque 6 | 7 | class Slice: 8 | """This class has Slice relative parameters and is used to implement the mapping between service requirements and slice configuration.""" 9 | def __init__(self,dly,thDL,thUL,avl,cnxDL,cnxUL,ba,dm,mmd,ly,lbl,tdd,sch): 10 | self.reqDelay = dly 11 | self.reqThroughputDL = thDL 12 | self.reqThroughputUL = thUL 13 | self.reqAvailability = avl 14 | self.reqDLconnections = cnxDL 15 | self.reqULconnections = cnxUL 16 | 17 | self.band = ba 18 | self.PRBs = 0 19 | self.signLoad = 0.000001 20 | self.scs = '15kHz' 21 | self.ttiBms = 1 22 | self.robustMCS = False 23 | self.mimoMd = mmd 24 | self.layers = ly 25 | self.tddSymb = 14 26 | self.schType = sch 27 | self.label = lbl 28 | self.tdd = tdd 29 | self.dm = dm 30 | self.rcvdBytes = deque([0]) # interSlice PF scheduler 31 | self.metric = 0 # interSlice PF scheduler 32 | self.setInitialConfig() 33 | self.schedulerDL = self.createSliceSched('DL',self.tddSymb) 34 | if self.label != 'LTE': 35 | self.schedulerUL = self.createSliceSched('UL',14-self.tddSymb) 36 | 37 | def createSliceSched(self,dir,tddSymb): 38 | """This method initializes and returns slice UL or DL scheduler. Scheduler algorithm is selected according to the Slice attribute schType.""" 39 | if self.tdd: 40 | if self.schType[0:2] == 'PF': 41 | scheduler = PF_Scheduler(self.band,self.PRBs,self.dm,self.signLoad,self.ttiBms,self.mimoMd,self.layers,dir,tddSymb,self.robustMCS,self.label,self.schType) 42 | else: 43 | scheduler = TDD_Scheduler(self.band,self.PRBs,self.dm,self.signLoad,self.ttiBms,self.mimoMd,self.layers,dir,tddSymb,self.robustMCS,self.label,self.schType) 44 | else: # FDD Schedulers 45 | if self.label == 'LTE': 46 | scheduler = LTE_scheduler(self.band,self.PRBs,self.dm,self.signLoad,self.mimoMd,self.layers,dir) 47 | elif self.schType[0:2] == 'PF': 48 | scheduler = PF_Scheduler(self.band,self.PRBs,self.dm,self.signLoad,self.ttiBms,self.mimoMd,self.layers,dir,14,self.robustMCS,self.label,self.schType) 49 | else: # RR Scheduler by default 50 | scheduler = IntraSliceScheduler(self.band,self.PRBs,self.dm,self.signLoad,self.ttiBms,self.mimoMd,self.layers,dir,14,self.robustMCS,self.label,self.schType) 51 | 52 | return scheduler 53 | 54 | def setInitialConfig(self): 55 | """This method sets initial Slice configuration according to service requirements.""" 56 | self.dly2scs(self.reqDelay) 57 | if self.band == 'n257' or self.band == 'n258' or self.band == 'n260' or self.band == 'n261': 58 | self.tdd = True 59 | numReftable = {'60kHz':1,'120kHz':2} 60 | self.numRefFactor = numReftable[self.scs] 61 | if self.reqDLconnections > 0 and self.reqULconnections == 0: 62 | self.tddSymb = 14 63 | if self.reqULconnections > 0 and self.reqDLconnections == 0: 64 | self.tddSymb = 0 65 | if self.reqULconnections > 0 and self.reqDLconnections > 0: 66 | DLfactor = float(self.reqDLconnections*self.reqThroughputDL)/(self.reqDLconnections*self.reqThroughputDL+self.reqULconnections*self.reqThroughputUL) 67 | self.tddSymb = int(14*DLfactor) 68 | # print(DLfactor,self.tddSymb) 69 | else: 70 | #self.tdd = False 71 | self.numRefFactor = self.ttiBms 72 | 73 | if self.reqAvailability == 'High': 74 | self.robustMCS = True 75 | 76 | if 'mMTC' in self.label: 77 | self.signLoad = 0.003 78 | 79 | def dly2scs(self,delay): 80 | """This method sets Slice numerology depending on delay requirements.""" 81 | if self.band == 'n257' or self.band == 'n258' or self.band == 'n260' or self.band == 'n261': #FR2 82 | if delay<=2.5: 83 | self.scs = '120kHz' 84 | self.ttiBms = 8 85 | else: 86 | self.scs = '60kHz' 87 | self.ttiBms = 4 88 | else: # FR1 89 | if delay<=5: 90 | self.scs = '60kHz' 91 | self.ttiBms = 4 92 | elif delay<=10: 93 | self.scs = '30kHz' 94 | self.ttiBms = 2 95 | else: 96 | self.scs = '15kHz' 97 | self.ttiBms = 1 98 | 99 | def updateConfig(self,n): 100 | """This method updates Slice allocated PRBs.""" 101 | self.PRBs = n 102 | self.schedulerDL.nrbUEmax = self.PRBs 103 | if self.label != 'LTE': 104 | self.schedulerUL.nrbUEmax = self.PRBs 105 | if self.mimoMd == 'MU': 106 | self.schedulerDL.queue.updateSize(self.PRBs*self.layers) 107 | if self.label != 'LTE': 108 | self.schedulerUL.queue.updateSize(self.PRBs*self.layers) 109 | else: 110 | self.schedulerDL.queue.updateSize(self.PRBs) 111 | if self.label != 'LTE': 112 | self.schedulerUL.queue.updateSize(self.PRBs) 113 | -------------------------------------------------------------------------------- /UE.py: -------------------------------------------------------------------------------- 1 | """ This module contains the UE, Packet Flow, Packet, PcktQueue, Bearer and RadioLink clases. 2 | This clases are oriented to describe UE traffic profile, and UE relative concepts 3 | """ 4 | import os 5 | import sys 6 | import random 7 | import simpy 8 | from collections import deque 9 | 10 | # UE class: terminal description 11 | 12 | class UE(): 13 | """ This class is used to model UE behabiour and relative properties """ 14 | def __init__(self, i,ue_sinr0,p,npM): 15 | self.id = i 16 | self.state = 'RRC-IDLE' 17 | self.packetFlows = [] 18 | self.bearers = [] 19 | self.radioLinks = RadioLink(1,ue_sinr0,self.id) 20 | self.TBid = 1 21 | self.pendingPckts = {} 22 | self.prbs = p 23 | self.resUse = 0 24 | self.pendingTB = [] 25 | self.bler = 0 26 | self.tbsz = 1 27 | self.MCS = 0 28 | self.pfFactor = 1 # PF Scheduler 29 | self.pastTbsz = deque([1]) # PF Scheduler 30 | self.lastDen = 0.001 # PF Scheduler 31 | self.num = 0 # PF Scheduler 32 | self.BWPs = npM 33 | self.TXedTB = 1 34 | self.lostTB = 0 35 | self.symb = 0 36 | 37 | def addPacketFlow(self,pckFl): 38 | self.packetFlows.append(pckFl) 39 | 40 | def addBearer(self,br): 41 | self.bearers.append(br) 42 | 43 | def receivePckt(self,env,c): # PEM ------------------------------------------- 44 | """This method takes packets on the application buffers and leave them on the bearer buffers. This is a PEM method.""" 45 | while True: 46 | if len(self.packetFlows[0].appBuff.pckts)>0: 47 | if self.state == 'RRC-IDLE': # Not connected 48 | self.connect(c) 49 | nextPackTime = c.tUdQueue 50 | yield env.timeout(nextPackTime) 51 | if nextPackTime > c.inactTimer: 52 | self.releaseConnection(c) 53 | else: # Already connecter user 54 | self.queueDataPckt(c) 55 | nextPackTime = c.tUdQueue 56 | yield env.timeout(nextPackTime) 57 | if nextPackTime > c.inactTimer: 58 | self.releaseConnection(c) 59 | else: 60 | nextPackTime = c.tUdQueue 61 | yield env.timeout(nextPackTime) 62 | 63 | def connect(self,cl): 64 | """This method creates bearers and bearers buffers.""" 65 | bD = Bearer(1,9,self.packetFlows[0].type) 66 | self.addBearer(bD) 67 | self.queueDataPckt(cl) 68 | if self.packetFlows[0].type == 'DL': 69 | if (list(cl.interSliceSched.slices[self.packetFlows[0].sliceName].schedulerDL.ues.keys()).count(self.id))<1: 70 | cl.interSliceSched.slices[self.packetFlows[0].sliceName].schedulerDL.ues[self.id] = self 71 | else: 72 | if (list(cl.interSliceSched.slices[self.packetFlows[0].sliceName].schedulerUL.ues.keys()).count(self.id))<1: 73 | cl.interSliceSched.slices[self.packetFlows[0].sliceName].schedulerUL.ues[self.id] = self 74 | self.state = 'RRC-CONNECTED' 75 | 76 | 77 | def queueDataPckt(self,cell): 78 | """This method queues the packets taken from the application buffer in the bearer buffers.""" 79 | pD = self.packetFlows[0].appBuff.removePckt() 80 | buffSizeAllUEs = 0 81 | buffSizeThisUE = 0 82 | if self.packetFlows[0].type == 'DL': 83 | for ue in list(cell.interSliceSched.slices[self.packetFlows[0].sliceName].schedulerDL.ues.keys()): 84 | buffSizeUE = 0 85 | for p in cell.interSliceSched.slices[self.packetFlows[0].sliceName].schedulerDL.ues[ue].bearers[0].buffer.pckts: 86 | buffSizeUE = buffSizeUE + p.size 87 | if self.id == ue: 88 | buffSizeThisUE = buffSizeUE 89 | buffSizeAllUEs = buffSizeAllUEs + buffSizeUE 90 | else: 91 | for ue in list(cell.interSliceSched.slices[self.packetFlows[0].sliceName].schedulerUL.ues.keys()): 92 | buffSizeUE = 0 93 | for p in cell.interSliceSched.slices[self.packetFlows[0].sliceName].schedulerUL.ues[ue].bearers[0].buffer.pckts: 94 | buffSizeUE = buffSizeUE + p.size 95 | if self.id == ue: 96 | buffSizeThisUE = buffSizeUE 97 | buffSizeAllUEs = buffSizeAllUEs + buffSizeUE 98 | 99 | if buffSizeThisUE'+str(self.id)+' packet '+str(pcktN)+' lost .....'+str(pD.tIn)+'

') 106 | else: 107 | cell.interSliceSched.slices[self.packetFlows[0].sliceName].schedulerUL.printDebDataDM('

'+str(self.id)+' packet '+str(pcktN)+' lost .....'+str(pD.tIn)+'

') 108 | self.packetFlows[0].lostPackets = self.packetFlows[0].lostPackets + 1 109 | 110 | def releaseConnection(self,cl): 111 | self.state = 'RRC-IDLE' 112 | self.bearers = [] 113 | 114 | # ------------------------------------------------ 115 | # PacketFlow class: PacketFlow description 116 | class PacketFlow(): 117 | """ This class is used to describe UE traffic profile for the simulation.""" 118 | def __init__(self,i,pckSize,pckArrRate,u,tp,slc): 119 | self.id = i 120 | self.tMed = 0 121 | self.sMed = 0 122 | self.type = tp 123 | self.sliceName = slc 124 | self.pckArrivalRate = pckArrRate 125 | self.qosFlowId = 0 126 | self.packetSize = pckSize 127 | self.ue = u 128 | self.sMax = (float(self.packetSize)/350)*600 129 | self.tMax = (float(self.pckArrivalRate)/6)*12.5 130 | self.tStart = 0 131 | self.appBuff = PcktQueue() 132 | self.lostPackets = 0 133 | self.sentPackets = 0 134 | self.rcvdBytes = 0 135 | self.pId = 1 136 | self.header = 30 137 | self.meassuredKPI = {'Throughput':0,'Delay':0,'PacketLossRate':0} 138 | 139 | 140 | def setQosFId(self,q): 141 | qosFlowId = q 142 | 143 | def queueAppPckt(self,env,tSim): # --- PEM ----- 144 | """This method creates packets according to the packet flow traffic profile and stores them in the application buffer. """ 145 | ueN = int(self.ue[2:]) # number of UEs in simulation 146 | self.tStart = (random.expovariate(1.0)) 147 | yield env.timeout(self.tStart) # each UE start transmission after tStart 148 | while env.now<(tSim*0.83): 149 | self.sentPackets = self.sentPackets + 1 150 | size = self.getPsize() 151 | pD = Packet(self.pId,size+self.header,self.qosFlowId,self.ue) 152 | self.pId = self.pId + 1 153 | pD.tIn = env.now 154 | self.appBuff.insertPckt(pD) 155 | nextPackTime = self.getParrRate() 156 | yield env.timeout(nextPackTime) 157 | 158 | def getPsize(self): 159 | pSize = random.paretovariate(1.2)*(self.packetSize*(0.2/1.2)) 160 | while pSize > self.sMax: 161 | pSize = random.paretovariate(1.2)*(self.packetSize*(0.2/1.2)) 162 | self.sMed = self.sMed + pSize 163 | return pSize 164 | 165 | def getParrRate(self): 166 | pArrRate = random.paretovariate(1.2)*(self.pckArrivalRate*(0.2/1.2)) 167 | while pArrRate > self.tMax: 168 | pArrRate = random.paretovariate(1.2)*(self.pckArrivalRate*(0.2/1.2)) 169 | self.tMed = self.tMed + pArrRate 170 | return pArrRate 171 | 172 | def setMeassures(self,tsim): 173 | """This method calculates average PLR and throughput for the simulation.""" 174 | self.meassuredKPI['PacketLossRate'] = float(100*self.lostPackets)/self.sentPackets 175 | if tsim>1000: 176 | self.meassuredKPI['Throughput'] = (float(self.rcvdBytes)*8000)/(0.83*tsim*1024*1024) 177 | else: 178 | self.meassuredKPI['Throughput'] = 0 179 | 180 | class Packet: 181 | """This class is used to model packets properties and behabiour.""" 182 | def __init__(self,sn,s,qfi,u): 183 | self.secNum = sn 184 | self.size = s 185 | self.qosFlowId = qfi 186 | self.ue = u 187 | self.tIn = 0 188 | 189 | def printPacket(self): 190 | print (Format.CYELLOW + Format.CBOLD + self.ue+ '+packet '+str(self.secNum)+' arrives at t ='+str(now()) + Format.CEND) 191 | 192 | class Bearer: 193 | """This class is used to model Bearers properties and behabiour.""" 194 | def __init__(self,i,q,tp): 195 | self.id = i 196 | self.qci = q 197 | self.type = tp 198 | self.buffer = PcktQueue() 199 | 200 | class PcktQueue: 201 | """This class is used to model application and bearer buffers.""" 202 | def __init__(self): 203 | self.pckts = deque([]) 204 | 205 | def insertPckt(self,p): 206 | self.pckts.append(p) 207 | 208 | def insertPcktLeft(self,p): 209 | self.pckts.appendleft(p) 210 | 211 | def removePckt(self): 212 | if len(self.pckts)>0: 213 | return self.pckts.popleft() 214 | 215 | class RadioLink(): 216 | """This class is used to model radio link properties and behabiour.""" 217 | def __init__(self,i,lq_0,u): 218 | self.id = i 219 | state = 'ON' 220 | self.linkQuality = lq_0 221 | self.ue = u 222 | self.totCount = 0 223 | self.maxVar = 0.1 224 | 225 | def updateLQ(self,env,udIntrv,tSim,fl,u,r): 226 | """This method updates UE link quality in terms of SINR during the simulation. This is a PEM method. 227 | 228 | During the simulation it is assumed that UE SINR varies following a normal distribution with mean value equal to initial SINR value, and a small variance.""" 229 | 230 | while env.now<(tSim*0.83): 231 | yield env.timeout(udIntrv) 232 | deltaSINR = random.normalvariate(0, self.maxVar) 233 | while deltaSINR > self.maxVar or deltaSINR<(0-self.maxVar): 234 | deltaSINR = random.normalvariate(0, self.maxVar) 235 | self.linkQuality = self.linkQuality + deltaSINR 236 | 237 | class Format: 238 | CEND = '\33[0m' 239 | CBOLD = '\33[1m' 240 | CITALIC = '\33[3m' 241 | CURL = '\33[4m' 242 | CBLINK = '\33[5m' 243 | CBLINK2 = '\33[6m' 244 | CSELECTED = '\33[7m' 245 | CBLACK = '\33[30m' 246 | CRED = '\33[31m' 247 | CGREEN = '\33[32m' 248 | CYELLOW = '\33[33m' 249 | CBLUE = '\33[34m' 250 | CVIOLET = '\33[35m' 251 | CBEIGE = '\33[36m' 252 | CWHITE = '\33[37m' 253 | CGREENBG = '\33[42m' 254 | CBLUEBG = '\33[44m' 255 | -------------------------------------------------------------------------------- /doc/Py5cheSim.Cell.Cell.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | Py5cheSim.Cell.Cell : API documentation 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 22 | 23 |
24 | 25 | 31 | 32 |
33 | class documentation 34 |
35 | 36 |
37 |

class Cell:

38 |

View In Hierarchy

39 |
40 | 41 |
42 |

Cell class has cell relative parameters and collect kpi ststistics.

43 |
44 | 45 |
46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 |
Method__init__This method creates a cell instance.
Instance VariableidUndocumented
Instance VariablebwUndocumented
Instance VariableinactTimerUndocumented
Instance VariabletUdQueueUndocumented
Instance VariablemaxBuffUEMaximum bearer buffer size by UE, in bytes
Instance VariableschUndocumented
Instance VariableinterSliceSchedUndocumented
Instance VariableslicesStstsUndocumented
MethodupdateStstsThis method manages the statistics collection. This is a PEM Method.
100 | 101 | 102 | 103 |
104 | 105 |
106 | 107 |
108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 |
116 | 117 | def __init__(self, i, b, fr, dm, mBue, tdd, gr, schInter): 118 | 119 |
120 |
121 | 122 | 123 |

This method creates a cell instance.

It initialices cell parameters and interSliceScheduler according to the algorithm specified on the sch attribute.

124 |
125 |
126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 |
134 | 135 | id = 136 | 137 |
138 |
139 | 140 | 141 |

Undocumented

142 |
143 |
144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 |
152 | 153 | bw = 154 | 155 |
156 |
157 | 158 | 159 |

Undocumented

160 |
161 |
162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 |
170 | 171 | inactTimer = 172 | 173 |
174 |
175 | 176 | 177 |

Undocumented

(type: int) 178 |
179 |
180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 |
188 | 189 | tUdQueue = 190 | 191 |
192 |
193 | 194 | 195 |

Undocumented

(type: float) 196 |
197 |
198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 |
206 | 207 | maxBuffUE = 208 | 209 |
210 |
211 | 212 | 213 |

Maximum bearer buffer size by UE, in bytes

214 |
215 |
216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 |
224 | 225 | sch = 226 | 227 |
228 |
229 | 230 | 231 |

Undocumented

(type: str) 232 |
233 |
234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 |
242 | 243 | interSliceSched = 244 | 245 |
246 |
247 | 248 | 249 |

Undocumented

250 |
251 |
252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 |
260 | 261 | slicesStsts = 262 | 263 |
264 |
265 | 266 | 267 |

Undocumented

(type: dict) 268 |
269 |
270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 |
278 | 279 | def updateStsts(self, env, interv, tSim): 280 | 281 |
282 |
283 | 284 | 285 |

This method manages the statistics collection. This is a PEM Method.

This method creates statistics files and stores counter values to calculate later the main kpi considered.

Inter Slice statistics are stored in the dlStsts_InterSlice.txt file for DL and ulStsts_InterSlice.txt file for UL.

Intra Slice statistics are stored in the dlStsts_<Slicename>Slice.txt file for DL and ulStsts_<Slicename>Slice.txt file for UL.

286 |
287 |
288 | 289 |
290 |
291 | API Documentation for Py5cheSim, generated by pydoctor 21.2.2 at 2021-09-05 13:11:47. 292 |
293 | 294 |
295 | 296 | 297 | 298 | 299 | -------------------------------------------------------------------------------- /doc/Py5cheSim.Cell.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | Py5cheSim.Cell : API documentation 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 22 | 23 |
24 | 25 | 31 | 32 |
33 | module documentation 34 |
35 | 36 |
37 | 38 |

39 |
40 | 41 |
42 |

This module contains the Cell class.

43 |
44 | 45 |
46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 |
ClassCellCell class has cell relative parameters and collect kpi ststistics.
55 | 56 | 57 | 58 |
59 | 60 |
61 | 62 | 63 | 64 |
65 |
66 | API Documentation for Py5cheSim, generated by pydoctor 21.2.2 at 2021-09-05 13:11:47. 67 |
68 | 69 |
70 | 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /doc/Py5cheSim.InterSliceSch.InterSliceScheduler.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | Py5cheSim.InterSliceSch.InterSliceScheduler : API documentation 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 22 | 23 |
24 | 25 | 31 | 32 |
33 | class documentation 34 |
35 | 36 |
37 |

class InterSliceScheduler:

38 |

View In Hierarchy

39 |
40 | 41 |
42 |

Basic inter slice scheduler. It implements Round Robin algorithm.

43 |
44 | 45 |
46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 |
Method__init__Undocumented
Instance VariablebwUndocumented
Instance VariableFRUndocumented
Instance VariablenRBtableUndocumented
Instance VariablePRBsUndocumented
Instance VariableslicesUndocumented
Instance VariabledmUndocumented
Instance VariabledbFileUndocumented
Instance VariabletddUndocumented
Instance VariablegranularityUndocumented
MethodresAllocThis method implements Round Robin PRB allocation between the different configured slices. This is a PEM method
MethodcreateSliceThis method creates a slice and stores it in the slices dictionary.
MethodprintSliceConfigThis method stores inter slice scheduling debugging information on the log file.
115 | 116 | 117 | 118 |
119 | 120 |
121 | 122 |
123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 |
131 | 132 | def __init__(self, ba, fr, dm, tdd, gr): 133 | 134 |
135 |
136 | 137 | 138 |

Undocumented

139 |
140 |
141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 |
149 | 150 | bw = 151 | 152 |
153 |
154 | 155 | 156 |

Undocumented

157 |
158 |
159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 |
167 | 168 | FR = 169 | 170 |
171 |
172 | 173 | 174 |

Undocumented

175 |
176 |
177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 |
185 | 186 | nRBtable = 187 | 188 |
189 |
190 | 191 | 192 |

Undocumented

(type: dict[str, dict]) 193 |
194 |
195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 |
203 | 204 | PRBs = 205 | 206 |
207 |
208 | 209 | 210 |

Undocumented

211 |
212 |
213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 |
221 | 222 | slices = 223 | 224 |
225 |
226 | 227 | 228 |

Undocumented

(type: dict) 229 |
230 |
231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 |
239 | 240 | dm = 241 | 242 |
243 |
244 | 245 | 246 |

Undocumented

247 |
248 |
249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 |
257 | 258 | dbFile = 259 | 260 |
261 |
262 | 263 | 264 |

Undocumented

265 |
266 |
267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 |
275 | 276 | tdd = 277 | 278 |
279 |
280 | 281 | 282 |

Undocumented

283 |
284 |
285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 |
293 | 294 | granularity = 295 | 296 |
297 |
298 | 299 | 300 |

Undocumented

301 |
302 |
303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 |
311 | 312 | def resAlloc(self, env): 313 | 314 |
315 |
316 | 317 | 318 |

This method implements Round Robin PRB allocation between the different configured slices. This is a PEM method

319 |
320 |
321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 |
329 | 330 | def createSlice(self, dly, thDL, thUL, avl, cnxDL, cnxUL, ba, dm, mmd, ly, lbl, sch): 331 | 332 |
333 |
334 | 335 | 336 |

This method creates a slice and stores it in the slices dictionary.

337 |
338 |
339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 |
347 | 348 | def printSliceConfig(self, slice): 349 | 350 |
351 |
352 | 353 | 354 |

This method stores inter slice scheduling debugging information on the log file.

355 |
356 |
357 | 358 |
359 |
360 | API Documentation for Py5cheSim, generated by pydoctor 21.2.2 at 2021-09-05 13:11:47. 361 |
362 | 363 |
364 | 365 | 366 | 367 | 368 | -------------------------------------------------------------------------------- /doc/Py5cheSim.InterSliceSch.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | Py5cheSim.InterSliceSch : API documentation 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 22 | 23 |
24 | 25 | 31 | 32 |
33 | module documentation 34 |
35 | 36 |
37 | 38 |

39 |
40 | 41 |
42 |

This module contains the basic Inter Slice Scheduler class. All possible inter slice schedulers should inherit from this.

43 |
44 | 45 |
46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 |
ClassInterSliceSchedulerBasic inter slice scheduler. It implements Round Robin algorithm.
55 | 56 | 57 | 58 |
59 | 60 |
61 | 62 | 63 | 64 |
65 |
66 | API Documentation for Py5cheSim, generated by pydoctor 21.2.2 at 2021-09-05 13:11:47. 67 |
68 | 69 |
70 | 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /doc/Py5cheSim.IntraSliceSch.TBqueue.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | Py5cheSim.IntraSliceSch.TBqueue : API documentation 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 22 | 23 |
24 | 25 | 31 | 32 |
33 | class documentation 34 |
35 | 36 |
37 |

class TBqueue:

38 |

View In Hierarchy

39 |
40 | 41 |
42 |

This class is used to model scheduler TB queue.

43 |
44 | 45 |
46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 |
Method__init__Undocumented
Instance VariableresUndocumented
Instance VariablenumRBUndocumented
MethodgetFreeSpaceUndocumented
MethodinsertTBUndocumented
MethodremoveTBUndocumented
MethodupdateSizeUndocumented
85 | 86 | 87 | 88 |
89 | 90 |
91 | 92 |
93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 |
101 | 102 | def __init__(self, nrb): 103 | 104 |
105 |
106 | 107 | 108 |

Undocumented

109 |
110 |
111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 |
119 | 120 | res = 121 | 122 |
123 |
124 | 125 | 126 |

Undocumented

127 |
128 |
129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 |
137 | 138 | numRB = 139 | 140 |
141 |
142 | 143 | 144 |

Undocumented

145 |
146 |
147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 |
155 | 156 | def getFreeSpace(self): 157 | 158 |
159 |
160 | 161 | 162 |

Undocumented

163 |
164 |
165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 |
173 | 174 | def insertTB(self, tb): 175 | 176 |
177 |
178 | 179 | 180 |

Undocumented

181 |
182 |
183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 |
191 | 192 | def removeTB(self): 193 | 194 |
195 |
196 | 197 | 198 |

Undocumented

199 |
200 |
201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 |
209 | 210 | def updateSize(self, newSize): 211 | 212 |
213 |
214 | 215 | 216 |

Undocumented

217 |
218 |
219 | 220 |
221 |
222 | API Documentation for Py5cheSim, generated by pydoctor 21.2.2 at 2021-09-05 13:11:47. 223 |
224 | 225 |
226 | 227 | 228 | 229 | 230 | -------------------------------------------------------------------------------- /doc/Py5cheSim.IntraSliceSch.TransportBlock.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | Py5cheSim.IntraSliceSch.TransportBlock : API documentation 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 22 | 23 |
24 | 25 | 31 | 32 |
33 | class documentation 34 |
35 | 36 |
37 |

class TransportBlock:

38 |

View In Hierarchy

39 |
40 | 41 |
42 |

This class is used to describe TB properties and behabiour.

43 |
44 | 45 |
46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 |
Method__init__Undocumented
Instance VariableidUndocumented
Instance VariablemodUndocumented
Instance VariableueUndocumented
Instance VariabletypeUndocumented
Instance Variablepckt_lUndocumented
Instance VariablenumRBUndocumented
Instance VariablereTxNumUndocumented
Instance VariablesizeUndocumented
95 | 96 | 97 | 98 |
99 | 100 |
101 | 102 |
103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 |
111 | 112 | def __init__(self, i, m, u, typ, p_l, nrb, sz): 113 | 114 |
115 |
116 | 117 | 118 |

Undocumented

119 |
120 |
121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 |
129 | 130 | id = 131 | 132 |
133 |
134 | 135 | 136 |

Undocumented

137 |
138 |
139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 |
147 | 148 | mod = 149 | 150 |
151 |
152 | 153 | 154 |

Undocumented

155 |
156 |
157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 |
165 | 166 | ue = 167 | 168 |
169 |
170 | 171 | 172 |

Undocumented

173 |
174 |
175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 |
183 | 184 | type = 185 | 186 |
187 |
188 | 189 | 190 |

Undocumented

191 |
192 |
193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 |
201 | 202 | pckt_l = 203 | 204 |
205 |
206 | 207 | 208 |

Undocumented

209 |
210 |
211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 |
219 | 220 | numRB = 221 | 222 |
223 |
224 | 225 | 226 |

Undocumented

227 |
228 |
229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 |
237 | 238 | reTxNum = 239 | 240 |
241 |
242 | 243 | 244 |

Undocumented

(type: int) 245 |
246 |
247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 |
255 | 256 | size = 257 | 258 |
259 |
260 | 261 | 262 |

Undocumented

263 |
264 |
265 | 266 |
267 |
268 | API Documentation for Py5cheSim, generated by pydoctor 21.2.2 at 2021-09-05 13:11:47. 269 |
270 | 271 |
272 | 273 | 274 | 275 | 276 | -------------------------------------------------------------------------------- /doc/Py5cheSim.IntraSliceSch.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | Py5cheSim.IntraSliceSch : API documentation 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 22 | 23 |
24 | 25 | 31 | 32 |
33 | module documentation 34 |
35 | 36 |
37 | 38 |

39 |
40 | 41 |
42 |

This module contains the basic Intra Slice Scheduler class. All possible intra slice schedulers should inherit from this.

43 |
44 | 45 |
46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 |
ClassIntraSliceSchedulerBasic intra slice scheduler. It implements Round Robin algorithm.
ClassLTE_schedulerBasic intra slice LTE scheduler. It implements Round Robin algorithm for scheduling in a LTE Slice.
ClassTBqueueThis class is used to model scheduler TB queue.
ClassTransportBlockThis class is used to describe TB properties and behabiour.
ClassFormatUndocumented
75 | 76 | 77 | 78 |
79 | 80 |
81 | 82 | 83 | 84 |
85 |
86 | API Documentation for Py5cheSim, generated by pydoctor 21.2.2 at 2021-09-05 13:11:47. 87 |
88 | 89 |
90 | 91 | 92 | 93 | 94 | -------------------------------------------------------------------------------- /doc/Py5cheSim.Results.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | Py5cheSim.Results : API documentation 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 22 | 23 |
24 | 25 | 31 | 32 |
33 | module documentation 34 |
35 | 36 |
37 | 38 |

39 |
40 | 41 |
42 |

This module contains auxiliary simulation classes and methods along with results processing.

43 |
44 | 45 |
46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 |
FunctioninitialSinrGeneratorAuxiliary method for SINR generation. This method is used to generate initial UE SINR. Later, during the simulation SINR will have small variations with time.
ClassUEgroupThis class is used to describe traffic profile and requirements of group of UE which the simulation will run for. It is assumed that all UEs shares the same traffic profile and service requirements, and will be served by the same slice.
FunctionprintResultsThis method prints main simulation results on the terminal
FunctiongetKPIsThis method gets the intra slice kpi from the statistic files
FunctiongetKPIsInterThis method gets the inter Slice kpi from the statistic files
FunctionmakeTimePlotThis method makes basic time plots. Labels deppend on which kpi is being plotted.
FunctionmakeIntraSlicePlotThis method makes and stores any Intra Slice plot
FunctionmakeInterSlicePlotThis method makes and stores any Inter Slice plot
FunctionmakePlotsIntraThis method makes all Intra Slice kpi plots
FunctionmakePlotsInterThis method makes all Inter Slice kpi plots
100 | 101 | 102 | 103 |
104 | 105 |
106 | 107 |
108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 |
116 | 117 | def initialSinrGenerator(n_ues, refValue): 118 | 119 |
120 |
121 | 122 | 123 |

Auxiliary method for SINR generation. This method is used to generate initial UE SINR. Later, during the simulation SINR will have small variations with time.

124 |
125 |
126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 |
134 | 135 | def printResults(dir, users, num_users, scheduler, t_sim, singleRunMode, fileSINR, sinr): 136 | 137 |
138 |
139 | 140 | 141 |

This method prints main simulation results on the terminal

142 |
143 |
144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 |
152 | 153 | def getKPIs(dir, stFile, users, num_users, sinr_0, measInterv, tSim): 154 | 155 |
156 |
157 | 158 | 159 |

This method gets the intra slice kpi from the statistic files

160 |
161 |
162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 |
170 | 171 | def getKPIsInter(dir, stFile, slices, num_slices): 172 | 173 |
174 |
175 | 176 | 177 |

This method gets the inter Slice kpi from the statistic files

178 |
179 |
180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 |
188 | 189 | def makeTimePlot(u, plotName, plotType, xAx, yAx): 190 | 191 |
192 |
193 | 194 | 195 |

This method makes basic time plots. Labels deppend on which kpi is being plotted.

196 |
197 |
198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 |
206 | 207 | def makeIntraSlicePlot(plotName, plotType, xAx, yAx, slcLbl, bw, sch, gran): 208 | 209 |
210 |
211 | 212 | 213 |

This method makes and stores any Intra Slice plot

214 |
215 |
216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 |
224 | 225 | def makeInterSlicePlot(plotName, plotType, xAx, yAx, bw, sch, gran): 226 | 227 |
228 |
229 | 230 | 231 |

This method makes and stores any Inter Slice plot

232 |
233 |
234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 |
242 | 243 | def makePlotsIntra(dir, times, sinr, mcs, rU, plr, th, slcLbl, bw, sch, gr): 244 | 245 |
246 |
247 | 248 | 249 |

This method makes all Intra Slice kpi plots

250 |
251 |
252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 |
260 | 261 | def makePlotsInter(dir, times, res, plr, th, cnx, buf, met, bw, schIn, gr): 262 | 263 |
264 |
265 | 266 | 267 |

This method makes all Inter Slice kpi plots

268 |
269 |
270 | 271 |
272 |
273 | API Documentation for Py5cheSim, generated by pydoctor 21.2.2 at 2021-09-05 13:11:47. 274 |
275 | 276 |
277 | 278 | 279 | 280 | 281 | -------------------------------------------------------------------------------- /doc/Py5cheSim.Scheds_Inter.PF_Scheduler.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | Py5cheSim.Scheds_Inter.PF_Scheduler : API documentation 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 22 | 23 |
24 | 25 | 31 | 32 |
33 | class documentation 34 |
35 | 36 |
37 |

class PF_Scheduler(InterSliceScheduler):

38 |

View In Hierarchy

39 |
40 | 41 |
42 |

This class implements Proportional Fair inter slice scheduling algorithm.

43 |
44 | 45 |
46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 |
Method__init__Undocumented
Instance VariableschString formatted as PFXY, with X=numerator exponent for metric formula, and Y=denominator exponent.
Instance VariablercvdBytesLenrcvdBytes list length in Slice instance. No more that rcvdBytesLen values are stored.
MethodresAllocThis method implements Proportional Fair resource allocation between the different configured slices. This PEM method overwrites the resAlloc method from InterSliceScheduler class.
MethodsetMetricThis method sets the PF metric for each slice
MethodfindMaxMetSliceThis method finds and returns the Slice with the highest metric
Methodassign2aSliceThis method allocates cell's PRBs to the indicated slice
MethodprintSliceConfigThis method stores inter slice scheduling debugging information on the log file, adding PF metric values.
90 | 91 | 92 | 93 |
94 | 95 |
96 | 97 |
98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 |
106 | 107 | def __init__(self, ba, fr, dm, tdd, gr, sch): 108 | 109 |
110 |
111 | 112 | 113 |

Undocumented

114 |
115 |
116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 |
124 | 125 | sch = 126 | 127 |
128 |
129 | 130 | 131 |

String formatted as PFXY, with X=numerator exponent for metric formula, and Y=denominator exponent.

132 |
133 |
134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 |
142 | 143 | rcvdBytesLen = 144 | 145 |
146 |
147 | 148 | 149 |

rcvdBytes list length in Slice instance. No more that rcvdBytesLen values are stored.

(type: int) 150 |
151 |
152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 |
160 | 161 | def resAlloc(self, env): 162 | 163 |
164 |
165 | 166 | 167 |

This method implements Proportional Fair resource allocation between the different configured slices. This PEM method overwrites the resAlloc method from InterSliceScheduler class.

Proportional Fair scheduler allocates all PRBs in the cell to the slice with the biggest metric. Metric for each slice is calculated as PossibleAverageUEtbs/ReceivedBytes.

168 |
169 |
170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 |
178 | 179 | def setMetric(self, exp_n, exp_d): 180 | 181 |
182 |
183 | 184 | 185 |

This method sets the PF metric for each slice

186 |
187 |
188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 |
196 | 197 | def findMaxMetSlice(self): 198 | 199 |
200 |
201 | 202 | 203 |

This method finds and returns the Slice with the highest metric

204 |
205 |
206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 |
214 | 215 | def assign2aSlice(self, slice): 216 | 217 |
218 |
219 | 220 | 221 |

This method allocates cell's PRBs to the indicated slice

222 |
223 |
224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 |
232 | 233 | def printSliceConfig(self, slice): 234 | 235 |
236 |
237 | 238 | 239 |

This method stores inter slice scheduling debugging information on the log file, adding PF metric values.

240 |
241 |
242 | 243 |
244 |
245 | API Documentation for Py5cheSim, generated by pydoctor 21.2.2 at 2021-09-05 13:11:47. 246 |
247 | 248 |
249 | 250 | 251 | 252 | 253 | -------------------------------------------------------------------------------- /doc/Py5cheSim.Scheds_Inter.RRplus_Scheduler.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | Py5cheSim.Scheds_Inter.RRplus_Scheduler : API documentation 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 22 | 23 |
24 | 25 | 31 | 32 |
33 | class documentation 34 |
35 | 36 |
37 |

class RRplus_Scheduler(InterSliceScheduler):

38 |

View In Hierarchy

39 |
40 | 41 |
42 |

This class implements Round Robin Plus inter slice scheduling algorithm.

43 |
44 | 45 |
46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 |
Method__init__Undocumented
MethodresAllocThis method implements Round Robin Plus PRB allocation between the different configured slices. This PEM method overwrites the resAlloc method from InterSliceScheduler class.
60 | 61 | 62 | 63 |
64 | 65 |
66 | 67 |
68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 |
76 | 77 | def __init__(self, ba, fr, dm, tdd, gr): 78 | 79 |
80 |
81 | 82 | 83 |

Undocumented

84 |
85 |
86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 |
94 | 95 | def resAlloc(self, env): 96 | 97 |
98 |
99 | 100 | 101 |

This method implements Round Robin Plus PRB allocation between the different configured slices. This PEM method overwrites the resAlloc method from InterSliceScheduler class.

Round Robin Plus scheduler allocates the same amount of resources to each slice with packets in buffer.

102 |
103 |
104 | 105 |
106 |
107 | API Documentation for Py5cheSim, generated by pydoctor 21.2.2 at 2021-09-05 13:11:47. 108 |
109 | 110 |
111 | 112 | 113 | 114 | 115 | -------------------------------------------------------------------------------- /doc/Py5cheSim.Scheds_Inter.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | Py5cheSim.Scheds_Inter : API documentation 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 22 | 23 |
24 | 25 | 31 | 32 |
33 | module documentation 34 |
35 | 36 |
37 | 38 |

39 |
40 | 41 |
42 |

This module contains different implemented inter slice schedulers. New schedulers should be implemented here following the current structure.

43 |
44 | 45 |
46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 |
ClassRRplus_SchedulerThis class implements Round Robin Plus inter slice scheduling algorithm.
ClassPF_SchedulerThis class implements Proportional Fair inter slice scheduling algorithm.
60 | 61 | 62 | 63 |
64 | 65 |
66 | 67 | 68 | 69 |
70 |
71 | API Documentation for Py5cheSim, generated by pydoctor 21.2.2 at 2021-09-05 13:11:47. 72 |
73 | 74 |
75 | 76 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /doc/Py5cheSim.Scheds_Intra.PF_Scheduler.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | Py5cheSim.Scheds_Intra.PF_Scheduler : API documentation 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 22 | 23 |
24 | 25 | 31 | 32 |
33 | class documentation 34 |
35 | 36 |
37 |

class PF_Scheduler(IntraSliceScheduler):

38 |

View In Hierarchy

39 |
40 | 41 |
42 |

This class implements Proportional Fair intra slice scheduling algorithm.

43 |
44 | 45 |
46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 |
Method__init__Undocumented
Instance VariablepromLenPast Throughput average length considered in PF metric
MethodresAllocThis method implements Proportional Fair resource allocation between the different connected UEs. This method overwrites the resAlloc method from IntraSliceScheduler class.
MethodsetUEfactorThis method sets the PF metric for each UE
MethodfindMaxFactorThis method finds and returns the UE with the highest metric
MethodprintResAllocUndocumented
80 | 81 | 82 | 83 |
84 | 85 |
86 | 87 |
88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 |
96 | 97 | def __init__(self, ba, n, debMd, sLod, ttiByms, mmd_, ly_, dir, Smb, robustMCS, slcLbl, sch): 98 | 99 |
100 |
101 | 102 | 103 |

Undocumented

104 |
105 |
106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 |
114 | 115 | promLen = 116 | 117 |
118 |
119 | 120 | 121 |

Past Throughput average length considered in PF metric

(type: int) 122 |
123 |
124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 |
132 | 133 | def resAlloc(self, band): 134 | 135 |
136 |
137 | 138 | 139 |

This method implements Proportional Fair resource allocation between the different connected UEs. This method overwrites the resAlloc method from IntraSliceScheduler class.

Proportional Fair scheduler allocates all PRBs in the slice to the UE with the biggest metric. Metric for each UE is calculated as PossibleUEtbs/AveragePastTbs.

140 |
141 |
142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 |
150 | 151 | def setUEfactor(self, exp_n, exp_d): 152 | 153 |
154 |
155 | 156 | 157 |

This method sets the PF metric for each UE

158 |
159 |
160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 |
168 | 169 | def findMaxFactor(self): 170 | 171 |
172 |
173 | 174 | 175 |

This method finds and returns the UE with the highest metric

176 |
177 |
178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 |
186 | 187 | def printResAlloc(self): 188 | 189 |
190 |
191 | 192 | 193 |

Undocumented

194 |
195 |
196 | 197 |
198 |
199 | API Documentation for Py5cheSim, generated by pydoctor 21.2.2 at 2021-09-05 13:11:47. 200 |
201 | 202 |
203 | 204 | 205 | 206 | 207 | -------------------------------------------------------------------------------- /doc/Py5cheSim.Scheds_Intra.TBqueueTDD.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | Py5cheSim.Scheds_Intra.TBqueueTDD : API documentation 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 22 | 23 |
24 | 25 | 31 | 32 |
33 | class documentation 34 |
35 | 36 |
37 |

class TBqueueTDD:

38 |

View In Hierarchy

39 |
40 | 41 |
42 |

This class is used to model scheduler TB queue in TDD scheduler.

43 |
44 | 45 |
46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 |
Method__init__Undocumented
Instance VariableresUndocumented
Instance VariablenumResUndocumented
MethodgetFreeSpaceUndocumented
MethodinsertTBUndocumented
MethodremoveTBUndocumented
MethodupdateSizeUndocumented
85 | 86 | 87 | 88 |
89 | 90 |
91 | 92 |
93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 |
101 | 102 | def __init__(self, symb): 103 | 104 |
105 |
106 | 107 | 108 |

Undocumented

109 |
110 |
111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 |
119 | 120 | res = 121 | 122 |
123 |
124 | 125 | 126 |

Undocumented

127 |
128 |
129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 |
137 | 138 | numRes = 139 | 140 |
141 |
142 | 143 | 144 |

Undocumented

145 |
146 |
147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 |
155 | 156 | def getFreeSpace(self): 157 | 158 |
159 |
160 | 161 | 162 |

Undocumented

163 |
164 |
165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 |
173 | 174 | def insertTB(self, tb): 175 | 176 |
177 |
178 | 179 | 180 |

Undocumented

181 |
182 |
183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 |
191 | 192 | def removeTB(self): 193 | 194 |
195 |
196 | 197 | 198 |

Undocumented

199 |
200 |
201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 |
209 | 210 | def updateSize(self, newSize): 211 | 212 |
213 |
214 | 215 | 216 |

Undocumented

217 |
218 |
219 | 220 |
221 |
222 | API Documentation for Py5cheSim, generated by pydoctor 21.2.2 at 2021-09-05 13:11:47. 223 |
224 | 225 |
226 | 227 | 228 | 229 | 230 | -------------------------------------------------------------------------------- /doc/Py5cheSim.Scheds_Intra.TDD_Scheduler.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | Py5cheSim.Scheds_Intra.TDD_Scheduler : API documentation 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 22 | 23 |
24 | 25 | 31 | 32 |
33 | class documentation 34 |
35 | 36 |
37 |

class TDD_Scheduler(IntraSliceScheduler):

38 |

View In Hierarchy

39 |
40 | 41 |
42 |

This class implements TDD intra slice scheduling.

43 |
44 | 45 |
46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 |
Method__init__Undocumented
Instance VariablesymMaxUndocumented
Instance VariablequeueTDD scheduler TB queue.
MethodresAllocThis method implements resource allocation between the different connected UEs in a TDD slice.
MethodqueueUpdateThis method fills scheduler TB queue at each TTI with TBs built with UE data/signalling bytes.
Instance VariableueLstUndocumented
Instance Variablesm_limUndocumented
MethodrrcUncstSigInUndocumented
MethodretransmitTBUndocumented
MethoddataPtoTBThis method takes UE data bytes, builds TB and puts them in the scheduler TB queue.
MethodsetTBSUndocumented
MethodprintResAllocUndocumented
110 | 111 | 112 | 113 |
114 | 115 |
116 | 117 |
118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 |
126 | 127 | def __init__(self, ba, n, debMd, sLod, ttiByms, mmd_, ly_, dir, Smb, robustMCS, slcLbl, sch): 128 | 129 |
130 |
131 | 132 | 133 |

Undocumented

134 |
135 |
136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 |
144 | 145 | symMax = 146 | 147 |
148 |
149 | 150 | 151 |

Undocumented

152 |
153 |
154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 |
162 | 163 | queue = 164 | 165 |
166 |
167 | 168 | 169 |

TDD scheduler TB queue.

IntraSliceScheduler class attribute queue is overwriten here by a new type of queue which handles symbols. This queue will contain as much TB as a slot can contain. If resource allocation is made in terms of slots, it will contain 1 element, else, it will contain as much mini-slots as can be supported in 1 slot.

170 |
171 |
172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 |
180 | 181 | def resAlloc(self, band): 182 | 183 |
184 |
185 | 186 | 187 |

This method implements resource allocation between the different connected UEs in a TDD slice.

It overwrites the resAlloc method from IntraSliceScheduler class. In this Py5cheSim version TDD scheduler allocates all PRBs in the slice to a UE during 1 slot. Future Py5cheSim versions could support mini-slot allocation by changing the UE symbol allocation in this method. Note that in that case, althoug there is no need to update the queueUpdate method, TBS calculation must be adjusted to avoid losing capacity when trunking the Nre__ value.

188 |
189 |
190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 |
198 | 199 | def queueUpdate(self): 200 | 201 |
202 |
203 | 204 | 205 |

This method fills scheduler TB queue at each TTI with TBs built with UE data/signalling bytes.

It overwrites queueUpdate method from IntraSliceScheduler class, making Resource allocation in terms of slot Symbols and insert generated TBs into Scheduler queue in a TTI. Althoug in this version Resource allocation is made by slot, it is prepared to support mini-slot resource allocation by handling a scheduler TB queue in terms of symbols.

206 |
207 |
208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 |
216 | 217 | ueLst = 218 | 219 |
220 |
221 | 222 | 223 |

Undocumented

224 |
225 |
226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 |
234 | 235 | sm_lim = 236 | 237 |
238 |
239 | 240 | 241 |

Undocumented

242 |
243 |
244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 |
252 | 253 | def rrcUncstSigIn(self, u): 254 | 255 |
256 |
257 | 258 | 259 |

Undocumented

260 |
261 |
262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 |
270 | 271 | def retransmitTB(self, u): 272 | 273 |
274 |
275 | 276 | 277 |

Undocumented

278 |
279 |
280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 |
288 | 289 | def dataPtoTB(self, u): 290 | 291 |
292 |
293 | 294 | 295 |

This method takes UE data bytes, builds TB and puts them in the scheduler TB queue.

It overwrites dataPtoTB method from IntraSliceScheduler class. In this case it returns the amount of allocated symbols to the UE.

296 |
297 |
298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 |
306 | 307 | def setTBS(self, r, qm, uldl, u_, fr, nprb): 308 | 309 |
310 |
311 | 312 | 313 |

Undocumented

314 |
315 |
316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 |
324 | 325 | def printResAlloc(self): 326 | 327 |
328 |
329 | 330 | 331 |

Undocumented

332 |
333 |
334 | 335 |
336 |
337 | API Documentation for Py5cheSim, generated by pydoctor 21.2.2 at 2021-09-05 13:11:47. 338 |
339 | 340 |
341 | 342 | 343 | 344 | 345 | -------------------------------------------------------------------------------- /doc/Py5cheSim.Scheds_Intra.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | Py5cheSim.Scheds_Intra : API documentation 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 22 | 23 |
24 | 25 | 31 | 32 |
33 | module documentation 34 |
35 | 36 |
37 | 38 |

39 |
40 | 41 |
42 |

This module contains different implemented intra slice schedulers. New schedulers should be implemented here following the current structure.

43 |
44 | 45 |
46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 |
ClassPF_SchedulerThis class implements Proportional Fair intra slice scheduling algorithm.
ClassTDD_SchedulerThis class implements TDD intra slice scheduling.
ClassTBqueueTDDThis class is used to model scheduler TB queue in TDD scheduler.
65 | 66 | 67 | 68 |
69 | 70 |
71 | 72 | 73 | 74 |
75 |
76 | API Documentation for Py5cheSim, generated by pydoctor 21.2.2 at 2021-09-05 13:11:47. 77 |
78 | 79 |
80 | 81 | 82 | 83 | 84 | -------------------------------------------------------------------------------- /doc/Py5cheSim.Slice.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | Py5cheSim.Slice : API documentation 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 22 | 23 |
24 | 25 | 31 | 32 |
33 | module documentation 34 |
35 | 36 |
37 | 38 |

39 |
40 | 41 |
42 |

This module contains the Slice class.

43 |
44 | 45 |
46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 |
ClassSliceThis class has Slice relative parameters and is used to implement the mapping between service requirements and slice configuration.
55 | 56 | 57 | 58 |
59 | 60 |
61 | 62 | 63 | 64 |
65 |
66 | API Documentation for Py5cheSim, generated by pydoctor 21.2.2 at 2021-09-05 13:11:47. 67 |
68 | 69 |
70 | 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /doc/Py5cheSim.UE.Bearer.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | Py5cheSim.UE.Bearer : API documentation 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 22 | 23 |
24 | 25 | 31 | 32 |
33 | class documentation 34 |
35 | 36 |
37 |

class Bearer:

38 |

View In Hierarchy

39 |
40 | 41 |
42 |

This class is used to model Bearers properties and behabiour.

43 |
44 | 45 |
46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 |
Method__init__Undocumented
Instance VariableidUndocumented
Instance VariableqciUndocumented
Instance VariabletypeUndocumented
Instance VariablebufferUndocumented
75 | 76 | 77 | 78 |
79 | 80 |
81 | 82 |
83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 |
91 | 92 | def __init__(self, i, q, tp): 93 | 94 |
95 |
96 | 97 | 98 |

Undocumented

99 |
100 |
101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 |
109 | 110 | id = 111 | 112 |
113 |
114 | 115 | 116 |

Undocumented

117 |
118 |
119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 |
127 | 128 | qci = 129 | 130 |
131 |
132 | 133 | 134 |

Undocumented

135 |
136 |
137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 |
145 | 146 | type = 147 | 148 |
149 |
150 | 151 | 152 |

Undocumented

153 |
154 |
155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 |
163 | 164 | buffer = 165 | 166 |
167 |
168 | 169 | 170 |

Undocumented

171 |
172 |
173 | 174 |
175 |
176 | API Documentation for Py5cheSim, generated by pydoctor 21.2.2 at 2021-09-05 13:11:47. 177 |
178 | 179 |
180 | 181 | 182 | 183 | 184 | -------------------------------------------------------------------------------- /doc/Py5cheSim.UE.Format.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | Py5cheSim.UE.Format : API documentation 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 22 | 23 |
24 | 25 | 31 | 32 |
33 | class documentation 34 |
35 | 36 |
37 |

class Format:

38 |

View In Hierarchy

39 |
40 | 41 |
42 |

Undocumented

43 |
44 | 45 |
46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 |
Class VariableCENDUndocumented
Class VariableCBOLDUndocumented
Class VariableCITALICUndocumented
Class VariableCURLUndocumented
Class VariableCBLINKUndocumented
Class VariableCBLINK2Undocumented
Class VariableCSELECTEDUndocumented
Class VariableCBLACKUndocumented
Class VariableCREDUndocumented
Class VariableCGREENUndocumented
Class VariableCYELLOWUndocumented
Class VariableCBLUEUndocumented
Class VariableCVIOLETUndocumented
Class VariableCBEIGEUndocumented
Class VariableCWHITEUndocumented
Class VariableCGREENBGUndocumented
Class VariableCBLUEBGUndocumented
135 | 136 | 137 | 138 |
139 | 140 |
141 | 142 |
143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 |
151 | 152 | CEND = 153 | 154 |
155 |
156 | 157 | 158 |

Undocumented

(type: str) 159 |
160 |
161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 |
169 | 170 | CBOLD = 171 | 172 |
173 |
174 | 175 | 176 |

Undocumented

(type: str) 177 |
178 |
179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 |
187 | 188 | CITALIC = 189 | 190 |
191 |
192 | 193 | 194 |

Undocumented

(type: str) 195 |
196 |
197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 |
205 | 206 | CURL = 207 | 208 |
209 |
210 | 211 | 212 |

Undocumented

(type: str) 213 |
214 |
215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 |
223 | 224 | CBLINK = 225 | 226 |
227 |
228 | 229 | 230 |

Undocumented

(type: str) 231 |
232 |
233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 |
241 | 242 | CBLINK2 = 243 | 244 |
245 |
246 | 247 | 248 |

Undocumented

(type: str) 249 |
250 |
251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 |
259 | 260 | CSELECTED = 261 | 262 |
263 |
264 | 265 | 266 |

Undocumented

(type: str) 267 |
268 |
269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 |
277 | 278 | CBLACK = 279 | 280 |
281 |
282 | 283 | 284 |

Undocumented

(type: str) 285 |
286 |
287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 |
295 | 296 | CRED = 297 | 298 |
299 |
300 | 301 | 302 |

Undocumented

(type: str) 303 |
304 |
305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 |
313 | 314 | CGREEN = 315 | 316 |
317 |
318 | 319 | 320 |

Undocumented

(type: str) 321 |
322 |
323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 |
331 | 332 | CYELLOW = 333 | 334 |
335 |
336 | 337 | 338 |

Undocumented

(type: str) 339 |
340 |
341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 |
349 | 350 | CBLUE = 351 | 352 |
353 |
354 | 355 | 356 |

Undocumented

(type: str) 357 |
358 |
359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 |
367 | 368 | CVIOLET = 369 | 370 |
371 |
372 | 373 | 374 |

Undocumented

(type: str) 375 |
376 |
377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 |
385 | 386 | CBEIGE = 387 | 388 |
389 |
390 | 391 | 392 |

Undocumented

(type: str) 393 |
394 |
395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 |
403 | 404 | CWHITE = 405 | 406 |
407 |
408 | 409 | 410 |

Undocumented

(type: str) 411 |
412 |
413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 |
421 | 422 | CGREENBG = 423 | 424 |
425 |
426 | 427 | 428 |

Undocumented

(type: str) 429 |
430 |
431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 |
439 | 440 | CBLUEBG = 441 | 442 |
443 |
444 | 445 | 446 |

Undocumented

(type: str) 447 |
448 |
449 | 450 |
451 |
452 | API Documentation for Py5cheSim, generated by pydoctor 21.2.2 at 2021-09-05 13:11:47. 453 |
454 | 455 |
456 | 457 | 458 | 459 | 460 | -------------------------------------------------------------------------------- /doc/Py5cheSim.UE.Packet.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | Py5cheSim.UE.Packet : API documentation 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 22 | 23 |
24 | 25 | 31 | 32 |
33 | class documentation 34 |
35 | 36 |
37 |

class Packet:

38 |

View In Hierarchy

39 |
40 | 41 |
42 |

This class is used to model packets properties and behabiour.

43 |
44 | 45 |
46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 |
Method__init__Undocumented
Instance VariablesecNumUndocumented
Instance VariablesizeUndocumented
Instance VariableqosFlowIdUndocumented
Instance VariableueUndocumented
Instance VariabletInUndocumented
MethodprintPacketUndocumented
85 | 86 | 87 | 88 |
89 | 90 |
91 | 92 |
93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 |
101 | 102 | def __init__(self, sn, s, qfi, u): 103 | 104 |
105 |
106 | 107 | 108 |

Undocumented

109 |
110 |
111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 |
119 | 120 | secNum = 121 | 122 |
123 |
124 | 125 | 126 |

Undocumented

127 |
128 |
129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 |
137 | 138 | size = 139 | 140 |
141 |
142 | 143 | 144 |

Undocumented

145 |
146 |
147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 |
155 | 156 | qosFlowId = 157 | 158 |
159 |
160 | 161 | 162 |

Undocumented

163 |
164 |
165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 |
173 | 174 | ue = 175 | 176 |
177 |
178 | 179 | 180 |

Undocumented

181 |
182 |
183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 |
191 | 192 | tIn = 193 | 194 |
195 |
196 | 197 | 198 |

Undocumented

(type: int) 199 |
200 |
201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 |
209 | 210 | def printPacket(self): 211 | 212 |
213 |
214 | 215 | 216 |

Undocumented

217 |
218 |
219 | 220 |
221 |
222 | API Documentation for Py5cheSim, generated by pydoctor 21.2.2 at 2021-09-05 13:11:47. 223 |
224 | 225 |
226 | 227 | 228 | 229 | 230 | -------------------------------------------------------------------------------- /doc/Py5cheSim.UE.PcktQueue.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | Py5cheSim.UE.PcktQueue : API documentation 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 22 | 23 |
24 | 25 | 31 | 32 |
33 | class documentation 34 |
35 | 36 |
37 |

class PcktQueue:

38 |

View In Hierarchy

39 |
40 | 41 |
42 |

This class is used to model application and bearer buffers.

43 |
44 | 45 |
46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 |
Method__init__Undocumented
Instance VariablepcktsUndocumented
MethodinsertPcktUndocumented
MethodinsertPcktLeftUndocumented
MethodremovePcktUndocumented
75 | 76 | 77 | 78 |
79 | 80 |
81 | 82 |
83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 |
91 | 92 | def __init__(self): 93 | 94 |
95 |
96 | 97 | 98 |

Undocumented

99 |
100 |
101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 |
109 | 110 | pckts = 111 | 112 |
113 |
114 | 115 | 116 |

Undocumented

117 |
118 |
119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 |
127 | 128 | def insertPckt(self, p): 129 | 130 |
131 |
132 | 133 | 134 |

Undocumented

135 |
136 |
137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 |
145 | 146 | def insertPcktLeft(self, p): 147 | 148 |
149 |
150 | 151 | 152 |

Undocumented

153 |
154 |
155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 |
163 | 164 | def removePckt(self): 165 | 166 |
167 |
168 | 169 | 170 |

Undocumented

171 |
172 |
173 | 174 |
175 |
176 | API Documentation for Py5cheSim, generated by pydoctor 21.2.2 at 2021-09-05 13:11:47. 177 |
178 | 179 |
180 | 181 | 182 | 183 | 184 | -------------------------------------------------------------------------------- /doc/Py5cheSim.UE.RadioLink.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | Py5cheSim.UE.RadioLink : API documentation 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 22 | 23 |
24 | 25 | 31 | 32 |
33 | class documentation 34 |
35 | 36 |
37 |

class RadioLink:

38 |

View In Hierarchy

39 |
40 | 41 |
42 |

This class is used to model radio link properties and behabiour.

43 |
44 | 45 |
46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 |
Method__init__Undocumented
Instance VariableidUndocumented
Instance VariablelinkQualityUndocumented
Instance VariableueUndocumented
Instance VariabletotCountUndocumented
Instance VariablemaxVarUndocumented
MethodupdateLQThis method updates UE link quality in terms of SINR during the simulation. This is a PEM method.
85 | 86 | 87 | 88 |
89 | 90 |
91 | 92 |
93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 |
101 | 102 | def __init__(self, i, lq_0, u): 103 | 104 |
105 |
106 | 107 | 108 |

Undocumented

109 |
110 |
111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 |
119 | 120 | id = 121 | 122 |
123 |
124 | 125 | 126 |

Undocumented

127 |
128 |
129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 |
137 | 138 | linkQuality = 139 | 140 |
141 |
142 | 143 | 144 |

Undocumented

145 |
146 |
147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 |
155 | 156 | ue = 157 | 158 |
159 |
160 | 161 | 162 |

Undocumented

163 |
164 |
165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 |
173 | 174 | totCount = 175 | 176 |
177 |
178 | 179 | 180 |

Undocumented

(type: int) 181 |
182 |
183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 |
191 | 192 | maxVar = 193 | 194 |
195 |
196 | 197 | 198 |

Undocumented

(type: float) 199 |
200 |
201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 |
209 | 210 | def updateLQ(self, env, udIntrv, tSim, fl, u, r): 211 | 212 |
213 |
214 | 215 | 216 |

This method updates UE link quality in terms of SINR during the simulation. This is a PEM method.

During the simulation it is assumed that UE SINR varies following a normal distribution with mean value equal to initial SINR value, and a small variance.

217 |
218 |
219 | 220 |
221 |
222 | API Documentation for Py5cheSim, generated by pydoctor 21.2.2 at 2021-09-05 13:11:47. 223 |
224 | 225 |
226 | 227 | 228 | 229 | 230 | -------------------------------------------------------------------------------- /doc/Py5cheSim.UE.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | Py5cheSim.UE : API documentation 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 22 | 23 |
24 | 25 | 31 | 32 |
33 | module documentation 34 |
35 | 36 |
37 | 38 |

39 |
40 | 41 |
42 |

This module contains the UE, Packet Flow, Packet, PcktQueue, Bearer and RadioLink clases. This clases are oriented to describe UE traffic profile, and UE relative concepts

43 |
44 | 45 |
46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 |
ClassUEThis class is used to model UE behabiour and relative properties
ClassPacketFlowThis class is used to describe UE traffic profile for the simulation.
ClassPacketThis class is used to model packets properties and behabiour.
ClassBearerThis class is used to model Bearers properties and behabiour.
ClassPcktQueueThis class is used to model application and bearer buffers.
ClassRadioLinkThis class is used to model radio link properties and behabiour.
ClassFormatUndocumented
85 | 86 | 87 | 88 |
89 | 90 |
91 | 92 | 93 | 94 |
95 |
96 | API Documentation for Py5cheSim, generated by pydoctor 21.2.2 at 2021-09-05 13:11:47. 97 |
98 | 99 |
100 | 101 | 102 | 103 | 104 | -------------------------------------------------------------------------------- /doc/Py5cheSim.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | Py5cheSim : API documentation 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 22 | 23 |
24 | 25 | 31 | 32 |
33 | package documentation 34 |
35 | 36 |
37 | 38 |

39 |
40 | 41 |
42 |

Undocumented

43 |
44 | 45 |
46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 |
ModuleCellThis module contains the Cell class.
ModuleInterSliceSchThis module contains the basic Inter Slice Scheduler class. All possible inter slice schedulers should inherit from this.
ModuleIntraSliceSchThis module contains the basic Intra Slice Scheduler class. All possible intra slice schedulers should inherit from this.
ModuleResultsThis module contains auxiliary simulation classes and methods along with results processing.
ModuleScheds_InterThis module contains different implemented inter slice schedulers. New schedulers should be implemented here following the current structure.
ModuleScheds_IntraThis module contains different implemented intra slice schedulers. New schedulers should be implemented here following the current structure.
ModuleSliceThis module contains the Slice class.
ModuleUEThis module contains the UE, Packet Flow, Packet, PcktQueue, Bearer and RadioLink clases. This clases are oriented to describe UE traffic profile, and UE relative concepts
ModulesimulationThis is the simulation script. Simulation, cell and traffic profile parameters can be set here.
95 | 96 | 97 | 98 |
99 | 100 |
101 | 102 | 103 | 104 |
105 |
106 | API Documentation for Py5cheSim, generated by pydoctor 21.2.2 at 2021-09-05 13:11:47. 107 |
108 | 109 |
110 | 111 | 112 | 113 | 114 | -------------------------------------------------------------------------------- /doc/apidocs.css: -------------------------------------------------------------------------------- 1 | body { 2 | overflow-y: scroll; 3 | } 4 | 5 | .navbar { 6 | margin-bottom: 0px; 7 | } 8 | 9 | .page-header { 10 | margin-top: 22px; 11 | position: sticky; 12 | top: 0; 13 | display: flex; 14 | flex-wrap: wrap; 15 | justify-content: space-between; 16 | align-items: baseline; 17 | background-color: #fff; 18 | margin-bottom: 3px; 19 | border-bottom: 0; 20 | box-shadow: 0px 0px 8px 8px #fff; 21 | } 22 | .page-header h1 { 23 | margin-bottom: 0; 24 | } 25 | 26 | .categoryHeader { 27 | font-size: 24px; 28 | color: #777; 29 | margin-bottom: 1.8em; 30 | } 31 | 32 | a[name] { 33 | position: relative; 34 | bottom: 80px; 35 | font-size: 0; 36 | } 37 | 38 | ul { 39 | margin-top: 10px; 40 | padding-left: 10px; 41 | } 42 | 43 | li { 44 | padding-top: 5px; 45 | padding-bottom: 5px; 46 | } 47 | 48 | li a { 49 | text-decoration: none; 50 | } 51 | 52 | ul { 53 | margin-left: 10px; 54 | } 55 | 56 | ul ul { 57 | border-left-color: #e1f5fe; 58 | border-left-width: 1px; 59 | border-left-style: solid; 60 | } 61 | 62 | ul ul ul { 63 | border-left-color: #b3e5fc; 64 | } 65 | 66 | ul ul ul ul { 67 | border-left-color: #81d4fa; 68 | } 69 | 70 | ul ul ul ul ul { 71 | border-left-color: #4fc3f7; 72 | } 73 | 74 | ul ul ul ul ul ul { 75 | border-left-color: #29b6f6; 76 | } 77 | 78 | ul ul ul ul ul ul ul { 79 | border-left-color: #03a9f4; 80 | } 81 | 82 | ul ul ul ul ul ul ul { 83 | border-left-color: #039be5; 84 | } 85 | 86 | .pre { 87 | white-space: pre; 88 | } 89 | 90 | .undocumented { 91 | font-style: italic; 92 | color: #9e9e9e; 93 | } 94 | 95 | .functionBody p { 96 | margin-top: 6px; 97 | margin-bottom: 6px; 98 | } 99 | 100 | #splitTables > p { 101 | margin-bottom: 5px; 102 | } 103 | 104 | #splitTables > table, .fieldTable { 105 | margin-bottom: 20px; 106 | width: 100%; 107 | border: 0; 108 | } 109 | 110 | #splitTables > table { 111 | border: 1px solid #eee; 112 | } 113 | 114 | #splitTables > table tr { 115 | border-bottom-color: #eee; 116 | border-bottom-width: 1px; 117 | border-bottom-style: solid; 118 | } 119 | 120 | #splitTables > table tr td, .fieldTable tr td { 121 | padding: 5px; 122 | } 123 | 124 | #splitTables > table tr td { 125 | border-left-color: #eee; 126 | border-left-width: 1px; 127 | border-left-style: solid; 128 | } 129 | 130 | #splitTables > table tr td:nth-child(1), .fieldTable tr td:nth-child(1) { 131 | border-left: none; 132 | width: 150px; 133 | } 134 | 135 | #splitTables > table tr td:nth-child(2), .fieldTable tr td.fieldArg { 136 | width: 200px; 137 | } 138 | 139 | tr.package { 140 | background-color: #fff3e0; 141 | } 142 | 143 | tr.module { 144 | background-color: #fff8e1; 145 | } 146 | 147 | tr.class, tr.classvariable, tr.baseclassvariable { 148 | background-color: #fffde7; 149 | } 150 | 151 | tr.instancevariable, tr.baseinstancevariable, tr.variable, tr.attribute, tr.property { 152 | background-color: #f3e5f5; 153 | } 154 | 155 | tr.interface { 156 | background-color: #fbe9e7; 157 | } 158 | 159 | tr.method, tr.function, tr.basemethod, tr.baseclassmethod, tr.classmethod { 160 | background-color: #f1f8e9; 161 | } 162 | 163 | tr.private { 164 | background-color: #f1f1f1; 165 | } 166 | 167 | .fieldTable { 168 | margin-top: 10px; 169 | } 170 | 171 | .fieldName { 172 | font-weight: bold; 173 | } 174 | 175 | 176 | #childList > div { 177 | margin: 10px; 178 | padding: 10px; 179 | padding-bottom: 5px; 180 | } 181 | 182 | .functionBody { 183 | margin-left: 15px; 184 | } 185 | 186 | .functionBody > #part { 187 | font-style: italic; 188 | } 189 | 190 | .functionBody > #part > a { 191 | text-decoration: none; 192 | } 193 | 194 | .functionBody .interfaceinfo { 195 | font-style: italic; 196 | margin-bottom: 3px; 197 | } 198 | 199 | .functionBody > .undocumented { 200 | 201 | margin-top: 6px; 202 | margin-bottom: 6px; 203 | } 204 | 205 | /* 206 | - Links to class/function/etc names are nested like this: 207 | label 208 | This applies to inline docstring content marked up as code, 209 | for example L{foo} in epytext or `bar` in restructuredtext, 210 | but also to links that are present in summary tables. 211 | - 'functionHeader' is used for lines like `def func():` and `var =` 212 | */ 213 | code, .pre, #childList > div .functionHeader, 214 | #splitTables > table tr td:nth-child(2), .fieldTable tr td.fieldArg { 215 | font-family: Menlo, Monaco, Consolas, "Courier New", monospace; 216 | } 217 | code, #childList > div .functionHeader, .fieldTable tr td.fieldArg { 218 | font-size: 90%; 219 | color: #222222; 220 | } 221 | code > a { 222 | color:#c7254e; 223 | background-color:#f9f2f4; 224 | } 225 | /* top navagation bar */ 226 | .page-header > h1 { 227 | margin-top: 0; 228 | } 229 | .page-header > h1 > code { 230 | color: #971c3a; 231 | } 232 | 233 | /* 234 | This defines the code style, it's black on light gray. 235 | It also overwrite the default values inherited from bootstrap min 236 | */ 237 | code { 238 | padding:2px 4px; 239 | background-color: #f4f4f4; 240 | border-radius:4px 241 | } 242 | 243 | 244 | a.functionSourceLink { 245 | font-weight: normal; 246 | } 247 | 248 | 249 | #childList > div { 250 | border-left-color: #03a9f4; 251 | border-left-width: 1px; 252 | border-left-style: solid; 253 | background: #fafafa; 254 | } 255 | 256 | .moduleDocstring { 257 | margin: 20px; 258 | } 259 | 260 | #partOf { 261 | margin-top: -13px; 262 | margin-bottom: 19px; 263 | } 264 | 265 | .fromInitPy { 266 | font-style: italic; 267 | } 268 | 269 | pre { 270 | padding-left: 0px; 271 | } 272 | 273 | /* Private stuff */ 274 | 275 | body.private-hidden #splitTables .private, 276 | body.private-hidden #childList .private, 277 | body.private-hidden #summaryTree .private { 278 | display: none; 279 | } 280 | 281 | #showPrivate { 282 | padding: 10px; 283 | } 284 | 285 | #current-docs-container { 286 | font-style: italic; 287 | padding-top: 11px; 288 | } 289 | 290 | /* Deprecation stuff */ 291 | 292 | .deprecationNotice { 293 | margin: 10px; 294 | } 295 | 296 | /* Syntax highlighting for source code */ 297 | 298 | .py-string { 299 | color: #337ab7; 300 | } 301 | .py-comment { 302 | color: #309078; 303 | font-style: italic; 304 | } 305 | .py-keyword { 306 | font-weight: bold; 307 | } 308 | .py-defname { 309 | color: #a947b8; 310 | font-weight: bold; 311 | } 312 | .py-builtin { 313 | color: #fc7844; 314 | font-weight: bold; 315 | } 316 | 317 | /* Doctest */ 318 | 319 | pre.py-doctest { 320 | padding: .5em; 321 | } 322 | .py-prompt, .py-more { 323 | color: #a8a8a8; 324 | } 325 | .py-output { 326 | color: #c7254e; 327 | } 328 | 329 | /* Admonitions */ 330 | 331 | div.rst-admonition p.rst-admonition-title:after { 332 | content: ":"; 333 | } 334 | 335 | div.rst-admonition p.rst-admonition-title { 336 | margin: 0; 337 | padding: 0.1em 0 0.35em 0em; 338 | font-weight: bold; 339 | } 340 | 341 | div.rst-admonition p.rst-admonition-title { 342 | color: #333333; 343 | } 344 | 345 | div.rst-admonition { 346 | padding: 8px; 347 | margin-bottom: 20px; 348 | background-color: #EEE; 349 | border: 1px solid #CCC; 350 | border-radius: 4px; 351 | } 352 | 353 | div.warning, div.attention, div.danger, div.error, div.caution { 354 | background-color: #ffcf9cb0; 355 | border: 1px solid #ffbbaa; 356 | } 357 | 358 | div.danger p.rst-admonition-title, div.error p.rst-admonition-title, div.caution p.rst-admonition-title { 359 | color: #b94a48; 360 | } 361 | 362 | div.tip p.rst-admonition-title, div.hint p.rst-admonition-title, div.important p.rst-admonition-title{ 363 | color: #3a87ad; 364 | } 365 | 366 | div.tip, div.hint, div.important { 367 | background-color: #d9edf7; 368 | border-color: #bce8f1; 369 | } 370 | -------------------------------------------------------------------------------- /doc/classIndex.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | Class Hierarchy 7 | 8 | 9 | 10 | 11 | 12 | 20 | 21 |
22 | 23 | 29 | 30 | 32 | 33 |
34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /doc/index.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | API Documentation for Py5cheSim 7 | 8 | 9 | 10 | 11 | 12 | 13 | 21 | 22 |
23 |

24 | Get Started 25 |

26 | 44 |

45 | About 46 |

47 |

48 | This documentation was automatically generated by 49 | pydoctor 50 | 21.2.2 51 | at 2021-09-05 13:11:47. 52 |

53 | 54 |
55 | 56 | 57 | -------------------------------------------------------------------------------- /doc/moduleIndex.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | Module Index 7 | 8 | 9 | 10 | 11 | 12 | 20 | 21 |
22 | 23 | 29 | 30 |
  • Py5cheSim - No package docstring; 9/9 modules documented
    • Py5cheSim.Cell - This module contains the Cell class.
    • Py5cheSim.InterSliceSch - This module contains the basic Inter Slice Scheduler class. All possible inter slice schedulers should inherit from this.
    • Py5cheSim.IntraSliceSch - This module contains the basic Intra Slice Scheduler class. All possible intra slice schedulers should inherit from this.
    • Py5cheSim.Results - This module contains auxiliary simulation classes and methods along with results processing.
    • Py5cheSim.Scheds_Inter - This module contains different implemented inter slice schedulers. New schedulers should be implemented here following the current structure.
    • Py5cheSim.Scheds_Intra - This module contains different implemented intra slice schedulers. New schedulers should be implemented here following the current structure.
    • Py5cheSim.Slice - This module contains the Slice class.
    • Py5cheSim.UE - This module contains the UE, Packet Flow, Packet, PcktQueue, Bearer and RadioLink clases. This clases are oriented to describe UE traffic profile, and UE relative concepts
    • Py5cheSim.simulation - This is the simulation script. Simulation, cell and traffic profile parameters can be set here.
31 | 32 |
33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /doc/objects.inv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClaudinaRattaro/Py5cheSim/1b757ffc4d026c980d3b6fd13f1e1c9b2cbc5737/doc/objects.inv -------------------------------------------------------------------------------- /doc/pydoctor.js: -------------------------------------------------------------------------------- 1 | function initPrivate() { 2 | var params = (new URL(document.location)).searchParams; 3 | if (!params || !parseInt(params.get('private'))) { 4 | var show = false; 5 | var hash = document.location.hash; 6 | if (hash != '') { 7 | var anchor = document.querySelector('a[name="' + hash.substring(1) + '"]'); 8 | show = anchor && anchor.parentNode.classList.contains('private'); 9 | } 10 | if (!show) { 11 | document.body.classList.add("private-hidden"); 12 | } 13 | } 14 | updatePrivate(); 15 | } 16 | function togglePrivate() { 17 | document.body.classList.toggle("private-hidden"); 18 | updatePrivate(); 19 | } 20 | function updatePrivate() { 21 | var hidden = document.body.classList.contains('private-hidden'); 22 | document.querySelector('#showPrivate button').innerText = 23 | hidden ? 'Show Private API' : 'Hide Private API'; 24 | if (history) { 25 | var search = hidden ? document.location.pathname : '?private=1'; 26 | history.replaceState(null, '', search + document.location.hash); 27 | } 28 | } 29 | initPrivate(); 30 | -------------------------------------------------------------------------------- /simulation.py: -------------------------------------------------------------------------------- 1 | """This is the simulation script. 2 | Simulation, cell and traffic profile parameters can be set here. 3 | """ 4 | import os 5 | import sys 6 | import simpy 7 | from UE import * 8 | from Cell import * 9 | from Results import * 10 | 11 | #------------------------------------------------------------------------------------------------------ 12 | # Cell & Simulation parameters 13 | #------------------------------------------------------------------------------------------------------ 14 | 15 | bw = [10]# MHz (FR1: 5, 10, 15, 20, 25, 30, 40, 50, 60, 80, 90, 100; FR2: 50, 100, 200, 400) 16 | """List containing each CC's bandwidth for the simulation. """ 17 | fr = 'FR1' # FR1 or FR2 18 | """String with frequency range (FR) to use. 'FR1' for FR1, or 'FR2' for FR2.""" 19 | band = 'B1' 20 | """String with used band for simulation. In TDD mode it is important to set correctly a band from the next list: n257, n258, n260, n261.""" 21 | tdd = False 22 | """Boolean indicating if the cell operates in TDD mode.""" 23 | buf = 81920 #10240 # 24 | """Integer with the maximum Bytes the UE Bearer buffer can tolerate before dropping packets.""" 25 | schedulerInter = 'PF11'# RRp for improved Round Robin, PFXX for Proportional Fair 26 | """String indicating the Inter Slice Scheduler to use. For only one Slice simulations use ''. 27 | If the simulation includes more than one slice, set '' for Round Robin, 'RRp' for Round Robin Plus, 28 | or 'PFXY' for Proportional Fair with X=numExp and Y=denExp.""" 29 | # Simulation parameters 30 | t_sim = 60000 # (ms) 31 | """Simulation duration in milliseconds.""" 32 | debMode = True # to show queues information by TTI during simulation 33 | """Boolean indicating if debugging mode is active. In that case, an html log file will be generated with schedulers operation. 34 | Note that in simulations with a high number of UEs this file can turn quite heavy.""" 35 | measInterv = 1000.0 # interval between meassures 36 | """Time interval (in milliseconds) between meassures for statistics reports.""" 37 | interSliceSchGr = 3000.0 # interSlice scheduler time granularity 38 | """Inter slice scheduler time granularity in milliseconds.""" 39 | 40 | #----------------------------------------------------------------- 41 | # Simulation process activation 42 | #----------------------------------------------------------------- 43 | 44 | env = simpy.Environment() 45 | """Environment instance needed by simpy for runing PEM methods""" 46 | cell1 = Cell('c1',bw,fr,debMode,buf,tdd,interSliceSchGr,schedulerInter) 47 | """Cell instance for running the simulation""" 48 | interSliceSche1 = cell1.interSliceSched 49 | """interSliceScheduler instance""" 50 | 51 | # DIFFERENT TRAFFIC PROFILES SETTING 52 | 53 | # A few examples ... 54 | 55 | #UEgroup1 = UEgroup(1,3,100000,8000,3,1,'eMBB',10,'','RR','',1,cell1,t_sim,measInterv,env,'S37') 56 | #UEgroup1 = UEgroup(0,5,0,150,0,60,'m-MTC-2',10,'','RR','',1,cell1,t_sim,measInterv,env,'D37') 57 | #UEgroup1 = UEgroup(0,4,0,2000,0,5000,'eMBB-1',20,'','','',1,cell1,t_sim,measInterv,env,'S25') 58 | #UEgroup2 = UEgroup(0,15,0,350,0,10,'eMBB-2',20,'','PF11','',1,cell1,t_sim,measInterv,env,'S20') 59 | UEgroup2 = UEgroup(0,10,0,350,0,6000,'mMTC-1',20,'','RR','',1,cell1,t_sim,measInterv,env,'S5') 60 | #UEgroup3 = UEgroup(0,8,0,1500,0,6,'URLLC-1',5,'','PF11','',1,cell1,t_sim,measInterv,env,'S25') 61 | # UEgroup1 = UEgroup(3,0,10000,0,2,0,'LTE',20,'','RR','',1,cell1,t_sim,measInterv,env,'S37') 62 | UEgroup1 = UEgroup(3,0,50000,0,1,0,'eMBB',20,'','','SU',4,cell1,t_sim,measInterv,env,'S37') 63 | """Group of users with defined traffic profile, capabilities and service requirements for which the sumulation will run. 64 | 65 | More than one can be instantiated in one simulation. 66 | For each one of them, the UEgroup instance must be added in the UEgroups list. 67 | 68 | UEgroupN = UEgroup(nuDL,nuUL,pszDL,pszUL,parrDL,parrUL,label,dly,avlty,schedulerType,mimo_mode,layers,cell,hdr,t_sim,measInterv,env,sinr): 69 | 70 | label: must contain substring according to the type of service: eMBB, mMTC, URLLC\n 71 | schedulerType: RR: Rounf Robin, PF: Proportional Fair (10, 11)\n 72 | mimo_mode: SU, MU\n 73 | layers: in SU-MIMO is the number of layers/UE, in MU-MIMO is the number of simultaneous UE to serve with the same resources\n 74 | sinr: is a string starting starting with S if all ues have the same sinr or D if not. The value next will be the initial sinr of each ue or the maximum.""" 75 | 76 | #UEgroup2 = UEgroup(3,3,800000,300,1,10,'eMBB-1',10,'','RR','',1,cell1,t_sim,measInterv,env,'D37') 77 | 78 | # Set UEgroups list according to the defined groups!!! 79 | UEgroups = [UEgroup1,UEgroup2]#,UEgroup3]#,UEgroup4] 80 | """UE group list for the configured simulation""" 81 | # Slices creation 82 | for ueG in UEgroups: 83 | interSliceSche1.createSlice(ueG.req['reqDelay'], 84 | ueG.req['reqThroughputDL'], 85 | ueG.req['reqThroughputUL'], 86 | ueG.req['reqAvailability'], 87 | ueG.num_usersDL, 88 | ueG.num_usersUL, 89 | band, 90 | debMode, 91 | ueG.mmMd, 92 | ueG.lyrs, 93 | ueG.label, 94 | ueG.sch) 95 | 96 | # Schedulers activation (inter/intra) 97 | 98 | procCell = env.process(cell1.updateStsts(env,interv=measInterv,tSim=t_sim)) 99 | procInter = env.process(interSliceSche1.resAlloc(env)) 100 | for ueG in UEgroups: 101 | ueG.activateSliceScheds(interSliceSche1,env) 102 | 103 | #---------------------------------------------------------------- 104 | env.run(until=t_sim) 105 | #---------------------------------------------------------------- 106 | 107 | # Closing statistic and debugging files 108 | 109 | for slice in list(cell1.slicesStsts.keys()): 110 | cell1.slicesStsts[slice]['DL'].close() 111 | cell1.slicesStsts[slice]['UL'].close() 112 | for slice in list(interSliceSche1.slices.keys()): 113 | interSliceSche1.slices[slice].schedulerDL.dbFile.close() 114 | if slice != 'LTE': 115 | interSliceSche1.slices[slice].schedulerUL.dbFile.close() 116 | 117 | #---------------------------------------------------------------- 118 | # RESULTS 119 | #---------------------------------------------------------------- 120 | # Show average PLR and Throughput in any case simulation and plots 121 | for UEg in UEgroups: 122 | print (Format.CBOLD+Format.CBLUE+'\n--------------------------------------------------'+Format.CEND) 123 | print (Format.CBOLD+Format.CBLUE+' SLICE: '+UEg.label+' '+Format.CEND) 124 | print (Format.CBOLD+Format.CBLUE+'--------------------------------------------------\n'+Format.CEND) 125 | UEg.printSliceResults(interSliceSche1,t_sim,bw,measInterv) 126 | print (Format.CBOLD+Format.CBLUE+'\n--------------------------------------------------'+Format.CEND) 127 | --------------------------------------------------------------------------------