Example #1
0
 def __init__(self, name, config_file):
     self.verilog_writer = VerilogWriter(name)
     self.template_writer = VerilogWriter(name)
     self.name = name
     d = OrderedDict()
     self.slaves = OrderedDict()
     self.masters = OrderedDict()
     config = configparser.SafeConfigParser()
     config.read(config_file)
     for section in config.sections():
         type = section.split()[0]
         try:
             name = section.split()[1]
         except IndexError:
             print(
                 "Malformed section header. Format is master|slave <name>")
             exit(1)
         if type == "master":
             print("Found master " + name)
             self.masters[name] = Master(name, dict(config.items(section)))
             d[name] = config.get(section, 'slaves').split()
         elif type == "slave":
             print("Found slave " + name)
             self.slaves[name] = Slave(name, dict(config.items(section)))
         else:
             print("Invalid section type " + type)
             exit(1)
     #Create master/slave connections
     for master, slaves in d.items():
         for slave in slaves:
             self.masters[master].slaves += [self.slaves[slave]]
             self.slaves[slave].masters += [self.masters[master]]
Example #2
0
    def __init__(self, name, config_file):
        self.verilog_writer = VerilogWriter(name)
        self.template_writer = VerilogWriter(name)
        self.name = name
        d = OrderedDict()
        self.slaves = []
        self.masters = []
        import yaml

        def ordered_load(stream, Loader=yaml.Loader, object_pairs_hook=OrderedDict):
            class OrderedLoader(Loader):
                pass
            def construct_mapping(loader, node):
                loader.flatten_mapping(node)
                return object_pairs_hook(loader.construct_pairs(node))
            OrderedLoader.add_constructor(
                yaml.resolver.BaseResolver.DEFAULT_MAPPING_TAG,
                construct_mapping)
            return yaml.load(stream, OrderedLoader)
        data = ordered_load(open(config_file))

        config     = data['parameters']

        self.vlnv       = data['vlnv']

        for k,v in config['masters'].items():
            print("Found master " + k)
            self.masters.append(Master(k,v))
        for k,v in config['slaves'].items():
            print("Found slave " + k)
            self.slaves.append(Slave(k,v))

        self.output_file = config.get('output_file', 'axi_intercon.v')
        self.atop = config.get('atop', False)
Example #3
0
 def __init__(self, name, config_file):
     self.verilog_writer = VerilogWriter(name)
     self.template_writer = VerilogWriter(name);
     self.name = name
     d = OrderedDict()
     self.slaves = OrderedDict()
     self.masters = OrderedDict()
     config = configparser.SafeConfigParser()
     config.read(config_file)
     for section in config.sections():
         type=section.split()[0]
         try:
             name=section.split()[1]
         except IndexError:
             print("Malformed section header. Format is master|slave <name>")
             exit(1)
         if type == "master":
             print("Found master " + name)
             self.masters[name] = Master(name, dict(config.items(section)))
             d[name] = config.get(section, 'slaves').split()
         elif type == "slave":
             print("Found slave " + name)
             self.slaves[name] = Slave(name, dict(config.items(section)))
         else:
             print("Invalid section type " + type)
             exit(1)
     #Create master/slave connections
     for master, slaves in d.items():
         for slave in slaves:
             self.masters[master].slaves += [self.slaves[slave]]
             self.slaves[slave].masters += [self.masters[master]]
Example #4
0
    def __init__(self, name, config_file):
        self.verilog_writer = VerilogWriter(name)
        self.template_writer = VerilogWriter(name);
        self.name = name
        d = OrderedDict()
        self.slaves = OrderedDict()
        self.masters = OrderedDict()
        import yaml

        def ordered_load(stream, Loader=yaml.Loader, object_pairs_hook=OrderedDict):
            class OrderedLoader(Loader):
                pass
            def construct_mapping(loader, node):
                loader.flatten_mapping(node)
                return object_pairs_hook(loader.construct_pairs(node))
            OrderedLoader.add_constructor(
                yaml.resolver.BaseResolver.DEFAULT_MAPPING_TAG,
                construct_mapping)
            return yaml.load(stream, OrderedLoader)
        data = ordered_load(open(config_file))

        config     = data['parameters']
        files_root = data['files_root']
        self.vlnv       = data['vlnv']

        valid_endians = ['big', 'little']
        if 'endian' in config:
            self.endian = config['endian']
            if self.endian not in valid_endians:
                raise UnknownPropertyError("Unknown data resizer endian '{}' specified. Valid endians: {}".format(config['endian'], valid_endians))
        else:
            self.endian = "big"

        print("Wishbone Data Resizer Endian: {}".format(config['endian']))

        for k,v in config['masters'].items():
            print("Found master " + k)
            self.masters[k] = Master(k,v)
            d[k] = v['slaves']
        for k,v in config['slaves'].items():
            print("Found slave " + k)
            self.slaves[k] = Slave(k,v)

        #Create master/slave connections
        for master, slaves in d.items():
            for slave in slaves:
                self.masters[master].slaves += [self.slaves[slave]]
                self.slaves[slave].masters += [self.masters[master]]

        self.output_file = config.get('output_file', 'wb_intercon.v')
    def __init__(self, name, config_file):
        self.verilog_writer = VerilogWriter(name)
        self.template_writer = VerilogWriter(name)
        self.name = name
        d = OrderedDict()
        self.slaves = OrderedDict()
        self.masters = OrderedDict()
        import yaml

        def ordered_load(stream,
                         Loader=yaml.Loader,
                         object_pairs_hook=OrderedDict):
            class OrderedLoader(Loader):
                pass

            def construct_mapping(loader, node):
                loader.flatten_mapping(node)
                return object_pairs_hook(loader.construct_pairs(node))

            OrderedLoader.add_constructor(
                yaml.resolver.BaseResolver.DEFAULT_MAPPING_TAG,
                construct_mapping)
            return yaml.load(stream, OrderedLoader)

        data = ordered_load(open(config_file))

        config = data['parameters']
        files_root = data['files_root']
        self.vlnv = data['vlnv']

        index = 0
        for k, v in config['masters'].items():
            print("Found master " + k)
            self.masters[k] = Master(k, index, v)
            index = index + 1
        index = 0
        for k, v in config['slaves'].items():
            print("Found slave " + k)
            self.slaves[k] = Slave(k, index, v)
            index = index + 1

        #Create master/slave connections
        for master, slaves in d.items():
            for slave in slaves:
                self.masters[master].slaves += [self.slaves[slave]]
                self.slaves[slave].masters += [self.masters[master]]

        self.output_file = config.get('output_file', 'ahb3lite_intercon.sv')
