working in model, 0.1%

This commit is contained in:
Wolfgang Spraul 2012-08-20 13:49:51 +02:00
parent d8a18a6034
commit 917c3e7ffd
14 changed files with 320 additions and 75 deletions

View File

@ -33,6 +33,7 @@ static int dump_file(const char* path)
char line[1024]; char line[1024];
FILE* f; FILE* f;
printf("\n");
printf("O begin dump %s\n", path); printf("O begin dump %s\n", path);
f = fopen(path, "r"); f = fopen(path, "r");
EXIT(!f); EXIT(!f);
@ -45,6 +46,7 @@ static int dump_file(const char* path)
} }
fclose(f); fclose(f);
printf("O end dump %s\n", path); printf("O end dump %s\n", path);
printf("\n");
return 0; return 0;
} }
@ -157,17 +159,15 @@ int main(int argc, char** argv)
P48_dev->iob.suspend = SUSP_3STATE; P48_dev->iob.suspend = SUSP_3STATE;
// configure logic // 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); if (!logic_dev) FAIL(EINVAL);
logic_dev->instantiated = 1; logic_dev->instantiated = 1;
logic_dev->logic.D_used = 1; logic_dev->logic.D_used = 1;
rc = fpga_set_lut(&model, logic_dev, D6_LUT, "A3", ZTERM); rc = fpga_set_lut(&model, logic_dev, D6_LUT, "A3", ZTERM);
if (rc) FAIL(rc); if (rc) FAIL(rc);
#if 1
rc = diff_printf(&tstate); rc = diff_printf(&tstate);
if (rc) goto fail; if (rc) goto fail;
#endif
printf("P46 I pinw %s\n", P46_dev->iob.pinw_out_I); printf("P46 I pinw %s\n", P46_dev->iob.pinw_out_I);
for (i = 0;; i++) { for (i = 0;; i++) {

View File

@ -2,7 +2,7 @@
diff -U 0 $1 $2 > ${2%.*}.fp_diff diff -U 0 $1 $2 > ${2%.*}.fp_diff
./fp2bit $2 ${2%.*}.f2b || exit $? ./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" ] if [ "$1" == "/dev/null" ]
then then
diff -U 0 /dev/null ${2%.*}.b2f > ${2%.*}.b2f_diff 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 diff -U 0 ${1%.*}.b2f ${2%.*}.b2f > ${2%.*}.b2f_diff
fi 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 cat ${2%.*}.b2f_diff | sed -e '/^--- /d;/^+++ /d;/^@@ /d' >> ${2%.*}.diff

14
bit.h
View File

@ -57,20 +57,6 @@ enum {
CMD_DESYNC = 13, CMD_IPROG 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_HEADER_STR_LEN 128
#define MAX_REG_ACTIONS 256 #define MAX_REG_ACTIONS 256

View File

@ -12,7 +12,7 @@
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
struct fpga_model model; 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; struct fpga_config config;
// parameters // parameters
@ -20,12 +20,13 @@ int main(int argc, char** argv)
fprintf(stderr, fprintf(stderr,
"\n" "\n"
"%s - bitstream to floorplan\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]); "\n", argv[0], argv[0]);
goto fail; goto fail;
} }
bit_header = 0; bit_header = 0;
bit_regs = 0; bit_regs = 0;
pull_model = 1;
fp_header = 1; fp_header = 1;
file_arg = 1; file_arg = 1;
while (!strncmp(argv[file_arg], "--", 2)) { while (!strncmp(argv[file_arg], "--", 2)) {
@ -33,6 +34,8 @@ int main(int argc, char** argv)
bit_header = 1; bit_header = 1;
else if (!strcmp(argv[file_arg], "--bit-regs")) else if (!strcmp(argv[file_arg], "--bit-regs"))
bit_regs = 1; bit_regs = 1;
else if (!strcmp(argv[file_arg], "--no-model"))
pull_model = 0;
else if (!strcmp(argv[file_arg], "--no-fp-header")) else if (!strcmp(argv[file_arg], "--no-fp-header"))
fp_header = 0; fp_header = 0;
else break; else break;
@ -54,6 +57,7 @@ int main(int argc, char** argv)
// build model and fill from bitstream // build model and fill from bitstream
if ((rc = fpga_build_model(&model, XC6SLX9_ROWS, XC6SLX9_COLUMNS, if ((rc = fpga_build_model(&model, XC6SLX9_ROWS, XC6SLX9_COLUMNS,
XC6SLX9_LEFT_WIRING, XC6SLX9_RIGHT_WIRING))) FAIL(rc); XC6SLX9_LEFT_WIRING, XC6SLX9_RIGHT_WIRING))) FAIL(rc);
if (pull_model)
if ((rc = extract_model(&model, &config.bits))) FAIL(rc); if ((rc = extract_model(&model, &config.bits))) FAIL(rc);
// dump model // dump model

View File

@ -8,6 +8,9 @@
#include "model.h" #include "model.h"
#include "bit.h" #include "bit.h"
#include "parts.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) 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, static int get_bit(struct fpga_bits* bits,
int row, int major, int minor, int bit_i) 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); + minor*FRAME_SIZE, bit_i);
} }
static void set_bit(struct fpga_bits* bits, static void set_bit(struct fpga_bits* bits,
int row, int major, int minor, int bit_i) 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); + minor*FRAME_SIZE, bit_i);
} }
static void clear_bit(struct fpga_bits* bits, static void clear_bit(struct fpga_bits* bits,
int row, int major, int minor, int bit_i) 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); + 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 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++) { for (i = 0; i < sizeof(s_default_bits)/sizeof(s_default_bits[0]); i++) {
if (!get_bitp(bits, &s_default_bits[i])) if (!get_bitp(bits, &s_default_bits[i]))
FAIL(EINVAL); FAIL(EINVAL);
clear_bitp(bits, &s_default_bits[i]); 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; return 0;
fail: fail:
return rc; return rc;

View File

@ -797,17 +797,17 @@ static void printf_clb(uint8_t* maj_bits, int row, int major)
// bits // bits
for (j = 0; j < 64; j++) { 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", printf("r%i ma%i clb i%i mi20 bit %i\n",
row, major, i-start, j); row, major, i-start, j);
} }
for (j = 0; j < 64; 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", printf("r%i ma%i clb i%i mi23 bit %i\n",
row, major, i-start, j); row, major, i-start, j);
} }
for (j = 0; j < 64; 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", printf("r%i ma%i clb i%i mi26 bit %i\n",
row, major, i-start, j); row, major, i-start, j);
} }
@ -822,7 +822,8 @@ static int dump_bits(struct fpga_config* cfg)
off = 0; off = 0;
for (row = 0; row < 4; row++) { for (row = 0; row < 4; row++) {
for (major = 0; major < 18; major++) { 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; int last_extra_minor;
if (!row || row == 3) if (!row || row == 3)
@ -845,14 +846,13 @@ static int dump_bits(struct fpga_config* cfg)
for (minor = last_extra_minor+1; minor < 24; for (minor = last_extra_minor+1; minor < 24;
minor++) { minor++) {
for (j = 0; j < 256; j++) { 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); 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 } else if (0 && (major == 2 || major == 5 || major == 8 || major == 10
|| major == 8 || major == 10 || major == 11 || major == 12 || major == 12 || major == 15)) { // logic_m
|| major == 13 || major == 15 || major == 16) { // logic
minor = 0; minor = 0;
while (minor < 20) { while (minor < 20) {
minor += printf_frames(&cfg->bits.d[off minor += printf_frames(&cfg->bits.d[off
@ -874,7 +874,7 @@ static int dump_bits(struct fpga_config* cfg)
// clbs // clbs
printf_clb(&cfg->bits.d[off], row, major); 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]; ramb16_cfg_t ramb16_cfg[4];
// minors 0..22 // minors 0..22
@ -918,7 +918,7 @@ static int dump_bits(struct fpga_config* cfg)
row, major, minor, /*print_empty*/ 0); row, major, minor, /*print_empty*/ 0);
} }
} }
off += get_major_minors(XC6SLX9, major) * 130; off += get_major_minors(XC6SLX9, major) * FRAME_SIZE;
} }
} }
return 0; return 0;

