Forum: FPGA, VHDL & Co. latch ?


von chris (Gast)


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;


1
library IEEE; 
2
use IEEE.std_logic_1164.all; 
3
entity fsm is 
4
  port ( 
5
    clk, reset, x1 : IN std_logic; 
6
    outp : OUT std_logic); 
7
end entity; 
8
architecture beh1 of fsm is 
9
  type state_type is (s1,s2,s3,s4); 
10
  signal state, next_state: state_type; 
11
begin 
12
  process1: process (clk, reset) 
13
  begin 
14
    if (reset ='1') then 
15
      state <= s1; 
16
    elsif (clk = '1' and clk'Event) then 
17
      state <= next_state; 
18
    end if; 
19
  end process process1; 
20
  process2 : process (state, x1) 
21
  begin 
22
    case state is 
23
      when s1 => 
24
        if x1='1' then 
25
          next_state <= s2; 
26
        else 
27
          next_state <= s1;    ------ 
28
        end if; 
29
      when s2 => next_state <= s4; 
30
      when s3 => next_state <= s4; 
31
      when s4 => next_state <= s1; 
32
    end case; 
33
  end process process2; 
34
  process3 : process (state) 
35
    begin 
36
      case state is 
37
        when s1 => outp <= '1'; 
38
        when s2 => outp <= '1'; 
39
        when s3 => outp <= '0'; 
40
        when s4 => outp <= '0'; 
41
      end case; 
42
  end process process3; 
43
end beh1;

 chris

von Xenu (Gast)


Lesenswert?

Wieso, es wird doch gar keins erzeugt...

von T.M. (Gast)


Lesenswert?

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

von chris (Gast)


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

von Axel (Gast)


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

von chris (Gast)


Lesenswert?

also da steig ich noch nicht dahinter ....

hier mal ein Auszug aus meinem Code


1
signal DATA : std_logic_vector(15 downto 0) ;
2
.
3
.
4
process(DATA,ACK, ... ) 
5
.
6
.
7
when DATA_H =>   ADDR <= "0";
8
                 if ACK = '1' then 
9
                 DATA(15 downto 8) <= DATA_IN;
10
                 end if;
11
when DATA_L =>   ADDR <= "0";
12
                 if ACK = '1' then 
13
                 DATA(7 downto 0) <= DATA_IN;
14
                 end if;
15
when START  =>   DATA_OUT <= DATA;
16
.
17
.
18
.

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
1
signal DATA : std_logic_vector(15 downto 0) ;
2
.
3
.
4
process(DATA,ACK, ... ) 
5
.
6
.
7
when DATA_H =>   ADDR <= "0";
8
                 if ACK = '1' then 
9
                 DATA(15 downto 8) <= DATA_IN;
10
                 else DATA <= DATA ;
11
                 end if;
12
when DATA_L =>   ADDR <= "0";
13
                 if ACK = '1' then 
14
                 DATA(7 downto 0) <= DATA_IN;
15
                 else DATA <= DATA ;
16
                 end if;
17
when START  =>   DATA_OUT <= DATA;
18
.
19
.
20
.

zweite Möglichkeit : DATA vorbelegen
1
signal DATA : std_logic_vector(15 downto 0) ;
2
.
3
.
4
process(DATA,ACK, ... ) 
5
.
6
DATA <= DATA ;
7
.
8
case xx is 
9
.
10
.
11
when DATA_H =>   ADDR <= "0";
12
                 if ACK = '1' then 
13
                 DATA(15 downto 8) <= DATA_IN;
14
                 end if;
15
when DATA_L =>   ADDR <= "0";
16
                 if ACK = '1' then 
17
                 DATA(7 downto 0) <= DATA_IN;
18
                 end if;
19
when START  =>   DATA_OUT <= DATA;
20
.
21
.
22
.

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' ..... :-(
1
signal DATA : std_logic_vector(15 downto 0) ;
2
.
3
.
4
process(DATA,ACK, ... ) 
5
.
6
DATA <= (others => '0');
7
.
8
case xx is 
9
.
10
.
11
when DATA_H =>   ADDR <= "0";
12
                 if ACK = '1' then 
13
                 DATA(15 downto 8) <= DATA_IN;
14
                 end if;
15
when DATA_L =>   ADDR <= "0";
16
                 if ACK = '1' then 
17
                 DATA(7 downto 0) <= DATA_IN;
18
                 end if;
19
when START  =>   DATA_OUT <= DATA;
20
.
21
.
22
.

von Torsten M. (tome)


Lesenswert?

Um sowas zu vermeiden mache ich folgendes:
1
signal DATA      : std_logic_vector(15 downto 0) ;
2
signal LOAD_DATA_HIGH : std_logic;
3
signal LOAD_DATA_LOW : std_logic;
4
.
5
.
6
process(DATA,ACK, ... )
7
.
8
LOAD_DATA_HIGH <= '0';
9
LOAD_DATA_LOW  <= '0';
10
.
11
case xx is
12
.
13
when DATA_H => ADDR <= "0";
14
               if ACK = '1' then
15
                 LOAD_DATA_HIGH <= '1';
16
               end if;
17
when DATA_L => ADDR <= "0";
18
               if ACK = '1' then
19
                 LOAD_DATA_LOW <= '1';
20
               end if;
21
22
when START => DATA_OUT <= DATA;
23
.
24
end process;
25
.
26
LOAD_DATA : process (clk) is
27
begin
28
if clk'event and clk='1' then
29
  if LOAD_DATA_HIGH = '1' then
30
    DATA(15 downto 8) <= DATA_IN;
31
  elsif LOAD_DATA_LOW = '1' then
32
    DATA(7 downto 0) <= DATA_IN;
33
  end if;
34
end if;
35
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.

von chris (Gast)


Lesenswert?

danke

 chris

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.