|
| 1 | +from migen.fhdl.std import * |
| 2 | +from migen.bank.description import * |
| 3 | +from migen.bank import wbgen |
| 4 | +from mibuild.generic_platform import * |
| 5 | + |
| 6 | +from misoclib.cpu.peripherals import gpio |
| 7 | +from targets.pipistrello import BaseSoC |
| 8 | + |
| 9 | +from artiq.gateware import rtio, ad9858 |
| 10 | + |
| 11 | + |
| 12 | +_tester_io = [ Has conversations. Original line has conversations. |
| 13 | + ("ext_led", 0, Pins("B:7"), IOStandard("LVTTL")), |
| 14 | + |
| 15 | + ("pmt", 0, Pins("C:13"), IOStandard("LVTTL")), |
| 16 | + ("pmt", 1, Pins("C:14"), IOStandard("LVTTL")), |
| 17 | + ("xtrig", 0, Pins("C:12"), IOStandard("LVTTL")), |
| 18 | + ("dds_clock", 0, Pins("C:15"), IOStandard("LVTTL")), |
| 19 | + |
| 20 | + ("ttl", 0, Pins("C:11"), IOStandard("LVTTL")), |
| 21 | + ("ttl", 1, Pins("C:10"), IOStandard("LVTTL")), |
| 22 | + ("ttl", 2, Pins("C:9"), IOStandard("LVTTL")), |
| 23 | + ("ttl", 3, Pins("C:8"), IOStandard("LVTTL")), |
| 24 | + ("ttl", 4, Pins("C:7"), IOStandard("LVTTL")), |
| 25 | + ("ttl", 5, Pins("C:6"), IOStandard("LVTTL")), |
| 26 | + ("ttl", 6, Pins("C:5"), IOStandard("LVTTL")), |
| 27 | + ("ttl", 7, Pins("C:4"), IOStandard("LVTTL")), |
| 28 | + ("ttl_l_tx_en", 0, Pins("A:9"), IOStandard("LVTTL")), |
| 29 | + |
| 30 | + ("ttl", 8, Pins("C:3"), IOStandard("LVTTL")), |
| 31 | + ("ttl", 9, Pins("C:2"), IOStandard("LVTTL")), |
| 32 | + ("ttl", 10, Pins("C:1"), IOStandard("LVTTL")), |
| 33 | + ("ttl", 11, Pins("C:0"), IOStandard("LVTTL")), |
| 34 | + ("ttl", 12, Pins("B:4"), IOStandard("LVTTL")), |
| 35 | + ("ttl", 13, Pins("A:11"), IOStandard("LVTTL")), |
| 36 | + ("ttl", 14, Pins("B:5"), IOStandard("LVTTL")), |
| 37 | + ("ttl", 15, Pins("A:10"), IOStandard("LVTTL")), |
| 38 | + ("ttl_h_tx_en", 0, Pins("B:6"), IOStandard("LVTTL")), |
| 39 | + |
| 40 | + ("dds", 0, |
| 41 | + Subsignal("a", Pins("A:5 B:10 A:6 B:9 A:7 B:8")), |
| 42 | + Subsignal("d", Pins("A:12 B:3 A:13 B:2 A:14 B:1 A:15 B:0")), |
| 43 | + Subsignal("sel", Pins("A:2 B:14 A:1 B:15 A:0")), |
| 44 | + Subsignal("p", Pins("A:8 B:12")), |
| 45 | + Subsignal("fud_n", Pins("B:11")), |
| 46 | + Subsignal("wr_n", Pins("A:4")), |
| 47 | + Subsignal("rd_n", Pins("B:13")), |
| 48 | + Subsignal("rst_n", Pins("A:3")), |
| 49 | + IOStandard("LVTTL")), |
| 50 | +] |
| 51 | + |
| 52 | + |
| 53 | +class _RTIOMiniCRG(Module, AutoCSR): |
| 54 | + def __init__(self, platform): |
| 55 | + self._r_clock_sel = CSRStorage() |
| 56 | + self.clock_domains.cd_rtio = ClockDomain() |
| 57 | + |
| 58 | + # 80MHz -> 125MHz |
| 59 | + rtio_internal_clk = Signal() |
| 60 | + self.specials += Instance("DCM_CLKGEN", |
| 61 | + p_CLKFXDV_DIVIDE=2, |
| 62 | + p_CLKFX_DIVIDE=16, |
| 63 | + p_CLKFX_MD_MAX=1.6, |
| 64 | + p_CLKFX_MULTIPLY=25, |
| 65 | + p_CLKIN_PERIOD=12.5, |
| 66 | + p_SPREAD_SPECTRUM="NONE", |
| 67 | + p_STARTUP_WAIT="FALSE", |
| 68 | + i_CLKIN=ClockSignal(), |
| 69 | + o_CLKFX=rtio_internal_clk, |
| 70 | + i_FREEZEDCM=0, |
| 71 | + i_RST=ResetSignal()) |
| 72 | + |
| 73 | + rtio_external_clk = platform.request("dds_clock") |
| 74 | + platform.add_period_constraint(rtio_external_clk, 8.0) |
| 75 | + self.specials += Instance("BUFGMUX", |
| 76 | + i_I0=rtio_internal_clk, |
| 77 | + i_I1=rtio_external_clk, |
| 78 | + i_S=self._r_clock_sel.storage, |
| 79 | + o_O=self.cd_rtio.clk) |
| 80 | + |
| 81 | + platform.add_platform_command(""" |
| 82 | +NET "{rtio_clk}" TNM_NET = "GRPrtio_clk"; |
| 83 | +NET "sys_clk" TNM_NET = "GRPsys_clk"; |
| 84 | +TIMESPEC "TSfix_ise1" = FROM "GRPrtio_clk" TO "GRPsys_clk" TIG; |
| 85 | +TIMESPEC "TSfix_ise2" = FROM "GRPsys_clk" TO "GRPrtio_clk" TIG; |
| 86 | +""", rtio_clk=rtio_internal_clk) |
| 87 | + |
| 88 | + |
| 89 | +class ARTIQMidiSoC(BaseSoC): |
| 90 | + csr_map = { |
| 91 | + "rtio": None, # mapped on Wishbone instead |
| 92 | + "rtiocrg": 13 |
| 93 | + } |
| 94 | + csr_map.update(BaseSoC.csr_map) |
| 95 | + |
| 96 | + def __init__(self, platform, cpu_type="or1k", **kwargs): |
| 97 | + BaseSoC.__init__(self, platform, cpu_type=cpu_type, **kwargs) |
| 98 | + platform.add_extension(_tester_io) |
| 99 | + |
| 100 | + self.submodules.leds = gpio.GPIOOut(Cat( |
| 101 | + platform.request("user_led", 0), |
| 102 | + platform.request("user_led", 1), |
| 103 | + platform.request("user_led", 2), |
| 104 | + platform.request("user_led", 3), |
| 105 | + platform.request("user_led", 4), |
| 106 | + platform.request("ext_led", 0), |
| 107 | + )) |
| 108 | + |
| 109 | + fud = Signal() |
| 110 | + self.comb += [ |
| 111 | + platform.request("ttl_l_tx_en").eq(1), |
| 112 | + platform.request("ttl_h_tx_en").eq(1) |
| 113 | + ] |
| 114 | + rtio_ins = [platform.request("pmt", i) for i in range(2)] |
| 115 | + rtio_ins += [platform.request("xtrig", 0)] |
| 116 | + rtio_outs = [platform.request("ttl", i) for i in range(16)] |
| 117 | + rtio_outs += [fud] |
| 118 | + |
| 119 | + self.submodules.rtiocrg = _RTIOMiniCRG(platform) |
| 120 | + self.submodules.rtiophy = rtio.phy.SimplePHY( |
| 121 | + rtio_ins + rtio_outs, |
| 122 | + output_only_pads=set(rtio_outs)) |
| 123 | + self.submodules.rtio = rtio.RTIO(self.rtiophy, |
| 124 | + clk_freq=125000000, |
| 125 | + ififo_depth=512) |
| 126 | + |
| 127 | + rtio_csrs = self.rtio.get_csrs() |
| 128 | + self.submodules.rtiowb = wbgen.Bank(rtio_csrs) |
| 129 | + self.add_wb_slave(lambda a: a[26:29] == 2, self.rtiowb.bus) |
| 130 | + self.add_csr_region("rtio", 0xa0000000, 32, rtio_csrs) |
| 131 | + |
| 132 | + dds_pads = platform.request("dds") |
| 133 | + self.submodules.dds = ad9858.AD9858(dds_pads) |
| 134 | + self.add_wb_slave(lambda a: a[26:29] == 3, self.dds.bus) |
| 135 | + self.comb += dds_pads.fud_n.eq(~fud) |
| 136 | + |
| 137 | + |
| 138 | +default_subtarget = ARTIQMidiSoC |