gw: finish CDC sampler module
Just need to hook this into the FIFO I made before, and write all the peak detection, triggering, and trigger enable logic, + hook everything into a single wishbone address space.
This commit is contained in:
parent
0bf6c2336c
commit
39b5dd7193
@ -37,6 +37,7 @@ class _CRG(Module):
|
|||||||
def __init__(self, platform, sys_clk_freq, use_internal_osc=False, with_usb_pll=False, with_video_pll=False, sdram_rate="1:1"):
|
def __init__(self, platform, sys_clk_freq, use_internal_osc=False, with_usb_pll=False, with_video_pll=False, sdram_rate="1:1"):
|
||||||
self.rst = Signal()
|
self.rst = Signal()
|
||||||
self.clock_domains.cd_sys = ClockDomain()
|
self.clock_domains.cd_sys = ClockDomain()
|
||||||
|
self.clock_domains.cd_sample_clock = ClockDomain("sample_clock")
|
||||||
if sdram_rate == "1:2":
|
if sdram_rate == "1:2":
|
||||||
self.clock_domains.cd_sys2x = ClockDomain()
|
self.clock_domains.cd_sys2x = ClockDomain()
|
||||||
self.clock_domains.cd_sys2x_ps = ClockDomain()
|
self.clock_domains.cd_sys2x_ps = ClockDomain()
|
||||||
@ -75,6 +76,9 @@ class _CRG(Module):
|
|||||||
sdram_clk = ClockSignal("sys2x_ps" if sdram_rate == "1:2" else "sys_ps")
|
sdram_clk = ClockSignal("sys2x_ps" if sdram_rate == "1:2" else "sys_ps")
|
||||||
self.specials += DDROutput(1, 0, platform.request("sdram_clock"), sdram_clk)
|
self.specials += DDROutput(1, 0, platform.request("sdram_clock"), sdram_clk)
|
||||||
|
|
||||||
|
# Sampler clock
|
||||||
|
pll.create_clkout(self.cd_sample_clock, int(10e6))
|
||||||
|
|
||||||
# BaseSoC ------------------------------------------------------------------------------------------
|
# BaseSoC ------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
# TODO make my own platform for this based on the colorlight one, so I can export I2C and other pins
|
# TODO make my own platform for this based on the colorlight one, so I can export I2C and other pins
|
||||||
@ -138,7 +142,7 @@ class BaseSoC(SoCCore):
|
|||||||
if with_video_framebuffer:
|
if with_video_framebuffer:
|
||||||
self.add_video_framebuffer(phy=self.videophy, timings="800x600@60Hz", clock_domain="hdmi")
|
self.add_video_framebuffer(phy=self.videophy, timings="800x600@60Hz", clock_domain="hdmi")
|
||||||
|
|
||||||
self.submodules.sampler = Sampler(platform.request("adc"))
|
self.submodules.sampler = Sampler(platform.request("adc"), self.crg.cd_sample_clock.clk)
|
||||||
sampler_region = SoCRegion(origin=None, size=0x1000, cached=False)
|
sampler_region = SoCRegion(origin=None, size=0x1000, cached=False)
|
||||||
#self.add_wb_slave(0x9000_0000, self.sampler.bus, 0x1000)
|
#self.add_wb_slave(0x9000_0000, self.sampler.bus, 0x1000)
|
||||||
# TODO better way to do this?
|
# TODO better way to do this?
|
||||||
|
@ -109,17 +109,35 @@ class CircularBuffer(Module):
|
|||||||
wr_ptr.eq(0), rd_ptr.eq(0), empty.eq(1))
|
wr_ptr.eq(0), rd_ptr.eq(0), empty.eq(1))
|
||||||
|
|
||||||
|
|
||||||
|
from migen.genlib.cdc import PulseSynchronizer
|
||||||
|
|
||||||
|
|
||||||
class Sampler(Module):
|
class Sampler(Module):
|
||||||
def __init__(self, adc_pins):
|
def __init__(self, adc_pins: Record, sampler_clock: Signal):
|
||||||
# TODO correct addr width
|
# TODO correct addr width
|
||||||
self.bus = Interface(data_width=32, adr_width=11)
|
self.bus = Interface(data_width=32, adr_width=11)
|
||||||
|
|
||||||
# self.clock_domains.foo = ClockDomain() is how to add a new clock domain, accessible at self.foo
|
# self.clock_domains.foo = ClockDomain() is how to add a new clock domain, accessible at self.foo
|
||||||
|
# Connect sampler clock domain
|
||||||
|
self.clock_domains.sample_clock = ClockDomain("sample_clock")
|
||||||
|
self.comb += self.sample_clock.clk.eq(sampler_clock)
|
||||||
|
|
||||||
# Provide a slow clock to the ADC, 60MHz / 600 = 100kHz
|
# Hook up ADC REFCLK to sample_clock
|
||||||
self._counter = Signal(32)
|
self.comb += adc_pins.refclk.eq(sampler_clock)
|
||||||
self.sync += self._counter.eq(self._counter + 1)
|
|
||||||
self.sync += If(self._counter >= 600, self._counter.eq(0), adc_pins.refclk.eq(~adc_pins.refclk))
|
# We can synchronize to the sampler clock, whenever it goes high we can
|
||||||
|
# strobe a single valid signal
|
||||||
|
synchronizer = PulseSynchronizer("sample_clock", "sys")
|
||||||
|
self.submodules += synchronizer
|
||||||
|
|
||||||
|
self.valid = Signal()
|
||||||
|
self.data = Signal(10)
|
||||||
|
|
||||||
|
self.comb += [
|
||||||
|
synchronizer.i.eq(self.sample_clock.clk),
|
||||||
|
self.valid.eq(synchronizer.o),
|
||||||
|
self.data.eq(adc_pins.data),
|
||||||
|
]
|
||||||
|
|
||||||
# Set config pins to constant values
|
# Set config pins to constant values
|
||||||
self.comb += adc_pins.oen_b.eq(0) # Data pins enable
|
self.comb += adc_pins.oen_b.eq(0) # Data pins enable
|
||||||
@ -128,7 +146,7 @@ class Sampler(Module):
|
|||||||
# The only remaining pin, OTR, is an out of range status indicator
|
# The only remaining pin, OTR, is an out of range status indicator
|
||||||
|
|
||||||
# Read directly from the data pins into the wishbone bus for now, just for bringup
|
# Read directly from the data pins into the wishbone bus for now, just for bringup
|
||||||
self.comb += self.bus.dat_r.eq(adc_pins.data)
|
self.sync += If(self.valid, self.bus.dat_r.eq(adc_pins.data))
|
||||||
self.sync += self.bus.ack.eq(0)
|
self.sync += self.bus.ack.eq(0)
|
||||||
self.sync += If(self.bus.cyc & self.bus.stb, self.bus.ack.eq(1))
|
self.sync += If(self.bus.cyc & self.bus.stb, self.bus.ack.eq(1))
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user