def __init__(self, sample_clk_ticks, sample_width, full_width): self.freq_out = CSRStatus(full_width) self.num_events = CSRStatus(full_width) self.num_samples = CSRStatus(full_width) self.last_inc = CSRStatus(sample_width) # TODO: Perhaps configure the number of dest clk ticks before # number of events is latched? self.submodules.core = FreqCountCore(sample_width, full_width) ### self.comb += [ self.freq_out.status.eq(self.core.count_latched), self.num_events.status.eq(self.core.count_curr), self.last_inc.status.eq(self.core.sampler.inc) ] # sample_clk_ticks = 0 is a legal sample period. It means sample each cycle. self.sync.dest += [ self.core.latch.eq(0), If(self.num_samples.status == sample_clk_ticks, self.num_samples.status.eq(0), self.core.latch.eq(1)).Else( self.num_samples.status.eq(self.num_samples.status + 1)) ]
def cross_connect(gpio, chains): state_names = ["force"] + ["di%i" % i for i in range(len(gpio.i))] states = [1, gpio.i] signal_names = ["zero"] signals = Array([0]) for n, c in chains: for s in c.state_out: states.append(s) state_names.append("%s_%s" % (n, s.backtrace[-1][0])) for s in c.signal_out: signals.append(s) name = s.backtrace[-1][0] signal_names.append("%s_%s" % (n, name)) sig = CSRStatus(len(s), name=name) clr = CSR(name="%s_clr" % name) max = CSRStatus(len(s), name="%s_max" % name) min = CSRStatus(len(s), name="%s_min" % name) # setattr(c, sig.name, sig) setattr(c, clr.name, clr) setattr(c, max.name, max) setattr(c, min.name, min) c.comb += sig.status.eq(s) c.sync += If(clr.re | (max.status < s), max.status.eq(s)) c.sync += If(clr.re | (min.status > s), min.status.eq(s)) states = Cat(states) state = Signal(len(states)) gpio.comb += state.eq(states) gpio.state = CSRStatus(len(state)) gpio.state_clr = CSR() gpio.sync += [ If( gpio.state_clr.re, gpio.state.status.eq(0), ).Else(gpio.state.status.eq(gpio.state.status | state), ) ] # connect gpio output to "doi%i_en" for i, s in enumerate(gpio.o): csr = CSRStorage(len(state), name="do%i_en" % i) setattr(gpio, csr.name, csr) gpio.sync += s.eq((state & csr.storage) != 0) # connect state ins to "%s_en" and signal ins to "%s_sel" for n, c in chains: for s in c.state_in: csr = CSRStorage(len(state), name="%s_en" % s.backtrace[-1][0]) setattr(c, csr.name, csr) c.sync += s.eq((state & csr.storage) != 0) for s in c.signal_in: csr = CSRStorage(bits_for(len(signals) - 1), name="%s_sel" % s.backtrace[-1][0]) setattr(c, csr.name, csr) c.sync += s.eq(signals[csr.storage]) return state_names, signal_names
def init_csr(self, width, signal_width, chain_factor_width): factor_reset = 1 << (chain_factor_width - 1) # we use chain_factor_width + 1 for the single channel mode self.dual_channel = CSRStorage(1) self.chain_a_factor = CSRStorage(chain_factor_width + 1, reset=factor_reset) self.chain_b_factor = CSRStorage(chain_factor_width + 1, reset=factor_reset) self.chain_a_offset = CSRStorage(width) self.chain_b_offset = CSRStorage(width) self.chain_a_offset_signed = Signal((width, True)) self.chain_b_offset_signed = Signal((width, True)) self.combined_offset = CSRStorage(width) self.combined_offset_signed = Signal((width, True)) self.out_offset = CSRStorage(width) self.out_offset_signed = Signal((width, True)) self.mod_channel = CSRStorage(1) self.control_channel = CSRStorage(1) self.sweep_channel = CSRStorage(2) self.slow_value = CSRStatus(width) max_decimation = 16 self.slow_decimation = CSRStorage(bits_for(max_decimation)) for i in range(4): if i == 0: continue name = "analog_out_%d" % i setattr(self, name, CSRStorage(15, name=name))
def __init__(self, width=14, N_points=16383, max_delay=16383): self.submodules.robust = RobustAutolock(max_delay=max_delay) self.submodules.fast = FastAutolock(width=width) self.request_lock = CSRStorage() self.autolock_mode = CSRStorage(2) self.lock_running = CSRStatus() self.comb += [ self.fast.request_lock.eq(self.request_lock.storage), self.robust.request_lock.eq(self.request_lock.storage), ] self.sync += [ If( ~self.request_lock.storage, self.lock_running.status.eq(0), ), If( self.request_lock.storage & self.fast.turn_on_lock & (self.autolock_mode.storage == FAST_AUTOLOCK), self.lock_running.status.eq(1), ), If( self.request_lock.storage & self.robust.turn_on_lock & (self.autolock_mode.storage == ROBUST_AUTOLOCK), self.lock_running.status.eq(1), ), ]
def _add_register(self, register, name): if not isinstance(register, _Register): register = register( ) # create a register instance to retrieve attributes in case a class was passed logger.debug( f"Creating register {name} of type {register.__class__.__name__}.") name_csr = f"{name}_csr" if register.depth == 1: if register.readonly: register_instance = CSRStatus(size=register.width, reset=register.default, name=name_csr) setattr(self, name_csr, register_instance) setattr(self, name, register_instance.status) else: register_instance = CSRStorage(size=register.width, reset=register.default, name=name_csr) setattr(self, name_csr, register_instance) setattr(self, name, register_instance.storage) setattr(self, f"{name}_re", register_instance.re) else: # register has nontrivial depth if register.readonly: register_instance = CSRStorage(size=register.width, reset=register.default, name=name_csr, write_from_dev=True) setattr(self, name_csr, register_instance) setattr(self, name, register_instance.dat_w) setattr(self, f"{name}_re", register_instance.re) setattr(self, f"{name}_we", register_instance.we) setattr(self, f"{name}_index", register_instance.storage)
def __init__(self, version=0b1000001): n = 64 self.dna = CSRStatus(n, reset=version << 57) ### do = Signal() cnt = Signal(max=2 * n + 1) self.specials += Instance( "DNA_PORT", i_DIN=self.dna.status[-1], o_DOUT=do, i_CLK=cnt[0], i_READ=cnt < 2, i_SHIFT=1, ) self.sync += [ If( cnt < 2 * n, cnt.eq(cnt + 1), If(cnt[0], self.dna.status.eq(Cat(do, self.dna.status))), ) ]
def __init__(self, io): self._program = CSRStorage() self._done = CSRStatus() self._error = CSRStatus() self._divisor = CSRStorage(32) self._data = CSRStorage(32) self._start = CSR() self._busy = CSRStatus() # # # ctr = Signal.like(self._divisor.storage) clk2x = Signal() self.comb += [ clk2x.eq(ctr == 0), ] self.sync += [ If(ctr == 0, ctr.eq(self._divisor.storage)).Else(ctr.eq(ctr - 1)) ] shreg = Signal.like(self._data.storage) bits = Signal(max=shreg.nbits) busy = Signal() clk = Signal() self.comb += [busy.eq(bits != 0), self._busy.status.eq(busy)] self.sync += [ If(self._start.re & self._start.r, clk.eq(0), bits.eq(shreg.nbits - 1), shreg.eq(self._data.storage)).Elif( clk2x & busy, clk.eq(~clk), If(clk, bits.eq(bits - 1), shreg.eq(shreg >> 1))) ] self.sync += [ io.program_b.eq(~self._program.storage), io.din.eq(shreg[0]), io.cclk.eq(clk) ] self.specials += [ MultiReg(io.done, self._done.status), MultiReg(~io.init_b, self._error.status) ]
def __init__(self, width): self.x = Signal((width, True)) self.y = Signal((width, True)) self.hold = Signal() self.clear = Signal() self.error = Signal() if False: self.y_current = CSRStatus(width) self.comb += self.y_current.status.eq(self.y)
def __init__(self, bus): self.burst_request = Signal() self._status = CSRStatus(10) ### dr, da = attrgetter("dr", "da")(bus) burst_type = dmac_bus.Type.burst flush_type = dmac_bus.Type.flush # control self.submodules.fsm = fsm = FSM(reset_state="IDLE") fsm.act( "IDLE", If( da.valid & (da.type == flush_type), NextState("ACK_FLUSH"), ).Elif( self.burst_request, dr.valid.eq(1), dr.type.eq(burst_type), If( dr.ready, NextState("READ"), ), ), ) fsm.act("ACK_FLUSH", dr.valid.eq(1), dr.type.eq(flush_type), If( dr.ready, NextState("IDLE"), )) fsm.act( "READ", If( da.valid, If( da.type == flush_type, NextState("ACK_FLUSH"), ).Elif( da.type == burst_type, NextState("IDLE"), ))) da_type = Signal(len(da.type), reset=0x3) self.sync += If(da.valid, da_type.eq(da.type)) self.comb += [ da.ready.eq(1), self._status.status.eq( Cat(self.burst_request, C(0, (3, False)), fsm.ongoing("IDLE"), fsm.ongoing("READ"), C(0, (2, False)), da_type)), ]
def __init__(self, pins): n = len(pins) self.i = Signal(n) self.o = Signal(n) self.ins = CSRStatus(n) self.outs = CSRStorage(n) self.oes = CSRStorage(n) ### t = [TSTriple(1) for i in range(n)] self.specials += [ti.get_tristate(pins[i]) for i, ti in enumerate(t)] self.specials += MultiReg(Cat([ti.i for ti in t]), self.i) self.comb += [ Cat([ti.o for ti in t]).eq(self.outs.storage | self.o), Cat([ti.oe for ti in t]).eq(self.oes.storage), self.ins.status.eq(self.i), ]
def get_remote_csr_regions(offset, csv_file): busword = 32 regions = [] for region_name, csrs_info in _get_csr_data(csv_file).items(): csrs_info = sorted(csrs_info, key=itemgetter(1)) origin = csrs_info[0][1] next_address = origin csrs = [] for csr_name, address, length, ro in csrs_info: if address != next_address: raise ValueError("CSRs are not contiguous") nr = (length + busword - 1) // busword next_address += nr * busword // 8 if ro: csr = CSRStatus(length, name=csr_name) else: csr = CSRStorage(length, name=csr_name) csrs.append(csr) regions.append((region_name, offset + origin, busword, csrs)) return regions
def __init__(self): self.id = CSRStatus(1, reset=1)
def __init__(self, hostif, host_burst_length=16): width = len(hostif.d_write) assert width == 16 awidth = len(hostif.i_addr) + 1 self.source = Endpoint([('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 = CSRStatus(32) self._debug_i_ack = CSRStatus(32) self._debug_d_stb = CSRStatus(32) self._debug_d_term = CSRStatus(32) self._debug_s0 = CSRStatus(32) self._debug_s1 = CSRStatus(32) self._debug_s2 = 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 = CSRStorage(awidth) self._ring_end = CSRStorage(awidth) # rptr readback self._rptr_status = CSRStatus(awidth) self.comb += self._rptr_status.status.eq(rptr) # 'go' bit self._go = 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, pads, default=_default_edid): self._hpd_notif = CSRStatus() self._hpd_en = CSRStorage() self.specials.mem = Memory(8, 128, init=default) ### # HPD if hasattr(pads, "hpd_notif"): self.specials += MultiReg(pads.hpd_notif, self._hpd_notif.status) else: self.comb += self._hpd_notif.status.eq(1) if hasattr(pads, "hpd_en"): self.comb += pads.hpd_en.eq(self._hpd_en.storage) # EDID scl_raw = Signal() sda_i = Signal() sda_raw = Signal() sda_drv = Signal() _sda_drv_reg = Signal() _sda_i_async = Signal() self.sync += _sda_drv_reg.eq(sda_drv) self.specials += [ MultiReg(pads.scl, scl_raw), Tristate(pads.sda, 0, _sda_drv_reg, _sda_i_async), MultiReg(_sda_i_async, sda_raw) ] scl_i = Signal() samp_count = Signal(6) samp_carry = Signal() self.sync += [ Cat(samp_count, samp_carry).eq(samp_count + 1), If(samp_carry, scl_i.eq(scl_raw), sda_i.eq(sda_raw)) ] scl_r = Signal() sda_r = Signal() scl_rising = Signal() sda_rising = Signal() sda_falling = Signal() self.sync += [scl_r.eq(scl_i), sda_r.eq(sda_i)] self.comb += [ scl_rising.eq(scl_i & ~scl_r), sda_rising.eq(sda_i & ~sda_r), sda_falling.eq(~sda_i & sda_r) ] start = Signal() self.comb += start.eq(scl_i & sda_falling) din = Signal(8) counter = Signal(max=9) self.sync += [ If(start, counter.eq(0)), If( scl_rising, If(counter == 8, counter.eq(0)).Else(counter.eq(counter + 1), din.eq(Cat(sda_i, din[:7])))) ] is_read = Signal() update_is_read = Signal() self.sync += If(update_is_read, is_read.eq(din[0])) offset_counter = Signal(max=128) oc_load = Signal() oc_inc = Signal() self.sync += [ If(oc_load, offset_counter.eq(din)).Elif( oc_inc, offset_counter.eq(offset_counter + 1)) ] rdport = self.mem.get_port() self.specials += rdport self.comb += rdport.adr.eq(offset_counter) data_bit = Signal() zero_drv = Signal() data_drv = Signal() self.comb += If(zero_drv, sda_drv.eq(1)).Elif(data_drv, sda_drv.eq(~data_bit)) data_drv_en = Signal() data_drv_stop = Signal() self.sync += If(data_drv_en, data_drv.eq(1)).Elif(data_drv_stop, data_drv.eq(0)) self.sync += If( data_drv_en, chooser(rdport.dat_r, counter, data_bit, 8, reverse=True)) fsm = FSM() self.submodules += fsm fsm.act("WAIT_START") fsm.act( "RCV_ADDRESS", If( counter == 8, If(din[1:] == 0x50, update_is_read.eq(1), NextState("ACK_ADDRESS0")).Else(NextState("WAIT_START")))) fsm.act("ACK_ADDRESS0", If(~scl_i, NextState("ACK_ADDRESS1"))) fsm.act("ACK_ADDRESS1", zero_drv.eq(1), If(scl_i, NextState("ACK_ADDRESS2"))) fsm.act( "ACK_ADDRESS2", zero_drv.eq(1), If(~scl_i, If(is_read, NextState("READ")).Else(NextState("RCV_OFFSET")))) fsm.act("RCV_OFFSET", If(counter == 8, oc_load.eq(1), NextState("ACK_OFFSET0"))) fsm.act("ACK_OFFSET0", If(~scl_i, NextState("ACK_OFFSET1"))) fsm.act("ACK_OFFSET1", zero_drv.eq(1), If(scl_i, NextState("ACK_OFFSET2"))) fsm.act("ACK_OFFSET2", zero_drv.eq(1), If(~scl_i, NextState("RCV_ADDRESS"))) fsm.act( "READ", If( ~scl_i, If(counter == 8, data_drv_stop.eq(1), NextState("ACK_READ")).Else(data_drv_en.eq(1)))) fsm.act( "ACK_READ", If(scl_rising, oc_inc.eq(1), If(sda_i, NextState("WAIT_START")).Else(NextState("READ")))) for state in fsm.actions.keys(): fsm.act(state, If(start, NextState("RCV_ADDRESS"))) fsm.act(state, If(~self._hpd_en.storage, NextState("WAIT_START")))
def __init__(self, pads, dummy=15, div=2, with_bitbang=True, endianness="big", dw=32): """ Simple SPI flash, e.g. N25Q128 on the LX9 Microboard. Supports multi-bit pseudo-parallel reads (aka Dual or Quad I/O Fast Read). Only supports mode0 (cpol=0, cpha=0). Optionally supports software bitbanging (for write, erase, or other commands). """ adr_width = 32 - log2_int(dw // 8) self.bus = bus = wishbone.Interface(data_width=dw, adr_width=adr_width) spi_width = len(pads.dq) if with_bitbang: self.bitbang = CSRStorage(4) self.miso = CSRStatus() self.bitbang_en = CSRStorage() ### cs_n = Signal(reset=1) clk = Signal() dq_oe = Signal() read_cmd_params = { 4: (_format_cmd(_QIOFR, 4), 4 * 8), 2: (_format_cmd(_DIOFR, 2), 2 * 8), 1: (_format_cmd(_FAST_READ, 1), 1 * 8) } read_cmd, cmd_width = read_cmd_params[spi_width] addr_width = 24 pads.cs_n.reset = 1 dq = TSTriple(spi_width) self.specials.dq = dq.get_tristate(pads.dq) sr = Signal(max(cmd_width, addr_width, dw)) if endianness == "big": self.comb += bus.dat_r.eq(sr) else: self.comb += bus.dat_r.eq(reverse_bytes(sr)) hw_read_logic = [ pads.clk.eq(clk), pads.cs_n.eq(cs_n), dq.o.eq(sr[-spi_width:]), dq.oe.eq(dq_oe) ] if with_bitbang: bitbang_logic = [ pads.clk.eq(self.bitbang.storage[1]), pads.cs_n.eq(self.bitbang.storage[2]), If(self.bitbang.storage[3], dq.oe.eq(0)).Else(dq.oe.eq(1)), If(self.bitbang.storage[1], self.miso.status.eq(dq.i[1])) ] if spi_width > 1: bitbang_logic += [ dq.o.eq( Cat(self.bitbang.storage[0], Replicate(1, spi_width - 1))) ] else: bitbang_logic += [dq.o.eq(self.bitbang.storage[0])] self.comb += \ If(self.bitbang_en.storage, bitbang_logic ).Else( hw_read_logic ) else: self.comb += hw_read_logic if div < 2: raise ValueError( "Unsupported value \'{}\' for div parameter for SpiFlash core". format(div)) else: i = Signal(max=div) dqi = Signal(spi_width) self.sync += [ If( i == div // 2 - 1, clk.eq(1), dqi.eq(dq.i), ), If(i == div - 1, i.eq(0), clk.eq(0), sr.eq(Cat(dqi, sr[:-spi_width]))).Else(i.eq(i + 1), ), ] # spi is byte-addressed, prefix by zeros z = Replicate(0, log2_int(dw // 8)) seq = [ (cmd_width // spi_width * div, [dq_oe.eq(1), cs_n.eq(0), sr[-cmd_width:].eq(read_cmd)]), (addr_width // spi_width * div, [sr[-addr_width:].eq(Cat(z, bus.adr))]), ((dummy + dw // spi_width) * div, [dq_oe.eq(0)]), (1, [bus.ack.eq(1), cs_n.eq(1)]), ( div, # tSHSL! [bus.ack.eq(0)]), (0, []), ] # accumulate timeline deltas t, tseq = 0, [] for dt, a in seq: tseq.append((t, a)) t += dt self.sync += timeline(bus.cyc & bus.stb & (i == div - 1), tseq)
def __init__(self, xadc): self.alarm = Signal(8) self.ot = Signal() self.adc = [Signal((12, True)) for i in range(4)] self.temp = CSRStatus(12) self.v = CSRStatus(12) self.a = CSRStatus(12) self.b = CSRStatus(12) self.c = CSRStatus(12) self.d = CSRStatus(12) ### self.comb += [ self.adc[0].eq(self.a.status), self.adc[1].eq(self.b.status), self.adc[2].eq(self.c.status), self.adc[3].eq(self.d.status), ] busy = Signal() channel = Signal(7) eoc = Signal() eos = Signal() data = Signal(16) drdy = Signal() vin = Cat(xadc.n[:2], Replicate(0, 6), xadc.n[2:4], Replicate(0, 6), xadc.n[4]) vip = Cat(xadc.p[:2], Replicate(0, 6), xadc.p[2:4], Replicate(0, 6), xadc.p[4]) self.specials += Instance( "XADC", p_INIT_40=0x0000, p_INIT_41=0x2F0F, p_INIT_42=0x0400, # config p_INIT_48=0x0900, p_INIT_49=0x0303, # channels VpVn, Temp p_INIT_4A=0x47E0, p_INIT_4B=0x0000, # avg VpVn, temp p_INIT_4C=0x0800, p_INIT_4D=0x0303, # bipolar p_INIT_4E=0x0000, p_INIT_4F=0x0000, # acq time p_INIT_50=0xB5ED, p_INIT_51=0x57E4, # temp trigger, vccint upper alarms p_INIT_52=0xA147, p_INIT_53=0xCA33, # vccaux upper, temp over upper p_INIT_54=0xA93A, p_INIT_55=0x52C6, # temp reset, vccint lower p_INIT_56=0x9555, p_INIT_57=0xAE4E, # vccaux lower, temp over reset p_INIT_58=0x5999, p_INIT_5C=0x5111, # vbram uppper, vbram lower p_INIT_59=0x5555, p_INIT_5D=0x5111, # vccpint upper lower p_INIT_5A=0x9999, p_INIT_5E=0x91EB, # vccpaux upper lower p_INIT_5B=0x6AAA, p_INIT_5F=0x6666, # vccdro upper lower o_ALM=self.alarm, o_OT=self.ot, o_BUSY=busy, o_CHANNEL=channel, o_EOC=eoc, o_EOS=eos, i_VAUXN=vin[:16], i_VAUXP=vip[:16], i_VN=vin[16], i_VP=vip[16], i_CONVST=0, i_CONVSTCLK=0, i_RESET=ResetSignal(), o_DO=data, o_DRDY=drdy, i_DADDR=channel, i_DCLK=ClockSignal(), i_DEN=eoc, i_DI=0, i_DWE=0, # o_JTAGBUSY=, o_JTAGLOCKED=, o_JTAGMODIFIED=, o_MUXADDR=, ) channels = { 0: self.temp, 3: self.v, 16: self.b, 17: self.c, 24: self.a, 25: self.d, } self.sync += [ If( drdy, Case( channel, dict((k, v.status.eq(data >> 4)) for k, v in channels.items()), ), ) ]
def __init__(self, hostif, max_burst_length=256): width = len(hostif.d_write) assert width == 16 awidth = len(hostif.i_addr) + 1 self.sink = Endpoint([('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 = CSRStorage(1) ptr_read = self._ptr_read.re self._wptr = CSRStatus(awidth) self.sync += If(ptr_read, self._wptr.status.eq(self.wptr)) self._rptr = CSRStatus(awidth) self.sync += If(ptr_read, self._rptr.status.eq(self.rptr)) self._ring_base = CSRStorage(awidth) self._ring_end = CSRStorage(awidth) self._go = 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 = CSRStorage(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 - 1) # CHECKME: was burst_rem_next - 1 which is a comb loop ), 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, clk, cd_rst, ulpi_rst, ulpi_stp_ovr, ulpi_reg): # TESTING - UCFG_RST register # - BRST: reseting of code in the ULPI cd # - URST: reset of external phy # - FSTP: Force assert of STP during reset # (should be part of ULPI cd bringup code) # # Format: # # 7 6 5 4 3 2 1 0 # --------------------------------------- # 0 0 0 0 0 FSTP BRST URST # self._rst = CSRStorage(3) self.comb += ulpi_rst.eq(self._rst.storage[0]) self.comb += cd_rst.eq(self._rst.storage[1]) self.comb += ulpi_stp_ovr.eq(self._rst.storage[2]) # TESTING - UCFG_STAT register # # CKACT: single status bit that indicates whether # the ULPI phy is providing a 60mhz clock signal on clk # # Format: # # 7 6 5 4 3 2 1 0 # ---------------------------------------- # 0 0 0 0 0 0 0 CKACT # self._stat = CSRStatus(1) ulpi_clk_act_cd = Signal(8) # Resample ulpi_clk in sys sys_ulpi_clk = Signal(1) self.specials += MultiReg(clk, sys_ulpi_clk) # Edge detect the ULPI clk last_ulpi_clk = Signal(1) self.sync += [ last_ulpi_clk.eq(sys_ulpi_clk), # On detected transistions, reset the countdown If(last_ulpi_clk != sys_ulpi_clk, ulpi_clk_act_cd.eq(0)).Elif( ulpi_clk_act_cd < 0xFF, ulpi_clk_act_cd.eq(ulpi_clk_act_cd + 1)) ] self.comb += self._stat.status.eq(ulpi_clk_act_cd != 0xFF) # ULPI_xDATA and xCMD registers # # Used for reading/writing ULPI regs # # ULPI_xDATA Format: just 8 bit data reg # # ULPI_xCMD Format: # # 7 6 5 4 3 2 1 0 # ---------------------------------------- # GO 0 UA5 UA4 UA3 UA2 UA1 UA0 # # GO: # - write 1 to start ULPI reg transaction # - stays 1 while transaction in progress # - clears to 0 when transaction complete # # UA5..0 - ULPI register address # To do a write: write UCFG_WDATA with the value # and then write ULPI_WCMD with GO | addr # # To read: write ULPI_RCMD with GO | addr, poll # until GO clear, then read ULPI_RDATA self._wdata = CSRStorage(8) self._wcmd = _ULPI_cmd_reg(ulpi_reg.wreq, ulpi_reg.wack, ulpi_reg.waddr) self.submodules += self._wcmd self.comb += ulpi_reg.wdata.eq(self._wdata.storage) self._rdata = CSRStatus(8) self._rcmd = _ULPI_cmd_reg(ulpi_reg.rreq, ulpi_reg.rack, ulpi_reg.raddr) self.submodules += self._rcmd self.sync += If(ulpi_reg.rack, self._rdata.status.eq(ulpi_reg.rdata))
def __init__(self, snapshot, reset, bits=32): CSRStatus.__init__(self, bits) self.submodules.acc = Acc_inc_sat(bits) self.sync += If(snapshot, self.status.eq(self.acc.v)) self.comb += If(reset, self.acc.set(0))
def __init__(self, depth): self._cfg = CSRStorage(1) debug_signals = 1 storage = Memory(8, depth) self.specials += storage wrport = storage.get_port(write_capable=True) self.specials += wrport rdport = storage.get_port(async_read=False) self.specials += rdport self.submodules.consumer = Consumer(rdport, depth) self.submodules.producer = Producer(wrport, depth, self.consumer.pos, self._cfg.storage[0]) self.sink = self.producer.ulpi_sink self.comb += self.producer.out_addr.connect(self.consumer.sink) self.source = self.consumer.source # Debug signals for state tracing if debug_signals: self._cons_lo = CSRStatus(8) self._cons_hi = CSRStatus(8) self._prod_lo = CSRStatus(8) self._prod_hi = CSRStatus(8) self._prod_hd_lo = CSRStatus(8) self._prod_hd_hi = CSRStatus(8) self._size_lo = CSRStatus(8) self._size_hi = CSRStatus(8) self._prod_state = CSRStatus(8) self._cons_status = CSRStatus(8) self._last_start_lo = CSRStatus(8) self._last_start_hi = CSRStatus(8) self._last_count_lo = CSRStatus(8) self._last_count_hi = CSRStatus(8) self._last_pw_lo = CSRStatus(8) self._last_pw_hi = CSRStatus(8) self.sync += [ self._cons_lo.status.eq(self.consumer.pos[:8]), self._cons_hi.status.eq(self.consumer.pos[8:]), self._prod_lo.status.eq(self.producer.produce_write.v[:8]), self._prod_hi.status.eq(self.producer.produce_write.v[8:]), self._prod_hd_lo.status.eq(self.producer.produce_header.v[:8]), self._prod_hd_hi.status.eq(self.producer.produce_header.v[8:]), self._size_lo.status.eq(self.producer.size.v[:8]), self._size_hi.status.eq(self.producer.size.v[8:]), self._cons_status.status[0].eq(self.consumer.busy), #self._prod_state.status.eq(self.producer.fsm.state), If( self.producer.out_addr.stb & self.producer.out_addr.ack, self._last_start_lo.status.eq( self.producer.out_addr.payload.start[:8]), self._last_start_hi.status.eq( self.producer.out_addr.payload.start[8:]), self._last_count_lo.status.eq( self.producer.out_addr.payload.count[:8]), self._last_count_hi.status.eq( self.producer.out_addr.payload.count[8:]), self._last_pw_lo.status.eq( self.producer.produce_write.v[:8]), self._last_pw_hi.status.eq( self.producer.produce_write.v[8:]), ) ]
def __init__(self, width=14, signal_width=25, chain_factor_width=8): combined_error_signal = Signal((signal_width, True)) self.control_signal = Signal((signal_width, True)) s = signal_width - width factor_reset = 1 << (chain_factor_width - 1) # we use chain_factor_width + 1 for the single channel mode self.dual_channel = CSRStorage(1) self.chain_a_factor = CSRStorage(chain_factor_width + 1, reset=factor_reset) self.chain_b_factor = CSRStorage(chain_factor_width + 1, reset=factor_reset) self.chain_a_offset = CSRStorage(width) self.chain_b_offset = CSRStorage(width) self.chain_a_offset_signed = Signal((width, True)) self.chain_b_offset_signed = Signal((width, True)) self.combined_offset = CSRStorage(width) self.combined_offset_signed = Signal((width, True)) self.out_offset = CSRStorage(width) self.out_offset_signed = Signal((width, True)) self.mod_channel = CSRStorage(1) self.control_channel = CSRStorage(1) self.sweep_channel = CSRStorage(2) self.sync += [ self.chain_a_offset_signed.eq(self.chain_a_offset.storage), self.chain_b_offset_signed.eq(self.chain_b_offset.storage), self.combined_offset_signed.eq(self.combined_offset.storage), self.out_offset_signed.eq(self.out_offset.storage) ] self.state_in = [] self.signal_in = [] self.state_out = [] self.signal_out = [self.control_signal, combined_error_signal] self.slow_value = CSRStatus(width) self.submodules.mod = Modulate(width=width) self.submodules.sweep = SweepCSR(width=width, step_width=30, step_shift=24) self.submodules.limit_error_signal = LimitCSR(width=signal_width, guard=4) self.submodules.limit_fast1 = LimitCSR(width=width, guard=5) self.submodules.limit_fast2 = LimitCSR(width=width, guard=5) self.submodules.pid = PID(width=signal_width) max_decimation = 16 self.slow_decimation = CSRStorage(bits_for(max_decimation)) self.comb += [ self.sweep.clear.eq(0), self.sweep.hold.eq(0), ] self.comb += [ combined_error_signal.eq(self.limit_error_signal.y), self.control_signal.eq( Array([self.limit_fast1.y, self.limit_fast2.y])[ self.control_channel.storage] << s), ]
def __init__(self, snapshot, reset, bits = 32): CSRStatus.__init__(self, bits) self.submodules.acc = Acc_inc_sat(bits) self.sync += If(snapshot, self.status.eq(self.acc.v)) self.comb += If(reset, self.acc.set(0))
def __init__(self, lvds_in, _debug, sim = False): self._adjust = CSRStorage(16, atomic_write=True) self._adjust_direction = CSRStorage(1) self._adjptotal = CSRStatus(32) self._adjmtotal = CSRStatus(32) self._lock = CSRStatus(1) self._invert = CSRStorage(1) self._update_counter = CSRStorage(1) self._debug_mux = CSRStorage(8) self.submodules.adjptotal_sync = BusSynchronizer(32, "pix1x", "sys") self.submodules.adjmtotal_sync = BusSynchronizer(32, "pix1x", "sys") # IBUFDS lvds_se = Signal() if not sim: self.specials += Instance("IBUFDS", i_I=lvds_in[0], i_IB=lvds_in[1], o_O=lvds_se) debug = Signal(len(_debug)) self.comb += _debug.eq(debug) d0 = Signal() self.sync.pix1x += [ d0.eq(~d0) ] # SERDES self.i = Signal(8) self.comb += debug[0].eq(lvds_se) pd_valid = Signal() pd_incdec = Signal() pd_edge = Signal() pd_cascade = Signal() self.serdesstrobe = Signal() if not sim: self.specials += Instance("ISERDES2", p_SERDES_MODE="MASTER", p_BITSLIP_ENABLE="FALSE", p_DATA_RATE="SDR", p_DATA_WIDTH=8, p_INTERFACE_TYPE="RETIMED", i_D=lvds_se, o_Q4=self.i[7], o_Q3=self.i[6], o_Q2=self.i[5], o_Q1=self.i[4], i_BITSLIP=0, i_CE0=1, i_RST=0, i_CLK0=ClockSignal("pix8x"), i_CLKDIV=ClockSignal("pix1x"), i_IOCE=self.serdesstrobe, o_VALID=pd_valid, o_INCDEC=pd_incdec, i_SHIFTIN=pd_edge, o_SHIFTOUT=pd_cascade) self.specials += Instance("ISERDES2", p_SERDES_MODE="SLAVE", p_BITSLIP_ENABLE="FALSE", p_DATA_RATE="SDR", p_DATA_WIDTH=8, p_INTERFACE_TYPE="RETIMED", i_D=lvds_se, o_Q4=self.i[3], o_Q3=self.i[2], o_Q2=self.i[1], o_Q1=self.i[0], i_BITSLIP=0, i_CE0=1, i_RST=0, i_CLK0=ClockSignal("pix8x"), i_CLKDIV=ClockSignal("pix1x"), i_IOCE=self.serdesstrobe, i_SHIFTIN=pd_cascade, o_SHIFTOUT=pd_edge) self.lock = Signal() self.submodules.sampler = ClockDomainsRenamer({"sys": "pix1x"})(Sampler()) fifo = AsyncFIFO(28, 64) self.submodules.fifo = ClockDomainsRenamer( {"write":"pix1x", "read":"sys"})(fifo) self.submodules.slip = PulseSynchronizer(idomain = "sys", odomain = "pix1x") self.submodules.decoder = Decoder() # CDC for adjust set self.submodules.adjust_sync = BusSynchronizer(1 + 16, "sys", "pix1x") self.comb += [ self.adjust_sync.i[-1].eq(self._adjust_direction.storage), self.adjust_sync.i[:16].eq(self._adjust.storage), self.sampler.adjust_direction.eq(self.adjust_sync.o[-1]), self.sampler.adjust_inc.eq(self.adjust_sync.o[:16]), ] self.comb += [ # SERDES -> sampler # If(self._invert.storage, # self.sampler.i.eq(self.i[::-1])) # .Else( # self.sampler.i.eq(~self.i[::-1])), self.sampler.i.eq(self.i[::-1]), # sampler -> fifo self.fifo.din.eq(self.sampler.q), self.fifo.we.eq(self.sampler.s), self.fifo.re.eq(1), # fifo -> decoder self.decoder.i.eq(self.fifo.dout[::-1]), self.decoder.s.eq(self.fifo.readable), # decoder slip request -> pulse sync -> sampler slip self.slip.i.eq(self.decoder.slip), self.sampler.slip.eq(self.slip.o), # self.source.stb.eq(self.decoder.qs), # self.source.d.eq(self.decoder.q[24:32]), self.lock.eq(self.decoder.lock), ] # capture decoder output on decoder.qs self.decoder_q = Signal(32) self.sync += [ If(self.decoder.qs, self.decoder_q.eq(self.decoder.q) ) ] # self.comb += debug[11].eq(self.source.stb) # self.comb += debug[9].eq(self.lock) self.samplerq = Signal(28) self.submodules.samplerq_sync = BusSynchronizer(idomain = "pix1x", odomain = "sys", width=len(self.samplerq)) self.comb += [ self.samplerq_sync.i.eq(self.sampler.q), self.samplerq.eq(self.samplerq_sync.o) ] self.comb += [ If(self._debug_mux.storage == 0, debug[1:9].eq(self.sampler.edge)). Elif(self._debug_mux.storage == 1, debug[1:9].eq(self.decoder.i[0:8])). Elif(self._debug_mux.storage == 2, debug[1:9].eq(self.decoder.i[8:16])). Elif(self._debug_mux.storage == 3, debug[1:9].eq(self.decoder.i[16:24])). Elif(self._debug_mux.storage == 4, debug[1:9].eq(self.decoder.i[24:28])). Elif(self._debug_mux.storage == 5, debug[1:9].eq(self.samplerq[0:8])). Elif(self._debug_mux.storage == 6, debug[1:9].eq(self.samplerq[8:16])). Elif(self._debug_mux.storage == 7, debug[1:9].eq(self.samplerq[16:24])). Elif(self._debug_mux.storage == 8, debug[1:9].eq(self.samplerq[24:28])). Elif(self._debug_mux.storage == 9, debug[1:9].eq(self.sampler.sr)) ] # self.comb += debug[2].eq(self.sampler.numbits[0]) self.comb += debug[0].eq(d0) # self.comb += debug[6].eq(self.i[0]) # self.comb += debug[8].eq(self.sampler.s) self.comb += debug[10].eq(self.fifo.readable) self.comb += debug[11].eq(self.decoder.lock) self.comb += debug[12].eq(self.decoder.qs) # self.comb += debug[10].eq(self.sampler.phase[0]) # self.comb += debug[11].eq(self.sampler.phase[1]) # self.comb += debug[12].eq(self.sampler.phase[2]) self.comb += self._lock.status.eq(self.decoder.lock) # status (via synchronizer) self.comb += [ self.adjptotal_sync.i.eq(self.sampler.adjptotal), self.adjmtotal_sync.i.eq(self.sampler.adjmtotal), ] self.sync += [ If(self._update_counter.storage, self._adjptotal.status.eq(self.adjptotal_sync.o), self._adjmtotal.status.eq(self.adjmtotal_sync.o), ) ] # output self.source = Endpoint([('d', 8)]) self.submodules.fifo_read_fsm = FSM() self.fifo_read_fsm.act("B0", If (self.source.ack & self.decoder.qs & self.decoder.lock, NextState("B1") ), self.source.stb.eq(self.decoder.qs & self.decoder.lock,), self.source.payload.d.eq(Cat(self.decoder.q[8:14], self.decoder.q[15:17])) ) self.fifo_read_fsm.act("B1", If (self.source.ack, NextState("B0") ), self.source.stb.eq(1), self.source.payload.d.eq(self.decoder_q[0:8]) )