carry chain fixes, devices, bram and macc switches

This commit is contained in:
Wolfgang Spraul 2012-10-18 14:34:53 +02:00
parent 0c08f07fee
commit 8d4c6dfe82
7 changed files with 1102 additions and 18 deletions

View File

@ -150,7 +150,7 @@ compare_%.ftest: compare_%.fcr
@if test ! -e test.gold/$(*F).fco; then echo Gold test.gold/$(*F).fco does not exist, aborting.; false; fi;
@diff -u test.gold/$(*F).fco $< >$@ || true
%.fce: %.fco
%.fce: %.fcd
@cat $< | grep ^+[^+] >$@ || true
compare_%_tiles.fco: compare_%.fp

View File

@ -762,7 +762,7 @@ static int printf_BUFIO(FILE* f, struct fpga_model* model,
type_count++;
continue;
}
snprintf(pref, sizeof(pref), "dev y%02i x%02i BUFGMUX %i",
snprintf(pref, sizeof(pref), "dev y%02i x%02i BUFIO %i",
y, x, type_count++);
if (!config_only)
fprintf(f, "%s\n", pref);
@ -841,7 +841,7 @@ static int printf_BSCAN(FILE* f, struct fpga_model* model,
type_count++;
continue;
}
snprintf(pref, sizeof(pref), "dev y%02i x%02i BUFGMUX %i",
snprintf(pref, sizeof(pref), "dev y%02i x%02i BSCAN %i",
y, x, type_count++);
if (!config_only)
fprintf(f, "%s\n", pref);

View File

@ -317,7 +317,8 @@ enum fpgadev_type
DEV_BUFH, DEV_BUFIO, DEV_BUFIO_FB, DEV_BUFPLL, DEV_BUFPLL_MCB,
DEV_BUFGMUX, DEV_BSCAN, DEV_DCM, DEV_PLL, DEV_ICAP,
DEV_POST_CRC_INTERNAL, DEV_STARTUP, DEV_SLAVE_SPI,
DEV_SUSPEND_SYNC, DEV_OCT_CALIBRATE, DEV_SPI_ACCESS };
DEV_SUSPEND_SYNC, DEV_OCT_CALIBRATE, DEV_SPI_ACCESS,
DEV_DNA, DEV_PMV, DEV_PCILOGIC_SE };
#define FPGA_DEV_STR \
{ 0, \
"LOGIC", "TIEOFF", "MACC", "IOB", \
@ -325,7 +326,8 @@ enum fpgadev_type
"BUFH", "BUFIO", "BUFIO_FB", "BUFPLL", "BUFPLL_MCB", \
"BUFGMUX", "BSCAN", "DCM", "PLL", "ICAP", \
"POST_CRC_INTERNAL", "STARTUP", "SLAVE_SPI", \
"SUSPEND_SYNC", "OCT_CALIBRATE", "SPI_ACCESS" }
"SUSPEND_SYNC", "OCT_CALIBRATE", "SPI_ACCESS", \
"DNA", "PMV", "PCILOGIC_SE" }
// We use two types of device indices, one is a flat index
// into the tile->devs array (dev_idx_t), the other
@ -534,6 +536,133 @@ struct fpgadev_bscan
int jtag_test;
};
//
// DEV_BRAM
//
// B8_0 or B8_1 can be or'ed into the BI/BO values
// to designate the first and second BRAM8 device,
// instead of the default BRAM16 device.
#define B8_0 0x100
#define B8_1 0x200
#define BW_FLAGS (B8_0|B8_1)
enum {
// input:
BI_FIRST = 0,
// port A
BI_ADDRA0 = BI_FIRST, BI_ADDRA1, BI_ADDRA2, BI_ADDRA3, BI_ADDRA4, BI_ADDRA5,
BI_ADDRA6, BI_ADDRA7, BI_ADDRA8, BI_ADDRA9, BI_ADDRA10, BI_ADDRA11,
BI_ADDRA12, BI_ADDRA13,
BI_DIA0, BI_DIA1, BI_DIA2, BI_DIA3, BI_DIA4, BI_DIA5,
BI_DIA6, BI_DIA7, BI_DIA8, BI_DIA9, BI_DIA10, BI_DIA11,
BI_DIA12, BI_DIA13, BI_DIA14, BI_DIA15, BI_DIA16, BI_DIA17,
BI_DIA18, BI_DIA19, BI_DIA20, BI_DIA21, BI_DIA22, BI_DIA23,
BI_DIA24, BI_DIA25, BI_DIA26, BI_DIA27, BI_DIA28, BI_DIA29,
BI_DIA30, BI_DIA31,
BI_DIPA0, BI_DIPA1, BI_DIPA2, BI_DIPA3,
BI_WEA0, BI_WEA1, BI_WEA2, BI_WEA3,
BI_REGCEA,
BI_ENA,
// port B
BI_ADDRB0, BI_ADDRB1, BI_ADDRB2, BI_ADDRB3, BI_ADDRB4, BI_ADDRB5,
BI_ADDRB6, BI_ADDRB7, BI_ADDRB8, BI_ADDRB9, BI_ADDRB10, BI_ADDRB11,
BI_ADDRB12, BI_ADDRB13,
BI_DIB0, BI_DIB1, BI_DIB2, BI_DIB3, BI_DIB4, BI_DIB5,
BI_DIB6, BI_DIB7, BI_DIB8, BI_DIB9, BI_DIB10, BI_DIB11,
BI_DIB12, BI_DIB13, BI_DIB14, BI_DIB15, BI_DIB16, BI_DIB17,
BI_DIB18, BI_DIB19, BI_DIB20, BI_DIB21, BI_DIB22, BI_DIB23,
BI_DIB24, BI_DIB25, BI_DIB26, BI_DIB27, BI_DIB28, BI_DIB29,
BI_DIB30, BI_DIB31,
BI_DIPB0, BI_DIPB1, BI_DIPB2, BI_DIPB3,
BI_WEB0, BI_WEB1, BI_WEB2, BI_WEB3,
BI_REGCEB,
BI_ENB,
BI_LAST = BI_ENB,
// output:
BO_FIRST,
// port A
BO_DOA0 = BO_FIRST, BO_DOA1, BO_DOA2, BO_DOA3, BO_DOA4, BO_DOA5,
BO_DOA6, BO_DOA7, BO_DOA8, BO_DOA9, BO_DOA10, BO_DOA11,
BO_DOA12, BO_DOA13, BO_DOA14, BO_DOA15, BO_DOA16, BO_DOA17,
BO_DOA18, BO_DOA19, BO_DOA20, BO_DOA21, BO_DOA22, BO_DOA23,
BO_DOA24, BO_DOA25, BO_DOA26, BO_DOA27, BO_DOA28, BO_DOA29,
BO_DOA30, BO_DOA31,
BO_DOPA0, BO_DOPA1, BO_DOPA2, BO_DOPA3,
// port B
BO_DOB0, BO_DOB1, BO_DOB2, BO_DOB3, BO_DOB4, BO_DOB5,
BO_DOB6, BO_DOB7, BO_DOB8, BO_DOB9, BO_DOB10, BO_DOB11,
BO_DOB12, BO_DOB13, BO_DOB14, BO_DOB15, BO_DOB16, BO_DOB17,
BO_DOB18, BO_DOB19, BO_DOB20, BO_DOB21, BO_DOB22, BO_DOB23,
BO_DOB24, BO_DOB25, BO_DOB26, BO_DOB27, BO_DOB28, BO_DOB29,
BO_DOB30, BO_DOB31,
BO_DOPB0, BO_DOPB1, BO_DOPB2, BO_DOPB3,
BO_LAST = BO_DOPB3
};
//
// DEV_MACC
//
enum {
// input:
MI_FIRST = 0,
MI_CEA = MI_FIRST, MI_CEB, MI_CEC, MI_CED, MI_CEM, MI_CEP,
MI_CE_OPMODE, MI_CE_CARRYIN,
MI_OPMODE0, MI_OPMODE1, MI_OPMODE2, MI_OPMODE3,
MI_OPMODE4, MI_OPMODE5, MI_OPMODE6, MI_OPMODE7,
MI_A0, MI_A1, MI_A2, MI_A3, MI_A4, MI_A5, MI_A6, MI_A7,
MI_A8, MI_A9, MI_A10, MI_A11, MI_A12, MI_A13, MI_A14, MI_A15,
MI_A16, MI_A17,
MI_B0, MI_B1, MI_B2, MI_B3, MI_B4, MI_B5, MI_B6, MI_B7,
MI_B8, MI_B9, MI_B10, MI_B11, MI_B12, MI_B13, MI_B14, MI_B15,
MI_B16, MI_B17,
MI_C0, MI_C1, MI_C2, MI_C3, MI_C4, MI_C5, MI_C6, MI_C7,
MI_C8, MI_C9, MI_C10, MI_C11, MI_C12, MI_C13, MI_C14, MI_C15,
MI_C16, MI_C17, MI_C18, MI_C19, MI_C20, MI_C21, MI_C22, MI_C23,
MI_C24, MI_C25, MI_C26, MI_C27, MI_C28, MI_C29, MI_C30, MI_C31,
MI_C32, MI_C33, MI_C34, MI_C35, MI_C36, MI_C37, MI_C38, MI_C39,
MI_C40, MI_C41, MI_C42, MI_C43, MI_C44, MI_C45, MI_C46, MI_C47,
MI_D0, MI_D1, MI_D2, MI_D3, MI_D4, MI_D5, MI_D6, MI_D7,
MI_D8, MI_D9, MI_D10, MI_D11, MI_D12, MI_D13, MI_D14, MI_D15,
MI_D16, MI_D17,
MI_LAST = MI_D17,
// output:
MO_FIRST,
MO_CARRYOUT = MO_FIRST,
MO_P0, MO_P1, MO_P2, MO_P3, MO_P4, MO_P5, MO_P6, MO_P7,
MO_P8, MO_P9, MO_P10, MO_P11, MO_P12, MO_P13, MO_P14, MO_P15,
MO_P16, MO_P17, MO_P18, MO_P19, MO_P20, MO_P21, MO_P22, MO_P23,
MO_P24, MO_P25, MO_P26, MO_P27, MO_P28, MO_P29, MO_P30, MO_P31,
MO_P32, MO_P33, MO_P34, MO_P35, MO_P36, MO_P37, MO_P38, MO_P39,
MO_P40, MO_P41, MO_P42, MO_P43, MO_P44, MO_P45, MO_P46, MO_P47,
MO_M0, MO_M1, MO_M2, MO_M3, MO_M4, MO_M5, MO_M6, MO_M7,
MO_M8, MO_M9, MO_M10, MO_M11, MO_M12, MO_M13, MO_M14, MO_M15,
MO_M16, MO_M17, MO_M18, MO_M19, MO_M20, MO_M21, MO_M22, MO_M23,
MO_M24, MO_M25, MO_M26, MO_M27, MO_M28, MO_M29, MO_M30, MO_M31,
MO_M32, MO_M33, MO_M34, MO_M35,
MO_LAST = MO_M35
};
//
// fpga_device
//
@ -851,10 +980,10 @@ enum extra_wires {
FAN_B,
GFAN0,
GFAN1,
CLK0,
CLK1,
SR0,
SR1,
CLK0, // == clka for bram
CLK1, // == clkb for bram
SR0, // == rsta for bram
SR1, // == rstb for bram
LOGICIN20,
LOGICIN21,
LOGICIN44,
@ -883,7 +1012,15 @@ enum extra_wires {
LW,
// logic wires are encoded here as LOGIC_BEG+LI_A1. LD1 (0x100)
// can be OR'ed to the LI or LO value.
LW_LAST = 1999
LW_LAST = 1999,
// bram wires are BW + (BI_/BO_, ORed with B8_0(0x100) or B8_1(0x200))
BW,
BW_LAST = 2999,
// macc wires are MW + MI_/MO_
MW,
MW_LAST = 3499,
};
const char* fpga_wire2str(enum extra_wires wire);
@ -891,3 +1028,13 @@ str16_t fpga_wire2str_i(struct fpga_model* model, enum extra_wires wire);
enum extra_wires fpga_str2wire(const char* str);
int fdev_logic_inbit(pinw_idx_t idx);
int fdev_logic_outbit(pinw_idx_t idx);
// physically, tile3 is at the top, tile0 at the bottom
// errors are returned as -1 in tile0_to_3
void fdev_bram_inbit(enum extra_wires wire, int* tile0_to_3, int* wire0_to_62);
void fdev_bram_outbit(enum extra_wires wire, int* tile0_to_3, int* wire0_to_23);
int fdev_is_bram8_inwire(int bi_wire); // direct BI_ value
int fdev_is_bram8_outwire(int bo_wire); // direct BO_ value
void fdev_macc_inbit(enum extra_wires wire, int* tile0_to_3, int* wire0_to_62);
void fdev_macc_outbit(enum extra_wires wire, int* tile0_to_3, int* wire0_to_23);

View File

@ -84,6 +84,49 @@ static int connect_logic_carry(struct fpga_model* model)
if ((rc = add_conn_bi(model, y, x, "M_COUT_N", y-1, x, "M_CIN"))) goto xout;
}
}
else if (has_device_type(model, y, x, DEV_LOGIC, LOGIC_L)) {
if (is_aty(Y_CHIP_HORIZ_REGS, model, y-1)) {
if (x == model->center_x - CENTER_LOGIC_O) {
struct w_net net = {
0,
{{ "L_CIN", 0, y-3, x },
{ "INT_INTERFACE_COUT", 0, y-2, x },
{ "REGC_CLE_COUT", 0, y-1, x },
{ "XL_COUT_N", 0, y, x },
{ "" }}};
if ((rc = add_conn_net(model, NOPREF_BI_F, &net))) goto xout;
} else {
struct w_net net = {
0,
{{ "L_CIN", 0, y-2, x },
{ "REGH_CLEXL_COUT", 0, y-1, x },
{ "XL_COUT_N", 0, y, x },
{ "" }}};
if ((rc = add_conn_net(model, NOPREF_BI_F, &net))) goto xout;
}
} else if (is_aty(Y_ROW_HORIZ_AXSYMM, model, y-1)) {
struct w_net net = {
0,
{{ "L_CIN", 0, y-2, x },
{ "HCLK_CLEXL_COUT", 0, y-1, x },
{ "XL_COUT_N", 0, y, x },
{ "" }}};
if ((rc = add_conn_net(model, NOPREF_BI_F, &net))) goto xout;
} else if (is_aty(Y_ROW_HORIZ_AXSYMM, model, y-2)
&& (x == model->center_x - CENTER_LOGIC_O)) {
struct w_net net = {
0,
{{ "L_CIN", 0, y-4, x },
{ "INT_INTERFACE_COUT", 0, y-3, x },
{ "HCLK_CLEXL_COUT", 0, y-2, x },
{ "INT_INTERFACE_COUT_BOT", 0, y-1, x },
{ "XL_COUT_N", 0, y, x },
{ "" }}};
if ((rc = add_conn_net(model, NOPREF_BI_F, &net))) goto xout;
} else if (has_device_type(model, y-1, x, DEV_LOGIC, LOGIC_L)) {
if ((rc = add_conn_bi(model, y, x, "XL_COUT_N", y-1, x, "L_CIN"))) goto xout;
}
}
}
}
}

