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.mod
 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;
}