more json, some bram work
This commit is contained in:
parent
ad0d2924df
commit
ea54683e8f
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -20,7 +20,7 @@
|
|||
# binaries
|
||||
#
|
||||
draw_svg_tiles
|
||||
new_fp
|
||||
fpinfo
|
||||
hstrrep
|
||||
sort_seq
|
||||
merge_seq
|
||||
|
|
16
Makefile
16
Makefile
|
@ -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
11
README
|
@ -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):
|
||||
|
|
12
autotest.c
12
autotest.c
|
@ -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);
|
||||
|
|
12
bit2fp.c
12
bit2fp.c
|
@ -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
|
||||
|
|
|
@ -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;
|
|
@ -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);
|
||||
}
|
||||
|
|
245
libs/bit_regs.c
245
libs/bit_regs.c
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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, " ]");
|
||||
}
|
||||
|
||||
//
|
||||
|
|
|
@ -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
|
||||
|
|
242
libs/floorplan.c
242
libs/floorplan.c
|
@ -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)
|
||||
int printf_switches(FILE *f, struct fpga_model *model)
|
||||
{
|
||||
struct fpga_tile* tile;
|
||||
int x, y, i, first_switch_printed;
|
||||
struct fpga_tile *tile;
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
232
libs/helper.c
232
libs/helper.c
|
@ -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)
|
||||
{
|
||||
|
@ -727,7 +700,7 @@ int frame_get_pinword(const void *bits)
|
|||
return byte0 << 8 | byte1;
|
||||
}
|
||||
|
||||
void frame_set_pinword(void* bits, int v)
|
||||
void frame_set_pinword(void *bits, int v)
|
||||
{
|
||||
((uint8_t*)bits)[0] = v >> 8;
|
||||
((uint8_t*)bits)[1] = v & 0xFF;
|
||||
|
@ -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];
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user