From: Luke Kenneth Casson Leighton Date: Mon, 28 Mar 2022 14:12:25 +0000 (+0100) Subject: work through the CSns to give the appearance of having a larger hyperram X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=9d99f237c42bf503a89f2f7bbf08a33dee5ae014;p=lambdasoc.git work through the CSns to give the appearance of having a larger hyperram memory when in fact, when one IC runs out of address space the next one is activated. this is not particularly fast but it is simple and functional --- diff --git a/lambdasoc/periph/hyperram.py b/lambdasoc/periph/hyperram.py index c992a29..a5b536e 100644 --- a/lambdasoc/periph/hyperram.py +++ b/lambdasoc/periph/hyperram.py @@ -16,19 +16,31 @@ Usage example when wiring up an external pmod. use platform.add_extension to first define the pins: from nmigen.resources.memory import HyperRAMResources - hyperram_ios = HyperRAMResources(cs="B1", + hyperram_ios = HyperRAMResources(cs="B1", # or cs="C0 C1 C2 C3" for Quad dq="D0 D1 D2 D3 D4 D7 D6 D7", rwds="B2", rst_n="B3", ck_p="B4", attrs=Attrs(IOSTANDARD="LVCMOS33")) self.platform.add_resources(hyperram_ios) io = self.platform.request("hyperram") +and then declare the instance using those pins: + + hyperram = HyperRAM(io=io, phy_kls=HyperRAMPHY, + latency=7) # Winbond W956D8MBYA + # latency=6 for Cypress S27KL0641DABHI020 + this trick will work with the 1-IC HyperRAM PMOD by Piotr Esden, sold by 1bitsquared. however for the *four* IC HyperRAM PMOD, *four* cs_n pins -are needed (and is not currently supported). -on the TODO list for this module: interleave multiple HyperRAM -cs_n's to give striped (like RAID) memory accesses behind one single -Wishbone interface. +are needed. These are then used to select, in turn, each IC, sequentially: + * Access to 0x00000-0xfffff will activate CS0n, + * Access to 0x100000-0x1fffff will activate CS1n, + * Access to 0x200000-0x2fffff will activate CS2n, + * Access to 0x300000-0x3fffff will activate CS3n + +TODO: interleave multiple HyperRAM cs_n's to give striped (like RAID) +memory accesses behind one single Wishbone interface. +TODO: investigate whether HyperBUS can do CSn-striping in hardware +(it should do, but this will require configuration registers to be written) """ @@ -150,22 +162,27 @@ class HyperRAM(Peripheral, Elaboratable): addr_width=23, # 8 GBytes, per IC bus=None, features=frozenset()): super().__init__() + self.n_cs = n_cs = len(io.cs_n) + self.cs_bits = cs_bits = n_cs.bit_length()-1 self.io = io self.phy = phy_kls(io) self.latency = latency - self.bus = wishbone.Interface(addr_width=21, + # per IC, times n_cs + addr_width += cs_bits + self.bus = wishbone.Interface(addr_width=addr_width-2, data_width=32, granularity=8, features=features) - mmap = MemoryMap(addr_width=23, data_width=8) - mmap.add_resource(object(), name="hyperram", size=2**23) + self.size = 2**addr_width + mmap = MemoryMap(addr_width=addr_width, data_width=8) + mmap.add_resource(object(), name="hyperram", size=self.size) self.bus.memory_map = mmap - self.size = 2**23 # # # def elaborate(self, platform): m = Module() m.submodules.phy = self.phy bus = self.bus + cs_bits = self.cs_bits comb, sync = m.d.comb, m.d.sync ck = self.phy.ck @@ -185,7 +202,21 @@ class HyperRAM(Peripheral, Elaboratable): rwds_o = self.phy.rwds_o rwds_oe = self.phy.rwds_oe + # chip&address selection: use the MSBs of the address for chip-select + # (bus_adr_hi) by doing "1<