Hallo Leute,
Ich habe ein halbwegs amüsantes Problem. Wir haben ein Board mit einem
Stapel AD7641 A/D Wandler (2MSPS, 18 Bit SAR). Diese sind seriell an
einen fetten FPGA angebunden. Das Board haben wir gekauft mit
Beispieldesigns. Letztere tasten die ADCs fies mit einer 140 MHz Clock
ab (slave serial mode, was der Hersteller nicht empfiehlt).
Bin mir noch nicht klar, wie man die "vernünftig" anbindet, und dachte,
ich stelle mal ein paar blöde Fragen hier im Forum. :)
Mein erster Gedanke (rein theoretisch, werden kaum das Board umbauen)
war, das Master Serial Interface zu verwenden und mit einem/mehreren
CPLDs die Daten aus den ADCs zu ziehen und auf der anderen Seite
wiederum per SPI in den FPGA zu pumpen (Takt vom FPGA beim Auslesen).
Die Empfangsseite vom ADC könnte wie folgt aussehen (leicht gekürzt):
1 | entity to_ad7641 is
|
2 | port (adc_sync : in std_logic; -- frame synchronization
|
3 | adc_sclk : in std_logic; -- clock from adc
|
4 | adc_dout : in std_logic; -- data from adc
|
5 | data_ready : out std_logic; -- transitions on new data
|
6 | data : out std_logic_vector(17 downto 0));
|
7 | end entity to_ad7641;
|
8 |
|
9 | architecture behavioural of to_ad7641 is
|
10 |
|
11 | signal shift_in : std_logic_vector(17 downto 0);
|
12 | signal ready : std_logic;
|
13 |
|
14 | begin
|
15 |
|
16 | data_ready <= ready;
|
17 |
|
18 | -- Daten seriell übernehmen, wenn sync aktiv.
|
19 | process (adc_sclk) is
|
20 | begin
|
21 | if rising_edge(adc_sclk) then
|
22 | if adc_sync = '1' then
|
23 | shift_in <= shift_in(16 downto 0) & adc_dout;
|
24 | end if;
|
25 | end if;
|
26 | end process;
|
27 |
|
28 | -- Nach dem Transfer wird Sync low gezogen, dann reichen wir die Daten
|
29 | -- weiter.
|
30 | process (adc_sync) is
|
31 | begin
|
32 | if falling_edge(adc_sync) then
|
33 | data <= shift_in;
|
34 | ready <= not ready;
|
35 | end if;
|
36 | end process;
|
37 |
|
38 | end architecture;
|
Rationale für die komische Formulierung: Wollte unabhängig von weiterer
Taktquelle bleiben, SCLK stoppt nach dem Transfer, wenn ich das
Datenblatt http://www.analog.com/UploadedFiles/Data_Sheets/AD7641.pdf
richtig lese.
Problem hier: Das Timing. Ich komme nicht so recht dahinter.
Nach Datenblatt (Figure 36) treibt der ADC die SDOUT-Leitung mindestens
t22 = 1ns vor SCLK. Während SCLK high (t20 >= 2ns) ist SDOUT gültig.
Tja, wie gibt man das der Xilinx-Software an? Ich habe folgenden
Constraint versucht:
1 | NET "adc_sclk" TNM_NET = "adc_sclk";
|
2 | TIMESPEC "TS_adc_sclk" = PERIOD "adc_sclk" 8 ns LOW 60 %;
|
3 | NET "adc_dout" OFFSET = IN 0 ns BEFORE "adc_sclk" LOW ;
|
Die Angabe zu SCLK ist so nicht richtig: Die Periode kann zwischen 8ns
und 14ns sein (t19). Dabei ist SCLK high mind. 2ns (t20) und SCLK low
mind. 3ns (t21). Für adc_dout möchte ich angeben, dass der 1ns vor SCLK
gesetzt wird und dann gehalten wird, bis SCLK auf low geht. In der Zeit
müsste der Eingang gesampled werden.
Kann ich das in Xilinx Constraints modellieren? Ich tue mich da noch ein
wenig schwer, weil ich bisher ganz gut ohne ausgekommen bin. Alles, was
synchron läuft, kann er ja auch so analysieren.
Hoffe auf viele Kommentare,
Torsten