Start implementing Kousaten
This commit is contained in:
parent
0072ed418b
commit
e12120fade
4
sw/kousaten/fdef/16x16.fdef
Normal file
4
sw/kousaten/fdef/16x16.fdef
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
PLLLL]
|
||||||
|
[LLLL]
|
||||||
|
[LLLL]
|
||||||
|
[LLLL
|
86
sw/kousaten/src/fpga_cell.c
Normal file
86
sw/kousaten/src/fpga_cell.c
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
#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;
|
||||||
|
}
|
38
sw/kousaten/src/fpga_cell.h
Normal file
38
sw/kousaten/src/fpga_cell.h
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
#ifndef FPGA_CELL_H
|
||||||
|
#define FPGA_CELL_H
|
||||||
|
|
||||||
|
enum fpga_cell_position {
|
||||||
|
LEFT = 0,
|
||||||
|
TOP,
|
||||||
|
RIGHT,
|
||||||
|
BOTTOM,
|
||||||
|
FPGA_CELL_CONNECTION_COUNT
|
||||||
|
};
|
||||||
|
|
||||||
|
enum fpga_cell_type {
|
||||||
|
FPGA_CELL_NONE = 0,
|
||||||
|
FPGA_CELL_WIRE,
|
||||||
|
FPGA_CELL_LUT34
|
||||||
|
};
|
||||||
|
|
||||||
|
/* FPGA Logic cell base parameters */
|
||||||
|
struct fpga_cell
|
||||||
|
{
|
||||||
|
enum fpga_cell_type type;
|
||||||
|
|
||||||
|
struct fpga_cell *cell_connections[FPGA_CELL_CONNECTION_COUNT];
|
||||||
|
|
||||||
|
/* Cell-specific data will be appended depending on the cell type. */
|
||||||
|
};
|
||||||
|
|
||||||
|
void fpga_cell_init(struct fpga_cell *fpga_cell,
|
||||||
|
enum fpga_cell_type fpga_cell_type);
|
||||||
|
int fpga_cell_connect(struct fpga_cell *fpga_cell,
|
||||||
|
struct fpga_cell *target_cell,
|
||||||
|
enum fpga_cell_position position);
|
||||||
|
struct fpga_cell *fpga_cell_get_far(struct fpga_cell *cell,
|
||||||
|
enum fpga_cell_position position);
|
||||||
|
|
||||||
|
#define FPGA_TO_CELL(a) ((struct fpga_cell*) a)
|
||||||
|
|
||||||
|
#endif // FPGA_CELL_H
|
15
sw/kousaten/src/fpga_cell_lut34.c
Normal file
15
sw/kousaten/src/fpga_cell_lut34.c
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#include "fpga_cell_lut34.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
struct fpga_cell_lut34 *fpga_cell_lut_34_new()
|
||||||
|
{
|
||||||
|
struct fpga_cell_lut34 *fpga_cell_lut_34;
|
||||||
|
|
||||||
|
fpga_cell_lut_34 = malloc(sizeof(struct fpga_cell_lut34));
|
||||||
|
if (fpga_cell_lut_34) {
|
||||||
|
fpga_cell_init(FPGA_TO_CELL(fpga_cell_lut_34),
|
||||||
|
FPGA_CELL_LUT34);
|
||||||
|
}
|
||||||
|
|
||||||
|
return fpga_cell_lut_34;
|
||||||
|
}
|
28
sw/kousaten/src/fpga_cell_lut34.h
Normal file
28
sw/kousaten/src/fpga_cell_lut34.h
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
#ifndef FPGA_CELL_LUT34_H
|
||||||
|
#define FPGA_CELL_LUT34_H
|
||||||
|
|
||||||
|
#include "fpga_cell.h"
|
||||||
|
|
||||||
|
enum lut_mode {LUT4, LUT3};
|
||||||
|
|
||||||
|
struct fpga_cell_lut34 {
|
||||||
|
struct fpga_cell base_cell;
|
||||||
|
|
||||||
|
int sync; /* Register output on rising edge of clk */
|
||||||
|
|
||||||
|
int led_lut_in_enable;
|
||||||
|
int led_lut_out_enable;
|
||||||
|
|
||||||
|
int lut_in_sel[4]; /* Input select */
|
||||||
|
int drive_sel[4]; /* Which signal to drive onto each fabric line */
|
||||||
|
int route_top_en[4]; /* Enable routing between top and main fabric */
|
||||||
|
int route_left_en[4]; /* Enable routing between left and main fabric */
|
||||||
|
|
||||||
|
int LUT4; /* Look-up table for LUT-4 configuration */
|
||||||
|
int LUT3[2]; /* Look-up tables for LUT-3 configuration */
|
||||||
|
enum lut_mode lut_mode; /* Look-up table mode selection */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct fpga_cell_lut34 *fpga_cell_lut_34_new();
|
||||||
|
|
||||||
|
#endif // FPGA_CELL_LUT34_H
|
15
sw/kousaten/src/fpga_cell_none.c
Normal file
15
sw/kousaten/src/fpga_cell_none.c
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#include "fpga_cell_none.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
struct fpga_cell_none *fpga_cell_none_new()
|
||||||
|
{
|
||||||
|
struct fpga_cell_none *fpga_cell_none;
|
||||||
|
|
||||||
|
fpga_cell_none = malloc(sizeof(struct fpga_cell_none));
|
||||||
|
if (fpga_cell_none) {
|
||||||
|
fpga_cell_init(FPGA_TO_CELL(fpga_cell_none),
|
||||||
|
FPGA_CELL_NONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
return fpga_cell_none;
|
||||||
|
}
|
12
sw/kousaten/src/fpga_cell_none.h
Normal file
12
sw/kousaten/src/fpga_cell_none.h
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
#ifndef FPGA_CELL_NONE_H
|
||||||
|
#define FPGA_CELL_NONE_H
|
||||||
|
|
||||||
|
#include "fpga_cell.h"
|
||||||
|
|
||||||
|
struct fpga_cell_none {
|
||||||
|
struct fpga_cell base_cell;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct fpga_cell_none *fpga_cell_none_new();
|
||||||
|
|
||||||
|
#endif // FPGA_CELL_NONE_H
|
75
sw/kousaten/src/fpga_fdef_loader.c
Normal file
75
sw/kousaten/src/fpga_fdef_loader.c
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
#include "fpga_fdef_loader.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
struct fpga_cell *fpga_fdef_loader_load(char *filename)
|
||||||
|
{
|
||||||
|
FILE *fdef;
|
||||||
|
int c;
|
||||||
|
int line = 1;
|
||||||
|
int col = 1;
|
||||||
|
|
||||||
|
struct fpga_cell *cell_left = NULL;
|
||||||
|
struct fpga_cell *cell_top = NULL;
|
||||||
|
struct fpga_cell *cell = NULL;
|
||||||
|
|
||||||
|
report(LL_INFO, "Loading FDEF from %s...", filename);
|
||||||
|
|
||||||
|
fdef = fopen(filename, "r");
|
||||||
|
|
||||||
|
if (!fdef)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
while ((c = fgetc(fdef)) != EOF) {
|
||||||
|
switch (c) {
|
||||||
|
case 'L':
|
||||||
|
cell = FPGA_TO_CELL(fpga_cell_lut_34_new());
|
||||||
|
if (!cell) {
|
||||||
|
report(LL_CRITICAL,
|
||||||
|
"Out of memory when creating cell.");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '\n':
|
||||||
|
col = 0;
|
||||||
|
line++;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
report(LL_ERROR,
|
||||||
|
"%s:%d:%d: Invalid cell type %c. Replacing with empty cell.",
|
||||||
|
filename, line, col, c);
|
||||||
|
/* fall-through */
|
||||||
|
case ' ':
|
||||||
|
cell = FPGA_TO_CELL(fpga_cell_none_new());
|
||||||
|
if (!cell) {
|
||||||
|
report(LL_CRITICAL,
|
||||||
|
"Out of memory when creating cell.");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c == '\n') {
|
||||||
|
cell_left = NULL;
|
||||||
|
cell_top = fpga_cell_get_far(cell, LEFT);
|
||||||
|
report(LL_DEBUG, "");
|
||||||
|
|
||||||
|
} else {
|
||||||
|
if (cell_left)
|
||||||
|
fpga_cell_connect(cell, cell_left, RIGHT);
|
||||||
|
if (cell_top)
|
||||||
|
fpga_cell_connect(cell, cell_top, BOTTOM);
|
||||||
|
|
||||||
|
cell_left = cell;
|
||||||
|
if (cell_top)
|
||||||
|
cell_top = cell_top->cell_connections[RIGHT];
|
||||||
|
}
|
||||||
|
|
||||||
|
col++;
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(fdef);
|
||||||
|
|
||||||
|
return fpga_cell_get_far(fpga_cell_get_far(cell, LEFT), TOP);
|
||||||
|
}
|
11
sw/kousaten/src/fpga_fdef_loader.h
Normal file
11
sw/kousaten/src/fpga_fdef_loader.h
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
#ifndef FPGA_FDEF_LOADER_H
|
||||||
|
#define FPGA_FDEF_LOADER_H
|
||||||
|
|
||||||
|
#include "fpga_global.h"
|
||||||
|
#include "fpga_cell.h"
|
||||||
|
#include "fpga_cell_lut34.h"
|
||||||
|
#include "fpga_cell_none.h"
|
||||||
|
|
||||||
|
struct fpga_cell *fpga_fdef_loader_load(char *filename);
|
||||||
|
|
||||||
|
#endif // FPGA_FDEF_LOADER_H
|
33
sw/kousaten/src/fpga_global.c
Normal file
33
sw/kousaten/src/fpga_global.c
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
#include "fpga_global.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
static int current_log_level = 100;
|
||||||
|
|
||||||
|
static const char *ll_string[] = {
|
||||||
|
"\x1B[34m[D] ",
|
||||||
|
"\x1B[32m[I] ",
|
||||||
|
"\x1B[33m[W] ",
|
||||||
|
"\x1B[31m[E] ",
|
||||||
|
"\x1B[31m\x1B[1m[X] ",
|
||||||
|
"[?] "
|
||||||
|
};
|
||||||
|
|
||||||
|
enum log_level report(enum log_level log_level, const char *format, ...)
|
||||||
|
{
|
||||||
|
va_list vargs;
|
||||||
|
|
||||||
|
if (log_level > LL_COUNT)
|
||||||
|
log_level = LL_COUNT;
|
||||||
|
|
||||||
|
if (log_level <= current_log_level) {
|
||||||
|
va_start(vargs, format);
|
||||||
|
fprintf(stderr, "%s", ll_string[log_level]);
|
||||||
|
vfprintf(stderr, format, vargs);
|
||||||
|
fprintf(stderr, "\x1B[0m\n");
|
||||||
|
va_end(vargs);
|
||||||
|
}
|
||||||
|
|
||||||
|
return log_level;
|
||||||
|
}
|
17
sw/kousaten/src/fpga_global.h
Normal file
17
sw/kousaten/src/fpga_global.h
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
#ifndef FPGA_GLOBAL_H
|
||||||
|
#define FPGA_GLOBAL_H
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
enum log_level {LL_DEBUG = 0,
|
||||||
|
LL_INFO,
|
||||||
|
LL_WARNING,
|
||||||
|
LL_ERROR,
|
||||||
|
LL_CRITICAL,
|
||||||
|
LL_COUNT};
|
||||||
|
enum log_level report(enum log_level log_level, const char *format, ...);
|
||||||
|
|
||||||
|
/* Error codes */
|
||||||
|
#define ECONN 1000 /* Tried to connect to already connected port */
|
||||||
|
|
||||||
|
#endif // FPGA_GLOBAL_H
|
@ -1,7 +1,25 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include "fpga_cell.h"
|
||||||
|
#include "fpga_fdef_loader.h"
|
||||||
|
#include "fpga_global.h"
|
||||||
|
|
||||||
int main()
|
int development_test_main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
printf("Hello World!\n");
|
struct fpga_cell *entry_cell;
|
||||||
|
|
||||||
|
entry_cell = fpga_fdef_loader_load("fdef/16x16.fdef");
|
||||||
|
|
||||||
|
if (!entry_cell) {
|
||||||
|
report(LL_CRITICAL, "Error loading FDEF.\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
report(LL_INFO, "FDEF loaded.");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
return development_test_main(argc, argv);
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user