bit2fp cleanup
This commit is contained in:
parent
c9ee1165da
commit
d8a18a6034
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -28,4 +28,5 @@ fp2bit
|
|||
fp2bit.o
|
||||
bit2fp
|
||||
bit2fp.o
|
||||
parts.o
|
||||
autotest.tmp/
|
||||
|
|
10
Makefile
10
Makefile
|
@ -28,11 +28,13 @@ new_fp: new_fp.o $(MODEL_OBJ) floorplan.o helper.o control.o
|
|||
|
||||
new_fp.o: new_fp.c floorplan.h model.h helper.h control.h
|
||||
|
||||
fp2bit: fp2bit.o $(MODEL_OBJ) floorplan.o control.o bit_regs.o bit_frames.o helper.o
|
||||
fp2bit: fp2bit.o $(MODEL_OBJ) floorplan.o control.o bit_regs.o bit_frames.o \
|
||||
helper.o parts.o
|
||||
|
||||
fp2bit.o: fp2bit.c model.h floorplan.h bit.h helper.h
|
||||
|
||||
bit2fp: bit2fp.o $(MODEL_OBJ) floorplan.o control.o bit_regs.o bit_frames.o helper.o
|
||||
bit2fp: bit2fp.o $(MODEL_OBJ) floorplan.o control.o bit_regs.o \
|
||||
bit_frames.o helper.o parts.o
|
||||
|
||||
bit2fp.o: bit2fp.c model.h floorplan.h bit.h helper.h
|
||||
|
||||
|
@ -42,6 +44,8 @@ bit_regs.o: bit_regs.c bit.h model.h
|
|||
|
||||
bit_frames.o: bit_frames.c bit.h model.h
|
||||
|
||||
parts.o: parts.c parts.h
|
||||
|
||||
control.o: control.c control.h model.h
|
||||
|
||||
draw_svg_tiles: draw_svg_tiles.o $(MODEL_OBJ) helper.o control.o
|
||||
|
@ -129,7 +133,7 @@ clean:
|
|||
autotest autotest.o control.o floorplan.o \
|
||||
fp2bit fp2bit.o \
|
||||
bit2fp bit2fp.o \
|
||||
bit_regs.o bit_frames.o \
|
||||
bit_regs.o bit_frames.o parts.o \
|
||||
pair2net pair2net.o \
|
||||
xc6slx9_empty.fp xc6slx9.svg \
|
||||
xc6slx9_empty.tiles xc6slx9_empty.devs xc6slx9_empty.conns \
|
||||
|
|
4
README
4
README
|
@ -11,7 +11,7 @@ Libraries
|
|||
|
||||
(most is to-be-done)
|
||||
- libfpga-model memory-only representation of an FPGA
|
||||
- libfpga-bits reads and writes .bit bitstream files
|
||||
- libfpga-bit reads and writes .bit bitstream files
|
||||
- libfpga-floorplan reads and writes .fp floorplan files
|
||||
- libfpga-control programmatic access to libfpga-model
|
||||
- libfpga-design larger design elements on top of libfpga-control
|
||||
|
@ -27,7 +27,7 @@ Design Utilities
|
|||
fpgatools Development Utilities
|
||||
|
||||
- autotest executes test suite
|
||||
- hstrrep high-speed hashed array based search and replace util
|
||||
- sort_seq sorts line-based text file by sequence numbers in strings
|
||||
- merge_seq merges a pre-sorted text file into wire sequences
|
||||
- pair2net reads the first two words per line and builds nets
|
||||
- hstrrep high-speed hashed array based search and replace util
|
||||
|
|
31
bit.h
31
bit.h
|
@ -5,24 +5,6 @@
|
|||
// For details see the UNLICENSE file at the root of the source tree.
|
||||
//
|
||||
|
||||
// The highest 4 bits are the binary revision and not
|
||||
// used when performing IDCODE verification.
|
||||
// ug380, Configuration Sequence, page 78
|
||||
#define IDCODE_MASK 0x0FFFFFFF
|
||||
|
||||
#define XC6SLX4 0x04000093
|
||||
#define XC6SLX9 0x04001093
|
||||
#define XC6SLX16 0x04002093
|
||||
#define XC6SLX25 0x04004093
|
||||
#define XC6SLX25T 0x04024093
|
||||
#define XC6SLX45 0x04008093
|
||||
#define XC6SLX45T 0x04028093
|
||||
#define XC6SLX75 0x0400E093
|
||||
#define XC6SLX75T 0x0402E093
|
||||
#define XC6SLX100 0x04011093
|
||||
#define XC6SLX100T 0x04031093
|
||||
#define XC6SLX150 0x0401D093
|
||||
|
||||
// xc6 configuration registers, documentation in ug380, page90
|
||||
enum fpga_config_reg {
|
||||
CRC = 0, FAR_MAJ, FAR_MIN, FDRI, FDRO, CMD, CTL, MASK, STAT, LOUT, COR1,
|
||||
|
@ -92,6 +74,12 @@ enum {
|
|||
#define MAX_HEADER_STR_LEN 128
|
||||
#define MAX_REG_ACTIONS 256
|
||||
|
||||
struct fpga_bits
|
||||
{
|
||||
uint8_t* d;
|
||||
int len;
|
||||
};
|
||||
|
||||
struct fpga_config
|
||||
{
|
||||
char header_str[4][MAX_HEADER_STR_LEN];
|
||||
|
@ -103,8 +91,7 @@ struct fpga_config
|
|||
int idcode_reg;
|
||||
int FLR_reg;
|
||||
|
||||
int bits_len;
|
||||
uint8_t* bits;
|
||||
struct fpga_bits bits;
|
||||
};
|
||||
|
||||
int read_bitfile(struct fpga_config* cfg, FILE* f);
|
||||
|
@ -118,5 +105,5 @@ void free_config(struct fpga_config* cfg);
|
|||
|
||||
int write_bitfile(FILE* f, struct fpga_model* model);
|
||||
|
||||
int extract_model(struct fpga_model* model, uint8_t* bits, int bits_len);
|
||||
int write_model(uint8_t* bits, int bits_len, struct fpga_model* model);
|
||||
int extract_model(struct fpga_model* model, struct fpga_bits* bits);
|
||||
int write_model(struct fpga_bits* bits, struct fpga_model* model);
|
||||
|
|
35
bit2fp.c
35
bit2fp.c
|
@ -12,7 +12,7 @@
|
|||
int main(int argc, char** argv)
|
||||
{
|
||||
struct fpga_model model;
|
||||
int bits_only, file_arg, rc = -1;
|
||||
int bit_header, bit_regs, fp_header, file_arg, flags, rc = -1;
|
||||
struct fpga_config config;
|
||||
|
||||
// parameters
|
||||
|
@ -20,16 +20,24 @@ int main(int argc, char** argv)
|
|||
fprintf(stderr,
|
||||
"\n"
|
||||
"%s - bitstream to floorplan\n"
|
||||
"Usage: %s [--bits-only] <bitstream_file>\n"
|
||||
"Usage: %s [--bit-header] [--bit-regs] [--no-fp-header] <bitstream_file>\n"
|
||||
"\n", argv[0], argv[0]);
|
||||
goto fail;
|
||||
}
|
||||
bits_only = 0;
|
||||
bit_header = 0;
|
||||
bit_regs = 0;
|
||||
fp_header = 1;
|
||||
file_arg = 1;
|
||||
if (!strcmp(argv[1], "--bits-only")) {
|
||||
bits_only = 1;
|
||||
file_arg = 2;
|
||||
}
|
||||
while (!strncmp(argv[file_arg], "--", 2)) {
|
||||
if (!strcmp(argv[file_arg], "--bit-header"))
|
||||
bit_header = 1;
|
||||
else if (!strcmp(argv[file_arg], "--bit-regs"))
|
||||
bit_regs = 1;
|
||||
else if (!strcmp(argv[file_arg], "--no-fp-header"))
|
||||
fp_header = 0;
|
||||
else break;
|
||||
file_arg++;
|
||||
}
|
||||
|
||||
// read bitstream file
|
||||
{
|
||||
|
@ -46,15 +54,18 @@ int main(int argc, char** argv)
|
|||
// build model and fill from bitstream
|
||||
if ((rc = fpga_build_model(&model, XC6SLX9_ROWS, XC6SLX9_COLUMNS,
|
||||
XC6SLX9_LEFT_WIRING, XC6SLX9_RIGHT_WIRING))) FAIL(rc);
|
||||
if ((rc = extract_model(&model, config.bits, config.bits_len))) FAIL(rc);
|
||||
if ((rc = extract_model(&model, &config.bits))) FAIL(rc);
|
||||
|
||||
// dump model
|
||||
if ((rc = write_floorplan(stdout, &model,
|
||||
bits_only ? FP_BITS_ONLY : FP_BITS_DEFAULT))) FAIL(rc);
|
||||
flags = FP_DEFAULT;
|
||||
if (!fp_header) flags |= FP_NO_HEADER;
|
||||
if ((rc = write_floorplan(stdout, &model, flags))) FAIL(rc);
|
||||
|
||||
// dump what doesn't fit into the model
|
||||
if ((rc = dump_config(&config, bits_only ? DUMP_BITS
|
||||
: DUMP_BITS|DUMP_HEADER_STR|DUMP_REGS))) FAIL(rc);
|
||||
flags = DUMP_BITS;
|
||||
if (bit_header) flags |= DUMP_HEADER_STR;
|
||||
if (bit_regs) flags |= DUMP_REGS;
|
||||
if ((rc = dump_config(&config, flags))) FAIL(rc);
|
||||
return EXIT_SUCCESS;
|
||||
fail:
|
||||
return rc;
|
||||
|
|
80
bit_frames.c
80
bit_frames.c
|
@ -7,13 +7,87 @@
|
|||
|
||||
#include "model.h"
|
||||
#include "bit.h"
|
||||
#include "parts.h"
|
||||
|
||||
int extract_model(struct fpga_model* model, uint8_t* bits, int bits_len)
|
||||
static uint8_t* get_first_minor(struct fpga_bits* bits, int row, int major)
|
||||
{
|
||||
return 0;
|
||||
int i, num_frames;
|
||||
|
||||
num_frames = 0;
|
||||
for (i = 0; i < major; i++)
|
||||
num_frames += get_major_minors(XC6SLX9, i);
|
||||
return &bits->d[(row*FRAMES_PER_ROW + num_frames)*FRAME_SIZE];
|
||||
}
|
||||
|
||||
int write_model(uint8_t* bits, int bits_len, struct fpga_model* model)
|
||||
static int get_bit(struct fpga_bits* bits,
|
||||
int row, int major, int minor, int bit_i)
|
||||
{
|
||||
return get_framebit(get_first_minor(bits, row, major)
|
||||
+ minor*FRAME_SIZE, bit_i);
|
||||
}
|
||||
|
||||
static void set_bit(struct fpga_bits* bits,
|
||||
int row, int major, int minor, int bit_i)
|
||||
{
|
||||
return set_framebit(get_first_minor(bits, row, major)
|
||||
+ minor*FRAME_SIZE, bit_i);
|
||||
}
|
||||
|
||||
static void clear_bit(struct fpga_bits* bits,
|
||||
int row, int major, int minor, int bit_i)
|
||||
{
|
||||
return clear_framebit(get_first_minor(bits, row, major)
|
||||
+ minor*FRAME_SIZE, bit_i);
|
||||
}
|
||||
|
||||
struct bit_pos
|
||||
{
|
||||
int row;
|
||||
int major;
|
||||
int minor;
|
||||
int bit_i;
|
||||
};
|
||||
|
||||
static int get_bitp(struct fpga_bits* bits, struct bit_pos* pos)
|
||||
{
|
||||
return get_bit(bits, pos->row, pos->major, pos->minor, pos->bit_i);
|
||||
}
|
||||
|
||||
static void set_bitp(struct fpga_bits* bits, struct bit_pos* pos)
|
||||
{
|
||||
set_bit(bits, pos->row, pos->major, pos->minor, pos->bit_i);
|
||||
}
|
||||
|
||||
static void clear_bitp(struct fpga_bits* bits, struct bit_pos* pos)
|
||||
{
|
||||
clear_bit(bits, pos->row, pos->major, pos->minor, pos->bit_i);
|
||||
}
|
||||
|
||||
static struct bit_pos s_default_bits[] = {
|
||||
{ 0, 0, 3, 66 },
|
||||
{ 0, 1, 23, 1034 },
|
||||
{ 0, 1, 23, 1035 },
|
||||
{ 0, 1, 23, 1039 },
|
||||
{ 2, 0, 3, 66 }};
|
||||
|
||||
int extract_model(struct fpga_model* model, struct fpga_bits* bits)
|
||||
{
|
||||
int i, rc;
|
||||
|
||||
for (i = 0; i < sizeof(s_default_bits)/sizeof(s_default_bits[0]); i++) {
|
||||
if (!get_bitp(bits, &s_default_bits[i]))
|
||||
FAIL(EINVAL);
|
||||
clear_bitp(bits, &s_default_bits[i]);
|
||||
}
|
||||
return 0;
|
||||
fail:
|
||||
return rc;
|
||||
}
|
||||
|
||||
int write_model(struct fpga_bits* bits, struct fpga_model* model)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < sizeof(s_default_bits)/sizeof(s_default_bits[0]); i++)
|
||||
set_bitp(bits, &s_default_bits[i]);
|
||||
return 0;
|
||||
}
|
||||
|
|
134
bit_regs.c
134
bit_regs.c
|
@ -7,34 +7,13 @@
|
|||
|
||||
#include "model.h"
|
||||
#include "bit.h"
|
||||
#include "parts.h"
|
||||
|
||||
static int parse_header(struct fpga_config* config, uint8_t* d,
|
||||
int len, int inpos, int* outdelta);
|
||||
static int parse_commands(struct fpga_config* config, uint8_t* d,
|
||||
int len, int inpos);
|
||||
|
||||
static const int minors_per_major[] =
|
||||
{
|
||||
/* 0 */ 4, // 505 bytes = middle 8-bit for each minor?
|
||||
/* 1 */ 30, // left
|
||||
/* 2 */ 31, // logic M
|
||||
/* 3 */ 30, // logic L
|
||||
/* 4 */ 25, // bram
|
||||
/* 5 */ 31, // logic M
|
||||
/* 6 */ 30, // logic L
|
||||
/* 7 */ 24, // macc
|
||||
/* 8 */ 31, // logic M
|
||||
/* 9 */ 31, // center
|
||||
/* 10 */ 31, // logic M
|
||||
/* 11 */ 30, // logic L
|
||||
/* 12 */ 31, // logic M
|
||||
/* 13 */ 30, // logic L
|
||||
/* 14 */ 25, // bram
|
||||
/* 15 */ 31, // logic M
|
||||
/* 16 */ 30, // logic L
|
||||
/* 17 */ 30, // right
|
||||
};
|
||||
|
||||
#define SYNC_WORD 0xAA995566
|
||||
|
||||
#define PACKET_HDR_TYPE_S 13
|
||||
|
@ -818,17 +797,17 @@ static void printf_clb(uint8_t* maj_bits, int row, int major)
|
|||
|
||||
// bits
|
||||
for (j = 0; j < 64; j++) {
|
||||
if (bit_set(&maj_bits[20*130], frame_off + j))
|
||||
if (get_framebit(&maj_bits[20*130], frame_off + j))
|
||||
printf("r%i ma%i clb i%i mi20 bit %i\n",
|
||||
row, major, i-start, j);
|
||||
}
|
||||
for (j = 0; j < 64; j++) {
|
||||
if (bit_set(&maj_bits[23*130], frame_off + j))
|
||||
if (get_framebit(&maj_bits[23*130], frame_off + j))
|
||||
printf("r%i ma%i clb i%i mi23 bit %i\n",
|
||||
row, major, i-start, j);
|
||||
}
|
||||
for (j = 0; j < 64; j++) {
|
||||
if (bit_set(&maj_bits[26*130], frame_off + j))
|
||||
if (get_framebit(&maj_bits[26*130], frame_off + j))
|
||||
printf("r%i ma%i clb i%i mi26 bit %i\n",
|
||||
row, major, i-start, j);
|
||||
}
|
||||
|
@ -852,21 +831,21 @@ static int dump_bits(struct fpga_config* cfg)
|
|||
last_extra_minor = 21;
|
||||
minor = 0;
|
||||
while (minor <= last_extra_minor) {
|
||||
minor += printf_frames(&cfg->bits[off
|
||||
minor += printf_frames(&cfg->bits.d[off
|
||||
+minor*130], 31 - minor, row,
|
||||
major, minor, /*print_empty*/ 0);
|
||||
}
|
||||
|
||||
// clock
|
||||
for (; minor < 24; minor++)
|
||||
printf_clock(&cfg->bits[off+minor*130],
|
||||
printf_clock(&cfg->bits.d[off+minor*130],
|
||||
row, major, minor);
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
for (minor = last_extra_minor+1; minor < 24;
|
||||
minor++) {
|
||||
for (j = 0; j < 256; j++) {
|
||||
if (bit_set(&cfg->bits[off+minor*130], i*256 + ((i>=2)?16:0) + j))
|
||||
if (get_framebit(&cfg->bits.d[off+minor*130], i*256 + ((i>=2)?16:0) + j))
|
||||
printf("r%i ma%i dsp i%i mi%i bit %i\n", row, major, i, minor, i*256+j);
|
||||
}
|
||||
}
|
||||
|
@ -876,46 +855,46 @@ static int dump_bits(struct fpga_config* cfg)
|
|||
|| major == 13 || major == 15 || major == 16) { // logic
|
||||
minor = 0;
|
||||
while (minor < 20) {
|
||||
minor += printf_frames(&cfg->bits[off
|
||||
minor += printf_frames(&cfg->bits.d[off
|
||||
+minor*130], 31 - minor, row,
|
||||
major, minor, /*print_empty*/ 0);
|
||||
}
|
||||
|
||||
// clock
|
||||
for (minor = 20; minor < 31; minor++)
|
||||
printf_clock(&cfg->bits[off+minor*130],
|
||||
printf_clock(&cfg->bits.d[off+minor*130],
|
||||
row, major, minor);
|
||||
// extra bits at bottom of row0 and top of row3
|
||||
if (row == 3)
|
||||
printf_extrabits(&cfg->bits[off], 20, 11,
|
||||
printf_extrabits(&cfg->bits.d[off], 20, 11,
|
||||
0, 128, row, major);
|
||||
else if (!row)
|
||||
printf_extrabits(&cfg->bits[off], 20, 11,
|
||||
printf_extrabits(&cfg->bits.d[off], 20, 11,
|
||||
14*64 + 16, 128, row, major);
|
||||
|
||||
// clbs
|
||||
printf_clb(&cfg->bits[off], row, major);
|
||||
printf_clb(&cfg->bits.d[off], row, major);
|
||||
} else if (major == 4 || major == 14) { // bram
|
||||
ramb16_cfg_t ramb16_cfg[4];
|
||||
|
||||
// minors 0..22
|
||||
minor = 0;
|
||||
while (minor < 23) {
|
||||
minor += printf_frames(&cfg->bits[off
|
||||
minor += printf_frames(&cfg->bits.d[off
|
||||
+minor*130], 23 - minor, row,
|
||||
major, minor, /*print_empty*/ 0);
|
||||
}
|
||||
|
||||
// minors 23&24
|
||||
printf_clock(&cfg->bits[off+23*130], row, major, 23);
|
||||
printf_clock(&cfg->bits[off+24*130], row, major, 24);
|
||||
printf_clock(&cfg->bits.d[off+23*130], row, major, 23);
|
||||
printf_clock(&cfg->bits.d[off+24*130], row, major, 24);
|
||||
for (i = 0; i < 4; i++) {
|
||||
offset_in_frame = i*32;
|
||||
if (offset_in_frame >= 64)
|
||||
offset_in_frame += 2;
|
||||
for (j = 0; j < 32; j++) {
|
||||
ramb16_cfg[i].byte[j] = cfg->bits[off+23*130+offset_in_frame+j];
|
||||
ramb16_cfg[i].byte[j+32] = cfg->bits[off+24*130+offset_in_frame+j];
|
||||
ramb16_cfg[i].byte[j] = cfg->bits.d[off+23*130+offset_in_frame+j];
|
||||
ramb16_cfg[i].byte[j+32] = cfg->bits.d[off+24*130+offset_in_frame+j];
|
||||
}
|
||||
}
|
||||
for (i = 0; i < 4; i++) {
|
||||
|
@ -930,14 +909,16 @@ static int dump_bits(struct fpga_config* cfg)
|
|||
print_ramb16_cfg(&ramb16_cfg[i]);
|
||||
}
|
||||
} else {
|
||||
int major_minors =
|
||||
get_major_minors(XC6SLX9, major);
|
||||
minor = 0;
|
||||
while (minor < minors_per_major[major]) {
|
||||
minor += printf_frames(&cfg->bits[off
|
||||
+minor*130], minors_per_major[major]
|
||||
- minor, row, major, minor, /*print_empty*/ 0);
|
||||
while (minor < major_minors) {
|
||||
minor += printf_frames(&cfg->bits.d[off
|
||||
+minor*130], major_minors - minor,
|
||||
row, major, minor, /*print_empty*/ 0);
|
||||
}
|
||||
}
|
||||
off += minors_per_major[major] * 130;
|
||||
off += get_major_minors(XC6SLX9, major) * 130;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
@ -951,7 +932,7 @@ static int dump_bram(struct fpga_config* cfg)
|
|||
for (row = 0; row < 4; row++) {
|
||||
for (i = 0; i < 8; i++) {
|
||||
for (j = 0; j < 18*130; j++) {
|
||||
if (cfg->bits[BRAM_DATA_START + row*144*130
|
||||
if (cfg->bits.d[BRAM_DATA_START + row*144*130
|
||||
+ i*18*130 + j])
|
||||
break;
|
||||
}
|
||||
|
@ -964,7 +945,7 @@ static int dump_bram(struct fpga_config* cfg)
|
|||
printf("br%i ramb16 i%i\n", row, i);
|
||||
printf("{\n");
|
||||
off = BRAM_DATA_START + row*144*130 + i*18*130;
|
||||
printf_ramb16_data(cfg->bits, off);
|
||||
printf_ramb16_data(cfg->bits.d, off);
|
||||
printf("}\n");
|
||||
}
|
||||
}
|
||||
|
@ -986,7 +967,7 @@ int dump_config(struct fpga_config* cfg, int flags)
|
|||
if (rc) FAIL(rc);
|
||||
rc = dump_bram(cfg);
|
||||
if (rc) FAIL(rc);
|
||||
printf_iob(cfg->bits, cfg->bits_len,
|
||||
printf_iob(cfg->bits.d, cfg->bits.len,
|
||||
BRAM_DATA_START + BRAM_DATA_LEN, 896*2/8);
|
||||
}
|
||||
if (flags & DUMP_REGS) {
|
||||
|
@ -1000,8 +981,8 @@ fail:
|
|||
|
||||
void free_config(struct fpga_config* cfg)
|
||||
{
|
||||
free(cfg->bits);
|
||||
cfg->bits = 0;
|
||||
free(cfg->bits.d);
|
||||
cfg->bits.d = 0;
|
||||
memset(cfg, 0, sizeof(*cfg));
|
||||
}
|
||||
|
||||
|
@ -1066,11 +1047,11 @@ static int FAR_pos(int FAR_row, int FAR_major, int FAR_minor)
|
|||
if (FAR_row < 0 || FAR_major < 0 || FAR_minor < 0)
|
||||
return -1;
|
||||
if (FAR_row > 3 || FAR_major > 17
|
||||
|| FAR_minor >= minors_per_major[FAR_major])
|
||||
|| FAR_minor >= get_major_minors(XC6SLX9, FAR_major))
|
||||
return -1;
|
||||
result = FAR_row * 505*130;
|
||||
for (i = 0; i < FAR_major; i++)
|
||||
result += minors_per_major[i]*130;
|
||||
result += get_major_minors(XC6SLX9, i)*130;
|
||||
return result + FAR_minor*130;
|
||||
}
|
||||
|
||||
|
@ -1091,9 +1072,9 @@ static int read_bits(struct fpga_config* cfg, uint8_t* d, int len, int inpos, in
|
|||
|| cfg->reg[cfg->FLR_reg].int_v != 896)
|
||||
FAIL(EINVAL);
|
||||
|
||||
cfg->bits_len = (4*505 + 4*144) * 130 + 896*2;
|
||||
cfg->bits = calloc(cfg->bits_len, 1 /* elsize */);
|
||||
if (!cfg->bits) FAIL(ENOMEM);
|
||||
cfg->bits.len = (4*505 + 4*144) * 130 + 896*2;
|
||||
cfg->bits.d = calloc(cfg->bits.len, 1 /* elsize */);
|
||||
if (!cfg->bits.d) FAIL(ENOMEM);
|
||||
|
||||
FAR_block = -1;
|
||||
FAR_row = -1;
|
||||
|
@ -1178,7 +1159,7 @@ static int read_bits(struct fpga_config* cfg, uint8_t* d, int len, int inpos, in
|
|||
if (FAR_block != 0) FAIL(EINVAL);
|
||||
offset_in_bits = FAR_pos(FAR_row, FAR_major, FAR_minor);
|
||||
if (offset_in_bits == -1) FAIL(EINVAL);
|
||||
memmove(&cfg->bits[offset_in_bits], &cfg->bits[MFW_src_off], 130);
|
||||
memmove(&cfg->bits.d[offset_in_bits], &cfg->bits.d[MFW_src_off], 130);
|
||||
|
||||
src_off += 8;
|
||||
continue;
|
||||
|
@ -1241,7 +1222,7 @@ static int read_bits(struct fpga_config* cfg, uint8_t* d, int len, int inpos, in
|
|||
padding_frames += 2;
|
||||
continue;
|
||||
}
|
||||
memcpy(&cfg->bits[offset_in_bits
|
||||
memcpy(&cfg->bits.d[offset_in_bits
|
||||
+ (i-padding_frames)*130],
|
||||
&d[src_off + i*130], 130);
|
||||
}
|
||||
|
@ -1250,7 +1231,7 @@ static int read_bits(struct fpga_config* cfg, uint8_t* d, int len, int inpos, in
|
|||
int bram_data_words = 4*144*65 + 896;
|
||||
if (u32 - block0_words != bram_data_words + 1) FAIL(EINVAL);
|
||||
offset_in_bits = BRAM_DATA_START;
|
||||
memcpy(&cfg->bits[offset_in_bits],
|
||||
memcpy(&cfg->bits.d[offset_in_bits],
|
||||
&d[src_off+block0_words*2],
|
||||
bram_data_words*2);
|
||||
u16 = __be16_to_cpu(*(uint16_t*)&d[
|
||||
|
@ -1264,8 +1245,8 @@ static int read_bits(struct fpga_config* cfg, uint8_t* d, int len, int inpos, in
|
|||
}
|
||||
rc = EINVAL;
|
||||
fail:
|
||||
free(cfg->bits);
|
||||
cfg->bits = 0;
|
||||
free(cfg->bits.d);
|
||||
cfg->bits.d = 0;
|
||||
return rc;
|
||||
success:
|
||||
*outdelta = src_off - inpos;
|
||||
|
@ -1289,7 +1270,7 @@ static int parse_commands(struct fpga_config* cfg, uint8_t* d,
|
|||
if (curpos + cmd_len > len) FAIL(EINVAL);
|
||||
if (curpos + cmd_len < len) {
|
||||
printf("#W Unexpected continuation after offset "
|
||||
"%i.\n", curpos + 5 + cmd_len);
|
||||
"%i (len %i).\n", curpos + cmd_len, len);
|
||||
}
|
||||
|
||||
if (curpos >= len) FAIL(EINVAL);
|
||||
|
@ -1678,17 +1659,17 @@ fail:
|
|||
|
||||
static int write_bits(FILE* f, struct fpga_model* model)
|
||||
{
|
||||
uint8_t* bits;
|
||||
struct fpga_bits bits;
|
||||
uint16_t u16;
|
||||
uint32_t u32;
|
||||
int bits_len, nwritten, i, j, rc;
|
||||
int nwritten, i, j, rc;
|
||||
char padding_frame[FRAME_SIZE];
|
||||
|
||||
bits_len = IOB_DATA_START + IOB_DATA_LEN;
|
||||
bits = calloc(bits_len, /*elsize*/ 1);
|
||||
if (!bits) FAIL(ENOMEM);
|
||||
bits.len = IOB_DATA_START + IOB_DATA_LEN;
|
||||
bits.d = calloc(bits.len, /*elsize*/ 1);
|
||||
if (!bits.d) FAIL(ENOMEM);
|
||||
|
||||
rc = write_model(bits, bits_len, model);
|
||||
rc = write_model(&bits, model);
|
||||
if (rc) FAIL(rc);
|
||||
|
||||
u16 = PACKET_TYPE_2 << PACKET_HDR_TYPE_S;
|
||||
|
@ -1713,7 +1694,7 @@ static int write_bits(FILE* f, struct fpga_model* model)
|
|||
|
||||
// write rows with padding frames
|
||||
for (i = 0; i < NUM_ROWS; i++) {
|
||||
nwritten = fwrite(&bits[i*FRAMES_PER_ROW*FRAME_SIZE],
|
||||
nwritten = fwrite(&bits.d[i*FRAMES_PER_ROW*FRAME_SIZE],
|
||||
/*size*/ 1, FRAMES_PER_ROW*FRAME_SIZE, f);
|
||||
if (nwritten != FRAMES_PER_ROW*FRAME_SIZE) FAIL(errno);
|
||||
for (j = 0; j < PADDING_FRAMES_PER_ROW; j++) {
|
||||
|
@ -1724,12 +1705,12 @@ static int write_bits(FILE* f, struct fpga_model* model)
|
|||
}
|
||||
|
||||
// write bram data
|
||||
nwritten = fwrite(&bits[BRAM_DATA_START],
|
||||
nwritten = fwrite(&bits.d[BRAM_DATA_START],
|
||||
/*size*/ 1, BRAM_DATA_LEN, f);
|
||||
if (nwritten != BRAM_DATA_LEN) FAIL(errno);
|
||||
|
||||
// write IOB data
|
||||
nwritten = fwrite(&bits[IOB_DATA_START],
|
||||
nwritten = fwrite(&bits.d[IOB_DATA_START],
|
||||
/*size*/ 1, IOB_DATA_LEN, f);
|
||||
if (nwritten != IOB_DATA_LEN) FAIL(errno);
|
||||
|
||||
|
@ -1743,17 +1724,17 @@ static int write_bits(FILE* f, struct fpga_model* model)
|
|||
nwritten = fwrite(&u32, /*size*/ 1, sizeof(u32), f);
|
||||
if (nwritten != sizeof(u32)) FAIL(errno);
|
||||
|
||||
free(bits);
|
||||
free(bits.d);
|
||||
return 0;
|
||||
fail:
|
||||
free(bits);
|
||||
free(bits.d);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int write_bitfile(FILE* f, struct fpga_model* model)
|
||||
{
|
||||
uint32_t u32;
|
||||
int len_to_eof_pos, nwritten, i, rc;
|
||||
int len_to_eof_pos, eof_pos, nwritten, i, rc;
|
||||
|
||||
rc = write_header(f, "fpgatools.fp;UserID=0xFFFFFFFF",
|
||||
"6slx9tqg144", "2010/05/26", "08:00:00");
|
||||
|
@ -1782,6 +1763,17 @@ int write_bitfile(FILE* f, struct fpga_model* model)
|
|||
rc = write_reg_action(f, &s_defregs_after_bits[i]);
|
||||
if (rc) FAIL(rc);
|
||||
}
|
||||
|
||||
// write len to eof at offset len_to_eof_pos
|
||||
if ((eof_pos = ftell(f)) == -1)
|
||||
FAIL(errno);
|
||||
if (fseek(f, len_to_eof_pos, SEEK_SET) == -1)
|
||||
FAIL(errno);
|
||||
u32 = __cpu_to_be32(eof_pos - len_to_eof_pos - sizeof(u32));
|
||||
nwritten = fwrite(&u32, /*size*/ 1, sizeof(u32), f);
|
||||
if (nwritten != sizeof(u32)) FAIL(errno);
|
||||
if (fseek(f, eof_pos, SEEK_SET) == -1)
|
||||
FAIL(errno);
|
||||
return 0;
|
||||
fail:
|
||||
return rc;
|
||||
|
|
13
floorplan.c
13
floorplan.c
|
@ -760,7 +760,18 @@ next_line: ;
|
|||
|
||||
int write_floorplan(FILE* f, struct fpga_model* model, int flags)
|
||||
{
|
||||
if (!(flags & FP_BITS_ONLY))
|
||||
int rc;
|
||||
|
||||
if (!(flags & FP_NO_HEADER))
|
||||
printf_version(f);
|
||||
|
||||
rc = printf_devices(f, model, /*config_only*/ 1);
|
||||
if (rc) FAIL(rc);
|
||||
|
||||
rc = printf_switches(f, model, /*enabled_only*/ 1);
|
||||
if (rc) FAIL(rc);
|
||||
|
||||
return 0;
|
||||
fail:
|
||||
return rc;
|
||||
}
|
||||
|
|
|
@ -25,8 +25,8 @@
|
|||
//
|
||||
|
||||
int read_floorplan(struct fpga_model* model, FILE* f);
|
||||
#define FP_BITS_DEFAULT 0x0000
|
||||
#define FP_BITS_ONLY 0x0001
|
||||
#define FP_DEFAULT 0x0000
|
||||
#define FP_NO_HEADER 0x0001
|
||||
int write_floorplan(FILE* f, struct fpga_model* model, int flags);
|
||||
|
||||
void printf_version(FILE* f);
|
||||
|
|
31
helper.c
31
helper.c
|
@ -480,9 +480,22 @@ int count_bits(uint8_t* d, int l)
|
|||
return bits;
|
||||
}
|
||||
|
||||
int bit_set(uint8_t* frame_d, int bit)
|
||||
int get_framebit(uint8_t* frame_d, int bit)
|
||||
{
|
||||
return (frame_d[(bit/16)*2 + !((bit/8)%2)] & 1<<(7-(bit%8))) != 0;
|
||||
uint8_t v = 1<<(7-(bit%8));
|
||||
return (frame_d[(bit/16)*2 + !((bit/8)%2)] & v) != 0;
|
||||
}
|
||||
|
||||
void clear_framebit(uint8_t* frame_d, int bit)
|
||||
{
|
||||
uint8_t v = 1<<(7-(bit%8));
|
||||
frame_d[(bit/16)*2 + !((bit/8)%2)] &= ~v;
|
||||
}
|
||||
|
||||
void set_framebit(uint8_t* frame_d, int bit)
|
||||
{
|
||||
uint8_t v = 1<<(7-(bit%8));
|
||||
frame_d[(bit/16)*2 + !((bit/8)%2)] |= v;
|
||||
}
|
||||
|
||||
int printf_frames(uint8_t* bits, int max_frames,
|
||||
|
@ -512,7 +525,7 @@ int printf_frames(uint8_t* bits, int max_frames,
|
|||
if (count_bits(bits, 130) <= 32) {
|
||||
printf_clock(bits, row, major, minor);
|
||||
for (i = 0; i < 1024; i++) {
|
||||
if (bit_set(bits, (i >= 512) ? i + 16 : i))
|
||||
if (get_framebit(bits, (i >= 512) ? i + 16 : i))
|
||||
printf("%sbit %i\n", prefix, i);
|
||||
}
|
||||
return 1;
|
||||
|
@ -528,7 +541,7 @@ void printf_clock(uint8_t* frame, int row, int major, int minor)
|
|||
{
|
||||
int i;
|
||||
for (i = 0; i < 16; i++) {
|
||||
if (bit_set(frame, 512 + i))
|
||||
if (get_framebit(frame, 512 + i))
|
||||
printf("r%i ma%i mi%i clock %i\n",
|
||||
row, major, minor, i);
|
||||
}
|
||||
|
@ -557,7 +570,7 @@ void printf_extrabits(uint8_t* maj_bits, int start_minor, int num_minors,
|
|||
|
||||
for (minor = start_minor; minor < start_minor + num_minors; minor++) {
|
||||
for (bit = start_bit; bit < start_bit + num_bits; bit++) {
|
||||
if (bit_set(&maj_bits[minor*130], bit))
|
||||
if (get_framebit(&maj_bits[minor*130], bit))
|
||||
printf("r%i ma%i extra mi%i bit %i\n",
|
||||
row, major, minor, bit);
|
||||
}
|
||||
|
@ -570,13 +583,13 @@ uint64_t read_lut64(uint8_t* two_minors, int off_in_frame)
|
|||
int j;
|
||||
|
||||
for (j = 0; j < 16; j++) {
|
||||
if (bit_set(two_minors, off_in_frame+j*2))
|
||||
if (get_framebit(two_minors, off_in_frame+j*2))
|
||||
lut64 |= 1LL << (j*4);
|
||||
if (bit_set(two_minors, off_in_frame+(j*2)+1))
|
||||
if (get_framebit(two_minors, off_in_frame+(j*2)+1))
|
||||
lut64 |= 1LL << (j*4+1);
|
||||
if (bit_set(&two_minors[130], off_in_frame+j*2))
|
||||
if (get_framebit(&two_minors[130], off_in_frame+j*2))
|
||||
lut64 |= 1LL << (j*4+2);
|
||||
if (bit_set(&two_minors[130], off_in_frame+(j*2)+1))
|
||||
if (get_framebit(&two_minors[130], off_in_frame+(j*2)+1))
|
||||
lut64 |= 1LL << (j*4+3);
|
||||
}
|
||||
return lut64;
|
||||
|
|
4
helper.h
4
helper.h
|
@ -64,7 +64,9 @@ void printf_ramb16_data(uint8_t* bits, int inpos);
|
|||
|
||||
int is_empty(uint8_t* d, int l);
|
||||
int count_bits(uint8_t* d, int l);
|
||||
int bit_set(uint8_t* frame_d, int bit);
|
||||
int get_framebit(uint8_t* frame_d, int bit);
|
||||
void clear_framebit(uint8_t* frame_d, int bit);
|
||||
void set_framebit(uint8_t* frame_d, int bit);
|
||||
|
||||
// if row is negative, it's an absolute frame number and major and
|
||||
// minor are ignored
|
||||
|
|
233
not-needed.h
233
not-needed.h
|
@ -1,233 +0,0 @@
|
|||
//
|
||||
// Author: Wolfgang Spraul
|
||||
//
|
||||
// This is free and unencumbered software released into the public domain.
|
||||
// For details see the UNLICENSE file at the root of the source tree.
|
||||
//
|
||||
|
||||
static const char* iob_xc6slx4_sitenames[896*2/8] =
|
||||
{
|
||||
[0x0000/8] "P70",
|
||||
"P69",
|
||||
"P67",
|
||||
"P66",
|
||||
"P65",
|
||||
"P64",
|
||||
"P62",
|
||||
"P61",
|
||||
"P60",
|
||||
"P59",
|
||||
"P58",
|
||||
"P57",
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
[0x0080/8] 0,
|
||||
0,
|
||||
"P56",
|
||||
"P55",
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
"P51",
|
||||
"P50",
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
[0x0100/8] 0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
"UNB131",
|
||||
"UNB132",
|
||||
"P48",
|
||||
"P47",
|
||||
"P46",
|
||||
"P45",
|
||||
"P44",
|
||||
"P43",
|
||||
0,
|
||||
0,
|
||||
"P41",
|
||||
"P40",
|
||||
[0x0180/8] "P39",
|
||||
"P38",
|
||||
"P35",
|
||||
"P34",
|
||||
"P33",
|
||||
"P32",
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
[0x0200/8] "P30",
|
||||
"P29",
|
||||
"P27",
|
||||
"P26",
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
"P24",
|
||||
"P23",
|
||||
"P22",
|
||||
"P21",
|
||||
0,
|
||||
0,
|
||||
[0x0280/8] 0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
"P17",
|
||||
"P16",
|
||||
"P15",
|
||||
"P14",
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
[0x0300/8] "P12",
|
||||
"P11",
|
||||
"P10",
|
||||
"P9",
|
||||
"P8",
|
||||
"P7",
|
||||
"P6",
|
||||
"P5",
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
"P2",
|
||||
"P1",
|
||||
[0x0380/8] "P144",
|
||||
"P143",
|
||||
"P142",
|
||||
"P141",
|
||||
"P140",
|
||||
"P139",
|
||||
"P138",
|
||||
"P137",
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
[0x0400/8] 0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
"P134",
|
||||
"P133",
|
||||
"P132",
|
||||
"P131",
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
"P127",
|
||||
"P126",
|
||||
[0x0480/8] "P124",
|
||||
"P123",
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
"P121",
|
||||
"P120",
|
||||
"P119",
|
||||
"P118",
|
||||
"P117",
|
||||
"P116",
|
||||
"P115",
|
||||
"P114",
|
||||
[0x0500/8] "P112",
|
||||
"P111",
|
||||
"P105",
|
||||
"P104",
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
"P102",
|
||||
"P101",
|
||||
"P99",
|
||||
"P98",
|
||||
"P97",
|
||||
[0x0580/8] 0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
"P95",
|
||||
"P94",
|
||||
"P93",
|
||||
"P92",
|
||||
0,
|
||||
0,
|
||||
[0x0600/8] 0,
|
||||
0,
|
||||
0,
|
||||
"P88",
|
||||
"P87",
|
||||
0,
|
||||
"P85",
|
||||
"P84",
|
||||
0,
|
||||
0,
|
||||
"P83",
|
||||
"P82",
|
||||
"P81",
|
||||
"P80",
|
||||
"P79",
|
||||
"P78",
|
||||
[0x0680/8] 0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
"P75",
|
||||
"P74"
|
||||
};
|
87
parts.c
Normal file
87
parts.c
Normal file
|
@ -0,0 +1,87 @@
|
|||
//
|
||||
// Author: Wolfgang Spraul
|
||||
//
|
||||
// This is free and unencumbered software released into the public domain.
|
||||
// For details see the UNLICENSE file at the root of the source tree.
|
||||
//
|
||||
|
||||
#include "helper.h"
|
||||
#include "parts.h"
|
||||
|
||||
const char* iob_xc6slx4_sitenames[896*2/8] =
|
||||
{
|
||||
[0x0000/8]
|
||||
"P70", "P69", "P67", "P66", "P65", "P64", "P62", "P61",
|
||||
"P60", "P59", "P58", "P57", 0, 0, 0, 0,
|
||||
[0x0080/8]
|
||||
0, 0, "P56", "P55", 0, 0, 0, 0,
|
||||
0, 0, "P51", "P50", 0, 0, 0, 0,
|
||||
[0x0100/8]
|
||||
0, 0, 0, 0, "UNB131", "UNB132", "P48", "P47",
|
||||
"P46", "P45", "P44", "P43", 0, 0, "P41", "P40",
|
||||
[0x0180/8]
|
||||
"P39", "P38", "P35", "P34", "P33", "P32", 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
[0x0200/8]
|
||||
"P30", "P29", "P27", "P26", 0, 0, 0, 0,
|
||||
0, 0, "P24", "P23", "P22", "P21", 0, 0,
|
||||
[0x0280/8]
|
||||
0, 0, 0, 0, "P17", "P16", "P15", "P14",
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
[0x0300/8]
|
||||
"P12", "P11", "P10", "P9", "P8", "P7", "P6", "P5",
|
||||
0, 0, 0, 0, 0, 0, "P2", "P1",
|
||||
[0x0380/8]
|
||||
"P144", "P143", "P142", "P141", "P140", "P139", "P138", "P137",
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
[0x0400/8]
|
||||
0, 0, 0, 0, "P134", "P133", "P132", "P131",
|
||||
0, 0, 0, 0, 0, 0, "P127", "P126",
|
||||
[0x0480/8]
|
||||
"P124", "P123", 0, 0, 0, 0, 0, 0,
|
||||
"P121", "P120", "P119", "P118", "P117", "P116", "P115", "P114",
|
||||
[0x0500/8]
|
||||
"P112", "P111", "P105", "P104", 0, 0, 0, 0,
|
||||
0, 0, "P102", "P101", "P99", "P98", "P97", 0,
|
||||
[0x0580/8]
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, "P95", "P94", "P93", "P92", 0, 0,
|
||||
[0x0600/8]
|
||||
0, 0, 0, "P88", "P87", 0, "P85", "P84",
|
||||
0, 0, "P83", "P82", "P81", "P80", "P79", "P78",
|
||||
[0x0680/8]
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, "P75", "P74"
|
||||
};
|
||||
|
||||
static const int minors_per_major[] = // for slx4 and slx9
|
||||
{
|
||||
/* 0 */ 4, // 505 bytes = middle 8-bit for each minor?
|
||||
/* 1 */ 30, // left
|
||||
/* 2 */ 31, // logic M
|
||||
/* 3 */ 30, // logic L
|
||||
/* 4 */ 25, // bram
|
||||
/* 5 */ 31, // logic M
|
||||
/* 6 */ 30, // logic L
|
||||
/* 7 */ 24, // macc
|
||||
/* 8 */ 31, // logic M
|
||||
/* 9 */ 31, // center
|
||||
/* 10 */ 31, // logic M
|
||||
/* 11 */ 30, // logic L
|
||||
/* 12 */ 31, // logic M
|
||||
/* 13 */ 30, // logic L
|
||||
/* 14 */ 25, // bram
|
||||
/* 15 */ 31, // logic M
|
||||
/* 16 */ 30, // logic L
|
||||
/* 17 */ 30, // right
|
||||
};
|
||||
|
||||
int get_major_minors(int idcode, int major)
|
||||
{
|
||||
if ((idcode & IDCODE_MASK) != XC6SLX9)
|
||||
EXIT(1);
|
||||
if (major < 0 || major
|
||||
> sizeof(minors_per_major)/sizeof(minors_per_major[0]))
|
||||
EXIT(1);
|
||||
return minors_per_major[major];
|
||||
}
|
26
parts.h
Normal file
26
parts.h
Normal file
|
@ -0,0 +1,26 @@
|
|||
//
|
||||
// Author: Wolfgang Spraul
|
||||
//
|
||||
// This is free and unencumbered software released into the public domain.
|
||||
// For details see the UNLICENSE file at the root of the source tree.
|
||||
//
|
||||
|
||||
// The highest 4 bits are the binary revision and not
|
||||
// used when performing IDCODE verification.
|
||||
// ug380, Configuration Sequence, page 78
|
||||
#define IDCODE_MASK 0x0FFFFFFF
|
||||
|
||||
#define XC6SLX4 0x04000093
|
||||
#define XC6SLX9 0x04001093
|
||||
#define XC6SLX16 0x04002093
|
||||
#define XC6SLX25 0x04004093
|
||||
#define XC6SLX25T 0x04024093
|
||||
#define XC6SLX45 0x04008093
|
||||
#define XC6SLX45T 0x04028093
|
||||
#define XC6SLX75 0x0400E093
|
||||
#define XC6SLX75T 0x0402E093
|
||||
#define XC6SLX100 0x04011093
|
||||
#define XC6SLX100T 0x04031093
|
||||
#define XC6SLX150 0x0401D093
|
||||
|
||||
int get_major_minors(int idcode, int major);
|
Loading…
Reference in New Issue
Block a user