oc_jpegencode 1.0 JPEGencoder

interfaces.py
Go to the documentation of this file.
1 """
2 A driver and monitor to abstract the interface to the JPEG encoder
3 """
4
5 import io
6 from PIL import Image
7
8 import cocotb
9 from cocotb.triggers import RisingEdge, ReadOnly
10 from cocotb.drivers import Driver
11 from cocotb.monitors import Monitor
12
13 _jpeg_header = open("header.bin", "r").read()
14
15 class JpegMonitor(Monitor):
16
17 def __init__(self, dut, **kwargs):
18 self.dut = dut
19 Monitor.__init__(self, **kwargs)
20
21 @cocotb.coroutine
22 def _monitor_recv(self):
23 """Creates an Image object from the output of the DUT"""
24 data = ""
25
26 clkedge = RisingEdge(self.dut.clk)
27 ro = ReadOnly()
28 while True:
29 yield clkedge
30 yield ro
31 if self.dut.data_ready.value:
32 data += self.dut.JPEG_bitstream.value.buff
33 if self.dut.eof_data_partial_ready.value:
34 f_obj = io.BytesIO(_jpeg_header + data + "\xff\xd9")
35 img = Image.open(f_obj)
36 self.log.info("Recovered image %s of %dx%d in mode %s" % (
37 img.format, img.size[0], img.size[1], img.mode))
38 yield clkedge
39 self._recv(img)
40 data = ""
41
42
43 class ImageDriver(Driver):
44
45 def __init__(self, dut):
46 self.dut = dut
47 Driver.__init__(self)
48
49 @cocotb.coroutine
50 def _driver_send(self, image, **kwargs):
51 """
52 Send an image into the DUT. Image should be in RGB format and a
53 multiple of 8 pixels in both width and height
54
55 Args:
56
57 image (PIL.Image) image to send into the dut
58 """
59 if image.mode != "RGB": # pragma: no cover
60 raise TypeError("Require an format RGB image")
61
62 width, height = image.size
63 dut = self.dut # Local reference to save lookup
64 clk_edge = RisingEdge(dut.clk) # Recycle objects for efficiency
65
66 yield clk_edge # Reset the dut first
67 dut.rst <= 1
68 yield clk_edge
69 dut.rst <= 0
70 dut.end_of_file_signal <= 0
71
72 pixels = image.load()
73
74 for y in xrange(0,height,8):
75 for x in xrange(0,width,8):
76 dut.enable <= 1
77
78 self.log.debug("Sending block X% 4d/% 4d, Y% 4d/% 4d" % (
79 x, width, y, height))
80
81 if y >= height-8 and x >= width-8:
82 dut.end_of_file_signal <= 1
83
84 for y_block in xrange(8):
85 for x_block in xrange(8):
86 # If the image isn't a multiple of 8 pixels we
87 # repeat the edge values (see Readme.doc)
88 x_ofs = min(x+x_block, width-1)
89 y_ofs = min(y+y_block, height-1)
90
91 r,g,b = pixels[x_ofs, y_ofs]
92 dut.data_in <= (b<<16 | g<<8 | r)
93 yield clk_edge
94 dut.end_of_file_signal <= 0
95
96 for i in xrange(33):
97 yield clk_edge
98
99 dut.enable <= 0
100 yield clk_edge
101
interfaces.JpegMonitor._monitor_recv
def _monitor_recv( self)
Definition: interfaces.py:22
interfaces.JpegMonitor.dut
dut
Definition: interfaces.py:18
interfaces.JpegMonitor.__init__
def __init__( self, dut, kwargs)
Definition: interfaces.py:17
interfaces.ImageDriver.__init__
def __init__( self, dut)
Definition: interfaces.py:45
interfaces.ImageDriver.dut
dut
Definition: interfaces.py:46
interfaces.ImageDriver._driver_send
def _driver_send( self, image, kwargs)
Definition: interfaces.py:50