Estoy siguiendo el curso From NAND to Tetris , pero en lugar de usar el software del autor, estoy tratando de programar directamente un Spartan 6 FPGA . Ahora estoy resolviendo el ejercicio ALU y terminé escribiendo el siguiente código ( descargo de responsabilidad: comencé a aprender VHDL ayer):
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity alu is
Port (x : in STD_LOGIC_VECTOR(15 downto 0);
y : in STD_LOGIC_VECTOR(15 downto 0);
zx : in STD_LOGIC;
nx : in STD_LOGIC;
zy : in STD_LOGIC;
ny : in STD_LOGIC;
f : in STD_LOGIC;
no : in STD_LOGIC;
output : out STD_LOGIC_VECTOR(15 downto 0);
zr : out STD_LOGIC;
ng : out STD_LOGIC);
constant zeros: STD_LOGIC_VECTOR(15 downto 0) := "0000000000000000";
end alu;
architecture Behavioral of alu is
begin
op: process(x, y, zx, nx, zy, ny, f, no)
variable px: STD_LOGIC_VECTOR(15 downto 0);
variable py: STD_LOGIC_VECTOR(15 downto 0);
variable po: STD_LOGIC_VECTOR(15 downto 0);
begin
px := x;
py := y;
px := zeros when (zx = '1');
px := not(px) when (nx = '1');
py := zeros when (zy = '1');
py := not(py) when (ny = '1');
if (f = '1') then
po := (px + py);
else
po := (px AND py);
end if;
po := not(po) when (no = '1');
output <= po;
if (po = zeros) then
zr <= '1';
else
zr <= '0';
end if;
ng <= po(0);
end process;
end Behavioral;
Ahora me pregunto si hay una forma más sencilla de lograr lo mismo, considerando:
(VHDL) Buenas prácticas;
Es mucho más fácil programar la reunión si haces que cada entidad sea sincrónica: dale un reloj (y reinícialo si es necesario) y escribe un proceso cronometrado. Entonces tampoco tiene que preocuparse por mantener actualizadas las listas de confidencialidad.
Tenga en cuenta esto:
use IEEE.STD_LOGIC_UNSIGNED.ALL;
No use eso, aunque se comporta mejor que std_logic_arith . Use ieee.numeric_std.all;
en su lugar y luego use los tipos apropiados para sus vectores.
Uso de variables: esa es una buena señal en mi libro. Mantiene las cosas locales muy locales.
Puede dimensionar sus variables automáticamente:
variable px : std_logic_vector(x'range);
y tu constante (que podrías trasladar a la arquitectura, que sería más convencional):
constant zeros: STD_LOGIC_VECTOR(x'range) := (others => '0');
(VHDL) Tamaño del código
No estoy seguro de que puedas guardar tanto código sin perder legibilidad.
Usar la menor lógica secuencial posible;
¿Por qué? Los flipflops son casi gratuitos en los FPGA. Casi siempre me quedo sin LUT primero.
Tamaño de síntesis
No es frecuente que el código tenga la mayor influencia en el tamaño de la síntesis. Son cosas de nivel superior como paralelo (mucha lógica) frente a secuencial (un poco de lógica a su vez, pero no olvide que la máquina de estado que lo controla puede ser una sobrecarga).