Giter Site home page Giter Site logo

lneuhaus / pyrpl Goto Github PK

View Code? Open in Web Editor NEW
139.0 32.0 108.0 205.33 MB

pyrpl turns your RedPitaya into a powerful DSP device, especially suitable as a lockbox in quantum optics experiments.

Home Page: http://lneuhaus.github.io/pyrpl/

License: MIT License

Python 70.00% Makefile 0.49% Tcl 2.89% Verilog 24.25% SystemVerilog 0.49% Shell 0.22% C 0.66% Batchfile 0.01% Dockerfile 0.22% Jupyter Notebook 0.78%

pyrpl's Introduction

PyRPL

travis status appveyor status code coverage Python versions on PyPI PyRPL version on PyPI Download pyrpl Documentation Status join chat on gitter License

Download PyRPL

PyRPL (Python RedPitaya Lockbox) turns your RedPitaya into a powerful DSP device, especially suitable as a digital lockbox and measurement device in quantum optics experiments.

Website

The official PyRPL website address is http://pyrpl.readthedocs.io/. The information on the website is more up-to-date than in this readme.

Installation

The easiest and fastest way to get PyRPL is to download and execute the precompiled executable for windows. This option requires no extra programs to be installed on the computer.

If instead you would like to use and/or modify the source code, make sure you have an installation of Python (2.7, 3.4, 3.5, or 3.6). If you are new to Python or unexperienced with fighting installation issues, it is recommended to install the Anaconda Python distribution, which allows to install all PyRPL dependencies via

conda install numpy scipy paramiko pandas nose pip pyqt qtpy pyqtgraph pyyaml nbconvert

Check this documentation section for hints if you are unable to execute conda in a terminal. Alternatively, if you prefer creating a virtual environment for pyrpl, do so with the following two commands

conda create -y -n pyrpl-env numpy scipy paramiko pandas nose pip pyqt qtpy pyqtgraph pyyaml nbconvert
activate pyrpl-env

If you are not using Anaconda, you must manually install the python package PyQt5 or PyQt4, which requires a working C compiler installation on the system.

Next, clone (if you have a git client installed - recommended option) the pyrpl repository to your computer with

git clone https://github.com/lneuhaus/pyrpl.git

or download and extract (if you do not want to install git on your computer) the repository.

Install PyRPL by navigating with the command line terminal (the one where the pyrpl-env environment is active in case you are using anaconda) into the pyrpl root directory and typing

python setup.py develop

Quick start

First, hook up your Red Pitaya / STEMlab to a LAN accessible from your computer (follow the instructions for this on redpitya.com and make sure you can access your Red Pitaya with a web browser by typing its ip-address / hostname into the address bar). In a command line terminal, type

python -m pyrpl your_configuration_name

A GUI should open, let you configure the redpitaya device you would like to use, and you can start playing around with pyrpl. Different strings for 'your_configuration_name' create different configurations that will be automatically remembered by PyRPL, for example if you have several different redpitayas. Different RedPitayas with different configuration names can be run simultaneously in separate terminals.

Issues

We collect a list of common problems on the documenation website. If you do not find your problem listed there, please report all problems or wishes as new issues on this page, so we can fix it and improve the future user experience.

Unit test

If you want to check whether PyRPL works correctly on your machine, navigate with a command line terminal into the pyrpl root directory and type the following commands (by substituting the ip-address / hostname of your Red Pitaya, of course)

set REDPITAYA_HOSTNAME=your_redpitaya_ip_address
nosetests

All tests should take about 3 minutes and finish without failures or errors. If there are errors, please report the console output as an issue (see the section "Issues" below for detailed explanations).

Next steps / documentation

The full html documentation is hosted at http://pyrpl.readthedocs.io. Alternatively, you can download a .pdf version at https://media.readthedocs.org/pdf/pyrpl/latest/pyrpl.pdf. We are still in the process of creating an fully up-to-date version of the documentation of the current code. If the current documentation is wrong or insufficient, please post an issue and we will prioritize documenting the part of code you need.

