-------------------------------------------------------------------------------
-- Title      : cpu 2bit top-level
-- Project    : cpu 2bit
-------------------------------------------------------------------------------
-- File       : cpu_2bit_top_level.vhd
-- Author     : 
-- Company    : TU-Chemnitz
-- Created    : 
-- Last update: 2002/04/11
-- Platform   : ANY
-------------------------------------------------------------------------------
-- Description: default 
-------------------------------------------------------------------------------

-------------------------------------------------------------------------------
-- Entity ip_counter
-------------------------------------------------------------------------------
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_unsigned.ALL;

ENTITY ip_counter IS

  PORT (
    clk    : IN  STD_LOGIC;
    reset  : IN  STD_LOGIC;
    step   : IN  STD_LOGIC;
    ip_ld  : IN  STD_LOGIC;
    ip_cnt : IN  STD_LOGIC;
    ip_in  : IN  STD_LOGIC_VECTOR(1 DOWNTO 0);
    ip_out : OUT STD_LOGIC_VECTOR(1 DOWNTO 0));

END ip_counter;

ARCHITECTURE A_behav OF ip_counter IS

  --
  -- Hier sind von Ihnen Ergänzungen zu machen.
  --
	signal ip: std_logic_vector(1 downto 0);

begin
P_ip:	process(clk, reset)
		begin
			if reset = '0' then
				ip <= (others => '0');
			elsif clk'event and clk = '1' then
				if step = '1' then
					if ip_ld = '1' then
						ip <= ip_in;
					elsif ip_cnt = '1' then
						ip <= ip + 1;
					end if;
				end if;
			end if;
		end process P_ip;

ip_out <= ip;

END A_behav;

-------------------------------------------------------------------------------
-- Entity register_2bit
-------------------------------------------------------------------------------
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_unsigned.ALL;

ENTITY register_2bit IS

  PORT (
    clk     : IN  STD_LOGIC;
    reset   : IN  STD_LOGIC;
    step    : IN  STD_LOGIC;
    reg_en  : IN  STD_LOGIC;
    reg_in  : IN  STD_LOGIC_VECTOR(1 DOWNTO 0);
    reg_out : OUT STD_LOGIC_VECTOR(1 DOWNTO 0));

END register_2bit;

ARCHITECTURE A_behav OF register_2bit IS

  --
  -- Hier sind von Ihnen Ergänzungen zu machen.
  --
	signal reg : std_logic_vector(1 downto 0);
begin
P_reg:	process(clk, reset)
		begin
			if reset = '0' then
				reg <= (others => '0');
			elsif clk'event and clk = '1' then
				if step = '1' then
					if reg_en = '1' then
						reg <= reg_in;
					end if;
				end if;
			end if;
		end process P_reg;

reg_out <= reg;

END A_behav;

-------------------------------------------------------------------------------
-- Entity mux
-------------------------------------------------------------------------------
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_unsigned.ALL;

ENTITY mux IS

  PORT (
    sel : IN  STD_LOGIC;
    a   : IN  STD_LOGIC_VECTOR(1 DOWNTO 0);
    b   : IN  STD_LOGIC_VECTOR(1 DOWNTO 0);
    y   : OUT STD_LOGIC_VECTOR(1 DOWNTO 0));

END mux;

ARCHITECTURE A_behav OF mux IS

  --
  -- Hier sind von Ihnen Ergänzungen zu machen.
  --
begin

	y <= a when sel = '0' else b;

END A_behav;

-------------------------------------------------------------------------------
-- entity alu
-------------------------------------------------------------------------------
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_unsigned.ALL;

ENTITY alu IS

  PORT (
    a : IN  STD_LOGIC_VECTOR(1 DOWNTO 0);
    b : IN  STD_LOGIC_VECTOR(1 DOWNTO 0);
    y : OUT STD_LOGIC_VECTOR(1 DOWNTO 0));

END alu;

ARCHITECTURE A_behav OF alu IS

  --
  -- Hier sind von Ihnen Ergänzungen zu machen.
  --
begin

y <= a + b;

