diff --git a/gateware/litex_main.py b/gateware/litex_main.py index 8a11a18..42c5d43 100755 --- a/gateware/litex_main.py +++ b/gateware/litex_main.py @@ -27,7 +27,7 @@ from litedram.phy import GENSDRPHY, HalfRateGENSDRPHY from liteeth.phy.ecp5rgmii import LiteEthPHYRGMII -from sampler import Sampler +from sampler import SamplerController, Sampler from litex.soc.integration.soc import SoCRegion from test import run_test, TestResult, skip_suite @@ -143,11 +143,11 @@ class BaseSoC(SoCCore): if with_video_framebuffer: self.add_video_framebuffer(phy=self.videophy, timings="800x600@60Hz", clock_domain="hdmi") - self.submodules.sampler = Sampler(platform.request("adc"), self.crg.cd_sample_clock.clk) - sampler_region = SoCRegion(origin=None, size=0x1000, cached=False) - #self.add_wb_slave(0x9000_0000, self.sampler.bus, 0x1000) - ## TODO better way to do this? - #self.bus.add_slave(name="sampler", slave=self.sampler.bus, region=sampler_region) + #samplers = [Sampler(platform.request("adc", i)) for i in range(3)] + #self.submodules.sampler_controller = SamplerController(samplers, buffer_len=2048 * 10) + ### TODO better way to do this? + #sampler_region = SoCRegion(origin=None, size=0x4000, cached=False) + #self.bus.add_slave(name="sampler", slave=self.sampler_controller.bus, region=sampler_region) # Build -------------------------------------------------------------------------------------------- @@ -200,8 +200,9 @@ def main(): print(f"{passed}/{passed + failed} passed ({skipped} skipped)") - # TODO maybe don't do this? - return + if failed > 0 or not args.build: + # Don't also build after this + return # Build firmware import subprocess as sp diff --git a/gateware/platforms/sonar.py b/gateware/platforms/sonar.py index 0232783..135011d 100644 --- a/gateware/platforms/sonar.py +++ b/gateware/platforms/sonar.py @@ -175,9 +175,7 @@ _io_v7_2 = copy.deepcopy(_io_v7_0) for i, x in enumerate(_io_v7_2): if x[:2] == ("user_led_n", 0): - # TODO fix in HW - #_io_v7_2[i] = ("user_led_n", 0, Pins("L2"), IOStandard("LVCMOS33")) - _io_v7_2[i] = ("user_led_n", 0, Pins("J19"), IOStandard("LVCMOS33")) + _io_v7_2[i] = ("user_led_n", 0, Pins("L2"), IOStandard("LVCMOS33")) break # optional, alternative uart location diff --git a/gateware/sampler/circular_buffer.py b/gateware/sampler/circular_buffer.py index 513e07b..062a446 100644 --- a/gateware/sampler/circular_buffer.py +++ b/gateware/sampler/circular_buffer.py @@ -34,14 +34,23 @@ class CircularBuffer(Module): rd_ptr = Signal(ptr_width) empty = Signal(reset=1) # Extra signal to distinguish between full and empty condition + # TODO this shouldn't be needed. Bug in migen IMO, I don't use this signal + dat_r = Signal(width) + # Hook write input signals to memory wr_port = storage.get_port(write_capable=True) + # TODO hacky bullshit because migen is broken or I'm using it wrong + if not hasattr(wr_port.clock, "cd"): + wr_port.clock.cd = "sys" + # Always ready to write data into memory, so hook these signals straight in self.comb += [ wr_port.adr.eq(wr_ptr), wr_port.dat_w.eq(self.wr_data), wr_port.we.eq(self.wr_valid), self.wr_ready.eq(1), # We are always ready to write data in + + dat_r.eq(wr_port.dat_r) ] # Advance write (and potentially read) @@ -66,6 +75,10 @@ class CircularBuffer(Module): # TODO should I actually set async_read? rd_port = storage.get_port(async_read=True) + # TODO hacky bullshit because migen is broken or I'm using it wrong + if not hasattr(rd_port.clock, "cd"): + rd_port.clock.cd = "sys" + # Set read addr so 0 starts at rd_ptr and wraps around, and connect read data up self.comb += [ If(self.rd_addr + rd_ptr < depth, diff --git a/gateware/sampler/sampler.py b/gateware/sampler/sampler.py index ff16d26..5e60b9b 100644 --- a/gateware/sampler/sampler.py +++ b/gateware/sampler/sampler.py @@ -3,14 +3,9 @@ from migen.genlib.cdc import PulseSynchronizer class Sampler(Module): - def __init__(self, adc_pins: Record, sampler_clock: Signal): - # 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) - + def __init__(self, adc_pins: Record): # Hook up ADC REFCLK to sample_clock - self.comb += adc_pins.refclk.eq(sampler_clock) + self.comb += adc_pins.refclk.eq(ClockDomain("sample_clock").clk) # We can synchronize to the sampler clock, whenever it goes high we can # strobe a single valid signal @@ -21,10 +16,10 @@ class Sampler(Module): self.data = Signal(10) self.comb += [ - synchronizer.i.eq(self.sample_clock.clk), + synchronizer.i.eq(ClockDomain("sample_clock").clk), self.valid.eq(synchronizer.o), - self.data.eq(adc_pins.data), ] + self.sync += self.data.eq(adc_pins.data) # Set config pins to constant values self.comb += adc_pins.oen_b.eq(0) # Data pins enable