From 6b6f4bc7638d2f5f375f5245b2d81d35eac9dfaf Mon Sep 17 00:00:00 2001 From: tangxifan Date: Sun, 7 Feb 2021 11:40:18 -0700 Subject: [PATCH 01/28] [Doc] Try use image converter instead of svg2pdf which requires more dependencies --- docs/requirements.txt | 3 ++- docs/source/conf.py | 9 ++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/docs/requirements.txt b/docs/requirements.txt index c66cd1334..60cbc4f34 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -12,7 +12,8 @@ sphinxcontrib-bibtex<2.0.0 sphinxcontrib-yt # Package required to convert svg for pdf builder -sphinxcontrib-svg2pdfconverter +#sphinxcontrib-svg2pdfconverter +sphinxcontrib-ext-imgconverter #Work-around bug "AttributeError: 'Values' object has no attribute 'character_level_inline_markup'" with docutils 0.13.1 #See: diff --git a/docs/source/conf.py b/docs/source/conf.py index 55f4c8a26..e71a7187b 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -38,11 +38,14 @@ except ImportError: have_sphinxcontrib_youtube = False # Import sphinxcontrib.svg2pdfconverter -have_sphinxcontrib_svg2pdfconverter = True +#have_sphinxcontrib_svg2pdfconverter = True +have_sphinxcontrib_ext_imgconverter = True try: - import sphinxcontrib.svg2pdfconverter +# import sphinxcontrib.svg2pdfconverter + import sphinxcontrib.ext.imgconverter except ImportError: - have_sphinxcontrib_svg2pdfconverter = False +# have_sphinxcontrib_svg2pdfconverter = False + have_sphinxcontrib_ext_imgconverter = False # -- Project information ----------------------------------------------------- From 49fc903bfbeac0da5c8db26ef9de580712b59cb6 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Sun, 7 Feb 2021 11:44:41 -0700 Subject: [PATCH 02/28] [Doc] Add img converter to conf.py --- docs/source/conf.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/source/conf.py b/docs/source/conf.py index e71a7187b..d1cf8a57b 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -75,6 +75,8 @@ extensions = [ 'sphinxcontrib.bibtex', 'sphinx.ext.autosectionlabel', 'sphinxcontrib.yt', +# 'sphinxcontrib.svg2pdfconverter', + 'sphinxcontrib.ext.imgconverter', ] # Add any paths that contain templates here, relative to this directory. From d96ffdc00c795d5b27bb11f0c8653143fc5c281c Mon Sep 17 00:00:00 2001 From: tangxifan Date: Sun, 7 Feb 2021 11:52:04 -0700 Subject: [PATCH 03/28] [Doc] Bug fix in importing imgconverter package --- docs/requirements.txt | 2 +- docs/source/conf.py | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/requirements.txt b/docs/requirements.txt index 60cbc4f34..f65f760ce 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -13,7 +13,7 @@ sphinxcontrib-yt # Package required to convert svg for pdf builder #sphinxcontrib-svg2pdfconverter -sphinxcontrib-ext-imgconverter +sphinx-ext-imgconverter #Work-around bug "AttributeError: 'Values' object has no attribute 'character_level_inline_markup'" with docutils 0.13.1 #See: diff --git a/docs/source/conf.py b/docs/source/conf.py index d1cf8a57b..d787f0145 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -39,13 +39,13 @@ except ImportError: # Import sphinxcontrib.svg2pdfconverter #have_sphinxcontrib_svg2pdfconverter = True -have_sphinxcontrib_ext_imgconverter = True +have_sphinx_ext_imgconverter = True try: # import sphinxcontrib.svg2pdfconverter - import sphinxcontrib.ext.imgconverter + import sphinx.ext.imgconverter except ImportError: # have_sphinxcontrib_svg2pdfconverter = False - have_sphinxcontrib_ext_imgconverter = False + have_sphinx_ext_imgconverter = False # -- Project information ----------------------------------------------------- @@ -76,7 +76,7 @@ extensions = [ 'sphinx.ext.autosectionlabel', 'sphinxcontrib.yt', # 'sphinxcontrib.svg2pdfconverter', - 'sphinxcontrib.ext.imgconverter', + 'sphinx.ext.imgconverter', ] # Add any paths that contain templates here, relative to this directory. From 8f43ab6ca423ea7333186f40d38f66c6a004d41d Mon Sep 17 00:00:00 2001 From: tangxifan Date: Sun, 7 Feb 2021 12:00:48 -0700 Subject: [PATCH 04/28] [Doc] Try to fix the bug when importing python packages --- docs/requirements.txt | 4 ++-- docs/source/conf.py | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/requirements.txt b/docs/requirements.txt index f65f760ce..19712af78 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -12,8 +12,8 @@ sphinxcontrib-bibtex<2.0.0 sphinxcontrib-yt # Package required to convert svg for pdf builder -#sphinxcontrib-svg2pdfconverter -sphinx-ext-imgconverter +sphinxcontrib-svg2pdfconverter +#sphinx-ext-imgconverter #Work-around bug "AttributeError: 'Values' object has no attribute 'character_level_inline_markup'" with docutils 0.13.1 #See: diff --git a/docs/source/conf.py b/docs/source/conf.py index d787f0145..f24d2df88 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -41,11 +41,11 @@ except ImportError: #have_sphinxcontrib_svg2pdfconverter = True have_sphinx_ext_imgconverter = True try: -# import sphinxcontrib.svg2pdfconverter - import sphinx.ext.imgconverter + import sphinxcontrib.svg2pdfconverter +# import sphinx.ext.imgconverter except ImportError: -# have_sphinxcontrib_svg2pdfconverter = False - have_sphinx_ext_imgconverter = False + have_sphinxcontrib_svg2pdfconverter = False +# have_sphinx_ext_imgconverter = False # -- Project information ----------------------------------------------------- @@ -75,8 +75,8 @@ extensions = [ 'sphinxcontrib.bibtex', 'sphinx.ext.autosectionlabel', 'sphinxcontrib.yt', -# 'sphinxcontrib.svg2pdfconverter', - 'sphinx.ext.imgconverter', + 'sphinxcontrib.svg2pdfconverter', +# 'sphinx.ext.imgconverter', ] # Add any paths that contain templates here, relative to this directory. From 4551f13290b33d78fe18b8a7b42d01543a84d20b Mon Sep 17 00:00:00 2001 From: tangxifan Date: Sun, 7 Feb 2021 12:06:23 -0700 Subject: [PATCH 05/28] [Doc] bug fix --- docs/requirements.txt | 2 +- docs/source/conf.py | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/requirements.txt b/docs/requirements.txt index 19712af78..f3c4a9c9e 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -12,7 +12,7 @@ sphinxcontrib-bibtex<2.0.0 sphinxcontrib-yt # Package required to convert svg for pdf builder -sphinxcontrib-svg2pdfconverter +sphinxcontrib-svg2pdfconverter[CairoSVG] #sphinx-ext-imgconverter #Work-around bug "AttributeError: 'Values' object has no attribute 'character_level_inline_markup'" with docutils 0.13.1 diff --git a/docs/source/conf.py b/docs/source/conf.py index f24d2df88..257dcd399 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -38,8 +38,8 @@ except ImportError: have_sphinxcontrib_youtube = False # Import sphinxcontrib.svg2pdfconverter -#have_sphinxcontrib_svg2pdfconverter = True -have_sphinx_ext_imgconverter = True +have_sphinxcontrib_svg2pdfconverter = True +#have_sphinx_ext_imgconverter = True try: import sphinxcontrib.svg2pdfconverter # import sphinx.ext.imgconverter @@ -75,7 +75,7 @@ extensions = [ 'sphinxcontrib.bibtex', 'sphinx.ext.autosectionlabel', 'sphinxcontrib.yt', - 'sphinxcontrib.svg2pdfconverter', + 'sphinxcontrib.cairosvgconverter', # 'sphinx.ext.imgconverter', ] From 6492d8f3a8ea90e52578cdb8f050cf375c25fee9 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Sun, 7 Feb 2021 12:27:45 -0700 Subject: [PATCH 06/28] [Doc] Try to use imgconverter rather than cairo --- docs/requirements.txt | 2 +- docs/source/conf.py | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/requirements.txt b/docs/requirements.txt index f3c4a9c9e..807e56865 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -12,7 +12,7 @@ sphinxcontrib-bibtex<2.0.0 sphinxcontrib-yt # Package required to convert svg for pdf builder -sphinxcontrib-svg2pdfconverter[CairoSVG] +#sphinxcontrib-svg2pdfconverter[CairoSVG] #sphinx-ext-imgconverter #Work-around bug "AttributeError: 'Values' object has no attribute 'character_level_inline_markup'" with docutils 0.13.1 diff --git a/docs/source/conf.py b/docs/source/conf.py index 257dcd399..6691f1626 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -38,14 +38,14 @@ except ImportError: have_sphinxcontrib_youtube = False # Import sphinxcontrib.svg2pdfconverter -have_sphinxcontrib_svg2pdfconverter = True -#have_sphinx_ext_imgconverter = True +#have_sphinxcontrib_svg2pdfconverter = True +have_sphinx_ext_imgconverter = True try: - import sphinxcontrib.svg2pdfconverter -# import sphinx.ext.imgconverter +# import sphinxcontrib.svg2pdfconverter + import sphinx.ext.imgconverter except ImportError: - have_sphinxcontrib_svg2pdfconverter = False -# have_sphinx_ext_imgconverter = False +# have_sphinxcontrib_svg2pdfconverter = False + have_sphinx_ext_imgconverter = False # -- Project information ----------------------------------------------------- @@ -75,8 +75,8 @@ extensions = [ 'sphinxcontrib.bibtex', 'sphinx.ext.autosectionlabel', 'sphinxcontrib.yt', - 'sphinxcontrib.cairosvgconverter', -# 'sphinx.ext.imgconverter', +# 'sphinxcontrib.cairosvgconverter', + 'sphinx.ext.imgconverter', ] # Add any paths that contain templates here, relative to this directory. From 40e9960618b19c156ee4f048cec2c22237e8a81e Mon Sep 17 00:00:00 2001 From: tangxifan Date: Sun, 7 Feb 2021 12:40:14 -0700 Subject: [PATCH 07/28] [Doc] Add svg to latex config in sphinx configuration file --- docs/source/conf.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/source/conf.py b/docs/source/conf.py index 6691f1626..557048c66 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -170,6 +170,8 @@ latex_elements = { # Latex figure (float) alignment # # 'figure_align': 'htbp', + 'preamble': '\\usepackage{tikz}', + 'preamble': '\\usepackage{svg}', } # Grouping the document tree into LaTeX files. List of tuples From b556e6e7df5b98d5c9c11dfca1aec17b7f1a4465 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Sun, 7 Feb 2021 14:55:13 -0700 Subject: [PATCH 08/28] [Doc] Try cairo svg converter --- docs/requirements.txt | 2 +- docs/source/conf.py | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/requirements.txt b/docs/requirements.txt index 807e56865..f3c4a9c9e 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -12,7 +12,7 @@ sphinxcontrib-bibtex<2.0.0 sphinxcontrib-yt # Package required to convert svg for pdf builder -#sphinxcontrib-svg2pdfconverter[CairoSVG] +sphinxcontrib-svg2pdfconverter[CairoSVG] #sphinx-ext-imgconverter #Work-around bug "AttributeError: 'Values' object has no attribute 'character_level_inline_markup'" with docutils 0.13.1 diff --git a/docs/source/conf.py b/docs/source/conf.py index 557048c66..366478f46 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -38,13 +38,13 @@ except ImportError: have_sphinxcontrib_youtube = False # Import sphinxcontrib.svg2pdfconverter -#have_sphinxcontrib_svg2pdfconverter = True +have_sphinxcontrib_svg2pdfconverter = True have_sphinx_ext_imgconverter = True try: -# import sphinxcontrib.svg2pdfconverter + import sphinxcontrib.svg2pdfconverter import sphinx.ext.imgconverter except ImportError: -# have_sphinxcontrib_svg2pdfconverter = False + have_sphinxcontrib_svg2pdfconverter = False have_sphinx_ext_imgconverter = False # -- Project information ----------------------------------------------------- @@ -75,8 +75,8 @@ extensions = [ 'sphinxcontrib.bibtex', 'sphinx.ext.autosectionlabel', 'sphinxcontrib.yt', -# 'sphinxcontrib.cairosvgconverter', - 'sphinx.ext.imgconverter', + 'sphinxcontrib.cairosvgconverter', +# 'sphinx.ext.imgconverter', ] # Add any paths that contain templates here, relative to this directory. From 9c5368f912c622b23be7369755a5671bcc2e77ed Mon Sep 17 00:00:00 2001 From: tangxifan Date: Sun, 7 Feb 2021 16:17:54 -0700 Subject: [PATCH 09/28] [Doc] Correct bugs in compiling latexpdf --- docs/requirements.txt | 4 --- docs/source/conf.py | 34 ++++--------------- .../arch_lang/circuit_model_examples.rst | 4 +-- 3 files changed, 9 insertions(+), 33 deletions(-) diff --git a/docs/requirements.txt b/docs/requirements.txt index f3c4a9c9e..eb876e494 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -11,10 +11,6 @@ sphinxcontrib-bibtex<2.0.0 # Package required to embed youtube video sphinxcontrib-yt -# Package required to convert svg for pdf builder -sphinxcontrib-svg2pdfconverter[CairoSVG] -#sphinx-ext-imgconverter - #Work-around bug "AttributeError: 'Values' object has no attribute 'character_level_inline_markup'" with docutils 0.13.1 #See: # * https://github.com/sphinx-doc/sphinx/issues/3951 diff --git a/docs/source/conf.py b/docs/source/conf.py index 366478f46..910e1bb07 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -23,29 +23,12 @@ import sphinx_rtd_theme #html_theme = "sphinx_rtd_theme" #html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] -# Import sphinxcontrib.bibtex -have_sphinxcontrib_bibtex = True -try: - import sphinxcontrib.bibtex -except ImportError: - have_sphinxcontrib_bibtex = False - -# Import sphinxcontrib.yt -have_sphinxcontrib_youtube = True -try: - import sphinxcontrib.yt -except ImportError: - have_sphinxcontrib_youtube = False - -# Import sphinxcontrib.svg2pdfconverter -have_sphinxcontrib_svg2pdfconverter = True -have_sphinx_ext_imgconverter = True -try: - import sphinxcontrib.svg2pdfconverter - import sphinx.ext.imgconverter -except ImportError: - have_sphinxcontrib_svg2pdfconverter = False - have_sphinx_ext_imgconverter = False +# For bibtex support +import sphinxcontrib.bibtex +# For embedded youtube +import sphinxcontrib.yt +# For converting SVG to PNG +import sphinx.ext.imgconverter # -- Project information ----------------------------------------------------- @@ -75,8 +58,7 @@ extensions = [ 'sphinxcontrib.bibtex', 'sphinx.ext.autosectionlabel', 'sphinxcontrib.yt', - 'sphinxcontrib.cairosvgconverter', -# 'sphinx.ext.imgconverter', + 'sphinx.ext.imgconverter', ] # Add any paths that contain templates here, relative to this directory. @@ -170,8 +152,6 @@ latex_elements = { # Latex figure (float) alignment # # 'figure_align': 'htbp', - 'preamble': '\\usepackage{tikz}', - 'preamble': '\\usepackage{svg}', } # Grouping the document tree into LaTeX files. List of tuples diff --git a/docs/source/manual/arch_lang/circuit_model_examples.rst b/docs/source/manual/arch_lang/circuit_model_examples.rst index 1f4c0c1d3..263ee1724 100644 --- a/docs/source/manual/arch_lang/circuit_model_examples.rst +++ b/docs/source/manual/arch_lang/circuit_model_examples.rst @@ -1160,7 +1160,7 @@ Template .. option:: - - ``model_type="pi|T"`` Specify the type of RC models for this wire segement. Currently, OpenFPGA supports the π-type and T-type multi-level RC models. + - ``model_type="pi|T"`` Specify the type of RC models for this wire segement. Currently, OpenFPGA supports the :math:`\pi`-type and T-type multi-level RC models. - ``R=""`` Specify the total resistance of the wire - ``C=""`` Specify the total capacitance of the wire. - ``num_level=""`` Specify the number of levels of the RC wire model. @@ -1193,7 +1193,7 @@ The code describing this wire is: This example shows - A routing track wire has 1 input and output - - The routing wire will be modelled as a 1-level π-type RC wire model with a total resistance of :math:`103.84\Omega` and a total capacitance of :math:`13.89fF` + - The routing wire will be modelled as a 1-level :math:`\pi`-type RC wire model with a total resistance of :math:`103.84\Omega` and a total capacitance of :math:`13.89fF` I/O pads ~~~~~~~~ From 4e05a4559f9c90330dfcb855d29b43ebc1a447ee Mon Sep 17 00:00:00 2001 From: tangxifan Date: Sun, 7 Feb 2021 16:31:48 -0700 Subject: [PATCH 10/28] [Doc] Use latest image in building readthedocs --- .readthedocs.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.readthedocs.yml b/.readthedocs.yml index 049c8b2c9..f4f14c7a5 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -5,6 +5,10 @@ # Required configuration file version version: 2 +# Specify docker image for building the doc +build: + image: latest + # Build documentation in the docs/ directory with Sphinx sphinx: builder: dirhtml From 2cfa3855f6ec0b84a7043417325b77cf940f2c10 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Sun, 7 Feb 2021 17:35:41 -0700 Subject: [PATCH 11/28] [Doc] Now use readthedocs docker image in building online documentation --- .readthedocs.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.readthedocs.yml b/.readthedocs.yml index f4f14c7a5..23c1ae920 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -20,5 +20,6 @@ formats: all # Optionally set the version of Python and requirements required to build your docs python: version: 3.7 + use_system_site_packages: true install: - requirements: docs/requirements.txt From 455e8a322cb4b2c8a64c6cce5a0e361987d61902 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Sun, 7 Feb 2021 17:47:23 -0700 Subject: [PATCH 12/28] [Doc] Correct typo in readthedocs setting --- .readthedocs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.readthedocs.yml b/.readthedocs.yml index 23c1ae920..5ff1814f4 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -20,6 +20,6 @@ formats: all # Optionally set the version of Python and requirements required to build your docs python: version: 3.7 - use_system_site_packages: true + system_packages: true install: - requirements: docs/requirements.txt From 3c1a538f7a530f46159d429323f9568a85384ce7 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Sun, 7 Feb 2021 17:53:58 -0700 Subject: [PATCH 13/28] [Doc] Try to use inkscape converter as imgconverter converted SVG to black images --- docs/requirements.txt | 3 +++ docs/source/conf.py | 6 +++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/docs/requirements.txt b/docs/requirements.txt index eb876e494..cd8e75de7 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -11,6 +11,9 @@ sphinxcontrib-bibtex<2.0.0 # Package required to embed youtube video sphinxcontrib-yt +# Package required to convert SVG for latex building +sphinxcontrib-svg2pdfconverter + #Work-around bug "AttributeError: 'Values' object has no attribute 'character_level_inline_markup'" with docutils 0.13.1 #See: # * https://github.com/sphinx-doc/sphinx/issues/3951 diff --git a/docs/source/conf.py b/docs/source/conf.py index 910e1bb07..c5528f690 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -27,8 +27,8 @@ import sphinx_rtd_theme import sphinxcontrib.bibtex # For embedded youtube import sphinxcontrib.yt -# For converting SVG to PNG -import sphinx.ext.imgconverter +# For converting SVG to PNG using inkscape +import sphinxcontrib.inkscapeconverter # -- Project information ----------------------------------------------------- @@ -58,7 +58,7 @@ extensions = [ 'sphinxcontrib.bibtex', 'sphinx.ext.autosectionlabel', 'sphinxcontrib.yt', - 'sphinx.ext.imgconverter', + 'sphinxcontrib.inkscapeconverter', ] # Add any paths that contain templates here, relative to this directory. From b71966363b61cf1baab468a76e9edd321b532925 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Sun, 7 Feb 2021 18:16:33 -0700 Subject: [PATCH 14/28] [Doc] Try RSVG --- docs/source/conf.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/source/conf.py b/docs/source/conf.py index c5528f690..0f442d9bd 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -27,8 +27,8 @@ import sphinx_rtd_theme import sphinxcontrib.bibtex # For embedded youtube import sphinxcontrib.yt -# For converting SVG to PNG using inkscape -import sphinxcontrib.inkscapeconverter +# For converting SVG to PNG using rsvg +import sphinxcontrib.rsvgconverter # -- Project information ----------------------------------------------------- @@ -58,7 +58,7 @@ extensions = [ 'sphinxcontrib.bibtex', 'sphinx.ext.autosectionlabel', 'sphinxcontrib.yt', - 'sphinxcontrib.inkscapeconverter', + 'sphinxcontrib.rsvgconverter', ] # Add any paths that contain templates here, relative to this directory. From 304b26c97f411940553b2b0c7b7f88d5d43deb3a Mon Sep 17 00:00:00 2001 From: tangxifan Date: Tue, 9 Feb 2021 15:11:12 -0700 Subject: [PATCH 15/28] [Arch] Add example architectures for superLUT circuit model --- ...avel_io_skywater130nm_fdhd_cc_openfpga.xml | 265 ++++++ ...n_chain_nonLR_caravel_io_skywater130nm.xml | 780 ++++++++++++++++++ 2 files changed, 1045 insertions(+) create mode 100644 openfpga_flow/openfpga_arch/k4_frac_N8_reset_softadderSuperLUT_register_scan_chain_caravel_io_skywater130nm_fdhd_cc_openfpga.xml create mode 100644 openfpga_flow/vpr_arch/k4_frac_N8_tileable_reset_softadderSuperLUT_register_scan_chain_nonLR_caravel_io_skywater130nm.xml diff --git a/openfpga_flow/openfpga_arch/k4_frac_N8_reset_softadderSuperLUT_register_scan_chain_caravel_io_skywater130nm_fdhd_cc_openfpga.xml b/openfpga_flow/openfpga_arch/k4_frac_N8_reset_softadderSuperLUT_register_scan_chain_caravel_io_skywater130nm_fdhd_cc_openfpga.xml new file mode 100644 index 000000000..27747891e --- /dev/null +++ b/openfpga_flow/openfpga_arch/k4_frac_N8_reset_softadderSuperLUT_register_scan_chain_caravel_io_skywater130nm_fdhd_cc_openfpga.xml @@ -0,0 +1,265 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 10e-12 + + + 10e-12 + + + + + + + + + 10e-12 + + + 10e-12 + + + + + + + + + 10e-12 + + + 10e-12 + + + + + + + + + 10e-12 + + + 10e-12 + + + + + + + + + + + + 10e-12 5e-12 + + + 10e-12 5e-12 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/openfpga_flow/vpr_arch/k4_frac_N8_tileable_reset_softadderSuperLUT_register_scan_chain_nonLR_caravel_io_skywater130nm.xml b/openfpga_flow/vpr_arch/k4_frac_N8_tileable_reset_softadderSuperLUT_register_scan_chain_nonLR_caravel_io_skywater130nm.xml new file mode 100644 index 000000000..97bbea7a7 --- /dev/null +++ b/openfpga_flow/vpr_arch/k4_frac_N8_tileable_reset_softadderSuperLUT_register_scan_chain_nonLR_caravel_io_skywater130nm.xml @@ -0,0 +1,780 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + io_top.outpad io_top.inpad + + + + + + + + + + + + io_right.outpad io_right.inpad + + + + + + + + + + + + io_bottom.outpad io_bottom.inpad + + + + + + + + + + + + io_left.outpad io_left.inpad + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + clb.clk clb.reset + clb.reg_in clb.sc_in clb.cin clb.O[7:0] clb.I0 clb.I0i clb.I1 clb.I1i clb.I2 clb.I2i clb.I3 clb.I3i + clb.O[15:8] clb.I4 clb.I4i clb.I5 clb.I5i clb.I6 clb.I6i clb.I7 clb.I7i + clb.reg_out clb.sc_out clb.cout + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 1 + 1 + + + + 1 1 1 + 1 1 + + + + 1 1 1 1 1 + 1 1 1 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 235e-12 + 235e-12 + 235e-12 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 261e-12 + 261e-12 + 261e-12 + 261e-12 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 56284059de65ebc2c6063a6f7b3be00d52a1889a Mon Sep 17 00:00:00 2001 From: tangxifan Date: Tue, 9 Feb 2021 15:25:32 -0700 Subject: [PATCH 16/28] [Test] Add a test case for a super LUT --- .../config/bitstream_annotation.xml | 3 ++ .../frac_lut4_arith/config/task.conf | 38 +++++++++++++++++++ 2 files changed, 41 insertions(+) create mode 100644 openfpga_flow/tasks/fpga_verilog/lut_design/frac_lut4_arith/config/bitstream_annotation.xml create mode 100644 openfpga_flow/tasks/fpga_verilog/lut_design/frac_lut4_arith/config/task.conf diff --git a/openfpga_flow/tasks/fpga_verilog/lut_design/frac_lut4_arith/config/bitstream_annotation.xml b/openfpga_flow/tasks/fpga_verilog/lut_design/frac_lut4_arith/config/bitstream_annotation.xml new file mode 100644 index 000000000..735d45c23 --- /dev/null +++ b/openfpga_flow/tasks/fpga_verilog/lut_design/frac_lut4_arith/config/bitstream_annotation.xml @@ -0,0 +1,3 @@ + + + diff --git a/openfpga_flow/tasks/fpga_verilog/lut_design/frac_lut4_arith/config/task.conf b/openfpga_flow/tasks/fpga_verilog/lut_design/frac_lut4_arith/config/task.conf new file mode 100644 index 000000000..6244bd525 --- /dev/null +++ b/openfpga_flow/tasks/fpga_verilog/lut_design/frac_lut4_arith/config/task.conf @@ -0,0 +1,38 @@ +# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +# Configuration file for running experiments +# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +# timeout_each_job : FPGA Task script splits fpga flow into multiple jobs +# Each job execute fpga_flow script on combination of architecture & benchmark +# timeout_each_job is timeout for each job +# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + +[GENERAL] +run_engine=openfpga_shell +power_tech_file = ${PATH:OPENFPGA_PATH}/openfpga_flow/tech/PTM_45nm/45nm.xml +power_analysis = false +spice_output=false +verilog_output=true +timeout_each_job = 1*60 +fpga_flow=vpr_blif + +[OpenFPGA_SHELL] +openfpga_shell_template=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_shell_scripts/bitstream_setting_example_script.openfpga +openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k4_frac_N8_reset_softadder_register_scan_chain_caravel_io_skywater130nm_fdhd_cc_openfpga.xml +openfpga_sim_setting_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_simulation_settings/fixed_sim_openfpga.xml +openfpga_bitstream_setting_file=${PATH:OPENFPGA_PATH}/openfpga_flow/tasks/fpga_verilog/lut_design/frac_lut4_arith/config/bitstream_annotation.xml +openfpga_vpr_circuit_format=eblif + +[ARCHITECTURES] +arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k4_frac_N8_tileable_reset_softadder_register_scan_chain_nonLR_caravel_io_skywater130nm.xml + +[BENCHMARKS] +bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.eblif + +[SYNTHESIS_PARAM] +bench0_top = and2 +bench0_act = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.act +bench0_verilog = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.v + +[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH] +end_flow_with_test= +vpr_fpga_verilog_formal_verification_top_netlist= From 2b51b36dd62f03319b769a6abf4b5fdef70e6327 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Tue, 9 Feb 2021 15:27:44 -0700 Subject: [PATCH 17/28] [Test] Now use the super LUT arch in the test case --- .../fpga_verilog/lut_design/frac_lut4_arith/config/task.conf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openfpga_flow/tasks/fpga_verilog/lut_design/frac_lut4_arith/config/task.conf b/openfpga_flow/tasks/fpga_verilog/lut_design/frac_lut4_arith/config/task.conf index 6244bd525..62d4ead4b 100644 --- a/openfpga_flow/tasks/fpga_verilog/lut_design/frac_lut4_arith/config/task.conf +++ b/openfpga_flow/tasks/fpga_verilog/lut_design/frac_lut4_arith/config/task.conf @@ -17,13 +17,13 @@ fpga_flow=vpr_blif [OpenFPGA_SHELL] openfpga_shell_template=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_shell_scripts/bitstream_setting_example_script.openfpga -openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k4_frac_N8_reset_softadder_register_scan_chain_caravel_io_skywater130nm_fdhd_cc_openfpga.xml +openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k4_frac_N8_reset_softadderSuperLUT_register_scan_chain_caravel_io_skywater130nm_fdhd_cc_openfpga.xml openfpga_sim_setting_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_simulation_settings/fixed_sim_openfpga.xml openfpga_bitstream_setting_file=${PATH:OPENFPGA_PATH}/openfpga_flow/tasks/fpga_verilog/lut_design/frac_lut4_arith/config/bitstream_annotation.xml openfpga_vpr_circuit_format=eblif [ARCHITECTURES] -arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k4_frac_N8_tileable_reset_softadder_register_scan_chain_nonLR_caravel_io_skywater130nm.xml +arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k4_frac_N8_tileable_reset_softadderSuperLUT_register_scan_chain_nonLR_caravel_io_skywater130nm.xml [BENCHMARKS] bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.eblif From 1712ee4edb2be8c42568d8cb51f13b7f03335b5f Mon Sep 17 00:00:00 2001 From: tangxifan Date: Tue, 9 Feb 2021 15:41:21 -0700 Subject: [PATCH 18/28] [Benchmark] Add a dedicated eblif to test the frac lut4 arith architecture --- .../and2/and2_frac_lut4_arith.eblif | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 openfpga_flow/benchmarks/micro_benchmark/and2/and2_frac_lut4_arith.eblif diff --git a/openfpga_flow/benchmarks/micro_benchmark/and2/and2_frac_lut4_arith.eblif b/openfpga_flow/benchmarks/micro_benchmark/and2/and2_frac_lut4_arith.eblif new file mode 100644 index 000000000..1e591e999 --- /dev/null +++ b/openfpga_flow/benchmarks/micro_benchmark/and2/and2_frac_lut4_arith.eblif @@ -0,0 +1,19 @@ +# This is an artificial microbenchmark +# which is designed to validate the support +# on using bitstream information from the .param +# attribute of hard macro of LUTs +# +.model and2 +.inputs a b +.outputs c + +.subckt adder_lut4 in[1]=a in[0]=b lut4_out[0]=c +.param LUT 1000100010001000 + +.end + +.model adder_lut4 +.inputs in[3] in[2] in[1] in[0] cin +.outputs lut4_out[0] cout +.blackbox +.end From 3ae501a5eaef5ca293a88d34fbae11a78ab90607 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Tue, 9 Feb 2021 15:51:57 -0700 Subject: [PATCH 19/28] [Test] Update test case to use dedicated eblif file --- .../fpga_verilog/lut_design/frac_lut4_arith/config/task.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openfpga_flow/tasks/fpga_verilog/lut_design/frac_lut4_arith/config/task.conf b/openfpga_flow/tasks/fpga_verilog/lut_design/frac_lut4_arith/config/task.conf index 62d4ead4b..e855cb3ba 100644 --- a/openfpga_flow/tasks/fpga_verilog/lut_design/frac_lut4_arith/config/task.conf +++ b/openfpga_flow/tasks/fpga_verilog/lut_design/frac_lut4_arith/config/task.conf @@ -26,7 +26,7 @@ openfpga_vpr_circuit_format=eblif arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k4_frac_N8_tileable_reset_softadderSuperLUT_register_scan_chain_nonLR_caravel_io_skywater130nm.xml [BENCHMARKS] -bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.eblif +bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2_frac_lut4_arith.eblif [SYNTHESIS_PARAM] bench0_top = and2 From 7dcc14d73faf6be85a8cb6569f4a67241ca6713b Mon Sep 17 00:00:00 2001 From: tangxifan Date: Tue, 9 Feb 2021 15:52:22 -0700 Subject: [PATCH 20/28] [Arch] Bug fix in the example arch with super LUT --- ...n_chain_nonLR_caravel_io_skywater130nm.xml | 21 +++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/openfpga_flow/vpr_arch/k4_frac_N8_tileable_reset_softadderSuperLUT_register_scan_chain_nonLR_caravel_io_skywater130nm.xml b/openfpga_flow/vpr_arch/k4_frac_N8_tileable_reset_softadderSuperLUT_register_scan_chain_nonLR_caravel_io_skywater130nm.xml index 97bbea7a7..3d71ffff9 100644 --- a/openfpga_flow/vpr_arch/k4_frac_N8_tileable_reset_softadderSuperLUT_register_scan_chain_nonLR_caravel_io_skywater130nm.xml +++ b/openfpga_flow/vpr_arch/k4_frac_N8_tileable_reset_softadderSuperLUT_register_scan_chain_nonLR_caravel_io_skywater130nm.xml @@ -35,20 +35,20 @@ - + + - + - - + + - @@ -400,10 +400,16 @@ - + + + + + + + @@ -483,7 +489,10 @@ + + + From 6a0f4f354f28344123fb041139995f7d52a169dc Mon Sep 17 00:00:00 2001 From: tangxifan Date: Tue, 9 Feb 2021 20:23:05 -0700 Subject: [PATCH 21/28] [Tool] Support superLUT circuit model in core engine --- openfpga/src/fabric/build_lut_modules.cpp | 34 ++++++--- openfpga/src/fabric/build_mux_modules.cpp | 58 ++++++++++++-- .../fpga_bitstream/build_grid_bitstream.cpp | 2 +- .../fpga_sdc/configure_port_sdc_writer.cpp | 4 +- openfpga/src/mux_lib/mux_library_builder.cpp | 3 +- .../src/repack/build_physical_truth_table.cpp | 76 ++++++++++++------- openfpga/src/utils/circuit_library_utils.cpp | 50 ++++++++++++ openfpga/src/utils/circuit_library_utils.h | 10 +++ 8 files changed, 186 insertions(+), 51 deletions(-) diff --git a/openfpga/src/fabric/build_lut_modules.cpp b/openfpga/src/fabric/build_lut_modules.cpp index 142c2369f..a8442f62f 100644 --- a/openfpga/src/fabric/build_lut_modules.cpp +++ b/openfpga/src/fabric/build_lut_modules.cpp @@ -45,8 +45,13 @@ void build_lut_module(ModuleManager& module_manager, std::vector lut_global_ports = circuit_lib.model_global_ports_by_type(lut_model, CIRCUIT_MODEL_PORT_INPUT, false, true); /* Get the input ports from the mux */ std::vector lut_input_ports = circuit_lib.model_ports_by_type(lut_model, CIRCUIT_MODEL_PORT_INPUT, true); + /* Find the inputs that drive the internal LUT MUX */ + std::vector lut_mux_input_ports = find_lut_circuit_model_input_port(circuit_lib, lut_model, false); + /* Get the output ports from the mux */ std::vector lut_output_ports = circuit_lib.model_ports_by_type(lut_model, CIRCUIT_MODEL_PORT_OUTPUT, false); + /* Find the outputs that are driven the internal LUT MUX */ + std::vector lut_mux_output_ports = find_lut_circuit_model_output_port(circuit_lib, lut_model, false); /* Classify SRAM ports into two categories: regular (not for mode select) and mode-select */ std::vector lut_regular_sram_ports = find_circuit_regular_sram_ports(circuit_lib, lut_model); @@ -60,8 +65,8 @@ void build_lut_module(ModuleManager& module_manager, /* Single-output LUTs: * We should have only 1 input port, 1 output port and 1 SRAM port */ - VTR_ASSERT (1 == lut_input_ports.size()); - VTR_ASSERT (1 == lut_output_ports.size()); + VTR_ASSERT (1 == lut_mux_input_ports.size()); + VTR_ASSERT (1 == lut_mux_output_ports.size()); VTR_ASSERT (1 == lut_regular_sram_ports.size()); VTR_ASSERT (0 == lut_mode_select_sram_ports.size()); } else { @@ -70,8 +75,8 @@ void build_lut_module(ModuleManager& module_manager, * We should have only 1 input port, a few output ports (fracturable outputs) * and two SRAM ports */ - VTR_ASSERT (1 == lut_input_ports.size()); - VTR_ASSERT (1 <= lut_output_ports.size()); + VTR_ASSERT (1 == lut_mux_input_ports.size()); + VTR_ASSERT (1 <= lut_mux_output_ports.size()); VTR_ASSERT (1 == lut_regular_sram_ports.size()); VTR_ASSERT ( (0 == lut_mode_select_sram_ports.size()) || (1 == lut_mode_select_sram_ports.size())); @@ -155,10 +160,10 @@ void build_lut_module(ModuleManager& module_manager, * +--------------------------------------+ */ /* Get the tri-state port map for the input ports*/ - std::string tri_state_map = circuit_lib.port_tri_state_map(lut_input_ports[0]); + std::string tri_state_map = circuit_lib.port_tri_state_map(lut_mux_input_ports[0]); size_t mode_select_port_lsb = 0; - for (const auto& pin : circuit_lib.pins(lut_input_ports[0])) { - ModulePortId lut_module_input_port_id = module_manager.find_module_port(lut_module, circuit_lib.port_prefix(lut_input_ports[0])); + for (const auto& pin : circuit_lib.pins(lut_mux_input_ports[0])) { + ModulePortId lut_module_input_port_id = module_manager.find_module_port(lut_module, circuit_lib.port_prefix(lut_mux_input_ports[0])); VTR_ASSERT(true == module_manager.valid_module_port_id(lut_module, lut_module_input_port_id)); /* Create a module net for the connection */ @@ -200,7 +205,7 @@ void build_lut_module(ModuleManager& module_manager, required_gate_type = CIRCUIT_MODEL_GATE_OR; } /* Get the circuit model of the gate */ - CircuitModelId gate_model = circuit_lib.port_tri_state_model(lut_input_ports[0]); + CircuitModelId gate_model = circuit_lib.port_tri_state_model(lut_mux_input_ports[0]); /* Check this is the gate we want ! */ VTR_ASSERT (required_gate_type == circuit_lib.gate_type(gate_model)); @@ -290,7 +295,7 @@ void build_lut_module(ModuleManager& module_manager, std::vector lut_mux_sram_inv_nets; /* Now we need to add inverters by instanciating the modules */ - for (size_t pin = 0; pin < circuit_lib.port_size(lut_input_ports[0]); ++pin) { + for (size_t pin = 0; pin < circuit_lib.port_size(lut_mux_input_ports[0]); ++pin) { ModuleNetId lut_mux_sram_inv_net = add_inverter_buffer_child_module_and_nets(module_manager, lut_module, circuit_lib, input_inverter_model, mode_selected_nets[pin]); @@ -308,7 +313,7 @@ void build_lut_module(ModuleManager& module_manager, std::vector lut_mux_sram_nets; /* Now we need to add inverters by instanciating the modules and add module nets */ - for (size_t pin = 0; pin < circuit_lib.port_size(lut_input_ports[0]); ++pin) { + for (size_t pin = 0; pin < circuit_lib.port_size(lut_mux_input_ports[0]); ++pin) { ModuleNetId lut_mux_sram_net = add_inverter_buffer_child_module_and_nets(module_manager, lut_module, circuit_lib, input_buffer_model, mode_selected_nets[pin]); @@ -362,7 +367,7 @@ void build_lut_module(ModuleManager& module_manager, */ ModulePortId lut_sram_port_id = module_manager.find_module_port(lut_module, circuit_lib.port_prefix(lut_regular_sram_ports[0])); BasicPort lut_sram_port = module_manager.module_port(lut_module, lut_sram_port_id); - ModulePortId lut_mux_input_port_id = module_manager.find_module_port(lut_mux_module, circuit_lib.port_prefix(lut_input_ports[0])); + ModulePortId lut_mux_input_port_id = module_manager.find_module_port(lut_mux_module, circuit_lib.port_prefix(lut_mux_input_ports[0])); BasicPort lut_mux_input_port = module_manager.module_port(lut_mux_module, lut_mux_input_port_id); VTR_ASSERT(lut_mux_input_port.get_width() == lut_sram_port.get_width()); /* Wire the port to lut_mux_sram_net */ @@ -372,7 +377,7 @@ void build_lut_module(ModuleManager& module_manager, module_manager.add_module_net_sink(lut_module, net, lut_mux_module, lut_mux_instance, lut_mux_input_port_id, lut_mux_input_port.pins()[pin_id]); } - for (const auto& port : lut_output_ports) { + for (const auto& port : lut_mux_output_ports) { ModulePortId lut_output_port_id = module_manager.find_module_port(lut_module, circuit_lib.port_prefix(port)); BasicPort lut_output_port = module_manager.module_port(lut_module, lut_output_port_id); ModulePortId lut_mux_output_port_id = module_manager.find_module_port(lut_mux_module, circuit_lib.port_prefix(port)); @@ -407,6 +412,11 @@ void build_lut_modules(ModuleManager& module_manager, if (CIRCUIT_MODEL_LUT != circuit_lib.model_type(lut_model)) { continue; } + /* We skip user-defined models */ + if ( (false == circuit_lib.model_verilog_netlist(lut_model).empty()) + || (false == circuit_lib.model_spice_netlist(lut_model).empty()) ) { + continue; + } build_lut_module(module_manager, circuit_lib, lut_model); } } diff --git a/openfpga/src/fabric/build_mux_modules.cpp b/openfpga/src/fabric/build_mux_modules.cpp index fcf0db026..10b693cfc 100644 --- a/openfpga/src/fabric/build_mux_modules.cpp +++ b/openfpga/src/fabric/build_mux_modules.cpp @@ -734,8 +734,18 @@ vtr::vector build_mux_module_input_buffers(ModuleManage const MuxGraph& mux_graph) { vtr::vector mux_input_nets(mux_graph.num_inputs(), ModuleNetId::INVALID()); - /* Get the input ports from the mux */ - std::vector mux_input_ports = circuit_lib.model_ports_by_type(mux_model, CIRCUIT_MODEL_PORT_INPUT, true); + /* Get the input ports from the mux: + * - LUT may have ports that are driven by harden logic, + * which should not be included when building the mux graph + */ + std::vector mux_input_ports; + if (CIRCUIT_MODEL_LUT == circuit_lib.model_type(mux_model)) { + mux_input_ports = find_lut_circuit_model_input_port(circuit_lib, mux_model, false); + } else { + VTR_ASSERT(CIRCUIT_MODEL_MUX == circuit_lib.model_type(mux_model)); + mux_input_ports = circuit_lib.model_ports_by_type(mux_model, CIRCUIT_MODEL_PORT_INPUT, true); + } + /* We should have only 1 input port! */ VTR_ASSERT(1 == mux_input_ports.size()); @@ -849,8 +859,18 @@ vtr::vector build_mux_module_output_buffers(ModuleMana /* Create module nets for output ports */ vtr::vector mux_output_nets(mux_graph.num_outputs(), ModuleNetId::INVALID()); - /* Get the output ports from the mux */ - std::vector mux_output_ports = circuit_lib.model_ports_by_type(mux_model, CIRCUIT_MODEL_PORT_OUTPUT, false); + /* Get the output ports from the mux: + * - LUT may have ports that are driven by harden logic, + * which should not be included when building the mux graph + * - LUT may have global output ports that are wired directly to top-level module + */ + std::vector mux_output_ports; + if (CIRCUIT_MODEL_LUT == circuit_lib.model_type(mux_model)) { + mux_output_ports = find_lut_circuit_model_output_port(circuit_lib, mux_model, false, false); + } else { + VTR_ASSERT(CIRCUIT_MODEL_MUX == circuit_lib.model_type(mux_model)); + mux_output_ports = circuit_lib.model_ports_by_type(mux_model, CIRCUIT_MODEL_PORT_OUTPUT, false); + } /* Iterate over all the outputs in the MUX module */ for (const auto& output_port : mux_output_ports) { @@ -1096,10 +1116,32 @@ void build_cmos_mux_module(ModuleManager& module_manager, const MuxGraph& mux_graph) { /* Get the global ports required by MUX (and any submodules) */ std::vector mux_global_ports = circuit_lib.model_global_ports_by_type(mux_model, CIRCUIT_MODEL_PORT_INPUT, true, true); - /* Get the input ports from the mux */ - std::vector mux_input_ports = circuit_lib.model_ports_by_type(mux_model, CIRCUIT_MODEL_PORT_INPUT, true); - /* Get the output ports from the mux */ - std::vector mux_output_ports = circuit_lib.model_ports_by_type(mux_model, CIRCUIT_MODEL_PORT_OUTPUT, false); + + /* Get the input ports from the mux: + * - LUT may have ports that are driven by harden logic, + * which should not be included when building the mux graph + */ + std::vector mux_input_ports; + if (CIRCUIT_MODEL_LUT == circuit_lib.model_type(mux_model)) { + mux_input_ports = find_lut_circuit_model_input_port(circuit_lib, mux_model, false); + } else { + VTR_ASSERT(CIRCUIT_MODEL_MUX == circuit_lib.model_type(mux_model)); + mux_input_ports = circuit_lib.model_ports_by_type(mux_model, CIRCUIT_MODEL_PORT_INPUT, true); + } + + /* Get the output ports from the mux: + * - LUT may have ports that are driven by harden logic, + * which should not be included when building the mux graph + * - LUT may have global output ports that are wired directly to top-level module + */ + std::vector mux_output_ports; + if (CIRCUIT_MODEL_LUT == circuit_lib.model_type(mux_model)) { + mux_output_ports = find_lut_circuit_model_output_port(circuit_lib, mux_model, false, false); + } else { + VTR_ASSERT(CIRCUIT_MODEL_MUX == circuit_lib.model_type(mux_model)); + mux_output_ports = circuit_lib.model_ports_by_type(mux_model, CIRCUIT_MODEL_PORT_OUTPUT, false); + } + /* Get the sram ports from the mux * Multiplexing structure does not mode_sram_ports, they are handled in LUT modules * Here we just bypass it. diff --git a/openfpga/src/fpga_bitstream/build_grid_bitstream.cpp b/openfpga/src/fpga_bitstream/build_grid_bitstream.cpp index 3062c126f..c7eca7aee 100644 --- a/openfpga/src/fpga_bitstream/build_grid_bitstream.cpp +++ b/openfpga/src/fpga_bitstream/build_grid_bitstream.cpp @@ -407,7 +407,7 @@ void build_lut_bitstream(BitstreamManager& bitstream_manager, VTR_ASSERT(CIRCUIT_MODEL_LUT == circuit_lib.model_type(lut_model)); /* Find the input ports for LUT size, this is used to decode the LUT memory bits! */ - std::vector model_input_ports = circuit_lib.model_ports_by_type(lut_model, CIRCUIT_MODEL_PORT_INPUT, true); + std::vector model_input_ports = find_lut_circuit_model_input_port(circuit_lib, lut_model, false); VTR_ASSERT(1 == model_input_ports.size()); size_t lut_size = circuit_lib.port_size(model_input_ports[0]); diff --git a/openfpga/src/fpga_sdc/configure_port_sdc_writer.cpp b/openfpga/src/fpga_sdc/configure_port_sdc_writer.cpp index 42d5c030c..861dac33d 100644 --- a/openfpga/src/fpga_sdc/configure_port_sdc_writer.cpp +++ b/openfpga/src/fpga_sdc/configure_port_sdc_writer.cpp @@ -89,7 +89,9 @@ int print_sdc_disable_lut_configure_ports(std::fstream& fp, } const std::string& sram_inv_port_name = circuit_lib.port_lib_name(sram_port) + INV_PORT_POSTFIX; - VTR_ASSERT(true == module_manager.valid_module_port_id(programmable_module, module_manager.find_module_port(programmable_module, sram_inv_port_name))); + if (false == module_manager.valid_module_port_id(programmable_module, module_manager.find_module_port(programmable_module, sram_inv_port_name))) { + continue; + } if (CMD_EXEC_FATAL_ERROR == rec_print_sdc_disable_timing_for_module_ports(fp, flatten_names, diff --git a/openfpga/src/mux_lib/mux_library_builder.cpp b/openfpga/src/mux_lib/mux_library_builder.cpp index 3657972ff..599914de8 100644 --- a/openfpga/src/mux_lib/mux_library_builder.cpp +++ b/openfpga/src/mux_lib/mux_library_builder.cpp @@ -11,6 +11,7 @@ /* Headers from readarchopenfpga library */ #include "circuit_types.h" #include "circuit_library.h" +#include "circuit_library_utils.h" #include "mux_utils.h" #include "pb_type_utils.h" @@ -182,7 +183,7 @@ void build_lut_mux_library(MuxLibrary& mux_lib, } /* Find the MUX size required by the LUT */ /* Get input ports which are not global ports! */ - std::vector input_ports = circuit_lib.model_ports_by_type(circuit_model, CIRCUIT_MODEL_PORT_INPUT, true); + std::vector input_ports = find_lut_circuit_model_input_port(circuit_lib, circuit_model, false); VTR_ASSERT(1 == input_ports.size()); /* MUX size = 2^lut_size */ size_t lut_mux_size = (size_t)pow(2., (double)(circuit_lib.port_size(input_ports[0]))); diff --git a/openfpga/src/repack/build_physical_truth_table.cpp b/openfpga/src/repack/build_physical_truth_table.cpp index 404911a2d..37dfa231c 100644 --- a/openfpga/src/repack/build_physical_truth_table.cpp +++ b/openfpga/src/repack/build_physical_truth_table.cpp @@ -50,39 +50,47 @@ static std::vector generate_lut_rotated_input_pin_map(const std::vector& input_nets, const AtomContext& atom_ctx, const AtomBlockId& atom_blk, + const VprDeviceAnnotation& device_annotation, + const CircuitLibrary& circuit_lib, const t_pb_graph_node* pb_graph_node) { /* Find the pin rotation status and record it , * Note that some LUT inputs may not be used, we set them to be open by default */ std::vector rotated_pin_map(input_nets.size(), -1); - VTR_ASSERT(1 == pb_graph_node->num_input_ports); + for (int iport = 0; iport < pb_graph_node->num_input_ports; ++iport) { + for (int ipin = 0; ipin < pb_graph_node->num_input_pins[iport]; ++ipin) { + /* Skip the input pin that do not drive by LUT MUXes */ + CircuitPortId circuit_port = device_annotation.pb_circuit_port(pb_graph_node->input_pins[iport][ipin].port); + if (true == circuit_lib.port_is_harden_lut_port(circuit_port)) { + continue; + } - for (int ipin = 0; ipin < pb_graph_node->num_input_pins[0]; ++ipin) { - /* The lut pb_graph_node may not be the primitive node - * because VPR adds two default modes to its LUT pb_type - * If so, we will use the LUT mode of the pb_graph node - */ - t_port* lut_pb_type_in_port = pb_graph_node->input_pins[0][ipin].port; - if (0 != pb_graph_node->pb_type->num_modes) { - VTR_ASSERT(2 == pb_graph_node->pb_type->num_modes); - VTR_ASSERT(1 == pb_graph_node->pb_type->modes[VPR_PB_TYPE_LUT_MODE].num_pb_type_children); - lut_pb_type_in_port = &(pb_graph_node->pb_type->modes[VPR_PB_TYPE_LUT_MODE].pb_type_children[0].ports[0]); - VTR_ASSERT(std::string(lut_pb_type_in_port->name) == std::string(pb_graph_node->input_pins[0][ipin].port->name)); - VTR_ASSERT(lut_pb_type_in_port->num_pins == pb_graph_node->input_pins[0][ipin].port->num_pins); - } + /* The lut pb_graph_node may not be the primitive node + * because VPR adds two default modes to its LUT pb_type + * If so, we will use the LUT mode of the pb_graph node + */ + t_port* lut_pb_type_in_port = pb_graph_node->input_pins[iport][ipin].port; + if (0 != pb_graph_node->pb_type->num_modes) { + VTR_ASSERT(2 == pb_graph_node->pb_type->num_modes); + VTR_ASSERT(1 == pb_graph_node->pb_type->modes[VPR_PB_TYPE_LUT_MODE].num_pb_type_children); + lut_pb_type_in_port = &(pb_graph_node->pb_type->modes[VPR_PB_TYPE_LUT_MODE].pb_type_children[0].ports[iport]); + VTR_ASSERT(std::string(lut_pb_type_in_port->name) == std::string(pb_graph_node->input_pins[iport][ipin].port->name)); + VTR_ASSERT(lut_pb_type_in_port->num_pins == pb_graph_node->input_pins[iport][ipin].port->num_pins); + } - /* Port exists (some LUTs may have no input and hence no port in the atom netlist) */ - AtomPortId atom_port = atom_ctx.nlist.find_atom_port(atom_blk, lut_pb_type_in_port->model_port); - if (!atom_port) { - continue; - } + /* Port exists (some LUTs may have no input and hence no port in the atom netlist) */ + AtomPortId atom_port = atom_ctx.nlist.find_atom_port(atom_blk, lut_pb_type_in_port->model_port); + if (!atom_port) { + continue; + } - for (AtomPinId atom_pin : atom_ctx.nlist.port_pins(atom_port)) { - AtomNetId atom_pin_net = atom_ctx.nlist.pin_net(atom_pin); - if (atom_pin_net == input_nets[ipin]) { - rotated_pin_map[ipin] = atom_ctx.nlist.pin_port_bit(atom_pin); - break; + for (AtomPinId atom_pin : atom_ctx.nlist.port_pins(atom_port)) { + AtomNetId atom_pin_net = atom_ctx.nlist.pin_net(atom_pin); + if (atom_pin_net == input_nets[ipin]) { + rotated_pin_map[ipin] = atom_ctx.nlist.pin_port_bit(atom_pin); + break; + } } } } @@ -109,15 +117,27 @@ void build_physical_pb_lut_truth_tables(PhysicalPb& physical_pb, /* Find all the nets mapped to each inputs */ std::vector input_nets; - VTR_ASSERT(1 == pb_graph_node->num_input_ports); - for (int ipin = 0; ipin < pb_graph_node->num_input_pins[0]; ++ipin) { - input_nets.push_back(physical_pb.pb_graph_pin_atom_net(lut_pb_id, &(pb_graph_node->input_pins[0][ipin]))); + for (int iport = 0; iport < pb_graph_node->num_input_ports; ++iport) { + for (int ipin = 0; ipin < pb_graph_node->num_input_pins[iport]; ++ipin) { + /* Skip the input pin that do not drive by LUT MUXes */ + CircuitPortId circuit_port = device_annotation.pb_circuit_port(pb_graph_node->input_pins[iport][ipin].port); + if (true == circuit_lib.port_is_harden_lut_port(circuit_port)) { + continue; + } + input_nets.push_back(physical_pb.pb_graph_pin_atom_net(lut_pb_id, &(pb_graph_node->input_pins[iport][ipin]))); + } } /* Find all the nets mapped to each outputs */ for (int iport = 0; iport < pb_graph_node->num_output_ports; ++iport) { for (int ipin = 0; ipin < pb_graph_node->num_output_pins[iport]; ++ipin) { const t_pb_graph_pin* output_pin = &(pb_graph_node->output_pins[iport][ipin]); + /* Skip the output ports that are not driven by LUT MUXes */ + CircuitPortId circuit_port = device_annotation.pb_circuit_port(output_pin->port); + if (true == circuit_lib.port_is_harden_lut_port(circuit_port)) { + continue; + } + AtomNetId output_net = physical_pb.pb_graph_pin_atom_net(lut_pb_id, output_pin); /* Bypass unmapped pins */ if (AtomNetId::INVALID() == output_net) { @@ -135,7 +155,7 @@ void build_physical_pb_lut_truth_tables(PhysicalPb& physical_pb, VTR_ASSERT(true == atom_ctx.nlist.valid_block_id(atom_blk)); const AtomNetlist::TruthTable& orig_tt = atom_ctx.nlist.block_truth_table(atom_blk); - std::vector rotated_pin_map = generate_lut_rotated_input_pin_map(input_nets, atom_ctx, atom_blk, pb_graph_node); + std::vector rotated_pin_map = generate_lut_rotated_input_pin_map(input_nets, atom_ctx, atom_blk, device_annotation, circuit_lib, pb_graph_node); adapt_tt = lut_truth_table_adaption(orig_tt, rotated_pin_map); } diff --git a/openfpga/src/utils/circuit_library_utils.cpp b/openfpga/src/utils/circuit_library_utils.cpp index 8fb5aa7bc..197c873bd 100644 --- a/openfpga/src/utils/circuit_library_utils.cpp +++ b/openfpga/src/utils/circuit_library_utils.cpp @@ -368,4 +368,54 @@ CircuitPortId find_circuit_model_power_gate_enb_port(const CircuitLibrary& circu return enb_port; } +/************************************************************************ + * Try to find the input ports for a LUT circuit model (EXCLUDE the global ports) + * which can optionally include those ports drives or is driven by hard logic + ***********************************************************************/ +std::vector find_lut_circuit_model_input_port(const CircuitLibrary& circuit_lib, + const CircuitModelId& circuit_model, + const bool& include_harden_port, + const bool& include_global_port) { + VTR_ASSERT(CIRCUIT_MODEL_LUT == circuit_lib.model_type(circuit_model)); + + std::vector input_ports; + + /* Find all the non-global input ports */ + for (const auto& port : circuit_lib.model_ports_by_type(circuit_model, CIRCUIT_MODEL_PORT_INPUT, !include_global_port)) { + /* Skip harden ports if specified */ + if ( (true == circuit_lib.port_is_harden_lut_port(port)) + && (false == include_harden_port)) { + continue; + } + input_ports.push_back(port); + } + + return input_ports; +} + +/************************************************************************ + * Try to find the output ports for a LUT circuit model (EXCLUDE the global ports) + * which can optionally include those ports drives or is driven by hard logic + ***********************************************************************/ +std::vector find_lut_circuit_model_output_port(const CircuitLibrary& circuit_lib, + const CircuitModelId& circuit_model, + const bool& include_harden_port, + const bool& include_global_port) { + VTR_ASSERT(CIRCUIT_MODEL_LUT == circuit_lib.model_type(circuit_model)); + + std::vector output_ports; + + /* Find all the non-global input ports */ + for (const auto& port : circuit_lib.model_ports_by_type(circuit_model, CIRCUIT_MODEL_PORT_OUTPUT, !include_global_port)) { + /* Skip harden ports if specified */ + if ( (true == circuit_lib.port_is_harden_lut_port(port)) + && (false == include_harden_port)) { + continue; + } + output_ports.push_back(port); + } + + return output_ports; +} + } /* end namespace openfpga */ diff --git a/openfpga/src/utils/circuit_library_utils.h b/openfpga/src/utils/circuit_library_utils.h index dc7fd0e34..758af9689 100644 --- a/openfpga/src/utils/circuit_library_utils.h +++ b/openfpga/src/utils/circuit_library_utils.h @@ -51,6 +51,16 @@ CircuitPortId find_circuit_model_power_gate_en_port(const CircuitLibrary& circui CircuitPortId find_circuit_model_power_gate_enb_port(const CircuitLibrary& circuit_lib, const CircuitModelId& circuit_model); +std::vector find_lut_circuit_model_input_port(const CircuitLibrary& circuit_lib, + const CircuitModelId& circuit_model, + const bool& include_harden_port, + const bool& include_global_port = true); + +std::vector find_lut_circuit_model_output_port(const CircuitLibrary& circuit_lib, + const CircuitModelId& circuit_model, + const bool& include_harden_port, + const bool& include_global_port = true); + } /* end namespace openfpga */ #endif From b81b74aa7cf7c15df78caed217f023fd0a538000 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Tue, 9 Feb 2021 20:23:32 -0700 Subject: [PATCH 22/28] [Arch] Patch architecture to support superLUT-related XML syntax --- ...r_scan_chain_caravel_io_skywater130nm_fdhd_cc_openfpga.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openfpga_flow/openfpga_arch/k4_frac_N8_reset_softadderSuperLUT_register_scan_chain_caravel_io_skywater130nm_fdhd_cc_openfpga.xml b/openfpga_flow/openfpga_arch/k4_frac_N8_reset_softadderSuperLUT_register_scan_chain_caravel_io_skywater130nm_fdhd_cc_openfpga.xml index 27747891e..e00faa1d1 100644 --- a/openfpga_flow/openfpga_arch/k4_frac_N8_reset_softadderSuperLUT_register_scan_chain_caravel_io_skywater130nm_fdhd_cc_openfpga.xml +++ b/openfpga_flow/openfpga_arch/k4_frac_N8_reset_softadderSuperLUT_register_scan_chain_caravel_io_skywater130nm_fdhd_cc_openfpga.xml @@ -168,10 +168,10 @@ - + - + From 22e675148e00e0909637226beebf26d77f525ae0 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Tue, 9 Feb 2021 21:13:22 -0700 Subject: [PATCH 23/28] [HDL] Add HDL codes for a super LUT with embedded carry logic --- .../verilog/frac_lut4_arith.v | 270 ++++++++++++++++++ 1 file changed, 270 insertions(+) create mode 100644 openfpga_flow/openfpga_cell_library/verilog/frac_lut4_arith.v diff --git a/openfpga_flow/openfpga_cell_library/verilog/frac_lut4_arith.v b/openfpga_flow/openfpga_cell_library/verilog/frac_lut4_arith.v new file mode 100644 index 000000000..9a5af98af --- /dev/null +++ b/openfpga_flow/openfpga_cell_library/verilog/frac_lut4_arith.v @@ -0,0 +1,270 @@ +//----------------------------------------------------- +// Design Name : frac_lut4_arith +// File Name : frac_lut4_arith.v +// Function : 4-input Look Up Table with integrated carry logic +// - mode_bit[0] switch between arithmetic mode and LUT mode +// - mode_bit[1] switch between regular LUT mode and fracturable +// mode +// Coder : Xifan TANG +//----------------------------------------------------- +module frac_lut4_arith ( +input [0:3] in, +input [0:0] cin, +output [0:1] lut3_out, +output [0:0] lut4_out, +output [0:0] cout, +input [0:15] sram, +input [0:1] mode); + +//----- BEGIN wire-connection ports ----- +wire [0:3] in; +wire [0:0] cin; +wire [0:1] lut2_out; +wire [0:1] lut3_out; +wire [0:0] lut4_out; +wire [0:0] cout; +wire [0:0] arith_in2; +//----- END wire-connection ports ----- + + +//----- BEGIN Registered ports ----- +//----- END Registered ports ----- + + +wire [0:0] sky130_fd_sc_hd__buf_2_0_X; +wire [0:0] sky130_fd_sc_hd__buf_2_1_X; +wire [0:0] sky130_fd_sc_hd__buf_2_2_X; +wire [0:0] sky130_fd_sc_hd__buf_2_3_X; +wire [0:0] sky130_fd_sc_hd__inv_1_0_Y; +wire [0:0] sky130_fd_sc_hd__inv_1_1_Y; +wire [0:0] sky130_fd_sc_hd__inv_1_2_Y; +wire [0:0] sky130_fd_sc_hd__inv_1_3_Y; +wire [0:0] sky130_fd_sc_hd__or2_1_0_X; + +// ----- BEGIN Local short connections ----- +// ----- END Local short connections ----- +// ----- BEGIN Local output short connections ----- +// ----- END Local output short connections ----- + + sky130_fd_sc_hd__or2_1 sky130_fd_sc_hd__or2_1_0_ ( + .A(mode[1]), + .B(in[3]), + .X(sky130_fd_sc_hd__or2_1_0_X[0])); + + sky130_fd_sc_hd__inv_1 sky130_fd_sc_hd__inv_1_0_ ( + .A(in[0]), + .Y(sky130_fd_sc_hd__inv_1_0_Y[0])); + + sky130_fd_sc_hd__inv_1 sky130_fd_sc_hd__inv_1_1_ ( + .A(in[1]), + .Y(sky130_fd_sc_hd__inv_1_1_Y[0])); + + assign arith_in2 = mode[0] ? in[2] : cin; + + sky130_fd_sc_hd__inv_1 sky130_fd_sc_hd__inv_1_2_ ( + .A(arith_in2), + .Y(sky130_fd_sc_hd__inv_1_2_Y[0])); + + sky130_fd_sc_hd__inv_1 sky130_fd_sc_hd__inv_1_3_ ( + .A(sky130_fd_sc_hd__or2_1_0_X[0]), + .Y(sky130_fd_sc_hd__inv_1_3_Y[0])); + + sky130_fd_sc_hd__buf_2 sky130_fd_sc_hd__buf_2_0_ ( + .A(in[0]), + .X(sky130_fd_sc_hd__buf_2_0_X[0])); + + sky130_fd_sc_hd__buf_2 sky130_fd_sc_hd__buf_2_1_ ( + .A(in[1]), + .X(sky130_fd_sc_hd__buf_2_1_X[0])); + + sky130_fd_sc_hd__buf_2 sky130_fd_sc_hd__buf_2_2_ ( + .A(in[2]), + .X(sky130_fd_sc_hd__buf_2_2_X[0])); + + sky130_fd_sc_hd__buf_2 sky130_fd_sc_hd__buf_2_3_ ( + .A(sky130_fd_sc_hd__or2_1_0_X[0]), + .X(sky130_fd_sc_hd__buf_2_3_X[0])); + + frac_lut4_mux frac_lut4_mux_0_ ( + .in(sram[0:15]), + .sram({sky130_fd_sc_hd__buf_2_0_X[0], sky130_fd_sc_hd__buf_2_1_X[0], sky130_fd_sc_hd__buf_2_2_X[0], sky130_fd_sc_hd__buf_2_3_X[0]}), + .sram_inv({sky130_fd_sc_hd__inv_1_0_Y[0], sky130_fd_sc_hd__inv_1_1_Y[0], sky130_fd_sc_hd__inv_1_2_Y[0], sky130_fd_sc_hd__inv_1_3_Y[0]}), + .lut2_out(lut2_out[0:1]), + .lut3_out(lut3_out[0:1]), + .lut4_out(lut4_out[0])); + + assign cout = lut2_out[0] ? cin : lut2_out[1]; + +endmodule + +// ----- Verilog module for frac_lut4_mux ----- +module frac_lut4_mux(in, + sram, + sram_inv, + lut2_out, + lut3_out, + lut4_out); +//----- INPUT PORTS ----- +input [0:15] in; +//----- INPUT PORTS ----- +input [0:3] sram; +//----- INPUT PORTS ----- +input [0:3] sram_inv; +//----- OUTPUT PORTS ----- +output [0:1] lut2_out; +//----- OUTPUT PORTS ----- +output [0:1] lut3_out; +//----- OUTPUT PORTS ----- +output [0:0] lut4_out; + +//----- BEGIN wire-connection ports ----- +//----- END wire-connection ports ----- + + +//----- BEGIN Registered ports ----- +//----- END Registered ports ----- + + +wire [0:0] sky130_fd_sc_hd__buf_2_5_X; +wire [0:0] sky130_fd_sc_hd__buf_2_6_X; +wire [0:0] sky130_fd_sc_hd__mux2_1_0_X; +wire [0:0] sky130_fd_sc_hd__mux2_1_10_X; +wire [0:0] sky130_fd_sc_hd__mux2_1_11_X; +wire [0:0] sky130_fd_sc_hd__mux2_1_12_X; +wire [0:0] sky130_fd_sc_hd__mux2_1_13_X; +wire [0:0] sky130_fd_sc_hd__mux2_1_14_X; +wire [0:0] sky130_fd_sc_hd__mux2_1_1_X; +wire [0:0] sky130_fd_sc_hd__mux2_1_2_X; +wire [0:0] sky130_fd_sc_hd__mux2_1_3_X; +wire [0:0] sky130_fd_sc_hd__mux2_1_4_X; +wire [0:0] sky130_fd_sc_hd__mux2_1_5_X; +wire [0:0] sky130_fd_sc_hd__mux2_1_6_X; +wire [0:0] sky130_fd_sc_hd__mux2_1_7_X; +wire [0:0] sky130_fd_sc_hd__mux2_1_8_X; +wire [0:0] sky130_fd_sc_hd__mux2_1_9_X; + +// ----- BEGIN Local short connections ----- +// ----- END Local short connections ----- +// ----- BEGIN Local output short connections ----- +// ----- END Local output short connections ----- + + sky130_fd_sc_hd__buf_2 sky130_fd_sc_hd__buf_2_0_ ( + .A(sky130_fd_sc_hd__mux2_1_10_X[0]), + .X(lut2_out[0])); + + sky130_fd_sc_hd__buf_2 sky130_fd_sc_hd__buf_2_1_ ( + .A(sky130_fd_sc_hd__mux2_1_11_X[0]), + .X(lut2_out[1])); + + sky130_fd_sc_hd__buf_2 sky130_fd_sc_hd__buf_2_2_ ( + .A(sky130_fd_sc_hd__mux2_1_12_X[0]), + .X(lut3_out[0])); + + sky130_fd_sc_hd__buf_2 sky130_fd_sc_hd__buf_2_3_ ( + .A(sky130_fd_sc_hd__mux2_1_13_X[0]), + .X(lut3_out[1])); + + sky130_fd_sc_hd__buf_2 sky130_fd_sc_hd__buf_2_4_ ( + .A(sky130_fd_sc_hd__mux2_1_14_X[0]), + .X(lut4_out[0])); + + sky130_fd_sc_hd__buf_2 sky130_fd_sc_hd__buf_2_5_ ( + .A(sky130_fd_sc_hd__mux2_1_8_X[0]), + .X(sky130_fd_sc_hd__buf_2_5_X[0])); + + sky130_fd_sc_hd__buf_2 sky130_fd_sc_hd__buf_2_6_ ( + .A(sky130_fd_sc_hd__mux2_1_9_X[0]), + .X(sky130_fd_sc_hd__buf_2_6_X[0])); + + sky130_fd_sc_hd__mux2_1 mux_l1_in_0_ ( + .A1(in[0]), + .A0(in[1]), + .S(sram[0]), + .X(sky130_fd_sc_hd__mux2_1_0_X[0])); + + sky130_fd_sc_hd__mux2_1 mux_l1_in_1_ ( + .A1(in[2]), + .A0(in[3]), + .S(sram[0]), + .X(sky130_fd_sc_hd__mux2_1_1_X[0])); + + sky130_fd_sc_hd__mux2_1 mux_l1_in_2_ ( + .A1(in[4]), + .A0(in[5]), + .S(sram[0]), + .X(sky130_fd_sc_hd__mux2_1_2_X[0])); + + sky130_fd_sc_hd__mux2_1 mux_l1_in_3_ ( + .A1(in[6]), + .A0(in[7]), + .S(sram[0]), + .X(sky130_fd_sc_hd__mux2_1_3_X[0])); + + sky130_fd_sc_hd__mux2_1 mux_l1_in_4_ ( + .A1(in[8]), + .A0(in[9]), + .S(sram[0]), + .X(sky130_fd_sc_hd__mux2_1_4_X[0])); + + sky130_fd_sc_hd__mux2_1 mux_l1_in_5_ ( + .A1(in[10]), + .A0(in[11]), + .S(sram[0]), + .X(sky130_fd_sc_hd__mux2_1_5_X[0])); + + sky130_fd_sc_hd__mux2_1 mux_l1_in_6_ ( + .A1(in[12]), + .A0(in[13]), + .S(sram[0]), + .X(sky130_fd_sc_hd__mux2_1_6_X[0])); + + sky130_fd_sc_hd__mux2_1 mux_l1_in_7_ ( + .A1(in[14]), + .A0(in[15]), + .S(sram[0]), + .X(sky130_fd_sc_hd__mux2_1_7_X[0])); + + sky130_fd_sc_hd__mux2_1 mux_l2_in_0_ ( + .A1(sky130_fd_sc_hd__mux2_1_0_X[0]), + .A0(sky130_fd_sc_hd__mux2_1_1_X[0]), + .S(sram[1]), + .X(sky130_fd_sc_hd__mux2_1_8_X[0])); + + sky130_fd_sc_hd__mux2_1 mux_l2_in_1_ ( + .A1(sky130_fd_sc_hd__mux2_1_2_X[0]), + .A0(sky130_fd_sc_hd__mux2_1_3_X[0]), + .S(sram[1]), + .X(sky130_fd_sc_hd__mux2_1_9_X[0])); + + sky130_fd_sc_hd__mux2_1 mux_l2_in_2_ ( + .A1(sky130_fd_sc_hd__mux2_1_4_X[0]), + .A0(sky130_fd_sc_hd__mux2_1_5_X[0]), + .S(sram[1]), + .X(sky130_fd_sc_hd__mux2_1_10_X[0])); + + sky130_fd_sc_hd__mux2_1 mux_l2_in_3_ ( + .A1(sky130_fd_sc_hd__mux2_1_6_X[0]), + .A0(sky130_fd_sc_hd__mux2_1_7_X[0]), + .S(sram[1]), + .X(sky130_fd_sc_hd__mux2_1_11_X[0])); + + sky130_fd_sc_hd__mux2_1 mux_l3_in_0_ ( + .A1(sky130_fd_sc_hd__buf_2_5_X[0]), + .A0(sky130_fd_sc_hd__buf_2_6_X[0]), + .S(sram[2]), + .X(sky130_fd_sc_hd__mux2_1_12_X[0])); + + sky130_fd_sc_hd__mux2_1 mux_l3_in_1_ ( + .A1(sky130_fd_sc_hd__mux2_1_10_X[0]), + .A0(sky130_fd_sc_hd__mux2_1_11_X[0]), + .S(sram[2]), + .X(sky130_fd_sc_hd__mux2_1_13_X[0])); + + sky130_fd_sc_hd__mux2_1 mux_l4_in_0_ ( + .A1(sky130_fd_sc_hd__mux2_1_12_X[0]), + .A0(sky130_fd_sc_hd__mux2_1_13_X[0]), + .S(sram[3]), + .X(sky130_fd_sc_hd__mux2_1_14_X[0])); + +endmodule +// ----- END Verilog module for frac_lut4_mux ----- \ No newline at end of file From be24c904afa3d8a381c5dbbb17e7dae7f9bf63d0 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Tue, 9 Feb 2021 21:15:21 -0700 Subject: [PATCH 24/28] [Test] Add superLUT test case to CI --- .github/workflows/fpga_verilog_reg_test.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/fpga_verilog_reg_test.sh b/.github/workflows/fpga_verilog_reg_test.sh index 7b7aad6b0..2f5b917dc 100755 --- a/.github/workflows/fpga_verilog_reg_test.sh +++ b/.github/workflows/fpga_verilog_reg_test.sh @@ -14,6 +14,9 @@ run-task fpga_verilog/lut_design/single_mode --debug --show_thread_logs echo -e "Testing Verilog generation for LUTs: simple fracturable LUT4 "; run-task fpga_verilog/lut_design/frac_lut4 --debug --show_thread_logs +echo -e "Testing Verilog generation for LUTs: fracturable LUT4 with embedded carry logic"; +run-task fpga_verilog/lut_design/frac_lut4_arith --debug --show_thread_logs + echo -e "Testing Verilog generation for LUTs: native fracturable LUT4 "; run-task fpga_verilog/lut_design/frac_native_lut4 --debug --show_thread_logs From b2984b46eeefc61e0bb582d80c41c83e4dd48f3b Mon Sep 17 00:00:00 2001 From: tangxifan Date: Tue, 9 Feb 2021 21:15:57 -0700 Subject: [PATCH 25/28] [Tool] Upgrade libopenfpga to support superLUT-related XML syntax --- .../libarchopenfpga/src/circuit_library.cpp | 19 +++++++++++++++++++ .../libarchopenfpga/src/circuit_library.h | 4 ++++ .../src/read_xml_circuit_library.cpp | 10 ++++++++++ .../src/write_xml_circuit_library.cpp | 8 ++++++++ 4 files changed, 41 insertions(+) diff --git a/libopenfpga/libarchopenfpga/src/circuit_library.cpp b/libopenfpga/libarchopenfpga/src/circuit_library.cpp index f63cbcfd3..f56b94199 100644 --- a/libopenfpga/libarchopenfpga/src/circuit_library.cpp +++ b/libopenfpga/libarchopenfpga/src/circuit_library.cpp @@ -964,6 +964,13 @@ size_t CircuitLibrary::port_lut_frac_level(const CircuitPortId& circuit_port_id) return port_lut_frac_level_[circuit_port_id]; } +/* Return if the port drives or is driven by a harden logic inside a LUT */ +bool CircuitLibrary::port_is_harden_lut_port(const CircuitPortId& circuit_port_id) const { + /* validate the circuit_port_id */ + VTR_ASSERT(valid_circuit_port_id(circuit_port_id)); + return port_is_harden_lut_port_[circuit_port_id]; +} + /* Return indices of internal nodes in a LUT multiplexing structure to which the output port is wired to */ std::vector CircuitLibrary::port_lut_output_mask(const CircuitPortId& circuit_port_id) const { /* validate the circuit_port_id */ @@ -1390,6 +1397,7 @@ CircuitPortId CircuitLibrary::add_model_port(const CircuitModelId& model_id, port_inv_model_ids_.push_back(CircuitModelId::INVALID()); port_tri_state_maps_.emplace_back(); port_lut_frac_level_.push_back(-1); + port_is_harden_lut_port_.push_back(false); port_lut_output_masks_.emplace_back(); port_sram_orgz_.push_back(NUM_CONFIG_PROTOCOL_TYPES); @@ -1576,6 +1584,17 @@ void CircuitLibrary::set_port_lut_frac_level(const CircuitPortId& circuit_port_i return; } +/* Set the LUT fracturable level for a port of a circuit model, only applicable to LUTs */ +void CircuitLibrary::set_port_is_harden_lut_port(const CircuitPortId& circuit_port_id, + const bool& is_harden_lut_port) { + /* validate the circuit_port_id */ + VTR_ASSERT(valid_circuit_port_id(circuit_port_id)); + /* Make sure this is a LUT */ + VTR_ASSERT(CIRCUIT_MODEL_LUT == model_type(port_model_ids_[circuit_port_id])); + port_is_harden_lut_port_[circuit_port_id] = is_harden_lut_port; + return; +} + /* Set the LUT fracturable level for a port of a circuit model, only applicable to LUTs */ void CircuitLibrary::set_port_lut_output_mask(const CircuitPortId& circuit_port_id, const std::vector& lut_output_masks) { diff --git a/libopenfpga/libarchopenfpga/src/circuit_library.h b/libopenfpga/libarchopenfpga/src/circuit_library.h index 415d1d4be..d2feee52b 100644 --- a/libopenfpga/libarchopenfpga/src/circuit_library.h +++ b/libopenfpga/libarchopenfpga/src/circuit_library.h @@ -289,6 +289,7 @@ class CircuitLibrary { bool port_is_config_enable(const CircuitPortId& circuit_port_id) const; bool port_is_prog(const CircuitPortId& circuit_port_id) const; size_t port_lut_frac_level(const CircuitPortId& circuit_port_id) const; + bool port_is_harden_lut_port(const CircuitPortId& circuit_port_id) const; std::vector port_lut_output_mask(const CircuitPortId& circuit_port_id) const; std::string port_tri_state_map(const CircuitPortId& circuit_port_id) const; CircuitModelId port_tri_state_model(const CircuitPortId& circuit_port_id) const; @@ -383,6 +384,8 @@ class CircuitLibrary { const std::string& tri_state_map); void set_port_lut_frac_level(const CircuitPortId& circuit_port_id, const size_t& lut_frac_level); + void set_port_is_harden_lut_port(const CircuitPortId& circuit_port_id, + const bool& is_harden_lut_port); void set_port_lut_output_mask(const CircuitPortId& circuit_port_id, const std::vector& lut_output_masks); void set_port_sram_orgz(const CircuitPortId& circuit_port_id, @@ -563,6 +566,7 @@ class CircuitLibrary { vtr::vector port_inv_model_ids_; vtr::vector port_tri_state_maps_; vtr::vector port_lut_frac_level_; + vtr::vector port_is_harden_lut_port_; vtr::vector> port_lut_output_masks_; vtr::vector port_sram_orgz_; diff --git a/libopenfpga/libarchopenfpga/src/read_xml_circuit_library.cpp b/libopenfpga/libarchopenfpga/src/read_xml_circuit_library.cpp index c574e890e..4fc3ddbb4 100644 --- a/libopenfpga/libarchopenfpga/src/read_xml_circuit_library.cpp +++ b/libopenfpga/libarchopenfpga/src/read_xml_circuit_library.cpp @@ -454,6 +454,16 @@ void read_xml_circuit_port(pugi::xml_node& xml_port, circuit_lib.set_port_lut_frac_level(port, get_attribute(xml_port, "lut_frac_level", loc_data, pugiutil::ReqOpt::OPTIONAL).as_int(-1)); } + /* Identify if the port carries a harden functionality rather than a reconfigurable port + * This is only applicable to LUT circuit models. + * The super LUT circuit model (whose netlists are supposed to be provided by users) contains + * some hard logic inside, e.g., a carry logic. + * By default, a port does NOT carry a hard functionality + */ + if (CIRCUIT_MODEL_LUT == circuit_lib.model_type(model)) { + circuit_lib.set_port_is_harden_lut_port(port, get_attribute(xml_port, "is_harden_lut_port", loc_data, pugiutil::ReqOpt::OPTIONAL).as_bool(false)); + } + /* Identify the output mask of the port in LUTs, by default it will be applied to each pin of this port * This is only applicable to output ports of a LUT */ diff --git a/libopenfpga/libarchopenfpga/src/write_xml_circuit_library.cpp b/libopenfpga/libarchopenfpga/src/write_xml_circuit_library.cpp index 954f9044f..f96780a92 100644 --- a/libopenfpga/libarchopenfpga/src/write_xml_circuit_library.cpp +++ b/libopenfpga/libarchopenfpga/src/write_xml_circuit_library.cpp @@ -186,6 +186,14 @@ void write_xml_circuit_port(std::fstream& fp, } } + /* LUT harden port attributes */ + if (CIRCUIT_MODEL_LUT == circuit_lib.model_type(model)) { + if (true == circuit_lib.port_is_harden_lut_port(port)) { + write_xml_attribute(fp, "is_harden_lut_port", "true"); + } + } + + /* I/O port attributes */ if (true == circuit_lib.port_is_io(port)) { write_xml_attribute(fp, "is_io", "true"); From af4cc117fb6069c3621d789fc3f807629e5e2012 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Tue, 9 Feb 2021 22:53:18 -0700 Subject: [PATCH 26/28] [Tool] bug fix in spypad lut --- openfpga/src/fabric/build_mux_modules.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/openfpga/src/fabric/build_mux_modules.cpp b/openfpga/src/fabric/build_mux_modules.cpp index 10b693cfc..2dbee6698 100644 --- a/openfpga/src/fabric/build_mux_modules.cpp +++ b/openfpga/src/fabric/build_mux_modules.cpp @@ -740,7 +740,7 @@ vtr::vector build_mux_module_input_buffers(ModuleManage */ std::vector mux_input_ports; if (CIRCUIT_MODEL_LUT == circuit_lib.model_type(mux_model)) { - mux_input_ports = find_lut_circuit_model_input_port(circuit_lib, mux_model, false); + mux_input_ports = find_lut_circuit_model_input_port(circuit_lib, mux_model, false, false); } else { VTR_ASSERT(CIRCUIT_MODEL_MUX == circuit_lib.model_type(mux_model)); mux_input_ports = circuit_lib.model_ports_by_type(mux_model, CIRCUIT_MODEL_PORT_INPUT, true); @@ -866,7 +866,7 @@ vtr::vector build_mux_module_output_buffers(ModuleMana */ std::vector mux_output_ports; if (CIRCUIT_MODEL_LUT == circuit_lib.model_type(mux_model)) { - mux_output_ports = find_lut_circuit_model_output_port(circuit_lib, mux_model, false, false); + mux_output_ports = find_lut_circuit_model_output_port(circuit_lib, mux_model, false, true); } else { VTR_ASSERT(CIRCUIT_MODEL_MUX == circuit_lib.model_type(mux_model)); mux_output_ports = circuit_lib.model_ports_by_type(mux_model, CIRCUIT_MODEL_PORT_OUTPUT, false); @@ -1123,7 +1123,7 @@ void build_cmos_mux_module(ModuleManager& module_manager, */ std::vector mux_input_ports; if (CIRCUIT_MODEL_LUT == circuit_lib.model_type(mux_model)) { - mux_input_ports = find_lut_circuit_model_input_port(circuit_lib, mux_model, false); + mux_input_ports = find_lut_circuit_model_input_port(circuit_lib, mux_model, false, false); } else { VTR_ASSERT(CIRCUIT_MODEL_MUX == circuit_lib.model_type(mux_model)); mux_input_ports = circuit_lib.model_ports_by_type(mux_model, CIRCUIT_MODEL_PORT_INPUT, true); @@ -1136,7 +1136,7 @@ void build_cmos_mux_module(ModuleManager& module_manager, */ std::vector mux_output_ports; if (CIRCUIT_MODEL_LUT == circuit_lib.model_type(mux_model)) { - mux_output_ports = find_lut_circuit_model_output_port(circuit_lib, mux_model, false, false); + mux_output_ports = find_lut_circuit_model_output_port(circuit_lib, mux_model, false, true); } else { VTR_ASSERT(CIRCUIT_MODEL_MUX == circuit_lib.model_type(mux_model)); mux_output_ports = circuit_lib.model_ports_by_type(mux_model, CIRCUIT_MODEL_PORT_OUTPUT, false); From 1c4dc9f74b75374a75afb86221a81950392b8791 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Wed, 10 Feb 2021 11:49:59 -0700 Subject: [PATCH 27/28] [Doc] Update documentation about the super LUT feature --- .../arch_lang/circuit_model_examples.rst | 65 ++++++- .../arch_lang/figures/lut_arith_example.svg | 177 ++++++++++++++++++ docs/source/overview/tech_highlights.rst | 106 ++++++----- 3 files changed, 293 insertions(+), 55 deletions(-) create mode 100644 docs/source/manual/arch_lang/figures/lut_arith_example.svg diff --git a/docs/source/manual/arch_lang/circuit_model_examples.rst b/docs/source/manual/arch_lang/circuit_model_examples.rst index 263ee1724..a7a6dba97 100644 --- a/docs/source/manual/arch_lang/circuit_model_examples.rst +++ b/docs/source/manual/arch_lang/circuit_model_examples.rst @@ -689,8 +689,8 @@ Template - - + + @@ -736,18 +736,22 @@ Template .. note:: For a LUT, three types of ports (``input``, ``output`` and ``sram``) should be defined. If the user provides an customized Verilog/SPICE netlist, the bandwidth of ports should be defined to the same as the Verilog/SPICE netlist. To support customizable LUTs, each type of port contain special keywords. -.. option:: +.. option:: - ``tri_state_map="[-|1]"`` Customize which inputs are fixed to constant values when the LUT is in fracturable modes. For example, ``tri_state_map="----11"`` indicates that the last two inputs will be fixed to be logic '1' when a 6-input LUT is in fracturable modes. - ``circuit_model_name=""`` Specify the circuit model to build logic gates in order to tri-state the inputs in fracturable LUT modes. It is required to use an ``AND`` gate to force logic '0' or an ``OR`` gate to force logic '1' for the input ports. -.. option:: + - ``is_harden_lut_port="[true|false]"`` Specify if the input drives a harden logic inside a LUT. A harden input is supposed **NOT** to drive any multiplexer input (the internal multiplexer of LUT). As a result, such inputs are not considered to implement any truth table mapped to the LUT. If enabled, the input will **NOT** be considered for wiring to internal multiplexers as well as bitstream generation. By default, an input port is treated **NOT** to be a harden LUT port. + +.. option:: - ``lut_frac_level=""`` Specify the level in LUT multiplexer tree where the output port are wired to. For example, ``lut_frac_level="4"`` in a fracturable LUT6 means that the output are potentially wired to the 4th stage of a LUT multiplexer and it is an output of a LUT4. - ``lut_output_mask=""`` Describe which fracturable outputs are used. For instance, in a 6-LUT, there are potentially four LUT4 outputs can be wired out. ``lut_output_mask="0,2"`` indicates that only the first and the thrid LUT4 outputs will be used in fracturable mode. + - ``is_harden_lut_port="[true|false]"`` Specify if the output is driven by a harden logic inside a LUT. A harden input is supposed **NOT** to be driven by any multiplexer output (the internal multiplexer of LUT). As a result, such outputs are not considered to implement any truth table mapped to the LUT. If enabled, the output will **NOT** be considered for wiring to internal multiplexers as well as bitstream generation. By default, an output port is treated **NOT** to be a harden LUT port. + .. note:: The size of the output port should be consistent to the length of ``lut_output_mask``. .. option:: @@ -912,6 +916,54 @@ This example shows: - There will be two outputs wired to the 5th stage of routing multiplexer (the outputs of dual 5-input LUTs) +.. _circuit_model_lut_harden_logic_example: + +LUT with Harden Logic +````````````````````` +:numref:`fig_lut_arith` illustrates the detailed schematic of a fracturable 4-input LUT coupled with carry logic gates. For fracturable LUT schematic, please refer to :numref:`fig_std_frac_lut`. +This feature allows users to fully customize their LUT circuit implementation while being compatible with OpenFPGA's bitstream generator when mapping truth tables to the LUTs. + +.. warning:: OpenFPGA does **NOT** support netlist autogeneration for the LUT with harden logic. Users should build their own netlist and use ``verilog_netlist`` syntax of :ref:`circuit_library` to include it. + +.. _fig_lut_arith: + +.. figure:: ./figures/lut_arith_example.svg + :scale: 80% + :alt: detailed lut composition + + Detailed schematic of a fracturable 4-input LUT with embedded carry logic. + +The code describing this LUT is: + +.. code-block:: xml + + + + + + + + + + + + + + + + + + +This example shows: + - Fracturable 4-input LUT which is configurable by 16 SRAM cells. + - There are two output wired to the 3th stage of routing multiplexer (the outputs of dual 3-input LUTs) + - There are two outputs wired to the 2th stage of routing multiplexer (the outputs of 2-input LUTs in the in the lower part of SRAM cells). Note that the two outputs drive the embedded carry logic + - There is a harden carry logic, i.e., a 2-input MUX, to implement high-performance carry function. + - There is a mode-switch multiplexer at ``cin`` port, which is used to switch between arithemetic mode and regular LUT mode. + +.. note:: If the embedded harden logic are driven partially by LUT outputs, users may use the :ref:`file_formats_bitstream_setting` to gaurantee correct bitstream generation for the LUTs. + + Flip-Flops ~~~~~~~~~~ @@ -1012,6 +1064,8 @@ This example shows: - The first output port **MUST** be the data output port, e.g., ``Q``. - The second output port **MUST** be the **inverted** data output port, e.g., ``QN``. +.. _circuit_model_ccff_enable_example: + Configuration-chain Flip-flop with Configure Enable Signals ``````````````````````````````````````````````````````````` @@ -1049,6 +1103,9 @@ The code describing this FF is: - The second output port **MUST** be the **inverted** data output port which is activated by the configure enable signal, e.g., ``QN``. - The second output port **MUST** be the data output port which is activated by the configure enable signal, e.g., ``Q``. + +.. _circuit_model_ccff_scanable_example: + Configuration-chain Flip-flop with Scan Input ````````````````````````````````````````````` diff --git a/docs/source/manual/arch_lang/figures/lut_arith_example.svg b/docs/source/manual/arch_lang/figures/lut_arith_example.svg new file mode 100644 index 000000000..42107e8d0 --- /dev/null +++ b/docs/source/manual/arch_lang/figures/lut_arith_example.svg @@ -0,0 +1,177 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + Produced by OmniGraffle 7.18.2\n2021-02-10 18:07:14 +0000 + + arith_lut + + 图层 1 + + + + + + + + + + + + Fractu + rable + 4-LUT + + + + + + + + + + + in3 + + + + + in0 + + + + + in1 + + + + + in2 + + + + + + + + LUT4_out + + + + + + + + + + + + + + LUT3_out[0] + + + + + LUT3_out[1] + + + + + + + + cin + + + + + + + + + M + U + X + + + + + LUT2_out[1] + + + + + + + + + + + + MUX + + + + + LUT2_out[0] + + + + + + + + + + + + + + + cout + + + + + + + + + + + mode[0] + + + + + + + + mode[1] + + + + + diff --git a/docs/source/overview/tech_highlights.rst b/docs/source/overview/tech_highlights.rst index fa1a364e3..95521cc29 100644 --- a/docs/source/overview/tech_highlights.rst +++ b/docs/source/overview/tech_highlights.rst @@ -1,61 +1,65 @@ Technical Highlights -------------------- -The follow lists of technical features are created to help users spot their needs in customizing FPGA fabrics.(**as of October 2020**) +The follow lists of technical features are created to help users spot their needs in customizing FPGA fabrics.(**as of February 2021**) Supported Circuit Designs ~~~~~~~~~~~~~~~~~~~~~~~~~ -+---------------+-----------------+--------------+-----------------------------------------------------+ -| Circuit Types | Auto-generation | User-Defined | Design Topologies | -+===============+=================+==============+=====================================================+ -| Inverter | Yes | Yes | - :ref:`circuit_model_power_gated_inverter_example` | -| | | | - :ref:`circuit_model_inverter_1x_example` | -| | | | - :ref:`circuit_model_tapered_inv_16x_example` | -+---------------+-----------------+--------------+-----------------------------------------------------+ -| Buffer | Yes | Yes | - :ref:`circuit_model_buffer_2x_example` | -| | | | - :ref:`circuit_model_power_gated_buffer_example` | -| | | | - :ref:`circuit_model_tapered_buffer_64x_example` | -+---------------+-----------------+--------------+-----------------------------------------------------+ -| AND gate | Yes | Yes | - :ref:`circuit_model_and2_example` | -+---------------+-----------------+--------------+-----------------------------------------------------+ -| OR gate | Yes | Yes | - :ref:`circuit_model_or2_example` | -+---------------+-----------------+--------------+-----------------------------------------------------+ -| MUX2 gate | Yes | Yes | - :ref:`circuit_model_mux2_gate_example` | -+---------------+-----------------+--------------+-----------------------------------------------------+ -| Pass gate | Yes | Yes | - :ref:`circuit_model_tgate_example` | -| | | | - :ref:`circuit_model_pass_transistor_example` | -+---------------+-----------------+--------------+-----------------------------------------------------+ -| Look-Up Table | Yes | Yes | - **Any size** | -| | | | - :ref:`circuit_model_single_output_lut_example` | -| | | | - :ref:`circuit_model_frac_lut_example` | -+---------------+-----------------+--------------+-----------------------------------------------------+ -| Routing | Yes | No | - **Any size** | -| Multiplexer | | | - :ref:`circuit_model_mux_multilevel_example` | -| | | | - :ref:`circuit_model_mux_1level_example` | -| | | | - :ref:`circuit_model_mux_tree_example` | -| | | | - :ref:`circuit_model_mux_stdcell_example` | -| | | | - :ref:`circuit_model_mux_local_encoder_example` | -| | | | - :ref:`circuit_model_mux_const_input_example` | -+---------------+-----------------+--------------+-----------------------------------------------------+ -| Configurable | No | Yes | - :ref:`circuit_model_config_latch_example` | -| Memory | | | - :ref:`circuit_model_sram_blwl_example` | -| | | | - :ref:`circuit_model_dff_example` | -| | | | - :ref:`circuit_model_ccff_example` | -+---------------+-----------------+--------------+-----------------------------------------------------+ -| Block RAM | No | Yes | - **Any size** | -| | | | - Single-port | -| | | | - Dual-port | -| | | | - Fracturable | -+---------------+-----------------+--------------+-----------------------------------------------------+ -| Arithmetic | No | Yes | - **Any size** | -| Units | | | - Multiplier | -| | | | - :ref:`circuit_model_full_adder_example` | -+---------------+-----------------+--------------+-----------------------------------------------------+ -| I/O | No | Yes | - :ref:`circuit_model_gpio_example` | -| | | | - Bi-directional buffer | -| | | | - AIB | -+---------------+-----------------+--------------+-----------------------------------------------------+ ++-----------------+--------------+-----------+-----------------------------------------------------+ +| | Circuit Types | | Auto- | | User- | | Design Topologies | +| | | | generation | | Defined | | ++=================+==============+===========+=====================================================+ +| Inverter | Yes | Yes | - :ref:`circuit_model_power_gated_inverter_example` | +| | | | - :ref:`circuit_model_inverter_1x_example` | +| | | | - :ref:`circuit_model_tapered_inv_16x_example` | ++-----------------+--------------+-----------+-----------------------------------------------------+ +| Buffer | Yes | Yes | - :ref:`circuit_model_buffer_2x_example` | +| | | | - :ref:`circuit_model_power_gated_buffer_example` | +| | | | - :ref:`circuit_model_tapered_buffer_64x_example` | ++-----------------+--------------+-----------+-----------------------------------------------------+ +| AND gate | Yes | Yes | - :ref:`circuit_model_and2_example` | ++-----------------+--------------+-----------+-----------------------------------------------------+ +| OR gate | Yes | Yes | - :ref:`circuit_model_or2_example` | ++-----------------+--------------+-----------+-----------------------------------------------------+ +| MUX2 gate | Yes | Yes | - :ref:`circuit_model_mux2_gate_example` | ++-----------------+--------------+-----------+-----------------------------------------------------+ +| Pass gate | Yes | Yes | - :ref:`circuit_model_tgate_example` | +| | | | - :ref:`circuit_model_pass_transistor_example` | ++-----------------+--------------+-----------+-----------------------------------------------------+ +| Look-Up Table | Yes | Yes | - **Any size** | +| | | | - :ref:`circuit_model_single_output_lut_example` | +| | | | - :ref:`circuit_model_frac_lut_example` | +| | | | - :ref:`circuit_model_lut_harden_logic_example` | ++-----------------+--------------+-----------+-----------------------------------------------------+ +| | Routing | Yes | No | - **Any size** | +| | Multiplexer | | | - :ref:`circuit_model_mux_multilevel_example` | +| | | | - :ref:`circuit_model_mux_1level_example` | +| | | | - :ref:`circuit_model_mux_tree_example` | +| | | | - :ref:`circuit_model_mux_stdcell_example` | +| | | | - :ref:`circuit_model_mux_local_encoder_example` | +| | | | - :ref:`circuit_model_mux_const_input_example` | ++-----------------+--------------+-----------+-----------------------------------------------------+ +| | Configurable | No | Yes | - :ref:`circuit_model_config_latch_example` | +| | Memory | | | - :ref:`circuit_model_sram_blwl_example` | +| | | | - :ref:`circuit_model_dff_example` | +| | | | - :ref:`circuit_model_ccff_example` | +| | | | - :ref:`circuit_model_ccff_enable_example` | +| | | | - :ref:`circuit_model_ccff_scanable_example` | ++-----------------+--------------+-----------+-----------------------------------------------------+ +| Block RAM | No | Yes | - **Any size** | +| | | | - Single-port | +| | | | - Dual-port | +| | | | - Fracturable | ++-----------------+--------------+-----------+-----------------------------------------------------+ +| | Arithmetic | No | Yes | - **Any size** | +| | Units | | | - Multiplier | +| | | | - :ref:`circuit_model_full_adder_example` | ++-----------------+--------------+-----------+-----------------------------------------------------+ +| I/O | No | Yes | - :ref:`circuit_model_gpio_example` | +| | | | - Bi-directional buffer | +| | | | - AIB | ++-----------------+--------------+-----------+-----------------------------------------------------+ * The user defined netlist could come from a standard cell From e683e0003238a01908b9df5082950166947a3a54 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Wed, 10 Feb 2021 14:50:11 -0700 Subject: [PATCH 28/28] [HDL] Add disclaimer for the frac_lut4_arith HDL codes --- .../openfpga_cell_library/verilog/frac_lut4_arith.v | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/openfpga_flow/openfpga_cell_library/verilog/frac_lut4_arith.v b/openfpga_flow/openfpga_cell_library/verilog/frac_lut4_arith.v index 9a5af98af..0b5461615 100644 --- a/openfpga_flow/openfpga_cell_library/verilog/frac_lut4_arith.v +++ b/openfpga_flow/openfpga_cell_library/verilog/frac_lut4_arith.v @@ -5,6 +5,10 @@ // - mode_bit[0] switch between arithmetic mode and LUT mode // - mode_bit[1] switch between regular LUT mode and fracturable // mode +// Note : The HDL is a technology mapped netlist based on the Skywater +// 130nm High-Density cell library. +// TODO: Create a behavioral HDL version so that we are portable +// between PDKs // Coder : Xifan TANG //----------------------------------------------------- module frac_lut4_arith ( @@ -267,4 +271,4 @@ wire [0:0] sky130_fd_sc_hd__mux2_1_9_X; .X(sky130_fd_sc_hd__mux2_1_14_X[0])); endmodule -// ----- END Verilog module for frac_lut4_mux ----- \ No newline at end of file +// ----- END Verilog module for frac_lut4_mux -----