Example #6
0
class AxiIntercon:
    def __init__(self, name, config_file):
        self.verilog_writer = VerilogWriter(name)
        self.template_writer = VerilogWriter(name)
        self.name = name
        d = OrderedDict()
        self.slaves = []
        self.masters = []
        import yaml

        def ordered_load(stream, Loader=yaml.Loader, object_pairs_hook=OrderedDict):
            class OrderedLoader(Loader):
                pass
            def construct_mapping(loader, node):
                loader.flatten_mapping(node)
                return object_pairs_hook(loader.construct_pairs(node))
            OrderedLoader.add_constructor(
                yaml.resolver.BaseResolver.DEFAULT_MAPPING_TAG,
                construct_mapping)
            return yaml.load(stream, OrderedLoader)
        data = ordered_load(open(config_file))

        config     = data['parameters']

        self.vlnv       = data['vlnv']

        for k,v in config['masters'].items():
            print("Found master " + k)
            self.masters.append(Master(k,v))
        for k,v in config['slaves'].items():
            print("Found slave " + k)
            self.slaves.append(Slave(k,v))

        self.output_file = config.get('output_file', 'axi_intercon.v')
        self.atop = config.get('atop', False)

    def _dump(self):
        print("*Masters*")
        for master in self.masters.values():
            print(master.name)
            for slave in master.slaves:
                print(' ' + slave.name)

        print("*Slaves*")
        for slave in self.slaves.values():
            print(slave.name)
            for master in slave.masters:
                print(' ' + master.name)

    def write(self):
        w = Widths()
        w.addr = 32
        w.data = 64
        w.user = 0
        w.atop = self.atop

        max_idw = max([m.idw for m in self.masters])
        max_sidw = max_idw + int(math.ceil(math.log2(len(self.masters))))
        file = self.output_file

        _template_ports = [Port('clk_i'  , 'clk'),
                           Port('rst_ni', 'rst_n')]
        template_parameters = []

        #Module header
        self.verilog_writer.add(ModulePort('clk_i'  , 'input'))
        self.verilog_writer.add(ModulePort('rst_ni', 'input'))
        for master in self.masters:
            for port in module_ports(w, master, master.idw, True):
                self.verilog_writer.add(port)
            for wire in template_wires(w, master, master.idw):
                self.template_writer.add(wire)
            _template_ports += template_ports(w, master, master.idw, True)

        for slave in self.slaves:
            for port in module_ports(w, slave, max_sidw, False):
                self.verilog_writer.add(port)
            for wire in template_wires(w, slave, max_sidw):
                self.template_writer.add(wire)
            _template_ports += template_ports(w, slave, max_sidw, False)

        raw = ""
        nm = len(self.masters)
        ns = len(self.slaves)

        raw += """
  localparam int unsigned NoMasters   = 32'd{};    // How many Axi Masters there are
  localparam int unsigned NoSlaves    = 32'd{};    // How many Axi Slaves  there are

  // axi configuration
  localparam int unsigned AxiIdWidthMasters =  32'd{};
  localparam int unsigned AxiIdUsed         =  32'd{}; // Has to be <= AxiIdWidthMasters
  localparam int unsigned AxiIdWidthSlaves  =  AxiIdWidthMasters + $clog2(NoMasters);
  localparam int unsigned AxiAddrWidth      =  32'd32;    // Axi Address Width
  localparam int unsigned AxiDataWidth      =  32'd64;    // Axi Data Width
  localparam int unsigned AxiStrbWidth      =  AxiDataWidth / 8;
  localparam int unsigned AxiUserWidth      =  1;
""".format(nm, ns, max_idw, max_idw)
        raw += "  localparam axi_pkg::xbar_cfg_t xbar_cfg = '{\n"
        raw += """
    NoSlvPorts:         NoMasters,
    NoMstPorts:         NoSlaves,
    MaxMstTrans:        10,
    MaxSlvTrans:        6,
    FallThrough:        1'b0,
    LatencyMode:        axi_pkg::CUT_ALL_AX,
    AxiIdWidthSlvPorts: AxiIdWidthMasters,
    AxiIdUsedSlvPorts:  AxiIdUsed,
    UniqueIds:          1'b0,
    AxiAddrWidth:       AxiAddrWidth,
    AxiDataWidth:       AxiDataWidth,
    NoAddrRules:        NoSlaves
"""
        raw += "  };\n"
        raw += """
  typedef logic [AxiIdWidthMasters-1:0] id_mst_t;
  typedef logic [AxiIdWidthSlaves-1:0]  id_slv_t;
  typedef logic [AxiAddrWidth-1:0]      addr_t;
  typedef axi_pkg::xbar_rule_32_t       rule_t; // Has to be the same width as axi addr
  typedef logic [AxiDataWidth-1:0]      data_t;
  typedef logic [AxiStrbWidth-1:0]      strb_t;
  typedef logic [AxiUserWidth-1:0]      user_t;

  `AXI_TYPEDEF_AW_CHAN_T(aw_chan_mst_t, addr_t, id_mst_t, user_t)
  `AXI_TYPEDEF_AW_CHAN_T(aw_chan_slv_t, addr_t, id_slv_t, user_t)
  `AXI_TYPEDEF_W_CHAN_T(w_chan_t, data_t, strb_t, user_t)
  `AXI_TYPEDEF_B_CHAN_T(b_chan_mst_t, id_mst_t, user_t)
  `AXI_TYPEDEF_B_CHAN_T(b_chan_slv_t, id_slv_t, user_t)

  `AXI_TYPEDEF_AR_CHAN_T(ar_chan_mst_t, addr_t, id_mst_t, user_t)
  `AXI_TYPEDEF_AR_CHAN_T(ar_chan_slv_t, addr_t, id_slv_t, user_t)
  `AXI_TYPEDEF_R_CHAN_T(r_chan_mst_t, data_t, id_mst_t, user_t)
  `AXI_TYPEDEF_R_CHAN_T(r_chan_slv_t, data_t, id_slv_t, user_t)

  `AXI_TYPEDEF_REQ_T(slv_req_t, aw_chan_mst_t, w_chan_t, ar_chan_mst_t)
  `AXI_TYPEDEF_RESP_T(slv_resp_t, b_chan_mst_t, r_chan_mst_t)
  `AXI_TYPEDEF_REQ_T(mst_req_t, aw_chan_slv_t, w_chan_t, ar_chan_slv_t)
  `AXI_TYPEDEF_RESP_T(mst_resp_t, b_chan_slv_t, r_chan_slv_t)

"""

        raw += "  localparam rule_t [{}:0] AddrMap = '".format(ns-1)
        raw += "{\n"
        i = 0
        rules = []
        for slave in self.slaves:
            rule = "    '{"
            rule += "idx: 32'd{}, start_addr: 32'h{:08x}, end_addr: 32'h{:08x}".format(i, slave.offset, slave.offset+slave.size)
            rule += "}"
            i += 1
            rules.append(rule)
        raw += ',\n'.join(rules)
        raw +=   "};\n"

        raw += "   slv_req_t  [{}:0] masters_req;\n".format(nm-1)
        raw += "   slv_resp_t [{}:0] masters_resp;\n".format(nm-1)

        raw += "   mst_req_t  [{}:0] slaves_req;\n".format(ns-1)
        raw += "   mst_resp_t [{}:0] slaves_resp;\n".format(ns-1)

        ns = len(self.slaves)

        raw += assigns(w, max_idw, self.masters, self.slaves)

        self.verilog_writer.raw = raw
        parameters = [
            Parameter('Cfg'          , 'xbar_cfg' ),
            Parameter('ATOPs'        , "1'b"+str(int(self.atop))),
            Parameter('slv_aw_chan_t', 'aw_chan_mst_t'),
            Parameter('mst_aw_chan_t', 'aw_chan_slv_t'),
            Parameter('w_chan_t'     , 'w_chan_t'     ),
            Parameter('slv_b_chan_t' , 'b_chan_mst_t' ),
            Parameter('mst_b_chan_t' , 'b_chan_slv_t' ),
            Parameter('slv_ar_chan_t', 'ar_chan_mst_t'),
            Parameter('mst_ar_chan_t', 'ar_chan_slv_t'),
            Parameter('slv_r_chan_t' , 'r_chan_mst_t' ),
            Parameter('mst_r_chan_t' , 'r_chan_slv_t' ),
            Parameter('slv_req_t'    , 'slv_req_t'    ),
            Parameter('slv_resp_t'   , 'slv_resp_t'   ),
            Parameter('mst_req_t'    , 'mst_req_t'    ),
            Parameter('mst_resp_t'   , 'mst_resp_t'   ),
            Parameter('rule_t'       , 'rule_t'       ),
        ]
        ports = instance_ports(w, max_idw, self.masters, self.slaves)

        self.verilog_writer.add(Instance('axi_xbar',
                                         'axi_xbar',
                                         parameters,
                                         ports))

        self.template_writer.add(Instance(self.name,
                                          self.name,
                                          template_parameters,
                                          _template_ports))

        self.verilog_writer.write(file)
        self.template_writer.write(file+'h')

        core_file = self.vlnv.split(':')[2]+'.core'
        vlnv = self.vlnv
        with open(core_file, 'w') as f:
            f.write('CAPI=2:\n')
            files = [{file     : {'file_type' : 'systemVerilogSource'}},
                     {file+'h' : {'is_include_file' : True,
                                  'file_type' : 'verilogSource'}}
            ]
            coredata = {'name' : vlnv,
                        'targets' : {'default' : {}},
            }

            coredata['filesets'] = {'rtl' : {'files' : files}}
            coredata['targets']['default']['filesets'] = ['rtl']

            f.write(yaml.dump(coredata))
Example #7
0
    def gen_corescorecore(self, count):
        corescorecore = VerilogWriter('corescorecore')

        corescorecore.add(ModulePort('i_clk', 'input'))
        corescorecore.add(ModulePort('i_rst', 'input'))
        corescorecore.add(ModulePort('o_tdata', 'output', 8))
        corescorecore.add(ModulePort('o_tlast', 'output'))
        corescorecore.add(ModulePort('o_tvalid', 'output'))
        corescorecore.add(ModulePort('i_tready', 'input'))

        corescorecore.add(Wire('tdata', count * 8))
        corescorecore.add(Wire('tlast', count))
        corescorecore.add(Wire('tvalid', count))
        corescorecore.add(Wire('tready', count))

        for idx in range(count):
            base_ports = [
                Port('i_clk', 'i_clk'),
                Port('i_rst', 'i_rst'),
                Port('o_tdata', 'tdata[{}:{}]'.format(idx * 8 + 7, idx * 8)),
                Port('o_tlast', 'tlast[{}]'.format(idx)),
                Port('o_tvalid', 'tvalid[{}]'.format(idx)),
                Port('i_tready', 'tready[{}]'.format(idx)),
            ]
            corescorecore.add(
                Instance('base', 'core_' + str(idx), [
                    Parameter('memfile', '"core_{}.hex"'.format(idx)),
                    Parameter('memsize', '256')
                ], base_ports))

        arbports = [
            Port('clk', 'i_clk'),
            Port('rst', 'i_rst'),
            Port("s_axis_tdata".format(idx), "tdata"),
            Port("s_axis_tkeep".format(idx), "{}'d0".format(count)),
            Port("s_axis_tvalid".format(idx), 'tvalid'),
            Port("s_axis_tready".format(idx), 'tready'),
            Port("s_axis_tlast".format(idx), 'tlast'),
            Port("s_axis_tid".format(idx), "{}'d0".format(count * 8)),
            Port("s_axis_tdest".format(idx), "{}'d0".format(count * 8)),
            Port("s_axis_tuser".format(idx), "{}'d0".format(count)),
            Port('m_axis_tdata ', 'o_tdata'),
            Port('m_axis_tkeep ', ''),
            Port('m_axis_tvalid', 'o_tvalid'),
            Port('m_axis_tready', 'i_tready'),
            Port('m_axis_tlast ', 'o_tlast'),
            Port('m_axis_tid   ', ''),
            Port('m_axis_tdest ', ''),
            Port('m_axis_tuser ', ''),
        ]
        arbparams = [
            Parameter('S_COUNT', count),
            Parameter('DATA_WIDTH', 8),
            Parameter('KEEP_ENABLE', 0),
            Parameter('KEEP_WIDTH', 1),
            Parameter('ID_ENABLE', 0),
            Parameter('ID_WIDTH', 8),
            Parameter('DEST_ENABLE', 0),
            Parameter('DEST_WIDTH', 8),
            Parameter('USER_ENABLE', 0),
            Parameter('USER_WIDTH', 1),
            Parameter('ARB_TYPE', '"ROUND_ROBIN"'),
            Parameter('LSB_PRIORITY', '"HIGH"'),
        ]

        corescorecore.add(
            Instance('axis_arb_mux', 'axis_mux', arbparams, arbports))
        corescorecore.write('corescorecore.v')
