Korrekte Methode zum Definieren von Ausbreitungsverzögerungen in VHDL

Ich lerne gerade VHDL. Als Übung entschied ich mich, einige der Chips der 7400-Serie zu implementieren. Unten ist der 74153 und beim Testen mit ghdl/gtkwave scheint es zu funktionieren.

Aber ich bin mir sicher, dass diese Implementierung naiv ist (viele Wiederholungen, Verwendung von extra verzögerten (*_d) Signalen usw.). Was wäre der saubere Weg, ein solches Gerät zu implementieren?

--
-- 74153 implementation
-- Dual 4-Line to 1-Line
--

library ieee;
use ieee.std_logic_1164.all;


entity TTL_74153 is
  port(
  c0, c1, c2, c3: in std_logic_vector(1 downto 0);
  sel: in std_logic_vector(1 downto 0);
  g: in std_logic_vector(1 downto 0);
  y: out std_logic_vector(1 downto 0));
end TTL_74153;

architecture behav of TTL_74153 is
  signal c0_d, c1_d, c2_d, c3_d: std_logic_vector(1 downto 0);
  signal sel_d, g_d: std_logic_vector(1 downto 0);
begin
  -- delays
  c0_d <= c0 after 11 ns;
  c1_d <= c1 after 11 ns;
  c2_d <= c2 after 11 ns;
  c3_d <= c3 after 11 ns;
  sel_d <= sel after 20 ns;
  g_d <= g after 18 ns;

  -- logic
  y(0) <= '0' when g_d(0) = '1' else
       c0_d(0) when sel_d = "00" else
       c1_d(0) when sel_d = "01" else
       c2_d(0) when sel_d = "10" else
       c3_d(0) when sel_d = "11";

  y(1) <= '0' when g_d(0) = '1' else
       c0_d(1) when sel_d = "00" else
       c1_d(1) when sel_d = "01" else
       c2_d(1) when sel_d = "10" else
       c3_d(1) when sel_d = "11";

end behav;
Normalerweise sind Verzögerungen Eigenschaften/Einschränkungen der zugrunde liegenden Hardware. VHDL ist nicht wirklich dafür gemacht, das zu simulieren, die Entwicklungssoftware erstellt dafür ein Verzögerungsmodell, das dann während der Simulation berücksichtigt wird. In Bezug auf Ihren Code hätten Sie ein with/select für die Zuweisung basierend auf verwenden können sel_d, aber es ist in Ordnung, wie es ist.

Antworten (2)

Verzögerungen wie „wait for“ und „after“ sind nicht synthetisierbar. Das heißt, die Art und Weise, wie Sie den Eingabe- und Ausgabedatenpfad trennen, scheint seltsam. Ich würde so etwas tun:

-- -- 74153 Implementierung -- Dual 4-Line auf 1-Line --

library ieee;
use ieee.std_logic_1164.all;


entity TTL_74153 is
  port(
  c0, c1, c2, c3: in std_logic_vector(1 downto 0);
  sel: in std_logic_vector(1 downto 0);
  g: in std_logic_vector(1 downto 0);
  y: out std_logic_vector(1 downto 0));
end TTL_74153;

architecture behav of TTL_74153 is


  signal mux_out: std_logic_vector(1 downto 0);
begin
  -- logic
  -- the vector indices aren't necessary, but i prefer them
  mux_out(1 downto 0) <= c0(1 downto 0) when sel = "00" else
                         c1(1 downto 0) when sel = "01" else
                         c2(1 downto 0) when sel = "10" else
                         c3(1 downto 0) when sel = "11" else
                         "00";
 y= "00" when g(0) = '1' else mux_out;


end behav;

Mit der Funktion to_integerim ieee.numeric_stdPaket kann der Logikteil weiter reduziert werden.

Ich denke, der richtige Weg, um die Ausbreitungsverzögerung in VHDL zu modellieren, ist die Verwendung des Transportverzögerungsmodells .

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity TTL_74153 is
  port(
  c0, c1: in std_logic_vector(3 downto 0); 
  sel, g: in std_logic_vector(1 downto 0);
  y: out std_logic_vector(1 downto 0));
end TTL_74153;

architecture behav of TTL_74153 is
  signal sel_d, g_d: std_logic_vector(1 downto 0);
begin
  -- delays
  sel_d <= transport sel after 9 ns;
  g_d <= transport g after 7 ns;

  -- logic
  y <= transport (not g_d) and (c1(to_integer(unsigned(sel_d))) & c0(to_integer(unsigned(sel_d)))) after 11 ns;

end behav;
Einfache Verzögerungen (anstelle von "Transport") sind hier realitätsnäher, da die Bandbreite der Komponente begrenzt ist.