autotester
This commit is contained in:
parent
b1d665e84b
commit
3487a8ad7b
8
Makefile
8
Makefile
|
@ -21,13 +21,17 @@ 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 model.h
|
||||
|
||||
autotest.c: model.h floorplan.h control.h
|
||||
|
||||
new_fp: new_fp.o $(MODEL_OBJ) floorplan.o helper.o
|
||||
|
||||
new_fp.o: new_fp.c floorplan.h model.h helper.h
|
||||
|
||||
fp2bit: fp2bit.c $(MODEL_OBJ) bits.o helper.o
|
||||
fp2bit: fp2bit.o $(MODEL_OBJ) floorplan.o control.o bits.o helper.o
|
||||
|
||||
floorplan.o: floorplan.c floorplan.h model.h
|
||||
fp2bit.o: fp2bit.c model.h floorplan.h bits.h helper.h
|
||||
|
||||
floorplan.o: floorplan.c floorplan.h model.h control.h
|
||||
|
||||
bits.o: bits.c bits.h model.h
|
||||
|
||||
|
|
2
README
2
README
|
@ -4,7 +4,7 @@ Design Principles
|
|||
- plain C, no C++
|
||||
- simple Makefiles
|
||||
- text-based file formats
|
||||
- no documentation - read the sources
|
||||
- no documentation - please read the sources
|
||||
- automatic test suite
|
||||
|
||||
Libraries
|
||||
|
|
|
@ -85,7 +85,13 @@ int main(int argc, char** argv)
|
|||
dev->iob.slew = SLEW_SLOW;
|
||||
dev->iob.suspend = SUSP_3STATE;
|
||||
|
||||
// todo: configure logic
|
||||
// configure logic
|
||||
dev = fpga_dev(&model, /*y*/ 68, /*x*/ 13, DEV_LOGIC, /*LOGIC_X*/ 1);
|
||||
EXIT(!dev);
|
||||
dev->instantiated = 1;
|
||||
dev->logic.D_used = 1;
|
||||
rc = fpga_set_lut(&model, dev, D6_LUT, "A3", ZTERM);
|
||||
EXIT(rc);
|
||||
|
||||
mkdir(AUTOTEST_TMP_DIR, S_IRWXU|S_IRWXG|S_IROTH|S_IXOTH);
|
||||
dest_f = fopen(AUTOTEST_TMP_DIR "/test_0001.fp", "w");
|
||||
|
|
5
bits.c
5
bits.c
|
@ -7,3 +7,8 @@
|
|||
|
||||
#include "model.h"
|
||||
#include "bits.h"
|
||||
|
||||
int write_bits(FILE* f, struct fpga_model* model)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
|
2
bits.h
2
bits.h
|
@ -4,3 +4,5 @@
|
|||
// This is free and unencumbered software released into the public domain.
|
||||
// For details see the UNLICENSE file at the root of the source tree.
|
||||
//
|
||||
|
||||
int write_bits(FILE* f, struct fpga_model* model);
|
||||
|
|
73
control.c
73
control.c
|
@ -156,6 +156,50 @@ int fpga_find_iob(struct fpga_model* model, const char* sitename,
|
|||
return -1;
|
||||
}
|
||||
|
||||
const char* fpga_iob_sitename(struct fpga_model* model, int y, int x,
|
||||
int idx)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (y == TOP_OUTER_ROW) {
|
||||
for (i = 0; i < sizeof(xc6slx9_iob_top)/sizeof(xc6slx9_iob_top[0]); i++) {
|
||||
if (xc6slx9_iob_right[i].xy == x) {
|
||||
if (idx < 0 || idx > 3) return 0;
|
||||
return xc6slx9_iob_top[i].name[idx];
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
if (y == model->y_height-BOT_OUTER_ROW) {
|
||||
for (i = 0; i < sizeof(xc6slx9_iob_bottom)/sizeof(xc6slx9_iob_bottom[0]); i++) {
|
||||
if (xc6slx9_iob_bottom[i].xy == x) {
|
||||
if (idx < 0 || idx > 3) return 0;
|
||||
return xc6slx9_iob_bottom[i].name[idx];
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
if (x == LEFT_OUTER_COL) {
|
||||
for (i = 0; i < sizeof(xc6slx9_iob_left)/sizeof(xc6slx9_iob_left[0]); i++) {
|
||||
if (xc6slx9_iob_left[i].xy == y) {
|
||||
if (idx < 0 || idx > 1) return 0;
|
||||
return xc6slx9_iob_left[i].name[idx];
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
if (x == model->x_width-RIGHT_OUTER_O) {
|
||||
for (i = 0; i < sizeof(xc6slx9_iob_right)/sizeof(xc6slx9_iob_right[0]); i++) {
|
||||
if (xc6slx9_iob_right[i].xy == y) {
|
||||
if (idx < 0 || idx > 1) return 0;
|
||||
return xc6slx9_iob_right[i].name[idx];
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct fpga_device* fpga_dev(struct fpga_model* model,
|
||||
int y, int x, enum fpgadev_type type, int idx)
|
||||
{
|
||||
|
@ -173,3 +217,32 @@ struct fpga_device* fpga_dev(struct fpga_model* model,
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define MAX_LUT_LEN 512
|
||||
|
||||
int fpga_set_lut(struct fpga_model* model, struct fpga_device* dev,
|
||||
int which_lut, const char* lut_str, int lut_len)
|
||||
{
|
||||
char** ptr;
|
||||
|
||||
if (dev->type != DEV_LOGIC)
|
||||
return -1;
|
||||
switch (which_lut) {
|
||||
case A6_LUT: ptr = &dev->logic.A6_lut; break;
|
||||
case B6_LUT: ptr = &dev->logic.B6_lut; break;
|
||||
case C6_LUT: ptr = &dev->logic.C6_lut; break;
|
||||
case D6_LUT: ptr = &dev->logic.D6_lut; break;
|
||||
default: return -1;
|
||||
}
|
||||
if (!(*ptr)) {
|
||||
*ptr = malloc(MAX_LUT_LEN);
|
||||
if (!(*ptr)) {
|
||||
OUT_OF_MEM();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (lut_len == ZTERM) lut_len = strlen(lut_str);
|
||||
memcpy(*ptr, lut_str, lut_len);
|
||||
(*ptr)[lut_len] = 0;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -8,5 +8,13 @@
|
|||
int fpga_find_iob(struct fpga_model* model, const char* sitename,
|
||||
int* y, int* x, int* idx);
|
||||
|
||||
const char* fpga_iob_sitename(struct fpga_model* model, int y, int x,
|
||||
int idx);
|
||||
|
||||
struct fpga_device* fpga_dev(struct fpga_model* model,
|
||||
int y, int x, enum fpgadev_type type, int idx);
|
||||
|
||||
enum { A6_LUT, B6_LUT, C6_LUT, D6_LUT };
|
||||
// lut_len can be -1 (ZTERM)
|
||||
int fpga_set_lut(struct fpga_model* model, struct fpga_device* dev,
|
||||
int which_lut, const char* lut_str, int lut_len);
|
||||
|
|
276
floorplan.c
276
floorplan.c
|
@ -8,6 +8,7 @@
|
|||
#include <stdarg.h>
|
||||
|
||||
#include "model.h"
|
||||
#include "control.h"
|
||||
#include "floorplan.h"
|
||||
|
||||
void printf_version(FILE* f)
|
||||
|
@ -146,7 +147,7 @@ static int printf_IOB(FILE* f, struct fpga_model* model,
|
|||
case 0: break; default: EXIT(1);
|
||||
}
|
||||
if (tile->devs[i].iob.O_used)
|
||||
printf_wrap(f, line, plen, "o_used");
|
||||
printf_wrap(f, line, plen, "O_used");
|
||||
switch (tile->devs[i].iob.suspend) {
|
||||
case SUSP_LAST_VAL:
|
||||
printf_wrap(f, line, plen, "suspend DRIVE_LAST_VALUE");
|
||||
|
@ -204,6 +205,109 @@ static int printf_IOB(FILE* f, struct fpga_model* model,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int read_IOB_attr(struct fpga_model* model, struct fpga_device* dev,
|
||||
const char* w1, int w1_len, const char* w2, int w2_len)
|
||||
{
|
||||
// First the one-word attributes.
|
||||
if (!str_cmp(w1, w1_len, "O_used", ZTERM)) {
|
||||
dev->iob.O_used = 1;
|
||||
goto inst_1;
|
||||
}
|
||||
// The remaining attributes all require 2 words.
|
||||
if (w2_len < 1) return 0;
|
||||
if (!str_cmp(w1, w1_len, "type", ZTERM))
|
||||
return 2; // no reason for instantiation
|
||||
if (!str_cmp(w1, w1_len, "istd", ZTERM)) {
|
||||
memcpy(dev->iob.istandard, w2, w2_len);
|
||||
dev->iob.istandard[w2_len] = 0;
|
||||
goto inst_2;
|
||||
}
|
||||
if (!str_cmp(w1, w1_len, "ostd", ZTERM)) {
|
||||
memcpy(dev->iob.ostandard, w2, w2_len);
|
||||
dev->iob.ostandard[w2_len] = 0;
|
||||
goto inst_2;
|
||||
}
|
||||
if (!str_cmp(w1, w1_len, "bypass_mux", ZTERM)) {
|
||||
if (!str_cmp(w2, w2_len, "I", ZTERM))
|
||||
dev->iob.bypass_mux = BYPASS_MUX_I;
|
||||
else if (!str_cmp(w2, w2_len, "O", ZTERM))
|
||||
dev->iob.bypass_mux = BYPASS_MUX_O;
|
||||
else if (!str_cmp(w2, w2_len, "T", ZTERM))
|
||||
dev->iob.bypass_mux = BYPASS_MUX_T;
|
||||
else return 0;
|
||||
goto inst_2;
|
||||
}
|
||||
if (!str_cmp(w1, w1_len, "imux", ZTERM)) {
|
||||
if (!str_cmp(w2, w2_len, "I_B", ZTERM))
|
||||
dev->iob.I_mux = IMUX_I_B;
|
||||
else if (!str_cmp(w2, w2_len, "I", ZTERM))
|
||||
dev->iob.I_mux = IMUX_I;
|
||||
else return 0;
|
||||
goto inst_2;
|
||||
}
|
||||
if (!str_cmp(w1, w1_len, "strength", ZTERM)) {
|
||||
dev->iob.drive_strength = to_i(w2, w2_len);
|
||||
goto inst_2;
|
||||
}
|
||||
if (!str_cmp(w1, w1_len, "slew", ZTERM)) {
|
||||
if (!str_cmp(w2, w2_len, "SLOW", ZTERM))
|
||||
dev->iob.slew = SLEW_SLOW;
|
||||
else if (!str_cmp(w2, w2_len, "FAST", ZTERM))
|
||||
dev->iob.slew = SLEW_FAST;
|
||||
else if (!str_cmp(w2, w2_len, "QUIETIO", ZTERM))
|
||||
dev->iob.slew = SLEW_QUIETIO;
|
||||
else return 0;
|
||||
goto inst_2;
|
||||
}
|
||||
if (!str_cmp(w1, w1_len, "suspend", 7)) {
|
||||
if (!str_cmp(w2, w2_len, "DRIVE_LAST_VALUE", ZTERM))
|
||||
dev->iob.suspend = SUSP_LAST_VAL;
|
||||
else if (!str_cmp(w2, w2_len, "3STATE", ZTERM))
|
||||
dev->iob.suspend = SUSP_3STATE;
|
||||
else if (!str_cmp(w2, w2_len, "3STATE_PULLUP", ZTERM))
|
||||
dev->iob.suspend = SUSP_3STATE_PULLUP;
|
||||
else if (!str_cmp(w2, w2_len, "3STATE_PULLDOWN", ZTERM))
|
||||
dev->iob.suspend = SUSP_3STATE_PULLDOWN;
|
||||
else if (!str_cmp(w2, w2_len, "3STATE_KEEPER", ZTERM))
|
||||
dev->iob.suspend = SUSP_3STATE_KEEPER;
|
||||
else if (!str_cmp(w2, w2_len, "3STATE_OCT_ON", ZTERM))
|
||||
dev->iob.suspend = SUSP_3STATE_OCT_ON;
|
||||
else return 0;
|
||||
goto inst_2;
|
||||
}
|
||||
if (!str_cmp(w1, w1_len, "in_term", ZTERM)) {
|
||||
if (!str_cmp(w2, w2_len, "NONE", ZTERM))
|
||||
dev->iob.in_term = ITERM_NONE;
|
||||
else if (!str_cmp(w2, w2_len, "UNTUNED_SPLIT_25", ZTERM))
|
||||
dev->iob.in_term = ITERM_UNTUNED_25;
|
||||
else if (!str_cmp(w2, w2_len, "UNTUNED_SPLIT_50", ZTERM))
|
||||
dev->iob.in_term = ITERM_UNTUNED_50;
|
||||
else if (!str_cmp(w2, w2_len, "UNTUNED_SPLIT_75", ZTERM))
|
||||
dev->iob.in_term = ITERM_UNTUNED_75;
|
||||
else return 0;
|
||||
goto inst_2;
|
||||
}
|
||||
if (!str_cmp(w1, w1_len, "out_term", ZTERM)) {
|
||||
if (!str_cmp(w2, w2_len, "NONE", ZTERM))
|
||||
dev->iob.out_term = OTERM_NONE;
|
||||
else if (!str_cmp(w2, w2_len, "UNTUNED_25", ZTERM))
|
||||
dev->iob.out_term = OTERM_UNTUNED_25;
|
||||
else if (!str_cmp(w2, w2_len, "UNTUNED_50", ZTERM))
|
||||
dev->iob.out_term = OTERM_UNTUNED_50;
|
||||
else if (!str_cmp(w2, w2_len, "UNTUNED_75", ZTERM))
|
||||
dev->iob.out_term = OTERM_UNTUNED_75;
|
||||
else return 0;
|
||||
goto inst_2;
|
||||
}
|
||||
return 0;
|
||||
inst_1:
|
||||
dev->instantiated = 1;
|
||||
return 1;
|
||||
inst_2:
|
||||
dev->instantiated = 2;
|
||||
return 2;
|
||||
}
|
||||
|
||||
static int printf_LOGIC(FILE* f, struct fpga_model* model,
|
||||
int y, int x, int config_only)
|
||||
{
|
||||
|
@ -237,12 +341,85 @@ static int printf_LOGIC(FILE* f, struct fpga_model* model,
|
|||
break;
|
||||
default: EXIT(1);
|
||||
}
|
||||
if (tile->devs[i].logic.A_used)
|
||||
printf_wrap(f, line, plen, "A_used");
|
||||
if (tile->devs[i].logic.B_used)
|
||||
printf_wrap(f, line, plen, "B_used");
|
||||
if (tile->devs[i].logic.C_used)
|
||||
printf_wrap(f, line, plen, "C_used");
|
||||
if (tile->devs[i].logic.D_used)
|
||||
printf_wrap(f, line, plen, "D_used");
|
||||
if (tile->devs[i].logic.A6_lut && tile->devs[i].logic.A6_lut[0])
|
||||
printf_wrap(f, line, plen, "A6_lut %s",
|
||||
tile->devs[i].logic.A6_lut);
|
||||
if (tile->devs[i].logic.B6_lut && tile->devs[i].logic.B6_lut[0])
|
||||
printf_wrap(f, line, plen, "B6_lut %s",
|
||||
tile->devs[i].logic.B6_lut);
|
||||
if (tile->devs[i].logic.C6_lut && tile->devs[i].logic.C6_lut[0])
|
||||
printf_wrap(f, line, plen, "C6_lut %s",
|
||||
tile->devs[i].logic.C6_lut);
|
||||
if (tile->devs[i].logic.D6_lut && tile->devs[i].logic.D6_lut[0])
|
||||
printf_wrap(f, line, plen, "D6_lut %s",
|
||||
tile->devs[i].logic.D6_lut);
|
||||
strcat(line, "\n");
|
||||
fprintf(f, line);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int read_LOGIC_attr(struct fpga_model* model, struct fpga_device* dev,
|
||||
const char* w1, int w1_len, const char* w2, int w2_len)
|
||||
{
|
||||
// First the one-word attributes.
|
||||
if (!str_cmp(w1, w1_len, "A_used", ZTERM)) {
|
||||
dev->logic.A_used = 1;
|
||||
goto inst_1;
|
||||
}
|
||||
if (!str_cmp(w1, w1_len, "B_used", ZTERM)) {
|
||||
dev->logic.B_used = 1;
|
||||
goto inst_1;
|
||||
}
|
||||
if (!str_cmp(w1, w1_len, "C_used", ZTERM)) {
|
||||
dev->logic.C_used = 1;
|
||||
goto inst_1;
|
||||
}
|
||||
if (!str_cmp(w1, w1_len, "D_used", ZTERM)) {
|
||||
dev->logic.D_used = 1;
|
||||
goto inst_1;
|
||||
}
|
||||
// The remaining attributes all require 2 words.
|
||||
if (w2_len < 1) return 0;
|
||||
if (!str_cmp(w1, w1_len, "type", ZTERM))
|
||||
return 2; // no reason for instantiation
|
||||
if (!str_cmp(w1, w1_len, "A6_lut", ZTERM)) {
|
||||
if (fpga_set_lut(model, dev, A6_LUT, w2, w2_len))
|
||||
return 0;
|
||||
goto inst_2;
|
||||
}
|
||||
if (!str_cmp(w1, w1_len, "B6_lut", ZTERM)) {
|
||||
if (fpga_set_lut(model, dev, B6_LUT, w2, w2_len))
|
||||
return 0;
|
||||
goto inst_2;
|
||||
}
|
||||
if (!str_cmp(w1, w1_len, "C6_lut", ZTERM)) {
|
||||
if (fpga_set_lut(model, dev, C6_LUT, w2, w2_len))
|
||||
return 0;
|
||||
goto inst_2;
|
||||
}
|
||||
if (!str_cmp(w1, w1_len, "D6_lut", ZTERM)) {
|
||||
if (fpga_set_lut(model, dev, D6_LUT, w2, w2_len))
|
||||
return 0;
|
||||
goto inst_2;
|
||||
}
|
||||
return 0;
|
||||
inst_1:
|
||||
dev->instantiated = 1;
|
||||
return 1;
|
||||
inst_2:
|
||||
dev->instantiated = 2;
|
||||
return 2;
|
||||
}
|
||||
|
||||
int printf_devices(FILE* f, struct fpga_model* model, int config_only)
|
||||
{
|
||||
int x, y, i, rc;
|
||||
|
@ -332,6 +509,7 @@ int printf_devices(FILE* f, struct fpga_model* model, int config_only)
|
|||
break;
|
||||
case DEV_IOB:
|
||||
case DEV_LOGIC:
|
||||
case DEV_NONE:
|
||||
// to suppress compiler warning
|
||||
break;
|
||||
}
|
||||
|
@ -483,3 +661,99 @@ int printf_switches(FILE* f, struct fpga_model* model, int enabled_only)
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static enum fpgadev_type to_type(const char* s, int len)
|
||||
{
|
||||
if (!str_cmp(s, len, "IOB", 3)) return DEV_IOB;
|
||||
if (!str_cmp(s, len, "LOGIC", 5)) return DEV_LOGIC;
|
||||
return DEV_NONE;
|
||||
}
|
||||
|
||||
int read_floorplan(struct fpga_model* model, FILE* f)
|
||||
{
|
||||
char line[1024];
|
||||
int beg, end;
|
||||
|
||||
while (fgets(line, sizeof(line), f)) {
|
||||
next_word(line, 0, &beg, &end);
|
||||
if (end == beg) continue;
|
||||
|
||||
if (!str_cmp(&line[beg], end-beg, "dev", 3)) {
|
||||
int y_beg, y_end, x_beg, x_end;
|
||||
int y_coord, x_coord;
|
||||
int type_beg, type_end, idx_beg, idx_end;
|
||||
enum fpgadev_type dev_type;
|
||||
int dev_idx, words_consumed;
|
||||
struct fpga_device* dev_ptr;
|
||||
int next_beg, next_end, second_beg, second_end;
|
||||
|
||||
next_word(line, end, &y_beg, &y_end);
|
||||
next_word(line, y_end, &x_beg, &x_end);
|
||||
if (y_end < y_beg+2 || x_end < x_beg+2
|
||||
|| line[y_beg] != 'y' || line[x_beg] != 'x'
|
||||
|| !all_digits(&line[y_beg+1], y_end-y_beg-1)
|
||||
|| !all_digits(&line[x_beg+1], x_end-x_beg-1)) {
|
||||
fprintf(stderr, "error %i: %s", __LINE__, line);
|
||||
continue;
|
||||
}
|
||||
y_coord = to_i(&line[y_beg+1], y_end-y_beg-1);
|
||||
x_coord = to_i(&line[x_beg+1], x_end-x_beg-1);
|
||||
|
||||
next_word(line, x_end, &type_beg, &type_end);
|
||||
next_word(line, type_end, &idx_beg, &idx_end);
|
||||
|
||||
if (type_end == type_beg || idx_end == idx_beg
|
||||
|| !all_digits(&line[idx_beg], idx_end-idx_beg)) {
|
||||
fprintf(stderr, "error %i: %s", __LINE__, line);
|
||||
continue;
|
||||
}
|
||||
dev_type = to_type(&line[type_beg], type_end-type_beg);
|
||||
dev_idx = to_i(&line[idx_beg], idx_end-idx_beg);
|
||||
dev_ptr = fpga_dev(model, y_coord, x_coord, dev_type, dev_idx);
|
||||
if (!dev_ptr) {
|
||||
fprintf(stderr, "error %i: %s", __LINE__, line);
|
||||
continue;
|
||||
}
|
||||
|
||||
next_end = idx_end;
|
||||
while (next_word(line, next_end, &next_beg, &next_end),
|
||||
next_end > next_beg) {
|
||||
next_word(line, next_end, &second_beg, &second_end);
|
||||
switch (dev_type) {
|
||||
case DEV_IOB:
|
||||
words_consumed = read_IOB_attr(
|
||||
model, dev_ptr,
|
||||
&line[next_beg],
|
||||
next_end-next_beg,
|
||||
&line[second_beg],
|
||||
second_end-second_beg);
|
||||
break;
|
||||
case DEV_LOGIC:
|
||||
words_consumed = read_LOGIC_attr(
|
||||
model, dev_ptr,
|
||||
&line[next_beg],
|
||||
next_end-next_beg,
|
||||
&line[second_beg],
|
||||
second_end-second_beg);
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "error %i: %s",
|
||||
__LINE__, line);
|
||||
goto next_line;
|
||||
}
|
||||
if (!words_consumed)
|
||||
fprintf(stderr,
|
||||
"error %i w1 %.*s w2 %.*s: %s",
|
||||
__LINE__, next_end-next_beg,
|
||||
&line[next_beg],
|
||||
second_end-second_beg,
|
||||
&line[second_beg],
|
||||
line);
|
||||
else if (words_consumed == 2)
|
||||
next_end = second_end;
|
||||
}
|
||||
next_line: ;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -24,6 +24,8 @@
|
|||
// - lines should typically not exceed 80 characters
|
||||
//
|
||||
|
||||
int read_floorplan(struct fpga_model* model, FILE* f);
|
||||
|
||||
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);
|
||||
|
|
30
fp2bit.c
30
fp2bit.c
|
@ -6,17 +6,45 @@
|
|||
//
|
||||
|
||||
#include "model.h"
|
||||
#include "floorplan.h"
|
||||
#include "bits.h"
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
struct fpga_model model;
|
||||
int rc;
|
||||
FILE* fp, *fbits;
|
||||
int rc = -1;
|
||||
|
||||
if (argc != 3) {
|
||||
fprintf(stderr,
|
||||
"\n"
|
||||
"%s - floorplan to bitstream\n"
|
||||
"Usage: %s <floorplan_file|- for stdin> <bits_file>\n"
|
||||
"\n", argv[0], argv[0]);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (!strcmp(argv[1], "-"))
|
||||
fp = stdin;
|
||||
else {
|
||||
fp = fopen(argv[1], "r");
|
||||
if (!fp) {
|
||||
fprintf(stderr, "Error opening %s.\n", argv[1]);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
fbits = fopen(argv[2], "w");
|
||||
if (!fbits) {
|
||||
fprintf(stderr, "Error opening %s.\n", argv[2]);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if ((rc = fpga_build_model(&model, XC6SLX9_ROWS, XC6SLX9_COLUMNS,
|
||||
XC6SLX9_LEFT_WIRING, XC6SLX9_RIGHT_WIRING)))
|
||||
goto fail;
|
||||
|
||||
if ((rc = read_floorplan(&model, fp))) goto fail;
|
||||
if ((rc = write_bits(fbits, &model))) goto fail;
|
||||
return EXIT_SUCCESS;
|
||||
fail:
|
||||
return rc;
|
||||
|
|
41
helper.c
41
helper.c
|
@ -702,6 +702,47 @@ void next_word(const char*s, int start, int* beg, int* end)
|
|||
*end = i;
|
||||
}
|
||||
|
||||
int str_cmp(const char* a, int a_len, const char* b, int b_len)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
if (a_len == -1) {
|
||||
a_len = 0;
|
||||
while (a[a_len]) a_len++;
|
||||
}
|
||||
if (b_len == -1) {
|
||||
b_len = 0;
|
||||
while (b[b_len]) b_len++;
|
||||
}
|
||||
while (1) {
|
||||
if (i >= a_len) {
|
||||
if (i >= b_len)
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
if (i >= b_len) {
|
||||
if (i >= a_len)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
if (a[i] != b[i])
|
||||
return a[i] - b[i];
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
int all_digits(const char* a, int len)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!len) return 0;
|
||||
for (i = 0; i < len; i++) {
|
||||
if (a[i] < '0' || a[i] > '9')
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int to_i(const char* s, int len)
|
||||
{
|
||||
int num, base;
|
||||
|
|
8
helper.h
8
helper.h
|
@ -16,6 +16,8 @@
|
|||
#define PROGRAM_REVISION "2012-06-27"
|
||||
#define MACRO_STR(arg) #arg
|
||||
|
||||
#define OUT_OF_MEM() { fprintf(stderr, \
|
||||
"Out of memory in %s:%i\n", __FILE__, __LINE__); }
|
||||
#define EXIT(expr) if (expr) { fprintf(stderr, \
|
||||
"Internal error in %s:%i\n", __FILE__, __LINE__); exit(1); }
|
||||
|
||||
|
@ -77,7 +79,13 @@ uint64_t read_lut64(uint8_t* two_minors, int off_in_frame);
|
|||
int get_vm_mb(void);
|
||||
int get_random(void);
|
||||
int compare_with_number(const char* a, const char* b);
|
||||
// If no next word is found, *end == *beg
|
||||
void next_word(const char* s, int start, int* beg, int* end);
|
||||
// if a_len or b_len are -1, the length is until 0-termination
|
||||
#define ZTERM -1
|
||||
int str_cmp(const char* a, int a_len, const char* b, int b_len);
|
||||
// all_digits() returns 0 if len == 0
|
||||
int all_digits(const char* a, int len);
|
||||
int to_i(const char* s, int len);
|
||||
|
||||
uint32_t hash_djb2(const unsigned char* str);
|
||||
|
|
4
model.h
4
model.h
|
@ -168,7 +168,7 @@ enum fpga_tile_type
|
|||
#define CENTER_LOGIC_O 2
|
||||
#define CENTER_ROUTING_O 3
|
||||
|
||||
#define YX_TILE(model, y, x) (&(model)->tiles[(y)*model->x_width+(x)])
|
||||
#define YX_TILE(model, y, x) (&(model)->tiles[(y)*(model)->x_width+(x)])
|
||||
|
||||
// tile flags
|
||||
|
||||
|
@ -271,6 +271,8 @@ const char* logicin_s(int wire, int routing_io);
|
|||
|
||||
enum fpgadev_type
|
||||
{
|
||||
DEV_NONE = 0,
|
||||
|
||||
DEV_LOGIC,
|
||||
DEV_TIEOFF,
|
||||
DEV_MACC,
|
||||
|
|
|
@ -325,13 +325,14 @@ int init_devices(struct fpga_model* model)
|
|||
if (!is_atx(X_LOGIC_COL, model, x))
|
||||
continue;
|
||||
for (y = TOP_IO_TILES; y < model->y_height - BOT_IO_TILES; y++) {
|
||||
// M and L are at index 0, X is at index 1.
|
||||
if (YX_TILE(model, y, x)->flags & TF_LOGIC_XM_DEV) {
|
||||
if ((rc = add_dev(model, y, x, DEV_LOGIC, LOGIC_X))) goto fail;
|
||||
if ((rc = add_dev(model, y, x, DEV_LOGIC, LOGIC_M))) goto fail;
|
||||
if ((rc = add_dev(model, y, x, DEV_LOGIC, LOGIC_X))) goto fail;
|
||||
}
|
||||
if (YX_TILE(model, y, x)->flags & TF_LOGIC_XL_DEV) {
|
||||
if ((rc = add_dev(model, y, x, DEV_LOGIC, LOGIC_X))) goto fail;
|
||||
if ((rc = add_dev(model, y, x, DEV_LOGIC, LOGIC_L))) goto fail;
|
||||
if ((rc = add_dev(model, y, x, DEV_LOGIC, LOGIC_X))) goto fail;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
21
sort_seq.c
21
sort_seq.c
|
@ -106,27 +106,6 @@ static void find_number(const char* s, int s_len, int* num_start, int* num_end)
|
|||
}
|
||||
}
|
||||
|
||||
static int str_cmp(const char* a, int a_len, const char* b, int b_len)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
while (1) {
|
||||
if (i >= a_len) {
|
||||
if (i >= b_len)
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
if (i >= b_len) {
|
||||
if (i >= a_len)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
if (a[i] != b[i])
|
||||
return a[i] - b[i];
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
static int is_known_suffix(const char* str, int str_len)
|
||||
{
|
||||
int i;
|
||||
|
|
Loading…
Reference in New Issue
Block a user