agentee

Simulación

Simulación lógica

Una simulación por eventos de las partes digitales de un esquemático: modelos de la serie 74, primitivas, estímulo, aserciones, setup y hold, salida VCD.

Una simulación por eventos de las partes digitales de un esquemático, directamente desde su lista de redes; no se necesita layout. agentee new sim NAME --kind logic (MCP new_item con kind = "sim" y sim_kind = "logic") escribe un archivo inicial con un reloj, un reset y una aserción con reloj para que la renombres a tus redes; --kind fdtd, el valor predeterminado, inicia una ejecución FDTD en su lugar. agentee sim NAME (MCP run_sim) escribe NAME.result.json y una forma de onda VCD NAME.vcd junto a la especificación; el visor dibuja una traza por cada red registrada en función del tiempo.

En la vista de forma de onda, la rueda del ratón (o pellizco, o ctrl y la rueda) hace zoom alrededor del puntero, un arrastre o un desplazamiento lateral desplaza la vista, un doble clic ajusta toda la ejecución y un clic fija el cursor de tiempo, ajustado a un borde de la fila de debajo dentro de unos pocos píxeles. + y - hacen zoom alrededor del cursor, las teclas de flecha desplazan, F o Home ajusta, Escape quita el cursor y N y P llevan el cursor al siguiente y al anterior marcador. Con más filas de las que caben, la rueda sobre los nombres, un arrastre o clic en la barra del borde derecho, y Page Up y Page Down desplazan las filas (top=N en --show empieza en la fila N). La columna junto a los nombres lee todas las filas en el cursor (en el puntero si no hay cursor, si no en el borde derecho de la vista), y la pista al pasar el ratón da el tiempo desde el cursor. Las redes llamadas X[0] a X[n], o X0 a Xn (también X0_N a Xn_N), se pliegan en una fila de bus dibujada en hexadecimal, MSB primero, con un nibble de x para cualquier bit desconocido y z para uno flotante; igual ocurre con una entrada record { name, nets }. Haz clic en el nombre de un bus para abrir sus bits. El VCD guarda los mismos buses como vectores en lugar de sus bits: Q0 a Q3 como $var wire 4 # Q [3:0] $end, Y0_N a Y7_N como Y_N [7:0] y un bus record de n redes como NAME [n-1:0], MSB primero. Los marcadores a lo largo de la parte superior muestran cada aserción fallida (rojo, en el tiempo en que se comprobó), violación de temporización (ámbar) y contención (violeta), con un punto en las filas de las redes implicadas; pasa el ratón por encima para ver su mensaje y haz clic para poner el cursor allí. Una ejecución conserva sus primeros 10000 marcadores, y la cabecera indica limitado cuando llega a ese número. agentee render NAME --show from=300ns,to=900ns,cursor=550ns,open=Q[3:0] dibuja la misma vista sin interfaz.

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--"]

Un reloj está en bajo hasta phase y luego en alto durante duty de cada period; sin phase, empieza en alto en 0. Un estímulo impulsa su red como un conductor fuerte; en una red de alimentación, sustituye el riel. Una comprobación at lee la red una vez que todo en ese tiempo se ha estabilizado; una secuencia lee las redes justo antes de cada flanco limpio (de 0 a 1, o de 1 a 0) del reloj, de modo que una salida registrada se ve tal como estaba cuando llegó el flanco. Las redes se nombran como en el esquemático, y una red unida a otra mediante un enlace de 0 ohmios responde a cualquiera de los dos nombres.

La lista de redes se convierte en celdas de la siguiente manera:

  • Las redes con style = "power" y los símbolos de alimentación (un símbolo con power = true) son fuentes constantes: un nombre con GND, o que empieza por VSS, VEE o 0V, es 0; cualquier otro es 1 (PWR_FLAG se omite).
  • Una resistencia (R) de 0 ohmios, un puente (JP, SJ, pines 1 y 2) y una unión de redes (NT) unen sus redes en una sola. Cualquier otra resistencia entre un riel y una red es una resistencia de subida o bajada, un conductor débil del nivel del riel; entre dos redes de señal, las une; entre dos rieles, se omite.
  • Los condensadores, inductores, cuentas, filtros, diodos, LEDs, puntos de prueba, agujeros, fiduciales y cristales (C, L, FB, FL, D, LED, TP, H, MH, FID, Y, X) se omiten.
  • Las piezas cuyo valor (o, en su defecto, nombre de símbolo) contiene un número de la serie 74 toman el modelo integrado por número de pin: 74HC00, SN74LVC1G08DBVR y CD74HCT04E coinciden todos. La biblioteca cubre 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 y 595, las puertas simples 1G00, 1G02, 1G04, 1G06, 1G07, 1G08, 1G14, 1G17, 1G32, 1G34, 1G74, 1G79, 1G80, 1G86, 1G125, 1G126 y 1G157, y las puertas dobles 2G00, 2G02, 2G04, 2G08, 2G14, 2G17, 2G32, 2G34, 2G74, 2G86, 2G125 y 2G126. Una unidad de un símbolo de varias unidades que no está colocada se omite; un pin colocado sin red se lee como flotante (z).
  • Los disparadores de Schmitt 14 (y 1G14, 2G14) son inversores; la simulación no tiene flanco analógico lento sobre el que actúe la histéresis. El 573 es ocho dlatch y el 574 ocho dff, cada uno con el OE compartido (pin 1, activo en bajo) que deja las salidas flotantes. El 245 es ocho xcvr: con OE (pin 19) en bajo, impulsa B desde A mientras DIR (pin 1) está en alto y A desde B mientras está en bajo. El 01, 03 (cuádruple NAND), 05, 06, 1G06 (inversores) y 07, 1G07 (buffers) son de drenador abierto: tiran a bajo o sueltan (z), y una resistencia de subida hace el 1. Todo 01 tiene el esquema de pines del 7402 (salidas en 1, 4, 10, 13, entradas después de cada una), según TI SDLS026 (SN7401, SN74LS01) y Renesas REJ03D0532 (HD74HC01); el 03 tiene el del 7400, según TI SCLS077 (SN74HC03).
  • Una puerta cuyos pines de salida son todos open_collector en su símbolo también es de drenador abierto.
  • Las piezas cuyo valor o símbolo es un nombre de primitiva (AND, NAND3, OR, NOR, XOR, XNOR, NOT, INV, BUF, TRIBUF, DFF, JKFF, SRLATCH, DLATCH, MUX2) mapean sus pines por nombre: D, CLK (también C, CP, CK), S / SET / PRE, R / RST / CLR, EN, OE, Q, ~{Q}; la salida de una puerta es su pin output (o Y, Q, OUT) y cualquier otro pin de señal es una entrada. Una barra superior (~{R}), un # final o _N, o una forma de pin invertida hacen que el pin sea activo en bajo.
  • Cualquier otra pieza es un error que la nombra, salvo que esté en ignore o tenga un modelo [[parts]].

Tiempo de la familia, a partir de las letras de la familia después de 74 (retraso de propagación, setup, hold, y recuperación y eliminación de un set o reset asíncrono):

FamiliaRetrasoSetupHoldRecuperaciónEliminación
HC, HCT10 ns15 ns3 ns8 ns0
AHC, AHCT, VHC, VHCT6 ns5 ns1 ns3.5 ns0
AC, ACT6 ns4 ns1 ns2.4 ns0
LVC4 ns3 ns1 ns2 ns0
ALVC, LVT, ALVT, AUC, AVC4 ns2 ns1 ns2 ns0
AUP, LV, LVX6 ns3 ns1 ns3 ns1 ns
LS y 74 simple15 ns20 ns5 ns25 ns3 ns
otros10 ns10 ns2 ns10 ns2 ns

La recuperación y la eliminación son mínimos de la hoja de datos entre -40 y 85 C a 4.5 V (familias de 5 V) o 3.3 V (LVC), el mayor de TI y Nexperia cuando ambos listan uno:

  • HC, HCT: 8 ns trec de nSD, nRD a nCP, Nexperia 74HC_HCT74 rev 9 (TI SN74HC74 SCLS094F da 6 ns, TI CD74HC74 SCHS124E 8 ns, llamado trem allí).
  • AHC, AHCT: 3.5 ns trec de nRD a nCP para el 74AHCT74 (3.0 ns para el 74AHC74), Nexperia 74AHC_AHCT74 rev 11 (TI SN74AHC74 SCLS255N da 3 ns).
  • AC, ACT: 2.4 ns trec a 5 V, TI CD74AC74 SCHS231E y CD74ACT74 SCHS321A (TI SN74AC74 SCAS521H da 0).
  • LVC: 2 ns setup de PRE o CLR inactivo antes de CLK, TI SN74LVC74A SCAS287W (Nexperia 74LVC74A da 1.0 ns).
  • LS: 25 ns setup de CLR inactivo y 3 ns hold en cualquier entrada, TI SN74LS161A SDLS060 (el SN74LS74A en SDLS119 no lista ninguno).

Ninguna de las hojas de datos CMOS anteriores (ni TI SN74HC161 SCLS297D o Nexperia 74LVC161, cuyo hold cubre solo las entradas síncronas) lista un tiempo de eliminación, por lo que es 0 allí. Las filas AUP, LV, LVX y otras toman su setup y hold.

Las primitivas por nombre y los símbolos genéricos toman 1 ns y no tienen setup ni hold.

Una pieza personalizada obtiene un modelo en línea, coincidente por ref o por value (todas las piezas con ese valor). Varias entradas para una pieza añaden una celda cada una (una por puerta de un cuádruple, por ejemplo). Una entrada con solo tiempo mantiene el modelo integrado y cambia su tiempo.

[[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

Claves de pin de primitiva (entradas, luego salidas); añade _N a una clave para un pin activo en bajo o una salida invertida, y omite una entrada opcional para mantenerla inactiva:

PrimitivaEntradasSalidas
and, or, xor, nand, nor, xnorcualquier clave excepto YY
not, bufuna claveY
cualquier puerta con _od (nand_od, not_od, buf_od)como la puertaY, drenador abierto: 0 o z
triA, OEY (z cuando OE está en bajo)
dffD, CLK, opcional S, R, OEQ, QN (z cuando OE está en bajo)
jkJ, K, CLK, opcional S, RQ, QN
srS, RQ, QN
dlatchD, EN, opcional R, OEQ, QN (z cuando OE está en bajo)
xcvrA, B, DIR, opcional OEA, B: los mismos pines, impulsados desde el otro lado por DIR
mux2I0, I1, S, EN opcionalY
dec138A0, A1, A2, E1, E2, E3Y0 a Y7
counter161, counter163R opcional, CLK, D0 a D3 opcionales, CEP, LOAD, CETQ0 a Q3, TC
shift164A, B opcional, CLK, R opcionalQ0 a Q7
shift595D, CLK, LATCH, R opcional, OEQ0 a Q7, QS

Los biestables se relajan en el flanco de subida (clave CLK_N para el de bajada); S y R son asincrónicos y si ambos están activos, Q = QN = 1, como en un 74HC74. El 161 se reinicia de inmediato, el 163 en el siguiente flanco. Un 595 desplaza en CLK, copia a sus salidas en LATCH (el valor de antes del desplazamiento en el mismo instante) y deja las salidas en alta impedancia mientras OE está bajo.

El motor mantiene cuatro niveles: 0, 1, x (desconocido) y z (flotante). Cada red resuelve sus conductores: los conductores fuertes (salidas, raíles, estímulos) que coinciden fijan el nivel; 0 contra 1 da x y una contención reportada, y las resistencias de polarización solo cuentan cuando no hay ningún conductor fuerte activo. Una entrada z se lee como x. Las puertas solo pasan a x cuando la entrada desconocida importa (0 en una AND es 0), y un biestable con un flanco de reloj incierto (de 0 a x, o de x a 1) pasa a x a menos que mantenga su valor. Cada salida tiene su propio retardo (de transporte, por lo que los pulsos más cortos que el retardo pasan); los eventos se ejecutan en orden temporal, y los cambios con retardo cero se asientan en ciclos delta en el mismo instante. Un bucle de retardo cero que sigue cambiando después de 1000 ciclos delta detiene la ejecución y reporta las redes, igual que una ejecución que supera los 50 millones de eventos.

Los biestables, contadores y registros de desplazamiento comprueban setup y hold en sus entradas con reloj contra el temporizado del modelo: una entrada de datos que cambió menos de setup antes de un flanco de subida del reloj, o menos de hold después, es una violación (no se comprueba mientras un reinicio o seteo asincrónico esté activo). Un latch D comprueba su D contra el flanco de cierre (de bajada) de EN de la misma manera. Un reinicio o seteo asincrónico liberado menos de recovery antes de un flanco de reloj, o menos de removal después, también es una violación, con el recovery y removal de la tabla de la familia. Un 595 también requiere que su flanco de subida de LATCH (RCLK) esté al menos setup después del último flanco de subida de CLK (SRCLK); los dos relojes unidos (en el mismo instante) está bien y captura el valor de antes del desplazamiento.

En una violación, el biestable, latch o registro que cubre la comprobación pasa a x, como hacen los modelos Verilog con sus notifiers, hasta que se reloje, setee o reinicie limpiamente de nuevo. Establece on_violation = "keep" en la simulación para reportar la violación y mantener el valor muestreado en su lugar.

Lecturas: aserciones superadas y fallidas, conteniones, violaciones de temporizado, celdas y eventos. La comprobación lista cada aserción fallida, contención, violación de temporizado o ejecución detenida como un error en la simulación, mientras el resultado esté actual. El resultado queda obsoleto cuando cambia la especificación o el netlist del esquemático. examples/logic contiene dos: counter, un 74HC161 contando hacia un 74HC138, e i2c, un bus de drenador abierto donde un controlador (dos 74LVC1G07) y un destino (un 74LVC1G06 que baja SDA para su ACK) comparten polarizaciones de 4.7k, y un 74HC595 con reloj SCL captura el byte, comprobado para START, los bits, el ACK, el byte (un bus record) y STOP.

docs/format.md · Markdown para agentes