END A_behav;


-------------------------------------------------------------------------------
-- entity steuerwerk
-------------------------------------------------------------------------------
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_unsigned.ALL;

ENTITY steuerwerk IS

  PORT (
    clk    : IN  STD_LOGIC;
    reset  : IN  STD_LOGIC;
    step   : IN  STD_LOGIC;
    br     : IN  STD_LOGIC_VECTOR(1 DOWNTO 0);
    state  : OUT STD_LOGIC_VECTOR(2 DOWNTO 0);
    br_en  : OUT STD_LOGIC;
    ar_en  : OUT STD_LOGIC;
    aa_en  : OUT STD_LOGIC;
    ip_ld  : OUT STD_LOGIC;
    ip_cnt : OUT STD_LOGIC;
    rd     : OUT STD_LOGIC;
    wr     : OUT STD_LOGIC;
    m1_s   : OUT STD_LOGIC;
    m2_s   : OUT STD_LOGIC;
    m3_s   : OUT STD_LOGIC;
    m4_s   : OUT STD_LOGIC);

END steuerwerk;

ARCHITECTURE A_behav OF steuerwerk IS

  --
  -- Hier sind von Ihnen Ergänzungen zu machen.
  --
	signal f		: std_logic_vector(3 downto 1);
	signal modres	: std_logic;

begin
	state <= f;

P_counter:	process(clk, reset)
			begin
				if reset = '0' then
					f <= "001";
				elsif clk'event and clk = '1' then
					if step = '1' then
						if modres = '1' then
							f <= "001";
						else
							f <= f(2 downto 1) & f(3);
						end if;
					end if;
				end if;
END process;

br_en	<= f(1);
ar_en	<= ((f(2) and not br(1) and br(0)) or (f(2) and br(1) and not br(0))
		or (f(2) and not br(1) and not br(0)));
aa_en	<= ((f(2) and br(1) and br(0)) or (f(3) and not br(1) and br(0)));
ip_ld	<= (f(3) and not br(1) and not br(0));
ip_cnt	<= (f(1) or (f(2) and not br(1) and br(0)) or (f(2) and br(1) and not br(0))
		or (f(2) and not br(1) and not br(0)));
rd		<= (f(1) or f(2) or (f(3) and not br(1) and br(0)));
wr		<= ((f(3) and br(1) and not br(0)) and not clk and step);
modres	<= (f(2) and br(1) and br(0));
m1_s	<= f(3);
m2_s	<= f(3);
m3_s	<= f(3);
m4_s	<= f(3);

end A_behav;

-------------------------------------------------------------------------------
-- CPU-2 Top Level
-------------------------------------------------------------------------------
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_arith.ALL;
USE ieee.std_logic_unsigned.ALL;

ENTITY cpu_2bit IS

  PORT (
    clk      : IN  STD_LOGIC;
    reset    : IN  STD_LOGIC;
    step     : IN  STD_LOGIC;
    rd       : OUT STD_LOGIC;
    wr       : OUT STD_LOGIC;
    addr     : OUT STD_LOGIC_VECTOR(1 DOWNTO 0);
    state    : OUT STD_LOGIC_VECTOR(2 DOWNTO 0);
    ar_out   : OUT STD_LOGIC_VECTOR(1 DOWNTO 0);
    br_out   : OUT STD_LOGIC_VECTOR(1 DOWNTO 0);
    ip_out   : OUT STD_LOGIC_VECTOR(1 DOWNTO 0);
    aa_out   : OUT STD_LOGIC_VECTOR(1 DOWNTO 0);
    bb_out   : OUT STD_LOGIC_VECTOR(1 DOWNTO 0);
    data_in  : IN  STD_LOGIC_VECTOR(1 DOWNTO 0);
    data_out : OUT STD_LOGIC_VECTOR(1 DOWNTO 0));

END cpu_2bit;

