Jump to content
  • 0

Working with DA4 PMOD on Nexys4


advisor

Question

Hello!

 

I have created some VHDL code (attached) to test if DA4 convertor works. The simulation reveals no problems with timing of SCLK, DATA and SYNC channels according to the AD5628 data sheet, however output of the eight out data pins of DA4 does not work.

 

Basically I am trying to send the the data to JB PMOD. Command and address are tuned by the eight switches on the Nexys4.  The used command is 0011 and the address is 1111 (is that correct, by the way?), but I have tried plenty of other commands. Still the problem persists — no out data from DA4.

 

Please do not hesitate asking for additional information.

 

Thank you for your help.

pmod.vhd.txt

Link to comment
Share on other sites

13 answers to this question

Recommended Posts

Hi,

 

Having worked with the PmodDA4, I believe I know what issue you are running into, but please correct me if this is not the case.  You are correct in that the update DAC address command is 0011 and that the value for all eight outputs is 1111.  However, the on board DAC assumes by default that it is using an external voltage reference on one of its pins.  

 

Since it rather inconvenient to use an external reference voltage for the chip, what you will need to do is send a command to use its internal reference voltage of 2.5V.  This 32 bit message you will need to send in four 8 bit chunks is 00001000 00000000 00000000 00000001.  

 

