Forum: FPGA, VHDL & Co. I2C Master in VHDL


von Robert S. (razer) Benutzerseite


Angehängte Dateien:

Lesenswert?

Hallo an alle,

erstmal, ich bin VHDL bzw. FPGA Anfänger, konnte jedoch meine ersten 
erfolge am Demoboard schon verbuchen (Lauflichter, 7 Segment Anzeige, 
Zustandsautomaten,...).

Jetzt versuche ich gerade einen einfachen I2C-Master zu beschreiben, der 
nur senden kann. Dazu habe ich jede I2C Aktion (Start, Sende Bit, Lese 
Ack, Stop) einzeln beschrieben. Diese Kommandos werden von einem höheren 
Modul dann in der richtigen Abfolge gestartet.

Angehängt habe ich meinen VHDL-Source Code.

Dabei bekomme ich mehrere Warnungen, die mir zu denken geben:
1
Warning (10631): VHDL Process Statement warning at i2c_low.vhd(225): inferring latch(es) for signal 
2
or variable "SDA", which holds its previous value in one or more paths through the process
3
4
Warning (10631): VHDL Process Statement warning at i2c_low.vhd(225): inferring latch(es) for signal 
5
or variable "SCL", which holds its previous value in one or more paths through the process
6
Warning: Timing Analysis is analyzing one or more combinational loops as latches
7
  Warning: Node "I2C_LOW:I2C|SDA_370" is a latch
8
  Warning: Node "I2C_LOW:I2C|SDA$latch" is a latch
9
  Warning: Node "I2C_LOW:I2C|SCL$latch" is a latch
10
  Warning: Node "I2C_LOW:I2C|SCL_353" is a latch

Mir ist klar, dass für SCL und SDA Latches erzeugt werden, da nicht in 
jedem Zustand die beiden Leitungen geändert werden. Erkenne ich das 
richtig?

Doch woher kommt die Kombinatorische Schleife??
1
Warning: Found 14 node(s) in clock paths which may be acting as ripple and/or gated clocks -- node(s) 
2
analyzed as buffer(s) resulting in clock skew
3
  Info: Detected gated clock "I2C_LOW:I2C|SCL~1" as buffer
4
  Info: Detected gated clock "I2C_LOW:I2C|SCL~0" as buffer
5
  Info: Detected gated clock "I2C_LOW:I2C|SDA~1" as buffer
6
  Info: Detected gated clock "I2C_LOW:I2C|SDA~2" as buffer
7
  Info: Detected ripple clock "I2C_LOW:I2C|i2c_state.ST_I2C_ACK_A" as buffer
8
  Info: Detected ripple clock "I2C_LOW:I2C|i2c_state.ST_I2C_ACK_B" as buffer
9
  Info: Detected ripple clock "I2C_LOW:I2C|i2c_state.ST_I2C_ACK_C" as buffer
10
  Info: Detected ripple clock "I2C_LOW:I2C|i2c_state.ST_I2C_ACK_D" as buffer
11
  Info: Detected ripple clock "I2C_LOW:I2C|i2c_state.ST_I2C_SEND_A" as buffer
12
  Info: Detected ripple clock "I2C_LOW:I2C|i2c_state.ST_I2C_ACK_E" as buffer
13
  Info: Detected ripple clock "I2C_LOW:I2C|i2c_state.ST_I2C_SEND_B" as buffer
14
  Info: Detected ripple clock "I2C_LOW:I2C|i2c_state.ST_I2C_IDLE" as buffer
15
  Info: Detected ripple clock "I2C_LOW:I2C|i2c_state.ST_I2C_SEND_C" as buffer
16
  Info: Detected ripple clock "I2C_LOW:I2C|delay_flag" as buffer
17
18
Warning: Can't achieve minimum setup and hold requirement CLOCK_24[0] along 8 path(s). 
19
See Report window for details.

Diese Warnungen verstehe ich leider (noch) nicht. Kann mir jemand dazu 
Tipps geben?

