Jump to content

artvvb

Technical Forum Moderator
  • Posts

    987
  • Joined

  • Last visited

Everything posted by artvvb

  1. Also, Whitney Knitter recently posted some tutorials for the Arty Z7 in 2023.2 that will likely be helpful: 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
  2. Hi @bloggins666 The xgpiops driver is used to control multiplexed input/output (MIO) GPIO pins in the Zynq Processing System (PS). These MIO pins are physically distinct from FPGA pins and are separate physical IOs on the chip. The xgpio driver is used to control an AXI GPIO peripheral. If you're using the board files to add an AXI GPIO to a block design, then that will control LEDs connected to FPGA pins on the programmable logic (PL) side of the chip. It's also possible to enable EMIO (extended MIO) pins that allow the hard GPIO controller in the Zynq PS to control pieces of the FPGA design, and then tie the EMIOs to FPGA IOs in the block design, so that LEDs that would normally be controlled by AXI GPIOs can be controlled by the PS GPIO controller. Probably clear as mud. All that is to say that, since you have axi_gpio controllers, use the xgpio (not xgpiops) drivers. Thanks, Arthur
  3. We've seen before that the DMA's ready signal comes up pretty quickly after the IP comes out of reset rather than waiting until a transfer has been initiated, which would allow extra samples into the DMA's internal FIFO if the upstream IP is set to assert tvalid right out of reset. If this is happening, I'd guess that a software reset of the DMA is clearing the FIFOs and discarding the first couple of values that the IP passes in. When the IP then sends the first block of data to the DMA after the PS starts the DMA transfer, tlast is sent early, terminating the DMA transfer a couple of words earlier than expected, leaving the last few pieces of data in the DDR buffer unchanged. A way to fix this would be to add an enable bit to the upstream AXI4-stream IP, controlled by an AXI4-lite module so that the software can tell the stream IP when to start. The IP could then be started after the first DMA transfer has already been initiated - after the first SimpleTransfer call. It looks like for your IP, it would require modifying the state machine in the verilog source to wait to exit IDLE state until a new enable input port is high. I might be misremembering some details, but that's my best guess. Yeah, AXI lite is good for control and status registers that you hit infrequently or poll, but can't do fast burst transfers. It's great to hear you're having success with this, it's an area with a steep learning curve. You could also add logic so that whenever a single address is read, the data in the register associated with that address is updated, potentially from a FIFO. This might consist of, for example, driving a FIFO read enable pin with "tvalid & tready" from the AXI4-lite read data channel. Thanks, Arthur
  4. Hi @werosic I assume based on previous threads that you are trying to use zmodlib and the lwip echo server template project together? I assume that you've replaced zmodlib with C (not C++) sources that accomplish similar things. Generally, the ADC sources and ethernet sources should not affect each other, except where shared resources are being accessed, or where performance concerns become a problem. I would check whether both the ADC library and the ethernet sources are initializing the GIC - the Zynq's interrupt controller, as it seems like the most likely potentially-shared system to cause an issue like this. If they both reset it and initialize it with their interrupt handlers, then the last subsystem initialized could cancel out part of the initialization of the other subsystem. Thanks, Arthur
  5. Hi @Zebryk If you haven't seen, a mechanical drawing for the BNC adapter is available on the Reference site: https://digilent.com/reference/_media/reference/test-and-measurement/bnc-adapter-board/discovery_bnc_mech.pdf. Linked from the resource center, here: https://digilent.com/reference/test-and-measurement/bnc-adapter-board/start. If this is insufficient for your purposes, I can make a request for additional material. Thanks, Arthur
  6. 2-3 Mb/s is very doable with DMA. I've seen 125x4 MB/s streaming to DDR. I haven't seen this before but will attempt to reproduce. If possible, could you post your modified code? Is data moving from DDR to the FPGA or vice-versa? They work pretty similarly with the DMA, but there are different catches to designing the hardware for each direction. Xil_In32 and Xil_Out32 are "just" macros to replace single-word memory accesses. Meaning something like "Xil_Out32(BASEADDR, value);" is equivalent to "*((u32*)BASEADDR) = value;". When the device tries to read from or write to a memory address assigned to a peripheral, the processor translates it into an AXI transaction, which is routed through the PS and PL interconnects to the peripheral's AXI controller. It's worth noting that the bulk transfer using the DMA is handled by the DMA controller: you configure what the transfer will be by setting values in its config registers, start it, and wait for the DMA controller to finish performing AXI transactions to write the data it's receiving to other addresses (in DDR). The demo should be using the XAxiDma_SimpleTransfer function to do most of the heavy lifting, though the simple transfer function is not that complicated under the hood - if I recall correctly, it's effectively three or four register reads & writes. https://github.com/Digilent/Zybo-Z7-SW/blob/27cf9ab8a5dc18ca0bf9e4e551551a6c509055af/src/Zybo-Z7-10-DMA/src/audio/audio.c#L374 The meat is in the audio.c source file. fnAudioRecord sets up a DMA transfer using XAxiDma_SimpleTransfer, then sets several control registers in the audio controller - first a sample count, so that the controller knows when to assert the "tlast" signal on the AXI stream, indicating to the DMA that the transfer has finished. Second, clearing and then setting the bit index 1 of the transfer control register, which is tied to a receive enable signal. Third, enabling the stream to the DMA. VHDL sources for the AXI controller and stream controller can be found in the IP's sources: https://github.com/Digilent/Zybo-Z7-HW/tree/3d1cfeb56b83dc7f9314aa4e2f0456d9bfc4bf68/repo/local/ip/d_axi_i2s_audio_v2_0/src, particularly d_axi_i2s_audio_v2_0_AXI_L.vhd and i2s_stream.vhd. You can access IP sources in the project by right-clicking on the IP in the block design and selecting "Edit in IP packager". They're a lot to read through, and there are easier ways of implementing AXI communication - I'd point to CSR generator tools capable of creating AXI controllers. Cheby seems interesting, since it can create AXI4-lite interfaces in VHDL source files that can be added directly to a block design through "Add module": https://gitlab.cern.ch/be-cem-edl/common/cheby/-/tree/master/doc?ref_type=heads. Digilent doesn't have a specific tutorial for this kind of thing right now. Apologies, this was a bit of an info-dump. Thanks, Arthur
  7. Hi @digility 1. I'm not sure what the highest tested resolution for the Basys 3 VGA port is, but the GPIO demo runs at 1280x1024 @ 60 Hz, which requires a faster pixel clock than 720p (108 MHz versus 74.25 MHz). https://digilent.com/reference/programmable-logic/basys-3/demos/gpio. 2. The Basys 3 would only support 4-bit greyscale images, due to each color component only having four bits - greyscale is achieved by setting R, G, and B outputs to the same value as each other for each pixel. You could always truncate off the bottom four bits of the image, obviously losing some information. Thanks, Arthur
  8. As an example of writing an RTL module from scratch, the following is the pulse extender described above. Design source: `timescale 1ns / 1ps module extend_pulse #( parameter integer LENGTH = 10 ) ( input wire clk, input wire resetn, input wire trigger_in, output wire extended_trigger_out ); reg trigger_reg = 'b0; reg [$clog2(LENGTH-1)-1:0] counter = 'b0; // Register, set when trigger_in is high, clear LENGTH clock cycles later always @(posedge clk) begin if (resetn == 1'b0) begin trigger_reg <= 'b0; end else if (trigger_reg == 1'b0) begin trigger_reg <= trigger_in; end else begin // if trigger_reg == 1'b1 if (counter >= LENGTH-1) begin trigger_reg <= trigger_in; end // else stay high end end // Counter, clear when trigger_in is high, else increment when trigger_reg is high always @(posedge clk) begin if (resetn == 1'b0) begin counter <= 'b0; end else if (trigger_in == 1'b1) begin counter <= 'b0; end else if (trigger_reg == 1'b1) begin counter <= counter + 1'b1; end end assign extended_trigger_out = trigger_reg; endmodule Simulation source: `timescale 1ns / 1ps module pulse_sim; reg clk = 1'b0; initial begin #10 clk = 1'b1; forever #5 clk = ~clk; end reg resetn = 1'b0; initial begin // clear on the first clock edge @(posedge clk) resetn <= 1'b1; end reg trigger_in = 0; initial begin #400 trigger_in <= 1'b1; #20 trigger_in <= 1'b0; end wire trigger_out; extend_pulse #( .LENGTH(10) ) dut ( .clk(clk), .resetn(resetn), .trigger_in(trigger_in), .extended_trigger_out(trigger_out) ); endmodule Simulation results, showing the extended pulse going for an additional 10 clock cycles after the pulse: And a guide for simulation, which ought to let you reproduce the above: https://digilent.com/reference/programmable-logic/guides/simulation
  9. Awesome! This means it's the newer board file version, which is good, don't need to suggest that readers revert to the old version or update the clock period setting. Should be able to have some links up in the next few days. I confirmed today that the test project I'd put together based on the tutorial functions in hardware, with a simple software app running out of DDR. Cheers, Arthur
  10. I'm really sorry, I was caught up with several other tasks today. The trigger outputs stay high for one stream beat (one clock cycle). Additional hardware that could handle this would be a register that gets set when the trigger output is high, paired with a counter that counts until it reaches a predefined value at which point the register clears, functionally a pulse extender/stretcher.
  11. Hi XBand, I'm actively taking a look through this and will have some more comments later this afternoon. Trying to break down the problem in a way that steps back a bit from the context of the DDR streaming demo, since I think that it is making things more complicated than needed. That said, some of the material in the demo project is still extremely necessary. The LabVIEW material looks interesting. A colleague also mentioned MATLAB, Simulink, and Model Composer as an option for this kind of DSP, but I have not used it myself, and it requires some licenses that you may or may not have access to. An accumulator will be able to perform the integration - this IP looks reasonable for it. Note that the output width probably needs to be large enough to fit the number 0xffff * 700 (assuming 700 us at 100 MS/s), so minimum 26 bits. Yes, it will be easier to treat each channel separately. Slicing off one of the channels so you can focus on designing the system for only one of them would also be appropriate. Also, you can treat tvalid on the AXI stream interface as an enable pin for downstream logic, as long as that logic needs to be run once every cycle - if you don't need extra control logic for the accumulator, maybe it's clock enable could just be tied to tvalid, for example. Would getting those scope captures of what a pulse looks like be possible? The paint diagrams below illustrate how I'm currently thinking about the shape of the pulses and timing: Charge threshold and voltage threshold would be specified separately. Thanks, Arthur
  12. Hi Viktor, Thanks for posting this guide, it looks really clean and you've clearly put in a lot of work. So far I've followed as far as generating a bitstream, with a couple of minor deviations, in that I specified no buffer in the clocking wizard and did not use the real-time preset. It seems to have built great (other than a hiccup where I initially capitalized the name of the CLK100MHZ port wrong, simple user error) and I'll be testing the project further. The same steps and design should be applicable to any Digilent board with a 100 MHz system clock and a DDR interface, including Nexys A7, Arty S7, Nexys Video, USB104 A7. Some comments and a couple of questions follow: It is possible to connect the external clock to the MIG, but still requires manually creating the clock port and adding a constraint like you do for CLK100MHZ in order to override the 2.5 V logic standard that the MIG tries to set. That said, it looks like your approach is better than wiring the clock port directly to sys_clk_i, for reasons described below. I've updated the 35T's template constraints on GitHub to use the correct naming convention. This should be the MIG's sys_rst port. Do you set the clocking wizard input clock source to No Buffer? I might be missing where this happens in the guide. Not positive if the setting is ignored in this case, but warnings or errors can crop up on Zynq devices if a clocking wizard is fed by an fclk pin and the input source is left as a single-ended clock-capable pin. Which version of the Arty A7 board files did you work with? I imagine that either 1.1 or 1.2 will be fine with the guide since you change the MIG configuration. On the off chance that someone uses v1.1, they will need to manually set the clock period to 3077 ps on the "Options for Controller 0 - DDR3 SDRAM" page of the MIG configuration. It's also notable that having a clocking wizard fed from a "clean" 100 MHz signal should make it easier to generate a 25 MHz clock for the Ethernet reference clock when attempting to follow the Microblaze servers guide. The approach recommended by this guide, https://digilent.com/reference/programmable-logic/guides/getting-started-with-ipi, a "loopback" configuration where the PLL inside of the MIG is used to generate the reference clock, isn't quite able to do this the same way - the frequencies for the clocks output from the MIG are calculated based on the 3077 ps period, rather than on the 325 MHz frequency. This leads to weird rounding errors in how the clock frequencies are displayed in the block design, and can make it look like a 25 MHz clock generated off of the "324.99 MHz" clock is out of spec for the Ethernet PHY, at something around 24.8 MHz. It's more complex than what I've just described, since some displayed frequencies are derived from periods and some periods are derived from frequencies, and the MIG wizard doesn't seem to tell you what the underlying representation is. Post-implementation clock reports will show that the frequencies are actually okay, but the UI is misleading until you've nearly finished generating a bitstream. This is all to say that your implementation looks great since it lets you divide more clocks that show their frequencies correctly off of the 100 MHz system clock. For reference, this is what the alternate approach looks like after the MIG clocks are wired up (image comes from the baremetal software guide, linked above): Do you mind if we link to your guide from the reference site to help point others in the right direction? Thanks! Arthur
  13. artvvb

    Pmod HB5

    Hi @aceblen Please check this guide: https://digilent.com/reference/programmable-logic/guides/getting-started-with-vivado. Any top-level ports in your design can be wired to a Pmod port by constraining them to the associated FPGA pins. The section of the guide on adding an XDC file to your project will cover how to do this. The guide presents Verilog, but the process is the same for VHDL - add a template constraint file, take the name of a top-level port in your VHDL source, and replace the name of a Pmod pin in the get_ports call on the line that corresponds to the Pmod pin, and uncomment the line. Thanks, Arthur
  14. Hi @bobvogt1961, There aren't many directly equivalent boards - the microprocessor line was EOL'd some years ago - however, there might be some other products that would be suitable. Digilent and Measurement Computing got merged together still fairly recently. There are various dedicated DAQ and data logging products that might be suitable - this page has an overview: https://digilent.com/shop/about-mcc-daq/. I asked some colleagues, and it sounds like depending on your application (particularly your channel count and specific sample rate requirements), there are various things that could fit. Raspberry Pi HATs (like MCC 172) and the E-1608 both came up. Cheaper FPGA boards might also work, but it would be a lot more of a pull to get running, and likely be overkill for your sample rates. Thanks, Arthur
  15. I'm not familiar with SpaceWire. The Pmod ports won't successfully recover a 100 MHz signal. The top speed hasn't been characterized, but is likely less than 25 MHz and north of 10 MHz. 1. It will negotiate for 100/1000 Mbps links, but I am unsure if it can sustain data rates close to this. 2. Yes, TCP/IP, though the library should also support UDP. 3. I believe telnet only. There's some more info in XAPP1026, here: https://docs.xilinx.com/v/u/en-US/xapp1026. Also in the template application project's README. Other examples that use the lwIP library may also be helpful (though Digilent has not tested them): If the data rate is over 100 Mbps, DMA is probably required. The DMA Audio demo for the Zybo Z7 might be a starting point. It takes data coming in from the audio codec, puts it into an AXI stream, and then uses an AXI DMA controller to send data from that AXI stream to PS-accessible DDR memory - there're all sorts of finicky details about how this transfer works under the hood. There are also plenty of other approaches for PS/PL data transfer, depending on the specific data rate needed, and on how "bursty" the data is. Thanks, Arthur
  16. Hi @Reckon1ng The NERP_demo_top module instantiation is missing the ground_touch input. Assignment of signals in a module instantiation using an ordered list instead of explicitly using the names of the module ports is an easy way to introduce errors. In this case, the clock is being connected to the logic associated with the ground_touch input which causes something that doesn't meet the FPGA architecture's requirements to happen. Try this in XADCdemo.v: NERP_demo_top flap1 ( .jump_btn (up), .down_btn (down), .enable_btn (enable_btn), .rst_btn (rst_btn), .jumprate1 (c1), .jumprate2 (c2), .jumprate3 (c3), .ground_touch (), // Not driven, tie high or low (1'b1 or 1'b0 inside the parentheses), or connect to some other signal .clk (CLK100MHZ), .clr (clr), .seg (seg), .an (an), .dp (dp), .red (red), .green (green), .blue (blue), .hsync (hsync), .vsync (vsync) ); Edit: For debugging purposes for catching this kind of thing, reviewing the design in Vivado's RTL Elaboration -> Schematic view can be helpful. Thanks, Arthur
  17. This is correct, both can be used with just these cables and no additional external hardware - the cable Digilent stocks is p/n 310-053. Drivers come with a Vivado installation. Thanks, Arthur
  18. Hi Chris, The Ethernet PHY on the Zybo Z7 is connected to Zynq PS instead of the PL (the subsystem IP would potentially be used if it was on the PL side). This means that there are very few steps required to get a Vivado project that will support Ethernet - the board preset applied during block automation already enables Ethernet. This tutorial for running Xilinx's LWIP TCP echo server example was recently updated: https://digilent.com/reference/programmable-logic/guides/zynq-servers, and this blog post extends off of it to do pretty much exactly what you are talking about with streaming bytes back up to a host via a Python script: https://digilent.com/blog/getting-out-of-the-echo-chamber-transferring-data-over-ethernet-using-zynq/. Thanks, Arthur
  19. artvvb

    2 PMOD BLE Modules

    Hi @Razvan1203 This isn't an application anyone at Digilent has tested. That said, it looks like there is some information in the RN4871 user guide on establishing a connection between two modules (section 4.3, page 61): https://digilent.com/reference/_media/reference/pmod/pmodble/rn4871_user_guide.pdf. To connect on power on, you'd either need to run an application on the host that communicates with the BLE module over a serial interface at startup to establish the connection, or use a power-on event to trigger embedded scripts on the BLEs themselves that can establish the connection (section 3.1, page 53). Thanks, Arthur
  20. As detailed further in this thread, Digilent-provided materials for the Pcam 5C only support the RAW10 format. I've reached out internally to update our store page to this effect. Apologies, Arthur
  21. No loops or reduced jogs may help somewhat with the interface routing mess. No loops makes it harder to tell at a glance what pins/interfaces are inputs and which are outputs. The regenerate layout button will also shuffle everything around to try to fit it on screen, which is a blessing and a curse.
  22. This is the selection menu for different views, I think what you're seeing as differences in block design are based on having interfaces selected:
  23. 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.
  24. Hi @Suprith The reset button on the Arty Z7 is not directly connected to the FPGA PL. Reviewing the schematic, the reset button, connected to the PS_RST net, triggers the PS side of the chip to reset and drives a reset on the CK_RST net, which is connected to the shield header reset pin. CK_RST is also connected to PS MIO12, however, this would not allow the PS to read a reset button press, since the upstream PS_RST will be applied. Reset signals within the FPGA can alternatively be driven by resets associated with the FCLKs. Thanks, Arthur
  25. Hi @Jonathan20 No, Digilent doesn't provide any Pmod -> Pcam adapters. The options are either a Zybo Z7 or a host board that supports the FMC Pcam Adapter. Thanks, Arthur
×
×
  • Create New...