/* 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 2002.10.06 */


/* ------ 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 */


/* ------ includes section */

/* malloc(), calloc(), realloc(), free(), exit(), abort() */
#include <stdlib.h>

/* fopen(), fclose(), fread(), fprintf(), printf(), stdin, stdour, stderr */
#include <stdio.h>

/* strerror() */
#include <string.h>

/* errno */
#include <errno.h>


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

/* my typical typing savers, oops some are already in Linux types.h */
typedef unsigned char uchar;
/*typedef unsigned short ushort;*/
/*typedef unsigned int uint;*/
/*typedef unsigned long ulong;*/


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

/* reading in functions */
char *readbitfile(char *BitfileName, int Verbose);
char *readfileheader(void);
char *readstreamheader(void);
char *setmodelfromconfigsize(void);
char *allocframes(void);
char *readmainframes(void);

/* range/stepping functions */
char *setclbrange(char *Range);

/* accessing functions */
uint getclb(void);
uint getlut(void);
uint getff(void);


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

/* assumptions on series differences: */
/* 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 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 and Virtex-IIpro: totally different architecture, no JBits for it
   and I have no BGA processing ability anyway, no support intended at all */

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 VirtexPadIobWECols    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 VirtexPadIobWEFrames  VirtexIobWEFrames
#define VirtexBramCFrames     27
#define VirtexBramDFrames     64
#define VirtexBramFrames      (VirtexBramCFrames+VirtexBramDFrames)
#define VirtexDllFrames       VirtexBramFrames

/* vertical arrangement */

#define VirtexMiddleBits      18
#define VirtexTopBotBits      18

extern int Bit, Frame;


/* ------ 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; };


/* ------ set Virtex model from config size section */

/* the actual device we are using for selecting parameters */
extern struct VirtexModel *Model;


/* ------ set range of CLBs from range string section */

/* constants for selecting slices and LUTs/FFs */

/* slice 1 is left(!) in the CLB, see XAPP page 11, table 7, formula MNA */
/*   we want to count 0->1, to use <= and ++ in for(), else bug source */
#define SLI1 0
#define SLI0 1
#define SLIL SLI1
#define SLIR SLI0

/* we want to count 0->1 for F->G and X->Y */
#define LUTF 0
#define LUTG 1
#define FFX LUTF
#define FFY LUTG

/* [First/Last][Sli/Lut] for looping, Begin/end for in first/last Col/Row */
extern int FirstCol, LastCol, Col;
extern int FirstSli, LastSli, Sli, BeginSli, EndSli;
extern int FirstRow, LastRow, Row;
extern int FirstLut, LastLut, Lut, BeginLut, EndLut;


/* ------ 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 */

extern uint LutFont[];

