Esempio n. 1
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. 2
0
def generate_async_mmap_signals(tag: str, arg: str,
                                data_width: int) -> Iterator[ast.Wire]:
    for suffix in ASYNC_MMAP_SUFFIXES[tag]:
        yield ast.Wire(
            name=async_mmap_arg_name(arg=arg, tag=tag, suffix=suffix),
            width=async_mmap_width(
                tag=tag,
                suffix=suffix,
                data_width=data_width,
            ),
        )
Esempio n. 3
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. 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: task.py Progetto: mfkiwl/tapa
    def add_m_axi(
        self,
        width_table: Dict[str, int],
        tcl_files: Dict[str, str],
    ) -> None:
        for arg_name, (m_axi_id_width, args) in self.mmaps.items():
            # add m_axi ports to the arg list
            self.module.add_m_axi(
                name=arg_name,
                data_width=width_table[arg_name],
                id_width=m_axi_id_width or None,
            )
            if len(args) == 1:
                continue

            # add AXI interconnect if necessary
            assert len(args) <= 16, f'too many ports connected to {arg_name}'
            assert m_axi_id_width is not None

            s_axi_id_width = max(
                arg.instance.task.get_id_width(arg.port) or 0 for arg in args)

            portargs = [
                ast.make_port_arg(port='INTERCONNECT_ACLK',
                                  arg=rtl.HANDSHAKE_CLK),
                ast.make_port_arg(
                    port='INTERCONNECT_ARESETN',
                    arg=rtl.HANDSHAKE_RST_N,
                ),
                ast.make_port_arg(port='M00_AXI_ACLK', arg=rtl.HANDSHAKE_CLK),
                ast.make_port_arg(port='M00_AXI_ARESET_OUT_N', arg=''),
            ]

            for axi_chan, axi_ports in rtl.M_AXI_PORTS.items():
                for axi_port, direction in axi_ports:
                    m_axi_arg = f'{rtl.M_AXI_PREFIX}{arg_name}_{axi_chan}{axi_port}'

                    if axi_port == 'ID' and direction == 'input':
                        m_axi_arg = (
                            f"{{{s_axi_id_width + 4 - m_axi_id_width}'d0, "
                            f"{m_axi_arg}}}")
                    portargs.append(
                        ast.make_port_arg(
                            port=f'M00_AXI_{axi_chan}{axi_port}',
                            arg=m_axi_arg,
                        ))

            for idx, arg in enumerate(args):
                portargs += (
                    ast.make_port_arg(port=f'S{idx:02d}_AXI_ACLK',
                                      arg=rtl.HANDSHAKE_CLK),
                    ast.make_port_arg(port=f'S{idx:02d}_AXI_ARESET_OUT_N',
                                      arg=''),
                )

                wires = []
                for axi_chan, axi_ports in rtl.M_AXI_PORTS.items():
                    for axi_port, _ in axi_ports:
                        wire_name = (f'{rtl.M_AXI_PREFIX}{arg.mmap_name}_'
                                     f'{axi_chan}{axi_port}')
                        wires.append(
                            ast.Wire(
                                name=wire_name,
                                width=rtl.get_m_axi_port_width(
                                    port=axi_port,
                                    data_width=width_table[arg_name],
                                    id_width=arg.instance.task.get_id_width(
                                        arg.port),
                                )))
                        portargs.append(
                            ast.make_port_arg(
                                port=f'S{idx:02d}_AXI_{axi_chan}{axi_port}',
                                arg=wire_name,
                            ))
                self.module.add_signals(wires)

            data_width = max(width_table[arg_name], 32)
            assert data_width in {32, 64, 128, 256, 512, 1024}
            module_name = (f'axi_interconnect_{data_width}b_'
                           f'{s_axi_id_width}t_x{len(args)}')
            s_axi_data_width = ' \\\n  '.join(
                f'CONFIG.S{idx:02d}_AXI_DATA_WIDTH {data_width}'
                for idx in range(len(args)))
            s_axi_read_acceptance = ' \\\n  '.join(
                f'CONFIG.S{idx:02d}_AXI_READ_ACCEPTANCE 16'
                for idx in range(len(args)))
            s_axi_write_acceptance = ' \\\n  '.join(
                f'CONFIG.S{idx:02d}_AXI_WRITE_ACCEPTANCE 16'
                for idx in range(len(args)))
            tcl_files.setdefault(
                module_name, f'''\
create_ip \\
  -name axi_interconnect \\
  -vendor xilinx.com \\
  -library ip \\
  -version 1.7 \\
  -module_name {module_name}
set_property -dict [list \\
  CONFIG.AXI_ADDR_WIDTH 64 \\
  CONFIG.NUM_SLAVE_PORTS {len(args)} \\
  CONFIG.THREAD_ID_WIDTH {s_axi_id_width} \\
  CONFIG.INTERCONNECT_DATA_WIDTH {data_width} \\
  CONFIG.M00_AXI_DATA_WIDTH {data_width} \\
  {s_axi_data_width} \\
  CONFIG.M00_AXI_READ_ISSUING 16 \\
  {s_axi_read_acceptance} \\
  CONFIG.M00_AXI_WRITE_ISSUING 16 \\
  {s_axi_write_acceptance} \\
  ] [get_ips {module_name}]
set_property generate_synth_checkpoint false [get_files {module_name}.xci]
generate_target {{synthesis simulation}} [get_files {module_name}.xci]
''')
            self.module.add_instance(
                module_name=module_name,
                instance_name=f'{module_name}__{arg_name}',
                ports=portargs,
            )
Esempio n. 7
0
 def signals(self) -> Iterator[Union[ast.Reg, ast.Wire, ast.Pragma]]:
     yield ast.Wire(name=self[0].name, width=self._width)
     for x in self[1:]:
         yield ast.Pragma(ast.PragmaEntry('dont_touch = "yes"'))
         yield ast.Reg(name=x.name, width=self._width)
Esempio n. 8
0
 def signals(self) -> Iterator[Union[ast.Reg, ast.Wire, ast.Pragma]]:
     yield ast.Wire(name=self[0].name, width=self._width)
     for x in self[1:]:
         yield ast.Pragma(ast.PragmaEntry('shreg_extract = "no"'))
         yield ast.Reg(name=x.name, width=self._width)