- a few things moved from custom text to json

- switched to llvm, fixed a few warnings
This commit is contained in:
Wolfgang Spraul 2015-03-15 16:42:35 -04:00
parent 7d872ef24f
commit ad0d2924df
18 changed files with 377 additions and 279 deletions

View File

@ -6,6 +6,7 @@
# For details see the UNLICENSE file at the root of the source tree.
#
CC = clang-3.6
CFLAGS += -I$(CURDIR)/libs

83
README
View File

@ -1,36 +1,31 @@
**** NOTE - JUNE 2013 ****
I would L O V E to do continue with fpgatools but each day is
short so I have to postpone fpgatools development probably
until 2014. Maybe I can switch directly to Artix then :-)
If you want to contact me please email wspraul@q-ag.de
****
Introduction
fpgatools is a toolchain to program field-programmable gate arrays
(FPGAs). The only supported chip at this time is the xc6slx9, a
45nm-generation fpga with 5720 6-input LUTs, block ram and
multiply-accumulate devices.
fpgatools converts the configuration of an FPGA between
JSON and bitstream representation.
*) maximize chip performance
*) fast development cycles
*) independent toolchain that only depends on free software
*) reconfigure on-chip
*) include get-started tools such as jtag, debugging, parts data
and hardware designs
*) design flow that includes asic manufacturing
*) lightweight C implementation without GUI
The only supported chips at this time is the xc6slx9, a 45nm-generation
FPGA with 5720 6-input LUTs, block ram and multiply-accumulate
resources.
Also not included are place and route tools or other higher-level
logic optimization, synthesis, Verilog, HLS, etc.
Future work on integrating with graywolf or yosys might be an option.
If you have ideas in that direction, please email the author at
wspraul@q-ag.de
*) educational resource
*) have fun and experiment with every feature of the chip
*) command-line tools, text-based file formats
*) supported platform: Linux
*) license: public domain
*) free software, released into the public domain (see
UNLICENSE for details)
FAQ
todo
Libraries
- libfpga-cores reusable cores
- libfpga-stdlib standard design elements on top of libfpga-control
- libfpga-control programmatic access to libfpga-model
- libfpga-model memory-only representation of an FPGA
- libfpga-model in-memory representation of the FPGA
- libfpga-floorplan reads and writes .fp floorplan files
- libfpga-bit reads and writes .bit bitstream files
@ -58,34 +53,27 @@ Profiling
~# perf annotate
~# perf report
Design Principles
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
- small independent command line utilities, no GUI
- plain C, no C++
- simple Makefiles
- text-based file formats
- automatic test suite
- public domain software
TODO (as of 2015-03)
TODO (as of February, 2013)
short-term (1 month):
short-term (3 months):
* support block memory
-> develop structure of dev_bram16/8
-> write block_mem autotest
* example: counter (including clock, jtag)
* support macc
* support pll_adv
* support dcm
* support ilogic2/ologic2
mid-term (6 months):
* example: j1 soc
* hls: llvm backend
* maybe fp2bit should natively write ieee1532 and separate tools convert
from ieee1532 to .bit and other formats
* macc
mid-term (12 months):
* example: counter (including clock, jtag)
* more cases in logic block configuration
* autotest: fix bugs in lut_encoding, logic_cfg, routing_sw, io_sw tests
* autotest: protect stderr of diff executable in autotest log
* support chips other than xc6slx9, maybe xc7a20
* write standard design elements for libfpga-stdlib library
* several places might benefit from a bison parser:
- switchbox description into bit parser/generator (bit_frames.c)
- inter-tile wire connections (model_conns.c)
@ -97,13 +85,14 @@ cleanup (whenever convenient):
* describe more wire names/meanings with integers instead of strings
* move all part-specific static data into xc_info()
long-term (>6 months):
long-term (>12 months):
* auto-crc calculation in .bit file
* MCB switches and connections
* support lm32 or openrisc core, either via libfpga or iverilog backend
* ipv6 or vnc in hardware?
* iverilog fpga backend
* maybe fp2bit should natively write ieee1532 and separate tools convert
from ieee1532 to .bit and other formats
* design fpga core that uses high-speed icap/reconfig to process data
* example: j1 soc
* support chips other than xc6slx9, maybe xc7a35 or xc7a100
ChangeLog

View File

@ -49,7 +49,7 @@ static int dump_file(const char* path)
|| !strncmp(line, "+++ ", 4)
|| !strncmp(line, "@@ ", 3))
continue;
printf(line);
printf("%s", line);
}
fclose(f);
}

View File

@ -6,6 +6,8 @@
# For details see the UNLICENSE file at the root of the source tree.
#
CC = clang-3.6
LIBS_VERSION_MAJOR = 0
LIBS_VERSION = $(LIBS_VERSION_MAJOR).0.0
@ -13,10 +15,9 @@ LIBFPGA_BIT_OBJS = bit_frames.o bit_regs.o
LIBFPGA_MODEL_OBJS = model_main.o model_tiles.o model_devices.o \
model_ports.o model_conns.o model_switches.o model_helper.o
LIBFPGA_FLOORPLAN_OBJS = floorplan.o
LIBFPGA_CONTROL_OBJS = control.o
LIBFPGA_CORES_OBJS = parts.o helper.o
LIBFPGA_CONTROL_OBJS = control.o parts.o helper.o
OBJS := $(LIBFPGA_CORES_OBJS) $(LIBFPGA_BIT_OBJS) $(LIBFPGA_MODEL_OBJS) \
OBJS := $(LIBFPGA_BIT_OBJS) $(LIBFPGA_MODEL_OBJS) \
$(LIBFPGA_FLOORPLAN_OBJS) $(LIBFPGA_CONTROL_OBJS)
DYNAMIC_LIBS = libfpga-model.so libfpga-bit.so libfpga-floorplan.so \
@ -31,8 +32,6 @@ all: $(DYNAMIC_LIBS) $(DYNAMIC_LIBS:.so=.a)
include ../Makefile.common
libfpga-cores.a: $(LIBFPGA_CORES_OBJS)
libfpga-bit.a: $(LIBFPGA_BIT_OBJS)
libfpga-model.a: $(LIBFPGA_MODEL_OBJS)
@ -45,8 +44,6 @@ libfpga-control.a: $(LIBFPGA_CONTROL_OBJS)
$(AR) $@ $^
$(RANLIB) $@
libfpga-cores.so: $(LIBFPGA_CORES_OBJS)
libfpga-bit.so: $(LIBFPGA_BIT_OBJS)
libfpga-model.so: $(LIBFPGA_MODEL_OBJS)

View File

