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,
diff --git a/src/axi_dw_upsizer.sv b/src/axi_dw_upsizer.sv
index 9908b7860..6e96e98f4 100644
--- a/src/axi_dw_upsizer.sv
+++ b/src/axi_dw_upsizer.sv
@@ -359,7 +359,7 @@ module axi_dw_upsizer #(
       // Initialize r_data
       r_data = '0;
 
-      case (r_state_q)
+      unique case (r_state_q)
         R_IDLE : begin
           // Reset channels
           r_req_d.ar = '0;
@@ -381,7 +381,7 @@ module axi_dw_upsizer #(
               r_req_d.burst_len    = slv_req_i.ar.len ;
               r_req_d.orig_ar_size = slv_req_i.ar.size;
 
-              case (r_req_d.ar.burst)
+              unique case (r_req_d.ar.burst)
                 axi_pkg::BURST_INCR: begin
                   // Modifiable transaction
                   if (modifiable(r_req_d.ar.cache)) begin
@@ -413,6 +413,8 @@ module axi_dw_upsizer #(
                   if (r_req_d.ar.len == '0)
                     r_req_d.ar_throw_error = 1'b0;
                 end
+
+                default: ;
               endcase
             end
           end
@@ -439,7 +441,7 @@ module axi_dw_upsizer #(
           // Default state
           r_state_d = R_PASSTHROUGH;
 
-          case (r_req_d.ar.burst)
+          unique case (r_req_d.ar.burst)
             axi_pkg::BURST_INCR: begin
               // Modifiable transaction
               if (modifiable(r_req_d.ar.cache)) begin
@@ -471,6 +473,8 @@ module axi_dw_upsizer #(
               if (r_req_d.ar.len == '0)
                 r_req_d.ar_throw_error = 1'b0;
             end
+
+            default: ;
           endcase
         end
 
@@ -499,22 +503,25 @@ module axi_dw_upsizer #(
               if (slv_r_ready_tran[t]) begin
                 r_req_d.burst_len = r_req_q.burst_len - 1;
 
-                case (r_req_q.ar.burst)
+                unique case (r_req_q.ar.burst)
                   axi_pkg::BURST_INCR: begin
                     r_req_d.ar.addr = aligned_addr(r_req_q.ar.addr, r_req_q.orig_ar_size) + (1 << r_req_q.orig_ar_size);
                   end
                   axi_pkg::BURST_FIXED: begin
                     r_req_d.ar.addr = r_req_q.ar.addr;
                   end
+                  default: ;
                 endcase
 
-                case (r_state_q)
+                unique case (r_state_q)
                   R_PASSTHROUGH:
                     mst_r_ready_tran[t] = 1'b1;
 
                   R_INCR_UPSIZE:
                     if (r_req_q.burst_len == 0 || (aligned_addr(r_req_d.ar.addr, AxiMstPortMaxSize) != aligned_addr(r_req_q.ar.addr, AxiMstPortMaxSize)))
                       mst_r_ready_tran[t] = 1'b1;
+
+                  default: ;
                 endcase
 
                 if (r_req_q.burst_len == '0)
@@ -522,6 +529,8 @@ module axi_dw_upsizer #(
               end
             end
         end
+
+        default: ;
       endcase
     end
 
@@ -585,7 +594,7 @@ module axi_dw_upsizer #(
       w_req_d.aw_throw_error = 1'b0;
     end
 
-    case (w_state_q)
+    unique case (w_state_q)
       W_PASSTHROUGH, W_INCR_UPSIZE: begin
         // Got a grant on the W channel
         if (mst_req.w_valid && mst_resp.w_ready) begin
@@ -617,16 +626,17 @@ module axi_dw_upsizer #(
             w_req_d.w.last    = (w_req_q.burst_len == 0);
             w_req_d.w.user    = slv_req_i.w.user        ;
 
-            case (w_req_q.aw.burst)
+            unique case (w_req_q.aw.burst)
               axi_pkg::BURST_INCR: begin
                 w_req_d.aw.addr = aligned_addr(w_req_q.aw.addr, w_req_q.orig_aw_size) + (1 << w_req_q.orig_aw_size);
               end
               axi_pkg::BURST_FIXED: begin
                 w_req_d.aw.addr = w_req_q.aw.addr;
               end
+              default: ;
             endcase
 
-            case (w_state_q)
+            unique case (w_state_q)
               W_PASSTHROUGH:
                 // Forward data as soon as we can
                 w_req_d.w_valid = 1'b1;
@@ -635,6 +645,7 @@ module axi_dw_upsizer #(
                 // Forward when the burst is finished, or after filling up a word
                 if (w_req_q.burst_len == 0 || (aligned_addr(w_req_d.aw.addr, AxiMstPortMaxSize) != aligned_addr(w_req_q.aw.addr, AxiMstPortMaxSize)))
                   w_req_d.w_valid = 1'b1;
+              default: ;
             endcase
           end
         end
@@ -645,6 +656,7 @@ module axi_dw_upsizer #(
             w_state_d          = W_IDLE;
           end
       end
+      default: ;
     endcase
 
     // Can start a new request as soon as w_state_d is W_IDLE
@@ -675,7 +687,7 @@ module axi_dw_upsizer #(
         w_req_d.burst_len    = slv_req_i.aw.len ;
         w_req_d.orig_aw_size = slv_req_i.aw.size;
 
-        case (slv_req_i.aw.burst)
+        unique case (slv_req_i.aw.burst)
           axi_pkg::BURST_INCR: begin
             // Modifiable transaction
             if (modifiable(slv_req_i.aw.cache))
@@ -707,6 +719,8 @@ module axi_dw_upsizer #(
             if (slv_req_i.aw.len == '0)
               w_req_d.aw_throw_error = 1'b0;
           end
+
+          default: ;
         endcase
       end
     end
diff --git a/src/axi_id_serialize.sv b/src/axi_id_serialize.sv
index 9a787dd25..671b38ad1 100644
--- a/src/axi_id_serialize.sv
+++ b/src/axi_id_serialize.sv
@@ -66,7 +66,7 @@ module axi_id_serialize #(
   /// Number of Entries in the explicit ID map (default: None)
   parameter int unsigned IdMapNumEntries = 32'd0,
   /// Explicit ID map; index [0] in each entry is the input ID to match, index [1] the output ID.
-  parameter int unsigned IdMap [IdMapNumEntries-1:0][0:1] = '{default: {32'b0, 32'b0}}
+  parameter int unsigned IdMap [axi_pkg::iomsb(IdMapNumEntries):0][0:1] = '{default: {32'b0, 32'b0}}
 ) (
   /// Rising-edge clock of both ports
   input  logic      clk_i,
diff --git a/src/axi_pkg.sv b/src/axi_pkg.sv
index 4102be0e8..6e6450bbd 100644
--- a/src/axi_pkg.sv
+++ b/src/axi_pkg.sv
@@ -532,4 +532,9 @@ package axi_pkg;
     logic [31:0] end_addr;
   } xbar_rule_32_t;
 
+  // Return either the argument minus 1 or 0 if 0; useful for IO vector width declaration
+  function automatic integer unsigned iomsb (input integer unsigned width);
+      return (width != 32'd0) ? unsigned'(width-1) : 32'd0;
+  endfunction
+
 endpackage