mikrocontroller.net

Forum: FPGA, VHDL & Co. Case konstrukt


Autor: Jan O. (Firma: keine) (quamstar)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo liebe Leute,

ich hab momentan folgendes Problem ich will 3 sachen unterscheiden, 
größer als, kleiner als und ist gleich wie. Jeder würde sachen, alles 
klar machen wir ein Case-Konstrukt, allerdings meckert mein Compiler, 
das würde nicht gehen. Vll hab jemand von Euch ja noch eine Lösung

case DATA_IN_SIG is

when (MAX_SIG < DATA_IN_SIG) =>
MAX_SIG <= DATA_IN_SIG;
MAX_VAL <= DATA_IN;

when (MIN_SIG > DATA_IN_SIG) =>
MIN_SIG <= DATA_IN_SIG;
MIN_VAL <= DATA_IN;

when others    =>
UR_VAL <= DATA_IN;

end case;

Danke im Voraus

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

Bewertung
0 lesenswert
nicht lesenswert
Jan Egal schrieb:
> allerdings meckert mein Compiler
Und was meckert er?
Dass es nicht in einem Prozess steht (case geht nur in einem Prozess)?
Zeig doch mal die ganze Datei...

BTW: Wenn du das kombinatorisch machst, dann wird er auf jeden Fall ein 
paar Latches anmeckern.

