OpenCores
URL https://opencores.org/ocsvn/hdl-deflate/hdl-deflate/trunk

Subversion Repositories hdl-deflate

[/] [hdl-deflate/] [trunk/] [deflate.py] - Blame information for rev 6

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 tomtor
"""
2
MyHDL FPGA Deflate (de)compressor, see RFC 1950/1951
3
 
4
Copyright 2018 by Tom Vijlbrief
5
 
6
See: https://github.com/tomtor
7
 
8
This MyHDL FPGA implementation is partially inspired by the C++ implementation
9
from https://create.stephan-brumme.com/deflate-decoder
10
 
11
"""
12
 
13
from math import log2
14
 
15
from myhdl import always, block, Signal, intbv, Error, ResetSignal, \
16
    enum, always_seq, always_comb, concat, ConcatSignal, modbv
17
 
18
IDLE, RESET, WRITE, READ, STARTC, STARTD = range(6)
19
 
20 5 tomtor
COMPRESS = True
21 6 tomtor
DECOMPRESS = False
22
DECOMPRESS = True
23
 
24
DYNAMIC = False
25
DYNAMIC = True
26
 
27 5 tomtor
MATCH10 = False
28
MATCH10 = True
29
 
30
FAST = False
31
FAST = True
32
 
33 2 tomtor
CWINDOW = 32    # Search window for compression
34
 
35
OBSIZE = 8192   # Size of output buffer (BRAM)
36 6 tomtor
OBSIZE = 32768  # Size of output buffer for ANY input (BRAM)
37 2 tomtor
 
38 6 tomtor
# Size of input buffer (LUT-RAM)
39
IBSIZE = 16 * CWINDOW  # This size gives method 2 (dynamic tree) for testbench
40
IBSIZE = 2 * CWINDOW   # Minimal window
41
 
42
LMAX = 24       # Size of progress and I/O counters
43
 
44
 
45 2 tomtor
if OBSIZE > IBSIZE:
46 5 tomtor
    LBSIZE = int(log2(OBSIZE))
47 2 tomtor
else:
48 5 tomtor
    LBSIZE = int(log2(IBSIZE))
49 2 tomtor
 
50 5 tomtor
LIBSIZE = int(log2(IBSIZE))
51 6 tomtor
LOBSIZE = int(log2(OBSIZE))
52
 
53 5 tomtor
IBS = (1 << LIBSIZE) - 1
54 6 tomtor
OBS = (1 << LOBSIZE) - 1
55 2 tomtor
 
56
d_state = enum('IDLE', 'HEADER', 'BL', 'READBL', 'REPEAT', 'DISTTREE', 'INIT3',
57
               'HF1', 'HF1INIT', 'HF2', 'HF3', 'HF4', 'HF4_2', 'HF4_3',
58
               'STATIC', 'D_NEXT', 'D_NEXT_2',
59
               'D_INFLATE', 'SPREAD', 'NEXT', 'INFLATE', 'COPY', 'CSTATIC',
60 6 tomtor
               'SEARCH', 'SEARCHF', 'DISTANCE', 'CHECKSUM') # , encoding='one_hot')
61 2 tomtor
 
62
CodeLengthOrder = (16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14,
63
                   1, 15)
64
 
65
CopyLength = (3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35,
66
              43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258)
67
 
68
ExtraLengthBits = (0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
69
                   3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0)
70
 
71
CopyDistance = (1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
72
                257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193,
73
                12289, 16385, 24577)
74
 
75
ExtraDistanceBits = (0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13)
76
 
77 6 tomtor
out_codes = (
78
    0x00c, 0x08c, 0x04c, 0x0cc, 0x02c, 0x0ac, 0x06c, 0x0ec,
79
    0x01c, 0x09c, 0x05c, 0x0dc, 0x03c, 0x0bc, 0x07c, 0x0fc,
80
    0x002, 0x082, 0x042, 0x0c2, 0x022, 0x0a2, 0x062, 0x0e2,
81
    0x012, 0x092, 0x052, 0x0d2, 0x032, 0x0b2, 0x072, 0x0f2,
82
    0x00a, 0x08a, 0x04a, 0x0ca, 0x02a, 0x0aa, 0x06a, 0x0ea,
83
    0x01a, 0x09a, 0x05a, 0x0da, 0x03a, 0x0ba, 0x07a, 0x0fa,
84
    0x006, 0x086, 0x046, 0x0c6, 0x026, 0x0a6, 0x066, 0x0e6,
85
    0x016, 0x096, 0x056, 0x0d6, 0x036, 0x0b6, 0x076, 0x0f6,
86
    0x00e, 0x08e, 0x04e, 0x0ce, 0x02e, 0x0ae, 0x06e, 0x0ee,
87
    0x01e, 0x09e, 0x05e, 0x0de, 0x03e, 0x0be, 0x07e, 0x0fe,
88
    0x001, 0x081, 0x041, 0x0c1, 0x021, 0x0a1, 0x061, 0x0e1,
89
    0x011, 0x091, 0x051, 0x0d1, 0x031, 0x0b1, 0x071, 0x0f1,
90
    0x009, 0x089, 0x049, 0x0c9, 0x029, 0x0a9, 0x069, 0x0e9,
91
    0x019, 0x099, 0x059, 0x0d9, 0x039, 0x0b9, 0x079, 0x0f9,
92
    0x005, 0x085, 0x045, 0x0c5, 0x025, 0x0a5, 0x065, 0x0e5,
93
    0x015, 0x095, 0x055, 0x0d5, 0x035, 0x0b5, 0x075, 0x0f5,
94
    0x00d, 0x08d, 0x04d, 0x0cd, 0x02d, 0x0ad, 0x06d, 0x0ed,
95
    0x01d, 0x09d, 0x05d, 0x0dd, 0x03d, 0x0bd, 0x07d, 0x0fd,
96
    0x013, 0x113, 0x093, 0x193, 0x053, 0x153, 0x0d3, 0x1d3,
97
    0x033, 0x133, 0x0b3, 0x1b3, 0x073, 0x173, 0x0f3, 0x1f3,
98
    0x00b, 0x10b, 0x08b, 0x18b, 0x04b, 0x14b, 0x0cb, 0x1cb,
99
    0x02b, 0x12b, 0x0ab, 0x1ab, 0x06b, 0x16b, 0x0eb, 0x1eb,
100
    0x01b, 0x11b, 0x09b, 0x19b, 0x05b, 0x15b, 0x0db, 0x1db,
101
    0x03b, 0x13b, 0x0bb, 0x1bb, 0x07b, 0x17b, 0x0fb, 0x1fb,
102
    0x007, 0x107, 0x087, 0x187, 0x047, 0x147, 0x0c7, 0x1c7,
103
    0x027, 0x127, 0x0a7, 0x1a7, 0x067, 0x167, 0x0e7, 0x1e7,
104
    0x017, 0x117, 0x097, 0x197, 0x057, 0x157, 0x0d7, 0x1d7,
105
    0x037, 0x137, 0x0b7, 0x1b7, 0x077, 0x177, 0x0f7, 0x1f7,
106
    0x00f, 0x10f, 0x08f, 0x18f, 0x04f, 0x14f, 0x0cf, 0x1cf,
107
    0x02f, 0x12f, 0x0af, 0x1af, 0x06f, 0x16f, 0x0ef, 0x1ef,
108
    0x01f, 0x11f, 0x09f, 0x19f, 0x05f, 0x15f, 0x0df, 0x1df,
109
    0x03f, 0x13f, 0x0bf, 0x1bf, 0x07f, 0x17f, 0x0ff, 0x1ff,
110
    0x000, 0x040, 0x020, 0x060, 0x010, 0x050, 0x030, 0x070,
111
    0x008, 0x048, 0x028, 0x068, 0x018, 0x058, 0x038, 0x078,
112
    0x004, 0x044, 0x024, 0x064, 0x014, 0x054, 0x034, 0x074,
113
    0x003, 0x083, 0x043, 0x0c3, 0x023, 0x0a3, 0x063, 0x0e3
114
)
115 2 tomtor
 
116 6 tomtor
 
117 2 tomtor
@block
118 6 tomtor
def deflate(i_mode, o_done, i_data, o_iprogress, o_oprogress, o_byte,
119
            i_waddr, i_raddr, clk, reset):
