diff --git a/compiler/characterizer/lib.py b/compiler/characterizer/lib.py
index 93592882..a38ecd93 100644
--- a/compiler/characterizer/lib.py
+++ b/compiler/characterizer/lib.py
@@ -527,7 +527,7 @@ class lib:
current_time = datetime.date.today()
datasheet.write("{0},{1},{2},{3},{4},{5},{6},{7},{8},{9},{10},{11},{12},{13},{14},{15},".format(
- "sram_{0}_{1}_{2}".format(OPTS.word_size, OPTS.num_words, OPTS.tech_name),
+ OPTS.output_name,
OPTS.num_words,
OPTS.num_banks,
OPTS.num_rw_ports,
diff --git a/compiler/datasheet/datasheet_gen.py b/compiler/datasheet/datasheet_gen.py
index ad14801b..24bc3953 100644
--- a/compiler/datasheet/datasheet_gen.py
+++ b/compiler/datasheet/datasheet_gen.py
@@ -16,34 +16,34 @@ import csv
import datasheet
import table_gen
-
-def process_name(corner):
- """
- Expands the names of the characterization corner types into something human friendly
- """
- if corner == "TS":
- return "Typical - Slow"
- if corner == "TT":
- return "Typical - Typical"
- if corner == "TF":
- return "Typical - Fast"
-
- if corner == "SS":
- return "Slow - Slow"
- if corner == "ST":
- return "Slow - Typical"
- if corner == "SF":
- return "Slow - Fast"
-
- if corner == "FS":
- return "Fast - Slow"
- if corner == "FT":
- return "Fast - Typical"
- if corner == "FF":
- return "Fast - Fast"
-
- else:
- return "custom"
+# def process_name(corner):
+# """
+# Expands the names of the characterization corner types into something human friendly
+# """
+# if corner == "TS":
+# return "Typical - Slow"
+# if corner == "TT":
+# return "Typical - Typical"
+# if corner == "TF":
+# return "Typical - Fast"
+#
+# if corner == "SS":
+# return "Slow - Slow"
+# if corner == "ST":
+# return "Slow - Typical"
+# if corner == "SF":
+# return "Slow - Fast"
+#
+# if corner == "FS":
+# return "Fast - Slow"
+# if corner == "FT":
+# return "Fast - Typical"
+# if corner == "FF":
+# return "Fast - Fast"
+#
+# else:
+# return "custom"
+#
def parse_characterizer_csv(f, pages):
@@ -351,8 +351,7 @@ def parse_characterizer_csv(f, pages):
sheet.description.append(str(element))
break
- new_sheet.corners_table.add_row([PROC, process_name(
- PROC), VOLT, TEMP, LIB_NAME.replace(OUT_DIR, '').replace(NAME, '')])
+ new_sheet.corners_table.add_row([PROC, VOLT, TEMP, LIB_NAME.replace(OUT_DIR, '').replace(NAME, '')])
new_sheet.dlv_table.add_row(
['.lib', 'Synthesis models', '{1}'.format(LIB_NAME, LIB_NAME.replace(OUT_DIR, ''))])
@@ -371,9 +370,8 @@ def parse_characterizer_csv(f, pages):
new_sheet.corners_table = table_gen.table_gen("corners")
new_sheet.corners_table.add_row(
- ['Corner Name', 'Process', 'Power Supply', 'Temperature', 'Library Name Suffix'])
- new_sheet.corners_table.add_row([PROC, process_name(
- PROC), VOLT, TEMP, LIB_NAME.replace(OUT_DIR, '').replace(NAME, '')])
+ ['Transistor Type', 'Power Supply', 'Temperature', 'Corner Name'])
+ new_sheet.corners_table.add_row([PROC, VOLT, TEMP, LIB_NAME.replace(OUT_DIR, '').replace(NAME, '')])
new_sheet.operating_table = table_gen.table_gen(
"operating_table")
new_sheet.operating_table.add_row(
@@ -552,7 +550,8 @@ def parse_characterizer_csv(f, pages):
new_sheet.io_table.add_row(['NUM_RW_PORTS', NUM_RW_PORTS])
new_sheet.io_table.add_row(['NUM_R_PORTS', NUM_R_PORTS])
new_sheet.io_table.add_row(['NUM_W_PORTS', NUM_W_PORTS])
- new_sheet.io_table.add_row(['Area (µm2)', AREA])
+ new_sheet.io_table.add_row(
+ ['Area (µm2)', AREA])
class datasheet_gen():
diff --git a/compiler/datasheet/wavedrom.py b/compiler/datasheet/wavedrom.py
deleted file mode 100644
index e8c68c56..00000000
--- a/compiler/datasheet/wavedrom.py
+++ /dev/null
@@ -1,827 +0,0 @@
-#!/usr/bin/python
-# The MIT License (MIT)
-#
-# Copyright (c) 2011-2016 Aliaksei Chapyzhenka
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to deal
-# in the Software without restriction, including without limitation the rights
-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-# copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in
-# all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-# THE SOFTWARE.
-#
-# Translated to Python from original file:
-# https://github.com/drom/wavedrom/blob/master/src/WaveDrom.js
-#
-
-import sys
-import json
-import math
-import waveskin
-
-font_width = 7
-
-lane = {
- "xs" : 20, # tmpgraphlane0.width
- "ys" : 20, # tmpgraphlane0.height
- "xg" : 120, # tmpgraphlane0.x
- "yg" : 0, # head gap
- "yh0" : 0, # head gap title
- "yh1" : 0, # head gap
- "yf0" : 0, # foot gap
- "yf1" : 0, # foot gap
- "y0" : 5, # tmpgraphlane0.y
- "yo" : 30, # tmpgraphlane1.y - y0
- "tgo" : -10, # tmptextlane0.x - xg
- "ym" : 15, # tmptextlane0.y - y0
- "xlabel" : 6, # tmptextlabel.x - xg
- "xmax" : 1,
- "scale" : 1,
- "head" : {},
- "foot" : {}
-}
-
-def genBrick (texts, extra, times) :
-
- R = []
- if len( texts ) == 4 :
- for j in range( times ):
-
- R.append(texts[0])
-
- for i in range ( extra ):
- R.append(texts[1])
-
- R.append(texts[2])
- for i in range ( extra ):
- R.append(texts[3])
-
- return R
-
- if len( texts ) == 1 :
- texts.append(texts[0])
-
- R.append(texts[0])
- for i in range (times * (2 * (extra + 1)) - 1) :
- R.append(texts[1])
- return R
-
-def genFirstWaveBrick (text, extra, times) :
-
- pattern = {
- 'p': ['pclk', '111', 'nclk', '000'],
- 'n': ['nclk', '000', 'pclk', '111'],
- 'P': ['Pclk', '111', 'nclk', '000'],
- 'N': ['Nclk', '000', 'pclk', '111'],
- 'l': ['000'],
- 'L': ['000'],
- '0': ['000'],
- 'h': ['111'],
- 'H': ['111'],
- '1': ['111'],
- '=': ['vvv-2'],
- '2': ['vvv-2'],
- '3': ['vvv-3'],
- '4': ['vvv-4'],
- '5': ['vvv-5'],
- 'd': ['ddd'],
- 'u': ['uuu'],
- 'z': ['zzz']
- }
-
- return genBrick( pattern.get( text, ['xxx'] ) , extra, times );
-
-def genWaveBrick (text, extra, times) :
-
- x1 = {'p':'pclk', 'n':'nclk', 'P':'Pclk', 'N':'Nclk', 'h':'pclk', 'l':'nclk', 'H':'Pclk', 'L':'Nclk'}
- x2 = {'0':'0', '1':'1', 'x':'x', 'd':'d', 'u':'u', 'z':'z', '=':'v', '2':'v', '3':'v', '4':'v', '5':'v' }
- x3 = {'0': '', '1': '', 'x': '', 'd': '', 'u': '', 'z': '', '=':'-2', '2':'-2', '3':'-3', '4':'-4', '5':'-5'}
- y1 = {
- 'p':'0', 'n':'1',
- 'P':'0', 'N':'1',
- 'h':'1', 'l':'0',
- 'H':'1', 'L':'0',
- '0':'0', '1':'1', 'x':'x', 'd':'d', 'u':'u', 'z':'z', '=':'v', '2':'v', '3':'v', '4':'v', '5':'v'}
-
- y2 = {
- 'p': '', 'n': '',
- 'P': '', 'N': '',
- 'h': '', 'l': '',
- 'H': '', 'L': '',
- '0': '', '1': '', 'x': '', 'd': '', 'u': '', 'z': '', '=':'-2', '2':'-2', '3':'-3', '4':'-4', '5':'-5'}
-
- x4 = {
- 'p': '111', 'n': '000',
- 'P': '111', 'N': '000',
- 'h': '111', 'l': '000',
- 'H': '111', 'L': '000',
- '0': '000', '1': '111', 'x': 'xxx', 'd': 'ddd', 'u': 'uuu', 'z': 'zzz',
- '=': 'vvv-2', '2': 'vvv-2', '3': 'vvv-3', '4': 'vvv-4', '5': 'vvv-5'}
-
- x5 = {'p':'nclk', 'n':'pclk', 'P':'nclk', 'N':'pclk'}
- x6 = {'p': '000', 'n': '111', 'P': '000', 'N': '111'}
- xclude = {'hp':'111', 'Hp':'111', 'ln': '000', 'Ln': '000', 'nh':'111', 'Nh':'111', 'pl': '000', 'Pl':'000'}
-
- #atext = text.split()
- atext = text
-
- tmp0 = x4.get(atext[1])
- tmp1 = x1.get(atext[1])
- if tmp1 == None :
- tmp2 = x2.get(atext[1])
- if tmp2 == None :
- # unknown
- return genBrick(['xxx'], extra, times)
- else :
- tmp3 = y1.get(atext[0])
- if tmp3 == None :
- # unknown
- return genBrick(['xxx'], extra, times)
-
- # soft curves
- return genBrick([tmp3 + 'm' + tmp2 + y2[atext[0]] + x3[atext[1]], tmp0], extra, times)
-
- else :
- tmp4 = xclude.get(text)
- if tmp4 != None :
- tmp1 = tmp4
-
- # sharp curves
- tmp2 = x5.get(atext[1])
- if tmp2 == None :
- # hlHL
- return genBrick([tmp1, tmp0], extra, times)
- else :
- # pnPN
- return genBrick([tmp1, tmp0, tmp2, x6[atext[1]]], extra, times)
-
-def parseWaveLane (text, extra) :
-
- R = []
- Stack = text
- Next = Stack[0]
- Stack = Stack[1:]
-
- Repeats = 1
- while len(Stack) and ( Stack[0] == '.' or Stack[0] == '|' ): # repeaters parser
- Stack=Stack[1:]
- Repeats += 1
-
- R.extend(genFirstWaveBrick(Next, extra, Repeats))
-
- while len(Stack) :
- Top = Next
- Next = Stack[0]
- Stack = Stack[1:]
- Repeats = 1
- while len(Stack) and ( Stack[0] == '.' or Stack[0] == '|' ) : # repeaters parser
- Stack=Stack[1:]
- Repeats += 1
- R.extend(genWaveBrick((Top + Next), extra, Repeats))
-
- for i in range( lane['phase'] ):
- R = R[1:]
- return R
-
-def parseWaveLanes (sig) :
-
- def data_extract (e) :
- tmp = e.get('data')
- if tmp == None : return None
- if is_type_str (tmp) : tmp=tmp.split()
- return tmp
-
- content = []
- for sigx in sig :
- lane['period'] = sigx.get('period',1)
- lane['phase'] = int( sigx.get('phase',0 ) * 2 )
- sub_content=[]
- sub_content.append( [sigx.get('name',' '), sigx.get('phase',0 ) ] )
- sub_content.append( parseWaveLane( sigx['wave'], int(lane['period'] * lane['hscale'] - 1 ) ) if sigx.get('wave') else None )
- sub_content.append( data_extract(sigx) )
- content.append(sub_content)
-
- return content
-
-def findLaneMarkers (lanetext) :
-
- lcount = 0
- gcount = 0
- ret = []
- for i in range( len( lanetext ) ) :
- if lanetext[i] == 'vvv-2' or lanetext[i] == 'vvv-3' or lanetext[i] == 'vvv-4' or lanetext[i] == 'vvv-5' :
- lcount += 1
- else :
- if lcount !=0 :
- ret.append(gcount - ((lcount + 1) / 2))
- lcount = 0
-
- gcount += 1
-
- if lcount != 0 :
- ret.append(gcount - ((lcount + 1) / 2))
-
- return ret
-
-def renderWaveLane (root, content, index) :
-
- xmax = 0
- xgmax = 0
- glengths = []
- svgns = 'http://www.w3.org/2000/svg'
- xlinkns = 'http://www.w3.org/1999/xlink'
- xmlns = 'http://www.w3.org/XML/1998/namespace'
- for j in range( len(content) ):
- name = content[j][0][0]
- if name : # check name
- g = [
- 'g',
- {
- 'id': 'wavelane_' + str(j) + '_' + str(index),
- 'transform': 'translate(0,' + str(lane['y0'] + j * lane['yo']) + ')'
- }
- ]
- root.append(g)
- title = [
- 'text',
- {
- 'x': lane['tgo'],
- 'y': lane['ym'],
- 'class': 'info',
- 'text-anchor': 'end',
- 'xml:space': 'preserve'
- },
- ['tspan', name]
- ]
- g.append(title)
-
- glengths.append( len(name) * font_width + font_width )
-
- xoffset = content[j][0][1]
- xoffset = math.ceil(2 * xoffset) - 2 * xoffset if xoffset > 0 else -2 * xoffset
- gg = [
- 'g',
- {
- 'id': 'wavelane_draw_' + str(j) + '_' + str(index),
- 'transform': 'translate(' + str( xoffset * lane['xs'] ) + ', 0)'
- }
- ]
- g.append(gg)
-
- if content[j][1] :
- for i in range( len(content[j][1]) ) :
- b = [
- 'use',
- {
- #'id': 'use_' + str(i) + '_' + str(j) + '_' + str(index),
- 'xmlns:xlink':xlinkns,
- 'xlink:href': '#' + str( content[j][1][i] ),
- 'transform': 'translate(' + str(i * lane['xs']) + ')'
- }
- ]
- gg.append(b)
-
- if content[j][2] and len(content[j][2]) :
- labels = findLaneMarkers(content[j][1])
- if len(labels) != 0 :
- for k in range( len(labels) ) :
- if content[j][2] and k < len(content[j][2]) :
- title = [
- 'text',
- {
- 'x': int(labels[k]) * lane['xs'] + lane['xlabel'],
- 'y': lane['ym'],
- 'text-anchor': 'middle',
- 'xml:space': 'preserve'
- },
- ['tspan',content[j][2][k]]
- ]
- gg.append(title)
-
-
- if len(content[j][1]) > xmax :
- xmax = len(content[j][1])
-
- lane['xmax'] = xmax
- lane['xg'] = xgmax + 20
- return glengths
-
-def renderMarks (root, content, index) :
-
- def captext ( g, cxt, anchor, y ) :
-
- if cxt.get(anchor) and cxt[anchor].get('text') :
- tmark = [
- 'text',
- {
- 'x': float( cxt['xmax'] ) * float( cxt['xs'] ) / 2,
- 'y': y,
- 'text-anchor': 'middle',
- 'fill': '#000',
- 'xml:space': 'preserve'
- }, cxt[anchor]['text']
- ]
- g.append(tmark)
-
- def ticktock ( g, cxt, ref1, ref2, x, dx, y, length ) :
- L = []
-
- if cxt.get(ref1) == None or cxt[ref1].get(ref2) == None :
- return
-
- val = cxt[ref1][ref2]
- if is_type_str( val ) :
- val = val.split()
- elif type( val ) is int :
- offset = val
- val = []
- for i in range ( length ) :
- val.append(i + offset)
-
- if type( val ) is list :
- if len( val ) == 0 :
- return
- elif len( val ) == 1 :
- offset = val[0]
- if is_type_str(offset) :
- L = val
- else :
- for i in range ( length ) :
- L[i] = i + offset
-
- elif len( val ) == 2:
- offset = int(val[0])
- step = int(val[1])
- tmp = val[1].split('.')
- if len( tmp ) == 2 :
- dp = len( tmp[1] )
-
- if is_type_str(offset) or is_type_str(step) :
- L = val
- else :
- offset = step * offset
- for i in range( length ) :
- L[i] = "{0:.",dp,"f}".format(step * i + offset)
-
- else :
- L = val
-
- else :
- return
-
- for i in range( length ) :
- tmp = L[i]
- tmark = [
- 'text',
- {
- 'x': i * dx + x,
- 'y': y,
- 'text-anchor': 'middle',
- 'class': 'muted',
- 'xml:space': 'preserve'
- }, str(tmp)
- ]
- g.append(tmark)
-
- mstep = 2 * int(lane['hscale'])
- mmstep = mstep * lane['xs']
- marks = int( lane['xmax'] / mstep )
- gy = len( content ) * int(lane['yo'])
-
- g = ['g', {'id': 'gmarks_' + str(index)}]
- root.insert(0,g)
-
- for i in range( marks + 1):
- gg = [
- 'path',
- {
- 'id': 'gmark_' + str(i) + '_' + str(index),
- 'd': 'm ' + str(i * mmstep) + ',' + '0' + ' 0,' + str(gy),
- 'style': 'stroke:#888;stroke-width:0.5;stroke-dasharray:1,3'
- }
- ]
- g.append( gg )
-
- captext(g, lane, 'head', -33 if lane['yh0'] else -13 )
- captext(g, lane, 'foot', gy + ( 45 if lane['yf0'] else 25 ) )
-
- ticktock( g, lane, 'head', 'tick', 0, mmstep, -5, marks + 1)
- ticktock( g, lane, 'head', 'tock', mmstep / 2, mmstep, -5, marks)
- ticktock( g, lane, 'foot', 'tick', 0, mmstep, gy + 15, marks + 1)
- ticktock( g, lane, 'foot', 'tock', mmstep / 2, mmstep, gy + 15, marks)
-
-def renderArcs (root, source, index, top) :
-
- Stack = []
- Edge = {'words': [], 'frm': 0, 'shape': '', 'to': 0, 'label': ''}
- Events = {}
- svgns = 'http://www.w3.org/2000/svg'
- xmlns = 'http://www.w3.org/XML/1998/namespace'
-
- if source :
- for i in range (len (source) ) :
- lane['period'] = source[i].get('period',1)
- lane['phase'] = int( source[i].get('phase',0 ) * 2 )
- text = source[i].get('node')
- if text:
- Stack = text
- pos = 0
- while len( Stack ) :
- eventname = Stack[0]
- Stack=Stack[1:]
- if eventname != '.' :
- Events[eventname] = {
- 'x' : str( int( float( lane['xs'] ) * (2 * pos * lane['period'] * lane['hscale'] - lane['phase'] ) + float( lane['xlabel'] ) ) ),
- 'y' : str( int( i * lane['yo'] + lane['y0'] + float( lane['ys'] ) * 0.5 ) )
- }
- pos += 1
-
- gg = [ 'g', { 'id' : 'wavearcs_' + str( index ) } ]
- root.append(gg)
-
- if top.get('edge') :
- for i in range( len ( top['edge'] ) ) :
- Edge['words'] = top['edge'][i].split()
- Edge['label'] = top['edge'][i][len(Edge['words'][0]):]
- Edge['label'] = Edge['label'][1:]
- Edge['frm'] = Edge['words'][0][0]
- Edge['to'] = Edge['words'][0][-1]
- Edge['shape'] = Edge['words'][0][1:-1]
- frm = Events[Edge['frm']]
- to = Events[Edge['to']]
- gmark = [
- 'path',
- {
- 'id': 'gmark_' + Edge['frm'] + '_' + Edge['to'],
- 'd': 'M ' + frm['x'] + ',' + frm['y'] + ' ' + to['x'] + ',' + to['y'],
- 'style': 'fill:none;stroke:#00F;stroke-width:1'
- }
- ]
- gg.append(gmark)
- dx = float( to['x'] ) - float( frm['x'] )
- dy = float( to['y'] ) - float( frm['y'] )
- lx = (float(frm['x']) + float(to['x'])) / 2
- ly = (float(frm['y']) + float(to['y'])) / 2
- pattern = {
- '~' : {'d': 'M ' + frm['x'] + ',' + frm['y'] + ' c ' + str(0.7 * dx) + ', 0 ' + str(0.3 * dx) + ', ' + str(dy) + ' ' + str(dx) + ', ' + str(dy) },
- '-~' : {'d': 'M ' + frm['x'] + ',' + frm['y'] + ' c ' + str(0.7 * dx) + ', 0 ' + str(dx) + ', ' + str(dy) + ' ' + str(dx) + ', ' + str(dy) },
- '~-' : {'d': 'M ' + frm['x'] + ',' + frm['y'] + ' c ' + '0' + ', 0 ' + str(0.3 * dx) + ', ' + str(dy) + ' ' + str(dx) + ', ' + str(dy) },
- '-|' : {'d': 'm ' + frm['x'] + ',' + frm['y'] + ' ' + str(dx) + ',0 0,' + str(dy)},
- '|-' : {'d': 'm ' + frm['x'] + ',' + frm['y'] + ' 0,' + str(dy) + ' ' + str(dx) + ',0'},
- '-|-' : {'d': 'm ' + frm['x'] + ',' + frm['y'] + ' ' + str(dx / 2) + ',0 0,' + str(dy) + ' ' + str(dx / 2) + ',0'},
- '->' : {'style': 'marker-end:url(#arrowhead);stroke:#0041c4;stroke-width:1;fill:none'},
- '~>' : {'style': 'marker-end:url(#arrowhead);stroke:#0041c4;stroke-width:1;fill:none', 'd': 'M ' + frm['x'] + ',' + frm['y'] + ' ' + 'c ' + str(0.7 * dx) + ', 0 ' + str(0.3 * dx) + ', ' + str(dy) + ' ' + str(dx) + ', ' + str(dy)},
- '-~>' : {'style': 'marker-end:url(#arrowhead);stroke:#0041c4;stroke-width:1;fill:none', 'd': 'M ' + frm['x'] + ',' + frm['y'] + ' ' + 'c ' + str(0.7 * dx) + ', 0 ' + str(dx) + ', ' + str(dy) + ' ' + str(dx) + ', ' + str(dy)},
- '~->' : {'style': 'marker-end:url(#arrowhead);stroke:#0041c4;stroke-width:1;fill:none', 'd': 'M ' + frm['x'] + ',' + frm['y'] + ' ' + 'c ' + '0' + ', 0 ' + str(0.3 * dx) + ', ' + str(dy) + ' ' + str(dx) + ', ' + str(dy)},
- '-|>' : {'style': 'marker-end:url(#arrowhead);stroke:#0041c4;stroke-width:1;fill:none', 'd': 'm ' + frm['x'] + ',' + frm['y'] + ' ' + str(dx) + ',0 0,' + str(dy)},
- '|->' : {'style': 'marker-end:url(#arrowhead);stroke:#0041c4;stroke-width:1;fill:none', 'd': 'm ' + frm['x'] + ',' + frm['y'] + ' 0,' + str(dy) + ' ' + str(dx) + ',0'},
- '-|->' : {'style': 'marker-end:url(#arrowhead);stroke:#0041c4;stroke-width:1;fill:none', 'd': 'm ' + frm['x'] + ',' + frm['y'] + ' ' + str(dx / 2) + ',0 0,' + str(dy) + ' ' + str(dx / 2) + ',0'},
- '<->' : {'style': 'marker-end:url(#arrowhead);marker-start:url(#arrowtail);stroke:#0041c4;stroke-width:1;fill:none'},
- '<~>' : {'style': 'marker-end:url(#arrowhead);marker-start:url(#arrowtail);stroke:#0041c4;stroke-width:1;fill:none','d': 'M ' + frm['x'] + ',' + frm['y'] + ' ' + 'c ' + str(0.7 * dx) + ', 0 ' + str(0.3 * dx) + ', ' + str(dy) + ' ' + str(dx) + ', ' + str(dy)},
- '<-~>' : {'style': 'marker-end:url(#arrowhead);marker-start:url(#arrowtail);stroke:#0041c4;stroke-width:1;fill:none','d': 'M ' + frm['x'] + ',' + frm['y'] + ' ' + 'c ' + str(0.7 * dx) + ', 0 ' + str(dx) + ', ' + str(dy) + ' ' + str(dx) + ', ' + str(dy)},
- '<-|>' : {'style': 'marker-end:url(#arrowhead);marker-start:url(#arrowtail);stroke:#0041c4;stroke-width:1;fill:none','d': 'm ' + frm['x'] + ',' + frm['y'] + ' ' + str(dx) + ',0 0,' + str(dy)},
- '<-|->': {'style': 'marker-end:url(#arrowhead);marker-start:url(#arrowtail);stroke:#0041c4;stroke-width:1;fill:none','d': 'm ' + frm['x'] + ',' + frm['y'] + ' ' + str(dx / 2) + ',0 0,' + str(dy) + ' ' + str(dx / 2) + ',0'}
- }
- gmark[1].update( pattern.get( Edge['shape'], { 'style': 'fill:none;stroke:#00F;stroke-width:1' } ) )
-
- if Edge['label']:
- if Edge['shape'] == '-~' :
- lx = float(frm['x']) + (float(to['x']) - float(frm['x'])) * 0.75
- if Edge['shape'] == '~-' :
- lx = float(frm['x']) + (float(to['x']) - float(frm['x'])) * 0.25
- if Edge['shape'] == '-|' :
- lx = float(to['x'])
- if Edge['shape'] == '|-' :
- lx = float(frm['x'])
- if Edge['shape'] == '-~>':
- lx = float(frm['x']) + (float(to['x']) - float(frm['x'])) * 0.75
- if Edge['shape'] == '~->':
- lx = float(frm['x']) + (float(to['x']) - float(frm['x'])) * 0.25
- if Edge['shape'] == '-|>' :
- lx = float(to['x'])
- if Edge['shape'] == '|->' :
- lx = float(frm['x'])
- if Edge['shape'] == '<-~>':
- lx = float(frm['x']) + (float(to['x']) - float(frm['x'])) * 0.75
- if Edge['shape'] =='<-|>' :
- lx = float(to['x'])
-
- lwidth = len( Edge['label'] ) * font_width
- label = [
- 'text',
- {
- 'style': 'font-size:10px;',
- 'text-anchor': 'middle',
- 'xml:space': 'preserve',
- 'x': int( lx ),
- 'y': int( ly + 3 )
- },
- [ 'tspan', Edge['label'] ]
- ]
- underlabel = [
- 'rect',
- {
- 'height': 9,
- 'style': 'fill:#FFF;',
- 'width': lwidth,
- 'x': int( lx - lwidth / 2 ),
- 'y': int( ly - 5 )
- }
- ]
- gg.append(underlabel)
- gg.append(label)
-
- for k in Events:
- if k.islower() :
- if int( Events[k]['x'] ) > 0 :
- lwidth = len( k ) * font_width
- underlabel = [
- 'rect',
- {
- 'x': float( Events[k]['x'] ) - float(lwidth) / 2,
- 'y': int( Events[k]['y'] ) - 4,
- 'height': 8,
- 'width': lwidth,
- 'style': 'fill:#FFF;'
- }
- ]
- gg.append(underlabel)
- label = [
- 'text',
- {
- 'style': 'font-size:8px;',
- 'x': int( Events[k]['x'] ),
- 'y': int( Events[k]['y'] ) + 2,
- 'width': lwidth,
- 'text-anchor': 'middle'
- },
- k
- ]
- gg.append(label)
-
-def parseConfig (source) :
-
- lane['hscale'] = 1
- if lane.get('hscale0') :
- lane['hscale'] = lane['hscale0']
-
- if source and source.get('config') and source.get('config').get('hscale'):
- hscale = round(source.get('config').get('hscale'))
- if hscale > 0 :
- if hscale > 100 : hscale = 100
- lane['hscale'] = hscale
-
- lane['yh0'] = 0
- lane['yh1'] = 0
- if source and source.get('head') :
- lane['head'] = source['head']
- if source.get('head').get('tick',0) == 0 : lane['yh0'] = 20
- if source.get('head').get('tock',0) == 0 : lane['yh0'] = 20
- if source.get('head').get('text') : lane['yh1'] = 46; lane['head']['text'] = source['head']['text']
-
- lane['yf0'] = 0
- lane['yf1'] = 0
- if source and source.get('foot') :
- lane['foot'] = source['foot']
- if source.get('foot').get('tick',0) == 0 : lane['yf0'] = 20
- if source.get('foot').get('tock',0) == 0 : lane['yf0'] = 20
- if source.get('foot').get('text') : lane['yf1'] = 46; lane['foot']['text'] = source['foot']['text']
-
-def rec (tmp, state) :
-
- name = str( tmp[0] )
- delta_x = 25
-
- state['x'] += delta_x
- for i in range( len( tmp ) ) :
- if type( tmp[i] ) is list :
- old_y = state['y']
- rec( tmp[i], state )
- state['groups'].append( {'x':state['xx'], 'y':old_y, 'height':state['y'] - old_y, 'name': state['name'] } )
- elif type( tmp[i] ) is dict :
- state['lanes'].append(tmp[i])
- state['width'].append(state['x'])
- state['y'] += 1
-
- state['xx'] = state['x']
- state['x'] -= delta_x
- state['name'] = name
-
-def insertSVGTemplate (index, parent, source) :
-
- e = waveskin.WaveSkin['default']
-
- if source.get('config') and source.get('config').get('skin') :
- if waveskin.WaveSkin.get( source.get('config').get('skin') ) :
- e = waveskin.WaveSkin[ source.get('config').get('skin') ]
-
- if index == 0 :
- lane['xs'] = int( e[3][1][2][1]['width'] )
- lane['ys'] = int( e[3][1][2][1]['height'] )
- lane['xlabel'] = int( e[3][1][2][1]['x'] )
- lane['ym'] = int( e[3][1][2][1]['y'] )
-
- else :
- e = ['svg', {'id': 'svg', 'xmlns': 'http://www.w3.org/2000/svg', 'xmlns:xlink': 'http://www.w3.org/1999/xlink', 'height': '0'},
- ['g', {'id': 'waves'},
- ['g', {'id': 'lanes'}],
- ['g', {'id': 'groups'}]
- ]
- ]
-
- e[-1][1]['id'] = 'waves_' + str(index)
- e[-1][2][1]['id'] = 'lanes_' + str(index)
- e[-1][3][1]['id'] = 'groups_' + str(index)
- e[1]['id'] = 'svgcontent_' + str(index)
- e[1]['height'] = 0
-
- parent.extend(e)
-
-def renderWaveForm (index, source, output) :
-
- xmax = 0
- root = []
- groups = []
-
- if source.get('signal'):
- insertSVGTemplate(index, output, source)
- parseConfig( source )
- ret = {'x':0, 'y':0, 'xmax':0, 'width':[], 'lanes':[], 'groups':[] }
- rec( source['signal'], ret )
- content = parseWaveLanes(ret['lanes'])
- glengths = renderWaveLane(root, content, index)
- for i in range( len( glengths ) ):
- xmax = max( xmax, ( glengths[i] + ret['width'][i] ) )
- renderMarks(root, content, index)
- renderArcs(root, ret['lanes'], index, source)
- renderGaps(root, ret['lanes'], index)
- renderGroups(groups, ret['groups'], index)
- lane['xg'] = int( math.ceil( float( xmax - lane['tgo'] ) / float(lane['xs'] ) ) ) * lane['xs']
- width = (lane['xg'] + lane['xs'] * (lane['xmax'] + 1) )
- height = len(content) * lane['yo'] + lane['yh0'] + lane['yh1'] + lane['yf0'] + lane['yf1']
- output[1]={
- 'id' :'svgcontent_' + str(index),
- 'xmlns' :"http://www.w3.org/2000/svg",
- 'xmlns:xlink':"http://www.w3.org/1999/xlink",
- 'width' :str(width),
- 'height' :str(height),
- 'viewBox' :'0 0 ' + str(width) + ' ' + str(height),
- 'overflow' :"hidden"
- }
- output[-1][2][1]['transform']='translate(' + str(lane['xg'] + 0.5) + ', ' + str((float(lane['yh0']) + float(lane['yh1'])) + 0.5) + ')'
-
- output[-1][2].extend(root)
- output[-1][3].extend(groups)
-
-def renderGroups (root, groups, index) :
-
- svgns = 'http://www.w3.org/2000/svg',
- xmlns = 'http://www.w3.org/XML/1998/namespace'
-
- for i in range( len( groups ) ) :
- group = [
- 'path',
- {
- 'id': 'group_' + str(i) + '_' + str(index),
- 'd': 'm ' + str( groups[i]['x'] + 0.5 ) + ',' + str( groups[i]['y']* lane['yo'] + 3.5 + lane['yh0'] + lane['yh1'] ) + ' c -3,0 -5,2 -5,5 l 0,' + str( int( groups[i]['height'] * lane['yo'] - 16 ) ) + ' c 0,3 2,5 5,5',
- 'style': 'stroke:#0041c4;stroke-width:1;fill:none'
- }
- ]
- root.append(group)
-
- name = groups[i]['name']
- x = str( int( groups[i]['x'] - 10 ) )
- y = str( int( lane['yo'] * (groups[i]['y'] + (float(groups[i]['height']) / 2)) + lane['yh0'] + lane['yh1'] ) )
- label = [
- ['g',
- {'transform': 'translate(' + x + ',' + y + ')'},
- ['g', {'transform': 'rotate(270)'},
- 'text',
- {
- 'text-anchor': 'middle',
- 'class': 'info',
- 'xml:space' : 'preserve'
- },
- ['tspan',name]
- ]
- ]
- ]
- root.append(label)
-
-def renderGaps (root, source, index) :
-
- Stack = []
- svgns = 'http://www.w3.org/2000/svg',
- xlinkns = 'http://www.w3.org/1999/xlink'
-
- if source:
-
- gg = [
- 'g',
- { 'id': 'wavegaps_' + str(index) }
- ]
-
- for i in range( len( source )):
- lane['period'] = source[i].get('period',1)
- lane['phase'] = int( source[i].get('phase',0 ) * 2 )
-
- g = [
- 'g',
- {
- 'id': 'wavegap_' + str(i) + '_' + str(index),
- 'transform': 'translate(0,' + str(lane['y0'] + i * lane['yo']) + ')'
- }
- ]
- gg.append(g)
-
- if source[i].get('wave'):
- text = source[i]['wave']
- Stack = text
- pos = 0
- while len( Stack ) :
- c = Stack [0]
- Stack = Stack[1:]
- if c == '|' :
- b = [
- 'use',
- {
- 'xmlns:xlink':xlinkns,
- 'xlink:href':'#gap',
- 'transform': 'translate(' + str(int(float(lane['xs']) * ((2 * pos + 1) * float(lane['period']) * float(lane['hscale']) - float(lane['phase'])))) + ')'
- }
- ]
- g.append(b)
- pos += 1
-
- root.append( gg )
-
-def is_type_str( var ) :
- if sys.version_info[0] < 3:
- return type( var ) is str or type( var ) is unicode
- else:
- return type( var ) is str
-
-def convert_to_svg( root ) :
-
- svg_output = ''
-
- if type( root ) is list:
- if len(root) >= 2 and type( root[1] ) is dict:
- if len( root ) == 2 :
- svg_output += '<' + root[0] + convert_to_svg( root[1] ) + '/>\n'
- elif len( root ) >= 3 :
- svg_output += '<' + root[0] + convert_to_svg( root[1] ) + '>\n'
- if len( root ) == 3:
- svg_output += convert_to_svg( root[2] )
- else:
- svg_output += convert_to_svg( root[2:] )
- svg_output += '' + root[0] + '>\n'
- elif type( root[0] ) is list:
- for eleml in root:
- svg_output += convert_to_svg( eleml )
- else:
- svg_output += '<' + root[0] + '>\n'
- for eleml in root[1:]:
- svg_output += convert_to_svg( eleml )
- svg_output += '' + root[0] + '>\n'
- elif type( root ) is dict:
- for elemd in root :
- svg_output += ' ' + elemd + '="' + str(root[elemd]) + '"'
- else:
- svg_output += root
-
- return svg_output
-
-if __name__ == '__main__':
-
- if len( sys.argv ) != 5:
- print ( 'Usage : ' + sys.argv[0] + ' source svg ' )
- exit(1)
-
- if sys.argv[3] != 'svg' :
- print ( 'Error: only SVG format supported.' )
- exit(1)
-
- output=[]
- inputfile = sys.argv[2]
- outputfile = sys.argv[4]
-
- with open(inputfile,'r') as f:
- jinput = json.load(f)
-
- renderWaveForm(0,jinput,output)
- svg_output = convert_to_svg(output)
-
- with open(outputfile,'w') as f:
- f.write( svg_output )