very first steps in autotester

This commit is contained in:
Wolfgang Spraul 2012-08-14 12:33:02 +02:00
parent 750bdba173
commit c9075b045c
12 changed files with 231 additions and 93 deletions

4
.gitignore vendored
View File

@ -24,3 +24,7 @@ floorplan.o
control.o
autotest
autotest.o
bits.o
fp2bit
fp2bit.o
autotest.tmp/

View File

@ -17,17 +17,21 @@ LDLIBS += `pkg-config libxml-2.0 --libs`
MODEL_OBJ = model_main.o model_tiles.o model_devices.o model_ports.o model_conns.o model_switches.o model_helper.o
all: autotest bit2txt draw_svg_tiles new_fp hstrrep sort_seq merge_seq
all: autotest bit2txt draw_svg_tiles new_fp fp2bit hstrrep sort_seq merge_seq
autotest: autotest.o $(MODEL_OBJ) floorplan.o control.o helper.o
autotest: autotest.o $(MODEL_OBJ) floorplan.o control.o helper.o model.h
new_fp: new_fp.o $(MODEL_OBJ) floorplan.o helper.o
new_fp.o: new_fp.c floorplan.h model.h helper.h
floorplan.o: floorplan.c floorplan.h
fp2bit: fp2bit.c $(MODEL_OBJ) bits.o helper.o
control.o: control.c control.h
floorplan.o: floorplan.c floorplan.h model.h
bits.o: bits.c bits.h model.h
control.o: control.c control.h model.h
draw_svg_tiles: draw_svg_tiles.o $(MODEL_OBJ) helper.o

View File

