Forum: FPGA, VHDL & Co. Sinus Abstand vergrößern, VHDL


von NoMatter (Gast)


Lesenswert?

Hallo,

hab mal ein kleines Problem, ich habe in VHDL einen DDS-Sinusgenerator 
geschrieben, der auch richtig Sinusse periodisch ausgibt, hab dazu auch 
einen Zähler konstruiert, der die Anzahl der Sinusse in der Periode 
zählt nun meine Frage, wie schaffe ich es im Sinusgenerator die Abstände 
zwischen den Sinussen zu vergrößern. möcht gern die Abstände variieren 
können, jemand ne idee, bin sehr dankbar für Anregungen.

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


Lesenswert?

NoMatter schrieb:
> wie schaffe ich es im Sinusgenerator die Abstände
> zwischen den Sinussen zu vergrößern.
Du mußt länger warten.
Mehr kann man ohne Quelltexte nicht sagen...  :-/

BTW: Mir kommt die Aufgabenstellung so vor wie im 
Beitrag "Re: Sinus über DDS erzeugen"?

von NoMatter (Gast)


Lesenswert?

Ah interessant, dass sich jemand anders auch damit beschäftigt hat. aber 
das hilft mir nicht weiter.

was ich fürs erste will ist, die Idee die dahinter steckt, wie man es 
realisieren kann, will ja selbst versuchen hinzubekommen. Ich will den 
Abstand zwischen den Sinussen variieren können, wie könnte man dies 
realisieren.Danke.

von Matthias (Gast)


Lesenswert?

NoMatter schrieb:
> Ah interessant, dass sich jemand anders auch damit beschäftigt hat. aber
> das hilft mir nicht weiter.
>
> was ich fürs erste will ist, die Idee die dahinter steckt, wie man es
> realisieren kann, will ja selbst versuchen hinzubekommen. Ich will den
> Abstand zwischen den Sinussen variieren können, wie könnte man dies
> realisieren.Danke.

Na, da musste schon mal selber den Papula zur Hand nehmen und dir die 
Sinus funktion anschauen. Wenn dein Sin(x) schoen laeuft, was kann man 
machen um die sinus funktion auf der X-Achse zu strecken/stauchen?
Fuer die Sinus funktion wird auf der X-Achse die ZEIT aufgetragen - Also 
muss deine Zeit einheit, mit der du den wert X veränderst, grösser oder 
kleiner werden. Grösser zum strecken, kleiner zum stauchen.

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


Lesenswert?

NoMatter schrieb:
> Ah interessant, dass sich jemand anders auch damit beschäftigt hat. aber
> das hilft mir nicht weiter.
Lies mal erst den Beitrag....
> was ich fürs erste will ist, die Idee die dahinter steckt
Lies mal erst den Beitrag....

> was ich fürs erste will ist, die Idee die dahinter steckt, wie man es
> realisieren kann
Du wartest einfach, nachdem ein Sinusdurchlauf/-paket fertig ist, eine 
Zeit ab, bevor du den nächsten Sinus erzeugst.

> will ja selbst versuchen hinzubekommen.
Sicher?

von NoMatter (Gast)


Lesenswert?

danke für deine Antwort, dass strecken und stauchen kann ich ja mit 
meinem Akkumulator vornehmen, das funktioniert ja auch, die idee von 
Lothar ist die richtige die mir auch durch den Kopf egangen ist, ich 
habs auch ausprobiert, mit der wait anweisung, da kommt der Fehler

" A wait statement is illegal for a process with a sensitivity list."

gibt es eine alternative um ein delay zuzufügen, da ich ja eine 
sensitivity list benutze kann ich ja kein wait statement benutzen.Danke.

Ich versuchs mal nmit der after statement.

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


Lesenswert?

NoMatter schrieb:
> habs auch ausprobiert, mit der wait anweisung, da kommt der Fehler
> Ich versuchs mal nmit der after statement.
Dar wird nix.
Du solltest unbedingt mal VHDL-Grundlagen ansehen. Lies mal das Buch 
VHDL-Synthese von Reichardt&Schwarz. Da wird dir wohl ein Licht 
aufgehen...

