Sägezahn in Sinus

Gast #1286508
Lesenswert?

Hallo,

wir haben vor aus einer Sägezahn Spannung eine Sinus Spannung zu 
generieren.
1
library IEEE;
2
use IEEE.STD_LOGIC_1164.ALL;
3
use IEEE.STD_LOGIC_ARITH.ALL;
4
use IEEE.MATH_REAL.ALL;
5

6
entity SinusGeneration is
7
  Port 
8
  (  
9
    clkin  : in std_logic;
10
    reset_n  : in std_logic;
11
    cnt_in  : in std_logic_vector(13 downto 0);
12
    cnt_out  : out std_logic_vector(13 downto 0)
13
  );
14
end SinusGeneration;
15

16
architecture Behavioral of SinusGeneration is
17
  signal state: std_logic_vector(1 downto 0);
18
begin
19
  --signal dac: std_logic_vector(13 downto 0);
20
  sin_gen: process(cnt_in)
21
  variable value1: integer range 0 to 16383;
22
  --variable state: integer;
23
  begin  
24
    if reset_n = '0' then
25
      state <= "00";
26
    elsif (clkin = '1') and (clkin'event) then
27
      value1 := conv_integer(unsigned(cnt_in));
28
      if (state = "00") then
29
        cnt_out <= conv_std_logic_vector((8191 + value1), 14);
30
        if (value1 = 8192) then
31
          state <= "01";
32
        end if;
33
      end if;
34
      if (state = "01") then
35
        cnt_out <= conv_std_logic_vector(8191 + (16383 - value1), 14);
36
        if ((16383 - value1) = 0) then
37
          state <= "10";
38
        end if;
39
      end if;
40
      if (state = "10") then
41
        cnt_out <= conv_std_logic_vector((8191 - value1), 14);
42
        if (value1 = 8192) then
43
          state <= "11";
44
        end if;
45
      end if;
46
      if (state = "11") then
47
        cnt_out <= conv_std_logic_vector(8191 - (16383 - value1), 14);
48
        if ((16383 - value1) = 0) then
49
          state <= "00";
50
        end if;
51
      end if;
52
      
53
    end if;
54
  end process sin_gen;
55
end Behavioral;

Jemand eine Idee? Evtl mit Hilfe eines Filters? Oder der Sinus Funktion 
in vhdl?

MfG
Jens&Max
Moderator (Firma: Titel) Persönliche Seite #1293582
Lesenswert?

> wir haben vor aus einer Sägezahn Spannung eine Sinus Spannung zu
> generieren.
:
>  Dachte an ein IIR 2. Ordnung.
Weniger interessant ist was ihr vorhabt,
sondern viel eher was das eigentlich werden soll.

Wie sieht die konkrete Aufgabe aus?
Woher kommt die Sägezahnspannung?
Ist die extern vorgegeben, oder wird die von euch erzeugt?
Welche(n) Frequenz(bereich) ist gefragt?

> haben bereits eine Sägezahn Spannung programmiert
Warum programmiert ihr dann nicht gleich eine Sinusspannung?

> DDS ? Was genau ist das?
Wikipedia hilft weiter:
DDS, DDFS --> Direkte Digitale (Frequenz) Synthese
http://de.wikipedia.org/wiki/Direct_Digital_Synthesis

Und so könnte das in der Realität aussehen:
http://www.lothar-miller.de/s9y/categories/31-DDFS
Moderator (Firma: Titel) Persönliche Seite #1293624
Lesenswert?

> Jetzt wollen wir aus der Sägezahn mit Hilfe eines IIR-Filters
> eine Sinus-Form erzeugen.
Das ist wahrhaftig der denkbar umständlichste Weg...   :-o

Wenn du einen Sägezahn (erzeugt) hast, dann nimm diese Zahlenwerte als 
Adresse für eine (ROM-)Tabelle, in der eine Sinuskurve abgelegt ist.

Mit ein wenig Nachdenken reicht es aus, nur 1/4 der kompletten 
Sinuskurve abzuspeichern, und dann mit den beiden höchsten Bits der 
Adresse auszuwählen, in welchem Quadranten du dich befindest.

Du kannst z.B. auch nur eine Tabelle mit wenigen Stützpunkten (z.B. 64) 
anlegen, und die Sinuswerte zwischen den Stützpunkten interpolieren.

Jede dieser Ideen ist garantiert einfacher als der Filteranstatz. Dies 
gilt im Besonderen, wenn die Frequenz variabel ist.
Moderator (Firma: Titel) Persönliche Seite #1293668
Lesenswert?

Jens schrieb:
> gibt es VHDL-Schnipsel für solche Tabellen?
Auf die Gefahr hin, dass ich mich wiederhole:
>>> Und so könnte das in der Realität aussehen:
>>> http://www.lothar-miller.de/s9y/categories/31-DDFS
Dort ist ein 8-Bit Viertel-Sinus abgelegt  :-/

> Bzw Beispiele für die Idee mit der Interpolation?
Ein wenig solltest du schon noch selbst machen (=lernen)   ;-)
Persönliche Seite #1863702
Lesenswert?

So eine Interpolation geht ein einfachsten, indem man die Phase mit 
mindestens 4fachger Genauigkeit berechnet und dann jeweils 4x die 
Tabelle mit 90,180,270 Grad Vorlauf abfragt. Dann kannst Du 4 Werte 
addieren, um die Genauigkeit zu erhöhen.

Ich habe in meinem VHDL-Synth eine Option auf eine 20->24 Bit 
Interpolation, was aber nur etwas bringt, wenn die Sinustabelle schon 
sehr fein ist.

Für einfache "Sinüsse" geht auch das hier:
Beitrag "Re: FPGA Größe ausreichend für komplexen FM Synthesizer"

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren