⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 loadsig.c

📁 hspice toolbox with matlab.
💻 C
📖 第 1 页 / 共 3 页
字号:
/*
 * loadsig.c: retrieval of HSPICE data into MATLAB
 *   written by Michael Perrott while at Silicon
 *   Laboratories.  This code leveraged the work of
 *   Stephen G. Tell (i.e., his Gwave viewer) to
 *   develop the Hspice loading functions.  At this
 *   point, the code here has little similarity to the
 *   routines he provided, but many thanks to Stephen
 *   for providing enough info to get started.
 *   For those wishing to modify this code - good luck!
 *   Unfortunatley, it is quite "hacked" due 
 *   to the fact that the actual binary format of Hspice output
 *   was never provided (i.e., I simply updated the
 *   code each time a new issue was found), and due to the
 *   fact that I had little time to develop it.  However,
 *   after years of use, it's pretty solid now.  
 *
 *   To compile this code into a mex file for Matlab, simply
 *   run Matlab in the directory that loadsig.c is contained
 *   and then type:
 *   mex loadsig.c
 *   You'll then have a loadsig mex function for whatever 
 *   computer (i.e., Sun, Linux, Windows) that you're running 
 *   on at the time.
 *
 *   I do ask for one thing for those that use this code - please
 *   keep my name and Silicon Labs attached to it when the user
 *   first executes it (as currently done).  I am not particularly
 *   interested in getting anything for this package other then 
 *   recognition, but I do want that since this was a nontrivial 
 *   amount of work.  Of course, if you want to throw money at me,
 *   I'm happy to accomodate you. :)  - Michael Perrott 6/3/03
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the MxFree
 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 */


#define MAX_NAME_LENGTH 1000
#define MAX_HEADER_BLOCKS 100
#define TIME 1
#define FREQUENCY 4
#define VOLTAGE 2
#define CURRENT 3
#define UNKNOWN 0

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <float.h>
#include "mat.h"
#include "mex.h"
 
typedef struct  
  {  
   char **signal_name, **sweep_name;
    int  *signal_type;  /* i.e. FREQ, TIME, VOLTAGE ... */
   int num_signals, num_data_rows, num_data_cols, nauto;
   int current_column, cur_sweep, num_sweeps, num_sweep_vars, num_sweep_names;
   int *signal_first_row,*signal_num_rows;
   float **signal_data, **sweep_data;
   int block_size;
} SpiceData;  

int fread_float_values(char *simsource,float *fval, FILE *fp);
size_t fread_int_values(char *simsource, unsigned int *ibuf, 
                        int size_of_block, FILE *fp);
int hs_determine_variables(FILE *fp, SpiceData *sf, char *simsource);
void hs_process_header(char *line, SpiceData *sf);
int hs_read_column(FILE *fp, SpiceData *sf, char *simsource);
SpiceData *init_SpiceData(int num_signals, int nauto, int num_data_rows, int num_data_cols, int num_sweeps, int num_sweep_vars, int num_sweep_names, int block_size);
int hs_determine_num_data_rows(char *line, int num_signals, int nauto, 
    int *ind_sig_type, int num_sweep_names, int *num_sweep_vars);
SpiceData *hs_allocate_sf(FILE *fp, char *simsource);
int hs_validate_column(FILE *fp, int num_data_rows, int current_column, int num_sweep_vars, int block_size, char *simsource, int col_count);
void free_SpiceData(SpiceData *A);