120 2 tomtor
 
121
    """ Deflate (de)compress
122
 
123
    Ports:
124
 
125
    """
126
 
127
    iram = [Signal(intbv()[8:]) for _ in range(IBSIZE)]
128
    oram = [Signal(intbv()[8:]) for _ in range(OBSIZE)]
129
 
130 6 tomtor
    oaddr = Signal(modbv()[LOBSIZE:])
131
    oraddr = Signal(modbv()[LOBSIZE:])
132 2 tomtor
    obyte = Signal(intbv()[8:])
133
    orbyte = Signal(intbv()[8:])
134
 
135 6 tomtor
    # iraddr = Signal(modbv()[LIBSIZE:])
136 5 tomtor
 
137 6 tomtor
    isize = Signal(intbv()[LMAX:])
138 2 tomtor
    state = Signal(d_state.IDLE)
139
    method = Signal(intbv()[3:])
140
    final = Signal(bool())
141 6 tomtor
    wtick = Signal(bool())
142 2 tomtor
    do_compress = Signal(bool())
143
 
144
    numLiterals = Signal(intbv()[9:])
145
    numDistance = Signal(intbv()[6:])
146
    numCodeLength = Signal(intbv()[9:])
147
    b_numCodeLength = Signal(intbv()[9:])
148
 
149
    CodeLengths = 19
150
    MaxCodeLength = 15
151
    InstantMaxBit = 10
152
    EndOfBlock = 256
153
    MaxBitLength = 288
154
    # MaxToken = 285
155
    InvalidToken = 300
156
 
157 6 tomtor
    CODEBITS = MaxCodeLength
158
    BITBITS = 4
159 2 tomtor
 
160 6 tomtor
    codeLength = [Signal(intbv()[4:]) for _ in range(MaxBitLength+32)]
161 2 tomtor
    bits = Signal(intbv()[4:])
162
    bitLengthCount = [Signal(intbv()[9:]) for _ in range(MaxCodeLength+1)]
163 6 tomtor
    nextCode = [Signal(intbv()[CODEBITS+1:]) for _ in range(MaxCodeLength+1)]
164
    reverse = Signal(modbv()[CODEBITS:])
165
    # code_bits = [Signal(intbv()[MaxCodeLength:]) for _ in range(MaxBitLength)]
166 2 tomtor
    distanceLength = [Signal(intbv()[4:]) for _ in range(32)]
167
 
168 6 tomtor
    if DECOMPRESS:
169
        if DYNAMIC:
170
            leaves = [Signal(intbv()[CODEBITS + BITBITS:]) for _ in range(16384)]
171
            d_leaves = [Signal(intbv()[CODEBITS + BITBITS:]) for _ in range(4096)]
172
        else:
173
            leaves = [Signal(intbv()[CODEBITS + BITBITS:]) for _ in range(512)]
174
            d_leaves = [Signal(bool())]
175
        # leaves = [Signal(intbv()[CODEBITS + BITBITS:]) for _ in range(32768)]
176
        # d_leaves = [Signal(intbv()[CODEBITS + BITBITS:]) for _ in range(32768)]
177
    else:
178
        leaves = [Signal(bool())]
179
        d_leaves = [Signal(bool())]
180
    lwaddr = Signal(intbv()[MaxCodeLength:])
181
    lraddr = Signal(intbv()[MaxCodeLength:])
182
    rleaf = Signal(intbv()[CODEBITS + BITBITS:])
183 2 tomtor
    wleaf = Signal(intbv()[CODEBITS + BITBITS:])
184
    leaf = Signal(intbv()[CODEBITS + BITBITS:])
185
 
186
    minBits = Signal(intbv()[5:])
187
    maxBits = Signal(intbv()[5:])
188
    d_maxBits = Signal(intbv()[5:])
189
    instantMaxBit = Signal(intbv()[InstantMaxBit:])
190
    d_instantMaxBit = Signal(intbv()[InstantMaxBit:])
191
    instantMask = Signal(intbv()[MaxCodeLength:])
192
    d_instantMask = Signal(intbv()[MaxCodeLength:])
193 6 tomtor
    spread = Signal(intbv()[InstantMaxBit:])
194
    step = Signal(intbv()[InstantMaxBit:])
195 2 tomtor
 
196
    static = Signal(bool())
197
 
198
    code = Signal(intbv()[15:])
199
    lastToken = Signal(intbv()[15:])
200
    howOften = Signal(intbv()[9:])
201
 
202 6 tomtor
    cur_i = Signal(intbv()[LMAX:])
203 2 tomtor
    spread_i = Signal(intbv()[9:])
204 6 tomtor
    cur_HF1 = Signal(intbv()[MaxCodeLength+1:])
205 2 tomtor
    cur_static = Signal(intbv()[9:])
206 6 tomtor
    cur_cstatic = Signal(intbv()[LMAX:])
207
    # cur_search = Signal(intbv(min=-CWINDOW,max=IBSIZE))
208
    cur_search = Signal(intbv(min=-1,max=1<<LMAX))
209 2 tomtor
    cur_dist = Signal(intbv(min=-CWINDOW,max=IBSIZE))
210 6 tomtor
    cur_next = Signal(intbv()[4:])
211
    # cur_next = Signal(bool())
212 2 tomtor
 
213 6 tomtor
    length = Signal(modbv()[LOBSIZE:])
214
    offset = Signal(intbv()[LOBSIZE:])
215 2 tomtor
 
216 6 tomtor
    di = Signal(modbv()[LMAX:])
217
    old_di = Signal(intbv()[LMAX:])
218 2 tomtor
    dio = Signal(intbv()[3:])
219 6 tomtor
    do = Signal(intbv()[LMAX:])
220 2 tomtor
    doo = Signal(intbv()[3:])
221
 
222
    b1 = Signal(intbv()[8:])
223
    b2 = Signal(intbv()[8:])
224
    b3 = Signal(intbv()[8:])
225
    b4 = Signal(intbv()[8:])
226 5 tomtor
    b5 = Signal(intbv()[8:])
227 2 tomtor
 
228
    b41 = ConcatSignal(b4, b3, b2, b1)
229
    b41._markUsed()
230
 
231 5 tomtor
    b14 = ConcatSignal(b1, b2, b3, b4)
232
    b14._markUsed()
233 6 tomtor
    b15 = ConcatSignal(b1, b2, b3, b4, b5)
234 5 tomtor
 
235
    if MATCH10:
236
        b6 = Signal(intbv()[8:])
237
        b7 = Signal(intbv()[8:])
238
        b8 = Signal(intbv()[8:])
239
        b9 = Signal(intbv()[8:])
240
        b10 = Signal(intbv()[8:])
241
        b110 = ConcatSignal(b1, b2, b3, b4, b5, b6, b7, b8, b9, b10)
242
        b110._markUsed()
243
    else:
244
        b6 = Signal(bool())
245
        b7 = Signal(bool())
246
        b8 = Signal(bool())
247
        b9 = Signal(bool())
248
        b10 = Signal(bool())
249
        b110 = Signal(bool())
250
 
251 2 tomtor
    nb = Signal(intbv()[3:])
252
 
253
    filled = Signal(bool())
254
 
255
    ob1 = Signal(intbv()[8:])
256
    copy1 = Signal(intbv()[8:])
257 4 tomtor
    copy2 = Signal(intbv()[8:])
258 5 tomtor
    flush = Signal(bool())
259 2 tomtor
 
260
    adler1 = Signal(intbv()[16:])
261
    adler2 = Signal(intbv()[16:])
262
    ladler1 = Signal(intbv()[16:])
263
 
264
 
265
    @always(clk.posedge)
266
    def oramwrite():
267
        oram[oaddr].next = obyte
268
        leaves[lwaddr].next = wleaf
269
 
270
    @always(clk.posedge)
271
    def oramread():
272
        orbyte.next = oram[oraddr]
273 6 tomtor
        rleaf.next = leaves[lraddr]
274 2 tomtor
 
275 5 tomtor
    @block
276
    def matcher3(o_m, mi):
277
        @always_comb
278
        def logic():
