#! /usr/bin/python # ------------------------------------------- # Copyright 2006-2007 Erik Lechak # ------------------------------------------- # lefview is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # lefview is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with Foobar; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA import socket import sys import os HOST = 'localhost' # The remote host PORT = 3666 name = sys.argv[1].split(os.sep)[-1] shapefmt = "shape ? cd @ quads\n" if "mesh" in sys.argv: shapefmt = "shape ? cd @ quads mesh\n" if "fog" in sys.argv: fog = "fog 0.2 1 10" else: fog="" layers={ "METAL1" : (3,4, (100,120,100) ), "METAL2" : (5,6, (80,100,150) ), "METAL3" : (7,8, (255,255,0) ), "METAL4" : (1,2, (255,0,0) ), "METAL5" : (1,2, (255,0,0) ), "METAL6" : (1,2, (255,0,0) ), "METAL7" : (1,2, (255,0,0) ), "METAL8" : (1,2, (255,0,0) ), "CONT" : (1.01,3, (100,50,255) ), "VIA12" : (4,5, (255,255,0) ), "VIA23" : (6,7, (255,255,0) ), "VIA34" : (1,2, (255,0,0) ), "POLY1" : (1,2, (0,0,255) ), "POLY2" : (1,2, (255,0,0) ), "POLY3" : (1,2, (255,0,0) ), "PDIFF" : (0,1, (255,0,0) ), "NDIFF" : (0,1, (0,255,0) ), } layout=''' cd / window %s cd @ bind "close" forward bind "1 mouse motion" rotate_selected bind "3 mouse motion" move_selected bind "2 mouse motion" ascale_selected view v cd @ bounds -20 20 -20 20 -100 100 origin dd %s light L cd @ ambient 170 170 170 diffuse 200 200 200 specular 200 200 200 position 0 0 30 cd .. diagram layout cd @ bind "1 mouse press" select cd .. ''' # Connect to batd instance # The same port as used by the server s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((HOST,PORT)) # send the layout s.send(layout % (name,fog)) # open lef file #f = file(sys.argv[1]) f = file(sys.argv[1]) vertfmt = " vertex %s %s %f %s %s %f %s %s %f %s %s %f\n" def parsePin(f , name): layer = "" layer_prop=None if not name: dname = "?" else: dname = name s.send("diagram %s cd @\n" % dname) if name: s.send('bind "1 mouse press" forward\n') while(1): line = getLine(f) if not line: break if line.startswith("END"): n = "" try: n = line.split()[1].strip() except: if not name: s.send("cd ..\n") break if n == name: s.send("cd ..\n") break elif line.startswith("LAYER"): layer = line.split()[1].strip() layer_prop = layers[layer] #print " ", layer elif line.startswith("RECT"): v= line.split() s.send(shapefmt) s.send( " rgb " + str(layer_prop[2]) ) #top s.send( " normal 0 0 1 0 0 1 0 0 1 0 0 1\n") d=( v[1], v[2], layer_prop[1], v[1], v[4], layer_prop[1], v[3], v[4], layer_prop[1], v[3], v[2], layer_prop[1]) s.send(vertfmt % d) #bottom s.send( " normal 0 0 -1 0 0 -1 0 0 -1 0 0 -1\n") d=( v[1], v[2], layer_prop[0], v[1], v[4], layer_prop[0], v[3], v[4], layer_prop[0], v[3], v[2], layer_prop[0]) s.send(vertfmt % d) #side1 s.send( " normal -1 0 0 -1 0 0 -1 0 0 -1 0 0\n") d=( v[1], v[2], layer_prop[1], v[1], v[4], layer_prop[1], v[1], v[4], layer_prop[0], v[1], v[2], layer_prop[0]) s.send(vertfmt % d) #side2 s.send( " normal 1 0 0 1 0 0 1 0 0 1 0 0\n") d=( v[3], v[2], layer_prop[1], v[3], v[4], layer_prop[1], v[3], v[4], layer_prop[0], v[3], v[2], layer_prop[0]) s.send(vertfmt % d) #side3 s.send( " normal 0 1 0 0 1 0 0 1 0 0 1 0\n") d=( v[1], v[4], layer_prop[1], v[3], v[4], layer_prop[1], v[3], v[4], layer_prop[0], v[1], v[4], layer_prop[0]) s.send(vertfmt % d) #side4 s.send( " normal 0 -1 0 0 -1 0 0 -1 0 0 -1 0\n") d=( v[1], v[2], layer_prop[1], v[3], v[2], layer_prop[1], v[3], v[2], layer_prop[0], v[1], v[2], layer_prop[0]) s.send(vertfmt % d) s.send( "cd ..\n") def getLine(f): while 1: line = f.readline() if not line: return "" if line == "\n": continue line = line.strip() if line.startswith("#"):continue return line #parser through lef file s.send( "cd /%s/v/layout\n" % name) while 1: line = getLine(f) if not line: break if line.startswith("PIN"): pname = line.split()[1].strip() parsePin(f, pname) if line.startswith("OBS"): parsePin(f, None) s.send("update\n\n") if "-error" in sys.argv: err = file(sys.argv[sys.argv.index("-error")+1], "r") lines = err.readlines() for line in lines: if line.strip().startswith("Merging Node"): d = line.strip().split() a = d[2] b = d[4] layer_a = a.split("(")[1][:-1] layer_b = b.split("(")[1][:-1] x1 = float(d[6])-1 y1 = float(d[8])-1 x2 = x1+2 y2 = y1+2 v = [None, str(x1),str(y1),str(x2),str(y2)] z1 = layers[layer_a][0] z2 = layers[layer_b][1] s.send( "cd /%s/v/layout\n" % name) if "mesh" in sys.argv: m = "" else: m = "mesh" s.send( "shape merge_error cd @ quads %s\n" % m ) s.send( " rgb 255 0 0\n" ) s.send( "error\n" ) #top s.send( " normal 0 0 1 0 0 1 0 0 1 0 0 1\n") d=( v[1], v[2], z2, v[1], v[4], z2, v[3], v[4], z2, v[3], v[2], z2) s.send(vertfmt % d) #bottom s.send( " normal 0 0 -1 0 0 -1 0 0 -1 0 0 -1\n") d=( v[1], v[2], z1, v[1], v[4], z1, v[3], v[4], z1, v[3], v[2], z1) s.send(vertfmt % d) #side1 s.send( " normal -1 0 0 -1 0 0 -1 0 0 -1 0 0\n") d=( v[1], v[2], z2, v[1], v[4], z2, v[1], v[4], z1, v[1], v[2], z1) s.send(vertfmt % d) #side2 s.send( " normal 1 0 0 1 0 0 1 0 0 1 0 0\n") d=( v[3], v[2], z2, v[3], v[4], z2, v[3], v[4], z1, v[3], v[2], z1) s.send(vertfmt % d) #side3 s.send( " normal 0 1 0 0 1 0 0 1 0 0 1 0\n") d=( v[1], v[4], z2, v[3], v[4], z2, v[3], v[4], z1, v[1], v[4], z1) s.send(vertfmt % d) #side4 s.send( " normal 0 -1 0 0 -1 0 0 -1 0 0 -1 0\n") d=( v[1], v[2], z2, v[3], v[2], z2, v[3], v[2], z1, v[1], v[2], z1) s.send(vertfmt % d) s.send( "update cd .. \n") # communication while 1: length,type = s.recv(16).split() print "Len:%s Type:%s" % (length,type) data = s.recv(int(length)) if (type == "event"): data = data.split(",") print data if data[1] == '"close"': sys.exit() else: print data #s.send('Hello, world') s.close()