void mexFunction(int nlhs, mxArray *plhs[],
                 int nrhs, const mxArray *prhs[])
{
SpiceData *sf;
FILE *fp;
int i,j,k,m,sweep_name_num;
float val;
/* char name[MAX_NAME_LENGTH],filename[MAX_NAME_LENGTH]; */
char filename[MAX_NAME_LENGTH], simsource[MAX_NAME_LENGTH];
mxArray *pa1;
double *matData;
const char *field_name[20] = {"name","data"};
static first_run=0;



/* mexPrintf("field_name = %s, %s\n",field_name[0],field_name[1]); */

if (nrhs != 1)
  mexErrMsgTxt("Error: missing filename. Usage:  x = loadsig('filename')");
if (!mxIsChar(prhs[0]))
  mexErrMsgTxt("Error: filename must be a string");
if (nlhs != 1)
  mexErrMsgTxt("Error: missing output variable.  Usage:  x = loadsig('filename')");

mxGetString(prhs[0],filename,MAX_NAME_LENGTH);

if (first_run == 0)
  {
   first_run = 1;
   mexPrintf("\n*********************************************************\n");
   mexPrintf("               Hspice Toolbox for Matlab\n");
   mexPrintf(" written by Michael Perrott (http://www-mtl.mit.edu/~perrott)\n");
   mexPrintf("   while at Silicon Laboratories (http://www.silabs.com)\n");
   mexPrintf("     Copyright (C) 1999 by Silicon Laboratories, Inc.\n");
   mexPrintf("     This software is distributed under the terms of\n");
   mexPrintf("       the GNU Public License (see the COPYING file\n");
   mexPrintf("  for more details), and comes with no warranty or support\n");
   mexPrintf("*********************************************************\n\n");
  }

if ((fp = fopen(filename,"rb")) == NULL)   
   mexErrMsgTxt("Error:  file can't be opened");


sf = hs_allocate_sf(fp,simsource);

/*
mexPrintf("num_data_cols = %d, num_data_rows = %d, num_signals = %d\n",
   sf->num_data_cols, sf->num_data_rows, sf->num_signals);
mexPrintf("current_col = %d\n",sf->current_column);
*/

if (sf == NULL)
   return;
if (hs_determine_variables(fp,sf,simsource) == 0)
   return;

/*
mexPrintf("num_data_cols = %d, num_data_rows = %d, num_signals = %d\n",
   sf->num_data_cols, sf->num_data_rows, sf->num_signals);
mexPrintf("current_col = %d\n",sf->current_column);
*/

for (k = 0; k < sf->num_signals; k++)
  {
   for (i = 0; sf->signal_name[k][i] != '\0'; i++)
      if (sf->signal_name[k][i] == '.' || sf->signal_name[k][i] == '(' ||
          sf->signal_name[k][i] == ')' || sf->signal_name[k][i] == '+' ||
          sf->signal_name[k][i] == '[' || sf->signal_name[k][i] == ']' ||
          sf->signal_name[k][i] == '-' || sf->signal_name[k][i] == '*' ||
          sf->signal_name[k][i] == '/' || sf->signal_name[k][i] == ',')
         sf->signal_name[k][i] = '_';
   /*
   if (k == 0)
      sprintf(name,"i");
   else
      sprintf(name,"d");
   switch(sf->signal_type[k]) 
      {
      case TIME:
		strcat(name,"t_");
		break;
      case FREQUENCY:
                strcat(name,"f_");
		break;
      case VOLTAGE:
		strcat(name,"v_");
		break;
      case CURRENT:
		strcat(name,"i_");
		break;
      default:
		strcat(name,"u_");
		break;
      }
   strncat(name,sf->signal_name[k],MAX_NAME_LENGTH-3);
   sprintf(sf->signal_name[k],"%s",name);
   */
  }

/*
for (i = 0; i < sf->num_signals; i++)
   mexPrintf("%s, type = %d, first_row = %d, num_rows = %d\n",
       sf->signal_name[i], sf->signal_type[i],
       sf->signal_first_row[i], sf->signal_num_rows[i]);
mexPrintf("num_signals = %d, nauto = %d\n",
        sf->num_signals, sf->nauto);
mexPrintf("num_data_rows = %d, num_data_cols = %d, current_column = %d\n",
        sf->num_data_rows, sf->num_data_cols, sf->current_column);
*/

for (k = 0; k < sf->num_sweeps; k++)
  {
   sf->cur_sweep = k;
   sf->current_column = 0;
   if (k > 0)
     {
     while(1)
       {
       if (fread_float_values(simsource,&val, fp) != 1)
	 {
          mexPrintf("error: premature file end\n");
          return;
	 }
       if (strncmp(simsource,"hspice",6) == 0)
	 {
          if (val >= (1e30 - DBL_EPSILON))
	    {
             fseek(fp,20,SEEK_CUR);
             break;
	     }
	 } 
       }
     }
   for (i = 0; i < sf->num_data_cols; i++)
     {
      if(hs_read_column(fp,sf,simsource) == 1)
	{
         mexPrintf("error:  premature break\n");
         break;
	}
     }
  }
fclose(fp);

/* write into MATLAB structure */
plhs[0] = mxCreateStructMatrix(sf->num_signals+sf->num_sweep_vars,1,2,field_name);

/*
mexPrintf("num fields = %d\n",mxGetNumberOfFields(plhs[0]));
mexPrintf("size = %d\n",mxGetN(plhs[0])*mxGetM(plhs[0]));
for (i = 0; i < 2; i++)
  mexPrintf("field name = %s\n",mxGetFieldNameByNumber(plhs[0],i));
*/

for (k = 0; k < sf->num_signals; k++)
    {
     /* copy over the signal name to the structure */
     pa1 = mxCreateString(sf->signal_name[k]);  
     mxSetField(plhs[0],k,field_name[0],pa1);

     if (sf->signal_num_rows[k] == 1)
        pa1 = mxCreateDoubleMatrix(sf->num_data_cols,sf->num_sweeps,mxREAL);
     else
        pa1 = mxCreateDoubleMatrix(sf->num_data_cols,sf->num_sweeps,mxCOMPLEX);

     /* copy over the spice data to the matlab matrix */
     matData = mxGetPr(pa1);
     j = 0; /* first data row */
     for (i = 0; i < sf->num_data_cols; i++)   
       {
        for (m = 0; m < sf->num_sweeps; m++)
          {
	   matData[i + m*sf->num_data_cols] = 
             sf->signal_data[sf->signal_first_row[k]+j+m*sf->num_data_rows][i];
          }   
       }
     if (sf->signal_num_rows[k] == 2)
       {
       /* mexPrintf("complex for k = %d\n",k); */
        matData = mxGetPi(pa1);
        j = 1; /* second data row */
        for (i = 0; i < sf->num_data_cols; i++)   
          {
          for (m = 0; m < sf->num_sweeps; m++)
            {
	    matData[i + m*sf->num_data_cols] = 
             sf->signal_data[sf->signal_first_row[k]+j+m*sf->num_data_rows][i];
            }   
          }
       }
        mxSetField(plhs[0],k,field_name[1],pa1);
    }

/* copy sweep parameters */

for (sweep_name_num = 0; k < sf->num_signals+sf->num_sweep_vars; k++, sweep_name_num++)
    {
     /* copy over the sweep parameter name to the structure */
     pa1 = mxCreateString(sf->sweep_name[sweep_name_num]); 
     mxSetField(plhs[0],k,field_name[0],pa1);

     pa1 = mxCreateDoubleMatrix(1,sf->num_sweeps,mxREAL);

     /* copy over the spice data to the matlab matrix */
     matData = mxGetPr(pa1);
     for (i = 0; i < sf->num_sweeps; i++)   
       {
	matData[i] = sf->sweep_data[sweep_name_num][i];
       }
     mxSetField(plhs[0],k,field_name[1],pa1);
    }

free_SpiceData(sf);
return;
}

