bit2fp cleanup

This commit is contained in:
Wolfgang Spraul 2012-08-20 04:42:18 +02:00
parent c9ee1165da
commit d8a18a6034
14 changed files with 334 additions and 359 deletions

1
.gitignore vendored
View File

@ -28,4 +28,5 @@ fp2bit
fp2bit.o
bit2fp
bit2fp.o
parts.o
autotest.tmp/

View File

@ -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
View File

@ -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
View File

@ -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);

View File

@ -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;

View File

@ -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;
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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);

View File

@ -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;

View File

@ -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

View File

@ -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
View 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
View 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);