Forum: FPGA, VHDL & Co. verschiedene Teile von std_Ulogic_vector aus mehreren Processen zuweisen


von Erik (Gast)


Lesenswert?

Hallo,


mir hat heute jemand erklärt das es nicht möglich sein soll auf 
verschiedene Teile von einen std_Ulogic_vector aus verschiedenen 
Prozessen zu schreiben und das es bei std_logic_vector problemlos geht 
und er deshalb nur noch std_logic_vector einsetzt.

etwa in der Art :
>>>>>>>>>>>>>>>>>>
architecture rtl of foo is

  signal s_data :std_ulogic_vector(15 downto 0);

begin

  name_a: process(clk,rst)
  begin
    if rst then
      s_data(7 downto 0) <= (others=>'0');
    elsif rising_edge(clk) then
      s_data(7 downto 0) <= i_data_byte_low;
    end if;
  end process;

  name_b: process(clk,rst)
  begin
    if rst then
      s_data(15 downto 8) <= (others=>'1');
    elsif rising_edge(clk) then
      s_data(15 downto 8) <= i_data_byte_high;
    end if;
  end process;

end architecture rtl;
>>>>>>>>>>>>>>>>>

Bei mir, mit aktuellem Synplify und ModelSim, geht das problemlos zu 
synthetisieren/simulieren.


Kennt jemand so ein Problem, eventuell mit älteren Versionen und/oder 
anderen Tools?
Gibt es eventuell irgendwelche Umstände die so ein Konstrukt bei 
std_Ulogic_vector verhindern und bei std_logic_vector zulassen könnten?


Danke schon mal für alle erhellenden Antworten!
Erik

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


Lesenswert?

> Kennt jemand so ein Problem...
Ich vermute, der gute Mensch hat damit (in grauer Vorzeit) mal ein 
Problem gehabt, weil er dem selben Signal aus verschiedenen 
Prozessen etwas zugewiesen, und dann natürlich Probleme bekommen hat. 
Bei einer Umstellung auf std_logic hat er (zufällig) die Doppelzuweisung 
auch enfernt und das Falsche daraus gelernt  ;-)
Unterschiedlichen Teilen von Vektoren aus mehreren Prozessen etwas 
zuzuweisen hat m.W. schon immer funktioniert.


> deshalb nur noch std_logic_vector einsetzt
std_ulogic wurde früher verwendet, um die Simulation zu beschleunigen, 
weil dann nicht jedes Mal die resolution table aufgelöst werden musste. 
Heutzutage ist das 'u' nur unnötige Tipparbeit.

von Erik (Gast)


Lesenswert?

Guten Morgen,


> .... und das Falsche daraus gelernt  ;-)
Sowas in der Art kann ich mir vorstellen, eine andere Erklärung fällt 
mir jedenfalls nicht ein.

> Unterschiedlichen Teilen von Vektoren aus mehreren Prozessen
> etwas zuzuweisen hat m.W. schon immer funktioniert.
Eben, genau dieser Meinung bin ich auch.
Aber ich wollte halt mal fragen weil sich dieser jemand sehr sicher ist, 
ich weis ja schließlich auch nicht alles.


> Heutzutage ist das 'u' nur unnötige Tipparbeit.
Warum, damit stelle ich doch quasi auf ein höheres Warning-Level um.
Ich benutze immer den Typ der meinem Problem am besten entspricht und 
wenn ich kein Tristate-Bus bauen möchte (was in den meisten FPGA auch 
gar nicht geht) verwende ich eben immer mit 'u'. Daraus entsteht IMHO 
doch schließlich kein Nachteil. In C setze ich eine Variable oder 
Funktions-Parameter auch auf 'const' wenn ich sie nicht modifizieren 
möchte.
Ohne 'u' verwende ich immer außerhalb vom FPGA und mit 'u' immer im 
FPGA, damit bin ich seit einigen Jahren immer gut (unfallfrei) gefahren.


Grüße
Erik

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


Lesenswert?

>> Heutzutage ist das 'u' nur unnötige Tipparbeit.
> Warum, damit stelle ich doch quasi auf ein höheres Warning-Level um.
Meinst du.
Mir fällt keine Beschreibung ein, die bei der Synthese auf aktuelle 
FPGAs mit std_ulogic andere Warnungen ausgeben würde als mit std_logic. 
Bei der Simulation mag das anders sein, aber auch dort wird ein 
Buskonflikt bei std_logic mit einem 'X' signalisiert.

> wenn ich kein Tristate-Bus bauen möchte
Tristate-Busse werden auf allen aktuellen FPGAs als Multiplexer 
abgebildet. Deshalb kann es dort gar keine Buskonflikte mehr geben.

Und wenn ich keine Beschreibung für alte FPGAs mache, dann kann ich ohne 
Zaudern die Beschreibungsregeln für alte FPGAs über Bord werfen.
> damit bin ich seit einigen Jahren immer gut (unfallfrei) gefahren.
So war es z.B. vor 100 Jahren auch ratsam, beim Automobil vor dem 
Losfahren den Ölstand zu kontrollieren. Heute tut das keiner mehr.

Der einzige Grund, std_ulogic zu verwenden, bleibt m.E. wie gesagt:
> std_ulogic wurde früher verwendet, um die Simulation zu beschleunigen

von Erik (Gast)


Lesenswert?

Hallo Lothar Miller,


> Mir fällt keine Beschreibung ein, die bei der Synthese auf aktuelle
> FPGAs mit std_ulogic andere Warnungen ausgeben würde als mit std_logic.

Das mehrfache zuweisen aus verschiedenen Prozessen/Instanzen/... auf ein 
Signal ist mit std_ulogic nicht erlaubt. Wenn ich mehrfache Zuweisungen 
nicht will dann benutze ich auch nicht std_logic sondern std_ulogic. 
Wenn ich im Code irgendwo std_logic(_vector) sehe dann bedeutet das 
*"Achtung mehrere Signal-Treiber vorhanden"*.


> Der einzige Grund, std_ulogic zu verwenden, bleibt m.E. wie gesagt:
>>> std_ulogic wurde früher verwendet, um die Simulation zu beschleunigen

Für mich ist es eine Art Vertrag mit mir selbst. Ich erlaube mir nur die 
Dinge die ich auch machen möchte. Wenn ich nicht mehrere Treiber für ein 
Signal will dann erlaube ich mir das auch nicht. Aus dem selben Grund 
benutze ich auch immer Ranges bei Integer.
Diese Erlaubnis lasse ich meine Tools so gut wie möglich abprüfen (in 
VHDL geht das glücklicherweise sehr gut und umfangreich) und wenn ich 
gegen eine Erlaubnis verstoße werde ich gewarnt und kann entweder meinen 
Code anpassen oder mir für bestimmte Dinge (in begründeten Ausnahmen) 
mehr erlauben.


Grüße
Erik

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


Lesenswert?

> Das mehrfache zuweisen aus verschiedenen Prozessen/Instanzen/... auf ein
> Signal ist mit std_ulogic nicht erlaubt.
Das geht auch mit std_logic nicht. Der Synthesizer klopft dir da sofort 
auf die Finger mit dem beliebten Fehler:
1
this signal is connected to multiple drivers
So wie z.B. im Beitrag "this signal is connected to multiple drivers."

> Für mich ist es eine Art Vertrag mit mir selbst.
Das ist allerdings ein stichhaltiger Grund, da kann man nichts 
dagegenhalten  ;-)

> Aus dem selben Grund benutze ich auch immer Ranges bei Integer.
Das macht Sinn, sonst wird jeder Integer in der Synthese mit 32 Bit 
angelegt und muss dann (mit entsprechenden Warnings) mühevoll 
herausoptimiert werden.

von Gast (Gast)


Lesenswert?

Frage:
   http://www.ht-lab.com/question.jpg


Antwort:
   http://www.ht-lab.com/answer.jpg

und wer's nicht glaubt, kann es selber ausprobieren !
(so ist VHDL spezifiziert)

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