> gibt es eine alternative um ein delay zuzufügen, da ich ja eine
> sensitivity list benutze kann ich ja kein wait statement benutzen.
Das ist nicht das Problem.
Dein Problem ist: du kannst überhaupt kein wait benutzen. Nicht hier 
und nicht für die Synthese in diesem Zusammenhang. Auf FPGAs werden 
99,9999% aller Verzögerungen und Delays über Zähler realisiert. Du 
brauchst einen Zähler, der eine bestimmte Anzahl Takte abzählt, und dann 
darfst du erst weitermachen.

BTW: hast du dir mal den verlinkten Beitrag angesehen? Hast du ihn 
verstanden? Soll ich dir das selbe nochmal schreiben?

von Hagen R. (hagen)


Lesenswert?

also bei DDS nutzt man den Akkumulator, bzw. den Schrittzähler der auf 
den Akkumulator aufaddiert wird, um die Frequenz des erzeugten Signales 
zu beeinflussen. Es ist also die Frequenz deines Sinuses die du ändern 
mußt um deine Stauchung und/oder Streckung des Signales zu erreichen.

Ich vermute nun das die sich ergebende Auflösung, sprich Genauigkeit, 
dein eigentliches Problem ist. Die Lösung ist ganz einfach

a) die Frequenz der Taktbasis des DDS Generators inkrementieren
b) die Breite der DDS Berechnungen zu inkrementieren, heist statt zB. 
16Bit breite Berechnungen nimst du 24 Bit breite Berechnungen, also 
Akkumulator, Index und Schrittweite verbreitern
c) die Tabelle mit den einzelnen Sinuswerten vergrößern, sprich eine 
höher aufgelösste Sinustabelle verwenden

Gruß Hagen

von NoMatter (Gast)


Lesenswert?

Hallo Hagen,
dass mit der Verstauchung ist nicht das Problem,
mein problem ist, sobald ein Sinus komplett ausgegeben wurde soll dann 
gewartet werden, bis der nächste Sinus kommt, ich will lediglich nur den 
Abstand zwischen zwei Sinussen vergrößern.

wie siehst damit aus:
1
L1: if Sinus = "1111111" --das ist der letzte Wert der sinus tabelle 
2
     then next L2;
3
    --wenn der letzte wert des Sinus erreicht ist, soll er zum Label L2 springen 
4
     
5
    L2: for i in 0 to 7 loop
6
           if Startflag then Sinus_Ausgang = x"0000";
7
            --wenn ein Startflag kommt (Bedingung) dann soll zu jedem Startflag Sinus_Ausgang 7 mal nullgesetzt werden, also 7 takte null, dann soll aus der Schleife gesprungen werden
8
           exit;
9
           end if;
10
        end loop;
11
    end loop L2;
12
end loop L1;

was meint ihr.Danke.

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


Lesenswert?

NoMatter schrieb:
> was meint ihr.
Das geht nicht. Du hast die falsche Denkweise.
Du programmierst hier nicht C oder sowas.
In VHDL macht eine for-Schleife KOMPLETT was anderes als in einer 
Programmiersprache wie Basic, C, Delphi, Java...

NoMatter schrieb:
> was meint ihr.
Lothar Miller schrieb:
>> Das wird nix.
>> Du solltest unbedingt mal VHDL-Grundlagen ansehen. Lies mal das Buch
>> VHDL-Synthese von Reichardt&Schwarz. Da wird dir wohl ein Licht
>> aufgehen...
Ich habe das ernst gemeint...

Hast du schon mal eine LED blinken lassen?

Und? Geht das so:
1
   led <= not led after 500 ms;

Oder ein Lauflicht so:
1
   leds <= "0001";
2
   process begin
3
     wait for 333 ms;
4
     leds(1) <= leds(0);
5
     leds(2) <= leds(1);
6
     leds(3) <= leds(2);
7
     leds(0) <= leds(3);
8
   end process;

Oder sollte man besser einen anderen Ansatz wählen?
http://www.lothar-miller.de/s9y/archives/61-Lauflicht.html

von Matthias (Gast)


Lesenswert?

Lothar Miller schrieb:
> Und? Geht das so:   led <= not led after 500 ms;

Modelsim kann das :P

von Max (Gast)


Lesenswert?

Hallo,

hab versucht anhand Zähler dies zu realisieren,
hab einen Zähler, der zu jedem Takt zählt, dann frage ich ab, wenn der 
Zähler z.B 5 Takte vorbei ist, soll ab diesem Zeitpunkt ein zweiter 
Zähler anfangen zu zählen, dieser Zähler ist halt die Adresse zu den 
Sinuswerten. Also immer wenn der erste Zähler größer gleich 5 ist soll 
der Zweite Zähler die Werte aus der SInus Tabelle laden.