View File

@ -58,6 +58,29 @@ int init_devices(struct fpga_model* model)
if ((rc = add_dev(model, y, x, DEV_SLAVE_SPI, 0))) goto fail;
if ((rc = add_dev(model, y, x, DEV_SUSPEND_SYNC, 0))) goto fail;
// OCT_CALIBRATE
x = LEFT_IO_DEVS;
if ((rc = add_dev(model, TOP_IO_TILES, x, DEV_OCT_CALIBRATE, 0)))
FAIL(rc);
if ((rc = add_dev(model, TOP_IO_TILES, x, DEV_OCT_CALIBRATE, 0)))
FAIL(rc);
if ((rc = add_dev(model, model->y_height-BOT_IO_TILES-1, x,
DEV_OCT_CALIBRATE, 0))) FAIL(rc);
if ((rc = add_dev(model, model->y_height-BOT_IO_TILES-1, x,
DEV_OCT_CALIBRATE, 0))) FAIL(rc);
// DNA, PMV
x = LEFT_IO_DEVS;
y = TOP_IO_TILES;
if ((rc = add_dev(model, y, x, DEV_DNA, 0))) FAIL(rc);
if ((rc = add_dev(model, y, x, DEV_PMV, 0))) FAIL(rc);
// PCILOGIC_SE
if ((rc = add_dev(model, model->center_y, LEFT_IO_ROUTING,
DEV_PCILOGIC_SE, 0))) FAIL(rc);
if ((rc = add_dev(model, model->center_y, model->x_width
- RIGHT_IO_DEVS_O, DEV_PCILOGIC_SE, 0))) FAIL(rc);
// BUFGMUX
y = model->center_y;
x = model->center_x;

View File

