Jump to content
  • 0

Eclypse DDR Streaming Project channel calibration question


Xband

Question

I have this hardware and software running and giving output on the serial port.  When I run the calibration routine it seems to give reasonable data but when I run the S2MM code the output seems to be in hex.  My guess is that the cal file isn't referenced properly but its a guess and I can't seem to locate where a file such as this is read in the code, I see the scope_calibration.c file Below are the serial result of the  calibration_reader_system and s2mm_cyclic_transfer_test_system. 

Eventually I want to perform some math on channel acquisitions and spit out a result.  I've input a 1kHz +/- 1V sine wave but direct conversion from hex to decimal in Exce (sorry I hate it too) gives nonsense huge numbers column H & I converting B and C. 

Thanks for any insight. 

 

 

image.thumb.png.63b1fe58a70b8f0f0c47319a501160dd.png

========= Zmod Port A : Zmod ADC 1410-105 Calibration Coefficients =========

    Factory Calibration:   December 24, 2021 at 02:55:34
    CHAN_1_LG_GAIN:        -0.000055
    CHAN_1_LG_OFFSET:      -0.076329
    CHAN_1_HG_GAIN:        0.011868
    CHAN_1_HG_OFFSET:      -0.002765
    CHAN_2_LG_GAIN:        -0.001325
    CHAN_2_LG_OFFSET:      0.130576
    CHAN_2_HG_GAIN:        0.010189
    CHAN_2_HG_OFFSET:      0.006026
    Ch1LgCoefMultStatic:   0x10CC9
    Ch1LgCoefAddStatic:    0x3FE71
    Ch1HgCoefMultStatic:   0x11951
    Ch1HgCoefAddStatic:    0x3FE97
    Ch2LgCoefMultStatic:   0x10C72
    Ch2LgCoefAddStatic:    0x002AD
    Ch2HgCoefMultStatic:   0x118D9
    Ch2HgCoefAddStatic:    0x00316

    User Calibration:      December 24, 2021 at 02:55:34
    CHAN_1_LG_GAIN:        -0.000055
    CHAN_1_LG_OFFSET:      -0.076329
    CHAN_1_HG_GAIN:        0.011868
    CHAN_1_HG_OFFSET:      -0.002765
    CHAN_2_LG_GAIN:        -0.001325
    CHAN_2_LG_OFFSET:      0.130576
    CHAN_2_HG_GAIN:        0.010189
    CHAN_2_HG_OFFSET:      0.006026
    Ch1LgCoefMultStatic:   0x10CC9
    Ch1LgCoefAddStatic:    0x3FE71
    Ch1HgCoefMultStatic:   0x11951
    Ch1HgCoefAddStatic:    0x3FE97
    Ch2LgCoefMultStatic:   0x10C72
    Ch2LgCoefAddStatic:    0x002AD
    Ch2HgCoefMultStatic:   0x118D9
    Ch2HgCoefAddStatic:    0x00316

Done initializing device drivers
TestMode: 0
Initialization done
ADC initialization done
Waiting for trigger...
Last beat found:
  BD base address: 00124168
  BD actual length: 0000000C
Buffer base address: 00124168
Buffer high address: 00128164
Length of buffer (words): 4096
Index of buffer head: 3
Trigger position: 0
Index of trigger position: 3
Detected trigger condition: 00000002
Transfer done
@00124174       FFE70007        3FF9    0001    0       3
@00124178       FFECFFFF        3FFB    3FFF    0       -3
@0012417C       FFF0FFEE        3FFC    3FFB    0       -15
@00124180       FFE7FFFF        3FF9    3FFF    0       -3
@00124184       FFDE0003        3FF7    0000    -1      0
@00124188       FFDEFFEA        3FF7    3FFA    -1      -18
@0012418C       FFD60003        3FF5    0000    -1      0
@00124190       FFDE0003        3FF7    0000    -1      0
@00124194       FFDAFFEA        3FF6    3FFA    -1      -18
@00124198       FFEC0003        3FFB    0000    0       0
@0012419C       FFECFFFF        3FFB    3FFF    0       -3
@001241A0       FFDA0003        3FF6    0000    -1      0
@001241A4       FFE3FFFB        3FF8    3FFE    0       -6
@001241A8       FFECFFF6        3FFB    3FFD    0       -9
@001241AC       036C0003        00DB    0000    26      0
@001241B0       0BD20035        02F4    000D    92      39
@001241B4       0A9100D5        02A4    0035    82      161
@001241B8       04E60157        0139    0055    38      259
@001241BC       049C0191        0127    0064    36      305
@001241C0       055D01AB        0157    006A    41      323
@001241C4       0611019A        0184    0066    47      311
@001241C8       064601AF        0191    006B    48      326
@001241CC       066901BB        019A    006E    50      335
@001241D0       06B401C0        01AD    0070    52      341
@001241D4       06FF01BB        01BF    006E    54      335
@001241D8       073C01C8        01CF    0072    56      347
@001241DC       078201BB        01E0    006E    58      335
@001241E0       07CD01DD        01F3    0077    60      363
@001241E4       082101E5        0208    0079    63      369
@001241E8       087401DD        021D    0077    66      363
@001241EC       08CC0

