Forum: FPGA, VHDL & Co. Xilinx Spartan 3E: Code geht bei der Translation kaputt


von Viktor B. (coldlogic)


Lesenswert?

Hi Leute,
Ich bastele gerade an einem größeren Projekt rum. Es soll auf dem Xilinx 
Spartan 3E FPGA Board ein SPI-zu-servotaugliches-PWM - Konverter 
implementiert werden. Nach einiger Arbeit funktioniert der Code in der 
behavioral simulation, aber auf dem FPGA tut sich sehr wenig (und was 
sich tut, tut es falsch). Schon die post-translate simulation funzt 
nicht mehr. Eins der Fehler hab ich schon isolieren können - ein 
3-Bit-Zähler initialisiert sich immer mit einer 7, wobei im Quellcode 
explizit der Init-Wert 0 steht. Also entweder hab ich einen Fehler 
gemacht oder die Maschinen fangen schon an, sich gegen die Menschen zu 
stellen. Könnte jemand mal meinen Code anschauen? Hier ist es:
1
----------------------------------------------------------------------------------
2
-- Company: 
3
-- Engineer: 
4
-- 
5
-- Create Date:    16:21:58 01/07/2017 
6
-- Design Name: 
7
-- Module Name:    c_cntr - Behavioral 
8
-- Project Name: 
9
-- Target Devices: 
10
-- Tool versions: 
11
-- Description: 
12
--
13
-- Dependencies: 
14
--
15
-- Revision: 
16
-- Revision 0.01 - File Created
17
-- Additional Comments: 
18
--
19
----------------------------------------------------------------------------------
20
library IEEE;
21
use IEEE.STD_LOGIC_1164.ALL;
22
23
-- Uncomment the following library declaration if using
24
-- arithmetic functions with Signed or Unsigned values
25
--use IEEE.NUMERIC_STD.ALL;
26
27
-- Uncomment the following library declaration if instantiating
28
-- any Xilinx primitives in this code.
29
--library UNISIM;
30
--use UNISIM.VComponents.all;
31
32
entity c_cntr is
33
generic (width: positive:= 8);
34
    Port ( clk : in  STD_LOGIC;
35
    clk_ersatz: in  STD_LOGIC;
36
           rst : in  STD_LOGIC;
37
           ovf : out  STD_LOGIC);
38
end c_cntr;
39
40
architecture Behavioral of c_cntr is
41
  signal value: integer range width-1 downto 0;
42
  signal sync_clk: std_logic;
43
begin
44
--ovf <= '1' when (value = width) else '0';
45
  counting: process (clk, rst)
46
    begin
47
      if (rst = '1') then
48
        value <= 0;
49
        ovf <= '0';
50
        sync_clk <= '0';
51
      else
52
        if (rising_edge(clk)) then
53
          if clk_ersatz = '1' and sync_clk = '0' then
54
            if (value = width-1) then
55
              value <= 0;
56
              ovf <= '1';
57
            else
58
              value <= value + 1;
59
              ovf <= '0';
60
            end if;
61
            sync_clk <= '1';
62
          elsif clk_ersatz = '0' and sync_clk = '1' then
63
            sync_clk <= '0';
64
            
65
          end if;--sync
66
        end if;--clk
67
      end if;--rst
68
  end process;
69
70
end Behavioral;

Der Zähler soll von 0 bis 7 zählen und bei jedem Overflow einen Puls 
geben. clk_ersatz ist der Zählinput.

MfG, Victor

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


Lesenswert?

Viktor B. schrieb:
> Könnte jemand mal meinen Code anschauen? Hier ist es:
Bitte die vhdl Tags um den Sourcecode Rum machen....

> clk_ersatz ist der Zählinput.
Wo kommt der her? Ist der synchron zum FPGA Takt?

> Könnte jemand mal meinen Code anschauen?
Dein Problem liegt nicht im geposteten Code...

von Viktor B. (coldlogic)


Lesenswert?

Die VHDL-Tags gibt es auch? Cool, merke ich mir. Also, der clk_ersatz 
ist an den SCL-Port des SPI angeschlossen, deswegen asynchron (ansonsten 
würde er immer an der Flanke erfasst werden, vllt keine so gute Idee). 
Wenn der Code hier fehlerfrei ist, was könnte sonst den Reset-Wert des 
Zählers beeinflussen?

Es kann auch sein, das mein ISE Webpack spinnt, ich versuche mal das 
übliche force reparse + cleanup

von C. A. Rotwang (Gast)


Lesenswert?

Viktor B. schrieb:

> nicht mehr. Eins der Fehler hab ich schon isolieren können - ein
> 3-Bit-Zähler initialisiert sich immer mit einer 7, wobei im Quellcode
> explizit der Init-Wert 0 steht.

Nein da steht der "Reset"-Wert 0, kein "Init"-Wert. Ein explizites Init 
-also eine Wertzuweisung bei der Signaldeklaration- findet sich nicht im 
Code.
Dann nimmt VHDL den linken Wert des ranges und das ist 7.

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


Lesenswert?