@ -7,15 +7,14 @@
// xc6 configuration registers, documentation in ug380, page90
enum fpga_config_reg {
CRC = 0, FAR_MAJ, FAR_MIN, FDRI, FDRO, CMD, CTL, MASK, STAT, LOUT, COR1,
REG_NOOP = -1, // pseudo register for noops
CRC, FAR_MAJ, FAR_MIN, FDRI, FDRO, CMD, CTL, MASK, STAT, LOUT, COR1,
COR2, PWRDN_REG, FLR, IDCODE, CWDT, HC_OPT_REG, CSBO = 18,
GENERAL1, GENERAL2, GENERAL3, GENERAL4, GENERAL5, MODE_REG, PU_GWE,
PU_GTS, MFWR, CCLK_FREQ, SEU_OPT, EXP_SIGN, RDBK_SIGN, BOOTSTS,
EYE_MASK, CBC_REG
};
#define REG_NOOP -1 // pseudo register for noops
#define COR1_DEF 0x3D00
#define COR1_CRC_BYPASS 0x0010
#define COR2_DEF 0x09EE

View File

@ -680,6 +680,8 @@ 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];
@ -851,6 +853,7 @@ static void print_ramb16_cfg(ramb16_cfg_t* cfg)
}
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)
@ -924,8 +927,9 @@ static void printf_minors(int row, int major, int minor, int num_minors,
static int dump_maj_bram(const uint8_t *bits, int row, int major)
{
ramb16_cfg_t ramb16_cfg[4];
int minor, i, j, offset_in_frame;
// ramb16_cfg_t ramb16_cfg[4];
// int j, offset_in_frame;
int minor, i;
for (minor = 0; minor < get_major_minors(XC6SLX9, major); minor++)
printf_clock(&bits[minor*FRAME_SIZE], row, major, minor);

View File

@ -171,7 +171,7 @@ static const char* dev_str[] = FPGA_DEV_STR;
const char* fdev_type2str(enum fpgadev_type type)
{
if (type < 0 || type >= sizeof(dev_str)/sizeof(*dev_str))
if (type >= sizeof(dev_str)/sizeof(*dev_str))
{ HERE(); return 0; }
return dev_str[type];
}
@ -1310,6 +1310,24 @@ const char* fpga_switch_print(struct fpga_model* model, int y, int x,
return buf[last_buf];
}
const char* fpga_switch_print_json(struct fpga_model* model, int y, int x,
swidx_t swidx)
{
enum { NUM_BUFS = 16, BUF_SIZE = 128 };
static char buf[NUM_BUFS][BUF_SIZE];
static int last_buf = 0;
uint32_t sw;
sw = YX_TILE(model, y, x)->switches[swidx];
last_buf = (last_buf+1)%NUM_BUFS;
snprintf(buf[last_buf], sizeof(*buf), ", \"from\" : \"%s\", \"to\" : \"%s\"%s",
connpt_str(model, y, x, SW_FROM_I(sw)),
connpt_str(model, y, x, SW_TO_I(sw)),
sw & SWITCH_BIDIRECTIONAL ? ", \"bidir\" : true" : "");
return buf[last_buf];
}
int fpga_switch_is_bidir(struct fpga_model* model, int y, int x,
swidx_t swidx)
{
@ -2148,6 +2166,7 @@ int fnet_add_port(struct fpga_model* model, net_idx_t net_i,
pinw_idx_t pinw_idx)
{
struct fpga_net* net;
dev_idx_t dev_idx;
fnet_useidx(model, net_i);
RC_CHECK(model);
@ -2158,8 +2177,9 @@ int fnet_add_port(struct fpga_model* model, net_idx_t net_i,
net->el[net->len].y = y;
net->el[net->len].x = x;
net->el[net->len].idx = pinw_idx | NET_IDX_IS_PINW;
net->el[net->len].dev_idx = fpga_dev_idx(model, y, x, type, type_idx);
RC_ASSERT(model, net->el[net->len].dev_idx != NO_DEV);
dev_idx = fpga_dev_idx(model, y, x, type, type_idx);
RC_ASSERT(model, dev_idx != NO_DEV);
net->el[net->len].dev_idx = dev_idx;
net->len++;
RC_RETURN(model);
@ -2290,8 +2310,9 @@ static void fprintf_inout_pin(FILE* f, struct fpga_model* model,
pin_str = fdev_pinw_idx2str(tile->devs[dev_idx].type, pinw_i);
if (!pin_str) { HERE(); return; }
snprintf(buf, sizeof(buf), "net %i %s y%i x%i %s %i pin %s\n",
net_i, in_pin ? "in" : "out", el->y, el->x,
snprintf(buf, sizeof(buf), " { \"type\" : \"%s\", \"y\" : %i, \"x\" : %i, "
"\"dev\" : \"%s\", \"dev_idx\" : %i, \"pin\" : \"%s\" }",
in_pin ? "in" : "out", el->y, el->x,
fdev_type2str(tile->devs[dev_idx].type),
fdev_typeidx(model, el->y, el->x, dev_idx),
pin_str);
@ -2301,21 +2322,27 @@ static void fprintf_inout_pin(FILE* f, struct fpga_model* model,
void fnet_printf(FILE* f, struct fpga_model* model, net_idx_t net_i)
{
struct fpga_net* net;
int i;
int i, first_line;
net = fnet_get(model, net_i);
if (!net) { HERE(); return; }
fprintf(f, "[\n");
first_line = 1;
for (i = 0; i < net->len; i++) {
if (!first_line)
fprintf(f, ",\n");
first_line = 0;
if (net->el[i].idx & NET_IDX_IS_PINW) {
fprintf_inout_pin(f, model, net_i, &net->el[i]);
continue;
}
// switch
fprintf(f, "net %i sw y%i x%i %s\n",
net_i, net->el[i].y, net->el[i].x,
fpga_switch_print(model, net->el[i].y,
fprintf(f, " { \"type\" : \"sw\", \"y\" : %i, \"x\" : %i%s }",
net->el[i].y, net->el[i].x,
fpga_switch_print_json(model, net->el[i].y,
net->el[i].x, net->el[i].idx));
}
fprintf(f, "\n ]");
}
//

View File

@ -190,6 +190,8 @@ const char* fpga_switch_str(struct fpga_model* model, int y, int x,
swidx_t swidx, int from_to);
str16_t fpga_switch_str_i(struct fpga_model* model, int y, int x,
swidx_t swidx, int from_to);
const char* fpga_switch_print_json(struct fpga_model* model, int y, int x,
swidx_t swidx);
const char* fpga_switch_print(struct fpga_model* model, int y, int x,
swidx_t swidx);
int fpga_switch_is_bidir(struct fpga_model* model, int y, int x,

View File

@ -11,14 +11,14 @@
#include "control.h"
#include "floorplan.h"
void printf_version(FILE* f)
{
fprintf(f, "fpga_floorplan_format 1\n");
}
#define PRINT_FLAG(fp, flag) if ((tf) & (flag)) \
{ fprintf (fp, " %s", #flag); tf &= ~(flag); }
void printf_version(FILE* f)
{
fprintf(f, " \"fpga_floorplan_version\" : 1");
}
int printf_tiles(FILE* f, struct fpga_model* model)
{
struct fpga_tile* tile;
@ -67,110 +67,143 @@ int printf_IOB(FILE *f, struct fpga_model *model,
{
struct fpga_tile *tile;
char pref[256];
int dev_i;
int dev_i, first_line;
dev_i = fpga_dev_idx(model, y, x, DEV_IOB, 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 IOB %i", y, x, type_idx);
snprintf(pref, sizeof(pref), " { \"y\" : %i, \"x\" : %i, \"dev\" : \"IOB\", \"dev_idx\" : %i, ", y, x, type_idx);
first_line = 1;
if (!config_only)
fprintf(f, "%s type %s\n", pref,
if (!config_only) {
fprintf(f, "%s%s\"type\" : \"%s\" }", first_line ? "" : ",\n", pref,
tile->devs[dev_i].subtype == IOBM ? "M" : "S");
if (tile->devs[dev_i].u.iob.istandard[0])
fprintf(f, "%s istd %s\n", pref,
first_line = 0;
}
if (tile->devs[dev_i].u.iob.istandard[0]) {
fprintf(f, "%s%s\"istd\" : \"%s\" }", first_line ? "" : ",\n", pref,
tile->devs[dev_i].u.iob.istandard);
if (tile->devs[dev_i].u.iob.ostandard[0])
fprintf(f, "%s ostd %s\n", pref,
first_line = 0;
}
if (tile->devs[dev_i].u.iob.ostandard[0]) {
fprintf(f, "%s%s\"ostd\" : \"%s\" }", first_line ? "" : ",\n", pref,
tile->devs[dev_i].u.iob.ostandard);
first_line = 0;
}
switch (tile->devs[dev_i].u.iob.bypass_mux) {
case BYPASS_MUX_I:
fprintf(f, "%s bypass_mux I\n", pref);
fprintf(f, "%s%s\"bypass_mux\" : \"I\" }", first_line ? "" : ",\n", pref);
first_line = 0;
break;
case BYPASS_MUX_O:
fprintf(f, "%s bypass_mux O\n", pref);
fprintf(f, "%s%s\"bypass_mux\" : \"O\" }", first_line ? "" : ",\n", pref);
first_line = 0;
break;
case BYPASS_MUX_T:
fprintf(f, "%s bypass_mux T\n", pref);
fprintf(f, "%s%s\"bypass_mux\" : \"T\" }", first_line ? "" : ",\n", pref);
first_line = 0;
break;
case 0: break; default: RC_FAIL(model, EINVAL);
}
switch (tile->devs[dev_i].u.iob.I_mux) {
case IMUX_I_B:
fprintf(f, "%s imux I_B\n", pref);
fprintf(f, "%s%s\"imux\" : \"I_B\" }", first_line ? "" : ",\n", pref);
first_line = 0;
break;
case IMUX_I:
fprintf(f, "%s imux I\n", pref);
fprintf(f, "%s%s\"imux\" : \"I\" }", first_line ? "" : ",\n", pref);
first_line = 0;
break;
case 0: break; default: RC_FAIL(model, EINVAL);
}
if (tile->devs[dev_i].u.iob.drive_strength)
fprintf(f, "%s strength %i\n", pref,
if (tile->devs[dev_i].u.iob.drive_strength) {
fprintf(f, "%s%s\"strength\" : %i }", first_line ? "" : ",\n", pref,
tile->devs[dev_i].u.iob.drive_strength);
first_line = 0;
}
switch (tile->devs[dev_i].u.iob.slew) {
case SLEW_SLOW:
fprintf(f, "%s slew SLOW\n", pref);
fprintf(f, "%s%s\"slew\" : \"SLOW\" }", first_line ? "" : ",\n", pref);
first_line = 0;
break;
case SLEW_FAST:
fprintf(f, "%s slew FAST\n", pref);
fprintf(f, "%s%s\"slew\" : \"FAST\" }", first_line ? "" : ",\n", pref);
first_line = 0;
break;
case SLEW_QUIETIO:
fprintf(f, "%s slew QUIETIO\n", pref);
fprintf(f, "%s%s\"slew\" : \"QUIETIO\" }", first_line ? "" : ",\n", pref);
first_line = 0;
break;
case 0: break; default: RC_FAIL(model, EINVAL);
}
if (tile->devs[dev_i].u.iob.O_used)
fprintf(f, "%s O_used\n", pref);
if (tile->devs[dev_i].u.iob.O_used) {
fprintf(f, "%s%s\"O_used\" : true }", first_line ? "" : ",\n", pref);
first_line = 0;
}
switch (tile->devs[dev_i].u.iob.suspend) {
case SUSP_LAST_VAL:
fprintf(f, "%s suspend DRIVE_LAST_VALUE\n", pref);
fprintf(f, "%s%s\"suspend\" : \"DRIVE_LAST_VALUE\" }", first_line ? "" : ",\n", pref);
first_line = 0;
break;
case SUSP_3STATE:
fprintf(f, "%s suspend 3STATE\n", pref);
fprintf(f, "%s%s\"suspend\" : \"3STATE\" }", first_line ? "" : ",\n", pref);
first_line = 0;
break;
case SUSP_3STATE_PULLUP:
fprintf(f, "%s suspend 3STATE_PULLUP\n", pref);
fprintf(f, "%s%s\"suspend\" : \"3STATE_PULLUP\" }", first_line ? "" : ",\n", pref);
first_line = 0;
break;
case SUSP_3STATE_PULLDOWN:
fprintf(f, "%s suspend 3STATE_PULLDOWN\n", pref);
fprintf(f, "%s%s\"suspend\" : \"3STATE_PULLDOWN\" }", first_line ? "" : ",\n", pref);
first_line = 0;
break;
case SUSP_3STATE_KEEPER:
fprintf(f, "%s suspend 3STATE_KEEPER\n", pref);
fprintf(f, "%s%s\"suspend\" : \"3STATE_KEEPER\" }", first_line ? "" : ",\n", pref);
first_line = 0;
break;
case SUSP_3STATE_OCT_ON:
fprintf(f, "%s suspend 3STATE_OCT_ON\n", pref);
fprintf(f, "%s%s\"suspend\" : \"3STATE_OCT_ON\" }", first_line ? "" : ",\n", pref);
first_line = 0;
break;
case 0: break; default: RC_FAIL(model, EINVAL);
}
switch (tile->devs[dev_i].u.iob.in_term) {
case ITERM_NONE:
fprintf(f, "%s in_term NONE\n", pref);
fprintf(f, "%s%s\"in_term\" : \"NONE\" }", first_line ? "" : ",\n", pref);
first_line = 0;
break;
case ITERM_UNTUNED_25:
fprintf(f, "%s in_term UNTUNED_SPLIT_25\n", pref);
fprintf(f, "%s%s\"in_term\" : \"UNTUNED_SPLIT_25\" }", first_line ? "" : ",\n", pref);
first_line = 0;
break;
case ITERM_UNTUNED_50:
fprintf(f, "%s in_term UNTUNED_SPLIT_50\n", pref);
fprintf(f, "%s%s\"in_term\" : \"UNTUNED_SPLIT_50\" }", first_line ? "" : ",\n", pref);
first_line = 0;
break;
case ITERM_UNTUNED_75:
fprintf(f, "%s in_term UNTUNED_SPLIT_75\n", pref);
fprintf(f, "%s%s\"in_term\" : \"UNTUNED_SPLIT_75\" }", first_line ? "" : ",\n", pref);
first_line = 0;
break;
case 0: break; default: RC_FAIL(model, EINVAL);
}
switch (tile->devs[dev_i].u.iob.out_term) {
case OTERM_NONE:
fprintf(f, "%s out_term NONE\n", pref);
fprintf(f, "%s%s\"out_term\" : \"NONE\" }", first_line ? "" : ",\n", pref);
first_line = 0;
break;
case OTERM_UNTUNED_25:
fprintf(f, "%s out_term UNTUNED_25\n", pref);
fprintf(f, "%s%s\"out_term\" : \"UNTUNED_25\" }", first_line ? "" : ",\n", pref);
first_line = 0;
break;
case OTERM_UNTUNED_50:
fprintf(f, "%s out_term UNTUNED_50\n", pref);
fprintf(f, "%s%s\"out_term\" : \"UNTUNED_50\" }", first_line ? "" : ",\n", pref);
first_line = 0;
break;
case OTERM_UNTUNED_75:
fprintf(f, "%s out_term UNTUNED_75\n", pref);
fprintf(f, "%s%s\"out_term\" : \"UNTUNED_75\" }", first_line ? "" : ",\n", pref);
first_line = 0;
break;
case 0: break; default: RC_FAIL(model, EINVAL);
}
@ -287,25 +320,29 @@ int printf_LOGIC(FILE* f, struct fpga_model* model,
struct fpgadev_logic *cfg;
char pref[256];
const char *str;
int dev_i, j;
int dev_i, j, first_line;
dev_i = fpga_dev_idx(model, y, x, DEV_LOGIC, 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 LOGIC %i", y, x, type_idx);
snprintf(pref, sizeof(pref), " { \"y\" : %i, \"x\" : %i, \"dev\" : \"LOGIC\", \"dev_idx\" : %i, ", y, x, type_idx);
first_line = 1;
if (!config_only) {
switch (tile->devs[dev_i].subtype) {
case LOGIC_X:
fprintf(f, "%s type X\n", pref);
fprintf(f, "%s%s\"type\" : \"X\" }", first_line ? "" : ",\n", pref);
first_line = 0;
break;
case LOGIC_L:
fprintf(f, "%s type L\n", pref);
fprintf(f, "%s%s\"type\" : \"L\" }", first_line ? "" : ",\n", pref);
first_line = 0;
break;
case LOGIC_M:
fprintf(f, "%s type M\n", pref);
fprintf(f, "%s%s\"type\" : \"M\" }", first_line ? "" : ",\n", pref);
first_line = 0;
break;
default: RC_FAIL(model, EINVAL);
}
@ -319,222 +356,282 @@ int printf_LOGIC(FILE* f, struct fpga_model* model,
if (cfg->a2d[j].flags & LUT6VAL_SET) {
RC_ASSERT(model, !ULL_HIGH32(cfg->a2d[j].lut6_val));
if (print_hex_vals)
fprintf(f, "%s %c6_lut_val 0x%016lX\n",
pref, 'A'+j, cfg->a2d[j].lut6_val);
fprintf(f, "%s%s\"%c6_lut_val\" : \"0x%016lX\" }",
first_line ? "" : ",\n", pref, 'A'+j, cfg->a2d[j].lut6_val);
else {
str = bool_bits2str(cfg->a2d[j].lut6_val, 32);
RC_ASSERT(model, str);
fprintf(f, "%s %c6_lut_str (A6+~A6)*(%s)\n",
pref, 'A'+j, str);
fprintf(f, "%s%s\"%c6_lut_str\" : \"(A6+~A6)*(%s)\" }",
first_line ? "" : ",\n", pref, 'A'+j, str);
}
first_line = 0;
}
if (print_hex_vals)
fprintf(f, "%s %c5_lut_val 0x%08X\n",
pref, 'A'+j, ULL_LOW32(cfg->a2d[j].lut5_val));
fprintf(f, "%s%s\"%c5_lut_val\" : \"0x%08X\" }",
first_line ? "" : ",\n", pref, 'A'+j, ULL_LOW32(cfg->a2d[j].lut5_val));
else {
str = bool_bits2str(cfg->a2d[j].lut5_val, 32);
RC_ASSERT(model, str);
fprintf(f, "%s %c5_lut_str %s\n",
pref, 'A'+j, str);
fprintf(f, "%s%s\"%c5_lut_str\" : \"%s\" }",
first_line ? "" : ",\n", pref, 'A'+j, str);
}
first_line = 0;
} else {
if (cfg->a2d[j].flags & LUT6VAL_SET) {
if (print_hex_vals)
fprintf(f, "%s %c6_lut_val 0x%016lX\n",
pref, 'A'+j, cfg->a2d[j].lut6_val);
fprintf(f, "%s%s\"%c6_lut_val\" : \"0x%016lX\" }",
first_line ? "" : ",\n", pref, 'A'+j, cfg->a2d[j].lut6_val);
else {
str = bool_bits2str(cfg->a2d[j].lut6_val, 64);
RC_ASSERT(model, str);
fprintf(f, "%s %c6_lut_str %s\n",
pref, 'A'+j, str);
fprintf(f, "%s%s\"%c6_lut_str\" : \"%s\" }",
first_line ? "" : ",\n", pref, 'A'+j, str);
}
first_line = 0;
}
}
if (cfg->a2d[j].flags & OUT_USED) {
fprintf(f, "%s%s\"%c_used\" : true }", first_line ? "" : ",\n", pref, 'A'+j);
first_line = 0;
}
if (cfg->a2d[j].flags & OUT_USED)
fprintf(f, "%s %c_used\n", pref, 'A'+j);
switch (cfg->a2d[j].ff) {
case FF_OR2L:
fprintf(f, "%s %c_ff OR2L\n", pref, 'A'+j);
fprintf(f, "%s%s\"%c_ff\" : \"OR2L\" }", first_line ? "" : ",\n", pref, 'A'+j);
first_line = 0;
break;
case FF_AND2L:
fprintf(f, "%s %c_ff AND2L\n", pref, 'A'+j);
fprintf(f, "%s%s\"%c_ff\" : \"AND2L\" }", first_line ? "" : ",\n", pref, 'A'+j);
first_line = 0;
break;
case FF_LATCH:
fprintf(f, "%s %c_ff LATCH\n", pref, 'A'+j);
fprintf(f, "%s%s\"%c_ff\" : \"LATCH\" }", first_line ? "" : ",\n", pref, 'A'+j);
first_line = 0;
break;
case FF_FF:
fprintf(f, "%s %c_ff FF\n", pref, 'A'+j);
fprintf(f, "%s%s\"%c_ff\" : \"FF\" }", first_line ? "" : ",\n", pref, 'A'+j);
first_line = 0;
break;
case 0: break; default: RC_FAIL(model, EINVAL);
}
switch (cfg->a2d[j].ff_mux) {
case MUX_O6:
fprintf(f, "%s %c_ffmux O6\n", pref, 'A'+j);
fprintf(f, "%s%s\"%c_ffmux\" : \"O6\" }", first_line ? "" : ",\n", pref, 'A'+j);
first_line = 0;
break;
case MUX_O5:
fprintf(f, "%s %c_ffmux O5\n", pref, 'A'+j);
fprintf(f, "%s%s\"%c_ffmux\" : \"O5\" }", first_line ? "" : ",\n", pref, 'A'+j);
first_line = 0;
break;
case MUX_X:
fprintf(f, "%s %c_ffmux X\n", pref, 'A'+j);
fprintf(f, "%s%s\"%c_ffmux\" : \"X\" }", first_line ? "" : ",\n", pref, 'A'+j);
first_line = 0;
break;
case MUX_CY:
fprintf(f, "%s %c_ffmux CY\n", pref, 'A'+j);
fprintf(f, "%s%s\"%c_ffmux\" : \"CY\" }", first_line ? "" : ",\n", pref, 'A'+j);
first_line = 0;
break;
case MUX_XOR:
fprintf(f, "%s %c_ffmux XOR\n", pref, 'A'+j);
fprintf(f, "%s%s\"%c_ffmux\" : \"XOR\" }", first_line ? "" : ",\n", pref, 'A'+j);
first_line = 0;
break;
case MUX_F7:
fprintf(f, "%s %c_ffmux F7\n", pref, 'A'+j);
fprintf(f, "%s%s\"%c_ffmux\" : \"F7\" }", first_line ? "" : ",\n", pref, 'A'+j);
first_line = 0;
break;
case MUX_F8:
fprintf(f, "%s %c_ffmux F8\n", pref, 'A'+j);
fprintf(f, "%s%s\"%c_ffmux\" : \"F8\" }", first_line ? "" : ",\n", pref, 'A'+j);
first_line = 0;
break;
case MUX_MC31:
fprintf(f, "%s %c_ffmux MC31\n", pref, 'A'+j);
fprintf(f, "%s%s\"%c_ffmux\" : \"MC31\" }", first_line ? "" : ",\n", pref, 'A'+j);
first_line = 0;
break;
case 0: break; default: RC_FAIL(model, EINVAL);
}
switch (cfg->a2d[j].ff_srinit) {
case FF_SRINIT0:
fprintf(f, "%s %c_ffsrinit 0\n", pref, 'A'+j);
fprintf(f, "%s%s\"%c_ffsrinit\" : false }", first_line ? "" : ",\n", pref, 'A'+j);
first_line = 0;
break;
case FF_SRINIT1:
fprintf(f, "%s %c_ffsrinit 1\n", pref, 'A'+j);
fprintf(f, "%s%s\"%c_ffsrinit\" : true }", first_line ? "" : ",\n", pref, 'A'+j);
first_line = 0;
break;
case 0: break; default: RC_FAIL(model, EINVAL);
}
switch (cfg->a2d[j].out_mux) {
case MUX_O6:
fprintf(f, "%s %c_outmux O6\n", pref, 'A'+j);
fprintf(f, "%s%s\"%c_outmux\" : \"O6\" }", first_line ? "" : ",\n", pref, 'A'+j);
first_line = 0;
break;
case MUX_O5:
fprintf(f, "%s %c_outmux O5\n", pref, 'A'+j);
fprintf(f, "%s%s\"%c_outmux\" : \"O5\" }", first_line ? "" : ",\n", pref, 'A'+j);
first_line = 0;
break;
case MUX_5Q:
fprintf(f, "%s %c_outmux 5Q\n", pref, 'A'+j);
fprintf(f, "%s%s\"%c_outmux\" : \"5Q\" }", first_line ? "" : ",\n", pref, 'A'+j);
first_line = 0;
break;
case MUX_CY:
fprintf(f, "%s %c_outmux CY\n", pref, 'A'+j);
fprintf(f, "%s%s\"%c_outmux\" : \"CY\" }", first_line ? "" : ",\n", pref, 'A'+j);
first_line = 0;
break;
case MUX_XOR:
fprintf(f, "%s %c_outmux XOR\n", pref, 'A'+j);
fprintf(f, "%s%s\"%c_outmux\" : \"XOR\" }", first_line ? "" : ",\n", pref, 'A'+j);
first_line = 0;
break;
case MUX_F7:
fprintf(f, "%s %c_outmux F7\n", pref, 'A'+j);
fprintf(f, "%s%s\"%c_outmux\" : \"F7\" }", first_line ? "" : ",\n", pref, 'A'+j);
first_line = 0;
break;
case MUX_F8:
fprintf(f, "%s %c_outmux F8\n", pref, 'A'+j);
fprintf(f, "%s%s\"%c_outmux\" : \"F8\" }", first_line ? "" : ",\n", pref, 'A'+j);
first_line = 0;
break;
case MUX_MC31:
fprintf(f, "%s %c_outmux MC31\n", pref, 'A'+j);
fprintf(f, "%s%s\"%c_outmux\" : \"MC31\" }", first_line ? "" : ",\n", pref, 'A'+j);
first_line = 0;
break;
case 0: break; default: RC_FAIL(model, EINVAL);
}
switch (cfg->a2d[j].ff5_srinit) {
case FF_SRINIT0:
fprintf(f, "%s %c5_ffsrinit 0\n", pref, 'A'+j);
fprintf(f, "%s%s\"%c5_ffsrinit\" : false }", first_line ? "" : ",\n", pref, 'A'+j);
first_line = 0;
break;
case FF_SRINIT1:
fprintf(f, "%s %c5_ffsrinit 1\n", pref, 'A'+j);
fprintf(f, "%s%s\"%c5_ffsrinit\" : true }", first_line ? "" : ",\n", pref, 'A'+j);
first_line = 0;
break;
case 0: break; default: RC_FAIL(model, EINVAL);
}
switch (cfg->a2d[j].cy0) {
case CY0_X:
fprintf(f, "%s %c_cy0 X\n", pref, 'A'+j);
fprintf(f, "%s%s\"%c_cy0\" : \"X\" }", first_line ? "" : ",\n", pref, 'A'+j);
first_line = 0;
break;
case CY0_O5:
fprintf(f, "%s %c_cy0 O5\n", pref, 'A'+j);
fprintf(f, "%s%s\"%c_cy0\" : \"O5\" }", first_line ? "" : ",\n", pref, 'A'+j);
first_line = 0;
break;
case 0: break; default: RC_FAIL(model, EINVAL);
}
// distributed memory related:
switch (cfg->a2d[j].ram_mode) {
case DPRAM64:
fprintf(f, "%s %c_ram_mode DPRAM64\n", pref, 'A'+j);
fprintf(f, "%s%s\"%c_ram_mode\" : \"DPRAM64\" }", first_line ? "" : ",\n", pref, 'A'+j);
first_line = 0;
break;
case DPRAM32:
fprintf(f, "%s %c_ram_mode DPRAM32\n", pref, 'A'+j);
fprintf(f, "%s%s\"%c_ram_mode\" : \"DPRAM32\" }", first_line ? "" : ",\n", pref, 'A'+j);
first_line = 0;
break;
case SPRAM64:
fprintf(f, "%s %c_ram_mode SPRAM64\n", pref, 'A'+j);
fprintf(f, "%s%s\"%c_ram_mode\" : \"SPRAM64\" }", first_line ? "" : ",\n", pref, 'A'+j);
first_line = 0;
break;
case SPRAM32:
fprintf(f, "%s %c_ram_mode SPRAM32\n", pref, 'A'+j);
fprintf(f, "%s%s\"%c_ram_mode\" : \"SPRAM32\" }", first_line ? "" : ",\n", pref, 'A'+j);
first_line = 0;
break;
case SRL32:
fprintf(f, "%s %c_ram_mode SRL32\n", pref, 'A'+j);
fprintf(f, "%s%s\"%c_ram_mode\" : \"SRL32\" }", first_line ? "" : ",\n", pref, 'A'+j);
first_line = 0;
break;
case SRL16:
fprintf(f, "%s %c_ram_mode SRL16\n", pref, 'A'+j);
fprintf(f, "%s%s\"%c_ram_mode\" : \"SRL16\" }", first_line ? "" : ",\n", pref, 'A'+j);
first_line = 0;
break;
case 0: break; default: RC_FAIL(model, EINVAL);
}
switch (cfg->a2d[j].di_mux) {
case DIMUX_MC31:
fprintf(f, "%s %c_di_mux MC31\n", pref, 'A'+j);
fprintf(f, "%s%s\"%c_di_mux\" : \"MC31\" }", first_line ? "" : ",\n", pref, 'A'+j);
first_line = 0;
break;
case DIMUX_X:
fprintf(f, "%s %c_di_mux X\n", pref, 'A'+j);
fprintf(f, "%s%s\"%c_di_mux\" : \"X\" }", first_line ? "" : ",\n", pref, 'A'+j);
first_line = 0;
break;
case DIMUX_DX:
fprintf(f, "%s %c_di_mux DX\n", pref, 'A'+j);
fprintf(f, "%s%s\"%c_di_mux\" : \"DX\" }", first_line ? "" : ",\n", pref, 'A'+j);
first_line = 0;
break;
case DIMUX_BDI1:
fprintf(f, "%s %c_di_mux BDI1\n", pref, 'A'+j);
fprintf(f, "%s%s\"%c_di_mux\" : \"BDI1\" }", first_line ? "" : ",\n", pref, 'A'+j);
first_line = 0;
break;
case 0: break; default: RC_FAIL(model, EINVAL);
}
}
switch (cfg->clk_inv) {
case CLKINV_B:
fprintf(f, "%s clk CLK_B\n", pref);
fprintf(f, "%s%s\"clk\" : \"CLK_B\" }", first_line ? "" : ",\n", pref);
first_line = 0;
break;
case CLKINV_CLK:
fprintf(f, "%s clk CLK\n", pref);
fprintf(f, "%s%s\"clk\" : \"CLK\" }", first_line ? "" : ",\n", pref);
first_line = 0;
break;
case 0: break; default: RC_FAIL(model, EINVAL);
}
switch (cfg->sync_attr) {
case SYNCATTR_SYNC:
fprintf(f, "%s sync SYNC\n", pref);
fprintf(f, "%s%s\"sync\" : \"SYNC\" }", first_line ? "" : ",\n", pref);
first_line = 0;
break;
case SYNCATTR_ASYNC:
fprintf(f, "%s sync ASYNC\n", pref);
fprintf(f, "%s%s\"sync\" : \"ASYNC\" }", first_line ? "" : ",\n", pref);
first_line = 0;
break;
case 0: break; default: RC_FAIL(model, EINVAL);
}
if (cfg->ce_used)
fprintf(f, "%s ce_used\n", pref);
if (cfg->sr_used)
fprintf(f, "%s sr_used\n", pref);
if (cfg->ce_used) {
fprintf(f, "%s%s\"ce_used\" : true }", first_line ? "" : ",\n", pref);
first_line = 0;
}
if (cfg->sr_used) {
fprintf(f, "%s%s\"sr_used\" : true }", first_line ? "" : ",\n", pref);
first_line = 0;
}
switch (cfg->we_mux) {
case WEMUX_WE:
fprintf(f, "%s wemux WE\n", pref);
fprintf(f, "%s%s\"wemux\" : \"WE\" }", first_line ? "" : ",\n", pref);
first_line = 0;
break;
case WEMUX_CE:
fprintf(f, "%s wemux CE\n", pref);
fprintf(f, "%s%s\"wemux\" : \"CE\" }", first_line ? "" : ",\n", pref);
first_line = 0;
break;
case 0: break; default: RC_FAIL(model, EINVAL);
}
if (cfg->cout_used)
fprintf(f, "%s cout_used\n", pref);
if (cfg->cout_used) {
fprintf(f, "%s%s\"cout_used\" : true }", first_line ? "" : ",\n", pref);
first_line = 0;
}
switch (cfg->precyinit) {
case PRECYINIT_0:
fprintf(f, "%s precyinit 0\n", pref);
fprintf(f, "%s%s\"precyinit\" : \"0\" }", first_line ? "" : ",\n", pref);
first_line = 0;
break;
case PRECYINIT_1:
fprintf(f, "%s precyinit 1\n", pref);
fprintf(f, "%s%s\"precyinit\" : \"1\" }", first_line ? "" : ",\n", pref);
first_line = 0;
break;
case PRECYINIT_AX:
fprintf(f, "%s precyinit AX\n", pref);
fprintf(f, "%s%s\"precyinit\" : \"AX\" }", first_line ? "" : ",\n", pref);
first_line = 0;
break;
case 0: break; default: RC_FAIL(model, EINVAL);
}
if (cfg->wa7_used)
fprintf(f, "%s wa7_used\n", pref);
if (cfg->wa8_used)
fprintf(f, "%s wa8_used\n", pref);
if (cfg->wa7_used) {
fprintf(f, "%s%s\"wa7_used\" : true }", first_line ? "" : ",\n", pref);
first_line = 0;
}
if (cfg->wa8_used) {
fprintf(f, "%s%s\"wa8_used\" : true }", first_line ? "" : ",\n", pref);
first_line = 0;
}
RC_RETURN(model);
}
@ -1016,16 +1113,21 @@ inst:
int printf_devices(FILE* f, struct fpga_model* model, int config_only)
{
int x, y, i;
int x, y, i, first_dev;
struct fpga_tile* tile;
RC_CHECK(model);
fprintf(f, " \"devices\" : [\n");
first_dev = 1;
for (x = 0; x < model->x_width; x++) {
for (y = 0; y < model->y_height; y++) {
tile = YX_TILE(model, y, x);
for (i = 0; i < tile->num_devs; i++) {
if (config_only && !(tile->devs[i].instantiated))
continue;
if (!first_dev)
fprintf(f, ",\n");
first_dev = 0;
switch (tile->devs[i].type) {
case DEV_IOB:
printf_IOB(f, model, y, x,
@ -1053,13 +1155,15 @@ int printf_devices(FILE* f, struct fpga_model* model, int config_only)
config_only);
break;
default:
fprintf(f, "dev y%i x%i %s\n", y, x,
fprintf(f, " { \"y\" : %i, \"x\" : %i, \"dev\" : \"%s\" }", y, x,
fdev_type2str(tile->devs[i].type));
break;
}
}
}
}
if (!first_dev) fprintf(f, "\n");
fprintf(f, " ]");
RC_RETURN(model);
}
@ -1189,13 +1293,21 @@ int printf_switches(FILE* f, struct fpga_model* model)
int printf_nets(FILE* f, struct fpga_model* model)
{
net_idx_t net_i;
int rc;
int rc, first_line;
RC_CHECK(model);
fprintf(f, " \"nets\" : [\n");
first_line = 1;
net_i = NO_NET;
while (!(rc = fnet_enum(model, net_i, &net_i)) && net_i != NO_NET)
while (!(rc = fnet_enum(model, net_i, &net_i)) && net_i != NO_NET) {
if (!first_line)
fprintf(f, ",");
first_line = 0;
fnet_printf(f, model, net_i);
}
if (rc) FAIL(rc);
if (!first_line) fprintf(f, "\n");
fprintf(f, " ]");
return 0;
fail:
return rc;
@ -1443,15 +1555,19 @@ int read_floorplan(struct fpga_model* model, FILE* f)
int write_floorplan(FILE* f, struct fpga_model* model, int flags)
{
if (!(flags & FP_NO_HEADER))
fprintf(f, "{\n");
printf_version(f);
if (model->rc)
fprintf(f, "rc %i\n", model->rc);
else {
fprintf(f, ",\n");
printf_devices(f, model, /*config_only*/ 1);
fprintf(f, ",\n");
printf_nets(f, model);
}
fprintf(f, "\n}\n");
RC_RETURN(model);
}

View File

@ -5,25 +5,6 @@
// For details see the UNLICENSE file at the root of the source tree.
//
//
// Design principles of a floorplan file
//
// What needs to be in the file:
// - all devices, configuration for each device
// probably multiple lines that are adding config strings
// - wires maybe separately, and/or as named connection points
// in tiles?
// - connection pairs that can be enabled/disabled
// - global flags and configuration registers
// - the static data should be optional (unused conn pairs,
// unused devices, wires)
//
// - each line should be in the global namespace, line order
// should not matter
// - file should be easily parsable with bison
// - lines should typically not exceed 80 characters
//
int read_floorplan(struct fpga_model *model, FILE *f);
#define FP_DEFAULT 0x0000
#define FP_NO_HEADER 0x0001

View File

@ -320,7 +320,7 @@ const char* logicin_s(int wire, int routing_io);
enum fpgadev_type
{ DEV_NONE = 0,
DEV_LOGIC, DEV_TIEOFF, DEV_MACC, DEV_IOB,
DEV_ILOGIC, DEV_OLOGIC, DEV_IODELAY, DEV_BRAM16, DEV_BRAM8,
DEV_ILOGIC, DEV_OLOGIC, DEV_IODELAY, DEV_BRAM,
DEV_BUFH, DEV_BUFIO, DEV_BUFIO_FB, DEV_BUFPLL, DEV_BUFPLL_MCB,
DEV_BUFGMUX, DEV_BSCAN, DEV_DCM, DEV_PLL, DEV_ICAP,
DEV_POST_CRC_INTERNAL, DEV_STARTUP, DEV_SLAVE_SPI,
@ -329,7 +329,7 @@ enum fpgadev_type
#define FPGA_DEV_STR \
{ 0, \
"LOGIC", "TIEOFF", "MACC", "IOB", \
"ILOGIC", "OLOGIC", "IODELAY", "BRAM16", "BRAM8", \
"ILOGIC", "OLOGIC", "IODELAY", "BRAM", \
"BUFH", "BUFIO", "BUFIO_FB", "BUFPLL", "BUFPLL_MCB", \
"BUFGMUX", "BSCAN", "DCM", "PLL", "ICAP", \
"POST_CRC_INTERNAL", "STARTUP", "SLAVE_SPI", \
@ -350,7 +350,9 @@ typedef int dev_type_idx_t;
#define NO_DEV -1
#define FPGA_DEV(model, y, x, dev_idx) \
(((dev_idx) == NO_DEV) ? 0 : (&YX_TILE(model, y, x)->devs[dev_idx]))
(((int) (dev_idx) == NO_DEV) ? 0 : (&YX_TILE(model, y, x)->devs[dev_idx]))
enum { DEVCFG_FALSE = 1, DEVCFG_TRUE };
//
// DEV_LOGIC
@ -664,15 +666,45 @@ enum {
};
// requirements for valid bram
// rstram and rst_priority must be set for A and B.
// todo: haven't decided whether dev_bram should be one structure
// for 8+16 or two separate structures
struct fpgadev_bram16
{
};
// - rstram and rst_priority must be set for A and B.
struct fpgadev_bram8
enum { BRAM16 = 1, BRAM8 }; // subtype
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 };
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.
// see ug383
struct fpgadev_bram
{
int *data; // points to 1024 (BRAM16) or 512 (BRAM8) words (each 16+2=18 bits)
int ram_mode; // BRAM8 only: BRAM_TDP, BRAM_SDP, BRAM_SP (?)
int rst_type; // BRAM_RST_SYNC, BRAM_RST_ASYNC
// Output latch/register init value after configuration:
int out_init_a, out_init_b;
// Output latch/register value after reset:
int srval_a, srval_b;
int data_width_a, data_width_b; // BRAM_WIDTH_0..36
int write_mode_a, write_mode_b; // BRAM_WRITE_FIRST, BRAM_READ_FIRST, BRAM_NO_CHANGE
int doa_reg, dob_reg; // BRAM_OUTREG_ON, BRAM_OUTREG_OFF
int rst_priority_a, rst_priority_b; // BRAM_RST_PRIORITY_SR, BRAM_RST_PRIORITY_CE
int en_rstram_a, en_rstram_b; // DEVCFG_FALSE, DEVCFG_TRUE
// inverter bits (DEVCFG_FALSE, DEVCFG_TRUE)
// Default polarity is active high (rising edge for clka/clkb).
// With invert = true this will change to active low (falling
// edge for clka/clkb).
int clka_inv, clkb_inv;
int ena_inv, enb_inv;
int reg_cea_inv, reg_ceb_inv;
int rsta_inv, rstb_inv;
int wea_inv[4], web_inv[4]; // only 2 used for BRAM8 (wea-wel, web-weu)
};
//
@ -739,8 +771,10 @@ struct fpga_device
{
enum fpgadev_type type;
// subtypes:
// --- todo: wouldn't it be better to have the subtype inside the fpgadev structures?
// IOB: IOBM, IOBS
// LOGIC: LOGIC_M, LOGIC_L, LOGIC_X
// BRAM: BRAM16, BRAM8
int subtype;
int instantiated;
@ -761,8 +795,7 @@ struct fpga_device
struct fpgadev_bufgmux bufgmux;
struct fpgadev_bufio bufio;
struct fpgadev_bscan bscan;
struct fpgadev_bram16 bram16;
struct fpgadev_bram8 bram8;
struct fpgadev_bram bram;
} u;
};
@ -1200,54 +1233,3 @@ struct w_net
int add_conn_net(struct fpga_model* model, int add_pref, const struct w_net *net);
#if 0
bram16:
int *data; // points to 1024 words (each 16+2=18 bits)
int clka_inv; // DEVCFG_INV_Y, DEVCFG_INV_N
int clkb_inv;
int data_width_a; // 0,1,2,4,9,18,36
int data_width_b; // 0,1,2,4,9,18,36
int doa_reg; // BRAM_OUTREG_ON, BRAM_OUTREG_OFF
int dob_reg;
int ena_inv;
int enb_inv; // BRAM_ENB_INV_Y, BRAM_ENB_INV_N
int reg_cea_inv;
int reg_ceb_inv;
int rsta_inv;
int rstb_inv;
int wea_inv[4];
int web_inv[4];
int rst_type; // BRAM_RST_SYNC, BRAM_RST_ASYNC
int write_mode_a; // BRAM_WRITE_FIRST, BRAM_READ_FIRST, BRAM_NO_CHANGE
int write_mode_b;
int ram_mode; // BRAM_TDP, BRAM_SDP, BRAM_SP
int rst_priority_a; // BRAM_RST_PRIORITY_SR, BRAM_RST_PRIORITY_CE
int rst_priority_b; // BRAM_RST_PRIORITY_SR, BRAM_RST_PRIORITY_CE
int en_rstram_a; // DEVCFG_FALSE, DEVCFG_TRUE
int en_rstram_b; // DEVCFG_FALSE, DEVCFG_TRUE
bram8:
int *data; // points to 512 words (each 16+2=18 bits)
int clk_awr_inv; // DEVCFG_INV_Y, DEVCFG_INV_N
int clk_brd_inv;
int data_width_a; // 0,1,2,4,9,18,36
int data_width_b; // 0,1,2,4,9,18,36
int doa_reg; // BRAM_OUTREG_ON, BRAM_OUTREG_OFF
int dob_reg;
int en_awr_inv;
int en_brd_inv; // BRAM_ENB_INV_Y, BRAM_ENB_INV_N
int reg_cea_inv;
int reg_ceb_reg_ce_inv;
int rsta_inv;
int rstb_rst_inv;
int wea_wel_inv[2];
int web_weu_inv[2];
int rst_type; // BRAM_RST_SYNC, BRAM_RST_ASYNC
int write_mode_a; // BRAM_WRITE_FIRST, BRAM_READ_FIRST, BRAM_NO_CHANGE
int write_mode_b;
int ram_mode; // BRAM_TDP, BRAM_SDP, BRAM_SP
int rst_priority_a; // BRAM_RST_PRIORITY_SR, BRAM_RST_PRIORITY_CE
int rst_priority_b; // BRAM_RST_PRIORITY_SR, BRAM_RST_PRIORITY_CE
int en_rstram_a; // DEVCFG_FALSE, DEVCFG_TRUE
int en_rstram_b; // DEVCFG_FALSE, DEVCFG_TRUE
#endif

View File

@ -3197,7 +3197,7 @@ static int connect_clk_sr(struct fpga_model* model, const char* clk_sr)
for (x = LEFT_SIDE_WIDTH; x < model->x_width - RIGHT_SIDE_WIDTH; x++) {
if (is_atx(X_FABRIC_BRAM_ROUTING_COL, model, x)) {
for (y = TOP_IO_TILES; y < model->y_height - BOT_IO_TILES; y++) {
if (has_device(model, y, x+2, DEV_BRAM16)) {
if (has_device(model, y, x+2, DEV_BRAM)) {
for (i = 0; i <= 3; i++) {
struct w_net n = {
.last_inc = 1, .num_pts = 3, .pt =

View File

@ -146,11 +146,9 @@ int init_devices(struct fpga_model* model)
for (y = TOP_IO_TILES; y < model->y_height-BOT_IO_TILES; y++) {
if (!(YX_TILE(model, y, x)->flags & TF_BRAM_DEV))
continue;
if ((rc = add_dev(model, y, x, DEV_BRAM16, 0)))
if ((rc = add_dev(model, y, x, DEV_BRAM, 0)))
goto fail;
if ((rc = add_dev(model, y, x, DEV_BRAM8, 0)))
goto fail;
if ((rc = add_dev(model, y, x, DEV_BRAM8, 0)))
if ((rc = add_dev(model, y, x, DEV_BRAM, 0)))
goto fail;
}
}

View File

@ -1722,7 +1722,7 @@ static int init_bram(struct fpga_model *model)
if (!is_atx(X_FABRIC_BRAM_COL, model, x))
continue;
for (y = TOP_IO_TILES; y < model->y_height - BOT_IO_TILES; y++) {
if (!has_device(model, y, x, DEV_BRAM16))
if (!has_device(model, y, x, DEV_BRAM))
continue;
{ const char* pairs[] = {
"BRAM_CLK%c_INT1", "RAMB16BWER_CLK%c",

View File

@ -285,6 +285,7 @@ const struct xc_die *xc_die_info(int idcode)
case XC6SLX9: return &xc6slx9_info;
}
HERE();
fprintf(stderr, "#E unknown id_code %i\n", idcode);
return 0;
}

View File

@ -32,7 +32,7 @@ static int print_line(const struct line_buf* line)
if (!line->buf[0]) return 0;
if (!line->sequence_size || line->left_digit_start_o < 0) {
printf(line->buf);
printf("%s", line->buf);
return 0;
}
if (line->right_digit_start_o < 0)
@ -53,7 +53,7 @@ static int print_line(const struct line_buf* line)
line->right_digit_base,
line->right_digit_base+line->sequence_size,
&line->buf[line->right_digit_end_o]);
printf(buf);
printf("%s", buf);
return 0;
}

View File

@ -5,6 +5,7 @@
# For details see the UNLICENSE file at the root of the source tree.
#
CC = clang-3.6
LDLIBS += `pkg-config libftdi --libs`
OBJS := mini-jtag.o load-bits.o jtag.o

View File

@ -409,7 +409,7 @@ int main(int argc, char** argv)
// print first 800 lines
for (i = 0; i < 800; i++) {
if (i >= s_numlines) break;
printf(s_lines[i]);
printf("%s", s_lines[i]);
}
// move up last 200 lines to beginning of buffer
if (s_numlines > i) {