ARCHITECTURE A_structure OF cpu_2bit IS

  --
  -- Hier sind von Ihnen Ergänzungen zu machen.
  --
	signal ar		: std_logic_vector(1 downto 0);
	signal br		: std_logic_vector(1 downto 0);
	signal ip		: std_logic_vector(1 downto 0);
	signal aa_in	: std_logic_vector(1 downto 0);
	signal aa		: std_logic_vector(1 downto 0);
	signal alu_out	: std_logic_vector(1 downto 0);
	signal bb		: std_logic_vector(1 downto 0);
	signal alu_in1	: std_logic_vector(1 downto 0);
	signal alu_in2	: std_logic_vector(1 downto 0);
	
	signal ip_cnt	: std_logic;
	signal ip_ld	: std_logic;
	signal ar_en	: std_logic;
	signal br_en	: std_logic;
	signal aa_en	: std_logic;
	signal rd_en	: std_logic;
	signal wr_en	: std_logic;
	signal m1_s		: std_logic;
	signal m2_s		: std_logic;
	signal m3_s		: std_logic;
	signal m4_s		: std_logic;

component ip_counter
  PORT (
    clk    : IN  STD_LOGIC;
    reset  : IN  STD_LOGIC;
    step   : IN  STD_LOGIC;
    ip_ld  : IN  STD_LOGIC;
    ip_cnt : IN  STD_LOGIC;
    ip_in  : IN  STD_LOGIC_VECTOR(1 DOWNTO 0);
    ip_out : OUT STD_LOGIC_VECTOR(1 DOWNTO 0));
end component;

component register_2bit
  PORT (
    clk     : IN  STD_LOGIC;
    reset   : IN  STD_LOGIC;
    step    : IN  STD_LOGIC;
    reg_en  : IN  STD_LOGIC;
    reg_in  : IN  STD_LOGIC_VECTOR(1 DOWNTO 0);
    reg_out : OUT STD_LOGIC_VECTOR(1 DOWNTO 0));
end component;

component mux
  PORT (
    sel : IN  STD_LOGIC;
    a   : IN  STD_LOGIC_VECTOR(1 DOWNTO 0);
    b   : IN  STD_LOGIC_VECTOR(1 DOWNTO 0);
    y   : OUT STD_LOGIC_VECTOR(1 DOWNTO 0));
end component;

component alu
  PORT (
    a : IN  STD_LOGIC_VECTOR(1 DOWNTO 0);
    b : IN  STD_LOGIC_VECTOR(1 DOWNTO 0);
    y : OUT STD_LOGIC_VECTOR(1 DOWNTO 0));
end component;

component steuerwerk
  PORT (
    clk    : IN  STD_LOGIC;
    reset  : IN  STD_LOGIC;
    step   : IN  STD_LOGIC;
    br     : IN  STD_LOGIC_VECTOR(1 DOWNTO 0);
    state  : OUT STD_LOGIC_VECTOR(2 DOWNTO 0);
    br_en  : OUT STD_LOGIC;
    ar_en  : OUT STD_LOGIC;
    aa_en  : OUT STD_LOGIC;
    ip_ld  : OUT STD_LOGIC;
    ip_cnt : OUT STD_LOGIC;
    rd     : OUT STD_LOGIC;
    wr     : OUT STD_LOGIC;
    m1_s   : OUT STD_LOGIC;
    m2_s   : OUT STD_LOGIC;
    m3_s   : OUT STD_LOGIC;
    m4_s   : OUT STD_LOGIC);
end component;

begin

	ar_out		<= ar;
	br_out		<= br;
	ip_out		<= ip;
	aa_out		<= aa;
	bb_out		<= bb;
	data_out	<= aa;

IP1	: ip_counter
	port map (
		clk		=> clk,
		reset	=> reset,
		step	=> step,
		ip_ld	=> ip_ld,
		ip_cnt	=> ip_cnt,
		ip_in	=> alu_out,
		ip_out	=> ip);

BR1	: register_2bit
	port map (
		clk		=> clk,
		reset	=> reset,
		step	=> step,
		reg_en	=> br_en,
		reg_in	=> data_in,
		reg_out	=> br);