Viktor B. schrieb:
> Also, der clk_ersatz ist an den SCL-Port des SPI angeschlossen,
> deswegen asynchron
Dann solltest du den SCL erst mal über 1-2 Flipflops einsynchronisieren. 
Sonst tut das Design immer wieder mal "seltsame" Dinge...
Siehe http://www.lothar-miller.de/s9y/categories/35-Einsynchronisieren

Eine Flankenerkennung geht übrigens einfacher:
http://www.lothar-miller.de/s9y/categories/18-Flankenerkennung

> Wenn der Code hier fehlerfrei ist
Wenn die Simulation läuft (und nicht solche seltsamen unvollständigen 
Sensitivlisten hat, die dann aber der Synthesizer anmeckert), dann ist 
der Code fehlerfrei.

> was könnte sonst den Reset-Wert des Zählers beeinflussen?
Wenn du den Zähler eigentlich nie verwendest, wird der auf den nötigen 
Wert zurechtoptimiert. Wenn du z.B. 100 Eingänge aufwändig miteinander 
verknüpfst und verrechnest aber das Ergebnis auf keine Art ausgibst, 
dann wird alles wegoptimiert. Denn der Synthesizer realisiert nur das in 
Hardware, was tatsächlich Auswirkung auf Ausgänge hat.

> Es kann auch sein, das mein ISE Webpack spinnt
Das ist die Hoffnung des Anfängers, aber sehr unwahrscheinlich 
(<0,0001%).
Welche Infos, Warnungen und Fehler werden beim Übersetzen des Codes 
ausgegeben?

> Eins der Fehler hab ich schon isolieren können - ein 3-Bit-Zähler
> initialisiert sich immer mit einer 7, wobei im Quellcode explizit der
> Init-Wert 0 steht.
Da steht gar nix (und deshalb wird wie erwähnt defaultmäßig der linke 
Rangewert genommen):
signal value: integer range width-1 downto 0;
Schreib doch einfach mal:
signal value: integer range width-1 downto 0 := 0;

BTW: warum definierst du die Zähler abfallend? Ein Integer ist als 
steigender Wert definiert. Evtl. haut es dich da schon auf die Nase. 
Probier es mal wie der Rest der Welt so:
signal value: integer range 0 to width-1;
Dann hat sich mit ein wenig Mitdenken auch die Sache mit dem Initwert 
erledigt. Und dir wird klar, warum der Rest der Welt dieses Problem 
nicht hat...

: Bearbeitet durch Moderator
von Viktor B. (coldlogic)


Lesenswert?

Nach dem Hinzufügen eines expliziten Inits (:= 0) scheint alles sogar in 
der post-route simulation zu funktionieren! Vielen Dank für die 
Hilfestellung, sonst hätte ich den Fehler noch etliche Monate gesucht. 
Trotzdem komisch, dass der Zähler sich auch nicht unter Reset 
zurückgesetzt hat. Dann wende ich mich als nächstes der 
Einsynchronisierung hin.

Und wegen der Definition des Zählers: Ich hab einfach stumpf alle 
Vektoren als abfallend definiert, weil es für mich (eben Anfänger) ein 
Leichtes ist, sich in den Definitionen zu verheddern und dann ein paar 
Vektoren spiegelverkehrt zuzuweisen. Das hatte ich schon durch und würde 
es nur ungerne nochmal tun.

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


Lesenswert?

Viktor B. schrieb:
> Ich hab einfach stumpf alle Vektoren als abfallend definiert
Vektoren schon, denn durch das downto wird da eine absteigende 
Wertigkeit der Bits von links nach rechts abgebildet.
Bei einem Integer ist das so nicht darstellbar. Der zählt einfach.von 
unten nach oben...

von C. A. Rotwang (Gast)


Lesenswert?

Viktor B. schrieb:

> Und wegen der Definition des Zählers: Ich hab einfach stumpf alle
> Vektoren als abfallend definiert, weil es für mich (eben Anfänger) ein
> Leichtes ist, sich in den Definitionen zu verheddern und dann ein paar
> Vektoren spiegelverkehrt zuzuweisen. Das hatte ich schon durch und würde
> es nur ungerne nochmal tun.

Man kann ein paar "Fehler" mit den Zählern umgehen, wenn man statt die 
"Eckwerte" des counters -also der Grösste und der Kleinste- als Zahlen 
anzugeben (bei dir 0 und 7) die Attribute 'high und 'low verwendet.
Dazu muss man -wie du bereits getan hast- den Zähler als integer range 
definieren und (was bei dir nicht der Fall ist) diese integer range als 
eigenen Typ deklarieren.

Beispielschnipsel:
1
architecture behave of clock_blink is
2
3
  signal blink_int_q : std_logic                        := '0';
4
  type T_COUNT is integer range 100*2**20 downto 0;
5
  signal count_q     : T_COUNT := T_COUNT'low;
6
begin
7
  process(clk)
8
  begin
9
    if rising_edge(clk) then
10
      if count_q = T_COUNT'low then
11
        count_q     <= T_COUNT'high;
12
        blink_int_q <= not blink_int_q;
13
      else
14
        count_q <= count_q - 1;
15
      end if;
16
    end if;
17
  end process;

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.