279
            o_m.next = ((concat(cwindow,b1,b2) >> (8 * mi)) & 0xFFFFFF) == (b14 >> 8)
280
        return logic
281
 
282
    if FAST:
283
        smatch = [Signal(bool()) for _ in range(CWINDOW)]
284
        cwindow = Signal(modbv()[8 * CWINDOW:])
285
        matchers = [matcher3(smatch[mi], mi) for mi in range(CWINDOW)]
286
    else:
287
        cwindow = Signal(bool())
288
        smatch = [Signal(bool())]
289
 
290 2 tomtor
    @always(clk.posedge)
291
    def fill_buf():
292
        if not reset:
293
            print("FILL RESET")
294
            nb.next = 0
295
            b1.next = 0
296
            b2.next = 0
297
            b3.next = 0
298
            b4.next = 0
299 5 tomtor
            old_di.next = 0
300 2 tomtor
        else:
301
            if isize < 4:
302 6 tomtor
                nb.next = 0
303
                old_di.next = 0
304 2 tomtor
            elif i_mode == STARTC or i_mode == STARTD:
305
                nb.next = 0
306 5 tomtor
                old_di.next = 0
307 2 tomtor
            else:
308 5 tomtor
                """
309
                if do_compress:
310
                    print("FILL", di, old_di, nb, b1, b2, b3, b4)
311
                """
312 6 tomtor
                if FAST:  # and do_compress:
313 5 tomtor
                    shift = (di - old_di) * 8
314
                    """
315
                    if shift != 0:
316
                        print("shift", shift, cwindow, b1, b2, b3, b4)
317
                    """
318 6 tomtor
                    if MATCH10:
319 5 tomtor
                        cwindow.next = (cwindow << shift) | (b110 >> (80 - shift))
320 6 tomtor
                    else:
321
                        cwindow.next = (cwindow << shift) | (b15 >> (40 - shift))
322 5 tomtor
 
323
                if old_di == di:
324
                    nb.next = 4
325 6 tomtor
 
326 5 tomtor
                old_di.next = di
327
 
328 6 tomtor
                # print("B1", iram[di & IBS])
329 2 tomtor
                b1.next = iram[di & IBS]
330
                b2.next = iram[di+1 & IBS]
331
                b3.next = iram[di+2 & IBS]
332
                b4.next = iram[di+3 & IBS]
333 5 tomtor
                b5.next = iram[di+4 & IBS]
334
                if MATCH10:
335
                    b6.next = iram[di+5 & IBS]
336
                    b7.next = iram[di+6 & IBS]
337
                    b8.next = iram[di+7 & IBS]
338
                    b9.next = iram[di+8 & IBS]
339
                    b10.next = iram[di+9 & IBS]
340 2 tomtor
 
341
    def get4(boffset, width):
342
        if nb != 4:
343
            print("----NB----")
344
            raise Error("NB")
345
        return (b41 >> (dio + boffset)) & ((1 << width) - 1)
346
        # return b41[dio + boffset + width: dio + boffset]
347
 
348
    def adv(width):
349
        # print("adv", width, di, dio, do, doo)
350
        nshift = ((dio + width) >> 3)
351
        # print("nshift: ", nshift)
352
 
353
        o_iprogress.next = di
354
        dio.next = (dio + width) & 0x7
355
        di.next = di + nshift
356
 
357
        if nshift != 0:
358
            filled.next = False
359
 
360
    def put(d, width):
361
        if width > 9:
362
            raise Error("width > 9")
363
        if d > ((1 << width) - 1):
364
            raise Error("too big")
365
        # print("put:", d, width, do, doo, ob1, (ob1 | (d << doo)))
366
        return (ob1 | (d << doo)) & 0xFF
367
 
368
    def put_adv(d, width):
369
        if width > 9:
370
            raise Error("width > 9")
371
        if d > ((1 << width) - 1):
372
            raise Error("too big")
373
        # print("put_adv:", d, width, do, doo, di, dio)
374
        pshift = (doo + width) > 8
375
        # print("pshift: ", pshift)
376
        if pshift:
377
            carry = width - (8 - doo)
378
            # print("carry:", carry, d >> (8 - carry))
379
            ob1.next = d >> (width - carry)
380
        else:
381
            # print("put_adv:", ob1, d, doo)
382
            ob1.next = ob1 | (d << doo)
383
            # print("ob1.next", ob1 | (d << doo))
384
        do.next = do + pshift
385
        o_oprogress.next = do + pshift
386
        doo_next = (doo + width) & 0x7
387
        if doo_next == 0:
388
            flush.next = True
389
        doo.next = doo_next
390
 
391
    def do_flush():
392
        # print("FLUSH")
393
        flush.next = False
394
        ob1.next = 0
395
        o_oprogress.next = do + 1
396
        do.next = do + 1
397
 
398
    def rev_bits(b, nb):
399
        if b >= 1 << nb:
400
            raise Error("too few bits")
401
            print("too few bits")
402 6 tomtor
        if nb > 15:
403
            raise Error("nb too large")
404 2 tomtor
        r = (((b >> 14) & 0x1) << 0) | (((b >> 13) & 0x1) << 1) | \
405
            (((b >> 12) & 0x1) << 2) | (((b >> 11) & 0x1) << 3) | \
406
            (((b >> 10) & 0x1) << 4) | (((b >> 9) & 0x1) << 5) | \
407
            (((b >> 8) & 0x1) << 6) | (((b >> 7) & 0x1) << 7) | \
408
            (((b >> 6) & 0x1) << 8) | (((b >> 5) & 0x1) << 9) | \
409
            (((b >> 4) & 0x1) << 10) | (((b >> 3) & 0x1) << 11) | \
410
            (((b >> 2) & 0x1) << 12) | (((b >> 1) & 0x1) << 13) | \
411
            (((b >> 0) & 0x1) << 14)
412
        r >>= (15 - nb)
413
        return r
414
 
415
    def makeLeaf(lcode, lbits):
416
        if lcode >= 1 << CODEBITS:
417
            raise Error("code too big")
418
        if lbits >= 1 << BITBITS:
419
            raise Error("bits too big")
420
        return (lcode << BITBITS) | lbits
421
 
422
    def get_bits(aleaf):
423
        return aleaf & ((1 << BITBITS) - 1)
424
 
425
    def get_code(aleaf):
426
        return (aleaf >> BITBITS)  # & ((1 << CODEBITS) - 1)
427
 
428
    @always(clk.posedge)
429
    def io_logic():
430 6 tomtor
        o_byte.next = oram[i_raddr & OBS]
431 2 tomtor
        if i_mode == WRITE:
432
            # print("WRITE:", i_addr, i_data)
433 6 tomtor
            iram[i_waddr & IBS].next = i_data
434
            isize.next = i_waddr
435 2 tomtor
 
436
    @always(clk.posedge)
437
    def logic():
438
        if not reset:
439
            print("DEFLATE RESET")
440
            state.next = d_state.IDLE
441
            o_done.next = False
442
            # oaddr.next = 0
443
            # obyte.next = 0
444
        else:
445
 
446
            if state == d_state.IDLE:
447
 
448 5 tomtor
                if COMPRESS and i_mode == STARTC:
449 2 tomtor
 
450
                    print("STARTC")
451
                    do_compress.next = True
452
                    method.next = 1
453
                    o_done.next = False
454
                    o_iprogress.next = 0
455
                    o_oprogress.next = 0
456
                    di.next = 0
457
                    dio.next = 0
458
                    do.next = 0
459
                    doo.next = 0
460
                    filled.next = True
461
                    cur_static.next = 0
462
                    state.next = d_state.STATIC
463
 
464 6 tomtor
                elif DECOMPRESS and i_mode == STARTD:
465 2 tomtor
 
466
                    do_compress.next = False
467
                    o_done.next = False
468
                    o_iprogress.next = 0
469
                    o_oprogress.next = 0
470
                    di.next = 0
471
                    dio.next = 0
472
                    # oaddr.next = 0
473
                    do.next = 0
474
                    doo.next = 0
475
                    filled.next = True
476
                    state.next = d_state.HEADER
477
 
478
                else:
479
                    pass
480
 
481
            elif state == d_state.HEADER:
482
 
483 6 tomtor
                if not DECOMPRESS:
484
                    pass
