Hallo ich verwende 2 ADCs, die immer abwechselnd digitalisieren (der 1. ADC mit der ansteigenden Flanke und der andere ADC mit der abfallenden Flanke). Die ADC erzeugen den Datenübertragungstakt Jetzt möchte ich meine VHDL-Schaltung mit einer Testbench simulieren. Den Takt für die Simulation kann ich auch erzeugen. Die beiden Takte sollen die gleiche Frequenz besitzen. Zwischen den beiden Takten soll ein Phasenversatz von z.B 1ns sein und genau das ist mein Problem. Wie kann ich 2 Takte mit der gleichen Frequenz und xns Phasenversatz erzeuegen? Die ist mein Code: F_INPUT1 : PROCESS BEGIN ADC_1_CLK <= '1'; wait for 1.25 ns; ADC_1_CLK <= '0'; wait for 1.25 ns; END PROCESS; F_INPUT2 : PROCESS BEGIN ADC_2_CLK <= '0'; wait for 1.25 ns; ADC_2_CLK <= '1'; wait for 1.25 ns; END PROCESS;
Erste spontane Idee: F_INPUT1 : PROCESS BEGIN ADC_1_CLK <= '1'; wait for 1.25 ns; ADC_1_CLK <= '0'; wait for 1.25 ns; END PROCESS; F_INPUT2 : PROCESS variable first: boolean := true; BEGIN ADC_2_CLK <= '0'; if first then first := false; wait for 1 ns; end if; wait for 1.25 ns; ADC_2_CLK <= '1'; wait for 1.25 ns; END PROCESS;
Mist, kann den Beitrag ja nicht editieren. F_INPUT1 : PROCESS BEGIN ADC_1_CLK <= '1'; wait for 1.25 ns; ADC_1_CLK <= '0'; wait for 1.25 ns; END PROCESS; F_INPUT2 : PROCESS(ADC_1_CLK) BEGIN ADC_2_CLK <= ADC_1_CLK after 1 ns; END PROCESS; Sorry für den Doppelpost!
Die zweite Lösung sieht deutlich eleganter aus ^^ Jetzt habe ich natürlich noch eine Frage: Kann ich auch einen kleinen Jitter einbauen? Der Datenclock von beiden ADCs ist ja nicht immer konstant, demnach ist der Phasenversatz ja auch nicht immer konstant. Kann man dies auch simulieren?
Ich hätte da noch was ganz ohne Prozesse und so:
1 | signal ADC_1_CLK : std_logic := '0'; |
2 | signal ADC_2_CLK : std_logic := '0'; |
3 | :
|
4 | ADC_1_CLK <= not ADC_1_CLK after 1.25 ns; |
5 | ADC_2_CLK <= ADC_1_CLK after 1 ns; |
6 | :
|
Kann man die beiden clocks nicht einfach in einem Prozess erzeugen?
1 | F_INPUT1 : PROCESS |
2 | BEGIN
|
3 | ADC_1_CLK <= '1'; |
4 | wait for 1 ns; |
5 | ADC_2_CLK <= '1'; |
6 | wait for 0.25 ns; |
7 | ADC_1_CLK <= '0'; |
8 | wait for 1 ns; |
9 | ADC_2_CLK <= '0'; |
10 | wait for 0.25 ns; |
11 | END PROCESS; |
Sebastian schrieb: > Kann ich auch einen kleinen Jitter einbauen? Ja, das geht. Du musst nur eine Zufallszahl in gewünschter Größe erzeugen und dem Delay dazu addieren. So was habe ich auch schon mal machen müssen.
2* 1,25ns ergibt 2,5ns für eine Periode und das sind immer noch 400MHz, also durchaus üblich bei schnellen ADCs.
Das sind 14Bit Wandler mit 400MHz es gibt auch 12Bit Varianten mit 500MHz, 550MHz und 1GHz.
> hast Du noch den kleinen Codeausschitt für mich?
Folgenden Code hatte ich mal geschrieben:
1 | -- Beschreibung
|
2 | -- Generiert einen verjitterten Clock für Testbenches
|
3 | |
4 | library ieee; |
5 | use ieee.std_logic_1164.all; |
6 | use ieee.math_real.all; |
7 | |
8 | entity jittered_clk_tbmod is |
9 | generic
|
10 | (
|
11 | random_initial : positive -- Jede Zahl an dieser Stelle erzeugt eine andere Random-Folge für den Jitter |
12 | );
|
13 | port
|
14 | (
|
15 | clk_rate : in natural; -- Taktrate in Hz |
16 | clk_dutycycle : in real; -- Typischer Weise 0.5 |
17 | clk_jitter : in real; -- max. "clk_dutycycle / 2" oder "(1-clk_dutycycle) / 2" |
18 | -- Ausgang
|
19 | clk_out : out std_logic := '0' |
20 | );
|
21 | end jittered_clk_tbmod; |
22 | |
23 | |
24 | architecture behavior of jittered_clk_tbmod is |
25 | |
26 | signal nom_clock : std_logic; -- Nominaler Grundtakt |
27 | signal random_seed1 : positive := random_initial; -- Hilfssignale für Zufalssignalgenerierung |
28 | signal random_seed2 : positive := random_initial+1; |
29 | signal random_jitter : real := 0.1; |
30 | |
31 | begin
|
32 | |
33 | nom_clock_proc: process |
34 | begin
|
35 | nom_clock <= '0'; |
36 | wait for 1 ns; |
37 | nom_clock <= '1' after (0.5 sec / clk_rate) - 1 ns; |
38 | wait for (1.0 sec / clk_rate) - 1 ns; |
39 | end process; |
40 | |
41 | master_clk_proc: process |
42 | variable vseed1, vseed2 : positive; |
43 | variable vjitter : real; |
44 | begin
|
45 | wait until rising_edge(nom_clock); |
46 | vseed1 := random_seed1; |
47 | vseed2 := random_seed2; |
48 | vjitter := random_jitter; |
49 | uniform(vseed1, vseed2, vjitter); |
50 | clk_out <= '0'; |
51 | clk_out <= '1' after (vjitter * clk_jitter + 0.25) * 1.0 sec / clk_rate; |
52 | wait until falling_edge(nom_clock); |
53 | uniform(vseed1, vseed2, vjitter); |
54 | clk_out <= '0' after (vjitter * clk_jitter + clk_dutycycle - 0.25) * 1.0 sec / clk_rate; |
55 | random_seed1 <= vseed1; |
56 | random_seed2 <= vseed2; |
57 | random_jitter <= vjitter; |
58 | end process; |
59 | |
60 | end behavior; |
Vielleicht ist ja was für Dich dabei! Kleine Anpassungen sind bei Deinen Taktraten sicherlich nötig. Bei mir ging es damals um vergleichsweise langsamere Takte.
Vielen Dank für Deinen Post ich werde den Code ihn ruhe durchlesen und versuchen zu verstehen.
Ich wurde leider unterbrochen, so das ich die leider noch nicht testen konnte, da ich mitte nächster Woche in den Urlaub gehe werde ich es bis dahin sicherlich auch nicht schaffen. Ich wered mich danach mit dem Problem wieder auseinandersetzen.
Was bringt ein verjitterter clk in einer Testbench? Jitteranalysen müssen so erfolgen, dass man 1) lang term und 2) short term untersucht und das geht nur mit deterministischen Werten.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.