Autor: mac4ever (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sowas würde keiner in einem CASE machen, da CASE kein "größer" oder 
"kleiner" kennt. Der CASE vergleicht auf Gleichkeit.

Mach es mittels IF THEN ELSE
if MAX_SIG < DATA_IN_SIG then
 MAX_SIG <= DATA_IN_SIG;
 MAX_VAL <= DATA_IN;
elsif MAX_SIG > DATA_IN_SIG then
 MIN_SIG <= DATA_IN_SIG;
 MIN_VAL <= DATA_IN;
else
 UR_VAL <= DATA_IN;
end if;

Autor: Jan O. (Firma: keine) (quamstar)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
if MAX_SIG < DATA_IN_SIG then
 MAX_SIG <= DATA_IN_SIG;
 MAX_VAL <= DATA_IN;
elsif MAX_SIG > DATA_IN_SIG then
 MIN_SIG <= DATA_IN_SIG;
 MIN_VAL <= DATA_IN;
else
 UR_VAL <= DATA_IN;
end if;


das klappt erstaunlicher weise nicht. Das gibt nur Grütze bei der 
Simulation, leider.

Komplett sieht das so aus:


library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;

-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity MIN_MAX_CUR is
    Port ( CLK : in STD_LOGIC;
        DATA_IN : in  STD_LOGIC_VECTOR (7 downto 0);
           CALC_EN : in STD_LOGIC;
        RAM_ADR : in STD_LOGIC_VECTOR (7 downto 0);
        MAX_VAL : out  STD_LOGIC_VECTOR (7 downto 0);
           MIN_VAL : out  STD_LOGIC_VECTOR (7 downto 0);
           CUR_VAL : out  STD_LOGIC_VECTOR (7 downto 0));
end MIN_MAX_CUR;

architecture Behavioral of MIN_MAX_CUR is

signal DATA_IN_SIG : STD_LOGIC_VECTOR (7 downto 0);
signal MAX_SIG : STD_LOGIC_VECTOR (7 downto 0):="00000000";
signal MIN_SIG : STD_LOGIC_VECTOR (7 downto 0):="00000000";
signal CUR_SIG : STD_LOGIC_VECTOR (7 downto 0):="00000000";
signal DATA_LOADED : std_logic;




begin


process (CLK)
begin


    if rising_edge (CLK)  then
      if CALC_EN = '1' then
        DATA_IN_SIG <= DATA_IN;
        CUR_VAL <= DATA_IN_SIG;
      end if;
    end if;

end process;
DATA_LOADED <= '1';

process (DATA_LOADED, DATA_IN_SIG)
begin


          if DATA_LOADED = '1' then
            if (MAX_SIG < DATA_IN_SIG) then
            MAX_SIG <= DATA_IN_SIG;
            MAX_VAL <= DATA_IN;

            else
            MIN_SIG <= DATA_IN_SIG;
            MIN_VAL <= DATA_IN;

            end if;
          end if;


--          case DATA_IN_SIG is
--
--          when (MAX_SIG < DATA_IN_SIG) =>
--          MAX_SIG <= DATA_IN_SIG;
--          MAX_VAL <= DATA_IN;
--
--          when (MIN_SIG > DATA_IN_SIG) =>
--          MIN_SIG <= DATA_IN_SIG;
--          MIN_VAL <= DATA_IN;
--
--          when others    =>
--          CUR_VAL <= DATA_IN;
--
--          end case;


end process;

end Behavioral;

den case hab ich ma auskommentiert. Die IF abfrage funzt so wie sie ist 
gut, nur wenn irgendwann mal einer gleicher wert auftritt gehts in die 
Hose

Autor: mac4ever (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Aus diesem Grund macht man
if ...>... then
 ...
elsif ...<... then
 ...
else
 ...
end if;

Autor: Christian R. (supachris)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jan Egal schrieb:
> use IEEE.NUMERIC_STD.ALL;
> use IEEE.STD_LOGIC_UNSIGNED.ALL;

Und das macht man schon gar nicht. Vor allem nicht bei Rechnerei und 
Vergleichen.
Nimm mal lieber nur die numeric_std und ersetze die Vektoren in den 
Vergleichen durch singned bzw. unsigned.

Autor: Steffen H. (avrsteffen)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich sehe gerade, dass hier in zwei Prozessen "CUR_VAL" ein Wert 
zugewiesen wird.

Geht das denn überhaupt?

Gruß
Steffen

Autor: mac4ever (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nein, das geht nicht ... da wird auch der Fehler liegen.

Lothar Miller schrieb:
>> allerdings meckert mein Compiler
> Und was meckert er?

Die Informationen hätte wirklich geholfen :)
Wahrscheinlich: Multiple Driver Error

Autor: Georg A. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hm, was ist "der" Compiler? Für die Simulation würde er (ghdl, modelsim, 
...) das mit den multiplen Treibern nicht bemeckern, das geht 
einwandfrei,s olange man nicht ulogic nimmt. Wird halt vermutlich 
dauernd eine Kollision (X) rauskommen ;) xst wirds nicht schlucken.

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

Bewertung
0 lesenswert
nicht lesenswert
Georg A. schrieb:
> xst wirds nicht schlucken.
Auch kein andrer Syhtesizer nicht.
Denn so ein Bauteil, das das könnte, gibt es nicht auf einem FPGA...

Und ich höre mich noch sagen:
Lothar Miller schrieb:
> BTW: Wenn du das kombinatorisch machst, dann wird er auf jeden Fall ein
> paar Latches anmeckern.

Zudem ist die Sensitivliste unvollständig:
process (DATA_LOADED, DATA_IN_SIG)
begin
          if DATA_LOADED = '1' then
            if (MAX_SIG < DATA_IN_SIG) then -- Ja, holla: MAX_SIG fehlt in der Senslist
              MAX_SIG <= DATA_IN_SIG;
              MAX_VAL <= DATA_IN;       -- Ja, holla: DATA_IN fehlt in der Senslist
            else
              MIN_SIG <= DATA_IN_SIG;
              MIN_VAL <= DATA_IN;
            end if;
          end if;
:
:



Christian R. schrieb:
> Jan Egal schrieb:
>> use IEEE.NUMERIC_STD.ALL;
>> use IEEE.STD_LOGIC_UNSIGNED.ALL;
> Und das macht man schon gar nicht.
Jan Egal ist das egal:
Beitrag "Re: Mittelwertberechnung aus vier 8-Bit Zahlen"
Man könnte das auch beratungsresitent bezeichnen...  :-(

Autor: Christian R. (supachris)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Lothar Miller schrieb:
> Jan Egal ist das egal:
> Beitrag "Re: Mittelwertberechnung aus vier 8-Bit Zahlen"
> Man könnte das auch beratungsresitent bezeichnen...  :-(

Hm, schlimm. Das blöde ist, dass es meistens klappt. Aber manchmal eben 
nicht :)

Autor: Jan O. (Firma: keine) (quamstar)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das hat nichts mit beratungsresistenz zu tun, ich nur kann der simple 
additionen nicht ausführn wenn die unsigned fehlt. Habs bisher nur auf 
diese Weise gemacht/gelernt. Und in diesem Funktionsblock hat das m.E. 
keinen EInfluss kann diese auch gern rausnehmen.

CUR_VAL ist wenn man hinsieht nur in einem process enthalten, da 
"case..." auskommentiert ist. Das es mit case nicht funzt ist mir auch 
klar, allerdings habe ich das Problem das der mit einem IF THEN ELSE 
konstrukt probleme bei dem Werte vergleich macht, CUR und MAX 
funktionieren einwandfrei leider nur nicht MIN und da is der Hund in der 
IF geschichte begraben

Autor: mac4ever (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also ich weiß nicht wo das Problem liegen soll ...

Pseudocode:
WENN MAX_SIG < DATA DANN
  ...
ANSONSTEN WENN MAX_SIG > DATA DANN
  ...
ANSONSTEN (hier ist MAX_SIG=DATA)
  ...

Die Ursache liegt mit Sicherheit nicht bei der IF-Anweisung. Prüfe 
nochmal die Eingangsdaten ...
Außerdem: Wenn Du es schon kombinatisch (also ohne Takt) versuchst, dann 
kodiere bitte auch alle IF-Zweige aus. Auch wenn dort nicht zu tun ist. 
Weise einfach das Signal sich selbst du.

Aber das wurde ja bereits zweimal erwähnt ...

Lothar Miller schrieb:
> Und ich höre mich noch sagen:
> Lothar Miller schrieb:
>> BTW: Wenn du das kombinatorisch machst, dann wird er auf jeden Fall ein
>> paar Latches anmeckern.

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

Bewertung
0 lesenswert
nicht lesenswert
Jan Egal schrieb:
> Das hat nichts mit beratungsresistenz zu tun, ich nur kann der simple
> additionen nicht ausführn wenn die unsigned fehlt.
Klar: du kannst Additionen mit std_logic-Vektoren nicht ausführen!
Und das ist gut so, denn: *Mit Vektoren rechnet man nicht.*
Dfür gibt es die Datentypen signed und unsigned...

Jan Egal schrieb:
> Die IF abfrage funzt so wie sie ist gut, nur wenn irgendwann mal
> einer gleicher wert auftritt gehts in die Hose
Nein. Dann wird der else-Pfad ausgeführt.
Oder sag mal, was in die Hose geht...

Jan Egal schrieb:
> Komplett sieht das so aus:
Wenn das der gesamte Code ist, dann kann das nicht stimmen:
Jan Egal schrieb:
> CUR und MAX funktionieren einwandfrei
> leider nur nicht MIN und da is der Hund in der IF geschichte begraben
Es gibt im gesamten Code kein CUR, MAX und MIN. Und wenn damit jeweils 
CUR_VAL, MAX_VAL und MIN_VAL gemeint waren, dann kann die Aussage 
trotzdem nicht stimmen.

BTW: das was du hier machst, ist als Salamitaktik bekannt.
Informationen nur spärlich und nur auf wiederholtes Bitten.
So macht Helfen keinen Spass... :-(

Autor: Jan O. (Firma: keine) (quamstar)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok, dann drück ich ma ein BSP aus wo es nicht gehen wird.

Wenn z.B die DATA_IN folge: 0, 1, 2, 4, 3 erscheint wird das ein Problem 
geben, und zwar deswegen bei dem MIN WERT. MIt dem Quelltext den ihr 
angebt wird dann 3 ausgegeben, und zwar deswegen, weil auf der 4 eine 3 
folgt und diese kleiner ist. Die kleinste Zahl in der Folge ist aber die 
0. Und vorher durchlaufen des processes steht ja nix in den Signale, 
oder kann man durch einen trick diese vordefenieren wie z.B bei einer 
variable?

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

Bewertung
0 lesenswert
nicht lesenswert
Dann machs so:
          if DATA_LOADED = '1' then
            if (MAX_SIG < DATA_IN_SIG) then
              MAX_SIG <= DATA_IN_SIG;
              MAX_VAL <= DATA_IN;
            elsif (MIN_SIG > DATA_IN_SIG) then  ---!
              MIN_SIG <= DATA_IN_SIG;
              MIN_VAL <= DATA_IN;
            end if;
          end if;

Autor: Jan O. (Firma: keine) (quamstar)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
So ich hab nochmal zur besseren übersicht ein Simulationsbild 
rangehängt. Wie man dort sieht wird der Wert MIN_VAL nie bearbeitet, was 
mich schon die ganze Zeit stört. Hier nochmal der Quelltext:

process (CLK)
begin
    if rising_edge(CLK) then
      if CALC_EN = '1' then
      DATA_IN_S <= DATA_IN;
      end if;
    end if;
end process;


process (CLK, DATA_IN_S)
begin


    if rising_edge (CLK) then

        CUR_S <= DATA_IN_S;
        CUR_VAL <= DATA_IN_S;

        if (MAX_S < DATA_IN_S)  then
          MAX_S <= DATA_IN_S;
          MAX_VAL <= DATA_IN_S;



    elsif (MIN_S /= DATA_IN_S) and (MIN_S > DATA_IN_S) then
       MIN_S <= DATA_IN_S;
       MIN_VAL <= DATA_IN_S;


      end if;
    end if;

end process;


Meine Vermutung liegt noch mit darin das MIN_S ja keinen Wert zuvor noch 
keinen Wert besitzt (default = 0?) und somit MIN_S niemals größer sein 
kann als der aktuelle wert DATA_IN, ich schaffe es auch nicht dem MIN_S 
z.B zu begin bevor CALC_EN auf 1 geht, z.B "11111111" zuzuweisen.

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

Bewertung
0 lesenswert
nicht lesenswert
Jan Egal schrieb:
> Meine Vermutung liegt noch mit darin das MIN_S ja keinen Wert zuvor noch
> keinen Wert besitzt (default = 0?)
Ja. So ist das.
Und du selber tust das ja auch noch:
signal MIN_SIG : STD_LOGIC_VECTOR (7 downto 0):="00000000";

Probier mal das:
signal MIN_SIG : STD_LOGIC_VECTOR (7 downto 0):="11111111";


Aber insgesamt ist das Design sowieso vermurkst, so mit den Latches...

Autor: Jan O. (Firma: keine) (quamstar)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Lassen sich die latches durch kombinatorik vermeiden? Als ich habs mal 
so sumuliert und es gibt zumindest (logischer weise) keine 
taktverzögerung mehr.

Das mit der zuweisung ...:="11111111"; klappt ebenfalls nicht

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

Bewertung
0 lesenswert
nicht lesenswert
Jan Egal schrieb:
> Lassen sich die latches durch kombinatorik vermeiden?
Nein.
Latches enstehen durch Kombinatorik.

Vermeiden kannst du die nur, wenn der Takt mit ins Spiel kommt. Denn 
dann werden ganz normale D-FFs zum Speichern hergenommen.

Autor: Jan O. (Firma: keine) (quamstar)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das is doch Taktabhänig, zumindest habe ich in beiden ÜProzessen CLK 
drin. Fällt dir noch eine möglichkeit ein warum der nicht mit dem MIN_S 
klarkommt?

Autor: Clemens M. (panko)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nur mit meinem bescheidenden Wissen:
as ist doch nicht Taktabhängig, du hast einen if(edge)und dann ELSE....

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

Bewertung
0 lesenswert
nicht lesenswert
Jan Egal schrieb:
> Das is doch Taktabhänig, zumindest habe ich in beiden ÜProzessen CLK
> drin.
Richtig.
Clemens M. schrieb:
> Nur mit meinem bescheidenden Wissen:
> as ist doch nicht Taktabhängig, du hast einen if(edge)und dann ELSE....
Das sieht nur so aus bei dieser Formatierung... :-/

Ich würde behaupten, dass das gehen muß:
signal MAX_S : STD_LOGIC_VECTOR (7 downto 0):="00000000";
signal MIN_S : STD_LOGIC_VECTOR (7 downto 0):="11111111";
signal CUR_S : STD_LOGIC_VECTOR (7 downto 0);
:
:
process (CLK) -- DATA_IN_S unnötig, der Prozess ist nur auf clk sensitiv
begin
    if rising_edge (CLK) then
      CUR_S <= DATA_IN_S;
      CUR_VAL <= DATA_IN_S;

      if (MAX_S < DATA_IN_S)  then
        MAX_S <= DATA_IN_S;
        MAX_VAL <= DATA_IN_S;
      elsif (MIN_S > DATA_IN_S) then
        MIN_S <= DATA_IN_S;
        MIN_VAL <= DATA_IN_S;
      end if;

    end if;
end process;

BTW:
Mit den Tags [ vhdl ]  und [ /vhdl ]   (ohne die Leerzeichen) kannst du 
das schöne Syntaxhighlighting nutzen...

Jan Egal schrieb:
> Das mit der zuweisung ...:="11111111"; klappt ebenfalls nicht
Bei mir klappt das bestens. Was machst du falsch?

Wrum machst du das alles doppelt:
        MAX_S   <= DATA_IN_S;
        MAX_VAL <= DATA_IN_S;
MAX_S und MAX_VAL sollen offenbar den selben Wert haben.
Warum nicht so:
signal MAX_S : STD_LOGIC_VECTOR (7 downto 0):="00000000";
signal MIN_S : STD_LOGIC_VECTOR (7 downto 0):="11111111";
signal CUR_S : STD_LOGIC_VECTOR (7 downto 0);
:
:
process (CLK) -- DATA_IN_S unnötig, der Prozess ist nur auf clk sensitiv
begin
    if rising_edge (CLK) then
      CUR_S <= DATA_IN_S;
      if (MAX_S < DATA_IN_S)  then
        MAX_S <= DATA_IN_S;
      elsif (MIN_S > DATA_IN_S) then
        MIN_S <= DATA_IN_S;
      end if;
    end if;
end process;

MIN_VAL <= MIN_S;
MAX_VAL <= MAX_S;
CUR_VAL <= CUR_S;

Autor: Jan O. (Firma: keine) (quamstar)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich glaube ich hab viel zu kompliziert gedacht. Hatte im Kopf das ich 
ständig die Signale sichern muss damit der das unterscheiden kann, daher 
diese doppelzuweisung. Wenn man so versteift auf einen Fehler ist, dann 
sieht den Wald vor lauter Bäumen nicht, Danke Lothar.

Autor: Christian R. (supachris)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bei 2 der Signale hast du am Anfang X, da schreiben irgendwie 2 Prozesse 
offenbar auf das gleiche Signal. Bei nicht initialisiert ist U, das ist 
was anderes. Und wieso wehrst du dich eigentlich immer noch gegen 
unsigned/signed? gerade bei den Vergleichen krieg ich da echt 
Bauchschmerzen mit Vektoren...das Argument, dann geht keine Addition, 
ist doch auch irgendwie völlig daneben. Alles ziemlich verwirrend.

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

Bewertung
0 lesenswert
nicht lesenswert
Christian R. schrieb:
> Alles ziemlich verwirrend.
ACK ;-)

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.