def __init__(self, pads, rd_timing, wr_timing): self.bus = wishbone.Interface() ### data = TSTriple(16) lsb = Signal() self.specials += data.get_tristate(pads.d) self.comb += [ data.oe.eq(pads.oe_n), pads.ce_n.eq(0) ] load_lo = Signal() load_hi = Signal() store = Signal() pads.oe_n.reset, pads.we_n.reset = 1, 1 self.sync += [ pads.oe_n.eq(1), pads.we_n.eq(1), # Register data/address to avoid off-chip glitches If(self.bus.cyc & self.bus.stb, pads.adr.eq(Cat(lsb, self.bus.adr)), If(self.bus.we, # Only 16-bit writes are supported. Assume sel=0011 or 1100. If(self.bus.sel[0], data.o.eq(self.bus.dat_w[:16]) ).Else( data.o.eq(self.bus.dat_w[16:]) ) ).Else( pads.oe_n.eq(0) ) ), If(load_lo, self.bus.dat_r[:16].eq(data.i)), If(load_hi, self.bus.dat_r[16:].eq(data.i)), If(store, pads.we_n.eq(0)) ] # Typical timing of the flash chips: # - 110ns address to output # - 50ns write pulse width counter = Signal(max=max(rd_timing, wr_timing)+1) counter_en = Signal() counter_wr_mode = Signal() counter_done = Signal() self.comb += counter_done.eq(counter == Mux(counter_wr_mode, wr_timing, rd_timing)) self.sync += If(counter_en & ~counter_done, counter.eq(counter + 1) ).Else( counter.eq(0) ) fsm = FSM() self.submodules += fsm fsm.act("IDLE", If(self.bus.cyc & self.bus.stb, If(self.bus.we, NextState("WR") ).Else( NextState("RD_HI") ) ) ) fsm.act("RD_HI", lsb.eq(0), counter_en.eq(1), If(counter_done, load_hi.eq(1), NextState("RD_LO") ) ) fsm.act("RD_LO", lsb.eq(1), counter_en.eq(1), If(counter_done, load_lo.eq(1), NextState("ACK") ) ) fsm.act("WR", # supported cases: sel=0011 [lsb=1] and sel=1100 [lsb=0] lsb.eq(self.bus.sel[0]), counter_wr_mode.eq(1), counter_en.eq(1), store.eq(1), If(counter_done, NextState("ACK")) ) fsm.act("ACK", self.bus.ack.eq(1), NextState("IDLE") )
def __init__(self, clock_pads, pads, with_hw_init_reset): 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 = Signal() if with_hw_init_reset: self.submodules.hw_reset = LiteEthPHYHWReset() self.comb += reset.eq(self._reset.storage | self.hw_reset.reset) else: self.comb += reset.eq(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, sink_description, source_description, header): self.sink = sink = stream.Endpoint(sink_description) self.source = source = stream.Endpoint(source_description) self.header = Signal(header.length*8) # # # dw = len(self.sink.data) header_reg = Signal(header.length*8) header_words = (header.length*8)//dw load = Signal() shift = Signal() counter = Signal(max=max(header_words, 2)) counter_reset = Signal() counter_ce = Signal() self.sync += \ If(counter_reset, counter.eq(0) ).Elif(counter_ce, counter.eq(counter + 1) ) self.comb += header.encode(sink, self.header) if header_words == 1: self.sync += [ If(load, header_reg.eq(self.header) ) ] else: self.sync += [ If(load, header_reg.eq(self.header) ).Elif(shift, header_reg.eq(Cat(header_reg[dw:], Signal(dw))) ) ] fsm = FSM(reset_state="IDLE") self.submodules += fsm if header_words == 1: idle_next_state = "COPY" else: idle_next_state = "SEND_HEADER" fsm.act("IDLE", sink.ready.eq(1), counter_reset.eq(1), If(sink.valid, sink.ready.eq(0), source.valid.eq(1), source.last.eq(0), source.data.eq(self.header[:dw]), If(source.valid & source.ready, load.eq(1), NextState(idle_next_state) ) ) ) if header_words != 1: fsm.act("SEND_HEADER", source.valid.eq(1), source.last.eq(0), source.data.eq(header_reg[dw:2*dw]), If(source.valid & source.ready, shift.eq(1), counter_ce.eq(1), If(counter == header_words-2, NextState("COPY") ) ) ) fsm.act("COPY", source.valid.eq(sink.valid), source.last.eq(sink.last), source.data.eq(sink.data), source.error.eq(sink.error), If(source.valid & source.ready, sink.ready.eq(1), If(source.last, NextState("IDLE") ) ) )
def __init__(self, sink_description, source_description, header): self.sink = sink = stream.Endpoint(sink_description) self.source = source = stream.Endpoint(source_description) self.header = Signal(header.length*8) # # # dw = len(sink.data) header_words = (header.length*8)//dw shift = Signal() counter = Signal(max=max(header_words, 2)) counter_reset = Signal() counter_ce = Signal() self.sync += \ If(counter_reset, counter.eq(0) ).Elif(counter_ce, counter.eq(counter + 1) ) if header_words == 1: self.sync += \ If(shift, self.header.eq(sink.data) ) else: self.sync += \ If(shift, self.header.eq(Cat(self.header[dw:], sink.data)) ) fsm = FSM(reset_state="IDLE") self.submodules += fsm if header_words == 1: idle_next_state = "COPY" else: idle_next_state = "RECEIVE_HEADER" fsm.act("IDLE", sink.ready.eq(1), counter_reset.eq(1), If(sink.valid, shift.eq(1), NextState(idle_next_state) ) ) if header_words != 1: fsm.act("RECEIVE_HEADER", sink.ready.eq(1), If(sink.valid, counter_ce.eq(1), shift.eq(1), If(counter == header_words-2, NextState("COPY") ) ) ) no_payload = Signal() self.sync += \ If(fsm.before_entering("COPY"), no_payload.eq(sink.last) ) if hasattr(sink, "error"): self.comb += source.error.eq(sink.error) self.comb += [ source.last.eq(sink.last | no_payload), source.data.eq(sink.data), header.decode(self.header, source) ] fsm.act("COPY", sink.ready.eq(source.ready), source.valid.eq(sink.valid | no_payload), If(source.valid & source.ready & source.last, NextState("IDLE") ) )
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, alignment_bits=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) ).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") ) )