asmicon: skeleton
authorSebastien Bourdeauducq <sebastien@milkymist.org>
Wed, 14 Mar 2012 17:26:05 +0000 (18:26 +0100)
committerSebastien Bourdeauducq <sebastien@milkymist.org>
Wed, 14 Mar 2012 17:26:05 +0000 (18:26 +0100)
milkymist/asmicon/__init__.py [new file with mode: 0644]
milkymist/asmicon/bankmachine.py [new file with mode: 0644]
milkymist/asmicon/multiplexer.py [new file with mode: 0644]
milkymist/asmicon/refresher.py [new file with mode: 0644]
top.py
verilog/s6ddrphy/s6ddrphy.v

diff --git a/milkymist/asmicon/__init__.py b/milkymist/asmicon/__init__.py
new file mode 100644 (file)
index 0000000..2a78320
--- /dev/null
@@ -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 (file)
index 0000000..d4820cd
--- /dev/null
@@ -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 (file)
index 0000000..286ee78
--- /dev/null
@@ -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 (file)
index 0000000..3971f7e
--- /dev/null
@@ -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 3665607459143e2321e2e82963ece68bbd64d239..551edc53de5b79bbcc275864b0808b44f88cf1a2 100644 (file)
--- 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
index d9a463994d1500ea3ea6f5976936a92370a8d54a..5feae88b075d8a6a9d073be1961c27a52ab12a16 100644 (file)
@@ -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.