def add_zest(self): self.platform.add_extension(zest_pads) bus = wishbone.Interface() self.add_memory_region("zest", self.mem_map["zest"], 0x1000000) self.add_wb_slave(self.mem_map["zest"], bus) self.submodules.zest = Zest(self.platform, bus, 0x8) self.clock_domains.cd_adc = ClockDomain() self.comb += [ ClockSignal("adc").eq(self.zest.dsp_clk_out), self.zest.clk.eq(self.crg.cd_sys.clk), self.zest.clk_200.eq(self.crg.cd_idelay.clk), self.zest.rst.eq(~self.crg.pll.locked), ] counter_adc = Signal(27) self.sync.adc += counter_adc.eq(counter_adc+1) self.comb += self.user_leds[0].eq(counter_adc[26]) counter_sys = Signal(27) self.sync += counter_sys.eq(counter_sys+1) self.comb += self.user_leds[1].eq(counter_sys[26]) self.platform.add_period_constraint(self.platform.lookup_request("ZEST_CLK_TO_FPGA", 1, loose=True).p, 8.7) self.platform.add_false_path_constraints(self.crg.cd_sys.clk, self.cd_adc.clk, self.crg.cd_idelay.clk, self.platform.lookup_request("ZEST_CLK_TO_FPGA", 1, loose=True).p, self.platform.lookup_request("ZEST_ADC_DCO", 0, loose=True).p, self.platform.lookup_request("ZEST_ADC_DCO", 1, loose=True).p, self.platform.lookup_request("ZEST_DAC_DCO", loose=True).p )
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) self.sync_phase = Signal() z = Signal(freq_width) stop = Signal() self.sync += [ stop.eq(self.freq.storage == 0), If(stop | self.sync_phase, 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), ]
class WBPassThrough(Module): def __init__(self, dwidth=32, awidth=30): self.adr = Signal(awidth) self.dat_w = Signal(dwidth) self.dat_r = Signal(dwidth) self.we = Signal(1) self.sel = Signal(int(dwidth / 8)) self.stb = Signal(1) self.ack = Signal(1) self.cyc = Signal(1) self.cti = Signal(3) self.bte = Signal(2) self.err = Signal(1) from misoc.interconnect import wishbone self.bus = bus = wishbone.Interface() self.comb += ( self.bus.adr.eq(self.adr), self.bus.dat_w.eq(self.dat_w), self.bus.we.eq(self.we), self.bus.sel.eq(self.sel), self.bus.stb.eq(self.stb), self.bus.cyc.eq(self.cyc), self.bus.cti.eq(self.cti), self.bus.bte.eq(self.bte), self.dat_r.eq(self.bus.dat_r), self.ack.eq(self.bus.ack), self.err.eq(self.bus.err), )
class Demodulate(Module, AutoCSR): 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), ]
class FIR(Module): def __init__(self): p = fb.fil[0]['fxqc'] # -------------- Get generics ----------------------------------------- # p = {} # # new Key , Key 1 und 2 in fxqc_dict, default value # p_list = [['WI', 'QI','W', 16], # ['WO', 'QO','W', 16], # ['WA', 'QA','W', 31], # ['WC', 'QC','W', 16], # ['b', 'QC','b', [1,1,1]] # ] #Automatic : p['WA'] = p['WC'] + p['WI'] =- 1 # for l in p_list: # try: # p[l[0]] = fxqc_dict[l[1]][l[2]] # except (KeyError, TypeError) as e: # logger.warning("Error [{0}][{1}]:\n{2}".format(l[1],l[2],e)) # p[l[0]] = l[3] # ------------- Define I/Os ------------------------------------------- ovfl_o = p['QO']['ovfl'] quant_o = p['QO']['quant'] WI = p['QI']['W'] WO = p['QO']['W'] # saturation logic doesn't make much sense with a FIR filter, this is # just for demonstration if ovfl_o == 'wrap': WA = p['QA']['W'] else: WA = p['QA']['W'] + 1 # add one guard bit self.i = Signal((WI, True)) # input signal self.o = Signal((WO, True)) # output signal MIN_o = -1 << (WO - 1) MAX_o = -MIN_o - 1 self.response = [] ### muls = [] src = self.i for c in p['QC']['b']: sreg = Signal((WI, True)) # registers for input signal self.sync += sreg.eq(src) src = sreg muls.append(c * sreg) sum_full = Signal((WA, True)) self.sync += sum_full.eq(reduce( add, muls)) # sum of multiplication products if ovfl_o == 'wrap': self.comb += self.o.eq(sum_full >> (WA - WO)) # rescale for output width else: self.comb += \ If(sum_full[WA-2:] == 0b10, self.o.eq(MIN_o) ).Elif(sum_full[WA-2:] == 0b01, self.o.eq(MAX_o) ).Else(self.o.eq(sum_full >> (WA-WO-1)) )
class test_module_2(Module): def __init__(self, size): self.a = Signal(size * 2) self.b = Signal(max=size) self.c = Signal() self.d = Signal(max=size) self.e = Signal() self.f = Signal() self.comb += [self.d.eq(self.b + 1), self.e.eq(1), self.f.eq(1)]
class Top(Module): def __init__(self, platform): clk12 = platform.request("clk12") self.clock_domains.cd_por = ClockDomain(reset_less=True) self.clock_domains.cd_sys = ClockDomain() reset_delay = Signal(max=1024) self.comb += [ self.cd_por.clk.eq(clk12), self.cd_sys.clk.eq(clk12), self.cd_sys.rst.eq(reset_delay != 1023) ] self.sync.por += \ If(reset_delay != 1023, reset_delay.eq(reset_delay + 1) ) self.submodules.dec = SyncDecoder(8, 3 * 7) self.comb += [ self.dec.data.eq(platform.request("din")), self.dec.wck.eq(platform.request("wck")), self.dec.bck.eq(platform.request("bck")), ] self.submodules.packager = Packager(0x47) serial = platform.request("fast_serial") self.submodules.tx = FastSerialTX(serial) self.comb += self.tx.sink.payload.port.eq(1) self.comb += [ self.dec.source.connect(self.packager.sink), self.packager.source.connect(self.tx.sink), ] # 96.000 MHz pll and /10 for mclk self.mclk = platform.request("mclk") pll_out = Signal() self.specials.pll = Instance("pll", i_clock_in=ClockSignal("sys"), o_clock_out=pll_out) self.clock_domains.cd_pll = ClockDomain(reset_less=True) self.comb += self.cd_pll.clk.eq(pll_out) self.counter = Signal(max=5) self.sync.pll += [ If(self.counter >= 4, self.counter.eq(0), self.mclk.eq(~self.mclk), ).Else( self.counter.eq(self.counter + 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
class Decimate(Module): def __init__(self, max_decimation): self.decimation = Signal(max_decimation) self.decimation_counter = Signal(max_decimation) self.sync += [self.decimation_counter.eq(self.decimation_counter + 1)] self.output = Signal(1) self.sync += [ self.output.eq(Array(self.decimation_counter)[self.decimation]) ]
class VGA(Module): """ VGA Module """ hpixels = 800 vlines = 521 ## vertical lines per frame hpulse = 96 ## hsync pulse length vpulse = 3 ## vsync pulse length hbp = 144 ## end of horizontal back porch hfp = 784 ## beginning of horizontal front porch vbp = 31 ## end of vertical back porch vfp = 511 ## beginning of vertical front porch ## active horizontal video is therefore: 784 - 144 = 640 ## active vertical video is therefore: 511 - 31 = 480 def __init__(self): self.hc = Signal(bits_sign=10) self.vc = Signal(bits_sign=10) self.hsync = Signal() self.vsync = Signal() self.color = Color6() self.comb += trinary(self.hc < VGA.hpulse, self.hsync.eq(0), self.hsync.eq(1)) self.comb += trinary(self.vc < VGA.hpulse, self.vsync.eq(0), self.vsync.eq(1)) self.sync += If(self.hc < VGA.hpixels - 1, [ self.hc.eq(self.hc + 1) ]).Else([ self.hc.eq(0), If(self.vc < VGA.vlines - 1, [ self.vc.eq(self.vc + 1) ]).Else([ self.vc.eq(0) ]) ])
class ExampleModule(Module): def __init__(self, width): self.i_first = Signal(width) self.i_second = Signal(width) self.o_first = Signal(width) self.o_second = Signal(width) ### self.sync += [ self.o_first.eq(self.i_first), self.o_second.eq(self.i_second) ]
class TriggeredGaterHarness(Module): """Test harness to wrap & pass signals to a ``TriggeredInputGater``.""" def __init__(self): """Create a test harness for the :class:`TriggeredInputGater`.""" self.m = Signal(14) self.rst = Signal() self.sync += [self.m.eq(self.m + 1), If(self.rst, self.m.eq(0))] self.submodules.phy_ref = MockPhy(self.m) self.submodules.phy_sig = MockPhy(self.m) core = TriggeredInputGater(self.m, self.phy_ref, self.phy_sig) self.submodules.core = core self.comb += core.clear.eq(self.rst)
class Counter(Module): def __init__(self, n): # Output self.o = Signal(max=n, reset=0) ### self.sync += [ If(self.o == n - 1, self.o.eq(0)) .Else( self.o.eq(self.o + 1) ) ]
class SumDiffCalculator(Module): """The autolock requires the integral of the spectrum over the last few values in a moving window. This module provides this quantity by summing over all values of the spectrum and comparing the current value of this sum with a delayed version. `width` is the signal width and `N_points` is the length of the spectrum. `self.input` is the input signal and `self.delay_value` the time constant in clock cycles. The result is stored in `self.output`. Use `self.restart` to restart the calculation. """ def __init__(self, width=14, N_points=16383, max_delay=16383): self.restart = Signal() self.writing_data_now = Signal() self.input = Signal((width, True)) self.delay_value = Signal(bits_for(N_points)) sum_value_bits = bits_for(((2**width) - 1) * N_points) self.sum_value = Signal((sum_value_bits, True)) delayed_sum = Signal((sum_value_bits, True)) current_sum_diff = Signal((sum_value_bits + 1, True)) self.output = Signal.like(current_sum_diff) self.submodules.delayer = DynamicDelay(sum_value_bits, max_delay=max_delay) self.sync += [ If( self.restart, self.sum_value.eq(0), ).Else( If( self.writing_data_now, # not at start self.sum_value.eq(self.sum_value + self.input), )) ] self.comb += [ self.delayer.writing_data_now.eq(self.writing_data_now), self.delayer.restart.eq(self.restart), self.delayer.delay.eq(self.delay_value), self.delayer.input.eq(self.sum_value), delayed_sum.eq(self.delayer.output), current_sum_diff.eq(self.sum_value - delayed_sum), self.output.eq(current_sum_diff), ]
class FIR(Module): def __init__(self, fxqc_dict): logger.debug(fxqc_dict) if 'QC' in fxqc_dict and 'W' in fxqc_dict['QC']: # coeff. format self.wsize_c = fxqc_dict['QC']['W'] else: self.wsize_c = 16 logger.warning( "Key 'fxqc_dict['QC']['W']' undefined, using default value.") self.coef = fxqc_dict['QC']['b'] # list with coefficients self.wsize_i = fxqc_dict['QI']['W'] # input format self.wsize_o = fxqc_dict['QO']['W'] # output format self.wsize_a = fxqc_dict['QA']['W'] # accumulator format self.i = Signal((self.wsize_i, True)) # input signal self.o = Signal((self.wsize_o, True)) # output signal self.response = [] ### muls = [] src = self.i for c in self.coef: sreg = Signal((self.wsize_i, True)) # registers for input signal self.sync += sreg.eq(src) src = sreg muls.append(c * sreg) sum_full = Signal((self.wsize_a, True)) self.sync += sum_full.eq(reduce( add, muls)) # sum of multiplication products self.comb += self.o.eq( sum_full >> (self.wsize_a - self.wsize_o)) # rescale for output width
class StandaloneHarness(Module): """Test harness for the ``EntanglerCore``.""" def __init__(self): """Pass through signals to an ``EntanglerCore`` instance.""" self.counter = Signal(32) self.submodules.phy_apd0 = MockPhy(self.counter) self.submodules.phy_apd1 = MockPhy(self.counter) self.submodules.phy_apd2 = MockPhy(self.counter) self.submodules.phy_apd3 = MockPhy(self.counter) self.submodules.phy_ref = MockPhy(self.counter) input_phys = [ self.phy_apd0, self.phy_apd1, self.phy_apd2, self.phy_apd3, self.phy_ref, ] core_link_pads = None output_pads = None passthrough_sigs = None self.submodules.core = EntanglerCore(core_link_pads, output_pads, passthrough_sigs, input_phys, simulate=True) self.comb += self.counter.eq(self.core.msm.m)
class FastAutolock(Module, AutoCSR): """The operation of fast autolock is simple: wait until the ramp has reached a certain point and turn on the lock. This method is well suited for systems with not too much jitter.""" 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)), ), ]
class PatternMatcher(Module): """Checks if input vector matches any pattern in patterns. Attributes: sig (:class:`Signal`(num_inputs)): input signal to match against patterns ([:class:`Signal`(num_inputs)] * num_patterns): patterns to match input signal against pattern_ens (:class:`Signal`(num_patterns)): enables matching for the specified pattern (one-hot encoding). matches (:class:`Signal`(num_patterns)): Outputs the patterns that matched the input is_match (:class:`Signal`): Asserted when any pattern matches. """ def __init__(self, num_inputs=4, num_patterns=1): """Define pattern matching gateware.""" self.sig = Signal(num_inputs) self.patterns = [Signal(num_inputs) for _ in range(num_patterns)] self.pattern_ens = Signal(num_patterns) self.matches = Signal(num_patterns) self.is_match = Signal() # # # self.comb += [ self.matches[i].eq(p == self.sig) for i, p in enumerate(self.patterns) ] self.comb += self.is_match.eq(self.pattern_ens & self.matches != 0)
def connect_everything(self, width, signal_width): s = signal_width - width combined_error_signal = Signal((signal_width, True)) self.control_signal = Signal((signal_width, True)) 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.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, parent, offsets=None): table = "" if offsets is not None: arr = [["Image", "Offset"]] for i, offset in enumerate(offsets): arr.append([str(i), str(offset)]) table = "\nYou can use this block to reboot into one of these four addresses:\n\n" \ + lxsocdoc.rst.make_table(arr) self.intro = ModuleDoc("""FPGA Reboot Interface This module provides the ability to reboot the FPGA. It is based on the ``SB_WARMBOOT`` primitive built in to the FPGA. When power is applied to the FPGA, it reads configuration data from the onboard flash chip. This contains reboot offsets for four images. It then booted from the first image, but kept note of the other addresses. {}""".format(table)) self.ctrl = CSRStorage(fields=[ CSRField("image", size=2, description=""" Which image to reboot to. ``SB_WARMBOOT`` supports four images that are configured at FPGA startup. The bootloader is image 0, so set these bits to 0 to reboot back into the bootloader. """), CSRField("key", size=6, description=""" A reboot key used to prevent accidental reboots when writing to random areas of memory. To initiate a reboot, set this to ``0b101011``.""" ) ], description=""" Provides support for rebooting the FPGA. You can select which of the four images to reboot to, just be sure to OR the image number with ``0xac``. For example, to reboot to the bootloader (image 0), write ``0xac``` to this register.""" ) self.addr = CSRStorage(size=32, description=""" This sets the reset vector for the VexRiscv. This address will be used whenever the CPU is reset, for example through a debug bridge. You should update this address whenever you load a new program, to enable the debugger to run ``mon reset`` """) do_reset = Signal() self.comb += [ # "Reset Key" is 0xac (0b101011xx) do_reset.eq(self.ctrl.storage[2] & self.ctrl.storage[3] & ~self.ctrl.storage[4] & self.ctrl.storage[5] & ~self.ctrl.storage[6] & self.ctrl.storage[7]) ] self.specials += Instance( "SB_WARMBOOT", i_S0=self.ctrl.storage[0], i_S1=self.ctrl.storage[1], i_BOOT=do_reset, ) parent.config["BITSTREAM_SYNC_HEADER1"] = 0x7e99aa7e parent.config["BITSTREAM_SYNC_HEADER2"] = 0x7eaa997e
class PhyHarness(Module): """PHY Test Harness for :class:`entangler.phy.Entangler`.""" def __init__(self): """Connect the mocked PHY devices to this device.""" self.counter = Signal(32) self.submodules.phy_apd0 = MockPhy(self.counter) self.submodules.phy_apd1 = MockPhy(self.counter) self.submodules.phy_apd2 = MockPhy(self.counter) self.submodules.phy_apd3 = MockPhy(self.counter) self.submodules.phy_ref = MockPhy(self.counter) input_phys = [ self.phy_apd0, self.phy_apd1, self.phy_apd2, self.phy_apd3, self.phy_ref, ] core_link_pads = None output_pads = None passthrough_sigs = None self.submodules.core = Entangler(core_link_pads, output_pads, passthrough_sigs, input_phys, simulate=True) self.comb += self.counter.eq(self.core.core.msm.m)
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 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)) ]
class BtPower(Module, AutoCSR, AutoDoc): def __init__(self, pads): self.intro = ModuleDoc("""BtPower - power control pins (EC)""") self.power = CSRStorage(8, fields =[ CSRField("self", description="Writing `1` to this keeps the EC powered on", reset=1), CSRField("soc_on", description="Writing `1` to this powers on the SoC", reset=1), CSRField("discharge", description="Writing `1` to this connects a low-value resistor across FPGA domain supplies to force a full discharge"), CSRField("kbddrive", description="Writing `1` to this drives the scan column to 1. Do this prior to reading to mitigate noise") ]) self.stats = CSRStatus(8, fields=[ CSRField("state", size=1, description="Current power state of the SOC"), CSRField("monkey", size=2, description="Power-on key monitor input"), ]) self.mon0 = Signal() self.mon1 = Signal() self.soc_on = Signal() self.comb += [ pads.sys_on.eq(self.power.fields.self), pads.u_to_t_on.eq(self.power.fields.soc_on), pads.fpga_dis.eq(self.power.fields.discharge), self.stats.fields.state.eq(pads.s0), # S1 is disregarded now self.stats.fields.monkey.eq(Cat(self.mon0, self.mon1)), self.soc_on.eq(self.power.fields.soc_on), ]
class CoreUnit(Module): def __init__(self, a_in, b_in, y_out, cmd, err, NBITS): # generics self.NBITS = NBITS # inputs self.a_in = a_in self.b_in = b_in self.y_out = y_out self.cmd = cmd self.err = err #internals self.sum = Signal(NBITS + 1) ### self.comb += [ If( self.cmd == Commands.MIN, self.err.eq(0), If(self.a_in < self.b_in, self.y_out.eq(self.a_in)).Else( self.y_out.eq(self.b_in))).Elif( self.cmd == Commands.MAX, self.err.eq(0), If(self.a_in > self.b_in, self.y_out.eq( self.a_in)).Else(self.y_out.eq(self.b_in))).Elif( self.cmd == Commands.SUM, self.err.eq(0), self.y_out.eq(self.a_in + self.b_in)).Elif( self.cmd == Commands.AVG, self.err.eq(0), self.sum.eq(self.a_in + self.b_in), If(self.sum != 0, self.y_out.eq(self.sum >> 1)).Else( self.y_out.eq(self.sum))).Else( self.err.eq(1)) ]
class Pulser(Module): """ This migen module produces 2 single-clock-cycle pulses depending on a virtual photon detection event. PMT and RF triggers never occur at the same time. Inputs: - reset: signal - photon: signal - Time_res: parameter. maximum time interval between 2 triggers Outputs: - pmt_trigger: signal. photon detection trigger - rf_trigger: signal. electrode RF trigger - clock: signal. time reference """ def __init__(self, reset, pmt_trigger, rf_trigger, photon, clock): # inputs self.reset = reset self.photon = photon # outputs self.pmt_trigger = pmt_trigger self.rf_trigger = rf_trigger self.clock = clock # internal signals self.photon_reg = Signal(5) ### self.sync += [ If( self.reset.data == 1, self.clock.eq(0), ).Else(self.clock.eq(self.clock + 1)), If(self.photon.valid, self.photon_reg.eq(self.photon.data)).Else( self.photon_reg.eq(self.photon_reg)) ] self.comb += [ If((self.clock == TIME_RES - 1), self.rf_trigger.eq(1), self.pmt_trigger.eq(0)).Elif( (self.clock == TIME_RES - 1 - self.photon_reg), self.rf_trigger.eq(0), self.pmt_trigger.eq(1)).Else(self.rf_trigger.eq(0), self.pmt_trigger.eq(0)) ]
class DynamicDelay(Module): """Delays a signal `self.input` of length `input_bit` by a dynamic number of clock cycles (`max_delay` is the maximum number of clock cycles). `self.output` contains the delayed signal. Internally, this module uses a memory. Set `restart` to 1 if you want to delete everything stored in this memory. """ def __init__(self, input_bit, max_delay): self.delay = Signal(bits_for(max_delay)) self.restart = Signal() self.writing_data_now = Signal() self.input = Signal((input_bit, True)) self.output = Signal((input_bit, True)) # this ensures that counter overflows / underflows correctly assert max_delay == (2**(bits_for(max_delay)) - 1) self.mem_rdport, self.mem_wrport = create_memory( self, input_bit, max_delay, "dynamic_delay_mem") # register all the ports self.specials += [self.mem_rdport, self.mem_wrport] self.counter = Signal(bits_for(max_delay)) self.counter_delayed = Signal((bits_for(max_delay))) negative_delay = 1 self.sync += [ If(self.restart, self.counter.eq(0)).Else( If(self.writing_data_now, self.counter.eq(self.counter + 1))), ] self.comb += [ self.mem_wrport.we.eq(self.writing_data_now), self.mem_wrport.adr.eq(self.counter), self.mem_wrport.dat_w.eq(self.input), self.mem_rdport.adr.eq(self.counter_delayed), self.counter_delayed.eq(self.counter - self.delay + negative_delay), self.mem_rdport.adr.eq(self.counter_delayed), If(self.counter < self.delay - negative_delay, self.output.eq(0)).Else(self.output.eq( self.mem_rdport.dat_r), ), ]
def __init__(self, plat): counter = Signal(30) self.sync += counter.eq(counter + 1) self.ios = set() for i in range(8): led = plat.request("user_led", i) self.comb += led.eq(counter[-1-i]) self.ios.add(led)
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 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