Alles wird wegoptimiert

Gast #2361467
Lesenswert?

1
library ieee;
2
use ieee.std_logic_1164.all;
3

4

5
entity e_test is
6
port(   
7
    Clk    : in  std_logic;
8
    EnaOut : out std_logic  
9
);
10
end e_test;
11

12

13

14
architecture test of e_test is
15

16

17
type t_fsm is ( ss_rst, ss_ini, ss_active);
18
signal fsm : t_fsm := ss_rst;
19
signal ena : std_logic := '0';
20

21
begin
22

23
EnaOut <= ena;  
24

25
FSM: process(Clk)
26
begin
27
    if rising_edge(Clk) then    
28
        case fsm is
29
            when ss_rst =>      fsm <= ss_ini;                              
30
            when ss_ini  =>     fsm <= ss_active;
31
            when ss_active =>   ena <= '1';         
32
        end case;
33
    end if;
34
end process;
35

36
end test;


Kann mir jemand sagen, wieso in Diamond1.3 die gezeigte 
VHDL-Beschreibung komplett wegoptimiert wird?

Grüsse,
Jonny
Gast #2361488
Lesenswert?

Es wird aber nicht mal ein Schieberegister implementiert, rein gar 
nichts.


Folgende Beschreibungen werden hingegen nicht wegoptimiert:


1
library ieee;
2
use ieee.std_logic_1164.all;
3
use ieee.numeric_std.all;
4

5

6

7
entity e_test is
8
port(   
9
  Reset  : in  std_logic;
10
    Clk    : in  std_logic;
11
    EnaOut : out std_logic  
12
);
13
end e_test;
14

15

16

17
architecture test of e_test is
18

19

20
type t_fsm is ( ss_rst, ss_ini, ss_active);
21
signal fsm : t_fsm := ss_rst;
22
signal ena : std_logic := '0';
23

24
begin
25

26
EnaOut <= ena;  
27

28
FSM: process(Clk)
29
begin
30
  if rising_edge(Clk) then    
31
    if Reset = '1' then
32
      fsm <= ss_rst;
33
      ena <= '0';
34
    else
35
      case fsm is
36
        when ss_rst =>      fsm <= ss_ini;                              
37
        when ss_ini  =>     fsm <= ss_active;
38
        when ss_active =>   ena <= '1';         
39
      end case;
40
    end if;
41
    end if;
42
end process;
43

44
end test;


1
library ieee;
2
use ieee.std_logic_1164.all;
3
use ieee.numeric_std.all;
4

5

6

7
entity e_test is
8
port(   
9
  Reset  : in  std_logic;
10
    Clk    : in  std_logic;
11
    EnaOut : out std_logic  
12
);
13
end e_test;
14

15

16

17
architecture test of e_test is
18

19

20
type t_fsm is ( ss_rst, ss_ini, ss_active);
21
signal fsm : t_fsm := ss_rst;
22
signal ena : std_logic := '0';
23

24
begin
25

26
EnaOut <= ena;  
27

28
FSM: process(Reset,Clk)
29
begin
30
  if Reset = '1' then
31
    fsm <= ss_rst;
32
    ena <= '0';
33
  
34
    elsif rising_edge(Clk) then    
35
        case fsm is
36
            when ss_rst =>      fsm <= ss_ini;                              
37
            when ss_ini  =>     fsm <= ss_active;
38
            when ss_active =>   ena <= '1';         
39
        end case;
40
    end if;
41
end process;
42

43
end test;
Gast #2361530
Lesenswert?

Altera Quartus II 11.0 SP1 nimmt obige Beschreibung und implementiert 
drei Register.


Bedeutet dies, dass man bei Lattice keine Signal-Initialisierungen 
verwenden darf und einen Reset benötigt?


Grüsse,

Jonny
Gast #2361550
Lesenswert?

Würde meinen ein default-assignment hilft:

    elsif rising_edge(Clk) then
        ena <= '0';  -- Default assignment
        case fsm is
            when ss_rst =>      fsm <=ss_ini;
            when ss_ini  =>     fsm <= ss_active;
            when ss_active =>   ena <= '1';
        end case;
    end if;
