idiomatic-zener

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Idiomatic Zener

Zener代码编写惯例

Prescriptive style rules for
.zen
code. These apply to all modules, reference designs, and board files.
.zen
代码的规范性风格规则,适用于所有模块、参考设计和板级文件。

No Conditional Instantiation

禁止条件化实例化

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.
zen
undefined
切勿使用
if
语句创建或移除组件。始终实例化所有组件,使用
dnp=
来控制组件是否被启用(Do Not Populate)。此规则适用于模块、板级设计和参考设计,包括可选功能模块。
zen
undefined

BAD

不良示例

if add_decoupling: Capacitor(name="C_VDD", value="100nF", package="0402", P1=VCC, P2=GND)
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)
undefined
Capacitor(name="C_VDD", value="100nF", package="0402", P1=VCC, P2=GND)
undefined

DNP via Record Pattern

基于记录模式的DNP实现

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.
zen
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)
对于由配置控制的可选子电路,使用记录类型将参数值与DNP状态配对。配置值为零/禁用状态时,意味着
dnp=True
并使用占位符参数。
zen
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)

Minimize Component Count

最小化组件数量

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.
zen
undefined
组件越少,BOM越简单、组装越容易、成本越低。
优先选择参数切换而非重复组件:当配置需要在多个离散选项中选择时,使用单个组件并通过计算切换参数值——不要实例化多个组件并设置相反的DNP条件。
zen
undefined

BAD: two resistors, one always 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")
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.
_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"))

**利用内部上拉/下拉电阻**:许多IC的引脚内置偏置电阻。如果默认状态使用内部偏置,则无需添加外部电阻——仅在需要时通过DNP控制单个电阻即可。

Typed Unit Configs

类型化单位配置

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.
zen
undefined
使用
@stdlib/units.zen
中的物理类型定义配置项。暴露有实际意义的参数(如截止频率),而非原始的电阻/电容值。仅在离散设计选择时使用
enum()
zen
undefined

BAD

不良示例

config("filter_r", str, default="10ohms")
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.")
undefined
input_filter = config("input_filter", Frequency, default="0Hz", optional=True, help="Input lowpass cutoff. 0Hz disables the filter.")
undefined

Computation in Named Functions

计算逻辑封装为命名函数

Put calculations in named functions with datasheet references. Snap to E-series with
e96()
/
e24()
.
zen
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))
将计算逻辑放入带有 datasheet 引用的命名函数中。使用
e96()
/
e24()
将值对齐到E系列标准。
zen
def load_r(v_out, v_sense):
    """参考 datasheet §8.1.1 / 公式4: V_OUT = V_SENSE × gm × R_L"""
    GM = Current("200uA") / Voltage("1V")
    return e96(v_out / (v_sense * GM))

Voltage Checks on Power IOs

电源IO的电压检查

Every
Power
io gets
voltage_within
matching the datasheet's absolute maximum or recommended operating range.
zen
VCC = io("VCC", Power, checks=voltage_within("2.7V to 36V"))
每个
Power
类型的IO都需要添加
voltage_within
检查,匹配 datasheet 中的绝对最大值或推荐工作范围。
zen
VCC = io("VCC", Power, checks=voltage_within("2.7V to 36V"))

Help Strings

帮助字符串

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.
zen
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.")
当帮助信息能为集成者提供名称、类型、检查规则或默认值之外的额外意义时,使用
help=
;如果帮助信息只是重复这些字段的内容,则无需添加。
zen
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表示禁用滤波器。")

No
.NET
Accessor

禁止使用
.NET
访问器

Use Power/Ground ios directly as pin connections. Never use
.NET
.
zen
undefined
直接使用Power/Ground类型的IO作为引脚连接,切勿使用
.NET
zen
undefined

BAD

不良示例

Capacitor(name="C_VDD", value="100nF", P1=VCC.NET, P2=GND.NET)
Capacitor(name="C_VDD", value="100nF", P1=VCC.NET, P2=GND.NET)

GOOD

良好示例

Capacitor(name="C_VDD", value="100nF", P1=VCC, P2=GND)
undefined
Capacitor(name="C_VDD", value="100nF", P1=VCC, P2=GND)
undefined

Naming

命名规则

Beyond the standard conventions (UPPERCASE io, lowercase config):
ElementConventionExample
Internal nets
_
prefix
_VREF
,
_XI
,
_RBIAS
Component namesUppercase functional prefix
R_LOAD
,
C_VDD
,
U_LDO
Differential pairs
_P
/
_N
suffixes
IN_P
,
IN_N
(not
_PLUS
/
_MINUS
)
除了标准惯例(IO使用大写,配置使用小写)之外:
元素命名惯例示例
内部网络
_
为前缀
_VREF
,
_XI
,
_RBIAS
组件名称大写功能前缀
R_LOAD
,
C_VDD
,
U_LDO
差分对使用
_P
/
_N
后缀
IN_P
,
IN_N
(不使用
_PLUS
/
_MINUS

Opinionated Defaults

约定式默认值

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.
对于集成者无需调整的实现细节,请勿暴露配置项:比如去耦电容值、无源器件封装尺寸、测试点样式。
对于集成者确实需要修改的内容,应当暴露配置项:比如滤波器截止频率、输出电压、增益设置、可选子电路的启用/禁用。

Checklist

检查清单

  1. No
    if
    guards on instantiation — always instantiate, use
    dnp=
  2. No
    .NET
    accessor — use ios directly
  3. No
    str
    configs for physical values — use typed units
  4. Calculations in named functions with
    e96()
    /
    e24()
  5. voltage_within
    on all
    Power
    ios
  6. Add
    help=
    only when it clarifies non-obvious integrator-facing meaning
  7. Diff pairs use
    _P
    /
    _N
    , not
    _PLUS
    /
    _MINUS
  8. Internal nets prefixed with
    _
  9. Minimize component count — value-switch, leverage internal bias
  10. When renaming components or nets, keep existing
    # pcb:sch
    comments in sync
  1. 实例化时禁止使用
    if
    判断——始终实例化组件,使用
    dnp=
    控制启用状态
  2. 禁止使用
    .NET
    访问器——直接使用IO
  3. 物理参数的配置项禁止使用
    str
    类型——使用类型化单位
  4. 计算逻辑封装到命名函数中,并使用
    e96()
    /
    e24()
    对齐标准值
  5. 所有
    Power
    类型IO都添加
    voltage_within
    检查
  6. 仅当帮助信息能澄清非显而易见的集成者视角意义时,才添加
    help=
  7. 差分对使用
    _P
    /
    _N
    后缀,而非
    _PLUS
    /
    _MINUS
  8. 内部网络以
    _
    为前缀
  9. 最小化组件数量——优先参数切换,利用内部偏置
  10. 重命名组件或网络时,保持现有
    # pcb:sch
    注释同步