def __init__(self, pads): charge_measurement = Signal(24) sense_mux = Signal(4) sense_enable_n = Signal(1) sense_ctrl = Signal(1) self.comb += [ pads.mux.eq(sense_mux), pads.enable.eq(sense_enable_n), pads.ctrl.eq(sense_ctrl) ] # CPU interface exposed through CSRs self._control = CSRStorage(fields=[ CSRField("start", size=1, offset=0, pulse=True, description="Write ``1`` to start a conversion"), CSRField( "chan", size=4, offset=8, description="Channel selector for ADC", values=[ ("0b0000", "GND"), ("0b0001", "A0", "analog0"), ("0b0010", "A1", "analog1"), ("0b0011", "A2", "analog2"), ("0b0100", "A3", "analog3"), ("0b0101", "A4", "analog4"), ("0b0110", "A5", "analog5"), ("0b0111", "AREF"), ("0b1000", "3v3"), ("0b1100", "1v35"), ("0b1101", "2v5"), ("0b1110", "1v1"), ("0b1111", "VBAT"), # Through 1/2 divider ]), ]) self._status = CSRStatus(fields=[ CSRField("idle", size=1, offset=0, description="Measurement complete when read as ``1``.") ], description="AnalogSense Status.") self._result = CSRStatus(24, description="Conversion result.") # FSM fsm = FSM(reset_state="IDLE") self.submodules += fsm timer = Signal(18) timer_trig = Signal() fsm.act("IDLE", If(self._control.fields.start, NextState("SETUP")), NextValue(timer, 0x18000)) # 680us fsm.act("SETUP", If(timer_trig, NextState("CHARGE"), NextValue(timer, 0x18000))) # 680us fsm.act("CHARGE", If(timer_trig, NextState("DISCHARGE"), NextValue(timer, 0x0))) # 2.73ms fsm.act("DISCHARGE", If(timer_trig, NextState("IDLE"))) # Timers self.sync += timer.eq(timer + 1) self.comb += timer_trig.eq(timer[17]) # Input sense_iob = Signal(2) self.specials += DDRInput(pads.sense_p, sense_iob[0], sense_iob[1]) sense_value = Signal(2) self.sync += sense_value.eq( Cat(sense_iob[0] ^ sense_iob[1], sense_iob[0] & sense_iob[1])) # Measurement Counters sense_counter = Signal(24) self.sync += [ If(timer_trig, sense_counter.eq(0)).Else( sense_counter.eq(sense_counter + sense_value)) ] # Control Hardware self.sync += [ If( fsm.ongoing("IDLE"), sense_mux.eq( Mux(self._control.fields.start, self._control.fields.chan, 0)), sense_enable_n.eq(~self._control.fields.start)), sense_ctrl.eq(fsm.ongoing("CHARGE")), ] # IF self.comb += [ self._status.fields.idle.eq(fsm.ongoing("IDLE")), self._result.status.eq(charge_measurement) ] # Save result of charge time self.sync += If( fsm.ongoing("CHARGE") & timer_trig, charge_measurement.eq(sense_counter))
def __init__(self, pads): assert len(pads) <= 32 fields = [ CSRField(name="dir%d" % i, description="Pin direction", values=[ ("0", "input", "Input mode"), ("1", "output", "Output mode"), ]) for i in range(32) ] self.dir = CSRStorage(32, description="GPIO pin direction", fields=fields) fields = [ CSRField(name="otype%d" % i, description="Pin output type", values=[ ("0", "push_pull", "Push-pull output"), ("1", "open_drain", "Open-drain output"), ]) for i in range(32) ] self.otyper = CSRStorage(32, description="GPIO output type register", fields=fields) fields = [ CSRField(name="id%d" % i, description="Pin input data") for i in range(32) ] self.idr = CSRStatus(32, description="GPIO input data register", fields=fields) fields = [ CSRField(name="od%d" % i, description="Pin output data") for i in range(32) ] self.odr = CSRStorage(32, description="GPIO output data register", write_from_dev=True, fields=fields) fields = [ CSRField(name="bs%d" % i, description="Pin set bit", pulse=True, values=[ ("1", "set", "Set bit"), ]) for i in range(32) ] self.bsr = CSRStorage(32, description="GPIO bit set register", fields=fields) fields = [ CSRField(name="bs%d" % i, description="Pin reset bit", pulse=True, values=[ ("1", "reset", "Reset bit"), ]) for i in range(32) ] self.brr = CSRStorage(32, description="GPIO bit reset register", fields=fields) self.comb += [ If( self.bsr.re, self.odr.dat_w.eq(self.odr.storage | self.bsr.storage), ).Elif( self.brr.re, self.odr.dat_w.eq(self.odr.storage & ~self.brr.storage), ).Else(self.odr.dat_w.eq(self.odr.storage)), self.odr.we.eq(self.bsr.re | self.brr.re), ] for i in range(32): pad = None if i < len(pads): pad = pads[i] if pad is None: continue t = TSTriple() self.specials += t.get_tristate(pad) dir_i = self.dir.storage[i] otyper_i = self.otyper.storage[i] odr_i = self.odr.storage[i] self.comb += [ t.oe.eq(~(otyper_i & odr_i) & dir_i), t.o.eq(odr_i), self.idr.status[i].eq(t.i), ]
def __init__(self, revision, pads): rgba_pwm = Signal(3) self.intro = ModuleDoc("""RGB LED Controller The ICE40 contains two different RGB LED control devices. The first is a constant-current LED source, which is fixed to deliver 4 mA to each of the three LEDs. This block is called ``SB_RGBA_DRV``. The other is used for creating interesting fading effects, particularly for "breathing" effects used to indicate a given state. This block is called ``SB_LEDDA_IP``. This block feeds directly into ``SB_RGBA_DRV``. The RGB LED controller available on this device allows for control of these two LED control devices. Additionally, it is possible to disable ``SB_LEDDA_IP`` and directly control the individual LEDs. """) self.dat = CSRStorage(8, description=""" This is the value for the ``SB_LEDDA_IP.DAT`` register. It is directly written into the ``SB_LEDDA_IP`` hardware block, so you should refer to http://www.latticesemi.com/view_document?document_id=50668. The contents of this register are written to the address specified in ``ADDR`` immediately upon writing this register.""" ) self.addr = CSRStorage(4, description=""" This register is directly connected to ``SB_LEDDA_IP.ADDR``. This register controls the address that is updated whenever ``DAT`` is written. Writing to this register has no immediate effect -- data isn't written until the ``DAT`` register is written.""" ) self.ctrl = CSRStorage(fields=[ CSRField( "exe", description= "Connected to ``SB_LEDDA_IP.LEDDEXE``. Set this to ``1`` to enable the fading pattern." ), CSRField( "curren", description= "Connected to ``SB_RGBA_DRV.CURREN``. Set this to ``1`` to enable the current source." ), CSRField( "rgbleden", description= "Connected to ``SB_RGBA_DRV.RGBLEDEN``. Set this to ``1`` to enable the RGB PWM control logic." ), CSRField( "rraw", description= "Set this to ``1`` to enable raw control of the red LED via the ``RAW.R`` register." ), CSRField( "graw", description= "Set this to ``1`` to enable raw control of the green LED via the ``RAW.G`` register." ), CSRField( "braw", description= "Set this to ``1`` to enable raw control of the blue LED via the ``RAW.B`` register." ), ], description= "Control logic for the RGB LED and LEDDA hardware PWM LED block." ) self.raw = CSRStorage(fields=[ CSRField("r", description= "Raw value for the red LED when ``CTRL.RRAW`` is ``1``."), CSRField( "g", description= "Raw value for the green LED when ``CTRL.GRAW`` is ``1``."), CSRField( "b", description= "Raw value for the blue LED when ``CTRL.BRAW`` is ``1``."), ], description=""" Normally the hardware ``SB_LEDDA_IP`` block controls the brightness of the LED, creating a gentle fading pattern. However, by setting the appropriate bit in ``CTRL``, it is possible to manually control the three individual LEDs.""" ) ledd_value = Signal(3) if revision == "pvt" or revision == "dvt": self.comb += [ If(self.ctrl.storage[3], rgba_pwm[1].eq( self.raw.storage[0])).Else(rgba_pwm[1].eq(ledd_value[0])), If(self.ctrl.storage[4], rgba_pwm[0].eq( self.raw.storage[1])).Else(rgba_pwm[0].eq(ledd_value[1])), If(self.ctrl.storage[5], rgba_pwm[2].eq( self.raw.storage[2])).Else(rgba_pwm[2].eq(ledd_value[2])), ] elif revision == "evt": self.comb += [ If(self.ctrl.storage[3], rgba_pwm[1].eq( self.raw.storage[0])).Else(rgba_pwm[1].eq(ledd_value[0])), If(self.ctrl.storage[4], rgba_pwm[2].eq( self.raw.storage[1])).Else(rgba_pwm[2].eq(ledd_value[1])), If(self.ctrl.storage[5], rgba_pwm[0].eq( self.raw.storage[2])).Else(rgba_pwm[0].eq(ledd_value[2])), ] elif revision == "hacker": self.comb += [ If(self.ctrl.storage[3], rgba_pwm[2].eq( self.raw.storage[0])).Else(rgba_pwm[2].eq(ledd_value[0])), If(self.ctrl.storage[4], rgba_pwm[1].eq( self.raw.storage[1])).Else(rgba_pwm[1].eq(ledd_value[1])), If(self.ctrl.storage[5], rgba_pwm[0].eq( self.raw.storage[2])).Else(rgba_pwm[0].eq(ledd_value[2])), ] else: self.comb += [ If(self.ctrl.storage[3], rgba_pwm[0].eq( self.raw.storage[0])).Else(rgba_pwm[0].eq(ledd_value[0])), If(self.ctrl.storage[4], rgba_pwm[1].eq( self.raw.storage[1])).Else(rgba_pwm[1].eq(ledd_value[1])), If(self.ctrl.storage[5], rgba_pwm[2].eq( self.raw.storage[2])).Else(rgba_pwm[2].eq(ledd_value[2])), ] self.specials += Instance( "SB_RGBA_DRV", i_CURREN=self.ctrl.storage[1], i_RGBLEDEN=self.ctrl.storage[2], i_RGB0PWM=rgba_pwm[0], i_RGB1PWM=rgba_pwm[1], i_RGB2PWM=rgba_pwm[2], o_RGB0=pads.r, o_RGB1=pads.g, o_RGB2=pads.b, p_CURRENT_MODE="0b1", p_RGB0_CURRENT="0b000011", p_RGB1_CURRENT="0b000011", p_RGB2_CURRENT="0b000011", ) self.specials += Instance( "SB_LEDDA_IP", i_LEDDCS=self.dat.re, i_LEDDCLK=ClockSignal(), i_LEDDDAT7=self.dat.storage[7], i_LEDDDAT6=self.dat.storage[6], i_LEDDDAT5=self.dat.storage[5], i_LEDDDAT4=self.dat.storage[4], i_LEDDDAT3=self.dat.storage[3], i_LEDDDAT2=self.dat.storage[2], i_LEDDDAT1=self.dat.storage[1], i_LEDDDAT0=self.dat.storage[0], i_LEDDADDR3=self.addr.storage[3], i_LEDDADDR2=self.addr.storage[2], i_LEDDADDR1=self.addr.storage[1], i_LEDDADDR0=self.addr.storage[0], i_LEDDDEN=self.dat.re, i_LEDDEXE=self.ctrl.storage[0], # o_LEDDON = led_is_on, # Indicates whether LED is on or not # i_LEDDRST = ResetSignal(), # This port doesn't actually exist o_PWMOUT0=ledd_value[0], o_PWMOUT1=ledd_value[1], o_PWMOUT2=ledd_value[2], o_LEDDON=Signal(), )
def document_interrupt(self, soc, submodules, irq): managers = submodules["event_managers"] for m in managers: sources_u = [ y for x, y in xdir(m, True) if isinstance(y, _EventSource) ] sources = sorted(sources_u, key=lambda x: x.duid) def source_description(src): if hasattr(src, "name") and src.name is not None: base_text = "`1` if a `{}` event occurred. ".format( src.name) else: base_text = "`1` if a this particular event occurred. " if hasattr(src, "description") and src.description is not None: return src.description elif isinstance(src, EventSourceLevel): return base_text + "This Event is **level triggered** when the signal is **high**." elif isinstance(src, EventSourcePulse): return base_text + "This Event is triggered on a **rising** edge." elif isinstance(src, EventSourceProcess): return base_text + "This Event is triggered on a **falling** edge." else: return base_text + "This Event uses an unknown method of triggering." # Patch the DocumentedCSR to add our own Description, if one doesn't exist. for dcsr in self.csrs: short_name = dcsr.short_name.upper() if short_name == m.status.name.upper(): if dcsr.fields is None or len(dcsr.fields) == 0: fields = [] for i, source in enumerate(sources): if hasattr(source, "name") and source.name is not None: fields.append( DocumentedCSRField( CSRField( name=source.name, offset=i, description= "Level of the `{}` event".format( source.name)))) else: fields.append( DocumentedCSRField( CSRField( name="event{}".format(i), offset=i, description= "Level of the `event{}` event". format(i)))) dcsr.fields = fields if dcsr.description is None: dcsr.description = "This register contains the current raw level of the Event trigger. Writes to this register have no effect." elif short_name == m.pending.name.upper(): if dcsr.fields is None or len(dcsr.fields) == 0: fields = [] for i, source in enumerate(sources): if hasattr(source, "name") and source.name is not None: fields.append( DocumentedCSRField( CSRField( name=source.name, offset=i, description=source_description( source)))) else: fields.append( DocumentedCSRField( CSRField( name="event{}".format(i), offset=i, description=source_description( source)))) dcsr.fields = fields if dcsr.description is None: dcsr.description = "When an Event occurs, the corresponding bit will be set in this register. To clear the Event, set the corresponding bit in this register." elif short_name == m.enable.name.upper(): if dcsr.fields is None or len(dcsr.fields) == 0: fields = [] for i, source in enumerate(sources): if hasattr(source, "name") and source.name is not None: fields.append( DocumentedCSRField( CSRField( name=source.name, offset=i, description= "Write a `1` to enable the `{}` Event" .format(source.name)))) else: fields.append( DocumentedCSRField( CSRField( name="event{}".format(i), offset=i, description= "Write a `1` to enable the `{}` Event" .format(i)))) dcsr.fields = fields if dcsr.description is None: dcsr.description = "This register enables the corresponding Events. Write a `0` to this register to disable individual events."
def __init__(self, platform, pads, refclk, cd_freerun="clk100", freerun_clk_freq=int(100e6), with_ila=True): LANES = 4 self.init_clk_locked = Signal(reset_less=True) self.sink_user_tx = sink_user_tx = Endpoint( kyokkoStreamDesc(lanes=LANES)) self.source_user_rx = source_user_rx = Endpoint( kyokkoStreamDesc(lanes=LANES)) # Clock domain self.clock_domains.cd_dp = cd_dp = ClockDomain() # Reset sequencer self.reset_pb = Signal() self.pma_init = Signal() # 最初の一度だけソースを読み込みたい if Aurora64b66b.verilog_source_ready is not True: import os.path srcdir = os.path.dirname(__file__) platform.add_sources(srcdir, "aurora_reset_seq.sv") Aurora64b66b.verilog_source_ready = True _vio_reset = Signal(reset_less=True) _reset_seq_done = Signal(reset_less=True) _init_clk_locked = Signal(reset_less=True) _are_sys_reset_synced = Signal(reset_less=True) from cores.xpm_fifo import XPMMultiReg self.specials += [ XPMMultiReg(self.init_clk_locked, _init_clk_locked, odomain=cd_freerun, n=8, reset=0), XPMMultiReg(cd_dp.rst, _are_sys_reset_synced, odomain=cd_freerun, n=8, reset=0), Instance( "aurora_reset_seq", p_INSERT_CDC=0b0, i_init_clk=ClockSignal(cd_freerun), i_init_clk_locked=_init_clk_locked, i_ext_reset_in=_vio_reset, i_are_sys_reset_in=_are_sys_reset_synced, o_done=_reset_seq_done, o_are_reset_pb_out=self.reset_pb, o_are_pma_init_out=self.pma_init, ) ] ip_vlnv = "xilinx.com:ip:aurora_64b66b" self.refname = "ar_" + pads.platform_info['quad'] self.ip_cfg = { "CONFIG.CHANNEL_ENABLE": " ".join(pads.platform_info['channel']), "CONFIG.C_START_QUAD": pads.platform_info['quad'], "CONFIG.C_AURORA_LANES": "4", "CONFIG.C_LINE_RATE": "25.78125", "CONFIG.C_REFCLK_FREQUENCY": "161.1328125", "CONFIG.C_INIT_CLK": freerun_clk_freq // 1000000, "CONFIG.flow_mode": "None", "CONFIG.SINGLEEND_GTREFCLK": "false" if isinstance(refclk, Record) else "true", "CONFIG.C_GT_LOC_4": "4", "CONFIG.C_GT_LOC_3": "3", "CONFIG.C_GT_LOC_2": "2", "CONFIG.drp_mode": "Native", "CONFIG.SupportLevel": "1", "CONFIG.C_USE_BYTESWAP": "true", "CONFIG.C_GTWIZ_OUT": "false", "CONFIG.C_UCOLUMN_USED": "left" if pads.platform_info['quad'][5:-2] == "X0" else "right", } platform.add_tcl_ip(ip_vlnv, self.refname, self.ip_cfg) # clock buffer if isinstance(refclk, Record): self.ip_params = dict(i_gt_refclk1_n=refclk.n, i_gt_refclk1_p=refclk.p) else: self.ip_params = dict(i_refclk_in=refclk) self.ip_params.update( i_init_clk=ClockSignal(cd_freerun), i_reset_pb=self.reset_pb, i_power_down=0b0, i_pma_init=self.pma_init, i_loopback=0b0, i_rxp=pads.rx_p, i_rxn=pads.rx_n, o_txp=pads.tx_p, o_txn=pads.tx_n, ) cdc_tx = XPMAsyncStreamFIFO(kyokkoStreamDesc(lanes=LANES), depth=512, sync_stages=4, xpm=True) cdc_tx = ClockDomainsRenamer({ "read": cd_dp.name, "write": "sys" })(cdc_tx) self.comb += self.sink_user_tx.connect(cdc_tx.sink) self.submodules.cdc_tx = cdc_tx cdc_rx = XPMAsyncStreamFIFO(kyokkoStreamDesc(lanes=LANES), depth=512, sync_stages=4, xpm=True) cdc_rx = ClockDomainsRenamer({ "read": "sys", "write": cd_dp.name })(cdc_rx) self.comb += cdc_rx.source.connect(self.source_user_rx) self.submodules.cdc_rx = cdc_rx if with_ila: # import util.xilinx_ila for ep in [cdc_tx.source, cdc_rx.sink]: for s in [ep.valid, ep.ready, ep.last]: platform.ila.add_probe(s, cd_dp.clk, trigger=True) for s in ep.payload.flatten(): platform.ila.add_probe(s, cd_dp.clk, trigger=False) self._status = CSRStatus(fields=[ CSRField("reset_pb", size=1), CSRField("pma_init", size=1), CSRField("mmcm_not_locked", size=1), ]) # Status Register mmcm_not_locked = Signal() from cores.xpm_fifo import XPMMultiReg self.specials += [ XPMMultiReg(self.reset_pb, self._status.fields.reset_pb, odomain="sys", n=4), XPMMultiReg(self.pma_init, self._status.fields.pma_init, odomain="sys", n=4), XPMMultiReg(mmcm_not_locked, self._status.fields.mmcm_not_locked, odomain="sys", n=4), ] self.ip_params.update( i_s_axi_tx_tdata=cdc_tx.source.data, i_s_axi_tx_tkeep=Replicate(0b1, len(cdc_tx.source.data) // 8), i_s_axi_tx_tlast=cdc_tx.source.last, i_s_axi_tx_tvalid=cdc_tx.source.valid, o_s_axi_tx_tready=cdc_tx.source.ready, o_m_axi_rx_tdata=self.cdc_rx.sink.data, o_m_axi_rx_tkeep=Signal(), o_m_axi_rx_tlast=self.cdc_rx.sink.last, o_m_axi_rx_tvalid=self.cdc_rx.sink.valid, ) lane_up = Signal(LANES, reset_less=True) channel_up = Signal(reset_less=True) hard_err = Signal(reset_less=True) soft_err = Signal(reset_less=True) # Status Output _gt_qpllrefclklost_quad1_out = Signal(reset_less=True) _gt_qplllock_quad1_out = Signal(reset_less=True) self.ip_params.update( o_gt_qpllclk_quad1_out=Signal(), o_gt_qpllrefclk_quad1_out=Signal(), o_gt_qpllrefclklost_quad1_out=_gt_qpllrefclklost_quad1_out, o_gt_qplllock_quad1_out=_gt_qplllock_quad1_out, o_gt_reset_out=Signal(), o_gt_powergood=Signal(), o_mmcm_not_locked_out=mmcm_not_locked, o_sys_reset_out=cd_dp.rst, o_user_clk_out=cd_dp.clk, o_link_reset_out=Signal(), o_sync_clk_out=Signal(), o_lane_up=lane_up, o_channel_up=channel_up, o_hard_err=hard_err, o_soft_err=soft_err, ) from util.xilinx_vio import XilinxVIO self.submodules.vio = vio = XilinxVIO(platform) vio.add_input_probe(lane_up, cd_dp) vio.add_input_probe(channel_up, cd_dp) vio.add_input_probe(hard_err, cd_dp) vio.add_input_probe(soft_err, cd_dp) vio.add_input_probe(self.pma_init) vio.add_input_probe(self.reset_pb) vio.add_input_probe(_reset_seq_done) vio.add_input_probe(_gt_qpllrefclklost_quad1_out) vio.add_input_probe(_gt_qplllock_quad1_out) # FIXME: Timing error on Trefoil platform vio.add_output_probe(_vio_reset) for _n in range(0, LANES): self.ip_params.update({ f"i_gt{_n}_drpaddr": 0, f"i_gt{_n}_drpdi": Replicate(0b0, 10), f"o_gt{_n}_drpdo": Signal(16), f"i_gt{_n}_drpen": 0, f"o_gt{_n}_drprdy": Signal(), f"i_gt{_n}_drpwe": 0, }) self.specials += Instance(self.refname, name=self.refname + "_i", **self.ip_params)
def __init__(self): self.intro = ModuleDoc("""SoC Version Information This block contains various information about the state of the source code repository when this SoC was built. """) def makeint(i, base=10): try: return int(i, base=base) except: return 0 def get_gitver(): major = 0 minor = 0 rev = 0 gitrev = 0 gitextra = 0 dirty = 0 def decode_version(v): version = v.split(".") major = 0 minor = 0 rev = 0 if len(version) >= 3: rev = makeint(version[2]) if len(version) >= 2: minor = makeint(version[1]) if len(version) >= 1: major = makeint(version[0]) return (major, minor, rev) git_rev_cmd = subprocess.Popen(["git", "describe", "--tags", "--long", "--dirty=+", "--abbrev=8"], stdout=subprocess.PIPE, stderr=subprocess.PIPE) (git_stdout, _) = git_rev_cmd.communicate() if git_rev_cmd.wait() != 0: print('unable to get git version') return (major, minor, rev, gitrev, gitextra, dirty) raw_git_rev = git_stdout.decode().strip() parts = raw_git_rev.split("-") if raw_git_rev[-1] == "+": raw_git_rev = raw_git_rev[:-1] dirty = 1 if len(parts) >= 3: if parts[0].startswith("v"): version = parts[0] if version.startswith("v"): version = parts[0][1:] (major, minor, rev) = decode_version(version) gitextra = makeint(parts[1]) if parts[2].startswith("g"): gitrev = makeint(parts[2][1:], base=16) elif len(parts) >= 2: if parts[1].startswith("g"): gitrev = makeint(parts[1][1:], base=16) version = parts[0] if version.startswith("v"): version = parts[0][1:] (major, minor, rev) = decode_version(version) elif len(parts) >= 1: version = parts[0] if version.startswith("v"): version = parts[0][1:] (major, minor, rev) = decode_version(version) return (major, minor, rev, gitrev, gitextra, dirty) (major, minor, rev, gitrev, gitextra, dirty) = get_gitver() self.major = CSRStatus(8, reset=major, description="Major git tag version. For example, this firmware was built from git tag ``v{}.{}.{}``, so this value is ``{}``.".format(major, minor, rev, major)) self.minor = CSRStatus(8, reset=minor, description="Minor git tag version. For example, this firmware was built from git tag ``v{}.{}.{}``, so this value is ``{}``.".format(major, minor, rev, minor)) self.revision = CSRStatus(8, reset=rev, description="Revision git tag version. For example, this firmware was built from git tag ``v{}.{}.{}``, so this value is ``{}``.".format(major, minor, rev, rev)) self.gitrev = CSRStatus(32, reset=gitrev, description="First 32-bits of the git revision. This documentation was built from git rev ``{:08x}``, so this value is {}, which should be enough to check out the exact git version used to build this firmware.".format(gitrev, gitrev)) self.gitextra = CSRStatus(10, reset=gitextra, description="The number of additional commits beyond the git tag. For example, if this value is ``1``, then the repository this was built from has one additional commit beyond the tag indicated in `MAJOR`, `MINOR`, and `REVISION`.") self.dirty = CSRStatus(fields=[ CSRField("dirty", reset=dirty, description="Set to ``1`` if this device was built from a git repo with uncommitted modifications.") ]) self.comb += [ self.major.status.eq(major), self.minor.status.eq(minor), self.revision.status.eq(rev), self.gitrev.status.eq(gitrev), self.gitextra.status.eq(gitextra), self.dirty.fields.dirty.eq(dirty), ]
def __init__(self, adc_ctrl, adc_data): self.wishbone = wishbone.Interface() self._start = CSRStorage(fields=[CSRField("start_burst", size=1, offset=0, pulse=True)]) self._ready = CSRStatus(8) self._burst_size = CSRStorage(16) self._base = CSRStorage(32) self._offset = CSRStorage(32) words_count = Signal(16) pass_count = Signal(5) self.comb += [ adc_ctrl.en_pwr.eq(1), adc_ctrl.pdn.eq(0), ] frontend_we = Signal() frontend_re = Signal() # FIFO self.adc_frontend_a = adc_frontend_a = ADC_Frontend() self.comb += [ adc_frontend_a.i_fclk.eq(adc_data.fclk), adc_frontend_a.i_dclk.eq(ClockSignal("adc_bitclk")), adc_frontend_a.i_din_0.eq(adc_data.da0), adc_frontend_a.i_din_1.eq(adc_data.da1), adc_frontend_a.i_we.eq(frontend_we), adc_frontend_a.i_re.eq(frontend_re), ] self.submodules += adc_frontend_a self.adc_frontend_b = adc_frontend_b = ADC_Frontend() self.comb += [ adc_frontend_b.i_fclk.eq(adc_data.fclk), adc_frontend_b.i_dclk.eq(ClockSignal("adc_bitclk")), adc_frontend_b.i_din_0.eq(adc_data.db0), adc_frontend_b.i_din_1.eq(adc_data.db1), adc_frontend_b.i_we.eq(frontend_we), adc_frontend_b.i_re.eq(frontend_re), ] self.submodules += adc_frontend_b self.wb_dma = wb_dma = WishboneDMAWriter(self.wishbone, endianness="big") self.submodules += wb_dma self.comb += [ self.wb_dma.sink.address.eq((self._base.storage >> 2) + (self._offset.storage>>2) + words_count), self.wb_dma.sink.data.eq(adc_frontend_a.o_dout + (adc_frontend_b.o_dout << 16)) ] fsm = FSM(reset_state="ADC_RESET") self.submodules += fsm fsm.act("ADC_RESET", adc_ctrl.reset.eq(1), NextState("WAIT-FOR-TRIGGER"), ) fsm.act("WAIT-FOR-TRIGGER", self._ready.status.eq(1), frontend_we.eq(0), NextValue(words_count, 0), If(self._start.fields.start_burst, NextState("CLEAR-FIFO"), ) ) # TODO: clear fifo at end of read instead of before.. fsm.act("CLEAR-FIFO", frontend_re.eq(1), If(adc_frontend_a.o_readable == 0, NextState("WAIT-FOR-DATA"), ) ) fsm.act("WAIT-FOR-DATA", frontend_we.eq(1), If(adc_frontend_a.o_readable, NextState("WRITE-DATA"), ), ) fsm.act("WRITE-DATA", frontend_we.eq(1), self.wb_dma.sink.valid.eq(1), If(self.wb_dma.sink.ready, NextValue(words_count, words_count+1), frontend_re.eq(1), If(words_count == (self._burst_size.storage-1), NextState("WAIT-FOR-TRIGGER"), NextValue(pass_count, pass_count+1) ).Else( NextState("WAIT-FOR-DATA"), ) ) )
def __init__(self, platform, pads, size=2 * 1024 * 1024): self.size = size self.bus = bus = wishbone.Interface() self.reset = Signal() self.cfg1 = CSRStorage(fields=[ CSRField( "bb_out", size=4, description="Output bits in bit-bang mode"), CSRField("bb_clk", description="Serial clock line in bit-bang mode"), CSRField("bb_cs", description="Chip select line in bit-bang mode"), ]) self.cfg2 = CSRStorage(fields=[ CSRField("bb_oe", size=4, description="Output Enable bits in bit-bang mode"), ]) self.cfg3 = CSRStorage(fields=[ CSRField( "rlat", size=4, description="Read latency/dummy cycle count"), CSRField("crm", description="Continuous Read Mode enable bit"), CSRField("qspi", description="Quad-SPI enable bit"), CSRField("ddr", description="Double Data Rate enable bit"), ]) self.cfg4 = CSRStorage(fields=[ CSRField( "memio", offset=7, reset=1, description= "Enable memory-mapped mode (set to 0 to enable bit-bang mode)") ]) self.stat1 = CSRStatus(fields=[ CSRField( "bb_in", size=4, description="Input bits in bit-bang mode"), ]) self.stat2 = CSRStatus(1, fields=[], description="Reserved") self.stat3 = CSRStatus(1, fields=[], description="Reserved") self.stat4 = CSRStatus(1, fields=[], description="Reserved") cfg = Signal(32) cfg_we = Signal(4) cfg_out = Signal(32) self.comb += [ cfg.eq( Cat(self.cfg1.storage, self.cfg2.storage, self.cfg3.storage, self.cfg4.storage)), cfg_we.eq( Cat(self.cfg1.re, self.cfg2.re, self.cfg3.re, self.cfg4.re)), self.stat1.status.eq(cfg_out[0:8]), self.stat2.status.eq(cfg_out[8:16]), self.stat3.status.eq(cfg_out[16:24]), self.stat4.status.eq(cfg_out[24:32]), ] mosi_pad = TSTriple() miso_pad = TSTriple() cs_n_pad = TSTriple() clk_pad = TSTriple() wp_pad = TSTriple() hold_pad = TSTriple() self.specials += mosi_pad.get_tristate(pads.mosi) self.specials += miso_pad.get_tristate(pads.miso) self.specials += cs_n_pad.get_tristate(pads.cs_n) self.specials += clk_pad.get_tristate(pads.clk) self.specials += wp_pad.get_tristate(pads.wp) self.specials += hold_pad.get_tristate(pads.hold) reset = Signal() self.comb += [ reset.eq(ResetSignal() | self.reset), cs_n_pad.oe.eq(~reset), clk_pad.oe.eq(~reset), ] flash_addr = Signal(24) # size/4 because data bus is 32 bits wide, -1 for base 0 mem_bits = bits_for(int(size / 4) - 1) pad = Signal(2) self.comb += flash_addr.eq(Cat(pad, bus.adr[0:mem_bits - 1])) read_active = Signal() spi_ready = Signal() self.sync += [ If( bus.stb & bus.cyc & ~read_active, read_active.eq(1), bus.ack.eq(0), ).Elif( read_active & spi_ready, read_active.eq(0), bus.ack.eq(1), ).Else( bus.ack.eq(0), read_active.eq(0), ) ] o_rdata = Signal(32) self.comb += bus.dat_r.eq(o_rdata) self.specials += Instance( "spimemio", o_flash_io0_oe=mosi_pad.oe, o_flash_io1_oe=miso_pad.oe, o_flash_io2_oe=wp_pad.oe, o_flash_io3_oe=hold_pad.oe, o_flash_io0_do=mosi_pad.o, o_flash_io1_do=miso_pad.o, o_flash_io2_do=wp_pad.o, o_flash_io3_do=hold_pad.o, o_flash_csb=cs_n_pad.o, o_flash_clk=clk_pad.o, i_flash_io0_di=mosi_pad.i, i_flash_io1_di=miso_pad.i, i_flash_io2_di=wp_pad.i, i_flash_io3_di=hold_pad.i, i_resetn=~reset, i_clk=ClockSignal(), i_valid=bus.stb & bus.cyc, o_ready=spi_ready, i_addr=flash_addr, o_rdata=o_rdata, i_cfgreg_we=cfg_we, i_cfgreg_di=cfg, o_cfgreg_do=cfg_out, ) platform.add_source("rtl/spimemio.v")
def __init__(self, dat, clk, sys_clk_freq): if type(dat) != TSTriple: t = TSTriple() self.specials += t.get_tristate(dat) dat = t if type(clk) != TSTriple: t = TSTriple() self.specials += t.get_tristate(clk) clk = t dat_i = Signal() clk_i = Signal() self.specials += [ MultiReg(dat.i, dat_i), MultiReg(clk.i, clk_i), ] self.comb += [ dat.oe.eq(0), clk.oe.eq(0), ] fields = [ CSRField(name="data", size=8, description="Received data"), CSRField(name="valid", description="Data valid"), ] self.rx = CSRStatus(32, description="Receive register", fields=fields) self.submodules.ev = EventManager() self.ev.data = EventSourceLevel() self.ev.finalize() layout = EndpointDescription([("data", 8)]) self.submodules.rx_fifo = rx_fifo = SyncFIFO(layout, 16) self.comb += [ self.rx.fields.data.eq(rx_fifo.source.data), self.rx.fields.valid.eq(rx_fifo.source.valid), rx_fifo.source.ready.eq(self.rx.we), self.ev.data.trigger.eq(rx_fifo.source.valid), ] # One transaction lasts about 1.1ms, so we can consider the bus idle # after 1.5ms of high CLK state idle_ticks = int(sys_clk_freq * 1.5e-3) reset = Signal() self.submodules.reset_timer = WaitTimer(idle_ticks) self.comb += [ self.reset_timer.wait.eq(clk_i), reset.eq(self.reset_timer.done), ] # Stabilize CLK clk_stable = Signal() prev_clk = Signal() self.sync += prev_clk.eq(clk_i) self.submodules.clk_timer = WaitTimer(10) self.comb += [ self.clk_timer.wait.eq(prev_clk == clk_i), clk_stable.eq(self.clk_timer.done), ] clk_pulse = Signal() clk_stable_d = Signal() self.sync += [ clk_stable_d.eq(clk_stable), clk_pulse.eq(clk_stable & ~clk_stable_d) ] bits = Signal(11) bitcount = Signal(4) parity = reduce(xor, bits) self.sync += [ rx_fifo.sink.valid.eq(0), If(reset, bitcount.eq(0), bits.eq(0), ).Else( If(clk_pulse & ~clk_i, bits.eq(Cat(bits[1:], dat_i)), bitcount.eq(bitcount + 1) ).Elif(bitcount == 11, If(bits[10] & ~bits[0] & ~parity, rx_fifo.sink.data.eq(bits[1:9]), rx_fifo.sink.valid.eq(1), ), bitcount.eq(0), bits.eq(0) ) ) ]