@ -17,9 +17,32 @@ time_t g_start_time;
#define MEMUSAGE() printf("O memusage %i\n", get_vm_mb());
#define TIME_AND_MEM() TIMESTAMP(); MEMUSAGE()
#define AUTOTEST_TMP_DIR "autotest.tmp"
static int dump_file(const char* path)
{
char line[1024];
FILE* f;
printf("O begin dump %s\n", path);
f = fopen(path, "r");
EXIT(!f);
while (fgets(line, sizeof(line), f)) {
if (!strncmp(line, "--- ", 4)
|| !strncmp(line, "+++ ", 4)
|| !strncmp(line, "@@ ", 3))
continue;
printf(line);
}
fclose(f);
printf("O end dump %s\n", path);
return 0;
}
int main(int argc, char** argv)
{
struct fpga_model model;
FILE* dest_f;
int rc;
printf("\n");
@ -39,12 +62,25 @@ int main(int argc, char** argv)
printf("O Done\n");
TIME_AND_MEM();
// pick 2 input IOBs, one output IOB and configure them
// pick 1 logic block and configure
// printf floorplan
// start routing, step by step
// after each step, printf floorplan diff (test_diff.sh)
// popen/fork/pipe
// todo: pick 2 input IOBs, one output IOB and configure them
// todo: pick 1 logic block and configure
mkdir(AUTOTEST_TMP_DIR, S_IRWXU|S_IRWXG|S_IROTH|S_IXOTH);
dest_f = fopen(AUTOTEST_TMP_DIR "/test_0001.fp", "w");
EXIT(!dest_f);
rc = printf_devices(dest_f, &model, /*config_only*/ 1);
EXIT(rc);
rc = printf_switches(dest_f, &model, /*enabled_only*/ 1);
EXIT(rc);
fclose(dest_f);
rc = system("./autotest_diff.sh autotest.tmp/test_0001.fp");
EXIT(rc);
rc = dump_file(AUTOTEST_TMP_DIR "/test_0001.diff");
EXIT(rc);
// todo: start routing, step by step
// todo: after each step, printf floorplan diff (test_diff.sh)
// todo: popen/fork/pipe
printf("\n");
printf("O Test suite completed.\n");

2
autotest_diff.sh Executable file
View File

@ -0,0 +1,2 @@
#!/bin/bash
diff -u /dev/null $1 > autotest.tmp/test_0001.diff || true

9
bits.c Normal file
View File

@ -0,0 +1,9 @@
//
// Author: Wolfgang Spraul
//
// This is free and unencumbered software released into the public domain.
// For details see the UNLICENSE file at the root of the source tree.
//
#include "model.h"
#include "bits.h"

6
bits.h Normal file
View File

@ -0,0 +1,6 @@
//
// Author: Wolfgang Spraul
//
// This is free and unencumbered software released into the public domain.
// For details see the UNLICENSE file at the root of the source tree.
//

View File

@ -8,55 +8,56 @@
#include "model.h"
#include "floorplan.h"
void printf_version(void)
void printf_version(FILE* f)
{
printf("fpga_floorplan_format 1\n");
fprintf(f, "fpga_floorplan_format 1\n");
}
#define PRINT_FLAG(f) if (tf & f) { printf (" %s", #f); tf &= ~f; }
#define PRINT_FLAG(fp, flag) if ((tf) & (flag)) \
{ fprintf (fp, " %s", #flag); tf &= ~(flag); }
int printf_tiles(struct fpga_model* model)
int printf_tiles(FILE* f, struct fpga_model* model)
{
struct fpga_tile* tile;
int x, y;
for (x = 0; x < model->x_width; x++) {
printf("\n");
fprintf(f, "\n");
for (y = 0; y < model->y_height; y++) {
tile = &model->tiles[y*model->x_width + x];
if (tile->type != NA)
printf("tile y%02i x%02i name %s\n", y, x,
fprintf(f, "tile y%02i x%02i name %s\n", y, x,
fpga_tiletype_str(tile->type));
if (tile->flags) {
int tf = tile->flags;
printf("tile y%02i x%02i flags", y, x);
fprintf(f, "tile y%02i x%02i flags", y, x);
PRINT_FLAG(TF_FABRIC_ROUTING_COL);
PRINT_FLAG(TF_FABRIC_LOGIC_COL);
PRINT_FLAG(TF_FABRIC_BRAM_VIA_COL);
PRINT_FLAG(TF_FABRIC_MACC_VIA_COL);
PRINT_FLAG(TF_FABRIC_BRAM_COL);
PRINT_FLAG(TF_FABRIC_MACC_COL);
PRINT_FLAG(TF_ROUTING_NO_IO);
PRINT_FLAG(TF_BRAM_DEV);
PRINT_FLAG(TF_MACC_DEV);
PRINT_FLAG(TF_LOGIC_XL_DEV);
PRINT_FLAG(TF_LOGIC_XM_DEV);
PRINT_FLAG(TF_IOLOGIC_DELAY_DEV);
PRINT_FLAG(TF_DCM_DEV);
PRINT_FLAG(TF_PLL_DEV);
PRINT_FLAG(TF_WIRED);
PRINT_FLAG(f, TF_FABRIC_ROUTING_COL);
PRINT_FLAG(f, TF_FABRIC_LOGIC_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);
if (tf) printf(" 0x%x", tf);
printf("\n");
if (tf) fprintf(f, " 0x%x", tf);
fprintf(f, "\n");
}
}
}
return 0;
}
int printf_devices(struct fpga_model* model)
int printf_devices(FILE* f, struct fpga_model* model, int config_only)
{
int x, y, i;
struct fpga_tile* tile;
@ -65,90 +66,92 @@ int printf_devices(struct fpga_model* model)
for (y = 0; y < model->y_height; y++) {
tile = YX_TILE(model, y, x);
for (i = 0; i < tile->num_devices; i++) {
if (config_only && !(tile->devices[i].instantiated))
continue;
switch (tile->devices[i].type) {
case DEV_LOGIC_M:
printf("device y%02i x%02i SLICEM\n", y, x);
fprintf(f, "device y%02i x%02i SLICEM\n", y, x);
break;
case DEV_LOGIC_L:
printf("device y%02i x%02i SLICEL\n", y, x);
fprintf(f, "device y%02i x%02i SLICEL\n", y, x);
break;
case DEV_LOGIC_X:
printf("device y%02i x%02i SLICEX\n", y, x);
fprintf(f, "device y%02i x%02i SLICEX\n", y, x);
break;
case DEV_MACC:
printf("device y%02i x%02i DSP48A1\n", y, x);
fprintf(f, "device y%02i x%02i DSP48A1\n", y, x);
break;
case DEV_TIEOFF:
printf("device y%02i x%02i TIEOFF\n", y, x);
fprintf(f, "device y%02i x%02i TIEOFF\n", y, x);
break;
case DEV_IOBM:
printf("device y%02i x%02i IOBM\n", y, x);
fprintf(f, "device y%02i x%02i IOBM\n", y, x);
break;
case DEV_IOBS:
printf("device y%02i x%02i IOBS\n", y, x);
fprintf(f, "device y%02i x%02i IOBS\n", y, x);
break;
case DEV_ILOGIC:
printf("device y%02i x%02i ILOGIC2\n", y, x);
fprintf(f, "device y%02i x%02i ILOGIC2\n", y, x);
break;
case DEV_OLOGIC:
printf("device y%02i x%02i OLOGIC2\n", y, x);
fprintf(f, "device y%02i x%02i OLOGIC2\n", y, x);
break;
case DEV_IODELAY:
printf("device y%02i x%02i IODELAY2\n", y, x);
fprintf(f, "device y%02i x%02i IODELAY2\n", y, x);
break;
case DEV_BRAM16:
printf("device y%02i x%02i RAMB16BWER\n", y, x);
fprintf(f, "device y%02i x%02i RAMB16BWER\n", y, x);
break;
case DEV_BRAM8:
printf("device y%02i x%02i RAMB8BWER\n", y, x);
fprintf(f, "device y%02i x%02i RAMB8BWER\n", y, x);
break;
case DEV_BUFH:
printf("device y%02i x%02i BUFH\n", y, x);
fprintf(f, "device y%02i x%02i BUFH\n", y, x);
break;
case DEV_BUFIO:
printf("device y%02i x%02i BUFIO2\n", y, x);
fprintf(f, "device y%02i x%02i BUFIO2\n", y, x);
break;
case DEV_BUFIO_FB:
printf("device y%02i x%02i BUFIO2FB\n", y, x);
fprintf(f, "device y%02i x%02i BUFIO2FB\n", y, x);
break;
case DEV_BUFPLL:
printf("device y%02i x%02i BUFPLL\n", y, x);
fprintf(f, "device y%02i x%02i BUFPLL\n", y, x);
break;
case DEV_BUFPLL_MCB:
printf("device y%02i x%02i BUFPLL_MCB\n", y, x);
fprintf(f, "device y%02i x%02i BUFPLL_MCB\n", y, x);
break;
case DEV_BUFGMUX:
printf("device y%02i x%02i BUFGMUX\n", y, x);
fprintf(f, "device y%02i x%02i BUFGMUX\n", y, x);
break;
case DEV_BSCAN:
printf("device y%02i x%02i BSCAN\n", y, x);
fprintf(f, "device y%02i x%02i BSCAN\n", y, x);
break;
case DEV_DCM:
printf("device y%02i x%02i DCM\n", y, x);
fprintf(f, "device y%02i x%02i DCM\n", y, x);
break;
case DEV_PLL:
printf("device y%02i x%02i PLL\n", y, x);
fprintf(f, "device y%02i x%02i PLL\n", y, x);
break;
case DEV_ICAP:
printf("device y%02i x%02i ICAP\n", y, x);
fprintf(f, "device y%02i x%02i ICAP\n", y, x);
break;
case DEV_POST_CRC_INTERNAL:
printf("device y%02i x%02i POST_CRC_INTERNAL\n", y, x);
fprintf(f, "device y%02i x%02i POST_CRC_INTERNAL\n", y, x);
break;
case DEV_STARTUP:
printf("device y%02i x%02i STARTUP\n", y, x);
fprintf(f, "device y%02i x%02i STARTUP\n", y, x);
break;
case DEV_SLAVE_SPI:
printf("device y%02i x%02i SLAVE_SPI\n", y, x);
fprintf(f, "device y%02i x%02i SLAVE_SPI\n", y, x);
break;
case DEV_SUSPEND_SYNC:
printf("device y%02i x%02i SUSPEND_SYNC\n", y, x);
fprintf(f, "device y%02i x%02i SUSPEND_SYNC\n", y, x);
break;
case DEV_OCT_CALIBRATE:
printf("device y%02i x%02i OCT_CALIBRATE\n", y, x);
fprintf(f, "device y%02i x%02i OCT_CALIBRATE\n", y, x);
break;
case DEV_SPI_ACCESS:
printf("device y%02i x%02i SPI_ACCESS\n", y, x);
fprintf(f, "device y%02i x%02i SPI_ACCESS\n", y, x);
break;
}
}
@ -157,7 +160,7 @@ int printf_devices(struct fpga_model* model)
return 0;
}
int printf_ports(struct fpga_model* model)
int printf_ports(FILE* f, struct fpga_model* model)
{
struct fpga_tile* tile;
const char* conn_point_name_src;
@ -186,16 +189,17 @@ int printf_ports(struct fpga_model* model)
}
if (!first_port_printed) {
first_port_printed = 1;
printf("\n");
fprintf(f, "\n");
}
printf("port y%02i x%02i %s\n", y, x, conn_point_name_src);
fprintf(f, "port y%02i x%02i %s\n",
y, x, conn_point_name_src);
}
}
}
return 0;
}
int printf_conns(struct fpga_model* model)
int printf_conns(FILE* f, struct fpga_model* model)
{
struct fpga_tile* tile;
char tmp_line[512];
@ -237,7 +241,7 @@ int printf_conns(struct fpga_model* model)
if (!first_conn_printed) {
first_conn_printed = 1;
printf("\n");
fprintf(f, "\n");
}
sprintf(tmp_line, "static_conn y%02i x%02i %s ",
y, x, conn_point_name_src);
@ -246,7 +250,7 @@ int printf_conns(struct fpga_model* model)
tmp_line[k++] = ' ';
sprintf(&tmp_line[k], "y%02i x%02i %s\n",
other_tile_y, other_tile_x, other_tile_connpt_str);
printf(tmp_line);
fprintf(f, tmp_line);
}
}
}
@ -254,11 +258,11 @@ int printf_conns(struct fpga_model* model)
return 0;
}
int printf_switches(struct fpga_model* model)
int printf_switches(FILE* f, struct fpga_model* model, int enabled_only)
{
struct fpga_tile* tile;
int x, y, i, from_connpt_o, to_connpt_o, from_str_i, to_str_i;
int first_switch_printed, is_bidirectional;
int first_switch_printed, is_bidirectional, is_on;
const char* from_str, *to_str;
for (x = 0; x < model->x_width; x++) {
@ -270,6 +274,7 @@ int printf_switches(struct fpga_model* model)
from_connpt_o = (tile->switches[i] & 0x3FFF8000) >> 15;
to_connpt_o = tile->switches[i] & 0x00007FFF;
is_bidirectional = (tile->switches[i] & SWITCH_BIDIRECTIONAL) != 0;
is_on = (tile->switches[i] & SWITCH_ON) != 0;
from_str_i = tile->conn_point_names[from_connpt_o*2+1];
to_str_i = tile->conn_point_names[to_connpt_o*2+1];
@ -281,12 +286,15 @@ int printf_switches(struct fpga_model* model)
__FILE__, __LINE__, from_str_i, to_str_i);
continue;
}
if (enabled_only && !is_on)
continue;
if (!first_switch_printed) {
first_switch_printed = 1;
printf("\n");
fprintf(f, "\n");
}
printf("switch y%02i x%02i %s %s %s\n", y, x, from_str,
is_bidirectional ? "<->" : "->", to_str);
fprintf(f, "switch y%02i x%02i %s %s %s\n",
y, x, from_str, is_bidirectional
? "<->" : "->", to_str);
}
}
}

View File

@ -24,9 +24,9 @@
// - lines should typically not exceed 80 characters
//
void printf_version(void);
int printf_tiles(struct fpga_model* model);
int printf_devices(struct fpga_model* model);
int printf_ports(struct fpga_model* model);
int printf_conns(struct fpga_model* model);
int printf_switches(struct fpga_model* model);
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_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 enabled_only);

23
fp2bit.c Normal file
View File

@ -0,0 +1,23 @@
//
// Author: Wolfgang Spraul
//
// This is free and unencumbered software released into the public domain.
// For details see the UNLICENSE file at the root of the source tree.
//
#include "model.h"
#include "bits.h"
int main(int argc, char** argv)
{
struct fpga_model model;
int rc;
if ((rc = fpga_build_model(&model, XC6SLX9_ROWS, XC6SLX9_COLUMNS,
XC6SLX9_LEFT_WIRING, XC6SLX9_RIGHT_WIRING)))
goto fail;
return EXIT_SUCCESS;
fail:
return rc;
}

58
model.h
View File

@ -301,6 +301,10 @@ enum fpgadev_type
DEV_SPI_ACCESS
};
// All device configuration is structured so that the value
// 0 is never a valid configured setting. That way all config
// data can safely be initialized to 0 meaning unconfigured.
struct fpgadev_logic_x
{
int a;
@ -316,13 +320,41 @@ struct fpgadev_logic_m
int c;
};
typedef char IOSTANDARD[32];
#define IO_LVCMOS33 "LVCMOS33"
enum { BYPASS_MUX_I = 1, BYPASS_MUX_O, BYPASS_MUX_T };
enum { IMUX_I_B = 1, IMUX_I };
enum { SLEW_SLOW = 1, SLEW_FAST, SLEW_QUIETIO };
enum { SUSP_LAST_VAL = 1, SUSP_3STATE, SUSP_3STATE_PULLUP,
SUSP_3STATE_PULLDOWN, SUSP_3STATE_KEEPER, SUSP_3STATE_OCT_ON };
enum { ITERM_NONE = 1, ITERM_UNTUNED_25, ITERM_UNTUNED_50,
ITERM_UNTUNED_75 };
enum { OTERM_NONE = 1, OTERM_UNTUNED_25, OTERM_UNTUNED_50,
OTERM_UNTUNED_75 };
struct fpgadev_iob
{
IOSTANDARD istandard;
IOSTANDARD ostandard;
int bypass_mux;
int imux;
int drive_strength; // supports 2,4,6,8,12,16 and 24
int slew;
int o_used;
int suspend;
int in_term;
int out_term;
};
struct fpga_device
{
enum fpgadev_type type;
int instantiated;
union {
struct fpgadev_logic_m log_m;
struct fpgadev_logic_l log_l;
struct fpgadev_logic_x log_x;
struct fpgadev_iob iob;
};
};
@ -335,7 +367,7 @@ struct fpga_tile
enum fpga_tile_type type;
int flags;
// expect up to 64 devices per tile
// we currently support a maximum of 32 devices per tile
int num_devices;
struct fpga_device devices[32];
@ -387,17 +419,29 @@ int has_device(struct fpga_model* model, int y, int x, int dev);
int add_connpt_2(struct fpga_model* model, int y, int x,
const char* connpt_name, const char* suffix1, const char* suffix2);
typedef int (*add_conn_f)(struct fpga_model* model, int y1, int x1, const char* name1, int y2, int x2, const char* name2);
typedef int (*add_conn_f)(struct fpga_model* model,
int y1, int x1, const char* name1,
int y2, int x2, const char* name2);
#define NOPREF_BI_F add_conn_bi
#define PREF_BI_F add_conn_bi_pref
#define NOPREF_UNI_F add_conn_uni
#define PREF_UNI_F add_conn_uni_pref
int add_conn_uni(struct fpga_model* model, int y1, int x1, const char* name1, int y2, int x2, const char* name2);
int add_conn_uni_pref(struct fpga_model* model, int y1, int x1, const char* name1, int y2, int x2, const char* name2);
int add_conn_bi(struct fpga_model* model, int y1, int x1, const char* name1, int y2, int x2, const char* name2);
int add_conn_bi_pref(struct fpga_model* model, int y1, int x1, const char* name1, int y2, int x2, const char* name2);
int add_conn_range(struct fpga_model* model, add_conn_f add_conn_func, int y1, int x1, const char* name1, int start1, int last1, int y2, int x2, const char* name2, int start2);
int add_conn_uni(struct fpga_model* model,
int y1, int x1, const char* name1,
int y2, int x2, const char* name2);
int add_conn_uni_pref(struct fpga_model* model,
int y1, int x1, const char* name1,
int y2, int x2, const char* name2);
int add_conn_bi(struct fpga_model* model,
int y1, int x1, const char* name1,
int y2, int x2, const char* name2);
int add_conn_bi_pref(struct fpga_model* model,
int y1, int x1, const char* name1,
int y2, int x2, const char* name2);
int add_conn_range(struct fpga_model* model, add_conn_f add_conn_func,
int y1, int x1, const char* name1, int start1, int last1,
int y2, int x2, const char* name2, int start2);
// COUNT_DOWN can be OR'ed to start_count to make
// the enumerated wires count from start_count down.

View File

@ -38,8 +38,10 @@ int fpga_build_model(struct fpga_model* model, int fpga_rows, const char* column
rc = init_conns(model);
if (rc) return rc;
#if 0
rc = init_switches(model);
if (rc) return rc;
#endif
return 0;
}

View File

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