Forum: FPGA, VHDL & Co. Verlust eines Bits während Optimierung


von guest (Gast)


Lesenswert?

Hallo,

ich verstehe bei der unten angegebenen Beschreibung nicht, weshalb ISE 
der Meinung ist das LOKAL_SER_OUT_MSG<15> niemals genutzt wird und es 
deshalb weg optimiert wird? Bei den Anweisungen "LOKAL_SER_OUT_MSG := 
x"1234"; SERIAL_OUT <= LOKAL_SER_OUT_MSG(15);" im zweiten if-Zweig wird 
das 15. Bit doch benötigt?


1
entity S3P_TX is  
2
  port(  CLK_SYS        : in std_logic;
3
         RST          : in std_logic;
4
         CLK_TX        : out std_logic;
5
         SERIAL_OUT      : out std_logic);
6
end S3P_TX;
7
8
architecture BEHAVIORAL of S3P_TX is
9
10
  component DATA_CLK_GENERATOR
11
    port(  CLK_SYS : in  std_logic;
12
           RST : in  std_logic;
13
           DATA_CLK : out  std_logic;
14
           TX_CLK_EN : out  std_logic);
15
    end component;
16
17
  signal SHIFT_CNT : integer range 0 to 15;
18
  signal TX_CLK_EN_CON : std_logic;
19
    
20
begin
21
  
22
  CLK_GEN : DATA_CLK_GENERATOR port map(  CLK_SYS => CLK_SYS,
23
                      RST => RST,
24
                      DATA_CLK => CLK_TX,
25
                      TX_CLK_EN => TX_CLK_EN_CON
26
                    );
27
    
28
  TEST : process(CLK_SYS)
29
    variable LOKAL_SER_OUT_MSG : std_logic_vector(15 downto 0);
30
  begin