Leider klappt das nicht ganz, da logischer Weise, die Sinuswerte nicht 
ganz ausgelesen sind, erst wenn der erste Zähler größer 5 ist wird von 
Anfang begonnen, ich kriege einfach nicht raus, wie ich ihn sagen soll, 
dass nach einem ganzen Sinus, er variabel Takte warten soll und dann 
erst wieder Ausgeben soll, wäre dankbar wenn mir einer da helfen 
könnte.Danke.

So ungefähr habe ich es versucht zu realisieren.
1
if Start then  
2
              
3
            Zaehler_1 <= Zaehler_1 + 1;
4
             
5
            if Zaehler_1 >= "0000101" then 
6
              Zaehler_2 <= Zaehler_2 + 1; --Zähler_2 ist die Adresse zu den Sinuswerten. Über ein Dual port Ram lade ich dann die Sinuswerte
7
            end if;
8
            
9
            if Zaehler_2 (6 downto 0) = "00000001" then n_Sinus <= n_Sinus + 1;  --zählt Anzahl der ganzen Sinusse
10
end if;

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


Lesenswert?

Max schrieb:
> So ungefähr habe ich es versucht zu realisieren.
Häng mal einfach deine *.vhdl Datei an, wo du es genau zu realisieren 
versucht hast...

von Max (Gast)


Lesenswert?

Leider kann ich die vhdl datei nicht anhängen, da es ein riesen Projekt 
ist und ich nicht alle datein laden kann, so sieht aber der teil aus, 
den ich geschrieben habe. hoffe du verstehst diesen code.

1
signal Sinus_WabcoReadAddr : std_logic_vector(6 downto 0);    
2
signal Zaehler_1: STD_LOGIC_VECTOR (7 downto 0);
3
signal Sinus_Werte:   STD_LOGIC_VECTOR (15 downto 0);
4
signal Sinus_Wabco_ram1b : STD_LOGIC_VECTOR (15 downto 0);  
5
signal Sinus_WabcoWriteData : STD_LOGIC_VECTOR(15 downto 0);
6
signal Sinus_WabcoWriteEnable : STD_LOGIC := '0';

1
-- Internal memory 
2
    DPRAM_1_Sinus : DPRAM_1_Sinus_Wabco
3
      port map (
4
        -- Port A (VME/SPI side)
5
        clka => nVmeClk,
6
        wea(0) => '0',
7
        addra => MappedWriteAddr, 
8
        dina => DataIn,
9
        douta => DataOut,
10
        -- Port B (FST side)
11
        clkb => Clk,
12
        web(0) => Sinus_WabcoWriteEnable,
13
        addrb => Sinus_WabcoReadAddr,
14
        dinb => Sinus_WabcoWriteData,
15
        doutb => Sinus_Wabco_ram1b 
16
      );

1
 
2
       if Reset = '1' then
3
          Sinus_WabcoReadAddr <= "0000000";
4
          Zaehler_1 <= "0000000";
5
          Sinus_werte <= "0000000";
6
          n_Sinus <= "0000000";
7
          Start <= False;
8
9
       elsif rising_edge(Clk) then
10
          Sinus_WabcoWriteEnable <= '0'
11
           
12
        Sinus_werte <= Sinus_Wabco_ram1b(11 downto 0);
13
14
        Sinus_werte (11 downto 0) <= Sinus_werte (10 downto 0) & '0';
1
            if Start then  
2
              
3
                Zaehler_1 <= Zaehler_1 + 1;
4
             
5
                if Zaehler_1 >= "0000101" then 
6
                Sinus_WabcoReadAddr <= Sinus_WabcoReadAddr + 1; --Sinus_WabcoReadAddr ist die Adresse zu den Sinuswerten. Über ein Dual port Ram lade ich dann die Sinuswerte
7
                end if;
8
            
9
            if Sinus_WabcoReadAddr (6 downto 0) = "00000001" then n_Sinus <= n_Sinus + 1;  --zählt Anzahl der ganzen Sinusse
10
             end if;
11
12
Start <= False;
13
end if;
14
end process;

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


Lesenswert?

Vorab:
1
 signal Zaehler_1: STD_LOGIC_VECTOR (7 downto 0);
