aboutsummaryrefslogtreecommitdiffstats
path: root/icepack
diff options
context:
space:
mode:
Diffstat (limited to 'icepack')
-rw-r--r--icepack/Makefile5
-rw-r--r--icepack/icepack.cc159
2 files changed, 152 insertions, 12 deletions
diff --git a/icepack/Makefile b/icepack/Makefile
index 75f81e7..469e34a 100644
--- a/icepack/Makefile
+++ b/icepack/Makefile
@@ -1,5 +1,4 @@
-
-CXX = clang
+# CXX = clang
LDLIBS = -lm -lstdc++
CXXFLAGS = -MD -O0 -ggdb -Wall -std=c++11
@@ -12,7 +11,7 @@ iceunpack: icepack
install: all
cp icepack /usr/local/bin/icepack
- ln -s icepack /usr/local/bin/iceunpack
+ ln -sf icepack /usr/local/bin/iceunpack
uninstall:
rm -f /usr/local/bin/icepack
diff --git a/icepack/icepack.cc b/icepack/icepack.cc
index f243e15..85531b1 100644
--- a/icepack/icepack.cc
+++ b/icepack/icepack.cc
@@ -110,6 +110,7 @@ struct FpgaConfig
// netpbm i/o
void write_cram_pbm(std::ostream &ofs, int bank_num = -1) const;
+ void write_bram_pbm(std::ostream &ofs, int bank_num = -1) const;
// query chip type metadata
int chip_width() const;
@@ -149,11 +150,23 @@ struct CramIndexConverter
void get_cram_index(int bit_x, int bit_y, int &cram_bank, int &cram_x, int &cram_y) const;
};
+struct BramIndexConverter
+{
+ const FpgaConfig *fpga;
+ int tile_x, tile_y;
+
+ int bank_num;
+ int bank_off;
+
+ BramIndexConverter(const FpgaConfig *fpga, int tile_x, int tile_y);
+ void get_bram_index(int bit_x, int bit_y, int &bram_bank, int &bram_x, int &bram_y) const;
+};
+
static void update_crc16(uint16_t &crc, uint8_t byte)
{
// CRC-16-CCITT, Initialize to 0xFFFF, No zero padding
for (int i = 7; i >= 0; i--) {
- uint16_t xor_value = ((crc >> 15) ^ (byte >> i) & 1) ? 0x1021 : 0;
+ uint16_t xor_value = ((crc >> 15) ^ ((byte >> i) & 1)) ? 0x1021 : 0;
crc = (crc << 1) ^ xor_value;
}
}
@@ -450,7 +463,7 @@ void FpgaConfig::write_bits(std::ostream &ofs) const
debug("CRAM: Writing bank %d data.\n", cram_bank);
write_byte(ofs, crc_value, file_offset, 0x01);
write_byte(ofs, crc_value, file_offset, 0x01);
- for (int i = 0; i < cram_bits.size(); i += 8) {
+ for (int i = 0; i < int(cram_bits.size()); i += 8) {
uint8_t byte = 0;
for (int j = 0; j < 8; j++)
byte = (byte << 1) | (cram_bits[i+j] ? 1 : 0);
@@ -494,7 +507,7 @@ void FpgaConfig::write_bits(std::ostream &ofs) const
debug("BRAM: Writing bank %d data.\n", bram_bank);
write_byte(ofs, crc_value, file_offset, 0x01);
write_byte(ofs, crc_value, file_offset, 0x03);
- for (int i = 0; i < bram_bits.size(); i += 8) {
+ for (int i = 0; i < int(bram_bits.size()); i += 8) {
uint8_t byte = 0;
for (int j = 0; j < 8; j++)
byte = (byte << 1) | (bram_bits[i+j] ? 1 : 0);
@@ -571,6 +584,9 @@ void FpgaConfig::read_ascii(std::istream &ifs)
if (command == ".device")
{
+ if (got_device)
+ error("More than one .device statement.\n");
+
is >> this->device;
if (this->device == "1k") {
@@ -620,7 +636,7 @@ void FpgaConfig::read_ascii(std::istream &ifs)
break;
}
- for (int bit_x = 0; bit_x < line.size() && bit_x < cic.tile_width; bit_x++)
+ for (int bit_x = 0; bit_x < int(line.size()) && bit_x < cic.tile_width; bit_x++)
if (line[bit_x] == '1') {
int cram_bank, cram_x, cram_y;
cic.get_cram_index(bit_x, bit_y, cram_bank, cram_x, cram_y);
@@ -631,6 +647,47 @@ void FpgaConfig::read_ascii(std::istream &ifs)
continue;
}
+ if (command == ".ram_data")
+ {
+ if (!got_device)
+ error("Missing .device statement before %s.\n", command.c_str());
+
+ int tile_x, tile_y;
+ is >> tile_x >> tile_y;
+
+ BramIndexConverter bic(this, tile_x, tile_y);
+
+ for (int bit_y = 0; bit_y < 16 && getline(ifs, line); bit_y++)
+ {
+ if (line.substr(0, 1) == ".") {
+ reuse_line = true;
+ break;
+ }
+
+ for (int bit_x = 256-4, ch_idx = 0; ch_idx < int(line.size()) && bit_x >= 0; bit_x -= 4, ch_idx++)
+ {
+ int value = -1;
+ if ('0' <= line[ch_idx] && line[ch_idx] <= '9')
+ value = line[ch_idx] - '0';
+ if ('a' <= line[ch_idx] && line[ch_idx] <= 'f')
+ value = line[ch_idx] - 'a' + 10;
+ if ('A' <= line[ch_idx] && line[ch_idx] <= 'F')
+ value = line[ch_idx] - 'A' + 10;
+ if (value < 0)
+ error("Not a hex character: '%c' (in line '%s')\n", line[ch_idx], line.c_str());
+
+ for (int i = 0; i < 4; i++)
+ if ((value & (1 << i)) != 0) {
+ int bram_bank, bram_x, bram_y;
+ bic.get_bram_index(bit_x+i, bit_y, bram_bank, bram_x, bram_y);
+ this->bram[bram_bank][bram_x][bram_y] = true;
+ }
+ }
+ }
+
+ continue;
+ }
+
if (command == ".extra_bit")
{
if (!got_device)
@@ -642,7 +699,10 @@ void FpgaConfig::read_ascii(std::istream &ifs)
continue;
}
-
+
+ if (command == ".sym")
+ continue;
+
if (command.substr(0, 1) == ".")
error("Unknown statement: %s\n", command.c_str());
error("Unexpected data line: %s\n", line.c_str());
@@ -693,6 +753,26 @@ void FpgaConfig::write_ascii(std::ostream &ofs) const
}
ofs << '\n';
}
+
+ if (cic.tile_type == "ramb")
+ {
+ BramIndexConverter bic(this, x, y);
+ ofs << stringf(".ram_data %d %d\n", x, y);
+
+ for (int bit_y = 0; bit_y < 16; bit_y++) {
+ for (int bit_x = 256-4; bit_x >= 0; bit_x -= 4) {
+ int value = 0;
+ for (int i = 0; i < 4; i++) {
+ int bram_bank, bram_x, bram_y;
+ bic.get_bram_index(bit_x+i, bit_y, bram_bank, bram_x, bram_y);
+ if (this->bram[bram_bank][bram_x][bram_y])
+ value += 1 << i;
+ }
+ ofs << "0123456789abcdef"[value];
+ }
+ ofs << '\n';
+ }
+ }
}
for (int i = 0; i < 4; i++)
@@ -717,7 +797,7 @@ void FpgaConfig::write_ascii(std::ostream &ofs) const
void FpgaConfig::write_cram_pbm(std::ostream &ofs, int bank_num) const
{
debug("## %s\n", __PRETTY_FUNCTION__);
- info("Writing pbm file..\n");
+ info("Writing cram pbm file..\n");
ofs << "P1\n";
ofs << stringf("%d %d\n", 2*this->cram_width, 2*this->cram_height);
@@ -737,6 +817,29 @@ void FpgaConfig::write_cram_pbm(std::ostream &ofs, int bank_num) const
}
}
+void FpgaConfig::write_bram_pbm(std::ostream &ofs, int bank_num) const
+{
+ debug("## %s\n", __PRETTY_FUNCTION__);
+ info("Writing bram pbm file..\n");
+
+ ofs << "P1\n";
+ ofs << stringf("%d %d\n", 2*this->bram_width, 2*this->bram_height);
+ for (int y = 2*this->bram_height-1; y >= 0; y--) {
+ for (int x = 0; x < 2*this->bram_width; x++) {
+ int bank = 0, bank_x = x, bank_y = y;
+ if (bank_x >= this->bram_width)
+ bank |= 1, bank_x = 2*this->bram_width - bank_x - 1;
+ if (bank_y >= this->bram_height)
+ bank |= 2, bank_y = 2*this->bram_height - bank_y - 1;
+ if (bank_num >= 0 && bank != bank_num)
+ ofs << " 0";
+ else
+ ofs << (this->bram[bank][bank_x][bank_y] ? " 1" : " 0");
+ }
+ ofs << '\n';
+ }
+}
+
int FpgaConfig::chip_width() const
{
if (this->device == "384") return 6;
@@ -901,6 +1004,33 @@ void CramIndexConverter::get_cram_index(int bit_x, int bit_y, int &cram_bank, in
}
}
+BramIndexConverter::BramIndexConverter(const FpgaConfig *fpga, int tile_x, int tile_y)
+{
+ this->fpga = fpga;
+ this->tile_x = tile_x;
+ this->tile_y = tile_y;
+
+ auto chip_width = fpga->chip_width();
+ auto chip_height = fpga->chip_height();
+
+ bool right_half = this->tile_x > chip_width / 2;
+ bool top_half = this->tile_y > chip_height / 2;
+
+ this->bank_num = 0;
+ if (top_half) this->bank_num |= 1;
+ if (right_half) this->bank_num |= 2;
+
+ this->bank_off = 16 * ((top_half ? this->tile_y - chip_height / 2 : this->tile_y - 1) / 2);
+}
+
+void BramIndexConverter::get_bram_index(int bit_x, int bit_y, int &bram_bank, int &bram_x, int &bram_y) const
+{
+ int index = 256 * bit_y + (16*(bit_x/16) + 15 - bit_x%16);
+ bram_bank = bank_num;
+ bram_x = bank_off + index % 16;
+ bram_y = index / 16;
+}
+
// ==================================================================
// Main program
@@ -926,6 +1056,9 @@ void usage()
log(" write cram bitmap (checkerboard) as netpbm file\n");
log(" repeat to flip the selection of tiles\n");
log("\n");
+ log(" -r\n");
+ log(" write bram data, not cram, to the netpbm file\n");
+ log("\n");
log(" -B0, -B1, -B2, -B3\n");
log(" only include the specified bank in the netpbm file\n");
log("\n");
@@ -937,6 +1070,7 @@ int main(int argc, char **argv)
vector<string> parameters;
bool unpack_mode = false;
bool netpbm_mode = false;
+ bool netpbm_bram = false;
bool netpbm_fill_tiles = false;
bool netpbm_checkerboard = false;
int netpbm_banknum = -1;
@@ -951,11 +1085,14 @@ int main(int argc, char **argv)
string arg(argv[i]);
if (arg[0] == '-' && arg.size() > 1) {
- for (int i = 1; i < arg.size(); i++)
+ for (int i = 1; i < int(arg.size()); i++)
if (arg[i] == 'u') {
unpack_mode = true;
} else if (arg[i] == 'b') {
netpbm_mode = true;
+ } else if (arg[i] == 'r') {
+ netpbm_mode = true;
+ netpbm_bram = true;
} else if (arg[i] == 'f') {
netpbm_mode = true;
netpbm_fill_tiles = true;
@@ -1023,8 +1160,12 @@ int main(int argc, char **argv)
if (netpbm_fill_tiles)
fpga_config.cram_fill_tiles();
- if (netpbm_mode)
- fpga_config.write_cram_pbm(*osp, netpbm_banknum);
+ if (netpbm_mode) {
+ if (netpbm_bram)
+ fpga_config.write_bram_pbm(*osp, netpbm_banknum);
+ else
+ fpga_config.write_cram_pbm(*osp, netpbm_banknum);
+ }
info("Done.\n");
return 0;