class AHB3Intercon:
    def __init__(self, name, config_file):
        self.verilog_writer = VerilogWriter(name)
        self.template_writer = VerilogWriter(name)
        self.name = name
        d = OrderedDict()
        self.slaves = OrderedDict()
        self.masters = OrderedDict()
        import yaml

        def ordered_load(stream,
                         Loader=yaml.Loader,
                         object_pairs_hook=OrderedDict):
            class OrderedLoader(Loader):
                pass

            def construct_mapping(loader, node):
                loader.flatten_mapping(node)
                return object_pairs_hook(loader.construct_pairs(node))

            OrderedLoader.add_constructor(
                yaml.resolver.BaseResolver.DEFAULT_MAPPING_TAG,
                construct_mapping)
            return yaml.load(stream, OrderedLoader)

        data = ordered_load(open(config_file))

        config = data['parameters']
        files_root = data['files_root']
        self.vlnv = data['vlnv']

        index = 0
        for k, v in config['masters'].items():
            print("Found master " + k)
            self.masters[k] = Master(k, index, v)
            index = index + 1
        index = 0
        for k, v in config['slaves'].items():
            print("Found slave " + k)
            self.slaves[k] = Slave(k, index, v)
            index = index + 1

        #Create master/slave connections
        for master, slaves in d.items():
            for slave in slaves:
                self.masters[master].slaves += [self.slaves[slave]]
                self.slaves[slave].masters += [self.masters[master]]

        self.output_file = config.get('output_file', 'ahb3lite_intercon.sv')

    def _dump(self):
        print("*Masters*")
        for master in self.masters.values():
            print(master.name)
            for slave in master.slaves:
                print(' ' + slave.name)

        print("*Slaves*")
        for slave in self.slaves.values():
            print(slave.name)
            for master in slave.masters:
                print(' ' + master.name)

    def write(self):
        file = self.output_file

        # Template port/parameters
        template_ports = [Port('clk', 'CLK'), Port('reset_n', 'RESETn')]
        template_parameters = []

        # Gen top level ports
        self.verilog_writer.add(ModulePort('clk', 'input'))
        self.verilog_writer.add(ModulePort('reset_n', 'input'))

        # Declare global wires to pass to instantiation
        self.verilog_writer.add(LocalParam('MASTERS', len(self.masters)))
        self.verilog_writer.add(LocalParam('SLAVES', len(self.slaves)))
        mclog2 = max([math.ceil(math.log2(len(self.masters))), 1])
        self.verilog_writer.add(LocalParam('MASTER_BITS', mclog2))
        self.verilog_writer.add(
            Wire('mst_priority', mclog2, append=' [MASTERS]'))
        self.verilog_writer.add(Wire('slv_addr_base', 32, append=' [SLAVES]'))
        self.verilog_writer.add(Wire('slv_addr_mask', 32, append=' [SLAVES]'))
        for p in AHB3_MASTER_PORTS:
            self.verilog_writer.add(
                Wire('mst_{0}'.format(p.name), p.width, append=' [MASTERS]'))
            self.verilog_writer.add(
                Wire('slv_{0}'.format(p.name), p.width, append=' [SLAVES]'))
        for p in AHB3_SLAVE_PORTS:
            self.verilog_writer.add(
                Wire('mst_{0}'.format(p.name), p.width, append=' [MASTERS]'))
            self.verilog_writer.add(
                Wire('slv_{0}'.format(p.name), p.width, append=' [SLAVES]'))
        # Add HREADY/HREADYOUT
        self.verilog_writer.add(Wire('mst_HREADY', append=' [MASTERS]'))
        self.verilog_writer.add(Wire('slv_HREADY', append=' [SLAVES]'))
        self.verilog_writer.add(Wire('mst_HREADYOUT', append=' [MASTERS]'))
        self.verilog_writer.add(Wire('slv_HREADYOUT', append=' [SLAVES]'))

        # Generate master wires
        for key, value in self.masters.items():
            for p in AHB3_MASTER_PORTS:
                self.template_writer.add(
                    Wire('{0}_{1}'.format(key, p.name), p.width))
                self.verilog_writer.add(
                    ModulePort('{0}_{1}'.format(key, p.name), 'input',
                               p.width))
                template_ports += [
                    Port('{0}_{1}'.format(key, p.name),
                         '{0}_{1}'.format(key, p.name))
                ]
            for p in AHB3_SLAVE_PORTS:
                self.template_writer.add(
                    Wire('{0}_{1}'.format(key, p.name), p.width))
                self.verilog_writer.add(
                    ModulePort('{0}_{1}'.format(key, p.name), 'output',
                               p.width))
                template_ports += [
                    Port('{0}_{1}'.format(key, p.name),
                         '{0}_{1}'.format(key, p.name))
                ]
            # Add HREADY input port
            self.verilog_writer.add(
                ModulePort('{0}_{1}'.format(key, 'HREADY'), 'output'))
            self.template_writer.add(Wire('{0}_{1}'.format(key, 'HREADY')))
            template_ports += [
                Port('{0}_{1}'.format(key, 'HREADY'),
                     '{0}_{1}'.format(key, 'HREADY'))
            ]

        # Generate slave wires
        for key, value in self.slaves.items():
            for p in AHB3_MASTER_PORTS:
                self.template_writer.add(
                    Wire('{0}_{1}'.format(key, p.name), p.width))
                self.verilog_writer.add(
                    ModulePort('{0}_{1}'.format(key, p.name), 'output',
                               p.width))
                template_ports += [
                    Port('{0}_{1}'.format(key, p.name),
                         '{0}_{1}'.format(key, p.name))
                ]
            for p in AHB3_SLAVE_PORTS:
                self.template_writer.add(
                    Wire('{0}_{1}'.format(key, p.name), p.width))
                self.verilog_writer.add(
                    ModulePort('{0}_{1}'.format(key, p.name), 'input',
                               p.width))
                template_ports += [
                    Port('{0}_{1}'.format(key, p.name),
                         '{0}_{1}'.format(key, p.name))
                ]
            # Add HREADY/HREADYOUT  ports
            self.template_writer.add(Wire('{0}_{1}'.format(key, 'HREADY')))
            self.verilog_writer.add(
                ModulePort('{0}_{1}'.format(key, 'HREADY'), 'output'))
            self.template_writer.add(Wire('{0}_{1}'.format(key, 'HREADYOUT')))
            self.verilog_writer.add(
                ModulePort('{0}_{1}'.format(key, 'HREADYOUT'), 'input'))
            template_ports += [
                Port('{0}_{1}'.format(key, 'HREADY'),
                     '{0}_{1}'.format(key, 'HREADY'))
            ]
            template_ports += [
                Port('{0}_{1}'.format(key, 'HREADYOUT'),
                     '{0}_{1}'.format(key, 'HREADYOUT'))
            ]

        # Generate master assignments
        for key, val in self.masters.items():
            self.verilog_writer.add(
                Assign('mst_{0} [{1}]'.format('priority', val.index),
                       val.priority))
            for p in AHB3_MASTER_PORTS:
                self.verilog_writer.add(
                    Assign('mst_{0} [{1}]'.format(p.name, val.index),
                           '{0}_{1}'.format(key, p.name)))
            for p in AHB3_SLAVE_PORTS:
                self.verilog_writer.add(
                    Assign('{0}_{1}'.format(key, p.name),
                           'mst_{0} [{1}]'.format(p.name, val.index)))
            # Add HREADY assignments
            self.verilog_writer.add(
                Assign('mst_{0} [{1}]'.format('HREADY', val.index),
                       'mst_{0} [{1}]'.format('HREADYOUT', val.index)))
            self.verilog_writer.add(
                Assign('{0}_{1}'.format(key, 'HREADY'),
                       'mst_{0} [{1}]'.format('HREADYOUT', val.index)))

        # Generate slave assignments
        for key, val in self.slaves.items():
            self.verilog_writer.add(
                Assign('slv_addr_base [{0}]'.format(val.index),
                       val.offset,
                       width=32))
            self.verilog_writer.add(
                Assign('slv_addr_mask [{0}]'.format(val.index),
                       ~(val.size - 1),
                       width=32))
            for p in AHB3_MASTER_PORTS:
                self.verilog_writer.add(
                    Assign('{0}_{1}'.format(key, p.name),
                           'slv_{0} [{1}]'.format(p.name, val.index)))
            for p in AHB3_SLAVE_PORTS:
                self.verilog_writer.add(
                    Assign('slv_{0} [{1}]'.format(p.name, val.index),
                           '{0}_{1}'.format(key, p.name)))
            # Add HREADY assignments
            self.verilog_writer.add(
                Assign('slv_{0} [{1}]'.format('HREADY', val.index),
                       '{0}_{1}'.format(key, 'HREADYOUT')))
            self.verilog_writer.add(
                Assign('{0}_{1}'.format(key, 'HREADY'),
                       'slv_{0} [{1}]'.format('HREADYOUT', val.index)))

        # Instantiate interconnect
        inter_param = [
            Parameter('MASTERS', len(self.masters)),
            Parameter('SLAVES', len(self.slaves)),
            Parameter('HADDR_SIZE', 32),
            Parameter('HDATA_SIZE', 32),
            Parameter('MASTER_BITS', 'MASTER_BITS'),
        ]
        inter_ports = [
            Port('HCLK', 'clk'),
            Port('HRESETn', 'reset_n'),
            Port('mst_priority', 'mst_priority'),
            Port('slv_addr_base', 'slv_addr_base'),
            Port('slv_addr_mask', 'slv_addr_mask'),
            Port('mst_HREADY', 'mst_HREADY'),
            Port('slv_HREADY', 'slv_HREADY'),
            Port('mst_HREADYOUT', 'mst_HREADYOUT'),
            Port('slv_HREADYOUT', 'slv_HREADYOUT'),
        ]
        inter_ports += [
            Port('mst_' + p.name, 'mst_' + p.name) for p in AHB3_MASTER_PORTS
        ]
        inter_ports += [
            Port('slv_' + p.name, 'slv_' + p.name) for p in AHB3_MASTER_PORTS
        ]
        inter_ports += [
            Port('mst_' + p.name, 'mst_' + p.name) for p in AHB3_SLAVE_PORTS
        ]
        inter_ports += [
            Port('slv_' + p.name, 'slv_' + p.name) for p in AHB3_SLAVE_PORTS
        ]
        self.verilog_writer.add(
            Instance('ahb3lite_interconnect', 'ahb3lite_intercon0',
                     inter_param, inter_ports))

        # Create template
        self.template_writer.add(
            Instance(self.name, self.name + '0', template_parameters,
                     template_ports))

        self.verilog_writer.write(file)
        self.template_writer.write(file[:-2] + 'vh')

        core_file = self.vlnv.split(':')[2] + '.core'
        vlnv = self.vlnv
        with open(core_file, 'w') as f:
            f.write('CAPI=2:\n')
            files = [{
                file: {
                    'file_type': 'verilogSource'
                }
            }, {
                file[:-2] + 'vh': {
                    'is_include_file': True,
                    'file_type': 'verilogSource'
                }
            }]
            coredata = {
                'name': vlnv,
                'targets': {
                    'default': {}
                },
            }

            coredata['filesets'] = {'rtl': {'files': files}}
            coredata['targets']['default']['filesets'] = ['rtl']

            f.write(yaml.dump(coredata))
