Hallo, ich möchte gerne ein kontinuierliches Signal um eine bestimmte (einstellbare) delay time verzögert ausgeben. Dazu dachte ich mir dies in ein Dual Port Ram verwirklichen, in dem ich in eine Adresse schreibe und in die andere Adresse auslese. Und der die delaytime rechnet sich dann doch theoretisch aus RD_PTR = WR_PTR - (Zeit/ OFFSET). So dualport in xilinx core generator erstellt, Breite 12 bit und tiefe 1024. Jetzt weis ich nur nicht wie ich dieses Verhältniss oben am besten realisere?? Benutze ein SPARTAN 6... Kann mir da jemand ein Tipp geben...? Gruss
> ich möchte gerne ein kontinuierliches Signal um eine bestimmte > (einstellbare) delay time verzögert ausgeben. Um welche Zeiten handelt es sich? Mit welcher Genauigkeit/Auflösung soll die Einstellbarkeit erfolgen? Welchen Takt hast du? > Dazu dachte ich mir dies in ein Dual Port Ram verwirklichen, Du brauchst einen FIFO. Den kannst du mit einem BRAM realisieren, allerdings ist sowohl das Schreiben wie auch das Lesen von einem Takt abhängig.
Hi, also ich lese das 12 bit breite Signal mit 20 Mhz rein, d.h alle 0,05usek ein signal. mit einer genauigkeit von 1 promil. Ich möchte das Signal um max. 900 stellen verzögert ausgeben, dies aber einstellbar veränder können. Gruss
> mit einer genauigkeit von 1 promil. Die 20Mhz sind auf 1 Promille genau? > um max. 900 stellen verzögert ausgeben Also um 0..900*50ns = 0..45us? Und die Ausgabe soll synchron zu den 20MHz sein? Dann brauchst du einen FIFO mit 900 Speicherplätzen. Am einfachsten machst du den selber über ein DPRAM mit 1024 Worten Speichertiefe, bei dem der Lesezähler über einen Offset dem Schreibzähler folgt.
> Die 20Mhz sind auf 1 Promille genau? Genau > Also um 0..900*50ns = 0..45us? Genau >Und die Ausgabe soll synchron zu den 20MHz sein? Genau >Dann brauchst du einen FIFO mit 900 Speicherplätzen. Am einfachsten machst du den selber über ein DPRAM mit 1024 Worten Speichertiefe, bei dem der Lesezähler über einen Offset dem Schreibzähler folgt.folgt. Genau soweit bin ich gedanklich auchgekommen, den DPRAM mit coregenerator hab ich schon erstellt, nun wie muss mein vhdlcode ausschuen um den LESEZHÄHLER mit OFFSET zu versehen und diesen OFFSET als einstellbar zu realisieren... Danke Gruss
> um den LESEZHÄHLER mit OFFSET zu versehen
Mal angenommen, deine Zähler wären integer und du würdest numeric_std
verwenden:
1 | port ( ... |
2 | offset : std_logic_vector(9 downto 0); -- Offset in 50ns Schritten |
3 | ... ); |
4 | |
5 | :
|
6 | signal RD_PTR : integer range 0 to 1023; |
7 | signal WR_PTR : integer range 0 to 1023; |
8 | :
|
9 | :
|
10 | if (offset=(offest'range=>'0')) then -- Sonderbehandlung: keine Verzögerung |
11 | dout <= din; |
12 | else
|
13 | RD_PTR <= to_integer(to_unsigned(WR_PTR,10)-unsigned(offest)); |
14 | end if; |
Wenn es std_logic Vektoren sind, müssen die Casts ein wenig anders aussehen:
1 | port ( ... |
2 | offset : std_logic_vector(9 downto 0); -- Offset in 50ns Schritten |
3 | ... ); |
4 | |
5 | :
|
6 | signal RD_PTR : std_logic_vector(9 downto 0); |
7 | signal WR_PTR : std_logic_vector(9 downto 0); |
8 | :
|
9 | :
|
10 | if (offset=(offest'range=>'0')) then -- Sonderbehandlung: keine Verzögerung |
11 | dout <= din; |
12 | else
|
13 | RD_PTR <= std_logic_vector(unsigned(WR_PTR)-unsigned(offest)); |
14 | end if; |
Hm... mal ein vereinfachtes beispiel, ich hab als eingagn 4 bit signal und länge vom DPRAM 16 ... über coregenerator implementiere ich mir
1 | COMPONENT TESTRAM |
2 | port ( |
3 | clka: IN std_logic; |
4 | wea: IN std_logic_VECTOR(0 downto 0); |
5 | addra: IN std_logic_VECTOR(3 downto 0); |
6 | dina: IN std_logic_VECTOR(3 downto 0); |
7 | clkb: IN std_logic; |
8 | rstb: IN std_logic; |
9 | addrb: IN std_logic_VECTOR(3 downto 0); |
10 | doutb: OUT std_logic_VECTOR(3 downto 0)); |
und über PORTMAP HAB ich dann die einzelnen signale zugewiesen..
1 | DP1 : TESTRAM |
2 | |
3 | Port Map ( clka => clk_2, |
4 | wea => "1", |
5 | addra => ADD1, |
6 | dina => SAVEY, |
7 | clkb =>clk_2, |
8 | rstb => MASTERRESET, |
9 | addrb =>ADD2, |
10 | doutb => AUSGANG); |
Ich denke jetzt müsste ich über addra und addrb diese logik implementieren z.B hab ich folgendes probiert
1 | ADD_TAKT:process (clk_A,reset) |
2 | begin
|
3 | |
4 | if clk_A = '1' and clk_A'event then |
5 | if reset = '1' then |
6 | ADDA1 <= "0000"; |
7 | ADDA2 <= ADDA1 -1; |
8 | cnt <= 0; |
9 | elsif (cnt= 16) then |
10 | cnt<=0; |
11 | ADDA1 <= "0000"; |
12 | |
13 | else
|
14 | ADDA1 <= ADDA1 +1; |
15 | |
16 | cnt<=cnt+1; |
17 | end if; |
18 | |
19 | end if; |
20 | |
21 | end process ADD_TAKT; |
22 | |
23 | ADDA <= ADDA1; |
24 | ADDB <= ADDA1; |
Als clk verwende ich ein 1 Hz takt, somit müsste ja das signal nach 8 takten am ausgang erscheinen, was es auch tut, nur geht es dann wieder aus, und dann wieder nach paar takten an, und dann bleibt es auch dauerhaft an.... Wieso Gruss
> Als clk verwende ich ein 1 Hz takt, somit müsste ja das signal nach 8 > takten am ausgang erscheinen, was es auch tut, nur geht es dann wieder > aus, und dann wieder nach paar takten an, und dann bleibt es auch > dauerhaft an.... Mit visuellem Debuggen wird das nichts... Du simulierst das einfach mal durch, dann kannst du auch interne signalverläufe sehen. > somit müsste ja das signal nach 8 takten am ausgang erscheinen 16 Takte sind es. Warum eigentlich zwei Zähler? ADDA und cnt zählen das selbe :-/ Probiers mal so:
1 | if clk_A = '1' and clk_A'event then |
2 | if reset = '1' then |
3 | ADDA1 <= "0000"; |
4 | else
|
5 | ADDA1 <= ADDA1+1; |
6 | end if; |
7 | end if; |
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.