485
                elif not filled:
486 2 tomtor
                    filled.next = True
487
                elif nb < 4:
488
                    pass
489
                # Read block header
490
                elif di == 0:
491
                    #print(iram[di & IBS])
492
                    #if iram[di & IBS] == 0x78:
493
                    if b1 == 0x78:
494
                        print("deflate mode")
495
                    else:
496
                        print(di, dio, nb, b1, b2, b3, b4, isize)
497
                        raise Error("unexpected mode")
498
                        o_done.next = True
499
                        state.next = d_state.IDLE
500
                    adv(16)
501
                else:
502
                    if get4(0, 1):
503
                        print("final")
504
                        final.next = True
505
                    hm = get4(1, 2)
506
                    method.next = hm
507
                    print("method", hm)
508
                    # print(di, dio, nb, b1, b2, b3, b4, hm, isize)
509
                    if hm == 2:
510 6 tomtor
                        if not DYNAMIC:
511
                            print("dynamic tree mode disabled")
512
                            raise Error("dynamic tree mode disabled")
513 2 tomtor
                        state.next = d_state.BL
514
                        numCodeLength.next = 0
515
                        numLiterals.next = 0
516
                        static.next = False
517
                        adv(3)
518
                    elif hm == 1:
519
                        static.next = True
520
                        cur_static.next = 0
521
                        state.next = d_state.STATIC
522
                        adv(3)
523
                    elif hm == 0:
524
                        state.next = d_state.COPY
525
                        skip = 8 - dio
526
                        if skip <= 2:
527
                            skip = 16 - dio
528
                        length.next = get4(skip, 16)
529
                        adv(skip + 16)
530
                        cur_i.next = 0
531
                        offset.next = 7
532
                    else:
533
                        state.next = d_state.IDLE
534
                        print("Bad method")
535
                        raise Error("Bad method")
536
 
537
            elif state == d_state.CSTATIC:
538
 
539
                # print("CSTATIC", cur_i, ob1, do, doo, isize)
540
 
541
                no_adv = 0
542 5 tomtor
                if not COMPRESS:
543
                    pass
544
                elif not filled:
545 2 tomtor
                    no_adv = 1
546
                    filled.next = True
547
                elif nb < 4:
548
                    no_adv = 1
549
                    pass
550
                elif cur_cstatic == 0:
551
                    flush.next = False
552
                    ob1.next = 0
553
                    adler1.next = 1
554
                    adler2.next = 0
555
                    ladler1.next = 0
556
                    oaddr.next = 0
557
                    obyte.next = 0x78
558
                elif cur_cstatic == 1:
559
                    oaddr.next = 1
560
                    obyte.next = 0x9c
561
                    do.next = 2
562
                elif cur_cstatic == 2:
563
                    oaddr.next = do
564
                    obyte.next = put(0x3, 3)
565
                    put_adv(0x3, 3)
566
                elif flush:
567 6 tomtor
                    # print("flush", do, ob1)
568 2 tomtor
                    no_adv = 1
569
                    oaddr.next = do
570
                    obyte.next = ob1
571
                    do_flush()
572 6 tomtor
                elif cur_cstatic >= isize - 10 and i_mode != IDLE:
573
                    print("P", cur_cstatic, isize)
574
                    no_adv = 1
575 2 tomtor
                elif cur_cstatic - 3 > isize:
576
                    if cur_cstatic - 3 == isize + 1:
577
                        print("Put EOF", do)
578
                        cs_i = EndOfBlock
579
                        outlen = codeLength[cs_i]
580 6 tomtor
                        outbits = out_codes[cs_i] # code_bits[cs_i]
581 2 tomtor
                        print("EOF BITS:", cs_i, outlen, outbits)
582
                        oaddr.next = do
583
                        obyte.next = put(outbits, outlen)
584
                        put_adv(outbits, outlen)
585
                    elif cur_cstatic - 3 == isize + 2:
586
                        print("calc end adler")
587
                        adler2.next = (adler2 + ladler1) % 65521
588
                        if doo != 0:
589
                            oaddr.next = do
590
                            obyte.next = ob1
591
                            do.next = do + 1
592
                    elif cur_cstatic - 3 == isize + 3:
593
                        print("c1")
594
                        oaddr.next = do
595
                        obyte.next = adler2 >> 8
596
                        do.next = do + 1
597 6 tomtor
                        o_oprogress.next = do + 1
598 2 tomtor
                    elif cur_cstatic - 3 == isize + 4:
599
                        print("c2")
600
                        oaddr.next = do
601
                        obyte.next = adler2 & 0xFF
602
                        do.next = do + 1
603 6 tomtor
                        o_oprogress.next = do + 1
604 2 tomtor
                    elif cur_cstatic - 3 == isize + 5:
605
                        print("c3")
606
                        oaddr.next = do
607
                        obyte.next = adler1 >> 8
608
                        do.next = do + 1
609 6 tomtor
                        o_oprogress.next = do + 1
610 2 tomtor
                    elif cur_cstatic - 3 == isize + 6:
611
                        print("c4")
612
                        oaddr.next = do
613
                        obyte.next = adler1 & 0xFF
614 6 tomtor
                        o_oprogress.next = do + 1
615 2 tomtor
                    elif cur_cstatic - 3 == isize + 7:
616
                        print("EOF finish", do)
617
                        o_done.next = True
618
                        state.next = d_state.IDLE
619
                    else:
620
                        print(cur_cstatic, isize)
621
                        raise Error("???")
622
                else:
623 6 tomtor
                    bdata = iram[di & IBS]
624
                    o_iprogress.next = di # & IBS
625 2 tomtor
                    adler1_next = (adler1 + bdata) % 65521
626
                    adler1.next = adler1_next
627
                    adler2.next = (adler2 + ladler1) % 65521
628
                    ladler1.next = adler1_next
629
                    # print("in: ", bdata, di, isize)
630
                    state.next = d_state.SEARCH
631 6 tomtor
                    cur_search.next = di - 1  # & IBS
632 2 tomtor
 
633
                if not no_adv:
634
                    cur_cstatic.next = cur_cstatic + 1
635
 
636
            elif state == d_state.DISTANCE:
637
 
638 5 tomtor
                if not COMPRESS:
639
                    pass
640
                elif flush:
641 2 tomtor
                    do_flush()
642 6 tomtor
                elif cur_i == 1024:
643
                    lencode = length + 254
644
                    # print("fast:", distance, di, isize, match)
645
                    outlen = codeLength[lencode]
646
                    outbits = out_codes[lencode] # code_bits[lencode]
647
                    # print("BITS:", outlen, outbits)
648
                    oaddr.next = do
649
                    obyte.next = put(outbits, outlen)
650
                    put_adv(outbits, outlen)
651
                    cur_i.next = 0
652 2 tomtor
                else:
653
                    # print("DISTANCE", di, do, cur_i, cur_dist)
654
                    nextdist = CopyDistance[cur_i+1]
655
                    if nextdist > cur_dist:
656
                        copydist = CopyDistance[cur_i]
657
                        # print("Found distance", copydist)
658
                        extra_dist = cur_dist - copydist
659
                        # print("extra dist", extra_dist)
