Jump to content

artvvb

Technical Forum Moderator
  • Posts

    1,063
  • Joined

  • Last visited

Posts posted by artvvb

  1. Hi @Sergio Lopez,

    I2S data is signed, twos complement. I suspect that when the signal is ~0, it's toggling back and forth between numbers slightly above (~0x0000) and below zero (~0xFFFF), resulting in the wild swings you're seeing. This might also be obscuring the peak you're trying to detect - especially if the peak is a peak in signal amplitude with zero offset, which would still be switching back and forth between positive and negative.

    Thanks,

    Arthur

  2. Hi Davide,

    To confirm whether it's an issue with the board or physical ethernet setup, does running the LwIP Echo Server example suggested by the guide work for you? I don't have much experience with the freertos OS and haven't tested that particular example as of yet.

    Thanks,

    Arthur

  3. On 2/9/2024 at 1:54 PM, Xband said:

     

    I think the basic concept of pulling out the data, using the DSP accumulator and then combining back into the AXI stream should work, though I could be really screwed up with the timing even if it compiles.  I'm interested in using the simulation to try and ring out the timing but this DDR project is pretty deep and I'm not sure how to implement that, though I see you have the ILA ip scattered throughout for this purpose. 

    To be clear, yes, this concept is sound. I'm only concerned about doing it for both channels simultaneously and passing data up to software through a single DMA controller.

    Simulation for this kind of project would be best served by pulling apart the different pieces. Keeping it likely way too vague, you might write a wrapper and a testbench for everything in the stream between the ZmodScopeController and DMA, and verify that it responds to control signals correctly - for example, you'd set an "enable" bit in a testbench that simulates the pipeline instead of trying to include the software and PS in simulation through cosimulation. Doing simulations of small components regularly and on a small scale before integrating them together would be helpful to verify that assumptions we're making are correct.

    It's at a really low level compared to the entirety of the project, but this guide might help for starting to poke around the simulator UI, in case you haven't touched it yet: https://digilent.com/reference/programmable-logic/guides/simulation.

  4. On 2/9/2024 at 1:54 PM, Xband said:

    Could you give a rough overview on which values should change to u64 (in the s2mm_cyclic_transfer main) or perhaps just a link to some code that would spit the actual hardware  buffer out so I can confirm it has changed to 64bit depth.  

    Reading a captured stream as 64-bit pieces of data is relatively straightforward. The data would be interleaved - every other word is a raw sample and the rest are accumulated samples. I haven't tested this code, and it would depend on whether your real samples and accumulated samples are in the high or low word of the 64-bit piece, but it would look somewhat like the following:

    // start at line 562 of https://github.com/Digilent/Eclypse-Z7-SW/blob/b42fb15a8ab4c52a38db2c15918cd7263e84f65e/src/s2mm_cyclic_transfer_test/src/main.c
        for (u32 i = 0; i < BufferLength; i++) {
            u32 index = (i + BufferHeadIndex) % BufferLength;
            if (index % 2 == 0) { // then it's probably raw samples
              	float ch1_mV = 1000.0f * RawDataToVolts(RxBuffer[index], 0, ZMOD_SCOPE_RESOLUTION, Relays.Ch1Gain);
              	float ch2_mV = 1000.0f * RawDataToVolts(RxBuffer[index], 1, ZMOD_SCOPE_RESOLUTION, Relays.Ch2Gain);
              	const u16 ch1_raw = ChannelData(0, RxBuffer[index], ZMOD_SCOPE_RESOLUTION);
              	const u16 ch2_raw = ChannelData(1, RxBuffer[index], ZMOD_SCOPE_RESOLUTION);
            } else { // it's accumulated samples
            	// do stuff with the samples
            }
            // ...
        }

    That said, I'm not certain how the logic that finds the start of the buffer would handle it, and an off-by-one error could crop up. There's a note in the S2mmFindStartOfBuffer function to this effect: https://github.com/Digilent/Eclypse-Z7-SW/blob/b42fb15a8ab4c52a38db2c15918cd7263e84f65e/src/s2mm_cyclic_transfer_test/src/s2mm_transfer.c#L238.

    Edit: Note that the DMA is currently transferring 64-bit chunks of data (in the demo project, it's sending two 32-bit samples at once), it's put sequentially into memory, and it's up to the software how to interpret this memory on the software side - it would also be possible to cast the buffer to a pointer of a 64-bit struct type, like the following, and iterate over it using that (though there's additional complexity from the "start of the buffer" potentially showing up anywhere in the memory region allocated for the it). The same possibilities of off-by-one, which word is the "top" of the 64-bit piece of data, and S2mmFindStartOfBuffer maybe needing changes show up here too.

    typedef struct {
      u16 acc_data_0;
      u16 acc_data_1;
      u16 raw_data_0;
      u16 raw_data_1;
    } rawAndAcc_Data;
    
    rawAndAcc_Data *buffer = (rawAndAcc_Data*)RxBuffer;
    
    // looping not shown here due to the aforementioned complexity around where the start of the buffer is located
    xil_printf("%04x", buffer[0].acc_data_0);

     

    On 2/9/2024 at 1:54 PM, Xband said:

    I seen to recall you being against changing this depth to 64, which is entirely reasonable given the complexity that the stream depends on, I tried to preserve the 32bit axi stream data through all the original hw in the base fpga design and then combine the stream just befor the DMA transfer coming out of the ZmodScope Port A. 

    The concern here was motivated by the potential loss of samples. The DMA master interface that connects to one of the PS HP ports is in fact 64 bits wide. In other demo projects, this was only 32 bits wide. The DDR demo increased the DMA master width of to 64 bits it to improve throughput - if the DMA is clocked at the same rate as incoming data (100 MHz for 100 MS/s or something) and the input interface to the DMA (AXI stream) and output interface are the same width, then protocol overhead needed for the AXI master interface makes it so that there will always be some clock cycles where data can't be pushed into the DMA. By protocol overhead, I mean that the DMA needs to take time to do things like specify the address it wants to write to. The way that this issue shows up is that if the DMA master interface is busy, its internal FIFOs are filling up - when they fill entirely, the ready signal on the DMA's AXI stream interface drops, and the rest of the input pipeline backs up. When the DMA becomes ready again, the stream starts up again, but there will have been samples that were lost during the stall.

    It may be possible to increase the clock frequency fed to the DMA sufficiently to cover the extra cycles needed for the protocol overhead, but that also makes it harder to meet timing. "Upconverting" from 32 to 64 bits inside of the DMA made this much easier to do, since it doubled the potential throughput at the output, giving plenty of margin to account for overhead. This is why I suggested limiting yourself to one channel of input, so that you could use 16 bit raw samples and 16 bit accumulated data from the same channel, staying within the original 32-bit width.

    Alternatively, it might be possible to copy the DMA hierarchy (effectively making a second instance of S2mmDmaTransfer_0) to handle a second 32-bit stream, but I would need to set up a project to see if/how it would work. It would also require software changes in main to manage a second DMA controller.

  5. No, the XADC primitive needs to be included in the project somehow for it to be connected in the bitstream, whether it's included through the IP or a direct primitive instantiation.

  6. Hi Davide,

    We don't have much experience with 2023.2 yet and there are significant changes between it and previous versions. It's possible that there's a new bug. I'll see if we can test a boot.bin file generated in 2023.2, but I would also recommend that you install another version to work with, I've personally found 2023.1 to be reasonably stable, but it will also depend on what support materials you want to be able to use - while it's possible to use material created for an older version of the tools, there could always be differences that break things.

    For 2023.2 specifically, these guides may be helpful, as the Cora and Arty Z7 are fairly similar:
    Vivado - https://www.hackster.io/whitney-knitter/getting-started-with-the-arty-z7-in-vivado-2023-2-26051a
    Vitis - https://www.hackster.io/whitney-knitter/getting-started-with-the-arty-z7-in-vitis-unified-ide-2023-2-1a8ee5

    Thanks,

    Arthur

  7. Hey @salamus

    On further review, Viktor is correct, an intermediate state that lets the state machine wait until the uart transmitter has acknowledged receipt of the byte (maybe by just waiting a cycle, since busy being low means you know it's ready to accept a byte) would help. The issue is likely that the state machine sees busy as being low, so asserts ready_2, and moves to the next state - this is all good, except that on the next clock cycle when it checks busy again, assuming busy is registered inside the uart transmitter, that busy signal hasn't had a chance to update yet and the state machine thinks it's okay to send another byte.

    There's a comparable issue that requires that skid buffers be used in modules implementing AXI stream interfaces to be fully protocol compliant, since both sides of the handshake must be registered. There are some good articles around the web on this. This is an example: http://fpgacpu.ca/fpga/Pipeline_Skid_Buffer.html. It's not completely 1-to-1 with your issue, since there's a line in the AXI stream spec that states "a transmitter [your state machine] is not permitted to wait until TREADY [not busy] is asserted before asserting TVALID [ready_2]" (page 18, section 2.2: https://developer.arm.com/documentation/ihi0051/latest/), but is still a very similar registered handshake.

    Edit: Richm is also correct, as a FIFO correctly implementing a handshake protocol would also take care of the issue. A skid buffer is just a very small FIFO.

    Further edited: A third solution would be to eliminate the handshake entirely by holding ready continuously high as long as you aren't in reset and rewriting the state machine to either 1. select the byte to send combinationally depending on the state it's in or 2. set the data_store register to whatever byte you want to send in the next state (as in 8'b00110101 in idle, 8'b10101010 in byte1, etc).

    Thanks,

    Arthur

  8. Hey Davide,

    Sorry for the delay. One of my colleagues, @JRys, potentially reproduced the issue and has been doing some investigating. He found that when using an SD card originally used with a Raspberry Pi, a small additional boot partition was left on the card, making it so that an equivalent Zynq board wouldn't boot - it was trying to boot from the incompatible boot partition instead of the expected one where the boot image from Vitis was loaded. Could something like this be the case with your setup?

    Thanks,

    Arthur

  9. Hi @mvernengo

    Apologies for the delay.

    The Zedboard ships with an SD card with the out-of-box image included, and also potentially an image in flash - we're currently investigating the flash side. There is an "Out-of-box demo" ZIP file including out-of-box source files and an image for the Zedboard on its resource center: https://digilent.com/reference/programmable-logic/zedboard/start. Note that this image is quite old, and was created using Xilinx XPS 14.1 and SDK 14.1, according to the included readme, and as such, may be quite difficult to rebuild from scratch. Recreating an SD card for boot from the included prebuilt files looks to be relatively straightforward, and is documented in the readme.

    As an aside, in my experience, ChatGPT results for this kind of technical topic, especially when related to specific products, tend to either be highly unreliable or not specific enough to be helpful, at least for new users. In this particular case, the output isn't the worst. SD card boot is also an option, and you should make sure to set the programming mode select jumpers to the appropriate position for the intended boot source. AMD/Xilinx's Vivado or Vitis (previously SDK) tools would typically be used to handle flashing an image. SD card prep, given the boot image, can be performed using the normal stuff intended for formatting drives and moving files around.

    Thanks,

    Arthur

  10. Hi @css

    Could you provide some photos of your board while the 01n issue is happening? If it's damaged, the described behavior sounds odd. I'd expect that the seven-segment display would show the same constant value on one or more of the four digits, with the others being all off or all on, due to common anode signals remaining constant. If it's different on each digit, that means that the anode signals are changing.

    It would also be helpful to know if you've programmed your board's flash memory, since an out-of-box image similar to the GPIO demo comes preinstalled and boots from flash when the board is powered on.

    What position do you have the programming mode select jumper set to?

    Thanks,

    Arthur

  11. 6 hours ago, engrpetero said:

    When you say, 'force Vivado to repackage their IP from scratch', what do you mean?

    I'd expect restarting the IP packager fresh to create a new instance of the IP, adding in the files you pulled from the original instance, would work, even if it would be a hassle.

    There's some more discussion of this issue here: https://support.xilinx.com/s/question/0D52E00006miunQSAQ/ip-packager-not-updating-ports-from-vhdl-code?language=en_US.

    Thanks,

    Arthur

  12. Hi @salamus

    Could you share port, signal, and parameter declarations in addition to the state machine process? The data_store signal resetting to a one-bit value has some cause for concern, not necessarily for it being the cause of problems, but more in case there are other more relevant width mismatches - like if state is only one bit wide the state machine would presumably toggle back and forth between idle and byte1, depending on what the actual values of the state parameters are.

    Also, if you haven't, simulate your design.

    Thanks,

    Arthur

  13. Yes, you should technically be able to use XADC without any IP in a project. While the Cmod A7 15T demo (https://digilent.com/reference/programmable-logic/cmod-a7/demos/xadc) instantiates an XADC IP, the primitive that this IP wraps can be directly instantiated in your design. See the screenshot of the language templates built into Vivado, below. Note that primitives like this are not necessarily easy to configure and still require the appropriate review of corresponding datasheets.

    image.png

    Thanks,

    Arthur

  14. @GLC

    Are you trying to use the USB JTAG / USB UART microUSB port? If so, drivers are installed through the Vivado installer on Windows. See "Install Cable Drivers ..." here:

    image.png

    You can rerun the installer via the "Help -> Add Design Tools or Devices" option in Vivado.

    Thanks,

    Arthur

  15. To try to answer one of your questions today:

    Sharing projects is kind of a huge topic... Digilent has used these two sets of scripts to get projects packaged up for git - https://github.com/Digilent/digilent-vivado-scriptshttps://github.com/Digilent/digilent-vitis-scripts - but there may be issues with various tool versions and certain unsupported features (RTL modules aren't handled automatically for example). GitHub's file size limits for files included in releases are pretty lenient, so it might be possible to attach full project archives for both Vivado and Vitis if you created a repo there. Starting points in the menus for creating ZIPs are File -> Project -> Archive in Vivado and File -> Export in Vitis, at least for 2021.1. The nice thing about using the auto export tools is that, at least in Vivado, it'll collect up all external dependencies like IPs and board files, and they can at least theoretically cut out a lot of the build outputs and other random files that show up in project directories.

  16. 26 minutes ago, boesterle said:

    Could something similar be going on with the mm2s project?

    Yes. The failure indicated by the error message that the calibration was not successfully read could come from a couple of different early exits from ZmodAwg_ReadCoefficientsFromDna. Please try bypassing this one, or modify the function it calls: https://github.com/Digilent/Eclypse-Z7-SW/blob/aa2f34efc4dc63317a58bbaeb02e946c4c2d68a9/src/mm2s_single_transfer_test/src/awg_calibration.c#L75.

  17. No other hardware configuration issues, seeing as you're getting USBUART printouts.

    Could you send me the printout from the calibration reader? This could be related to a recently reported issue where the app was not able to determine the name and type of the Zmod correctly, due to names not matching expected values - see this comment: 

    There's a more extensive fix in the works, but it has not yet been pushed out to Github.

    Thanks,

    Arthur

×
×
  • Create New...