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


von wladimir (Gast)


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;

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


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?

von wladimir (Gast)


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

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


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?

von wladimir (Gast)


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

von Segor (Gast)


Lesenswert?

Ich nehme an, es geht wegen des timings nicht?

Dann musst Du es aufteilen und Zwischenergebnisse parallel berechnen.

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.