diff --git a/milkymist/asmicon/__init__.py b/milkymist/asmicon/__init__.py new file mode 100644 index 000000000..2a7832074 --- /dev/null +++ b/milkymist/asmicon/__init__.py @@ -0,0 +1,62 @@ +from migen.fhdl.structure import * +from migen.bus import dfi, asmibus + +from milkymist.asmicon.refresher import * +from milkymist.asmicon.bankmachine import * +from milkymist.asmicon.multiplexer import * + +class PhySettings: + def __init__(self, dfi_a, dfi_ba, dfi_d, nphases, rdphase, wrphase): + self.dfi_a = dfi_a + self.dfi_ba = dfi_ba + self.dfi_d = dfi_d + self.nphases = nphases + self.rdphase = rdphase + self.wrphase = wrphase + +class GeomSettings: + def __init__(self, row_a, col_a): + self.row_a = row_a + self.col_a = col_a + +class TimingSettings: + def __init__(self, tREFI, tRFC): + self.tREFI = tREFI + self.tRFC = tRFC + +class ASMIcon: + def __init__(self, phy_settings, geom_settings, timing_settings, time=0): + self.phy_settings = phy_settings + self.geom_settings = geom_settings + self.timing_settings = timing_settings + self.finalized = False + + self.dfi = dfi.Interface(self.phy_settings.dfi_a, + self.phy_settings.dfi_ba, + self.phy_settings.dfi_d, + self.phy_settings.nphases) + burst_length = self.phy_settings.nphases*2 + self.address_align = log2_int(burst_length) + aw = self.phy_settings.dfi_ba + self.geom_settings.row_a + self.geom_settings.col_a - self.address_align + dw = self.phy_settings.dfi_d*self.phy_settings.nphases + self.hub = asmibus.Hub(aw, dw, time) + + def finalize(self): + if self.finalized: + raise FinalizeError + self.finalized = True + self.hub.finalize() + slots = self.hub.get_slots() + self.refresher = Refresher(self.timing_settings) + self.bank_machines = [BankMachine(self.geom_settings, self.timing_settings, self.address_align, i, slots) for i in range(2**self.phy_settings.dfi_ba)] + self.multiplexer = Multiplexer(self.phy_settings, self.geom_settings, self.timing_settings, + self.bank_machines, self.refresher, + self.dfi, self.hub) + + def get_fragment(self): + if not self.finalized: + raise FinalizeError + return self.hub.get_fragment() + \ + self.refresher.get_fragment() + \ + sum([bm.get_fragment() for bm in self.bank_machines], Fragment()) + \ + self.multiplexer.get_fragment() diff --git a/milkymist/asmicon/bankmachine.py b/milkymist/asmicon/bankmachine.py new file mode 100644 index 000000000..d4820cde0 --- /dev/null +++ b/milkymist/asmicon/bankmachine.py @@ -0,0 +1,8 @@ +from migen.fhdl.structure import * + +class BankMachine: + def __init__(self, geom_settings, timing_settings, address_align, bankn, slots): + pass + + def get_fragment(self): + return Fragment() diff --git a/milkymist/asmicon/multiplexer.py b/milkymist/asmicon/multiplexer.py new file mode 100644 index 000000000..286ee78c5 --- /dev/null +++ b/milkymist/asmicon/multiplexer.py @@ -0,0 +1,8 @@ +from migen.fhdl.structure import * + +class Multiplexer: + def __init__(self, phy_settings, geom_settings, timing_settings, bank_machines, refresher, dfi, hub): + pass + + def get_fragment(self): + return Fragment() diff --git a/milkymist/asmicon/refresher.py b/milkymist/asmicon/refresher.py new file mode 100644 index 000000000..3971f7ef9 --- /dev/null +++ b/milkymist/asmicon/refresher.py @@ -0,0 +1,8 @@ +from migen.fhdl.structure import * + +class Refresher: + def __init__(self, timing_settings): + pass + + def get_fragment(self): + return Fragment() diff --git a/top.py b/top.py index 366560745..551edc53d 100644 --- a/top.py +++ b/top.py @@ -1,10 +1,11 @@ from fractions import Fraction +from math import ceil from migen.fhdl.structure import * from migen.fhdl import verilog, autofragment -from migen.bus import wishbone, asmibus, wishbone2asmi, csr, wishbone2csr, dfi +from migen.bus import wishbone, wishbone2asmi, csr, wishbone2csr, dfi -from milkymist import m1crg, lm32, norflash, uart, sram, s6ddrphy, dfii +from milkymist import m1crg, lm32, norflash, uart, sram, s6ddrphy, dfii, asmicon import constraints MHz = 1000000 @@ -12,9 +13,28 @@ clk_freq = (83 + Fraction(1, 3))*MHz sram_size = 4096 # in bytes l2_size = 8192 # in bytes -dfi_a = 13 -dfi_ba = 2 -dfi_d = 64 +clk_period_ns = 1000000000/clk_freq +def ns(t, margin=False): + if margin: + t += clk_period_ns/2 + return ceil(t/clk_period_ns) + +sdram_phy = asmicon.PhySettings( + dfi_a=13, + dfi_ba=2, + dfi_d=64, + nphases=2, + rdphase=0, + wrphase=1 +) +sdram_geom = asmicon.GeomSettings( + row_a=13, + col_a=10 +) +sdram_timing = asmicon.TimingSettings( + tREFI=ns(7800), + tRFC=ns(70) +) def ddrphy_clocking(crg, phy): names = [ @@ -31,16 +51,17 @@ def get(): # # ASMI # - asmihub0 = asmibus.Hub(23, 128, 12) # TODO: get hub from memory controller - asmiport_wb = asmihub0.get_port() - asmihub0.finalize() + asmicon0 = asmicon.ASMIcon(sdram_phy, sdram_geom, sdram_timing, 8) + asmiport_wb = asmicon0.hub.get_port() + asmicon0.finalize() # # DFI # - ddrphy0 = s6ddrphy.S6DDRPHY(dfi_a, dfi_ba, dfi_d) - dfii0 = dfii.DFIInjector(1, dfi_a, dfi_ba, dfi_d, 2) + ddrphy0 = s6ddrphy.S6DDRPHY(sdram_phy.dfi_a, sdram_phy.dfi_ba, sdram_phy.dfi_d) + dfii0 = dfii.DFIInjector(1, sdram_phy.dfi_a, sdram_phy.dfi_ba, sdram_phy.dfi_d, sdram_phy.nphases) dficon0 = dfi.Interconnect(dfii0.master, ddrphy0.dfi) + dficon1 = dfi.Interconnect(asmicon0.dfi, dfii0.slave) # # WISHBONE diff --git a/verilog/s6ddrphy/s6ddrphy.v b/verilog/s6ddrphy/s6ddrphy.v index d9a463994..5feae88b0 100644 --- a/verilog/s6ddrphy/s6ddrphy.v +++ b/verilog/s6ddrphy/s6ddrphy.v @@ -1,7 +1,6 @@ /* * 1:2 frequency-ratio DDR PHY for Spartan-6 * - ************* DATAPATH SIGNALS *********** * Assert dfi_wrdata_en and present the data * on dfi_wrdata_mask/dfi_wrdata in the same * cycle as the write command.