Skip to content

Commit

Permalink
Connect DDR PHY
Browse files Browse the repository at this point in the history
Doesn't do much for the moment, just to check synthesis/P&R.
  • Loading branch information
Sebastien Bourdeauducq committed Feb 17, 2012
1 parent cdd58e0 commit 5d1dad5
Show file tree
Hide file tree
Showing 5 changed files with 163 additions and 11 deletions.
9 changes: 7 additions & 2 deletions build.py
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -4,13 +4,16 @@
# list Verilog sources before changing directory # list Verilog sources before changing directory
verilog_sources = [] verilog_sources = []
def add_core_dir(d): def add_core_dir(d):
for root, subFolders, files in os.walk(os.path.join("verilog", d)): root = os.path.join("verilog", d)
for f in files: files = os.listdir(root)
for f in files:
if f[-2:] == ".v":
verilog_sources.append(os.path.join(root, f)) verilog_sources.append(os.path.join(root, f))
def add_core_files(d, files): def add_core_files(d, files):
for f in files: for f in files:
verilog_sources.append(os.path.join("verilog", d, f)) verilog_sources.append(os.path.join("verilog", d, f))
add_core_dir("m1crg") add_core_dir("m1crg")
add_core_dir("s6ddrphy")
add_core_files("lm32", ["lm32_cpu.v", "lm32_instruction_unit.v", "lm32_decoder.v", add_core_files("lm32", ["lm32_cpu.v", "lm32_instruction_unit.v", "lm32_decoder.v",
"lm32_load_store_unit.v", "lm32_adder.v", "lm32_addsub.v", "lm32_logic_op.v", "lm32_load_store_unit.v", "lm32_adder.v", "lm32_addsub.v", "lm32_logic_op.v",
"lm32_shifter.v", "lm32_multiplier_spartan6.v", "lm32_mc_arithmetic.v", "lm32_shifter.v", "lm32_multiplier_spartan6.v", "lm32_mc_arithmetic.v",
Expand All @@ -31,7 +34,9 @@ def str2file(filename, contents):
str2file("soc.v", src_verilog) str2file("soc.v", src_verilog)
str2file("soc.ucf", src_ucf) str2file("soc.ucf", src_ucf)
verilog_sources.append("build/soc.v") verilog_sources.append("build/soc.v")

#raise SystemExit #raise SystemExit

# xst # xst
xst_prj = "" xst_prj = ""
for s in verilog_sources: for s in verilog_sources:
Expand Down
36 changes: 32 additions & 4 deletions constraints.py
Original file line number Original file line Diff line number Diff line change
@@ -1,8 +1,9 @@
def get(ns, crg0, norflash0, uart0): def get(ns, crg0, norflash0, uart0, ddrphy0):
constraints = [] constraints = []
def add(signal, pin, vec=-1, iostandard="LVCMOS33", extra=""): def add(signal, pin, vec=-1, iostandard="LVCMOS33", extra=""):
constraints.append((ns.get_name(signal), vec, pin, iostandard, extra)) constraints.append((ns.get_name(signal), vec, pin, iostandard, extra))
def add_vec(signal, pins, iostandard="LVCMOS33", extra=""): def add_vec(signal, pins, iostandard="LVCMOS33", extra=""):
assert(signal.bv.width == len(pins))
i = 0 i = 0
for p in pins: for p in pins:
add(signal, p, i, iostandard, extra) add(signal, p, i, iostandard, extra)
Expand All @@ -12,7 +13,7 @@ def add_vec(signal, pins, iostandard="LVCMOS33", extra=""):
add(crg0.ac97_rst_n, "D6") add(crg0.ac97_rst_n, "D6")
add(crg0.videoin_rst_n, "W17") add(crg0.videoin_rst_n, "W17")
add(crg0.flash_rst_n, "P22", extra="SLEW = FAST | DRIVE = 8") add(crg0.flash_rst_n, "P22", extra="SLEW = FAST | DRIVE = 8")
add(crg0.rd_clk_lb, "K5") add(crg0.rd_clk_lb, "K5", extra="IOSTANDARD = SSTL2_I")
add(crg0.trigger_reset, "AA4") add(crg0.trigger_reset, "AA4")


add_vec(norflash0.adr, ["L22", "L20", "K22", "K21", "J19", "H20", "F22", add_vec(norflash0.adr, ["L22", "L20", "K22", "K21", "J19", "H20", "F22",
Expand All @@ -21,14 +22,32 @@ def add_vec(signal, pins, iostandard="LVCMOS33", extra=""):
extra="SLEW = FAST | DRIVE = 8") extra="SLEW = FAST | DRIVE = 8")
add_vec(norflash0.d, ["AA20", "U14", "U13", "AA6", "AB6", "W4", "Y4", "Y7", add_vec(norflash0.d, ["AA20", "U14", "U13", "AA6", "AB6", "W4", "Y4", "Y7",
"AA2", "AB2", "V15", "AA18", "AB18", "Y13", "AA12", "AB12"], "AA2", "AB2", "V15", "AA18", "AB18", "Y13", "AA12", "AB12"],
extra = "SLEW = FAST | DRIVE = 8 | PULLDOWN") extra="SLEW = FAST | DRIVE = 8 | PULLDOWN")
add(norflash0.oe_n, "M22", extra="SLEW = FAST | DRIVE = 8") add(norflash0.oe_n, "M22", extra="SLEW = FAST | DRIVE = 8")
add(norflash0.we_n, "N20", extra="SLEW = FAST | DRIVE = 8") add(norflash0.we_n, "N20", extra="SLEW = FAST | DRIVE = 8")
add(norflash0.ce_n, "M21", extra="SLEW = FAST | DRIVE = 8") add(norflash0.ce_n, "M21", extra="SLEW = FAST | DRIVE = 8")


add(uart0.tx, "L17", extra="SLEW = SLOW") add(uart0.tx, "L17", extra="SLEW = SLOW")
add(uart0.rx, "K18", extra="PULLUP") add(uart0.rx, "K18", extra="PULLUP")


ddrsettings = "IOSTANDARD = SSTL2_I"
add(ddrphy0.sd_clk_out_p, "M3", extra=ddrsettings)
add(ddrphy0.sd_clk_out_n, "L4", extra=ddrsettings)
add_vec(ddrphy0.sd_a, ["B1", "B2", "H8", "J7", "E4", "D5", "K7", "F5",
"G6", "C1", "C3", "D1", "D2"], extra=ddrsettings)
add_vec(ddrphy0.sd_ba, ["A2", "E6"], extra=ddrsettings)
add(ddrphy0.sd_cs_n, "F7", extra=ddrsettings)
add(ddrphy0.sd_cke, "G7", extra=ddrsettings)
add(ddrphy0.sd_ras_n, "E5", extra=ddrsettings)
add(ddrphy0.sd_cas_n, "C4", extra=ddrsettings)
add(ddrphy0.sd_we_n, "D3", extra=ddrsettings)
add_vec(ddrphy0.sd_dq, ["Y2", "W3", "W1", "P8", "P7", "P6", "P5", "T4", "T3",
"U4", "V3", "N6", "N7", "M7", "M8", "R4", "P4", "M6", "L6", "P3", "N4",
"M5", "V2", "V1", "U3", "U1", "T2", "T1", "R3", "R1", "P2", "P1"],
extra=ddrsettings)
add_vec(ddrphy0.sd_dm, ["E1", "E3", "F3", "G4"], extra=ddrsettings)
add_vec(ddrphy0.sd_dqs, ["F1", "F2", "H5", "H6"], extra=ddrsettings)

r = "" r = ""
for c in constraints: for c in constraints:
r += "NET \"" + c[0] r += "NET \"" + c[0]
Expand All @@ -42,6 +61,15 @@ def add_vec(signal, pins, iostandard="LVCMOS33", extra=""):


r += """ r += """
TIMESPEC "TSclk50" = PERIOD "GRPclk50" 20 ns HIGH 50%; TIMESPEC "TSclk50" = PERIOD "GRPclk50" 20 ns HIGH 50%;
""" INST "spartan6_soft_phy/datapath_s6_inst/dq_idelay_cal_inst/max_tap_drp" LOC = "IODELAY_X0Y79"; # use sd_dm[0] at E1
INST "m1crg/wr_bufpll_left" LOC = "BUFPLL_X0Y2";
INST "m1crg/wr_bufpll_right" LOC = "BUFPLL_X2Y2";
INST "m1crg/rd_bufpll_left" LOC = "BUFPLL_X0Y3";
INST "m1crg/rd_bufpll_right" LOC = "BUFPLL_X2Y3";
# MAP (13.4) hallucinates that this placement is unroutable. Tell it to STFU.
PIN "m1crg/rd_bufpll_left.IOCLK" CLOCK_DEDICATED_ROUTE = FALSE;
PIN "spartan6_soft_phy/datapath_s6_inst/dq_idelay_cal_inst/max_tap_drp.IOCLK0" CLOCK_DEDICATED_ROUTE = FALSE;
"""


return r return r
2 changes: 1 addition & 1 deletion milkymist/m1crg/__init__.py
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ def __init__(self, infreq, outfreq1x):
"clk4x_rd_strb_left", "clk4x_rd_strb_left",
"clk4x_rd_right", "clk4x_rd_right",
"clk4x_rd_strb_right" "clk4x_rd_strb_right"
]: ]:
s = Signal(name=name) s = Signal(name=name)
setattr(self, name, s) setattr(self, name, s)
generated.append((name, s)) generated.append((name, s))
Expand Down
104 changes: 104 additions & 0 deletions milkymist/s6ddrphy/__init__.py
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,104 @@
from migen.fhdl.structure import *
from migen.bus import dfi

class S6DDRPHY:
def __init__(self, a, ba, d):
ins = []
outs = []
inouts = []

for name in [
"clk2x_90",
"clk4x_wr_left",
"clk4x_wr_strb_left",
"clk4x_wr_right",
"clk4x_wr_strb_right",
"clk4x_rd_left",
"clk4x_rd_strb_left",
"clk4x_rd_right",
"clk4x_rd_strb_right",
"reset_n"
]:
s = Signal(name=name)
setattr(self, name, s)
ins.append((name, s))

self._sd_pins = []
sd_d = d//4
for name, width, l in [
("sd_clk_out_p", 1, outs),
("sd_clk_out_n", 1, outs),
("sd_a", a, outs),
("sd_ba", ba, outs),
("sd_cs_n", 1, outs),
("sd_cke", 1, outs),
("sd_ras_n", 1, outs),
("sd_cas_n", 1, outs),
("sd_we_n", 1, outs),
("sd_dq", sd_d, inouts),
("sd_dm", sd_d//8, outs),
("sd_dqs", sd_d//8, inouts)

]:
s = Signal(BV(width), name=name)
setattr(self, name, s)
l.append((name, s))
self._sd_pins.append(s)

self.dfi = dfi.Interface(a, ba, d)
ins += self.dfi.get_standard_names(True, False)
outs += self.dfi.get_standard_names(False, True)

ins += [
("cfg_al", BV(3)),
("cfg_cl", BV(3)),
("cfg_bl", BV(2)),
("cfg_regdimm", BV(1)),

("init_done", BV(1)),

("cpg_busy", BV(1)),

("diag_dq_recal", BV(1)),
("diag_io_sel", BV(9)),
("diag_disable_cal_on_startup", BV(1)),
("diag_cal_bits", BV(2)),
("diag_short_cal", BV(1))
]
outs += [
("phy_cal_done", BV(1)),

("cpg_r_req", BV(1)),
("cpg_w_req", BV(1)),
("cpg_addr", BV(a)),
("cpg_b_size", BV(4))
]

self._inst = Instance("spartan6_soft_phy",
outs,
ins,
inouts,
[
("DSIZE", d),
("NUM_AD", a),
("NUM_BA", ba),
("ADDR_WIDTH", 31),
("DQ_IO_LOC", Constant(2**32-1, BV(32))),
("DM_IO_LOC", Constant(2**4-1, BV(4)))
],
clkport="clk")

def get_fragment(self):
comb = [
self._inst.ins["cfg_al"].eq(0),
self._inst.ins["cfg_cl"].eq(3),
self._inst.ins["cfg_bl"].eq(1),
self._inst.ins["cfg_regdimm"].eq(0),

self._inst.ins["diag_dq_recal"].eq(0),
self._inst.ins["diag_io_sel"].eq(0),
self._inst.ins["diag_disable_cal_on_startup"].eq(0),
self._inst.ins["diag_cal_bits"].eq(0),
self._inst.ins["diag_short_cal"].eq(0)
]
return Fragment(comb, instances=[self._inst], pads=set(self._sd_pins))
23 changes: 19 additions & 4 deletions top.py
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -4,19 +4,34 @@
from migen.fhdl import verilog, autofragment from migen.fhdl import verilog, autofragment
from migen.bus import wishbone, asmibus, wishbone2asmi, csr, wishbone2csr from migen.bus import wishbone, asmibus, wishbone2asmi, csr, wishbone2csr


from milkymist import m1crg, lm32, norflash, uart, sram#, s6ddrphy from milkymist import m1crg, lm32, norflash, uart, sram, s6ddrphy
import constraints import constraints


MHz = 1000000 MHz = 1000000
clk_freq = (83 + Fraction(1, 3))*MHz clk_freq = (83 + Fraction(1, 3))*MHz
sram_size = 4096 # in bytes sram_size = 4096 # in bytes
l2_size = 8192 # in bytes l2_size = 8192 # in bytes


def ddrphy_clocking(crg, phy):
names = [
"clk2x_90",
"clk4x_wr_left",
"clk4x_wr_strb_left",
"clk4x_wr_right",
"clk4x_wr_strb_right",
"clk4x_rd_left",
"clk4x_rd_strb_left",
"clk4x_rd_right",
"clk4x_rd_strb_right",
]
comb = [getattr(phy, name).eq(getattr(crg, name)) for name in names]
return Fragment(comb)

def get(): def get():
# #
# ASMI # ASMI
# #
#ddrphy0 = s6ddrphy.S6DDRPHY(13, 2, 128) ddrphy0 = s6ddrphy.S6DDRPHY(13, 2, 128)
asmihub0 = asmibus.Hub(23, 128, 12) # TODO: get hub from memory controller asmihub0 = asmibus.Hub(23, 128, 12) # TODO: get hub from memory controller
asmiport_wb = asmihub0.get_port() asmiport_wb = asmihub0.get_port()
asmihub0.finalize() asmihub0.finalize()
Expand Down Expand Up @@ -67,12 +82,12 @@ def get():
# #
crg0 = m1crg.M1CRG(50*MHz, clk_freq) crg0 = m1crg.M1CRG(50*MHz, clk_freq)


frag = autofragment.from_local() + interrupts frag = autofragment.from_local() + interrupts + ddrphy_clocking(crg0, ddrphy0)
src_verilog, vns = verilog.convert(frag, src_verilog, vns = verilog.convert(frag,
{crg0.trigger_reset}, {crg0.trigger_reset},
name="soc", name="soc",
clk_signal=crg0.sys_clk, clk_signal=crg0.sys_clk,
rst_signal=crg0.sys_rst, rst_signal=crg0.sys_rst,
return_ns=True) return_ns=True)
src_ucf = constraints.get(vns, crg0, norflash0, uart0) src_ucf = constraints.get(vns, crg0, norflash0, uart0, ddrphy0)
return (src_verilog, src_ucf) return (src_verilog, src_ucf)

0 comments on commit 5d1dad5

Please sign in to comment.