diff --git a/axi.core b/axi.core index 5d17f61b9..ba6b3e44b 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..00ff2a0b5 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 self.masters: + connstr = f"{ns}'b" + if master.slaves: + for slave in 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,