Combinational Logic Design
Rules for combinational processes:
Include all read signals in the sensitivity list (or use process(all)).
Assign every output in every path (use defaults) — otherwise you infer latches.
No clock edges, no feedback loops.
12.1 Multiplexer (4:1, generic width)
entity mux4 is
generic (WIDTH : positive := 8);
port (
a, b, c, d : in std_logic_vector(WIDTH-1 downto 0);
sel : in std_logic_vector(1 downto 0);
y : out std_logic_vector(WIDTH-1 downto 0));
end entity;
architecture rtl of mux4 is
begin
with sel select
y <= a when "00", b when "01", c when "10", d when others;
end architecture;12.2 Decoder (3-to-8) and encoder
process (all)
begin
y <= (others => '0');
if en = '1' then
y(to_integer(unsigned(sel))) <= '1';
end if;
end process;
-- Priority encoder (8-to-3)
process (all)
begin
code <= "000";
valid <= '0';
for i in 0 to 7 loop -- later iterations override earlier ones → highest index wins
if req(i) = '1' then
code <= std_logic_vector(to_unsigned(i, 3));
valid <= '1';
end if;
end loop;
end process;12.3 Ripple-carry adder (structural idea) & behavioral adder
-- Behavioral (preferred — synthesis maps to fast carry chains)
sum <= std_logic_vector(resize(unsigned(a), N+1) + resize(unsigned(b), N+1) + unsigned'(0 => cin));
-- Explicit ripple-carry with a generate loop
carry(0) <= cin;
gen_fa : for i in 0 to N-1 generate
s(i) <= a(i) xor b(i) xor carry(i);
carry(i+1) <= (a(i) and b(i)) or (carry(i) and (a(i) xor b(i)));
end generate;
cout <= carry(N);12.4 ALU
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity alu is
generic (N : positive := 8);
port (
a, b : in std_logic_vector(N-1 downto 0);
op : in std_logic_vector(2 downto 0);
result : out std_logic_vector(N-1 downto 0);
zero : out std_logic;
carry : out std_logic);
end entity;
architecture rtl of alu is
begin
process (all)
variable ua, ub : unsigned(N downto 0);
variable r : unsigned(N downto 0);
begin
ua := resize(unsigned(a), N+1);
ub := resize(unsigned(b), N+1);
case op is
when "000" => r := ua + ub; -- ADD
when "001" => r := ua - ub; -- SUB
when "010" => r := ua and ub; -- AND
when "011" => r := ua or ub; -- OR
when "100" => r := ua xor ub; -- XOR
when "101" => r := '0' & not ua(N-1 downto 0); -- NOT A
when "110" => r := shift_left(ua, 1); -- SHL
when others => r := shift_right(ua, 1); -- SHR
end case;
result <= std_logic_vector(r(N-1 downto 0));
carry <= r(N);
zero <= '1' when r(
…12.5 Other combinational blocks
Comparators, barrel shifters, seven-segment decoders, binary↔BCD converters, Gray code converters (g <= b xor ('0' & b(N-1 downto 1))), population count, leading-zero counters, parity generators, multipliers.
12.6 Seven-segment decoder
process (all)
begin
case digit is -- segments "gfedcba", active low
when x"0" => seg <= "1000000";
when x"1" => seg <= "1111001";
when x"2" => seg <= "0100100";
when x"3" => seg <= "0110000";
when x"4" => seg <= "0011001";
when x"5" => seg <= "0010010";
when x"6" => seg <= "0000010";
when x"7" => seg <= "1111000";
when x"8" => seg <= "0000000";
when x"9" => seg <= "0010000";
when x"A" => seg <= "0001000";
when x"B" => seg <= "0000011";
when x"C" => seg <= "1000110";
when x"D" => seg <= "0100001";
when x"E" => seg <= "0000110";
when others => seg <= "0001110"; -- F
end case;
end process;