2020年12月18日 星期五

在3D Layout當中如何取得元件的座標

元件的尺寸大小不一,嚴格來說,更有用的是取得元件所有的pin及pin所在的位置,下面的程式碼可以取得上層電阻的pin及其座標以及pin連接的net name

import ScriptEnv
ScriptEnv.Initialize("Ansoft.ElectronicsDesktop")
oDesktop.RestoreWindow()
oProject = oDesktop.GetActiveProject()
oDesign = oProject.GetActiveDesign()
oEditor = oDesign.GetActiveEditor()
R_top = []
R_bot = []
for i in oEditor.FindObjects('Type', 'component'):
part_type = oEditor.GetPropertyValue('BaseElementTab', i, 'Part Type')
placement_layer = oEditor.GetPropertyValue('BaseElementTab', i, 'PlacementLayer')
if part_type == 'Resistor':
if placement_layer == 'TOP':
R_top.append(i)

for i in R_top:
for pin in oEditor.GetComponentPins(i):
AddWarningMessage(str(oEditor.GetComponentPinInfo(i, pin)))
(圖一) 輸出Top R對應pin的座標及net name


在3D layout當中如何取得上層或底層的電阻編號?

 要在HFSS 3D Layout運行script來取得PCB上面的電阻/電容/電感編號,可以參考以下代碼:


import ScriptEnv
ScriptEnv.Initialize("Ansoft.ElectronicsDesktop")
oDesktop.RestoreWindow()
oProject = oDesktop.GetActiveProject()
oDesign = oProject.GetActiveDesign()
oEditor = oDesign.GetActiveEditor()
R_top = []
R_bot = []
for i in oEditor.FindObjects('Type', 'component'):
part_type = oEditor.GetPropertyValue('BaseElementTab', i, 'Part Type')
placement_layer = oEditor.GetPropertyValue('BaseElementTab', i, 'PlacementLayer')
if part_type == 'Resistor':
if placement_layer == 'TOP':
R_top.append(i)
elif placement_layer == 'BOTTOM':
R_bot.append(i)

AddWarningMessage(str(R_top))
AddWarningMessage(str(R_bot))
(圖一) TOP層以以及BOTTOM層的電阻



2020年12月15日 星期二

如何在AEDT當中產生訊息視窗

 我們可以在程式執行完畢之後產生訊息窗告知使用者處理狀況:

import clr
clr.AddReference("System.Windows.Forms")
from System.Windows.Forms import MessageBox

MessageBox.Show("Process Successfully!", 'Message Window')

(圖一) 跳出訊息視窗


2020年12月5日 星期六

如何依照元件連接數排序輸出nets

不同類別的net連接不同數量的原件(IC, R, L, C,...)。訊號線一般是2個,Clock則是兩個到多個,電源net連接的元件數可能多達數十個。GND通常是連接最多元件的net,包含晶片,去耦電容及其他等等。透過讀取這些訊息,可以讓我們對PCB的複雜度有一個初步的了解。以下為程式碼:

import clr, os, sys, System
AnsysEM_Path = 'C:/Program Files/AnsysEM/AnsysEM20.2/Win64/'
sys.path.append(AnsysEM_Path)
os.environ['PATH'] += ';' + AnsysEM_Path

clr.AddReference('Ansys.Ansoft.Edb')
clr.AddReference('Ansys.Ansoft.SimSetupData')
import Ansys.Ansoft.Edb as edb

edb.Database.SetRunAsStandAlone(True)

DB = edb.Database.Open('D:/demo/test.aedb', False)

cell = list(DB.TopCircuitCells)
layout = cell[0].GetLayout()

def getNetInfo(layout):
net_info={}
for n in layout.Nets:
netname=n.GetName()
net_info[netname]={}
for i in n.PadstackInstances:
if len(i.GetName())==0:
continue
try:
net_info[netname][i.GetComponent().GetName()]+=[i.GetName()]
except:
net_info[netname][i.GetComponent().GetName()]=[i.GetName()]

return net_info

netinfo = getNetInfo(layout)
result = []
for i in netinfo:

