Esempio n. 1
0
File: task.py Progetto: Blaok/tapa
  def convert_axis_to_fifo(self, axis_name: str) -> str:
    assert len(self.get_fifo_directions(axis_name)) == 1, \
        "axis interfaces should have one direction"
    direction_axis = {
        'consumed_by': 'produced_by',
        'produced_by': 'consumed_by',
    }[self.get_fifo_directions(axis_name)[0]]
    data_width = self.ports[axis_name].width

    # add FIFO registerings to provide timing isolation
    fifo_name = 'tapa_fifo_' + axis_name
    self.module.add_fifo_instance(name=fifo_name,
        width=data_width+1, depth=2)

    # add FIFO's wires
    for suffix in rtl.STREAM_PORT_DIRECTION:
      wire_name = rtl.wire_name(fifo_name, suffix)
      wire_width = rtl.get_stream_width(suffix, data_width)
      self.module.add_signals([ast.Wire(name=wire_name, width=wire_width)])

    # add constant outputs for AXIS output ports
    if direction_axis == 'consumed_by':
      for axis_suffix, bit in rtl.AXIS_CONSTANTS.items():
        port_name = self.module.find_port(axis_name, axis_suffix)
        width = rtl.get_axis_port_width_int(axis_suffix, data_width)

        self.module.add_logics([
            ast.Assign(left=ast.Identifier(port_name),
                       right=ast.IntConst("%d'b%s"%(width, str(bit)*width)))])

    # connect the FIFO to the AXIS interface
    for suffix in self.get_fifo_suffixes(direction_axis):
      wire_name = rtl.wire_name(fifo_name, suffix)

      offset = 0
      for axis_suffix in rtl.STREAM_TO_AXIS[suffix]:
        port_name = self.module.find_port(axis_name, axis_suffix)
        width = rtl.get_axis_port_width_int(axis_suffix, data_width)

        if len(rtl.STREAM_TO_AXIS[suffix]) > 1:
          wire = ast.Partselect(ast.Identifier(wire_name),
              ast.IntConst(str(offset + width - 1)),
              ast.IntConst(str(offset)))
        else:
          wire = ast.Identifier(wire_name)

        self.assign_directional(
            ast.Identifier(port_name), wire,
            rtl.STREAM_PORT_DIRECTION[suffix])

        offset += width

    return fifo_name
Esempio n. 2
0
File: task.py Progetto: Blaok/tapa
  def connect_fifo_externally(self, internal_name: str, top: bool) -> None:
    assert len(self.get_fifo_directions(internal_name)) == 1, \
        "externally connected fifos should have one direction"
    direction = self.get_fifo_directions(internal_name)[0]
    external_name = self.convert_axis_to_fifo(internal_name) \
        if top else internal_name

    # connect fifo with external ports
    for suffix in self.get_fifo_suffixes(direction):
      self.assign_directional(
          ast.Identifier(rtl.wire_name(internal_name, suffix)),
          ast.Identifier(
              self.module.get_port_of(external_name, suffix).name
              if external_name == internal_name
              else rtl.wire_name(external_name, suffix)),
          rtl.STREAM_PORT_DIRECTION[suffix])
Esempio n. 3
0
    def handshake_signals(self) -> Iterator[Union[ast.Wire, ast.Reg]]:
        """All handshake signals used for this instance.

    Yields:
      Union[ast.Wire, ast.Reg] of signals.
    """
        if self.is_autorun:
            yield ast.Reg(name=self.start.name, width=None)
        else:
            yield ast.Wire(name=self.start.name, width=None)
            yield ast.Reg(name=self.state.name, width=ast.make_width(2))
            yield from (ast.Wire(name=rtl.wire_name(self.name, suffix),
                                 width=None)
                        for suffix in rtl.HANDSHAKE_OUTPUT_PORTS)
Esempio n. 4
0
File: core.py Progetto: Blaok/tapa
    def _connect_fifos(self, task: Task) -> None:
        _logger.debug("  connecting %s's children tasks", task.name)
        for fifo_name in task.fifos:
            for direction in task.get_fifo_directions(fifo_name):
                task_name, _, fifo_port = task.get_connection_to(
                    fifo_name, direction)

                for suffix in task.get_fifo_suffixes(direction):
                    # declare wires for FIFOs
                    wire_name = rtl.wire_name(fifo_name, suffix)
                    wire_width = self.get_task(task_name).module.get_port_of(
                        fifo_port, suffix).width
                    wire = ast.Wire(name=wire_name, width=wire_width)
                    task.module.add_signals([wire])

            if task.is_fifo_external(fifo_name):
                task.connect_fifo_externally(fifo_name, task.name == self.top)