660
                        extra_bits = ExtraDistanceBits[cur_i // 2]
661
                        # print("extra bits", extra_bits)
662
                        if extra_dist > ((1 << extra_bits) - 1):
663
                            raise Error("too few extra")
664
                        # print("rev", cur_i, rev_bits(cur_i, 5))
665
                        outcode = (rev_bits(cur_i, 5) | (extra_dist << 5))
666
                        # print("outcode", outcode)
667
                        oaddr.next = do
668
                        obyte.next = put(outcode, 5 + extra_bits)
669
                        put_adv(outcode, 5 + extra_bits)
670
                        #state.next = d_state.CSTATIC
671
                        cur_i.next = di - length + 1
672
                        state.next = d_state.CHECKSUM
673
                    else:
674
                        cur_i.next = cur_i + 1
675
 
676
            elif state == d_state.CHECKSUM:
677
 
678 5 tomtor
                if not COMPRESS:
679
                    pass
680
                elif cur_i < di:
681 2 tomtor
                    # print("CHECKSUM", cur_i, di, iram[cur_i])
682
                    bdata = iram[cur_i & IBS]
683
                    adler1_next = (adler1 + bdata) % 65521
684
                    adler1.next = adler1_next
685
                    adler2.next = (adler2 + ladler1) % 65521
686
                    ladler1.next = adler1_next
687
                    cur_i.next = cur_i.next + 1
688
                else:
689
                    state.next = d_state.CSTATIC
690
 
691 6 tomtor
            elif state == d_state.SEARCHF:
692
 
693
                if FAST and COMPRESS:
694
                    lfmatch = length
695
                    distance = lfmatch + 1
696
                    # print("FSEARCH", distance)
697
                    fmatch2 = di - lfmatch + 2
698
                    # Length is 3 code
699
                    lencode = 257
700
                    match = 3
701
 
702
                    if di < isize - 4 and \
703
                            iram[fmatch2 & IBS] == b4:
704
                        lencode = 258
705
                        match = 4
706
                        if di < isize - 5 and \
707
                                iram[fmatch2+1 & IBS] == b5:
708
                            lencode = 259
709
                            match = 5
710
                            if MATCH10 and di < isize - 6 and \
711
                                    iram[fmatch2+2 & IBS] == b6:
712
                                lencode = 260
713
                                match = 6
714
                                if di < isize - 7 and \
715
                                        iram[fmatch2+3 & IBS] == b7:
716
                                    lencode = 261
717
                                    match = 7
718
                                    if di < isize - 8 and \
719
                                            iram[fmatch2+4 & IBS] == b8:
720
                                        lencode = 262
721
                                        match = 8
722
                                        if di < isize - 9 and \
723
                                                iram[fmatch2+5 & IBS] == b9:
724
                                            lencode = 263
725
                                            match = 9
726
                                            if di < isize - 10 and \
727
                                                    iram[fmatch2+6 & IBS] == b10:
728
                                                lencode = 264
729
                                                match = 10
730
 
731
                    # distance = di - cur_search
732
                    # print("d/l", di, distance, match)
733
                    cur_dist.next = distance
734
                    cur_i.next = 1024
735
                    # adv(match * 8)
736
                    di.next = di + match
737
                    cur_cstatic.next = cur_cstatic + match - 1
738
                    length.next = match
739
                    state.next = d_state.DISTANCE
740
 
741 2 tomtor
            elif state == d_state.SEARCH:
742
 
743 5 tomtor
                if not COMPRESS:
744
                    pass
745
                elif not filled:
746 2 tomtor
                    filled.next = True
747
                elif nb < 4:
748
                    pass
749
                else:
750 6 tomtor
                    # print("cs",  cur_search, di, di - CWINDOW)
751 2 tomtor
                    if cur_search >= 0 \
752
                             and cur_search >= di - CWINDOW \
753
                             and di < isize - 3:
754 5 tomtor
 
755
                        if FAST:
756
                            found = 0
757
                            fmatch = 0
758
                            for si in range(CWINDOW):
759
                                # print("test", di, si, di - si - 1)
760
                                if smatch[si]:
761 6 tomtor
                                    # print("fmatch", si)
762 5 tomtor
                                    fmatch = si
763
                                    found = 1
764
                                    break
765
                            if not found or di - fmatch - 1 < 0:
766
                                cur_search.next = -1
767
                                # print("NO FSEARCH")
768
                            else:
769 6 tomtor
                                length.next = fmatch
770
                                state.next = d_state.SEARCHF
771 5 tomtor
 
772 6 tomtor
                        elif not FAST and iram[cur_search & IBS] == b1 and \
773 2 tomtor
                                iram[cur_search+1 & IBS] == b2 and \
774
                                iram[cur_search+2 & IBS] == b3:
775
                            # Length is 3 code
776
                            lencode = 257
777
                            match = 3
778
 
779
                            if di < isize - 4 and \
780
                                    iram[cur_search+3 & IBS] == b4: # iram[di + 3 & IBS]:
781
                                lencode = 258
782
                                match = 4
783
                                if di < isize - 5 and \
784 6 tomtor
                                        iram[cur_search+4 & IBS] == b5:
785 2 tomtor
                                    lencode = 259
786
                                    match = 5
787 5 tomtor
                                    if MATCH10 and di < isize - 6 and \
788 6 tomtor
                                            iram[cur_search+5 & IBS] == b6:
789 2 tomtor
                                        lencode = 260
790
                                        match = 6
791
                                        if di < isize - 7 and \
792 6 tomtor
                                                iram[cur_search+6 & IBS] == b7:
793 2 tomtor
                                            lencode = 261
794
                                            match = 7
795
                                            if di < isize - 8 and \
796 6 tomtor
                                                    iram[cur_search+7 & IBS] == b8:
797 2 tomtor
                                                lencode = 262
798
                                                match = 8
799
                                                if di < isize - 9 and \
800 6 tomtor
                                                        iram[cur_search+8 & IBS] == b9:
801 2 tomtor
                                                    lencode = 263
802
                                                    match = 9
803
                                                    if di < isize - 10 and \
804 6 tomtor
                                                            iram[cur_search+9 & IBS] == b10:
805 2 tomtor
                                                        lencode = 264
806
                                                        match = 10
807 5 tomtor
 
808 2 tomtor
                            distance = di - cur_search
809
                            # print("distance", distance)
810
                            cur_dist.next = distance
811 6 tomtor
                            cur_i.next = 1024  # 0
812 2 tomtor
                            # adv(match * 8)
813
                            di.next = di + match
814
                            cur_cstatic.next = cur_cstatic + match - 1
815
                            length.next = match
816
                            state.next = d_state.DISTANCE
817
                        else:
818
                            cur_search.next = cur_search - 1
819
                    else:
820 5 tomtor
                        # print("NO MATCH")
821 6 tomtor
                        bdata = b1  # iram[di]
822 2 tomtor
                        # adv(8)
823
                        di.next = di + 1
824
                        outlen = codeLength[bdata]
825 6 tomtor
                        outbits = out_codes[bdata] # code_bits[bdata]
826 2 tomtor
                        # print("CBITS:", bdata, outlen, outbits)
827
                        oaddr.next = do
828
                        obyte.next = put(outbits, outlen)
829
                        put_adv(outbits, outlen)
830
                        state.next = d_state.CSTATIC
831
 
832
            elif state == d_state.STATIC:
833
 
834
                for stat_i in range(0, 144):
835
                    codeLength[stat_i].next = 8
836
                for stat_i in range(144, 256):
837
                    codeLength[stat_i].next = 9
838
                for stat_i in range(256, 280):
839
                    codeLength[stat_i].next = 7
840
                for stat_i in range(280, 288):
841
                    codeLength[stat_i].next = 8
842
                numCodeLength.next = 288
843 6 tomtor
                if do_compress:
844
                    state.next = d_state.CSTATIC
845 2 tomtor
                else:
846
                    cur_HF1.next = 0
847
                    state.next = d_state.HF1
848
 
849
            elif state == d_state.BL:
850
 
851 6 tomtor
                if not DECOMPRESS or not DYNAMIC:
852
                    pass
853
                elif not filled:
854 2 tomtor
                    filled.next = True
855
                elif nb < 4:
856
                    pass
857
                elif numLiterals == 0:
858 6 tomtor
                    print(di, isize)
859 2 tomtor
                    numLiterals.next = 257 + get4(0, 5)
860
                    print("NL:", 257 + get4(0, 5))
861
                    numDistance.next = 1 + get4(5, 5)
862
                    print("ND:", 1 + get4(5, 5))
863
                    b_numCodeLength.next = 4 + get4(10, 4)
864
                    print("NCL:", 4 + get4(10, 4))
865
                    numCodeLength.next = 0
866
                    adv(14)
867
                else:
868
                    if numCodeLength < CodeLengths:
869
                        clo_i = CodeLengthOrder[numCodeLength]
870
                        # print("CLI: ", clo_i)
871
                        if numCodeLength < b_numCodeLength:
872
                            codeLength[clo_i].next = get4(0, 3)
873
                            adv(3)
874
                        else:
875
                            # print("SKIP")
876
                            codeLength[clo_i].next = 0
877
                        numCodeLength.next = numCodeLength + 1
878
                    else:
879
                        numCodeLength.next = CodeLengths
880
                        cur_HF1.next = 0
881
                        state.next = d_state.HF1
882
 
883
            elif state == d_state.READBL:
884
 
885 6 tomtor
                if not DECOMPRESS or not DYNAMIC:
886
                    pass
887
                elif not filled:
888 2 tomtor
                    filled.next = True
889
                elif nb < 4:
890
                    pass
891
                elif numCodeLength < numLiterals + numDistance:
892
                    # print(numLiterals + numDistance, numCodeLength)
893
                    n_adv = 0
894
                    if code < 16:
895
                        howOften.next = 1
896
                        lastToken.next = code
897
                    elif code == 16:
898
                        howOften.next = 3 + get4(0, 2)
899
                        n_adv = 2
900
                    elif code == 17:
901
                        howOften.next = 3 + get4(0, 3)
902
                        lastToken.next = 0
903
                        n_adv = 3
904
                    elif code == 18:
905
                        howOften.next = 11 + get4(0, 7)
906
                        lastToken.next = 0
907
                        n_adv = 7
908
                    else:
909
                        raise Error("Invalid data")
910
 
911
                    # print(numCodeLength, howOften, code, di, n_adv)
912
                    if n_adv != 0:
913
                        adv(n_adv)
914
 
915
                    state.next = d_state.REPEAT
916
                else:
917
                    print("FILL UP")
918
 
919
                    for dbl_i in range(32):
920
                        dbl = 0
921
                        if dbl_i + numLiterals < numCodeLength:
922
                            dbl = int(codeLength[dbl_i + numLiterals])
923
                        # print("dbl:", dbl)
924
                        distanceLength[dbl_i].next = dbl
925
 
926
                    # print(numCodeLength, numLiterals, MaxBitLength)
927
 
928
                    cur_i.next = numLiterals
929
                    state.next = d_state.INIT3
930
 
931
            elif state == d_state.INIT3:
932
 
933 6 tomtor
                if not DECOMPRESS:
934
                    pass
935
                elif cur_i < len(codeLength): # MaxBitLength:
936
                    codeLength[cur_i].next = 0
937
                    cur_i.next = cur_i + 1
938
                else:
939
                    # numCodeLength.next = MaxBitLength
940
                    method.next = 3  # Start building bit tree
941
                    cur_HF1.next = 0
942
                    state.next = d_state.HF1
943 2 tomtor
 
944
            elif state == d_state.DISTTREE:
945
 
946 6 tomtor
                if DECOMPRESS and DYNAMIC:
947
                    print("DISTTREE")
948
                    for dist_i in range(32):
949
                        codeLength[dist_i].next = distanceLength[dist_i]
950
                        # print(dist_i, distanceLength[dist_i])
951
                    numCodeLength.next = 32
952
                    method.next = 4  # Start building dist tree
953
                    cur_HF1.next = 0
954
                    state.next = d_state.HF1
955 2 tomtor
 
956
            elif state == d_state.REPEAT:
957
 
958 6 tomtor
                if not DECOMPRESS:
959
                    pass
960
                elif howOften != 0:
961 2 tomtor
                    codeLength[numCodeLength].next = lastToken
962
                    howOften.next = howOften - 1
963
                    numCodeLength.next = numCodeLength + 1
964
                elif numCodeLength < numLiterals + numDistance:
965
                    cur_next.next = 0
966
                    state.next = d_state.NEXT
967
                else:
968
                    state.next = d_state.READBL
969
 
970
            elif state == d_state.HF1:
971
 
972 6 tomtor
                if DECOMPRESS:
973
                    if cur_HF1 < len(bitLengthCount):
974
                        bitLengthCount[cur_HF1].next = 0
975
                    if cur_HF1 < len(d_leaves) and DYNAMIC:
976
                        d_leaves[cur_HF1].next = 0
977
                    if method != 4 and cur_HF1 < len(leaves):
978
                        lwaddr.next = cur_HF1
979
                        wleaf.next = 0
980
                        # leaves[cur_HF1].next = 0
981
                    limit = len(leaves)
982
                    if method == 4 and DYNAMIC:
983
                        limit = len(d_leaves)
984
                    if cur_HF1 < limit:
985
                        cur_HF1.next = cur_HF1 + 1
986
                    else:
987
                        print("DID HF1 INIT")
988
                        cur_i.next = 0
989
                        state.next = d_state.HF1INIT
990 2 tomtor
 
991
            elif state == d_state.HF1INIT:
992
                # get frequencies of each bit length and ignore 0's
993
 
994
                # print("HF1")
995 6 tomtor
                if not DECOMPRESS:
996
                    pass
997
                elif cur_i < numCodeLength:
998 2 tomtor
                    j = codeLength[cur_i]
999
                    bitLengthCount[j].next = bitLengthCount[j] + 1
1000
                    # print(cur_i, j, bitLengthCount[j] + 1)
1001
                    cur_i.next = cur_i + 1
1002
                else:
1003
                    bitLengthCount[0].next = 0
1004
                    state.next = d_state.HF2
1005
                    cur_i.next = 1
1006
                    if method == 4:
1007
                        d_maxBits.next = 0
1008
                    else:
1009
                        maxBits.next = 0
1010
                    minBits.next = MaxCodeLength
1011
 
1012
            elif state == d_state.HF2:
1013
                # shortest and longest codes
1014
 
1015
                # print("HF2")
1016 6 tomtor
                if not DECOMPRESS:
1017
                    pass
1018
                elif cur_i <= MaxCodeLength:
1019 2 tomtor
                    if bitLengthCount[cur_i] != 0:
1020
                        if cur_i < minBits:
1021
                            minBits.next = cur_i
1022
                        if method == 4:
1023
                            if cur_i > d_maxBits:
1024
                                d_maxBits.next = cur_i
1025
                        else:
1026
                            if cur_i > maxBits:
1027
                                maxBits.next = cur_i
1028
                    cur_i.next = cur_i + 1
1029
                else:
1030
                    print(minBits, maxBits)
1031
                    t = InstantMaxBit
1032 6 tomtor
                    if method == 4 and DYNAMIC:
1033 2 tomtor
                        if t > int(d_maxBits):
1034
                            t = int(d_maxBits)
1035
                        d_instantMaxBit.next = t
1036
                        d_instantMask.next = (1 << t) - 1
1037
                    else:
1038
                        if t > int(maxBits):
1039
                            t = int(maxBits)
1040
                        instantMaxBit.next = t
1041
                        instantMask.next = (1 << t) - 1
1042
                    print((1 << t) - 1)
1043
                    state.next = d_state.HF3
1044
                    cur_i.next = minBits
1045
                    code.next = 0
1046
                    for hf2_i in range(len(nextCode)):
1047
                        nextCode[hf2_i].next = 0
1048
                    print("to HF3")
1049
 
1050
            elif state == d_state.HF3:
1051
                # find bit code for first element of each bitLength group
1052
 
1053
                # print("HF3")
1054 6 tomtor
                if DECOMPRESS:
1055
                    amb = maxBits
1056
                    if method == 4 and DYNAMIC:
1057
                        amb = d_maxBits
1058
                    if cur_i <= amb:
1059
                        ncode = ((code + bitLengthCount[cur_i - 1]) << 1)
1060
                        code.next = ncode
1061
                        nextCode[cur_i].next = ncode
1062
                        # print(cur_i, ncode)
1063
                        cur_i.next = cur_i + 1
1064
                    else:
1065
                        state.next = d_state.HF4
1066
                        cur_i.next = 0
1067
                        spread_i.next = 0
1068
                        print("to HF4")
1069 2 tomtor
 
1070
            elif state == d_state.HF4_2:
1071
 
1072 6 tomtor
                if DECOMPRESS:
1073
                    canonical = nextCode[bits]
1074
                    nextCode[bits].next = nextCode[bits] + 1
1075
                    if bits > MaxCodeLength:
1076
                        raise Error("too many bits: %d" % bits)
1077
                    # print(canonical, bits)
1078
                    reverse.next = rev_bits(canonical, bits)
1079
                    # print("LEAF: ", spread_i, bits, reverse, canonical)
1080
                    leaf.next = makeLeaf(spread_i, bits)
1081
                    state.next = d_state.HF4_3
1082 2 tomtor
 
1083
            elif state == d_state.HF4_3:
1084
 
1085 6 tomtor
                if not DECOMPRESS:
1086
                    pass
1087
                elif method == 4 and DYNAMIC:
1088 2 tomtor
                    d_leaves[reverse].next = leaf # makeLeaf(spread_i, bits)
1089
                    if bits <= d_instantMaxBit:
1090
                        if reverse + (1 << bits) <= d_instantMask:
1091
                            step.next = 1 << bits
1092
                            spread.next = reverse + (1 << bits)
1093
                            state.next = d_state.SPREAD
1094
                        else:
1095
                            spread_i.next = spread_i + 1
1096
                            state.next = d_state.HF4
1097
                    else:
1098
                        state.next = d_state.HF4
1099
                        spread_i.next = spread_i + 1
1100
                else:
1101
                    wleaf.next = leaf
1102
                    lwaddr.next = reverse
1103
                    # leaves[reverse].next = leaf # makeLeaf(spread_i, bits)
1104 6 tomtor
                    # code_bits[spread_i].next = reverse
1105 2 tomtor
                    if bits <= instantMaxBit:
1106
                        if reverse + (1 << bits) <= instantMask:
1107
                            step.next = 1 << bits
1108
                            spread.next = reverse + (1 << bits)
1109
                            state.next = d_state.SPREAD
1110
                        else:
1111
                            spread_i.next = spread_i + 1
1112
                            state.next = d_state.HF4
1113
                    else:
1114
                        spread_i.next = spread_i + 1
1115
                        state.next = d_state.HF4
1116
 
1117
            elif state == d_state.HF4:
1118
                # create binary codes for each literal
1119
 
1120 6 tomtor
                if not DECOMPRESS:
1121
                    pass
1122
                elif spread_i < numCodeLength:
1123 2 tomtor
                    bits_next = codeLength[spread_i]
1124
                    if bits_next != 0:
1125
                        bits.next = bits_next
1126
                        state.next = d_state.HF4_2
1127
                    else:
1128 6 tomtor
                        # print("SKIP UNUSED")
1129 2 tomtor
                        spread_i.next = spread_i + 1
1130
                else:
1131
                    if do_compress:
1132
                        state.next = d_state.CSTATIC
1133
                        cur_cstatic.next = 0
1134 6 tomtor
                    elif method == 3 and DYNAMIC:
1135 2 tomtor
                        state.next = d_state.DISTTREE
1136 6 tomtor
                    elif method == 4 and DYNAMIC:
1137 2 tomtor
                        print("DEFLATE m2!")
1138
                        state.next = d_state.NEXT
1139 6 tomtor
                    elif method == 2 and DYNAMIC:
1140 2 tomtor
                        numCodeLength.next = 0
1141
                        state.next = d_state.NEXT
1142
                    else:
1143
                        state.next = d_state.NEXT
1144
                    cur_next.next = 0
1145
                    cur_i.next = 0
1146
 
1147
            elif state == d_state.SPREAD:
1148
 
1149 6 tomtor
                if DECOMPRESS:
1150
                    if method == 4 and DYNAMIC:
1151
                        # print(spread, spread_i)
1152
                        d_leaves[spread].next = makeLeaf(
1153
                            spread_i, codeLength[spread_i])
1154
                    else:
1155
                        lwaddr.next = spread
1156
                        wleaf.next = makeLeaf(spread_i, codeLength[spread_i])
1157
                        # leaves[spread].next = makeLeaf(spread_i, codeLength[spread_i])
1158
                    # print("SPREAD:", spread, step, instantMask)
1159
                    aim = instantMask
1160
                    if method == 4 and DYNAMIC:
1161
                        aim = d_instantMask
1162
                    if spread > aim - step:
1163
                        spread_i.next = spread_i + 1
1164
                        state.next = d_state.HF4
1165
                    else:
1166
                        spread.next = spread + step
1167 2 tomtor
 
1168
            elif state == d_state.NEXT:
1169
 
1170 6 tomtor
                if not DECOMPRESS:
1171
                    pass
1172
                elif not filled:
1173 2 tomtor
                    filled.next = True
1174
                elif nb < 4:
1175
                    pass
1176
                elif cur_next == 0:
1177
                    # print("INIT:", di, dio, instantMaxBit, maxBits)
1178
                    cto = get4(0, maxBits)
1179
                    mask = (1 << instantMaxBit) - 1
1180 6 tomtor
                    lraddr.next = (cto & mask)
1181
                    # leaf.next = leaves[cto & mask]
1182
                    filled.next = False
1183
                    cur_next.next = instantMaxBit + 1
1184 2 tomtor
                    # print(cur_next, mask, leaf, maxBits)
1185 6 tomtor
                # elif get_bits(leaf) >= cur_next:
1186
                elif get_bits(rleaf) >= cur_next:
1187
                    print("CACHE MISS", cur_next)
1188
                    cto = get4(0, maxBits)
1189
                    mask = (1 << cur_next) - 1
1190
                    lraddr.next = (cto & mask)
1191
                    # leaf.next = leaves[cto & mask]
1192
                    filled.next = False
1193
                    cur_next.next = cur_next + 1
1194 2 tomtor
                else:
1195 6 tomtor
                    # if get_bits(leaf) < 1:
1196
                    if get_bits(rleaf) < 1:
1197 2 tomtor
                        print("< 1 bits: ")
1198
                        raise Error("< 1 bits: ")
1199 6 tomtor
                    #adv(get_bits(leaf))
1200
                    adv(get_bits(rleaf))
1201
                    """
1202 2 tomtor
                    if get_code(leaf) == 0:
1203 6 tomtor
                        print("leaf 0", di, isize)
1204
                    """
1205
                    #code.next = get_code(leaf)
1206
                    code.next = get_code(rleaf)
1207 2 tomtor
                    # print("ADV:", di, get_bits(leaf), get_code(leaf))
1208 6 tomtor
                    if method == 2 and DYNAMIC:
1209 2 tomtor
                        state.next = d_state.READBL
1210
                    else:
1211
                        state.next = d_state.INFLATE
1212
 
1213
            elif state == d_state.D_NEXT:
1214
 
1215 6 tomtor
                if not DECOMPRESS or not DYNAMIC:
1216
                    pass
1217
                elif not filled:
1218 2 tomtor
                    filled.next = True
1219
                elif nb < 4:
1220
                    pass
1221 6 tomtor
                elif cur_next == 0:
1222 2 tomtor
                    # print("D_INIT:", di, dio, d_instantMaxBit, d_maxBits)
1223 6 tomtor
                    if d_instantMaxBit > InstantMaxBit:
1224
                        raise Error("???")
1225 2 tomtor
                    token = code - 257
1226
                    # print("token: ", token)
1227
                    extraLength = ExtraLengthBits[token]
1228
                    # print("extra length bits:", extraLength)
1229 6 tomtor
                    # print("d_maxBits", d_maxBits, d_instantMaxBit)
1230 2 tomtor
                    cto = get4(extraLength, d_maxBits)
1231
                    mask = (1 << d_instantMaxBit) - 1
1232
                    leaf.next = d_leaves[cto & mask]
1233 6 tomtor
                    # state.next = d_state.D_NEXT_2
1234
                    cur_next.next = instantMaxBit + 1
1235
                elif get_bits(leaf) >= cur_next:
1236
                    print("DCACHE MISS", cur_next)
1237
                    token = code - 257
1238
                    # print("token: ", token)
1239
                    extraLength = ExtraLengthBits[token]
1240
                    cto = get4(extraLength, d_maxBits)
1241
                    mask = (1 << cur_next) - 1
1242
                    leaf.next = d_leaves[cto & mask]
1243
                    cur_next.next = cur_next + 1
1244
                else:
1245 2 tomtor
                    state.next = d_state.D_NEXT_2
1246
 
1247
            elif state == d_state.D_NEXT_2:
1248
 
1249 6 tomtor
                if DECOMPRESS and DYNAMIC:
1250
                    if get_bits(leaf) == 0:
1251
                        raise Error("0 bits")
1252
                    token = code - 257
1253
                    # print("E2:", token, leaf)
1254
                    tlength = CopyLength[token]
1255
                    # print("tlength:", tlength)
1256
                    extraLength = ExtraLengthBits[token]
1257
                    # print("extra length bits:", extraLength)
1258
                    tlength += get4(0, extraLength)
1259
                    # print("extra length:", tlength)
1260
                    distanceCode = get_code(leaf)
1261
                    # print("distance code:", distanceCode)
1262
                    distance = CopyDistance[distanceCode]
1263
                    # print("distance:", distance)
1264
                    moreBits = ExtraDistanceBits[distanceCode >> 1]
1265
                    # print("more bits:", moreBits)
1266
                    # print("bits:", get_bits(leaf))
1267
                    mored = get4(extraLength + get_bits(leaf), moreBits)
1268
                    # print("mored:", mored)
1269
                    distance += mored
1270
                    # print("distance more:", distance, do, di, isize)
1271
                    if distance > do:
1272
                        print(distance, do)
1273
                        raise Error("distance too big")
1274
                    adv(moreBits + extraLength + get_bits(leaf))
1275
                    # print("offset:", do - distance)
1276
                    # print("FAIL?: ", di, dio, do, b1, b2, b3, b4)
1277
                    offset.next = (do - distance) & OBS
1278
                    length.next = tlength
1279
                    # cur_next.next = 0
1280
                    cur_i.next = 0
1281
                    oraddr.next = do - distance
1282
                    state.next = d_state.COPY
1283 2 tomtor
 
1284
            elif state == d_state.INFLATE:
1285
 
1286 6 tomtor
                if not DECOMPRESS:
1287
                    pass
1288
                elif not filled:
1289
                    filled.next = True
1290
                elif nb < 4:  # nb <= 2 or (nb == 3 and dio > 1):
1291
                    # print("EXTRA FETCH", nb, dio)
1292
                    pass  # fetch more bytes
1293
                elif di >= isize - 4 and not i_mode == IDLE:
1294
                    pass  # fetch more bytes
1295
                elif do >= i_raddr + OBSIZE: # - 10:
1296
                    # print("HOLDB")
1297
                    # filled.next = False
1298
                    pass
1299
                elif di > isize - 3:  # checksum is 4 bytes
1300
                    state.next = d_state.IDLE
1301
                    o_done.next = True
1302
                    print("NO EOF ", di)
1303
                    raise Error("NO EOF!")
1304
                elif code == EndOfBlock:
1305
                    print("EOF:", di, do)
1306
                    if not final:
1307
                        state.next = d_state.HEADER
1308
                        filled.next = False
1309
                        print("New Block!")
1310
                    else:
1311
                        o_done.next = True
1312 2 tomtor
                        state.next = d_state.IDLE
1313 6 tomtor
                else:
1314
                    if code < EndOfBlock:
1315
                        # print("B:", code, di, do)
1316
                        oaddr.next = do
1317
                        obyte.next = code
1318
                        o_oprogress.next = do + 1
1319
                        do.next = do + 1
1320
                        cur_next.next = 0
1321
                        state.next = d_state.NEXT
1322
                        # raise Error("DF!")
1323
                    elif code == InvalidToken:
1324
                        raise Error("invalid token")
1325 2 tomtor
                    else:
1326 6 tomtor
                        if static:
1327
                            token = code - 257
1328
                            # print("E:", token)
1329
                            tlength = CopyLength[token]
1330
                            # print("tlength", tlength)
1331
                            extraLength = ExtraLengthBits[token]
1332
                            # print("extralengthbits", extraLength)
1333
                            tlength += get4(0, extraLength)
1334
                            # print("tlength extra", tlength)
1335
                            t = get4(extraLength, 5)
1336
                            distanceCode = rev_bits(t, 5)
1337
                            # print("dcode", distanceCode)
1338
                            distance = CopyDistance[distanceCode]
1339
                            # print("distance", distance)
1340
                            moreBits = ExtraDistanceBits[distanceCode
1341
                                                            >> 1]
1342
                            distance += get4(extraLength + 5, moreBits)
1343
                            # print("distance2", distance)
1344
                            adv(extraLength + 5 + moreBits)
1345
                            # print("adv", extraLength + 5 + moreBits)
1346
                            offset.next = do - distance
1347
                            length.next = tlength
1348
                            cur_i.next = 0
1349
                            oraddr.next = do - distance
1350
                            state.next = d_state.COPY
1351 2 tomtor
                        else:
1352 6 tomtor
                            if not DYNAMIC:
1353
                                print("DYNAMIC mode disabled")
1354
                                raise Error("DYNAMIC mode disabled")
1355
                            state.next = d_state.D_NEXT
1356
                    cur_next.next = 0
1357 2 tomtor
 
1358
            elif state == d_state.COPY:
1359
 
1360 6 tomtor
                if not DECOMPRESS:
1361
                    pass
1362
                elif not filled:
1363 2 tomtor
                    filled.next = True
1364
                elif nb < 4:
1365
                    pass
1366 6 tomtor
                elif cur_i == 0 and do + length >= i_raddr + OBSIZE: # - 10:
1367
                    # print("HOLDW", length, offset, cur_i, do, i_raddr)
1368
                    pass
1369
                elif di >= isize - 2:
1370
                    # print("HOLD2")
1371
                    pass
1372 2 tomtor
                elif method == 0:
1373
                    if cur_i < length:
1374
                        oaddr.next = do
1375
                        obyte.next = b3
1376
                        adv(8)
1377
                        cur_i.next = cur_i + 1
1378
                        do.next = do + 1
1379
                        o_oprogress.next = do + 1
1380
                    elif not final:
1381 6 tomtor
                        adv(16)
1382 2 tomtor
                        state.next = d_state.HEADER
1383 6 tomtor
                        filled.next = False
1384
                        print("new block")
1385 2 tomtor
                    else:
1386
                        o_done.next = True
1387
                        state.next = d_state.IDLE
1388 4 tomtor
                elif cur_i < length + 2:
1389 6 tomtor
                    # print("L/O", length, offset)
1390 2 tomtor
                    oraddr.next = offset + cur_i
1391
                    if cur_i == 1:
1392
                        copy1.next = orbyte
1393 4 tomtor
                        # print("c1", cur_i, length, offset, do, orbyte)
1394
                    if cur_i == 3:
1395
                        copy2.next = orbyte
1396 2 tomtor
                    if cur_i > 1:
1397 4 tomtor
                        # Special 1 byte offset handling:
1398 6 tomtor
                        if (offset + cur_i) & OBS == (do + 1) & OBS:
1399 2 tomtor
                            obyte.next = copy1
1400 6 tomtor
                        elif cur_i == 3 or (offset + cur_i) & OBS != do & OBS:
1401
                            obyte.next = orbyte
1402 4 tomtor
                        # Special 2 byte offset handling:
1403
                        elif cur_i > 2:
1404
                            if cur_i & 1:
1405
                                obyte.next = copy2
1406
                            else:
1407
                                obyte.next = copy1
1408
                        else:  # cur_i == 2
1409
                            obyte.next = copy1
1410 2 tomtor
                        oaddr.next = do
1411
                        o_oprogress.next = do + 1
1412
                        do.next = do + 1
1413
                    cur_i.next = cur_i + 1
1414
                else:
1415
                    cur_next.next = 0
1416
                    state.next = d_state.NEXT
1417
 
1418
            else:
1419
 
1420
                print("unknown state?!")
1421
                state.next = d_state.IDLE
1422
 
1423 5 tomtor
    if FAST:
1424
        return io_logic, logic, fill_buf, oramwrite, oramread, matchers
1425
    else:
1426
        return io_logic, logic, fill_buf, oramwrite, oramread
1427 2 tomtor
 
1428
 
1429
if __name__ == "__main__":
1430
    d = deflate(Signal(intbv()[3:]), Signal(bool(0)),
1431 6 tomtor
                Signal(intbv()[8:]), Signal(intbv()[LMAX:]),
1432
                Signal(intbv()[LMAX:]),
1433
                Signal(intbv()[8:]),
1434
                Signal(modbv()[LIBSIZE:]), Signal(modbv()[LBSIZE:]),
1435 2 tomtor
                Signal(bool(0)), ResetSignal(1, 0, True))
1436
    d.convert()

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.