Top secrets sources NedoPC ngs

Rev

Blame | Last modification | View Log | Download | RSS feed | ?url?

/*
 *  INFO:
 *     bsdl.cpp (C) 2002  Dr. Yuri Klimets (www.jtag.tk, jtagtools.sf.net)  
 *     E-mail: klimets@jtag.tk
 *     Rev. 1.3 - 12.10.2002
 *  
 *  
 *  DESCRIPTION:
 *     Defines functions to parse BSDL-files
 *
 *     Data structures:
 *     ----------------
 *     PINS - stores information about JTAG devices pins
 *     BS   - stores information about JTAG devices
 *
 *     Main functions:
 *     ---------------
 *     readBSD - reads JTAG DEVICE description from specified BSDL-file and
 *               stores it in the structures PINS and BS
 *
 *
 *  DISCLAIMER:
 *     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 General Public License
 *     along with this program; if not, write to the Free Software
 *     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/


#include "bsdl.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

DWORD CUR_ID=800;
DWORD CUR_PINS;

struct PINS* Pbegin;
struct BS*   BSbegin;

//----------------------------------------------------------
// GETS: stream CHAR* STR, SYM is an end symbol of stream STR  
// RETURNS: INT from stream CHAR* STR (current pointer is on the end of INT)
int getbackint(char *str,char sym) {                                  
 char ch=*str;                      
 *str=0;
 for (int i=1;*(str-i)!=sym;i++);
 i=atoi(str-i+1);
 *str=ch;
 return i;
}
//----------------------------------------------------------
// GETS: stream CHAR* STR, SYM is an end symbol of stream STR  
// RETURNS: INT from stream CHAR* STR (current pointer is on the begin of INT)
int getfwdint(char *str,char sym) {                                  
 char *s=strchr(str,sym);          
 if (s==NULL) return -1;            
 char ch=*s;
 *s=0;
 for (DWORD j=0;j<strlen(str);j++)
    if (*(str+j)<'0'||*(str+j)>'9') return -1;
 int i=atoi(str);
 *s=ch;
 return i;
}
//----------------------------------------------------------
// copy JTAG COMMAND code from SRC to DEST
int getCMDcode(char *src,char *dest) {
 for (;(*src=='0')||(*src=='1');*dest=*src,src++,dest++);
 if (*src!=')') return -1;
 *dest=0;
 return 0;
}
//----------------------------------------------------------
// copy JTAG DEVICE ID code from SRC to DEST
int getIDcode(char *src,char *dest) {
 for (;;src++) {
     if (*src=='0'||*src=='1') {*dest=*src;dest++;continue;}
     if (*src=='\"'||*src=='&') continue;
     break;
 }
 if (*src!=0) return -1;
 *dest=0;
 return 0;
}
//----------------------------------------------------------
// adds pin with name NAME to the structure PINS
// RETURNS: pointer to the new pin  
PINS *addPIN(char *name) {                        
 if (*name=='*') return NULL;
 PINS *tmp=new PINS;
 tmp->next=NULL;
 if (Pbegin==NULL) Pbegin=tmp;
   else {
     PINS *x=Pbegin;
     for (;x->next!=NULL;x=x->next);
     x->next=tmp;
   }
 tmp->name=new char[strlen(name)+1];
 tmp->altname="";
 strcpy(tmp->name,strupr(name));
 tmp->control=-1;
 tmp->input=-1;
 tmp->output=-1;
 tmp->vOUT=-1;
 tmp->prev_i='0';
 tmp->prev_o='0';
 tmp->prev_c='0';
 tmp->id_pins=CUR_PINS;
 CUR_PINS++;
 return tmp;
}
//----------------------------------------------------------
void addPINalias(char * pin_name,char * pin_alias)
{
        PINS * pin;

        pin=findPIN(pin_name);

        if(pin!=NULL)
        {
                pin->altname = pin_alias;
        }

}
//----------------------------------------------------------
// RETURNS: the pointer to the pin with name NAME
PINS *findPINalias(char *name) {
 PINS *item=Pbegin;
 for (;item!=NULL;item=item->next)
    if (strcmp(name,item->altname)==0) return item;
 return NULL;
}
//----------------------------------------------------------
// RETURNS: the pointer to the pin with name NAME
PINS *findPIN(char *name) {
 PINS *item=Pbegin;
 for (;item!=NULL;item=item->next)
    if (strcmp(name,item->name)==0) return item;
 return NULL;
}
//----------------------------------------------------------
// the same, but if pin not found it will create pin with this name
PINS *findPINx(char *name) {                          
 PINS *item=Pbegin;
 strupr(name);
 for (;item!=NULL;item=item->next)
    if (strcmp(name,item->name)==0) return item;
 return addPIN(name);
}
//----------------------------------------------------------
// delete the pin with pointer ITEM
void delPINSitem(PINS *item) {
 if (item==NULL) return;
 PINS *tmp=Pbegin;
 if (item==Pbegin) {
    if (item->name!=NULL) {
       delete[] item->name;
       item->name=NULL;
    }
    Pbegin=Pbegin->next;
    delete tmp;
    tmp=NULL;
    return;
 }
 for (;tmp->next!=NULL;tmp=tmp->next)
    if (tmp->next==item) {
       tmp->next=item->next;
       if (item->name!=NULL) {
          delete[] item->name;
          item->name=NULL;
        }
       delete item;
       item=NULL;
       return;
    }
}
//----------------------------------------------------------
// delete all pins in structure PINS
void delPINSall(PINS *item) {
 for (PINS *tmp=item;tmp!=NULL;) {
     PINS *x=tmp->next;
     if (tmp->name!=NULL) {
        delete[] tmp->name;
        tmp->name=NULL;
     }
     delete tmp;tmp=NULL;
     tmp=x;
 }
}
//-----------------------------------------------------------
// add new device to the list of jtag devices BS
void addBSitem() {
 BS *BStmp=new BS;
 BStmp->next=BSbegin;
 BSbegin=BStmp;
 BStmp->name=NULL;
 BStmp->file=NULL;
 BStmp->BYPASS=NULL;
 BStmp->EXTEST=NULL;
 BStmp->SAMPLE=NULL;
 BStmp->IDCODE=NULL;
 BStmp->ID=NULL;
 BStmp->pins=NULL;
 BStmp->DRlen=0;
 BStmp->IRlen=0;
 BStmp->DRlen=0;
 BStmp->IDlen=0;
 BStmp->PINnum=0;
 BStmp->id_bs=CUR_ID;
 CUR_ID++;
}
//-----------------------------------------------------------
// delete JTAG DEVICE with pointer item from the list
void delBSitem(BS *item) {
 if (item->name!=NULL) {delete[] item->name;item->name=NULL;}
 if (item->file!=NULL) {delete[] item->file;item->file=NULL;}
 if (item->SAMPLE!=NULL) {delete[] item->SAMPLE;item->SAMPLE=NULL;}
 if (item->IDCODE!=NULL) {delete[] item->IDCODE;item->IDCODE=NULL;}
 if (item->ID!=NULL) {delete[] item->ID;item->ID=NULL;}
 delPINSall(item->pins);
 if (item==BSbegin) BSbegin=item->next;
   else
     for (BS *tmp=BSbegin;tmp!=NULL;tmp=tmp->next)
        if (tmp->next==item) {tmp->next=item->next;break;}
 delete item;item=NULL;
}
//-----------------------------------------------------------
// RETURNS: ID of pin with name PINNAME which belongs to JTAG DEVICE with ID=id
DWORD pins2id(DWORD id,char *pinname) {                                    
 for (BS *tmp=BSbegin;tmp!=NULL;tmp=tmp->next)
     if (tmp->id_bs==id) {
        PINS *item=tmp->pins;
        for (;item!=NULL;item=item->next)
          if (strcmp(pinname,item->name)==0) return item->id_pins;
     }
 return -1;
}
//-----------------------------------------------------------
// delete whole list of JTAG DEVICES
void delBSall() {
 for (;BSbegin!=NULL;) {
     if (BSbegin->name!=NULL) {delete[] BSbegin->name;BSbegin->name=NULL;}
     if (BSbegin->file!=NULL) {delete[] BSbegin->file;BSbegin->file=NULL;}
     if (BSbegin->SAMPLE!=NULL) {delete[] BSbegin->SAMPLE;BSbegin->SAMPLE=NULL;}
     if (BSbegin->IDCODE!=NULL) {delete[] BSbegin->IDCODE;BSbegin->IDCODE=NULL;}
     if (BSbegin->ID!=NULL) {delete[] BSbegin->ID;BSbegin->ID=NULL;}
     delPINSall(BSbegin->pins);
     BS *tmp=BSbegin->next;
     delete BSbegin;BSbegin=NULL;
     BSbegin=tmp;
 }
}
//----------------------------------------------------------------
// start analysis of BSDL-file for DEVICE PINS
// STR is a pointer to the stream with BSDL-file
void PINanalysis(char *str) {                          
 char *s;
 char *buf1=new char[strlen(str)+1];
 s=buf1;
 int j=0;
 for (DWORD i=0;i<strlen(str);i++) {
     if (*(str+i)=='&'||*(str+i)=='\"'||*(str+i)==' '||*(str+i)==9) continue;
     *(s+j)=*(str+i);j++;
 }
 *(s+j)=0;
 char* prev_name=NULL;
 for (;;) {
     char* _str=NULL;
     int bracket=0;
     for (unsigned int i=0;i<strlen(s);i++) {
         if (s[i]=='(') bracket++;
         if (s[i]==')')
             if (bracket==1) break;
                else bracket--;
     }
     if (i!=strlen(s)) _str=s+i;
     if (_str==NULL) {delete[] buf1;buf1=NULL;return;}
     *_str=0;
     j=getfwdint(s,'(');
     if (j==-1) {s=_str+1;if (*s==',') s++;continue;}
     s=strchr(s,',')+1;
     char *_s=strchr(s,',');
     if (_s==NULL) {s=_str+1;if (*s==',') s++;continue;}
     *_s=0;
     char *name=s;
     if (*name=='*') name=prev_name;
        else prev_name=name;
     s=_s+1;
     _s=strchr(s,',');
     if (_s==NULL) {s=_str+1;if (*s==',') s++;continue;}
     *_s=0;
     int type,ctrl,vout;
     if (strstr(s,"input")!=NULL) type=1;
      else if (strstr(s,"output")!=NULL) type=2;
       else type=0;
     if (type==0) {s=_str+1;if (*s==',') s++;continue;}
     s=_s+1;
     if (type==2) {
         _s=strchr(s,',');
         if (_s==NULL) {s=_str+1;if (*s==',') s++;continue;}
         s=_s+1;
         _s=strchr(s,',');
         if (_s==NULL) {s=_str+1;if (*s==',') s++;continue;}
         ctrl=getfwdint(s,',');
         if (ctrl==-1) {s=_str+1;if (*s==',') s++;continue;}
         s=_s+1;
         _s=strchr(s,',');
         if (_s==NULL) {s=_str+1;if (*s==',') s++;continue;}
         vout=getfwdint(s,',');
         if (vout==-1||(vout!=0&&vout!=1)) {s=_str+1;if (*s==',') s++;continue;}
         vout=1-vout;
     }
     PINS *x=findPINx(name);
     if (x==NULL) {s=_str+1;if (*s==',') s++;continue;}
     switch (type) {
        case 1 : x->input=j;break;
        case 2 : x->output=j;x->control=ctrl;x->vOUT=vout;break;
     }
     s=_str+1;
     if (*s==',') s++;
 }
}

//-------------------------------------------------------------------
// reads JTAG DEVICE description from the file FL. CURDEV - is a current DEVICE ID
// mode=1(read with pins), mode=0(read without pins) - to optimize on speed
BS* readBSD(char* fl,int mode,DWORD curdev) {
 CUR_ID=curdev;
 CUR_PINS=0;
 if (fl==NULL) return NULL;
 FILE *in=fopen(fl,"rt");
 if (in==NULL) return NULL;
 fseek(in,0,SEEK_END);
 int filelen=ftell(in);
 rewind(in);
 char _lex[256];
 char  lex[256];
 char *buf,*_buf,*bufbegin;
 bufbegin=buf=_buf=new char[filelen];
 for (;!feof(in);) {
     if (fgets(_lex,255,in)==NULL) break;
     strlwr(_lex);
     int ind=0;
     for (DWORD i=0;i<strlen(_lex);i++)
        if (_lex[i]>=32 && _lex[i]<127) {lex[ind]=_lex[i];ind++;};
     lex[ind]=0;
     for (i=0;i<strlen(lex);i++)
        if (lex[i]!=' ') break;
     strcpy(_lex,lex+i);
     ind=0;
     for (i=0;i<strlen(_lex);i++) {
         if (ind && lex[ind-1]==' ' && (_lex[i]==',' || _lex[i]==':' || _lex[i]==' ' ||
             _lex[i]==';' || _lex[i]=='\"' || _lex[i]=='(' || _lex[i]==')' ||
             _lex[i]=='&' || _lex[i]=='[' || _lex[i]==']')) ind--;
         if (ind && _lex[i]==' ' && (lex[ind-1]==',' || lex[ind-1]==':' || lex[ind-1]==';' ||
             lex[ind-1]=='\"' || lex[ind-1]=='(' || lex[ind-1]==')' || lex[ind-1]=='&' ||
             lex[ind-1]=='[' || lex[ind-1]==']' || lex[ind-1]==' ')) continue;
         lex[ind]=_lex[i];ind++;
        }
     lex[ind]=0;
     for (i=1;i<strlen(lex);i++)
         if (lex[i]=='-' && lex[i-1]=='-') {lex[i-1]=0;break;}
     if (!strlen(lex)) continue;
     if (lex[0]=='-' && lex[1]=='-') continue;
     strcpy(_buf,lex);
     _buf+=strlen(lex);
    }
 // At this point all lexems are represented as a one long string with pointer "char *buf"
 for (;;) {
     int i;
     char *Ctmp1,*Ctmp2,*Ctmp3;
     int curpin=0;
     int flag1=0;
     int flag2=0;
     if (*buf==0) break;            // if it's an end of lexems?
     _buf=strstr(buf,";end ");
     if (_buf==NULL) break;       // there is no new entities
     _buf+=5;
     Ctmp1=strstr(_buf,";");
     if (Ctmp1==NULL) break;
     *Ctmp1=0;                     // now Ctmp points to the name of current entity
     sprintf(lex,"entity %s is",_buf);
     buf=strstr(buf,lex);
     if (buf==NULL) {buf=lex+1;continue;}
     buf+=strlen(lex);
     addBSitem();
     BSbegin->name=new char[strlen(_buf)+1];
     strcpy(BSbegin->name,strupr(_buf));
     BSbegin->file=new char[strlen(fl)+1];
     strcpy(BSbegin->file,fl);
     // looking for IR length
     _buf=strstr(buf," instruction_length ");
     if (_buf==NULL) goto m1;
     _buf=strstr(_buf,";");
     if (_buf==NULL) goto m1;
     i=getbackint(_buf,' ');
     if (i==0) goto m1;
     BSbegin->IRlen=i;
     // looking for DR length
     _buf=strstr(buf," boundary_length ");
     if (_buf==NULL) goto m1;
     _buf=strstr(_buf,";");
     if (_buf==NULL) goto m1;
     i=getbackint(_buf,' ');
     if (i==0) goto m1;
     BSbegin->DRlen=i;
     // looking for commands SAMPLE and IDCODE
     _buf=strstr(buf," instruction_opcode ");
     if (_buf==NULL) goto m1;
     Ctmp2=strstr(_buf,";");
     if (Ctmp2==NULL) goto m1;
     *Ctmp2=0;

     // BYPASS
     Ctmp3=strstr(_buf,"\"bypass(");
     if (Ctmp3==NULL) {*Ctmp2=';';goto m1;}
     i=strstr(Ctmp3,")")-Ctmp3-7;
     BSbegin->BYPASS=new char[i];
     if (getCMDcode(Ctmp3+8,BSbegin->BYPASS)) {*Ctmp2=';';goto m1;}
     
     // EXTEST
     Ctmp3=strstr(_buf,"\"extest(");
     if (Ctmp3==NULL) {*Ctmp2=';';goto m1;}
     i=strstr(Ctmp3,")")-Ctmp3-7;
     BSbegin->EXTEST=new char[i];
     if (getCMDcode(Ctmp3+8,BSbegin->EXTEST)) {*Ctmp2=';';goto m1;}
     
     // SAMPLE
     Ctmp3=strstr(_buf,"\"sample(");
     if (Ctmp3==NULL) {*Ctmp2=';';goto m1;}
     i=strstr(Ctmp3,")")-Ctmp3-7;
     BSbegin->SAMPLE=new char[i];
     if (getCMDcode(Ctmp3+8,BSbegin->SAMPLE)) {*Ctmp2=';';goto m1;}
     
     // IDCODE
         Ctmp3=strstr(_buf,"\"idcode(");
     if (Ctmp3==NULL) {*Ctmp2=';';goto m2;}
     i=strstr(Ctmp3,")")-Ctmp3-7;
     BSbegin->IDCODE=new char[i];
     getCMDcode(Ctmp3+8,BSbegin->IDCODE);
     *Ctmp2=';';
     
         // looking for device ID
     _buf=strstr(buf," idcode_register ");
     if (_buf==NULL) goto m2;
     Ctmp2=strstr(_buf,";");
     if (Ctmp2==NULL) goto m2;
     *Ctmp2=0;
     Ctmp3=strstr(_buf,"\"");
     if (Ctmp3==NULL) {*Ctmp2=';';goto m2;}
     if (getIDcode(Ctmp3+1,lex)) {*Ctmp2=';';goto m2;}
     if (strlen(lex)==0) {*Ctmp2=';';goto m2;}
     BSbegin->ID=new char[strlen(lex)+1];
     strcpy(BSbegin->ID,lex);
     BSbegin->IDlen=strlen(lex);
     *Ctmp2=';';
m2:  
     // looking for device pins
     if (mode==1) {
         _buf=strstr(buf," boundary_register ");
         if (_buf==NULL) goto m1;
         Ctmp2=strstr(_buf,";");
         if (Ctmp2==NULL) goto m1;
         *Ctmp2=0;
         Ctmp3=strstr(_buf,"\"");
         if (Ctmp3==NULL) {*Ctmp2=';';goto m1;}
         Pbegin=NULL;
         PINanalysis(Ctmp3);
         if (Pbegin==NULL) {*Ctmp2=';';goto m1;}
         PINS *x;
         x=Pbegin;
         for (;Pbegin!=NULL;) {
             if (Pbegin->input==-1&&Pbegin->output==-1)
                {Pbegin=Pbegin->next;delPINSitem(x);x=Pbegin;continue;}
             break;
         }
         if (Pbegin==NULL) goto m1;
         curpin=0;
         for (;x->next!=NULL;x=x->next) {
             if (x->next->input==-1&&x->next->output==-1) {
                 delPINSitem(x->next);
                 if (x->next==NULL) break;
                 continue;
             }
             curpin++;
         }  
         BSbegin->pins=Pbegin;
         BSbegin->PINnum=curpin+1;
         buf=Ctmp1+1;continue;
        }
      else {BSbegin->pins=NULL;BSbegin->PINnum=0;buf=Ctmp1+1;continue;}
m1:  
     buf=Ctmp1+1;
     delBSitem(BSbegin);
     continue;
 }
 delete[] bufbegin;bufbegin=NULL;
 fclose(in);
 return BSbegin;
}