@ -749,6 +749,7 @@ const char* fpga_wire2str(enum extra_wires wire)
enum { NUM_BUFS = 8, BUF_SIZE = 64 };
static char buf[NUM_BUFS][BUF_SIZE];
static int last_buf = 0;
int flags;
switch (wire) {
case GFAN0: return "GFAN0";
@ -781,7 +782,6 @@ const char* fpga_wire2str(enum extra_wires wire)
snprintf(buf[last_buf], sizeof(buf[0]), "GCLK%i", wire-GCLK0);
else if (wire >= DW && wire <= DW_LAST) {
char beg_end;
int flags;
wire -= DW;
flags = wire & DIR_FLAGS;
@ -804,7 +804,92 @@ const char* fpga_wire2str(enum extra_wires wire)
else if ((wire&(~LD1)) >= LO_FIRST && (wire&(~LD1)) <= LO_LAST)
snprintf(buf[last_buf], sizeof(buf[0]), "LOGICOUT%i", fdev_logic_outbit(wire));
else HERE();
} else if (wire >= BW && wire <= BW_LAST) {
const char* bram_pref;
int bram_w;
wire -= BW;
flags = wire & BW_FLAGS;
bram_w = wire & ~BW_FLAGS;
if (flags & B8_0)
bram_pref = "RAMB8BWER_0_";
else if (flags & B8_1)
bram_pref = "RAMB8BWER_1_";
else
bram_pref = "RAMB16BWER_";
if (bram_w >= BI_ADDRA0 && bram_w <= BI_ADDRA13) {
snprintf(buf[last_buf], sizeof(buf[0]), "%sADDRA%i", bram_pref, bram_w-BI_ADDRA0);
} else if (bram_w >= BI_ADDRB0 && bram_w <= BI_ADDRB13) {
snprintf(buf[last_buf], sizeof(buf[0]), "%sADDRB%i", bram_pref, bram_w-BI_ADDRB0);
} else if (bram_w >= BI_DIA0 && bram_w <= BI_DIA31) {
snprintf(buf[last_buf], sizeof(buf[0]), "%sDIA%i", bram_pref, bram_w-BI_DIA0);
} else if (bram_w >= BI_DIB0 && bram_w <= BI_DIB31) {
snprintf(buf[last_buf], sizeof(buf[0]), "%sDIB%i", bram_pref, bram_w-BI_DIB0);
} else if (bram_w >= BI_DIPA0 && bram_w <= BI_DIPA3) {
snprintf(buf[last_buf], sizeof(buf[0]), "%sDIPA%i", bram_pref, bram_w-BI_DIPA0);
} else if (bram_w >= BI_DIPB0 && bram_w <= BI_DIPB3) {
snprintf(buf[last_buf], sizeof(buf[0]), "%sDIPB%i", bram_pref, bram_w-BI_DIPB0);
} else if (bram_w >= BO_DOA0 && bram_w <= BO_DOA31) {
snprintf(buf[last_buf], sizeof(buf[0]), "%sDOA%i", bram_pref, bram_w-BO_DOA0);
} else if (bram_w >= BO_DOB0 && bram_w <= BO_DOB31) {
snprintf(buf[last_buf], sizeof(buf[0]), "%sDOB%i", bram_pref, bram_w-BO_DOB0);
} else if (bram_w >= BO_DOPA0 && bram_w <= BO_DOPA3) {
snprintf(buf[last_buf], sizeof(buf[0]), "%sDOPA%i", bram_pref, bram_w-BO_DOPA0);
} else if (bram_w >= BO_DOPB0 && bram_w <= BO_DOPB3) {
snprintf(buf[last_buf], sizeof(buf[0]), "%sDOPB%i", bram_pref, bram_w-BO_DOPB0);
} else if (bram_w >= BI_WEA0 && bram_w <= BI_WEA3) {
snprintf(buf[last_buf], sizeof(buf[0]), "%sWEA%i", bram_pref, bram_w-BI_WEA0);
} else if (bram_w >= BI_WEB0 && bram_w <= BI_WEB3) {
snprintf(buf[last_buf], sizeof(buf[0]), "%sWEB%i", bram_pref, bram_w-BI_WEB0);
} else if (bram_w == BI_REGCEA) {
snprintf(buf[last_buf], sizeof(buf[0]), "%sREGCEA", bram_pref);
} else if (bram_w == BI_REGCEB) {
snprintf(buf[last_buf], sizeof(buf[0]), "%sREGCEB", bram_pref);
} else if (bram_w == BI_ENA) {
snprintf(buf[last_buf], sizeof(buf[0]), "%sENA", bram_pref);
} else if (bram_w == BI_ENB) {
snprintf(buf[last_buf], sizeof(buf[0]), "%sENB", bram_pref);
} else HERE();
} else if (wire >= MW && wire <= MW_LAST) {
int macc_w = wire - MW;
if (macc_w >= MI_A0 && macc_w <= MI_A17)
snprintf(buf[last_buf], sizeof(buf[0]), "A%i_DSP48A1_SITE", macc_w-MI_A0);
else if (macc_w >= MI_B0 && macc_w <= MI_B17)
snprintf(buf[last_buf], sizeof(buf[0]), "B%i_DSP48A1_SITE", macc_w-MI_B0);
else if (macc_w >= MI_C0 && macc_w <= MI_C47)
snprintf(buf[last_buf], sizeof(buf[0]), "C%i_DSP48A1_SITE", macc_w-MI_C0);
else if (macc_w >= MI_D0 && macc_w <= MI_D17)
snprintf(buf[last_buf], sizeof(buf[0]), "D%i_DSP48A1_SITE", macc_w-MI_D0);
else if (macc_w >= MI_OPMODE0 && macc_w <= MI_OPMODE7)
snprintf(buf[last_buf], sizeof(buf[0]), "OPMODE%i_DSP48A1_SITE", macc_w-MI_OPMODE0);
else if (macc_w >= MO_P0 && macc_w <= MO_P47)
snprintf(buf[last_buf], sizeof(buf[0]), "P%i_DSP48A1_SITE", macc_w-MO_P0);
else if (macc_w >= MO_M0 && macc_w <= MO_M35)
snprintf(buf[last_buf], sizeof(buf[0]), "M%i_DSP48A1_SITE", macc_w-MO_M0);
else if (macc_w == MI_CEA)
snprintf(buf[last_buf], sizeof(buf[0]), "CEA_DSP48A1_SITE");
else if (macc_w == MI_CEB)
snprintf(buf[last_buf], sizeof(buf[0]), "CEB_DSP48A1_SITE");
else if (macc_w == MI_CEC)
snprintf(buf[last_buf], sizeof(buf[0]), "CEC_DSP48A1_SITE");
else if (macc_w == MI_CED)
snprintf(buf[last_buf], sizeof(buf[0]), "CED_DSP48A1_SITE");
else if (macc_w == MI_CEM)
snprintf(buf[last_buf], sizeof(buf[0]), "CEM_DSP48A1_SITE");
else if (macc_w == MI_CEP)
snprintf(buf[last_buf], sizeof(buf[0]), "CEP_DSP48A1_SITE");
else if (macc_w == MI_CE_OPMODE)
snprintf(buf[last_buf], sizeof(buf[0]), "CEOPMODE_DSP48A1_SITE");
else if (macc_w == MI_CE_CARRYIN)
snprintf(buf[last_buf], sizeof(buf[0]), "CECARRYIN_DSP48A1_SITE");
else if (macc_w == MO_CARRYOUT)
snprintf(buf[last_buf], sizeof(buf[0]), "CARRYOUTF_DSP48A1_SITE");
else HERE();
} else HERE();
return buf[last_buf];
}
@ -1064,3 +1149,432 @@ int fdev_logic_outbit(pinw_idx_t idx)
HERE();
return -1;
}
void fdev_bram_inbit(enum extra_wires wire, int* tile0_to_3, int* wire0_to_62)
{
const int ramb16_map[4*63] = {
// tile #3 (topmost)
/* 0*/ 0, BW+BI_DIB25, 0, BW+BI_DIB24,
/* 4*/ BW+BI_DIB22, 0, 0, 0,
/* 8*/ BW+BI_DIB31, BW+BI_DIB29, BW+BI_WEA0, 0,
/*12*/ 0, 0, 0, 0,
/*16*/ 0, 0, 0, BW+BI_DIB26,
/*20*/ 0, 0, 0, BW+BI_DIB19,
/*24*/ BW+BI_ADDRB13, BW+BI_REGCEB, BW+BI_DIPB2, BW+BI_DIB27,
/*28*/ 0, 0, BW+BI_WEA1, 0,
/*32*/ 0, 0, 0, 0,
/*36*/ 0, 0, BW+BI_DIB18, BW+BI_DIB30,
/*40*/ 0, BW+BI_DIPB3, 0, 0,
/*44*/ BW+BI_WEA3, 0, 0, BW+BI_DIB17,
/*48*/ 0, 0, 0, 0,
/*52*/ 0, 0, BW+BI_DIB20, BW+BI_DIB23,
/*56*/ 0, BW+BI_DIB21, BW+BI_WEA2, BW+BI_DIB28,
/*60*/ 0, 0, BW+BI_DIB16,
// tile #2
/* 0*/ 0, 0, 0, BW+BI_DIA27,
/* 4*/ BW+BI_ADDRB10, BW+BI_ADDRB2, 0, BW+BI_DIA17,
/* 8*/ 0, BW+BI_DIA31, BW+BI_ADDRB12, 0,
/*12*/ BW+BI_ADDRB3, 0, 0, BW+BI_DIA16,
/*16*/ BW+BI_DIA19, BW+BI_ADDRB7, 0, BW+BI_DIA28,
/*20*/ BW+BI_DIA20, 0, 0, BW+BI_DIA22,
/*24*/ BW+BI_ADDRB0, BW+BI_ADDRB9, BW+BI_DIA24, BW+BI_DIA30,
/*28*/ BW+BI_DIA29, 0, BW+BI_DIA25, 0,
/*32*/ BW+BI_REGCEA, 0, 0, 0,
/*36*/ BW+BI_DIA18, 0, BW+BI_DIA21, 0,
/*40*/ 0, BW+BI_DIA26, BW+BI_ADDRB1, 0,
/*44*/ BW+BI_DIPA2, BW+BI_ADDRB6, 0, BW+BI_ADDRB5,
/*48*/ BW+BI_DIA23, 0, 0, 0,
/*52*/ 0, 0, BW+BI_ENB, BW+BI_DIPA3,
/*56*/ 0, BW+BI_ADDRB8, BW+BI_ADDRB11, 0,
/*60*/ 0, 0, BW+BI_ADDRB4,
// tile #1
/* 0*/ 0, BW+BI_ADDRA5, BW+BI_DIB13, BW+BI_DIB8,
/* 4*/ BW+BI_DIB5, 0, 0, 0,
/* 8*/ BW+BI_ADDRA11, BW+BI_ADDRA8, BW+BI_ADDRA3, 0,
/*12*/ BW+BI_DIB0, 0, BW+BI_DIB14, 0,
/*16*/ 0, 0, 0, BW+BI_DIB9,
/*20*/ 0, 0, 0, BW+BI_DIB3,
/*24*/ 0, 0, BW+BI_DIB7, BW+BI_ADDRA6,
/*28*/ BW+BI_DIB10, BW+BI_DIB11, BW+BI_DIPB1, BW+BI_ADDRA12,
/*32*/ BW+BI_ADDRA7, 0, BW+BI_ADDRA0, 0,
/*36*/ 0, BW+BI_DIB15, BW+BI_DIB2, BW+BI_ADDRA10,
/*40*/ 0, BW+BI_DIPB0, 0, 0,
/*44*/ BW+BI_ADDRA2, 0, 0, BW+BI_DIB1,
/*48*/ BW+BI_ENA, 0, 0, 0,
/*52*/ BW+BI_ADDRA9, 0, BW+BI_ADDRA1, BW+BI_DIB6,
/*56*/ 0, BW+BI_DIB4, BW+BI_ADDRA4, BW+BI_DIB12,
/*60*/ 0, 0, 0,
// tile #0 (bottommost)
/* 0*/ 0, 0, 0, BW+BI_DIA11,
/* 4*/ BW+BI_WEB0, 0, 0, BW+BI_DIA1,
/* 8*/ 0, BW+BI_DIA15, BW+BI_DIA10, 0,
/*12*/ 0, 0, 0, BW+BI_DIA0,
/*16*/ BW+BI_DIA3, 0, 0, BW+BI_DIA12,
/*20*/ BW+BI_DIA4, 0, 0, BW+BI_DIA6,
/*24*/ 0, BW+BI_WEB1, BW+BI_DIA8, BW+BI_DIA13,
/*28*/ 0, 0, BW+BI_DIA9, BW+BI_ADDRA13,
/*32*/ BW+BI_DIA14, 0, BW+BI_WEB3, 0,
/*36*/ BW+BI_DIA2, 0, BW+BI_DIA5, 0,
/*40*/ 0, 0, 0, 0,
/*44*/ 0, 0, 0, 0,
/*48*/ BW+BI_DIA7, 0, 0, 0,
/*52*/ 0, 0, BW+BI_WEB2, BW+BI_DIPA1,
/*56*/ 0, BW+BI_DIPA0, 0, 0,
/*60*/ 0, 0, 0 };
const int ramb8_map[4*63] = {
// tile #3 (topmost)
/* 0*/ 0, BW+(B8_1|BI_DIB9), 0, BW+(B8_1|BI_DIB8),
/* 4*/ BW+(B8_1|BI_DIB6), BW+(B8_1|BI_ADDRB4), 0, BW+(B8_1|BI_ADDRB2),
/* 8*/ BW+(B8_1|BI_DIB15), BW+(B8_1|BI_DIB13), BW+(B8_0|BI_WEA0), 0,
/*12*/ BW+(B8_1|BI_ADDRB6), 0, 0, BW+(B8_1|BI_ADDRB1),
/*16*/ BW+(B8_1|BI_ADDRB8), BW+(B8_1|BI_ADDRB10), 0, BW+(B8_1|BI_DIB10),
/*20*/ BW+(B8_1|BI_ADDRB7), 0, 0, BW+(B8_1|BI_DIB3),
/*24*/ BW+(B8_1|BI_ADDRB0), BW+(B8_0|BI_REGCEB), BW+(B8_1|BI_DIPB0), BW+(B8_1|BI_DIB11),
/*28*/ 0, 0, BW+(B8_0|BI_WEA1), 0,
/*32*/ 0, 0, BW+(B8_1|BI_ADDRB11), 0,
/*36*/ BW+(B8_1|BI_ADDRB5), 0, BW+(B8_1|BI_DIB2), BW+(B8_1|BI_DIB14),
/*40*/ 0, BW+(B8_1|BI_DIPB1), BW+(B8_1|BI_ADDRB3), 0,
/*44*/ BW+(B8_1|BI_WEA1), BW+(B8_1|BI_ADDRB9), 0, BW+(B8_1|BI_DIB1),
/*48*/ BW+(B8_1|BI_ADDRB12), 0, 0, 0,
/*52*/ 0, 0, BW+(B8_1|BI_DIB4), BW+(B8_1|BI_DIB7),
/*56*/ 0, BW+(B8_1|BI_DIB5), BW+(B8_1|BI_WEA0), BW+(B8_1|BI_DIB12),
/*60*/ 0, 0, BW+(B8_1|BI_DIB0),
// tile #2
/* 0*/ 0, 0, 0, BW+(B8_1|BI_DIA11),
/* 4*/ BW+(B8_0|BI_ADDRB10), BW+(B8_0|BI_ADDRB2), 0, BW+(B8_1|BI_DIA1),
/* 8*/ 0, BW+(B8_1|BI_DIA15), BW+(B8_0|BI_ADDRB12), 0,
/*12*/ BW+(B8_0|BI_ADDRB3), 0, 0, BW+(B8_1|BI_DIA0),
/*16*/ BW+(B8_1|BI_DIA3), BW+(B8_0|BI_ADDRB7), 0, BW+(B8_1|BI_DIA12),
/*20*/ BW+(B8_1|BI_DIA4), 0, 0, BW+(B8_1|BI_DIA6),
/*24*/ BW+(B8_0|BI_ADDRB0), BW+(B8_0|BI_ADDRB9), BW+(B8_1|BI_DIA8), BW+(B8_1|BI_DIA14),
/*28*/ BW+(B8_1|BI_DIA13), BW+(B8_1|BI_REGCEA), BW+(B8_1|BI_DIA9), 0,
/*32*/ BW+(B8_0|BI_REGCEA), 0, BW+(B8_1|BI_ENB), 0,
/*36*/ BW+(B8_1|BI_DIA2), 0, BW+(B8_1|BI_DIA5), 0,
/*40*/ 0, BW+(B8_1|BI_DIA10), BW+(B8_0|BI_ADDRB1), 0,
/*44*/ BW+(B8_1|BI_DIPA0), BW+(B8_0|BI_ADDRB6), 0, BW+(B8_0|BI_ADDRB5),
/*48*/ BW+(B8_1|BI_DIA7), 0, 0, 0,
/*52*/ 0, 0, BW+(B8_0|BI_ENB), BW+(B8_1|BI_DIPA1),
/*56*/ 0, BW+(B8_0|BI_ADDRB8), BW+(B8_0|BI_ADDRB11), BW+(B8_1|BI_REGCEB),
/*60*/ 0, 0, BW+(B8_0|BI_ADDRB4),
// tile #1
/* 0*/ 0, BW+(B8_0|BI_ADDRA5), BW+(B8_0|BI_DIB13), BW+(B8_0|BI_DIB8),
/* 4*/ BW+(B8_0|BI_DIB5), 0, 0, 0,
/* 8*/ BW+(B8_0|BI_ADDRA11), BW+(B8_0|BI_ADDRA8), BW+(B8_0|BI_ADDRA3), 0,
/*12*/ BW+(B8_0|BI_DIB0), 0, BW+(B8_0|BI_DIB14), 0,
/*16*/ 0, 0, 0, BW+(B8_0|BI_DIB9),
/*20*/ 0, 0, 0, BW+(B8_0|BI_DIB3),
/*24*/ 0, BW+(B8_1|BI_ENA), BW+(B8_0|BI_DIB7), BW+(B8_0|BI_ADDRA6),
/*28*/ BW+(B8_0|BI_DIB10), BW+(B8_0|BI_DIB11), BW+(B8_0|BI_DIPB1), BW+(B8_0|BI_ADDRA12),
/*32*/ BW+(B8_0|BI_ADDRA7), 0, BW+(B8_0|BI_ADDRA0), 0,
/*36*/ 0, BW+(B8_0|BI_DIB15), BW+(B8_0|BI_DIB2), BW+(B8_0|BI_ADDRA10),
/*40*/ 0, BW+(B8_0|BI_DIPB0), 0, 0,
/*44*/ BW+(B8_0|BI_ADDRA2), 0, 0, BW+(B8_0|BI_DIB1),
/*48*/ BW+(B8_0|BI_ENA), 0, 0, 0,
/*52*/ BW+(B8_0|BI_ADDRA9), 0, BW+(B8_0|BI_ADDRA1), BW+(B8_0|BI_DIB6),
/*56*/ 0, BW+(B8_0|BI_DIB4), BW+(B8_0|BI_ADDRA4), BW+(B8_0|BI_DIB12),
/*60*/ 0, 0, 0,
// tile #0 (bottommost)
/* 0*/ 0, BW+(B8_1|BI_ADDRA3), BW+(B8_1|BI_ADDRA8), BW+(B8_0|BI_DIA11),
/* 4*/ BW+(B8_0|BI_WEB0), 0, 0, BW+(B8_0|BI_DIA1),
/* 8*/ BW+(B8_1|BI_ADDRA12), BW+(B8_0|BI_DIA15), BW+(B8_0|BI_DIA10), 0,
/*12*/ 0, 0, BW+(B8_1|BI_ADDRA9), BW+(B8_0|BI_DIA0),
/*16*/ BW+(B8_0|BI_DIA3), 0, 0, BW+(B8_0|BI_DIA12),
/*20*/ BW+(B8_0|BI_DIA4), 0, 0, BW+(B8_0|BI_DIA6),
/*24*/ 0, BW+(B8_0|BI_WEB1), BW+(B8_0|BI_DIA8), BW+(B8_0|BI_DIA13),
/*28*/ BW+(B8_1|BI_ADDRA4), BW+(B8_1|BI_ADDRA5), BW+(B8_0|BI_DIA9), BW+(B8_1|BI_ADDRA0),
/*32*/ BW+(B8_0|BI_DIA14), 0, BW+(B8_1|BI_WEB1), 0,
/*36*/ BW+(B8_0|BI_DIA2), BW+(B8_1|BI_ADDRA11), BW+(B8_0|BI_DIA5), BW+(B8_1|BI_ADDRA10),
/*40*/ 0, BW+(B8_1|BI_ADDRA1), 0, 0,
/*44*/ 0, 0, 0, 0,
/*48*/ BW+(B8_0|BI_DIA7), 0, 0, 0,
/*52*/ BW+(B8_1|BI_ADDRA7), 0, BW+(B8_1|BI_WEB0), BW+(B8_0|BI_DIPA1),
/*56*/ 0, BW+(B8_0|BI_DIPA0), BW+(B8_1|BI_ADDRA2), BW+(B8_1|BI_ADDRA6),
/*60*/ 0, 0, 0 };
const int *search_map;
int i;
if (wire < BW || wire > BW_LAST) {
HERE();
*tile0_to_3 = -1;
return;
}
search_map = ((wire-BW) & BW_FLAGS) ? ramb8_map : ramb16_map;
for (i = 0; i < 4*63; i++) {
if (search_map[i] == wire) {
*tile0_to_3 = 3-(i/63);
*wire0_to_62 = i%63;
return;
}
}
fprintf(stderr, "#E %s:%i unknown wire %i\n",
__FILE__, __LINE__, wire);
*tile0_to_3 = -1;
}
void fdev_bram_outbit(enum extra_wires wire, int* tile0_to_3, int* wire0_to_23)
{
const int ramb16_map[4*24] = {
// tile #3 (topmost)
/* 0*/ 0, BW+BO_DOPB3, 0, BW+BO_DOB27,
/* 4*/ BW+BO_DOA29, BW+BO_DOA25, BW+BO_DOB29, BW+BO_DOA24,
/* 8*/ BW+BO_DOPA3, BW+BO_DOB31, BW+BO_DOB25, BW+BO_DOA31,
/*12*/ BW+BO_DOB24, 0, 0, BW+BO_DOA27,
/*16*/ BW+BO_DOA30, BW+BO_DOA26, BW+BO_DOA28, 0,
/*20*/ BW+BO_DOB28, BW+BO_DOB30, BW+BO_DOB26, 0,
// tile #2
/* 0*/ BW+BO_DOA18, BW+BO_DOB20, BW+BO_DOA16, BW+BO_DOPB2,
/* 4*/ BW+BO_DOA23, BW+BO_DOB18, BW+BO_DOB22, 0,
/* 8*/ BW+BO_DOA20, 0, BW+BO_DOA19, 0,
/*12*/ BW+BO_DOB17, BW+BO_DOA22, BW+BO_DOA17, 0,
/*16*/ BW+BO_DOB23, BW+BO_DOB19, BW+BO_DOA21, BW+BO_DOB16,
/*20*/ BW+BO_DOB21, 0, BW+BO_DOPA2, 0,
// tile #1
/* 0*/ BW+BO_DOB8, BW+BO_DOPA1, 0, BW+BO_DOA11,
/* 4*/ BW+BO_DOB13, BW+BO_DOA9, BW+BO_DOA13, 0,
/* 8*/ BW+BO_DOB11, BW+BO_DOB15, BW+BO_DOB9, BW+BO_DOA15,
/*12*/ BW+BO_DOA8, BW+BO_DOB12, 0, 0,
/*16*/ BW+BO_DOA14, BW+BO_DOA10, BW+BO_DOPB1, 0,
/*20*/ BW+BO_DOA12, BW+BO_DOB14, BW+BO_DOB10, 0,
// tile #0 (bottommost)
/* 0*/ BW+BO_DOA2, BW+BO_DOB4, BW+BO_DOA0, BW+BO_DOPB0,
/* 4*/ BW+BO_DOB6, BW+BO_DOB2, BW+BO_DOA6, BW+BO_DOA1,
/* 8*/ BW+BO_DOA4, 0, BW+BO_DOA3, 0,
/*12*/ BW+BO_DOB1, BW+BO_DOB5, BW+BO_DOB0, BW+BO_DOPA0,
/*16*/ BW+BO_DOA7, BW+BO_DOB3, BW+BO_DOA5, 0,
/*20*/ 0, BW+BO_DOB7, 0, 0
};
const int ramb8_map[4*24] = {
// tile #3 (topmost)
/* 0*/ 0, BW+(BO_DOPB1|B8_1), 0, BW+(BO_DOB11|B8_1),
/* 4*/ BW+(BO_DOA13|B8_1), BW+(BO_DOA9|B8_1), BW+(BO_DOB13|B8_1), BW+(BO_DOA8|B8_1),
/* 8*/ BW+(BO_DOPA1|B8_1), BW+(BO_DOB15|B8_1), BW+(BO_DOB9|B8_1), BW+(BO_DOA15|B8_1),
/*12*/ BW+(BO_DOB8|B8_1), 0, 0, BW+(BO_DOA11|B8_1),
/*16*/ BW+(BO_DOA14|B8_1), BW+(BO_DOA10|B8_1), BW+(BO_DOA12|B8_1), 0,
/*20*/ BW+(BO_DOB12|B8_1), BW+(BO_DOB14|B8_1), BW+(BO_DOB10|B8_1), 0,
// tile #2
/* 0*/ BW+(BO_DOA2|B8_1), BW+(BO_DOB4|B8_1), BW+(BO_DOA0|B8_1), BW+(BO_DOPB0|B8_1),
/* 4*/ BW+(BO_DOA7|B8_1), BW+(BO_DOB2|B8_1), BW+(BO_DOB6|B8_1), 0,
/* 8*/ BW+(BO_DOA4|B8_1), 0, BW+(BO_DOA3|B8_1), 0,
/*12*/ BW+(BO_DOB1|B8_1), BW+(BO_DOA6|B8_1), BW+(BO_DOA1|B8_1), 0,
/*16*/ BW+(BO_DOB7|B8_1), BW+(BO_DOB3|B8_1), BW+(BO_DOA5|B8_1), BW+(BO_DOB0|B8_1),
/*20*/ BW+(BO_DOB5|B8_1), 0, BW+(BO_DOPA0|B8_1), 0,
// tile #1
/* 0*/ BW+(BO_DOB8|B8_0), BW+(BO_DOPA1|B8_0), 0, BW+(BO_DOA11|B8_0),
/* 4*/ BW+(BO_DOB13|B8_0), BW+(BO_DOA9|B8_0), BW+(BO_DOA13|B8_0), 0,
/* 8*/ BW+(BO_DOB11|B8_0), BW+(BO_DOB15|B8_0), BW+(BO_DOB9|B8_0), BW+(BO_DOA15|B8_0),
/*12*/ BW+(BO_DOA8|B8_0), BW+(BO_DOB12|B8_0), 0, 0,
/*16*/ BW+(BO_DOA14|B8_0), BW+(BO_DOA10|B8_0), BW+(BO_DOPB1|B8_0), 0,
/*20*/ BW+(BO_DOA12|B8_0), BW+(BO_DOB14|B8_0), BW+(BO_DOB10|B8_0), 0,
// tile #0 (bottommost)
/* 0*/ BW+(BO_DOA2|B8_0), BW+(BO_DOB4|B8_0), BW+(BO_DOA0|B8_0), BW+(BO_DOPB0|B8_0),
/* 4*/ BW+(BO_DOB6|B8_0), BW+(BO_DOB2|B8_0), BW+(BO_DOA6|B8_0), BW+(BO_DOA1|B8_0),
/* 8*/ BW+(BO_DOA4|B8_0), 0, BW+(BO_DOA3|B8_0), 0,
/*12*/ BW+(BO_DOB1|B8_0), BW+(BO_DOB5|B8_0), BW+(BO_DOB0|B8_0), BW+(BO_DOPA0|B8_0),
/*16*/ BW+(BO_DOA7|B8_0), BW+(BO_DOB3|B8_0), BW+(BO_DOA5|B8_0), 0,
/*20*/ 0, BW+(BO_DOB7|B8_0), 0, 0
};
const int *search_map;
int i;
if (wire < BW || wire > BW_LAST) {
HERE();
*tile0_to_3 = -1;
return;
}
search_map = ((wire-BW) & BW_FLAGS) ? ramb8_map : ramb16_map;
for (i = 0; i < 4*24; i++) {
if (search_map[i] == wire) {
*tile0_to_3 = 3-(i/24);
*wire0_to_23 = i%24;
return;
}
}
fprintf(stderr, "#E %s:%i unknown wire %i\n",
__FILE__, __LINE__, wire);
*tile0_to_3 = -1;
}
int fdev_is_bram8_inwire(int bi_wire)
{
if (bi_wire == BI_ADDRA13 || bi_wire == BI_ADDRB13)
return 0;
if (bi_wire == BI_WEA2 || bi_wire == BI_WEA3
|| bi_wire == BI_WEB2 || bi_wire == BI_WEB3)
return 0;
if (bi_wire == BI_DIPA2 || bi_wire == BI_DIPA3
|| bi_wire == BI_DIPB2 || bi_wire == BI_DIPB3)
return 0;
if ((bi_wire >= BI_DIA16 && bi_wire <= BI_DIA31)
|| (bi_wire >= BI_DIB16 && bi_wire <= BI_DIB31))
return 0;
return 1;
}
int fdev_is_bram8_outwire(int bo_wire)
{
if (bo_wire == BO_DOPA2 || bo_wire == BO_DOPA3
|| bo_wire == BO_DOPB2 || bo_wire == BO_DOPB3)
return 0;
if ((bo_wire >= BO_DOA16 && bo_wire <= BO_DOA31)
|| (bo_wire >= BO_DOB16 && bo_wire <= BO_DOB31))
return 0;
return 1;
}
void fdev_macc_inbit(enum extra_wires wire, int* tile0_to_3, int* wire0_to_62)
{
const int map[4*63] = {
// tile #3 (topmost)
/* 0*/ 0, MW+MI_A12, 0, MW+MI_C43,
/* 4*/ MW+MI_C40, 0, 0, MW+MI_A6,
/* 8*/ MW+MI_A17, 0, MW+MI_C42, 0,
/*12*/ 0, 0, MW+MI_A16, MW+MI_A5,
/*16*/ MW+MI_A7, MW+MI_C38, 0, MW+MI_A13,
/*20*/ 0, 0, 0, MW+MI_A8,
/*24*/ 0, 0, MW+MI_A10, MW+MI_C44,
/*28*/ 0, MW+MI_A14, MW+MI_A11, 0,
/*32*/ MW+MI_C45, 0, 0, 0,
/*36*/ MW+MI_C36, MW+MI_C47, 0, MW+MI_C46,
/*40*/ 0, 0, 0, 0,
/*44*/ MW+MI_A9, 0, 0, MW+MI_C37,
/*48*/ 0, 0, 0, 0,
/*52*/ MW+MI_A15, 0, 0, MW+MI_C41,
/*56*/ 0, MW+MI_C39, 0, 0,
/*60*/ 0, 0, 0,
// tile #2
/* 0*/ 0, 0, 0, MW+MI_C31,
/* 4*/ MW+MI_C28, 0, 0, MW+MI_D16,
/* 8*/ MW+MI_A4, 0, MW+MI_C30, 0,
/*12*/ MW+MI_D17, 0, MW+MI_C34, MW+MI_OPMODE3,
/*16*/ MW+MI_C24, MW+MI_CED, 0, MW+MI_A0,
/*20*/ MW+MI_C25, 0, 0, MW+MI_C26,
/*24*/ MW+MI_OPMODE7, 0, MW+MI_C29, MW+MI_C32,
/*28*/ 0, MW+MI_A1, MW+MI_CEA, MW+MI_C35,
/*32*/ 0, 0, MW+MI_CE_CARRYIN, 0,
/*36*/ MW+MI_B16, 0, 0, MW+MI_A3,
/*40*/ 0, MW+MI_CEB, MW+MI_OPMODE2, 0,
/*44*/ MW+MI_CEP, 0, 0, MW+MI_B17,
/*48*/ MW+MI_C27, 0, 0, 0,
/*52*/ MW+MI_A2, 0, 0, MW+MI_CE_OPMODE,
/*56*/ 0, MW+MI_CEC, MW+MI_CEM, MW+MI_C33,
/*60*/ 0, 0, MW+MI_OPMODE5,
// tile #1
/* 0*/ 0, MW+MI_B12, MW+MI_D14, 0,
/* 4*/ MW+MI_D11, MW+MI_OPMODE4, 0, 0,
/* 8*/ MW+MI_OPMODE1, MW+MI_C23, MW+MI_D12, 0,
/*12*/ 0, 0, MW+MI_D15, MW+MI_C12,
/*16*/ MW+MI_OPMODE6, MW+MI_C15, 0, MW+MI_C21,
/*20*/ 0, 0, 0, MW+MI_D10,
/*24*/ 0, 0, MW+MI_C18, MW+MI_B13,
/*28*/ MW+MI_D13, 0, 0, MW+MI_OPMODE0,
/*32*/ MW+MI_C22, 0, MW+MI_B9, 0,
/*36*/ MW+MI_C13, 0, 0, MW+MI_B15,
/*40*/ 0, MW+MI_C19, 0, 0,
/*44*/ MW+MI_C17, MW+MI_D9, 0, MW+MI_C14,
/*48*/ MW+MI_C16, 0, 0, 0,
/*52*/ MW+MI_B14, 0, 0, MW+MI_B11,
/*56*/ 0, MW+MI_B10, MW+MI_C20, 0,
/*60*/ 0, 0, 0,
// tile #0 (bottommost)
/* 0*/ 0, MW+MI_D5, 0, MW+MI_C8,
/* 4*/ MW+MI_C5, 0, 0, MW+MI_D0,
/* 8*/ MW+MI_D8, 0, 0, 0,
/*12*/ 0, 0, MW+MI_C11, MW+MI_C0,
/*16*/ 0, MW+MI_C3, 0, 0,
/*20*/ MW+MI_C2, 0, 0, MW+MI_C4,
/*24*/ 0, MW+MI_D2, MW+MI_D4, 0,
/*28*/ MW+MI_C9, MW+MI_B6, MW+MI_B4, MW+MI_B8,
/*32*/ MW+MI_C10, 0, MW+MI_B2, 0,
/*36*/ 0, MW+MI_B7, MW+MI_B1, MW+MI_D7,
/*40*/ 0, MW+MI_C7, MW+MI_B0, 0,
/*44*/ MW+MI_B3, 0, 0, MW+MI_D1,
/*48*/ 0, 0, 0, 0,
/*52*/ 0, 0, 0, MW+MI_C6,
/*56*/ 0, MW+MI_D3, MW+MI_B5, MW+MI_D6,
/*60*/ 0, 0, MW+MI_C1 };
int i;
if (wire < MW || wire > MW_LAST) {
HERE();
*tile0_to_3 = -1;
return;
}
for (i = 0; i < 4*63; i++) {
if (map[i] == wire) {
*tile0_to_3 = 3-(i/63);
*wire0_to_62 = i%63;
return;
}
}
fprintf(stderr, "#E %s:%i unknown wire %i\n",
__FILE__, __LINE__, wire);
*tile0_to_3 = -1;
}
void fdev_macc_outbit(enum extra_wires wire, int* tile0_to_3, int* wire0_to_23)
{
const int map[4*24] = {
// tile #3 (topmost)
/* 0*/ MW+MO_P37, MW+MO_M33, MW+MO_P35, MW+MO_P41,
/* 4*/ MW+MO_M34, MW+MO_P38, MW+MO_P44, MW+MO_M29,
/* 8*/ MW+MO_M32, MW+MO_CARRYOUT, MW+MO_M30, MW+MO_P47,
/*12*/ MW+MO_P36, 0, 0, MW+MO_P40,
/*16*/ MW+MO_M35, MW+MO_M31, MW+MO_P42, MW+MO_M28,
/*20*/ MW+MO_P43, MW+MO_P45, MW+MO_P39, MW+MO_P46,
// tile #2
/* 0*/ MW+MO_M21, MW+MO_P29, MW+MO_M18, MW+MO_M23,
/* 4*/ MW+MO_P32, 0, MW+MO_P31, MW+MO_P24,
/* 8*/ MW+MO_P28, MW+MO_P34, MW+MO_P25, MW+MO_M27,
/*12*/ MW+MO_M20, MW+MO_M25, MW+MO_M19, MW+MO_M22,
/*16*/ 0, MW+MO_P26, MW+MO_P30, 0,
/*20*/ MW+MO_M24, MW+MO_P33, MW+MO_P27, MW+MO_M26,
// tile #1
/* 0*/ MW+MO_M11, MW+MO_P19, MW+MO_P12, MW+MO_M14,
/* 4*/ MW+MO_P21, MW+MO_M12, 0, MW+MO_P13,
/* 8*/ MW+MO_P18, 0, MW+MO_P15, MW+MO_P23,
/*12*/ MW+MO_P14, MW+MO_P20, MW+MO_M9, MW+MO_M13,
/*16*/ MW+MO_P22, MW+MO_P16, MW+MO_M15, MW+MO_M10,
/*20*/ MW+MO_M16, 0, MW+MO_P17, MW+MO_M17,
// tile #0 (bottommost)
/* 0*/ MW+MO_P2, MW+MO_P6, 0, MW+MO_M3,
/* 4*/ MW+MO_P9, MW+MO_P3, MW+MO_M6, MW+MO_P1,
/* 8*/ MW+MO_M4, MW+MO_P11, MW+MO_M1, 0,
/*12*/ MW+MO_M0, MW+MO_M5, MW+MO_P0, MW+MO_P5,
/*16*/ MW+MO_P10, MW+MO_M2, MW+MO_P7, 0,
/*20*/ MW+MO_P8, MW+MO_M7, MW+MO_P4, MW+MO_M8 };
int i;
if (wire < MW || wire > MW_LAST) {
HERE();
*tile0_to_3 = -1;
return;
}
for (i = 0; i < 4*24; i++) {
if (map[i] == wire) {
*tile0_to_3 = 3-(i/24);
*wire0_to_23 = i%24;
return;
}
}
fprintf(stderr, "#E %s:%i unknown wire %i\n",
__FILE__, __LINE__, wire);
*tile0_to_3 = -1;
}

