From 9288feaa22d982d7caaf4277c4b25af8d2f562cb Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Thu, 10 Feb 2022 11:59:39 +0000 Subject: [PATCH] add gram soc example and license and contributors --- CONTRIBUTORS | 22 +++++++++ LICENSE | 31 +++++++++++++ examples/soc.py | 115 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 168 insertions(+) create mode 100644 CONTRIBUTORS create mode 100644 LICENSE create mode 100644 examples/soc.py diff --git a/CONTRIBUTORS b/CONTRIBUTORS new file mode 100644 index 0000000..67fe9ca --- /dev/null +++ b/CONTRIBUTORS @@ -0,0 +1,22 @@ +gram is based off the LiteDRAM project, a DRAM controller for LiteX SoCs. + +If you think you should be in this list and don't find yourself, please send a pull-request +and we'll fix it! + +Contributors: +Copyright (c) 2019 Ambroz Bizjak +Copyright (c) 2019 Antony Pavlov +Copyright (c) 2018 bunnie +Copyright (c) 2018-2019 David Shah +Copyright (c) 2020 Drew Fustini +Copyright (c) 2019 Ewout ter Hoeven +Copyright (c) 2018 Felix Held +Copyright (c) 2015-2020 Florent Kermarrec +Copyright (c) 2019 Gabriel L. Somlo +Copyright (c) 2018 John Sully +Copyright (c) 2019 Antmicro +Copyright (c) 2020 Michael Welling +Copyright (c) 2019 Pierre-Olivier Vauboin +Copyright (c) 2015 Sebastien Bourdeauducq +Copyright (c) 2016-2016 Tim 'mithro' Ansell +Copyright (c) 2020 LambdaConcept diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..991cbcf --- /dev/null +++ b/LICENSE @@ -0,0 +1,31 @@ +Unless otherwise noted, Gram is Copyright 2020 / LambdaConcept + +Initial development is based on MiSoC's LASMICON / Copyright 2007-2016 / M-Labs + LiteDRAM / Copyright 2012-2018 / EnjoyDigital + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +Other authors retain ownership of their contributions. If a submission can +reasonably be considered independently copyrightable, it's yours and we +encourage you to claim it with appropriate copyright notices. This submission +then falls under the "otherwise noted" category. All submissions are strongly +encouraged to use the two-clause BSD license reproduced above. diff --git a/examples/soc.py b/examples/soc.py new file mode 100644 index 0000000..33a0561 --- /dev/null +++ b/examples/soc.py @@ -0,0 +1,115 @@ +# This file is Copyright (c) 2020 LambdaConcept + +from nmigen import * +from nmigen.lib.cdc import ResetSynchronizer +from nmigen_soc import wishbone, memory +from nmigen_stdio.serial import AsyncSerial + +from lambdasoc.cpu.minerva import MinervaCPU +from lambdasoc.periph.intc import GenericInterruptController +from lambdasoc.periph.serial import AsyncSerialPeripheral +from lambdasoc.periph.sram import SRAMPeripheral +from lambdasoc.periph.timer import TimerPeripheral +from lambdasoc.periph import Peripheral +from lambdasoc.soc.base import SoC + +from gram.core import gramCore +from gram.phy.ecp5ddrphy import ECP5DDRPHY +from gram.modules import MT41K256M16 +from gram.frontend.wishbone import gramWishbone + +from nmigen_boards.versa_ecp5 import VersaECP5Platform +from uartbridge import UARTBridge +from crg import * + +class DDR3SoC(SoC, Elaboratable): + def __init__(self, *, + uart_pins, ddr_pins, + ddrphy_addr, dramcore_addr, + ddr_addr): + self._arbiter = wishbone.Arbiter(addr_width=30, data_width=32, granularity=8, + features={"cti", "bte"}) + self._decoder = wishbone.Decoder(addr_width=30, data_width=32, granularity=8, + features={"cti", "bte"}) + + freq = 100e6 + + self.crg = ECPIX5CRG() + + self.cpu = MinervaCPU(reset_address=0) + self._arbiter.add(self.cpu.ibus) + self._arbiter.add(self.cpu.dbus) + self.intc = GenericInterruptController(width=len(self.cpu.ip)) + + self.rom = SRAMPeripheral(size=4096, writable=False) + with open("firmware/main.bin", "rb") as f: + words = iter(lambda: f.read(self.cpu.data_width // 8), b'') + bios = [int.from_bytes(w, self.cpu.byteorder) for w in words] + self.rom.init = bios + self._decoder.add(self.rom.bus, addr=0) + + self.ram = SRAMPeripheral(size=4096) + self._decoder.add(self.ram.bus, addr=0x1000) + + self.uart_phy = AsyncSerial(data_bits=8, + divisor=int(freq//115200), + pins=uart_pins) + self.uart = AsyncSerialPeripheral(core=self.uart_phy) + self._decoder.add(self.uart.bus, addr=0x2000) + + + self.ddrphy = DomainRenamer("dramsync")(ECP5DDRPHY(ddr_pins, + sys_clk_freq=100e6)) + self._decoder.add(self.ddrphy.bus, addr=ddrphy_addr) + + ddrmodule = MT41K256M16(freq, "1:2") + + self.dramcore = DomainRenamer("dramsync")(gramCore( + phy=self.ddrphy, + geom_settings=ddrmodule.geom_settings, + timing_settings=ddrmodule.timing_settings, + clk_freq=freq)) + self._decoder.add(self.dramcore.bus, addr=dramcore_addr) + + self.drambone = DomainRenamer("dramsync")(gramWishbone(self.dramcore)) + self._decoder.add(self.drambone.bus, addr=ddr_addr) + + self.memory_map = self._decoder.bus.memory_map + + self.clk_freq = freq + + def elaborate(self, platform): + m = Module() + + m.submodules.sysclk = self.crg + + m.submodules.rom = self.rom + m.submodules.ram = self.ram + m.submodules.uart = self.uart + m.submodules.intc = self.intc + m.submodules.cpu = self.cpu + m.submodules.arbiter = self._arbiter + m.submodules.decoder = self._decoder + m.submodules.ddrphy = self.ddrphy + m.submodules.dramcore = self.dramcore + m.submodules.drambone = self.drambone + + m.d.comb += [ + self._arbiter.bus.connect(self._decoder.bus), + self.cpu.ip.eq(self.intc.ip), + ] + + return m + + +if __name__ == "__main__": + platform = VersaECP5Platform() + + ddr_pins = platform.request("ddr3", 0, dir={"dq":"-", "dqs":"-"}, + xdr={"clk":4, "a":4, "ba":4, "clk_en":4, "odt":4, "ras":4, "cas":4, "we":4}) + uart_pins = platform.request("uart", 0) + + soc = DDR3SoC(ddrphy_addr=0x00008000, dramcore_addr=0x00009000, + ddr_addr=0x10000000, ddr_pins=ddr_pins, uart_pins=uart_pins) + + platform.build(soc, do_program=True) -- 2.30.2