View File

@ -31,17 +31,17 @@ static const struct iob_site xc6slx9_iob_top[] =
static const struct iob_site xc6slx9_iob_bottom[] = static const struct iob_site xc6slx9_iob_bottom[] =
{ {
{ 5, {"P39", "P38", "P40", "P41"}}, { 5, {"P38", "P39", "P40", "P41"}},
{ 7, {"UNB139", "UNB140", "P43", "P44"}}, { 7, {"UNB140", "UNB139", "P43", "P44"}},
{12, {"P46", "P45", "P47", "P48"}}, {12, {"P45", "P46", "P47", "P48"}},
{14, {"UNB131", "UNB132", "UNB130", "UNB129"}}, {14, {"UNB132", "UNB131", "UNB130", "UNB129"}},
{19, {"UNB127", "UNB128", "UNB126", "UNB125"}}, {19, {"UNB128", "UNB127", "UNB126", "UNB125"}},
{21, {"UNB123", "UNB124", "P50", "P51"}}, {21, {"UNB124", "UNB123", "P50", "P51"}},
{25, {"P56", "P55", "UNB118", "UNB117"}}, {25, {"P55", "P56", "UNB118", "UNB117"}},
{29, {"UNB115", "UNB116", "UNB114", "UNB113"}}, {29, {"UNB116", "UNB115", "UNB114", "UNB113"}},
{31, {"P58", "P57", "P59", "P60"}}, {31, {"P57", "P58", "P59", "P60"}},
{36, {"P62", "P61", "P64", "P65"}}, {36, {"P61", "P62", "P64", "P65"}},
{38, {"P67", "P66", "P69", "P70"}}, {38, {"P66", "P67", "P69", "P70"}},
}; };
static const struct iob_site xc6slx9_iob_left[] = static const struct iob_site xc6slx9_iob_left[] =