View File

@ -15,6 +15,11 @@ static int init_routing_switches(struct fpga_model* model);
static int init_north_south_dirwire_term(struct fpga_model* model);
static int init_iologic_switches(struct fpga_model* model);
static int init_logic_switches(struct fpga_model* model);
static int init_center_switches(struct fpga_model* model);
static int init_hclk_switches(struct fpga_model* model);
static int init_logicout_fw_switches(struct fpga_model* model);
static int init_bram_switches(struct fpga_model* model);
static int init_macc_switches(struct fpga_model* model);
int init_switches(struct fpga_model* model, int routing_sw)
{
@ -22,26 +27,41 @@ int init_switches(struct fpga_model* model, int routing_sw)
if (routing_sw) {
rc = init_routing_switches(model);
if (rc) goto xout;
if (rc) FAIL(rc);
}
rc = init_logic_switches(model);
if (rc) goto xout;
if (rc) FAIL(rc);
rc = init_iologic_switches(model);
if (rc) goto xout;
if (rc) FAIL(rc);
rc = init_north_south_dirwire_term(model);
if (rc) goto xout;
if (rc) FAIL(rc);
rc = init_ce_clk_switches(model);
if (rc) goto xout;
if (rc) FAIL(rc);
rc = init_io_switches(model);
if (rc) goto xout;
if (rc) FAIL(rc);
rc = init_center_switches(model);
if (rc) FAIL(rc);
rc = init_hclk_switches(model);
if (rc) FAIL(rc);
rc = init_logicout_fw_switches(model);
if (rc) FAIL(rc);
rc = init_bram_switches(model);
if (rc) FAIL(rc);
rc = init_macc_switches(model);
if (rc) FAIL(rc);
return 0;
xout:
fail:
return rc;
}
@ -1142,3 +1162,340 @@ int replicate_routing_switches(struct fpga_model* model)
fail:
return rc;
}
static int init_center_switches(struct fpga_model* model)
{
int i, j, rc;
{ const char* pairs[] =
{ "CLKC_CKLR%i", "CLKC_GCLK%i",
"CLKC_CKTB%i", "CLKC_GCLK%i",
"CLKC_PLL_L%i", "CLKC_GCLK%i",
"CLKC_PLL_U%i", "CLKC_GCLK%i",
"CLKC_SEL%i_PLL", "S_GCLK_SITE%i",
"I0_GCLK_SITE%i", "O_GCLK_SITE%i",
"O_GCLK_SITE%i", "CLKC_GCLK_MAIN%i" };
int i_dest[2][16] =
{{ 0,1,2,4,3,5,6,7,8,9,10,12,11,13,14,15 },
{ 1,0,3,5,2,4,7,6,9,8,11,13,10,12,15,14 }};
for (i = 0; i < sizeof(pairs)/sizeof(*pairs)/2; i++) {
for (j = 0; j <= 15; j++) {
if ((rc = add_switch(model, model->center_y, model->center_x,
pf(pairs[i*2], j), pf(pairs[i*2+1], j),
/*bidir*/ 0))) FAIL(rc);
}
}
for (j = 0; j <= 15; j++) {
if ((rc = add_switch(model, model->center_y, model->center_x,
pf("CLKC_GCLK%i", j), pf("I0_GCLK_SITE%i", i_dest[0][j]),
/*bidir*/ 0))) FAIL(rc);
if ((rc = add_switch(model, model->center_y, model->center_x,
pf("CLKC_GCLK%i", j), pf("I1_GCLK_SITE%i", i_dest[1][j]),
/*bidir*/ 0))) FAIL(rc);
}}
{ const char *to[] = {
"CLK_PLL_LOCK_LT0", "CLK_PLL_LOCK_LT1",
"CLK_PLL_LOCK_RT0", "CLK_PLL_LOCK_RT1" };
const char *from[] = {
"PLL_LOCK_BOT0", "PLL_LOCK_BOT1",
"PLL_LOCK_TOP0", "PLL_LOCK_TOP1" };
for (i = 0; i < sizeof(to)/sizeof(*to); i++) {
for (j = 0; j < sizeof(from)/sizeof(*from); j++) {
if ((rc = add_switch(model, model->center_y,
model->center_x-CENTER_CMTPLL_O,
from[j], to[i], /*bidir*/ 0))) FAIL(rc);
}
}}
{ const char* pairs[] = {
"PLL_LOCK_BOT0", "PLL_LOCK_TOP2",
"PLL_LOCK_BOT1", "PLL_LOCK_TOP2",
"PLL_LOCK_TOP0", "PLL_LOCK_BOT2",
"PLL_LOCK_TOP1", "PLL_LOCK_BOT2" };
for (i = 0; i < sizeof(pairs)/sizeof(*pairs)/2; i++) {
if ((rc = add_switch(model, model->center_y,
model->center_x-CENTER_CMTPLL_O,
pairs[i*2], pairs[i*2+1],
/*bidir*/ 0))) FAIL(rc);
}}
{ const char *to[] = {
"REGC_CLKPLL_IO_LT0", "REGC_CLKPLL_IO_LT1",
"REGC_CLKPLL_IO_RT0", "REGC_CLKPLL_IO_RT1",
"REGC_PLLCLK_UP_OUT0", "REGC_PLLCLK_UP_OUT1" };
for (i = 0; i <= 3; i++) {
for (j = 0; j < sizeof(to)/sizeof(*to); j++) {
if ((rc = add_switch(model, model->center_y,
model->center_x-CENTER_CMTPLL_O,
pf("REGC_PLLCLK_DN_IN%i", i), to[j],
/*bidir*/ 0))) FAIL(rc);
}
}}
{ const char *to[] = {
"REGC_CLKPLL_IO_LT0", "REGC_CLKPLL_IO_LT1",
"REGC_CLKPLL_IO_RT0", "REGC_CLKPLL_IO_RT1",
"REGC_PLLCLK_DN_OUT0", "REGC_PLLCLK_DN_OUT1" };
for (i = 0; i <= 3; i++) {
for (j = 0; j < sizeof(to)/sizeof(*to); j++) {
if ((rc = add_switch(model, model->center_y,
model->center_x-CENTER_CMTPLL_O,
pf("REGC_PLLCLK_UP_IN%i", i), to[j],
/*bidir*/ 0))) FAIL(rc);
}
}}
return 0;
fail:
return rc;
}
static int init_hclk_switches(struct fpga_model* model)
{
int x, y, i, rc;
for (x = 0; x < model->x_width; x++) {
if (!is_atx(X_ROUTING_COL, model, x))
continue;
for (y = TOP_IO_TILES; y < model->y_height-BOT_IO_TILES; y++) {
if (!is_aty(Y_ROW_HORIZ_AXSYMM, model, y))
continue;
for (i = 0; i <= 15; i++) {
if ((rc = add_switch(model, y, x,
pf("HCLK_GCLK%i_INT", i), pf("HCLK_GCLK%i", i),
/*bidir*/ 0))) FAIL(rc);
if ((rc = add_switch(model, y, x,
pf("HCLK_GCLK%i_INT", i), pf("HCLK_GCLK_UP%i", i),
/*bidir*/ 0))) FAIL(rc);
}
}
}
return 0;
fail:
return rc;
}
static int init_logicout_fw_switches(struct fpga_model *model)
{
int i, x, y, rc;
for (x = 0; x < model->x_width; x++) {
if (is_atx(X_FABRIC_BRAM_VIA_COL|X_FABRIC_MACC_VIA_COL, model, x)) {
for (y = TOP_IO_TILES; y < model->y_height - BOT_IO_TILES; y++) {
if (is_aty(Y_CHIP_HORIZ_REGS|Y_ROW_HORIZ_AXSYMM, model, y))
continue;
for (i = 0; i <= 23; i++) {
if ((rc = add_switch(model, y, x,
pf("INT_INTERFACE_LOGICOUT_%i", i), pf("INT_INTERFACE_LOGICOUT%i", i),
/*bidir*/ 0))) FAIL(rc);
}
}
continue;
}
if (is_atx(X_CENTER_ROUTING_COL, model, x)) {
for (y = TOP_IO_TILES; y < model->y_height - BOT_IO_TILES; y++) {
if (!is_aty(Y_ROW_HORIZ_AXSYMM, model, y))
continue;
for (i = 0; i <= 23; i++) {
if ((rc = add_switch(model, y-1, model->center_x-CENTER_LOGIC_O,
pf("INT_INTERFACE_LOGICOUT_%i", i), pf("INT_INTERFACE_LOGICOUT%i", i),
/*bidir*/ 0))) FAIL(rc);
if ((rc = add_switch(model, y+1, model->center_x-CENTER_LOGIC_O,
pf("INT_INTERFACE_LOGICOUT_%i", i), pf("INT_INTERFACE_LOGICOUT%i", i),
/*bidir*/ 0))) FAIL(rc);
}
}
continue;
}
if (is_atx(X_LEFT_IO_DEVS_COL, model, x)) {
for (y = TOP_IO_TILES; y < model->y_height - BOT_IO_TILES; y++) {
if (is_aty(Y_CHIP_HORIZ_REGS|Y_ROW_HORIZ_AXSYMM, model, y)
|| has_device(model, y, LEFT_IO_DEVS, DEV_ILOGIC))
continue;
if (has_device(model, y, LEFT_IO_DEVS, DEV_OCT_CALIBRATE)) {
for (i = 0; i <= 23; i++) {
if ((rc = add_switch(model, y, x,
pf("INT_INTERFACE_LOCAL_LOGICOUT_%i", i), pf("INT_INTERFACE_LOCAL_LOGICOUT%i", i),
/*bidir*/ 0))) FAIL(rc);
}
continue;
}
// todo: this is probably not right...
if (y == model->center_y-1 || y == model->center_y-2
|| y < TOP_IO_TILES + HALF_ROW
|| y == model->y_height-BOT_INNER_IO)
continue;
for (i = 0; i <= 23; i++) {
if ((rc = add_switch(model, y, x,
pf("INT_INTERFACE_LOGICOUT_%i", i), pf("INT_INTERFACE_LOGICOUT%i", i),
/*bidir*/ 0))) FAIL(rc);
}
}
continue;
}
if (is_atx(X_RIGHT_IO_DEVS_COL, model, x)) {
for (y = TOP_IO_TILES; y < model->y_height - BOT_IO_TILES; y++) {
if (is_aty(Y_CHIP_HORIZ_REGS|Y_ROW_HORIZ_AXSYMM, model, y)
|| has_device(model, y, model->x_width-RIGHT_IO_DEVS_O, DEV_ILOGIC))
continue;
if (has_device(model, y, model->x_width-RIGHT_IO_DEVS_O, DEV_BSCAN)
|| has_device(model, y, model->x_width-RIGHT_IO_DEVS_O, DEV_ICAP)
|| has_device(model, y, model->x_width-RIGHT_IO_DEVS_O, DEV_SLAVE_SPI)) {
for (i = 0; i <= 23; i++) {
if ((rc = add_switch(model, y, x,
pf("INT_INTERFACE_LOCAL_LOGICOUT_%i", i), pf("INT_INTERFACE_LOCAL_LOGICOUT%i", i),
/*bidir*/ 0))) FAIL(rc);
}
continue;
}
// todo: this is probably not right...
if (y == model->center_y-1 || y == model->center_y-2
|| y < TOP_IO_TILES + HALF_ROW)
continue;
for (i = 0; i <= 23; i++) {
if ((rc = add_switch(model, y, x,
pf("INT_INTERFACE_LOGICOUT_%i", i), pf("INT_INTERFACE_LOGICOUT%i", i),
/*bidir*/ 0))) FAIL(rc);
}
}
continue;
}
}
return 0;
fail:
return rc;
}
static int init_bram_switches(struct fpga_model* model)
{
int i, x, y, tile0_to_3, wire_num, rc;
for (x = 0; x < model->x_width; x++) {
if (!is_atx(X_FABRIC_BRAM_COL, model, x))
continue;
for (y = TOP_IO_TILES; y < model->y_height - BOT_IO_TILES; y++) {
if (!has_device(model, y, x, DEV_BRAM16))
continue;
{ const char* pairs[] = {
"BRAM_CLK%c_INT1", "RAMB16BWER_CLK%c",
"BRAM_CLK%c_INT1", "RAMB8BWER_0_CLK%c",
"BRAM_CLK%c_INT2", "RAMB8BWER_1_CLK%c" };
for (i = 0; i < sizeof(pairs)/sizeof(*pairs)/2; i++) {
if ((rc = add_switch(model, y, x,
pf(pairs[i*2], '0'+0), pf(pairs[i*2+1], 'A'+0),
/*bidir*/ 0))) FAIL(rc);
if ((rc = add_switch(model, y, x,
pf(pairs[i*2], '0'+1), pf(pairs[i*2+1], 'A'+1),
/*bidir*/ 0))) FAIL(rc);
}}
{ const char *s[] = {
"BRAM_SR0_INT1", "RAMB16BWER_RSTA",
"BRAM_SR0_INT1", "RAMB8BWER_0_RSTA",
"BRAM_SR0_INT2", "RAMB8BWER_1_RSTA",
"BRAM_SR1_INT1", "RAMB16BWER_RSTB",
"BRAM_SR1_INT1", "RAMB8BWER_0_RSTB",
"BRAM_SR1_INT2", "RAMB8BWER_1_RSTB" };
for (i = 0; i < sizeof(s)/sizeof(*s)/2; i++) {
if ((rc = add_switch(model, y, x, s[i*2],
s[i*2+1], /*bidir*/ 0))) FAIL(rc);
}}
for (i = BI_FIRST; i <= BI_LAST; i++) {
fdev_bram_inbit(BW+i, &tile0_to_3, &wire_num);
if (tile0_to_3 == -1) { HERE(); continue; }
if ((rc = add_switch(model, y, x,
pf("BRAM_LOGICINB%i_INT%i", wire_num, tile0_to_3),
fpga_wire2str(BW+i),
/*bidir*/ 0))) FAIL(rc);
if (fdev_is_bram8_inwire(i)) {
fdev_bram_inbit(BW+(B8_0|i), &tile0_to_3, &wire_num);
if (tile0_to_3 == -1) { HERE(); continue; }
if ((rc = add_switch(model, y, x,
pf("BRAM_LOGICINB%i_INT%i", wire_num, tile0_to_3),
fpga_wire2str(BW+(B8_0|i)),
/*bidir*/ 0))) FAIL(rc);
fdev_bram_inbit(BW+(B8_1|i), &tile0_to_3, &wire_num);
if (tile0_to_3 == -1) { HERE(); continue; }
if ((rc = add_switch(model, y, x,
pf("BRAM_LOGICINB%i_INT%i", wire_num, tile0_to_3),
fpga_wire2str(BW+(B8_1|i)),
/*bidir*/ 0))) FAIL(rc);
}
}
for (i = BO_FIRST; i <= BO_LAST; i++) {
fdev_bram_outbit(BW+i, &tile0_to_3, &wire_num);
if (tile0_to_3 == -1) { HERE(); continue; }
if ((rc = add_switch(model, y, x,
fpga_wire2str(BW+i),
pf("BRAM_LOGICOUT%i_INT%i", wire_num, tile0_to_3),
/*bidir*/ 0))) FAIL(rc);
if (fdev_is_bram8_outwire(i)) {
fdev_bram_outbit(BW+(B8_0|i), &tile0_to_3, &wire_num);
if (tile0_to_3 == -1) { HERE(); continue; }
if ((rc = add_switch(model, y, x,
fpga_wire2str(BW+(B8_0|i)),
pf("BRAM_LOGICOUT%i_INT%i", wire_num, tile0_to_3),
/*bidir*/ 0))) FAIL(rc);
fdev_bram_outbit(BW+(B8_1|i), &tile0_to_3, &wire_num);
if (tile0_to_3 == -1) { HERE(); continue; }
if ((rc = add_switch(model, y, x,
fpga_wire2str(BW+(B8_1|i)),
pf("BRAM_LOGICOUT%i_INT%i", wire_num, tile0_to_3),
/*bidir*/ 0))) FAIL(rc);
}
}
}
}
return 0;
fail:
return rc;
}
static int init_macc_switches(struct fpga_model* model)
{
int i, x, y, tile0_to_3, wire_num, rc;
for (x = 0; x < model->x_width; x++) {
if (!is_atx(X_FABRIC_MACC_COL, model, x))
continue;
for (y = TOP_IO_TILES; y < model->y_height - BOT_IO_TILES; y++) {
if (!has_device(model, y, x, DEV_MACC))
continue;
{ const char *s[] = {
"MACC_SR0_INT0", "RSTD_DSP48A1_SITE",
"MACC_SR0_INT1", "RSTP_DSP48A1_SITE",
"MACC_SR0_INT2", "RSTC_DSP48A1_SITE",
"MACC_SR0_INT3", "RSTA_DSP48A1_SITE",
"MACC_SR1_INT0", "RSTCARRYIN_DSP48A1_SITE",
"MACC_SR1_INT1", "RSTOPMODE_DSP48A1_SITE",
"MACC_SR1_INT2", "RSTM_DSP48A1_SITE",
"MACC_SR1_INT3", "RSTB_DSP48A1_SITE",
"MACC_CLK0_INT2", "CLK_DSP48A1_SITE" };
for (i = 0; i < sizeof(s)/sizeof(*s)/2; i++) {
if ((rc = add_switch(model, y, x, s[i*2],
s[i*2+1], /*bidir*/ 0))) FAIL(rc);
}}
for (i = MI_FIRST; i <= MI_LAST; i++) {
fdev_macc_inbit(MW+i, &tile0_to_3, &wire_num);
if (tile0_to_3 == -1) { HERE(); continue; }
if ((rc = add_switch(model, y, x,
pf("MACC_LOGICINB%i_INT%i", wire_num, tile0_to_3),
fpga_wire2str(MW+i),
/*bidir*/ 0))) FAIL(rc);
}
for (i = MO_FIRST; i <= MO_LAST; i++) {
fdev_macc_outbit(MW+i, &tile0_to_3, &wire_num);
if (tile0_to_3 == -1) { HERE(); continue; }
if ((rc = add_switch(model, y, x,
fpga_wire2str(MW+i),
pf("MACC_LOGICOUT%i_INT%i", wire_num, tile0_to_3),
/*bidir*/ 0))) FAIL(rc);
}
}
}
return 0;
fail:
return rc;
}