第4章:結線をコードで書き、ネットリストを作り、機械で検算する
前章の足慣らし(分圧器)と同じ骨格で、今回のボード(第1章で決めた、電源部つきのCH32V003ボード)の結線をコードで書き下します。部品を宣言し、基本形の結線を書き、電源部(
VIN_5V)を足し、generate_netlist() でネットリストを作り、ERC() で機械に検算させるところまでを通します。あわせて、この章のいちばん大事な線引き――コードで書くのは「結線」まで。トラック幅・ビア径・ベタGNDといった“物理の数値”は、ここでは決めない(次章のKiCadで決める)――を、はっきりさせます。
4.1 書く順番(分圧器と同じ骨格)
やることは、前章の分圧器と同じ3ステップです。①ネット(網)を用意する → ②部品を用意する → ③つなぐ。ボードが大きくなっても、骨格は変わりません。違うのは、部品と結線の数が増えることだけ。だからこそ、増えたぶんを繰り返し(ループ)で畳めるところが出てきます。まずは、今回のボードの「部品」と「主要なネット」を宣言するところから始めます。
基本形(CH32V003まわり)のピンとネットの正確な対応は、KiCad入門・第3章の全結線の早見表が正本です。この章は、その早見表をコードに“写す”方法を示します。以下のコードで、ピン名やネット名を 例 として書いている箇所は、必ずご自分の早見表(と実際に使うシンボルのピン名)に合わせて置き換えてください。ここで新しい配線を発明するのではなく、手で描いたのと同じ結線を、コードで書き直すのが目的です。
4.2 部品を宣言する
基本形の部品(U1・C1・R1・R2・D1・J1~J3)に、第1章で足した電源部(U2・C2・C3・J4)を加えて宣言します。値とフットプリントは、第1章の部品表に合わせます。ライブラリ名とシンボル名は、KiCad入門で選んだものに合わせてください(とくにCH32V003は、環境によって入っているシンボル名が違うことがあります)。
from skidl import *
# ---- 主要なネット(電気的な網)----
vcc = Net('VCC') # 3.3V(基板全体)
gnd = Net('GND')
vin5 = Net('VIN_5V') # 今回あらたに増える5V入力
# ---- 基本形の部品(値・フットプリントは第1章の部品表どおり)----
# ※ 'ライブラリ:シンボル' は、KiCad入門で選んだものに合わせる
u1 = Part('MCU_WCH', 'CH32V003F4P6',
footprint='Package_SO:TSSOP-20_4.4x6.5mm_P0.65mm') # マイコン
c1 = Part('Device', 'C', value='100nF',
footprint='Capacitor_SMD:C_0805_2012Metric') # パスコン
r1 = Part('Device', 'R', value='1k',
footprint='Resistor_SMD:R_0805_2012Metric') # LED電流制限
r2 = Part('Device', 'R', value='10k',
footprint='Resistor_SMD:R_0805_2012Metric') # SWIOプルアップ
d1 = Part('Device', 'LED',
footprint='LED_SMD:LED_0805_2012Metric') # LED
j1 = Part('Connector_Generic', 'Conn_01x12',
footprint='Connector_PinHeader_2.54mm:PinHeader_1x12_P2.54mm_Vertical') # 左ヘッダ
j2 = Part('Connector_Generic', 'Conn_01x12',
footprint='Connector_PinHeader_2.54mm:PinHeader_1x12_P2.54mm_Vertical') # 右ヘッダ
j3 = Part('Connector_Generic', 'Conn_01x03',
footprint='Connector_PinHeader_2.54mm:PinHeader_1x03_P2.54mm_Vertical') # 書き込み端子
# ---- 電源部の部品(第1章で追加した4点)----
u2 = Part('Regulator_Linear', 'AMS1117-3.3',
footprint='Package_TO_SOT_SMD:SOT-223-3_TabPin2') # 5V→3.3V
c2 = Part('Device', 'C', value='10uF',
footprint='Capacitor_SMD:C_0805_2012Metric') # 入力側
c3 = Part('Device', 'C', value='10uF',
footprint='Capacitor_SMD:C_0805_2012Metric') # 出力側
j4 = Part('Connector_Generic', 'Conn_01x02',
footprint='Connector_PinHeader_2.54mm:PinHeader_1x02_P2.54mm_Vertical') # 5V入力
上のコードは、部品を「用意した」だけです。分圧器のときと同じで、つないで初めて回路になります。次項から、早見表に沿って結線していきます。値(value)とフットプリント(footprint)は、最終的なネットリストに必要な情報なので、この宣言の時点で入れておきます。
4.3 基本形の結線をコードに写す
まず、基本形の結線です。パスコン、SWIOプルアップ、LED、そして書き込み端子。ここは早見表を1行ずつコードに直していく作業です。ネットにピンを足していく書き方(ネット += 部品[ピン])で書けます。
# ---- パスコン C1:VCC-GND間 ----
vcc += c1[1]
gnd += c1[2]
# ---- 書き込み端子 J3:VDD / GND / SWIO の3本(順番は早見表に合わせる)----
swio = Net('SWIO')
vcc += j3[1]
gnd += j3[2]
swio += j3[3]
# ---- SWIO まわり:マイコンのSWIOピン と プルアップR2 ----
# ※ CH32V003のSWIOは PD1。ピン名は使うシンボルに合わせる
swio += u1['PD1'], r2[1]
vcc += r2[2]
# ---- LED:駆動GPIO(LED_A) → R1 → D1 → GND ----
led_a = Net('LED_A')
led_a += u1['PD6'], r1[1] # 駆動ピンは早見表に合わせる(例:PD6)
r1[2] += d1['A'] # 抵抗の先にLEDのアノード
d1['K'] += gnd # LEDのカソードをGND
# ---- 電源をマイコンへ:VDD / VSS(ピン名はシンボルに合わせる)----
vcc += u1['VDD']
gnd += u1['VSS']
ここまでは、分圧器の & より少し丁寧に、「このネットに、この部品のこのピンを足す」と書いています。早見表の1行が、コードの1~数行に、素直に対応します。
繰り返しが効くところ:GPIOをJ1・J2へ引き出す
ここが、コードにして楽になる場面です。マイコンの多数のGPIOを、左右のピンヘッダ(J1・J2)へ順番に引き出す――この同じ形の繰り返しを、手で一本ずつ書く代わりに、早見表の並びをリストにして、ループで回します。
# ---- GPIOをJ1へ引き出す:早見表の「J1に出す信号」を順に並べる ----
# ※ ネット名・並び順は、必ず早見表に合わせて置き換える(下は例)
j1_signals = ['PA1', 'PA2', 'PC0', 'PC1', 'PC2', 'PC3', 'PC4', 'PC5']
for i, name in enumerate(j1_signals, start=1):
net = Net(name) # そのGPIO用のネットを作り
net += u1[name], j1[i] # マイコンの当該ピンと、J1のi番ピンをつなぐ
# J2側も同じ要領で、早見表の「J2に出す信号」をリストにして回す
# j2_signals = [...] # ← 早見表に合わせる
# for i, name in enumerate(j2_signals, start=1):
# net = Net(name)
# net += u1[name], j2[i]
もし手で回路図を描くなら、GPIOの数だけ名札を置き、線を引くことになります。コードなら、早見表の並びをリストにして、ループを1つ回すだけ。信号が1本増えても、リストに一語足すだけで済みます。第2章で見た「繰り返しはループで畳める」が、まさにこれです。ただし、どのピンをどこに出すかを“決める”のは、あくまで早見表(=人の設計)。コードは、その決定を手早く・間違いなく写し取る道具です。
4.4 電源部の結線を書く(VIN_5V の追加)
次に、第1章で足した電源部です。第1章1.6の結線表を、そのままコードにします。新しく増えるのは VIN_5V というネットだけ。VCC と GND は、基本形と共通の網に合流します。
# ---- 電源部:第1章1.6の結線表をコードに ---- # ※ AMS1117のピン名(VI / VO / GND)は使うシンボルに合わせる vin5 += j4[1], u2['VI'], c2[1] # 5V入力側:J4-1, U2-IN, C2-1 vcc += u2['VO'], c3[1] # 3.3V出力側:U2-OUT, C3-1(基板VCCへ合流) gnd += j4[2], u2['GND'], c2[2], c3[2] # GND:J4-2, U2-GND, C2-2, C3-2
これで、基本形の全結線に、電源部の3行が足されました。vcc と gnd は、4.3ですでに基本形の各所につながっているので、ここで u2['VO'] を足せば、レギュレータの3.3V出力が、そのまま基板全体のVCCに合流します。同じネット名に足していくだけで、網が広がっていく――これがネットで結線するということです。
第1章で触れたとおり、3.3Vの供給元が「書き込み器の3V3(J3経由)」と「レギュレータ出力(U2)」の2つになりえます。コード上は
vcc という一つの網にどちらもつながって見えますが、実際の基板では、両方から同時に電気を流さない設計(ジャンパで切り替える等)にします。これは結線(論理)というより運用と物理の判断なので、次章以降の配置・配線で具体化します。コードは「つながっている」ことを表すだけで、「どちらから給電するか」までは決めません。
4.5 ここが肝:コードで書くのは「結線」まで。太さ・ビア・ベタGNDは書かない
この章で、いちばん誤解されやすい線引きをはっきりさせます。skidl(コード)で書けるのは、「どことどこがつながるか」という論理までです。「その線を何ミリの太さで引くか」「ビアの穴径はいくつか」「空き地をどうGND銅箔で埋めるか」――こうした物理の数値は、skidlのネットリストには入りません。入る場所がないのです。
ここは、実際に多くの人が一度はまるところです。「配線を自動化するのだから、線の太さやGNDベタも、コード側で指定できるはず」と考えてしまう。ところが、トラック幅・クリアランス・ビア径・ベタGND(ゾーン塗りつぶし)は、ネットリストが扱う情報ではありません。これらは基板(物理)の設定であり、KiCadのボード設定側で決めるものです(KiCad入門でいえば、第3章のネットクラス設定と、第6章のベタGNDにあたります)。コードでいくら探しても見つからないのは、そもそもコードの担当ではないから。そう考えると、どちらが何を担当するのかが、はっきりします。
では、コード側では何もできないのかというと、そうではありません。「このネットは電源系だ」という“意図”のラベル(ネットのクラス分け)までは、コードで持てます。たとえば VCC と GND を「電源クラス」としてまとめておく、という具合です。ただし、そのクラスに“幅0.5mm”という数値を結びつけて実際の配線に効かせるのは、KiCadのボード設定の仕事です。コードは「これは電源だ」と意図を示すところまで、KiCadは「電源は0.5mmで引く」と物理を決めるところ――と分かれます。
# ネットに「意図」を持たせる(例):電源系をまとめて扱う下地 # ── ただし、ここで幅やビア径の“数値”は決めない ── # 実際のトラック幅・クリアランス・ビア径・ベタGNDは、 # 次章でKiCadのボード設定として決める(=物理は人の担当)。 power_nets = [vcc, gnd, vin5] # 電源系はこの3本、という整理まではコードで持てる
序章の図(論理はコード/物理は人と機械/検算は機械)を思い出してください。4.5は、その背骨がいちばんはっきり出る場面です。コードは論理の担当、KiCadは物理の担当。この境目を、太さ・ビア・ベタGNDという具体でつかんでおくと、次章でKiCadに取り込んだあと、「どこで何を設定するのか」で迷わなくなります。“コードで全部やる”のではなく、“コードに向くところをコードに渡す”――ここが要です。
4.6 ネットリストを作り、機械で検算する
結線を書き終えたら、分圧器のときと同じく、検算とネットリスト出力です。ERC() で電気的なミス(つなぎ忘れ、電源の衝突など)を機械に洗わせ、generate_netlist() でネットリストを出力します。
# ---- 検算とネットリスト出力 ---- ERC() # つなぎ忘れ・電源衝突などを機械が点検 generate_netlist() # KiCadへ渡すネットリストを出力
python このスクリプト.pyを実行する。- ERCの警告を読む。 つなぎ忘れや、電源ピンの扱いに関する警告が出たら、早見表と照らして直す。
- 出力された
.netファイルを開き、VCCやGND、VIN_5Vに、意図した部品のピンがぶら下がっているかを目で確かめる。
電源ネット(VCC・GNDなど)に対して、ERCが「このネットは、どこから電気が供給されるのか宣言されていない」という趣旨の警告を出すことがあります。KiCad入門・第3章で PWR_FLAG を置いたのと同じ事情です。skidl側でも、電源フラグにあたる部品をVCC・GNDに付けて「ここが電源の供給点だ」と宣言すると、この警告は収まります。付け方はskidlの版で少し変わるので、警告文とあわせて公式の案内を確認してください。大事なのは、警告を放置せず、意味を読んで一つずつ潰すことです。
4.7 次章への橋渡し
- 今回のボードの部品(基本形+電源部)を、値・フットプリント付きで宣言した
- 基本形の結線を早見表から写し、GPIOのJ1/J2引き出しはループで畳んだ
- 電源部の結線(新規
VIN_5V、VCC/GNDへの合流)を書いた - 太さ・ビア・ベタGNDはコードに書かない(=物理はKiCadの担当)と線引きした
ERC()で検算し、generate_netlist()でネットリストを出力・目視した
これで、今回のボードの「論理(結線)」がコードとネットリストの形で手に入りました。ここまでが「コードの担当」です。次章からは「物理の担当」――このネットリストをKiCadに取り込み、部品を並べ、そして4.5で保留したトラック幅・ビア・ベタGNDを、KiCadのボード設定として自分で決めます。前回のプロジェクトで飛ばしてしまった一手を、今度は正面から押さえにいきます。