Example #9
0
    def gen_junctions_top(self, config):
        junctions = VerilogWriter('junctions')
        junctions.add(ModulePort('i_clk', 'input'))
        junctions.add(ModulePort('i_rst', 'input'))
        i = 0
        muxports = [Port('clk', 'i_clk'), Port('rst', 'i_rst')]

        for name, data in config.items():
            collector = None
            if data:
                collector = data.get('collector')

            junction_ports = [
                Port('i_clk', 'i_clk'),
                Port('i_rst', 'i_rst'),
            ]
            if collector == 'gpio':
                junction_ports += [
                    Port('i_gpio', 'i_' + name + '_gpio'),
                ]
            elif collector == 'spi':
                junction_ports += [
                    Port('o_sclk', 'o_' + name + '_sclk'),
                    Port('o_cs_n', 'o_' + name + '_cs_n'),
                    Port('o_mosi', 'o_' + name + '_mosi'),
                    Port('i_miso', 'i_' + name + '_miso'),
                ]
            junction_ports += [
                Port('o_tdata', 'tdata' + str(i)),
                Port('o_tlast', 'tlast' + str(i)),
                Port('o_tvalid', 'tvalid' + str(i)),
                Port('i_tready', 'tready' + str(i)),
            ]
            junctions.add(
                Instance(name, 'junction_' + name, [], junction_ports))

            if collector == 'gpio':
                junctions.add(ModulePort('i_' + name + '_gpio', 'input'))
            elif collector == 'spi':
                junctions.add(ModulePort('o_' + name + '_sclk', 'output'))
                junctions.add(ModulePort('o_' + name + '_cs_n', 'output'))
                junctions.add(ModulePort('o_' + name + '_mosi', 'output'))
                junctions.add(ModulePort('i_' + name + '_miso', 'input'))
            junctions.add(Wire('tdata' + str(i), 8))
            junctions.add(Wire('tlast' + str(i)))
            junctions.add(Wire('tvalid' + str(i)))
            junctions.add(Wire('tready' + str(i)))

            muxports += [
                Port("s{:02}_axis_tdata".format(i), 'tdata' + str(i)),
                Port("s{:02}_axis_tkeep".format(i), "1'b0"),
                Port("s{:02}_axis_tvalid".format(i), 'tvalid' + str(i)),
                Port("s{:02}_axis_tready".format(i), 'tready' + str(i)),
                Port("s{:02}_axis_tlast".format(i), 'tlast' + str(i)),
                Port("s{:02}_axis_tid".format(i), "8'd0"),
                Port("s{:02}_axis_tdest".format(i), "8'd0"),
                Port("s{:02}_axis_tuser".format(i), "1'b0"),
            ]
            i += 1

        junctions.add(ModulePort('o_tdata', 'output', 8))
        junctions.add(ModulePort('o_tlast', 'output'))
        junctions.add(ModulePort('o_tvalid', 'output'))
        junctions.add(ModulePort('i_tready', 'input'))

        muxports += [
            Port('m_axis_tdata ', 'o_tdata'),
            Port('m_axis_tkeep ', ''),
            Port('m_axis_tvalid', 'o_tvalid'),
            Port('m_axis_tready', 'i_tready'),
            Port('m_axis_tlast ', 'o_tlast'),
            Port('m_axis_tid   ', ''),
            Port('m_axis_tdest ', ''),
            Port('m_axis_tuser ', ''),
        ]

        junctions.add(
            Instance('bcmux', 'bcmux', [
                Parameter('USER_ENABLE', '0'),
                Parameter('ARB_TYPE', '"ROUND_ROBIN"')
            ], muxports))
        junctions.write('junctions.v')
Example #10
0
    def junction_top(self, name, collector, memfile):
        junction_top = VerilogWriter(name)
        junction_top.add(ModulePort('i_clk', 'input'))
        junction_top.add(ModulePort('i_rst', 'input'))
        if collector == 'gpio':
            junction_top.add(ModulePort('i_gpio', 'input'))
            junction_top.add(Wire('wb_stb'))
            junction_top.add(Wire('wb_rdt'))
            junction_top.add(Wire('wb_ack'))
            junction_top.add(
                Instance('collector_gpio', 'gpio', [], [
                    Port('i_clk', 'i_clk'),
                    Port('i_rst', 'i_rst'),
                    Port('i_dat', 'i_gpio'),
                    Port('i_wb_stb', 'wb_stb'),
                    Port('o_wb_rdt', 'wb_rdt'),
                    Port('o_wb_ack', 'wb_ack'),
                ]))

        elif collector == 'spi':
            junction_top.add(ModulePort('o_sclk', 'output'))
            junction_top.add(ModulePort('o_cs_n', 'output'))
            junction_top.add(ModulePort('o_mosi', 'output'))
            junction_top.add(ModulePort('i_miso', 'input'))
            junction_top.add(Wire('wb_adr', 32))
            junction_top.add(Wire('wb_dat', 32))
            junction_top.add(Wire('wb_we'))
            junction_top.add(Wire('wb_stb'))
            junction_top.add(Wire('wb_rdt', 32))
            junction_top.add(Wire('wb_ack'))
            junction_top.add(
                Instance('collector_spi', 'spi', [], [
                    Port('i_clk', 'i_clk'),
                    Port('i_rst', 'i_rst'),
                    Port('o_sclk', 'o_sclk'),
                    Port('o_cs_n', 'o_cs_n'),
                    Port('o_mosi', 'o_mosi'),
                    Port('i_miso', 'i_miso'),
                    Port('i_wb_adr', 'wb_adr[4:0]'),
                    Port('i_wb_dat', 'wb_dat'),
                    Port('i_wb_we', 'wb_we'),
                    Port('i_wb_stb', 'wb_stb'),
                    Port('o_wb_rdt', 'wb_rdt'),
                    Port('o_wb_ack', 'wb_ack'),
                ]))
        junction_top.add(ModulePort('o_tdata', 'output', 8))
        junction_top.add(ModulePort('o_tlast', 'output'))
        junction_top.add(ModulePort('o_tvalid', 'output'))
        junction_top.add(ModulePort('i_tready', 'input'))

        ports = [
            Port('i_clk', 'i_clk'),
            Port('i_rst', 'i_rst'),
        ]
        if collector == 'spi':
            ports += [
                Port('o_wb_coll_adr', 'wb_adr'),
                Port('o_wb_coll_dat', 'wb_dat'),
                Port('o_wb_coll_we', 'wb_we'),
            ]
        else:
            ports += [
                Port('o_wb_coll_adr', ''),
                Port('o_wb_coll_dat', ''),
                Port('o_wb_coll_we', ''),
            ]
        if collector:
            ports.append(Port('o_wb_coll_stb', 'wb_stb'))
        else:
            ports.append(Port('o_wb_coll_stb', ''))
        if collector == 'gpio':
            ports.append(Port('i_wb_coll_rdt', "{31'd0,wb_rdt}"))
        elif collector == 'spi':
            ports.append(Port('i_wb_coll_rdt', 'wb_rdt'))
        else:
            ports.append(Port('i_wb_coll_rdt', "32'd0"))
        if collector:
            ports.append(Port('i_wb_coll_ack', 'wb_ack'))
        else:
            ports.append(Port('i_wb_coll_ack', "1'b0"))
        ports += [
            Port('o_tdata', 'o_tdata'),
            Port('o_tlast', 'o_tlast'),
            Port('o_tvalid', 'o_tvalid'),
            Port('i_tready', 'i_tready'),
        ]

        junction_top.add(
            Instance('base', 'base',
                     [Parameter('memfile', '"' + memfile + '"')], ports))

        junction_top.write(os.path.join(name, 'junction.v'))
