more json, some bram work

This commit is contained in:
Wolfgang Spraul 2015-04-01 17:13:32 -04:00
parent ad0d2924df
commit ea54683e8f
15 changed files with 612 additions and 566 deletions

2
.gitignore vendored
View File

@ -20,7 +20,7 @@
# binaries
#
draw_svg_tiles
new_fp
fpinfo
hstrrep
sort_seq
merge_seq

View File

@ -13,7 +13,7 @@ CFLAGS += -I$(CURDIR)/libs
LDFLAGS += -Wl,-rpath,$(CURDIR)/libs
OBJS = autotest.o bit2fp.o printf_swbits.o draw_svg_tiles.o fp2bit.o \
hstrrep.o merge_seq.o new_fp.o pair2net.o sort_seq.o hello_world.o \
hstrrep.o merge_seq.o fpinfo.o pair2net.o sort_seq.o hello_world.o \
blinking_led.o jtag_counter.o j1_blinking.o
DYNAMIC_LIBS = libs/libfpga-model.so libs/libfpga-bit.so \
@ -24,7 +24,7 @@ DYNAMIC_LIBS = libs/libfpga-model.so libs/libfpga-bit.so \
.SECONDARY:
.SECONDEXPANSION:
all: new_fp fp2bit bit2fp printf_swbits draw_svg_tiles autotest hstrrep \
all: fpinfo fp2bit bit2fp printf_swbits draw_svg_tiles autotest hstrrep \
sort_seq merge_seq pair2net hello_world blinking_led jtag_counter \
j1_blinking.o
@ -173,8 +173,8 @@ compare_%_sw.fco: compare_%.fp
compare_%_swbits.fco: printf_swbits
@./printf_swbits | sort > $@
compare_%.fp: new_fp
@./new_fp >$@
compare_%.fp: fpinfo
@./fpinfo >$@
# todo: .cnets not integrated yet
%.cnets: %.fp pair2net
@ -206,7 +206,7 @@ bit2fp: bit2fp.o $(DYNAMIC_LIBS)
printf_swbits: printf_swbits.o $(DYNAMIC_LIBS)
new_fp: new_fp.o $(DYNAMIC_LIBS)
fpinfo: fpinfo.o $(DYNAMIC_LIBS)
draw_svg_tiles: CFLAGS += `pkg-config libxml-2.0 --cflags`
draw_svg_tiles: LDLIBS += `pkg-config libxml-2.0 --libs`
@ -220,8 +220,8 @@ merge_seq: merge_seq.o $(DYNAMIC_LIBS)
hstrrep: hstrrep.o $(DYNAMIC_LIBS)
xc6slx9.fp: new_fp
./new_fp > $@
xc6slx9.fp: fpinfo
./fpinfo > $@
xc6slx9.svg: draw_svg_tiles
./draw_svg_tiles | xmllint --pretty 1 - > $@
@ -229,7 +229,7 @@ xc6slx9.svg: draw_svg_tiles
clean:
@make -C libs clean
rm -f $(OBJS) *.d
rm -f draw_svg_tiles new_fp hstrrep sort_seq merge_seq autotest
rm -f draw_svg_tiles fpinfo hstrrep sort_seq merge_seq autotest
rm -f fp2bit bit2fp printf_swbits pair2net hello_world blinking_led
rm -f jtag_counter j1_blinking
rm -f xc6slx9.fp xc6slx9.svg

11
README
View File

@ -2,7 +2,7 @@ Introduction
fpgatools converts the configuration of an FPGA between
JSON and bitstream representation.
The only supported chips at this time is the xc6slx9, a 45nm-generation
The only supported chip at this time is the xc6slx9, a 45nm-generation
FPGA with 5720 6-input LUTs, block ram and multiply-accumulate
resources.
@ -33,7 +33,8 @@ Design Utilities
- hello_world outputs an AND gate floorplan to stdout
- blinking_led outputs blinking led design to stdout
- new_fp creates empty .fp floorplan file
- fpinfo outputs information about tiles, devices, ports,
connections and switches in a floorplan
- fp2bit converts .fp floorplan into .bit bitstream
- bit2fp converts .bit bitstream into .fp floorplan
- draw_svg_tiles draws a simple .svg showing tile types
@ -53,12 +54,6 @@ Profiling
~# perf annotate
~# perf report
How to Help
- use fpgatools, email author for free support
- fund electron microscope photos
- want bigger or newer chips? email the author
- timing analysis, temperature analysis, visualizations
TODO (as of 2015-03)
short-term (3 months):

View File