Gast #2361604
Lesenswert?

Aus der Synplify Pro Hilfe von Diamond:

----------------------
Ignored VHDL Language Constructs

The synthesis tool ignores the following constructs in your design. If 
found, the tool parses and ignores the construct (provided that no logic 
is required to be synthesized) and continues with the synthesis run.

disconnect
assert and report
initial values on inout ports
------------------------------

Ich denke Punkt 3 trifft hier zu.
Gast #2361652
Lesenswert?

Hi Pek,

ja eine Default-Zuweisung hilft.

Aber finde ich ja höchst interessant, dass Xilinx und Altera die 
Beschreibung schlucken, aber Lattice nicht. Man kann halt überhaupt gar 
nichts verallgemeinern, das ist mal sicher! Gerade die Aussage: "Man 
nehme überhaupt keinen Reset, und alles ist in Ordnung".


Grüsse,
Jonny
Moderator (Firma: Titel) Persönliche Seite #2361791
Lesenswert?

Jonny schrieb:
> Aber finde ich ja höchst interessant, dass Xilinx und Altera die
> Beschreibung schlucken, aber Lattice nicht.
Bis vor knapp 2 Jahren hat das noch keiner geschluckt. Nicht mal bei 
internen Signalen.

Jonny schrieb:
> Gerade die Aussage:
> "Man nehme überhaupt keinen Reset, und alles ist in Ordnung".
Ich meinte, darauf verwiesen zu haben, dass es um das WP272 der Firma 
Xilinx ging. Bei Lattice war bis zum Synthesizerwechsel vor 2 Jahren 
überhaupt keine Signalinitialisierung in der freien Toolchain möglich.

> Man kann halt überhaupt gar nichts verallgemeinern, das ist mal sicher!
Man kann einiges verallgemeinern, aber man sollte sich immer wieder mal 
anschauen, ob die Verallgemeinerung im Allgemeinen noch funktioniert... 
;-)
Gast #2361908
Lesenswert?

Lothar Miller schrieb:
>> Gerade die Aussage:
>> "Man nehme überhaupt keinen Reset, und alles ist in Ordnung".
> Ich meinte, darauf verwiesen zu haben, dass es um das WP272 der Firma
> Xilinx ging.

Vieles was im WP272 über Resetprobleme steht ist allgemein gültig, z.B. 
dass ein Resettaster böse ist.

Die Konsequenzen sind halt verschieden und hängen von der Architektur 
ab. Die Flipflops im Lattice haben im Gegensatz zu Xilinx immer noch 
einen Set/Reset Eingang.

Die Beschreibung eines Registers mit einem asynchronen Reset braucht bei 
Lattice keine extra Reseourcen, während das bei Xilinx wohl die teuerste 
Variante ist.

Man kann bei Lattice das Reset auf dem Toplevel an eine PUR Instanz 
binden und braucht dann kein externes Resetsignal mit seinen extra 
Problemen.

Schwierig ist halt allgemein portabler VHDL/Vferilog Code zu schreiben.
Gast #2361931
Lesenswert?

martin schrieb:
> Die Verwendung von initial Werten ist keine gute Idee bei der Synthese.
> Wie soll denn die Hardware so etwas nachbilden.

Hä?!? Ganz einfach, indem die initialen Werte beim Laden der 
Konfiguration in die Register geladen werden? Das sowas bei einem ASIC 
Design nicht geht ist klar, aber bei FPGAs gehts nunmal. Punkt.
Gast #2361985
Lesenswert?

Ich denke es kommt auf auf die Zielhardware an
ob init-Werte Sinn machen oder nicht.

Also ich beim ersten Code mal 1 und 0 bei "ena" vertauscht,
und den Code dann in den ISE9.2 geworfen:
Beim ersten Lauf ist das Ziel ein Spartan3:
  Und siehe da
  Es werden 3 FF erzeugt, und das erste hat den init
  wert '1' bekommen => also started dieses Flipflop nach dem
  FPGA download mit einer 1 (ganz ohne extra Reset Leitungen).

