added lut_encoding tests

This commit is contained in:
Wolfgang Spraul 2012-10-03 04:15:52 +02:00
parent fd21f8ce9d
commit 3c04a14023
10 changed files with 515 additions and 124 deletions

View File

@ -128,7 +128,7 @@ fail:
// goal: configure logic devices in all supported variations
static int test_logic_config(struct test_state* tstate)
{
int idx_enum[] = { DEV_LOGM, DEV_LOGX };
int idx_enum[] = { DEV_LOG_M_OR_L, DEV_LOG_X };
int y, x, i, j, k, rc;
y = 68;
@ -139,7 +139,7 @@ static int test_logic_config(struct test_state* tstate)
// A1..A6 to A..D
for (k = '1'; k <= '6'; k++) {
rc = fdev_logic_set_lut(tstate->model, y, x,
rc = fdev_logic_a2d_lut(tstate->model, y, x,
idx_enum[i], j, 6, pf("A%c", k), ZTERM);
if (rc) FAIL(rc);
rc = fdev_set_required_pins(tstate->model, y, x,
@ -155,10 +155,10 @@ static int test_logic_config(struct test_state* tstate)
}
// A1 to O6 to FF to AQ
rc = fdev_logic_set_lut(tstate->model, y, x,
rc = fdev_logic_a2d_lut(tstate->model, y, x,
idx_enum[i], j, 6, "A1", ZTERM);
if (rc) FAIL(rc);
rc = fdev_logic_FF(tstate->model, y, x, idx_enum[i],
rc = fdev_logic_a2d_ff(tstate->model, y, x, idx_enum[i],
j, MUX_O6, FF_SRINIT0);
if (rc) FAIL(rc);
rc = fdev_logic_sync(tstate->model, y, x, idx_enum[i],
@ -167,9 +167,9 @@ static int test_logic_config(struct test_state* tstate)
rc = fdev_logic_clk(tstate->model, y, x, idx_enum[i],
CLKINV_B);
if (rc) FAIL(rc);
rc = fdev_logic_ceused(tstate->model, y, x, idx_enum[i]);
rc = fdev_logic_ce_used(tstate->model, y, x, idx_enum[i]);
if (rc) FAIL(rc);
rc = fdev_logic_srused(tstate->model, y, x, idx_enum[i]);
rc = fdev_logic_sr_used(tstate->model, y, x, idx_enum[i]);
if (rc) FAIL(rc);
rc = fdev_set_required_pins(tstate->model, y, x,
@ -599,24 +599,24 @@ static int test_routing_sw_from_logic(struct test_state* tstate,
// from below, or sr1/sl1 wires from above.
for (rel_y = -1; rel_y <= 1; rel_y += 2) {
for (i = '1'; i <= '6'; i++) {
rc = fdev_logic_set_lut(tstate->model, y, x,
DEV_LOGM, LUT_A, 6, pf("A%c", i), ZTERM);
rc = fdev_logic_a2d_lut(tstate->model, y, x,
DEV_LOG_M_OR_L, LUT_A, 6, pf("A%c", i), ZTERM);
if (rc) FAIL(rc);
rc = fdev_set_required_pins(tstate->model, y, x,
DEV_LOGIC, DEV_LOGM);
DEV_LOGIC, DEV_LOG_M_OR_L);
if (rc) FAIL(rc);
if (tstate->dry_run)
fdev_print_required_pins(tstate->model,
y, x, DEV_LOGIC, DEV_LOGM);
dev = fdev_p(tstate->model, y, x, DEV_LOGIC, DEV_LOGM);
y, x, DEV_LOGIC, DEV_LOG_M_OR_L);
dev = fdev_p(tstate->model, y, x, DEV_LOGIC, DEV_LOG_M_OR_L);
if (!dev) FAIL(EINVAL);
if (!dev->pinw_req_in) FAIL(EINVAL);
rc = fnet_new(tstate->model, &net);
if (rc) FAIL(rc);
rc = fnet_add_port(tstate->model, net, y, x,
DEV_LOGIC, DEV_LOGM, dev->pinw_req_for_cfg[0]);
DEV_LOGIC, DEV_LOG_M_OR_L, dev->pinw_req_for_cfg[0]);
if (rc) FAIL(rc);
swto.model = tstate->model;
@ -665,7 +665,7 @@ static int test_routing_sw_from_logic(struct test_state* tstate,
if (rc) FAIL(rc);
}
destruct_sw_conns(&conns);
fdev_delete(tstate->model, y, x, DEV_LOGIC, DEV_LOGM);
fdev_delete(tstate->model, y, x, DEV_LOGIC, DEV_LOG_M_OR_L);
fnet_delete(tstate->model, net);
}
}
@ -677,7 +677,7 @@ fail:
// goal: use all switches in a routing switchbox
static int test_routing_switches(struct test_state* tstate)
{
int idx_enum[] = { DEV_LOGM, DEV_LOGX };
int idx_enum[] = { DEV_LOG_M_OR_L, DEV_LOG_X };
int y, x, i, j, k, r, rc;
swidx_t done_sw_list[MAX_SWITCHBOX_SIZE];
int done_sw_len;
@ -699,12 +699,9 @@ static int test_routing_switches(struct test_state* tstate)
// A1-A6 to A (same for lut B-D)
for (k = '1'; k <= '6'; k++) {
rc = fdev_logic_set_lut(tstate->model, y, x,
rc = fdev_logic_a2d_lut(tstate->model, y, x,
idx_enum[i], j, 6, pf("A%c", k), ZTERM);
if (rc) FAIL(rc);
rc = fdev_logic_out_used(tstate->model, y, x,
idx_enum[i], j);
if (rc) FAIL(rc);
if (!r)
rc = test_logic_net_l1(tstate, y, x, DEV_LOGIC,
@ -719,10 +716,10 @@ static int test_routing_switches(struct test_state* tstate)
}
// A1->O6->FF->AQ (same for lut B-D)
rc = fdev_logic_set_lut(tstate->model, y, x,
rc = fdev_logic_a2d_lut(tstate->model, y, x,
idx_enum[i], j, 6, "A1", ZTERM);
if (rc) FAIL(rc);
rc = fdev_logic_FF(tstate->model, y, x, idx_enum[i],
rc = fdev_logic_a2d_ff(tstate->model, y, x, idx_enum[i],
j, MUX_O6, FF_SRINIT0);
if (rc) FAIL(rc);
rc = fdev_logic_sync(tstate->model, y, x, idx_enum[i],
@ -731,9 +728,9 @@ static int test_routing_switches(struct test_state* tstate)
rc = fdev_logic_clk(tstate->model, y, x, idx_enum[i],
CLKINV_B);
if (rc) FAIL(rc);
rc = fdev_logic_ceused(tstate->model, y, x, idx_enum[i]);
rc = fdev_logic_ce_used(tstate->model, y, x, idx_enum[i]);
if (rc) FAIL(rc);
rc = fdev_logic_srused(tstate->model, y, x, idx_enum[i]);
rc = fdev_logic_sr_used(tstate->model, y, x, idx_enum[i]);
if (rc) FAIL(rc);
rc = fdev_set_required_pins(tstate->model, y, x,
@ -986,6 +983,155 @@ fail:
return rc;
}
static int test_lut(struct test_state* tstate, int y, int x, int type_idx,
int lut, const char* lut6, const char* lut5)
{
struct fpga_device* dev;
net_idx_t pinw_nets[MAX_NUM_PINW];
int i, rc;
if (tstate->dry_run)
printf("O lut6 '%s' lut5 '%s'\n",
lut6 ? lut6 : "-", lut5 ? lut5 : "-");
if (lut6) {
rc = fdev_logic_a2d_lut(tstate->model, y, x,
type_idx, lut, 6, lut6, ZTERM);
if (rc) FAIL(rc);
}
if (lut5) {
rc = fdev_logic_a2d_lut(tstate->model, y, x,
type_idx, lut, 5, lut5, ZTERM);
if (rc) FAIL(rc);
}
rc = fdev_set_required_pins(tstate->model, y, x, DEV_LOGIC, type_idx);
if (rc) FAIL(rc);
if (tstate->dry_run) {
fdev_print_required_pins(tstate->model, y, x,
DEV_LOGIC, type_idx);
}
// add stub nets for each required pin
dev = fdev_p(tstate->model, y, x, DEV_LOGIC, type_idx);
if (!dev) FAIL(EINVAL);
for (i = 0; i < dev->pinw_req_total; i++) {
// i < dev->pinw_req_in -> input
rc = fnet_new(tstate->model, &pinw_nets[i]);
if (rc) FAIL(rc);
rc = fnet_add_port(tstate->model, pinw_nets[i], y, x,
DEV_LOGIC, type_idx, dev->pinw_req_for_cfg[i]);
if (rc) FAIL(rc);
if ((dev->pinw_req_for_cfg[i] == LI_A6
&& dev->u.logic.a2d[LUT_A].lut5
&& *dev->u.logic.a2d[LUT_A].lut5)
|| (dev->pinw_req_for_cfg[i] == LI_B6
&& dev->u.logic.a2d[LUT_B].lut5
&& *dev->u.logic.a2d[LUT_B].lut5)
|| (dev->pinw_req_for_cfg[i] == LI_C6
&& dev->u.logic.a2d[LUT_C].lut5
&& *dev->u.logic.a2d[LUT_C].lut5)
|| (dev->pinw_req_for_cfg[i] == LI_D6
&& dev->u.logic.a2d[LUT_D].lut5
&& *dev->u.logic.a2d[LUT_D].lut5)) {
rc = fnet_route_to_inpins(tstate->model, pinw_nets[i], "VCC_WIRE");
if (rc) FAIL(rc);
}
}
if ((rc = diff_printf(tstate))) FAIL(rc);
for (i = 0; i < dev->pinw_req_total; i++)
fnet_delete(tstate->model, pinw_nets[i]);
fdev_delete(tstate->model, y, x, DEV_LOGIC, type_idx);
return 0;
fail:
return rc;
}
static int test_lut_encoding(struct test_state* tstate)
{
int idx_enum[] = { DEV_LOG_M_OR_L, DEV_LOG_X };
int x_enum[] = { /*xm*/ 13, /* center-xl*/ 22, /*xl*/ 39 };
int y, x_i, i, j, k, lut_str_len, rc;
int type_i, lut;
char lut_str[128];
const char* lut5_parents[] = {"(A6+~A6)*1", "(A6+~A6)*0",
"(A6+~A6)*A1", "(A6+~A6)*A3", 0};
tstate->diff_to_null = 1;
y = 68;
for (x_i = 0; x_i < sizeof(x_enum)/sizeof(*x_enum); x_i++) {
for (type_i = 0; type_i < sizeof(idx_enum)/sizeof(*idx_enum); type_i++) {
for (lut = LUT_A; lut <= LUT_D; lut++) {
// lut6 only
rc = test_lut(tstate, y, x_enum[x_i], idx_enum[type_i],
lut, "0", /*lut5*/ 0);
if (rc) FAIL(rc);
rc = test_lut(tstate, y, x_enum[x_i], idx_enum[type_i],
lut, "1", /*lut5*/ 0);
if (rc) FAIL(rc);
for (i = '1'; i <= '6'; i++) {
snprintf(lut_str, sizeof(lut_str), "A%c", i);
rc = test_lut(tstate, y, x_enum[x_i], idx_enum[type_i],
lut, lut_str, /*lut5*/ 0);
if (rc) FAIL(rc);
}
for (i = 0; i < 64; i++) {
lut_str_len = 0;
for (j = 0; j < 6; j++) {
if (lut_str_len)
lut_str[lut_str_len++] = '*';
if (!(i & (1<<j)))
lut_str[lut_str_len++] = '~';
lut_str[lut_str_len++] = 'A';
lut_str[lut_str_len++] = '1' + j;
}
lut_str[lut_str_len] = 0;
rc = test_lut(tstate, y, x_enum[x_i], idx_enum[type_i],
lut, lut_str, /*lut5*/ 0);
if (rc) FAIL(rc);
}
// lut6 and lut5 pairs
i = 0;
while (lut5_parents[i]) {
rc = test_lut(tstate, y, x_enum[x_i], idx_enum[type_i],
lut, /*lut6*/ lut5_parents[i], /*lut5*/ "0");
if (rc) FAIL(rc);
rc = test_lut(tstate, y, x_enum[x_i], idx_enum[type_i],
lut, /*lut6*/ lut5_parents[i], /*lut5*/ "1");
if (rc) FAIL(rc);
for (j = '1'; j <= '5'; j++) {
snprintf(lut_str, sizeof(lut_str), "A%c", j);
rc = test_lut(tstate, y, x_enum[x_i], idx_enum[type_i],
lut, /*lut6*/ lut5_parents[i], /*lut5*/ lut_str);
if (rc) FAIL(rc);
}
for (j = 0; j < 32; j++) {
lut_str_len = 0;
for (k = 0; k < 5; k++) {
if (lut_str_len)
lut_str[lut_str_len++] = '*';
if (!(j & (1<<k)))
lut_str[lut_str_len++] = '~';
lut_str[lut_str_len++] = 'A';
lut_str[lut_str_len++] = '1' + k;
}
lut_str[lut_str_len] = 0;
rc = test_lut(tstate, y, x_enum[x_i], idx_enum[type_i],
lut, /*lut6*/ lut5_parents[i], /*lut5*/ lut_str);
if (rc) FAIL(rc);
}
i++;
}
}
}
}
out:
return 0;
fail:
return rc;
}
#define DEFAULT_DIFF_EXEC "./autotest_diff.sh"
static void printf_help(const char* argv_0, const char** available_tests)
@ -1016,7 +1162,7 @@ int main(int argc, char** argv)
char param[1024], cmdline_test[1024];
int i, param_skip, rc;
const char* available_tests[] =
{ "logic_cfg", "routing_sw", "io_sw", "iob_cfg", 0 };
{ "logic_cfg", "routing_sw", "io_sw", "iob_cfg", "lut_encoding", 0 };
// flush after every line is better for the autotest
// output, tee, etc.
@ -1141,6 +1287,10 @@ int main(int argc, char** argv)
rc = test_iob_config(&tstate);
if (rc) FAIL(rc);
}
if (!strcmp(cmdline_test, "lut_encoding")) {
rc = test_lut_encoding(&tstate);
if (rc) FAIL(rc);
}
printf("\n");
printf("O Test completed.\n");

View File

@ -39,11 +39,9 @@ int main(int argc, char** argv)
logic_y = 68;
logic_x = 13;
logic_type_idx = DEV_LOGX;
if ((rc = fdev_logic_set_lut(&model, logic_y, logic_x, logic_type_idx,
logic_type_idx = DEV_LOG_X;
if ((rc = fdev_logic_a2d_lut(&model, logic_y, logic_x, logic_type_idx,
LUT_D, 6, "A3*A5", ZTERM))) FAIL(rc);
if ((rc = fdev_logic_out_used(&model, logic_y, logic_x, logic_type_idx,
LUT_D))) FAIL(rc);
if ((rc = fnet_new(&model, &inA_net))) FAIL(rc);
if ((rc = fnet_add_port(&model, inA_net, iob_inA_y, iob_inA_x,

View File

@ -39,11 +39,9 @@ int main(int argc, char** argv)
logic_y = 68;
logic_x = 13;
logic_type_idx = DEV_LOGX;
if ((rc = fdev_logic_set_lut(&model, logic_y, logic_x, logic_type_idx,
logic_type_idx = DEV_LOG_X;
if ((rc = fdev_logic_a2d_lut(&model, logic_y, logic_x, logic_type_idx,
LUT_D, 6, "A3*A5", ZTERM))) FAIL(rc);
if ((rc = fdev_logic_out_used(&model, logic_y, logic_x, logic_type_idx,
LUT_D))) FAIL(rc);
if ((rc = fnet_new(&model, &inA_net))) FAIL(rc);
if ((rc = fnet_add_port(&model, inA_net, iob_inA_y, iob_inA_x,

View File

@ -354,7 +354,7 @@ static int extract_logic(struct fpga_model* model, struct fpga_bits* bits)
if (row_pos >= 8) byte_off += HCLK_BYTES;
// M device
dev_idx = fpga_dev_idx(model, y, x, DEV_LOGIC, DEV_LOGM);
dev_idx = fpga_dev_idx(model, y, x, DEV_LOGIC, DEV_LOG_M_OR_L);
if (dev_idx == NO_DEV) FAIL(EINVAL);
// A6_LUT
@ -364,7 +364,7 @@ static int extract_logic(struct fpga_model* model, struct fpga_bits* bits)
{ int logic_base[6] = {0,1,0,0,1,0};
lut_str = lut2bool(u64, 64, &logic_base, /*flip_b0*/ 1); }
if (*lut_str) {
rc = fdev_logic_set_lut(model, y, x, DEV_LOGM,
rc = fdev_logic_a2d_lut(model, y, x, DEV_LOG_M_OR_L,
LUT_A, 6, lut_str, ZTERM);
if (rc) FAIL(rc);
*(uint32_t*)(u8_p+24*FRAME_SIZE+byte_off+4) = 0;
@ -378,7 +378,7 @@ static int extract_logic(struct fpga_model* model, struct fpga_bits* bits)
{ int logic_base[6] = {1,1,0,1,0,1};
lut_str = lut2bool(u64, 64, &logic_base, /*flip_b0*/ 1); }
if (*lut_str) {
rc = fdev_logic_set_lut(model, y, x, DEV_LOGM,
rc = fdev_logic_a2d_lut(model, y, x, DEV_LOG_M_OR_L,
LUT_B, 6, lut_str, ZTERM);
if (rc) FAIL(rc);
*(uint32_t*)(u8_p+21*FRAME_SIZE+byte_off+4) = 0;
@ -392,7 +392,7 @@ static int extract_logic(struct fpga_model* model, struct fpga_bits* bits)
{ int logic_base[6] = {0,1,0,0,1,0};
lut_str = lut2bool(u64, 64, &logic_base, /*flip_b0*/ 1); }
if (*lut_str) {
rc = fdev_logic_set_lut(model, y, x, DEV_LOGM,
rc = fdev_logic_a2d_lut(model, y, x, DEV_LOG_M_OR_L,
LUT_C, 6, lut_str, ZTERM);
if (rc) FAIL(rc);
*(uint32_t*)(u8_p+24*FRAME_SIZE+byte_off) = 0;
@ -406,7 +406,7 @@ static int extract_logic(struct fpga_model* model, struct fpga_bits* bits)
{ int logic_base[6] = {1,1,0,1,0,1};
lut_str = lut2bool(u64, 64, &logic_base, /*flip_b0*/ 1); }
if (*lut_str) {
rc = fdev_logic_set_lut(model, y, x, DEV_LOGM,
rc = fdev_logic_a2d_lut(model, y, x, DEV_LOG_M_OR_L,
LUT_D, 6, lut_str, ZTERM);
if (rc) FAIL(rc);
*(uint32_t*)(u8_p+21*FRAME_SIZE+byte_off) = 0;
@ -433,16 +433,19 @@ static int extract_logic(struct fpga_model* model, struct fpga_bits* bits)
continue;
}
dev_idx = fpga_dev_idx(model, y, x, DEV_LOGIC, DEV_LOGX);
dev_idx = fpga_dev_idx(model, y, x, DEV_LOGIC, DEV_LOG_X);
if (dev_idx == NO_DEV) FAIL(EINVAL);
*(uint64_t*)(u8_p+26*FRAME_SIZE+byte_off) = 0;
// A6_LUT
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 = fdev_logic_set_lut(model, y, x, DEV_LOGX,
if (!u64) lut_str = 0;
else {
int logic_base[6] = {1,1,0,1,1,0};
lut_str = lut2bool(u64, 64, &logic_base, /*flip_b0*/ 0);
}
if (lut_str && *lut_str) {
rc = fdev_logic_a2d_lut(model, y, x, DEV_LOG_X,
LUT_A, 6, lut_str, ZTERM);
if (rc) FAIL(rc);
*(uint32_t*)(u8_p+27*FRAME_SIZE+byte_off+4) = 0;
@ -450,30 +453,39 @@ static int extract_logic(struct fpga_model* model, struct fpga_bits* bits)
}
// B6_LUT
u64 = read_lut64(u8_p + 29*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 = fdev_logic_set_lut(model, y, x, DEV_LOGX,
if (!u64) lut_str = 0;
else {
int logic_base[6] = {1,1,0,1,1,0};
lut_str = lut2bool(u64, 64, &logic_base, /*flip_b0*/ 0);
}
if (lut_str && *lut_str) {
rc = fdev_logic_a2d_lut(model, y, x, DEV_LOG_X,
LUT_B, 6, 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;
}
// C6_LUT
u64 = read_lut64(u8_p + 27*FRAME_SIZE, byte_off*8);
{ int logic_base[6] = {0,1,0,0,0,1};
lut_str = lut2bool(u64, 64, &logic_base, /*flip_b0*/ 0); }
if (*lut_str) {
rc = fdev_logic_set_lut(model, y, x, DEV_LOGX,
if (!u64) lut_str = 0;
else {
int logic_base[6] = {0,1,0,0,0,1};
lut_str = lut2bool(u64, 64, &logic_base, /*flip_b0*/ 0);
}
if (lut_str && *lut_str) {
rc = fdev_logic_a2d_lut(model, y, x, DEV_LOG_X,
LUT_C, 6, lut_str, ZTERM);
*(uint32_t*)(u8_p+27*FRAME_SIZE+byte_off) = 0;
*(uint32_t*)(u8_p+28*FRAME_SIZE+byte_off) = 0;
}
// D6_LUT
u64 = read_lut64(u8_p + 29*FRAME_SIZE, byte_off*8);
{ int logic_base[6] = {0,1,0,0,0,1};
lut_str = lut2bool(u64, 64, &logic_base, /*flip_b0*/ 0); }
if (*lut_str) {
rc = fdev_logic_set_lut(model, y, x, DEV_LOGX,
if (!u64) lut_str = 0;
else {
int logic_base[6] = {0,1,0,0,0,1};
lut_str = lut2bool(u64, 64, &logic_base, /*flip_b0*/ 0);
}
if (lut_str && *lut_str) {
rc = fdev_logic_a2d_lut(model, y, x, DEV_LOG_X,
LUT_D, 6, lut_str, ZTERM);
*(uint32_t*)(u8_p+29*FRAME_SIZE+byte_off) = 0;
*(uint32_t*)(u8_p+30*FRAME_SIZE+byte_off) = 0;
@ -1074,7 +1086,7 @@ static int write_logic(struct fpga_bits* bits, struct fpga_model* model)
if (xm_col) {
// X device
dev_idx = fpga_dev_idx(model, y, x, DEV_LOGIC, DEV_LOGX);
dev_idx = fpga_dev_idx(model, y, x, DEV_LOGIC, DEV_LOG_X);
if (dev_idx == NO_DEV) FAIL(EINVAL);
dev = FPGA_DEV(model, y, x, dev_idx);
if (dev->instantiated) {
@ -1102,7 +1114,7 @@ static int write_logic(struct fpga_bits* bits, struct fpga_model* model)
}
// M device
dev_idx = fpga_dev_idx(model, y, x, DEV_LOGIC, DEV_LOGM);
dev_idx = fpga_dev_idx(model, y, x, DEV_LOGIC, DEV_LOG_M_OR_L);
if (dev_idx == NO_DEV) FAIL(EINVAL);
dev = FPGA_DEV(model, y, x, dev_idx);
if (dev->instantiated) {
@ -1110,7 +1122,7 @@ static int write_logic(struct fpga_bits* bits, struct fpga_model* model)
}
} else {
// X device
dev_idx = fpga_dev_idx(model, y, x, DEV_LOGIC, DEV_LOGX);
dev_idx = fpga_dev_idx(model, y, x, DEV_LOGIC, DEV_LOG_X);
if (dev_idx == NO_DEV) FAIL(EINVAL);
dev = FPGA_DEV(model, y, x, dev_idx);
if (dev->instantiated) {
@ -1118,7 +1130,7 @@ static int write_logic(struct fpga_bits* bits, struct fpga_model* model)
}
// L device
dev_idx = fpga_dev_idx(model, y, x, DEV_LOGIC, DEV_LOGL);
dev_idx = fpga_dev_idx(model, y, x, DEV_LOGIC, DEV_LOG_M_OR_L);
if (dev_idx == NO_DEV) FAIL(EINVAL);
dev = FPGA_DEV(model, y, x, dev_idx);
if (dev->instantiated) {

View File

@ -225,7 +225,11 @@ 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; }
if (dev_idx == NO_DEV) {
fprintf(stderr, "#E %s:%i fdev_p() y%02i x%02i type %i/%i not"
" found\n", __FILE__, __LINE__, y, x, type, type_idx);
return 0;
}
return FPGA_DEV(model, y, x, dev_idx);
}
@ -395,6 +399,13 @@ void fdev_print_required_pins(struct fpga_model* model, int y, int x,
static void add_req_inpin(struct fpga_device* dev, pinw_idx_t pinw_i)
{
int i;
// check for duplicate
for (i = 0; i < dev->pinw_req_in; i++) {
if (dev->pinw_req_for_cfg[i] == pinw_i)
return;
}
if (dev->pinw_req_total > dev->pinw_req_in) {
memmove(&dev->pinw_req_for_cfg[dev->pinw_req_in+1],
&dev->pinw_req_for_cfg[dev->pinw_req_in],
@ -408,11 +419,40 @@ static void add_req_inpin(struct fpga_device* dev, pinw_idx_t pinw_i)
static void add_req_outpin(struct fpga_device* dev, pinw_idx_t pinw_i)
{
int i;
// check for duplicate
for (i = dev->pinw_req_in; i < dev->pinw_req_total; i++) {
if (dev->pinw_req_for_cfg[i] == pinw_i)
return;
}
dev->pinw_req_for_cfg[dev->pinw_req_total] = pinw_i;
dev->pinw_req_total++;
}
int fdev_logic_set_lut(struct fpga_model* model, int y, int x, int type_idx,
//
// logic device
//
int fdev_logic_a2d_out_used(struct fpga_model* model, int y, int x,
int type_idx, int lut_a2d, int used)
{
struct fpga_device* dev;
int rc;
dev = fdev_p(model, y, x, DEV_LOGIC, type_idx);
if (!dev) FAIL(EINVAL);
rc = reset_required_pins(dev);
if (rc) FAIL(rc);
dev->u.logic.a2d[lut_a2d].out_used = (used != 0);
dev->instantiated = 1;
return 0;
fail:
return rc;
}
int fdev_logic_a2d_lut(struct fpga_model* model, int y, int x, int type_idx,
int lut_a2d, int lut_5or6, const char* lut_str, int lut_len)
{
struct fpga_device* dev;
@ -435,31 +475,28 @@ int fdev_logic_set_lut(struct fpga_model* model, int y, int x, int type_idx,
memcpy(*lut_ptr, lut_str, lut_len);
(*lut_ptr)[lut_len] = 0;
// todo: the logic by which we auto-enable the direct
// output could have more cases, the O6 signal
// could go into the carry chain/XOR/CY, F7/F8, others?
// O5 could go into carry chain/XOR/CY, others?
// We need to find out over time what makes sense for
// the caller.
if (lut_5or6 == 6
&& dev->u.logic.a2d[lut_a2d].ff_mux != MUX_O6
&& dev->u.logic.a2d[lut_a2d].out_mux != MUX_O6)
dev->u.logic.a2d[lut_a2d].out_used = 1;
if (lut_5or6 == 5
&& dev->u.logic.a2d[lut_a2d].ff_mux != MUX_O5
&& !dev->u.logic.a2d[lut_a2d].out_mux)
dev->u.logic.a2d[lut_a2d].out_mux = MUX_O5;
dev->instantiated = 1;
return 0;
fail:
return rc;
}
int fdev_logic_out_used(struct fpga_model* model, int y, int x, int type_idx,
int lut_a2d)
{
struct fpga_device* dev;
int rc;
dev = fdev_p(model, y, x, DEV_LOGIC, type_idx);
if (!dev) FAIL(EINVAL);
rc = reset_required_pins(dev);
if (rc) FAIL(rc);
dev->u.logic.a2d[lut_a2d].used = 1;
dev->instantiated = 1;
return 0;
fail:
return rc;
}
int fdev_logic_FF(struct fpga_model* model, int y, int x, int type_idx,
int fdev_logic_a2d_ff(struct fpga_model* model, int y, int x, int type_idx,
int lut_a2d, int ff_mux, int srinit)
{
struct fpga_device* dev;
@ -479,6 +516,44 @@ fail:
return rc;
}
int fdev_logic_a2d_out_mux(struct fpga_model* model, int y, int x,
int type_idx, int lut_a2d, int out_mux)
{
struct fpga_device* dev;
int rc;
dev = fdev_p(model, y, x, DEV_LOGIC, type_idx);
if (!dev) FAIL(EINVAL);
rc = reset_required_pins(dev);
if (rc) FAIL(rc);
dev->u.logic.a2d[lut_a2d].out_mux = out_mux;
dev->instantiated = 1;
return 0;
fail:
return rc;
}
int fdev_logic_a2d_cy0(struct fpga_model* model, int y, int x,
int type_idx, int lut_a2d, int cy0)
{
struct fpga_device* dev;
int rc;
dev = fdev_p(model, y, x, DEV_LOGIC, type_idx);
if (!dev) FAIL(EINVAL);
rc = reset_required_pins(dev);
if (rc) FAIL(rc);
dev->u.logic.a2d[lut_a2d].cy0 = cy0;
// todo: when cy0 is CY0_O5 and lut5 is empty, set to "0"
// (same for setting ff_mux or out_mux to MUX_O5
dev->instantiated = 1;
return 0;
fail:
return rc;
}
int fdev_logic_clk(struct fpga_model* model, int y, int x, int type_idx,
int clk)
{
@ -515,7 +590,7 @@ fail:
return rc;
}
int fdev_logic_ceused(struct fpga_model* model, int y, int x, int type_idx)
int fdev_logic_ce_used(struct fpga_model* model, int y, int x, int type_idx)
{
struct fpga_device* dev;
int rc;
@ -532,7 +607,7 @@ fail:
return rc;
}
int fdev_logic_srused(struct fpga_model* model, int y, int x, int type_idx)
int fdev_logic_sr_used(struct fpga_model* model, int y, int x, int type_idx)
{
struct fpga_device* dev;
int rc;
@ -549,6 +624,64 @@ fail:
return rc;
}
int fdev_logic_we_mux(struct fpga_model* model, int y, int x,
int type_idx, int we_mux)
{
struct fpga_device* dev;
int rc;
dev = fdev_p(model, y, x, DEV_LOGIC, type_idx);
if (!dev) FAIL(EINVAL);
rc = reset_required_pins(dev);
if (rc) FAIL(rc);
dev->u.logic.we_mux = we_mux;
dev->instantiated = 1;
return 0;
fail:
return rc;
}
int fdev_logic_cout_used(struct fpga_model* model, int y, int x,
int type_idx, int used)
{
struct fpga_device* dev;
int rc;
dev = fdev_p(model, y, x, DEV_LOGIC, type_idx);
if (!dev) FAIL(EINVAL);
rc = reset_required_pins(dev);
if (rc) FAIL(rc);
dev->u.logic.cout_used = (used != 0);
dev->instantiated = 1;
return 0;
fail:
return rc;
}
int fdev_logic_precyinit(struct fpga_model* model, int y, int x,
int type_idx, int precyinit)
{
struct fpga_device* dev;
int rc;
dev = fdev_p(model, y, x, DEV_LOGIC, type_idx);
if (!dev) FAIL(EINVAL);
rc = reset_required_pins(dev);
if (rc) FAIL(rc);
dev->u.logic.precyinit = precyinit;
dev->instantiated = 1;
return 0;
fail:
return rc;
}
//
// iob device
//
int fdev_iob_input(struct fpga_model* model, int y, int x, int type_idx)
{
struct fpga_device* dev;
@ -596,9 +729,13 @@ static void scan_lut_digits(const char* s, int* digits)
for (i = 0; i < 6; i++)
digits[i] = 0;
if (!s) return;
// Note special cases "0" and "1" for a lut that
// always results in 0 or 1.
for (i = 0; s[i]; i++) {
if (s[i] >= '1' && s[i] <= '6')
digits[s[i]-'1']++;
if (s[i] != 'A' && s[i] != 'a')
continue;
if (s[i+1] >= '1' && s[i+1] <= '6')
digits[s[++i]-'1']++;
}
}
@ -620,16 +757,28 @@ int fdev_set_required_pins(struct fpga_model* model, int y, int x, int type,
add_req_inpin(dev, LI_CE);
if (dev->u.logic.sr_used)
add_req_inpin(dev, LI_SR);
if (dev->u.logic.cout_used) {
add_req_outpin(dev, LO_COUT);
if (!dev->u.logic.precyinit)
add_req_inpin(dev, LI_CIN);
}
if (dev->u.logic.precyinit == PRECYINIT_AX)
add_req_inpin(dev, LI_AX);
for (i = LUT_A; i <= LUT_D; i++) {
if (dev->u.logic.a2d[i].used) {
if (dev->u.logic.a2d[i].out_used) {
// LO_A..LO_D are in sequence
add_req_outpin(dev, LO_A+i);
}
if (dev->u.logic.a2d[i].out_mux) {
// LO_AMUX..LO_DMUX are in sequence
add_req_outpin(dev, LO_AMUX+i);
}
if (dev->u.logic.a2d[i].ff) {
// LO_AQ..LO_DQ are in sequence
add_req_outpin(dev, LO_AQ+i);
}
if (dev->u.logic.a2d[i].ff_mux == MUX_X) {
if (dev->u.logic.a2d[i].ff_mux == MUX_X
|| dev->u.logic.a2d[i].cy0 == CY0_X) {
// LI_AX..LI_DX are in sequence
add_req_inpin(dev, LI_AX+i);
}
@ -641,12 +790,18 @@ int fdev_set_required_pins(struct fpga_model* model, int y, int x, int type,
}
}
if (dev->u.logic.a2d[i].lut5) {
// A6 must be high/vcc if lut5 is used
add_req_inpin(dev, LI_A6+i*6);
scan_lut_digits(dev->u.logic.a2d[i].lut5, digits);
for (j = 0; j < 6; j++) {
if (!digits[j]) continue;
add_req_inpin(dev, LI_A1+i*6+j);
}
}
if ((dev->u.logic.a2d[i].ff_mux == MUX_XOR
|| dev->u.logic.a2d[i].out_mux == MUX_XOR)
&& !dev->u.logic.precyinit)
add_req_inpin(dev, LI_CIN);
}
return 0;
}
@ -1983,6 +2138,46 @@ fail:
return rc;
}
int fnet_route_to_inpins(struct fpga_model* model, net_idx_t net_i,
const char* from)
{
struct fpga_net* net_p;
struct fpga_device* dev_p;
str16_t from_i;
struct sw_set start_set, end_set;
int i, rc;
net_p = fnet_get(model, net_i);
if (!net_p) FAIL(EINVAL);
from_i = strarray_find(&model->str, from);
if (from_i == STRIDX_NO_ENTRY) FAIL(EINVAL);
for (i = 0; i < net_p->len; i++) {
if (!(net_p->el[i].idx & NET_IDX_IS_PINW))
// skip existing switch
continue;
dev_p = FPGA_DEV(model, net_p->el[i].y,
net_p->el[i].x, net_p->el[i].dev_idx);
if ((net_p->el[i].idx & NET_IDX_MASK) >= dev_p->num_pinw_in)
// skip outpin
continue;
rc = froute_direct(model, net_p->el[i].y, net_p->el[i].x-1,
from_i, net_p->el[i].y, net_p->el[i].x,
dev_p->pinw[net_p->el[i].idx & NET_IDX_MASK],
&start_set, &end_set);
if (rc) FAIL(rc);
rc = fnet_add_sw(model, net_i, net_p->el[i].y,
net_p->el[i].x-1, start_set.sw, start_set.len);
if (rc) FAIL(rc);
rc = fnet_add_sw(model, net_i, net_p->el[i].y,
net_p->el[i].x, end_set.sw, end_set.len);
if (rc) FAIL(rc);
}
return 0;
fail:
return rc;
}
int froute_direct(struct fpga_model* model, int start_y, int start_x,
str16_t start_pt, int end_y, int end_x, str16_t end_pt,
struct sw_set* start_set, struct sw_set* end_set)

View File

@ -46,23 +46,37 @@ const char* fdev_pinw_idx2str(int devtype, pinw_idx_t idx);
const char* fdev_logic_pinstr(pinw_idx_t idx, int ld1_type);
str16_t fdev_logic_pinstr_i(struct fpga_model* model, pinw_idx_t idx, int ld1_type);
// lut_a2d is LUT_A to LUT_D value, lut_5or6 is int 5 or int 6.
int fdev_logic_set_lut(struct fpga_model* model, int y, int x, int type_idx,
// lut_a2d is LUT_A to LUT_D
int fdev_logic_a2d_out_used(struct fpga_model* model, int y, int x,
int type_idx, int lut_a2d, int used);
// lut_5or6 is int 5 or int 6
int fdev_logic_a2d_lut(struct fpga_model* model, int y, int x, int type_idx,
int lut_a2d, int lut_5or6, const char* lut_str, int lut_len);
int fdev_logic_out_used(struct fpga_model* model, int y, int x, int type_idx,
int lut_a2d);
// ff_mux is MUX_O6 or MUX_X
// srinit is FF_SRINIT0 or FF_SRINIT1
int fdev_logic_FF(struct fpga_model* model, int y, int x, int type_idx,
int fdev_logic_a2d_ff(struct fpga_model* model, int y, int x, int type_idx,
int lut_a2d, int ff_mux, int srinit);
int fdev_logic_a2d_out_mux(struct fpga_model* model, int y, int x,
int type_idx, int lut_a2d, int out_mux);
// cy0 is CY0_X or CY0_O5
int fdev_logic_a2d_cy0(struct fpga_model* model, int y, int x,
int type_idx, int lut_a2d, int cy0);
// clk is CLKINV_B or CLKINV_CLK
int fdev_logic_clk(struct fpga_model* model, int y, int x, int type_idx,
int clk);
// sync is SYNCATTR_SYNC or SYNCATTR_ASYNC
int fdev_logic_sync(struct fpga_model* model, int y, int x, int type_idx,
int sync_attr);
int fdev_logic_ceused(struct fpga_model* model, int y, int x, int type_idx);
int fdev_logic_srused(struct fpga_model* model, int y, int x, int type_idx);
int fdev_logic_ce_used(struct fpga_model* model, int y, int x, int type_idx);
int fdev_logic_sr_used(struct fpga_model* model, int y, int x, int type_idx);
// we_mux can be WEMUX_WE or WEMUX_CE
int fdev_logic_we_mux(struct fpga_model* model, int y, int x,
int type_idx, int we_mux);
int fdev_logic_cout_used(struct fpga_model* model, int y, int x,
int type_idx, int used);
// precyinit can be PRECYINIT_O, PRECYINIT_1 or PRECYINIT_AX
int fdev_logic_precyinit(struct fpga_model* model, int y, int x,
int type_idx, int precyinit);
int fdev_iob_input(struct fpga_model* model, int y, int x, int type_idx);
int fdev_iob_output(struct fpga_model* model, int y, int x, int type_idx);
@ -335,6 +349,9 @@ void fnet_printf(FILE* f, struct fpga_model* model, net_idx_t net_i);
int fnet_autoroute(struct fpga_model* model, net_idx_t net_i);
int fnet_route_to_inpins(struct fpga_model* model, net_idx_t net_i,
const char* from);
//
// routing
//

View File

@ -324,7 +324,7 @@ static int printf_LOGIC(FILE* f, struct fpga_model* model,
}
cfg = &tile->devs[i].u.logic;
for (j = LUT_A; j <= LUT_D; j++) {
if (cfg->a2d[j].used)
if (cfg->a2d[j].out_used)
fprintf(f, "%s %c_used\n", pref, 'A'+j);
if (cfg->a2d[j].lut6 && cfg->a2d[j].lut6[0])
fprintf(f, "%s %c6_lut %s\n", pref, 'A'+j,
@ -343,15 +343,21 @@ static int printf_LOGIC(FILE* f, struct fpga_model* model,
case MUX_X:
fprintf(f, "%s %c_ffmux X\n", pref, 'A'+j);
break;
case MUX_F7:
fprintf(f, "%s %c_ffmux F7\n", pref, 'A'+j);
break;
case MUX_CY:
fprintf(f, "%s %c_ffmux CY\n", pref, 'A'+j);
break;
case MUX_XOR:
fprintf(f, "%s %c_ffmux XOR\n", pref, 'A'+j);
break;
case MUX_F7:
fprintf(f, "%s %c_ffmux F7\n", pref, 'A'+j);
break;
case MUX_F8:
fprintf(f, "%s %c_ffmux F8\n", pref, 'A'+j);
break;
case MUX_MC31:
fprintf(f, "%s %c_ffmux MC31\n", pref, 'A'+j);
break;
case 0: break; default: FAIL(EINVAL);
}
switch (cfg->a2d[j].ff_srinit) {
@ -373,15 +379,21 @@ static int printf_LOGIC(FILE* f, struct fpga_model* model,
case MUX_5Q:
fprintf(f, "%s %c_outmux 5Q\n", pref, 'A'+j);
break;
case MUX_F7:
fprintf(f, "%s %c_outmux F7\n", pref, 'A'+j);
break;
case MUX_CY:
fprintf(f, "%s %c_outmux CY\n", pref, 'A'+j);
break;
case MUX_XOR:
fprintf(f, "%s %c_outmux XOR\n", pref, 'A'+j);
break;
case MUX_F7:
fprintf(f, "%s %c_outmux F7\n", pref, 'A'+j);
break;
case MUX_F8:
fprintf(f, "%s %c_outmux F8\n", pref, 'A'+j);
break;
case MUX_MC31:
fprintf(f, "%s %c_outmux MC31\n", pref, 'A'+j);
break;
case 0: break; default: FAIL(EINVAL);
}
switch (cfg->a2d[j].ff) {
@ -474,7 +486,7 @@ static int read_LOGIC_attr(struct fpga_model* model, int y, int x, int type_idx,
for (i = LUT_A; i <= LUT_D; i++) {
snprintf(cmp_str, sizeof(cmp_str), "%c_used", 'A'+i);
if (!str_cmp(w1, w1_len, cmp_str, ZTERM)) {
dev->u.logic.a2d[i].used = 1;
dev->u.logic.a2d[i].out_used = 1;
goto inst_1;
}
}
@ -499,13 +511,13 @@ static int read_LOGIC_attr(struct fpga_model* model, int y, int x, int type_idx,
for (i = LUT_A; i <= LUT_D; i++) {
snprintf(cmp_str, sizeof(cmp_str), "%c6_lut", 'A'+i);
if (!str_cmp(w1, w1_len, cmp_str, ZTERM)) {
rc = fdev_logic_set_lut(model, y, x, type_idx, i, 6, w2, w2_len);
rc = fdev_logic_a2d_lut(model, y, x, type_idx, i, 6, w2, w2_len);
if (rc) return 0;
goto inst_2;
}
snprintf(cmp_str, sizeof(cmp_str), "%c5_lut", 'A'+i);
if (!str_cmp(w1, w1_len, cmp_str, ZTERM)) {
rc = fdev_logic_set_lut(model, y, x, type_idx, i, 5, w2, w2_len);
rc = fdev_logic_a2d_lut(model, y, x, type_idx, i, 5, w2, w2_len);
if (rc) return 0;
goto inst_2;
}
@ -517,12 +529,16 @@ static int read_LOGIC_attr(struct fpga_model* model, int y, int x, int type_idx,
dev->u.logic.a2d[i].ff_mux = MUX_O5;
else if (!str_cmp(w2, w2_len, "X", ZTERM))
dev->u.logic.a2d[i].ff_mux = MUX_X;
else if (!str_cmp(w2, w2_len, "F7", ZTERM))
dev->u.logic.a2d[i].ff_mux = MUX_F7;
else if (!str_cmp(w2, w2_len, "CY", ZTERM))
dev->u.logic.a2d[i].ff_mux = MUX_CY;
else if (!str_cmp(w2, w2_len, "XOR", ZTERM))
dev->u.logic.a2d[i].ff_mux = MUX_XOR;
else if (!str_cmp(w2, w2_len, "F7", ZTERM))
dev->u.logic.a2d[i].ff_mux = MUX_F7;
else if (!str_cmp(w2, w2_len, "F8", ZTERM))
dev->u.logic.a2d[i].ff_mux = MUX_F8;
else if (!str_cmp(w2, w2_len, "MC31", ZTERM))
dev->u.logic.a2d[i].ff_mux = MUX_MC31;
else return 0;
goto inst_2;
}
@ -543,12 +559,16 @@ static int read_LOGIC_attr(struct fpga_model* model, int y, int x, int type_idx,
dev->u.logic.a2d[i].out_mux = MUX_O5;
else if (!str_cmp(w2, w2_len, "5Q", ZTERM))
dev->u.logic.a2d[i].out_mux = MUX_5Q;
else if (!str_cmp(w2, w2_len, "F7", ZTERM))
dev->u.logic.a2d[i].out_mux = MUX_F7;
else if (!str_cmp(w2, w2_len, "CY", ZTERM))
dev->u.logic.a2d[i].out_mux = MUX_CY;
else if (!str_cmp(w2, w2_len, "XOR", ZTERM))
dev->u.logic.a2d[i].out_mux = MUX_XOR;
else if (!str_cmp(w2, w2_len, "F7", ZTERM))
dev->u.logic.a2d[i].out_mux = MUX_F7;
else if (!str_cmp(w2, w2_len, "F8", ZTERM))
dev->u.logic.a2d[i].out_mux = MUX_F8;
else if (!str_cmp(w2, w2_len, "MC31", ZTERM))
dev->u.logic.a2d[i].out_mux = MUX_MC31;
else return 0;
goto inst_2;
}

View File

@ -245,6 +245,9 @@ const char* lut2bool(const uint64_t lut, int bits,
int str_end, first_op;
static char str[2048];
if (!lut) return "0";
if (lut == 0xFFFFFFFFFFFFFFFFULL) return "1";
memset(mt, 0, sizeof(mt));
memset(mt_size, 0, sizeof(mt_size));

View File

@ -346,9 +346,8 @@ typedef int dev_type_idx_t;
// M and L device is always at type index 0, X device
// is always at type index 1.
#define DEV_LOGM 0
#define DEV_LOGL 0
#define DEV_LOGX 1
#define DEV_LOG_M_OR_L 0
#define DEV_LOG_X 1
// All device configuration is structured so that the value
// 0 is never a valid configured setting. That way all config
@ -368,14 +367,10 @@ enum {
// input:
LI_FIRST = 0,
LI_A1 = LI_FIRST,
LI_A2, LI_A3, LI_A4, LI_A5, LI_A6,
LI_B1, LI_B2, LI_B3, LI_B4, LI_B5,
LI_B6,
LI_C1, LI_C2, LI_C3, LI_C4, LI_C5,
LI_C6,
LI_D1, LI_D2, LI_D3, LI_D4, LI_D5,
LI_D6,
LI_A1 = LI_FIRST, LI_A2, LI_A3, LI_A4, LI_A5, LI_A6,
LI_B1, LI_B2, LI_B3, LI_B4, LI_B5, LI_B6,
LI_C1, LI_C2, LI_C3, LI_C4, LI_C5, LI_C6,
LI_D1, LI_D2, LI_D3, LI_D4, LI_D5, LI_D6,
LI_AX, LI_BX, LI_CX, LI_DX,
LI_CLK, LI_CE, LI_SR,
// only for L and M:
@ -410,7 +405,7 @@ enum {
enum { LUT_A = 0, LUT_B, LUT_C, LUT_D }; // offset into a2d[]
enum { FF_SRINIT0 = 1, FF_SRINIT1 };
enum { MUX_O6 = 1, MUX_O5, MUX_5Q, MUX_X, MUX_F7, MUX_CY, MUX_XOR };
enum { MUX_O6 = 1, MUX_O5, MUX_5Q, MUX_X, MUX_CY, MUX_XOR, MUX_F7, MUX_F8, MUX_MC31 };
enum { FF_OR2L = 1, FF_AND2L, FF_LATCH, FF_FF };
enum { CY0_X = 1, CY0_O5 };
enum { CLKINV_B = 1, CLKINV_CLK };
@ -422,12 +417,12 @@ enum { PRECYINIT_0 = 1, PRECYINIT_1, PRECYINIT_AX };
struct fpgadev_logic_a2d
{
int used;
int out_used;
char* lut6;
char* lut5;
int ff_mux; // O6, O5, X, F7, CY, XOR
int ff_mux; // O6, O5, X, F7(a/c), F8(b), MC31(d), CY, XOR
int ff_srinit; // SRINIT0, SRINIT1
int out_mux; // O6, O5, 5Q, F7, CY, XOR
int out_mux; // O6, O5, 5Q, F7(a/c), F8(b), MC31(d), CY, XOR
int ff; // OR2L, AND2L, LATCH, FF
int cy0; // X, O5
};
@ -492,6 +487,10 @@ struct fpgadev_iob
typedef int pinw_idx_t; // index into pinw array
// A bram dev has about 190 pinwires (input and output
// combined), macc about 350, mcb about 1200.
#define MAX_NUM_PINW 2048
struct fpga_device
{
enum fpgadev_type type;
@ -501,8 +500,6 @@ struct fpga_device
int subtype;
int instantiated;
// A bram dev has about 190 pinwires (input and output
// combined), macc about 350, mcb about 1200.
int num_pinw_total, num_pinw_in;
// The array holds first the input wires, then the output wires.
// Unused members are set to STRIDX_NO_ENTRY.

View File

@ -284,7 +284,8 @@ int init_devices(struct fpga_model* model)
if (!is_atx(X_FABRIC_LOGIC_COL|X_CENTER_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 (DEV_LOGM and DEV_LOGL), X is at index 1 (DEV_LOGX).
// M and L are at index 0 (DEV_LOG_M_OR_L),
// X is at index 1 (DEV_LOG_X).
if (YX_TILE(model, y, x)->flags & TF_LOGIC_XM_DEV) {
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;