AR1	: register_2bit
	port map (
		clk		=> clk,
		reset	=> reset,
		step	=> step,
		reg_en	=> ar_en,
		reg_in	=> data_in,
		reg_out	=> ar);

AA1	: register_2bit
	port map (
		clk		=> clk,
		reset	=> reset,
		step	=> step,
		reg_en	=> aa_en,
		reg_in	=> aa_in,
		reg_out	=> aa);

M1	: mux
	port map (
		sel	=> m1_s,
		a	=> ip,
		b	=> ar,
		y	=> addr);

M2	: mux
	port map (
		sel	=> m2_s,
		a	=> alu_out,
		b	=> data_in,
		y	=> aa_in);

M3	: mux
	port map (
		sel	=> m3_s,
		a	=> aa,
		b	=> ar,
		y	=> alu_in1);

bb <= "01";

M4	: mux
	port map (
		sel	=> m4_s,
		a	=> bb,
		b	=> ip,
		y	=> alu_in2);

ALU1: alu
	port map (
		a	=> alu_in1,
		b	=> alu_in2,
		y	=> alu_out);

SW1	: steuerwerk
	port map (
		clk		=> clk,
		reset	=> reset,
		step	=> step,
		br		=> br,
		state	=> state,
		br_en	=> br_en,
		ar_en	=> ar_en,
		aa_en	=> aa_en,
		ip_ld	=> ip_ld,
		ip_cnt	=> ip_cnt,
		rd		=> rd,
		wr		=> wr,
		m1_s	=> m1_s,
		m2_s	=> m2_s,
		m3_s	=> m3_s,
		m4_s	=> m4_s);

END A_structure;


-------------------------------------------------------------------------------
-- Hier folgen die zum Test der CPU notwendigen Module. Diese sind bereits
-- vollständig implementiert und sollten daher nicht verändert werden.
-------------------------------------------------------------------------------

-------------------------------------------------------------------------------
-- memory
-------------------------------------------------------------------------------
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_arith.ALL;
USE ieee.std_logic_unsigned.ALL;

ENTITY memory IS

  PORT (
    clk          : IN  STD_LOGIC;
    addr         : IN  STD_LOGIC_VECTOR(1 DOWNTO 0);
    data_in      : IN  STD_LOGIC_VECTOR(1 DOWNTO 0);
    data_out     : OUT STD_LOGIC_VECTOR(1 DOWNTO 0);
    preset_data  : IN  STD_LOGIC_VECTOR(7 DOWNTO 0);
    data_display : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
    preset       : IN  STD_LOGIC;
    rd           : IN  STD_LOGIC;
    wr           : IN  STD_LOGIC);
END memory;

ARCHITECTURE A_behav OF memory IS
  TYPE mem_type IS ARRAY (0 TO 3) OF STD_LOGIC_VECTOR(1 DOWNTO 0);

  SIGNAL memory_array : mem_type;

BEGIN
  P_memory : PROCESS (clk, preset)
  BEGIN
    IF preset = '0' THEN
      memory_array(0)                    <= preset_data(1 DOWNTO 0);
      memory_array(1)                    <= preset_data(3 DOWNTO 2);
      memory_array(2)                    <= preset_data(5 DOWNTO 4);
      memory_array(3)                    <= preset_data(7 DOWNTO 6);
    ELSIF clk'EVENT AND clk = '1' THEN
      IF wr = '1' THEN
        memory_array(conv_integer(addr)) <= data_in;
      END IF;
    END IF;
  END PROCESS P_memory;

  data_out <= memory_array(conv_integer(addr));

  data_display(1 DOWNTO 0) <= memory_array(0);
  data_display(3 DOWNTO 2) <= memory_array(1);
  data_display(5 DOWNTO 4) <= memory_array(2);
  data_display(7 DOWNTO 6) <= memory_array(3);

END A_behav;

-------------------------------------------------------------------------------
-- single step state maschine
-------------------------------------------------------------------------------
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_arith.ALL;
USE ieee.std_logic_unsigned.ALL;

ENTITY single_step IS
  PORT (
    clk    : IN  STD_LOGIC;
    reset  : IN  STD_LOGIC;
    button : IN  STD_LOGIC;
    step   : OUT STD_LOGIC);

