better routing from and to logic block
This commit is contained in:
parent
9b059ec9b5
commit
3e5b83ed07
95
autotest.c
95
autotest.c
|
@ -136,7 +136,7 @@ static int test_net(struct test_state* tstate, net_idx_t net_i)
|
|||
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);
|
||||
net->el[2].idx, SW_TO), SW_TO, 1);
|
||||
same_len = sizeof(same_sw)/sizeof(*same_sw);
|
||||
rc = fpga_switch_same_fromto(tstate->model,
|
||||
net->el[2].y, net->el[2].x,
|
||||
|
@ -174,7 +174,7 @@ static int test_net2(struct test_state* tstate, net_idx_t net_i)
|
|||
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);
|
||||
net->el[i-1].idx, SW_FROM), SW_FROM, 1);
|
||||
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,
|
||||
|
@ -195,37 +195,13 @@ 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;
|
||||
struct fpga_device* dev;
|
||||
struct switch_to_yx switch_to;
|
||||
struct sw_chain chain;
|
||||
net_idx_t net_idx;
|
||||
int y, x, i, from_to, rc;
|
||||
|
||||
// todo: goal: configure valid logic with as many possible in and out
|
||||
// pins, for M and X device
|
||||
|
@ -238,10 +214,54 @@ static int test_all_logic_configs(struct test_state* tstate)
|
|||
|
||||
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);
|
||||
|
||||
fdev_print_required_pins(tstate->model, y, x, DEV_LOGIC, DEV_LOGX);
|
||||
rc = diff_printf(tstate);
|
||||
if (rc) FAIL(rc);
|
||||
dev = fdev_p(tstate->model, y, x, DEV_LOGIC, DEV_LOGX);
|
||||
if (!dev) FAIL(EINVAL);
|
||||
for (i = 0; i < dev->pinw_req_total; i++) {
|
||||
from_to = (i < dev->pinw_req_in) ? SW_TO : SW_FROM;
|
||||
switch_to.yx_req = YX_ROUTING_TILE;
|
||||
switch_to.flags = SWTO_YX_DEF;
|
||||
switch_to.model = tstate->model;
|
||||
switch_to.y = y;
|
||||
switch_to.x = x;
|
||||
switch_to.start_switch = dev->pinw[dev->pinw_req_for_cfg[i]];
|
||||
switch_to.from_to = from_to;
|
||||
rc = fpga_switch_to_yx(&switch_to);
|
||||
if (rc) FAIL(rc);
|
||||
// printf_switch_to_result(&switch_to);
|
||||
|
||||
chain.model = tstate->model;
|
||||
chain.y = switch_to.dest_y;
|
||||
chain.x = switch_to.dest_x;
|
||||
chain.start_switch = switch_to.dest_connpt;
|
||||
chain.from_to = from_to;
|
||||
chain.max_chain_size = 1;
|
||||
while (fpga_switch_chain(&chain) != NO_SWITCH) {
|
||||
rc = fpga_net_new(tstate->model, &net_idx);
|
||||
if (rc) FAIL(rc);
|
||||
|
||||
// add port
|
||||
rc = fpga_net_add_port(tstate->model, net_idx,
|
||||
y, x, fpga_dev_idx(tstate->model, y, x,
|
||||
DEV_LOGIC, DEV_LOGX), dev->pinw_req_for_cfg[i]);
|
||||
if (rc) FAIL(rc);
|
||||
// add (one) switch in logic tile
|
||||
rc = fpga_net_add_switches(tstate->model, net_idx,
|
||||
y, x, &switch_to.set);
|
||||
if (rc) FAIL(rc);
|
||||
// add switches in routing tile
|
||||
rc = fpga_net_add_switches(tstate->model, net_idx,
|
||||
switch_to.dest_y, switch_to.dest_x, &chain.set);
|
||||
if (rc) FAIL(rc);
|
||||
|
||||
// fprintf_net(stdout, tstate->model, net_idx);
|
||||
|
||||
rc = diff_printf(tstate);
|
||||
if (rc) FAIL(rc);
|
||||
fpga_net_delete(tstate->model, net_idx);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
fail:
|
||||
return rc;
|
||||
|
@ -349,6 +369,7 @@ int main(int argc, char** argv)
|
|||
switch_to.y = P46_y;
|
||||
switch_to.x = P46_x;
|
||||
switch_to.start_switch = P46_dev->pinw[IOB_OUT_I];
|
||||
switch_to.from_to = SW_FROM;
|
||||
rc = fpga_switch_to_yx(&switch_to);
|
||||
if (rc) FAIL(rc);
|
||||
rc = fpga_net_add_switches(&model, P46_net, switch_to.y,
|
||||
|
@ -357,9 +378,11 @@ int main(int argc, char** argv)
|
|||
|
||||
switch_to.yx_req = YX_ROUTING_TILE;
|
||||
switch_to.flags = SWTO_YX_DEF;
|
||||
switch_to.model = &model;
|
||||
switch_to.y = switch_to.dest_y;
|
||||
switch_to.x = switch_to.dest_x;
|
||||
switch_to.start_switch = switch_to.dest_connpt;
|
||||
switch_to.from_to = SW_FROM;
|
||||
rc = fpga_switch_to_yx(&switch_to);
|
||||
if (rc) FAIL(rc);
|
||||
rc = fpga_net_add_switches(&model, P46_net, switch_to.y,
|
||||
|
@ -368,9 +391,11 @@ int main(int argc, char** argv)
|
|||
|
||||
switch_to.yx_req = YX_ROUTING_TO_FABLOGIC;
|
||||
switch_to.flags = SWTO_YX_CLOSEST;
|
||||
switch_to.model = &model;
|
||||
switch_to.y = switch_to.dest_y;
|
||||
switch_to.x = switch_to.dest_x;
|
||||
switch_to.start_switch = switch_to.dest_connpt;
|
||||
switch_to.from_to = SW_FROM;
|
||||
rc = fpga_switch_to_yx(&switch_to);
|
||||
if (rc) FAIL(rc);
|
||||
rc = fpga_net_add_switches(&model, P46_net, switch_to.y,
|
||||
|
@ -379,9 +404,11 @@ int main(int argc, char** argv)
|
|||
|
||||
switch_to.yx_req = YX_DEV_LOGIC;
|
||||
switch_to.flags = SWTO_YX_TARGET_CONNPT|SWTO_YX_MAX_SWITCH_DEPTH;
|
||||
switch_to.model = &model;
|
||||
switch_to.y = switch_to.dest_y;
|
||||
switch_to.x = switch_to.dest_x;
|
||||
switch_to.start_switch = switch_to.dest_connpt;
|
||||
switch_to.from_to = SW_FROM;
|
||||
switch_to.max_switch_depth = 1;
|
||||
{
|
||||
struct sw_chain c = {
|
||||
|
|
39
bit_frames.c
39
bit_frames.c
|
@ -165,15 +165,6 @@ int extract_model(struct fpga_model* model, struct fpga_bits* bits)
|
|||
continue;
|
||||
}
|
||||
|
||||
// any logic block will enable r0ma17mi22b980
|
||||
if (!get_bit(bits, /*row*/ 0, /*major*/ 17,
|
||||
/*minor*/ 22, /*bit_i*/ 980)) {
|
||||
HERE();
|
||||
continue;
|
||||
}
|
||||
clear_bit(bits, /*row*/ 0, /*major*/ 17,
|
||||
/*minor*/ 22, /*bit_i*/ 980);
|
||||
|
||||
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);
|
||||
|
@ -216,6 +207,36 @@ int extract_model(struct fpga_model* model, struct fpga_bits* bits)
|
|||
*(uint32_t*)(u8_p+29*FRAME_SIZE+byte_off) = 0;
|
||||
*(uint32_t*)(u8_p+30*FRAME_SIZE+byte_off) = 0;
|
||||
}
|
||||
#if 0
|
||||
// M-LUTs
|
||||
lut64 = read_lut64(&maj_bits[24*130], frame_off+32);
|
||||
{ int logic_base[6] = {0,1,0,0,1,0};
|
||||
lut_str = lut2bool(lut64, 64, &logic_base, 1 /* flip_b0 */); }
|
||||
if (*lut_str)
|
||||
printf("r%i ma%i clb i%i s0_A6LUT \"%s\"\n",
|
||||
row, major, i-start, lut_str);
|
||||
|
||||
lut64 = read_lut64(&maj_bits[21*130], frame_off+32);
|
||||
{ int logic_base[6] = {1,1,0,1,0,1};
|
||||
lut_str = lut2bool(lut64, 64, &logic_base, 1 /* flip_b0 */); }
|
||||
if (*lut_str)
|
||||
printf("r%i ma%i clb i%i s0_B6LUT \"%s\"\n",
|
||||
row, major, i-start, lut_str);
|
||||
|
||||
lut64 = read_lut64(&maj_bits[24*130], frame_off);
|
||||
{ int logic_base[6] = {0,1,0,0,1,0};
|
||||
lut_str = lut2bool(lut64, 64, &logic_base, 1 /* flip_b0 */); }
|
||||
if (*lut_str)
|
||||
printf("r%i ma%i clb i%i s0_C6LUT \"%s\"\n",
|
||||
row, major, i-start, lut_str);
|
||||
|
||||
lut64 = read_lut64(&maj_bits[21*130], frame_off);
|
||||
{ int logic_base[6] = {1,1,0,1,0,1};
|
||||
lut_str = lut2bool(lut64, 64, &logic_base, 1 /* flip_b0 */); }
|
||||
if (*lut_str)
|
||||
printf("r%i ma%i clb i%i s0_D6LUT \"%s\"\n",
|
||||
row, major, i-start, lut_str);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
155
bit_regs.c
155
bit_regs.c
|
@ -713,103 +713,28 @@ static void print_ramb16_cfg(ramb16_cfg_t* cfg)
|
|||
printf("}\n");
|
||||
}
|
||||
|
||||
static void printf_clb(uint8_t* maj_bits, int row, int major)
|
||||
static void printf_routing_2minors(uint8_t* bits, int row, int major,
|
||||
int even_minor)
|
||||
{
|
||||
int i, j, start, max_idx, frame_off;
|
||||
const char* lut_str;
|
||||
uint64_t lut64;
|
||||
int y, i, hclk;
|
||||
uint64_t u64_0, u64_1;
|
||||
char bit_str[128];
|
||||
|
||||
// the first two slots on top and bottom row are not used for clb
|
||||
if (!row) {
|
||||
start = 0;
|
||||
max_idx = 14;
|
||||
} else if (row == 3) {
|
||||
start = 2;
|
||||
max_idx = 16;
|
||||
} else {
|
||||
start = 0;
|
||||
max_idx = 16;
|
||||
}
|
||||
|
||||
for (i = start; i < max_idx; i++) {
|
||||
if (clb_empty(maj_bits, i))
|
||||
continue;
|
||||
frame_off = i*64;
|
||||
if (i >= 8)
|
||||
frame_off += 16; // skip clock bits for idx >= 8
|
||||
|
||||
// LUTs
|
||||
lut64 = read_lut64(&maj_bits[24*130], frame_off+32);
|
||||
{ int logic_base[6] = {0,1,0,0,1,0};
|
||||
lut_str = lut2bool(lut64, 64, &logic_base, 1 /* flip_b0 */); }
|
||||
if (*lut_str)
|
||||
printf("r%i ma%i clb i%i s0_A6LUT \"%s\"\n",
|
||||
row, major, i-start, lut_str);
|
||||
|
||||
lut64 = read_lut64(&maj_bits[21*130], frame_off+32);
|
||||
{ int logic_base[6] = {1,1,0,1,0,1};
|
||||
lut_str = lut2bool(lut64, 64, &logic_base, 1 /* flip_b0 */); }
|
||||
if (*lut_str)
|
||||
printf("r%i ma%i clb i%i s0_B6LUT \"%s\"\n",
|
||||
row, major, i-start, lut_str);
|
||||
|
||||
lut64 = read_lut64(&maj_bits[24*130], frame_off);
|
||||
{ int logic_base[6] = {0,1,0,0,1,0};
|
||||
lut_str = lut2bool(lut64, 64, &logic_base, 1 /* flip_b0 */); }
|
||||
if (*lut_str)
|
||||
printf("r%i ma%i clb i%i s0_C6LUT \"%s\"\n",
|
||||
row, major, i-start, lut_str);
|
||||
|
||||
lut64 = read_lut64(&maj_bits[21*130], frame_off);
|
||||
{ int logic_base[6] = {1,1,0,1,0,1};
|
||||
lut_str = lut2bool(lut64, 64, &logic_base, 1 /* flip_b0 */); }
|
||||
if (*lut_str)
|
||||
printf("r%i ma%i clb i%i s0_D6LUT \"%s\"\n",
|
||||
row, major, i-start, lut_str);
|
||||
|
||||
lut64 = read_lut64(&maj_bits[27*130], frame_off+32);
|
||||
{ int logic_base[6] = {1,1,0,1,1,0};
|
||||
lut_str = lut2bool(lut64, 64, &logic_base, 0 /* flip_b0 */); }
|
||||
if (*lut_str)
|
||||
printf("r%i ma%i clb i%i s1_A6LUT \"%s\"\n",
|
||||
row, major, i-start, lut_str);
|
||||
|
||||
lut64 = read_lut64(&maj_bits[29*130], frame_off+32);
|
||||
{ int logic_base[6] = {1,1,0,1,1,0};
|
||||
lut_str = lut2bool(lut64, 64, &logic_base, 0 /* flip_b0 */); }
|
||||
if (*lut_str)
|
||||
printf("r%i ma%i clb i%i s1_B6LUT \"%s\"\n",
|
||||
row, major, i-start, lut_str);
|
||||
|
||||
lut64 = read_lut64(&maj_bits[27*130], frame_off);
|
||||
{ int logic_base[6] = {0,1,0,0,0,1};
|
||||
lut_str = lut2bool(lut64, 64, &logic_base, 0 /* flip_b0 */); }
|
||||
if (*lut_str)
|
||||
printf("r%i ma%i clb i%i s1_C6LUT \"%s\"\n",
|
||||
row, major, i-start, lut_str);
|
||||
|
||||
lut64 = read_lut64(&maj_bits[29*130], frame_off);
|
||||
{ int logic_base[6] = {0,1,0,0,0,1};
|
||||
lut_str = lut2bool(lut64, 64, &logic_base, 0 /* flip_b0 */); }
|
||||
if (*lut_str)
|
||||
printf("r%i ma%i clb i%i s1_D6LUT \"%s\"\n",
|
||||
row, major, i-start, lut_str);
|
||||
|
||||
// bits
|
||||
for (j = 0; j < 64; j++) {
|
||||
if (frame_get_bit(&maj_bits[20*130], frame_off + j))
|
||||
printf("r%i ma%i clb i%i mi20 bit %i\n",
|
||||
row, major, i-start, j);
|
||||
}
|
||||
for (j = 0; j < 64; j++) {
|
||||
if (frame_get_bit(&maj_bits[23*130], frame_off + j))
|
||||
printf("r%i ma%i clb i%i mi23 bit %i\n",
|
||||
row, major, i-start, j);
|
||||
}
|
||||
for (j = 0; j < 64; j++) {
|
||||
if (frame_get_bit(&maj_bits[26*130], frame_off + j))
|
||||
printf("r%i ma%i clb i%i mi26 bit %i\n",
|
||||
row, major, i-start, j);
|
||||
for (y = 0; y < 16; y++) {
|
||||
hclk = (y < 8) ? 0 : 2;
|
||||
u64_0 = frame_get_u64(bits + y*8 + hclk);
|
||||
u64_1 = frame_get_u64(bits + y*8 + hclk + FRAME_SIZE);
|
||||
if (u64_0 || u64_1) {
|
||||
for (i = 0; i < sizeof(bit_str); i++)
|
||||
bit_str[i] = '0';
|
||||
for (i = 0; i < 64; i++) {
|
||||
if (u64_0 & (1ULL << i))
|
||||
bit_str[i*2] = '1';
|
||||
if (u64_1 & (1ULL << i))
|
||||
bit_str[i*2+1] = '1';
|
||||
}
|
||||
printf("r%i ma%i v64_%i mip%i %s\n",
|
||||
row, major, y, even_minor, bit_str);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -823,7 +748,8 @@ static int dump_bits(struct fpga_config* cfg)
|
|||
for (row = 0; row < 4; row++) {
|
||||
for (major = 0; major < 18; major++) {
|
||||
// todo: the macc/bram/logic special cases can be removed
|
||||
if (0 && major == 7) { // MACC
|
||||
if (get_major_type(cfg->reg[cfg->idcode_reg].int_v,
|
||||
major) == MAJ_MACC) {
|
||||
int last_extra_minor;
|
||||
|
||||
if (!row || row == 3)
|
||||
|
@ -851,30 +777,25 @@ static int dump_bits(struct fpga_config* cfg)
|
|||
}
|
||||
}
|
||||
}
|
||||
} else if (0 && (major == 2 || major == 5 || major == 8 || major == 10
|
||||
|| major == 12 || major == 15)) { // logic_m
|
||||
} else if (get_major_type(cfg->reg[cfg->idcode_reg].int_v, major) == MAJ_LOGIC_XM) {
|
||||
// clock
|
||||
for (minor = 0; minor < 31; minor++)
|
||||
printf_clock(
|
||||
&cfg->bits.d[off+minor*130],
|
||||
row, major, minor);
|
||||
|
||||
// bitwise
|
||||
minor = 0;
|
||||
while (minor < 20) {
|
||||
while (minor < 31) {
|
||||
minor += printf_frames(&cfg->bits.d[off
|
||||
+minor*130], 31 - minor, row,
|
||||
major, minor, /*print_empty*/ 0);
|
||||
+minor*130], 31 - minor,
|
||||
row, major, minor, /*print_empty*/ 0);
|
||||
}
|
||||
|
||||
// clock
|
||||
for (minor = 20; minor < 31; minor++)
|
||||
printf_clock(&cfg->bits.d[off+minor*130],
|
||||
row, major, minor);
|
||||
// extra bits at bottom of row0 and top of row3
|
||||
if (row == 3)
|
||||
printf_extrabits(&cfg->bits.d[off], 20, 11,
|
||||
0, 128, row, major);
|
||||
else if (!row)
|
||||
printf_extrabits(&cfg->bits.d[off], 20, 11,
|
||||
14*64 + 16, 128, row, major);
|
||||
|
||||
// clbs
|
||||
printf_clb(&cfg->bits.d[off], row, major);
|
||||
} else if (0 && (major == 4 || major == 14)) { // bram
|
||||
// 0:20 routing minor pairs
|
||||
for (i = 0; i < 10; i++)
|
||||
printf_routing_2minors(&cfg->bits.d[off+i*2*FRAME_SIZE], row, major, i*2);
|
||||
} else if (get_major_type(cfg->reg[cfg->idcode_reg].int_v, major) == MAJ_BRAM) {
|
||||
ramb16_cfg_t ramb16_cfg[4];
|
||||
|
||||
// minors 0..22
|
||||
|
@ -910,7 +831,7 @@ static int dump_bits(struct fpga_config* cfg)
|
|||
}
|
||||
} else {
|
||||
int major_minors =
|
||||
get_major_minors(XC6SLX9, major);
|
||||
get_major_minors(cfg->reg[cfg->idcode_reg].int_v, major);
|
||||
minor = 0;
|
||||
while (minor < major_minors) {
|
||||
minor += printf_frames(&cfg->bits.d[off
|
||||
|
|
169
control.c
169
control.c
|
@ -312,12 +312,67 @@ const char* fdev_pinw_idx2str(int devtype, pinw_idx_t idx)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void free_required_pins(struct fpga_device* dev)
|
||||
static int reset_required_pins(struct fpga_device* dev)
|
||||
{
|
||||
free(dev->pinw_req_for_cfg);
|
||||
dev->pinw_req_for_cfg = 0;
|
||||
int rc;
|
||||
|
||||
if (!dev->pinw_req_for_cfg) {
|
||||
dev->pinw_req_for_cfg = malloc(dev->num_pinw_total
|
||||
* sizeof(*dev->pinw_req_for_cfg));
|
||||
if (!dev->pinw_req_for_cfg) FAIL(ENOMEM);
|
||||
}
|
||||
dev->pinw_req_total = 0;
|
||||
dev->pinw_req_in = 0;
|
||||
return 0;
|
||||
fail:
|
||||
return rc;
|
||||
}
|
||||
|
||||
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 void add_req_inpin(struct fpga_device* dev, pinw_idx_t pinw_i)
|
||||
{
|
||||
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],
|
||||
(dev->pinw_req_total-dev->pinw_req_in)
|
||||
*sizeof(*dev->pinw_req_for_cfg));
|
||||
}
|
||||
dev->pinw_req_for_cfg[dev->pinw_req_in] = pinw_i;
|
||||
dev->pinw_req_in++;
|
||||
dev->pinw_req_total++;
|
||||
}
|
||||
|
||||
static void add_req_outpin(struct fpga_device* dev, pinw_idx_t pinw_i)
|
||||
{
|
||||
dev->pinw_req_for_cfg[dev->pinw_req_total] = pinw_i;
|
||||
dev->pinw_req_total++;
|
||||
}
|
||||
|
||||
#define MAX_LUT_LEN 512
|
||||
|
@ -331,7 +386,8 @@ int fdev_logic_set_lut(struct fpga_model* model, int y, int x, int type_idx,
|
|||
|
||||
dev = fdev_p(model, y, x, DEV_LOGIC, type_idx);
|
||||
if (!dev) FAIL(EINVAL);
|
||||
free_required_pins(dev);
|
||||
rc = reset_required_pins(dev);
|
||||
if (rc) FAIL(rc);
|
||||
|
||||
luts = dev->u.logic.luts;
|
||||
if (!luts[which_lut]) {
|
||||
|
@ -371,23 +427,50 @@ fail:
|
|||
return rc;
|
||||
}
|
||||
|
||||
static void scan_lut_digits(const char* s, int* digits)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 6; i++)
|
||||
digits[i] = 0;
|
||||
if (!s) return;
|
||||
for (i = 0; s[i]; i++) {
|
||||
if (s[i] >= '1' && s[i] <= '6')
|
||||
digits[s[i]-'1']++;
|
||||
}
|
||||
}
|
||||
|
||||
int fdev_set_required_pins(struct fpga_model* model, int y, int x, int type,
|
||||
int type_idx)
|
||||
{
|
||||
struct fpga_device* dev;
|
||||
int rc;
|
||||
int digits[6];
|
||||
int i, j, rc;
|
||||
|
||||
dev = fdev_p(model, y, x, type, type_idx);
|
||||
if (!dev) FAIL(EINVAL);
|
||||
free_required_pins(dev);
|
||||
rc = reset_required_pins(dev);
|
||||
if (rc) FAIL(rc);
|
||||
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
|
||||
if (dev->u.logic.A_used)
|
||||
add_req_outpin(dev, LOGIC_OUT_A);
|
||||
if (dev->u.logic.B_used)
|
||||
add_req_outpin(dev, LOGIC_OUT_B);
|
||||
if (dev->u.logic.C_used)
|
||||
add_req_outpin(dev, LOGIC_OUT_C);
|
||||
if (dev->u.logic.D_used)
|
||||
add_req_outpin(dev, LOGIC_OUT_D);
|
||||
for (i = 0; i < sizeof(dev->u.logic.luts)
|
||||
/sizeof(dev->u.logic.luts[0]); i++) {
|
||||
if (!dev->u.logic.luts[i]) continue;
|
||||
scan_lut_digits(dev->u.logic.luts[i], digits);
|
||||
for (j = 0; j < 6; j++) {
|
||||
// i/2 because luts order is A5-A6 B5-B6, etc.
|
||||
if (digits[j])
|
||||
add_req_inpin(dev,
|
||||
LOGIC_IN_A1+(i/2)*6+j);
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
fail:
|
||||
|
@ -402,7 +485,10 @@ void fdev_delete(struct fpga_model* model, int y, int x, int type, int type_idx)
|
|||
dev = fdev_p(model, y, x, type, type_idx);
|
||||
if (!dev) { HERE(); return; }
|
||||
if (!dev->instantiated) return;
|
||||
free_required_pins(dev);
|
||||
free(dev->pinw_req_for_cfg);
|
||||
dev->pinw_req_for_cfg = 0;
|
||||
dev->pinw_req_total = 0;
|
||||
dev->pinw_req_in = 0;
|
||||
if (dev->type == DEV_LOGIC) {
|
||||
for (i = 0; i < sizeof(dev->u.logic.luts)
|
||||
/sizeof(dev->u.logic.luts[0]); i++) {
|
||||
|
@ -825,7 +911,7 @@ int fpga_switch_conns(struct sw_conns* conns)
|
|||
conns->chain.y = conns->y;
|
||||
conns->chain.x = conns->x;
|
||||
conns->chain.start_switch = conns->start_switch;
|
||||
conns->chain.from_to = SW_FROM;
|
||||
conns->chain.from_to = conns->from_to;
|
||||
conns->chain.max_chain_size = conns->max_switch_depth;
|
||||
|
||||
conns->start_switch = STRIDX_NO_ENTRY;
|
||||
|
@ -841,7 +927,7 @@ int fpga_switch_conns(struct sw_conns* conns)
|
|||
end_of_chain_str = fpga_switch_str_i(conns->model,
|
||||
conns->y, conns->x,
|
||||
conns->chain.set.sw[conns->chain.set.len-1],
|
||||
SW_TO);
|
||||
!conns->from_to);
|
||||
if (end_of_chain_str == STRIDX_NO_ENTRY)
|
||||
{ HERE(); goto internal_error; }
|
||||
conns->dest_i = 0;
|
||||
|
@ -865,7 +951,7 @@ internal_error:
|
|||
}
|
||||
|
||||
void printf_swchain(struct fpga_model* model, int y, int x,
|
||||
str16_t sw, int max_depth, int from_to)
|
||||
str16_t sw, int from_to, int max_depth)
|
||||
{
|
||||
struct sw_chain chain =
|
||||
{ .model = model, .y = y, .x = x, .start_switch = sw,
|
||||
|
@ -877,14 +963,14 @@ void printf_swchain(struct fpga_model* model, int y, int x,
|
|||
}
|
||||
|
||||
void printf_swconns(struct fpga_model* model, int y, int x,
|
||||
str16_t sw, int max_depth)
|
||||
str16_t sw, int from_to, int max_depth)
|
||||
{
|
||||
struct sw_conns conns =
|
||||
{ .model = model, .y = y, .x = x, .start_switch = sw,
|
||||
.max_switch_depth = max_depth };
|
||||
.from_to = from_to, .max_switch_depth = max_depth };
|
||||
while (fpga_switch_conns(&conns) != NO_CONN) {
|
||||
printf("sw %s conn y%02i x%02i %s\n", fmt_swset(model, y, x,
|
||||
&conns.chain.set, SW_FROM),
|
||||
&conns.chain.set, from_to),
|
||||
conns.dest_y, conns.dest_x,
|
||||
strarray_lookup(&model->str, conns.dest_str_i));
|
||||
}
|
||||
|
@ -894,7 +980,7 @@ int fpga_switch_to_yx(struct switch_to_yx* p)
|
|||
{
|
||||
struct sw_conns conns = {
|
||||
.model = p->model, .y = p->y, .x = p->x,
|
||||
.start_switch = p->start_switch,
|
||||
.start_switch = p->start_switch, .from_to = p->from_to,
|
||||
.max_switch_depth =
|
||||
(p->flags & SWTO_YX_MAX_SWITCH_DEPTH)
|
||||
? p->max_switch_depth : MAX_SW_DEPTH };
|
||||
|
@ -942,6 +1028,18 @@ int fpga_switch_to_yx(struct switch_to_yx* p)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void printf_switch_to_result(struct switch_to_yx* p)
|
||||
{
|
||||
printf("switch_to_yx() from y%02i x%02i connpt %s (%s)\n",
|
||||
p->y, p->x, strarray_lookup(&p->model->str, p->start_switch),
|
||||
p->from_to == SW_FROM ? "SW_FROM" : "SW_TO");
|
||||
printf(" %s y%02i x%02i %s via %s\n",
|
||||
p->from_to == SW_FROM ? "to" : "from",
|
||||
p->dest_y, p->dest_x,
|
||||
strarray_lookup(&p->model->str, p->dest_connpt),
|
||||
fmt_swset(p->model, p->y, p->x, &p->set, p->from_to));
|
||||
}
|
||||
|
||||
#define NET_ALLOC_INCREMENT 64
|
||||
|
||||
static int fpga_net_useidx(struct fpga_model* model, net_idx_t new_idx)
|
||||
|
@ -981,6 +1079,26 @@ int fpga_net_new(struct fpga_model* model, net_idx_t* new_idx)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void fpga_net_delete(struct fpga_model* model, net_idx_t net_idx)
|
||||
{
|
||||
struct fpga_net* net;
|
||||
int i;
|
||||
|
||||
net = &model->nets[net_idx-1];
|
||||
for (i = 0; i < net->len; i++) {
|
||||
if (net->el[i].idx & NET_IDX_IS_PINW)
|
||||
continue;
|
||||
if (!fpga_switch_is_used(model, net->el[i].y, net->el[i].x,
|
||||
net->el[i].idx))
|
||||
HERE();
|
||||
fpga_switch_disable(model, net->el[i].y, net->el[i].x,
|
||||
net->el[i].idx);
|
||||
}
|
||||
model->nets[net_idx-1].len = 0;
|
||||
if (model->highest_used_net == net_idx)
|
||||
model->highest_used_net--;
|
||||
}
|
||||
|
||||
int fpga_net_enum(struct fpga_model* model, net_idx_t last, net_idx_t* next)
|
||||
{
|
||||
int i;
|
||||
|
@ -1029,6 +1147,15 @@ fail:
|
|||
return rc;
|
||||
}
|
||||
|
||||
int fpga_net_add_switch(struct fpga_model* model, net_idx_t net_i,
|
||||
int y, int x, swidx_t one_sw)
|
||||
{
|
||||
struct sw_set set;
|
||||
set.sw[0] = one_sw;
|
||||
set.len = 1;
|
||||
return fpga_net_add_switches(model, net_i, y, x, &set);
|
||||
}
|
||||
|
||||
int fpga_net_add_switches(struct fpga_model* model, net_idx_t net_i,
|
||||
int y, int x, const struct sw_set* set)
|
||||
{
|
||||
|
|
12
control.h
12
control.h
|
@ -43,6 +43,8 @@ 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_print_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);
|
||||
|
||||
|
@ -139,6 +141,7 @@ struct sw_conns
|
|||
int x;
|
||||
// start_switch will be set to STRIDX_NO_ENTRY (0) after first call
|
||||
str16_t start_switch;
|
||||
int from_to;
|
||||
int max_switch_depth;
|
||||
|
||||
// return values:
|
||||
|
@ -156,9 +159,9 @@ struct sw_conns
|
|||
int fpga_switch_conns(struct sw_conns* conns);
|
||||
|
||||
void printf_swchain(struct fpga_model* model, int y, int x,
|
||||
str16_t sw, int max_depth, int from_to);
|
||||
str16_t sw, int from_to, int max_depth);
|
||||
void printf_swconns(struct fpga_model* model, int y, int x,
|
||||
str16_t sw, int max_depth);
|
||||
str16_t sw, int from_to, int max_depth);
|
||||
|
||||
#define SWTO_YX_DEF 0
|
||||
#define SWTO_YX_CLOSEST 0x0001
|
||||
|
@ -174,6 +177,7 @@ struct switch_to_yx
|
|||
int y;
|
||||
int x;
|
||||
str16_t start_switch;
|
||||
int from_to;
|
||||
int max_switch_depth; // only if SWTO_YX_MAX_SWITCH_DEPTH is set
|
||||
str16_t target_connpt; // only if SWTO_YX_TARGET_CONNPT is set
|
||||
|
||||
|
@ -185,6 +189,7 @@ struct switch_to_yx
|
|||
};
|
||||
|
||||
int fpga_switch_to_yx(struct switch_to_yx* p);
|
||||
void printf_switch_to_result(struct switch_to_yx* p);
|
||||
|
||||
//
|
||||
// nets
|
||||
|
@ -221,11 +226,14 @@ typedef int net_idx_t; // net indices are 1-based
|
|||
#define NO_NET 0
|
||||
|
||||
int fpga_net_new(struct fpga_model* model, net_idx_t* new_idx);
|
||||
void fpga_net_delete(struct fpga_model* model, net_idx_t net_idx);
|
||||
// start a new enumeration by calling with last==NO_NET
|
||||
int fpga_net_enum(struct fpga_model* model, net_idx_t last, net_idx_t* next);
|
||||
struct fpga_net* fpga_net_get(struct fpga_model* model, net_idx_t net_i);
|
||||
int fpga_net_add_port(struct fpga_model* model, net_idx_t net_i,
|
||||
int y, int x, dev_idx_t dev_idx, pinw_idx_t pinw_idx);
|
||||
int fpga_net_add_switch(struct fpga_model* model, net_idx_t net_i,
|
||||
int y, int x, swidx_t one_sw);
|
||||
int fpga_net_add_switches(struct fpga_model* model, net_idx_t net_i,
|
||||
int y, int x, const struct sw_set* set);
|
||||
void fpga_net_free_all(struct fpga_model* model);
|
||||
|
|
10
model.h
10
model.h
|
@ -348,7 +348,8 @@ typedef int dev_type_idx_t;
|
|||
|
||||
enum { LOGIC_M = 1, LOGIC_L, LOGIC_X };
|
||||
// All LOGICIN_IN A..D sequences must be exactly sequential as
|
||||
// here to match initialization in model_device:init_logic().
|
||||
// here to match initialization in model_devices.c:init_logic()
|
||||
// and control.c:fdev_set_required_pins().
|
||||
enum { // input:
|
||||
LOGIC_IN_A1 = 0,
|
||||
LOGIC_IN_A2, LOGIC_IN_A3, LOGIC_IN_A4, LOGIC_IN_A5, LOGIC_IN_A6,
|
||||
|
@ -385,8 +386,11 @@ 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 };
|
||||
// offsets into fpgadev_logic:luts[], also hardcoded in
|
||||
// control.c:fdev_set_required_pins(), where we assume
|
||||
// that div2 will lead to A-D
|
||||
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" }
|
||||
|
|
74
parts.c
74
parts.c
|
@ -70,30 +70,29 @@ const char* get_iob_sitename(int idcode, int idx)
|
|||
return iob_xc6slx9_sitenames[idx];
|
||||
}
|
||||
|
||||
static const int minors_per_major[] = // for slx4 and slx9
|
||||
{
|
||||
/* 0 */ 4, // 505 bytes = middle 8-bit for each minor?
|
||||
/* 1 */ 30, // left
|
||||
/* 2 */ 31, // logic M
|
||||
/* 3 */ 30, // logic L
|
||||
/* 4 */ 25, // bram
|
||||
/* 5 */ 31, // logic M
|
||||
/* 6 */ 30, // logic L
|
||||
/* 7 */ 24, // macc
|
||||
/* 8 */ 31, // logic M
|
||||
/* 9 */ 31, // center
|
||||
/* 10 */ 31, // logic M
|
||||
/* 11 */ 30, // logic L
|
||||
/* 12 */ 31, // logic M
|
||||
/* 13 */ 30, // logic L
|
||||
/* 14 */ 25, // bram
|
||||
/* 15 */ 31, // logic M
|
||||
/* 16 */ 30, // logic L
|
||||
/* 17 */ 30, // right
|
||||
};
|
||||
|
||||
int get_major_minors(int idcode, int major)
|
||||
{
|
||||
static const int minors_per_major[] = // for slx9
|
||||
{
|
||||
/* 0 */ 4, // 505 bytes = middle 8-bit for each minor?
|
||||
/* 1 */ 30, // left
|
||||
/* 2 */ 31, // logic M
|
||||
/* 3 */ 30, // logic L
|
||||
/* 4 */ 25, // bram
|
||||
/* 5 */ 31, // logic M
|
||||
/* 6 */ 30, // logic L
|
||||
/* 7 */ 24, // macc
|
||||
/* 8 */ 31, // logic M
|
||||
/* 9 */ 31, // center
|
||||
/* 10 */ 31, // logic M
|
||||
/* 11 */ 30, // logic L
|
||||
/* 12 */ 31, // logic M
|
||||
/* 13 */ 30, // logic L
|
||||
/* 14 */ 25, // bram
|
||||
/* 15 */ 31, // logic M
|
||||
/* 16 */ 30, // logic L
|
||||
/* 17 */ 30, // right
|
||||
};
|
||||
if ((idcode & IDCODE_MASK) != XC6SLX9)
|
||||
EXIT(1);
|
||||
if (major < 0 || major
|
||||
|
@ -101,3 +100,34 @@ int get_major_minors(int idcode, int major)
|
|||
EXIT(1);
|
||||
return minors_per_major[major];
|
||||
}
|
||||
|
||||
enum major_type get_major_type(int idcode, int major)
|
||||
{
|
||||
static const int major_types[] = // for slx9
|
||||
{
|
||||
/* 0 */ MAJ_ZERO,
|
||||
/* 1 */ MAJ_LEFT,
|
||||
/* 2 */ MAJ_LOGIC_XM,
|
||||
/* 3 */ MAJ_LOGIC_XL,
|
||||
/* 4 */ MAJ_BRAM,
|
||||
/* 5 */ MAJ_LOGIC_XM,
|
||||
/* 6 */ MAJ_LOGIC_XL,
|
||||
/* 7 */ MAJ_MACC,
|
||||
/* 8 */ MAJ_LOGIC_XM,
|
||||
/* 9 */ MAJ_CENTER,
|
||||
/* 10 */ MAJ_LOGIC_XM,
|
||||
/* 11 */ MAJ_LOGIC_XL,
|
||||
/* 12 */ MAJ_LOGIC_XM,
|
||||
/* 13 */ MAJ_LOGIC_XL,
|
||||
/* 14 */ MAJ_BRAM,
|
||||
/* 15 */ MAJ_LOGIC_XM,
|
||||
/* 16 */ MAJ_LOGIC_XL,
|
||||
/* 17 */ MAJ_RIGHT
|
||||
};
|
||||
if ((idcode & IDCODE_MASK) != XC6SLX9)
|
||||
EXIT(1);
|
||||
if (major < 0 || major
|
||||
> sizeof(major_types)/sizeof(major_types[0]))
|
||||
EXIT(1);
|
||||
return major_types[major];
|
||||
}
|
||||
|
|
5
parts.h
5
parts.h
|
@ -39,5 +39,10 @@
|
|||
#define BITS_LEN (IOB_DATA_START+IOB_DATA_LEN)
|
||||
|
||||
int get_major_minors(int idcode, int major);
|
||||
|
||||
enum major_type { MAJ_ZERO, MAJ_LEFT, MAJ_RIGHT, MAJ_CENTER,
|
||||
MAJ_LOGIC_XM, MAJ_LOGIC_XL, MAJ_BRAM, MAJ_MACC };
|
||||
enum major_type get_major_type(int idcode, int major);
|
||||
|
||||
int get_num_iobs(int idcode);
|
||||
const char* get_iob_sitename(int idcode, int idx);
|
||||
|
|
Loading…
Reference in New Issue
Block a user