/usr/include/control.h is in libfpga-dev 0.0+201212-1build1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 | //
// Author: Wolfgang Spraul
//
// This is free and unencumbered software released into the public domain.
// For details see the UNLICENSE file at the root of the source tree.
//
typedef int net_idx_t; // net indices are 1-based
#define NO_NET 0
const char* fpga_enum_iob(struct fpga_model* model, int enum_idx,
int* y, int* x, dev_type_idx_t* type_idx);
int fpga_find_iob(struct fpga_model* model, const char* sitename,
int* y, int* x, dev_type_idx_t* idx);
const char* fpga_iob_sitename(struct fpga_model* model, int y, int x,
dev_type_idx_t idx);
//
// When dealing with devices, there are two indices:
// 1. The index of the device in the device array for that tile.
// 2. The index of the device within devices of the same type in the tile.
//
// If index is past the last device of that type,
// y is returned as -1.
int fdev_enum(struct fpga_model* model, enum fpgadev_type type, int enum_i,
int *y, int *x, int *type_idx);
const char* fdev_type2str(enum fpgadev_type type);
enum fpgadev_type fdev_str2type(const char* str, int len);
// returns 0 if device not found
struct fpga_device* fdev_p(struct fpga_model* model,
int y, int x, enum fpgadev_type type, dev_type_idx_t type_idx);
// Looks up a device index based on the type index.
// returns NO_DEV (-1) if not found
dev_idx_t fpga_dev_idx(struct fpga_model* model,
int y, int x, enum fpgadev_type type, dev_type_idx_t type_idx);
// Counts how many devices of the same type as dev_idx are in
// the array up to dev_idx.
dev_type_idx_t fdev_typeidx(struct fpga_model* model, int y, int x,
dev_idx_t dev_idx);
#define PINW_NO_IDX -1
pinw_idx_t fdev_pinw_str2idx(int devtype, const char* str, int len);
// returns 0 when idx not found for the given devtype
const char* fdev_pinw_idx2str(int devtype, pinw_idx_t idx);
// ld1_type can be LOGIC_M or LOGIC_L to specify whether
// we are in a XM or XL column. You can |LD1 to idx for
// the second logic device (L or M).
const char* fdev_logic_pinstr(pinw_idx_t idx, int ld1_type);
str16_t fdev_logic_pinstr_i(struct fpga_model* model, pinw_idx_t idx, int ld1_type);
int fdev_logic_setconf(struct fpga_model* model, int y, int x,
int type_idx, const struct fpgadev_logic* logic_cfg);
// lut_a2d is LUT_A to LUT_D
int fdev_logic_a2d_out_used(struct fpga_model* model, int y, int x,
int type_idx, int lut_a2d, int used);
// lut_5or6 is int 5 or int 6
int fdev_logic_a2d_lut(struct fpga_model* model, int y, int x, int type_idx,
int lut_a2d, int lut_5or6, const char* lut_str, int lut_len);
// srinit is FF_SRINIT0 or FF_SRINIT1
int fdev_logic_a2d_ff(struct fpga_model* model, int y, int x, int type_idx,
int lut_a2d, int ff_mux, int srinit);
int fdev_logic_a2d_ff5_srinit(struct fpga_model* model, int y, int x,
int type_idx, int lut_a2d, int srinit);
int fdev_logic_a2d_out_mux(struct fpga_model* model, int y, int x,
int type_idx, int lut_a2d, int out_mux);
// cy0 is CY0_X or CY0_O5
int fdev_logic_a2d_cy0(struct fpga_model* model, int y, int x,
int type_idx, int lut_a2d, int cy0);
// clk is CLKINV_B or CLKINV_CLK
int fdev_logic_clk(struct fpga_model* model, int y, int x, int type_idx,
int clk);
// sync is SYNCATTR_SYNC or SYNCATTR_ASYNC
int fdev_logic_sync(struct fpga_model* model, int y, int x, int type_idx,
int sync_attr);
int fdev_logic_ce_used(struct fpga_model* model, int y, int x, int type_idx);
int fdev_logic_sr_used(struct fpga_model* model, int y, int x, int type_idx);
// we_mux can be WEMUX_WE or WEMUX_CE
int fdev_logic_we_mux(struct fpga_model* model, int y, int x,
int type_idx, int we_mux);
int fdev_logic_cout_used(struct fpga_model* model, int y, int x,
int type_idx, int used);
// precyinit can be PRECYINIT_O, PRECYINIT_1 or PRECYINIT_AX
int fdev_logic_precyinit(struct fpga_model* model, int y, int x,
int type_idx, int precyinit);
int fdev_iob_input(struct fpga_model* model, int y, int x,
int type_idx, const char* io_std);
int fdev_iob_output(struct fpga_model* model, int y, int x,
int type_idx, const char* io_std);
int fdev_iob_IMUX(struct fpga_model* model, int y, int x,
int type_idx, int mux);
int fdev_iob_slew(struct fpga_model* model, int y, int x,
int type_idx, int slew);
int fdev_iob_drive(struct fpga_model* model, int y, int x,
int type_idx, int drive_strength);
int fdev_bufgmux(struct fpga_model* model, int y, int x,
int type_idx, int clk, int disable_attr, int s_inv);
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);
// Returns the connpt index or NO_CONN if the name was not
// found. connpt_dests_o and num_dests are optional and may
// return the offset into the connpt's destination array
// and number of elements there.
int fpga_connpt_find(struct fpga_model* model, int y, int x,
str16_t name_i, int* connpt_dests_o, int* num_dests);
void fpga_conn_dest(struct fpga_model* model, int y, int x,
int connpt_dest_idx, int* dest_y, int* dest_x, str16_t* str_i);
// Searches a connection in search_y/search_x that connects to
// target_y/target_x/target_pt.
int fpga_find_conn(struct fpga_model* model, int search_y, int search_x,
str16_t* pt, int target_y, int target_x, str16_t target_pt);
//
// switches
//
typedef int swidx_t; // swidx_t is an index into the uint32_t switches array
// SW_SET_SIZE should be enough for:
// *) largest number of switches that can go from or to one
// specific connection point (ca. 32)
// *) largest depth inside a switchbox (ca. 20)
// *) some wires that go 'everywhere' like GFAN (70)
#define SW_SET_SIZE 128
struct sw_set
{
swidx_t sw[SW_SET_SIZE];
int len;
};
// returns a switch index, or -1 (NO_SWITCH) if no switch was found
swidx_t fpga_switch_first(struct fpga_model* model, int y, int x,
str16_t name_i, int from_to);
swidx_t fpga_switch_next(struct fpga_model* model, int y, int x,
swidx_t last, int from_to);
swidx_t fpga_switch_backtofirst(struct fpga_model* model, int y, int x,
swidx_t last, int from_to);
int fpga_swset_fromto(struct fpga_model* model, int y, int x,
str16_t start_switch, int from_to, struct sw_set* set);
// returns -1 if not found, otherwise index into the set
int fpga_swset_contains(struct fpga_model* model, int y, int x,
const struct sw_set* set, int from_to, str16_t connpt);
void fpga_swset_remove_connpt(struct fpga_model* model, int y, int x,
struct sw_set* set, int from_to, str16_t connpt);
// removes all switches from set whose !from_to is equal to the
// from_to in parents
void fpga_swset_remove_loop(struct fpga_model* model, int y, int x,
struct sw_set* set, const struct sw_set* parents, int from_to);
void fpga_swset_remove_sw(struct fpga_model* model, int y, int x,
struct sw_set* set, swidx_t sw);
int fpga_swset_level_down(struct fpga_model* model, int y, int x,
struct sw_set* set, int from_to);
void fpga_swset_print(struct fpga_model* model, int y, int x,
struct sw_set* set, int from_to);
int fpga_swset_is_used(struct fpga_model* model, int y, int x,
swidx_t* sw, int len);
// When calling, same_len must contain the size of the
// same_sw array. Upon return same_len returns how many
// switches were found and written to same_sw.
int fpga_switch_same_fromto(struct fpga_model* model, int y, int x,
swidx_t sw, int from_to, swidx_t* same_sw, int *same_len);
// fpga_switch_lookup() returns NO_SWITCH if switch not found.
swidx_t fpga_switch_lookup(struct fpga_model* model, int y, int x,
str16_t from_str_i, str16_t to_str_i);
const char* fpga_switch_str(struct fpga_model* model, int y, int x,
swidx_t swidx, int from_to);
str16_t fpga_switch_str_i(struct fpga_model* model, int y, int x,
swidx_t swidx, int from_to);
const char* fpga_switch_print(struct fpga_model* model, int y, int x,
swidx_t swidx);
int fpga_switch_is_bidir(struct fpga_model* model, int y, int x,
swidx_t swidx);
int fpga_switch_is_used(struct fpga_model* model, int y, int x,
swidx_t swidx);
void fpga_switch_enable(struct fpga_model* model, int y, int x,
swidx_t swidx);
int fpga_switch_set_enable(struct fpga_model* model, int y, int x,
struct sw_set* set);
void fpga_switch_disable(struct fpga_model* model, int y, int x,
swidx_t swidx);
const char* fmt_swset(struct fpga_model* model, int y, int x,
struct sw_set* set, int from_to);
// MAX_SWITCHBOX_SIZE can be used to allocate the block
// list and should be larger than the largest known number
// of switches in a tile, currently 3459 in a slx9 routing tile.
#define MAX_SWITCHBOX_SIZE 4000
struct sw_chain
{
// start and recurring values:
struct fpga_model* model;
int y;
int x;
int from_to;
int max_depth;
// exclusive_net will skip switches that are in use by any
// net other than exclusive_net.
// Set to NO_NET to accept any switch.
net_idx_t exclusive_net;
//
// block_list works as if all switches from or to the ones
// on the block list are blocked, that is the recursion will
// never step into a part of the tree that goes through a
// blocked from or to point.
// Every call to fpga_switch_chain(), even the last one that
// returns NO_SWITCH, may add switches to the block list.
//
swidx_t* block_list;
int block_list_len;
// return value: set is carried forward through the
// enumeration and must only be read from.
struct sw_set set;
// internal:
int first_round;
swidx_t* internal_block_list;
};
int construct_sw_chain(struct sw_chain* chain, struct fpga_model* model,
int y, int x, str16_t start_switch, int from_to, int max_depth,
net_idx_t exclusive_net, swidx_t* block_list, int block_list_len);
void destruct_sw_chain(struct sw_chain* chain);
// Returns 0 if another switchset is returned in chain, or
// NO_SWITCH (-1) if there is no other switchset.
// set.len is 0 when there are no more switches in the tree
int fpga_switch_chain(struct sw_chain* chain);
int fpga_multi_switch_lookup(struct fpga_model *model, int y, int x,
str16_t from_sw, str16_t to_sw, int max_depth, net_idx_t exclusive_net,
struct sw_set *sw_set);
struct sw_conns
{
struct sw_chain chain;
int connpt_dest_start;
int num_dests;
int dest_i;
int dest_y;
int dest_x;
str16_t dest_str_i;
};
int construct_sw_conns(struct sw_conns* conns, struct fpga_model* model,
int y, int x, str16_t start_switch, int from_to, int max_depth,
net_idx_t exclusive_net);
void destruct_sw_conns(struct sw_conns* conns);
// Returns 0 if another connection is returned in conns, or
// NO_CONN (-1) if there is no other connection.
int fpga_switch_conns(struct sw_conns* conns);
int fpga_first_conn(struct fpga_model *model, int sw_y, int sw_x, str16_t sw_str,
int from_to, int max_depth, net_idx_t exclusive_net,
struct sw_set *sw_set, int *dest_y, int *dest_x, str16_t *dest_connpt);
// max_depth can be -1 for internal maximum (SW_SET_SIZE)
void printf_swchain(struct fpga_model* model, int y, int x,
str16_t sw, int from_to, int max_depth, swidx_t* block_list,
int* block_list_len);
void printf_swconns(struct fpga_model* model, int y, int x,
str16_t sw, int from_to, int max_depth);
#define SWTO_YX_DEF 0
// SWTO_YX_CLOSEST finds the closest tile that satisfies
// the YX requirement.
#define SWTO_YX_CLOSEST 0x0001
struct switch_to_yx
{
// input:
int yx_req; // YX_-value
int flags; // SWTO_YX-value
struct fpga_model* model;
int y;
int x;
str16_t start_switch;
int from_to;
net_idx_t exclusive_net; // can be NO_NET
// output:
struct sw_set set;
int dest_y;
int dest_x;
str16_t dest_connpt;
};
int fpga_switch_to_yx(struct switch_to_yx *p);
void printf_switch_to_yx_result(struct switch_to_yx *p);
struct switch_to_yx_l2
{
struct switch_to_yx l1;
// l2 y/x/set is inserted between l1.y/x/start_switch
// and l1.dest_y/dest_x/dest_connpt
struct sw_set l2_set;
int l2_y, l2_x;
};
// fpga_switch_to_yx_l2() allows for an optional intermediate tile
// to come before the yx_req. If a direct link was found, l2_set.len
// will be 0 and l2_y and l2_x are undefined.
int fpga_switch_to_yx_l2(struct switch_to_yx_l2 *p);
#define SWTO_REL_DEFAULT 0
// If a connection to the actual target is not found,
// WEAK_TARGET will allow to return the connection that
// reaches as close as possible to the x/y target.
#define SWTO_REL_WEAK_TARGET 0x0001
struct switch_to_rel
{
// input:
struct fpga_model* model;
int start_y;
int start_x;
str16_t start_switch;
int from_to;
int flags; // SWTO_REL-value
int rel_y;
int rel_x;
str16_t target_connpt; // can be STRIDX_NO_ENTRY
// output:
struct sw_set set;
int dest_y;
int dest_x;
str16_t dest_connpt;
};
// if no switches are found, the returned set.len will be 0.
int fpga_switch_to_rel(struct switch_to_rel* p);
void printf_switch_to_rel_result(struct switch_to_rel* p);
//
// nets
//
// The last m1 soc has about 20k nets with about 470k
// connection points. The largest net has about 110
// connection points. For now we work with a simple
// fixed-size array, we can later make this more dynamic
// depending on which load on the memory manager is better.
#define MAX_NET_LEN 128
#define NET_IDX_IS_PINW 0x8000
#define NET_IDX_MASK 0x7FFF
struct net_el
{
uint16_t y;
uint16_t x;
// idx is either an index into tile->switches[]
// if bit15 (NET_IDX_IS_PINW) is off, or an index
// into dev->pinw[] if bit15 is on.
uint16_t idx;
uint16_t dev_idx; // only used if idx&NET_IDX_IS_PINW
};
struct fpga_net
{
int len;
struct net_el el[MAX_NET_LEN];
};
int fnet_new(struct fpga_model* model, net_idx_t* new_idx);
void fnet_delete(struct fpga_model* model, net_idx_t net_idx);
// start a new enumeration by calling with last==NO_NET
int fnet_enum(struct fpga_model* model, net_idx_t last, net_idx_t* next);
struct fpga_net* fnet_get(struct fpga_model* model, net_idx_t net_i);
void fnet_free_all(struct fpga_model* model);
int fpga_swset_in_other_net(struct fpga_model *model, int y, int x,
const swidx_t* sw, int len, net_idx_t our_net);
int fnet_add_port(struct fpga_model* model, net_idx_t net_i,
int y, int x, enum fpgadev_type type, dev_type_idx_t type_idx,
pinw_idx_t pinw_idx);
int fnet_add_sw(struct fpga_model* model, net_idx_t net_i,
int y, int x, const swidx_t* switches, int num_sw);
int fnet_remove_sw(struct fpga_model* model, net_idx_t net_i,
int y, int x, const swidx_t* switches, int num_sw);
int fnet_remove_all_sw(struct fpga_model* model, net_idx_t net_i);
void fnet_printf(FILE* f, struct fpga_model* model, net_idx_t net_i);
int fnet_route(struct fpga_model* model, net_idx_t net_i);
// is_vcc == 1 for a vcc net, is_vcc == 0 for a gnd net
int fnet_vcc_gnd(struct fpga_model* model, net_idx_t net_i, int is_vcc);
|