diff --git a/axi.core b/axi.core index eb38359ad..d1a859168 100644 --- a/axi.core +++ b/axi.core @@ -137,11 +137,15 @@ generators: offset (int): Base address for the slave size (int): Size of the allocated memory map for the slave + slaves (list): List of device ports that this host is + connected to. A missing or empty list means + connection to all devices. Example usage: The following config will generate an interconnect wrapper to which two AXI4 master interfaces (dma and ibus) with different id widths are connected, and connects downstream to three AXI4 slaves (rom, gpio, ram) + The ibus port is only allowed to access the rom and ram ports. soc_intercon: generator: axi_intercon_gen @@ -151,6 +155,7 @@ generators: id_width : 1 ibus: id_width : 2 + slaves: [ram, rom] slaves: ram: offset : 0 diff --git a/scripts/axi_intercon_gen.py b/scripts/axi_intercon_gen.py index af5b3a209..9e8e606d5 100644 --- a/scripts/axi_intercon_gen.py +++ b/scripts/axi_intercon_gen.py @@ -200,13 +200,12 @@ def load_dict(self, d): for key, value in d.items(): if key == 'slaves': # Handled in file loading, ignore here - continue - if key == 'id_width': + self.slaves = value + elif key == 'id_width': self.idw = value elif key == 'read_only': self.read_only = value else: - print(key) raise UnknownPropertyError( "Unknown property '%s' in master section '%s'" % ( key, self.name)) @@ -276,7 +275,7 @@ def construct_mapping(loader, node): print("Found slave " + k) self.slaves.append(Slave(k,v)) - self.output_file = config.get('output_file', 'axi_intercon.v') + self.output_file = config.get('output_file', 'axi_intercon.sv') self.atop = config.get('atop', False) def _dump(self): @@ -349,6 +348,7 @@ def write(self): MaxSlvTrans: 6, FallThrough: 1'b0, LatencyMode: axi_pkg::CUT_ALL_AX, + PipelineStages: 0, AxiIdWidthSlvPorts: AxiIdWidthMasters, AxiIdUsedSlvPorts: AxiIdUsed, UniqueIds: 1'b0, @@ -403,7 +403,18 @@ def write(self): 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 += f"\n localparam bit [{nm-1}:0][{ns-1}:0] connectivity = " + '{\n {' + connmap = [] + for master in reversed(self.masters): + connstr = f"{ns}'b" + if master.slaves: + for slave in reversed(self.slaves): + connstr += '1' if slave.name in master.slaves else '0' + else: + connstr += '1'*ns + connmap.append(connstr) + raw += "},\n {".join(connmap) + raw += "}};\n" raw += assigns(w, max_idw, self.masters, self.slaves) @@ -411,6 +422,7 @@ def write(self): parameters = [ Parameter('Cfg' , 'xbar_cfg' ), Parameter('ATOPs' , "1'b"+str(int(self.atop))), + Parameter('Connectivity' , 'connectivity'), 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' ), @@ -439,14 +451,15 @@ def write(self): _template_ports)) self.verilog_writer.write(file) - self.template_writer.write(file+'h') + template_file = file.split('.')[0]+'.vh' + self.template_writer.write(template_file) 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, + {template_file : {'is_include_file' : True, 'file_type' : 'verilogSource'}} ] coredata = {'name' : vlnv,