Forma correcta de definir los retrasos de propagación en VHDL

Actualmente estoy aprendiendo VHDL. Como ejercicio decidí implementar algunos de los chips de la serie 7400. A continuación se muestra el 74153 y, al probarlo con ghdl/gtkwave, parece funcionar.

Pero estoy seguro de que esta implementación es ingenua (muchas repeticiones, uso de señales extra retrasadas (*_d), etc.). ¿Cuál sería la forma limpia de implementar dicho dispositivo?

--
-- 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;
Por lo general, los retrasos son propiedades/limitaciones del hardware subyacente. VHDL no está realmente hecho para simular eso, el software de desarrollo crea un modelo de retraso para él, que luego se tiene en cuenta durante la simulación. Con respecto a su código, podría haber usado un with/select para la asignación basada en sel_d, pero está bien como está.

Respuestas (2)

Los retrasos como "esperar" y "después" no son sintetizables. Dicho esto, la forma en que separas la ruta de datos de entrada y salida parece extraña. Yo haría algo como esto:

-- -- Implementación 74153 -- Dual de 4 líneas a 1 línea --

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;

Usando la función to_integeren ieee.numeric_stdel paquete, la parte lógica se puede reducir aún más.

Creo que la forma correcta de modelar el retraso de propagación en VHDL es usando el modelo de retraso de transporte .

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;
Los retrasos simples (en lugar de "transporte") están aquí más cerca de la realidad porque el ancho de banda del componente es limitado.