Updates

Since PyRPL is continuously improved, you should install upgrades if you expect bugfixes. If you installed PyRPL by using pip, just type

pip install --upgrade pyrpl

If instead you have clonded the github repository (recommended for bleeding-edge updates), navigate into the pyrpl root directory on your local harddisk computer and type

git pull

FPGA bitfile generation (only for developers)

In case you would like to modify the logic running on the FPGA, you should make sure that you are able to generate a working bitfile on your machine. In short, to do so, you must install Vivado 2015.4 [(64-bit windows](windows web-installer](https://www.xilinx.com/member/forms/download/xef.html?filename=Xilinx_Vivado_SDK_2015.4_1118_2_Win64.exe&akdm=1) or Linux) together with a working license. Next, with a terminal in the pyrpl root directory, type

cd pyrpl/fpga
make

Compilation should take between 10 and 30 minutes, depending on your machine. If there are no errors during compilation, the new bitfile (pyrpl/fpga/red_pitaya.bin) will be automatically used at the next restart of PyRPL. The best way to getting started is to skim through the very short Makefile in the fpga directory and to continue by reading the files mentioned in the makefile and the refences therein. All verilog source code is located in the subdirectory pyrpl/fpga/rtl/.

License

Please read our license file LICENSE for more information.

pyrpl's People

Contributors

alexandrejourneaux avatar alfrisch avatar eivanov556 avatar ivan-galinskiy avatar jerome-lma avatar leo10tt10 avatar lneuhaus avatar manipmembranes avatar metzdorffremi avatar michaelcroquette avatar neago avatar pyrpl-visitor avatar samueldeleglise avatar sundaechen avatar xueshiguo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pyrpl's Issues

MemoryTree behaves non-intuitively

I am not sure whether it is a bug or a "feature", but the following works fine:
pyrpl.c.foo.bar = 4 # if foo and bar are already existing
this works fine as well
pyrpl.c.foo["bar"] = 4 # #even if bar did not exist before
On the other hand, this never works:
pyrpl.c["foo"]["bar"] = 4 # even if foo and bar exist
Moreover, it doesn't throw any error, and even worst, it gives the wrong impression that the data has been stored properly, eventhough the file hasn't been touched at all... I find this very misleading...

Also, it is not clear to me how to create new branches: it seems that you have to do:
pyrpl.c["foo"] = dict() # I would have expected something like pyrpl.c._new_branch("foo")

oscilloscope duration

It would be nice to have durations 10_[2_*(-n) for n in range(???)] (sampling-rate limited) available in the scope..

Improve sampler to read arbitrary large number of values

It would be nice to have a function sampler.read('adc1', 10000) to read 10000 values in a short time.

Even if the values are not guaranteed to be consecutive, it would still be very useful to have an idea of the variance and mean of the channel without having to block the resource of the scope. In particular, in the context of detecting unlocks of the lockbox.

Gui bugs collection

  • NA:
  • upper plot should be in logscale
  • when 'logscale' is enabled, frequency axis should be in log scale as well

Outputs dont work / FPGA timing problem

There is a timing problem with the FPGA. The current version fails compilation. I need to add more delay in the output summation.. The problem also makes that with the current bitfile the outputs remain zero whatever is done to them. Internal signal processing works however.

CurveDB gui

Similar thing - a gui tab should display a list of all CurveDB objects, and display the selected Curve(s) in a graph, along with their params.

Code hangs if automatically started in ipython

If you load a file containing the following ipython the code hangs while it tries to establish a connection to the redpitaya:

from pyrpl import RedPitaya
r = RedPitaya()

If you load the same code with python (without the i), it works correctly. The issue is in paramiko, not in pyrpl. The bug has been reported since April: paramiko/paramiko#719
With older versions of paramiko, I did not experience this problem. However, reverting to those older versions does not work any better for some reason. If someone has a nice idea for avoiding this bug, lets hear it. For now, using system calls to launch paramiko can do the job, but it is a very ugly solution.

Renaming of Variables

Some variables have unintuitive names. Let's collect them here and do a collective renaming some day in the future, when everybody is aware that issues might arise.

  • asg.scale should be asg.amplitude

Big refactorization

I have spent the week-end on code refactoring. I hope to be able to issue a pull-request by the end of the week. I list here the main changes that are on-going + some that we need to make sure we agree upon:

Main changes:

Before: the gui was a layer completely disconnected from the redpitaya_module layer. So, to know which registers are displayed in the gui, one had to look in the redpitaya_gui.py file. Moreover; the names of the registers had to match in the 2 different places.

Now:

  1. Registers handle their gui themselves:
    The Registers have a function create_widget() that automatically creates the widget according to the kind of register we have. Moreover, the set and get attributes of the Registers handle themselves the gui updating such that timers are not needed anymore to maintain the gui in-sync with the redpitaya.

  2. created a class BaseAttribute that is more general than Register:
    All the mechanisms that are expected to happen when the value of a register is changed (updating gui, saving the new value to a config file) is also sometimes needed for an attribute that is not directly a register (for instance scope.input1 was in fact a property that was modifying the register scope._ch1.input). For that reason, the set/get method hack described in 1 is implemented in an ancestor class of Register that is called BaseAttribute. Then the descriptor doing the trick scope.input1 --> scope._ch1.input is now a ScopeInputAttribute(SelectAttribute) that simply has custom methods get_value()/set_value(). However, the gui updating is done transparently as if it was a register and the create_widget method comes for free from the ancestor. These Attributes will be also useful to implement SoftwareModules that are not really mapping a module on the fpga, but which should be displayed as a widget in the gui, and should use parameter gui/saving mechanisms as if they were real modules (e.g.: curve fitting, or pyrpl_control)

  3. The list of Attributes that should be displayed in the gui are defined in a single place:
    ModuleClass.gui_attributes: a list containing the names of the attributes to display
    ModuleClass.save_attributes: a list containing the names of the attributes to save in the config file

  4. In principle, if the gui display is as simple as exposing the gui_attributes in the gui, the default ModuleWidget class can handle it. However, sometimes more involved stuffs have to be done (for instance, adding a plot window for the scope...). For this reason, the particular class of widget that should be created when calling module.create_widget is configurable in
    ModuleClass.widget_class
    --> This solves a problem that I encountered a lot with the previous version: how do I easily subclass a module_widget to add my custom buttons without messing up with pyrpl's source code?

  5. ModuleWidget instances are now accessed via module.widget (rather than at the same level before) which reduces the pollution of the redpitaya namespace.

  6. Now (after oral discussion with LÊo), I think we are OK to merge Pyrpl and Redpitaya into one class, such that Attributes can be saved in the config file that is currently only accessible to pyrpl level. To let the user decide whether he wants to load only the redpitaya level or the full pyrpl high-level functionality, the constructor of the class should take an argument that will let him decide which modules to load. The high-level pyrpl functionalities will simply be implemented in a particular SoftwareModule. Of course, if the user initializes the object with the name of a config-file, the list of modules to load by default will be read from the config-file.

  7. In case the high-level pyrpl_control module is loaded, it would be nice to export the attributes of this module directly to the parent object (should we call it Redpitaya or Pyrpl?).

I guess once this is done, the smell of the code should be greatly improved...

Scope trig on 3rd signal

Many times one wants to record signal1 and signal2, triggered by some threshold on signal3. Therefore we should add a third scope channel for this. To save resources, we should:

  • remove the double trigger in the scope module
  • not create a databuffer for signal3 (therefore it will be a 'virtual' signal)
  • remove one of the 2 asg channels (1 asg channel is enough for everything we have done so far

This will liberate a slot for the extra signal in dsp_module.

module.params should be uniformized

  • Each DSP module / scope / fgen should have a property and setter params that recovers a dictionary containing the current state of the module. The setter should do essentially the same thing as setup with that dictionary. When curves are saved, the params should be added to the curve by default.

===> Now, every module has a list parameter_names containing the name of the relevant parameters
a function set_state(dic) ==> That sets the state from the dictionnary
a function get_state() ===> that returns a dictionnary

  • Similarly, the gui modules should also have a uniform syntax for retrieving / setting params dicts.

Using the list property_names, the same functionality is implemented:
a function set_state(dic) ==> That sets the state from the dictionnary
a function get_state() ===> that returns a dictionnary
== For now, module level and gui level are completely independent, and the lists parameter_names (in class Module) and property_names (in class ModuleWidget) have to be maintained independently. I think, it is better to stick with this in order not to introduce coupling between these 2 layers...
== The function save (in the gui) appends this dictionary to the curve parameters

  • This functionality should be used by the gui to improve user comfort.

I am not sure if we want to reload previous settings of all modules at startup (for instance with a 1 s autosave timer) ? This could make the scripts harder to debug since initial conditions would depend on the history... Otherwise, that is easy to do, just let me know.

  • Pyrpl should also make use of this, i.e. to restore the previous scope setting after a measurement.
    For now, spec_an and scope --who share the same hardware resource-- are 2 tabs of a single TabWidget, and whenever the active tab is toggled, the other module is stopped and parameters are restored from a hot backup.

Nosetests fail on 'bad' silicon

One older RedPitaya does not pass nosetests. There are 6 failures, related to

  • NA transfer function incorrect
  • pid.d and asg.phase registers do not reliably store values: some bits can be written to high but never return to low unless fpga is reset (among them bit 18 of pid.d register, who knows why this one).

This is probably a timing/threshold voltage issue, but the issue can be resolved by reducing FPGA complexity slightly. The errors are reproducible, and robust against a 1V change of supply voltage (5->6V). This shows the importance of executing unittests on every device that is used.

However, the na transfer issue is not well-understood. It looks like the acquisition goes well until after a few points the transfer function drops rapidly towards very small values. Most likely this is also some data transfer issue.

In the long run, we should reduce FPGA complexity for the master release slightly (easiest by restricting IIR stages to 8 or so), and distribute some 'advanced' versions of the bitfile for nonstandard applications like high-order IIR filters, which must be tested on the Redpitaya to run on. If you observe this problem, maybe we can collect the RedPitaya MAC addresses here to find out if its related to the age/manufacture date of the chip.

Failed no 1 (actually the first one I bought in 2014): 00:26:32:F0:08:8A

Output limits on individual modules

Since we are multiplexing low frequency/high frequency signals on one DAC output, saturation of the output of one module has a detrimental effect on the other component of the output signal. A natural way of dealing with the problem would be to saturate the output of individual modules before they enter the summation stage.

For instance:
r.module1.max_output_voltage = 0.8
r.module1.min_output_voltage = -0.8

IQ possibly yiels imperfect sine

average over sine slightly non-zero.. Reason: very likely timing problem in red_pitaya_iq_fgen.v:
the inversion signals don't arrive at the right moment..

installation issues

  • install pyqtgraph
  • install guiqwt for fitting
  • default hostname leads to errors in nosetests
  • setup_pdh automatically launched even if not wanted
  • save curves must be tested in unittests
  • curves directory must be there by default

IIR gui

Since there is a gui for everything now, people will not be aware that there is an IIR module. If anyone has some spare time, one could migrate bodefit into another gui module to set up and diagnose the iir filter.

scipy 18 dependence

sos2zpk is a new function of scipy, only used once in iir.py for a special case. Replace by raw code..

Dock positions

Dont think this is related to lock():

r.lock(factor=20)

KeyError Traceback (most recent call last)
C:\Users\Remi\Documents\GitHub\pyrpl\pyrpl\pyrpl.pyc in _save_window_position(self)
530
531 def _save_window_position(self):
--> 532 if self.c["dock_positions"]!=bytes(self.rp.main_window.saveState()):
533 self.c["dock_positions"] = bytes(self.rp.main_window.saveState())
534 try:

C:\Users\Remi\Documents\GitHub\pyrpl\pyrpl\memory.pyc in getitem(self, item)
196 self._reload()
197 try:
--> 198 return self._data[item]
199 except KeyError:
200 for defaultbranch in self._defaults:

KeyError: 'dock_positions'

monitor_server speedup possible

need to debug what happens when monitor_server does not create a new memory interface per request but keeps it forever - speedup possible?

Flatness of NA transfer function limited

Internal transfer function is only flat to +-0.5 dB -> where does this problem come from?
-> very likely artifact from lookup-table iq_fgen, but not clear whether this is normal for finite-size LUT's (and should be corrected by calibration factors for each frequency), or whether this is a bug..

to reproduce, check the data returned by
f, tf = r.iq1.na_trace(start=1e3, stop=50e6, points=1001, rbw=1000, avg=1, amplitude=0.2, input='iq1', output_direct='off', acbandwidth=0)
plt.plot(f,20.*np.log10(np.abs(tf)))

any ideas?

Add scope trigger on ASG sync

Right now, the option scope.trigger_source = "asg_trigger_positive_edge" will only let the scope trig once at the ASG setup call. It would be nice to trig on every asg cycle:

This could be either a new trigger_source : "asg_sync_positive_edge"
or simply modify the ASG trigger to send an event at every cycle...

I am not sure which solution is the best.

Point on refactoring

Current status

I am now at the point where everything is working fine again: the whole attribute layer has been carefully redesigned to include gui and parameter saving in an efficient and elegant way. All unittests are OK, and for the end-user, the API has only undergone minor changes:

  • accessing software modules (such as na and spectrum_analyzer) is done via pyrpl.na.
  • accessing hardware_module is done via either the old way (pyrpl.rp.iq1 for quick debugging) or using the ModuleManagers (iq = pyrpl.iqs.pop(owner_name) to be consistent, scope and iir can also be accessed via pyrpl.scopes.pop() or pyrpl.iir.pop(), after all, it's only an implementation detail that we have decided to have only one scope and one iir...)
  • The whole organization of the config file has been redesigned: it is now pretty much module-oriented (one module=one section)

New cool features:

  • The attribute widgets are now working perfectly (even in log increment mode), because they are fully aware of the minimum increment and max/min values of the underlying attribute (I also included support for mouse wheel).
  • Thanks to the normalized way attributes are defined, all buttons now come with an informative tooltip (help displayed upon mouse hover) with min/max/increment values. Also, the attribute's helpstring is displayed in the tooltip.
  • Modules are auto-saving and reloading their parameters from the config file.
  • setup() finally has a nice help string autogenerated from the setup_attributes list (the same that is used to know which parameters are necessary to save/store the module state). In the end the helpstring for attributes is defined only in one place (at the attribute's creation), and not duplicated in the setup() helpstring, which was a pain to maintain.
  • The config file defines a list of modules to be loaded at startup to make things modular. For instance, those only interested by interfacing the hardware_modules of the redpitaya (previously RedPitaya class users) would leave this list empty.
  • Another big advantage of the new attribute design is that creating new software_modules with automatically generated GUI and parameter saving is extremely easy (and clean). The plan is to allow users to build their own software_modules (or derived module classes) to control their experiment and to include these external modules without screwing up the repository by adding "my_external_python_package.MySoftwareModuleClass" in the list of modules defined in the config file.
  • There is a gui for the iir module (to be improved, see below).
  • There is an ownership mechanism for modules that is fully integrated with the pop() logic and parameter saving. For instance, when a module is freed, its attributes automatically come back to the preceding state. Also, the widget visibility is disabled/enabled when its ownership changes (the owner name is also visible for clarity).
  • For instance, the scope<-> spec an interaction is much more peaceful than previously: launching a spec-an acquisition will stop the current scope acquisition, disable the scope gui for the time of the acquisition, and put back the scope in the previous working state afterwards. Now, there is no need to have scope and spec an guis on 2 mutually exclusive tabs.
  • Possibility to close and reopen unneeded modules in the gui.
  • I finally found the way to show a message (with nice coloring) in the statusbar of Pyrpl's main window when an exception occurs in the event loop (working both in ipython or standalone mode): this avoids the big pitfall of not noticing the exceptions when they pop out in the background console.

That's all I can think of right now...

Issues fixed:

  • #76 IIR gui -->I would say half of it, see below
  • #65 module params should be uniformized --> That was the initial point
  • #40 Renaming of variables (the part of it on numbering) --> All module index are now 1-based
  • #36 Gui bug collections: I expect most of these bugs to be gone, and given the much cleaner gui code now, bug hunting in the gui should become a pleasure.

What is still left to do before pulling into master:

  • Make some new unittests to test the new functionalities.

  • Gui for the iir is still minimalist (basically, an interface to define zeros and poles), it would be really nice to include the graph with the transfer function in the widget, with some nice keyboard shortcuts to move zeros/poles values as you (Leo) did it in bodeplot. However, I am not sure if I will be very efficient at doing that, and I will probably wait for you before doing it since I am not sure if we want to just keep everything from your bodefit or to adapt it slightly (for instance, using pyqtgraph and QShortCuts instead of matplotlib?).

  • With this huge cleanup in attribute saving, it becomes extremely easy to add save/restore states for each modules. for instance, if a new state for an iq is saved with name 'pdh', I suggest to create a section "iq__pdh" (2 underscores to avoid accidental collision with user module names) in the config file, that can be loaded to any of the 3 iq modules later on. Of course, for software modules, this will work perfectly fine as well since they use the same Attribute logic. Even cooler, we could choose to let the attribute save their modifications in the "active" state of each modules instead of the default state (eventually, there could be a flag "autosave=True/False" in each state).

  • Lockbox is still not re-included in the code (and that is probably the most important point of this post where I would need feedback): my plan is to encapsulate the lockbox functionality inside a software_module "lockbox" that would be accessed similar to the na or the spectrum_analyzer. I guess it would be nice to build a little bit upon the load/save state mechanism that I described above.
    For instance, it would make sense that when going into sweep mode, rather than having the lockbox slaving the scope (and thus blocking any gui input), to have the lockbox load the "sweep" state of the scope, allowing the user to make modifications on that state on the fly. The only time when the scope needs to be really slaved is when acquiring calibration curves (anyway, the "sweep" state could be used)
    Also since I believe each OutputSignal has an associated pid, why not to have a state "fast_piezo", "slow_piezo" (the output signal names) for the pids. These states would be loaded whenever the lockbox is set to a locking state (actually, in this case, we probably also want the iqs to be slaved because gains are really handled by the high-level lockbox module).

A possibility would be that the scope, iq, and iir states are only created once by the lockbox (and then eventually manipulated by the adult user) while the pids states are always overwritten to match the PI corner frequencies and other internal attributes of the lockbox (or maybe even better, not using states at all for the pids).

Long term evolution:

  • A CurveManager SoftwareModule replacing pyinstruments would definitely fit very nicely in this modular architecture. In this case, there are a lot of design mistakes that we could avoid with our experience of pyinstruments. Would we keep django for the database model?

Scope needs nicer interface

-setup() should be written along some optimization
-some registers should be hidden / others created to hide various scope bugs
-some registers are not interfaced in the newest version - compare vs verilog / memorymap

SCPClient load delayed

from pyrpl import Pyrpl, gui

r = Pyrpl('fpmtest')

NameError Traceback (most recent call last)
in ()
1 from pyrpl import Pyrpl, gui
----> 2 r = Pyrpl('fpmtest')

w:\pyrpl\pyrpl\pyrpl.pyc in init(self, config, source)
408 self._setloglevel()
409 # initialize RedPitaya object with the configured parameters
--> 410 self.rp = RedPitaya(**self.c.redpitaya._dict)
411 # signal class and optional arguments are passed through this argument
412 self._signalinit = {"inputs": RPSignal, "outputs": RPOutputSignal},
w:\pyrpl\pyrpl\redpitaya.pyc in init(self, hostname, port, user, password, delay, autostart, reloadfpga, reloadserver, filename, dirname, leds_off, frequency_correction, timeout, monitor_server_name, gui, silence_env)
126 # start other stuff
127 if reloadfpga:
--> 128 self.update_fpga()
129 if reloadserver:
130 self.installserver()

w:\pyrpl\pyrpl\redpitaya.pyc in update_fpga(self, filename)
177 self.startscp()
178 sleep(self.delay)
--> 179 self.scp = SCPClient(self.ssh.get_transport())
180 sleep(self.delay)
181 # kill all other servers to prevent reading while fpga is flashed

NameError: global name 'SCPClient' is not defined

Then, typing
r = Pyrpl('fpmtest')
loads correctly...

Treat PWM as additional outputs

Right now, using a PWM requires to set the input of the "PWMx" to some internal signal.

However, this comes with some limitations, for instance, I would like to use the pwm as the output_direct of an iq module (without sacrificing the normal output of the iq), and in this case I am screwed.

Would it be possible/not too expensive in hardware resources to add PWM0/1 to the list of output_directs?

Random noise generator

Original suggestion:
x_{n+1} = (a x_n + b) modulo c

a=16807
b= plus ou moins n'importe quoi
c=2^31

https://en.wikipedia.org/wiki/Lehmer_random_number_generator:

  • In 1988, Park and Miller[2] suggested a Lehmer RNG with particular parameters n = 231 − 1 = 2,147,483,647 (a Mersenne prime M31)
  • Given the dynamic nature of the area, it is difficult for nonspecialists to make decisions about what generator to use. "Give me something I can understand, implement and port... it needn't be state-of-the-art, just make sure it's reasonably good and efficient." Our article and the associated minimal standard generator was an attempt to respond to this request. Five years later, we see no need to alter our response other than to suggest the use of the multiplier a = 48271 in place of 16807.

Therefore:
x_{n+1} = (a x_n + b) modulo c
a=48271
b= 2*_18 * 1234 (or user override)
c=2^31-1
asg_phase_register <= 2_x_n (32 bits) in fpga

asg.scale = 1.0
http://docs.scipy.org/doc/numpy/reference/generated/numpy.random.normal.html
asg.data = np.random.normal(loc=0.0, scale=sigma_in_volt, size=data_length)

IIR filter needs more dynamic range / more robustness

Implement input filter for IIR (lowpass bandwidth = nyquist)

Compute error propagation in IIR module

  • coefficient quantization error
  • data quantization / truncation error
  • (floating point-limited) design error
    -> find reason for dynamic range issue
    Parallel implementatin allows debugging with single biquad for noise analysis, except for coefficient quantization error.

Keep series implementation as an option (would make many things easier):

  • removes floating point problems because analytical separtation is easily possible
  • standard libraries for coefficient design available
  • higher-order possible
  • increases latency by max. 80 ns for typical filters
  • easier to calculate and optimize errors
  • still possible to keep 2 series-IIRs in parallel for lower latency and more flexibility
  • still: needs careful noise analysis

iq module maximally outputs 0.5 V

go through all bitshifts in demodulation / modulation chain.

exclude signal=0x3FFF already in saturation part and gain one bit and possibly some noise performance

Scope gui untriggered/triggered

The user experience when using untriggered mode is not very nice: a number of unnatural behaviour occurs for example when untriggered mode is on and duration goes below the minimally allowed untriggered one. The corresponding code should be read, cleaned and adjusted to make this a bit smoother.

+- buttons in gui dont work so nicely

example: Spectrum analyzer - acbandwidth cannot be tuned with +- buttons because increment is of the order 1e-3, and by the time an important increment has accumulated, the program rounds to the next allowed value, which is always the previous one...

-> how to deal with this?

  1. choose proper increment for each such value
  2. let the program only update the value once the button is released

Any other opinions?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤ī¸ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.