Sök…


Anmärkningar

D-Flip-Flops (DFF) och spärrar är minneselement. En DFF samplar sin ingång på den ena eller den andra kanten av sin klocka (inte båda) medan en spärr är transparent på en nivå av dess aktivering och memorering på den andra. Följande figur illustrerar skillnaden:

DFF vs. spärrar beteende

Det är enkelt att modellera DFF: er eller spärrar i VHDL men det är några viktiga aspekter som måste beaktas:

  • Skillnaderna mellan VHDL-modeller av DFF: er och spärrar.

  • Hur man beskriver kanterna på en signal.

  • Hur man beskriver synkron eller asynkron uppsättning eller återställning.

D-Flip-Flops (DFF)

I alla exempel:

  • clk är klockan,
  • d är ingången,
  • q är utgången,
  • srst är en aktiv hög synkron återställning,
  • srstn är en aktiv lågsynkron återställning,
  • arst är en aktiv hög asynkron återställning,
  • arstn är en aktiv låg asynkron återställning,
  • sset är en aktiv högsynkronuppsättning,
  • ssetn är en aktiv lågsynkronuppsättning,
  • aset är en aktiv hög asynkron uppsättning,
  • asetn är en aktiv låg-asynkron uppsättning

Alla signaler är av typen ieee.std_logic_1164.std_ulogic . Syntaxen som används är den som leder till korrekta syntesresultat med alla logiska synteser. Se exempel på klockkantdetektering för en diskussion om alternativ syntax.

Stigande klocka

process(clk)
begin
  if rising_edge(clk) then
    q <= d;
  end if;
end process;

Fallande kantklocka

process(clk)
begin
  if falling_edge(clk) then
    q <= d;
  end if;
end process;

Stigande klocka, synkron aktiv hög återställning

process(clk)
begin
  if rising_edge(clk) then
    if srst = '1' then
      q <= '0';
    else
      q <= d;
    end if;
  end if;
end process;

Stigande klocka, asynkron aktiv hög återställning

process(clk, arst)
begin
  if arst = '1' then
    q <= '0';
  elsif rising_edge(clk) then
    q <= d;
  end if;
end process;

Fallande kantklocka, asynkron aktiv låg återställning, synkron aktiv höguppsättning

process(clk, arstn)
begin
  if arstn = '0' then
    q <= '0';
  elsif falling_edge(clk) then
    if sset = '1' then
      q <= '1';
    else
      q <= d;
    end if;
  end if;
end process;

Stigande klocka, asynkron aktiv hög återställning, asynkron aktiv låg inställning

Obs: set har högre prioritet än återställning

process(clk, arst, asetn)
begin
  if asetn = '0' then
    q <= '1';
  elsif arst = '1' then
    q <= '0';
  elsif rising_edge(clk) then
    q <= d;
  end if;
end process;

Latches

I alla exempel:

  • en är aktiveringssignalen,
  • d är ingången,
  • q är utgången,
  • srst är en aktiv hög synkron återställning,
  • srstn är en aktiv lågsynkron återställning,
  • arst är en aktiv hög asynkron återställning,
  • arstn är en aktiv låg asynkron återställning,
  • sset är en aktiv högsynkronuppsättning,
  • ssetn är en aktiv lågsynkronuppsättning,
  • aset är en aktiv hög asynkron uppsättning,
  • asetn är en aktiv låg-asynkron uppsättning

Alla signaler är av typen ieee.std_logic_1164.std_ulogic . Syntaxen som används är den som leder till korrekta syntesresultat med alla logiska synteser. Se exempel på klockkantdetektering för en diskussion om alternativ syntax.

Aktiv hög aktivering

process(en, d)
begin
  if en = '1' then
    q <= d;
  end if;
end process;

Aktiv låg aktivering

process(en, d)
begin
  if en = '0' then
    q <= d;
  end if;
end process;

Aktiv hög aktivering, synkron aktiv hög återställning

process(en, d)
begin
  if en = '1' then
    if srst = '1' then
      q <= '0';
    else
      q <= d;
    end if;
  end if;
end process;

Aktiv hög aktivering, asynkron aktiv hög återställning

process(en, d, arst)
begin
  if arst = '1' then
    q <= '0';
  elsif en = '1' then
    q <= d;
  end if;
end process;

Aktiv låg aktivering, asynkron aktiv låg återställning, synkron aktiv hög uppsättning

process(en, d, arstn)
begin
  if arstn = '0' then
    q <= '0';
  elsif en = '0' then
    if sset = '1' then
      q <= '1';
    else
      q <= d;
    end if;
  end if;