END single_step;

ARCHITECTURE A_behav OF single_step IS

  CONSTANT DELAY : NATURAL RANGE 0 TO 131071 := 131071;

  TYPE states IS (high, low, step_out, cnt_reset);
  SIGNAL current_state : states;
  SIGNAL next_state    : states;
  SIGNAL counter       : INTEGER RANGE 0 TO 131071;
  SIGNAL timeout       : STD_LOGIC;
  SIGNAL cnt_clear     : STD_LOGIC;
  SIGNAL cnt_count     : STD_LOGIC;

BEGIN
  P_step_state : PROCESS (clk, reset)
  BEGIN
    IF reset = '0' THEN
      current_state <= high;
    ELSIF clk'EVENT AND clk = '1' THEN
      current_state <= next_state;
    END IF;
  END PROCESS P_step_state;

  P_step_trans_out : PROCESS (button, current_state, timeout)
  BEGIN
    CASE current_state IS
      WHEN high      =>
        IF timeout = '1' AND button = '0' THEN
          next_state <= cnt_reset;
        ELSE
          next_state <= high;
        END IF;
      WHEN low       =>
        IF timeout = '1' AND button = '1' THEN
          next_state <= step_out;
        ELSE
          next_state <= low;
        END IF;
      WHEN step_out  =>
        next_state   <= high;
      WHEN cnt_reset =>
        next_state   <= low;
      WHEN OTHERS    => NULL;
    END CASE;
  END PROCESS P_step_trans_out;

  step      <= '1' WHEN current_state = step_out                                  ELSE '0';
  cnt_clear <= '1' WHEN (current_state = step_out) OR (current_state = cnt_reset) ELSE '0';
  cnt_count <= '1' WHEN (current_state = high) OR (current_state = low)           ELSE '0';

  P_timeout : PROCESS (clk, reset)
  BEGIN
    IF reset = '0' THEN
      counter     <= 0;
    ELSIF clk'EVENT AND clk = '1' THEN
      IF cnt_clear = '1' THEN
        counter   <= 0;
      ELSIF cnt_count = '1' THEN
        IF counter < delay THEN
          counter <= counter + 1;
        END IF;
      END IF;
    END IF;
  END PROCESS P_timeout;

  timeout <= '1' WHEN counter = DELAY ELSE '0';

END A_behav;

-------------------------------------------------------------------------------
-- top_level_entity
-------------------------------------------------------------------------------
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_arith.ALL;
USE ieee.std_logic_unsigned.ALL;

ENTITY cpu_2bit_top_level IS

  PORT (
    clk            : IN  STD_LOGIC;
    flex_pb1       : IN  STD_LOGIC;
    flex_pb2       : IN  STD_LOGIC;
    flex_switch_1  : IN  STD_LOGIC;
    flex_switch_2  : IN  STD_LOGIC;
    flex_switch_3  : IN  STD_LOGIC;
    flex_switch_4  : IN  STD_LOGIC;
    flex_switch_5  : IN  STD_LOGIC;
    flex_switch_6  : IN  STD_LOGIC;
    flex_switch_7  : IN  STD_LOGIC;
    flex_switch_8  : IN  STD_LOGIC;
    flex_d1        : OUT STD_LOGIC;
    flex_d2        : OUT STD_LOGIC;
    flex_d3        : OUT STD_LOGIC;
    flex_d4        : OUT STD_LOGIC;
    flex_d5        : OUT STD_LOGIC;
    flex_d6        : OUT STD_LOGIC;
    flex_d7        : OUT STD_LOGIC;
    flex_d8        : OUT STD_LOGIC;
    flex_d9        : OUT STD_LOGIC;
    flex_d10       : OUT STD_LOGIC;
    flex_d11       : OUT STD_LOGIC;
    flex_d12       : OUT STD_LOGIC;
    flex_d13       : OUT STD_LOGIC;
    flex_d14       : OUT STD_LOGIC;
    flex_d15       : OUT STD_LOGIC;
    flex_d16       : OUT STD_LOGIC;
    flex_digit1_a  : OUT STD_LOGIC;
    flex_digit1_b  : OUT STD_LOGIC;
    flex_digit1_c  : OUT STD_LOGIC;
    flex_digit1_d  : OUT STD_LOGIC;
    flex_digit1_e  : OUT STD_LOGIC;
    flex_digit1_f  : OUT STD_LOGIC;
    flex_digit1_g  : OUT STD_LOGIC;
    flex_digit1_dp : OUT STD_LOGIC;
    flex_digit2_a  : OUT STD_LOGIC;
    flex_digit2_b  : OUT STD_LOGIC;
    flex_digit2_c  : OUT STD_LOGIC;
    flex_digit2_d  : OUT STD_LOGIC;
    flex_digit2_e  : OUT STD_LOGIC;
    flex_digit2_f  : OUT STD_LOGIC;
    flex_digit2_g  : OUT STD_LOGIC;
    flex_digit2_dp : OUT STD_LOGIC);

