diff --git a/casperfpga b/casperfpga index 658d312..54eab47 160000 --- a/casperfpga +++ b/casperfpga @@ -1 +1 @@ -Subproject commit 658d312e96bfe5ce05699c7290a569e64800da35 +Subproject commit 54eab47207d80ee962a6f3e0def95c19d8ff61c2 diff --git a/docs/_static/img/tut_corr/snap_adc.png b/docs/_static/img/tut_corr/snap_adc.png new file mode 100644 index 0000000..be433e5 Binary files /dev/null and b/docs/_static/img/tut_corr/snap_adc.png differ diff --git a/docs/_static/img/tut_corr/snap_cmac.png b/docs/_static/img/tut_corr/snap_cmac.png new file mode 100644 index 0000000..4e5b982 Binary files /dev/null and b/docs/_static/img/tut_corr/snap_cmac.png differ diff --git a/docs/_static/img/tut_corr/snap_fft_mask.png b/docs/_static/img/tut_corr/snap_fft_mask.png new file mode 100644 index 0000000..803c398 Binary files /dev/null and b/docs/_static/img/tut_corr/snap_fft_mask.png differ diff --git a/docs/_static/img/tut_corr/snap_fir_mask.png b/docs/_static/img/tut_corr/snap_fir_mask.png new file mode 100644 index 0000000..c0f4b6b Binary files /dev/null and b/docs/_static/img/tut_corr/snap_fir_mask.png differ diff --git a/docs/_static/img/tut_corr/snap_leds.png b/docs/_static/img/tut_corr/snap_leds.png new file mode 100644 index 0000000..ba34b65 Binary files /dev/null and b/docs/_static/img/tut_corr/snap_leds.png differ diff --git a/docs/_static/img/tut_corr/snap_pfb.png b/docs/_static/img/tut_corr/snap_pfb.png new file mode 100644 index 0000000..008baf2 Binary files /dev/null and b/docs/_static/img/tut_corr/snap_pfb.png differ diff --git a/docs/_static/img/tut_corr/snap_quantizer.png b/docs/_static/img/tut_corr/snap_quantizer.png new file mode 100644 index 0000000..31a77bf Binary files /dev/null and b/docs/_static/img/tut_corr/snap_quantizer.png differ diff --git a/docs/_static/img/tut_corr/snap_quantizer_top.png b/docs/_static/img/tut_corr/snap_quantizer_top.png new file mode 100644 index 0000000..f04c344 Binary files /dev/null and b/docs/_static/img/tut_corr/snap_quantizer_top.png differ diff --git a/docs/_static/img/tut_corr/snap_rms.png b/docs/_static/img/tut_corr/snap_rms.png new file mode 100644 index 0000000..d20783f Binary files /dev/null and b/docs/_static/img/tut_corr/snap_rms.png differ diff --git a/docs/_static/img/tut_corr/snap_sync.png b/docs/_static/img/tut_corr/snap_sync.png new file mode 100644 index 0000000..4f1c85e Binary files /dev/null and b/docs/_static/img/tut_corr/snap_sync.png differ diff --git a/docs/_static/img/tut_corr/sysgen_snap_platform.png b/docs/_static/img/tut_corr/sysgen_snap_platform.png new file mode 100644 index 0000000..6b1a81f Binary files /dev/null and b/docs/_static/img/tut_corr/sysgen_snap_platform.png differ diff --git a/docs/_static/img/tut_intro/Casper_xps_blockset_default_final.png b/docs/_static/img/tut_intro/Casper_xps_blockset_default_final.png index 0ebf5ee..5bfad7d 100644 Binary files a/docs/_static/img/tut_intro/Casper_xps_blockset_default_final.png and b/docs/_static/img/tut_intro/Casper_xps_blockset_default_final.png differ diff --git a/docs/_static/img/tut_intro/Cnt_ctrl_sw_reg_config_r2.png b/docs/_static/img/tut_intro/Cnt_ctrl_sw_reg_config_r2.png index 3be9232..a803518 100644 Binary files a/docs/_static/img/tut_intro/Cnt_ctrl_sw_reg_config_r2.png and b/docs/_static/img/tut_intro/Cnt_ctrl_sw_reg_config_r2.png differ diff --git a/docs/_static/img/tut_intro/Cnt_val_sw_reg_config_r2.png b/docs/_static/img/tut_intro/Cnt_val_sw_reg_config_r2.png index 589b6e5..12fed61 100644 Binary files a/docs/_static/img/tut_intro/Cnt_val_sw_reg_config_r2.png and b/docs/_static/img/tut_intro/Cnt_val_sw_reg_config_r2.png differ diff --git a/docs/_static/img/tut_intro/Jasper_sysgen_SNAP.png b/docs/_static/img/tut_intro/Jasper_sysgen_SNAP.png new file mode 100644 index 0000000..1fe63de Binary files /dev/null and b/docs/_static/img/tut_intro/Jasper_sysgen_SNAP.png differ diff --git a/docs/_static/img/tut_intro/jasper_sysgen_skarab.png b/docs/_static/img/tut_intro/jasper_sysgen_skarab.png deleted file mode 100644 index 63f4654..0000000 Binary files a/docs/_static/img/tut_intro/jasper_sysgen_skarab.png and /dev/null differ diff --git a/docs/_static/img/tut_intro/snap_tut_intro_hw_platform.png b/docs/_static/img/tut_intro/snap_tut_intro_hw_platform.png new file mode 100644 index 0000000..0dc9792 Binary files /dev/null and b/docs/_static/img/tut_intro/snap_tut_intro_hw_platform.png differ diff --git a/docs/_static/img/tut_spec/adc_2018.png b/docs/_static/img/tut_spec/adc_2018.png new file mode 100644 index 0000000..25357b9 Binary files /dev/null and b/docs/_static/img/tut_spec/adc_2018.png differ diff --git a/docs/_static/img/tut_spec/pfb_fir_real_2018.png b/docs/_static/img/tut_spec/pfb_fir_real_2018.png new file mode 100644 index 0000000..a9b4137 Binary files /dev/null and b/docs/_static/img/tut_spec/pfb_fir_real_2018.png differ diff --git a/docs/_static/img/tut_spec/shared_bram_2012.png b/docs/_static/img/tut_spec/shared_bram_2012.png index 4a3e5a8..87cb98c 100644 Binary files a/docs/_static/img/tut_spec/shared_bram_2012.png and b/docs/_static/img/tut_spec/shared_bram_2012.png differ diff --git a/docs/_static/img/tut_spec/vacc_4.6.png b/docs/_static/img/tut_spec/vacc_4.6.png index 47ba663..4ef9a48 100644 Binary files a/docs/_static/img/tut_spec/vacc_4.6.png and b/docs/_static/img/tut_spec/vacc_4.6.png differ diff --git a/docs/_static/img/tut_ten_gbe/snap_gbe_core_0_debug_params.png b/docs/_static/img/tut_ten_gbe/snap_gbe_core_0_debug_params.png new file mode 100644 index 0000000..679aace Binary files /dev/null and b/docs/_static/img/tut_ten_gbe/snap_gbe_core_0_debug_params.png differ diff --git a/docs/_static/img/tut_ten_gbe/snap_gbe_core_0_params.png b/docs/_static/img/tut_ten_gbe/snap_gbe_core_0_params.png new file mode 100644 index 0000000..42007ac Binary files /dev/null and b/docs/_static/img/tut_ten_gbe/snap_gbe_core_0_params.png differ diff --git a/docs/_static/img/tut_ten_gbe/tut2_rst_mask_params.png b/docs/_static/img/tut_ten_gbe/tut2_rst_mask_params.png index aeaaeae..4180c43 100644 Binary files a/docs/_static/img/tut_ten_gbe/tut2_rst_mask_params.png and b/docs/_static/img/tut_ten_gbe/tut2_rst_mask_params.png differ diff --git a/docs/tutorials/skarab/tut_intro.md b/docs/tutorials/skarab/tut_intro.md index 5048b5d..f2e889c 100644 --- a/docs/tutorials/skarab/tut_intro.md +++ b/docs/tutorials/skarab/tut_intro.md @@ -62,7 +62,7 @@ Set it for 1 bit wide with offset from top bit at zero. As you might guess, this ![](../../_static/img/tut_intro/Slice_params.png) #### Add a GPIO block -From: CASPER XPS library -> gpio. +From: CASPER XPS library -> IO -> gpio. ![casper_xps_select_io.png](../../_static/img/tut_intro/casper_xps_select_io.png) diff --git a/docs/tutorials/snap/tut_corr.md b/docs/tutorials/snap/tut_corr.md index 177d8e3..51fef14 100644 --- a/docs/tutorials/snap/tut_corr.md +++ b/docs/tutorials/snap/tut_corr.md @@ -21,56 +21,37 @@ see this implemented later. The complexity of this calculation scales with the n Dish type receivers are typically dual polarized (horizontal and vertical feeds). Each polarization is fed into separate ADC inputs. When correlating these antennae, we differentiate between full Stokes correlation or a half Stokes method. A full Stokes correlator does cross correlation between the different polarizations (ie for a given two antennas, A and B, it multiplies the horizontal feed from A with the vertical feed from B and vice-versa). A half stokes correlator only correlates like polarizations with each other, thereby halving the compute requirements. ### The Correlator ### -The correlator we will be designing is a 4 input correlator as shown below. It uses 2 inputs from each of two ADCs. It can be thought of as a 2-input full Stokes correlator or as a four input single polarization correlator. - -![](../../_static/img/tut_corr/Roach_with_iadcs_on_bench.jpg) - -## Setup ## -The lab at the workshop is preconfigured with the CASPER libraries, Matlab and Xilinx tools. Start Matlab. +The correlator we will be designing is a 3 input correlator which uses a SNAP board with each ADC operating in maximum speed mode. ## Creating Your Design ## ### Create a new model ### -Having started Matlab, open Simulink (either by typing simulink on the Matlab command line, or by clicking the Simulink icon in the taskbar). Create a new model and add the Xilinx System Generator and XSG core config blocks as before in Tutorial 1. +Having started Matlab, open Simulink (either by typing simulink on the Matlab command line, or by clicking the Simulink icon in the taskbar). Create a new model and add the Xilinx System Generator and SNAP platform blocks as before in Tutorial 1. -### System Generator and XSG Blocks ### -![](../../_static/img/tut_corr/sysgen_xsg.png) +### System Generator and Platform Blocks ### +![](../../_static/img/tut_corr/sysgen_snap_platform.png) By now you should have used these blocks a number of times. Pull the System Generator block into your design from the Xilinx Blockset menu under Basic Elements. The settings can be left on default. -The XSG block can be found under the CASPER XPS System Blockset. Set the Hardware platform to ROACH:sx95t, the Clock Source to adc0_clk and the rest of the configuration as the default. - -Make sure you have an ADC plugged into ZDOK0 to supply the FPGA's clock! +The SNAP platform block can be found under the CASPER XPS System Blockset: Platform subsystem. Set the Clock Source to adc0_clk and the rest of the configuration as the default. ### Sync Generator ### -![](../../_static/img/tut_corr/t4_sync_gen.png) +![](../../_static/img/tut_corr/snap_sync.png) The Sync Generator puts out a sync pulse which is used to synchronize the blocks in the design. See the CASPER memo on sync pulse generation for a detailed explanation. -This sync generator is able to synchronize with an external trigger input. Typically we connect this to a GPS's 1pps output to allow the system to reset on a second boundary after a software arm and thus know precisely the time at which an accumulation was started. To do this you can input the 1pps signal into either ADCs' sync input. -The sync pulse allows data to be tagged with a precise timestamp. It also allows multiple ROACH boards to be synchronized, which is useful if large numbers of antenna signals are being correlated. - -### ADCs ### -![](../../_static/img/tut_corr/t4_adcs_jbo.png) - -Connection of the ADCs is as in tutorial 3 except for the sync outputs. Here we OR all four outputs together to produce a sync pulse sampled at one quarter the rate of the ADC's sample clock. This is the simplest way of dealing with the four sync samples supplied to the FPGA on every clock cycle, but means that our system can only be synchronized to within 3 ADC sample clocks. +This sync generator is able to synchronize with an external trigger input. Typically we connect this to a GPS's 1pps output to allow the system to reset on a second boundary after a software arm. This enables us to know precisely the time at which an accumulation was started. It also allows multiple boards to be synchronized which is vital if we are using a signal which correlates digitizers hosted on separate boards. +To synchronize from an external PPS we can drive the sync generator logic with the SNAP's sync_in GPIO input. Logic is also provided to generate a sync manually via a software input. This allows the design to be used even in the absence of a 1 pps signal. However, in this case, the time the sync pulse occurs depends on the latency of software issuing the sync command and the FPGA signal triggering. This introduces some uncertainty in the timestamps associated with the correlator outputs. -We will not use the 1pps in this tutorial although the design has the facility to do this hardware sync'ing. -Set up the ADCs as follows and change the second ADC board's mask parameter to adc1... +### ADCs ### +![](../../_static/img/tut_corr/snap_adc.png) -![](../../_static/img/tut_corr/t4_adc_set.png) +Connection of the ADCs is as in tutorial 3 except now we are using all three available inputs. Throughout this design, we use CASPER's bus_create and bus_expand blocks to simplify routing and make the design easier to follow. -![](../../_static/img/tut_corr/t4_concat_block.png) - -For the purposes of simulation, it can be useful to put simulation input signals into the ADCs. These blocks are pulse generators in the case of sync inputs and any analogue source for the RF inputs (noise, CW tones etc). - -![](../../_static/img/tut_corr/t4_sin_wave_set.png) -![](../../_static/img/tut_corr/t4_noise_set.png) - ### Control Register ### ![](../../_static/img/tut_corr/t4_ctrl_reg_jbo.png) @@ -84,7 +65,7 @@ The slice block can be found under the Xilinx Blockset → Control Logic. The on After each slice block we put an edge_detect block, this outputs true if a boolean input signal is true this clock and was false last clock. Found under CASPER DSP Blockset → Misc. -Next are the delay blocks. They can be left with their default settings and can be found under Xilinx Blockset → Common. +Next are the delay blocks. They can be left with their default settings and can be found under Xilinx Blockset → Common. The delays used here aren't necessary for the function of the design, but can help meet timing by giving the compiler an extra cycle of latency to use when routing control signals. The Goto and From bocks can be found under Simulink-> Signal Routing. Label them as in the block diagram above. @@ -103,52 +84,51 @@ The Registers (inputs 10 - 33) must be set up with an initial value of 0 and wit The status register on the output of the clip detect is set to processor in with unsigned data type and 0 binary point with a sample period of 1. ### PFBs, FFTs and Quantisers ### -The PFB FIR, FFT and the Quantizer are the heart of this design, there is one set of each for the 4 outputs of the ADCs. However, in order to save resources associated with control logic and PFB and FFT coefficient storage, the four independent filters are combined into a single simulink block. This is configured to process four independent data streams by setting the "number of inputs" parameter on the PFB_FIR and FFT blocks to 4. +The PFB FIR, FFT and the Quantizer are the heart of this design, there is one set of each for the 3 ADC channels. However, in order to save resources associated with control logic and PFB and FFT coefficient storage, the independent filters are combined into a single simulink block. This is configured to process three independent data streams by setting the "number of inputs" parameter on the PFB_FIR and FFT blocks to 3. -![](../../_static/img/tut_corr/t4_pfb_fft_jbo.png) +![](../../_static/img/tut_corr/snap_pfb.png) Configure the PFB_FIR_generic blocks as shown below: -![](../../_static/img/tut_corr/t4_pfb_set_jbo.png) +![](../../_static/img/tut_corr/snap_fir_mask.png) -There is potential to overflow the first FFT stage if the input is periodic or signal levels are high as shifting inside the FFT is only performed after each butterfly stage calculation. For this reason, we recommend casting any inputs up to 18 bits with the binary point at position 17 (thus keeping the range of values -1 to 1), and then ownshifting by 1 bit to place the signal in one less than the most significant bits. +There is potential to overflow the first FFT stage if the input is periodic or signal levels are high as shifting inside the FFT is only performed after each butterfly stage calculation. For this reason, we recommend casting any inputs up to 18 bits with the binary point at position 17 (thus keeping the range of values -1 to 1), and then downshifting by 1 bit to place the signal in one less than the most significant bits. The fft_wideband_real block should be configured as follows: -![](../../_static/img/tut_corr/t4_fft_set_jbo.png) +![](../../_static/img/tut_corr/snap_fft_mask.png) -The Quantizer Subsystem is designed as seen below. The quantizer removes the bit growth that was introduced in the PFB and FFT. We can do this because we do not need the full dynamic range. +The Quantizer Subsystem is designed as seen below. The quantizer cuts the data signals from the FFT output width (18 bits) down to 4 bits. This means that the downstream processing can be implemented with less resources. In particular, less RAM is needed to store the accumulated correlations. +We have to be careful when quantizing signals to make sure that we're not either saturating the quantizer, or suffering from low signal levels. Prior to quantizing we multiply our signals by a runtime programmable set of coefficients, which can be set so as to ensure the quantizer power output levels are optimal. -![](../../_static/img/tut_corr/t4_quant_jbo.png) +![](../../_static/img/tut_corr/snap_quantizer.png) -The top level view of the Quantizer Subsystem is as seen below. +The top level view of the Quantizer Subsystem is as seen below. We repeat this system once for each signal path. -![](../../_static/img/tut_corr/t4_quant_top_lvl.png) +![](../../_static/img/tut_corr/snap_quantizer_top.png) ### LEDs ### -The following sections are more periphery to the design and will only be touched on. By now you should be comfortable putting the blocks together and be able to figure out many of the values and parameters. Also feel free to consult the reference design which sits in the tutorial 4 project directory or ask any questions of the tutorial helpers. +The following sections are more periphery to the design and will only be touched on. By now you should be comfortable putting the blocks together and be able to figure out many of the values and parameters. The complete design is available in the tutorials repository for reference. As a debug and monitoring output we can wire up the LEDs to certain signals. We light an LED with every sync pulse. This is a sort of heartbeat showing that the design is clocking and the FPGA is running. -We light an error LED in case any ADC overflows and another if the system is reset. The fourth LED gives a visual indication of when an accumulation is complete. - -ROACH's LEDs are negative logic, so when the input to the yellow block is high, the LED is off. Since this is the opposite of what you'd normally expect, we invert the logic signals with a NOT gate. +We also use an LED to give a visual indication of when an accumulation is complete. -Since the signals might be too short to light up an LED and for us to actually see it (consider the case where a single ADC sample overflows; 1/800MHz is 1.25 nS – much too short for the human eye to see) we add a negedge delay block which delays the negative edge of a block, thereby extending the positive pulse. A length of 2^23 gives about a 10ms pulse. +Since the signals in our design are very low duty cycle, they won't naturally make LED flashes which are visible. We therefore use a pulse extend module to stretch pulses on these signals for 2^24 FPGA clock cycles, which is about 10 ms. -![](../../_static/img/tut_corr/t4_leds_jbo.png) +![](../../_static/img/tut_corr/snap_leds.png) ### ADC RMS ### These blocks calculate the RMS values of the ADCs' input signals. We subsample the input stream by a factor of four and do a pseudo random selection of the parallel inputs to prevent false reporting of repetitive signals. This subsampled stream is squared and accumulated for 2^16 samples. -![](../../_static/img/tut_corr/t4_adc_rms.png) +![](../../_static/img/tut_corr/snap_rms.png) ### The MAC operation ### The multiply and accumulate is performed in the dir_x (direct-x) blocks, so named because different antenna signal pairs are multiplied directly, in parallel (as opposed to the packetized correlators' X engines which process serially). Two sets are used, one for the even channels and another for the odd channels. Accumulation for each antenna pair takes place in BRAM using the same simple vector accumulator used in tut3. -![](../../_static/img/tut_corr/t4_mac_op_jbo.png) +![](../../_static/img/tut_corr/snap_cmac.png) CONTROL: @@ -161,63 +141,6 @@ New accumulation LED gives a visual indication of data rates and dump times. Accumulation counter provides simple mechanism for checking if a new spectrum output is available. (poll and compare to last value) ## Software ## -The python scripts are located in the tut4 tutorial directory. We first need to run poco_init.py to program the FPGA and configure the design. Then we can run either the auto or the cross correlations plotting scripts (plot_poco_auto.py and plot_poco_cross.py). - -poco_init.py -```python - print('Connecting to server %s on port %i... '%(roach,katcp_port)), - fpga = corr.katcp_wrapper.FpgaClient(roach, katcp_port, - timeout=10,logger=logger) - time.sleep(1) - if fpga.is_connected(): - print 'ok\n' - else: - print 'ERROR connecting to server %s on port %i.\n'% - (roach,katcp_port) - exit_fail() - print '------------------------' - print 'Programming FPGA...', - if not opts.skip: - fpga.progdev(boffile) - print 'done' - else: - print 'Skipped.' - print 'Configuring fft_shift...', - fpga.write_int('fft_shift',(2**32)-1) - print 'done' - print 'Configuring accumulation period...', - fpga.write_int('acc_len',opts.acc_len) - print 'done' - print 'Resetting board, software triggering and resetting error - counters...', - fpga.write_int('ctrl',1<<17) #arm - fpga.write_int('ctrl',1<<18) #software trigger - fpga.write_int('ctrl',0) - fpga.write_int('ctrl',1<<18) #issue a second trigger - print 'done' -``` -In previous tutorials you will probably have seen very similar code to the code above. This initiates the katcp wrapper named fpga which manages the interface between the software and the hardware. fpga.progdev programs the boffile onto the FPGA and fpga.write_int writes to a register. - -poco_adc_amplitudes.py - -This script outputs in the amplitudes (or power) of each signal as well as the bits used. It updates itself ever second or so. - -```bash - ADC amplitudes - -------------- - ADC0 input I: 0.006 (0.51 bits used) - ADC0 input Q: 0.004 (0.19 bits used) - ADC1 input I: 0.005 (0.45 bits used) - ADC1 input Q: 0.004 (0.19 bits used) - ----------------------------------- -``` -poco_plot_auto.py - -This script grabs auto-correlations from the brams and plots them. Since there are 4 inputs, 2 for each ADC there are 4 plots. Some plots will be random if there is no noise source or tone being inputted into ADC. Ie plots 3 and 4. - -![](../../_static/img/tut_corr/t4_plot_auto.png) - -poco_plot_cross.py -This script grabs cross-correlations from the brams and plots them. This plotshows the cross-correlation of AB. - -![](../../_static/img/tut_corr/t4_plot_cross.png) \ No newline at end of file +The python scripts are located in the tut_corr tutorial directory. We first need to run poco_init.py to program the FPGA and configure the design. Then we can run either the auto or the cross correlations plotting scripts (plot_poco_auto.py and plot_poco_cross.py). + +Try running these scripts with the -h option to get a description of optional and required arguments. diff --git a/docs/tutorials/snap/tut_intro.md b/docs/tutorials/snap/tut_intro.md index 3355c2e..9fdb525 100644 --- a/docs/tutorials/snap/tut_intro.md +++ b/docs/tutorials/snap/tut_intro.md @@ -3,30 +3,32 @@ In this tutorial, you will create a simple Simulink design using both standard X ## Creating Your Design ### Create a New Model -Start Matlab via executing the startsg command, as described [here](https://casper.berkeley.edu/wiki/Casper_Caltech_Workshop_2017_Tutorials_Help_Page). This ensures that necessary Xilinx and CASPER libraries are loaded into your by Simulink. When MATLAB starts up, open Simulink by typing simulink on the MATLAB command line. Start a new model, and save it with an appropriate name. **With Simulink, it is very wise to save early, and often**. +Start Matlab via executing the startsg command, as described [here](https://github.com/casper-astro/tutorials_devel/blob/master/workshop_setup.md). This ensures that necessary Xilinx and CASPER libraries are loaded into your by Simulink. When MATLAB starts up, open Simulink by typing simulink on the MATLAB command line. Start a new model, and save it with an appropriate name. **With Simulink, it is very wise to save early, and often**. There are some Matlab limitations you should be aware-of right from the start: -**Do not use spaces in your filenames** or anywhere in the file path as it will break the toolflow. -**Do not use capital letters in your filenames** or anywhere in the file path as it will break the toolflow. -**Beware block paths that exceed 64 characters**. This refers to not only the file path, but also the path to any block within your design. For example, if you save a model file with a name ~/some_really_long_filename.slx, and have a block called in a submodule the longest block path would be: some_really_long_filename_submodule_block. If you use lots of subsystems, this can cause problems. +- **Do not use spaces in your filenames** or anywhere in the file path as it will break the toolflow. +- **Do not use capital letters in your filenames** or anywhere in the file path as it will break the toolflow. +- **Beware block paths that exceed 64 characters**. This refers to not only the file path, but also the path to any block within your design. + - For example, if you save a model file with a name ~/some_really_long_filename.slx, and have a block called in a submodule the longest block path would be: some_really_long_filename_submodule_block. + - If you use lots of subsystems, this can cause problems. ### Library organization There are three libraries which you will use when you design firmware in Simulink. -1. The *CASPER XPS Library* contains "Yellow Blocks" -- these are blocks which encapsulate interfaces to hardware (ADCs, Memory chips, CPUs, Ethernet ports, etc.) -2. The *CASPER DSP Library* contains (mostly green) blocks which inplement DSP functions, like filters, FFTs, etc. -3. The *Xilinx Library* contains blue blocks which provide low-level functionality such as multiplexing, delaying, adding, etc. The Xilinx library also contains the super-special System Generator block, which contains information about the type of FPGA you are targeting. +1. The **CASPER XPS Library** contains "Yellow Blocks" -- these are blocks which encapsulate interfaces to hardware (ADCs, Memory chips, CPUs, Ethernet ports, etc.) +2. The **CASPER DSP Library** contains (mostly green) blocks which implement DSP functions such as filters, FFTs, etc. +3. The **Xilinx Library** contains blue blocks which provide low-level functionality such as multiplexing, delaying, adding, etc. The Xilinx library also contains the super-special System Generator block, which contains information about the type of FPGA you are targeting. ### Add Xilinx System Generator and XSG core config blocks Add a System generator block from the Xilinx library by locating the Xilinx Blockset library's Basic Elements subsection and dragging a System Generator token onto your new file. -![](../../_static/img/tut_intro/sysgen_select.png) +![xilinx_select_sysgen.png](../../_static/img/tut_intro/xilinx_select_sysgen.png) Do not configure it directly, but rather add a platform block representing the system you care compiling for. These can be found in the CASPER XPS System Blockset library. For SNAP (and later) platforms, you need a block which matches the platform name, which can be found in the library under "platforms", as shown below. -![](../../_static/img/tut_intro/Casper_xps_blockset_default_final.png) +![casper_xps_select_platform.png](../../_static/img/tut_intro/casper_xps_select_platform.png) -![](../../_static/img/tut_intro/Casper_xps_blockset_hw_plat.png) +![casper_xps_select_platform_skarab.png](../../_static/img/tut_intro/snap_tut_intro_hw_platform.png) Double click on the platform block that you just added. The Hardware Platform parameter should match the platform you are compiling for. Once you have selected a board, you need to choose where it will get its clock. In designs including ADCs you probably want the FPGA clock to be derived from the sampling clock, but for this simple design (which doesn't include an ADC) you should use the platform's on-board clock. To do this, set the User IP Clock Source to sys_clk. The sys_clk rate is 100 MHz, so you should set this for *User IP Clock Rate* in the block. @@ -42,16 +44,16 @@ To demonstrate the basic use of hardware interfaces, we will make an LED flash. #### Add a counter Add a counter to your design by navigating to Xilinx Blockset -> Basic Elements -> Counter and dragging it onto your model. -![](../../_static/img/tut_intro/counter_select.png) +![xilinx_select_counter.png](../../_static/img/tut_intro/xilinx_select_counter.png) Double-click it and set it for free running, 27 bits, unsigned. This means it will count from 0 to 2^27 - 1, and will then wrap back to zero and continue. -![](../../_static/img/tut_intro/Counter_params.png) +![xilinx_params_counter_led](../../_static/img/tut_intro/xilinx_params_counter_led.png) #### Add a slice block to select out the msb We now need to select the [most significant bit](http://en.wikipedia.org/wiki/Most_significant_bit) (msb) of the counter. We do this using a slice block, which Xilinx provides. Xilinx Blockset -> Basic Elements -> Slice. -![](../../_static/img/tut_intro/Slice_select.png) +![Slice_select.png](../../_static/img/tut_intro/Slice_select.png) Double-click on the newly added slice block. There are multiple ways to select which bit(s) you want. In this case, it is simplest to index from the upper end and select the first bit. If you wanted the [least significant bit](http://en.wikipedia.org/wiki/Least_significant_bit) (lsb), you can also index from that position. You can either select the width and offset, or two bit locations. @@ -60,13 +62,15 @@ Set it for 1 bit wide with offset from top bit at zero. As you might guess, this ![](../../_static/img/tut_intro/Slice_params.png) #### Add a GPIO block -From: CASPER XPS library -> gpio. +From: CASPER XPS library -> IO -> gpio. -![](../../_static/img/tut_intro/Gpio_select.png) +![casper_xps_select_io.png](../../_static/img/tut_intro/casper_xps_select_io.png) + +![casper_xps_select_io_gpio.png](../../_static/img/tut_intro/casper_xps_select_io_gpio.png) In order to send the 1 bit signal you have sliced off to an LED, you need to connect it to the right FPGA output pin. To do this you can use a GPIO (general-purpose input/output) block from the XPS library, this allows you to route a signal from Simulink to a selection of FPGA pins, which are addressed with user-friendly names. Set it to use SNAP's LED bank as output. Once you've chosen the LED bank, you need to pick *which* LED you want to output to. Set the GPIO bit index to 0 (the first LED) and the data type to Boolean with bitwidth 1. This means your simulink input is a 1 bit Boolean, and the output is LED0. -![](../../_static/img/tut_intro/Gpio_params_r2.png) +![casper_xps_params_io_gpio.png](../../_static/img/tut_intro/casper_xps_params_io_gpio.png) #### Add a terminator To prevent warnings (from MATLAB & Simulink) about unconnected outputs, terminate all unused outputs using a *Terminator*: @@ -96,7 +100,7 @@ By the end of this section, you will create a system that looks like this: #### Add the software registers ### We need two software registers. One to control the counter, and a second one to read its current value. From the CASPER XPS System Blockset library, drag two Software Registers onto your design. -![SW_reg_select2.png](../../_static/img/tut_intro/SW_reg_select2.png) +![casper_xps_select_memory_swreg.png](../../_static/img/tut_intro/casper_xps_select_memory_swreg.png) Set the I/O direction to *From Processor* on the first one (counter control) to enable a value to be set from software and sent *to* your FPGA design. Set it to *To Processor* on the second one (counter value) to enable a value to be sent *from* the FPGA to software. Set both registers to a bitwidth of 32 bits. @@ -140,11 +144,11 @@ The enable and reset ports of the counter require boolean values (which Simulink Slice for enable: -![](../../_static/img/tut_intro/Slice_en.png) +![casper_xps_params_slice_enable.png](../../_static/img/tut_intro/casper_xps_params_slice_enable.png) Slice for reset: -![](../../_static/img/tut_intro/Slice_rst.png) +![casper_xps_params_slice_reset.png](../../_static/img/tut_intro/casper_xps_params_slice_reset.png) #### Connect it all up Now we need to connect all these blocks together. To neaten things up, consider resizing the slice blocks and hiding their names. Their function is clear enough from their icon without needing to see their names. @@ -156,7 +160,7 @@ Do so by right-clicking and unchecking Format → Show Block Name. You could do ### Adder To demonstrate some simple mathematical operations, we will create an adder. It will add two numbers on demand and output the result to another software register. Almost all astronomy DSP is done using fixed-point (integer) notation, and this adder will be no different. -We will calculate a+b#sum_a_b. +We will calculate a+b = sum_a_b. ![](../../_static/img/tut_intro/Add_sub_circuit.png) @@ -168,7 +172,7 @@ Either copy your existing software register blocks (copy-paste or holding ctrl w #### Add the adder block Locate the adder/subtractor block, Xilinx Blockset -> Math -> AddSub and drag one onto your design. This block can optionally perform addition or subtraction. Let's leave it set at it's default, for addition. -![](../../_static/img/tut_intro/Add_sub_basic.png) +![](../../_static/img/tut_intro/xilinx_params_addsub_basic.png) The output register is 32 bits. If we add two 32 bit numbers, we will have 33 bits. @@ -183,7 +187,7 @@ be a 32 bit saturating adder. On the second tab, set it for user-defined precisi Also, under overflow, set it to saturate. Now if we add two very large numbers, it will simply return 2^32 -1. -![](../../_static/img/tut_intro/Add_sub_output.png) +![](../../_static/img/tut_intro/xilinx_params_addsub_output.png) #### Add the scope and simulation inputs Either copy your existing scope and simulation constants (copy-paste or ctrl-drag) or place a new one from the library as before. Set the values of the simulation inputs to anything you like. @@ -202,11 +206,11 @@ You can watch the simulation progress in the status bar in the bottom right. It You can double-click on the scopes to see what the signals look like on those lines. For example, the one connected to the counter should look like this: -![](../../_static/img/tut_intro/Counter_sim.png) +![](../../_static/img/tut_intro/scope_counter.png) The one connected to your adder should return a constant, equal to the sum of the two numbers you entered. You might have to press the Autoscale button to scale the scope appropriately. -![](../../_static/img/tut_intro/Adder_sim.png) +![](../../_static/img/tut_intro/scope_sum_with_model.png) Once you have verified that that design functions as you'd like, you're ready to compile for the FPGA... @@ -219,7 +223,7 @@ In order to compile this to an FPGA bitstream, execute the following command in ``` When a GUI pops up, click "Compile!". This will run the complete build process, which consists of two stages. The first involving Xilinx's System Generator, which compiles any Xilinx blocks in your Simulink design to a circuit which can be implemented on your FPGA. While System Generator is running, you should see the following window pop up: -![](../../_static/img/tut_intro/Jasper_sysgen_SKARAB.png) +![](../../_static/img/tut_intro/Jasper_sysgen_SNAP.png) After this, the second stage involves synthesis of your design through Vivado, which goes about turning your design into a physical implementation and figuring out where to put the resulting components and signals on your FPGA. Finally the toolflow will create the final output fpg file that you will use to program your FPGA. This file contains the bitstream (the FPGA configuration information) as well as meta-data describing what registers and other yellow blocks are in your design. This file will be created in the 'outputs' folder in the working directory of your Simulink model. **Note: Compile time is approximately 15-20 minutes**. @@ -232,7 +236,7 @@ Once you are familiar with the CASPER toolflow, you might find you want to run t ``` After this is completed, the last message printed will tell you how to finish the compile. It will look something like: ```bash - 'python /path_to/mlib_devel/jasper_library/exec_flow.py -m /home/user/path_to/snap/tut_intro/snap_tut_intro.slx --middleware --backend --software' +$ python /path_to/mlib_devel/jasper_library/exec_flow.py -m /home/user/path_to/snap/tut_intro/snap_tut_intro.slx --middleware --backend --software ``` You can run this command in a separate terminal, after sourcing appropriate environment variables. Not recommended for beginners. @@ -253,21 +257,25 @@ SSH into the server that the SNAP board is connected to and navigate to the fold Start interactive python by running: ```bash -ipython +$ ipython ``` + Now import the fpga control library. This will automatically pull-in the KATCP library and any other required communications libraries. ```python import casperfpga ``` + To connect to the board we create a CasperFpga instance; let's call it fpga. The CasperFpga constructor requires just one argument: the IP hostname or address of your FPGA board. ```python -fpga = casperfpga.CasperFpga('') +fpga = casperfpga.CasperFpga('SNAP hostname or ip_address') ``` + The first thing we do is program the FPGA with the .fpg file which your compile generated. ```python -fpga.upload_to_ram_and_program('') +fpga.upload_to_ram_and_program('your_fpgfile.fpg') ``` + Should the execution of this command return true, you can safely assume the FPGA is now configured with your design. You should see the LED on your board flashing. Go check! All the available/configured registers can be displayed using: ```python fpga.listdev() @@ -278,13 +286,16 @@ fpga.write_int('a',10) fpga.write_int('b',20) fpga.read_int('sum_a_b') ``` + With any luck, the sum returned by the FPGA should be correct. You can also try writing to the counter control registers in your design. You should find that with appropriate manipulation of the control register, you can make the counter start, stop, and return to zero. + ```python fpga.write_int('counter_ctrl',10') fpga.read_uint('counter_value') ``` + ## Conclusion This concludes the first CASPER Tutorial. You have learned how to construct a simple Simulink design, program an FPGA board and interact with it with Python using [casperfpga](https://github.com/casper-astro/casperfpga). Congratulations! diff --git a/docs/tutorials/snap/tut_spec.md b/docs/tutorials/snap/tut_spec.md index 7f2540c..e1b69a2 100644 --- a/docs/tutorials/snap/tut_spec.md +++ b/docs/tutorials/snap/tut_spec.md @@ -8,7 +8,7 @@ When designing a spectrometer for astronomical applications, it's important to c ## Setup ## This tutorial comes with a completed model file, -a compiled bitstream, ready for execution on ROACH, as well as a Python script to configure the ROACH and make plots. [Here](https://github.com/casper-astro/tutorials_devel/tree/master/ise/roach2/tut_spec) +a compiled bitstream, ready for execution on SNAP, as well as a Python script to configure the SNAP and make plots. [Here](https://github.com/casper-astro/tutorials_devel/tree/master/vivado/snap/tut_spec) ## Spectrometer Basics ## @@ -42,7 +42,7 @@ The best way to understand fully is to follow the arrows, go through what each b - The all important Xilinx token is placed to allow System Generator to be called to compile the design. -- In the MSSGE block, the hardware type is set to “ROACH:sx95t” and clock rate is specified as 200MHz. +- In the MSSGE block, the hardware type is set to “SNAP:xc7k160t” and clock rate is specified as 200MHz. - The input signal is digitised by the ADC, resulting in four parallel time samples of 8 bits each clock cycle. The ADC runs at 800MHz, which gives a 400MHz nyquist sampled spectrum. The output range is a signed number in the range -1 to +1 (ie 7 bits after the decimal point). This is expressed as fix_8_7. @@ -50,11 +50,9 @@ The best way to understand fully is to follow the arrows, go through what each b - You may notice Xilinx delay blocks dotted all over the design. It's common practice to add these into the design as it makes it easier to fit the design into the logic of the FPGA. It consumes more resources, but eases signal timing-induced placement restrictions. -- The real and imaginary (sine and cosine value) components of the FFT are plugged into power blocks, to convert from complex values to real power values by squaring. They are also scaled by a gain factor before being quantised... +- The real and imaginary (sine and cosine value) components of the FFT are plugged into power blocks, to convert from complex values to real power values by squaring. -- These power values are then requantized by the quant0 block, from 36.34 bits to 6.5 bits, in preparation for accumulation. This is done to limit bit growth. - -- The requantized signals then enter the vector accumulators, vacc0 and vacc1, which are simple_bram_vacc 32 bit vector accumulators. Accumulation length is controlled by the acc_cntrl block. +- These power values enter the vector accumulators, vacc0 and vacc1, which are simple_bram_vacc 64 bit vector accumulators. Accumulation length is controlled by the acc_cntrl block. - The accumulated signal is then fed into software registers, odd and even. @@ -63,7 +61,7 @@ Without further ado, open up the model file and start clicking on things, referr ### [adc](https://casper.berkeley.edu/wiki/Adc) ### -![](../../_static/img/tut_spec/adc_4.1.png) +![](../../_static/img/tut_spec/adc_2018.png) The first step to creating a frequency spectrum is to digitize the signal. This is done with an ADC – an Analogue to Digital Converter. In Simulink, the ADC daughter board is represented by a yellow block. Work through the “iADC tutorial” if you're not familiar with the iADC card. @@ -71,7 +69,7 @@ The ADC block converts analog inputs to digital outputs. Every clock cycle, the ADCs often internally bias themselves to halfway between 0 and -1. This means that you'd typically see the output of an ADC toggling between zero and -1 when there's no input. It also means that unless otherwise calibrated, an ADC will have a negative DC offset. -The ADC has to be clocked to four times that of the FPGA clock. In this design the ADC is clocked to 800MHz, so the ROACH will be clocked to 200MHz . This gives us a bandwidth of 400MHz, as Nyquist sampling requires two samples (or more) each second. +The ADC has to be clocked to four times that of the FPGA clock. In this design the ADC is clocked to 800MHz, so the SNAP will be clocked to 200MHz . This gives us a bandwidth of 400MHz, as Nyquist sampling requires two samples (or more) each second. **INPUTS** @@ -85,9 +83,9 @@ The ADC has to be clocked to four times that of the FPGA clock. In this design t The ADC outputs two main signals: i and q, which correspond to the coaxial inputs of the ADC board. In this tutorial, we'll only be using input i. As the ADC runs at 4x the FPGA rate, there are four parallel time sampled outputs: i0, i1, i2 and i3. As mentioned before, these outputs are 8.7 bit. -### [pfb_fir_real](https://casper.berkeley.edu/wiki/Pfb_fir_real) ### +### [pfb_fir_real](https://casper-toolflow.readthedocs.io/en/latest/src/blockdocs/Pfb_fir_real.html) ### -![](../../_static/img/tut_spec/pfb_fir_real_2012.png) +![](../../_static/img/tut_spec/pfb_fir_real_2018.png) There are two main blocks required for a polyphase filter bank. The first is the pfb_fir_real block, which divides the signal into parallel 'taps' then applies finite impulse response filters (FIR). The output of this block is still a time-domain signal. When combined with the FFT_wideband_real block, this constitutes a polyphase filterbank. @@ -111,7 +109,8 @@ As the ADC has four parallel time sampled outputs: i0, i1, i2 and i3, we need fo | Number of Simultaneous Inputs (2?) | The number of parallel time samples which are presented to the FFT core each clock. The number of output ports are set to this same value. We have four inputs from the ADC, so set this to 2. | | Make biplex | 0 (not making it biplex) is default. Double up the inputs to match with a biplex FFT. | | Input bitwidth. | The number of bits in each real and imaginary sample input to the PFB. The ADC outputs 8.7 bit data, so the input bitwidth should be set to 8 in our design. | -| Output bitwidth | The number of bits in each real and imaginary sample output from the PFB. This should match the bit width in the FFT that follows. 18 bits is recommended for the ROACH (18x25 multipliers) and iBOB/BEE2 (18x18 multipliers). | +| Output bitwidth | The number of bits in each real and imaginary sample output from the PFB. This should match the bit width in the FFT that follows. 18 bits is recommended for the SNAP, whose multiplers are natively 18x25 bits wide. + | Coefficient bitwidth | The number of bits in each coefficient. This is usually chosen to be less than or equal to the input bit width. | | Use dist mem for coeffients | Store the FIR coefficients in distributed memory (if = 1). Otherwise, BRAMs are used to hold the coefficients. 0 (not using distributed memory) is default | | Add/Mult/BRAM/Convert Latency | These values set the number of clock cycles taken by various processes in the filter. There's normally no reason to change this unless you're having troubles fitting the design into the fabric. | @@ -122,7 +121,7 @@ As the ADC has four parallel time sampled outputs: i0, i1, i2 and i3, we need fo | Adder implementation | Adders not folded into DSPs can be implemented either using fabric resources (i.e. registers and LUTs in slices) or using DSP cores. Here you get to choose which is used. Choosing a behavioural implementation will allow the compiler to choose whichever implementation it thinks is best. | | Share coefficients between polarisations | Where the pfb block is simultaneously processing more than one polarization, you can save RAM by using the same set of coefficients for each stream. This may, however, make the timing performance of your design worse. | -### [fft_wideband_real](https://casper.berkeley.edu/wiki/Fft_wideband_real) ### +### [fft_wideband_real](https://casper-toolflow.readthedocs.io/en/latest/src/blockdocs/Fft_wideband_real.html) ### ![](../../_static/img/tut_spec/Fft_wideband_real_block_and_parameters.png) @@ -135,7 +134,7 @@ Parts of the documentation below are taken from the [[Block_Documentation | bloc | --- | --- | | shift | Like many of the blocks, the FFT needs a heartbeat to keep it sync'd | | in0-3 | Sets the shifting schedule through the FFT. Bit 0 specifies the behavior of stage 0, bit 1 of stage 1, and so on. If a stage is set to shift (with bit = 1), then every sample is divided by 2 at the output of that stage. In this design, we've set Shift to 2^(13 − 1) − 1, which will shift the data by 1 on every stage to prevent overflows. | -| out0-1 | This real FFT produces two simultaneous outputs. Because it's a real FFT, the spectrum's left and right halves are mirror images and so we don't bother to output the imaginary half (negative channel indices). Thus, for a 1024-point FFT, you get 512 useful channels. That's why there are half the number of parallel outputs (two complex output paths to four real input paths). Each of these parallel FFT outputs will produce sequential channels on every clock cycle. So, on the first clock cycle (after a sync pulse, which denotes the start), you'll get frequency channel zero and frequency channel one. Each of those are complex numbers. Then, on the second clock cycle, you'll get frequency channels 2 and 3. These are followed by 4 and 5 etc etc. So we chose to label these output paths "even" and "odd", to differentiate the path outputting channels 0,2,4,6,8...N-1 from the channel doing 1,3,5,7...N. As you can see, in order to recreate the full spectrum, we need to interleave these paths to produce 0,1,2,3,4,5...N. Following the lines you'll see that these two inputs end up in an “odd” and “even” shared BRAMs. These are then interleaved in the tut3.py script to form a complete spectrum. | +| out0-1 | This real FFT produces two simultaneous outputs. Because it's a real FFT, the spectrum's left and right halves are mirror images and so we don't bother to output the imaginary half (negative channel indices). Thus, for a 1024-point FFT, you get 512 useful channels. That's why there are half the number of parallel outputs (two complex output paths to four real input paths). Each of these parallel FFT outputs will produce sequential channels on every clock cycle. So, on the first clock cycle (after a sync pulse, which denotes the start), you'll get frequency channel zero and frequency channel one. Each of those are complex numbers. Then, on the second clock cycle, you'll get frequency channels 2 and 3. These are followed by 4 and 5 etc etc. So we chose to label these output paths "even" and "odd", to differentiate the path outputting channels 0,2,4,6,8...N-1 from the channel doing 1,3,5,7...N. As you can see, in order to recreate the full spectrum, we need to interleave these paths to produce 0,1,2,3,4,5...N. Following the lines you'll see that these two inputs end up in an “odd” and “even” shared BRAMs. These are then interleaved in the snap_tut_spec.py script to form a complete spectrum. | **PARAMETERS** @@ -153,7 +152,7 @@ Parts of the documentation below are taken from the [[Block_Documentation | bloc | Convert Latency | Latency through blocks used to reduce bit widths after twiddle and butterfly stages. Set this to 1. | | Input Latency | Here you can register your input data streams in case you run into timing issues. Leave this set to 0. | | Latency between biplexes and fft_direct | Here you can add optional register stages between the two major processing blocks in the FFT. These can help a failing design meet timing. For this tutorial, you should be able to compile the design with this parameter set to 0. | -| Architecture | Set to Virtex5, the architecture of the FPGA on the ROACH. This changes some of the internal logic to better optimise for the DSP slices. If you were using an older iBOB board, you would need to set this to Virtex2Pro. | +| Architecture | Set to Virtex5, the architecture of the FPGA on the SNAP. This changes some of the internal logic to better optimise for the DSP slices. If you were using an older iBOB board, you would need to set this to Virtex2Pro. | | Use less | This affects the implementation of complex multiplication in the FFT, so that they either use fewer multipliers or less logic/adders. For the complex multipliers in the FFT, you can use 4 multipliers and 2 adders, or 3 multipliers and a bunch or adders. So you can trade-off DSP slices for logic or vice-versa. Set this to Multipliers. | | Number of bits above which to store stage's coefficients in BRAM | Determines the threshold at which the twiddle coefficients in a stage are stored in BRAM. Below this threshold distributed RAM is used. By changing this, you can bias your design to use more BRAM or more logic. We're going to set this to 8. | | Number of bits above which to store stage's delays in BRAM | Determines the threshold at which the twiddle coefficients in a stage are stored in BRAM. Below this threshold distributed RAM is used. Set this to 9. | @@ -161,12 +160,12 @@ Parts of the documentation below are taken from the [[Block_Documentation | bloc | Hardcode shift schedule | If you wish to save logic, at the expense of being able to dynamically specify your shifting regime using the block's "shift" input, you can check this box. Leave it unchecked for this tutorial. | | Use DSP48's for adders | The butterfly operation at each stage consists of two adders and two subtracters that can be implemented using DSP48 units instead of logic. Leave this unchecked. | -### [power](https://casper.berkeley.edu/wiki/Power) ### +### [power](https://casper-toolflow.readthedocs.io/en/latest/src/blockdocs/Power.html) ### ![](../../_static/img/tut_spec/power_4.4.png) The power block computes the power of a complex number. The power block typically has a latency of 5 and will compute the power of its input by taking the sum of the squares of its real and imaginary components. The power block is written by Aaron Parsons and online documentation is by Ben Blackman. -In our design, there are two power blocks, which compute the power of the odd and even outputs of the FFT. The output of the block is 36.34 bits; the next stage of the design re-quantizes this down to a lower bitrate. +In our design, there are two power blocks, which compute the power of the odd and even outputs of the FFT. The output of the block is 36.34 bits. **INPUTS/OUTPUTS** @@ -181,39 +180,21 @@ In our design, there are two power blocks, which compute the power of the odd an |-----------|----------|----------------------------------| | Bit Width | BitWidth | The number of bits in its input. | -### quant ### - -![](../../_static/img/tut_spec/quant_4.5.png) - -The quant0 was written by Jason Manley for this tutorial and is not part of the CASPER blockset. The block re-quantizes from 36.34 bits to 6.5 unsigned bits, in preparation for accumulation by the 32 bit bram_vacc block. This block also adds gain control, via a software register. The tut3.py script sets this gain control. You would not need to re-quantize if you used a larger vacc block, such as the 64bit one, but it's illustrative to see a simple example of re-quantization, so it's in the design anyway. -Note that the sync_out port is connected to a block, acc_cntrl, which provides accumulation control. - -**INPUTS/OUTPUTS** - -| Port | Description | -|---------|---------------------------------------------------------------------------------------------------------------------------------------------------------| -| Sync | Input/output for the sync heartbeat pulse. | -| din0-1 | Data inputs – odd is connected to din0 and even is connected to din1. In our design, data in is 36.34 bits. | -| dout0-1 | Data outputs. In this design, the quant0 block requantizes from the 36.34 input to 6.5 bits, so the output on both of these ports is 6.5 unsigned bits. | - -**PARAMETERS** - -None. - ### simple_bram_vacc ### ![](../../_static/img/tut_spec/vacc_4.6.png) -The simple_bram_vacc block is used in this design for vector accumulation. Vector growth is approximately 28 bits each second, so if you wanted a really long accumulation (say a few hours), you'd have to use a block such as the qdr_vacc or dram_vacc. As the name suggests, the simple_bram_vacc is simpler so it is fine for this demo spectrometer. -The FFT block outputs 1024 cosine values (odd) and 1024 sine values, making 2048 values in total. We have two of these bram vacc's in the design, one for the odd and one for the even frequency channels. The vector length is thus set to 1024 on both. +The simple_bram_vacc block is used in this design for vector accumulation. Vector growth is approximately 18 bits each second, since we are accumulating about 2^18 spectra every second. We configure the vector accumulator to output values which are 64 bits wide - since our inputs are only 36 bits wide we can accumulate 2^28 spectra (several minutes of data) before having to worry about possible overflows. +The FFT block 2048 independent frequency channels, split over two outputs. We need a vector accumulator for each of these odd and even channel streams. The vector length is thus set to 1024 on both. **PARAMETERS** | Parameter | Description | |-----------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | Vector length | The length of the input/output vector. The FFT block produces two streams of 1024 length (odd and even values), so we set this to 1024. | -| no. output bits | As there is bit growth due to accumulation, we need to set this higher than the input bits. The input is 6.5 from the quant0 block, we have set this to 32 bits. Note: We could set this to 64 bits and skip the quant block. | -| Binary point (output) | Since we are accumulating 6.5 values there should be 5 bits below the binary point of the output, so set this to 5. | +| Output type | We are accumulating powers, which can only be positive, so this should be set to "Unsigned" +| no. output bits | As there is bit growth due to accumulation, we need to set this higher than the input bits. The input is 36.35 from the power block so we have set this to 64 bits. | +| Binary point (output) | Since we are accumulating 36.35 values there should continue to be 35 bits below the binary point of the output, so set this to 35.| **INPUTS/OUTPUTS** @@ -227,17 +208,19 @@ The FFT block outputs 1024 cosine values (odd) and 1024 sine values, making 2048 ![](../../_static/img/tut_spec/shared_bram_2012.png) -The final blocks, odd and even, are shared BRAMs, which we will read out the values of using the tut3.py script. +The final blocks, odd and even, are shared BRAMs, from which we will read out the values using the [snap_tut_spec.py](https://github.com/casper-astro/tutorials_devel/blob/master/vivado/snap/tut_spec/snap_tut_spec.py) script. **PARAMETERS** | Parameter | Description | |-------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | Output data type | Unsigned | -| Address width | 2^(Address width) is the number of 32 bit words of the implemented BRAM. There is no theoretical maximum for the Virtex 5, but there will be significant timing issues at bitwidths of 13. QDR or DRAM can be used for larger address spaces. Set this value to 11 for our design. | -| Data Width | The Shared BRAM may have a data input/output width of either 8,16,32,64 or 128 bits. Since the vector accumulator feeds the shared bram data port with 32 bit wide values, this should be set to 32 for this tutorial. | -| Data binary point | The binary point should be set to zero. The data going to the processor will be converted to a value with this binary point and the output data type. | -| Initial values | This is a test vector for simulation only. We can leave it as is. | +| Address width | 2^(Address width) is the number of 64 bit words of the implemented BRAM. There is no theoretical maximum for the SNAP, but there will be significant timing issues at bitwidths of 13. Off-chip RAM can be used for larger address spaces on some CASPER boards. Set this value to 10 for our design, since each vector accumulator outputs 2^10 values | +| Data Width | The Shared BRAM may have a data input/output width of either 8,16,32,64 or 128 bits. Since the vector accumulator feeds the shared bram data port with 64 bit wide values, this should be set to 64 for this tutorial. | +| Data binary point | The position of the binary point should match the input data type. We have reinterpreted our data as having a binary point of 0, so this should be 0. | +| Register Primitive Output | Selecting this option adds a cycle of latency to the RAM used by this block, increasing it's timing performance. This should be turned on. | +| Register Core Output | Selecting this option adds a cycle of latency to the RAM used by this block, increasing it's timing performance. This should be turned on. | +| Initial values | This is a test vector for simulation only. We can set it to any 1024-element vactor. | | Sample rate | Set this to 1. | @@ -250,26 +233,26 @@ The final blocks, odd and even, are shared BRAMs, which we will read out the val | we | Write enable port | | data_out | Writing the data to a register. This is simply terminated in the design, as the data has finally reached its final form and destination. | -### [Software Registers](https://casper.berkeley.edu/wiki/Software_register) ### +### [Software Registers](https://casper-toolflow.readthedocs.io/en/latest/src/blockdocs/Software_register.html) ### -There are a few [control registers](https://casper.berkeley.edu/wiki/Software_register), led blinkers, and [snap](https://casper.berkeley.edu/wiki/Snap) block dotted around the design too: +There are a few [control registers](https://casper-toolflow.readthedocs.io/en/latest/src/blockdocs/Software_register.html), led blinkers, and [snapshot](https://casper-toolflow.readthedocs.io/en/latest/src/blockdocs/Snapshot.html) blocks dotted around the design too: - **cnt_rst**: Counter reset control. Pulse this high to reset all counters back to zero. -- **acc_len**: Sets the accumulation length. Have a look in tut3.py for usage. +- **acc_len**: Sets the accumulation length. Have a look in snap_tut_spec.py for usage. - **sync_cnt**: Sync pulse counter. Counts the number of sync pulses issued. Can be used to figure out board uptime and confirm that your design is being clocked correctly. - **acc_cnt**: Accumulation counter. Keeps track of how many accumulations have been done. -- **led0_sync**: Back on topic: the led0_sync light flashes each time a sync pulse is generated. It lets you know your ROACH is alive. +- **led0_sync**: Back on topic: the led0_sync light flashes each time a sync pulse is generated. It lets you know your SNAP is alive. - **led1_new_acc**: This lights up led1 each time a new accumulation is triggered. - **led2_acc_clip**: This lights up led2 whenever clipping is detected. -There are also some [snap](https://casper.berkeley.edu/wiki/Snap) blocks, which capture data from the FPGA fabric and makes it accessible to the Power PC. This tutorial doesn't go into these blocks (in its current revision, at least), but if you have the inclination, have a look at their [documentation](https://casper.berkeley.edu/wiki/Snap). +There are also some [snapshot](https://casper-toolflow.readthedocs.io/en/latest/src/blockdocs/Snapshot.html) blocks, which capture data from the FPGA fabric and makes it accessible to the Power PC. This tutorial doesn't go into these blocks (in its current revision, at least), but if you have the inclination, have a look at their [documentation](https://casper-toolflow.readthedocs.io/en/latest/src/blockdocs/Snapshot.html). In this design, the snap blocks are placed such that they can give useful debugging information. You can probe these through [KATCP](https://casper.berkeley.edu/wiki/KATCP), as done in [Tutorial 1](tut_intro.html), if interested. If you've made it to here, congratulations, go and get yourself a cup of tea and a biscuit, then come back for part two, which explains the second part of the tutorial – actually getting the spectrometer running, and having a look at some spectra. @@ -277,76 +260,90 @@ If you've made it to here, congratulations, go and get yourself a cup of tea and ### Hardware Configuration ### -The tutorial comes with a pre-compiled bof file, which is generated from the model you just went through (tut3.bof) -Copy this over to you ROACH boffiles directory, chmod it to a+x as in the other tutorials, then load up your ROACH. You don't need to telnet in to the ROACH; all communication and configuration will be done by the python control script called tut3.py. - -Next, you need to set up your ROACH. Switch it on, making sure that: +The tutorial comes with a pre-compiled fpg file, which is generated from the model you just went through. +Copy this over to you SNAP fpg directory, then load it onto your SNAP. All communication and configuration will be done by the python control script called snap_tut_spec.py. -• You have your ADC in ZDOK0, which is the one nearest to the power supply. +Next, you need to set up your SNAP. Switch it on, making sure that: -• You have your clock source connected to clk_i on the ADC, which is the second on the right. It should be generating an 800MHz sine wave with 0dBm power. +* You have your clock source connected to the ADC (3rd SMA input from left). It should be generating an 80 0MHz sine wave with 0 dBm power. -### The tut3.py spectrometer script ### +### The snap_tut_spec.py spectrometer script ### -Once you've got that done, it's time to run the script. First, check that you've connected the ADC to ZDOK0, and that the clock source is connected to clk_i of the ADC. -Now, if you're in linux, browse to where the tut3.py file is in a terminal and at the prompt type +Once you've got that done, it's time to run the script. First, check that the clock source is connected to clk_i of the ADC. +Now, if you're in linux, browse to where the snap_tut_spec.py file is in a terminal and at the prompt type ```bash - ./tut3.py -b + ./snap_tut_spec.py -b ``` -replacing with the IP address of your ROACH and with your boffile. You should see a spectrum like this: +replacing with the IP address of your SNAP and with your fpg file. You should see a spectrum like this: ![](../../_static/img/tut_spec/Spectrometer.py_4.8.png) -In the plot, there should be a fixed DC offset spike; and if you're putting in a tone, you should also see a spike at the correct input frequency. If you'd like to take a closer look, click the icon that is below your plot and third from the right, then select a section you'd like to zoom in to. The digital gain (-g option) is set to maximum (0xffff_ffff) by default to observe the ADC noise floor. Reduce the gain (decrease the value (for a -10dBm input 0x100)) when you are feeding the ADC with a tone, as not to saturate the spectrum. +In the plot, there should be a fixed DC offset spike; and if you're putting in a tone, you should also see a spike at the correct input frequency. If you'd like to take a closer look, click the icon that is below your plot and third from the right, then select a section you'd like to zoom in to. Now you've seen the python script running, let's go under the hood and have a look at how the FPGA is programmed and how data is interrogated. To stop the python script running, go back to the terminal and press ctrl + c a few times. ### iPython walkthrough ### -The tut3.py script has quite a few lines of code, which you might find daunting at first. Fear not though, it's all pretty easy. To whet your whistle, let's start off by operating the spectrometer through iPython. Open up a terminal and type: +The snap_tut_spec.py script has quite a few lines of code, which you might find daunting at first. Fear not though, it's all pretty easy. To whet your whistle, let's start off by operating the spectrometer through iPython. Open up a terminal and type: ```bash ipython ``` -and press enter. You'll be transported into the magical world of iPython, where we can do our scripting line by line, similar to MATLAB. Our first command will be to import the python packages we're going to use: +and press enter. You'll be transported into the magical world of iPython, where we can do our scripting line by line, similar to MATLAB (you can also use jupyter if you're familiar with that). Our first command will be to import the python packages we're going to use: ```python -import corr,time,numpy,struct,sys,logging,pylab +import casperfpga,casperfpga.snapadc,time,numpy,struct,sys,logging,pylab,matplotlib ``` Next, we set a few variables: ```python -katcp_port = 7147 -roach = 'enter IP address or hostname here' -timeout = 10 +snap='192.168.0.1' # Put your SNAP IP here +katcp_port=7147 # This is default KATCP port +bitstream='snap_tut_spec.fpg' # Path to the fpg file +sample_rate = 800.0 # Sample rate in MHz +freq_range_mhz = numpy.linspace(0., sample_rate/2, 2048) ``` -Which we can then use in FpgaClient() such that we can connect to the ROACH and issue commands to the FPGA: +Which we can then use to connect to the SNAP board using casperfpga: ```python -fpga = corr.katcp_wrapper.FpgaClient(roach,katcp_port, timeout) +print('Connecting to server %s on port %i... '%(snap,katcp_port)), +fpga = casperfpga.CasperFpga(snap) ``` -We now have an fpga object to play around with. To check if you managed to connect to your ROACH, type: +We now have an fpga object to play around with. To check if you managed to connect to your SNAP, type: ```python fpga.is_connected() ``` -Let's set the bitstream running using the progdev() command: +Let's set the bitstream running using the upload_to_ram_and_program() command: ```python -fpga.progdev('tut3.bof') +fpga.upload_to_ram_and_program(bitstream) ``` -Now we need to configure the accumulation length and gain by writing values to their registers. For two seconds and maximum gain: accumulation length, 2*(2^28)/2048, or just under 2 seconds: +Next, we need to initialize the ADC. Note in the future this will be done automatically, but for now, we need to: ```python -fpga.write_int('acc_len',2*(2**28)/2048) -fpga.write_int('gain',0xffffffff) +# Create an ADC object +adc = casperfpga.snapadc.SNAPADC(fpga, ref=10) # reference at 10MHz +# We want a sample rate of 800 Mhz, with 1 channel per ADC chip, using 8-bit ADCs +adc.init(samplingRate=sample_rate, numChannel=1, resolution=8) +adc.selectADC(0) +# Since we're in 4-way interleaving mode (i.e., one input per snap chip) we should configure +# the ADC inputs accordingly +adc.selectADC(0) # send commands to the first ADC chip +adc.adc.selectInput([1,1,1,1]) # Interleave four ADCs all pointing to the first input +``` + +Now we need to configure the accumulation length by writing values to the acc_len register. For two seconds of integration, the accumulation length is: 2 [seconds] * 4096 [samples per spectrum] / 800e6 [ADC sample rate]. In nice powers-of-two, this is approximately 2*(2^30)/4096 + +```python +fpga.write_int('acc_len',2*(2**30)/4096) ``` Finally, we reset the counters: @@ -392,67 +389,38 @@ pylab.xlim(0,2048) pylab.show() ``` -Voila! You have successfully controlled the ROACH spectrometer using python, and plotted a spectrum. Bravo! You should now have enough of an idea of what's going on to tackle the python script. Type exit() to quit ipython. -tut3.py notes == - -Now you're ready to have a closer look at the tut3.py script. Open it with your favorite editor. Again, line by line is the only way to fully understand it, but to give you a head start, here's a few notes: - -Connecting to the ROACH - -To make a connection to the ROACH, we need to know what port to connect to, and the IP address or hostname of our ROACH. The connection is made on line 96: - -```python -fpga = corr.katcp_wrapper.FpgaClient(...) -``` - -The katcp_port variable is set on line 16, and the roach variable is passed to the script at the terminal (remember that you typed python tut3.py roachname). We can check if the connection worked by using fpga.is_connected(), which returns true or false: +Voila! You have successfully controlled the SNAP spectrometer using python, and plotted a spectrum. Bravo! You should now have enough of an idea of what's going on to tackle the python script. Type exit() to quit ipython. -```python -if fpga.is_connected(): -``` +### snap_spec_tut.py notes -The next step is to get the right bitstream programmed onto the FPGA fabric. The bitstream is set on line 15: +Now you're ready to have a closer look at the [snap_spec_tut.py](https://github.com/telegraphic/tutorials_devel/blob/master/vivado/snap/tut_spec/snap_tut_spec.py) script. Open it with your favorite editor. Again, line by line is the only way to fully understand it, but to give you a head start, here's a few notes: -```python -bitstream = 'tut3.bof' -``` +#### Connecting to the SNAP -Then the progdev command is issued on line 108: +To make a connection to the SNAP, we need to know what port to connect to, and the IP address or hostname of our SNAP. -```python -fpga.progdev(bitstream) -``` - -Passing variables to the script - -Starting from line 64, you'll see the following code: +Starting from [line 47](https://github.com/telegraphic/tutorials_devel/blob/master/vivado/snap/tut_spec/snap_tut_spec.py#L47), you'll see the following code: ```python -from optparse import OptionParser - -p = OptionParser() -p.set_usage('tut3.py [options]') -p.set_description(__doc__) - -p.add_option('-l','—acc_len',dest='acc_len', -type='int', default=2*(2**28)/2048, -help='Set the number of vectors to accumulate between dumps. default is 2*(2^28)/2048, or just under 2 seconds.') - -p.add_option('-g', '--gain', dest='gain', -type='int',default=0xffffffff, -help='Set the digital gain (6bit quantisation scalar). Default is 0xffffffff (max), good for wideband noise. Set lower for CW tones.') - -p.add_option('-s', '--skip', dest='skip', action='store_true', -help='Skip reprogramming the FPGA and configuring EQ.') - -opts, args = p.parse_args(sys.argv[1:]) - - if args==[]: - print 'Please specify a ROACH board. Run with the -h flag to see all options.\nExiting.' - exit() - else: - roach = args[0] + p = OptionParser() + p.set_usage('spectrometer.py [options]') + p.set_description(__doc__) + p.add_option('-l', '--acc_len', dest='acc_len', type='int',default=2*(2**28)/2048, + help='Set the number of vectors to accumulate between dumps. default is 2*(2^28)/2048, or just under 2 seconds.') + p.add_option('-s', '--skip', dest='skip', action='store_true', + help='Skip reprogramming the FPGA and configuring EQ.') + p.add_option('-b', '--fpg', dest='fpgfile',type='str', default='', + help='Specify the fpg file to load') + opts, args = p.parse_args(sys.argv[1:]) + + if args==[]: + print 'Please specify a SNAP board. Run with the -h flag to see all options.\nExiting.' + exit() + else: + snap = args[0] + if opts.fpgfile != '': +bitstream = opts.fpgfile ``` What this code does is set up some defaults parameters which we can pass to the script from the command line. If the flags aren't present, it will default to the values set here. @@ -460,10 +428,10 @@ What this code does is set up some defaults parameters which we can pass to the ## Conclusion ## If you have followed this tutorial faithfully, you should now know: -• What a spectrometer is and what the important parameters for astronomy are. +* What a spectrometer is and what the important parameters for astronomy are. -• Which CASPER blocks you might want to use to make a spectrometer, and how to connect them up in Simulink. +* Which CASPER blocks you might want to use to make a spectrometer, and how to connect them up in Simulink. -• How to connect to and control a ROACH spectrometer using python scripting. +* How to connect to and control a SNAP spectrometer using python scripting. -In the following tutorials, you will learn to build a correlator, and a polyphase filtering spectrometer using an FPGA in conjunction with a Graphics Processing Unit (GPU). \ No newline at end of file +In the following tutorials, you will learn to build a correlator, and a polyphase filtering spectrometer using an FPGA in conjunction with a Graphics Processing Unit (GPU). diff --git a/docs/tutorials/snap/tut_ten_gbe.md b/docs/tutorials/snap/tut_ten_gbe.md index 297190e..af56594 100644 --- a/docs/tutorials/snap/tut_ten_gbe.md +++ b/docs/tutorials/snap/tut_ten_gbe.md @@ -86,9 +86,9 @@ The receive logic is is composed of another 10GbE yellow block with the transmis The casperfpga Python package contains all kinds of methods to interact with your 10GbE cores. For example, grabbing packets from the TX and RX stream, or counting the number of packets sent and received are all supported, as long as you turn on the appropriate functionality in the 10GbE yellow block. The settings we'll use are -- -![](../../_static/img/tut_ten_gbe/gbe_core_0_params.png) +![](../../_static/img/tut_ten_gbe/snap_gbe_core_0_params.png) -![](../../_static/img/tut_ten_gbe/gbe_core_0_debug_params.png) +![](../../_static/img/tut_ten_gbe/snap_gbe_core_0_debug_params.png) You can see how to use these functions in the software that accompanies this tutorial. diff --git a/ise/roach2/tut_spec/roach2_tut_spec.py b/ise/roach2/tut_spec/roach2_tut_spec.py new file mode 100644 index 0000000..d6ff3d7 --- /dev/null +++ b/ise/roach2/tut_spec/roach2_tut_spec.py @@ -0,0 +1,377 @@ +#!/usr/bin/env python +''' +This script demonstrates programming an FPGA, configuring a wideband spectrometer and plotting the received data using the Python KATCP library along with the katcp_wrapper distributed in the corr package. Designed for use with TUT3 at the 2009 CASPER workshop.\n +You need to have KATCP and CORR installed. Get them from http://pypi.python.org/pypi/katcp and http://casper.berkeley.edu/svn/trunk/projects/packetized_correlator/corr-0.4.0/ +\nAuthor: Jason Manley, November 2009. +Updated by: Tyrone van Balla, October 2015 +Updated for CASPER 2016 workshop. Updated to use casperfpga library and for ROACH-2 +''' + +#TODO: add support for ADC histogram plotting. +#TODO: add support for determining ADC input level + +import casperfpga +import time +import numpy +import struct +import sys +import logging +import pylab +import matplotlib + +bitstream = 'tut3_updated.fpg' + +def exit_fail(): + print 'FAILURE DETECTED. Log entries:\n',lh.printMessages() + try: + fpga.stop() + except: pass + raise + exit() + +def exit_clean(): + try: + fpga.stop() + except: pass + exit() + +def get_data(): + #get the data... + acc_n = fpga.read_uint('acc_cnt') + a_0=struct.unpack('>1024Q',fpga.read('even',1024*8,0)) + a_1=struct.unpack('>1024Q',fpga.read('odd',1024*8,0)) + + interleave_a=[] + + for i in range(1024): + interleave_a.append(a_0[i]) + interleave_a.append(a_1[i]) + return acc_n, interleave_a + +def plot_spectrum(): + matplotlib.pyplot.clf() + acc_n, interleave_a = get_data() + + matplotlib.pylab.plot(interleave_a) + #matplotlib.pylab.semilogy(interleave_a) + matplotlib.pylab.title('Integration number %i.'%acc_n) + matplotlib.pylab.ylabel('Power (arbitrary units)') + matplotlib.pylab.ylim(0) + matplotlib.pylab.grid() + matplotlib.pylab.xlabel('Channel') + matplotlib.pylab.xlim(0,2048) + fig.canvas.draw() + fig.canvas.manager.window.after(100, plot_spectrum) + +# debug log handler +class DebugLogHandler(logging.Handler): + """A logger for KATCP tests.""" + + def __init__(self,max_len=100): + """Create a TestLogHandler. + @param max_len Integer: The maximum number of log entries + to store. After this, will wrap. + """ + logging.Handler.__init__(self) + self._max_len = max_len + self._records = [] + + def emit(self, record): + """Handle the arrival of a log message.""" + if len(self._records) >= self._max_len: self._records.pop(0) + self._records.append(record) + + def clear(self): + """Clear the list of remembered logs.""" + self._records = [] + + def setMaxLen(self,max_len): + self._max_len=max_len + + def printMessages(self): + for i in self._records: + if i.exc_info: + print '%s: %s Exception: '%(i.name,i.msg),i.exc_info[0:-1] + else: + if i.levelno < logging.WARNING: + print '%s: %s'%(i.name,i.msg) + elif (i.levelno >= logging.WARNING) and (i.levelno < logging.ERROR): + print '%s: %s'%(i.name,i.msg) + elif i.levelno >= logging.ERROR: + print '%s: %s'%(i.name,i.msg) + else: + print '%s: %s'%(i.name,i.msg) + + +#START OF MAIN: + +if __name__ == '__main__': + from optparse import OptionParser + + p = OptionParser() + p.set_usage('tut3_update.py [options]') + p.set_description(__doc__) + p.add_option('-l', '--acc_len', dest='acc_len', type='int',default=2*(2**28)/2048, + help='Set the number of vectors to accumulate between dumps. default is 2*(2^28)/2048, or just under 2 seconds.') + p.add_option('-g', '--gain', dest='gain', type='int',default=0xffffffff, + help='Set the digital gain (6bit quantisation scalar). Default is 0xffffffff (max), good for wideband noise. Set lower for CW tones.') + p.add_option('-s', '--skip', dest='skip', action='store_true', + help='Skip reprogramming the FPGA and configuring EQ.') + p.add_option('-f', '--fpgfile', dest='fpg',type='str', default=bitstream, + help='Specify the bof file to load') + opts, args = p.parse_args(sys.argv[1:]) + + if args==[]: + print 'Please specify a ROACH board. Run with the -h flag to see all options.\nExiting.' + exit() + else: + roach = args[0] + if opts.fpg != '': + bitstream = opts.fpg + +try: + loggers = [] + lh=DebugLogHandler() + logger = logging.getLogger(roach) + logger.addHandler(lh) + logger.setLevel(10) + + print('Connecting to server %s... '%(roach)), + fpga = casperfpga.CasperFpga(roach) + time.sleep(1) + + if fpga.is_connected(): + print 'ok\n' + else: + print 'ERROR connecting to server %s.\n'%(roach) + exit_fail() + + print '------------------------' + print 'Programming FPGA with %s...' %bitstream, + if not opts.skip: + sys.stdout.flush() + fpga.upload_to_ram_and_program(bitstream) + time.sleep(10) + print 'ok' + else: + print 'Skipped.' + + print 'Configuring accumulation period...', + fpga.write_int('acc_len',opts.acc_len) + print 'done' + + print 'Resetting counters...', + fpga.write_int('cnt_rst',1) + fpga.write_int('cnt_rst',0) + print 'done' + + print 'Setting digital gain of all channels to %i...'%opts.gain, + if not opts.skip: + fpga.write_int('gain',opts.gain) #write the same gain for all inputs, all channels + print 'done' + else: + print 'Skipped.' + + #set up the figure with a subplot to be plotted + fig = matplotlib.pyplot.figure() + ax = fig.add_subplot(1,1,1) + + # start the process + fig.canvas.manager.window.after(100, plot_spectrum) + matplotlib.pyplot.show() + print 'Plot started.' + +except KeyboardInterrupt: + exit_clean() +except: + exit_fail() +#!/usr/bin/env python +''' +This script demonstrates programming an FPGA, configuring a wideband spectrometer and plotting the received data using the Python KATCP library along with the katcp_wrapper distributed in the corr package. Designed for use with TUT3 at the 2009 CASPER workshop.\n +You need to have KATCP and CORR installed. Get them from http://pypi.python.org/pypi/katcp and http://casper.berkeley.edu/svn/trunk/projects/packetized_correlator/corr-0.4.0/ +\nAuthor: Jason Manley, November 2009. +Updated by: Tyrone van Balla, October 2015 +Updated for CASPER 2016 workshop. Updated to use casperfpga library and for ROACH-2 +''' + +#TODO: add support for ADC histogram plotting. +#TODO: add support for determining ADC input level + +import casperfpga +import time +import numpy +import struct +import sys +import logging +import pylab +import matplotlib + +bitstream = 'tut3_updated.fpg' + +def exit_fail(): + print 'FAILURE DETECTED. Log entries:\n',lh.printMessages() + try: + fpga.stop() + except: pass + raise + exit() + +def exit_clean(): + try: + fpga.stop() + except: pass + exit() + +def get_data(): + #get the data... + acc_n = fpga.read_uint('acc_cnt') + a_0=struct.unpack('>1024l',fpga.read('even',1024*4,0)) + a_1=struct.unpack('>1024l',fpga.read('odd',1024*4,0)) + + interleave_a=[] + + for i in range(1024): + interleave_a.append(a_0[i]) + interleave_a.append(a_1[i]) + return acc_n, interleave_a + +def plot_spectrum(): + matplotlib.pyplot.clf() + acc_n, interleave_a = get_data() + + matplotlib.pylab.plot(interleave_a) + #matplotlib.pylab.semilogy(interleave_a) + matplotlib.pylab.title('Integration number %i.'%acc_n) + matplotlib.pylab.ylabel('Power (arbitrary units)') + matplotlib.pylab.ylim(0) + matplotlib.pylab.grid() + matplotlib.pylab.xlabel('Channel') + matplotlib.pylab.xlim(0,2048) + fig.canvas.draw() + fig.canvas.manager.window.after(100, plot_spectrum) + +# debug log handler +class DebugLogHandler(logging.Handler): + """A logger for KATCP tests.""" + + def __init__(self,max_len=100): + """Create a TestLogHandler. + @param max_len Integer: The maximum number of log entries + to store. After this, will wrap. + """ + logging.Handler.__init__(self) + self._max_len = max_len + self._records = [] + + def emit(self, record): + """Handle the arrival of a log message.""" + if len(self._records) >= self._max_len: self._records.pop(0) + self._records.append(record) + + def clear(self): + """Clear the list of remembered logs.""" + self._records = [] + + def setMaxLen(self,max_len): + self._max_len=max_len + + def printMessages(self): + for i in self._records: + if i.exc_info: + print '%s: %s Exception: '%(i.name,i.msg),i.exc_info[0:-1] + else: + if i.levelno < logging.WARNING: + print '%s: %s'%(i.name,i.msg) + elif (i.levelno >= logging.WARNING) and (i.levelno < logging.ERROR): + print '%s: %s'%(i.name,i.msg) + elif i.levelno >= logging.ERROR: + print '%s: %s'%(i.name,i.msg) + else: + print '%s: %s'%(i.name,i.msg) + + +#START OF MAIN: + +if __name__ == '__main__': + from optparse import OptionParser + + p = OptionParser() + p.set_usage('tut3_update.py [options]') + p.set_description(__doc__) + p.add_option('-l', '--acc_len', dest='acc_len', type='int',default=2*(2**28)/2048, + help='Set the number of vectors to accumulate between dumps. default is 2*(2^28)/2048, or just under 2 seconds.') + p.add_option('-g', '--gain', dest='gain', type='int',default=0xffffffff, + help='Set the digital gain (6bit quantisation scalar). Default is 0xffffffff (max), good for wideband noise. Set lower for CW tones.') + p.add_option('-s', '--skip', dest='skip', action='store_true', + help='Skip reprogramming the FPGA and configuring EQ.') + p.add_option('-f', '--fpgfile', dest='fpg',type='str', default=bitstream, + help='Specify the bof file to load') + opts, args = p.parse_args(sys.argv[1:]) + + if args==[]: + print 'Please specify a ROACH board. Run with the -h flag to see all options.\nExiting.' + exit() + else: + roach = args[0] + if opts.fpg != '': + bitstream = opts.fpg + +try: + loggers = [] + lh=DebugLogHandler() + logger = logging.getLogger(roach) + logger.addHandler(lh) + logger.setLevel(10) + + print('Connecting to server %s... '%(roach)), + fpga = casperfpga.katcp_fpga.KatcpFpga(roach) + time.sleep(1) + + if fpga.is_connected(): + print 'ok\n' + else: + print 'ERROR connecting to server %s.\n'%(roach) + exit_fail() + + print '------------------------' + print 'Programming FPGA with %s...' %bitstream, + if not opts.skip: + sys.stdout.flush() + fpga.upload_to_ram_and_program(bitstream) + time.sleep(10) + print 'ok' + else: + print 'Skipped.' + + print 'Configuring accumulation period...', + fpga.write_int('acc_len',opts.acc_len) + print 'done' + + print 'Resetting counters...', + fpga.write_int('cnt_rst',1) + fpga.write_int('cnt_rst',0) + print 'done' + + print 'Setting digital gain of all channels to %i...'%opts.gain, + if not opts.skip: + fpga.write_int('gain',opts.gain) #write the same gain for all inputs, all channels + print 'done' + else: + print 'Skipped.' + + #set up the figure with a subplot to be plotted + fig = matplotlib.pyplot.figure() + ax = fig.add_subplot(1,1,1) + + # start the process + fig.canvas.manager.window.after(100, plot_spectrum) + matplotlib.pyplot.show() + print 'Plot started.' + +except KeyboardInterrupt: + exit_clean() +except: + exit_fail() + +exit_clean() +exit_clean() diff --git a/vivado/mlib_devel b/vivado/mlib_devel index 2253ebd..0f70f45 160000 --- a/vivado/mlib_devel +++ b/vivado/mlib_devel @@ -1 +1 @@ -Subproject commit 2253ebd9a79ba26b3287247ba1490a72c87daee9 +Subproject commit 0f70f450bcf087084b03c76d325ea33e9f24f4bf diff --git a/vivado/snap/tut_corr/snap_auto_plot.py b/vivado/snap/tut_corr/snap_auto_plot.py new file mode 100644 index 0000000..1d5458b --- /dev/null +++ b/vivado/snap/tut_corr/snap_auto_plot.py @@ -0,0 +1,138 @@ +#!/usr/bin/env python +''' +This code demonstrates readount of a SNAP spectrometer. You need a SNAP with: +-- A 10 MHz, 8dBm reference going into the SYNTH_OSC SMA (3rd SMA from the left) +-- a test tone going into the ADC0 input 0 (8th input from the left) +''' + +#TODO: add support for ADC histogram plotting. +#TODO: add support for determining ADC input level + +import casperfpga,casperfpga.snapadc,time,numpy,struct,sys,logging,pylab,matplotlib + +katcp_port=7147 +freq_range_mhz = numpy.linspace(0., 400., 2048) + +def set_coeff(coeff,nch): + quants_coeffs = [coeff] * nch * 2 + quants_coeffs = struct.pack('>{0}H'.format(nch*2),*quants_coeffs) + for i in range(3): + fpga.blindwrite('quant{0}_coeffs'.format(i), quants_coeffs) + +def get_data(): + #get the data... + acc_n = fpga.read_uint('acc_num') + a_0=struct.unpack('>512l',fpga.read('dir_x0_aa_real',512*4,0)) + a_1=struct.unpack('>512l',fpga.read('dir_x1_aa_real',512*4,0)) + b_0=struct.unpack('>512l',fpga.read('dir_x0_bb_real',512*4,0)) + b_1=struct.unpack('>512l',fpga.read('dir_x1_bb_real',512*4,0)) + c_0=struct.unpack('>512l',fpga.read('dir_x0_cc_real',512*4,0)) + c_1=struct.unpack('>512l',fpga.read('dir_x1_cc_real',512*4,0)) + + interleave_a=[] + interleave_b=[] + interleave_c=[] + + for i in range(512): + interleave_a.append(a_0[i]) + interleave_a.append(a_1[i]) + interleave_b.append(b_0[i]) + interleave_b.append(b_1[i]) + interleave_c.append(c_0[i]) + interleave_c.append(c_1[i]) + return acc_n, numpy.array(interleave_a,dtype=numpy.float), numpy.array(interleave_b,dtype=numpy.float), numpy.array(interleave_c,dtype=numpy.float) + +def plot_spectrum(): + matplotlib.pyplot.clf() + acc_n, interleave_a, interleave_b, interleave_c = get_data() + #interleave_a = 10*numpy.log10(interleave_a/(numpy.max(interleave_a))) + interleave_a = 10*numpy.log10(interleave_a) + interleave_b = 10*numpy.log10(interleave_b) + interleave_c = 10*numpy.log10(interleave_c) + matplotlib.pylab.plot(freq_range_mhz, interleave_a) + matplotlib.pylab.plot(freq_range_mhz, interleave_b,'r') + matplotlib.pylab.plot(freq_range_mhz, interleave_c,'g') + matplotlib.pylab.title('Integration number %i.'%acc_n) + matplotlib.pylab.ylabel('Power (dB)') + #matplotlib.pylab.ylim(0) + matplotlib.pylab.grid() + matplotlib.pylab.xlabel('Freq (MHz)') + matplotlib.pylab.xlim(freq_range_mhz[0], freq_range_mhz[-1]) + fig.canvas.draw() + fig.canvas.manager.window.after(100, plot_spectrum) + + +#START OF MAIN: + +if __name__ == '__main__': + from optparse import OptionParser + + + p = OptionParser() + p.set_usage('spectrometer.py [options]') + p.set_description(__doc__) + p.add_argument('-n', '--nchannel', dest='nch',type=int, default=1024, + help='The number of frequency channel. Default is 1024.') + p.add_argument('-c', '--coeff', dest='coeff', type=int, default=1000, + help='Set the coefficients in quantisation (4bit quantisation scalar).') + p.add_option('-l', '--acc_len', dest='acc_len', type='int',default=2*(2**28)/2048, + help='Set the number of vectors to accumulate between dumps. default is 2*(2^28)/2048, or just under 2 seconds.') + opts, args = p.parse_args(sys.argv[1:]) + + if args==[]: + print 'Please specify a SNAP board. Run with the -h flag to see all options.\nExiting.' + exit() + else: + snap = args[0] + +try: + + print('Connecting to server %s on port %i... '%(snap,katcp_port)), + fpga = casperfpga.CasperFpga(snap) + time.sleep(0.2) + + if fpga.is_connected(): + print 'ok\n' + else: + print 'ERROR connecting to server %s on port %i.\n'%(snap,katcp_port) + exit_fail() + + + print 'Configuring accumulation period...', + sys.stdout.flush() + if args.acc_len: + fpga.write_int('acc_len',opts.acc_len) + print 'done' + + fpga.write_int('ctrl',0) + fpga.write_int('ctrl',1<<16) #clip reset + fpga.write_int('ctrl',0) + fpga.write_int('ctrl',1<<17) #arm + fpga.write_int('ctrl',0) + fpga.write_int('ctrl',1<<18) #software trigger + fpga.write_int('ctrl',0) + fpga.write_int('ctrl',1<<18) #issue a second trigger + fpga.write_int('ctrl',0) + time.sleep(0.1) + + if args.coeff: + print 'Configuring quantisation coefficients with parameter {0}...'.format(args.coeff), + sys.stdout.flush() + set_coeff(args.coeff,args.nch) + print 'done' + + #set up the figure with a subplot to be plotted + fig = matplotlib.pyplot.figure() + ax = fig.add_subplot(1,1,1) + + # start the process + fig.canvas.manager.window.after(100, plot_spectrum) + matplotlib.pyplot.show() + print 'Plot started.' + + +except KeyboardInterrupt: + exit() + +exit() + diff --git a/vivado/snap/tut_corr/snap_cross_plot.py b/vivado/snap/tut_corr/snap_cross_plot.py new file mode 100644 index 0000000..cc0a406 --- /dev/null +++ b/vivado/snap/tut_corr/snap_cross_plot.py @@ -0,0 +1,132 @@ +#!/usr/bin/env python +''' +This code demonstrates readount of a SNAP spectrometer. You need a SNAP with: +-- A 10 MHz, 8dBm reference going into the SYNTH_OSC SMA (3rd SMA from the left) +-- a test tone going into the ADC0 input 0 (8th input from the left) +''' + +#TODO: add support for ADC histogram plotting. +#TODO: add support for determining ADC input level + +import casperfpga,casperfpga.snapadc,time,numpy,struct,sys,logging,pylab,matplotlib + +katcp_port=7147 +freq_range_mhz = numpy.linspace(0., 400., 2048) + +def set_coeff(coeff,nch): + quants_coeffs = [coeff] * nch * 2 + quants_coeffs = struct.pack('>{0}H'.format(nch*2),*quants_coeffs) + for i in range(3): + fpga.blindwrite('quant{0}_coeffs'.format(i), quants_coeffs) + +def get_data(baseline): + #get the data... + acc_n = fpga.read_uint('acc_num') + data_0r=struct.unpack('>512l',fpga.read('dir_x0_%s_real'%baseline,512*4,0)) + data_1r=struct.unpack('>512l',fpga.read('dir_x1_%s_real'%baseline,512*4,0)) + data_0i=struct.unpack('>512l',fpga.read('dir_x0_%s_imag'%baseline,512*4,0)) + data_1i=struct.unpack('>512l',fpga.read('dir_x1_%s_imag'%baseline,512*4,0)) + + interleave_data=[] + + for i in range(512): + interleave_data.append(complex(data_0r[i], data_0i[i])) + interleave_data.append(complex(data_1r[i], data_1i[i])) + + return acc_n,interleave_data + + +def drawDataCallback(baseline): + matplotlib.pyplot.clf() + acc_n,interleave_data = get_data(baseline) + + matplotlib.pyplot.subplot(211) + matplotlib.pyplot.semilogy(freq_range_mhz,numpy.abs(interleave_data)) + matplotlib.pyplot.grid() + matplotlib.pyplot.title('Integration number %i \n%s'%(acc_n,baseline)) + matplotlib.pyplot.ylabel('Power (arbitrary units)') + + matplotlib.pyplot.subplot(212) + matplotlib.pyplot.plot(freq_range_mhz,(numpy.angle(interleave_data))) + matplotlib.pyplot.xlabel('Frequency') + matplotlib.pyplot.ylabel('Phase') + matplotlib.pyplot.ylim(-numpy.pi,numpy.pi) + matplotlib.pyplot.grid() + + matplotlib.pyplot.draw() + fig.canvas.manager.window.after(100, drawDataCallback,baseline) + +#START OF MAIN: + +if __name__ == '__main__': + from optparse import OptionParser + + + p = OptionParser() + p.set_usage('spectrometer.py [options]') + p.set_description(__doc__) + p.add_argument('-n', '--nchannel', dest='nch',type=int, default=1024, + help='The number of frequency channel. Default is 1024.') + p.add_argument('-c', '--coeff', dest='coeff', type=int, default=1000, + help='Set the coefficients in quantisation (4bit quantisation scalar).') + p.add_option('-l', '--acc_len', dest='acc_len', type='int',default=2*(2**28)/2048, + help='Set the number of vectors to accumulate between dumps. default is 2*(2^28)/2048, or just under 2 seconds.') + opts, args = p.parse_args(sys.argv[1:]) + + if args==[]: + print 'Please specify a SNAP board. Run with the -h flag to see all options.\nExiting.' + exit() + else: + snap = args[0] + +try: + + print('Connecting to server %s on port %i... '%(snap,katcp_port)), + fpga = casperfpga.CasperFpga(snap) + time.sleep(0.2) + + if fpga.is_connected(): + print 'ok\n' + else: + print 'ERROR connecting to server %s on port %i.\n'%(snap,katcp_port) + exit_fail() + + + print 'Configuring accumulation period...', + sys.stdout.flush() + if args.acc_len: + fpga.write_int('acc_len',opts.acc_len) + print 'done' + + fpga.write_int('ctrl',0) + fpga.write_int('ctrl',1<<16) #clip reset + fpga.write_int('ctrl',0) + fpga.write_int('ctrl',1<<17) #arm + fpga.write_int('ctrl',0) + fpga.write_int('ctrl',1<<18) #software trigger + fpga.write_int('ctrl',0) + fpga.write_int('ctrl',1<<18) #issue a second trigger + fpga.write_int('ctrl',0) + time.sleep(0.1) + + if args.coeff: + print 'Configuring quantisation coefficients with parameter {0}...'.format(args.coeff), + sys.stdout.flush() + set_coeff(args.coeff,args.nch) + print 'done' + + #set up the figure with a subplot to be plotted + fig = matplotlib.pyplot.figure() + ax = fig.add_subplot(2,1,1) + + # start the process + fig.canvas.manager.window.after(100, drawDataCallback,baseline) + matplotlib.pyplot.show() + print 'Plot started.' + + +except KeyboardInterrupt: + exit() + +exit() + diff --git a/vivado/snap/tut_corr/snap_init.py b/vivado/snap/tut_corr/snap_init.py new file mode 100644 index 0000000..4a22d79 --- /dev/null +++ b/vivado/snap/tut_corr/snap_init.py @@ -0,0 +1,100 @@ +#!/usr/bin/env python +''' +This code demonstrates readount of a SNAP spectrometer. You need a SNAP with: +-- A 10 MHz, 8dBm reference going into the SYNTH_OSC SMA (3rd SMA from the left) +-- a test tone going into the ADC0 input 0 (8th input from the left) +''' + +#TODO: add support for ADC histogram plotting. +#TODO: add support for determining ADC input level + +import casperfpga,casperfpga.snapadc,time,numpy,struct,sys,logging,pylab,matplotlib + +katcp_port=7147 + + +#START OF MAIN: + +if __name__ == '__main__': + from optparse import OptionParser + + + p = OptionParser() + p.set_usage('spectrometer.py [options]') + p.set_description(__doc__) + p.add_option('-s', '--skip', dest='skip', action='store_true', + help='Skip reprogramming the FPGA and configuring EQ.') + p.add_option('-b', '--fpg', dest='fpgfile',type='str', default='snap_tut_corr.fpg', + help='Specify the fpg file to load') + opts, args = p.parse_args(sys.argv[1:]) + + if args==[]: + print 'Please specify a SNAP board. Run with the -h flag to see all options.\nExiting.' + exit() + else: + snap = args[0] + if opts.fpgfile != '': + bitstream = opts.fpgfile + +try: + + print('Connecting to server %s on port %i... '%(snap,katcp_port)), + fpga = casperfpga.CasperFpga(snap) + time.sleep(0.2) + + if fpga.is_connected(): + print 'ok\n' + else: + print 'ERROR connecting to server %s on port %i.\n'%(snap,katcp_port) + exit_fail() + + print '------------------------' + print 'Programming FPGA with %s...' %bitstream, + sys.stdout.flush() + if not opts.skip: + fpga.upload_to_ram_and_program(bitstream) + print 'done' + else: + print 'Skipped.' + + # After programming we need to configure the ADC. The following function call assumes that + # the SNAP has a 10 MHz reference connected. It will use this reference to generate an 800 MHz + # sampling clock. The init function will also tweak the alignment of the digital lanes that + # carry data from the ADC chips to the FPGA, to ensure reliable data capture. It should take about + # 30 seconds to run. + # In the future you won't have to instantiate an adc object as below, casperfpga will automatically + # detect the presence of an adc block in your SNAP design, and will automagically create you + # an adc object to interact with. + adc = casperfpga.snapadc.SNAPADC(fpga, ref=10) # reference at 10MHz + # We want a sample rate of 800 Mhz, with 1 channel per ADC chip, using 8-bit ADCs + # (there is another version of the ADC chip which operates with 12 bits of precision) + if not opts.skip: + print 'Attempting to initialize ADC chips...' + sys.stdout.flush() + # try initializing a few times for good measure in case it fails... + done = False + for i in range(3): + if adc.init(samplingRate=800, numChannel=1, resolution=8) == 0: + done = True + break + print 'done (took %d attempts)' % (i+1) + if not done: + print 'Failed to calibrate after %d attempts' % (i+1) + exit_clean() + + # Since we're in 4-way interleaving mode (i.e., one input per snap chip) we should configure + # the ADC inputs accordingly + adc.selectADC([0,1,2]) # send commands to the all three ADC chips + adc.adc.selectInput([1,1,1,1]) # Interleave four ADCs all pointing to the first input + + print 'Configuring accumulation period...', + sys.stdout.flush() + fpga.write_int('acc_len',opts.acc_len) + print 'done' + + +except KeyboardInterrupt: + exit() + +exit() + diff --git a/workshop_setup.md b/workshop_setup.md index a50f55a..c8f9a16 100644 --- a/workshop_setup.md +++ b/workshop_setup.md @@ -1,31 +1,23 @@ -# Casper Caltech Workshop 2017 Tutorials Help Page +# Casper Guiyang Workshop 2018 Tutorials Help Page ## Local Configuration Information ### Accounts and login info -When you first arrive please connect to the local network in the tutorial room. If you can, plug in to one of the network switches on the tables (marked "casper.pvt"). A small number of USBA to RJ45 dongles are available if you need them. If you are unable to join the wired network, you should connect to the local wireless network. The **SSID is casper (5 Ghz) or casper24 (2.4 GHz)**. Please use the 5 Ghz if you can. **The WiFi password will be given to you when you arrive**. +When you first arrive please connect to the local network in the tutorial room. If you are unable to join the wired network, you should connect to the local wireless network. The **SSID is casper2018tutorials**. **The WiFi password will be given to you when you arrive**. -Once on the local network, you should be given an address on the 192.168.2.X subnet. You should be able to access the internet, as well as all the hardware in the tutorial room. +Once on the local network, you should be given an address on the 10.0.1.X subnet. You should be able to access the internet, as well as all the hardware in the tutorial room. **When you arrive at the tutorial sessions you will be allocated a remote server to build designs on, and provided with login details.** -### Setting up VNC -You will be working on remote machines using VNC to get a remote graphical interface. - -You will need a VNC client installed on your laptop. - -There are a variety of options -- For Windows or Linux laptops, TightVNC should be available. MacOS has a built in VNC client, but you may also like to download and use "Chicken" a 3rd party VNC client. - -Once you have a client installed, you will be able to use it to connect to the remote servers, using a path of the form :. The hostname and session IDs will be allocated when you show up to the tutorial sessions. - ### Setting Up SSH -You will also need SSH to log in to the server in the tutorial room which controls the ROACH/SNAP/SKARAB boards. SSH is supported natively in Linux and MacOS. If you are using a Windows laptop, you should install an SSH client, like Putty. Log in details for this server will be provided when you arrive at the tutorial sessions. +You will also need SSH (including X tunneling to provide graphics) to log in to the server in the tutorial room which controls the ROACH/SNAP/SKARAB boards. SSH is supported natively in Linux and MacOS (though MacOS may require the "XQuartz" application to support X windows tunneling). If you are using a Windows laptop, you should install an SSH client, like Putty, and an X windows client. Log in details for this server will be provided when you arrive at the tutorial sessions. ### Preparing to run the tutorials In order to get ready to build and compile designs, you need to log into the server you have been allocated, and set up a directory in which to work. To do this, follow the step-by-step instructions below. -1. Using your VNC client, and the server details you were given at the tutorial session, connect to a remote desktop session 2. Start a terminal on this desktop, by clicking (look in the top left of the screen) Applications >> System Tools >> Terminal 3. Grab the tutorials code repository, and associated CASPER libraries. In the terminal, run: +1. Using your ssh client, and the server details you will be given at the tutorials session, connect to one of the provided compile server. +2. Copy the tutorials code repository, and associated CASPER libraries. In the terminal, run: ```bash # Go into the home directory (you're probably already there, but let's make sure) cd ~ @@ -33,22 +25,11 @@ cd ~ mkdir # eg. mkdir julio-iglesias # Go into this directory cd #eg. cd julio-iglesias -# Grab a copy of the tutorials repository from github -git clone https://github.com/casper-astro/tutorials_devel.git -# Go in to the repository -cd tutorials_devel -# Switch to the version of the tutorials being used at the 2017 workshop -# The following command will check out the workshop2017 branch from CASPER's github repo, and save it as a local branch, names "workshop2017" -git checkout origin/workshop2017 -b workshop2017 -# Now update the CASPER libraries to be compatible with this version of the tutorials -git submodule init -git submodule update -# This last command might take a minute or two -- it downloads the complete CASPER library codebase. +# Grab a copy of the tutorials repository from the '/home/fast' directory +cp -r /home/fast/tutorials_devel . ``` -That wasn't so hard, right? Running all the above commands might be a little bit cumbersome, but it ensures your versions of the CASPER libraries are in sync with the tutorial models you are running. This will prevent all kinds of pain later on. - -2. Decide which hardware platform you are compiling for and go to the appropriate direcctory. Different directories contain slightly different MATLAB / Xilinx configurations, so it's important to choose the right one for the platform you are using. +3. Decide which hardware platform you are compiling for and go to the appropriate direcctory. Different directories contain slightly different MATLAB / Xilinx configurations, so it's important to choose the right one for the platform you are using. ```bash cd ise # For ROACH only # or... @@ -59,39 +40,27 @@ cd snap # For SNAP designs cd skarab # For skarab designs ``` -3. Finally, start MATLAB. The following command will configure your environment with the install locations of the MATLAB / Xilinx tools. This configuration depends on how you have set up your compile machines. The startsg.local.caltech2017 files below will only work on the CalTech build machines. +3. Finally, start MATLAB. The following command will configure your environment with the install locations of the MATLAB / Xilinx tools. This configuration depends on how you have set up your compile machines. The startsg.local files below will only work on the build machines. ```bash -./startsg startsg.local.caltech2017 +./startsg ``` You should be greeted with a MATLAB window. After a few seconds, it should be ready to accept user input. 4. From here, you can either open one of the tutorial .slx files using the "Open" button, or start a new simulink design by typing "simulink" in the MATLAB prompt and starting a new model. -5. Now go to the [Tutorials](https://casper.berkeley.edu/wiki/Tutorials) page to find the instructions for your chosen tutorial. When you have compiled your design, come back here to see how to load it on to hardware. +5. Now go to the [Tutorials](https://casper-toolflow.readthedocs.io/projects/tutorials/en/workshop2018/) page to find the instructions for your chosen tutorial. When you have compiled your design, come back here to see how to load it on to hardware. ## Getting your designs on to hardware -When your compile has finished, it should deliver you a .fpg file (this will be created in /bit_files/ for ROACHs, or /outputs/ for SNAP / SKARAB). This file needs copying to the server in the tutorial room which is connected to all the FPGA boards. To copy the file between machines, run (in a terminal within your vnc session): -```bash -scp /path/to/fpg_file.fpg casper1@maze:.fpg -``` -For example: -```bash -scp ~/julio-iglesias/tutorials_devel/vivado/snap/tut_intro/snap_tut_intro/outputs/snap_tut_intro_2017-08-13_1508.fpg casper1@maze:julio-iglesias_snap_intro.fpg -``` -You should not be asked for a password. You may be warned that the authenticity of the host can't be verified. If so, type "yes" to continue. +When your compile has finished, it should deliver you a .fpg file (this will be created in /bit_files/ for ROACHs, or /outputs/ for SNAP / SKARAB). -You can now ssh from your laptop into maze, with username casper1. The password will be provided at the tutorial sessions. Once you are in maze, you should see the file you copied if you list all files in the home directory with the command: -```bash -ls -``` You can now follow the tutorial instructions to program this file to an FPGA board. Details of the available FPGA platforms is below. ### Available FPGA hardware -There are two SNAPs, two SKARABs, and 2 ROACH2s in the tutorial room. You can access them from maze (or your laptops, if you have the casperfpga libraries installed) using the hostnames +There are two SNAPs, two SKARABs, and 2 ROACH2s in the tutorial room. You can access them from whichever server you are using (or your laptops, if you have the casperfpga libraries installed) using the hostnames * roach1 * roach2 * snap1 * snap2 -* skarab02030D-01 (40GbE port) -* skarab020310-01 (40GbE port) \ No newline at end of file +* skarab020406-01 (40GbE port) +* skarab020802-01 (40GbE port)