Lesenswert?

Gut, ausprobiert und: Richtig, der Simulator sagt das.
Aber die Synthese (also die reale Welt, die harte Hardware) setzt ganz 
einfach alles undefinierte auf '0' und nur das Bit 3 auf '1'.
Ergebnis nach der Synthese also: 00001000     :-o

Treiben wir das Spielchen weiter.
Was kommt da raus:
1
architecture Behavioral of SimpleZuweisung is
2
signal sig : std_logic_vector(7 downto 0);
3
begin
4
   process (sig) begin
5
     for i in 0 to 2 loop
6
       sig(i) <= '0';
7
     end loop;
8
     sig(3) <= '1';
9
   end process;
10
11
   mug    <= sig;
12
end Behavioral;

Und da:
1
architecture Behavioral of SimpleZuweisung is
2
signal sig : std_logic_vector(7 downto 0);
3
begin
4
   process (sig) begin
5
     sig(2 downto 0) <= "000";
6
   end process;
7
   sig(3) <= '1';
8
9
   mug    <= sig;
10
end Behavioral;

Antwort:
beides mal das selbe
Simulation UUUU1000
Synthese   00001000

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


Lesenswert?

Nachtrag:
Der Synthesizer schert sich dabei auch nicht, wenn ich in der Quizfrage 
den Datentyp std_ulogic verwende (wohl aber der Simulator).


So, zum Abrunden jetzt noch die klassische doppelte Zuweisung:
1
architecture Behavioral of SimpleZuweisung is
2
signal sig : std_logic_vector(7 downto 0);
3
begin
4
   process (sig) begin
5
     for i in 0 to 3 loop
6
       sig(i) <= '0';
7
     end loop;
8
   end process;
9
   sig(3) <= '1';
10
11
   mug    <= sig;
12
end Behavioral;

Damit bekommen wir den sattsam bekannten
1
ERROR:Xst:528 - Multi-source in Unit <SimpleZuweisung> on signal <mug<3>>

von Erik (Gast)


Lesenswert?

Hallo,

sorry for my delay.



>> Das mehrfache zuweisen aus verschiedenen Prozessen/Instanzen/... auf
>> ein Signal ist mit std_ulogic nicht erlaubt.
> Das geht auch mit std_logic nicht. Der Synthesizer klopft dir
> da sofort auf die Finger

Aber nicht wenn ich den Zuweisungsprozessen die Möglichkeit gebe 'Z' 
zuzuweisen. Natürlich kann man solche Bösartigkeiten per "Coding-Style" 
bannen aber mir ist es lieber der Compiler verbietet das zuverlässig.


>> Für mich ist es eine Art Vertrag mit mir selbst.
> Das ist allerdings ein stichhaltiger Grund,
> da kann man nichts dagegenhalten  ;-)

Wenn das mein spezieller jemand auch so sehen würde währe mir deutlich 
wohler.


>> Aus dem selben Grund benutze ich auch immer Ranges bei Integer.
> Das macht Sinn, sonst wird jeder Integer in der Synthese mit 32 Bit
> angelegt und muss dann (mit entsprechenden Warnings) mühevoll
> herausoptimiert werden.

Wie viel Mühe sich Synplify geben muss ist mir ehrlich gesagt egal (zu 
viele Warnings soll mein Code natürlich nicht produzieren), mir geht es 
um sauberen Code. Für einen einfachen ganzzahligen Schleifenzähler 
würde ich in C ja auch nicht double nehmen obwohl es genau so gut geht. 
Ich bemühe mich einfach für jedes Problem das richtige, am besten 
geeignete, Werkzeug zu benutzen, für einen einfachen Schleifenzähler in 
C ist das für gewöhnlich int und für Signale in einem FPGA (die 
zumindest bei mir eigentlich immer nur einen Treiber haben dürfen) ist 
das eben std_Ulogic.



zur Quizfrage :

> Gut, ausprobiert und: Richtig, der Simulator sagt das.

Warum geht sig(3) wieder auf 'U' zurück oder wurde die Zuweisung nicht 
ausgeführt?

> Aber die Synthese (also die reale Welt, die harte Hardware) setzt
> ganz einfach alles undefinierte auf '0' und nur das Bit 3 auf '1'.
> Ergebnis nach der Synthese also: 00001000     :-o

Also das, bezogen auf sig(7 downto 4), habe ich noch nicht erlebt. Bei 
mir weigert sich Synplify strikt Signale zu verwenden (nach draußen zu 
führen) denen nichts zugewiesen wird. Deshalb gibt es bei mir in 
unfertigen Modulen oft solche Zuweisungen wie die für sig(3) in der 
Quizfrage um erst mal weiter machen zu können. Falls Synplify jemals die 
Frechheit besitzen sollte eigenmächtig was zuzuweisen wird es aus meiner 
Tool-Chain rückstandsfrei verbannt.
Das Register ohne Reset in realer Hardware natürlich trotzdem '0' oder 
'1' haben und nicht sowas abstraktes wie 'U' oder 'X' ist klar.


> Nachtrag:
> Der Synthesizer schert sich dabei auch nicht, wenn ich in der Quizfrage
> den Datentyp std_ulogic verwende (wohl aber der Simulator).

Warum? Gibt es doch kleine aber feine Unterschiede?



Grüße
Erik

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


Lesenswert?

>> Der Synthesizer schert sich dabei auch nicht, wenn ich in der Quizfrage
>> den Datentyp std_ulogic verwende (wohl aber der Simulator).
> Warum? Gibt es doch kleine aber feine Unterschiede?
An dem Quiz-Screenshot siehst du, das der Simulator Modelsim ist. Mit 
genau dem selben Code erhalte ich für std_logic genau wie im Bild 
"UUUUU000". Der Synthesizer macht "00001000" daraus (und weißt darauf 
hin, dass den Bits 7..4 nichts zugewiesen wird, und die deshalb auf '0' 
gelegt werden).

Mit std_ulogic sagt der Simulator, er könne das Bit 3 nicht auflösen und 
bricht die Simulation ab. Die Synthese macht allerdings ohne weitere 
Meldungen/Warnungen/Info genau das gleiche wie bei std_logic.

von Erik (Gast)


Lesenswert?

Hallo,


> Der Synthesizer macht "00001000" daraus (und weißt darauf hin,
> dass den Bits 7..4 nichts zugewiesen wird, und die deshalb
> auf '0' gelegt werden).

Welchen Synthesizer benutzt Du?

Für die Synthese muss aber noch einiges mehr drum herum als in der 
Quizfrage gezeigt. Diese kleine Architecture ist IMHO so nicht 
synthetisierbar. Das Signal muss mindestens irgendwie nach draußen 
kommen.

Wenn wir das mal so (als Top-Level) ausbauen :
>>>>>>>>>>>>>>>>
entity foo is
  port ( o_sig : out std_logic_vector(7 downto 0) );
end entity;

architecture rtl of foo is

  signal sig :std_logic_vector(7 downto 0);

begin

  process(sig)
  begin
    for i in 0 to 2 loop
      sig(i) <= '0';
    end loop;
  end process;

  sig(3) <= '1';

  o_sig <= sig;

end architecture rtl;
>>>>>>>>>>>>>>>>
sollte das in der Sythese mit dem Fehler "<o_sig(7 downto 4)> is not 
asigned" abbrechen. War bei mir, mit Synplify, bis jetzt immer so. Ich 
würd es gerade so noch akzeptieren wenn Synplify, mit Warning, bei 
o_sig(7 downto 4) keine Output-Buffer für die FPGA-Pins implementiert 
und die Pins in 'Z' bleiben aber wenn es einfach nach gut dünken einen 
Wert festlegt fliegt es von meiner Festplatte. Bis jetzt hat es aber 
immer mit Fehler abgebrochen. Das einzigste was so durchgeht sind 
unbenutzte Inputs für welche Synplify, mit entsprechender Warnung, 
keinen Input-Buffer implementiert und das FPGA-Pin frei bleibt. Macht 
dann üblicherweise beim Place&Route ein Problem wenn der Input-Pin 
bereits in der Pin-Liste zugewiesen ist aber in der Netzliste noch 
fehlt.


