仿真
逻辑仿真
原理图中数字部分的事件驱动仿真:74 系列模型、原语、激励、断言、建立和保持时间,输出 VCD。
对原理图中数字部分的事件驱动仿真,直接来自其网络表;无需 PCB 布局。agentee new sim NAME --kind logic(MCP new_item,kind = "sim" 且 sim_kind = "logic")会写入一个包含时钟、复位和带时钟断言的起始文件,请将其重命名为您的网络;--kind fdtd(默认)会启动 FDTD 运行。agentee sim NAME(MCP run_sim)会在规范文件旁写入 NAME.result.json 和 VCD 波形 NAME.vcd;查看器会按时间绘制每个记录网络的轨迹。
在波形视图中,鼠标滚轮(或捏合,或 Ctrl 加滚轮)围绕指针缩放,拖动或横向滚动平移,双击适配整个运行,单击设置时间光标,光标会吸附到下方行边缘几像素范围内。+ 和 - 围绕光标缩放,方向键平移,F 或 Home 适配,Escape 取消光标,N 和 P 将光标跳转到下一个和上一个标记。当行数超过显示范围时,在名称上的滚轮、拖动或点击右边缘的条,以及 Page Up 和 Page Down 会滚动行(--show 中的 top=N 从第 N 行开始)。名称旁边的列会在光标处读取每一行(无光标时在指针处,否则在视图右边缘),悬停提示会给出从光标开始的时间。命名为 X[0] 到 X[n],或 X0 到 Xn(也包括 X0_N 到 Xn_N)的网络会折叠为一个总线行,以十六进制绘制,最高位在前,未知位用 x 表示,高阻位用 z 表示;record 条目 { name, nets } 也是如此。点击总线名称可打开其位。VCD 将相同的总线作为向量存储,代替其位:Q0 到 Q3 作为 $var wire 4 # Q [3:0] $end,Y0_N 到 Y7_N 作为 Y_N [7:0],包含 n 个网络的 record 总线作为 NAME [n-1:0],最高位在前。顶部的标记显示每个失败的断言(红色,在检查时间)、时序违规(琥珀色)和竞争(紫色),并在涉及网络的行上显示圆点;悬停查看其消息,点击将光标置于该处。运行保留前 10000 个标记,达到上限时头部会显示 capped。agentee render NAME --show from=300ns,to=900ns,cursor=550ns,open=Q[3:0] 无头绘制相同的视图。
name = "counter"
kind = "logic"
schematic = "counter" # default: the only top-level schematic
duration = "2us"
ignore = ["J1", "J2"] # parts with no logic model to leave out
record = ["CLK", "Q3", "Q2", "Q1", "Q0"] # default every net but the rails
# record = ["CLK", { name = "COUNT", nets = ["Q3", "Q2", "Q1", "Q0"] }] # a bus, MSB first
# on_violation = "keep" # default "x": a timing violation makes the flip-flop x
[[stimulus]]
net = "CLK"
clock = { period = "100ns", duty = 0.5, phase = "50ns" }
[[stimulus]]
net = "RST_N"
steps = [["0ns", 0], ["120ns", 1]] # [time, level] in time order; levels 0, 1, "x", "z"
[[stimulus]]
net = "MODE"
constant = 1
[[expect]] # a level at a time
net = "TC"
at = "1600ns"
value = 1
[[expect]] # a bus, MSB first: a number or a string of 0 1 x z and - (any)
nets = ["Y7_N", "Y6_N", "Y5_N", "Y4_N", "Y3_N", "Y2_N", "Y1_N", "Y0_N"]
at = "600ns"
value = "11011111"
[[expect]] # a sequence sampled on clock edges
nets = ["Q3", "Q2", "Q1", "Q0"]
clock = "CLK"
edge = "rising" # or "falling"
from = "0ns" # edges before this are skipped
sequence = [0, 0, 1, 2, 3, "01--"]时钟在 phase 之前为低电平,之后在每个 period 内保持高电平 duty 的时间;如果没有相位,则从 0 开始即为高电平。激励源作为强驱动源驱动其网络;在电源网络上,它取代电源轨。at 检查在该时间点所有信号稳定后读取一次网络;序列在时钟的每个干净边沿(0 到 1,或 1 到 0)之前读取网络,因此寄存器输出显示的是边沿到来时的状态。网络名称与原理图中一致,通过 0 欧姆连接件连接到另一个网络的网络,使用任一名称均可响应。
网表按以下方式转换为单元:
- 具有
style = "power"的网络和电源符号(power = true的符号)是恒定源:名称包含GND,或以VSS、VEE或0V开头的为 0,其他为 1(跳过PWR_FLAG)。 - 0 欧姆电阻(
R)、跳线(JP、SJ,引脚 1 和 2)和网络连接件(NT)将其网络合并为一个。电源轨与网络之间的其他电阻是上拉或下拉,作为电源轨电平的弱驱动源;两个信号网络之间的电阻将其合并;两个电源轨之间的电阻被忽略。 - 电容、电感、磁珠、滤波器、二极管、发光二极管、测试点、孔、基准点和晶振(
C、L、FB、FL、D、LED、TP、H、MH、FID、Y、X)被忽略。 - 数值(或符号名称)包含 74 系列编号的元件,按引脚号使用内置模型:
74HC00、SN74LVC1G08DBVR和CD74HCT04E均匹配。库涵盖 00、01、02、03、04、05、06、07、08、10、11、14、20、21、27、32、74、86、125、126、132、138、157、161、163、164、244、245、573、574 和 595,单门 1G00、1G02、1G04、1G06、1G07、1G08、1G14、1G17、1G32、1G34、1G74、1G79、1G80、1G86、1G125、1G126 和 1G157,以及双门 2G00、2G02、2G04、2G08、2G14、2G17、2G32、2G34、2G74、2G86、2G125 和 2G126。多单元符号中未放置的单元被忽略;已放置但无网络的引脚读取为浮空(z)。 - 14(以及 1G14、2G14)施密特触发器是反相器;仿真中没有缓慢的模拟边沿供迟滞作用。573 是八个
dlatch,574 是八个dff,每个都有共享的OE(引脚 1,低电平有效),用于将输出置为浮空。245 是八个xcvr:当OE(引脚 19)为低电平时,若DIR(引脚 1)为高电平则从 A 驱动 B,若为低电平则从 B 驱动 A。01、03(四与非门)、05、06、1G06(反相器)和 07、1G07(缓冲器)是开漏:它们拉低或释放(z),上拉电阻产生 1。所有 01 均采用 7402 引脚排列(输出在 1、4、10、13,输入紧随其后),依据 TI SDLS026(SN7401、SN74LS01)和瑞萨 REJ03D0532(HD74HC01);03 采用 7400 引脚排列,依据 TI SCLS077(SN74HC03)。 - 符号中所有输出引脚均为
open_collector的门也是开漏。 - 数值或符号为原语名称(
AND、NAND3、OR、NOR、XOR、XNOR、NOT、INV、BUF、TRIBUF、DFF、JKFF、SRLATCH、DLATCH、MUX2)的元件,按名称映射引脚:D、CLK(也接受C、CP、CK)、S/SET/PRE、R/RST/CLR、EN、OE、Q、~{Q};门的输出是其output引脚(或Y、Q、OUT),其他所有信号引脚均为输入。上划线(~{R})、末尾的#或_N,或反相引脚形状,表示该引脚为低电平有效。 - 其他任何元件都会报错并指明名称,除非它在
ignore中,或者拥有[[parts]]模型。
系列时序,取自 74 后的系列字母(传播延迟、建立时间、保持时间,以及异步置位或复位的恢复时间和移除时间):
| 系列 | 延迟 | 建立时间 | 保持时间 | 恢复时间 | 移除时间 |
|---|---|---|---|---|---|
| HC, HCT | 10 ns | 15 ns | 3 ns | 8 ns | 0 |
| AHC, AHCT, VHC, VHCT | 6 ns | 5 ns | 1 ns | 3.5 ns | 0 |
| AC, ACT | 6 ns | 4 ns | 1 ns | 2.4 ns | 0 |
| LVC | 4 ns | 3 ns | 1 ns | 2 ns | 0 |
| ALVC, LVT, ALVT, AUC, AVC | 4 ns | 2 ns | 1 ns | 2 ns | 0 |
| AUP, LV, LVX | 6 ns | 3 ns | 1 ns | 3 ns | 1 ns |
| LS 和纯 74 | 15 ns | 20 ns | 5 ns | 25 ns | 3 ns |
| 其他 | 10 ns | 10 ns | 2 ns | 10 ns | 2 ns |
恢复时间和移除时间是数据手册在 -40 到 85 C、4.5 V(5 V 系列)或 3.3 V(LVC)下的最小值,若 TI 和 Nexperia 均列出,则取较大者:
- HC, HCT:
nSD、nRD到nCP的 trec 为 8 ns,Nexperia 74HC_HCT74 rev 9(TI SN74HC74 SCLS094F 给出 6 ns,TI CD74HC74 SCHS124E 给出 8 ns,后者称为 trem)。 - AHC, AHCT:74AHCT74 的
nRD到nCP的 trec 为 3.5 ns(74AHC74 为 3.0 ns),Nexperia 74AHC_AHCT74 rev 11(TI SN74AHC74 SCLS255N 给出 3 ns)。 - AC, ACT: 5 V 下 trec 为 2.4 ns,TI CD74AC74 SCHS231E 和 CD74ACT74 SCHS321A(TI SN74AC74 SCAS521H 给出 0)。
- LVC:
PRE或CLR在CLK前无效的建立时间为 2 ns,TI SN74LVC74A SCAS287W(Nexperia 74LVC74A 给出 1.0 ns)。 - LS:
CLR无效的建立时间为 25 ns,任意输入的保持时间为 3 ns,TI SN74LS161A SDLS060(SDLS119 中的 SN74LS74A 未列出这两项)。
上述 CMOS 数据手册(以及 TI SN74HC161 SCLS297D 或 Nexperia 74LVC161,其保持时间仅覆盖同步输入)均未列出移除时间,因此这些系列为 0。AUP、LV、LVX 和其他行采用其建立时间和保持时间。
按名称指定的原语和通用符号采用 1 ns,无建立时间或保持时间。
自定义元件通过内联模型定义,按 ref 或 value(具有该数值的所有元件)匹配。一个元件的多个条目各添加一个单元(例如四门的每个门一个)。仅包含时序的条目保留内置模型并修改其时序。
[[parts]]
ref = "U7"
primitive = "nand" # a primitive; pins map its pin keys to the part's pins
pins = { A = "1", B = "2", Y = "3" }
delay = "3ns" # every output; setup, hold, recovery and removal as well
delays = { Y = "5ns" } # or per output key
[[parts]]
value = "MYBUF8"
primitive = "74HC244" # borrow a library pinout
[[parts]]
ref = "U9"
inputs = ["1", "2", "3"] # pins by number or unique name
outputs = ["4"]
truth = ["000 1", "1-- 0", "01- z"] # first matching row wins; no match (or an x input) gives x原语引脚键(先输入,后输出);在键后添加 _N 表示低电平有效引脚或反相输出,省略可选输入以保持其无效:
| 原语 | 输入 | 输出 |
|---|---|---|
and、or、xor、nand、nor、xnor | 除 Y 外的任意键 | Y |
not、buf | 一个键 | Y |
带 _od 的任意门(nand_od、not_od、buf_od) | 与门相同 | Y,开漏:0 或 z |
tri | A、OE | Y(OE 为低电平时为 z) |
dff | D、CLK,可选 S、R、OE | Q、QN(OE 为低电平时为 z) |
jk | J、K、CLK,可选 S、R | Q、QN |
sr | S、R | Q、QN |
dlatch | D、EN,可选 R、OE | Q、QN(OE 为低电平时为 z) |
xcvr | A、B、DIR,可选 OE | A、B:相同的引脚,由另一侧的 DIR 驱动 |
mux2 | I0、I1、S,可选 EN | Y |
dec138 | A0、A1、A2、E1、E2、E3 | Y0 到 Y7 |
counter161、counter163 | 可选 R、CLK,可选 D0 到 D3、CEP、LOAD、CET | Q0 到 Q3、TC |
shift164 | A,可选 B、CLK,可选 R | Q0 到 Q7 |
shift595 | D、CLK、LATCH,可选 R、OE | Q0 到 Q7、QS |
触发器在上升沿时钟(下降沿使用键 CLK_N);S 和 R 是异步的,两者同时有效时 Q = QN = 1,与 74HC74 一致。161 立即复位,163 在下一个边沿复位。595 在 CLK 上移位,在 LATCH 上复制到输出(取同一时刻移位前的值),并在 OE 为低时悬空。
引擎保持四个电平:0、1、x(未知)和 z(悬空)。每个网络解析其驱动源:一致的强驱动源(输出、电源轨、激励)设定电平,0 对 1 产生 x 并报告冲突,上拉电阻仅在无强驱动源时计数。z 输入读取为 x。门电路仅在未知输入起作用时变为 x(例如 AND 门输入 0 输出 0),由不确定边沿(0 到 x,或 x 到 1)时钟的触发器变为 x,除非它保持原值。每个输出都有独立的延迟(传输延迟,短于延迟的脉冲会通过);事件按时间顺序运行,零延迟的变化在同一时刻的 delta 周期内稳定。零延迟环路在 1000 个 delta 周期后仍在变化时停止运行并报告网络,超过 5000 万个事件的运行也会停止。
触发器、计数器和移位寄存器根据模型时序检查其时钟输入的建立时间和保持时间:数据输入在上升时钟边沿前变化小于 setup,或之后变化小于 hold,即为违规(异步复位或置位有效时不检查)。D 锁存器以相同方式检查其 D 相对于 EN 的关闭(下降)边沿。异步复位或置位在时钟边沿前释放小于 recovery,或之后释放小于 removal,也是违规,使用系列表中的恢复和移除时间。595 还要求其 LATCH(RCLK)上升边沿至少在最后一个 CLK(SRCLK)上升边沿之后 setup;两个时钟连接在一起(同一时刻)是可以的,并锁存移位前的值。
违规时,检查覆盖的触发器、锁存器或寄存器变为 x,如同 Verilog 模型中的通知器,直到再次干净地时钟、置位或复位。在仿真上设置 on_violation = "keep" 以报告违规并保留采样值。
读数:断言通过和失败、冲突、时序违规、单元和事件。检查将每个失败的断言、冲突、时序违规或停止的运行作为仿真上的错误列出,只要结果是当前的。当规范或原理图的网表改变时,结果变为过期。examples/logic 包含两个:counter,一个 74HC161 计数到 74HC138;以及 i2c,一个开漏总线,其中控制器(两个 74LVC1G07)和目标(一个 74LVC1G06 将其 ACK 拉低 SDA)共享 4.7k 上拉,一个由 SCL 时钟的 74HC595 捕获字节,检查 START、位、ACK、字节(一个 record 总线)和 STOP。