Improve my “From NAND to Tetris” ALU in VHDL
(VHDL) Good practices;


It's a lot easier meeting timing if you make each entity synchronous - give it a clock (and reset if necessary) and write a clocked process.  You then also don't have to worry about keeping sensitivity lists up to date.

Note this:

use IEEE.STD_LOGIC_UNSIGNED.ALL;


Don't use that - although it's better behaved than std_logic_arith.  Use ieee.numeric_std.all; instead and then use the appropriate types for your vectors.

Use of variables - that's a good sign in my book.  Keeps local things very local.

You could size your variables automatically:

variable px : std_logic_vector(x'range);


and your constant (which you could move to the architecture, which would be more conventional):

constant zeros: STD_LOGIC_VECTOR(x'range) := (others =&gt; '0');



  (VHDL) Code size


I'm not sure you could save that much code without losing readability


  Using as little sequential logic as possible;


Why?  Flipflops are almost free in FPGAs.  I almost always run out of LUTs first.


  Synthesis size


It's not often that the code has the biggest influence on synthesis size.  It's higher level things like parallel (lots of logic) vs. sequential (a little logic in turn - but don't forget the state machine controlling it can be an overhead).