> Mit std_ulogic sagt der Simulator, er könne das Bit 3 nicht auflösen
> und bricht die Simulation ab.

Das verstehe ich nicht.
Ist es möglich das es da einen Konflikt wegen der Sensitivlist vom 
Process gibt? Die kommt mir sowieso komisch vor. Ich glaube im ModelSim 
kann man die Delta-Cycles in der Wave-Ansicht ausklappen, probier das 
mal.
Ich denke die Zuweisung für sig(3) wird an 0 ps delta 0 und der Prozess 
an 0 ps delta 1 ausgeführt. Sehe ich das richtig?

> Die Synthese macht allerdings ohne weitere
> Meldungen/Warnungen/Info genau das gleiche wie bei std_logic.

Die Synthese ignoriert ja auch die Sensitivlist. Ist nur ne Vermutung 
aber könnte das ein relevanter Punkt bei diesem speziellem Beispiel 
sein?
Ein Signal das in einem Prozess bedingungslos zugewiesen wird würde ich 
persönlich nicht in die Sensitivlist nehmen, quasi ein kombinatorischer 
Loop.



Grüße
Erik

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


Lesenswert?

> Welchen Synthesizer benutzt Du?
XST

> Wenn wir das mal so (als Top-Level) ausbauen :.....
> sollte das in der Sythese mit dem Fehler "<o_sig(7 downto 4)> is not
> asigned" abbrechen.
Ja bei mir hieß das Signal mug

Und es gab nur eine Warnung, dass die Bits 7..4 nicht initialisiert 
wären und deshalb auf '0' verdrahtet würden. Genau dieses Bild konnte 
ich dann im RTL-Viewer beobachten. Mit dem erhaltenen Bitmuster 
"00001000" waren bis auf Bit 3 alle Bits auf GND verdrahtet und nach 
aussen geführt.

> wenn es einfach nach gut dünken einen
> Wert festlegt fliegt es von meiner Festplatte.
Naja, das Verhalten ist im Manual dokumentiert und eigentlich 
nachvollziehbar. Der Wert wird nicht nach Gutdünken festgelegt, sondern 
es werden alle Signale, die nicht explizit mit einem anderen Wert 
initialisiert werden, mit '0' vorbelegt.

Und es gibt ja eine Warnung, dass da etwas faul ist im Staate Dänemark. 
Die muß man nur zur Kenntnis nehmen ;-)


> Ich denke die Zuweisung für sig(3) wird an 0 ps delta 0 und der Prozess
> an 0 ps delta 1 ausgeführt. Sehe ich das richtig?
Ich habe das Projekt gerade nicht zur Hand, werde es aber nochmal 
genauer untersuchen.


> Die Synthese ignoriert ja auch die Sensitivlist.
Ich habe eher den Verdacht, dass die Synthese solche Signale in 8 
einzelne Signale auftrennt, und die dann getrennt betrachtet.

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Beim XST Simulator macht er das auch, wenn man damit rechnet, da gibts 
dann ne Warnung der Art "There was an X, U, -, Z in an arithmetic 
operation which has ben converted to zero" wenn man z.B. den Addressbus 
eines RAM nicht vorinitialisiert und diesem erst einen Takt später was 
gültiges zuweisst.

von Erik (Gast)


Lesenswert?

Hallo,


> Und es gibt ja eine Warnung, ....

Also für mich ist das benutzen uninitialisierter Signale ein Fehler, 
so wie in Java (dort natürlich Variablen) und den meisten anderen 
Hochsprachen ja auch.


> Ich habe eher den Verdacht, dass die Synthese solche Signale in 8
> einzelne Signale auftrennt, und die dann getrennt betrachtet.

Die einzelnen Elemente eines Vectors müssen ja IMHO auch getrennt 
betrachtet werden. Wenn der Simulator hier Optimierungen einsetzt dann 
sollten die aber nicht zu einem abweichendem Verhalten führen. In der 
Sensitivlist ist aber sig komplett gemeint und nicht nur sig(3). Deshalb 
sollte der Process an 0 ps delta 2 nochmal (weil sig(2 downto 0) von 'U' 
nach '0' wechselten) ausgeführt werden aber dann nicht mehr.


Ich verstehe allerdings immer noch nicht welchen Einfluss std_logic <> 
std_ulogic auf die Quizfrage haben soll.


Grüße
Erik

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


Angehängte Dateien:

Lesenswert?

> und den meisten anderen Hochsprachen ja auch.
C ist das gerade mal ne Warnung wert ;-)

> Die einzelnen Elemente eines Vectors müssen ja IMHO auch getrennt
> betrachtet werden.
Genau das tut der Simulator offenbar nicht.
Wie ich weiter oben schon untersucht habe, geht die Zuweisung des Bit 3 
nur beim Originalcode der Quizfrage so eigenartig schief:
1
   process (sig) begin
2
     for i in 0 to 2 loop
3
       sig(i) <= '0';
4
     end loop;
5
   end process;
6
   sig(3) <= '1';
Ergebnis: UUUUU000

Dieser Effekt tritt nur bei der Simulation der partiellen Zuweisung mit 
der For-Schleife auf. Mit anderen Zuweisungsarten klappt das besser, wie 
bereits im Beitrag "Re: verschiedene Teile von std_Ulogic_vector aus mehreren Processen zuweisen" 
beschrieben.

> Ich verstehe allerdings immer noch nicht welchen Einfluss std_logic <>
> std_ulogic auf die Quizfrage haben soll.
std_logic:  Verhalten wie in der Quizfrage beschrieben
            Ergebnis UUUUU000
std_ulogic: Simulation bricht ab mit der Meldung
1
** Failure: (vsim-3344) Signal 'sig' has multiple drivers but is not a resolved signal.


Eine Antwort war ich noch schuldig:
>> Ich denke die Zuweisung für sig(3) wird an 0 ps delta 0 und der Prozess
>> an 0 ps delta 1 ausgeführt. Sehe ich das richtig?
Nein, dem sig(3) wird mit dem Quizcode sofort 'U' zugewiesen, und es 
ändert sich nicht mehr. Es sieht fast so aus, also ob die zuweisung 
ausserhalb des Prozesses nie ausgeführt wird: sig(3) wird niemals '1' 
(siehe Bild).

Da hilft es auch nichts, wenn ich schreibe
1
   sig(3) <= '1' after 1 ns;

von Erik (Gast)


Lesenswert?

Hallo,


> C ist das gerade mal ne Warnung wert ;-)

ja, leider. (Da könnte man jetzt natürlich diskutieren ob C eine 
/Hoch/-Sprache ist .... aber nicht heute)
Diese Warnung lässt sich sogar einfachst austricksen :
1
myPrint(const int* value) { printf("aktueller Wert ist : %i\n",value); }
2
3
.....
4
5
int myFunc()
6
{
7
  int c;
8
  myPrint(&i);
9
  return(c);
10
}
beachte das const im Parameter von myPrint.

Kann man das beschriebene Verhalten beim XST-Synthesizer abschalten?
Ich werde demnächst wohl mit Xilinx-FPGAs arbeiten dürfen und da hätte 
ich bei solchen Dingen lieber einen richtigen Fehler und nicht nur ne 
Warnung.


> Dieser Effekt tritt nur bei der Simulation
> der partiellen Zuweisung mit der For-Schleife auf.

