mirror of https://github.com/YosysHQ/icestorm.git
Import of icestorm-snapshot-150401.zip
This commit is contained in:
parent
dfeb92a46b
commit
0347c37d56
|
|
@ -27,10 +27,12 @@ class iceconfig:
|
|||
def clear(self):
|
||||
self.max_x = 0
|
||||
self.max_y = 0
|
||||
self.device = ""
|
||||
self.logic_tiles = dict()
|
||||
self.io_tiles = dict()
|
||||
self.ram_tiles = dict()
|
||||
self.ram_init = dict()
|
||||
self.extra_bits = set()
|
||||
|
||||
def setup_empty_1k(self):
|
||||
self.clear()
|
||||
|
|
@ -52,6 +54,12 @@ class iceconfig:
|
|||
self.io_tiles[(0, y)] = ["0" * 18 for i in range(16)]
|
||||
self.io_tiles[(self.max_x, y)] = ["0" * 18 for i in range(16)]
|
||||
|
||||
def lookup_extra_bit(self, bit):
|
||||
assert self.device in extra_bits_db
|
||||
if bit in extra_bits_db[self.device]:
|
||||
return extra_bits_db[self.device][bit]
|
||||
return ("UNKNOWN_FUNCTION",)
|
||||
|
||||
def tile(self, x, y):
|
||||
if (x, y) in self.io_tiles: return self.io_tiles[(x, y)]
|
||||
if (x, y) in self.logic_tiles: return self.logic_tiles[(x, y)]
|
||||
|
|
@ -354,6 +362,8 @@ class iceconfig:
|
|||
assert expected_data_lines == 0
|
||||
continue
|
||||
if line[0][0] != ".":
|
||||
if expected_data_lines == -1:
|
||||
continue
|
||||
if line[0][0] != "0" and line[0][0] != "1":
|
||||
print("%sWarning: ignoring data block in line %d: %s" % (logprefix, linenum, linetext.strip()))
|
||||
expected_data_lines = 0
|
||||
|
|
@ -362,7 +372,7 @@ class iceconfig:
|
|||
current_data.append(line[0])
|
||||
expected_data_lines -= 1
|
||||
continue
|
||||
assert expected_data_lines == 0
|
||||
assert expected_data_lines <= 0
|
||||
if line[0] in (".io_tile", ".logic_tile", ".ram_tile"):
|
||||
current_data = list()
|
||||
expected_data_lines = 16
|
||||
|
|
@ -377,8 +387,15 @@ class iceconfig:
|
|||
if line[0] == ".ram_tile":
|
||||
self.ram_tiles[(int(line[1]), int(line[2]))] = current_data
|
||||
continue
|
||||
if line[0] == ".extra_bit":
|
||||
self.extra_bits.add((int(line[1]), int(line[2]), int(line[3])))
|
||||
continue
|
||||
if line[0] == ".device":
|
||||
assert line[1] == "1k"
|
||||
assert line[1] in ["1k"]
|
||||
self.device = line[1]
|
||||
continue
|
||||
if line[0] == ".comment":
|
||||
expected_data_lines = -1
|
||||
continue
|
||||
print("%sWarning: ignoring line %d: %s" % (logprefix, linenum, linetext.strip()))
|
||||
|
||||
|
|
@ -770,6 +787,12 @@ def parse_db(text):
|
|||
db.append(line)
|
||||
return db
|
||||
|
||||
extra_bits_db = {
|
||||
"1k": {
|
||||
(0, 331, 142): ("routing", "padin_1", "glb_netwk_1")
|
||||
}
|
||||
}
|
||||
|
||||
iotile_full_db = parse_db(iceboxdb.database_io_txt)
|
||||
logictile_db = parse_db(iceboxdb.database_logic_txt)
|
||||
ramtile_db = parse_db(iceboxdb.database_ram_txt)
|
||||
|
|
|
|||
|
|
@ -153,5 +153,11 @@ for idx in ic.logic_tiles:
|
|||
|
||||
for idx in ic.ram_tiles:
|
||||
print_tile(".ram_tile %d %d" % idx, ic, idx[0], idx[1], ic.ram_tiles[idx], ic.tile_db(idx[0], idx[1]))
|
||||
|
||||
for bit in ic.extra_bits:
|
||||
print()
|
||||
print(".extra_bit %d %d %d" % bit)
|
||||
print(" ".join(ic.lookup_extra_bit(bit)))
|
||||
|
||||
print()
|
||||
|
||||
|
|
|
|||
|
|
@ -1,25 +1,29 @@
|
|||
|
||||
CC = clang
|
||||
CXX = clang
|
||||
LDFLAGS = -lm -lstdc++
|
||||
CFLAGS = -MD -Os -Wall -std=c99
|
||||
CXXFLAGS = -MD -Os -Wall -std=c99
|
||||
LDLIBS = -lm -lstdc++
|
||||
CXXFLAGS = -MD -O0 -ggdb -Wall -std=c++11
|
||||
|
||||
all: iceunpack
|
||||
all: icepack iceunpack
|
||||
|
||||
iceunpack: iceunpack.o
|
||||
icepack: icepack.o
|
||||
|
||||
iceunpack: icepack
|
||||
ln -sf icepack iceunpack
|
||||
|
||||
install: all
|
||||
cp iceunpack /usr/local/bin/iceunpack
|
||||
cp icepack /usr/local/bin/icepack
|
||||
ln -s icepack /usr/local/bin/iceunpack
|
||||
|
||||
uninstall:
|
||||
rm -f /usr/local/bin/icepack
|
||||
rm -f /usr/local/bin/iceunpack
|
||||
|
||||
clean:
|
||||
rm -f icepack
|
||||
rm -f iceunpack
|
||||
rm -f *.o *.d
|
||||
|
||||
-include *.d
|
||||
|
||||
.PHONY: install uninstall clean
|
||||
.PHONY: all install uninstall clean
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,368 +0,0 @@
|
|||
// Written by Mathias Lasser
|
||||
// License terms are unclear at the moment
|
||||
|
||||
#include<stdio.h>
|
||||
#include<stdbool.h>
|
||||
#include<stdlib.h>
|
||||
#include<stdint.h>
|
||||
#include<string.h>
|
||||
|
||||
int enable_debug=0;
|
||||
#define debugf(...) do{if(enable_debug)fprintf(stderr,__VA_ARGS__);}while(0)
|
||||
|
||||
#pragma pack(2)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t bfType;
|
||||
uint32_t bfSize;
|
||||
uint16_t bfReserved1;
|
||||
uint16_t bfReserved2;
|
||||
uint32_t bfOffBits;
|
||||
}BITMAPFILEHEADER;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t biSize;
|
||||
uint32_t biWidth;
|
||||
uint32_t biHeight;
|
||||
uint16_t biPlanes;
|
||||
uint16_t biBitCount;
|
||||
uint32_t biCompression;
|
||||
uint32_t biSizeImage;
|
||||
uint32_t biXPelsPerMeter;
|
||||
uint32_t biYPelsPerMeter;
|
||||
uint32_t biClrUsed;
|
||||
uint32_t biClrImportant;
|
||||
}BITMAPINFOHEADER;
|
||||
|
||||
typedef struct{
|
||||
uint16_t boot_mode;
|
||||
uint16_t crc;
|
||||
uint8_t freq;
|
||||
uint8_t bank;
|
||||
uint32_t write_pointer;
|
||||
|
||||
uint32_t CRAM_rowsize;
|
||||
uint32_t CRAM_colsize;
|
||||
uint8_t* CRAM[4];
|
||||
uint32_t BRAM_rowsize;
|
||||
uint32_t BRAM_colsize;
|
||||
uint8_t* BRAM[4];
|
||||
}FPGA_t;
|
||||
|
||||
typedef struct{
|
||||
uint32_t len;
|
||||
uint32_t pointer;
|
||||
uint16_t crc;
|
||||
uint8_t payload[0];
|
||||
}bitstream_t;
|
||||
|
||||
typedef union{
|
||||
struct{
|
||||
uint8_t lo:4;
|
||||
uint8_t hi:4;
|
||||
};
|
||||
uint8_t full;
|
||||
}nibble_t;
|
||||
|
||||
const char* freq_settings[]={"low","medium","high"};
|
||||
const char* boot_settings[]={"Disable","Enable"};
|
||||
|
||||
uint16_t crc16(uint32_t crc,uint8_t in){
|
||||
for(int i=7;i>=0;i--){
|
||||
crc<<=1;
|
||||
if((crc^(in<<(16-i)))&0x10000)
|
||||
crc^=0x1021;
|
||||
}
|
||||
return crc;
|
||||
}
|
||||
|
||||
uint32_t get_byte(bitstream_t* bitstream){
|
||||
if(bitstream->pointer>=bitstream->len)return 0xFFFFFF;
|
||||
uint8_t data=bitstream->payload[bitstream->pointer++];
|
||||
bitstream->crc=crc16(bitstream->crc,data);
|
||||
return data;
|
||||
}
|
||||
|
||||
uint32_t get_payload(bitstream_t* bitstream,int len){
|
||||
uint32_t ret=get_byte(bitstream);
|
||||
for(int i=1;i<len&&ret!=0xFFFFFFFF;i++){
|
||||
ret<<=8;
|
||||
ret|=get_byte(bitstream);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void FPGA_write(FPGA_t* FPGA,bitstream_t* bitstream){
|
||||
int n=FPGA->CRAM_colsize*FPGA->CRAM_rowsize/8;
|
||||
uint8_t* temp=(uint8_t*)malloc(n);
|
||||
for(int i=0;i<n;i++)
|
||||
temp[i]=get_byte(bitstream);
|
||||
FPGA->CRAM[FPGA->bank]=temp;
|
||||
}
|
||||
|
||||
void FPGA_EBR_write(FPGA_t* FPGA,bitstream_t* bitstream){
|
||||
int n=FPGA->BRAM_colsize*FPGA->BRAM_rowsize/8;
|
||||
uint8_t* temp=(uint8_t*)malloc(FPGA->write_pointer+n);
|
||||
if(FPGA->write_pointer!=0){
|
||||
uint8_t* old_data=FPGA->BRAM[FPGA->bank];
|
||||
memcpy(temp,old_data,FPGA->write_pointer);
|
||||
free(old_data);
|
||||
}
|
||||
for(int i=0;i<n;i++)temp[FPGA->write_pointer++]=get_byte(bitstream);
|
||||
FPGA->BRAM[FPGA->bank]=temp;
|
||||
}
|
||||
|
||||
int parse(bitstream_t* bitstream, FPGA_t* FPGA) {
|
||||
uint32_t preamble=0;
|
||||
while(1){
|
||||
preamble<<=8;
|
||||
preamble|=get_byte(bitstream);
|
||||
if(preamble==0x7EAA997E){
|
||||
debugf("Got preamble\n");
|
||||
break;
|
||||
}
|
||||
if(preamble==0xFFFFFFFF){
|
||||
fprintf(stderr,"Error: could not find preamble...\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
nibble_t command;
|
||||
uint32_t payload;
|
||||
uint16_t crc;
|
||||
while(1){
|
||||
crc=bitstream->crc;
|
||||
command.full=get_byte(bitstream);
|
||||
if(command.full==0xFF){
|
||||
payload=get_byte(bitstream);
|
||||
if(payload!=0x00)goto err;
|
||||
char*comment=(char*)&bitstream->payload[bitstream->pointer];
|
||||
debugf("Got comment section start\n");
|
||||
while(1){
|
||||
payload<<=8;
|
||||
payload|=get_byte(bitstream);
|
||||
if((payload&0xFFFF)==0x00FF)break;
|
||||
if(payload==0xFFFFFFFF){
|
||||
fprintf(stderr,"Error: could not find comment section end\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
debugf("\n%s\n\n",comment);
|
||||
debugf("Got comment section end\n");
|
||||
continue;
|
||||
}
|
||||
payload=get_payload(bitstream,command.lo);
|
||||
switch(command.hi){
|
||||
case 0x0:
|
||||
if(command.lo!=0x01)goto err;
|
||||
switch(payload){
|
||||
case 0x01:
|
||||
debugf("Write to CRAM!!!\n");
|
||||
FPGA_write(FPGA,bitstream);
|
||||
get_payload(bitstream,2);
|
||||
break;
|
||||
case 0x03:
|
||||
debugf("Write to BRAM!!!\n");
|
||||
FPGA_EBR_write(FPGA,bitstream);
|
||||
get_payload(bitstream,2);
|
||||
break;
|
||||
case 0x05:
|
||||
debugf("Resetting CRC\n");
|
||||
bitstream->crc=0;
|
||||
break;
|
||||
case 0x06:
|
||||
debugf("Wake up\n");
|
||||
return 0;
|
||||
default:
|
||||
goto err;
|
||||
}
|
||||
break;
|
||||
case 0x1:
|
||||
if(command.lo!=0x01)goto err;
|
||||
if(payload>3){
|
||||
fprintf(stderr,"Error: bank %u does not exist...\n",payload);
|
||||
}
|
||||
debugf("Set bank to %u\n",payload);
|
||||
FPGA->bank=payload;
|
||||
break;
|
||||
case 0x2:
|
||||
if(command.lo!=0x02)goto err;
|
||||
debugf("CRC check: %04X %04X\n",payload,crc);
|
||||
break;
|
||||
case 0x5:
|
||||
if(command.lo!=0x01)goto err;
|
||||
if(payload>2){
|
||||
fprintf(stderr,"Error: unknown frequency setting...\n");
|
||||
return -1;
|
||||
}
|
||||
debugf("Boot frequency set to %s\n",freq_settings[payload]);
|
||||
FPGA->freq=payload;
|
||||
break;
|
||||
case 0x6:
|
||||
if(command.lo!=0x02)goto err;
|
||||
payload++;
|
||||
debugf("Row size: %i\n",payload);
|
||||
if(FPGA->CRAM_rowsize)FPGA->BRAM_rowsize=payload;
|
||||
else FPGA->CRAM_rowsize=payload;
|
||||
break;
|
||||
case 0x7:
|
||||
if(command.lo!=0x02)goto err;
|
||||
debugf("Column size: %i\n",payload);
|
||||
if(FPGA->CRAM_colsize)FPGA->BRAM_colsize=payload;
|
||||
else FPGA->CRAM_colsize=payload;
|
||||
break;
|
||||
case 0x8:
|
||||
if(command.lo!=0x02)goto err;
|
||||
if(payload==0x0000){
|
||||
debugf("Reset write pointer\n");
|
||||
FPGA->write_pointer=0;
|
||||
}
|
||||
else if(payload==0x0080){
|
||||
debugf("Don't reset write pointer\n");
|
||||
}
|
||||
else goto err;
|
||||
break;
|
||||
case 0x9:
|
||||
if(command.lo!=0x02)goto err;
|
||||
if(payload&0xFFDF){
|
||||
fprintf(stderr,"Error: Unknown warmboot setting... %04X\n",payload);
|
||||
return -1;
|
||||
}
|
||||
debugf("%s warmboot\n",boot_settings[payload?1:0]);
|
||||
FPGA->boot_mode=payload;
|
||||
break;
|
||||
default:
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
err:
|
||||
fprintf(stderr,"Error: unkown command... %08X\n",bitstream->pointer);
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint8_t get_CRAM_bit_from_sector(FPGA_t* FPGA,int bank,int x,int y){
|
||||
if(x<0||x>=FPGA->CRAM_rowsize)return 0xFF;
|
||||
if(y<0||y>=FPGA->CRAM_colsize)return 0xFF;
|
||||
if(bank<0||bank>=4)return 0xFF;
|
||||
|
||||
|
||||
int bit=y*FPGA->CRAM_rowsize+x;
|
||||
int pointer=bit>>3;
|
||||
int shifts=7-(bit&7);
|
||||
return (FPGA->CRAM[bank][pointer]>>shifts)&1;
|
||||
}
|
||||
|
||||
int tiles[2][20]={
|
||||
{18,54,54,42,54,54,54},
|
||||
{18,2,54,54,54,54,54,54,54,42,54,54,54,54,54,54,54,54}
|
||||
};
|
||||
|
||||
int permx[2][18]={
|
||||
{23,25,26,27,16,17,18,19,20,14,32,33,34,35,36,37,4,5},
|
||||
{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17}};
|
||||
int permy[4][16]={
|
||||
{0,1,3,2,4,5,7,6,8,9,11,10,12,13,15,14},
|
||||
{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15},
|
||||
};
|
||||
|
||||
int tile_row_size[2]={7,17};
|
||||
int tile_col_size[2]={9,17};
|
||||
|
||||
void print_tile(FPGA_t* FPGA,int x,int y){
|
||||
int type=FPGA->CRAM_rowsize==872;
|
||||
int dirx=0;
|
||||
int diry=0;
|
||||
int tx=x;
|
||||
int ty=y;
|
||||
|
||||
int corner_flags=0;
|
||||
if(x==0)corner_flags|=1;
|
||||
if(y==0)corner_flags|=2;
|
||||
if(x==tile_row_size[type]*2-1)corner_flags|=4;
|
||||
if(y==tile_col_size[type]*2-1)corner_flags|=8;
|
||||
if(corner_flags&(corner_flags-1))
|
||||
return;
|
||||
|
||||
if(x>=tile_row_size[type]){
|
||||
dirx=1;
|
||||
tx=tile_row_size[type]*2-1-x;
|
||||
}
|
||||
if(y>=tile_col_size[type]){
|
||||
diry=1;
|
||||
ty=tile_col_size[type]*2-1-y;
|
||||
}
|
||||
int sector=(diry|dirx<<1);
|
||||
int offx=0;for(int i=0;i<tx;i++)offx+=tiles[type][i];
|
||||
if(corner_flags){
|
||||
printf(".io_tile %i %i\n",x,y);
|
||||
for(int cy=0;cy<16;cy++){
|
||||
for(int cx=0;cx<18;cx++){
|
||||
int val;
|
||||
if(corner_flags&5){
|
||||
if(diry){
|
||||
val=get_CRAM_bit_from_sector(FPGA,sector,offx+tiles[type][tx]-1-permx[1][cx],ty*16+15-permy[1][cy]);
|
||||
}else{
|
||||
val=get_CRAM_bit_from_sector(FPGA,sector,offx+tiles[type][tx]-1-permx[1][cx],ty*16+permy[1][cy]);
|
||||
}
|
||||
}else{
|
||||
if(dirx){
|
||||
val=get_CRAM_bit_from_sector(FPGA,sector,offx+tiles[type][tx]-1-permx[0][cx],ty*16+15-permy[0][cy]);
|
||||
}else{
|
||||
val=get_CRAM_bit_from_sector(FPGA,sector,offx+permx[0][cx],ty*16+15-permy[0][cy]);
|
||||
}
|
||||
}
|
||||
printf("%i",val);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
else{
|
||||
if(tiles[type][tx]==20)printf(".io_tile %i %i\n",x,y);
|
||||
if(tiles[type][tx]==42)printf(".ram_tile %i %i\n",x,y);
|
||||
if(tiles[type][tx]==54)printf(".logic_tile %i %i\n",x,y);
|
||||
for(int cy=0;cy<16;cy++){
|
||||
for(int cx=0;cx<tiles[type][tx];cx++){
|
||||
printf("%i",get_CRAM_bit_from_sector(FPGA,sector,(dirx?(offx+tiles[type][tx]-1-cx):(offx+cx)),(diry?(ty*16+(15-cy)):(ty*16+cy))));
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc,char**argv) {
|
||||
if(argc>=2&&!strcmp(argv[1], "-v")) {
|
||||
enable_debug=1;
|
||||
argc--;
|
||||
argv++;
|
||||
}
|
||||
if(argc!=2) {
|
||||
fprintf(stderr,"iceunpack [-v] input\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
FILE*r_file=fopen(argv[1],"rb");
|
||||
if(r_file==NULL) {
|
||||
fprintf(stderr,"could not open %s\n",argv[1]);
|
||||
return 1;
|
||||
}
|
||||
fseek(r_file,0,SEEK_END);
|
||||
size_t r_size=ftell(r_file);
|
||||
fseek(r_file,0,SEEK_SET);
|
||||
|
||||
bitstream_t* bitstream=(bitstream_t*)malloc(sizeof(bitstream_t)+r_size);
|
||||
bitstream->len=r_size;
|
||||
bitstream->pointer=0;
|
||||
fread(bitstream->payload,1,r_size,r_file);
|
||||
fclose(r_file);
|
||||
|
||||
FPGA_t FPGA;
|
||||
memset(&FPGA,0,sizeof(FPGA));
|
||||
|
||||
parse(bitstream,&FPGA);
|
||||
free(bitstream);
|
||||
|
||||
printf(".device 1k\n");
|
||||
for(int y=0;y<18;y++)for(int x=0;x<14;x++)print_tile(&FPGA,x,y);
|
||||
return 0;
|
||||
}
|
||||
Loading…
Reference in New Issue