Example #11
0
class WbIntercon:
    def __init__(self, name, config_file):
        self.verilog_writer = VerilogWriter(name)
        self.template_writer = VerilogWriter(name)
        self.name = name
        d = OrderedDict()
        self.slaves = OrderedDict()
        self.masters = OrderedDict()
        config = configparser.SafeConfigParser()
        config.read(config_file)
        for section in config.sections():
            type = section.split()[0]
            try:
                name = section.split()[1]
            except IndexError:
                print(
                    "Malformed section header. Format is master|slave <name>")
                exit(1)
            if type == "master":
                print("Found master " + name)
                self.masters[name] = Master(name, dict(config.items(section)))
                d[name] = config.get(section, 'slaves').split()
            elif type == "slave":
                print("Found slave " + name)
                self.slaves[name] = Slave(name, dict(config.items(section)))
            else:
                print("Invalid section type " + type)
                exit(1)
        #Create master/slave connections
        for master, slaves in d.items():
            for slave in slaves:
                self.masters[master].slaves += [self.slaves[slave]]
                self.slaves[slave].masters += [self.masters[master]]

    def _dump(self):
        print("*Masters*")
        for master in self.masters.values():
            print(master.name)
            for slave in master.slaves:
                print(' ' + slave.name)

        print("*Slaves*")
        for slave in self.slaves.values():
            print(slave.name)
            for master in slave.masters:
                print(' ' + master.name)

    def _gen_mux(self, master):
        parameters = [Parameter('num_slaves', len(master.slaves))]
        match_addr = '{' + ', '.join(
            ["32'h{addr:08x}".format(addr=s.offset)
             for s in master.slaves]) + '}'
        parameters += [Parameter('MATCH_ADDR', match_addr)]

        match_mask = '{' + ', '.join(
            ["32'h{mask:08x}".format(mask=s.mask)
             for s in master.slaves]) + '}'
        parameters += [Parameter('MATCH_MASK', match_mask)]
        ports = [Port('wb_clk_i', 'wb_clk_i'), Port('wb_rst_i', 'wb_rst_i')]
        m = master.name

        # If we are converting bus type, do not use _i / _o
        if master.bus_type == 'wishbone':
            input_format = 'wb_%s_%s_i'
            output_format = 'wb_%s_%s_o'
        else:
            # We're the slave to the conversion logic
            input_format = 'wb_m2s_%s_%s'
            output_format = 'wb_s2m_%s_%s'

        #Create mux master side connections
        for p in WB_MASTER_PORTS:
            ports += [Port('wbm_' + p.name + '_i', input_format % (m, p.name))]
        for p in WB_SLAVE_PORTS:
            ports += [
                Port('wbm_' + p.name + '_o', output_format % (m, p.name))
            ]

        #Create mux slave side connections
        name_list = []
        for s in master.slaves:

            #If we have only one master the wb_mux is the last piece before
            #the slave. If the slave's datawidth is 32, we go straight from
            #the wb_mux to the slave.
            if len(s.masters) == 1 and int(s.datawidth) == 32:
                name_list += ['wb_' + s.name + '_{0}_{1}']
            #If not, we'll need a wb_data_resize and then new wires.
            elif len(s.masters) == 1 and int(s.datawidth) < 32:
                name_list += ['wb_{dir}' + 'resize_' + s.name + '_{0}']
            #If there is more than on master for that slave, there will
            #be an arbiter and the wb_data_resize will be after that.
            else:
                name_list += ['wb_{dir}' + m + '_' + s.name + '_{0}']

        for p in WB_MASTER_PORTS:
            ports += [
                Port(
                    'wbs_' + p.name + '_o', '{' +
                    ', '.join(name_list).format(p.name, 'o', dir='m2s_') + '}')
            ]
        for p in WB_SLAVE_PORTS:
            ports += [
                Port(
                    'wbs_' + p.name + '_i', '{' +
                    ', '.join(name_list).format(p.name, 'i', dir='s2m_') + '}')
            ]

        self.verilog_writer.add(
            Instance('wb_mux', 'wb_mux_' + m, parameters, ports))

    def _gen_arbiter(self, slave):
        parameters = [Parameter('num_masters', len(slave.masters))]
        ports = [Port('wb_clk_i', 'wb_clk_i'), Port('wb_rst_i', 'wb_rst_i')]
        s = slave.name

        name_list = []
        for m in slave.masters:
            name_list += ['wb_{dir}' + m.name + '_' + s + '_{0}']
        for p in WB_MASTER_PORTS:
            ports += [
                Port(
                    'wbm_' + p.name + '_i', '{' +
                    ', '.join(name_list).format(p.name, 'i', dir='m2s_') + '}')
            ]
        for p in WB_SLAVE_PORTS:
            ports += [
                Port(
                    'wbm_' + p.name + '_o', '{' +
                    ', '.join(name_list).format(p.name, 'o', dir='s2m_') + '}')
            ]

        #Create slave connections
        #If the slave's data width is 32, we don't need a wb_data_resize
        if int(slave.datawidth) == 32:
            # If we are converting bus type, do not use _i / _o
            if slave.bus_type == 'wishbone':
                input_format = 'wb_%s_%s_i'
                output_format = 'wb_%s_%s_o'
            else:
                input_format = 'wb_s2m_%s_%s'
                output_format = 'wb_m2s_%s_%s'
            for p in WB_MASTER_PORTS:
                ports += [
                    Port('wbs_' + p.name + '_o', output_format % (s, p.name))
                ]
            for p in WB_SLAVE_PORTS:
                ports += [
                    Port('wbs_' + p.name + '_i', input_format % (s, p.name))
                ]
        #Else, connect to the resizer
        else:
            for p in WB_MASTER_PORTS:
                ports += [
                    Port('wbs_' + p.name + '_o',
                         'wb_m2s_resize_' + s + '_' + p.name)
                ]
            for p in WB_SLAVE_PORTS:
                ports += [
                    Port('wbs_' + p.name + '_i',
                         'wb_s2m_resize_' + s + '_' + p.name)
                ]

        self.verilog_writer.add(
            Instance('wb_arbiter', 'wb_arbiter_' + s, parameters, ports))

    def _gen_resize(self, slave):
        parameters = [Parameter('aw', 32)]
        parameters += [Parameter('mdw', 32)]
        parameters += [Parameter('sdw', slave.datawidth)]
        s = slave.name

        ports = []
        #Create master connections
        for p in WB_MASTER_PORTS:
            ports += [
                Port('wbm_' + p.name + '_i',
                     'wb_m2s_resize_' + s + '_' + p.name)
            ]
        for p in WB_SLAVE_PORTS:
            ports += [
                Port('wbm_' + p.name + '_o',
                     'wb_s2m_resize_' + s + '_' + p.name)
            ]

        # If we are converting bus type, do not use _i / _o
        if slave.bus_type == 'wishbone':
            input_format = 'wb_%s_%s_i'
            output_format = 'wb_%s_%s_o'
        else:
            input_format = 'wb_s2m_%s_%s'
            output_format = 'wb_m2s_%s_%s'

        #Create slave connections
        for p in WB_MASTER_PORTS:
            if p.name != "sel":
                ports.append(
                    Port('wbs_' + p.name + '_o', output_format % (s, p.name)))
        for p in WB_SLAVE_PORTS:
            ports.append(
                Port('wbs_' + p.name + '_i', input_format % (s, p.name)))

        self.verilog_writer.add(
            Instance('wb_data_resize', 'wb_data_resize_' + s, parameters,
                     ports))

        for p in WB_MASTER_PORTS:
            wirename = 'wb_m2s_resize_{slave}_{port}'.format(slave=s,
                                                             port=p.name)
            self.verilog_writer.add(Wire(wirename, p.width))
        for p in WB_SLAVE_PORTS:
            wirename = 'wb_s2m_resize_{slave}_{port}'.format(slave=s,
                                                             port=p.name)
            self.verilog_writer.add(Wire(wirename, p.width))

    def _gen_wishbone_master_port(self, master):
        template_ports = []
        for p in WB_MASTER_PORTS:
            portname = 'wb_{master}_{port}_i'.format(master=master.name,
                                                     port=p.name)
            wirename = 'wb_m2s_{master}_{port}'.format(master=master.name,
                                                       port=p.name)
            self.verilog_writer.add(ModulePort(portname, 'input', p.width))
            self.template_writer.add(Wire(wirename, p.width))
            template_ports += [Port(portname, wirename)]
        for p in WB_SLAVE_PORTS:
            portname = 'wb_{master}_{port}_o'.format(master=master.name,
                                                     port=p.name)
            wirename = 'wb_s2m_{master}_{port}'.format(master=master.name,
                                                       port=p.name)
            self.verilog_writer.add(ModulePort(portname, 'output', p.width))
            self.template_writer.add(Wire(wirename, p.width))
            template_ports += [Port(portname, wirename)]
        return template_ports

    def _gen_wishbone_port(self, slave):
        template_ports = []
        for p in WB_MASTER_PORTS:
            portname = 'wb_{slave}_{port}_o'.format(slave=slave.name,
                                                    port=p.name)
            wirename = 'wb_m2s_{slave}_{port}'.format(slave=slave.name,
                                                      port=p.name)
            dw = int(WB_DATA_WIDTH[p.name] * slave.datawidth) or p.width
            self.verilog_writer.add(ModulePort(portname, 'output', dw))
            self.template_writer.add(Wire(wirename, dw))
            template_ports += [Port(portname, wirename)]
        for p in WB_SLAVE_PORTS:
            portname = 'wb_{slave}_{port}_i'.format(slave=slave.name,
                                                    port=p.name)
            wirename = 'wb_s2m_{slave}_{port}'.format(slave=slave.name,
                                                      port=p.name)
            dw = int(WB_DATA_WIDTH[p.name] * slave.datawidth) or p.width
            self.verilog_writer.add(ModulePort(portname, 'input', dw))
            self.template_writer.add(Wire(wirename, dw))
            template_ports += [Port(portname, wirename)]
        return template_ports

    def _gen_bus_converter(self, bus, name, is_master, datawidth,
                           datawidth_map, ports):
        converter_ports = [
            Port('wb_clk_i', 'wb_clk_i'),
            Port('wb_rst_i', 'wb_rst_i')
        ]
        template_ports = []

        out_direction = 'm2s' if is_master else 's2m'

        # Wishbone side
        ms_type = 'm' if is_master else 's'
        # Foreign side
        f_ms_type = 's' if is_master else 'm'

        # Create Wishbone connections
        wb_ports = []
        wb_ports.extend([(p, 'm2s') for p in WB_MASTER_PORTS])
        wb_ports.extend([(p, 's2m') for p in WB_SLAVE_PORTS])
        for p, direction in wb_ports:
            pin_direction = 'output' if direction == out_direction else 'input'
            wirename = 'wb_{direction}_{name}_{port}'.format(
                direction=direction, name=name, port=p.name)
            converter_ports.append(
                Port(
                    '%s_%s_%s' % ('wbm' if ms_type == 'm' else 'wb', p.name,
                                  pin_direction[0]), wirename))
            dw = int(WB_DATA_WIDTH[p.name] * datawidth) or p.width
            self.verilog_writer.add(Wire(wirename, dw))

        # Create foreign bus connections
        for p, direction in ports:
            pin_direction = 'output' if direction != out_direction else 'input'
            portname = '{d}_{bus}_{name}_{port}_{direction}'.format(
                d=f_ms_type,
                bus=bus,
                direction=pin_direction[0],
                name=name,
                port=p.name)
            wirename = '{bus}_{direction}_{name}_{port}'.format(
                bus=bus, direction=direction, name=name, port=p.name)
            converter_ports.append(
                Port(
                    '{d}_{bus}_{port}_{direction}'.format(
                        d=f_ms_type,
                        bus=bus,
                        direction=pin_direction[0],
                        port=p.name), portname))
            dw = int(datawidth_map[p.name] * datawidth) or p.width
            self.verilog_writer.add(
                ModulePort(portname, pin_direction, p.width))
            self.template_writer.add(Wire(wirename, dw))
            template_ports.append(Port(portname, wirename))

        return template_ports, converter_ports

    def _gen_axi4_port(self, thing, is_master=False):
        parameters = [
            Parameter('C_AXI_ADDR_WIDTH', 32),
            Parameter('C_S_AXI_DATA_WIDTH', thing.datawidth)
        ]

        ports = []
        ports.extend([(p, 'm2s') for p in AXI4_MASTER_PORTS])
        ports.extend([(p, 's2m') for p in AXI4_SLAVE_PORTS])
        if thing.bus_type == 'axi4-lite':
            ports = [p for p in ports if p[0].name in AXI4_LITE_PORTS]

        template_ports, converter_ports = self._gen_bus_converter(
            'axi',
            name=thing.name,
            is_master=is_master,
            datawidth=thing.datawidth,
            datawidth_map=AXI4_DATA_WIDTH,
            ports=ports)

        core = 'wb_axi_slave' if is_master else 'wb_axi_master'
        self.verilog_writer.add(
            Instance(core, '%s_%s' % (core, thing.name), parameters,
                     converter_ports))
        return template_ports

    def _gen_avalon_port(self, thing, is_master=False):
        parameters = [Parameter('AW', 32), Parameter('DW', thing.datawidth)]

        if not is_master:
            parameters.append(Parameter('BURST_SUPPORT', 1))

        ports = []
        ports.extend([(p, 'm2s') for p in AVALON_MASTER_PORTS])
        ports.extend([(p, 's2m') for p in AVALON_SLAVE_PORTS])

        template_ports, converter_ports = self._gen_bus_converter(
            'av',
            name=thing.name,
            is_master=is_master,
            datawidth=thing.datawidth,
            datawidth_map=AVALON_DATA_WIDTH,
            ports=ports)

        core = 'avalon_to_wb_bridge' if is_master else 'wb_to_avalon_bridge'
        self.verilog_writer.add(
            Instance(core, '%s_%s' % (core, thing.name), parameters,
                     converter_ports))
        return template_ports

    def write(self, file):
        #Declare wires. Only conections between muxes and arbiters need explicit wires
        for key, value in self.masters.items():
            for slave in value.slaves:
                if len(slave.masters) > 1:
                    for p in WB_MASTER_PORTS:
                        self.verilog_writer.add(
                            Wire(
                                'wb_m2s_{0}_{1}_{2}'.format(
                                    key, slave.name, p.name), p.width))
                    for p in WB_SLAVE_PORTS:
                        self.verilog_writer.add(
                            Wire(
                                'wb_s2m_{0}_{1}_{2}'.format(
                                    key, slave.name, p.name), p.width))

        self.verilog_writer.add(ModulePort('wb_clk_i', 'input'))
        self.verilog_writer.add(ModulePort('wb_rst_i', 'input'))

        template_ports = [
            Port('wb_clk_i', 'wb_clk'),
            Port('wb_rst_i', 'wb_rst')
        ]
        template_parameters = []

        for master in self.masters.values():
            self._gen_mux(master)
            if master.bus_type == 'wishbone':
                master_template_ports = self._gen_wishbone_master_port(master)
            elif master.bus_type.startswith('axi4'):
                master_template_ports = self._gen_axi4_port(master,
                                                            is_master=True)
            elif master.bus_type == 'avalon':
                master_template_ports = self._gen_avalon_port(master,
                                                              is_master=True)
            template_ports.extend(master_template_ports)

        for slave in self.slaves.values():
            if len(slave.masters) > 1:
                self._gen_arbiter(slave)
            if int(slave.datawidth) < 32:
                self._gen_resize(slave)
            if slave.bus_type == 'wishbone':
                slave_template_ports = self._gen_wishbone_port(slave)
            elif slave.bus_type.startswith('axi4'):
                slave_template_ports = self._gen_axi4_port(slave)
            elif slave.bus_type == 'avalon':
                slave_template_ports = self._gen_avalon_port(slave)
            template_ports.extend(slave_template_ports)

        self.template_writer.add(
            Instance(self.name, self.name + '0', template_parameters,
                     template_ports))

        self.verilog_writer.write(file)
        self.template_writer.write(file + 'h')
