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, 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, pads, dacs): self.reset = Signal() self.dcm_sel = Signal() self.sink = Sink(bus_layout) ### self.sink.ack.reset = 1 self.submodules.rg = ResetGen() # two stage synchronizer for inputs frame = Signal.like(pads.frame) trigger = Signal() arm = Signal() start = Signal() soft_trigger = Signal() self.specials += MultiReg(pads.trigger, trigger) self.sync += [ frame.eq(pads.frame), pads.aux.eq(Cat(*(dac.out.aux for dac in dacs)) != 0), #pads.go2_out.eq( # Cat(*(dac.out.sink.stb for dac in dacs)) != 0), #pads.go2_out.eq(pads.go2_in), # loop #pads.go2_out.eq(0), ] self.comb += [ self.reset.eq(self.rg.reset), pads.reset.eq(ResetSignal()), ] for dac in dacs: self.sync += [ dac.parser.frame.eq(frame), dac.out.trigger.eq(arm & (trigger | soft_trigger)), dac.out.arm.eq(arm), dac.parser.arm.eq(arm), dac.parser.start.eq(start), ] self.sync += [ If( self.sink.stb, Case( self.sink.payload.data, { 0x00: self.rg.trigger.eq(1), #0x01: self.rg.trigger.eq(0), 0x02: soft_trigger.eq(1), 0x03: soft_trigger.eq(0), 0x04: arm.eq(1), 0x05: arm.eq(0), 0x06: self.dcm_sel.eq(1), 0x07: self.dcm_sel.eq(0), 0x08: start.eq(1), 0x09: start.eq(0), })) ]
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, 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): 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, 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, board, dacs): self.sink = Sink(mem_layout) ### mems = [dac.parser.mem.get_port(write_capable=True) for dac in dacs] self.specials += mems dac = Signal(max=len(dacs)) adr = Signal(16) end = Signal(16) listen = Signal() we = Signal() inc = Signal() pd = self.sink.payload.data self.sink.ack.reset = 1 self.comb += Array(m.we for m in mems)[dac].eq(we) for mem in mems: self.comb += [mem.adr.eq(adr), mem.dat_w.eq(pd)] self.submodules.fsm = fsm = FSM(reset_state="DEV") fsm.act("DEV", If(self.sink.stb, NextState("START"))) fsm.act("START", If(self.sink.stb, NextState("END"))) fsm.act("END", If(self.sink.stb, NextState("DATA"))) fsm.act( "DATA", If(self.sink.stb, we.eq(listen), inc.eq(1), If(adr == end, NextState("DEV")))) self.sync += [ If( fsm.ongoing("DEV"), dac.eq(pd[:4]), listen.eq(pd[4:4 + flen(board)] == board), ), If(fsm.ongoing("START"), adr.eq(pd)), If(fsm.ongoing("END"), end.eq(pd)), If(fsm.ongoing("DATA"), If(inc, adr.eq(adr + 1))) ]
def __init__(self, pads, tuning_word): self.sink = Sink([("data", 8)]) ### uart_clk_txen = Signal() phase_accumulator_tx = Signal(32) pads.tx.reset = 1 tx_reg = Signal(8) tx_bitcount = Signal(4) tx_busy = Signal() self.sync += [ self.sink.ack.eq(0), If(self.sink.stb & ~tx_busy & ~self.sink.ack, tx_reg.eq(self.sink.data), tx_bitcount.eq(0), tx_busy.eq(1), pads.tx.eq(0) ).Elif(uart_clk_txen & tx_busy, tx_bitcount.eq(tx_bitcount + 1), If(tx_bitcount == 8, pads.tx.eq(1) ).Elif(tx_bitcount == 9, pads.tx.eq(1), tx_busy.eq(0), self.sink.ack.eq(1), ).Else( pads.tx.eq(tx_reg[0]), tx_reg.eq(Cat(tx_reg[1:], 0)) ) ) ] self.sync += [ If(tx_busy, Cat(phase_accumulator_tx, uart_clk_txen).eq(phase_accumulator_tx + tuning_word) ).Else( Cat(phase_accumulator_tx, uart_clk_txen).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, 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, name): self.sink = Sink(data_layout) self.recv = [] SimActor.__init__(self, self.gen(name))
def __init__(self): self.dout = Sink(slave_layout) self.din = Source(slave_layout) self.busy = Signal()
def __init__(self, wrport, depth, consume_watermark, ena, la_filters=[]): self.ulpi_sink = Sink(ULPI_DATA_TAG) self.out_addr = Source(dmatpl(depth)) # Produce side self.submodules.produce_write = Acc_inc(max=depth) self.submodules.produce_header = Acc(max=depth) self.consume_point = Acc(max=depth) self.submodules.size = Acc_inc(16) self.submodules.flags = Acc_or(16) self.submodules.to_start = Acc(1) # Header format: # A0 F0 F1 SL SH 00 00 00 d0....dN # Flags format # # F0.0 - ERR - Line level error (ULPI.RXERR asserted during packet) # F0.1 - OVF - RX Path Overflow (shouldn't happen - debugging) # F0.2 - CLIP - Filter clipped (we do not set yet) # F0.3 - PERR - Protocol level err (but ULPI was fine, ???) # # Following not implemented yet # F0.6 - SHORT - short packet, no size, fixed 4 byte data # F0.7 - EXT - Extended header self.submodules.fsm = FSM() has_space = Signal() self.comb += has_space.eq( ((consume_watermark - self.produce_write.v - 1) & (depth - 1)) > 8) # Grab packet timestamp at SOP pkt_timestamp = Signal(flen(self.ulpi_sink.payload.ts)) self.sync += If(self.ulpi_sink.payload.is_start & self.ulpi_sink.ack, pkt_timestamp.eq(self.ulpi_sink.payload.ts)) payload_is_rxcmd = Signal() self.comb += payload_is_rxcmd.eq(self.ulpi_sink.payload.is_start | self.ulpi_sink.payload.is_end | self.ulpi_sink.payload.is_err | self.ulpi_sink.payload.is_ovf) # Packet first/last bits clear_acc_flags = Signal() en_last = Signal() self.sync += en_last.eq(ena) self.submodules.packet_first = Acc(1) self.submodules.packet_last = Acc(1) # Stuff-packet bit # At start-of-capture or end-of-capture, we stuff a packet to # indicate the exact time of capture stuff_packet = Signal() self.comb += stuff_packet.eq(self.packet_first.v | self.packet_last.v) self.comb += If(ena & ~en_last, self.packet_first.set(1)).Elif( clear_acc_flags, self.packet_first.set(0)) self.comb += If(~ena & en_last, self.packet_last.set(1)).Elif(clear_acc_flags, self.packet_last.set(0)) flags_ini = Signal(16) self.comb += flags_ini.eq( Mux(self.packet_last.v, HF0_LAST, 0) | Mux(self.packet_first.v, HF0_FIRST, 0)) # Combine outputs of filters la_resets = [f.reset.eq(1) for f in la_filters] filter_done = 1 filter_reject = 0 for f in la_filters: filter_done = f.done & filter_done filter_reject = f.reject | filter_reject self.fsm.act( "IDLE", If(((self.ulpi_sink.stb | self.to_start.v) & ena | stuff_packet) & has_space, If(~self.to_start.v | (self.ulpi_sink.stb & stuff_packet), self.ulpi_sink.ack.eq(1)), self.produce_write.set(self.produce_header.v + 8), self.size.set(0), self.flags.set(flags_ini), self.to_start.set(0), la_resets, If(self.ulpi_sink.payload.is_start | self.to_start.v, NextState("DATA")).Elif( stuff_packet, NextState("WH0"), clear_acc_flags.eq(1), ) # If not enabled, we just dump RX'ed data ).Elif(~ena, self.ulpi_sink.ack.eq(1))) def write_hdr(statename, nextname, hdr_offs, val): self.fsm.act(statename, NextState(nextname), wrport.adr.eq(self.produce_header.v + hdr_offs), wrport.dat_w.eq(val), wrport.we.eq(1)) do_filter_write = Signal() # Feed data to lookaside filters for f in la_filters: self.comb += [ f.write.eq(do_filter_write), f.dat_w.eq(self.ulpi_sink.payload) ] packet_too_long = Signal() self.comb += packet_too_long.eq(self.size.v >= MAX_PACKET_SIZE) self.fsm.act( "DATA", If(packet_too_long, self.flags._or(HF0_TRUNC), NextState("WH0")).Elif( has_space & self.ulpi_sink.stb, self.ulpi_sink.ack.eq(1), If( payload_is_rxcmd, # Got another start-of-packet If( self.ulpi_sink.payload.is_start, self.flags._or(HF0_OVF), # If we got a SOP, we need to skip RXCMD det in IDLE self.to_start.set(1) # Mark error if we hit an error ).Elif( self.ulpi_sink.payload.is_err, self.flags._or(HF0_ERR), # Mark overflow if we got a stuffed overflow ).Elif(self.ulpi_sink.payload.is_ovf, self.flags._or(HF0_OVF)), # In any case (including END), we're done RXing NextState("waitdone")).Else( self.size.inc(), self.produce_write.inc(), wrport.adr.eq(self.produce_write.v), wrport.dat_w.eq(self.ulpi_sink.payload.d), wrport.we.eq(1), do_filter_write.eq(1)))) self.fsm.act( "waitdone", If( filter_done, If(filter_reject, NextState("IDLE")).Else(clear_acc_flags.eq(1), NextState("WH0")))) write_hdr("WH0", "WRF0", 0, 0xA0) # Write flags field write_hdr("WRF0", "WRF1", 1, self.flags.v[:8]) write_hdr("WRF1", "WRSL", 2, self.flags.v[8:16]) # Write size field write_hdr("WRSL", "WRSH", 3, self.size.v[:8]) write_hdr("WRSH", "WRTL", 4, self.size.v[8:16]) write_hdr("WRTL", "WRTM", 5, pkt_timestamp[:8]) write_hdr("WRTM", "WRTH", 6, pkt_timestamp[8:16]) write_hdr("WRTH", "SEND", 7, pkt_timestamp[16:24]) self.fsm.act( "SEND", self.out_addr.stb.eq(1), self.out_addr.payload.start.eq(self.produce_header.v), self.out_addr.payload.count.eq(self.size.v + 8), If(self.out_addr.ack, self.produce_header.set(self.produce_write.v), NextState("IDLE")))
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): self.sink = Sink(dmatpl(1024)) SimActor.__init__(self, _deferred_sink_gen())
def __init__(self): self.sink = Sink(line_layout) self.trigger = Signal() self.aux = Signal() self.silence = Signal() self.arm = Signal() self.data = Signal(16) ### line = Record(line_layout) dt_dec = Signal(16) dt_end = Signal(16) dt = Signal(16) adv = Signal() tic = Signal() toc = Signal() stb = Signal() toc0 = Signal() inc = Signal() lp = self.sink.payload self.comb += [ adv.eq(self.arm & self.sink.stb & (self.trigger | ~(line.header.wait | lp.header.trigger))), tic.eq(dt_dec == dt_end), toc.eq(dt == line.dt), stb.eq(tic & toc & adv), self.sink.ack.eq(stb), inc.eq(self.arm & tic & (~toc | (~toc0 & ~adv))), ] subs = [ Volt(lp, stb & (lp.header.typ == 0), inc), Dds(lp, stb & (lp.header.typ == 1), inc), ] for i, sub in enumerate(subs): self.submodules += sub self.sync += [ toc0.eq(toc), self.data.eq(optree("+", [sub.data for sub in subs])), self.aux.eq(line.header.aux), self.silence.eq(line.header.silence), If( ~tic, dt_dec.eq(dt_dec + 1), ).Elif( ~toc, dt_dec.eq(0), dt.eq(dt + 1), ).Elif( stb, line.header.eq(lp.header), line.dt.eq(lp.dt - 1), dt_end.eq((1 << lp.header.shift) - 1), dt_dec.eq(0), dt.eq(0), ) ]
def __init__(self): self.sink = Sink(D_LAST) SimActor.__init__(self, _deferred_sink_gen())
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, description): self.sink = Sink(description) # # # self.packet = Packet()
def __init__(self, hostif, max_burst_length=256): width = flen(hostif.d_write) assert width == 16 awidth = flen(hostif.i_addr) + 1 self.sink = Sink([('d', 8), ('last', 1)]) self.submodules.sdram_fifo = SyncFIFO(width, max_burst_length) self.submodules.fifo_write_fsm = FSM() self.wptr = Signal(awidth) # rptr (from SDRAM Source) self.rptr = Signal(awidth) # CSRs self._ptr_read = CSRStorageEx(1) ptr_read = self._ptr_read.re self._wptr = description.CSRStatus(awidth) self.sync += If(ptr_read, self._wptr.status.eq(self.wptr)) self._rptr = description.CSRStatus(awidth) self.sync += If(ptr_read, self._rptr.status.eq(self.rptr)) self._ring_base = description.CSRStorage(awidth) self._ring_end = description.CSRStorage(awidth) self._go = description.CSRStorage(1) go = self._go.storage[0] # 'go'-signal edge detect gor = Signal() self.sync += gor.eq(go) self._wrap_count = Perfcounter(ptr_read, go & ~gor) # wptr wrap around wrap = Signal() self.comb += wrap.eq(self.wptr == self._ring_end.storage) wptr_next = Signal(awidth) self.comb += If(wrap, wptr_next.eq(self._ring_base.storage)).Else( wptr_next.eq(self.wptr + 1)) # debug self._debug_ctl = CSRStorageEx(1) snapshot = self._debug_ctl.re perf_reset = self._debug_ctl.storage[0] self._debug_i_stb = Perfcounter(snapshot, perf_reset) self._debug_i_ack = Perfcounter(snapshot, perf_reset) self._debug_d_stb = Perfcounter(snapshot, perf_reset) self._debug_d_term = Perfcounter(snapshot, perf_reset) self._debug_s0 = Perfcounter(snapshot, perf_reset) self._debug_s1 = Perfcounter(snapshot, perf_reset) self._debug_s2 = Perfcounter(snapshot, perf_reset) self._perf_busy = Perfcounter(snapshot, perf_reset) self.comb += If(hostif.i_stb, self._debug_i_stb.inc()) self.comb += If(hostif.i_ack, self._debug_i_ack.inc()) self.comb += If(hostif.d_stb, self._debug_d_stb.inc()) self.comb += If(hostif.d_term, self._debug_d_term.inc()) self.comb += If(~self.sdram_fifo.writable, self._perf_busy.inc()) # FSM to move FIFO data to SDRAM burst_rem = Signal(max=max_burst_length) burst_rem_next = Signal(max=max_burst_length) self.comb += burst_rem_next.eq(burst_rem) self.sync += burst_rem.eq(burst_rem_next) self.comb += hostif.i_wr.eq(1) blocked = Signal() self.comb += blocked.eq(self.rptr == wptr_next) # start writing data if # - 'go'-signal set, and # - input data available # - not blocked self.fifo_write_fsm.act( "IDLE", self._debug_s0.inc(), If(self.sdram_fifo.readable & go & ~blocked, hostif.i_addr.eq(self.wptr), hostif.i_stb.eq(1), burst_rem_next.eq(max_burst_length - 1)), If(hostif.i_ack, NextState("WRITE"))) self.comb += hostif.d_write.eq(self.sdram_fifo.dout) # stop writing if # - max burst length reached, or # - no more input data, or # - wrap # - blocked self.fifo_write_fsm.act( "WRITE", self._debug_s1.inc(), hostif.d_term.eq((burst_rem == 0) | ~self.sdram_fifo.readable | wrap | blocked), self.sdram_fifo.re.eq(hostif.d_stb & ~hostif.d_term), If(~hostif.d_term & hostif.d_stb, burst_rem_next.eq(burst_rem_next - 1)), If(hostif.d_term & ~hostif.d_stb, NextState("WAIT")).Elif(hostif.d_term & hostif.d_stb, NextState("IDLE"))) self.fifo_write_fsm.act("WAIT", self._debug_s2.inc(), hostif.d_term.eq(1), If(hostif.d_stb, NextState("IDLE"))) # wrap around counter self.comb += If(wrap & hostif.d_stb & ~hostif.d_term, self._wrap_count.inc()) # update wptr self.sync += If( go & ~gor, self.wptr.eq(self._ring_base.storage), ).Elif((hostif.d_stb & ~hostif.d_term) | wrap, self.wptr.eq(wptr_next)) # sink into fifo self.submodules.fifo_fsm = FSM() capture_low = Signal() din_low = Signal(8) self.comb += self.sdram_fifo.din.eq(Cat(din_low, self.sink.payload.d)) self.sync += If(capture_low, din_low.eq(self.sink.payload.d)) self.fifo_fsm.act("READ_LOW", capture_low.eq(1), self.sink.ack.eq(1), If(self.sink.stb, NextState("READ_HI"))) self.fifo_fsm.act( "READ_HI", self.sdram_fifo.we.eq(self.sink.stb), self.sink.ack.eq(self.sdram_fifo.writable), If(self.sink.ack & self.sink.stb, NextState("READ_LOW")))
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)