LIBRARY IEEE; 
USE IEEE.std_logic_1164.ALL;
ENTITY dff IS
  GENERIC( q_out, qb_out : time);
  PORT( preset, clear, din, 
        clock : IN std_logic;
        q, qb : OUT std_logic);
END dff;

ARCHITECTURE behave OF dff IS
BEGIN
  dff_proc : PROCESS(preset, clear, clock)
    VARIABLE int_q : std_logic;
  BEGIN
    IF preset = '0' and clear = '0' THEN
      IF (clock'EVENT) AND (clock = '1') THEN
        int_q := din;
      END IF;

    ELSIF preset = '1' AND clear = '0' THEN
      int_q := '1';

    ELSIF clear = '1' AND preset = '0' THEN
      int_q := '0';

    ELSE
      int_q := 'X';

    END IF;

    q <= int_q after q_out;

    int_q := not(int_q);
    qb <= int_q after qb_out;

  END PROCESS dff_proc;
END behave;

LIBRARY IEEE; 
USE IEEE.std_logic_1164.ALL;
ENTITY board IS
  GENERIC (qdelay, qbdelay : time);
  PORT( clk, reset, data_in : IN std_logic;
        data_out : OUT std_logic);
END board; 

ARCHITECTURE structural OF board IS
  COMPONENT dff
    GENERIC( g1, g2 : time);
    PORT( p1, p2, p3, p4 : IN std_logic;
          p5, p6 : OUT std_logic);
  END COMPONENT;

  SIGNAL ground : std_logic := '1';
  SIGNAL int1, nc : std_logic;
BEGIN
  U1 : dff 
    GENERIC MAP( g1 => qdelay, 
                 g2 => qbdelay)
    PORT MAP( p1 => clk, 
              p2 => data_in, 
              p3 => reset,
              p4 => ground, 
              p5 => int1, 
              p6 => nc);

  U2 : dff
    GENERIC MAP( g1 => qdelay, 
                 g2 => qbdelay)
    PORT MAP( p1 => clk, 
              p2 => int1, 
              p3 => reset,
              p4 => ground, 
              p5 => data_out, 
              p6 => nc); 
END structural;



CONFIGURATION board_con OF board IS
  FOR structural
    FOR U1,U2: dff USE ENTITY WORK.dff(behave)
      GENERIC MAP( q_out => g1, qb_out => g2)
      PORT MAP( preset => p4, clear => p3,
                din => p2, clock => p1, 
                q => p5, qb => p6);
    END FOR;
  END FOR; 
END board_con;



LIBRARY IEEE; 
USE IEEE.std_logic_1164.ALL;
ENTITY cpu IS
  PORT( clock : IN std_logic;
        addr  : OUT std_logic_vector(0 to 3);
        data  : INOUT std_logic_vector(0 to 3);
        interrupt : IN std_logic;
        reset : IN std_logic); 
END cpu; 

ARCHITECTURE fragment OF cpu IS
  COMPONENT int_reg
    PORT( data : IN std_logic;
          regclock : IN std_logic;
          data_out : OUT std_logic);
  END COMPONENT;

  COMPONENT alu
    PORT( a, b : IN std_logic;
          c, carry : OUT std_logic);
  END COMPONENT;

  SIGNAL a, c, carry : std_logic_vector(0 TO 3);
BEGIN    
  reg_array : BLOCK
  BEGIN
    R1 : int_reg
      PORT MAP( data(0), clock, data(0));

    R2 : int_reg
      PORT MAP( data(1), clock, data(1));

    R3 : int_reg
      PORT MAP( data(2), clock, data(2));

    R4 : int_reg
      PORT MAP( data(3), clock, data(3));

  END BLOCK reg_array;

  shifter : BLOCK
  BEGIN
    A1 : alu
      PORT MAP( a(0), data(0), c(0), carry(0));

    A2 : alu
      PORT MAP( a(1), data(1), c(1), carry(1));

    A3 : alu
      PORT MAP( a(2), data(2), c(2), carry(2));

    A4 : alu
      PORT MAP( a(3), data(3), c(3), carry(3));

    shift_reg : BLOCK
    BEGIN
      R1 : int_reg
        PORT MAP( a(0), clock, a(1));

    END BLOCK shift_reg;
  END BLOCK shifter;
END fragment;



CONFIGURATION cpu_con OF cpu IS
  FOR fragment
    FOR reg_array
      FOR ALL: int_reg USE CONFIGURATION WORK.int_reg_con;
      END FOR;
    END FOR;
    FOR shifter
      FOR A1 : alu USE CONFIGURATION WORK.alu_con;
      END FOR;
      FOR shift_reg
        FOR R1 : int_reg USE CONFIGURATION WORK.int_reg_con;
        END FOR;
      END FOR;
    END FOR;
  END FOR;
END cpu_con;




