Forum: FPGA, VHDL & Co. Single Dual Port RAM, delay time einstellen


von Gast (Gast)


Lesenswert?

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

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

> 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.

von Gast (Gast)


Lesenswert?

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

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

> 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.

von Gast (Gast)


Lesenswert?

> 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

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

> 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;

von Gast (Gast)


Lesenswert?

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

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

> 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
Noch kein Account? Hier anmelden.