-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathplot.py
144 lines (123 loc) · 5.88 KB
/
plot.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
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
135
136
137
138
139
140
141
142
143
144
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap, LinearSegmentedColormap
import glob, os
## SETTING #########################################################
# This code visualizes a designated FPGA composition with the given
# tile information extracted from Vivado.
# - case 0: if MAIN_TYPES is not empty, the code draws map for only MAIN_TYPES,
# - case 1: if MAIN_TYPES is empty and IS_CONCISE is True, the code draws concise version of map,
# - case 2: if MAIN_TYPES is empty and IS_CONCISE is False, the code draws detailed version.
# MAIN_TYPES = []
MAIN_TYPES = ["BRAM", "CLB", "CLK", "DSP", "INT", "IO", "PS"]
IS_CONCISE = True
BOARD_NAME = "vc707"
FILE_PATH = "./data/" + BOARD_NAME # tile information
pd.set_option('display.max_columns', None) # print all cols
####################################################################
# In concise version, INT_R and INT_L are considered INT,
# CLBLL_L, CLBLL_R are considered CLBLL,
# CLBLM_L, CLBLM_R are considered CLBLM.
# It cuts "Types" from the first "_"
def genConcise(tile_df, deviceMat, rowIDs, colIDs):
tile_df['Type_concise'] = tile_df['Type'].\
apply(lambda r: r.split('_')[0] if len(r.split('_')) > 1 else r)
# assign unique id to each tile type
tile_df['id_concise'] = tile_df["Type_concise"].astype('category').cat.codes
null_df = tile_df[tile_df['Type'] == "empty"]
deviceMat[rowIDs, colIDs] = tile_df['id_concise']
numIDs = len(tile_df['id_concise'].unique())
types = []
for id_i in range(numIDs):
id_df = tile_df[tile_df['id_concise'] == id_i]
# peek 1st row's val, list all types in concise ver.
type_concise = id_df['Type_concise'].iloc[0]
types.append(type_concise)
nullID = null_df['id_concise'].iloc[0] # peek 1st row's val, finds what's id for "empty"
return (deviceMat, numIDs, types, nullID)
# In verbose version, the code draws a map for all tile types.
def genVerbose(tile_df, deviceMat, rowIDs, colIDs):
null_df = tile_df[tile_df['Type'] == "empty"]
deviceMat[rowIDs, colIDs] = tile_df['id']
numIDs = len(tile_df['id'].unique())
types = []
for id_i in range(numIDs):
id_df = tile_df[tile_df['id'] == id_i]
# peek 1st row's val, list all types in verbose ver.
type_verbose = id_df['Type'].iloc[0]
types.append(type_verbose)
nullID = null_df['id'].iloc[0] # peek 1st row's val, finds what's id for "empty"
return (deviceMat, numIDs, types, nullID)
# In mainTypes version, it draws map only for tiles in mailTypes list.
# e.g. if CLB is in mainTypes, CLBLL_L, CLBLL_R, CLBLM_L, CLBLM_R are all considered CLB.
# if CLB is NOT in mainTypes, they are considered "empty"
def genMainTypes(tile_df, mainTypes, deviceMat, rowIDs, colIDs):
tile_df['isMainTile'] = "no" # initialized
tile_df['Main Type'] = tile_df["Type"] # initialized
# print(tile_df)
for elem in mainTypes:
tile_df.loc[tile_df['Type'].str.startswith(elem), "isMainTile"] = "yes"
tile_df.loc[tile_df['Type'].str.startswith(elem), "Main Type"] = elem
tile_df.loc[tile_df['isMainTile'] == "no", "Main Type"] = "empty" # if not main type, empty
tile_df['id_main_type'] = tile_df["Main Type"].astype('category').cat.codes
# print(tile_df)
null_df = tile_df[tile_df['Main Type'] == "empty"]
deviceMat[rowIDs, colIDs] = tile_df['id_main_type']
numIDs = len(tile_df['id_main_type'].unique())
types = []
for id_i in range(numIDs):
id_df = tile_df[tile_df['id_main_type'] == id_i]
# peek 1st row's val, list all types in main types ver.
type_concise = id_df['Main Type'].iloc[0]
types.append(type_concise)
nullID = null_df['id_main_type'].iloc[0] # peek 1st row's val, finds what's id for "empty"
return (deviceMat, numIDs, types, nullID)
# Draws 2D grid, "empty" tiles are grey
def matShow(data, numIDs, nullID, types):
cmap = plt.get_cmap('jet', numIDs)
cmaplist = [cmap(i) for i in range(cmap.N)]
cmaplist[nullID] = (.5, .5, .5, 1.0) # force "empty" tile to be grey
# create the new map
cmap = LinearSegmentedColormap.from_list('Custom cmap', cmaplist, cmap.N)
# set limits .5 outside true range
mat = plt.matshow(data, cmap=cmap, vmin=np.min(data) - .5, vmax=np.max(data) + .5)
# plt.colorbar(mat, ticks=types)
cbar = plt.colorbar(mat, ticks=np.arange(np.min(data), np.max(data) + 1))
# cbar.set_ticks([])
cbar.ax.set_yticklabels(types) # labels
plt.axis('off')
def main():
all_files = glob.glob(FILE_PATH + "*.csv")
each_file_df = (pd.read_csv(f) for f in all_files)
concatenated_df = pd.concat(each_file_df, ignore_index=True)
tile_df = concatenated_df
# tile_df = pd.read_csv(csvFileName)
rowMax = tile_df['Row'].max()
colMax = tile_df['Col'].max()
tile_df = tile_df.drop('Sites', 1)
tile_df = tile_df.drop('Cells', 1)
# print(rowMax)
# print(colMax)
# fill NULL as "empty"
tile_df['Type'] = tile_df['Type'].fillna('empty')
# assign unique id to each tile type
tile_df['id'] = tile_df["Type"].astype('category').cat.codes
rowIDs = tile_df['Row']
colIDs = tile_df['Col']
# Creates 2d array for plot.
# deviceMat[row][col] value is id for the tile in (row,col) location.
# Each tile in 2d array is colored with different color,
# and the "empty" tile type is colored grey
deviceMat = np.zeros((rowIDs.max() + 1, colIDs.max() + 1))
if(len(MAIN_TYPES) == 0):
if(IS_CONCISE):
(deviceMat, numIDs, types, nullID) = genConcise(tile_df, deviceMat, rowIDs, colIDs)
else:
(deviceMat, numIDs, types, nullID) = genVerbose(tile_df, deviceMat, rowIDs, colIDs)
else:
(deviceMat, numIDs, types, nullID) = genMainTypes(tile_df, MAIN_TYPES, deviceMat, rowIDs, colIDs)
matShow(deviceMat, numIDs, nullID, types)
plt.show()
if __name__ == '__main__':
main()