注意这不是转载。
已经在Spartan 6, ZYNQ 7000, ZYNQ Ultrascale三个系列的器件上验证过。每个系列测试了1种器件。
提供文件解析代码。
The Xilinx .bit format is pretty simple. It uses keys and lengths to
divide the file.
Here is an example. Below is a hex dump from the beginning of a .bit file:
00000000: 00 09 0f f0 0f f0 0f f0 0f f0 00 00 01 61 00 0a .............a..
00000010: 78 66 6f 72 6d 2e 6e 63 64 00 62 00 0c 76 31 30 xform.ncd.b..v10
00000020: 30 30 65 66 67 38 36 30 00 63 00 0b 32 30 30 31 00efg860.c..2001
00000030: 2f 30 38 2f 31 30 00 64 00 09 30 36 3a 35 35 3a /08/10.d..06:55:
00000040: 30 34 00 65 00 0c 28 18 ff ff ff ff aa 99 55 66 04.e..(.......Uf
Field 1
2 bytes length 0x0009 (big endian)
9 bytes some sort of header 0f f0 0f f0 0f f0 0f f0 00
Field 2
2 bytes length 0x0001 (key-length-value below)
Field 3
1 byte key 0x61 (The letter "a")
2 bytes length 0x000a (value depends on file name length)
10 bytes string design name "xform.ncd" end with \0
Field 4
1 byte key 0x62 (The letter "b")
2 bytes length 0x000c (value depends on part name length)
12 bytes string part name "v1000efg860" end with \0
Field 4
1 byte key 0x63 (The letter "c")
2 bytes length 0x000b
11 bytes string date "2001/08/10" end with \0
Field 5
1 byte key 0x64 (The letter "d")
2 bytes length 0x0009
9 bytes string time "06:55:04" end with \0
Field 6
1 byte key 0x65 (The letter "e")
4 bytes length 0x000c2818 (configuration length)
796696 bytes raw bitstream starting with ffff ffff aa99 5566 sync word
//Xilinx .bit file header parser
class HeaderParser {
private:
uint8_t state;
//0=header len, 1=header data,
//2=key, 3=length, 4=value,
//5=bitstream len, 6=bitstream
uint32_t len;
uint8_t n;
uint8_t key;
protected:
virtual void parseKey(uint8_t k, char c) {
qDebug() << "key" << (int)k << ":" << c;
}
public:
bool done() {
return (state == 6);
}
void reset() {
state = 0;
n = 2;
}
size_t bitstream_len() {
if(state == 6) return len;
else return 0;
}
HeaderParser() {
reset();
}
void operator()(char x) {
switch(state) {
case 0: { //record header len
len = (len << 8) | x;
n--;
if(n == 0) {
n = len & 0x0000ffff;
if(n == 0x0001) state = 2; //go key-length-value mode
else state = 1; //go bitstream len
}
} break;
case 1: //consume header data
n--;
if(n == 0) {
n = 2;
state = 0;
}
break;
case 2: //parse key
key = x;
if(key == 0x65) {
n = 4;
state = 5;
} else {
n = 2;
state = 3;
}
break;
case 3: { //record value len
len = (len << 8) | x;
n--;
if(n == 0) {
n = len & 0x0000ffff;
state = 4;
}
} break;
case 4: { //consume value
parseKey(key, x);
n--;
if(n == 0) state = 2;
} break;
case 5: { //record bitstream len
len = (len << 8) | x;
n--;
if(n == 0) state = 6; //bitstream len acquired
}
case 6:
default:;
}
}
};
[修改于 1年10个月前 - 2023/03/05 17:30:28]
200字以内,仅用于支线交流,主线讨论请采用回复功能。