-- EXAMPLE: VHDL CODE FOR MUX2:1 
-- WITH CONDITIONAL SIGNAL ASSIGNMENT STATEMENTS ——————————————————————— 

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity mux2to1 is
    Port (
        a   : in  STD_LOGIC;
        b   : in  STD_LOGIC;
        sel : in  STD_LOGIC;
        y   : out STD_LOGIC
    );
end mux2to1;

architecture mux2to1_arch of mux2to1 is
begin
	-- conditional signal assignment statement	
    y <= a when sel = '0' else
         b when sel = '1' else
         '0';
        
        -- this way of writing the MUX2:1 lists all possible conditions of SEL
        	-- it is recommended to provide all the options in a conditional signal assignment statement	
            -- '0' is a catch-all statement
            	-- if none of the previous conditions is evaluated as true, then this statement is executed
        
        -- the conditional signal assignment statement could have been written as 
        	-- y <= a when sel = '0' else b; 
        	-- where else b is a catch-all statement
        	-- this is a catch-all statement for intented signal assignment
        
        -- when using the relational operator =, single quotes are used to describe values associated with one-bit signals, as SEL in this example

end mux2to1_arch;

-- EXAMPLE: TEST BENCH FOR MUX2:1 ——————————————————————— 

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity tb_mux2to1 is
end tb_mux2to1;

architecture test_mux2to1 of tb_mux2to1 is

    -- Component declaration for the DUT
    component mux2to1
        Port (
            a   : in  STD_LOGIC;
            b   : in  STD_LOGIC;
            sel : in  STD_LOGIC;
            y   : out STD_LOGIC
        );
    end component;

    -- Testbench signals declaration
    signal a_tb   : STD_LOGIC := '0';
    signal b_tb   : STD_LOGIC := '0';
    signal sel_tb : STD_LOGIC := '0';
    signal y_tb   : STD_LOGIC;

begin

    -- Instantiate the DUT
    dut: mux2to1
        port map(
            a   => a_tb,
            b   => b_tb,
            sel => sel_tb,
            y   => y_tb
        );

    -- Stimulus process
    stim_proc: process
    begin

        -- Test 1: sel=0 -> output should follow a
        a_tb <= '0'; b_tb <= '1'; sel_tb <= '0';
        wait for 10 ns;
        assert (y_tb = a_tb)
        report "Test 1 Error: sel=0 but y differs from a"
        severity error;

        -- Test 2: sel=1 -> output should follow b
        a_tb <= '0'; b_tb <= '1'; sel_tb <= '1';
        wait for 10 ns;
        assert (y_tb = b_tb)
        report "Test 2 Error: sel=1 but y differs from b"
        severity error;

        -- Test 3: sel=0 -> output should follow a
        a_tb <= '1'; b_tb <= '0'; sel_tb <= '0';
        wait for 10 ns;
        assert (y_tb = a_tb)
        report "Test 3 Error: sel=0 but y differs from a"
        severity error;

        -- Test 4: sel=1 -> output should follow b
        a_tb <= '1'; b_tb <= '0'; sel_tb <= '1';
        wait for 10 ns;
        assert (y_tb = b_tb)
        report "Test 4 Error: sel=1 but y differs from b"
        severity error;

        -- Simulation complete
        assert false
        report "Simulation completed successfully"
        severity note;

        wait;  -- stop process

    end process;

end test_mux2to1;