2
          Zaehler_1 <= "0000000";
3
               Zaehler_1 <= Zaehler_1 + 1;
4
               if Zaehler_1 >= "0000101" then
Mit Vektoren rechnet man nicht. Nimm doch einen (eingeschränkten) 
Integer, dann kan man das viel besser lesen:
1
 signal Zaehler_1: integer range 0 to 5 := 0;
2
          Zaehler_1 <= 0;
3
               Zaehler_1 <= Zaehler_1 + 1;
4
               if Zaehler_1 >= 5 then

Max schrieb:
> hoffe du verstehst diesen code.
So lala... :-o

Max schrieb:
> ich kriege einfach nicht raus, wie ich ihn sagen soll,
> dass nach einem ganzen Sinus, er variabel Takte warten soll und dann
> erst wieder Ausgeben soll,
Dazu mußt du erst mal die Sinusausgabe und das Warten entkoppeln.
Also brauchst du eine FSM, die Startsignal für 1 Sinus erzeugt, und 
danach die Wartezeit einfügt. Das hier mal als Denkanstoß:
1
 signal wartezaehler: integer := 0;
2
 signal warten: std_logic := '0';
3
4
5
  if rising_edge(clk) then ....
6
7
      if warten='0' then -- Sinus ausgeben
8
           Sinus_WabcoReadAddr <= Sinus_WabcoReadAddr + 1; --Sinus_WabcoReadAddr ist die Adresse zu den Sinuswerten. 
9
            
10
            if Sinus_WabcoReadAddr (6 downto 0) = "00000000" then 
11
                 warten <= '1';
12
            end if;
13
            wartezaehler <= 0;
14
       else              -- Sinus fertig: warten
15
          wartezaehler <= wartezaehler+1; 
16
          if (wartezaehler = 5) then
17
             warten <= '0';
18
             Sinus_WabcoReadAddr <= (others=>'0');
19
          end if;
20
       end if;
21
   end if;

von Max (Gast)


Lesenswert?

Danke für deine Antwort hat geklappt, lediglich musste ich 
Sinus_WabcoReadAddr (6 downto 0) = "00000000" auf das Ende vom Sinus 
beziehen das heißt, Sinus_WabcoReadAddr (6 downto 0) = "1111111", dann 
hats super geklappt, da hab ich wieder was dazu gelernt, hab soviele 
varianten ausprobiert, vielen Dank nochmal.

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


Lesenswert?

Max schrieb:
> lediglich musste ich
> Sinus_WabcoReadAddr (6 downto 0) = "00000000" auf das Ende vom Sinus
> beziehen das heißt, Sinus_WabcoReadAddr (6 downto 0) = "1111111"
Das wusste ich, ich habe dich aber selber raten lassen... ;-)
Der Effekt heißt Latency.

Du hast in diesem Konstrukt übrigens noch einen Takt Latency drin, 
nämlich beim Umschalten des Zustands des signals warten von '0' nach 
'1'. Kann aber ganz gut sein, dass du das nicht merken wirst...

von Max (Gast)


Lesenswert?

ja das habe ich mir schon gedacht, aber vielen dank auch.
hab zwar so gut wie alles hinbekommen, nur eine kleinigkeit fehlt noch, 
bevor ich diese wartezeit eingebaut habe, hat mein Sinus zähler noch 
einwandfrei funktioniert, eigentlich funktioniert er immer noch richtig, 
nur optisch sieht das nicht schön aus, wenn die takte für die wartezeit 
im Sinus zaehler drin sind, der Sinus zähler soll ganze sinusse aber 
ohne die warte zeit zählen. aber mein Sinus zähler muss trotzdem 
abhängig von dem Sinus_WabcoReadAddr sein, da dies ja die werte vom 
Sinus sind, ich probier noch weiter wie ich das hinbekomme, dass der 
Sinuszähler immer zu beginn des Sinus zählt ohne den wartezähler.danke.

von Max (Gast)


Lesenswert?

Guten Morgen,
hab mir überlegt, ich mach mal zwei Zähler, einer läuft normal weiter 
und den andern setze ich zum Zeitpunkt des wartezaehlers immer null und 
wenn wartezähler immer null wird soll der wert des einen Zählers in den 
anderen kopiert werden,
1
if warten='0' then -- Sinus ausgeben
2
              Sinus_WabcoReadAddr <= Sinus_WabcoReadAddr + 1; --Sinus_WabcoReadAddr ist die Adresse zu den Sinuswerten. 