end process;

Aktiv hög aktivering, asynkron aktiv hög återställning, asynkron aktiv låg inställning

Obs: set har högre prioritet än återställning

process(en, d, arst, asetn)
begin
  if asetn = '0' then
    q <= '1';
  elsif arst = '1' then
    q <= '0';
  elsif en = '1' then
    q <= d;
  end if;
end process;

Klockkantdetektering

Den korta historien

Med VHDL 2008 och om klocktypen är bit , boolean , ieee.std_logic_1164.std_ulogic eller ieee.std_logic_1164.std_logic , kan en ieee.std_logic_1164.std_logic kodas för stigande kant

  • if rising_edge(clock) then
  • if clock'event and clock = '1' then -- type bit, std_ulogic or std_logic
  • if clock'event and clock then -- type boolean

och för fallande kant

  • if falling_edge(clock) then
  • if clock'event and clock = '0' then -- type bit, std_ulogic or std_logic
  • if clock'event and not clock then -- type boolean

Detta kommer att bete sig som förväntat, både för simulering och syntes.

Obs: definitionen av en stigande kant på en signal av typen std_ulogic är lite mer komplex än den enkla if clock'event and clock = '1' then . Standarden rising_edge funktion, till exempel, har en annan definition. Även om det förmodligen inte kommer att göra någon skillnad för syntesen, kan det göra en för simulering.

Användning av rising_edge och falling_edge uppmuntras starkt. Med tidigare versioner av VHDL användningen av dessa funktioner kan kräva att uttryckligen förklara användningen av standardpaket (t.ex. ieee.numeric_bit för typ bit ) eller till och med att definiera dem i en anpassad paket.

Obs: rising_edge falling_edge standardfunktionerna rising_edge och falling_edge för att upptäcka kanter på icke-klocksignaler. Vissa synthesizers kan dra slutsatsen att signalen är en klocka. Tips: detektering av en kant på en icke-klocksignal kan ofta göras genom att sampla in signalen i ett skiftregister och jämföra samplade värden i olika steg i skiftregistret.

Den långa berättelsen

Att korrekt beskriva detekteringen av kanterna på en klocksignal är avgörande vid modellering av D-Flip-Flops (DFF). En kant är per definition en övergång från ett visst värde till ett annat. Till exempel kan vi definiera stigningen på en signal av bit (den standardiserade VHDL-typen som tar två värden: '0' och '1' ) som övergången från '0' till '1' . För typ boolean vi definiera det som en övergång från false till true .

Ofta används mer komplexa typer. ieee.std_logic_1164.std_ulogic är till exempel också en uppräknad typ, precis som bit eller boolean , men har 9 värden istället för 2:

Värde Menande
'U' oinitierad
'X' Tvinga okänt
'0' Tvinga låg nivå
'1' Tvinga hög nivå
'Z' Hög impedans
'W' Svag okänd
'L' Svag låg nivå
'H' Svag hög nivå
'-' Bryr sig inte

Att definiera en stigande kant på en sådan typ är lite mer komplex än för bit eller boolean . Vi kan till exempel bestämma att det är en övergång från '0' till '1' . Men vi kan också bestämma att det är en övergång från '0' eller 'L' till '1' eller 'H' .

Obs: det är denna andra definition som standarden använder för den rising_edge(signal s: std_ulogic) -funktionen definierad i ieee.std_logic_1164 .

När man diskuterar olika sätt att upptäcka kanter är det alltså viktigt att beakta signalens typ. Det är också viktigt att ta hänsyn till modelleringsmålet: endast simulering eller logisk syntes? Låt oss illustrera detta med några exempel:

Rising edge DFF med typbit

signal clock, d, q: bit;
...
P1: process(clock)
begin
  if clock = '1' then
    q <= d;
  end if;
end process P1;

Tekniskt sett, på ren simuleringssemantik synvinkel, process P1 modellerar en stigande kant utlöst DFF. Faktum är att q <= d tilldelningen utförs om och bara om:

  • clock ändrats (detta är vad känslighetslistan uttrycker) och
  • clock nuvarande värde är '1' .

Eftersom clock är av typbit och typbit har bara värden '0' och '1' , är det exakt vad vi definierade som en stigande kant av en signal av typbit. Varje simulator hanterar den här modellen som vi förväntar oss.

Obs: För logiska synthesizers är sakerna lite mer komplexa, som vi kommer att se senare.

Rising edge DFF med asynkron aktiv hög återställning och typbit

