Shaos wrote:Надо писать редактор и вызывать
ngspice с подмножеством директив Xspice, для симуляции цифровой электроники:
Code: Select all
a6 [1 2 3] 8 nand1
.model nand1 d_nand(rise_delay = 0.5e-9 fall_delay = 0.3e-9
+ input_load = 0.5e-12
Поглядел я в описание Xspice что в составе
ngspice идёт - там даже есть возможность свои event-driven модели на сях писать
т.е. теоретически можно попробовать прикрутить туда ваши модели процыков, что для протэуса писаны - и тогда мы завоюем мир
Вот список цифровых моделей, которые уже включены в состав пакета (некоторые аргументы могут быть как единичными сигналами, так и векторами):
- d_buffer (Buffer) in out
- d_inverter (Inverter) in out
- d_and (AND) in out
- d_nand (NAND) in out
- d_or (OR) in out
- d_nor (NOR) in out
- d_xor (XOR) in out
- d_xnor (XNOR) in out
- d_tristate (Tristate buffer) in enable out
- d_pullup (Pull-up) out
- d_pulldown (Pull-down) out
- d_dff (D-flipflop) data clk set reset out Nout (parameter ic - initial state)
- d_jkff (JK-flipflop) j k clk set reset out Nout
- d_tff (Toggle flipflop) t clk set reset out Nout
- d_srff (Set-Reset flipflop) s r clk set reset out Nout
- d_dlatch (D-Latch) data enable set reset out Nout
- d_srlatch (Set-Reset Latch) s r enable set reset out Nout
- d_state (State Machine) in clk reset out (parameters state_file "filename.txt" and reset_state 0)
- d_fdiv (Frequency Divider) freq_in freq_out (parameters div_factor, high_cycles, i_count - initial count)
- d_ram (RAM) data_in data_out address write_en select (parameters select_value 1, read_delay 100e-9, ic - initial state)
- d_source (Digital Source) out (parameter input_file "source.txt" with lines time value value value...)
- d_lut (Look-Up Table) in out (parameter table_values "01X")
- d_genlut (General LUT) in out (parameter table_values "01XZ")
ещё почти у каждой модели есть параметры rise_delay, fall_delay (оба имеют значение по умолчанию 1e-9 и минимум могут быть установлены в 1e-12) и input_load (задётся в фарадах и по умолчанию составляет 1e-12).
В качестве значений на входах и выходах вышеописанных цифровых моделей могут выступать 12 состояний:
0s,0r,0z,0u,1s,1r,1z,1u,Us,Ur,Uz,Uu
где суффиксы это s=strong, r=resistive, z=high-impedance, u=unknown и значение U это так же unknown ( т.е. Uu это неизвестное значение с неизвестной силой : )
P.S. В исходниках ещё есть модель d_osc (осциллятор) и модули для связи с аналоговой частью - adc_bridge и dac_bridge (аналоговая часть по-видимому считается классическим SPICE3 через дифуры).
P.P.S. Вот под спойлером для примера исходник модели d_and, судя по всему написанный 32 года назад:
d_and/cfunc.modCode: Select all
/*.......1.........2.........3.........4.........5.........6.........7.........8
================================================================================
FILE d_and/cfunc.mod
Public Domain
Georgia Tech Research Corporation
Atlanta, Georgia 30332
PROJECT A-8503-405
AUTHORS
14 June 1991 Jeffrey P. Murray
MODIFICATIONS
27 Sept 1991 Jeffrey P. Murray
SUMMARY
This file contains the functional description of the d_and
code model.
INTERFACES
FILE ROUTINE CALLED
CMevt.c void *cm_event_alloc()
void *cm_event_get_ptr()
REFERENCED FILES
Inputs from and outputs to ARGS structure.
NON-STANDARD FEATURES
NONE
===============================================================================*/
/*=== INCLUDE FILES ====================*/
#include <stdio.h>
#include <ctype.h>
#include <math.h>
#include <string.h>
/*=== CONSTANTS ========================*/
/*=== MACROS ===========================*/
/*=== LOCAL VARIABLES & TYPEDEFS =======*/
/*=== FUNCTION PROTOTYPE DEFINITIONS ===*/
/*==============================================================================
FUNCTION cm_d_and()
AUTHORS
14 Jun 1991 Jeffrey P. Murray
MODIFICATIONS
27 Sep 1991 Jeffrey P. Murray
SUMMARY
This function implements the d_and code model.
INTERFACES
FILE ROUTINE CALLED
CMevt.c void *cm_event_alloc()
void *cm_event_get_ptr()
RETURNED VALUE
Returns inputs and outputs via ARGS structure.
GLOBAL VARIABLES
NONE
NON-STANDARD FEATURES
NONE
==============================================================================*/
/*=== CM_D_AND ROUTINE ===*/
/************************************************
* The following is the model for the *
* digital AND gate for the *
* ATESSE Version 2.0 system. *
* *
* Created 6/14/91 J.P.Murray *
************************************************/
void cm_d_and(ARGS)
{
int i, /* generic loop counter index */
size; /* number of input & output ports */
Digital_State_t *out, /* temporary output for buffers */
*out_old, /* previous output for buffers */
input; /* temp storage for input bits */
/** Retrieve size value... **/
size = PORT_SIZE(in);
/*** Setup required state variables ***/
if(INIT) { /* initial pass */
/* allocate storage for the outputs */
cm_event_alloc(0,sizeof(Digital_State_t));
/* set loading for inputs */
for (i=0; i<size; i++) LOAD(in[i]) = PARAM(input_load);
/* retrieve storage for the outputs */
out = out_old = (Digital_State_t *) cm_event_get_ptr(0,0);
}
else { /* Retrieve previous values */
/* retrieve storage for the outputs */
out = (Digital_State_t *) cm_event_get_ptr(0,0);
out_old = (Digital_State_t *) cm_event_get_ptr(0,1);
}
/*** Calculate new output value based on inputs ***/
*out = ONE;
for (i=0; i<size; i++) {
/* make sure this input isn't floating... */
if ( FALSE == PORT_NULL(in) ) {
/* if a 0, set *out low */
if ( ZERO == (input = INPUT_STATE(in[i])) ) {
*out = ZERO;
break;
}
else {
/* if an unknown input, set *out to unknown & break */
if ( UNKNOWN == input ) {
*out = UNKNOWN;
}
}
}
else {
/* at least one port is floating...output is unknown */
*out = UNKNOWN;
break;
}
}
/*** Determine analysis type and output appropriate values ***/
if (ANALYSIS == DC) { /** DC analysis...output w/o delays **/
OUTPUT_STATE(out) = *out;
}
else { /** Transient Analysis **/
if ( *out != *out_old ) { /* output value is changing */
switch ( *out ) {
/* fall to zero value */
case 0: OUTPUT_STATE(out) = ZERO;
OUTPUT_DELAY(out) = PARAM(fall_delay);
break;
/* rise to one value */
case 1: OUTPUT_STATE(out) = ONE;
OUTPUT_DELAY(out) = PARAM(rise_delay);
break;
/* unknown output */
default:
OUTPUT_STATE(out) = *out = UNKNOWN;
/* based on old value, add rise or fall delay */
if (0 == *out_old) { /* add rising delay */
OUTPUT_DELAY(out) = PARAM(rise_delay);
}
else { /* add falling delay */
OUTPUT_DELAY(out) = PARAM(fall_delay);
}
break;
}
}
else { /* output value not changing */
OUTPUT_CHANGED(out) = FALSE;
}
}
OUTPUT_STRENGTH(out) = STRONG;
}