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;
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_integer
im ieee.numeric_std
Paket 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;
Svens
sel_d
, aber es ist in Ordnung, wie es ist.