+So after running the autogenerator again, to confirm that this has
+generated the correct code, we examine several files, starting with
+fast\+memory\_map.bsv:
+
+ /*====== Fast peripherals Memory Map ======= */
+ `define SDR0_0_Base 'h50000000
+ `define SDR0_0_End 'h5FFFFFFF // 4194304 32-bit regs
+ `define SDR0_1_Base 'h60000000
+ `define SDR0_1_End 'h600002FF // 12 32-bit regs
+
+This looks slightly awkward (and in need of an external specification
+section for addresses) but is fine: the range is 1GB for the main
+map and covers 12 32-bit registers for the SDR Config map.
+Next we note the slave numbering:
+
+ typedef 0 SDR0_0__fastslave_num;
+ typedef 1 SDR0_1__fastslave_num;
+ typedef 2 FB0_fastslave_num;
+ typedef 3 LCD0_fastslave_num;
+ typedef 3 LastGen_fastslave_num;
+ typedef TAdd#(LastGen_fastslave_num,1) Sdram_slave_num;
+ typedef TAdd#(Sdram_slave_num ,`ifdef SDRAM 1 `else 0 `endif )
+ Sdram_cfg_slave_num;
+
+Again this looks reasonable and we may subsequently (carefully! noting
+the use of the TAdd# chain!) remove the #define for Sdram\_cfg\_slave\_num.
+The next phase is to examine the fn\_addr\_to\_fastslave\_num function,
+where we note that there were *two* hand-created sections previously,
+now joined by two *auto-generated* sections:
+
+ function Tuple2 #(Bool, Bit#(TLog#(Num_Fast_Slaves)))
+ fn_addr_to_fastslave_num (Bit#(`PADDR) addr);
+
+ if(addr>=`SDRAMMemBase && addr<=`SDRAMMemEnd)
+ return tuple2(True,fromInteger(valueOf(Sdram_slave_num))); <--
+ else if(addr>=`DebugBase && addr<=`DebugEnd)
+ return tuple2(True,fromInteger(valueOf(Debug_slave_num))); <--
+ `ifdef SDRAM
+ else if(addr>=`SDRAMCfgBase && addr<=`SDRAMCfgEnd )
+ return tuple2(True,fromInteger(valueOf(Sdram_cfg_slave_num)));
+ `endif
+
+ ...
+ ...
+ if(addr>=`SDR0_0_Base && addr<=`SDR0_0_End) <--
+ return tuple2(True,fromInteger(valueOf(SDR0_0__fastslave_num)));
+ else
+ if(addr>=`SDR0_1_Base && addr<=`SDR0_1_End) <--
+ return tuple2(True,fromInteger(valueOf(SDR0_1__fastslave_num)));
+ else
+ if(addr>=`FB0Base && addr<=`FB0End)
+
+Now, here is where, in a slightly unusual unique set of circumstances, we
+cannot just remove all instances of this address / typedef from the template
+code. Looking in the shakti-core repository's src/lib/MemoryMap.bsv file,
+the SDRAMMemBase macro is utilise in the is\_IO\_Addr function. So as a
+really bad hack, which will need to be properly resolved, whilst the
+hand-generated sections from fast\_tuple2\_template.bsv are removed,
+and the corresponding (now redundant) defines in src/core/core\_parameters.bsv
+are commented out, some temporary typedefs to deal with the name change are
+also added:
+
+ `define SDRAMMemBase SDR0_0_Base
+ `define SDRAMMemEnd SDR0_0_End
+
+This needs to be addressed (pun intended) including being able to specify
+the name(s) of the configuration parameters, as well as specifying which
+memory map range they must be added to.
+
+Now however finally, after carefully comparing the hard-coded fabric
+connections to what was formerly named sdram, we may remove the mkConnections
+that drop sdram.axi4\_slave\_sdram and its associated cntrl reg from
+the soc\_template.bsv file.
+
+## Connecting up the pins
+
+We are still not done! It is however worth pointing out that if this peripheral
+were not wired into the pinmux, we would in fact be finished. However there
+is a task that (previously having been left to outside tools) now needs to
+be specified, which is to connect the sdram's pins, declared in this
+instance in Ifc\_sdram\_out, and the PeripheralSideSDR instance that
+was kindly / strategically / thoughtfully / absolutely-necessarily exported
+from slow\_peripherals for exactly this purpose.
+
+Recall earlier that we took a cut/paste copy of the flexbus.py code. If
+we now examine socgen.bsv we find that it contains connections to pins
+that match the FlexBus specification, not SDRAM. So, returning to the
+declaration of the Ifc\_sdram\_out interface, we first identify the
+single-bit output-only pins, and add a mapping table between them:
+
+ class sdram(PBase):
+
+ def pinname_out(self, pname):
+ return {'sdrwen': 'ifc_sdram_out.osdr_we_n',
+ 'sdrcsn0': 'ifc_sdram_out.osdr_cs_n',
+ 'sdrcke': 'ifc_sdram_out.osdr_cke',
+ 'sdrrasn': 'ifc_sdram_out.osdr_ras_n',
+ 'sdrcasn': 'ifc_sdram_out.osdr_cas_n',
+ }.get(pname, '')
+
+Re-running the tool confirms that the relevant mkConnections are generated:
+
+ //sdr {'action': True, 'type': 'out', 'name': 'sdrcke'}
+ mkConnection(slow_peripherals.sdr0.sdrcke,
+ sdr0_sdrcke_sync.get);
+ mkConnection(sdr0_sdrcke_sync.put,
+ sdr0.ifc_sdram_out.osdr_cke);
+ //sdr {'action': True, 'type': 'out', 'name': 'sdrrasn'}
+ mkConnection(slow_peripherals.sdr0.sdrrasn,
+ sdr0_sdrrasn_sync.get);
+ mkConnection(sdr0_sdrrasn_sync.put,
+ sdr0.ifc_sdram_out.osdr_ras_n);
+
+Next, the multi-value entries are tackled (both in and out). At present
+the code is messy, as it does not automatically detect the multiple numerical
+declarations, nor that the entries are sometimes inout (in, out, outen),
+so it is *presently* done by hand:
+
+ class sdram(PBase):