Jump to content

artvvb

Technical Forum Moderator
  • Posts

    1,063
  • Joined

  • Last visited

Everything posted by artvvb

  1. Hi @skinnypanda Take a look at the "Language Templates" menu in the tool. There's both some example code for inferring BRAMs as well as some templates for instantiating BRAM primitives directly. Thanks, Arthur
  2. The voltage provided by a microphone tends to be quite low. You could potentially amplify the signal before it reaches the I2S2, multiply it up in the FPGA (resulting in a poor quality signal, since you are only effectively using the lowest couple of bits), or try out your project with a cable connected to a computer's audio out. I'd recommend the latter if you happen to have a 3.5mm-3.5mm cable lying around. Getting a bunch of samples dumped into block RAM and then potentially out over UART or into the ILA in a burst could be a good way of looking at more than just one sample at a time. Could potentially also wire something up to look for the minimum and maximum values received in the incoming data. Thanks, Arthur
  3. @Jan Kager It looks like the constraints for the top and bottom row of the Pmod port are swapped. I don't have a Pmod I2S2 to test with at the moment, but was able to get the transceiver core running with your constraints and a Pmod I2S (which uses the same CS4344 chip used in the I2S2's line-out) connected to the bottom row of port JA. I've attached the Verilog module I used to generate the audio output data for testing, as well as a screenshot of the block design. Please also check that your MST/SLV jumper is in the SLV position, since the transceiver core generates the clocks for the line-in chip, rather than taking them as input. Thanks, Arthur module audio_test_pattern( input clk, // 11.29 MHz mclk input lrck_in, // 44.1 kHz lrck output [23:0] count_out ); reg store; wire enable; always@(posedge clk) begin store <= lrck_in; end assign enable = store & ~lrck_in; reg [23:0] count = 0; assign count_out = count; always@(posedge clk) begin if (enable) begin count <= count + 24'd100000; // the counter rolls over at ~262 Hz end end endmodule
  4. Hi @rmccormack1 Something in the project is misconfigured. Undefined reference to main implies that either the "int main (void)" pattern of the definition isn't the one that the tools are looking for - maybe the application was created using a C++ template, or some other template that doesn't work for your code. It's also possible that the source file isn't in a directory that the tools are looking in for sources. Console logs and/or a project archive would help me to figure out what exactly is going on. Thanks, Arthur
  5. Hi @rmccormack1 This error message means that the project's build outputs don't exist; either the project hasn't been built, or it failed to build. The processor exists (probably), but the file that its supposed to run doesn't exist. Either way, there is nothing to be run on the device. If you can provide either the Vitis console logs or an exported ZIP archive of the project, I might be able to determine why the required ELF file is missing. Thanks, Arthur
  6. Hi @rmccormack1, Can you export your projects to a ZIP file and post it here? Errors that appear as makefile errors like this one may indicate that something in the board support package is failing to build properly, which would imply either a problem with the Vivado project and XSA, or with the configuration of one the software projects. It could be missing stdin, or it could be one of a couple other potential issues not directly related to the posted source code. Alternatively it might be down to xil_printf.h not being included, though I haven't managed to reproduce your error message. Thanks, Arthur
  7. Adding fuel to the fire: Whether or not the tick pulse appears depends on whether you use non-blocking or blocking assignment in your testbench. If you observe the signals inside the mealy_edge_detect module as well, you can see that the state register is toggling as expected, but that since there is no delay in the simulation between the level rising edge and the state transition (when blocking assignment is used), the tick pulse never fires (or in reality very briefly fires, as you mention). -Arthur
  8. Hi Sheraz, I think that MAX_PKT_LEN is primarily there to inform the drivers about the size of the chunk of memory that it is allowed to put data into - it should match the size of the array that RxBufferPtr is pointing at, which also needs to be equal to or larger than the size of the longest packet that might be received, 2 words in this case. The missing bus interface is likely due to not including the [vivado-library](https://github.com/Digilent/vivado-library) repository as an IP repository in the project - it contains the definition of the Pmod interface used in the board files. That said, getting the Pmod interface working with a custom IP takes extra work that is not necessary here. I'd recommend either using the Pmod Bridge IP contained in vivado-library to connect to GPIO interfaces on your custom IP and to the board file interface, or to remove the Pmod interface entirely and just manually constrain the individual pins (which would then not be associated with any interface). Thanks, Arthur
  9. Hi @rmccormack1 Your verilog code has some issues. For example, writeCounter, readCounter, and Count should never hold the value of 8 - required to have some of the if statements and ternaries do anything - since they are all three bits wide, meaning that FULL is never asserted. The block design also presents issues, depending on your constraints. What pin locations are all of your ports connected to in your XDC? The prog_txen port should only be a single bit wide, and you are entirely missing the prog_d data bus. The USB104 A7's reference manual has some more information on which ports should be used when working with the DPTI interface. https://reference.digilentinc.com/programmable-logic/usb104a7/reference-manual#dpti_parallel_data_transfer_interface It might be worthwhile to make sure that you can send data through the DPTI in one direction before attempting the loopback - something like writing an incrementing stream of bytes into the USB controller's emulated FIFO from the FPGA and using the Adept API to read them on the PC side. As an analogy, it would be more difficult to design a UART transmitter/receiver and a loopback than it would be to just make a transmitter, make sure it works, then design the receiver, make sure it works, then combine the two. Thanks, Arthur
  10. Hi @westman The DDR Clock pin is intended to be connected to the MIG's sys_clk_i input. The MIG preset also is configured such that ui_addn_clk_0 is (near enough to) 200 MHz and can be used to drive ref_clk_i. The rest of the Microblaze design should be driven by the MIG's ui_clk or another clock derived from it. There's also a current issue that prevents the sys_clk_i input from being connected to the DDR Clock board interface, where the workaround is to instead manually constrain the port with an XDC file. There are some instructions on wiring the MIG up like this that can be found here: https://reference.digilentinc.com/programmable-logic/guides/microblaze-adding-ddr. Edit: "Microblaze held in reset" implies to me that the polarity of the reset may be incorrect, please check the IP ports that the reset interface is connected to and make sure they are expecting it to be active low. Thanks, Arthur
  11. Hi Sheraz, I'm not sure if anyone around here is familiar with that particular I2S IP, as it looks like it was released quite recently. As you might have seen in other threads and on the I2S2's resource center, there are a couple of different I2S demos/examples we've put together over the years - I recommend starting with these instead. That said, I'll try to provide some general comments on potential issues in getting this IP connected up: The AXI-stream master interface needs to be connected to something downstream to consume the data - this will be how the audio data exits the receiver. An AXI DMA is a common way of pushing this data into DDR so that the Zynq PS can do stuff with it. Since the I2S IP's stream interface doesn't have a tlast signal, you will need to provide that yourself - probably requiring something along the lines of detecting the start/end of a block based on the values in tdata (but I'm not sure). The aud_mclk input should be connected to FCLK_CLK1 and to an external port. The _axis_ clock should likely be connected to FCLK_CLK0 (and the _axi_ctrl_ clock), with the reset getting tied to the AXI control reset. irq needs to be connected to the Zynq's IRQ_F2P interrupt port, which needs to be enabled in the Zynq configuration. Thanks, Arthur
  12. Hi @rmccormack1, There's an not-yet-fully-released version of the board files that helps to fix it available here: https://github.com/Digilent/vivado-boards/archive/refs/heads/Microblaze-MIG.zip The solution is to reconfigure the MIG to accept a 100 MHz system clock (avoiding the upstream clocking wizard entirely, and just connecting the system clock to the 100 MHz clock pin) and produce it's own reference clock. This also entails constraining the sys_clk_i port in an XDC and, in the case of the USB104, either tying off the sys_reset or connecting it to a button through an inverter manually. I've attached a working Vivado 2020.1 project. Thanks, Arthur USB104A7-MIG.xpr.zip
  13. Welcome to the forum. Unfortunately we don't currently have a manual available for the I2S IP. Likely the best source of information about the register set at the moment is going to be the name/address enums in the audio.h source files in the demos using the IP. Thanks, Arthur
  14. Hi @Sheraz Mainly, one, make sure that your packets can fit in the DMA buffer, as set in hardware by the AXI DMA's buffer length register width parameter. Two, make sure that the number of bytes specified by the third argument of the XAxiDma_SimpleTransfer calls matches the actual length of your packets in bytes (not transfer beats). If tlast doesn't show up on the transfer beat that the DMA is expecting (based on that third argument), then the IP can lock up. How is your AXI DMA configured? Thanks, Arthur
  15. @Zzingoh It looks like this thread on the Xilinx forum may have more information on this topic: https://forums.xilinx.com/t5/Processor-System-Design-and-AXI/FMC-single-ended-signal-routing/td-p/808012 Thanks, Arthur
  16. Hi @palmervb I tested the 2020.1 page's steps in Vitis 2020.2 today, and it is now functional. There was a step missing which was preventing the Vitis project from building due to some incorrect paths which must be manually updated. These steps have now been added to the document. Please make sure you are using the release files linked from the 2020.1 page. When opening the Vivado project (as the optional steps discuss), you are likely to also need to use the Tools > Report IP Status option, upgrade all IP, and (maybe) make changes required by new versions of the IP in the project. This is what the warning about major version changes in an IP is indicating. If an IP version goes from (for example) 4.1 to 4.2, the minor version has incremented, and typically won't require changes to the design. If the IP version goes from 2.1 to 3.1, then the major version has incremented and changes are likely required - potentially some port on the IP's name has changed, or a configuration parameter has a different name, or there may be some major functional change that requires additional changes to the surrounding hardware design. In any of these cases, it likely requires going to the datasheets of the IP involved in order to get it working in the new version. Thanks, Arthur
  17. Hi @Zzingoh The VP/VN signals are dedicated analog inputs and should not be used for your digital SPI signals. Descriptions of each of the analog-capable pins can be seen on page 16 of the XADC user guide (https://www.xilinx.com/support/documentation/user_guides/ug480_7Series_XADC.pdf). Using differential signals requires you dedicate two package pins to each signal (you would have separate constraints for spi_clk_p and spi_clk_n, for example), and likely requires you to explicitly instantiate differential buffers in your design. The device on the other end of the connection would also need to be differential. I'm not 100% certain, but it could be that you are starting to run into the speed limitations mentioned in the reference manual for the board. Thanks, Arthur
  18. Hi @Joe_01 I've attached ZIP files with 2020.2 projects for the baremetal demos for the Zmod ADC and Zmod DAC, and the vivado project supporting both of them. Note, I have not tested this in hardware. You can also take a look at an updated version of the IPI getting started guide written for 2020.1 (there should be only minimal differences): https://reference.digilentinc.com/programmable-logic/guides/getting-started-with-ipi Thanks, Arthur vitis_export_archive.ide.zip hw.xpr.zip
  19. Here's the mentioned example, connecting the Pmod OLED to the Cmod A7 through the Pmod port. Notably, the project uses the Pmod bridge IP to connect the QSPI to a board interface. Drivers are pulled from the IP core for the Pmod OLED. The Vitis workspace can be opened by importing projects from the .ide.zip file. Some screenshots of the section of interest of the block design and IP configurations are also attached, in case the tool version doesn't allow the project to be opened. -Arthur 21582.xpr.zip cmod-a7-pmod-oled.ide.zip bd-screenshots.zip
  20. Hi @Elisheva The result port in your VHDL design is 24 bits wide, and should not be directly connected to the UART pin. You need to add a UART transmitter to the hardware design that can produce the correct wave to send those three frames through the single pin. The individual result bus ports do not currently have location constraints. If you mapped each of them to a physical pin (probably Pmod ports), you might be able to put data out through those pins to meaningfully read the data (whether with LEDs or something else). Fundamentally, you need to figure out how you want to get data out of the device, and add hardware to the design to aid that - whether using a logic analyzer or LEDs to read off of GPIOs, or designing a UART controller to serialize your parallel data. Thanks, Arthur
  21. If the Zynq sample uses the AXI QSPI IP core, the software sources should nearly work as-is on Microblaze (typically with some additional calls to enable/disable caches if you are using them). If it's using the PS SPI instead, then that's different. For a relatively simple case of using the AXI QSPI, you can take a look at the drivers for the Pmod AD5 IP: https://github.com/Digilent/vivado-library/blob/master/ip/Pmods/PmodAD5_v1_0/drivers/PmodAD5_v1_0/examples/main.c https://github.com/Digilent/vivado-library/blob/master/ip/Pmods/PmodAD5_v1_0/drivers/PmodAD5_v1_0/src/PmodAD5.c https://github.com/Digilent/vivado-library/blob/master/ip/Pmods/PmodAD5_v1_0/drivers/PmodAD5_v1_0/src/PmodAD5.h The following configuration should be good enough for a lot of devices, given the correct external clock, and use of the drivers. Chapter 4 (starting on page 87) of the Xilinx product guide for the core has some more info on how to configure it, which is linked from its product page: https://www.xilinx.com/products/intellectual-property/axi_quadspi.html. -Arthur
  22. Hi @RichardV Could you clarify what you mean by "the QSPI port"? You can create your own SPI controller and have it use any of the Cmod's IO pins - constraining the pins with an XDC instead of through the board files. The AXI QSPI IP can similarly be connected to various external pins, on the Pmod port, breadboard connector, pretty much wherever (but should be used with a Microblaze processor). You can configure the AXI QSPI to work in standard SPI mode (SPI Options: Mode = Standard instead of Quad). Thanks, Arthur
  23. Hi @jungle AXI lite and full are memory-mapped interfaces, while the AXI stream interface is not. As such, you won't find the streams in the address editor. DMA is a good way to connect an AXI stream to one of these memory mapped interfaces. To send data to this stream, you should then be using the xaxidma drivers to set up and trigger the transfer. The DMA IP acts as an intermediary: for simple transfers, the processor hands it an address and a transaction length, and it reads each word of data out of that region of RAM, and sends it down the AXI stream. Can also note that the DMA IP contains block RAM buffers. There are some DMA audio demos for other boards (like for the Zybo Z7) that take this approach, and that should be useful for reference. There's an AXIS IP that handles I2S data in and out that can be found in that demo as well. Thanks, Arthur
  24. Hi Dave, The board files lock in the some of the IP settings. The number of slaves can't be changed when using the board files to constrain the SPI bus, since the board.xml interface and the part0_pins.xml constraints only specify a single chip select pin. I'd recommend using Make External on the relevant pins of the AXI Quad SPI's SPI port, and constraining them all yourself. For what its worth, it looks like clearing the interface selection to Custom in the IP's Board tab will preserve all of the other settings. It may also be necessary to manually add IO buffers into the design (probably in an RTL module between the AXI SPI core and the block design ports) as I'm not positive if Vivado will automatically insert the right buffers for the single tristate, multiple i/o pin pattern of the SS bus. Alternatively, if wasting resources isn't an issue, you could just add a second AXI SPI controller. -Arthur
  25. Hi @davec I don't see anything wrong with your hardware design or the board files. So I spun up a similar design with port J6, working from the polled_example (Vivado/Vitis 2020.1 and version 4.6 of the xspi drivers). Debugging the modifications showed a problem where XSpi_Transfer was silently failing when checking if a slave was selected in the driver, and finding none. Make sure you are calling XSpi_SetSlaveSelect. See my main.c, below. #include "xspi.h" #include "xparameters.h" #include "xil_printf.h" #include "sleep.h" int main() { xil_printf("Hello World!\r\n"); XSpi device; XSpi_Config *pcfg; pcfg = XSpi_LookupConfig(XPAR_AXI_QUAD_SPI_0_DEVICE_ID); XSpi_CfgInitialize(&device, pcfg, pcfg->BaseAddress); XSpi_SetOptions(&device, XSP_MASTER_OPTION); XSpi_Start(&device); XSpi_IntrGlobalDisable(&device); XSpi_SetSlaveSelect(&device, 0b1); u8 bytes [4] = {0xDE,0xAD,0xBE,0xEF}; while (1) { XSpi_Transfer(&device, bytes, NULL, 4); usleep(1); } } Hope this helps, Arthur
×
×
  • Create New...