diff --git a/src/gateware/si549.py b/src/gateware/si549.py deleted file mode 100644 index 3ae8948..0000000 --- a/src/gateware/si549.py +++ /dev/null @@ -1,277 +0,0 @@ -from migen import * -from migen.genlib.fsm import * - -from misoc.interconnect.csr import * - - -class I2CClockGen(Module): - def __init__(self, width): - self.load = Signal(width) - self.clk2x = Signal() - - cnt = Signal.like(self.load) - self.comb += [ - self.clk2x.eq(cnt == 0), - ] - self.sync += [ - If(self.clk2x, - cnt.eq(self.load), - ).Else( - cnt.eq(cnt - 1), - ) - ] - - -class I2CMasterMachine(Module): - def __init__(self, clock_width): - self.scl = Signal(reset=1) - self.sda_o = Signal(reset=1) - self.sda_i = Signal() - - self.submodules.cg = CEInserter()(I2CClockGen(clock_width)) - self.start = Signal() - self.stop = Signal() - self.write = Signal() - self.ack = Signal() - self.data = Signal(8) - self.ready = Signal() - - # # # - - bits = Signal(4) - data = Signal(8) - - fsm = CEInserter()(FSM("IDLE")) - self.submodules += fsm - - fsm.act("IDLE", - self.ready.eq(1), - If(self.start, - NextState("START0"), - ).Elif(self.stop, - NextState("STOP0"), - ).Elif(self.write, - NextValue(bits, 8), - NextValue(data, self.data), - NextState("WRITE0") - ) - ) - - fsm.act("START0", - NextValue(self.scl, 1), - NextState("START1") - ) - fsm.act("START1", - NextValue(self.sda_o, 0), - NextState("IDLE") - ) - - fsm.act("STOP0", - NextValue(self.scl, 0), - NextState("STOP1") - ) - fsm.act("STOP1", - NextValue(self.sda_o, 0), - NextState("STOP2") - ) - fsm.act("STOP2", - NextValue(self.scl, 1), - NextState("STOP3") - ) - fsm.act("STOP3", - NextValue(self.sda_o, 1), - NextState("IDLE") - ) - - fsm.act("WRITE0", - NextValue(self.scl, 0), - NextState("WRITE1") - ) - fsm.act("WRITE1", - If(bits == 0, - NextValue(self.sda_o, 1), - NextState("READACK0"), - ).Else( - NextValue(self.sda_o, data[7]), - NextState("WRITE2"), - ) - ) - fsm.act("WRITE2", - NextValue(self.scl, 1), - NextValue(data[1:], data[:-1]), - NextValue(bits, bits - 1), - NextState("WRITE0"), - ) - fsm.act("READACK0", - NextValue(self.scl, 1), - NextState("READACK1"), - ) - fsm.act("READACK1", - NextValue(self.ack, ~self.sda_i), - NextState("IDLE") - ) - - run = Signal() - idle = Signal() - self.comb += [ - run.eq((self.start | self.stop | self.write) & self.ready), - idle.eq(~run & fsm.ongoing("IDLE")), - self.cg.ce.eq(~idle), - fsm.ce.eq(run | self.cg.clk2x), - ] - - -class ADPLLProgrammer(Module): - def __init__(self): - self.i2c_divider = Signal(16) - self.i2c_address = Signal(7) - - self.adpll = Signal(24) - self.stb = Signal() - self.busy = Signal() - self.nack = Signal() - - self.scl = Signal() - self.sda_i = Signal() - self.sda_o = Signal() - - # # # - - master = I2CMasterMachine(16) - self.submodules += master - - self.comb += [ - master.cg.load.eq(self.i2c_divider), - self.scl.eq(master.scl), - master.sda_i.eq(self.sda_i), - self.sda_o.eq(master.sda_o) - ] - - fsm = FSM() - self.submodules += fsm - - fsm.act("IDLE", - If(self.stb, - NextValue(self.nack, 0), - NextState("START") - ) - ) - fsm.act("START", - master.start.eq(1), - If(master.ready, NextState("DEVADDRESS")) - ) - fsm.act("DEVADDRESS", - master.data.eq(self.i2c_address << 1), - master.write.eq(1), - If(master.ready, NextState("REGADRESS")) - ) - fsm.act("REGADRESS", - master.data.eq(231), - master.write.eq(1), - If(master.ready, - If(master.ack, - NextState("DATA0") - ).Else( - NextValue(self.nack, 1), - NextState("STOP") - ) - ) - ) - fsm.act("DATA0", - master.data.eq(self.adpll[0:8]), - master.write.eq(1), - If(master.ready, - If(master.ack, - NextState("DATA1") - ).Else( - NextValue(self.nack, 1), - NextState("STOP") - ) - ) - ) - fsm.act("DATA1", - master.data.eq(self.adpll[8:16]), - master.write.eq(1), - If(master.ready, - If(master.ack, - NextState("DATA2") - ).Else( - NextValue(self.nack, 1), - NextState("STOP") - ) - ) - ) - fsm.act("DATA2", - master.data.eq(self.adpll[16:24]), - master.write.eq(1), - If(master.ready, - If(~master.ack, NextValue(self.nack, 1)), - NextState("STOP") - ) - ) - fsm.act("STOP", - master.stop.eq(1), - If(master.ready, - If(~master.ack, NextValue(self.nack, 1)), - NextState("IDLE") - ) - ) - - self.comb += self.busy.eq(~fsm.ongoing("IDLE")) - - -class Si549(Module, AutoCSR): - def __init__(self, pads): - self.i2c_divider = CSRStorage(16, reset=75) - self.i2c_address = CSRStorage(7) - - self.adpll = CSRStorage(24) - self.adpll_stb = CSR() - self.adpll_busy = CSRStatus() - self.nack = CSRStatus() - - self.bitbang_enable = CSRStorage() - - self.sda_oe = CSRStorage() - self.sda_out = CSRStorage() - self.sda_in = CSRStatus() - self.scl_oe = CSRStorage() - self.scl_out = CSRStorage() - - # # # - - self.submodules.programmer = ADPLLProgrammer() - - self.sync += self.programmer.stb.eq(self.adpll_stb.re) - - self.comb += [ - self.programmer.i2c_divider.eq(self.i2c_divider.storage), - self.programmer.i2c_address.eq(self.i2c_address.storage), - self.programmer.adpll.eq(self.adpll.storage), - self.adpll_busy.status.eq(self.programmer.busy), - self.nack.status.eq(self.programmer.nack) - ] - - # I2C with bitbang/gateware mode select - sda_t = TSTriple(1) - scl_t = TSTriple(1) - self.specials += [ - sda_t.get_tristate(pads.sda), - scl_t.get_tristate(pads.scl) - ] - - self.comb += [ - If(self.bitbang_enable.storage, - sda_t.oe.eq(self.sda_oe.storage), - sda_t.o.eq(self.sda_out.storage), - self.sda_in.status.eq(sda_t.i), - scl_t.oe.eq(self.scl_oe.storage), - scl_t.o.eq(self.scl_out.storage) - ).Else( - sda_t.oe.eq(~self.programmer.sda_o), - sda_t.o.eq(0), - self.programmer.sda_i.eq(sda_t.i), - scl_t.oe.eq(~self.programmer.scl), - scl_t.o.eq(0), - ) - ] \ No newline at end of file diff --git a/src/gateware/wrpll.py b/src/gateware/wrpll.py deleted file mode 100644 index aaf604b..0000000 --- a/src/gateware/wrpll.py +++ /dev/null @@ -1,237 +0,0 @@ -from migen import * -from migen.genlib.cdc import MultiReg, AsyncResetSynchronizer, PulseSynchronizer -from misoc.interconnect.csr import * -from misoc.interconnect.csr_eventmanager import * - -from ddmtd import DDMTDSampler, DDMTD -from si549 import Si549 - -class FrequencyCounter(Module, AutoCSR): - def __init__(self, domains, counter_width=24): - self.update = CSR() - self.busy = CSRStatus() - - counter_reset = Signal() - counter_stb = Signal() - timer = Signal(counter_width) - - # # # - - fsm = FSM() - self.submodules += fsm - - fsm.act("IDLE", - counter_reset.eq(1), - If(self.update.re, - NextValue(timer, 2**counter_width - 1), - NextState("COUNTING") - ) - ) - fsm.act("COUNTING", - self.busy.status.eq(1), - If(timer != 0, - NextValue(timer, timer - 1) - ).Else( - counter_stb.eq(1), - NextState("IDLE") - ) - ) - - for domain in domains: - name = "counter_" + domain - counter_csr = CSRStatus(counter_width, name=name) - setattr(self, name, counter_csr) - - divider = Signal(2) - divided = Signal() - divided_sys = Signal() - divided_sys_r = Signal() - divided_tick = Signal() - counter = Signal(counter_width) - - # # # - - sync_domain = getattr(self.sync, domain) - sync_domain +=[ - divider.eq(divider + 1), - divided.eq(divider[-1]) - ] - self.specials += MultiReg(divided, divided_sys) - self.sync += divided_sys_r.eq(divided_sys) - self.comb += divided_tick.eq(divided_sys & ~divided_sys_r) - - self.sync += [ - If(counter_stb, counter_csr.status.eq(counter)), - If(divided_tick, counter.eq(counter + 1)), - If(counter_reset, counter.eq(0)) - ] - -class SkewTester(Module, AutoCSR): - def __init__(self, rx_synchronizer): - self.error = CSR() - - # # # - - # The RX synchronizer is tested for setup/hold violations by feeding it a - # toggling pattern and checking that the same toggling pattern comes out. - toggle_in = Signal() - self.sync.rtio_rx0 += toggle_in.eq(~toggle_in) - toggle_out = rx_synchronizer.resync(toggle_in) - - toggle_out_expected = Signal() - self.sync += toggle_out_expected.eq(~toggle_out) - - error = Signal() - self.sync += [ - If(toggle_out != toggle_out_expected, error.eq(1)), - If(self.error.re, error.eq(0)) - ] - self.specials += MultiReg(error, self.error.w) - - -class WRPLL(Module, AutoCSR): - def __init__(self, platform, cd_ref, main_clk_se, COUNTER_BIT=32): - self.helper_reset = CSRStorage(reset=1) - self.ref_tag = CSRStatus(COUNTER_BIT) - self.main_tag = CSRStatus(COUNTER_BIT) - - ddmtd_counter = Signal(COUNTER_BIT) - - ref_tag_sys = Signal(COUNTER_BIT) - main_tag_sys = Signal(COUNTER_BIT) - ref_tag_stb_sys = Signal() - main_tag_stb_sys = Signal() - - # # # - - self.submodules.main_dcxo = Si549(platform.request("ddmtd_main_dcxo_i2c")) - self.submodules.helper_dcxo = Si549(platform.request("ddmtd_helper_dcxo_i2c")) - - helper_dcxo_pads = platform.request("ddmtd_helper_clk") - self.clock_domains.cd_helper = ClockDomain() - self.specials += [ - Instance("IBUFGDS", - i_I=helper_dcxo_pads.p, i_IB=helper_dcxo_pads.n, - o_O=self.cd_helper.clk), - AsyncResetSynchronizer(self.cd_helper, self.helper_reset.storage) - ] - - self.submodules.frequency_counter = FrequencyCounter(["sys", cd_ref.name]) - - self.submodules.ddmtd_sampler = DDMTDSampler(cd_ref, main_clk_se) - - self.sync.helper += ddmtd_counter.eq(ddmtd_counter + 1) - self.submodules.ddmtd_ref = DDMTD(ddmtd_counter, self.ddmtd_sampler.ref_beating) - self.submodules.ddmtd_main = DDMTD(ddmtd_counter, self.ddmtd_sampler.main_beating) - - # DDMTD tags collection - - self.specials += [ - MultiReg(self.ddmtd_ref.h_tag, ref_tag_sys), - MultiReg(self.ddmtd_main.h_tag, main_tag_sys) - ] - - ref_tag_stb_ps = PulseSynchronizer("helper", "sys") - main_tag_stb_ps = PulseSynchronizer("helper", "sys") - self.submodules += [ - ref_tag_stb_ps, - main_tag_stb_ps - ] - self.sync.helper += [ - ref_tag_stb_ps.i.eq(self.ddmtd_ref.h_tag_update), - main_tag_stb_ps.i.eq(self.ddmtd_main.h_tag_update) - ] - self.sync += [ - ref_tag_stb_sys.eq(ref_tag_stb_ps.o), - main_tag_stb_sys.eq(main_tag_stb_ps.o) - ] - - self.sync += [ - If(ref_tag_stb_sys, - self.ref_tag.status.eq(ref_tag_sys), - ), - If(main_tag_stb_sys, - self.main_tag.status.eq(main_tag_sys) - ) - ] - - # EventMangers for firmware interrupt - - self.submodules.ref_tag_ev = EventManager() - self.ref_tag_ev.stb = EventSourcePulse() - self.ref_tag_ev.finalize() - - self.submodules.main_tag_ev = EventManager() - self.main_tag_ev.stb = EventSourcePulse() - self.main_tag_ev.finalize() - - self.sync += [ - self.ref_tag_ev.stb.trigger.eq(ref_tag_stb_sys), - self.main_tag_ev.stb.trigger.eq(main_tag_stb_sys) - ] - - self.submodules.ev = SharedIRQ(self.ref_tag_ev, self.main_tag_ev) - - -class SMAFrequencyMultiplier(Module, AutoCSR): - def __init__(self, sma_clkin): - sma_clkin_se = Signal() - mmcm_locked = Signal() - mmcm_fb_clk = Signal() - ref_clk = Signal() - self.clock_domains.cd_ref = ClockDomain() - self.refclk_reset = CSRStorage(reset=1) - - self.mmcm_bypass = CSRStorage() - self.mmcm_locked = CSRStatus() - self.mmcm_reset = CSRStorage(reset=1) - - self.mmcm_daddr = CSRStorage(7) - self.mmcm_din = CSRStorage(16) - self.mmcm_dwen = CSRStorage() - self.mmcm_den = CSRStorage() - self.mmcm_dclk = CSRStorage() - self.mmcm_dout = CSRStatus(16) - self.mmcm_dready = CSRStatus() - - # # # - - self.specials += [ - Instance("IBUFDS", - i_I=sma_clkin.p, i_IB=sma_clkin.n, - o_O=sma_clkin_se), - # MMCME2 is capable to accept 10MHz input while PLLE2 only support down to 19MHz input (DS191) - # The MMCME2 can be reconfiged during runtime using the Dynamic Reconfiguration Ports - Instance("MMCME2_ADV", - p_BANDWIDTH="HIGH", # lower output jitter (see https://support.xilinx.com/s/question/0D52E00006iHqRqSAK) - o_LOCKED=self.mmcm_locked.status, - i_RST=self.mmcm_reset.storage, - - p_CLKIN1_PERIOD=8, # ns - i_CLKIN1=sma_clkin_se, - i_CLKINSEL=1, # 1=CLKIN1 0=CLKIN2 - - # VCO @ 1.25GHz - p_CLKFBOUT_MULT_F=10, p_DIVCLK_DIVIDE=1, - i_CLKFBIN=mmcm_fb_clk, o_CLKFBOUT=mmcm_fb_clk, - - # 125MHz for WRPLL - p_CLKOUT0_DIVIDE_F=10, p_CLKOUT0_PHASE=0.0, o_CLKOUT0=ref_clk, - - # Dynamic Reconfiguration Ports - i_DADDR = self.mmcm_daddr.storage, - i_DI = self.mmcm_din.storage, - i_DWE = self.mmcm_dwen.storage, - i_DEN = self.mmcm_den.storage, - i_DCLK = self.mmcm_dclk.storage, - o_DO = self.mmcm_dout.status, - o_DRDY = self.mmcm_dready.status - ), - Instance("BUFGMUX", - i_I0=ref_clk, - i_I1=sma_clkin_se, - i_S=self.mmcm_bypass.storage, - o_O=self.cd_ref.clk - ), - AsyncResetSynchronizer(self.cd_ref, self.refclk_reset.storage), - ]