minor devidx cleanup, net preparation
This commit is contained in:
parent
0b28e6cf04
commit
1f3997b4bb
17
autotest.c
17
autotest.c
|
@ -107,7 +107,7 @@ int main(int argc, char** argv)
|
|||
{
|
||||
struct fpga_model model;
|
||||
struct fpga_device* P46_dev, *P48_dev, *logic_dev;
|
||||
int P46_y, P46_x, P46_idx, P48_y, P48_x, P48_idx, rc;
|
||||
int P46_y, P46_x, P46_idx, P48_y, P48_x, P48_idx, dev_idx, rc;
|
||||
struct test_state tstate;
|
||||
struct switch_to_yx switch_to;
|
||||
|
||||
|
@ -137,8 +137,9 @@ int main(int argc, char** argv)
|
|||
// configure P46
|
||||
rc = fpga_find_iob(&model, "P46", &P46_y, &P46_x, &P46_idx);
|
||||
if (rc) FAIL(rc);
|
||||
P46_dev = fpga_dev(&model, P46_y, P46_x, DEV_IOB, P46_idx);
|
||||
if (!P46_dev) FAIL(EINVAL);
|
||||
dev_idx = fpga_dev_idx(&model, P46_y, P46_x, DEV_IOB, P46_idx);
|
||||
if (dev_idx == NO_DEV) FAIL(EINVAL);
|
||||
P46_dev = FPGA_DEV(&model, P46_y, P46_x, dev_idx);
|
||||
P46_dev->instantiated = 1;
|
||||
strcpy(P46_dev->iob.istandard, IO_LVCMOS33);
|
||||
P46_dev->iob.bypass_mux = BYPASS_MUX_I;
|
||||
|
@ -147,8 +148,9 @@ int main(int argc, char** argv)
|
|||
// configure P48
|
||||
rc = fpga_find_iob(&model, "P48", &P48_y, &P48_x, &P48_idx);
|
||||
if (rc) FAIL(rc);
|
||||
P48_dev = fpga_dev(&model, P48_y, P48_x, DEV_IOB, P48_idx);
|
||||
if (!P48_dev) FAIL(EINVAL);
|
||||
dev_idx = fpga_dev_idx(&model, P48_y, P48_x, DEV_IOB, P48_idx);
|
||||
if (dev_idx == NO_DEV) FAIL(EINVAL);
|
||||
P48_dev = FPGA_DEV(&model, P48_y, P48_x, dev_idx);
|
||||
P48_dev->instantiated = 1;
|
||||
strcpy(P48_dev->iob.ostandard, IO_LVCMOS33);
|
||||
P48_dev->iob.drive_strength = 12;
|
||||
|
@ -157,8 +159,9 @@ int main(int argc, char** argv)
|
|||
P48_dev->iob.suspend = SUSP_3STATE;
|
||||
|
||||
// configure logic
|
||||
logic_dev = fpga_dev(&model, /*y*/ 68, /*x*/ 13, DEV_LOGIC, DEV_LOGX);
|
||||
if (!logic_dev) FAIL(EINVAL);
|
||||
dev_idx = fpga_dev_idx(&model, /*y*/ 68, /*x*/ 13, DEV_LOGIC, DEV_LOGX);
|
||||
if (dev_idx == NO_DEV) FAIL(EINVAL);
|
||||
logic_dev = FPGA_DEV(&model, /*y*/ 68, /*x*/ 13, dev_idx);
|
||||
logic_dev->instantiated = 1;
|
||||
logic_dev->logic.D_used = 1;
|
||||
rc = fpga_set_lut(&model, logic_dev, D6_LUT, "A3", ZTERM);
|
||||
|
|
12
bit_frames.c
12
bit_frames.c
|
@ -75,7 +75,7 @@ static struct bit_pos s_default_bits[] = {
|
|||
|
||||
int extract_model(struct fpga_model* model, struct fpga_bits* bits)
|
||||
{
|
||||
int i, num_iobs, iob_y, iob_x, iob_idx, row, row_pos, rc;
|
||||
int i, num_iobs, iob_y, iob_x, iob_idx, dev_idx, row, row_pos, rc;
|
||||
int x, y, byte_off;
|
||||
uint32_t* u32_p;
|
||||
uint8_t* u8_p;
|
||||
|
@ -102,8 +102,9 @@ int extract_model(struct fpga_model* model, struct fpga_bits* bits)
|
|||
}
|
||||
rc = fpga_find_iob(model, iob_sitename, &iob_y, &iob_x, &iob_idx);
|
||||
if (rc) FAIL(rc);
|
||||
dev = fpga_dev(model, iob_y, iob_x, DEV_IOB, iob_idx);
|
||||
if (!dev) FAIL(rc);
|
||||
dev_idx = fpga_dev_idx(model, iob_y, iob_x, DEV_IOB, iob_idx);
|
||||
if (dev_idx == NO_DEV) FAIL(EINVAL);
|
||||
dev = FPGA_DEV(model, iob_y, iob_x, dev_idx);
|
||||
|
||||
// we only support 2 hardcoded types of IOB right now
|
||||
// todo: bit 7 goes on when out-net connected?
|
||||
|
@ -173,8 +174,9 @@ int extract_model(struct fpga_model* model, struct fpga_bits* bits)
|
|||
clear_bit(bits, /*row*/ 0, /*major*/ 17,
|
||||
/*minor*/ 22, /*bit_i*/ 980);
|
||||
|
||||
dev = fpga_dev(model, y, x, DEV_LOGIC, DEV_LOGX);
|
||||
if (!dev) FAIL(EINVAL);
|
||||
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);
|
||||
dev->instantiated = 1;
|
||||
*(uint64_t*)(u8_p+26*FRAME_SIZE+byte_off) = 0;
|
||||
|
||||
|
|
53
control.c
53
control.c
|
@ -200,34 +200,35 @@ const char* fpga_iob_sitename(struct fpga_model* model, int y, int x,
|
|||
return 0;
|
||||
}
|
||||
|
||||
struct fpga_device* fpga_dev(struct fpga_model* model,
|
||||
int y, int x, enum fpgadev_type type, int type_idx)
|
||||
dev_idx_t fpga_dev_idx(struct fpga_model* model,
|
||||
int y, int x, enum fpgadev_type type, dev_type_idx_t type_idx)
|
||||
{
|
||||
struct fpga_tile* tile;
|
||||
int type_count, i;
|
||||
dev_type_idx_t type_count;
|
||||
dev_idx_t i;
|
||||
|
||||
tile = YX_TILE(model, y, x);
|
||||
type_count = 0;
|
||||
for (i = 0; i < tile->num_devs; i++) {
|
||||
if (tile->devs[i].type == type) {
|
||||
if (type_count == type_idx)
|
||||
return &tile->devs[i];
|
||||
return i;
|
||||
type_count++;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
return NO_DEV;
|
||||
}
|
||||
|
||||
int fpga_dev_typecount(struct fpga_model* model, int y, int x,
|
||||
enum fpgadev_type type, int dev_idx)
|
||||
dev_type_idx_t fpga_dev_typeidx(struct fpga_model* model, int y, int x,
|
||||
dev_idx_t dev_idx)
|
||||
{
|
||||
struct fpga_tile* tile;
|
||||
int type_count, i;
|
||||
dev_type_idx_t type_count, i;
|
||||
|
||||
tile = YX_TILE(model, y, x);
|
||||
type_count = 0;
|
||||
for (i = 0; i < dev_idx; i++) {
|
||||
if (tile->devs[i].type == type)
|
||||
if (tile->devs[i].type == tile->devs[dev_idx].type)
|
||||
type_count++;
|
||||
}
|
||||
return type_count;
|
||||
|
@ -749,3 +750,37 @@ int fpga_switch_to_yx(struct switch_to_yx* p)
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fpga_net_new(struct fpga_model* model, net_idx_t* new_idx)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int fpga_net_enum(struct fpga_model* model, net_idx_t last, net_idx_t* next)
|
||||
{
|
||||
*next = NO_NET;
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct fpga_net* fpga_net_get(struct fpga_model* model, net_idx_t net_i)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int fpga_net_add_switches(struct fpga_model* model, net_idx_t net_i,
|
||||
const struct sw_set* set)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
void fpga_net_free_all(struct fpga_model* model)
|
||||
{
|
||||
free(model->nets);
|
||||
model->nets = 0;
|
||||
}
|
||||
|
|
62
control.h
62
control.h
|
@ -17,14 +17,14 @@ const char* fpga_iob_sitename(struct fpga_model* model, int y, int x,
|
|||
// 2. The index of the device within devices of the same type in the tile.
|
||||
//
|
||||
|
||||
// Looks up a device pointer based on the type index.
|
||||
struct fpga_device* fpga_dev(struct fpga_model* model,
|
||||
int y, int x, enum fpgadev_type type, int type_idx);
|
||||
// Looks up a device index based on the type index.
|
||||
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 type 'type' are in the device
|
||||
// array up to devidx.
|
||||
int fpga_dev_typecount(struct fpga_model* model, int y, int x,
|
||||
enum fpgadev_type type, int dev_idx);
|
||||
// Counts how many devices of the same type as dev_idx are in
|
||||
// the array up to dev_idx.
|
||||
dev_type_idx_t fpga_dev_typeidx(struct fpga_model* model, int y, int x,
|
||||
dev_idx_t dev_idx);
|
||||
|
||||
enum { A6_LUT, B6_LUT, C6_LUT, D6_LUT };
|
||||
// lut_len can be -1 (ZTERM)
|
||||
|
@ -41,6 +41,10 @@ int fpga_connpt_find(struct fpga_model* model, int y, int x,
|
|||
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);
|
||||
|
||||
//
|
||||
// switches
|
||||
//
|
||||
|
||||
typedef int swidx_t; // swidx_t is an index into the uint32_t switches array
|
||||
#define MAX_SW_DEPTH 64 // largest seen so far was 20
|
||||
|
||||
|
@ -161,3 +165,47 @@ struct switch_to_yx
|
|||
};
|
||||
|
||||
int fpga_switch_to_yx(struct switch_to_yx* 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_SIZE 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 size;
|
||||
struct net_el el[MAX_NET_SIZE];
|
||||
};
|
||||
|
||||
typedef int net_idx_t;
|
||||
#define NO_NET 0
|
||||
|
||||
int fpga_net_new(struct fpga_model* model, net_idx_t* new_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_switches(struct fpga_model* model, net_idx_t net_i,
|
||||
const struct sw_set* set);
|
||||
void fpga_net_free_all(struct fpga_model* model);
|
||||
|
|
|
@ -772,7 +772,7 @@ static void read_dev_line(struct fpga_model* model, const char* line, int start)
|
|||
int coord_end, y_coord, x_coord;
|
||||
int type_beg, type_end, idx_beg, idx_end;
|
||||
enum fpgadev_type dev_type;
|
||||
int dev_idx, words_consumed;
|
||||
int dev_type_idx, dev_idx, words_consumed;
|
||||
struct fpga_device* dev_ptr;
|
||||
int next_beg, next_end, second_beg, second_end;
|
||||
|
||||
|
@ -788,12 +788,13 @@ static void read_dev_line(struct fpga_model* model, const char* line, int start)
|
|||
return;
|
||||
}
|
||||
dev_type = to_type(&line[type_beg], type_end-type_beg);
|
||||
dev_idx = to_i(&line[idx_beg], idx_end-idx_beg);
|
||||
dev_ptr = fpga_dev(model, y_coord, x_coord, dev_type, dev_idx);
|
||||
if (!dev_ptr) {
|
||||
dev_type_idx = to_i(&line[idx_beg], idx_end-idx_beg);
|
||||
dev_idx = fpga_dev_idx(model, y_coord, x_coord, dev_type, dev_type_idx);
|
||||
if (dev_idx == NO_DEV) {
|
||||
fprintf(stderr, "error %i: %s", __LINE__, line);
|
||||
return;
|
||||
}
|
||||
dev_ptr = FPGA_DEV(model, y_coord, x_coord, dev_idx);
|
||||
|
||||
next_end = idx_end;
|
||||
while (next_word(line, next_end, &next_beg, &next_end),
|
||||
|
|
17
model.h
17
model.h
|
@ -75,6 +75,8 @@ struct fpga_model
|
|||
struct fpga_tile* tiles;
|
||||
struct hashed_strarray str;
|
||||
|
||||
struct fpga_net* nets;
|
||||
|
||||
// tmp_str will be allocated to hold max(x_width, y_height)
|
||||
// pointers, useful for string seeding when running wires.
|
||||
const char** tmp_str;
|
||||
|
@ -331,6 +333,21 @@ enum fpgadev_type
|
|||
DEV_SPI_ACCESS
|
||||
};
|
||||
|
||||
// We use two types of device indices, one is a flat index
|
||||
// into the tile->devs array (dev_idx_t), the other
|
||||
// one counts up from 0 through devices of one particular
|
||||
// type in the tile. The first logic device has type_idx == 0,
|
||||
// the second logic device has type_idx == 1, etc, no matter
|
||||
// at which index they are in the device array. The type indices
|
||||
// are used in the floorplan, the flat array indices internally
|
||||
// in memory.
|
||||
|
||||
typedef int dev_idx_t;
|
||||
typedef int dev_type_idx_t;
|
||||
|
||||
#define NO_DEV -1
|
||||
#define FPGA_DEV(model, y, x, dev_idx) (&YX_TILE(model, y, x)->devs[dev_idx])
|
||||
|
||||
// M and L device is always at type index 0, X device
|
||||
// is always at type index 1.
|
||||
#define DEV_LOGM 0
|
||||
|
|
|
@ -424,7 +424,7 @@ static int init_iob(struct fpga_model* model, int y, int x,
|
|||
|
||||
tile = YX_TILE(model, y, x);
|
||||
tile->devs[idx].iob.subtype = subtype;
|
||||
type_idx = fpga_dev_typecount(model, y, x, DEV_IOB, idx);
|
||||
type_idx = fpga_dev_typeidx(model, y, x, idx);
|
||||
if (!y)
|
||||
prefix = "TIOB";
|
||||
else if (y == model->y_height - BOT_OUTER_ROW)
|
||||
|
|
Loading…
Reference in New Issue
Block a user