View File

@ -6,6 +6,7 @@
// //
#include "helper.h" #include "helper.h"
#include "parts.h"
const char* bitstr(uint32_t value, int digits) const char* bitstr(uint32_t value, int digits)
{ {
@ -480,34 +481,67 @@ int count_bits(uint8_t* d, int l)
return bits; 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)); uint8_t v = 1<<(7-(bit%8));
return (frame_d[(bit/16)*2 + !((bit/8)%2)] & v) != 0; 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)); uint8_t v = 1<<(7-(bit%8));
frame_d[(bit/16)*2 + !((bit/8)%2)] &= ~v; 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)); uint8_t v = 1<<(7-(bit%8));
frame_d[(bit/16)*2 + !((bit/8)%2)] |= v; 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 printf_frames(uint8_t* bits, int max_frames,
int row, int major, int minor, int print_empty) int row, int major, int minor, int print_empty)
{ {
int i; int i, i_without_clk;
char prefix[32]; char prefix[128], suffix[128];
if (row < 0) if (row < 0)
sprintf(prefix, "f%i ", abs(row)); sprintf(prefix, "f%i ", abs(row));
else 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)) { if (is_empty(bits, 130)) {
for (i = 1; i < max_frames; i++) { for (i = 1; i < max_frames; i++) {
@ -523,10 +557,19 @@ int printf_frames(uint8_t* bits, int max_frames,
return i; return i;
} }
if (count_bits(bits, 130) <= 32) { if (count_bits(bits, 130) <= 32) {
printf_clock(bits, row, major, minor); for (i = 0; i < FRAME_SIZE*8; i++) {
for (i = 0; i < 1024; i++) { if (!frame_get_bit(bits, i)) continue;
if (get_framebit(bits, (i >= 512) ? i + 16 : i)) if (i >= 512 && i < 528) { // hclk
printf("%sbit %i\n", prefix, i); 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; return 1;
} }
@ -541,7 +584,7 @@ void printf_clock(uint8_t* frame, int row, int major, int minor)
{ {
int i; int i;
for (i = 0; i < 16; 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", printf("r%i ma%i mi%i clock %i\n",
row, major, minor, i); 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 (minor = start_minor; minor < start_minor + num_minors; minor++) {
for (bit = start_bit; bit < start_bit + num_bits; bit++) { 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", printf("r%i ma%i extra mi%i bit %i\n",
row, major, minor, bit); row, major, minor, bit);
} }
@ -583,13 +626,13 @@ uint64_t read_lut64(uint8_t* two_minors, int off_in_frame)
int j; int j;
for (j = 0; j < 16; 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); 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); 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); 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); lut64 |= 1LL << (j*4+3);
} }
return lut64; return lut64;

View File

@ -64,9 +64,15 @@ void printf_ramb16_data(uint8_t* bits, int inpos);
int is_empty(uint8_t* d, int l); int is_empty(uint8_t* d, int l);
int count_bits(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); int frame_get_bit(uint8_t* frame_d, int bit);
void set_framebit(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 // if row is negative, it's an absolute frame number and major and
// minor are ignored // minor are ignored

14
model.h
View File

@ -50,6 +50,8 @@
/* row 1 */ "WWWUUWUU" "WUUWUUWU" \ /* row 1 */ "WWWUUWUU" "WUUWUUWU" \
/* row 0 */ "UWUUWUUW" "UUWWWWUU" /* row 0 */ "UWUUWUUW" "UUWWWWUU"
#define LEFT_SIDE_MAJOR 1
struct fpga_model struct fpga_model
{ {
int cfg_rows; int cfg_rows;
@ -64,6 +66,12 @@ struct fpga_model
// column as indicated in the chip's cfg_columns with a 'g'. // column as indicated in the chip's cfg_columns with a 'g'.
int left_gclk_sep_x, right_gclk_sep_x; 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 fpga_tile* tiles;
struct hashed_strarray str; struct hashed_strarray str;
@ -304,6 +312,12 @@ enum fpgadev_type
DEV_SPI_ACCESS 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 // All device configuration is structured so that the value
// 0 is never a valid configured setting. That way all config // 0 is never a valid configured setting. That way all config
// data can safely be initialized to 0 meaning unconfigured. // data can safely be initialized to 0 meaning unconfigured.

View File

@ -346,8 +346,8 @@ int init_devices(struct fpga_model* model)
if ((rc = add_dev(model, y, x, DEV_IOB, IOBS))) goto fail; if ((rc = add_dev(model, y, x, DEV_IOB, IOBS))) goto fail;
y = model->y_height-BOT_OUTER_ROW; 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, 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, IOBS))) goto fail;
if ((rc = add_dev(model, y, x, DEV_IOB, IOBM))) 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)) if (!is_atx(X_LOGIC_COL, model, x))
continue; continue;
for (y = TOP_IO_TILES; y < model->y_height - BOT_IO_TILES; y++) { 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 (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_M))) goto fail;
if ((rc = add_dev(model, y, x, DEV_LOGIC, LOGIC_X))) goto fail; if ((rc = add_dev(model, y, x, DEV_LOGIC, LOGIC_X))) goto fail;

