Author Topic: Nexys4 DDR ADC -> UART  (Read 2752 times)

0 Members and 1 Guest are viewing this topic.

Offline SAI_PeregrinusTopic starter

  • Contributor
  • Posts: 23
Nexys4 DDR ADC -> UART
« on: June 12, 2017, 12:45:51 pm »
What I'm trying to do: Use a Nexys4 DDR board (Xilinx Artix-7 FPGA XC7A100T-1CSG324C) to capture analog signals, do some processing on them, and output the resulting data over USB. The dev board has an FTDI FT2232 onboard, wired for two-wire serial communication. The FPGA has a built-in ADC module, which Xilinx calls XADC. I'm using VHDL because I have somewhat more experience with that than with Verilog. This is part of a project for school, so using a language my advisor / instructor knows well seemed like a good idea.

At this stage, all I want to do is take data from the XADC and send it out the serial port.

I'm not sure how to simulate this thing properly. The ADC never seems to do anything, so the UART never gets started. This has made debugging the issue difficult.

The code I'm using for the UART is mostly hamster_nz's example code with comments added and style changes to make things easier for me to understand.

Xilinx's XADC documentation isn't entirely clear to me. I think drdy_out indicates that data is ready, and do_out contains the data word output. Since I'm running the ADC in continuous conversion mode with the channel sequencer and 4 channels enabled, the documentation seems to indicate that it should cycle through the channels, output data when each conversion finishes, and indicate which channel it came from on channel_out. I don't think I should need to manually change channels by writing the channel address to daddr_in, but I'm not sure on this.

Can anyone help? This seems like it should be simple, but Xilinx are masters at making the simple complicated, and I'm apparently amazing at overthinking things and going in circles...

I've attached a file with just the sources and not the generated mess Vivado spews out.
 

Offline hamster_nz

  • Super Contributor
  • ***
  • Posts: 2803
  • Country: nz
Re: Nexys4 DDR ADC -> UART
« Reply #1 on: June 12, 2017, 08:54:02 pm »
Have a look here if you want: http://hamsterworks.co.nz/mediawiki/index.php/Minimal_XADC_design - it just reads one channel over and over.

You most likely want to use EOC or EOS as a strobe (not to sure about this - I'ld have to check the manual)
Gaze not into the abyss, lest you become recognized as an abyss domain expert, and they expect you keep gazing into the damn thing.
 

Offline hamster_nz

  • Super Contributor
  • ***
  • Posts: 2803
  • Country: nz
Re: Nexys4 DDR ADC -> UART
« Reply #2 on: June 13, 2017, 09:29:19 am »
Had a quick sim... first issues, both in main.vhd:

(Style, no real difference)

Code: [Select]
    constant clk_rate  : unsigned(31 downto 0) := to_unsigned(100000000,32);   -- 100000000, for 100 MHz clock.
    constant baud_rate : unsigned(31 downto 0) := to_unsigned(9600,32);         -- 9600 baud

Actual fault - not setting bit-tick or updating count
Code: [Select]
bit_tick_proc:  process(clk)
    begin
        if rising_edge(clk) then
            if count = clk_rate/baud_rate-1 then
                count <= (others => '0');
                bit_tick <= '1';  -- << Added
            else
                count <= count + 1;  -- << Added
                bit_tick <= '0';
            end if;
        end if;
    end process;
Gaze not into the abyss, lest you become recognized as an abyss domain expert, and they expect you keep gazing into the damn thing.
 

Offline hamster_nz

  • Super Contributor
  • ***
  • Posts: 2803
  • Country: nz
Re: Nexys4 DDR ADC -> UART
« Reply #3 on: June 13, 2017, 10:21:32 am »
You may also need to connect "den_in" to something that isn't always asserted (simulation fails with a DRC check):
Code: [Select]
adc : ....
        den_in => bit_tick, -- was '1', this will read the XADC register 9600 times a second
        .....

You can then use the pulse from the XADC's data ready (drdy) to start the Serial TX transmitting:
Code: [Select]
uart_tx : .....
        data_en => drdy,
        ....

Page 74 of the XADC user guide (https://www.xilinx.com/support/documentation/user_guides/ug480_7Series_XADC.pdf):
Quote
When the DEN is logic High, the DRP address (DADDR) and write enable (DWE) inputs are captured on the next rising edge of DCLK.  DEN should only go high for one DCLK period.

Is that looking any better?
Gaze not into the abyss, lest you become recognized as an abyss domain expert, and they expect you keep gazing into the damn thing.
 

Offline hamster_nz

  • Super Contributor
  • ***
  • Posts: 2803
  • Country: nz
Re: Nexys4 DDR ADC -> UART
« Reply #4 on: June 14, 2017, 08:58:19 am »
Hi,

Attached are the project files...

* It is for the Basys3

* The main file includes a slightly different - it has the baud generator set to 115200 baud, and is set up to read the XADC temperature.

* The UART converts the 16 bit values to four ASCII bytes, and appends a NL and CR character, so you can see it in the serial console session. Because it is send back-to-back you need have the console open before you program the FPGA or you might not get the framing correctly and get what looks to be garbage.

Sample output (with my finger on the FPGA):

Code: [Select]
9C36
9C46
9C48
9C56
9C8C
9C68
9C9A
9C5A
9C60
9C3C

The upper 12 bits are the temperature  (eg 0x9c3). Transfer function (from https://www.xilinx.com/support/documentation/user_guides/ug480_7Series_XADC.pdf) is 

  Temp = (value * 503.975)/4096 - 273.15
          =  (2499* 503.975)/4096 - 273.15
          = 34.3 degrees C

With the finger off it read around  0x998 (29.05 degrees C) - note this is the die temp.
Gaze not into the abyss, lest you become recognized as an abyss domain expert, and they expect you keep gazing into the damn thing.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf