def __init__(self, layout, escape=0xa5): self.sink = i = Sink(layout) self.source_a = oa = Source(layout) self.source_b = ob = Source(layout) self.busy = Signal() ### is_escape = Signal() was_escape = Signal() ctrl = Cat(i.ack, oa.stb, ob.stb) self.sync += [ If(i.ack & i.stb, was_escape.eq(is_escape & ~was_escape)) ] self.comb += [ oa.payload.eq(i.payload), ob.payload.eq(i.payload), is_escape.eq(i.stb & (i.payload.raw_bits() == escape)), If( is_escape == was_escape, # 00 or 11: data, oa ctrl.eq(Cat(oa.ack, i.stb, 0)), ).Elif( is_escape, # 01, swallow ctrl.eq(Cat(1, 0, 0)), ).Else( # 10, command, ob ctrl.eq(Cat(ob.ack, 0, i.stb)), ) ]
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): self.sink = Sink(ULPI_DATA_D) self.source = Source(ULPI_DATA_D) self._ctl = CSRStorageEx(1) snapshot = self._ctl.re reset = self._ctl.storage[0] self._num_ovf = Perfcounter(snapshot, reset) self._num_total = Perfcounter(snapshot, reset) self.comb += If(self.sink.stb, self._num_total.inc()) self.comb += If(self.source.stb & ~self.source.ack, self._num_ovf.inc()) valid = Signal() data = Record(ULPI_DATA_D) self.comb += [If( self.sink.stb, self.sink.ack.eq(1), )] self.sync += [ If( self.sink.stb, valid.eq(1), If( valid & ~self.source.ack, data.rxcmd.eq(1), data.d.eq(RXCMD_MAGIC_OVF), ).Else(data.eq(self.sink.payload))).Elif( self.source.ack, valid.eq(0)) ] self.comb += [self.source.stb.eq(valid), self.source.payload.eq(data)]
def __init__(self, description, last_be=None): self.source = Source(description) self.last_be = last_be # # # self.packets = [] self.packet = Packet() self.packet.done = True
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._size = description.CSRStorage(8, reset=8) self._cfg = description.CSRStorage(1, reset=0) self.source = Source([('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, 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, 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.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, description, level=0): self.level = level self.sink = Sink(description) self.source = Source(description) self.run = Signal() self.comb += \ If(self.run, Record.connect(self.sink, self.source) ).Else( self.source.stb.eq(0), self.sink.ack.eq(0), )
def __init__(self, pads, tuning_word): self.source = Source([("data", 8)]) ### uart_clk_rxen = Signal() phase_accumulator_rx = Signal(32) rx = Signal() self.specials += MultiReg(pads.rx, rx) rx_r = Signal() rx_reg = Signal(8) rx_bitcount = Signal(4) rx_busy = Signal() rx_done = self.source.stb rx_data = self.source.data self.sync += [ rx_done.eq(0), rx_r.eq(rx), If(~rx_busy, If(~rx & rx_r, # look for start bit rx_busy.eq(1), rx_bitcount.eq(0), ) ).Else( If(uart_clk_rxen, rx_bitcount.eq(rx_bitcount + 1), If(rx_bitcount == 0, If(rx, # verify start bit rx_busy.eq(0) ) ).Elif(rx_bitcount == 9, rx_busy.eq(0), If(rx, # verify stop bit rx_data.eq(rx_reg), rx_done.eq(1) ) ).Else( rx_reg.eq(Cat(rx_reg[1:], rx)) ) ) ) ] self.sync += \ If(rx_busy, Cat(phase_accumulator_rx, uart_clk_rxen).eq(phase_accumulator_rx + tuning_word) ).Else( Cat(phase_accumulator_rx, uart_clk_rxen).eq(2**31) )
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"))
def __init__(self, pads, *args, **kwargs): self.sink = Sink([("data", 8)]) self.source = Source([("data", 8)]) self.comb += [ pads.source_stb.eq(self.sink.stb), pads.source_data.eq(self.sink.data), self.sink.ack.eq(pads.source_ack), self.source.stb.eq(pads.sink_stb), self.source.data.eq(pads.sink_data), pads.sink_ack.eq(self.source.ack) ] m, s = pty.openpty() name = os.ttyname(s) print("UART tty: " + name) time.sleep(0.5) # pause for user f = open("/tmp/simserial", "w") f.write(os.ttyname(s)) f.close()
def __init__(self, pads, clk=10.): self.source = do = Source(bus_layout) self.busy = Signal() # t_RDLl_Dv = 50 ns (setup) # t_RDLh_Di = 0ns (hold) # t_RDLl_RDLh = 50 ns (redundant, <= r_RDLl_Dv) # t_RDLh_RXFLh = 25ns (from FT245R) (redundant, <= t_RDLh_RDLl) # t_RXFLh_RXFLl = 80ns (from FT245R) # t_RDLh_RDLl = 50ns + t_RXh_RXl (we understand this as a # conditional addition) # we read every t_hold + t_precharge + t_setup + 2 cycles # can only sustain 1MByte/s anyway at full speed USB # stb implicitly needs to be acked within a read cycle #clk /= 4 # slow it down t_latch = int(ceil(50 / clk)) # t_RDLl_Dv t_drop = t_latch + int(ceil(20 / clk)) # slave skew t_refill = t_drop + int(ceil(50 / clk)) # t_RDLh_RDLl reading = Signal() # proxy rxfl to slaves, drive rdl self.comb += [ pads.rdl.eq(~pads.rd_out), self.busy.eq(~do.stb | do.ack) ] self.sync += [ If( ~reading & ~pads.rd_in, pads.rd_out.eq(~pads.rxfl), ), do.stb.eq(do.stb & ~do.ack), timeline(pads.rd_in, [ (0, [reading.eq(1)]), (t_latch, [do.stb.eq(1), do.payload.data.eq(pads.data)]), (t_drop, [pads.rd_out.eq(0)]), (t_refill, [reading.eq(0)]), ]) ]
def __init__(self): self._cfg = CSRStorage(8) self._stat = CSRStatus(8) self.sink = Sink(ULPI_DATA) self.source = Source([("d", 8), ("last", 1)]) latch_d = Signal() latched = Signal(8) self.sync += If(latch_d, latched.eq(self.sink.payload.d)) self.submodules.fsm = FSM() self.fsm.act("IDLE", self.sink.ack.eq(1), If(self.sink.stb & self._cfg.storage[0], latch_d.eq(1), If(self.sink.payload.rxcmd, NextState("RXCMD") ).Else(NextState("UDATA")))) self.fsm.act("RXCMD", self.source.payload.d.eq(0xAC), self.source.stb.eq(1), If(self.source.ack, NextState("SENDB")) ) self.fsm.act("UDATA", self.source.payload.d.eq(0xAD), self.source.stb.eq(1), If(self.source.ack, NextState("SENDB")) ) self.fsm.act("SENDB", self.source.payload.d.eq(latched), self.source.payload.last.eq(1), self.source.stb.eq(1), If(self.source.ack, NextState("IDLE")))
def __init__(self, mux_ports): self.source = Source([('d', 8)]) n = len(mux_ports) self.submodules.rr = RoundRobin(n, SP_CE) granted = self.rr.grant release = Signal() request = Signal() released = Signal(reset=1) self.sync += If(self.rr.ce, released.eq(0)).Elif( release, released.eq(1)) self.comb += request.eq(self.rr.request != 0) self.comb += self.rr.ce.eq(request & released) for i, port in enumerate(mux_ports): _grant = Signal(name="grant_to_%d" % i) self.comb += [ _grant.eq(granted == i), If(granted == i, self.source.payload.d.eq(port.source.payload.d), release.eq(self.source.ack & port.source.stb & port.source.payload.last), self.source.stb.eq(port.source.stb), ), port.source.ack.eq(self.source.ack & _grant), self.rr.request[i].eq(port.source.stb) ]
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) fsm = FSM(reset_state="RESET_CRC") self.submodules += fsm fsm.act("RESET_CRC", sink.ack.eq(0), self.crc.reset.eq(1), NextState("IDLE") ) fsm.act("IDLE", sink.ack.eq(sink.stb), If(sink.stb & sink.sop, Record.connect(sink, source), self.crc.ce.eq(sink.ack), self.crc.d.eq(sink.d), NextState("COPY") ) ) fsm.act("COPY", Record.connect(sink, source), self.crc.ce.eq(sink.stb & sink.ack), self.crc.d.eq(sink.d), source.error.eq(sink.eop & self.crc.error), If(sink.stb & sink.ack & sink.eop, NextState("RESET_CRC") ) ) self.comb += self.busy.eq(~fsm.ongoing("IDLE"))
def __init__(self): self.sink = Sink(ULPI_DATA_D) self.source = Source(ULPI_DATA_D) valid = Signal() data = Record(ULPI_DATA_D) self.comb += [If( self.sink.stb, self.sink.ack.eq(1), )] self.sync += [ If( self.sink.stb, valid.eq(1), If( valid & ~self.source.ack, data.rxcmd.eq(1), data.d.eq(RXCMD_MAGIC_OVF), ).Else(data.eq(self.sink.payload))).Elif( self.source.ack, valid.eq(0)) ] self.comb += [self.source.stb.eq(valid), self.source.payload.eq(data)]
def __init__(self, slaves, depth=256, bus=None, with_wishbone=True): time_width, addr_width, data_width = [_[1] for _ in ventilator_layout] self.submodules.ctrl = CycleControl() self.submodules.ev = ev = EventManager() ev.in_readable = EventSourceLevel() ev.out_overflow = EventSourceProcess() ev.in_overflow = EventSourceLevel() ev.out_readable = EventSourceProcess() ev.stopped = EventSourceProcess() ev.started = EventSourceProcess() ev.finalize() self._in_time = CSRStatus(time_width) self._in_addr = CSRStatus(addr_width) self._in_data = CSRStatus(data_width) self._in_next = CSR() self._in_flush = CSR() self._out_time = CSRStorage(time_width, write_from_dev=with_wishbone) self._out_addr = CSRStorage(addr_width, write_from_dev=with_wishbone) self._out_data = CSRStorage(data_width, write_from_dev=with_wishbone) self._out_next = CSR() self._out_flush = CSR() self.busy = Signal() ### if with_wishbone: if bus is None: bus = wishbone.Interface() self.bus = bus slaves = [(self.ctrl, 0x00000000, 0xffffff00)] + slaves self.submodules.in_fifo = in_fifo = SyncFIFOBuffered( ventilator_layout, depth) self.submodules.out_fifo = out_fifo = SyncFIFOBuffered( ventilator_layout, depth) self.submodules.enc = PriorityEncoder(len(slaves)) wb_in_next = Signal() wb_out_next = Signal() out_request = Signal() in_request = Signal() # CSRs and Events self.comb += [ ev.in_readable.trigger.eq(in_fifo.readable), ev.out_overflow.trigger.eq(~out_fifo.writable), ev.in_overflow.trigger.eq(~in_fifo.writable), ev.out_readable.trigger.eq(out_fifo.readable), ev.started.trigger.eq(~self.ctrl.run), ev.stopped.trigger.eq(self.ctrl.run), self.ctrl.have_in.eq(~self.enc.n), self.ctrl.have_out.eq(out_fifo.readable), self._in_time.status.eq(in_fifo.dout.time), self._in_addr.status.eq(in_fifo.dout.addr), self._in_data.status.eq(in_fifo.dout.data), in_fifo.re.eq(self._in_next.re | wb_in_next), in_fifo.flush.eq(self._in_flush.re), out_fifo.din.time.eq(self._out_time.storage), out_fifo.din.addr.eq(self._out_addr.storage), out_fifo.din.data.eq(self._out_data.storage), out_fifo.we.eq(self._out_next.re | wb_out_next), out_fifo.flush.eq(self._out_flush.re), ] # din dout strobing self.comb += [ # TODO: 0 <= diff <= plausibility range out_request.eq(out_fifo.readable & self.ctrl.run & (self.ctrl.cycle == out_fifo.dout.time)), # ignore in_fifo.writable in_request.eq(~self.enc.n & self.ctrl.run), self.busy.eq(out_request | in_request), ] # to slaves addrs = [] datas = [] stbs = [] acks = [] for i, (slave, prefix, mask) in enumerate(slaves): prefix &= mask source = Source(slave_layout) sink = Sink(slave_layout) self.comb += [ source.connect(slave.dout), sink.connect(slave.din), ] sel = Signal() acks.append(sel & source.ack) addrs.append(prefix | (sink.payload.addr & (~mask & 0xffffffff))) datas.append(sink.payload.data) stbs.append(sink.stb) self.comb += [ sel.eq(out_fifo.dout.addr & mask == prefix), source.payload.addr.eq(out_fifo.dout.addr), source.payload.data.eq(out_fifo.dout.data), source.stb.eq(sel & out_request), sink.ack.eq((self.enc.o == i) & in_request), ] self.comb += out_fifo.re.eq(out_request & optree("|", acks)) # from slaves self.comb += [ self.enc.i.eq(Cat(stbs)), in_fifo.din.time.eq(self.ctrl.cycle), in_fifo.din.addr.eq(Array(addrs)[self.enc.o]), in_fifo.din.data.eq(Array(datas)[self.enc.o]), in_fifo.we.eq(in_request), ] # optional high throughput wishbone access if with_wishbone: self.comb += [ self._out_time.dat_w.eq(bus.dat_w), self._out_addr.dat_w.eq(bus.dat_w), self._out_data.dat_w.eq(bus.dat_w), If(bus.cyc & bus.stb, If(bus.we, Case(bus.adr[:4], { 0x5: wb_in_next.eq(1), 0x6: self._out_time.we.eq(1), 0x7: self._out_addr.we.eq(1), 0x8: self._out_data.we.eq(1), 0x9: wb_out_next.eq(1), }), ), Case(bus.adr[:4], { 0x0: bus.dat_r.eq(self.ctrl.cycle), 0x1: bus.dat_r.eq(self.ev.status.w), 0x2: bus.dat_r.eq(in_fifo.dout.time), 0x3: bus.dat_r.eq(in_fifo.dout.addr), 0x4: bus.dat_r.eq(in_fifo.dout.data), }), )] self.sync += bus.ack.eq(bus.cyc & bus.stb & ~bus.ack)
def __init__(self): self.sink = Sink(ULPI_DATA_D) self.source = Source(ULPI_DATA_TAG) is_sop = Signal() is_eop = Signal() is_ovf = Signal() is_nop = Signal() is_active = Signal() is_nactive = Signal() is_error = Signal() ts_counter = Signal(flen(self.source.payload.ts)) self.comb += [ is_sop.eq(self.sink.payload.rxcmd & (self.sink.payload.d == RXCMD_MAGIC_SOP)), is_eop.eq(self.sink.payload.rxcmd & (self.sink.payload.d == RXCMD_MAGIC_EOP)), is_ovf.eq(self.sink.payload.rxcmd & (self.sink.payload.d == RXCMD_MAGIC_OVF)), is_nop.eq(self.sink.payload.rxcmd & (self.sink.payload.d == RXCMD_MAGIC_NOP)), is_active.eq(self.sink.payload.rxcmd & ~self.sink.payload.d[6] & (self.sink.payload.d[4:6] == 0x1)), is_nactive.eq(self.sink.payload.rxcmd & ~self.sink.payload.d[6] & (self.sink.payload.d[4:6] == 0x0)), is_error.eq(self.sink.payload.rxcmd & ~self.sink.payload.d[6] & (self.sink.payload.d[4:6] == 0x3)), self.source.payload.d.eq(self.sink.payload.d), self.source.payload.ts.eq(ts_counter) ] self.sync += If(self.sink.ack, ts_counter.eq(ts_counter + 1)) self.submodules.fsm = FSM() def pass_(state): return send(state, 0, 0, 0, 0) def send(state, is_start, is_end, is_err, is_ovf): return [ self.source.stb.eq(1), self.source.payload.is_start.eq(is_start), self.source.payload.is_end.eq(is_end), self.source.payload.is_err.eq(is_err), self.source.payload.is_ovf.eq(is_ovf), If(self.source.ack, self.sink.ack.eq(1), NextState(state) ) ] def skip(state): return [ self.sink.ack.eq(1), NextState(state) ] def act(state, *args): self.fsm.act(state, If(self.sink.stb, If(~self.sink.payload.rxcmd, pass_(state) ).Elif(is_nop, self.sink.ack.eq(1), ).Else(*args))) act("NO_PACKET", If(is_sop | is_active, send("PACKET", 1, 0, 0, 0) ).Else( skip("NO_PACKET") )) act("PACKET", If(is_eop | is_nactive, send("NO_PACKET", 0, 1, 0, 0) ).Elif(is_error, send("NO_PACKET", 0, 0, 1, 0) ).Elif(is_ovf, send("NO_PACKET", 0, 0, 0, 1) ).Else( skip("PACKET") ))
def __init__(self, data): self.source = Source(data_layout) SimActor.__init__(self, self.gen(data))
def __init__(self, slaves, depth=256, bus=None, with_wishbone=True): time_width, addr_width, data_width = [_[1] for _ in ventilator_layout] self.submodules.ctrl = CycleControl() self.submodules.ev = ev = EventManager() ev.in_readable = EventSourceLevel() ev.out_overflow = EventSourceProcess() ev.in_overflow = EventSourceLevel() ev.out_readable = EventSourceProcess() ev.stopped = EventSourceProcess() ev.started = EventSourceProcess() ev.finalize() self._in_time = CSRStatus(time_width) self._in_addr = CSRStatus(addr_width) self._in_data = CSRStatus(data_width) self._in_next = CSR() self._in_flush = CSR() self._out_time = CSRStorage(time_width, write_from_dev=with_wishbone) self._out_addr = CSRStorage(addr_width, write_from_dev=with_wishbone) self._out_data = CSRStorage(data_width, write_from_dev=with_wishbone) self._out_next = CSR() self._out_flush = CSR() self.busy = Signal() ### if with_wishbone: if bus is None: bus = wishbone.Interface() self.bus = bus slaves = [(self.ctrl, 0x00000000, 0xffffff00)] + slaves self.submodules.in_fifo = in_fifo = SyncFIFOBuffered( ventilator_layout, depth) self.submodules.out_fifo = out_fifo = SyncFIFOBuffered( ventilator_layout, depth) self.submodules.enc = PriorityEncoder(len(slaves)) wb_in_next = Signal() wb_out_next = Signal() out_request = Signal() in_request = Signal() # CSRs and Events self.comb += [ ev.in_readable.trigger.eq(in_fifo.readable), ev.out_overflow.trigger.eq(~out_fifo.writable), ev.in_overflow.trigger.eq(~in_fifo.writable), ev.out_readable.trigger.eq(out_fifo.readable), ev.started.trigger.eq(~self.ctrl.run), ev.stopped.trigger.eq(self.ctrl.run), self.ctrl.have_in.eq(~self.enc.n), self.ctrl.have_out.eq(out_fifo.readable), self._in_time.status.eq(in_fifo.dout.time), self._in_addr.status.eq(in_fifo.dout.addr), self._in_data.status.eq(in_fifo.dout.data), in_fifo.re.eq(self._in_next.re | wb_in_next), in_fifo.flush.eq(self._in_flush.re), out_fifo.din.time.eq(self._out_time.storage), out_fifo.din.addr.eq(self._out_addr.storage), out_fifo.din.data.eq(self._out_data.storage), out_fifo.we.eq(self._out_next.re | wb_out_next), out_fifo.flush.eq(self._out_flush.re), ] # din dout strobing self.comb += [ # TODO: 0 <= diff <= plausibility range out_request.eq(out_fifo.readable & self.ctrl.run & (self.ctrl.cycle == out_fifo.dout.time)), # ignore in_fifo.writable in_request.eq(~self.enc.n & self.ctrl.run), self.busy.eq(out_request | in_request), ] # to slaves addrs = [] datas = [] stbs = [] acks = [] for i, (slave, prefix, mask) in enumerate(slaves): prefix &= mask source = Source(slave_layout) sink = Sink(slave_layout) self.comb += [ source.connect(slave.dout), sink.connect(slave.din), ] sel = Signal() acks.append(sel & source.ack) addrs.append(prefix | (sink.payload.addr & (~mask & 0xffffffff))) datas.append(sink.payload.data) stbs.append(sink.stb) self.comb += [ sel.eq(out_fifo.dout.addr & mask == prefix), source.payload.addr.eq(out_fifo.dout.addr), source.payload.data.eq(out_fifo.dout.data), source.stb.eq(sel & out_request), sink.ack.eq((self.enc.o == i) & in_request), ] self.comb += out_fifo.re.eq(out_request & optree("|", acks)) # from slaves self.comb += [ self.enc.i.eq(Cat(stbs)), in_fifo.din.time.eq(self.ctrl.cycle), in_fifo.din.addr.eq(Array(addrs)[self.enc.o]), in_fifo.din.data.eq(Array(datas)[self.enc.o]), in_fifo.we.eq(in_request), ] # optional high throughput wishbone access if with_wishbone: self.comb += [ self._out_time.dat_w.eq(bus.dat_w), self._out_addr.dat_w.eq(bus.dat_w), self._out_data.dat_w.eq(bus.dat_w), If( bus.cyc & bus.stb, If( bus.we, Case( bus.adr[:4], { 0x5: wb_in_next.eq(1), 0x6: self._out_time.we.eq(1), 0x7: self._out_addr.we.eq(1), 0x8: self._out_data.we.eq(1), 0x9: wb_out_next.eq(1), }), ), Case( bus.adr[:4], { 0x0: bus.dat_r.eq(self.ctrl.cycle), 0x1: bus.dat_r.eq(self.ev.status.w), 0x2: bus.dat_r.eq(in_fifo.dout.time), 0x3: bus.dat_r.eq(in_fifo.dout.addr), 0x4: bus.dat_r.eq(in_fifo.dout.data), }), ) ] self.sync += bus.ack.eq(bus.cyc & bus.stb & ~bus.ack)
def __init__(self): self.source = Source(ULPI_DATA_D) SimActor.__init__(self, gen())
def __init__(self, ulpi, ulpi_reg): ulpi_data_out = Signal(8) ulpi_data_tristate = Signal() ulpi_data_next = Signal(8) ulpi_data_tristate_next = Signal() ulpi_stp_next = Signal() ulpi_state_rx = Signal() ulpi_state_rrd = Signal() self.data_out_source = Source(ULPI_DATA) RegWriteReqR = Signal() RegReadReqR = Signal() RegWriteReq = Signal() RegReadReq = Signal() RegReadAckSet = Signal() RegWriteAckSet = Signal() # register the reg read/write requests self.sync += RegReadReqR.eq(ulpi_reg.rreq) self.sync += RegWriteReqR.eq(ulpi_reg.wreq) # signal when read/write is requested but not done self.comb += RegReadReq.eq(RegReadReqR & ~ulpi_reg.rack) v = (RegReadReqR & ~ulpi_reg.rack) self.comb += RegWriteReq.eq(RegWriteReqR & ~ulpi_reg.wack) # ack logic: set ack=0 when req=0, set ack=1 when access done self.sync += If(~RegReadReqR, ulpi_reg.rack.eq(0) ).Elif(RegReadAckSet, ulpi_reg.rack.eq(1)) self.sync += If(~RegWriteReqR, ulpi_reg.wack.eq(0) ).Elif(RegWriteAckSet, ulpi_reg.wack.eq(1)) exp = If(~RegWriteReqR, ulpi_reg.wack.eq(0)).Elif(RegWriteAckSet, ulpi_reg.wack.eq(1)) # output data if required by state self.comb += ulpi.stp.eq(ulpi_stp_next) self.comb += ulpi_data_out.eq(ulpi_data_next) self.comb += ulpi_data_tristate.eq(ulpi_data_tristate_next) self.comb += ulpi.do.eq(ulpi_data_out) self.comb += ulpi.doe.eq(~ulpi_data_tristate) # capture RX data at the end of RX, but only if no turnaround was requested # We also support "stuffing" data, to indicate conditions such as: # - Simultaneous DIR + NXT assertion # (the spec doesn't require an RXCMD - DIR+NXT asserting may be the' # only SOP signal) # - End-of-packet # (Packets may end without an RXCMD, unless an error occurs) ulpi_rx_stuff = Signal() ulpi_rx_stuff_d = Signal(8) self.sync += self.data_out_source.stb.eq(ulpi_state_rx & ulpi.dir | ulpi_rx_stuff) self.sync += If(ulpi_rx_stuff, self.data_out_source.payload.d.eq(ulpi_rx_stuff_d), self.data_out_source.payload.rxcmd.eq(1) ).Else( If(~ulpi.nxt, self.data_out_source.payload.d.eq(ulpi.di & RXCMD_MASK), self.data_out_source.payload.rxcmd.eq(1) ).Else( self.data_out_source.payload.d.eq(ulpi.di), self.data_out_source.payload.rxcmd.eq(0) ) ) # capture register reads at the end of RRD self.sync += If(ulpi_state_rrd,ulpi_reg.rdata.eq(ulpi.di)) fsm = FSM() self.submodules += fsm fsm.act("IDLE", ulpi_data_next.eq(0x00), # NOOP ulpi_data_tristate_next.eq(0), ulpi_stp_next.eq(0), If(~ulpi.dir & ~ulpi.nxt & ~(RegWriteReq | RegReadReq), NextState("IDLE") ).Elif(ulpi.dir, # TA, and then either RXCMD or Data NextState("RX"), ulpi_data_tristate_next.eq(1), # If dir & nxt, we're starting a packet, so stuff a custom SOP If(ulpi.nxt, ulpi_rx_stuff.eq(1), ulpi_rx_stuff_d.eq(RXCMD_MAGIC_SOP) ) ).Elif(RegWriteReq, NextState("RW0"), ulpi_data_next.eq(0x80 | ulpi_reg.waddr), # REGW ulpi_data_tristate_next.eq(0), ulpi_stp_next.eq(0) ).Elif(RegReadReq, NextState("RR0"), ulpi_data_next.eq(0xC0 | ulpi_reg.raddr), # REGR ulpi_data_tristate_next.eq(0), ulpi_stp_next.eq(0) ).Else( NextState("ERROR") )) fsm.act("RX", If(ulpi.dir, # stay in RX NextState("RX"), ulpi_state_rx.eq(1), ulpi_data_tristate_next.eq(1) ).Else( # TA back to idle # Stuff an EOP on return to idle ulpi_rx_stuff.eq(1), ulpi_rx_stuff_d.eq(RXCMD_MAGIC_EOP), ulpi_data_tristate_next.eq(0), NextState("IDLE") )) fsm.act("RW0", If(ulpi.dir, NextState("RX"), ulpi_data_tristate_next.eq(1), ).Elif(~ulpi.dir, ulpi_data_next.eq(0x80 | ulpi_reg.waddr), # REGW ulpi_data_tristate_next.eq(0), ulpi_stp_next.eq(0), If(ulpi.nxt, NextState("RWD")).Else(NextState("RW0")), ).Else( NextState("ERROR") )) fsm.act("RWD", If(ulpi.dir, NextState("RX"), ulpi_data_tristate_next.eq(1) ).Elif(~ulpi.dir & ulpi.nxt, NextState("RWS"), ulpi_data_next.eq(ulpi_reg.wdata), ulpi_data_tristate_next.eq(0), ulpi_stp_next.eq(0) ).Else( NextState("ERROR") ), ) fsm.act("RWS", If(~ulpi.dir, NextState("IDLE"), ulpi_data_next.eq(0x00), # NOOP ulpi_data_tristate_next.eq(0), ulpi_stp_next.eq(1), RegWriteAckSet.eq(1) ).Elif(ulpi.dir, NextState("RX"), ulpi_data_tristate_next.eq(1), ), ) fsm.act("RR0", If(~ulpi.dir, ulpi_data_next.eq(0xC0 | ulpi_reg.raddr), # REGR NextState("RR1") ).Elif(ulpi.dir, NextState("RX"), RegWriteAckSet.eq(1) ).Else( NextState("ERROR") )) fsm.act("RR1", If(~ulpi.dir & ulpi.nxt, # PHY accepts REGR ulpi_data_tristate_next.eq(1), # TA NextState("RR2") ).Elif(~ulpi.dir & ~ulpi.nxt, # PHY delays REGR ulpi_data_next.eq(0xC0 | ulpi_reg.raddr), # REGR NextState("RR1") ).Elif(ulpi.dir, NextState("RX"), RegWriteAckSet.eq(1) ).Else( NextState("ERROR") )) fsm.act("RR2", ulpi_data_tristate_next.eq(1), If(~ulpi.nxt, # REGR continue NextState("RRD") ).Elif(ulpi.dir, # PHY indicates RX NextState("RX"), RegWriteAckSet.eq(1) ).Else( NextState("ERROR") )) fsm.act("RRD", If(ulpi.dir & ~ulpi.nxt, NextState("IDLE"), RegReadAckSet.eq(1), ulpi_state_rrd.eq(1), ).Elif(ulpi.dir & ulpi.nxt, NextState("RX"), RegWriteAckSet.eq(1) ).Else( NextState("ERROR") ), ulpi_data_tristate_next.eq(1), ) fsm.act("ERROR", NextState("IDLE"))
def __init__(self): self.source = Source(dmatpl(1024)) SimActor.__init__(self, gen())
def __init__(self): self.source = Source(ULPI_DATA_TAG) SimActor.__init__(self, _deferred_source_gen())
def __init__(self): self.source = Source(dmatpl(1024)) SimActor.__init__(self, _deferred_src_gen())
def __init__(self, hostif, host_burst_length = 16): width = flen(hostif.d_write) assert width == 16 awidth = flen(hostif.i_addr) + 1 self.source = Source([('d', 8), ('last', 1)]) go = Signal() gor = Signal() rptr = Signal(awidth) self.rptr = rptr rptr_w = Signal(awidth) rptr_we = Signal() self.wptr = Signal(awidth) # CSRs ## self._debug_i_stb = description.CSRStatus(32) self._debug_i_ack = description.CSRStatus(32) self._debug_d_stb = description.CSRStatus(32) self._debug_d_term = description.CSRStatus(32) self._debug_s0 = description.CSRStatus(32) self._debug_s1 = description.CSRStatus(32) self._debug_s2 = description.CSRStatus(32) self.submodules.i_stb_acc = Acc_inc(32) self.submodules.i_ack_acc = Acc_inc(32) self.submodules.d_stb_acc = Acc_inc(32) self.submodules.d_term_acc = Acc_inc(32) self.comb += self._debug_i_stb.status.eq(self.i_stb_acc.v) self.comb += self._debug_i_ack.status.eq(self.i_ack_acc.v) self.comb += self._debug_d_stb.status.eq(self.d_stb_acc.v) self.comb += self._debug_d_term.status.eq(self.d_term_acc.v) self.comb += If(hostif.i_stb, self.i_stb_acc.inc()) self.comb += If(hostif.i_ack, self.i_ack_acc.inc()) self.comb += If(hostif.d_stb, self.d_stb_acc.inc()) self.comb += If(hostif.d_term, self.d_term_acc.inc()) self.submodules.s0_acc = Acc_inc(32) self.submodules.s1_acc = Acc_inc(32) self.submodules.s2_acc = Acc_inc(32) self.comb += self._debug_s0.status.eq(self.s0_acc.v) self.comb += self._debug_s1.status.eq(self.s1_acc.v) self.comb += self._debug_s2.status.eq(self.s2_acc.v) ## self._ring_base = description.CSRStorage(awidth) self._ring_end = description.CSRStorage(awidth) # rptr readback self._rptr_status = description.CSRStatus(awidth) self.comb += self._rptr_status.status.eq(rptr) # 'go' bit self._go = description.CSRStorage(1) self.comb += go.eq(self._go.storage[0]) self.sync += gor.eq(go) # state machine to read self.submodules.sdram_read_fsm = FSM() sdram_fifo = SyncFIFO(width, host_burst_length) self.submodules += sdram_fifo # we always read (never write) self.comb += hostif.i_wr.eq(0) # blocked blocked = Signal() self.comb += blocked.eq(rptr == self.wptr) # wait until there's data and go, and then when the fifo has space, issue request. self.sdram_read_fsm.act("BLOCKED", self.s2_acc.inc(), If(go & ~blocked, NextState("IDLE")) ) self.sdram_read_fsm.act("IDLE", self.s0_acc.inc(), hostif.i_addr.eq(rptr), hostif.i_stb.eq(sdram_fifo.writable), If (hostif.i_stb & hostif.i_ack, NextState("DATA") ) ) # read until fifo is full; when fifo is not writable but data was received, # abort SDRAM read request. wrap = Signal() self.comb += wrap.eq(self.rptr == self._ring_end.storage) self.sdram_read_fsm.act("DATA", self.s1_acc.inc(), hostif.d_term.eq(~sdram_fifo.writable | ~go | blocked | wrap), If (hostif.d_term, If (hostif.d_stb, NextState("BLOCKED") ).Else( NextState("WAIT") ) ) ) self.sdram_read_fsm.act("WAIT", hostif.d_term.eq(1), If (hostif.d_stb, NextState("BLOCKED") ) ) # allow rptr to be updated via CSR. Otherwise, # increment read point whenever valid data is fed into the fifo. rptr_next = Signal(awidth) self.comb += If(wrap, rptr_next.eq(self._ring_base.storage)).Else(rptr_next.eq(self.rptr + 1)) self.sync += \ If(go &~ gor, rptr.eq(self._ring_base.storage), ).Elif(hostif.d_stb &~hostif.d_term | wrap, rptr.eq(rptr_next)) self.comb += sdram_fifo.we.eq(hostif.d_stb &~ hostif.d_term) self.comb += sdram_fifo.din.eq(hostif.d_read) # fifo to host interface self.submodules.host_write_fsm = FSM() burst_rem = Signal(max = host_burst_length) burst_rem_next = Signal(max = host_burst_length) self.comb += burst_rem_next.eq(burst_rem) self.sync += burst_rem.eq(burst_rem_next) # when the sdram_fifo is not anymore writable, start bursting out that data. self.host_write_fsm.act("IDLE", self.source.payload.d.eq(0xD0), self.source.stb.eq(sdram_fifo.readable &~ sdram_fifo.writable), If(self.source.ack & self.source.stb, NextState("SEND_HEADER") ) ) self.host_write_fsm.act("SEND_HEADER", self.source.payload.d.eq(host_burst_length - 1), self.source.stb.eq(1), If(self.source.ack & self.source.stb, burst_rem_next.eq(host_burst_length - 1), NextState("SEND_DATA_ODD") ) ) # when byte available, write low byte until ack'ed. self.host_write_fsm.act("SEND_DATA_ODD", self.source.payload.d.eq(sdram_fifo.dout[0:8]), self.source.stb.eq(sdram_fifo.readable), If (self.source.stb & self.source.ack, NextState("SEND_DATA_EVEN") ) ) # write high byte. when ack'ed, read next byte, unless we hit the burst length limit. self.host_write_fsm.act("SEND_DATA_EVEN", self.source.payload.d.eq(sdram_fifo.dout[8:16]), self.source.payload.last.eq(burst_rem == 0), self.source.stb.eq(1), sdram_fifo.re.eq(self.source.ack), If (self.source.ack, If (burst_rem != 0, NextState("SEND_DATA_ODD"), burst_rem_next.eq(burst_rem - 1) ).Else( NextState("IDLE") ) ) )
def __init__(self): self.dout = Sink(slave_layout) self.din = Source(slave_layout) self.busy = Signal()
def __init__(self, data): self.source = Source(bus_layout) gen = (Token("source", {"data": _}) for _ in data) SimActor.__init__(self, gen)