-- Model Name : Concurrent - Data Path -- Author : Armita Peymandoust -- Last Updated : 09 / 15 / 1996 -- This document is © copyrighted by the Author.
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
--
LIBRARY EXEMPLAR;
USE EXEMPLAR.exemplar_1164.ALL;
--
LIBRARY WORK;
USE WORK.synthesis_utilities.ALL;
USE WORK.synthesis_parameters.ALL;
USE WORK.global_environment.ALL;
--
ENTITY par_data_path IS
  PORT (
        -- register controls:
        load_ac, zero_ac, 
        load_ir, 
        increment_pc, load_page_pc, load_offset_pc, reset_pc,
        load_page_mar, load_offset_mar, 
        load_sr, cm_carry_sr, 
        -- bus connections:
        pc_on_mar_page_bus, ir_on_mar_page_bus, 
        pc_on_mar_offset_bus, dbus_on_mar_offset_bus,
        pc_offset_on_dbus, obus_on_dbus, databus_on_dbus, 
        mar_on_adbus,
        dbus_on_databus,
        -- logic unit function control inputs:
        arith_shift_left, arith_shift_right, no_shift,
        alu_operate : IN std_logic;
        alu_code : IN std_logic_vector (2 DOWNTO 0)
       );
END par_data_path;
--
ARCHITECTURE Concurrent OF par_data_path IS
  --
  COMPONENT accumulator_unit PORT (load, zero : IN std_logic); END COMPONENT;
  --
  COMPONENT instruction_register_unit PORT (load : IN std_logic); END COMPONENT;
   --
  COMPONENT program_counter_unit 
    PORT (increment, load_page, load_offset, reset : IN std_logic);
  END COMPONENT;
  --
  COMPONENT memory_address_register_unit 
    PORT (load_page, load_offset : IN std_logic);
  END COMPONENT;
  --
  COMPONENT status_register_unit PORT (load, cm_carry : IN std_logic ); END COMPONENT;
  --
  COMPONENT arithmetic_logic_unit 
    PORT (code : IN std_logic_vector; alu_operate : IN std_logic); 
  END COMPONENT;
  --
  COMPONENT shifter_unit 
    PORT (arith_shift_left, arith_shift_right, no_shift : IN std_logic);
  END COMPONENT;

BEGIN
  -- bus connections --
  --
  PROCESS (dbus_on_mar_offset_bus)
  BEGIN
    IF (mar_offset_bus/=NULL AND mar_offset_bus/=zero_8) THEN DEALLOCATE(mar_offset_bus)
; END IF;
    mar_offset_bus := NEW byte_node;
    mar_offset_bus.val (7 DOWNTO 0) := dbus.val;
  END PROCESS;
 --  
  PROCESS
  BEGIN
    databus := dbus;
    WAIT ON dbus_on_databus;
  END PROCESS;
  --
  PROCESS (obus_on_dbus)
  BEGIN
    dbus := obus; 
  END PROCESS;
  --
  PROCESS (databus_on_dbus)
  BEGIN
    dbus := databus;
  END PROCESS;
     
  -- register connections --
  --
  r1: accumulator_unit PORT MAP (load_ac, zero_ac);
  --
  r2: instruction_register_unit PORT MAP (load_ir);
  
  PROCESS (ir_on_mar_page_bus)
  BEGIN
    IF (mar_page_bus/=NULL AND mar_page_bus/=zero_4) THEN DEALLOCATE(mar_page_bus); END 
IF;
    mar_page_bus := NEW nibble_node;
    mar_page_bus.val := ir_out.val (3 DOWNTO 0);
  END PROCESS;
  --
  r3: program_counter_unit PORT MAP (increment_pc, load_page_pc, load_offset_pc, reset_p
c);

  PROCESS (pc_on_mar_page_bus)
  BEGIN
    IF (mar_page_bus/=NULL AND mar_page_bus/=zero_4) THEN DEALLOCATE(mar_page_bus); END 
IF;
    mar_page_bus := NEW nibble_node;
    mar_page_bus.val  := pc_out.val (11 DOWNTO 8);
  END PROCESS;

  PROCESS (pc_on_mar_offset_bus)
   BEGIN
    IF (mar_offset_bus/=NULL AND mar_offset_bus/=zero_8) THEN DEALLOCATE(mar_offset_bus)
; END IF;
    mar_offset_bus := NEW byte_node;
    mar_offset_bus.val := pc_out.val (7 DOWNTO 0);
  END PROCESS;
  
  PROCESS (pc_offset_on_dbus)
  BEGIN  --************************
    IF (dbus/=NULL AND dbus/=zero_8) THEN DEALLOCATE(dbus); END IF;
    dbus := NEW byte_node;
    dbus.val := pc_out.val (7 DOWNTO 0);
  END PROCESS;    
  --
  r4: memory_address_register_unit PORT MAP (load_page_mar, load_offset_mar);
  PROCESS (mar_on_adbus)
  BEGIN
    IF (adbus/=NULL AND adbus/=zero_12) THEN DEALLOCATE(adbus); END IF;
    adbus := NEW twelve_node;
    adbus.val(7 DOWNTO 0) := mar_offset_out.val;
    adbus.val(11 DOWNTO 8) := mar_page_out.val;
  END PROCESS;
  --
  r5: status_register_unit PORT MAP (load_sr, cm_carry_sr);
  --
  -- connection of logical and register structures --
  --
  l1: arithmetic_logic_unit PORT MAP (alu_code, alu_operate);
  l2: shifter_unit PORT MAP (arith_shift_left, arith_shift_right, no_shift); 
END Concurrent;