I am trying to produce a sine wave using the DAC of a ZYNQ board (red pitaya). It is important that I have accurate control over the phase of the signal that I am producing.

I would like to do this as follows:

  1. Generate the signal (samples) with a program that runs on the CPU.
  2. Transfer the samples to a block ram in the logical part of my design.
  3. Clock the samples out of the block ram and into the DAC.
  4. Repeat the above.

My current setup is based on Anton Potočnik's tutorial:

enter image description here

The heirarchy "dac_side" contains some IP cores for memory management and a signal generator: enter image description here

and the following memory addresses have been assigned: memory addresses

I have no problem controlling the LEDs via the GPIO port at address 0x42000000.

Writing the samples of a sine wave into 0x42400000 results in short bursts of 20 MHz sine waves that completely fade away within a few cycles (possibly some kind of impulse response).

Writing the samples to 0x42430000 results in the following error message:

Unhandled fault: external abort on non-linefetch (0x818) at 0xb6f42000
pgd = d84bc000
[b6f42000] *pgd=18a09831, *pte=42430743, *ppte=42430c33
Bus error

The fact that I have the choice between two addresses is already a sign that I haven't configured the IP cores for memory management correctly. Also, I currently don't have any control signals in order to specify when the processing system is writing to the BRAM and when the DAC should read out the values from the BRAM. Maybe these kind of tasks are handled by the AXI BRAM Controller, or maybe my Block Memory Generator should have two ports and I should be connecting a second AXI Bram Controller.

My question:

How should I be connecting the Block Memory Generator in order to achieve the sequency (1, 2, 3, 4) described above?


1 Answer 1


Your whole set-up does not make sense to me.

In cases like this follow KISS: Keep It Simple and Stupid.

Make a dual ported block ram memory which has an AXI interface on one port. This lets the CPU write (en possible read) your memory.

Tie the other block ram's port read signal active (always read) and put a counter on the second address bus. Connect the DOUT of the memory to your DAC data input.
You now have the core of a function generator.

Ideally you should make the counter run at different (programmable) speeds to get different frequencies. You should also set a start and end value so it loops between specified addresses. But all that can be postponed until after you got the core running.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.