@ -103,9 +103,9 @@ static int diff_printf(struct test_state* tstate)
dest_f = fopen(path, "w");
if (!dest_f) FAIL(errno);
rc = printf_devices(dest_f, tstate->model, /*config_only*/ 1);
rc = printf_devices(dest_f, tstate->model, /*config_only*/ 1, /*no_json*/ 1);
if (rc) FAIL(rc);
rc = printf_nets(dest_f, tstate->model);
rc = printf_nets(dest_f, tstate->model, /*no_json*/ 1);
if (rc) FAIL(rc);
fclose(dest_f);
@ -382,7 +382,7 @@ static int test_switches(struct test_state* tstate, int y, int x,
if (switch_str[2] == '4') {
// base for len-4 wire
if (tstate->dry_run)
fnet_printf(stdout, tstate->model, net);
fnet_printf(stdout, tstate->model, net, /*no_json*/ 1);
rc = diff_printf(tstate);
if (rc) FAIL(rc);
@ -420,7 +420,7 @@ static int test_switches(struct test_state* tstate, int y, int x,
// base for len-4 target
if (tstate->dry_run)
fnet_printf(stdout, tstate->model, net);
fnet_printf(stdout, tstate->model, net, /*no_json*/ 1);
rc = diff_printf(tstate);
if (rc) FAIL(rc);
@ -430,7 +430,7 @@ static int test_switches(struct test_state* tstate, int y, int x,
if (rc) FAIL(rc);
if (tstate->dry_run)
fnet_printf(stdout, tstate->model, net);
fnet_printf(stdout, tstate->model, net, /*no_json*/ 1);
rc = diff_printf(tstate);
if (rc) FAIL(rc);
@ -605,7 +605,7 @@ static int test_routing_sw_from_logic(struct test_state *tstate,
swto.dest_x, conns.chain.set.sw, conns.chain.set.len);
if (rc) FAIL(rc);
if (tstate->dry_run)
fnet_printf(stdout, tstate->model, net);
fnet_printf(stdout, tstate->model, net, /*no_json*/ 1);
rc = test_switches(tstate, conns.dest_y, conns.dest_x,
conns.dest_str_i, net, done_list, done_list_len);

View File

@ -15,7 +15,7 @@ static void help_exit(int argc, char **argv)
"\n"
"%s - bitstream to floorplan\n"
"Usage: %s [--help] [--verbose] [--bit-header] [--bit-regs] [--bit-crc]\n"
" %*s [--no-model] [--no-fp-header] <bitstream_file>\n"
" %*s [--no-model] [--no-json] <bitstream_file>\n"
"\n", argv[0], argv[0], (int) strlen(argv[0]), "");
exit(EXIT_SUCCESS);
}
@ -23,7 +23,7 @@ static void help_exit(int argc, char **argv)
int main(int argc, char** argv)
{
struct fpga_model model;
int bit_header, bit_regs, bit_crc, fp_header, pull_model, file_arg;
int bit_header, bit_regs, bit_crc, json, pull_model, file_arg;
int verbose, flags, rc = -1;
struct fpga_config config;
@ -34,7 +34,7 @@ int main(int argc, char** argv)
bit_regs = 0;
bit_crc = 0;
pull_model = 1;
fp_header = 1;
json = 1;
file_arg = 1;
while (file_arg < argc && !strncmp(argv[file_arg], "--", 2)) {
if (!strcmp(argv[file_arg], "--help"))
@ -50,8 +50,8 @@ int main(int argc, char** argv)
bit_crc = 1;
else if (!strcmp(argv[file_arg], "--no-model"))
pull_model = 0;
else if (!strcmp(argv[file_arg], "--no-fp-header"))
fp_header = 0;
else if (!strcmp(argv[file_arg], "--no-json"))
json = 0;
else break;
file_arg++;
}
@ -83,7 +83,7 @@ int main(int argc, char** argv)
// dump model
flags = FP_DEFAULT;
if (!fp_header) flags |= FP_NO_HEADER;
if (!json) flags |= FP_NO_JSON;
if ((rc = write_floorplan(stdout, &model, flags))) FAIL(rc);
// dump what doesn't fit into the model

View File

@ -20,25 +20,32 @@ int main(int argc, char** argv)
if (argc > 1 && !strcmp(argv[1], "--no-conns"))
no_conns = 1;
printf("{\n");
printf_version(stdout);
printf(",\n");
rc = printf_tiles(stdout, &model);
if (rc) goto fail;
rc = printf_devices(stdout, &model, /*config_only*/ 0);
printf(",\n");
rc = printf_devices(stdout, &model, /*config_only*/ 0, /*no_json*/ 0);
if (rc) goto fail;
printf(",\n");
rc = printf_ports(stdout, &model);
if (rc) goto fail;
if (!no_conns) {
printf(",\n");
rc = printf_conns(stdout, &model);
if (rc) goto fail;
}
printf(",\n");
rc = printf_switches(stdout, &model);
if (rc) goto fail;
printf("\n}\n");
return EXIT_SUCCESS;
fail:
return rc;

View File

@ -2315,6 +2315,10 @@ static void destruct_extract_state(struct extract_state *es)
es->yx_pos = 0;
}
//
// bscan
//
static int extract_bscan(struct extract_state *es)
{
int enum_i, bscan_y, bscan_x, bscan_type_idx;
@ -2389,6 +2393,245 @@ static int write_bscan(struct fpga_bits *bits, struct fpga_model *model)
RC_RETURN(model);
}
//
// bram
//
// Each RAMB16 stores configuration in 3 minors (22-24) and 16 vertical
// 16-bit words, for a total of 3*16*16 = 768 configuration bits per RAMB16.
// This does not include parity and initial data values which are stored
// in the data section.
// Minor 22 is for INIT and SRVAL A+B bits only (36*4=144 bits).
enum bram_cfg_names { BRAM_ENABLED_TOP, BRAM_ENABLED_BOTTOM,
BRAM_ENA_HIGH, BRAM_ENB_HIGH,
BRAM_REGCEA_HIGH, BRAM_REGCEB_HIGH,
BRAM_RSTA_LOW, BRAM_RSTB_HIGH,
BRAM_WEA0_HIGH, BRAM_WEA1_HIGH, BRAM_WEA2_HIGH,
BRAM_WEA3_HIGH,
BRAM_WEB0_HIGH, BRAM_WEB1_HIGH, BRAM_WEB2_HIGH,
BRAM_WEB3_HIGH,
BRAM_RSTTYPE_ASYNC,
BRAM_DOA_REG, BRAM_DOB_REG,
BRAM_READ_FIRST_A, BRAM_NO_CHANGE_A,
BRAM_READ_FIRST_B, BRAM_NO_CHANGE_B,
BRAM_EN_RSTRAM_A, BRAM_EN_RSTRAM_B,
BRAM_RST_PRIORITY_A_CE, BRAM_RST_PRIORITY_B_CE,
BRAM_DATA_WIDTH_A_0, BRAM_DATA_WIDTH_A_2, BRAM_DATA_WIDTH_A_4,
BRAM_DATA_WIDTH_A_9, BRAM_DATA_WIDTH_A_18,
BRAM_DATA_WIDTH_A_36,
BRAM_DATA_WIDTH_B_0, BRAM_DATA_WIDTH_B_2, BRAM_DATA_WIDTH_B_4,
BRAM_DATA_WIDTH_B_9, BRAM_DATA_WIDTH_B_18,
BRAM_DATA_WIDTH_B_36,
BRAM_RAM_MODE_TDP, BRAM_RAM_MODE_SDP };
static const cfg_bits_t bram_bits[] =
{
// minor v16 bits name
{ 23, 0, 0x0040, BRAM_ENABLED_TOP },
{ 24, 0, 0x0600, BRAM_ENABLED_TOP },
{ 24, 1, 0xC000, BRAM_ENABLED_TOP },
{ 24, 5, 0x000C, BRAM_ENABLED_TOP },
{ 24, 10, 0x3000, BRAM_ENABLED_BOTTOM },
{ 24, 14, 0x0003, BRAM_ENABLED_BOTTOM },
{ 23, 15, 0x0200, BRAM_ENABLED_BOTTOM },
{ 24, 15, 0x0060, BRAM_ENABLED_BOTTOM },
{ 24, 5, 0x0080, BRAM_ENA_HIGH },
{ 24, 6, 0x0200, BRAM_ENA_HIGH },
{ 24, 6, 0x0500, BRAM_ENB_HIGH },
{ 23, 0, 0x0400, BRAM_REGCEA_HIGH },
{ 23, 15, 0x0020, BRAM_REGCEA_HIGH },
{ 23, 0, 0x0010, BRAM_REGCEB_HIGH },
{ 23, 15, 0x0800, BRAM_REGCEB_HIGH },
{ 23, 0, 0x1000, BRAM_RSTA_LOW },
{ 23, 15, 0x0008, BRAM_RSTA_LOW },
{ 23, 0, 0x0004, BRAM_RSTB_HIGH },
{ 23, 15, 0x2000, BRAM_RSTB_HIGH },
{ 23, 15, 0x0040, BRAM_WEA0_HIGH },
{ 23, 15, 0x0010, BRAM_WEA1_HIGH },
{ 23, 0, 0x0200, BRAM_WEA2_HIGH },
{ 23, 0, 0x0800, BRAM_WEA3_HIGH },
{ 23, 15, 0x1000, BRAM_WEB0_HIGH },
{ 23, 15, 0x4000, BRAM_WEB1_HIGH },
{ 23, 0, 0x0008, BRAM_WEB2_HIGH },
{ 23, 0, 0x0002, BRAM_WEB3_HIGH },
{ 24, 0, 0x0080, BRAM_RSTTYPE_ASYNC },
{ 24, 1, 0x0100, BRAM_RSTTYPE_ASYNC },
{ 24, 14, 0x0080, BRAM_RSTTYPE_ASYNC },
{ 24, 15, 0x0100, BRAM_RSTTYPE_ASYNC },
{ 24, 1, 0x0400, BRAM_DOA_REG },
{ 24, 14, 0x0020, BRAM_DOA_REG },
{ 24, 1, 0x0200, BRAM_DOB_REG },
{ 24, 14, 0x0040, BRAM_DOB_REG },
{ 24, 0, 0x1000, BRAM_READ_FIRST_A },
{ 24, 15, 0x0008, BRAM_READ_FIRST_A },
{ 24, 0, 0x4000, BRAM_NO_CHANGE_A },
{ 24, 15, 0x0002, BRAM_NO_CHANGE_A },
{ 24, 0, 0x0800, BRAM_READ_FIRST_B },
{ 24, 15, 0x0010, BRAM_READ_FIRST_B },
{ 24, 0, 0x2000, BRAM_NO_CHANGE_B },
{ 24, 15, 0x0004, BRAM_NO_CHANGE_B },
{ 24, 1, 0x0002, BRAM_EN_RSTRAM_A },
{ 24, 14, 0x4000, BRAM_EN_RSTRAM_A },
{ 24, 5, 0x4000, BRAM_EN_RSTRAM_B },
{ 24, 10, 0x0002, BRAM_EN_RSTRAM_B },
{ 24, 0, 0x0040, BRAM_RST_PRIORITY_A_CE },
{ 24, 15, 0x0200, BRAM_RST_PRIORITY_A_CE },
{ 24, 0, 0x0020, BRAM_RST_PRIORITY_B_CE },
{ 24, 15, 0x0400, BRAM_RST_PRIORITY_B_CE },
{ 24, 0, 0x0015, BRAM_DATA_WIDTH_A_0 },
{ 24, 15, 0xA800, BRAM_DATA_WIDTH_A_0 },
{ 24, 0, 0x0001, BRAM_DATA_WIDTH_A_2 },
{ 24, 15, 0x8000, BRAM_DATA_WIDTH_A_2 },
{ 24, 0, 0x0004, BRAM_DATA_WIDTH_A_4 },
{ 24, 15, 0x2000, BRAM_DATA_WIDTH_A_4 },
{ 24, 0, 0x0005, BRAM_DATA_WIDTH_A_9 },
{ 24, 15, 0xA000, BRAM_DATA_WIDTH_A_9 },
{ 24, 0, 0x0010, BRAM_DATA_WIDTH_A_18 },
{ 24, 15, 0x0800, BRAM_DATA_WIDTH_A_18 },
{ 24, 0, 0x0011, BRAM_DATA_WIDTH_A_36 },
{ 24, 15, 0x8800, BRAM_DATA_WIDTH_A_36 },
{ 24, 0, 0x800A, BRAM_DATA_WIDTH_B_0 },
{ 24, 15, 0x5001, BRAM_DATA_WIDTH_B_0 },
{ 24, 0, 0x0002, BRAM_DATA_WIDTH_B_2 },
{ 24, 15, 0x4000, BRAM_DATA_WIDTH_B_2 },
{ 24, 0, 0x8000, BRAM_DATA_WIDTH_B_4 },
{ 24, 15, 0x0001, BRAM_DATA_WIDTH_B_4 },
{ 24, 0, 0x8002, BRAM_DATA_WIDTH_B_9 },
{ 24, 15, 0x4001, BRAM_DATA_WIDTH_B_9 },
{ 24, 0, 0x0008, BRAM_DATA_WIDTH_B_18 },
{ 24, 15, 0x1000, BRAM_DATA_WIDTH_B_18 },
{ 24, 0, 0x000A, BRAM_DATA_WIDTH_B_36 },
{ 24, 15, 0x5000, BRAM_DATA_WIDTH_B_36 },
{ 23, 0, 0x0080, BRAM_RAM_MODE_TDP },
{ 23, 15, 0x0200, BRAM_RAM_MODE_TDP },
{ 23, 1, 0x0100, BRAM_RAM_MODE_SDP },
{ 23, 15, 0x0080, BRAM_RAM_MODE_SDP },
{ -1 }
};
// Use struct to avoid warnings/casts compared to pointer to array of int.
struct eight_words
{
int w[8];
};
static void extract_init_srval_18(struct eight_words* eight_words, int *init_a,
int *init_b, int *srval_a, int *srval_b);
static void extract_init_srval_36(struct eight_words* eight_top_words,
struct eight_words* eight_bot_words, int64_t *init_a,
int64_t *init_b, int64_t *srval_a, int64_t *srval_b);
#define INIT_A 0x40000000
#define SRVAL_A 0x20000000
#define INIT_B 0x10000000
#define SRVAL_B 0x08000000
#define INIT_SRVAL_BITMASK 0x0000001F // max 17 (16-bit word plus 2 parity bits)
static void extract_init_srval_18(struct eight_words* eight_words, int *init_a,
int *init_b, int *srval_a, int *srval_b)
{
static const int bits[] = {
/* 0*/ SRVAL_B|14, INIT_A|14, 0, SRVAL_A|14, INIT_B|13, 0, SRVAL_B|13, INIT_A|13,
INIT_B|15, 0, SRVAL_B|15, INIT_A|15, 0, SRVAL_A|15, INIT_B|14, 0,
/*16*/ INIT_B|17, 0, SRVAL_B|17, INIT_A|17, 0, SRVAL_A|17, INIT_B|11, 0,
SRVAL_A|13, 0, INIT_B|12, 0, SRVAL_B|12, 0, INIT_A|12, SRVAL_A|12,
/*32*/ INIT_A|10, SRVAL_A|10, INIT_B|9, 0, 0, SRVAL_B|9, INIT_A|9, SRVAL_A|9,
SRVAL_B|11, INIT_A|11, 0, SRVAL_A|11, 0, INIT_B|10, 0, SRVAL_B|10,
/*48*/ 0, 0, 0, 0, 0, 0, 0, 0,
INIT_B|8, 0, SRVAL_B|8, INIT_A|8, 0, SRVAL_A|8, 0, 0,
/*64*/ 0, INIT_B|7, SRVAL_B|7, INIT_A|7, 0, SRVAL_A|7, 0, INIT_B|6,
0, 0, 0, 0, 0, 0, 0, 0,
/*80*/ 0, SRVAL_A|5, INIT_B|4, 0, 0, SRVAL_B|4, INIT_A|4, SRVAL_A|4,
SRVAL_B|6, INIT_A|6, 0, SRVAL_A|6, INIT_B|5, 0, SRVAL_B|5, INIT_A|5,
/*96*/ SRVAL_B|3, INIT_A|3, 0, SRVAL_A|3, 0, INIT_B|2, 0, SRVAL_B|2,
INIT_B|16, 0, SRVAL_B|16, INIT_A|16, 0, SRVAL_A|16, 0, INIT_B|3,
/*112*/ INIT_B|0, 0, SRVAL_B|0, INIT_A|0, 0, 0, SRVAL_A|0, 0,
INIT_A|2, SRVAL_A|2, 0, INIT_B|1, 0, SRVAL_B|1, INIT_A|1, SRVAL_A|1 };
int i, j, bit_set;
*init_a = 0; *srval_a = 0;
*init_b = 0; *srval_b = 0;
for (i = 0; i < 8; i++) {
for (j = 0; j < 16; j++) {
if (!(eight_words->w[i] & (1<<j))) continue;
if ((bits[i*16+j] & INIT_SRVAL_BITMASK) > 17)
HERE();
bit_set = 1<<(bits[i*16+j]&INIT_SRVAL_BITMASK);
if (bits[i*16+j] & INIT_A) {
*init_a |= bit_set;
} else if (bits[i*16+j] & SRVAL_A) {
*srval_a |= bit_set;
} else if (bits[i*16+j] & INIT_B) {
*init_b |= bit_set;
} else if (bits[i*16+j] & SRVAL_B) {
*srval_b |= bit_set;
} else {
HERE();
}
}
}
}
static void extract_init_srval_36(struct eight_words* eight_top_words,
struct eight_words* eight_bot_words, int64_t *init_a,
int64_t *init_b, int64_t *srval_a, int64_t *srval_b)
{
int init_a_top, init_a_bot, srval_a_top, srval_a_bot,
init_b_top, init_b_bot, srval_b_top, srval_b_bot;
extract_init_srval_18(eight_top_words, &init_a_top, &init_b_top, &srval_a_top, &srval_b_top);
extract_init_srval_18(eight_bot_words, &init_a_bot, &init_b_bot, &srval_a_bot, &srval_b_bot);
*init_a = ((int64_t) init_a_top & 0xFFFF) | (((int64_t) init_a_bot & 0xFFFF) << 16)
| (((int64_t) init_a_top & 0x3000) << 32) | (( (int64_t) init_a_bot & 0x3000) << 34);
*init_b = ((int64_t) init_b_top & 0xFFFF) | (((int64_t) init_b_bot & 0xFFFF) << 16)
| (((int64_t) init_b_top & 0x3000) << 32) | (( (int64_t) init_b_bot & 0x3000) << 34);
*srval_a = ((int64_t) srval_a_top & 0xFFFF) | (((int64_t) srval_a_bot & 0xFFFF) << 16)
| (((int64_t) srval_a_top & 0x3000) << 32) | (( (int64_t) srval_a_bot & 0x3000) << 34);
*srval_b = ((int64_t) srval_b_top & 0xFFFF) | (((int64_t) srval_b_bot & 0xFFFF) << 16)
| (((int64_t) srval_b_top & 0x3000) << 32) | (( (int64_t) srval_b_bot & 0x3000) << 34);
}
static int extract_bram(struct extract_state *es)
{
RC_CHECK(es->model);
/*
typedef struct _bram_init // only first half of array used for bram8
{
int data[64][16];
int parity[8][16];
} bram_init_t;
void bram_extract_init(bram_init_t *init, const uint8_t *bits);
for (row = 3; row >= 0; row--) {
for (i = XC6_BRAM16_DEVS_PER_ROW-1; i >= 0; i--) {
printf_ramb_data(&cfg->bits.d[BRAM_DATA_START
+ (row*XC6_BRAM16_DEVS_PER_ROW+i)
*XC6_BRAM_DATA_FRAMES_PER_DEV*FRAME_SIZE],
row, i);
}
}
*/
// todo
RC_RETURN(es->model);
}
static int write_bram(struct fpga_bits *bits, struct fpga_model *model)
{
RC_CHECK(model);
// todo
RC_RETURN(model);
}
int extract_model(struct fpga_model* model, struct fpga_bits* bits)
{
struct extract_state es;
@ -2415,6 +2658,8 @@ int extract_model(struct fpga_model* model, struct fpga_bits* bits)
if (rc) { RC_SET(model, rc); goto out; }
rc = extract_bscan(&es);
if (rc) { RC_SET(model, rc); goto out; }
rc = extract_bram(&es);
if (rc) { RC_SET(model, rc); goto out; }
// turn switches into nets
if (model->nets)
@ -3188,6 +3433,7 @@ int write_model(struct fpga_bits *bits, struct fpga_model *model)
write_type2(bits, model);
write_logic(bits, model);
write_bscan(bits, model);
write_bram(bits, model);
RC_RETURN(model);
}

View File

@ -680,200 +680,12 @@ static int dump_maj_logic(const uint8_t* bits, int row, int major)
return 0;
}
#if 0
typedef struct ramb16_cfg
{
uint8_t byte[64];
} __attribute((packed)) ramb16_cfg_t;
static const cfg_atom_t ramb16_instance =
{
{-1}, {12,13, 274,275,276,277,316,317,318,319,
420,421,422,423,-1}, "default_bits"
};
static cfg_atom_t ramb16_atoms[] =
{
// data_width_a
{{264,265,260,261,256,257,-1},{ -1},"data_width_a 1"},
{{264,265,260,261, -1},{ 256,257,-1},"data_width_a 2"},
{{264,265, 256,257,-1},{ 260,261, -1},"data_width_a 4"},
{{264,265, -1},{ 260,261,256,257,-1},"data_width_a 9"},
{{ 260,261,256,257,-1},{264,265, -1},"data_width_a 18"},
{{ 260,261, -1},{264,265, 256,257,-1},"data_width_a 36"},
{{ -1},{264,265,260,261,256,257,-1},"data_width_a 0"},
// data_width_b
{{262,263,286,287,258,259,-1},{ -1},"data_width_b 1"},
{{262,263,286,287, -1},{ 258,259,-1},"data_width_b 2"},
{{262,263, 258,259,-1},{ 286,287, -1},"data_width_b 4"},
{{262,263, -1},{ 286,287,258,259,-1},"data_width_b 9"},
{{ 286,287,258,259,-1},{262,263, -1},"data_width_b 18"},
{{ 286,287, -1},{262,263, 258,259,-1},"data_width_b 36"},
{{ -1},{262,263,286,287,258,259,-1},"data_width_b 0"},
// required
{ { -1}, {266, 267, -1}, "RST_PRIORITY_B:CE" },
{ {266, 267, -1}, { -1}, "RST_PRIORITY_B:SR" },
{ { -1}, {268, 269, -1}, "RST_PRIORITY_A:CE" },
{ {268, 269, -1}, { -1}, "RST_PRIORITY_A:SR" },
{ { -1}, {290, 291, -1}, "EN_RSTRAM_A:TRUE" },
{ {290, 291, -1}, { -1}, "EN_RSTRAM_A:FALSE" },
{ { -1}, {444, 445, -1}, "EN_RSTRAM_B:TRUE" },
{ {444, 445, -1}, { -1}, "EN_RSTRAM_B:FALSE" },
// optional
{ { -1}, { 26, 27, -1}, "CLKAINV:CLKA" },
{ { 26, 27, -1}, { -1}, "CLKAINV:CLKA_B" }, // def
{ { -1}, { 30, 31, -1}, "CLKBINV:CLKB" },
{ { 30, 31, -1}, { -1}, "CLKBINV:CLKB_B" }, // def
{ { -1}, {270, 271, -1}, "RSTTYPE:ASYNC" },
{ {270, 271, -1}, { -1}, "RSTTYPE:SYNC" }, // def
{ { -1}, {278, 279, -1}, "WRITE_MODE_B:READ_FIRST" },
{ { -1}, {280, 281, -1}, "WRITE_MODE_A:READ_FIRST" },
{ { -1}, {282, 283, -1}, "WRITE_MODE_B:NO_CHANGE" },
{ { -1}, {284, 285, -1}, "WRITE_MODE_A:NO_CHANGE" },
{ {278, 279, 282, 283, -1}, {-1}, "WRITE_MODE_B:WRITE_FIRST" }, //def
{ {280, 281, 284, 285, -1}, {-1}, "WRITE_MODE_A:WRITE_FIRST" }, //def
{ { -1}, {306, 307, -1}, "DOB_REG:1" },
{ {306, 306, -1}, { -1}, "DOB_REG:0" }, // def
{ { -1}, {308, 309, -1}, "DOA_REG:1" },
{ {308, 309, -1}, { -1}, "DOA_REG:0" }, // def
{ {431, 467, -1}, {430, 466, -1}, "ENAINV:ENA" }, // def
{ {430, 431, 466, 467, -1}, {-1}, "ENAINV:ENA_B" },
{ {465, 469, -1}, {464, 468, -1}, "ENBINV:ENB" }, // def
{ {464, 465, 468, 469, -1}, {-1}, "ENBINV:ENB_B" },
{ { -1}, { 20, 21, -1}, "REGCEAINV:REGCEA" }, // def
{ { 20, 21, -1}, { -1}, "REGCEAINV:REGCEA_B" },
{ { -1}, { 8, 9, -1}, "REGCEBINV:REGCEB" },
{ { 8, 9, -1}, { -1}, "REGCEBINV:REGCEB_B" }, // def
{ { 24, 25, -1}, { -1}, "RSTAINV:RSTA" }, // def
{ { -1}, { 24, 25, -1}, "RSTAINV:RSTA_B" },
{ { -1}, { 4, 5, -1}, "RSTBINV:RSTB" }, // def
{ { 4, 5, -1}, { -1}, "RSTBINV:RSTB_B" },
{ { -1}, { 19, -1}, "WEA0INV:WEA0" }, // def
{ { 19, -1}, { -1}, "WEA0INV:WEA0_B" },
{ { -1}, { 23, -1}, "WEA2INV:WEA1" }, // def
{ { 23, -1}, { -1}, "WEA2INV:WEA1_B" },
{ { -1}, { 18, -1}, "WEA2INV:WEA2" }, // def
{ { 18, -1}, { -1}, "WEA2INV:WEA2_B" },
{ { -1}, { 22, -1}, "WEA2INV:WEA3" }, // def
{ { 22, -1}, { -1}, "WEA2INV:WEA3_B" },
{ { -1}, { 7, -1}, "WEB0INV:WEB0" }, // def
{ { 7, -1}, { -1}, "WEB0INV:WEB0_B" },
{ { -1}, { 3, -1}, "WEB1INV:WEB1" }, // def
{ { 3, -1}, { -1}, "WEB1INV:WEB1_B" },
{ { -1}, { 6, -1}, "WEB2INV:WEB2" }, // def
{ { 6, -1}, { -1}, "WEB2INV:WEB2_B" },
{ { -1}, { 2, -1}, "WEB3INV:WEB3" }, // def
{ { 2, -1}, { -1}, "WEB3INV:WEB3_B" },
};
static void print_ramb16_cfg(ramb16_cfg_t* cfg)
{
char bits[512];
uint8_t u8;
int i, first_extra;
for (i = 0; i < 32; i++) {
u8 = cfg->byte[i*2];
cfg->byte[i*2] = cfg->byte[i*2+1];
cfg->byte[i*2+1] = u8;
}
for (i = 0; i < 64; i++) {
u8 = 0;
if (cfg->byte[i] & 0x01) u8 |= 0x80;
if (cfg->byte[i] & 0x02) u8 |= 0x40;
if (cfg->byte[i] & 0x04) u8 |= 0x20;
if (cfg->byte[i] & 0x08) u8 |= 0x10;
if (cfg->byte[i] & 0x10) u8 |= 0x08;
if (cfg->byte[i] & 0x20) u8 |= 0x04;
if (cfg->byte[i] & 0x40) u8 |= 0x02;
if (cfg->byte[i] & 0x80) u8 |= 0x01;
cfg->byte[i] = u8;
}
//
// Bits 0..255 come from minor 23, Bits 256..511 from minor 24.
// Each set of 256 bits is divided into two halfs of 128 bits
// that are swept forward and backward to form 2-bit pairs,
// pairs 0..127 are formed out of bits 0..127 and 255..128,
// p128..p255 are formed out of b256..b383 and b511..b384.
// Since so much bit twiddling is already happening, we are sorting
// the bits so that pairs are next to each other.
// The notation for a pair is "p8=01".
// minor 23
for (i = 0; i < 128; i++) {
bits[i*2] = (cfg->byte[i/8] & (1<<(i%8))) != 0;
bits[i*2+1] = (cfg->byte[(255-i)/8]
& (1<<(7-(i%8)))) != 0;
}
// minor 24
for (i = 0; i < 128; i++) {
bits[256+i*2] = (cfg->byte[32+i/8] & (1<<(i%8))) != 0;
bits[256+i*2+1] = (cfg->byte[32+(255-i)/8]
& (1<<(7-(i%8)))) != 0;
}
printf("{\n");
// hexdump(1 /* indent */, &cfg->byte[0], 64 /* len */);
for (i = 0; i < sizeof(ramb16_atoms)/sizeof(ramb16_atoms[0]); i++) {
if (atom_found(bits, &ramb16_atoms[i])
&& ramb16_atoms[i].must_1[0] != -1) {
printf(" %s\n", ramb16_atoms[i].str);
ramb16_atoms[i].flag = 1;
} else
ramb16_atoms[i].flag = 0;
}
for (i = 0; i < sizeof(ramb16_atoms)/sizeof(ramb16_atoms[0]); i++) {
if (ramb16_atoms[i].flag)
atom_remove(bits, &ramb16_atoms[i]);
}
// instantiation bits
if (ramb16_instance.must_1[0] != -1) {
if (atom_found(bits, &ramb16_instance)) {
for (i = 0; ramb16_instance.must_1[i] != -1; i++)
printf(" b%i\n", ramb16_instance.must_1[i]);
atom_remove(bits, &ramb16_instance);
} else
printf(" #W Not all instantiation bits set.\n");
}
// extra bits
first_extra = 1;
for (i = 0; i < 512; i++) {
if (bits[i]) {
if (first_extra) {
printf(" #W Extra bits set.\n");
first_extra = 0;
}
printf(" b%i\n", i);
}
}
printf("}\n");
}
#endif
static void printf_minor_diff(int row, int major, int minor,
const uint8_t *old_minor_bits, const uint8_t *new_minor_bits)
{
int word_i, w_old, w_new;
char v16_str[32];
// print words as pins (fpga bit ordering)
for (word_i = 0; word_i < FRAME_SIZE/XC6_WORD_BYTES; word_i++) {
if (word_i == XC6_HCLK_POS/XC6_WORD_BYTES)
sprintf(v16_str, "v16_clk");
else
sprintf(v16_str, "v16_%i",
word_i<XC6_HCLK_POS/XC6_WORD_BYTES ? word_i : word_i - 1);
w_old = frame_get_pinword(&old_minor_bits[word_i*XC6_WORD_BYTES]);
w_new = frame_get_pinword(&new_minor_bits[word_i*XC6_WORD_BYTES]);
if (w_old == w_new) continue;
printf("#I <r%i ma%i %s mi%i pin %s", row, major, v16_str, minor, fmt_word(w_old));
printf("#I >r%i ma%i %s mi%i pin %s", row, major, v16_str, minor, fmt_word(w_new));
}
// print words as bits (cpu bit ordering)
for (word_i = 0; word_i < FRAME_SIZE/XC6_WORD_BYTES; word_i++) {
if (word_i == XC6_HCLK_POS/XC6_WORD_BYTES)
@ -881,11 +693,11 @@ static void printf_minor_diff(int row, int major, int minor,
else
sprintf(v16_str, "v16_%i",
word_i<XC6_HCLK_POS/XC6_WORD_BYTES ? word_i : word_i - 1);
w_old = frame_get_pinword(&old_minor_bits[word_i*XC6_WORD_BYTES]);
w_new = frame_get_pinword(&new_minor_bits[word_i*XC6_WORD_BYTES]);
w_old = frame_get_cpuword(&old_minor_bits[word_i*XC6_WORD_BYTES]);
w_new = frame_get_cpuword(&new_minor_bits[word_i*XC6_WORD_BYTES]);
if (w_old == w_new) continue;
printf("#I <r%i ma%i %s mi%i cpu %s", row, major, v16_str, minor, fmt_word(pinword_to_cpu(w_old)));
printf("#I >r%i ma%i %s mi%i cpu %s", row, major, v16_str, minor, fmt_word(pinword_to_cpu(w_new)));
printf("#I <r%i ma%i %s mi%i %s", row, major, v16_str, minor, fmt_word(w_old));
printf("#I >r%i ma%i %s mi%i %s", row, major, v16_str, minor, fmt_word(w_new));
}
}
@ -895,20 +707,6 @@ static void printf_minors(int row, int major, int minor, int num_minors,
int word_i, minor_i, w;
char v16_str[32];
// print words as pins (fpga bit ordering)
for (word_i = 0; word_i < FRAME_SIZE/XC6_WORD_BYTES; word_i++) {
if (word_i == XC6_HCLK_POS/XC6_WORD_BYTES)
sprintf(v16_str, "v16_clk");
else
sprintf(v16_str, "v16_%i",
word_i<XC6_HCLK_POS/XC6_WORD_BYTES ? word_i : word_i - 1);
for (minor_i = minor; minor_i < minor + num_minors; minor_i++) {
w = frame_get_pinword(&major_bits[minor_i*FRAME_SIZE
+ word_i*XC6_WORD_BYTES]);
if (!w) continue;
printf("r%i ma%i %s mi%i pin %s", row, major, v16_str, minor_i, fmt_word(w));
}
}
// print words as bits (cpu bit ordering)
for (word_i = 0; word_i < FRAME_SIZE/XC6_WORD_BYTES; word_i++) {
if (word_i == XC6_HCLK_POS/XC6_WORD_BYTES)
@ -917,18 +715,16 @@ static void printf_minors(int row, int major, int minor, int num_minors,
sprintf(v16_str, "v16_%i",
word_i<XC6_HCLK_POS/XC6_WORD_BYTES ? word_i : word_i - 1);
for (minor_i = minor; minor_i < minor + num_minors; minor_i++) {
w = frame_get_pinword(&major_bits[minor_i*FRAME_SIZE
w = frame_get_cpuword(&major_bits[minor_i*FRAME_SIZE
+ word_i*XC6_WORD_BYTES]);
if (!w) continue;
printf("r%i ma%i %s mi%i cpu %s", row, major, v16_str, minor_i, fmt_word(pinword_to_cpu(w)));
printf("r%i ma%i %s mi%i %s", row, major, v16_str, minor_i, fmt_word(w));
}
}
}
static int dump_maj_bram(const uint8_t *bits, int row, int major)
{
// ramb16_cfg_t ramb16_cfg[4];
// int j, offset_in_frame;
int minor, i;
for (minor = 0; minor < get_major_minors(XC6SLX9, major); minor++)
@ -942,35 +738,6 @@ static int dump_maj_bram(const uint8_t *bits, int row, int major)
printf_v64_mi20(&bits[20*FRAME_SIZE], row, major);
printf_minors(row, major, /*minor*/ 21, /*num_minors*/ 4, bits);
#if 0
printf_frames(&bits[21*FRAME_SIZE], /*max_frames*/ 1,
row, major, 21, /*print_empty*/ 0, /*no_clock*/ 1);
printf_frames(&bits[22*FRAME_SIZE], /*max_frames*/ 1,
row, major, 22, /*print_empty*/ 0, /*no_clock*/ 1);
// minors 23&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] = bits[23*130+offset_in_frame+j];
ramb16_cfg[i].byte[j+32] = bits[24*130+offset_in_frame+j];
}
}
for (i = 0; i < 4; i++) {
for (j = 0; j < 64; j++) {
if (ramb16_cfg[i].byte[j])
break;
}
if (j >= 64)
continue;
printf("r%i ma%i ramb16 i%i\n",
row, major, i);
print_ramb16_cfg(&ramb16_cfg[i]);
}
#endif
return 0;
}

View File

@ -2319,19 +2319,20 @@ static void fprintf_inout_pin(FILE* f, struct fpga_model* model,
fprintf(f, "%s", buf);
}
void fnet_printf(FILE* f, struct fpga_model* model, net_idx_t net_i)
void fnet_printf(FILE* f, struct fpga_model* model, net_idx_t net_i, int no_json)
{
struct fpga_net* net;
int i, first_line;
net = fnet_get(model, net_i);
if (!net) { HERE(); return; }
fprintf(f, "[\n");
if (!no_json) fprintf(f, "[\n");
first_line = 1;
for (i = 0; i < net->len; i++) {
if (!first_line)
fprintf(f, ",\n");
first_line = 0;
if (no_json) fprintf(f, "net_i %i:", net_i);
if (net->el[i].idx & NET_IDX_IS_PINW) {
fprintf_inout_pin(f, model, net_i, &net->el[i]);
continue;
@ -2342,7 +2343,8 @@ void fnet_printf(FILE* f, struct fpga_model* model, net_idx_t net_i)
fpga_switch_print_json(model, net->el[i].y,
net->el[i].x, net->el[i].idx));
}
fprintf(f, "\n ]");
fprintf(f, "\n");
if (!no_json) fprintf(f, " ]");
}
//

View File

@ -410,7 +410,7 @@ int fnet_add_sw(struct fpga_model* model, net_idx_t net_i,
int fnet_remove_sw(struct fpga_model* model, net_idx_t net_i,
int y, int x, const swidx_t* switches, int num_sw);
int fnet_remove_all_sw(struct fpga_model* model, net_idx_t net_i);
void fnet_printf(FILE* f, struct fpga_model* model, net_idx_t net_i);
void fnet_printf(FILE* f, struct fpga_model* model, net_idx_t net_i, int no_json);
int fnet_route(struct fpga_model* model, net_idx_t net_i);
// is_vcc == 1 for a vcc net, is_vcc == 0 for a gnd net

View File

@ -11,8 +11,8 @@
#include "control.h"
#include "floorplan.h"
#define PRINT_FLAG(fp, flag) if ((tf) & (flag)) \
{ fprintf (fp, " %s", #flag); tf &= ~(flag); }
#define PRINT_FLAG(fp, flag, firstp) if ((tf) & (flag)) \
{ fprintf (fp, "%s\"%s\"", firstp ? "" : ", ", #flag); tf &= ~(flag); firstp = 0; }
void printf_version(FILE* f)
{
@ -22,43 +22,53 @@ void printf_version(FILE* f)
int printf_tiles(FILE* f, struct fpga_model* model)
{
struct fpga_tile* tile;
int x, y;
int x, y, first_line;
RC_CHECK(model);
fprintf(f, " \"tiles\" : [\n");
for (x = 0; x < model->x_width; x++) {
fprintf(f, "\n");
if (x) fprintf(f, ",\n\n");
first_line = 1;
for (y = 0; y < model->y_height; y++) {
tile = &model->tiles[y*model->x_width + x];
if (tile->type != NA)
fprintf(f, "tile y%i x%i name %s\n", y, x,
if (tile->type != NA) {
fprintf(f, "%s { \"y\" : %i, \"x\" : %i, \"name\" : \"%s\" }",
first_line ? "" : ",\n", y, x,
fpga_tiletype_str(tile->type));
first_line = 0;
}
if (tile->flags) {
int tf = tile->flags;
fprintf(f, "tile y%i x%i flags", y, x);
int tf = tile->flags, first_flag = 1;
PRINT_FLAG(f, TF_FABRIC_ROUTING_COL);
PRINT_FLAG(f, TF_FABRIC_LOGIC_XM_COL);
PRINT_FLAG(f, TF_FABRIC_LOGIC_XL_COL);
PRINT_FLAG(f, TF_FABRIC_BRAM_VIA_COL);
PRINT_FLAG(f, TF_FABRIC_MACC_VIA_COL);
PRINT_FLAG(f, TF_FABRIC_BRAM_COL);
PRINT_FLAG(f, TF_FABRIC_MACC_COL);
PRINT_FLAG(f, TF_ROUTING_NO_IO);
PRINT_FLAG(f, TF_BRAM_DEV);
PRINT_FLAG(f, TF_MACC_DEV);
PRINT_FLAG(f, TF_LOGIC_XL_DEV);
PRINT_FLAG(f, TF_LOGIC_XM_DEV);
PRINT_FLAG(f, TF_IOLOGIC_DELAY_DEV);
PRINT_FLAG(f, TF_DCM_DEV);
PRINT_FLAG(f, TF_PLL_DEV);
PRINT_FLAG(f, TF_WIRED);
fprintf(f, "%s { \"y\" : %i, \"x\" : %i, \"flags\" : [ ",
first_line ? "" : ",\n", y, x);
first_line = 0;
if (tf) fprintf(f, " 0x%x", tf);
fprintf(f, "\n");
PRINT_FLAG(f, TF_FABRIC_ROUTING_COL, first_flag);
PRINT_FLAG(f, TF_FABRIC_LOGIC_XM_COL, first_flag);
PRINT_FLAG(f, TF_FABRIC_LOGIC_XL_COL, first_flag);
PRINT_FLAG(f, TF_FABRIC_BRAM_VIA_COL, first_flag);
PRINT_FLAG(f, TF_FABRIC_MACC_VIA_COL, first_flag);
PRINT_FLAG(f, TF_FABRIC_BRAM_COL, first_flag);
PRINT_FLAG(f, TF_FABRIC_MACC_COL, first_flag);
PRINT_FLAG(f, TF_ROUTING_NO_IO, first_flag);
PRINT_FLAG(f, TF_BRAM_DEV, first_flag);
PRINT_FLAG(f, TF_MACC_DEV, first_flag);
PRINT_FLAG(f, TF_LOGIC_XL_DEV, first_flag);
PRINT_FLAG(f, TF_LOGIC_XM_DEV, first_flag);
PRINT_FLAG(f, TF_IOLOGIC_DELAY_DEV, first_flag);
PRINT_FLAG(f, TF_DCM_DEV, first_flag);
PRINT_FLAG(f, TF_PLL_DEV, first_flag);
PRINT_FLAG(f, TF_WIRED, first_flag);
PRINT_FLAG(f, TF_CENTER_MIDBUF, first_flag);
if (tf) fprintf(f, "%s\"0x%x\"", first_flag ? "" : ", ", tf);
fprintf(f, " ] }");
}
}
}
fprintf(f, "\n ]");
return 0;
}
@ -907,42 +917,51 @@ int printf_BUFGMUX(FILE *f, struct fpga_model *model,
struct fpga_tile *tile;
struct fpgadev_bufgmux *cfg;
char pref[256];
int dev_i;
int dev_i, first_line;
dev_i = fpga_dev_idx(model, y, x, DEV_BUFGMUX, type_idx);
RC_ASSERT(model, dev_i != NO_DEV);
tile = YX_TILE(model, y, x);
if (config_only && !(tile->devs[dev_i].instantiated))
RC_RETURN(model);
snprintf(pref, sizeof(pref), "dev y%i x%i BUFGMUX %i", y, x, type_idx);
snprintf(pref, sizeof(pref), " { \"y\" : %i, \"x\" : %i, \"dev\" : \"BUFGMUX\", \"dev_idx\" : %i", y, x, type_idx);
first_line = 1;
if (!config_only)
fprintf(f, "%s\n", pref);
if (!config_only) {
fprintf(f, "%s }", pref);
first_line = 0;
}
cfg = &tile->devs[dev_i].u.bufgmux;
switch (cfg->clk) {
case BUFG_CLK_ASYNC:
fprintf(f, "%s clk ASYNC\n", pref);
fprintf(f, "%s%s, \"clk\" : \"ASYNC\" }", first_line ? "" : ",\n", pref);
first_line = 0;
break;
case BUFG_CLK_SYNC:
fprintf(f, "%s clk SYNC\n", pref);
fprintf(f, "%s%s, \"clk\" : \"SYNC\" }", first_line ? "" : ",\n", pref);
first_line = 0;
break;
case 0: break; default: RC_FAIL(model, EINVAL);
}
switch (cfg->disable_attr) {
case BUFG_DISATTR_LOW:
fprintf(f, "%s disable_attr LOW\n", pref);
fprintf(f, "%s%s, \"disable_attr\" : \"LOW\" }", first_line ? "" : ",\n", pref);
first_line = 0;
break;
case BUFG_DISATTR_HIGH:
fprintf(f, "%s disable_attr HIGH\n", pref);
fprintf(f, "%s%s, \"disable_attr\" : \"HIGH\" }", first_line ? "" : ",\n", pref);
first_line = 0;
break;
case 0: break; default: RC_FAIL(model, EINVAL);
}
switch (cfg->s_inv) {
case BUFG_SINV_N:
fprintf(f, "%s s_inv NO\n", pref);
fprintf(f, "%s%s, \"s_inv\" : false }", first_line ? "" : ",\n", pref);
first_line = 0;
break;
case BUFG_SINV_Y:
fprintf(f, "%s s_inv YES\n", pref);
fprintf(f, "%s%s, \"s_inv\" : true }", first_line ? "" : ",\n", pref);
first_line = 0;
break;
case 0: break; default: RC_FAIL(model, EINVAL);
}
@ -990,35 +1009,44 @@ int printf_BUFIO(FILE *f, struct fpga_model *model,
struct fpga_tile *tile;
struct fpgadev_bufio *cfg;
char pref[256];
int dev_i;
int dev_i, first_line;
dev_i = fpga_dev_idx(model, y, x, DEV_BUFIO, type_idx);
RC_ASSERT(model, dev_i != NO_DEV);
tile = YX_TILE(model, y, x);
if (config_only && !(tile->devs[dev_i].instantiated))
RC_RETURN(model);
snprintf(pref, sizeof(pref), "dev y%i x%i BUFIO %i", y, x, type_idx);
snprintf(pref, sizeof(pref), " { \"y\" : %i, \"x\" : %i, \"dev\" : \"BUFIO\", \"dev_idx\" : %i", y, x, type_idx);
first_line = 1;
if (!config_only)
fprintf(f, "%s\n", pref);
if (!config_only) {
fprintf(f, "%s }", pref);
first_line = 0;
}
cfg = &tile->devs[dev_i].u.bufio;
if (cfg->divide)
fprintf(f, "%s divide %i\n", pref, cfg->divide);
if (cfg->divide) {
fprintf(f, "%s%s, \"divide\" : %i\n", first_line ? "" : ",\n", pref, cfg->divide);
first_line = 0;
}
switch (cfg->divide_bypass) {
case BUFIO_DIVIDEBP_N:
fprintf(f, "%s divide_bypass NO\n", pref);
fprintf(f, "%s%s, \"divide_bypass\" : false }", first_line ? "" : ",\n", pref);
first_line = 0;
break;
case BUFIO_DIVIDEBP_Y:
fprintf(f, "%s divide_bypass YES\n", pref);
fprintf(f, "%s%s, \"divide_bypass\" : true }", first_line ? "" : ",\n", pref);
first_line = 0;
break;
case 0: break; default: RC_FAIL(model, EINVAL);
}
switch (cfg->i_inv) {
case BUFIO_IINV_N:
fprintf(f, "%s i_inv NO\n", pref);
fprintf(f, "%s%s, \"i_inv\" : false }", first_line ? "" : ",\n", pref);
first_line = 0;
break;
case BUFIO_IINV_Y:
fprintf(f, "%s i_inv YES\n", pref);
fprintf(f, "%s%s, \"i_inv\" : true }", first_line ? "" : ",\n", pref);
first_line = 0;
break;
case 0: break; default: RC_FAIL(model, EINVAL);
}
@ -1062,26 +1090,33 @@ int printf_BSCAN(FILE *f, struct fpga_model *model,
struct fpga_tile *tile;
struct fpgadev_bscan *cfg;
char pref[256];
int dev_i;
int dev_i, first_line;
dev_i = fpga_dev_idx(model, y, x, DEV_BSCAN, type_idx);
RC_ASSERT(model, dev_i != NO_DEV);
tile = YX_TILE(model, y, x);
if (config_only && !(tile->devs[dev_i].instantiated))
RC_RETURN(model);
snprintf(pref, sizeof(pref), "dev y%i x%i BSCAN %i", y, x, type_idx);
snprintf(pref, sizeof(pref), " { \"y\" : %i, \"x\" : %i, \"dev\" : \"BSCAN\", \"dev_idx\" : %i", y, x, type_idx);
first_line = 1;
if (!config_only)
fprintf(f, "%s\n", pref);
if (!config_only) {
fprintf(f, "%s }", pref);
first_line = 0;
}
cfg = &tile->devs[dev_i].u.bscan;
if (cfg->jtag_chain)
fprintf(f, "%s jtag_chain %i\n", pref, cfg->jtag_chain);
if (cfg->jtag_chain) {
fprintf(f, "%s%s, \"jtag_chain\" : %i }", first_line ? "" : ",\n", pref, cfg->jtag_chain);
first_line = 0;
}
switch (cfg->jtag_test) {
case BSCAN_JTAG_TEST_N:
fprintf(f, "%s jtag_test NO\n", pref);
fprintf(f, "%s%s, \"jtag_test\" : false }", first_line ? "" : ",\n", pref);
first_line = 0;
break;
case BSCAN_JTAG_TEST_Y:
fprintf(f, "%s jtag_test YES\n", pref);
fprintf(f, "%s%s, \"jtag_test\" : true }", first_line ? "" : ",\n", pref);
first_line = 0;
break;
case 0: break; default: RC_FAIL(model, EINVAL);
}
@ -1111,13 +1146,13 @@ inst:
return 2;
}
int printf_devices(FILE* f, struct fpga_model* model, int config_only)
int printf_devices(FILE* f, struct fpga_model* model, int config_only, int no_json)
{
int x, y, i, first_dev;
struct fpga_tile* tile;
RC_CHECK(model);
fprintf(f, " \"devices\" : [\n");
if (!no_json) fprintf(f, " \"devices\" : [\n");
first_dev = 1;
for (x = 0; x < model->x_width; x++) {
for (y = 0; y < model->y_height; y++) {
@ -1163,7 +1198,7 @@ int printf_devices(FILE* f, struct fpga_model* model, int config_only)
}
}
if (!first_dev) fprintf(f, "\n");
fprintf(f, " ]");
if (!no_json) fprintf(f, " ]");
RC_RETURN(model);
}
@ -1172,14 +1207,16 @@ int printf_ports(FILE* f, struct fpga_model* model)
struct fpga_tile* tile;
const char* conn_point_name_src;
int x, y, i, conn_point_dests_o, num_dests_for_this_conn_point;
int first_port_printed;
int first_in_tile, first_tile;
RC_CHECK(model);
fprintf(f, " \"ports\" : [\n");
first_tile = 1;
for (x = 0; x < model->x_width; x++) {
for (y = 0; y < model->y_height; y++) {
tile = &model->tiles[y*model->x_width + x];
first_port_printed = 0;
first_in_tile = 1;
for (i = 0; i < tile->num_conn_point_names; i++) {
conn_point_dests_o = tile->conn_point_names[i*2];
if (i < tile->num_conn_point_names-1)
@ -1195,16 +1232,17 @@ int printf_ports(FILE* f, struct fpga_model* model)
tile->conn_point_names[i*2+1], x, y, i);
continue;
}
if (!first_port_printed) {
first_port_printed = 1;
fprintf(f, "\n");
}
fprintf(f, "port y%i x%i %s\n",
y, x, conn_point_name_src);
if (first_in_tile && !first_tile)
fprintf(f, ",\n\n");
fprintf(f, "%s { \"y\" : %i, \"x\" : %i, \"name\" : \"%s\" }",
first_in_tile ? "" : ",\n", y, x, conn_point_name_src);
first_in_tile = 0;
first_tile = 0;
}
}
}
return 0;
fprintf(f, "\n ]");
RC_RETURN(model);
}
int printf_conns(FILE* f, struct fpga_model* model)
@ -1214,14 +1252,16 @@ int printf_conns(FILE* f, struct fpga_model* model)
const char* conn_point_name_src, *other_tile_connpt_str;
uint16_t other_tile_connpt_str_i;
int x, y, i, j, k, conn_point_dests_o, num_dests_for_this_conn_point;
int other_tile_x, other_tile_y, first_conn_printed;
int other_tile_x, other_tile_y, first_tile, first_in_tile;
RC_CHECK(model);
fprintf(f, " \"connections\" : [\n");
first_tile = 1;
for (x = 0; x < model->x_width; x++) {
for (y = 0; y < model->y_height; y++) {
tile = &model->tiles[y*model->x_width + x];
first_conn_printed = 0;
first_in_tile = 1;
for (i = 0; i < tile->num_conn_point_names; i++) {
conn_point_dests_o = tile->conn_point_names[i*2];
if (i < tile->num_conn_point_names-1)
@ -1248,66 +1288,73 @@ int printf_conns(FILE* f, struct fpga_model* model)
continue;
}
if (!first_conn_printed) {
first_conn_printed = 1;
fprintf(f, "\n");
}
sprintf(tmp_line, "conn y%i x%i %s ",
if (first_in_tile && !first_tile)
fprintf(f, ",\n\n");
sprintf(tmp_line, "\"y1\" : %i, \"x1\" : %i, \"name1\" : \"%s\", ",
y, x, conn_point_name_src);
k = strlen(tmp_line);
while (k < 45)
while (k < 60)
tmp_line[k++] = ' ';
sprintf(&tmp_line[k], "y%i x%i %s\n",
sprintf(&tmp_line[k], "\"y2\" : %i, \"x2\" : %i, \"name2\" : \"%s\"",
other_tile_y, other_tile_x, other_tile_connpt_str);
fprintf(f, "%s", tmp_line);
fprintf(f, "%s { %s }",
first_in_tile ? "" : ",\n", tmp_line);
first_in_tile = 0;
first_tile = 0;
}
}
}
}
return 0;
fprintf(f, "\n ]");
RC_RETURN(model);
}
int printf_switches(FILE *f, struct fpga_model *model)
{
struct fpga_tile *tile;
int x, y, i, first_switch_printed;
int x, y, i, first_in_tile, first_tile;
RC_CHECK(model);
fprintf(f, " \"switches\" : [\n");
first_tile = 1;
for (x = 0; x < model->x_width; x++) {
for (y = 0; y < model->y_height; y++) {
tile = YX_TILE(model, y, x);
first_switch_printed = 0;
first_in_tile = 1;
for (i = 0; i < tile->num_switches; i++) {
if (!first_switch_printed) {
first_switch_printed = 1;
fprintf(f, "\n");
}
fprintf(f, "sw y%i x%i %s\n",
y, x, fpga_switch_print(model, y, x, i));
if (first_in_tile && !first_tile)
fprintf(f, ",\n\n");
fprintf(f, "%s { \"y\" : %i, \"x\" : %i%s }",
first_in_tile ? "" : ",\n", y, x,
fpga_switch_print_json(model, y, x, i));
first_in_tile = 0;
first_tile = 0;
}
}
}
return 0;
fprintf(f, "\n ]");
RC_RETURN(model);
}
int printf_nets(FILE* f, struct fpga_model* model)
int printf_nets(FILE* f, struct fpga_model* model, int no_json)
{
net_idx_t net_i;
int rc, first_line;
RC_CHECK(model);
fprintf(f, " \"nets\" : [\n");
if (!no_json) fprintf(f, " \"nets\" : [\n");
first_line = 1;
net_i = NO_NET;
while (!(rc = fnet_enum(model, net_i, &net_i)) && net_i != NO_NET) {
if (!first_line)
fprintf(f, ",");
if (!no_json) fprintf(f, first_line ? " " : ",");
first_line = 0;
fnet_printf(f, model, net_i);
fnet_printf(f, model, net_i, no_json);
}
if (rc) FAIL(rc);
if (!no_json) {
if (!first_line) fprintf(f, "\n");
fprintf(f, " ]");
}
return 0;
fail:
return rc;
@ -1555,19 +1602,24 @@ int read_floorplan(struct fpga_model* model, FILE* f)
int write_floorplan(FILE* f, struct fpga_model* model, int flags)
{
if (!(flags & FP_NO_JSON)) {
fprintf(f, "{\n");
printf_version(f);
}
if (model->rc)
fprintf(f, "rc %i\n", model->rc);
else {
if (!(flags & FP_NO_JSON))
fprintf(f, ",\n");
printf_devices(f, model, /*config_only*/ 1);
printf_devices(f, model, /*config_only*/ 1, flags & FP_NO_JSON);
if (!(flags & FP_NO_JSON))
fprintf(f, ",\n");
printf_nets(f, model);
printf_nets(f, model, flags & FP_NO_JSON);
}
if (!(flags & FP_NO_JSON))
fprintf(f, "\n}\n");
RC_RETURN(model);
}

View File

@ -7,16 +7,16 @@
int read_floorplan(struct fpga_model *model, FILE *f);
#define FP_DEFAULT 0x0000
#define FP_NO_HEADER 0x0001
#define FP_NO_JSON 0x0001
int write_floorplan(FILE *f, struct fpga_model *model, int flags);
void printf_version(FILE *f);
int printf_tiles(FILE *f, struct fpga_model *model);
int printf_devices(FILE *f, struct fpga_model *model, int config_only);
int printf_devices(FILE *f, struct fpga_model *model, int config_only, int no_json);
int printf_ports(FILE *f, struct fpga_model *model);
int printf_conns(FILE *f, struct fpga_model *model);
int printf_switches(FILE *f, struct fpga_model *model);
int printf_nets(FILE *f, struct fpga_model *model);
int printf_nets(FILE *f, struct fpga_model *model, int no_json);
int printf_IOB(FILE* f, struct fpga_model* model,
int y, int x, int type_idx, int config_only);

View File

@ -79,32 +79,41 @@ void dump_data(int indent, const uint8_t *data, int len, int base)
}
// returns a 16-bit word (0:15) plus 2 bits parity in bits 16 & 17
static int get_ramb_word_with_parity(const void *d, int word_idx)
static int get_ramb_word_with_parity(const void *d, int word_idx, int clear_bits)
{
int w, i, bit_pos;
int w, i, bit_pos, bit_mask;
w = 0;
for (i = 0; i < 16; i++) {
bit_pos = word_idx * 18 + 2 + 15-i;
if (((uint8_t *)d)[bit_pos/8] & (1<<((7-(bit_pos%8)))))
bit_mask = 1<<((7-(bit_pos%8)));
if (((uint8_t *)d)[bit_pos/8] & bit_mask)
w |= 1<<i;
if (clear_bits)
((uint8_t *)d)[bit_pos/8] &= ~bit_mask;
}
// parity bit 0 (pos +1)
if (((uint8_t *)d)[(word_idx*18+1)/8] & (1<<(7-((word_idx*18+1)%8))))
bit_mask = 1<<(7-((word_idx*18+1)%8));
if (((uint8_t *)d)[(word_idx*18+1)/8] & bit_mask)
w |= 1<<16;
if (clear_bits)
((uint8_t *)d)[(word_idx*18+1)/8] &= ~bit_mask;
// parity bit 1 (pos +0)
if (((uint8_t *)d)[(word_idx*18+0)/8] & (1<<(7-((word_idx*18+0)%8))))
bit_mask = 1<<(7-((word_idx*18+0)%8));
if (((uint8_t *)d)[(word_idx*18+0)/8] & bit_mask)
w |= 1<<17;
if (clear_bits)
((uint8_t *)d)[(word_idx*18+0)/8] &= ~bit_mask;
return w;
}
// src points to 16+2 (=18) bit words, dest must hold enough space
// for num_words words.
static void ramb_data_to_words(int *dest, const void *src, int num_words)
static void ramb_data_to_words(int *dest, const void *src, int num_words, int clear_bits)
{
int i;
for (i = 0; i < num_words; i++)
dest[i] = get_ramb_word_with_parity(src, i);
dest[i] = get_ramb_word_with_parity(src, i, clear_bits);
}
uint16_t __swab16(uint16_t x)
@ -121,29 +130,6 @@ uint32_t __swab32(uint32_t x)
((x & 0xff000000UL) >> 24)); \
}
int atom_found(char *bits, const cfg_atom_t *atom)
{
int i;
for (i = 0; atom->must_0[i] != -1; i++)
if (bits[atom->must_0[i]])
break;
if (atom->must_0[i] != -1)
return 0;
for (i = 0; atom->must_1[i] != -1; i++)
if (!bits[atom->must_1[i]])
break;
return atom->must_1[i] == -1;
}
void atom_remove(char *bits, const cfg_atom_t *atom)
{
int i;
for (i = 0; atom->must_1[i] != -1; i++) {
if (bits[atom->must_1[i]])
bits[atom->must_1[i]] = 0;
}
}
static int bool_nextlen(const char *expr, int len)
{
int i, depth;
@ -471,53 +457,14 @@ void printf_type2(uint8_t *d, int len, int inpos, int num_entries)
}
}
static int ramb_words_to_bram16(int (*init_data)[64][16], int (*init_parity)[8][16], int (*ramb_words)[1024])
static void ramb_words_split_data_parity(const int (*ramb_words)[1024],
int (*init_data)[64][16], int (*init_parity)[8][16])
{
int init_i, i, j, bits_set;
int init_i, i, j;
bits_set = 0;
// prepare parity words for string printf
// merge parity bits into parity words
for (init_i = 0; init_i < 8; init_i++) {
for (i = 0; i < 16; i++) { // 16 uint16_t words in one ramb16 parity string
(*init_parity)[init_i][i] = 0;
// 2 parity bits from each word, so 2*4=8 words have
// to be processed for 16 parity bits
for (j = 0; j < 4; j++) {
if ((*ramb_words)[64*init_i + 4*i + j] & (1<<16))
(*init_parity)[init_i][i] |= 1<<(j*4+0);
if ((*ramb_words)[64*init_i + 4*i + j] & (1<<17))
(*init_parity)[init_i][i] |= 1<<(j*4+1);
if ((*ramb_words)[512 + 64*init_i + 4*i + j] & (1<<16))
(*init_parity)[init_i][i] |= 1<<(j*4+2);
if ((*ramb_words)[512 + 64*init_i + 4*i + j] & (1<<17))
(*init_parity)[init_i][i] |= 1<<(j*4+3);
}
if ((*init_parity)[init_i][i])
bits_set = 1;
}
}
// prepare data words for string printf
for (init_i = 0; init_i < 64; init_i++) {
for (i = 0; i < 8; i++) {
(*init_data)[init_i][i*2] = (*ramb_words)[init_i*8 + i] & 0xFFFF;
(*init_data)[init_i][i*2+1] = (*ramb_words)[512 + init_i*8 + i] & 0xFFFF;
if ((*init_data)[init_i][i*2]
|| (*init_data)[init_i][i*2+1])
bits_set = 1;
}
}
return bits_set;
}
static int ramb_words_to_bram8(int (*init_data)[64][16], int (*init_parity)[8][16], int (*ramb_words)[1024])
{
int init_i, i, j, devs_used;
devs_used = 0; // bit1 = dev0, bit2 = dev1
// prepare parity words (0:3 are for the first bram8 device, 4:7 for the second one)
for (init_i = 0; init_i < 8; init_i++) {
for (i = 0; i < 16; i++) { // 16 uint16_t words in one ramb16 parity string
for (i = 0; i < 16; i++) {
(*init_parity)[init_i][i] = 0;
// 2 parity bits from each word, so 2*4=8 words have
// to be processed for 16 parity bits
@ -527,26 +474,21 @@ static int ramb_words_to_bram8(int (*init_data)[64][16], int (*init_parity)[8][1
if ((*ramb_words)[128*init_i + 8*i + j] & (1<<17))
(*init_parity)[init_i][i] |= 1<<(j*2+1);
}
if ((*init_parity)[init_i][i])
devs_used |= (init_i < 4) ? 0x01 : 0x02;
}
}
// prepare data words (0:31 are for the first bram8 device, 32:63 for the second one)
// mask out parity bits
for (init_i = 0; init_i < 64; init_i++) {
for (i = 0; i < 16; i++) {
(*init_data)[init_i][i] = (*ramb_words)[init_i*16 + i] & 0xFFFF;
if ((*init_data)[init_i][i])
devs_used |= (init_i < 32) ? 0x01 : 0x02;
}
}
return devs_used;
}
void printf_ramb_data(const uint8_t *bits, int row, int bram_idx)
{
int nonzero_head, nonzero_tail, ramb_words[1024];
int init_data[64][16], init_parity[8][16];
int i, j, devs_used;
int i, j, header_printed;
// check head and tail
nonzero_head = 0;
@ -579,102 +521,123 @@ void printf_ramb_data(const uint8_t *bits, int row, int bram_idx)
}
}
ramb_data_to_words(ramb_words, &bits[18], sizeof(ramb_words)/sizeof(*ramb_words));
ramb_data_to_words(ramb_words, &bits[XC6_BRAM_DATA_PREFIX_LEN],
sizeof(ramb_words)/sizeof(*ramb_words), /*clear_bits*/ 0);
ramb_words_split_data_parity(&ramb_words, &init_data, &init_parity);
// ramb16
devs_used = ramb_words_to_bram16(&init_data, &init_parity, &ramb_words);
if (devs_used) {
printf("br%i maj_i %i dev_i %i/16\n", row,
bram_idx/XC6_BRAM16_DEVS_PER_MAJOR,
bram_idx%XC6_BRAM16_DEVS_PER_MAJOR);
printf("{\n");
header_printed = 0;
for (i = 0; i < 8; i++) {
for (j = 0; j < 16; j++) {
if (init_parity[i][j]) {
if (!init_parity[i][j]) continue;
if (!header_printed) {
header_printed = 1;
printf("br%i maj_i %i dev_i %i/16\n{\n", row,
bram_idx/XC6_BRAM16_DEVS_PER_MAJOR,
bram_idx%XC6_BRAM16_DEVS_PER_MAJOR);
}
printf(" parity 0x%02X \"", i);
for (j = 0; j < 16; j++)
printf("%04X", init_parity[i][15-j]);
printf("\"\n");
break;
}
}
}
for (i = 0; i < 64; i++) {
for (j = 0; j < 16; j++) {
if (init_data[i][j]) {
if (!init_data[i][j]) continue;
if (!header_printed) {
header_printed = 1;
printf("br%i maj_i %i dev_i %i/16\n{\n", row,
bram_idx/XC6_BRAM16_DEVS_PER_MAJOR,
bram_idx%XC6_BRAM16_DEVS_PER_MAJOR);
}
printf(" init 0x%02X \"", i);
for (j = 0; j < 16; j++)
printf("%04X", init_data[i][15-j]);
printf("\"\n");
break;
}
}
}
if (header_printed)
printf("}\n");
}
devs_used = ramb_words_to_bram8(&init_data, &init_parity, &ramb_words);
// ramb8,0
if (devs_used & 0x01) {
printf("br%i maj_i %i dev_i %i,0/8\n", row,
bram_idx/XC6_BRAM16_DEVS_PER_MAJOR,
bram_idx%XC6_BRAM16_DEVS_PER_MAJOR);
printf("{\n");
header_printed = 0;
for (i = 0; i < 4; i++) {
for (j = 0; j < 16; j++) {
if (init_parity[i][j]) {
if (!init_parity[i][j]) continue;
if (!header_printed) {
header_printed = 1;
printf("br%i maj_i %i dev_i %i,0/8\n{\n", row,
bram_idx/XC6_BRAM16_DEVS_PER_MAJOR,
bram_idx%XC6_BRAM16_DEVS_PER_MAJOR);
}
printf(" parity 0x%02X \"", i);
for (j = 0; j < 16; j++)
printf("%04X", init_parity[i][15-j]);
printf("\"\n");
break;
}
}
}
for (i = 0; i < 32; i++) {
for (j = 0; j < 16; j++) {
if (init_data[i][j]) {
if (!init_data[i][j]) continue;
if (!header_printed) {
header_printed = 1;
printf("br%i maj_i %i dev_i %i,0/8\n{\n", row,
bram_idx/XC6_BRAM16_DEVS_PER_MAJOR,
bram_idx%XC6_BRAM16_DEVS_PER_MAJOR);
}
printf(" init 0x%02X \"", i);
for (j = 0; j < 16; j++)
printf("%04X", init_data[i][15-j]);
printf("\"\n");
break;
}
}
}
if (header_printed)
printf("}\n");
}
// ramb8,1
if (devs_used & 0x02) {
printf("br%i maj_i %i dev_i %i,1/8\n", row,
bram_idx/XC6_BRAM16_DEVS_PER_MAJOR,
bram_idx%XC6_BRAM16_DEVS_PER_MAJOR);
printf("{\n");
header_printed = 0;
for (i = 4; i < 8; i++) {
for (j = 0; j < 16; j++) {
if (init_parity[i][j]) {
if (!init_parity[i][j]) continue;
if (!header_printed) {
header_printed = 1;
printf("br%i maj_i %i dev_i %i,1/8\n{\n", row,
bram_idx/XC6_BRAM16_DEVS_PER_MAJOR,
bram_idx%XC6_BRAM16_DEVS_PER_MAJOR);
}
printf(" parity 0x%02X \"", i-4);
for (j = 0; j < 16; j++)
printf("%04X", init_parity[i][15-j]);
printf("\"\n");
break;
}
}
}
for (i = 32; i < 64; i++) {
for (j = 0; j < 16; j++) {
if (init_data[i][j]) {
if (!init_data[i][j]) continue;
if (!header_printed) {
header_printed = 1;
printf("br%i maj_i %i dev_i %i,1/8\n{\n", row,
bram_idx/XC6_BRAM16_DEVS_PER_MAJOR,
bram_idx%XC6_BRAM16_DEVS_PER_MAJOR);
}
printf(" init 0x%02X \"", i-32);
for (j = 0; j < 16; j++)
printf("%04X", init_data[i][15-j]);
printf("\"\n");
break;
}
}
}
if (header_printed)
printf("}\n");
}
void bram_extract_init(bram_init_t *init, const uint8_t *bits)
{
int ramb_words[1024];
ramb_data_to_words(ramb_words, &bits[XC6_BRAM_DATA_PREFIX_LEN],
sizeof(ramb_words)/sizeof(*ramb_words), /*clear_bits*/ 1);
ramb_words_split_data_parity(&ramb_words, &init->data, &init->parity);
}
int is_empty(const uint8_t *d, int l)
@ -718,6 +681,16 @@ void frame_set_bit(uint8_t *frame_d, int bit)
frame_d[(bit/16)*2 + !((bit/8)%2)] |= v;
}
int frame_get_cpuword(const void *bits)
{
return mirror_2bytes(frame_get_pinword(bits));
}
void frame_set_cpuword(void *bits, int v)
{
frame_set_pinword(bits, mirror_2bytes(v));
}
// see ug380, table 2-5, bit ordering
int frame_get_pinword(const void *bits)
{
@ -742,9 +715,9 @@ uint8_t mirror_bits(uint8_t v)
return mv;
}
int pinword_to_cpu(int pinword)
int mirror_2bytes(int v)
{
return mirror_bits(((pinword & 0xFF00) >> 8)) << 8 | mirror_bits(pinword & 0xFF);
return mirror_bits(((v & 0xFF00) >> 8)) << 8 | mirror_bits(v & 0xFF);
}
// see ug380, table 2-5, bit ordering
@ -1025,7 +998,7 @@ const char *fmt_word(int word)
static char buf[NUM_BUFS][BUF_SIZE];
static int last_buf = 0;
char bit_str[XC6_WORD_BITS];
int i, num_bits_printed;
int i;
last_buf = (last_buf+1)%NUM_BUFS;
@ -1033,16 +1006,11 @@ const char *fmt_word(int word)
bit_str[i] = (word & (1ULL << (XC6_WORD_BITS-i-1))) ? '1' : '0';
snprintf(buf[last_buf], sizeof(*buf), "0b%.*s 0x%.*X", XC6_WORD_BITS, bit_str, XC6_WORD_BITS/4, word);
num_bits_printed = 0;
for (i = 0; i < XC6_WORD_BITS; i++) {
if (word & (1 << i)) {
if (num_bits_printed >= 4) {
sprintf(&buf[last_buf][strlen(buf[last_buf])], " ...");
break;
}
if (word & (1 << i))
sprintf(&buf[last_buf][strlen(buf[last_buf])], " %i", i);
num_bits_printed++;
}
else
sprintf(&buf[last_buf][strlen(buf[last_buf])], i < 10 ? " " : " ");
}
strcat(buf[last_buf], "\n");
return buf[last_buf];

View File

@ -57,16 +57,13 @@ uint32_t __swab32(uint32_t x);
#define ATOM_MAX_BITS 32+1 // -1 signals end of array
typedef struct _cfg_atom
typedef struct _cfg_bits
{
int must_0[ATOM_MAX_BITS];
int must_1[ATOM_MAX_BITS];
const char* str;
int flag; // used to remember a state such as 'found'
} cfg_atom_t;
int atom_found(char* bits, const cfg_atom_t* atom);
void atom_remove(char* bits, const cfg_atom_t* atom);
int minor; // -1 is illegal and can be used to signal end-of-array
int rel_v16; // vertical 16 from top, relative to start of device
int bits; // 1 or more bits set
int name; // enum value
} cfg_bits_t;
uint64_t map_bits(uint64_t u64, int num_bits, int* src_pos);
@ -80,6 +77,13 @@ int bool_req_pins(uint64_t u64, int num_bits);
void printf_type2(uint8_t* d, int len, int inpos, int num_entries);
void printf_ramb_data(const uint8_t *bits, int row, int bram_idx);
typedef struct _bram_init // only first half of array used for bram8
{
int data[64][16];
int parity[8][16];
} bram_init_t;
void bram_extract_init(bram_init_t *init, const uint8_t *bits);
int is_empty(const uint8_t* d, int l);
int count_set_bits(const uint8_t* d, int l);
@ -87,11 +91,17 @@ int frame_get_bit(const uint8_t* frame_d, int bit);
void frame_clear_bit(uint8_t* frame_d, int bit);
void frame_set_bit(uint8_t* frame_d, int bit);
// cpuword returns the word in such a way that a bit
// index (cpuword & (1<<i)) corresponds to the same bit
// position as presented to the FPGA.
int frame_get_cpuword(const void *bits);
void frame_set_cpuword(void* bits, int v);
int frame_get_pinword(const void *bits);
void frame_set_pinword(void* bits, int v);
uint8_t mirror_bits(uint8_t v);
int pinword_to_cpu(int pinword);
int mirror_2bytes(int pinword);
uint16_t frame_get_u16(const uint8_t* frame_d);
uint64_t frame_get_u64(const uint8_t* frame_d);

View File

@ -668,7 +668,7 @@ enum {
// requirements for valid bram
// - rstram and rst_priority must be set for A and B.
enum { BRAM16 = 1, BRAM8 }; // subtype
enum { BRAM16 = 1, BRAM8 }; // subtype, bram8 not currently supported
enum { BRAM_TDP = 1, BRAM_SDP, BRAM_SP };
enum { BRAM_RST_SYNC = 1, BRAM_RST_ASYNC };
enum { BRAM_WIDTH_0 = 1, BRAM_WIDTH_1, BRAM_WIDTH_2, BRAM_WIDTH_4, BRAM_WIDTH_9, BRAM_WIDTH_18, BRAM_WIDTH_36 };
@ -676,11 +676,11 @@ enum { BRAM_WRITE_FIRST = 1, BRAM_READ_FIRST, BRAM_NO_CHANGE };
enum { BRAM_OUTREG_ON = 1, BRAM_OUTREG_OFF };
enum { BRAM_RST_PRIORITY_SR = 1, BRAM_RST_PRIORITY_CE };
// fpgadev_bram configures either a bram16 or a bram8 device.
// fpgadev_bram configures a bram16 device (bram8 is not currently supported)
// see ug383
struct fpgadev_bram
{
int *data; // points to 1024 (BRAM16) or 512 (BRAM8) words (each 16+2=18 bits)
struct bram_init *init;
int ram_mode; // BRAM8 only: BRAM_TDP, BRAM_SDP, BRAM_SP (?)
int rst_type; // BRAM_RST_SYNC, BRAM_RST_ASYNC
@ -1232,4 +1232,3 @@ struct w_net
#define ADD_PREF 1
int add_conn_net(struct fpga_model* model, int add_pref, const struct w_net *net);