END cpu_2bit_top_level;

ARCHITECTURE A_structure OF cpu_2bit_top_level IS

  SIGNAL preset_data  : STD_LOGIC_VECTOR(7 DOWNTO 0);
  SIGNAL addr         : STD_LOGIC_VECTOR(1 DOWNTO 0);
  SIGNAL data_in      : STD_LOGIC_VECTOR(1 DOWNTO 0);
  SIGNAL data_out     : STD_LOGIC_VECTOR(1 DOWNTO 0);
  SIGNAL rd           : STD_LOGIC;
  SIGNAL wr           : STD_LOGIC;
  SIGNAL step         : STD_LOGIC;
  SIGNAL state        : STD_LOGIC_VECTOR(2 DOWNTO 0);
  SIGNAL ar_out       : STD_LOGIC_VECTOR(1 DOWNTO 0);
  SIGNAL br_out       : STD_LOGIC_VECTOR(1 DOWNTO 0);
  SIGNAL ip_out       : STD_LOGIC_VECTOR(1 DOWNTO 0);
  SIGNAL aa_out       : STD_LOGIC_VECTOR(1 DOWNTO 0);
  SIGNAL bb_out       : STD_LOGIC_VECTOR(1 DOWNTO 0);
  SIGNAL data_display : STD_LOGIC_VECTOR(7 DOWNTO 0);

  COMPONENT single_step
    PORT (
      clk    : IN  STD_LOGIC;
      reset  : IN  STD_LOGIC;
      button : IN  STD_LOGIC;
      step   : OUT STD_LOGIC);
  END COMPONENT;

  COMPONENT cpu_2bit
    PORT (
      clk      : IN  STD_LOGIC;
      reset    : IN  STD_LOGIC;
      step     : IN  STD_LOGIC;
      rd       : OUT STD_LOGIC;
      wr       : OUT STD_LOGIC;
      addr     : OUT STD_LOGIC_VECTOR(1 DOWNTO 0);
      state    : OUT STD_LOGIC_VECTOR(2 DOWNTO 0);
      ar_out   : OUT STD_LOGIC_VECTOR(1 DOWNTO 0);
      br_out   : OUT STD_LOGIC_VECTOR(1 DOWNTO 0);
      ip_out   : OUT STD_LOGIC_VECTOR(1 DOWNTO 0);
      aa_out   : OUT STD_LOGIC_VECTOR(1 DOWNTO 0);
      bb_out   : OUT STD_LOGIC_VECTOR(1 DOWNTO 0);
      data_in  : IN  STD_LOGIC_VECTOR(1 DOWNTO 0);
      data_out : OUT STD_LOGIC_VECTOR(1 DOWNTO 0));
  END COMPONENT;

  COMPONENT memory
    PORT (
      clk          : IN  STD_LOGIC;
      addr         : IN  STD_LOGIC_VECTOR(1 DOWNTO 0);
      data_in      : IN  STD_LOGIC_VECTOR(1 DOWNTO 0);
      data_out     : OUT STD_LOGIC_VECTOR(1 DOWNTO 0);
      preset_data  : IN  STD_LOGIC_VECTOR(7 DOWNTO 0);
      data_display : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
      preset       : IN  STD_LOGIC;
      rd           : IN  STD_LOGIC;
      wr           : IN  STD_LOGIC);
  END COMPONENT;