Ich denke das Konstrukt 'sig(i) <= *' lässt den Simulator nicht erkennen 
das es sich exakt um sig(2 dwonto 0) handelt. Denn für diese Erkenntnis 
müsste er eine Datenfluss-Analyse o.ä. über den Loop machen, ein Problem 
mit dem viele Interpreter zu kämpfen haben. Mit dieser Vereinfachung 
braucht man dann für den ganzen Vector nur eine Signal-Event-Queue. Das 
der Vector in der Simulation als ganzes betrachtet wird würde auch deine 
Fehlermeldung erklären.
In der Synthese hingegen wird der Loop tatsächlich ausgeführt so das 
alles ordentlich funktioniert und sogar mit std_Ulogic_vector kein 
Problem entsteht.


> Nein, dem sig(3) wird mit dem Quizcode sofort 'U' zugewiesen, und es
> ändert sich nicht mehr. Es sieht fast so aus, also ob die zuweisung
> ausserhalb des Prozesses nie ausgeführt wird: sig(3) wird niemals '1'
> (siehe Bild).

Danke für Deine Mühe. Verstehen kann ich das trotzdem nicht. Solche 
Zuweisungen, wie die auf sig(3), hab ich oft in meinem Code (auch auf 
Teile von std_ulogic_vector wo andere Teile ganz normal aus Prozessen 
bedient werden) und die arbeiten immer korrekt.
Wenn die Zuweisung auf sig(3) nicht ausgeführt wird warum wird dann der 
Process ausgeführt? Wenn sich in sig nie etwas ändert dürfte der Process 
IMHO auch nie anspringen.

> Da hilft es auch nichts, wenn ich schreibe ....
Seeehr merkwürdig das Ganze!
Ich bleibe bei der Meinung das die Sensitivlist ungeschickt ist.


Grüße
Erik

von SuperWilly (Gast)


Lesenswert?

Zusammenfassung:

Wenn man es schafft, dem Simulator zu befrieden (keine 'U' o.Ä.),
dann wird man in der Synthese keine Probleme haben.
Umgekehrt kann man in Teufelsküche geraten, wenn man die 
Synthese-"Fehlerfreiheit" als Maßstab für die Simulation verwendet.
Synthese-Tools sind in vielerlei Hinsicht toleranter, was nicht immer
von Vorteil sein muss.

Gruß,
SuperWilly

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


Angehängte Dateien:

Lesenswert?

> Ich denke das Konstrukt 'sig(i) <= *' lässt den Simulator nicht erkennen
> das es sich exakt um sig(2 dwonto 0) handelt.
Es hilft aber auch nicht, wenn ich in der Sensitivity-List des Prozesses 
genau sig(2 downto 0) angebe. Das Gesamt-Verhalten ändert sich nicht 
:-o

Es wird noch merkwürdiger. Was kommt hier raus (mit Initialisierung):
1
signal sig : std_logic_vector(7 downto 0) := (others=>'0');
2
begin
3
   process (sig) begin
4
     for i in 0 to 2 loop
5
       sig(i) <= '1' after 2 ns;
6
     end loop;
7
   end process;
8
   sig(3) <= '1' after 1 ns;
9
   mug    <= sig;
10
end Behavioral;
Ergebnis: siehe Schreenshot  :-/

von Erik (Gast)


Lesenswert?

Hallo,


> Es hilft aber auch nicht, wenn ich in der Sensitivity-List des Prozesses
> genau sig(2 downto 0) angebe.
Dann dürfte der Prozess gar nicht mehr ausgeführt werden da sich in 
sig(2 downto 0) ja ohne den Prozess selber nichts ändert.


Leider fehlt in Deinem Bild die Zeitleiste und der Signalname ist 
unvollständig, ich vermute mal pro grauer vertikaler Linie sind 0,5 ns 
und das das dargestellte Signal irgendwo außerhalb der Entity 
abgegriffen wird.

Das sig(3) zum Zeitpunkt 1 ns von '0' nach 'X', und nicht nach '1', 
wechselt könnte ich mir damit erklären das die Initialisierung als 
zusätzlicher Treiber angesehen wird und damit '0' gegen '1' zu 'X' wird. 
Warum das nicht auch mit sig(2 downto 0) passiert kann ich mir 
allerdings nicht erklären.
Vielleicht wirkt eine Zuweisung aus einem Prozess mehr. ;-)

Das sig(2 downto 0) bereits zum Zeitpunkt 2 ns wechselt, und nicht erst 
zum Zeitpunkt 3 ns, deutet darauf hin das der Prozess sofort nach Start 
der Simulation ausgeführt wird und nicht erst wenn sich sig(3) ändert. 
Dieses Verhalten ist meiner Meinung nach nicht Spezifikationskonform 
oder wirkt die Initialisierung als Event?

Ich vermute mal aus der Synthese kommt "00001111".


Jedenfalls könnte dieses Szenario, teilweise Zuweisung auf einen 
std_ulogic_vector mit Loop, das sein was meinem speziellem jemand 
Probleme (zumindest mit der Simulation) bereitet hat. Quasi eine 
Unzulänglichkeit des Simulators (Vectoren immer als ganzes zu 
betrachten) welche durch ein zusätzliches Feature eines bestimmten 
Datentypes ohne U (Resolverfunktion) ausgeglichen wurde.
Sowas muss ich mal bei mir in ein Projekt einbauen um zu prüfen ob da 
wirklich ein Problem mit std_ulogic_vector und teilweisen Loops 
existiert.


Grüße
Erik

von Morin (Gast)


Lesenswert?

Eine Suche hat folgendes ergeben:

> Ich denke das Konstrukt 'sig(i) <= *' lässt den Simulator nicht erkennen
> das es sich exakt um sig(2 dwonto 0) handelt. Denn für diese Erkenntnis
> müsste er eine Datenfluss-Analyse o.ä. über den Loop machen, ein Problem
> mit dem viele Interpreter zu kämpfen haben. Mit dieser Vereinfachung
> braucht man dann für den ganzen Vector nur eine Signal-Event-Queue. Das
> der Vector in der Simulation als ganzes betrachtet wird würde auch deine
> Fehlermeldung erklären.

Richtig. Der Simulator arbeitet in mehreren Phasen. In einer frühen 
Phase wird für jeden "Draht" (also für jedes Vektorelement einzeln) eine 
Menge von Treibern bestimmt - ein Treiber kann z.B. ein Prozess oder 
eine Concurrent-Zuweisung sein. Die for-Schleife wird zu diesem 
Zeitpunkt noch nicht ausgeführt, deshalb kann nur festgestellt werden, 
dass der Prozess alle Elemente des Vektors treibt (die 
Berechnungsvorschrift dafür nennt sich "longest static prefix"). Die 
Concurrent-Zuweisung treibt nur Element 3. Dieses Verhalten ist 
standardisiert.

Später in der Ausführung haben die Elemente 0..2 den Prozess als 
Treiber, Element 3 hat zwei Treiber, Elemente 4+ haben den Prozess als 
Treiber. Der Prozess-Treiber für 0..2 treibt diese "Drähte" auf 0. Der 
Prozess-Treiber für 4+ verhält sich still, deshalb verbleibt das 'U' 
dort.

Bei Element 3 treibt der Prozess ein 'U', die Concurrent-Zuweisung 
treibt '1'. Fall std_logic: Laut Resolution-Funktion ist 'U' stärker als 
jeder andere Wert, soll heißen: Solange auch nur ein einziger Treiber 
auf einer Leitung noch 'U' treibt, bleibt diese auf 'U'. Fall 
std_ulogic: Mehrere Treiber führen zum Fehler.

> Wenn die Zuweisung auf sig(3) nicht ausgeführt wird warum wird dann der
> Process ausgeführt? Wenn sich in sig nie etwas ändert dürfte der Process
> IMHO auch nie anspringen.

Ich hoffe, das ist jetzt etwas klarer geworden. Die Zuweisung wird 
ausgeführt, sogar "dauerhaft" und "concurrent", ist aber schwächer als 
das vom Prozess getriebene 'U' - ganz analog dazu, dass ein 'H' (z.B. 
pull-up) schwächer ist als '0'.

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


Lesenswert?

