I'm following the course From NAND to Tetris, but instead of using the author's software, I'm trying to directly program a Spartan 6 FPGA. I'm now solving the ALU exercise, and ended up writing the following code (disclaimer: I started learning VHDL yesterday):
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;
I'm now wondering if there is a simpler way to achieve the same thing, considering:
- (VHDL) Good practices;
- (VHDL) Code size;
- Using as little sequential logic as possible;
- Synthesis size.