From b20a95914ea13e7b9dbbc2aa5d256baaa9c3636a Mon Sep 17 00:00:00 2001 From: Christopher Felton Date: Wed, 21 Sep 2016 13:32:33 -0500 Subject: [PATCH 01/32] updating and reorg docs --- README.md | 36 +++++++++++++++++++++++++++------ docs/source/conf.py | 4 +++- docs/source/getting_started.rst | 0 docs/source/index.rst | 6 +++--- 4 files changed, 36 insertions(+), 10 deletions(-) create mode 100644 docs/source/getting_started.rst diff --git a/README.md b/README.md index 3ce0325..9ef9c53 100644 --- a/README.md +++ b/README.md @@ -8,18 +8,42 @@ Introduction ============ -This repository is a development sandbox. The respository +The `test_jpeg` repository is in the middle of a change, originally +this repository was an example how to use MyHDL to setup a cosimulation +environment and the jpegenc cores were used (cosim with Verilog) ... +it is evolving to something more. + +During the summer of 2016 two students participated in +[MyHDL's GSoC](http://dev.myhdl.org/gsoc/gsoc_2016.html). The +students worked on implementing the various JPEG Encoder subblocks +in MyHDL. The sublocks were broken into frontend and backend. +Their blogs, [the frontend](https://myhdlgsoc2016.blogspot.gr/) and +[the backend](https://vikram9866.wordpress.com/), outline their +work over the summer. The [latest documentation is available +on readthedocs](http://jpegenc.readthedocs.io/en/latest/) + +The primary goal of this repository is to have a working JPEG +Encoder implemented in MyHDL. But not simply implemented in +MyHDL but also utilizing methodologies such as a focus on +clean and reusable block-to-block interfaces and a full +regression test suite. + +This repository is a development sandbox. The repository contains three related development efforts: -1. VHDL to Verilog conversion of the first JPEG-encoder reference - (rational explained below). +1. A MyHDL implementation of a JPEG-Encoder. +2. Two Verilog reference implementations. 2. MyHDL verification and co-simulation environment, tests will - functionally verify and compare the reference JPEG-encoders. -3. A MyHDL implementation of a JPEG-encoder. + functionally verify and compare the reference JPEG-Encoders. The JPEG encoders used are the cores available at open-cores in addition to JPEG encoders being developed. This is a WIP and not -fully complete. +fully complete (yet). + + +Quick start guide +================= + Verification Environment diff --git a/docs/source/conf.py b/docs/source/conf.py index 930e09b..6c81642 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -35,6 +35,7 @@ 'sphinx.ext.todo', 'sphinx.ext.coverage', 'sphinx.ext.mathjax', + 'sphinx.ext.napoleon', ] # Add any paths that contain templates here, relative to this directory. @@ -114,7 +115,8 @@ # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. -html_theme = 'alabaster' +# html_theme = 'alabaster' +html_theme = 'default' # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the diff --git a/docs/source/getting_started.rst b/docs/source/getting_started.rst new file mode 100644 index 0000000..e69de29 diff --git a/docs/source/index.rst b/docs/source/index.rst index 9733464..9faa16d 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -6,10 +6,10 @@ Welcome to jpegenc's documentation! =================================== -Frontend Part Modules Documentation -+++++++++++++++++++++++++++++++++++ +Frontend Documentation +++++++++++++++++++++++ -Frontend Part Modules: +Frontend Subblocks: .. toctree:: :maxdepth: 1 From 4bca5e98b3aabcb2e2cf52f03ee57efec1dddccb Mon Sep 17 00:00:00 2001 From: Christopher Felton Date: Wed, 21 Sep 2016 13:33:35 -0500 Subject: [PATCH 02/32] updating and reorg docs --- docs/source/overview.rst | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 docs/source/overview.rst diff --git a/docs/source/overview.rst b/docs/source/overview.rst new file mode 100644 index 0000000..c94789d --- /dev/null +++ b/docs/source/overview.rst @@ -0,0 +1,18 @@ + +Overview +======== + +.. image:: https://docs.google.com/drawings/d/1c9tR1OmzBcTfnZdMq3hcuBwiMCCwYyGezcLF3YnsZQg/pub?w=996&h=382 + + The JPEG encoder system diagram + + +Measurements +------------ + +.. toctree:: + :maxdepth: 1 + + Coverage<./subblocks/coverage.rst> + Implementation Results<./subblocks/impl.rst> + From bc04db14e07baaaa51f6bfaf9a26fda24f060166 Mon Sep 17 00:00:00 2001 From: Christopher Felton Date: Wed, 21 Sep 2016 13:38:28 -0500 Subject: [PATCH 03/32] updating and reorg docs --- docs/source/index.rst | 49 ++++++------------------------------------- 1 file changed, 6 insertions(+), 43 deletions(-) diff --git a/docs/source/index.rst b/docs/source/index.rst index 9faa16d..b1cc7ff 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -3,54 +3,17 @@ You can adapt this file completely to your liking, but it should at least contain the root `toctree` directive. -Welcome to jpegenc's documentation! -=================================== -Frontend Documentation -++++++++++++++++++++++ - -Frontend Subblocks: - -.. toctree:: - :maxdepth: 1 - - Color Space Conversion<./subblocks/color_converts.rst> - Color Space Conversion v2<./subblocks/color_converts_v2.rst> - 1D-DCT<./subblocks/dct_1d.rst> - 2D-DCT<./subblocks/dct_2d.rst> - Zig Zaz Scan Module<./subblocks/zig_zag.rst> - Frontend Part<./subblocks/frontend.rst> - -Test Units: - -.. toctree:: - :maxdepth: 1 - - Color Space Conversion Test <./subblocks/test_color_converts.rst> - Color Space Conversion v2 Test <./subblocks/test_color_converts_v2.rst> - 1D-DCT Test<./subblocks/test_dct_1d.rst> - 2D-DCT Test<./subblocks/test_dct_2d.rst> - Zig Zag Scan Test<./subblocks/test_zig_zag.rst> - Frontend Part Test<./subblocks/test_frontend.rst> - -Interfaces: +JPEG encoder (test_jpeg) documentation +======================================= .. toctree:: - :maxdepth: 1 + :maxdepth: 1 - Color Space Conversion Interfaces<./subblocks/test_color_converts_ints.rst> - 1D-DCT Interfaces<./subblocks/dct_1d_ints.rst> - 2D-DCT Interfaces<./subblocks/dct_2d_ints.rst> - Zig Zag Scan Interfaces<./subblocks/zig_zag_scan_ints.rst> - Frontend Part Interfaces<./subblocks/frontend_ints.rst> - -Measurements: - -.. toctree:: - :maxdepth: 1 + overview + getting_started + reference - Coverage<./subblocks/coverage.rst> - Implementation Results<./subblocks/impl.rst> Indices and tables ================== From 6fa4c5083a445d3c4621defc308876f47fc0aed6 Mon Sep 17 00:00:00 2001 From: Christopher Felton Date: Wed, 21 Sep 2016 13:47:31 -0500 Subject: [PATCH 04/32] updating and reorg docs --- docs/source/getting_started.rst | 13 ++++++++ docs/source/reference.rst | 57 +++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+) create mode 100644 docs/source/reference.rst diff --git a/docs/source/getting_started.rst b/docs/source/getting_started.rst index e69de29..d747309 100644 --- a/docs/source/getting_started.rst +++ b/docs/source/getting_started.rst @@ -0,0 +1,13 @@ + +Quick start +=========== + +The easiest path to install the package is to use `pip`:: + + >> pip install git://github.com/cfelton/test_jpeg.git#egg=test_jpeg + + +Once the package is installed the test suite can be run:: + + >> py.test + diff --git a/docs/source/reference.rst b/docs/source/reference.rst new file mode 100644 index 0000000..258539b --- /dev/null +++ b/docs/source/reference.rst @@ -0,0 +1,57 @@ + +JPEG encoder reference +====================== + +Interfaces +---------- +.. todo:: + + This sections needs to be completed, the interfaces are in a state + of change. + + +Frontend +--------- + +Interfaces +++++++++++ + +Interfaces: + +.. toctree:: + :maxdepth: 1 + + Color Space Conversion Interfaces<./subblocks/test_color_converts_ints.rst> + 1D-DCT Interfaces<./subblocks/dct_1d_ints.rst> + 2D-DCT Interfaces<./subblocks/dct_2d_ints.rst> + Zig Zag Scan Interfaces<./subblocks/zig_zag_scan_ints.rst> + Frontend Part Interfaces<./subblocks/frontend_ints.rst> + + +Subblocks ++++++++++ + +.. toctree:: + :maxdepth: 1 + + Color Space Conversion<./subblocks/color_converts.rst> + Color Space Conversion v2<./subblocks/color_converts_v2.rst> + 1D-DCT<./subblocks/dct_1d.rst> + 2D-DCT<./subblocks/dct_2d.rst> + Zig Zaz Scan Module<./subblocks/zig_zag.rst> + Frontend Part<./subblocks/frontend.rst> + + +Test units +++++++++++ + +.. toctree:: + :maxdepth: 1 + + Color Space Conversion Test <./subblocks/test_color_converts.rst> + Color Space Conversion v2 Test <./subblocks/test_color_converts_v2.rst> + 1D-DCT Test<./subblocks/test_dct_1d.rst> + 2D-DCT Test<./subblocks/test_dct_2d.rst> + Zig Zag Scan Test<./subblocks/test_zig_zag.rst> + Frontend Part Test<./subblocks/test_frontend.rst> + From 8557feb48c66e57494c21941cececb1a8f64bffe Mon Sep 17 00:00:00 2001 From: Christopher Felton Date: Wed, 21 Sep 2016 13:50:52 -0500 Subject: [PATCH 05/32] renamed test to tests (pytest recommended) --- docs/source/getting_started.rst | 1 + {test => tests}/Makefile | 0 {test => tests}/__init__.py | 0 {test => tests}/conftest.py | 0 {test => tests}/header.hex | 0 {test => tests}/huff_test_inputs.py | 0 {test => tests}/quant_test_inputs.py | 0 .../jpegenc_v1/verilog/AC_CR_ROM.v | 0 .../reference_designs/jpegenc_v1/verilog/AC_ROM.v | 0 .../reference_designs/jpegenc_v1/verilog/BUF_FIFO.v | 0 .../jpegenc_v1/verilog/ByteStuffer.v | 0 .../reference_designs/jpegenc_v1/verilog/CtrlSM.v | 0 .../reference_designs/jpegenc_v1/verilog/DBUFCTL.v | 0 .../reference_designs/jpegenc_v1/verilog/DCT1D.v | 0 .../reference_designs/jpegenc_v1/verilog/DCT2D.v | 0 .../jpegenc_v1/verilog/DC_CR_ROM.v | 0 .../reference_designs/jpegenc_v1/verilog/DC_ROM.v | 0 .../jpegenc_v1/verilog/DoubleFifo.v | 0 .../reference_designs/jpegenc_v1/verilog/FDCT.v | 0 .../reference_designs/jpegenc_v1/verilog/FIFO.v | 0 .../jpegenc_v1/verilog/HeaderRAM.v | 0 .../reference_designs/jpegenc_v1/verilog/HostIF.v | 0 .../reference_designs/jpegenc_v1/verilog/Huffman.v | 0 .../reference_designs/jpegenc_v1/verilog/JFIFGen.v | 0 .../reference_designs/jpegenc_v1/verilog/JpegEnc.v | 0 .../reference_designs/jpegenc_v1/verilog/MDCT.v | 0 .../reference_designs/jpegenc_v1/verilog/OutMux.v | 0 .../jpegenc_v1/verilog/QUANTIZER.v | 0 .../jpegenc_v1/verilog/QUANT_TOP.v | 0 .../reference_designs/jpegenc_v1/verilog/RAM.v | 0 .../reference_designs/jpegenc_v1/verilog/RAMF.v | 0 .../reference_designs/jpegenc_v1/verilog/RAMZ.v | 0 .../reference_designs/jpegenc_v1/verilog/RLE.v | 0 .../reference_designs/jpegenc_v1/verilog/RLE_TOP.v | 0 .../reference_designs/jpegenc_v1/verilog/ROME.v | 0 .../reference_designs/jpegenc_v1/verilog/ROMO.v | 0 .../reference_designs/jpegenc_v1/verilog/ROMR.v | 0 .../jpegenc_v1/verilog/RleDoubleFifo.v | 0 .../reference_designs/jpegenc_v1/verilog/SUB_RAMZ.v | 0 .../reference_designs/jpegenc_v1/verilog/SingleSM.v | 0 .../reference_designs/jpegenc_v1/verilog/ZIGZAG.v | 0 .../reference_designs/jpegenc_v1/verilog/ZZ_TOP.v | 0 .../jpegenc_v1/verilog/fdct_read_proc_sm_mon.py | 0 .../reference_designs/jpegenc_v1/verilog/header.hex | 0 .../verilog/m_fdct_read_proc_sm_monitor.v | 0 .../reference_designs/jpegenc_v1/verilog/m_zz_rom.v | 0 .../jpegenc_v1/verilog/mdct_coefs.py | 0 .../jpegenc_v1/verilog/output_files/RAM.v | 0 .../jpegenc_v1/verilog/output_files/RAM_6x12.v | 0 .../jpegenc_v1/verilog/output_files/ROME.v | 0 .../jpegenc_v1/verilog/output_files/ROMO.v | 0 .../jpegenc_v1/verilog/output_files/ROMR.v | 0 .../jpegenc_v1/verilog/r_divider.v | 0 .../reference_designs/jpegenc_v1/verilog/ramz.py | 0 .../reference_designs/jpegenc_v1/verilog/rome.py | 0 .../reference_designs/jpegenc_v1/verilog/romo.py | 0 .../reference_designs/jpegenc_v1/verilog/romr.py | 0 .../jpegenc_v1/verilog/wip_todo.txt | 0 .../reference_designs/jpegenc_v1/vhdl/AC_CR_ROM.vhd | 0 .../reference_designs/jpegenc_v1/vhdl/AC_ROM.vhd | 0 .../reference_designs/jpegenc_v1/vhdl/BUF_FIFO.vhd | 0 .../jpegenc_v1/vhdl/ByteStuffer.vhd | 0 .../reference_designs/jpegenc_v1/vhdl/CtrlSM.vhd | 0 .../reference_designs/jpegenc_v1/vhdl/DBUFCTL.vhd | 0 .../reference_designs/jpegenc_v1/vhdl/DCT1D.vhd | 0 .../reference_designs/jpegenc_v1/vhdl/DCT2D.vhd | 0 .../reference_designs/jpegenc_v1/vhdl/DC_CR_ROM.vhd | 0 .../reference_designs/jpegenc_v1/vhdl/DC_ROM.vhd | 0 .../jpegenc_v1/vhdl/DoubleFifo.vhd | 0 .../reference_designs/jpegenc_v1/vhdl/FDCT.vhd | 0 .../reference_designs/jpegenc_v1/vhdl/FIFO.vhd | 0 .../reference_designs/jpegenc_v1/vhdl/HeaderRAM.v | 0 .../reference_designs/jpegenc_v1/vhdl/HeaderRam.vhd | 0 .../reference_designs/jpegenc_v1/vhdl/HostIF.vhd | 0 .../reference_designs/jpegenc_v1/vhdl/Huffman.vhd | 0 .../reference_designs/jpegenc_v1/vhdl/JFIFGen.vhd | 0 .../reference_designs/jpegenc_v1/vhdl/JPEG_PKG.vhd | 0 .../reference_designs/jpegenc_v1/vhdl/JpegEnc.vhd | 0 .../reference_designs/jpegenc_v1/vhdl/MDCT.vhd | 0 .../reference_designs/jpegenc_v1/vhdl/MDCT_PKG.vhd | 0 .../reference_designs/jpegenc_v1/vhdl/OutMux.vhd | 0 .../reference_designs/jpegenc_v1/vhdl/QUANTIZER.vhd | 0 .../reference_designs/jpegenc_v1/vhdl/QUANT_TOP.vhd | 0 .../reference_designs/jpegenc_v1/vhdl/RAM.vhd | 0 .../reference_designs/jpegenc_v1/vhdl/RAMZ.vhd | 0 .../reference_designs/jpegenc_v1/vhdl/RLE.vhd | 0 .../reference_designs/jpegenc_v1/vhdl/RLE_TOP.vhd | 0 .../reference_designs/jpegenc_v1/vhdl/ROME.vhd | 0 .../reference_designs/jpegenc_v1/vhdl/ROMO.vhd | 0 .../reference_designs/jpegenc_v1/vhdl/ROMR.vhd | 0 .../jpegenc_v1/vhdl/RleDoubleFifo.vhd | 0 .../reference_designs/jpegenc_v1/vhdl/SUB_RAMZ.vhd | 0 .../reference_designs/jpegenc_v1/vhdl/SingleSM.vhd | 0 .../reference_designs/jpegenc_v1/vhdl/ZIGZAG.vhd | 0 .../reference_designs/jpegenc_v1/vhdl/ZZ_TOP.vhd | 0 .../reference_designs/jpegenc_v1/vhdl/header.hex | 0 .../reference_designs/jpegenc_v1/vhdl/header_ram.py | 0 .../jpegenc_v1/vhdl/pck_myhdl_09.vhd | 0 .../reference_designs/jpegenc_v1/vhdl/r_divider.vhd | 0 .../reference_designs/jpegenc_v1/vhdl/tb/Makefile | 0 .../jpegenc_v1/vhdl/tb/vhdl/ClkGen.vhd | 0 .../jpegenc_v1/vhdl/tb/vhdl/DCT_TROM.vhd | 0 .../jpegenc_v1/vhdl/tb/vhdl/GPL_V2_Image_pkg.vhd | 0 .../jpegenc_v1/vhdl/tb/vhdl/HostBFM.vhd | 0 .../jpegenc_v1/vhdl/tb/vhdl/JPEG_TB.vhd | 0 .../jpegenc_v1/vhdl/tb/vhdl/MDCTTB_PKG.vhd | 0 .../jpegenc_v1/vhdl/tb/vhdl/RAMSIM.vhd | 0 .../jpegenc_v1/vhdl/tb/work/Makefile | 0 .../reference_designs/jpegenc_v2/myhdl/__init__.py | 0 .../reference_designs/jpegenc_v2/myhdl/commons.py | 0 .../jpegenc_v2/myhdl/dct1pinpout.py | 0 .../jpegenc_v2/myhdl/dct1sinpout.py | 0 .../jpegenc_v2/myhdl/dct2sinpout.py | 0 .../jpegenc_v2/myhdl/dctconstructs.py | 0 .../reference_designs/jpegenc_v2/myhdl/quantizer.py | 0 .../reference_designs/jpegenc_v2/myhdl/rgb2ycbcr.py | 0 .../jpegenc_v2/myhdl/test/test_dct1pinpout.py | 0 .../jpegenc_v2/myhdl/test/test_dct1sinpout.py | 0 .../jpegenc_v2/myhdl/test/test_dct2sinpout.py | 0 .../jpegenc_v2/myhdl/test/test_quantizer.py | 0 .../jpegenc_v2/myhdl/test/test_rgb2ycbcr.py | 0 .../reference_designs/jpegenc_v2/verilog/cb_dct.v | 0 .../reference_designs/jpegenc_v2/verilog/cb_huff.v | 0 .../jpegenc_v2/verilog/cb_quantizer.v | 0 .../reference_designs/jpegenc_v2/verilog/cbd_q_h.v | 0 .../reference_designs/jpegenc_v2/verilog/cr_dct.v | 0 .../reference_designs/jpegenc_v2/verilog/cr_huff.v | 0 .../jpegenc_v2/verilog/cr_quantizer.v | 0 .../reference_designs/jpegenc_v2/verilog/crd_q_h.v | 0 .../jpegenc_v2/verilog/ff_checker.v | 0 .../reference_designs/jpegenc_v2/verilog/fifo_out.v | 0 .../jpegenc_v2/verilog/ja_bits_out.v | 0 .../reference_designs/jpegenc_v2/verilog/jpeg_top.v | 0 .../jpegenc_v2/verilog/jpeg_top_TB.v | 0 .../reference_designs/jpegenc_v2/verilog/pre_fifo.v | 0 .../jpegenc_v2/verilog/rgb2ycbcr.v | 0 .../jpegenc_v2/verilog/sync_fifo_32.v | 0 .../jpegenc_v2/verilog/sync_fifo_ff.v | 0 .../reference_designs/jpegenc_v2/verilog/y_dct.v | 0 .../reference_designs/jpegenc_v2/verilog/y_huff.v | 0 .../jpegenc_v2/verilog/y_quantizer.v | 0 .../reference_designs/jpegenc_v2/verilog/yd_q_h.v | 0 {test => tests}/rle_test_inputs.py | 0 {test => tests}/setup.cfg | 0 {test => tests}/support/__init__.py | 0 {test => tests}/support/jpeg_compare_bitstreams.py | 0 {test => tests}/support/jpeg_filelist.py | 0 {test => tests}/support/jpeg_intf.py | 0 {test => tests}/support/jpeg_prep_cosim.py | 0 {test => tests}/support/jpeg_roms.py | 0 {test => tests}/support/jpeg_v1_intf.py | 0 {test => tests}/support/jpeg_v2_intf.py | 0 {test => tests}/support/jpegenc_v1_top.py | 0 {test => tests}/support/opb.py | 0 {test => tests}/support/signal_queue.py | 0 {test => tests}/support/utils.py | 0 {test => tests}/tb_jpegenc.v | 0 {test => tests}/tb_mdct.v | 0 {test => tests}/test_backend.py | 0 {test => tests}/test_block_buffer.py | 0 {test => tests}/test_bytestuffer.py | 0 {test => tests}/test_dct_1d.py | 0 {test => tests}/test_dct_2d.py | 0 {test => tests}/test_divider.py | 0 {test => tests}/test_entropycoder.py | 0 {test => tests}/test_frontend_v2.py | 0 {test => tests}/test_huffdoublebuffer.py | 0 {test => tests}/test_huffman.py | 0 {test => tests}/test_images/color/small1.png | Bin {test => tests}/test_images/color/small2.png | Bin {test => tests}/test_images/color/small3.png | Bin {test => tests}/test_images/color/small4.png | Bin {test => tests}/test_quantizer.py | 0 {test => tests}/test_quantizer_core.py | 0 {test => tests}/test_ref_designs.py | 0 {test => tests}/test_ref_mdct.py | 0 {test => tests}/test_rgb2ycbcr.py | 0 {test => tests}/test_rgb2ycbcr_v2.py | 0 {test => tests}/test_rle.py | 0 {test => tests}/test_rlecore.py | 0 {test => tests}/test_rledoublebuffer.py | 0 {test => tests}/test_zig_zag.py | 0 182 files changed, 1 insertion(+) rename {test => tests}/Makefile (100%) rename {test => tests}/__init__.py (100%) rename {test => tests}/conftest.py (100%) rename {test => tests}/header.hex (100%) rename {test => tests}/huff_test_inputs.py (100%) rename {test => tests}/quant_test_inputs.py (100%) rename {test => tests}/reference_designs/jpegenc_v1/verilog/AC_CR_ROM.v (100%) rename {test => tests}/reference_designs/jpegenc_v1/verilog/AC_ROM.v (100%) rename {test => tests}/reference_designs/jpegenc_v1/verilog/BUF_FIFO.v (100%) rename {test => tests}/reference_designs/jpegenc_v1/verilog/ByteStuffer.v (100%) rename {test => tests}/reference_designs/jpegenc_v1/verilog/CtrlSM.v (100%) rename {test => tests}/reference_designs/jpegenc_v1/verilog/DBUFCTL.v (100%) rename {test => tests}/reference_designs/jpegenc_v1/verilog/DCT1D.v (100%) rename {test => tests}/reference_designs/jpegenc_v1/verilog/DCT2D.v (100%) rename {test => tests}/reference_designs/jpegenc_v1/verilog/DC_CR_ROM.v (100%) rename {test => tests}/reference_designs/jpegenc_v1/verilog/DC_ROM.v (100%) rename {test => tests}/reference_designs/jpegenc_v1/verilog/DoubleFifo.v (100%) rename {test => tests}/reference_designs/jpegenc_v1/verilog/FDCT.v (100%) rename {test => tests}/reference_designs/jpegenc_v1/verilog/FIFO.v (100%) rename {test => tests}/reference_designs/jpegenc_v1/verilog/HeaderRAM.v (100%) rename {test => tests}/reference_designs/jpegenc_v1/verilog/HostIF.v (100%) rename {test => tests}/reference_designs/jpegenc_v1/verilog/Huffman.v (100%) rename {test => tests}/reference_designs/jpegenc_v1/verilog/JFIFGen.v (100%) rename {test => tests}/reference_designs/jpegenc_v1/verilog/JpegEnc.v (100%) rename {test => tests}/reference_designs/jpegenc_v1/verilog/MDCT.v (100%) rename {test => tests}/reference_designs/jpegenc_v1/verilog/OutMux.v (100%) rename {test => tests}/reference_designs/jpegenc_v1/verilog/QUANTIZER.v (100%) rename {test => tests}/reference_designs/jpegenc_v1/verilog/QUANT_TOP.v (100%) rename {test => tests}/reference_designs/jpegenc_v1/verilog/RAM.v (100%) rename {test => tests}/reference_designs/jpegenc_v1/verilog/RAMF.v (100%) rename {test => tests}/reference_designs/jpegenc_v1/verilog/RAMZ.v (100%) rename {test => tests}/reference_designs/jpegenc_v1/verilog/RLE.v (100%) rename {test => tests}/reference_designs/jpegenc_v1/verilog/RLE_TOP.v (100%) rename {test => tests}/reference_designs/jpegenc_v1/verilog/ROME.v (100%) rename {test => tests}/reference_designs/jpegenc_v1/verilog/ROMO.v (100%) rename {test => tests}/reference_designs/jpegenc_v1/verilog/ROMR.v (100%) rename {test => tests}/reference_designs/jpegenc_v1/verilog/RleDoubleFifo.v (100%) rename {test => tests}/reference_designs/jpegenc_v1/verilog/SUB_RAMZ.v (100%) rename {test => tests}/reference_designs/jpegenc_v1/verilog/SingleSM.v (100%) rename {test => tests}/reference_designs/jpegenc_v1/verilog/ZIGZAG.v (100%) rename {test => tests}/reference_designs/jpegenc_v1/verilog/ZZ_TOP.v (100%) rename {test => tests}/reference_designs/jpegenc_v1/verilog/fdct_read_proc_sm_mon.py (100%) rename {test => tests}/reference_designs/jpegenc_v1/verilog/header.hex (100%) rename {test => tests}/reference_designs/jpegenc_v1/verilog/m_fdct_read_proc_sm_monitor.v (100%) rename {test => tests}/reference_designs/jpegenc_v1/verilog/m_zz_rom.v (100%) rename {test => tests}/reference_designs/jpegenc_v1/verilog/mdct_coefs.py (100%) rename {test => tests}/reference_designs/jpegenc_v1/verilog/output_files/RAM.v (100%) rename {test => tests}/reference_designs/jpegenc_v1/verilog/output_files/RAM_6x12.v (100%) rename {test => tests}/reference_designs/jpegenc_v1/verilog/output_files/ROME.v (100%) rename {test => tests}/reference_designs/jpegenc_v1/verilog/output_files/ROMO.v (100%) rename {test => tests}/reference_designs/jpegenc_v1/verilog/output_files/ROMR.v (100%) rename {test => tests}/reference_designs/jpegenc_v1/verilog/r_divider.v (100%) rename {test => tests}/reference_designs/jpegenc_v1/verilog/ramz.py (100%) rename {test => tests}/reference_designs/jpegenc_v1/verilog/rome.py (100%) rename {test => tests}/reference_designs/jpegenc_v1/verilog/romo.py (100%) rename {test => tests}/reference_designs/jpegenc_v1/verilog/romr.py (100%) rename {test => tests}/reference_designs/jpegenc_v1/verilog/wip_todo.txt (100%) rename {test => tests}/reference_designs/jpegenc_v1/vhdl/AC_CR_ROM.vhd (100%) rename {test => tests}/reference_designs/jpegenc_v1/vhdl/AC_ROM.vhd (100%) rename {test => tests}/reference_designs/jpegenc_v1/vhdl/BUF_FIFO.vhd (100%) rename {test => tests}/reference_designs/jpegenc_v1/vhdl/ByteStuffer.vhd (100%) rename {test => tests}/reference_designs/jpegenc_v1/vhdl/CtrlSM.vhd (100%) rename {test => tests}/reference_designs/jpegenc_v1/vhdl/DBUFCTL.vhd (100%) rename {test => tests}/reference_designs/jpegenc_v1/vhdl/DCT1D.vhd (100%) rename {test => tests}/reference_designs/jpegenc_v1/vhdl/DCT2D.vhd (100%) rename {test => tests}/reference_designs/jpegenc_v1/vhdl/DC_CR_ROM.vhd (100%) rename {test => tests}/reference_designs/jpegenc_v1/vhdl/DC_ROM.vhd (100%) rename {test => tests}/reference_designs/jpegenc_v1/vhdl/DoubleFifo.vhd (100%) rename {test => tests}/reference_designs/jpegenc_v1/vhdl/FDCT.vhd (100%) rename {test => tests}/reference_designs/jpegenc_v1/vhdl/FIFO.vhd (100%) rename {test => tests}/reference_designs/jpegenc_v1/vhdl/HeaderRAM.v (100%) rename {test => tests}/reference_designs/jpegenc_v1/vhdl/HeaderRam.vhd (100%) rename {test => tests}/reference_designs/jpegenc_v1/vhdl/HostIF.vhd (100%) rename {test => tests}/reference_designs/jpegenc_v1/vhdl/Huffman.vhd (100%) rename {test => tests}/reference_designs/jpegenc_v1/vhdl/JFIFGen.vhd (100%) rename {test => tests}/reference_designs/jpegenc_v1/vhdl/JPEG_PKG.vhd (100%) rename {test => tests}/reference_designs/jpegenc_v1/vhdl/JpegEnc.vhd (100%) rename {test => tests}/reference_designs/jpegenc_v1/vhdl/MDCT.vhd (100%) rename {test => tests}/reference_designs/jpegenc_v1/vhdl/MDCT_PKG.vhd (100%) rename {test => tests}/reference_designs/jpegenc_v1/vhdl/OutMux.vhd (100%) rename {test => tests}/reference_designs/jpegenc_v1/vhdl/QUANTIZER.vhd (100%) rename {test => tests}/reference_designs/jpegenc_v1/vhdl/QUANT_TOP.vhd (100%) rename {test => tests}/reference_designs/jpegenc_v1/vhdl/RAM.vhd (100%) rename {test => tests}/reference_designs/jpegenc_v1/vhdl/RAMZ.vhd (100%) rename {test => tests}/reference_designs/jpegenc_v1/vhdl/RLE.vhd (100%) rename {test => tests}/reference_designs/jpegenc_v1/vhdl/RLE_TOP.vhd (100%) rename {test => tests}/reference_designs/jpegenc_v1/vhdl/ROME.vhd (100%) rename {test => tests}/reference_designs/jpegenc_v1/vhdl/ROMO.vhd (100%) rename {test => tests}/reference_designs/jpegenc_v1/vhdl/ROMR.vhd (100%) rename {test => tests}/reference_designs/jpegenc_v1/vhdl/RleDoubleFifo.vhd (100%) rename {test => tests}/reference_designs/jpegenc_v1/vhdl/SUB_RAMZ.vhd (100%) rename {test => tests}/reference_designs/jpegenc_v1/vhdl/SingleSM.vhd (100%) rename {test => tests}/reference_designs/jpegenc_v1/vhdl/ZIGZAG.vhd (100%) rename {test => tests}/reference_designs/jpegenc_v1/vhdl/ZZ_TOP.vhd (100%) rename {test => tests}/reference_designs/jpegenc_v1/vhdl/header.hex (100%) rename {test => tests}/reference_designs/jpegenc_v1/vhdl/header_ram.py (100%) rename {test => tests}/reference_designs/jpegenc_v1/vhdl/pck_myhdl_09.vhd (100%) rename {test => tests}/reference_designs/jpegenc_v1/vhdl/r_divider.vhd (100%) rename {test => tests}/reference_designs/jpegenc_v1/vhdl/tb/Makefile (100%) rename {test => tests}/reference_designs/jpegenc_v1/vhdl/tb/vhdl/ClkGen.vhd (100%) rename {test => tests}/reference_designs/jpegenc_v1/vhdl/tb/vhdl/DCT_TROM.vhd (100%) rename {test => tests}/reference_designs/jpegenc_v1/vhdl/tb/vhdl/GPL_V2_Image_pkg.vhd (100%) rename {test => tests}/reference_designs/jpegenc_v1/vhdl/tb/vhdl/HostBFM.vhd (100%) rename {test => tests}/reference_designs/jpegenc_v1/vhdl/tb/vhdl/JPEG_TB.vhd (100%) rename {test => tests}/reference_designs/jpegenc_v1/vhdl/tb/vhdl/MDCTTB_PKG.vhd (100%) rename {test => tests}/reference_designs/jpegenc_v1/vhdl/tb/vhdl/RAMSIM.vhd (100%) rename {test => tests}/reference_designs/jpegenc_v1/vhdl/tb/work/Makefile (100%) rename {test => tests}/reference_designs/jpegenc_v2/myhdl/__init__.py (100%) rename {test => tests}/reference_designs/jpegenc_v2/myhdl/commons.py (100%) rename {test => tests}/reference_designs/jpegenc_v2/myhdl/dct1pinpout.py (100%) rename {test => tests}/reference_designs/jpegenc_v2/myhdl/dct1sinpout.py (100%) rename {test => tests}/reference_designs/jpegenc_v2/myhdl/dct2sinpout.py (100%) rename {test => tests}/reference_designs/jpegenc_v2/myhdl/dctconstructs.py (100%) rename {test => tests}/reference_designs/jpegenc_v2/myhdl/quantizer.py (100%) rename {test => tests}/reference_designs/jpegenc_v2/myhdl/rgb2ycbcr.py (100%) rename {test => tests}/reference_designs/jpegenc_v2/myhdl/test/test_dct1pinpout.py (100%) rename {test => tests}/reference_designs/jpegenc_v2/myhdl/test/test_dct1sinpout.py (100%) rename {test => tests}/reference_designs/jpegenc_v2/myhdl/test/test_dct2sinpout.py (100%) rename {test => tests}/reference_designs/jpegenc_v2/myhdl/test/test_quantizer.py (100%) rename {test => tests}/reference_designs/jpegenc_v2/myhdl/test/test_rgb2ycbcr.py (100%) rename {test => tests}/reference_designs/jpegenc_v2/verilog/cb_dct.v (100%) rename {test => tests}/reference_designs/jpegenc_v2/verilog/cb_huff.v (100%) rename {test => tests}/reference_designs/jpegenc_v2/verilog/cb_quantizer.v (100%) rename {test => tests}/reference_designs/jpegenc_v2/verilog/cbd_q_h.v (100%) rename {test => tests}/reference_designs/jpegenc_v2/verilog/cr_dct.v (100%) rename {test => tests}/reference_designs/jpegenc_v2/verilog/cr_huff.v (100%) rename {test => tests}/reference_designs/jpegenc_v2/verilog/cr_quantizer.v (100%) rename {test => tests}/reference_designs/jpegenc_v2/verilog/crd_q_h.v (100%) rename {test => tests}/reference_designs/jpegenc_v2/verilog/ff_checker.v (100%) rename {test => tests}/reference_designs/jpegenc_v2/verilog/fifo_out.v (100%) rename {test => tests}/reference_designs/jpegenc_v2/verilog/ja_bits_out.v (100%) rename {test => tests}/reference_designs/jpegenc_v2/verilog/jpeg_top.v (100%) rename {test => tests}/reference_designs/jpegenc_v2/verilog/jpeg_top_TB.v (100%) rename {test => tests}/reference_designs/jpegenc_v2/verilog/pre_fifo.v (100%) rename {test => tests}/reference_designs/jpegenc_v2/verilog/rgb2ycbcr.v (100%) rename {test => tests}/reference_designs/jpegenc_v2/verilog/sync_fifo_32.v (100%) rename {test => tests}/reference_designs/jpegenc_v2/verilog/sync_fifo_ff.v (100%) rename {test => tests}/reference_designs/jpegenc_v2/verilog/y_dct.v (100%) rename {test => tests}/reference_designs/jpegenc_v2/verilog/y_huff.v (100%) rename {test => tests}/reference_designs/jpegenc_v2/verilog/y_quantizer.v (100%) rename {test => tests}/reference_designs/jpegenc_v2/verilog/yd_q_h.v (100%) rename {test => tests}/rle_test_inputs.py (100%) rename {test => tests}/setup.cfg (100%) rename {test => tests}/support/__init__.py (100%) rename {test => tests}/support/jpeg_compare_bitstreams.py (100%) rename {test => tests}/support/jpeg_filelist.py (100%) rename {test => tests}/support/jpeg_intf.py (100%) rename {test => tests}/support/jpeg_prep_cosim.py (100%) rename {test => tests}/support/jpeg_roms.py (100%) rename {test => tests}/support/jpeg_v1_intf.py (100%) rename {test => tests}/support/jpeg_v2_intf.py (100%) rename {test => tests}/support/jpegenc_v1_top.py (100%) rename {test => tests}/support/opb.py (100%) rename {test => tests}/support/signal_queue.py (100%) rename {test => tests}/support/utils.py (100%) rename {test => tests}/tb_jpegenc.v (100%) rename {test => tests}/tb_mdct.v (100%) rename {test => tests}/test_backend.py (100%) rename {test => tests}/test_block_buffer.py (100%) rename {test => tests}/test_bytestuffer.py (100%) rename {test => tests}/test_dct_1d.py (100%) rename {test => tests}/test_dct_2d.py (100%) rename {test => tests}/test_divider.py (100%) rename {test => tests}/test_entropycoder.py (100%) rename {test => tests}/test_frontend_v2.py (100%) rename {test => tests}/test_huffdoublebuffer.py (100%) rename {test => tests}/test_huffman.py (100%) rename {test => tests}/test_images/color/small1.png (100%) rename {test => tests}/test_images/color/small2.png (100%) rename {test => tests}/test_images/color/small3.png (100%) rename {test => tests}/test_images/color/small4.png (100%) rename {test => tests}/test_quantizer.py (100%) rename {test => tests}/test_quantizer_core.py (100%) rename {test => tests}/test_ref_designs.py (100%) rename {test => tests}/test_ref_mdct.py (100%) rename {test => tests}/test_rgb2ycbcr.py (100%) rename {test => tests}/test_rgb2ycbcr_v2.py (100%) rename {test => tests}/test_rle.py (100%) rename {test => tests}/test_rlecore.py (100%) rename {test => tests}/test_rledoublebuffer.py (100%) rename {test => tests}/test_zig_zag.py (100%) diff --git a/docs/source/getting_started.rst b/docs/source/getting_started.rst index d747309..7d5148a 100644 --- a/docs/source/getting_started.rst +++ b/docs/source/getting_started.rst @@ -9,5 +9,6 @@ The easiest path to install the package is to use `pip`:: Once the package is installed the test suite can be run:: + >> cd tests >> py.test diff --git a/test/Makefile b/tests/Makefile similarity index 100% rename from test/Makefile rename to tests/Makefile diff --git a/test/__init__.py b/tests/__init__.py similarity index 100% rename from test/__init__.py rename to tests/__init__.py diff --git a/test/conftest.py b/tests/conftest.py similarity index 100% rename from test/conftest.py rename to tests/conftest.py diff --git a/test/header.hex b/tests/header.hex similarity index 100% rename from test/header.hex rename to tests/header.hex diff --git a/test/huff_test_inputs.py b/tests/huff_test_inputs.py similarity index 100% rename from test/huff_test_inputs.py rename to tests/huff_test_inputs.py diff --git a/test/quant_test_inputs.py b/tests/quant_test_inputs.py similarity index 100% rename from test/quant_test_inputs.py rename to tests/quant_test_inputs.py diff --git a/test/reference_designs/jpegenc_v1/verilog/AC_CR_ROM.v b/tests/reference_designs/jpegenc_v1/verilog/AC_CR_ROM.v similarity index 100% rename from test/reference_designs/jpegenc_v1/verilog/AC_CR_ROM.v rename to tests/reference_designs/jpegenc_v1/verilog/AC_CR_ROM.v diff --git a/test/reference_designs/jpegenc_v1/verilog/AC_ROM.v b/tests/reference_designs/jpegenc_v1/verilog/AC_ROM.v similarity index 100% rename from test/reference_designs/jpegenc_v1/verilog/AC_ROM.v rename to tests/reference_designs/jpegenc_v1/verilog/AC_ROM.v diff --git a/test/reference_designs/jpegenc_v1/verilog/BUF_FIFO.v b/tests/reference_designs/jpegenc_v1/verilog/BUF_FIFO.v similarity index 100% rename from test/reference_designs/jpegenc_v1/verilog/BUF_FIFO.v rename to tests/reference_designs/jpegenc_v1/verilog/BUF_FIFO.v diff --git a/test/reference_designs/jpegenc_v1/verilog/ByteStuffer.v b/tests/reference_designs/jpegenc_v1/verilog/ByteStuffer.v similarity index 100% rename from test/reference_designs/jpegenc_v1/verilog/ByteStuffer.v rename to tests/reference_designs/jpegenc_v1/verilog/ByteStuffer.v diff --git a/test/reference_designs/jpegenc_v1/verilog/CtrlSM.v b/tests/reference_designs/jpegenc_v1/verilog/CtrlSM.v similarity index 100% rename from test/reference_designs/jpegenc_v1/verilog/CtrlSM.v rename to tests/reference_designs/jpegenc_v1/verilog/CtrlSM.v diff --git a/test/reference_designs/jpegenc_v1/verilog/DBUFCTL.v b/tests/reference_designs/jpegenc_v1/verilog/DBUFCTL.v similarity index 100% rename from test/reference_designs/jpegenc_v1/verilog/DBUFCTL.v rename to tests/reference_designs/jpegenc_v1/verilog/DBUFCTL.v diff --git a/test/reference_designs/jpegenc_v1/verilog/DCT1D.v b/tests/reference_designs/jpegenc_v1/verilog/DCT1D.v similarity index 100% rename from test/reference_designs/jpegenc_v1/verilog/DCT1D.v rename to tests/reference_designs/jpegenc_v1/verilog/DCT1D.v diff --git a/test/reference_designs/jpegenc_v1/verilog/DCT2D.v b/tests/reference_designs/jpegenc_v1/verilog/DCT2D.v similarity index 100% rename from test/reference_designs/jpegenc_v1/verilog/DCT2D.v rename to tests/reference_designs/jpegenc_v1/verilog/DCT2D.v diff --git a/test/reference_designs/jpegenc_v1/verilog/DC_CR_ROM.v b/tests/reference_designs/jpegenc_v1/verilog/DC_CR_ROM.v similarity index 100% rename from test/reference_designs/jpegenc_v1/verilog/DC_CR_ROM.v rename to tests/reference_designs/jpegenc_v1/verilog/DC_CR_ROM.v diff --git a/test/reference_designs/jpegenc_v1/verilog/DC_ROM.v b/tests/reference_designs/jpegenc_v1/verilog/DC_ROM.v similarity index 100% rename from test/reference_designs/jpegenc_v1/verilog/DC_ROM.v rename to tests/reference_designs/jpegenc_v1/verilog/DC_ROM.v diff --git a/test/reference_designs/jpegenc_v1/verilog/DoubleFifo.v b/tests/reference_designs/jpegenc_v1/verilog/DoubleFifo.v similarity index 100% rename from test/reference_designs/jpegenc_v1/verilog/DoubleFifo.v rename to tests/reference_designs/jpegenc_v1/verilog/DoubleFifo.v diff --git a/test/reference_designs/jpegenc_v1/verilog/FDCT.v b/tests/reference_designs/jpegenc_v1/verilog/FDCT.v similarity index 100% rename from test/reference_designs/jpegenc_v1/verilog/FDCT.v rename to tests/reference_designs/jpegenc_v1/verilog/FDCT.v diff --git a/test/reference_designs/jpegenc_v1/verilog/FIFO.v b/tests/reference_designs/jpegenc_v1/verilog/FIFO.v similarity index 100% rename from test/reference_designs/jpegenc_v1/verilog/FIFO.v rename to tests/reference_designs/jpegenc_v1/verilog/FIFO.v diff --git a/test/reference_designs/jpegenc_v1/verilog/HeaderRAM.v b/tests/reference_designs/jpegenc_v1/verilog/HeaderRAM.v similarity index 100% rename from test/reference_designs/jpegenc_v1/verilog/HeaderRAM.v rename to tests/reference_designs/jpegenc_v1/verilog/HeaderRAM.v diff --git a/test/reference_designs/jpegenc_v1/verilog/HostIF.v b/tests/reference_designs/jpegenc_v1/verilog/HostIF.v similarity index 100% rename from test/reference_designs/jpegenc_v1/verilog/HostIF.v rename to tests/reference_designs/jpegenc_v1/verilog/HostIF.v diff --git a/test/reference_designs/jpegenc_v1/verilog/Huffman.v b/tests/reference_designs/jpegenc_v1/verilog/Huffman.v similarity index 100% rename from test/reference_designs/jpegenc_v1/verilog/Huffman.v rename to tests/reference_designs/jpegenc_v1/verilog/Huffman.v diff --git a/test/reference_designs/jpegenc_v1/verilog/JFIFGen.v b/tests/reference_designs/jpegenc_v1/verilog/JFIFGen.v similarity index 100% rename from test/reference_designs/jpegenc_v1/verilog/JFIFGen.v rename to tests/reference_designs/jpegenc_v1/verilog/JFIFGen.v diff --git a/test/reference_designs/jpegenc_v1/verilog/JpegEnc.v b/tests/reference_designs/jpegenc_v1/verilog/JpegEnc.v similarity index 100% rename from test/reference_designs/jpegenc_v1/verilog/JpegEnc.v rename to tests/reference_designs/jpegenc_v1/verilog/JpegEnc.v diff --git a/test/reference_designs/jpegenc_v1/verilog/MDCT.v b/tests/reference_designs/jpegenc_v1/verilog/MDCT.v similarity index 100% rename from test/reference_designs/jpegenc_v1/verilog/MDCT.v rename to tests/reference_designs/jpegenc_v1/verilog/MDCT.v diff --git a/test/reference_designs/jpegenc_v1/verilog/OutMux.v b/tests/reference_designs/jpegenc_v1/verilog/OutMux.v similarity index 100% rename from test/reference_designs/jpegenc_v1/verilog/OutMux.v rename to tests/reference_designs/jpegenc_v1/verilog/OutMux.v diff --git a/test/reference_designs/jpegenc_v1/verilog/QUANTIZER.v b/tests/reference_designs/jpegenc_v1/verilog/QUANTIZER.v similarity index 100% rename from test/reference_designs/jpegenc_v1/verilog/QUANTIZER.v rename to tests/reference_designs/jpegenc_v1/verilog/QUANTIZER.v diff --git a/test/reference_designs/jpegenc_v1/verilog/QUANT_TOP.v b/tests/reference_designs/jpegenc_v1/verilog/QUANT_TOP.v similarity index 100% rename from test/reference_designs/jpegenc_v1/verilog/QUANT_TOP.v rename to tests/reference_designs/jpegenc_v1/verilog/QUANT_TOP.v diff --git a/test/reference_designs/jpegenc_v1/verilog/RAM.v b/tests/reference_designs/jpegenc_v1/verilog/RAM.v similarity index 100% rename from test/reference_designs/jpegenc_v1/verilog/RAM.v rename to tests/reference_designs/jpegenc_v1/verilog/RAM.v diff --git a/test/reference_designs/jpegenc_v1/verilog/RAMF.v b/tests/reference_designs/jpegenc_v1/verilog/RAMF.v similarity index 100% rename from test/reference_designs/jpegenc_v1/verilog/RAMF.v rename to tests/reference_designs/jpegenc_v1/verilog/RAMF.v diff --git a/test/reference_designs/jpegenc_v1/verilog/RAMZ.v b/tests/reference_designs/jpegenc_v1/verilog/RAMZ.v similarity index 100% rename from test/reference_designs/jpegenc_v1/verilog/RAMZ.v rename to tests/reference_designs/jpegenc_v1/verilog/RAMZ.v diff --git a/test/reference_designs/jpegenc_v1/verilog/RLE.v b/tests/reference_designs/jpegenc_v1/verilog/RLE.v similarity index 100% rename from test/reference_designs/jpegenc_v1/verilog/RLE.v rename to tests/reference_designs/jpegenc_v1/verilog/RLE.v diff --git a/test/reference_designs/jpegenc_v1/verilog/RLE_TOP.v b/tests/reference_designs/jpegenc_v1/verilog/RLE_TOP.v similarity index 100% rename from test/reference_designs/jpegenc_v1/verilog/RLE_TOP.v rename to tests/reference_designs/jpegenc_v1/verilog/RLE_TOP.v diff --git a/test/reference_designs/jpegenc_v1/verilog/ROME.v b/tests/reference_designs/jpegenc_v1/verilog/ROME.v similarity index 100% rename from test/reference_designs/jpegenc_v1/verilog/ROME.v rename to tests/reference_designs/jpegenc_v1/verilog/ROME.v diff --git a/test/reference_designs/jpegenc_v1/verilog/ROMO.v b/tests/reference_designs/jpegenc_v1/verilog/ROMO.v similarity index 100% rename from test/reference_designs/jpegenc_v1/verilog/ROMO.v rename to tests/reference_designs/jpegenc_v1/verilog/ROMO.v diff --git a/test/reference_designs/jpegenc_v1/verilog/ROMR.v b/tests/reference_designs/jpegenc_v1/verilog/ROMR.v similarity index 100% rename from test/reference_designs/jpegenc_v1/verilog/ROMR.v rename to tests/reference_designs/jpegenc_v1/verilog/ROMR.v diff --git a/test/reference_designs/jpegenc_v1/verilog/RleDoubleFifo.v b/tests/reference_designs/jpegenc_v1/verilog/RleDoubleFifo.v similarity index 100% rename from test/reference_designs/jpegenc_v1/verilog/RleDoubleFifo.v rename to tests/reference_designs/jpegenc_v1/verilog/RleDoubleFifo.v diff --git a/test/reference_designs/jpegenc_v1/verilog/SUB_RAMZ.v b/tests/reference_designs/jpegenc_v1/verilog/SUB_RAMZ.v similarity index 100% rename from test/reference_designs/jpegenc_v1/verilog/SUB_RAMZ.v rename to tests/reference_designs/jpegenc_v1/verilog/SUB_RAMZ.v diff --git a/test/reference_designs/jpegenc_v1/verilog/SingleSM.v b/tests/reference_designs/jpegenc_v1/verilog/SingleSM.v similarity index 100% rename from test/reference_designs/jpegenc_v1/verilog/SingleSM.v rename to tests/reference_designs/jpegenc_v1/verilog/SingleSM.v diff --git a/test/reference_designs/jpegenc_v1/verilog/ZIGZAG.v b/tests/reference_designs/jpegenc_v1/verilog/ZIGZAG.v similarity index 100% rename from test/reference_designs/jpegenc_v1/verilog/ZIGZAG.v rename to tests/reference_designs/jpegenc_v1/verilog/ZIGZAG.v diff --git a/test/reference_designs/jpegenc_v1/verilog/ZZ_TOP.v b/tests/reference_designs/jpegenc_v1/verilog/ZZ_TOP.v similarity index 100% rename from test/reference_designs/jpegenc_v1/verilog/ZZ_TOP.v rename to tests/reference_designs/jpegenc_v1/verilog/ZZ_TOP.v diff --git a/test/reference_designs/jpegenc_v1/verilog/fdct_read_proc_sm_mon.py b/tests/reference_designs/jpegenc_v1/verilog/fdct_read_proc_sm_mon.py similarity index 100% rename from test/reference_designs/jpegenc_v1/verilog/fdct_read_proc_sm_mon.py rename to tests/reference_designs/jpegenc_v1/verilog/fdct_read_proc_sm_mon.py diff --git a/test/reference_designs/jpegenc_v1/verilog/header.hex b/tests/reference_designs/jpegenc_v1/verilog/header.hex similarity index 100% rename from test/reference_designs/jpegenc_v1/verilog/header.hex rename to tests/reference_designs/jpegenc_v1/verilog/header.hex diff --git a/test/reference_designs/jpegenc_v1/verilog/m_fdct_read_proc_sm_monitor.v b/tests/reference_designs/jpegenc_v1/verilog/m_fdct_read_proc_sm_monitor.v similarity index 100% rename from test/reference_designs/jpegenc_v1/verilog/m_fdct_read_proc_sm_monitor.v rename to tests/reference_designs/jpegenc_v1/verilog/m_fdct_read_proc_sm_monitor.v diff --git a/test/reference_designs/jpegenc_v1/verilog/m_zz_rom.v b/tests/reference_designs/jpegenc_v1/verilog/m_zz_rom.v similarity index 100% rename from test/reference_designs/jpegenc_v1/verilog/m_zz_rom.v rename to tests/reference_designs/jpegenc_v1/verilog/m_zz_rom.v diff --git a/test/reference_designs/jpegenc_v1/verilog/mdct_coefs.py b/tests/reference_designs/jpegenc_v1/verilog/mdct_coefs.py similarity index 100% rename from test/reference_designs/jpegenc_v1/verilog/mdct_coefs.py rename to tests/reference_designs/jpegenc_v1/verilog/mdct_coefs.py diff --git a/test/reference_designs/jpegenc_v1/verilog/output_files/RAM.v b/tests/reference_designs/jpegenc_v1/verilog/output_files/RAM.v similarity index 100% rename from test/reference_designs/jpegenc_v1/verilog/output_files/RAM.v rename to tests/reference_designs/jpegenc_v1/verilog/output_files/RAM.v diff --git a/test/reference_designs/jpegenc_v1/verilog/output_files/RAM_6x12.v b/tests/reference_designs/jpegenc_v1/verilog/output_files/RAM_6x12.v similarity index 100% rename from test/reference_designs/jpegenc_v1/verilog/output_files/RAM_6x12.v rename to tests/reference_designs/jpegenc_v1/verilog/output_files/RAM_6x12.v diff --git a/test/reference_designs/jpegenc_v1/verilog/output_files/ROME.v b/tests/reference_designs/jpegenc_v1/verilog/output_files/ROME.v similarity index 100% rename from test/reference_designs/jpegenc_v1/verilog/output_files/ROME.v rename to tests/reference_designs/jpegenc_v1/verilog/output_files/ROME.v diff --git a/test/reference_designs/jpegenc_v1/verilog/output_files/ROMO.v b/tests/reference_designs/jpegenc_v1/verilog/output_files/ROMO.v similarity index 100% rename from test/reference_designs/jpegenc_v1/verilog/output_files/ROMO.v rename to tests/reference_designs/jpegenc_v1/verilog/output_files/ROMO.v diff --git a/test/reference_designs/jpegenc_v1/verilog/output_files/ROMR.v b/tests/reference_designs/jpegenc_v1/verilog/output_files/ROMR.v similarity index 100% rename from test/reference_designs/jpegenc_v1/verilog/output_files/ROMR.v rename to tests/reference_designs/jpegenc_v1/verilog/output_files/ROMR.v diff --git a/test/reference_designs/jpegenc_v1/verilog/r_divider.v b/tests/reference_designs/jpegenc_v1/verilog/r_divider.v similarity index 100% rename from test/reference_designs/jpegenc_v1/verilog/r_divider.v rename to tests/reference_designs/jpegenc_v1/verilog/r_divider.v diff --git a/test/reference_designs/jpegenc_v1/verilog/ramz.py b/tests/reference_designs/jpegenc_v1/verilog/ramz.py similarity index 100% rename from test/reference_designs/jpegenc_v1/verilog/ramz.py rename to tests/reference_designs/jpegenc_v1/verilog/ramz.py diff --git a/test/reference_designs/jpegenc_v1/verilog/rome.py b/tests/reference_designs/jpegenc_v1/verilog/rome.py similarity index 100% rename from test/reference_designs/jpegenc_v1/verilog/rome.py rename to tests/reference_designs/jpegenc_v1/verilog/rome.py diff --git a/test/reference_designs/jpegenc_v1/verilog/romo.py b/tests/reference_designs/jpegenc_v1/verilog/romo.py similarity index 100% rename from test/reference_designs/jpegenc_v1/verilog/romo.py rename to tests/reference_designs/jpegenc_v1/verilog/romo.py diff --git a/test/reference_designs/jpegenc_v1/verilog/romr.py b/tests/reference_designs/jpegenc_v1/verilog/romr.py similarity index 100% rename from test/reference_designs/jpegenc_v1/verilog/romr.py rename to tests/reference_designs/jpegenc_v1/verilog/romr.py diff --git a/test/reference_designs/jpegenc_v1/verilog/wip_todo.txt b/tests/reference_designs/jpegenc_v1/verilog/wip_todo.txt similarity index 100% rename from test/reference_designs/jpegenc_v1/verilog/wip_todo.txt rename to tests/reference_designs/jpegenc_v1/verilog/wip_todo.txt diff --git a/test/reference_designs/jpegenc_v1/vhdl/AC_CR_ROM.vhd b/tests/reference_designs/jpegenc_v1/vhdl/AC_CR_ROM.vhd similarity index 100% rename from test/reference_designs/jpegenc_v1/vhdl/AC_CR_ROM.vhd rename to tests/reference_designs/jpegenc_v1/vhdl/AC_CR_ROM.vhd diff --git a/test/reference_designs/jpegenc_v1/vhdl/AC_ROM.vhd b/tests/reference_designs/jpegenc_v1/vhdl/AC_ROM.vhd similarity index 100% rename from test/reference_designs/jpegenc_v1/vhdl/AC_ROM.vhd rename to tests/reference_designs/jpegenc_v1/vhdl/AC_ROM.vhd diff --git a/test/reference_designs/jpegenc_v1/vhdl/BUF_FIFO.vhd b/tests/reference_designs/jpegenc_v1/vhdl/BUF_FIFO.vhd similarity index 100% rename from test/reference_designs/jpegenc_v1/vhdl/BUF_FIFO.vhd rename to tests/reference_designs/jpegenc_v1/vhdl/BUF_FIFO.vhd diff --git a/test/reference_designs/jpegenc_v1/vhdl/ByteStuffer.vhd b/tests/reference_designs/jpegenc_v1/vhdl/ByteStuffer.vhd similarity index 100% rename from test/reference_designs/jpegenc_v1/vhdl/ByteStuffer.vhd rename to tests/reference_designs/jpegenc_v1/vhdl/ByteStuffer.vhd diff --git a/test/reference_designs/jpegenc_v1/vhdl/CtrlSM.vhd b/tests/reference_designs/jpegenc_v1/vhdl/CtrlSM.vhd similarity index 100% rename from test/reference_designs/jpegenc_v1/vhdl/CtrlSM.vhd rename to tests/reference_designs/jpegenc_v1/vhdl/CtrlSM.vhd diff --git a/test/reference_designs/jpegenc_v1/vhdl/DBUFCTL.vhd b/tests/reference_designs/jpegenc_v1/vhdl/DBUFCTL.vhd similarity index 100% rename from test/reference_designs/jpegenc_v1/vhdl/DBUFCTL.vhd rename to tests/reference_designs/jpegenc_v1/vhdl/DBUFCTL.vhd diff --git a/test/reference_designs/jpegenc_v1/vhdl/DCT1D.vhd b/tests/reference_designs/jpegenc_v1/vhdl/DCT1D.vhd similarity index 100% rename from test/reference_designs/jpegenc_v1/vhdl/DCT1D.vhd rename to tests/reference_designs/jpegenc_v1/vhdl/DCT1D.vhd diff --git a/test/reference_designs/jpegenc_v1/vhdl/DCT2D.vhd b/tests/reference_designs/jpegenc_v1/vhdl/DCT2D.vhd similarity index 100% rename from test/reference_designs/jpegenc_v1/vhdl/DCT2D.vhd rename to tests/reference_designs/jpegenc_v1/vhdl/DCT2D.vhd diff --git a/test/reference_designs/jpegenc_v1/vhdl/DC_CR_ROM.vhd b/tests/reference_designs/jpegenc_v1/vhdl/DC_CR_ROM.vhd similarity index 100% rename from test/reference_designs/jpegenc_v1/vhdl/DC_CR_ROM.vhd rename to tests/reference_designs/jpegenc_v1/vhdl/DC_CR_ROM.vhd diff --git a/test/reference_designs/jpegenc_v1/vhdl/DC_ROM.vhd b/tests/reference_designs/jpegenc_v1/vhdl/DC_ROM.vhd similarity index 100% rename from test/reference_designs/jpegenc_v1/vhdl/DC_ROM.vhd rename to tests/reference_designs/jpegenc_v1/vhdl/DC_ROM.vhd diff --git a/test/reference_designs/jpegenc_v1/vhdl/DoubleFifo.vhd b/tests/reference_designs/jpegenc_v1/vhdl/DoubleFifo.vhd similarity index 100% rename from test/reference_designs/jpegenc_v1/vhdl/DoubleFifo.vhd rename to tests/reference_designs/jpegenc_v1/vhdl/DoubleFifo.vhd diff --git a/test/reference_designs/jpegenc_v1/vhdl/FDCT.vhd b/tests/reference_designs/jpegenc_v1/vhdl/FDCT.vhd similarity index 100% rename from test/reference_designs/jpegenc_v1/vhdl/FDCT.vhd rename to tests/reference_designs/jpegenc_v1/vhdl/FDCT.vhd diff --git a/test/reference_designs/jpegenc_v1/vhdl/FIFO.vhd b/tests/reference_designs/jpegenc_v1/vhdl/FIFO.vhd similarity index 100% rename from test/reference_designs/jpegenc_v1/vhdl/FIFO.vhd rename to tests/reference_designs/jpegenc_v1/vhdl/FIFO.vhd diff --git a/test/reference_designs/jpegenc_v1/vhdl/HeaderRAM.v b/tests/reference_designs/jpegenc_v1/vhdl/HeaderRAM.v similarity index 100% rename from test/reference_designs/jpegenc_v1/vhdl/HeaderRAM.v rename to tests/reference_designs/jpegenc_v1/vhdl/HeaderRAM.v diff --git a/test/reference_designs/jpegenc_v1/vhdl/HeaderRam.vhd b/tests/reference_designs/jpegenc_v1/vhdl/HeaderRam.vhd similarity index 100% rename from test/reference_designs/jpegenc_v1/vhdl/HeaderRam.vhd rename to tests/reference_designs/jpegenc_v1/vhdl/HeaderRam.vhd diff --git a/test/reference_designs/jpegenc_v1/vhdl/HostIF.vhd b/tests/reference_designs/jpegenc_v1/vhdl/HostIF.vhd similarity index 100% rename from test/reference_designs/jpegenc_v1/vhdl/HostIF.vhd rename to tests/reference_designs/jpegenc_v1/vhdl/HostIF.vhd diff --git a/test/reference_designs/jpegenc_v1/vhdl/Huffman.vhd b/tests/reference_designs/jpegenc_v1/vhdl/Huffman.vhd similarity index 100% rename from test/reference_designs/jpegenc_v1/vhdl/Huffman.vhd rename to tests/reference_designs/jpegenc_v1/vhdl/Huffman.vhd diff --git a/test/reference_designs/jpegenc_v1/vhdl/JFIFGen.vhd b/tests/reference_designs/jpegenc_v1/vhdl/JFIFGen.vhd similarity index 100% rename from test/reference_designs/jpegenc_v1/vhdl/JFIFGen.vhd rename to tests/reference_designs/jpegenc_v1/vhdl/JFIFGen.vhd diff --git a/test/reference_designs/jpegenc_v1/vhdl/JPEG_PKG.vhd b/tests/reference_designs/jpegenc_v1/vhdl/JPEG_PKG.vhd similarity index 100% rename from test/reference_designs/jpegenc_v1/vhdl/JPEG_PKG.vhd rename to tests/reference_designs/jpegenc_v1/vhdl/JPEG_PKG.vhd diff --git a/test/reference_designs/jpegenc_v1/vhdl/JpegEnc.vhd b/tests/reference_designs/jpegenc_v1/vhdl/JpegEnc.vhd similarity index 100% rename from test/reference_designs/jpegenc_v1/vhdl/JpegEnc.vhd rename to tests/reference_designs/jpegenc_v1/vhdl/JpegEnc.vhd diff --git a/test/reference_designs/jpegenc_v1/vhdl/MDCT.vhd b/tests/reference_designs/jpegenc_v1/vhdl/MDCT.vhd similarity index 100% rename from test/reference_designs/jpegenc_v1/vhdl/MDCT.vhd rename to tests/reference_designs/jpegenc_v1/vhdl/MDCT.vhd diff --git a/test/reference_designs/jpegenc_v1/vhdl/MDCT_PKG.vhd b/tests/reference_designs/jpegenc_v1/vhdl/MDCT_PKG.vhd similarity index 100% rename from test/reference_designs/jpegenc_v1/vhdl/MDCT_PKG.vhd rename to tests/reference_designs/jpegenc_v1/vhdl/MDCT_PKG.vhd diff --git a/test/reference_designs/jpegenc_v1/vhdl/OutMux.vhd b/tests/reference_designs/jpegenc_v1/vhdl/OutMux.vhd similarity index 100% rename from test/reference_designs/jpegenc_v1/vhdl/OutMux.vhd rename to tests/reference_designs/jpegenc_v1/vhdl/OutMux.vhd diff --git a/test/reference_designs/jpegenc_v1/vhdl/QUANTIZER.vhd b/tests/reference_designs/jpegenc_v1/vhdl/QUANTIZER.vhd similarity index 100% rename from test/reference_designs/jpegenc_v1/vhdl/QUANTIZER.vhd rename to tests/reference_designs/jpegenc_v1/vhdl/QUANTIZER.vhd diff --git a/test/reference_designs/jpegenc_v1/vhdl/QUANT_TOP.vhd b/tests/reference_designs/jpegenc_v1/vhdl/QUANT_TOP.vhd similarity index 100% rename from test/reference_designs/jpegenc_v1/vhdl/QUANT_TOP.vhd rename to tests/reference_designs/jpegenc_v1/vhdl/QUANT_TOP.vhd diff --git a/test/reference_designs/jpegenc_v1/vhdl/RAM.vhd b/tests/reference_designs/jpegenc_v1/vhdl/RAM.vhd similarity index 100% rename from test/reference_designs/jpegenc_v1/vhdl/RAM.vhd rename to tests/reference_designs/jpegenc_v1/vhdl/RAM.vhd diff --git a/test/reference_designs/jpegenc_v1/vhdl/RAMZ.vhd b/tests/reference_designs/jpegenc_v1/vhdl/RAMZ.vhd similarity index 100% rename from test/reference_designs/jpegenc_v1/vhdl/RAMZ.vhd rename to tests/reference_designs/jpegenc_v1/vhdl/RAMZ.vhd diff --git a/test/reference_designs/jpegenc_v1/vhdl/RLE.vhd b/tests/reference_designs/jpegenc_v1/vhdl/RLE.vhd similarity index 100% rename from test/reference_designs/jpegenc_v1/vhdl/RLE.vhd rename to tests/reference_designs/jpegenc_v1/vhdl/RLE.vhd diff --git a/test/reference_designs/jpegenc_v1/vhdl/RLE_TOP.vhd b/tests/reference_designs/jpegenc_v1/vhdl/RLE_TOP.vhd similarity index 100% rename from test/reference_designs/jpegenc_v1/vhdl/RLE_TOP.vhd rename to tests/reference_designs/jpegenc_v1/vhdl/RLE_TOP.vhd diff --git a/test/reference_designs/jpegenc_v1/vhdl/ROME.vhd b/tests/reference_designs/jpegenc_v1/vhdl/ROME.vhd similarity index 100% rename from test/reference_designs/jpegenc_v1/vhdl/ROME.vhd rename to tests/reference_designs/jpegenc_v1/vhdl/ROME.vhd diff --git a/test/reference_designs/jpegenc_v1/vhdl/ROMO.vhd b/tests/reference_designs/jpegenc_v1/vhdl/ROMO.vhd similarity index 100% rename from test/reference_designs/jpegenc_v1/vhdl/ROMO.vhd rename to tests/reference_designs/jpegenc_v1/vhdl/ROMO.vhd diff --git a/test/reference_designs/jpegenc_v1/vhdl/ROMR.vhd b/tests/reference_designs/jpegenc_v1/vhdl/ROMR.vhd similarity index 100% rename from test/reference_designs/jpegenc_v1/vhdl/ROMR.vhd rename to tests/reference_designs/jpegenc_v1/vhdl/ROMR.vhd diff --git a/test/reference_designs/jpegenc_v1/vhdl/RleDoubleFifo.vhd b/tests/reference_designs/jpegenc_v1/vhdl/RleDoubleFifo.vhd similarity index 100% rename from test/reference_designs/jpegenc_v1/vhdl/RleDoubleFifo.vhd rename to tests/reference_designs/jpegenc_v1/vhdl/RleDoubleFifo.vhd diff --git a/test/reference_designs/jpegenc_v1/vhdl/SUB_RAMZ.vhd b/tests/reference_designs/jpegenc_v1/vhdl/SUB_RAMZ.vhd similarity index 100% rename from test/reference_designs/jpegenc_v1/vhdl/SUB_RAMZ.vhd rename to tests/reference_designs/jpegenc_v1/vhdl/SUB_RAMZ.vhd diff --git a/test/reference_designs/jpegenc_v1/vhdl/SingleSM.vhd b/tests/reference_designs/jpegenc_v1/vhdl/SingleSM.vhd similarity index 100% rename from test/reference_designs/jpegenc_v1/vhdl/SingleSM.vhd rename to tests/reference_designs/jpegenc_v1/vhdl/SingleSM.vhd diff --git a/test/reference_designs/jpegenc_v1/vhdl/ZIGZAG.vhd b/tests/reference_designs/jpegenc_v1/vhdl/ZIGZAG.vhd similarity index 100% rename from test/reference_designs/jpegenc_v1/vhdl/ZIGZAG.vhd rename to tests/reference_designs/jpegenc_v1/vhdl/ZIGZAG.vhd diff --git a/test/reference_designs/jpegenc_v1/vhdl/ZZ_TOP.vhd b/tests/reference_designs/jpegenc_v1/vhdl/ZZ_TOP.vhd similarity index 100% rename from test/reference_designs/jpegenc_v1/vhdl/ZZ_TOP.vhd rename to tests/reference_designs/jpegenc_v1/vhdl/ZZ_TOP.vhd diff --git a/test/reference_designs/jpegenc_v1/vhdl/header.hex b/tests/reference_designs/jpegenc_v1/vhdl/header.hex similarity index 100% rename from test/reference_designs/jpegenc_v1/vhdl/header.hex rename to tests/reference_designs/jpegenc_v1/vhdl/header.hex diff --git a/test/reference_designs/jpegenc_v1/vhdl/header_ram.py b/tests/reference_designs/jpegenc_v1/vhdl/header_ram.py similarity index 100% rename from test/reference_designs/jpegenc_v1/vhdl/header_ram.py rename to tests/reference_designs/jpegenc_v1/vhdl/header_ram.py diff --git a/test/reference_designs/jpegenc_v1/vhdl/pck_myhdl_09.vhd b/tests/reference_designs/jpegenc_v1/vhdl/pck_myhdl_09.vhd similarity index 100% rename from test/reference_designs/jpegenc_v1/vhdl/pck_myhdl_09.vhd rename to tests/reference_designs/jpegenc_v1/vhdl/pck_myhdl_09.vhd diff --git a/test/reference_designs/jpegenc_v1/vhdl/r_divider.vhd b/tests/reference_designs/jpegenc_v1/vhdl/r_divider.vhd similarity index 100% rename from test/reference_designs/jpegenc_v1/vhdl/r_divider.vhd rename to tests/reference_designs/jpegenc_v1/vhdl/r_divider.vhd diff --git a/test/reference_designs/jpegenc_v1/vhdl/tb/Makefile b/tests/reference_designs/jpegenc_v1/vhdl/tb/Makefile similarity index 100% rename from test/reference_designs/jpegenc_v1/vhdl/tb/Makefile rename to tests/reference_designs/jpegenc_v1/vhdl/tb/Makefile diff --git a/test/reference_designs/jpegenc_v1/vhdl/tb/vhdl/ClkGen.vhd b/tests/reference_designs/jpegenc_v1/vhdl/tb/vhdl/ClkGen.vhd similarity index 100% rename from test/reference_designs/jpegenc_v1/vhdl/tb/vhdl/ClkGen.vhd rename to tests/reference_designs/jpegenc_v1/vhdl/tb/vhdl/ClkGen.vhd diff --git a/test/reference_designs/jpegenc_v1/vhdl/tb/vhdl/DCT_TROM.vhd b/tests/reference_designs/jpegenc_v1/vhdl/tb/vhdl/DCT_TROM.vhd similarity index 100% rename from test/reference_designs/jpegenc_v1/vhdl/tb/vhdl/DCT_TROM.vhd rename to tests/reference_designs/jpegenc_v1/vhdl/tb/vhdl/DCT_TROM.vhd diff --git a/test/reference_designs/jpegenc_v1/vhdl/tb/vhdl/GPL_V2_Image_pkg.vhd b/tests/reference_designs/jpegenc_v1/vhdl/tb/vhdl/GPL_V2_Image_pkg.vhd similarity index 100% rename from test/reference_designs/jpegenc_v1/vhdl/tb/vhdl/GPL_V2_Image_pkg.vhd rename to tests/reference_designs/jpegenc_v1/vhdl/tb/vhdl/GPL_V2_Image_pkg.vhd diff --git a/test/reference_designs/jpegenc_v1/vhdl/tb/vhdl/HostBFM.vhd b/tests/reference_designs/jpegenc_v1/vhdl/tb/vhdl/HostBFM.vhd similarity index 100% rename from test/reference_designs/jpegenc_v1/vhdl/tb/vhdl/HostBFM.vhd rename to tests/reference_designs/jpegenc_v1/vhdl/tb/vhdl/HostBFM.vhd diff --git a/test/reference_designs/jpegenc_v1/vhdl/tb/vhdl/JPEG_TB.vhd b/tests/reference_designs/jpegenc_v1/vhdl/tb/vhdl/JPEG_TB.vhd similarity index 100% rename from test/reference_designs/jpegenc_v1/vhdl/tb/vhdl/JPEG_TB.vhd rename to tests/reference_designs/jpegenc_v1/vhdl/tb/vhdl/JPEG_TB.vhd diff --git a/test/reference_designs/jpegenc_v1/vhdl/tb/vhdl/MDCTTB_PKG.vhd b/tests/reference_designs/jpegenc_v1/vhdl/tb/vhdl/MDCTTB_PKG.vhd similarity index 100% rename from test/reference_designs/jpegenc_v1/vhdl/tb/vhdl/MDCTTB_PKG.vhd rename to tests/reference_designs/jpegenc_v1/vhdl/tb/vhdl/MDCTTB_PKG.vhd diff --git a/test/reference_designs/jpegenc_v1/vhdl/tb/vhdl/RAMSIM.vhd b/tests/reference_designs/jpegenc_v1/vhdl/tb/vhdl/RAMSIM.vhd similarity index 100% rename from test/reference_designs/jpegenc_v1/vhdl/tb/vhdl/RAMSIM.vhd rename to tests/reference_designs/jpegenc_v1/vhdl/tb/vhdl/RAMSIM.vhd diff --git a/test/reference_designs/jpegenc_v1/vhdl/tb/work/Makefile b/tests/reference_designs/jpegenc_v1/vhdl/tb/work/Makefile similarity index 100% rename from test/reference_designs/jpegenc_v1/vhdl/tb/work/Makefile rename to tests/reference_designs/jpegenc_v1/vhdl/tb/work/Makefile diff --git a/test/reference_designs/jpegenc_v2/myhdl/__init__.py b/tests/reference_designs/jpegenc_v2/myhdl/__init__.py similarity index 100% rename from test/reference_designs/jpegenc_v2/myhdl/__init__.py rename to tests/reference_designs/jpegenc_v2/myhdl/__init__.py diff --git a/test/reference_designs/jpegenc_v2/myhdl/commons.py b/tests/reference_designs/jpegenc_v2/myhdl/commons.py similarity index 100% rename from test/reference_designs/jpegenc_v2/myhdl/commons.py rename to tests/reference_designs/jpegenc_v2/myhdl/commons.py diff --git a/test/reference_designs/jpegenc_v2/myhdl/dct1pinpout.py b/tests/reference_designs/jpegenc_v2/myhdl/dct1pinpout.py similarity index 100% rename from test/reference_designs/jpegenc_v2/myhdl/dct1pinpout.py rename to tests/reference_designs/jpegenc_v2/myhdl/dct1pinpout.py diff --git a/test/reference_designs/jpegenc_v2/myhdl/dct1sinpout.py b/tests/reference_designs/jpegenc_v2/myhdl/dct1sinpout.py similarity index 100% rename from test/reference_designs/jpegenc_v2/myhdl/dct1sinpout.py rename to tests/reference_designs/jpegenc_v2/myhdl/dct1sinpout.py diff --git a/test/reference_designs/jpegenc_v2/myhdl/dct2sinpout.py b/tests/reference_designs/jpegenc_v2/myhdl/dct2sinpout.py similarity index 100% rename from test/reference_designs/jpegenc_v2/myhdl/dct2sinpout.py rename to tests/reference_designs/jpegenc_v2/myhdl/dct2sinpout.py diff --git a/test/reference_designs/jpegenc_v2/myhdl/dctconstructs.py b/tests/reference_designs/jpegenc_v2/myhdl/dctconstructs.py similarity index 100% rename from test/reference_designs/jpegenc_v2/myhdl/dctconstructs.py rename to tests/reference_designs/jpegenc_v2/myhdl/dctconstructs.py diff --git a/test/reference_designs/jpegenc_v2/myhdl/quantizer.py b/tests/reference_designs/jpegenc_v2/myhdl/quantizer.py similarity index 100% rename from test/reference_designs/jpegenc_v2/myhdl/quantizer.py rename to tests/reference_designs/jpegenc_v2/myhdl/quantizer.py diff --git a/test/reference_designs/jpegenc_v2/myhdl/rgb2ycbcr.py b/tests/reference_designs/jpegenc_v2/myhdl/rgb2ycbcr.py similarity index 100% rename from test/reference_designs/jpegenc_v2/myhdl/rgb2ycbcr.py rename to tests/reference_designs/jpegenc_v2/myhdl/rgb2ycbcr.py diff --git a/test/reference_designs/jpegenc_v2/myhdl/test/test_dct1pinpout.py b/tests/reference_designs/jpegenc_v2/myhdl/test/test_dct1pinpout.py similarity index 100% rename from test/reference_designs/jpegenc_v2/myhdl/test/test_dct1pinpout.py rename to tests/reference_designs/jpegenc_v2/myhdl/test/test_dct1pinpout.py diff --git a/test/reference_designs/jpegenc_v2/myhdl/test/test_dct1sinpout.py b/tests/reference_designs/jpegenc_v2/myhdl/test/test_dct1sinpout.py similarity index 100% rename from test/reference_designs/jpegenc_v2/myhdl/test/test_dct1sinpout.py rename to tests/reference_designs/jpegenc_v2/myhdl/test/test_dct1sinpout.py diff --git a/test/reference_designs/jpegenc_v2/myhdl/test/test_dct2sinpout.py b/tests/reference_designs/jpegenc_v2/myhdl/test/test_dct2sinpout.py similarity index 100% rename from test/reference_designs/jpegenc_v2/myhdl/test/test_dct2sinpout.py rename to tests/reference_designs/jpegenc_v2/myhdl/test/test_dct2sinpout.py diff --git a/test/reference_designs/jpegenc_v2/myhdl/test/test_quantizer.py b/tests/reference_designs/jpegenc_v2/myhdl/test/test_quantizer.py similarity index 100% rename from test/reference_designs/jpegenc_v2/myhdl/test/test_quantizer.py rename to tests/reference_designs/jpegenc_v2/myhdl/test/test_quantizer.py diff --git a/test/reference_designs/jpegenc_v2/myhdl/test/test_rgb2ycbcr.py b/tests/reference_designs/jpegenc_v2/myhdl/test/test_rgb2ycbcr.py similarity index 100% rename from test/reference_designs/jpegenc_v2/myhdl/test/test_rgb2ycbcr.py rename to tests/reference_designs/jpegenc_v2/myhdl/test/test_rgb2ycbcr.py diff --git a/test/reference_designs/jpegenc_v2/verilog/cb_dct.v b/tests/reference_designs/jpegenc_v2/verilog/cb_dct.v similarity index 100% rename from test/reference_designs/jpegenc_v2/verilog/cb_dct.v rename to tests/reference_designs/jpegenc_v2/verilog/cb_dct.v diff --git a/test/reference_designs/jpegenc_v2/verilog/cb_huff.v b/tests/reference_designs/jpegenc_v2/verilog/cb_huff.v similarity index 100% rename from test/reference_designs/jpegenc_v2/verilog/cb_huff.v rename to tests/reference_designs/jpegenc_v2/verilog/cb_huff.v diff --git a/test/reference_designs/jpegenc_v2/verilog/cb_quantizer.v b/tests/reference_designs/jpegenc_v2/verilog/cb_quantizer.v similarity index 100% rename from test/reference_designs/jpegenc_v2/verilog/cb_quantizer.v rename to tests/reference_designs/jpegenc_v2/verilog/cb_quantizer.v diff --git a/test/reference_designs/jpegenc_v2/verilog/cbd_q_h.v b/tests/reference_designs/jpegenc_v2/verilog/cbd_q_h.v similarity index 100% rename from test/reference_designs/jpegenc_v2/verilog/cbd_q_h.v rename to tests/reference_designs/jpegenc_v2/verilog/cbd_q_h.v diff --git a/test/reference_designs/jpegenc_v2/verilog/cr_dct.v b/tests/reference_designs/jpegenc_v2/verilog/cr_dct.v similarity index 100% rename from test/reference_designs/jpegenc_v2/verilog/cr_dct.v rename to tests/reference_designs/jpegenc_v2/verilog/cr_dct.v diff --git a/test/reference_designs/jpegenc_v2/verilog/cr_huff.v b/tests/reference_designs/jpegenc_v2/verilog/cr_huff.v similarity index 100% rename from test/reference_designs/jpegenc_v2/verilog/cr_huff.v rename to tests/reference_designs/jpegenc_v2/verilog/cr_huff.v diff --git a/test/reference_designs/jpegenc_v2/verilog/cr_quantizer.v b/tests/reference_designs/jpegenc_v2/verilog/cr_quantizer.v similarity index 100% rename from test/reference_designs/jpegenc_v2/verilog/cr_quantizer.v rename to tests/reference_designs/jpegenc_v2/verilog/cr_quantizer.v diff --git a/test/reference_designs/jpegenc_v2/verilog/crd_q_h.v b/tests/reference_designs/jpegenc_v2/verilog/crd_q_h.v similarity index 100% rename from test/reference_designs/jpegenc_v2/verilog/crd_q_h.v rename to tests/reference_designs/jpegenc_v2/verilog/crd_q_h.v diff --git a/test/reference_designs/jpegenc_v2/verilog/ff_checker.v b/tests/reference_designs/jpegenc_v2/verilog/ff_checker.v similarity index 100% rename from test/reference_designs/jpegenc_v2/verilog/ff_checker.v rename to tests/reference_designs/jpegenc_v2/verilog/ff_checker.v diff --git a/test/reference_designs/jpegenc_v2/verilog/fifo_out.v b/tests/reference_designs/jpegenc_v2/verilog/fifo_out.v similarity index 100% rename from test/reference_designs/jpegenc_v2/verilog/fifo_out.v rename to tests/reference_designs/jpegenc_v2/verilog/fifo_out.v diff --git a/test/reference_designs/jpegenc_v2/verilog/ja_bits_out.v b/tests/reference_designs/jpegenc_v2/verilog/ja_bits_out.v similarity index 100% rename from test/reference_designs/jpegenc_v2/verilog/ja_bits_out.v rename to tests/reference_designs/jpegenc_v2/verilog/ja_bits_out.v diff --git a/test/reference_designs/jpegenc_v2/verilog/jpeg_top.v b/tests/reference_designs/jpegenc_v2/verilog/jpeg_top.v similarity index 100% rename from test/reference_designs/jpegenc_v2/verilog/jpeg_top.v rename to tests/reference_designs/jpegenc_v2/verilog/jpeg_top.v diff --git a/test/reference_designs/jpegenc_v2/verilog/jpeg_top_TB.v b/tests/reference_designs/jpegenc_v2/verilog/jpeg_top_TB.v similarity index 100% rename from test/reference_designs/jpegenc_v2/verilog/jpeg_top_TB.v rename to tests/reference_designs/jpegenc_v2/verilog/jpeg_top_TB.v diff --git a/test/reference_designs/jpegenc_v2/verilog/pre_fifo.v b/tests/reference_designs/jpegenc_v2/verilog/pre_fifo.v similarity index 100% rename from test/reference_designs/jpegenc_v2/verilog/pre_fifo.v rename to tests/reference_designs/jpegenc_v2/verilog/pre_fifo.v diff --git a/test/reference_designs/jpegenc_v2/verilog/rgb2ycbcr.v b/tests/reference_designs/jpegenc_v2/verilog/rgb2ycbcr.v similarity index 100% rename from test/reference_designs/jpegenc_v2/verilog/rgb2ycbcr.v rename to tests/reference_designs/jpegenc_v2/verilog/rgb2ycbcr.v diff --git a/test/reference_designs/jpegenc_v2/verilog/sync_fifo_32.v b/tests/reference_designs/jpegenc_v2/verilog/sync_fifo_32.v similarity index 100% rename from test/reference_designs/jpegenc_v2/verilog/sync_fifo_32.v rename to tests/reference_designs/jpegenc_v2/verilog/sync_fifo_32.v diff --git a/test/reference_designs/jpegenc_v2/verilog/sync_fifo_ff.v b/tests/reference_designs/jpegenc_v2/verilog/sync_fifo_ff.v similarity index 100% rename from test/reference_designs/jpegenc_v2/verilog/sync_fifo_ff.v rename to tests/reference_designs/jpegenc_v2/verilog/sync_fifo_ff.v diff --git a/test/reference_designs/jpegenc_v2/verilog/y_dct.v b/tests/reference_designs/jpegenc_v2/verilog/y_dct.v similarity index 100% rename from test/reference_designs/jpegenc_v2/verilog/y_dct.v rename to tests/reference_designs/jpegenc_v2/verilog/y_dct.v diff --git a/test/reference_designs/jpegenc_v2/verilog/y_huff.v b/tests/reference_designs/jpegenc_v2/verilog/y_huff.v similarity index 100% rename from test/reference_designs/jpegenc_v2/verilog/y_huff.v rename to tests/reference_designs/jpegenc_v2/verilog/y_huff.v diff --git a/test/reference_designs/jpegenc_v2/verilog/y_quantizer.v b/tests/reference_designs/jpegenc_v2/verilog/y_quantizer.v similarity index 100% rename from test/reference_designs/jpegenc_v2/verilog/y_quantizer.v rename to tests/reference_designs/jpegenc_v2/verilog/y_quantizer.v diff --git a/test/reference_designs/jpegenc_v2/verilog/yd_q_h.v b/tests/reference_designs/jpegenc_v2/verilog/yd_q_h.v similarity index 100% rename from test/reference_designs/jpegenc_v2/verilog/yd_q_h.v rename to tests/reference_designs/jpegenc_v2/verilog/yd_q_h.v diff --git a/test/rle_test_inputs.py b/tests/rle_test_inputs.py similarity index 100% rename from test/rle_test_inputs.py rename to tests/rle_test_inputs.py diff --git a/test/setup.cfg b/tests/setup.cfg similarity index 100% rename from test/setup.cfg rename to tests/setup.cfg diff --git a/test/support/__init__.py b/tests/support/__init__.py similarity index 100% rename from test/support/__init__.py rename to tests/support/__init__.py diff --git a/test/support/jpeg_compare_bitstreams.py b/tests/support/jpeg_compare_bitstreams.py similarity index 100% rename from test/support/jpeg_compare_bitstreams.py rename to tests/support/jpeg_compare_bitstreams.py diff --git a/test/support/jpeg_filelist.py b/tests/support/jpeg_filelist.py similarity index 100% rename from test/support/jpeg_filelist.py rename to tests/support/jpeg_filelist.py diff --git a/test/support/jpeg_intf.py b/tests/support/jpeg_intf.py similarity index 100% rename from test/support/jpeg_intf.py rename to tests/support/jpeg_intf.py diff --git a/test/support/jpeg_prep_cosim.py b/tests/support/jpeg_prep_cosim.py similarity index 100% rename from test/support/jpeg_prep_cosim.py rename to tests/support/jpeg_prep_cosim.py diff --git a/test/support/jpeg_roms.py b/tests/support/jpeg_roms.py similarity index 100% rename from test/support/jpeg_roms.py rename to tests/support/jpeg_roms.py diff --git a/test/support/jpeg_v1_intf.py b/tests/support/jpeg_v1_intf.py similarity index 100% rename from test/support/jpeg_v1_intf.py rename to tests/support/jpeg_v1_intf.py diff --git a/test/support/jpeg_v2_intf.py b/tests/support/jpeg_v2_intf.py similarity index 100% rename from test/support/jpeg_v2_intf.py rename to tests/support/jpeg_v2_intf.py diff --git a/test/support/jpegenc_v1_top.py b/tests/support/jpegenc_v1_top.py similarity index 100% rename from test/support/jpegenc_v1_top.py rename to tests/support/jpegenc_v1_top.py diff --git a/test/support/opb.py b/tests/support/opb.py similarity index 100% rename from test/support/opb.py rename to tests/support/opb.py diff --git a/test/support/signal_queue.py b/tests/support/signal_queue.py similarity index 100% rename from test/support/signal_queue.py rename to tests/support/signal_queue.py diff --git a/test/support/utils.py b/tests/support/utils.py similarity index 100% rename from test/support/utils.py rename to tests/support/utils.py diff --git a/test/tb_jpegenc.v b/tests/tb_jpegenc.v similarity index 100% rename from test/tb_jpegenc.v rename to tests/tb_jpegenc.v diff --git a/test/tb_mdct.v b/tests/tb_mdct.v similarity index 100% rename from test/tb_mdct.v rename to tests/tb_mdct.v diff --git a/test/test_backend.py b/tests/test_backend.py similarity index 100% rename from test/test_backend.py rename to tests/test_backend.py diff --git a/test/test_block_buffer.py b/tests/test_block_buffer.py similarity index 100% rename from test/test_block_buffer.py rename to tests/test_block_buffer.py diff --git a/test/test_bytestuffer.py b/tests/test_bytestuffer.py similarity index 100% rename from test/test_bytestuffer.py rename to tests/test_bytestuffer.py diff --git a/test/test_dct_1d.py b/tests/test_dct_1d.py similarity index 100% rename from test/test_dct_1d.py rename to tests/test_dct_1d.py diff --git a/test/test_dct_2d.py b/tests/test_dct_2d.py similarity index 100% rename from test/test_dct_2d.py rename to tests/test_dct_2d.py diff --git a/test/test_divider.py b/tests/test_divider.py similarity index 100% rename from test/test_divider.py rename to tests/test_divider.py diff --git a/test/test_entropycoder.py b/tests/test_entropycoder.py similarity index 100% rename from test/test_entropycoder.py rename to tests/test_entropycoder.py diff --git a/test/test_frontend_v2.py b/tests/test_frontend_v2.py similarity index 100% rename from test/test_frontend_v2.py rename to tests/test_frontend_v2.py diff --git a/test/test_huffdoublebuffer.py b/tests/test_huffdoublebuffer.py similarity index 100% rename from test/test_huffdoublebuffer.py rename to tests/test_huffdoublebuffer.py diff --git a/test/test_huffman.py b/tests/test_huffman.py similarity index 100% rename from test/test_huffman.py rename to tests/test_huffman.py diff --git a/test/test_images/color/small1.png b/tests/test_images/color/small1.png similarity index 100% rename from test/test_images/color/small1.png rename to tests/test_images/color/small1.png diff --git a/test/test_images/color/small2.png b/tests/test_images/color/small2.png similarity index 100% rename from test/test_images/color/small2.png rename to tests/test_images/color/small2.png diff --git a/test/test_images/color/small3.png b/tests/test_images/color/small3.png similarity index 100% rename from test/test_images/color/small3.png rename to tests/test_images/color/small3.png diff --git a/test/test_images/color/small4.png b/tests/test_images/color/small4.png similarity index 100% rename from test/test_images/color/small4.png rename to tests/test_images/color/small4.png diff --git a/test/test_quantizer.py b/tests/test_quantizer.py similarity index 100% rename from test/test_quantizer.py rename to tests/test_quantizer.py diff --git a/test/test_quantizer_core.py b/tests/test_quantizer_core.py similarity index 100% rename from test/test_quantizer_core.py rename to tests/test_quantizer_core.py diff --git a/test/test_ref_designs.py b/tests/test_ref_designs.py similarity index 100% rename from test/test_ref_designs.py rename to tests/test_ref_designs.py diff --git a/test/test_ref_mdct.py b/tests/test_ref_mdct.py similarity index 100% rename from test/test_ref_mdct.py rename to tests/test_ref_mdct.py diff --git a/test/test_rgb2ycbcr.py b/tests/test_rgb2ycbcr.py similarity index 100% rename from test/test_rgb2ycbcr.py rename to tests/test_rgb2ycbcr.py diff --git a/test/test_rgb2ycbcr_v2.py b/tests/test_rgb2ycbcr_v2.py similarity index 100% rename from test/test_rgb2ycbcr_v2.py rename to tests/test_rgb2ycbcr_v2.py diff --git a/test/test_rle.py b/tests/test_rle.py similarity index 100% rename from test/test_rle.py rename to tests/test_rle.py diff --git a/test/test_rlecore.py b/tests/test_rlecore.py similarity index 100% rename from test/test_rlecore.py rename to tests/test_rlecore.py diff --git a/test/test_rledoublebuffer.py b/tests/test_rledoublebuffer.py similarity index 100% rename from test/test_rledoublebuffer.py rename to tests/test_rledoublebuffer.py diff --git a/test/test_zig_zag.py b/tests/test_zig_zag.py similarity index 100% rename from test/test_zig_zag.py rename to tests/test_zig_zag.py From 246e209d3cdb85432464daac7c52c686220e5df0 Mon Sep 17 00:00:00 2001 From: Christopher Felton Date: Wed, 21 Sep 2016 13:56:37 -0500 Subject: [PATCH 06/32] updating and reorg docs --- docs/source/overview.rst | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/docs/source/overview.rst b/docs/source/overview.rst index c94789d..cb65b04 100644 --- a/docs/source/overview.rst +++ b/docs/source/overview.rst @@ -2,17 +2,19 @@ Overview ======== -.. image:: https://docs.google.com/drawings/d/1c9tR1OmzBcTfnZdMq3hcuBwiMCCwYyGezcLF3YnsZQg/pub?w=996&h=382 +.. image:: https://cloud.githubusercontent.com/assets/766391/18724671/e3eff6e8-8002-11e6-9dfe-9a03379a06fb.png + :scale: 80% + + The JPEG encoder system diagram - The JPEG encoder system diagram Measurements ------------ .. toctree:: - :maxdepth: 1 + :maxdepth: 1 - Coverage<./subblocks/coverage.rst> - Implementation Results<./subblocks/impl.rst> + Coverage<./subblocks/coverage.rst> + Implementation Results<./subblocks/impl.rst> From 85a623542895b3aa9279ddea75779795c8779315 Mon Sep 17 00:00:00 2001 From: Christopher Felton Date: Wed, 21 Sep 2016 13:58:30 -0500 Subject: [PATCH 07/32] renamed test to tests (pytest recommended) --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 2ed7005..76e920f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -42,7 +42,7 @@ install: script: - - cd test + - cd tests - coverage run --source=jpegenc -m py.test --include-reference - cp .coverage ../ From a54f6c5c84c55d2195eb3b8daa78de1b37ab82e6 Mon Sep 17 00:00:00 2001 From: Christopher Felton Date: Wed, 21 Sep 2016 14:12:56 -0500 Subject: [PATCH 08/32] updating and reorg docs --- docs/source/overview.rst | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/source/overview.rst b/docs/source/overview.rst index cb65b04..15b3bce 100644 --- a/docs/source/overview.rst +++ b/docs/source/overview.rst @@ -1,12 +1,16 @@ Overview ======== +This is the documentation for a JPEG encoder implemented in MyHDL. +The following figure outlines the main subblocks in the system. -.. image:: https://cloud.githubusercontent.com/assets/766391/18724671/e3eff6e8-8002-11e6-9dfe-9a03379a06fb.png +.. figure:: https://cloud.githubusercontent.com/assets/766391/18724671/e3eff6e8-8002-11e6-9dfe-9a03379a06fb.png :scale: 80% The JPEG encoder system diagram +The subblocks were designed to be independent and process an +image stream. Measurements From 3cec4b61b160d8ac36c9f826deab4f7d58c237a3 Mon Sep 17 00:00:00 2001 From: Christopher Felton Date: Wed, 21 Sep 2016 21:55:57 -0500 Subject: [PATCH 09/32] updating docs --- docs/source/overview.rst | 22 ++++++++++++++++++++-- docs/source/reference.rst | 2 -- jpegenc/models/__init__.py | 5 +++++ jpegenc/models/buffers/__init__.py | 6 +++++- scripts/ci/install_myhdl.sh | 2 +- 5 files changed, 31 insertions(+), 6 deletions(-) diff --git a/docs/source/overview.rst b/docs/source/overview.rst index 15b3bce..7929ece 100644 --- a/docs/source/overview.rst +++ b/docs/source/overview.rst @@ -1,7 +1,11 @@ Overview ======== -This is the documentation for a JPEG encoder implemented in MyHDL. +The `jpegenc` package is a JPEG encoder implemented in +[MyHDL](http://www.myhdl.org). The JPEG encoder is intended to be +flexible with reusable subblocks. This project also includes a +verification environment for the encoder. + The following figure outlines the main subblocks in the system. .. figure:: https://cloud.githubusercontent.com/assets/766391/18724671/e3eff6e8-8002-11e6-9dfe-9a03379a06fb.png @@ -13,8 +17,22 @@ The subblocks were designed to be independent and process an image stream. +Uses +---- + * (M)JPEG real-time video compression. + * Framework for investigation image and video compression. + + +Goals +----- + + * Easy to use and understand JPEG encoder implementation. + * Flexible (modular) and reusable subblocks. + * Base set of blocks to build various image and video encoders. + + Measurements ------------- +============ .. toctree:: :maxdepth: 1 diff --git a/docs/source/reference.rst b/docs/source/reference.rst index 258539b..cffda61 100644 --- a/docs/source/reference.rst +++ b/docs/source/reference.rst @@ -16,8 +16,6 @@ Frontend Interfaces ++++++++++ -Interfaces: - .. toctree:: :maxdepth: 1 diff --git a/jpegenc/models/__init__.py b/jpegenc/models/__init__.py index e69de29..1f29882 100644 --- a/jpegenc/models/__init__.py +++ b/jpegenc/models/__init__.py @@ -0,0 +1,5 @@ + +from .interfaces import DataStream +from .interfaces import RGBStream + +from .processing import ProcessingSubblock \ No newline at end of file diff --git a/jpegenc/models/buffers/__init__.py b/jpegenc/models/buffers/__init__.py index c056495..336b5c7 100644 --- a/jpegenc/models/buffers/__init__.py +++ b/jpegenc/models/buffers/__init__.py @@ -1,5 +1,9 @@ from __future__ import absolute_import +from .fifo_ready_valid import FIFOReadyValid +# from .row_buffer import RowBuffer + from .block_buffer import PixelStream from .block_buffer import ImageBlock -from .block_buffer import mdl_block_buffer \ No newline at end of file +from .block_buffer import mdl_block_buffer +# from .block_buffer import BlockBuffer \ No newline at end of file diff --git a/scripts/ci/install_myhdl.sh b/scripts/ci/install_myhdl.sh index b3f8f7c..a1314e9 100644 --- a/scripts/ci/install_myhdl.sh +++ b/scripts/ci/install_myhdl.sh @@ -4,4 +4,4 @@ cd myhdl python setup.py install make -C cosimulation/icarus # copy the VPI to the test directory -cp cosimulation/icarus/myhdl.vpi ../test/ +cp cosimulation/icarus/myhdl.vpi ../tests/ From b7a5e6bb18350b9edd68723989d5119166971b83 Mon Sep 17 00:00:00 2001 From: Christopher Felton Date: Wed, 5 Oct 2016 05:19:48 -0500 Subject: [PATCH 10/32] added test_models --- .../test_single_processing_subblock.py | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 tests/test_models/test_single_processing_subblock.py diff --git a/tests/test_models/test_single_processing_subblock.py b/tests/test_models/test_single_processing_subblock.py new file mode 100644 index 0000000..7d7a50a --- /dev/null +++ b/tests/test_models/test_single_processing_subblock.py @@ -0,0 +1,57 @@ + +import myhdl +from myhdl import instance, delay, StopSimulation +from rhea import Global, Clock + +from jpegenc.models import DataStream +from jpegenc.models import ProcessingSubblock +from jpegenc.models.video import ColorBars +from jpegenc.models.video import BitstreamDevourer + +from jpegenc.testing import run_testbench + + +def test_single_pb(): + """Test a single processing subblock + + This test will verify the basic building blocks to model and prototype + the data flow through an image processing system. The blocks uses + are: + ColorBars: video sources, generates the continuous video stream + ProcessingSubblock: a generic model for a processing blocks + (subblock) in the system. In this test a single + """ + resolution = (640, 480) + frame_rate = 60 + color_depth = (8, 8, 8) + + @myhdl.block + def bench(): + clock = Clock(0, frequency=125e6) + glbl = Global(clock) + ck_drv = clock.gen() + + # a known generated video stream + video_source = ColorBars(resolution=resolution, color_depth=color_depth, + frame_rate=frame_rate) + vd_proc = video_source.process(glbl) + + # processing element that does nothing :) + data = DataStream(data_width=len(video_source.pixels.data)) + pe = ProcessingSubblock(cycles_to_process=1) + pe_proc = pe.process(glbl, video_source.pixels, data) + + # collect the output and compare if the video_source supports + # checking, use an encoder (decode portion) if one exists + video_sink = BitstreamDevourer(source=video_source, encoder=None) + vk_proc = video_sink.process(glbl, data) + + @instance + def tbstim(): + yield delay(1000) + raise StopSimulation + + return myhdl.instances() + + run_testbench(bench, trace=True, bench_id="single_process_subblock") + From cb51963e2a9f95bd3f551aae0f553c26b823e0bd Mon Sep 17 00:00:00 2001 From: Christopher Felton Date: Sat, 8 Oct 2016 10:00:54 -0500 Subject: [PATCH 11/32] moved many of the support test modules to jpegenc/testing Organized many of the test support to jpegenc/testing. Also adding models and model tests. --- README.md | 2 +- jpegenc/models/buffers/__init__.py | 3 +- jpegenc/models/buffers/fifo_ready_valid.py | 58 +++++ jpegenc/models/interfaces.py | 228 ++++++++++++++++++ jpegenc/models/processing.py | 119 +++++++++ jpegenc/models/useful_things.py | 16 ++ jpegenc/models/video/__init__.py | 3 + jpegenc/models/video/bitstream.py | 40 +++ jpegenc/models/video/colorbars.py | 95 ++++++++ jpegenc/models/video/video_source.py | 135 +++++++++++ .../testing/cosim}/__init__.py | 0 .../testing/cosim}/jpeg_compare_bitstreams.py | 0 .../testing/cosim}/jpeg_filelist.py | 0 .../testing/cosim}/jpeg_intf.py | 0 .../testing/cosim}/jpeg_prep_cosim.py | 0 .../testing/cosim}/jpeg_roms.py | 0 .../testing/cosim}/jpeg_v1_intf.py | 0 .../testing/cosim}/jpeg_v2_intf.py | 0 .../testing/cosim}/jpegenc_v1_top.py | 0 .../support => jpegenc/testing/cosim}/opb.py | 0 .../testing/cosim}/signal_queue.py | 0 .../testing/cosim}/utils.py | 0 .../testing/huff_inputs.py | 5 + jpegenc/testing/quant_inputs.py | 35 +++ .../testing/rle_inputs.py | 6 + tests/quant_test_inputs.py | 29 --- tests/test_huffman.py | 50 ++-- tests/test_quantizer.py | 34 +-- tests/test_quantizer_core.py | 28 ++- tests/test_ref_designs.py | 5 +- tests/test_ref_mdct.py | 2 +- tests/test_rle.py | 37 ++- tests/{test_rlecore.py => test_rle_core.py} | 30 ++- 33 files changed, 841 insertions(+), 119 deletions(-) create mode 100644 jpegenc/models/buffers/fifo_ready_valid.py create mode 100644 jpegenc/models/interfaces.py create mode 100644 jpegenc/models/processing.py create mode 100644 jpegenc/models/useful_things.py create mode 100644 jpegenc/models/video/__init__.py create mode 100644 jpegenc/models/video/bitstream.py create mode 100644 jpegenc/models/video/colorbars.py create mode 100644 jpegenc/models/video/video_source.py rename {tests/support => jpegenc/testing/cosim}/__init__.py (100%) rename {tests/support => jpegenc/testing/cosim}/jpeg_compare_bitstreams.py (100%) rename {tests/support => jpegenc/testing/cosim}/jpeg_filelist.py (100%) rename {tests/support => jpegenc/testing/cosim}/jpeg_intf.py (100%) rename {tests/support => jpegenc/testing/cosim}/jpeg_prep_cosim.py (100%) rename {tests/support => jpegenc/testing/cosim}/jpeg_roms.py (100%) rename {tests/support => jpegenc/testing/cosim}/jpeg_v1_intf.py (100%) rename {tests/support => jpegenc/testing/cosim}/jpeg_v2_intf.py (100%) rename {tests/support => jpegenc/testing/cosim}/jpegenc_v1_top.py (100%) rename {tests/support => jpegenc/testing/cosim}/opb.py (100%) rename {tests/support => jpegenc/testing/cosim}/signal_queue.py (100%) rename {tests/support => jpegenc/testing/cosim}/utils.py (100%) rename tests/huff_test_inputs.py => jpegenc/testing/huff_inputs.py (91%) create mode 100644 jpegenc/testing/quant_inputs.py rename tests/rle_test_inputs.py => jpegenc/testing/rle_inputs.py (89%) delete mode 100644 tests/quant_test_inputs.py rename tests/{test_rlecore.py => test_rle_core.py} (91%) diff --git a/README.md b/README.md index 9ef9c53..ae77835 100644 --- a/README.md +++ b/README.md @@ -187,7 +187,7 @@ Progress Log Things to be completed ---------------------- - 1. [ ] Use Python3 as the default python verson. + 1. [X] Use Python3 as the default python verson. 1. [ ] Check encoded bitstreams, determine metrics to compare encoders. diff --git a/jpegenc/models/buffers/__init__.py b/jpegenc/models/buffers/__init__.py index 336b5c7..3bf8273 100644 --- a/jpegenc/models/buffers/__init__.py +++ b/jpegenc/models/buffers/__init__.py @@ -1,3 +1,4 @@ + from __future__ import absolute_import from .fifo_ready_valid import FIFOReadyValid @@ -6,4 +7,4 @@ from .block_buffer import PixelStream from .block_buffer import ImageBlock from .block_buffer import mdl_block_buffer -# from .block_buffer import BlockBuffer \ No newline at end of file +# from .block_buffer import BlockBuffer diff --git a/jpegenc/models/buffers/fifo_ready_valid.py b/jpegenc/models/buffers/fifo_ready_valid.py new file mode 100644 index 0000000..1ba2fb5 --- /dev/null +++ b/jpegenc/models/buffers/fifo_ready_valid.py @@ -0,0 +1,58 @@ + +import myhdl +from myhdl import Signal, intbv, instance, always_comb +from rhea import Global, Clock, Signals + + +class FIFOReadyValid(object): + def __init__(self): + """A simple ready-valid FIFO model (no size restriction) + + This FIFO is used to model a ready-valid FIFO that controls the + flow of data in the encoder. The FIFOs will not restrict the + size, the flow stop will need to come from. + """ + self.max_count = 0 + self._fifo = [] + + @property + def count(self): + return len(self._fifo) + + @myhdl.block + def process(self, glbl, datain, dataout): + assert type(datain) == type(dataout), \ + "FIFOReadyValid only supports same type interface in and out" + + clock = glbl.clock + + @instance + def model_fifo(): + while True: + datain.ready.next = True + if len(self._fifo) > 0: + do = self._fifo[0] + else: + do = 0 + dataout.data.next = do + + yield clock.posedge + + if datain.valid: + # @todo: push a complete copy of the data interface + # need to maintain, start-of-frame, end-of-frame + # and other signals and state + self._fifo.append(int(datain.data)) + self.max_count = max(self.max_count, len(self._fifo)) + + if len(self._fifo) > 0: + self.valid.next = True + else: + self.valid.next = False + + # if the downstream is ready, above valid would be set + # pop the read data from the FIFO. + if dataout.ready and len(self._fifo) > 0: + self._fifo.pop(0) + + return myhdl.instances() diff --git a/jpegenc/models/interfaces.py b/jpegenc/models/interfaces.py new file mode 100644 index 0000000..76df02d --- /dev/null +++ b/jpegenc/models/interfaces.py @@ -0,0 +1,228 @@ +""" +Example (exploration) of interface types useful for a JPEG encoder +system. The JPEG encoder (jpegenc) has a collection of processing +blocks with a data-streaming interface to each. The data-streaming +interface is a read-valid flow control interface [1]. + +The base interface has a ``data``, ``ready``, and ``valid`` +attributes, this interface is sufficient to completely define +the data flow between processing blocks (for our first system +definition): + +""" + +from random import randint + +import myhdl +from myhdl import (Signal, ResetSignal, ConcatSignal, intbv, + always_seq, always_comb, ) +from myhdl import instance, delay, StopSimulation +from myhdl.conversion import verify + +try: + from rhea import Signals, assign +except ImportError: + from .useful_things import Signals, assign + + +class DataStream(object): + def __init__(self, data_width=24): + """Data stream with ready-valid flow control.""" + self.data = Signal(intbv(0)[data_width:0]) + self.valid = Signal(bool(0)) + self.ready = Signal(bool(0)) + + def assign(self, stream): + assert isinstance(stream, DataStream) + self.data.next = stream.data + self.valid.next = stream.valid + + +class PixelStream(DataStream): + def __init__(self, data_width=24): + """Pixel stream.""" + self.start_of_frame = Signal(bool(0)) + self.end_of_frame = Signal(bool(0)) + super(PixelStream, self).__init__(data_width+2) + self.data = ConcatSignal(self.start_of_frame, self.end_of_frame, + self.data) + + def assign(self, stream): + assert isinstance(stream, PixelStream) + self.data.next = stream.data + self.valid.next = stream.valid + self.start_of_frame.next = stream.start_of_frame + self.end_of_frame.next = stream.end_of_frame + + # def map_to_data(self): + # raise NotImplementedError() + + +class RGBStream(PixelStream): + def __init__(self, color_depth=(8, 8, 8), num_pixels=1): + """A red-green-blue pixel stream. + Args: + color_depth (tuple): the number of bits for each color component. + num_pixels (int): define the number of pixels in this interface, + this is used to define a parallel interface. + """ + assert len(color_depth) == 3 + data_width = sum(color_depth) + super(RGBStream, self).__init__(data_width=data_width) + + self.color_depth = color_depth + rbits, gbits, bbits = color_depth + print(vars(self)) + + # a single pixel (color component) is the most + if num_pixels == 1: + self.red = Signal(intbv(0)[rbits:0]) + self.green = Signal(intbv(0)[gbits:0]) + self.blue = Signal(intbv(0)[rbits:0]) + # alias to the above signals + self.data = ConcatSignal(self.start_of_frame, self.end_of_frame, + self.red, self.green, self.blue) + else: + self.red = Signals(intbv(0)[rbits:0], num_pixels) + self.green = Signals(intbv(0)[gbits:0], num_pixels) + self.blue = Signals(intbv(0)[rbits:0], num_pixels) + # @todo data alias for multiple pixels + raise NotImplementedError + + def assign(self, stream): + assert isinstance(stream, RGBStream) + self.valid.next = stream.valid + self.start_of_frame.next = stream.start_of_frame + self.end_of_frame.next = stream.end_of_frame + self.red.next = stream.red + self.green.next = stream.green + self.blue.next = stream.blue + + def assign_from_data(self, data): + """Given a data vector, update the attributes""" + assert len(data) == len(self.data) + rbits, gbits, bbits = self.color_depth + self.blue.next = data[bbits:0] + self.green.next = data[gbits+bbits:bbits] + self.red.next = data[rbits+gbits+bbits:gbits] + self.end_of_frame.next = data[rbits] + self.start_of_frame.next = data[rbits+1] + + # @myhdl.block + # def map_to_data(self): + # """Map red, green, and blue to data + # The base interface to all the subblocks is `DataStream` but in most + # of the subblocks it is more convenient to deal with the color + # components. When using the color components the data needs to be + # assigned. + # + # myhdl convertible + # """ + # raise NotImplementedError + # + # # insts = [] + # # for nn in range(self.num_pixels): + # # for jj in range(3): + # # insts = assign() + + +class YCbCrStream(PixelStream): + def __init__(self, color_depth=(8, 8, 8)): + """A y-cb-cr pixel stream. + + Args: + color_depth (tuple): the number of bits for each color component + """ + assert len(color_depth) == 3 + data_width = sum(color_depth) + + super(YCbCrStream, self).__init__(data_width=data_width) + + ybits, cbbits, crbits = color_depth + self.y = Signal(intbv(0)[ybits:]) + self.cb = Signal(intbv(0)[cbbits:]) + self.cr = Signal(intbv(0)[crbits:]) + + # alias to the above color signals + self.data = ConcatSignal(self.y, self.cb, self.cr) + + +class DataBlock(object): + def __init__(self, size=8, min=0, max=8): + """A block of data (parallel data) that is transferred together. + + Arguments: + size: the number of items to have in the block + min: the data min value + max: the data max value + """ + self.size = size + dtype = intbv(0, min=min, max=max) + self.data = Signals(dtype, size) + self.valid = Signal(bool(0)) + self.ready = Signal(bool(0)) + + +class ImageBlock(object): + def __init__(self, size=(8, 8), min=0, max=8): + """ + + Arguments: + size (tuple): + min (int): the min value of the data contained in the + matrix + max (int)L the max value of the data contained in the + matrix + + """ + assert isinstance(size, tuple) + assert len(size) == 2 + self.size = size + ncols, nrows = size + self.nitems = nrows * ncols + dtype = intbv(0, min=min, max=max) + self.nbits = len(dtype) + self.dtype = dtype + + self.mat = [Signals(dtype, ncols) for _ in range(nrows)] + + self.data = self.get_bit_vector() + self.valid = Signal(bool(0)) + self.ready = Signal(bool(0)) + + def __getitem__(self, idx): + item = None + if isinstance(idx, tuple): + item = self.mat[idx[0]][idx[1]] + + return item + + def __setitem__(self): + raise NotImplementedError + + def get_bit_vector(self): + nrows, ncols = self.size + nbits = nrows * ncols * self.nbits + sig = Signal(intbv(0)[nbits:0]) + return sig + + @myhdl.block + def stack(self, flat): + """ """ + nitems = sum(self.size) + nbits = self.nbits + assert len(flat) == nitems*nbits + # create a flat list of signals (references) + + @myhdl.block + def flatten(self, flat): + """ """ + nbits = self.nbits + shadowbits = [col(nbits, 0) for row in self.mat for col in row] + flats = ConcatSignal(*shadowbits) + + @always_comb + def beh_assign(): + flat.next = flats + + return beh_assign \ No newline at end of file diff --git a/jpegenc/models/processing.py b/jpegenc/models/processing.py new file mode 100644 index 0000000..5b6599d --- /dev/null +++ b/jpegenc/models/processing.py @@ -0,0 +1,119 @@ + +from random import randint +from math import floor + +import myhdl +from myhdl import Signal, intbv, instance, always_comb +from rhea import Global, Clock, Signals + +from .interfaces import DataStream, RGBStream +from .buffers import FIFOReadyValid + + +class ProcessingSubblock(object): + def __init__(self, cycles_to_process=1, block_size=None, buffered=False): + """A simple model to represent a processing subblock in the jpegenc + + Arguments: + cycles_to_process: the number of cycles to model, this is the + number of cycles to process a sample/block. If + `cycles_to_process` is a 2-element tuple a random range is + used with the tuple defining the range. + + @todo: latency is the same (essentially) as cycles_to_process, need + some other argument to indicated successive output gaps, + no gap fully pipelined (latency == ctp) if gap == ctp not + pipelined and stalls in between, the same for sample or + block processing. + ~~latency: the latency of the processing, this is additional to + the processing time, but the latency represents a pipeline, + new samples can. If `latency` is a 2-element tuple a random + range is used with the tuple defining the range.~~ + + pipelined: indicates the procesing block is fully pipelined, a + new sample can be input on every clock. The pipeline length + is the ``cycles_to_process``. + + block_size: the size of an image block, if None process + sample by sample. + + buffered + """ + assert isinstance(cycles_to_process, (int, tuple)) + if isinstance(cycles_to_process, tuple): + assert len(cycles_to_process) == 2 + # assert isinstance(latency, int) + # assert isinstance(process_block, bool) + if block_size is not None: + assert isinstance(block_size, tuple) and len(block_size) == 2 + assert isinstance(buffered, bool) + + # the cycles to process is the same as latency + self.ctp = cycles_to_process + # self.lat = latency + self.block_size = block_size + self.buffered = buffered + + if buffered: + # @todo: use buffer_size argument to limit buffer size + # test overruns + self.fifo_i = FIFOReadyValid() + self.fifo_o = FIFOReadyValid() + else: + self.fifo_i = None + self.fifo_o = None + + @myhdl.block + def process(self, glbl, datain, dataout): + assert isinstance(datain, DataStream) + assert isinstance(dataout, DataStream) + + clock, reset = glbl.clock, glbl.reset + ready = Signal(bool(0)) + + # include an input and output fifo + if self.buffered: + # @todo: implement the FIFO + raise NotImplementedError + + # @todo: the interfaces need to override copy ... + buffered_data_i = type(datain)() + buffered_data_o = type(datain)() + + fifo_i = self.fifo_i + fifo_i_inst = fifo_i.process(glbl, datain, buffered_data_i) + fifo_o = self.fifo_o + fifo_o_inst = fifo_o.process(glbl, buffered_data_o, dataout) + else: + buffered_data_i = datain + buffered_data_o = None + + @always_comb + def beh_ready(): + # tell upstream ready to process + if self.buffered: + datain.ready.next = ready and buffered_data_i.ready + else: + datain.ready.next = ready + + # need an intermediate to hold the signal values + # @todo: the interfaces need to overload __copy__, + # To make this generic this needs a new (copy) instance + # with all the same attributes/properties, the current + # only uses the default. + dataproc = type(datain)() + + @instance + def processing_model(): + ready.next = True + while True: + # datain -> dataproc -> dataout + dataproc.assign(datain) + # @todo: fixed at 1 cycle for now + # if the latency is less than + # for nn in range(self.ctp): + yield clock.posedge + dataout.assign(dataproc) + + return myhdl.instances() + diff --git a/jpegenc/models/useful_things.py b/jpegenc/models/useful_things.py new file mode 100644 index 0000000..6918910 --- /dev/null +++ b/jpegenc/models/useful_things.py @@ -0,0 +1,16 @@ + +import myhdl +from myhdl import Signal, always_comb + + +def Signals(dtype, nitems): + return [Signal(dtype) for _ in range(nitems)] + + +@myhdl.block +def assign(a, b): + @always_comb + def beh_assign(): + b.next = a + + return beh_assign diff --git a/jpegenc/models/video/__init__.py b/jpegenc/models/video/__init__.py new file mode 100644 index 0000000..dc8d6d6 --- /dev/null +++ b/jpegenc/models/video/__init__.py @@ -0,0 +1,3 @@ + +from .colorbars import ColorBars +from .bitstream import BitstreamDevourer diff --git a/jpegenc/models/video/bitstream.py b/jpegenc/models/video/bitstream.py new file mode 100644 index 0000000..5b294aa --- /dev/null +++ b/jpegenc/models/video/bitstream.py @@ -0,0 +1,40 @@ + +import myhdl +from myhdl import instance + +from ..interfaces import DataStream +from .video_source import VideoSource + + +class BitstreamDevourer(object): + def __init__(self, source, encoder=None): + assert isinstance(source, VideoSource) + self.source = source + self.resolution = source.resolution + self.encoder = encoder + + @myhdl.block + def process(self, glbl, data): + """ + + Args: + glbl (Global): global interface, contains clock and reset + data (DataStream): final bitstream + + """ + assert isinstance(data, DataStream) + clock, reset = glbl.clock, glbl.reset + src = self.source + + @instance + def mdl_simple_capture(): + """Temp capture and display""" + # ready to receive the data + src.pixel.ready.next = True + while True: + yield clock.posedge + if src.pixel.valid: + print(" [BD]: {:03X}".format(src.pixel.data)) + + return myhdl.instances() + diff --git a/jpegenc/models/video/colorbars.py b/jpegenc/models/video/colorbars.py new file mode 100644 index 0000000..9b98d98 --- /dev/null +++ b/jpegenc/models/video/colorbars.py @@ -0,0 +1,95 @@ + +from collections import OrderedDict + +from .video_source import VideoSource + +# color bar template, lifted from rhea.cores.video.color_bars +COLOR_BARS = OrderedDict( + white=dict(red=1, green=1, blue=1), + yellow=dict(red=1, green=1, blue=0), + cyan=dict(red=0, green=1, blue=1), + green=dict(red=0, green=1, blue=0), + magenta=dict(red=1, green=0, blue=1), + red=dict(red=1, green=0, blue=0), + blue=dict(red=0, green=0, blue=1), + black=dict(red=0, green=0, blue=0), +) + + +class ColorBars(VideoSource): + def __init__(self, resolution=(1920, 1080), color_depth=(8, 8, 8), + frame_rate=60, swap_rate=1): + """A color bar video stream model + + Args: + resolution (tuple): + color_depth (tuple): + frame_rate (float): frame rate of the video in Hz + swap_rate (float): color bar shift in Hz, each bar will + move one to the right at this rate, should be much less + than the frame rate + """ + self.resolution = res = resolution + self.color_depth = color_depth + self.frame_rate = frame_rate + self.swap_rate = swap_rate + + self.pwidth = pwidth = sum(self.color_depth) + self.num_colors, pmax = len(COLOR_BARS), (2**pwidth)-1 + # the bar widths are all the same + self.bar_width = int(res[0] // self.num_colors) + + # create a list to index into + self.color_bars = [vv for vv in COLOR_BARS.values()] + + # convert the colors to the color depth + rmx, gmx, bmx = [(cc**2)-1 for cc in self.color_depth] + for color in self.color_bars: + color['red'] = color['red'] * rmx + color['green'] = color['green'] * gmx + color['blue'] = color['blue'] * gmx + + super(ColorBars, self).__init__(resolution, frame_rate) + + def pixel_value(self, row, col): + # the row index is not used/needed for color bars + idx = int(col // self.bar_width) + color = self.color_bars[idx] + + self.pixel.red.next = r = color['red'] + self.pixel.green.next = g = color['green'] + self.pixel.blue.next = b = color['blue'] + + return r, g, b + + def check_pixel(self, rgb, npixel=None): + """ + + Args: + row: row index of the pixel + col: column index of the pixel + rgb (tuple): + """ + if npixel is None: + npixel = self.npixel + + ncols, nrows = self.resolution + row, col = npixel // nrows, npixel % nrows + r, g, b = self.pixel_value(row, col) + assert r == rgb[0] and g == rgb[1] and b == rgb[2] + + npixel += 1 + if npixel >= (nrows * ncols): + npixel = 0 + + + def check_pixel(self, buffer, frame=0, offset=0): + """Regenerate a frame and compare it to a buffer + + Args: + frame (int): which frame to compare + + Returns: + + """ + pass \ No newline at end of file diff --git a/jpegenc/models/video/video_source.py b/jpegenc/models/video/video_source.py new file mode 100644 index 0000000..f68af22 --- /dev/null +++ b/jpegenc/models/video/video_source.py @@ -0,0 +1,135 @@ + +from math import floor +from random import randint + +import myhdl +from myhdl import Signal, intbv, instance, always_comb + +from ..interfaces import DataStream, RGBStream + + +class VideoSource(object): + def __init__(self, resolution=(1920, 1080), frame_rate=60): + """A model of a video source + This object contains an example of a video source interface and + a process to generate the video source. + + Arguments: + resolution (tuple): the resolution of the video source, the + default is 1920 x 1080 (1080 rows and 1920 columns). + + frame_rate (int): the frame rate of the video source, the + default is 60 Hz (a.k.a. refresh rate). + + Attributes: + pixel (RGBStream): the current pixel in the data stream + rowmon (int): current row index + colmon (int): current col index + + Usage example: + # create a video source object with the defaults + video = VideoStreamSource() + video_inst = video.process() + + row_buffer_inst = video.row_buffer(video, image_block) + + """ + self.resolution = resolution + self.frame_rate = frame_rate + self.pixel = RGBStream(color_depth=(8, 8, 8)) + # signals that monitor the current row and column + self.rowmon = Signal(intbv(0, min=0, max=resolution[1])) + self.colmon = Signal(intbv(0, min=0, max=resolution[0])) + + # the number of clock ticks per pixel + self. pixels_per_second = resolution[0] * resolution[1] * frame_rate + + # this is a counter to keep track of which pixel is being checked + self.npixel = 0 + + def get_ticks(self, clock): + """Get the number of clock ticks per pixel""" + pps = self.pixels_per_second + ticks = int(floor(pps / clock.frequency)) + return ticks + + @myhdl.block + def process(self, glbl): + """Generate random frames + + The default process will simply generate random frames, this + (VideoSource) is intended to be a base class but can be used as + a bare minimum stimulus generator. + + Args: + glbl: interface with clock and reset + + """ + res = self.resolution + num_cols, num_rows = res + clock, reset = glbl.clock, glbl.reset + + # note, if the video rate is not a multiple of the clock then + # the video rate will not be exact (which is fine) + ticks = self.get_ticks(clock) + + @instance + def model_video_source(): + tcnt, row, col = 0, 0, 0 + + for ii in range(23): + yield clock.posedge + + while True: + # default values + self.pixel.start_of_frame.next = False + self.pixel.end_of_frame.next = False + self.pixel.valid.next = False + self.rowmon.next = row + self.colmon.next = col + + if reset == reset.active: + row, col = 0, 0 + continue + + tcnt += 1 + # tick count expired, output a new pixel + if tcnt == ticks: + if row == 0 and col == 0: + self.pixel.start_of_frame.next = True + if row == num_rows-1 and col == num_cols-1: + self.pixel.end_of_frame.next = True + + # set the current pixel value + self.pixel_value(row, col) + self.pixel.valid.next = True + + row = row + 1 if row < num_rows-1 else 0 + col = col + 1 if col < num_cols-1 else 0 + tcnt = 0 + + yield clock.posedge + + return myhdl.instances() + + def pixel_value(self, row, col): + self.pixel.red.next = r = randint(0, self.pixel.red.max - 1) + self.pixel.green.next = g = randint(0, self.pixel.green.max - 1) + self.pixel.blue.next = b = randint(0, self.pixel.blue.max - 1) + + return r, g, b + + def check_pixel(self, rgb, npixel=None): + """Check a pixel + + Args: + rgb (list): + npixel: + + Returns: + + """ + raise NotImplementedError + + def check_buffer(self, buffer, frame=0, offset=0): + raise NotImplementedError diff --git a/tests/support/__init__.py b/jpegenc/testing/cosim/__init__.py similarity index 100% rename from tests/support/__init__.py rename to jpegenc/testing/cosim/__init__.py diff --git a/tests/support/jpeg_compare_bitstreams.py b/jpegenc/testing/cosim/jpeg_compare_bitstreams.py similarity index 100% rename from tests/support/jpeg_compare_bitstreams.py rename to jpegenc/testing/cosim/jpeg_compare_bitstreams.py diff --git a/tests/support/jpeg_filelist.py b/jpegenc/testing/cosim/jpeg_filelist.py similarity index 100% rename from tests/support/jpeg_filelist.py rename to jpegenc/testing/cosim/jpeg_filelist.py diff --git a/tests/support/jpeg_intf.py b/jpegenc/testing/cosim/jpeg_intf.py similarity index 100% rename from tests/support/jpeg_intf.py rename to jpegenc/testing/cosim/jpeg_intf.py diff --git a/tests/support/jpeg_prep_cosim.py b/jpegenc/testing/cosim/jpeg_prep_cosim.py similarity index 100% rename from tests/support/jpeg_prep_cosim.py rename to jpegenc/testing/cosim/jpeg_prep_cosim.py diff --git a/tests/support/jpeg_roms.py b/jpegenc/testing/cosim/jpeg_roms.py similarity index 100% rename from tests/support/jpeg_roms.py rename to jpegenc/testing/cosim/jpeg_roms.py diff --git a/tests/support/jpeg_v1_intf.py b/jpegenc/testing/cosim/jpeg_v1_intf.py similarity index 100% rename from tests/support/jpeg_v1_intf.py rename to jpegenc/testing/cosim/jpeg_v1_intf.py diff --git a/tests/support/jpeg_v2_intf.py b/jpegenc/testing/cosim/jpeg_v2_intf.py similarity index 100% rename from tests/support/jpeg_v2_intf.py rename to jpegenc/testing/cosim/jpeg_v2_intf.py diff --git a/tests/support/jpegenc_v1_top.py b/jpegenc/testing/cosim/jpegenc_v1_top.py similarity index 100% rename from tests/support/jpegenc_v1_top.py rename to jpegenc/testing/cosim/jpegenc_v1_top.py diff --git a/tests/support/opb.py b/jpegenc/testing/cosim/opb.py similarity index 100% rename from tests/support/opb.py rename to jpegenc/testing/cosim/opb.py diff --git a/tests/support/signal_queue.py b/jpegenc/testing/cosim/signal_queue.py similarity index 100% rename from tests/support/signal_queue.py rename to jpegenc/testing/cosim/signal_queue.py diff --git a/tests/support/utils.py b/jpegenc/testing/cosim/utils.py similarity index 100% rename from tests/support/utils.py rename to jpegenc/testing/cosim/utils.py diff --git a/tests/huff_test_inputs.py b/jpegenc/testing/huff_inputs.py similarity index 91% rename from tests/huff_test_inputs.py rename to jpegenc/testing/huff_inputs.py index 3539dd9..5dd3d90 100644 --- a/tests/huff_test_inputs.py +++ b/jpegenc/testing/huff_inputs.py @@ -1,3 +1,8 @@ + +# @todo: How were these generated ??? Create a github issue +# How were these test inputs generated. These should be replaced with a +# model/function/object that generates the inputs instead of static inputs + vli_test_y = [ 10, 1, 2, 4, 8, 16, 32, 65, 128, 256, 1000, 1, 2, 4, 8, 16, diff --git a/jpegenc/testing/quant_inputs.py b/jpegenc/testing/quant_inputs.py new file mode 100644 index 0000000..612bb73 --- /dev/null +++ b/jpegenc/testing/quant_inputs.py @@ -0,0 +1,35 @@ + +# @todo: How were these generated ??? Create a github issue +# How were these test inputs generated. These should be replaced with a +# model/function/object that generates the inputs instead of static inputs + +quant_rom = [ + 16, 11, 10, 16, 24, 40, 51, 61, + 12, 12, 14, 19, 26, 58, 60, 55, + 14, 13, 16, 24, 40, 57, 69, 56, + 14, 17, 22, 29, 51, 87, 80, 62, + 18, 22, 37, 56, 68, 109, 103, 77, + 24, 35, 55, 64, 81, 104, 113, 92, + 49, 64, 78, 87, 103, 121, 120, 101, + 72, 92, 95, 98, 112, 100, 103, 99, + + 17, 18, 24, 47, 99, 99, 99, 99, + 18, 21, 26, 66, 99, 99, 99, 99, + 24, 26, 56, 99, 99, 99, 99, 99, + 47, 66, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99 +] + +quant_in = [ + 10, 1000, 2047, 3, 4, 5, 6, 7, + -1, -2, -3, -4, -5, -6, -7, -8, + 12, 13, 16, 17, 18, 18, 19, 20, + 111, 112, 113, 114, 115, 116, 117, 190, + 1111, 1112, 1113, 1212, 1232, 1214, 1542, 1432, + 999, -999, -1221, -1232, -12, -298, -123, 123, + -111, -112, -113, -114, -115, -116, -117, -190, + -12, -13, -16, -17, -18, -18, -19, -2048 +] diff --git a/tests/rle_test_inputs.py b/jpegenc/testing/rle_inputs.py similarity index 89% rename from tests/rle_test_inputs.py rename to jpegenc/testing/rle_inputs.py index 1877003..69f61ff 100755 --- a/tests/rle_test_inputs.py +++ b/jpegenc/testing/rle_inputs.py @@ -1,3 +1,9 @@ + +# @todo: How were these generated ??? Create a github issue +# How were these test inputs generated. These should be replaced with a +# model/function/object that generates the inputs instead of static inputs + + red_pixels_1 = [ 1, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, diff --git a/tests/quant_test_inputs.py b/tests/quant_test_inputs.py deleted file mode 100644 index 8bf1b9c..0000000 --- a/tests/quant_test_inputs.py +++ /dev/null @@ -1,29 +0,0 @@ -quant_rom = [ -16, 11, 10, 16, 24, 40, 51, 61, -12, 12, 14, 19, 26, 58, 60, 55, -14, 13, 16, 24, 40, 57, 69, 56, -14, 17, 22, 29, 51, 87, 80, 62, -18, 22, 37, 56, 68, 109, 103, 77, -24, 35, 55, 64, 81, 104, 113, 92, -49, 64, 78, 87, 103, 121, 120, 101, -72, 92, 95, 98, 112, 100, 103, 99, - -17, 18, 24, 47, 99, 99, 99, 99, -18, 21, 26, 66, 99, 99, 99, 99, -24, 26, 56, 99, 99, 99, 99, 99, -47, 66, 99, 99, 99, 99, 99, 99, -99, 99, 99, 99, 99, 99, 99, 99, -99, 99, 99, 99, 99, 99, 99, 99, -99, 99, 99, 99, 99, 99, 99, 99, -99, 99, 99, 99, 99, 99, 99, 99 -] - -quant_in = [10, 1000, 2047, 3, 4, 5, 6, 7, --1, -2, -3, -4, -5, -6, -7, -8, -12, 13, 16, 17, 18, 18, 19, 20, -111, 112, 113, 114, 115, 116, 117, 190, -1111, 1112, 1113, 1212, 1232, 1214, 1542, 1432, -999, -999, -1221, -1232, -12, -298, -123, 123, --111, -112, -113, -114, -115, -116, -117, -190, --12, -13, -16, -17, -18, -18, -19, -2048 -] diff --git a/tests/test_huffman.py b/tests/test_huffman.py index 644c2b4..41b57e2 100644 --- a/tests/test_huffman.py +++ b/tests/test_huffman.py @@ -1,5 +1,6 @@ -"""The functionality of entire - Run Length Encoder is checked here""" +""" +The functionality of entire Run Length Encoder is checked here +""" from myhdl import StopSimulation from myhdl import block @@ -15,11 +16,12 @@ from jpegenc.testing import run_testbench from jpegenc.subblocks.rle import Component +from jpegenc.testing import huff_inputs -from huff_test_inputs import (vli_test_y, vli_size_test_y, runlength_test_y, - vli_test_cb, vli_size_test_cb, - runlength_test_cb, vli_test_cr, - vli_size_test_cr, runlength_test_cr,) +# from huff_test_inputs import (vli_test_y, vli_size_test_y, runlength_test_y, +# vli_test_cb, vli_size_test_cb, +# runlength_test_cb, vli_test_cr, +# vli_size_test_cr, runlength_test_cr,) def write_block( @@ -147,41 +149,47 @@ def tbstim(): bufferdatabus.buffer_sel.next = False # send y1 component into the module color = component.y1_space - yield write_block(huffmandatastream, huffmancntrl, rle_fifo_empty, - color, vli_test_y, runlength_test_y, - vli_size_test_y, clock) - print ("=======================================") + yield write_block( + huffmandatastream, huffmancntrl, rle_fifo_empty, + color, huff_inputs.vli_test_y, huff_inputs.runlength_test_y, + huff_inputs.vli_size_test_y, clock + ) + print("=======================================") # read y1 component from the double FIFO bufferdatabus.buffer_sel.next = True yield read_block(bufferdatabus, clock) - print ("==============================") + print("==============================") # send cb component into the module color = component.cb_space - yield write_block(huffmandatastream, huffmancntrl, rle_fifo_empty, - color, vli_test_cb, runlength_test_cb, - vli_size_test_cb, clock) - print ("==========================================") + yield write_block( + huffmandatastream, huffmancntrl, rle_fifo_empty, + color, huff_inputs.vli_test_cb, huff_inputs.runlength_test_cb, + huff_inputs.vli_size_test_cb, clock + ) + print("==========================================") # read cb component from the double FIFO bufferdatabus.buffer_sel.next = False yield clock.posedge yield read_block(bufferdatabus, clock) - print ("==============================") + print("==============================") # send cr component into the module color = component.cr_space - yield write_block(huffmandatastream, huffmancntrl, rle_fifo_empty, - color, vli_test_cr, runlength_test_cr, - vli_size_test_cr, clock) - print ("============================") + yield write_block( + huffmandatastream, huffmancntrl, rle_fifo_empty, + color, huff_inputs.vli_test_cr, huff_inputs.runlength_test_cr, + huff_inputs.vli_size_test_cr, clock + ) + print("============================") # read cr component from the double FIFO bufferdatabus.buffer_sel.next = True yield clock.posedge yield read_block(bufferdatabus, clock) - print ("==============================") + print("==============================") yield toggle_signal(huffmancntrl.sof, clock) diff --git a/tests/test_quantizer.py b/tests/test_quantizer.py index b475d62..82967ec 100644 --- a/tests/test_quantizer.py +++ b/tests/test_quantizer.py @@ -1,5 +1,6 @@ -"""This module is the testbench for - the Quantizer top module""" +""" +This module is the testbench for the Quantizer top module +""" from myhdl import block, instance from myhdl import ResetSignal, Signal, StopSimulation @@ -14,8 +15,7 @@ pulse_reset, toggle_signal,) from jpegenc.testing import run_testbench - -from quant_test_inputs import quant_rom, quant_in +from jpegenc.testing import quant_inputs def quant_top_block_process( @@ -57,18 +57,18 @@ def quant_top_block_process( for i in range(max_addr): output_interface.addr.next = i if i >= 2: - print (" output data is %d" % (output_interface.data)) - #assert list_ouput_ref.pop(0) == output_interface.data + print(" output data is %d" % (output_interface.data,)) + # assert list_ouput_ref.pop(0) == output_interface.data yield clock.posedge # print left outputs - print (" output data is %d" % (output_interface.data)) - #assert list_ouput_ref.pop(0) == output_interface.data + print(" output data is %d" % (output_interface.data,)) + # assert list_ouput_ref.pop(0) == output_interface.data yield clock.posedge # print left outputs - print (" output data is %d" % (output_interface.data)) - #assert list_ouput_ref.pop(0) == output_interface.data + print(" output data is %d" % (output_interface.data,)) + # assert list_ouput_ref.pop(0) == output_interface.data def test_quantizer(): @@ -120,18 +120,20 @@ def tbstim(): # process Cb or Cr component yield quant_top_block_process( - clock, quant_ctrl, color, quanto_datastream, - quanti_datastream, quant_in, quant_rom, max_addr, 1) + clock, quant_ctrl, color, quanto_datastream, quanti_datastream, + quant_inputs.quant_in, quant_inputs.quant_rom, max_addr, 1 + ) - print ("===============================================") + print("===============================================") # select Y1 or Y2 component color = component.cr_space # process Cb or Cr component yield quant_top_block_process( - clock, quant_ctrl, color, quanto_datastream, - quanti_datastream, quant_in, quant_rom, max_addr, 1) + clock, quant_ctrl, color, quanto_datastream, quanti_datastream, + quant_inputs.quant_in, quant_inputs.quant_rom, max_addr, 1 + ) raise StopSimulation @@ -178,7 +180,7 @@ def bench_quant_top_core(): def tbstim(): """dummy tests to convert the module""" yield clock.posedge - print ("Conversion done!!") + print("Conversion done!!") raise StopSimulation return tbstim, inst, inst_clock, inst_reset diff --git a/tests/test_quantizer_core.py b/tests/test_quantizer_core.py index 22cf0c0..57195d0 100644 --- a/tests/test_quantizer_core.py +++ b/tests/test_quantizer_core.py @@ -1,5 +1,6 @@ -"""This module is the testbench for the - divider used in quantizer core module""" +""" +This module is the testbench for the divider used in quantizer core module +""" from myhdl import block, instance, StopSimulation from myhdl import intbv, ResetSignal, Signal @@ -14,8 +15,7 @@ pulse_reset,) from jpegenc.testing import run_testbench - -from quant_test_inputs import quant_rom, quant_in +from jpegenc.testing import quant_inputs def quant_block_process( @@ -53,7 +53,7 @@ def quant_block_process( input_interface.valid.next = False # print the outputs if output_interface.valid: - print ("output is %d" % output_interface.data) + print("output is %d" % output_interface.data) assert list_ouput_ref.pop(0) == output_interface.data # de-assert data_valid signal @@ -63,7 +63,7 @@ def quant_block_process( # print some more outputs for i in range(5): if output_interface.valid: - print ("output is %d" % output_interface.data) + print("output is %d" % output_interface.data) assert list_ouput_ref.pop(0) == output_interface.data yield clock.posedge @@ -118,19 +118,23 @@ def tbstim(): # process the component selected yield quant_block_process( - clock, color_component, color, quant_in, quant_rom, - quant_input_stream, quant_output_stream, max_addr) + clock, color_component, color, + quant_inputs.quant_in, quant_inputs.quant_rom, + quant_input_stream, quant_output_stream, max_addr + ) yield clock.posedge - print ("====================================") + print("====================================") # select Y1 or Y2 component color = component.cb_space # process the component selected yield quant_block_process( - clock, color_component, color, quant_in, quant_rom, - quant_input_stream, quant_output_stream, max_addr) + clock, color_component, color, + quant_inputs.quant_in, quant_inputs.quant_rom, + quant_input_stream, quant_output_stream, max_addr + ) yield clock.posedge raise StopSimulation @@ -173,7 +177,7 @@ def bench_quant_core(): def tbstim(): """dummy tests to convert the module""" yield clock.posedge - print ("Conversion done!!") + print("Conversion done!!") raise StopSimulation return tbstim, inst, inst_clock, inst_reset diff --git a/tests/test_ref_designs.py b/tests/test_ref_designs.py index b39acb8..883829d 100644 --- a/tests/test_ref_designs.py +++ b/tests/test_ref_designs.py @@ -12,9 +12,8 @@ from myhdl import * # local test support package -from support import (prep_cosim, JPEGEncV1, JPEGEncV2, - set_default_args, get_cli_args) - +from jpegenc.testing.cosim import (prep_cosim, JPEGEncV1, JPEGEncV2, + set_default_args, get_cli_args) from jpegenc.testing import skip_ref_test diff --git a/tests/test_ref_mdct.py b/tests/test_ref_mdct.py index ce3ac6d..e578b8f 100644 --- a/tests/test_ref_mdct.py +++ b/tests/test_ref_mdct.py @@ -9,7 +9,7 @@ StopSimulation) from jpegenc.testing import skip_ref_test -from support import get_cli_args +from jpegenc.testing.cosim import get_cli_args class DataBus(object): diff --git a/tests/test_rle.py b/tests/test_rle.py index 16d670c..5e98c95 100755 --- a/tests/test_rle.py +++ b/tests/test_rle.py @@ -1,5 +1,6 @@ -"""The functionality of entire - Run Length Encoder is checked here""" +""" +The functionality of entire Run Length Encoder is checked here +""" from myhdl import StopSimulation from myhdl import block @@ -13,9 +14,7 @@ pulse_reset, toggle_signal,) from jpegenc.testing import run_testbench - -from rle_test_inputs import (red_pixels_1, green_pixels_1, blue_pixels_1, - red_pixels_2, green_pixels_2, blue_pixels_2,) +from jpegenc.testing import rle_inputs def write_block( @@ -57,7 +56,7 @@ def read_block(select, output_interface, clock): # pop data out into the bus until fifo becomes empty while not output_interface.fifo_empty: - print ("runlength %d size %d amplitude %d" % ( + print("runlength %d size %d amplitude %d" % ( output_interface.runlength, output_interface.size, output_interface.amplitude)) yield clock.posedge @@ -121,78 +120,78 @@ def tbstim(): yield clock.posedge yield write_block( - clock, red_pixels_1, + clock, rle_inputs.red_pixels_1, datastream, rleconfig, component.y1_space ) yield clock.posedge - print ("============================") + print("============================") # read y1 component from 1st Buffer yield read_block(True, bufferdatabus, clock) # write y2 component into 2nd Buffer yield write_block( - clock, red_pixels_2, + clock, rle_inputs.red_pixels_2, datastream, rleconfig, component.y2_space ) yield clock.posedge - print ("============================") + print("============================") # read y2 component from 2nd Buffer yield read_block(False, bufferdatabus, clock) # write cb Component into 1st Buffer yield write_block( - clock, green_pixels_1, + clock, rle_inputs.green_pixels_1, datastream, rleconfig, component.cb_space ) yield clock.posedge - print ("=============================") + print("=============================") # read cb component from 1st Buffer yield read_block(True, bufferdatabus, clock) # write cb Component into 2nd Buffer yield write_block( - clock, green_pixels_2, + clock, rle_inputs.green_pixels_2, datastream, rleconfig, component.cb_space ) yield clock.posedge - print ("==============================") + print("==============================") # read cb component from 2nd Buffer yield read_block(False, bufferdatabus, clock) # write cr Component into 1st Buffer yield write_block( - clock, blue_pixels_1, + clock, rle_inputs.blue_pixels_1, datastream, rleconfig, component.cr_space ) yield clock.posedge - print ("==============================") + print("==============================") # read cr component from 1st Buffer yield read_block(True, bufferdatabus, clock) # write cr Component into 2nd Buffer yield write_block( - clock, blue_pixels_2, + clock, rle_inputs.blue_pixels_2, datastream, rleconfig, component.cr_space ) yield clock.posedge - print ("==============================") + print("==============================") # read cr component from 1st Buffer yield read_block(False, bufferdatabus, clock) - print ("==============================") + print("==============================") # end of stream when sof asserts yield clock.posedge diff --git a/tests/test_rlecore.py b/tests/test_rle_core.py similarity index 91% rename from tests/test_rlecore.py rename to tests/test_rle_core.py index c213f61..c47696b 100755 --- a/tests/test_rlecore.py +++ b/tests/test_rle_core.py @@ -11,9 +11,7 @@ from jpegenc.testing import run_testbench from jpegenc.testing import (toggle_signal, clock_driver, reset_on_start, pulse_reset) - -from rle_test_inputs import (red_pixels_1, green_pixels_1, blue_pixels_1, - red_pixels_2, green_pixels_2, blue_pixels_2,) +from jpegenc.testing import rle_inputs def block_process( @@ -111,7 +109,7 @@ def test_rle_core(): width_size = width_data.bit_length() # maximum counter value - max_addr_cnt = (2**(width_addr)) - 1 + max_addr_cnt = (2**width_addr) - 1 # maximum width of the runlength value width_runlength = 4 @@ -149,63 +147,63 @@ def tbstim(): # components of type y1 or y2 processed yield block_process( - clock, red_pixels_1, + clock, rle_inputs.red_pixels_1, datastream, rlesymbols, rleconfig, component.y1_space, max_count=max_addr_cnt ) - print ("======================") + print("======================") # components of type y1 or y2 processed yield block_process( - clock, red_pixels_2, + clock, rle_inputs.red_pixels_2, datastream, rlesymbols, rleconfig, component.y2_space, max_count=max_addr_cnt ) - print ("=====================") + print("=====================") # components of type cb processes yield block_process( - clock, green_pixels_1, + clock, rle_inputs.green_pixels_1, datastream, rlesymbols, rleconfig, component.cb_space, max_count=max_addr_cnt ) - print ("=====================") + print("=====================") # components od type cb processed yield block_process( - clock, green_pixels_2, + clock, rle_inputs.green_pixels_2, datastream, rlesymbols, rleconfig, component.cb_space, max_count=max_addr_cnt ) - print ("=====================") + print("=====================") # components of type cr processed yield block_process( - clock, blue_pixels_1, + clock, rle_inputs.blue_pixels_1, datastream, rlesymbols, rleconfig, component.cr_space, max_count=max_addr_cnt ) - print ("=====================") + print("=====================") # components of type cr processed yield block_process( - clock, blue_pixels_2, + clock, rle_inputs.blue_pixels_2, datastream, rlesymbols, rleconfig, component.cr_space, max_count=max_addr_cnt ) - print ("=====================") + print("=====================") # start of new frame asserts rleconfig.sof.next = True From c2f89ee5c3cd644e3028abc6dd846dc8b3b1d1b6 Mon Sep 17 00:00:00 2001 From: Christopher Felton Date: Sat, 8 Oct 2016 14:52:46 -0500 Subject: [PATCH 12/32] fixed incorrect attr name --- tests/test_models/test_single_processing_subblock.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_models/test_single_processing_subblock.py b/tests/test_models/test_single_processing_subblock.py index 7d7a50a..e2f7809 100644 --- a/tests/test_models/test_single_processing_subblock.py +++ b/tests/test_models/test_single_processing_subblock.py @@ -37,9 +37,9 @@ def bench(): vd_proc = video_source.process(glbl) # processing element that does nothing :) - data = DataStream(data_width=len(video_source.pixels.data)) + data = DataStream(data_width=len(video_source.pixel.data)) pe = ProcessingSubblock(cycles_to_process=1) - pe_proc = pe.process(glbl, video_source.pixels, data) + pe_proc = pe.process(glbl, video_source.pixel, data) # collect the output and compare if the video_source supports # checking, use an encoder (decode portion) if one exists From a145f3ea1223111bac0fde3f876def720fdb1574 Mon Sep 17 00:00:00 2001 From: Christopher Felton Date: Wed, 19 Oct 2016 18:00:45 -0500 Subject: [PATCH 13/32] checkpoint / sync --- README.md | 86 +++++++++++++++++++--------- jpegenc/models/video/video_source.py | 6 ++ 2 files changed, 64 insertions(+), 28 deletions(-) diff --git a/README.md b/README.md index ae77835..a7b2e17 100644 --- a/README.md +++ b/README.md @@ -17,15 +17,18 @@ During the summer of 2016 two students participated in [MyHDL's GSoC](http://dev.myhdl.org/gsoc/gsoc_2016.html). The students worked on implementing the various JPEG Encoder subblocks in MyHDL. The sublocks were broken into frontend and backend. -Their blogs, [the frontend](https://myhdlgsoc2016.blogspot.gr/) and -[the backend](https://vikram9866.wordpress.com/), outline their +The student's blogs for +[the frontend](https://myhdlgsoc2016.blogspot.gr/) +and +[the backend](https://vikram9866.wordpress.com/), +outline their work over the summer. The [latest documentation is available on readthedocs](http://jpegenc.readthedocs.io/en/latest/) The primary goal of this repository is to have a working JPEG -Encoder implemented in MyHDL. But not simply implemented in -MyHDL but also utilizing methodologies such as a focus on -clean and reusable block-to-block interfaces and a full +Encoder (`jpegenc`) implemented in MyHDL. But not simply +implemented in MyHDL but also utilizing methodologies such as +a focus on clean and reusable block-to-block interfaces and a full regression test suite. This repository is a development sandbox. The repository @@ -36,17 +39,36 @@ contains three related development efforts: 2. MyHDL verification and co-simulation environment, tests will functionally verify and compare the reference JPEG-Encoders. -The JPEG encoders used are the cores available at open-cores in -addition to JPEG encoders being developed. This is a WIP and not -fully complete (yet). +The reference JPEG encoders are the cores available at open-cores. + +This is a WIP and not fully complete (yet). Quick start guide ================= +Get the latest `jpegenc` package from the `test_jpeg` repository. + +>> git clone https://github.com/cfelton/test_jpeg + +Create a [virtualenv](https://www.davidfischer.name/2010/04/why-you-should-be-using-pip-and-virtualenv/) +to test the `jpegenc` package. + +>> virtualenv --no-site-packages env/test_jpeg +>> source env/test_jpeg/bin/activate + +Install the required packages. +>> pip install -r requirements.txt -Verification Environment +Run the test suite. + +>> cd tests +>> py.test + + + +Verification environment ======================== A stimulus and verification environment was created with Python and MyHDL. An image is streamed to the encoder and the output is captured. @@ -57,24 +79,28 @@ In the future the output of the various encoders will be compared to each other as well as the encoder performance (.e.g. max fps). -JPEG Encoders -============= +Cosimulation +============ +This repository also contains a cosimulation interface to two +reference designs. - - hdl/jpegenc_v1: [VHDL JPEG encoder](http://opencores.org/project,mkjpeg) converted to Verilog - - hdl/jpegenc_v2: [OC Verilog JPEG](http://opencores.org/project,jpegencode) encoder. - - jpegenc: A fresh (non-ported) MyHDL implementation, `jpegenc` is a Python package - being developed. - +Reference JPEG encoders +----------------------- + - tests/reference_designs/jpegenc_v1: [VHDL JPEG encoder](http://opencores.org/project,mkjpeg) + converted to Verilog + - tests/reference_designs/jpegenc_v2: [OC Verilog JPEG](http://opencores.org/project,jpegencode) + encoder. + -Getting Started -=============== -To run the test the following needs to be installed: +Getting started with cosim +-------------------------- +To run the cosim tests the following needs to be installed: * Icarus Verilog - * Python (currently using 2.7) - * MyHDL + * Python (currently using 3.5) + * MyHDL (1.0dev) * Python Imaging Library (e.g. pip install Pillow) @@ -84,15 +110,15 @@ directory. ``` >> cd myhdl/cosimulation/icarus >> make ->> cp myhdl.vpi /test_jpeg/test +>> cp myhdl.vpi /test_jpeg/tests ``` -Once the tools and installed and the VPI module built the test can +Once the tools are installed and the VPI module built the tests can be run. ``` >> cd test ->> python test_jpecenc.py +>> py.test test_jpecenc.py ``` Depending on the test file the test can take significant time to run. @@ -166,20 +192,24 @@ and fast ... correct? Progress Log ============== - **28-Dec-2014** : Conversion error was found in V1, V1 finishes + **09-Oct-2016**: A version of the JPEG encoder has been + implemented in MyHDL. This was completed by two students + during GSoC 2016. + + **28-Dec-2014**: Conversion error was found in V1, V1 finishes compressing the frame. V2 has error with small images, this might be a design limitation. - **07-Dec-2014** : Neither encoder completes successfully with a + **07-Dec-2014**: Neither encoder completes successfully with a small test image, currently debugging (design1 (v1) conversion complete need to find any errors in conversion). The test environment will stream the image in and complete shortly after the image has been streamed in. - **05-Dec-2014** : Design1 conversion to verilog is mostly complete, + **05-Dec-2014**: Design1 conversion to verilog is mostly complete, spending some time verifying. - **09-Nov-2014** : The test environment will stream an image to both + **09-Nov-2014**: The test environment will stream an image to both the design1 and design2 encoders. The output is not interrogated (yet). Design1 conversion to verilog is incomplete. diff --git a/jpegenc/models/video/video_source.py b/jpegenc/models/video/video_source.py index f68af22..6019067 100644 --- a/jpegenc/models/video/video_source.py +++ b/jpegenc/models/video/video_source.py @@ -113,6 +113,12 @@ def model_video_source(): return myhdl.instances() def pixel_value(self, row, col): + """Get the pixel value for the video source. + Given the ``row`` and ``col`` address return the RGB value + for the pixel. The default is to return a random value + (will not be consistent across calls). This method should + be implemented (overridden) for each video source type. + """ self.pixel.red.next = r = randint(0, self.pixel.red.max - 1) self.pixel.green.next = g = randint(0, self.pixel.green.max - 1) self.pixel.blue.next = b = randint(0, self.pixel.blue.max - 1) From 81dcac3411417a6381b4b204300c0de71d3ea8cd Mon Sep 17 00:00:00 2001 From: Christopher Felton Date: Thu, 20 Oct 2016 09:13:56 -0500 Subject: [PATCH 14/32] Added tests for processing subblocks (pe). This commit contains the addition of general processing element models (ProcessingSubblock). This commit also has some other minor changes made during test creation. --- jpegenc/models/processing.py | 40 ++++-------- jpegenc/models/video/bitstream.py | 5 ++ tests/Makefile | 2 +- tests/setup.cfg | 2 +- tests/test_models/test_001_cb.py | 0 tests/test_models/test_002_bd.py | 0 ...processing_subblock.py => test_003_psb.py} | 16 +++-- tests/test_models/test_004_psb.py | 62 +++++++++++++++++++ 8 files changed, 93 insertions(+), 34 deletions(-) create mode 100644 tests/test_models/test_001_cb.py create mode 100644 tests/test_models/test_002_bd.py rename tests/test_models/{test_single_processing_subblock.py => test_003_psb.py} (79%) create mode 100644 tests/test_models/test_004_psb.py diff --git a/jpegenc/models/processing.py b/jpegenc/models/processing.py index 5b6599d..a18936b 100644 --- a/jpegenc/models/processing.py +++ b/jpegenc/models/processing.py @@ -15,42 +15,28 @@ def __init__(self, cycles_to_process=1, block_size=None, buffered=False): """A simple model to represent a processing subblock in the jpegenc Arguments: - cycles_to_process: the number of cycles to model, this is the - number of cycles to process a sample/block. If - `cycles_to_process` is a 2-element tuple a random range is - used with the tuple defining the range. - - @todo: latency is the same (essentially) as cycles_to_process, need - some other argument to indicated successive output gaps, - no gap fully pipelined (latency == ctp) if gap == ctp not - pipelined and stalls in between, the same for sample or - block processing. - ~~latency: the latency of the processing, this is additional to - the processing time, but the latency represents a pipeline, - new samples can. If `latency` is a 2-element tuple a random - range is used with the tuple defining the range.~~ - - pipelined: indicates the procesing block is fully pipelined, a - new sample can be input on every clock. The pipeline length - is the ``cycles_to_process``. - - block_size: the size of an image block, if None process + cycles_to_process (int): the number of cycles to model, + this is the number of cycles to process a sample/block. + + pipelined (bool): indicates the processing block is fully + pipelined, a new sample can be input on every clock. + The pipeline length is the ``cycles_to_process``. + + block_size (tuple): the size of an image block, if None process sample by sample. - buffered + buffered (bool): + + The processing element class is named ProcessingSubblock and `psb` + and `pe` will be used as shorthand in various spots. """ - assert isinstance(cycles_to_process, (int, tuple)) - if isinstance(cycles_to_process, tuple): - assert len(cycles_to_process) == 2 - # assert isinstance(latency, int) - # assert isinstance(process_block, bool) + assert isinstance(cycles_to_process, int) if block_size is not None: assert isinstance(block_size, tuple) and len(block_size) == 2 assert isinstance(buffered, bool) # the cycles to process is the same as latency self.ctp = cycles_to_process - # self.lat = latency self.block_size = block_size self.buffered = buffered diff --git a/jpegenc/models/video/bitstream.py b/jpegenc/models/video/bitstream.py index 5b294aa..739cb5a 100644 --- a/jpegenc/models/video/bitstream.py +++ b/jpegenc/models/video/bitstream.py @@ -13,6 +13,9 @@ def __init__(self, source, encoder=None): self.resolution = source.resolution self.encoder = encoder + # keep track of the data words captured + self.num_data = 0 + @myhdl.block def process(self, glbl, data): """ @@ -25,6 +28,7 @@ def process(self, glbl, data): assert isinstance(data, DataStream) clock, reset = glbl.clock, glbl.reset src = self.source + self.num_data = 0 @instance def mdl_simple_capture(): @@ -35,6 +39,7 @@ def mdl_simple_capture(): yield clock.posedge if src.pixel.valid: print(" [BD]: {:03X}".format(src.pixel.data)) + self.num_data += 1 return myhdl.instances() diff --git a/tests/Makefile b/tests/Makefile index 7c5cb7f..e7cc13e 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -1,6 +1,6 @@ # invoke the test with the python -# nosetests --verbosity=2 --with-converage +# nosetests --verbosity=2 --with-coverage all: python test_jpegenc.py diff --git a/tests/setup.cfg b/tests/setup.cfg index 2eb845e..2bdf212 100644 --- a/tests/setup.cfg +++ b/tests/setup.cfg @@ -4,5 +4,5 @@ nocapture=True nologcapture=True with-coverage=True -[pytest] +[tool:pytest] norecursedirs = reference_designs diff --git a/tests/test_models/test_001_cb.py b/tests/test_models/test_001_cb.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/test_models/test_002_bd.py b/tests/test_models/test_002_bd.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/test_models/test_single_processing_subblock.py b/tests/test_models/test_003_psb.py similarity index 79% rename from tests/test_models/test_single_processing_subblock.py rename to tests/test_models/test_003_psb.py index e2f7809..7d4068e 100644 --- a/tests/test_models/test_single_processing_subblock.py +++ b/tests/test_models/test_003_psb.py @@ -11,7 +11,7 @@ from jpegenc.testing import run_testbench -def test_single_pb(): +def test_single_psb(): """Test a single processing subblock This test will verify the basic building blocks to model and prototype @@ -32,8 +32,10 @@ def bench(): ck_drv = clock.gen() # a known generated video stream - video_source = ColorBars(resolution=resolution, color_depth=color_depth, - frame_rate=frame_rate) + video_source = ColorBars( + resolution=resolution, color_depth=color_depth, + frame_rate=frame_rate + ) vd_proc = video_source.process(glbl) # processing element that does nothing :) @@ -48,10 +50,14 @@ def bench(): @instance def tbstim(): - yield delay(1000) + tcnt, timeout = 0, 10 + while video_sink.num_data < 5 and tcnt < timeout: + yield delay(1000) + tcnt += 1 + assert tcnt < timeout raise StopSimulation return myhdl.instances() - run_testbench(bench, trace=True, bench_id="single_process_subblock") + run_testbench(bench, trace=True, bench_id="single_pe") diff --git a/tests/test_models/test_004_psb.py b/tests/test_models/test_004_psb.py new file mode 100644 index 0000000..a7f65c6 --- /dev/null +++ b/tests/test_models/test_004_psb.py @@ -0,0 +1,62 @@ + +import myhdl +from myhdl import instance, delay, StopSimulation +from rhea import Global, Clock + +from jpegenc.models import DataStream +from jpegenc.models import ProcessingSubblock +from jpegenc.models.video import ColorBars +from jpegenc.models.video import BitstreamDevourer + +from jpegenc.testing import run_testbench + + +def test_psb_basic(): + """Test a small chain of processing blocks with default config. + """ + resolution = (1920, 1080) + frame_rate = 60 + color_depth = (8, 8, 8) + + @myhdl.block + def bench(): + clock = Clock(0, frequency=125e6) + glbl = Global(clock) + ck_drv = clock.gen() + + # a known generated video stream + video_source = ColorBars( + resolution=resolution, color_depth=color_depth, + frame_rate=frame_rate + ) + vd_proc = video_source.process(glbl) + + dw = len(video_source.pixel.data) + pe_procs = [] + for ii in range(13): + data_i = data_o if ii > 0 else video_source.pixel + data_o = DataStream(data_width=dw) + + pe = ProcessingSubblock(cycles_to_process=24) + pe_procs += [pe.process(glbl, data_i, data_o)] + + video_sink = BitstreamDevourer(video_source, encoder=None) + vk_proc = video_sink.process(glbl, data_o) + + @instance + def tbstim(): + while video_sink.num_data < 32: + yield delay(1000) + raise StopSimulation + + return myhdl.instances() + + run_testbench(bench, trace=True, bench_id="psb_basic") + + +def test_psb_buffered(): + pass + + +def test_psb_block(): + pass \ No newline at end of file From e57158ba28e62fc1f418650ae88e2a4d20aa3a97 Mon Sep 17 00:00:00 2001 From: Christopher Felton Date: Thu, 20 Oct 2016 11:08:11 -0500 Subject: [PATCH 15/32] Added tests for the source and sink models. --- jpegenc/models/interfaces.py | 8 ++- jpegenc/models/processing.py | 5 +- jpegenc/models/video/bitstream.py | 38 +++++++++----- jpegenc/models/video/colorbars.py | 4 +- jpegenc/models/video/video_source.py | 11 ++-- tests/test_models/test_001_cb.py | 50 +++++++++++++++++++ tests/test_models/test_002_bd.py | 50 +++++++++++++++++++ .../{test_003_psb.py => test_003_pe.py} | 2 +- .../{test_004_psb.py => test_004_pe.py} | 3 +- 9 files changed, 149 insertions(+), 22 deletions(-) rename tests/test_models/{test_003_psb.py => test_003_pe.py} (96%) rename tests/test_models/{test_004_psb.py => test_004_pe.py} (96%) diff --git a/jpegenc/models/interfaces.py b/jpegenc/models/interfaces.py index 76df02d..87db267 100644 --- a/jpegenc/models/interfaces.py +++ b/jpegenc/models/interfaces.py @@ -37,6 +37,13 @@ def assign(self, stream): self.data.next = stream.data self.valid.next = stream.valid + def __copy__(self): + ds = DataStream(data_width=len(self.data)) + return ds + + def copy(self): + return self.__copy__() + class PixelStream(DataStream): def __init__(self, data_width=24): @@ -72,7 +79,6 @@ def __init__(self, color_depth=(8, 8, 8), num_pixels=1): self.color_depth = color_depth rbits, gbits, bbits = color_depth - print(vars(self)) # a single pixel (color component) is the most if num_pixels == 1: diff --git a/jpegenc/models/processing.py b/jpegenc/models/processing.py index a18936b..ceae44b 100644 --- a/jpegenc/models/processing.py +++ b/jpegenc/models/processing.py @@ -54,6 +54,8 @@ def process(self, glbl, datain, dataout): assert isinstance(datain, DataStream) assert isinstance(dataout, DataStream) + assert len(datain.data) == len(dataout.data) + clock, reset = glbl.clock, glbl.reset ready = Signal(bool(0)) @@ -87,7 +89,8 @@ def beh_ready(): # To make this generic this needs a new (copy) instance # with all the same attributes/properties, the current # only uses the default. - dataproc = type(datain)() + dataproc = datain.copy() + @instance def processing_model(): diff --git a/jpegenc/models/video/bitstream.py b/jpegenc/models/video/bitstream.py index 739cb5a..f9cc734 100644 --- a/jpegenc/models/video/bitstream.py +++ b/jpegenc/models/video/bitstream.py @@ -1,6 +1,7 @@ + import myhdl -from myhdl import instance +from myhdl import Signal, instance from ..interfaces import DataStream from .video_source import VideoSource @@ -8,38 +9,51 @@ class BitstreamDevourer(object): def __init__(self, source, encoder=None): - assert isinstance(source, VideoSource) + """ + + Args: + source (VideoSource): the original video/image source to + compare the decoded bitstream to. + encoder (CODEC): + """ + assert isinstance(source, (VideoSource, type(None))) + self.source = source - self.resolution = source.resolution + if source is not None: + self.resolution = source.resolution self.encoder = encoder + self.bits = None # keep track of the data words captured - self.num_data = 0 + self.num_data_words = Signal(0) @myhdl.block - def process(self, glbl, data): + def process(self, glbl, bits): """ Args: glbl (Global): global interface, contains clock and reset - data (DataStream): final bitstream + bits (DataStream): final bitstream """ - assert isinstance(data, DataStream) + assert isinstance(bits, DataStream) clock, reset = glbl.clock, glbl.reset + self.bits = bits src = self.source - self.num_data = 0 + ndw = self.num_data_words @instance def mdl_simple_capture(): """Temp capture and display""" # ready to receive the data - src.pixel.ready.next = True + bits.ready.next = True + while True: yield clock.posedge - if src.pixel.valid: - print(" [BD]: {:03X}".format(src.pixel.data)) - self.num_data += 1 + if bits.valid: + print(" [BD][{:5d}]: {:06X}".format( + int(ndw), int(bits.data))) + ndw.next = ndw + 1 return myhdl.instances() diff --git a/jpegenc/models/video/colorbars.py b/jpegenc/models/video/colorbars.py index 9b98d98..eba5a79 100644 --- a/jpegenc/models/video/colorbars.py +++ b/jpegenc/models/video/colorbars.py @@ -40,7 +40,7 @@ def __init__(self, resolution=(1920, 1080), color_depth=(8, 8, 8), self.bar_width = int(res[0] // self.num_colors) # create a list to index into - self.color_bars = [vv for vv in COLOR_BARS.values()] + self.color_bars = [vv.copy() for vv in COLOR_BARS.values()] # convert the colors to the color depth rmx, gmx, bmx = [(cc**2)-1 for cc in self.color_depth] @@ -49,7 +49,7 @@ def __init__(self, resolution=(1920, 1080), color_depth=(8, 8, 8), color['green'] = color['green'] * gmx color['blue'] = color['blue'] * gmx - super(ColorBars, self).__init__(resolution, frame_rate) + super(ColorBars, self).__init__(resolution, frame_rate, color_depth) def pixel_value(self, row, col): # the row index is not used/needed for color bars diff --git a/jpegenc/models/video/video_source.py b/jpegenc/models/video/video_source.py index 6019067..3a3bdfc 100644 --- a/jpegenc/models/video/video_source.py +++ b/jpegenc/models/video/video_source.py @@ -9,7 +9,7 @@ class VideoSource(object): - def __init__(self, resolution=(1920, 1080), frame_rate=60): + def __init__(self, resolution=(1920, 1080), frame_rate=60, color_depth=(8, 8, 8)): """A model of a video source This object contains an example of a video source interface and a process to generate the video source. @@ -36,7 +36,7 @@ def __init__(self, resolution=(1920, 1080), frame_rate=60): """ self.resolution = resolution self.frame_rate = frame_rate - self.pixel = RGBStream(color_depth=(8, 8, 8)) + self.pixel = RGBStream(color_depth=color_depth) # signals that monitor the current row and column self.rowmon = Signal(intbv(0, min=0, max=resolution[1])) self.colmon = Signal(intbv(0, min=0, max=resolution[0])) @@ -50,7 +50,9 @@ def __init__(self, resolution=(1920, 1080), frame_rate=60): def get_ticks(self, clock): """Get the number of clock ticks per pixel""" pps = self.pixels_per_second - ticks = int(floor(pps / clock.frequency)) + ticks = int(floor(clock.frequency / pps)) + assert ticks > 0, "clock frequency too low {:.3f} MHz".format( + clock.frequency / 1e6) return ticks @myhdl.block @@ -72,6 +74,7 @@ def process(self, glbl): # note, if the video rate is not a multiple of the clock then # the video rate will not be exact (which is fine) ticks = self.get_ticks(clock) + print("{} clock ticks per pixel".format(ticks)) @instance def model_video_source(): @@ -94,7 +97,7 @@ def model_video_source(): tcnt += 1 # tick count expired, output a new pixel - if tcnt == ticks: + if tcnt >= ticks: if row == 0 and col == 0: self.pixel.start_of_frame.next = True if row == num_rows-1 and col == num_cols-1: diff --git a/tests/test_models/test_001_cb.py b/tests/test_models/test_001_cb.py index e69de29..4e4ee14 100644 --- a/tests/test_models/test_001_cb.py +++ b/tests/test_models/test_001_cb.py @@ -0,0 +1,50 @@ + +import myhdl +from myhdl import instance, StopSimulation +from rhea import Global, Clock + +from jpegenc.models.video import ColorBars +from jpegenc.testing import run_testbench + + +def test_colorbars(): + resolution = (1920, 1080) + frame_rate = 60 + color_depth = (8, 8, 8) + + @myhdl.block + def bench(): + clock = Clock(0, frequency=125e6) + glbl = Global(clock) + ck_drv = clock.gen() + + video_source = ColorBars( + resolution=resolution, color_depth=color_depth, + frame_rate=frame_rate + ) + vd_proc = video_source.process(glbl) + pixel = video_source.pixel + + @instance + def tbstim(): + # only capture a subset of pixels for this test + npx = 128 + pcnt, tcnt, timeout = 0, 0, 4*npx + + # the video source has a pixel interface, indicate to + # the video source downstream is read to get pixels + pixel.ready.next = True + + while pcnt < npx and tcnt < timeout: + yield clock.posedge + tcnt += 1 + if pixel.valid: + pcnt += 1 + + assert pcnt == npx + raise StopSimulation + + return myhdl.instances() + + run_testbench(bench, trace=True, bench_id='colorbars') + diff --git a/tests/test_models/test_002_bd.py b/tests/test_models/test_002_bd.py index e69de29..1d0f137 100644 --- a/tests/test_models/test_002_bd.py +++ b/tests/test_models/test_002_bd.py @@ -0,0 +1,50 @@ + +from random import randint + +import myhdl +from myhdl import instance, delay, StopSimulation +from rhea import Global, Clock + +from jpegenc.models import DataStream +from jpegenc.models.video import BitstreamDevourer +from jpegenc.testing import run_testbench + + +def test_bitstream_devourer(): + + clock = Clock(0, frequency=125e6) + glbl = Global(clock) + data = DataStream(data_width=24) + video_sink = BitstreamDevourer(source=None, encoder=None) + + @myhdl.block + def bench(): + ck_drv = clock.gen() + vk_proc = video_sink.process(glbl, data) + + @instance + def tbstim(): + npx = 23 + tcnt, timeout = 0, 4*npx + vmax = data.data.max-1 + + for _ in range(4): + yield clock.posedge + + while video_sink.num_data_words < npx-1 and tcnt < timeout: + data.valid.next = True + data.data.next = randint(0, vmax) + yield clock.posedge + tcnt += 1 + data.valid.next = False + yield clock.posedge + yield delay(1000) + + nw = video_sink.num_data_words + assert nw == npx, "{} != {}, in {} cycles".format(nw, npx, tcnt) + raise StopSimulation + + return myhdl.instances() + + run_testbench(bench, trace=True, bench_id='devourbits') + diff --git a/tests/test_models/test_003_psb.py b/tests/test_models/test_003_pe.py similarity index 96% rename from tests/test_models/test_003_psb.py rename to tests/test_models/test_003_pe.py index 7d4068e..4fc8d4b 100644 --- a/tests/test_models/test_003_psb.py +++ b/tests/test_models/test_003_pe.py @@ -51,7 +51,7 @@ def bench(): @instance def tbstim(): tcnt, timeout = 0, 10 - while video_sink.num_data < 5 and tcnt < timeout: + while video_sink.num_data_words < 5 and tcnt < timeout: yield delay(1000) tcnt += 1 assert tcnt < timeout diff --git a/tests/test_models/test_004_psb.py b/tests/test_models/test_004_pe.py similarity index 96% rename from tests/test_models/test_004_psb.py rename to tests/test_models/test_004_pe.py index a7f65c6..edfd716 100644 --- a/tests/test_models/test_004_psb.py +++ b/tests/test_models/test_004_pe.py @@ -33,6 +33,7 @@ def bench(): dw = len(video_source.pixel.data) pe_procs = [] + for ii in range(13): data_i = data_o if ii > 0 else video_source.pixel data_o = DataStream(data_width=dw) @@ -45,7 +46,7 @@ def bench(): @instance def tbstim(): - while video_sink.num_data < 32: + while video_sink.num_data_words < 32: yield delay(1000) raise StopSimulation From c42cf8ab4e95c24d22f6233b5e3ae25227540ab8 Mon Sep 17 00:00:00 2001 From: Christopher Felton Date: Thu, 20 Oct 2016 11:34:20 -0500 Subject: [PATCH 16/32] reverted to the old pytest setup.cfg --- jpegenc/models/processing.py | 2 +- .../jpegenc_v2/myhdl/test/test_dct1sinpout.py | 18 +++++++++--------- .../jpegenc_v2/myhdl/test/test_dct2sinpout.py | 12 ++++++------ .../jpegenc_v2/myhdl/test/test_quantizer.py | 10 +++++----- .../jpegenc_v2/myhdl/test/test_rgb2ycbcr.py | 8 ++++---- tests/setup.cfg | 2 +- 6 files changed, 26 insertions(+), 26 deletions(-) diff --git a/jpegenc/models/processing.py b/jpegenc/models/processing.py index ceae44b..7a43ef9 100644 --- a/jpegenc/models/processing.py +++ b/jpegenc/models/processing.py @@ -90,7 +90,7 @@ def beh_ready(): # with all the same attributes/properties, the current # only uses the default. dataproc = datain.copy() - + @instance def processing_model(): diff --git a/tests/reference_designs/jpegenc_v2/myhdl/test/test_dct1sinpout.py b/tests/reference_designs/jpegenc_v2/myhdl/test/test_dct1sinpout.py index 5a9bb16..ce44063 100644 --- a/tests/reference_designs/jpegenc_v2/myhdl/test/test_dct1sinpout.py +++ b/tests/reference_designs/jpegenc_v2/myhdl/test/test_dct1sinpout.py @@ -10,8 +10,8 @@ def print_list(signalList): for i in RANGE1_8: - print "{:7d}".format(int(signalList[i])), - print "" + print("{:7d}".format(int(signalList[i]))) + print("") def print_matrix(matrix): @@ -43,14 +43,14 @@ def stimulus(): def monitor(): while True: yield delay(11) - print "\t".join(['en_out', 'input', 'en_in', 'reset', - ' clk', ' now']) - print "\t".join([" %d"]*6) % (enable_out, pixelValue, enable_in, - reset, clk, now()) - print "-" * 72 - print "-" * 72 + print("\t".join(['en_out', 'input', 'en_in', 'reset', + ' clk', ' now'])) + print("\t".join([" %d"]*6) % (enable_out, pixelValue, enable_in, + reset, clk, now())) + print("-" * 72) + print("-" * 72) print_list(pixelLine.pixels) - print "-" * 72 + print("-" * 72) yield delay(9) dct_inst = dct1SinPout( diff --git a/tests/reference_designs/jpegenc_v2/myhdl/test/test_dct2sinpout.py b/tests/reference_designs/jpegenc_v2/myhdl/test/test_dct2sinpout.py index 20486da..3311311 100644 --- a/tests/reference_designs/jpegenc_v2/myhdl/test/test_dct2sinpout.py +++ b/tests/reference_designs/jpegenc_v2/myhdl/test/test_dct2sinpout.py @@ -53,13 +53,13 @@ def stimulus(): def monitor(): while True: yield delay(11) - print "\t".join(['input', 'en_out', 'en_in', 'reset', - 'clk', 'now']) - print "\t".join(["%d"]*6) % (pixelVal, enable_out, - enable_in, reset, clk, now()) - print "-" * 70 + print("\t".join(['input', 'en_out', 'en_in', 'reset', + 'clk', 'now'])) + print("\t".join(["%d"]*6) % (pixelVal, enable_out, + enable_in, reset, clk, now())) + print("-" * 70) print_matrix(pixelBlock) - print "-" * 70 + print("-" * 70) yield delay(9) dct_inst = dct2SinPout( diff --git a/tests/reference_designs/jpegenc_v2/myhdl/test/test_quantizer.py b/tests/reference_designs/jpegenc_v2/myhdl/test/test_quantizer.py index dd7bbc6..3466ae7 100644 --- a/tests/reference_designs/jpegenc_v2/myhdl/test/test_quantizer.py +++ b/tests/reference_designs/jpegenc_v2/myhdl/test/test_quantizer.py @@ -60,13 +60,13 @@ def stimulus(): def monitor(): while True: yield delay(1) - print "\t".join(['e_in', 'e_out', 'reset', 'clk', 'now']) - print "\t".join(["%d"]*5) % (enable_in, enable_out, reset, clk, now()) - print "-" * 70 + print("\t".join(['e_in', 'e_out', 'reset', 'clk', 'now'])) + print("\t".join(["%d"]*5) % (enable_in, enable_out, reset, clk, now())) + print("-" * 70) print_matrix(iPixelBlock) - print "-" * 70 + print("-" * 70) print_matrix(qPixelBlock) - print "-" * 70 + print("-" * 70) yield delay(19) quantizer_inst = quantizer(qPixelBlock, enable_out, iPixelBlock, enable_in, clk, reset) diff --git a/tests/reference_designs/jpegenc_v2/myhdl/test/test_rgb2ycbcr.py b/tests/reference_designs/jpegenc_v2/myhdl/test/test_rgb2ycbcr.py index 0728820..4655652 100644 --- a/tests/reference_designs/jpegenc_v2/myhdl/test/test_rgb2ycbcr.py +++ b/tests/reference_designs/jpegenc_v2/myhdl/test/test_rgb2ycbcr.py @@ -31,13 +31,13 @@ def stimulus(): @instance def monitor(): - print "\t".join( + print("\t".join( ['red', 'green', 'blue', 'e_in', 'y', 'cb', 'cr', - 'e_out', 'reset', 'clk', 'now']) - print "-" * 70 + 'e_out', 'reset', 'clk', 'now'])) + print("-" * 70) while True: yield delay(11) - print "\t".join(["%d"] * 11) % \ + print("\t".join(["%d"] * 11) % \) (rgb.red, rgb.green, rgb.blue, enable_in, ycbcr.y, ycbcr.cb, ycbcr.cr, enable_out, reset, clk, now()) diff --git a/tests/setup.cfg b/tests/setup.cfg index 2bdf212..2eb845e 100644 --- a/tests/setup.cfg +++ b/tests/setup.cfg @@ -4,5 +4,5 @@ nocapture=True nologcapture=True with-coverage=True -[tool:pytest] +[pytest] norecursedirs = reference_designs From 27c5cd34b517d97f025278f835fdc73d777f0183 Mon Sep 17 00:00:00 2001 From: Christopher Felton Date: Fri, 21 Oct 2016 11:05:55 -0500 Subject: [PATCH 17/32] Added DCT data flow test Added a DCT data flow test to emulate the possible data flow through the system. This commit also has changed to the interfaces, the previous simulation `assign` functions were replaced with the `next` attribute. The `assign` function is now a myhdl.block to be used in the convertible HDL blocks. --- docs/source/overview.rst | 6 +- jpegenc/models/interfaces.py | 220 +++++++++++++++++++++++++++-------- jpegenc/models/processing.py | 65 +++++++---- requirements.txt | 2 +- 4 files changed, 218 insertions(+), 75 deletions(-) diff --git a/docs/source/overview.rst b/docs/source/overview.rst index 7929ece..edd92fc 100644 --- a/docs/source/overview.rst +++ b/docs/source/overview.rst @@ -2,10 +2,12 @@ Overview ======== The `jpegenc` package is a JPEG encoder implemented in -[MyHDL](http://www.myhdl.org). The JPEG encoder is intended to be +MyHDL_. The JPEG encoder is intended to be flexible with reusable subblocks. This project also includes a verification environment for the encoder. +.. _MyHDL: http://www.myhdl.org + The following figure outlines the main subblocks in the system. .. figure:: https://cloud.githubusercontent.com/assets/766391/18724671/e3eff6e8-8002-11e6-9dfe-9a03379a06fb.png @@ -32,7 +34,7 @@ Goals Measurements -============ +------------ .. toctree:: :maxdepth: 1 diff --git a/jpegenc/models/interfaces.py b/jpegenc/models/interfaces.py index 87db267..dec6301 100644 --- a/jpegenc/models/interfaces.py +++ b/jpegenc/models/interfaces.py @@ -12,10 +12,11 @@ """ from random import randint +from copy import copy, deepcopy import myhdl -from myhdl import (Signal, ResetSignal, ConcatSignal, intbv, - always_seq, always_comb, ) +from myhdl import (Signal, SignalType, ResetSignal, ConcatSignal, intbv, + always_seq, always, always_comb, ) from myhdl import instance, delay, StopSimulation from myhdl.conversion import verify @@ -24,25 +25,108 @@ except ImportError: from .useful_things import Signals, assign +# @todo: refactor each of the interfaces to their own module +# There is a fair amount of documentation with the interfaces. +# Having the interfaces in their own file (python.module) makes +# it easier to navigate + class DataStream(object): def __init__(self, data_width=24): - """Data stream with ready-valid flow control.""" + """Data stream with ready-valid flow control. + + The "next" property can only be used in simulation, it is + not convertible! + """ + self.data_width = data_width self.data = Signal(intbv(0)[data_width:0]) self.valid = Signal(bool(0)) self.ready = Signal(bool(0)) - def assign(self, stream): + @property + def name(self): + nm = 'data_stream_inst' + if hasattr(self, '__name__'): + nm = self.__name__ + return nm + + @property + def next(self): + return None + + @next.setter + def next(self, ds): + self._assign_next(ds) + + def _assign_next(self, stream): + """Simulation assign only (see next) + """ assert isinstance(stream, DataStream) self.data.next = stream.data self.valid.next = stream.valid - def __copy__(self): - ds = DataStream(data_width=len(self.data)) + def copy(self): + # hmmm, wanted deepcopy but it doesn't work because the + # myhdl.Signal does a deepcopy ... + ds = DataStream(data_width=self.data_width) return ds - def copy(self): - return self.__copy__() + @myhdl.block + def monitor(self): + """ + In the current myhdl tracing there are some limitations + that prevent most of the signals not to be traced in + the interfaces. This block will trace the signals in + the interface. + """ + mdata = Signal(intbv(0)[len(self.data):0]) + mvalid = Signal(bool(0)) + mready = Signal(bool(0)) + + @always_comb + def mon_interface_attrs(): + mdata.next = self.data + mvalid.next = self.valid + mready.next = self.ready + + return myhdl.instances() + + @staticmethod + def always_deco(clock=None): + if clock is None: + deco = always_comb + else: + deco = always(clock.posedge) + + return deco + + @myhdl.block + def assign(self, ds, clock=None): + """Assign another datastream to this datastream + This assign block needs to be used in convertible in place + of the `next` attribute. + + Args: + ds (DataStream): the datastream to assign from + clock (Signal): system clock, optional + + This needs to be implemented for each interface that uses + DataStream as a base class. In subclasses the `data` field + is read-only (shadow), the lower bits are the data bits and + upper bits of the data field are additional control and meta + data. + + myhdl convertible + """ + assert isinstance(ds, DataStream) + + @self.always_deco(clock) + def beh_assign(): + self.data.next = ds.data + self.ready.next = ds.ready + self.valid.next = ds.valid + + return beh_assign class PixelStream(DataStream): @@ -50,19 +134,23 @@ def __init__(self, data_width=24): """Pixel stream.""" self.start_of_frame = Signal(bool(0)) self.end_of_frame = Signal(bool(0)) + self.pixel = Signal(intbv(0)[data_width:0]) super(PixelStream, self).__init__(data_width+2) - self.data = ConcatSignal(self.start_of_frame, self.end_of_frame, - self.data) - def assign(self, stream): + # override the data to be a shadow (read-only) + self.data = ConcatSignal(self.start_of_frame, + self.end_of_frame, + self.pixel) + + def _assign_next(self, stream): assert isinstance(stream, PixelStream) - self.data.next = stream.data + self.pixel.next = stream.pixel self.valid.next = stream.valid self.start_of_frame.next = stream.start_of_frame self.end_of_frame.next = stream.end_of_frame - # def map_to_data(self): - # raise NotImplementedError() + def copy(self): + raise NotImplementedError class RGBStream(PixelStream): @@ -75,17 +163,19 @@ def __init__(self, color_depth=(8, 8, 8), num_pixels=1): """ assert len(color_depth) == 3 data_width = sum(color_depth) - super(RGBStream, self).__init__(data_width=data_width) + super(RGBStream, self).__init__(data_width=data_width+2) self.color_depth = color_depth rbits, gbits, bbits = color_depth # a single pixel (color component) is the most + self.num_pixels = num_pixels if num_pixels == 1: self.red = Signal(intbv(0)[rbits:0]) self.green = Signal(intbv(0)[gbits:0]) self.blue = Signal(intbv(0)[rbits:0]) - # alias to the above signals + # alias to the above signals, overrides data, data is + # a shadow (read-only) of the RGB attributes self.data = ConcatSignal(self.start_of_frame, self.end_of_frame, self.red, self.green, self.blue) else: @@ -95,41 +185,60 @@ def __init__(self, color_depth=(8, 8, 8), num_pixels=1): # @todo data alias for multiple pixels raise NotImplementedError - def assign(self, stream): - assert isinstance(stream, RGBStream) - self.valid.next = stream.valid - self.start_of_frame.next = stream.start_of_frame - self.end_of_frame.next = stream.end_of_frame - self.red.next = stream.red - self.green.next = stream.green - self.blue.next = stream.blue - - def assign_from_data(self, data): - """Given a data vector, update the attributes""" - assert len(data) == len(self.data) - rbits, gbits, bbits = self.color_depth - self.blue.next = data[bbits:0] - self.green.next = data[gbits+bbits:bbits] - self.red.next = data[rbits+gbits+bbits:gbits] - self.end_of_frame.next = data[rbits] - self.start_of_frame.next = data[rbits+1] - - # @myhdl.block - # def map_to_data(self): - # """Map red, green, and blue to data - # The base interface to all the subblocks is `DataStream` but in most - # of the subblocks it is more convenient to deal with the color - # components. When using the color components the data needs to be - # assigned. - # - # myhdl convertible - # """ - # raise NotImplementedError - # - # # insts = [] - # # for nn in range(self.num_pixels): - # # for jj in range(3): - # # insts = assign() + def copy(self): + rgb = RGBStream(color_depth=self.color_depth, + num_pixels=self.num_pixels) + return rgb + + def _assign_next(self, stream): + if isinstance(stream, RGBStream): + self.valid.next = stream.valid + self.start_of_frame.next = stream.start_of_frame + self.end_of_frame.next = stream.end_of_frame + self.red.next = stream.red + self.green.next = stream.green + self.blue.next = stream.blue + elif isinstance(stream, (DataStream, SignalType,)): + data = stream.data if isinstance(stream, DataStream) else stream + assert len(data) == len(self.data) + rbits, gbits, bbits = self.color_depth + self.blue.next = data[bbits:0] + self.green.next = data[gbits + bbits:bbits] + self.red.next = data[rbits + gbits + bbits:gbits] + self.end_of_frame.next = data[rbits] + self.start_of_frame.next = data[rbits + 1] + else: + raise TypeError("Invalid stream type {}".format(type(stream))) + + @myhdl.block + def assign(self, stream, clock=None): + # @todo this should be identical to _assign_next + # but the assignments need to be wrapped in a myhdl always decorator + + # @todo: maybe make these external modules and name the instances + # if RGBStream: + # inst = rgb_assign_rgbstream(stream, clock) + # elif DataStream, SignalType + # inst = rgb_assign_data(data, color_depth, clock) + # inst.name = self.name + if isinstance(stream, RGBStream): + @self.always_deco(clock) + def beh_assign(): + pass + elif isinstance(stream (DataStream, SignalType)): + data = stream.data if isinstance(stream, DataStream) else stream + assert len(data) == len(self.data) + rbits, gbits, bbits = self.color_depth + + @self.always_deco(clock) + def beh_assign(): + pass + else: + raise TypeError("Invalid stream type {}".format(type(stream))) + + raise NotImplementedError + + return beh_assign class YCbCrStream(PixelStream): @@ -152,6 +261,15 @@ def __init__(self, color_depth=(8, 8, 8)): # alias to the above color signals self.data = ConcatSignal(self.y, self.cb, self.cr) + def copy(self): + raise NotImplementedError + + def _assign_next(self, stream): + raise NotImplementedError + + def assign(self, ds, clock=None): + raise NotImplementedError + class DataBlock(object): def __init__(self, size=8, min=0, max=8): diff --git a/jpegenc/models/processing.py b/jpegenc/models/processing.py index 7a43ef9..b7db35b 100644 --- a/jpegenc/models/processing.py +++ b/jpegenc/models/processing.py @@ -11,7 +11,7 @@ class ProcessingSubblock(object): - def __init__(self, cycles_to_process=1, block_size=None, buffered=False): + def __init__(self, cycles_to_process=1, pipelined=False, block_size=None, buffered=False): """A simple model to represent a processing subblock in the jpegenc Arguments: @@ -27,17 +27,28 @@ def __init__(self, cycles_to_process=1, block_size=None, buffered=False): buffered (bool): - The processing element class is named ProcessingSubblock and `psb` - and `pe` will be used as shorthand in various spots. + The processing element class is named ProcessingSubblock, `psb` + and `pe` will be used as shorthand. """ assert isinstance(cycles_to_process, int) + assert cycles_to_process > 0 + assert isinstance(pipelined, bool) if block_size is not None: assert isinstance(block_size, tuple) and len(block_size) == 2 - assert isinstance(buffered, bool) # the cycles to process is the same as latency self.ctp = cycles_to_process + self.pipe = pipelined self.block_size = block_size + + # determine if buffered on inputs, outputs, or both + assert isinstance(buffered, (bool, str)) + if isinstance(buffered, str): + assert buffered in ('input', 'output') + self.buffer_type = buffered + buffered = True + else: + self.buffer_type = 'both' if buffered else 'none' self.buffered = buffered if buffered: @@ -53,20 +64,17 @@ def __init__(self, cycles_to_process=1, block_size=None, buffered=False): def process(self, glbl, datain, dataout): assert isinstance(datain, DataStream) assert isinstance(dataout, DataStream) - assert len(datain.data) == len(dataout.data) + ctp, piped, buffered = self.ctp, self.pipe, self.buffered + clock, reset = glbl.clock, glbl.reset ready = Signal(bool(0)) # include an input and output fifo if self.buffered: - # @todo: implement the FIFO - raise NotImplementedError - - # @todo: the interfaces need to override copy ... - buffered_data_i = type(datain)() - buffered_data_o = type(datain)() + buffered_data_i = datain.copy() + buffered_data_o = datain.copy() fifo_i = self.fifo_i fifo_i_inst = fifo_i.process(glbl, datain, buffered_data_i) @@ -85,24 +93,39 @@ def beh_ready(): datain.ready.next = ready # need an intermediate to hold the signal values - # @todo: the interfaces need to overload __copy__, - # To make this generic this needs a new (copy) instance - # with all the same attributes/properties, the current - # only uses the default. dataproc = datain.copy() - + npipe = ctp-1 + pipeline = [datain.copy() for _ in range(npipe)] @instance def processing_model(): ready.next = True + while True: # datain -> dataproc -> dataout - dataproc.assign(datain) - # @todo: fixed at 1 cycle for now - # if the latency is less than - # for nn in range(self.ctp): + if piped: + pipeline[0].next = datain + for ii in range(1, npipe): + pipeline[ii].next = pipeline[ii-1] + else: + dataproc.assign(datain) + for nn in range(self.ctp-1): + ready.next = False + yield clock.posedge + ready.next = True + + # always at least one yield clock.posedge - dataout.assign(dataproc) + dataout.next = dataproc + + # @todo: this causes a duplicate error in the + # many of the interface signals are not traced by default, + # get a bunch of monitors so the signals can be traced. + # mon_insts = [] + # for intf in (datain, dataproc, dataout): + # inst = intf.monitor() + # # inst.name = intf.name + # mon_insts += [inst] return myhdl.instances() diff --git a/requirements.txt b/requirements.txt index dc2d69e..dd8c6a2 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ -pytest +pytest>=3.0.3 numpy Pillow -e git://github.com/jandecaluwe/myhdl.git#egg=myhdl-1.0dev0 From df0442a85c024bb705fe95fdaa75755b227a5a1a Mon Sep 17 00:00:00 2001 From: Christopher Felton Date: Fri, 21 Oct 2016 16:13:51 -0500 Subject: [PATCH 18/32] Added ObjectWithBlocks base class (experiment) --- jpegenc/models/__init__.py | 4 +- jpegenc/models/interfaces.py | 36 +++++------ jpegenc/models/owb.py | 30 +++++++++ jpegenc/models/processing.py | 22 ++++--- jpegenc/models/video/bitstream.py | 4 +- jpegenc/models/video/video_source.py | 5 +- .../jpegenc_v2/myhdl/test/test_dct2sinpout.py | 12 ++-- .../jpegenc_v2/myhdl/test/test_quantizer.py | 6 +- .../jpegenc_v2/myhdl/test/test_rgb2ycbcr.py | 10 +-- tests/test_models/test_nnn_dct.py | 62 +++++++++++++++++++ 10 files changed, 148 insertions(+), 43 deletions(-) create mode 100644 jpegenc/models/owb.py create mode 100644 tests/test_models/test_nnn_dct.py diff --git a/jpegenc/models/__init__.py b/jpegenc/models/__init__.py index 1f29882..1fd6935 100644 --- a/jpegenc/models/__init__.py +++ b/jpegenc/models/__init__.py @@ -1,5 +1,7 @@ +from .owb import ObjectWithBlocks + from .interfaces import DataStream from .interfaces import RGBStream -from .processing import ProcessingSubblock \ No newline at end of file +from .processing import ProcessingSubblock diff --git a/jpegenc/models/interfaces.py b/jpegenc/models/interfaces.py index dec6301..f4d3b3b 100644 --- a/jpegenc/models/interfaces.py +++ b/jpegenc/models/interfaces.py @@ -12,7 +12,6 @@ """ from random import randint -from copy import copy, deepcopy import myhdl from myhdl import (Signal, SignalType, ResetSignal, ConcatSignal, intbv, @@ -25,13 +24,15 @@ except ImportError: from .useful_things import Signals, assign +from . import ObjectWithBlocks + # @todo: refactor each of the interfaces to their own module # There is a fair amount of documentation with the interfaces. # Having the interfaces in their own file (python.module) makes # it easier to navigate -class DataStream(object): +class DataStream(ObjectWithBlocks): def __init__(self, data_width=24): """Data stream with ready-valid flow control. @@ -42,13 +43,7 @@ def __init__(self, data_width=24): self.data = Signal(intbv(0)[data_width:0]) self.valid = Signal(bool(0)) self.ready = Signal(bool(0)) - - @property - def name(self): - nm = 'data_stream_inst' - if hasattr(self, '__name__'): - nm = self.__name__ - return nm + super(DataStream, self).__init__(name='datastream') @property def next(self): @@ -66,11 +61,18 @@ def _assign_next(self, stream): self.valid.next = stream.valid def copy(self): - # hmmm, wanted deepcopy but it doesn't work because the - # myhdl.Signal does a deepcopy ... ds = DataStream(data_width=self.data_width) return ds + @staticmethod + def always_deco(clock=None): + if clock is None: + deco = always_comb + else: + deco = always(clock.posedge) + + return deco + @myhdl.block def monitor(self): """ @@ -79,6 +81,7 @@ def monitor(self): the interfaces. This block will trace the signals in the interface. """ + # @todo: there is an odd issue with this and myhdl 1.0dev mdata = Signal(intbv(0)[len(self.data):0]) mvalid = Signal(bool(0)) mready = Signal(bool(0)) @@ -89,16 +92,7 @@ def mon_interface_attrs(): mvalid.next = self.valid mready.next = self.ready - return myhdl.instances() - - @staticmethod - def always_deco(clock=None): - if clock is None: - deco = always_comb - else: - deco = always(clock.posedge) - - return deco + return mon_interface_attrs @myhdl.block def assign(self, ds, clock=None): diff --git a/jpegenc/models/owb.py b/jpegenc/models/owb.py new file mode 100644 index 0000000..027641d --- /dev/null +++ b/jpegenc/models/owb.py @@ -0,0 +1,30 @@ + +import myhdl + + +g_inst_id = 0 + + +class ObjectWithBlocks(object): + def __init__(self, name="owb"): + global g_inst_id + self.inst_id = g_inst_id + g_inst_id += 1 + self._name = name + + @property + def name(self): + nm = self._name + if hasattr(self, __name__): + nm = self.__name__ + nm = "{}_{}".format(nm, self.inst_id) + return nm + + @myhdl.block + def __call__(self, *ports, **params): + inst = self.process(*ports, **params) + inst.name = self.name + return inst + + def process(self, *ports, **params): + raise NotImplementedError diff --git a/jpegenc/models/processing.py b/jpegenc/models/processing.py index b7db35b..6295085 100644 --- a/jpegenc/models/processing.py +++ b/jpegenc/models/processing.py @@ -1,6 +1,7 @@ from random import randint from math import floor +import traceback import myhdl from myhdl import Signal, intbv, instance, always_comb @@ -9,8 +10,10 @@ from .interfaces import DataStream, RGBStream from .buffers import FIFOReadyValid +from . import ObjectWithBlocks -class ProcessingSubblock(object): + +class ProcessingSubblock(ObjectWithBlocks): def __init__(self, cycles_to_process=1, pipelined=False, block_size=None, buffered=False): """A simple model to represent a processing subblock in the jpegenc @@ -36,6 +39,8 @@ def __init__(self, cycles_to_process=1, pipelined=False, block_size=None, buffer if block_size is not None: assert isinstance(block_size, tuple) and len(block_size) == 2 + super(ProcessingSubblock, self).__init__(name='pe') + # the cycles to process is the same as latency self.ctp = cycles_to_process self.pipe = pipelined @@ -107,8 +112,9 @@ def processing_model(): pipeline[0].next = datain for ii in range(1, npipe): pipeline[ii].next = pipeline[ii-1] + dataproc.next = pipeline[-1] else: - dataproc.assign(datain) + dataproc.next = datain for nn in range(self.ctp-1): ready.next = False yield clock.posedge @@ -121,11 +127,13 @@ def processing_model(): # @todo: this causes a duplicate error in the # many of the interface signals are not traced by default, # get a bunch of monitors so the signals can be traced. - # mon_insts = [] - # for intf in (datain, dataproc, dataout): - # inst = intf.monitor() - # # inst.name = intf.name - # mon_insts += [inst] + mon_insts = [] + for intf in (datain, dataproc, dataout): + inst = intf.monitor() + inst.name = intf.name + mon_insts.append(inst) + # must delete the temp inst reference when using myhdl.instances() + del inst return myhdl.instances() diff --git a/jpegenc/models/video/bitstream.py b/jpegenc/models/video/bitstream.py index f9cc734..50fe74c 100644 --- a/jpegenc/models/video/bitstream.py +++ b/jpegenc/models/video/bitstream.py @@ -3,11 +3,12 @@ import myhdl from myhdl import Signal, instance +from .. import ObjectWithBlocks from ..interfaces import DataStream from .video_source import VideoSource -class BitstreamDevourer(object): +class BitstreamDevourer(ObjectWithBlocks): def __init__(self, source, encoder=None): """ @@ -17,6 +18,7 @@ def __init__(self, source, encoder=None): encoder (CODEC): """ assert isinstance(source, (VideoSource, type(None))) + super(BitstreamDevourer, self).__init__(name='bitdevour') self.source = source if source is not None: diff --git a/jpegenc/models/video/video_source.py b/jpegenc/models/video/video_source.py index 3a3bdfc..07f960d 100644 --- a/jpegenc/models/video/video_source.py +++ b/jpegenc/models/video/video_source.py @@ -5,10 +5,11 @@ import myhdl from myhdl import Signal, intbv, instance, always_comb +from .. import ObjectWithBlocks from ..interfaces import DataStream, RGBStream -class VideoSource(object): +class VideoSource(ObjectWithBlocks): def __init__(self, resolution=(1920, 1080), frame_rate=60, color_depth=(8, 8, 8)): """A model of a video source This object contains an example of a video source interface and @@ -34,6 +35,8 @@ def __init__(self, resolution=(1920, 1080), frame_rate=60, color_depth=(8, 8, 8) row_buffer_inst = video.row_buffer(video, image_block) """ + super(VideoSource, self).__init__(name='video_source') + self.resolution = resolution self.frame_rate = frame_rate self.pixel = RGBStream(color_depth=color_depth) diff --git a/tests/reference_designs/jpegenc_v2/myhdl/test/test_dct2sinpout.py b/tests/reference_designs/jpegenc_v2/myhdl/test/test_dct2sinpout.py index 3311311..89c2275 100644 --- a/tests/reference_designs/jpegenc_v2/myhdl/test/test_dct2sinpout.py +++ b/tests/reference_designs/jpegenc_v2/myhdl/test/test_dct2sinpout.py @@ -1,17 +1,21 @@ -#!/bin/python + +from __future__ import print_function, division + +from random import randrange + from myhdl import * + from commons import * from dctconstructs import * from dct2sinpout import * -from random import randrange RANGE1_8 = range(8) def print_list(signalList): for i in RANGE1_8: - print "{:6d}".format(int(signalList[i])), - print "" + print("{:6d}".format(int(signalList[i])),) + print("") def print_matrix(matrix): diff --git a/tests/reference_designs/jpegenc_v2/myhdl/test/test_quantizer.py b/tests/reference_designs/jpegenc_v2/myhdl/test/test_quantizer.py index 3466ae7..b057e61 100644 --- a/tests/reference_designs/jpegenc_v2/myhdl/test/test_quantizer.py +++ b/tests/reference_designs/jpegenc_v2/myhdl/test/test_quantizer.py @@ -1,4 +1,4 @@ -#!/bin/python + from myhdl import * from commons import * from dctconstructs import PixelBlock @@ -9,8 +9,8 @@ def print_list(signalList): for i in RANGE1_8: - print "{:6d}".format(int(signalList[i])), - print "" + print("{:6d}".format(int(signalList[i])),) + print("") def print_matrix(matrix): diff --git a/tests/reference_designs/jpegenc_v2/myhdl/test/test_rgb2ycbcr.py b/tests/reference_designs/jpegenc_v2/myhdl/test/test_rgb2ycbcr.py index 4655652..958b60e 100644 --- a/tests/reference_designs/jpegenc_v2/myhdl/test/test_rgb2ycbcr.py +++ b/tests/reference_designs/jpegenc_v2/myhdl/test/test_rgb2ycbcr.py @@ -1,4 +1,4 @@ -#!/bin/python + from myhdl import * from random import randrange from commons import * @@ -37,10 +37,10 @@ def monitor(): print("-" * 70) while True: yield delay(11) - print("\t".join(["%d"] * 11) % \) - (rgb.red, rgb.green, rgb.blue, enable_in, - ycbcr.y, ycbcr.cb, ycbcr.cr, enable_out, - reset, clk, now()) + print("\t".join(["%d"] * 11) % + (rgb.red, rgb.green, rgb.blue, enable_in, + ycbcr.y, ycbcr.cb, ycbcr.cr, enable_out, + reset, clk, now())) yield delay(9) rgb2ycbcr_inst = rgb2ycbcr(ycbcr, enable_out, rgb, enable_in, clk, reset) diff --git a/tests/test_models/test_nnn_dct.py b/tests/test_models/test_nnn_dct.py new file mode 100644 index 0000000..3a4986b --- /dev/null +++ b/tests/test_models/test_nnn_dct.py @@ -0,0 +1,62 @@ + +import myhdl +from myhdl import instance, delay, StopSimulation +from rhea import Global, Clock + +from jpegenc.models.subblocks import DCTDataFlow +from jpegenc.models.video import ColorBars +from jpegenc.models.video import BitstreamDevourer + +from jpegenc.testing import run_testbench + + +def test_dct_data_flow(): + + resolution = (1920, 1080) + frame_rate = 60 + color_depth = (8, 8, 8) + + clock = Clock(0, frequency=125e6) + glbl = Global(clock) + video_source = ColorBars(resolution, color_depth, frame_rate) + dct = DCTDataFlow() + bit_sink = BitstreamDevourer(source=video_source, encoder=None) + + @myhdl.block + def bench(): + ck_drv = clock.gen() + + vd_proc = video_source(glbl) + pixel_i = video_source.pixel + pixel_o = video_source.pixel.copy() + + dct_proc = dct(glbl, pixel_i, pixel_o) + vk_proc = bit_sink(glbl, pixel_o) + bd = bit_sink + + @instance + def tbstim(): + npxl = 3*64 # get 3 blocks + tcnt, timeout = 0, 4*npxl + + while bd.num_data_words < npxl and tcnt < timeout: + yield clock.posedge + tcnt += 1 + + # not concerned about an actual amount, just that it + # received at least the number specified + assert bd.num_data_words >= npxl + + raise StopSimulation + + # set a name for the instances for tracing, otherwise the + # "process" method in each of the objects results in the + # same extended name for all the processes. + # ck_drv.name = 'clock_driver' + # vd_proc.name = 'video_source' + # dct_proc.name = 'dct_data_flow' + # vk_proc.name = 'bit_sink' + + return myhdl.instances() + + run_testbench(bench, trace=True, bench_id='dct_data_flow') From 237a6cd73c6f041a1dd1b735cde11878ddacf90c Mon Sep 17 00:00:00 2001 From: Christopher Felton Date: Sat, 22 Oct 2016 07:06:49 -0500 Subject: [PATCH 19/32] Moved the reference design tests to test_ref. The Verilog cosimulation tests, reference design tests, were moved to a separate directory. This was done to organize the tests. The cosim (ref tests) being in a separate directory can be troublesome. The cosim needs to know the path to the Verilog files and the VPI module. When run from pytest this typically will be from the test_jpeg/tests/ directory, all the paths would be relative from here. Currently all the paths are fixed from the tests/ dir, this should be enhanced in the future to determine which directory the pytest runner exectuing from and adjust the paths accordingly. --- jpegenc/testing/cosim/jpeg_prep_cosim.py | 6 +++--- tests/__init__.py | 26 ------------------------ tests/{ => test_ref}/tb_jpegenc.v | 0 tests/{ => test_ref}/tb_mdct.v | 0 tests/{ => test_ref}/test_ref_designs.py | 0 tests/{ => test_ref}/test_ref_mdct.py | 2 +- 6 files changed, 4 insertions(+), 30 deletions(-) delete mode 100644 tests/__init__.py rename tests/{ => test_ref}/tb_jpegenc.v (100%) rename tests/{ => test_ref}/tb_mdct.v (100%) rename tests/{ => test_ref}/test_ref_designs.py (100%) rename tests/{ => test_ref}/test_ref_mdct.py (99%) diff --git a/jpegenc/testing/cosim/jpeg_prep_cosim.py b/jpegenc/testing/cosim/jpeg_prep_cosim.py index ebaa5d7..ddbb212 100644 --- a/jpegenc/testing/cosim/jpeg_prep_cosim.py +++ b/jpegenc/testing/cosim/jpeg_prep_cosim.py @@ -33,7 +33,7 @@ def prep_cosim(clock, reset, jpgv1, jpgv2, args=None): print("compiling v2 ...") os.system(cmd) - files = ['tb_jpegenc.v'] + files = ['test_ref/tb_jpegenc.v'] vstr = "-D VTRACE" if args.vtrace else "" dstr = "%s -D VTRACE_LEVEL=%d -D VTRACE_MODULE=%s " % \ (vstr, args.vtrace_level, args.vtrace_module) @@ -61,8 +61,8 @@ def prep_cosim(clock, reset, jpgv1, jpgv2, args=None): reset=reset, # encoder 1 (V1, design1) - j1_iram_wdata = jpgv1.iram_wdata, - j1_iram_wren = jpgv1.iram_wren, + j1_iram_wdata=jpgv1.iram_wdata, + j1_iram_wren=jpgv1.iram_wren, j1_iram_fifo_afull = jpgv1.iram_fifo_afull, j1_ram_byte = jpgv1.ram_byte, j1_ram_wren = jpgv1.ram_wren, diff --git a/tests/__init__.py b/tests/__init__.py deleted file mode 100644 index 6e39ab3..0000000 --- a/tests/__init__.py +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/env python -# coding=utf-8 -from __future__ import absolute_import - -from .test_rgb2ycbcr import test_color_translation -from .test_rgb2ycbcr import test_block_conversion - -from .test_rgb2ycbcr_v2 import test_color_translation_v2 -from .test_rgb2ycbcr_v2 import test_color_translation_conversion_v2 - -from .test_dct_1d import test_dct_1d -from .test_dct_1d import test_dct_1d_conversion - -from .test_dct_2d import test_dct_2d -from .test_dct_2d import test_dct_2d_conversion - -from .test_zig_zag import test_zig_zag -from .test_zig_zag import test_zig_zag_conversion - -from .test_frontend_v2 import test_frontend -from .test_frontend_v2 import test_frontend_conversion - -__all__ = ['test_block_conversion', 'test_color_translation', 'test_color_translation_v2', - 'test_color_translation_conversion_v2', 'test_dct_1d', 'test_dct_1d_conversion', - 'test_dct_2d', 'test_dct_2d_conversion', 'test_zig_zag', 'test_zig_zag_conversion', - 'test_frontend', 'test_frontend_conversion'] diff --git a/tests/tb_jpegenc.v b/tests/test_ref/tb_jpegenc.v similarity index 100% rename from tests/tb_jpegenc.v rename to tests/test_ref/tb_jpegenc.v diff --git a/tests/tb_mdct.v b/tests/test_ref/tb_mdct.v similarity index 100% rename from tests/tb_mdct.v rename to tests/test_ref/tb_mdct.v diff --git a/tests/test_ref_designs.py b/tests/test_ref/test_ref_designs.py similarity index 100% rename from tests/test_ref_designs.py rename to tests/test_ref/test_ref_designs.py diff --git a/tests/test_ref_mdct.py b/tests/test_ref/test_ref_mdct.py similarity index 99% rename from tests/test_ref_mdct.py rename to tests/test_ref/test_ref_mdct.py index e578b8f..3d34cb8 100644 --- a/tests/test_ref_mdct.py +++ b/tests/test_ref/test_ref_mdct.py @@ -25,7 +25,7 @@ def prep_cosim(clock, reset, datai, datao, args=None): 'MDCT.v'] filelist = [os.path.join(spth, ff) for ff in filelist] - filelist += ['tb_mdct.v'] + filelist += ['test_ref/tb_mdct.v'] for ff in filelist: assert os.path.isfile(ff), "%s" % (ff,) From 4a625c8e96e1b8581577c33c8d2b17ed39d6787e Mon Sep 17 00:00:00 2001 From: Christopher Felton Date: Sat, 22 Oct 2016 09:27:56 -0500 Subject: [PATCH 20/32] minor change to ObjectWithBlocks --- jpegenc/models/owb.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/jpegenc/models/owb.py b/jpegenc/models/owb.py index 027641d..ee78cb6 100644 --- a/jpegenc/models/owb.py +++ b/jpegenc/models/owb.py @@ -7,6 +7,12 @@ class ObjectWithBlocks(object): def __init__(self, name="owb"): + """ + + Args: + name: a name for the object, this will be used for + the instance names in the tracing and conversion. + """ global g_inst_id self.inst_id = g_inst_id g_inst_id += 1 From 1fe78cbae1d5d1efe03efdb2d870f469f49e0fc3 Mon Sep 17 00:00:00 2001 From: Christopher Felton Date: Sat, 22 Oct 2016 10:16:23 -0500 Subject: [PATCH 21/32] Moved some of the interfaced from models to the encoder --- docs/jpegenc_v2_notes.md | 0 jpegenc/interfaces/__init__.py | 8 + jpegenc/interfaces/datastream.py | 97 +++++++ .../object_with_blocks.py} | 0 jpegenc/interfaces/pixelstream.py | 27 ++ jpegenc/interfaces/rgbstream.py | 95 +++++++ jpegenc/interfaces/ycbcrstream.py | 34 +++ jpegenc/models/__init__.py | 4 - jpegenc/models/interfaces.py | 248 +----------------- jpegenc/models/processing.py | 10 +- jpegenc/models/video/bitstream.py | 3 +- jpegenc/models/video/colorbars.py | 1 - jpegenc/models/video/video_source.py | 5 +- jpegenc/subblocks/dct/dct_2d_rcd.py | 39 +++ jpegenc/subblocks/dct/dct_2d_rcd_par.py | 34 +++ tests/test_models/test_002_bd.py | 2 +- tests/test_models/test_003_pe.py | 2 +- tests/test_models/test_004_pe.py | 2 +- 18 files changed, 343 insertions(+), 268 deletions(-) create mode 100644 docs/jpegenc_v2_notes.md create mode 100644 jpegenc/interfaces/__init__.py create mode 100644 jpegenc/interfaces/datastream.py rename jpegenc/{models/owb.py => interfaces/object_with_blocks.py} (100%) create mode 100644 jpegenc/interfaces/pixelstream.py create mode 100644 jpegenc/interfaces/rgbstream.py create mode 100644 jpegenc/interfaces/ycbcrstream.py create mode 100644 jpegenc/subblocks/dct/dct_2d_rcd.py create mode 100644 jpegenc/subblocks/dct/dct_2d_rcd_par.py diff --git a/docs/jpegenc_v2_notes.md b/docs/jpegenc_v2_notes.md new file mode 100644 index 0000000..e69de29 diff --git a/jpegenc/interfaces/__init__.py b/jpegenc/interfaces/__init__.py new file mode 100644 index 0000000..9a18445 --- /dev/null +++ b/jpegenc/interfaces/__init__.py @@ -0,0 +1,8 @@ + +from __future__ import absolute_import + +from .object_with_blocks import ObjectWithBlocks +from .datastream import DataStream +from .pixelstream import PixelStream +from .rgbstream import RGBStream +from .ycbcrstream import YCbCrStream diff --git a/jpegenc/interfaces/datastream.py b/jpegenc/interfaces/datastream.py new file mode 100644 index 0000000..e3e09f5 --- /dev/null +++ b/jpegenc/interfaces/datastream.py @@ -0,0 +1,97 @@ + +import myhdl +from myhdl import Signal, intbv, always, always_comb + +from .object_with_blocks import ObjectWithBlocks + + +class DataStream(ObjectWithBlocks): + def __init__(self, data_width=24): + """Data stream with ready-valid flow control. + + The "next" property can only be used in simulation, it is + not convertible! + """ + self.data_width = data_width + self.data = Signal(intbv(0)[data_width:0]) + self.valid = Signal(bool(0)) + self.ready = Signal(bool(0)) + super(DataStream, self).__init__(name='datastream') + + @property + def next(self): + return None + + @next.setter + def next(self, ds): + self._assign_next(ds) + + def _assign_next(self, stream): + """Simulation assign only (see next) + """ + assert isinstance(stream, DataStream) + self.data.next = stream.data + self.valid.next = stream.valid + + def copy(self): + ds = DataStream(data_width=self.data_width) + return ds + + @staticmethod + def always_deco(clock=None): + if clock is None: + deco = always_comb + else: + deco = always(clock.posedge) + + return deco + + @myhdl.block + def monitor(self): + """ + In the current myhdl tracing there are some limitations + that prevent most of the signals not to be traced in + the interfaces. This block will trace the signals in + the interface. + """ + data = self.data + valid = self.valid + ready = self.ready + changed = Signal(bool(0)) + + @always_comb + def mon_interface_attrs(): + if valid or ready or data > 0: + changed.next = True + else: + changed.next = False + + return mon_interface_attrs + + @myhdl.block + def assign(self, ds, clock=None): + """Assign another datastream to this datastream + This assign block needs to be used in convertible in place + of the `next` attribute. + + Args: + ds (DataStream): the datastream to assign from + clock (Signal): system clock, optional + + This needs to be implemented for each interface that uses + DataStream as a base class. In subclasses the `data` field + is read-only (shadow), the lower bits are the data bits and + upper bits of the data field are additional control and meta + data. + + myhdl convertible + """ + assert isinstance(ds, DataStream) + + @self.always_deco(clock) + def beh_assign(): + self.data.next = ds.data + self.ready.next = ds.ready + self.valid.next = ds.valid + + return beh_assign diff --git a/jpegenc/models/owb.py b/jpegenc/interfaces/object_with_blocks.py similarity index 100% rename from jpegenc/models/owb.py rename to jpegenc/interfaces/object_with_blocks.py diff --git a/jpegenc/interfaces/pixelstream.py b/jpegenc/interfaces/pixelstream.py new file mode 100644 index 0000000..21a7a86 --- /dev/null +++ b/jpegenc/interfaces/pixelstream.py @@ -0,0 +1,27 @@ + +from myhdl import Signal, intbv, ConcatSignal +from .datastream import DataStream + + +class PixelStream(DataStream): + def __init__(self, data_width=24): + """Pixel stream.""" + self.start_of_frame = Signal(bool(0)) + self.end_of_frame = Signal(bool(0)) + self.pixel = Signal(intbv(0)[data_width:0]) + super(PixelStream, self).__init__(data_width+2) + + # override the data to be a shadow (read-only) + self.data = ConcatSignal(self.start_of_frame, + self.end_of_frame, + self.pixel) + + def _assign_next(self, stream): + assert isinstance(stream, PixelStream) + self.pixel.next = stream.pixel + self.valid.next = stream.valid + self.start_of_frame.next = stream.start_of_frame + self.end_of_frame.next = stream.end_of_frame + + def copy(self): + raise NotImplementedError diff --git a/jpegenc/interfaces/rgbstream.py b/jpegenc/interfaces/rgbstream.py new file mode 100644 index 0000000..7ef34b1 --- /dev/null +++ b/jpegenc/interfaces/rgbstream.py @@ -0,0 +1,95 @@ + +import myhdl +from myhdl import Signal, intbv, ConcatSignal, SignalType +from rhea import Signals + +from .datastream import DataStream +from .pixelstream import PixelStream + + +class RGBStream(PixelStream): + def __init__(self, color_depth=(8, 8, 8), num_pixels=1): + """A red-green-blue pixel stream. + Args: + color_depth (tuple): the number of bits for each color component. + num_pixels (int): define the number of pixels in this interface, + this is used to define a parallel interface. + """ + assert len(color_depth) == 3 + data_width = sum(color_depth) + super(RGBStream, self).__init__(data_width=data_width+2) + + self.color_depth = color_depth + rbits, gbits, bbits = color_depth + + # a single pixel (color component) is the most + self.num_pixels = num_pixels + if num_pixels == 1: + self.red = Signal(intbv(0)[rbits:0]) + self.green = Signal(intbv(0)[gbits:0]) + self.blue = Signal(intbv(0)[rbits:0]) + # alias to the above signals, overrides data, data is + # a shadow (read-only) of the RGB attributes + self.data = ConcatSignal(self.start_of_frame, self.end_of_frame, + self.red, self.green, self.blue) + else: + self.red = Signals(intbv(0)[rbits:0], num_pixels) + self.green = Signals(intbv(0)[gbits:0], num_pixels) + self.blue = Signals(intbv(0)[rbits:0], num_pixels) + # @todo data alias for multiple pixels + raise NotImplementedError + + def copy(self): + rgb = RGBStream(color_depth=self.color_depth, + num_pixels=self.num_pixels) + return rgb + + def _assign_next(self, stream): + if isinstance(stream, RGBStream): + self.valid.next = stream.valid + self.start_of_frame.next = stream.start_of_frame + self.end_of_frame.next = stream.end_of_frame + self.red.next = stream.red + self.green.next = stream.green + self.blue.next = stream.blue + elif isinstance(stream, (DataStream, SignalType,)): + data = stream.data if isinstance(stream, DataStream) else stream + assert len(data) == len(self.data) + rbits, gbits, bbits = self.color_depth + self.blue.next = data[bbits:0] + self.green.next = data[gbits + bbits:bbits] + self.red.next = data[rbits + gbits + bbits:gbits] + self.end_of_frame.next = data[rbits] + self.start_of_frame.next = data[rbits + 1] + else: + raise TypeError("Invalid stream type {}".format(type(stream))) + + @myhdl.block + def assign(self, stream, clock=None): + # @todo this should be identical to _assign_next + # but the assignments need to be wrapped in a myhdl always decorator + + # @todo: maybe make these external modules and name the instances + # if RGBStream: + # inst = rgb_assign_rgbstream(stream, clock) + # elif DataStream, SignalType + # inst = rgb_assign_data(data, color_depth, clock) + # inst.name = self.name + if isinstance(stream, RGBStream): + @self.always_deco(clock) + def beh_assign(): + pass + elif isinstance(stream (DataStream, SignalType)): + data = stream.data if isinstance(stream, DataStream) else stream + assert len(data) == len(self.data) + rbits, gbits, bbits = self.color_depth + + @self.always_deco(clock) + def beh_assign(): + pass + else: + raise TypeError("Invalid stream type {}".format(type(stream))) + + raise NotImplementedError + + return beh_assign diff --git a/jpegenc/interfaces/ycbcrstream.py b/jpegenc/interfaces/ycbcrstream.py new file mode 100644 index 0000000..b88ea20 --- /dev/null +++ b/jpegenc/interfaces/ycbcrstream.py @@ -0,0 +1,34 @@ + +import myhdl +from myhdl import Signal, intbv, ConcatSignal +from .pixelstream import PixelStream + + +class YCbCrStream(PixelStream): + def __init__(self, color_depth=(8, 8, 8)): + """A y-cb-cr pixel stream. + + Args: + color_depth (tuple): the number of bits for each color component + """ + assert len(color_depth) == 3 + data_width = sum(color_depth) + + super(YCbCrStream, self).__init__(data_width=data_width) + + ybits, cbbits, crbits = color_depth + self.y = Signal(intbv(0)[ybits:]) + self.cb = Signal(intbv(0)[cbbits:]) + self.cr = Signal(intbv(0)[crbits:]) + + # alias to the above color signals + self.data = ConcatSignal(self.y, self.cb, self.cr) + + def copy(self): + raise NotImplementedError + + def _assign_next(self, stream): + raise NotImplementedError + + def assign(self, ds, clock=None): + raise NotImplementedError diff --git a/jpegenc/models/__init__.py b/jpegenc/models/__init__.py index 1fd6935..5995a33 100644 --- a/jpegenc/models/__init__.py +++ b/jpegenc/models/__init__.py @@ -1,7 +1,3 @@ -from .owb import ObjectWithBlocks - -from .interfaces import DataStream -from .interfaces import RGBStream from .processing import ProcessingSubblock diff --git a/jpegenc/models/interfaces.py b/jpegenc/models/interfaces.py index f4d3b3b..93a269c 100644 --- a/jpegenc/models/interfaces.py +++ b/jpegenc/models/interfaces.py @@ -11,259 +11,13 @@ """ -from random import randint - import myhdl -from myhdl import (Signal, SignalType, ResetSignal, ConcatSignal, intbv, - always_seq, always, always_comb, ) -from myhdl import instance, delay, StopSimulation -from myhdl.conversion import verify - +from myhdl import Signal, ConcatSignal, intbv, always_comb try: from rhea import Signals, assign except ImportError: from .useful_things import Signals, assign -from . import ObjectWithBlocks - -# @todo: refactor each of the interfaces to their own module -# There is a fair amount of documentation with the interfaces. -# Having the interfaces in their own file (python.module) makes -# it easier to navigate - - -class DataStream(ObjectWithBlocks): - def __init__(self, data_width=24): - """Data stream with ready-valid flow control. - - The "next" property can only be used in simulation, it is - not convertible! - """ - self.data_width = data_width - self.data = Signal(intbv(0)[data_width:0]) - self.valid = Signal(bool(0)) - self.ready = Signal(bool(0)) - super(DataStream, self).__init__(name='datastream') - - @property - def next(self): - return None - - @next.setter - def next(self, ds): - self._assign_next(ds) - - def _assign_next(self, stream): - """Simulation assign only (see next) - """ - assert isinstance(stream, DataStream) - self.data.next = stream.data - self.valid.next = stream.valid - - def copy(self): - ds = DataStream(data_width=self.data_width) - return ds - - @staticmethod - def always_deco(clock=None): - if clock is None: - deco = always_comb - else: - deco = always(clock.posedge) - - return deco - - @myhdl.block - def monitor(self): - """ - In the current myhdl tracing there are some limitations - that prevent most of the signals not to be traced in - the interfaces. This block will trace the signals in - the interface. - """ - # @todo: there is an odd issue with this and myhdl 1.0dev - mdata = Signal(intbv(0)[len(self.data):0]) - mvalid = Signal(bool(0)) - mready = Signal(bool(0)) - - @always_comb - def mon_interface_attrs(): - mdata.next = self.data - mvalid.next = self.valid - mready.next = self.ready - - return mon_interface_attrs - - @myhdl.block - def assign(self, ds, clock=None): - """Assign another datastream to this datastream - This assign block needs to be used in convertible in place - of the `next` attribute. - - Args: - ds (DataStream): the datastream to assign from - clock (Signal): system clock, optional - - This needs to be implemented for each interface that uses - DataStream as a base class. In subclasses the `data` field - is read-only (shadow), the lower bits are the data bits and - upper bits of the data field are additional control and meta - data. - - myhdl convertible - """ - assert isinstance(ds, DataStream) - - @self.always_deco(clock) - def beh_assign(): - self.data.next = ds.data - self.ready.next = ds.ready - self.valid.next = ds.valid - - return beh_assign - - -class PixelStream(DataStream): - def __init__(self, data_width=24): - """Pixel stream.""" - self.start_of_frame = Signal(bool(0)) - self.end_of_frame = Signal(bool(0)) - self.pixel = Signal(intbv(0)[data_width:0]) - super(PixelStream, self).__init__(data_width+2) - - # override the data to be a shadow (read-only) - self.data = ConcatSignal(self.start_of_frame, - self.end_of_frame, - self.pixel) - - def _assign_next(self, stream): - assert isinstance(stream, PixelStream) - self.pixel.next = stream.pixel - self.valid.next = stream.valid - self.start_of_frame.next = stream.start_of_frame - self.end_of_frame.next = stream.end_of_frame - - def copy(self): - raise NotImplementedError - - -class RGBStream(PixelStream): - def __init__(self, color_depth=(8, 8, 8), num_pixels=1): - """A red-green-blue pixel stream. - Args: - color_depth (tuple): the number of bits for each color component. - num_pixels (int): define the number of pixels in this interface, - this is used to define a parallel interface. - """ - assert len(color_depth) == 3 - data_width = sum(color_depth) - super(RGBStream, self).__init__(data_width=data_width+2) - - self.color_depth = color_depth - rbits, gbits, bbits = color_depth - - # a single pixel (color component) is the most - self.num_pixels = num_pixels - if num_pixels == 1: - self.red = Signal(intbv(0)[rbits:0]) - self.green = Signal(intbv(0)[gbits:0]) - self.blue = Signal(intbv(0)[rbits:0]) - # alias to the above signals, overrides data, data is - # a shadow (read-only) of the RGB attributes - self.data = ConcatSignal(self.start_of_frame, self.end_of_frame, - self.red, self.green, self.blue) - else: - self.red = Signals(intbv(0)[rbits:0], num_pixels) - self.green = Signals(intbv(0)[gbits:0], num_pixels) - self.blue = Signals(intbv(0)[rbits:0], num_pixels) - # @todo data alias for multiple pixels - raise NotImplementedError - - def copy(self): - rgb = RGBStream(color_depth=self.color_depth, - num_pixels=self.num_pixels) - return rgb - - def _assign_next(self, stream): - if isinstance(stream, RGBStream): - self.valid.next = stream.valid - self.start_of_frame.next = stream.start_of_frame - self.end_of_frame.next = stream.end_of_frame - self.red.next = stream.red - self.green.next = stream.green - self.blue.next = stream.blue - elif isinstance(stream, (DataStream, SignalType,)): - data = stream.data if isinstance(stream, DataStream) else stream - assert len(data) == len(self.data) - rbits, gbits, bbits = self.color_depth - self.blue.next = data[bbits:0] - self.green.next = data[gbits + bbits:bbits] - self.red.next = data[rbits + gbits + bbits:gbits] - self.end_of_frame.next = data[rbits] - self.start_of_frame.next = data[rbits + 1] - else: - raise TypeError("Invalid stream type {}".format(type(stream))) - - @myhdl.block - def assign(self, stream, clock=None): - # @todo this should be identical to _assign_next - # but the assignments need to be wrapped in a myhdl always decorator - - # @todo: maybe make these external modules and name the instances - # if RGBStream: - # inst = rgb_assign_rgbstream(stream, clock) - # elif DataStream, SignalType - # inst = rgb_assign_data(data, color_depth, clock) - # inst.name = self.name - if isinstance(stream, RGBStream): - @self.always_deco(clock) - def beh_assign(): - pass - elif isinstance(stream (DataStream, SignalType)): - data = stream.data if isinstance(stream, DataStream) else stream - assert len(data) == len(self.data) - rbits, gbits, bbits = self.color_depth - - @self.always_deco(clock) - def beh_assign(): - pass - else: - raise TypeError("Invalid stream type {}".format(type(stream))) - - raise NotImplementedError - - return beh_assign - - -class YCbCrStream(PixelStream): - def __init__(self, color_depth=(8, 8, 8)): - """A y-cb-cr pixel stream. - - Args: - color_depth (tuple): the number of bits for each color component - """ - assert len(color_depth) == 3 - data_width = sum(color_depth) - - super(YCbCrStream, self).__init__(data_width=data_width) - - ybits, cbbits, crbits = color_depth - self.y = Signal(intbv(0)[ybits:]) - self.cb = Signal(intbv(0)[cbbits:]) - self.cr = Signal(intbv(0)[crbits:]) - - # alias to the above color signals - self.data = ConcatSignal(self.y, self.cb, self.cr) - - def copy(self): - raise NotImplementedError - - def _assign_next(self, stream): - raise NotImplementedError - - def assign(self, ds, clock=None): - raise NotImplementedError - class DataBlock(object): def __init__(self, size=8, min=0, max=8): diff --git a/jpegenc/models/processing.py b/jpegenc/models/processing.py index 6295085..111db5c 100644 --- a/jpegenc/models/processing.py +++ b/jpegenc/models/processing.py @@ -4,14 +4,11 @@ import traceback import myhdl -from myhdl import Signal, intbv, instance, always_comb -from rhea import Global, Clock, Signals +from myhdl import Signal, instance, always_comb -from .interfaces import DataStream, RGBStream +from jpegenc.interfaces import ObjectWithBlocks, DataStream from .buffers import FIFOReadyValid -from . import ObjectWithBlocks - class ProcessingSubblock(ObjectWithBlocks): def __init__(self, cycles_to_process=1, pipelined=False, block_size=None, buffered=False): @@ -124,9 +121,6 @@ def processing_model(): yield clock.posedge dataout.next = dataproc - # @todo: this causes a duplicate error in the - # many of the interface signals are not traced by default, - # get a bunch of monitors so the signals can be traced. mon_insts = [] for intf in (datain, dataproc, dataout): inst = intf.monitor() diff --git a/jpegenc/models/video/bitstream.py b/jpegenc/models/video/bitstream.py index 50fe74c..be7ee98 100644 --- a/jpegenc/models/video/bitstream.py +++ b/jpegenc/models/video/bitstream.py @@ -3,8 +3,7 @@ import myhdl from myhdl import Signal, instance -from .. import ObjectWithBlocks -from ..interfaces import DataStream +from jpegenc.interfaces import ObjectWithBlocks, DataStream from .video_source import VideoSource diff --git a/jpegenc/models/video/colorbars.py b/jpegenc/models/video/colorbars.py index eba5a79..c3f5030 100644 --- a/jpegenc/models/video/colorbars.py +++ b/jpegenc/models/video/colorbars.py @@ -82,7 +82,6 @@ def check_pixel(self, rgb, npixel=None): if npixel >= (nrows * ncols): npixel = 0 - def check_pixel(self, buffer, frame=0, offset=0): """Regenerate a frame and compare it to a buffer diff --git a/jpegenc/models/video/video_source.py b/jpegenc/models/video/video_source.py index 07f960d..e588f5f 100644 --- a/jpegenc/models/video/video_source.py +++ b/jpegenc/models/video/video_source.py @@ -3,10 +3,9 @@ from random import randint import myhdl -from myhdl import Signal, intbv, instance, always_comb +from myhdl import Signal, intbv, instance -from .. import ObjectWithBlocks -from ..interfaces import DataStream, RGBStream +from jpegenc.interfaces import ObjectWithBlocks, RGBStream class VideoSource(ObjectWithBlocks): diff --git a/jpegenc/subblocks/dct/dct_2d_rcd.py b/jpegenc/subblocks/dct/dct_2d_rcd.py new file mode 100644 index 0000000..c72ca94 --- /dev/null +++ b/jpegenc/subblocks/dct/dct_2d_rcd.py @@ -0,0 +1,39 @@ + +import myhdl +from rhea import Global +from jpegenc.interfaces import YCbCrStream + + +@myhdl.block +def dct2_rcd(glbl, color_in, dct_out, csb=None, cso=None): + """ DCT 2D row-column decomposition implementation. + + This block implements the DCT 2D row-column decomposition DCT-2D + [1], this block conforms to the interfaces defined for the + JPEG encoder. + + Arguments (Ports): + glbl (Global): common signals, clock, reset, enable + color_in (YCbCrStream): input color stream + dct_out (???): + csb (MemoryMapped): + cso (ControlStatus): + + Parameters: + block_size (tuple): image block size + + myhdl convertible + + [1]: A. Madisetti and A. N. Willson, "A 100 MHz 2-D 8×8 DCT/IDCT + processor for HDTV applications," in IEEE Transactions on + Circuits and Systems for Video Technology, + vol. 5, no. 2, pp. 158-165, Apr 1995. doi: 10.1109/76.388064 + URL: http://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=388064&isnumber=8802 + + """ + assert isinstance(glbl, Global) + assert isinstance(color_in, YCbCrStream) + assert isinstance(dct_out, object) + assert isinstance(csb, (type(None), )) # MemoryMapped + assert isinstance(cso, (type(None), )) # ControlStatusObject + diff --git a/jpegenc/subblocks/dct/dct_2d_rcd_par.py b/jpegenc/subblocks/dct/dct_2d_rcd_par.py new file mode 100644 index 0000000..c6dc631 --- /dev/null +++ b/jpegenc/subblocks/dct/dct_2d_rcd_par.py @@ -0,0 +1,34 @@ + +import myhdl +from rhea import Global +from jpegenc.interfaces import YCbCrStream + + +@myhdl.block +def dct2_rcd_par(glbl, color_in, dct_out, csb=None, cso=None): + """DCT 2D parallel row-column decomposition. + + This is a parallel implementation of the row-column decomposition + DCT. This is best used when a whole row from the image block + (matrix) is transferred in parallel (e.g. 8 pixels). + + Args: + glbl (Global): + color_in (YCbCrStream): + dct_out (): + csb (MemoryMapped): + cso (ControlStatusBase): + + Returns: + + """ + assert isinstance(glbl, Global) + assert isinstance(color_in, YCbCrStream) + assert isinstance(dct_out, object) + assert isinstance(csb, (type(None), )) # MemoryMapped + assert isinstance(cso, (type(None), )) # ControlStatusObject + + # @todo: add a warning if the number of pixels in the input + # interfaces is less than the + + diff --git a/tests/test_models/test_002_bd.py b/tests/test_models/test_002_bd.py index 1d0f137..c982605 100644 --- a/tests/test_models/test_002_bd.py +++ b/tests/test_models/test_002_bd.py @@ -5,7 +5,7 @@ from myhdl import instance, delay, StopSimulation from rhea import Global, Clock -from jpegenc.models import DataStream +from jpegenc.interfaces import DataStream from jpegenc.models.video import BitstreamDevourer from jpegenc.testing import run_testbench diff --git a/tests/test_models/test_003_pe.py b/tests/test_models/test_003_pe.py index 4fc8d4b..d8d6bc2 100644 --- a/tests/test_models/test_003_pe.py +++ b/tests/test_models/test_003_pe.py @@ -3,7 +3,7 @@ from myhdl import instance, delay, StopSimulation from rhea import Global, Clock -from jpegenc.models import DataStream +from jpegenc.interfaces import DataStream from jpegenc.models import ProcessingSubblock from jpegenc.models.video import ColorBars from jpegenc.models.video import BitstreamDevourer diff --git a/tests/test_models/test_004_pe.py b/tests/test_models/test_004_pe.py index edfd716..8ee69d6 100644 --- a/tests/test_models/test_004_pe.py +++ b/tests/test_models/test_004_pe.py @@ -3,7 +3,7 @@ from myhdl import instance, delay, StopSimulation from rhea import Global, Clock -from jpegenc.models import DataStream +from jpegenc.interfaces import DataStream from jpegenc.models import ProcessingSubblock from jpegenc.models.video import ColorBars from jpegenc.models.video import BitstreamDevourer From 27e5993ebdf3bf33aa4bc582d8a6b14017e1cf20 Mon Sep 17 00:00:00 2001 From: Christopher Felton Date: Sat, 22 Oct 2016 10:25:44 -0500 Subject: [PATCH 22/32] added a stub for dct data flow model --- jpegenc/models/subblocks/__init__.py | 2 ++ jpegenc/models/subblocks/dct_2d_rcd.py | 23 +++++++++++++++++++++++ 2 files changed, 25 insertions(+) create mode 100644 jpegenc/models/subblocks/__init__.py create mode 100644 jpegenc/models/subblocks/dct_2d_rcd.py diff --git a/jpegenc/models/subblocks/__init__.py b/jpegenc/models/subblocks/__init__.py new file mode 100644 index 0000000..e4a35f4 --- /dev/null +++ b/jpegenc/models/subblocks/__init__.py @@ -0,0 +1,2 @@ + +from .dct_2d_rcd import DCTDataFlow \ No newline at end of file diff --git a/jpegenc/models/subblocks/dct_2d_rcd.py b/jpegenc/models/subblocks/dct_2d_rcd.py new file mode 100644 index 0000000..fe9e74b --- /dev/null +++ b/jpegenc/models/subblocks/dct_2d_rcd.py @@ -0,0 +1,23 @@ + +from .. import ProcessingSubblock + + +class DCTDataFlow(ProcessingSubblock): + def __init__(self, block_size=(8, 8)): + """Emulate the dataflow of a row-column decomposition DCT. + + Args: + block_size (tuple: + """ + ncyc = 2 * block_size[0] * block_size[0] + self.ctp = ncyc + self.pipe = True + + # @todo: output should be buffered, not inpput + super(DCTDataFlow, self).__init__( + cycles_to_process=self.ctp, + pipelined=self.pipe, + block_size=block_size, + buffered=False + ) + From 7adfd1084578f5a6cf99db2ff7a644fc7ca3a4c5 Mon Sep 17 00:00:00 2001 From: Christopher Felton Date: Sat, 22 Oct 2016 10:42:18 -0500 Subject: [PATCH 23/32] code cleanup --- jpegenc/testing/cosim/jpeg_prep_cosim.py | 68 +++++++++++------------- jpegenc/testing/cosim/jpeg_roms.py | 6 +-- jpegenc/testing/cosim/jpeg_v1_intf.py | 18 +++---- jpegenc/testing/cosim/jpeg_v2_intf.py | 28 +++++----- jpegenc/testing/cosim/jpegenc_v1_top.py | 5 +- jpegenc/testing/cosim/opb.py | 11 ++-- 6 files changed, 62 insertions(+), 74 deletions(-) diff --git a/jpegenc/testing/cosim/jpeg_prep_cosim.py b/jpegenc/testing/cosim/jpeg_prep_cosim.py index ddbb212..c4110bb 100644 --- a/jpegenc/testing/cosim/jpeg_prep_cosim.py +++ b/jpegenc/testing/cosim/jpeg_prep_cosim.py @@ -1,11 +1,9 @@ - from __future__ import print_function, division, absolute_import import os from argparse import Namespace -from myhdl import * -from .jpeg_filelist import filelist_v1 -from .jpeg_filelist import filelist_v2 + +from myhdl import Signal, ResetSignal, Cosimulation def prep_cosim(clock, reset, jpgv1, jpgv2, args=None): @@ -53,48 +51,48 @@ def prep_cosim(clock, reset, jpgv1, jpgv2, args=None): print("cosimulation setup ...") dstr = "-lxt2 " if args.vtrace else "-none " - cmd = "vvp -m ./myhdl.vpi jpegenc %s" % (dstr) + cmd = "vvp -m ./myhdl.vpi jpegenc %s" % (dstr,) gcosim = Cosimulation( cmd, clock=clock, reset=reset, - + # encoder 1 (V1, design1) j1_iram_wdata=jpgv1.iram_wdata, j1_iram_wren=jpgv1.iram_wren, - j1_iram_fifo_afull = jpgv1.iram_fifo_afull, - j1_ram_byte = jpgv1.ram_byte, - j1_ram_wren = jpgv1.ram_wren, - j1_ram_wraddr = jpgv1.ram_wraddr, - j1_almost_full = jpgv1.almost_full, - j1_frame_size = jpgv1.frame_size, - - j1_opb_abus = jpgv1.opb.ABus, - j1_opb_be = jpgv1.opb.BE, - j1_opb_dbus_in = jpgv1.opb.DBus_in, - j1_opb_rnw = jpgv1.opb.RNW, - j1_opb_select = jpgv1.opb.select, - j1_opb_dbus_out = jpgv1.opb.DBus_out, - j1_opb_xferack = jpgv1.opb.XferAck, - j1_opb_retry = jpgv1.opb.retry, - j1_opb_toutsup = jpgv1.opb.toutSup, - j1_opb_errack = jpgv1.opb.errAck, + j1_iram_fifo_afull=jpgv1.iram_fifo_afull, + j1_ram_byte=jpgv1.ram_byte, + j1_ram_wren=jpgv1.ram_wren, + j1_ram_wraddr=jpgv1.ram_wraddr, + j1_almost_full=jpgv1.almost_full, + j1_frame_size=jpgv1.frame_size, + + j1_opb_abus=jpgv1.opb.ABus, + j1_opb_be=jpgv1.opb.BE, + j1_opb_dbus_in=jpgv1.opb.DBus_in, + j1_opb_rnw=jpgv1.opb.RNW, + j1_opb_select=jpgv1.opb.select, + j1_opb_dbus_out=jpgv1.opb.DBus_out, + j1_opb_xferack=jpgv1.opb.XferAck, + j1_opb_retry=jpgv1.opb.retry, + j1_opb_toutsup=jpgv1.opb.toutSup, + j1_opb_errack=jpgv1.opb.errAck, # encoder 2 (V2, design2) - j2_eof = jpgv2.end_of_file_signal, - j2_en = jpgv2.enable, - j2_dati = jpgv2.data_in, - j2_bits = jpgv2.jpeg_bitstream, - j2_rdy = jpgv2.data_ready, - j2_eof_cnt = jpgv2.end_of_file_bitstream_count, - j2_eof_p = jpgv2.eof_data_partial_ready + j2_eof=jpgv2.end_of_file_signal, + j2_en=jpgv2.enable, + j2_dati=jpgv2.data_in, + j2_bits=jpgv2.jpeg_bitstream, + j2_rdy=jpgv2.data_ready, + j2_eof_cnt=jpgv2.end_of_file_bitstream_count, + j2_eof_p=jpgv2.eof_data_partial_ready # encoder (future versions) ) return gcosim - + if __name__ == '__main__': args = Namespace( @@ -105,8 +103,6 @@ def prep_cosim(clock, reset, jpgv1, jpgv2, args=None): vtrace_level=0, # Verilog VCD dumpvars level vtrace_module='tb_jpegenc', # Verilog VCD dumpvars module to trace ) - - prep_cosim(Signal(bool(0)), - ResetSignal(0, 0, False), - None, None, - args) + + prep_cosim(Signal(bool(0)), ResetSignal(0, 0, False), + None, None, args) diff --git a/jpegenc/testing/cosim/jpeg_roms.py b/jpegenc/testing/cosim/jpeg_roms.py index 8d8463a..7cdf135 100644 --- a/jpegenc/testing/cosim/jpeg_roms.py +++ b/jpegenc/testing/cosim/jpeg_roms.py @@ -1,7 +1,6 @@ # luminance table -rom_lum = \ -[ +rom_lum = [ # 100% @ 0x00 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, @@ -45,8 +44,7 @@ # chrominance table -rom_chr = \ -[ +rom_chr = [ # 100% @ 0x00 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, diff --git a/jpegenc/testing/cosim/jpeg_v1_intf.py b/jpegenc/testing/cosim/jpeg_v1_intf.py index c2474ea..f7f8b82 100644 --- a/jpegenc/testing/cosim/jpeg_v1_intf.py +++ b/jpegenc/testing/cosim/jpeg_v1_intf.py @@ -4,18 +4,15 @@ import datetime import struct -from PIL import Image +import myhdl +from myhdl import Signal, SignalType, intbv, instance, concat -from myhdl import * - -from .signal_queue import SignalQueue from .opb import OPBBus from .jpeg_intf import JPEGEnc from .jpeg_roms import rom_lum, rom_chr class JPEGEncV1(JPEGEnc): - def __init__(self, clock, reset, args=None): """ """ @@ -116,7 +113,7 @@ def t_bus_in(): print("V1: encode image %s %d x %d" % (str(img), nx, ny,)) self.img_size = img.size - self.encode_start_time = now() + self.encode_start_time = myhdl.now() for yy in range(0, ny): for xx in range(0, nx): self.iram_wren.next = False @@ -148,7 +145,7 @@ def t_bus_in(): yield self.clock.posedge # at this point the next frame can be sent - self.encode_end_time = now() + self.encode_end_time = myhdl.now() # display the max frame rate dt = self.encode_end_time - self.encode_start_time self.max_frame_rate = 1/(dt * 1e-9) @@ -179,19 +176,18 @@ def t_bus_out(): word = (word << 8) | nb ii += 1 # when 4 bytes received save it - if (ii%4) == 0: + if (ii % 4) == 0: self._bitstream.append(word) nwords += 1 - if nwords%Ncyc == 0: + if nwords % Ncyc == 0: print("V1: %6d output, latest %08X" % (nwords, self._bitstream[-1],)) # write this word to the file fword = struct.pack('>L', word) - #print("V1: {:08X}, {}".format(word, fword)) + # print("V1: {:08X}, {}".format(word, fword)) jfp.write(fword) word = 0 - #if ii > 10: if ((self.nout > 0 and ii >= self.nout) or self._enc_done): yield self._outq.put(self._bitstream) do_capture = False diff --git a/jpegenc/testing/cosim/jpeg_v2_intf.py b/jpegenc/testing/cosim/jpeg_v2_intf.py index 43c0f0b..d1be89e 100644 --- a/jpegenc/testing/cosim/jpeg_v2_intf.py +++ b/jpegenc/testing/cosim/jpeg_v2_intf.py @@ -4,11 +4,9 @@ import datetime import struct -from PIL import Image +import myhdl +from myhdl import Signal, SignalType, ResetSignal, intbv, instance -from myhdl import * - -from .signal_queue import SignalQueue from .jpeg_intf import JPEGEnc @@ -22,13 +20,13 @@ def __init__(self, clock, reset, args=None): # ---[encoder interface]--- # the default interface (Signals) to the jpeg encoder - self.end_of_file_signal = Signal(bool(0)) # input - self.enable = Signal(bool(0)) # input - self.data_in = Signal(intbv(0)[24:]) # input - self.jpeg_bitstream = Signal(intbv(0)[32:]) # output - self.data_ready = Signal(bool(0)) # output - self.end_of_file_bitstream_count = Signal(intbv(0)[5:]) # output - self.eof_data_partial_ready = Signal(bool(0)) # output + self.end_of_file_signal = Signal(bool(0)) # input + self.enable = Signal(bool(0)) # input + self.data_in = Signal(intbv(0)[24:]) # input + self.jpeg_bitstream = Signal(intbv(0)[32:]) # output + self.data_ready = Signal(bool(0)) # output + self.end_of_file_bitstream_count = Signal(intbv(0)[5:]) # output + self.eof_data_partial_ready = Signal(bool(0)) # output # set the encoder parameters self.block_size = (8,8,) @@ -56,7 +54,7 @@ def t_bus_in(): print("V2: encode image %s %d x %d" % (str(img), nx, ny,)) self.img_size = img.size - self.encode_start_time = now() + self.encode_start_time = myhdl.now() for yy in range(0, ny, 8): for xx in range(0, nx, 8): self.enable.next = True @@ -68,7 +66,7 @@ def t_bus_in(): # send the 8x8 block for yb in range(8): for xb in range(8): - r,g,b = img.getpixel((xx+xb,yy+yb,)) + r, g, b = img.getpixel((xx+xb,yy+yb,)) self.data_in.next[24:16] = b self.data_in.next[16:8] = g self.data_in.next[8:0] = r @@ -83,7 +81,7 @@ def t_bus_in(): yield self.clock.posedge # at this point the next frame can be sent - self.encode_end_time = now() + self.encode_end_time = myhdl.now() dt = self.encode_end_time - self.encode_start_time self.max_frame_rate = 1/(dt * 1e-9) print("V2: max frame rate %8.3f frames/sec" % (self.max_frame_rate,)) @@ -129,7 +127,7 @@ def t_bus_out(): jfp.write(fword) if ((self.nout > 0 and ii >= self.nout) or - self.eof_data_partial_ready): + self.eof_data_partial_ready): yield self._outq.put(self._bitstream) do_capture = False diff --git a/jpegenc/testing/cosim/jpegenc_v1_top.py b/jpegenc/testing/cosim/jpegenc_v1_top.py index 40f72e0..a81d376 100644 --- a/jpegenc/testing/cosim/jpegenc_v1_top.py +++ b/jpegenc/testing/cosim/jpegenc_v1_top.py @@ -44,7 +44,7 @@ def beh_data_input(): iram_wren.next = True bytecnt.next = 0 elif datain_valid: - if bytecnt == 2: + if bytecnt == 2: iram_wdata.next[24:16] = datain bytecnt.next = 3 elif bytecnt == 1: @@ -132,10 +132,11 @@ def beh_stub(): """ + def convert(): portmap = jpegenc_top.portmap myhdl.toVerilog(jpegenc_top, **portmap) if __name__ == '__main__': - convert() \ No newline at end of file + convert() diff --git a/jpegenc/testing/cosim/opb.py b/jpegenc/testing/cosim/opb.py index 8eb4157..90ef08b 100644 --- a/jpegenc/testing/cosim/opb.py +++ b/jpegenc/testing/cosim/opb.py @@ -1,6 +1,7 @@ -from myhdl import * +from myhdl import Signal, SignalType, intbv, always_comb + class OPBBus(object): def __init__(self, clock, reset): @@ -17,7 +18,6 @@ def __init__(self, clock, reset): self.toutSup = Signal(bool(0)) self.errAck = Signal(bool(0)) - def write(self, addr, data): """ write to address """ self.ABus.next = addr @@ -35,7 +35,6 @@ def write(self, addr, data): self.BE.next = 0x0 yield self.clock.posedge - def read(self, addr, rval): """ read address """ assert isinstance(rval, SignalType) @@ -55,16 +54,16 @@ def read(self, addr, rval): self.RNW.next = False yield self.clock.posedge - def interconnect(self, *per): """ """ num_per = len(per) + @always_comb - def rtl(): + def beh(): self.DBus_in.next = 0 self.XferAck.next = False for ii in range(num_per): self.DBus_in.next = self.DBus_in | per[ii].DBus_in self.XferAck.next = self.XferAck | per[ii].XferAck - return rtl \ No newline at end of file + return beh From 729a4f8d280964ead05dda05ddee1a966c74d7b7 Mon Sep 17 00:00:00 2001 From: Christopher Felton Date: Sat, 22 Oct 2016 10:54:18 -0500 Subject: [PATCH 24/32] fixed the missing file list import --- jpegenc/testing/cosim/jpeg_prep_cosim.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/jpegenc/testing/cosim/jpeg_prep_cosim.py b/jpegenc/testing/cosim/jpeg_prep_cosim.py index c4110bb..88955f0 100644 --- a/jpegenc/testing/cosim/jpeg_prep_cosim.py +++ b/jpegenc/testing/cosim/jpeg_prep_cosim.py @@ -5,12 +5,12 @@ from myhdl import Signal, ResetSignal, Cosimulation +from .jpeg_filelist import filelist_v1, filelist_v2 + def prep_cosim(clock, reset, jpgv1, jpgv2, args=None): """ """ - global filelist_v1, filelist_v2 - # build the first JPEG encoder # @note: this encoder is still being converted to # Verilog, for now just build From 85f2df46baf39a09f2a960cb27fda8d72709c49d Mon Sep 17 00:00:00 2001 From: Christopher Felton Date: Sat, 22 Oct 2016 20:57:43 -0500 Subject: [PATCH 25/32] code guideline modifications --- jpegenc/testing/cosim/jpeg_intf.py | 8 ++++---- jpegenc/testing/cosim/jpeg_roms.py | 1 + jpegenc/testing/cosim/jpeg_v1_intf.py | 21 ++++++++++----------- jpegenc/testing/cosim/jpeg_v2_intf.py | 16 ++++++++-------- jpegenc/testing/cosim/jpegenc_v1_top.py | 3 +-- jpegenc/testing/cosim/opb.py | 4 ++-- jpegenc/testing/cosim/signal_queue.py | 4 ++-- 7 files changed, 28 insertions(+), 29 deletions(-) diff --git a/jpegenc/testing/cosim/jpeg_intf.py b/jpegenc/testing/cosim/jpeg_intf.py index 70d97d3..2f35736 100644 --- a/jpegenc/testing/cosim/jpeg_intf.py +++ b/jpegenc/testing/cosim/jpeg_intf.py @@ -51,9 +51,9 @@ def _ext(self, img, N=16): """ extend an image to be a multiple of N pixels """ w, h = img.size - we, he = w+(N-w%N), h+(N-h%N) - nimg = Image.new("RGB", (we,he,)) - nimg.paste(img, (0,0,)) + we, he = w+(N-w % N), h+(N-h % N) + nimg = Image.new("RGB", (we, he,)) + nimg.paste(img, (0, 0,)) return nimg def put_image(self, img): @@ -86,4 +86,4 @@ def stream_jpg_out(self): def get_gens(self): d = self.stream_img_in() m = self.stream_jpg_out() - return d, m \ No newline at end of file + return d, m diff --git a/jpegenc/testing/cosim/jpeg_roms.py b/jpegenc/testing/cosim/jpeg_roms.py index 7cdf135..60cd52b 100644 --- a/jpegenc/testing/cosim/jpeg_roms.py +++ b/jpegenc/testing/cosim/jpeg_roms.py @@ -86,3 +86,4 @@ 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63 ] + diff --git a/jpegenc/testing/cosim/jpeg_v1_intf.py b/jpegenc/testing/cosim/jpeg_v1_intf.py index f7f8b82..e5e708d 100644 --- a/jpegenc/testing/cosim/jpeg_v1_intf.py +++ b/jpegenc/testing/cosim/jpeg_v1_intf.py @@ -36,7 +36,7 @@ def __init__(self, clock, reset, args=None): self._enc_done = Signal(bool(0)) # set the encoder parameters - self.block_size = (16,8,) + self.block_size = (16, 8,) self.nout = args.nout self.start_time = args.start_time @@ -44,17 +44,16 @@ def __init__(self, clock, reset, args=None): def initialize(self, luminance=1, chrominance=1): """ initialize the encoder - Arguments - --------- - luninance : 1, .85, .75 or .5 - chrominance : 1, .85, .75 or .5 + Arguments: + luminance: 1, .85, .75 or .5 + chrominance: 1, .85, .75 or .5 """ # lum address offset = {1: 0x00, .85: 0x40, .75: 0x80, .50: 0xC0} lbase, cbase = 64*offset[luminance], 64*offset[chrominance] # program the luminance table - for ii, off in enumerate(range(lbase,lbase+64)): + for ii, off in enumerate(range(lbase, lbase+64)): addr = 0x00000100 + ii*4 # print("[%8d] V1 init %8X --> %8X" % (now(), addr, rom_lum[off])) yield self.opb.write(addr, rom_lum[off]) @@ -66,7 +65,7 @@ def initialize(self, luminance=1, chrominance=1): def check_done(self, done): assert isinstance(done, SignalType) - dn = False + # read the status register rval = Signal(intbv(0)[32:]) yield self.opb.read(0x0C, rval) @@ -121,7 +120,7 @@ def t_bus_in(): yield self.clock.posedge # clear to write a pixel in - r, g, b = img.getpixel((xx,yy,)) + r, g, b = img.getpixel((xx, yy,)) self.iram_wren.next = True self.iram_wdata.next[24:16] = b self.iram_wdata.next[16:8] = g @@ -163,7 +162,7 @@ def stream_jpg_out(self): def t_bus_out(): ii = 0 do_capture = True - Ncyc = self.args.ncyc + ncyc = self.args.ncyc word = 0 nwords = 0 @@ -179,7 +178,7 @@ def t_bus_out(): if (ii % 4) == 0: self._bitstream.append(word) nwords += 1 - if nwords % Ncyc == 0: + if nwords % ncyc == 0: print("V1: %6d output, latest %08X" % (nwords, self._bitstream[-1],)) # write this word to the file @@ -188,7 +187,7 @@ def t_bus_out(): jfp.write(fword) word = 0 - if ((self.nout > 0 and ii >= self.nout) or self._enc_done): + if (self.nout > 0 and ii >= self.nout) or self._enc_done: yield self._outq.put(self._bitstream) do_capture = False diff --git a/jpegenc/testing/cosim/jpeg_v2_intf.py b/jpegenc/testing/cosim/jpeg_v2_intf.py index d1be89e..2d6fa82 100644 --- a/jpegenc/testing/cosim/jpeg_v2_intf.py +++ b/jpegenc/testing/cosim/jpeg_v2_intf.py @@ -5,7 +5,7 @@ import struct import myhdl -from myhdl import Signal, SignalType, ResetSignal, intbv, instance +from myhdl import Signal, intbv, instance from .jpeg_intf import JPEGEnc @@ -29,7 +29,7 @@ def __init__(self, clock, reset, args=None): self.eof_data_partial_ready = Signal(bool(0)) # output # set the encoder parameters - self.block_size = (8,8,) + self.block_size = (8, 8,) self.nout = args.nout self.start_time = args.start_time @@ -50,7 +50,7 @@ def t_bus_in(): yield self._inq.get(imglst, block=True) self.pxl_done.next = False img = imglst[0] - nx,ny = img.size + nx, ny = img.size print("V2: encode image %s %d x %d" % (str(img), nx, ny,)) self.img_size = img.size @@ -66,7 +66,7 @@ def t_bus_in(): # send the 8x8 block for yb in range(8): for xb in range(8): - r, g, b = img.getpixel((xx+xb,yy+yb,)) + r, g, b = img.getpixel((xx+xb, yy+yb,)) self.data_in.next[24:16] = b self.data_in.next[16:8] = g self.data_in.next[8:0] = r @@ -109,7 +109,7 @@ def stream_jpg_out(self): def t_bus_out(): ii = 0 do_capture = True - Ncyc = self.args.ncyc + ncyc = self.args.ncyc # capture the output from the encoder while do_capture: @@ -119,15 +119,15 @@ def t_bus_out(): word = int(self.jpeg_bitstream) self._bitstream.append(word) ii += 1 - if ii % Ncyc == 0: + if ii % ncyc == 0: print("V2: %6d output, latest %08X" % (ii, self._bitstream[-1],)) fword = struct.pack('>L', word) # print("V2: {:08X}, {}".format(word, fword)) jfp.write(fword) - if ((self.nout > 0 and ii >= self.nout) or - self.eof_data_partial_ready): + if (self.nout > 0 and ii >= self.nout or + self.eof_data_partial_ready): yield self._outq.put(self._bitstream) do_capture = False diff --git a/jpegenc/testing/cosim/jpegenc_v1_top.py b/jpegenc/testing/cosim/jpegenc_v1_top.py index a81d376..2f997ad 100644 --- a/jpegenc/testing/cosim/jpegenc_v1_top.py +++ b/jpegenc/testing/cosim/jpegenc_v1_top.py @@ -33,6 +33,7 @@ def jpegenc_top( ram_byte, ram_wren, ram_wraddr, outif_almost_full, frame_size ) + jpegenc_inst.name = 'jpegenc' bytecnt = Signal(intbv(0, min=0, max=4)) @@ -59,7 +60,6 @@ def beh_data_input(): frame_size.next = 1024 - return myhdl.instances() @@ -99,7 +99,6 @@ def beh_stub(): if opb_rnw: opb_dbus_out.next = 0 - return beh_stub diff --git a/jpegenc/testing/cosim/opb.py b/jpegenc/testing/cosim/opb.py index 90ef08b..f334f90 100644 --- a/jpegenc/testing/cosim/opb.py +++ b/jpegenc/testing/cosim/opb.py @@ -6,7 +6,7 @@ class OPBBus(object): def __init__(self, clock, reset): self.clock = clock - self.reest = reset + self.reset = reset self.ABus = Signal(intbv(0)[32:]) self.BE = Signal(intbv(0)[4:]) self.DBus_in = Signal(intbv(0)[32:]) @@ -46,7 +46,7 @@ def read(self, addr, rval): while not ack: yield self.clock.posedge ack = self.XferAck - #rval.append(self.DBus_in.val) + # rval.append(self.DBus_in.val) rval.next = self.DBus_out self.ABus.next = 0 self.select.next = False diff --git a/jpegenc/testing/cosim/signal_queue.py b/jpegenc/testing/cosim/signal_queue.py index b738e2a..fff5096 100644 --- a/jpegenc/testing/cosim/signal_queue.py +++ b/jpegenc/testing/cosim/signal_queue.py @@ -29,7 +29,7 @@ def put(self, item, block=True, timeout=None): yield delay(1) def put_nowait(self, item): - self.put(item, Block=False, timeout=None) + self.put(item, block=False, timeout=None) def get(self, item, block=True, timeout=None): assert timeout is None, "Timeout not yet implemented" @@ -47,7 +47,7 @@ def get_nowait(self, item): yield self.get(item, block=False, timeout=None) def __str__(self): - s = 'len %d, max %d'%(self.qsize(),self._max) + s = 'len %d, max %d' % (self.qsize(), self._max,) return s def __repr__(self): From 933ab2af3175c95a59d2c7d5eb87ff4b63285274 Mon Sep 17 00:00:00 2001 From: Christopher Felton Date: Sat, 22 Oct 2016 21:06:39 -0500 Subject: [PATCH 26/32] code guideline modifications --- jpegenc/interfaces/__init__.py | 6 ++++++ jpegenc/models/buffers/__init__.py | 4 ++-- jpegenc/models/subblocks/__init__.py | 4 +++- jpegenc/models/video/__init__.py | 3 +++ jpegenc/testing/cosim/jpeg_intf.py | 17 ++++++++--------- 5 files changed, 22 insertions(+), 12 deletions(-) diff --git a/jpegenc/interfaces/__init__.py b/jpegenc/interfaces/__init__.py index 9a18445..5822bf9 100644 --- a/jpegenc/interfaces/__init__.py +++ b/jpegenc/interfaces/__init__.py @@ -6,3 +6,9 @@ from .pixelstream import PixelStream from .rgbstream import RGBStream from .ycbcrstream import YCbCrStream + + +__all__ = [ + 'ObjectWithBlocks', 'DataStream', 'PixelStream', + 'RGBStream', 'YCbCrStream', +] diff --git a/jpegenc/models/buffers/__init__.py b/jpegenc/models/buffers/__init__.py index 3bf8273..6d417be 100644 --- a/jpegenc/models/buffers/__init__.py +++ b/jpegenc/models/buffers/__init__.py @@ -4,7 +4,7 @@ from .fifo_ready_valid import FIFOReadyValid # from .row_buffer import RowBuffer -from .block_buffer import PixelStream -from .block_buffer import ImageBlock from .block_buffer import mdl_block_buffer # from .block_buffer import BlockBuffer + +__all__ = ['FIFOReadyValid', 'mdl_block_buffer'] diff --git a/jpegenc/models/subblocks/__init__.py b/jpegenc/models/subblocks/__init__.py index e4a35f4..9a33881 100644 --- a/jpegenc/models/subblocks/__init__.py +++ b/jpegenc/models/subblocks/__init__.py @@ -1,2 +1,4 @@ -from .dct_2d_rcd import DCTDataFlow \ No newline at end of file +from .dct_2d_rcd import DCTDataFlow + +__all__ = ['DCTDataFlow'] diff --git a/jpegenc/models/video/__init__.py b/jpegenc/models/video/__init__.py index dc8d6d6..8db6069 100644 --- a/jpegenc/models/video/__init__.py +++ b/jpegenc/models/video/__init__.py @@ -1,3 +1,6 @@ from .colorbars import ColorBars from .bitstream import BitstreamDevourer + +__all__ = ['ColorBars', 'BitstreamDevourer',] + diff --git a/jpegenc/testing/cosim/jpeg_intf.py b/jpegenc/testing/cosim/jpeg_intf.py index 2f35736..9307d07 100644 --- a/jpegenc/testing/cosim/jpeg_intf.py +++ b/jpegenc/testing/cosim/jpeg_intf.py @@ -2,16 +2,15 @@ from PIL import Image -from myhdl import * +from myhdl import Signal, intbv from .signal_queue import SignalQueue class JPEGEnc(object): - def __init__(self, clock, reset, args=None): + def __init__(self, clock, reset): + """An interface to the Verilog JPEG encoders. """ - """ - # @todo: the following parameters should be part of the args self.pixel_nbits = 24 self.block_size = (8, 8,) @@ -47,11 +46,11 @@ def __init__(self, clock, reset, args=None): self.encode_start_time = 0 self.encode_end_time = 0 - def _ext(self, img, N=16): + def _ext(self, img, n=16): """ extend an image to be a multiple of N pixels """ w, h = img.size - we, he = w+(N-w % N), h+(N-h % N) + we, he = w+(n-w % n), h+(n-h % n) nimg = Image.new("RGB", (we, he,)) nimg.paste(img, (0, 0,)) return nimg @@ -60,7 +59,7 @@ def put_image(self, img): """ put an image to stream into the encoder """ assert img.mode == 'RGB' - nimg = self._ext(img, N=16) + nimg = self._ext(img, n=16) self._bitstream = [] yield self._inq.put(nimg) yield self.clock.posedge @@ -77,11 +76,11 @@ def get_jpeg(self, bic): def stream_img_in(self): """ stream image in adapter """ - raise NotImplemented + raise NotImplementedError def stream_jpg_out(self): """ stream jpeg bitstream out """ - raise NotImplemented + raise NotImplementedError def get_gens(self): d = self.stream_img_in() From c059c00087fd4bd36fb9c65e4002b99cbe9726a2 Mon Sep 17 00:00:00 2001 From: Christopher Felton Date: Sat, 22 Oct 2016 21:19:29 -0500 Subject: [PATCH 27/32] code guideline modifications --- jpegenc/models/__init__.py | 2 + jpegenc/models/buffers/block_buffer.py | 46 +++++++++---------- jpegenc/testing/cosim/__init__.py | 7 ++- .../testing/cosim/jpeg_compare_bitstreams.py | 7 ++- 4 files changed, 35 insertions(+), 27 deletions(-) diff --git a/jpegenc/models/__init__.py b/jpegenc/models/__init__.py index 5995a33..8bc9350 100644 --- a/jpegenc/models/__init__.py +++ b/jpegenc/models/__init__.py @@ -1,3 +1,5 @@ from .processing import ProcessingSubblock + +__all__ = ['ProcessingSubblock'] diff --git a/jpegenc/models/buffers/block_buffer.py b/jpegenc/models/buffers/block_buffer.py index a51ca78..8c5d92f 100644 --- a/jpegenc/models/buffers/block_buffer.py +++ b/jpegenc/models/buffers/block_buffer.py @@ -2,16 +2,16 @@ from __future__ import print_function, division from math import ceil -from random import randint import myhdl from myhdl import Signal, intbv, always class PixelStream(object): - """ Pixel stream interface - """ def __init__(self, resolution=(640, 480,), pformat=(8, 8, 8)): + """ Pixel stream interface + """ + # @todo: merge this with jpegenc.interfaces.pixelstream.py self.resolution = resolution self.pformat = pformat self.width = sum(pformat) @@ -42,18 +42,17 @@ class ImageBlock(object): def __init__(self, pxl, block_size=(9, 9)): pw = pxl.width - V, H = pxl.resolution - M, N = block_size + v, h = pxl.resolution + m, n = block_size self.block_size = block_size self.pixel = Signal(intbv(0)[pw:]) - self.row = Signal(intbv(0, min=0, max=M)) - self.col = Signal(intbv(0, min=0, max=N)) + self.row = Signal(intbv(0, min=0, max=m)) + self.col = Signal(intbv(0, min=0, max=n)) # number of blocks in a buffer, number of blocks in a row - self.blocks_per_buffer = H//N - self.block_num = Signal(intbv(0, min=0, - max=self.blocks_per_buffer)) + self.blocks_per_buffer = bpb = h//n + self.block_num = Signal(intbv(0, min=0, max=bpb)) def _dump_info(resolution, block_size, pwidth): @@ -67,10 +66,10 @@ def _dump_info(resolution, block_size, pwidth): :return bytes: :return mem_bytes: """ - V, H = resolution - M, N = block_size - bytes = int(ceil(pwidth / 8)) - mem_bytes = 2 * M * H * bytes + v, h = resolution + m, n = block_size + bytez = int(ceil(pwidth / 8)) + mem_bytes = 2 * m * h * bytez print("Memory requirements:") print(" {:d} bytes for double buffer".format(mem_bytes)) @@ -86,26 +85,25 @@ def mdl_block_buffer(pxl, bmem): row (line) at a time. The buffer needs to store M rows into memory - - :param pxl: input pixel stream interface - :param bmem: block memory interface - :return: + Args: + pxl: input pixel stream interface + bmem: block memory interface """ block_size = bmem.block_size pw = pxl.width # pixel width - V, H = pxl.resolution # video stream resolution - M, N = block_size # block size + v, h = pxl.resolution # video stream resolution + m, n = block_size # block size # dump information - bytes, mb = _dump_info(pxl.resolution, block_size, pw) + bytez, mb = _dump_info(pxl.resolution, block_size, pw) # memory buffers, double buffered - num_pixels = M*H + num_pixels = m * h line_buffer_a = [Signal(intbv(0)[pw:]) for _ in range(num_pixels)] line_buffer_b = [Signal(intbv(0)[pw:]) for _ in range(num_pixels)] anotb = Signal(bool(0)) - ccnt = Signal(intbv(0, min=0, max=M*H)) + ccnt = Signal(intbv(0, min=0, max=m*h)) # input double buffer, capture the stream @always(pxl.clock.posedge) @@ -116,7 +114,7 @@ def mdl_input_capture(): else: line_buffer_b[ccnt].next = pxl.pixel - if ccnt == num_pixels-1: + if ccnt == num_pixels - 1: ccnt.next = 0 anotb.next = not anotb else: diff --git a/jpegenc/testing/cosim/__init__.py b/jpegenc/testing/cosim/__init__.py index bdbdb8f..e461092 100644 --- a/jpegenc/testing/cosim/__init__.py +++ b/jpegenc/testing/cosim/__init__.py @@ -5,6 +5,9 @@ from .jpeg_v1_intf import JPEGEncV1 from .jpeg_v2_intf import JPEGEncV2 -from .jpegenc_v1_top import convert as convertv1 - from .utils import set_default_args, get_cli_args + +__all__ = [ + 'prep_cosim', 'JPEGEncV1', 'JPEGEncV2', + 'set_default_args', 'get_cli_args', +] diff --git a/jpegenc/testing/cosim/jpeg_compare_bitstreams.py b/jpegenc/testing/cosim/jpeg_compare_bitstreams.py index 0e6c7af..60e0b59 100644 --- a/jpegenc/testing/cosim/jpeg_compare_bitstreams.py +++ b/jpegenc/testing/cosim/jpeg_compare_bitstreams.py @@ -1,5 +1,6 @@ from __future__ import division, print_function +import os from PIL import Image @@ -8,5 +9,9 @@ def compare_bitstreams(ipth, bitstreams): This function will compare the generated bit-streams with the software generated JPEG bitstream from the original file. """ - pass + if os.path.isfile(ipth): + img = Image(ipth) + + # @todo: complete this function, the following is not valid + assert img == bitstreams From 0b1ce9544e9751bb24f73e5c80e936290245a0bd Mon Sep 17 00:00:00 2001 From: Christopher Felton Date: Sat, 22 Oct 2016 21:20:40 -0500 Subject: [PATCH 28/32] code guideline modifications --- jpegenc/models/buffers/__init__.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/jpegenc/models/buffers/__init__.py b/jpegenc/models/buffers/__init__.py index 6d417be..672a4d3 100644 --- a/jpegenc/models/buffers/__init__.py +++ b/jpegenc/models/buffers/__init__.py @@ -4,7 +4,8 @@ from .fifo_ready_valid import FIFOReadyValid # from .row_buffer import RowBuffer +from .block_buffer import PixelStream from .block_buffer import mdl_block_buffer # from .block_buffer import BlockBuffer -__all__ = ['FIFOReadyValid', 'mdl_block_buffer'] +__all__ = ['FIFOReadyValid', 'PixelStream', 'mdl_block_buffer'] From 42550fddf3283ad5fc6046849bc3de72f9e90b75 Mon Sep 17 00:00:00 2001 From: Christopher Felton Date: Sat, 22 Oct 2016 21:28:00 -0500 Subject: [PATCH 29/32] code guideline modifications --- jpegenc/models/buffers/__init__.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/jpegenc/models/buffers/__init__.py b/jpegenc/models/buffers/__init__.py index 672a4d3..b91e3c8 100644 --- a/jpegenc/models/buffers/__init__.py +++ b/jpegenc/models/buffers/__init__.py @@ -5,7 +5,8 @@ # from .row_buffer import RowBuffer from .block_buffer import PixelStream +from .block_buffer import ImageBlock from .block_buffer import mdl_block_buffer # from .block_buffer import BlockBuffer -__all__ = ['FIFOReadyValid', 'PixelStream', 'mdl_block_buffer'] +__all__ = ['FIFOReadyValid', 'PixelStream', 'ImageBlock', 'mdl_block_buffer'] From f132cd5c61279214cdb6223a8a50e4c35e904353 Mon Sep 17 00:00:00 2001 From: Christopher Felton Date: Sat, 22 Oct 2016 21:31:44 -0500 Subject: [PATCH 30/32] code guideline modifications --- jpegenc/testing/huff_inputs.py | 16 ++--- jpegenc/testing/quant_inputs.py | 10 ++- jpegenc/testing/rle_inputs.py | 113 ++++++++++++++++---------------- 3 files changed, 72 insertions(+), 67 deletions(-) diff --git a/jpegenc/testing/huff_inputs.py b/jpegenc/testing/huff_inputs.py index 5dd3d90..2b40d22 100644 --- a/jpegenc/testing/huff_inputs.py +++ b/jpegenc/testing/huff_inputs.py @@ -1,7 +1,11 @@ - +""" +Test inputs for the Huffman encoder +""" # @todo: How were these generated ??? Create a github issue -# How were these test inputs generated. These should be replaced with a -# model/function/object that generates the inputs instead of static inputs +# How were these test inputs generated. These should be replaced +# with a model/function/object that generates the inputs instead +# of static inputs + vli_test_y = [ 10, 1, 2, 4, 8, 16, 32, 65, @@ -14,7 +18,6 @@ 2, 2, 2, 2, 3, 3, 3, 2, ] - vli_size_test_y = [ 4, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, @@ -26,7 +29,6 @@ 1, 1, 1, 1, 2, 2, 2, 1, ] - runlength_test_y = [ 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 2, 1, 0, @@ -49,7 +51,6 @@ 2, 2, 2, 2, 3, 3, 3, 2, ] - vli_size_test_cb = [ 4, 1, 1, 1, 1, 1, 1, 1, 8, 2, 2, 1, 2, 3, 4, 5, @@ -61,7 +62,6 @@ 2, 2, 2, 2, 2, 2, 2, 2, ] - runlength_test_cb = [ 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 2, 1, 0, @@ -84,7 +84,6 @@ 2, 2, 2, 2, 3, 3, 3, 2, ] - vli_size_test_cr = [ 4, 1, 1, 1, 1, 1, 1, 1, 8, 1, 1, 1, 2, 3, 4, 5, @@ -96,7 +95,6 @@ 1, 1, 1, 1, 2, 2, 2, 1, ] - runlength_test_cr = [ 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 2, 1, 0, diff --git a/jpegenc/testing/quant_inputs.py b/jpegenc/testing/quant_inputs.py index 612bb73..0fb01c3 100644 --- a/jpegenc/testing/quant_inputs.py +++ b/jpegenc/testing/quant_inputs.py @@ -1,7 +1,11 @@ - +""" +Test inputs for the quantizer. +""" # @todo: How were these generated ??? Create a github issue -# How were these test inputs generated. These should be replaced with a -# model/function/object that generates the inputs instead of static inputs +# How were these test inputs generated. These should be replaced +# with a model/function/object that generates the inputs instead +# of static inputs + quant_rom = [ 16, 11, 10, 16, 24, 40, 51, 61, diff --git a/jpegenc/testing/rle_inputs.py b/jpegenc/testing/rle_inputs.py index 69f61ff..8883bc8 100755 --- a/jpegenc/testing/rle_inputs.py +++ b/jpegenc/testing/rle_inputs.py @@ -1,71 +1,74 @@ - +""" +Test inputs for the run-length encoder +""" # @todo: How were these generated ??? Create a github issue -# How were these test inputs generated. These should be replaced with a -# model/function/object that generates the inputs instead of static inputs +# How were these test inputs generated. These should be replaced +# with a model/function/object that generates the inputs instead +# of static inputs red_pixels_1 = [ - 1, 12, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 10, 2, 3, 4, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0 -] + 1, 12, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 10, 2, 3, 4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 0 +] red_pixels_2 = [ - 0, 12, 20, 0, 0, 2, 3, 4, - 0, 0, 2, 3, 4, 5, 1, 0, - 0, 0, 0, 0, 0, 0, 90, 0, - 0, 0, 0, 10, 0, 0, 0, 9, - 1, 1, 1, 1, 2, 3, 4, 5, - 1, 2, 3, 4, 1, 2, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0 -] + 0, 12, 20, 0, 0, 2, 3, 4, + 0, 0, 2, 3, 4, 5, 1, 0, + 0, 0, 0, 0, 0, 0, 90, 0, + 0, 0, 0, 10, 0, 0, 0, 9, + 1, 1, 1, 1, 2, 3, 4, 5, + 1, 2, 3, 4, 1, 2, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 +] green_pixels_1 = [ - 11, 12, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 10, 2, 3, 4, 0, - 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 1, 1, 2, 3, 4, 5, - 1, 2, 3, 4, 1, 2, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0 -] + 11, 12, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 10, 2, 3, 4, 0, + 0, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 1, 1, 2, 3, 4, 5, + 1, 2, 3, 4, 1, 2, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 0 +] green_pixels_2 = [ - 13, 12, 20, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1, - 1, 0, 0, 0, 1, 32, 4, 2 + 13, 12, 20, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1, + 1, 0, 0, 0, 1, 32, 4, 2 ] blue_pixels_1 = [ - 11, 12, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 2, 3, 4, 5, - 1, 2, 3, 4, 1, 2, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1 -] + 11, 12, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 2, 3, 4, 5, + 1, 2, 3, 4, 1, 2, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1 +] blue_pixels_2 = [ - 16, 12, 20, 0, 0, 2, 3, 4, - 0, 0, 2, 3, 4, 5, 1, 0, - 0, 0, 0, 0, 0, 0, 90, 0, - 0, 0, 0, 10, 0, 0, 0, 9, - 1, 1, 1, 1, 2, 3, 4, 5, - 1, 2, 3, 4, 1, 2, 0, 1, - 1, 0, 0, 0, 0, 0, 0, 1, - 1, 0, 0, 0, 1, 32, 4, 2 + 16, 12, 20, 0, 0, 2, 3, 4, + 0, 0, 2, 3, 4, 5, 1, 0, + 0, 0, 0, 0, 0, 0, 90, 0, + 0, 0, 0, 10, 0, 0, 0, 9, + 1, 1, 1, 1, 2, 3, 4, 5, + 1, 2, 3, 4, 1, 2, 0, 1, + 1, 0, 0, 0, 0, 0, 0, 1, + 1, 0, 0, 0, 1, 32, 4, 2 ] From dd7d06cce4fa6a65c019e51a51234e80e554446f Mon Sep 17 00:00:00 2001 From: Christopher Felton Date: Sat, 22 Oct 2016 21:56:46 -0500 Subject: [PATCH 31/32] code guideline modifications --- jpegenc/interfaces/pixelstream.py | 5 + jpegenc/interfaces/rgbstream.py | 8 +- jpegenc/interfaces/ycbcrstream.py | 5 + jpegenc/models/buffers/block_buffer.py | 15 +-- jpegenc/models/system/__init__.py | 0 jpegenc/models/system/interfaces.py | 126 ------------------ jpegenc/models/system/useful_things.py | 16 --- jpegenc/subblocks/frontend/frontend_v2.py | 71 ++++++---- jpegenc/subblocks/zig_zag/zig_zag.py | 46 +++---- .../testing/cosim/jpeg_compare_bitstreams.py | 2 +- 10 files changed, 89 insertions(+), 205 deletions(-) delete mode 100644 jpegenc/models/system/__init__.py delete mode 100644 jpegenc/models/system/interfaces.py delete mode 100644 jpegenc/models/system/useful_things.py diff --git a/jpegenc/interfaces/pixelstream.py b/jpegenc/interfaces/pixelstream.py index 21a7a86..4c1663f 100644 --- a/jpegenc/interfaces/pixelstream.py +++ b/jpegenc/interfaces/pixelstream.py @@ -1,4 +1,5 @@ +import myhdl from myhdl import Signal, intbv, ConcatSignal from .datastream import DataStream @@ -25,3 +26,7 @@ def _assign_next(self, stream): def copy(self): raise NotImplementedError + + @myhdl.block + def process(self): + raise NotImplementedError diff --git a/jpegenc/interfaces/rgbstream.py b/jpegenc/interfaces/rgbstream.py index 7ef34b1..0693ce1 100644 --- a/jpegenc/interfaces/rgbstream.py +++ b/jpegenc/interfaces/rgbstream.py @@ -82,7 +82,7 @@ def beh_assign(): elif isinstance(stream (DataStream, SignalType)): data = stream.data if isinstance(stream, DataStream) else stream assert len(data) == len(self.data) - rbits, gbits, bbits = self.color_depth + # rbits, gbits, bbits = self.color_depth @self.always_deco(clock) def beh_assign(): @@ -92,4 +92,8 @@ def beh_assign(): raise NotImplementedError - return beh_assign + # return beh_assign + + @myhdl.block + def process(self): + raise NotImplementedError diff --git a/jpegenc/interfaces/ycbcrstream.py b/jpegenc/interfaces/ycbcrstream.py index b88ea20..9fcfa80 100644 --- a/jpegenc/interfaces/ycbcrstream.py +++ b/jpegenc/interfaces/ycbcrstream.py @@ -30,5 +30,10 @@ def copy(self): def _assign_next(self, stream): raise NotImplementedError + @myhdl.block def assign(self, ds, clock=None): raise NotImplementedError + + @myhdl.block + def process(self): + raise NotImplementedError diff --git a/jpegenc/models/buffers/block_buffer.py b/jpegenc/models/buffers/block_buffer.py index 8c5d92f..a561b5f 100644 --- a/jpegenc/models/buffers/block_buffer.py +++ b/jpegenc/models/buffers/block_buffer.py @@ -36,11 +36,10 @@ def mdl_stream(): class ImageBlock(object): - """ Interface to a block of memory - This interface is used to retrieve blocks of an image - """ def __init__(self, pxl, block_size=(9, 9)): - + """ Interface to a block of memory + This interface is used to retrieve blocks of an image. + """ pw = pxl.width v, h = pxl.resolution m, n = block_size @@ -61,10 +60,10 @@ def _dump_info(resolution, block_size, pwidth): video horizontal resolution times M times the number of bytes required for a pixel times 2 (double buffered). - :param block_size: - :param pwidth: - :return bytes: - :return mem_bytes: + Args: + resolution: video resolution + block_size: the sub-image size (matrix size) + pwidth: pixel width (change to color_depth) """ v, h = resolution m, n = block_size diff --git a/jpegenc/models/system/__init__.py b/jpegenc/models/system/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/jpegenc/models/system/interfaces.py b/jpegenc/models/system/interfaces.py deleted file mode 100644 index 6c1d9dd..0000000 --- a/jpegenc/models/system/interfaces.py +++ /dev/null @@ -1,126 +0,0 @@ -""" -This example demonstrates how interfaces can be used in the 2D-DCT. -The 2D-DCT streams in a sample at a time, these samples are sent to -parallel 1D-DCT (pipelined). - -There are two interfaces used: - - ImageBlock: this represents the 2D image block that is being - transformed - - DataBlock: which is a generic parallel data interface. - -These interfaces give an example how to use a list-of-signals (LoS) - -""" - -from random import randint - -import myhdl -from myhdl import (Signal, ResetSignal, ConcatSignal, intbv, - always_seq, always_comb, ) -from myhdl import instance, delay, StopSimulation -from myhdl.conversion import verify - -try: - from rhea import Signals, assign -except ImportError: - from .useful_things import Signals, assign - - -class PixelStream(object): - def __init__(self, color_space=(8, 8, 8)): - """An red-green-blue interface """ - assert len(color_space) == 3 - rbits, gbits, bbits = color_space - self.red = Signal(intbv(0)[rbits:0]) - self.green = Signal(intbv(0)[gbits:0]) - self.blue = Signal(intbv(0)[rbits:0]) - - -class DataStream(object): - def __init__(self): - pass - - -class DataBlock(object): - def __init__(self, size=8, min=0, max=8): - """ - - Arguments: - size: the number of items to have in the block - min: the data min value - max: the data max value - """ - self.size = size - dtype = intbv(0, min=min, max=max) - self.data = Signals(dtype, size) - self.valid = Signal(bool(0)) - self.ready = Signal(bool(0)) - - -class ImageBlock(object): - def __init__(self, size=(8, 8), min=0, max=8): - """ - - Arguments: - size (tuple): - min (int): the min value of the data contained in the - matrix - max (int)L the max value of the data contained in the - matrix - - """ - assert isinstance(size, tuple) - assert len(size) == 2 - self.size = size - nrows, ncols = size - self.nitems = nrows * ncols - dtype = intbv(0, min=min, max=max) - self.nbits = len(dtype) - self.dtype = dtype - - self.mat = [Signals(dtype, ncols) for _ in range(nrows)] - - self.data = self.get_bit_vector() - self.valid = Signal(bool(0)) - self.ready = Signal(bool(0)) - - def __getitem__(self, idx): - item = None - if isinstance(idx, tuple): - item = self.mat[idx[0]][idx[1]] - - return item - - def __setitem__(self): - raise NotImplementedError - - def get_bit_vector(self): - nrows, ncols = self.size - nbits = nrows * ncols * self.nbits - sig = Signal(intbv(0)[nbits:0]) - return sig - - @myhdl.block - def stack(self, flat): - """ """ - nitems = sum(self.size) - nbits = self.nbits - assert len(flat) == nitems*nbits - # create a flat list of signals (references) - - @myhdl.block - def flatten(self, flat): - """ """ - nbits = self.nbits - shadowbits = [col(nbits, 0) for row in self.mat for col in row] - flats = ConcatSignal(*shadowbits) - - @always_comb - def beh_assign(): - flat.next = flats - - return beh_assign - - diff --git a/jpegenc/models/system/useful_things.py b/jpegenc/models/system/useful_things.py deleted file mode 100644 index 6918910..0000000 --- a/jpegenc/models/system/useful_things.py +++ /dev/null @@ -1,16 +0,0 @@ - -import myhdl -from myhdl import Signal, always_comb - - -def Signals(dtype, nitems): - return [Signal(dtype) for _ in range(nitems)] - - -@myhdl.block -def assign(a, b): - @always_comb - def beh_assign(): - b.next = a - - return beh_assign diff --git a/jpegenc/subblocks/frontend/frontend_v2.py b/jpegenc/subblocks/frontend/frontend_v2.py index 85b937a..2bb9119 100644 --- a/jpegenc/subblocks/frontend/frontend_v2.py +++ b/jpegenc/subblocks/frontend/frontend_v2.py @@ -1,26 +1,26 @@ #!/usr/bin/env python # coding=utf-8 -import numpy as np - from itertools import chain + import myhdl -from myhdl import Signal, intbv, always_comb, always_seq, block, ResetSignal +from myhdl import Signal, intbv, always_comb, always_seq, ResetSignal from jpegenc.subblocks.color_converters import ColorSpace, rgb2ycbcr_v2 from jpegenc.subblocks.dct.dct_2d import dct_2d_transformation, dct_2d from jpegenc.subblocks.zig_zag import zig_zag_scan, zig_zag -from jpegenc.subblocks.common import YCbCr_v2, input_interface, outputs_2d, RGB, outputs_frontend_new +from jpegenc.subblocks.common import (YCbCr_v2, input_interface, outputs_2d, + RGB, outputs_frontend_new,) -def frontend_transform(blockr, blockg, blockb, N=8): +def frontend_transform(blockr, blockg, blockb, n=8): """Software implementation of the frontend part""" - ycbcr_blocks = [[[] for _ in range(N)] for _ in range(3)] + ycbcr_blocks = [[[] for _ in range(n)] for _ in range(3)] dct_blocks, dct_blocks_linear, zig_zag_blocks = [[] for _ in range(3)] - """Color space conversion""" - for i in range(N): - for j in range(N): + # Color space conversion + for i in range(n): + for j in range(n): red = blockr[i][j] green = blockg[i][j] blue = blockb[i][j] @@ -31,17 +31,22 @@ def frontend_transform(blockr, blockg, blockb, N=8): ycbcr_blocks[k][i].append(ycbcr[k][0]) for i in range(3): - """dct-2d transformation""" - dct_blocks.append(dct_2d_transformation(N).dct_2d_transformation(ycbcr_blocks[i])) - """dct blocks to linear lists""" + # dct-2d transformation + dct_blocks.append( + dct_2d_transformation(n).dct_2d_transformation(ycbcr_blocks[i]) + ) + + # dct blocks to linear lists dct_blocks_linear.append(list(chain.from_iterable(dct_blocks[i]))) - """zig zag scan""" - zig_zag_blocks.append(zig_zag_scan(N).zig_zag(dct_blocks_linear[i])) + + # zig zag scan + zig_zag_blocks.append(zig_zag_scan(n).zig_zag(dct_blocks_linear[i])) return zig_zag_blocks -@block -def frontend_top_level_v2(inputs, outputs, clock, reset, N=8): + +@myhdl.block +def frontend_top_level_v2(inputs, outputs, clock, reset): """Frontend Part of the JPEG Encoder @@ -60,24 +65,24 @@ def frontend_top_level_v2(inputs, outputs, clock, reset, N=8): """ - """Color Space Conversion""" + # Color Space Conversion rgb2ycbcr_out = YCbCr_v2() inputs_reg = RGB() color_space_converter = rgb2ycbcr_v2(inputs_reg, rgb2ycbcr_out, clock, reset) - """2D-DCT Transformation""" + # 2D-DCT Transformation dct_2d_input = input_interface() dct_2d_output = outputs_2d() dct_2d_inst = dct_2d(dct_2d_input, dct_2d_output, clock, reset) - """Zig-Zag Module""" + # Zig-Zag Module zig_zag_out = outputs_2d() zig_zag_inst = zig_zag(dct_2d_output, zig_zag_out, clock, reset) - """Intermediate signals""" + # Intermediate signals input_counter = Signal(intbv(0, min=0, max=64)) color_mode = Signal(intbv(0, min=0, max=3)) output_counter = Signal(intbv(0, min=0, max=64)) @@ -93,15 +98,19 @@ def input_reg(): @always_seq(clock.posedge, reset=reset) def color_space_to_dct(): - """signal assignment from color_space_conversion module to dct_2d inputs""" + """ + signal assignment from color_space_conversion module to + dct_2d inputs + """ if rgb2ycbcr_out.data_valid: dct_2d_input.data_in.next = rgb2ycbcr_out.data_out dct_2d_input.data_valid.next = rgb2ycbcr_out.data_valid @always_seq(clock.posedge, reset=reset) def first_control_signals_update(): - """Is used to update the control signal color_mode for the first mux of the rgb2ycbcr - output to 2d dct""" + """ + Is used to update the control signal color_mode for the + first mux of the rgb2ycbcr output to 2d dct""" if inputs.data_valid: if input_counter == 63: input_counter.next = 0 @@ -136,20 +145,24 @@ def output_counter_reset(): else: output_counter.next = output_counter + 1 - return (color_space_converter, zig_zag_inst, dct_2d_inst, color_space_to_dct, - zig_zag_to_output_mux, first_control_signals_update, set_start_out, - output_counter_reset, input_reg, data_valid_assign) + return (color_space_converter, zig_zag_inst, dct_2d_inst, + color_space_to_dct, zig_zag_to_output_mux, + first_control_signals_update, set_start_out, + output_counter_reset, input_reg, data_valid_assign,) -def convert(): +def convert(): input_interface = RGB() output_interface = outputs_frontend_new() clock = Signal(bool(0)) reset = ResetSignal(0, active=True, async=False) - inst = frontend_top_level_v2(input_interface, output_interface, clock, reset) + inst = frontend_top_level_v2(input_interface, output_interface, + clock, reset) inst.convert(hdl='vhdl') inst.convert(hdl='verilog') -#convert() + +if __name__ == '__main__': + convert() diff --git a/jpegenc/subblocks/zig_zag/zig_zag.py b/jpegenc/subblocks/zig_zag/zig_zag.py index 2e90ef6..7d65a31 100644 --- a/jpegenc/subblocks/zig_zag/zig_zag.py +++ b/jpegenc/subblocks/zig_zag/zig_zag.py @@ -2,30 +2,31 @@ # coding=utf-8 import myhdl -from myhdl import Signal, intbv, always_comb, always_seq, block +from myhdl import Signal, intbv, always_seq, block -from jpegenc.subblocks.common import outputs_2d, assign_array +from jpegenc.subblocks.common import assign_array class zig_zag_scan(object): - - """Zig-Zag Scan Class - - It is used to produce the zig-zag matrix and as a software - reference for the zig-zag scan. - """ - def __init__(self, N): - """Initialize the zig-zag matrix""" + """Zig-Zag Scan Class + + It is used to produce the zig-zag matrix and as a software + reference for the zig-zag scan. + """ self.N = N self.zig_zag_matrix = self.build_zig_zag_matrix(N) - def build_zig_zag_matrix(self, N): - """Build the zig-zag matrix""" - """Code taken from http://paddy3118.blogspot.gr/2008/08/zig-zag.html""" + @staticmethod + def build_zig_zag_matrix(N): + """Build the zig-zag matrix + Code taken from http://paddy3118.blogspot.gr/2008/08/zig-zag.html + """ def zigzag(n): - indexorder = sorted(((x, y) for x in range(n) for y in range(n)), - key=lambda p: (p[0]+p[1], -p[1] if (p[0]+p[1]) % 2 else p[1])) + indexorder = sorted( + ((x, y) for x in range(n) for y in range(n)), + key=lambda p: (p[0]+p[1], -p[1] if (p[0]+p[1]) % 2 else p[1]) + ) return dict((index, n) for n, index in enumerate(indexorder)) def zig_zag_list(myarray): @@ -48,7 +49,7 @@ def zig_zag(self, signal_list): return zig_zag_result -@block +@myhdl.block def zig_zag(inputs, outputs, clock, reset, N=8): """Zig-Zag Module @@ -68,11 +69,12 @@ def zig_zag(inputs, outputs, clock, reset, N=8): """ zig_zag_obj = zig_zag_scan(N) zig_zag_rom = tuple(zig_zag_obj.zig_zag_matrix) - index = Signal(intbv(0, min=0, max=N**2)) - output_sigs = [Signal(intbv(0, min =-inputs.out_range, max=inputs.out_range)) - for _ in range(N**2)] - input_sigs = [Signal(intbv(0, min =-inputs.out_range, max=inputs.out_range)) + # index = Signal(intbv(0, min=0, max=N**2)) + ior = inputs.out_range + output_sigs = [Signal(intbv(0, min =-ior, max=ior)) for _ in range(N**2)] + input_sigs = [Signal(intbv(0, min =-ior, max=ior)) + for _ in range(N**2)] @always_seq(clock.posedge, reset=reset) def zig_zag_assign(): @@ -84,9 +86,7 @@ def zig_zag_assign(): else: outputs.data_valid.next = False - - - output_assignments =assign_array(outputs.out_sigs, output_sigs) + output_assignments = assign_array(outputs.out_sigs, output_sigs) input_assignments = assign_array(input_sigs, inputs.out_sigs) return zig_zag_assign, output_assignments, input_assignments diff --git a/jpegenc/testing/cosim/jpeg_compare_bitstreams.py b/jpegenc/testing/cosim/jpeg_compare_bitstreams.py index 60e0b59..3c573f5 100644 --- a/jpegenc/testing/cosim/jpeg_compare_bitstreams.py +++ b/jpegenc/testing/cosim/jpeg_compare_bitstreams.py @@ -10,7 +10,7 @@ def compare_bitstreams(ipth, bitstreams): software generated JPEG bitstream from the original file. """ if os.path.isfile(ipth): - img = Image(ipth) + img = Image.open(ipth, 'r') # @todo: complete this function, the following is not valid assert img == bitstreams From 729a6e61cff6ff82ce3f9edc34d3f2fd6c0dd245 Mon Sep 17 00:00:00 2001 From: Christopher Felton Date: Sat, 22 Oct 2016 22:04:45 -0500 Subject: [PATCH 32/32] fixed bunk guideline changes --- jpegenc/testing/cosim/jpeg_intf.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/jpegenc/testing/cosim/jpeg_intf.py b/jpegenc/testing/cosim/jpeg_intf.py index 9307d07..eb937fb 100644 --- a/jpegenc/testing/cosim/jpeg_intf.py +++ b/jpegenc/testing/cosim/jpeg_intf.py @@ -7,11 +7,12 @@ class JPEGEnc(object): - - def __init__(self, clock, reset): + def __init__(self, clock, reset, args=None): """An interface to the Verilog JPEG encoders. """ # @todo: the following parameters should be part of the args + if hasattr(args, 'pixel_nbits'): + pass self.pixel_nbits = 24 self.block_size = (8, 8,) self.max_frame_rate = 0