comps = netinfo[i].keys()
Ucomps = [j for j in comps if j[0] in ['u', 'U']]
NUcomps = [j for j in comps if j[0] not in ['u', 'U']]
sortedcomp = sorted(Ucomps) + sorted(NUcomps)
result.append((len(netinfo[i]), sortedcomp, i))

result.sort()
with open('d:/demo/netinfo.csv', 'w') as f:
for n, comps, net in result:
print(n, comps, net)
f.writelines('{:>4}, {:>32}, {}\n'.format(n, net, comps))

(圖一) 輸出按照連接元件數量排序的net name


2020年12月1日 星期二

如何在Anaconda安裝skrf模組

Scikit-RF提供了S參數讀取,S參數運算及Smith Chart繪圖等功能。我們可以在Anaconda當中安裝該套件來處理S參數的相關運算。套件功能可參考:https://scikit-rf.readthedocs.io/en/latest/index.html 

底下為安裝步驟:

步驟一:開啟Anaconda Prompt視窗

(圖一) 開啟開啟Anaconda Prompt視窗

步驟二:輸入conda install -c conda-forge  scikit-rf。此時Anaconda會檢查環境。

(圖二) 輸入安裝指令

步驟三:完成環境檢查之後,詢問是否安裝,按Y鍵確認。之後會自動聯網下載相關套件並啟動安裝過程,約1-2分鐘可完成。

(圖三) 安裝過程

步驟四:安裝完成之後會出現done的訊息,此時可關閉視窗完成安裝。

(圖四) 結束套件安裝


最後,回到Anaconda之後我們就可以匯入skrf模組來處理S參數了。

(圖五)匯入skrf模組






2020年11月29日 星期日

3D Layout當中該如何找出Overlap物件?

(圖一) 部分紅色圓形與藍色方塊重疊


藍色方塊在Top層,紅色圓形在Bottom層。假設想要找出所有與藍色方塊重疊的紅色圓形並加以刪除,可參考底下程式碼:

import ScriptEnv
ScriptEnv.Initialize("Ansoft.ElectronicsDesktop")
oDesktop.RestoreWindow()
oProject = oDesktop.GetActiveProject()
oDesign = oProject.GetActiveDesign()
oEditor = oDesign.GetActiveEditor()

x1 = set(oEditor.FindObjects('Type', 'rect'))
y1 = set(oEditor.FindObjects('Layer', 'Top'))
z1 = x1.intersection(y1)

x2 = set(oEditor.FindObjects('Type', 'circle'))
y2 = set(oEditor.FindObjects('Layer', 'Bottom'))
z2 = x2.intersection(y2)

todelete = []
for i in z1:
poly_i = oEditor.GetPolygon(i)
for j in z2:
poly_j = oEditor.GetPolygon(j)
if poly_i.GetIntersectionType(poly_j):
todelete.append(j)

oEditor.Delete(todelete)


(圖二)執行程式之後,重疊紅色圓形已被刪除




2020年11月27日 星期五

透過EDB抓取疊層相關資料

以下代碼可以透過EDB抓取堆疊當中像是厚度,顏色,材料,粗糙度等訊息。注意當中Solver設定只支援HFSS,不支援Planar EM。

import clr, os, sys, System, json
AnsysEM_Path = 'C:/Program Files/AnsysEM/AnsysEM20.2/Win64/'
sys.path.append(AnsysEM_Path)
os.environ['PATH'] += ';' + AnsysEM_Path

clr.AddReference('Ansys.Ansoft.Edb')
clr.AddReference('Ansys.Ansoft.SimSetupData')
import Ansys.Ansoft.Edb as edb

edb.Database.SetRunAsStandAlone(True)

DB = edb.Database.Open('D:/demo/test.aedb', False)

cell = list(DB.TopCircuitCells)
layout = cell[0].GetLayout()

x = layout.GetLayerCollection()
zids =x.GetZoneIds()
print(zids)
y=[]
y = x.Layers([-2, 20])

