Forum: FPGA, VHDL & Co. Address Latch ohne Reset ohne Einsynchronisieren


von Michael S. (msb)


Lesenswert?

Funktioniert ein solches Address-Latch ohne Reset und ohne 
Einsynchronisieren des asynchronen Latch-Impulses störungsfrei?

Ich nehme in kauf, dass es beim Systemstart ein unnötiges, aber nicht 
weiter schädliches latchen gibt.

1
entity address_latch is
2
    generic
3
    (
4
        width : integer := 16
5
    );
6
    port
7
    (
8
        clk_i             : in  std_logic;                           -- system clock (200Mhz)
9
        latch_enable_i    : in  std_logic;                           -- latch on rising edge (20ns wide pulse)
10
        address_data_i    : in  std_logic_vector(width-1 downto 0);  -- input data
11
        latched_address_o : out std_logic_vector(width-1 downto 0)   -- latched data
12
    );
13
end address_latch;
14
15
architecture address_latch_architecture of address_latch is
16
17
    signal last_latch_enable : std_logic; 
18
 
19
begin
20
21
    latch_address : process( clk_i )
22
    begin
23
        if rising_edge( clk_i ) then
24
           if ( last_latch_enable = '0' ) and ( latch_enable_i = '1' ) then
25
              latched_address_o <= address_data_i;
26
           end if;
27
           last_latch_enable = latch_i;
28
        end if;
29
    end process;
30
31
end address_latch_architecture;

von Klaus F. (kfalser)


Lesenswert?

Michael S1. schrieb:
> Funktioniert ein solches Address-Latch ohne Reset und ohne
> Einsynchronisieren des asynchronen Latch-Impulses störungsfrei?

Nein.
Denn es kann vorkommen, dass manche latched_address_o gelatcht werden, 
und manche nicht.

von Michael S. (msb)


Lesenswert?

Hmm, warum?
Der latch Impuls ist doppelt so lang wie ein Systemclockzyklus.
Da sollte man beim Abtasten des latch_enable_i doch eigentlich immer 
einen 0/1 Übergang erwischen.

Was müsste man denn Deiner Meinung nach tun um es sicher zu machen?

von Klaus F. (kfalser)


Lesenswert?

Es werden für jedes latched_address_o und für last_latch_enable ein FF 
erzeugt.
Die FF für latched_address_o haben einen Dateneingang der wahrscheinlich 
stabil ist (ich nehme an, die Adressen liegen längere Zeit stabil an) 
und eine CE Eingang, der die Setup- oder Hold Zeit verletzt.
In diesem Fall kann das FF latched_address_o die Adresse übernehmen oder 
nicht.

Auch das FF für last_latch_enable verletzt die Setup- oder Holdzeit.
Falls es in diesem Fall aber das latch_enable übernimmt, aber 
latched_address_o nicht, dann wird latched_address_o bei der nächsten 
Taktflanke nicht mehr getriggert,

von Klaus F. (kfalser)


Lesenswert?

Michael S1. schrieb:
> Was müsste man denn Deiner Meinung nach tun um es sicher zu machen?

latch_enable_i einsynchronisieren.
Damit verzögert sich das ganze um einen Takt.
Es hängt jetzt von Deinem System ab, ob die Adressen lange genug stabil 
liegen, oder ob man diese auch abtakten muss.

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


Lesenswert?

Ich würde mal diesen Ansatz vorsehen:
1
entity address_latch is
2
    generic
3
    (
4
        width : integer := 16
5
    );
6
    port
7
    (
8
        clk_i             : in  std_logic;                           -- system clock (200Mhz)
9
        latch_enable_i    : in  std_logic;                           -- latch on rising edge (20ns wide pulse)
10
        address_data_i    : in  std_logic_vector(width-1 downto 0);  -- input data
11
        latched_address_o : out std_logic_vector(width-1 downto 0);   -- latched data
12
        latched_valid_o   : out std_logic -- active for one cycle if adress is valid
13
    );
