Forum: FPGA, VHDL & Co. Simulation funktioniert, im CPLD werden Signale ignoriert!


von Roman D. (smarties)


Angehängte Dateien:

Lesenswert?

Hallo,

ich arbeite mit einem Coolrunner2 CPLD und möchte mir zwei 
Phasenverschobene Signale erzeugen wobei die Phasenverschiebung in 
90Grad Schritten einstellbar sein soll. Gelöst habe ich das mit vier 
2-bit Countern mit verschiedenen preload Werten. Die Ausgangssignale mit 
1/4 der CLK Frequenz werden über einen MUX ausgeben.
In der Simulation funktioniert das auch perfekt, nur im CPLD eben nicht. 
Ich kann an den beiden Pins zur Phasenauswahl beliebige Signale anlegen, 
die Phasenverschiebung bleibt immer auf 0Grad.
Wenn ich mir im Xilinx WebPack die RTL Schematic ansehe, ist der Port 
PHSEL nicht verbunden (siehe Anhang).
Vielleicht kann mir in dieser Angelegenheit jemand helfen. Ich bin schon 
etwas verzweifelt!

Danke, Roman

Hier der Code:
count.vhd
1
library IEEE;
2
use IEEE.STD_LOGIC_1164.ALL;
3
use IEEE.NUMERIC_STD.ALL;
4
5
entity count is
6
    Port ( CLK : in  STD_LOGIC;
7
           RST : in  STD_LOGIC;
8
           PH0 : out  STD_LOGIC;
9
           PH1 : out  STD_LOGIC;
10
           PH2 : out  STD_LOGIC;
11
           PH3 : out  STD_LOGIC
12
    );
13
end count;
14
15
architecture Behavioral of count is
16
   signal sCNT0 : STD_LOGIC_VECTOR(1 downto 0);
17
   signal sCNT1 : STD_LOGIC_VECTOR(1 downto 0);
18
   signal sCNT2 : STD_LOGIC_VECTOR(1 downto 0);
19
   signal sCNT3 : STD_LOGIC_VECTOR(1 downto 0);
20
begin
21
22
   count : process (CLK, RST)
23
   begin
24
      if RST = '0' then
25
         sCNT0 <= "00";
26
         sCNT1 <= "11";
27
         sCNT2 <= "10";
28
         sCNT3 <= "01";
29
      elsif rising_edge(CLK) then
30
         PH0 <= NOT(sCNT0(1));
31
         PH1 <= NOT(sCNT1(1));
32
         PH2 <= NOT(sCNT2(1));
33
         PH3 <= NOT(sCNT3(1));
34
         sCNT0 <= STD_LOGIC_VECTOR(unsigned(sCNT0) + 1);
35
         sCNT1 <= STD_LOGIC_VECTOR(unsigned(sCNT1) + 1);
36
         sCNT2 <= STD_LOGIC_VECTOR(unsigned(sCNT2) + 1);
37
         sCNT3 <= STD_LOGIC_VECTOR(unsigned(sCNT3) + 1);
38
      end if;
39
   end process count;
40
      
41
end Behavioral;

comb.vhd
1
library IEEE;
2
use IEEE.STD_LOGIC_1164.ALL;
3
4
entity comb is
5
    Port ( PH0 : in  STD_LOGIC;
6
           PH1 : in  STD_LOGIC;
7
           PH2 : in  STD_LOGIC;
8
           PH3 : in  STD_LOGIC;
9
           PHSEL : in  STD_LOGIC_VECTOR (1 downto 0);
10
           LEDEN : in  STD_LOGIC_VECTOR (1 downto 0);
11
           TOFO : out  STD_LOGIC;
12
           LEDOA : out  STD_LOGIC;
13
           LEDOB : out  STD_LOGIC);
14
end comb;
15
16
architecture Behavioral of comb is
17
   signal sEN   : STD_LOGIC;
18
   signal sINT0 : STD_LOGIC;
19
   signal sINT1 : STD_LOGIC;
20
   signal sINT2 : STD_LOGIC;
21
   signal sINT3 : STD_LOGIC;
22
   signal sLEDO : STD_LOGIC;
23
begin
24
25
   sEN   <= LEDEN(1) OR LEDEN(0);