Link to comment
Share on other sites

Recommended Posts

  • 0

Hi @Xband

Please review the RawDataToVolts implementation in main.c - huge numbers are likely due to the decimal number representing ADC counts instead of Volts. Pages 7-10 of the ZmodScopeController user manual also have some good insight on the conversion math: https://github.com/Digilent/vivado-library/blob/master/ip/Zmods/ZmodScopeController/docs/ZmodScopeController.pdf.

For not seeing a sine wave in the acquired data, the buffer currently being captured is 4096 samples long - when running at 100 MS/s, this covers about 40 microseconds of capture time. This is indicated by the "Length of buffer (words): 4096" line in the printout. You can increase this by changing line 497 of main.c, where the "BufferLength" constant is set. Alternatively, you might send a faster test signal.

Thanks,

Arthur

Link to comment
Share on other sites

  • 0

@artvvb

Ok, I found the column structure in the code, and had changed that buffer length.  Increased my signal to 50KHz and can see the oscillation in the data. 

Can you change the sampling rate by uncommenting these lines?  I would think the sampling rate is set in the HW IP with the clock?

 

// Define the acquisition window
    //    const u32 SampleRateMegaSamplesPerSecond = 125;
    //    const u32 SamplePeriodNanoseconds = 1000.0 / SampleRateMegaSamplesPerSecond;
    // fails at bufferlength=0x100
    const u32 BufferLength = 0x2000;//0x400000;
    // 0x400000 / 125 MS/s = 3.3 ms
    // 0x1000 / 100 MS/s = 40.96 us => ~10.4 kHz
    const u32 TriggerPosition = 0;//BufferLength / 4;

 

 

Link to comment
Share on other sites

  • 0
Quote

I would think the sampling rate is set in the HW IP with the clock?

Yes, changing the sampling rate would require hardware changes to modify the clock frequency. It can only go so low though, depending on the requirements of the FPGA clocking circuitry, and calibration could potentially be affected. Decimation of data could also help, either after the fact on the host or in PS software, or with hardware changes to do the decimation in FPGA fabric - the demo doesn't include this though.

Edit to add - the commented lines were originally intended for calculating the buffer length based on a specified acquisition period and should likely be removed.

Link to comment
Share on other sites

  • 0

@artvvb,

Looking at the code it seems that the entire buffer is captured and then output as individual lines.  My goal is to integrate point to point and react to a level that is reached over multiple 5us pulses in a 30Hz train. 

I"m not sure how do do this yet, can we estimate the total time required for 1 triggered acquisition?  If I need to trigger and read the buffer each time what is the effective sample rate I can achieve?   How many pulses could I read and then react to over a 10us period?  For normal sampling rate of 100Ms/s it should be about 1000 points in the normal buffer.  

Thanks, 

 

 

Link to comment
Share on other sites

  • 0

@artvvb,

My thought process on this subject is influenced by work I've done in Labview FPGA.  The concept of "High Throughput Math Functions in a Single-Cycle Timed Loop (FPGA Module)" to do what I"m trying.  My guess is that there are lower level FPGA concepts underlying the Labview implementation layer.  I need to understand this at a lower level somehow so see if this ADC integration could be done on the FPGA possibly, though I could be delusional.  :)

https://www.ni.com/docs/en-US/bundle/labview-fpga-module/page/lvfpgaconcepts/ht_math_single_cycle.html

Link to comment
Share on other sites

  • 0
Quote

I"m not sure how do do this yet, can we estimate the total time required for 1 triggered acquisition?

We don't currently have a blind time benchmark or estimate for how long it would take for the demo to rearm a trigger. Fully resetting the DMA may be required, due some potential bugs - if I recall correctly, this would be on the order of tens or hundreds of milliseconds between acquisitions.

Quote

My goal is to integrate point to point and react to a level that is reached over multiple 5us pulses in a 30Hz train. 

Changes to the hardware design could accomplish this but would require designing your own modules to add to the design. Some kind of component sitting between the Scope Controller and trigger mechanism might be able to do it, but would get tricky - an additional trigger mechanism to limit data flowing to the DMA module, a buffer to hold data that arrives before a trigger, summing consecutive samples as they arrive and storing them in a register, then potentially passing the contents of that register to the DMA via AXI stream once the entire trigger has come through. Some documentation on the functionality of the hardware in the existing design can be seen in this page: https://digilent.com/reference/programmable-logic/eclypse-z7/demos/eclypse_platform_manual#trigger_detector. Also, this is the source code for the level trigger mechanism, for reference: https://github.com/Digilent/Eclypse-Z7-HW/blob/ddr-streaming/src/hdl/level_trigger.v.The trigger detector section might be most helpful, though do note, the doc is incomplete. It might also be just as easy to start working from the Low-level Low-pass Filter example instead.

When you say that you want to react to a level, how quickly do you need to react, and how what form does that reaction take? Messaging the host PC via serial, or by setting an AWG level or digital output?

One additional note, once it's in the FPGA, data flows through the AXI stream interface, shown in orange in the below, reading up on AXI streams might be handy. AXI streams are probably what a lot of the LabVIEW material is based on, at least for how it handles inputs and outputs. I'm not familiar enough with LabVIEW FPGA to really comment though.

image.png

 

Link to comment
Share on other sites

  • 0

@artvvb

Thanks for the information.  I'll start trying to absorb this so I can ask better questions. 

The "reaction" should be in the form of a digital output, maybe the PMOD would work, or some other line on the board.  The timing can be either a few clock cycles, 20ns'ish or 10ms.  The faster one would be preferred. 

Thanks, 

 

Link to comment
Share on other sites

  • 0

Hi @Xband,

I was talking to a colleague about this today. There are potentially a lot of different approaches to do this kind of thing, writing HDL as I was describing before is one option. It also should be possible to use the FIR filter channels in the WaveForms image for Eclypse to do a rolling average, perform a level trigger on the filter output, and then use the trigger to trigger the Wavegen or Pattern Generator to output a logic high signal on a Pmod pin. The catch with this approach is that the average would only be able to be performed over a 16-sample window, so the sample rate used would need to be low.

Would you be able to share where the pulses would be coming from in the proposed system, as in what device the Eclypse would be connected to? Also, do you have some form of mathematical model for the processing you are trying to do, like in Python or MATLAB?

Thanks,
Arthur

 

Link to comment
Share on other sites

  • 0

@artvvb

Hi, thanks for following up on this.  The signal is a current monitor looking at an approximate 5us pulse.  The sample rate needs to be pretty fast to get good resolution on the signal and the full window should capture at least 1us on either side of the pulse to be safe.  The source is an electron beam from an accelerator.  At this point the processing is just integrating the signal and multiplying or dividing by a calibration factor.

The processing needs to be fast enough to produce a digital interlock once the required amount of current is produced, or provide the interlock before the limit is met.  I'm currently only trying to address the basic acquisition and calculation at a high speed, and then hopefully expand the application with the Pmod output.  It would be very useful to trigger the acquisition with an external trigger into a Pmod.  

I found an external example of custom ip to create a math coprocessor in the AXI fifo stream.  This is the link, at least is seems possibly, though the tutorial may not be seamless. 

https://www.mehmetburakaykenar.com/creating-custom-axi-stream-ip-tutorial-with-vivado/397/

 

Thanks, 

 

Link to comment
Share on other sites

  • 0

@artvvb

I'm also trying to reproduce the streaming DDR example on another computer.  The code I downloaded does not include your "level_trigger.v" ip.  Does this need to be added after?  I had it working on the other machine but forgot how I got there. 

Thanks, 

