mikrocontroller.net

Forum: FPGA, VHDL & Co. arithmetische operatoren für regler im vhdl


Autor: wladimir (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
versuche eine regelabweichung zu bilden und differenzengleichung zu 
berechnen. Konvertiere zunächst eingang auf integer, um dann berechnung 
auszuführen. doch wenn ich mir negativwerte auf board anzeigen lasse, 
kommt da nur müll, nachdem ich integer ergebnis zurückkonvertiert habe 
in std_logic_vector. bei positiver regelabweichung haut alles hin, aber 
mit der negativen hauts leider nich hin. hat vielleicht jemand ne idee?

LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_arith.all;
use ieee.std_logic_signed.all;
use ieee.numeric_std.all;

ENTITY regler IS
PORT
(
  ein,clk      :in std_logic;  --EIN/AUS-Schalter für den regler
  x0        :in  std_logic_vector(11 downto 0);
  y0,y1      :out std_logic_vector(7 downto 0);
  e_test      :out std_logic_vector(12 downto 0)
);
END regler;

ARCHITECTURE regler_1 OF regler IS
signal x    :integer;
signal y    :integer;
signal y_1    :integer;
signal e_1    :integer range -2048 to 2048;
signal e_2    :integer range -2048 to 2048;
signal e    :integer range -2048 to 2048;    --regelabweichung


BEGIN
PROCESS(clk,ein,x0)
BEGIN

    --zu beginn y_1,e_1,e_2 sind null

  if (rising_edge(clk) AND ein='1') then

    x <= conv_integer(x0);



    e<=2048-x;  --regelabweichung nur für e>0




    e_test<=conv_std_logic_vector(e,13);


    y<=y_1+(10*e)-(20*e_1)+(10*e_2);     --PD-Algorithmus

      if y>0 then
      y0 <= conv_std_logic_vector(y,8);
      end if;

      if y<0 then
      y1 <= conv_std_logic_vector(y,8);
      end if;


    y_1<=y;                --neuer vorheriger stellwert
    e_2<=e_1;
    e_1<=e;                --neue vorherige regelabweichung


  end if;

END PROCESS;

END regler_1;

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

Bewertung
0 lesenswert
nicht lesenswert
wladimir schrieb:
Entweder:
> USE ieee.std_logic_arith.all;
> use ieee.std_logic_signed.all;
Oder besser die neuere:
> use ieee.numeric_std.all;
Aber niemals beides zusammen, weil dann ein paar Typkonvertierungen 
doppelt vorhanden sind...

> ... integer range -2048 to 2048;
Warum ist das ungünstig?
Und warum kann ich behaupten, dass das hier deutlich besser wäre:
 ... integer range -2048 to 2047;

> bei positiver regelabweichung haut alles hin, aber
> mit der negativen hauts leider nich hin.
Was erwartest du und was bekommst du?

Autor: wladimir (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
so jetzt haut das mit der regelabweichung zumindest hin aber bei der 
differenzengleichung macht er nicht was er soll.

LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_arith.all;
use ieee.std_logic_signed.all;

ENTITY regler IS
PORT
(
  ein,clk      :in std_logic;  --EIN/AUS-Schalter für den regler
  x0        :in  std_logic_vector(11 downto 0);
  y0,y1      :out std_logic_vector(7 downto 0)
  --e_test      :out std_logic_vector(7 downto 0)
);
END regler;

ARCHITECTURE regler_1 OF regler IS
signal x    :integer range -2048 to 2047;
signal y    :integer range -32760 to 32760;
signal yp    :integer range -32760 to 32760;
signal y_1    :integer range -32760 to 32760;
signal e_1    :integer range -128 to 127;
signal e_2    :integer range -128 to 127;
signal e    :integer range -128 to 127;


BEGIN
PROCESS(clk,ein,x0)
BEGIN

    --zu beginn y_1,e_1,e_2 sind null

  if (rising_edge(clk) AND ein='1') then

    x <= conv_integer(x0);


    --regelabweichung
    e<=2048-x;



    --nur zum testen, ob integerwerte korrekt?
    --if e<0 then
      --if e>-70 then
      --y0<="11111111";
      --else y0<="11110000";
      --end if;
    --else y0<="00000000";
    --end if;



    --PD-Algorithmus (Differenzengleichung)
    y<=y_1+(15*e)-(30*e_1)+(15*e_2);

    y_1<=y;
    e_2<=e_1;
    e_1<=e;


    --nur zum testen, ob y korrekt berechnet?
      if y<0 then
      y0<="00001111";
      else
      y0<="11110000";
      end if;




      --if y>0 then
      --e_test<="00001111";  --zum test--
      --y0 <= conv_std_logic_vector(y,8);
      --y1 <= "00000000";
      --else
      --yp <= y*(-1);
      --e_test<="11110000";  --zum test--
      --y1 <= conv_std_logic_vector(yp,8);
      --y0 <= "00000000";
      --end if;

  end if;

END PROCESS;

END regler_1;


für y0 müsste eigentlich jeweils nur eine gruppe vierer bits leuchten 
bleibt aber nur bei einer hängen, obwohl rein mathematisch positiv sowie 
negativ ist.

vielleicht jemand me idee???

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

Bewertung
0 lesenswert
nicht lesenswert
wladimir schrieb:
> für y0 müsste eigentlich jeweils nur eine gruppe vierer bits leuchten
> bleibt aber nur bei einer hängen, obwohl rein mathematisch positiv sowie
> negativ ist.
Das habe ich jetzt nicht verstanden...  :-/
Was ist positiv wie negativ?
Und seit wann leuchten Bits?

Autor: wladimir (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
die bits leuchten doch nur als test, ob das so funktioniert.

das wäre jetzt schon geklärt

nächstes problem ist wieder die differenzengleichung, da das alles 
gleichzeitig berechnet wird, geht folgende anweisung nicht.


  y<=y_1+(15*(e))-(30*(e_1))+(15*(e_2));

    y_1<=y;
    e_2<=e_1;
    e_1<=e;

das wird ja alles im selben takt gemacht, die anweisung, deswegen kann 
ich ja nicht y zu y_1 zuweisen und y erneut berechnen

denkfehler, dachte erst, dass das sequentiell abgearbeitet wird

vielleicht jemand ne idee???

Autor: Segor (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich nehme an, es geht wegen des timings nicht?

Dann musst Du es aufteilen und Zwischenergebnisse parallel berechnen.

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.