3
                                   
4
              if Sinus_WabcoReadAddr(6 downto 0) = "0000000" then s_Sinus <= s_Sinus + 1;n_Sinus <= n_Sinus + 1; --n_Sinus <= n_Sinus + 1;
5
              end if;
6
              
7
              
8
             if Sinus_WabcoReadAddr (6 downto 0) = "1111111" then 
9
                         warten <= '1';
10
                    end if;
11
                    wartezaehler <= 0;
12
            else              -- Sinus fertig: warten
13
              wartezaehler <= wartezaehler+1; 
14
              
15
              case wartezaehler is
16
                when 0 => n_Sinus <= s_Sinus;
17
                when others => n_Sinus <= "00000000";
18
              end case;
19
              
20
            if (wartezaehler = 25) then
21
                warten <= '0';
22
                Sinus_WabcoReadAddr <= (others=>'0');
23
                --if (wartezaehler >= 0) then 
24
              end if;
25
            end if;

n_Sinus wird zwar zu den Zeiten von wartezähler null aber danach wird er 
nicht durch s_Sinus ersetzt, woran liegt das denn, ich will halt den 
Wert von n_Sinus überschreiben.kannst mit erklären wieso das nicht 
möglich ist.Danke.

von Edi M. (Gast)


Lesenswert?

Wieso erklärst du nicht erst einmal, wann du welchen Abstand zwischen 
was wie vergrößern wilsst. Mit halben Infos ist schwer zu antworten.

von Max (Gast)


Lesenswert?

Hallo,
hab doch im Thread geschrieben, dass ich den Abstand zwischen den 
einzelnen Sinussen variabel verändern will, dass klappt ja auch Lothar 
hat da ja gut geholfen, ich weiß  nicht genau was du jetzt meinst, 
beziehst du dich auf meine letzte Antwort oder auf den ganzen Beitrag. 
Was mir noch fehlt ist, dass mein Sinus Zähler wieder richtig 
funktioniert, er zählt ja die Sinusse aber ich will es optisch besser 
haben, dass der Zähler nur die Sinusse zählt und zu den bei den 
Zuständen des wartezählers der Sinus Zähler z.B Null wird und danach 
wieder den richtigen Wert ausgibt, ich hoffe die Idee ist richtig, wenns 
ne andere Möglichkeit gibt bin ich sehr dankbar

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


Lesenswert?

Zeig doch mal eine Waveform deiner Testbench und zeichne dort ein, was 
du wann wie womit zählen willst...

von Max (Gast)


Angehängte Dateien:

Lesenswert?

Hier eine waveform, so n_Sinus ist mein Sinus Zähler, der soll lediglich 
nur die Sinusse zählen und die wartezeit nicht, der s_Sinus ist derselbe 
Sinus Zähler jedoch war dies meine vorherige Version, bevor ich die 
wartzeit eingebaut hatte, da lief es natürlich noch in ordnung, nun soll 
mein Sinus Zähler so aussehen, wie der n_Sinus, das heißt bei jedem 
Sinus soll er die Richtige Zahl angeben wievielter Sinus gerade ist und 
während des wartezählers soll er null oder dergleichen werden, hab zwar 
hinbekommen, dass n_Sinus während des wartezählers null wird aber habs 
nicht hinbekommen, dass der n_Sinus die Werte von s_Sinus übernimmt.
1
case wartezaehler is
2
                when 0 => n_Sinus <= s_Sinus;
3
                when others => n_Sinus <= "00000000";
4
              end case;
solange wartezähler null ist soll n_Sinus die Werte von s_Sinus 
übernehmen, aber bei anderen werten soll n_Sinus null werden.

was meint ihr.Danke.

von PittyJ (Gast)


Lesenswert?

Hätte da nicht ein normales if then else gereicht?
Das case ist ja richtig abenteuerlich.

von Duke Scarring (Gast)


Lesenswert?

PittyJ schrieb:
> Hätte da nicht ein normales if then else gereicht?
Betimmt.

Und mit
1
n_Sinus <= "10000000";
bleibt er vielleicht auch in der "Mitte" stehen und nicht "unten" ;-)

Duke

von Max (Gast)


Lesenswert?

