2023-07-23 14:53:18 +02:00

163 lines
8.4 KiB
Python

from migen import *
from migen.genlib.fifo import *
from litex.soc.interconnect.csr import *
class Zscreen(Module, AutoCSR):
def __init__(self, platform, wb, width=1920, height=1080, depth=8):
self.trace_data = trace_data = CSRStorage(32, description = "trace_data")
self.submodules.fifo = fifo = SyncFIFOBuffered(width=32,depth=128)
self.comb += [
fifo.din.eq(trace_data.storage),
fifo.we.eq(trace_data.re),
]
#curx = Signal(12, reset = (width-136))
#cury = Signal(12, reset = (8))
default_address = (0x8f800000 + (width-138) + (width*24) ) // 4 # FIXME: for 8 MiB FB only IMPROVEME: assumes 32-bits WB
last_address = (0x8f800000 + (width-138) + (width*1072)) // 4 # FIXME: for 8 MiB FB only IMPROVEME: assumes 32-bits WB
address_increment = (width) // 4
#default_address = (0x8f800000 + width//2 + width*height//2) // 4
#last_address = (0x8f800000 + width//2 + width*(height-8)) // 4
#address_increment = (width) // 4
base_address = Signal(30, reset = default_address) # IMPROVEME: assumes 32-bits WB
cur_address = Signal(30)
print(f"TRACE: displaying @ 0x{default_address*4:08x} with increment {address_increment*4}")
cur_nib_idx = Signal(3)
cur_line_idx = Signal(3)
val = Signal(32)
cur_nib = Signal(4)
self.comb += [
Case((cur_nib_idx ^ 1), { ## nibble-swap for proper order
x: cur_nib.eq(val[(4*x):(4*x+4)]) for x in range(0, 8)
}),
]
cur_nib_decoded = Signal(8)
self.submodules.fsm = fsm = FSM(reset_state="Reset")
saw_ongoing = Signal()
saw_re = Signal()
saw_readable= Signal()
self.sync += [
If(~fsm.ongoing("Idle"),
saw_ongoing.eq(1),
),
If(trace_data.re,
saw_re.eq(1),
),
If(fifo.readable,
saw_readable.eq(1),
),
]
if (False):
led0 = platform.request("user_led", 0)
led1 = platform.request("user_led", 1)
led2 = platform.request("user_led", 2)
led3 = platform.request("user_led", 3)
led4 = platform.request("user_led", 4)
led5 = platform.request("user_led", 5)
led6 = platform.request("user_led", 6)
led7 = platform.request("user_led", 7)
self.comb += [
led0.eq(~fsm.ongoing("Idle")),
led1.eq(trace_data.re),
led2.eq(fifo.readable),
led3.eq(0),
led4.eq(saw_ongoing),
led5.eq(saw_re),
led6.eq(saw_readable),
led7.eq(trace_data.storage[0]),
]
# set up wishbone
self.comb += [
wb.we.eq(1),
wb.sel.eq(0xF),
wb.adr.eq(cur_address),
]
fsm.act("Reset",
NextState("Idle"),
)
fsm.act("Idle",
If(fifo.readable,
NextValue(val, fifo.dout),
NextValue(cur_line_idx, 0),
NextValue(cur_nib_idx, 0),
NextValue(cur_address, base_address),
fifo.re.eq(1),
NextState("StartWriteLow"),
),
)
fsm.act("StartWriteLow",
wb.cyc.eq(1),
wb.stb.eq(1),
wb.dat_w.eq(Cat(Replicate(cur_nib_decoded[7], 8), Replicate(cur_nib_decoded[6], 8), Replicate(cur_nib_decoded[5], 8), Replicate(cur_nib_decoded[4], 8))),
If(wb.ack,
NextValue(cur_address, cur_address + 1),
NextState("StartWriteHigh"),
),
)
fsm.act("StartWriteHigh",
wb.cyc.eq(1),
wb.stb.eq(1),
wb.dat_w.eq(Cat(Replicate(cur_nib_decoded[3], 8), Replicate(cur_nib_decoded[2], 8), Replicate(cur_nib_decoded[1], 8), Replicate(cur_nib_decoded[0], 8))),
If(wb.ack,
If((cur_line_idx == 7) & (cur_nib_idx == 7),
#If(base_address == last_address,
# NextValue(base_address, default_address),
#).Else(
NextValue(base_address, base_address + address_increment),
#),
NextState("Idle"),
).Elif(cur_nib_idx == 7,
NextValue(base_address, base_address + address_increment),
NextValue(cur_address, base_address + address_increment),
NextValue(cur_nib_idx, 0),
NextValue(cur_line_idx, cur_line_idx + 1),
NextState("StartWriteLow"),
).Else(
NextValue(cur_address, cur_address + 1),
NextValue(cur_nib_idx, cur_nib_idx + 1),
NextState("StartWriteLow"),
)
),
)
self.comb += [
Case((cur_line_idx), {
0: cur_nib_decoded.eq(0),
7: cur_nib_decoded.eq(0),
1: Case(cur_nib, {
0:cur_nib_decoded.eq(0x18), 1:cur_nib_decoded.eq(0x10), 2:cur_nib_decoded.eq(0x18), 3:cur_nib_decoded.eq(0x38), 4:cur_nib_decoded.eq(0x20), 5:cur_nib_decoded.eq(0x3c), 6:cur_nib_decoded.eq(0x1c), 7:cur_nib_decoded.eq(0x3c), 8:cur_nib_decoded.eq(0x18), 9:cur_nib_decoded.eq(0x18), 10:cur_nib_decoded.eq(0x18), 11:cur_nib_decoded.eq(0x38), 12:cur_nib_decoded.eq(0x18), 13:cur_nib_decoded.eq(0x38), 14:cur_nib_decoded.eq(0x3c), 15:cur_nib_decoded.eq(0x3c),
}),
2: Case(cur_nib, {
0:cur_nib_decoded.eq(0x24), 1:cur_nib_decoded.eq(0x30), 2:cur_nib_decoded.eq(0x24), 3:cur_nib_decoded.eq(0x04), 4:cur_nib_decoded.eq(0x28), 5:cur_nib_decoded.eq(0x20), 6:cur_nib_decoded.eq(0x20), 7:cur_nib_decoded.eq(0x04), 8:cur_nib_decoded.eq(0x24), 9:cur_nib_decoded.eq(0x24), 10:cur_nib_decoded.eq(0x24), 11:cur_nib_decoded.eq(0x24), 12:cur_nib_decoded.eq(0x24), 13:cur_nib_decoded.eq(0x24), 14:cur_nib_decoded.eq(0x20), 15:cur_nib_decoded.eq(0x20),
}),
3: Case(cur_nib, {
0:cur_nib_decoded.eq(0x2c), 1:cur_nib_decoded.eq(0x10), 2:cur_nib_decoded.eq(0x04), 3:cur_nib_decoded.eq(0x18), 4:cur_nib_decoded.eq(0x28), 5:cur_nib_decoded.eq(0x38), 6:cur_nib_decoded.eq(0x38), 7:cur_nib_decoded.eq(0x08), 8:cur_nib_decoded.eq(0x18), 9:cur_nib_decoded.eq(0x24), 10:cur_nib_decoded.eq(0x24), 11:cur_nib_decoded.eq(0x38), 12:cur_nib_decoded.eq(0x20), 13:cur_nib_decoded.eq(0x24), 14:cur_nib_decoded.eq(0x38), 15:cur_nib_decoded.eq(0x38),
}),
4: Case(cur_nib, {
0:cur_nib_decoded.eq(0x34), 1:cur_nib_decoded.eq(0x10), 2:cur_nib_decoded.eq(0x18), 3:cur_nib_decoded.eq(0x04), 4:cur_nib_decoded.eq(0x3c), 5:cur_nib_decoded.eq(0x04), 6:cur_nib_decoded.eq(0x24), 7:cur_nib_decoded.eq(0x10), 8:cur_nib_decoded.eq(0x24), 9:cur_nib_decoded.eq(0x1c), 10:cur_nib_decoded.eq(0x3c), 11:cur_nib_decoded.eq(0x24), 12:cur_nib_decoded.eq(0x20), 13:cur_nib_decoded.eq(0x24), 14:cur_nib_decoded.eq(0x20), 15:cur_nib_decoded.eq(0x20),
}),
5: Case(cur_nib, {
0:cur_nib_decoded.eq(0x24), 1:cur_nib_decoded.eq(0x10), 2:cur_nib_decoded.eq(0x20), 3:cur_nib_decoded.eq(0x04), 4:cur_nib_decoded.eq(0x08), 5:cur_nib_decoded.eq(0x04), 6:cur_nib_decoded.eq(0x24), 7:cur_nib_decoded.eq(0x10), 8:cur_nib_decoded.eq(0x24), 9:cur_nib_decoded.eq(0x04), 10:cur_nib_decoded.eq(0x24), 11:cur_nib_decoded.eq(0x24), 12:cur_nib_decoded.eq(0x24), 13:cur_nib_decoded.eq(0x24), 14:cur_nib_decoded.eq(0x20), 15:cur_nib_decoded.eq(0x20),
}),
6: Case(cur_nib, {
0:cur_nib_decoded.eq(0x18), 1:cur_nib_decoded.eq(0x38), 2:cur_nib_decoded.eq(0x3c), 3:cur_nib_decoded.eq(0x38), 4:cur_nib_decoded.eq(0x08), 5:cur_nib_decoded.eq(0x38), 6:cur_nib_decoded.eq(0x18), 7:cur_nib_decoded.eq(0x10), 8:cur_nib_decoded.eq(0x18), 9:cur_nib_decoded.eq(0x38), 10:cur_nib_decoded.eq(0x24), 11:cur_nib_decoded.eq(0x38), 12:cur_nib_decoded.eq(0x18), 13:cur_nib_decoded.eq(0x38), 14:cur_nib_decoded.eq(0x3c), 15:cur_nib_decoded.eq(0x20),
}),
}
),
]