aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--examples/hx8kboard/example.v2
-rw-r--r--examples/hx8kboard/hx8kboard.pcf18
-rw-r--r--examples/iceblink/example.v2
-rw-r--r--examples/iceblink/iceblink.pcf10
-rw-r--r--examples/icestick/Makefile2
-rw-r--r--examples/icestick/example.v2
-rw-r--r--examples/icestick/icestick.pcf22
-rw-r--r--examples/icestick/rs232demo.v48
-rw-r--r--examples/icezum/example.v2
-rw-r--r--examples/icezum/icezum.pcf18
-rw-r--r--icebox/Makefile2
-rwxr-xr-xicebox/icebox_stat.py139
-rw-r--r--icecompr/.gitignore5
-rw-r--r--icecompr/Makefile31
-rw-r--r--icecompr/README52
-rw-r--r--icecompr/example_1k.binbin0 -> 32220 bytes
-rw-r--r--icecompr/example_8k.binbin0 -> 135100 bytes
-rw-r--r--icecompr/icecompr.cc316
-rw-r--r--icecompr/iceuncompr.c162
-rw-r--r--icefuzz/icecube.sh4
-rw-r--r--icefuzz/tests/bitop.pcf6
-rw-r--r--icefuzz/tests/example_hx8kboard.pcf18
-rw-r--r--icefuzz/tests/example_icestick.pcf12
23 files changed, 790 insertions, 83 deletions
diff --git a/examples/hx8kboard/example.v b/examples/hx8kboard/example.v
index accbc2e..69a446f 100644
--- a/examples/hx8kboard/example.v
+++ b/examples/hx8kboard/example.v
@@ -16,7 +16,7 @@ module top (
reg [BITS+LOG2DELAY-1:0] counter = 0;
reg [BITS-1:0] outcnt;
- always@(posedge clk) begin
+ always @(posedge clk) begin
counter <= counter + 1;
outcnt <= counter >> LOG2DELAY;
end
diff --git a/examples/hx8kboard/hx8kboard.pcf b/examples/hx8kboard/hx8kboard.pcf
index 417ca01..503eb36 100644
--- a/examples/hx8kboard/hx8kboard.pcf
+++ b/examples/hx8kboard/hx8kboard.pcf
@@ -1,9 +1,9 @@
-set_io LED0 B5
-set_io LED1 B4
-set_io LED2 A2
-set_io LED3 A1
-set_io LED4 C5
-set_io LED5 C4
-set_io LED6 B3
-set_io LED7 C3
-set_io clk J3
+set_io LED0 B5
+set_io LED1 B4
+set_io LED2 A2
+set_io LED3 A1
+set_io LED4 C5
+set_io LED5 C4
+set_io LED6 B3
+set_io LED7 C3
+set_io clk J3
diff --git a/examples/iceblink/example.v b/examples/iceblink/example.v
index 6bccc1e..4642ef2 100644
--- a/examples/iceblink/example.v
+++ b/examples/iceblink/example.v
@@ -15,7 +15,7 @@ module top (
reg [BITS+LOG2DELAY-1:0] counter = 0;
reg [BITS-1:0] outcnt;
- always@(posedge clk) begin
+ always @(posedge clk) begin
counter <= counter + 1;
outcnt <= counter >> LOG2DELAY;
end
diff --git a/examples/iceblink/iceblink.pcf b/examples/iceblink/iceblink.pcf
index 0d5e6c1..e737772 100644
--- a/examples/iceblink/iceblink.pcf
+++ b/examples/iceblink/iceblink.pcf
@@ -1,5 +1,5 @@
-set_io LED2 59
-set_io LED3 56
-set_io LED4 53
-set_io LED5 51
-set_io clk 13
+set_io LED2 59
+set_io LED3 56
+set_io LED4 53
+set_io LED5 51
+set_io clk 13
diff --git a/examples/icestick/Makefile b/examples/icestick/Makefile
index f40c8a3..9294608 100644
--- a/examples/icestick/Makefile
+++ b/examples/icestick/Makefile
@@ -1,4 +1,6 @@
PROJ = example
+# PROJ = rs232demo
+
PIN_DEF = icestick.pcf
DEVICE = hx1k
diff --git a/examples/icestick/example.v b/examples/icestick/example.v
index a934400..3eb7007 100644
--- a/examples/icestick/example.v
+++ b/examples/icestick/example.v
@@ -13,7 +13,7 @@ module top (
reg [BITS+LOG2DELAY-1:0] counter = 0;
reg [BITS-1:0] outcnt;
- always@(posedge clk) begin
+ always @(posedge clk) begin
counter <= counter + 1;
outcnt <= counter >> LOG2DELAY;
end
diff --git a/examples/icestick/icestick.pcf b/examples/icestick/icestick.pcf
index 23067be..8bf462e 100644
--- a/examples/icestick/icestick.pcf
+++ b/examples/icestick/icestick.pcf
@@ -1,11 +1,11 @@
-# full iCEstick pinout:
-# http://www.pighixxx.com/test/portfolio-items/icestick/
-
-set_io --warn-no-port RX 9
-set_io --warn-no-port TX 8
-set_io LED1 99
-set_io LED2 98
-set_io LED3 97
-set_io LED4 96
-set_io LED5 95
-set_io clk 21
+# full iCEstick pinout:
+# http://www.pighixxx.com/test/portfolio-items/icestick/
+
+set_io --warn-no-port RX 9
+set_io --warn-no-port TX 8
+set_io LED1 99
+set_io LED2 98
+set_io LED3 97
+set_io LED4 96
+set_io LED5 95
+set_io clk 21
diff --git a/examples/icestick/rs232demo.v b/examples/icestick/rs232demo.v
index fc7a770..f9e7546 100644
--- a/examples/icestick/rs232demo.v
+++ b/examples/icestick/rs232demo.v
@@ -12,46 +12,44 @@ module top (
parameter integer CLOCK_FREQ_HZ = 12000000;
localparam integer HALF_PERIOD = CLOCK_FREQ_HZ / (2 * BAUD_RATE);
- reg [9:0] buffer;
+ reg [7:0] buffer;
reg buffer_valid;
reg [$clog2(3*HALF_PERIOD):0] cycle_cnt;
reg [3:0] bit_cnt = 0;
- reg [0:0] state = 0;
+ reg recv = 0;
always @(posedge clk) begin
buffer_valid <= 0;
- case (state)
- 0: begin
- if (!RX) begin
- cycle_cnt <= HALF_PERIOD;
- bit_cnt <= 0;
- state <= 1;
- end
+ if (!recv) begin
+ if (!RX) begin
+ cycle_cnt <= HALF_PERIOD;
+ bit_cnt <= 0;
+ recv <= 1;
end
- 1: begin
- if (cycle_cnt == 2*HALF_PERIOD) begin
- cycle_cnt <= 0;
- buffer[bit_cnt] <= RX;
- bit_cnt <= bit_cnt + 1;
- if (bit_cnt == 9) begin
- buffer_valid <= 1;
- state <= 0;
- end
+ end else begin
+ if (cycle_cnt == 2*HALF_PERIOD) begin
+ cycle_cnt <= 0;
+ bit_cnt <= bit_cnt + 1;
+ if (bit_cnt == 9) begin
+ buffer_valid <= 1;
+ recv <= 0;
end else begin
- cycle_cnt <= cycle_cnt + 1;
+ buffer <= {RX, buffer[7:1]};
end
+ end else begin
+ cycle_cnt <= cycle_cnt + 1;
end
- endcase
+ end
end
always @(posedge clk) begin
if (buffer_valid) begin
- if (buffer[8:1] == "1") LED1 <= !LED1;
- if (buffer[8:1] == "2") LED2 <= !LED2;
- if (buffer[8:1] == "3") LED3 <= !LED3;
- if (buffer[8:1] == "4") LED4 <= !LED4;
- if (buffer[8:1] == "5") LED5 <= !LED5;
+ if (buffer == "1") LED1 <= !LED1;
+ if (buffer == "2") LED2 <= !LED2;
+ if (buffer == "3") LED3 <= !LED3;
+ if (buffer == "4") LED4 <= !LED4;
+ if (buffer == "5") LED5 <= !LED5;
end
end
diff --git a/examples/icezum/example.v b/examples/icezum/example.v
index 9bdf587..1274e69 100644
--- a/examples/icezum/example.v
+++ b/examples/icezum/example.v
@@ -16,7 +16,7 @@ module top (
reg [BITS+LOG2DELAY-1:0] counter = 0;
reg [BITS-1:0] outcnt;
- always@(posedge clk) begin
+ always @(posedge clk) begin
counter <= counter + 1;
outcnt <= counter >> LOG2DELAY;
end
diff --git a/examples/icezum/icezum.pcf b/examples/icezum/icezum.pcf
index 4139e7f..bafdbd9 100644
--- a/examples/icezum/icezum.pcf
+++ b/examples/icezum/icezum.pcf
@@ -1,9 +1,9 @@
-set_io LED0 95
-set_io LED1 96
-set_io LED2 97
-set_io LED3 98
-set_io LED4 99
-set_io LED5 101
-set_io LED6 102
-set_io LED7 104
-set_io clk 21
+set_io LED0 95
+set_io LED1 96
+set_io LED2 97
+set_io LED3 98
+set_io LED4 99
+set_io LED5 101
+set_io LED6 102
+set_io LED7 104
+set_io clk 21
diff --git a/icebox/Makefile b/icebox/Makefile
index 43d4664..3db1a50 100644
--- a/icebox/Makefile
+++ b/icebox/Makefile
@@ -28,6 +28,7 @@ install: all
cp icebox_html.py $(DESTDIR)$(PREFIX)/bin/icebox_html
cp icebox_maps.py $(DESTDIR)$(PREFIX)/bin/icebox_maps
cp icebox_vlog.py $(DESTDIR)$(PREFIX)/bin/icebox_vlog
+ cp icebox_stat.py $(DESTDIR)$(PREFIX)/bin/icebox_stat
uninstall:
rm -f $(DESTDIR)$(PREFIX)/bin/icebox.py
@@ -39,6 +40,7 @@ uninstall:
rm -f $(DESTDIR)$(PREFIX)/bin/icebox_html
rm -f $(DESTDIR)$(PREFIX)/bin/icebox_maps
rm -f $(DESTDIR)$(PREFIX)/bin/icebox_vlog
+ rm -f $(DESTDIR)$(PREFIX)/bin/icebox_stat
rm -f $(DESTDIR)$(PREFIX)/share/icebox/chipdb-1k.txt
rm -f $(DESTDIR)$(PREFIX)/share/icebox/chipdb-8k.txt
-rmdir $(DESTDIR)$(PREFIX)/share/icebox
diff --git a/icebox/icebox_stat.py b/icebox/icebox_stat.py
new file mode 100755
index 0000000..ffb7b6a
--- /dev/null
+++ b/icebox/icebox_stat.py
@@ -0,0 +1,139 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2015 Clifford Wolf <clifford@clifford.at>
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+#
+
+import icebox
+import getopt, sys, re
+
+verbose = False
+
+def usage():
+ print("""
+Usage: icebox_stat [options] [bitmap.asc]
+
+ -v
+ verbose output
+
+""")
+ sys.exit(0)
+
+try:
+ opts, args = getopt.getopt(sys.argv[1:], "v")
+except:
+ usage()
+
+for o, a in opts:
+ if o == "-v":
+ verbose = True
+ else:
+ usage()
+
+if len(args) == 0:
+ args.append("/dev/stdin")
+
+if len(args) != 1:
+ usage()
+
+if verbose:
+ print("Reading input file.")
+
+ic = icebox.iceconfig()
+ic.read_file(args[0])
+
+dff_locations = set()
+lut_locations = set()
+carry_locations = set()
+bram_locations = set()
+io_locations = set()
+pll_locations = set()
+global_nets = set()
+
+if verbose:
+ print("Analyzing connectivity.")
+
+connections = sorted(ic.group_segments())
+
+if verbose:
+ print("Counting resources.")
+
+for segs in connections:
+ for seg in segs:
+ if ic.tile_type(seg[0], seg[1]) == "IO" and seg[2].startswith("io_"):
+ match = re.match("io_(\d+)/D_(IN|OUT)_(\d+)", seg[2])
+ if match:
+ loc = (seg[0], seg[1], int(match.group(1)))
+ io_locations.add(loc)
+
+ if ic.tile_type(seg[0], seg[1]) == "LOGIC" and seg[2].startswith("lutff_"):
+ match = re.match("lutff_(\d)/in_\d", seg[2])
+ if match:
+ loc = (seg[0], seg[1], int(match.group(1)))
+ lut_locations.add(loc)
+
+ match = re.match("lutff_(\d)/cout", seg[2])
+ if match:
+ loc = (seg[0], seg[1], int(match.group(1)))
+ carry_locations.add(loc)
+
+ match = re.match("lutff_(\d)/out", seg[2])
+ if match:
+ loc = (seg[0], seg[1], int(match.group(1)))
+ seq_bits = icebox.get_lutff_seq_bits(ic.tile(loc[0], loc[1]), loc[2])
+ if seq_bits[1] == "1":
+ dff_locations.add(loc)
+
+ if ic.tile_type(seg[0], seg[1]) in ("RAMB", "RAMT") and seg[2].startswith("ram/"):
+ loc = (seg[0], seg[1] - (seg[1] % 2))
+ bram_locations.add(loc)
+
+ if seg[2].startswith("glb_netwk_"):
+ match = re.match("glb_netwk_(\d)", seg[2])
+ if match:
+ global_nets.add(int(match.group(1)))
+
+pll_config_bitidx = dict()
+
+for entry in icebox.iotile_l_db:
+ if entry[1] == "PLL":
+ match = re.match(r"B(\d+)\[(\d+)\]", entry[0][0]);
+ assert match
+ pll_config_bitidx[entry[2]] = (int(match.group(1)), int(match.group(2)))
+
+def get_pll_bit(pllinfo, name):
+ bit = pllinfo[name]
+ assert bit[2] in pll_config_bitidx
+ return ic.tile(bit[0], bit[1])[pll_config_bitidx[bit[2]][0]][pll_config_bitidx[bit[2]][1]]
+
+def get_pll_bits(pllinfo, name, n):
+ return "".join([get_pll_bit(pllinfo, "%s_%d" % (name, i)) for i in range(n-1, -1, -1)])
+
+for pllid in ic.pll_list():
+ pllinfo = icebox.pllinfo_db[pllid]
+ plltype = get_pll_bits(pllinfo, "PLLTYPE", 3)
+ if plltype != "000":
+ pll_locations.add(pllid)
+
+if verbose:
+ print()
+
+print("DFFs: %4d" % len(dff_locations))
+print("LUTs: %4d" % len(lut_locations))
+print("CARRYs: %4d" % len(carry_locations))
+print("BRAMs: %4d" % len(bram_locations))
+print("IOBs: %4d" % len(io_locations))
+print("PLLs: %4d" % len(pll_locations))
+print("GLBs: %4d" % len(global_nets))
+
diff --git a/icecompr/.gitignore b/icecompr/.gitignore
new file mode 100644
index 0000000..1ebf48a
--- /dev/null
+++ b/icecompr/.gitignore
@@ -0,0 +1,5 @@
+icecompr
+iceuncompr
+example_?k.compr
+example_?k.ok
+example_?k.uncompr
diff --git a/icecompr/Makefile b/icecompr/Makefile
new file mode 100644
index 0000000..88512f0
--- /dev/null
+++ b/icecompr/Makefile
@@ -0,0 +1,31 @@
+
+all: icecompr iceuncompr
+
+test: example_1k.ok example_8k.ok
+
+icecompr: icecompr.cc
+ clang++ -o icecompr -Wall -Wextra -std=c++11 icecompr.cc
+
+iceuncompr: iceuncompr.c
+ clang -o iceuncompr -Wall -Wextra iceuncompr.c
+
+%.compr: %.bin icecompr
+ ./icecompr -v $< $@
+
+
+%.uncompr: %.compr iceuncompr
+ ./iceuncompr $< $@
+
+%.ok: %.uncompr %.bin
+ cmp $^
+ touch $@
+
+clean:
+ rm -f icecompr iceuncompr
+ rm -f example_1k.compr example_8k.compr
+ rm -f example_1k.uncompr example_8k.uncompr
+ rm -f example_1k.ok example_8k.ok
+
+.SECONDARY:
+.PHONY: all test clean
+
diff --git a/icecompr/README b/icecompr/README
new file mode 100644
index 0000000..5e04bb5
--- /dev/null
+++ b/icecompr/README
@@ -0,0 +1,52 @@
+
+A simple compression algorithm for iCE40 bit-streams
+====================================================
+
+This directory contains tools for compressing and uncompressing
+iCE40 bit-streams. The motivation is to reduce the bandwidth
+requirements for bit-stream upload.
+
+Note that iCE40 FPGAs can not uncompress this compressed bit-streams!
+Uncompression must be performed by e.g. a uC on the FPGA board.
+
+This compression algorithm uses the fact that most bits in an iCE40
+bit-stream are cleared.
+
+The bit-stream is encoded as the distances between set bits (i.e.
+the length of runs of ZERO bits between two ONE bits). This sequence
+of integers is stored using a simple prefix code to spend fewer bits
+on smaller (more frequent) numbers.
+
+The algorithm includes an escape-mechanism to mix uncompressed binary
+data with compressed bit-streams. This is useful when the bit-stream
+contains sections that do not compress well with this algorithm, for
+example in BRAM initialization data.
+
+The compressed bitstream starts with the ASCII string "ICECOMPR", i.e.
+the hex values 0x49434543 and 0x4f4d5052 (stored as big-endian numbers).
+
+After the 8 bytes magic the compressed bitstream is a stream of the
+following opcodes that must be interpreted by the decompressor. The
+notation ZERO and ONE is used for zero and one bits. The notation foo[N]
+is used for an N bit value "foo", transmitted MSB first.
+
+ ONE count[2]
+ ZERO ONE count[5]
+ ZERO ZERO ONE count[8]
+ ZERO ZERO ZERO ZERO ONE count[23]
+ output count ZERO bits followed by a single ONE bit
+
+ ZERO ZERO ZERO ONE count[6] data[count]
+ output the count data bits followed by a single ONE bit
+
+ ZERO ZERO ZERO ZERO ZERO count[23]
+ output count ZERO bits and stop decompressing. (end of file)
+
+The program "icecompr" (C++11, ISC license) contains an implementation of a
+compressor and a decompressor. The decompressor in this program however is
+only used for integrity checking the compressed bit-stream.
+
+The program "iceuncompr" (plain C, public domain) contains an implementation
+of a stand-alone decompressor. Simply copy&paste this implementation into
+your uC firmware.
+
diff --git a/icecompr/example_1k.bin b/icecompr/example_1k.bin
new file mode 100644
index 0000000..0321b9a
--- /dev/null
+++ b/icecompr/example_1k.bin
Binary files differ
diff --git a/icecompr/example_8k.bin b/icecompr/example_8k.bin
new file mode 100644
index 0000000..8b6c7c5
--- /dev/null
+++ b/icecompr/example_8k.bin
Binary files differ
diff --git a/icecompr/icecompr.cc b/icecompr/icecompr.cc
new file mode 100644
index 0000000..322de9a
--- /dev/null
+++ b/icecompr/icecompr.cc
@@ -0,0 +1,316 @@
+/*
+ * IceCompr -- A simple compressor for iCE40 bit-streams
+ *
+ * Copyright (C) 2017 Clifford Wolf <clifford@clifford.at>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <vector>
+#include <map>
+
+int verbose = 0;
+
+static void push_int_bits(std::vector<bool> &outbits, int value, int bits)
+{
+ while (bits-- > 0)
+ outbits.push_back((value >> bits) & 1);
+}
+
+static void push_zero_bits(std::vector<bool> &outbits, int bits)
+{
+ while (bits-- > 0)
+ outbits.push_back(false);
+}
+
+static int decode_int_from_bits(const std::vector<bool> &inbits, int &cursor, int bits)
+{
+ int ret = 0;
+ while (bits-- > 0)
+ if (inbits.at(cursor++))
+ ret |= 1 << bits;
+ return ret;
+}
+
+void ice_compress(std::vector<bool> &outbits, const std::vector<bool> &inbits)
+{
+ int opcode_stats_d4 = 0;
+ int opcode_stats_d32 = 0;
+ int opcode_stats_d256 = 0;
+ int opcode_stats_raw = 0;
+ int opcode_stats_d8M = 0;
+ int opcode_stats_end = 0;
+
+ std::vector<int> deltas;
+ int numzeros = 0;
+
+ for (auto bit : inbits)
+ {
+ if (bit) {
+ deltas.push_back(numzeros);
+ numzeros = 0;
+ } else {
+ numzeros++;
+ }
+ }
+
+ for (int i = 0; i < int(deltas.size()); i++)
+ {
+ int raw_len = 0;
+ int compr_len = 0;
+ int best_compr_raw_diff = -1;
+ int best_compr_raw_idx = -1;
+ int best_compr_raw_len = -1;
+
+ for (int j = 0; j+i < int(deltas.size()); j++)
+ {
+ int delta = deltas.at(i + j);
+ raw_len += delta + 1;
+
+ if (delta < 4)
+ compr_len += 3;
+ else if (delta < 32)
+ compr_len += 7;
+ else if (delta < 256)
+ compr_len += 11;
+ else
+ compr_len += 26;
+
+ if (compr_len - raw_len < std::max(best_compr_raw_diff - 4, 0) || raw_len > 64)
+ break;
+
+ if (compr_len - raw_len > best_compr_raw_diff) {
+ best_compr_raw_diff = compr_len - raw_len;
+ best_compr_raw_idx = j;
+ best_compr_raw_len = raw_len;
+ }
+ }
+
+ if (best_compr_raw_diff > 9)
+ {
+ opcode_stats_raw++;
+ outbits.push_back(false);
+ outbits.push_back(false);
+ outbits.push_back(false);
+ outbits.push_back(true);
+ push_int_bits(outbits, best_compr_raw_len-1, 6);
+
+ for (int j = 0; j <= best_compr_raw_idx; j++) {
+ int delta = deltas.at(i + j);
+ for (int k = 0; k < delta; k++)
+ outbits.push_back(false);
+ if (j < best_compr_raw_idx)
+ outbits.push_back(true);
+ }
+
+ i += best_compr_raw_idx;
+ continue;
+ }
+
+ int delta = deltas.at(i);
+
+ if (delta < 4) {
+ opcode_stats_d4++;
+ outbits.push_back(true);
+ push_int_bits(outbits, delta, 2);
+ } else
+ if (delta < 32) {
+ opcode_stats_d32++;
+ outbits.push_back(false);
+ outbits.push_back(true);
+ push_int_bits(outbits, delta, 5);
+ } else
+ if (delta < 256) {
+ opcode_stats_d256++;
+ outbits.push_back(false);
+ outbits.push_back(false);
+ outbits.push_back(true);
+ push_int_bits(outbits, delta, 8);
+ } else {
+ opcode_stats_d8M++;
+ outbits.push_back(false);
+ outbits.push_back(false);
+ outbits.push_back(false);
+ outbits.push_back(false);
+ outbits.push_back(true);
+ push_int_bits(outbits, delta, 23);
+ }
+ }
+
+ opcode_stats_end++;
+ outbits.push_back(false);
+ outbits.push_back(false);
+ outbits.push_back(false);
+ outbits.push_back(false);
+ outbits.push_back(false);
+ push_int_bits(outbits, numzeros, 23);
+
+ if (verbose > 1) {
+ fprintf(stderr, "opcode d4 %5d\n", opcode_stats_d4);
+ fprintf(stderr, "opcode d32 %5d\n", opcode_stats_d32);
+ fprintf(stderr, "opcode d256 %5d\n", opcode_stats_d256);
+ fprintf(stderr, "opcode raw %5d\n", opcode_stats_raw);
+ fprintf(stderr, "opcode d8M %5d\n", opcode_stats_d8M);
+ fprintf(stderr, "opcode end %5d\n", opcode_stats_end);
+ }
+}
+
+void ice_uncompress(std::vector<bool> &outbits, const std::vector<bool> &inbits)
+{
+ int cursor = 0;
+
+ while (cursor < int(inbits.size()))
+ {
+ if (inbits.at(cursor++)) {
+ int zeros = decode_int_from_bits(inbits, cursor, 2);
+ push_zero_bits(outbits, zeros);
+ outbits.push_back(true);
+ } else
+ if (inbits.at(cursor++)) {
+ int zeros = decode_int_from_bits(inbits, cursor, 5);
+ push_zero_bits(outbits, zeros);
+ outbits.push_back(true);
+ } else
+ if (inbits.at(cursor++)) {
+ int zeros = decode_int_from_bits(inbits, cursor, 8);
+ push_zero_bits(outbits, zeros);
+ outbits.push_back(true);
+ } else
+ if (inbits.at(cursor++)) {
+ int raw_len = decode_int_from_bits(inbits, cursor, 6);
+ while (raw_len--)
+ outbits.push_back(inbits.at(cursor++));
+ outbits.push_back(true);
+ } else
+ if (inbits.at(cursor++)) {
+ int zeros = decode_int_from_bits(inbits, cursor, 23);
+ push_zero_bits(outbits, zeros);
+ outbits.push_back(true);
+ } else {
+ int zeros = decode_int_from_bits(inbits, cursor, 23);
+ push_zero_bits(outbits, zeros);
+ }
+ }
+}
+
+void help()
+{
+ printf("\n");
+ printf("Usage: icecompr [-v] [input-file [output-file]]\n");
+ printf("\n");
+ exit(1);
+}
+
+int main(int argc, char **argv)
+{
+ FILE *input_file = stdin;
+ FILE *output_file = stdout;
+
+ int opt;
+ while ((opt = getopt(argc, argv, "v")) != -1)
+ {
+ switch (opt)
+ {
+ case 'v':
+ verbose++;
+ break;
+ default:
+ help();
+ }
+ }
+
+ if (optind < argc) {
+ input_file = fopen(argv[optind], "rb");
+ if (input_file == NULL) {
+ fprintf(stderr, "Failed to open input file `%s': %s\n", argv[optind], strerror(errno));
+ return 1;
+ }
+ optind++;
+ }
+
+ if (optind < argc) {
+ output_file = fopen(argv[optind], "wb");
+ if (output_file == NULL) {
+ fprintf(stderr, "Failed to open output file `%s': %s\n", argv[optind], strerror(errno));
+ return 1;
+ }
+ optind++;
+ }
+
+ if (optind != argc)
+ help();
+
+ std::vector<bool> original_bits;
+ int count_set_bits = 0;
+
+ while (1)
+ {
+ int byte = fgetc(input_file);
+
+ if (byte < 0)
+ break;
+
+ // MSB first
+ for (int i = 7; i >= 0; i--) {
+ bool bit = (byte >> i) & 1;
+ if (bit) count_set_bits++;
+ original_bits.push_back(bit);
+ }
+ }
+
+ int uncompressed_size = original_bits.size();
+
+ if (verbose > 0) {
+ fprintf(stderr, "Percentage of set bits: %.2f%%\n", (100.0*count_set_bits) / uncompressed_size);
+ fprintf(stderr, "Uncompressed size: %8d bits\n", uncompressed_size);
+ }
+
+ std::vector<bool> compressed_bits;
+ ice_compress(compressed_bits, original_bits);
+
+ int compressed_size = compressed_bits.size();
+
+ if (verbose > 0) {
+ fprintf(stderr, "Compressed size: %8d bits\n", compressed_size);
+ fprintf(stderr, "Space savings: %.2f%%\n", 100 - (100.0*compressed_size) / uncompressed_size);
+ }
+
+ std::vector<bool> uncompressed_bits;
+ ice_uncompress(uncompressed_bits, compressed_bits);
+
+ bool check_ok = original_bits == uncompressed_bits;
+
+ if (verbose > 0 || !check_ok) {
+ fprintf(stderr, "Integrity check: %s\n", check_ok ? "OK" : "ERROR");
+ if (!check_ok)
+ return 1;
+ }
+
+ fprintf(output_file, "ICECOMPR");
+ for (int i = 0; i < int(compressed_bits.size()); i += 8) {
+ int value = 0;
+ for (int j = 0; j < 8 && i+j < int(compressed_bits.size()); j++)
+ if (compressed_bits.at(i+j))
+ value |= 1 << (7-j);
+ fputc(value, output_file);
+ }
+
+ return 0;
+}
+
diff --git a/icecompr/iceuncompr.c b/icecompr/iceuncompr.c
new file mode 100644
index 0000000..04e7dc8
--- /dev/null
+++ b/icecompr/iceuncompr.c
@@ -0,0 +1,162 @@
+// This is free and unencumbered software released into the public domain.
+//
+// Anyone is free to copy, modify, publish, use, compile, sell, or
+// distribute this software, either in source code form or as a compiled
+// binary, for any purpose, commercial or non-commercial, and by any
+// means.
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+
+FILE *input_file;
+FILE *output_file;
+
+int read_bitcounter;
+int read_buffer;
+
+int write_bitcounter;
+int write_buffer;
+
+static int read_bit()
+{
+ if (read_bitcounter == 0) {
+ read_bitcounter = 8;
+ read_buffer = fgetc(input_file);
+ }
+
+ read_bitcounter--;
+ return (read_buffer >> read_bitcounter) & 1;
+}
+
+static void write_bit(int value)
+{
+ write_bitcounter--;
+
+ if (value)
+ write_buffer |= 1 << write_bitcounter;
+
+ if (write_bitcounter == 0) {
+ fputc(write_buffer, output_file);
+ write_bitcounter = 8;
+ write_buffer = 0;
+ }
+}
+
+static int read_int(int bits)
+{
+ int ret = 0;
+ while (bits-- > 0)
+ if (read_bit())
+ ret |= 1 << bits;
+ return ret;
+}
+
+static void write_zeros(int bits)
+{
+ while (bits-- > 0)
+ write_bit(0);
+}
+
+int ice_uncompress()
+{
+ read_bitcounter = 0;
+ read_buffer = 0;
+
+ write_bitcounter = 8;
+ write_buffer = 0;
+
+ int magic1_ok = read_int(32) == 0x49434543;
+ int magic2_ok = read_int(32) == 0x4f4d5052;
+
+ if (!magic1_ok || !magic2_ok) {
+ fprintf(stderr, "Missing ICECOMPR magic. Abort!\n");
+ return 1;
+ }
+
+ while (1)
+ {
+ if (read_bit()) {
+ write_zeros(read_int(2));
+ write_bit(1);
+ } else
+ if (read_bit()) {
+ write_zeros(read_int(5));
+ write_bit(1);
+ } else
+ if (read_bit()) {
+ write_zeros(read_int(8));
+ write_bit(1);
+ } else
+ if (read_bit()) {
+ int n = read_int(6);
+ while (n--)
+ write_bit(read_bit());
+ write_bit(1);
+ } else
+ if (read_bit()) {
+ write_zeros(read_int(23));
+ write_bit(1);
+ } else {
+ write_zeros(read_int(23));
+ break;
+ }
+ }
+
+ return 0;
+}
+
+void help()
+{
+ printf("\n");
+ printf("Usage: iceuncompr [input-file [output-file]]\n");
+ printf("\n");
+ exit(1);
+}
+
+int main(int argc, char **argv)
+{
+ input_file = stdin;
+ output_file = stdout;
+
+ int opt;
+ while ((opt = getopt(argc, argv, "v")) != -1)
+ {
+ switch (opt)
+ {
+ case 'v':
+ break;
+ default:
+ help();
+ }
+ }
+
+ if (optind < argc) {
+ input_file = fopen(argv[optind], "rb");
+ if (input_file == NULL) {
+ fprintf(stderr, "Failed to open input file `%s': %s\n", argv[optind], strerror(errno));
+ return 1;
+ }
+ optind++;
+ }
+
+ if (optind < argc) {
+ output_file = fopen(argv[optind], "wb");
+ if (output_file == NULL) {
+ fprintf(stderr, "Failed to open output file `%s': %s\n", argv[optind], strerror(errno));
+ return 1;
+ }
+ optind++;
+ }
+
+ if (optind != argc)
+ help();
+
+ if (optind != argc)
+ help();
+
+ return ice_uncompress();
+}
+
diff --git a/icefuzz/icecube.sh b/icefuzz/icecube.sh
index 809d437..2154b87 100644
--- a/icefuzz/icecube.sh
+++ b/icefuzz/icecube.sh
@@ -16,9 +16,9 @@
#
# Additional notes for installing iCEcube2 on 64 Bit Ubuntu:
#
-# sudo apt-get install ibc6-i386 zlib1g:i386 libxext6:i386 libpng12-0:i386 libsm6:i386
+# sudo apt-get install libc6-i386 zlib1g:i386 libxext6:i386 libpng12-0:i386 libsm6:i386
# sudo apt-get install libxi6:i386 libxrender1:i386 libxrandr2:i386 libxfixes3:i386
-# sudo apt-get install libxcursor1:i386 libXinerama.so.1:i386 libXinerama1:i386 libfreetype6:i386
+# sudo apt-get install libxcursor1:i386 libxinerama1:i386 libfreetype6:i386
# sudo apt-get install libfontconfig1:i386 libglib2.0-0:i386 libstdc++6:i386 libelf1:i386
#
# icecubedir="/opt/lscc/iCEcube2.2015.08"
diff --git a/icefuzz/tests/bitop.pcf b/icefuzz/tests/bitop.pcf
index 143632e..8a80285 100644
--- a/icefuzz/tests/bitop.pcf
+++ b/icefuzz/tests/bitop.pcf
@@ -1,3 +1,3 @@
-set_io a 1
-set_io b 10
-set_io y 11
+set_io a 1
+set_io b 10
+set_io y 11
diff --git a/icefuzz/tests/example_hx8kboard.pcf b/icefuzz/tests/example_hx8kboard.pcf
index 417ca01..503eb36 100644
--- a/icefuzz/tests/example_hx8kboard.pcf
+++ b/icefuzz/tests/example_hx8kboard.pcf
@@ -1,9 +1,9 @@
-set_io LED0 B5
-set_io LED1 B4
-set_io LED2 A2
-set_io LED3 A1
-set_io LED4 C5
-set_io LED5 C4
-set_io LED6 B3
-set_io LED7 C3
-set_io clk J3
+set_io LED0 B5
+set_io LED1 B4
+set_io LED2 A2
+set_io LED3 A1
+set_io LED4 C5
+set_io LED5 C4
+set_io LED6 B3
+set_io LED7 C3
+set_io clk J3
diff --git a/icefuzz/tests/example_icestick.pcf b/icefuzz/tests/example_icestick.pcf
index a1693eb..de06f5d 100644
--- a/icefuzz/tests/example_icestick.pcf
+++ b/icefuzz/tests/example_icestick.pcf
@@ -1,6 +1,6 @@
-set_io LED1 99
-set_io LED2 98
-set_io LED3 97
-set_io LED4 96
-set_io LED5 95
-set_io clk 21
+set_io LED1 99
+set_io LED2 98
+set_io LED3 97
+set_io LED4 96
+set_io LED5 95
+set_io clk 21