das bringt doch gar nichts, dann zeigt er während der wartezeit 128 und 
dann für den darauffolgenden sinus 129 und das periodisch, ist nichts 
anderes wie 0 und dann auf 1 zählen, hat mir leider nichts gebracht, 
vielleicht mach ich da einen Denkfehler, in der sprache c ist es ganz 
einfach, das überschreiben von variablen, danke trotzdem für deine hilfe

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


Lesenswert?

Naja, es reicht nicht aus, eine Waveform darzustellen, man muß schon ein 
wenig was draus heraus und dort hineininterpretieren können...

von Max (Gast)


Lesenswert?

was genau willst du denn wissen, hab doch unterhalb der waveform doch 
erklärt was was ist, ist da noch was unklar ist, dann bitte darauf 
hinweisen, da ch nicht ganz weis was genau du jetzt wissen willst.danke.

von Max (Gast)


Angehängte Dateien:

Lesenswert?

Guten Morgen,
hab nochmal die wave Form erläutert, hab diesmal Farben benutzt um 
besser verstehen zu können. In der roten Umrahmung soll die eigentliche 
Anzahl der Sinusse stehen, der Zähler soll sozusagen, nur bis zum Énde 
des Sinus zählen und dann soll er während des wartezählers null´werden, 
dies soll anhand der blauen Umrahmung klar gestellt werden, dass habe 
ich ja immerhin hinbekommen, dass der Sinus Zähler auf null wird, dann 
soll der Sinus Zähler den nächsten Sinus eins höher zählen das sie´ht 
man in der grünen Umrahmung. in der Violetten Umrahmung also die untere 
Färbung ist mein alter Sinus Zähler, der bevor der wartezähler eingebaut 
wurde richtig funktionierte, aber nun aufgeund des Wartezählers, die 
Wartezeit mit einbezieht. im hellblauem Kreis sieht man ganz schwach, 
dass der Sinus Zähler für einen Takt seinen Zustand wechselt, als ich es 
gezoomt hatte, stand da tatsächlich der Wert drin, den ich vom s_Sinus 
kopiert hatte und in n_Sinus eingefügt hatte, was ich nicht verstehe 
ist, dass laut meiner Zuweisung, der Zustand beibehalten werden sollte, 
solange wartezähler null ist:
1
              case wartezaehler is
2
                when 0 => n_Sinus <= s_Sinus;
3
                when others => n_Sinus <= "00000000";
4
              end case;

ich komm da leider nicht mehr weiter wäre ich dankbar wenn mir einer 
weiterhelfen könnte.danke.

von Duke Scarring (Gast)


Lesenswert?

Entweder Du drückst Dich zu konfus aus, oder meine Auffassungsgabe ist 
zu beschränkt. Willst Du jetz die Perioden zählen? Oder die Länge der 
Pausen? Wann soll denn Dein Zähler zurückgesetzt werden?

Duke

von Max (Gast)


Lesenswert?

ich will die Perioden zählen, nicht die Pausen, was ich jedoch will ist, 
man sieht doch in der waveform, dass s_Sinus (alter Sinus Zähler) die 
Pause mitzählt oder?? ist das nicht der Fall, was ich will ist, das 
n_Sinus (der neue Sinus Zähler), natürlich auch die Perioden zählt aber 
ohne die Pause zu beinhalten man sieht doch in der wavgorm, dass n_Sinus 
die erste Periode 1 zählt, dann während der Pause null anzeigt, dann 
jedoch soll der sinus zähler normalerweise die nächste periode 2 
hochzählen, und während der Pause einfach nur null ist, wie in der 
waveform, nur dort zählt der Zähler immer nur bis eins, da ich den 
zähler bei jeder Periode auf null setze während der Pause, ich hatte 
gedacht, das wenn ich einen weiteren Sinus zähler habe, den s_Sinus, 
dass ich seinen Wert in n_Sinus übeschreibe und zu jeder Periode dieser 
den Wert von s_Sinus übernimmt, hoffe du verstehst jetzt was ich sagen 
will.Danke.

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


Lesenswert?

Max schrieb:
> jedoch soll der sinus zähler normalerweise die nächste periode 2
> hochzählen, und während der Pause einfach nur null ist
Das ist dein Denkfehler! Es ist ganz einfach: wenn der Zähler mitzählen 
soll, dann darf er in der Pause nicht zurückgesetzt werden...

> da ich den zähler bei jeder Periode auf null setze während der Pause
Warum denn überhaupt?

