www.mikrocontroller.net

Forum: FPGA, VHDL & Co. Sinus


Autor: Micha (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
ich hab noch ein Problem in VHDL.

Ich möchte eine Sinus-Funktion auf einen A/D-Wandler ausgeben.
In meinem Programm habe ich eine "Variable INTEGER RANGE 0 to 255",
die bei jeder positiven Flanke um 1 erhöht wird. Die Sinusfunktion soll
mit diesen 256 Schritten abgebildet werden. Ich hab jetzt versucht, dies
mit sin(counter) zu machen, bekam allerdings die Meldung, daß sin()
static sein muß.

Wie lässt sich das realisieren? Über ein Array, in dem ich die 256
Sinuswerte abspeichere?

Autor: FPGAküchle (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du willst bestimmt keinen CORDIC Block zur sinusberechnung einbauen und
sicherlich keine CPU um den sinus berechnen lassen. Bleibt also
Tabelle, meint ROM-feld. Du kannst Dir für Xilinx einen solchen vor
coregen bauen lassen, die sinuswerte schreibst du dann in das *.coe
file. Soviel in Kürze.
Aber muss es ein Sinus sein? ein Dreieck ist auch ganz gut zum Testen.
Und
ein bisserl Tiefpass dahinter macht fast einen Sinus draus. das dreieck
erzeugt dir
bequem ein up/Down counter. Aber meinst du wirklich einen AD und
keinen
DA wandler? Aus einen FPGA kriegst du keine Analogen Signale, da
musstest du schon was hinter die Pins schalten.

Autor: Micha (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich meinte natürlich einen D/A-Wandler, da habe ich mich vertippt.
Ein Dreieck reciht leider nicht aus.
Ich hab jetzt nach einigen Stunden folgendes geschrieben:

  sin_gen: process(int_clock, reset)
      TYPE sinus_array IS ARRAY (natural range 0 to 255) of INTEGER;
      variable counter: integer range 0 to 255;
      variable sinus: sinus_array;
  begin

     for I in 0 to 255 loop
         sinus(I) :=integer((sin(2.0  MATH_PI  real(I) / 256.0) + 1.0
) * 127.5);
    end loop;

      if (reset = '1') then
       q <= (others =>'0');
     elsif (int_clock'event and int_clock='1') then
        q <= conv_std_logic_vector(sinus(counter),8);
        if (counter < 255) then
             counter := counter +1;
         else counter := 0;
            end if;
    end if;
  end process sin_gen;

Simulation sieht gut aus. Morgen teste ich es mal mit Hardware. Vielen
Dank.

Autor: Jens (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ich bekomme hier ständig die Fehlermeldung
Error (10500): VHDL syntax error at SinusGeneration.vhd(21) near text "real";  expecting ")", or ","
Error (10500): VHDL syntax error at SinusGeneration.vhd(21) near text ")";  expecting ";"
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;

entity SinusGeneration is
  generic
  (  
    test: integer := 256
  );
  Port 
  (  
    clk: in std_logic;
    rst: in std_logic
  );
end SinusGeneration;

architecture Behavioral of SinusGeneration is
begin
  sin_gen: process(clk, rst)
  TYPE sinus_array IS ARRAY (natural range 0 to 255) of INTEGER;
  variable counter: integer range 0 to 255;
  variable sinus: sinus_array;
  begin
    for I in 0 to 255 loop
      sinus(I) :=integer((sin(2.0 MATH_PI real(I) / 256.0) + 1.0) * 127.5);
    end loop;
    if (rst = '1') then
      q <= (others =>'0');
    elsif (clk'event and clk='1') then
      q <= conv_std_logic_vector(sinus(counter),8);
      if (counter < 255) then
        counter := counter +1;
      else counter := 0;
      end if;
    end if;
    end process sin_gen;
  
end Behavioral;


ich habe auch vor einen Sinus zu erzeugen und diesen variable machen in 
der Frequenz. Kann mir da jemand einen Denkanstoß geben?

Danke im vorraus

Autor: Matthias (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dir fehlt der *-Operator.

Im vorigen Post war der wohl drin aber wurde in der Anzeige zu einer 
Hervorhebung von MATH_PI umgewandelt.

Autor: Jens (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ja danke habe alle Compilerfehler ausgebügelt.

Jedoch versuche ich jetzt diesen über ein Oszi ein Sinus Signal 
darzustellen. Klappt leider nur nicht. Wo habe ich einen Denkfehler?

Autor: Duke Scarring (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Jens:
> Wo habe ich einen Denkfehler?
Es sind nicht alle VHDL-Konstrukte synthetisierbar.

Duke

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@  Micha (Gast)

>Wie lässt sich das realisieren? Über ein Array, in dem ich die 256
>Sinuswerte abspeichere?

Ja. Und das Array legast du am besten als Konstanten an, welche du 
vorher per Excel oder so berechnest. Scnst gibts wieder 
Compiler-Gemecker.

Wie man das machen kann sieht man hier.

http://www.mikrocontroller.net/articles/TTL74185#K...

MFG
Falk

Autor: GastausHannover (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hallo zusammen

ich hab den code mals mit ise 10 von xilinx synthesieren gelassen, es 
geht fehlerfrei!?

Mit extra pagket-Einbinden: (sonst fehlermeldung wegen real-type und 
konstant MATH_PI)
use IEEE.MATH_REAL.ALL;

ich bewundere mich: MATH_REAL Paket kann nicht synthesieren werden, also 
nur für Simulation!

Hab ich einen Denkfehler?

gruß

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
GastausHannover schrieb:
> Hab ich einen Denkfehler?
Zwei hast du:
1) Der Thread ist 1,5 Jahre alt. Wozu hast du den ausgegraben?
2) Die MATH_REAL wird nicht synthetisiert, sondern nur zur Berechnung 
verwendet. Das Ergebnis der Berechnung ist ein integer. Und der kann 
ohne weiteres synthetisiert werden:
    for I in 0 to 255 loop
      sinus(I) :=integer((sin(2.0 * MATH_PI * real(I) / 256.0) + 1.0) * 127.5);
    end loop;


BTW:
Es würde reichen, nur 1/4 vom Sinus auszurechnen.
Der Rest wiederholt sich irgendwie immer wieder...   :-o

Autor: GastausHannover (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Lothar Miller schrieb:
> 1) Der Thread ist 1,5 Jahre alt. Wozu hast du den ausgegraben?

weil ich bin noch newbie in vhdl:-)

Lothar Miller schrieb:
> Das Ergebnis der Berechnung ist ein integer. Und der kann
> ohne weiteres synthetisiert werden:    for I in 0 to 255 loop
>       sinus(I) :=integer((sin(2.0  MATH_PI  real(I) / 256.0) + 1.0) * 127.5);
>     end loop;

Dann wieso muss man noch einen Type-cast integer brauchen?kann man nicht 
einfach so zuweisen?:
sinus(I) :=(sin(2.0 * MATH_PI * real(I) / 256.0) + 1.0) * 127.5);

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> kann man nicht einfach so zuweisen?:
Nein.
Kann man nicht, weil das hier VHDL ist und nicht C, BASIC oder sonst 
was. Denn in VHDL kann auf ein Signal bzw. eine Variable nur etwas 
zugewiesen werden, das explizit den selben Typ hat.

Autor: René D. (Firma: www.dossmatik.de) (dose)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Am Anfang sind Typen und der Typ-cast etwas lästiges. Erspart dann doch 
die Fehlersuche, weil zwischen dem Programmier und der Fitsoftware keine 
Missverständnisse existieren.

Autor: GastausHannover (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Lothar Miller schrieb:
> Es würde reichen, nur 1/4 vom Sinus auszurechnen.
> Der Rest wiederholt sich irgendwie immer wieder...   :-o

genau, ich hab grad ausprobiert:-)


FPGAküchle schrieb:
> Du kannst Dir für Xilinx einen solchen vor
> coregen bauen lassen, die sinuswerte schreibst du dann in das *.coe
> file.

wie kann man ein sinus.coe-file erzeugen? damit man in ROM reinlegen und 
auslesen kann?

Autor: René D. (Firma: www.dossmatik.de) (dose)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du musst ein Array erzeugen, das ist deine Table.

type wave_typ is array (0 to 127) of signed (0 to 7);

constant sin_fkt: wave_typ :=
("10000000",
 "01000000",
.......

);

Autor: GastausHannover (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
René D. schrieb:
> Du musst ein Array erzeugen, das ist deine Table.
>
> type wave_typ is array (0 to 127) of signed (0 to 7);
>
> constant sin_fkt: wave_typ :=
> ("10000000",
>  "01000000",
> .......
>
> );


kann man das automatisch erzeugen lassen, ich meine vllt mit matlab, 
exel..?

Autor: René D. (Firma: www.dossmatik.de) (dose)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es geht auch mit VHDL!!!!
Matlab ist gut für Untersuchungen. Halte es besser aus dem Design.

Doch da muss ich auch erst in das Buch schauen.

Autor: René D. (Firma: www.dossmatik.de) (dose)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So ungefähr muss es lauten.
Das ist ungetestet!!!



USE ieee.math_real.all; --ergänzen


----
constant interations:integer:127;

type wave_typ is array (0 to 127) of signed (0 to 7);

signal sinus_fkt: wave_typ;


table :for a in 1 to interations  generate

  sinus_fkt(a)<=to_signed(integer(angle_bits *( sin( real(a))),size);
end generate table;

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [vhdl]VHDL-Code[/vhdl]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.