> ich vermute mal pro grauer vertikaler Linie sind 0,5 ns
Richtig
> und das das dargestellte Signal irgendwo außerhalb der Entity
> abgegriffen wird.
Richtig, sig wird einem Port namens mug zugewiesen.
Und den sehen wir da.

> Dieses Verhalten ist meiner Meinung nach nicht Spezifikationskonform
> oder wirkt die Initialisierung als Event?
Jeder Prozess wird (entsprechend dem VHDL-Standard) einmal beim 
Simulationsstart und anschliessend bei Änderung eines der Signale der 
Sensitivity-List neu berechnet.

> Sowas muss ich mal bei mir in ein Projekt einbauen um zu prüfen ob da
> wirklich ein Problem mit std_ulogic_vector und teilweisen Loops
> existiert.
Ich bin gespannt ;-)

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


Lesenswert?

> ein Treiber kann z.B. ein Prozess oder
> eine Concurrent-Zuweisung sein.
In seinem tiefsten Inneren und als Ganzes betrachtet ist ein Prozess 
doch genau 1 Concurrent-Anweisung.

Der Knackpunkt ist also
> Die for-Schleife wird zu diesem Zeitpunkt noch nicht ausgeführt...
1
architecture Behavioral of SimpleZuweisung is
2
signal sig : std_logic_vector(7 downto 0);
3
begin
4
   process (sig) begin
5
     for i in 0 to 2 loop
6
       sig(i) <= '0';
7
     end loop;
8
   end process;
9
   sig(3) <= '1';
10
end Behavioral;
Antwort: Simulation UUUUU000

Wenn ich aber einen Bereich angebe schlägt die for-Falle nicht zu? Kann 
hier der Simulator feststellen, dass nur sig(2..0) manipuliert werden. 
Gibt es deshalb keinen Konflikt und auch sig(3) wird (wie erwartet) 
korrekt zugewiesen?
1
architecture Behavioral of SimpleZuweisung is
2
signal sig : std_logic_vector(7 downto 0);
3
begin
4
   process (sig) begin
5
     sig(2 downto 0) <= "000";
6
   end process;
7
   sig(3) <= '1';
8
end Behavioral;
Antwort: Simulation UUUU1000


> Dieses Verhalten ist standardisiert.
Was mich jetzt allerdings ein wenig nachdenklich macht, ist, dass sich 
die Synthese so überhaupt nicht um dieses schräge Standard-Verhalten 
schert :-/
(Und z.B. nur einen Kommentar zu den Bits 4..7 abgibt)

von Morin (Gast)


Lesenswert?

> Was mich jetzt allerdings ein wenig nachdenklich macht, ist, dass sich
> die Synthese so überhaupt nicht um dieses schräge Standard-Verhalten
> schert :-/

Der Standard schweigt sich zur Synthese aus, weil VHDL ofiziell ja nur 
eine Simulationssprache ist und nicht zur Synthese gedacht. Dass 
"Standards" und "Synthese" nicht zusammenpassen musste sicher jeder von 
uns schon schmerzlich erfahren :/

Die Synthese zu standardisieren wäre aber auch nur bedingt sinnvoll. Ein 
vernünftiger Standard legt nämlich - gerade an diesem Beispiel sichtbar 
- auch fest, was nicht geht bzw. was anders geht, als man es sich 
erstmal vorstellt. Ein "oben offener" Standard lässt immer die 
Möglichkeit, eben doch ein Design zu entwerfen, welches doch nur mit 
bestimmten Tools funktioniert, weil es nicht-Standard-Features benutzt. 
Wenn Features vorhanden sind werden sie auch benutzt (wozu sonst 
überhaupt einbauen), und damit wäre der Standard wertlos. Bei den 
Synthesetools ist "oben offen" aber gerade gewünscht, weil die 
Hersteller dann bei ihren Kunden mit den Features der Synthesetools 
punkten können.

Es gab ja mal den Versuch, ein "synthesefähiges Subset" von VHDL zu 
standardisieren. Dieser Standard musste "oben offen" sein: Es war 
erlaubt, mehr zu synthetisieren als der Standard vorgibt, aber nie 
weniger. Resultat: Die Hersteller boten natürlich Tools an, die mehr 
konnten, um beim Kunden zu punkten. Inzwischen ist der Standard kaum 
noch was wert, weil man beim standardkonformen Programmieren viele 
sinnvolle Features nicht benutzen kann (auch solche, die inzwischen 
jedes Tool kann, z.B. Synthese von Signalinitialisierungen).

von Erik (Gast)


Lesenswert?

Hallo,



@Morin:


> ... (die Berechnungsvorschrift dafür nennt sich "longest static prefix").

Danke für diesen Hinweis.


> Der Prozess-Treiber für 4+ verhält sich still,

Und warum verhält er sich nicht auch für sig(3) still?


> Bei Element 3 treibt der Prozess ein 'U',

Warum? Verlangt das der VHDL-Standard?


> Solange auch nur ein einziger Treiber auf einer Leitung
> noch 'U' treibt, bleibt diese auf 'U'.

In dem Screenshot von Lothar Miller (20.04.2009 14:18) sieht man aber 
ein 'X' bei sig(3)! Da kann IMHO niemand ein 'U' treiben. Oder ein 
Bug/Feature von ModelSim?


> Ich hoffe, das ist jetzt etwas klarer geworden.

Wenn der VHDL-Standard das wirklich so will dann verstehe ich ihn jetzt 
noch weniger als vorher. Ist Verilog in dieser Hinsicht besser?


> ... die inzwischen jedes Tool kann,
> z.B. Synthese von Signalinitialisierungen

Bei Actel geht das nicht, dort hat die Signalinitialisierung nur 
Einfluss auf die Simulation.
Ich denke das bei den typischen ASIC-Tool-Chains sowas auch nicht 
unterstützt wird sondern sich dieses Feature allein auf SRAM-Basierte 
FPGAs beschränkt.



@Lothar Miller:


> Wenn ich aber einen Bereich angebe schlägt die for-Falle nicht zu?

Ja. Ich würde das als Bug im Standard bezeichnen. Ich denke nicht das es 
sinnvoll ist die Wirkungsweise einer Zuweisung von umgebenen Konstrukten 
abhängig zu machen.


> Jeder Prozess wird (entsprechend dem VHDL-Standard)
> einmal beim Simulationsstart und ...

Das das auch für Prozesse mit Sensitivity-List zutrifft wuste ich noch 
nicht.
Danke für den Hinweis.



Grüße
Erik

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


Lesenswert?

> In dem Screenshot von Lothar Miller (20.04.2009 14:18) sieht man aber
> ein 'X' bei sig(3)!
Das war allerdings auch mit Initialisierung / :=(others=>'0') /.
Eine 0 (aus der Initialisierung) und eine 1 (nach 1 ns) gibt dann als 
klassischen Treiberkonflikt das X.

von Erik (Gast)


Lesenswert?

Hallo,


> Das war allerdings auch mit Initialisierung / :=(others=>'0') /. ....

Meinst Du das ernst? Ist die Initialisierung wirklich ein Treiber?
Als ich das vorgestern Nachmittag vorschlug hatte ich das nicht wirklich 
ernst gemeint. Außerdem bleibt dann die Frage warum das nicht auch bei 
sig(2 downto 0) passiert.


