-PYTHON=python3
-
all: build/soc.bit
-# We need to change to the build directory because the Xilinx tools
-# tend to dump a mess of various files in the current directory.
-
-build/soc.prj build/soc.ucf:
- $(PYTHON) build.py
-
-build/soc.ngc: build/soc.prj
- cd build && xst -ifn ../soc.xst
-
-build/soc.ngd: build/soc.ngc build/soc.ucf
- cd build && ngdbuild -uc soc.ucf soc.ngc
-
-build/soc.ncd: build/soc.ngd
- cd build && map -ol high -w soc.ngd
-
-build/soc-routed.ncd: build/soc.ncd
- cd build && par -ol high -w soc.ncd soc-routed.ncd
-
-build/soc.bit build/soc.bin: build/soc-routed.ncd
- cd build && bitgen -g LCK_cycle:6 -g Binary:Yes -g INIT_9K:Yes -w soc-routed.ncd soc.bit
+build/soc.bit build/soc.bin:
+ ./build.py
load: build/soc.bit
jtag -n load.jtag
+#!/usr/bin/env python3
+
import os
+from mibuild.platforms import m1
import top
-# list Verilog sources before changing directory
-verilog_sources = []
-def add_core_dir(d):
- root = os.path.join("verilog", d)
- files = os.listdir(root)
- for f in files:
- if f[-2:] == ".v":
- verilog_sources.append(os.path.join(root, f))
-def add_core_files(d, files):
- for f in files:
- verilog_sources.append(os.path.join("verilog", d, f))
-add_core_dir("generic")
-add_core_dir("m1crg")
-add_core_dir("s6ddrphy")
-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_shifter.v", "lm32_multiplier_spartan6.v", "lm32_mc_arithmetic.v",
- "lm32_interrupt.v", "lm32_ram.v", "lm32_dp_ram.v", "lm32_icache.v",
- "lm32_dcache.v", "lm32_top.v", "lm32_debug.v", "lm32_jtag.v", "jtag_cores.v",
- "jtag_tap_spartan6.v"])
-add_core_dir("minimac3")
+def main():
+ plat = m1.Platform()
+ soc = top.SoC()
+
+ # set pin constraints
+ plat.request("clk50", obj=soc.crg.clk50_pad)
+ plat.request("user_btn", 1, obj=soc.crg.trigger_reset)
+ plat.request("norflash_rst_n", obj=soc.crg.norflash_rst_n)
+ plat.request("vga_clock", obj=soc.crg.vga_clk_pad)
+ plat.request("ddram_clock", obj=soc.crg, name_map=lambda s: "ddr_clk_pad_" + s)
+ plat.request("eth_clocks", obj=soc.crg, name_map=lambda s: "eth_" + s + "_clk_pad")
+
+ plat.request("norflash", obj=soc.norflash)
+ plat.request("serial", obj=soc.uart)
+ plat.request("ddram", obj=soc.ddrphy, name_map=lambda s: "sd_" + s)
+ plat.request("eth", obj=soc.minimac, name_map=lambda s: "phy_" + s)
+ plat.request("vga", obj=soc.fb, name_map=lambda s: "vga_" + s)
+
+ # set extra constraints
+ plat.add_platform_command("""
+NET "{clk50}" TNM_NET = "GRPclk50";
+TIMESPEC "TSclk50" = PERIOD "GRPclk50" 20 ns HIGH 50%;
+INST "m1crg/wr_bufpll" LOC = "BUFPLL_X0Y2";
+INST "m1crg/rd_bufpll" LOC = "BUFPLL_X0Y3";
-os.chdir("build")
+PIN "m1crg/bufg_x1.O" CLOCK_DEDICATED_ROUTE = FALSE;
-def str2file(filename, contents):
- f = open(filename, "w")
- f.write(contents)
- f.close()
+NET "{phy_rx_clk}" TNM_NET = "GRPphy_rx_clk";
+NET "{phy_tx_clk}" TNM_NET = "GRPphy_tx_clk";
+TIMESPEC "TSphy_rx_clk" = PERIOD "GRPphy_rx_clk" 40 ns HIGH 50%;
+TIMESPEC "TSphy_tx_clk" = PERIOD "GRPphy_tx_clk" 40 ns HIGH 50%;
+TIMESPEC "TSphy_tx_clk_io" = FROM "GRPphy_tx_clk" TO "PADS" 10 ns;
+TIMESPEC "TSphy_rx_clk_io" = FROM "PADS" TO "GRPphy_rx_clk" 10 ns;
-# generate source
-(src_verilog, src_ucf) = top.get()
-str2file("soc.v", src_verilog)
-str2file("soc.ucf", src_ucf)
-verilog_sources.append("build/soc.v")
+NET "asfifo*/counter_read/gray_count*" TIG;
+NET "asfifo*/counter_write/gray_count*" TIG;
+NET "asfifo*/preset_empty*" TIG;
+""",
+ clk50=soc.crg.clk50_pad,
+ phy_rx_clk=soc.crg.eth_rx_clk_pad,
+ phy_tx_clk=soc.crg.eth_tx_clk_pad)
+
+ # add Verilog sources
+ for d in ["generic", "m1crg", "s6ddrphy", "minimac3"]:
+ plat.add_source_dir(os.path.join("verilog", d))
+ plat.add_sources(os.path.join("verilog", "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_shifter.v", "lm32_multiplier_spartan6.v", "lm32_mc_arithmetic.v",
+ "lm32_interrupt.v", "lm32_ram.v", "lm32_dp_ram.v", "lm32_icache.v",
+ "lm32_dcache.v", "lm32_top.v", "lm32_debug.v", "lm32_jtag.v", "jtag_cores.v",
+ "jtag_tap_spartan6.v")
+
+ plat.build_cmdline(soc.get_fragment(), clock_domains=soc.crg.get_clock_domains())
-# generate XST project file
-xst_prj = ""
-for s in verilog_sources:
- xst_prj += "verilog work ../" + s + "\n"
-str2file("soc.prj", xst_prj)
+if __name__ == "__main__":
+ main()
+++ /dev/null
-class Constraints:
- def __init__(self, crg0, norflash0, uart0, ddrphy0, minimac0, fb0):
- self.constraints = []
- def add(signal, pin, vec=-1, iostandard="LVCMOS33", extra=""):
- self.constraints.append((signal, vec, pin, iostandard, extra))
- def add_vec(signal, pins, iostandard="LVCMOS33", extra=""):
- assert(signal.nbits == len(pins))
- i = 0
- for p in pins:
- add(signal, p, i, iostandard, extra)
- i += 1
-
- add(crg0.clkin, "AB11", extra="TNM_NET = \"GRPclk50\"")
- add(crg0.ac97_rst_n, "D6")
- add(crg0.videoin_rst_n, "W17")
- add(crg0.flash_rst_n, "P22", extra="SLEW = FAST | DRIVE = 8")
- add(crg0.trigger_reset, "AA4")
- add(crg0.eth_clk_pad, "M20")
- add(crg0.vga_clk_pad, "A11")
-
- add_vec(norflash0.adr, ["L22", "L20", "K22", "K21", "J19", "H20", "F22",
- "F21", "K17", "J17", "E22", "E20", "H18", "H19", "F20",
- "G19", "C22", "C20", "D22", "D21", "F19", "F18", "D20", "D19"],
- extra="SLEW = FAST | DRIVE = 8")
- add_vec(norflash0.d, ["AA20", "U14", "U13", "AA6", "AB6", "W4", "Y4", "Y7",
- "AA2", "AB2", "V15", "AA18", "AB18", "Y13", "AA12", "AB12"],
- extra="SLEW = FAST | DRIVE = 8 | PULLDOWN")
- add(norflash0.oe_n, "M22", 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(uart0.tx, "L17", extra="SLEW = SLOW")
- 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)
-
- add(minimac0.phy_rst_n, "R22")
- add(minimac0.phy_dv, "V21")
- add(minimac0.phy_rx_clk, "H22")
- add(minimac0.phy_rx_er, "V22")
- add_vec(minimac0.phy_rx_data, ["U22", "U20", "T22", "T21"])
- add(minimac0.phy_tx_en, "N19")
- add(minimac0.phy_tx_clk, "H21")
- add(minimac0.phy_tx_er, "M19")
- add_vec(minimac0.phy_tx_data, ["M16", "L15", "P19", "P20"])
- add(minimac0.phy_col, "W20")
- add(minimac0.phy_crs, "W22")
-
- add_vec(fb0.vga_r, ["C6", "B6", "A6", "C7", "A7", "B8", "A8", "D9"])
- add_vec(fb0.vga_g, ["C8", "C9", "A9", "D7", "D8", "D10", "C10", "B10"])
- add_vec(fb0.vga_b, ["D11", "C12", "B12", "A12", "C13", "A13", "D14", "C14"])
- add(fb0.vga_hsync_n, "A14")
- add(fb0.vga_vsync_n, "C15")
- add(fb0.vga_psave_n, "B14")
-
- self._phy_rx_clk = minimac0.phy_rx_clk
- self._phy_tx_clk = minimac0.phy_tx_clk
-
- def get_ios(self):
- return set([c[0] for c in self.constraints])
-
- def get_ucf(self, ns):
- r = ""
- for c in self.constraints:
- r += "NET \"" + ns.get_name(c[0])
- if c[1] >= 0:
- r += "(" + str(c[1]) + ")"
- r += "\" LOC = " + c[2]
- r += " | IOSTANDARD = " + c[3]
- if c[4]:
- r += " | " + c[4]
- r += ";\n"
-
- r += """
-TIMESPEC "TSclk50" = PERIOD "GRPclk50" 20 ns HIGH 50%;
-INST "m1crg/wr_bufpll" LOC = "BUFPLL_X0Y2";
-INST "m1crg/rd_bufpll" LOC = "BUFPLL_X0Y3";
-
-PIN "m1crg/bufg_x1.O" CLOCK_DEDICATED_ROUTE = FALSE;
-
-NET "{phy_rx_clk}" TNM_NET = "GRPphy_rx_clk";
-NET "{phy_tx_clk}" TNM_NET = "GRPphy_tx_clk";
-TIMESPEC "TSphy_rx_clk" = PERIOD "GRPphy_rx_clk" 40 ns HIGH 50%;
-TIMESPEC "TSphy_tx_clk" = PERIOD "GRPphy_tx_clk" 40 ns HIGH 50%;
-TIMESPEC "TSphy_tx_clk_io" = FROM "GRPphy_tx_clk" TO "PADS" 10 ns;
-TIMESPEC "TSphy_rx_clk_io" = FROM "PADS" TO "GRPphy_rx_clk" 10 ns;
-
-NET "asfifo*/counter_read/gray_count*" TIG;
-NET "asfifo*/counter_write/gray_count*" TIG;
-NET "asfifo*/preset_empty*" TIG;
-
-""".format(phy_rx_clk=ns.get_name(self._phy_rx_clk), phy_tx_clk=ns.get_name(self._phy_tx_clk))
-
- return r
from fractions import Fraction
from migen.fhdl.structure import *
+from mibuild.crg import CRG
-class M1CRG:
+class M1CRG(CRG):
def __init__(self, infreq, outfreq1x):
- self.clkin = Signal()
+ self.clk50_pad = Signal()
self.trigger_reset = Signal()
+ self.eth_rx_clk_pad = Signal()
+ self.eth_tx_clk_pad = Signal()
+
self.cd_sys = ClockDomain("sys")
self.cd_sys2x_270 = ClockDomain("sys2x_270")
self.cd_sys4x_wr = ClockDomain("sys4x_wr")
self.cd_sys4x_rd = ClockDomain("sys4x_rd")
+ self.cd_eth_rx = ClockDomain("eth_rx")
+ self.cd_eth_tx = ClockDomain("eth_tx")
self.cd_vga = ClockDomain("vga")
ratio = Fraction(outfreq1x)/Fraction(infreq)
Instance.Parameter("in_period", in_period),
Instance.Parameter("f_mult", ratio.numerator),
Instance.Parameter("f_div", ratio.denominator),
- Instance.Input("clkin", self.clkin),
+ Instance.Input("clk50_pad", self.clk50_pad),
Instance.Input("trigger_reset", self.trigger_reset),
+ Instance.Input("eth_rx_clk_pad", self.eth_rx_clk_pad),
+ Instance.Input("eth_tx_clk_pad", self.eth_tx_clk_pad),
+
Instance.Output("sys_clk", self.cd_sys.clk),
Instance.Output("sys_rst", self.cd_sys.rst),
Instance.Output("clk2x_270", self.cd_sys2x_270.clk),
Instance.Output("clk4x_wr", self.cd_sys4x_wr.clk),
Instance.Output("clk4x_rd", self.cd_sys4x_rd.clk),
+ Instance.Output("eth_rx_clk", self.cd_eth_rx.clk),
+ Instance.Output("eth_tx_clk", self.cd_eth_tx.clk),
Instance.Output("vga_clk", self.cd_vga.clk)
]
for name in [
- "ac97_rst_n",
- "videoin_rst_n",
- "flash_rst_n",
+ "norflash_rst_n",
"clk4x_wr_strb",
"clk4x_rd_strb",
- "eth_clk_pad",
+ "ddr_clk_pad_p",
+ "ddr_clk_pad_n",
+ "eth_phy_clk_pad",
"vga_clk_pad"
]:
s = Signal(name=name)
self._inst = Instance("m1crg", *inst_items)
-
def get_fragment(self):
return Fragment(instances=[self._inst])
Instance.Output("wb_dat_o", self.membus.dat_r),
Instance.Output("wb_ack_o", self.membus.ack),
+ Instance.ClockPort("phy_tx_clk", "eth_tx"),
Instance.Output("phy_tx_data", self.phy_tx_data),
Instance.Output("phy_tx_en", self.phy_tx_en),
- Instance.Output("phy_tx_er", self.phy_tx_er),
- Instance.Input("phy_tx_clk", self.phy_tx_clk),
- Instance.Input("phy_rx_clk", self.phy_rx_clk),
+ Instance.Output("phy_tx_er", self.phy_tx_er),
+ Instance.ClockPort("phy_rx_clk", "eth_rx"),
Instance.Input("phy_rx_data", self.phy_rx_data),
Instance.Input("phy_dv", self.phy_dv),
Instance.Input("phy_rx_er", self.phy_rx_er),
("clk4x_wr_strb", 1, Instance.Input),
("clk4x_rd_strb", 1, Instance.Input),
- ("sd_clk_out_p", 1, Instance.Output),
- ("sd_clk_out_n", 1, Instance.Output),
("sd_a", a, Instance.Output),
("sd_ba", ba, Instance.Output),
("sd_cs_n", 1, Instance.Output),
from milkymist import m1crg, lm32, norflash, uart, s6ddrphy, dfii, asmicon, \
identifier, timer, minimac3, framebuffer, asmiprobe
from cmacros import get_macros
-from constraints import Constraints
MHz = 1000000
clk_freq = (83 + Fraction(1, 3))*MHz
version = get_macros("common/version.h")["VERSION"][1:-1]
-def get():
- #
- # ASMI
- #
- asmicon0 = asmicon.ASMIcon(sdram_phy, sdram_geom, sdram_timing)
- asmiport_wb = asmicon0.hub.get_port()
- asmiport_fb = asmicon0.hub.get_port(2)
- asmicon0.finalize()
-
- #
- # DFI
- #
- ddrphy0 = s6ddrphy.S6DDRPHY(sdram_geom.mux_a, sdram_geom.bank_a, sdram_phy.dfi_d)
- dfii0 = dfii.DFIInjector(csr_offset("DFII"),
- sdram_geom.mux_a, sdram_geom.bank_a, sdram_phy.dfi_d, sdram_phy.nphases)
- dficon0 = dfi.Interconnect(dfii0.master, ddrphy0.dfi)
- dficon1 = dfi.Interconnect(asmicon0.dfi, dfii0.slave)
+class SoC:
+ def __init__(self):
+ #
+ # ASMI
+ #
+ self.asmicon = asmicon.ASMIcon(sdram_phy, sdram_geom, sdram_timing)
+ asmiport_wb = self.asmicon.hub.get_port()
+ asmiport_fb = self.asmicon.hub.get_port(2)
+ self.asmicon.finalize()
+
+ #
+ # DFI
+ #
+ self.ddrphy = s6ddrphy.S6DDRPHY(sdram_geom.mux_a, sdram_geom.bank_a, sdram_phy.dfi_d)
+ self.dfii = dfii.DFIInjector(csr_offset("DFII"),
+ sdram_geom.mux_a, sdram_geom.bank_a, sdram_phy.dfi_d, sdram_phy.nphases)
+ self.dficon0 = dfi.Interconnect(self.dfii.master, self.ddrphy.dfi)
+ self.dficon1 = dfi.Interconnect(self.asmicon.dfi, self.dfii.slave)
- #
- # WISHBONE
- #
- cpu0 = lm32.LM32()
- norflash0 = norflash.NorFlash(25, 12)
- sram0 = wishbone.SRAM(sram_size)
- minimac0 = minimac3.MiniMAC(csr_offset("MINIMAC"))
- wishbone2asmi0 = wishbone2asmi.WB2ASMI(l2_size//4, asmiport_wb)
- wishbone2csr0 = wishbone2csr.WB2CSR()
-
- # norflash 0x00000000 (shadow @0x80000000)
- # SRAM/debug 0x10000000 (shadow @0x90000000)
- # USB 0x20000000 (shadow @0xa0000000)
- # Ethernet 0x30000000 (shadow @0xb0000000)
- # SDRAM 0x40000000 (shadow @0xc0000000)
- # CSR bridge 0x60000000 (shadow @0xe0000000)
- wishbonecon0 = wishbone.InterconnectShared(
- [
- cpu0.ibus,
- cpu0.dbus
- ], [
- (lambda a: a[26:29] == 0, norflash0.bus),
- (lambda a: a[26:29] == 1, sram0.bus),
- (lambda a: a[26:29] == 3, minimac0.membus),
- (lambda a: a[27:29] == 2, wishbone2asmi0.wishbone),
- (lambda a: a[27:29] == 3, wishbone2csr0.wishbone)
- ],
- register=True)
-
- #
- # CSR
- #
- uart0 = uart.UART(csr_offset("UART"), clk_freq, baud=115200)
- identifier0 = identifier.Identifier(csr_offset("ID"), 0x4D31, version, int(clk_freq))
- timer0 = timer.Timer(csr_offset("TIMER0"))
- fb0 = framebuffer.Framebuffer(csr_offset("FB"), asmiport_fb)
- asmiprobe0 = asmiprobe.ASMIprobe(csr_offset("ASMIPROBE"), asmicon0.hub)
- csrcon0 = csr.Interconnect(wishbone2csr0.csr, [
- uart0.bank.bus,
- dfii0.bank.bus,
- identifier0.bank.bus,
- timer0.bank.bus,
- minimac0.bank.bus,
- fb0.bank.bus,
- asmiprobe0.bank.bus
- ])
-
- #
- # Interrupts
- #
- interrupts = Fragment([
- cpu0.interrupt[interrupt_n("UART")].eq(uart0.events.irq),
- cpu0.interrupt[interrupt_n("TIMER0")].eq(timer0.events.irq),
- cpu0.interrupt[interrupt_n("MINIMAC")].eq(minimac0.events.irq)
- ])
-
- #
- # Housekeeping
- #
- crg0 = m1crg.M1CRG(50*MHz, clk_freq)
-
- ddrphy_strobes = Fragment([
- ddrphy0.clk4x_wr_strb.eq(crg0.clk4x_wr_strb),
- ddrphy0.clk4x_rd_strb.eq(crg0.clk4x_rd_strb)
- ])
- frag = autofragment.from_local() \
- + interrupts \
- + ddrphy_strobes
- cst = Constraints(crg0, norflash0, uart0, ddrphy0, minimac0, fb0)
- src_verilog, vns = verilog.convert(frag,
- cst.get_ios(),
- name="soc",
- clock_domains={
- "sys": crg0.cd_sys,
- "sys2x_270": crg0.cd_sys2x_270,
- "sys4x_wr": crg0.cd_sys4x_wr,
- "sys4x_rd": crg0.cd_sys4x_rd,
- "vga": crg0.cd_vga
- },
- return_ns=True)
- src_ucf = cst.get_ucf(vns)
- return (src_verilog, src_ucf)
+ #
+ # WISHBONE
+ #
+ self.cpu = lm32.LM32()
+ self.norflash = norflash.NorFlash(25, 12)
+ self.sram = wishbone.SRAM(sram_size)
+ self.minimac = minimac3.MiniMAC(csr_offset("MINIMAC"))
+ self.wishbone2asmi = wishbone2asmi.WB2ASMI(l2_size//4, asmiport_wb)
+ self.wishbone2csr = wishbone2csr.WB2CSR()
+
+ # norflash 0x00000000 (shadow @0x80000000)
+ # SRAM/debug 0x10000000 (shadow @0x90000000)
+ # USB 0x20000000 (shadow @0xa0000000)
+ # Ethernet 0x30000000 (shadow @0xb0000000)
+ # SDRAM 0x40000000 (shadow @0xc0000000)
+ # CSR bridge 0x60000000 (shadow @0xe0000000)
+ self.wishbonecon = wishbone.InterconnectShared(
+ [
+ self.cpu.ibus,
+ self.cpu.dbus
+ ], [
+ (lambda a: a[26:29] == 0, self.norflash.bus),
+ (lambda a: a[26:29] == 1, self.sram.bus),
+ (lambda a: a[26:29] == 3, self.minimac.membus),
+ (lambda a: a[27:29] == 2, self.wishbone2asmi.wishbone),
+ (lambda a: a[27:29] == 3, self.wishbone2csr.wishbone)
+ ],
+ register=True)
+
+ #
+ # CSR
+ #
+ self.uart = uart.UART(csr_offset("UART"), clk_freq, baud=115200)
+ self.identifier = identifier.Identifier(csr_offset("ID"), 0x4D31, version, int(clk_freq))
+ self.timer = timer.Timer(csr_offset("TIMER0"))
+ self.fb = framebuffer.Framebuffer(csr_offset("FB"), asmiport_fb)
+ self.asmiprobe = asmiprobe.ASMIprobe(csr_offset("ASMIPROBE"), self.asmicon.hub)
+ self.csrcon = csr.Interconnect(self.wishbone2csr.csr, [
+ self.uart.bank.bus,
+ self.dfii.bank.bus,
+ self.identifier.bank.bus,
+ self.timer.bank.bus,
+ self.minimac.bank.bus,
+ self.fb.bank.bus,
+ self.asmiprobe.bank.bus
+ ])
+
+ #
+ # Clocking
+ #
+ self.crg = m1crg.M1CRG(50*MHz, clk_freq)
+
+ def get_fragment(self):
+ comb = [
+ #
+ # Interrupts
+ #
+ self.cpu.interrupt[interrupt_n("UART")].eq(self.uart.events.irq),
+ self.cpu.interrupt[interrupt_n("TIMER0")].eq(self.timer.events.irq),
+ self.cpu.interrupt[interrupt_n("MINIMAC")].eq(self.minimac.events.irq),
+ #
+ # DDR PHY strobes
+ #
+ self.ddrphy.clk4x_wr_strb.eq(self.crg.clk4x_wr_strb),
+ self.ddrphy.clk4x_rd_strb.eq(self.crg.clk4x_rd_strb)
+ ]
+ glue = Fragment(comb)
+ return glue + autofragment.from_attributes(self)
parameter f_div = 0,
parameter clk2x_period = (in_period*f_div)/(2.0*f_mult)
) (
- input clkin,
+ input clk50_pad,
input trigger_reset,
output sys_clk,
output reg sys_rst,
- /* Reset off-chip devices */
- output ac97_rst_n,
- output videoin_rst_n,
- output flash_rst_n,
+ /* Reset NOR flash */
+ output norflash_rst_n,
/* DDR PHY clocks */
output clk2x_270,
output clk4x_wr_strb,
output clk4x_rd,
output clk4x_rd_strb,
+
+ /* DDR off-chip clocking */
+ output ddr_clk_pad_p,
+ output ddr_clk_pad_n,
- /* Ethernet PHY clock */
- output reg eth_clk_pad, /* < unbuffered, to I/O */
+ /* Ethernet PHY clocks */
+ output reg eth_phy_clk_pad,
+ input eth_rx_clk_pad,
+ input eth_tx_clk_pad,
+ output eth_rx_clk,
+ output eth_tx_clk,
/* VGA clock */
output vga_clk, /* < buffered, to internal clock network */
sys_rst <= rst_debounce != 20'd0;
end
-assign ac97_rst_n = ~sys_rst;
-assign videoin_rst_n = ~sys_rst;
-
/*
* We must release the Flash reset before the system reset
* because the Flash needs some time to come out of reset
flash_rstcounter <= flash_rstcounter + 8'd1;
end
-assign flash_rst_n = flash_rstcounter[7];
+assign norflash_rst_n = flash_rstcounter[7];
/*
* Clock management. Inspired by the NWL reference design.
*/
-wire sdr_clkin;
+wire sdr_clk50;
wire clkdiv;
IBUF #(
.IOSTANDARD("DEFAULT")
) clk2_iob (
- .I(clkin),
- .O(sdr_clkin)
+ .I(clk50_pad),
+ .O(sdr_clk50)
);
BUFIO2 #(
.DIVIDE_BYPASS("FALSE"),
.I_INVERT("FALSE")
) bufio2_inst2 (
- .I(sdr_clkin),
+ .I(sdr_clk50),
.IOCLK(),
.DIVCLK(clkdiv),
.SERDESSTROBE()
.CLKOUT1(pllout1), /* < x4 clock for reads */
.CLKOUT2(pllout2), /* < x2 90 clock to generate memory clock, clock DQS and memory address and control signals. */
.CLKOUT3(pllout3), /* < x1 clock for system and memory controller */
- .CLKOUT4(pllout4), /* < buffered clkin */
+ .CLKOUT4(pllout4), /* < buffered clk50 */
.CLKOUT5(),
.CLKOUTDCM0(),
.CLKOUTDCM1(),
.O(sys_clk)
);
-/* Ethernet PHY */
+
+/*
+ * SDRAM clock
+ */
+
+ODDR2 #(
+ .DDR_ALIGNMENT("NONE"),
+ .INIT(1'b0),
+ .SRTYPE("SYNC")
+) sd_clk_forward_p (
+ .Q(sd_clk_out_p),
+ .C0(clk2x_270),
+ .C1(~clk2x_270),
+ .CE(1'b1),
+ .D0(1'b1),
+ .D1(1'b0),
+ .R(1'b0),
+ .S(1'b0)
+);
+ODDR2 #(
+ .DDR_ALIGNMENT("NONE"),
+ .INIT(1'b0),
+ .SRTYPE("SYNC")
+) sd_clk_forward_n (
+ .Q(sd_clk_out_n),
+ .C0(clk2x_270),
+ .C1(~clk2x_270),
+ .CE(1'b1),
+ .D0(1'b0),
+ .D1(1'b1),
+ .R(1'b0),
+ .S(1'b0)
+);
+
+/*
+ * Ethernet PHY
+ */
+
always @(posedge pllout4)
eth_clk_pad <= ~eth_clk_pad;
-/* VGA clock */
+/* Let the synthesizer insert the appropriate buffers */
+assign eth_rx_clk = eth_rx_clk_pad;
+assign eth_tx_clk = eth_tx_clk_pad;
+
+/*
+ * VGA clock
+ */
+
// TODO: hook up the reprogramming interface
DCM_CLKGEN #(
.CLKFXDV_DIVIDE(2),
output dfi_rddata_valid_w1,
/* DDR SDRAM pads */
- output sd_clk_out_p,
- output sd_clk_out_n,
output reg [NUM_AD-1:0] sd_a,
output reg [NUM_BA-1:0] sd_ba,
output reg sd_cs_n,
inout [NUM_D/16-1:0] sd_dqs
);
-/*
- * SDRAM clock
- */
-ODDR2 #(
- .DDR_ALIGNMENT("NONE"),
- .INIT(1'b0),
- .SRTYPE("SYNC")
-) sd_clk_forward_p (
- .Q(sd_clk_out_p),
- .C0(clk2x_270),
- .C1(~clk2x_270),
- .CE(1'b1),
- .D0(1'b1),
- .D1(1'b0),
- .R(1'b0),
- .S(1'b0)
-);
-ODDR2 #(
- .DDR_ALIGNMENT("NONE"),
- .INIT(1'b0),
- .SRTYPE("SYNC")
-) sd_clk_forward_n (
- .Q(sd_clk_out_n),
- .C0(clk2x_270),
- .C1(~clk2x_270),
- .CE(1'b1),
- .D0(1'b0),
- .D1(1'b1),
- .R(1'b0),
- .S(1'b0)
-);
-
/*
* Command/address
*/