2020年10月31日 星期六

如何用EDB函式庫輸出path跟polygon的座標點

在3D Layout當中的電路板設計。

(圖一) HFSS 3D Layout

以下程式碼讀取.aedb並輸出trace, polygon的座標訊息,並輸出到json檔案當中

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()
data = {}
type_group = set()
for i in layout.Primitives:
name = i.GetId()
net = i.GetNet().GetName()
layer = i.GetLayer().GetName()
ptype = i.GetPrimitiveType()
key = ','.join([str(net), str(name), str(layer), str(ptype)])
type_group.add(str(ptype))

data[key]=[]
for p in i.GetPolygonData().Points:
_x = p.X.ToDouble()
_y = p.Y.ToDouble()
if _x == sys.float_info.max or _y == sys.float_info.max:
continue
data[key].append((_x, _y))
sk = sorted(data.keys())
newdata = {str(i):data[i] for i in sk}

print(type_group)
with open('d:/demo/pcb.log', 'w') as f:
json.dump(newdata, f, indent=4)

為了要確保抓到的資料是否完整,我們接著到Anaconda Spyder環境當中讀取.json檔的內容並根據座標輸出圖片。注意輸出結果並不包含pads及via的相關結構。

import json
import matplotlib.pyplot as plt
plt.figure(figsize=(30, 20))
with open('d:/demo/pcb.log', 'r') as f:
data = json.load(f)

for i in data:
net, gid, layer, ptype = i.split(',')
if layer == 'PWR':
x, y = zip(*data[i])
plt.fill(list(x)+[x[0]], list(y)+[y[0]], color='r')

plt.savefig('d:/demo/top.png')
plt.show()
(圖二)用Matplotlib繪圖


2020年10月30日 星期五

如何利用EDB函式輸出3D Layout當中元件SolderBall的訊息

在不打開AEDT的狀況之下,我們可以透過直接讀取3D Layout的.aedb方式取得版圖相關訊息。這裡示範如何取得某一個IC元件的Solder Ball的類別、直徑及高度。

(圖一) IC Component Solder Ball參數

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()

u2a5 = edb.Cell.Hierarchy.Component.FindByName(layout, 'U2A5')
u2a5_property = u2a5.GetComponentProperty().GetSolderBallProperty()
print(u2a5_property.GetShape())
print(u2a5_property.GetDiameter())
print(u2a5_property.GetHeight())

comp_names=[]
for c in layout.Groups:
comp_names.append(c.GetName())
print(comp_names)
輸出結果:
(圖二)輸出solderball及所有PCB元件

2020年10月20日 星期二

如何在PyCharm當中編寫SIwave腳本

在PyCharm開啟專案時,Existing Interpreter需指向AEDT的IronPython路徑,如圖一:

(圖一)開啟新檔時設定IronPython路徑

接著程式碼需先取得oApp,以下為範例程式碼,抓取SIwave版本及專案名稱,並輸出"Hello World"到訊息視窗:

(圖二)取得並輸出SIwave訊息

from System import Activator, Type

SIwaveVerision = "SIwave.Application.2020.2"
oApp = Activator.CreateInstance(Type.GetTypeFromProgID(SIwaveVerision))

print(oApp.GetVersion())

oDoc = oApp.GetActiveProject()
print(oDoc.GetName())

oDoc.ScrLogMessage("Hello World")

(圖三)SIwave輸出訊息



2020年10月11日 星期日

IronPython如何讀取內含中文的.txt並輸出到message window

底下為範例碼:

# -*- coding: utf-8 -*-

import codecs
with codecs.open('d:/demo/help.txt', 'r', 'utf-8', errors = 'ignore') as f:
info = f.read()

    AddWarningMessage(info)


(圖一) help.txt


(圖二) 輸出到訊息視窗


2020年10月9日 星期五

如何取得HFSS可以輸出的solution種類、頻率範圍以及變數?

 要輸出HFSS結果,必須先知道想要的數值屬於哪一種類別,比方說:

  • Fields
  • Modal Solution Type
  • Antenna Parameters
  • Emission Test
  • Far Fields
  • ...

不同類別各自包含不同的solution。而每一個soulution有對應的頻率範圍及變數範圍。底下的函式GetSolutionInfo()可以一次輸出現有專案內關於模擬結果的所有相關訊息:

def GetSolutionInfo():
'''Get all solution variables'''
oProject = oDesktop.GetActiveProject()
oDesign = oProject.GetActiveDesign()

oModule_rs = oDesign.GetModule("ReportSetup")
oModule_sol = oDesign.GetModule("Solutions")

result = {}
for report_type in oModule_rs.GetAvailableReportTypes():
result[report_type] = []

for solution in oModule_rs.GetAvailableSolutions(report_type):
result[report_type].append((solution,
oModule_sol.GetSolveRangeInfo(solution),
oModule_sol.GetAvailableVariations(solution),
))
# AddWarningMessage(str(result))
return result

if __name__ == '__main__':
info = GetSolutionInfo()
for i in info:
AddWarningMessage(i)
AddInfoMessage(str(info[i]))
(圖一)不同類別及其包括的solution



2020年10月3日 星期六

如何用PyQT5建立TableView?

以下為一個範例檔,欄位當中可以勾選。

tableview.py檔

import os, sys

os.chdir(os.path.dirname(__file__))

from PyQt5 import QtCore
from PyQt5 import QtWidgets, uic
from PyQt5.QtGui import QStandardItemModel, QStandardItem, QBrush, QColor

Ui_MainWindow, QtBaseClass = uic.loadUiType('tableview.ui')


class MainUi(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self):
QtWidgets.QMainWindow.__init__(self)
Ui_MainWindow.__init__(self)
self.setupUi(self)
self.initializeNetTAB()

def initializeNetTAB(self):
tableModel = QStandardItemModel(self)
tableModel.itemChanged.connect(self.itemChanged)

tableModel.setHorizontalHeaderLabels(['Name', 'import', 'ports', 'pwr/gnd'])
for i in range(4):
item = QStandardItem(f"case{i}")
tableModel.setItem(i, 0, item)

for j in range(1, 4):
item = QStandardItem()
item.setCheckable(True)
item.setEditable(False)
tableModel.setItem(i, j, item)

self.tableView.setModel(tableModel)

def itemChanged(self, item):
if item.isCheckable() == False:
return

if item.checkState():
item.setText('Yes')
item.setForeground((QBrush(QColor(0, 0, 255, 255))))
else:
item.setText('No')
item.setForeground((QBrush(QColor(100, 100, 100, 255))))


if __name__ == "__main__":
def run_app():
app = QtWidgets.QApplication(sys.argv)
window = MainUi()
window.show()
app.exec_()

run_app()


tableview.ui檔
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>582</width>
<height>751</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralwidget">
<widget class="QTableView" name="tableView">
<property name="geometry">
<rect>
<x>10</x>
<y>10</y>
<width>561</width>
<height>691</height>
</rect>
</property>
</widget>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>582</width>
<height>25</height>
</rect>
</property>
</widget>
<widget class="QStatusBar" name="statusbar"/>
</widget>
<resources/>
<connections/>
</ui>
(圖一) TableView表格