Also langsam verstehe ich immer weniger.  :-(


Grüße
Erik

von Morin (Gast)


Lesenswert?

> Und warum verhält er sich nicht auch für sig(3) still?

Da ist mir wohl ein Fehler unterlaufen (ich habe diese ganze Sache 
hiermit selbst erst gelernt)... nach meinem Verständnis sendet der 
Prozess-Treiber auch auf 4+ ein 'U'... da hab ich einfach Mist 
geschrieben.

> Warum? Verlangt das der VHDL-Standard?

Ja. Und er verlangt es auch für 4+, wie gesagt das war ein Irrtum. Der 
Standard sagt (soweit ich die Sache verstehe): For-Schleife kann in der 
frühen Phase nicht analysiert werden -> der Prozess treibt den ganzen 
Vektor. Zur Laufzeit entscheidet sich dann, welche Werte er treibt: '0' 
für 0..2, 'U' für 3+.

> In dem Screenshot von Lothar Miller (20.04.2009 14:18) sieht man aber
> ein 'X' bei sig(3)! Da kann IMHO niemand ein 'U' treiben. Oder ein
> Bug/Feature von ModelSim?

Ich denke auch, dass da niemand ein 'U' treiben kann, da wie gesagt 'U' 
stärker ist als alle anderen Werte und diese überschreiben würde. 
Ansonsten hat Lothar ja schon geantwortet.

> Wenn der VHDL-Standard das wirklich so will dann verstehe ich ihn jetzt
> noch weniger als vorher. Ist Verilog in dieser Hinsicht besser?

Leider kann ich dir nicht sagen, wie es bei Verilog aussieht. 'Besser' 
ist aber immer Ansichtssache: VHDL wurde ja bewusst so designed, um eine 
brauchbare Simulationssprache zu sein...

> Bei Actel geht das nicht, dort hat die Signalinitialisierung nur
> Einfluss auf die Simulation.
> Ich denke das bei den typischen ASIC-Tool-Chains sowas auch nicht
> unterstützt wird sondern sich dieses Feature allein auf SRAM-Basierte
> FPGAs beschränkt.

Danke für den Hinweis. Das wird wohl auch der Grund sein, warum es nicht 
Teil des Standards für die Synthese ist.

Das macht aber nur noch deutlicher, warum die Synthese kaum zu 
standardisieren ist: Bei ASICs gibt es keine Initialisierungen, bei 
SRAM-FPGAs ist man im Nachteil wenn man sie nicht benutzt (vor allem bei 
Block-RAMs).

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


Angehängte Dateien:

Lesenswert?

> Meinst Du das ernst? Ist die Initialisierung wirklich ein Treiber?
Nicht die Initialisierung selber, sondern der Initialisierungswert 
zusammen mit der for-Schleife im Prozess. In diesem Prozess wird der 
Initialisierungswert getrieben, solange, bis (bei meinem Code nach 2ns) 
einzelne Signale umgeschaltet werden.
Somit nimmt dieser Prozess jetzt kein 'U' als Voreinstellung für den 
Vektor, sondern den Initialisierungswert "00000000".

Mit 'Z' als Initialisierungswert kann der std_logic aufgelöst werden
(siehe Screenshot):
1
entity SimpleZuweisung is
2
    Port ( mug : out  std_logic_vector (7 downto 0));
3
end SimpleZuweisung;
4
5
architecture Behavioral of SimpleZuweisung is
6
signal sig : std_logic_vector(7 downto 0) := (others=>'Z');
7
begin
8
   process (sig) begin
9
     for i in 0 to 2 loop
10
       sig(i) <= '0' after 2 ns;
11
     end loop;
12
   end process;
13
   sig(3) <= '1' after 1 ns;
14
15
   mug    <= sig;
16
end Behavioral;

von Marcus H. (mharnisch) Benutzerseite


Lesenswert?

Erik wrote:
> Ist Verilog in dieser Hinsicht besser?

Verilog hat ein ganz anderes Konzept. Man kann aus einem always-Block
(entspricht in etwa einem Prozess in VHDL) nur Variablen (vergleichbar
mit unresolved Signalen in VHDL) treiben. Daher existiert dieses
Problem in dieser Form nicht.

Gruß
Marcus
http://www.doulos.com/

von Erik (Gast)


Lesenswert?

Hallo,


entschuldigt bitte das ich da noch mal drauf rum reite aber ich verstehe 
nicht warum das Problem mit dem 'X' auf sig(3) nicht auch auf sig(2 
downto 0) auftritt (auf dem Screenshot von Lothar Miller vom 20.04.2009 
14:18).

Ich habe alle meine letzten Projekte komplett mit std_Ulogc gemacht und 
dort auch oft Signal-Initialisierung verwendet. Da sind nie Probleme im 
ModelSim aufgetreten. Ich hab extra nachgesehen und festgestellt das ich 
auch auf Teile von einem std_Ulogic_vector mit einer for-Schleife 
zuweise und der Rest des Vectors in mehreren anderen Prozessen (manchmal 
mit weiteren for-Schleifen) bzw. normalen Zuweisungen gemacht wird.
Auch wenn ich mich an die Zeiten zurückerinnere wo ich auch im FPGA noch 
std_logic verwendet hatte gab es keine derartigen Probleme.


Im übrigen verstehe ich nicht welchen Sinn eine Initialisierung mit 'Z' 
macht. Ich denke nicht das es FPGAs/ASICs gibt die ihre internen Signale 
mit 'Z' vorbelegen können. Daher gibt es bestimmt viele Leute die ihre 
Signale mit '0' oder '1' initialisieren und bei den meisten wird es kaum 
solche Probleme geben. Ich denke Lothars Bild hat eine andere Ursache. 
Ich weis nur leider nicht welche.



> For-Schleife kann in der frühen Phase nicht analysiert werden
>  -> der Prozess treibt den ganzen Vektor.

Verstanden. Ein klassisches Problem.

> Zur Laufzeit entscheidet sich dann, welche Werte er treibt:
> '0' für 0..2,

ACK

> 'U' für 3+.

Das verstehe ich nicht. Warum tut der Prozess das? Wie ist damit das 'X' 
in Lothars Bild zu erklären? 'U' ist doch stärker als alles andere.
Was tut er für sig(7 downto 4)?
Auf Lothars heutigem Bild (Danke übrigens für Deine Mühen) passiert 
sowas offenbar nicht. Warum?


> VHDL wurde ja bewusst so designed, um eine
> brauchbare Simulationssprache zu sein...

Das Problem das wir gerade diskutieren qualifiziert VHDL nicht gerade 
für die Kategorie "brauchbar".  :-/



Grüße
Erik (der bald noch von VHDL (alb)träumt)

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


Angehängte Dateien:

Lesenswert?

> Ich denke nicht das es FPGAs/ASICs gibt die ihre internen Signale
> mit 'Z' vorbelegen können.
Nein, das war auch nur so eine Spielerei...

> Daher gibt es bestimmt viele Leute die ihre Signale mit '0' oder '1'
> initialisieren und bei den meisten wird es kaum solche Probleme geben.
Weil sie entweder keine for-Schleifen für eine partielle 
Verktorzuweisung machen, oder das Verhalten nicht simulieren, oder das 
Verhalten schulterzuckend hinnehmen?
Es geht (wie schon mehrmals erwähnt) "nur" die Simulation schief  :-/

> Ich hab extra nachgesehen und festgestellt das ich
> auch auf Teile von einem std_Ulogic_vector mit einer for-Schleife
> zuweise und der Rest des Vectors in mehreren anderen Prozessen (manchmal
> mit weiteren for-Schleifen) bzw. normalen Zuweisungen gemacht wird.
1
architecture Behavioral of SimpleZuweisung is
2
signal sig : std_logic_vector(7 downto 0) := (others=>'U');
3
begin
4
   process (sig) begin 
5
     for i in 0 to 2 loop
6
       sig(i) <= '0' after 2 ns;
7
     end loop;
8
   end process;
9
10
   process (sig) begin
11
     for i in 3 to 3 loop
12
       sig(i) <= '1' after 1 ns;
13
     end loop;
14
   end process;
15
16
   mug <= sig;
17
end Behavioral;
Ergebnis (Screenshot):
0ns = "UUUUUUUU"
1ns = "UUUUUUUU"
2ns = "UUUUUUUU"

Mit std_ulogic Vektoren ergibt sich im Simulator der Fehler:
1
# ** Error: SimpleZuweisung.vhd(18): Nonresolved signal 'sig' has multiple sources.
2
#   Drivers:
3
#     SimpleZuweisung.vhd(20):Process line__20
4
#        Driven at:
5
#           SimpleZuweisung.vhd(22)
6
#     SimpleZuweisung.vhd(25):Process line__25
7
#        Driven at:
8
#           SimpleZuweisung.vhd(27)
Zeile 20 ist der erste, Zeile 25 der zweite Prozess.

Mit dieser Beschreibung:
1
architecture Behavioral of SimpleZuweisung is
2
signal sig : std_logic_vector(7 downto 0) := (others=>'U');
3
begin
4
   process (sig) begin
5
     sig(0) <= '0' after 2 ns;
6
     sig(1) <= '0' after 3 ns;
7
     sig(2) <= '0' after 4 ns;
8
   end process;
9
10
   process (sig) begin
11
     sig(3) <= '1' after 1 ns;
12
   end process;
13
14
   mug <= sig;
15
end Behavioral;
ist das Verhalten wie erwartet, und mit std_logic und std_ulogic gleich.
0ns = "UUUUUUUU"
1ns = "UUUU1UUU"
2ns = "UUUU1UU0"
3ns = "UUUU1U00"
4ns = "UUUU1000"

Die Synthese macht übrigens aus jeder Beschreibung das gleiche:
"00001000"

Fazit:
aufpassen mit partiellen for-Schleifen.

von Erik (Gast)


Lesenswert?

Hallo,


>> Ich denke nicht das es FPGAs/ASICs gibt die ihre internen Signale
>> mit 'Z' vorbelegen können.
> Nein, das war auch nur so eine Spielerei...

War mir klar. Ist ein interessantes Experiment aber ohne praktische 
Bedeutung. Trotzdem verstehe ich nicht warum in Deinem Bild vom 20.04. 
nur sig(3) auf 'X' geht und sig (2 downto 0) ordentlich arbeiten. Bei 
sig(2 downto 0) müsste eigentlich doch die Initialisierung genau so 
stören wie bei sig(3).


> Mit std_ulogic Vektoren ergibt sich im Simulator der Fehler:

Wenn Du noch ein klein wenig Zeit übrig hast, dann Probier es mal Bitte 
mit 'alias'. Ein Alias fürs Low-Nibble und das in einem Prozess mit Loop 
0 to 3 zuweisen und ein weiteres Alias fürs High-Nibble und in einem 
anderen Prozess mit Loop 4 to 7 zuweisen. Ich glaube das geht auch mit 
Ulogic.


Grüße
Erik

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


Angehängte Dateien:

Lesenswert?

> Ich glaube das geht auch mit Ulogic.
Klappt mit und ohne u korrekt und wie erwartet (Screenshot).
Durch den Alias wird der Namensraum auf den Teil eines Vektors 
eingeschränkt.
1
entity SimpleZuweisung is
2
    Port ( mug : out  std_ulogic_vector (7 downto 0));
3
end SimpleZuweisung;
4
5
architecture Behavioral of SimpleZuweisung is
6
signal sig : std_ulogic_vector(7 downto 0) := (others=>'U');
7
alias sigh : std_ulogic_vector(3 downto 0) is sig(7 downto 4);
8
alias sigl : std_ulogic_vector(3 downto 0) is sig(3 downto 0);
9
10
begin
11
   process (sigh) begin
12
     for i in 0 to 2 loop
13
       sigh(i) <= '0' after 2 ns;
14
     end loop;
15
   end process;
16
17
   process (sigl) begin
18
     for i in 1 to 3 loop
19
       sigl(i) <= '1' after 1 ns;
20
     end loop;
21
   end process;
22
23
   mug    <= sig;
24
end Behavioral;

von nixda (Gast)


Lesenswert?

servus,

ein langer guter thread. die "auflösung"+analyse findet sich in 
http://tams-www.informatik.uni-hamburg.de/vhdl/doc/faq/FAQ1.html section 
4.2.13 (fast das identische beispiel).

nur die schlussfolgerung macht mich stutzig...

>aufpassen mit partiellen for-Schleifen.
>ulogic braucht doch keiner ....

das ganze waere nicht aufgetreten wuerde man sich im "vertrag mit sich 
selbst"(OT erik) schonmal einschraenken.

mfg
/uwe

btw: >Erik (der bald noch von VHDL (alb)träumt)

sei froh, verilog oder systemverilog sind nicht besser und haben mehr 
als genug interpretationsspielraum im LRM.

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


Lesenswert?

nixda wrote:
> ein langer guter thread. die "auflösung"+analyse findet sich in
> http://tams-www.informatik.uni-hamburg.de/vhdl/doc/faq/FAQ1.html section
> 4.2.13 (fast das identische beispiel).

Insgesamt recht hübsche Seite,
aber diese Beschreibung aus dem Kapitel 4.2.13 hat was:
1
    process (Clk, Clr)
2
    begin
3
      case To_X01( Clr ) is
4
        when '1' =>
5
          Q <= '0';
6
          QBar <= '1';
7
8
        when '0' =>
9
          if rising_edge( Clk ) then  -------- na toll !!!!!
10
            Q <= D;
11
            QBar <= not D;
12
          end if;
13
14
        when 'X' =>
15
          Q <= 'X';
16
          QBar <= 'X';
17
      end case;
18
    end process;
Da könnte mancher Anfänger auf die Idee kommen, sowas liesse sich in 
Hardware abbilden  :-o

von nixda (Gast)


Lesenswert?

nicht das ich das als vorbild nehmen wollte, aber ist das nicht nur ein 
FF mit 1-aktiven clear + 'X' handling?

sonst ist der 'clr' reset, das 'X' handling wird nicht benutzt und statt 
dem case wird ein "if" benutzt ... und schon ist es die standard loesung 
eines synchronen+synthetisierbaren Megabauteils (FF) - also ganz kaputt 
finde ich es fuer simulationszwecke nicht unbedingt

mfg
/uwe

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


Lesenswert?

> also ganz kaputt finde ich es fuer simulationszwecke nicht unbedingt
Richtig, aber ich zitiere mich selber:
>> Da könnte mancher Anfänger auf die Idee kommen, sowas liesse sich in
>> Hardware abbilden

Viele meinen, alles was VHDL kann, kann auch ein FPGA. Und schreiben 
dann hin (weil es mehr oder weniger so in jedem Buch steht):
1
  ausgang <= eingang after 10 ms;

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Lothar Miller wrote:
> Viele meinen, alles was VHDL kann, kann auch ein FPGA. Und schreiben
> dann hin (weil es mehr oder weniger so in jedem Buch steht):
>
1
>   ausgang <= eingang after 10 ms;
2
>
WO wir schon bei fikitven Szenarien sind: Ich meine sowas KÖNNTE das 
Synthesetool wenn es die Taktfrequenz kennt aber auch in eine 
Statemaschine+Zähler übersetzen. Wäre mal ne neue Sache :)

