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

📄 loadsig.c

📁 generate eye diagram from spice sim result
💻 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 + -