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), ]
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), ) ]
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())
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)
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)
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))
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)
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)
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)
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")
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")
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())
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), ]
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)
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)
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()
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")), ]
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)
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)