def __init__(self, plat): neopixel_gpio = [('neopixel', 0, Subsignal('tx', Pins('PMOD:0')), IOStandard('LVCMOS33'))] plat.add_extension(neopixel_gpio) neopixel_pads = plat.request('neopixel') leds = plat.request('user_led') serial_pads = plat.request('serial') self.submodules.uart = UART(serial_pads, baud_rate=115200, clk_freq=12000000) self.submodules.restrider = Restrider() data = Signal(8) self.submodules.uart_fsm = FSM() self.uart_fsm.act( 'RX', If( self.uart.rx_ready, self.uart.rx_ack.eq(1), NextValue(data, self.uart.rx_data), NextState('INGEST'), )) self.comb += self.restrider.data_in.eq(data) self.uart_fsm.act( 'INGEST', self.restrider.latch_data.eq(1), NextState('RX'), ) N_PIXELS = 8 self.submodules.fifo = SyncFIFOBuffered(24, N_PIXELS) pixel_data = Signal(24) self.submodules.slurp_fsm = FSM() self.slurp_fsm.act( 'IDLE', self.fifo.we.eq(0), If( self.restrider.done, self.restrider.out_read_ack.eq(1), NextValue(pixel_data, self.restrider.data_out), NextState('CHUNK'), )) self.comb += self.fifo.din.eq(pixel_data) self.slurp_fsm.act( 'CHUNK', If( self.fifo.writable, self.fifo.we.eq(1), ), NextState('IDLE'), ) self.submodules.neopixels = WS2812Controller(neopixel_pads, self.fifo, 12000000) self.comb += self.neopixels.write_en.eq(self.fifo.level == N_PIXELS)
def __init__(self, syncword): self.sink = stream.Endpoint([ ("data", 8), ]) self.source = stream.Endpoint([ ("data", 8), ]) ### self.submodules.fsm = FSM(reset_state="DATA") self.fsm.act( "DATA", self.source.payload.data.eq(self.sink.payload.data), self.source.stb.eq(self.sink.stb), self.sink.ack.eq(self.source.ack), If( self.sink.stb & self.sink.ack & self.sink.eop, NextState("SYNC"), ), ) self.fsm.act( "SYNC", self.source.payload.data.eq(syncword), self.source.stb.eq(1), self.sink.ack.eq(0), If( self.source.stb & self.source.ack, NextState("DATA"), ), )
def __init__(self, bus_wishbone=None, bus_csr=None): if bus_wishbone is None: bus_wishbone = wishbone.Interface() self.wishbone = bus_wishbone if bus_csr is None: bus_csr = csr_bus.Interface() self.csr = bus_csr self.ack = Signal() self.en = Signal() # # # self.comb += [ self.csr.dat_w.eq(self.wishbone.dat_w), self.wishbone.dat_r.eq(self.csr.dat_r) ] count = Signal(8) fsm = FSM(reset_state="WRITE-READ") self.submodules += fsm fsm.act( "WRITE-READ", If( self.wishbone.cyc & self.wishbone.stb, self.csr.adr.eq(self.wishbone.adr), self.csr.we.eq(self.wishbone.we), self.en.eq(1), NextState("ACK"), )) fsm.act( "ACK", If(self.wishbone.we | self.ack, self.wishbone.ack.eq(1), NextState("WRITE-READ")))
def __init__(self, wishbone, lasmim): ### # Control FSM self.submodules.fsm = fsm = FSM(reset_state="IDLE") fsm.act("IDLE", If(wishbone.cyc & wishbone.stb, NextState("REQUEST"))) fsm.act( "REQUEST", lasmim.stb.eq(1), lasmim.we.eq(wishbone.we), If( lasmim.req_ack, If(wishbone.we, NextState("WRITE_DATA")).Else(NextState("READ_DATA")))) fsm.act( "WRITE_DATA", If(lasmim.dat_w_ack, lasmim.dat_we.eq(wishbone.sel), wishbone.ack.eq(1), NextState("IDLE"))) fsm.act("READ_DATA", If(lasmim.dat_r_ack, wishbone.ack.eq(1), NextState("IDLE"))) # Address / Datapath self.comb += [ lasmim.adr.eq(wishbone.adr), If( lasmim.dat_w_ack, lasmim.dat_w.eq(wishbone.dat_w), ), wishbone.dat_r.eq(lasmim.dat_r) ]
def __init__(self): self.ctrl = Signal() self.data = Signal() self.status = Signal(8) self.submodules.dut = FSM() self.dut.act( "IDLE", If(self.ctrl, NextState("START") ) ) self.dut.act( "START", If( self.data, NextState("SET-STATUS-LOW") ).Else( NextState("SET-STATUS") ) ) self.dut.act( "SET-STATUS", NextValue(self.status, 0xaa), NextState("IDLE") ) self.dut.act( "SET-STATUS-LOW", NextValue(self.status[:4], 0xb), 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(self.sink.data) header_reg = Signal(header.length * 8, reset_less=True) 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")))) if hasattr(sink, "error"): self.comb += source.error.eq(sink.error) fsm.act( "COPY", source.valid.eq(sink.valid), source.last.eq(sink.last), source.data.eq(sink.data), If(source.valid & source.ready, sink.ready.eq(1), If(source.last, NextState("IDLE"))))
def __init__(self, membus): self.enable = CSR() flow_enable = Signal() self.submodules.dma = DMAReader(membus, flow_enable) self.submodules.slicer = RecordSlicer(len(membus.dat_w)) self.submodules.time_offset = TimeOffset() self.submodules.cri_master = CRIMaster() self.cri = self.cri_master.cri self.comb += [ self.dma.source.connect(self.slicer.sink), self.slicer.source.connect(self.time_offset.sink), self.time_offset.source.connect(self.cri_master.sink) ] fsm = FSM(reset_state="IDLE") self.submodules += fsm fsm.act("IDLE", If(self.enable.re, NextState("FLOWING"))) fsm.act("FLOWING", self.enable.w.eq(1), flow_enable.eq(1), If(self.slicer.end_marker_found, NextState("FLUSH"))) fsm.act("FLUSH", self.enable.w.eq(1), self.slicer.flush.eq(1), NextState("WAIT_EOP")) fsm.act( "WAIT_EOP", self.enable.w.eq(1), If( self.cri_master.sink.stb & self.cri_master.sink.ack & self.cri_master.sink.eop, NextState("WAIT_CRI_MASTER"))) fsm.act("WAIT_CRI_MASTER", self.enable.w.eq(1), If(~self.cri_master.busy, NextState("IDLE")))
def __init__(self, base, data=300, idle=1000): self.source = Source([('d', 8), ('last', 1)]) self.submodules.dummy = FSM() dummy_count = Signal(max=max(idle, data)) dummy_count_next = Signal(max=max(idle, data)) self.sync += dummy_count.eq(dummy_count_next) self.comb += dummy_count_next.eq(dummy_count) self.dummy.act("S0", self.source.payload.d.eq(base + 0), self.source.stb.eq(1), dummy_count_next.eq(0), If(self.source.ack, NextState("S1"))) self.dummy.act("S1", self.source.payload.d.eq(base + 1), self.source.stb.eq(1), If(self.source.ack, NextState("S2"))) self.dummy.act( "S2", self.source.payload.d.eq(dummy_count[0:8]), self.source.stb.eq(1), If( self.source.ack, If(dummy_count != data, dummy_count_next.eq(dummy_count_next + 1)).Else( dummy_count_next.eq(0), self.source.payload.last.eq(1), NextState("S3")))) self.dummy.act( "S3", If(dummy_count != idle, dummy_count_next.eq(dummy_count_next + 1)).Else( dummy_count_next.eq(0), NextState("S0")))
def __init__(self, update, counts, rtlink_i): self.gate = Signal(len(counts)) # # # gate = Signal(len(counts)) sentinel = 2**(len(rtlink_i.data) - 1) fsm = ClockDomainsRenamer("rio")(FSM()) self.submodules += fsm fsm.act("INIT", rtlink_i.data.eq(sentinel), If(update & (self.gate != 0), NextValue(gate, self.gate), rtlink_i.stb.eq(1), NextState(0) ) ) for n, count in enumerate(counts): last = n == len(counts)-1 fsm.act(n, rtlink_i.data.eq(count), rtlink_i.stb.eq(gate[n]), NextState("INIT" if last else n+1) )
def __init__(self, data_width=44, trigger_id_width=0, length=128): self.data_in = Signal(data_width) self.we = Signal() self.pretrigger = Signal(max=length - 1) self.posttrigger = Signal(max=length - 1) self.trigger = Signal() # trigger_id will be optimized out if not required self.trigger_id = Signal(max(trigger_id_width, 1)) # Trigger ID will be embedded into output data self.data_out = Signal(data_width + trigger_id_width) self.stb_out = Signal() # # # buffer = Memory(data_width + trigger_id_width, length) wr_port = buffer.get_port(write_capable=True) rd_port = buffer.get_port(has_re=True) self.specials += [buffer, wr_port, rd_port] self.wr_ptr = wr_ptr = Signal.like(wr_port.adr) self.rd_ptr = rd_ptr = Signal.like(rd_port.adr) trigger_id_d = Signal.like(self.trigger_id) readout_cnt = Signal(max=length - 1) readout_fsm = FSM("IDLE") self.submodules += readout_fsm readout_fsm.act( "IDLE", If(self.trigger == 1, NextState("READOUT"), NextValue(trigger_id_d, self.trigger_id), NextValue(rd_port.re, 1), NextValue(readout_cnt, self.pretrigger + self.posttrigger + 1)).Else( NextValue(rd_port.re, 0))) readout_fsm.act( "READOUT", If(readout_cnt != 0, NextValue(readout_cnt, readout_cnt - 1), NextValue(rd_port.re, 1), NextValue(self.stb_out, 1)).Else(NextState("IDLE"), NextValue(rd_port.re, 0), NextValue(self.stb_out, 0))) self.comb += [ wr_port.we.eq(self.we), wr_port.adr.eq(wr_ptr), # Will be truncated from left (MSB) wr_port.dat_w.eq(Cat(self.data_in, trigger_id_d)), rd_port.adr.eq(rd_ptr), self.data_out.eq(rd_port.dat_r) ] self.sync += [ If(self.we, rd_ptr.eq(wr_ptr - self.pretrigger), wr_ptr.eq(wr_ptr + 1)) ]
def __init__(self, sys_clk_freq): self.rx_reset = Signal() self.rx_pma_reset_done = Signal() # DRPCLK must be driven by the system clock self.drpaddr = Signal(9) self.drpen = Signal() self.drpdi = Signal(16) self.drprdy = Signal() self.drpdo = Signal(16) self.drpwe = Signal() self.enable = Signal() self.restart = Signal() self.done = Signal() # Handle async signals rx_reset = Signal() self.sync += self.rx_reset.eq(rx_reset) self.rx_reset.attr.add("no_retiming") rx_pma_reset_done = Signal() self.specials += MultiReg(self.rx_pma_reset_done, rx_pma_reset_done) drpvalue = Signal(16) drpmask = Signal() self.comb += [ self.drpaddr.eq(0x011), If(drpmask, self.drpdi.eq(drpvalue & 0xf7ff)).Else(self.drpdi.eq(drpvalue)) ] rx_pma_reset_done_r = Signal() self.sync += rx_pma_reset_done_r.eq(rx_pma_reset_done) fsm = FSM() self.submodules += fsm fsm.act("WAIT_ENABLE", If(self.enable, NextState("GTRXRESET"))) fsm.act("GTRXRESET", rx_reset.eq(1), NextState("DRP_READ_ISSUE")) fsm.act("DRP_READ_ISSUE", rx_reset.eq(1), self.drpen.eq(1), NextState("DRP_READ_WAIT")) fsm.act( "DRP_READ_WAIT", rx_reset.eq(1), If(self.drprdy, NextValue(drpvalue, self.drpdo), NextState("DRP_MOD_ISSUE"))) fsm.act("DRP_MOD_ISSUE", rx_reset.eq(1), drpmask.eq(1), self.drpen.eq(1), self.drpwe.eq(1), NextState("DRP_MOD_WAIT")) fsm.act("DRP_MOD_WAIT", rx_reset.eq(1), If(self.drprdy, NextState("WAIT_PMARST_FALL"))) fsm.act( "WAIT_PMARST_FALL", If(rx_pma_reset_done_r & ~rx_pma_reset_done, NextState("DRP_RESTORE_ISSUE"))) fsm.act("DRP_RESTORE_ISSUE", self.drpen.eq(1), self.drpwe.eq(1), NextState("DRP_RESTORE_WAIT")) fsm.act("DRP_RESTORE_WAIT", If(self.drprdy, NextState("DONE"))) fsm.act("DONE", self.done.eq(1), If(self.restart, NextState("WAIT_ENABLE")))
def __init__(self, ulpi_reg): ReadAddress = Signal(6) write_fsm = FSM() self.submodules += write_fsm def delay_clocks(v, d): for i in range(d): n = Signal() self.sync += n.eq(v) v = n return v ulpi_reg_wack = delay_clocks(ulpi_reg.wack, 2) ulpi_reg_rack = delay_clocks(ulpi_reg.rack, 2) write_fsm.delayed_enter("RESET", "WRITE_HS_SNOOP", 16) write_fsm.act("WRITE_HS_SNOOP", ulpi_reg.waddr.eq(0x4), ulpi_reg.wdata.eq(0x48), ulpi_reg.wreq.eq(1), If(ulpi_reg_wack, NextState("WRITE_IDLE"))) write_fsm.act("WRITE_IDLE", ulpi_reg.wreq.eq(0)) read_fsm = FSM() self.submodules += read_fsm read_fsm.delayed_enter("RESET", "READ_REG", 16) read_fsm.act("READ_REG", ulpi_reg.raddr.eq(ReadAddress), ulpi_reg.rreq.eq(1), If(ulpi_reg_rack, NextState("READ_ACK"))) self.sync += If(ulpi_reg_rack & ulpi_reg.rreq, ReadAddress.eq(ReadAddress + 1)) read_fsm.act("READ_ACK", ulpi_reg.rreq.eq(0), If(~ulpi_reg_rack, NextState("READ_WAIT"))) read_fsm.delayed_enter("READ_WAIT", "READ_REG", 16)
def __init__(self, pins, out_fifo, in_fifo, period_cyc): jtag_oe = Signal(len(pins)) jtag_o = Signal(len(pins)) jtag_i = Signal(len(pins)) self.comb += [ Cat(pin.oe for pin in pins).eq(jtag_oe), Cat(pin.o for pin in pins).eq(jtag_o), ] self.specials += MultiReg(Cat(pin.i for pin in pins), jtag_i) timer = Signal(max=period_cyc) cmd = Signal(8) self.submodules.fsm = FSM(reset_state="RECV-COMMAND") self.fsm.act("RECV-COMMAND", If(out_fifo.readable, out_fifo.re.eq(1), NextValue(cmd, out_fifo.dout), If(out_fifo.dout == CMD_W, NextValue(timer, period_cyc - 1), NextState("WAIT") ).Elif(out_fifo.dout == CMD_I, NextState("INPUT") ).Else( NextState("RECV-DATA") ) ) ) self.fsm.act("RECV-DATA", If(out_fifo.readable, out_fifo.re.eq(1), If(cmd == CMD_OE, NextValue(jtag_oe, out_fifo.dout) ).Elif(cmd == CMD_O, NextValue(jtag_o, out_fifo.dout) ).Elif(cmd == CMD_L, NextValue(jtag_o, ~out_fifo.dout & jtag_o) ).Elif(cmd == CMD_H, NextValue(jtag_o, out_fifo.dout | jtag_o) ), NextState("RECV-COMMAND") ) ) self.fsm.act("WAIT", If(timer == 0, NextState("RECV-COMMAND") ).Else( NextValue(timer, timer - 1) ) ) self.fsm.act("INPUT", If(in_fifo.writable, in_fifo.we.eq(1), in_fifo.din.eq(jtag_i), NextState("RECV-COMMAND") ) )
def __init__(self, in_size, out_size, granularity): g = granularity self.sink = stream.Endpoint([("data", in_size * g)]) self.source = Signal(out_size * g) self.source_stb = Signal() self.source_consume = Signal(max=out_size + 1) self.flush = Signal() self.flush_done = Signal() # # # # worst-case buffer space required (when loading): # <data being shifted out> <new incoming word> buf_size = out_size - 1 + in_size buf = Signal(buf_size * g) self.comb += self.source.eq(buf[:out_size * g]) level = Signal(max=buf_size + 1) next_level = Signal(max=buf_size + 1) self.sync += level.eq(next_level) self.comb += next_level.eq(level) load_buf = Signal() shift_buf = Signal() self.sync += [ If( load_buf, Case( level, { i: buf[i * g:(i + in_size) * g].eq( _reverse_bytes(self.sink.data, g)) for i in range(out_size) })), If( shift_buf, Case(self.source_consume, {i: buf.eq(buf[i * g:]) for i in range(out_size)})), ] fsm = FSM(reset_state="FETCH") self.submodules += fsm fsm.act("FETCH", self.sink.ack.eq(1), load_buf.eq(1), If(self.sink.stb, next_level.eq(level + in_size)), If(next_level >= out_size, NextState("OUTPUT"))) fsm.act("OUTPUT", self.source_stb.eq(1), shift_buf.eq(1), next_level.eq(level - self.source_consume), If(next_level < out_size, NextState("FETCH")), If(self.flush, NextState("FLUSH"))) fsm.act( "FLUSH", next_level.eq(0), self.sink.ack.eq(1), If(self.sink.stb & self.sink.eop, self.flush_done.eq(1), NextState("FETCH")))
def __init__(self, mem_depth=4 * (1 << 10)): # XC3S500E: 20x18bx1024 self.specials.mem = Memory(width=16, depth=mem_depth) self.specials.read = read = self.mem.get_port() self.source = Source(line_layout) self.arm = Signal() self.start = Signal() self.frame = Signal(3) ### adr = Signal.like(read.adr) inc = Signal() lp = self.source.payload raw = Signal.like(lp.raw_bits()) self.comb += lp.raw_bits().eq(raw) lpa = Array([ raw[i:i + flen(read.dat_r)] for i in range(0, flen(raw), flen(read.dat_r)) ]) data_read = Signal.like(lp.header.length) self.submodules.fsm = fsm = FSM(reset_state="JUMP") fsm.act("JUMP", read.adr.eq(self.frame), If(self.start, NextState("FRAME"))) fsm.act( "FRAME", read.adr.eq(read.dat_r), inc.eq(1), If(read.dat_r == 0, NextState("JUMP")).Else(NextState("HEADER"))) fsm.act("HEADER", read.adr.eq(adr), inc.eq(1), NextState("LINE")) fsm.act( "LINE", read.adr.eq(adr), If(data_read == lp.header.length, NextState("STB")).Else(inc.eq(1), )) fsm.act( "STB", read.adr.eq(adr), self.source.stb.eq(1), If(self.source.ack, inc.eq(1), If(lp.header.end, NextState("JUMP")).Else(NextState("HEADER"))), If(~self.arm, NextState("JUMP"))) self.sync += [ If( inc, adr.eq(read.adr + 1), ), If( fsm.ongoing("HEADER"), raw.eq(read.dat_r), data_read.eq(1), ), If( fsm.ongoing("LINE"), lpa[data_read].eq(read.dat_r), data_read.eq(data_read + 1), ) ]
def __init__(self): self.s = Signal() myfsm = FSM() self.submodules += myfsm myfsm.act("FOO", self.s.eq(1), NextState("BAR")) myfsm.act("BAR", self.s.eq(0), NextState("FOO")) self.be = myfsm.before_entering("FOO") self.ae = myfsm.after_entering("FOO") self.bl = myfsm.before_leaving("FOO") self.al = myfsm.after_leaving("FOO")
def __init__(self, maxlen=65536, data_width=256): self.sink_ctrl = sink_ctrl = stream.Endpoint( self.getControlInterfaceDescriptor(maxlen=maxlen)) self.go = Signal() self.length = Signal(max=maxlen) self.source = source = stream.Endpoint( K2MMPacket.packet_user_description(dw=data_width)) # # # beats = Signal(max=maxlen, reset_less=True) length = Signal.like(sink_ctrl.length) # Status Signal self.busy = busy = Signal() self.sync += busy.eq(sink_ctrl.valid | (sink_ctrl.ready == 0)) # Transition detection _go = Signal.like(self.go) _single_start = Signal() self.sync += _go.eq(self.go) self.comb += _single_start.eq(self.go & ~_go) fsm = FSM(reset_state="IDLE") fsm.act( "IDLE", sink_ctrl.ready.eq(1), If( sink_ctrl.valid | _single_start, NextState("RUN"), NextValue(length, sink_ctrl.length), NextValue(beats, 0), )) _last_sending = Signal() self.comb += _last_sending.eq(beats == length) fsm.act( "RUN", sink_ctrl.ready.eq(0), source.data.eq(Replicate(beats, data_width // len(beats))), source.length.eq((length + 1) * (data_width // 8)), source.pf.eq(1), source.valid.eq(1), source.first.eq(beats == 0), source.last.eq(_last_sending), source.last_be.eq(Replicate(_last_sending, data_width // 8)), If( source.ready == 1, If( _last_sending, NextState("IDLE"), ).Else(NextValue(beats, beats + 1))), ) self.submodules += fsm
def __init__(self, we_bit=28, sel_bits=slice(24, 28)): super(Wishbone, self).__init__() self.bus = bus = wishbone.Interface() ### start = Signal() read = Signal() self.sync += [ If( start, self.bus.adr.eq(self.dout.payload.addr), self.bus.dat_w.eq(self.dout.payload.data), ), If( read, self.din.payload.data.eq(self.bus.dat_r), ) ] self.comb += [ self.dout.ack.eq(1), self.din.payload.addr.eq(self.bus.adr), self.bus.cyc.eq(self.bus.stb), self.bus.we.eq(self.bus.adr[we_bit]), ] if sel_bits is not None: self.comb += self.bus.sel.eq(self.bus.adr[sel_bits]) else: self.bus.sel.reset = 0b1111 self.submodules.fsm = fsm = FSM() fsm.act("IDLE", If( self.dout.stb, start.eq(1), NextState("BUS"), )) fsm.act( "BUS", self.bus.stb.eq(1), If( self.bus.ack, If( self.bus.we, NextState("IDLE"), ).Else( read.eq(1), NextState("QUEUE"), ), )) fsm.act("QUEUE", self.din.stb.eq(1), If( self.din.ack, NextState("IDLE"), ))
def __init__(self): self._size = CSRStorage(8, reset=8) self._cfg = CSRStorage(1, reset=0) self.source = Endpoint([('d', 8), ('last', 1)]) START_BYTE = 0xAA self.lfsr_state = Signal(17) self.lfsr_state_next = Signal(17) self.sync += If(~self._cfg.storage[0], self.lfsr_state.eq(1)).Else( self.lfsr_state.eq(self.lfsr_state_next)) self.bytecount = Signal(8) self.bytecount_next = Signal(8) self.comb += [ self.lfsr_state_next.eq(self.lfsr_state), self.bytecount_next.eq(self.bytecount), self.source.payload.last.eq(0) ] self.sync += self.bytecount.eq(self.bytecount_next) self.submodules.fsm = FSM() self.fsm.act("IDLE", If(self._cfg.storage[0], NextState("SEND_HEAD"))) self.fsm.act("SEND_HEAD", self.source.payload.d.eq(0xAA), self.source.stb.eq(1), If(self.source.ack, NextState("SEND_SIZE"))) self.fsm.act( "SEND_SIZE", self.source.payload.d.eq(self._size.storage), self.source.stb.eq(1), If(self.source.ack, self.bytecount_next.eq(0), NextState("SEND_DATA")), ) self.fsm.act( "SEND_DATA", self.source.payload.d.eq(self.lfsr_state), self.source.stb.eq(1), If(self.bytecount + 1 == self._size.storage, self.source.payload.last.eq(1)), If( self.source.ack, self.lfsr_state_next.eq( Cat( self.lfsr_state[16] ^ self.lfsr_state[14] ^ self.lfsr_state[13] ^ self.lfsr_state[11], self.lfsr_state)), self.bytecount_next.eq(self.bytecount + 1), If(self.bytecount + 1 == self._size.storage, NextState("IDLE"))))
def __init__(self, dw): self.sink = Sink(phy_layout(dw)) self.source = Source(tlp_raw_layout(dw)) ### sink, source = self.sink, self.source sop = Signal() shift = Signal() sink_dat_r = Signal(dw) sink_be_r = Signal(dw // 8) fsm = FSM(reset_state="HEADER1") self.submodules += fsm fsm.act("HEADER1", sink.ack.eq(1), If(sink.stb, shift.eq(1), NextState("HEADER2"))) fsm.act( "HEADER2", sink.ack.eq(1), If( sink.stb, shift.eq(1), If( sink.eop, sink.ack.eq(0), NextState("TERMINATE"), ).Else(NextState("COPY")))) self.sync += [ If(shift, self.source.header.eq(Cat(self.source.header[64:], sink.dat))), If(sink.stb & sink.ack, sink_dat_r.eq(sink.dat), sink_be_r.eq(sink.be)) ] fsm.act( "COPY", sink.ack.eq(source.ack), source.stb.eq(sink.stb), source.sop.eq(sop), source.eop.eq(sink.eop), source.dat.eq( Cat(reverse_bytes(sink_dat_r[32:]), reverse_bytes(sink.dat[:32]))), source.be.eq(Cat(freversed(sink_be_r[4:]), freversed(sink.be[:4]))), If(source.stb & source.ack & source.eop, NextState("HEADER1"))) self.sync += \ If(fsm.before_entering("COPY"), sop.eq(1) ).Elif(source.stb & source.ack, sop.eq(0) ) fsm.act("TERMINATE", sink.ack.eq(source.ack), source.stb.eq(1), source.sop.eq(1), source.eop.eq(1), source.dat.eq(reverse_bytes(sink.dat[32:])), source.be.eq(freversed(sink.be[4:])), If(source.stb & source.ack & source.eop, NextState("HEADER1")))
def __init__(self, port, depth): self.sink = Sink(dmatpl(depth)) self.source = Source(D_LAST) self.busy = Signal() self.pos = Signal(max=depth, reset=0) self.pos_next = Signal(max=depth, reset=0) self.ct = Signal(max=depth, reset=0) self.ct_next = Signal(max=depth) self.comb += [ self.ct_next.eq(self.ct), self.pos_next.eq(self.pos), port.adr.eq(self.pos_next), ] self.sync += [ self.pos.eq(self.pos_next), self.ct.eq(self.ct_next) ] self.submodules.fsm = FSM() self.fsm.act("IDLE", self.busy.eq(0), If(self.sink.stb, self.busy.eq(1), self.sink.ack.eq(1), self.pos_next.eq(self.sink.payload.start), self.ct_next.eq(self.sink.payload.count-1), NextState('d'), ) ) self.fsm.act("d", self.busy.eq(1), self.source.stb.eq(1), self.source.payload.d.eq(port.dat_r), If(self.ct == 0, self.source.payload.last.eq(1)), If(self.source.ack, If(self.ct, _inc(self.pos, depth, self.pos_next), self.ct_next.eq(self.ct - 1), ).Else( NextState("IDLE") ) ) )
def __init__(self): self.underflow = CSR() self.error_channel = CSRStatus(24) self.error_timestamp = CSRStatus(64) self.error_address = CSRStatus(16) self.sink = stream.Endpoint(record_layout) self.cri = cri.Interface() self.busy = Signal() # # # underflow_trigger = Signal() self.sync += [ If(underflow_trigger, self.underflow.w.eq(1), self.error_channel.status.eq(self.sink.channel), self.error_timestamp.status.eq(self.sink.timestamp), self.error_address.status.eq(self.sink.address)), If(self.underflow.re, self.underflow.w.eq(0)) ] self.comb += [ self.cri.chan_sel.eq(self.sink.channel), self.cri.timestamp.eq(self.sink.timestamp), self.cri.o_address.eq(self.sink.address), self.cri.o_data.eq(self.sink.data) ] fsm = FSM(reset_state="IDLE") self.submodules += fsm fsm.act( "IDLE", If( ~self.underflow.w, If( self.sink.stb, If( self.sink.eop, # last packet contains dummy data, discard it self.sink.ack.eq(1)).Else(NextState("WRITE")))).Else( # discard all data until errors are acked self.sink.ack.eq(1))) fsm.act("WRITE", self.busy.eq(1), self.cri.cmd.eq(cri.commands["write"]), NextState("CHECK_STATE")) fsm.act( "CHECK_STATE", self.busy.eq(1), If(self.cri.o_status == 0, self.sink.ack.eq(1), NextState("IDLE")), If(self.cri.o_status[1], NextState("UNDERFLOW"))) fsm.act("UNDERFLOW", self.busy.eq(1), underflow_trigger.eq(1), self.sink.ack.eq(1), NextState("IDLE"))
def __init__(self, crc_class, layout): self.sink = sink = Sink(layout) self.source = source = Source(layout) self.busy = Signal() # # # dw = flen(sink.data) crc = crc_class(dw) self.submodules += crc ratio = crc.width // dw error = Signal() fifo = InsertReset(SyncFIFO(layout, ratio + 1)) self.submodules += fifo fsm = FSM(reset_state="RESET") self.submodules += fsm fifo_in = Signal() fifo_out = Signal() fifo_full = Signal() self.comb += [ fifo_full.eq(fifo.fifo.level == ratio), fifo_in.eq(sink.stb & (~fifo_full | fifo_out)), fifo_out.eq(source.stb & source.ack), Record.connect(sink, fifo.sink), fifo.sink.stb.eq(fifo_in), self.sink.ack.eq(fifo_in), source.stb.eq(sink.stb & fifo_full), source.sop.eq(fifo.source.sop), source.eop.eq(sink.eop), fifo.source.ack.eq(fifo_out), source.payload.eq(fifo.source.payload), source.error.eq(sink.error | crc.error), ] fsm.act( "RESET", crc.reset.eq(1), fifo.reset.eq(1), NextState("IDLE"), ) fsm.act( "IDLE", crc.data.eq(sink.data), If(sink.stb & sink.sop & sink.ack, crc.ce.eq(1), NextState("COPY"))) fsm.act( "COPY", crc.data.eq(sink.data), If(sink.stb & sink.ack, crc.ce.eq(1), If(sink.eop, NextState("RESET")))) self.comb += self.busy.eq(~fsm.ongoing("IDLE"))
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): self.busy = Signal() self.sink = Sink(CMD_REC) self.source = Source([('d',8), ('last',1)]) sm = FSM(reset_state="IDLE") self.submodules += sm self.comb += [ self.source.stb.eq(0), self.source.payload.last.eq(0) ] ssum = Signal(8) token_next = Record(CMD_REC) token = Record(CMD_REC) self.comb += token_next.eq(token) self.sync += token.eq(token_next) sm.act("IDLE", If(self.sink.stb, self.sink.ack.eq(1), token_next.eq(self.sink.payload), NextState('c0'))) _outs = [ 0x55, Cat(token.a[8:14], 0, token.wr), token.a[0:8], token.d, ssum ] s = _outs[0] for i in _outs[1:-1]: s = s + i self.sync += ssum.eq(s) for c, v in enumerate(_outs): _last = 1 if c == len(_outs) - 1 else 0 _next = "IDLE" if _last else "c%d" % (c + 1) sm.act("c%d" % c, self.source.stb.eq(1), self.source.payload.d.eq(v), self.source.payload.last.eq(_last), If(self.source.ack, NextState(_next) ))
def __init__(self): self.busy=Signal() self.sink = Sink([('d',8)]) self.source = Source(CMD_REC) sm = FSM(reset_state="IDLE") self.submodules += sm # Basic checksum token = self.source.payload token_next = Record(CMD_REC) self.sync += token.eq(token_next) self.comb += token_next.eq(token) sm.act("IDLE", self.sink.ack.eq(1), If(self.sink.stb, If(self.sink.payload.d == 0x55, NextState("ADRH") ))) def parse_state(st, to, *update): sm.act(st, self.sink.ack.eq(1), If(self.sink.stb, NextState(to), *update )) parse_state('ADRH', 'ADRL', token_next.wr.eq(self.sink.payload.d[7]), token_next.a[8:14].eq(self.sink.payload.d[:6])) parse_state('ADRL', 'DATA', token_next.a[0:8].eq(self.sink.payload.d)), parse_state('DATA', 'CKSUM', token_next.d.eq(self.sink.payload.d)), sm.act("CKSUM", self.sink.ack.eq(1), If(self.sink.stb, NextState('ISSUE') ) ) sm.act("ISSUE", self.source.stb.eq(1), If(self.source.ack, NextState('IDLE')))
def __init__(self, N): self.tag_helper = Signal((N, True)) self.tag_helper_update = Signal() self.tag_main = Signal((N, True)) self.tag_main_update = Signal() self.output = Signal((N + 1, True)) # # # fsm = FSM(reset_state="IDLE") self.submodules += fsm tag_collector = Signal((N + 1, True)) fsm.act( "IDLE", If(self.tag_main_update & self.tag_helper_update, NextValue(tag_collector, 0), NextState("UPDATE")).Elif( self.tag_main_update, NextValue(tag_collector, self.tag_main), NextState("WAITHELPER")).Elif( self.tag_helper_update, NextValue(tag_collector, -self.tag_helper), NextState("WAITMAIN"))) fsm.act( "WAITHELPER", If(self.tag_helper_update, NextValue(tag_collector, tag_collector - self.tag_helper), NextState("LEADCHECK"))) fsm.act( "WAITMAIN", If(self.tag_main_update, NextValue(tag_collector, tag_collector + self.tag_main), NextState("LAGCHECK"))) # To compensate DDMTD counter roll-over when main is ahead of roll-over # and helper is after roll-over fsm.act( "LEADCHECK", If(tag_collector > 0, NextValue(tag_collector, tag_collector - (2**N - 1))), NextState("UPDATE")) # To compensate DDMTD counter roll-over when helper is ahead of roll-over # and main is after roll-over fsm.act( "LAGCHECK", If(tag_collector < 0, NextValue(tag_collector, tag_collector + (2**N - 1))), NextState("UPDATE")) fsm.act("UPDATE", NextValue(self.output, tag_collector), NextState("IDLE"))
def __init__(self, stream_slicer): self.source = stream.Endpoint(record_layout) self.end_marker_found = Signal() self.flush = Signal() hdrlen = (layout_len(record_layout) - 512)//8 record_raw = Record(record_layout) self.comb += [ record_raw.raw_bits().eq(stream_slicer.source), self.source.channel.eq(record_raw.channel), self.source.timestamp.eq(record_raw.timestamp), self.source.address.eq(record_raw.address), Case(record_raw.length, {hdrlen+i: self.source.data.eq(record_raw.data[:i*8]) for i in range(1, 512//8+1)}), ] fsm = FSM(reset_state="FLOWING") self.submodules += fsm fsm.act("FLOWING", If(stream_slicer.source_stb, If(record_raw.length == 0, NextState("END_MARKER_FOUND") ).Else( self.source.stb.eq(1) ) ), If(self.source.ack, stream_slicer.source_consume.eq(record_raw.length) ) ) fsm.act("END_MARKER_FOUND", self.end_marker_found.eq(1), If(self.flush, stream_slicer.flush.eq(1), NextState("WAIT_FLUSH") ) ) fsm.act("WAIT_FLUSH", If(stream_slicer.flush_done, NextState("SEND_EOP") ) ) fsm.act("SEND_EOP", self.source.eop.eq(1), self.source.stb.eq(1), If(self.source.ack, NextState("FLOWING")) )
def __init__(self, pads, params): self.params = p = params self.data = [ Signal(p.width, reset_less=True) for i in range(p.channels) ] # data to be output, MSB first self.start = Signal() # start transfer self.done = Signal() # transfer complete, next transfer can be # started ### assert p.clk >= 1 cnt = Signal(max=max(2, p.clk), reset_less=True) cnt_done = Signal() cnt_next = Signal() self.comb += cnt_done.eq(cnt == 0) self.sync += [ If(cnt_done, If(cnt_next, cnt.eq(p.clk - 1))).Else(cnt.eq(cnt - 1)) ] for i, d in enumerate(self.data): self.comb += getattr(pads, "mosi{}".format(i)).eq( d[-1]) # mosi = MSB of d bits = Signal(max=p.width + 1, reset_less=True) self.submodules.fsm = fsm = CEInserter()(FSM("IDLE")) self.comb += fsm.ce.eq(cnt_done) fsm.act("IDLE", self.done.eq(1), pads.cs_n.eq(1), If(self.start, cnt_next.eq(1), NextState("SETUP"))) fsm.act("SETUP", cnt_next.eq(1), If(bits == 0, NextState("IDLE")).Else(NextState("HOLD"))) fsm.act("HOLD", cnt_next.eq(1), pads.clk.eq(1), NextState("SETUP")) self.sync += [ If( fsm.ce, If( fsm.before_leaving("HOLD"), bits.eq(bits - 1), [d[1:].eq(d) for d in self.data] # shift d = d << 1 ), If(fsm.ongoing("IDLE"), bits.eq(p.width))) ]
def __init__(self, crc_class, layout): self.sink = sink = Sink(layout, True) self.source = source = Source(layout, True) self.busy = Signal() ### dw = flen(sink.d) self.submodules.crc = crc_class(dw) self.submodules.fsm = fsm = FSM(reset_state="IDLE") fsm.act("IDLE", self.crc.reset.eq(1), sink.ack.eq(1), If(sink.stb & sink.sop, sink.ack.eq(0), NextState("COPY"), ) ) fsm.act("COPY", self.crc.ce.eq(sink.stb & source.ack), self.crc.d.eq(sink.d), Record.connect(sink, source), source.eop.eq(0), If(sink.stb & sink.eop & source.ack, NextState("INSERT"), ) ) ratio = self.crc.width//dw cnt = Signal(max=ratio, reset=ratio-1) cnt_done = Signal() fsm.act("INSERT", source.stb.eq(1), chooser(self.crc.value, cnt, source.d, reverse=True), If(cnt_done, source.eop.eq(1), If(source.ack, NextState("IDLE")) ) ) self.comb += cnt_done.eq(cnt == 0) self.sync += \ If(fsm.ongoing("IDLE"), cnt.eq(cnt.reset) ).Elif(fsm.ongoing("INSERT") & ~cnt_done, cnt.eq(cnt - source.ack) ) self.comb += self.busy.eq(~fsm.ongoing("IDLE"))