This commit is contained in:
2020-08-15 02:59:40 +02:00
parent 18bf707fdc
commit 5702101d03
14 changed files with 599 additions and 65 deletions

123
fpga/modules/bad_apple.dg Normal file
View File

@@ -0,0 +1,123 @@
#!/usr/bin/env -S python3 -m dg
import "/nmigen/cli/main"
import "/nmigen/sim/pysim/Simulator"
import "/nmigen_dg/*"
import "/os/path" qualified
import "../common/deduce_ports"
RleXorPrevDecoder = subclass Elaboratable where
__init__ = w h data ~> None where
@w, @h, @data, @size = w, h, data, w*h
@pixel_x = Signal$ range w # pixel being output
@pixel_y = Signal$ range h # pixel being output
@pixel_data = Signal! # data of pixel being output
@pixel_valid = Signal! # wether pixel being output is valid
@next = Signal! # pulse this to start decoding next frame
elaborate = platform ~> m where with m = Module! =>
# Default output
Sync$ @pixel_valid ::= 0
# Data to decode
data_mem = Memory # TODO: use spi flash instead
width: 8
depth: (len @data)
init: (list$ bytearray$ @data)
rddata = Submodule.rddata$ data_mem.read_port!
# RLE decoder state:
pixel = Signal 1
pixel_prev = Signal 1
n_times = Signal 14
# XOR Frame buffer
frame = Memory
width: 1
depth: @size
rdframe = Submodule.rdframe$ frame.read_port!
wrframe = Submodule.wrframe$ frame.write_port!
offset = Signal$ range @size
Comb$ rdframe.addr ::= offset
Comb$ wrframe.addr ::= offset
Sync$ wrframe.en ::= 0
do_write_pixel = Signal!
pixel_to_write = Signal!
Comb$ do_write_pixel ::= 0 # TODO: needed?
When do_write_pixel $ ->
Sync$ @pixel_data ::= (rdframe.data ^ pixel_to_write)
Sync$ wrframe.data ::= (rdframe.data ^ pixel_to_write)
Sync$ @pixel_valid ::= 1
Sync$ wrframe.en ::= 1
Sync$ offset ::= offset + 1 # needs to start at -1
Sync$ @pixel_y ::= @pixel_y + 1
When (@pixel_y == @h - 1) $ ->
Sync$ @pixel_y ::= 0
Sync$ @pixel_x ::= @pixel_x + 1
# RLE & XOR Decoder
FSM
DECODED ->
When @next $ ->
Sync$ offset ::= -1 # max int
Sync$ @pixel_y ::= -1 # max int
Sync$ @pixel_x ::= 0
DECODED |>. READ
READ ->
Sync$ pixel ::= rddata.data !! 7
Sync$ n_times ::= rddata.data !! slice 0 6 # TODO: proper slicing syntax would be nice
Sync$ rddata.addr ::= rddata.addr + 1
When
rddata.data !! 6 ,-> READ |>. READ_MORE
otherwise ,-> READ |>. WRITE_PIXELS_BEGIN
READ_MORE ->
Sync$ n_times ::= ((n_times << 8) | rddata.data)
Sync$ rddata.addr ::= rddata.addr + 1
READ_MORE |>. WRITE_PIXELS_BEGIN
WRITE_PIXELS_BEGIN ->
is_first = offset == 0
has_changed = pixel != pixel_prev
When (~has_changed & ~is_first) $ -> # there was an omitted n_values=1 in between
Comb$ pixel_to_write ::= ~pixel
Comb$ do_write_pixel ::= 1
Sync$ pixel_prev ::= pixel
WRITE_PIXELS_BEGIN |>. WRITE_PIXELS
WRITE_PIXELS ->
Comb$ pixel_to_write ::= pixel
Comb$ do_write_pixel ::= 1
Sync$ n_times ::= n_times - 1
When (n_times == 1) $ -> When # == 0 next cycle
offset == @size - 1 ,-> WRITE_PIXELS |>. DECODED
otherwise ,-> WRITE_PIXELS |>. READ
BadAppleDecoder = -> RleXorPrevDecoder 85 64 bad_apple_data where
fname = os.path.join
os.path.dirname __file__
"data"
"bad_apple.bin"
with f = open fname "rb" =>
bad_apple_data = f.read!
bad_apple_data = bad_apple_data !! slice 0 ((len bad_apple_data) // 58) # TODO: use full movie when we've moved data to spi flash
print ((len bad_apple_data) // 58)
#bad_apple_data = b"0000"
if __name__ == "__main__" =>
design = RleXorPrevDecoder 85 64 b"1234"
ports = deduce_ports design
main design
name: "bad_apple"
ports: ports

Binary file not shown.