carry chain fixes
This commit is contained in:
parent
9c964f848e
commit
c330b8e11f
62
autotest.c
62
autotest.c
|
@ -1012,7 +1012,7 @@ static int test_logic(struct test_state* tstate, int y, int x, int type_idx,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// add stub nets for each required pin
|
// add one stub net per required pin
|
||||||
dev = fdev_p(tstate->model, y, x, DEV_LOGIC, type_idx);
|
dev = fdev_p(tstate->model, y, x, DEV_LOGIC, type_idx);
|
||||||
if (!dev) FAIL(EINVAL);
|
if (!dev) FAIL(EINVAL);
|
||||||
for (i = 0; i < dev->pinw_req_total; i++) {
|
for (i = 0; i < dev->pinw_req_total; i++) {
|
||||||
|
@ -1022,6 +1022,30 @@ static int test_logic(struct test_state* tstate, int y, int x, int type_idx,
|
||||||
rc = fnet_add_port(tstate->model, pinw_nets[i], y, x,
|
rc = fnet_add_port(tstate->model, pinw_nets[i], y, x,
|
||||||
DEV_LOGIC, type_idx, dev->pinw_req_for_cfg[i]);
|
DEV_LOGIC, type_idx, dev->pinw_req_for_cfg[i]);
|
||||||
if (rc) FAIL(rc);
|
if (rc) FAIL(rc);
|
||||||
|
if (dev->pinw_req_for_cfg[i] == LI_CIN) {
|
||||||
|
int connpt_dests_o, num_dests, cout_y, cout_x;
|
||||||
|
str16_t cout_str;
|
||||||
|
swidx_t cout_sw;
|
||||||
|
|
||||||
|
if ((fpga_connpt_find(tstate->model, y, x,
|
||||||
|
dev->pinw[LI_CIN], &connpt_dests_o,
|
||||||
|
&num_dests) == NO_CONN)
|
||||||
|
|| num_dests != 1) {
|
||||||
|
HERE();
|
||||||
|
} else {
|
||||||
|
fpga_conn_dest(tstate->model, y, x,
|
||||||
|
connpt_dests_o, &cout_y, &cout_x, &cout_str);
|
||||||
|
cout_sw = fpga_switch_first(tstate->model,
|
||||||
|
cout_y, cout_x, cout_str, SW_TO);
|
||||||
|
if (cout_sw == NO_SWITCH) HERE();
|
||||||
|
else {
|
||||||
|
rc = fnet_add_sw(tstate->model,
|
||||||
|
pinw_nets[i], cout_y, cout_x,
|
||||||
|
&cout_sw, /*num_sw*/ 1);
|
||||||
|
if (rc) FAIL(rc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
if ((dev->pinw_req_for_cfg[i] == LI_A6
|
if ((dev->pinw_req_for_cfg[i] == LI_A6
|
||||||
&& dev->u.logic.a2d[LUT_A].lut5
|
&& dev->u.logic.a2d[LUT_A].lut5
|
||||||
&& *dev->u.logic.a2d[LUT_A].lut5)
|
&& *dev->u.logic.a2d[LUT_A].lut5)
|
||||||
|
@ -1247,7 +1271,8 @@ static int test_logic_config(struct test_state* tstate)
|
||||||
|
|
||||||
tstate->diff_to_null = 1;
|
tstate->diff_to_null = 1;
|
||||||
|
|
||||||
y = 68;
|
// For cin/cout testing, pick a y that is not at the bottom.
|
||||||
|
y = 67;
|
||||||
for (x_i = 0; x_i < sizeof(x_enum)/sizeof(*x_enum); x_i++) {
|
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 (type_i = 0; type_i < sizeof(idx_enum)/sizeof(*idx_enum); type_i++) {
|
||||||
for (lut = LUT_A; lut <= LUT_D; lut++) {
|
for (lut = LUT_A; lut <= LUT_D; lut++) {
|
||||||
|
@ -1693,39 +1718,6 @@ int main(int argc, char** argv)
|
||||||
// for example: ./autotest 2>&1 | tee autotest.log
|
// for example: ./autotest 2>&1 | tee autotest.log
|
||||||
setvbuf(stdout, /*buf*/ 0, _IOLBF, /*size*/ 0);
|
setvbuf(stdout, /*buf*/ 0, _IOLBF, /*size*/ 0);
|
||||||
|
|
||||||
#if 0
|
|
||||||
int lut_map1[64] = {63,62,61,60,59,58,57,56,55,54,53,52,51,50,
|
|
||||||
49,48,47,46,45,44,43,42,41,40,39,38,37,36,35,34,33,32,31,
|
|
||||||
30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,
|
|
||||||
9,8,7,6,5,4,3,2,1,0};
|
|
||||||
//int bool_str2bits(const char* str, uint64_t* u64, int num_bits);
|
|
||||||
//const char* bool_bits2str(uint64_t u64, int num_bits);
|
|
||||||
{
|
|
||||||
uint64_t u64, u64_2;
|
|
||||||
|
|
||||||
rc = bool_str2bits("~A6*~A5*~A4*~A3*~A2*~A1", &u64, 64);
|
|
||||||
printf("rc %i u64 %llX 2str %s\n", rc, u64, bool_bits2str(u64, 64));
|
|
||||||
rc = bool_str2bits("~A6*~A5*~A4*~A3*~A2*A1", &u64, 64);
|
|
||||||
printf("rc %i u64 %llX 2str %s\n", rc, u64, bool_bits2str(u64, 64));
|
|
||||||
rc = bool_str2bits("A6*A5*A4*A3*A2*A1", &u64, 64);
|
|
||||||
printf("rc %i u64 %llX 2str %s\n", rc, u64, bool_bits2str(u64, 64));
|
|
||||||
rc = bool_str2bits("A5*A4*A3*A2*A1", &u64, 32);
|
|
||||||
printf("rc %i u32 %llX 2str %s\n", rc, u64, bool_bits2str(u64, 32));
|
|
||||||
rc = bool_str2bits("A4*A3", &u64, 32);
|
|
||||||
printf("rc %i u32 %llX 2str %s\n", rc, u64, bool_bits2str(u64, 32));
|
|
||||||
rc = bool_str2bits("A1", &u64, 64);
|
|
||||||
printf("rc %i u64 %llX 2str %s\n", rc, u64, bool_bits2str(u64, 64));
|
|
||||||
rc = bool_str2bits("A1", &u64, 32);
|
|
||||||
printf("rc %i u32 %llX 2str %s\n", rc, u64, bool_bits2str(u64, 32));
|
|
||||||
|
|
||||||
u64 = 1;
|
|
||||||
u64_2 = map_bits(u64, 64, lut_map1);
|
|
||||||
printf("u %llX mapped %llX\n", u64, u64_2);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (argc < 2) {
|
if (argc < 2) {
|
||||||
printf_help(argv[0], available_tests);
|
printf_help(argv[0], available_tests);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -270,7 +270,9 @@ static int extract_iobs(struct extract_state* es)
|
||||||
|
|
||||||
iob_sitename = get_iob_sitename(XC6SLX9, i);
|
iob_sitename = get_iob_sitename(XC6SLX9, i);
|
||||||
if (!iob_sitename) {
|
if (!iob_sitename) {
|
||||||
HERE();
|
// The space for 6 IOBs on all four sides
|
||||||
|
// (6*8 = 48 bytes, *4=192 bytes) is used
|
||||||
|
// for clocks etc, so we ignore them here.
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
rc = fpga_find_iob(es->model, iob_sitename, &iob_y, &iob_x, &iob_idx);
|
rc = fpga_find_iob(es->model, iob_sitename, &iob_y, &iob_x, &iob_idx);
|
||||||
|
@ -1038,8 +1040,22 @@ static int extract_logic(struct extract_state* es)
|
||||||
// instantiate the logic devices.
|
// instantiate the logic devices.
|
||||||
//
|
//
|
||||||
|
|
||||||
if (mi20 || mi23_M || mi2526) {
|
if (mi20) {
|
||||||
HERE();
|
fprintf(stderr, "#E %s:%i y%02i x%02i l%i "
|
||||||
|
"mi20 0x%016lX\n",
|
||||||
|
__FILE__, __LINE__, y, x, l_col, mi20);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (mi23_M) {
|
||||||
|
fprintf(stderr, "#E %s:%i y%02i x%02i l%i "
|
||||||
|
"mi23_M 0x%016lX\n",
|
||||||
|
__FILE__, __LINE__, y, x, l_col, mi23_M);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (mi2526) {
|
||||||
|
fprintf(stderr, "#E %s:%i y%02i x%02i l%i "
|
||||||
|
"mi2526 0x%016lX\n",
|
||||||
|
__FILE__, __LINE__, y, x, l_col, mi2526);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1452,12 +1468,54 @@ fail:
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int extract_logic_switches(struct extract_state* es, int y, int x)
|
||||||
|
{
|
||||||
|
int row, row_pos, byte_off, minor, rc;
|
||||||
|
swidx_t sw_idx;
|
||||||
|
uint8_t* u8_p;
|
||||||
|
|
||||||
|
row = which_row(y, es->model);
|
||||||
|
row_pos = pos_in_row(y, es->model);
|
||||||
|
if (row == -1 || row_pos == -1 || row_pos == 8) FAIL(EINVAL);
|
||||||
|
if (row_pos > 8) row_pos--;
|
||||||
|
u8_p = get_first_minor(es->bits, row, es->model->x_major[x]);
|
||||||
|
byte_off = row_pos * 8;
|
||||||
|
if (row_pos >= 8) byte_off += HCLK_BYTES;
|
||||||
|
|
||||||
|
if (has_device_type(es->model, y, x, DEV_LOGIC, LOGIC_M))
|
||||||
|
minor = 26;
|
||||||
|
else if (has_device_type(es->model, y, x, DEV_LOGIC, LOGIC_L))
|
||||||
|
minor = 25;
|
||||||
|
else
|
||||||
|
FAIL(EINVAL);
|
||||||
|
|
||||||
|
if (frame_get_bit(u8_p + minor*FRAME_SIZE, byte_off*8 + XC6_ML_COUT_CIN_SW)) {
|
||||||
|
sw_idx = fpga_switch_lookup(es->model, y, x,
|
||||||
|
strarray_find(&es->model->str, "M_COUT"),
|
||||||
|
strarray_find(&es->model->str, "M_COUT_N"));
|
||||||
|
if (sw_idx == NO_SWITCH) { HERE(); return 0; }
|
||||||
|
|
||||||
|
if (es->num_yx_pos >= MAX_YX_SWITCHES)
|
||||||
|
{ FAIL(ENOTSUP); }
|
||||||
|
es->yx_pos[es->num_yx_pos].y = y;
|
||||||
|
es->yx_pos[es->num_yx_pos].x = x;
|
||||||
|
es->yx_pos[es->num_yx_pos].idx = sw_idx;
|
||||||
|
es->num_yx_pos++;
|
||||||
|
|
||||||
|
frame_clear_bit(u8_p + minor*FRAME_SIZE, byte_off*8 + XC6_ML_COUT_CIN_SW);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
fail:
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
static int extract_switches(struct extract_state* es)
|
static int extract_switches(struct extract_state* es)
|
||||||
{
|
{
|
||||||
int x, y, rc;
|
int x, y, rc;
|
||||||
|
|
||||||
for (x = 0; x < es->model->x_width; x++) {
|
for (x = 0; x < es->model->x_width; x++) {
|
||||||
for (y = 0; y < es->model->y_height; y++) {
|
for (y = 0; y < es->model->y_height; y++) {
|
||||||
|
// routing switches
|
||||||
if (is_atx(X_ROUTING_COL, es->model, x)
|
if (is_atx(X_ROUTING_COL, es->model, x)
|
||||||
&& y >= TOP_IO_TILES
|
&& y >= TOP_IO_TILES
|
||||||
&& y < es->model->y_height-BOT_IO_TILES
|
&& y < es->model->y_height-BOT_IO_TILES
|
||||||
|
@ -1466,6 +1524,11 @@ static int extract_switches(struct extract_state* es)
|
||||||
rc = extract_routing_switches(es, y, x);
|
rc = extract_routing_switches(es, y, x);
|
||||||
if (rc) FAIL(rc);
|
if (rc) FAIL(rc);
|
||||||
}
|
}
|
||||||
|
// logic switches
|
||||||
|
if (has_device(es->model, y, x, DEV_LOGIC)) {
|
||||||
|
rc = extract_logic_switches(es, y, x);
|
||||||
|
if (rc) FAIL(rc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -887,11 +887,8 @@ int fdev_set_required_pins(struct fpga_model* model, int y, int x, int type,
|
||||||
add_req_inpin(dev, LI_CE);
|
add_req_inpin(dev, LI_CE);
|
||||||
if (dev->u.logic.sr_used)
|
if (dev->u.logic.sr_used)
|
||||||
add_req_inpin(dev, LI_SR);
|
add_req_inpin(dev, LI_SR);
|
||||||
if (dev->u.logic.cout_used) {
|
if (dev->u.logic.cout_used)
|
||||||
add_req_outpin(dev, LO_COUT);
|
add_req_outpin(dev, LO_COUT);
|
||||||
if (!dev->u.logic.precyinit)
|
|
||||||
add_req_inpin(dev, LI_CIN);
|
|
||||||
}
|
|
||||||
if (dev->u.logic.precyinit == PRECYINIT_AX)
|
if (dev->u.logic.precyinit == PRECYINIT_AX)
|
||||||
add_req_inpin(dev, LI_AX);
|
add_req_inpin(dev, LI_AX);
|
||||||
if (dev->u.logic.a2d[LUT_A].out_mux == MUX_F7
|
if (dev->u.logic.a2d[LUT_A].out_mux == MUX_F7
|
||||||
|
@ -1537,7 +1534,8 @@ int fpga_switch_chain(struct sw_chain* ch)
|
||||||
idx = fpga_switch_backtofirst(ch->model, ch->y, ch->x,
|
idx = fpga_switch_backtofirst(ch->model, ch->y, ch->x,
|
||||||
ch->set.sw[ch->set.len-1], ch->from_to);
|
ch->set.sw[ch->set.len-1], ch->from_to);
|
||||||
if (idx == NO_SWITCH) {
|
if (idx == NO_SWITCH) {
|
||||||
HERE(); goto internal_error;
|
ch->set.len = 0;
|
||||||
|
return NO_SWITCH;
|
||||||
}
|
}
|
||||||
#ifdef DBG_ENUM_SWITCH
|
#ifdef DBG_ENUM_SWITCH
|
||||||
printf("back_to_first from %s to %s\n",
|
printf("back_to_first from %s to %s\n",
|
||||||
|
|
|
@ -359,8 +359,7 @@ int printf_iob(uint8_t* d, int len, int inpos, int num_entries)
|
||||||
for (i = 0; i < num_entries; i++) {
|
for (i = 0; i < num_entries; i++) {
|
||||||
u64 = frame_get_u64(&d[inpos+i*8]);
|
u64 = frame_get_u64(&d[inpos+i*8]);
|
||||||
if (u64) {
|
if (u64) {
|
||||||
printf("iob i%i 0x%016llX\n", i,
|
printf("iob i%i 0x%016lX\n", i, u64);
|
||||||
(long long unsigned) u64);
|
|
||||||
num_printed++;
|
num_printed++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
__FILE__, __LINE__)
|
__FILE__, __LINE__)
|
||||||
#define FAIL(code) do { HERE(); rc = (code); goto fail; } while (0)
|
#define FAIL(code) do { HERE(); rc = (code); goto fail; } while (0)
|
||||||
#define XOUT() do { HERE(); goto xout; } while (0)
|
#define XOUT() do { HERE(); goto xout; } while (0)
|
||||||
|
#define CHECK_MODEL(m) do { if ((m)->rc) return (m)->rc; } while (0)
|
||||||
|
|
||||||
#define OUT_OF_U16(val) ((val) < 0 || (val) > 0xFFFF)
|
#define OUT_OF_U16(val) ((val) < 0 || (val) > 0xFFFF)
|
||||||
|
|
||||||
|
|
|
@ -376,7 +376,7 @@ enum {
|
||||||
LI_AX, LI_BX, LI_CX, LI_DX,
|
LI_AX, LI_BX, LI_CX, LI_DX,
|
||||||
LI_CLK, LI_CE, LI_SR,
|
LI_CLK, LI_CE, LI_SR,
|
||||||
// only for L and M:
|
// only for L and M:
|
||||||
LI_CIN, // only some L and M devs have this
|
LI_CIN,
|
||||||
// only for M:
|
// only for M:
|
||||||
LI_WE, LI_AI, LI_BI, LI_CI, LI_DI,
|
LI_WE, LI_AI, LI_BI, LI_CI, LI_DI,
|
||||||
|
|
||||||
|
|
|
@ -510,11 +510,11 @@ static int init_logic(struct fpga_model* model, int y, int x, int idx)
|
||||||
if (rc) FAIL(rc);
|
if (rc) FAIL(rc);
|
||||||
} else
|
} else
|
||||||
tile->devs[idx].pinw[LI_WE] = STRIDX_NO_ENTRY;
|
tile->devs[idx].pinw[LI_WE] = STRIDX_NO_ENTRY;
|
||||||
if (tile->devs[idx].subtype != LOGIC_X
|
if (tile->devs[idx].subtype != LOGIC_X) {
|
||||||
&& ((is_atx(X_ROUTING_NO_IO, model, x-1)
|
// Wire connections will go to some CIN later
|
||||||
&& is_aty(Y_INNER_BOTTOM, model, y+1))
|
// (and must not warn about duplicates), but we
|
||||||
|| (!is_atx(X_ROUTING_NO_IO, model, x-1)
|
// have to add the connection point here so
|
||||||
&& is_aty(Y_BOT_INNER_IO, model, y+1)))) {
|
// that pinw[LI_CIN] is initialized.
|
||||||
rc = add_connpt_name(model, y, x, pf("%sCIN", pre),
|
rc = add_connpt_name(model, y, x, pf("%sCIN", pre),
|
||||||
/*dup_warn*/ 1,
|
/*dup_warn*/ 1,
|
||||||
&tile->devs[idx].pinw[LI_CIN], 0);
|
&tile->devs[idx].pinw[LI_CIN], 0);
|
||||||
|
|
|
@ -11,6 +11,9 @@
|
||||||
|
|
||||||
const char* iob_xc6slx9_sitenames[IOB_WORDS*2/8] =
|
const char* iob_xc6slx9_sitenames[IOB_WORDS*2/8] =
|
||||||
{
|
{
|
||||||
|
// Note that the configuration space for 4*6 IOBs
|
||||||
|
// that are marked with 0 is used for clocks etc,
|
||||||
|
// just not IOBs.
|
||||||
[0]
|
[0]
|
||||||
"P70", "P69", "P67", "P66", "P65", "P64", "P62", "P61",
|
"P70", "P69", "P67", "P66", "P65", "P64", "P62", "P61",
|
||||||
"P60", "P59", "P58", "P57", "UNB113", "UNB114", "UNB115", "UNB116",
|
"P60", "P59", "P58", "P57", "UNB113", "UNB114", "UNB115", "UNB116",
|
||||||
|
|
|
@ -323,6 +323,7 @@ void xc6_lut_bitmap(int lut_pos, int (*map)[64], int num_bits);
|
||||||
#define XC6_ML_B_CY0_O5 56 // implies lut5 on ML-B
|
#define XC6_ML_B_CY0_O5 56 // implies lut5 on ML-B
|
||||||
#define XC6_ML_PRECYINIT_AX 57
|
#define XC6_ML_PRECYINIT_AX 57
|
||||||
#define XC6_X_A_FFSRINIT_1 58
|
#define XC6_X_A_FFSRINIT_1 58
|
||||||
|
#define XC6_ML_COUT_CIN_SW 59
|
||||||
// ML_PRECYINIT=0 -
|
// ML_PRECYINIT=0 -
|
||||||
#define XC6_ML_PRECYINIT_1 60
|
#define XC6_ML_PRECYINIT_1 60
|
||||||
#define XC6_ML_B_FFSRINIT_1 61
|
#define XC6_ML_B_FFSRINIT_1 61
|
||||||
|
|
Loading…
Reference in New Issue
Block a user