npx skills add https://github.com/diodeinc/pcb --skill idiomatic-zener.zen 代码的规范性风格规则。这些规则适用于所有模块、参考设计和板级文件。
切勿使用 if 来创建或移除元件。始终实例化每个元件。使用 dnp= 来控制是否装配。这适用于模块、板级文件和参考设计,包括可选功能块。
# 错误示例
if add_decoupling:
Capacitor(name="C_VDD", value="100nF", package="0402", P1=VCC, P2=GND)
# 正确示例
Capacitor(name="C_VDD", value="100nF", package="0402", P1=VCC, P2=GND)
对于由配置控制的可选子电路,使用记录将值与 DNP 状态配对。零值/禁用的配置值意味着 dnp=True 并带有占位值。
Passive = record(value=typing.Any, dnp=bool)
input_filter = config("input_filter", Frequency, default="0Hz", optional=True,
help="输入低通截止频率。0Hz 表示禁用滤波器。")
def input_rc(f):
dnp = f <= Frequency("0Hz")
r = e96(Resistance("100ohm") if not dnp else Resistance("0ohm"))
c = e24(1 / (2 * PI * r * f) if not dnp else Capacitance("100pF"))
return Passive(value=r, dnp=False), Passive(value=c, dnp=dnp)
input_r, input_c = input_rc(input_filter)
Resistor(name="R_IN", value=input_r.value, dnp=input_r.dnp, package="0402", P1=A, P2=B)
Capacitor(name="C_IN", value=input_c.value, dnp=input_c.dnp, package="0402", P1=B, P2=GND)
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
更少的元件 = 更简单的物料清单、更易组装、更低成本。
优先选择值切换而非重复元件。 当配置在离散选项之间选择时,使用具有计算值的单个元件——不要实例化具有相反 DNP 条件的多个元件。
# 错误示例:两个电阻,一个总是 DNP
Resistor(name="R_STRAP_HI", value="10kohm", P1=STRAP, P2=VCC, dnp=mode != "HIGH")
Resistor(name="R_STRAP_LO", value="100kohm", P1=STRAP, P2=VCC, dnp=mode != "LOW")
# 正确示例:一个电阻,值随配置变化
_strap_value = { Mode("HIGH"): "10kohm", Mode("LOW"): "100kohm", Mode("FLOAT"): "10kohm" }[mode]
Resistor(name="R_STRAP", value=_strap_value, P1=STRAP, P2=VCC, dnp=mode == Mode("FLOAT"))
利用内部上拉/下拉。 许多集成电路在配置引脚上具有内部偏置。如果默认状态使用内部上拉,则不要添加外部电阻——只需为该情况将单个电阻设为 DNP。
对配置使用来自 @stdlib/units.zen 的物理类型。暴露一个有意义的参数(例如截止频率),而不是原始的 R/C 值。仅对离散的设计选择使用 enum()。
# 错误示例
config("filter_r", str, default="10ohms")
# 正确示例
input_filter = config("input_filter", Frequency, default="0Hz", optional=True,
help="输入低通截止频率。0Hz 表示禁用滤波器。")
将计算放在带有数据手册引用的命名函数中。使用 e96() / e24() 对齐 E 系列。
def load_r(v_out, v_sense):
"""数据手册 §8.1.1 / 公式 4: V_OUT = V_SENSE × gm × R_L"""
GM = Current("200uA") / Voltage("1V")
return e96(v_out / (v_sense * GM))
每个 Power io 都应具有与数据手册绝对最大值或推荐工作范围匹配的 voltage_within。
VCC = io("VCC", Power, checks=voltage_within("2.7V to 36V"))
当 help= 能增加集成者可见的、从名称、类型、检查或默认值中不明显的含义时使用它。当它只是重复这些字段时,请省略。
VDD = io("VDD", Power, checks=voltage_within("3.0V to 5.5V"))
GND = io("GND", Ground)
EN = io("EN", Net, help="高电平使能稳压器")
input_filter = config("input_filter", Frequency, default="0Hz", optional=True,
help="输入低通截止频率。0Hz 表示禁用滤波器。")
.NET 访问器直接将 Power/Ground io 用作引脚连接。切勿使用 .NET。
# 错误示例
Capacitor(name="C_VDD", value="100nF", P1=VCC.NET, P2=GND.NET)
# 正确示例
Capacitor(name="C_VDD", value="100nF", P1=VCC, P2=GND)
除了标准约定(大写 io,小写 config):
| 元素 | 约定 | 示例 |
|---|---|---|
| 内部网络 | _ 前缀 | _VREF, _XI, _RBIAS |
| 元件名称 | 大写的功能前缀 | R_LOAD, C_VDD, U_LDO |
| 差分对 | _P / _N 后缀 | IN_P, IN_N (非 _PLUS / _MINUS) |
不要为集成者不应调整的实现细节暴露配置:去耦电容值、无源元件封装尺寸、测试点样式。
要为集成者确实需要更改的内容暴露配置:滤波器截止频率、输出电压、增益设置、启用/禁用可选子电路。
if 守卫——始终实例化,使用 dnp=.NET 访问器——直接使用 iostr 配置——使用带单位的类型e96() / e24() 进行计算Power io 上都有 voltage_withinhelp=_P / _N,而非 _PLUS / _MINUS_ 为前缀# pcb:sch 注释同步每周安装次数
106
代码仓库
GitHub 星标数
198
首次出现
8 天前
安全审计
已安装于
claude-code106
cline3
github-copilot3
codex3
kimi-cli3
gemini-cli3
Prescriptive style rules for .zen code. These apply to all modules, reference designs, and board files.
Never use if to create or remove components. Always instantiate every component. Use dnp= to control whether it is populated. This applies to modules, boards, and reference designs, including optional feature blocks.
# BAD
if add_decoupling:
Capacitor(name="C_VDD", value="100nF", package="0402", P1=VCC, P2=GND)
# GOOD
Capacitor(name="C_VDD", value="100nF", package="0402", P1=VCC, P2=GND)
For optional subcircuits controlled by a config, use a record to pair values with DNP state. A zero/disabled config value means dnp=True with placeholder values.
Passive = record(value=typing.Any, dnp=bool)
input_filter = config("input_filter", Frequency, default="0Hz", optional=True,
help="Input lowpass cutoff. 0Hz disables the filter.")
def input_rc(f):
dnp = f <= Frequency("0Hz")
r = e96(Resistance("100ohm") if not dnp else Resistance("0ohm"))
c = e24(1 / (2 * PI * r * f) if not dnp else Capacitance("100pF"))
return Passive(value=r, dnp=False), Passive(value=c, dnp=dnp)
input_r, input_c = input_rc(input_filter)
Resistor(name="R_IN", value=input_r.value, dnp=input_r.dnp, package="0402", P1=A, P2=B)
Capacitor(name="C_IN", value=input_c.value, dnp=input_c.dnp, package="0402", P1=B, P2=GND)
Fewer parts = simpler BOM, easier assembly, lower cost.
Prefer value-switching over duplicate components. When a config selects between discrete options, use a single component with a computed value — don't instantiate multiple components with opposing DNP conditions.
# BAD: two resistors, one always DNP
Resistor(name="R_STRAP_HI", value="10kohm", P1=STRAP, P2=VCC, dnp=mode != "HIGH")
Resistor(name="R_STRAP_LO", value="100kohm", P1=STRAP, P2=VCC, dnp=mode != "LOW")
# GOOD: one resistor, value changes with config
_strap_value = { Mode("HIGH"): "10kohm", Mode("LOW"): "100kohm", Mode("FLOAT"): "10kohm" }[mode]
Resistor(name="R_STRAP", value=_strap_value, P1=STRAP, P2=VCC, dnp=mode == Mode("FLOAT"))
Leverage internal pull-ups/pull-downs. Many ICs have internal bias on strap pins. If the default state uses the internal pull, don't add an external resistor — just DNP the single resistor for that case.
Use physical types from @stdlib/units.zen for configs. Expose one meaningful parameter (e.g. cutoff frequency), not raw R/C values. Use enum() only for discrete design choices.
# BAD
config("filter_r", str, default="10ohms")
# GOOD
input_filter = config("input_filter", Frequency, default="0Hz", optional=True,
help="Input lowpass cutoff. 0Hz disables the filter.")
Put calculations in named functions with datasheet references. Snap to E-series with e96() / e24().
def load_r(v_out, v_sense):
"""Datasheet §8.1.1 / Eq 4: V_OUT = V_SENSE × gm × R_L"""
GM = Current("200uA") / Voltage("1V")
return e96(v_out / (v_sense * GM))
Every Power io gets voltage_within matching the datasheet's absolute maximum or recommended operating range.
VCC = io("VCC", Power, checks=voltage_within("2.7V to 36V"))
Use help= when it adds integrator-visible meaning that is not already obvious from the name, type, checks, or default. Omit it when it would just restate those fields.
VDD = io("VDD", Power, checks=voltage_within("3.0V to 5.5V"))
GND = io("GND", Ground)
EN = io("EN", Net, help="High to enable the regulator")
input_filter = config("input_filter", Frequency, default="0Hz", optional=True,
help="Input lowpass cutoff. 0Hz disables the filter.")
.NET AccessorUse Power/Ground ios directly as pin connections. Never use .NET.
# BAD
Capacitor(name="C_VDD", value="100nF", P1=VCC.NET, P2=GND.NET)
# GOOD
Capacitor(name="C_VDD", value="100nF", P1=VCC, P2=GND)
Beyond the standard conventions (UPPERCASE io, lowercase config):
| Element | Convention | Example |
|---|---|---|
| Internal nets | _ prefix | _VREF, _XI, _RBIAS |
| Component names | Uppercase functional prefix | R_LOAD, C_VDD, U_LDO |
| Differential pairs | _P / suffixes |
Don't expose configs for implementation details integrators shouldn't tune: decoupling cap values, passive package sizes, test point style.
Do expose configs for things integrators legitimately need to change: filter cutoffs, output voltage, gain settings, enable/disable optional subcircuits.
if guards on instantiation — always instantiate, use dnp=.NET accessor — use ios directlystr configs for physical values — use typed unitse96() / e24()voltage_within on all Power ioshelp= only when it clarifies non-obvious integrator-facing meaning_P / , not / Weekly Installs
106
Repository
GitHub Stars
198
First Seen
8 days ago
Security Audits
Gen Agent Trust HubPassSocketPassSnykPass
Installed on
claude-code106
cline3
github-copilot3
codex3
kimi-cli3
gemini-cli3
Perl安全编程指南:输入验证、注入防护与安全编码实践
1,200 周安装
阿里云 AnalyticDB MySQL 数据库技能冒烟测试指南与自动化脚本
144 周安装
AI技能模板 - 高效构建AI助手技能,支持主流开发工具集成
145 周安装
iOS游戏开发终极指南:SpriteKit、SceneKit、RealityKit架构、性能优化与故障排除
142 周安装
Anime.js v4 中文指南:轻量级 JavaScript 动画库安装、核心概念与 API 详解
145 周安装
Claude Code 插件设置模式详解:YAML配置与本地状态管理
146 周安装
AI内部沟通助手:自动生成3P更新、公司通讯、FAQ回复、状态报告
145 周安装
_NIN_P, IN_N (not _PLUS / _MINUS) |
_N_PLUS_MINUS_# pcb:sch comments in sync