Example #12
0
class WbIntercon:
    def __init__(self, name, config_file):
        self.verilog_writer = VerilogWriter(name)
        self.template_writer = VerilogWriter(name);
        self.name = name
        d = OrderedDict()
        self.slaves = OrderedDict()
        self.masters = OrderedDict()
        config = configparser.SafeConfigParser()
        config.read(config_file)
        for section in config.sections():
            type=section.split()[0]
            try:
                name=section.split()[1]
            except IndexError:
                print("Malformed section header. Format is master|slave <name>")
                exit(1)
            if type == "master":
                print("Found master " + name)
                self.masters[name] = Master(name, dict(config.items(section)))
                d[name] = config.get(section, 'slaves').split()
            elif type == "slave":
                print("Found slave " + name)
                self.slaves[name] = Slave(name, dict(config.items(section)))
            else:
                print("Invalid section type " + type)
                exit(1)
        #Create master/slave connections
        for master, slaves in d.items():
            for slave in slaves:
                self.masters[master].slaves += [self.slaves[slave]]
                self.slaves[slave].masters += [self.masters[master]]

    def _dump(self):
        print("*Masters*")
        for master in self.masters.values():
            print(master.name)
            for slave in master.slaves:
                print(' ' + slave.name)

        print("*Slaves*")
        for slave in self.slaves.values():
            print(slave.name)
            for master in slave.masters:
                print(' ' + master.name)
                            

    def _gen_mux(self, master):
        parameters = [Parameter('num_slaves', len(master.slaves))]
        match_addr = '{' + ', '.join(["32'h{addr:08x}".format(addr=s.offset) for s in master.slaves]) + '}'
        parameters += [Parameter('MATCH_ADDR', match_addr)]

        match_mask = '{' + ', '.join(["32'h{mask:08x}".format(mask=s.mask) for s in master.slaves]) + '}'
        parameters += [Parameter('MATCH_MASK', match_mask)]
        ports = [Port('wb_clk_i', 'wb_clk_i'),
                 Port('wb_rst_i', 'wb_rst_i')]
        m = master.name

        # If we are converting bus type, do not use _i / _o
        if master.bus_type == 'wishbone':
            input_format = 'wb_%s_%s_i'
            output_format = 'wb_%s_%s_o'
        else:
            # We're the slave to the conversion logic
            input_format = 'wb_m2s_%s_%s'
            output_format = 'wb_s2m_%s_%s'

        #Create mux master side connections
        for p in WB_MASTER_PORTS:
            ports += [Port('wbm_' + p.name + '_i', input_format % (m, p.name))]
        for p in WB_SLAVE_PORTS:
            ports += [Port('wbm_' + p.name + '_o', output_format % (m, p.name))]

        #Create mux slave side connections
        name_list = []
        for s in master.slaves:

            #If we have only one master the wb_mux is the last piece before
            #the slave. If the slave's datawidth is 32, we go straight from
            #the wb_mux to the slave.
            if len(s.masters) == 1 and int(s.datawidth) == 32:
                name_list += ['wb_' + s.name + '_{0}_{1}']
            #If not, we'll need a wb_data_resize and then new wires.
            elif len(s.masters) == 1 and int(s.datawidth) < 32:
                 name_list += ['wb_{dir}' + 'resize_' + s.name + '_{0}']
            #If there is more than on master for that slave, there will
            #be an arbiter and the wb_data_resize will be after that.
            else:
                name_list += ['wb_{dir}'+ m + '_' + s.name + '_{0}']

        for p in WB_MASTER_PORTS:
            ports += [Port('wbs_'+p.name+'_o', '{' + ', '.join(name_list).format(p.name, 'o', dir='m2s_')+'}')]
        for p in WB_SLAVE_PORTS:
            ports += [Port('wbs_'+p.name+'_i', '{' + ', '.join(name_list).format(p.name, 'i', dir='s2m_')+'}')]

        self.verilog_writer.add(Instance('wb_mux', 'wb_mux_'+m,parameters, ports))

    def _gen_arbiter(self, slave):
        parameters = [Parameter('num_masters', len(slave.masters))]
        ports = [Port('wb_clk_i', 'wb_clk_i'),
                 Port('wb_rst_i', 'wb_rst_i')]
        s = slave.name

        name_list = []
        for m in slave.masters:
            name_list += ['wb_{dir}'+ m.name + '_' + s + '_{0}']
        for p in WB_MASTER_PORTS:
            ports += [Port('wbm_'+p.name+'_i', '{' + ', '.join(name_list).format(p.name, 'i', dir='m2s_')+'}')]
        for p in WB_SLAVE_PORTS:
            ports += [Port('wbm_'+p.name+'_o', '{' + ', '.join(name_list).format(p.name, 'o', dir='s2m_')+'}')]

        #Create slave connections
        #If the slave's data width is 32, we don't need a wb_data_resize
        if int(slave.datawidth) == 32:
            # If we are converting bus type, do not use _i / _o
            if slave.bus_type == 'wishbone':
                input_format = 'wb_%s_%s_i'
                output_format = 'wb_%s_%s_o'
            else:
                input_format = 'wb_s2m_%s_%s'
                output_format = 'wb_m2s_%s_%s'
            for p in WB_MASTER_PORTS:
                ports += [Port('wbs_' + p.name + '_o', output_format % (s, p.name))]
            for p in WB_SLAVE_PORTS:
                ports += [Port('wbs_' + p.name + '_i', input_format % (s, p.name))]
        #Else, connect to the resizer
        else:
            for p in WB_MASTER_PORTS:
                ports += [Port('wbs_' + p.name + '_o', 'wb_m2s_resize_'+s+'_'+p.name)]
            for p in WB_SLAVE_PORTS:
                ports += [Port('wbs_' + p.name + '_i', 'wb_s2m_resize_'+s+'_'+p.name)]

        self.verilog_writer.add(Instance('wb_arbiter', 'wb_arbiter_'+s,parameters, ports))

    def _gen_resize(self, slave):
        parameters = [Parameter('aw', 32)]
        parameters += [Parameter('mdw', 32)]
        parameters += [Parameter('sdw', slave.datawidth)]
        s = slave.name

        ports =[]
        #Create master connections
        for p in WB_MASTER_PORTS:
            ports += [Port('wbm_'+p.name+'_i', 'wb_m2s_resize_'+s+'_'+p.name)]
        for p in WB_SLAVE_PORTS:
            ports += [Port('wbm_'+p.name+'_o', 'wb_s2m_resize_'+s+'_'+p.name)]

        # If we are converting bus type, do not use _i / _o
        if slave.bus_type == 'wishbone':
          input_format = 'wb_%s_%s_i'
          output_format = 'wb_%s_%s_o'
        else:
          input_format = 'wb_s2m_%s_%s'
          output_format = 'wb_m2s_%s_%s'

        #Create slave connections
        for p in WB_MASTER_PORTS:
            if p.name != "sel":
                ports.append(Port('wbs_' + p.name + '_o', output_format % (s, p.name)))
        for p in WB_SLAVE_PORTS:
            ports.append(Port('wbs_' + p.name + '_i', input_format % (s, p.name)))

        self.verilog_writer.add(Instance('wb_data_resize', 'wb_data_resize_'+s,parameters, ports))

        for p in WB_MASTER_PORTS:
            wirename = 'wb_m2s_resize_{slave}_{port}'.format(slave=s, port=p.name)
            self.verilog_writer.add(Wire(wirename, p.width))
        for p in WB_SLAVE_PORTS:
            wirename = 'wb_s2m_resize_{slave}_{port}'.format(slave=s, port=p.name)
            self.verilog_writer.add(Wire(wirename, p.width))

    def _gen_wishbone_master_port(self, master):
        template_ports = []
        for p in WB_MASTER_PORTS:
            portname = 'wb_{master}_{port}_i'.format(master=master.name, port=p.name)
            wirename = 'wb_m2s_{master}_{port}'.format(master=master.name, port=p.name)
            self.verilog_writer.add(ModulePort(portname, 'input', p.width))
            self.template_writer.add(Wire(wirename, p.width))
            template_ports += [Port(portname, wirename)]
        for p in WB_SLAVE_PORTS:
            portname = 'wb_{master}_{port}_o'.format(master=master.name, port=p.name)
            wirename = 'wb_s2m_{master}_{port}'.format(master=master.name, port=p.name)
            self.verilog_writer.add(ModulePort(portname, 'output', p.width))
            self.template_writer.add(Wire(wirename, p.width))
            template_ports += [Port(portname, wirename)]
        return template_ports

    def _gen_wishbone_port(self, slave):
        template_ports = []
        for p in WB_MASTER_PORTS:
            portname = 'wb_{slave}_{port}_o'.format(slave=slave.name, port=p.name)
            wirename = 'wb_m2s_{slave}_{port}'.format(slave=slave.name, port=p.name)
            dw = int(WB_DATA_WIDTH[p.name] * slave.datawidth) or p.width
            self.verilog_writer.add(ModulePort(portname, 'output', dw))
            self.template_writer.add(Wire(wirename, dw))
            template_ports += [Port(portname, wirename)]
        for p in WB_SLAVE_PORTS:
            portname = 'wb_{slave}_{port}_i'.format(slave=slave.name, port=p.name)
            wirename = 'wb_s2m_{slave}_{port}'.format(slave=slave.name, port=p.name)
            dw = int(WB_DATA_WIDTH[p.name] * slave.datawidth) or p.width
            self.verilog_writer.add(ModulePort(portname, 'input', dw))
            self.template_writer.add(Wire(wirename, dw))
            template_ports += [Port(portname, wirename)]
        return template_ports

    def _gen_bus_converter(self, bus, name, is_master, datawidth, datawidth_map, ports):
        converter_ports = [Port('wb_clk_i', 'wb_clk_i'),
            Port('wb_rst_i', 'wb_rst_i')]
        template_ports = []

        out_direction = 'm2s' if is_master else 's2m'

        # Wishbone side
        ms_type = 'm' if is_master else 's'
        # Foreign side
        f_ms_type = 's' if is_master else 'm'

        # Create Wishbone connections
        wb_ports = []
        wb_ports.extend([(p, 'm2s') for p in WB_MASTER_PORTS])
        wb_ports.extend([(p, 's2m') for p in WB_SLAVE_PORTS])
        for p, direction in wb_ports:
            pin_direction = 'output' if direction == out_direction else 'input'
            wirename = 'wb_{direction}_{name}_{port}'.format(
                direction=direction, name=name, port=p.name)
            converter_ports.append(
                Port('%s_%s_%s' % ('wbm' if ms_type == 'm' else 'wb', p.name,
                  pin_direction[0]), wirename))
            dw = int(WB_DATA_WIDTH[p.name] * datawidth) or p.width
            self.verilog_writer.add(Wire(wirename, dw))

        # Create foreign bus connections
        for p, direction in ports:
            pin_direction = 'output' if direction != out_direction else 'input'
            portname = '{d}_{bus}_{name}_{port}_{direction}'.format(
                d=f_ms_type, bus=bus, direction=pin_direction[0],
                name=name, port=p.name)
            wirename = '{bus}_{direction}_{name}_{port}'.format(
                bus=bus, direction=direction, name=name, port=p.name)
            converter_ports.append(
                Port('{d}_{bus}_{port}_{direction}'.format(
                    d=f_ms_type, bus=bus, direction=pin_direction[0],
                    port=p.name), portname))
            dw = int(datawidth_map[p.name] * datawidth) or p.width
            self.verilog_writer.add(
                ModulePort(portname, pin_direction, p.width))
            self.template_writer.add(Wire(wirename, dw))
            template_ports.append(Port(portname, wirename))

        return template_ports, converter_ports

    def _gen_axi4_port(self, thing, is_master=False):
        parameters = [Parameter('C_AXI_ADDR_WIDTH', 32),
            Parameter('C_S_AXI_DATA_WIDTH', thing.datawidth)]

        ports = []
        ports.extend([(p, 'm2s') for p in AXI4_MASTER_PORTS])
        ports.extend([(p, 's2m') for p in AXI4_SLAVE_PORTS])
        if thing.bus_type == 'axi4-lite':
            ports = [p for p in ports if p[0].name in AXI4_LITE_PORTS]

        template_ports, converter_ports = self._gen_bus_converter(
            'axi', name=thing.name, is_master=is_master,
            datawidth=thing.datawidth, datawidth_map=AXI4_DATA_WIDTH,
            ports=ports)

        core = 'wb_axi_slave' if is_master else 'wb_axi_master'
        self.verilog_writer.add(Instance(
            core, '%s_%s' % (core, thing.name), parameters, converter_ports))
        return template_ports

    def _gen_avalon_port(self, thing, is_master=False):
        parameters = [Parameter('AW', 32),
            Parameter('DW', thing.datawidth)]

        if not is_master:
            parameters.append(Parameter('BURST_SUPPORT', 1))

        ports = []
        ports.extend([(p, 'm2s') for p in AVALON_MASTER_PORTS])
        ports.extend([(p, 's2m') for p in AVALON_SLAVE_PORTS])

        template_ports, converter_ports = self._gen_bus_converter(
            'av', name=thing.name, is_master=is_master,
            datawidth=thing.datawidth, datawidth_map=AVALON_DATA_WIDTH,
            ports=ports)

        core = 'avalon_to_wb_bridge' if is_master else 'wb_to_avalon_bridge'
        self.verilog_writer.add(Instance(
            core, '%s_%s' % (core, thing.name), parameters, converter_ports))
        return template_ports

    def write(self, file):
        #Declare wires. Only conections between muxes and arbiters need explicit wires
        for key, value in self.masters.items():
            for slave in value.slaves:
                if len(slave.masters)>1:
                    for p in WB_MASTER_PORTS:
                        self.verilog_writer.add(Wire('wb_m2s_{0}_{1}_{2}'.format(key, slave.name, p.name), p.width))
                    for p in WB_SLAVE_PORTS:
                        self.verilog_writer.add(Wire('wb_s2m_{0}_{1}_{2}'.format(key, slave.name, p.name), p.width))

        self.verilog_writer.add(ModulePort('wb_clk_i', 'input'))
        self.verilog_writer.add(ModulePort('wb_rst_i', 'input'))

        template_ports = [Port('wb_clk_i', 'wb_clk'),
                          Port('wb_rst_i', 'wb_rst')]
        template_parameters = []

        for master in self.masters.values():
            self._gen_mux(master)
            if master.bus_type == 'wishbone':
                master_template_ports = self._gen_wishbone_master_port(master)
            elif master.bus_type.startswith('axi4'):
                master_template_ports = self._gen_axi4_port(
                    master, is_master=True)
            elif master.bus_type == 'avalon':
                master_template_ports = self._gen_avalon_port(
                    master, is_master=True)
            template_ports.extend(master_template_ports)

        for slave in self.slaves.values():
            if len(slave.masters) > 1:
                self._gen_arbiter(slave)
            if int(slave.datawidth) < 32:
                self._gen_resize(slave)
            if slave.bus_type == 'wishbone':
                slave_template_ports = self._gen_wishbone_port(slave)
            elif slave.bus_type.startswith('axi4'):
                slave_template_ports = self._gen_axi4_port(slave)
            elif slave.bus_type == 'avalon':
                slave_template_ports = self._gen_avalon_port(slave)
            template_ports.extend(slave_template_ports)

        self.template_writer.add(Instance(self.name, self.name+'0',
                                          template_parameters, template_ports))

        self.verilog_writer.write(file)
        self.template_writer.write(file+'h')