Ein Tipp: mit Punkten im Text lassen sich abgeschlossene Einheiten 
zusammenfassen und als Satz definieren...  :-/

von Max (Gast)


Lesenswert?

Na gut, wenns keine andere Möglichkeit gibt belasse ich dann hierbei, 
das heißt die Anzahl der Perioden beinhaltet eine Periode des Sinus plus 
die Pause. Dann lass ich den s_Sinus so wie er ist.

Die Pause gehört doch nicht zur Sinus Periode, deshalb wollte ich, dass 
diese nicht in den Zähler eingebunden wird. sagen wir so ich will den 
Zähler nicht auf null setzten, aber damit während der Pause nichts 
angezeigt wird, muss ich doch irgendwie den Wert auf null bringen und 
dann weiter ausgeben.

Lothar Miller schrieb:
> Ein Tipp: mit Punkten im Text lassen sich abgeschlossene Einheiten
>
> zusammenfassen und als Satz definieren...  :-/

ja beim tippen hab ich wohl nicht aufgepasst, hab zu schnell getippt.

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


Lesenswert?

Max schrieb:
> die Anzahl der Perioden beinhaltet eine Periode des Sinus plus
> die Pause. Dann lass ich den s_Sinus so wie er ist.
Klar, weil die Pause ja die Anzahl der ausgegebenen Sinuszyklen nicht 
ändert. Wenn du z.B. Holz hackst, und 456 Scheite kleingemacht hast, 
dann hast du auch nach und während einer kurzen Vesperpause immer noch 
456 Scheite...

> Die Pause gehört doch nicht zur Sinus Periode, deshalb wollte ich, dass
> diese nicht in den Zähler eingebunden wird.
Die Pause gehört nicht dazu, sie ändert aber auch nichts.

von Max (Gast)


Lesenswert?

Danke nochmal für alles, dann habe ich wohl einen Denkfehler gemacht und 
hab wohl in einem Dilemma gesteckt. Hast trotzdem viel geholfen und ich 
konnte weites gehend meine Aufgaben erfüllen. Danke auch an allen 
Anregungen.

von Max (Gast)


Lesenswert?

Hallo leute,
hab wieder was neues und brauche euere Hilfe dazu.

Den Abstand zwischen den Sinussen konnte ich ja realsieren, nun möchte 
ich gerne die Amplitude der Sinusse ändern können. Je größer die 
Frequenz wird umso größer wird ja auch die Amplitude. Wie kann man sowas 
in vhdl realisieren.

Hab mir überlegt, dass ich die Sinuswerte mit einer konstanten 
multipliziere und die wiederum mit der Frequenz.

was denkt ihr.Danke Nochmals.

von Max (Gast)


Lesenswert?

Ich hätte da nochwas, zum Abstand des Sinus. mir fällt auf, dass wenn 
ich für den wartezähler 0 einstelle der zwischen den Sinussen doch noch 
eine Lücke lässt, weil er ja zuum nächsten takt reagiert, wie kann ich 
nun das verbessern, wenn ich eine 0 einstelle dann darf da keine lücke 
sein und es soll ein sauberer Übergang vom Sinus zum Sinus 
stattfinden.Danke.

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


Lesenswert?

Max schrieb:
> Hab mir überlegt, dass ich die Sinuswerte mit einer konstanten
> multipliziere
Das ist üblich, aber...

> und die wiederum mit der Frequenz.
...wie soll das gehen?

> die Amplitude der Sinusse ändern
Du multiplizierst einfach den 8-Bit Wert, den du jetzt noch ausgibst, 
mit einer 2. Zahl, die von 0..255 geht, und schneidest von dem Produkt 
die unteren 8 Bit ab. Das wars.

von NoMatter (Gast)


Lesenswert?