Beim zweiten Lauf ist der Zielbaustein ein CPLD:
  Und: tja auch ISE optimiert hier alles weg,
    der ena ist nur noch Konstant auf 1.

Nun ist die Frage: Welches Ziel hat  Jonny bei
der Synthese mit Diamond1.3 von Lattice gewählt:
  FPGA oder CPLD ?

Ich denke das bei RAM-basierte FPGAs die Init-Werte bei
  Registern durchaus Sinn machen, denn die download logic
  auf den FPGAs sorgt dafür das Initwerte bei den Flipflops
  (und RAMs) ankommen.

Hingegen brauchen CPLDs, Proasics und richtige ASICs durchaus
immer Syncrone oder Asyncrone Resets, da hier jedes
Flipflop in einem Unbekannten Zustand started.

Zusatz:
Behauptung: jeder Chip enthält mindestens einen asyncronen Reset!
Moderator (Firma: Titel) Persönliche Seite #2362227
Lesenswert?

martin schrieb:
> Und weils beim asic nicht geht sollte man sich so einen stil garnicht
> erst angewoehnen
Weil 1% der VHDL-Anwender ASICs machen, sollen 99% die Vorteile der 
FPGAs nicht nutzen?
Weil 1% der VHDL-Anwender ASICs machen, sollen 99% asynchrone Resets 
verwenden?
Sollte man dann auch keine Taktmanager, IO-Zellen usw. verwenden?
Für mich gilt auf jeden Fall: wenn mir mein Chip eine tolle Funktion 
bietet, dann verwende ich die auch.

bko schrieb:
> Behauptung: jeder Chip enthält mindestens einen asyncronen Reset!
Logisch, das steht ja sogar in der Xilinx-Doku und ist im altbekannten 
Beitrag "Re: Xilinx und die Resets" erwähnt.
Gast #2362230
Lesenswert?

Die Tools machens unterschiedlich, weil die "ena" für die ersten beiden 
States schlicht nicht definiert ist. Der springende Punkt ist, dass Du 
in Software denkst. VHDL ist aber keine Programmiersprache, sondern eine 
Hardwarebeschreibungssprache (mindestens soweit das Elaborat 
synthetisierbar sein soll). Deshalb ist es ein guter Ansatz, in 
Registern und Übergangslogik zu denken (strikte Zweiprozesslösung ist 
für mich die direkte Quintessenz daraus, in den sequentiellen Prozess 
gehört überhaupt keine Logik, in den kombinatorischen gehört ein 
Default-Assignment für JEDES Ausgangssignal).

In Hardware gedacht bedeutet folgende Sequenz:

    if rising_edge(Clk) then
         case fsm is
            when ss_rst =>      fsm <=ss_ini;
            when ss_ini  =>     fsm <= ss_active;
            when ss_active =>   ena <= '1';
        end case;
    end if;

nichts anderes als:

    ss_rst    : ena = don't care
    ss_ini    : ena = don't care
    ss_active : ena = '1'

und der Synthesizer macht damit, was er will (ein guter wird die Logik 
minimieren und eine fixe '1' zuweisen). Dass der Initialwert 
ursprünglich '0' war spielt aus HW-Sicht keine Rolle. Es wäre 
(akademischer Fall) sogar noch korrekt wenn das Tool bei ss_rst eine '1' 
und bei ss_ini eine '0' zuweist. Darum: Wenn man ein Signal in jedem 
Fall definiert, kriegt man auch, was man sich wünscht.

Gruss
Peter
Gast #2362232
Lesenswert?

das ist doch unfug, ena soll den Zustand behalten bis der State erreicht 
ist.

Man muss keinesfalls für jeden State einer FSM auch jedem Signal eine 
Zuweisung machen.

Es ist vielmehr so:

In Hardware gedacht bedeutet folgende Sequenz:

    if rising_edge(Clk) then
         case fsm is
            when ss_rst =>      fsm <=ss_ini;
            when ss_ini  =>     fsm <= ss_active;
            when ss_active =>   ena <= '1';
        end case;
    end if;

nichts anderes als:

    ss_rst    : ena <= ena
    ss_ini    : ena <= ena
    ss_active : ena <= '1'