31
    if(CLK_SYS'event and CLK_SYS = '1')then
32
        if(RST = '1') then
33
          LOKAL_SER_OUT_MSG := x"FFFF";
34
          SHIFT_CNT <= 0;
35
          SERIAL_OUT <= '1';
36
        elsif(TX_CLK_EN_CON = '1') then
37
          if(SHIFT_CNT < 15) then
38
            LOKAL_SER_OUT_MSG := LOKAL_SER_OUT_MSG(14 downto 0) & '0';
39
            SERIAL_OUT <= LOKAL_SER_OUT_MSG(15);        
40
            SHIFT_CNT <= SHIFT_CNT + 1;
41
          elsif(SHIFT_CNT >= 15) then
42
            LOKAL_SER_OUT_MSG := x"0123";
43
            SERIAL_OUT <= LOKAL_SER_OUT_MSG(15);
44
            SHIFT_CNT <= 0;
45
          end if;
46
        end if;
47
    end if;  
48
  end process;
49
    
50
end BEHAVIORAL;

von dito (Gast)


Lesenswert?

LOKAL_SER_OUT_MSG(15) steht schon zum Synthesezeitpunkt fest. Ist also 
eine Konstante und kann direkt eingesetzt werden.

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


Lesenswert?

guest schrieb:
> SERIAL_OUT <= LOKAL_SER_OUT_MSG(15);
Mein Verdacht: LOKAL_SER_OUT_MSG(15) ist das selbe wie SERIAL_OUT und 
wird deshalb wegrationalisiert.
Trotz der der Optimierung und der unnötigen Verwendung einer Variablen 
sollte die Beschreibung aber das machen, was man von ihr verlangt...

von guest (Gast)


Lesenswert?

Danke soweit. Wäre nur der erste If-Zweig vorhanden könnt ich das weg 
optimieren nachvollziehen. Im "elsif(SHIFT_CNT >= 15) then" Zweig wird 
aber doch LOKAL_SER_OUT_MSG := x"0123"; ausgeführt, wodurch auch 
SERIAL_OUT auf 0 gesetzt wird?
Selbst wenn ich die Zuweisung von einem externen Signal abhängig mache, 
wobei der Wert von SERIAL_OUT nur von LOKAL_SER_OUT_MSG(15) abhängt, 
geht Bit 15 verloren.


1
TEST : process(CLK_SYS)
2
    variable LOKAL_SER_OUT_MSG : std_logic_vector(15 downto 0);
3
  begin
4
    if(CLK_SYS'event and CLK_SYS = '1')then
5
        if(RST = '1') then
6
          LOKAL_SER_OUT_MSG := x"FFFF";
7
          SHIFT_CNT <= 0;
8
          SERIAL_OUT <= '1';
9
        elsif(TX_CLK_EN_CON = '1') then
10
          if(SHIFT_CNT < 15) then
11
            LOKAL_SER_OUT_MSG := LOKAL_SER_OUT_MSG(14 downto 0) & '0';
12
            SERIAL_OUT <= LOKAL_SER_OUT_MSG(15);        
13
            SHIFT_CNT <= SHIFT_CNT + 1;
14
          elsif(SHIFT_CNT >= 15) then
15
            if(EXTERN = '1') then
16
               LOKAL_SER_OUT_MSG := b"0111_1111_1111_1111";
17
            else
18
               LOKAL_SER_OUT_MSG := b"1111_1111_1111_1111";
19
            end if;
20
            SERIAL_OUT <= LOKAL_SER_OUT_MSG(15);   
21
            SHIFT_CNT <= 0;
22
          end if;
23
        end if;
24
    end if;  
25
  end process;

von Der Besucher (Gast)


Lesenswert?

Hallo,

LOKAL_SER_OUT_MSG(15) wird wegoptimiert, da nie auf den gespeicherten 
Wert zugegriffen wird.

Im ersten if-Zweig wird auf das in LOKAL_SER_OUT_MSG(14) gespeicherte 
Element zugegriffen.
Im Zweiten If-Zweig wird LOKAL_SER_OUT_MSG(15) gar nicht benötigt, da es 
direkt von EXTERN abhängt (im 2. Codestück).

Deine Verwirrung stammt sicherlich aus der unterschiedlichen 
abarbeitungsweise von Signalen und Variablen. Wenn du LOKAL_SER_OUT_MSG 
als Signal definierst (was ich dringend empfehle!), sollte dir schnell 
klar werden, warum das Bit nicht benötigt wird. Denn da reicht ein 15 
Bit breiter Vektor zum Speichern des Wertes völlig aus.

Kleiner Tipp noch:  elsif(SHIFT_CNT >= 15) then
kann einfach mit einem "else" ersetz werden.

Der Besucher

von guest (Gast)


Lesenswert?

Besten Dank nochmal. Erlich gesagt weiß ich auch nicht warum ich erst 
shiften wollte um diesen Wert in Bit 15 dann nochmals (SERIAL_OUT) zu 
speichern. Desshalb hatte ich auch zur Variable gegriffen..

Wesshalb wird hier oftmals von Variablen abgeraten? Nur weil die 
Abarbeitung anders ist und somit das Nachvollziehen des Codes 
unangenehmer wird, oder kann das auch zu Problemen führen an jeder Ecke 
Variablen zu nutzen?

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


Lesenswert?

> Wesshalb wird hier oftmals von Variablen abgeraten?
Weil (insbesondere mit [implizit] speichernden) Variablen selbst Profis 
ins Schleudern kommen...
Siehe auch die Verweise auf die AppNotes im 
Beitrag "Variable vs Signal"

Variablen sind sehr gut geeignet, wenn ein Rechenschritt der Übersicht 
halber auf einzelne Berechnungen verteilt werden soll:
http://www.lothar-miller.de/s9y/archives/73-Wurzel-in-VHDL.html
Aber dann sollten die Dinger nicht speichernd sein.

Oder wenn in Testbenches mit Funktionen und Schleifen herumgemacht wird:
http://www.lothar-miller.de/s9y/archives/75-PS2-Tastatur.html

von Der Besucher (Gast)


Lesenswert?

@guest: es ist schon möglich, an jeder Ecke Variablen zu nutzen. Man muß 
sich nur mit der Beschränkung auf den aktuellen Process anfreunden (von 
globalen Variablen spreche ich hier nicht, denn um die mache ich einen 
großen Bogen). Auch, dass sie anders gehandhabt werden als Signale. 
Falsch ist die Nutzung sicherlich nicht, solange das gewünschte Ergebnis 
erzielt wird.
Nur, dein Codebeispiel zeigt doch sehr eindringlich, dass selbst bei 
einfachster Logik die genauen Zusammenhänge schwerer zu durchschauen 
sind, wenn Signale und Variablen für Speicherelemente parallel verwendet 
werden.

Aber jeder muß seinen eigenen Codestil finden. Richtig und Falsch gibt 
es wohl nur im Type Boolean ;)

Der Besucher

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.