layer_type ={'SignalLayer': "signal",
'DielectricLayer': "dielectric",
'MeasureLayer': "measures",
'OutlineLayer': "outline",
'SIwaveHFSSSolverRegions': "SIwave HFSS regions",
'AirlinesLayer': "rat",
'ErrorsLayer': "error",
'SymbolLayer': "symbol",
'PostprocessingLayer': "Postprocessing",
'AssemblyLayer': "assembly",
'SilkscreenLayer': "silkscreen",
'SolderPasteLayer': "solderpaste",
'GlueLayer': "glue",
'UserLayer': "user",
}
tb_type = {0: 'top', 1: 'neither', 2:'bottom'}
result = []
for i in y:
ltype = layer_type[str(i.GetLayerType())]
if ltype in ['signal', 'dielectric']:
info = ["NAME:stackup layer"]
else:
info = ["NAME:layer"]
info += ["Name:=", i.GetName()]
info += ["ID:=", i.GetLayerId()]

info += ["Type:=", ltype]
info += ["Top Bottom:=", tb_type[int(i.GetTopBottomAssociation())]]
R, G, B = i.GetColor()
colorcode = int(R) + int(G)*(256) + int(B)*(256**2)
info += ["Color:=", colorcode]
info += ["Transparency:=", i.GetTransparency()]
info += ["Pattern:=", 1]
info += ["VisFlag:=", int(i.GetVisibilityMask())]
info += ["Locked:=", i.GetLocked()]
info += ["DrawOverride:=", int(i.GetDrawOverride())]
inzone =[id for id in zids if i.IsInZone(id)]
info += ["Zones:=", inzone]

if ltype in ['signal', 'dielectric']:
values = ["NAME:Sublayer",]
values += ["Thickness:=", str(i.GetThicknessValue())]
values += ["LowerElevation:=", str(i.GetLowerElevationValue())]
values += ["Roughness:=", "0um"]
values += ["BotRoughness:=", "0um"]
values += ["SideRoughness:=", "0um"]
values += ["Material:=", i.GetMaterial()]
if ltype == 'signal':
values += ["FillMaterial:=", i.GetFillMaterial()]
info.append(values)

if i.GetNegative():
info += ["Neg:=", True]

if i.GetUseSolverProperties():
info += ["Usp:=", True]
solver = i.GetHFSSSolverProperties()
solveinside = 'true' if solver.SolveInside else 'false'
dc_type = int(solver.DCType)
dc_thickness = str(solver.DCThickness)
s1 = [
"NAME:Sp",
"Sn:=" , "HFSS",
"Sv:=" , "so(si={}, dt={}, dtv=\'{}\')".format(solveinside, dc_type, dc_thickness)
]
s2= [
"NAME:Sp",
"Sn:=" , "PlanarEM",
"Sv:=" , "so(ifg=false, vly=false)"
]
info.append(s1)
info.append(s2)
if i.IsEtchFactorEnabled():
info += ["Etch:=", str(i.GetEtchFactor())]
info += ["UseEtch:=", True]

if i.IsRoughnessEnabled():
info += ["UseR:=", str(i.IsRoughnessEnabled())]
location = [(edb.Cell.RoughnessModel.Region.Top, "RMdl:=", "NR:=", "HRatio:=", 6),
(edb.Cell.RoughnessModel.Region.Bottom, "BRMdl:=", "BNR:=", "BHRatio:=", 8),
(edb.Cell.RoughnessModel.Region.Side, "SRMdl:=", "SNR:=", "SHRatio:=", 10),
]
for loc, loc_name, nodule_radius, surface_ratio, rough_index in location:
model = i.GetRoughnessModel(loc)

if type(model).__name__ == 'HurrayRoughnessModel':
info += [loc_name, "Huray"]
info += [nodule_radius, str(model.NoduleRadius)]
info += [surface_ratio, str(model.SurfaceRatio)]
else:
info += [loc_name, "Groisse"]
info += [nodule_radius, "0um"]
info += [surface_ratio, "1"]
values[rough_index] = str(model.Roughness)

result.append(info)

with open('d:/demo/testing.txt', 'w') as f:
for i in result:
f.writelines( str(i) + '\n')
print(str(i))
(圖一)在PyCharm抓取疊層相關訊息