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
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.
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
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.
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
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.
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:
1
process(DATA_LOADED,DATA_IN_SIG)
2
begin
3
ifDATA_LOADED='1'then
4
if(MAX_SIG<DATA_IN_SIG)then-- Ja, holla: MAX_SIG fehlt in der Senslist
5
MAX_SIG<=DATA_IN_SIG;
6
MAX_VAL<=DATA_IN;-- Ja, holla: DATA_IN fehlt in der Senslist
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 :)
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
Also ich weiß nicht wo das Problem liegen soll ...
Pseudocode:
1
WENN MAX_SIG < DATA DANN
2
...
3
ANSONSTEN WENN MAX_SIG > DATA DANN
4
...
5
ANSONSTEN (hier ist MAX_SIG=DATA)
6
...
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.
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... :-(
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?
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.
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...
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
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.
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?
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ß:
process(CLK)-- DATA_IN_S unnötig, der Prozess ist nur auf clk sensitiv
7
begin
8
ifrising_edge(CLK)then
9
CUR_S<=DATA_IN_S;
10
CUR_VAL<=DATA_IN_S;
11
12
if(MAX_S<DATA_IN_S)then
13
MAX_S<=DATA_IN_S;
14
MAX_VAL<=DATA_IN_S;
15
elsif(MIN_S>DATA_IN_S)then
16
MIN_S<=DATA_IN_S;
17
MIN_VAL<=DATA_IN_S;
18
endif;
19
20
endif;
21
endprocess;
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:
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.
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.