Warum bitte soll man das explizit hinschreiben?
Moderator (Firma: Titel) Persönliche Seite #2362235
Lesenswert?

pek schrieb:
> Die Tools machens unterschiedlich, weil die "ena" für die ersten beiden
> States schlicht nicht definiert ist.
Nein, es ist sehr wohl definiert. Aber weil ena in den ersten beiden 
States nicht verändert/verwendet wird, MUSS es speichernd sein und den 
zuletzt zugewiesenen Wert halten. Und das ist hier nun mal der 
Initialisierungswert '0'. Der Simulator sieht das genauso, und deshalb 
ist das hier falsch:
> und der Synthesizer macht damit, was er will (ein guter wird die Logik
> minimieren und eine fixe '1' zuweisen).
Darf er nicht!
Ausgenommen: er kann es nicht und dieses (aus VHDL-Sicht fehlerhafte) 
Verhalten ist dokumentiert.
> Dass der Initialwert ursprünglich '0' war spielt aus HW-Sicht keine Rolle.
Oh doch, durchaus....

Im Anhang die Screenshots der Simulation und der RTL-Pläne von Xilinx 
ISE13 auf Spartan3...
Angehängte Dateien:
Gast #2362241
Lesenswert?

abc schrieb:
>     ss_rst    : ena <= ena
>     ss_ini    : ena <= ena
>     ss_active : ena <= '1'

Du hast Recht, das ist mir die nicht sehr lesbare "alles in einem 
Prozess"-Variante etwas durch die Lappen. Nichts desto trotz, erachte 
ich folgende Schreibweise (obwohl sie etwas mehr Platz benötigt) als 
viel lesbarer und robuster:

  -- Combinational: Reset FSM
  -----------------------------------------------------------------------
  fsm : process (fsm_cur)
  begin
    -- Default assignments
    ---------------------------------------------------------------------
    ena      <= '0';
    fsm_next <= fsm_cur;
    -- FSM
    ---------------------------------------------------------------------
    case fsm_cur is
      when SS_RST =>
        fsm_next <= SS_INI;
      when SS_INI =>
        fsm_next <= SS_ACTIVE;
      when SS_ACTIVE =>
        ena <= '1';
      when others =>
        fsm_next <= SS_RST;
    end case;
  end fsm;


  -- Sequential: Common register block
  ----------------------------------------------------------------------
  seq : process (HardResxRN, SysxC)
  begin
    if HardResxRN = RESET_ACTIVE then
      fsm_cur <= SS_RST;
    elsif (SysxC'event and SysxC = '1'
           --synopsys translate_off
           and SysxC'last_value = '0'
           --synopsys translate_on
           ) then
      fsm_cur <= fsm_next after PROP_DELAY;
    end if;
  end process seq;
Moderator (Firma: Titel) Persönliche Seite #2362252
Lesenswert?

pek schrieb:
> erachte ich folgende Schreibweise als viel lesbarer und robuster:
Die beliebte Zwei-Prozess-Schreibweise, die Anfänger immer in 
kombinatorische Schleifen führt...  ;-)

Seis durm: der eine mag Blonde, der andere Schwarze, der eine Große, der 
andere kleine... Aber Hauptsache: sie mögen sich und kommen miteinander 
aus.

> fsm_cur <= fsm_next after PROP_DELAY;
Zum Thema "Zeiten in der funktionalen Simulation" das dort im 
Beitrag "Re: Frage zu Pseudozufallsgenerator!?"

> (SysxC'event and SysxC = '1'
>           --synopsys translate_off
>           and SysxC'last_value = '0'
>           --synopsys translate_on
>           )
Wieso 5 Zeilen, wenn rising_edge() (was ja EXAKT das selbe macht) 
gereicht hätte?
Gast #2362265
Lesenswert?

Lothar Miller schrieb:
>> fsm_cur <= fsm_next after PROP_DELAY;
> Zum Thema "Zeiten in der funktionalen Simulation" das dort im
> Beitrag "Re: Frage zu Pseudozufallsgenerator!?"

