Forum: FPGA, VHDL & Co. SPI Schnittstelle CLK und Counter gesteuert


von Fredolin .. (fredolin92)


Angehängte Dateien:

Lesenswert?

Hallo liebe Community,
ich bin noch ein VHDL Neuling und stehe vor einem Problem.
Ich möchte eine SPI Schnittstelle auf einem CPLD realisieren.
Dabei soll es kein ChipSelect geben und die Ausgabe der MISO Leitung 
soll bei Beginn des Clocks starten. Mein Problem ist aus dem Screenshot 
zu entnehmen. Das Register "dinsr" wird erst bei der zweiten Flanke 
geschoben und dadurch kommt es zur Fehlübertragung. Ich habe bereits 
etliche Versuche im Code unternommen, jedoch ohne erfolg. Ich wäre um 
Ratschläge unendlich dankbar!

Hier mein Code:
1
library IEEE;
2
use IEEE.STD_LOGIC_1164.ALL;
3
use IEEE.NUMERIC_STD.ALL;
4
use IEEE.STD_LOGIC_UNSIGNED.ALL;
5
6
entity SPISlave is
7
    Generic (  dataBitDepth: NATURAL := 8;
8
    counterBitDepth: NATURAL := 3
9
  );
10
    Port ( SPICLK : in  STD_LOGIC;
11
           MISO : out  STD_LOGIC;
12
     count:  out std_logic_vector(counterBitDepth-1 downto 0);
13
           Din  : in  STD_LOGIC_VECTOR (dataBitDepth-1 downto 0)
14
    );
15
end SPISlave;
16
17
architecture Behavioral of SPISlave is
18
signal dinsr  : STD_LOGIC_VECTOR (dataBitDepth-1 downto 0) := "00000000";
19
signal pre_count: STD_LOGIC_VECTOR (counterBitDepth-1 downto 0) := "000";  --Initialisierung des Startzählers
20
begin
21
-- Counter Prozess
22
  process (SPICLK)   
23
  begin
24
    if RISING_EDGE(SPICLK) then   
25
      pre_count <= pre_count + "1";    
26
    end if;
27
  end process;
28
  count <= pre_count;
29
  count_8 <=  '1' when (pre_count = "111") else '0';
30
  
31
  
32
  -- Parallel-Eingänge --> MISO
33
  process (pre_count, SPICLK)   
34
  begin
35
    if (pre_count = "000") then
36
      dinsr <= Din;
37
    elsif RISING_EDGE(SPICLK) then                                
38
      dinsr <= dinsr(dinsr'left-1 downto 0) & '0'; 
39
    end if;
40
  end process;
41
    end Behavioral

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


Lesenswert?

Fredolin .. schrieb:
> Ich möchte eine SPI Schnittstelle auf einem CPLD realisieren. Dabei soll
> es kein ChipSelect geben
Das ist Murks. Ein einziger kleiner ESD Peak auf der CLK Leitung, und 
für den Test des Tages bist du um 1 Bit versetzt.
Oder hast du sonst irgendeinen Resync-Mechanismus?

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


Lesenswert?

Fredolin .. schrieb:
> use IEEE.NUMERIC_STD.ALL;
> use IEEE.STD_LOGIC_UNSIGNED.ALL;
Wer hat dir den Tipp gegeben?
Die numeric_std hat mit Sicherheit alles, was du brauchst...
http://www.lothar-miller.de/s9y/categories/16-Numeric_Std
Und auch den Beitrag "IEEE.STD_LOGIC_ARITH.ALL obsolete"

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


Lesenswert?

Fredolin .. schrieb:
> if (pre_count = "000") then
>       dinsr <= Din;
Das ist ein asynchroner kombinatorischer Reset. Der wird wegen 
Glitches in der Realität niemals zuverlässig funktionieren. Denn 
wenn z.B. der Zähler von 001 nach 010 hochgezählt wird, dann kann für 
kurze Zeit (im sub-ns Bereich) auch 011 oder 000 auftreten. Und was 
macht dann dein Zähler? Oder besser noch: was machen dann einzelne 
Flipflops deines Zählers?
Du weißt es nicht sicher? Richtig!

BTW: die Ursache deines jetzigen "Problems" heißt Latency...

: Bearbeitet durch Moderator
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.