View File

@ -11,7 +11,7 @@
int init_tiles(struct fpga_model* model) int init_tiles(struct fpga_model* model)
{ {
int tile_rows, tile_columns, i, j, k, l, row_top_y, left_side; 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; char cur_cfgcol, last_col;
struct fpga_tile* tile_i0; 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 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++) { for (j = 0; model->cfg_columns[j]; j++) {
cur_cfgcol = model->cfg_columns[j]; cur_cfgcol = model->cfg_columns[j];
switch (cur_cfgcol) { 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].type = REGH_ROUTING_XM;
model->tiles[model->center_y*tile_columns + i + 1].type = REGH_LOGIC_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; break;
case 'B': case 'B':
if (next_non_whitespace(&model->cfg_columns[j+1]) == 'g') { if (next_non_whitespace(&model->cfg_columns[j+1]) == 'g') {
if (left_side) 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].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 + 1].type = REGH_BRAM_ROUTING_VIA;
model->tiles[model->center_y*tile_columns + i + 2].type = left_side ? REGH_BRAM_L : REGH_BRAM_R; 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; break;
case 'D': case 'D':
model->tiles[i].flags |= TF_FABRIC_ROUTING_COL; model->tiles[i].flags |= TF_FABRIC_ROUTING_COL;
model->tiles[i].flags |= TF_ROUTING_NO_IO; // no_io always on for MACC 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].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 + 1].type = REGH_MACC_ROUTING_VIA;
model->tiles[model->center_y*tile_columns + i + 2].type = REGH_MACC_L; 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; break;
case 'R': case 'R':
if (next_non_whitespace(&model->cfg_columns[j+1]) != 'M') { if (next_non_whitespace(&model->cfg_columns[j+1]) != 'M') {
// We expect a LOGIC_XM column to follow the center for // 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 + 2].type = REGC_CMT;
model->tiles[model->center_y*tile_columns + i + 3].type = CENTER; 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; break;
case ' ': // space used to make string more readable only case ' ': // space used to make string more readable only
case 'g': // global clock separator case 'g': // global clock separator
case 'n': // noio for logic blocks case 'n': // noio for logic blocks
break; break;
default: default:
fprintf(stderr, "Ignoring unexpected column identifier '%c'\n", cur_cfgcol); fprintf(stderr, "Ignoring unexpected column "
"identifier '%c'\n", cur_cfgcol);
break; break;
} }
} }
for (k = 0; k < RIGHT_SIDE_WIDTH; k++)
model->x_major[i++] = cur_major;
// //
// left IO // left IO

18
parts.c
View File

@ -8,7 +8,7 @@
#include "helper.h" #include "helper.h"
#include "parts.h" #include "parts.h"
const char* iob_xc6slx4_sitenames[896*2/8] = const char* iob_xc6slx9_sitenames[IOB_WORDS*2/8] =
{ {
[0x0000/8] [0x0000/8]
"P70", "P69", "P67", "P66", "P65", "P64", "P62", "P61", "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" 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 static const int minors_per_major[] = // for slx4 and slx9
{ {
/* 0 */ 4, // 505 bytes = middle 8-bit for each minor? /* 0 */ 4, // 505 bytes = middle 8-bit for each minor?

17
parts.h
View File

@ -23,4 +23,21 @@
#define XC6SLX100T 0x04031093 #define XC6SLX100T 0x04031093
#define XC6SLX150 0x0401D093 #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_major_minors(int idcode, int major);
int get_num_iobs(int idcode);
const char* get_iob_sitename(int idcode, int idx);