Zusammengefasst: Der Delay wird nicht synthetisiert. Ist vorbeugend für 
die Simulation. Es gibt Simulatoren/Modelle, die können mit 0-Holdtime 
schlecht umgehen. Wichtig PROP_DELAY muss kürzer als ein clock-cycle 
sein.

>> (SysxC'event and SysxC = '1'
>>           --synopsys translate_off
>>           and SysxC'last_value = '0'
>>           --synopsys translate_on
>>           )
>
> Wieso 5 Zeilen, wenn rising_edge() (was ja EXAKT das selbe macht)
> gereicht hätte?

Naja, Einwand stimmt zu 100% für FPGA-Only. Benutze immer denselben 
sequentiellen Prozess, der halt auch für den Einsatz in ASIC's und 
Simulation mit "Würfel"-FF und "Don't care at start"-FF benutzt wurde. 
Bei einer späteren ASIC-Integration wäre dann alles schon da.
Gast #2362321
Lesenswert?

Lothar Miller schrieb:
>> Zusammengefasst: Der Delay wird nicht synthetisiert....
> ...und er kann zu Pseudotakten führen.
...vermutlich nur wenn noch Übergangslogik im Prozess ist, hatte noch 
nie Probleme damit (wir haben damit 3 Multimedia-Prozessoren simuliert 
und synthetisiert).

> pek schrieb:
>
>> Es gibt Simulatoren/Modelle, die können mit 0-Holdtime schlecht umgehen.
> Welchen Simulator betrifft das?
> Drei weiß ich, die es nicht betrifft: Aldec, Modelsim und ISIM.
ncsim, vcs, und ja, auch mit modelsim gabs schon probleme, vorwiegend 
mit IP-Simulationsmodellen (das sind dann Simulations-Fälle die 
vermutlich in eine ähnliche Kategorie gehören, wie diejenigien wo noch 
ein "wait for 0 ns" eingefügt werden muss, damit der Tick eins weiter 
geht...)
Moderator (Firma: Titel) Persönliche Seite #2362344
Lesenswert?

pek schrieb:
>>> Zusammengefasst: Der Delay wird nicht synthetisiert....
>> ...und er kann zu Pseudotakten führen.
> ...vermutlich nur wenn noch Übergangslogik im Prozess ist
Richtig:
1
  signal count : integer;
2

3
  -- Combinational: Reset FSM
4
  -----------------------------------------------------------------------
5
  fsm : process (fsm_cur)
6
  begin
7
    -- Default assignments
8
    ---------------------------------------------------------------------
9
    ena      <= '0';
10
    fsm_next <= fsm_cur;
11
    -- FSM
12
    ---------------------------------------------------------------------
13
    case fsm_cur is
14
      when SS_RST =>
15
        fsm_next <= SS_INI;
16
      when SS_INI =>
17
        fsm_next <= SS_ACTIVE;
18
      when SS_ACTIVE =>
19
        ena <= '1';
20

21
        count <= count + 1 after 10ns;  -- eigentlich eine kombinatorische Schleife
22
                                        -- wird aber bei der Simulation durch das after
23
                                        -- und bei der Synthese durch die FSM versteckt
24
      when others =>
25
        fsm_next <= SS_RST;
26
    end case;
27
  end fsm;
28

29

30
  -- Sequential: Common register block
31
  ----------------------------------------------------------------------
32
  seq : process (HardResxRN, SysxC)
33
  begin
34
    if HardResxRN = RESET_ACTIVE then
35
      fsm_cur <= SS_RST;
36
    elsif (SysxC'event and SysxC = '1'
37
           --synopsys translate_off
38
           and SysxC'last_value = '0'
39
           --synopsys translate_on
40
           ) then
41
      fsm_cur <= fsm_next after PROP_DELAY;
42
    end if;
43
  end process seq;


BTW:
Das hier ist eigentlich falsch:
1
    :
2
    elsif rising_edge(SysxC) then
3
      fsm_cur <= fsm_next after PROP_DELAY;
4
    end if;
Ein Propagation-Delay tritt im kombinatorischen Prozess auf.
Die Zeit vom Takt bis zum stabilen Durchreichen an den FF-Ausgang heißt 
tco (Clock-to-Output).
Gast #2362607
Lesenswert?

