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, ), )
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)