www.mikrocontroller.net

Forum: FPGA, VHDL & Co. latch ?


Autor: chris (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hallo,
das beispiel eine SM habe ich von xilinx .. leicht abgeändert ...
wie kann ich es vermeiden das ein Latch für das Signal outp erzeugt
wird, wenn der Fall eintritt
when s1 => xxxxx next_state => s1;



library IEEE; 
use IEEE.std_logic_1164.all; 
entity fsm is 
  port ( 
    clk, reset, x1 : IN std_logic; 
    outp : OUT std_logic); 
end entity; 
architecture beh1 of fsm is 
  type state_type is (s1,s2,s3,s4); 
  signal state, next_state: state_type; 
begin 
  process1: process (clk, reset) 
  begin 
    if (reset ='1') then 
      state <= s1; 
    elsif (clk = '1' and clk'Event) then 
      state <= next_state; 
    end if; 
  end process process1; 
  process2 : process (state, x1) 
  begin 
    case state is 
      when s1 => 
        if x1='1' then 
          next_state <= s2; 
        else 
          next_state <= s1;    ------ 
        end if; 
      when s2 => next_state <= s4; 
      when s3 => next_state <= s4; 
      when s4 => next_state <= s1; 
    end case; 
  end process process2; 
  process3 : process (state) 
    begin 
      case state is 
        when s1 => outp <= '1'; 
        when s2 => outp <= '1'; 
        when s3 => outp <= '0'; 
        when s4 => outp <= '0'; 
      end case; 
  end process process3; 
end beh1;


 chris

Autor: Xenu (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wieso, es wird doch gar keins erzeugt...

Autor: T.M. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Den letzten Prozess könnte man mit eine Defaultanweisung bissl
verkürzen, sonst fällt mir auch kein Fehler auf:
process3 : process (state)
begin
outp <= '0';
case state is
when s1 => outp <= '1';
when s2 => outp <= '1';
end case;
end process process3;

Autor: chris (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ok,
ich dachte :
1. für x1 /= '1' dann bleibt immer  next_state <= s1
2. ok, process1 wird mir dem Takt aufgerufen und macht
   state <= next_state;
3. process3 wird nicht mehr aufgerufen, weil state sich nicht
   ändert siehe 1.

d.h. doch das process3 nicht mit jedem Takt aufgerufen wird und somit
ein Latch erzeugt wird ?

 Danke
   chris

Autor: Axel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ein Latch wird nur generiert, wenn sich ein Eingang ändern kann und
keinen Einfluss auf den Ausgang haben soll. Die fehlen dann meist in
der Sensitivity List.

Ist hier aber nicht der Fall, weil die Eingänge alle in der Sensitivity
List stehen.

Ist übrigends vollkommen unabhängig vom Takt.

Gruss
Axel

Autor: chris (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
also da steig ich noch nicht dahinter ....

hier mal ein Auszug aus meinem Code


signal DATA : std_logic_vector(15 downto 0) ;
.
.
process(DATA,ACK, ... ) 
.
.
when DATA_H =>   ADDR <= "0";
                 if ACK = '1' then 
                 DATA(15 downto 8) <= DATA_IN;
                 end if;
when DATA_L =>   ADDR <= "0";
                 if ACK = '1' then 
                 DATA(7 downto 0) <= DATA_IN;
                 end if;
when START  =>   DATA_OUT <= DATA;
.
.
.

ich hab eine Stae Machine mit 3 Prozesse gemacht, das ist ein Auszug
aus dem dritten Prozess (nicht getaktet)
es könnne 8 bit gelesenen werden,  mit ACK wird mitgeteilt das dier
richtigen daten am eingang anliegen.
es sollen zwei byte gelesen werden und dann als 16 bit wort
weitergegeben werden. (in state START)
.. also für obenigen code entsteht für DATA ein Latch. ( bzw 16 1 bit
Latches )
ok das verstehe ich da es bei if der else zweig fehlt...

also erte möglichkeit : else zweig einfügen
signal DATA : std_logic_vector(15 downto 0) ;
.
.
process(DATA,ACK, ... ) 
.
.
when DATA_H =>   ADDR <= "0";
                 if ACK = '1' then 
                 DATA(15 downto 8) <= DATA_IN;
                 else DATA <= DATA ;
                 end if;
when DATA_L =>   ADDR <= "0";
                 if ACK = '1' then 
                 DATA(7 downto 0) <= DATA_IN;
                 else DATA <= DATA ;
                 end if;
when START  =>   DATA_OUT <= DATA;
.
.
.

zweite Möglichkeit : DATA vorbelegen
signal DATA : std_logic_vector(15 downto 0) ;
.
.
process(DATA,ACK, ... ) 
.
DATA <= DATA ;
.
case xx is 
.
.
when DATA_H =>   ADDR <= "0";
                 if ACK = '1' then 
                 DATA(15 downto 8) <= DATA_IN;
                 end if;
when DATA_L =>   ADDR <= "0";
                 if ACK = '1' then 
                 DATA(7 downto 0) <= DATA_IN;
                 end if;
when START  =>   DATA_OUT <= DATA;
.
.
.

es wird bei beiden möglichkeiten ein Latch erzeugt ....
jetzt bin ich verwirrt ....

Damit wird kein Latch erzeugt, aber die funktionsweise ist auch nciht
die von mir gewünschte, oder ?
schließtlich wird bit 7..0 im ersten state geladen,
wenn der Prozess wieder aufgerufen wird um bit 15-8 zu laden werden bit
7..0 zu '0' ..... :-(
signal DATA : std_logic_vector(15 downto 0) ;
.
.
process(DATA,ACK, ... ) 
.
DATA <= (others => '0');
.
case xx is 
.
.
when DATA_H =>   ADDR <= "0";
                 if ACK = '1' then 
                 DATA(15 downto 8) <= DATA_IN;
                 end if;
when DATA_L =>   ADDR <= "0";
                 if ACK = '1' then 
                 DATA(7 downto 0) <= DATA_IN;
                 end if;
when START  =>   DATA_OUT <= DATA;
.
.
.

Autor: Torsten M. (tome)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Um sowas zu vermeiden mache ich folgendes:
signal DATA      : std_logic_vector(15 downto 0) ;
signal LOAD_DATA_HIGH : std_logic;
signal LOAD_DATA_LOW : std_logic;
.
.
process(DATA,ACK, ... )
.
LOAD_DATA_HIGH <= '0';
LOAD_DATA_LOW  <= '0';
.
case xx is
.
when DATA_H => ADDR <= "0";
               if ACK = '1' then
                 LOAD_DATA_HIGH <= '1';
               end if;
when DATA_L => ADDR <= "0";
               if ACK = '1' then
                 LOAD_DATA_LOW <= '1';
               end if;

when START => DATA_OUT <= DATA;
.
end process;
.
LOAD_DATA : process (clk) is
begin
if clk'event and clk='1' then
  if LOAD_DATA_HIGH = '1' then
    DATA(15 downto 8) <= DATA_IN;
  elsif LOAD_DATA_LOW = '1' then
    DATA(7 downto 0) <= DATA_IN;
  end if;
end if;
end process LOAD_DATA;

In der State-Machine setze ich nur die 2 LOAD-Signale auf 1 wenn die
Daten geladen werden sollen. In dem anderen Prozess werden diese
Signale dann abgefragt und die Daten zugewiesen. Bei dem Ganzen dürfte
aber eine Verzögerung um 1 Takt entstehen, weil der 2. Prozess erst
reagieren kann, wenn die LOAD-Signale im vorherigen Takt gesetzt
wurden. Das müsste man beachten.

Autor: chris (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
danke

 chris

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [vhdl]VHDL-Code[/vhdl]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.