Hallo,
ich brauche dringend Hilfe bei VHDL programmieren.
Ich habe mit Excel eine Sinus Tabelle mit 128 Stützwerten erstellt. 
Hährend der Hardwaretests festgestellt, dass der Sinus im 
Spannungsbereich des DA Wandlers nicht passt, muss also angepasst 
werden. In meinem Code hame ich einen Multiplikator drin, womit dei 
Amplitude vom Sinus verändert werden kann, das problem ist nun, dass die 
Sinus Tabelle ja laut y=mx+b einen offset mit drin hat, wenn ich aber 
meinen Multiplikator anwende, wird natürlich das Offset auch mit 
multipliziert, deshalb wird der Offset mach der Multiplikation addiert. 
Meine Frage nun, wenn ich meine Tabelle ohne den Offset erstelle, habe 
ich immer noch negative Werte in meiner Tabelle, durch den Offset wurden 
ja vorher positive werte generiert, und dann einen negativen Wert in Hex 
uinzuwandeln kommt ja humgug dabei raus, wie kann ich nun meine Sinus 
Tabelle ohne Offset erstellen und anschließend alle Werte in Hex 
umwandeln, da die dann in dem Dual port Ram agelegt werden.Danke für 
jede HIlfe.

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


Lesenswert?

NoMatter schrieb:
> ich brauche dringend Hilfe bei VHDL programmieren.
Fang doch besser einen neuen Thread an, wenn du eine komplett neue Frage 
hast...

> Ich habe mit Excel eine Sinus Tabelle mit 128 Stützwerten erstellt.
Dir reicht ein Viertel vom Sinus aus....
Und warum mit Excel? Du kannst mit VHDL rechnen:
http://www.lothar-miller.de/s9y/archives/37-DDFS-mit-BROM.html

> Meine Frage nun, wenn ich meine Tabelle ohne den Offset erstelle, habe
> ich immer noch negative Werte in meiner Tabelle
Wenn du "nur" das erste Viertel vom Sinus ablegst (oder auch die erste 
Halbwelle), dann hast du nur positive Werte.
Schritt 1: du berechnest einen Siuns ohne Offset. Dafür gibt es z.B. den 
Datentyp Integer, der super mit negativen Zahlen zurechtkommt.
Schritt 2: du skalierst den Wert so hoch, dass er zum DAC und der 
gewünschten Amplitude passt.
Schritt 3: du addierst einen evtl. nötigen Offset dazu
Schritt 4: du gibst das an den DAC aus

Aber: der Sinus ist ganz und gar nicht dein Problem. Dein Problem ist, 
dass du dir nicht vorstellen kannst, wie diese Zahlen in der Hardware 
von der Tabelle über den DAC zu einem schönen Sinus werden. Das mußt du 
mal grundlegend durchdenken und aufzeichnen...

von NoMatter (Gast)


Lesenswert?

Danke für deine ausführliche Antwort, mit excel rechne ich deshalb, da 
ich die Werte in Hex brauche um dann in mein Dual Port Ram in das .COE 
file reinschreiben will um die dann auszulesen. Deshalb Excel.

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


Lesenswert?

NoMatter schrieb:
> Deshalb Excel.
Wie gesagt: das ist kein Grund. Das geht ganz ohne COE Datei, denn auch 
mit der Formel, die ich verlinkt habe, wird ein Blockram gefüllt.

von NoMatter (Gast)


Lesenswert?

Ja ne, dass habe ich schon verstanden, aber meine Aufgabe ist gebunden 
an dieser COE file, da werden default werte abgelegt, die beim 
einschalten der HArdware, einfach vorhanden sein müssen, bevor es 
losgeht.Danke.

von Klaus F. (kfalser)


Lesenswert?

Du legst die Tabelle ohne Offest an und addierst den Offset in der 
Hardware dazu, kurz bevor Du die Werte zum DAC schickst.

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


Lesenswert?

NoMatter schrieb:
> da werden default werte abgelegt,
> die beim einschalten der HArdware, einfach vorhanden sein müssen
Nur nochmal zur Verdeutlichung:
Das wird mit den Werten, die mein Code anlegt ebenfalls so sein: da 
wird nicht nach dem Einschalten erst mal was berechnet, das macht 
bereits der Synthesizer!

von Max (Gast)


Lesenswert?

Hallo Klaus, das ist ja das problem, ohne Offset ist die Tabelle negativ 
und negative Werte kann ich in Hex nicht umwandeln, ich arbeite nunmal 
mit Hexwerten, Das ist auch die Idee die ich realisieren werde. erst 
brauche ich eine Sinus Tabelle mit positiven Werten. Hab mir überlegt 
die Tabelle mit dem Datentyp Integer zu realisieren, hab in einem 
anderen Beitrag auch die Frage gestellt, ob man den Integer Datentyp in 
ein coe file des Block Ram Memory eines Dual Pórt Rams verwenden 
kann.Danke.

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.