def __init__(self, platform):
        clk = platform.request("clk")
        rst = platform.request("reset")

        clk12 = Signal()

        self.clock_domains.cd_sys = ClockDomain()
        self.clock_domains.cd_usb_12 = ClockDomain()
        self.clock_domains.cd_usb_16 = ClockDomain()
        self.clock_domains.cd_usb_48 = ClockDomain()
        self.clock_domains.cd_usb_48_to_12 = ClockDomain()

        clk48 = clk.clk48
        clk16 = clk.clk16
        self.comb += clk.clk12.eq(clk12)

        self.comb += self.cd_usb_16.clk.eq(clk16)
        self.comb += self.cd_usb_48.clk.eq(clk48)
        self.comb += self.cd_usb_48_to_12.clk.eq(clk48)

        clk12_counter = Signal(2)
        self.sync.usb_48_to_12 += clk12_counter.eq(clk12_counter + 1)

        self.comb += clk12.eq(clk12_counter[1])

        self.comb += self.cd_sys.clk.eq(clk12)
        self.comb += self.cd_usb_12.clk.eq(clk12)

        self.comb += [
            ResetSignal("sys").eq(rst),
            ResetSignal("usb_12").eq(rst),
            ResetSignal("usb_48").eq(rst),
        ]
Exemple #2
0
    def __init__(self, platform):

        clk12 = platform.request("clk12")
        self.clock_domains.cd_por = ClockDomain(reset_less=True)
        self.clock_domains.cd_sys = ClockDomain()
        reset_delay = Signal(max=1024)
        self.comb += [
            self.cd_por.clk.eq(clk12),
            self.cd_sys.clk.eq(clk12),
            self.cd_sys.rst.eq(reset_delay != 1023)
        ]
        self.sync.por += \
            If(reset_delay != 1023,
                reset_delay.eq(reset_delay + 1)
            )

        self.submodules.dec = SyncDecoder(8, 3 * 7)
        self.comb += [
            self.dec.data.eq(platform.request("din")),
            self.dec.wck.eq(platform.request("wck")),
            self.dec.bck.eq(platform.request("bck")),
        ]

        self.submodules.packager = Packager(0x47)

        serial = platform.request("fast_serial")
        self.submodules.tx = FastSerialTX(serial)
        self.comb += self.tx.sink.payload.port.eq(1)

        self.comb += [
            self.dec.source.connect(self.packager.sink),
            self.packager.source.connect(self.tx.sink),
        ]

        # 96.000 MHz pll and /10 for mclk
        self.mclk = platform.request("mclk")
        pll_out = Signal()
        self.specials.pll = Instance("pll",
                                     i_clock_in=ClockSignal("sys"),
                                     o_clock_out=pll_out)
        self.clock_domains.cd_pll = ClockDomain(reset_less=True)
        self.comb += self.cd_pll.clk.eq(pll_out)

        self.counter = Signal(max=5)

        self.sync.pll += [
            If(self.counter >= 4,
                self.counter.eq(0),
                self.mclk.eq(~self.mclk),
            ).Else(
                self.counter.eq(self.counter + 1),
            )
        ]
Exemple #3
0
    def __init__(self,
                 use_ext_clock=False,
                 csr_data_width=def_csr_data_width,
                 csr_addr_width=def_csr_addr_width):
        ps = jesd204b.common.JESD204BPhysicalSettings(l=self.nLanes,
                                                      m=4,
                                                      n=16,
                                                      np=16)
        ts = jesd204b.common.JESD204BTransportSettings(f=2, s=1, k=16, cs=0)
        jesd_settings = jesd204b.common.JESD204BSettings(ps,
                                                         ts,
                                                         did=0x5a,
                                                         bid=0x5)

        self.submodules.crg = JESDConfig(use_ext_clock=use_ext_clock)
        if use_ext_clock:
            self.clock_domains.cd_ext = ClockDomain()

        refclk = self.crg.refclk
        refclk_freq = self.crg.refclk_freq
        linerate = self.crg.linerate
        sys_clk_freq = self.crg.fabric_freq

        self.jesd_pads_txp = Signal(self.nLanes, name="jesd_txp")
        self.jesd_pads_txn = Signal(self.nLanes, name="jesd_txn")

        self.dac_sync = Signal()
        self.jref = self.crg.jref

        self.csr_devices = ["crg", "control"]

        phys = []

        for i in range(self.nLanes):
            gtxq = jesdphy.gtx.GTXQuadPLL(refclk, refclk_freq, linerate)
            self.submodules += gtxq
            phy = jesdphy.JESD204BPhyTX(gtxq,
                                        phyPad(self.jesd_pads_txp[i],
                                               self.jesd_pads_txn[i]),
                                        sys_clk_freq,
                                        transceiver="gtx")
            phys.append(phy)

        self.submodules.core = jesdc.JESD204BCoreTX(phys,
                                                    jesd_settings,
                                                    converter_data_width=64)

        self.submodules.control = jesdc.JESD204BCoreTXControl(self.core)
        self.core.register_jsync(self.dac_sync)
        self.core.register_jref(self.jref)

        self.csr_master = csr_bus.Interface(data_width=csr_data_width,
                                            address_width=csr_addr_width)
        self.submodules.csrbankarray = csr_bus.CSRBankArray(
            self,
            self.map_csr_dev,
            data_width=csr_data_width,
            address_width=csr_addr_width)
        self.submodules.csrcon = csr_bus.Interconnect(
            self.csr_master, self.csrbankarray.get_buses())
Exemple #4
0
    def __init__(self, use_ext_clock=False):
        self.ibuf_disable = CSRStorage(reset=1)
        self.jreset = CSRStorage(reset=1)
        self.jref = Signal()
        self.refclk = Signal()
        self.clock_domains.cd_jesd = ClockDomain()

        self.refclk_pads = lvdsPair(Signal(name="refclk_p"),
                                    Signal(name="refclk_n"))

        refclk2 = Signal()  # Useless for gtx transceivers
        self.specials += [
            Instance("IBUFDS_GTE2",
                     i_CEB=self.ibuf_disable.storage,
                     i_I=self.refclk_pads.p,
                     i_IB=self.refclk_pads.n,
                     o_O=self.refclk,
                     o_ODIV2=refclk2),
            AsyncResetSynchronizer(self.cd_jesd, self.jreset.storage),
        ]
        if use_ext_clock:
            self.comb += self.cd_jesd.clk.eq(ClockSignal("ext"))
        else:
            self.specials += Instance("BUFG",
                                      i_I=self.refclk,
                                      o_O=self.cd_jesd.clk)