Esempio n. 5
0
File: core.py Progetto: mfkiwl/tapa
    def _connect_fifos(self, task: Task) -> None:
        _logger.debug("  connecting %s's children tasks", task.name)
        for fifo_name, fifo in task.fifos.items():
            directions = {
                'consumed_by': rtl.ISTREAM_SUFFIXES,
                'produced_by': rtl.OSTREAM_SUFFIXES
            }

            for direction, suffixes in directions.items():
                # skip if not in this direction
                if direction not in fifo:
                    continue

                task_name, _, fifo_port = task.get_fifo_port(
                    fifo_name, direction)
                child_ports = self.get_task(task_name).module.ports

                for suffix in suffixes:
                    # declare wires for FIFOs
                    wire_name = rtl.wire_name(fifo_name, suffix)
                    wire_width = child_ports[rtl.fifo_port_name(
                        fifo_port, suffix)].width
                    wire = ast.Wire(name=wire_name, width=wire_width)
                    task.module.add_signals([wire])

                    # if this FIFO is not declared, connect it directly to ports
                    if 'depth' not in fifo:
                        port_name = rtl.fifo_port_name(fifo_name, suffix)
                        port_direction = rtl.STREAM_PORT_DIRECTION[suffix]
                        if port_direction == 'input':
                            task.module.add_logics([
                                ast.Assign(left=ast.Identifier(wire_name),
                                           right=ast.Identifier(port_name))
                            ])
                        elif port_direction == 'output':
                            task.module.add_logics([
                                ast.Assign(left=ast.Identifier(port_name),
                                           right=ast.Identifier(wire_name))
                            ])
Esempio n. 6
0
File: core.py Progetto: Blaok/tapa
    def _instantiate_fifos(self, task: Task) -> None:
        _logger.debug('  instantiating FIFOs in %s', task.name)

        # skip instantiating if the fifo is not declared in this task
        fifos = {
            name: fifo
            for name, fifo in task.fifos.items() if 'depth' in fifo
        }
        if not fifos:
            return

        col_width = max(
            max(len(name), len(util.get_instance_name(fifo['consumed_by'])),
                len(util.get_instance_name(fifo['produced_by'])))
            for name, fifo in fifos.items())

        for fifo_name, fifo in fifos.items():
            _logger.debug('    instantiating %s.%s', task.name, fifo_name)

            # add FIFO instances
            task.module.add_fifo_instance(
                name=fifo_name,
                width=self._get_fifo_width(task, fifo_name),
                depth=fifo['depth'],
            )

            # print debugging info
            debugging_blocks = []
            fmtargs = {
                'fifo_prefix': '\\033[97m',
                'fifo_suffix': '\\033[0m',
                'task_prefix': '\\033[90m',
                'task_suffix': '\\033[0m',
            }
            for suffixes, fmt, fifo_tag in zip(
                (rtl.ISTREAM_SUFFIXES, rtl.OSTREAM_SUFFIXES),
                ('DEBUG: R: {fifo_prefix}{fifo:>{width}}{fifo_suffix} -> '
                 '{task_prefix}{task:<{width}}{task_suffix} %h',
                 'DEBUG: W: {task_prefix}{task:>{width}}{task_suffix} -> '
                 '{fifo_prefix}{fifo:<{width}}{fifo_suffix} %h'),
                ('consumed_by', 'produced_by')):
                display = ast.SingleStatement(statement=ast.SystemCall(
                    syscall='display',
                    args=(ast.StringConst(value=fmt.format(
                        width=col_width,
                        fifo=fifo_name,
                        task=(util.get_instance_name(fifo[fifo_tag])),
                        **fmtargs)),
                          ast.Identifier(
                              name=rtl.wire_name(fifo_name, suffixes[0])))))
                debugging_blocks.append(
                    ast.Always(
                        sens_list=rtl.CLK_SENS_LIST,
                        statement=ast.make_block(
                            ast.IfStatement(
                                cond=ast.Eq(
                                    left=ast.Identifier(name=rtl.wire_name(
                                        fifo_name, suffixes[-1])),
                                    right=rtl.TRUE,
                                ),
                                true_statement=ast.make_block(display),
                                false_statement=None))))
            task.module.add_logics(debugging_blocks)