diff options
author | Wade Fife <wade.fife@ettus.com> | 2019-10-23 19:50:34 -0500 |
---|---|---|
committer | Martin Braun <martin.braun@ettus.com> | 2019-11-26 12:21:32 -0800 |
commit | 4e6177ed5564180fe7a0da705490087e736371b6 (patch) | |
tree | 34896baea16d0e7cf6d5101ac91a2e28fdb5b0d4 /host/utils/rfnoc | |
parent | ea89fd0dd4e7bd9a4050f6ae2b79d3b359c60a9a (diff) | |
download | uhd-4e6177ed5564180fe7a0da705490087e736371b6.tar.gz uhd-4e6177ed5564180fe7a0da705490087e736371b6.tar.bz2 uhd-4e6177ed5564180fe7a0da705490087e736371b6.zip |
utils: image_builder: Support parameterized number of ports on blocks
Diffstat (limited to 'host/utils/rfnoc')
-rwxr-xr-x | host/utils/rfnoc/image_builder.py | 64 | ||||
-rw-r--r-- | host/utils/rfnoc/templates/modules/drive_unused_ports.v.mako | 38 | ||||
-rw-r--r-- | host/utils/rfnoc/templates/modules/rfnoc_block.v.mako | 17 | ||||
-rw-r--r-- | host/utils/rfnoc/templates/rfnoc_image_core.v.mako | 4 |
4 files changed, 76 insertions, 47 deletions
diff --git a/host/utils/rfnoc/image_builder.py b/host/utils/rfnoc/image_builder.py index 965b2d454..19740c211 100755 --- a/host/utils/rfnoc/image_builder.py +++ b/host/utils/rfnoc/image_builder.py @@ -18,6 +18,7 @@ import sys import six import mako.lookup import mako.template +from mako import exceptions from ruamel import yaml # Adapted from code found at @@ -100,7 +101,7 @@ class IOConfig: Class containing configuration from a yml file. Each top level entry is translated into a class member variable. If the - configuration contains an io_ports section the ports get an wire list which + configuration contains an io_ports section the ports get a wire list which is derived from the signature file. This allows easier processing of IO ports in the mako templates and failures from yml configuration files fail in this script rather than during template processing which is easier to @@ -173,16 +174,12 @@ class ImageBuilderConfig: def _collect_noc_ports(self): """ Create lookup table for noc blocks. The key is a tuple of block - name, port name and flow direction. + name, port name and flow direction. If any block port has num_ports > 1 + then unroll that port into multiple ports of the same name plus a + number to make its name unique. """ for name, block in six.iteritems(self.noc_blocks): desc = self.blocks[block["block_desc"]] - ports = desc.data["inputs"] - self.block_ports.update({(name, port, "input"): - ports[port] for port in ports}) - ports = desc.data["outputs"] - self.block_ports.update({(name, port, "output"): - ports[port] for port in ports}) # Update per-instance parameters if not hasattr(desc, "parameters"): setattr(desc, "parameters", {}) @@ -195,6 +192,43 @@ class ImageBuilderConfig: for param, value in six.iteritems(desc.parameters): if param not in block["parameters"]: block["parameters"][param] = value + # Generate list of block ports, adding 'index' to each port's dict + for direction in ("inputs", "outputs"): + index = 0 + for port_name, port_info in desc.data[direction].items(): + num_ports = 1 + if "num_ports" in port_info: + parameter = port_info["num_ports"] + num_ports = parameter + if parameter in block["parameters"]: + num_ports = block["parameters"][parameter] + # Make sure the parameter resolved to a number + if not isinstance(num_ports, int): + logging.error( + "'num_ports' of port '%s' on block '%s' " + "resolved to invalid value of '%s'", + port_name, name, str(num_ports)) + sys.exit(1) + if num_ports < 1 or num_ports > 64: + logging.error( + "'num_ports' of port '%s' on block '%s' " + "has invalid value '%s', must be in [1, 64]", + port_name, name, str(num_ports)) + sys.exit(1) + if "num_ports" in port_info: + # If num_ports was a variable in the YAML, unroll into + # multiple ports + for i in range(num_ports): + new_port_info = port_info.copy() + new_port_info['index'] = index + index = index + 1 + self.block_ports.update({(name, port_name + "_" \ + + str(i), direction[:-1]) : new_port_info}) + else: + port_info['index'] = index + self.block_ports.update( + {(name, port_name, direction[:-1]) : port_info}) + index = index + 1 ports = self.stream_endpoints for sep in self.stream_endpoints: inputs = {(sep, "in%d" % port, "input") : @@ -578,11 +612,15 @@ def write_verilog(config, destination, source, source_hash): lookup=lookup, strict_undefined=True) - block = tpl.render(**{ - "config": config, - "source": source, - "source_hash": source_hash, - }) + try: + block = tpl.render(**{ + "config": config, + "source": source, + "source_hash": source_hash, + }) + except: + print(exceptions.text_error_template().render()) + sys.exit(1) logging.info("Writing image core to %s", destination) with open(destination, "w") as image_core_file: diff --git a/host/utils/rfnoc/templates/modules/drive_unused_ports.v.mako b/host/utils/rfnoc/templates/modules/drive_unused_ports.v.mako index e6df532f0..dfa1e7eb6 100644 --- a/host/utils/rfnoc/templates/modules/drive_unused_ports.v.mako +++ b/host/utils/rfnoc/templates/modules/drive_unused_ports.v.mako @@ -1,5 +1,4 @@ -<%page args="connections, blocks, block_descs, seps"/>\ -\ +<%page args="connections, block_ports"/>\ <% sources = [] destinations = [] @@ -7,31 +6,16 @@ sources.append((connection["srcblk"], connection["srcport"])) destinations.append((connection["dstblk"], connection["dstport"])) %>\ -%for sep in seps: - %for input in range(seps[sep]["num_data_i"]): - %if not (sep, "in%d" % (input)) in destinations: - assign s_${sep}_in${input}_tdata = 'h0; - assign s_${sep}_in${input}_tlast = 1'b0; - assign s_${sep}_in${input}_tvalid = 1'b0; +%for (block_name, port_name, direction) in block_ports: + %if direction == "input": + %if not (block_name, port_name) in destinations: + assign s_${block_name}_${port_name}_tdata = {CHDR_W{1'b0}}; + assign s_${block_name}_${port_name}_tlast = 1'b0; + assign s_${block_name}_${port_name}_tvalid = 1'b0; %endif - %endfor - %for output in range(seps[sep]["num_data_o"]): - %if not (sep, "out%d" % (output)) in sources: - assign m_${sep}_out${output}_tready = 1'b1; + %elif direction == "output": + %if not (block_name, port_name) in sources: + assign m_${block_name}_${port_name}_tready = 1'b1; %endif - %endfor -%endfor -%for block in blocks: - %for input in block_descs[blocks[block]["block_desc"]].data["inputs"]: - %if not (block, input) in destinations: - assign s_${block}_${input}_tdata = ${block_descs[blocks[block]["block_desc"]].chdr_width}'h0; - assign s_${block}_${input}_tlast = 1'b0; - assign s_${block}_${input}_tvalid = 1'b0; - %endif - %endfor - %for output in block_descs[blocks[block]["block_desc"]].data["outputs"]: - %if not (block, output) in sources: - assign m_${block}_${output}_tready = 1'b1; - %endif - %endfor + %endif %endfor diff --git a/host/utils/rfnoc/templates/modules/rfnoc_block.v.mako b/host/utils/rfnoc/templates/modules/rfnoc_block.v.mako index 061e4dc8e..ee4a811a8 100644 --- a/host/utils/rfnoc/templates/modules/rfnoc_block.v.mako +++ b/host/utils/rfnoc/templates/modules/rfnoc_block.v.mako @@ -1,15 +1,22 @@ -<%page args="block_id, block_number, block_name, block, block_params"/>\ +<%page args="block_id, block_number, block_name, block, block_params, block_ports"/>\ \ <% import re import six + + # Create two strings, one for the input and one for the output, that each + # contains all the signal names to be connected to the input or output + # AXIS-CHDR ports of this block. axis_inputs = "" axis_outputs = "" - for input in list(block.data["inputs"].keys()): - axis_inputs = "{0}_%s_%s_{1}, " % (block_name, input) + axis_inputs + for port_desc in block_ports: + if port_desc[0] == block_name: + port_name = port_desc[1] + if port_desc[2] == "input": + axis_inputs = "{0}_%s_%s_{1}, " % (block_name, port_name) + axis_inputs + elif port_desc[2] == "output": + axis_outputs = "{0}_%s_%s_{1}, " % (block_name, port_name) + axis_outputs axis_inputs = axis_inputs[:-2] - for output in list(block.data["outputs"].keys()): - axis_outputs = "{0}_%s_%s_{1}, " % (block_name, output) + axis_outputs axis_outputs = axis_outputs[:-2] %>\ diff --git a/host/utils/rfnoc/templates/rfnoc_image_core.v.mako b/host/utils/rfnoc/templates/rfnoc_image_core.v.mako index fb3cb3d2e..a18ff53a1 100644 --- a/host/utils/rfnoc/templates/rfnoc_image_core.v.mako +++ b/host/utils/rfnoc/templates/rfnoc_image_core.v.mako @@ -131,7 +131,7 @@ module rfnoc_image_core #( // Blocks // ---------------------------------------------------- %for i, name in enumerate(config.noc_blocks): -<%include file="/modules/rfnoc_block.v.mako" args="block_id=i + len(ctrl_seps) + 1, block_number=i, block_name=name, block=config.blocks[config.noc_blocks[name]['block_desc']], block_params=config.noc_blocks[name]['parameters']"/> +<%include file="/modules/rfnoc_block.v.mako" args="block_id=i + len(ctrl_seps) + 1, block_number=i, block_name=name, block=config.blocks[config.noc_blocks[name]['block_desc']], block_params=config.noc_blocks[name]['parameters'], block_ports=config.block_ports"/> %endfor // ---------------------------------------------------- @@ -142,7 +142,7 @@ module rfnoc_image_core #( // ---------------------------------------------------- // Unused Ports // ---------------------------------------------------- -<%include file="/modules/drive_unused_ports.v.mako" args="connections=config.block_con, blocks=config.noc_blocks, block_descs=config.blocks, seps=config.stream_endpoints"/>\ +<%include file="/modules/drive_unused_ports.v.mako" args="connections=config.block_con, block_ports=config.block_ports"/>\ // ---------------------------------------------------- // Clock Domains |