SpiceData *hs_allocate_sf(FILE *fp, char *simsource)
{
	char *ahdr;
	unsigned int ahdrsize, term_seq;
	int nprobe,num_signals,nauto,block_size;
	char nbuf[16], version[16], full_version[50];
        int data_rows,i,data_cols,nsweep_var,nsweep_names;
        int sig_type,val_flag,sweep_count;
        int char_position,j;
        unsigned int header_seg_length[MAX_HEADER_BLOCKS],k;	
	unsigned int ibuf[4];
        int col_count;

	/* probably not necessary to rewind, but just to make sure ... */
        rewind(fp);

	/* assume hspice is simulation source by default */
	sprintf(simsource,"hspice");
	if(fread_int_values(simsource,ibuf, 4, fp) != 4) 
           {
	    mexPrintf("error in hs_allocate_sf: EOF reading block1 header\n");
            return(NULL);
	   } 
	if(ibuf[0] != 4 || ibuf[2] != 4) 
           {
	    /*  check if Windows Hspice */
	    /*
	    printf("ibuf[0] = %x, ibuf[1] = %x, ibuf[2] = %x, ibuf[3] = %x\n",
		    ibuf[0],ibuf[1],ibuf[2],ibuf[3]);
	    */
	    if (ibuf[0] == 0x4000000 && ibuf[2] == 0x4000000)
	       {
	       sprintf(simsource,"hspice_win");
	       /*  printf("sim = %s\n",simsource); */
	       rewind(fp);
   	       if (fread_int_values(simsource,ibuf, 4, fp) != 4) 
                   {
	           mexPrintf("error in hs_allocate_sf: EOF reading block1 header\n");
                   return(NULL);
	           } 
	       /* printf("ibuf[0] = %x, ibuf[1] = %x, ibuf[2] = %x, ibuf[3] = %x\n",
		  ibuf[0],ibuf[1],ibuf[2],ibuf[3]); */

               if (ibuf[0] != 4 || ibuf[2] != 4)
		 {
  	          mexPrintf("error in hs_allocate_sf: unexpected values in block1 header\n");
                  return(NULL);
		 }
	       }
            else
	       {
  	       mexPrintf("error in hs_allocate_sf: unexpected values in block1 header\n");
               return(NULL);
	       }
 	   }

        ahdrsize = 0;
        for (i = 0; i < MAX_HEADER_BLOCKS; i++)
	  {
          header_seg_length[i] =ibuf[3];
          ahdrsize += header_seg_length[i];
          fseek(fp,header_seg_length[i]-8,SEEK_CUR);
 	  if(fread_int_values(simsource,&term_seq,1, fp) != 1) 
             {
	     mexPrintf("error in hs_allocate_sf: EOF reading block trailer\n");
             return(NULL);
	     }
	  /* mexPrintf("term_seq = %x\n",term_seq); */
          fseek(fp,4,SEEK_CUR);
 	  if(fread_int_values(simsource,ibuf,1, fp) != 1) 
             {
	     mexPrintf("error in hs_allocate_sf: EOF reading block trailer\n");
             return(NULL);
	     }
	  /*
           mexPrintf("ibuf[0] = %x, ibuf[1] = %x, ibuf[2] = %x, ibuf[3] = %x, head_length = %x\n",
           ibuf[0],ibuf[1],ibuf[2],ibuf[3],header_seg_length[i]);
	  */
          if (ibuf[0] != header_seg_length[i])
	    {
	     mexPrintf("error in hs_allocate_sf:  block trailer mismatch\n");
             return(NULL);
	    }
    	  if(fread_int_values(simsource,ibuf, 4, fp) != 4) 
            {
	    mexPrintf("error in hs_allocate_sf:  EOF reading block header\n");
	    return(NULL);
	    }
	  if(ibuf[0] != 4 || ibuf[2] != 4) 
            {
	    mexPrintf("error in hs_allocate_sf:  unexepected values in block header\n");
	    return(NULL);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -