from fractions import Fraction from math import ceil from migen.fhdl.structure import * from migen.fhdl import verilog, autofragment from migen.bus import wishbone, wishbone2asmi, csr, wishbone2csr, dfi from milkymist import m1crg, lm32, norflash, uart, sram, s6ddrphy, dfii, asmicon, identifier, timer, minimac3 from cmacros import get_macros from constraints import Constraints MHz = 1000000 clk_freq = (83 + Fraction(1, 3))*MHz sram_size = 4096 # in bytes l2_size = 8192 # in bytes clk_period_ns = 1000000000/clk_freq def ns(t, margin=True): if margin: t += clk_period_ns/2 return ceil(t/clk_period_ns) sdram_phy = asmicon.PhySettings( dfi_d=64, nphases=2, rdphase=0, wrphase=1 ) sdram_geom = asmicon.GeomSettings( bank_a=2, row_a=13, col_a=10 ) sdram_timing = asmicon.TimingSettings( tRP=ns(15), tRCD=ns(15), tWR=ns(15), tREFI=ns(7800, False), tRFC=ns(70), CL=3, rd_delay=4, slot_time=16, read_time=32, write_time=16 ) def ddrphy_clocking(crg, phy): names = [ "clk2x_270", "clk4x_wr", "clk4x_wr_strb", "clk4x_rd", "clk4x_rd_strb" ] comb = [getattr(phy, name).eq(getattr(crg, name)) for name in names] return Fragment(comb) csr_macros = get_macros("common/csrbase.h") def csr_offset(name): base = int(csr_macros[name + "_BASE"], 0) assert((base >= 0xe0000000) and (base <= 0xe0010000)) return (base - 0xe0000000)//0x800 interrupt_macros = get_macros("common/interrupt.h") def interrupt_n(name): return int(interrupt_macros[name + "_INTERRUPT"], 0) 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() 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) # # WISHBONE # cpu0 = lm32.LM32() norflash0 = norflash.NorFlash(25, 12) sram0 = sram.SRAM(sram_size//4) 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 ], [ (binc("000"), norflash0.bus), (binc("001"), sram0.bus), (binc("011"), minimac0.membus), (binc("10"), wishbone2asmi0.wishbone), (binc("11"), wishbone2csr0.wishbone) ], register=True, offset=1) # # 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")) csrcon0 = csr.Interconnect(wishbone2csr0.csr, [ uart0.bank.interface, dfii0.bank.interface, identifier0.bank.interface, timer0.bank.interface, minimac0.bank.interface ]) # # 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) frag = autofragment.from_local() + interrupts + ddrphy_clocking(crg0, ddrphy0) cst = Constraints(crg0, norflash0, uart0, ddrphy0, minimac0) src_verilog, vns = verilog.convert(frag, cst.get_ios(), name="soc", clk_signal=crg0.sys_clk, rst_signal=crg0.sys_rst, return_ns=True) src_ucf = cst.get_ucf(vns) return (src_verilog, src_ucf)