• 0

Basic verilog question - hardware driver for an AD7606 and the "always" block


Question

Greetings All!

I'm trying to write my own verilog custom IP in Vivado for interfacing with an AD7606 ADC (8 channels, 16 bits, simultaneous sampling).  The basic idea of my timing diagram is as follows:

-Raise the CONVSTART pin from an EXTERNAL source (conversion will start on a positive edge)

[Verilog module starts in an IDLE state]

1.Wait for the negative edge of the "BUSY" input pin from the AD7606

2. Drop !CS (chip select) LOW

       3. Drop !RD (read) LOW, wait at least 100 nanosec

       4. Raise !RD high, read channel 1 result, wait a least 100 nanosec

        [Repeat steps 3 and 4 seven more times to read channels 2 through 8]

5. Raise !CS high

I am making the above into a verilog state machine.  I know that I need a clock (100MHz on my board) for the 100 nanosec delay states.  My state machine STARTS with the negative edge of the BUSY input (step 2), but it also needs to accept the clock. 

--> I don't think I can use both edges "always @(posedge clk)" and "always @(negedge BUSY)" to drive my state machine.  How can I, somehow, combine these to trigger my state machine?

Edited by rt54321
Link to post
Share on other sites

4 answers to this question

Recommended Posts

  • 0

My reaction from reading your post is that you should be working on basic Verilog skills before trying to control actual hardware.



ADI has example projects, with HDL sources, for most of the AD7606 type devices. If you want to learn Verilog you should take advantage of ADI's better than average FPGA support for their devices. I recommend that you use a development platform as similar to ADI's release that your want to use and recommend that it be a Linux as ADI uses MAKE, which happens to be a pretty good way to manage such projects. You should also use the same Vivado tools version if you aren't prepared to resolve issues. One thing that ADI could do a better job of is their documentation ( who couldn't do a better job of that? ) as it might not be clear about all of the dependencies that you need to install before using their HDL repository.



I've designed a few projects using devices in the AD7606 family and the interface isn't especially difficult. You shouldn't be using both edges of your logic clock as this has ramifications for meeting timing. Advanced FPGA developers might on rare occasions do this if they understand the ramifications. If your state machine requires both edges then you need to rethink your design strategy. Using both edges of a clock for IOB for DDR applications is different than using both edges of a clock in your CLB logic.



I;ve been doing FPGA designs for a long long time and still encounter situations that drive me to expand or improve my HDL comfort zone. There's nothing wrong with running into obstacles that come your way. Just take them as an incentive to broader your skills.

Edited by zygot
Link to post
Share on other sites
  • 0

I misread your question so my comment about using both edges of a clock for your logic is not relevant.

Why do you want to use edge detection for the BUSY input? If you relax your conceptualization of your state machine timing it might be simpler to implement.

I often want to detect edges of input signals. One way to do this asynchronously is to feed the signal into a short pipeline or shift register clocked by the same clock as my state machine. You can then use simple logic to create a strobe that is one clock wide near either edge of the signal of interest. The strobes then an be used in a state machine where you need to know about transitions from 0 to 1 or 1 to 0.

For the case of the AD7606 the BUSY signal indicates that a conversion is is progress in response to as asertion of the CONVST input. This simplifies your use of the BUSY signal. For general purpose use the technique that I described above has to take into consideration a number of things like clock domain crossing when relevant.

Edited by zygot
Link to post
Share on other sites
  • 0

Greetings Zygot,

Thank you for your help!  Indeed, this is a beginners question, and I have followed your advice regarding how to sense the negative edge of the "BUSY" input:

[pseudo code here]:

if ( (BUSY == 0) and (BUSY_LAST == 1) ) then "The ADC is no longer busy, so commence the state machine to read the results"

...Read the ADC inputs blah blah blah...

(and finally): BUSY_LAST = BUSY  //Remember the current BUSY value for next loop iteration

 

 

 

Link to post
Share on other sites
  • 0

Don't forget to simulate your code using testbenches. If you haven't been exposed to using a simulator @Tim S.has been very busy the past year or so posting excellent examples in the Diligent Project Vault that you can look through and learn from. Writing an effective testbench is often harder than writing the HDL source that it tests. Unfortunately, there isn't a lot of good information on verification which is why I mention those in the Project Vault.

A digital simulator is good for more than seeing what's happening with your code. I'm currently working on a project that takes 30 minutes to generate a bitstream. I can run most simulations in a lot less time. If your fingers are as uncooperative as mine and your code has lots of typos, a simulator will help you wade through the silly stuff a lot quicker than generating a bitstream.

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now