working in model, 0.1%
This commit is contained in:
parent
d8a18a6034
commit
917c3e7ffd
|
@ -33,6 +33,7 @@ static int dump_file(const char* path)
|
|||
char line[1024];
|
||||
FILE* f;
|
||||
|
||||
printf("\n");
|
||||
printf("O begin dump %s\n", path);
|
||||
f = fopen(path, "r");
|
||||
EXIT(!f);
|
||||
|
@ -45,6 +46,7 @@ static int dump_file(const char* path)
|
|||
}
|
||||
fclose(f);
|
||||
printf("O end dump %s\n", path);
|
||||
printf("\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -157,17 +159,15 @@ 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, /*LOGIC_X*/ 1);
|
||||
logic_dev = fpga_dev(&model, /*y*/ 68, /*x*/ 13, DEV_LOGIC, DEV_LOGX);
|
||||
if (!logic_dev) FAIL(EINVAL);
|
||||
logic_dev->instantiated = 1;
|
||||
logic_dev->logic.D_used = 1;
|
||||
rc = fpga_set_lut(&model, logic_dev, D6_LUT, "A3", ZTERM);
|
||||
if (rc) FAIL(rc);
|
||||
|
||||
#if 1
|
||||
rc = diff_printf(&tstate);
|
||||
if (rc) goto fail;
|
||||
#endif
|
||||
|
||||
printf("P46 I pinw %s\n", P46_dev->iob.pinw_out_I);
|
||||
for (i = 0;; i++) {
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
diff -U 0 $1 $2 > ${2%.*}.fp_diff
|
||||
|
||||
./fp2bit $2 ${2%.*}.f2b || exit $?
|
||||
./bit2fp --bits-only ${2%.*}.f2b > ${2%.*}.b2f || exit $?
|
||||
./bit2fp --no-fp-header ${2%.*}.f2b > ${2%.*}.b2f || exit $?
|
||||
if [ "$1" == "/dev/null" ]
|
||||
then
|
||||
diff -U 0 /dev/null ${2%.*}.b2f > ${2%.*}.b2f_diff
|
||||
|
@ -10,5 +10,7 @@ else
|
|||
diff -U 0 ${1%.*}.b2f ${2%.*}.b2f > ${2%.*}.b2f_diff
|
||||
fi
|
||||
|
||||
cat ${2%.*}.fp_diff | sed -e '/^--- /d;/^+++ /d;/^@@ /d' > ${2%.*}.diff
|
||||
echo "fp:" > ${2%.*}.diff
|
||||
cat ${2%.*}.fp_diff | sed -e '/^--- /d;/^+++ /d;/^@@ /d' >> ${2%.*}.diff
|
||||
echo "b2f:" >> ${2%.*}.diff
|
||||
cat ${2%.*}.b2f_diff | sed -e '/^--- /d;/^+++ /d;/^@@ /d' >> ${2%.*}.diff
|
||||
|
|
14
bit.h
14
bit.h
|
@ -57,20 +57,6 @@ enum {
|
|||
CMD_DESYNC = 13, CMD_IPROG
|
||||
};
|
||||
|
||||
#define FRAME_SIZE 130
|
||||
#define FRAMES_PER_ROW 505 // for slx4 and slx9
|
||||
#define PADDING_FRAMES_PER_ROW 2
|
||||
#define NUM_ROWS 4 // for slx9 and slx9
|
||||
|
||||
#define FRAMES_DATA_START 0
|
||||
#define FRAMES_DATA_LEN (NUM_ROWS*FRAMES_PER_ROW*FRAME_SIZE)
|
||||
#define BRAM_DATA_START FRAMES_DATA_LEN
|
||||
#define BRAM_DATA_LEN (4*144*FRAME_SIZE)
|
||||
#define IOB_DATA_START (BRAM_DATA_START + BRAM_DATA_LEN)
|
||||
#define IOB_WORDS 896 // 16-bit words, for slx4 and slx9
|
||||
#define IOB_DATA_LEN (IOB_WORDS*2)
|
||||
#define BITS_LEN (IOB_DATA_START+IOB_DATA_LEN)
|
||||
|
||||
#define MAX_HEADER_STR_LEN 128
|
||||
#define MAX_REG_ACTIONS 256
|
||||
|
||||
|
|
10
bit2fp.c
10
bit2fp.c
|
@ -12,7 +12,7 @@
|
|||
int main(int argc, char** argv)
|
||||
{
|
||||
struct fpga_model model;
|
||||
int bit_header, bit_regs, fp_header, file_arg, flags, rc = -1;
|
||||
int bit_header, bit_regs, fp_header, pull_model, file_arg, flags, rc = -1;
|
||||
struct fpga_config config;
|
||||
|
||||
// parameters
|
||||
|
@ -20,12 +20,13 @@ int main(int argc, char** argv)
|
|||
fprintf(stderr,
|
||||
"\n"
|
||||
"%s - bitstream to floorplan\n"
|
||||
"Usage: %s [--bit-header] [--bit-regs] [--no-fp-header] <bitstream_file>\n"
|
||||
"Usage: %s [--bit-header] [--bit-regs] [--no-model] [--no-fp-header] <bitstream_file>\n"
|
||||
"\n", argv[0], argv[0]);
|
||||
goto fail;
|
||||
}
|
||||
bit_header = 0;
|
||||
bit_regs = 0;
|
||||
pull_model = 1;
|
||||
fp_header = 1;
|
||||
file_arg = 1;
|
||||
while (!strncmp(argv[file_arg], "--", 2)) {
|
||||
|
@ -33,6 +34,8 @@ int main(int argc, char** argv)
|
|||
bit_header = 1;
|
||||
else if (!strcmp(argv[file_arg], "--bit-regs"))
|
||||
bit_regs = 1;
|
||||
else if (!strcmp(argv[file_arg], "--no-model"))
|
||||
pull_model = 0;
|
||||
else if (!strcmp(argv[file_arg], "--no-fp-header"))
|
||||
fp_header = 0;
|
||||
else break;
|
||||
|
@ -54,7 +57,8 @@ int main(int argc, char** argv)
|
|||
// build model and fill from bitstream
|
||||
if ((rc = fpga_build_model(&model, XC6SLX9_ROWS, XC6SLX9_COLUMNS,
|
||||
XC6SLX9_LEFT_WIRING, XC6SLX9_RIGHT_WIRING))) FAIL(rc);
|
||||
if ((rc = extract_model(&model, &config.bits))) FAIL(rc);
|
||||
if (pull_model)
|
||||
if ((rc = extract_model(&model, &config.bits))) FAIL(rc);
|
||||
|
||||
// dump model
|
||||
flags = FP_DEFAULT;
|
||||
|
|
145
bit_frames.c
145
bit_frames.c
|
@ -8,6 +8,9 @@
|
|||
#include "model.h"
|
||||
#include "bit.h"
|
||||
#include "parts.h"
|
||||
#include "control.h"
|
||||
|
||||
#define HCLK_BYTES 2
|
||||
|
||||
static uint8_t* get_first_minor(struct fpga_bits* bits, int row, int major)
|
||||
{
|
||||
|
@ -22,21 +25,21 @@ static uint8_t* get_first_minor(struct fpga_bits* bits, int row, int major)
|
|||
static int get_bit(struct fpga_bits* bits,
|
||||
int row, int major, int minor, int bit_i)
|
||||
{
|
||||
return get_framebit(get_first_minor(bits, row, major)
|
||||
return frame_get_bit(get_first_minor(bits, row, major)
|
||||
+ minor*FRAME_SIZE, bit_i);
|
||||
}
|
||||
|
||||
static void set_bit(struct fpga_bits* bits,
|
||||
int row, int major, int minor, int bit_i)
|
||||
{
|
||||
return set_framebit(get_first_minor(bits, row, major)
|
||||
return frame_set_bit(get_first_minor(bits, row, major)
|
||||
+ minor*FRAME_SIZE, bit_i);
|
||||
}
|
||||
|
||||
static void clear_bit(struct fpga_bits* bits,
|
||||
int row, int major, int minor, int bit_i)
|
||||
{
|
||||
return clear_framebit(get_first_minor(bits, row, major)
|
||||
return frame_clear_bit(get_first_minor(bits, row, major)
|
||||
+ minor*FRAME_SIZE, bit_i);
|
||||
}
|
||||
|
||||
|
@ -72,13 +75,147 @@ static struct bit_pos s_default_bits[] = {
|
|||
|
||||
int extract_model(struct fpga_model* model, struct fpga_bits* bits)
|
||||
{
|
||||
int i, rc;
|
||||
int i, num_iobs, iob_y, iob_x, iob_idx, row, row_pos, rc;
|
||||
int x, y, byte_off;
|
||||
uint32_t* u32_p;
|
||||
uint8_t* u8_p;
|
||||
uint64_t u64;
|
||||
const char* iob_sitename, *lut_str;
|
||||
struct fpga_device* dev;
|
||||
|
||||
for (i = 0; i < sizeof(s_default_bits)/sizeof(s_default_bits[0]); i++) {
|
||||
if (!get_bitp(bits, &s_default_bits[i]))
|
||||
FAIL(EINVAL);
|
||||
clear_bitp(bits, &s_default_bits[i]);
|
||||
}
|
||||
|
||||
// IOBs
|
||||
num_iobs = get_num_iobs(XC6SLX9);
|
||||
for (i = 0; i < num_iobs; i++) {
|
||||
u32_p = (uint32_t*) &bits->d[IOB_DATA_START + i*IOB_ENTRY_LEN];
|
||||
if (!u32_p[0] && !u32_p[1])
|
||||
continue;
|
||||
iob_sitename = get_iob_sitename(XC6SLX9, i);
|
||||
if (!iob_sitename) {
|
||||
HERE();
|
||||
continue;
|
||||
}
|
||||
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);
|
||||
|
||||
// we only support 2 hardcoded types of IOB right now
|
||||
if (u32_p[0] == 0x00000100
|
||||
&& u32_p[1] == 0x06001100) {
|
||||
dev->instantiated = 1;
|
||||
strcpy(dev->iob.ostandard, IO_LVCMOS33);
|
||||
dev->iob.drive_strength = 12;
|
||||
dev->iob.O_used = 1;
|
||||
dev->iob.slew = SLEW_SLOW;
|
||||
dev->iob.suspend = SUSP_3STATE;
|
||||
u32_p[0] = 0;
|
||||
u32_p[1] = 0;
|
||||
} else if (u32_p[0] == 0x00000107
|
||||
&& u32_p[1] == 0x0B002400) {
|
||||
dev->instantiated = 1;
|
||||
strcpy(dev->iob.istandard, IO_LVCMOS33);
|
||||
dev->iob.bypass_mux = BYPASS_MUX_I;
|
||||
dev->iob.I_mux = IMUX_I;
|
||||
u32_p[0] = 0;
|
||||
u32_p[1] = 0;
|
||||
} else HERE();
|
||||
}
|
||||
|
||||
// logic
|
||||
for (x = LEFT_SIDE_WIDTH; x < model->x_width-RIGHT_SIDE_WIDTH; x++) {
|
||||
if (!is_atx(X_LOGIC_COL, model, x))
|
||||
continue;
|
||||
for (y = TOP_IO_TILES; y < model->y_height - BOT_IO_TILES; y++) {
|
||||
if (!has_device_type(model, y, x, DEV_LOGIC, LOGIC_M))
|
||||
continue;
|
||||
row = which_row(y, model);
|
||||
row_pos = pos_in_row(y, model);
|
||||
if (row == -1 || row_pos == -1 || row_pos == 8) {
|
||||
HERE();
|
||||
continue;
|
||||
}
|
||||
if (row_pos > 8) row_pos--;
|
||||
u8_p = get_first_minor(bits, row, model->x_major[x]);
|
||||
byte_off = row_pos * 8;
|
||||
if (row_pos >= 8) byte_off += HCLK_BYTES;
|
||||
|
||||
u64 = frame_get_u64(u8_p + 26*FRAME_SIZE + byte_off);
|
||||
if ( u64 ) {
|
||||
// 21, 22, 36 and 37 are actually not default
|
||||
// and can go off with the FFMUXes or routing
|
||||
// say D over the FF to DQ etc. (AFFMUX=b37,
|
||||
// BFFMUX=b36, CFFMUX=b22, DFFMUX=b21).
|
||||
if (!(u64 & (1ULL<<1) && u64 & (1ULL<<2)
|
||||
&& u64 & (1ULL<<7) && u64 & (1ULL<<21)
|
||||
&& u64 & (1ULL<<22) && u64 & (1ULL<<36)
|
||||
&& u64 & (1ULL<<37) && u64 & (1ULL<<39)))
|
||||
continue;
|
||||
if (u64 & ~(0x000000B000600086ULL))
|
||||
continue;
|
||||
|
||||
// any logic block will enable r0ma17mi22b980
|
||||
if (!get_bit(bits, /*row*/ 0, /*major*/ 17,
|
||||
/*minor*/ 22, /*bit_i*/ 980)) {
|
||||
HERE();
|
||||
continue;
|
||||
}
|
||||
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->instantiated = 1;
|
||||
*(uint64_t*)(u8_p+26*FRAME_SIZE+byte_off) = 0;
|
||||
|
||||
u64 = read_lut64(u8_p + 27*FRAME_SIZE, (byte_off+4)*8);
|
||||
{ int logic_base[6] = {1,1,0,1,1,0};
|
||||
lut_str = lut2bool(u64, 64, &logic_base, /*flip_b0*/ 0); }
|
||||
if (*lut_str) {
|
||||
rc = fpga_set_lut(model, dev, A6_LUT, lut_str, ZTERM);
|
||||
if (rc) FAIL(rc);
|
||||
dev->logic.A_used = 1;
|
||||
*(uint32_t*)(u8_p+27*FRAME_SIZE+byte_off+4) = 0;
|
||||
*(uint32_t*)(u8_p+28*FRAME_SIZE+byte_off+4) = 0;
|
||||
}
|
||||
u64 = read_lut64(u8_p + 29*FRAME_SIZE, (byte_off+4)*8);
|
||||
{ int logic_base[6] = {1,1,0,1,1,0};
|
||||
lut_str = lut2bool(u64, 64, &logic_base, /*flip_b0*/ 0); }
|
||||
if (*lut_str) {
|
||||
rc = fpga_set_lut(model, dev, B6_LUT, lut_str, ZTERM);
|
||||
if (rc) FAIL(rc);
|
||||
dev->logic.B_used = 1;
|
||||
*(uint32_t*)(u8_p+29*FRAME_SIZE+byte_off+4) = 0;
|
||||
*(uint32_t*)(u8_p+30*FRAME_SIZE+byte_off+4) = 0;
|
||||
}
|
||||
u64 = read_lut64(u8_p + 27*FRAME_SIZE, byte_off*8);
|
||||
{ int logic_base[6] = {0,1,0,0,0,1};
|
||||
lut_str = lut2bool(u64, 64, &logic_base, /*flip_b0*/ 0); }
|
||||
if (*lut_str) {
|
||||
rc = fpga_set_lut(model, dev, C6_LUT, lut_str, ZTERM);
|
||||
if (rc) FAIL(rc);
|
||||
dev->logic.C_used = 1;
|
||||
*(uint32_t*)(u8_p+27*FRAME_SIZE+byte_off) = 0;
|
||||
*(uint32_t*)(u8_p+28*FRAME_SIZE+byte_off) = 0;
|
||||
}
|
||||
u64 = read_lut64(u8_p + 29*FRAME_SIZE, byte_off*8);
|
||||
{ int logic_base[6] = {0,1,0,0,0,1};
|
||||
lut_str = lut2bool(u64, 64, &logic_base, /*flip_b0*/ 0); }
|
||||
if (*lut_str) {
|
||||
rc = fpga_set_lut(model, dev, D6_LUT, lut_str, ZTERM);
|
||||
if (rc) FAIL(rc);
|
||||
dev->logic.D_used = 1;
|
||||
*(uint32_t*)(u8_p+29*FRAME_SIZE+byte_off) = 0;
|
||||
*(uint32_t*)(u8_p+30*FRAME_SIZE+byte_off) = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
fail:
|
||||
return rc;
|
||||
|
|
20
bit_regs.c
20
bit_regs.c
|
@ -797,17 +797,17 @@ static void printf_clb(uint8_t* maj_bits, int row, int major)
|
|||
|
||||
// bits
|
||||
for (j = 0; j < 64; j++) {
|
||||
if (get_framebit(&maj_bits[20*130], frame_off + j))
|
||||
if (frame_get_bit(&maj_bits[20*130], frame_off + j))
|
||||
printf("r%i ma%i clb i%i mi20 bit %i\n",
|
||||
row, major, i-start, j);
|
||||
}
|
||||
for (j = 0; j < 64; j++) {
|
||||
if (get_framebit(&maj_bits[23*130], frame_off + j))
|
||||
if (frame_get_bit(&maj_bits[23*130], frame_off + j))
|
||||
printf("r%i ma%i clb i%i mi23 bit %i\n",
|
||||
row, major, i-start, j);
|
||||
}
|
||||
for (j = 0; j < 64; j++) {
|
||||
if (get_framebit(&maj_bits[26*130], frame_off + j))
|
||||
if (frame_get_bit(&maj_bits[26*130], frame_off + j))
|
||||
printf("r%i ma%i clb i%i mi26 bit %i\n",
|
||||
row, major, i-start, j);
|
||||
}
|
||||
|
@ -822,7 +822,8 @@ static int dump_bits(struct fpga_config* cfg)
|
|||
off = 0;
|
||||
for (row = 0; row < 4; row++) {
|
||||
for (major = 0; major < 18; major++) {
|
||||
if (major == 7) { // MACC
|
||||
// todo: the macc/bram/logic special cases can be removed
|
||||
if (0 && major == 7) { // MACC
|
||||
int last_extra_minor;
|
||||
|
||||
if (!row || row == 3)
|
||||
|
@ -845,14 +846,13 @@ static int dump_bits(struct fpga_config* cfg)
|
|||
for (minor = last_extra_minor+1; minor < 24;
|
||||
minor++) {
|
||||
for (j = 0; j < 256; j++) {
|
||||
if (get_framebit(&cfg->bits.d[off+minor*130], i*256 + ((i>=2)?16:0) + j))
|
||||
if (frame_get_bit(&cfg->bits.d[off+minor*130], i*256 + ((i>=2)?16:0) + j))
|
||||
printf("r%i ma%i dsp i%i mi%i bit %i\n", row, major, i, minor, i*256+j);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (major == 2 || major == 3 || major == 5 || major == 6
|
||||
|| major == 8 || major == 10 || major == 11 || major == 12
|
||||
|| major == 13 || major == 15 || major == 16) { // logic
|
||||
} else if (0 && (major == 2 || major == 5 || major == 8 || major == 10
|
||||
|| major == 12 || major == 15)) { // logic_m
|
||||
minor = 0;
|
||||
while (minor < 20) {
|
||||
minor += printf_frames(&cfg->bits.d[off
|
||||
|
@ -874,7 +874,7 @@ static int dump_bits(struct fpga_config* cfg)
|
|||
|
||||
// clbs
|
||||
printf_clb(&cfg->bits.d[off], row, major);
|
||||
} else if (major == 4 || major == 14) { // bram
|
||||
} else if (0 && (major == 4 || major == 14)) { // bram
|
||||
ramb16_cfg_t ramb16_cfg[4];
|
||||
|
||||
// minors 0..22
|
||||
|
@ -918,7 +918,7 @@ static int dump_bits(struct fpga_config* cfg)
|
|||
row, major, minor, /*print_empty*/ 0);
|
||||
}
|
||||
}
|
||||
off += get_major_minors(XC6SLX9, major) * 130;
|
||||
off += get_major_minors(XC6SLX9, major) * FRAME_SIZE;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
|
22
control.c
22
control.c
|
@ -31,17 +31,17 @@ static const struct iob_site xc6slx9_iob_top[] =
|
|||
|
||||
static const struct iob_site xc6slx9_iob_bottom[] =
|
||||
{
|
||||
{ 5, {"P39", "P38", "P40", "P41"}},
|
||||
{ 7, {"UNB139", "UNB140", "P43", "P44"}},
|
||||
{12, {"P46", "P45", "P47", "P48"}},
|
||||
{14, {"UNB131", "UNB132", "UNB130", "UNB129"}},
|
||||
{19, {"UNB127", "UNB128", "UNB126", "UNB125"}},
|
||||
{21, {"UNB123", "UNB124", "P50", "P51"}},
|
||||
{25, {"P56", "P55", "UNB118", "UNB117"}},
|
||||
{29, {"UNB115", "UNB116", "UNB114", "UNB113"}},
|
||||
{31, {"P58", "P57", "P59", "P60"}},
|
||||
{36, {"P62", "P61", "P64", "P65"}},
|
||||
{38, {"P67", "P66", "P69", "P70"}},
|
||||
{ 5, {"P38", "P39", "P40", "P41"}},
|
||||
{ 7, {"UNB140", "UNB139", "P43", "P44"}},
|
||||
{12, {"P45", "P46", "P47", "P48"}},
|
||||
{14, {"UNB132", "UNB131", "UNB130", "UNB129"}},
|
||||
{19, {"UNB128", "UNB127", "UNB126", "UNB125"}},
|
||||
{21, {"UNB124", "UNB123", "P50", "P51"}},
|
||||
{25, {"P55", "P56", "UNB118", "UNB117"}},
|
||||
{29, {"UNB116", "UNB115", "UNB114", "UNB113"}},
|
||||
{31, {"P57", "P58", "P59", "P60"}},
|
||||
{36, {"P61", "P62", "P64", "P65"}},
|
||||
{38, {"P66", "P67", "P69", "P70"}},
|
||||
};
|
||||
|
||||
static const struct iob_site xc6slx9_iob_left[] =
|
||||
|
|
73
helper.c
73
helper.c
|
@ -6,6 +6,7 @@
|
|||
//
|
||||
|
||||
#include "helper.h"
|
||||
#include "parts.h"
|
||||
|
||||
const char* bitstr(uint32_t value, int digits)
|
||||
{
|
||||
|
@ -480,34 +481,67 @@ int count_bits(uint8_t* d, int l)
|
|||
return bits;
|
||||
}
|
||||
|
||||
int get_framebit(uint8_t* frame_d, int bit)
|
||||
int frame_get_bit(uint8_t* frame_d, int bit)
|
||||
{
|
||||
uint8_t v = 1<<(7-(bit%8));
|
||||
return (frame_d[(bit/16)*2 + !((bit/8)%2)] & v) != 0;
|
||||
}
|
||||
|
||||
void clear_framebit(uint8_t* frame_d, int bit)
|
||||
void frame_clear_bit(uint8_t* frame_d, int bit)
|
||||
{
|
||||
uint8_t v = 1<<(7-(bit%8));
|
||||
frame_d[(bit/16)*2 + !((bit/8)%2)] &= ~v;
|
||||
}
|
||||
|
||||
void set_framebit(uint8_t* frame_d, int bit)
|
||||
void frame_set_bit(uint8_t* frame_d, int bit)
|
||||
{
|
||||
uint8_t v = 1<<(7-(bit%8));
|
||||
frame_d[(bit/16)*2 + !((bit/8)%2)] |= v;
|
||||
}
|
||||
|
||||
uint8_t frame_get_u8(uint8_t* frame_d)
|
||||
{
|
||||
uint8_t v = 0;
|
||||
int i;
|
||||
for (i = 0; i < 8; i++)
|
||||
if (*frame_d & (1<<i)) v |= 1 << (7-i);
|
||||
return v;
|
||||
}
|
||||
|
||||
uint16_t frame_get_u16(uint8_t* frame_d)
|
||||
{
|
||||
uint16_t high_b, low_b;
|
||||
high_b = frame_get_u8(frame_d);
|
||||
low_b = frame_get_u8(frame_d+1);
|
||||
return (high_b << 8) | low_b;
|
||||
}
|
||||
|
||||
uint32_t frame_get_u32(uint8_t* frame_d)
|
||||
{
|
||||
uint32_t high_w, low_w;
|
||||
low_w = frame_get_u16(frame_d);
|
||||
high_w = frame_get_u16(frame_d+2);
|
||||
return (high_w << 16) | low_w;
|
||||
}
|
||||
|
||||
uint64_t frame_get_u64(uint8_t* frame_d)
|
||||
{
|
||||
uint64_t high_w, low_w;
|
||||
low_w = frame_get_u32(frame_d);
|
||||
high_w = frame_get_u32(frame_d+4);
|
||||
return (high_w << 32) | low_w;
|
||||
}
|
||||
|
||||
int printf_frames(uint8_t* bits, int max_frames,
|
||||
int row, int major, int minor, int print_empty)
|
||||
{
|
||||
int i;
|
||||
char prefix[32];
|
||||
int i, i_without_clk;
|
||||
char prefix[128], suffix[128];
|
||||
|
||||
if (row < 0)
|
||||
sprintf(prefix, "f%i ", abs(row));
|
||||
else
|
||||
sprintf(prefix, "r%i ma%i extra mi%i ", row, major, minor);
|
||||
sprintf(prefix, "r%i ma%i mi%i ", row, major, minor);
|
||||
|
||||
if (is_empty(bits, 130)) {
|
||||
for (i = 1; i < max_frames; i++) {
|
||||
|
@ -523,10 +557,19 @@ int printf_frames(uint8_t* bits, int max_frames,
|
|||
return i;
|
||||
}
|
||||
if (count_bits(bits, 130) <= 32) {
|
||||
printf_clock(bits, row, major, minor);
|
||||
for (i = 0; i < 1024; i++) {
|
||||
if (get_framebit(bits, (i >= 512) ? i + 16 : i))
|
||||
for (i = 0; i < FRAME_SIZE*8; i++) {
|
||||
if (!frame_get_bit(bits, i)) continue;
|
||||
if (i >= 512 && i < 528) { // hclk
|
||||
printf("%sbit %i\n", prefix, i);
|
||||
continue;
|
||||
}
|
||||
i_without_clk = i;
|
||||
if (i_without_clk >= 528)
|
||||
i_without_clk -= 16;
|
||||
snprintf(suffix, sizeof(suffix), "64*%i+%i 256*%i+%i",
|
||||
i_without_clk/64, i_without_clk%64,
|
||||
i_without_clk/256, i_without_clk%256);
|
||||
printf("%sbit %i %s\n", prefix, i, suffix);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
@ -541,7 +584,7 @@ void printf_clock(uint8_t* frame, int row, int major, int minor)
|
|||
{
|
||||
int i;
|
||||
for (i = 0; i < 16; i++) {
|
||||
if (get_framebit(frame, 512 + i))
|
||||
if (frame_get_bit(frame, 512 + i))
|
||||
printf("r%i ma%i mi%i clock %i\n",
|
||||
row, major, minor, i);
|
||||
}
|
||||
|
@ -570,7 +613,7 @@ void printf_extrabits(uint8_t* maj_bits, int start_minor, int num_minors,
|
|||
|
||||
for (minor = start_minor; minor < start_minor + num_minors; minor++) {
|
||||
for (bit = start_bit; bit < start_bit + num_bits; bit++) {
|
||||
if (get_framebit(&maj_bits[minor*130], bit))
|
||||
if (frame_get_bit(&maj_bits[minor*130], bit))
|
||||
printf("r%i ma%i extra mi%i bit %i\n",
|
||||
row, major, minor, bit);
|
||||
}
|
||||
|
@ -583,13 +626,13 @@ uint64_t read_lut64(uint8_t* two_minors, int off_in_frame)
|
|||
int j;
|
||||
|
||||
for (j = 0; j < 16; j++) {
|
||||
if (get_framebit(two_minors, off_in_frame+j*2))
|
||||
if (frame_get_bit(two_minors, off_in_frame+j*2))
|
||||
lut64 |= 1LL << (j*4);
|
||||
if (get_framebit(two_minors, off_in_frame+(j*2)+1))
|
||||
if (frame_get_bit(two_minors, off_in_frame+(j*2)+1))
|
||||
lut64 |= 1LL << (j*4+1);
|
||||
if (get_framebit(&two_minors[130], off_in_frame+j*2))
|
||||
if (frame_get_bit(&two_minors[130], off_in_frame+j*2))
|
||||
lut64 |= 1LL << (j*4+2);
|
||||
if (get_framebit(&two_minors[130], off_in_frame+(j*2)+1))
|
||||
if (frame_get_bit(&two_minors[130], off_in_frame+(j*2)+1))
|
||||
lut64 |= 1LL << (j*4+3);
|
||||
}
|
||||
return lut64;
|
||||
|
|
12
helper.h
12
helper.h
|
@ -64,9 +64,15 @@ void printf_ramb16_data(uint8_t* bits, int inpos);
|
|||
|
||||
int is_empty(uint8_t* d, int l);
|
||||
int count_bits(uint8_t* d, int l);
|
||||
int get_framebit(uint8_t* frame_d, int bit);
|
||||
void clear_framebit(uint8_t* frame_d, int bit);
|
||||
void set_framebit(uint8_t* frame_d, int bit);
|
||||
|
||||
int frame_get_bit(uint8_t* frame_d, int bit);
|
||||
void frame_clear_bit(uint8_t* frame_d, int bit);
|
||||
void frame_set_bit(uint8_t* frame_d, int bit);
|
||||
|
||||
uint8_t frame_get_u8(uint8_t* frame_d);
|
||||
uint16_t frame_get_u16(uint8_t* frame_d);
|
||||
uint32_t frame_get_u32(uint8_t* frame_d);
|
||||
uint64_t frame_get_u64(uint8_t* frame_d);
|
||||
|
||||
// if row is negative, it's an absolute frame number and major and
|
||||
// minor are ignored
|
||||
|
|
14
model.h
14
model.h
|
@ -50,6 +50,8 @@
|
|||
/* row 1 */ "WWWUUWUU" "WUUWUUWU" \
|
||||
/* row 0 */ "UWUUWUUW" "UUWWWWUU"
|
||||
|
||||
#define LEFT_SIDE_MAJOR 1
|
||||
|
||||
struct fpga_model
|
||||
{
|
||||
int cfg_rows;
|
||||
|
@ -64,6 +66,12 @@ struct fpga_model
|
|||
// column as indicated in the chip's cfg_columns with a 'g'.
|
||||
int left_gclk_sep_x, right_gclk_sep_x;
|
||||
|
||||
// x_major is an array of column indices for each x coordinate,
|
||||
// starting with column 1 for the left side, and incrementing
|
||||
// through the configuration columns. This corresponds to the
|
||||
// 'majors' in the bitstream.
|
||||
int x_major[512];
|
||||
|
||||
struct fpga_tile* tiles;
|
||||
struct hashed_strarray str;
|
||||
|
||||
|
@ -304,6 +312,12 @@ enum fpgadev_type
|
|||
DEV_SPI_ACCESS
|
||||
};
|
||||
|
||||
// M and L device is always at type index 0, X device
|
||||
// is always at type index 1.
|
||||
#define DEV_LOGM 0
|
||||
#define DEV_LOGL 0
|
||||
#define DEV_LOGX 1
|
||||
|
||||
// All device configuration is structured so that the value
|
||||
// 0 is never a valid configured setting. That way all config
|
||||
// data can safely be initialized to 0 meaning unconfigured.
|
||||
|
|
|
@ -346,8 +346,8 @@ int init_devices(struct fpga_model* model)
|
|||
if ((rc = add_dev(model, y, x, DEV_IOB, IOBS))) goto fail;
|
||||
|
||||
y = model->y_height-BOT_OUTER_ROW;
|
||||
if ((rc = add_dev(model, y, x, DEV_IOB, IOBM))) goto fail;
|
||||
if ((rc = add_dev(model, y, x, DEV_IOB, IOBS))) goto fail;
|
||||
if ((rc = add_dev(model, y, x, DEV_IOB, IOBM))) goto fail;
|
||||
if ((rc = add_dev(model, y, x, DEV_IOB, IOBS))) goto fail;
|
||||
if ((rc = add_dev(model, y, x, DEV_IOB, IOBM))) goto fail;
|
||||
}
|
||||
|
@ -413,7 +413,7 @@ int init_devices(struct fpga_model* model)
|
|||
if (!is_atx(X_LOGIC_COL, model, x))
|
||||
continue;
|
||||
for (y = TOP_IO_TILES; y < model->y_height - BOT_IO_TILES; y++) {
|
||||
// M and L are at index 0, X is at index 1.
|
||||
// M and L are at index 0 (DEV_LOGM and DEV_LOGL), X is at index 1 (DEV_LOGX).
|
||||
if (YX_TILE(model, y, x)->flags & TF_LOGIC_XM_DEV) {
|
||||
if ((rc = add_dev(model, y, x, DEV_LOGIC, LOGIC_M))) goto fail;
|
||||
if ((rc = add_dev(model, y, x, DEV_LOGIC, LOGIC_X))) goto fail;
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
int init_tiles(struct fpga_model* model)
|
||||
{
|
||||
int tile_rows, tile_columns, i, j, k, l, row_top_y, left_side;
|
||||
int start, end, no_io;
|
||||
int start, end, no_io, cur_major;
|
||||
char cur_cfgcol, last_col;
|
||||
struct fpga_tile* tile_i0;
|
||||
|
||||
|
@ -50,7 +50,10 @@ int init_tiles(struct fpga_model* model)
|
|||
//
|
||||
|
||||
left_side = 1; // turn off (=right side) when reaching the 'R' middle column
|
||||
i = 5; // skip left IO columns
|
||||
for (i = 0; i < LEFT_SIDE_WIDTH; i++)
|
||||
model->x_major[i] = LEFT_SIDE_MAJOR;
|
||||
cur_major = LEFT_SIDE_MAJOR+1;
|
||||
// i is now LEFT_SIDE_WIDTH (5)
|
||||
for (j = 0; model->cfg_columns[j]; j++) {
|
||||
cur_cfgcol = model->cfg_columns[j];
|
||||
switch (cur_cfgcol) {
|
||||
|
@ -139,8 +142,12 @@ int init_tiles(struct fpga_model* model)
|
|||
model->tiles[model->center_y*tile_columns + i].type = REGH_ROUTING_XM;
|
||||
model->tiles[model->center_y*tile_columns + i + 1].type = REGH_LOGIC_XM;
|
||||
}
|
||||
i += 2;
|
||||
|
||||
for (k = 0; k < 2; k++)
|
||||
model->x_major[i++] = cur_major;
|
||||
cur_major++;
|
||||
break;
|
||||
|
||||
case 'B':
|
||||
if (next_non_whitespace(&model->cfg_columns[j+1]) == 'g') {
|
||||
if (left_side)
|
||||
|
@ -182,8 +189,12 @@ int init_tiles(struct fpga_model* model)
|
|||
model->tiles[model->center_y*tile_columns + i].type = REGH_BRAM_ROUTING;
|
||||
model->tiles[model->center_y*tile_columns + i + 1].type = REGH_BRAM_ROUTING_VIA;
|
||||
model->tiles[model->center_y*tile_columns + i + 2].type = left_side ? REGH_BRAM_L : REGH_BRAM_R;
|
||||
i += 3;
|
||||
|
||||
for (k = 0; k < 3; k++)
|
||||
model->x_major[i++] = cur_major;
|
||||
cur_major++;
|
||||
break;
|
||||
|
||||
case 'D':
|
||||
model->tiles[i].flags |= TF_FABRIC_ROUTING_COL;
|
||||
model->tiles[i].flags |= TF_ROUTING_NO_IO; // no_io always on for MACC
|
||||
|
@ -219,8 +230,12 @@ int init_tiles(struct fpga_model* model)
|
|||
model->tiles[model->center_y*tile_columns + i].type = REGH_MACC_ROUTING;
|
||||
model->tiles[model->center_y*tile_columns + i + 1].type = REGH_MACC_ROUTING_VIA;
|
||||
model->tiles[model->center_y*tile_columns + i + 2].type = REGH_MACC_L;
|
||||
i += 3;
|
||||
|
||||
for (k = 0; k < 3; k++)
|
||||
model->x_major[i++] = cur_major;
|
||||
cur_major++;
|
||||
break;
|
||||
|
||||
case 'R':
|
||||
if (next_non_whitespace(&model->cfg_columns[j+1]) != 'M') {
|
||||
// We expect a LOGIC_XM column to follow the center for
|
||||
|
@ -320,17 +335,22 @@ int init_tiles(struct fpga_model* model)
|
|||
model->tiles[model->center_y*tile_columns + i + 2].type = REGC_CMT;
|
||||
model->tiles[model->center_y*tile_columns + i + 3].type = CENTER;
|
||||
|
||||
i += 4;
|
||||
for (k = 0; k < 4; k++)
|
||||
model->x_major[i++] = cur_major;
|
||||
cur_major++;
|
||||
break;
|
||||
case ' ': // space used to make string more readable only
|
||||
case 'g': // global clock separator
|
||||
case 'n': // noio for logic blocks
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Ignoring unexpected column identifier '%c'\n", cur_cfgcol);
|
||||
fprintf(stderr, "Ignoring unexpected column "
|
||||
"identifier '%c'\n", cur_cfgcol);
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (k = 0; k < RIGHT_SIDE_WIDTH; k++)
|
||||
model->x_major[i++] = cur_major;
|
||||
|
||||
//
|
||||
// left IO
|
||||
|
|
18
parts.c
18
parts.c
|
@ -8,7 +8,7 @@
|
|||
#include "helper.h"
|
||||
#include "parts.h"
|
||||
|
||||
const char* iob_xc6slx4_sitenames[896*2/8] =
|
||||
const char* iob_xc6slx9_sitenames[IOB_WORDS*2/8] =
|
||||
{
|
||||
[0x0000/8]
|
||||
"P70", "P69", "P67", "P66", "P65", "P64", "P62", "P61",
|
||||
|
@ -54,6 +54,22 @@ const char* iob_xc6slx4_sitenames[896*2/8] =
|
|||
0, 0, 0, 0, 0, 0, "P75", "P74"
|
||||
};
|
||||
|
||||
int get_num_iobs(int idcode)
|
||||
{
|
||||
if ((idcode & IDCODE_MASK) != XC6SLX9)
|
||||
EXIT(1);
|
||||
return sizeof(iob_xc6slx9_sitenames)/sizeof(iob_xc6slx9_sitenames[0]);
|
||||
}
|
||||
|
||||
const char* get_iob_sitename(int idcode, int idx)
|
||||
{
|
||||
if ((idcode & IDCODE_MASK) != XC6SLX9)
|
||||
EXIT(1);
|
||||
if (idx < 0 || idx > sizeof(iob_xc6slx9_sitenames)/sizeof(iob_xc6slx9_sitenames[0]))
|
||||
EXIT(1);
|
||||
return iob_xc6slx9_sitenames[idx];
|
||||
}
|
||||
|
||||
static const int minors_per_major[] = // for slx4 and slx9
|
||||
{
|
||||
/* 0 */ 4, // 505 bytes = middle 8-bit for each minor?
|
||||
|
|
17
parts.h
17
parts.h
|
@ -23,4 +23,21 @@
|
|||
#define XC6SLX100T 0x04031093
|
||||
#define XC6SLX150 0x0401D093
|
||||
|
||||
#define FRAME_SIZE 130
|
||||
#define FRAMES_PER_ROW 505 // for slx4 and slx9
|
||||
#define PADDING_FRAMES_PER_ROW 2
|
||||
#define NUM_ROWS 4 // for slx9 and slx9
|
||||
|
||||
#define FRAMES_DATA_START 0
|
||||
#define FRAMES_DATA_LEN (NUM_ROWS*FRAMES_PER_ROW*FRAME_SIZE)
|
||||
#define BRAM_DATA_START FRAMES_DATA_LEN
|
||||
#define BRAM_DATA_LEN (4*144*FRAME_SIZE)
|
||||
#define IOB_DATA_START (BRAM_DATA_START + BRAM_DATA_LEN)
|
||||
#define IOB_WORDS 896 // 16-bit words, for slx4 and slx9
|
||||
#define IOB_DATA_LEN (IOB_WORDS*2)
|
||||
#define IOB_ENTRY_LEN 8
|
||||
#define BITS_LEN (IOB_DATA_START+IOB_DATA_LEN)
|
||||
|
||||
int get_major_minors(int idcode, int major);
|
||||
int get_num_iobs(int idcode);
|
||||
const char* get_iob_sitename(int idcode, int idx);
|
||||
|
|
Loading…
Reference in New Issue
Block a user