Xband,  (I've aslo created a separate profile RT_biker, so thats also me)

Link to comment
Share on other sites

  • 0

@artvvb

I could probably dig up some similar oscilloscope waveform data files I don't have any "simulations," only real data.  Or I could produce a similar waveform from a waveform generator.  The structure is the 5us pulse coming in at 30Hz, maybe 1V peak, this is a good enough approximation. 

 

Edited by Xband
add more
Link to comment
Share on other sites

  • 0

Thanks for the additional info, it definitely sounds like this is doable in hardware. 

On 11/16/2023 at 1:14 PM, Xband said:

It would be very useful to trigger the acquisition with an external trigger into a Pmod.  

Does the hardware you're using provide a 3.3 V external trigger? Wiring it to a Pmod pin, getting it synced to FPGA clocks, and routing it into trigger detect logic should also be fairly straightforward.

Quote

I found an external example of custom ip to create a math coprocessor in the AXI fifo stream.  This is the link, at least is seems possibly, though the tutorial may not be seamless. 

https://www.mehmetburakaykenar.com/creating-custom-axi-stream-ip-tutorial-with-vivado/397/

So I haven't worked through that specific tutorial, but at a glance, it looks reasonable for creating IP with AXI streams, and should have some decent info about how to write the logic for these modules. It's also possible to skip the IP packager, and use Verilog or VHDL files directly in the block design. As long as the ports of a module have a common prefix and the correct tready/tvalid/tlast suffixes, it'll even bundle those ports together as interfaces for you. That said, the approach of using IP like in that guide automates some things that are easy to mess up otherwise (setting clock frequencies for the bundled interfaces for example). A short recording of what it looks like to connect a module into an existing stream is attached (do make sure that all of the signals represented in the streams and things are connected up - the video is just to show the tool flow). Once you've created an IP using that guide, and made sure it's included in the IP repo, the process of changing the block design to include that IP follows a very similar process.

On 11/16/2023 at 1:35 PM, Xband said:

I'm also trying to reproduce the streaming DDR example on another computer.  The code I downloaded does not include your "level_trigger.v" ip.  Does this need to be added after?  I had it working on the other machine but forgot how I got there. 

It should be in there. It's possible that the file isn't being displayed at the top level of the Sources tab's Design Sources group. It could still be in the project, just hidden. You could check by opening up the block design and expanding down into the ZmodScope_PortA/TriggerGenerator hierarchy.

Link to comment
Share on other sites

  • 0

@artvvb,

Which hardware project are you starting with?  I've downloaded the DDR streaming from the link below but it does not contain your level trigger IP.  

https://digilent.com/reference/lib/exe/fetch.php?tok=42351c&media=https%3A%2F%2Fgithub.com%2FDigilent%2FEclypse-Z7%2Freleases%2Fdownload%2Fddr-streaming%2F2021.1.1-prerelease%2FEclypse-Z7-DDR-Streaming-hw.xpr.zip

 

Thanks, 

 

 

Link to comment
Share on other sites

  • 0

The level trigger is instantiated a couple of levels down in the ZmodScope hierarchy - see the screenshot below:

image.png

The screenshot is taken from the project from the release download you linked. The hierarchy blocks expand/collapse with the plus/minus buttons. The video was instead using sources checked out from git from the tip of the demo branch, but there are not substantial changes in the block design that would affect things - there are some bugfixes in individual files though.

Link to comment
Share on other sites

  • 0

image.thumb.png.ce8092d66625084d67a8034c969f1295.png@artvvb, the block design I have is quite different.  This is what I unzipped from the DDR page.  Do you have a link to the project in Git?  I can find the DDR directory but do not see a "hw.xpr" file for the project.  I'll dig some more to try and find it. 

I loaded the top level hw.xpr, I'll dig through the other designs to see if I can find the matching project. 

 

I upgraded to 2023.2, maybe it changed some things and doesn't look quite the same now.  

 

 

Edited by Xband
update
Link to comment
Share on other sites

  • 0

@zygot

well, it is a bit of a nightmare for me, novice at this and trying to do something that seems kind of simple/obvious but I cannot seem to make anything work smoothly.  Switched computers and am rebuilding previous efforts again and its not smooth either. 

Seems like I should be able to find where the corresponding project file would live in github but i've downloaded zips of these directories and subdirectories are empty.  

I've gotten the Z7 hw to run the application but something changed when I changed computers or upgraded to 2023 as the block design doesn't match visually. 

I'll keep pounding my head on the wall.  Its a result of me trying to minimize effort and produce results.  This hardware fills a gap in performance that isn't available elsewhere so its worth it to me to keep slogging through the mud.  It will eventually work I'm confident. 

You should play tennis if you enjoy watching others suffer.  :)

 

 

Edited by Xband
Link to comment
Share on other sites

  • 0
51 minutes ago, Xband said:

Do you have a link to the project in Git?  I can find the DDR directory but do not see a "hw.xpr" file for the project.  I'll dig some more to try and find it. 

Working with the project from git requires using scripts in the hw/scripts folder. You would recursively clone the branch, "git clone --recursive https://github.com/Digilent/Eclypse-Z7 -b ddr-streaming" in a command line, then use the command "source <path to repo>/Eclypse-Z7/hw/scripts/checkout.tcl" to create the XPR and open it in the same Vivado window you ran the script from. If not using the recursive flag, the entire hw folder is empty, same goes for the scripts folder. These scripts usually have to be run in the same Vivado version as they were created for though, so downloading the XPR is cleaner if you really want to use a 2023 version. It's also very common for a project to work in one version but not another, since IP used in these designs can change between versions.

In your screenshot, the "interfaces view" changes a lot of what renders in the block design - it only shows the AXI interfaces and similar, instead of also showing clocks and individual signal nets. 

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...