von Erik (Gast)


Lesenswert?

Hallo,


> Klappt mit und ohne u korrekt und wie erwartet ...

Hab ich mir gedacht. Ich hab noch mal meinen Code genauer angesehen. 
Dort wo ich partielle Loops eingesetzt habe (doch nicht ganz so oft wie 
ich dachte) war auch ein/mehrere 'alias' zu finden, nur etwas versteckt. 
;-)
Es geht also, aber man muss dem Simulator etwas unter die Arme greifen 
weil er Loops in einer frühen Phase nicht ganz versteht. Ich schätze mal 
das wirklich für einen Vector nur eine Event-Queue verwendet wird, bei 
großen Designs (mit vielen breiten Registern) kann man so sicher einige 
Prozente Rechenzeit und Speicherverbrauch einsparen.



> ein langer guter thread.

Danke!
Man will ja was lernen. Ich denke meine Ursprungsfrage ist beantwortet.
Nur
>>>> entschuldigt bitte das ich da noch mal drauf rum reite aber ich
>>>> verstehe nicht warum das Problem mit dem 'X' auf sig(3) nicht auch
>>>> auf sig(2 downto 0) auftritt
>>>> (auf dem Screenshot von Lothar Miller vom 20.04.2009 14:18).
ist leider immer noch unklar.


