Implement fpga_isp_chain_new
This commit is contained in:
parent
d0fed3cce4
commit
925e17372a
@ -1,23 +1,4 @@
|
|||||||
#include "fpga.h"
|
#include "fpga.h"
|
||||||
#include "fpga_global.h"
|
#include "fpga_global.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
int fpga_generate_bitstream(struct fpga_cell *cell)
|
|
||||||
{
|
|
||||||
struct fpga_cell *current_cell = cell;
|
|
||||||
enum fpga_isp_channel current_channel = FPGA_ISP_CHANNEL_NORMAL;
|
|
||||||
|
|
||||||
while (current_cell) {
|
|
||||||
report(LL_DEBUG,
|
|
||||||
"Adding %p (%c) to ISP chain.",
|
|
||||||
current_cell, current_cell->type->identifier);
|
|
||||||
current_cell = current_cell->type->get_next_isp(current_cell,
|
|
||||||
¤t_channel);
|
|
||||||
if (current_channel == FPGA_ISP_CHANNEL_ERROR)
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
report(LL_INFO,
|
|
||||||
"Bitstream generation finished.");
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
@ -2,6 +2,4 @@
|
|||||||
#define FPGA_H
|
#define FPGA_H
|
||||||
#include "fpga_cell.h"
|
#include "fpga_cell.h"
|
||||||
|
|
||||||
int fpga_generate_bitstream(struct fpga_cell *cell);
|
|
||||||
|
|
||||||
#endif // FPGA_H
|
#endif // FPGA_H
|
||||||
|
@ -3,37 +3,44 @@
|
|||||||
#include "fpga_cell_lut34.h"
|
#include "fpga_cell_lut34.h"
|
||||||
#include "fpga_cell_none.h"
|
#include "fpga_cell_none.h"
|
||||||
#include "fpga_cell_wire.h"
|
#include "fpga_cell_wire.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
static struct fpga_cell_type fpga_cell_list[] = {
|
static struct fpga_cell_type fpga_cell_list[] = {
|
||||||
{
|
{
|
||||||
.identifier = ' ',
|
.identifier = ' ',
|
||||||
.cell_new = fpga_cell_none_new,
|
.cell_new = fpga_cell_none_new,
|
||||||
.get_next_isp = fpga_cell_none_get_next_isp
|
.get_next_isp = fpga_cell_none_get_next_isp,
|
||||||
|
.isp_length = 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.identifier = '[',
|
.identifier = '[',
|
||||||
.cell_new = fpga_cell_wire_new,
|
.cell_new = fpga_cell_wire_new,
|
||||||
.get_next_isp = fpga_cell_wire_get_next_isp
|
.get_next_isp = fpga_cell_wire_get_next_isp,
|
||||||
|
.isp_length = 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.identifier = ']',
|
.identifier = ']',
|
||||||
.cell_new = fpga_cell_wire_new,
|
.cell_new = fpga_cell_wire_new,
|
||||||
.get_next_isp = fpga_cell_wire_get_next_isp
|
.get_next_isp = fpga_cell_wire_get_next_isp,
|
||||||
|
.isp_length = 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.identifier = 'P',
|
.identifier = 'P',
|
||||||
.cell_new = fpga_cell_wire_new,
|
.cell_new = fpga_cell_wire_new,
|
||||||
.get_next_isp = fpga_cell_wire_get_next_isp
|
.get_next_isp = fpga_cell_wire_get_next_isp,
|
||||||
|
.isp_length = 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.identifier = 'L',
|
.identifier = 'L',
|
||||||
.cell_new = fpga_cell_lut34_new,
|
.cell_new = fpga_cell_lut34_new,
|
||||||
.get_next_isp = fpga_cell_lut34_get_next_isp
|
.get_next_isp = fpga_cell_lut34_get_next_isp,
|
||||||
|
.isp_length = 1 // TODO:TBD
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.identifier = '\0',
|
.identifier = '\0',
|
||||||
.cell_new = NULL,
|
.cell_new = NULL,
|
||||||
.get_next_isp = NULL
|
.get_next_isp = NULL,
|
||||||
|
.isp_length = 0
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -169,3 +176,72 @@ struct fpga_cell *fpga_cell_new(char identifier)
|
|||||||
identifier);
|
identifier);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief fpga_isp_chain_new
|
||||||
|
* @param entry
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
struct fpga_chain *fpga_isp_chain_new(struct fpga_cell *entry)
|
||||||
|
{
|
||||||
|
struct fpga_cell *current_cell = entry;
|
||||||
|
enum fpga_isp_channel current_channel = FPGA_ISP_CHANNEL_NORMAL;
|
||||||
|
struct fpga_chain *chain;
|
||||||
|
|
||||||
|
report(LL_INFO,
|
||||||
|
"Generating ISP chain...");
|
||||||
|
|
||||||
|
chain = calloc(sizeof (struct fpga_chain), 1);
|
||||||
|
if (!chain) {
|
||||||
|
report (LL_CRITICAL,
|
||||||
|
"Out of memory during ISP chain generation.");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (current_cell) {
|
||||||
|
if (current_channel == FPGA_ISP_CHANNEL_NORMAL &&
|
||||||
|
current_cell->type->isp_length > 0) {
|
||||||
|
report(LL_DEBUG,
|
||||||
|
"Adding %p (%c) to ISP chain.",
|
||||||
|
current_cell, current_cell->type->identifier);
|
||||||
|
|
||||||
|
if (!chain->head) {
|
||||||
|
chain->head = malloc(sizeof(chain->head));
|
||||||
|
*(chain->head) = current_cell;
|
||||||
|
chain->length = 1;
|
||||||
|
} else {
|
||||||
|
chain->length++;
|
||||||
|
chain->head = realloc(chain->head,
|
||||||
|
sizeof(chain->head) * chain->length);
|
||||||
|
*(chain->head + chain->length - 1) = current_cell;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
report(LL_DEBUG,
|
||||||
|
"Using %p (%c) for ISP routing.",
|
||||||
|
current_cell, current_cell->type->identifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
current_cell = current_cell->type->get_next_isp(current_cell,
|
||||||
|
¤t_channel);
|
||||||
|
if (current_channel == FPGA_ISP_CHANNEL_ERROR) {
|
||||||
|
/* TODO: Clean up memory */
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
report(LL_INFO,
|
||||||
|
"Added %d cells to ISP chain.",
|
||||||
|
chain->length);
|
||||||
|
|
||||||
|
for (int i = 0; i < chain->length; ++i) {
|
||||||
|
report(LL_DEBUG,
|
||||||
|
" %4d = %p",
|
||||||
|
i, chain->head[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
report(LL_INFO,
|
||||||
|
"ISP chain generated finished.");
|
||||||
|
|
||||||
|
return chain;
|
||||||
|
}
|
||||||
|
@ -25,6 +25,7 @@ struct fpga_cell_type
|
|||||||
struct fpga_cell *(*cell_new)();
|
struct fpga_cell *(*cell_new)();
|
||||||
struct fpga_cell *(*get_next_isp)(struct fpga_cell *cell,
|
struct fpga_cell *(*get_next_isp)(struct fpga_cell *cell,
|
||||||
enum fpga_isp_channel *isp_channel);
|
enum fpga_isp_channel *isp_channel);
|
||||||
|
int isp_length;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* FPGA Logic cell base parameters */
|
/* FPGA Logic cell base parameters */
|
||||||
@ -37,6 +38,11 @@ struct fpga_cell
|
|||||||
/* Cell-specific data will be appended depending on the cell type. */
|
/* Cell-specific data will be appended depending on the cell type. */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct fpga_chain {
|
||||||
|
struct fpga_cell **head;
|
||||||
|
int length;
|
||||||
|
};
|
||||||
|
|
||||||
void fpga_cell_init(struct fpga_cell *cell,
|
void fpga_cell_init(struct fpga_cell *cell,
|
||||||
struct fpga_cell_type *cell_type);
|
struct fpga_cell_type *cell_type);
|
||||||
int fpga_cell_connect(struct fpga_cell *fpga_cell,
|
int fpga_cell_connect(struct fpga_cell *fpga_cell,
|
||||||
@ -49,4 +55,6 @@ struct fpga_cell *fpga_cell_get_next_isp_dummy(struct fpga_cell *fpga_cell,
|
|||||||
struct fpga_cell *fpga_cell_new(char identifier);
|
struct fpga_cell *fpga_cell_new(char identifier);
|
||||||
#define FPGA_TO_CELL(a) ((struct fpga_cell*) a)
|
#define FPGA_TO_CELL(a) ((struct fpga_cell*) a)
|
||||||
|
|
||||||
|
struct fpga_chain *fpga_isp_chain_new(struct fpga_cell *entry);
|
||||||
|
|
||||||
#endif // FPGA_CELL_H
|
#endif // FPGA_CELL_H
|
||||||
|
@ -33,23 +33,10 @@ struct fpga_cell *fpga_cell_wire_get_next_isp(struct fpga_cell *cell,
|
|||||||
*isp_channel = FPGA_ISP_CHANNEL_LFDN;
|
*isp_channel = FPGA_ISP_CHANNEL_LFDN;
|
||||||
return cell->cell_connections[RIGHT];
|
return cell->cell_connections[RIGHT];
|
||||||
}
|
}
|
||||||
|
default:
|
||||||
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
// switch (cell->type->identifier) {
|
|
||||||
// case ' ':
|
|
||||||
// report(LL_WARNING,
|
|
||||||
// "ISP signal ran into empty cell. Terminating chain.");
|
|
||||||
// return NULL;
|
|
||||||
// case ']':
|
|
||||||
// switch (*isp_channel) {
|
|
||||||
// case FPGA_ISP_CHANNEL_NORMAL:
|
|
||||||
// *isp_channel = FPGA_ISP_CHANNEL_BACK;
|
|
||||||
// return cell->cell_connections[LEFT];
|
|
||||||
// default:
|
|
||||||
// goto fail;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
report(LL_ERROR,
|
report(LL_ERROR,
|
||||||
"Entered wiring cell %c on invalid ISP channel %d.",
|
"Entered wiring cell %c on invalid ISP channel %d.",
|
||||||
|
@ -25,7 +25,7 @@ int development_test_main(int argc, char *argv[])
|
|||||||
|
|
||||||
report(LL_INFO, "FDEF loaded.");
|
report(LL_INFO, "FDEF loaded.");
|
||||||
|
|
||||||
if (fpga_generate_bitstream(entry_cell)) {
|
if (!fpga_isp_chain_new(entry_cell)) {
|
||||||
report(LL_CRITICAL, "Critical error during bitstream generation.");
|
report(LL_CRITICAL, "Critical error during bitstream generation.");
|
||||||
return E_BITSTREAM;
|
return E_BITSTREAM;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user