From f19bdf5986b28acb1b714a438406914a2293dfef Mon Sep 17 00:00:00 2001 From: Jean THOMAS Date: Tue, 9 Jun 2020 11:45:17 +0200 Subject: [PATCH] Rework LiteDRAM wishbone frontend (wip) --- examples/ecpix5.py | 11 ++-- gram/frontend/wishbone.py | 104 +++++++++++++------------------------- 2 files changed, 44 insertions(+), 71 deletions(-) diff --git a/examples/ecpix5.py b/examples/ecpix5.py index 3848436..6fe9ae9 100644 --- a/examples/ecpix5.py +++ b/examples/ecpix5.py @@ -14,6 +14,7 @@ from lambdasoc.soc.cpu import CPUSoC from gram.core import gramCore from gram.phy.ecp5ddrphy import ECP5DDRPHY from gram.modules import MT41K256M16 +from gram.frontend.wishbone import gramWishbone from customecpix5 import ECPIX5Platform @@ -113,7 +114,8 @@ class DDR3SoC(CPUSoC, Elaboratable): ram_addr, ram_size, uart_addr, uart_divisor, uart_pins, timer_addr, timer_width, - ddrphy_addr, dramcore_addr): + 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, @@ -154,7 +156,8 @@ class DDR3SoC(CPUSoC, Elaboratable): clk_freq = clk_freq) self._decoder.add(self.dramcore.bus, addr=dramcore_addr) - self.dramport = self.dramcore.crossbar.get_port() + self.drambone = gramWishbone(self.dramcore) + self._decoder.add(self.drambone.bus, addr=ddr_addr) self.memory_map = self._decoder.bus.memory_map @@ -174,6 +177,7 @@ class DDR3SoC(CPUSoC, Elaboratable): m.submodules.intc = self.intc m.submodules.ddrphy = self.ddrphy m.submodules.dramcore = self.dramcore + m.submodules.drambone = self.drambone m.submodules.sysclk = SysClocker() @@ -198,7 +202,8 @@ if __name__ == "__main__": ram_addr=0x00004000, ram_size=0x1000, uart_addr=0x00005000, uart_divisor=uart_divisor, uart_pins=uart_pins, timer_addr=0x00006000, timer_width=32, - ddrphy_addr=0x00008000, dramcore_addr=0x00009000 + ddrphy_addr=0x00008000, dramcore_addr=0x00009000, + ddr_addr=0x10000000 ) soc.build(do_build=True, do_init=True) diff --git a/gram/frontend/wishbone.py b/gram/frontend/wishbone.py index f3e6ea3..25154b3 100644 --- a/gram/frontend/wishbone.py +++ b/gram/frontend/wishbone.py @@ -1,81 +1,49 @@ -# This file is Copyright (c) 2016-2020 Florent Kermarrec +# This file is Copyright (c) 2020 LambdaConcept # License: BSD -"""Wishbone frontend for LiteDRAM""" - -from math import log2 - from nmigen import * +from nmigen.utils import log2_int -import gram.stream as stream +from nmigen_soc import wishbone +from nmigen_soc.memory import MemoryMap +from lambdasoc.periph import Peripheral +class gramWishbone(Peripheral, Elaboratable): + def __init__(self, core): + super().__init__() -# LiteDRAMWishbone2Native -------------------------------------------------------------------------- + self._port = core.crossbar.get_port() -class LiteDRAMWishbone2Native(Module): - def __init__(self, wishbone, port, base_address=0x00000000): - wishbone_data_width = len(wishbone.dat_w) - port_data_width = 2**int(log2(len(port.wdata.data))) # Round to lowest power 2 - assert wishbone_data_width >= port_data_width + dram_size = core.size//4 + dram_addr_width = log2_int(dram_size) + granularity = 8 - # # # + self.bus = wishbone.Interface(addr_width=dram_addr_width, + data_width=32, granularity=granularity) - adr_offset = base_address >> log2_int(port.data_width//8) + map = MemoryMap(addr_width=dram_addr_width, data_width=granularity) + map.add_resource(self, size=dram_size) + self.bus.memory_map = map - # Write Datapath --------------------------------------------------------------------------- - wdata_converter = stream.StrideConverter( - [("data", wishbone_data_width), ("we", wishbone_data_width//8)], - [("data", port_data_width), ("we", port_data_width//8)], - ) - self.submodules += wdata_converter - self.comb += [ - wdata_converter.sink.valid.eq(wishbone.cyc & wishbone.stb & wishbone.we), - wdata_converter.sink.data.eq(wishbone.dat_w), - wdata_converter.sink.we.eq(wishbone.sel), - wdata_converter.source.connect(port.wdata) - ] + def elaborate(self, platform): + m = Module() - # Read Datapath ---------------------------------------------------------------------------- - rdata_converter = stream.StrideConverter( - [("data", port_data_width)], - [("data", wishbone_data_width)], - ) - self.submodules += rdata_converter - self.comb += [ - port.rdata.connect(rdata_converter.sink), - rdata_converter.source.ready.eq(1), - wishbone.dat_r.eq(rdata_converter.source.data), - ] - - # Control ---------------------------------------------------------------------------------- ratio = wishbone_data_width//port_data_width count = Signal(max=max(ratio, 2)) - self.submodules.fsm = fsm = FSM(reset_state="CMD") - fsm.act("CMD", - port.cmd.valid.eq(wishbone.cyc & wishbone.stb), - port.cmd.we.eq(wishbone.we), - port.cmd.addr.eq(wishbone.adr*ratio + count - adr_offset), - If(port.cmd.valid & port.cmd.ready, - NextValue(count, count + 1), - If(count == (ratio - 1), - NextValue(count, 0), - If(wishbone.we, - NextState("WAIT-WRITE") - ).Else( - NextState("WAIT-READ") - ) - ) - ) - ) - fsm.act("WAIT-WRITE", - If(wdata_converter.sink.ready, - wishbone.ack.eq(1), - NextState("CMD") - ) - ) - fsm.act("WAIT-READ", - If(rdata_converter.source.valid, - wishbone.ack.eq(1), - NextState("CMD") - ) - ) + with m.FSM(): + with m.State("Send-Cmd"): + m.d.comb += [ + port.cmd.valid.eq(self.bus.cyc & self.bus.stb), + port.cmd.we.eq(self.bus.we), + port.cmd.addr.eq(self.bus.adr*ratio + count - adr_offset), + ] + with m.If(port.cmd.valid & port.cmd.ready): + + + # with m.State("Write"): + # ... + + # with m.State("Read"): + # ... + + return m -- 2.30.2