[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [partial-reconfig] Virtex-4 bitstream



On Tue, Feb 14, 2006 at 12:06:30PM +0100, kw@xxxxxxxxxx wrote:

> if you know the part number, then you just knows the addressing. it's
> hard-coded in the ise. The way to figure it out is to create a partial
> stream which only modify a small part of the circuit that you understand
> well, e.g. one or two frames manually modified in FPGA editor by yourself,
> and open the partial bitfile with hex editor to study it. And i remember
> there use to be some xilinx documents on how the bit file works on older
> virtex. putting all these small pieces together, and you get it.

OT, I have used the attached programs (bitdiff/decode_bit.c) for decoding
and diffing .bit files for Spartan3 devices, and I have decoded quite a
bit of the bitstream format this way.  (But didn't have time to work on
it for a while now.)


=== bitdiff
#!/bin/sh

if [ ! -f "$1" -o ! -f "$2" ]
then
	echo syntax: $0 oldfile.bit newfile.bit >&2
	exit 1
fi

FILE1=`mktemp /tmp/bitdiff-XXXXXX`
FILE2=`mktemp /tmp/bitdiff-XXXXXX`

decode_bit < $1 > $FILE1 2>/dev/null
decode_bit < $2 > $FILE2 2>/dev/null

diff -u $FILE1 $FILE2
rm -f $FILE1 $FILE2
=== decode_bit.c
/*
 * Simple program to decode .bit files.
 *
 * Copyright (C) 2005 Lennert Buytenhek <buytenh@xxxxxxxxxxxxxx>
 */

#include <stdio.h>
#include <stdlib.h>
#include <netinet/in.h>

u_int32_t flr_plus_one;

static void read_until_ff(void)
{
	u_int32_t blah;

	blah = 0;
	while (blah != 0xffffffff) {
		u_int8_t c;

		if (fread(&c, 1, 1, stdin) != 1) {
			fprintf(stderr, "EOF while looking for sync word\n");
			exit(-1);
		}
		blah = (blah << 8) | c;
	}
}

static int read_u32(u_int32_t *x)
{
	u_int32_t w;

	if (fread(&w, 4, 1, stdin) == 1) {
		*x = ntohl(w);
		return 1;
	}

	return 0;
}

static char *reg_name(int reg)
{
	switch (reg) {
	case 0:	return "CRC";
	case 1: return "FAR";
	case 2: return "FDRI";
	case 3: return "FDRO";
	case 4: return "CMD";
	case 5: return "CTL";
	case 6: return "MASK";
	case 7: return "STAT";
	case 8: return "LOUT";
	case 9: return "COR";
	case 10:	return "MFWR";
	case 11:	return "FLR";
	case 14:	return "IDCODE";
	case 15:	return "SNOWPLOW";
	}

	return "unknown";
}

static char *cmd_code(int cmd)
{
	switch (cmd) {
	case 0:	return "NULL";
	case 1: return "WCFG";
	case 2: return "MFWR";
	case 3: return "DGHIGH/LFRM";
	case 4:	return "RCFG";
	case 5: return "START";
	case 6:	return "RCAP";
	case 7:	return "RCRC";
	case 8:	return "AGHIGH";
	case 9:	return "SWITCH";
	case 10:	return "GRESTORE";
	case 11:	return "SHUTDOWN";
	case 12:	return "GCAPTURE";
	case 13:	return "DESYNCH";
	}

	return "unknown";
}

static void decode_type1_hdr(int reg, int num)
{
	int i;

	printf("WRITE REG %s(%d) ", reg_name(reg), reg);
	printf("with %.8x words: ", num);

	for (i=0;i<num;i++) {
		u_int32_t w;

		if (!read_u32(&w)) {
			fprintf(stderr, "EOF while writing register\n");
			exit(-1);
		}

		if (reg == 4 && num == 1) {
			printf("%s(%d)", cmd_code(w), w);
		} else {
			printf("%.8x ", w);
			if (reg == 11 && num == 1)
				flr_plus_one = w + 1;
		}
	}
	printf("\n");
}

static void decode_type2_hdr(int reg)
{
	u_int32_t r;
	int num;
	int i;

	if (!read_u32(&r)) {
		fprintf(stderr, "EOF while reading type2 header\n");
		exit(-1);
	}

	if ((r & 0xf8000000) != 0x50000000) {
		fprintf(stderr, "incorrect type2 header\n");
		exit(-1);
	}

	if (flr_plus_one == 0)
		flr_plus_one = 37;

	printf("WRITE REG %s(%d) ", reg_name(reg), reg);

	num = r & 0x07ffffff;
	printf("with %.8x words:\n", num);

	for (i=0;i<num;i++) {
		u_int32_t w;

		if (!read_u32(&w)) {
			fprintf(stderr, "EOF while writing register\n");
			exit(-1);
		}

		printf("%4d,%3d: %.8x\n", i / flr_plus_one, i % flr_plus_one, w);
	}
	printf("\n");
}

int main()
{
	read_until_ff();
	while (1) {
		u_int32_t word;

		if (!read_u32(&word))
			break;

		if (word == 0xaa995566) {
			printf("SYNC WORD (aa995566)\n");
			continue;
		}

		if (word == 0x20000000) {
			printf("NOP\n");
			continue;
		}

		if ((word & 0xf8000000) == 0x30000000) {
			int reg;
			int num;

			reg = (word >> 13) & 0x3fff;
			num = word & 0x7ff;

			if (num)
				decode_type1_hdr(reg, num);
			else
				decode_type2_hdr(reg);

			continue;
		}

		printf("unknown word %.8x\n", word);
	}

	return 0;
}
___________________________
partial-reconfig mailing list
partial-reconfig@xxxxxxxxxxxxxx
Mailing List Archive : http://www.itee.uq.edu.au/~listarch/partial-reconfig/