This commit is contained in:
Wolfgang Spraul 2012-08-13 05:16:36 +02:00
parent 273679d34f
commit 86f8d22d84
3 changed files with 409 additions and 150 deletions

39
model.h
View File

@ -222,23 +222,26 @@ int is_aty(int check, struct fpga_model* model, int y);
#define X_FABRIC_ROUTING_COL 0x00000400 // logic+BRAM+MACC
#define X_FABRIC_LOGIC_ROUTING_COL 0x00000800 // logic only
#define X_FABRIC_LOGIC_COL 0x00001000
#define X_FABRIC_BRAM_ROUTING_COL 0x00002000 // BRAM only
#define X_FABRIC_MACC_ROUTING_COL 0x00004000 // MACC only
#define X_FABRIC_BRAM_VIA_COL 0x00008000 // second routing col for BRAM
#define X_FABRIC_MACC_VIA_COL 0x00010000 // second routing col for MACC
#define X_FABRIC_BRAM_COL 0x00020000
#define X_FABRIC_MACC_COL 0x00040000
#define X_CENTER_ROUTING_COL 0x00080000
#define X_CENTER_LOGIC_COL 0x00100000
#define X_CENTER_CMTPLL_COL 0x00200000
#define X_CENTER_REGS_COL 0x00400000
#define X_LEFT_IO_ROUTING_COL 0x00800000
#define X_LEFT_IO_DEVS_COL 0x01000000
#define X_RIGHT_IO_ROUTING_COL 0x02000000
#define X_RIGHT_IO_DEVS_COL 0x04000000
#define X_LEFT_SIDE 0x08000000 // true for anything left of the center (not including center)
#define X_LEFT_MCB 0x10000000
#define X_RIGHT_MCB 0x20000000
// X_FABRIC_LOGIC_IO_COL is like X_FABRIC_LOGIC_COL but
// excluding those that have the no-io flag set.
#define X_FABRIC_LOGIC_IO_COL 0x00002000
#define X_FABRIC_BRAM_ROUTING_COL 0x00004000 // BRAM only
#define X_FABRIC_MACC_ROUTING_COL 0x00008000 // MACC only
#define X_FABRIC_BRAM_VIA_COL 0x00010000 // second routing col for BRAM
#define X_FABRIC_MACC_VIA_COL 0x00020000 // second routing col for MACC
#define X_FABRIC_BRAM_COL 0x00040000
#define X_FABRIC_MACC_COL 0x00080000
#define X_CENTER_ROUTING_COL 0x00100000
#define X_CENTER_LOGIC_COL 0x00200000
#define X_CENTER_CMTPLL_COL 0x00400000
#define X_CENTER_REGS_COL 0x00800000
#define X_LEFT_IO_ROUTING_COL 0x01000000
#define X_LEFT_IO_DEVS_COL 0x02000000
#define X_RIGHT_IO_ROUTING_COL 0x04000000
#define X_RIGHT_IO_DEVS_COL 0x08000000
#define X_LEFT_SIDE 0x10000000 // true for anything left of the center (not including center)
#define X_LEFT_MCB 0x20000000
#define X_RIGHT_MCB 0x40000000
#define IS_TOP_ROW(row, model) ((row) == (model)->cfg_rows-1)
#define IS_BOTTOM_ROW(row, model) ((row) == 0)
@ -425,6 +428,8 @@ int add_conn_net(struct fpga_model* model, add_conn_f add_conn_func, struct w_ne
int add_switch(struct fpga_model* model, int y, int x, const char* from,
const char* to, int is_bidirectional);
int add_switch_set(struct fpga_model* model, int y, int x, const char* prefix,
const char** pairs, int suffix_inc);
struct seed_data
{

View File

@ -404,6 +404,36 @@ xout:
return rc;
}
int add_switch_set(struct fpga_model* model, int y, int x, const char* prefix,
const char** pairs, int suffix_inc)
{
int i, j, from_len, to_len, rc;
char from[64], to[64];
for (i = 0; pairs[i*2][0]; i++) {
snprintf(from, sizeof(from), "%s%s", prefix, pairs[i*2]);
snprintf(to, sizeof(to), "%s%s", prefix, pairs[i*2+1]);
if (!suffix_inc) {
rc = add_switch(model, y, x, from, to,
0 /* bidir */);
if (rc) goto xout;
} else {
from_len = strlen(from);
to_len = strlen(to);
for (j = 0; j <= suffix_inc; j++) {
snprintf(&from[from_len], sizeof(from)-from_len, "%i", j);
snprintf(&to[to_len], sizeof(to)-to_len, "%i", j);
rc = add_switch(model, y, x, from, to,
0 /* bidir */);
if (rc) goto xout;
}
}
}
return 0;
xout:
return rc;
}
void seed_strx(struct fpga_model* model, struct seed_data* data)
{
int x, i;
@ -482,6 +512,7 @@ int is_atx(int check, struct fpga_model* model, int x)
&& model->tiles[x].flags & TF_FABRIC_ROUTING_COL
&& model->tiles[x+1].flags & TF_FABRIC_LOGIC_COL) return 1;
if (check & X_FABRIC_LOGIC_COL && model->tiles[x].flags & TF_FABRIC_LOGIC_COL) return 1;
if (check & X_FABRIC_LOGIC_IO_COL && model->tiles[x].flags & TF_FABRIC_LOGIC_COL && !(model->tiles[x-1].flags & TF_ROUTING_NO_IO)) return 1;
if (check & X_FABRIC_BRAM_ROUTING_COL
&& model->tiles[x].flags & TF_FABRIC_ROUTING_COL
&& model->tiles[x+1].flags & TF_FABRIC_BRAM_VIA_COL

View File

@ -8,6 +8,344 @@
#include <stdarg.h>
#include "model.h"
static int init_ce_clk_switches(struct fpga_model* model);
static int init_io_switches(struct fpga_model* model);
static int init_routing_switches(struct fpga_model* model);
static int init_north_south_dirwire_term(struct fpga_model* model);
int init_switches(struct fpga_model* model)
{
int rc;
// todo: IO_TERM_B, IO_OUTER_B, IO_INNER_B, LOGIC_XM
rc = init_north_south_dirwire_term(model);
if (rc) goto xout;
return 0;
rc = init_ce_clk_switches(model);
if (rc) goto xout;
rc = init_io_switches(model);
if (rc) goto xout;
rc = init_routing_switches(model);
if (rc) goto xout;
return 0;
xout:
return rc;
}
static int init_north_south_dirwire_term(struct fpga_model* model)
{
static const int logicin_pairs[] = {21,20, 28,36, 52,44, 60,62};
int x, i, rc;
for (x = 0; x < model->x_width; x++) {
if (!is_atx(X_ROUTING_COL, model, x))
continue;
// top
for (i = 0; i < 4; i++) {
rc = add_switch(model,
TOP_INNER_ROW, x,
pf("IOI_TTERM_LOGICIN%i", logicin_pairs[i*2]),
pf("IOI_TTERM_LOGICIN_S%i", logicin_pairs[i*2+1]),
0 /* bidir */);
if (rc) goto xout;
}
{ const char* s0_switches[] = {
"ER1E3", "EL1E_S0",
"SR1E_N3", "NL1E_S0",
"SS2E_N3", "NN2E_S0",
"SS4E3", "NW4E_S0",
"SW2E3", "NE2E_S0",
"SW4E3", "WW4E_S0",
"WL1E3", "WR1E_S0",
"WW2E3", "NW2E_S0", "" };
if ((rc = add_switch_set(model, TOP_INNER_ROW, x,
"IOI_TTERM_", s0_switches, /*inc*/ 0))) goto xout; }
{ const char* dir[] = {
"NN4B", "SS4A", "NN4A", "SS4M", "NN4M", "SS4C", "NN4C", "SS4E",
"NN2B", "SS2M", "NN2M", "SS2E",
"NE4B", "SE4A", "NE4A", "SE4M",
"NE2B", "SE2M",
"NW4B", "SW4A", "NW4A", "SW4M", "NW2B", "SW2M",
"NL1B", "SL1E",
"NR1B", "SR1E", "" };
if ((rc = add_switch_set(model, TOP_INNER_ROW, x,
"IOI_TTERM_", dir, /*inc*/ 3))) goto xout; }
// bottom
if (is_atx(X_ROUTING_TO_BRAM_COL, model, x))
continue;
for (i = 0; i < 4; i++) {
rc = add_switch(model,
model->y_height-BOT_INNER_ROW, x,
pf("IOI_BTERM_LOGICIN%i", logicin_pairs[i*2+1]),
pf("IOI_BTERM_LOGICIN_N%i", logicin_pairs[i*2]),
0 /* bidir */);
if (rc) goto xout;
}
{ const char* n3_switches[] = {
"EL1E0", "ER1E_N3",
"NE2E0", "SW2E_N3",
"NL1E_S0", "SR1E_N3",
"NN2E_S0", "SS2E_N3",
"NW2E0", "WW2E_N3",
"NW4E0", "SS4E_N3",
"WR1E0", "WL1E_N3",
"WW4E0", "SW4E_N3", "" };
if ((rc = add_switch_set(model, model->y_height-BOT_INNER_ROW,
x, "IOI_BTERM_", n3_switches, /*inc*/ 0))) goto xout; }
{ const char* dir[] = {
"SS4B", "NN4A", "SS4A", "NN4M", "SS4M", "NN4C", "SS4C", "NN4E",
"SS2B", "NN2M", "SS2M", "NN2E",
"SE4B", "NE4A", "SE4A", "NE4M",
"SE2B", "NE2M",
"SW4B", "NW4A", "SW4A", "NW4M", "SW2B", "NW2M",
"NL1E", "SL1B",
"SR1B", "NR1E", "" };
if ((rc = add_switch_set(model, model->y_height-BOT_INNER_ROW,
x, "IOI_BTERM_", dir, /*inc*/ 3))) goto xout; }
}
return 0;
xout:
return rc;
}
static int init_ce_clk_switches(struct fpga_model* model)
{
int x, y, i, rc;
// There are CE and CLK wires for IO and PLL that are going
// horizontally through the HCLK and vertically through the logic
// dev columns (except no-io).
// The following sets up their corresponding switches in the term
// tiles.
for (y = TOP_IO_TILES; y < model->y_height - BOT_IO_TILES; y++) {
if (is_aty(Y_ROW_HORIZ_AXSYMM, model, y)) {
// left
for (i = 0; i <= 3; i++) {
rc = add_switch(model, y, LEFT_INNER_COL,
pf("HCLK_IOI_LTERM_IOCE%i", i),
pf("HCLK_IOI_LTERM_IOCE%i_E", i),
0 /* bidir */);
if (rc) goto xout;
rc = add_switch(model, y, LEFT_INNER_COL,
pf("HCLK_IOI_LTERM_IOCLK%i", i),
pf("HCLK_IOI_LTERM_IOCLK%i_E", i),
0 /* bidir */);
if (rc) goto xout;
}
for (i = 0; i <= 1; i++) {
rc = add_switch(model, y, LEFT_INNER_COL,
pf("HCLK_IOI_LTERM_PLLCE%i", i),
pf("HCLK_IOI_LTERM_PLLCE%i_E", i),
0 /* bidir */);
if (rc) goto xout;
rc = add_switch(model, y, LEFT_INNER_COL,
pf("HCLK_IOI_LTERM_PLLCLK%i", i),
pf("HCLK_IOI_LTERM_PLLCLK%i_E", i),
0 /* bidir */);
if (rc) goto xout;
}
// right
for (i = 0; i <= 3; i++) {
rc = add_switch(model, y, model->x_width-RIGHT_INNER_O,
pf("HCLK_IOI_RTERM_IOCE%i", i),
pf("HCLK_IOI_RTERM_IOCE%i_W", 3-i),
0 /* bidir */);
if (rc) goto xout;
rc = add_switch(model, y, model->x_width-RIGHT_INNER_O,
pf("HCLK_IOI_RTERM_IOCLK%i", i),
pf("HCLK_IOI_RTERM_IOCLK%i_W", 3-i),
0 /* bidir */);
if (rc) goto xout;
}
for (i = 0; i <= 1; i++) {
rc = add_switch(model, y, model->x_width-RIGHT_INNER_O,
pf("HCLK_IOI_RTERM_PLLCEOUT%i", i),
pf("HCLK_IOI_RTERM_PLLCEOUT%i_W", i),
0 /* bidir */);
if (rc) goto xout;
rc = add_switch(model, y, model->x_width-RIGHT_INNER_O,
pf("HCLK_IOI_RTERM_PLLCLKOUT%i", i),
pf("HCLK_IOI_RTERM_PLLCLKOUT%i_W", i),
0 /* bidir */);
if (rc) goto xout;
}
}
}
for (x = LEFT_SIDE_WIDTH; x < model->x_width - RIGHT_SIDE_WIDTH; x++) {
if ((is_atx(X_FABRIC_LOGIC_IO_COL|X_CENTER_LOGIC_COL, model, x))) {
// top
for (i = 0; i <= 3; i++) {
rc = add_switch(model, TOP_INNER_ROW, x,
pf("TTERM_CLB_IOCE%i", i),
pf("TTERM_CLB_IOCE%i_S", i),
0 /* bidir */);
if (rc) goto xout;
rc = add_switch(model, TOP_INNER_ROW, x,
pf("TTERM_CLB_IOCLK%i", i),
pf("TTERM_CLB_IOCLK%i_S", i),
0 /* bidir */);
if (rc) goto xout;
}
for (i = 0; i <= 1; i++) {
rc = add_switch(model, TOP_INNER_ROW, x,
pf("TTERM_CLB_PLLCE%i", i),
pf("TTERM_CLB_PLLCE%i_S", i),
0 /* bidir */);
if (rc) goto xout;
rc = add_switch(model, TOP_INNER_ROW, x,
pf("TTERM_CLB_PLLCLK%i", i),
pf("TTERM_CLB_PLLCLK%i_S", i),
0 /* bidir */);
if (rc) goto xout;
}
rc = add_switch(model, TOP_INNER_ROW, x,
"TTERM_CLB_PCICE",
"TTERM_CLB_PCICE_S",
0 /* bidir */);
// bottom
if (rc) goto xout;
for (i = 0; i <= 3; i++) {
rc = add_switch(model, model->y_height - BOT_INNER_ROW, x,
pf("BTERM_CLB_CEOUT%i", i),
pf("BTERM_CLB_CEOUT%i_N", i),
0 /* bidir */);
if (rc) goto xout;
rc = add_switch(model, model->y_height - BOT_INNER_ROW, x,
pf("BTERM_CLB_CLKOUT%i", i),
pf("BTERM_CLB_CLKOUT%i_N", i),
0 /* bidir */);
if (rc) goto xout;
}
for (i = 0; i <= 1; i++) {
rc = add_switch(model, model->y_height - BOT_INNER_ROW, x,
pf("BTERM_CLB_PLLCEOUT%i", i),
pf("BTERM_CLB_PLLCEOUT%i_N", i),
0 /* bidir */);
if (rc) goto xout;
rc = add_switch(model, model->y_height - BOT_INNER_ROW, x,
pf("BTERM_CLB_PLLCLKOUT%i", i),
pf("BTERM_CLB_PLLCLKOUT%i_N", i),
0 /* bidir */);
if (rc) goto xout;
}
rc = add_switch(model, model->y_height - BOT_INNER_ROW, x,
"BTERM_CLB_PCICE",
"BTERM_CLB_PCICE_N",
0 /* bidir */);
if (rc) goto xout;
}
}
return 0;
xout:
return rc;
}
static int init_io_tile(struct fpga_model* model, int y, int x)
{
const char* prefix;
int i, num_devs, rc;
if (!y) {
prefix = "TIOB";
rc = add_switch(model, y, x,
pf("%s_DIFFO_OUT2", prefix),
pf("%s_DIFFO_IN3", prefix), 0 /* bidir */);
if (rc) goto xout;
num_devs = 2;
} else if (y == model->y_height - BOT_OUTER_ROW) {
prefix = "BIOB";
rc = add_switch(model, y, x,
pf("%s_DIFFO_OUT3", prefix),
pf("%s_DIFFO_IN2", prefix), 0 /* bidir */);
if (rc) goto xout;
num_devs = 2;
} else if (!x) {
prefix = "LIOB";
num_devs = 1;
} else if (x == model->x_width - RIGHT_OUTER_O) {
prefix = "RIOB";
num_devs = 1;
} else
ABORT(1);
for (i = 0; i < num_devs*2; i++) {
rc = add_switch(model, y, x,
pf("%s_IBUF%i_PINW", prefix, i),
pf("%s_IBUF%i", prefix, i), 0 /* bidir */);
if (rc) goto xout;
rc = add_switch(model, y, x,
pf("%s_O%i", prefix, i),
pf("%s_O%i_PINW", prefix, i), 0 /* bidir */);
if (rc) goto xout;
rc = add_switch(model, y, x,
pf("%s_T%i", prefix, i),
pf("%s_T%i_PINW", prefix, i), 0 /* bidir */);
if (rc) goto xout;
}
rc = add_switch(model, y, x,
pf("%s_DIFFO_OUT0", prefix),
pf("%s_DIFFO_IN1", prefix), 0 /* bidir */);
if (rc) goto xout;
for (i = 0; i <= 1; i++) {
rc = add_switch(model, y, x,
pf("%s_PADOUT%i", prefix, i),
pf("%s_DIFFI_IN%i", prefix, 1-i),
0 /* bidir */);
if (rc) goto xout;
}
if (num_devs > 1) {
for (i = 0; i <= 1; i++) {
rc = add_switch(model, y, x,
pf("%s_PADOUT%i", prefix, i+2),
pf("%s_DIFFI_IN%i", prefix, 3-i),
0 /* bidir */);
if (rc) goto xout;
}
}
return 0;
xout:
return rc;
}
static int init_io_switches(struct fpga_model* model)
{
int x, y, rc;
for (x = 0; x < model->x_width; x++) {
if (has_device(model, /*y*/ 0, x, DEV_IOBM)) {
rc = init_io_tile(model, 0, x);
if (rc) goto xout;
}
if (has_device(model, model->y_height - BOT_OUTER_ROW, x,
DEV_IOBM)) {
rc = init_io_tile(model,
model->y_height-BOT_OUTER_ROW, x);
if (rc) goto xout;
}
}
for (y = 0; y < model->y_height; y++) {
if (has_device(model, y, /*x*/ 0, DEV_IOBM)) {
rc = init_io_tile(model, y, 0);
if (rc) goto xout;
}
if (has_device(model, y, model->x_width - RIGHT_OUTER_O,
DEV_IOBM)) {
rc = init_io_tile(model,
y, model->x_width - RIGHT_OUTER_O);
if (rc) goto xout;
}
}
return 0;
xout:
return rc;
}
// The wires are ordered clockwise. Order is important for
// wire_to_NESW4().
enum wire_type
@ -46,6 +384,23 @@ enum wire_type
LAST_LEN4 = W_NW4
};
#define W_CLOCKWISE(w) rotate_wire((w), 1)
#define W_CLOCKWISE_2(w) rotate_wire((w), 2)
#define W_COUNTER_CLOCKWISE(w) rotate_wire((w), -1)
#define W_COUNTER_CLOCKWISE_2(w) rotate_wire((w), -2)
#define W_IS_LEN1(w) ((w) >= FIRST_LEN1 && (w) <= LAST_LEN1)
#define W_IS_LEN2(w) ((w) >= FIRST_LEN2 && (w) <= LAST_LEN2)
#define W_IS_LEN4(w) ((w) >= FIRST_LEN4 && (w) <= LAST_LEN4)
#define W_TO_LEN1(w) wire_to_len(w, FIRST_LEN1)
#define W_TO_LEN2(w) wire_to_len(w, FIRST_LEN2)
#define W_TO_LEN4(w) wire_to_len(w, FIRST_LEN4)
static const char* wire_base(enum wire_type w);
static enum wire_type rotate_wire(enum wire_type cur, int off);
static enum wire_type wire_to_len(enum wire_type w, int first_len);
static const char* wire_base(enum wire_type w)
{
switch (w) {
@ -79,20 +434,7 @@ static const char* wire_base(enum wire_type w)
ABORT(1);
}
#define W_CLOCKWISE(w) rotate_wire((w), 1)
#define W_CLOCKWISE_2(w) rotate_wire((w), 2)
#define W_COUNTER_CLOCKWISE(w) rotate_wire((w), -1)
#define W_COUNTER_CLOCKWISE_2(w) rotate_wire((w), -2)
#define W_IS_LEN1(w) ((w) >= FIRST_LEN1 && (w) <= LAST_LEN1)
#define W_IS_LEN2(w) ((w) >= FIRST_LEN2 && (w) <= LAST_LEN2)
#define W_IS_LEN4(w) ((w) >= FIRST_LEN4 && (w) <= LAST_LEN4)
#define W_TO_LEN1(w) wire_to_len(w, FIRST_LEN1)
#define W_TO_LEN2(w) wire_to_len(w, FIRST_LEN2)
#define W_TO_LEN4(w) wire_to_len(w, FIRST_LEN4)
int rotate_num(int cur, int off, int first, int last)
static int rotate_num(int cur, int off, int first, int last)
{
if (cur+off > last)
return first + (cur+off-last-1) % ((last+1)-first);
@ -801,125 +1143,6 @@ xout:
return rc;
}
static int init_io_switches(struct fpga_model* model);
static int init_routing_switches(struct fpga_model* model);
int init_switches(struct fpga_model* model)
{
int rc;
// todo: IO_B, IO_TERM_B, IO_LOGIC_TERM_B, IO_OUTER_B, IO_INNER_B, LOGIC_XM
rc = init_io_switches(model);
if (rc) goto xout;
return 0;
rc = init_routing_switches(model);
if (rc) goto xout;
return 0;
xout:
return rc;
}
static int init_io_tile(struct fpga_model* model, int y, int x)
{
const char* prefix;
int i, num_devs, rc;
if (!y) {
prefix = "TIOB";
rc = add_switch(model, y, x,
pf("%s_DIFFO_OUT2", prefix),
pf("%s_DIFFO_IN3", prefix), 0 /* bidir */);
if (rc) goto xout;
num_devs = 2;
} else if (y == model->y_height - BOT_OUTER_ROW) {
prefix = "BIOB";
rc = add_switch(model, y, x,
pf("%s_DIFFO_OUT3", prefix),
pf("%s_DIFFO_IN2", prefix), 0 /* bidir */);
if (rc) goto xout;
num_devs = 2;
} else if (!x) {
prefix = "LIOB";
num_devs = 1;
} else if (x == model->x_width - RIGHT_OUTER_O) {
prefix = "RIOB";
num_devs = 1;
} else
ABORT(1);
for (i = 0; i < num_devs*2; i++) {
rc = add_switch(model, y, x,
pf("%s_IBUF%i_PINW", prefix, i),
pf("%s_IBUF%i", prefix, i), 0 /* bidir */);
if (rc) goto xout;
rc = add_switch(model, y, x,
pf("%s_O%i", prefix, i),
pf("%s_O%i_PINW", prefix, i), 0 /* bidir */);
if (rc) goto xout;
rc = add_switch(model, y, x,
pf("%s_T%i", prefix, i),
pf("%s_T%i_PINW", prefix, i), 0 /* bidir */);
if (rc) goto xout;
}
rc = add_switch(model, y, x,
pf("%s_DIFFO_OUT0", prefix),
pf("%s_DIFFO_IN1", prefix), 0 /* bidir */);
if (rc) goto xout;
for (i = 0; i <= 1; i++) {
rc = add_switch(model, y, x,
pf("%s_PADOUT%i", prefix, i),
pf("%s_DIFFI_IN%i", prefix, 1-i),
0 /* bidir */);
if (rc) goto xout;
}
if (num_devs > 1) {
for (i = 0; i <= 1; i++) {
rc = add_switch(model, y, x,
pf("%s_PADOUT%i", prefix, i+2),
pf("%s_DIFFI_IN%i", prefix, 3-i),
0 /* bidir */);
if (rc) goto xout;
}
}
return 0;
xout:
return rc;
}
static int init_io_switches(struct fpga_model* model)
{
int x, y, i, rc;
for (x = 0; x < model->x_width; x++) {
if (has_device(model, /*y*/ 0, x, DEV_IOBM)) {
rc = init_io_tile(model, 0, x);
if (rc) goto xout;
}
if (has_device(model, model->y_height - BOT_OUTER_ROW, x,
DEV_IOBM)) {
rc = init_io_tile(model,
model->y_height-BOT_OUTER_ROW, x);
if (rc) goto xout;
}
}
for (y = 0; y < model->y_height; y++) {
if (has_device(model, y, /*x*/ 0, DEV_IOBM)) {
rc = init_io_tile(model, y, 0);
if (rc) goto xout;
}
if (has_device(model, y, model->x_width - RIGHT_OUTER_O,
DEV_IOBM)) {
rc = init_io_tile(model,
y, model->x_width - RIGHT_OUTER_O);
if (rc) goto xout;
}
}
return 0;
xout:
return rc;
}
static int init_routing_switches(struct fpga_model* model)
{
int x, y, i, j, routing_io, rc;