Start bitstream generator
This commit is contained in:
parent
a1d635889c
commit
5d86f8c7cf
@ -1,4 +1,52 @@
|
|||||||
#include "fpga.h"
|
#include "fpga.h"
|
||||||
#include "fpga_global.h"
|
#include "fpga_global.h"
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
int fpga_generate_bitstream(struct fpga_chain *chain,
|
||||||
|
char *filename)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
char *buf = NULL;
|
||||||
|
FILE *bitstream = stderr;
|
||||||
|
|
||||||
|
if (strcmp(filename, "-")) {
|
||||||
|
bitstream = fopen(filename, "wb");
|
||||||
|
}
|
||||||
|
if (!bitstream) {
|
||||||
|
report(LL_ERROR,
|
||||||
|
"Could not open output file '%s'.",
|
||||||
|
filename);
|
||||||
|
errno = EIO;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
report(LL_INFO, "Generating bitstream...");
|
||||||
|
|
||||||
|
for (i = chain->length - 1; i >= 0; --i) {
|
||||||
|
report(LL_DEBUG,
|
||||||
|
"Generating bitstream for cell %p (%c)...",
|
||||||
|
chain->head[i], chain->head[i]->type->identifier);
|
||||||
|
buf = chain->head[i]->type->isp_generate_bitstream(chain->head[i]);
|
||||||
|
if (!buf) {
|
||||||
|
report(LL_ERROR,
|
||||||
|
"Error during bitstream generation for cell %p.",
|
||||||
|
chain->head[i]);
|
||||||
|
errno = ETYPE;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
for (int j = 0; j < chain->head[i]->type->isp_length; ++j) {
|
||||||
|
fprintf(bitstream, "%02X ", buf[j] & 0xFF);
|
||||||
|
}
|
||||||
|
fprintf(bitstream, "\n");
|
||||||
|
free(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
if (bitstream && (strcmp(filename, "-")))
|
||||||
|
fclose(bitstream);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
@ -2,4 +2,7 @@
|
|||||||
#define FPGA_H
|
#define FPGA_H
|
||||||
#include "fpga_cell.h"
|
#include "fpga_cell.h"
|
||||||
|
|
||||||
|
int fpga_generate_bitstream(struct fpga_chain *chain,
|
||||||
|
char *filename);
|
||||||
|
|
||||||
#endif // FPGA_H
|
#endif // FPGA_H
|
||||||
|
@ -10,37 +10,43 @@ 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
|
.isp_length = 0,
|
||||||
|
.isp_generate_bitstream = fpga_cell_isp_generate_bitstream_dummy
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.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
|
.isp_length = 0,
|
||||||
|
.isp_generate_bitstream = fpga_cell_isp_generate_bitstream_dummy
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.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
|
.isp_length = 0,
|
||||||
|
.isp_generate_bitstream = fpga_cell_isp_generate_bitstream_dummy
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.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
|
.isp_length = 0,
|
||||||
|
.isp_generate_bitstream = fpga_cell_isp_generate_bitstream_dummy
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.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
|
.isp_length = 6,
|
||||||
|
.isp_generate_bitstream = fpga_cell_lut34_isp_generate_bitstream
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.identifier = '\0',
|
.identifier = '\0',
|
||||||
.cell_new = NULL,
|
.cell_new = NULL,
|
||||||
.get_next_isp = NULL,
|
.get_next_isp = NULL,
|
||||||
.isp_length = 0
|
.isp_length = 0,
|
||||||
|
.isp_generate_bitstream = fpga_cell_isp_generate_bitstream_dummy
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -144,6 +150,20 @@ struct fpga_cell *fpga_cell_get_next_isp_dummy(struct fpga_cell *cell,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief isp_generate_bitstream_dummy
|
||||||
|
* @param cell
|
||||||
|
* @param buf
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
char *fpga_cell_isp_generate_bitstream_dummy(struct fpga_cell *cell)
|
||||||
|
{
|
||||||
|
report(LL_CRITICAL,
|
||||||
|
"Internal error. Cell type %c does not implement isp_generate_bitstream!",
|
||||||
|
cell->type->identifier);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief fpga_cell_new Create a new instance of type <identifier>
|
* @brief fpga_cell_new Create a new instance of type <identifier>
|
||||||
* @param identifier
|
* @param identifier
|
||||||
@ -255,3 +275,24 @@ struct fpga_chain *fpga_isp_chain_new(struct fpga_cell *entry)
|
|||||||
|
|
||||||
return chain;
|
return chain;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int fpga_cell_bitstream_set_bit(char *buffer, char *sbuffer,
|
||||||
|
int bit, int value) {
|
||||||
|
int byteno;
|
||||||
|
int bitno;
|
||||||
|
|
||||||
|
bitno = bit % 8;
|
||||||
|
byteno = bit / 8;
|
||||||
|
|
||||||
|
if ((sbuffer[byteno] & (1 << bitno))) { /* Already set */
|
||||||
|
return value == !((buffer[byteno] & (1 << bitno)));
|
||||||
|
} else {
|
||||||
|
sbuffer[byteno] |= (1 << bitno);
|
||||||
|
if (value)
|
||||||
|
buffer[byteno] |= (1 << bitno);
|
||||||
|
else
|
||||||
|
buffer[byteno] &= ~(1 << bitno);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@ -25,7 +25,8 @@ 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;
|
unsigned long isp_length;
|
||||||
|
char *(*isp_generate_bitstream)(struct fpga_cell *cell);
|
||||||
};
|
};
|
||||||
|
|
||||||
/* FPGA Logic cell base parameters */
|
/* FPGA Logic cell base parameters */
|
||||||
@ -52,9 +53,12 @@ struct fpga_cell *fpga_cell_get_far(struct fpga_cell *cell,
|
|||||||
enum fpga_cell_position position);
|
enum fpga_cell_position position);
|
||||||
struct fpga_cell *fpga_cell_get_next_isp_dummy(struct fpga_cell *fpga_cell,
|
struct fpga_cell *fpga_cell_get_next_isp_dummy(struct fpga_cell *fpga_cell,
|
||||||
enum fpga_isp_channel *isp_channel);
|
enum fpga_isp_channel *isp_channel);
|
||||||
|
char *fpga_cell_isp_generate_bitstream_dummy(struct fpga_cell *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);
|
struct fpga_chain *fpga_isp_chain_new(struct fpga_cell *entry);
|
||||||
|
int fpga_cell_bitstream_set_bit(char *buffer, char *sbuffer,
|
||||||
|
int bit, int value);
|
||||||
|
|
||||||
#endif // FPGA_CELL_H
|
#endif // FPGA_CELL_H
|
||||||
|
@ -1,6 +1,35 @@
|
|||||||
#include "fpga_cell_lut34.h"
|
#include "fpga_cell_lut34.h"
|
||||||
#include "fpga_global.h"
|
#include "fpga_global.h"
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
/* LUT IN MUX Definitions */
|
||||||
|
static char LUT_IN_MUX[4][8] = {
|
||||||
|
{LUT_NET_F2, LUT_NET_L0, LUT_NET_L3, LUT_NET_L2, LUT_NET_L1, LUT_NET_F1, LUT_NET_F0, LUT_NET_T0},
|
||||||
|
{LUT_NET_F0, LUT_NET_F1, LUT_NET_L1, LUT_NET_L2, LUT_NET_L3, LUT_NET_L0, LUT_NET_F2, LUT_NET_T1},
|
||||||
|
{LUT_NET_F3, LUT_NET_L0, LUT_NET_L3, LUT_NET_L2, LUT_NET_L1, LUT_NET_F1, LUT_NET_F0, LUT_NET_T2},
|
||||||
|
{LUT_NET_F0, LUT_NET_F1, LUT_NET_L1, LUT_NET_L2, LUT_NET_L3, LUT_NET_L0, LUT_NET_F3, LUT_NET_T3}
|
||||||
|
};
|
||||||
|
static int LUT_IN_BITMAP[4][3] = {
|
||||||
|
{12, 11, 19},
|
||||||
|
{ 8, 9, 10},
|
||||||
|
{15, 14, 13},
|
||||||
|
{16, 17, 18}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static int fpga_cell_lut34_lut_get_mux(int lut, char port) {
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (port == LUT_NET_DC)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
for (i = 0; i < 8; ++i) {
|
||||||
|
if (LUT_IN_MUX[lut][i] == port)
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
struct fpga_cell *fpga_cell_lut34_new()
|
struct fpga_cell *fpga_cell_lut34_new()
|
||||||
{
|
{
|
||||||
@ -30,3 +59,44 @@ struct fpga_cell *fpga_cell_lut34_get_next_isp(struct fpga_cell *cell,
|
|||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *fpga_cell_lut34_isp_generate_bitstream(struct fpga_cell *cell)
|
||||||
|
{
|
||||||
|
struct fpga_cell_lut34 *lut34 = (struct fpga_cell_lut34 *) cell;
|
||||||
|
char *buf = NULL;
|
||||||
|
char *sbuf = NULL;
|
||||||
|
int i;
|
||||||
|
int temp;
|
||||||
|
|
||||||
|
buf = calloc(cell->type->isp_length, sizeof(char));
|
||||||
|
sbuf = calloc(cell->type->isp_length, sizeof(char));
|
||||||
|
|
||||||
|
if (!buf) {
|
||||||
|
report(LL_CRITICAL,
|
||||||
|
"Out of memory during bitstream generation.");
|
||||||
|
errno = ENOMEM;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < 4; ++i) {
|
||||||
|
temp = fpga_cell_lut34_lut_get_mux(i, lut34->lut_in_sel[i]);
|
||||||
|
|
||||||
|
if (temp < 0) {
|
||||||
|
report(LL_ERROR,
|
||||||
|
"Invalid input mux '%c' selected for mux %d on cell %p.",
|
||||||
|
lut34->lut_in_sel[i], i, cell);
|
||||||
|
errno = EINVAL;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return buf;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
if (buf)
|
||||||
|
free(buf);
|
||||||
|
if (sbuf)
|
||||||
|
free(sbuf);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
@ -5,6 +5,22 @@
|
|||||||
|
|
||||||
enum lut_mode {LUT4, LUT3};
|
enum lut_mode {LUT4, LUT3};
|
||||||
|
|
||||||
|
enum LUT_NET_NAMES {
|
||||||
|
LUT_NET_DC = '\0', /* Dont' care */
|
||||||
|
LUT_NET_T0 = '0',
|
||||||
|
LUT_NET_T1 = '1',
|
||||||
|
LUT_NET_T2 = '2',
|
||||||
|
LUT_NET_T3 = '3',
|
||||||
|
LUT_NET_L0 = 'A',
|
||||||
|
LUT_NET_L1 = 'B',
|
||||||
|
LUT_NET_L2 = 'C',
|
||||||
|
LUT_NET_L3 = 'D',
|
||||||
|
LUT_NET_F0 = 'W',
|
||||||
|
LUT_NET_F1 = 'X',
|
||||||
|
LUT_NET_F2 = 'Y',
|
||||||
|
LUT_NET_F3 = 'Z'
|
||||||
|
};
|
||||||
|
|
||||||
struct fpga_cell_lut34 {
|
struct fpga_cell_lut34 {
|
||||||
struct fpga_cell base_cell;
|
struct fpga_cell base_cell;
|
||||||
|
|
||||||
@ -13,7 +29,7 @@ struct fpga_cell_lut34 {
|
|||||||
int led_lut_in_enable;
|
int led_lut_in_enable;
|
||||||
int led_lut_out_enable;
|
int led_lut_out_enable;
|
||||||
|
|
||||||
int lut_in_sel[4]; /* Input select */
|
char lut_in_sel[4]; /* Input select */
|
||||||
int drive_sel[4]; /* Which signal to drive onto each fabric line */
|
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_top_en[4]; /* Enable routing between top and main fabric */
|
||||||
int route_left_en[4]; /* Enable routing between left and main fabric */
|
int route_left_en[4]; /* Enable routing between left and main fabric */
|
||||||
@ -26,5 +42,5 @@ struct fpga_cell_lut34 {
|
|||||||
struct fpga_cell *fpga_cell_lut34_new();
|
struct fpga_cell *fpga_cell_lut34_new();
|
||||||
struct fpga_cell *fpga_cell_lut34_get_next_isp(struct fpga_cell *cell,
|
struct fpga_cell *fpga_cell_lut34_get_next_isp(struct fpga_cell *cell,
|
||||||
enum fpga_isp_channel *isp_channel);
|
enum fpga_isp_channel *isp_channel);
|
||||||
|
char *fpga_cell_lut34_isp_generate_bitstream(struct fpga_cell *cell);
|
||||||
#endif // FPGA_CELL_LUT34_H
|
#endif // FPGA_CELL_LUT34_H
|
||||||
|
@ -10,22 +10,35 @@
|
|||||||
int development_test_main(int argc, char *argv[])
|
int development_test_main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
struct fpga_cell *entry_cell;
|
struct fpga_cell *entry_cell;
|
||||||
|
struct fpga_chain *chain;
|
||||||
|
|
||||||
|
char *fdef_filename = "fdef/4x4.fdef";
|
||||||
|
char *bitstream_filename = "-";
|
||||||
|
|
||||||
set_log_level(LL_DEBUG);
|
set_log_level(LL_DEBUG);
|
||||||
|
|
||||||
entry_cell = fpga_fdef_loader_load("fdef/4x4.fdef");
|
entry_cell = fpga_fdef_loader_load(fdef_filename);
|
||||||
|
|
||||||
if (!entry_cell) {
|
if (!entry_cell) {
|
||||||
report(LL_CRITICAL, "Error loading FDEF.");
|
report(LL_CRITICAL, "Error loading FDEF.");
|
||||||
return E_FDEF;
|
return E_FDEF;
|
||||||
}
|
}
|
||||||
|
|
||||||
report(LL_INFO, "FDEF loaded.");
|
report(LL_INFO, "FDEF loaded.");
|
||||||
|
|
||||||
if (!fpga_isp_chain_new(entry_cell)) {
|
chain = fpga_isp_chain_new(entry_cell);
|
||||||
|
if (!chain) {
|
||||||
report(LL_CRITICAL, "Critical error during bitstream generation.");
|
report(LL_CRITICAL, "Critical error during bitstream generation.");
|
||||||
return E_BITSTREAM;
|
return E_BITSTREAM;
|
||||||
}
|
}
|
||||||
|
report(LL_INFO, "Chain loaded.");
|
||||||
|
|
||||||
|
/* TODO: Configure application specific logic */
|
||||||
|
((struct fpga_cell_lut34 *)(entry_cell->cell_connections[RIGHT]))->lut_in_sel[0] = 'A';
|
||||||
|
|
||||||
|
if (fpga_generate_bitstream(chain, bitstream_filename)) {
|
||||||
|
report(LL_ERROR, "Bitstream generation failed.");
|
||||||
|
return E_BITSTREAM;
|
||||||
|
}
|
||||||
|
report(LL_INFO, "Generated bitstream.");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user