Line 15... |
Line 15... |
from myhdl import always, block, Signal, intbv, Error, ResetSignal, \
|
from myhdl import always, block, Signal, intbv, Error, ResetSignal, \
|
enum, always_seq, always_comb, concat, ConcatSignal, modbv
|
enum, always_seq, always_comb, concat, ConcatSignal, modbv
|
|
|
IDLE, RESET, WRITE, READ, STARTC, STARTD = range(6)
|
IDLE, RESET, WRITE, READ, STARTC, STARTD = range(6)
|
|
|
|
COMPRESS = True
|
|
MATCH10 = False
|
|
MATCH10 = True
|
|
|
|
FAST = False
|
|
FAST = True
|
|
|
CWINDOW = 32 # Search window for compression
|
CWINDOW = 32 # Search window for compression
|
|
|
OBSIZE = 8192 # Size of output buffer (BRAM)
|
OBSIZE = 8192 # Size of output buffer (BRAM)
|
IBSIZE = 4 * CWINDOW # 2048 # Size of input buffer (LUT-RAM)
|
IBSIZE = 4 * CWINDOW # 2048 # Size of input buffer (LUT-RAM)
|
|
|
if OBSIZE > IBSIZE:
|
if OBSIZE > IBSIZE:
|
LBSIZE = log2(OBSIZE)
|
LBSIZE = int(log2(OBSIZE))
|
else:
|
else:
|
LBSIZE = log2(IBSIZE)
|
LBSIZE = int(log2(IBSIZE))
|
|
|
IBS = (1 << int(log2(IBSIZE))) - 1
|
LIBSIZE = int(log2(IBSIZE))
|
|
IBS = (1 << LIBSIZE) - 1
|
|
|
d_state = enum('IDLE', 'HEADER', 'BL', 'READBL', 'REPEAT', 'DISTTREE', 'INIT3',
|
d_state = enum('IDLE', 'HEADER', 'BL', 'READBL', 'REPEAT', 'DISTTREE', 'INIT3',
|
'HF1', 'HF1INIT', 'HF2', 'HF3', 'HF4', 'HF4_2', 'HF4_3',
|
'HF1', 'HF1INIT', 'HF2', 'HF3', 'HF4', 'HF4_2', 'HF4_3',
|
'STATIC', 'D_NEXT', 'D_NEXT_2',
|
'STATIC', 'D_NEXT', 'D_NEXT_2',
|
'D_INFLATE', 'SPREAD', 'NEXT', 'INFLATE', 'COPY', 'CSTATIC',
|
'D_INFLATE', 'SPREAD', 'NEXT', 'INFLATE', 'COPY', 'CSTATIC',
|
Line 67... |
Line 75... |
oaddr = Signal(intbv()[LBSIZE:])
|
oaddr = Signal(intbv()[LBSIZE:])
|
oraddr = Signal(intbv()[LBSIZE:])
|
oraddr = Signal(intbv()[LBSIZE:])
|
obyte = Signal(intbv()[8:])
|
obyte = Signal(intbv()[8:])
|
orbyte = Signal(intbv()[8:])
|
orbyte = Signal(intbv()[8:])
|
|
|
|
iraddr = Signal(intbv()[LIBSIZE:])
|
|
|
isize = Signal(intbv()[LBSIZE:])
|
isize = Signal(intbv()[LBSIZE:])
|
state = Signal(d_state.IDLE)
|
state = Signal(d_state.IDLE)
|
method = Signal(intbv()[3:])
|
method = Signal(intbv()[3:])
|
final = Signal(bool())
|
final = Signal(bool())
|
do_compress = Signal(bool())
|
do_compress = Signal(bool())
|
Line 144... |
Line 154... |
|
|
b1 = Signal(intbv()[8:])
|
b1 = Signal(intbv()[8:])
|
b2 = Signal(intbv()[8:])
|
b2 = Signal(intbv()[8:])
|
b3 = Signal(intbv()[8:])
|
b3 = Signal(intbv()[8:])
|
b4 = Signal(intbv()[8:])
|
b4 = Signal(intbv()[8:])
|
|
b5 = Signal(intbv()[8:])
|
|
|
b41 = ConcatSignal(b4, b3, b2, b1)
|
b41 = ConcatSignal(b4, b3, b2, b1)
|
b41._markUsed()
|
b41._markUsed()
|
|
|
|
b14 = ConcatSignal(b1, b2, b3, b4)
|
|
b14._markUsed()
|
|
|
|
if MATCH10:
|
|
b6 = Signal(intbv()[8:])
|
|
b7 = Signal(intbv()[8:])
|
|
b8 = Signal(intbv()[8:])
|
|
b9 = Signal(intbv()[8:])
|
|
b10 = Signal(intbv()[8:])
|
|
b110 = ConcatSignal(b1, b2, b3, b4, b5, b6, b7, b8, b9, b10)
|
|
b110._markUsed()
|
|
else:
|
|
b6 = Signal(bool())
|
|
b7 = Signal(bool())
|
|
b8 = Signal(bool())
|
|
b9 = Signal(bool())
|
|
b10 = Signal(bool())
|
|
b110 = Signal(bool())
|
|
|
nb = Signal(intbv()[3:])
|
nb = Signal(intbv()[3:])
|
|
|
filled = Signal(bool())
|
filled = Signal(bool())
|
|
|
ob1 = Signal(intbv()[8:])
|
ob1 = Signal(intbv()[8:])
|
copy1 = Signal(intbv()[8:])
|
copy1 = Signal(intbv()[8:])
|
copy2 = Signal(intbv()[8:])
|
copy2 = Signal(intbv()[8:])
|
flush = Signal(bool(0))
|
flush = Signal(bool())
|
|
|
adler1 = Signal(intbv()[16:])
|
adler1 = Signal(intbv()[16:])
|
adler2 = Signal(intbv()[16:])
|
adler2 = Signal(intbv()[16:])
|
ladler1 = Signal(intbv()[16:])
|
ladler1 = Signal(intbv()[16:])
|
|
|
Line 172... |
Line 202... |
@always(clk.posedge)
|
@always(clk.posedge)
|
def oramread():
|
def oramread():
|
orbyte.next = oram[oraddr]
|
orbyte.next = oram[oraddr]
|
# rleaf.next = leaves[lraddr]
|
# rleaf.next = leaves[lraddr]
|
|
|
|
@block
|
|
def matcher3(o_m, mi):
|
|
@always_comb
|
|
def logic():
|
|
o_m.next = ((concat(cwindow,b1,b2) >> (8 * mi)) & 0xFFFFFF) == (b14 >> 8)
|
|
return logic
|
|
|
|
if FAST:
|
|
smatch = [Signal(bool()) for _ in range(CWINDOW)]
|
|
cwindow = Signal(modbv()[8 * CWINDOW:])
|
|
matchers = [matcher3(smatch[mi], mi) for mi in range(CWINDOW)]
|
|
else:
|
|
cwindow = Signal(bool())
|
|
smatch = [Signal(bool())]
|
|
|
@always(clk.posedge)
|
@always(clk.posedge)
|
def fill_buf():
|
def fill_buf():
|
if not reset:
|
if not reset:
|
print("FILL RESET")
|
print("FILL RESET")
|
nb.next = 0
|
nb.next = 0
|
b1.next = 0
|
b1.next = 0
|
b2.next = 0
|
b2.next = 0
|
b3.next = 0
|
b3.next = 0
|
b4.next = 0
|
b4.next = 0
|
|
old_di.next = 0
|
else:
|
else:
|
if isize < 4:
|
if isize < 4:
|
pass
|
pass
|
elif i_mode == STARTC or i_mode == STARTD:
|
elif i_mode == STARTC or i_mode == STARTD:
|
nb.next = 0
|
nb.next = 0
|
|
old_di.next = 0
|
else:
|
else:
|
# print("FILL", di, isize)
|
"""
|
|
if do_compress:
|
|
print("FILL", di, old_di, nb, b1, b2, b3, b4)
|
|
"""
|
|
if FAST: # and nb == 4:
|
|
shift = (di - old_di) * 8
|
|
"""
|
|
if shift != 0:
|
|
print("shift", shift, cwindow, b1, b2, b3, b4)
|
|
"""
|
|
if shift <= 32:
|
|
cwindow.next = (cwindow << shift) | (b14 >> (32 - shift))
|
|
elif shift == 40:
|
|
cwindow.next = (cwindow << shift) | (b14 << 8) | b5
|
|
elif MATCH10:
|
|
cwindow.next = (cwindow << shift) | (b110 >> (80 - shift))
|
|
|
|
if old_di == di:
|
nb.next = 4
|
nb.next = 4
|
|
# wtick.next = True
|
|
old_di.next = di
|
|
|
|
# iraddr.next = di
|
b1.next = iram[di & IBS]
|
b1.next = iram[di & IBS]
|
b2.next = iram[di+1 & IBS]
|
b2.next = iram[di+1 & IBS]
|
b3.next = iram[di+2 & IBS]
|
b3.next = iram[di+2 & IBS]
|
b4.next = iram[di+3 & IBS]
|
b4.next = iram[di+3 & IBS]
|
|
b5.next = iram[di+4 & IBS]
|
|
if MATCH10:
|
|
b6.next = iram[di+5 & IBS]
|
|
b7.next = iram[di+6 & IBS]
|
|
b8.next = iram[di+7 & IBS]
|
|
b9.next = iram[di+8 & IBS]
|
|
b10.next = iram[di+9 & IBS]
|
"""
|
"""
|
@always(clk.posedge)
|
@always(clk.posedge)
|
def fill_buf():
|
def fill_buf():
|
if not reset:
|
if not reset:
|
print("FILL RESET")
|
print("FILL RESET")
|
Line 213... |
Line 288... |
nb.next = 0
|
nb.next = 0
|
elif not filled and nb == 4 and di - old_di <= 4:
|
elif not filled and nb == 4 and di - old_di <= 4:
|
delta = di - old_di
|
delta = di - old_di
|
if delta == 1:
|
if delta == 1:
|
# print("delta == 1")
|
# print("delta == 1")
|
|
if FAST:
|
|
cwindow.next = (cwindow << 8) | b1
|
b1.next = b2
|
b1.next = b2
|
b2.next = b3
|
b2.next = b3
|
b3.next = b4
|
b3.next = b4
|
b4.next = iram[di+3 & IBS]
|
b4.next = iram[di+3 & IBS]
|
# nb.next = 4
|
# nb.next = 4
|
elif delta == 2:
|
elif delta == 2:
|
|
print("delta == 2")
|
|
if FAST:
|
|
cwindow.next = (cwindow << 16) | (b14 >> 16)
|
b1.next = b3
|
b1.next = b3
|
b2.next = b4
|
b2.next = b4
|
b3.next = iram[di+2 & IBS]
|
b3.next = iram[di+2 & IBS]
|
nb.next = 3
|
nb.next = 3
|
elif delta == 3:
|
elif delta == 3:
|
|
print("delta == 3")
|
|
if FAST:
|
|
cwindow.next = (cwindow << 24) | (b14 >> 8)
|
b1.next = b4
|
b1.next = b4
|
b2.next = iram[di+1 & IBS]
|
b2.next = iram[di+1 & IBS]
|
nb.next = 2
|
nb.next = 2
|
elif delta == 4:
|
elif delta == 4:
|
|
print("delta == 4")
|
|
if FAST:
|
|
cwindow.next = (cwindow << 32) | (b14)
|
b1.next = iram[di & IBS]
|
b1.next = iram[di & IBS]
|
nb.next = 1
|
nb.next = 1
|
else:
|
else:
|
pass
|
pass
|
elif not filled or nb == 0:
|
elif not filled or nb == 0:
|
# print("nb.next = 1")
|
print("nb = 0")
|
b1.next = iram[di & IBS]
|
b1.next = iram[di & IBS]
|
nb.next = 1
|
nb.next = 1
|
elif not filled or nb == 1:
|
elif not filled or nb == 1:
|
|
print("nb = 1")
|
b2.next = iram[di+1 & IBS]
|
b2.next = iram[di+1 & IBS]
|
nb.next = 2
|
nb.next = 2
|
elif not filled or nb == 2:
|
elif not filled or nb == 2:
|
|
print("nb = 2")
|
|
# raise Error("nb == 2")
|
b3.next = iram[di+2 & IBS]
|
b3.next = iram[di+2 & IBS]
|
nb.next = 3
|
nb.next = 3
|
elif not filled or nb == 3:
|
elif not filled or nb == 3:
|
|
print("nb = 3")
|
b4.next = iram[di+3 & IBS]
|
b4.next = iram[di+3 & IBS]
|
nb.next = 4
|
nb.next = 4
|
else:
|
else:
|
pass
|
pass
|
old_di.next = di
|
old_di.next = di
|
Line 364... |
Line 454... |
# obyte.next = 0
|
# obyte.next = 0
|
else:
|
else:
|
|
|
if state == d_state.IDLE:
|
if state == d_state.IDLE:
|
|
|
if i_mode == STARTC:
|
if COMPRESS and i_mode == STARTC:
|
|
|
print("STARTC")
|
print("STARTC")
|
do_compress.next = True
|
do_compress.next = True
|
method.next = 1
|
method.next = 1
|
o_done.next = False
|
o_done.next = False
|
Line 453... |
Line 543... |
elif state == d_state.CSTATIC:
|
elif state == d_state.CSTATIC:
|
|
|
# print("CSTATIC", cur_i, ob1, do, doo, isize)
|
# print("CSTATIC", cur_i, ob1, do, doo, isize)
|
|
|
no_adv = 0
|
no_adv = 0
|
if not filled:
|
if not COMPRESS:
|
|
pass
|
|
elif not filled:
|
no_adv = 1
|
no_adv = 1
|
filled.next = True
|
filled.next = True
|
elif nb < 4:
|
elif nb < 4:
|
no_adv = 1
|
no_adv = 1
|
pass
|
pass
|
Line 535... |
Line 627... |
adler1.next = adler1_next
|
adler1.next = adler1_next
|
adler2.next = (adler2 + ladler1) % 65521
|
adler2.next = (adler2 + ladler1) % 65521
|
ladler1.next = adler1_next
|
ladler1.next = adler1_next
|
# print("in: ", bdata, di, isize)
|
# print("in: ", bdata, di, isize)
|
state.next = d_state.SEARCH
|
state.next = d_state.SEARCH
|
cur_search.next = di - 1 # - 3
|
cur_search.next = di - 1
|
|
|
if not no_adv:
|
if not no_adv:
|
cur_cstatic.next = cur_cstatic + 1
|
cur_cstatic.next = cur_cstatic + 1
|
|
|
elif state == d_state.DISTANCE:
|
elif state == d_state.DISTANCE:
|
|
|
if flush:
|
if not COMPRESS:
|
|
pass
|
|
elif flush:
|
do_flush()
|
do_flush()
|
else:
|
else:
|
# print("DISTANCE", di, do, cur_i, cur_dist)
|
# print("DISTANCE", di, do, cur_i, cur_dist)
|
nextdist = CopyDistance[cur_i+1]
|
nextdist = CopyDistance[cur_i+1]
|
if nextdist > cur_dist:
|
if nextdist > cur_dist:
|
Line 570... |
Line 664... |
else:
|
else:
|
cur_i.next = cur_i + 1
|
cur_i.next = cur_i + 1
|
|
|
elif state == d_state.CHECKSUM:
|
elif state == d_state.CHECKSUM:
|
|
|
if cur_i < di:
|
if not COMPRESS:
|
|
pass
|
|
elif cur_i < di:
|
# print("CHECKSUM", cur_i, di, iram[cur_i])
|
# print("CHECKSUM", cur_i, di, iram[cur_i])
|
bdata = iram[cur_i & IBS]
|
bdata = iram[cur_i & IBS]
|
adler1_next = (adler1 + bdata) % 65521
|
adler1_next = (adler1 + bdata) % 65521
|
adler1.next = adler1_next
|
adler1.next = adler1_next
|
adler2.next = (adler2 + ladler1) % 65521
|
adler2.next = (adler2 + ladler1) % 65521
|
Line 583... |
Line 679... |
else:
|
else:
|
state.next = d_state.CSTATIC
|
state.next = d_state.CSTATIC
|
|
|
elif state == d_state.SEARCH:
|
elif state == d_state.SEARCH:
|
|
|
if not filled:
|
if not COMPRESS:
|
|
pass
|
|
elif not filled:
|
filled.next = True
|
filled.next = True
|
elif nb < 4:
|
elif nb < 4:
|
pass
|
pass
|
else:
|
else:
|
if cur_search >= 0 \
|
if cur_search >= 0 \
|
and cur_search >= di - CWINDOW \
|
and cur_search >= di - CWINDOW \
|
and di < isize - 3:
|
and di < isize - 3:
|
if iram[cur_search & IBS] == b1 and \
|
|
|
if FAST:
|
|
found = 0
|
|
fmatch = 0
|
|
for si in range(CWINDOW):
|
|
# print("test", di, si, di - si - 1)
|
|
if smatch[si]:
|
|
print("fmatch", si)
|
|
fmatch = si
|
|
found = 1
|
|
break
|
|
if not found or di - fmatch - 1 < 0:
|
|
cur_search.next = -1
|
|
# print("NO FSEARCH")
|
|
else:
|
|
distance = fmatch + 1
|
|
# print("FSEARCH", distance)
|
|
fmatch = di - fmatch + 2
|
|
# Length is 3 code
|
|
lencode = 257
|
|
match = 3
|
|
|
|
if di < isize - 4 and \
|
|
iram[fmatch & IBS] == b4:
|
|
lencode = 258
|
|
match = 4
|
|
if di < isize - 5 and \
|
|
iram[fmatch+1 & IBS] == b5:
|
|
lencode = 259
|
|
match = 5
|
|
if MATCH10 and di < isize - 6 and \
|
|
iram[fmatch+2 & IBS] == b6:
|
|
lencode = 260
|
|
match = 6
|
|
if di < isize - 7 and \
|
|
iram[fmatch+3 & IBS] == b7:
|
|
lencode = 261
|
|
match = 7
|
|
if di < isize - 8 and \
|
|
iram[fmatch+4 & IBS] == b8:
|
|
lencode = 262
|
|
match = 8
|
|
if di < isize - 9 and \
|
|
iram[fmatch+5 & IBS] == b9:
|
|
lencode = 263
|
|
match = 9
|
|
if di < isize - 10 and \
|
|
iram[fmatch+6 & IBS] == b10:
|
|
lencode = 264
|
|
match = 10
|
|
|
|
print("fast:", distance, di, isize, match)
|
|
outlen = codeLength[lencode]
|
|
outbits = code_bits[lencode]
|
|
# print("BITS:", outlen, outbits)
|
|
oaddr.next = do
|
|
obyte.next = put(outbits, outlen)
|
|
put_adv(outbits, outlen)
|
|
|
|
# distance = di - cur_search
|
|
# print("distance", distance)
|
|
cur_dist.next = distance
|
|
cur_i.next = 0
|
|
# adv(match * 8)
|
|
di.next = di + match
|
|
cur_cstatic.next = cur_cstatic + match - 1
|
|
length.next = match
|
|
state.next = d_state.DISTANCE
|
|
|
|
elif iram[cur_search & IBS] == b1 and \
|
iram[cur_search+1 & IBS] == b2 and \
|
iram[cur_search+1 & IBS] == b2 and \
|
iram[cur_search+2 & IBS] == b3:
|
iram[cur_search+2 & IBS] == b3:
|
# Length is 3 code
|
# Length is 3 code
|
lencode = 257
|
lencode = 257
|
match = 3
|
match = 3
|
Line 606... |
Line 773... |
match = 4
|
match = 4
|
if di < isize - 5 and \
|
if di < isize - 5 and \
|
iram[cur_search+4 & IBS] == iram[di + 4 & IBS]:
|
iram[cur_search+4 & IBS] == iram[di + 4 & IBS]:
|
lencode = 259
|
lencode = 259
|
match = 5
|
match = 5
|
"""
|
if MATCH10 and di < isize - 6 and \
|
if di < isize - 6 and \
|
iram[cur_search+5 & IBS] == iram[di + 5 & IBS]:
|
iram[cur_search+5 & IBS] == iram[di + 5 & IBS]:
|
lencode = 260
|
lencode = 260
|
match = 6
|
match = 6
|
if di < isize - 7 and \
|
if di < isize - 7 and \
|
iram[cur_search+6 & IBS] == iram[di + 6 & IBS]:
|
iram[cur_search+6 & IBS] == iram[di + 6 & IBS]:
|
lencode = 261
|
lencode = 261
|
match = 7
|
match = 7
|
if di < isize - 8 and \
|
if di < isize - 8 and \
|
iram[cur_search+7 & IBS] == iram[di + 7 & IBS]:
|
iram[cur_search+7 & IBS] == iram[di + 7 & IBS]:
|
lencode = 262
|
lencode = 262
|
match = 8
|
match = 8
|
if di < isize - 9 and \
|
if di < isize - 9 and \
|
iram[cur_search+8 & IBS] == iram[di + 8 & IBS]:
|
iram[cur_search+8 & IBS] == iram[di + 8 & IBS]:
|
lencode = 263
|
lencode = 263
|
match = 9
|
match = 9
|
if di < isize - 10 and \
|
if di < isize - 10 and \
|
iram[cur_search+9 & IBS] == iram[di + 9 & IBS]:
|
iram[cur_search+9 & IBS] == iram[di + 9 & IBS]:
|
lencode = 264
|
lencode = 264
|
match = 10
|
match = 10
|
|
"""
|
|
print("found:", cur_search, di, isize, match)
|
print("found:", cur_search, di, isize, match)
|
outlen = codeLength[lencode]
|
outlen = codeLength[lencode]
|
outbits = code_bits[lencode]
|
outbits = code_bits[lencode]
|
# print("BITS:", outlen, outbits)
|
# print("BITS:", outlen, outbits)
|
oaddr.next = do
|
oaddr.next = do
|
Line 648... |
Line 814... |
length.next = match
|
length.next = match
|
state.next = d_state.DISTANCE
|
state.next = d_state.DISTANCE
|
else:
|
else:
|
cur_search.next = cur_search - 1
|
cur_search.next = cur_search - 1
|
else:
|
else:
|
|
# print("NO MATCH")
|
bdata = iram[di]
|
bdata = iram[di]
|
# adv(8)
|
# adv(8)
|
di.next = di + 1
|
di.next = di + 1
|
outlen = codeLength[bdata]
|
outlen = codeLength[bdata]
|
outbits = code_bits[bdata]
|
outbits = code_bits[bdata]
|
Line 1072... |
Line 1239... |
if not filled:
|
if not filled:
|
filled.next = True
|
filled.next = True
|
elif nb < 4: # nb <= 2 or (nb == 3 and dio > 1):
|
elif nb < 4: # nb <= 2 or (nb == 3 and dio > 1):
|
# print("EXTRA FETCH", nb, dio)
|
# print("EXTRA FETCH", nb, dio)
|
pass # fetch more bytes
|
pass # fetch more bytes
|
elif di > isize - 3: # checksum is 4 bytes
|
elif di > isize: # - 3: # checksum is 4 bytes
|
state.next = d_state.IDLE
|
state.next = d_state.IDLE
|
o_done.next = True
|
o_done.next = True
|
print("NO EOF ", di)
|
print("NO EOF ", di)
|
raise Error("NO EOF!")
|
raise Error("NO EOF!")
|
elif code == EndOfBlock:
|
elif code == EndOfBlock:
|
Line 1182... |
Line 1349... |
else:
|
else:
|
|
|
print("unknown state?!")
|
print("unknown state?!")
|
state.next = d_state.IDLE
|
state.next = d_state.IDLE
|
|
|
|
if FAST:
|
|
return io_logic, logic, fill_buf, oramwrite, oramread, matchers
|
|
else:
|
return io_logic, logic, fill_buf, oramwrite, oramread
|
return io_logic, logic, fill_buf, oramwrite, oramread
|
|
|
|
|
if __name__ == "__main__":
|
if __name__ == "__main__":
|
d = deflate(Signal(intbv()[3:]), Signal(bool(0)),
|
d = deflate(Signal(intbv()[3:]), Signal(bool(0)),
|