def __init__(self, dram_port, random): ashift = log2_int(dram_port.dw // 8) awidth = dram_port.aw + ashift self.start = Signal() self.done = Signal() self.base = Signal(awidth) self.length = Signal(awidth) self.ticks = Signal(32) # # # gen_cls = LFSR if random else Counter gen = gen_cls(min(dram_port.dw, 32)) # FIXME: remove lfsr limitation dma = LiteDRAMDMAWriter(dram_port) self.submodules += dma, gen cmd_counter = Signal(dram_port.aw, reset_less=True) fsm = FSM(reset_state="IDLE") self.submodules += fsm fsm.act("IDLE", If(self.start, NextValue(cmd_counter, 0), NextState("RUN")), NextValue(self.ticks, 0)) fsm.act( "RUN", dma.sink.valid.eq(1), If( dma.sink.ready, gen.ce.eq(1), NextValue(cmd_counter, cmd_counter + 1), If(cmd_counter == (self.length[ashift:] - 1), NextState("DONE"))), NextValue(self.ticks, self.ticks + 1)) fsm.act("DONE", self.done.eq(1)) self.comb += [ dma.sink.address.eq(self.base[ashift:] + cmd_counter), dma.sink.data.eq(gen.o) ]
def __init__(self, dram_port, init=[]): ashift, awidth = get_ashift_awidth(dram_port) self.start = Signal() self.done = Signal() self.ticks = Signal(32) self.run_cascade_in = Signal(reset=1) self.run_cascade_out = Signal() # # # # Data / Address pattern ------------------------------------------------------------------- addr_init, data_init = zip(*init) addr_mem = Memory(dram_port.address_width, len(addr_init), init=addr_init) data_mem = Memory(dram_port.data_width, len(data_init), init=data_init) addr_port = addr_mem.get_port(async_read=True) data_port = data_mem.get_port(async_read=True) self.specials += addr_mem, data_mem, addr_port, data_port # DMA -------------------------------------------------------------------------------------- dma = LiteDRAMDMAWriter(dram_port) self.submodules += dma cmd_counter = Signal(dram_port.address_width, reset_less=True) # Data / Address FSM ----------------------------------------------------------------------- fsm = FSM(reset_state="IDLE") self.submodules += fsm fsm.act("IDLE", If(self.start, NextValue(cmd_counter, 0), NextState("RUN")), NextValue(self.ticks, 0)) fsm.act("WAIT", If(self.run_cascade_in, NextState("RUN"))) fsm.act( "RUN", dma.sink.valid.eq(1), If( dma.sink.ready, self.run_cascade_out.eq(1), NextValue(cmd_counter, cmd_counter + 1), If(cmd_counter == (len(init) - 1), NextState("DONE")).Elif(~self.run_cascade_in, NextState("WAIT"))), NextValue(self.ticks, self.ticks + 1)) fsm.act("DONE", self.run_cascade_out.eq(1), self.done.eq(1)) if isinstance(dram_port, LiteDRAMNativePort): # addressing in dwords dma_sink_addr = dma.sink.address elif isinstance(dram_port, LiteDRAMAXIPort): # addressing in bytes dma_sink_addr = dma.sink.address[ashift:] else: raise NotImplementedError self.comb += [ addr_port.adr.eq(cmd_counter), dma_sink_addr.eq(addr_port.dat_r), data_port.adr.eq(cmd_counter), dma.sink.data.eq(data_port.dat_r), ]
def __init__(self, dram_port, w0_port, w1_port, w2_port, w3_port, adr_port): self.reset = CSRStorage() self.start = CSRStorage() self.done = CSRStatus() self.count = CSRStorage(size=(32 * 1)) self.mem_base = CSRStorage(size=32) self.mem_mask = CSRStorage(size=32) self.data_mask = CSRStorage(size=32) # patterns dma = LiteDRAMDMAWriter(dram_port, fifo_depth=1) self.submodules += dma cmd_counter = Signal(32) self.comb += [ w0_port.adr.eq(cmd_counter & self.data_mask.storage), w1_port.adr.eq(cmd_counter & self.data_mask.storage), w2_port.adr.eq(cmd_counter & self.data_mask.storage), w3_port.adr.eq(cmd_counter & self.data_mask.storage), adr_port.adr.eq(cmd_counter & self.data_mask.storage), ] self.comb += [ dma.sink.address.eq(self.mem_base.storage + adr_port.dat_r + (cmd_counter & self.mem_mask.storage)), dma.sink.data.eq( Cat(w0_port.dat_r, w1_port.dat_r, w2_port.dat_r, w3_port.dat_r)), ] fsm = FSM(reset_state="IDLE") self.submodules += fsm fsm.act( "IDLE", If( self.start.storage, NextValue(cmd_counter, 0), NextState("WAIT"), )) fsm.act( "WAIT", If(cmd_counter >= self.count.storage, NextState("DONE")).Else(NextState("RUN"))) fsm.act( "RUN", dma.sink.valid.eq(1), If(dma.sink.ready, NextValue(cmd_counter, cmd_counter + 1), NextState("WAIT"))) fsm.act("DONE", self.done.status.eq(1), If(self.reset.storage, NextState("IDLE")))
def __init__(self, dram_port): ashift, awidth = get_ashift_awidth(dram_port) self.start = Signal() self.done = Signal() self.base = Signal(awidth) self.length = Signal(awidth) self.random = Signal() self.ticks = Signal(32) # # # # Data / Address generators ---------------------------------------------------------------- data_gen = Generator(31, n_state=31, taps=[27, 30]) # PRBS31 addr_gen = CEInserter()(Counter(awidth)) self.submodules += data_gen, addr_gen self.comb += data_gen.random_enable.eq(self.random) # DMA -------------------------------------------------------------------------------------- dma = LiteDRAMDMAWriter(dram_port) self.submodules += dma cmd_counter = Signal(dram_port.address_width, reset_less=True) # Data / Address FSM ----------------------------------------------------------------------- fsm = FSM(reset_state="IDLE") self.submodules += fsm fsm.act("IDLE", If(self.start, NextValue(cmd_counter, 0), NextState("RUN") ), NextValue(self.ticks, 0) ) fsm.act("RUN", dma.sink.valid.eq(1), If(dma.sink.ready, data_gen.ce.eq(1), addr_gen.ce.eq(1), NextValue(cmd_counter, cmd_counter + 1), If(cmd_counter == (self.length[ashift:] - 1), NextState("DONE") ) ), NextValue(self.ticks, self.ticks + 1) ) fsm.act("DONE", self.done.eq(1) ) if isinstance(dram_port, LiteDRAMNativePort): # addressing in dwords self.comb += dma.sink.address.eq(self.base[ashift:] + addr_gen.o) elif isinstance(dram_port, LiteDRAMAXIPort): # addressing in bytes self.comb += dma.sink.address[ashift:].eq(self.base[ashift:] + addr_gen.o) else: raise NotImplementedError self.comb += dma.sink.data.eq(data_gen.o)
def __init__(self, dram_port, pattern_mem, *, rowbits, row_shift): super().__init__(pattern_mem) self.doc = ModuleDoc(""" DMA DRAM writer. Allows to fill DRAM with a predefined pattern using DMA. Pattern ------- {common} """.format(common=BISTModule.__doc__)) dma = LiteDRAMDMAWriter(dram_port, fifo_depth=4) self.submodules += dma cmd_counter = Signal(32) self.comb += [ self.done.eq(cmd_counter), # pattern self.data_port.adr.eq(cmd_counter & self.data_mask), self.addr_port.adr.eq(cmd_counter & self.data_mask), # DMA dma.sink.address.eq(self.addr_port.dat_r + (cmd_counter & self.mem_mask)), ] # DMA data may be inverted using AddressSelector self.submodules.inverter = RowDataInverter( addr=dma.sink.address, data_in=self.data_port.dat_r, data_out=dma.sink.data, rowbits=rowbits, row_shift=row_shift, ) self.submodules.fsm = fsm = FSM() fsm.act("READY", self.ready.eq(1), If( self.start, NextValue(cmd_counter, 0), NextState("WAIT"), )) fsm.act( "WAIT", # TODO: we could pipeline the access If(cmd_counter >= self.count, NextState("READY")).Else(NextState("RUN"))) fsm.act( "RUN", dma.sink.valid.eq(1), If(dma.sink.ready, NextValue(cmd_counter, cmd_counter + 1), NextState("WAIT")))
def __init__(self, dram_port, pattern_mem): super().__init__(pattern_mem) self.doc = ModuleDoc(""" DMA DRAM writer. Allows to fill DRAM with a predefined pattern using DMA. Pattern ------- {common} """.format(common=BISTModule.__doc__)) # FIXME: Increase fifo depth dma = LiteDRAMDMAWriter(dram_port, fifo_depth=1) self.submodules += dma cmd_counter = Signal(32) self.comb += [ self.done.eq(cmd_counter), # pattern self.data_port.adr.eq(cmd_counter & self.data_mask), self.addr_port.adr.eq(cmd_counter & self.data_mask), # DMA dma.sink.address.eq(self.addr_port.dat_r + (cmd_counter & self.mem_mask)), dma.sink.data.eq(self.data_port.dat_r), ] self.submodules.fsm = fsm = FSM() fsm.act("READY", self.ready.eq(1), If( self.start, NextValue(cmd_counter, 0), NextState("WAIT"), )) fsm.act( "WAIT", # TODO: we could pipeline the access If(cmd_counter >= self.count, NextState("READY")).Else(NextState("RUN"))) fsm.act( "RUN", dma.sink.valid.eq(1), If(dma.sink.ready, NextValue(cmd_counter, cmd_counter + 1), NextState("WAIT")))
def __init__(self, dram_port, random): self.start = Signal() self.done = Signal() self.base = Signal(dram_port.aw) self.length = Signal(dram_port.aw) # # # self.submodules.dma = dma = LiteDRAMDMAWriter(dram_port) gen_cls = LFSR if random else Counter self.submodules.gen = gen = gen_cls(dram_port.dw) self.cmd_counter = cmd_counter = Signal(dram_port.aw) self.submodules.fsm = fsm = FSM(reset_state="IDLE") fsm.act( "IDLE", If( self.start, NextValue(cmd_counter, 0), NextState("RUN"), ), ) fsm.act( "RUN", dma.sink.valid.eq(1), If( dma.sink.ready, gen.ce.eq(1), NextValue(cmd_counter, cmd_counter + 1), If( cmd_counter == (self.length - 1), NextState("DONE"), ), ), ) fsm.act( "DONE", self.done.eq(1), ) self.comb += [ dma.sink.address.eq(self.base + cmd_counter), dma.sink.data.eq(gen.o), ]
def __init__(self, dram_port): self._ready = CSRStatus(8) self._value = CSRStorage(32) self._base = CSRStorage(32) self._offset = CSRStorage(32) self._start = CSRStorage( fields=[CSRField("start", size=1, offset=0, pulse=True)]) base = Signal(dram_port.address_width) offset = Signal(dram_port.address_width) # determine the first significant bit of an byte address in memory shift = log2_int(dram_port.data_width // 8) self.comb += [ base.eq(self._base.storage[shift:]), ] self.dma = LiteDRAMDMAWriter(dram_port) self.submodules += self.dma fsm = FSM(reset_state="IDLE") self.submodules += fsm fsm.act("IDLE", self._ready.status.eq(1), If( self._start.fields.start, NextState("RUN"), )) fsm.act( "RUN", self.dma.sink.valid.eq(1), self._ready.status.eq(0), If( self.dma.sink.ready, NextState("IDLE"), ), ) self.comb += self.dma.sink.address.eq(base + self._offset.storage) self.comb += self.dma.sink.data.eq(self._value.storage)
def __init__(self, platform, with_cpu=True, with_sdram=True, with_etherbone=True, with_gtp=True, gtp_connector="pcie", gtp_refclk="pcie", gtp_linerate=5e9, with_gtp_bist=True, with_gtp_freqmeter=True, with_record=True): sys_clk_freq = int(100e6) # SoCSDRAM --------------------------------------------------------------------------------- SoCSDRAM.__init__( self, platform, sys_clk_freq, cpu_type="vexriscv" if with_cpu else None, csr_data_width=32, with_uart=with_cpu, uart_name="crossover", integrated_rom_size=0x8000 if with_cpu else 0x0000, integrated_main_ram_size=0x1000 if not with_sdram else 0x0000, ident="PCIe Analyzer LiteX SoC", ident_version=True) # CRG -------------------------------------------------------------------------------------- self.submodules.crg = _CRG(platform, sys_clk_freq) # DDR3 SDRAM ------------------------------------------------------------------------------- if not self.integrated_main_ram_size: self.submodules.ddrphy = s7ddrphy.A7DDRPHY( platform.request("ddram"), memtype="DDR3", nphases=4, sys_clk_freq=sys_clk_freq) self.add_csr("ddrphy") sdram_module = K4B2G1646F(sys_clk_freq, "1:4") self.register_sdram(self.ddrphy, geom_settings=sdram_module.geom_settings, timing_settings=sdram_module.timing_settings) # Etherbone -------------------------------------------------------------------------------- if with_etherbone: # ethphy self.submodules.ethphy = LiteEthPHYRMII( clock_pads=self.platform.request("eth_clocks"), pads=self.platform.request("eth")) self.add_csr("ethphy") # ethcore self.submodules.ethcore = LiteEthUDPIPCore( phy=self.ethphy, mac_address=0x10e2d5000000, ip_address="192.168.1.50", clk_freq=self.clk_freq) # etherbone self.submodules.etherbone = LiteEthEtherbone( self.ethcore.udp, 1234) self.add_wb_master(self.etherbone.wishbone.bus) # timing constraints self.platform.add_period_constraint(self.ethphy.crg.cd_eth_rx.clk, 1e9 / 50e6) self.platform.add_period_constraint(self.ethphy.crg.cd_eth_tx.clk, 1e9 / 50e6) 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) # GTP RefClk ------------------------------------------------------------------------------- if with_gtp: assert gtp_refclk in ["pcie", "internal"] if gtp_refclk == "pcie": refclk = Signal() refclk_freq = 100e6 refclk_pads = platform.request("pcie_refclk") self.specials += Instance("IBUFDS_GTE2", i_CEB=0, i_I=refclk_pads.p, i_IB=refclk_pads.n, o_O=refclk) else: refclk = Signal() refclk_freq = 100e6 self.comb += refclk.eq(ClockSignal("clk100")) platform.add_platform_command( "set_property SEVERITY {{Warning}} [get_drc_checks REQP-49]" ) # GTP PLL ---------------------------------------------------------------------------------- if with_gtp: qpll = GTPQuadPLL(refclk, refclk_freq, gtp_linerate) print(qpll) self.submodules += qpll # GTPs ------------------------------------------------------------------------------------- if with_gtp: for i in range(2): tx_pads = platform.request(gtp_connector + "_tx", i) rx_pads = platform.request(gtp_connector + "_rx", i) gtp = GTP(qpll, tx_pads, rx_pads, sys_clk_freq, data_width=20, clock_aligner=False, tx_buffer_enable=True, rx_buffer_enable=True) gtp.add_stream_endpoints() setattr(self.submodules, "gtp" + str(i), gtp) platform.add_period_constraint(gtp.cd_tx.clk, 1e9 / gtp.tx_clk_freq) platform.add_period_constraint(gtp.cd_rx.clk, 1e9 / gtp.rx_clk_freq) self.platform.add_false_path_constraints( self.crg.cd_sys.clk, gtp.cd_tx.clk, gtp.cd_rx.clk) # GTPs FreqMeters -------------------------------------------------------------------------- if with_gtp_freqmeter: self.submodules.gtp0_tx_freq = FreqMeter(ClockSignal("gtp0_tx")) self.submodules.gtp0_rx_freq = FreqMeter(ClockSignal("gtp0_rx")) self.submodules.gtp1_tx_freq = FreqMeter(ClockSignal("gtp1_tx")) self.submodules.gtp1_rx_freq = FreqMeter(ClockSignal("gtp1_rx")) self.add_csr("gtp0_tx_freq") self.add_csr("gtp0_rx_freq") self.add_csr("gtp1_tx_freq") self.add_csr("gtp1_rx_freq") # GTPs BIST -------------------------------------------------------------------------------- if with_gtp_bist: self.submodules.gtp0_tx_bist = GTPTXBIST(self.gtp0, "gtp0_tx") self.submodules.gtp0_rx_bist = GTPRXBIST(self.gtp0, "gtp0_rx") self.submodules.gtp1_tx_bist = GTPTXBIST(self.gtp1, "gtp1_tx") self.submodules.gtp1_rx_bist = GTPRXBIST(self.gtp1, "gtp1_rx") self.add_csr("gtp0_tx_bist") self.add_csr("gtp0_rx_bist") self.add_csr("gtp1_tx_bist") self.add_csr("gtp1_rx_bist") # Record ----------------------------------------------------------------------------------- # FIXME: use better data/ctrl packing (or separate recorders) if with_record: # Convert RX stream from 16-bit@250MHz to 64-bit@sys_clk rx_converter = stream.StrideConverter([("data", 16), ("ctrl", 2)], [("data", 96), ("ctrl", 12)], reverse=False) rx_converter = ClockDomainsRenamer("gtp0_rx")(rx_converter) self.submodules.rx_converter = rx_converter rx_cdc = stream.AsyncFIFO([("data", 96), ("ctrl", 12)], 8, buffered=True) rx_cdc = ClockDomainsRenamer({ "write": "gtp0_rx", "read": "sys" })(rx_cdc) self.submodules.rx_cdc = rx_cdc # RX DMA Recorder self.submodules.rx_dma_recorder = LiteDRAMDMAWriter( self.sdram.crossbar.get_port("write", 128)) self.rx_dma_recorder.add_csr() self.add_csr("rx_dma_recorder") self.comb += [ gtp.source.connect(rx_converter.sink), rx_converter.source.connect(rx_cdc.sink), self.rx_dma_recorder.sink.valid.eq(rx_cdc.source.valid), self.rx_dma_recorder.sink.data[0:96].eq(rx_cdc.source.data), self.rx_dma_recorder.sink.data[96:108].eq(rx_cdc.source.ctrl), ]
def __init__(self, dram_port, adc_pins): self._start = CSRStorage(fields=[CSRField("start_burst", size=1, offset=0, pulse=True)]) self._ready = CSRStatus(8) self._base = CSRStorage(32) self._offset = CSRStorage(32) self.sample_index = Signal(11) SAMPLE_BUFFER = 1024 ADC_BITS = 18 base = Signal(dram_port.address_width) offset = Signal(dram_port.address_width) # determine the first significant bit of an byte address in memory shift = log2_int(dram_port.data_width//8) self.comb += [ base.eq(self._base.storage[shift:]), ] self.dma = LiteDRAMDMAWriter(dram_port) self.submodules += self.dma # hook up pins of ADC self.adc_sdi = Signal() self.adc_sck = Signal() self.adc_sdo = Signal() self.adc_cnv = Signal() self.comb += adc_pins.sdi.eq(self.adc_sdi) self.comb += adc_pins.sck.eq(self.adc_sck) self.comb += self.adc_sdo.eq(adc_pins.sdo) self.comb += adc_pins.cnv.eq(self.adc_cnv) adc_value = Signal(ADC_BITS) cnv_settle = Signal(10) self.comb += self.dma.sink.address.eq(base + self._offset.storage + self.sample_index) self.comb += self.dma.sink.data.eq(adc_value) #self.comb += self.dma.sink.data.eq(self.sample_index) # divide system clock by adc_clk_divisor * 2 self.cnv_strobe = Signal(12) cnv_clk_divisor = 1000 self.sync += \ If(self.cnv_strobe == 0, self.cnv_strobe.eq(cnv_clk_divisor - 1), ).Else( self.cnv_strobe.eq(self.cnv_strobe - 1), ) # divide system 20 for spi clock self.spi_strobe = Signal(5) spi_clk_divisor = 10 self.sync += \ If(self.spi_strobe == 0, self.spi_strobe.eq(spi_clk_divisor - 1), ).Else( self.spi_strobe.eq(self.spi_strobe - 1), ) self.adc_bit = Signal(5) adc_fsm = FSM(reset_state="INIT") self.submodules += adc_fsm # wait for a start pulse adc_fsm.act("INIT", NextValue(self.sample_index, 0), self._ready.status.eq(1), If(self._start.fields.start_burst, NextState("CNV_PREPARE"), ), ) # prepare for conversion adc_fsm.act("CNV_PREPARE", self.adc_cnv.eq(0), NextValue(self.adc_bit, 0), If(self.cnv_strobe == 0, If(self.sample_index == SAMPLE_BUFFER, NextState("INIT"), ).Else( NextState("CNV_START"), ), ).Else( NextState("CNV_PREPARE"), ) ) # start conversion adc_fsm.act("CNV_START", self.adc_cnv.eq(1), NextValue(cnv_settle, 100), # max tcnv is 500 ns, max flck is ~50 MHz. so, 100 cycles should do it NextState("CNV_WAIT"), ) # wait for conversion to end adc_fsm.act("CNV_WAIT", self.adc_cnv.eq(1), NextValue(cnv_settle, cnv_settle -1), # eventually, work off ready signal? #If(self.adc_sdo == 0, # NextState("ACQ_INIT") #) If(cnv_settle == 0, NextState("ACQ_INIT"), ), ) # start acquisition adc_fsm.act("ACQ_INIT", self.adc_cnv.eq(0), NextValue(self.adc_bit, 0), If(self.spi_strobe == 0, NextState("ACQ_CLKH"), ), ) # capture ADC_BITS + 1 bits # read data on rising edg eof sck adc_fsm.act("ACQ_CLKH", self.adc_sck.eq(1), self.adc_cnv.eq(0), If(self.spi_strobe == 0, NextValue(adc_value, (adc_value << 1) + self.adc_sdo), NextState("ACQ_CLKL"), ), ) adc_fsm.act("ACQ_CLKL", self.adc_sck.eq(0), self.adc_cnv.eq(0), If(self.spi_strobe == 0, If(self.adc_bit == ADC_BITS, NextValue(self.sample_index, self.sample_index+1), NextState("ACQ_END"), self.dma.sink.valid.eq(1), ).Else( NextState("ACQ_CLKH"), NextValue(self.adc_bit, self.adc_bit + 1), ) ) ) adc_fsm.act("ACQ_END", self.adc_cnv.eq(0), If(self.spi_strobe == 0, NextState("CNV_PREPARE"), ), )
def __init__(self, dram_port, nslots): bus_aw = dram_port.aw bus_dw = dram_port.dw alignment_bits = bits_for(bus_dw // 8) - 1 fifo_word_width = bus_dw self.frame = stream.Endpoint([("sof", 1), ("pixels", fifo_word_width)]) self._frame_size = CSRStorage(bus_aw + alignment_bits) self.submodules._slot_array = _SlotArray(nslots, bus_aw, alignment_bits) self.ev = self._slot_array.ev # # # # address generator + maximum memory word count to prevent DMA buffer # overrun reset_words = Signal() count_word = Signal() last_word = Signal() current_address = Signal(bus_aw) mwords_remaining = Signal(bus_aw) self.comb += [ self._slot_array.address_reached.eq(current_address), last_word.eq(mwords_remaining == 1) ] self.sync += [ If(reset_words, current_address.eq(self._slot_array.address), mwords_remaining.eq( self._frame_size.storage[alignment_bits:])).Elif( count_word, current_address.eq(current_address + 1), mwords_remaining.eq(mwords_remaining - 1)) ] memory_word = Signal(bus_dw) pixbits = [] for i in range(bus_dw // 16): pixbits.append(self.frame.pixels) self.comb += memory_word.eq(Cat(*pixbits)) # bus accessor self.submodules._bus_accessor = LiteDRAMDMAWriter(dram_port) self.comb += [ self._bus_accessor.sink.address.eq(current_address), self._bus_accessor.sink.data.eq(memory_word) ] # control FSM fsm = FSM() self.submodules += fsm fsm.act( "WAIT_SOF", reset_words.eq(1), self.frame.ready.eq(~self._slot_array.address_valid | ~self.frame.sof), If( self._slot_array.address_valid & self.frame.sof & self.frame.valid, NextState("TRANSFER_PIXELS"))) fsm.act( "TRANSFER_PIXELS", self.frame.ready.eq(self._bus_accessor.sink.ready), If( self.frame.valid, self._bus_accessor.sink.valid.eq(1), If(self._bus_accessor.sink.ready, count_word.eq(1), If(last_word, NextState("EOF"))))) fsm.act( "EOF", If(~dram_port.wdata.valid, self._slot_array.address_done.eq(1), NextState("WAIT_SOF")))
def __init__(self, mode, dram_port, fifo_depth): assert mode == dram_port.mode ashift = log2_int(dram_port.dw // 8) awidth = dram_port.aw + ashift self.cd = dram_port.cd # control self.enable = Signal(reset=1) # reset to 1 if not used self.start = Signal(reset=1) # i / reset to 1 if not used self.idle = Signal() # o self.slot = Signal() # o # parameters self.slot0_base = Signal(awidth) # in bytes self.slot1_base = Signal(awidth) # in bytes self.length = Signal(awidth) # in bytes # stream self.endpoint = endpoint = stream.Endpoint([("data", dram_port.dw)]) # # # base = Signal(dram_port.aw) length = Signal(dram_port.aw) offset = Signal(dram_port.aw) # slot selection self.comb += \ If(self.slot, base.eq(self.slot1_base[ashift:]) ).Else( base.eq(self.slot0_base[ashift:])) # length self.comb += length.eq(self.length[ashift:]) # dma if mode == "write": # dma self.submodules.dma = dma = ResetInserter()(LiteDRAMDMAWriter( dram_port, fifo_depth, True)) # data self.comb += dma.sink.data.eq(endpoint.data) elif mode == "read": # dma self.submodules.dma = dma = ResetInserter()(LiteDRAMDMAReader( dram_port, fifo_depth, True)) # data self.comb += [ endpoint.valid.eq(dma.source.valid), dma.source.ready.eq(endpoint.ready), endpoint.data.eq(dma.source.data) ] # control self.submodules.fsm = fsm = FSM(reset_state="IDLE") fsm.act( "IDLE", self.idle.eq(1), If(self.enable & self.start, NextValue(offset, 0), NextState("RUN"))) fsm.act( "RUN", If( mode == "write", dma.sink.valid.eq(endpoint.valid), endpoint.ready.eq(dma.sink.ready), ).Elif( mode == "read", dma.sink.valid.eq(1), ), If(~self.enable, dma.reset.eq(1), dram_port.flush.eq(1), NextState("IDLE")).Elif( dma.sink.valid & dma.sink.ready, NextValue(offset, offset + 1), If(offset == (length - 1), NextValue(offset, 0), NextValue(self.slot, ~self.slot)))) self.comb += dma.sink.address.eq(base + offset)
def __init__(self, platform, connector="pcie", linerate=2.5e9): assert connector in ["pcie"] sys_clk_freq = int(50e6) # SoCSDRAM ---------------------------------------------------------------------------------- SoCSDRAM.__init__( self, platform, sys_clk_freq, integrated_rom_size=0x8000, integrated_sram_size=0x1000, uart_name="serial", l2_size=0, csr_data_width=32, ) # CRG -------------------------------------------------------------------------------------- self.submodules.crg = _CRG(platform, sys_clk_freq) platform.add_period_constraint(self.crg.cd_sys.clk, 1e9 / 100e6) # DDR3 SDRAM ------------------------------------------------------------------------------- self.submodules.ddrphy = s7ddrphy.A7DDRPHY(platform.request("ddram"), memtype="DDR3", nphases=4, sys_clk_freq=sys_clk_freq) self.add_csr("ddrphy") sdram_module = MT8JTF12864(sys_clk_freq, "1:4") self.register_sdram(self.ddrphy, geom_settings=sdram_module.geom_settings, timing_settings=sdram_module.timing_settings) # Ethernet --------------------------------------------------------------------------------- # phy eth_phy = LiteEthPHYRGMII(clock_pads=platform.request("eth_clocks"), pads=platform.request("eth"), with_hw_init_reset=False, tx_delay=0e-9, rx_delay=0e-9) self.submodules.eth_phy = ClockDomainsRenamer("eth_tx")(eth_phy) self.add_csr("eth_phy") # core eth_core = LiteEthUDPIPCore(phy=self.eth_phy, mac_address=0x10e2d5000000, ip_address="172.30.28.201", clk_freq=125000000) self.submodules.eth_core = ClockDomainsRenamer("eth_tx")(eth_core) # etherbone bridge etherbone_cd = ClockDomain( "etherbone") # similar to sys but need for correct self.clock_domains += etherbone_cd # clock domain renaming self.comb += [ etherbone_cd.clk.eq(ClockSignal("sys")), etherbone_cd.rst.eq(ResetSignal("sys")) ] self.submodules.etherbone = LiteEthEtherbone(self.eth_core.udp, 1234, cd="etherbone") self.add_wb_master(self.etherbone.wishbone.bus) # timing constraints self.platform.add_period_constraint(self.eth_phy.crg.cd_eth_rx.clk, 1e9 / 125e6) self.platform.add_period_constraint(self.eth_phy.crg.cd_eth_tx.clk, 1e9 / 125e6) self.platform.add_false_path_constraints( self.crg.cd_sys.clk, self.eth_phy.crg.cd_eth_rx.clk, self.eth_phy.crg.cd_eth_tx.clk) # GTP RefClk ------------------------------------------------------------------------------- refclk = Signal() refclk_freq = 100e6 refclk_pads = platform.request("pcie_refclk") self.specials += Instance("IBUFDS_GTE2", i_CEB=0, i_I=refclk_pads.p, i_IB=refclk_pads.n, o_O=refclk) # GTP PLL ---------------------------------------------------------------------------------- qpll = GTPQuadPLL(refclk, refclk_freq, linerate) print(qpll) self.submodules += qpll # GTPs ------------------------------------------------------------------------------------- for i in range(2): tx_pads = platform.request(connector + "_tx", i) rx_pads = platform.request(connector + "_rx", i) gtp = GTP(qpll, tx_pads, rx_pads, sys_clk_freq, data_width=20, clock_aligner=False, tx_buffer_enable=True, rx_buffer_enable=True) gtp.add_stream_endpoints() setattr(self.submodules, "gtp" + str(i), gtp) platform.add_period_constraint(gtp.cd_tx.clk, 1e9 / gtp.tx_clk_freq) platform.add_period_constraint(gtp.cd_rx.clk, 1e9 / gtp.rx_clk_freq) self.platform.add_false_path_constraints(self.crg.cd_sys.clk, gtp.cd_tx.clk, gtp.cd_rx.clk) # Record ------------------------------------------------------------------------------------- self.submodules.rx_dma_recorder = LiteDRAMDMAWriter( self.sdram.crossbar.get_port("write", 32, clock_domain="gtp0_rx")) self.rx_dma_recorder.add_csr() self.add_csr("rx_dma_recorder") self.submodules.tx_dma_recorder = LiteDRAMDMAWriter( self.sdram.crossbar.get_port("write", 32, clock_domain="gtp1_rx")) self.tx_dma_recorder.add_csr() self.add_csr("tx_dma_recorder") self.comb += [ self.rx_dma_recorder.sink.valid.eq(self.gtp0.source.valid), self.rx_dma_recorder.sink.data.eq( self.gtp0.source.payload.raw_bits()), self.tx_dma_recorder.sink.valid.eq(self.gtp1.source.valid), self.tx_dma_recorder.sink.data.eq( self.gtp1.source.payload.raw_bits()), ]
def __init__(self, dram_port): self.reset = CSRStorage() self.start = CSRStorage() self.done = CSRStatus() self.count = CSRStorage(size=(32 * 1)) self.mem_base = CSRStorage(size=32) self.mem_mask = CSRStorage(size=32) self.data_mask = CSRStorage(size=32) # patterns # FIXME: Increase fifo depth dma = LiteDRAMDMAWriter(dram_port, fifo_depth=1) self.submodules += dma self.memory_w0 = Memory(32, 1024) self.memory_w1 = Memory(32, 1024) self.memory_w2 = Memory(32, 1024) self.memory_w3 = Memory(32, 1024) self.memory_adr = Memory(32, 1024) self.specials += self.memory_w0, self.memory_w1, \ self.memory_w2, self.memory_w3, \ self.memory_adr self.autocsr_exclude = 'memory_w0', 'memory_w1', \ 'memory_w2', 'memory_w3', \ 'memory_adr' w0_port = self.memory_w0.get_port() w1_port = self.memory_w1.get_port() w2_port = self.memory_w2.get_port() w3_port = self.memory_w3.get_port() adr_port = self.memory_adr.get_port() self.specials += w0_port, w1_port, w2_port, w3_port, adr_port cmd_counter = Signal(32) self.comb += [ w0_port.adr.eq(cmd_counter & self.data_mask.storage), w1_port.adr.eq(cmd_counter & self.data_mask.storage), w2_port.adr.eq(cmd_counter & self.data_mask.storage), w3_port.adr.eq(cmd_counter & self.data_mask.storage), adr_port.adr.eq(cmd_counter & self.data_mask.storage), ] self.comb += [ dma.sink.address.eq(self.mem_base.storage + adr_port.dat_r + (cmd_counter & self.mem_mask.storage)), dma.sink.data.eq( Cat(w0_port.dat_r, w1_port.dat_r, w2_port.dat_r, w3_port.dat_r)), ] fsm = FSM(reset_state="IDLE") self.submodules += fsm fsm.act( "IDLE", If( self.start.storage, NextValue(cmd_counter, 0), NextState("WAIT"), )) fsm.act( "WAIT", If(cmd_counter >= self.count.storage, NextState("DONE")).Else(NextState("RUN"))) fsm.act( "RUN", dma.sink.valid.eq(1), If(dma.sink.ready, NextValue(cmd_counter, cmd_counter + 1), NextState("WAIT"))) fsm.act("DONE", self.done.status.eq(1), If(self.reset.storage, NextState("IDLE")))
def __init__(self, clock_domain, dram_port, ring_buffer_base_address, ring_buffer_size, filter_fifo_size=2048, trigger_memory_size=128, cdc_stream_fifo_size=1024): # ********************************************************* # * Interface * # ********************************************************* self.simu = CSRStorage() # GTP or Exerciser datas self.source = source = stream.Endpoint([("address", dram_port.address_width), ("data", dram_port.data_width)]) self.sink = sink = stream.Endpoint(gtp_layout) self.forced = Signal() # Another CapturePipeline ask us to record datas self.record = Signal() # Ask another CapturePipeline to record datas self.trigOut = Signal() # Inform another recorder that we trigged self.trigExt = Signal() # Another recorder has trigged self.time = Signal(32) # Time source self.simmode = Signal() # ********************************************************* # * CDC * # ********************************************************* self.specials += MultiReg(self.simu.storage, self.simmode, clock_domain) # ********************************************************* # * Submodules * # ********************************************************* self.submodules.exerciser = Exerciser(clock_domain) self.submodules.multiplexer = stream.Multiplexer(gtp_layout, 2) self.submodules.descrambler = Descrambler(clock_domain) self.submodules.detect = ClockDomainsRenamer(clock_domain)(DetectOrderedSets()) self.submodules.aligner = ClockDomainsRenamer(clock_domain)(Aligner()) self.submodules.filter = Filter(clock_domain, filter_fifo_size) self.submodules.trigger = Trigger(clock_domain, trigger_memory_size) self.submodules.recorder = RingRecorder(clock_domain, dram_port, ring_buffer_base_address, ring_buffer_size) cdc = stream.AsyncFIFO([("address", dram_port.address_width), ("data", dram_port.data_width)], cdc_stream_fifo_size, buffered=True) cdc = ClockDomainsRenamer({"write": clock_domain, "read": "sys"})(cdc) self.submodules.cdc = cdc self.submodules.dma = LiteDRAMDMAWriter(dram_port) # ********************************************************* # * Combinatorial * # ********************************************************* self.comb += [ self.multiplexer.sel.eq(self.simmode), self.sink.connect(self.multiplexer.sink0), self.exerciser.source.connect(self.multiplexer.sink1), self.exerciser.time.eq(self.time), self.multiplexer.source.connect(self.detect.sink), self.detect.source.connect(self.descrambler.sink), self.descrambler.source.connect(self.aligner.sink), self.aligner.source.connect(self.filter.sink), self.filter.source.connect(self.trigger.sink), self.filter.ts.eq(self.time), self.trigger.source.connect(self.recorder.sink), self.trigger.enable.eq(self.recorder.enableTrigger), self.trigOut.eq(self.trigger.trigExt), self.filter.trigExt.eq(self.trigExt), self.recorder.source.connect(self.cdc.sink), self.recorder.forced.eq(self.forced), self.record.eq(self.recorder.record), self.recorder.trigExt.eq(self.trigExt), self.cdc.source.connect(self.dma.sink), ]
def __init__(self, dram_port): ashift, awidth = get_ashift_awidth(dram_port) self.start = Signal() self.done = Signal() self.base = Signal(awidth) self.end = Signal(awidth) self.length = Signal(awidth) self.random_data = Signal() self.random_addr = Signal() self.ticks = Signal(32) self.run_cascade_in = Signal(reset=1) self.run_cascade_out = Signal() # # # # Data / Address generators ---------------------------------------------------------------- data_gen = Generator(31, n_state=31, taps=[27, 30]) # PRBS31 addr_gen = Generator(31, n_state=31, taps=[27, 30]) self.submodules += data_gen, addr_gen self.comb += data_gen.random_enable.eq(self.random_data) self.comb += addr_gen.random_enable.eq(self.random_addr) # mask random address to the range <base, end), range size must be power of 2 addr_mask = Signal(awidth) self.comb += addr_mask.eq((self.end - self.base) - 1) # DMA -------------------------------------------------------------------------------------- dma = LiteDRAMDMAWriter(dram_port) self.submodules += dma cmd_counter = Signal(dram_port.address_width, reset_less=True) # Data / Address FSM ----------------------------------------------------------------------- fsm = FSM(reset_state="IDLE") self.submodules += fsm fsm.act("IDLE", If(self.start, NextValue(cmd_counter, 0), NextState("RUN")), NextValue(self.ticks, 0)) fsm.act("WAIT", If(self.run_cascade_in, NextState("RUN"))) fsm.act( "RUN", dma.sink.valid.eq(1), If( dma.sink.ready, self.run_cascade_out.eq(1), data_gen.ce.eq(1), addr_gen.ce.eq(1), NextValue(cmd_counter, cmd_counter + 1), If(cmd_counter == (self.length[ashift:] - 1), NextState("DONE")).Elif(~self.run_cascade_in, NextState("WAIT"))), NextValue(self.ticks, self.ticks + 1)) fsm.act("DONE", self.run_cascade_out.eq(1), self.done.eq(1)) if isinstance(dram_port, LiteDRAMNativePort): # addressing in dwords dma_sink_addr = dma.sink.address elif isinstance(dram_port, LiteDRAMAXIPort): # addressing in bytes dma_sink_addr = dma.sink.address[ashift:] else: raise NotImplementedError self.comb += dma_sink_addr.eq(self.base[ashift:] + (addr_gen.o & addr_mask)) self.comb += dma.sink.data.eq(data_gen.o)
def __init__(self, sdram_module, sdram_data_width, **kwargs): platform = Platform() sys_clk_freq = int(1e6) # SoCSDRAM --------------------------------------------------------------------------------- SoCSDRAM.__init__(self, platform, sys_clk_freq, integrated_rom_size = 0x8000, integrated_sram_size = 0x1000, uart_name = "crossover", l2_size = 0, csr_data_width = 32, **kwargs ) # CRG -------------------------------------------------------------------------------------- self.submodules.crg = CRG(platform.request("sys_clk")) # SDR SDRAM -------------------------------------------------------------------------------- from litex.tools.litex_sim import sdram_module_nphases, get_sdram_phy_settings sdram_clk_freq = int(100e6) # FIXME: use 100MHz timings sdram_module_cls = getattr(litedram_modules, sdram_module) sdram_rate = "1:{}".format(sdram_module_nphases[sdram_module_cls.memtype]) sdram_module = sdram_module_cls(sdram_clk_freq, sdram_rate) phy_settings = get_sdram_phy_settings( memtype = sdram_module.memtype, data_width = sdram_data_width, clk_freq = sdram_clk_freq) self.submodules.sdrphy = SDRAMPHYModel( module = sdram_module, settings = phy_settings, clk_freq = sdram_clk_freq) self.register_sdram( self.sdrphy, sdram_module.geom_settings, sdram_module.timing_settings) # Disable Memtest for simulation speedup self.add_constant("MEMTEST_BUS_SIZE", 0) self.add_constant("MEMTEST_ADDR_SIZE", 0) self.add_constant("MEMTEST_DATA_SIZE", 0) # Ethernet --------------------------------------------------------------------------------- # phy self.submodules.ethphy = LiteEthPHYModel(self.platform.request("eth")) self.add_csr("ethphy") # core ethcore = LiteEthUDPIPCore(self.ethphy, mac_address = 0x10e2d5000000, ip_address = "192.168.1.50", clk_freq = sys_clk_freq) self.submodules.ethcore = ethcore # etherbone self.submodules.etherbone = LiteEthEtherbone(self.ethcore.udp, 1234, mode="master") self.add_wb_master(self.etherbone.wishbone.bus) # Record ----------------------------------------------------------------------------------- self.submodules.rx_dma_recorder = LiteDRAMDMAWriter(self.sdram.crossbar.get_port("write", 32)) self.rx_dma_recorder.add_csr() self.add_csr("rx_dma_recorder") self.submodules.tx_dma_recorder = LiteDRAMDMAWriter(self.sdram.crossbar.get_port("write", 32)) self.tx_dma_recorder.add_csr() self.add_csr("tx_dma_recorder") counter = Signal(32) self.sync += counter.eq(counter + 1) self.comb += [ self.rx_dma_recorder.sink.valid.eq(1), self.rx_dma_recorder.sink.data.eq(counter), self.tx_dma_recorder.sink.valid.eq(1), self.tx_dma_recorder.sink.data.eq(counter), ]
def __init__(self, sdram_module, sdram_data_width, **kwargs): platform = Platform() sys_clk_freq = int(1e6) # ********************************************************* # * SoC SDRAM * # ********************************************************* SoCSDRAM.__init__(self, platform, sys_clk_freq, integrated_rom_size=0x8000, integrated_sram_size=0x1000, uart_name="crossover", l2_size=0, csr_data_width=32, **kwargs) # ********************************************************* # * CRG * # ********************************************************* self.submodules.crg = CRG(platform.request("sys_clk")) # ********************************************************* # * SDR SDRAM * # ********************************************************* from litex.tools.litex_sim import sdram_module_nphases, get_sdram_phy_settings sdram_clk_freq = int(100e6) # FIXME: use 100MHz timings sdram_module_cls = getattr(litedram_modules, sdram_module) sdram_rate = "1:{}".format( sdram_module_nphases[sdram_module_cls.memtype]) sdram_module = sdram_module_cls(sdram_clk_freq, sdram_rate) phy_settings = get_sdram_phy_settings(memtype=sdram_module.memtype, data_width=sdram_data_width, clk_freq=sdram_clk_freq) self.submodules.sdrphy = SDRAMPHYModel(module=sdram_module, settings=phy_settings, clk_freq=sdram_clk_freq) self.register_sdram(self.sdrphy, sdram_module.geom_settings, sdram_module.timing_settings) # Disable Memtest for simulation speedup self.add_constant("MEMTEST_BUS_SIZE", 0) self.add_constant("MEMTEST_ADDR_SIZE", 0) self.add_constant("MEMTEST_DATA_SIZE", 0) # ********************************************************* # * Ethernet PHY * # ********************************************************* self.submodules.ethphy = LiteEthPHYModel(self.platform.request("eth")) self.add_csr("ethphy") # ********************************************************* # * Ethernet Core * # ********************************************************* ethcore = LiteEthUDPIPCore(self.ethphy, mac_address=0x10e2d5000000, ip_address="172.30.28.201", clk_freq=sys_clk_freq) self.submodules.ethcore = ethcore # ********************************************************* # * Etherbone bridge * # ********************************************************* self.submodules.etherbone = LiteEthEtherbone(self.ethcore.udp, 1234, mode="master") self.add_wb_master(self.etherbone.wishbone.bus) # ********************************************************* # * Ordered Sets Detector / Descrambler RX * # ********************************************************* self.submodules.rx_detector = DetectOrderedSets() self.submodules.rx_descrambler = Descrambler("sys") self.add_csr("rx_descrambler") self.comb += [ #self.gtp0.source.connect(self.rx_detector.sink, omit={"valid"}), self.rx_detector.sink.valid.eq(1), self.rx_detector.source.connect(self.rx_descrambler.sink), ] # ********************************************************* # * Ordered Sets Detector / Descrambler TX * # ********************************************************* self.submodules.tx_detector = DetectOrderedSets() self.submodules.tx_descrambler = Descrambler("sys") self.add_csr("tx_descrambler") self.comb += [ #self.gtp1.source.connect(self.tx_detector.sink, omit={"valid"}), self.tx_detector.sink.valid.eq(1), self.tx_detector.source.connect(self.tx_descrambler.sink), ] # ********************************************************* # * Trigger RX * # ********************************************************* self.submodules.rx_trigger = Trigger("sys") self.comb += [ self.rx_descrambler.source.connect(self.rx_trigger.sink), ] self.add_csr("rx_trigger_mem") self.add_csr("rx_trigger") # ********************************************************* # * Trigger TX * # ********************************************************* self.submodules.tx_trigger = Trigger("sys") self.comb += [ self.tx_descrambler.source.connect(self.tx_trigger.sink), ] self.add_csr("tx_trigger_mem") self.add_csr("tx_trigger") # ********************************************************* # * Recorder RX * # ********************************************************* rx_port = self.sdram.crossbar.get_port("write", 256) STRIDE_MULTIPLIER = 12 rx_recorder = RingRecorder("sys", rx_port, 0, 0x100000, STRIDE_MULTIPLIER) self.submodules.rx_recorder = rx_recorder self.add_csr("rx_recorder") rx_cdc = stream.AsyncFIFO([("address", rx_port.address_width), ("data", rx_port.data_width)], 1024, buffered=True) rx_cdc = ClockDomainsRenamer({"write": "sys", "read": "sys"})(rx_cdc) self.submodules.rx_cdc = rx_cdc self.submodules.rx_dma = LiteDRAMDMAWriter(rx_port) self.comb += [ self.rx_trigger.source.connect(self.rx_recorder.sink), self.rx_trigger.enable.eq(self.rx_recorder.enable), self.rx_recorder.source.connect(self.rx_cdc.sink), self.rx_cdc.source.connect(self.rx_dma.sink), ] # ********************************************************* # * Recorder TX * # ********************************************************* tx_port = self.sdram.crossbar.get_port("write", 256) tx_recorder = RingRecorder("sys", tx_port, 0x100000, 0x100000, STRIDE_MULTIPLIER) self.submodules.tx_recorder = tx_recorder self.add_csr("tx_recorder") tx_cdc = stream.AsyncFIFO([("address", tx_port.address_width), ("data", tx_port.data_width)], 1024, buffered=True) tx_cdc = ClockDomainsRenamer({"write": "sys", "read": "sys"})(tx_cdc) self.submodules.tx_cdc = tx_cdc self.submodules.tx_dma = LiteDRAMDMAWriter(tx_port) self.comb += [ self.tx_trigger.source.connect(self.tx_recorder.sink), self.tx_trigger.enable.eq(self.tx_recorder.enable), self.tx_recorder.source.connect(self.tx_cdc.sink), self.tx_cdc.source.connect(self.tx_dma.sink), ] # ********************************************************* # * Recorder RX/TX * # ********************************************************* self.comb += [ self.tx_recorder.force.eq(self.rx_recorder.enable), self.rx_recorder.force.eq(self.tx_recorder.enable), ]