26
   TOFO  <= sEN AND PH0;
27
   sINT0 <= NOT(PHSEL(1)) AND NOT(PHSEL(0)) AND PH0;
28
   sINT1 <= NOT(PHSEL(1)) AND PHSEL(0) AND PH1;
29
   sINT2 <= PHSEL(1) AND NOT(PHSEL(0)) AND PH2;
30
   sINT3 <= PHSEL(1) AND PHSEL(0) AND PH3;
31
   sLEDO <= sINT0 OR sINT1 OR sINT2 OR sINT3;
32
   LEDOA <= sLEDO;
33
   LEDOB <= sLEDO;
34
35
end Behavioral;

clkgen.vhd
1
library IEEE;
2
use IEEE.STD_LOGIC_1164.ALL;
3
4
entity clkgen is
5
    Port ( CLK   : in   STD_LOGIC;
6
           RST   : in   STD_LOGIC;
7
           PHSEL : in   STD_LOGIC_VECTOR (1 downto 0);
8
           LEDEN : in   STD_LOGIC_VECTOR (1 downto 0);
9
           TOFO  : out  STD_LOGIC;
10
           LEDOA : out  STD_LOGIC;
11
           LEDOB : out  STD_LOGIC);
12
end clkgen;
13
14
architecture Behavioral of clkgen is
15
16
   component comb is
17
       Port ( PH0 : in  STD_LOGIC;
18
              PH1 : in  STD_LOGIC;
19
              PH2 : in  STD_LOGIC;
20
              PH3 : in  STD_LOGIC;
21
              PHSEL : in  STD_LOGIC_VECTOR (1 downto 0);
22
              LEDEN : in  STD_LOGIC_VECTOR (1 downto 0);
23
              TOFO : out  STD_LOGIC;
24
              LEDOA : out  STD_LOGIC;
25
              LEDOB : out  STD_LOGIC);
26
   end component comb;
27
   
28
   component count is
29
    Port ( CLK : in  STD_LOGIC;
30
           RST : in  STD_LOGIC;
31
           PH0 : out  STD_LOGIC;
32
           PH1 : out  STD_LOGIC;
33
           PH2 : out  STD_LOGIC;
34
           PH3 : out  STD_LOGIC);
35
   end component count;
36
37
   signal sPH0 : STD_LOGIC;
38
   signal sPH1 : STD_LOGIC;
39
   signal sPH2 : STD_LOGIC;
40
   signal sPH3 : STD_LOGIC;
41
begin
42
43
   inst_comb : comb
44
   port map (
45
      PH0      => sPH0,
46
      PH1      => sPH1,
47
      PH2      => sPH2,
48
      PH3      => sPH3,
49
      PHSEL    => PHSEL,
50
      LEDEN    => LEDEN,
51
      TOFO     => TOFO,
52
      LEDOA    => LEDOA,
53
      LEDOB    => LEDOB
54
      );
55
      
56
   inst_count : count
57
   port map (
58
      CLK      => CLK,
59
      RST      => RST,
60
      PH0      => sPH0,
61
      PH1      => sPH1,
62
      PH2      => sPH2,
63
      PH3      => sPH3
64
      );
65
66
end Behavioral;

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


Lesenswert?

Offenbar  hast du Probleme mit der Initialisierung der Zähler. Die 
Synthese geht davon aus, dass alle vier mit Null starten und so immer 
das selbe ausgeben. Ergo ist der Wahleingamg nutzlos. Merke: Resetwert 
/= Initialwert.
Dein Reset hier ist (wie üblich) nutzlos und unnötig.


Ich mache einen Schritt zurück und frage mich: warum eigentlich so 
umständlich?
Warum nimmst du nicht ein einziges 4-Bit-Schieberegister, initialisierst 
das mit "1100" und lässt über den Mux ein Bit davon ausgeben?
20 Zeilen Code in einem Modul und fertig....

von Roman D. (smarties)


Lesenswert?

