From: Newsgroups: comp.arch.fpga Subject: Linux download bitstream [w/ source] Date: 3 Sep 2001 03:54:49 GMT Organization: ERG CUHK Lines: 196 Message-ID: <9muuu9$s1d$1@eng-ser1.erg.cuhk.edu.hk> NNTP-Posting-Host: fraser.cse.cuhk.edu.hk X-Trace: eng-ser1.erg.cuhk.edu.hk 999489289 28717 137.189.90.232 (3 Sep 2001 03:54:49 GMT) X-Complaints-To: abuse@erg.cuhk.edu.hk NNTP-Posting-Date: 3 Sep 2001 03:54:49 GMT User-Agent: tin/1.4.5-20010409 ("One More Nightmare") (UNIX) (Linux/2.4.7 (i686)) Path: chonsp.franklin.ch!pfaff.ethz.ch!news-zh.switch.ch!news-ge.switch.ch!newsfeed.mathworks.com!portc01.blue.aol.com!news.stealth.net!newsgate.cuhk.edu.hk!news.cuhk.edu.hk!news.erg.cuhk.edu.hk!not-for-mail Xref: chonsp.franklin.ch comp.arch.fpga:9710 Hi, Thanks to the good ppl. in this news group, I can finally download the bit stream to FPGA under Linux. I am here to share the experience (maybe somebody have done it before but I could not find). Environment: 1. Software Linux with kernel 2.2.17 (others whould work also) GNU gcc-2.95.2 2. Hardware Xilinx FPGA (I tried XCV600HQ240 and V1000EHQ240) Xilinx Parallel Cable III (DB25M head) six flying lead Procedure: 1. connect the flying lead to Parallel Cable only the FPGA side is connected (i.e. VCC, GND, D/P, DIN, CCLK, /PROG) 2. connect the cable to a Linux computer and connect the leads to FPGA pins VCC <--> VCC GND <--> GND D/P <--> DONE DIN <--> DIN CCLK <--> CCLK /PROG <--> /PROG note that the /INT pin in FPGA is not connected 3. download and compile the source file (at the end of the document) use the following command (-O2 is a must) gcc -Wall -O2 -o w w.c 4. get ready the bitstream (*.bit) in the same directory of the program here assume the file name is "design.bit" 5. just involve the program after power up the FPGA make sure you are root when runing the command if the "DONE!" is printed, your design is downloaded correctly Important: 1. I have only test it on Vertix/VertixE FPGA chips. This should also work on VertixII. Other families may not work (should not work since the programming requirements are differents) 2. The Parallel Cable III is not a must. you can make you only cable, check it out in the reference 3. Since the lack of /INT input to Linux host, the download process will not be interrupted by error(s). The initial stage is also not safe. But if Xilinx makes the cable and thinks it will work, who others will care that? 4. The DONE signal will tell the condition of program at the end. Since it's release only when CRC checking is passed, it can be trusted. 5. The download speed is quite fast (4-5 sec for XCV600HQ240 design) on a PIII700 PC. 6. User must be root to download the bitstream since the program use inb() and outb() to access the port directly. But you still have the choice to setuid and avoid logging in as root every time. 7. EPP mode is selected for this program. But it really don't matter. You can still run it in other modes. 8. This porgam is for development use only. Use it on your own risk. Reference: 1. http://www.xilinx.com/support/programr/files/0380507.pdf 2. XAP137, XAP138, XAP138, XAP501 3. news from Alan Nishioka <--begin--> However, the format is pretty simple. It uses keys and lengths to divide the file. 2 bytes length 0x0009 (big endian) 9 bytes some sort of header (the length given above) 2 bytes length 0x0001 1 byte key 0x61 2 bytes length 0x000a 10 bytes string giving design name 1 byte key 0x62 2 bytes length 0x000c 12 bytes string giving part name 1 byte key 0x63 2 bytes length 0x000b 11 bytes string giving date 1 byte key 0x64 2 bytes length 0x0009 9 bytes string giving time 1 byte key 0x65 2 bytes length 0x000c9090 8233440 bytes raw bit stream starting with 0xffffffff aa995566 sync word documented below. <--end--> 4. Linux Device Driver p236 Fig.8 Reg bit # Direction DB25 pin # Data Reg 0 - 7 ----> 2 - 9 Status Reg 3 <---- 15 Status Reg 4 <---- 13 5. http://www.beyondlogic.org/epp/epp.htm Source Code: <--begin--> #include #include #include /* needed for ioperm() */ #include //#include /* for outb() and inb() */ #define DATA 0x378 #define STATUS DATA+1 #define CONTROL DATA+2 int main(void) { FILE *bitfile; union { unsigned int i; unsigned short s[2]; char c[4]; } head_len; unsigned char head_key; char buf[2035464]; unsigned int i; int j; unsigned char tmp; bitfile = fopen("design.bit", "r"); fread(&(head_len.c[1]), 1, 1, bitfile); fread(&(head_len.c[0]), 1, 1, bitfile); fread(buf, head_len.s[0], 1, bitfile); fread(&(head_len.c[1]), 1, 1, bitfile); fread(&(head_len.c[0]), 1, 1, bitfile); head_key = 0; while (head_key != 0x65) { fread(&head_key, 1, 1, bitfile); fread(&(head_len.c[3]), 1, 1, bitfile); fread(&(head_len.c[2]), 1, 1, bitfile); if (head_key == 0x65) { fread(&(head_len.c[1]), 1, 1, bitfile); fread(&(head_len.c[0]), 1, 1, bitfile); fread(buf, head_len.i, 1, bitfile); } else { fread(buf, head_len.s[1], 1, bitfile); printf("%s\n", buf); } } fclose(bitfile); if (iopl(3)) { printf("cannot access port!\n"); exit(1); } outb(0x04, CONTROL); // sense VCC tmp = inb(STATUS); tmp = (tmp>>3) & 1; if (!tmp) { printf("cabel not found\n"); exit(0); } else printf("cabel detected\n"); // clear config outb(0x10, DATA); printf("configuration memory cleared\n"); outb(0x14, DATA); printf("start loading %d bytes\n", head_len.i); for (i=0; i=0; j--) { tmp = (buf[i]>>j) & 1; outb(tmp|0x14, DATA); outb(tmp|0x16, DATA); } } printf("finish loading\n"); // Done tmp = inb(STATUS); tmp = (tmp>4)&1; if (tmp) printf("DONE!\n"); else printf("FAILED!\n"); return (0); } <--end--> Good Luck! ---- Brittle