You can see the data sheet reference for this command on pages 24 and 25 for the DAC (http://www.analog.com/static/imported-files/data_sheets/AD5628_5648_5668.pdf)

 

Let me know if you have any other questions.

 

Thanks,

James

Link to comment
Share on other sites

Hello Josh.

I am electrical engineer and programmer by education, but I am new to digital electronics and FPGAs. I have acquired some initial experience by learning book “Digital Design Using Digilent FPGA Boards. Verilog/ Active –HDL Edition” by Richard E.Haskell and Darrin M.Hanna from 2012. I have implemented many examples from the book on BASYS2 board that I have.

Now I would like to see voltages on outputs of PmodDA4 that I connect to my BASYS2 board. For beginning I will be satisfied with direct (permanent) voltages. I have been trying few versions of code and didn’t succeed.

Please, advise – what is wrong? May be many things…

I will try to describe you my logic in details and will send my code too.    

I use Verilog. I connect PmodDA4 to JA connector of BASYS2 board.

I have to create 3 correct signals: SYNC, DIN and SCLK.

According to documentation I assume that

1. SYNC: JA1 (B2) – pio<72> in ucf file.

2. DIN: JA2 (A3) – pio<73> in ucf file.

3. SCLK: JA4 (B5) – pio<75> in ucf file.

Default frequency of a board is 50 MHz. I use half of this frequency – 25 MHz as a SCLK signal.

I understand logic of operation so: if SYNC is high – data from signal DIN does not go into internal register of PmodDA4.

After SYNC went low – data starts to go into internal register of PmodDA4. It goes into PmodDA4 on each negedge of SCLK and it counted by PmodDA4. By data we mean signal DIN: 0 or 1. After transferring 32 bits into internal register of PmodDA4 we have to change SYNC on high. May be that not necessarily to do right away after 32 accumulated bits, but I do that in my code, because in any way we must bring SYNC high for min 15 ns and after low for initiation of a new cycle of writing data into internal register of PmodDA4.  I control that process by variable count.

I simulated the process with Aldec simulator and visually it seems to me correct. I assume that bit db31 on a page 7 of http://www.analog.com/media/en/technical-documentation/data-sheets/AD5628_5648_5668.pdf is a first bit in time among 32 bits that is clocked into internal register of PmodDA4.    

Here is a sequence of 32 bits that I try to produce, taking your notice about using Internal source of power.

Don’t care bits db31, 30, 29, 28: 0000.

Command bits db27, 26, 25, 24: 1011.   

Address bits db23, 22, 21, 20: 1111 – command for having voltage on all 8 outputs.

For AD5628 12 bits db19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8 equal to 1 for max output voltage: 111111111111.

And last 8 bits db7, 6, 5, 4, 3, 2, 1, 0: 00000001.

As I understood your notice bits db27 and db0 have to be 1 – for using internal voltage as a source.  

Kind regards,

Vladimir

Basys2_PmodDA4_code.txt

Link to comment
Share on other sites

Hi Vladimir,

From my understanding, you have the right idea on how to get the data sent to the PmodDA4. What I do notice is that you have combined the two commands together; both the command to use the internal voltage along with the command to send a maximum output voltage on all of the channels. The Analog Devices chip present on the PmodDA4 is not able to handle both commands simultaneously.

So what you will need to do instead is to send the two commands separately. First the internal voltage command (don't care bits - 0000, then Command bits -1000, then some more don't care bits in the place of address bits - 0000, then more don't care bits in the place of the output voltage 000000000000, and then the final 8 bits - 00000001) will need to be sent by itself. Then you may send the command to produce the maximum voltage on all available outputs (don't care bits - 0000, command bits - 0011, address bits - 1111, ouptut voltage bits - 111111111111, more don't care bits - 00000000)

Let me know if you have any more questions.

Thanks,
JColvin

Link to comment
Share on other sites

James, thanks a lot for your quick reply on my question.

I understand what do you mean. Only I would like to clarify my task.

I will describe to you my logic as I understand now.

My program now sends the same 32 bit sequence to the PmodDA4 - the same and not correct sequence, because it combined two commands in one.

Am I right if I say, that it should be sequence of 2 commands that will be repeated again and again: 32bit_command_for_using_internal_voltage, 32bit_command_for_using_all_outputs? 

I will try that for now, while waiting answer on my questions. 

 

Link to comment
Share on other sites

Hi Vladimir,

You only need to send the 32-bit command for using the internal voltage once for each time the Pmod is connected to a power source.

If you only want the maximum voltage output on all 8 outputs, you will also only need to send that command once for each time the PmodDA4 is connected to a power source.

If you disconnect the Pmod from a power source, you will need to send the two commands again because the on-board Analog Devices chip will revert to it's default settings.

Let me know if you have any more questions.

Thanks,
JColvin

Link to comment
Share on other sites

Hello James.

Thank you very much for following my questions. 

According what you said - answer on my previous question is No.

I don't need to send continuously 2 commands - but only once.

I will try that approach now. I will change my code. I realized that I don't need to organize each command in code as I do.

It will be easier to put each command as a parameter - constant and then to read each bit from that word at posedge of the clock.

After first command will be sent, sync will go High for few periods, after Low and I will send second command. And it should be all.

I think I will add button Go to perform that operation in one method and some logic to do that only once. 

This is my plan. It will take a some time, but I will certainly will let you know about my progress. 

Thanks,

Vladimir.  

Link to comment
Share on other sites

Hello James.

I would like to thank you very much for advises. It seems as it started to work. I even crossed my fingers. Although it works.

In my code I have these lines:

//first command1 to use internal voltage

initial command1 = 32'b00001000000000000000000000000001;

//in second command2 first 2 bits: 11

//next 4 bits: 1111 - to use all 8 outputs

//next 12 bit are '1' - to produce full voltage. AD5628 uses 12 bits to define value voltage from the max voltage.

//initial command2 = 32'b00000011111111111111111100000000; // max voltage – 2.5v

//initial command2 = 32'b00000011111101111111111100000000; // half of max voltage – 1.25v

  initial command2 = 32'b00000011111100111111111100000000; // fourth of max voltage – 0.625v = ~ 0.63v

First of all finally I saw an output voltage, initially max value = 2.5v. Secondary by changing value of command2 I saw different value of output voltage and that gave me more conformation that code is working.

I am attaching my current code: Basys2_PmodDA4_code1.txt.

Nevertheless I am not completely satisfied with code and I am going to experiment different things by changing the first version.

I would like to ask you few questions:

1. I finished my code by bringing sync signal to high and parameter done =  1.

Please advice – how better to let program know that it really completed?

In this new for me world of digital programming it seems as method continues to work in infinitive loop. With done = 1 it goes inside of always @ (posedge clk) any way, but inside because of done = 1 it does nothing, avoiding part of code.  

Can it be improved?

2. Can we receive negative voltage here? If yes – how?

3. Of cause whole purpose of this exercise is to control the voltage as a function of time. So it should be some external method where we are watching the time and reload commands. Is that correct?   

Thanks,

Vladimir

Basys2_PmodDA4_code1.txt

Link to comment
Share on other sites

Hi Vladimir,

I am not the most experienced with FPGAs so I will not necessarily be able to offer any specific help in terms of the code. 

As for better letting you know that the program has been completed, perhaps you can turn on one of the LEDs on the Basys 2 once the "done" parameter is true.

From what I can tell from your code, there is currently nothing else to do once done = 1, so I'm not sure what part of the code is being avoided. In terms of improvement, it would depend if there is something else you want your program to do. If you wanted it to cycle through different output voltage levels, you could write some code to do that with a command3 and command4 (if you so choose to use those parameter names) and and some sort of delay inbetween the changes.

You will not be able to output a negative voltage with this Pmod; it can only output a voltage between 0V and the supplied reference voltage. (2.5V in our case since we essentially have to use the internal reference voltage)

I looked through the book you mentioned, but I didn't see any exercise that involved voltage over time, but I'll presume you have something. As you know, for the PmodDA4, you will have to keep loading new voltage values when you want the voltage to change. In terms of having them change with time, you can do it in one of two ways (at least as far as I am aware). You may use an external timer of some sort and then press a button or flip a switch (or something similar) on the FPGA when you want the voltage value to change. I would probably instead try to create an internal timer in the FPGA that sends a new command once the set time (or delay) is reached.

Let me know if you have any more questions.

Thanks,
JColvin

Link to comment
Share on other sites

Hello James.

Thank you for the last answer on my additional questions. I am completely satisfied with your answers and will continue my investigations from here. 

Thank you again for your help. I really moved ahead. Program started to work due to your main advice to use 2 commands, instead of one.

I don't have other critical questions for now.

Warm regards,

Vladimir.   

Link to comment
Share on other sites

Hi,

I have tried to create a VHDL code for the DA4; and I have followed all that has been discussed here. However, I don't get any analog signals on any output channel! Can someone please help with this? I have tried with both internal (x"08000001") and external (x"08000000") references. 

 

Thanks,

Mohsen

 

DA4_v9.vhd

Link to comment
Share on other sites

Hi @Mosi_513

Simulating your design will help a lot in debugging the issues with it. For example, it looks like your clock_divide process is actually dividing the clock by 12, not by 5. The counter counts from 0 to 5, and on 5 (the 6th iteration), it toggles the clkdiv signal. Doing a toggle like this doubles the period of the enable strobe, so the main process only actually activates every 12 cycles. See the attached screenshot. I have also attached the testbench I used, which should help to get you started.

There are likely other issues that I haven't spotted yet, but using the simulator will take you a long way.

Thanks,

Arthur

image.thumb.png.44e2d1b8f467f47471ab33cd8c5d6fd4.png

testbench.vhd

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...