14
end address_latch;
15
16
architecture address_latch_architecture of address_latch is
17
    signal latch_enable_sr : std_logic_vector(2); 
18
begin
19
20
    latched_adress_o <= address_data_i when rising_edge(latch_enable_i);
21
    latch_enable_sr  <= latch_enable_sr(0) & latch_enable_i  when rising_edge(clk_i);
22
    latched_valid_o  <= '1' when latch_enable_sr="01" else '0';
23
24
end address_latch_architecture;

Aber es gilt auf jeden Fall, was Klaus Falser schrieb im Beitrag 
#3295956:
> Damit verzögert sich das ganze um einen Takt.

von Michael S. (msb)


Lesenswert?

Und wenn ich latched_address_o stabil haben möchte bis zum nächsten 
latch_enable_i?
Müsste ich das dann nochmal latchen mit dem valid signal?
Das kommt mir irgendwie zu kompliziert vor.

Warum verändet sich latched_address_o bei Deiner implementierung 
überhaupt, wenn keine steigende Flanke des enable kommt?

von Michael S. (msb)


Lesenswert?

In diskreter Hardware benutzt man dafür ja gern transparente Latches. 
Die haben ja auch den den Vorteil, dass die Adressen am Ausgang früh 
anliegen und die Addressdecoder mehr Zeit haben.

Es wird immer vor ungewollten latches in FPGAs gewarnt, aber warum nicht 
ein gewolltes transparentes Latch im FPGA implementieren?

Oder anderst gefragt: Was könnte folgender Code böses tun?

1
entity address_latch is
2
    generic
3
    (
4
        width : integer := 16
5
    );
6
    port
7
    (
8
        latch_enable_i    : in  std_logic;                           -- latch on rising edge (20ns wide pulse)
9
        address_data_i    : in  std_logic_vector(width-1 downto 0);  -- input data
10
        latched_address_o : out std_logic_vector(width-1 downto 0)   -- latched data
11
    );
12
end address_latch;
13
14
architecture address_latch_architecture of address_latch is
15
begin
16
17
    latch_address : process( latch_enable_i )
18
    begin
19
        if latch_enable_i = '1' then
20
            latched_address_o <= address_data_i;
21
        end if;
22
    end process;
23
24
end address_latch_architecture;

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


Lesenswert?

Michael S1. schrieb:
> Oder anderst gefragt: Was könnte folgender Code böses tun?
Der Code an sich ist nicht böse. Aber der Witz kommt dann, wenn dieses 
asynchrone Latch auf den Rest des synchronen Designs trifft...

BTW: VHDL muss nicht unbedingt geschwätzig sein.
Ich hätte das so geschrieben (und richtigerweise ist das Latch bei low 
transparent, wenn auf die steigende Flanke gespeichert wird):
1
        latched_address_o <= address_data_i when latch_enable_i='0';

von Michael S. (msb)


Lesenswert?

Im Moment des latchens passiert nichts synchrones, lediglich asynchrone 
Addressvergleicher fangen an sich einzustellen. Wenn dann die 
einsynchronisierten read oder write zu arbeiten beginnen sind Adressen 
und daraus generierte chip selects bereits lange stabil.

Ist damit die "Achse des Bösen" gebannt?

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


Lesenswert?

Michael S1. schrieb:
> die einsynchronisierten read oder write
Ja, das wird dann hoffentlich beachtet werden.

von Michael S. (msb)


Lesenswert?

Danke, ich verstehe das so: Dann hat das Lothars FPGA Papst Segen ;)

Grosses Indianerehrenwort: rd und wr  werden nur einsynchronisiert 
benutzt!

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


Lesenswert?

Michael S1. schrieb:
> Grosses Indianerehrenwort: rd und wr  werden nur einsynchronisiert
> benutzt!
Und die Adresse bleibt hoffentlich während des gesamten Zyklus stabil...

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.