/* http://neil.franklin.ch/Projects/VirtexTools/virtex.h */
/*   - header file for libvirtex (virtex.c) library */
/*       functions to handle Virtex (and Spartan-II) FPGA bitstreams */
/* author Neil Franklin, last modification 2003.09.20 */


/* ------ prerequisites section */

/* to really understand this code you should */
/*   have an understanding of the basics of */
/*     designing logic circuits, such as with [74|74LS|74F]xx(x) chips */
/*     basics of how programmable logic works, particularly FPGAs */
/*   have read the specifics from the */
/*     Xilinx Virtex 2.5V FPGAs (XCV00) data sheet */
/*       http://www.xilinx.com/partinfo/ds003.pdf */
/*     Xilinx Virtex-E 1.8V FPGAs (XCV00E) data sheet */
/*       http://www.xilinx.com/partinfo/ds022.pdf */
/*     Xilinx Virtex-E 1.8V Extended Memory FPGAs (XCV00E) data sheet */
/*       http://www.xilinx.com/partinfo/ds025.pdf */
/*     Xilinx Spartan[tm]-II data sheet (XC2S00) */
/*       http://www.xilinx.com/partinfo/ds001.htm */
/*     Xilinx Spartan[tm]-IIE data sheet (XC2S00E) */
/*       http://www.xilinx.com/partinfo/ds077.htm */
/*     Xilinx Application Note XAPP138, Virtex Configuration and Readback */
/*       http://www.xilinx.com/xapp/xapp138.pdf */
/*     Xilinx XAPP151, Virtex Series Configuration Architecture User Guide */
/*       http://www.xilinx.com/xapp/xapp151.pdf */


/* ------ typedef section */

/* my typical typing saver, completes the old ushort, uint, ulong types */
typedef unsigned char uchar;


/* ------ define the various Virtex series section */

/* assumptions on series differences, and what will be supported: */

/* Virtex: JBits makes code for these, so my reverse engineering is for these
   will be supported from beginning on */
/* Virtex-E: XAPP151 documented bit positions (LUTs, FFs, IO-FFs, BRAMs)
   are identical, bitmap sizes also, different BRAM arrangement is in XAPP151
   will be supported when someone wants the extra code
   "entire mode" data sheet description of CLBs and BRAMs looks same
   DLLs and IOBs can do more, need more PIPs?, added or changed PIPs?
   will be supported after I can get an bitstream to cross compare */
/* Virtex-ME: most of the data sheet is verbatim Virtex-E
   seems to be just more memory, no other change
   XAPP151 documents differences in BRAM arrangement, more like normal Virtex
   will be supported as soon as Virtex-E is supported */
/* Sparten-II: are equivalent-size compatible with Virtex, according to Xilinx
   will be supported from beginning on, as just more sizes */
/* Sparten-IIE: seems to be Virtex-E but some models with only 2 BRAM columns
   will be supported tentatively when Virtex-E is in
   will be definitive only after I get an bitstream to cross compare */

/* Virtex-II, Virtex-IIpro, Spartan-III: totally different architecture
   no JBits or XAPP documentation for it, total separate reverse engineering */
/* XC4000, XC4000XL, Spartan, Spartax-XL: also totally different
   also no documentation, and in addition outdated, will never be suppoerted */

enum VirtexSeries {
  none       = 0,
  virtex     = 1,
  virtex_e   = 2,
  virtex_em  = 3,
  spartan_2  = 4,
  spartan_2e = 5 };


/* ------ define various Virtex chip architecture constants section */

/* these constants are from the data sheets */

/* horizontal arrangement */

#define VirtexSlicesPerClb    2
#define VirtexIosPerIobNS     2

