@@ 100,12 100,13 @@ class PixelStream(Module):
]
class LCDLineInput(Module):
- def __init__(self, lcd, capture, ddr_inp):
+ def __init__(self, lcd, ddr_inp):
self.valid = Signal(name='line_valid')
# rightmost pixel in MSB, leftmost pixel in LSB
self.line = Signal(LINE_BITS, name='line_shiftreg')
self.frame_done = Signal()
+ self.start_capture = Signal(reset=0)
self.capturing = Signal(reset=0)
self.submodules.pixels = PixelStream(lcd, ddr_inp)
@@ 114,7 115,7 @@ class LCDLineInput(Module):
self.sync += [
# Only start/stop capturing at the start of a frame
- If(self.pixels.frame_start, self.capturing.eq(capture)),
+ If(self.pixels.frame_start, self.capturing.eq(self.start_capture)),
self.frame_done.eq(self.pixels.frame_start & self.capturing)
]
@@ 129,41 130,39 @@ class LCDLineInput(Module):
)
]
-class PixelsToUART(Module):
- def __init__(self, lcd, serial, clk_period_ns, baud_rate, ddr_inp):
- self.capture = Signal(reset=0)
-
- self.submodules.lcd = LCDLineInput(lcd, self.capture, ddr_inp)
- self.submodules.fifo = SyncFIFOBuffered(8, LINE_BYTES + 1)
-
- self.submodules.uart = uart.RS232PHY(serial, clk_period_ns, baud_rate)
- self.frame_done = self.lcd.frame_done
-
+class CompressToUART(Module):
+ def __init__(self, line_data, line_valid, serial, clk_period_ns, baud_rate):
+ self.capture_req = Signal(reset=0)
self.error = Signal()
+ # lines --> compressor --> fifo --> UART
+ # output FIFO can buffer a whole uncompressed line so the compression of
+ # the next line should always be able to overlap the output of a line
self.submodules.compress = compress.CompressFrames(LINE_PX, FRAME_HEIGHT, 1024)
+ self.submodules.fifo = SyncFIFOBuffered(8, LINE_BYTES + 1)
+ self.submodules.uart = uart.RS232PHY(serial, clk_period_ns, baud_rate)
###
self.comb += [
- self.compress.input.data.eq(self.lcd.line),
- self.compress.input.valid.eq(self.lcd.valid),
+ self.compress.input.data.eq(line_data),
+ self.compress.input.valid.eq(line_valid),
self.fifo.din.eq(self.compress.output.data),
self.fifo.we.eq(self.compress.output.valid),
self.compress.output.ready.eq(self.fifo.writable),
]
self.sync += [
- If(self.lcd.valid & ~self.compress.input.ready, self.error.eq(1)),
+ If(line_valid & ~self.compress.input.ready, self.error.eq(1)),
]
self.sync += [
# Start capture on frame start after UART rx
- If(self.uart.rx.valid, self.capture.eq(1)),
+ If(self.uart.rx.valid, self.capture_req.eq(1)),
# Stop on error (fifo overflow), and clear the error so it is
# possible to start caturing again
If(self.error,
- self.capture.eq(0),
+ self.capture_req.eq(0),
self.error.eq(0)),
]
@@ 173,6 172,19 @@ class PixelsToUART(Module):
self.uart.tx.data.eq(self.fifo.dout)
]
+class PixelsToUART(Module):
+ def __init__(self, lcd, serial, clk_period_ns, baud_rate, ddr_inp):
+ self.submodules.lcd = LCDLineInput(lcd, ddr_inp)
+ self.submodules.comp_out = CompressToUART(self.lcd.line, self.lcd.valid,
+ serial, clk_period_ns, baud_rate)
+
+ self.frame_done = self.lcd.frame_done
+ self.error = self.comp_out.error
+
+ ###
+
+ self.comb += self.lcd.start_capture.eq(self.comp_out.capture_req)
+
if __name__ == '__main__':
import sys
if sys.argv[1] == 'build':
@@ 217,7 229,7 @@ if __name__ == '__main__':
yield dut.loopback.tx.valid.eq(0)
# Wait for capture to start (byte received)
- while (yield dut.pixel_uart.capture) == 0:
+ while (yield dut.pixel_uart.lcd.start_capture) == 0:
yield
yield from gen(dut)
@@ 228,7 240,7 @@ if __name__ == '__main__':
codec = compress_ref.CODEC(LINE_PX, FRAME_HEIGHT, 4)
compressed = list(codec.compress(lines))
- output = dut.pixel_uart.compress.output
+ output = dut.pixel_uart.comp_out.compress.output
for i, b in enumerate(compressed):
while (yield output.valid) == 0 or (yield output.ready) == 0:
yield
@@ 272,3 284,31 @@ if __name__ == '__main__':
dut = DUT()
run_simulation(dut, [tx(dut), rx(dut), check_comp_out(dut)], vcd_name='out.vcd')
+
+ elif sys.argv[1] == 'verilator':
+ import utils
+ from migen.fhdl.verilog import convert
+ class TB(Module):
+ def __init__(self):
+ self.serial_pads = Record([('tx', 1), ('rx', 1)])
+ self.loop_serial_pads = Record([('tx', 1), ('rx', 1)])
+ self.line_pads = Record([('data', 320), ('valid', 1)])
+ self.submodules.compress = CompressToUART(
+ self.line_pads.data, self.line_pads.valid, self.serial_pads,
+ 31.25, baud_rate=2000000)
+ self.submodules.loopback = uart.RS232PHY(self.loop_serial_pads, 31.25, baud_rate=2000000)
+
+ self.comb += [
+ self.serial_pads.rx.eq(self.loop_serial_pads.tx),
+ self.loop_serial_pads.rx.eq(self.serial_pads.tx)
+ ]
+
+ tb = TB()
+ ios = {
+ tb.line_pads.data, tb.line_pads.valid,
+ tb.loopback.tx.data, tb.loopback.tx.valid,
+ tb.loopback.rx.data, tb.loopback.rx.valid,
+ }
+ c = convert(tb, ios=ios)
+ utils.update_verilog_if_changed('gbcap_tb.v', c)
+ utils.verilate(['gbcap_tb.v', 'gbcap_tb_wrap.cpp'], output='gbcap_tb')