> nur die schlussfolgerung macht mich stutzig...
> >aufpassen mit partiellen for-Schleifen.

Wieso, was ist an dieser Schlussfolgerung verkehrt?
Mit Partiellen Loops gibt es doch ganz eindeutig verschiedene 
Stolperfallen wo die Simulation anderes macht als man auf den ersten 
Blick vermutet. Es wurden in diesem Thread ja mehrere problematische 
Szenarien diskutiert wo IMHO die Simulatoren schon ein bisschen besser 
sein könnten. Oder verlangt der VHDL-Standard wirklich solchen Mist.

> >ulogic braucht doch keiner ....

Das empfinde ich allerdings auch als schlechte Schlussfolgerung.


> das ganze waere nicht aufgetreten wuerde man sich im
> "vertrag mit sich selbst"(OT erik) schonmal einschraenken.

Was meinst Du damit? Bitte erkläre das etwas genauer.


> btw: >Erik (der bald noch von VHDL (alb)träumt)

Nunja, ich kann es mir gerade so noch verkneifen. Ich träume dann doch 
lieber von angenehmer anfasbaren Dingen.

> sei froh, verilog oder systemverilog sind nicht besser
> und haben mehr als genug interpretationsspielraum im LRM.

Und ich hatte schon fast Angst aufs falsche Pferd gesetzt zu haben.  ;-)



Gutes Nächtle
Erik



PS.:

Bevor jetzt jemand auf "als man auf den ersten Blick vermutet" 
rumreitet, ich bin schon der Meinung das eine 
Beschreibungs-/Programmier-sprache einigermaßen verständlich sein 
sollte. Wenn man bei jedem kleinen Kram immer erst um fünf Ecken denken 
muss, so wie in der Quizfrage, dann ist das einem flüssigen und 
fehler"armen" arbeiten IMHO nicht gerade zuträglich. In der 
Softwareentwicklung würde das heutzutage der gemeine Programmieranfänger 
nicht mehr akzeptieren (muss er ja auch nicht) und sich eben einer 
anderen Sprache zuwenden (gibt ja schließlich mehr als genug Auswahl).
Ich find es zwar nicht toll das sich heutzutage jeder Dummie das Buch 
"C++/Java/PHP/VB/... für Dummies" (eine VHDL-Variante kommt bestimmt 
noch) kauft und meint nun ein guter Softwareentwickler zu sein (die 
Qualität heutiger Software ist nicht nur selten zufriedenstellend) aber 
zumindest den Tools und den Programmiersprachen selber hat dieser 
"Ansturm der Dummies" etwas gutes gebracht.
Ich als "Profi" (ich behaupte jetzt mal ganz frech einer zu sein) 
empfinde die hier diskutierten Probleme als störend. Die aktuellen 
Gewinner der Evolution der Software-Programmiersprachen haben solche 
Probleme jedenfalls nur noch sehr vereinzelt. Bei den 
Hardware-Beschreibungssprachen fehlt IMHO etwas Konkurrenz.
Ein bisschen Angst habe ich schon wenn in der c't VHDL-Einführungskurse 
sind aber vielleicht kann ich ja in ein paar Jahren auch davon 
profitieren, in Form besserer Tools vielleicht, wenn sich genügend 
"Dummies" ein FPGA-Board kaufen.

SCNR

von nixda (Gast)


Lesenswert?

servus erik,

>> >ulogic braucht doch keiner ....
>Das empfinde ich allerdings auch als schlechte Schlussfolgerung.

>> das ganze waere nicht aufgetreten wuerde man sich im
>> "vertrag mit sich selbst"(OT erik) schonmal einschraenken.

>Was meinst Du damit? Bitte erkläre das etwas genauer.

ich bin ganz deiner meinung, dass ulogic entscheidende vorteile bzgl. 
designsicherheit hat (keine unabsichtlichen mehrfach treiber). auch das 
in diesem thread analysierte verhalten tritt nur mir logic auf (ist 
zwar auch ein mehrfachtreiber problem, aber ist nicht auf den ersten 
blick ersichtlich, weil das lrm es so definiert).

>Es wurden in diesem Thread ja mehrere problematische
>Szenarien diskutiert wo IMHO die Simulatoren schon ein bisschen besser
>sein könnten. Oder verlangt der VHDL-Standard wirklich solchen Mist.

bei vhdl features der standards -87 und -93 wuerde ich davon ausgehen, 
dass mittlerweile alle grossen hersteller (snps,ment,cdns) das LRM 
korrekt implementiert haben. (und es ist mehr als problematisch sachen 
zu implementieren, die ausserhalb des lrm liegen)

>ist leider immer noch unklar.

- der longest static prefix definiert auf welcher granularitaet treiber 
erzeugt werden (pro process wird dies gemacht)
- im beispiel ist das ein 7-bit treiber aus dem process und ein 1bit 
treiber aus dem concurrent signal assignment. nur sig(3) hat einen 
doppelten treiber simulationstechnisch gesehen

/mfg

von Erik (Gast)


Lesenswert?

Hallo nixda,


> bei vhdl features der standards -87 und -93 wuerde ich davon ausgehen,
> dass mittlerweile alle grossen hersteller

Ist das nicht beschämend? Wir diskutieren hier über 20 (zwanzig) Jahre 
alte Standards! Wie alt ist der C++-Standard den der GCC aktuell 
unterstützt?
Der nächste C++-Standard steht kurz bevor und sogar der ewige 
Standard-Verweigerer aus Redmond will wohl diesmal bei der 
Standard-Konformität vorne mitspielen.
Und ich muss mir banale Dinge wie boolean_vector immer noch von Hand 
definieren.


> - im beispiel ist das ein 7-bit treiber aus dem process und ein 1bit
>  treiber aus dem concurrent signal assignment.
>  nur sig(3) hat einen doppelten treiber simulationstechnisch gesehen

Ist zwar aus meiner persönlichen Sicht unschön aber man kann sich ja 
drauf einstellen.
Obwohl ich immer noch nicht verstehe warum dann für sig(3) ein 'X' und 
kein 'U' kommt.


Schönen Sonntag noch!
Erik

von nixda (Gast)


Lesenswert?

servus,

das X auf sig(3) kommt dadurch, dass der treiber des processes mit dem 
default wert des signals initialisiert wurde (others=>'0'). damit treibt 
der process mit den treibern auf sig ein 0000000, spaeter dann 00000111. 
mit den treiber des zweiten assignments fuehrt dies mit '0'+'1' auf ein 
'X' bei sig(3).


>Ist das nicht beschämend? Wir diskutieren hier über 20 (zwanzig) Jahre
>alte Standards! Wie alt ist der C++-Standard den der GCC aktuell
>unterstützt?

natuerlich gibt es neuere standards (alle ieee standards werden alle N 
jahre ueberarbeitet vhdl-87,93,00,02,08 verilog-1995,2001, 
systemverilog-3.1,3.1a,1800-2005,..., den ganzen analogkram: verilog-a, 
vhdl-a, verilog-ams,... ). problematisch ist bei HDL's das der zu 
benutzende featureset durch den gesamtflow eingeschraenkt wird (also ich 
bin gezwungen mich auf den subset zu beschraenken den ALLE tools im flow 
koennen (simulation/synthese/equivalence checking/...). zudem sind die 
standards recht umfangreich dass zb. lt. aussage einer analyse von 2005 
(zur einfuehrung von systemverilog ieee1800-2005) keiner der relevanten 
verilog simulatoren den kompletten verilog 2001 standard implementiert - 
also z.T kommen die standards schneller als es zu implementieren ist, 
brauchen die standards 1-2 releases um zu "reifen" und zudem nutzen die 
wenigsten user den kompletten standard (ich sag mal guarded blocks z.B 
in vhdl habe ich noch nie gesehen :))

/mfg

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.