Exemple #5
0
    def add_zest(self):
        self.platform.add_extension(zest_pads)
        bus = wishbone.Interface()
        self.add_memory_region("zest", self.mem_map["zest"], 0x1000000)
        self.add_wb_slave(self.mem_map["zest"], bus)

        self.submodules.zest = Zest(self.platform, bus, 0x8)

        self.clock_domains.cd_adc    = ClockDomain()

        self.comb += [
            ClockSignal("adc").eq(self.zest.dsp_clk_out),
            self.zest.clk.eq(self.crg.cd_sys.clk),
            self.zest.clk_200.eq(self.crg.cd_idelay.clk),
            self.zest.rst.eq(~self.crg.pll.locked),
        ]

        counter_adc = Signal(27)
        self.sync.adc += counter_adc.eq(counter_adc+1)
        self.comb += self.user_leds[0].eq(counter_adc[26])

        counter_sys = Signal(27)
        self.sync += counter_sys.eq(counter_sys+1)
        self.comb += self.user_leds[1].eq(counter_sys[26])

        self.platform.add_period_constraint(self.platform.lookup_request("ZEST_CLK_TO_FPGA", 1, loose=True).p, 8.7)
        self.platform.add_false_path_constraints(self.crg.cd_sys.clk,
                                                 self.cd_adc.clk,
                                                 self.crg.cd_idelay.clk,
                                                 self.platform.lookup_request("ZEST_CLK_TO_FPGA", 1, loose=True).p,
                                                 self.platform.lookup_request("ZEST_ADC_DCO", 0, loose=True).p,
                                                 self.platform.lookup_request("ZEST_ADC_DCO", 1, loose=True).p,
                                                 self.platform.lookup_request("ZEST_DAC_DCO", loose=True).p
        )
    def __init__(self, platform, sys_clk_freq):
        self.clock_domains.cd_sys = ClockDomain()
        self.clock_domains.cd_sys4x = ClockDomain(reset_less=True)
        self.clock_domains.cd_sys4x_dqs = ClockDomain(reset_less=True)
        self.clock_domains.cd_clk200 = ClockDomain()

        # # #

        self.submodules.pll = pll = S7PLL(speedgrade=-1)
        self.comb += pll.reset.eq(~platform.request("cpu_reset"))
        pll.register_clkin(platform.request("clk100"), 100e6)
        pll.create_clkout(self.cd_sys, sys_clk_freq)
        pll.create_clkout(self.cd_sys4x, 4 * sys_clk_freq)
        pll.create_clkout(self.cd_sys4x_dqs, 4 * sys_clk_freq, phase=90)
        pll.create_clkout(self.cd_clk200, 200e6)

        self.submodules.idelayctrl = S7IDELAYCTRL(self.cd_clk200)
Exemple #7
0
    def __init__(self, platform):
        serial = platform.request("fast_serial")

        clk12 = platform.request("clk12")

        self.clock_domains.cd_sys = ClockDomain()

        if True:
            self.specials.pll = Instance("pll_test",
                                         i_clock_in=clk12,
                                         o_clock_out=self.cd_sys.clk)
        else:
            self.comb += self.cd_sys.clk.eq(clk12)

        self.clock_domains.cd_por = ClockDomain(reset_less=True)
        reset_delay = Signal(max=1024)
        self.comb += [
            self.cd_por.clk.eq(self.cd_sys.clk),
            self.cd_sys.rst.eq(reset_delay != 1023)
        ]
        self.sync.por += If(reset_delay != 1023,
                            reset_delay.eq(reset_delay + 1))

        self.submodules.tx = FastSerialTX(serial)
        self.submodules.packager = Packager(0x47)
        self.comb += self.packager.source.connect(self.tx.sink)
        self.comb += self.tx.sink.payload.port.eq(1)

        counter = Signal(5)

        self.comb += [
            self.packager.sink.stb.eq(1),
            self.packager.sink.payload.data.eq(counter),
            self.packager.sink.eop.eq(counter == 2**counter.nbits - 1)
        ]

        self.sync += [
            If(self.packager.sink.stb & self.packager.sink.ack,
               counter.eq(counter + 1)),
        ]

        debug = platform.request("debug")
        self.comb += [
            debug.eq(Cat(serial.clk, serial.di, serial.cts)),
        ]
        def add_mmcm(self, nclkout):
            if (nclkout > 7):
                raise ValueError("nclkout cannot be above 7!")

            self.cd_mmcm_clkout = []
            self.submodules.mmcm = S7MMCM(speedgrade=-1)
            self.mmcm.register_clkin(self.crg.cd_sys.clk, self.clk_freq)

            for n in range(nclkout):
                self.cd_mmcm_clkout += [
                    ClockDomain(name="cd_mmcm_clkout{}".format(n))
                ]
                self.mmcm.create_clkout(self.cd_mmcm_clkout[n], self.clk_freq)
            self.mmcm.clock_domains.cd_mmcm_clkout = self.cd_mmcm_clkout

            self.add_constant("clkout_def_freq", int(self.clk_freq))
            self.add_constant("clkout_def_phase", int(0))
            self.add_constant("clkout_def_duty_num", int(50))
            self.add_constant("clkout_def_duty_den", int(100))
            # We need to write exponent of clkout_margin to allow the driver for smaller inaccuracy
            from math import log10
            exp = log10(self.mmcm.clkouts[0][3])
            if exp < 0:
                self.add_constant("clkout_margin_exp", int(abs(exp)))
                self.add_constant("clkout_margin",
                                  int(self.mmcm.clkouts[0][3] * 10**abs(exp)))
            else:
                self.add_constant("clkout_margin",
                                  int(self.mmcm.clkouts[0][3]))
                self.add_constant("clkout_margin_exp", int(0))

            self.add_constant("nclkout", int(nclkout))
            self.add_constant("mmcm_lock_timeout", int(10))
            self.add_constant("mmcm_drdy_timeout", int(10))
            self.add_constant("vco_margin", int(self.mmcm.vco_margin))
            self.add_constant("vco_freq_range_min",
                              int(self.mmcm.vco_freq_range[0]))
            self.add_constant("vco_freq_range_max",
                              int(self.mmcm.vco_freq_range[1]))
            self.add_constant("clkfbout_mult_frange_min",
                              int(self.mmcm.clkfbout_mult_frange[0]))
            self.add_constant("clkfbout_mult_frange_max",
                              int(self.mmcm.clkfbout_mult_frange[1]))
            self.add_constant("divclk_divide_range_min",
                              int(self.mmcm.divclk_divide_range[0]))
            self.add_constant("divclk_divide_range_max",
                              int(self.mmcm.divclk_divide_range[1]))
            self.add_constant("clkout_divide_range_min",
                              int(self.mmcm.clkout_divide_range[0]))
            self.add_constant("clkout_divide_range_max",
                              int(self.mmcm.clkout_divide_range[1]))

            self.mmcm.expose_drp()
            self.add_csr("mmcm")

            self.comb += self.mmcm.reset.eq(self.mmcm.drp_reset.re)
    def __init__(self, platform):
        clk = platform.request("clk")
        rst = platform.request("reset")

        self.clock_domains.cd_sys = ClockDomain()
        self.comb += self.cd_sys.clk.eq(clk.clk48)

        self.comb += [
            ResetSignal("sys").eq(rst),
        ]
    def __init__(self, platform, sys_clk_freq):
        self.clock_domains.cd_sys = ClockDomain()
        self.clock_domains.cd_por = ClockDomain()

        # Clock from HFOSC
        self.submodules.sys_clk = sys_osc = NXOSCA()
        sys_osc.create_hf_clk(self.cd_sys, sys_clk_freq)
        # We make the period constraint 10% tighter than our actual system
        # clock frequency, because the CrossLink-NX internal oscillator runs
        # at ±10% of nominal frequency.
        platform.add_period_constraint(self.cd_sys.clk,
                                       1e9 / (sys_clk_freq * 1.1))

        # Power On Reset
        por_cycles = 4096
        por_counter = Signal(log2_int(por_cycles), reset=por_cycles - 1)
        self.comb += self.cd_por.clk.eq(self.cd_sys.clk)
        self.sync.por += If(por_counter != 0, por_counter.eq(por_counter - 1))
        self.specials += AsyncResetSynchronizer(self.cd_sys,
                                                (por_counter != 0))
