Example #1
0
    def add_fifo_instance(
        self,
        name: str,
        width: int,
        depth: int,
    ) -> 'Module':
        name = sanitize_array_name(name)
        rst_q = Pipeline(f'{name}__rst', level=self.register_level)
        self.add_pipeline(rst_q, init=ast.Unot(RST_N))

        def ports() -> Iterator[ast.PortArg]:
            yield ast.make_port_arg(port='clk', arg=CLK)
            yield ast.make_port_arg(port='reset', arg=rst_q[-1])
            yield from (ast.make_port_arg(port=port_name,
                                          arg=wire_name(name, arg_suffix))
                        for port_name, arg_suffix in zip(
                            FIFO_READ_PORTS, ISTREAM_SUFFIXES))
            yield ast.make_port_arg(port=FIFO_READ_PORTS[-1], arg=TRUE)
            yield from (ast.make_port_arg(port=port_name,
                                          arg=wire_name(name, arg_suffix))
                        for port_name, arg_suffix in zip(
                            FIFO_WRITE_PORTS, OSTREAM_SUFFIXES))
            yield ast.make_port_arg(port=FIFO_WRITE_PORTS[-1], arg=TRUE)

        partition_count = self.partition_count_of(name)
        module_name = 'fifo'
        level = []
        if partition_count > 1:
            module_name = 'relay_station'
            level.append(
                ast.ParamArg(
                    paramname='LEVEL',
                    argname=ast.Constant(partition_count),
                ))
        return self.add_instance(
            module_name=module_name,
            instance_name=name,
            ports=ports(),
            params=(
                ast.ParamArg(paramname='DATA_WIDTH',
                             argname=ast.Constant(width)),
                ast.ParamArg(
                    paramname='ADDR_WIDTH',
                    argname=ast.Constant(max(1, (depth - 1).bit_length())),
                ),
                ast.ParamArg(paramname='DEPTH', argname=ast.Constant(depth)),
                *level,
            ),
        )
Example #2
0
    def add_async_mmap_instance(
        self,
        name: str,
        tags: Iterable[str],
        data_width: int,
        addr_width: int = 64,
        buffer_size: Optional[int] = None,
        max_wait_time: int = 3,
        max_burst_len: Optional[int] = None,
        offset_name: str = '',
    ) -> 'Module':
        rst_q = Pipeline(f'{name}__rst', level=self.register_level)
        self.add_pipeline(rst_q, init=ast.Unot(RST_N))

        paramargs = [
            ast.ParamArg(paramname='DataWidth',
                         argname=ast.Constant(data_width)),
            ast.ParamArg(paramname='DataWidthBytesLog',
                         argname=ast.Constant(
                             (data_width // 8 - 1).bit_length())),
        ]
        portargs = [
            ast.make_port_arg(port='clk', arg=CLK),
            ast.make_port_arg(port='rst', arg=rst_q[-1]),
        ]
        paramargs.append(
            ast.ParamArg(paramname='AddrWidth',
                         argname=ast.Constant(addr_width)))
        if buffer_size:
            paramargs.extend(
                (ast.ParamArg(paramname='BufferSize',
                              argname=ast.Constant(buffer_size)),
                 ast.ParamArg(paramname='BufferSizeLog',
                              argname=ast.Constant(
                                  (buffer_size - 1).bit_length()))))
        max_wait_time = max(1, max_wait_time)
        paramargs.append(
            ast.ParamArg(paramname='WaitTimeWidth',
                         argname=ast.Constant(max_wait_time.bit_length())))
        portargs.append(
            ast.make_port_arg(port='max_wait_time',
                              arg="{}'d{}".format(max_wait_time.bit_length(),
                                                  max_wait_time)))
        if max_burst_len is None:
            max_burst_len = max(0, 4096 // data_width - 1)
        paramargs.append(
            ast.ParamArg(paramname='BurstLenWidth',
                         argname=ast.Constant(
                             max(1, max_burst_len.bit_length()))))
        portargs.append(
            ast.make_port_arg(port='max_burst_len',
                              arg="{}'d{}".format(
                                  max(1, max_burst_len.bit_length()),
                                  max_burst_len)))

        for channel, ports in M_AXI_PORTS.items():
            for port, direction in ports:
                portargs.append(
                    ast.make_port_arg(
                        port=f'{M_AXI_PREFIX}{channel}{port}',
                        arg=f'{M_AXI_PREFIX}{name}_{channel}{port}'))

        tags = set(tags)
        for tag in 'read_addr', 'read_data', 'write_addr', 'write_data':
            for suffix in async_mmap_suffixes(tag=tag):
                if tag in tags:
                    arg = async_mmap_arg_name(arg=name, tag=tag, suffix=suffix)
                    if tag.endswith('_addr') and suffix.endswith('_din'):
                        elem_size_bytes_m1 = data_width // 8 - 1
                        arg = "{name} + {{{arg}[{}:0], {}'d0}}".format(
                            addr_width - elem_size_bytes_m1.bit_length() - 1,
                            elem_size_bytes_m1.bit_length(),
                            arg=arg,
                            name=offset_name or name)
                else:
                    if suffix.endswith('_read') or suffix.endswith('_write'):
                        arg = "1'b0"
                    elif suffix.endswith('_din'):
                        arg = "'d0"
                    else:
                        arg = ''
                portargs.append(ast.make_port_arg(port=tag + suffix, arg=arg))

        return self.add_instance(module_name='async_mmap',
                                 instance_name=async_mmap_instance_name(name),
                                 ports=portargs,
                                 params=paramargs)