1import struct
2import numpy as np
3# Tools to read the generated pattern files and the hex output files
4
5def readQ31Pattern(r):
6    l = []
7    with open(r, 'r') as f:
8       f.readline()
9       nb = int(f.readline())
10       for i in range(nb):
11          f.readline()
12          # Read the hex and interpret the sign
13          r=int(f.readline(),16)
14          r=struct.unpack('<i', struct.pack('<I',r))[0]
15          l.append(r)
16    l = (1.0*np.array(l)) / 2**31
17    #print(l)
18    return(l)
19
20def readQ15Pattern(r):
21    l = []
22    with open(r, 'r') as f:
23       f.readline()
24       nb = int(f.readline())
25       for i in range(nb):
26          f.readline()
27          # Read the hex and interpret the sign
28          r=int(f.readline(),16)
29          r=struct.unpack('<h', struct.pack('<H',r))[0]
30          l.append(r)
31    l = (1.0*np.array(l)) / 2**15
32    #print(l)
33    return(l)
34
35def hex2float(h):
36    return(struct.unpack('<f', struct.pack('<I', int(h,16)))[0])
37
38def hex2f16(h):
39    return(struct.unpack('<e', struct.pack('<H', int(h,16)))[0])
40
41
42def readF32Pattern(r):
43    l = []
44    with open(r, 'r') as f:
45       f.readline()
46       nb = int(f.readline())
47       for i in range(nb):
48          f.readline()
49          l.append(hex2float(f.readline()))
50    l = (1.0*np.array(l))
51    #print(l)
52    return(l)
53
54def readF16Pattern(r):
55    l = []
56    with open(r, 'r') as f:
57       f.readline()
58       nb = int(f.readline())
59       for i in range(nb):
60          f.readline()
61          l.append(hex2f16(f.readline()))
62    l = (1.0*np.array(l))
63    #print(l)
64    return(l)
65
66# Read the hex and interpret the sign
67def hexToQ31(s):
68   r = int(s,0)
69   r=struct.unpack('<i', struct.pack('<I',r))[0]
70   return(r)
71
72# Read the hex and interpret the sign
73def hexToQ15(s):
74   r = int(s,0)
75   r=struct.unpack('<i', struct.pack('<I',r))[0]
76   return(r)
77
78def readQ31Output(path):
79   sig = np.loadtxt(path, delimiter=',',dtype="int64",converters= {0:hexToQ31})
80   sig = 1.0 * sig / 2**31
81   return(sig)
82
83def readQ15Output(path):
84   sig = np.loadtxt(path, delimiter=',',dtype="int64",converters= {0:hexToQ15})
85   sig = 1.0 * sig / 2**15
86   return(sig)
87
88
89def readF32Output(path):
90   sig = np.loadtxt(path, delimiter=',',dtype="float",converters= {0:hex2float})
91   sig = 1.0 * sig
92   return(sig)
93
94def readF16Output(path):
95   sig = np.loadtxt(path, delimiter=',',dtype="float",converters= {0:hex2f16})
96   sig = 1.0 * sig
97   return(sig)
98
99def SNR(ref,sig):
100  energy = np.dot(ref,np.conj(ref))
101  error = np.dot(ref-sig,np.conj(ref-sig))
102  snr = 10 * np.log10(energy/error)
103  return(snr)