Bitte gebt mir auch Kritiken zu meinem VHDL Code. Bin noch Anfänger und 
kann Tipps gut gebrauchen ;)

Danke im Voraus!
lg Robert

von bko (Gast)


Lesenswert?

>Mir ist klar, dass für SCL und SDA Latches erzeugt werden, da nicht in
>jedem Zustand die beiden Leitungen geändert werden. Erkenne ich das
>richtig?

Genau, alleine schon die if(delay_flag = '0')-Anweisung würde
ohne else Zweig in diesm Prozess Latches ergeben.

>   I2CPINS:process(i2c_state, delay_flag, bit_to_send)
>    begin
>      if(delay_flag = '0') then
>        case i2c_state is
>          when ST_I2C_START_A =>
>            SDA <= '0';
>            SCL <= '1';
  (...)
>       when others =>
>       end case;
>     end if;
>    end process;

Ich nehme mal an das deine Zielhardware ein (Xilinx, Altera oa.)
FPFA ist. Da es bei diesen Bausteinen keine Latches als Primitives
gibt, muss die Software die Latches aus den LUTs "basteln".
a) Die globalen Clock-Trees können an die Latches nur mit
   zusätzlichem Delay  geroutet werden.
    Das besagt diese Warnung:
>Warning: Can't achieve minimum setup and hold requirement CLOCK_24[0] >along 8 
path(s).

Außerdem ist der Speicherzustand deiner Latches von verschiedenen
Eingangssignalen abhängig:
  z.B. Speichern wenn Delay_flag = '1' oder
       speichern in state "ST_I2C_START_B" und so weiter....
Da kommt eine Menge Kombinatorik auf den Takteingängen der
 Latches zusammen, was dann diese Meldungen besagen:

>Warning: Found 14 node(s) in clock paths which may be acting as ripple >and/or 
gated clocks -- node(s)
>analyzed as buffer(s) resulting in clock skew
>  Info: Detected gated clock "I2C_LOW:I2C|SCL~1" as buffer
   (...)

Ich hätte zwei Lösungen:
  SDA und SCL nach dem Prozess-Statement vorbesetzen:
  I2CPINS:process(i2c_state, delay_flag, bit_to_send)
     begin
     SDA <= EinWert;
     SCL <= andererWert;
    if(delay_flag = '0') then
        case i2c_state is
       (...)

oder um "Latchgefahren" ganz auszuschließen, die
Einprozessschreibweise, beschrieben bei lkmiller:
http://www.lothar-miller.de/s9y/categories/37-FSM

dann müssten diese Warnings verschwinden.

von Robert S. (razer) Benutzerseite


Lesenswert?

Danke für die Antwort :)

bko schrieb:
> Ich nehme mal an das deine Zielhardware ein (Xilinx, Altera oa.)
> FPFA ist. Da es bei diesen Bausteinen keine Latches als Primitives

Genau. Zielplatform ist ein Alter CycloneII EP2C20 (Altera DE 
Development Board)

bko schrieb:
> Ich hätte zwei Lösungen:
>   SDA und SCL nach dem Prozess-Statement vorbesetzen:
>   I2CPINS:process(i2c_state, delay_flag, bit_to_send)
>      begin
>      SDA <= EinWert;
>      SCL <= andererWert;
>     if(delay_flag = '0') then
>         case i2c_state is
>        (...)

Denke ich geht nicht, da eben das SDA und SCL sich nicht nicht bei jeder 
Stateänderung ändern dürfen (Sie Beschreibung der Zustände).

Das heißt, in der Zweiprozessdarstellung ist das so nicht möglich?

Kann ich einem Prozess 2 "case"-Zustandsautomaten beschreiben, um die 
Trennung der Zuweisung der Ausgänge sichtbarer zu machen?

lg Robert

von Timscho (Gast)


Lesenswert?

Hallo Robert,

hast du dein I2C Modul mittlerweile schon zum Laufen gebracht?

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.