| # Copyright lowRISC contributors. | |
| # Licensed under the Apache License, Version 2.0, see LICENSE for details. | |
| # SPDX-License-Identifier: Apache-2.0 | |
| # Not overly pretty approach to find ipgen dependencies in the right directory. | |
| # Remove once we are properly packaging our Python code. | |
| import os | |
| import sys | |
| sys.path.append(os.path.join(os.path.dirname(__file__), '../../')) | |
| import pytest | |
| from ipgen import IpBlockRenderer, IpConfig, IpTemplate | |
| from ipgen.lib import TemplateParams | |
| from reggen.params import BaseParam | |
| @pytest.fixture | |
| def rendertest_dirs(tmp_path) -> None: | |
| """ Produce a simple IP template for render testing. | |
| Returns a tuple (template_directory, output_directory), expects the template | |
| to be rendered into output_directory, and checks that the minimal expected | |
| directory contents are present there. | |
| """ | |
| template_dir = tmp_path / 'template' | |
| template_dir.mkdir() | |
| data_dir = template_dir / 'data' | |
| data_dir.mkdir() | |
| RENDERTEST_HJSON = """ | |
| { | |
| name: "rendertest" | |
| clocking: [ | |
| {clock: "clk_i", reset: "rst_ni", idle: "idle_o", primary: true}, | |
| ] | |
| bus_interfaces: [ | |
| { protocol: "tlul", direction: "device" } | |
| ], | |
| registers: [] | |
| } | |
| """ | |
| (data_dir / 'rendertest.hjson').write_text(RENDERTEST_HJSON) | |
| out_dir = tmp_path / 'out' | |
| yield (template_dir, out_dir) | |
| # Check that the basic structure of the IP template directory is retained. | |
| actual = set(str(p.relative_to(out_dir)) for p in out_dir.rglob('*')) | |
| exp = set([ | |
| 'rtl', | |
| 'rtl/rendertest_reg_top.sv', | |
| 'rtl/rendertest_reg_pkg.sv', | |
| 'data', | |
| 'data/inst_rendertest.ipconfig.hjson', | |
| 'data/rendertest.hjson', | |
| ]) | |
| assert exp.issubset(actual) | |
| def test_render_simpleparam(rendertest_dirs) -> None: | |
| """ Test the IpBlockRenderer when it gets passed simple parameters. """ | |
| (template_dir, out_dir) = rendertest_dirs | |
| (template_dir / 'test.txt.tpl').write_text('param1=${param1}') | |
| # Declare the template parameters. | |
| params = TemplateParams() | |
| params.add(BaseParam(name='param1', desc=None, param_type='string')) | |
| ip_template = IpTemplate('rendertest', params, template_dir) | |
| param_values = { | |
| 'param1': 'somevalue', | |
| } | |
| ip_config = IpConfig(ip_template.params, 'inst_rendertest', param_values) | |
| # Render into the output directory. | |
| renderer = IpBlockRenderer(ip_template, ip_config) | |
| renderer.render(out_dir, overwrite_output_dir=False) | |
| # Check that the template parameters are rendered correctly. | |
| assert (out_dir / 'test.txt').is_file() | |
| assert (out_dir / 'test.txt').read_text() == 'param1=somevalue' | |
| def test_render_objectparam(rendertest_dirs) -> None: | |
| """ Test the IpBlockRenderer when it gets passed object parameters. """ | |
| (template_dir, out_dir) = rendertest_dirs | |
| template = """${obj['super']} | |
| ${obj['mega']} | |
| % for item in obj['list']: | |
| ${item} | |
| % endfor | |
| """ | |
| (template_dir / 'test.txt.tpl').write_text(template) | |
| # Declare the template parameters. | |
| params = TemplateParams() | |
| params.add(BaseParam(name='obj', desc=None, param_type='object')) | |
| ip_template = IpTemplate('rendertest', params, template_dir) | |
| param_values = { | |
| 'obj': { | |
| 'super': 'duper', | |
| 'mega': 1e6, | |
| 'list': ['of', 'things'], | |
| }, | |
| } | |
| ip_config = IpConfig(ip_template.params, 'inst_rendertest', param_values) | |
| # Render into the output directory. | |
| renderer = IpBlockRenderer(ip_template, ip_config) | |
| renderer.render(out_dir, overwrite_output_dir=False) | |
| # Check that the template parameters are rendered correctly. | |
| assert (out_dir / 'test.txt').is_file() | |
| assert (out_dir / 'test.txt').read_text() == 'duper\n1000000\nof\nthings\n' |