87 lines
2.0 KiB
C
87 lines
2.0 KiB
C
|
#include "fpga_cell.h"
|
||
|
#include "fpga_global.h"
|
||
|
#include <stddef.h>
|
||
|
|
||
|
void fpga_cell_init(struct fpga_cell *fpga_cell,
|
||
|
enum fpga_cell_type fpga_cell_type)
|
||
|
{
|
||
|
int i;
|
||
|
|
||
|
for (i = 0; i < FPGA_CELL_CONNECTION_COUNT; ++i) {
|
||
|
fpga_cell->cell_connections[i] = NULL;
|
||
|
}
|
||
|
|
||
|
fpga_cell->type = fpga_cell_type;
|
||
|
|
||
|
report(LL_DEBUG,
|
||
|
"Initialized cell of type %d at %p.",
|
||
|
fpga_cell_type, fpga_cell);
|
||
|
}
|
||
|
|
||
|
enum fpga_cell_position fpga_cell_connection_opposing(enum fpga_cell_position position)
|
||
|
{
|
||
|
switch (position) {
|
||
|
case LEFT:
|
||
|
return RIGHT;
|
||
|
case RIGHT:
|
||
|
return LEFT;
|
||
|
case TOP:
|
||
|
return BOTTOM;
|
||
|
case BOTTOM:
|
||
|
return TOP;
|
||
|
default:
|
||
|
report(LL_ERROR,
|
||
|
"Internal error: Requested opposite of invalid position %d.",
|
||
|
position);
|
||
|
return LEFT;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief fpga_cell_connect Connect <fpga_cell> to the <position> of <target_cell>
|
||
|
* @param fpga_cell
|
||
|
* @param target_cell
|
||
|
* @param position
|
||
|
* @return 0 on success, -1 on failure
|
||
|
*/
|
||
|
int fpga_cell_connect(struct fpga_cell *fpga_cell,
|
||
|
struct fpga_cell *target_cell,
|
||
|
enum fpga_cell_position position)
|
||
|
{
|
||
|
if (target_cell->cell_connections[position] ||
|
||
|
fpga_cell->cell_connections[fpga_cell_connection_opposing(position)]) {
|
||
|
report(LL_WARNING,
|
||
|
"Tried to connect cell %p to pos %d of %p, even though a connection already exists for a least one of them.",
|
||
|
fpga_cell, target_cell, position);
|
||
|
errno = -ECONN;
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
target_cell->cell_connections[position] = fpga_cell;
|
||
|
fpga_cell->cell_connections[fpga_cell_connection_opposing(position)] = target_cell;
|
||
|
|
||
|
report(LL_DEBUG,
|
||
|
"Connected cell %p to port %d of %p.",
|
||
|
fpga_cell, position, target_cell);
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief fpga_cell_get_far Get cell on the far <position> of <cell>
|
||
|
* @param cell
|
||
|
* @param position
|
||
|
* @return
|
||
|
*/
|
||
|
struct fpga_cell *fpga_cell_get_far(struct fpga_cell *cell,
|
||
|
enum fpga_cell_position position)
|
||
|
{
|
||
|
struct fpga_cell *next = cell;
|
||
|
|
||
|
while (next->cell_connections[position]) {
|
||
|
next = next->cell_connections[position];
|
||
|
}
|
||
|
|
||
|
return next;
|
||
|
}
|