import cif
def main():
- plat = m1.Platform()
- soc = top.SoC()
+ platform = m1.Platform()
+ soc = top.SoC(platform)
- # 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)
- plat.request("dvi_in", 0, obj=soc.dvisampler0)
- plat.request("dvi_in", 1, obj=soc.dvisampler1)
-
- # set extra constraints
- plat.add_platform_command("""
+ platform.add_platform_command("""
NET "{clk50}" TNM_NET = "GRPclk50";
TIMESPEC "TSclk50" = PERIOD "GRPclk50" 20 ns HIGH 50%;
INST "m1crg/wr_bufpll" LOC = "BUFPLL_X0Y2";
NET "{dviclk1}" CLOCK_DEDICATED_ROUTE = FALSE;
TIMESPEC "TSdviclk1" = PERIOD "GRPdviclk1" 26.7 ns HIGH 50%;
""",
- clk50=soc.crg.clk50_pad,
- phy_rx_clk=soc.crg.eth_rx_clk_pad,
- phy_tx_clk=soc.crg.eth_tx_clk_pad,
- dviclk0=soc.dvisampler0.clk,
- dviclk1=soc.dvisampler1.clk)
+ clk50=platform.lookup_request("clk50"),
+ phy_rx_clk=platform.lookup_request("eth_clocks").rx,
+ phy_tx_clk=platform.lookup_request("eth_clocks").tx,
+ dviclk0=platform.lookup_request("dvi_in", 0).clk,
+ dviclk1=platform.lookup_request("dvi_in", 1).clk)
- # 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", "submodule", "rtl"),
+ platform.add_source_dir(os.path.join("verilog", d))
+ platform.add_sources(os.path.join("verilog", "lm32", "submodule", "rtl"),
"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.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", "lm32_itlb.v", "lm32_dtlb.v")
- plat.add_sources(os.path.join("verilog", "lm32"), "lm32_config.v")
+ platform.add_sources(os.path.join("verilog", "lm32"), "lm32_config.v")
- plat.build_cmdline(soc)
+ platform.build_cmdline(soc)
csr_header = cif.get_csr_header(soc.csr_base, soc.csrbankarray, soc.interrupt_map)
write_to_file("software/include/hw/csr.h", csr_header)
from milkymist.dvisampler.resdetection import ResolutionDetection
class DVISampler(Module, AutoReg):
- def __init__(self, inversions=""):
- self.submodules.edid = EDID()
- self.sda = self.edid.sda
- self.scl = self.edid.scl
+ def __init__(self, pads):
+ self.submodules.edid = EDID(pads)
+ self.submodules.clocking = Clocking(pads)
- self.submodules.clocking = Clocking()
- self.clk = self.clocking.clkin
-
- for datan in "012":
+ for datan in range(3):
name = "data" + str(datan)
- invert = datan in inversions
+ invert = False
+ try:
+ s = getattr(pads, name)
+ except AttributeError:
+ s = getattr(pads, name + "_n")
+ invert = True
- signame = name + "_n" if invert else name
- s = Signal(name=signame)
- setattr(self, signame, s)
-
cap = DataCapture(8, invert)
setattr(self.submodules, name + "_cap", cap)
self.comb += [
from migen.bank.description import *
class Clocking(Module, AutoReg):
- def __init__(self):
- self.clkin = Signal()
-
+ def __init__(self, pads):
self._r_pll_reset = RegisterField()
self._r_locked = RegisterField(1, READ_ONLY, WRITE_ONLY)
Instance.Output("CLKOUT3", pll_clk3),
Instance.Output("LOCKED", pll_locked),
Instance.Input("CLKFBIN", clkfbout),
- Instance.Input("CLKIN", self.clkin),
+ Instance.Input("CLKIN", pads.clk),
Instance.Input("RST", self._r_pll_reset.field.r)
)
]
class EDID(Module, AutoReg):
- def __init__(self, default=_default_edid):
- self.scl = Signal()
- self.sda = Signal()
-
+ def __init__(self, pads, default=_default_edid):
self.specials.mem = Memory(8, 128, init=default)
###
_sda_i_async = Signal()
self.sync += _sda_drv_reg.eq(sda_drv)
self.specials += [
- MultiReg(self.scl, scl_i, "sys"),
- Tristate(self.sda, 0, _sda_drv_reg, _sda_i_async),
- MultiReg(_sda_i_async, sda_i, "sys")
+ MultiReg(pads.scl, scl_i),
+ Tristate(pads.sda, 0, _sda_drv_reg, _sda_i_async),
+ MultiReg(_sda_i_async, sda_i)
]
# FIXME: understand what is really going on here and get rid of that workaround
+ " " + str(t.value["r"]) + " " + str(t.value["g"]) + " " + str(t.value["b"]))
class Framebuffer(Module):
- def __init__(self, asmiport, simulation=False):
+ def __init__(self, pads, asmiport, simulation=False):
asmi_bits = asmiport.hub.aw
alignment_bits = bits_for(asmiport.hub.dw//8) - 1
length_bits = _hbits + _vbits + 2 - alignment_bits
self._registers = fi.get_registers() + self._comp_actor.get_registers()
- # Pads
- self.vga_psave_n = Signal()
+ # Drive pads
if not simulation:
- self.vga_hsync_n = fifo.vga_hsync_n
- self.vga_vsync_n = fifo.vga_vsync_n
- self.vga_sync_n = Signal()
- self.vga_blank_n = Signal()
- if not simulation:
- self.vga_r = fifo.vga_r
- self.vga_g = fifo.vga_g
- self.vga_b = fifo.vga_b
-
- self.comb += [
- self.vga_sync_n.eq(0),
- self.vga_psave_n.eq(1),
- self.vga_blank_n.eq(1)
- ]
+ self.comb += [
+ pads.hsync_n.eq(fifo.vga_hsync_n),
+ pads.vsync_n.eq(fifo.vga_vsync_n),
+ pads.r.eq(fifo.vga_r),
+ pads.g.eq(fifo.vga_g),
+ pads.b.eq(fifo.vga_b)
+ ]
+ self.comb += pads.psave_n.eq(1)
def get_registers(self):
return self._registers
from migen.fhdl.module import Module
class M1CRG(Module):
- def __init__(self, infreq, outfreq1x):
- self.clk50_pad = Signal()
- self.trigger_reset = Signal()
-
- self.eth_rx_clk_pad = Signal()
- self.eth_tx_clk_pad = Signal()
-
+ def __init__(self, pads, outfreq1x):
self.clock_domains.cd_sys = ClockDomain()
self.clock_domains.cd_sys2x_270 = ClockDomain()
self.clock_domains.cd_sys4x_wr = ClockDomain()
self.clock_domains.cd_eth_rx = ClockDomain()
self.clock_domains.cd_eth_tx = ClockDomain()
self.clock_domains.cd_vga = ClockDomain()
+
+ self.clk4x_wr_strb = Signal()
+ self.clk4x_rd_strb = Signal()
+
+ ###
+ infreq = 50*1000000
ratio = Fraction(outfreq1x)/Fraction(infreq)
in_period = float(Fraction(1000000000)/Fraction(infreq))
- inst_items = [
+ self.specials += Instance("m1crg",
Instance.Parameter("in_period", in_period),
Instance.Parameter("f_mult", ratio.numerator),
Instance.Parameter("f_div", ratio.denominator),
- Instance.Input("clk50_pad", self.clk50_pad),
- Instance.Input("trigger_reset", self.trigger_reset),
+ Instance.Input("clk50_pad", pads.clk50),
+ Instance.Input("trigger_reset", pads.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.Input("eth_rx_clk_pad", pads.eth_rx_clk),
+ Instance.Input("eth_tx_clk_pad", pads.eth_tx_clk),
Instance.Output("sys_clk", self.cd_sys.clk),
Instance.Output("sys_rst", self.cd_sys.rst),
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 [
- "norflash_rst_n",
- "clk4x_wr_strb",
- "clk4x_rd_strb",
- "ddr_clk_pad_p",
- "ddr_clk_pad_n",
- "eth_phy_clk_pad",
- "vga_clk_pad"
- ]:
- s = Signal(name=name)
- setattr(self, name, s)
- inst_items.append(Instance.Output(name, s))
-
- self.specials += Instance("m1crg", *inst_items)
+ Instance.Output("vga_clk", self.cd_vga.clk),
+
+ Instance.Output("clk4x_wr_strb", self.clk4x_wr_strb),
+ Instance.Output("clk4x_rd_strb", self.clk4x_rd_strb),
+ Instance.Output("norflash_rst_n", pads.norflash_rst_n),
+ Instance.Output("ddr_clk_pad_p", pads.ddr_clk_p),
+ Instance.Output("ddr_clk_pad_n", pads.ddr_clk_n),
+ Instance.Output("eth_phy_clk_pad", pads.eth_phy_clk),
+ Instance.Output("vga_clk_pad", pads.vga_clk))
_count_width = 11
class MiniMAC(Module, AutoReg):
- def __init__(self):
- # PHY signals
- self.phy_tx_clk = Signal()
- self.phy_tx_data = Signal(4)
- self.phy_tx_en = Signal()
- self.phy_tx_er = Signal()
- self.phy_rx_clk = Signal()
- self.phy_rx_data = Signal(4)
- self.phy_dv = Signal()
- self.phy_rx_er = Signal()
- self.phy_col = Signal()
- self.phy_crs = Signal()
- self.phy_rst_n = Signal()
-
+ def __init__(self, pads):
# CPU interface
self._phy_reset = RegisterField(reset=1)
self._rx_count_0 = RegisterField(_count_width, access_bus=READ_ONLY, access_dev=WRITE_ONLY)
rx_pending_0_r = Signal()
rx_pending_1_r = Signal()
self.comb += [
- self.phy_rst_n.eq(~self._phy_reset.field.r),
+ pads.rst_n.eq(~self._phy_reset.field.r),
rx_ready_0.eq(init | (rx_pending_0_r & ~rx_pending_0)),
rx_ready_1.eq(init | (rx_pending_1_r & ~rx_pending_1)),
Instance.Output("wb_ack_o", self.membus.ack),
Instance.Input("phy_tx_clk", ClockSignal("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.Output("phy_tx_data", pads.tx_data),
+ Instance.Output("phy_tx_en", pads.tx_en),
+ Instance.Output("phy_tx_er", pads.tx_er),
Instance.Input("phy_rx_clk", ClockSignal("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),
- Instance.Input("phy_col", self.phy_col),
- Instance.Input("phy_crs", self.phy_crs))
+ Instance.Input("phy_rx_data", pads.rx_data),
+ Instance.Input("phy_dv", pads.dv),
+ Instance.Input("phy_rx_er", pads.rx_er),
+ Instance.Input("phy_col", pads.col),
+ Instance.Input("phy_crs", pads.crs))
from migen.genlib.misc import timeline
class NorFlash(Module):
- def __init__(self, adr_width, rd_timing):
+ def __init__(self, pads, rd_timing):
self.bus = wishbone.Interface()
- self.adr = Signal(adr_width-1)
- self.d = Signal(16)
- self.oe_n = Signal()
- self.we_n = Signal()
- self.ce_n = Signal()
###
-
- self.comb += [self.oe_n.eq(0), self.we_n.eq(1),
- self.ce_n.eq(0)]
+
+ adr_width = len(pads.adr) + 1
+ self.comb += [pads.oe_n.eq(0), pads.we_n.eq(1),
+ pads.ce_n.eq(0)]
self.sync += timeline(self.bus.cyc & self.bus.stb, [
- (0, [self.adr.eq(Cat(0, self.bus.adr[:adr_width-2]))]),
+ (0, [pads.adr.eq(Cat(0, self.bus.adr[:adr_width-2]))]),
(rd_timing, [
- self.bus.dat_r[16:].eq(self.d),
- self.adr.eq(Cat(1, self.bus.adr[:adr_width-2]))]),
+ self.bus.dat_r[16:].eq(pads.d),
+ pads.adr.eq(Cat(1, self.bus.adr[:adr_width-2]))]),
(2*rd_timing, [
- self.bus.dat_r[:16].eq(self.d),
+ self.bus.dat_r[:16].eq(pads.d),
self.bus.ack.eq(1)]),
(2*rd_timing + 1, [
self.bus.ack.eq(0)])
from migen.bus import dfi
class S6DDRPHY(Module):
- def __init__(self, a, ba, d):
+ def __init__(self, pads):
+ self.dfi = dfi.Interface(len(pads.a), len(pads.ba), 2*len(pads.dq), 2)
+ self.clk4x_wr_strb = Signal()
+ self.clk4x_rd_strb = Signal()
+
+ ###
+
inst_items = [
- Instance.Parameter("NUM_AD", a),
- Instance.Parameter("NUM_BA", ba),
- Instance.Parameter("NUM_D", d),
+ Instance.Parameter("NUM_AD", len(pads.a)),
+ Instance.Parameter("NUM_BA", len(pads.ba)),
+ Instance.Parameter("NUM_D", 2*len(pads.dq)),
+
Instance.Input("sys_clk", ClockSignal()),
Instance.Input("clk2x_270", ClockSignal("sys2x_270")),
Instance.Input("clk4x_wr", ClockSignal("sys4x_wr")),
- Instance.Input("clk4x_rd", ClockSignal("sys4x_rd"))
+ Instance.Input("clk4x_rd", ClockSignal("sys4x_rd")),
+
+ Instance.Input("clk4x_wr_strb", self.clk4x_wr_strb),
+ Instance.Input("clk4x_rd_strb", self.clk4x_rd_strb),
+
+ Instance.Output("sd_a", pads.a),
+ Instance.Output("sd_ba", pads.ba),
+ Instance.Output("sd_cs_n", pads.cs_n),
+ Instance.Output("sd_cke", pads.cke),
+ Instance.Output("sd_ras_n", pads.ras_n),
+ Instance.Output("sd_cas_n", pads.cas_n),
+ Instance.Output("sd_we_n", pads.we_n),
+ Instance.InOut("sd_dq", pads.dq),
+ Instance.Output("sd_dm", pads.dm),
+ Instance.InOut("sd_dqs", pads.dqs)
]
- for name, width, cl in [
- ("clk4x_wr_strb", 1, Instance.Input),
- ("clk4x_rd_strb", 1, Instance.Input),
-
- ("sd_a", a, Instance.Output),
- ("sd_ba", ba, Instance.Output),
- ("sd_cs_n", 1, Instance.Output),
- ("sd_cke", 1, Instance.Output),
- ("sd_ras_n", 1, Instance.Output),
- ("sd_cas_n", 1, Instance.Output),
- ("sd_we_n", 1, Instance.Output),
- ("sd_dq", d//2, Instance.InOut),
- ("sd_dm", d//16, Instance.Output),
- ("sd_dqs", d//16, Instance.InOut)
-
- ]:
- s = Signal(width, name=name)
- setattr(self, name, s)
- inst_items.append(cl(name, s))
-
- self.dfi = dfi.Interface(a, ba, d, 2)
inst_items += [Instance.Input(name, signal)
for name, signal in self.dfi.get_standard_names(True, False)]
inst_items += [Instance.Output(name, signal)
for name, signal in self.dfi.get_standard_names(False, True)]
-
self.specials += Instance("s6ddrphy", *inst_items)
from migen.bank.eventmanager import *
class UART(Module, AutoReg):
- def __init__(self, clk_freq, baud=115200):
+ def __init__(self, pads, clk_freq, baud=115200):
self._rxtx = RegisterRaw(8)
self._divisor = RegisterField(16, reset=int(clk_freq/baud/16))
self.ev.tx = EventSourceLevel()
self.ev.rx = EventSourcePulse()
self.ev.finalize()
-
- self.tx = Signal(reset=1)
- self.rx = Signal()
###
+ pads.tx.reset = 1
+
enable16 = Signal()
enable16_counter = Signal(16)
self.comb += enable16.eq(enable16_counter == 0)
tx_bitcount.eq(0),
tx_count16.eq(1),
tx_busy.eq(1),
- self.tx.eq(0)
+ pads.tx.eq(0)
).Elif(enable16 & tx_busy,
tx_count16.eq(tx_count16 + 1),
If(tx_count16 == 0,
tx_bitcount.eq(tx_bitcount + 1),
If(tx_bitcount == 8,
- self.tx.eq(1)
+ pads.tx.eq(1)
).Elif(tx_bitcount == 9,
- self.tx.eq(1),
+ pads.tx.eq(1),
tx_busy.eq(0)
).Else(
- self.tx.eq(tx_reg[0]),
+ pads.tx.eq(tx_reg[0]),
tx_reg.eq(Cat(tx_reg[1:], 0))
)
)
# RX
rx = Signal()
- self.specials += MultiReg(self.rx, rx, "sys")
+ self.specials += MultiReg(pads.rx, rx)
rx_r = Signal()
rx_reg = Signal(8)
rx_bitcount = Signal(4)
identifier, timer, minimac3, framebuffer, asmiprobe, dvisampler
from cif import get_macros
-MHz = 1000000
-clk_freq = (83 + Fraction(1, 3))*MHz
+version = get_macros("common/version.h")["VERSION"][1:-1]
+
+clk_freq = (83 + Fraction(1, 3))*1000000
sram_size = 4096 # in bytes
l2_size = 8192 # in bytes
write_time=16
)
-version = get_macros("common/version.h")["VERSION"][1:-1]
+class M1ClockPads:
+ def __init__(self, platform):
+ self.clk50 = platform.request("clk50")
+ self.trigger_reset = platform.request("user_btn", 1)
+ self.norflash_rst_n = platform.request("norflash_rst_n")
+ self.vga_clk = platform.request("vga_clock")
+ ddram_clock = platform.request("ddram_clock")
+ self.ddr_clk_p = ddram_clock.p
+ self.ddr_clk_n = ddram_clock.n
+ eth_clocks = platform.request("eth_clocks")
+ self.eth_phy_clk = eth_clocks.phy
+ self.eth_rx_clk = eth_clocks.rx
+ self.eth_tx_clk = eth_clocks.tx
class SoC(Module):
csr_base = 0xe0000000
"minimac": 2,
}
- def __init__(self):
+ def __init__(self, platform):
#
# ASMI
#
#
# DFI
#
- self.submodules.ddrphy = s6ddrphy.S6DDRPHY(sdram_geom.mux_a, sdram_geom.bank_a, sdram_phy.dfi_d)
+ self.submodules.ddrphy = s6ddrphy.S6DDRPHY(platform.request("ddram"))
self.submodules.dfii = dfii.DFIInjector(sdram_geom.mux_a, sdram_geom.bank_a, sdram_phy.dfi_d,
sdram_phy.nphases)
self.submodules.dficon0 = dfi.Interconnect(self.dfii.master, self.ddrphy.dfi)
# WISHBONE
#
self.submodules.cpu = lm32.LM32()
- self.submodules.norflash = norflash.NorFlash(25, 12)
+ self.submodules.norflash = norflash.NorFlash(platform.request("norflash"), 12)
self.submodules.sram = wishbone.SRAM(sram_size)
- self.submodules.minimac = minimac3.MiniMAC()
+ self.submodules.minimac = minimac3.MiniMAC(platform.request("eth"))
self.submodules.wishbone2asmi = wishbone2asmi.WB2ASMI(l2_size//4, asmiport_wb)
self.submodules.wishbone2csr = wishbone2csr.WB2CSR()
#
# CSR
#
- self.submodules.uart = uart.UART(clk_freq, baud=115200)
+ self.submodules.uart = uart.UART(platform.request("serial"), clk_freq, baud=115200)
self.submodules.identifier = identifier.Identifier(0x4D31, version, int(clk_freq))
self.submodules.timer0 = timer.Timer()
- self.submodules.fb = framebuffer.Framebuffer(asmiport_fb)
+ self.submodules.fb = framebuffer.Framebuffer(platform.request("vga"), asmiport_fb)
self.submodules.asmiprobe = asmiprobe.ASMIprobe(self.asmicon.hub)
- self.submodules.dvisampler0 = dvisampler.DVISampler("02")
- self.submodules.dvisampler1 = dvisampler.DVISampler("02")
+ self.submodules.dvisampler0 = dvisampler.DVISampler(platform.request("dvi_in", 0))
+ self.submodules.dvisampler1 = dvisampler.DVISampler(platform.request("dvi_in", 1))
self.submodules.csrbankarray = csrgen.BankArray(self,
lambda name, memory: self.csr_map[name if memory is None else name + "_" + memory.name_override])
#
# Clocking
#
- self.submodules.crg = m1crg.M1CRG(50*MHz, clk_freq)
+ self.submodules.crg = m1crg.M1CRG(M1ClockPads(platform), clk_freq)
self.comb += [
self.ddrphy.clk4x_wr_strb.eq(self.crg.clk4x_wr_strb),
self.ddrphy.clk4x_rd_strb.eq(self.crg.clk4x_rd_strb)