Example #13
0
class WbIntercon:
    def __init__(self, name, config_file):
        self.verilog_writer = VerilogWriter(name)
        self.template_writer = VerilogWriter(name);
        self.name = name
        d = OrderedDict()
        self.slaves = OrderedDict()
        self.masters = OrderedDict()
        import yaml

        def ordered_load(stream, Loader=yaml.Loader, object_pairs_hook=OrderedDict):
            class OrderedLoader(Loader):
                pass
            def construct_mapping(loader, node):
                loader.flatten_mapping(node)
                return object_pairs_hook(loader.construct_pairs(node))
            OrderedLoader.add_constructor(
                yaml.resolver.BaseResolver.DEFAULT_MAPPING_TAG,
                construct_mapping)
            return yaml.load(stream, OrderedLoader)
        data = ordered_load(open(config_file))

        config     = data['parameters']
        files_root = data['files_root']
        self.vlnv       = data['vlnv']

        valid_endians = ['big', 'little']
        if 'endian' in config:
            self.endian = config['endian']
            if self.endian not in valid_endians:
                raise UnknownPropertyError("Unknown data resizer endian '{}' specified. Valid endians: {}".format(config['endian'], valid_endians))
        else:
            self.endian = "big"

        print("Wishbone Data Resizer Endian: {}".format(config['endian']))

        for k,v in config['masters'].items():
            print("Found master " + k)
            self.masters[k] = Master(k,v)
            d[k] = v['slaves']
        for k,v in config['slaves'].items():
            print("Found slave " + k)
            self.slaves[k] = Slave(k,v)

        #Create master/slave connections
        for master, slaves in d.items():
            for slave in slaves:
                self.masters[master].slaves += [self.slaves[slave]]
                self.slaves[slave].masters += [self.masters[master]]

        self.output_file = config.get('output_file', 'wb_intercon.v')

    def _dump(self):
        print("*Masters*")
        for master in self.masters.values():
            print(master.name)
            for slave in master.slaves:
                print(' ' + slave.name)

        print("*Slaves*")
        for slave in self.slaves.values():
            print(slave.name)
            for master in slave.masters:
                print(' ' + master.name)


    def _gen_mux(self, master):
        parameters = [Parameter('num_slaves', len(master.slaves))]
        match_addr = '{' + ', '.join(["32'h{addr:08x}".format(addr=s.offset) for s in master.slaves]) + '}'
        parameters += [Parameter('MATCH_ADDR', match_addr)]

        match_mask = '{' + ', '.join(["32'h{mask:08x}".format(mask=s.mask) for s in master.slaves]) + '}'
        parameters += [Parameter('MATCH_MASK', match_mask)]
        ports = [Port('wb_clk_i', 'wb_clk_i'),
                 Port('wb_rst_i', 'wb_rst_i')]
        m = master.name

        input_format = 'wb_%s_%s_i'
        output_format = 'wb_%s_%s_o'

        #Create mux master side connections
        for p in WB_MASTER_PORTS:
            ports += [Port('wbm_' + p.name + '_i', input_format % (m, p.name))]
        for p in WB_SLAVE_PORTS:
            ports += [Port('wbm_' + p.name + '_o', output_format % (m, p.name))]

        #Create mux slave side connections
        name_list = []
        for s in master.slaves:

            #If we have only one master the wb_mux is the last piece before
            #the slave. If the slave's datawidth is 32, we go straight from
            #the wb_mux to the slave.
            if len(s.masters) == 1 and int(s.datawidth) == 32:
                name_list += ['wb_' + s.name + '_{0}_{1}']
            #If not, we'll need a wb_data_resize and then new wires.
            elif len(s.masters) == 1 and int(s.datawidth) < 32:
                 name_list += ['wb_{dir}' + 'resize_' + s.name + '_{0}']
            #If there is more than on master for that slave, there will
            #be an arbiter and the wb_data_resize will be after that.
            else:
                name_list += ['wb_{dir}'+ m + '_' + s.name + '_{0}']

        for p in WB_MASTER_PORTS:
            ports += [Port('wbs_'+p.name+'_o', '{' + ', '.join(name_list).format(p.name, 'o', dir='m2s_')+'}')]
        for p in WB_SLAVE_PORTS:
            ports += [Port('wbs_'+p.name+'_i', '{' + ', '.join(name_list).format(p.name, 'i', dir='s2m_')+'}')]

        self.verilog_writer.add(Instance('wb_mux', 'wb_mux_'+m,parameters, ports))

    def _gen_arbiter(self, slave):
        parameters = [Parameter('num_masters', len(slave.masters))]
        ports = [Port('wb_clk_i', 'wb_clk_i'),
                 Port('wb_rst_i', 'wb_rst_i')]
        s = slave.name

        name_list = []
        for m in slave.masters:
            name_list += ['wb_{dir}'+ m.name + '_' + s + '_{0}']
        for p in WB_MASTER_PORTS:
            ports += [Port('wbm_'+p.name+'_i', '{' + ', '.join(name_list).format(p.name, 'i', dir='m2s_')+'}')]
        for p in WB_SLAVE_PORTS:
            ports += [Port('wbm_'+p.name+'_o', '{' + ', '.join(name_list).format(p.name, 'o', dir='s2m_')+'}')]

        #Create slave connections
        #If the slave's data width is 32, we don't need a wb_data_resize
        if int(slave.datawidth) == 32:
            input_format = 'wb_%s_%s_i'
            output_format = 'wb_%s_%s_o'
            for p in WB_MASTER_PORTS:
                ports += [Port('wbs_' + p.name + '_o', output_format % (s, p.name))]
            for p in WB_SLAVE_PORTS:
                ports += [Port('wbs_' + p.name + '_i', input_format % (s, p.name))]
        #Else, connect to the resizer
        else:
            for p in WB_MASTER_PORTS:
                ports += [Port('wbs_' + p.name + '_o', 'wb_m2s_resize_'+s+'_'+p.name)]
            for p in WB_SLAVE_PORTS:
                ports += [Port('wbs_' + p.name + '_i', 'wb_s2m_resize_'+s+'_'+p.name)]

        self.verilog_writer.add(Instance('wb_arbiter', 'wb_arbiter_'+s,parameters, ports))

    def _gen_resize(self, slave):
        parameters = [Parameter('aw', 32)]
        parameters += [Parameter('mdw', 32)]
        parameters += [Parameter('sdw', slave.datawidth)]
        parameters += [Parameter('endian', '"{}"'.format(self.endian))]
        s = slave.name

        ports =[]
        #Create master connections
        for p in WB_MASTER_PORTS:
            ports += [Port('wbm_'+p.name+'_i', 'wb_m2s_resize_'+s+'_'+p.name)]
        for p in WB_SLAVE_PORTS:
            ports += [Port('wbm_'+p.name+'_o', 'wb_s2m_resize_'+s+'_'+p.name)]

        input_format = 'wb_%s_%s_i'
        output_format = 'wb_%s_%s_o'

        #Create slave connections
        for p in WB_MASTER_PORTS:
            if p.name != "sel":
                ports.append(Port('wbs_' + p.name + '_o', output_format % (s, p.name)))
        for p in WB_SLAVE_PORTS:
            ports.append(Port('wbs_' + p.name + '_i', input_format % (s, p.name)))

        self.verilog_writer.add(Instance('wb_data_resize', 'wb_data_resize_'+s,parameters, ports))

        for p in WB_MASTER_PORTS:
            wirename = 'wb_m2s_resize_{slave}_{port}'.format(slave=s, port=p.name)
            self.verilog_writer.add(Wire(wirename, p.width))
        for p in WB_SLAVE_PORTS:
            wirename = 'wb_s2m_resize_{slave}_{port}'.format(slave=s, port=p.name)
            self.verilog_writer.add(Wire(wirename, p.width))

    def _gen_wishbone_master_port(self, master):
        template_ports = []
        for p in WB_MASTER_PORTS:
            portname = 'wb_{master}_{port}_i'.format(master=master.name, port=p.name)
            wirename = 'wb_m2s_{master}_{port}'.format(master=master.name, port=p.name)
            self.verilog_writer.add(ModulePort(portname, 'input', p.width))
            self.template_writer.add(Wire(wirename, p.width))
            template_ports += [Port(portname, wirename)]
        for p in WB_SLAVE_PORTS:
            portname = 'wb_{master}_{port}_o'.format(master=master.name, port=p.name)
            wirename = 'wb_s2m_{master}_{port}'.format(master=master.name, port=p.name)
            self.verilog_writer.add(ModulePort(portname, 'output', p.width))
            self.template_writer.add(Wire(wirename, p.width))
            template_ports += [Port(portname, wirename)]
        return template_ports

    def _gen_wishbone_port(self, slave):
        template_ports = []
        for p in WB_MASTER_PORTS:
            portname = 'wb_{slave}_{port}_o'.format(slave=slave.name, port=p.name)
            wirename = 'wb_m2s_{slave}_{port}'.format(slave=slave.name, port=p.name)
            dw = int(WB_DATA_WIDTH[p.name] * slave.datawidth) or p.width
            self.verilog_writer.add(ModulePort(portname, 'output', dw))
            self.template_writer.add(Wire(wirename, dw))
            template_ports += [Port(portname, wirename)]
        for p in WB_SLAVE_PORTS:
            portname = 'wb_{slave}_{port}_i'.format(slave=slave.name, port=p.name)
            wirename = 'wb_s2m_{slave}_{port}'.format(slave=slave.name, port=p.name)
            dw = int(WB_DATA_WIDTH[p.name] * slave.datawidth) or p.width
            self.verilog_writer.add(ModulePort(portname, 'input', dw))
            self.template_writer.add(Wire(wirename, dw))
            template_ports += [Port(portname, wirename)]
        return template_ports

    def _gen_bus_converter(self, bus, name, is_master, datawidth, datawidth_map, ports):
        converter_ports = [Port('wb_clk_i', 'wb_clk_i'),
            Port('wb_rst_i', 'wb_rst_i')]
        template_ports = []

        out_direction = 'm2s' if is_master else 's2m'

        # Wishbone side
        ms_type = 'm' if is_master else 's'
        # Foreign side
        f_ms_type = 's' if is_master else 'm'

        # Create Wishbone connections
        wb_ports = []
        wb_ports.extend([(p, 'm2s') for p in WB_MASTER_PORTS])
        wb_ports.extend([(p, 's2m') for p in WB_SLAVE_PORTS])
        for p, direction in wb_ports:
            pin_direction = 'output' if direction == out_direction else 'input'
            wirename = 'wb_{direction}_{name}_{port}'.format(
                direction=direction, name=name, port=p.name)
            converter_ports.append(
                Port('%s_%s_%s' % ('wbm' if ms_type == 'm' else 'wb', p.name,
                  pin_direction[0]), wirename))
            dw = int(WB_DATA_WIDTH[p.name] * datawidth) or p.width
            self.verilog_writer.add(Wire(wirename, dw))

        # Create foreign bus connections
        for p, direction in ports:
            pin_direction = 'output' if direction != out_direction else 'input'
            portname = '{d}_{bus}_{name}_{port}_{direction}'.format(
                d=f_ms_type, bus=bus, direction=pin_direction[0],
                name=name, port=p.name)
            wirename = '{bus}_{direction}_{name}_{port}'.format(
                bus=bus, direction=direction, name=name, port=p.name)
            converter_ports.append(
                Port('{d}_{bus}_{port}_{direction}'.format(
                    d=f_ms_type, bus=bus, direction=pin_direction[0],
                    port=p.name), portname))
            dw = int(datawidth_map[p.name] * datawidth) or p.width
            self.verilog_writer.add(
                ModulePort(portname, pin_direction, p.width))
            self.template_writer.add(Wire(wirename, dw))
            template_ports.append(Port(portname, wirename))

        return template_ports, converter_ports

    def write(self):
        file = self.output_file
        #Declare wires. Only conections between muxes and arbiters need explicit wires
        for key, value in self.masters.items():
            for slave in value.slaves:
                if len(slave.masters)>1:
                    for p in WB_MASTER_PORTS:
                        self.verilog_writer.add(Wire('wb_m2s_{0}_{1}_{2}'.format(key, slave.name, p.name), p.width))
                    for p in WB_SLAVE_PORTS:
                        self.verilog_writer.add(Wire('wb_s2m_{0}_{1}_{2}'.format(key, slave.name, p.name), p.width))

        self.verilog_writer.add(ModulePort('wb_clk_i', 'input'))
        self.verilog_writer.add(ModulePort('wb_rst_i', 'input'))

        template_ports = [Port('wb_clk_i', 'wb_clk'),
                          Port('wb_rst_i', 'wb_rst')]
        template_parameters = []

        for master in self.masters.values():
            self._gen_mux(master)
            master_template_ports = self._gen_wishbone_master_port(master)
            template_ports.extend(master_template_ports)

        for slave in self.slaves.values():
            if len(slave.masters) > 1:
                self._gen_arbiter(slave)
            if int(slave.datawidth) < 32:
                self._gen_resize(slave)
            slave_template_ports = self._gen_wishbone_port(slave)
            template_ports.extend(slave_template_ports)

        self.template_writer.add(Instance(self.name, self.name+'0',
                                          template_parameters, template_ports))

        self.verilog_writer.write(file)
        self.template_writer.write(file+'h')

        core_file = self.vlnv.split(':')[2]+'.core'
        vlnv = self.vlnv
        with open(core_file, 'w') as f:
            f.write('CAPI=2:\n')
            files = [{file     : {'file_type' : 'verilogSource'}},
                     {file+'h' : {'is_include_file' : True,
                                  'file_type' : 'verilogSource'}}
            ]
            coredata = {'name' : vlnv,
                        'targets' : {'default' : {}},
            }

            coredata['filesets'] = {'rtl' : {'files' : files}}
            coredata['targets']['default']['filesets'] = ['rtl']

            f.write(yaml.dump(coredata))