#define VirtexCenterCols      1
#define VirtexGclkCols        VirtexCenterCols
/*      VirtexClbCols         is model dependant from VirtexModels */
/*      VirtexIobNSCols       is model dependant = VirtexClbCols */
#define VirtexIobWECols       2
#define VirtexCornerCols      VirtexIobWECols
/*      VirtexBramCols        is model dependant from VirtexModels */
/*      VirtexDllCols         is model dependant = VirtexBramCols */

/* vertical arrangement */

#define VirtexLutsPerSlice    2
#define VirtexIosPerIobWE     3
#define VirtexClbsPerBram     4

/*      VirtexMiddleRows      is model dependant from VirtexModels */
#define VirtexTopBotRows      2


/* these constants are from XAPP151, page7 */

/* horizontal arrangement */

#define VirtexCenterFrames    8
#define VirtexGclkFrames      VirtexCenterFrames
#define VirtexClbFrames       48
#define VirtexIobNSFrames     VirtexClbFrames
#define VirtexIobWEFrames     54
#define VirtexCornerFrames    VirtexIobWEFrames
#define VirtexBramCFrames     27
#define VirtexDllFrames       VirtexBramCFrames
#define VirtexBramDFrames     64
#define VirtexBramDPadFrames  VirtexBramDFrames

/* vertical arrangement */

#define VirtexMiddleBits      18
#define VirtexTopBotBits      18


/* ------ define various Virtex chip model dependant constants section */

/* chip model dependant constants, so they are not scattered over code */
struct VirtexModel {

  /* given data, set here */
  char* Name;
  enum VirtexSeries Series;

  int ClbCols;
  int ClbRows;
  int BramCols;

  int BramSpacing;

  /* computed data, calculated later */
  int IobNSCols;
  int DllCols;
  /* MiddleRows not given, because ClbRows given for easier understanding */
  int MiddleRows;

  int FrameBits;
  int FrameWords;
  int MainFrames; };


/* ------ current LUT position setting, looping and output functions section */

typedef struct lutpos {
  int Col;
  char Sli;
  int Row;
  char Lut; } lutpos;


/* ------ bit for function selection section */

typedef ushort lutval;


/* ------ prototypes section */

/* reading in functions */
char *readbitfile(FILE *BitfilePtr, int Verbose);
char *readfileheader(void);
char *readstreamheader(void);
char *setmodelfromconfigsize(void);
char *allocframes(void);
char *readmainframes(void);
char *readframe(ulong *Top, ulong *Middle, int StepMiddle, ulong *Bottom);
char *readpipeframe(void);
char *readbramdframes(void);
char *readstreamtail(void);

/* range parsing functions */
char *setlutrange(char *Range);

/* position setting, looping, testing and outputting functions */
/*   horizontally, slice wise */
void firstsli(void);
void lastsli(void);
void nextsli(void);
void prevsli(void);
int isinslis(void);
/*   vertically, lut wise */
void firstlut(void);
void lastlut(void);
void nextlut(void);
void prevlut(void);
int isinluts(void);
/*   and output where we are */
lutpos *getlutpos(void);

/* bitstream frame data access functions */
int getcenterbit(int Frame, int Bit);
int getgclkbit(int Frame, int Bit);
int getclbbit(int Frame, int Bit);
int getiobnsbit(int Frame, int Bit);
int getiobwebit(int Frame, int Bit);
int getcornerbit(int Frame, int Bit);
int getbramcbit(int Frame, int Bit);
int getdllbit(int Frame, int Bit);
int getbramdbit(int Frame, int Bit);
int getbramdpadbit(int Frame, int Bit);

/* bits for function selection functions */
ushort getlut(void);
int getff(void);


/* ------ auxillary code for LUT comment writting section */

/* allow putting text bit patterns into LUTs */
/*   for layout display in BoardScope or VirtexView */
/*   uses LUT 16 bits displayed 0123/4567/89AB/CDEF as 4x4 pixel font */

/* for all programs using the global variable/array in virtex.c */
/*   virtex.c itsself does not mind #including the double definition */
extern lutval LutFont[];
