Subversion Repositories ngs

Rev

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

  1. /*
  2.  *  INFO:
  3.  *     bsdl.cpp (C) 2002  Dr. Yuri Klimets (www.jtag.tk, jtagtools.sf.net)  
  4.  *     E-mail: klimets@jtag.tk
  5.  *     Rev. 1.3 - 12.10.2002
  6.  *  
  7.  *  
  8.  *  DESCRIPTION:
  9.  *     Defines functions to parse BSDL-files
  10.  *
  11.  *     Data structures:
  12.  *     ----------------
  13.  *     PINS - stores information about JTAG devices pins
  14.  *     BS   - stores information about JTAG devices
  15.  *
  16.  *     Main functions:
  17.  *     ---------------
  18.  *     readBSD - reads JTAG DEVICE description from specified BSDL-file and
  19.  *               stores it in the structures PINS and BS
  20.  *
  21.  *
  22.  *  DISCLAIMER:
  23.  *     This program is free software; you can redistribute it and/or modify
  24.  *     it under the terms of the GNU General Public License as published by
  25.  *     the Free Software Foundation; either version 2 of the License, or
  26.  *     (at your option) any later version.
  27.  *
  28.  *     This program is distributed in the hope that it will be useful,
  29.  *     but WITHOUT ANY WARRANTY; without even the implied warranty of
  30.  *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  31.  *     GNU General Public License for more details.
  32.  *
  33.  *     You should have received a copy of the GNU General Public License
  34.  *     along with this program; if not, write to the Free Software
  35.  *     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  36. */
  37.  
  38. #include "bsdl.h"
  39. #include <stdio.h>
  40. #include <string.h>
  41. #include <stdlib.h>
  42.  
  43. DWORD CUR_ID=800;
  44. DWORD CUR_PINS;
  45.  
  46. struct PINS* Pbegin;
  47. struct BS*   BSbegin;
  48.  
  49. //----------------------------------------------------------
  50. // GETS: stream CHAR* STR, SYM is an end symbol of stream STR  
  51. // RETURNS: INT from stream CHAR* STR (current pointer is on the end of INT)
  52. int getbackint(char *str,char sym) {                                  
  53.  char ch=*str;                      
  54.  *str=0;
  55.  for (int i=1;*(str-i)!=sym;i++);
  56.  i=atoi(str-i+1);
  57.  *str=ch;
  58.  return i;
  59. }
  60. //----------------------------------------------------------
  61. // GETS: stream CHAR* STR, SYM is an end symbol of stream STR  
  62. // RETURNS: INT from stream CHAR* STR (current pointer is on the begin of INT)
  63. int getfwdint(char *str,char sym) {                                  
  64.  char *s=strchr(str,sym);          
  65.  if (s==NULL) return -1;            
  66.  char ch=*s;
  67.  *s=0;
  68.  for (DWORD j=0;j<strlen(str);j++)
  69.     if (*(str+j)<'0'||*(str+j)>'9') return -1;
  70.  int i=atoi(str);
  71.  *s=ch;
  72.  return i;
  73. }
  74. //----------------------------------------------------------
  75. // copy JTAG COMMAND code from SRC to DEST
  76. int getCMDcode(char *src,char *dest) {
  77.  for (;(*src=='0')||(*src=='1');*dest=*src,src++,dest++);
  78.  if (*src!=')') return -1;
  79.  *dest=0;
  80.  return 0;
  81. }
  82. //----------------------------------------------------------
  83. // copy JTAG DEVICE ID code from SRC to DEST
  84. int getIDcode(char *src,char *dest) {
  85.  for (;;src++) {
  86.      if (*src=='0'||*src=='1') {*dest=*src;dest++;continue;}
  87.      if (*src=='\"'||*src=='&') continue;
  88.      break;
  89.  }
  90.  if (*src!=0) return -1;
  91.  *dest=0;
  92.  return 0;
  93. }
  94. //----------------------------------------------------------
  95. // adds pin with name NAME to the structure PINS
  96. // RETURNS: pointer to the new pin  
  97. PINS *addPIN(char *name) {                        
  98.  if (*name=='*') return NULL;
  99.  PINS *tmp=new PINS;
  100.  tmp->next=NULL;
  101.  if (Pbegin==NULL) Pbegin=tmp;
  102.    else {
  103.      PINS *x=Pbegin;
  104.      for (;x->next!=NULL;x=x->next);
  105.      x->next=tmp;
  106.    }
  107.  tmp->name=new char[strlen(name)+1];
  108.  tmp->altname="";
  109.  strcpy(tmp->name,strupr(name));
  110.  tmp->control=-1;
  111.  tmp->input=-1;
  112.  tmp->output=-1;
  113.  tmp->vOUT=-1;
  114.  tmp->prev_i='0';
  115.  tmp->prev_o='0';
  116.  tmp->prev_c='0';
  117.  tmp->id_pins=CUR_PINS;
  118.  CUR_PINS++;
  119.  return tmp;
  120. }
  121. //----------------------------------------------------------
  122. void addPINalias(char * pin_name,char * pin_alias)
  123. {
  124.         PINS * pin;
  125.  
  126.         pin=findPIN(pin_name);
  127.  
  128.         if(pin!=NULL)
  129.         {
  130.                 pin->altname = pin_alias;
  131.         }
  132.  
  133. }
  134. //----------------------------------------------------------
  135. // RETURNS: the pointer to the pin with name NAME
  136. PINS *findPINalias(char *name) {
  137.  PINS *item=Pbegin;
  138.  for (;item!=NULL;item=item->next)
  139.     if (strcmp(name,item->altname)==0) return item;
  140.  return NULL;
  141. }
  142. //----------------------------------------------------------
  143. // RETURNS: the pointer to the pin with name NAME
  144. PINS *findPIN(char *name) {
  145.  PINS *item=Pbegin;
  146.  for (;item!=NULL;item=item->next)
  147.     if (strcmp(name,item->name)==0) return item;
  148.  return NULL;
  149. }
  150. //----------------------------------------------------------
  151. // the same, but if pin not found it will create pin with this name
  152. PINS *findPINx(char *name) {                          
  153.  PINS *item=Pbegin;
  154.  strupr(name);
  155.  for (;item!=NULL;item=item->next)
  156.     if (strcmp(name,item->name)==0) return item;
  157.  return addPIN(name);
  158. }
  159. //----------------------------------------------------------
  160. // delete the pin with pointer ITEM
  161. void delPINSitem(PINS *item) {
  162.  if (item==NULL) return;
  163.  PINS *tmp=Pbegin;
  164.  if (item==Pbegin) {
  165.     if (item->name!=NULL) {
  166.        delete[] item->name;
  167.        item->name=NULL;
  168.     }
  169.     Pbegin=Pbegin->next;
  170.     delete tmp;
  171.     tmp=NULL;
  172.     return;
  173.  }
  174.  for (;tmp->next!=NULL;tmp=tmp->next)
  175.     if (tmp->next==item) {
  176.        tmp->next=item->next;
  177.        if (item->name!=NULL) {
  178.           delete[] item->name;
  179.           item->name=NULL;
  180.         }
  181.        delete item;
  182.        item=NULL;
  183.        return;
  184.     }
  185. }
  186. //----------------------------------------------------------
  187. // delete all pins in structure PINS
  188. void delPINSall(PINS *item) {
  189.  for (PINS *tmp=item;tmp!=NULL;) {
  190.      PINS *x=tmp->next;
  191.      if (tmp->name!=NULL) {
  192.         delete[] tmp->name;
  193.         tmp->name=NULL;
  194.      }
  195.      delete tmp;tmp=NULL;
  196.      tmp=x;
  197.  }
  198. }
  199. //-----------------------------------------------------------
  200. // add new device to the list of jtag devices BS
  201. void addBSitem() {
  202.  BS *BStmp=new BS;
  203.  BStmp->next=BSbegin;
  204.  BSbegin=BStmp;
  205.  BStmp->name=NULL;
  206.  BStmp->file=NULL;
  207.  BStmp->BYPASS=NULL;
  208.  BStmp->EXTEST=NULL;
  209.  BStmp->SAMPLE=NULL;
  210.  BStmp->IDCODE=NULL;
  211.  BStmp->ID=NULL;
  212.  BStmp->pins=NULL;
  213.  BStmp->DRlen=0;
  214.  BStmp->IRlen=0;
  215.  BStmp->DRlen=0;
  216.  BStmp->IDlen=0;
  217.  BStmp->PINnum=0;
  218.  BStmp->id_bs=CUR_ID;
  219.  CUR_ID++;
  220. }
  221. //-----------------------------------------------------------
  222. // delete JTAG DEVICE with pointer item from the list
  223. void delBSitem(BS *item) {
  224.  if (item->name!=NULL) {delete[] item->name;item->name=NULL;}
  225.  if (item->file!=NULL) {delete[] item->file;item->file=NULL;}
  226.  if (item->SAMPLE!=NULL) {delete[] item->SAMPLE;item->SAMPLE=NULL;}
  227.  if (item->IDCODE!=NULL) {delete[] item->IDCODE;item->IDCODE=NULL;}
  228.  if (item->ID!=NULL) {delete[] item->ID;item->ID=NULL;}
  229.  delPINSall(item->pins);
  230.  if (item==BSbegin) BSbegin=item->next;
  231.    else
  232.      for (BS *tmp=BSbegin;tmp!=NULL;tmp=tmp->next)
  233.         if (tmp->next==item) {tmp->next=item->next;break;}
  234.  delete item;item=NULL;
  235. }
  236. //-----------------------------------------------------------
  237. // RETURNS: ID of pin with name PINNAME which belongs to JTAG DEVICE with ID=id
  238. DWORD pins2id(DWORD id,char *pinname) {                                    
  239.  for (BS *tmp=BSbegin;tmp!=NULL;tmp=tmp->next)
  240.      if (tmp->id_bs==id) {
  241.         PINS *item=tmp->pins;
  242.         for (;item!=NULL;item=item->next)
  243.           if (strcmp(pinname,item->name)==0) return item->id_pins;
  244.      }
  245.  return -1;
  246. }
  247. //-----------------------------------------------------------
  248. // delete whole list of JTAG DEVICES
  249. void delBSall() {
  250.  for (;BSbegin!=NULL;) {
  251.      if (BSbegin->name!=NULL) {delete[] BSbegin->name;BSbegin->name=NULL;}
  252.      if (BSbegin->file!=NULL) {delete[] BSbegin->file;BSbegin->file=NULL;}
  253.      if (BSbegin->SAMPLE!=NULL) {delete[] BSbegin->SAMPLE;BSbegin->SAMPLE=NULL;}
  254.      if (BSbegin->IDCODE!=NULL) {delete[] BSbegin->IDCODE;BSbegin->IDCODE=NULL;}
  255.      if (BSbegin->ID!=NULL) {delete[] BSbegin->ID;BSbegin->ID=NULL;}
  256.      delPINSall(BSbegin->pins);
  257.      BS *tmp=BSbegin->next;
  258.      delete BSbegin;BSbegin=NULL;
  259.      BSbegin=tmp;
  260.  }
  261. }
  262. //----------------------------------------------------------------
  263. // start analysis of BSDL-file for DEVICE PINS
  264. // STR is a pointer to the stream with BSDL-file
  265. void PINanalysis(char *str) {                          
  266.  char *s;
  267.  char *buf1=new char[strlen(str)+1];
  268.  s=buf1;
  269.  int j=0;
  270.  for (DWORD i=0;i<strlen(str);i++) {
  271.      if (*(str+i)=='&'||*(str+i)=='\"'||*(str+i)==' '||*(str+i)==9) continue;
  272.      *(s+j)=*(str+i);j++;
  273.  }
  274.  *(s+j)=0;
  275.  char* prev_name=NULL;
  276.  for (;;) {
  277.      char* _str=NULL;
  278.      int bracket=0;
  279.      for (unsigned int i=0;i<strlen(s);i++) {
  280.          if (s[i]=='(') bracket++;
  281.          if (s[i]==')')
  282.              if (bracket==1) break;
  283.                 else bracket--;
  284.      }
  285.      if (i!=strlen(s)) _str=s+i;
  286.      if (_str==NULL) {delete[] buf1;buf1=NULL;return;}
  287.      *_str=0;
  288.      j=getfwdint(s,'(');
  289.      if (j==-1) {s=_str+1;if (*s==',') s++;continue;}
  290.      s=strchr(s,',')+1;
  291.      char *_s=strchr(s,',');
  292.      if (_s==NULL) {s=_str+1;if (*s==',') s++;continue;}
  293.      *_s=0;
  294.      char *name=s;
  295.      if (*name=='*') name=prev_name;
  296.         else prev_name=name;
  297.      s=_s+1;
  298.      _s=strchr(s,',');
  299.      if (_s==NULL) {s=_str+1;if (*s==',') s++;continue;}
  300.      *_s=0;
  301.      int type,ctrl,vout;
  302.      if (strstr(s,"input")!=NULL) type=1;
  303.       else if (strstr(s,"output")!=NULL) type=2;
  304.        else type=0;
  305.      if (type==0) {s=_str+1;if (*s==',') s++;continue;}
  306.      s=_s+1;
  307.      if (type==2) {
  308.          _s=strchr(s,',');
  309.          if (_s==NULL) {s=_str+1;if (*s==',') s++;continue;}
  310.          s=_s+1;
  311.          _s=strchr(s,',');
  312.          if (_s==NULL) {s=_str+1;if (*s==',') s++;continue;}
  313.          ctrl=getfwdint(s,',');
  314.          if (ctrl==-1) {s=_str+1;if (*s==',') s++;continue;}
  315.          s=_s+1;
  316.          _s=strchr(s,',');
  317.          if (_s==NULL) {s=_str+1;if (*s==',') s++;continue;}
  318.          vout=getfwdint(s,',');
  319.          if (vout==-1||(vout!=0&&vout!=1)) {s=_str+1;if (*s==',') s++;continue;}
  320.          vout=1-vout;
  321.      }
  322.      PINS *x=findPINx(name);
  323.      if (x==NULL) {s=_str+1;if (*s==',') s++;continue;}
  324.      switch (type) {
  325.         case 1 : x->input=j;break;
  326.         case 2 : x->output=j;x->control=ctrl;x->vOUT=vout;break;
  327.      }
  328.      s=_str+1;
  329.      if (*s==',') s++;
  330.  }
  331. }
  332.  
  333. //-------------------------------------------------------------------
  334. // reads JTAG DEVICE description from the file FL. CURDEV - is a current DEVICE ID
  335. // mode=1(read with pins), mode=0(read without pins) - to optimize on speed
  336. BS* readBSD(char* fl,int mode,DWORD curdev) {
  337.  CUR_ID=curdev;
  338.  CUR_PINS=0;
  339.  if (fl==NULL) return NULL;
  340.  FILE *in=fopen(fl,"rt");
  341.  if (in==NULL) return NULL;
  342.  fseek(in,0,SEEK_END);
  343.  int filelen=ftell(in);
  344.  rewind(in);
  345.  char _lex[256];
  346.  char  lex[256];
  347.  char *buf,*_buf,*bufbegin;
  348.  bufbegin=buf=_buf=new char[filelen];
  349.  for (;!feof(in);) {
  350.      if (fgets(_lex,255,in)==NULL) break;
  351.      strlwr(_lex);
  352.      int ind=0;
  353.      for (DWORD i=0;i<strlen(_lex);i++)
  354.         if (_lex[i]>=32 && _lex[i]<127) {lex[ind]=_lex[i];ind++;};
  355.      lex[ind]=0;
  356.      for (i=0;i<strlen(lex);i++)
  357.         if (lex[i]!=' ') break;
  358.      strcpy(_lex,lex+i);
  359.      ind=0;
  360.      for (i=0;i<strlen(_lex);i++) {
  361.          if (ind && lex[ind-1]==' ' && (_lex[i]==',' || _lex[i]==':' || _lex[i]==' ' ||
  362.              _lex[i]==';' || _lex[i]=='\"' || _lex[i]=='(' || _lex[i]==')' ||
  363.              _lex[i]=='&' || _lex[i]=='[' || _lex[i]==']')) ind--;
  364.          if (ind && _lex[i]==' ' && (lex[ind-1]==',' || lex[ind-1]==':' || lex[ind-1]==';' ||
  365.              lex[ind-1]=='\"' || lex[ind-1]=='(' || lex[ind-1]==')' || lex[ind-1]=='&' ||
  366.              lex[ind-1]=='[' || lex[ind-1]==']' || lex[ind-1]==' ')) continue;
  367.          lex[ind]=_lex[i];ind++;
  368.         }
  369.      lex[ind]=0;
  370.      for (i=1;i<strlen(lex);i++)
  371.          if (lex[i]=='-' && lex[i-1]=='-') {lex[i-1]=0;break;}
  372.      if (!strlen(lex)) continue;
  373.      if (lex[0]=='-' && lex[1]=='-') continue;
  374.      strcpy(_buf,lex);
  375.      _buf+=strlen(lex);
  376.     }
  377.  // At this point all lexems are represented as a one long string with pointer "char *buf"
  378.  for (;;) {
  379.      int i;
  380.      char *Ctmp1,*Ctmp2,*Ctmp3;
  381.      int curpin=0;
  382.      int flag1=0;
  383.      int flag2=0;
  384.      if (*buf==0) break;            // if it's an end of lexems?
  385.      _buf=strstr(buf,";end ");
  386.      if (_buf==NULL) break;       // there is no new entities
  387.      _buf+=5;
  388.      Ctmp1=strstr(_buf,";");
  389.      if (Ctmp1==NULL) break;
  390.      *Ctmp1=0;                     // now Ctmp points to the name of current entity
  391.      sprintf(lex,"entity %s is",_buf);
  392.      buf=strstr(buf,lex);
  393.      if (buf==NULL) {buf=lex+1;continue;}
  394.      buf+=strlen(lex);
  395.      addBSitem();
  396.      BSbegin->name=new char[strlen(_buf)+1];
  397.      strcpy(BSbegin->name,strupr(_buf));
  398.      BSbegin->file=new char[strlen(fl)+1];
  399.      strcpy(BSbegin->file,fl);
  400.      // looking for IR length
  401.      _buf=strstr(buf," instruction_length ");
  402.      if (_buf==NULL) goto m1;
  403.      _buf=strstr(_buf,";");
  404.      if (_buf==NULL) goto m1;
  405.      i=getbackint(_buf,' ');
  406.      if (i==0) goto m1;
  407.      BSbegin->IRlen=i;
  408.      // looking for DR length
  409.      _buf=strstr(buf," boundary_length ");
  410.      if (_buf==NULL) goto m1;
  411.      _buf=strstr(_buf,";");
  412.      if (_buf==NULL) goto m1;
  413.      i=getbackint(_buf,' ');
  414.      if (i==0) goto m1;
  415.      BSbegin->DRlen=i;
  416.      // looking for commands SAMPLE and IDCODE
  417.      _buf=strstr(buf," instruction_opcode ");
  418.      if (_buf==NULL) goto m1;
  419.      Ctmp2=strstr(_buf,";");
  420.      if (Ctmp2==NULL) goto m1;
  421.      *Ctmp2=0;
  422.  
  423.      // BYPASS
  424.      Ctmp3=strstr(_buf,"\"bypass(");
  425.      if (Ctmp3==NULL) {*Ctmp2=';';goto m1;}
  426.      i=strstr(Ctmp3,")")-Ctmp3-7;
  427.      BSbegin->BYPASS=new char[i];
  428.      if (getCMDcode(Ctmp3+8,BSbegin->BYPASS)) {*Ctmp2=';';goto m1;}
  429.      
  430.      // EXTEST
  431.      Ctmp3=strstr(_buf,"\"extest(");
  432.      if (Ctmp3==NULL) {*Ctmp2=';';goto m1;}
  433.      i=strstr(Ctmp3,")")-Ctmp3-7;
  434.      BSbegin->EXTEST=new char[i];
  435.      if (getCMDcode(Ctmp3+8,BSbegin->EXTEST)) {*Ctmp2=';';goto m1;}
  436.      
  437.      // SAMPLE
  438.      Ctmp3=strstr(_buf,"\"sample(");
  439.      if (Ctmp3==NULL) {*Ctmp2=';';goto m1;}
  440.      i=strstr(Ctmp3,")")-Ctmp3-7;
  441.      BSbegin->SAMPLE=new char[i];
  442.      if (getCMDcode(Ctmp3+8,BSbegin->SAMPLE)) {*Ctmp2=';';goto m1;}
  443.      
  444.      // IDCODE
  445.          Ctmp3=strstr(_buf,"\"idcode(");
  446.      if (Ctmp3==NULL) {*Ctmp2=';';goto m2;}
  447.      i=strstr(Ctmp3,")")-Ctmp3-7;
  448.      BSbegin->IDCODE=new char[i];
  449.      getCMDcode(Ctmp3+8,BSbegin->IDCODE);
  450.      *Ctmp2=';';
  451.      
  452.          // looking for device ID
  453.      _buf=strstr(buf," idcode_register ");
  454.      if (_buf==NULL) goto m2;
  455.      Ctmp2=strstr(_buf,";");
  456.      if (Ctmp2==NULL) goto m2;
  457.      *Ctmp2=0;
  458.      Ctmp3=strstr(_buf,"\"");
  459.      if (Ctmp3==NULL) {*Ctmp2=';';goto m2;}
  460.      if (getIDcode(Ctmp3+1,lex)) {*Ctmp2=';';goto m2;}
  461.      if (strlen(lex)==0) {*Ctmp2=';';goto m2;}
  462.      BSbegin->ID=new char[strlen(lex)+1];
  463.      strcpy(BSbegin->ID,lex);
  464.      BSbegin->IDlen=strlen(lex);
  465.      *Ctmp2=';';
  466. m2:  
  467.      // looking for device pins
  468.      if (mode==1) {
  469.          _buf=strstr(buf," boundary_register ");
  470.          if (_buf==NULL) goto m1;
  471.          Ctmp2=strstr(_buf,";");
  472.          if (Ctmp2==NULL) goto m1;
  473.          *Ctmp2=0;
  474.          Ctmp3=strstr(_buf,"\"");
  475.          if (Ctmp3==NULL) {*Ctmp2=';';goto m1;}
  476.          Pbegin=NULL;
  477.          PINanalysis(Ctmp3);
  478.          if (Pbegin==NULL) {*Ctmp2=';';goto m1;}
  479.          PINS *x;
  480.          x=Pbegin;
  481.          for (;Pbegin!=NULL;) {
  482.              if (Pbegin->input==-1&&Pbegin->output==-1)
  483.                 {Pbegin=Pbegin->next;delPINSitem(x);x=Pbegin;continue;}
  484.              break;
  485.          }
  486.          if (Pbegin==NULL) goto m1;
  487.          curpin=0;
  488.          for (;x->next!=NULL;x=x->next) {
  489.              if (x->next->input==-1&&x->next->output==-1) {
  490.                  delPINSitem(x->next);
  491.                  if (x->next==NULL) break;
  492.                  continue;
  493.              }
  494.              curpin++;
  495.          }  
  496.          BSbegin->pins=Pbegin;
  497.          BSbegin->PINnum=curpin+1;
  498.          buf=Ctmp1+1;continue;
  499.         }
  500.       else {BSbegin->pins=NULL;BSbegin->PINnum=0;buf=Ctmp1+1;continue;}
  501. m1:  
  502.      buf=Ctmp1+1;
  503.      delBSitem(BSbegin);
  504.      continue;
  505.  }
  506.  delete[] bufbegin;bufbegin=NULL;
  507.  fclose(in);
  508.  return BSbegin;
  509. }