start code-gen for mux cells
[pinmux.git] / src / parse.py
1 import math
2 import os.path
3
4
5 def missing_numbers(num_list):
6 original_list = [x for x in range(num_list[0], num_list[-1] + 1)]
7 num_list = set(num_list)
8 return (list(num_list ^ set(original_list)))
9
10
11 class Parse(object):
12 # == Parameters == #
13 N_MUX = 1 # number of selection lines for the mux per io
14 N_IO = 0
15 N_MUX_IO = 0
16 ADDR_WIDTH = 64 # TODO parameterise
17 PADDR_WIDTH = 32 # TODO parameterise
18 DATA_WIDTH = 64 # TODO parameterise
19 # ================ #
20
21 def __init__(self, pth=None, verify=True):
22
23 max_io = 0
24 self.muxed_cells = []
25 self.muxed_cells_width = []
26 self.muxed_cells_bank = []
27 self.dedicated_cells = []
28 self.pinnumbers = []
29 self.bankwidths = {}
30 self.banksize = {}
31 self.bankstart = {}
32
33 fname = 'pinspec.txt'
34 if pth:
35 fname = os.path.join(pth, fname)
36 with open(fname) as bankwidths:
37 for lineno, line in enumerate(bankwidths):
38 line1 = line[:-1].split('\t')
39 self.bankwidths[line1[0]] = int(line1[3])
40 self.banksize[line1[0]] = int(line1[2])
41 self.bankstart[line1[0]] = int(line1[1])
42
43 # == capture the number of IO cells required == #
44 fname = 'pinmap.txt'
45 if pth:
46 fname = os.path.join(pth, fname)
47 with open(fname) as pinmapfile:
48 for lineno, line in enumerate(pinmapfile):
49 line1 = line[:-1].split('\t')
50 if len(line1) <= 3:
51 continue
52 self.pinnumbers.append(int(line1[0]))
53 self.muxed_cells_bank.append(line1[1])
54 self.muxed_cells_width.append(int(line1[2]))
55 # XXX TODO: dedicated pins in separate file
56 #if len(line1) == 2: # dedicated
57 # self.dedicated_cells.append(line1)
58 #else:
59 for i in range(3, len(line1)):
60 # XXX HORRIBLE HACK!!
61 if line1[i].startswith('pwm'):
62 line1[i] = 'pwm%s_out' % line1[i][4:]
63 line1 = [line1[0]] + line1[3:]
64 print "line", line1
65 self.muxed_cells.append(line1)
66
67 self.pinnumbers = sorted(self.pinnumbers)
68
69 if verify:
70 self.do_checks()
71
72 #self.cell_bitwidth = self.get_cell_bit_widths()
73
74 # == user info after parsing ================= #
75 self.N_IO = len(self.dedicated_cells) + len(self.muxed_cells)
76 print("Max number of IO: " + str(self.N_IO))
77 #print("Muxer bit width: " + str(self.cell_bitwidth))
78 print("Muxed IOs: " + str(len(self.muxed_cells)))
79 print("Dedicated IOs: " + str(len(self.dedicated_cells)))
80 #sys.exit(0)
81
82 def do_checks(self):
83 """ Multiple checks to see if the user has not screwed up
84 """
85 missing_pins = missing_numbers(self.pinnumbers)
86
87 # Check-1: ensure no pin is present in both muxed and dedicated pins
88 for muxcell in self.muxed_cells:
89 for dedcel in self.dedicated_cells:
90 if dedcel[1] in muxcell:
91 print("ERROR: " + str(dedcel[1]) + " present \
92 in dedicated & muxed lists")
93 exit(1)
94
95 # Check-2: if pin numbering is consistent:
96 if missing_pins:
97 print("ERROR: Following pins have no assignment: " +
98 str(missing_numbers(self.pinnumbers)))
99 exit(1)
100 unique = set(self.pinnumbers)
101 duplicate = False
102 for each in unique:
103 count = self.pinnumbers.count(each)
104 if count > 1:
105 print("ERROR: Multiple assignment for pin: " + str(each))
106 duplicate = True
107 if duplicate:
108 exit(1)
109
110 # Check-3: confirm if N_* matches the instances in the pinmap
111 # ============================================================== #
112
113 # TODO
114
115 def get_max_cell_bitwidth(self):
116 max_num_cells = 0
117 for cell in self.muxed_cells:
118 print cell
119 max_num_cells = max(len(cell) - 1, max_num_cells)
120 return int(math.log(max_num_cells + 1, 2))
121
122 def get_muxwidth(self, cellnum):
123 return self.muxed_cells_width[int(cellnum)]
124
125
126 if __name__ == '__main__':
127 p = Parse()
128 print (p.N_IO)