BEGIN

  I_single_step : single_step
    PORT MAP (
      clk    => clk,
      reset  => flex_pb1,
      button => flex_pb2,
      step   => step);

  I_cpu : cpu_2bit
    PORT MAP (
      clk      => clk,
      reset    => flex_pb1,
      step     => step,
      rd       => rd,
      wr       => wr,
      addr     => addr,
      state    => state,
      ar_out   => ar_out,
      br_out   => br_out,
      ip_out   => ip_out,
      aa_out   => aa_out,
      bb_out   => bb_out,
      data_in  => data_in,
      data_out => data_out);

  flex_d1 <= NOT br_out(1);
  flex_d5 <= NOT br_out(0);
  flex_d2 <= NOT ar_out(1);
  flex_d6 <= NOT ar_out(0);
  flex_d3 <= NOT aa_out(1);
  flex_d7 <= NOT aa_out(0);
  flex_d4 <= NOT bb_out(1);
  flex_d8 <= NOT bb_out(0);

  flex_digit1_dp <= NOT rd;
  flex_digit2_dp <= NOT wr;

  -----------------------------------------------------------------------------
  I_memory : memory
    PORT MAP (
      clk          => clk,
      addr         => addr,
      data_in      => data_out,
      data_out     => data_in,
      preset_data  => preset_data,
      data_display => data_display,
      preset       => flex_pb1,
      rd           => rd,
      wr           => wr);

  flex_d9  <= NOT data_display(1);
  flex_d13 <= NOT data_display(0);
  flex_d10 <= NOT data_display(3);
  flex_d14 <= NOT data_display(2);
  flex_d11 <= NOT data_display(5);
  flex_d15 <= NOT data_display(4);
  flex_d12 <= NOT data_display(7);
  flex_d16 <= NOT data_display(6);

  preset_data(1) <= flex_switch_1;
  preset_data(0) <= flex_switch_2;
  preset_data(3) <= flex_switch_3;
  preset_data(2) <= flex_switch_4;
  preset_data(5) <= flex_switch_5;
  preset_data(4) <= flex_switch_6;
  preset_data(7) <= flex_switch_7;
  preset_data(6) <= flex_switch_8;

  -----------------------------------------------------------------------------
  -- cpu-state display
  -----------------------------------------------------------------------------

  flex_digit1_d <= '0' WHEN state(0) = '1' ELSE '1';
  flex_digit1_g <= '0' WHEN state(1) = '1' ELSE '1';
  flex_digit1_a <= '0' WHEN state(2) = '1' ELSE '1';
  flex_digit1_b <= '1';
  flex_digit1_c <= '1';
  flex_digit1_e <= '1';
  flex_digit1_f <= '1';

  -----------------------------------------------------------------------------
  -- cpu ip display 
  -----------------------------------------------------------------------------
  P_ip_display         : PROCESS (ip_out)
    VARIABLE segment_v : STD_LOGIC_VECTOR(6 DOWNTO 0);
  BEGIN
    segment_v     := (OTHERS => '1');
    CASE ip_out IS
      WHEN "00"              =>
        segment_v := "0000001";
      WHEN "01"              =>
        segment_v := "1001111";
      WHEN "10"              =>
        segment_v := "0010010";
      WHEN "11"              =>
        segment_v := "0000110";
      WHEN OTHERS            => NULL;
    END CASE;
    flex_digit2_a <= segment_v(6);
    flex_digit2_b <= segment_v(5);
    flex_digit2_c <= segment_v(4);
    flex_digit2_d <= segment_v(3);
    flex_digit2_e <= segment_v(2);
    flex_digit2_f <= segment_v(1);
    flex_digit2_g <= segment_v(0);
  END PROCESS P_ip_display;

END A_structure;