def __init__(self, phy, clk_freq, mode): self.submodules.etherbone = etherbone = Etherbone(mode) depacketizer = Depacketizer(clk_freq) packetizer = Packetizer() self.submodules += depacketizer, packetizer tx_cdc = stream.AsyncFIFO([("data", 32)], 8) tx_cdc = ClockDomainsRenamer({ "write": "sys", "read": "serwb_serdes" })(tx_cdc) self.submodules += tx_cdc rx_cdc = stream.AsyncFIFO([("data", 32)], 8) rx_cdc = ClockDomainsRenamer({ "write": "serwb_serdes", "read": "sys" })(rx_cdc) self.submodules += rx_cdc self.comb += [ # core <--> etherbone depacketizer.source.connect(etherbone.sink), etherbone.source.connect(packetizer.sink), # core --> serdes packetizer.source.connect(tx_cdc.sink), If(tx_cdc.source.stb & phy.init.ready, phy.serdes.tx_data.eq(tx_cdc.source.data)), tx_cdc.source.ack.eq(phy.init.ready), # serdes --> core rx_cdc.sink.stb.eq(phy.init.ready), rx_cdc.sink.data.eq(phy.serdes.rx_data), rx_cdc.source.connect(depacketizer.sink), ]
def __init__(self, phy, clk_freq, mode, with_scrambling=False): # etherbone self.submodules.etherbone = etherbone = Etherbone(mode) # packetizer / depacketizer depacketizer = Depacketizer(clk_freq) packetizer = Packetizer() self.submodules += depacketizer, packetizer # clock domain crossing tx_cdc = stream.AsyncFIFO([("data", 32)], 16) tx_cdc = ClockDomainsRenamer({"write": "sys", "read": phy.cd})(tx_cdc) rx_cdc = stream.AsyncFIFO([("data", 32)], 16) rx_cdc = ClockDomainsRenamer({"write": phy.cd, "read": "sys"})(rx_cdc) self.submodules += tx_cdc, rx_cdc # scrambling scrambler = ClockDomainsRenamer(phy.cd)( Scrambler(enable=with_scrambling)) descrambler = ClockDomainsRenamer(phy.cd)( Descrambler(enable=with_scrambling)) self.submodules += scrambler, descrambler # modules connection self.comb += [ # core --> phy packetizer.source.connect(tx_cdc.sink), tx_cdc.source.connect(scrambler.sink), If( phy.init.ready, If(scrambler.source.stb, phy.serdes.tx_k.eq(scrambler.source.k), phy.serdes.tx_d.eq(scrambler.source.d)), scrambler.source.ack.eq(1)), # phy --> core descrambler.sink.stb.eq(phy.init.ready), descrambler.sink.k.eq(phy.serdes.rx_k), descrambler.sink.d.eq(phy.serdes.rx_d), descrambler.source.connect(rx_cdc.sink), rx_cdc.source.connect(depacketizer.sink), # etherbone <--> core depacketizer.source.connect(etherbone.sink), etherbone.source.connect(packetizer.sink) ]
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, phy, dw, endianness="big", with_preamble_crc=True, with_padding=True): if dw < phy.dw: raise ValueError("Core data width({}) must be larger than PHY data width({})".format(dw, phy.dw)) rx_pipeline = [phy] tx_pipeline = [phy] # Interpacket gap tx_gap_inserter = gap.LiteEthMACGap(phy.dw) self.submodules += ClockDomainsRenamer("eth_tx")(tx_gap_inserter) tx_pipeline += [tx_gap_inserter] # Preamble / CRC if with_preamble_crc: self._preamble_crc = CSRStatus(reset=1) self.preamble_errors = CSRStatus(32) self.crc_errors = CSRStatus(32) # Preamble insert/check preamble_inserter = preamble.LiteEthMACPreambleInserter(phy.dw) preamble_checker = preamble.LiteEthMACPreambleChecker(phy.dw) self.submodules += ClockDomainsRenamer("eth_tx")(preamble_inserter) self.submodules += ClockDomainsRenamer("eth_rx")(preamble_checker) # CRC insert/check crc32_inserter = crc.LiteEthMACCRC32Inserter(eth_phy_layout(phy.dw)) crc32_checker = crc.LiteEthMACCRC32Checker(eth_phy_layout(phy.dw)) self.submodules += ClockDomainsRenamer("eth_tx")(crc32_inserter) self.submodules += ClockDomainsRenamer("eth_rx")(crc32_checker) tx_pipeline += [preamble_inserter, crc32_inserter] rx_pipeline += [preamble_checker, crc32_checker] # Error counters self.submodules.ps_preamble_error = PulseSynchronizer("eth_rx", "sys") self.submodules.ps_crc_error = PulseSynchronizer("eth_rx", "sys") self.comb += [ self.ps_preamble_error.i.eq(preamble_checker.error), self.ps_crc_error.i.eq(crc32_checker.error), ] self.sync += [ If(self.ps_preamble_error.o, self.preamble_errors.status.eq(self.preamble_errors.status + 1)), If(self.ps_crc_error.o, self.crc_errors.status.eq(self.crc_errors.status + 1)), ] # Padding if with_padding: padding_inserter = padding.LiteEthMACPaddingInserter(phy.dw, 60) padding_checker = padding.LiteEthMACPaddingChecker(phy.dw, 60) self.submodules += ClockDomainsRenamer("eth_tx")(padding_inserter) self.submodules += ClockDomainsRenamer("eth_rx")(padding_checker) tx_pipeline += [padding_inserter] rx_pipeline += [padding_checker] # Delimiters if dw != 8: tx_last_be = last_be.LiteEthMACTXLastBE(phy.dw) rx_last_be = last_be.LiteEthMACRXLastBE(phy.dw) self.submodules += ClockDomainsRenamer("eth_tx")(tx_last_be) self.submodules += ClockDomainsRenamer("eth_rx")(rx_last_be) tx_pipeline += [tx_last_be] rx_pipeline += [rx_last_be] # Converters if dw != phy.dw: reverse = endianness == "big" tx_converter = stream.StrideConverter(eth_phy_layout(dw), eth_phy_layout(phy.dw), reverse=reverse) rx_converter = stream.StrideConverter(eth_phy_layout(phy.dw), eth_phy_layout(dw), reverse=reverse) self.submodules += ClockDomainsRenamer("eth_tx")(tx_converter) self.submodules += ClockDomainsRenamer("eth_rx")(rx_converter) tx_pipeline += [tx_converter] rx_pipeline += [rx_converter] # Cross Domain Crossing tx_cdc = stream.AsyncFIFO(eth_phy_layout(dw), 64) rx_cdc = stream.AsyncFIFO(eth_phy_layout(dw), 64) self.submodules += ClockDomainsRenamer({"write": "sys", "read": "eth_tx"})(tx_cdc) self.submodules += ClockDomainsRenamer({"write": "eth_rx", "read": "sys"})(rx_cdc) tx_pipeline += [tx_cdc] rx_pipeline += [rx_cdc] tx_pipeline_r = list(reversed(tx_pipeline)) for s, d in zip(tx_pipeline_r, tx_pipeline_r[1:]): self.comb += s.source.connect(d.sink) for s, d in zip(rx_pipeline, rx_pipeline[1:]): self.comb += s.source.connect(d.sink) self.sink = tx_pipeline[-1].sink self.source = rx_pipeline[-1].source
def __init__(self, plat): # Clocking clk_ref = plat.request( "clk12") # 12mhz reference clock from which all else is derived self.submodules.clockgen = clocking.ClockGen(clk_ref) self.clock_domains.cd_sys = self.clockgen.cd_sys self.clock_domains.cd_pix1x = self.clockgen.cd_pix1x self.clock_domains.cd_pix8x = self.clockgen.cd_pix8x # SDRAM Controller sd_param = ovplatform.sdram_params.getSDRAMParams('mt48lc16m16a2') # Build the SDRAM controller (TODO: Replace with MISOC SDRAM controller) self.submodules.sdramctl = SDRAMCTL( plat.request("sdram"), clk_out=self.clockgen.clk_sdram, clk_sample=self.clockgen.clk_sdram_sample, **sd_param._asdict()) # SDRAM Master arbiter (TODO: Replace with MISOC bus arbiter) self.submodules.sdram_mux = SDRAMMux(self.sdramctl.hostif) # SDRAM BIST (TODO: Rewrite to use internal bus) memsize = 2**(sd_param.colbits + sd_param.rowbits + sd_param.bankbits) self.submodules.bist = SDRAMBIST(self.sdram_mux.getPort(), memsize) self.submodules.sdram_test = SDRAMBISTCfg(self.bist) # SDRAM host read translator self.submodules.sdram_host_read = SDRAM_Host_Read( self.sdram_mux.getPort(), host_burst_length=0x20) # SDRAM sink - sends data from USB capture to host self.submodules.sdram_sink = SDRAM_Sink(self.sdram_mux.getPort()) # connect wptr/rptr for ringbuffer flow control self.comb += self.sdram_host_read.wptr.eq(self.sdram_sink.wptr) self.comb += self.sdram_sink.rptr.eq(self.sdram_host_read.rptr) # ULPI Interfce # Diagnostics/Testing signals ulpi_cd_rst = Signal() ulpi_stp_ovr = Signal(1) # ULPI physical layer self.submodules.ulpi_pl = ULPI_pl(plat.request("ulpi"), ulpi_cd_rst, ulpi_stp_ovr) self.clock_domains.cd_ulpi = self.ulpi_pl.cd_ulpi # ULPI controller ulpi_reg = Record(ULPI_REG) self.submodules.ulpi = ClockDomainsRenamer({"sys": "ulpi"})(ULPI_ctrl( self.ulpi_pl.ulpi_bus, ulpi_reg), ) # ULPI register R/W CSR interface self.submodules.ucfg = ULPICfg(self.cd_ulpi.clk, ulpi_cd_rst, self.ulpi_pl.ulpi_bus.rst, ulpi_stp_ovr, ulpi_reg) # Receive Path self.submodules.ovf_insert = ClockDomainsRenamer({"sys": "ulpi"})( OverflowInserter()) self.submodules.udata_fifo = ClockDomainsRenamer({ "write": "ulpi", "read": "sys" })(al_fifo.AsyncFIFO(ULPI_DATA_D, 1024)) self.submodules.cfilt = RXCmdFilter() self.submodules.cstream = Whacker(1024) self.comb += [ self.ulpi.data_out_source.connect(self.ovf_insert.sink), self.ovf_insert.source.connect(self.udata_fifo.sink), self.udata_fifo.source.connect(self.cfilt.sink), self.cfilt.source.connect(self.cstream.sink), # self.cstream.source.connect(self.sdram_sink.sink), ] # FPD receiver lvds_in = Cat(plat.request('spare', 0), plat.request('spare', 1)) debug = Cat(plat.request('spare', i) for i in range(2, 2 + 14)) self.submodules.fpdtop = FpdTop(lvds_in, debug) self.comb += [ self.fpdtop.source.connect(self.sdram_sink.sink), self.fpdtop.serdesstrobe.eq(self.clockgen.serdesstrobe) ] # FTDI bus interface ftdi_io = plat.request("ftdi") self.submodules.ftdi_bus = ftdi_bus = FTDI_sync245( self.clockgen.cd_sys.rst, ftdi_io) # FTDI command processor self.submodules.randtest = FTDI_randtest() self.submodules.cmdproc = CmdProc( self.ftdi_bus, [self.randtest, self.sdram_host_read]) # GPIOs (leds/buttons) self.submodules.leds = LED_outputs( plat.request('leds'), [[self.bist.busy, self.ftdi_bus.tx_ind], [0, self.ftdi_bus.rx_ind], [self.fpdtop.lock]], active=0) # Bind all device CSRs self.csr_map = { 'leds': 0, 'buttons': 1, 'ucfg': 2, 'randtest': 3, 'cstream': 4, 'sdram_test': 5, 'sdram_host_read': 6, 'sdram_sink': 7, 'ovf_insert': 8, 'fpdtop': 9, } self.submodules.csrbankarray = CSRBankArray( self, lambda name, _: self.csr_map[name]) # Connect FTDI CSR Master to CSR bus self.submodules.incon = Interconnect(self.cmdproc.master, self.csrbankarray.get_buses())