Exemple #11
0
    def __init__(self, platform, sys_clk_freq, resets=[]):
        self.rst = Signal()
        self.clock_domains.cd_sys = ClockDomain()
        self.clock_domains.cd_sys4x = ClockDomain(reset_less=True)
        self.clock_domains.cd_sys4x_dqs = ClockDomain(reset_less=True)
        self.clock_domains.cd_idelay = ClockDomain()

        # # #

        self.submodules.pll = pll = S7MMCM(speedgrade=-2)

        resets.append(self.rst)
        self.comb += pll.reset.eq(reduce(or_, resets))
        pll.register_clkin(platform.request("clk125"), 125e6)
        pll.create_clkout(self.cd_sys, sys_clk_freq)
        pll.create_clkout(self.cd_sys4x, 4 * sys_clk_freq)
        # pll.create_clkout(self.cd_sys4x_dqs, 4*sys_clk_freq, phase=90)
        pll.create_clkout(self.cd_idelay, 200e6)
        # Ignore sys_clk to pll.clkin path created by SoC's rst.
        platform.add_false_path_constraints(self.cd_sys.clk, pll.clkin)
        platform.add_period_constraint(self.cd_sys.clk, 1e9 / sys_clk_freq)
        platform.add_period_constraint(self.cd_idelay.clk, 1e9 / 200e6)
        platform.add_platform_command(
            "set_property LOC IDELAYCTRL_X1Y1 [get_cells IDELAYCTRL]")
        platform.add_platform_command(
            "set_property LOC IDELAYCTRL_X1Y2 [get_cells IDELAYCTRL_1]")
        platform.add_platform_command(
            "set_property LOC IDELAYCTRL_X0Y3 [get_cells IDELAYCTRL_2]")
        platform.add_platform_command(
            "set_property LOC IDELAYCTRL_X0Y4 [get_cells IDELAYCTRL_3]")
        platform.add_platform_command(
            "set_property LOC IDELAYCTRL_X1Y0 [get_cells IDELAYCTRL_4]")
        # platform.add_platform_command("set_property IODELAY_GROUP IO_DLY1 [get_cells *IDELAYCTRL*]")
        # platform.add_platform_command("set_property IODELAY_GROUP IO_DLY1 [get_cells *ODELAYE2*]")
        # platform.add_platform_command("set_property IODELAY_GROUP IO_DLY1 [get_cells -hier *IDELAYE2*]")
        # platform.add_platform_command("set_property IODELAY_GROUP IO_DLY1 [get_cells -hier *idelaye2*]")
        platform.add_false_path_constraint(self.cd_idelay.clk, self.cd_sys.clk)
        for _ in range(5):
            self.submodules += S7IDELAYCTRL(self.cd_idelay)
Exemple #12
0
def test_rx():
    # Real values divided by 100 to make for a faster test.
    clk_freq = 12000000 // 100
    baud_rate = 921600 // 100
    dut = RX(clk_freq=clk_freq, baud_rate=baud_rate)
    dut.clock_domains.cd_sys = ClockDomain('sys')
    run_simulation(dut,
                   _test_rx(dut, clk_freq // baud_rate),
                   vcd_name='vcd/uart-rx.vcd')

    dut = RXFIFO(clk_freq=clk_freq, baud_rate=baud_rate)
    run_simulation(dut,
                   _test_rx_fifo(dut, clk_freq // baud_rate),
                   vcd_name='vcd/uart-rx-fifo.vcd')
    def __init__(self, platform, sys_clk_freq):
        self.clock_domains.cd_sys = ClockDomain()

        # # #

        self.cd_sys.clk.attr.add("keep")

        self.submodules.pll = pll = S7PLL(speedgrade=-1)
        self.comb += pll.reset.eq(~platform.request("cpu_reset"))
        pll_clkin = Signal()
        pll.register_clkin(pll_clkin, 100e6)
        pll.create_clkout(self.cd_sys, sys_clk_freq)

        self.specials += Instance("BUFG",
                                  i_I=platform.request("clk100"),
                                  o_O=pll_clkin)
Exemple #14
0
    def __init__(self,
                 platform,
                 mac_address=0x10e2d5000004,
                 ip_address="10.0.11.2"):
        BaseSoC.__init__(self,
                         platform,
                         cpu_type="vexriscv",
                         cpu_variant="debug",
                         csr_data_width=8,
                         l2_size=32)

        # ethernet mac/udp/ip stack
        self.submodules.ethphy = LiteEthPHYMII(
            self.platform.request("eth_clocks"), self.platform.request("eth"))
        self.submodules.ethcore = LiteEthUDPIPCore(self.ethphy,
                                                   mac_address,
                                                   convert_ip(ip_address),
                                                   self.clk_freq,
                                                   with_icmp=True)

        # vexriscv debugging, at offset 0xf00f0000
        self.register_mem("vexriscv_debug", 0xf00f0000,
                          self.cpu_or_bridge.debug_bus, 0x10)

        # Hook Etherbone up to the Wishbone bus, providing Wishbone over Ethernet.
        etherbone_cd = ClockDomain("etherbone")
        self.clock_domains += etherbone_cd
        self.comb += [
            etherbone_cd.clk.eq(ClockSignal("sys")),
            etherbone_cd.rst.eq(ResetSignal("sys"))
        ]
        self.submodules.etherbone = LiteEthEtherbone(self.ethcore.udp,
                                                     1234,
                                                     mode="master",
                                                     cd="etherbone")
        self.add_wb_master(self.etherbone.wishbone.bus)

        self.ethphy.crg.cd_eth_rx.clk.attr.add("keep")
        self.ethphy.crg.cd_eth_tx.clk.attr.add("keep")
        self.platform.add_period_constraint(self.ethphy.crg.cd_eth_rx.clk,
                                            period_ns(25e6))
        self.platform.add_period_constraint(self.ethphy.crg.cd_eth_tx.clk,
                                            period_ns(25e6))

        self.platform.add_false_path_constraints(self.crg.cd_sys.clk,
                                                 self.ethphy.crg.cd_eth_rx.clk,
                                                 self.ethphy.crg.cd_eth_tx.clk)
Exemple #15
0
def test_decoder():

    def feed_in(dut, tests):
        for test in tests:
            if test is None:
                yield
                continue

            yield dut.wck.eq(1)
            for word in test:
                for bit in range(dut.n_bits)[::-1]:
                    yield dut.data.eq((word >> bit) & 1)
                    yield
                    yield dut.wck.eq(0)

    def test_out(dut, tests):
        for test in tests:
            if test is None:
                continue

            for i, word in enumerate(test[:dut.n_words]):
                while not (yield dut.source.stb):
                    yield
                assert (yield dut.source.payload.data) == word
                assert (yield dut.source.eop) == (i == dut.n_words - 1)

                yield

    tests = [
        None, None, None, None,
        [0x81, 0xff],
        [0x00, 0xff],
        None, None, None, None,
        [0x00, 0xff, 0x81],
        [0x00, 0xff],
    ]

    dut = Decoder(8, 2)
    dut.clock_domains.cd_sys = ClockDomain("sys")
    run_simulation(dut, [feed_in(dut, tests), test_out(dut, tests)], vcd_name="decoder.vcd")
Exemple #16
0
def simulate():
    dut = TestBench()
    dut.clock_domains.cd_sys = ClockDomain("sys")

    def testbench():
        """
        Tesbench
        """
        step = 0
        while True:
            hc = yield dut.vga.hc
            vc = yield dut.vga.vc
            r0 = yield dut.vga.color.r0
            r1 = yield dut.vga.color.r1
            g0 = yield dut.vga.color.g0
            g1 = yield dut.vga.color.g1
            assert hc == step % VGA.hpixels
            assert vc == (step // VGA.hpixels) % VGA.vlines
            yield
            step += 1

    run_simulation(dut, testbench(), vcd_name="vga.vcd")
Exemple #17
0
def view():
    dut = TestBench()
    dut.clock_domains.cd_sys = ClockDomain("sys")

    def setup_view(q):
        import view
        v = view.Veiw(VGA.hpixels, VGA.vlines, VGA.hfp, VGA.hbp, VGA.vfp, VGA.vbp)
        v.run(q)

    q = Queue()
    p = Process(target=setup_view, args=(q,))
    p.start()

    def testbench():
        """
        Tesbench
        """
        step = 0
        line = []
        prev_vc = 0
        while True:
            hc = yield dut.vga.hc
            vc = yield dut.vga.vc
            r0 = yield dut.vga.color.r0
            r1 = yield dut.vga.color.r1
            g0 = yield dut.vga.color.g0
            g1 = yield dut.vga.color.g1
            assert hc == step % VGA.hpixels
            assert vc == (step // VGA.hpixels) % VGA.vlines
            if prev_vc != vc and line:
                q.put((vc, line))
                line = []
            line.append((scale(r0, r1), scale(g0, g1), 0))
            prev_vc = vc
            yield
            step += 1

    run_simulation(dut, testbench())
Exemple #18
0
    def __init__(self, n_bits, n_words):
        self.data = Signal()
        self.wck = Signal()
        self.bck = Signal()

        layout = [("data", n_bits)]

        self.clock_domains.cd_decode = ClockDomain()
        self.specials += AsyncResetSynchronizer(self.cd_decode, ResetSignal("sys"))

        decoder = ClockDomainsRenamer("decode")(Decoder(n_bits, n_words))
        self.submodules.decoder = decoder

        cdr = ClockDomainsRenamer({"read": "sys", "write": "decode"})
        self.submodules.fifo = cdr(stream.AsyncFIFO(layout, 8))

        self.source = self.fifo.source

        self.comb += [
            self.cd_decode.clk.eq(self.bck),
            decoder.wck.eq(self.wck),
            decoder.data.eq(self.data),
            decoder.source.connect(self.fifo.sink),
        ]
Exemple #19
0
        def __init__(self, platform):
            clk12_raw = platform.request("clk12")
            clk18 = Signal()

            self.clock_domains.cd_sys = ClockDomain()
            self.comb += self.cd_sys.clk.eq(clk18)

            platform.add_period_constraint(clk12_raw, 1e9/12e6)  # this is fixed and comes from external crystal

            # POR reset logic- POR generated from sys clk, POR logic feeds sys clk
            # reset. Just need a pulse one cycle wide to get things working right.
            # ^^^ this line is a lie. I have found devices that do not reliably reset with
            # one pulse. Extending the pulse to 2 wide seems to fix the issue.
            self.clock_domains.cd_por = ClockDomain()
            reset_cascade = Signal(reset=1)
            reset_cascade2 = Signal(reset=1)
            reset_initiator = Signal()
            self.sync.por += [
                reset_cascade.eq(reset_initiator),
                reset_cascade2.eq(reset_cascade),
            ]
            self.comb += [
                self.cd_por.clk.eq(self.cd_sys.clk),
                self.cd_sys.rst.eq(reset_cascade2),
            ]

            # generate a >1us-wide pulse at ~1Hz based on sysclk for display extcomm signal
            # count down from 12e6 to 0 so that first extcomm pulse comes after lcd_disp is high
            # note: going to a 25-bit counter makes this the critical path at speeds > 12 MHz, so stay with
            # 24 bits but a faster extcomm clock.
            extcomm = platform.request("extcommin", 0)
            extcomm_div = Signal(24, reset=int(12e6)) # datasheet range is 0.5Hz - 5Hz, so actual speed is 1.5Hz
            self.sync += [
                If(extcomm_div == 0,
                   extcomm_div.eq(int(12e6))
                ).Else(
                   extcomm_div.eq(extcomm_div - 1)
                ),

                If(extcomm_div < 13,
                   extcomm.eq(1)
                ).Else(
                   extcomm.eq(0)
                )
            ]
            self.comb += platform.request("lcd_disp", 0).eq(1)  # force display on for now

            ### WATCHDOG RESET, uses the extcomm_div divider to save on gates
            self.watchdog = CSRStorage(17, fields=[
                CSRField("reset_code", size=16, description="Write `600d` then `c0de` in sequence to this register to reset the watchdog timer"),
                CSRField("enable", description="Enable the watchdog timer. Cannot be disabled once enabled, except with a reset. Notably, a watchdog reset will disable the watchdog.", reset=0),
            ])
            wdog_enabled=Signal(reset=0)
            self.sync += [
                If(self.watchdog.fields.enable,
                    wdog_enabled.eq(1)
                ).Else(
                    wdog_enabled.eq(wdog_enabled)
                )
            ]
            wdog_cycle_r = Signal()
            wdog_cycle = Signal()
            self.sync += wdog_cycle_r.eq(extcomm)
            self.comb += wdog_cycle.eq(extcomm & ~wdog_cycle_r)
            wdog = FSM(reset_state="IDLE")
            self.submodules += wdog
            wdog.act("IDLE",
                If(wdog_enabled,
                    NextState("WAIT_ARM")
                )
            )
            wdog.act("WAIT_ARM",
                # sync up to the watchdog cycle so we give ourselves a full cycle to disarm the watchdog
                If(wdog_cycle,
                    NextState("ARMED")
                )
            )
            wdog.act("ARMED",
                If(wdog_cycle,
                    self.cd_sys.rst.eq(1),
                ),
                If(self.watchdog.re,
                    If(self.watchdog.fields.reset_code == 0x600d,
                        NextState("DISARM1")
                    )
                )
            )
            wdog.act("DISARM1",
                If(wdog_cycle,
                    self.cd_sys.rst.eq(1),
                ),
                If(self.watchdog.re,
                    If(self.watchdog.fields.reset_code == 0xc0de,
                       NextState("DISARMED")
                    ).Else(
                       NextState("ARMED")
                    )
                )
            )
            wdog.act("DISARMED",
                If(wdog_cycle,
                    NextState("ARMED")
                )
            )


            # make an 18 MHz clock for the SPI bus controller
            self.specials += Instance(
                "SB_PLL40_PAD",
                # Parameters
                p_DIVR = 0,
                p_DIVF = 47,
                p_DIVQ = 5,
                p_FILTER_RANGE = 1,
                p_FEEDBACK_PATH = "SIMPLE",
                p_DELAY_ADJUSTMENT_MODE_FEEDBACK = "FIXED",
                p_FDA_FEEDBACK = 0,
                p_DELAY_ADJUSTMENT_MODE_RELATIVE = "FIXED",
                p_FDA_RELATIVE = 0,
                p_SHIFTREG_DIV_MODE = 1,
                p_PLLOUT_SELECT = "GENCLK",
                p_ENABLE_ICEGATE = 0,
                # IO
                i_PACKAGEPIN = clk12_raw,
                o_PLLOUTGLOBAL = clk18,   # from PLL
                i_BYPASS = 0,
                i_RESETB = 1,
            )
            # global buffer for input SPI clock
            self.clock_domains.cd_spi_peripheral = ClockDomain()
            clk_spi_peripheral = Signal()
            self.comb += self.cd_spi_peripheral.clk.eq(clk_spi_peripheral)
            clk_spi_peripheral_pin = platform.request("com_sclk")

            self.specials += Instance(
                "SB_GB",
                i_USER_SIGNAL_TO_GLOBAL_BUFFER=clk_spi_peripheral_pin,
                o_GLOBAL_BUFFER_OUTPUT=clk_spi_peripheral,
            )
            platform.add_period_constraint(clk_spi_peripheral_pin, 1e9/20e6)  # 20 MHz according to Artix betrusted-soc config

            # Add a period constraint for each clock wire.
            # NextPNR picks the clock domain's name randomly from one of the wires
            # that it finds in the domain.  Migen passes the information on timing
            # to NextPNR in a file called `top_pre_pack.py`.  In order to ensure
            # it chooses the timing for this net, annotate period constraints for
            # all wires.
            platform.add_period_constraint(clk_spi_peripheral, 1e9/20e6)
            platform.add_period_constraint(clk18, 1e9/sysclkfreq)
            platform.add_period_constraint(self.cd_por.clk, 1e9/sysclkfreq)
Exemple #20
0
    def __init__(self,
                 platform,
                 debug,
                 variant=None,
                 cpu_cfu=None,
                 execute_from_lram=False,
                 separate_arena=False,
                 with_led_chaser=False,
                 integrated_rom_init=[],
                 build_bios=False,
                 cfu_mport=False,
                 dynamic_clock_control=False):
        LiteXSoC.__init__(self,
                          platform=platform,
                          sys_clk_freq=platform.sys_clk_freq,
                          csr_data_width=32)
        if variant == None:
            variant = "full+debug" if debug else "full"

        # Clock, Controller, CPU
        self.submodules.crg = platform.create_crg()
        self.add_controller("ctrl")
        if execute_from_lram:
            reset_address = 0x00000000
        else:
            reset_address = self.spiflash_region.origin + self.rom_offset
        self.add_cpu(self.cpu_type,
                     variant=variant,
                     reset_address=reset_address,
                     cfu=cpu_cfu)

        # RAM
        if separate_arena:
            ram_size = 64 * KB
            arena_size = RAM_SIZE - ram_size
        elif execute_from_lram:
            # Leave one LRAM free for ROM
            ram_size = RAM_SIZE - 64 * KB
            arena_size = 0
        else:
            ram_size = RAM_SIZE
            arena_size = 0
        self.setup_ram(size=ram_size)
        self.setup_arena(size=arena_size)

        # Dynamic clock control between CPU and CFU
        if dynamic_clock_control:
            # Add dynamic clock control logic
            from clock_control import CfuCpuClockCtrl
            self.submodules.cfu_cpu_clk_ctl = ClockDomainsRenamer("osc")(
                CfuCpuClockCtrl())
            cfu_cen = self.cfu_cpu_clk_ctl.cfu_cen
            cpu_cen = self.cfu_cpu_clk_ctl.cpu_cen
            ctl_cfu_bus = self.cfu_cpu_clk_ctl.cfu_bus
            cpu_cfu_bus = self.cpu.cfu_bus

            self.comb += [
                # Connect dynamic clock control bus to CPU <-> CFU BUS
                ctl_cfu_bus.rsp.valid.eq(cpu_cfu_bus.rsp.valid),
                ctl_cfu_bus.rsp.ready.eq(cpu_cfu_bus.rsp.ready),
                ctl_cfu_bus.cmd.valid.eq(cpu_cfu_bus.cmd.valid),
                ctl_cfu_bus.cmd.ready.eq(cpu_cfu_bus.cmd.ready),

                # Connect system clock to dynamic clock enable
                self.crg.sys_clk_enable.eq(cpu_cen),
            ]

            # Create separate clock for CFU
            clko = ClockSignal("cfu")
            self.clock_domains.cd_cfu = ClockDomain("cfu")
            self.specials += Instance(
                "DCC",
                i_CLKI=ClockSignal("osc"),
                o_CLKO=clko,
                i_CE=cfu_cen,
            )

            # Connect separate clock to CFU, keep reset from oscillator clock domain
            self.cpu.cfu_params.update(i_clk=clko)
            self.cpu.cfu_params.update(i_reset=ResetSignal("osc"))

            # Connect clock enable signals to RAM and Arena
            self.comb += [
                self.lram.a_clkens[i].eq(cpu_cen)
                for i in range(len(self.lram.a_clkens))
            ]
            if separate_arena:
                self.comb += [
                    self.arena.a_clkens[i].eq(cpu_cen)
                    for i in range(len(self.arena.a_clkens))
                ]
                if cfu_mport:
                    self.comb += [
                        self.arena.b_clkens[i].eq(cfu_cen)
                        for i in range(len(self.arena.b_clkens))
                    ]
        else:
            # If dynamic clock control is disabled, assert all memory clock enable signals
            self.comb += [
                self.lram.a_clkens[i].eq(1)
                for i in range(len(self.lram.a_clkens))
            ]
            if separate_arena:
                self.comb += [
                    self.arena.a_clkens[i].eq(1)
                    for i in range(len(self.arena.a_clkens))
                ]
                if cfu_mport:
                    self.comb += [
                        self.arena.b_clkens[i].eq(1)
                        for i in range(len(self.arena.b_clkens))
                    ]

        # Connect CFU directly to Arena LRAM memory
        if cfu_mport:
            self.connect_cfu_to_lram()

        # SPI Flash
        self.setup_litespi_flash()

        # ROM (either part of SPI Flash, or embedded)
        if execute_from_lram:
            self.setup_rom_in_lram()
            if integrated_rom_init:
                assert len(integrated_rom_init) <= 64 * KB / 4
                self.integrated_rom_initialized = True
                self.rom.add_init(integrated_rom_init)
        else:
            self.setup_rom_in_flash()

        # "LEDS" - Just one LED on JTAG port
        if with_led_chaser:
            self.submodules.leds = LedChaser(
                pads=platform.request_all("user_led"),
                sys_clk_freq=platform.sys_clk_freq)
            self.csr.add("leds")

        # UART
        self.add_serial()

        # Wishbone UART and CPU debug - JTAG must be disabled to use serial2
        if debug:
            self.add_uartbone("serial2", baudrate=UART_SPEED)
            self.bus.add_slave("vexriscv_debug", self.cpu.debug_bus,
                               self.vexriscv_region)

        if build_bios:
            # Timer (required for the BIOS build only)
            self.add_timer(name="timer0")
            self.timer0.add_uptime()
    def __init__(self, platform):
        clk48_raw = platform.request("clk48")
        clk12 = Signal()

        reset_delay = Signal(12, reset=4095)
        self.clock_domains.cd_por = ClockDomain()
        self.reset = Signal()

        self.clock_domains.cd_sys = ClockDomain()
        self.clock_domains.cd_usb_12 = ClockDomain()
        self.clock_domains.cd_usb_48 = ClockDomain()

        platform.add_period_constraint(self.cd_usb_48.clk, 1e9 / 48e6)
        platform.add_period_constraint(self.cd_sys.clk, 1e9 / 12e6)
        platform.add_period_constraint(self.cd_usb_12.clk, 1e9 / 12e6)
        platform.add_period_constraint(clk48_raw, 1e9 / 48e6)

        # POR reset logic- POR generated from sys clk, POR logic feeds sys clk
        # reset.
        self.comb += [
            self.cd_por.clk.eq(self.cd_sys.clk),
            self.cd_sys.rst.eq(reset_delay != 0),
            self.cd_usb_12.rst.eq(reset_delay != 0),
        ]

        # POR reset logic- POR generated from sys clk, POR logic feeds sys clk
        # reset.
        self.comb += [
            self.cd_usb_48.rst.eq(reset_delay != 0),
        ]

        self.comb += self.cd_usb_48.clk.eq(clk48_raw)

        self.specials += Instance(
            "SB_PLL40_CORE",
            # Parameters
            p_DIVR=0,
            p_DIVF=15,
            p_DIVQ=5,
            p_FILTER_RANGE=1,
            p_FEEDBACK_PATH="SIMPLE",
            p_DELAY_ADJUSTMENT_MODE_FEEDBACK="FIXED",
            p_FDA_FEEDBACK=15,
            p_DELAY_ADJUSTMENT_MODE_RELATIVE="FIXED",
            p_FDA_RELATIVE=0,
            p_SHIFTREG_DIV_MODE=1,
            p_PLLOUT_SELECT="GENCLK_HALF",
            p_ENABLE_ICEGATE=0,
            # IO
            i_REFERENCECLK=clk48_raw,
            o_PLLOUTCORE=clk12,
            # o_PLLOUTGLOBAL = clk12,
            #i_EXTFEEDBACK,
            #i_DYNAMICDELAY,
            #o_LOCK,
            i_BYPASS=0,
            i_RESETB=1,
            #i_LATCHINPUTVALUE,
            #o_SDO,
            #i_SDI,
        )

        self.comb += self.cd_sys.clk.eq(clk12)
        self.comb += self.cd_usb_12.clk.eq(clk12)

        self.sync.por += \
            If(reset_delay != 0,
                reset_delay.eq(reset_delay - 1)
            )
        self.specials += AsyncResetSynchronizer(self.cd_por, self.reset)
Exemple #22
0
    def __init__(self, cd_sys, platform, dw=64):
        self._reset = CSRStorage(reset=0)
        self._pcs_status = CSRStatus(fields=[
            CSRField("pcs_fault", size=1, offset=1),
            CSRField("pcs_fault_rx", size=1, offset=2),
            CSRField("pcs_fault_tx", size=1, offset=3),
        ])
        self._pcs_config = CSRStorage(reset=0, fields=[
            CSRField("pcs_clear", size=1, offset=0, pulse=True),
        ])


        self.clock_domains.cd_clkmgt = ClockDomain()

        self.tx_data = Signal(dw)
        self.tx_ctl = Signal(dw//8)

        self.rx_data = Signal(dw)
        self.rx_ctl = Signal(dw//8)
        self.pma_status = Signal(448)
        _pma_status = Signal(448)

        txusrclk = Signal()
        txusrclk2 = Signal()

        drp_req = Signal()

        drp_daddr_o = Signal(16)
        drp_den_o   = Signal()
        drp_di_o    = Signal(16)
        drp_dwe_o   = Signal()
        drp_drpdo_i = Signal(16)
        drp_drdy_i  = Signal()
        drp_den_i   = Signal()

        refclk_pads = platform.request("user_sma_mgt_refclk")
        rx_pads     = platform.request("sfp_rx")
        tx_pads     = platform.request("sfp_tx")
        self.tx_disable = Signal()
        self.qplllock   = Signal()
        self.gtrxreset  = Signal()
        self.gttxreset  = Signal()
        self.txusrrdy   = Signal()

        self.coreclk = Signal()

        self.comb += [
            platform.request("sfp_tx_disable_n").eq(~self.tx_disable),
        ]

        self.pcs_clear = pcs_clear = Signal()
        config_vector = Signal(536, reset=0)
        self.submodules.ps = PulseSynchronizer("sys", "clkmgt")
        self.pma_multi = pma_multi = Signal(3)
        self.specials += MultiReg(Cat(self.pma_status[250:252], self.pma_status[231]), pma_multi)
        self.comb += [
            self.ps.i.eq(self._pcs_config.fields.pcs_clear),
            pcs_clear.eq(self.ps.o),
            self._pcs_status.fields.pcs_fault_rx.eq(pma_multi[0]),
            self._pcs_status.fields.pcs_fault_tx.eq(pma_multi[1]),
            self._pcs_status.fields.pcs_fault.eq(pma_multi[2])
        ]

        self.comb += [
            ClockSignal("clkmgt").eq(self.coreclk)
        ]
        self.sync.clkmgt += [
            config_vector[517].eq(pcs_clear),
            self.pma_status.eq(_pma_status)
        ]

        self.specials += Instance(
            "ten_gig_eth_pcs_pma_0",
            i_refclk_p=refclk_pads.p,
            i_refclk_n=refclk_pads.n,
            i_reset=self._reset.storage,
            # o_resetdone_out=
            o_coreclk_out=self.coreclk,
            # rxrecclkout_0=rxrecclkout_0, # What is
            i_rxp=rx_pads.p,
            i_rxn=rx_pads.n,
            o_txp=tx_pads.p,
            o_txn=tx_pads.n,
            i_dclk=cd_sys.clk,
            i_sim_speedup_control=0,
            o_txusrclk_out=txusrclk,
            o_txusrclk2_out=txusrclk2,    # UltraScale only
            #o_areset_datapathclk_out=
            o_qplllock_out=self.qplllock,

            o_txuserrdy_out=self.txusrrdy,
            #o_reset_counter_done=,  # UltraScale only


            o_gttxreset_out=self.gttxreset,
            o_gtrxreset_out=self.gtrxreset, # TODO Set it to 5 seconds?

            o_xgmii_rxd=self.rx_data,
            o_xgmii_rxc=self.rx_ctl,
            i_xgmii_txd=self.tx_data,
            i_xgmii_txc=self.tx_ctl,

            i_configuration_vector=config_vector,
            o_status_vector=_pma_status,
            # o_core_status=,
            # tx_resetdone=,
            # rx_resetdone=,

            # Connects to sfp+
            i_signal_detect=1,
            i_tx_fault=0,  # Unused inside the core
            o_tx_disable=self.tx_disable,

            i_pma_pmd_type=0b111,

            # DRP Stuff
            o_drp_req=drp_req,
            i_drp_gnt=drp_req,

            o_drp_daddr_o=drp_daddr_o,
            o_drp_den_o=drp_den_o,
            o_drp_di_o=drp_di_o,
            o_drp_dwe_o=drp_dwe_o,
            i_drp_drpdo_i=drp_drpdo_i,
            i_drp_drdy_i=drp_drdy_i,

            i_drp_daddr_i=drp_daddr_o,
            i_drp_den_i=drp_den_o,
            i_drp_di_i=drp_di_o,
            i_drp_dwe_i=drp_dwe_o,
            o_drp_drpdo_o=drp_drpdo_i,
            o_drp_drdy_o=drp_drdy_i,
        )
        class Pads:
            rx = ClockSignal("clkmgt")
            rx_ctl = self.rx_ctl
            rx_data = self.rx_data
            tx = ClockSignal("clkmgt")
            tx_ctl = self.tx_ctl
            tx_data = self.tx_data
        self.pads = Pads()
Exemple #23
0
    def __init__(self, platform):
        self.clock_domains.cd_sys = ClockDomain()
        self.clock_domains.cd_sys4x = ClockDomain(reset_less=True)
        self.clock_domains.cd_sys4x_dqs = ClockDomain(reset_less=True)
        self.clock_domains.cd_clk200 = ClockDomain()
        self.clock_domains.cd_clk50 = ClockDomain()

        clk100 = platform.request("clk100")
        rst = ~platform.request("cpu_reset")

        pll_locked = Signal()
        pll_fb = Signal()
        self.pll_sys = Signal()
        pll_sys4x = Signal()
        pll_sys4x_dqs = Signal()
        pll_clk200 = Signal()
        pll_clk50 = Signal()
        self.specials += [
            Instance(
                "PLLE2_BASE",
                p_STARTUP_WAIT="FALSE",
                o_LOCKED=pll_locked,

                # VCO @ 1600 MHz
                p_REF_JITTER1=0.01,
                p_CLKIN1_PERIOD=10.0,
                p_CLKFBOUT_MULT=16,
                p_DIVCLK_DIVIDE=1,
                i_CLKIN1=clk100,
                i_CLKFBIN=pll_fb,
                o_CLKFBOUT=pll_fb,

                # 100 MHz
                p_CLKOUT0_DIVIDE=16,
                p_CLKOUT0_PHASE=0.0,
                o_CLKOUT0=self.pll_sys,

                # 400 MHz
                p_CLKOUT1_DIVIDE=4,
                p_CLKOUT1_PHASE=0.0,
                o_CLKOUT1=pll_sys4x,

                # 400 MHz dqs
                p_CLKOUT2_DIVIDE=4,
                p_CLKOUT2_PHASE=90.0,
                o_CLKOUT2=pll_sys4x_dqs,

                # 200 MHz
                p_CLKOUT3_DIVIDE=8,
                p_CLKOUT3_PHASE=0.0,
                o_CLKOUT3=pll_clk200,

                # 50MHz
                p_CLKOUT4_DIVIDE=32,
                p_CLKOUT4_PHASE=0.0,
                o_CLKOUT4=pll_clk50),
            Instance("BUFG", i_I=self.pll_sys, o_O=self.cd_sys.clk),
            Instance("BUFG", i_I=pll_sys4x, o_O=self.cd_sys4x.clk),
            Instance("BUFG", i_I=pll_sys4x_dqs, o_O=self.cd_sys4x_dqs.clk),
            Instance("BUFG", i_I=pll_clk200, o_O=self.cd_clk200.clk),
            Instance("BUFG", i_I=pll_clk50, o_O=self.cd_clk50.clk),
            AsyncResetSynchronizer(self.cd_sys, ~pll_locked | rst),
            AsyncResetSynchronizer(self.cd_clk200, ~pll_locked | rst),
            AsyncResetSynchronizer(self.cd_clk50, ~pll_locked | rst),
        ]

        reset_counter = Signal(4, reset=15)
        ic_reset = Signal(reset=1)
        self.sync.clk200 += \
            If(reset_counter != 0,
                reset_counter.eq(reset_counter - 1)
            ).Else(
                ic_reset.eq(0)
            )
        self.specials += Instance("IDELAYCTRL",
                                  i_REFCLK=ClockSignal("clk200"),
                                  i_RST=ic_reset)

        # For Arty, this is required in order to get a clock generated.  Otherwise,
        # there will be no carrier.
        if platform.device[:4] == "xc7a":
            eth_clk = Signal()
            self.specials += [
                Instance("BUFR",
                         p_BUFR_DIVIDE="4",
                         i_CE=1,
                         i_CLR=0,
                         i_I=clk100,
                         o_O=eth_clk),
                Instance("BUFG",
                         i_I=eth_clk,
                         o_O=platform.request("eth_ref_clk")),
            ]
Exemple #24
0
        def __logic__(self, platform):
            # signals for external connectivity
            clk_adc_pins = platform.request("clk125")
            platform.add_platform_command(
                "create_clock -name clk_adc -period 8 [get_ports {port}]",
                port=clk_adc_pins.p)  # xdc 208
            clk_adc_unbuffered = Signal()
            clk_adc_buffered = Signal()
            self.specials += Instance("IBUFGDS",
                                      i_I=clk_adc_pins.p,
                                      i_IB=clk_adc_pins.n,
                                      o_O=clk_adc_unbuffered)
            self.specials += Instance("BUFG",
                                      i_I=clk_adc_unbuffered,
                                      o_O=clk_adc_buffered)
            clk_feedback = Signal()
            clk_feedback_buffered = Signal()
            self.specials += Instance("BUFG",
                                      i_I=clk_feedback,
                                      o_O=clk_feedback_buffered)
            clk_adc = Signal()
            clk_dac_1p = Signal()
            clk_dac_2x = Signal()
            clk_dac_2p = Signal()
            clk_ser = Signal()
            clk_pwm = Signal()
            reset = Signal(reset=1)
            self.specials += [
                Instance(
                    "PLLE2_ADV",
                    p_BANDWIDTH="OPTIMIZED",
                    p_COMPENSATION="ZHOLD",
                    p_DIVCLK_DIVIDE=1,
                    p_CLKIN1_PERIOD=8.000,
                    p_REF_JITTER1=0.010,
                    i_RST=~reset,
                    i_CLKIN1=
                    clk_adc_unbuffered,  # top.v 314 uses unbuffered version
                    i_CLKIN2=0,
                    i_CLKINSEL=1,
                    i_PWRDWN=0,
                    p_CLKFBOUT_MULT=8,
                    p_CLKFBOUT_PHASE=0.0,
                    o_CLKFBOUT=clk_feedback,
                    i_CLKFBIN=clk_feedback_buffered,
                    o_LOCKED=self.locked,

                    # dynamic reconfiguration settings, all disabled
                    i_DADDR=0,
                    i_DCLK=0,
                    i_DEN=0,
                    i_DI=0,
                    i_DWE=0,
                    # o_DO=,
                    # o_DRDY=,
                    p_CLKOUT0_DIVIDE=8,  # 125 MHz
                    p_CLKOUT0_PHASE=0.0,
                    p_CLKOUT0_DUTY_CYCLE=0.5,
                    o_CLKOUT0=clk_adc,
                    p_CLKOUT1_DIVIDE=8,  # 125 MHz
                    p_CLKOUT1_PHASE=0.000,
                    p_CLKOUT1_DUTY_CYCLE=0.5,
                    o_CLKOUT1=clk_dac_1p,
                    p_CLKOUT2_DIVIDE=4,  # 250 MHz
                    p_CLKOUT2_PHASE=0.000,
                    p_CLKOUT2_DUTY_CYCLE=0.5,
                    o_CLKOUT2=clk_dac_2x,
                    p_CLKOUT3_DIVIDE=4,  # 250 MHz, 45 degree advanced
                    p_CLKOUT3_PHASE=-45.000,
                    p_CLKOUT3_DUTY_CYCLE=0.5,
                    o_CLKOUT3=clk_dac_2p,
                    p_CLKOUT4_DIVIDE=4,  # 250 MHz
                    p_CLKOUT4_PHASE=0.000,
                    p_CLKOUT4_DUTY_CYCLE=0.5,
                    o_CLKOUT4=clk_ser,
                    p_CLKOUT5_DIVIDE=4,  # 250 MHz
                    p_CLKOUT5_PHASE=0.000,
                    p_CLKOUT5_DUTY_CYCLE=0.5,
                    o_CLKOUT5=clk_pwm,
                )
            ]
            self.clock_domains.sys_ps = ClockDomain()
            self.clock_domains.clk_adc = ClockDomain()
            self.clock_domains.clk_dac_1p = ClockDomain(reset_less=True)
            self.clock_domains.clk_dac_2x = ClockDomain(reset_less=True)
            self.clock_domains.clk_dac_2p = ClockDomain(reset_less=True)
            self.clock_domains.clk_ser = ClockDomain(reset_less=True)
            self.clock_domains.clk_pwm = ClockDomain(reset_less=True)
            self.specials += Instance("BUFG",
                                      i_I=clk_adc,
                                      o_O=self.clk_adc.clk)
            self.specials += Instance("BUFG",
                                      i_I=clk_dac_1p,
                                      o_O=self.clk_dac_1p.clk)
            self.specials += Instance("BUFG",
                                      i_I=clk_dac_2x,
                                      o_O=self.clk_dac_2x.clk)
            self.specials += Instance("BUFG",
                                      i_I=clk_dac_2p,
                                      o_O=self.clk_dac_2p.clk)
            self.specials += Instance("BUFG",
                                      i_I=clk_ser,
                                      o_O=self.clk_ser.clk)
            self.specials += Instance("BUFG",
                                      i_I=clk_pwm,
                                      o_O=self.clk_pwm.clk)
            self.specials += Instance(
                "FD",
                p_INIT=1,
                i_D=~self.locked,
                i_C=self.clk_adc.clk,
                o_Q=self.clk_adc.rst,
            )
    def init_submodules(
        self, width, signal_width, coeff_width, chain_factor_bits, platform
    ):
        sys_double = ClockDomainsRenamer("sys_double")

        self.submodules.logic = LinienLogic(chain_factor_width=chain_factor_bits)
        self.submodules.analog = PitayaAnalog(
            platform.request("adc"), platform.request("dac")
        )
        self.submodules.xadc = XADC(platform.request("xadc"))

        for i in range(4):
            pwm = platform.request("pwm", i)
            ds = sys_double(DeltaSigma(width=15))
            self.comb += pwm.eq(ds.out)
            setattr(self.submodules, "ds%i" % i, ds)

        exp = platform.request("exp")
        self.submodules.gpio_n = Gpio(exp.n)
        self.submodules.gpio_p = Gpio(exp.p)

        leds = Cat(*(platform.request("user_led", i) for i in range(8)))
        self.comb += leds.eq(self.gpio_n.o)

        self.submodules.dna = DNA(version=2)

        self.submodules.fast_a = FastChain(
            width,
            signal_width,
            coeff_width,
            self.logic.mod,
            offset_signal=self.logic.chain_a_offset_signed,
        )
        self.submodules.fast_b = FastChain(
            width,
            signal_width,
            coeff_width,
            self.logic.mod,
            offset_signal=self.logic.chain_b_offset_signed,
        )

        sys_slow = ClockDomainsRenamer("sys_slow")
        sys_double = ClockDomainsRenamer("sys_double")
        max_decimation = 16
        self.submodules.decimate = sys_double(Decimate(max_decimation))
        self.clock_domains.cd_decimated_clock = ClockDomain()
        decimated_clock = ClockDomainsRenamer("decimated_clock")
        self.submodules.slow = decimated_clock(SlowChain())

        self.submodules.scopegen = ScopeGen(signal_width)

        self.state_names, self.signal_names = cross_connect(
            self.gpio_n,
            [
                ("fast_a", self.fast_a),
                ("fast_b", self.fast_b),
                ("slow", self.slow),
                ("scopegen", self.scopegen),
                ("logic", self.logic),
                ("robust", self.logic.autolock.robust),
            ],
        )

        csr_map = {
            "dna": 28,
            "xadc": 29,
            "gpio_n": 30,
            "gpio_p": 31,
            "fast_a": 0,
            "fast_b": 1,
            "slow": 2,
            "scopegen": 6,
            "noise": 7,
            "logic": 8,
        }

        self.submodules.csrbanks = csr_bus.CSRBankArray(
            self,
            lambda name, mem: csr_map[
                name if mem is None else name + "_" + mem.name_override
            ],
        )
        self.submodules.sys2csr = Sys2CSR()
        self.submodules.csrcon = csr_bus.Interconnect(
            self.sys2csr.csr, self.csrbanks.get_buses()
        )
        self.submodules.syscdc = SysCDC()
        self.comb += self.syscdc.target.connect(self.sys2csr.sys)
Exemple #26
0
        def __init__(self, platform):
            clk12_raw = platform.request("clk12")
            clk18 = Signal()

            self.clock_domains.cd_sys = ClockDomain()
            self.comb += self.cd_sys.clk.eq(clk18)

            platform.add_period_constraint(
                clk12_raw,
                1e9 / 12e6)  # this is fixed and comes from external crystal

            # POR reset logic- POR generated from sys clk, POR logic feeds sys clk
            # reset. Just need a pulse one cycle wide to get things working right.
            self.clock_domains.cd_por = ClockDomain()
            reset_cascade = Signal(reset=1)
            reset_initiator = Signal()
            self.sync.por += [reset_cascade.eq(reset_initiator)]
            self.comb += [
                self.cd_por.clk.eq(self.cd_sys.clk),
                self.cd_sys.rst.eq(reset_cascade),
            ]

            # generate a >1us-wide pulse at ~1Hz based on sysclk for display extcomm signal
            # count down from 12e6 to 0 so that first extcomm pulse comes after lcd_disp is high
            # note: going to a 25-bit counter makes this the critical path at speeds > 12 MHz, so stay with
            # 24 bits but a faster extcomm clock.
            extcomm = platform.request("extcommin", 0)
            extcomm_div = Signal(
                24, reset=int(12e6)
            )  # datasheet range is 0.5Hz - 5Hz, so actual speed is 1.5Hz
            self.sync += [
                If(extcomm_div == 0, extcomm_div.eq(int(12e6))).Else(
                    extcomm_div.eq(extcomm_div - 1)),
                If(extcomm_div < 13, extcomm.eq(1)).Else(extcomm.eq(0))
            ]
            self.comb += platform.request("lcd_disp",
                                          0).eq(1)  # force display on for now

            # make an 18 MHz clock for the SPI bus controller
            self.specials += Instance(
                "SB_PLL40_PAD",
                # Parameters
                p_DIVR=0,
                p_DIVF=47,
                p_DIVQ=5,
                p_FILTER_RANGE=1,
                p_FEEDBACK_PATH="SIMPLE",
                p_DELAY_ADJUSTMENT_MODE_FEEDBACK="FIXED",
                p_FDA_FEEDBACK=0,
                p_DELAY_ADJUSTMENT_MODE_RELATIVE="FIXED",
                p_FDA_RELATIVE=0,
                p_SHIFTREG_DIV_MODE=1,
                p_PLLOUT_SELECT="GENCLK",
                p_ENABLE_ICEGATE=0,
                # IO
                i_PACKAGEPIN=clk12_raw,
                o_PLLOUTGLOBAL=clk18,  # from PLL
                i_BYPASS=0,
                i_RESETB=1,
            )
            # global buffer for input SPI clock
            self.clock_domains.cd_spi_peripheral = ClockDomain()
            clk_spi_peripheral = Signal()
            self.comb += self.cd_spi_peripheral.clk.eq(clk_spi_peripheral)
            clk_spi_peripheral_pin = platform.request("com_sclk")

            self.specials += Instance(
                "SB_GB",
                i_USER_SIGNAL_TO_GLOBAL_BUFFER=clk_spi_peripheral_pin,
                o_GLOBAL_BUFFER_OUTPUT=clk_spi_peripheral,
            )
            platform.add_period_constraint(
                clk_spi_peripheral_pin,
                1e9 / 20e6)  # 20 MHz according to Artix betrusted-soc config

            # Add a period constraint for each clock wire.
            # NextPNR picks the clock domain's name randomly from one of the wires
            # that it finds in the domain.  Migen passes the information on timing
            # to NextPNR in a file called `top_pre_pack.py`.  In order to ensure
            # it chooses the timing for this net, annotate period constraints for
            # all wires.
            platform.add_period_constraint(clk_spi_peripheral, 1e9 / 20e6)
            platform.add_period_constraint(clk18, 1e9 / sysclkfreq)