{ "cells": [ { "cell_type": "markdown", "id": "1dfb41b6", "metadata": {}, "source": [ "# Vector/Pipelining scenario #1: RGB to YUV conversion\n", "\n", "Example RGB to YUV conversion (simplified, not clamping)\n", "\n", "**Note** Not verified for correct conversion, concept study only\n", "\n", "Makes use of the `VectorSig` data type and the simple `@pipeline` decorator." ] }, { "cell_type": "code", "execution_count": 1, "id": "6d8214c3", "metadata": {}, "outputs": [], "source": [ "!pip install numpy > /dev/null" ] }, { "cell_type": "markdown", "id": "3b32d6ee", "metadata": {}, "source": [ "Import video types:" ] }, { "cell_type": "code", "execution_count": 2, "id": "d3e79eea", "metadata": {}, "outputs": [], "source": [ "from video.color import *\n", "from video.videotypes import *" ] }, { "cell_type": "markdown", "id": "2f79ee5c", "metadata": {}, "source": [ "Import pipeline and target auxiliaries:" ] }, { "cell_type": "code", "execution_count": 3, "id": "56975585", "metadata": {}, "outputs": [], "source": [ "from myirl.library.pipeline import *\n", "from myirl import targets" ] }, { "cell_type": "markdown", "id": "8d9edb7e", "metadata": {}, "source": [ "Construct the conversion matrix, in this case for JPEG-compliant YCrCb:" ] }, { "cell_type": "code", "execution_count": 4, "id": "2b7ab395", "metadata": {}, "outputs": [], "source": [ "CLAMP = False\n", "LEVELSHIFT = False\n", "BPP = 8\n", "FRACT_SIZE = 16\n", "CALCSIZE = FRACT_SIZE + BPP\n", "SATURATION_VALUE_MAX = 127 # YUV maximum value (saturation)\n", "SATURATION_VALUE_MIN = -128 # YUV minimum value (saturation)\n", "\n", "\n", "# Signed matrix entries:\n", "Y_FROM_RGB = vector_to_fp(FRACT_SIZE, 1, mat_jpeg_rgb2yuv[0])\n", "U_FROM_RGB = vector_to_fp(FRACT_SIZE, 1, mat_jpeg_rgb2yuv[1])\n", "V_FROM_RGB = vector_to_fp(FRACT_SIZE, 1, mat_jpeg_rgb2yuv[2])\n", "\n", "def F(x, s = FRACT_SIZE):\n", " return intbv(x)[s:]\n", "\n", "YUV_SLICE = slice(CALCSIZE-1, CALCSIZE-1 - BPP)\n", "\n", "MATRIX = [\n", " [ F(Y_FROM_RGB[i]) for i in range(3) ],\n", " [ F(U_FROM_RGB[i]) for i in range(3) ],\n", " [ F(V_FROM_RGB[i]) for i in range(3) ]\n", "]\n", "\n", "from myirl.vector import VectorSignal\n", "\n", "I = lambda x: ( x[i]._val for i in range(3) )\n", "\n", "# @bulkwrapper()\n", "# class RGBParam:\n", "# def __init__(self):\n", "# self.y = VectorSig(3, MATRIX[0], initializer = I(MATRIX[0]))\n", "# self.u = VectorSig(3, MATRIX[1], initializer = I(MATRIX[1]))\n", "# self.v = VectorSig(3, MATRIX[1], initializer = I(MATRIX[2]))" ] }, { "cell_type": "code", "execution_count": 5, "id": "6c10fdd7", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[[intbv(9797), intbv(19234), intbv(3735)],\n", " [intbv(60007), intbv(54682), intbv(16384)],\n", " [intbv(16384), intbv(51817), intbv(62872)]]" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "MATRIX" ] }, { "cell_type": "code", "execution_count": 6, "id": "f5ef10e3", "metadata": {}, "outputs": [], "source": [ "from myirl import simulation as sim\n", "from myirl.test.common_test import gen_osc\n", "\n", "@block\n", "def video_rgb_yuv(clk : ClkSignal,\n", " vin : VideoPort,\n", " rgb : Signal,\n", " param_matrix : list,\n", " vout : VideoPort.Output,\n", " yuv : Signal.Output,):\n", " \"\"\"RGB to full range YUV422 converter, manual pipeline inference\"\"\"\n", " \n", " py, pu, pv = [\n", " VectorSignal(3, F(0), initializer = I(param_matrix[i]), name = \"p_coef%d\" % i) \\\n", " for i in range(3)\n", " ]\n", " \n", " # Use initializers:\n", " py._init = True\n", " pu._init = True\n", " pv._init = True\n", " \n", " valid = Signal(bool())\n", " \n", " rgb_v = VectorSignal(3, FractUnsigned(0, BPP), name = 'rgbv')\n", " \n", " a = VectorSignal(3, FractSigned(0, CALCSIZE+2), name = \"add_res\")\n", " y = VectorSignal(3, FractUnsigned(0, CALCSIZE), name = \"ydata\")\n", " u, v = [ VectorSignal(3, FractSigned(0, CALCSIZE+1), name = n) for n in ['udata', 'vdata'] ]\n", "\n", " # Wire up input RGB video:\n", " wires = []\n", " for i in range(3):\n", " j = 3 - i\n", " wires.append(rgb_v[i].wireup(rgb[j*BPP:(j-1)*BPP]))\n", "\n", " # Predefine YUV slices\n", " yuv_slices = (a[i][YUV_SLICE] for i in range(3) )\n", " \n", " wires += [\n", " yuv.wireup(\n", " concat(*yuv_slices)\n", " ) \n", " ]\n", " \n", " @pipeline(clk, None, ce = vin.dval, pass_in = vin, pass_out = vout)\n", " def yuv_pipe(ctx):\n", " \"\"\"This contains the two-stage transformation for the RGB-YUV matrix.\n", "Because it's a vector signal, we can use HDL notation (<=)\"\"\"\n", " yield [ \n", " y <= (py * rgb_v),\n", " u <= (pu.signed() * rgb_v),\n", " v <= (pv.signed() * rgb_v) \n", " ]\n", "\n", " # Create sum expressions for readability:\n", " _y, _u, _v = (i.sum() for i in [y, u, v])\n", " \n", " yield [ \n", " a[0].set(_y.signed()),\n", " a[1].set(_u),\n", " a[2].set(_v) \n", " ]\n", "\n", " return locals()\n" ] }, { "cell_type": "markdown", "id": "3677184a", "metadata": {}, "source": [ "### Testbench" ] }, { "cell_type": "code", "execution_count": 7, "id": "7cb8ffd1", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\u001b[7;35m Declare obj 'testbench_rgb2yuv' in context '(DesignModule 'top')' \u001b[0m\n" ] } ], "source": [ "from myirl.targets import VHDL\n", "from myirl.test.common_test import run_ghdl\n", "\n", "d = DesignModule(\"top\", debug = True)\n", "\n", "@component(d)\n", "def testbench_rgb2yuv():\n", " clk = ClkSignal(name = \"pclk\")\n", " yuv = Signal(intbv(0)[3*BPP:])\n", " vint, vout = [VideoPort() for _ in range(2)]\n", " \n", " yuv = Signal(intbv(0)[3*BPP:], name = 'yuv_data')\n", " rgb = Signal(intbv(0)[3*BPP:], name = 'rgb_data')\n", "\n", " \n", " inst = video_rgb_yuv(clk = clk,\n", " vin = vint,\n", " rgb = rgb,\n", " param_matrix = MATRIX,\n", " vout = vout,\n", " yuv = yuv\n", " )\n", " \n", " osc = gen_osc(clk, CYCLE = 5)\n", " \n", " @sim.generator\n", " def stimulus(): \n", " \n", " # Feed a few color values:\n", " values = sim.Iterator([0x00ffff, 0x7f7f7f, 0x008300, 0x1a840a])\n", " \n", " yield [\n", " vint.dval.set(False), vint.fval.set(True), vint.lval.set(True),\n", " sim.wait(4 * [ clk.posedge, ] ), \n", " vint.dval.set(True),\n", " sim.For(values)(\n", " sim.wait('1 ns'),\n", " rgb.set(values),\n", " sim.wait(2 * [clk.posedge]),\n", " sim.print_(yuv),\n", " ),\n", "\n", " sim.wait(3 * [ clk.posedge, ] ), \n", " sim.assert_(vout.dval == True, \"Video not valid\"),\n", " ]\n", "\n", " for _ in range(3):\n", " yield [\n", " sim.print_(yuv),\n", " sim.wait(clk.posedge), \n", " ]\n", "\n", " yield [\n", " sim.raise_(sim.StopSimulation)\n", " ]\n", " \n", " return locals()\n", "\n", "def test():\n", " tb = testbench_rgb2yuv()\n", " files = tb.elab(VHDL, elab_all = True)\n", " run_ghdl(files, tb, debug = True, vcdfile=\"yuv.vcd\")\n", " return files, tb" ] }, { "cell_type": "code", "execution_count": 8, "id": "707357e9", "metadata": { "scrolled": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "DEBUG GET CONTEXT [Component 'video_rgb_yuv/video_rgb_yuv']\n", "Adding param_matrix to port dict (fallback)\n", "\u001b[32m Insert unit video_rgb_yuv_s1dval_1_slval_1_sfval_1_s24_l3dval_1_slval_1_sfval_1_s24 \u001b[0m\n", "\u001b[32m Insert unit testbench_rgb2yuv \u001b[0m\n", "DEBUG Skip latency accounting for `ydata`\n", "DEBUG Skip latency accounting for `udata`\n", "DEBUG Skip latency accounting for `vdata`\n", "DEBUG Skip latency accounting for `add_res`\n", " DEBUG: Skip array for evaluation: 'ydata' \n", " DEBUG: Skip array for evaluation: 'udata' \n", " DEBUG: Skip array for evaluation: 'vdata' \n", " DEBUG: Skip array for evaluation: 'p_coef0' \n", " DEBUG: Skip array for evaluation: 'rgbv' \n", " DEBUG: Skip array for evaluation: 'p_coef1' \n", " DEBUG: Skip array for evaluation: 'p_coef2' \n", " DEBUG: Skip array for evaluation: 'ydata' \n", " DEBUG: Skip array for evaluation: 'udata' \n", " DEBUG: Skip array for evaluation: 'vdata' \n", " DEBUG: Skip array for evaluation: 'p_coef0' \n", " DEBUG: Skip array for evaluation: 'rgbv' \n", " DEBUG: Skip array for evaluation: 'p_coef1' \n", " DEBUG: Skip array for evaluation: 'p_coef2' \n", " DEBUG: Skip array for evaluation: 'ydata' \n", " DEBUG: Skip array for evaluation: 'udata' \n", " DEBUG: Skip array for evaluation: 'vdata' \n", " DEBUG: Skip array for evaluation: 'p_coef0' \n", " DEBUG: Skip array for evaluation: 'rgbv' \n", " DEBUG: Skip array for evaluation: 'p_coef1' \n", " DEBUG: Skip array for evaluation: 'p_coef2' \n", " DEBUG: Skip array for evaluation: 'ydata' \n", " DEBUG: Skip array for evaluation: 'udata' \n", " DEBUG: Skip array for evaluation: 'vdata' \n", " DEBUG: Skip array for evaluation: 'p_coef0' \n", " DEBUG: Skip array for evaluation: 'rgbv' \n", " DEBUG: Skip array for evaluation: 'p_coef1' \n", " DEBUG: Skip array for evaluation: 'p_coef2' \n", " DEBUG: Skip array for evaluation: 'ydata' \n", " DEBUG: Skip array for evaluation: 'udata' \n", " DEBUG: Skip array for evaluation: 'vdata' \n", " DEBUG: Skip array for evaluation: 'p_coef0' \n", " DEBUG: Skip array for evaluation: 'rgbv' \n", " DEBUG: Skip array for evaluation: 'p_coef1' \n", " DEBUG: Skip array for evaluation: 'p_coef2' \n", " Writing 'video_rgb_yuv' to file /tmp/video_rgb_yuv.vhdl \n", "Warning: Implicit truncation of ADD(ADD(udata, udata), udata) result\n", "Warning: Implicit truncation of ADD(ADD(vdata, vdata), vdata) result\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "/home/testing/.local/lib/python3.9/site-packages/myirl-0.0.0-py3.9-linux-x86_64.egg/myirl/library/pipeline.py:147: TranslationWarning: yuv_pipe(): `ce` (type ) is not a pipeline signal\n", " base.warn(\"%s(): `ce` (type %s) is not a pipeline signal\" % (func.__name__, type(ce)))\n", "/home/testing/.local/lib/python3.9/site-packages/myirl-0.0.0-py3.9-linux-x86_64.egg/myirl/library/pipeline.py:177: TranslationWarning: /tmp/ipykernel_172075/1859329269.py::video_rgb_yuv:47: `p_coef0` (type ) is not a pipeline signal\n", " base.warn(\"%s: `%s` (type %s) is not a pipeline signal\" % (self.trace_info(), n, type(src)))\n", "/home/testing/.local/lib/python3.9/site-packages/myirl-0.0.0-py3.9-linux-x86_64.egg/myirl/library/pipeline.py:177: TranslationWarning: /tmp/ipykernel_172075/1859329269.py::video_rgb_yuv:47: `rgbv` (type ) is not a pipeline signal\n", " base.warn(\"%s: `%s` (type %s) is not a pipeline signal\" % (self.trace_info(), n, type(src)))\n", "/home/testing/.local/lib/python3.9/site-packages/myirl-0.0.0-py3.9-linux-x86_64.egg/myirl/library/pipeline.py:177: TranslationWarning: /tmp/ipykernel_172075/1859329269.py::video_rgb_yuv:47: `p_coef1` (type ) is not a pipeline signal\n", " base.warn(\"%s: `%s` (type %s) is not a pipeline signal\" % (self.trace_info(), n, type(src)))\n", "/home/testing/.local/lib/python3.9/site-packages/myirl-0.0.0-py3.9-linux-x86_64.egg/myirl/library/pipeline.py:177: TranslationWarning: /tmp/ipykernel_172075/1859329269.py::video_rgb_yuv:47: `p_coef2` (type ) is not a pipeline signal\n", " base.warn(\"%s: `%s` (type %s) is not a pipeline signal\" % (self.trace_info(), n, type(src)))\n", "/home/testing/.local/lib/python3.9/site-packages/myirl-0.0.0-py3.9-linux-x86_64.egg/myirl/library/pipeline.py:177: TranslationWarning: /tmp/ipykernel_172075/1859329269.py::video_rgb_yuv:47: `ydata` (type ) is not a pipeline signal\n", " base.warn(\"%s: `%s` (type %s) is not a pipeline signal\" % (self.trace_info(), n, type(src)))\n", "/home/testing/.local/lib/python3.9/site-packages/myirl-0.0.0-py3.9-linux-x86_64.egg/myirl/library/pipeline.py:177: TranslationWarning: /tmp/ipykernel_172075/1859329269.py::video_rgb_yuv:47: `udata` (type ) is not a pipeline signal\n", " base.warn(\"%s: `%s` (type %s) is not a pipeline signal\" % (self.trace_info(), n, type(src)))\n", "/home/testing/.local/lib/python3.9/site-packages/myirl-0.0.0-py3.9-linux-x86_64.egg/myirl/library/pipeline.py:177: TranslationWarning: /tmp/ipykernel_172075/1859329269.py::video_rgb_yuv:47: `vdata` (type ) is not a pipeline signal\n", " base.warn(\"%s: `%s` (type %s) is not a pipeline signal\" % (self.trace_info(), n, type(src)))\n", "/home/testing/.local/lib/python3.9/site-packages/myirl-0.0.0-py3.9-linux-x86_64.egg/myirl/kernel/instance.py:424: TranslationWarning: @component `video_rgb_yuv`: DEBUG UNUSED 'vin'\n", " base.warn(\"@component `%s`: DEBUG UNUSED '%s'\" % (self.obj.func.__name__, n), category = base.TranslationWarning)\n", "/home/testing/.local/lib/python3.9/site-packages/myirl-0.0.0-py3.9-linux-x86_64.egg/myirl/kernel/instance.py:424: TranslationWarning: @component `video_rgb_yuv`: DEBUG UNUSED 'valid'\n", " base.warn(\"@component `%s`: DEBUG UNUSED '%s'\" % (self.obj.func.__name__, n), category = base.TranslationWarning)\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ " Writing 'testbench_rgb2yuv' to file /tmp/testbench_rgb2yuv.vhdl \n", " Creating library file /tmp/module_defs.vhdl \n", "==== COSIM stdout ====\n", "0xuuuuuu\n", "0xB22B80\n", "0x7E0000\n", "0x4CD4C9\n", "0x56D4D4\n", "0x56D4D4\n", "0x56D4D4\n", "simulation stopped @175ns\n", "\n" ] } ], "source": [ "files, tb = test()" ] }, { "cell_type": "markdown", "id": "9aaec22a", "metadata": {}, "source": [ "## Waveform trace" ] }, { "cell_type": "code", "execution_count": 9, "id": "513b09a3", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/javascript": [ "new Promise(function(resolve, reject) {\n", "\tvar script = document.createElement(\"script\");\n", "\tscript.onload = resolve;\n", "\tscript.onerror = reject;\n", "\tscript.src = \"https://wavedrom.com/wavedrom.min.js\";\n", "\tdocument.head.appendChild(script);\n", "}).then(() => {\n", "new Promise(function(resolve, reject) {\n", "\tvar script = document.createElement(\"script\");\n", "\tscript.onload = resolve;\n", "\tscript.onerror = reject;\n", "\tscript.src = \"https://wavedrom.com/skins/narrow.js\";\n", "\tdocument.head.appendChild(script);\n", "}).then(() => {\n", "WaveDrom.ProcessAll();\n", "});\n", "});" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "import wavedraw; import nbwavedrom\n", "TB = tb.name;\n", "\n", "waveform = wavedraw.vcd2wave(\"yuv.vcd\", TB + '.pclk', None)\n", "nbwavedrom.draw(waveform)" ] }, { "cell_type": "markdown", "id": "9162c1ae", "metadata": {}, "source": [ "Download VCD trace [yuv.vcd](yuv.vcd)" ] }, { "cell_type": "code", "execution_count": 10, "id": "30cfbe8a", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " 1\t-- File generated from source:\n", " 2\t-- /tmp/ipykernel_172075/1859329269.py\n", " 3\t-- (c) 2016-2022 section5.ch\n", " 4\t-- Modifications may be lost, edit the source file instead.\n", " 5\t\n", " 6\tlibrary IEEE;\n", " 7\tuse IEEE.std_logic_1164.all;\n", " 8\tuse IEEE.numeric_std.all;\n", " 9\t\n", " 10\tlibrary work;\n", " 11\t\n", " 12\tuse work.module_defs.all;\n", " 13\tuse work.txt_util.all;\n", " 14\tuse work.myirl_conversion.all;\n", " 15\t\n", " 16\t\n", " 17\t\n", " 18\tentity video_rgb_yuv is\n", " 19\t port (\n", " 20\t clk : in std_ulogic;\n", " 21\t vin : in t_VideoPort;\n", " 22\t rgb : in unsigned(23 downto 0);\n", " 23\t vout : out t_VideoPort;\n", " 24\t yuv : out unsigned(23 downto 0)\n", " 25\t );\n", " 26\tend entity video_rgb_yuv;\n", " 27\t\n", " 28\tarchitecture myIRL of video_rgb_yuv is\n", " 29\t -- Local type declarations\n", " 30\t -- Signal declarations\n", " 31\t signal yuv_pipe_ce1 : std_ulogic;\n", " 32\t signal yuv_pipe_ce2 : std_ulogic;\n", " 33\t signal yuv_pipe_ce0 : std_ulogic;\n", " 34\t type a_ydata is array (0 to 2) of unsigned(23 downto 0);\n", " 35\t signal ydata : a_ydata ;\n", " 36\t type a_udata is array (0 to 2) of signed(24 downto 0);\n", " 37\t signal udata : a_udata ;\n", " 38\t type a_vdata is array (0 to 2) of signed(24 downto 0);\n", " 39\t signal vdata : a_vdata ;\n", " 40\t type a_add_res is array (0 to 2) of signed(25 downto 0);\n", " 41\t signal add_res : a_add_res;\n", " 42\t signal yuv_pipe_bypass1 : t_VideoPort;\n", " 43\t signal yuv_pipe_bypass2 : t_VideoPort;\n", " 44\t signal yuv_pipe_bypass0 : t_VideoPort;\n", " 45\t type a_p_coef0 is array (0 to 2) of unsigned(15 downto 0);\n", " 46\t signal p_coef0 : a_p_coef0 := (\n", " 47\t x\"2645\",x\"4b22\",x\"0e97\"\n", " 48\t );\n", " 49\t type a_rgbv is array (0 to 2) of unsigned(7 downto 0);\n", " 50\t signal rgbv : a_rgbv ;\n", " 51\t type a_p_coef1 is array (0 to 2) of unsigned(15 downto 0);\n", " 52\t signal p_coef1 : a_p_coef1 := (\n", " 53\t x\"ea67\",x\"d59a\",x\"4000\"\n", " 54\t );\n", " 55\t type a_p_coef2 is array (0 to 2) of unsigned(15 downto 0);\n", " 56\t signal p_coef2 : a_p_coef2 := (\n", " 57\t x\"4000\",x\"ca69\",x\"f598\"\n", " 58\t );\n", " 59\tbegin\n", " 60\t \n", " 61\tce_queue:\n", " 62\t process(clk)\n", " 63\t begin\n", " 64\t if rising_edge(clk) then\n", " 65\t yuv_pipe_ce1 <= yuv_pipe_ce0;\n", " 66\t yuv_pipe_ce2 <= yuv_pipe_ce1;\n", " 67\t end if;\n", " 68\t end process;\n", " 69\t yuv_pipe_ce0 <= vin.dval;\n", " 70\t \n", " 71\tyuv_pipe_stage0:\n", " 72\t process(clk)\n", " 73\t begin\n", " 74\t if rising_edge(clk) then\n", " 75\t if (yuv_pipe_ce0 = '1') then\n", " 76\t ydata(0) <= (p_coef0(0) * rgbv(0));\n", " 77\t ydata(1) <= (p_coef0(1) * rgbv(1));\n", " 78\t ydata(2) <= (p_coef0(2) * rgbv(2));\n", " 79\t udata(0) <= signed(resize((signed(p_coef1(0)) * signed(resize(rgbv(0), 9))), 25));\n", " 80\t udata(1) <= signed(resize((signed(p_coef1(1)) * signed(resize(rgbv(1), 9))), 25));\n", " 81\t udata(2) <= signed(resize((signed(p_coef1(2)) * signed(resize(rgbv(2), 9))), 25));\n", " 82\t vdata(0) <= signed(resize((signed(p_coef2(0)) * signed(resize(rgbv(0), 9))), 25));\n", " 83\t vdata(1) <= signed(resize((signed(p_coef2(1)) * signed(resize(rgbv(1), 9))), 25));\n", " 84\t vdata(2) <= signed(resize((signed(p_coef2(2)) * signed(resize(rgbv(2), 9))), 25));\n", " 85\t end if;\n", " 86\t end if;\n", " 87\t end process;\n", " 88\t \n", " 89\tyuv_pipe_stage1:\n", " 90\t process(clk)\n", " 91\t begin\n", " 92\t if rising_edge(clk) then\n", " 93\t if (yuv_pipe_ce1 = '1') then\n", " 94\t add_res(0) <= signed((resize((ydata(0) + resize(ydata(1), 25)), 26) + ydata(2)));\n", " 95\t add_res(1) <= signed(resize((signed(resize((udata(0) + signed(resize(udata(1), 26))), 27)) + udata(2)), 26));\n", " 96\t add_res(2) <= signed(resize((signed(resize((vdata(0) + signed(resize(vdata(1), 26))), 27)) + vdata(2)), 26));\n", " 97\t end if;\n", " 98\t end if;\n", " 99\t end process;\n", " 100\t \n", " 101\tdelay_queue:\n", " 102\t process(clk)\n", " 103\t begin\n", " 104\t if rising_edge(clk) then\n", " 105\t yuv_pipe_bypass1 <= yuv_pipe_bypass0;\n", " 106\t yuv_pipe_bypass2 <= yuv_pipe_bypass1;\n", " 107\t end if;\n", " 108\t end process;\n", " 109\t vout <= yuv_pipe_bypass2;\n", " 110\t yuv_pipe_bypass0 <= vin;\n", " 111\t rgbv(0) <= rgb(24-1 downto 16);\n", " 112\t rgbv(1) <= rgb(16-1 downto 8);\n", " 113\t rgbv(2) <= rgb(8-1 downto 0);\n", " 114\t yuv <= (unsigned(add_res(0)(23-1 downto 15)) & unsigned(add_res(1)(23-1 downto 15)) & unsigned(add_res(2)(23-1 downto 15)));\n", " 115\tend architecture myIRL;\n", " 116\t\n" ] } ], "source": [ "!cat -n {files[0]}" ] }, { "cell_type": "markdown", "id": "f921e8a5", "metadata": {}, "source": [ "## Verification exercise\n", "\n", "Using numpy, we can run our samples through the floating point matrix as well:" ] }, { "cell_type": "code", "execution_count": 11, "id": "5e7e74b9", "metadata": {}, "outputs": [], "source": [ "v = numpy.matrix(mat_jpeg_rgb2yuv)\n", "rgb = numpy.matrix([ (127, 127, 127), (0, 255, 255), (0, 0x83, 0)]).T\n", "\n", "yuv = v * rgb" ] }, { "cell_type": "code", "execution_count": 12, "id": "41a7c122", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "matrix([['7e', '00', '00'],\n", " ['b2', '2b', '81'],\n", " ['4c', 'd5', 'ca']], dtype='