Vielen Dank für die Info, an die Initialisierung habe ich nicht gedacht! 
Ich habe den Code umgebaut und mit einem Schieberegister realisiert, das 
funktioniert, jedoch habe ich ein ganz komisches Phänomen.
Ich gebe dem CPLD folgenden Ablauf vor:
100us Phase 0
1,5ms Pause (sEN = '0')
100us Phase 90
1,5ms Pause (sEN = '0')
100us Phase 180
1,5ms Pause (sEN = '0')
100us Phase 270
1,5ms Pause (sEN = '0')
20ms Pause
Das ganze wird in einer Endlosschleife wiederholt. Wenn ich mir den 
Output am Oszi ansehe, habe ich manchmal (jeder 10. - 20. Durchlauf) ein 
fehlerhaftes Signal.
11100110011... oder
10110011001... oder
00011001100... oder
10001000100... oder ähnliche

wie kann das passieren?
der CPLD läuft mit 80MHz

Vielen Dank für die Hilfe!
Roman
1
entity clkgen is
2
  port (
3
    CLKI    : in  STD_LOGIC;
4
    RST     : in  STD_LOGIC;
5
    LEDEN  : in  STD_LOGIC_VECTOR(1 downto 0);
6
    PHSEL   : in  STD_LOGIC_VECTOR(1 downto 0);
7
    TOFO    : out STD_LOGIC;
8
    LEDOA   : out STD_LOGIC;
9
    LEDOB   : out STD_LOGIC
10
    );
11
end clkgen;
12
13
architecture behavioural of clkgen is
14
    signal sPH0    : STD_LOGIC;
15
    signal sPH1    : STD_LOGIC;
16
    signal sPH2    : STD_LOGIC;
17
    signal sPH3    : STD_LOGIC;
18
    signal sINT0   : STD_LOGIC;
19
    signal sINT1   : STD_LOGIC;
20
    signal sINT2   : STD_LOGIC;
21
    signal sINT3   : STD_LOGIC;
22
    signal sEN     : STD_LOGIC;
23
    signal sLEDO   : STD_LOGIC;
24
    signal sREG    : STD_LOGIC_VECTOR(3 downto 0);
25
    constant cINIT : STD_LOGIC_VECTOR(3 downto 0) := "1100";
26
begin
27
  generate: process (CLKI, RST)
28
  begin
29
    if RST = '0' then
30
      sREG <= cINIT;
31
      sPH0 <= sREG(3);
32
      sPH1 <= sREG(0);
33
      sPH2 <= sREG(1);
34
      sPH3 <= sREG(2);
35
    else 
36
      if rising_edge(CLKI) then
37
        if sEN = '1' then
38
          sPH0 <= sREG(3);
39
          sPH1 <= sREG(0);
40
          sPH2 <= sREG(1);
41
          sPH3 <= sREG(2);
42
          sREG <= sREG(2 downto 0) & sREG(3); -- rotate left
43
        else
44
          sREG  <= cINIT;
45
        end if;
46
      end if;
47
    end if;
48
  end process;
49
  
50
  sEN   <= LEDEN(1) OR LEDEN(0);
51
  TOFO  <= sPH0 AND sEN;
52
  sINT0 <= NOT(PHSEL(1)) AND NOT(PHSEL(0)) AND sPH0;
53
  sINT1 <= NOT(PHSEL(1)) AND PHSEL(0) AND sPH1;
54
  sINT2 <= PHSEL(1) AND NOT(PHSEL(0)) AND sPH2;
55
  sINT3 <= PHSEL(1) AND PHSEL(0) AND sPH3;
56
  sLEDO <= sINT0 OR sINT1 OR sINT2 OR sINT3;
57
  LEDOA <= sLEDO AND sEN;
58
  LEDOB <= sLEDO AND sEN;
59
  
60
end behavioural;

von bko (Gast)


Lesenswert?

Evtl. kommt es daher das "sEN" nicht einsyncronisiert ist.

Mindestens mit einem Flipflop z.b. so in etwa:

 (...)
> if rising_edge(CLKI) then
>    sEN_reg <= sEN
>    if sENreg = '1' then
 (...0

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


Lesenswert?

Falls das so ist, dann hast du folgenden Effekt:
 http://www.lothar-miller.de/s9y/archives/64-State-Machine-mit-asynchronem-Eingang.html
Denn (d)ein Schieberegister ist nichts anderes wie eine FSM...

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.