def __init__(self, step_width=None, step_shift=0, **kwargs): Filter.__init__(self, **kwargs) # required by tests self.step_shift = step_shift width = len(self.y) if step_width is None: step_width = width self.shift = CSRConstant(step_shift, bits_for(step_shift)) self.step = CSRStorage(step_width) self.min = CSRStorage(width, reset=1 << (width - 1)) self.max = CSRStorage(width, reset=(1 << (width - 1)) - 1) self.run = CSRStorage(1) ### self.submodules.sweep = Sweep(width + step_shift + 1) self.submodules.limit = Limit(width + 1) min, max = self.min.storage, self.max.storage self.comb += [ self.sweep.run.eq(~self.clear & self.run.storage), self.sweep.hold.eq(self.hold), self.limit.x.eq(self.sweep.y >> step_shift), self.sweep.step.eq(self.step.storage), ] self.sync += [ self.limit.min.eq(Cat(min, min[-1])), self.limit.max.eq(Cat(max, max[-1])), self.sweep.turn.eq(self.limit.railed), self.y.eq(self.limit.y), ]
def __init__(self, data_i, data_o, idelay_rdy=None): delay_value = CSRStorage(5, name="delay_value") delay_load = CSRStorage(1, name="delay_load") reset = Signal() if idelay_rdy is not None: self.comb += reset.eq(idelay_rdy | ResetSignal()) else: reset = ResetSignal() self.specials += Instance( "IDELAYE2", # Parameters # p_INVCTRL_SEL="FALSE", # Enable dynamic clock inversion (FALSE, TRUE) p_DELAY_SRC="IDATAIN", # Delay input (IDATAIN, DATAIN) p_HIGH_PERFORMANCE_MODE= "TRUE", # Reduced jitter ("TRUE"), Reduced power ("FALSE") p_IDELAY_TYPE="VAR_LOAD", # FIXED, VARIABLE, VAR_LOAD, VAR_LOAD_PIPE p_IDELAY_VALUE=0, # Input delay tap setting (0-31) p_PIPE_SEL="FALSE", # Select pipelined mode, FALSE, TRUE p_REFCLK_FREQUENCY= 200.0, # IDELAYCTRL clock input frequency in MHz (190.0-210.0, 290.0-310.0). p_SIGNAL_PATTERN="DATA", # DATA, CLOCK input signal # Ports i_DATAIN=0, # 1-bit input: Internal delay data input o_DATAOUT=data_o, # 1-bit output: Delayed data output i_C=ClockSignal(), # 1-bit input: Clock input i_CE=0, # 1-bit input: Active high enable increment/decrement input i_CINVCTRL=0, # 1-bit input: Dynamic clock inversion input i_CNTVALUEIN=delay_value. storage, # 5-bit input: Counter value input i_IDATAIN=data_i, # 1-bit input: Data input from the I/O i_INC=0, # 1-bit input: Increment / Decrement tap delay input i_LD=delay_load.storage, # 1-bit input: Load IDELAY_VALUE input i_LDPIPEEN= 0, # 1-bit input: Enable PIPELINE register to load data input i_REGRST=reset) # 1-bit input: Active-high reset tap-delay input
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 calculate_i(self): self.ki = CSRStorage(self.coeff_width) self.reset = CSRStorage() ki_signed = Signal((self.coeff_width, True)) self.comb += [ki_signed.eq(self.ki.storage)] self.ki_mult = Signal((1 + self.width + self.coeff_width, True)) self.comb += [self.ki_mult.eq((self.error * ki_signed) >> 4)] int_reg_width = self.width + self.coeff_width + 4 extra_width = int_reg_width - self.width self.int_reg = Signal((int_reg_width, True)) self.int_sum = Signal((int_reg_width + 1, True)) self.int_out = Signal((self.width, True)) self.comb += [ self.int_sum.eq(self.ki_mult + self.int_reg), self.int_out.eq(self.int_reg >> extra_width) ] max_pos_extra = (self.max_pos << extra_width) max_neg_extra = (-1 * max_pos_extra) - 1 self.sync += [ If(self.reset.storage, self.int_reg.eq(0)).Elif( self.int_sum > max_pos_extra, # positive saturation self.int_reg.eq(max_pos_extra)).Elif( self.int_sum < max_neg_extra, # negative saturation self.int_reg.eq(max_neg_extra)).Else( self.int_reg.eq(self.int_sum)) ]
def __init__(self, freq_width=32, width=14): # input signal self.x = Signal((width, True)) # demodulated signals (i and q) self.i = Signal((width, True)) self.q = Signal((width, True)) self.delay = CSRStorage(freq_width) self.multiplier = CSRStorage(4, reset=1) self.phase = Signal(width) self.submodules.cordic = Cordic( width=width + 1, stages=width + 1, guard=2, eval_mode="pipelined", cordic_mode="rotate", func_mode="circular", ) self.comb += [ # cordic input self.cordic.xi.eq(self.x), self.cordic.zi.eq( ((self.phase * self.multiplier.storage) + self.delay.storage) << 1 ), # cordic output self.i.eq(self.cordic.xo >> 1), self.q.eq(self.cordic.yo >> 1), ]
def __init__(self, freq_width=32, **kwargs): Filter.__init__(self, **kwargs) width = len(self.y) self.amp = CSRStorage(width) self.freq = CSRStorage(freq_width) self.phase = Signal(width) z = Signal(freq_width) stop = Signal() self.sync += [ stop.eq(self.freq.storage == 0), If(stop, z.eq(0)).Else(z.eq(z + self.freq.storage)) ] self.submodules.cordic = Cordic(width=width + 1, stages=width + 1, guard=2, eval_mode="pipelined", cordic_mode="rotate", func_mode="circular") self.comb += [ self.phase.eq(z[-len(self.phase):]), self.cordic.xi.eq(self.amp.storage + self.x), self.cordic.zi.eq(self.phase << 1), self.y.eq(self.cordic.xo >> 1) ]
def __init__(self, use_ext_clock=False): self.ibuf_disable = CSRStorage(reset=1) self.jreset = CSRStorage(reset=1) self.jref = Signal() self.refclk = Signal() self.clock_domains.cd_jesd = ClockDomain() self.refclk_pads = lvdsPair(Signal(name="refclk_p"), Signal(name="refclk_n")) refclk2 = Signal() # Useless for gtx transceivers self.specials += [ Instance("IBUFDS_GTE2", i_CEB=self.ibuf_disable.storage, i_I=self.refclk_pads.p, i_IB=self.refclk_pads.n, o_O=self.refclk, o_ODIV2=refclk2), AsyncResetSynchronizer(self.cd_jesd, self.jreset.storage), ] if use_ext_clock: self.comb += self.cd_jesd.clk.eq(ClockSignal("ext")) else: self.specials += Instance("BUFG", i_I=self.refclk, o_O=self.cd_jesd.clk)
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 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__(self): self._size = CSRStorage(8, reset=8) self._cfg = CSRStorage(1, reset=0) self.source = Endpoint([('d', 8), ('last', 1)]) START_BYTE = 0xAA self.lfsr_state = Signal(17) self.lfsr_state_next = Signal(17) self.sync += If(~self._cfg.storage[0], self.lfsr_state.eq(1)).Else( self.lfsr_state.eq(self.lfsr_state_next)) self.bytecount = Signal(8) self.bytecount_next = Signal(8) self.comb += [ self.lfsr_state_next.eq(self.lfsr_state), self.bytecount_next.eq(self.bytecount), self.source.payload.last.eq(0) ] self.sync += self.bytecount.eq(self.bytecount_next) self.submodules.fsm = FSM() self.fsm.act("IDLE", If(self._cfg.storage[0], NextState("SEND_HEAD"))) self.fsm.act("SEND_HEAD", self.source.payload.d.eq(0xAA), self.source.stb.eq(1), If(self.source.ack, NextState("SEND_SIZE"))) self.fsm.act( "SEND_SIZE", self.source.payload.d.eq(self._size.storage), self.source.stb.eq(1), If(self.source.ack, self.bytecount_next.eq(0), NextState("SEND_DATA")), ) self.fsm.act( "SEND_DATA", self.source.payload.d.eq(self.lfsr_state), self.source.stb.eq(1), If(self.bytecount + 1 == self._size.storage, self.source.payload.last.eq(1)), If( self.source.ack, self.lfsr_state_next.eq( Cat( self.lfsr_state[16] ^ self.lfsr_state[14] ^ self.lfsr_state[13] ^ self.lfsr_state[11], self.lfsr_state)), self.bytecount_next.eq(self.bytecount + 1), If(self.bytecount + 1 == self._size.storage, NextState("IDLE"))))
def __init__(self, step_width=None, step_shift=0, **kwargs): Filter.__init__(self, **kwargs) width = len(self.y) if step_width is None: step_width = width self.shift = CSRConstant(step_shift, bits_for(step_shift)) self.step = CSRStorage(step_width) self.run = CSRStorage(1) self.min = CSRStorage(width, reset=1 << (width - 1)) self.max = CSRStorage(width, reset=(1 << (width - 1)) - 1) ### self.submodules.sweep = Sweep(width + step_shift + 1) self.submodules.limit = Limit(width) cnt = Signal(width + step_shift + 1) range = Signal(max=len(cnt)) self.sync += [ cnt.eq(cnt + 1), If( ~self.error, # stop sweep, drive to zero cnt.eq(0), range.eq(0)).Elif( self.clear | (self.sweep.y[-1] != self.sweep.y[-2]), # max range if we hit limit cnt.eq(0), range.eq(len(cnt) - 1)).Elif( Array(cnt)[range], # 1<<range steps, turn, inc range cnt.eq(0), If(range != len(cnt) - 1, range.eq(range + 1))), self.limit.min.eq(self.min.storage), self.limit.max.eq(self.max.storage), self.error.eq(self.run.storage & (self.limit.railed | self.hold)), If(self.sweep.y[-1] == self.sweep.y[-2], self.y.eq(self.sweep.y >> step_shift)) ] self.comb += [ # relock at limit.railed or trigger if not prevented by hold # stop sweep at not relock # drive error on relock to hold others # turn at range or clear (from final limiter) self.limit.x.eq(self.x), self.sweep.step.eq(self.step.storage), self.sweep.run.eq(self.error), self.sweep.turn.eq(cnt == 0) ]
def __init__(self, width=14): # pid is not started directly by `request_lock` signal. Instead, `request_lock` # queues a run that is then started when the ramp is at the zero target position self.request_lock = Signal() self.turn_on_lock = Signal() self.sweep_value = Signal((width, True)) self.sweep_step = Signal(width) self.sweep_up = Signal() self.target_position = CSRStorage(width) target_position_signed = Signal((width, True)) self.comb += [target_position_signed.eq(self.target_position.storage)] self.sync += [ If( ~self.request_lock, self.turn_on_lock.eq(0), ).Else( self.turn_on_lock. eq((self.sweep_value >= target_position_signed - (self.sweep_step >> 1)) & (self.sweep_value <= target_position_signed + 1 + (self.sweep_step >> 1)) # and if the ramp is going up (because this is when a # spectrum is recorded) & (self.sweep_up)), ), ]
def __init__(self): self.sink = Endpoint(ULPI_DATA_D) self.source = Endpoint(ULPI_DATA_D) self._ctl = CSRStorage(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, width, n=31): y = Signal((width, True)) self.signal_out = y, self.signal_in = () self.state_in = () self.state_out = () self.bits = CSRStorage(bits_for(width)) taps = { 7: (6, 5), 15: (14, 13), 31: (30, 27), 63: (62, 61), }[n] self.submodules.gen = LFSR(n, taps) cnt = Signal(max=width + 1) store = Signal(width) self.sync += [ store.eq(Cat(self.gen.o, store)), cnt.eq(cnt + 1), If(cnt == self.bits.storage, cnt.eq(1), y.eq(store), store.eq(Replicate(self.gen.o, flen(store))) ) ]
def calculate_error_signal(self): self.setpoint = CSRStorage(self.width) setpoint_signed = Signal((self.width, True)) self.comb += [setpoint_signed.eq(self.setpoint.storage)] self.error = Signal((self.width + 1, True)) self.comb += [self.error.eq(self.input - self.setpoint.storage)]
def __init__(self, out, **kwargs): for i, o in enumerate(out): ds = DeltaSigma(**kwargs) self.submodules += ds cs = CSRStorage(len(ds.data), name="data%i" % i) # atomic_write=True setattr(self, "r_data%i" % i, cs) self.sync += ds.data.eq(cs.storage), o.eq(ds.out)
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 __init__(self, leds_raw, leds_muxes=None, active=1): """ leds_raw: output IOs for the LEDs leds_muxes: internal digital signals that could feed a LED """ leds = Signal(len(leds_raw)) # Register containing the desired LED status self._out = CSRStorage(len(leds), atomic_write=True) # For each LED, we generate a MUX register. # The MUX register can connect either the bit in the 'output' register or # signals supplied via led_muxes if leds_muxes: assert len(leds_muxes) == len(leds) for n in range(len(leds)): name = "mux_%d" % n attr = CSRStorage(8, atomic_write=True, name=name) setattr(self, "_%s" % name, attr) mux_vals = [self._out.storage[n]] if leds_muxes[n]: mux_vals.extend(leds_muxes[n]) cases = {k: leds[n].eq(v) for k, v in enumerate(mux_vals)} self.comb += [ leds[n].eq(0), Case(attr.storage, cases) ] else: self.comb += [ leds.eq(self._out.storage), ] self.comb += [ leds_raw.eq(leds if active else ~leds) ]
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, freq_width=32, **kwargs): Filter.__init__(self, **kwargs) width = len(self.y) self.delay = CSRStorage(freq_width) self.multiplier = CSRStorage(4, reset=1) self.phase = Signal(width) self.submodules.cordic = Cordic(width=width + 1, stages=width + 1, guard=2, eval_mode="pipelined", cordic_mode="rotate", func_mode="circular") self.comb += [ self.cordic.xi.eq(self.x), self.cordic.zi.eq(((self.phase * self.multiplier.storage) + self.delay.storage) << 1), self.y.eq(self.cordic.xo >> 1) ]
def calculate_p(self): self.kp = CSRStorage(self.coeff_width) kp_signed = Signal((self.coeff_width, True)) self.comb += [kp_signed.eq(self.kp.storage)] kp_mult = Signal((self.width + self.coeff_width, True)) self.comb += [kp_mult.eq(self.error * kp_signed)] self.output_p = Signal((self.width, True)) self.comb += [self.output_p.eq(kp_mult >> (self.coeff_width - 2))] self.kp_mult = kp_mult
def __init__(self, width=16, signal_width=25, coeff_width=18): self.adc = Signal((width, True)) self.dac = Signal((width, True)) hold = Signal() clear = Signal() sat = Signal() railed = Signal() self.brk = CSRStorage(1) x = Signal((signal_width, True)) dx = Signal((signal_width, True)) y = Signal((signal_width, True)) dy = Signal((signal_width, True)) self.state_in = hold, clear self.state_out = sat, railed self.signal_in = dx, self.signal_out = x, y ### self.submodules.x_limit = LimitCSR(width=signal_width, guard=1) self.submodules.iir = Iir(width=2 * coeff_width, coeff_width=signal_width, order=2, shift=signal_width - 2, mode="iterative") #self.submodules.sweep = SweepCSR(width=width, step_width=24, # step_shift=18) self.submodules.y_limit = LimitCSR(width=width, guard=1) ### s = signal_width - width s1 = 2 * coeff_width - signal_width s2 = 2 * coeff_width - width self.comb += [ x.eq(self.adc << s), self.x_limit.x.eq(Mux(self.brk.storage, 0, x) + dx), self.iir.x.eq(self.x_limit.y << s1), self.iir.hold.eq(hold), self.iir.clear.eq(clear), sat.eq(self.iir.error), self.y_limit.x.eq((self.iir.y >> s2) + (dy >> s)), railed.eq(self.y_limit.error), y.eq(self.y_limit.y << s), self.dac.eq(y >> s) ]
def __init__(self, width, **kwargs): y = Signal((width, True)) self.signal_out = y, self.signal_in = () self.state_in = () self.state_out = () self.bits = CSRStorage(bits_for(width)) self.submodules.gen = XORSHIFT(**kwargs) q = Signal(width) self.sync += [ q.eq(self.gen.state[:width] >> (width - self.bits.storage)), y.eq(q[1:] ^ (Replicate(q[0], width))) ]
def __init__(self, guard=0, **kwargs): Filter.__init__(self, **kwargs) width = len(self.y) if guard: self.x = Signal((width + guard, True)) self.min = CSRStorage(width, reset=1 << (width - 1)) self.max = CSRStorage(width, reset=(1 << (width - 1)) - 1) ### self.submodules.limit = Limit(width + guard) min, max = self.min.storage, self.max.storage if guard: min = Cat(min, Replicate(min[-1], guard)) max = Cat(max, Replicate(max[-1], guard)) self.comb += [self.limit.x.eq(self.x)] self.sync += [ self.limit.min.eq(min), self.limit.max.eq(max), self.y.eq(self.limit.y), self.error.eq(self.limit.railed) ]
def init_csr(self, N_points): # CSR storages self.time_scale = CSRStorage(bits_for(N_points)) self.N_instructions = CSRStorage( bits_for(AUTOLOCK_MAX_N_INSTRUCTIONS - 1)) self.final_wait_time = CSRStorage(bits_for(N_points)) peak_height_bit = len(self.sum_diff_calculator.sum_value) self.peak_heights = [ CSRStorage(peak_height_bit, name="peak_height_%d" % idx) for idx in range(AUTOLOCK_MAX_N_INSTRUCTIONS) ] for idx, peak_height in enumerate(self.peak_heights): setattr(self, "peak_height_%d" % idx, peak_height) x_data_length_bit = bits_for(N_points) self.wait_for = [ CSRStorage(x_data_length_bit, name="wait_for_%d" % idx) for idx in range(AUTOLOCK_MAX_N_INSTRUCTIONS) ] for idx, wait_for in enumerate(self.wait_for): setattr(self, "wait_for_%d" % idx, wait_for) return peak_height_bit, x_data_length_bit
def calculate_d(self): self.kd = CSRStorage(self.coeff_width) kd_mult = Signal((29, True)) kd_reg = Signal((19, True)) kd_reg_r = Signal((19, True)) self.kd_reg_s = Signal((20, True)) kd_signed = Signal((self.coeff_width, True)) self.comb += [ kd_signed.eq(self.kd.storage), kd_mult.eq(self.error * kd_signed) ] self.sync += [ kd_reg.eq(kd_mult[10:29]), kd_reg_r.eq(kd_reg), self.kd_reg_s.eq(kd_reg - kd_reg_r) ]
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 calculate_d(self): self.d_shift = 6 mult_width = self.coeff_width + self.width + 2 out_width = mult_width - self.coeff_width + self.d_shift + 1 self.kd = CSRStorage(self.coeff_width) kd_signed = Signal((self.coeff_width, True)) kd_mult = Signal((mult_width, True)) self.comb += [ kd_signed.eq(self.kd.storage), kd_mult.eq(self.error * kd_signed) ] kd_reg = Signal((out_width, True)) kd_reg_r = Signal((out_width, True)) self.output_d = Signal((out_width, True)) self.sync += [ kd_reg.eq(kd_mult >> (self.coeff_width - self.d_shift)), kd_reg_r.eq(kd_reg), self.output_d.eq(kd_reg - kd_reg_r), ]
def __init__(self, order=1, mode="pipelined", width=25, coeff_width=18, shift=16, intermediate_width=None): Filter.__init__(self, width) assert mode in ("pipelined", "iterative") if intermediate_width is None: intermediate_width = width + coeff_width # + bits_for(2*(order + 1)) self.z0 = CSRStorage(intermediate_width - shift, reset=0) self.shift = CSRConstant(shift) self.width = CSRConstant(coeff_width) self.interval = CSRConstant(0, 8) self.latency = CSRConstant(0, 8) self.order = CSRConstant(order, 8) self.iterative = CSRConstant(mode == "iterative", 1) self.c = c = {} for i in "ab": for j in range(order + 1): name = "%s%i" % (i, j) if name == "a0": continue ci = Signal((coeff_width, True), name=name) rci = CSRStorage(len(ci), name=name) self.sync += ci.eq(rci.storage) c[name] = ci setattr(self, "r_" + name, rci) ### z = Signal((intermediate_width, True), name="z0r") self.sync += z.eq(self.z0.storage << shift) y_lim = Signal.like(self.y) y_next = Signal.like(z) y_over = y_next[shift+width-1:] y_pat = Signal.like(y_over, reset=-1) y = Signal.like(self.y) railed = Signal() self.comb += [ railed.eq(~((y_over == y_pat) | (y_over == ~y_pat))), If(railed, y_lim.eq(self.y) ).Else( y_lim.eq(y_next[shift:]) ) ] self.sync += [ self.error.eq(railed), self.y.eq(y_lim), If(self.clear, y.eq(0) ).Elif(~self.hold, y.eq(y_lim) ) ] if mode == "pipelined": r = [("b%i" % i, self.x) for i in reversed(range(order + 1))] r += [("a%i" % i, y) for i in reversed(range(1, order + 1))] for coeff, signal in r: zr = Signal.like(z) self.sync += zr.eq(z) z = Signal.like(zr) self.comb += z.eq(zr + signal*c[coeff]) self.comb += y_next.eq(z) self.latency.value = Constant(order + 1) self.interval.value = Constant(1) elif mode == "iterative": ma = Signal.like(self.y) mb = Signal.like(c["a1"]) mm = Signal.like(z) mc = Signal.like(z) mp = Signal.like(z) self.sync += mm.eq(ma*mb), mc.eq(mp) self.comb += mp.eq(mm + mc) steps = [] x = [self.x] + [Signal.like(self.x) for i in range(order + 1)] for i in reversed(range(order + 1)): steps.append([ x[i + 1].eq(x[i]), ma.eq(x[i]), mb.eq(c["b%i" % i]) ]) y = [None, y] + [Signal.like(y) for i in range(1, order + 1)] for i in reversed(range(1, order + 1)): steps.append([ y[i + 1].eq(y[i]), ma.eq(y[i]), mb.eq(c["a%i" % i]) ]) steps[1].append(mc.eq(z)) latency = order + 4 if order == 1: steps.append([]) latency += 1 self.latency.value = Constant(latency) steps[int(order > 1)].append(y_next.eq(mp)) self.sync += timeline(1, list(enumerate(steps))) self.interval.value = Constant(len(steps)) else: raise ValueError
def __init__(self, width=14, signal_width=25, coeff_width=18, mod=None, offset_signal=None): self.adc = Signal((width, True)) self.dac = Signal((signal_width, True)) self.y_tap = CSRStorage(2) self.invert = CSRStorage(1) x_hold = Signal() x_clear = Signal() x_railed = Signal() y_hold = Signal() y_clear = Signal() y_sat = Signal() y_railed = Signal() self.state_in = x_hold, x_clear, y_hold, y_clear self.state_out = x_railed, y_sat, y_railed x = Signal((signal_width, True)) dx = Signal((signal_width, True)) y = Signal((signal_width, True)) dy = Signal((signal_width, True)) rx = Signal((signal_width, True)) self.signal_in = dx, dy, rx self.signal_out = x, y ### self.submodules.demod = Demodulate(width=width) self.submodules.x_limit = LimitCSR(width=signal_width, guard=1) self.submodules.iir_c = Iir(width=signal_width, coeff_width=coeff_width, shift=coeff_width - 2, order=1) self.submodules.iir_d = Iir(width=signal_width, coeff_width=coeff_width, shift=coeff_width - 2, order=2) if mod is None: self.submodules.mod = Modulate(width=width) mod = self.mod self.submodules.y_limit = LimitCSR(width=signal_width, guard=3) ### s = signal_width - width self.comb += [ self.demod.x.eq(self.adc), self.demod.phase.eq(mod.phase), self.x_limit.x.eq((self.demod.y << s) + dx), x_railed.eq(self.x_limit.error), self.iir_c.x.eq(self.x_limit.y), self.iir_c.hold.eq(y_hold), self.iir_c.clear.eq(y_clear), self.iir_d.x.eq(self.iir_c.y), self.iir_d.hold.eq(y_hold), self.iir_d.clear.eq(y_clear), y_sat.eq((self.iir_c.error & (self.y_tap.storage > 1)) | (self.iir_d.error & (self.y_tap.storage > 2))), ] ya = Signal((width + 3, True)) ys = Array([self.iir_c.x, self.iir_c.y, self.iir_d.y]) self.sync += ya.eq(((dy >> s))), self.comb += [ self.y_limit.x.eq( Mux(self.invert.storage, -1, 1) * (ys[self.y_tap.storage] + (ya << s) + (offset_signal << s))), y.eq(self.y_limit.y), y_railed.eq(self.y_limit.error), self.dac.eq(self.y_limit.y) ]