def __init__(self, master, cycles): self.error = Signal() wr_error = Signal() rd_error = Signal() # # # self.comb += self.error.eq(wr_error | rd_error) wr_timer = WaitTimer(int(cycles)) rd_timer = WaitTimer(int(cycles)) self.submodules += wr_timer, rd_timer def channel_fsm(timer, wait_cond, error, response): fsm = FSM(reset_state="WAIT") fsm.act("WAIT", timer.wait.eq(wait_cond), # done is updated in `sync`, so we must make sure that `ready` has not been issued # by slave during that single cycle, by checking `timer.wait`. If(timer.done & timer.wait, error.eq(1), NextState("RESPOND") ) ) fsm.act("RESPOND", *response) return fsm self.submodules.wr_fsm = channel_fsm( timer = wr_timer, wait_cond = (master.aw.valid & ~master.aw.ready) | (master.w.valid & ~master.w.ready), error = wr_error, response = [ master.aw.ready.eq(master.aw.valid), master.w.ready.eq(master.w.valid), master.b.valid.eq(~master.aw.valid & ~master.w.valid), master.b.resp.eq(RESP_SLVERR), If(master.b.valid & master.b.ready, NextState("WAIT") ) ]) self.submodules.rd_fsm = channel_fsm( timer = rd_timer, wait_cond = master.ar.valid & ~master.ar.ready, error = rd_error, response = [ master.ar.ready.eq(master.ar.valid), master.r.valid.eq(~master.ar.valid), master.r.last.eq(1), master.r.resp.eq(RESP_SLVERR), master.r.data.eq(2**len(master.r.data) - 1), If(master.r.valid & master.r.ready, NextState("WAIT") ) ])
def __init__(self, clk_freq, timeout=10): self.sink = sink = stream.Endpoint(phy_description(32)) self.source = source = stream.Endpoint(user_description(32)) # # # count = Signal(len(source.length)) length = Signal(len(source.length)) # Packet description # - preamble : 4 bytes # - length : 4 bytes # - payload fsm = FSM(reset_state="PREAMBLE") self.submodules += fsm timer = WaitTimer(clk_freq * timeout) self.submodules += timer fsm.act( "PREAMBLE", sink.ready.eq(1), If(sink.valid & (sink.data == 0x5aa55aa5), NextState("LENGTH"))) fsm.act( "LENGTH", sink.ready.eq(1), If(sink.valid, NextValue(count, 0), NextValue(length, sink.data), NextState("DATA")), timer.wait.eq(1)) fsm.act( "DATA", source.valid.eq(sink.valid), source.last.eq(count == (length[2:] - 1)), source.length.eq(length), source.data.eq(sink.data), sink.ready.eq(source.ready), If(timer.done, NextState("PREAMBLE")).Elif( source.valid & source.ready, NextValue(count, count + 1), If(source.last, NextState("PREAMBLE"))), timer.wait.eq(1))
def __init__(self, width, idomain, odomain, timeout=128): self.i = Signal(width) self.o = Signal(width, reset_less=True) if width == 1: self.specials += MultiReg(self.i, self.o, odomain) else: sync_i = getattr(self.sync, idomain) sync_o = getattr(self.sync, odomain) starter = Signal(reset=1) sync_i += starter.eq(0) self.submodules._ping = PulseSynchronizer(idomain, odomain) # Extra flop on i->o to avoid race between data and request # https://github.com/m-labs/nmigen/pull/40#issuecomment-484166790 ping_o = Signal() sync_o += ping_o.eq(self._ping.o) self.submodules._pong = PulseSynchronizer(odomain, idomain) self.submodules._timeout = ClockDomainsRenamer(idomain)( WaitTimer(timeout)) self.comb += [ self._timeout.wait.eq(~self._ping.i), self._ping.i.eq(starter | self._pong.o | self._timeout.done), self._pong.i.eq(ping_o) ] ibuffer = Signal(width, reset_less=True) obuffer = Signal(width) # registered reset_less by MultiReg sync_i += If(self._pong.o, ibuffer.eq(self.i)) ibuffer.attr.add("no_retiming") self.specials += MultiReg(ibuffer, obuffer, odomain) sync_o += If(ping_o, self.o.eq(obuffer))
def __init__(self, width, idomain, odomain, timeout=128): self.i = Signal(width) self.o = Signal(width, reset_less=True) if width == 1: self.specials += MultiReg(self.i, self.o, odomain) else: sync_i = getattr(self.sync, idomain) sync_o = getattr(self.sync, odomain) starter = Signal(reset=1) sync_i += starter.eq(0) self.submodules._ping = PulseSynchronizer(idomain, odomain) self.submodules._pong = PulseSynchronizer(odomain, idomain) self.submodules._timeout = ClockDomainsRenamer(idomain)( WaitTimer(timeout)) self.comb += [ self._timeout.wait.eq(~self._ping.i), self._ping.i.eq(starter | self._pong.o | self._timeout.done), self._pong.i.eq(self._ping.i) ] ibuffer = Signal(width, reset_less=True) obuffer = Signal(width) # registered reset_less by MultiReg sync_i += If(self._pong.o, ibuffer.eq(self.i)) ibuffer.attr.add("no_retiming") self.specials += MultiReg(ibuffer, obuffer, odomain) sync_o += If(self._ping.o, self.o.eq(obuffer))
def __init__(self, endianness="big"): self.source = source = stream.Endpoint(spi_core2phy_layout) self.sink = sink = stream.Endpoint(spi_phy2core_layout) self.bus = bus = wishbone.Interface() self.cs = cs = Signal() # # # # Burst Control. burst_cs = Signal() burst_adr = Signal(len(bus.adr), reset_less=True) burst_timeout = WaitTimer(MMAP_DEFAULT_TIMEOUT) self.submodules += burst_timeout # FSM. self.submodules.fsm = fsm = FSM(reset_state="IDLE") fsm.act( "IDLE", # Keep CS active after Burst for Timeout. burst_timeout.wait.eq(1), NextValue(burst_cs, burst_cs & ~burst_timeout.done), cs.eq(burst_cs), # On Bus Read access... If( bus.cyc & bus.stb & ~bus.we, # If CS is still active and Bus address matches previous Burst address: # Just continue the current Burst. If(burst_cs & (bus.adr == burst_adr), NextState("BURST-REQ") # Otherwise initialize a new Burst. ).Else(cs.eq(0), NextState("BURST-CMD")))) fsm.act( "BURST-CMD", cs.eq(1), source.valid.eq(1), source.cmd.eq(CMD), source.data.eq(Cat(Signal(2), bus.adr)), # Words to Bytes. NextValue(burst_cs, 1), NextValue(burst_adr, bus.adr), If( source.ready, NextState("BURST-REQ"), )) fsm.act("BURST-REQ", cs.eq(1), source.valid.eq(1), source.cmd.eq(READ), source.last.eq(1), If( source.ready, NextState("BURST-DAT"), )) fsm.act( "BURST-DAT", cs.eq(1), sink.ready.eq(1), bus.dat_r.eq({ "big": sink.data, "little": reverse_bytes(sink.data) }[endianness]), If( sink.valid, bus.ack.eq(1), NextValue(burst_adr, burst_adr + 1), NextState("IDLE"), ))
def __init__(self, platform, sys_clk_freq, clk_external): self.clock_domains.cd_sys = ClockDomain() self.rst = CSR() # # # # Delay software reset by 10us to ensure write has been acked on PCIe. rst_delay = WaitTimer(int(10e-6 * sys_clk_freq)) self.submodules += rst_delay self.sync += If(self.rst.re, rst_delay.wait.eq(1)) if clk_external: platform.add_extension(get_clkin_ios()) self.comb += self.cd_sys.clk.eq(platform.request("clk")) self.specials += AsyncResetSynchronizer( self.cd_sys, platform.request("rst") | rst_delay.done) else: platform.add_extension(get_clkout_ios()) self.comb += self.cd_sys.clk.eq(ClockSignal("pcie")) self.specials += AsyncResetSynchronizer(self.cd_sys, rst_delay.done) self.comb += [ platform.request("clk125").eq(ClockSignal()), platform.request("rst125").eq(ResetSignal()), ]
def __init__(self, platform, sys_clk_freq): self.rst = CSR() self.clock_domains.cd_sys = ClockDomain() self.clock_domains.cd_sys4x = ClockDomain(reset_less=True) self.clock_domains.cd_sys4x_dqs = ClockDomain(reset_less=True) self.clock_domains.cd_clk200 = ClockDomain() # Clk/Rst clk200 = platform.request("clk200") # Delay software reset by 10us to ensure write has been acked on PCIe. rst_delay = WaitTimer(int(10e-6*sys_clk_freq)) self.submodules += rst_delay self.sync += If(self.rst.re, rst_delay.wait.eq(1)) # PLL self.submodules.pll = pll = S7PLL() self.comb += pll.reset.eq(rst_delay.done) pll.register_clkin(clk200, 200e6) pll.create_clkout(self.cd_sys, sys_clk_freq) pll.create_clkout(self.cd_sys4x, 4*sys_clk_freq) pll.create_clkout(self.cd_sys4x_dqs, 4*sys_clk_freq, phase=90) pll.create_clkout(self.cd_clk200, 200e6) self.submodules.idelayctrl = S7IDELAYCTRL(self.cd_clk200)
def __init__(self, cycles=1): self.i = Signal() self.o = Signal() ### timer = WaitTimer(cycles - 1) self.submodules += timer new = Signal() rst = Signal(reset=1) self.sync += [ If( timer.wait, If( timer.done, timer.wait.eq(0), new.eq(~new), ), ).Elif( self.i == new, timer.wait.eq(1), ), If( rst, rst.eq(0), timer.wait.eq(0), new.eq(~self.i), ), ] self.comb += [ self.o.eq(Mux(timer.wait, new, self.i)), ]
def __init__(self, sys_clk_freq, lfps_clk_freq): # Control self.start = Signal() # i self.done = Signal() # o self.length = Signal(32) # i # Transceiver self.tx_idle = Signal(reset=1) # o self.tx_pattern = Signal(20) # o # # # # Assertions ------------------------------------------------------------------------------- # The LFPS Burst has a minimum and maximum allowed period. assert lfps_clk_freq >= lfps_clk_freq_min assert lfps_clk_freq <= lfps_clk_freq_max # LFPS Burst Clock generation -------------------------------------------------------------- clk = Signal() clk_timer = WaitTimer(ceil(sys_clk_freq / (2 * lfps_clk_freq)) - 1) clk_timer = ResetInserter()(clk_timer) self.submodules += clk_timer self.comb += clk_timer.wait.eq(~clk_timer.done) self.sync += If(clk_timer.done, clk.eq(~clk)) # LFPS Burst generation -------------------------------------------------------------------- count = Signal.like(self.length) self.submodules.fsm = fsm = FSM(reset_state="IDLE") fsm.act("IDLE", self.done.eq(1), clk_timer.reset.eq(1), NextValue(count, self.length), If(self.start, NextState("BURST"))) fsm.act("BURST", self.tx_idle.eq(0), self.tx_pattern.eq(Replicate(clk, 20)), NextValue(count, count - 1), If(count == 0, NextState("IDLE")))
def __init__(self, settings): # 1st command 1 cycle after assertion of ready self.cmd = cmd = stream.Endpoint(cmd_request_rw_layout(settings.geom.addressbits, settings.geom.bankbits)) # # # # Refresh sequence generator: # PRECHARGE ALL --(tRP)--> AUTO REFRESH --(tRFC)--> done seq_start = Signal() seq_done = Signal() self.sync += [ cmd.a.eq(2**10), cmd.ba.eq(0), cmd.cas.eq(0), cmd.ras.eq(0), cmd.we.eq(0), seq_done.eq(0) ] self.sync += timeline(seq_start, [ (1, [ cmd.ras.eq(1), cmd.we.eq(1) ]), (1+settings.timing.tRP, [ cmd.cas.eq(1), cmd.ras.eq(1) ]), (1+settings.timing.tRP+settings.timing.tRFC, [ seq_done.eq(1) ]) ]) # Periodic refresh counter self.submodules.timer = WaitTimer(settings.timing.tREFI) self.comb += self.timer.wait.eq(settings.with_refresh & ~self.timer.done) # Control FSM self.submodules.fsm = fsm = FSM() fsm.act("IDLE", If(self.timer.done, NextState("WAIT_GRANT") ) ) fsm.act("WAIT_GRANT", cmd.valid.eq(1), If(cmd.ready, seq_start.eq(1), NextState("WAIT_SEQ") ) ) fsm.act("WAIT_SEQ", If(seq_done, cmd.last.eq(1), NextState("IDLE") ).Else( cmd.valid.eq(1) ) )
def __init__(self, phy_dw, with_scrambling=True): self.bitslip_value = bitslip_value = Signal(6) self.sink = sink = stream.Endpoint([("data", phy_dw)]) self.source = source = stream.Endpoint([("data", 32)]) self.idle = idle = Signal() self.comma = comma = Signal() # # # # converter self.submodules.converter = converter = stream.Converter(phy_dw, 40) # bitslip self.submodules.bitslip = bitslip = _Bitslip() self.comb += bitslip.value.eq(bitslip_value) # line coding self.submodules.decoder = decoder = _8b10bDecoder() # descrambler if with_scrambling: self.submodules.descrambler = descrambler = Descrambler() # dataflow self.comb += [ sink.connect(converter.sink), converter.source.connect(bitslip.sink), bitslip.source.connect(decoder.sink) ] if with_scrambling: self.comb += [ decoder.source.connect(descrambler.sink), descrambler.source.connect(source) ] else: self.comb += [ decoder.source.connect(source, omit={"d", "k"}), source.data.eq(decoder.source.d) ] # idle decoding idle_timer = WaitTimer(32) self.submodules += idle_timer self.sync += [ If( converter.source.valid, idle_timer.wait.eq((converter.source.data == 0) | (converter.source.data == (2**40 - 1)))), idle.eq(idle_timer.done) ] # comma decoding self.sync += \ If(decoder.source.valid, comma.eq((decoder.source.k == 1) & (decoder.source.d == K(28, 5))) )
def __init__(self, data_width, depth=16): self.sink = sink = stream.Endpoint(core_layout(data_width)) self.source = source = stream.Endpoint(core_layout(data_width)) self.enable = CSRStorage() self.done = CSRStatus() self.mem_write = CSR() self.mem_mask = CSRStorage(data_width) self.mem_value = CSRStorage(data_width) self.mem_full = CSRStatus() # # # # Control re-synchronization enable = Signal() enable_d = Signal() self.specials += MultiReg(self.enable.storage, enable, "scope") self.sync.scope += enable_d.eq(enable) # Status re-synchronization done = Signal() self.specials += MultiReg(done, self.done.status) # Memory and configuration mem = stream.AsyncFIFO([("mask", data_width), ("value", data_width)], depth) mem = ClockDomainsRenamer({"write": "sys", "read": "scope"})(mem) self.submodules += mem self.comb += [ mem.sink.valid.eq(self.mem_write.re), mem.sink.mask.eq(self.mem_mask.storage), mem.sink.value.eq(self.mem_value.storage), self.mem_full.status.eq(~mem.sink.ready) ] # Hit and memory read/flush hit = Signal() flush = WaitTimer(2 * depth) flush = ClockDomainsRenamer("scope")(flush) self.submodules += flush self.comb += [ flush.wait.eq(~(~enable & enable_d)), # flush when disabling hit.eq((sink.data & mem.source.mask) == (mem.source.value & mem.source.mask)), mem.source.ready.eq((enable & hit) | ~flush.done), ] # Output self.comb += [ sink.connect(source), # Done when all triggers have been consumed done.eq(~mem.source.valid), source.hit.eq(done) ]
def __init__(self, master, cycles): self.error = Signal() # # # timer = WaitTimer(int(cycles)) self.submodules += timer self.comb += [ timer.wait.eq(master.stb & master.cyc & ~master.ack), If(timer.done, master.dat_r.eq((2**len(master.dat_w)) - 1), master.ack.eq(1), self.error.eq(1)) ]
def __init__(self, sys_clk_freq=int(50e6), with_etherbone=True, ip_address=None, mac_address=None): platform = colorlight_5a_75b.Platform(revision="7.0") # CRG -------------------------------------------------------------------------------------- self.submodules.crg = _CRG(platform, sys_clk_freq) # SoCMini ---------------------------------------------------------------------------------- SoCMini.__init__(self, platform, clk_freq=sys_clk_freq) # Etherbone -------------------------------------------------------------------------------- if with_etherbone: self.submodules.ethphy = LiteEthPHYRGMII( clock_pads=self.platform.request("eth_clocks"), pads=self.platform.request("eth"), tx_delay=0e-9) self.add_etherbone( phy=self.ethphy, ip_address=ip_address, mac_address=mac_address, data_width=32, ) # SPIFlash --------------------------------------------------------------------------------- self.submodules.spiflash = ECP5SPIFlash( pads=platform.request("spiflash"), sys_clk_freq=sys_clk_freq, spi_clk_freq=5e6, ) # Led -------------------------------------------------------------------------------------- self.submodules.leds = LedChaser( pads=platform.request_all("user_led_n"), sys_clk_freq=sys_clk_freq) # GPIOs ------------------------------------------------------------------------------------ platform.add_extension(_gpios) # Power switch power_sw_pads = platform.request("gpio", 0) power_sw_gpio = Signal() power_sw_timer = WaitTimer( 2 * sys_clk_freq) # Set Power switch high after power up for 2s. self.comb += power_sw_timer.wait.eq(1) self.submodules += power_sw_timer self.submodules.gpio0 = GPIOOut(power_sw_gpio) self.comb += power_sw_pads.eq(power_sw_gpio | ~power_sw_timer.done) # Reset Switch reset_sw_pads = platform.request("gpio", 1) self.submodules.gpio1 = GPIOOut(reset_sw_pads)
def __init__(self, clock_pads, pads): self._reset = CSRStorage() # # # self.clock_domains.cd_eth_rx = ClockDomain() self.clock_domains.cd_eth_tx = ClockDomain() # RX dcm_reset = Signal() dcm_locked = Signal() timer = WaitTimer(1024) fsm = FSM(reset_state="DCM_RESET") self.submodules += timer, fsm fsm.act("DCM_RESET", dcm_reset.eq(1), timer.wait.eq(1), If(timer.done, timer.wait.eq(0), NextState("DCM_WAIT"))) fsm.act("DCM_WAIT", timer.wait.eq(1), If(timer.done, NextState("DCM_CHECK_LOCK"))) fsm.act("DCM_CHECK_LOCK", If(~dcm_locked, NextState("DCM_RESET"))) clk90_rx = Signal() clk0_rx = Signal() clk0_rx_bufg = Signal() self.specials += Instance("DCM", i_CLKIN=clock_pads.rx, i_CLKFB=clk0_rx_bufg, o_CLK0=clk0_rx, o_CLK90=clk90_rx, o_LOCKED=dcm_locked, i_PSEN=0, i_PSCLK=0, i_PSINCDEC=0, i_RST=dcm_reset) self.specials += Instance("BUFG", i_I=clk0_rx, o_O=clk0_rx_bufg) self.specials += Instance("BUFG", i_I=clk90_rx, o_O=self.cd_eth_rx.clk) # TX self.specials += DDROutput(1, 0, clock_pads.tx, ClockSignal("eth_tx")) self.specials += Instance("BUFG", i_I=self.cd_eth_rx.clk, o_O=self.cd_eth_tx.clk) # Reset reset = self._reset.storage self.comb += pads.rst_n.eq(~reset) self.specials += [ AsyncResetSynchronizer(self.cd_eth_tx, reset), AsyncResetSynchronizer(self.cd_eth_rx, reset), ]
def __init__(self, identifier, depth=128): self.submodules.buf = buf = stream.SyncFIFO(wrap_description(32), depth + 1) self.sink = sink = buf.sink self.source = source = stream.Endpoint(usb_description(32)) # # # count = Signal(32) self.submodules.timer = WaitTimer(int(1e6)) self.comb += [ source.dst.eq(identifier), ] fsm = FSM() self.submodules.fsm = fsm fsm.act( "BUFFER", If( buf.level > 0, self.timer.wait.eq(1), ), # if buffer full or timeout elapsed If( (buf.level >= depth) | self.timer.done, NextValue(count, buf.level), NextState("TRANSFER"), )) fsm.act( "TRANSFER", source.length.eq(Cat(C(0, 2), count)), source.valid.eq(buf.source.valid), source.last.eq(count == 1), source.data.eq(buf.source.data), buf.source.ready.eq(source.ready), If( source.valid & source.ready, If( source.last, # if enough data stay in transfer state If( buf.level - 1 >= depth, NextValue(count, buf.level - 1), ).Else(NextState("BUFFER"), ), ).Else(NextValue(count, count - 1), )), )
def __init__(self, jesd_settings, n=0): self.jsync = Signal() # Input self.jref = Signal() # Input self.lmfc_zero = Signal() # Input self.ready = Signal() # Output self.sink = sink = Record([("data", jesd_settings.LINK_DW)]) self.source = source = Record(link_layout(jesd_settings.LINK_DW)) # # # # Code Group Synchronization cgs = CGSGenerator(jesd_settings.LINK_DW) self.submodules.cgs = cgs # Initial Lane Alignment Sequence jesd_settings.LID = n jesd_settings.calc_fchk() ilas = ILASGenerator(jesd_settings) self.submodules.ilas = ilas # Datapath datapath = LiteJESD204BLinkTXDapath(jesd_settings) self.submodules.datapath = datapath self.comb += datapath.sink.eq(sink) # Sync jsync_timer = WaitTimer( 4) # Distinguish errors reporting / re-synchronization requests. self.submodules += jsync_timer self.comb += jsync_timer.wait.eq(~self.jsync) # FSM self.submodules.fsm = fsm = FSM(reset_state="SEND-CGS") fsm.act( "SEND-CGS", ilas.reset.eq(1), datapath.scrambler.reset.eq(1), datapath.framer.reset.eq(1), source.data.eq(cgs.source.data), source.ctrl.eq(cgs.source.ctrl), # Start ILAS on first LMFC after jsync is asserted If(self.lmfc_zero & self.jsync, NextState("SEND-ILAS"))) fsm.act("SEND-ILAS", datapath.framer.reset.eq(1), source.data.eq(ilas.source.data), source.ctrl.eq(ilas.source.ctrl), If(ilas.source.last, NextState("SEND-DATA"))) fsm.act("SEND-DATA", self.ready.eq(1), source.eq(datapath.source), If(jsync_timer.done, NextState("SEND-CGS")))
def __init__(self, phy_dw, with_scrambling=False): self.shift = shift = Signal(6) self.sink = sink = stream.Endpoint([("data", phy_dw)]) self.source = source = stream.Endpoint([("data", 32)]) self.idle = idle = Signal() self.comma = comma = Signal() # # # # Aligner self.submodules.aligner = aligner = RXAligner(phy_dw, shift) # Converter self.submodules.converter = converter = stream.Converter(phy_dw, 40) # Line Coding self.submodules.decoder = decoder = StreamDecoder(nwords=4) # Descrambler if with_scrambling: self.submodules.descrambler = descrambler = Descrambler() # Dataflow self.comb += [ sink.connect(aligner.sink), aligner.source.connect(converter.sink), converter.source.connect(decoder.sink), ] if with_scrambling: self.comb += decoder.source.connect(descrambler.sink) self.comb += descrambler.source.connect(source) else: self.comb += decoder.source.connect(source, omit={"d", "k"}) self.comb += source.data.eq(decoder.source.d) # Decode Idle idle_timer = WaitTimer(32) self.submodules += idle_timer self.sync += If( converter.source.valid, idle_timer.wait.eq((converter.source.data == 0) | (converter.source.data == (2**40 - 1)))) self.comb += idle.eq(idle_timer.done) # Decode Comma self.sync += If( decoder.source.valid, comma.eq((decoder.source.k == 1) & (decoder.source.d == K(28, 5))))
def __init__(self, clk_freq, timeout=10): self.sink = sink = stream.Endpoint(phy_description(32)) self.source = source = stream.Endpoint(user_description(32)) # # # # Packet description # - preamble : 4 bytes # - length : 4 bytes # - payload fsm = FSM(reset_state="IDLE") self.submodules += fsm self.submodules.timer = WaitTimer(clk_freq*timeout) self.comb += self.timer.wait.eq(~fsm.ongoing("IDLE")) fsm.act("IDLE", sink.ack.eq(1), If(sink.stb & (sink.data == 0x5aa55aa5), NextState("RECEIVE_LENGTH") ) ) fsm.act("RECEIVE_LENGTH", sink.ack.eq(1), If(sink.stb, NextValue(source.length, sink.data), NextState("COPY") ) ) eop = Signal() cnt = Signal(32) fsm.act("COPY", source.stb.eq(sink.stb), source.eop.eq(eop), source.data.eq(sink.data), sink.ack.eq(source.ack), If((source.stb & source.ack & eop) | self.timer.done, NextState("IDLE") ) ) self.sync += \ If(fsm.ongoing("IDLE"), cnt.eq(0) ).Elif(source.stb & source.ack, cnt.eq(cnt + 1) ) self.comb += eop.eq(cnt == source.length[2:] - 1)
def add_auto_tx_flush(self, sys_clk_freq, timeout=1e-2, interval=2): # Add automatic TX flush when ready is not active for a long time (timeout), this can prevent # stalling the UART (and thus CPU) when the PHY is not operational at startup. flush_ep = stream.Endpoint([("data", 8)]) flush_count = Signal(int(log2(interval))) # Insert Flush Endpoint between TX FIFO and Source. self.comb += self.tx_fifo.source.connect(flush_ep) self.comb += flush_ep.connect(self.source) # Flush TX FIFO when Source.ready is inactive for timeout (with interval cycles between # each ready). self.submodules.timer = timer = WaitTimer(int(timeout * sys_clk_freq)) self.comb += timer.wait.eq(~self.source.ready) self.sync += flush_count.eq(flush_count + 1) self.comb += If(timer.done, flush_ep.ready.eq(flush_count == 0))
def __init__(self, platform, sys_clk_freq): self.rst = CSR() self.clock_domains.cd_sys = ClockDomain() # # # # Delay software reset by 10us to ensure write has been acked on PCIe. rst_delay = WaitTimer(int(10e-6*sys_clk_freq)) self.submodules += rst_delay self.sync += If(self.rst.re, rst_delay.wait.eq(1)) # PLL self.submodules.pll = pll = S7MMCM(speedgrade=-2) self.comb += pll.reset.eq(rst_delay.done) pll.register_clkin(platform.request("clk200"), 200e6) pll.create_clkout(self.cd_sys, sys_clk_freq)
def __init__(self, pads, sys_clk_freq, period=1e0): self._out = CSRStorage(len(pads), description="Led Output(s) Control.") # # # n = len(pads) chaser = Signal(n) mode = Signal(reset=_CHASER_MODE) timer = WaitTimer(int(period * sys_clk_freq / (2 * n))) self.submodules += timer self.comb += timer.wait.eq(~timer.done) self.sync += If(timer.done, chaser.eq(Cat(~chaser[-1], chaser))) self.sync += If(self._out.re, mode.eq(_CONTROL_MODE)) self.comb += [ If(mode == _CONTROL_MODE, pads.eq(self._out.storage)).Else(pads.eq(chaser)) ]
def __init__(self): self.sink = sink = stream.Endpoint(phy_description(32)) # # # self.submodules.timer = WaitTimer(256 * 16) charisk_match = sink.charisk == 0b0001 data_match = sink.data == primitives["ALIGN"] self.comb += \ If(sink.valid & (sink.charisk == 0b0001) & (sink.data == primitives["ALIGN"]), self.timer.wait.eq(0) ).Else( self.timer.wait.eq(1), )
def __init__(self, platform, sys_clk_freq, with_usb_pll=False): self.rst = Signal() self.clock_domains.cd_por = ClockDomain(reset_less=True) self.clock_domains.cd_sys = ClockDomain() # # # # Clk / Rst clk48 = platform.request("clk48") rst_n = platform.request("usr_btn", loose=True) if rst_n is None: rst_n = 1 # Power on reset por_count = Signal(16, reset=2**16 - 1) por_done = Signal() self.comb += self.cd_por.clk.eq(clk48) self.comb += por_done.eq(por_count == 0) self.sync.por += If(~por_done, por_count.eq(por_count - 1)) # PLL self.submodules.pll = pll = ECP5PLL() self.comb += pll.reset.eq(~por_done | ~rst_n | self.rst) pll.register_clkin(clk48, 48e6) pll.create_clkout(self.cd_sys, sys_clk_freq) # USB PLL if with_usb_pll: self.clock_domains.cd_usb_12 = ClockDomain() self.clock_domains.cd_usb_48 = ClockDomain() usb_pll = ECP5PLL() self.submodules += usb_pll self.comb += usb_pll.reset.eq(~por_done) usb_pll.register_clkin(clk48, 48e6) usb_pll.create_clkout(self.cd_usb_48, 48e6) usb_pll.create_clkout(self.cd_usb_12, 12e6) # FPGA Reset (press usr_btn for 1 second to fallback to bootloader) reset_timer = WaitTimer(int(48e6)) reset_timer = ClockDomainsRenamer("por")(reset_timer) self.submodules += reset_timer self.comb += reset_timer.wait.eq(~rst_n) self.comb += platform.request("rst_n").eq(~reset_timer.done)
def __init__(self, serdes, timeout): self.ready = Signal() self.error = Signal() # # # # Shift self.shift = shift = Signal(max=40) # Timer self.submodules.timer = timer = WaitTimer(timeout) # FSM self.submodules.fsm = fsm = FSM(reset_state="IDLE") fsm.act("IDLE", NextValue(shift, 0), NextState("RESET-SLAVE"), serdes.tx.idle.eq(1)) fsm.act("RESET-SLAVE", timer.wait.eq(1), If(timer.done, timer.wait.eq(0), NextState("SEND-PATTERN")), serdes.tx.idle.eq(1)) fsm.act( "SEND-PATTERN", If(~serdes.rx.idle, timer.wait.eq(1), If(timer.done, NextState("CHECK-PATTERN"))), serdes.tx.comma.eq(1)) fsm.act("WAIT-STABLE", timer.wait.eq(1), If(timer.done, timer.wait.eq(0), NextState("CHECK-PATTERN")), serdes.tx.comma.eq(1)) fsm.act( "CHECK-PATTERN", If(serdes.rx.comma, timer.wait.eq(1), If(timer.done, NextState("READY"))).Else(NextState("INC-SHIFT")), serdes.tx.comma.eq(1)) fsm.act( "INC-SHIFT", NextState("WAIT-STABLE"), If(shift == (40 - 1), NextState("ERROR")).Else(serdes.rx.shift.eq(1), NextValue(shift, shift + 1)), serdes.tx.comma.eq(1)) fsm.act("READY", self.ready.eq(1)) fsm.act("ERROR", self.error.eq(1))
def __init__(self, platform, clk_freq): switches = Signal(1) leds = Signal(2) self.reset = Signal() # # # self.submodules.switches = GPIOIn(switches) self.submodules.leds = GPIOOut(leds) self.comb += [ switches[0].eq(~platform.request("pwrsw")), platform.request("hdled").eq(~leds[0]), platform.request("pwled").eq(~leds[1]), ] # generate a reset when power switch is pressed for 1 second self.submodules.reset_timer = WaitTimer(clk_freq) self.comb += [ self.reset_timer.wait.eq(switches[0]), self.reset.eq(self.reset_timer.done) ]
def __init__(self, core, sys_clk_freq): self.enable = CSRStorage() self.ready = CSRStatus() self.stpl_enable = CSRStorage() self.stpl_errors = CSRStatus(32) self.jsync = CSRStatus() # # # self.specials += [ MultiReg(self.enable.storage, core.enable, "jesd"), MultiReg(self.stpl_enable.storage, core.stpl_enable, "jesd"), MultiReg(core.stpl.errors, self.stpl_errors.status, "sys"), MultiReg(core.ready, self.ready.status, "sys") ] jsync_timer = WaitTimer(int(1e-3 * sys_clk_freq)) self.submodules += jsync_timer self.specials += MultiReg(core.jsync, jsync_timer.wait, "sys") self.comb += self.jsync.status.eq(jsync_timer.done)
def __init__(self, serdes, timeout): self.ready = Signal() self.error = Signal() # # # self.bitslip = bitslip = Signal(max=40) self.submodules.timer = timer = WaitTimer(timeout) self.submodules.fsm = fsm = FSM(reset_state="IDLE") # reset fsm.act("IDLE", NextValue(bitslip, 0), timer.wait.eq(1), If( timer.done, timer.wait.eq(0), NextState("WAIT_STABLE"), ), serdes.tx.idle.eq(1)) fsm.act("WAIT_STABLE", timer.wait.eq(1), If(timer.done, timer.wait.eq(0), NextState("CHECK_PATTERN")), serdes.tx.idle.eq(1)) fsm.act( "CHECK_PATTERN", If(serdes.rx.comma, timer.wait.eq(1), If(timer.done, NextState("SEND_PATTERN"))).Else(NextState("INC_BITSLIP")), serdes.tx.idle.eq(1)) self.comb += serdes.rx.bitslip_value.eq(bitslip) fsm.act( "INC_BITSLIP", NextState("WAIT_STABLE"), If(bitslip == (40 - 1), NextState("ERROR")).Else(NextValue(bitslip, bitslip + 1)), serdes.tx.idle.eq(1)) fsm.act("SEND_PATTERN", timer.wait.eq(1), If(timer.done, If(~serdes.rx.comma, NextState("READY"))), serdes.tx.comma.eq(1)) fsm.act("READY", self.ready.eq(1)) fsm.act("ERROR", self.error.eq(1))
def __init__(self, n_in, n_state=23, taps=[17, 22]): self.i = Signal(n_in) self.errors = Signal(n_in) # # # # LFSR Update / Check. state = Signal(n_state, reset=1) curval = [state[i] for i in range(n_state)] for i in reversed(range(n_in)): correctv = reduce(xor, [curval[tap] for tap in taps]) self.comb += self.errors[i].eq(self.i[i] != correctv) curval.insert(0, self.i[i]) curval.pop() self.sync += state.eq(Cat(*curval[:n_state])) # Idle Check. i_last = Signal(n_in) idle_timer = WaitTimer(1024) self.submodules += idle_timer self.sync += i_last.eq(self.i) self.comb += idle_timer.wait.eq(self.i == i_last) self.comb += If(idle_timer.done, self.errors.eq(2**n_in - 1))
def __init__(self, tx_lol, rx_lol, rx_los, rx_lsm): self.rrst = Signal() self.lane_rx_rst = Signal() # # # _tx_lol = Signal() _rx_lol = Signal() _rx_los = Signal() _rx_lsm = Signal() _rx_lsm_seen = Signal() self.specials += [ MultiReg(tx_lol, _tx_lol), MultiReg(rx_lol, _rx_lol), MultiReg(rx_los, _rx_los), MultiReg(rx_lsm, _rx_lsm), ] timer = WaitTimer(int(4e5)) self.submodules += timer self.submodules.fsm = fsm = FSM(reset_state="IDLE") fsm.act("IDLE", self.lane_rx_rst.eq(1), If(~_tx_lol, NextState("RESET-ALL"))) fsm.act("RESET-ALL", self.rrst.eq(1), self.lane_rx_rst.eq(1), NextState("RESET-PCS")) fsm.act( "RESET-PCS", self.lane_rx_rst.eq(1), timer.wait.eq(~_rx_lol & ~_rx_los), If(timer.done, timer.wait.eq(0), NextValue(_rx_lsm_seen, 0), NextState("CHECK-LSM"))) fsm.act( "CHECK-LSM", NextValue(_rx_lsm_seen, _rx_lsm_seen | _rx_lsm), timer.wait.eq(1), If(_rx_lsm_seen & ~_rx_lsm, NextState("IDLE")), If(timer.done, If(_rx_lsm, NextState("READY")).Else(NextState("IDLE")))) fsm.act("READY", If(_tx_lol | _rx_lol | _rx_los, NextState("IDLE")))