Skip to content

Commit 64bf35c

Browse files
committedOct 28, 2012
First release of dmp tool
1 parent 0d81d4e commit 64bf35c

File tree

1 file changed

+211
-0
lines changed

1 file changed

+211
-0
lines changed
 

‎dmp

+211
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,211 @@
1+
#!/usr/bin/env python
2+
3+
# Author: Yann Sionneau <yann.sionneau@gmail.com>
4+
# This is a first release supporting only HTML rendering
5+
# It is originally designed to be used with milkymist-mmu-simulation project
6+
# Which is a simulation of LatticeMico32 CPU using ISim simulator
7+
8+
import sys, argparse, pydot
9+
10+
parser = argparse.ArgumentParser(description='Draw Me a Pipeline')
11+
parser.add_argument('datafile')
12+
parser.add_argument('--tofile', default=None)
13+
parser.add_argument('--starttime', default=0)
14+
parser.add_argument('--endtime', default=10)
15+
parser.add_argument('--renderengine', default='html', choices=['html', 'dot'])
16+
17+
args = parser.parse_args()
18+
19+
print "Using renderer: " + str(args.renderengine)
20+
print "Start time: " + str(args.starttime)
21+
print "End time: " + str(args.endtime)
22+
23+
if args.tofile == None:
24+
if args.renderengine == 'html':
25+
result_file_name = 'output.html'
26+
elif args.renderengine == 'dot':
27+
result_file_name = 'output.png'
28+
else:
29+
print 'Fatal error: render engine should be either HTML or DOT'
30+
sys.exit(1)
31+
else:
32+
result_file_name = args.tofile
33+
34+
input = open(args.datafile, 'r')
35+
36+
class LogLineParser:
37+
38+
def __init__(self,line):
39+
self.line = line
40+
# timestamp is number between [ ]
41+
self.timestamp = int(line[1:].split(']')[0])
42+
# action is the words after '[] '
43+
self.action = line.split(']')[1][1:]
44+
45+
def getAction(self):
46+
return self.action
47+
48+
def getTimestamp(self):
49+
return self.timestamp
50+
51+
def __str__(self):
52+
return self.line
53+
54+
class Pipeline:
55+
def __init__(self):
56+
self.pc = {}
57+
self.assignments = {}
58+
self.stages = ()
59+
self.timestamp = None
60+
self.empty = True
61+
62+
self.assignments['A'] = {}
63+
self.assignments['F'] = {}
64+
self.assignments['D'] = {}
65+
self.assignments['X'] = {}
66+
self.assignments['M'] = {}
67+
self.assignments['W'] = {}
68+
69+
self.pc['PC_A'] = ''
70+
self.pc['PC_F'] = ''
71+
self.pc['PC_D'] = ''
72+
self.pc['PC_X'] = ''
73+
self.pc['PC_M'] = ''
74+
self.pc['PC_W'] = ''
75+
76+
def addInformation(self, logline):
77+
78+
if self.timestamp != None and self.timestamp != logline.getTimestamp():
79+
print "ERROR : Trying to add information gathered at different timestamps in the same pipeline"
80+
sys.exit(1)
81+
else:
82+
self.timestamp = logline.getTimestamp()
83+
84+
if self.isEmpty():
85+
self.empty = False
86+
87+
words = logline.getAction().split()
88+
first_word = words[0]
89+
if first_word.startswith('PC_') and len(words) == 2:
90+
address = words[1]
91+
self.addPC(first_word, address)
92+
93+
if len(words) == 4 and words[1] == "<=":
94+
stage_name = words[0].replace(']','').replace('[','')
95+
signal_name = words[1]
96+
value = words[3]
97+
self.addAssignment(stage_name, signal_name, value)
98+
99+
100+
def addPC(self, pc_name, address):
101+
self.pc[pc_name] = address
102+
103+
def addAssignment(self, stage_name, signal_name, value):
104+
self.assignments[stage_name][signal_name] = value
105+
106+
def isEmpty(self):
107+
return self.empty
108+
109+
def my_sort(string):
110+
dict = {}
111+
dict["PC_A"] = 0
112+
dict["PC_F"] = 1
113+
dict["PC_D"] = 2
114+
dict["PC_X"] = 3
115+
dict["PC_M"] = 4
116+
dict["PC_W"] = 5
117+
return dict['PC_' + string]
118+
119+
def render_html(pipeline):
120+
stages = sorted(pipeline.assignments.keys(), key=my_sort)
121+
122+
global rowcount
123+
global html_output
124+
if (rowcount % 2) == 1:
125+
html_output += "<tr bgcolor=\"silver\" valign=\"top\">\n"
126+
else:
127+
html_output += "<tr valign=\"top\">\n"
128+
129+
html_output += "<td valign=\"middle\">t = " + str(pipeline.timestamp) + " ns</td>"
130+
131+
for stage in stages:
132+
html_output += "<td>" + pipeline.pc['PC_' + stage]
133+
if len(pipeline.assignments) > 0:
134+
html_output += "<br><br>"
135+
for varname in pipeline.assignments[stage].iterkeys():
136+
print varname + " = " + pipeline.assignments[stage][varname] + "<br>"
137+
html_output += "</td>\n"
138+
139+
html_output += "</tr>\n"
140+
141+
rowcount += 1
142+
143+
def finalyze_drawing(pipeline):
144+
145+
result = open(result_file_name, "w")
146+
result.write("""<html>
147+
<body>
148+
<table border="1">
149+
<tr>
150+
<th>Time</th>
151+
""")
152+
stages = sorted(pipeline.assignments.keys(), key=my_sort)
153+
154+
for stage in stages:
155+
result.write("<th>" + stage + "</th>\n")
156+
157+
result.write("</tr>\n")
158+
159+
result.write(html_output)
160+
161+
result.write("""</table>
162+
</body>
163+
</html>""")
164+
165+
def render_dot(pipeline):
166+
print "Dot renderer is not implemented yet!"
167+
168+
def generateDrawing(pipeline):
169+
if str(args.renderengine) == 'html':
170+
render_html(pipeline)
171+
elif str(args.renderengine) == 'dot':
172+
render_dot(pipeline)
173+
else:
174+
print "Rendering engine " + str(args.renderengine) + " not supported"
175+
sys.exit(1)
176+
177+
currentTime = 0
178+
previousPipeline = Pipeline()
179+
currentPipeline = Pipeline()
180+
rowcount = 0
181+
html_output = ''
182+
183+
for line in input:
184+
logline = LogLineParser(line)
185+
186+
if currentTime == 0:
187+
previousTime = logline.getTimestamp()
188+
else:
189+
previousTime = currentTime
190+
191+
currentTime = logline.getTimestamp()
192+
193+
if currentTime < int(args.starttime):
194+
continue
195+
196+
if currentTime != previousTime:
197+
if not currentPipeline.isEmpty():
198+
generateDrawing(currentPipeline)
199+
previousPipeline = currentPipeline
200+
currentPipeline = Pipeline()
201+
if currentTime > int(args.endtime):
202+
break
203+
204+
currentPipeline.addInformation(logline)
205+
206+
# print logline.getAction()
207+
208+
209+
finalyze_drawing(previousPipeline)
210+
211+
print "result has been written to " + result_file_name

0 commit comments

Comments
 (0)