>Man kann bei Lattice das Reset auf dem Toplevel an eine PUR Instanz
>binden und braucht dann kein externes Resetsignal mit seinen extra
>Problemen.


OK, und wie sehen dann die Reset-Werte der einzelnen Register aus? Wie 
wir ja festgestellt haben, werden "signal initial values" ignoriert. 
Also was für einen Sinn macht es dann eine PUR-Instanz zu verwenden, 
zumal diese ja nur einen Eingang hat?


Grüsse, Jonny
Gast #2362661
Lesenswert?

>Aus der Synplify Pro Hilfe von Diamond:
>
>----------------------
>Ignored VHDL Language Constructs
>
>initial values on inout ports
>-----------------------------



Aus der Synplify Pro Hilfe von Diamond, ab Version 1.2

Nun ist es endlich mal offiziell!


VG, SuperWilly
Gast #2362882
Lesenswert?

Jonny schrieb:
> Was hilft dir eine PUR-Instanz, wenn die Module keinen Reset-Eingang
> haben?

Ich habe mich getäuscht, PUR/GSR Instanzen dienen dazu um in einer 
Testbench das Startupverhalten besser abbilden zu können.


Nach einigen probieren bin ich zum folgenden Schluss gekommen:

Synplify erkennt in deiner orginalen Version ein synchrones R/S Flipflop 
für ena, und ignoriert dann den initial value.
1
W  BN288  Register ena with set has an initial value of 0. Ignoring initial value.    test5.vhd (27)  Test5.srr (38)  17:26:57 Wed Sep 28  premapping

wenn man in der FSM irgendwo noch eine '0' an ena zuweist, klappt es mit 
dem D-Fliplop und auch mit initial value.
Gast #2363395
Lesenswert?

>Aus der Synplify Pro Hilfe von Diamond:
>
>----------------------
>Ignored VHDL Language Constructs
>
>initial values on inout ports
>-----------------------------



Aber bedeutet dies nicht, dass Signale (Register) initialisiert werden 
dürfen? Es werden ja nur Ports genannt.


Grüsse, Jonny
Gast #2363555
Lesenswert?

OK, also wenn wir nochmal zum Ausgangspunkt der Diskussion zurück gehen 
-
wieso wird der als erstes gezeigte Code wegoptimiert?

Weil Lattice (bzw. SynplifyPro für Lattice) keine 
Signalinitialisierungen unterstützt oder warum?
Gast #2363665
Lesenswert?

Jonny schrieb:
> Weil Lattice (bzw. SynplifyPro für Lattice) keine
> Signalinitialisierungen unterstützt oder warum?

Hast du meine letze Post weiter oben gelesen und versucht zu verstehen?

Es wird nicht das korrekte FF inferreriert, da in der FSM nur einmal 
eine '1' an ena zugewiesen wird.

Da geht:
1
library ieee;
2
use ieee.std_logic_1164.all;
3

4

5
entity e_test is
6
port(   
7
    Clk    : in  std_logic;
8
    EnaOut : out std_logic  
9
);
10
end e_test;
11

12

13

14
architecture test of e_test is
15

16

17
type t_fsm is ( ss_rst, ss_ini, ss_active);
18
signal fsm : t_fsm := ss_rst;
19
signal ena : std_logic := '0';
20

21
begin
22

23
EnaOut <= ena;  
24

25
FSM: process(Clk)
26
begin
27
    if rising_edge(Clk) then    
28
        case fsm is
29
            when ss_rst =>      fsm <= ss_ini;                              
30
            when ss_ini  =>     fsm <= ss_active; ena <= '0';
31
            when ss_active =>   ena <= '1';         
32
        end case;
33
    end if;
34
end process;
35

36
end test;


Und wenn ich den initial Wert ändere
1
signal ena : std_logic := '1';

sehe ich das auch im Ergebnis (Physical View von Diamond).
Siehe in den beiden angängten Bildern, der Reset/Set am FF unterscheidet 
sich.
Angehängte Dateien:

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren