cleanup, fixes, renames/reorg - messy but committed to set base for next steps...
This commit is contained in:
parent
4d576e55fd
commit
9b059ec9b5
169
autotest.c
169
autotest.c
|
@ -46,7 +46,6 @@ static int dump_file(const char* path)
|
|||
}
|
||||
fclose(f);
|
||||
printf("O end dump %s\n", path);
|
||||
printf("\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -103,6 +102,151 @@ fail:
|
|||
return rc;
|
||||
}
|
||||
|
||||
static void cut_sw_from_end(struct fpga_net* net, int cut_o)
|
||||
{
|
||||
if (cut_o <= 2) return;
|
||||
memmove(&net->el[2], &net->el[cut_o],
|
||||
(net->len-cut_o)*sizeof(net->el[0]));
|
||||
net->len = 2 + net->len-cut_o;
|
||||
}
|
||||
|
||||
static int test_net(struct test_state* tstate, net_idx_t net_i)
|
||||
{
|
||||
struct fpga_net* net;
|
||||
struct fpga_net copy_net;
|
||||
swidx_t same_sw[64];
|
||||
int same_len;
|
||||
int i, j, rc;
|
||||
|
||||
net = fpga_net_get(tstate->model, net_i);
|
||||
if (!net) FAIL(EINVAL);
|
||||
copy_net = *net;
|
||||
|
||||
for (i = net->len-1; i >= 2; i--) {
|
||||
printf("round i %i\n", i);
|
||||
*net = copy_net;
|
||||
cut_sw_from_end(net, i);
|
||||
if (net->len <= 2) {
|
||||
rc = diff_printf(tstate);
|
||||
if (rc) FAIL(rc);
|
||||
continue;
|
||||
}
|
||||
// what other switches go to SW_TO(el[2])?
|
||||
printf_swchain(tstate->model,
|
||||
net->el[2].y, net->el[2].x,
|
||||
fpga_switch_str_i(tstate->model,
|
||||
net->el[2].y, net->el[2].x,
|
||||
net->el[2].idx, SW_TO), 1, SW_TO);
|
||||
same_len = sizeof(same_sw)/sizeof(*same_sw);
|
||||
rc = fpga_switch_same_fromto(tstate->model,
|
||||
net->el[2].y, net->el[2].x,
|
||||
net->el[2].idx, SW_TO, same_sw, &same_len);
|
||||
if (rc) FAIL(rc);
|
||||
printf("same_len at this level %i\n", same_len);
|
||||
for (j = 0; j < same_len; j++) {
|
||||
net->el[2].idx = same_sw[j];
|
||||
rc = diff_printf(tstate);
|
||||
if (rc) FAIL(rc);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
fail:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int test_net2(struct test_state* tstate, net_idx_t net_i)
|
||||
{
|
||||
struct fpga_net* net;
|
||||
struct fpga_net copy_net;
|
||||
swidx_t same_sw[64];
|
||||
int same_len;
|
||||
int i, j, rc;
|
||||
|
||||
net = fpga_net_get(tstate->model, net_i);
|
||||
if (!net) FAIL(EINVAL);
|
||||
copy_net = *net;
|
||||
|
||||
for (i = 3; i <= net->len-1; i++) {
|
||||
printf("round i %i\n", i);
|
||||
net->len = i;
|
||||
// what other switches go from SW_FROM(el[i-1])?
|
||||
printf_swchain(tstate->model,
|
||||
net->el[i-1].y, net->el[i-1].x,
|
||||
fpga_switch_str_i(tstate->model,
|
||||
net->el[i-1].y, net->el[i-1].x,
|
||||
net->el[i-1].idx, SW_FROM), 1, SW_FROM);
|
||||
same_len = sizeof(same_sw)/sizeof(*same_sw);
|
||||
rc = fpga_switch_same_fromto(tstate->model,
|
||||
net->el[i-1].y, net->el[i-1].x,
|
||||
net->el[i-1].idx, SW_FROM, same_sw, &same_len);
|
||||
if (rc) FAIL(rc);
|
||||
printf("same_len at this level %i\n", same_len);
|
||||
#if 1
|
||||
for (j = 0; j < same_len; j++) {
|
||||
net->el[i-1].idx = same_sw[j];
|
||||
rc = diff_printf(tstate);
|
||||
if (rc) FAIL(rc);
|
||||
}
|
||||
#endif
|
||||
*net = copy_net;
|
||||
}
|
||||
return 0;
|
||||
fail:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void fdev_print_required_pins(struct fpga_model* model, int y, int x,
|
||||
int type, int type_idx)
|
||||
{
|
||||
struct fpga_device* dev;
|
||||
int i;
|
||||
|
||||
dev = fdev_p(model, y, x, type, type_idx);
|
||||
if (!dev) { HERE(); return; }
|
||||
|
||||
printf("y%02i x%02i %s %i inpin", y, x, fdev_type2str(type), type_idx);
|
||||
if (!dev->pinw_req_in)
|
||||
printf(" -\n");
|
||||
else {
|
||||
for (i = 0; i < dev->pinw_req_in; i++)
|
||||
printf(" %s", fdev_pinw_idx2str(type, dev->pinw_req_for_cfg[i]));
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
printf("y%02i x%02i %s %i outpin", y, x, fdev_type2str(type), type_idx);
|
||||
if (dev->pinw_req_total <= dev->pinw_req_in)
|
||||
printf(" -\n");
|
||||
else {
|
||||
for (i = dev->pinw_req_in; i < dev->pinw_req_total; i++)
|
||||
printf(" %s", fdev_pinw_idx2str(type, dev->pinw_req_for_cfg[i]));
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
static int test_all_logic_configs(struct test_state* tstate)
|
||||
{
|
||||
int y, x, rc;
|
||||
|
||||
// todo: goal: configure valid logic with as many possible in and out
|
||||
// pins, for M and X device
|
||||
y = 68;
|
||||
x = 13;
|
||||
|
||||
rc = fdev_logic_set_lut(tstate->model, y, x,
|
||||
DEV_LOGX, D6_LUT, "A3", ZTERM);
|
||||
if (rc) FAIL(rc);
|
||||
|
||||
rc = fdev_set_required_pins(tstate->model, y, x, DEV_LOGIC, DEV_LOGX);
|
||||
if (rc) FAIL(rc);
|
||||
|
||||
fdev_print_required_pins(tstate->model, y, x, DEV_LOGIC, DEV_LOGX);
|
||||
rc = diff_printf(tstate);
|
||||
if (rc) FAIL(rc);
|
||||
return 0;
|
||||
fail:
|
||||
return rc;
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
struct fpga_model model;
|
||||
|
@ -113,6 +257,11 @@ int main(int argc, char** argv)
|
|||
struct switch_to_yx switch_to;
|
||||
net_idx_t P46_net;
|
||||
|
||||
// flush after every line is better for the autotest
|
||||
// output, tee, etc.
|
||||
// for example: ./autotest 2>&1 | tee autotest.log
|
||||
setvbuf(stdout, /*buf*/ 0, _IOLBF, /*size*/ 0);
|
||||
|
||||
printf("\n");
|
||||
printf("O fpgatools automatic test suite. Be welcome and be "
|
||||
"our guest. namo namaha.\n");
|
||||
|
@ -136,6 +285,7 @@ int main(int argc, char** argv)
|
|||
rc = diff_start(&tstate, "and");
|
||||
if (rc) FAIL(rc);
|
||||
|
||||
#if 0
|
||||
// configure P46
|
||||
rc = fpga_find_iob(&model, "P46", &P46_y, &P46_x, &P46_type_idx);
|
||||
if (rc) FAIL(rc);
|
||||
|
@ -159,8 +309,12 @@ int main(int argc, char** argv)
|
|||
P48_dev->iob.O_used = 1;
|
||||
P48_dev->iob.slew = SLEW_SLOW;
|
||||
P48_dev->iob.suspend = SUSP_3STATE;
|
||||
#endif
|
||||
|
||||
// configure logic
|
||||
// todo: goal: configure valid logic with as many possible in and out
|
||||
// pins, for M and X device
|
||||
#if 0
|
||||
logic_dev_idx = fpga_dev_idx(&model, /*y*/ 68, /*x*/ 13,
|
||||
DEV_LOGIC, DEV_LOGX);
|
||||
if (logic_dev_idx == NO_DEV) FAIL(EINVAL);
|
||||
|
@ -169,10 +323,16 @@ int main(int argc, char** argv)
|
|||
logic_dev->logic.D_used = 1;
|
||||
rc = fpga_set_lut(&model, logic_dev, D6_LUT, "A3", ZTERM);
|
||||
if (rc) FAIL(rc);
|
||||
|
||||
rc = diff_printf(&tstate);
|
||||
#endif
|
||||
rc = test_all_logic_configs(&tstate);
|
||||
if (rc) FAIL(rc);
|
||||
|
||||
#if 0
|
||||
rc = diff_printf(&tstate);
|
||||
if (rc) FAIL(rc);
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
// configure net from P46.I to logic.D3
|
||||
rc = fpga_net_new(&model, &P46_net);
|
||||
if (rc) FAIL(rc);
|
||||
|
@ -253,8 +413,9 @@ int main(int argc, char** argv)
|
|||
if (rc) FAIL(rc);
|
||||
}
|
||||
|
||||
rc = diff_printf(&tstate);
|
||||
rc = test_net2(&tstate, P46_net);
|
||||
if (rc) FAIL(rc);
|
||||
#endif
|
||||
|
||||
printf("\n");
|
||||
printf("O Test suite completed.\n");
|
||||
|
|
36
bit_frames.c
36
bit_frames.c
|
@ -111,19 +111,19 @@ int extract_model(struct fpga_model* model, struct fpga_bits* bits)
|
|||
if ((u32_p[0] & 0xFFFFFF7F) == 0x00000100
|
||||
&& u32_p[1] == 0x06001100) {
|
||||
dev->instantiated = 1;
|
||||
strcpy(dev->iob.ostandard, IO_LVCMOS33);
|
||||
dev->iob.drive_strength = 12;
|
||||
dev->iob.O_used = 1;
|
||||
dev->iob.slew = SLEW_SLOW;
|
||||
dev->iob.suspend = SUSP_3STATE;
|
||||
strcpy(dev->u.iob.ostandard, IO_LVCMOS33);
|
||||
dev->u.iob.drive_strength = 12;
|
||||
dev->u.iob.O_used = 1;
|
||||
dev->u.iob.slew = SLEW_SLOW;
|
||||
dev->u.iob.suspend = SUSP_3STATE;
|
||||
u32_p[0] = 0;
|
||||
u32_p[1] = 0;
|
||||
} else if (u32_p[0] == 0x00000107
|
||||
&& u32_p[1] == 0x0B002400) {
|
||||
dev->instantiated = 1;
|
||||
strcpy(dev->iob.istandard, IO_LVCMOS33);
|
||||
dev->iob.bypass_mux = BYPASS_MUX_I;
|
||||
dev->iob.I_mux = IMUX_I;
|
||||
strcpy(dev->u.iob.istandard, IO_LVCMOS33);
|
||||
dev->u.iob.bypass_mux = BYPASS_MUX_I;
|
||||
dev->u.iob.I_mux = IMUX_I;
|
||||
u32_p[0] = 0;
|
||||
u32_p[1] = 0;
|
||||
} else HERE();
|
||||
|
@ -177,16 +177,15 @@ int extract_model(struct fpga_model* model, struct fpga_bits* bits)
|
|||
dev_idx = fpga_dev_idx(model, y, x, DEV_LOGIC, DEV_LOGX);
|
||||
if (dev_idx == NO_DEV) FAIL(EINVAL);
|
||||
dev = FPGA_DEV(model, y, x, dev_idx);
|
||||
dev->instantiated = 1;
|
||||
*(uint64_t*)(u8_p+26*FRAME_SIZE+byte_off) = 0;
|
||||
|
||||
u64 = read_lut64(u8_p + 27*FRAME_SIZE, (byte_off+4)*8);
|
||||
{ int logic_base[6] = {1,1,0,1,1,0};
|
||||
lut_str = lut2bool(u64, 64, &logic_base, /*flip_b0*/ 0); }
|
||||
if (*lut_str) {
|
||||
rc = fpga_set_lut(model, dev, A6_LUT, lut_str, ZTERM);
|
||||
rc = fdev_logic_set_lut(model, y, x, DEV_LOGX,
|
||||
A6_LUT, lut_str, ZTERM);
|
||||
if (rc) FAIL(rc);
|
||||
dev->logic.A_used = 1;
|
||||
*(uint32_t*)(u8_p+27*FRAME_SIZE+byte_off+4) = 0;
|
||||
*(uint32_t*)(u8_p+28*FRAME_SIZE+byte_off+4) = 0;
|
||||
}
|
||||
|
@ -194,9 +193,8 @@ int extract_model(struct fpga_model* model, struct fpga_bits* bits)
|
|||
{ int logic_base[6] = {1,1,0,1,1,0};
|
||||
lut_str = lut2bool(u64, 64, &logic_base, /*flip_b0*/ 0); }
|
||||
if (*lut_str) {
|
||||
rc = fpga_set_lut(model, dev, B6_LUT, lut_str, ZTERM);
|
||||
if (rc) FAIL(rc);
|
||||
dev->logic.B_used = 1;
|
||||
rc = fdev_logic_set_lut(model, y, x, DEV_LOGX,
|
||||
B6_LUT, lut_str, ZTERM);
|
||||
*(uint32_t*)(u8_p+29*FRAME_SIZE+byte_off+4) = 0;
|
||||
*(uint32_t*)(u8_p+30*FRAME_SIZE+byte_off+4) = 0;
|
||||
}
|
||||
|
@ -204,9 +202,8 @@ int extract_model(struct fpga_model* model, struct fpga_bits* bits)
|
|||
{ int logic_base[6] = {0,1,0,0,0,1};
|
||||
lut_str = lut2bool(u64, 64, &logic_base, /*flip_b0*/ 0); }
|
||||
if (*lut_str) {
|
||||
rc = fpga_set_lut(model, dev, C6_LUT, lut_str, ZTERM);
|
||||
if (rc) FAIL(rc);
|
||||
dev->logic.C_used = 1;
|
||||
rc = fdev_logic_set_lut(model, y, x, DEV_LOGX,
|
||||
C6_LUT, lut_str, ZTERM);
|
||||
*(uint32_t*)(u8_p+27*FRAME_SIZE+byte_off) = 0;
|
||||
*(uint32_t*)(u8_p+28*FRAME_SIZE+byte_off) = 0;
|
||||
}
|
||||
|
@ -214,9 +211,8 @@ int extract_model(struct fpga_model* model, struct fpga_bits* bits)
|
|||
{ int logic_base[6] = {0,1,0,0,0,1};
|
||||
lut_str = lut2bool(u64, 64, &logic_base, /*flip_b0*/ 0); }
|
||||
if (*lut_str) {
|
||||
rc = fpga_set_lut(model, dev, D6_LUT, lut_str, ZTERM);
|
||||
if (rc) FAIL(rc);
|
||||
dev->logic.D_used = 1;
|
||||
rc = fdev_logic_set_lut(model, y, x, DEV_LOGX,
|
||||
D6_LUT, lut_str, ZTERM);
|
||||
*(uint32_t*)(u8_p+29*FRAME_SIZE+byte_off) = 0;
|
||||
*(uint32_t*)(u8_p+30*FRAME_SIZE+byte_off) = 0;
|
||||
}
|
||||
|
|
178
control.c
178
control.c
|
@ -202,14 +202,14 @@ const char* fpga_iob_sitename(struct fpga_model* model, int y, int x,
|
|||
|
||||
static const char* dev_str[] = FPGA_DEV_STR;
|
||||
|
||||
const char* fpgadev_str(enum fpgadev_type type)
|
||||
const char* fdev_type2str(enum fpgadev_type type)
|
||||
{
|
||||
if (type < 0 || type >= sizeof(dev_str)/sizeof(*dev_str))
|
||||
{ HERE(); return 0; }
|
||||
return dev_str[type];
|
||||
}
|
||||
|
||||
enum fpgadev_type fpgadev_str2type(const char* str, int len)
|
||||
enum fpgadev_type fdev_str2type(const char* str, int len)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < sizeof(dev_str)/sizeof(*dev_str); i++) {
|
||||
|
@ -221,6 +221,14 @@ enum fpgadev_type fpgadev_str2type(const char* str, int len)
|
|||
return DEV_NONE;
|
||||
}
|
||||
|
||||
struct fpga_device* fdev_p(struct fpga_model* model,
|
||||
int y, int x, enum fpgadev_type type, dev_type_idx_t type_idx)
|
||||
{
|
||||
dev_idx_t dev_idx = fpga_dev_idx(model, y, x, type, type_idx);
|
||||
if (dev_idx == NO_DEV) { HERE(); return 0; }
|
||||
return FPGA_DEV(model, y, x, dev_idx);
|
||||
}
|
||||
|
||||
dev_idx_t fpga_dev_idx(struct fpga_model* model,
|
||||
int y, int x, enum fpgadev_type type, dev_type_idx_t type_idx)
|
||||
{
|
||||
|
@ -240,7 +248,7 @@ dev_idx_t fpga_dev_idx(struct fpga_model* model,
|
|||
return NO_DEV;
|
||||
}
|
||||
|
||||
dev_type_idx_t fpga_dev_typeidx(struct fpga_model* model, int y, int x,
|
||||
dev_type_idx_t fdev_typeidx(struct fpga_model* model, int y, int x,
|
||||
dev_idx_t dev_idx)
|
||||
{
|
||||
struct fpga_tile* tile;
|
||||
|
@ -258,7 +266,7 @@ dev_type_idx_t fpga_dev_typeidx(struct fpga_model* model, int y, int x,
|
|||
static const char* iob_pinw_str[] = IOB_PINW_STR;
|
||||
static const char* logic_pinw_str[] = LOGIC_PINW_STR;
|
||||
|
||||
pinw_idx_t fpgadev_pinw_str2idx(int devtype, const char* str, int len)
|
||||
pinw_idx_t fdev_pinw_str2idx(int devtype, const char* str, int len)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
@ -284,7 +292,7 @@ pinw_idx_t fpgadev_pinw_str2idx(int devtype, const char* str, int len)
|
|||
return PINW_NO_IDX;
|
||||
}
|
||||
|
||||
const char* fpgadev_pinw_idx2str(int devtype, pinw_idx_t idx)
|
||||
const char* fdev_pinw_idx2str(int devtype, pinw_idx_t idx)
|
||||
{
|
||||
if (devtype == DEV_IOB) {
|
||||
if (idx < 0 || idx >= sizeof(iob_pinw_str)/sizeof(*iob_pinw_str)) {
|
||||
|
@ -304,33 +312,106 @@ const char* fpgadev_pinw_idx2str(int devtype, pinw_idx_t idx)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void free_required_pins(struct fpga_device* dev)
|
||||
{
|
||||
free(dev->pinw_req_for_cfg);
|
||||
dev->pinw_req_for_cfg = 0;
|
||||
dev->pinw_req_total = 0;
|
||||
dev->pinw_req_in = 0;
|
||||
}
|
||||
|
||||
#define MAX_LUT_LEN 512
|
||||
|
||||
int fpga_set_lut(struct fpga_model* model, struct fpga_device* dev,
|
||||
int fdev_logic_set_lut(struct fpga_model* model, int y, int x, int type_idx,
|
||||
int which_lut, const char* lut_str, int lut_len)
|
||||
{
|
||||
char** ptr;
|
||||
struct fpga_device* dev;
|
||||
char** luts;
|
||||
int rc;
|
||||
|
||||
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)) {
|
||||
dev = fdev_p(model, y, x, DEV_LOGIC, type_idx);
|
||||
if (!dev) FAIL(EINVAL);
|
||||
free_required_pins(dev);
|
||||
|
||||
luts = dev->u.logic.luts;
|
||||
if (!luts[which_lut]) {
|
||||
luts[which_lut] = malloc(MAX_LUT_LEN);
|
||||
if (!luts[which_lut]) {
|
||||
OUT_OF_MEM();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (lut_len == ZTERM) lut_len = strlen(lut_str);
|
||||
memcpy(*ptr, lut_str, lut_len);
|
||||
(*ptr)[lut_len] = 0;
|
||||
memcpy(luts[which_lut], lut_str, lut_len);
|
||||
luts[which_lut][lut_len] = 0;
|
||||
|
||||
switch (which_lut) {
|
||||
case A5_LUT:
|
||||
case A6_LUT:
|
||||
dev->u.logic.A_used = 1;
|
||||
break;
|
||||
case B5_LUT:
|
||||
case B6_LUT:
|
||||
dev->u.logic.B_used = 1;
|
||||
break;
|
||||
case C5_LUT:
|
||||
case C6_LUT:
|
||||
dev->u.logic.C_used = 1;
|
||||
break;
|
||||
case D5_LUT:
|
||||
case D6_LUT:
|
||||
dev->u.logic.D_used = 1;
|
||||
break;
|
||||
default: FAIL(EINVAL);
|
||||
}
|
||||
|
||||
dev->instantiated = 1;
|
||||
return 0;
|
||||
fail:
|
||||
return rc;
|
||||
}
|
||||
|
||||
int fdev_set_required_pins(struct fpga_model* model, int y, int x, int type,
|
||||
int type_idx)
|
||||
{
|
||||
struct fpga_device* dev;
|
||||
int rc;
|
||||
|
||||
dev = fdev_p(model, y, x, type, type_idx);
|
||||
if (!dev) FAIL(EINVAL);
|
||||
free_required_pins(dev);
|
||||
if (type == DEV_LOGIC) {
|
||||
#if 0
|
||||
TODO:
|
||||
// required pinwires depend on the given config and will
|
||||
// be deleted/invalidated on any config change.
|
||||
int pinw_req_total, pinw_req_in;
|
||||
pinw_idx_t* pinw_req_for_cfg;
|
||||
#endif
|
||||
}
|
||||
return 0;
|
||||
fail:
|
||||
return rc;
|
||||
}
|
||||
|
||||
void fdev_delete(struct fpga_model* model, int y, int x, int type, int type_idx)
|
||||
{
|
||||
struct fpga_device* dev;
|
||||
int i;
|
||||
|
||||
dev = fdev_p(model, y, x, type, type_idx);
|
||||
if (!dev) { HERE(); return; }
|
||||
if (!dev->instantiated) return;
|
||||
free_required_pins(dev);
|
||||
if (dev->type == DEV_LOGIC) {
|
||||
for (i = 0; i < sizeof(dev->u.logic.luts)
|
||||
/sizeof(dev->u.logic.luts[0]); i++) {
|
||||
free(dev->u.logic.luts[i]);
|
||||
dev->u.logic.luts[i] = 0;
|
||||
}
|
||||
}
|
||||
dev->instantiated = 0;
|
||||
memset(&dev->u, 0, sizeof(dev->u));
|
||||
}
|
||||
|
||||
int fpga_connpt_find(struct fpga_model* model, int y, int x,
|
||||
|
@ -422,6 +503,29 @@ swidx_t fpga_switch_backtofirst(struct fpga_model* model, int y, int x,
|
|||
return fpga_switch_search(model, y, x, last, /*search_beg*/ 0, from_to);
|
||||
}
|
||||
|
||||
int fpga_switch_same_fromto(struct fpga_model* model, int y, int x,
|
||||
swidx_t sw, int from_to, swidx_t* same_sw, int *same_len)
|
||||
{
|
||||
swidx_t cur_sw;
|
||||
int max_len, rc;
|
||||
|
||||
max_len = *same_len;
|
||||
*same_len = 0;
|
||||
if (max_len < 1) FAIL(EINVAL);
|
||||
cur_sw = fpga_switch_search(model, y, x, sw, /*search_beg*/ 0, from_to);
|
||||
// We should at least fine sw itself, if not something is wrong...
|
||||
if (cur_sw == NO_SWITCH) FAIL(EINVAL);
|
||||
|
||||
same_sw[(*same_len)++] = cur_sw;
|
||||
while ((cur_sw = fpga_switch_search(model, y, x, sw, cur_sw+1, from_to)) != NO_SWITCH) {
|
||||
same_sw[(*same_len)++] = cur_sw;
|
||||
if ((*same_len) >= max_len) FAIL(EINVAL);
|
||||
}
|
||||
return 0;
|
||||
fail:
|
||||
return rc;
|
||||
}
|
||||
|
||||
swidx_t fpga_switch_lookup(struct fpga_model* model, int y, int x,
|
||||
str16_t from_str_i, str16_t to_str_i)
|
||||
{
|
||||
|
@ -550,24 +654,20 @@ static const char* fmt_swset_el(struct fpga_model* model, int y, int x,
|
|||
char midstr[64];
|
||||
|
||||
last_buf = (last_buf+1)%NUM_SW_BUFS;
|
||||
|
||||
strcpy(midstr, fpga_switch_is_used(model, y, x, sw) ? "on:" : "");
|
||||
if (fpga_switch_is_bidir(model, y, x, sw))
|
||||
strcat(midstr, "<->");
|
||||
else {
|
||||
// a 'to-switch' is actually still a switch that physically
|
||||
// points in the other direction (unless it's a bidir switch),
|
||||
// so when displaying the 'to-switch', we make the arrow point
|
||||
// to the left side to match the physical direction.
|
||||
strcat(midstr, (from_to == SW_TO) ? "<-" : "->");
|
||||
}
|
||||
// fmt_swset_el() prints only the destination side of the switch (!from_to),
|
||||
// because it is the significant one in a chain of switches, and if the
|
||||
// caller wants the source side they can add it outside.
|
||||
strcpy(midstr, "<->");
|
||||
else
|
||||
strcpy(midstr, "->");
|
||||
// fmt_swset_el() prints only the destination side of the
|
||||
// switch (!from_to), because it is the significant one in
|
||||
// a chain of switches, and if the caller wants the source
|
||||
// side they can add it outside.
|
||||
snprintf(sw_buf[last_buf], sizeof(sw_buf[0]), "%s%s%s",
|
||||
(from_to == SW_FROM) ? "" : fpga_switch_str(model, y, x, sw, SW_FROM),
|
||||
(from_to == SW_FROM) ? ""
|
||||
: fpga_switch_str(model, y, x, sw, SW_FROM),
|
||||
midstr,
|
||||
(from_to == SW_TO) ? "" : fpga_switch_str(model, y, x, sw, SW_TO));
|
||||
(from_to == SW_TO) ? ""
|
||||
: fpga_switch_str(model, y, x, sw, SW_TO));
|
||||
|
||||
return sw_buf[last_buf];
|
||||
}
|
||||
|
@ -986,13 +1086,13 @@ static void fprintf_inout_pin(FILE* f, struct fpga_model* model,
|
|||
{ HERE(); return; }
|
||||
in_pin = pinw_i < tile->devs[dev_idx].num_pinw_in;
|
||||
|
||||
pin_str = fpgadev_pinw_idx2str(tile->devs[dev_idx].type, pinw_i);
|
||||
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%02i x%02i %s %i pin %s\n",
|
||||
net_i, in_pin ? "in" : "out", el->y, el->x,
|
||||
fpgadev_str(tile->devs[dev_idx].type),
|
||||
fpga_dev_typeidx(model, el->y, el->x, dev_idx),
|
||||
fdev_type2str(tile->devs[dev_idx].type),
|
||||
fdev_typeidx(model, el->y, el->x, dev_idx),
|
||||
pin_str);
|
||||
fprintf(f, buf);
|
||||
}
|
||||
|
|
27
control.h
27
control.h
|
@ -17,8 +17,12 @@ const char* fpga_iob_sitename(struct fpga_model* model, int y, int x,
|
|||
// 2. The index of the device within devices of the same type in the tile.
|
||||
//
|
||||
|
||||
const char* fpgadev_str(enum fpgadev_type type);
|
||||
enum fpgadev_type fpgadev_str2type(const char* str, int len);
|
||||
const char* fdev_type2str(enum fpgadev_type type);
|
||||
enum fpgadev_type fdev_str2type(const char* str, int len);
|
||||
|
||||
// returns 0 if device not found
|
||||
struct fpga_device* fdev_p(struct fpga_model* model,
|
||||
int y, int x, enum fpgadev_type type, dev_type_idx_t type_idx);
|
||||
|
||||
// Looks up a device index based on the type index.
|
||||
// returns NO_DEV (-1) if not found
|
||||
|
@ -27,18 +31,20 @@ dev_idx_t fpga_dev_idx(struct fpga_model* model,
|
|||
|
||||
// Counts how many devices of the same type as dev_idx are in
|
||||
// the array up to dev_idx.
|
||||
dev_type_idx_t fpga_dev_typeidx(struct fpga_model* model, int y, int x,
|
||||
dev_type_idx_t fdev_typeidx(struct fpga_model* model, int y, int x,
|
||||
dev_idx_t dev_idx);
|
||||
|
||||
#define PINW_NO_IDX -1
|
||||
pinw_idx_t fpgadev_pinw_str2idx(int devtype, const char* str, int len);
|
||||
pinw_idx_t fdev_pinw_str2idx(int devtype, const char* str, int len);
|
||||
// returns 0 when idx not found for the given devtype
|
||||
const char* fpgadev_pinw_idx2str(int devtype, pinw_idx_t idx);
|
||||
const char* fdev_pinw_idx2str(int devtype, pinw_idx_t 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 fdev_logic_set_lut(struct fpga_model* model, int y, int x, int type_idx,
|
||||
int which_lut, const char* lut_str, int lut_len);
|
||||
int fdev_set_required_pins(struct fpga_model* model, int y, int x, int type,
|
||||
int type_idx);
|
||||
void fdev_delete(struct fpga_model* model, int y, int x, int type,
|
||||
int type_idx);
|
||||
|
||||
// Returns the connpt index or NO_CONN if the name was not
|
||||
// found. connpt_dests_o and num_dests are optional and may
|
||||
|
@ -70,6 +76,11 @@ swidx_t fpga_switch_next(struct fpga_model* model, int y, int x,
|
|||
swidx_t last, int from_to);
|
||||
swidx_t fpga_switch_backtofirst(struct fpga_model* model, int y, int x,
|
||||
swidx_t last, int from_to);
|
||||
// When calling, same_len must contain the size of the
|
||||
// same_sw array. Upon return same_len returns how many
|
||||
// switches were found and writen to same_sw.
|
||||
int fpga_switch_same_fromto(struct fpga_model* model, int y, int x,
|
||||
swidx_t sw, int from_to, swidx_t* same_sw, int *same_len);
|
||||
swidx_t fpga_switch_lookup(struct fpga_model* model, int y, int x,
|
||||
str16_t from_str_i, str16_t to_str_i);
|
||||
|
||||
|
|
170
floorplan.c
170
floorplan.c
|
@ -83,15 +83,15 @@ static int printf_IOB(FILE* f, struct fpga_model* model,
|
|||
|
||||
if (!config_only) {
|
||||
fprintf(f, "%s type %s\n", pref,
|
||||
tile->devs[i].iob.subtype == IOBM ? "M" : "S");
|
||||
tile->devs[i].subtype == IOBM ? "M" : "S");
|
||||
}
|
||||
if (tile->devs[i].iob.istandard[0])
|
||||
if (tile->devs[i].u.iob.istandard[0])
|
||||
fprintf(f, "%s istd %s\n", pref,
|
||||
tile->devs[i].iob.istandard);
|
||||
if (tile->devs[i].iob.ostandard[0])
|
||||
tile->devs[i].u.iob.istandard);
|
||||
if (tile->devs[i].u.iob.ostandard[0])
|
||||
fprintf(f, "%s ostd %s\n", pref,
|
||||
tile->devs[i].iob.ostandard);
|
||||
switch (tile->devs[i].iob.bypass_mux) {
|
||||
tile->devs[i].u.iob.ostandard);
|
||||
switch (tile->devs[i].u.iob.bypass_mux) {
|
||||
case BYPASS_MUX_I:
|
||||
fprintf(f, "%s bypass_mux I\n", pref);
|
||||
break;
|
||||
|
@ -103,7 +103,7 @@ static int printf_IOB(FILE* f, struct fpga_model* model,
|
|||
break;
|
||||
case 0: break; default: EXIT(1);
|
||||
}
|
||||
switch (tile->devs[i].iob.I_mux) {
|
||||
switch (tile->devs[i].u.iob.I_mux) {
|
||||
case IMUX_I_B:
|
||||
fprintf(f, "%s imux I_B\n", pref);
|
||||
break;
|
||||
|
@ -112,10 +112,10 @@ static int printf_IOB(FILE* f, struct fpga_model* model,
|
|||
break;
|
||||
case 0: break; default: EXIT(1);
|
||||
}
|
||||
if (tile->devs[i].iob.drive_strength)
|
||||
if (tile->devs[i].u.iob.drive_strength)
|
||||
fprintf(f, "%s strength %i\n", pref,
|
||||
tile->devs[i].iob.drive_strength);
|
||||
switch (tile->devs[i].iob.slew) {
|
||||
tile->devs[i].u.iob.drive_strength);
|
||||
switch (tile->devs[i].u.iob.slew) {
|
||||
case SLEW_SLOW:
|
||||
fprintf(f, "%s slew SLOW\n", pref);
|
||||
break;
|
||||
|
@ -127,9 +127,9 @@ static int printf_IOB(FILE* f, struct fpga_model* model,
|
|||
break;
|
||||
case 0: break; default: EXIT(1);
|
||||
}
|
||||
if (tile->devs[i].iob.O_used)
|
||||
if (tile->devs[i].u.iob.O_used)
|
||||
fprintf(f, "%s O_used\n", pref);
|
||||
switch (tile->devs[i].iob.suspend) {
|
||||
switch (tile->devs[i].u.iob.suspend) {
|
||||
case SUSP_LAST_VAL:
|
||||
fprintf(f, "%s suspend DRIVE_LAST_VALUE\n", pref);
|
||||
break;
|
||||
|
@ -150,7 +150,7 @@ static int printf_IOB(FILE* f, struct fpga_model* model,
|
|||
break;
|
||||
case 0: break; default: EXIT(1);
|
||||
}
|
||||
switch (tile->devs[i].iob.in_term) {
|
||||
switch (tile->devs[i].u.iob.in_term) {
|
||||
case ITERM_NONE:
|
||||
fprintf(f, "%s in_term NONE\n", pref);
|
||||
break;
|
||||
|
@ -165,7 +165,7 @@ static int printf_IOB(FILE* f, struct fpga_model* model,
|
|||
break;
|
||||
case 0: break; default: EXIT(1);
|
||||
}
|
||||
switch (tile->devs[i].iob.out_term) {
|
||||
switch (tile->devs[i].u.iob.out_term) {
|
||||
case OTERM_NONE:
|
||||
fprintf(f, "%s out_term NONE\n", pref);
|
||||
break;
|
||||
|
@ -189,7 +189,7 @@ static int read_IOB_attr(struct fpga_model* model, struct fpga_device* dev,
|
|||
{
|
||||
// First the one-word attributes.
|
||||
if (!str_cmp(w1, w1_len, "O_used", ZTERM)) {
|
||||
dev->iob.O_used = 1;
|
||||
dev->u.iob.O_used = 1;
|
||||
goto inst_1;
|
||||
}
|
||||
// The remaining attributes all require 2 words.
|
||||
|
@ -197,84 +197,84 @@ static int read_IOB_attr(struct fpga_model* model, struct fpga_device* dev,
|
|||
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;
|
||||
memcpy(dev->u.iob.istandard, w2, w2_len);
|
||||
dev->u.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;
|
||||
memcpy(dev->u.iob.ostandard, w2, w2_len);
|
||||
dev->u.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;
|
||||
dev->u.iob.bypass_mux = BYPASS_MUX_I;
|
||||
else if (!str_cmp(w2, w2_len, "O", ZTERM))
|
||||
dev->iob.bypass_mux = BYPASS_MUX_O;
|
||||
dev->u.iob.bypass_mux = BYPASS_MUX_O;
|
||||
else if (!str_cmp(w2, w2_len, "T", ZTERM))
|
||||
dev->iob.bypass_mux = BYPASS_MUX_T;
|
||||
dev->u.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;
|
||||
dev->u.iob.I_mux = IMUX_I_B;
|
||||
else if (!str_cmp(w2, w2_len, "I", ZTERM))
|
||||
dev->iob.I_mux = IMUX_I;
|
||||
dev->u.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);
|
||||
dev->u.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;
|
||||
dev->u.iob.slew = SLEW_SLOW;
|
||||
else if (!str_cmp(w2, w2_len, "FAST", ZTERM))
|
||||
dev->iob.slew = SLEW_FAST;
|
||||
dev->u.iob.slew = SLEW_FAST;
|
||||
else if (!str_cmp(w2, w2_len, "QUIETIO", ZTERM))
|
||||
dev->iob.slew = SLEW_QUIETIO;
|
||||
dev->u.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;
|
||||
dev->u.iob.suspend = SUSP_LAST_VAL;
|
||||
else if (!str_cmp(w2, w2_len, "3STATE", ZTERM))
|
||||
dev->iob.suspend = SUSP_3STATE;
|
||||
dev->u.iob.suspend = SUSP_3STATE;
|
||||
else if (!str_cmp(w2, w2_len, "3STATE_PULLUP", ZTERM))
|
||||
dev->iob.suspend = SUSP_3STATE_PULLUP;
|
||||
dev->u.iob.suspend = SUSP_3STATE_PULLUP;
|
||||
else if (!str_cmp(w2, w2_len, "3STATE_PULLDOWN", ZTERM))
|
||||
dev->iob.suspend = SUSP_3STATE_PULLDOWN;
|
||||
dev->u.iob.suspend = SUSP_3STATE_PULLDOWN;
|
||||
else if (!str_cmp(w2, w2_len, "3STATE_KEEPER", ZTERM))
|
||||
dev->iob.suspend = SUSP_3STATE_KEEPER;
|
||||
dev->u.iob.suspend = SUSP_3STATE_KEEPER;
|
||||
else if (!str_cmp(w2, w2_len, "3STATE_OCT_ON", ZTERM))
|
||||
dev->iob.suspend = SUSP_3STATE_OCT_ON;
|
||||
dev->u.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;
|
||||
dev->u.iob.in_term = ITERM_NONE;
|
||||
else if (!str_cmp(w2, w2_len, "UNTUNED_SPLIT_25", ZTERM))
|
||||
dev->iob.in_term = ITERM_UNTUNED_25;
|
||||
dev->u.iob.in_term = ITERM_UNTUNED_25;
|
||||
else if (!str_cmp(w2, w2_len, "UNTUNED_SPLIT_50", ZTERM))
|
||||
dev->iob.in_term = ITERM_UNTUNED_50;
|
||||
dev->u.iob.in_term = ITERM_UNTUNED_50;
|
||||
else if (!str_cmp(w2, w2_len, "UNTUNED_SPLIT_75", ZTERM))
|
||||
dev->iob.in_term = ITERM_UNTUNED_75;
|
||||
dev->u.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;
|
||||
dev->u.iob.out_term = OTERM_NONE;
|
||||
else if (!str_cmp(w2, w2_len, "UNTUNED_25", ZTERM))
|
||||
dev->iob.out_term = OTERM_UNTUNED_25;
|
||||
dev->u.iob.out_term = OTERM_UNTUNED_25;
|
||||
else if (!str_cmp(w2, w2_len, "UNTUNED_50", ZTERM))
|
||||
dev->iob.out_term = OTERM_UNTUNED_50;
|
||||
dev->u.iob.out_term = OTERM_UNTUNED_50;
|
||||
else if (!str_cmp(w2, w2_len, "UNTUNED_75", ZTERM))
|
||||
dev->iob.out_term = OTERM_UNTUNED_75;
|
||||
dev->u.iob.out_term = OTERM_UNTUNED_75;
|
||||
else return 0;
|
||||
goto inst_2;
|
||||
}
|
||||
|
@ -287,12 +287,14 @@ inst_2:
|
|||
return 2;
|
||||
}
|
||||
|
||||
static const char* s_fplut_str[] = FP_LUT_STR;
|
||||
|
||||
static int printf_LOGIC(FILE* f, struct fpga_model* model,
|
||||
int y, int x, int config_only)
|
||||
{
|
||||
struct fpga_tile* tile;
|
||||
char pref[256];
|
||||
int type_count, i;
|
||||
int type_count, i, j;
|
||||
|
||||
tile = YX_TILE(model, y, x);
|
||||
type_count = 0;
|
||||
|
@ -308,7 +310,7 @@ static int printf_LOGIC(FILE* f, struct fpga_model* model,
|
|||
type_count++;
|
||||
|
||||
if (!config_only) {
|
||||
switch (tile->devs[i].logic.subtype) {
|
||||
switch (tile->devs[i].subtype) {
|
||||
case LOGIC_X:
|
||||
fprintf(f, "%s type X\n", pref);
|
||||
break;
|
||||
|
@ -321,73 +323,64 @@ static int printf_LOGIC(FILE* f, struct fpga_model* model,
|
|||
default: EXIT(1);
|
||||
}
|
||||
}
|
||||
if (tile->devs[i].logic.A_used)
|
||||
if (tile->devs[i].u.logic.A_used)
|
||||
fprintf(f, "%s A_used\n", pref);
|
||||
if (tile->devs[i].logic.B_used)
|
||||
if (tile->devs[i].u.logic.B_used)
|
||||
fprintf(f, "%s B_used\n", pref);
|
||||
if (tile->devs[i].logic.C_used)
|
||||
if (tile->devs[i].u.logic.C_used)
|
||||
fprintf(f, "%s C_used\n", pref);
|
||||
if (tile->devs[i].logic.D_used)
|
||||
if (tile->devs[i].u.logic.D_used)
|
||||
fprintf(f, "%s D_used\n", pref);
|
||||
if (tile->devs[i].logic.A6_lut && tile->devs[i].logic.A6_lut[0])
|
||||
fprintf(f, "%s A6_lut %s\n", pref,
|
||||
tile->devs[i].logic.A6_lut);
|
||||
if (tile->devs[i].logic.B6_lut && tile->devs[i].logic.B6_lut[0])
|
||||
fprintf(f, "%s B6_lut %s\n", pref,
|
||||
tile->devs[i].logic.B6_lut);
|
||||
if (tile->devs[i].logic.C6_lut && tile->devs[i].logic.C6_lut[0])
|
||||
fprintf(f, "%s C6_lut %s\n", pref,
|
||||
tile->devs[i].logic.C6_lut);
|
||||
if (tile->devs[i].logic.D6_lut && tile->devs[i].logic.D6_lut[0])
|
||||
fprintf(f, "%s D6_lut %s\n", pref,
|
||||
tile->devs[i].logic.D6_lut);
|
||||
{
|
||||
for (j = 0; j < sizeof(tile->devs[i].u.logic.luts)
|
||||
/ sizeof(tile->devs[i].u.logic.luts[0]); j++) {
|
||||
if (tile->devs[i].u.logic.luts[j]
|
||||
&& tile->devs[i].u.logic.luts[j][0])
|
||||
fprintf(f, "%s %s %s\n", pref,
|
||||
s_fplut_str[j],
|
||||
tile->devs[i].u.logic.luts[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int read_LOGIC_attr(struct fpga_model* model, struct fpga_device* dev,
|
||||
static int read_LOGIC_attr(struct fpga_model* model, int y, int x, int type_idx,
|
||||
const char* w1, int w1_len, const char* w2, int w2_len)
|
||||
{
|
||||
struct fpga_device* dev;
|
||||
int i, rc;
|
||||
|
||||
dev = fdev_p(model, y, x, DEV_LOGIC, type_idx);
|
||||
if (!dev) { HERE(); return 0; }
|
||||
|
||||
// First the one-word attributes.
|
||||
if (!str_cmp(w1, w1_len, "A_used", ZTERM)) {
|
||||
dev->logic.A_used = 1;
|
||||
dev->u.logic.A_used = 1;
|
||||
goto inst_1;
|
||||
}
|
||||
if (!str_cmp(w1, w1_len, "B_used", ZTERM)) {
|
||||
dev->logic.B_used = 1;
|
||||
dev->u.logic.B_used = 1;
|
||||
goto inst_1;
|
||||
}
|
||||
if (!str_cmp(w1, w1_len, "C_used", ZTERM)) {
|
||||
dev->logic.C_used = 1;
|
||||
dev->u.logic.C_used = 1;
|
||||
goto inst_1;
|
||||
}
|
||||
if (!str_cmp(w1, w1_len, "D_used", ZTERM)) {
|
||||
dev->logic.D_used = 1;
|
||||
dev->u.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;
|
||||
for (i = 0; i < sizeof(dev->u.logic.luts)/sizeof(dev->u.logic.luts[0]); i++) {
|
||||
if (!str_cmp(w1, w1_len, s_fplut_str[i], ZTERM)) {
|
||||
rc = fdev_logic_set_lut(model, y, x, type_idx, i, w2, w2_len);
|
||||
if (rc) return 0;
|
||||
goto inst_2;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
inst_1:
|
||||
|
@ -419,7 +412,7 @@ int printf_devices(FILE* f, struct fpga_model* model, int config_only)
|
|||
|| tile->devs[i].type == DEV_IOB)
|
||||
continue; // handled above
|
||||
fprintf(f, "dev y%02i x%02i %s\n", y, x,
|
||||
fpgadev_str(tile->devs[i].type));
|
||||
fdev_type2str(tile->devs[i].type));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -696,13 +689,13 @@ static void read_net_line(struct fpga_model* model, const char* line, int start)
|
|||
|| !all_digits(&line[dev_type_idx_str_beg], dev_type_idx_str_end-dev_type_idx_str_beg)
|
||||
|| str_cmp(&line[pin_str_beg], pin_str_end-pin_str_beg, "pin", 3))
|
||||
{ HERE(); return; }
|
||||
dev_type = fpgadev_str2type(&line[dev_str_beg], dev_str_end-dev_str_beg);
|
||||
dev_type = fdev_str2type(&line[dev_str_beg], dev_str_end-dev_str_beg);
|
||||
if (dev_type == DEV_NONE) { HERE(); return; }
|
||||
dev_idx = fpga_dev_idx(model, y_coord, x_coord, dev_type,
|
||||
to_i(&line[dev_type_idx_str_beg],
|
||||
dev_type_idx_str_end-dev_type_idx_str_beg));
|
||||
if (dev_idx == NO_DEV) { HERE(); return; }
|
||||
pinw_idx = fpgadev_pinw_str2idx(dev_type, &line[pin_name_beg],
|
||||
pinw_idx = fdev_pinw_str2idx(dev_type, &line[pin_name_beg],
|
||||
pin_name_end-pin_name_beg);
|
||||
if (pinw_idx == PINW_NO_IDX) { HERE(); return; }
|
||||
if (fpga_net_add_port(model, net_idx, y_coord, x_coord, dev_idx, pinw_idx))
|
||||
|
@ -750,7 +743,8 @@ static void read_dev_line(struct fpga_model* model, const char* line, int start)
|
|||
second_end-second_beg);
|
||||
break;
|
||||
case DEV_LOGIC:
|
||||
words_consumed = read_LOGIC_attr(model, dev_ptr,
|
||||
words_consumed = read_LOGIC_attr(model, y_coord,
|
||||
x_coord, dev_type_idx,
|
||||
&line[next_beg], next_end-next_beg,
|
||||
&line[second_beg],
|
||||
second_end-second_beg);
|
||||
|
|
22
model.h
22
model.h
|
@ -385,11 +385,16 @@ enum { // input:
|
|||
"AQ", "BQ", "CQ", "DQ", \
|
||||
"COUT" }
|
||||
|
||||
// offsets into fpgadev_logic:luts[]
|
||||
enum { A5_LUT = 0, A6_LUT, B5_LUT, B6_LUT, C5_LUT, C6_LUT, D5_LUT, D6_LUT, NUM_LUTS };
|
||||
#define FP_LUT_STR \
|
||||
{ "A5_lut", "A6_lut", "B5_lut", "B6_lut", \
|
||||
"C5_lut", "C6_lut", "D5_lut", "D6_lut" }
|
||||
|
||||
struct fpgadev_logic
|
||||
{
|
||||
int subtype; // LOGIC_M, LOGIC_L or LOGIC_X
|
||||
int A_used, B_used, C_used, D_used;
|
||||
char* A6_lut, *B6_lut, *C6_lut, *D6_lut;
|
||||
char* luts[NUM_LUTS];
|
||||
};
|
||||
|
||||
enum { IOBM = 1, IOBS };
|
||||
|
@ -417,7 +422,6 @@ enum { // input:
|
|||
|
||||
struct fpgadev_iob
|
||||
{
|
||||
int subtype; // IOBM or IOBS
|
||||
IOSTANDARD istandard;
|
||||
IOSTANDARD ostandard;
|
||||
int bypass_mux;
|
||||
|
@ -435,6 +439,10 @@ typedef int pinw_idx_t; // index into pinw array
|
|||
struct fpga_device
|
||||
{
|
||||
enum fpgadev_type type;
|
||||
// subtypes:
|
||||
// IOB: IOBM, IOBS
|
||||
// LOGIC: LOGIC_M, LOGIC_L, LOGIC_X
|
||||
int subtype;
|
||||
int instantiated;
|
||||
|
||||
// A bram dev has about 190 pinwires (input and output
|
||||
|
@ -443,11 +451,17 @@ struct fpga_device
|
|||
// The array holds first the input wires, then the output wires.
|
||||
// Unused members are set to STRIDX_NO_ENTRY.
|
||||
str16_t* pinw;
|
||||
|
||||
// required pinwires depend on the given config and will
|
||||
// be deleted/invalidated on any config change.
|
||||
int pinw_req_total, pinw_req_in;
|
||||
pinw_idx_t* pinw_req_for_cfg;
|
||||
|
||||
// the rest will be memset to 0 on any device removal/uninstantiation
|
||||
union {
|
||||
struct fpgadev_logic logic;
|
||||
struct fpgadev_iob iob;
|
||||
};
|
||||
} u;
|
||||
};
|
||||
|
||||
#define SWITCH_USED 0x80000000
|
||||
|
|
|
@ -11,10 +11,8 @@
|
|||
|
||||
static int add_dev(struct fpga_model* model,
|
||||
int y, int x, int type, int subtype);
|
||||
static int init_iob(struct fpga_model* model, int y, int x,
|
||||
int idx, int subtype);
|
||||
static int init_logic(struct fpga_model* model, int y, int x,
|
||||
int idx, int subtype);
|
||||
static int init_iob(struct fpga_model* model, int y, int x, int idx);
|
||||
static int init_logic(struct fpga_model* model, int y, int x, int idx);
|
||||
|
||||
int init_devices(struct fpga_model* model)
|
||||
{
|
||||
|
@ -304,32 +302,26 @@ fail:
|
|||
|
||||
void free_devices(struct fpga_model* model)
|
||||
{
|
||||
int i, j;
|
||||
for (i = 0; i < model->x_width * model->y_height; i++) {
|
||||
if (!model->tiles[i].num_devs)
|
||||
continue;
|
||||
EXIT(!model->tiles[i].devs);
|
||||
for (j = 0; j < model->tiles[i].num_devs; j++) {
|
||||
free(model->tiles[i].devs[j].pinw);
|
||||
model->tiles[i].devs[j].pinw = 0;
|
||||
model->tiles[i].devs[j].num_pinw_total = 0;
|
||||
model->tiles[i].devs[j].num_pinw_in = 0;
|
||||
struct fpga_tile* tile;
|
||||
int x, y, i;
|
||||
|
||||
if (model->tiles[i].devs[j].type != DEV_LOGIC)
|
||||
for (x = 0; x < model->x_width; x++) {
|
||||
for (y = 0; y < model->y_height; y++) {
|
||||
tile = YX_TILE(model, y, x);
|
||||
if (!tile->num_devs)
|
||||
continue;
|
||||
|
||||
free(model->tiles[i].devs[i].logic.A6_lut);
|
||||
model->tiles[i].devs[i].logic.A6_lut = 0;
|
||||
free(model->tiles[i].devs[i].logic.B6_lut);
|
||||
model->tiles[i].devs[i].logic.B6_lut = 0;
|
||||
free(model->tiles[i].devs[i].logic.C6_lut);
|
||||
model->tiles[i].devs[i].logic.C6_lut = 0;
|
||||
free(model->tiles[i].devs[i].logic.D6_lut);
|
||||
model->tiles[i].devs[i].logic.D6_lut = 0;
|
||||
if (!tile->devs) {
|
||||
HERE();
|
||||
continue;
|
||||
}
|
||||
for (i = 0; i < tile->num_devs; i++) {
|
||||
fdev_delete(model, y, x, tile->devs[i].type,
|
||||
fdev_typeidx(model, y, x, i));
|
||||
}
|
||||
free(tile->devs);
|
||||
tile->devs = 0;
|
||||
tile->num_devs = 0;
|
||||
}
|
||||
free(model->tiles[i].devs);
|
||||
model->tiles[i].devs = 0;
|
||||
model->tiles[i].num_devs = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -356,11 +348,12 @@ static int add_dev(struct fpga_model* model,
|
|||
|
||||
// init new device
|
||||
tile->devs[new_dev_i].type = type;
|
||||
tile->devs[new_dev_i].subtype = subtype;
|
||||
if (type == DEV_IOB) {
|
||||
rc = init_iob(model, y, x, new_dev_i, subtype);
|
||||
rc = init_iob(model, y, x, new_dev_i);
|
||||
if (rc) FAIL(rc);
|
||||
} else if (type == DEV_LOGIC) {
|
||||
rc = init_logic(model, y, x, new_dev_i, subtype);
|
||||
rc = init_logic(model, y, x, new_dev_i);
|
||||
if (rc) FAIL(rc);
|
||||
}
|
||||
return 0;
|
||||
|
@ -368,8 +361,7 @@ fail:
|
|||
return rc;
|
||||
}
|
||||
|
||||
static int init_iob(struct fpga_model* model, int y, int x,
|
||||
int idx, int subtype)
|
||||
static int init_iob(struct fpga_model* model, int y, int x, int idx)
|
||||
{
|
||||
struct fpga_tile* tile;
|
||||
const char* prefix;
|
||||
|
@ -377,8 +369,7 @@ static int init_iob(struct fpga_model* model, int y, int x,
|
|||
char tmp_str[128];
|
||||
|
||||
tile = YX_TILE(model, y, x);
|
||||
tile->devs[idx].iob.subtype = subtype;
|
||||
type_idx = fpga_dev_typeidx(model, y, x, idx);
|
||||
type_idx = fdev_typeidx(model, y, x, idx);
|
||||
if (!y)
|
||||
prefix = "TIOB";
|
||||
else if (y == model->y_height - BOT_OUTER_ROW)
|
||||
|
@ -446,20 +437,18 @@ fail:
|
|||
return rc;
|
||||
}
|
||||
|
||||
static int init_logic(struct fpga_model* model, int y, int x,
|
||||
int idx, int subtype)
|
||||
static int init_logic(struct fpga_model* model, int y, int x, int idx)
|
||||
{
|
||||
struct fpga_tile* tile;
|
||||
const char* pre;
|
||||
int i, j, rc;
|
||||
|
||||
tile = YX_TILE(model, y, x);
|
||||
tile->devs[idx].logic.subtype = subtype;
|
||||
if (subtype == LOGIC_M)
|
||||
if (tile->devs[idx].subtype == LOGIC_M)
|
||||
pre = "M_";
|
||||
else if (subtype == LOGIC_L)
|
||||
else if (tile->devs[idx].subtype == LOGIC_L)
|
||||
pre = "L_";
|
||||
else if (subtype == LOGIC_X) {
|
||||
else if (tile->devs[idx].subtype == LOGIC_X) {
|
||||
pre = is_atx(X_FABRIC_LOGIC_XL_COL|X_CENTER_LOGIC_COL, model, x)
|
||||
? "XX_" : "X_";
|
||||
} else FAIL(EINVAL);
|
||||
|
@ -481,7 +470,7 @@ static int init_logic(struct fpga_model* model, int y, int x,
|
|||
/*dup_warn*/ 1,
|
||||
&tile->devs[idx].pinw[LOGIC_IN_AX+i], 0);
|
||||
if (rc) FAIL(rc);
|
||||
if (subtype == LOGIC_M) {
|
||||
if (tile->devs[idx].subtype == LOGIC_M) {
|
||||
rc = add_connpt_name(model, y, x, pf("%s%cI", pre, 'A'+i),
|
||||
/*dup_warn*/ 1,
|
||||
&tile->devs[idx].pinw[LOGIC_IN_AI+i], 0);
|
||||
|
@ -513,14 +502,14 @@ static int init_logic(struct fpga_model* model, int y, int x,
|
|||
/*dup_warn*/ 1,
|
||||
&tile->devs[idx].pinw[LOGIC_IN_SR], 0);
|
||||
if (rc) FAIL(rc);
|
||||
if (subtype == LOGIC_M) {
|
||||
if (tile->devs[idx].subtype == LOGIC_M) {
|
||||
rc = add_connpt_name(model, y, x, pf("%sWE", pre),
|
||||
/*dup_warn*/ 1,
|
||||
&tile->devs[idx].pinw[LOGIC_IN_WE], 0);
|
||||
if (rc) FAIL(rc);
|
||||
} else
|
||||
tile->devs[idx].pinw[LOGIC_IN_WE] = STRIDX_NO_ENTRY;
|
||||
if (subtype != LOGIC_X
|
||||
if (tile->devs[idx].subtype != LOGIC_X
|
||||
&& ((is_atx(X_ROUTING_NO_IO, model, x-1)
|
||||
&& is_aty(Y_INNER_BOTTOM, model, y+1))
|
||||
|| (!is_atx(X_ROUTING_NO_IO, model, x-1)
|
||||
|
@ -531,12 +520,12 @@ static int init_logic(struct fpga_model* model, int y, int x,
|
|||
if (rc) FAIL(rc);
|
||||
} else
|
||||
tile->devs[idx].pinw[LOGIC_IN_CIN] = STRIDX_NO_ENTRY;
|
||||
if (subtype == LOGIC_M) {
|
||||
if (tile->devs[idx].subtype == LOGIC_M) {
|
||||
rc = add_connpt_name(model, y, x, "M_COUT",
|
||||
/*dup_warn*/ 1,
|
||||
&tile->devs[idx].pinw[LOGIC_OUT_COUT], 0);
|
||||
if (rc) FAIL(rc);
|
||||
} else if (subtype == LOGIC_L) {
|
||||
} else if (tile->devs[idx].subtype == LOGIC_L) {
|
||||
rc = add_connpt_name(model, y, x, "XL_COUT",
|
||||
/*dup_warn*/ 1,
|
||||
&tile->devs[idx].pinw[LOGIC_OUT_COUT], 0);
|
||||
|
|
|
@ -145,11 +145,8 @@ int has_device_type(struct fpga_model* model, int y, int x, int dev, int subtype
|
|||
if (tile->devs[i].type == dev) {
|
||||
switch (dev) {
|
||||
case DEV_LOGIC:
|
||||
if (tile->devs[i].logic.subtype == subtype)
|
||||
return 1;
|
||||
break;
|
||||
case DEV_IOB:
|
||||
if (tile->devs[i].iob.subtype == subtype)
|
||||
if (tile->devs[i].subtype == subtype)
|
||||
return 1;
|
||||
break;
|
||||
default: EXIT(1);
|
||||
|
|
Loading…
Reference in New Issue
Block a user