För att lägga till en asynkron aktiv hög återställning till vår DFF kan man prova något som:

signal clock, reset, d, q: bit;
...
P2_BOGUS: process(clock, reset)
begin
  if reset = '1' then
    q <= '0';
  elsif clock = '1' then
    q <= d;
  end if;
end process P2_BOGUS;

Men detta fungerar inte . Villkoret för att q <= d tilldelningen ska utföras ska vara: en stigande clock medan reset = '0' . Men det vi modellerade är:

  • clock eller reset eller båda ändrade och
  • reset = '0' och
  • clock = '1'

Vilket är inte detsamma: om reset ändras från '1' till '0' medan clock = '1' kommer tilldelningen att utföras medan det inte är en stigande clock .

Det finns faktiskt inget sätt att modellera detta i VHDL utan hjälp av ett signalattribut:

P2_OK: process(clock, reset)
begin
  if reset = '1' then
    q <= '0';
  elsif clock = '1' and clock'event then
    q <= d;
  end if;
end process P2_OK;

Den clock'event är signalattribut event tillämpas på clock . Det utvärderas som en boolean och det är true om och endast om clock ändras under signaluppdateringsfasen som bara föregick den nuvarande genomförandefasen. Tack vare detta P2_OK process P2_OK nu perfekt vad vi vill ha i simulering (och syntes).

Syntesemantik

Många logiska syntetisatorer identifierar signalkantsdetekteringar baserade på syntaktiska mönster, inte på semantiken i VHDL-modellen. Med andra ord överväger de hur VHDL-koden ser ut, inte vilket beteende den modellerar. Ett av mönstren som de alla känner igen är:

if clock = '1' and clock'event then

Så även i exemplet med process P1 bör vi använda den om vi vill att vår modell ska syntetiseras av alla logiska synteser:

signal clock, d, q: bit;
...
P1_OK: process(clock)
begin
  if clock = '1' and clock'event then
    q <= d;
  end if;
end process P1_OK;

Den and clock'event delen av tillståndet är helt överflödigt med känslighetslistan men eftersom vissa synthesizers behöver det ...

Rising edge DFF med asynkron aktiv hög återställning och typ std_ulogic

I detta fall kan det bli komplicerat att uttrycka klockans stigande kant och återställningstillståndet. Om vi behåller definitionen av en stigande kant som vi föreslog ovan och om vi anser att återställningen är aktiv om den är '1' eller 'H' blir modellen:

library ieee;
use ieee.std_logic_1164.all;
...
signal clock, reset, d, q: std_ulogic;
...
P4: process(clock, reset)
begin
  if reset = '1' or reset = 'H' then
    q <= '0';
  elsif clock'event and
        (clock'last_value = '0' or clock'last_value = 'L') and
        (clock = '1' or clock = 'H') then
    q <= d;
  end if;
end process P4;

Obs: 'last_value är ett annat 'last_value som returnerar värdet som signalen hade innan den senaste värdeförändringen.

Hjälparfunktioner

VHDL 2008-standarden erbjuder flera hjälpfunktioner för att förenkla upptäckten av signalkanter, särskilt med flera värderade uppräknade typer som std_ulogic . std.standard paketet definierar rising_edge och falling_edge på typer bit och boolean och paketet ieee.std_logic_1164 definierar dem på typerna std_ulogic och std_logic .

Obs: med tidigare versioner av VHDL kan användningen av dessa funktioner kräva att de uttryckligen förklarar användningen av standardpaket (t.ex. ieee.numeric_bit för typbit) eller till och med för att definiera dem i ett användarpaket.

Låt oss gå igenom de tidigare exemplen och använda hjälpfunktionerna:

signal clock, d, q: bit;
...
P1_OK_NEW: process(clock)
begin
  if rising_edge(clock) then
    q <= d;
  end if;
end process P1_OK_NEW;
signal clock, d, q: bit;
...
P2_OK_NEW: process(clock, reset)
begin
  if reset = '1' then
    q <= '0';
  elsif rising_edge(clock) then
    q <= d;
  end if;
end process P2_OK_NEW;
library ieee;
use ieee.std_logic_1164.all;
...
signal clock, reset, d, q: std_ulogic;
...
P4_NEW: process(clock, reset)
begin
  if reset = '1' then
    q <= '0';
  elsif rising_edge(clock) then
    q <= d;
  end if;
end process P4_NEW;

Obs! I detta sista exempel förenklar vi också testet på återställningen. Flytande, hög impedans, återställningar är ganska sällsynta och i de flesta fall fungerar denna förenklade version för simulering och syntes.



Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow