[Feature]Upload Modem source code

Change-Id: Id4294f30faced84d3e6fd6d5e61e1111bf287a37
diff --git a/mcu/tools/IQ_Analyzer/src/PBCH_decoder.py b/mcu/tools/IQ_Analyzer/src/PBCH_decoder.py
new file mode 100644
index 0000000..3afd99e
--- /dev/null
+++ b/mcu/tools/IQ_Analyzer/src/PBCH_decoder.py
@@ -0,0 +1,167 @@
+from get_3GPP_N import get_3GPP_N

+from get_3GPP_crc_interleaver_pattern import get_3GPP_crc_interleaver_pattern

+from get_3GPP_rate_matching_pattern import get_3GPP_rate_matching_pattern

+from get_3GPP_sequence_pattern import get_3GPP_sequence_pattern

+from get_3GPP_info_bit_pattern import get_3GPP_info_bit_pattern

+from DCKA_polar_decoder import DCKA_polar_decoder

+from Scrambler import Scrambler

+import IQ_Utils

+

+class MIB_Parser:

+#####################################################

+#    38.331. 6.2.2

+#    MIB ::=                             SEQUENCE {

+#    systemFrameNumber                   BIT STRING (SIZE (6)),                          6 bit

+#    subCarrierSpacingCommon             ENUMERATED {scs15or60, scs30or120},             1 bit

+#    ssb_SubcarrierOffset                INTEGER (0..15),                                4 bit

+#    dmrs_TypeA_position                 ENUMERATED {pos2, pos3},                        1 bit 

+#    pdcchConfigSIB1                     PDCCH-ConfigSIB1,                               8 bit 

+#    cellBarred                          ENUMERATED {barred, notBarred},                 1 bit

+#    intraFreqReselection                ENUMERATED {allowed, notAllowed},               1 bit

+#    spare                               BIT STRING (SIZE (1))                           1 bit

+#

+#    

+#pdcchConfigSIB1 ::=                SEQUENCE {

+#    controlResourceSetZero              ControlResourceSetZero,

+#    searchSpaceZero                     SearchSpaceZero

+#}

+#####################################################

+

+    def __init__(self, a_hat, Lmax):

+        

+        ############# MIB fields parsing for frequency range 1 #############

+        mibbits = a_hat

+        mibbits = ''.join(map(str, mibbits))

+        mibbits = mibbits[::-1] #reverse

+        self.reservedBits = IQ_Utils.bi2de(mibbits[0:2])

+        self.k_ssb = mibbits[2]

+        self.HRF = mibbits[3]

+        sfnCombinePHYRRC = mibbits[25:31] + mibbits[4:8]

+        self.systemFrameNumber = IQ_Utils.bi2de(sfnCombinePHYRRC) 

+        

+        if Lmax == 64:

+            commonSCSs = [60, 120]

+            

+        else:

+            commonSCSs = [15, 30]

+          

+        self.RAN2_sparedBit = mibbits[8]

+        self.intraFreqSelection = mibbits[9]

+        self.cellBarred = mibbits[10]

+        self.pdcchConfigSIB1 = IQ_Utils.bi2de(mibbits[11:19])    

+        self.dmrs_TypeA_position = 2 + int(mibbits[19])

+        self.ssb_SubcarrierOffset = IQ_Utils.bi2de(mibbits[20:24])    

+        self.subCarrierSpacingCommon = commonSCSs[int(mibbits[24])]

+        self.msgIndicator = mibbits[31]

+        

+        print "NFrame: ", self.systemFrameNumber

+        print "SubcarrierSpacingCommon: ", self.subCarrierSpacingCommon

+        print "ssb-SubcarrierOffset: ", self.ssb_SubcarrierOffset

+        print "DL-DMRS_typeA_pos: ", self.dmrs_TypeA_position

+        print "PDCCHConfigSIB1: ", self.pdcchConfigSIB1

+        print "CellBarred: ", self.cellBarred

+        print "IntraFreqSelection: ", self.intraFreqSelection

+        print "Spare: ", self.RAN2_sparedBit

+        print "k_ssb", self.k_ssb

+        print "HRF: ", self.HRF

+        print "reservedBits:", self.reservedBits 

+

+##############################################################################

+# NR PBCH payload interleaving 

+# NOTE: N/A

+# input: 

+#        payload (32-bit)

+# output: 

+#         interleaved payload (32-bit)

+##############################################################################

+

+def get_3GPP_PBCH_payload_intlv(payload_bit):

+        

+    mib_intlv_pattern = [1,16,23,18,17,8,30,4,9,11,12,13,14,15,19,20,21,22,25,

+               26,27,28,29,31,10,6,24,7,0,5,3,2]

+    

+    intlv_out = [0]*32

+    for idx in xrange(31,-1,-1):

+        intlv_out[idx] = payload_bit[mib_intlv_pattern[idx]]

+

+    return intlv_out     

+

+#####################################################################################################################################

+# PBCH_DECODER Polar decoder for the Public Broadcast Channel (PBCH) of 3GPP New Radio, as defined in Section 7.1 of TS38.212. 

+# Implements the Cyclic Redudancy Check (CRC) attachment of Section 7.1.3, the channel coding of Section 7.1.4 and the rate 

+# matching of Section 7.1.5.  

+# NOTE: This code does not implement the payload generation of Section 7.1.1 or the scrambling of Section 7.1.2. Function decodes 

+# the encoded LLR sequence f_tilde, in order to obtain the recovered information bit sequence a_hat.

+# input: 

+#        f_tilde should be a real row vector comprising 864 Logarithmic Likelihood Ratios (LLRS), each having a value obtained 

+#        as LLR = ln(P(bit=0)/P(bit=1)). The first LLR corresponds to f_0 from Section  7.1.5 of TS38.212, while the last LLR 

+#        corresponds to f_E-1.

+#        A should be 32. It specifies the number of bits in the information bit sequence.       

+#        L should be a scalar integer. It specifies the list size to use during Successive Cancellation List (SCL) decoding.

+#        min_sum shoular be a scalar logical. If it is true, then the SCL decoding process will be completed using the min-sum 

+#        approximation. Otherwise, the log-sum-product will be used. The log-sum-product gives better error correction capability 

+#        than the min-sum, but it has higher complexity.

+#        Lmax is number of SSB candidates in a burst.

+# output: 

+#         a_hat will be a binary row vector comprising 32 bits, each having the value 0 or 1. The first output bit corresponds

+#         to a'_0 from Section 7.1.3 of TS38.212, while the last output bit corresponds to a'_A-1.

+#####################################################################################################################################

+def PBCH_decoder(f_tilde, A, list_size, min_sum, NidCell, Lmax, ibar_SSB):

+

+    E = len(f_tilde)

+    

+    # A is always 32 in PBCH

+    if A != 32:

+        raise Exception('polar_3gpp_matlab:UnsupportedBlockLength, A should be 32.')

+    

+    # E is always 864 in PBCH

+    if E != 864:

+        raise Exception('polar_3gpp_matlab:UnsupportedBlockLength, E should be 864.')

+    

+    # The CRC polynomial used in 3GPP PBCH and PDCCH channel is

+    # D^24 + D^23 + D^21 + D^20 + D^17 + D^15 + D^13 + D^12 + D^8 + D^4 + D^2 + D + 1

+    crc_polynomial_pattern = [1,1,0,1,1,0,0,1,0,1,0,1,1,0,0,0,1,0,0,0,1,0,1,1,1]

+

+    # The CRC has P bits. P-min(P2,log2(L)) of these are used for error

+    # detection, where L is the list size. Meanwhile, min(P2,log2(L)) of

+    # them are used to improve error correction. So the CRC needs to be

+    # min(P2,log2(L)) number of bits longer than CRCs used in other codes,

+    # in order to achieve the same error detection capability.

+    P = len(crc_polynomial_pattern) - 1

+    P2 = 3

+    

+    # Determine the number of information and CRC bits.

+    K = A + P

+    

+    # Determine the number of bits used at the input and output of the polar

+    # encoder kernal.

+    N = get_3GPP_N(K, E, 9)   

+

+    # Get the 3GPP CRC interleaver pattern.

+    crc_interleaver_pattern = get_3GPP_crc_interleaver_pattern(K)

+    

+    # Get the 3GPP rate matching pattern.

+    rate_matching_pattern,mode = get_3GPP_rate_matching_pattern(K, N, E)

+

+    # Get the 3GPP sequence pattern.  

+    Q_N = get_3GPP_sequence_pattern(N)

+    

+    # Get the 3GPP information bit pattern.

+    info_bit_pattern = get_3GPP_info_bit_pattern(K, Q_N, rate_matching_pattern, mode)

+    

+    # Initialize scrambler

+    scrambler = Scrambler(NidCell, Lmax)

+    f_tilde_scrambled = scrambler.get_3GPP_2nd_scramble_s_seq(f_tilde, ibar_SSB) # scramble 864 LLRs 

+    

+    # Perform Distributed-CRC-and-Known-bit-Aided polar decoding.     

+    a_hat = DCKA_polar_decoder(f_tilde_scrambled, crc_polynomial_pattern, crc_interleaver_pattern, info_bit_pattern, rate_matching_pattern, mode, list_size, min_sum, P2)  

+    

+    if (a_hat == 0):

+        print "no MIB"

+    else:

+        cellSfn = 1     # System frame number for cell

+        scrambled = scrambler.get_3GPP_1st_scramble_s_seq(cellSfn, a_hat)   # Get scrambled hard coded bits

+        out = get_3GPP_PBCH_payload_intlv(scrambled)    # Get interleaved payload

+        

+        MIB_Parser(out, Lmax) # Parse MIB field messages from bit sequence

+